import { MwCorePreferenceApiModel } from './../models/preference.model'; import { Injectable } from '@angular/core'; import { Store, select } from '@ngrx/store'; import { Subject, Observable } from 'rxjs'; import { takeUntil, filter, debounceTime, switchMap, map, } from 'rxjs/operators'; import { cloneDeep, isEqual } from 'lodash-es'; import * as companyReducers from '../@store/company.reducer'; import * as companyActions from '../@store/company.actions'; import { MwCorePreferenceModel } from '../models/preference.model'; import { ColumnApi, ColumnState, GridApi } from '@ag-grid-community/core'; // ------------------------------------------------------------ // - Core preferences - general across all projects // ------------------------------------------------------------ export abstract class MwBasePreferenceService { private static preferenceStore: any; gridStates: any = 'gridStates'; gridFilterModels: any = 'gridFilters'; get preference(): T { return MwBasePreferenceService.preferenceStore as T; } set preference(value: T) { MwBasePreferenceService.preferenceStore = value; } get preferenceLoaded(): boolean { return !!this.preference; } get preference$(): Observable { return this.store.pipe( select(companyReducers.isPreferenceReady), filter((ready) => ready), switchMap(() => this.store.pipe(select(companyReducers.preference))), map((t) => t as T) ); } private unsubscribeAll$ = new Subject(); private savePreference$ = new Subject(); constructor(private store: Store) { this.savePreference$ .pipe(takeUntil(this.unsubscribeAll$), debounceTime(1000)) .subscribe(() => { this.store.dispatch( companyActions.savePreference({ data: cloneDeep(this.preference) }) ); }); this.preference$.subscribe((value) => (this.preference = cloneDeep(value))); } setValue(key: K, value: T[K]): void { if (this.preference && !isEqual(this.preference[key], value)) { this.preference[key] = value; this.saveGeneralPreference(); } } setCustomValue(key: string, value: any): void { if (!this.preference) { return; } const customPreferences = this.getCustomPreferences(); customPreferences[key] = value; this.preference.customPreferences = customPreferences; this.saveGeneralPreference(); } getValue(key: K): T[K] { return this.preference && this.preference[key]; } getCustomValue(key: string): any { const customPreferences = this.getCustomPreferences(); return customPreferences[key]; } abstract map(apiModel: MwCorePreferenceApiModel): T; private saveGeneralPreference(): void { this.savePreference$.next(true); } private getCustomPreferences(): { [key: string]: any } { return this.preference.customPreferences || {}; } } @Injectable({ providedIn: 'root', }) export class MwCorePreferenceService extends MwBasePreferenceService { constructor(store: Store) { super(store); } map(apiModel: MwCorePreferenceApiModel): MwCorePreferenceModel { return new MwCorePreferenceModel(apiModel); } saveGridState(gridId: string, columnApi: ColumnApi): void { const columnsState = cloneDeep(this.getValue(this.gridStates)) || {}; columnsState[gridId] = columnApi.getColumnState(); this.setValue(this.gridStates, columnsState); } saveGridStateFilters(gridId: string, gridApi: GridApi): void { const columnsFilter = cloneDeep(this.getValue(this.gridFilterModels)) || {}; columnsFilter[gridId] = gridApi.getFilterModel(); this.setValue(this.gridFilterModels, columnsFilter); } restoreGridState( gridId: string, columnApi: ColumnApi, gridApi: GridApi, ignoreColumnsIds: string[] = [] ): void { const columnsState = this.getValue(this.gridStates); const savedColumnsState: ColumnState[] = ( (columnsState && columnsState[gridId]) || [] ).filter((column: any) => ignoreColumnsIds.indexOf(column.colId) === -1); columnApi.applyColumnState({ state: savedColumnsState, applyOrder: true, }); const columnsFilters = this.getValue(this.gridFilterModels); const savedColumnsFilters: {[key: string]: any} = ( (columnsFilters && columnsFilters[gridId]) || {} ); if (savedColumnsFilters && Object.keys(savedColumnsFilters).length !== 0) { gridApi.setFilterModel(savedColumnsFilters); } } }