import mapValues = require('lodash/mapValues'); import {BulkColValues, ColInfo, ColInfoWithId, ColValues, DocAction} from "./DocActions"; // TODO this replaces modelUtil's ActionDispatcher and bulkActionExpand. Those should be removed. /** * Helper class which provides a `dispatchAction` method that dispatches DocActions received from * the server to methods `this.on{ActionType}`, e.g. `this.onUpdateRecord`. * * Implementation methods `on*` are called with the action as the first argument, and with * the action arguments as additional method arguments, for convenience. * * Methods for bulk actions may be implemented directly, or will iterate through each record in * the action, and call the single-record methods for each one. */ export abstract class ActionDispatcher { public dispatchAction(action: DocAction): void { // In node 6 testing, this switch is 5+ times faster than looking up "on"+action[0]. const a: any[] = action; switch (action[0]) { case "AddRecord": return this.onAddRecord (action, a[1], a[2], a[3]); case "UpdateRecord": return this.onUpdateRecord (action, a[1], a[2], a[3]); case "RemoveRecord": return this.onRemoveRecord (action, a[1], a[2]); case "BulkAddRecord": return this.onBulkAddRecord (action, a[1], a[2], a[3]); case "BulkUpdateRecord": return this.onBulkUpdateRecord(action, a[1], a[2], a[3]); case "BulkRemoveRecord": return this.onBulkRemoveRecord(action, a[1], a[2]); case "ReplaceTableData": return this.onReplaceTableData(action, a[1], a[2], a[3]); case "AddColumn": return this.onAddColumn (action, a[1], a[2], a[3]); case "RemoveColumn": return this.onRemoveColumn (action, a[1], a[2]); case "RenameColumn": return this.onRenameColumn (action, a[1], a[2], a[3]); case "ModifyColumn": return this.onModifyColumn (action, a[1], a[2], a[3]); case "AddTable": return this.onAddTable (action, a[1], a[2]); case "RemoveTable": return this.onRemoveTable (action, a[1]); case "RenameTable": return this.onRenameTable (action, a[1], a[2]); default: throw new Error(`Received unknown action ${action[0]}`); } } protected abstract onAddRecord(action: DocAction, tableId: string, rowId: number, colValues: ColValues): void; protected abstract onUpdateRecord(action: DocAction, tableId: string, rowId: number, colValues: ColValues): void; protected abstract onRemoveRecord(action: DocAction, tableId: string, rowId: number): void; // If not overridden, these will make multiple calls to single-record action methods. protected onBulkAddRecord(action: DocAction, tableId: string, rowIds: number[], colValues: BulkColValues): void { for (let i = 0; i < rowIds.length; i++) { this.onAddRecord(action, tableId, rowIds[i], mapValues(colValues, (values) => values[i])); } } protected onBulkUpdateRecord(action: DocAction, tableId: string, rowIds: number[], colValues: BulkColValues): void { for (let i = 0; i < rowIds.length; i++) { this.onUpdateRecord(action, tableId, rowIds[i], mapValues(colValues, (values) => values[i])); } } protected onBulkRemoveRecord(action: DocAction, tableId: string, rowIds: number[]) { for (const r of rowIds) { this.onRemoveRecord(action, tableId, r); } } protected abstract onReplaceTableData( action: DocAction, tableId: string, rowIds: number[], colValues: BulkColValues): void; protected abstract onAddColumn(action: DocAction, tableId: string, colId: string, colInfo: ColInfo): void; protected abstract onRemoveColumn(action: DocAction, tableId: string, colId: string): void; protected abstract onRenameColumn(action: DocAction, tableId: string, oldColId: string, newColId: string): void; protected abstract onModifyColumn(action: DocAction, tableId: string, colId: string, colInfo: ColInfo): void; protected abstract onAddTable(action: DocAction, tableId: string, columns: ColInfoWithId[]): void; protected abstract onRemoveTable(action: DocAction, tableId: string): void; protected abstract onRenameTable(action: DocAction, oldTableId: string, newTableId: string): void; }