@vuu-ui/vuu-utils 2.1.19 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -95,10 +95,16 @@ class EditSession extends eventEmitter.EventEmitter {
95
95
  if (protocolMessageUtils.isRpcError(response)) return;
96
96
  const deletedKeys = response?.data?.deletedKeys;
97
97
  if (deletedKeys && deletedKeys.length > 0) {
98
+ let newCount = 0;
98
99
  for (const key of deletedKeys) {
99
- __privateGet(this, _deletedRows).add(key);
100
+ if (!__privateGet(this, _deletedRows).has(key)) {
101
+ __privateGet(this, _deletedRows).add(key);
102
+ newCount++;
103
+ }
104
+ }
105
+ if (newCount > 0) {
106
+ this.deleteCount = __privateGet(this, _deleteCount) + newCount;
100
107
  }
101
- this.deleteCount = __privateGet(this, _deleteCount) + deletedKeys.length;
102
108
  }
103
109
  }
104
110
  addRows(count = 15, rowData = {}) {
@@ -1 +1 @@
1
- {"version":3,"file":"EditSession.js","sources":["../../../../../../../packages/vuu-utils/src/data-editing/EditSession.tsx"],"sourcesContent":["import { CopyOption, DataSource, DeleteRowMode, DeleteSelectedRowsResult, EditApi, EditSessionMode, UndoRowChangeResult } from \"@vuu-ui/vuu-data-types\";\nimport type { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { EventEmitter } from \"../event-emitter\";\nimport { isRpcError } from \"../protocol-message-utils\";\n\nexport const isCopyOption = (mode?: EditSessionMode | CopyOption): mode is CopyOption =>\n mode === \"All\" || mode === \"Empty\" || mode === \"Selected\";\n\nexport type EditState = \"clean\" | \"dirty\" | \"invalid\" | \"stale\";\n\nexport class EditError extends Error {}\n\ntype CellEdit = {\n originalValue: VuuRowDataItemType;\n editedValue: VuuRowDataItemType;\n isValid?: boolean;\n isDeleted?: boolean;\n};\n\n// TODO can add more when when we know what the server implementation of error columns will look like\nexport class StaleUpdateError extends Error {}\n\ntype RowEditDetails = {\n /**\n * Column name => cell edit details\n */\n cellEdits: Map<string, CellEdit>;\n};\n\ntype EditSessionEvents = {\n editState: (editState: EditState) => void;\n};\n\nexport class EditSession extends EventEmitter<EditSessionEvents> {\n /**\n * Row key => row edits\n */\n #rowEdits = new Map<string, RowEditDetails>();\n #deletedRows = new Set<string>();\n #editCount = 0;\n #deleteCount = 0;\n #addCount = 0;\n #invalidCount = 0;\n #deleteMode: DeleteRowMode;\n #sourceTableDataSource?: EditApi;\n #sessionDataSource?: EditApi;\n #inEditMode = false;\n #endEditModePending = false;\n\n constructor(dataSource: EditApi, deleteMode: DeleteRowMode = \"soft\") {\n super();\n this.#sourceTableDataSource = dataSource;\n this.#deleteMode = deleteMode;\n }\n\n get editCount() {\n return this.#editCount;\n }\n\n set editCount(val: number) {\n if (val !== this.#editCount) {\n const oldCount = this.#editCount;\n this.#editCount = val;\n if (val === 0 && this.#deleteCount === 0 && this.#addCount === 0) {\n this.emit(\"editState\", \"clean\");\n } else if (oldCount === 0) {\n this.emit(\"editState\", \"dirty\");\n }\n }\n }\n\n get invalidCount() {\n return this.#invalidCount;\n }\n\n set invalidCount(val: number) {\n if (val !== this.#invalidCount) {\n const oldCount = this.#invalidCount;\n this.#invalidCount = val;\n if (val === 0) {\n this.emit(\"editState\", this.#editCount === 0 ? \"clean\" : \"dirty\");\n } else if (oldCount === 0) {\n this.emit(\"editState\", \"invalid\");\n }\n }\n }\n\n get deleteCount() {\n return this.#deleteCount;\n }\n\n set deleteCount(val: number) {\n if (val !== this.#deleteCount) {\n const oldCount = this.#deleteCount;\n this.#deleteCount = val;\n if (val === 0 && this.#editCount === 0 && this.#addCount === 0) {\n this.emit(\"editState\", \"clean\");\n } else if (oldCount === 0) {\n this.emit(\"editState\", \"dirty\");\n }\n }\n }\n\n get addCount() {\n return this.#addCount;\n }\n\n set addCount(val: number) {\n if (val !== this.#addCount) {\n const oldCount = this.#addCount;\n this.#addCount = val;\n if (val === 0 && this.#editCount === 0 && this.#deleteCount === 0) {\n this.emit(\"editState\", \"clean\");\n } else if (oldCount === 0) {\n this.emit(\"editState\", \"dirty\");\n }\n }\n }\n\n async deleteSelectedRows(): Promise<void> {\n const response = await this.dataSource?.deleteSelectedRows?.(this.#deleteMode);\n if (isRpcError(response)) return;\n const deletedKeys = (response?.data as DeleteSelectedRowsResult | undefined)\n ?.deletedKeys;\n if (deletedKeys && deletedKeys.length > 0) {\n for (const key of deletedKeys) {\n this.#deletedRows.add(key);\n }\n this.deleteCount = this.#deleteCount + deletedKeys.length;\n }\n }\n\n addRows(\n count = 15,\n rowData: Record<string, VuuRowDataItemType> = {},\n ) {\n for (let i = 0; i < count; i++) {\n this.#sourceTableDataSource?.addRow?.(rowData);\n }\n this.addCount = this.#addCount + count;\n }\n\n restoreRows(keys: string[]) {\n for (const key of keys) {\n if (this.#deletedRows.has(key)) {\n this.#deletedRows.delete(key);\n this.deleteCount = this.#deleteCount - 1;\n }\n }\n }\n\n hasRowChanges(key: string): boolean {\n return this.#rowEdits.has(key) || this.#deletedRows.has(key);\n }\n\n async undoRowChange(key: string): Promise<void> {\n if (!this.#inEditMode) return;\n\n const rowEdits = this.#rowEdits.get(key);\n const wasDeleted = this.#deletedRows.has(key);\n\n if (!rowEdits?.cellEdits.size && !wasDeleted) return;\n\n this.#rowEdits.delete(key);\n if (wasDeleted) this.#deletedRows.delete(key);\n\n const response = await this.dataSource?.undoRowChange?.(key);\n\n if (isRpcError(response)) {\n // Restore on failure\n if (rowEdits) this.#rowEdits.set(key, rowEdits);\n if (wasDeleted) this.#deletedRows.add(key);\n return;\n }\n\n // Update counters after confirmed success\n if (rowEdits) {\n let validCount = 0;\n let invalidCount = 0;\n for (const [, cellEdit] of rowEdits.cellEdits) {\n if (cellEdit.isValid === false) {\n invalidCount++;\n } else {\n validCount++;\n }\n }\n this.editCount = this.#editCount - validCount;\n this.invalidCount = this.#invalidCount - invalidCount;\n }\n if (wasDeleted) {\n this.deleteCount = this.#deleteCount - 1;\n }\n \n // If the server deleted a newly inserted row, decrement addCount\n const wasInsertedRow =\n (response?.data as UndoRowChangeResult | undefined)?.wasInsertedRow === true;\n if (wasInsertedRow) {\n this.addCount = this.#addCount - 1;\n }\n }\n\n clear() {\n this.#rowEdits.clear();\n this.#deletedRows.clear();\n this.#editCount = 0;\n this.#deleteCount = 0;\n this.#addCount = 0;\n this.#invalidCount = 0;\n this.#inEditMode = false;\n this.#endEditModePending = false;\n }\n\n /** @deprecated Pass a `CopyOption` (\"All\" | \"Empty\" | \"Selected\") to use `createSessionDataSource` instead. Long-form `EditSessionMode` values will be removed in a future release. */\n async begin(mode: EditSessionMode): Promise<DataSource | undefined>;\n async begin(mode?: CopyOption): Promise<DataSource | undefined>;\n async begin(mode?: EditSessionMode | CopyOption): Promise<DataSource | undefined> {\n try {\n this.#inEditMode = true;\n const sessionDataSource = isCopyOption(mode)\n ? await this.#sourceTableDataSource?.createSessionDataSource?.(mode)\n : await this.#sourceTableDataSource?.beginEditSession?.(mode);\n\n this.#sessionDataSource = sessionDataSource;\n return sessionDataSource;\n } catch (e) {\n this.#inEditMode = false;\n }\n }\n\n get dataSource() {\n return this.#sessionDataSource ?? this.#sourceTableDataSource;\n }\n\n async end(saveChanges = false, force = false) {\n try {\n if (this.#inEditMode) {\n this.#endEditModePending = true;\n await this.dataSource?.endEditSession?.(saveChanges, force);\n this.clear();\n }\n } catch (e) {\n this.#endEditModePending = false;\n if (e instanceof StaleUpdateError) {\n this.emit(\"editState\", \"stale\");\n } else {\n console.error(`[EditSession] ${(e as Error).message}`);\n }\n }\n }\n\n get inEditMode() {\n return this.#inEditMode === true && this.#endEditModePending === false;\n }\n\n get editState(): EditState {\n return this.editCount === 0 && this.#deleteCount === 0 && this.#addCount === 0\n ? \"clean\"\n : \"dirty\";\n }\n\n getOrCreateRowEdits(key: string): RowEditDetails {\n const rowEditDetails = this.#rowEdits.get(key);\n if (rowEditDetails) {\n return rowEditDetails;\n } else {\n const rowEditDetails = {\n cellEdits: new Map(),\n };\n this.#rowEdits.set(key, rowEditDetails);\n return rowEditDetails;\n }\n }\n\n storeCellEdit(\n cellEdits: Map<string, CellEdit>,\n column: string,\n originalValue: VuuRowDataItemType,\n editedValue: VuuRowDataItemType,\n isValid: boolean,\n ) {\n const cellEdit = cellEdits.get(column);\n if (cellEdit) {\n if (cellEdit.originalValue === editedValue) {\n cellEdits.delete(column);\n cellEdit.isDeleted = true;\n if (cellEdit.isValid) {\n this.editCount -= 1;\n } else {\n this.invalidCount -= 1;\n }\n } else {\n if (isValid && cellEdit.isValid === false) {\n cellEdit.isValid = true;\n cellEdit.editedValue = editedValue;\n // do not trigger the event, save it for the editCount\n this.#invalidCount -= 1;\n this.editCount += 1;\n }\n }\n return cellEdit;\n } else {\n const cellEdit: CellEdit = {\n originalValue,\n editedValue,\n isValid,\n };\n cellEdits.set(column, cellEdit);\n if (isValid) {\n this.editCount += 1;\n }\n return cellEdit;\n }\n }\n\n async commit(\n key: string,\n columnName: string,\n originalValue: VuuRowDataItemType,\n typedValue: string | number | boolean,\n isValid: boolean,\n ) {\n if (!this.#inEditMode) {\n throw new Error(\"No edit session in progress\");\n }\n const rowEditDetails = this.getOrCreateRowEdits(key);\n\n if (isValid) {\n const { cellEdits } = rowEditDetails;\n\n const cellEdit = this.storeCellEdit(\n cellEdits,\n columnName,\n originalValue,\n typedValue,\n isValid,\n );\n\n if (cellEdit.isDeleted) {\n if (rowEditDetails.cellEdits.size === 0) {\n this.#rowEdits.delete(key);\n }\n }\n\n if (this.dataSource?.editCell) {\n const response = await this.dataSource.editCell(\n key,\n columnName,\n typedValue,\n );\n if (isRpcError(response)) {\n cellEdit.isValid = false;\n this.invalidCount += 1;\n }\n\n return {\n editedDuringCurrentSession: cellEdit.originalValue !== typedValue,\n ...response,\n };\n }\n } else {\n const { cellEdits } = rowEditDetails;\n let cellEdit = cellEdits.get(columnName);\n if (cellEdit && cellEdit.isValid !== false) {\n cellEdit.isValid = false;\n this.invalidCount += 1;\n } else if (cellEdit === undefined) {\n cellEdit = this.storeCellEdit(\n cellEdits,\n columnName,\n originalValue,\n typedValue,\n isValid,\n );\n this.invalidCount += 1;\n }\n return { editedDuringCurrentSession: false };\n }\n }\n}\n"],"names":["EventEmitter","isRpcError","rowEditDetails","cellEdit"],"mappings":"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"}
1
+ {"version":3,"file":"EditSession.js","sources":["../../../../../../../packages/vuu-utils/src/data-editing/EditSession.tsx"],"sourcesContent":["import { CopyOption, DataSource, DeleteRowMode, DeleteSelectedRowsResult, EditApi, EditSessionMode, UndoRowChangeResult } from \"@vuu-ui/vuu-data-types\";\nimport type { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { EventEmitter } from \"../event-emitter\";\nimport { isRpcError } from \"../protocol-message-utils\";\n\nexport const isCopyOption = (mode?: EditSessionMode | CopyOption): mode is CopyOption =>\n mode === \"All\" || mode === \"Empty\" || mode === \"Selected\";\n\nexport type EditState = \"clean\" | \"dirty\" | \"invalid\" | \"stale\";\n\nexport class EditError extends Error {}\n\ntype CellEdit = {\n originalValue: VuuRowDataItemType;\n editedValue: VuuRowDataItemType;\n isValid?: boolean;\n isDeleted?: boolean;\n};\n\n// TODO can add more when when we know what the server implementation of error columns will look like\nexport class StaleUpdateError extends Error {}\n\ntype RowEditDetails = {\n /**\n * Column name => cell edit details\n */\n cellEdits: Map<string, CellEdit>;\n};\n\ntype EditSessionEvents = {\n editState: (editState: EditState) => void;\n};\n\nexport class EditSession extends EventEmitter<EditSessionEvents> {\n /**\n * Row key => row edits\n */\n #rowEdits = new Map<string, RowEditDetails>();\n #deletedRows = new Set<string>();\n #editCount = 0;\n #deleteCount = 0;\n #addCount = 0;\n #invalidCount = 0;\n #deleteMode: DeleteRowMode;\n #sourceTableDataSource?: EditApi;\n #sessionDataSource?: EditApi;\n #inEditMode = false;\n #endEditModePending = false;\n\n constructor(dataSource: EditApi, deleteMode: DeleteRowMode = \"soft\") {\n super();\n this.#sourceTableDataSource = dataSource;\n this.#deleteMode = deleteMode;\n }\n\n get editCount() {\n return this.#editCount;\n }\n\n set editCount(val: number) {\n if (val !== this.#editCount) {\n const oldCount = this.#editCount;\n this.#editCount = val;\n if (val === 0 && this.#deleteCount === 0 && this.#addCount === 0) {\n this.emit(\"editState\", \"clean\");\n } else if (oldCount === 0) {\n this.emit(\"editState\", \"dirty\");\n }\n }\n }\n\n get invalidCount() {\n return this.#invalidCount;\n }\n\n set invalidCount(val: number) {\n if (val !== this.#invalidCount) {\n const oldCount = this.#invalidCount;\n this.#invalidCount = val;\n if (val === 0) {\n this.emit(\"editState\", this.#editCount === 0 ? \"clean\" : \"dirty\");\n } else if (oldCount === 0) {\n this.emit(\"editState\", \"invalid\");\n }\n }\n }\n\n get deleteCount() {\n return this.#deleteCount;\n }\n\n set deleteCount(val: number) {\n if (val !== this.#deleteCount) {\n const oldCount = this.#deleteCount;\n this.#deleteCount = val;\n if (val === 0 && this.#editCount === 0 && this.#addCount === 0) {\n this.emit(\"editState\", \"clean\");\n } else if (oldCount === 0) {\n this.emit(\"editState\", \"dirty\");\n }\n }\n }\n\n get addCount() {\n return this.#addCount;\n }\n\n set addCount(val: number) {\n if (val !== this.#addCount) {\n const oldCount = this.#addCount;\n this.#addCount = val;\n if (val === 0 && this.#editCount === 0 && this.#deleteCount === 0) {\n this.emit(\"editState\", \"clean\");\n } else if (oldCount === 0) {\n this.emit(\"editState\", \"dirty\");\n }\n }\n }\n\n async deleteSelectedRows(): Promise<void> {\n const response = await this.dataSource?.deleteSelectedRows?.(this.#deleteMode);\n if (isRpcError(response)) return;\n const deletedKeys = (response?.data as DeleteSelectedRowsResult | undefined)\n ?.deletedKeys;\n if (deletedKeys && deletedKeys.length > 0) {\n let newCount = 0;\n for (const key of deletedKeys) {\n if (!this.#deletedRows.has(key)) {\n this.#deletedRows.add(key);\n newCount++;\n }\n }\n if (newCount > 0) {\n this.deleteCount = this.#deleteCount + newCount;\n }\n }\n }\n\n addRows(\n count = 15,\n rowData: Record<string, VuuRowDataItemType> = {},\n ) {\n for (let i = 0; i < count; i++) {\n this.#sourceTableDataSource?.addRow?.(rowData);\n }\n this.addCount = this.#addCount + count;\n }\n\n restoreRows(keys: string[]) {\n for (const key of keys) {\n if (this.#deletedRows.has(key)) {\n this.#deletedRows.delete(key);\n this.deleteCount = this.#deleteCount - 1;\n }\n }\n }\n\n hasRowChanges(key: string): boolean {\n return this.#rowEdits.has(key) || this.#deletedRows.has(key);\n }\n\n async undoRowChange(key: string): Promise<void> {\n if (!this.#inEditMode) return;\n\n const rowEdits = this.#rowEdits.get(key);\n const wasDeleted = this.#deletedRows.has(key);\n\n if (!rowEdits?.cellEdits.size && !wasDeleted) return;\n\n this.#rowEdits.delete(key);\n if (wasDeleted) this.#deletedRows.delete(key);\n\n const response = await this.dataSource?.undoRowChange?.(key);\n\n if (isRpcError(response)) {\n // Restore on failure\n if (rowEdits) this.#rowEdits.set(key, rowEdits);\n if (wasDeleted) this.#deletedRows.add(key);\n return;\n }\n\n // Update counters after confirmed success\n if (rowEdits) {\n let validCount = 0;\n let invalidCount = 0;\n for (const [, cellEdit] of rowEdits.cellEdits) {\n if (cellEdit.isValid === false) {\n invalidCount++;\n } else {\n validCount++;\n }\n }\n this.editCount = this.#editCount - validCount;\n this.invalidCount = this.#invalidCount - invalidCount;\n }\n if (wasDeleted) {\n this.deleteCount = this.#deleteCount - 1;\n }\n \n // If the server deleted a newly inserted row, decrement addCount\n const wasInsertedRow =\n (response?.data as UndoRowChangeResult | undefined)?.wasInsertedRow === true;\n if (wasInsertedRow) {\n this.addCount = this.#addCount - 1;\n }\n }\n\n clear() {\n this.#rowEdits.clear();\n this.#deletedRows.clear();\n this.#editCount = 0;\n this.#deleteCount = 0;\n this.#addCount = 0;\n this.#invalidCount = 0;\n this.#inEditMode = false;\n this.#endEditModePending = false;\n }\n\n /** @deprecated Pass a `CopyOption` (\"All\" | \"Empty\" | \"Selected\") to use `createSessionDataSource` instead. Long-form `EditSessionMode` values will be removed in a future release. */\n async begin(mode: EditSessionMode): Promise<DataSource | undefined>;\n async begin(mode?: CopyOption): Promise<DataSource | undefined>;\n async begin(mode?: EditSessionMode | CopyOption): Promise<DataSource | undefined> {\n try {\n this.#inEditMode = true;\n const sessionDataSource = isCopyOption(mode)\n ? await this.#sourceTableDataSource?.createSessionDataSource?.(mode)\n : await this.#sourceTableDataSource?.beginEditSession?.(mode);\n\n this.#sessionDataSource = sessionDataSource;\n return sessionDataSource;\n } catch (e) {\n this.#inEditMode = false;\n }\n }\n\n get dataSource() {\n return this.#sessionDataSource ?? this.#sourceTableDataSource;\n }\n\n async end(saveChanges = false, force = false) {\n try {\n if (this.#inEditMode) {\n this.#endEditModePending = true;\n await this.dataSource?.endEditSession?.(saveChanges, force);\n this.clear();\n }\n } catch (e) {\n this.#endEditModePending = false;\n if (e instanceof StaleUpdateError) {\n this.emit(\"editState\", \"stale\");\n } else {\n console.error(`[EditSession] ${(e as Error).message}`);\n }\n }\n }\n\n get inEditMode() {\n return this.#inEditMode === true && this.#endEditModePending === false;\n }\n\n get editState(): EditState {\n return this.editCount === 0 && this.#deleteCount === 0 && this.#addCount === 0\n ? \"clean\"\n : \"dirty\";\n }\n\n getOrCreateRowEdits(key: string): RowEditDetails {\n const rowEditDetails = this.#rowEdits.get(key);\n if (rowEditDetails) {\n return rowEditDetails;\n } else {\n const rowEditDetails = {\n cellEdits: new Map(),\n };\n this.#rowEdits.set(key, rowEditDetails);\n return rowEditDetails;\n }\n }\n\n storeCellEdit(\n cellEdits: Map<string, CellEdit>,\n column: string,\n originalValue: VuuRowDataItemType,\n editedValue: VuuRowDataItemType,\n isValid: boolean,\n ) {\n const cellEdit = cellEdits.get(column);\n if (cellEdit) {\n if (cellEdit.originalValue === editedValue) {\n cellEdits.delete(column);\n cellEdit.isDeleted = true;\n if (cellEdit.isValid) {\n this.editCount -= 1;\n } else {\n this.invalidCount -= 1;\n }\n } else {\n if (isValid && cellEdit.isValid === false) {\n cellEdit.isValid = true;\n cellEdit.editedValue = editedValue;\n // do not trigger the event, save it for the editCount\n this.#invalidCount -= 1;\n this.editCount += 1;\n }\n }\n return cellEdit;\n } else {\n const cellEdit: CellEdit = {\n originalValue,\n editedValue,\n isValid,\n };\n cellEdits.set(column, cellEdit);\n if (isValid) {\n this.editCount += 1;\n }\n return cellEdit;\n }\n }\n\n async commit(\n key: string,\n columnName: string,\n originalValue: VuuRowDataItemType,\n typedValue: string | number | boolean,\n isValid: boolean,\n ) {\n if (!this.#inEditMode) {\n throw new Error(\"No edit session in progress\");\n }\n const rowEditDetails = this.getOrCreateRowEdits(key);\n\n if (isValid) {\n const { cellEdits } = rowEditDetails;\n\n const cellEdit = this.storeCellEdit(\n cellEdits,\n columnName,\n originalValue,\n typedValue,\n isValid,\n );\n\n if (cellEdit.isDeleted) {\n if (rowEditDetails.cellEdits.size === 0) {\n this.#rowEdits.delete(key);\n }\n }\n\n if (this.dataSource?.editCell) {\n const response = await this.dataSource.editCell(\n key,\n columnName,\n typedValue,\n );\n if (isRpcError(response)) {\n cellEdit.isValid = false;\n this.invalidCount += 1;\n }\n\n return {\n editedDuringCurrentSession: cellEdit.originalValue !== typedValue,\n ...response,\n };\n }\n } else {\n const { cellEdits } = rowEditDetails;\n let cellEdit = cellEdits.get(columnName);\n if (cellEdit && cellEdit.isValid !== false) {\n cellEdit.isValid = false;\n this.invalidCount += 1;\n } else if (cellEdit === undefined) {\n cellEdit = this.storeCellEdit(\n cellEdits,\n columnName,\n originalValue,\n typedValue,\n isValid,\n );\n this.invalidCount += 1;\n }\n return { editedDuringCurrentSession: false };\n }\n }\n}\n"],"names":["EventEmitter","isRpcError","rowEditDetails","cellEdit"],"mappings":"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"}
@@ -19,6 +19,7 @@ const useEditableTable = ({
19
19
  const { VuuDataSource } = DataProvider.useData();
20
20
  const [sessionDataSource, setSessionDataSource] = React.useState(void 0);
21
21
  const [selectionCount, setSelectionCount] = React.useState(0);
22
+ const [deleteCount, setDeleteCount] = React.useState(0);
22
23
  useLayoutEffectSkipFirst.useLayoutEffectSkipFirst(() => {
23
24
  console.warn(`[useEditableTable] columns and or table changed`);
24
25
  }, [columns, table]);
@@ -80,12 +81,21 @@ const useEditableTable = ({
80
81
  activeDataSource.on("row-selection", setSelectionCount);
81
82
  return () => activeDataSource.removeListener("row-selection", setSelectionCount);
82
83
  }, [dataSource, sessionDataSource]);
84
+ React.useEffect(() => {
85
+ const syncDeleteCount = () => setDeleteCount(editSession.deleteCount);
86
+ editSession.on("editState", syncDeleteCount);
87
+ return () => editSession.removeListener("editState", syncDeleteCount);
88
+ }, [editSession]);
83
89
  React.useMemo(async () => {
84
90
  if (isEditMode) {
85
91
  try {
86
- const sessionDataSource2 = EditSession.isCopyOption(editSessionMode) ? await editSession.begin(editSessionMode) : await editSession.begin(editSessionMode);
87
- if (sessionDataSource2) {
88
- setSessionDataSource(sessionDataSource2);
92
+ const sessionDs = EditSession.isCopyOption(editSessionMode) ? await editSession.begin(editSessionMode) : await editSession.begin(editSessionMode);
93
+ if (sessionDs) {
94
+ setSessionDataSource(sessionDs);
95
+ } else {
96
+ console.warn(
97
+ `[useEditableTable] editSession.begin(${editSessionMode}) did not return a session DataSource`
98
+ );
89
99
  }
90
100
  } catch (e) {
91
101
  console.error(`[useEditableTable] begin edit session failed`, e);
@@ -100,7 +110,7 @@ const useEditableTable = ({
100
110
  return {
101
111
  dataSource,
102
112
  editSession,
103
- hasSelection: selectionCount > 0,
113
+ hasSelection: selectionCount > 0 || deleteCount > 0,
104
114
  onAddRows: handleAddRows,
105
115
  onCancel: handleCancel,
106
116
  onDelete: handleDelete,
@@ -1 +1 @@
1
- {"version":3,"file":"useEditableTable.js","sources":["../../../../../../../packages/vuu-utils/src/data-editing/useEditableTable.ts"],"sourcesContent":["import { CopyOption, DataSource, DeleteRowMode, EditApi, EditSessionMode } from \"@vuu-ui/vuu-data-types\";\nimport type { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useData } from \"../context-definitions/DataProvider\";\nimport { useLayoutEffectSkipFirst } from \"../useLayoutEffectSkipFirst\";\nimport { EditSession, isCopyOption } from \"./EditSession\";\n\nexport type EditMode = \"edit\" | \"view\";\n\nexport interface EditableTableHookProps {\n /**\n * columns to be included in subscription. If not provided,\n * default will be '*'. Ignored if dataSource prop present.\n */\n columns?: string[];\n dataSource?: DataSource;\n addRowsCount?: number;\n deleteMode?: DeleteRowMode;\n editSessionMode?: EditSessionMode | CopyOption;\n isEditMode: boolean;\n onCancel: () => void;\n onSave: () => void;\n /**\n * If dataSource not provided, new DataSource\n * will be created using table and columns\n */\n table?: VuuTable;\n}\n\nexport const useEditableTable = ({\n addRowsCount = 15,\n columns,\n dataSource: dataSourceProp,\n deleteMode = \"soft\",\n editSessionMode = \"inline-all-rows\" as EditSessionMode | CopyOption,\n isEditMode,\n onCancel,\n onSave,\n table,\n}: EditableTableHookProps) => {\n const { VuuDataSource } = useData();\n const [sessionDataSource, setSessionDataSource] = useState<\n DataSource | undefined\n >(undefined);\n const [selectionCount, setSelectionCount] = useState(0);\n useLayoutEffectSkipFirst(() => {\n console.warn(`[useEditableTable] columns and or table changed`);\n }, [columns, table]);\n\n const dataSource = useMemo(() => {\n if (dataSourceProp) {\n return dataSourceProp;\n } else if (table) {\n return new VuuDataSource({ columns, table });\n } else {\n throw Error(\n `useEditableTable unable to provide DataSource, neither dataSource nor table available as props`,\n );\n }\n }, [VuuDataSource, columns, dataSourceProp, table]);\n\n // The editSession will be made available to all the edit controls in scope\n // by wrapping the edit component with a DataEditingProvider.\n const editSession = useMemo(\n () => new EditSession(dataSource as EditApi, deleteMode),\n // deleteMode is intentionally excluded — changing it mid-session is not supported\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [dataSource],\n );\n\n const handleCancel = useCallback(async () => {\n try {\n await editSession.end();\n setSessionDataSource(undefined);\n setSelectionCount(0);\n onCancel();\n } catch (e) {\n //\n }\n }, [editSession, onCancel]);\n\n const handleSave = useCallback(\n async (force = false) => {\n dataSource.resume?.();\n try {\n await editSession.end(true, force);\n if (editSession.inEditMode === false) {\n setSessionDataSource(undefined);\n setSelectionCount(0);\n onSave();\n }\n } catch (e) {\n console.log(`[useEditableTable] handleSave ${(e as Error).message}`);\n }\n },\n [dataSource, editSession, onSave],\n );\n\n const handleDelete = useCallback(async () => {\n await editSession.deleteSelectedRows();\n setSelectionCount(0);\n }, [editSession]);\n\n const handleAddRows = useCallback(() => {\n editSession.addRows(addRowsCount);\n }, [addRowsCount, editSession]);\n\n const handleUndoRowChange = useCallback(\n (key: string) => void editSession.undoRowChange(key),\n [editSession],\n );\n\n useEffect(() => {\n const activeDataSource = sessionDataSource ?? dataSource;\n activeDataSource.on(\"row-selection\", setSelectionCount);\n return () => activeDataSource.removeListener(\"row-selection\", setSelectionCount);\n }, [dataSource, sessionDataSource]);\n\n useMemo(async () => {\n if (isEditMode) {\n try {\n const sessionDataSource = isCopyOption(editSessionMode)\n ? await editSession.begin(editSessionMode)\n : await editSession.begin(editSessionMode);\n if (sessionDataSource) {\n setSessionDataSource(sessionDataSource);\n }\n } catch (e) {\n console.error(`[useEditableTable] begin edit session failed`, e);\n onCancel();\n }\n } else if (editSession.inEditMode) {\n await editSession.end();\n setSessionDataSource(undefined);\n setSelectionCount(0);\n }\n }, [editSession, editSessionMode, isEditMode, onCancel]);\n\n return {\n dataSource,\n editSession,\n hasSelection: selectionCount > 0,\n onAddRows: handleAddRows,\n onCancel: handleCancel,\n onDelete: handleDelete,\n onSave: handleSave,\n onUndoRowChange: handleUndoRowChange,\n sessionDataSource,\n };\n};\n"],"names":["useData","useState","useLayoutEffectSkipFirst","useMemo","EditSession","useCallback","useEffect","sessionDataSource","isCopyOption"],"mappings":"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"}
1
+ {"version":3,"file":"useEditableTable.js","sources":["../../../../../../../packages/vuu-utils/src/data-editing/useEditableTable.ts"],"sourcesContent":["import { CopyOption, DataSource, DeleteRowMode, EditApi, EditSessionMode } from \"@vuu-ui/vuu-data-types\";\nimport type { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useData } from \"../context-definitions/DataProvider\";\nimport { useLayoutEffectSkipFirst } from \"../useLayoutEffectSkipFirst\";\nimport { EditSession, isCopyOption } from \"./EditSession\";\n\nexport type EditMode = \"edit\" | \"view\";\n\nexport interface EditableTableHookProps {\n /**\n * columns to be included in subscription. If not provided,\n * default will be '*'. Ignored if dataSource prop present.\n */\n columns?: string[];\n dataSource?: DataSource;\n addRowsCount?: number;\n deleteMode?: DeleteRowMode;\n editSessionMode?: EditSessionMode | CopyOption;\n isEditMode: boolean;\n onCancel: () => void;\n onSave: () => void;\n /**\n * If dataSource not provided, new DataSource\n * will be created using table and columns\n */\n table?: VuuTable;\n}\n\nexport const useEditableTable = ({\n addRowsCount = 15,\n columns,\n dataSource: dataSourceProp,\n deleteMode = \"soft\",\n editSessionMode = \"inline-all-rows\" as EditSessionMode | CopyOption,\n isEditMode,\n onCancel,\n onSave,\n table,\n}: EditableTableHookProps) => {\n const { VuuDataSource } = useData();\n const [sessionDataSource, setSessionDataSource] = useState<\n DataSource | undefined\n >(undefined);\n const [selectionCount, setSelectionCount] = useState(0);\n const [deleteCount, setDeleteCount] = useState(0);\n useLayoutEffectSkipFirst(() => {\n console.warn(`[useEditableTable] columns and or table changed`);\n }, [columns, table]);\n\n const dataSource = useMemo(() => {\n if (dataSourceProp) {\n return dataSourceProp;\n } else if (table) {\n return new VuuDataSource({ columns, table });\n } else {\n throw Error(\n `useEditableTable unable to provide DataSource, neither dataSource nor table available as props`,\n );\n }\n }, [VuuDataSource, columns, dataSourceProp, table]);\n\n // The editSession will be made available to all the edit controls in scope\n // by wrapping the edit component with a DataEditingProvider.\n const editSession = useMemo(\n () => new EditSession(dataSource as EditApi, deleteMode),\n // deleteMode is intentionally excluded — changing it mid-session is not supported\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [dataSource],\n );\n\n const handleCancel = useCallback(async () => {\n try {\n await editSession.end();\n setSessionDataSource(undefined);\n setSelectionCount(0);\n onCancel();\n } catch (e) {\n //\n }\n }, [editSession, onCancel]);\n\n const handleSave = useCallback(\n async (force = false) => {\n dataSource.resume?.();\n try {\n await editSession.end(true, force);\n if (editSession.inEditMode === false) {\n setSessionDataSource(undefined);\n setSelectionCount(0);\n onSave();\n }\n } catch (e) {\n console.log(`[useEditableTable] handleSave ${(e as Error).message}`);\n }\n },\n [dataSource, editSession, onSave],\n );\n\n const handleDelete = useCallback(async () => {\n await editSession.deleteSelectedRows();\n setSelectionCount(0);\n }, [editSession]);\n\n const handleAddRows = useCallback(() => {\n editSession.addRows(addRowsCount);\n }, [addRowsCount, editSession]);\n\n const handleUndoRowChange = useCallback(\n (key: string) => void editSession.undoRowChange(key),\n [editSession],\n );\n\n useEffect(() => {\n const activeDataSource = sessionDataSource ?? dataSource;\n activeDataSource.on(\"row-selection\", setSelectionCount);\n return () => activeDataSource.removeListener(\"row-selection\", setSelectionCount);\n }, [dataSource, sessionDataSource]);\n\n useEffect(() => {\n const syncDeleteCount = () => setDeleteCount(editSession.deleteCount);\n editSession.on(\"editState\", syncDeleteCount);\n return () => editSession.removeListener(\"editState\", syncDeleteCount);\n }, [editSession]);\n\n useMemo(async () => {\n if (isEditMode) {\n try {\n const sessionDs = isCopyOption(editSessionMode)\n ? await editSession.begin(editSessionMode)\n : await editSession.begin(editSessionMode);\n if (sessionDs) {\n setSessionDataSource(sessionDs);\n } else {\n console.warn(\n `[useEditableTable] editSession.begin(${editSessionMode}) did not return a session DataSource`,\n );\n }\n } catch (e) {\n console.error(`[useEditableTable] begin edit session failed`, e);\n onCancel();\n }\n } else if (editSession.inEditMode) {\n await editSession.end();\n setSessionDataSource(undefined);\n setSelectionCount(0);\n }\n }, [editSession, editSessionMode, isEditMode, onCancel]);\n\n return {\n dataSource,\n editSession,\n hasSelection: selectionCount > 0 || deleteCount > 0,\n onAddRows: handleAddRows,\n onCancel: handleCancel,\n onDelete: handleDelete,\n onSave: handleSave,\n onUndoRowChange: handleUndoRowChange,\n sessionDataSource,\n };\n};\n"],"names":["useData","useState","useLayoutEffectSkipFirst","useMemo","EditSession","useCallback","useEffect","isCopyOption"],"mappings":"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"}
@@ -414,6 +414,7 @@ exports.isVuuMenuRpcRequest = protocolMessageUtils.isVuuMenuRpcRequest;
414
414
  exports.NULL_RANGE = rangeUtils.NULL_RANGE;
415
415
  exports.Range = rangeUtils.Range;
416
416
  exports.WindowRange = rangeUtils.WindowRange;
417
+ exports.constrainRange = rangeUtils.constrainRange;
417
418
  exports.getFullRange = rangeUtils.getFullRange;
418
419
  exports.rangeNewItems = rangeUtils.rangeNewItems;
419
420
  exports.withinRange = rangeUtils.withinRange;
@@ -436,6 +437,7 @@ exports.ScaledDecimal6 = ScaledDecimal.ScaledDecimal6;
436
437
  exports.ScaledDecimal8 = ScaledDecimal.ScaledDecimal8;
437
438
  exports.deselectItem = selectionUtils.deselectItem;
438
439
  exports.selectItem = selectionUtils.selectItem;
440
+ exports.splitSelectableRanges = selectionUtils.splitSelectableRanges;
439
441
  exports.VuuShellLocation = shellLayoutTypes.VuuShellLocation;
440
442
  exports.addSortColumn = sortUtils.addSortColumn;
441
443
  exports.getSortStatus = sortUtils.getSortStatus;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -52,28 +52,28 @@ _baseTo = new WeakMap();
52
52
  let RangeImpl = _RangeImpl;
53
53
  const Range = (from, to, renderBufferSize) => new RangeImpl(from, to, renderBufferSize);
54
54
  const NULL_RANGE = Range(0, 0);
55
- function getFullRange({ from, to }, bufferSize = 0, totalRowCount = Number.MAX_SAFE_INTEGER) {
55
+ function getFullRange({ from, to }, bufferSize = 0, maxRangeEnd = Number.MAX_SAFE_INTEGER) {
56
56
  if (from === 0 && to === 0) {
57
57
  return { from, to };
58
58
  } else if (bufferSize === 0) {
59
- if (totalRowCount < from) {
59
+ if (maxRangeEnd < from) {
60
60
  return { from: 0, to: 0 };
61
61
  } else {
62
- return { from, to: Math.min(to, totalRowCount) };
62
+ return { from, to: Math.min(to, maxRangeEnd) };
63
63
  }
64
64
  } else if (from === 0) {
65
- return { from, to: Math.min(to + bufferSize, totalRowCount) };
65
+ return { from, to: Math.min(to + bufferSize, maxRangeEnd) };
66
66
  } else {
67
67
  const shortfallBefore = from - bufferSize < 0;
68
- const shortfallAfter = totalRowCount - (to + bufferSize) < 0;
68
+ const shortfallAfter = maxRangeEnd - (to + bufferSize) < 0;
69
69
  if (shortfallBefore && shortfallAfter) {
70
- return { from: 0, to: totalRowCount };
70
+ return { from: 0, to: maxRangeEnd };
71
71
  } else if (shortfallBefore) {
72
72
  return { from: 0, to: to + bufferSize };
73
73
  } else if (shortfallAfter) {
74
74
  return {
75
75
  from: Math.max(0, from - bufferSize),
76
- to: totalRowCount
76
+ to: maxRangeEnd
77
77
  };
78
78
  } else {
79
79
  return { from: from - bufferSize, to: to + bufferSize };
@@ -105,10 +105,35 @@ class WindowRange {
105
105
  return new WindowRange(this.from, this.to);
106
106
  }
107
107
  }
108
+ const constrainRangeWidth = (range, maxRangeWidth = Number.MAX_SAFE_INTEGER) => {
109
+ if (range.to - range.from < maxRangeWidth) {
110
+ return range;
111
+ }
112
+ console.warn(`[range-utils] range ${range.from} - ${range.to} exceeds maxRangeWidth ${maxRangeWidth} for this table `);
113
+ return {
114
+ from: range.from,
115
+ to: range.from + maxRangeWidth
116
+ };
117
+ };
118
+ const constrainRange = (range, maxRangeEnd, maxRangeWidth) => {
119
+ if (maxRangeEnd > 0 && maxRangeEnd < range.to) {
120
+ if (maxRangeEnd > range.from) {
121
+ return constrainRangeWidth({
122
+ from: range.from,
123
+ to: maxRangeEnd
124
+ }, maxRangeWidth);
125
+ } else {
126
+ throw Error(`constrainRange: cannot apply the maxRangeEnd ${maxRangeEnd} to range ${range.from} - ${range.to}`);
127
+ }
128
+ } else {
129
+ return constrainRangeWidth(range, maxRangeWidth);
130
+ }
131
+ };
108
132
 
109
133
  exports.NULL_RANGE = NULL_RANGE;
110
134
  exports.Range = Range;
111
135
  exports.WindowRange = WindowRange;
136
+ exports.constrainRange = constrainRange;
112
137
  exports.getFullRange = getFullRange;
113
138
  exports.rangeNewItems = rangeNewItems;
114
139
  exports.withinRange = withinRange;
@@ -1 +1 @@
1
- {"version":3,"file":"range-utils.js","sources":["../../../../../../packages/vuu-utils/src/range-utils.ts"],"sourcesContent":["import { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\n\ninterface FromToRange {\n from: number;\n to: number;\n}\n\nexport interface Range extends VuuRange {\n equals: (vuuRange: VuuRange) => boolean;\n reset: Range;\n withBuffer: VuuRange;\n}\n\nexport interface RangeOptions {\n renderBufferSize?: number;\n rowCount?: number;\n}\n\nclass RangeImpl implements Range {\n #baseFrom: number;\n #renderBufferSize = 0;\n #baseTo: number;\n\n // We have to keep from and to as simple public properties (not getters) so they survive structuredClone\n constructor(\n /** Index position of first visible row in viewport */\n public from: number,\n /** Index position of last visible row in viewport + 1 */\n public to: number,\n renderBufferSize = 0,\n ) {\n this.#baseFrom = from;\n this.#baseTo = to;\n this.#renderBufferSize = renderBufferSize;\n }\n\n get reset() {\n return new RangeImpl(\n 0,\n this.#baseTo - this.#baseFrom,\n this.#renderBufferSize,\n );\n }\n\n get withBuffer() {\n return getFullRange(this, this.#renderBufferSize);\n }\n\n equals(range: VuuRange) {\n return range.from === this.#baseFrom && range.to === this.#baseTo;\n }\n\n toJson() {\n return {\n from: this.from,\n to: this.to,\n baseFrom: this.#baseFrom,\n baseTo: this.#baseTo,\n renderBufferSize: this.#renderBufferSize,\n };\n }\n}\n\nexport const Range = (\n from: number,\n to: number,\n renderBufferSize?: number,\n): Range => new RangeImpl(from, to, renderBufferSize);\n\nexport const NULL_RANGE = Range(0, 0);\n\nexport function getFullRange(\n { from, to }: VuuRange,\n bufferSize = 0,\n totalRowCount: number = Number.MAX_SAFE_INTEGER,\n): FromToRange {\n if (from === 0 && to === 0) {\n return { from, to };\n } else if (bufferSize === 0) {\n if (totalRowCount < from) {\n return { from: 0, to: 0 };\n } else {\n return { from, to: Math.min(to, totalRowCount) };\n }\n } else if (from === 0) {\n return { from, to: Math.min(to + bufferSize, totalRowCount) };\n } else {\n const shortfallBefore = from - bufferSize < 0;\n const shortfallAfter = totalRowCount - (to + bufferSize) < 0;\n if (shortfallBefore && shortfallAfter) {\n return { from: 0, to: totalRowCount };\n } else if (shortfallBefore) {\n return { from: 0, to: to + bufferSize };\n } else if (shortfallAfter) {\n return {\n from: Math.max(0, from - bufferSize),\n to: totalRowCount,\n };\n } else {\n return { from: from - bufferSize, to: to + bufferSize };\n }\n }\n}\n\nexport const withinRange = (value: number, { from, to }: VuuRange) =>\n value >= from && value < to;\n\nexport const rangeNewItems = (\n { from: from1, to: to1 }: VuuRange,\n newRange: VuuRange,\n): VuuRange => {\n const { from: from2, to: to2 } = newRange;\n const noOverlap = from2 >= to1 || to2 <= from1;\n const newFullySubsumesOld = from2 < from1 && to2 > to1;\n return noOverlap || newFullySubsumesOld\n ? newRange\n : to2 > to1\n ? { from: to1, to: to2 }\n : { from: from2, to: from1 };\n};\n\nexport class WindowRange {\n public from: number;\n public to: number;\n\n constructor(from: number, to: number) {\n this.from = from;\n this.to = to;\n }\n\n public isWithin(index: number) {\n return withinRange(index, this);\n }\n\n //find the overlap of this range and a new one\n public overlap(from: number, to: number): [number, number] {\n return from >= this.to || to < this.from\n ? [0, 0]\n : [Math.max(from, this.from), Math.min(to, this.to)];\n }\n\n public copy(): WindowRange {\n return new WindowRange(this.from, this.to);\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"range-utils.js","sources":["../../../../../../packages/vuu-utils/src/range-utils.ts"],"sourcesContent":["import { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\n\ninterface FromToRange {\n from: number;\n to: number;\n}\n\nexport interface Range extends VuuRange {\n equals: (vuuRange: VuuRange) => boolean;\n reset: Range;\n withBuffer: VuuRange;\n}\n\nexport interface RangeOptions {\n renderBufferSize?: number;\n rowCount?: number;\n}\n\nclass RangeImpl implements Range {\n #baseFrom: number;\n #renderBufferSize = 0;\n #baseTo: number;\n\n // We have to keep from and to as simple public properties (not getters) so they survive structuredClone\n constructor(\n /** Index position of first visible row in viewport */\n public from: number,\n /** Index position of last visible row in viewport + 1 */\n public to: number,\n renderBufferSize = 0,\n ) {\n this.#baseFrom = from;\n this.#baseTo = to;\n this.#renderBufferSize = renderBufferSize;\n }\n\n get reset() {\n return new RangeImpl(\n 0,\n this.#baseTo - this.#baseFrom,\n this.#renderBufferSize,\n );\n }\n\n get withBuffer() {\n return getFullRange(this, this.#renderBufferSize);\n }\n\n equals(range: VuuRange) {\n return range.from === this.#baseFrom && range.to === this.#baseTo;\n }\n\n toJson() {\n return {\n from: this.from,\n to: this.to,\n baseFrom: this.#baseFrom,\n baseTo: this.#baseTo,\n renderBufferSize: this.#renderBufferSize,\n };\n }\n}\n\nexport const Range = (\n from: number,\n to: number,\n renderBufferSize?: number,\n): Range => new RangeImpl(from, to, renderBufferSize);\n\nexport const NULL_RANGE = Range(0, 0);\n\nexport function getFullRange(\n { from, to }: VuuRange,\n bufferSize = 0,\n maxRangeEnd: number = Number.MAX_SAFE_INTEGER,\n): FromToRange {\n if (from === 0 && to === 0) {\n return { from, to };\n } else if (bufferSize === 0) {\n if (maxRangeEnd < from) {\n return { from: 0, to: 0 };\n } else {\n return { from, to: Math.min(to, maxRangeEnd) };\n }\n } else if (from === 0) {\n return { from, to: Math.min(to + bufferSize, maxRangeEnd) };\n } else {\n const shortfallBefore = from - bufferSize < 0;\n const shortfallAfter = maxRangeEnd - (to + bufferSize) < 0;\n if (shortfallBefore && shortfallAfter) {\n return { from: 0, to: maxRangeEnd };\n } else if (shortfallBefore) {\n return { from: 0, to: to + bufferSize };\n } else if (shortfallAfter) {\n return {\n from: Math.max(0, from - bufferSize),\n to: maxRangeEnd,\n };\n } else {\n return { from: from - bufferSize, to: to + bufferSize };\n }\n }\n}\n\nexport const withinRange = (value: number, { from, to }: VuuRange) =>\n value >= from && value < to;\n\nexport const rangeNewItems = (\n { from: from1, to: to1 }: VuuRange,\n newRange: VuuRange,\n): VuuRange => {\n const { from: from2, to: to2 } = newRange;\n const noOverlap = from2 >= to1 || to2 <= from1;\n const newFullySubsumesOld = from2 < from1 && to2 > to1;\n return noOverlap || newFullySubsumesOld\n ? newRange\n : to2 > to1\n ? { from: to1, to: to2 }\n : { from: from2, to: from1 };\n};\n\nexport class WindowRange {\n public from: number;\n public to: number;\n\n constructor(from: number, to: number) {\n this.from = from;\n this.to = to;\n }\n\n public isWithin(index: number) {\n return withinRange(index, this);\n }\n\n //find the overlap of this range and a new one\n public overlap(from: number, to: number): [number, number] {\n return from >= this.to || to < this.from\n ? [0, 0]\n : [Math.max(from, this.from), Math.min(to, this.to)];\n }\n\n public copy(): WindowRange {\n return new WindowRange(this.from, this.to);\n }\n}\n\n\nconst constrainRangeWidth = (range: VuuRange, maxRangeWidth = Number.MAX_SAFE_INTEGER) => {\n if (range.to - range.from < maxRangeWidth) {\n return range;\n }\n console.warn(`[range-utils] range ${range.from} - ${range.to} exceeds maxRangeWidth ${maxRangeWidth} for this table `);\n return {\n from: range.from,\n to: range.from + maxRangeWidth\n }\n}\nexport const constrainRange = (range: VuuRange, maxRangeEnd: number, maxRangeWidth?: number) => {\n if (maxRangeEnd > 0 && maxRangeEnd < range.to) {\n if (maxRangeEnd > range.from) {\n return constrainRangeWidth({\n from: range.from,\n to: maxRangeEnd\n }, maxRangeWidth);\n } else {\n throw Error(`constrainRange: cannot apply the maxRangeEnd ${maxRangeEnd} to range ${range.from} - ${range.to}`);\n }\n } else {\n return constrainRangeWidth(range, maxRangeWidth);\n }\n}"],"names":[],"mappings":"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"}
@@ -28,7 +28,38 @@ const selectItem = (selectionModel, rowKey, rangeSelect, preserveExistingSelecti
28
28
  };
29
29
  }
30
30
  };
31
+ const splitSelectableRanges = (rows, isRowSelectable, preserveExistingSelection) => {
32
+ const requests = [];
33
+ let fromKey;
34
+ let toKey;
35
+ for (const row of rows) {
36
+ if (isRowSelectable(row)) {
37
+ if (!fromKey) fromKey = row.key;
38
+ toKey = row.key;
39
+ } else if (fromKey && toKey) {
40
+ requests.push({
41
+ type: "SELECT_ROW_RANGE",
42
+ fromRowKey: fromKey,
43
+ toRowKey: toKey,
44
+ // first sub-range respects the caller's preserve flag; subsequent ones must preserve
45
+ preserveExistingSelection: requests.length > 0 ? true : preserveExistingSelection
46
+ });
47
+ fromKey = void 0;
48
+ toKey = void 0;
49
+ }
50
+ }
51
+ if (fromKey && toKey) {
52
+ requests.push({
53
+ type: "SELECT_ROW_RANGE",
54
+ fromRowKey: fromKey,
55
+ toRowKey: toKey,
56
+ preserveExistingSelection: requests.length > 0 ? true : preserveExistingSelection
57
+ });
58
+ }
59
+ return requests;
60
+ };
31
61
 
32
62
  exports.deselectItem = deselectItem;
33
63
  exports.selectItem = selectItem;
64
+ exports.splitSelectableRanges = splitSelectableRanges;
34
65
  //# sourceMappingURL=selection-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"selection-utils.js","sources":["../../../../../../packages/vuu-utils/src/selection-utils.ts"],"sourcesContent":["import { TableSelectionModel } from \"@vuu-ui/vuu-table-types\";\nimport { SelectRequest } from \"@vuu-ui/vuu-protocol-types\";\n\nexport const deselectItem = (\n selectionModel: TableSelectionModel,\n rowKey: string,\n rangeSelect: boolean,\n preserveExistingSelection = false,\n): Omit<SelectRequest, \"vpId\"> | undefined => {\n return {\n preserveExistingSelection,\n rowKey,\n type: \"DESELECT_ROW\",\n } as Omit<SelectRequest, \"vpId\">;\n};\n\nexport const selectItem = (\n selectionModel: TableSelectionModel,\n rowKey: string,\n rangeSelect: boolean,\n preserveExistingSelection = false,\n activeRowKey?: string,\n): Omit<SelectRequest, \"vpId\"> | undefined => {\n const singleSelect =\n selectionModel === \"single\" || selectionModel === \"single-no-deselect\";\n const actsLikeSingleSelect = singleSelect || activeRowKey === undefined;\n\n if (selectionModel === \"none\") {\n return;\n } else if (actsLikeSingleSelect) {\n const preserveSelection = singleSelect ? false : preserveExistingSelection;\n return {\n preserveExistingSelection: preserveSelection,\n rowKey,\n type: \"SELECT_ROW\",\n } as Omit<SelectRequest, \"vpId\">;\n } else if (rangeSelect) {\n return {\n preserveExistingSelection,\n fromRowKey: rowKey,\n toRowKey: activeRowKey,\n type: \"SELECT_ROW_RANGE\",\n } as Omit<SelectRequest, \"vpId\">;\n }\n};\n"],"names":[],"mappings":";;AAGO,MAAM,eAAe,CAC1B,cAAA,EACA,MACA,EAAA,WAAA,EACA,4BAA4B,KACgB,KAAA;AAC5C,EAAO,OAAA;AAAA,IACL,yBAAA;AAAA,IACA,MAAA;AAAA,IACA,IAAM,EAAA;AAAA,GACR;AACF;AAEO,MAAM,aAAa,CACxB,cAAA,EACA,QACA,WACA,EAAA,yBAAA,GAA4B,OAC5B,YAC4C,KAAA;AAC5C,EAAM,MAAA,YAAA,GACJ,cAAmB,KAAA,QAAA,IAAY,cAAmB,KAAA,oBAAA;AACpD,EAAM,MAAA,oBAAA,GAAuB,gBAAgB,YAAiB,KAAA,KAAA,CAAA;AAE9D,EAAA,IAAI,mBAAmB,MAAQ,EAAA;AAC7B,IAAA;AAAA,aACS,oBAAsB,EAAA;AAC/B,IAAM,MAAA,iBAAA,GAAoB,eAAe,KAAQ,GAAA,yBAAA;AACjD,IAAO,OAAA;AAAA,MACL,yBAA2B,EAAA,iBAAA;AAAA,MAC3B,MAAA;AAAA,MACA,IAAM,EAAA;AAAA,KACR;AAAA,aACS,WAAa,EAAA;AACtB,IAAO,OAAA;AAAA,MACL,yBAAA;AAAA,MACA,UAAY,EAAA,MAAA;AAAA,MACZ,QAAU,EAAA,YAAA;AAAA,MACV,IAAM,EAAA;AAAA,KACR;AAAA;AAEJ;;;;;"}
1
+ {"version":3,"file":"selection-utils.js","sources":["../../../../../../packages/vuu-utils/src/selection-utils.ts"],"sourcesContent":["import { DataRow, TableSelectionModel } from \"@vuu-ui/vuu-table-types\";\nimport { SelectRequest } from \"@vuu-ui/vuu-protocol-types\";\n\nexport const deselectItem = (\n selectionModel: TableSelectionModel,\n rowKey: string,\n rangeSelect: boolean,\n preserveExistingSelection = false,\n): Omit<SelectRequest, \"vpId\"> | undefined => {\n return {\n preserveExistingSelection,\n rowKey,\n type: \"DESELECT_ROW\",\n } as Omit<SelectRequest, \"vpId\">;\n};\n\nexport const selectItem = (\n selectionModel: TableSelectionModel,\n rowKey: string,\n rangeSelect: boolean,\n preserveExistingSelection = false,\n activeRowKey?: string,\n): Omit<SelectRequest, \"vpId\"> | undefined => {\n const singleSelect =\n selectionModel === \"single\" || selectionModel === \"single-no-deselect\";\n const actsLikeSingleSelect = singleSelect || activeRowKey === undefined;\n\n if (selectionModel === \"none\") {\n return;\n } else if (actsLikeSingleSelect) {\n const preserveSelection = singleSelect ? false : preserveExistingSelection;\n return {\n preserveExistingSelection: preserveSelection,\n rowKey,\n type: \"SELECT_ROW\",\n } as Omit<SelectRequest, \"vpId\">;\n } else if (rangeSelect) {\n return {\n preserveExistingSelection,\n fromRowKey: rowKey,\n toRowKey: activeRowKey,\n type: \"SELECT_ROW_RANGE\",\n } as Omit<SelectRequest, \"vpId\">;\n }\n};\n\n/**\n * Split a row range into sub-ranges that exclude non-selectable rows.\n * Returns one SELECT_ROW_RANGE per consecutive run of selectable rows.\n */\nexport const splitSelectableRanges = (\n rows: DataRow[],\n isRowSelectable: (row: DataRow) => boolean,\n preserveExistingSelection: boolean,\n): Omit<SelectRequest, \"vpId\">[] => {\n const requests: Omit<SelectRequest, \"vpId\">[] = [];\n let fromKey: string | undefined;\n let toKey: string | undefined;\n\n for (const row of rows) {\n if (isRowSelectable(row)) {\n if (!fromKey) fromKey = row.key;\n toKey = row.key;\n } else if (fromKey && toKey) {\n requests.push({\n type: \"SELECT_ROW_RANGE\",\n fromRowKey: fromKey,\n toRowKey: toKey,\n // first sub-range respects the caller's preserve flag; subsequent ones must preserve\n preserveExistingSelection: requests.length > 0 ? true : preserveExistingSelection,\n } as Omit<SelectRequest, \"vpId\">);\n fromKey = undefined;\n toKey = undefined;\n }\n }\n if (fromKey && toKey) {\n requests.push({\n type: \"SELECT_ROW_RANGE\",\n fromRowKey: fromKey,\n toRowKey: toKey,\n preserveExistingSelection: requests.length > 0 ? true : preserveExistingSelection,\n } as Omit<SelectRequest, \"vpId\">);\n }\n return requests;\n};\n"],"names":[],"mappings":";;AAGO,MAAM,eAAe,CAC1B,cAAA,EACA,MACA,EAAA,WAAA,EACA,4BAA4B,KACgB,KAAA;AAC5C,EAAO,OAAA;AAAA,IACL,yBAAA;AAAA,IACA,MAAA;AAAA,IACA,IAAM,EAAA;AAAA,GACR;AACF;AAEO,MAAM,aAAa,CACxB,cAAA,EACA,QACA,WACA,EAAA,yBAAA,GAA4B,OAC5B,YAC4C,KAAA;AAC5C,EAAM,MAAA,YAAA,GACJ,cAAmB,KAAA,QAAA,IAAY,cAAmB,KAAA,oBAAA;AACpD,EAAM,MAAA,oBAAA,GAAuB,gBAAgB,YAAiB,KAAA,KAAA,CAAA;AAE9D,EAAA,IAAI,mBAAmB,MAAQ,EAAA;AAC7B,IAAA;AAAA,aACS,oBAAsB,EAAA;AAC/B,IAAM,MAAA,iBAAA,GAAoB,eAAe,KAAQ,GAAA,yBAAA;AACjD,IAAO,OAAA;AAAA,MACL,yBAA2B,EAAA,iBAAA;AAAA,MAC3B,MAAA;AAAA,MACA,IAAM,EAAA;AAAA,KACR;AAAA,aACS,WAAa,EAAA;AACtB,IAAO,OAAA;AAAA,MACL,yBAAA;AAAA,MACA,UAAY,EAAA,MAAA;AAAA,MACZ,QAAU,EAAA,YAAA;AAAA,MACV,IAAM,EAAA;AAAA,KACR;AAAA;AAEJ;AAMO,MAAM,qBAAwB,GAAA,CACnC,IACA,EAAA,eAAA,EACA,yBACkC,KAAA;AAClC,EAAA,MAAM,WAA0C,EAAC;AACjD,EAAI,IAAA,OAAA;AACJ,EAAI,IAAA,KAAA;AAEJ,EAAA,KAAA,MAAW,OAAO,IAAM,EAAA;AACtB,IAAI,IAAA,eAAA,CAAgB,GAAG,CAAG,EAAA;AACxB,MAAI,IAAA,CAAC,OAAS,EAAA,OAAA,GAAU,GAAI,CAAA,GAAA;AAC5B,MAAA,KAAA,GAAQ,GAAI,CAAA,GAAA;AAAA,KACd,MAAA,IAAW,WAAW,KAAO,EAAA;AAC3B,MAAA,QAAA,CAAS,IAAK,CAAA;AAAA,QACZ,IAAM,EAAA,kBAAA;AAAA,QACN,UAAY,EAAA,OAAA;AAAA,QACZ,QAAU,EAAA,KAAA;AAAA;AAAA,QAEV,yBAA2B,EAAA,QAAA,CAAS,MAAS,GAAA,CAAA,GAAI,IAAO,GAAA;AAAA,OAC1B,CAAA;AAChC,MAAU,OAAA,GAAA,KAAA,CAAA;AACV,MAAQ,KAAA,GAAA,KAAA,CAAA;AAAA;AACV;AAEF,EAAA,IAAI,WAAW,KAAO,EAAA;AACpB,IAAA,QAAA,CAAS,IAAK,CAAA;AAAA,MACZ,IAAM,EAAA,kBAAA;AAAA,MACN,UAAY,EAAA,OAAA;AAAA,MACZ,QAAU,EAAA,KAAA;AAAA,MACV,yBAA2B,EAAA,QAAA,CAAS,MAAS,GAAA,CAAA,GAAI,IAAO,GAAA;AAAA,KAC1B,CAAA;AAAA;AAElC,EAAO,OAAA,QAAA;AACT;;;;;;"}
@@ -93,10 +93,16 @@ class EditSession extends EventEmitter {
93
93
  if (isRpcError(response)) return;
94
94
  const deletedKeys = response?.data?.deletedKeys;
95
95
  if (deletedKeys && deletedKeys.length > 0) {
96
+ let newCount = 0;
96
97
  for (const key of deletedKeys) {
97
- __privateGet(this, _deletedRows).add(key);
98
+ if (!__privateGet(this, _deletedRows).has(key)) {
99
+ __privateGet(this, _deletedRows).add(key);
100
+ newCount++;
101
+ }
102
+ }
103
+ if (newCount > 0) {
104
+ this.deleteCount = __privateGet(this, _deleteCount) + newCount;
98
105
  }
99
- this.deleteCount = __privateGet(this, _deleteCount) + deletedKeys.length;
100
106
  }
101
107
  }
102
108
  addRows(count = 15, rowData = {}) {
@@ -1 +1 @@
1
- {"version":3,"file":"EditSession.js","sources":["../../../../../../../packages/vuu-utils/src/data-editing/EditSession.tsx"],"sourcesContent":["import { CopyOption, DataSource, DeleteRowMode, DeleteSelectedRowsResult, EditApi, EditSessionMode, UndoRowChangeResult } from \"@vuu-ui/vuu-data-types\";\nimport type { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { EventEmitter } from \"../event-emitter\";\nimport { isRpcError } from \"../protocol-message-utils\";\n\nexport const isCopyOption = (mode?: EditSessionMode | CopyOption): mode is CopyOption =>\n mode === \"All\" || mode === \"Empty\" || mode === \"Selected\";\n\nexport type EditState = \"clean\" | \"dirty\" | \"invalid\" | \"stale\";\n\nexport class EditError extends Error {}\n\ntype CellEdit = {\n originalValue: VuuRowDataItemType;\n editedValue: VuuRowDataItemType;\n isValid?: boolean;\n isDeleted?: boolean;\n};\n\n// TODO can add more when when we know what the server implementation of error columns will look like\nexport class StaleUpdateError extends Error {}\n\ntype RowEditDetails = {\n /**\n * Column name => cell edit details\n */\n cellEdits: Map<string, CellEdit>;\n};\n\ntype EditSessionEvents = {\n editState: (editState: EditState) => void;\n};\n\nexport class EditSession extends EventEmitter<EditSessionEvents> {\n /**\n * Row key => row edits\n */\n #rowEdits = new Map<string, RowEditDetails>();\n #deletedRows = new Set<string>();\n #editCount = 0;\n #deleteCount = 0;\n #addCount = 0;\n #invalidCount = 0;\n #deleteMode: DeleteRowMode;\n #sourceTableDataSource?: EditApi;\n #sessionDataSource?: EditApi;\n #inEditMode = false;\n #endEditModePending = false;\n\n constructor(dataSource: EditApi, deleteMode: DeleteRowMode = \"soft\") {\n super();\n this.#sourceTableDataSource = dataSource;\n this.#deleteMode = deleteMode;\n }\n\n get editCount() {\n return this.#editCount;\n }\n\n set editCount(val: number) {\n if (val !== this.#editCount) {\n const oldCount = this.#editCount;\n this.#editCount = val;\n if (val === 0 && this.#deleteCount === 0 && this.#addCount === 0) {\n this.emit(\"editState\", \"clean\");\n } else if (oldCount === 0) {\n this.emit(\"editState\", \"dirty\");\n }\n }\n }\n\n get invalidCount() {\n return this.#invalidCount;\n }\n\n set invalidCount(val: number) {\n if (val !== this.#invalidCount) {\n const oldCount = this.#invalidCount;\n this.#invalidCount = val;\n if (val === 0) {\n this.emit(\"editState\", this.#editCount === 0 ? \"clean\" : \"dirty\");\n } else if (oldCount === 0) {\n this.emit(\"editState\", \"invalid\");\n }\n }\n }\n\n get deleteCount() {\n return this.#deleteCount;\n }\n\n set deleteCount(val: number) {\n if (val !== this.#deleteCount) {\n const oldCount = this.#deleteCount;\n this.#deleteCount = val;\n if (val === 0 && this.#editCount === 0 && this.#addCount === 0) {\n this.emit(\"editState\", \"clean\");\n } else if (oldCount === 0) {\n this.emit(\"editState\", \"dirty\");\n }\n }\n }\n\n get addCount() {\n return this.#addCount;\n }\n\n set addCount(val: number) {\n if (val !== this.#addCount) {\n const oldCount = this.#addCount;\n this.#addCount = val;\n if (val === 0 && this.#editCount === 0 && this.#deleteCount === 0) {\n this.emit(\"editState\", \"clean\");\n } else if (oldCount === 0) {\n this.emit(\"editState\", \"dirty\");\n }\n }\n }\n\n async deleteSelectedRows(): Promise<void> {\n const response = await this.dataSource?.deleteSelectedRows?.(this.#deleteMode);\n if (isRpcError(response)) return;\n const deletedKeys = (response?.data as DeleteSelectedRowsResult | undefined)\n ?.deletedKeys;\n if (deletedKeys && deletedKeys.length > 0) {\n for (const key of deletedKeys) {\n this.#deletedRows.add(key);\n }\n this.deleteCount = this.#deleteCount + deletedKeys.length;\n }\n }\n\n addRows(\n count = 15,\n rowData: Record<string, VuuRowDataItemType> = {},\n ) {\n for (let i = 0; i < count; i++) {\n this.#sourceTableDataSource?.addRow?.(rowData);\n }\n this.addCount = this.#addCount + count;\n }\n\n restoreRows(keys: string[]) {\n for (const key of keys) {\n if (this.#deletedRows.has(key)) {\n this.#deletedRows.delete(key);\n this.deleteCount = this.#deleteCount - 1;\n }\n }\n }\n\n hasRowChanges(key: string): boolean {\n return this.#rowEdits.has(key) || this.#deletedRows.has(key);\n }\n\n async undoRowChange(key: string): Promise<void> {\n if (!this.#inEditMode) return;\n\n const rowEdits = this.#rowEdits.get(key);\n const wasDeleted = this.#deletedRows.has(key);\n\n if (!rowEdits?.cellEdits.size && !wasDeleted) return;\n\n this.#rowEdits.delete(key);\n if (wasDeleted) this.#deletedRows.delete(key);\n\n const response = await this.dataSource?.undoRowChange?.(key);\n\n if (isRpcError(response)) {\n // Restore on failure\n if (rowEdits) this.#rowEdits.set(key, rowEdits);\n if (wasDeleted) this.#deletedRows.add(key);\n return;\n }\n\n // Update counters after confirmed success\n if (rowEdits) {\n let validCount = 0;\n let invalidCount = 0;\n for (const [, cellEdit] of rowEdits.cellEdits) {\n if (cellEdit.isValid === false) {\n invalidCount++;\n } else {\n validCount++;\n }\n }\n this.editCount = this.#editCount - validCount;\n this.invalidCount = this.#invalidCount - invalidCount;\n }\n if (wasDeleted) {\n this.deleteCount = this.#deleteCount - 1;\n }\n \n // If the server deleted a newly inserted row, decrement addCount\n const wasInsertedRow =\n (response?.data as UndoRowChangeResult | undefined)?.wasInsertedRow === true;\n if (wasInsertedRow) {\n this.addCount = this.#addCount - 1;\n }\n }\n\n clear() {\n this.#rowEdits.clear();\n this.#deletedRows.clear();\n this.#editCount = 0;\n this.#deleteCount = 0;\n this.#addCount = 0;\n this.#invalidCount = 0;\n this.#inEditMode = false;\n this.#endEditModePending = false;\n }\n\n /** @deprecated Pass a `CopyOption` (\"All\" | \"Empty\" | \"Selected\") to use `createSessionDataSource` instead. Long-form `EditSessionMode` values will be removed in a future release. */\n async begin(mode: EditSessionMode): Promise<DataSource | undefined>;\n async begin(mode?: CopyOption): Promise<DataSource | undefined>;\n async begin(mode?: EditSessionMode | CopyOption): Promise<DataSource | undefined> {\n try {\n this.#inEditMode = true;\n const sessionDataSource = isCopyOption(mode)\n ? await this.#sourceTableDataSource?.createSessionDataSource?.(mode)\n : await this.#sourceTableDataSource?.beginEditSession?.(mode);\n\n this.#sessionDataSource = sessionDataSource;\n return sessionDataSource;\n } catch (e) {\n this.#inEditMode = false;\n }\n }\n\n get dataSource() {\n return this.#sessionDataSource ?? this.#sourceTableDataSource;\n }\n\n async end(saveChanges = false, force = false) {\n try {\n if (this.#inEditMode) {\n this.#endEditModePending = true;\n await this.dataSource?.endEditSession?.(saveChanges, force);\n this.clear();\n }\n } catch (e) {\n this.#endEditModePending = false;\n if (e instanceof StaleUpdateError) {\n this.emit(\"editState\", \"stale\");\n } else {\n console.error(`[EditSession] ${(e as Error).message}`);\n }\n }\n }\n\n get inEditMode() {\n return this.#inEditMode === true && this.#endEditModePending === false;\n }\n\n get editState(): EditState {\n return this.editCount === 0 && this.#deleteCount === 0 && this.#addCount === 0\n ? \"clean\"\n : \"dirty\";\n }\n\n getOrCreateRowEdits(key: string): RowEditDetails {\n const rowEditDetails = this.#rowEdits.get(key);\n if (rowEditDetails) {\n return rowEditDetails;\n } else {\n const rowEditDetails = {\n cellEdits: new Map(),\n };\n this.#rowEdits.set(key, rowEditDetails);\n return rowEditDetails;\n }\n }\n\n storeCellEdit(\n cellEdits: Map<string, CellEdit>,\n column: string,\n originalValue: VuuRowDataItemType,\n editedValue: VuuRowDataItemType,\n isValid: boolean,\n ) {\n const cellEdit = cellEdits.get(column);\n if (cellEdit) {\n if (cellEdit.originalValue === editedValue) {\n cellEdits.delete(column);\n cellEdit.isDeleted = true;\n if (cellEdit.isValid) {\n this.editCount -= 1;\n } else {\n this.invalidCount -= 1;\n }\n } else {\n if (isValid && cellEdit.isValid === false) {\n cellEdit.isValid = true;\n cellEdit.editedValue = editedValue;\n // do not trigger the event, save it for the editCount\n this.#invalidCount -= 1;\n this.editCount += 1;\n }\n }\n return cellEdit;\n } else {\n const cellEdit: CellEdit = {\n originalValue,\n editedValue,\n isValid,\n };\n cellEdits.set(column, cellEdit);\n if (isValid) {\n this.editCount += 1;\n }\n return cellEdit;\n }\n }\n\n async commit(\n key: string,\n columnName: string,\n originalValue: VuuRowDataItemType,\n typedValue: string | number | boolean,\n isValid: boolean,\n ) {\n if (!this.#inEditMode) {\n throw new Error(\"No edit session in progress\");\n }\n const rowEditDetails = this.getOrCreateRowEdits(key);\n\n if (isValid) {\n const { cellEdits } = rowEditDetails;\n\n const cellEdit = this.storeCellEdit(\n cellEdits,\n columnName,\n originalValue,\n typedValue,\n isValid,\n );\n\n if (cellEdit.isDeleted) {\n if (rowEditDetails.cellEdits.size === 0) {\n this.#rowEdits.delete(key);\n }\n }\n\n if (this.dataSource?.editCell) {\n const response = await this.dataSource.editCell(\n key,\n columnName,\n typedValue,\n );\n if (isRpcError(response)) {\n cellEdit.isValid = false;\n this.invalidCount += 1;\n }\n\n return {\n editedDuringCurrentSession: cellEdit.originalValue !== typedValue,\n ...response,\n };\n }\n } else {\n const { cellEdits } = rowEditDetails;\n let cellEdit = cellEdits.get(columnName);\n if (cellEdit && cellEdit.isValid !== false) {\n cellEdit.isValid = false;\n this.invalidCount += 1;\n } else if (cellEdit === undefined) {\n cellEdit = this.storeCellEdit(\n cellEdits,\n columnName,\n originalValue,\n typedValue,\n isValid,\n );\n this.invalidCount += 1;\n }\n return { editedDuringCurrentSession: false };\n }\n }\n}\n"],"names":["rowEditDetails","cellEdit"],"mappings":"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"}
1
+ {"version":3,"file":"EditSession.js","sources":["../../../../../../../packages/vuu-utils/src/data-editing/EditSession.tsx"],"sourcesContent":["import { CopyOption, DataSource, DeleteRowMode, DeleteSelectedRowsResult, EditApi, EditSessionMode, UndoRowChangeResult } from \"@vuu-ui/vuu-data-types\";\nimport type { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { EventEmitter } from \"../event-emitter\";\nimport { isRpcError } from \"../protocol-message-utils\";\n\nexport const isCopyOption = (mode?: EditSessionMode | CopyOption): mode is CopyOption =>\n mode === \"All\" || mode === \"Empty\" || mode === \"Selected\";\n\nexport type EditState = \"clean\" | \"dirty\" | \"invalid\" | \"stale\";\n\nexport class EditError extends Error {}\n\ntype CellEdit = {\n originalValue: VuuRowDataItemType;\n editedValue: VuuRowDataItemType;\n isValid?: boolean;\n isDeleted?: boolean;\n};\n\n// TODO can add more when when we know what the server implementation of error columns will look like\nexport class StaleUpdateError extends Error {}\n\ntype RowEditDetails = {\n /**\n * Column name => cell edit details\n */\n cellEdits: Map<string, CellEdit>;\n};\n\ntype EditSessionEvents = {\n editState: (editState: EditState) => void;\n};\n\nexport class EditSession extends EventEmitter<EditSessionEvents> {\n /**\n * Row key => row edits\n */\n #rowEdits = new Map<string, RowEditDetails>();\n #deletedRows = new Set<string>();\n #editCount = 0;\n #deleteCount = 0;\n #addCount = 0;\n #invalidCount = 0;\n #deleteMode: DeleteRowMode;\n #sourceTableDataSource?: EditApi;\n #sessionDataSource?: EditApi;\n #inEditMode = false;\n #endEditModePending = false;\n\n constructor(dataSource: EditApi, deleteMode: DeleteRowMode = \"soft\") {\n super();\n this.#sourceTableDataSource = dataSource;\n this.#deleteMode = deleteMode;\n }\n\n get editCount() {\n return this.#editCount;\n }\n\n set editCount(val: number) {\n if (val !== this.#editCount) {\n const oldCount = this.#editCount;\n this.#editCount = val;\n if (val === 0 && this.#deleteCount === 0 && this.#addCount === 0) {\n this.emit(\"editState\", \"clean\");\n } else if (oldCount === 0) {\n this.emit(\"editState\", \"dirty\");\n }\n }\n }\n\n get invalidCount() {\n return this.#invalidCount;\n }\n\n set invalidCount(val: number) {\n if (val !== this.#invalidCount) {\n const oldCount = this.#invalidCount;\n this.#invalidCount = val;\n if (val === 0) {\n this.emit(\"editState\", this.#editCount === 0 ? \"clean\" : \"dirty\");\n } else if (oldCount === 0) {\n this.emit(\"editState\", \"invalid\");\n }\n }\n }\n\n get deleteCount() {\n return this.#deleteCount;\n }\n\n set deleteCount(val: number) {\n if (val !== this.#deleteCount) {\n const oldCount = this.#deleteCount;\n this.#deleteCount = val;\n if (val === 0 && this.#editCount === 0 && this.#addCount === 0) {\n this.emit(\"editState\", \"clean\");\n } else if (oldCount === 0) {\n this.emit(\"editState\", \"dirty\");\n }\n }\n }\n\n get addCount() {\n return this.#addCount;\n }\n\n set addCount(val: number) {\n if (val !== this.#addCount) {\n const oldCount = this.#addCount;\n this.#addCount = val;\n if (val === 0 && this.#editCount === 0 && this.#deleteCount === 0) {\n this.emit(\"editState\", \"clean\");\n } else if (oldCount === 0) {\n this.emit(\"editState\", \"dirty\");\n }\n }\n }\n\n async deleteSelectedRows(): Promise<void> {\n const response = await this.dataSource?.deleteSelectedRows?.(this.#deleteMode);\n if (isRpcError(response)) return;\n const deletedKeys = (response?.data as DeleteSelectedRowsResult | undefined)\n ?.deletedKeys;\n if (deletedKeys && deletedKeys.length > 0) {\n let newCount = 0;\n for (const key of deletedKeys) {\n if (!this.#deletedRows.has(key)) {\n this.#deletedRows.add(key);\n newCount++;\n }\n }\n if (newCount > 0) {\n this.deleteCount = this.#deleteCount + newCount;\n }\n }\n }\n\n addRows(\n count = 15,\n rowData: Record<string, VuuRowDataItemType> = {},\n ) {\n for (let i = 0; i < count; i++) {\n this.#sourceTableDataSource?.addRow?.(rowData);\n }\n this.addCount = this.#addCount + count;\n }\n\n restoreRows(keys: string[]) {\n for (const key of keys) {\n if (this.#deletedRows.has(key)) {\n this.#deletedRows.delete(key);\n this.deleteCount = this.#deleteCount - 1;\n }\n }\n }\n\n hasRowChanges(key: string): boolean {\n return this.#rowEdits.has(key) || this.#deletedRows.has(key);\n }\n\n async undoRowChange(key: string): Promise<void> {\n if (!this.#inEditMode) return;\n\n const rowEdits = this.#rowEdits.get(key);\n const wasDeleted = this.#deletedRows.has(key);\n\n if (!rowEdits?.cellEdits.size && !wasDeleted) return;\n\n this.#rowEdits.delete(key);\n if (wasDeleted) this.#deletedRows.delete(key);\n\n const response = await this.dataSource?.undoRowChange?.(key);\n\n if (isRpcError(response)) {\n // Restore on failure\n if (rowEdits) this.#rowEdits.set(key, rowEdits);\n if (wasDeleted) this.#deletedRows.add(key);\n return;\n }\n\n // Update counters after confirmed success\n if (rowEdits) {\n let validCount = 0;\n let invalidCount = 0;\n for (const [, cellEdit] of rowEdits.cellEdits) {\n if (cellEdit.isValid === false) {\n invalidCount++;\n } else {\n validCount++;\n }\n }\n this.editCount = this.#editCount - validCount;\n this.invalidCount = this.#invalidCount - invalidCount;\n }\n if (wasDeleted) {\n this.deleteCount = this.#deleteCount - 1;\n }\n \n // If the server deleted a newly inserted row, decrement addCount\n const wasInsertedRow =\n (response?.data as UndoRowChangeResult | undefined)?.wasInsertedRow === true;\n if (wasInsertedRow) {\n this.addCount = this.#addCount - 1;\n }\n }\n\n clear() {\n this.#rowEdits.clear();\n this.#deletedRows.clear();\n this.#editCount = 0;\n this.#deleteCount = 0;\n this.#addCount = 0;\n this.#invalidCount = 0;\n this.#inEditMode = false;\n this.#endEditModePending = false;\n }\n\n /** @deprecated Pass a `CopyOption` (\"All\" | \"Empty\" | \"Selected\") to use `createSessionDataSource` instead. Long-form `EditSessionMode` values will be removed in a future release. */\n async begin(mode: EditSessionMode): Promise<DataSource | undefined>;\n async begin(mode?: CopyOption): Promise<DataSource | undefined>;\n async begin(mode?: EditSessionMode | CopyOption): Promise<DataSource | undefined> {\n try {\n this.#inEditMode = true;\n const sessionDataSource = isCopyOption(mode)\n ? await this.#sourceTableDataSource?.createSessionDataSource?.(mode)\n : await this.#sourceTableDataSource?.beginEditSession?.(mode);\n\n this.#sessionDataSource = sessionDataSource;\n return sessionDataSource;\n } catch (e) {\n this.#inEditMode = false;\n }\n }\n\n get dataSource() {\n return this.#sessionDataSource ?? this.#sourceTableDataSource;\n }\n\n async end(saveChanges = false, force = false) {\n try {\n if (this.#inEditMode) {\n this.#endEditModePending = true;\n await this.dataSource?.endEditSession?.(saveChanges, force);\n this.clear();\n }\n } catch (e) {\n this.#endEditModePending = false;\n if (e instanceof StaleUpdateError) {\n this.emit(\"editState\", \"stale\");\n } else {\n console.error(`[EditSession] ${(e as Error).message}`);\n }\n }\n }\n\n get inEditMode() {\n return this.#inEditMode === true && this.#endEditModePending === false;\n }\n\n get editState(): EditState {\n return this.editCount === 0 && this.#deleteCount === 0 && this.#addCount === 0\n ? \"clean\"\n : \"dirty\";\n }\n\n getOrCreateRowEdits(key: string): RowEditDetails {\n const rowEditDetails = this.#rowEdits.get(key);\n if (rowEditDetails) {\n return rowEditDetails;\n } else {\n const rowEditDetails = {\n cellEdits: new Map(),\n };\n this.#rowEdits.set(key, rowEditDetails);\n return rowEditDetails;\n }\n }\n\n storeCellEdit(\n cellEdits: Map<string, CellEdit>,\n column: string,\n originalValue: VuuRowDataItemType,\n editedValue: VuuRowDataItemType,\n isValid: boolean,\n ) {\n const cellEdit = cellEdits.get(column);\n if (cellEdit) {\n if (cellEdit.originalValue === editedValue) {\n cellEdits.delete(column);\n cellEdit.isDeleted = true;\n if (cellEdit.isValid) {\n this.editCount -= 1;\n } else {\n this.invalidCount -= 1;\n }\n } else {\n if (isValid && cellEdit.isValid === false) {\n cellEdit.isValid = true;\n cellEdit.editedValue = editedValue;\n // do not trigger the event, save it for the editCount\n this.#invalidCount -= 1;\n this.editCount += 1;\n }\n }\n return cellEdit;\n } else {\n const cellEdit: CellEdit = {\n originalValue,\n editedValue,\n isValid,\n };\n cellEdits.set(column, cellEdit);\n if (isValid) {\n this.editCount += 1;\n }\n return cellEdit;\n }\n }\n\n async commit(\n key: string,\n columnName: string,\n originalValue: VuuRowDataItemType,\n typedValue: string | number | boolean,\n isValid: boolean,\n ) {\n if (!this.#inEditMode) {\n throw new Error(\"No edit session in progress\");\n }\n const rowEditDetails = this.getOrCreateRowEdits(key);\n\n if (isValid) {\n const { cellEdits } = rowEditDetails;\n\n const cellEdit = this.storeCellEdit(\n cellEdits,\n columnName,\n originalValue,\n typedValue,\n isValid,\n );\n\n if (cellEdit.isDeleted) {\n if (rowEditDetails.cellEdits.size === 0) {\n this.#rowEdits.delete(key);\n }\n }\n\n if (this.dataSource?.editCell) {\n const response = await this.dataSource.editCell(\n key,\n columnName,\n typedValue,\n );\n if (isRpcError(response)) {\n cellEdit.isValid = false;\n this.invalidCount += 1;\n }\n\n return {\n editedDuringCurrentSession: cellEdit.originalValue !== typedValue,\n ...response,\n };\n }\n } else {\n const { cellEdits } = rowEditDetails;\n let cellEdit = cellEdits.get(columnName);\n if (cellEdit && cellEdit.isValid !== false) {\n cellEdit.isValid = false;\n this.invalidCount += 1;\n } else if (cellEdit === undefined) {\n cellEdit = this.storeCellEdit(\n cellEdits,\n columnName,\n originalValue,\n typedValue,\n isValid,\n );\n this.invalidCount += 1;\n }\n return { editedDuringCurrentSession: false };\n }\n }\n}\n"],"names":["rowEditDetails","cellEdit"],"mappings":"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"}
@@ -17,6 +17,7 @@ const useEditableTable = ({
17
17
  const { VuuDataSource } = useData();
18
18
  const [sessionDataSource, setSessionDataSource] = useState(void 0);
19
19
  const [selectionCount, setSelectionCount] = useState(0);
20
+ const [deleteCount, setDeleteCount] = useState(0);
20
21
  useLayoutEffectSkipFirst(() => {
21
22
  console.warn(`[useEditableTable] columns and or table changed`);
22
23
  }, [columns, table]);
@@ -78,12 +79,21 @@ const useEditableTable = ({
78
79
  activeDataSource.on("row-selection", setSelectionCount);
79
80
  return () => activeDataSource.removeListener("row-selection", setSelectionCount);
80
81
  }, [dataSource, sessionDataSource]);
82
+ useEffect(() => {
83
+ const syncDeleteCount = () => setDeleteCount(editSession.deleteCount);
84
+ editSession.on("editState", syncDeleteCount);
85
+ return () => editSession.removeListener("editState", syncDeleteCount);
86
+ }, [editSession]);
81
87
  useMemo(async () => {
82
88
  if (isEditMode) {
83
89
  try {
84
- const sessionDataSource2 = isCopyOption(editSessionMode) ? await editSession.begin(editSessionMode) : await editSession.begin(editSessionMode);
85
- if (sessionDataSource2) {
86
- setSessionDataSource(sessionDataSource2);
90
+ const sessionDs = isCopyOption(editSessionMode) ? await editSession.begin(editSessionMode) : await editSession.begin(editSessionMode);
91
+ if (sessionDs) {
92
+ setSessionDataSource(sessionDs);
93
+ } else {
94
+ console.warn(
95
+ `[useEditableTable] editSession.begin(${editSessionMode}) did not return a session DataSource`
96
+ );
87
97
  }
88
98
  } catch (e) {
89
99
  console.error(`[useEditableTable] begin edit session failed`, e);
@@ -98,7 +108,7 @@ const useEditableTable = ({
98
108
  return {
99
109
  dataSource,
100
110
  editSession,
101
- hasSelection: selectionCount > 0,
111
+ hasSelection: selectionCount > 0 || deleteCount > 0,
102
112
  onAddRows: handleAddRows,
103
113
  onCancel: handleCancel,
104
114
  onDelete: handleDelete,
@@ -1 +1 @@
1
- {"version":3,"file":"useEditableTable.js","sources":["../../../../../../../packages/vuu-utils/src/data-editing/useEditableTable.ts"],"sourcesContent":["import { CopyOption, DataSource, DeleteRowMode, EditApi, EditSessionMode } from \"@vuu-ui/vuu-data-types\";\nimport type { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useData } from \"../context-definitions/DataProvider\";\nimport { useLayoutEffectSkipFirst } from \"../useLayoutEffectSkipFirst\";\nimport { EditSession, isCopyOption } from \"./EditSession\";\n\nexport type EditMode = \"edit\" | \"view\";\n\nexport interface EditableTableHookProps {\n /**\n * columns to be included in subscription. If not provided,\n * default will be '*'. Ignored if dataSource prop present.\n */\n columns?: string[];\n dataSource?: DataSource;\n addRowsCount?: number;\n deleteMode?: DeleteRowMode;\n editSessionMode?: EditSessionMode | CopyOption;\n isEditMode: boolean;\n onCancel: () => void;\n onSave: () => void;\n /**\n * If dataSource not provided, new DataSource\n * will be created using table and columns\n */\n table?: VuuTable;\n}\n\nexport const useEditableTable = ({\n addRowsCount = 15,\n columns,\n dataSource: dataSourceProp,\n deleteMode = \"soft\",\n editSessionMode = \"inline-all-rows\" as EditSessionMode | CopyOption,\n isEditMode,\n onCancel,\n onSave,\n table,\n}: EditableTableHookProps) => {\n const { VuuDataSource } = useData();\n const [sessionDataSource, setSessionDataSource] = useState<\n DataSource | undefined\n >(undefined);\n const [selectionCount, setSelectionCount] = useState(0);\n useLayoutEffectSkipFirst(() => {\n console.warn(`[useEditableTable] columns and or table changed`);\n }, [columns, table]);\n\n const dataSource = useMemo(() => {\n if (dataSourceProp) {\n return dataSourceProp;\n } else if (table) {\n return new VuuDataSource({ columns, table });\n } else {\n throw Error(\n `useEditableTable unable to provide DataSource, neither dataSource nor table available as props`,\n );\n }\n }, [VuuDataSource, columns, dataSourceProp, table]);\n\n // The editSession will be made available to all the edit controls in scope\n // by wrapping the edit component with a DataEditingProvider.\n const editSession = useMemo(\n () => new EditSession(dataSource as EditApi, deleteMode),\n // deleteMode is intentionally excluded — changing it mid-session is not supported\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [dataSource],\n );\n\n const handleCancel = useCallback(async () => {\n try {\n await editSession.end();\n setSessionDataSource(undefined);\n setSelectionCount(0);\n onCancel();\n } catch (e) {\n //\n }\n }, [editSession, onCancel]);\n\n const handleSave = useCallback(\n async (force = false) => {\n dataSource.resume?.();\n try {\n await editSession.end(true, force);\n if (editSession.inEditMode === false) {\n setSessionDataSource(undefined);\n setSelectionCount(0);\n onSave();\n }\n } catch (e) {\n console.log(`[useEditableTable] handleSave ${(e as Error).message}`);\n }\n },\n [dataSource, editSession, onSave],\n );\n\n const handleDelete = useCallback(async () => {\n await editSession.deleteSelectedRows();\n setSelectionCount(0);\n }, [editSession]);\n\n const handleAddRows = useCallback(() => {\n editSession.addRows(addRowsCount);\n }, [addRowsCount, editSession]);\n\n const handleUndoRowChange = useCallback(\n (key: string) => void editSession.undoRowChange(key),\n [editSession],\n );\n\n useEffect(() => {\n const activeDataSource = sessionDataSource ?? dataSource;\n activeDataSource.on(\"row-selection\", setSelectionCount);\n return () => activeDataSource.removeListener(\"row-selection\", setSelectionCount);\n }, [dataSource, sessionDataSource]);\n\n useMemo(async () => {\n if (isEditMode) {\n try {\n const sessionDataSource = isCopyOption(editSessionMode)\n ? await editSession.begin(editSessionMode)\n : await editSession.begin(editSessionMode);\n if (sessionDataSource) {\n setSessionDataSource(sessionDataSource);\n }\n } catch (e) {\n console.error(`[useEditableTable] begin edit session failed`, e);\n onCancel();\n }\n } else if (editSession.inEditMode) {\n await editSession.end();\n setSessionDataSource(undefined);\n setSelectionCount(0);\n }\n }, [editSession, editSessionMode, isEditMode, onCancel]);\n\n return {\n dataSource,\n editSession,\n hasSelection: selectionCount > 0,\n onAddRows: handleAddRows,\n onCancel: handleCancel,\n onDelete: handleDelete,\n onSave: handleSave,\n onUndoRowChange: handleUndoRowChange,\n sessionDataSource,\n };\n};\n"],"names":["sessionDataSource"],"mappings":"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"}
1
+ {"version":3,"file":"useEditableTable.js","sources":["../../../../../../../packages/vuu-utils/src/data-editing/useEditableTable.ts"],"sourcesContent":["import { CopyOption, DataSource, DeleteRowMode, EditApi, EditSessionMode } from \"@vuu-ui/vuu-data-types\";\nimport type { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useData } from \"../context-definitions/DataProvider\";\nimport { useLayoutEffectSkipFirst } from \"../useLayoutEffectSkipFirst\";\nimport { EditSession, isCopyOption } from \"./EditSession\";\n\nexport type EditMode = \"edit\" | \"view\";\n\nexport interface EditableTableHookProps {\n /**\n * columns to be included in subscription. If not provided,\n * default will be '*'. Ignored if dataSource prop present.\n */\n columns?: string[];\n dataSource?: DataSource;\n addRowsCount?: number;\n deleteMode?: DeleteRowMode;\n editSessionMode?: EditSessionMode | CopyOption;\n isEditMode: boolean;\n onCancel: () => void;\n onSave: () => void;\n /**\n * If dataSource not provided, new DataSource\n * will be created using table and columns\n */\n table?: VuuTable;\n}\n\nexport const useEditableTable = ({\n addRowsCount = 15,\n columns,\n dataSource: dataSourceProp,\n deleteMode = \"soft\",\n editSessionMode = \"inline-all-rows\" as EditSessionMode | CopyOption,\n isEditMode,\n onCancel,\n onSave,\n table,\n}: EditableTableHookProps) => {\n const { VuuDataSource } = useData();\n const [sessionDataSource, setSessionDataSource] = useState<\n DataSource | undefined\n >(undefined);\n const [selectionCount, setSelectionCount] = useState(0);\n const [deleteCount, setDeleteCount] = useState(0);\n useLayoutEffectSkipFirst(() => {\n console.warn(`[useEditableTable] columns and or table changed`);\n }, [columns, table]);\n\n const dataSource = useMemo(() => {\n if (dataSourceProp) {\n return dataSourceProp;\n } else if (table) {\n return new VuuDataSource({ columns, table });\n } else {\n throw Error(\n `useEditableTable unable to provide DataSource, neither dataSource nor table available as props`,\n );\n }\n }, [VuuDataSource, columns, dataSourceProp, table]);\n\n // The editSession will be made available to all the edit controls in scope\n // by wrapping the edit component with a DataEditingProvider.\n const editSession = useMemo(\n () => new EditSession(dataSource as EditApi, deleteMode),\n // deleteMode is intentionally excluded — changing it mid-session is not supported\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [dataSource],\n );\n\n const handleCancel = useCallback(async () => {\n try {\n await editSession.end();\n setSessionDataSource(undefined);\n setSelectionCount(0);\n onCancel();\n } catch (e) {\n //\n }\n }, [editSession, onCancel]);\n\n const handleSave = useCallback(\n async (force = false) => {\n dataSource.resume?.();\n try {\n await editSession.end(true, force);\n if (editSession.inEditMode === false) {\n setSessionDataSource(undefined);\n setSelectionCount(0);\n onSave();\n }\n } catch (e) {\n console.log(`[useEditableTable] handleSave ${(e as Error).message}`);\n }\n },\n [dataSource, editSession, onSave],\n );\n\n const handleDelete = useCallback(async () => {\n await editSession.deleteSelectedRows();\n setSelectionCount(0);\n }, [editSession]);\n\n const handleAddRows = useCallback(() => {\n editSession.addRows(addRowsCount);\n }, [addRowsCount, editSession]);\n\n const handleUndoRowChange = useCallback(\n (key: string) => void editSession.undoRowChange(key),\n [editSession],\n );\n\n useEffect(() => {\n const activeDataSource = sessionDataSource ?? dataSource;\n activeDataSource.on(\"row-selection\", setSelectionCount);\n return () => activeDataSource.removeListener(\"row-selection\", setSelectionCount);\n }, [dataSource, sessionDataSource]);\n\n useEffect(() => {\n const syncDeleteCount = () => setDeleteCount(editSession.deleteCount);\n editSession.on(\"editState\", syncDeleteCount);\n return () => editSession.removeListener(\"editState\", syncDeleteCount);\n }, [editSession]);\n\n useMemo(async () => {\n if (isEditMode) {\n try {\n const sessionDs = isCopyOption(editSessionMode)\n ? await editSession.begin(editSessionMode)\n : await editSession.begin(editSessionMode);\n if (sessionDs) {\n setSessionDataSource(sessionDs);\n } else {\n console.warn(\n `[useEditableTable] editSession.begin(${editSessionMode}) did not return a session DataSource`,\n );\n }\n } catch (e) {\n console.error(`[useEditableTable] begin edit session failed`, e);\n onCancel();\n }\n } else if (editSession.inEditMode) {\n await editSession.end();\n setSessionDataSource(undefined);\n setSelectionCount(0);\n }\n }, [editSession, editSessionMode, isEditMode, onCancel]);\n\n return {\n dataSource,\n editSession,\n hasSelection: selectionCount > 0 || deleteCount > 0,\n onAddRows: handleAddRows,\n onCancel: handleCancel,\n onDelete: handleDelete,\n onSave: handleSave,\n onUndoRowChange: handleUndoRowChange,\n sessionDataSource,\n };\n};\n"],"names":[],"mappings":"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"}
@@ -48,12 +48,12 @@ export { uuid } from './nanoid/index.js';
48
48
  export { debounce, throttle } from './perf-utils.js';
49
49
  export { DeferredPromise } from './promise-utils.js';
50
50
  export { INVALID_SESSION, INVALID_TOKEN, SESSION_LIMIT_EXCEEDED, TOKEN_EXPIRED, hasViewPortContext, isActionMessage, isAddRowRpcRequest, isBeginEditSessionRpcRequest, isCreateSessionTableRpcRequest, isCreateVpSuccess, isCustomComponentActionMessage, isDeleteSelectedRowsRpcRequest, isEditCellRpcRequest, isEndEditSessionRpcRequest, isErrorMessage, isLoginErrorMessage, isLoginResponse, isNumericType, isOpenDialogAction, isOpenSessionTableDialogMessage, isRequestResponse, isRpcError, isRpcServiceRequest, isRpcSuccess, isSelectRequest, isSelectSuccessWithRowCount, isSessionTable, isSessionTableActionMessage, isTypeaheadRequest, isUndoRowChangeRpcRequest, isVuuMenuRpcRequest } from './protocol-message-utils.js';
51
- export { NULL_RANGE, Range, WindowRange, getFullRange, rangeNewItems, withinRange } from './range-utils.js';
51
+ export { NULL_RANGE, Range, WindowRange, constrainRange, getFullRange, rangeNewItems, withinRange } from './range-utils.js';
52
52
  export { asReactElements, createSyntheticEvent, isSimpleStateValue, useIsMounted, useStableReference } from './react-utils.js';
53
53
  export { exceedsMaxSafeInteger, roundDecimal, roundScaledDecimal } from './round-decimal.js';
54
54
  export { actualRowPositioning, asDataSourceRowObject, virtualRowPositioning, vuuRowToDataSourceRow } from './row-utils.js';
55
55
  export { ScaledDecimal, ScaledDecimal2, ScaledDecimal4, ScaledDecimal6, ScaledDecimal8 } from './ScaledDecimal.js';
56
- export { deselectItem, selectItem } from './selection-utils.js';
56
+ export { deselectItem, selectItem, splitSelectableRanges } from './selection-utils.js';
57
57
  export { VuuShellLocation } from './shell-layout-types.js';
58
58
  export { addSortColumn, getSortStatus, setSortColumn, toggleOrApplySort } from './sort-utils.js';
59
59
  export { getVuuTable } from './table-schema-utils.js';
@@ -50,28 +50,28 @@ _baseTo = new WeakMap();
50
50
  let RangeImpl = _RangeImpl;
51
51
  const Range = (from, to, renderBufferSize) => new RangeImpl(from, to, renderBufferSize);
52
52
  const NULL_RANGE = Range(0, 0);
53
- function getFullRange({ from, to }, bufferSize = 0, totalRowCount = Number.MAX_SAFE_INTEGER) {
53
+ function getFullRange({ from, to }, bufferSize = 0, maxRangeEnd = Number.MAX_SAFE_INTEGER) {
54
54
  if (from === 0 && to === 0) {
55
55
  return { from, to };
56
56
  } else if (bufferSize === 0) {
57
- if (totalRowCount < from) {
57
+ if (maxRangeEnd < from) {
58
58
  return { from: 0, to: 0 };
59
59
  } else {
60
- return { from, to: Math.min(to, totalRowCount) };
60
+ return { from, to: Math.min(to, maxRangeEnd) };
61
61
  }
62
62
  } else if (from === 0) {
63
- return { from, to: Math.min(to + bufferSize, totalRowCount) };
63
+ return { from, to: Math.min(to + bufferSize, maxRangeEnd) };
64
64
  } else {
65
65
  const shortfallBefore = from - bufferSize < 0;
66
- const shortfallAfter = totalRowCount - (to + bufferSize) < 0;
66
+ const shortfallAfter = maxRangeEnd - (to + bufferSize) < 0;
67
67
  if (shortfallBefore && shortfallAfter) {
68
- return { from: 0, to: totalRowCount };
68
+ return { from: 0, to: maxRangeEnd };
69
69
  } else if (shortfallBefore) {
70
70
  return { from: 0, to: to + bufferSize };
71
71
  } else if (shortfallAfter) {
72
72
  return {
73
73
  from: Math.max(0, from - bufferSize),
74
- to: totalRowCount
74
+ to: maxRangeEnd
75
75
  };
76
76
  } else {
77
77
  return { from: from - bufferSize, to: to + bufferSize };
@@ -103,6 +103,30 @@ class WindowRange {
103
103
  return new WindowRange(this.from, this.to);
104
104
  }
105
105
  }
106
+ const constrainRangeWidth = (range, maxRangeWidth = Number.MAX_SAFE_INTEGER) => {
107
+ if (range.to - range.from < maxRangeWidth) {
108
+ return range;
109
+ }
110
+ console.warn(`[range-utils] range ${range.from} - ${range.to} exceeds maxRangeWidth ${maxRangeWidth} for this table `);
111
+ return {
112
+ from: range.from,
113
+ to: range.from + maxRangeWidth
114
+ };
115
+ };
116
+ const constrainRange = (range, maxRangeEnd, maxRangeWidth) => {
117
+ if (maxRangeEnd > 0 && maxRangeEnd < range.to) {
118
+ if (maxRangeEnd > range.from) {
119
+ return constrainRangeWidth({
120
+ from: range.from,
121
+ to: maxRangeEnd
122
+ }, maxRangeWidth);
123
+ } else {
124
+ throw Error(`constrainRange: cannot apply the maxRangeEnd ${maxRangeEnd} to range ${range.from} - ${range.to}`);
125
+ }
126
+ } else {
127
+ return constrainRangeWidth(range, maxRangeWidth);
128
+ }
129
+ };
106
130
 
107
- export { NULL_RANGE, Range, WindowRange, getFullRange, rangeNewItems, withinRange };
131
+ export { NULL_RANGE, Range, WindowRange, constrainRange, getFullRange, rangeNewItems, withinRange };
108
132
  //# sourceMappingURL=range-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"range-utils.js","sources":["../../../../../../packages/vuu-utils/src/range-utils.ts"],"sourcesContent":["import { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\n\ninterface FromToRange {\n from: number;\n to: number;\n}\n\nexport interface Range extends VuuRange {\n equals: (vuuRange: VuuRange) => boolean;\n reset: Range;\n withBuffer: VuuRange;\n}\n\nexport interface RangeOptions {\n renderBufferSize?: number;\n rowCount?: number;\n}\n\nclass RangeImpl implements Range {\n #baseFrom: number;\n #renderBufferSize = 0;\n #baseTo: number;\n\n // We have to keep from and to as simple public properties (not getters) so they survive structuredClone\n constructor(\n /** Index position of first visible row in viewport */\n public from: number,\n /** Index position of last visible row in viewport + 1 */\n public to: number,\n renderBufferSize = 0,\n ) {\n this.#baseFrom = from;\n this.#baseTo = to;\n this.#renderBufferSize = renderBufferSize;\n }\n\n get reset() {\n return new RangeImpl(\n 0,\n this.#baseTo - this.#baseFrom,\n this.#renderBufferSize,\n );\n }\n\n get withBuffer() {\n return getFullRange(this, this.#renderBufferSize);\n }\n\n equals(range: VuuRange) {\n return range.from === this.#baseFrom && range.to === this.#baseTo;\n }\n\n toJson() {\n return {\n from: this.from,\n to: this.to,\n baseFrom: this.#baseFrom,\n baseTo: this.#baseTo,\n renderBufferSize: this.#renderBufferSize,\n };\n }\n}\n\nexport const Range = (\n from: number,\n to: number,\n renderBufferSize?: number,\n): Range => new RangeImpl(from, to, renderBufferSize);\n\nexport const NULL_RANGE = Range(0, 0);\n\nexport function getFullRange(\n { from, to }: VuuRange,\n bufferSize = 0,\n totalRowCount: number = Number.MAX_SAFE_INTEGER,\n): FromToRange {\n if (from === 0 && to === 0) {\n return { from, to };\n } else if (bufferSize === 0) {\n if (totalRowCount < from) {\n return { from: 0, to: 0 };\n } else {\n return { from, to: Math.min(to, totalRowCount) };\n }\n } else if (from === 0) {\n return { from, to: Math.min(to + bufferSize, totalRowCount) };\n } else {\n const shortfallBefore = from - bufferSize < 0;\n const shortfallAfter = totalRowCount - (to + bufferSize) < 0;\n if (shortfallBefore && shortfallAfter) {\n return { from: 0, to: totalRowCount };\n } else if (shortfallBefore) {\n return { from: 0, to: to + bufferSize };\n } else if (shortfallAfter) {\n return {\n from: Math.max(0, from - bufferSize),\n to: totalRowCount,\n };\n } else {\n return { from: from - bufferSize, to: to + bufferSize };\n }\n }\n}\n\nexport const withinRange = (value: number, { from, to }: VuuRange) =>\n value >= from && value < to;\n\nexport const rangeNewItems = (\n { from: from1, to: to1 }: VuuRange,\n newRange: VuuRange,\n): VuuRange => {\n const { from: from2, to: to2 } = newRange;\n const noOverlap = from2 >= to1 || to2 <= from1;\n const newFullySubsumesOld = from2 < from1 && to2 > to1;\n return noOverlap || newFullySubsumesOld\n ? newRange\n : to2 > to1\n ? { from: to1, to: to2 }\n : { from: from2, to: from1 };\n};\n\nexport class WindowRange {\n public from: number;\n public to: number;\n\n constructor(from: number, to: number) {\n this.from = from;\n this.to = to;\n }\n\n public isWithin(index: number) {\n return withinRange(index, this);\n }\n\n //find the overlap of this range and a new one\n public overlap(from: number, to: number): [number, number] {\n return from >= this.to || to < this.from\n ? [0, 0]\n : [Math.max(from, this.from), Math.min(to, this.to)];\n }\n\n public copy(): WindowRange {\n return new WindowRange(this.from, this.to);\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"range-utils.js","sources":["../../../../../../packages/vuu-utils/src/range-utils.ts"],"sourcesContent":["import { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\n\ninterface FromToRange {\n from: number;\n to: number;\n}\n\nexport interface Range extends VuuRange {\n equals: (vuuRange: VuuRange) => boolean;\n reset: Range;\n withBuffer: VuuRange;\n}\n\nexport interface RangeOptions {\n renderBufferSize?: number;\n rowCount?: number;\n}\n\nclass RangeImpl implements Range {\n #baseFrom: number;\n #renderBufferSize = 0;\n #baseTo: number;\n\n // We have to keep from and to as simple public properties (not getters) so they survive structuredClone\n constructor(\n /** Index position of first visible row in viewport */\n public from: number,\n /** Index position of last visible row in viewport + 1 */\n public to: number,\n renderBufferSize = 0,\n ) {\n this.#baseFrom = from;\n this.#baseTo = to;\n this.#renderBufferSize = renderBufferSize;\n }\n\n get reset() {\n return new RangeImpl(\n 0,\n this.#baseTo - this.#baseFrom,\n this.#renderBufferSize,\n );\n }\n\n get withBuffer() {\n return getFullRange(this, this.#renderBufferSize);\n }\n\n equals(range: VuuRange) {\n return range.from === this.#baseFrom && range.to === this.#baseTo;\n }\n\n toJson() {\n return {\n from: this.from,\n to: this.to,\n baseFrom: this.#baseFrom,\n baseTo: this.#baseTo,\n renderBufferSize: this.#renderBufferSize,\n };\n }\n}\n\nexport const Range = (\n from: number,\n to: number,\n renderBufferSize?: number,\n): Range => new RangeImpl(from, to, renderBufferSize);\n\nexport const NULL_RANGE = Range(0, 0);\n\nexport function getFullRange(\n { from, to }: VuuRange,\n bufferSize = 0,\n maxRangeEnd: number = Number.MAX_SAFE_INTEGER,\n): FromToRange {\n if (from === 0 && to === 0) {\n return { from, to };\n } else if (bufferSize === 0) {\n if (maxRangeEnd < from) {\n return { from: 0, to: 0 };\n } else {\n return { from, to: Math.min(to, maxRangeEnd) };\n }\n } else if (from === 0) {\n return { from, to: Math.min(to + bufferSize, maxRangeEnd) };\n } else {\n const shortfallBefore = from - bufferSize < 0;\n const shortfallAfter = maxRangeEnd - (to + bufferSize) < 0;\n if (shortfallBefore && shortfallAfter) {\n return { from: 0, to: maxRangeEnd };\n } else if (shortfallBefore) {\n return { from: 0, to: to + bufferSize };\n } else if (shortfallAfter) {\n return {\n from: Math.max(0, from - bufferSize),\n to: maxRangeEnd,\n };\n } else {\n return { from: from - bufferSize, to: to + bufferSize };\n }\n }\n}\n\nexport const withinRange = (value: number, { from, to }: VuuRange) =>\n value >= from && value < to;\n\nexport const rangeNewItems = (\n { from: from1, to: to1 }: VuuRange,\n newRange: VuuRange,\n): VuuRange => {\n const { from: from2, to: to2 } = newRange;\n const noOverlap = from2 >= to1 || to2 <= from1;\n const newFullySubsumesOld = from2 < from1 && to2 > to1;\n return noOverlap || newFullySubsumesOld\n ? newRange\n : to2 > to1\n ? { from: to1, to: to2 }\n : { from: from2, to: from1 };\n};\n\nexport class WindowRange {\n public from: number;\n public to: number;\n\n constructor(from: number, to: number) {\n this.from = from;\n this.to = to;\n }\n\n public isWithin(index: number) {\n return withinRange(index, this);\n }\n\n //find the overlap of this range and a new one\n public overlap(from: number, to: number): [number, number] {\n return from >= this.to || to < this.from\n ? [0, 0]\n : [Math.max(from, this.from), Math.min(to, this.to)];\n }\n\n public copy(): WindowRange {\n return new WindowRange(this.from, this.to);\n }\n}\n\n\nconst constrainRangeWidth = (range: VuuRange, maxRangeWidth = Number.MAX_SAFE_INTEGER) => {\n if (range.to - range.from < maxRangeWidth) {\n return range;\n }\n console.warn(`[range-utils] range ${range.from} - ${range.to} exceeds maxRangeWidth ${maxRangeWidth} for this table `);\n return {\n from: range.from,\n to: range.from + maxRangeWidth\n }\n}\nexport const constrainRange = (range: VuuRange, maxRangeEnd: number, maxRangeWidth?: number) => {\n if (maxRangeEnd > 0 && maxRangeEnd < range.to) {\n if (maxRangeEnd > range.from) {\n return constrainRangeWidth({\n from: range.from,\n to: maxRangeEnd\n }, maxRangeWidth);\n } else {\n throw Error(`constrainRange: cannot apply the maxRangeEnd ${maxRangeEnd} to range ${range.from} - ${range.to}`);\n }\n } else {\n return constrainRangeWidth(range, maxRangeWidth);\n }\n}"],"names":[],"mappings":"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"}
@@ -26,6 +26,36 @@ const selectItem = (selectionModel, rowKey, rangeSelect, preserveExistingSelecti
26
26
  };
27
27
  }
28
28
  };
29
+ const splitSelectableRanges = (rows, isRowSelectable, preserveExistingSelection) => {
30
+ const requests = [];
31
+ let fromKey;
32
+ let toKey;
33
+ for (const row of rows) {
34
+ if (isRowSelectable(row)) {
35
+ if (!fromKey) fromKey = row.key;
36
+ toKey = row.key;
37
+ } else if (fromKey && toKey) {
38
+ requests.push({
39
+ type: "SELECT_ROW_RANGE",
40
+ fromRowKey: fromKey,
41
+ toRowKey: toKey,
42
+ // first sub-range respects the caller's preserve flag; subsequent ones must preserve
43
+ preserveExistingSelection: requests.length > 0 ? true : preserveExistingSelection
44
+ });
45
+ fromKey = void 0;
46
+ toKey = void 0;
47
+ }
48
+ }
49
+ if (fromKey && toKey) {
50
+ requests.push({
51
+ type: "SELECT_ROW_RANGE",
52
+ fromRowKey: fromKey,
53
+ toRowKey: toKey,
54
+ preserveExistingSelection: requests.length > 0 ? true : preserveExistingSelection
55
+ });
56
+ }
57
+ return requests;
58
+ };
29
59
 
30
- export { deselectItem, selectItem };
60
+ export { deselectItem, selectItem, splitSelectableRanges };
31
61
  //# sourceMappingURL=selection-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"selection-utils.js","sources":["../../../../../../packages/vuu-utils/src/selection-utils.ts"],"sourcesContent":["import { TableSelectionModel } from \"@vuu-ui/vuu-table-types\";\nimport { SelectRequest } from \"@vuu-ui/vuu-protocol-types\";\n\nexport const deselectItem = (\n selectionModel: TableSelectionModel,\n rowKey: string,\n rangeSelect: boolean,\n preserveExistingSelection = false,\n): Omit<SelectRequest, \"vpId\"> | undefined => {\n return {\n preserveExistingSelection,\n rowKey,\n type: \"DESELECT_ROW\",\n } as Omit<SelectRequest, \"vpId\">;\n};\n\nexport const selectItem = (\n selectionModel: TableSelectionModel,\n rowKey: string,\n rangeSelect: boolean,\n preserveExistingSelection = false,\n activeRowKey?: string,\n): Omit<SelectRequest, \"vpId\"> | undefined => {\n const singleSelect =\n selectionModel === \"single\" || selectionModel === \"single-no-deselect\";\n const actsLikeSingleSelect = singleSelect || activeRowKey === undefined;\n\n if (selectionModel === \"none\") {\n return;\n } else if (actsLikeSingleSelect) {\n const preserveSelection = singleSelect ? false : preserveExistingSelection;\n return {\n preserveExistingSelection: preserveSelection,\n rowKey,\n type: \"SELECT_ROW\",\n } as Omit<SelectRequest, \"vpId\">;\n } else if (rangeSelect) {\n return {\n preserveExistingSelection,\n fromRowKey: rowKey,\n toRowKey: activeRowKey,\n type: \"SELECT_ROW_RANGE\",\n } as Omit<SelectRequest, \"vpId\">;\n }\n};\n"],"names":[],"mappings":"AAGO,MAAM,eAAe,CAC1B,cAAA,EACA,MACA,EAAA,WAAA,EACA,4BAA4B,KACgB,KAAA;AAC5C,EAAO,OAAA;AAAA,IACL,yBAAA;AAAA,IACA,MAAA;AAAA,IACA,IAAM,EAAA;AAAA,GACR;AACF;AAEO,MAAM,aAAa,CACxB,cAAA,EACA,QACA,WACA,EAAA,yBAAA,GAA4B,OAC5B,YAC4C,KAAA;AAC5C,EAAM,MAAA,YAAA,GACJ,cAAmB,KAAA,QAAA,IAAY,cAAmB,KAAA,oBAAA;AACpD,EAAM,MAAA,oBAAA,GAAuB,gBAAgB,YAAiB,KAAA,KAAA,CAAA;AAE9D,EAAA,IAAI,mBAAmB,MAAQ,EAAA;AAC7B,IAAA;AAAA,aACS,oBAAsB,EAAA;AAC/B,IAAM,MAAA,iBAAA,GAAoB,eAAe,KAAQ,GAAA,yBAAA;AACjD,IAAO,OAAA;AAAA,MACL,yBAA2B,EAAA,iBAAA;AAAA,MAC3B,MAAA;AAAA,MACA,IAAM,EAAA;AAAA,KACR;AAAA,aACS,WAAa,EAAA;AACtB,IAAO,OAAA;AAAA,MACL,yBAAA;AAAA,MACA,UAAY,EAAA,MAAA;AAAA,MACZ,QAAU,EAAA,YAAA;AAAA,MACV,IAAM,EAAA;AAAA,KACR;AAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"selection-utils.js","sources":["../../../../../../packages/vuu-utils/src/selection-utils.ts"],"sourcesContent":["import { DataRow, TableSelectionModel } from \"@vuu-ui/vuu-table-types\";\nimport { SelectRequest } from \"@vuu-ui/vuu-protocol-types\";\n\nexport const deselectItem = (\n selectionModel: TableSelectionModel,\n rowKey: string,\n rangeSelect: boolean,\n preserveExistingSelection = false,\n): Omit<SelectRequest, \"vpId\"> | undefined => {\n return {\n preserveExistingSelection,\n rowKey,\n type: \"DESELECT_ROW\",\n } as Omit<SelectRequest, \"vpId\">;\n};\n\nexport const selectItem = (\n selectionModel: TableSelectionModel,\n rowKey: string,\n rangeSelect: boolean,\n preserveExistingSelection = false,\n activeRowKey?: string,\n): Omit<SelectRequest, \"vpId\"> | undefined => {\n const singleSelect =\n selectionModel === \"single\" || selectionModel === \"single-no-deselect\";\n const actsLikeSingleSelect = singleSelect || activeRowKey === undefined;\n\n if (selectionModel === \"none\") {\n return;\n } else if (actsLikeSingleSelect) {\n const preserveSelection = singleSelect ? false : preserveExistingSelection;\n return {\n preserveExistingSelection: preserveSelection,\n rowKey,\n type: \"SELECT_ROW\",\n } as Omit<SelectRequest, \"vpId\">;\n } else if (rangeSelect) {\n return {\n preserveExistingSelection,\n fromRowKey: rowKey,\n toRowKey: activeRowKey,\n type: \"SELECT_ROW_RANGE\",\n } as Omit<SelectRequest, \"vpId\">;\n }\n};\n\n/**\n * Split a row range into sub-ranges that exclude non-selectable rows.\n * Returns one SELECT_ROW_RANGE per consecutive run of selectable rows.\n */\nexport const splitSelectableRanges = (\n rows: DataRow[],\n isRowSelectable: (row: DataRow) => boolean,\n preserveExistingSelection: boolean,\n): Omit<SelectRequest, \"vpId\">[] => {\n const requests: Omit<SelectRequest, \"vpId\">[] = [];\n let fromKey: string | undefined;\n let toKey: string | undefined;\n\n for (const row of rows) {\n if (isRowSelectable(row)) {\n if (!fromKey) fromKey = row.key;\n toKey = row.key;\n } else if (fromKey && toKey) {\n requests.push({\n type: \"SELECT_ROW_RANGE\",\n fromRowKey: fromKey,\n toRowKey: toKey,\n // first sub-range respects the caller's preserve flag; subsequent ones must preserve\n preserveExistingSelection: requests.length > 0 ? true : preserveExistingSelection,\n } as Omit<SelectRequest, \"vpId\">);\n fromKey = undefined;\n toKey = undefined;\n }\n }\n if (fromKey && toKey) {\n requests.push({\n type: \"SELECT_ROW_RANGE\",\n fromRowKey: fromKey,\n toRowKey: toKey,\n preserveExistingSelection: requests.length > 0 ? true : preserveExistingSelection,\n } as Omit<SelectRequest, \"vpId\">);\n }\n return requests;\n};\n"],"names":[],"mappings":"AAGO,MAAM,eAAe,CAC1B,cAAA,EACA,MACA,EAAA,WAAA,EACA,4BAA4B,KACgB,KAAA;AAC5C,EAAO,OAAA;AAAA,IACL,yBAAA;AAAA,IACA,MAAA;AAAA,IACA,IAAM,EAAA;AAAA,GACR;AACF;AAEO,MAAM,aAAa,CACxB,cAAA,EACA,QACA,WACA,EAAA,yBAAA,GAA4B,OAC5B,YAC4C,KAAA;AAC5C,EAAM,MAAA,YAAA,GACJ,cAAmB,KAAA,QAAA,IAAY,cAAmB,KAAA,oBAAA;AACpD,EAAM,MAAA,oBAAA,GAAuB,gBAAgB,YAAiB,KAAA,KAAA,CAAA;AAE9D,EAAA,IAAI,mBAAmB,MAAQ,EAAA;AAC7B,IAAA;AAAA,aACS,oBAAsB,EAAA;AAC/B,IAAM,MAAA,iBAAA,GAAoB,eAAe,KAAQ,GAAA,yBAAA;AACjD,IAAO,OAAA;AAAA,MACL,yBAA2B,EAAA,iBAAA;AAAA,MAC3B,MAAA;AAAA,MACA,IAAM,EAAA;AAAA,KACR;AAAA,aACS,WAAa,EAAA;AACtB,IAAO,OAAA;AAAA,MACL,yBAAA;AAAA,MACA,UAAY,EAAA,MAAA;AAAA,MACZ,QAAU,EAAA,YAAA;AAAA,MACV,IAAM,EAAA;AAAA,KACR;AAAA;AAEJ;AAMO,MAAM,qBAAwB,GAAA,CACnC,IACA,EAAA,eAAA,EACA,yBACkC,KAAA;AAClC,EAAA,MAAM,WAA0C,EAAC;AACjD,EAAI,IAAA,OAAA;AACJ,EAAI,IAAA,KAAA;AAEJ,EAAA,KAAA,MAAW,OAAO,IAAM,EAAA;AACtB,IAAI,IAAA,eAAA,CAAgB,GAAG,CAAG,EAAA;AACxB,MAAI,IAAA,CAAC,OAAS,EAAA,OAAA,GAAU,GAAI,CAAA,GAAA;AAC5B,MAAA,KAAA,GAAQ,GAAI,CAAA,GAAA;AAAA,KACd,MAAA,IAAW,WAAW,KAAO,EAAA;AAC3B,MAAA,QAAA,CAAS,IAAK,CAAA;AAAA,QACZ,IAAM,EAAA,kBAAA;AAAA,QACN,UAAY,EAAA,OAAA;AAAA,QACZ,QAAU,EAAA,KAAA;AAAA;AAAA,QAEV,yBAA2B,EAAA,QAAA,CAAS,MAAS,GAAA,CAAA,GAAI,IAAO,GAAA;AAAA,OAC1B,CAAA;AAChC,MAAU,OAAA,GAAA,KAAA,CAAA;AACV,MAAQ,KAAA,GAAA,KAAA,CAAA;AAAA;AACV;AAEF,EAAA,IAAI,WAAW,KAAO,EAAA;AACpB,IAAA,QAAA,CAAS,IAAK,CAAA;AAAA,MACZ,IAAM,EAAA,kBAAA;AAAA,MACN,UAAY,EAAA,OAAA;AAAA,MACZ,QAAU,EAAA,KAAA;AAAA,MACV,yBAA2B,EAAA,QAAA,CAAS,MAAS,GAAA,CAAA,GAAI,IAAO,GAAA;AAAA,KAC1B,CAAA;AAAA;AAElC,EAAO,OAAA,QAAA;AACT;;;;"}
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.1.19",
2
+ "version": "2.2.1",
3
3
  "author": "heswell",
4
4
  "license": "Apache-2.0",
5
5
  "types": "types/index.d.ts",
@@ -7,14 +7,14 @@
7
7
  "@salt-ds/core": "1.54.1"
8
8
  },
9
9
  "devDependencies": {
10
- "@vuu-ui/vuu-data-types": "2.1.19",
11
- "@vuu-ui/vuu-table-types": "2.1.19",
12
- "@vuu-ui/vuu-filter-types": "2.1.19",
13
- "@vuu-ui/vuu-protocol-types": "2.1.19"
10
+ "@vuu-ui/vuu-data-types": "2.2.1",
11
+ "@vuu-ui/vuu-table-types": "2.2.1",
12
+ "@vuu-ui/vuu-filter-types": "2.2.1",
13
+ "@vuu-ui/vuu-protocol-types": "2.2.1"
14
14
  },
15
15
  "peerDependencies": {
16
16
  "@internationalized/date": "^3.0.0",
17
- "@vuu-ui/vuu-filter-parser": "2.1.19",
17
+ "@vuu-ui/vuu-filter-parser": "2.2.1",
18
18
  "clsx": "^2.0.0",
19
19
  "react": "^19.2.3",
20
20
  "react-dom": "^19.2.3"
@@ -25,8 +25,8 @@ export declare const stripFilterFromColumns: (columns: RuntimeColumnDescriptor[]
25
25
  align?: "left" | "right";
26
26
  ariaColIndex: number;
27
27
  CellRenderer?: import("react").FunctionComponent<import("@vuu-ui/vuu-table-types").TableCellRendererProps>;
28
- HeaderCellLabelRenderer?: import("react").FunctionComponent<Omit<import("@vuu-ui/vuu-table-types").HeaderCellProps, "id" | "index">>;
29
28
  HeaderCellContentRenderer?: import("react").FunctionComponent<Omit<import("@vuu-ui/vuu-table-types").HeaderCellProps, "id" | "index">>;
29
+ HeaderCellLabelRenderer?: import("react").FunctionComponent<Omit<import("@vuu-ui/vuu-table-types").HeaderCellProps, "id" | "index">>;
30
30
  canStretch?: boolean;
31
31
  className?: string;
32
32
  clientSideEditValidationCheck?: import("@vuu-ui/vuu-data-types").DataValueValidationChecker;
@@ -14,7 +14,7 @@ export interface RangeOptions {
14
14
  }
15
15
  export declare const Range: (from: number, to: number, renderBufferSize?: number) => Range;
16
16
  export declare const NULL_RANGE: Range;
17
- export declare function getFullRange({ from, to }: VuuRange, bufferSize?: number, totalRowCount?: number): FromToRange;
17
+ export declare function getFullRange({ from, to }: VuuRange, bufferSize?: number, maxRangeEnd?: number): FromToRange;
18
18
  export declare const withinRange: (value: number, { from, to }: VuuRange) => boolean;
19
19
  export declare const rangeNewItems: ({ from: from1, to: to1 }: VuuRange, newRange: VuuRange) => VuuRange;
20
20
  export declare class WindowRange {
@@ -25,4 +25,5 @@ export declare class WindowRange {
25
25
  overlap(from: number, to: number): [number, number];
26
26
  copy(): WindowRange;
27
27
  }
28
+ export declare const constrainRange: (range: VuuRange, maxRangeEnd: number, maxRangeWidth?: number) => VuuRange;
28
29
  export {};
@@ -1,4 +1,9 @@
1
- import { TableSelectionModel } from "@vuu-ui/vuu-table-types";
1
+ import { DataRow, TableSelectionModel } from "@vuu-ui/vuu-table-types";
2
2
  import { SelectRequest } from "@vuu-ui/vuu-protocol-types";
3
3
  export declare const deselectItem: (selectionModel: TableSelectionModel, rowKey: string, rangeSelect: boolean, preserveExistingSelection?: boolean) => Omit<SelectRequest, "vpId"> | undefined;
4
4
  export declare const selectItem: (selectionModel: TableSelectionModel, rowKey: string, rangeSelect: boolean, preserveExistingSelection?: boolean, activeRowKey?: string) => Omit<SelectRequest, "vpId"> | undefined;
5
+ /**
6
+ * Split a row range into sub-ranges that exclude non-selectable rows.
7
+ * Returns one SELECT_ROW_RANGE per consecutive run of selectable rows.
8
+ */
9
+ export declare const splitSelectableRanges: (rows: DataRow[], isRowSelectable: (row: DataRow) => boolean, preserveExistingSelection: boolean) => Omit<SelectRequest, "vpId">[];