import { ActionReducer } from "../StateManager.js"; import StateManager from "../StateManager.js"; import { Record } from "../../interfaces/dataUnit.js"; import { getRecords } from "./RecordsSlice.js"; import { getSelection } from "./SelectionSlice.js"; import { getChangedFieldValue, getChanges } from "./ChangesSlice.js"; import { getRemovedRecords } from "./RemovedRecordsSlice.js"; import { getAddedRecords } from "./AddedRecordsSlice.js"; class SnapshotReducerImpl implements ActionReducer{ public sliceName: string = "snapshot"; public reduce(stateManager: StateManager, currentSnapshot: Snapshot): Snapshot { return buildSnapshot(currentSnapshot, stateManager); } } export const SnapshotReducer = new SnapshotReducerImpl(); export const getSnapshot = (stateManager: StateManager): Snapshot | undefined => { return stateManager.select(SnapshotReducer.sliceName, (state: Snapshot) => state); } export const getCurrentRecords = (stateManager: StateManager): Map => { const snapshot = getSnapshot(stateManager); return snapshot ? snapshot.records : new Map(); }; export const getSelectionRecords = (stateManager: StateManager): Array | undefined => { const snapshot = getSnapshot(stateManager); return snapshot ? Array.from(snapshot.selectionRecords.values()) : undefined; } export const getModifiedRecords = (stateManager: StateManager): Array | undefined => { const currentRecords = getCurrentRecords(stateManager); if(!currentRecords){ return undefined } const changes = getChanges(stateManager); const added = getAddedRecords(stateManager); if(!changes && !added){ return undefined } let modifiedIDs = changes ? Array.from(changes.keys()) : []; if(added){ modifiedIDs = modifiedIDs.concat(added.map(r=>r.__record__id__)); } return Array.from(currentRecords.values()).filter(r=>modifiedIDs.includes(r.__record__id__)); } export const getSelectedRecord = (stateManager: StateManager): Record|undefined => { const selection = getSelectionRecords(stateManager); return selection == undefined ? undefined : selection[0]; } export const getFieldValue = (stateManager: StateManager, fieldName: string): any => { const record = getSelectedRecord(stateManager); return record == undefined ? undefined : getChangedFieldValue(fieldName, record, stateManager); }; export interface Snapshot{ records: Map; selectionRecords: Map } function buildSnapshot(oldSnapshot: Snapshot, stateManager: StateManager): Snapshot{ let records = getRecords(stateManager) || []; const added = getAddedRecords(stateManager); if(added){ records = (records).concat(added); } const removedRecords = getRemovedRecords(stateManager); if(removedRecords){ records = records.filter(record => !removedRecords.includes(record.__record__id__)); } const changes = getChanges(stateManager); const snapshotRecords: Map = new Map(records.map(source => [source.__record__id__, {...source, ...changes?.get(source.__record__id__)}])); const selectionRecords: Map = new Map(oldSnapshot?.selectionRecords); const selection: Array = getSelection(stateManager); if(selection && selection.length > 0){ selection.forEach(recordId => { const record = snapshotRecords.has(recordId) ? snapshotRecords.get(recordId) : oldSnapshot?.records.get(recordId); if(record){ selectionRecords.set(recordId, record); } }); } Array.from(selectionRecords.keys()).forEach(key => { if(!selection.includes(key)){ selectionRecords.delete(key); } }); return { records: snapshotRecords, selectionRecords } }