import { UserAccessAction } from '../models/user-access-action'; import { createReducer, on, Action, createFeatureSelector, createSelector, } from '@ngrx/store'; import { CompanyViewModel, UserProfileModel } from '../models'; import * as userActions from './user.actions'; import * as oidcActions from './oidc.actions'; export interface State { userProfile: UserProfileModel | null; userAccessActions: UserAccessAction[]; activeCompany: CompanyViewModel | null; hasManyCompanies: boolean; companyDataIsReady: boolean; } export const initialState: State = { userProfile: null, userAccessActions: [], activeCompany: null, hasManyCompanies: false, companyDataIsReady: false, }; const userReducers = createReducer( initialState, on(userActions.init, (state) => ({ ...state, companyDataIsReady: false, })), on(userActions.logIn, (state) => ({ ...state, companyDataIsReady: false, })), on(userActions.logOut, (state) => ({ ...state, userProfile: null, userAccessActions: [], activeCompany: null, companyDataIsReady: false, })), on(oidcActions.checkAuth, (state) => ({ ...state, userProfile: null, userAccessActions: [], activeCompany: null, hasManyCompanies: false, })), on(userActions.setActiveCompany, (state, action) => ({ ...state, userProfile: null, userAccessActions: [], activeCompany: { ...action.company } as CompanyViewModel, hasManyCompanies: action.hasManyCompanies, companyDataIsReady: true, })), on(userActions.setUserProfile, (state, action) => ({ ...state, userProfile: ((action.userApiProfile && new UserProfileModel(action.userApiProfile, action.forceLanguage)) || null) as UserProfileModel, })), on(userActions.userProfileLanguageChanged, (state, action) => { const userLanguage = action.userLanguage && action.userLanguage.toLocaleLowerCase(); const userProfileLanguage = state.userProfile && state.userProfile.userLanguage.toLocaleLowerCase(); if (userLanguage === userProfileLanguage) { return state; } return { ...state, userProfile: { ...state.userProfile, userLanguage, } as UserProfileModel, }; }), on(oidcActions.userDataReceived, (state, action) => ({ ...state, companyDataIsReady: false, })), on(userActions.setUserAccessActions, (state, action) => ({ ...state, userAccessActions: [ ...state.userAccessActions, ...Object.keys(action.accessActions).map((accessAction) => ({ action: accessAction, allow: action.accessActions[accessAction], timestamp: new Date(), })), ], })) ); export function reducer(state: State | undefined, action: Action): State { return userReducers(state, action); } export const userReducer = reducer; export const userFeatureKey = 'core-user'; export const userState = createFeatureSelector(userFeatureKey); export const getUserProfile = createSelector( userState, // Need to check state existence because // selector could be called before state // setup in monitor.service.ts (state) => state && state.userProfile ); export const hasAccess = createSelector( userState, (state) => state.userProfile && state.userProfile.hasAccessToModule ); export const getUserLanguage = createSelector( userState, (state) => state.userProfile && state.userProfile.userLanguage ); export const getActiveCompany = createSelector( userState, (state) => state.activeCompany ); export const hasManyCompanies = createSelector( userState, (state) => state.hasManyCompanies ); export const companyDataIsReady = createSelector( userState, (state) => state.companyDataIsReady ); export const userAccessActions = createSelector( userState, (state) => state.userAccessActions );