Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/arbol contable refactor #134

Merged
merged 8 commits into from
Jan 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@
"@nebular/security": "4.1.2",
"@nebular/theme": "4.1.2",
"@ng-bootstrap/ng-bootstrap": "^5.3.1",
"@ngrx/effects": "8.5.0",
"@ngrx/entity": "8.5.0",
"@ngrx/router-store": "8.5.0",
"@ngrx/store": "8.5.0",
"@ngrx/store-devtools": "8.5.0",
"@ngx-translate/core": "^11.0.1",
"@ngx-translate/http-loader": "^4.0.0",
"@swimlane/ngx-charts": "^10.0.0",
Expand Down
19 changes: 19 additions & 0 deletions src/app/@core/_custom-validators/custom-validators.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {AbstractControl, ValidationErrors, ValidatorFn, Validators} from '@angular/forms';

function customRequired(msg: string): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {

return Validators.required(control) ? {
required: true,
msg
} : null;
};
}

const CustomValidators = {
customRequired
};

export {
CustomValidators
};
32 changes: 32 additions & 0 deletions src/app/@core/_resolver/entities.resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Injectable } from '@angular/core';
import { Resolve } from '@angular/router';
import { Store, select } from '@ngrx/store';
import { Observable } from 'rxjs';
import { filter, take } from 'rxjs/operators';
import { fromCuentaActions } from '../_store/actions';
import { CuentaPartialState } from '../_store/reducer';
import { selectCuentaLoaded, selectNaturalezaLoaded} from '../_store/selectors';



@Injectable()
export class CuentasResolver implements Resolve<boolean> {
constructor(private store: Store<CuentaPartialState>) {}

resolve(): Observable<boolean> {
const loaded$ = this.store.pipe(select(selectCuentaLoaded));

const loadedNaturaleza$ = this.store.pipe(select(selectNaturalezaLoaded));

return loaded$.pipe(
filter(loaded => {
if (loaded === false) {
this.store.dispatch(fromCuentaActions.loadCuentas());
}

return loaded;
}),
take(1)
);
}
}
87 changes: 87 additions & 0 deletions src/app/@core/_store/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { createAction, props } from '@ngrx/store';

export enum CuentaActionTypes {
LoadCuentas = '[Cuenta] Load Cuentas',
LoadCuentasSuccess = '[Cuenta] Load Cuentas Success',
LoadCuentasFail = '[Cuenta] Load Cuentas Fail',
LoadCuenta = '[Cuenta] Load Cuenta',
LoadCuentaSuccess = '[Cuenta] Load Cuenta Success',
LoadCuentaFail = '[Cuenta] Load Cuenta Fail',
UpdateCuenta = '[Cuenta] Update Cuenta',
UpdateCuentaSuccess = '[Cuenta] Update Cuenta Success',
UpdateCuentaFail = '[Cuenta] Update Cuenta Fail',
LoadNaturalezas = '[Naturaleza] Load Naturaleza',
LoadNaturalezasSuccess = '[Naturaleza] Load Naturalezas Success',
LoadNaturalezasFail = '[Naturaleza] Load Naturalezas Fail',
}

export const loadCuentas = createAction(CuentaActionTypes.LoadCuentas);

export const loadCuentasSuccess = createAction(
CuentaActionTypes.LoadCuentasSuccess,
props<{ data: any[] }>()
);

export const loadCuentasFail = createAction(
CuentaActionTypes.LoadCuentasFail,
props<{ error: Error | any }>()
);

export const loadCuenta = createAction(
CuentaActionTypes.LoadCuenta,
props<{ id: string | number }>()
);

export const loadCuentaSuccess = createAction(
CuentaActionTypes.LoadCuentaSuccess,
props<{ id: string | number; item: any }>()
);

export const loadCuentaFail = createAction(
CuentaActionTypes.LoadCuentaFail,
props<{ error: Error | any }>()
);

export const updateCuenta = createAction(
CuentaActionTypes.UpdateCuenta,
props<{ id: number | string; originalItem: any; updatedItem: any }>()
);

export const updateCuentaSuccess = createAction(
CuentaActionTypes.UpdateCuentaSuccess,
props<{ id: number | string; originalItem: any; updatedItem: any }>()
);

export const updateCuentaFail = createAction(
CuentaActionTypes.UpdateCuentaFail,
props<{
id: number | string;
originalItem: any;
updatedItem: any;
error: Error | any;
}>()
);

export const loadNaturalezas = createAction(CuentaActionTypes.LoadNaturalezas);

export const loadNaturalezasSuccess = createAction(
CuentaActionTypes.LoadNaturalezasSuccess,
props<{ data: any[] }>()
);

export const loadNaturalezasFail = createAction(
CuentaActionTypes.LoadNaturalezasFail,
props<{ error: Error | any }>()
);

export const fromCuentaActions = {
loadCuentas,
loadCuentasFail,
loadCuentasSuccess,
loadCuenta,
loadCuentaFail,
loadCuentaSuccess,
loadNaturalezas,
loadNaturalezasFail,
loadNaturalezasSuccess,
};
58 changes: 58 additions & 0 deletions src/app/@core/_store/effects.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { of } from 'rxjs';
import { map, switchMap, catchError } from 'rxjs/operators';

import { fromCuentaActions } from './actions';
import { ArbolHelper } from '../helpers/arbol/arbolHelper';

