import { Change, ChangeOperation, DataType, DataUnit, DateUtils, FieldDescriptor, LoadDataRequest, LoadDataResponse, Record, SavedRecord, StringUtils, UnitMetadata, } from '../../index.js'; import { DataUnitInMemoryLoaderConfig, RECORD_DATE_FORMAT } from './DataUnitInMemoryLoaderConfig.js'; import { DataUnitLoaderUtils } from './utils/dataUnitLoaderUtils.js'; export class DataUnitInMemoryLoader { private _dataUnit: DataUnit; private _metadata: UnitMetadata | undefined; private _initialRecords: Array = []; private recordDateFormat: RECORD_DATE_FORMAT; public static readonly IN_MEMORY_DATA_UNIT_NAME = 'InMemoryDataUnit'; public static readonly DEFAULT_PAGE_SIZE = 150; constructor(metadata?: UnitMetadata, records?: Array, config?: DataUnitInMemoryLoaderConfig) { this.metadata = metadata as UnitMetadata; this.recordDateFormat = config?.recordDateFormat ?? RECORD_DATE_FORMAT.DD_MM_YYYY; this.records = records ?? [] as Array; this._dataUnit = new DataUnit(DataUnitInMemoryLoader.IN_MEMORY_DATA_UNIT_NAME); this._dataUnit.pageSize = config?.pageSize ?? DataUnitInMemoryLoader.DEFAULT_PAGE_SIZE; this._dataUnit.metadataLoader = () => this.metadaLoader(); this._dataUnit.dataLoader = (dataUnit: DataUnit, request: LoadDataRequest) => this.inMemoryLoader(dataUnit, request, this.getRecordsToLoad()); this._dataUnit.saveLoader = (_dataUnit: DataUnit, changes: Array) => this.saveLoader(_dataUnit, changes); this._dataUnit.removeLoader = (_dataUnit: DataUnit, recordIds: Array) => this.removeLoader(_dataUnit, recordIds); this.dataUnit.loadMetadata().then(() => { if (config?.autoLoad !== false) { this.dataUnit.loadData(); } }); } private getRecordsToLoad(): Array { if (this._initialRecords == undefined && this.dataUnit.records.length > 0) { this._initialRecords = this.dataUnit.records; } const addedRecords = this.dataUnit.getAddedRecords(); if (addedRecords) { return [...this._initialRecords, ...addedRecords]; } return this._initialRecords; } public get dataUnit(): DataUnit { return this._dataUnit; } public get records(): Array { return this.dataUnit.records; } public set records(records: Array) { const columns = this.buildColumns(); this._initialRecords = this.buildInitialRecords(records, columns); if (!this._dataUnit) return; //Isso força o refresh internamente no datunit mantendo a seleção anterior this._dataUnit.loadDataWithParams({keepSelection: true}); } public static getConvertedValue(descriptor: FieldDescriptor, strValue: string, dateFormat?: RECORD_DATE_FORMAT) { if (!descriptor) return strValue; if (descriptor.dataType === DataType.BOOLEAN) return strValue === 'S'; if (descriptor.dataType === DataType.NUMBER) return Number(strValue); if (descriptor.dataType === DataType.OBJECT) return JSON.parse(strValue); if (descriptor.dataType === DataType.DATE) { return dateFormat === RECORD_DATE_FORMAT.ISO ? DateUtils.validateDate(new Date(strValue), true) : DateUtils.strToDate(strValue, true); } return strValue; } private buildColumns() { return this._metadata ? new Map(this._metadata.fields.map(descriptor => [descriptor.name, descriptor])) : undefined; } private buildInitialRecords(records: Array, columns: Map | undefined) { const newRecords = records?.map(record => { if (!record['__record__id__']) { record['__record__id__'] = this.generateUniqueId(); } if (!columns) return record; for (const fieldName in record) { const value = record[fieldName]; const fieldDescriptor = columns.get(fieldName); if (typeof value === 'string' && fieldDescriptor) { record[fieldName] = DataUnitInMemoryLoader.getConvertedValue(fieldDescriptor, value, this.recordDateFormat); } } return record; }); return newRecords; } public get metadata(): UnitMetadata { return this._metadata as UnitMetadata; } public set metadata(metadata: UnitMetadata) { this._metadata = metadata; if (this._dataUnit) { this._dataUnit.metadata = metadata as UnitMetadata; } } private generateUniqueId(): string { return StringUtils.generateUUID(); } private inMemoryLoader(dataUnit: DataUnit, request: LoadDataRequest, recordsIn: Array): Promise { return DataUnitLoaderUtils.buildLoadDataResponse(recordsIn, dataUnit, request); } private metadaLoader(): Promise { return Promise.resolve(this._metadata as UnitMetadata); } private saveLoader(_dataUnit: DataUnit, changes: Array): Promise> { return new Promise((resolve) => { let dataUnitRecords: SavedRecord[] = []; changes.forEach(change => { let { record, updatingFields, operation } = change; const changedRecord = { ...record, ...updatingFields }; if (operation === ChangeOperation.INSERT || operation === ChangeOperation.COPY) { changedRecord['__old__id__'] = record['__record__id__']; changedRecord['__record__id__'] = this.generateUniqueId(); this.records.push(changedRecord); } else { const recordIndex = this.records.findIndex(r => r['__record__id__'] == changedRecord['__record__id__']); this.records[recordIndex] = changedRecord; } dataUnitRecords.push(changedRecord); }); resolve(dataUnitRecords); }); } public removeLoader(_dataUnit: DataUnit, recordIds: Array): Promise> { return new Promise((resolve) => resolve(recordIds)); } }