put in the ngrx
This commit is contained in:
Generated
+44
@@ -14,6 +14,9 @@
|
||||
"@angular/forms": "^21.0.0",
|
||||
"@angular/platform-browser": "^21.0.0",
|
||||
"@angular/router": "^21.0.0",
|
||||
"@ngrx/effects": "^21.0.1",
|
||||
"@ngrx/store": "^21.0.1",
|
||||
"@ngrx/store-devtools": "^21.0.1",
|
||||
"@primeuix/themes": "^2.0.2",
|
||||
"@tailwindcss/postcss": "^4.1.17",
|
||||
"file-saver": "^2.0.5",
|
||||
@@ -2611,6 +2614,47 @@
|
||||
"@tybys/wasm-util": "^0.10.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrx/effects": {
|
||||
"version": "21.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-21.0.1.tgz",
|
||||
"integrity": "sha512-hSdpToAiSYa5FJ/CAygQHpnCaF2S1HO7q/57ob3XvNTWmkofa0VqI/IIe4W57bojh2YOWCJ91SCn3kAjymaV3g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/core": "^21.0.0",
|
||||
"@ngrx/store": "21.0.1",
|
||||
"rxjs": "^6.5.3 || ^7.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrx/store": {
|
||||
"version": "21.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@ngrx/store/-/store-21.0.1.tgz",
|
||||
"integrity": "sha512-2hGnw/c5o8nmKzyx7TrUUM7FXjE2zqjX0EF+wLbw9Oy/L+VdCmx+ZI1BFjuAR4B8PKEWHG2KSbOM13SMNkpZiA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/core": "^21.0.0",
|
||||
"rxjs": "^6.5.3 || ^7.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrx/store-devtools": {
|
||||
"version": "21.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@ngrx/store-devtools/-/store-devtools-21.0.1.tgz",
|
||||
"integrity": "sha512-G9fO7CFwYUpz8+JZ9uny+lVJ7iv6PcFJDg+jae5CCrAUIiflnR8gbwD8exAd2AODpxPCpmnSojuLNpLDAcwGzQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/core": "^21.0.0",
|
||||
"@ngrx/store": "21.0.1",
|
||||
"rxjs": "^6.5.3 || ^7.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@npmcli/agent": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-4.0.0.tgz",
|
||||
|
||||
+4
-1
@@ -29,6 +29,9 @@
|
||||
"@angular/forms": "^21.0.0",
|
||||
"@angular/platform-browser": "^21.0.0",
|
||||
"@angular/router": "^21.0.0",
|
||||
"@ngrx/effects": "^21.0.1",
|
||||
"@ngrx/store": "^21.0.1",
|
||||
"@ngrx/store-devtools": "^21.0.1",
|
||||
"@primeuix/themes": "^2.0.2",
|
||||
"@tailwindcss/postcss": "^4.1.17",
|
||||
"file-saver": "^2.0.5",
|
||||
@@ -51,4 +54,4 @@
|
||||
"typescript": "~5.9.2",
|
||||
"vitest": "^4.0.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
Binary file not shown.
+45
-11
@@ -8,23 +8,57 @@ import { routes } from './app.routes';
|
||||
import MyPreset from './mythem';
|
||||
import { JwtInterceptor, ErrorInterceptor, initializeApp } from './shares';
|
||||
|
||||
import { provideStore } from '@ngrx/store';
|
||||
import { provideStoreDevtools } from '@ngrx/store-devtools';
|
||||
import { isDevMode } from '@angular/core';
|
||||
import { provideEffects } from '@ngrx/effects';
|
||||
import { staffEffects,staffsReducer } from './state';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
provideStore({
|
||||
myStaffs: staffsReducer,
|
||||
}),
|
||||
provideStoreDevtools({
|
||||
maxAge: 25,
|
||||
logOnly: !isDevMode()
|
||||
}),
|
||||
provideBrowserGlobalErrorListeners(),
|
||||
MessageService, ConfirmationService,
|
||||
provideAppInitializer(initializeApp()),
|
||||
provideHttpClient(withInterceptors([JwtInterceptor, ErrorInterceptor])),
|
||||
MessageService, ConfirmationService,
|
||||
provideAppInitializer(initializeApp()),
|
||||
provideHttpClient(withInterceptors([JwtInterceptor, ErrorInterceptor])),
|
||||
provideRouter(routes, withComponentInputBinding()),
|
||||
providePrimeNG({
|
||||
theme: {
|
||||
preset: MyPreset,
|
||||
options: {
|
||||
cssLayer: {
|
||||
providePrimeNG({
|
||||
theme: {
|
||||
preset: MyPreset,
|
||||
options: {
|
||||
cssLayer: {
|
||||
name: 'primeng',
|
||||
order: 'theme, base, primeng'
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
]
|
||||
}
|
||||
}),
|
||||
provideEffects([staffEffects])
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
import { Store } from '@ngrx/store';
|
||||
private readonly store = inject(Store);
|
||||
protected books = this.store.selectSignal(selectBooks);
|
||||
protected onAdd(id: number) {
|
||||
this.store.dispatch(StaffsActions.addStaff({ id }));
|
||||
}
|
||||
|
||||
protected onRemove(id: number) {
|
||||
this.store.dispatch(StaffsActions.removeStaff({ id }));
|
||||
}
|
||||
on ngOnInit() {
|
||||
use it normal get from API first
|
||||
and subscribe( (x) => this.store.dispatch(StaffApiAction.LoadStaffList({x})))
|
||||
}
|
||||
*/
|
||||
@@ -85,15 +85,16 @@ export class PersonEdit implements OnInit, OnDestroy {
|
||||
alive: [false], //Validators.required
|
||||
fatherId:[0],
|
||||
motherId:[0]
|
||||
|
||||
|
||||
|
||||
});
|
||||
constructor( private cdr: ChangeDetectorRef,public dialogService: DialogService,
|
||||
public ref: DynamicDialogRef, public config: DynamicDialogConfig,
|
||||
|
||||
private router: Router, private route: ActivatedRoute,
|
||||
private appSetting: AppSettingService,
|
||||
constructor(
|
||||
private cdr: ChangeDetectorRef,
|
||||
public dialogService: DialogService,
|
||||
public ref: DynamicDialogRef,
|
||||
public config: DynamicDialogConfig,
|
||||
private router: Router,
|
||||
private route: ActivatedRoute,
|
||||
private appSetting: AppSettingService,
|
||||
) {
|
||||
this.hostsite = this.appSetting.appSetting.attachment;
|
||||
}
|
||||
@@ -118,11 +119,8 @@ constructor( private cdr: ChangeDetectorRef,public dialogService: DialogService,
|
||||
this.motherList.push(item);
|
||||
else
|
||||
this.fatherList.push(item);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
getClassForRequire(prev:string,name:string){
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<p-table [value]="userList" sortMode="multiple"
|
||||
<!--[value]="userList"-->
|
||||
<p-table [value]="users" sortMode="multiple"
|
||||
class="p-datatable-sm" [loading]="loading">
|
||||
<ng-template pTemplate="header">
|
||||
<tr>
|
||||
|
||||
@@ -2,13 +2,8 @@ import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, inject, ChangeDe
|
||||
|
||||
import { StaffView ,StaffSearch } from '../models';
|
||||
|
||||
/* ngRx */
|
||||
/*
|
||||
import { Store, select } from '@ngrx/store';
|
||||
import * as validationActions from './store/actions/validationpoint.action';
|
||||
import * as validationSelector from './store/selectors/validationpoint.selector';
|
||||
import { appValidationState } from './store/reducers';
|
||||
*/
|
||||
import { Store } from '@ngrx/store';
|
||||
import { StaffsActions, StaffsApiActions } from '../state/staff.actions';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { Router } from '@angular/router';
|
||||
@@ -19,6 +14,7 @@ import { FormsModule } from '@angular/forms';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ButtonModule } from 'primeng/button';
|
||||
import { InputTextModule } from 'primeng/inputtext';
|
||||
import { selectStaffLoaded,selectState } from '../state/staff.selectors';
|
||||
|
||||
@Component({
|
||||
selector: 'staff-list',
|
||||
@@ -28,13 +24,16 @@ import { InputTextModule } from 'primeng/inputtext';
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class StaffComponent implements OnInit, OnDestroy{
|
||||
|
||||
private readonly store = inject(Store);
|
||||
private subscription:Subscription = new Subscription();
|
||||
firstname = '';
|
||||
email = '';
|
||||
lastname = '';
|
||||
loading = false;
|
||||
userList:StaffView[] = [];
|
||||
appState = this.store.selectSignal(selectState);
|
||||
users = this.appState().staffs;
|
||||
staffloadyet = this.appState().staffloaded;
|
||||
private cd = inject(ChangeDetectorRef);
|
||||
msg ="[Staff component]";
|
||||
|
||||
@@ -99,25 +98,32 @@ export class StaffComponent implements OnInit, OnDestroy{
|
||||
const canSearch = true; // this.canSearch();
|
||||
if (canSearch)
|
||||
{
|
||||
this.loading = true;
|
||||
|
||||
const criteria = this.getSearchCiteria();
|
||||
this.staffService.searchCriteria = criteria;
|
||||
this.subscription.add(
|
||||
this.staffService.searchStaffs(criteria).subscribe( {
|
||||
next: result => {
|
||||
this.loading = false;
|
||||
// console.log(this.msg + "search load Data", result);
|
||||
this.userList = result.data;
|
||||
this.cd.detectChanges();
|
||||
},
|
||||
error: e => {
|
||||
const message = e || e.message;
|
||||
// this.toastr.error(message);
|
||||
this.loading = false;
|
||||
console.log("error ", e);
|
||||
console.log("search function store staffload yet",this.staffloadyet, this.users);
|
||||
if (this.staffloadyet != true) {
|
||||
this.loading = true;
|
||||
const loadStaff$ = this.staffService.searchStaffs(criteria);
|
||||
this.subscription.add(
|
||||
loadStaff$.subscribe( {
|
||||
next: result => {
|
||||
|
||||
this.loading = false;
|
||||
|
||||
this.userList = result.data;
|
||||
this.store.dispatch(StaffsApiActions.loadStaffSuccess({staffs:this.userList, staffLoad: true}));
|
||||
this.cd.detectChanges();
|
||||
},
|
||||
error: e => {
|
||||
const message = e || e.message;
|
||||
// this.toastr.error(message);
|
||||
this.loading = false;
|
||||
console.log("error ", e);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
newUser():void {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import { StaffView } from '../models';
|
||||
|
||||
export interface AppState {
|
||||
staffs: Array<StaffView>;
|
||||
staffloaded : boolean;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export * from './app.state';
|
||||
export * from './staff.actions';
|
||||
export * from './staff.effects';
|
||||
export * from './staff.reducer';
|
||||
export * from './staff.selectors';
|
||||
@@ -0,0 +1,19 @@
|
||||
import { createActionGroup, emptyProps, props } from '@ngrx/store';
|
||||
import { StaffSearch, StaffView } from '../models';
|
||||
|
||||
export const StaffsActions = createActionGroup({
|
||||
source: 'Staffs',
|
||||
events: {
|
||||
'Add Staff': props<{ staffId: number }>(),
|
||||
'Remove Staff': props<{ staffId: number }>(),
|
||||
'Load Staff': props<{criteria: StaffSearch}>(),
|
||||
},
|
||||
});
|
||||
|
||||
export const StaffsApiActions = createActionGroup({
|
||||
source: 'Staffs API',
|
||||
events: {
|
||||
'LoadStaffSuccess': props<{ staffs: Array<StaffView>; staffLoad: boolean }>(),
|
||||
'LoadStaffFail': props<{ error: string }>(),
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
import { Actions, createEffect, ofType } from '@ngrx/effects';
|
||||
import { catchError, filter, map, of, switchMap, exhaustMap } from 'rxjs';
|
||||
//import { concatLatestFrom } from '@ngrx/operators';
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
import { StaffsActions, StaffsApiActions } from './staff.actions';
|
||||
|
||||
import { StaffService } from '../staff/staff.service';
|
||||
import { StaffSearch } from '../models';
|
||||
|
||||
@Injectable()
|
||||
export class staffEffects {
|
||||
private actions$: Actions = inject(Actions);
|
||||
private staffService: StaffService = inject(StaffService);
|
||||
private store: Store = inject(Store);
|
||||
|
||||
LoadStaffs$ = createEffect(() =>
|
||||
this.actions$.pipe(
|
||||
ofType(StaffsActions.loadStaff),
|
||||
exhaustMap((action: {criteria:StaffSearch}) =>
|
||||
this.staffService.searchStaffs(action.criteria).pipe(
|
||||
map((response) => StaffsApiActions.loadStaffSuccess({staffs: response.data, staffLoad: true})),
|
||||
catchError((err: HttpErrorResponse) => of(StaffsApiActions.loadStaffFail({ error: err.error})))
|
||||
)
|
||||
)
|
||||
));
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { createReducer, on } from '@ngrx/store';
|
||||
|
||||
import { StaffsApiActions } from './staff.actions';
|
||||
import { StaffView } from '../models';
|
||||
import { AppState } from './app.state';
|
||||
|
||||
export const initialState: AppState ={
|
||||
staffs:[],
|
||||
staffloaded: false
|
||||
}
|
||||
|
||||
export const staffsReducer = createReducer(
|
||||
initialState,
|
||||
on(StaffsApiActions.loadStaffSuccess, (
|
||||
state, action) => {
|
||||
return {
|
||||
...state,
|
||||
staffs: action.staffs,
|
||||
staffloaded: true
|
||||
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
@@ -0,0 +1,16 @@
|
||||
import { createSelector, createFeatureSelector } from '@ngrx/store';
|
||||
import { StaffView } from '../models';
|
||||
import { AppState } from './app.state';
|
||||
|
||||
export const selectState = createFeatureSelector<AppState>('myStaffs');
|
||||
|
||||
// 2. Create a selector for a specific piece of state
|
||||
export const selectStaff = createSelector(
|
||||
selectState,
|
||||
(state: AppState) => state.staffs
|
||||
);
|
||||
|
||||
// 2. Create a selector for a specific piece of state
|
||||
export const selectStaffLoaded = createSelector(
|
||||
selectState,
|
||||
(state: AppState) => state.staffloaded);
|
||||
Reference in New Issue
Block a user