@Injectable()
export class CuentaEffects {
loadCuentas$ = createEffect(() =>
this.actions$.pipe(
ofType(fromCuentaActions.loadCuentas),
switchMap(() =>
this.entityService.getTree().pipe(
map((res: any) => fromCuentaActions.loadCuentasSuccess({
data: res
})
),
catchError(error =>
of(
fromCuentaActions.loadCuentasFail({
error
})
)
)
)
)
)
);

loadNaturalezas$ = createEffect(() =>
this.actions$.pipe(
ofType(fromCuentaActions.loadNaturalezas),
switchMap(() =>
this.entityService.getNaturalezaCuenta().pipe(
map((res: any) => fromCuentaActions.loadNaturalezasSuccess({
data: res
})
),
catchError(error =>
of(
fromCuentaActions.loadNaturalezasFail({
error
})
)
)
)
)
)
);


constructor(
private actions$: Actions,
private entityService: ArbolHelper
) {}
}
85 changes: 85 additions & 0 deletions src/app/@core/_store/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { InjectionToken } from '@angular/core';
import { ActionReducerMap, MetaReducer } from '@ngrx/store';
import * as fromRouter from '@ngrx/router-store';
import { Params } from '@angular/router';

import {
State as CuentaState,
reducer as CuentaReducer,
CUENTA_FEATURE_KEY,
NATURALEZA_FEATURE_KEY
} from './reducer';
import { CuentaEffects } from './effects';
import { environment } from '../../../environments/environment';

export interface RouterStateUrl {
url: string;
params: Params;
queryParams: Params;
}

/**
* Reset the state the store on logout
*/
function resetState(reducer) {
return (state, action) => {
// if (action.type === fromUser.logoutSuccess().type) {
// state = undefined;
// }

return reducer(state, action);
};
}

/**
* Every reducer module's default export is the reducer function itself. In
* addition, each module should export a type or interface that describes
* the state of the reducer plus any selector functions. The `* as`
* notation packages up all of the exports into a single object.
*/

// import * as fromLayout from './layout';

/**
* As mentioned, we treat each reducer like a table in a database. This means
* our top level state interface is just a map of keys to inner state types.
*/
export interface AppState {
router: fromRouter.RouterReducerState<RouterStateUrl>;
[CUENTA_FEATURE_KEY]: CuentaState;
[NATURALEZA_FEATURE_KEY]: CuentaState;
}

/**
* Our state is composed of a map of action reducer functions.
* These reducer functions are called with each dispatched action
* and the current or initial state and return a new immutable state.
*/
const reducers: ActionReducerMap<AppState> = {
router: fromRouter.routerReducer,
[CUENTA_FEATURE_KEY]: CuentaReducer,
[NATURALEZA_FEATURE_KEY]: CuentaReducer
};

/**
* By default, @ngrx/store uses combineReducers with the reducer map to compose
* the root meta-reducer. To add more meta-reducers, provide an array of meta-reducers
* that will be composed to form the root meta-reducer.
*/
const metaReducers: MetaReducer<AppState>[] = !environment.production
? [resetState]
: [resetState];

export const getMetaReducers = (): MetaReducer<AppState>[] => metaReducers;

/**
* We need to inject reducers to our application to make AOT build worked
*/
export const REDUCER_TOKEN = new InjectionToken<ActionReducerMap<AppState>>(
'Registered Reducers',
{
factory: () => reducers
}
);

export const appEffects = [CuentaEffects];
69 changes: 69 additions & 0 deletions src/app/@core/_store/reducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { createReducer, on, Action } from '@ngrx/store';
import { EntityState, EntityAdapter, createEntityAdapter } from '@ngrx/entity';

import { fromCuentaActions } from './actions';

export const CUENTA_FEATURE_KEY = 'Cuenta';
export const NATURALEZA_FEATURE_KEY = 'naturaleza';

export interface State extends EntityState<any> {
loaded: boolean;
error?: Error | any;
}

export const adapter: EntityAdapter<any> = createEntityAdapter<any>({
// In this case this would be optional since primary key is id
selectId: item => item.data.Codigo,
});

export interface CuentaPartialState {
readonly [CUENTA_FEATURE_KEY]: State;
readonly [NATURALEZA_FEATURE_KEY]: State;
}

export const initialState: State = adapter.getInitialState({
// Additional entity state properties
loaded: false,
error: null
});

const _reducer = createReducer(
initialState,
on(fromCuentaActions.loadCuentasSuccess, (state, { data }) => {
return adapter.addMany(data, {
...state,
loaded: true
});
}),
on(fromCuentaActions.loadCuentasFail, (state, { error }) => {
return {
...state,
error
};
}),
on(fromCuentaActions.loadCuentaSuccess, (state, { id, item }) => {
return adapter.addOne(item, state);
}),
on(fromCuentaActions.loadCuentaFail, (state, { error }) => {
return {
...state,
error
};
}),
on(fromCuentaActions.loadNaturalezasSuccess, (state, { data }) => {
return adapter.addMany(data, {
...state,
loaded: true
});
}),
on(fromCuentaActions.loadNaturalezasFail, (state, { error }) => {
return {
...state,
error
};
}),
);

export function reducer(state: State | undefined, action: Action) {
return _reducer(state, action);
}
Loading