import { ChangeOperation } from "../../interfaces/dataUnit.js"; import { LoadDataRequest } from "../../loading/LoadDataRequest.js"; import { PaginationInfo } from "../../loading/PaginationInfo.js"; import { Action } from "../action/DataUnitAction.js"; import StateManager, { ActionReducer, StateAction } from "../StateManager.js"; class LoadingControlReducerImpl implements ActionReducer { public sliceName: string = "loadingControl"; public reduce(stateManager: StateManager, currentState: LoadingControlState, action: StateAction): LoadingControlState { switch (action.type) { case Action.LOADING_DATA : return {...currentState, lastRequest: action.payload}; case Action.DATA_LOADED: return {...currentState, paginationInfo: action.payload?.paginationInfo}; case Action.PAGINATION_UPDATED: return {...currentState, paginationInfo: action.payload}; case Action.DATA_SAVED: return {...currentState, paginationInfo: updatePaginationInfo(stateManager, action.payload)}; } return currentState; } } export const LoadingControlReducer = new LoadingControlReducerImpl(); export const getPaginationInfo = (stateManager: StateManager): PaginationInfo|undefined => { const state: LoadingControlState = stateManager.select(LoadingControlReducer.sliceName, (state: LoadingControlState) => state); return state ? state.paginationInfo : undefined; }; export const getCurrentRequest = (stateManager: StateManager): LoadDataRequest|undefined => { const state: LoadingControlState = stateManager.select(LoadingControlReducer.sliceName, (state: LoadingControlState) => state); return state ? state.lastRequest : undefined; }; export const getCurrentPage = (stateManager: StateManager): number => { const paginationInfo = getPaginationInfo(stateManager); return paginationInfo ? paginationInfo.currentPage : 0; }; export const getLastPage = (stateManager: StateManager, pageSize: number): number => { const paginationInfo = getPaginationInfo(stateManager); return paginationInfo ? Math.ceil((paginationInfo.total||paginationInfo.count||0) / pageSize) : 0; }; export const hasMorePages = (stateManager: StateManager): boolean => { const paginationInfo = getPaginationInfo(stateManager); if(paginationInfo && paginationInfo.hasMore){ return true; } return false; } export const hasPreviousPages = (stateManager: StateManager): boolean => { const paginationInfo = getPaginationInfo(stateManager); return paginationInfo ? paginationInfo.currentPage > 0 : false; } const updatePaginationInfo = (stateManager: StateManager, payload: Payload): PaginationInfo =>{ const paginationInfo = getPaginationInfo(stateManager); let { records, changes } = payload; if(!records || !changes || !paginationInfo || !validateNewRecordOperation(changes)) return paginationInfo as PaginationInfo; const { count, firstRecord, lastRecord, total } = paginationInfo; return { ...paginationInfo, count: (count ?? 0) + records.length, firstRecord: firstRecord === 0 && records.length > 0 ? 1 : firstRecord, lastRecord: lastRecord + records.length, total: (total ?? 0) + records.length } } const validateNewRecordOperation = (changes: Array): boolean => { return changes.every(change => isNewRecordOperation(change._operation)); }; const isNewRecordOperation = (operation: string): operation is ChangeOperation => { return ["INSERT", "COPY"].includes(operation); }; interface LoadingControlState{ lastRequest: LoadDataRequest; paginationInfo: PaginationInfo; } interface Change { dataUnit: string; record: Record; updatingFields: Record; _operation: string; } interface Payload { changes: Change[]; records: Record[]; }