State Management
NgRx-based state management for the Angular frontend.
Overviewβ
Ever Gauzy uses NgRx for global state management alongside Angular services for local component state.
Store Structureβ
AppState
βββ auth β User, token, permissions
βββ organization β Current organization
βββ employee β Current employee context
βββ navigation β Sidebar, breadcrumbs
βββ layout β Theme, sidebar state
βββ feature stores (lazy-loaded)
βββ employees
βββ projects
βββ tasks
βββ time-tracker
Patternsβ
Actionsβ
export const login = createAction(
"[Auth] Login",
props<{ email: string; password: string }>(),
);
export const loginSuccess = createAction(
"[Auth] Login Success",
props<{ user: IUser; token: string }>(),
);
export const loginFailure = createAction(
"[Auth] Login Failure",
props<{ error: string }>(),
);
Reducersβ
export const authReducer = createReducer(
initialState,
on(loginSuccess, (state, { user, token }) => ({
...state,
user,
token,
isAuthenticated: true,
})),
on(loginFailure, (state, { error }) => ({
...state,
error,
isAuthenticated: false,
})),
);
Effectsβ
@Injectable()
export class AuthEffects {
login$ = createEffect(() =>
this.actions$.pipe(
ofType(login),
switchMap(({ email, password }) =>
this.authService.login(email, password).pipe(
map((result) => loginSuccess(result)),
catchError((error) => of(loginFailure({ error }))),
),
),
),
);
}
Selectorsβ
export const selectAuth = createFeatureSelector<AuthState>("auth");
export const selectCurrentUser = createSelector(
selectAuth,
(state) => state.user,
);
export const selectIsAuthenticated = createSelector(
selectAuth,
(state) => state.isAuthenticated,
);
Service-Based Stateβ
For simpler component state, services with BehaviorSubject:
@Injectable({ providedIn: "root" })
export class OrganizationService {
private selectedOrganization$ = new BehaviorSubject<IOrganization>(null);
get organization$(): Observable<IOrganization> {
return this.selectedOrganization$.asObservable();
}
setOrganization(org: IOrganization): void {
this.selectedOrganization$.next(org);
}
}