import { OnKeyDownEventArgs, SlickDataView, SlickEventData, SlickGrid, } from "slickgrid"; import { IExternalVariables, IHotKeysBehavior, ISlickRow, ISlickTable, TGridRow, } from "shared/model/types"; import { copySelectedRows, hotKeysCopy, hotKeysDelete, hotKeysRedo, hotKeysUndo, nothingToCopy, } from "../../../lib"; export class DefaultHotKeys implements IHotKeysBehavior { private externalVariables: IExternalVariables = {}; private commandQueue: ISlickRow[][] = []; private queueIndex = -1; private getQueueIndex(): number { return this.queueIndex; } private setQueueIndex(queueIndex: number): void { this.queueIndex = queueIndex; } public handleKeyboardEvent( event: SlickEventData, table: ISlickTable, ): void { if (!table.isActive) return; const grid = table.grid; if (!grid || !grid.getOptions().editable) return; const dataView: SlickDataView = grid.getData(); if (hotKeysCopy(event)) { event.preventDefault(); event.stopImmediatePropagation(); if (nothingToCopy(grid)) return; copySelectedRows(grid); grid.invalidate(); this.pushToCommandQueue(grid); table.isEdited = true; } else if (hotKeysDelete(event)) { event.preventDefault(); event.stopImmediatePropagation(); const selectedRows = grid.getSelectedRows(); if (!selectedRows.length) return; selectedRows.forEach((rowNumber): void => { const row = dataView.getItem(rowNumber); row.isDeleted = true; }); grid.setSelectedRows([]); dataView.refresh(); grid.invalidate(); this.pushToCommandQueue(grid); table.isEdited = true; } else if (hotKeysUndo(event)) { event.preventDefault(); event.stopImmediatePropagation(); const queueIndex = this.getQueueIndex(); if (queueIndex < 1) { return; } const newQueueIndex = queueIndex - 1; this.setQueueIndex(newQueueIndex); dataView.setItems(copy(this.commandQueue[newQueueIndex])); grid.invalidate(); table.isEdited = newQueueIndex !== 0; } else if (hotKeysRedo(event)) { event.preventDefault(); event.stopImmediatePropagation(); const queueIndex = this.getQueueIndex(); if (queueIndex === this.commandQueue.length - 1) return; const newQueueIndex = queueIndex + 1; this.setQueueIndex(newQueueIndex); dataView.setItems(copy(this.commandQueue[newQueueIndex])); grid.invalidate(); table.isEdited = true; } } public pushToCommandQueue(grid: SlickGrid | null): void { if (!grid) return; const dataView: SlickDataView = grid.getData(); const rows = dataView.getItems(); const queueIndex = this.getQueueIndex(); const newQueueIndex = queueIndex + 1; this.commandQueue.length = newQueueIndex; this.commandQueue.push(copy(rows)); this.setQueueIndex(newQueueIndex); } public resetQueue(): void { this.commandQueue.length = 0; this.queueIndex = -1; } public setExternalVariables(variables: IExternalVariables): void { this.externalVariables = { ...this.externalVariables, ...variables }; } public getExternalVariables(): IExternalVariables { return this.externalVariables; } } function copy(rows: ISlickRow[]): ISlickRow[] { return rows.map((row) => ({ ...row })); }