@vuu-ui/vuu-data-editing 3.2.0 → 3.3.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.
- package/package.json +6 -6
- package/src/EditSession.js +20 -4
- package/src/UndoCellRenderer.js +1 -1
- package/src/edit-utils.js +1 -1
- package/src/editActionRowClassNameGenerator.js +1 -1
- package/src/useEditableTable.js +8 -2
- package/types/EditSession.d.ts +14 -3
- package/types/index.d.ts +1 -1
- package/types/useEditableTable.d.ts +4 -2
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "3.
|
|
2
|
+
"version": "3.3.1",
|
|
3
3
|
"description": "Shared data editing APIs and React components for VUU UI",
|
|
4
4
|
"main": "./src/index.js",
|
|
5
5
|
"author": "heswell",
|
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@salt-ds/core": "1.54.1",
|
|
15
|
-
"@vuu-ui/vuu-ui-controls": "3.
|
|
16
|
-
"@vuu-ui/vuu-utils": "3.
|
|
15
|
+
"@vuu-ui/vuu-ui-controls": "3.3.1",
|
|
16
|
+
"@vuu-ui/vuu-utils": "3.3.1"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@vuu-ui/vuu-data-types": "3.
|
|
20
|
-
"@vuu-ui/vuu-protocol-types": "3.
|
|
21
|
-
"@vuu-ui/vuu-table-types": "3.
|
|
19
|
+
"@vuu-ui/vuu-data-types": "3.3.1",
|
|
20
|
+
"@vuu-ui/vuu-protocol-types": "3.3.1",
|
|
21
|
+
"@vuu-ui/vuu-table-types": "3.3.1"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
24
24
|
"react": "^19.2.3"
|
package/src/EditSession.js
CHANGED
|
@@ -28,6 +28,7 @@ class EditSession extends EventEmitter {
|
|
|
28
28
|
#cellCommitRevisions = new Map();
|
|
29
29
|
#deleteMode;
|
|
30
30
|
#editSessionApi;
|
|
31
|
+
#rowDefaults;
|
|
31
32
|
#sourceTableDataSource;
|
|
32
33
|
#sessionDataSource;
|
|
33
34
|
#newRowState = {
|
|
@@ -41,11 +42,12 @@ class EditSession extends EventEmitter {
|
|
|
41
42
|
status: "idle"
|
|
42
43
|
};
|
|
43
44
|
#transitionQueue = Promise.resolve();
|
|
44
|
-
constructor(dataSource, deleteMode = "soft", editSessionApi = "createSessionDataSource"){
|
|
45
|
+
constructor({ dataSource, deleteMode = "soft", editSessionApi = "createSessionDataSource", rowDefaults = {} }){
|
|
45
46
|
super();
|
|
46
47
|
this.#sourceTableDataSource = dataSource;
|
|
47
48
|
this.#deleteMode = deleteMode;
|
|
48
49
|
this.#editSessionApi = editSessionApi;
|
|
50
|
+
this.#rowDefaults = rowDefaults;
|
|
49
51
|
}
|
|
50
52
|
get editCount() {
|
|
51
53
|
return this.#editCount;
|
|
@@ -245,7 +247,10 @@ class EditSession extends EventEmitter {
|
|
|
245
247
|
async addRow(rowData = {}) {
|
|
246
248
|
const addRow = this.dataSource?.addRow;
|
|
247
249
|
if (void 0 === addRow) throw Error("[EditSession] datasource does not support adding rows");
|
|
248
|
-
const response = await addRow.call(this.dataSource,
|
|
250
|
+
const response = await addRow.call(this.dataSource, {
|
|
251
|
+
...this.#rowDefaults,
|
|
252
|
+
...rowData
|
|
253
|
+
});
|
|
249
254
|
if (void 0 === response) throw Error("[EditSession] datasource returned no response when adding row");
|
|
250
255
|
if (!isRpcError(response)) this.addCount = this.#addCount + 1;
|
|
251
256
|
return response;
|
|
@@ -334,7 +339,7 @@ class EditSession extends EventEmitter {
|
|
|
334
339
|
this.#transitionQueue = result.then(()=>void 0, ()=>void 0);
|
|
335
340
|
return result;
|
|
336
341
|
}
|
|
337
|
-
begin(copyOption = "All") {
|
|
342
|
+
begin(copyOption = "All", sessionType = "edit") {
|
|
338
343
|
return this.#enqueue(async ()=>{
|
|
339
344
|
if ("active" === this.#lifecycle.status || "error" === this.#lifecycle.status && "end" === this.#lifecycle.operation) {
|
|
340
345
|
const sessionDataSource = this.#sessionDataSource;
|
|
@@ -350,7 +355,7 @@ class EditSession extends EventEmitter {
|
|
|
350
355
|
});
|
|
351
356
|
try {
|
|
352
357
|
const sourceDataSource = this.#sourceTableDataSource;
|
|
353
|
-
const sessionDataSource = "beginEditSession" === this.#editSessionApi ? await sourceDataSource?.beginEditSession?.(toEditSessionMode(copyOption)) : await sourceDataSource?.createSessionDataSource?.(copyOption);
|
|
358
|
+
const sessionDataSource = "beginEditSession" === this.#editSessionApi ? await sourceDataSource?.beginEditSession?.(toEditSessionMode(copyOption)) : await sourceDataSource?.createSessionDataSource?.(copyOption, sessionType);
|
|
354
359
|
if (!sessionDataSource) throw new Error(`[EditSession] datasource does not support ${this.#editSessionApi}`);
|
|
355
360
|
this.#sessionDataSource = sessionDataSource;
|
|
356
361
|
this.#setStale(false);
|
|
@@ -358,6 +363,17 @@ class EditSession extends EventEmitter {
|
|
|
358
363
|
status: "active",
|
|
359
364
|
sessionDataSource
|
|
360
365
|
});
|
|
366
|
+
if (Object.keys(this.#rowDefaults).length > 0) {
|
|
367
|
+
const schema = sessionDataSource.tableSchema;
|
|
368
|
+
if (schema) {
|
|
369
|
+
const columnNames = new Set(schema.columns.map((c)=>c.name));
|
|
370
|
+
const unknown = Object.keys(this.#rowDefaults).filter((key)=>!columnNames.has(key));
|
|
371
|
+
if (unknown.length > 0) {
|
|
372
|
+
console.warn(`[EditSession] rowDefaults contains columns not in table schema, removing: ${unknown.join(", ")}`);
|
|
373
|
+
for (const key of unknown)delete this.#rowDefaults[key];
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
361
377
|
return sessionDataSource;
|
|
362
378
|
} catch (cause) {
|
|
363
379
|
const error = cause instanceof Error ? cause : new Error(String(cause));
|
package/src/UndoCellRenderer.js
CHANGED
|
@@ -13,7 +13,7 @@ const UndoCellRenderer = ({ column, dataRow })=>{
|
|
|
13
13
|
const editSession = useEditSession();
|
|
14
14
|
const renderer = column.type?.renderer;
|
|
15
15
|
const { icon, text } = getUndoButtonContent(renderer?.componentProps);
|
|
16
|
-
const tooltipContent = getUndoTooltipContent(dataRow.
|
|
16
|
+
const tooltipContent = getUndoTooltipContent(dataRow.vuuAction);
|
|
17
17
|
if (void 0 === tooltipContent) return null;
|
|
18
18
|
return /*#__PURE__*/ jsx(Tooltip, {
|
|
19
19
|
content: tooltipContent,
|
package/src/edit-utils.js
CHANGED
|
@@ -4,7 +4,7 @@ const timeFormatter = formatDate({
|
|
|
4
4
|
time: "hh:mm:ss"
|
|
5
5
|
});
|
|
6
6
|
const dataRowEditErrors = Symbol("vuuDataRowEditErrors");
|
|
7
|
-
const isEditRowReadOnly = (dataRow)=>"deleteRow" === dataRow.
|
|
7
|
+
const isEditRowReadOnly = (dataRow)=>"deleteRow" === dataRow.vuuAction;
|
|
8
8
|
const withDataRowEditErrors = (dataRow, errors)=>{
|
|
9
9
|
Object.defineProperty(dataRow, dataRowEditErrors, {
|
|
10
10
|
configurable: true,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { registerComponent } from "@vuu-ui/vuu-utils";
|
|
2
2
|
const EDIT_ACTION_ROW_CLASS_NAME_GENERATOR = "vuu-edit-actions";
|
|
3
3
|
const editActionRowClassNameGenerator = (dataRow)=>{
|
|
4
|
-
switch(dataRow.
|
|
4
|
+
switch(dataRow.vuuAction){
|
|
5
5
|
case "addRow":
|
|
6
6
|
return "vuuTableRow-inserted";
|
|
7
7
|
case "deleteRow":
|
package/src/useEditableTable.js
CHANGED
|
@@ -5,7 +5,7 @@ import { EDIT_ACTION_ROW_CLASS_NAME_GENERATOR } from "./editActionRowClassNameGe
|
|
|
5
5
|
const EDIT_ACTION_ROW_CLASS_NAME_GENERATORS = [
|
|
6
6
|
EDIT_ACTION_ROW_CLASS_NAME_GENERATOR
|
|
7
7
|
];
|
|
8
|
-
const useEditableTable = ({ columns, dataSource: dataSourceProp, deleteMode = "soft", editSessionApi = "createSessionDataSource", copyOption = "All", isEditMode, onCancel, onSave, table })=>{
|
|
8
|
+
const useEditableTable = ({ columns, dataSource: dataSourceProp, deleteMode = "soft", editSessionApi = "createSessionDataSource", copyOption = "All", isEditMode, onCancel, onSave, rowDefaults, table })=>{
|
|
9
9
|
const { VuuDataSource } = useData();
|
|
10
10
|
const [selectionCount, setSelectionCount] = useState(0);
|
|
11
11
|
useLayoutEffectSkipFirst(()=>{
|
|
@@ -27,9 +27,15 @@ const useEditableTable = ({ columns, dataSource: dataSourceProp, deleteMode = "s
|
|
|
27
27
|
dataSourceProp,
|
|
28
28
|
table
|
|
29
29
|
]);
|
|
30
|
-
const editSession = useMemo(()=>new EditSession(
|
|
30
|
+
const editSession = useMemo(()=>new EditSession({
|
|
31
|
+
dataSource: sourceDataSource,
|
|
32
|
+
deleteMode,
|
|
33
|
+
editSessionApi,
|
|
34
|
+
rowDefaults
|
|
35
|
+
}), [
|
|
31
36
|
deleteMode,
|
|
32
37
|
editSessionApi,
|
|
38
|
+
rowDefaults,
|
|
33
39
|
sourceDataSource
|
|
34
40
|
]);
|
|
35
41
|
const [lifecycle, setLifecycle] = useState(editSession.lifecycle);
|
package/types/EditSession.d.ts
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
|
-
import type { CopyOption, DataSource, DeleteRowMode, EditApi } from "@vuu-ui/vuu-data-types";
|
|
1
|
+
import type { CopyOption, DataSource, DeleteRowMode, EditApi, SessionType } from "@vuu-ui/vuu-data-types";
|
|
2
2
|
import type { RpcResult, VuuRowDataItemType } from "@vuu-ui/vuu-protocol-types";
|
|
3
3
|
import { EventEmitter } from "@vuu-ui/vuu-utils";
|
|
4
4
|
export type EditState = "clean" | "dirty" | "invalid" | "stale";
|
|
5
|
+
/** Column name to default value mapping applied to every addRow call when a column is absent from the row data. */
|
|
6
|
+
export type RowDefaultDataItemValues = Record<string, VuuRowDataItemType>;
|
|
5
7
|
export type EditSessionApi = "createSessionDataSource" | "beginEditSession";
|
|
8
|
+
export type EditSessionConstructorProps = {
|
|
9
|
+
dataSource: EditApi;
|
|
10
|
+
/** @default "soft" */
|
|
11
|
+
deleteMode?: DeleteRowMode;
|
|
12
|
+
/** @default "createSessionDataSource" */
|
|
13
|
+
editSessionApi?: EditSessionApi;
|
|
14
|
+
/** Default column values merged into every addRow call for absent columns. Pass a stable reference. */
|
|
15
|
+
rowDefaults?: RowDefaultDataItemValues;
|
|
16
|
+
};
|
|
6
17
|
export type NewRowState = {
|
|
7
18
|
columns: readonly string[];
|
|
8
19
|
draftRevision: number;
|
|
@@ -39,7 +50,7 @@ type EditSessionEvents = {
|
|
|
39
50
|
export declare class EditSession extends EventEmitter<EditSessionEvents> {
|
|
40
51
|
#private;
|
|
41
52
|
static readonly newRowKey = "__vuu_new_row__";
|
|
42
|
-
constructor(dataSource
|
|
53
|
+
constructor({ dataSource, deleteMode, editSessionApi, rowDefaults, }: EditSessionConstructorProps);
|
|
43
54
|
get editCount(): number;
|
|
44
55
|
set editCount(val: number);
|
|
45
56
|
get invalidCount(): number;
|
|
@@ -62,7 +73,7 @@ export declare class EditSession extends EventEmitter<EditSessionEvents> {
|
|
|
62
73
|
hasRowChanges(key: string): boolean;
|
|
63
74
|
isCellEdited(key: string, columnName: string): boolean;
|
|
64
75
|
undoRowChange(key: string): Promise<void>;
|
|
65
|
-
begin(copyOption?: CopyOption): Promise<DataSource>;
|
|
76
|
+
begin(copyOption?: CopyOption, sessionType?: SessionType): Promise<DataSource>;
|
|
66
77
|
get dataSource(): EditApi<import("@vuu-ui/vuu-data-types").DataSourceRow<VuuRowDataItemType>> | undefined;
|
|
67
78
|
get sessionDataSource(): DataSource | undefined;
|
|
68
79
|
end(saveChanges?: boolean, force?: boolean): Promise<void>;
|
package/types/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export { useCellEdited } from "./useCellEdited";
|
|
|
3
3
|
export { getVuuEditMessage, isInlineEditingSession, isEditRowReadOnly, withDataRowEditErrors, } from "./edit-utils";
|
|
4
4
|
export { EditButtons, type EditButtonProps } from "./EditButtons";
|
|
5
5
|
export { EditModeProvider, useEditMode, type EditModeContextProps, } from "./EditModeProvider";
|
|
6
|
-
export { EditError, EditSession, SupersededEditError, type EditLifecycle, type NewRowState, type EditState, } from "./EditSession";
|
|
6
|
+
export { EditError, EditSession, SupersededEditError, type EditLifecycle, type EditSessionConstructorProps, type NewRowState, type EditState, type RowDefaultDataItemValues, } from "./EditSession";
|
|
7
7
|
export { StaleUpdateError } from "@vuu-ui/vuu-utils";
|
|
8
8
|
export { EDIT_ACTION_ROW_CLASS_NAME_GENERATOR, editActionRowClassNameGenerator, } from "./editActionRowClassNameGenerator";
|
|
9
9
|
export { getUndoButtonContent, getUndoTooltipContent, UNDO_CELL_RENDERER, UndoCellRenderer, type UndoCellRendererComponentProps, } from "./UndoCellRenderer";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CopyOption, DataSource, DeleteRowMode } from "@vuu-ui/vuu-data-types";
|
|
2
2
|
import type { VuuTable } from "@vuu-ui/vuu-protocol-types";
|
|
3
|
-
import { EditSession, type EditLifecycle, type EditSessionApi } from "./EditSession";
|
|
3
|
+
import { EditSession, type EditLifecycle, type EditSessionApi, type RowDefaultDataItemValues } from "./EditSession";
|
|
4
4
|
export type EditMode = "edit" | "view";
|
|
5
5
|
export interface EditableTableHookProps {
|
|
6
6
|
/**
|
|
@@ -16,13 +16,15 @@ export interface EditableTableHookProps {
|
|
|
16
16
|
isEditMode: boolean;
|
|
17
17
|
onCancel: () => void;
|
|
18
18
|
onSave: () => void;
|
|
19
|
+
/** Default column values applied to every addRow call. Pass a stable reference — a new object triggers EditSession recreation. */
|
|
20
|
+
rowDefaults?: RowDefaultDataItemValues;
|
|
19
21
|
/**
|
|
20
22
|
* If dataSource not provided, new DataSource
|
|
21
23
|
* will be created using table and columns
|
|
22
24
|
*/
|
|
23
25
|
table?: VuuTable;
|
|
24
26
|
}
|
|
25
|
-
export declare const useEditableTable: ({ columns, dataSource: dataSourceProp, deleteMode, editSessionApi, copyOption, isEditMode, onCancel, onSave, table, }: EditableTableHookProps) => {
|
|
27
|
+
export declare const useEditableTable: ({ columns, dataSource: dataSourceProp, deleteMode, editSessionApi, copyOption, isEditMode, onCancel, onSave, rowDefaults, table, }: EditableTableHookProps) => {
|
|
26
28
|
canCancel: boolean;
|
|
27
29
|
canSave: boolean;
|
|
28
30
|
dataSource: DataSource;
|