@vuu-ui/vuu-utils 2.0.0 → 2.1.0-alpha.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.
@@ -0,0 +1,25 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var React = require('react');
5
+
6
+ const DataEditingContext = React.createContext(void 0);
7
+ const DataEditingProvider = ({
8
+ children,
9
+ editTracker
10
+ }) => {
11
+ return /* @__PURE__ */ jsxRuntime.jsx(DataEditingContext.Provider, { value: editTracker, children });
12
+ };
13
+ const useEditTracker = () => {
14
+ const editTracker = React.useContext(DataEditingContext);
15
+ if (editTracker === void 0) {
16
+ console.warn(
17
+ "[useEditTracker] no DataEditingContext in scope. You need to enclose editable component(s) with DataEditingProvider"
18
+ );
19
+ }
20
+ return editTracker;
21
+ };
22
+
23
+ exports.DataEditingProvider = DataEditingProvider;
24
+ exports.useEditTracker = useEditTracker;
25
+ //# sourceMappingURL=DataEditingProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataEditingProvider.js","sources":["../../../../../../../packages/vuu-utils/src/data-editing/DataEditingProvider.tsx"],"sourcesContent":["import { createContext, ReactNode, useContext } from \"react\";\nimport { EditTracker } from \"./EditTracker\";\n\nconst DataEditingContext = createContext<EditTracker | undefined>(undefined);\n\nexport const DataEditingProvider = ({\n children,\n editTracker,\n}: {\n children: ReactNode;\n editTracker: EditTracker;\n}) => {\n return (\n <DataEditingContext.Provider value={editTracker}>\n {children}\n </DataEditingContext.Provider>\n );\n};\n\nexport const useEditTracker = () => {\n const editTracker = useContext(DataEditingContext);\n if (editTracker === undefined) {\n console.warn(\n \"[useEditTracker] no DataEditingContext in scope. You need to enclose editable component(s) with DataEditingProvider\",\n );\n }\n return editTracker;\n};\n"],"names":["createContext","useContext"],"mappings":";;;;;AAGA,MAAM,kBAAA,GAAqBA,oBAAuC,KAAS,CAAA,CAAA;AAEpE,MAAM,sBAAsB,CAAC;AAAA,EAClC,QAAA;AAAA,EACA;AACF,CAGM,KAAA;AACJ,EAAA,sCACG,kBAAmB,CAAA,QAAA,EAAnB,EAA4B,KAAA,EAAO,aACjC,QACH,EAAA,CAAA;AAEJ;AAEO,MAAM,iBAAiB,MAAM;AAClC,EAAM,MAAA,WAAA,GAAcC,iBAAW,kBAAkB,CAAA;AACjD,EAAA,IAAI,gBAAgB,KAAW,CAAA,EAAA;AAC7B,IAAQ,OAAA,CAAA,IAAA;AAAA,MACN;AAAA,KACF;AAAA;AAEF,EAAO,OAAA,WAAA;AACT;;;;;"}
@@ -0,0 +1,154 @@
1
+ 'use strict';
2
+
3
+ var eventEmitter = require('../event-emitter.js');
4
+ var protocolMessageUtils = require('../protocol-message-utils.js');
5
+
6
+ var __typeError = (msg) => {
7
+ throw TypeError(msg);
8
+ };
9
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
10
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
11
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
12
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
13
+ var _active, _rowEdits, _editCount, _dataSource, _inEditMode;
14
+ class EditTracker extends eventEmitter.EventEmitter {
15
+ constructor() {
16
+ super(...arguments);
17
+ __privateAdd(this, _active, false);
18
+ /**
19
+ * Row key => row edits
20
+ */
21
+ __privateAdd(this, _rowEdits, /* @__PURE__ */ new Map());
22
+ __privateAdd(this, _editCount, 0);
23
+ __privateAdd(this, _dataSource);
24
+ __privateAdd(this, _inEditMode, false);
25
+ }
26
+ get active() {
27
+ return __privateGet(this, _active);
28
+ }
29
+ set active(isActive) {
30
+ __privateSet(this, _active, isActive);
31
+ }
32
+ get editCount() {
33
+ return __privateGet(this, _editCount);
34
+ }
35
+ set editCount(val) {
36
+ if (val !== __privateGet(this, _editCount)) {
37
+ const oldCount = __privateGet(this, _editCount);
38
+ __privateSet(this, _editCount, val);
39
+ if (val === 0) {
40
+ this.emit("editState", "clean");
41
+ } else if (oldCount === 0) {
42
+ this.emit("editState", "dirty");
43
+ }
44
+ }
45
+ }
46
+ set dataSource(ds) {
47
+ __privateSet(this, _dataSource, ds);
48
+ }
49
+ clear() {
50
+ __privateGet(this, _rowEdits).clear();
51
+ __privateSet(this, _editCount, 0);
52
+ }
53
+ async enterEditMode() {
54
+ __privateSet(this, _inEditMode, true);
55
+ const rpcResponse = await __privateGet(this, _dataSource)?.rpcRequest?.({
56
+ type: "RPC_REQUEST",
57
+ rpcName: "ENTER_EDIT_MODE",
58
+ params: {}
59
+ });
60
+ if (protocolMessageUtils.isRpcSuccess(rpcResponse)) {
61
+ const { table: sessionTable } = rpcResponse.data;
62
+ return sessionTable;
63
+ } else {
64
+ console.log("fail");
65
+ }
66
+ }
67
+ get inEditMode() {
68
+ return __privateGet(this, _inEditMode);
69
+ }
70
+ get editState() {
71
+ return this.editCount === 0 ? "clean" : "dirty";
72
+ }
73
+ async cancelChanges() {
74
+ const rpcResponse = await __privateGet(this, _dataSource)?.rpcRequest?.({
75
+ type: "RPC_REQUEST",
76
+ rpcName: "EXIT_EDIT_MODE",
77
+ params: {}
78
+ });
79
+ this.clear();
80
+ return rpcResponse;
81
+ }
82
+ async saveChanges() {
83
+ const rpcResponse = await __privateGet(this, _dataSource)?.rpcRequest?.({
84
+ type: "RPC_REQUEST",
85
+ rpcName: "EXIT_EDIT_MODE",
86
+ params: { save: true }
87
+ });
88
+ this.clear();
89
+ return rpcResponse;
90
+ }
91
+ // TODO how do we deal with the '_edited' pattern
92
+ edit(key, columnName, originalValue, newValue) {
93
+ const rowEditDetails = __privateGet(this, _rowEdits).get(key);
94
+ if (rowEditDetails) {
95
+ const { cellEdits } = rowEditDetails;
96
+ const cellEdit = cellEdits.get(columnName);
97
+ if (cellEdit) {
98
+ if (newValue === cellEdit.originalValue) {
99
+ if (cellEdits.size === 1) {
100
+ __privateGet(this, _rowEdits).delete(key);
101
+ } else {
102
+ cellEdits.delete(columnName);
103
+ }
104
+ this.editCount = __privateGet(this, _editCount) - 1;
105
+ } else {
106
+ cellEdit.editedValue = newValue;
107
+ }
108
+ } else {
109
+ cellEdits.set(columnName, {
110
+ originalValue,
111
+ editedValue: newValue
112
+ });
113
+ this.editCount = __privateGet(this, _editCount) + 1;
114
+ }
115
+ } else {
116
+ __privateGet(this, _rowEdits).set(key, {
117
+ cellEdits: /* @__PURE__ */ new Map([
118
+ [columnName, { originalValue, editedValue: newValue }]
119
+ ])
120
+ });
121
+ this.editCount = __privateGet(this, _editCount) + 1;
122
+ }
123
+ }
124
+ async commit(key, columnName) {
125
+ const rowEditDetails = __privateGet(this, _rowEdits).get(key);
126
+ if (rowEditDetails) {
127
+ const { cellEdits } = rowEditDetails;
128
+ const cellEditValues = cellEdits.get(columnName);
129
+ if (cellEditValues) {
130
+ const { editedValue } = cellEditValues;
131
+ const rpcResponse = await __privateGet(this, _dataSource)?.rpcRequest?.({
132
+ type: "RPC_REQUEST",
133
+ rpcName: "editCell",
134
+ params: {
135
+ column: `${columnName}`,
136
+ data: editedValue,
137
+ key
138
+ }
139
+ });
140
+ return rpcResponse;
141
+ }
142
+ } else {
143
+ throw Error(`[EditTracker] commit, key ${key} not found `);
144
+ }
145
+ }
146
+ }
147
+ _active = new WeakMap();
148
+ _rowEdits = new WeakMap();
149
+ _editCount = new WeakMap();
150
+ _dataSource = new WeakMap();
151
+ _inEditMode = new WeakMap();
152
+
153
+ exports.EditTracker = EditTracker;
154
+ //# sourceMappingURL=EditTracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EditTracker.js","sources":["../../../../../../../packages/vuu-utils/src/data-editing/EditTracker.tsx"],"sourcesContent":["import { DataSource } from \"@vuu-ui/vuu-data-types\";\nimport type { VuuRowDataItemType, VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport { EventEmitter } from \"../event-emitter\";\nimport { isRpcSuccess } from \"../protocol-message-utils\";\n\nexport type EditState = \"clean\" | \"dirty\";\n\ntype CellEdit = {\n originalValue: VuuRowDataItemType;\n editedValue: VuuRowDataItemType;\n};\n\ntype RowEditDetails = {\n /**\n * Column name => cell edit details\n */\n cellEdits: Map<string, CellEdit>;\n};\n\ntype EditTrackerEvents = {\n editState: (editState: EditState) => void;\n};\n\nexport class EditTracker extends EventEmitter<EditTrackerEvents> {\n #active = false;\n /**\n * Row key => row edits\n */\n #rowEdits = new Map<string, RowEditDetails>();\n #editCount = 0;\n #dataSource?: DataSource;\n #inEditMode = false;\n\n get active() {\n return this.#active;\n }\n set active(isActive: boolean) {\n this.#active = isActive;\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) {\n this.emit(\"editState\", \"clean\");\n } else if (oldCount === 0) {\n this.emit(\"editState\", \"dirty\");\n }\n }\n }\n\n set dataSource(ds: DataSource) {\n this.#dataSource = ds;\n }\n\n clear() {\n this.#rowEdits.clear();\n this.#editCount = 0;\n }\n\n async enterEditMode() {\n this.#inEditMode = true;\n\n const rpcResponse = await this.#dataSource?.rpcRequest?.({\n type: \"RPC_REQUEST\",\n rpcName: \"ENTER_EDIT_MODE\",\n params: {},\n });\n\n if (isRpcSuccess(rpcResponse)) {\n const { table: sessionTable } = rpcResponse.data as { table: VuuTable };\n return sessionTable;\n } else {\n console.log(\"fail\");\n }\n }\n\n get inEditMode() {\n return this.#inEditMode;\n }\n\n get editState(): EditState {\n return this.editCount === 0 ? \"clean\" : \"dirty\";\n }\n\n async cancelChanges() {\n const rpcResponse = await this.#dataSource?.rpcRequest?.({\n type: \"RPC_REQUEST\",\n rpcName: \"EXIT_EDIT_MODE\",\n params: {},\n });\n this.clear();\n return rpcResponse;\n }\n\n async saveChanges() {\n const rpcResponse = await this.#dataSource?.rpcRequest?.({\n type: \"RPC_REQUEST\",\n rpcName: \"EXIT_EDIT_MODE\",\n params: { save: true },\n });\n this.clear();\n return rpcResponse;\n }\n\n // TODO how do we deal with the '_edited' pattern\n edit(\n key: string,\n columnName: string,\n originalValue: VuuRowDataItemType,\n newValue: VuuRowDataItemType,\n ) {\n const rowEditDetails = this.#rowEdits.get(key);\n if (rowEditDetails) {\n const { cellEdits } = rowEditDetails;\n const cellEdit = cellEdits.get(columnName);\n if (cellEdit) {\n if (newValue === cellEdit.originalValue) {\n if (cellEdits.size === 1) {\n this.#rowEdits.delete(key);\n } else {\n // re-editing a cell had removed the edit\n cellEdits.delete(columnName);\n }\n this.editCount = this.#editCount - 1;\n } else {\n cellEdit.editedValue = newValue;\n }\n } else {\n // row has already been edited, but this column has not\n cellEdits.set(columnName, {\n originalValue,\n editedValue: newValue,\n });\n this.editCount = this.#editCount + 1;\n }\n } else {\n this.#rowEdits.set(key, {\n cellEdits: new Map([\n [columnName, { originalValue, editedValue: newValue }],\n ]),\n });\n this.editCount = this.#editCount + 1;\n }\n }\n\n async commit(key: string, columnName: string) {\n const rowEditDetails = this.#rowEdits.get(key);\n if (rowEditDetails) {\n const { cellEdits } = rowEditDetails;\n const cellEditValues = cellEdits.get(columnName);\n if (cellEditValues) {\n const { editedValue } = cellEditValues;\n const rpcResponse = await this.#dataSource?.rpcRequest?.({\n type: \"RPC_REQUEST\",\n rpcName: \"editCell\",\n params: {\n column: `${columnName}`,\n data: editedValue,\n key,\n },\n });\n\n return rpcResponse;\n }\n } else {\n throw Error(`[EditTracker] commit, key ${key} not found `);\n }\n }\n}\n"],"names":["EventEmitter","isRpcSuccess"],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var EditTracker = require('./EditTracker.js');
5
+ var DataProvider = require('../context-definitions/DataProvider.js');
6
+ var protocolMessageUtils = require('../protocol-message-utils.js');
7
+
8
+ const useEditableTable = ({ table }) => {
9
+ const { VuuDataSource } = DataProvider.useData();
10
+ const [editMode, setEditMode] = React.useState("view");
11
+ const [sessionDataSource, setSessionDataSource] = React.useState(void 0);
12
+ const dataSource = React.useMemo(() => {
13
+ return new VuuDataSource({ table });
14
+ }, [table, VuuDataSource]);
15
+ const editTracker = React.useMemo(() => new EditTracker.EditTracker(), []);
16
+ React.useMemo(() => {
17
+ if (dataSource) {
18
+ editTracker.dataSource = dataSource;
19
+ }
20
+ }, [dataSource, editTracker]);
21
+ const onCancel = React.useCallback(() => {
22
+ editTracker.dataSource = dataSource;
23
+ editTracker.cancelChanges();
24
+ setEditMode("view");
25
+ setSessionDataSource(void 0);
26
+ dataSource.resume?.();
27
+ }, [dataSource, editTracker]);
28
+ const onSave = React.useCallback(async () => {
29
+ editTracker.dataSource = dataSource;
30
+ const response = await editTracker.saveChanges();
31
+ if (protocolMessageUtils.isRpcSuccess(response)) {
32
+ setEditMode("view");
33
+ setSessionDataSource(void 0);
34
+ dataSource.resume?.();
35
+ }
36
+ }, [dataSource, editTracker]);
37
+ const onToggleEditMode = React.useCallback(
38
+ async (e) => {
39
+ const toggleButton = e.target;
40
+ const editMode2 = toggleButton.value;
41
+ setEditMode(editMode2);
42
+ if (editMode2 === "edit") {
43
+ const sessionTable = await editTracker.enterEditMode();
44
+ if (sessionTable && dataSource.tableSchema) {
45
+ dataSource.suspend?.(false);
46
+ const sessionDataSource2 = new VuuDataSource({
47
+ columns: dataSource.columns,
48
+ table: sessionTable,
49
+ viewport: sessionTable.table
50
+ });
51
+ setSessionDataSource(sessionDataSource2);
52
+ editTracker.dataSource = sessionDataSource2;
53
+ }
54
+ }
55
+ },
56
+ [VuuDataSource, dataSource, editTracker]
57
+ );
58
+ return {
59
+ dataSource: sessionDataSource ?? dataSource,
60
+ editMode,
61
+ editTracker,
62
+ onCancel,
63
+ onSave,
64
+ onToggleEditMode
65
+ };
66
+ };
67
+
68
+ exports.useEditableTable = useEditableTable;
69
+ //# sourceMappingURL=useEditableTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useEditableTable.js","sources":["../../../../../../../packages/vuu-utils/src/data-editing/useEditableTable.ts"],"sourcesContent":["import { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport { SyntheticEvent, useCallback, useMemo, useState } from \"react\";\nimport { EditTracker } from \"./EditTracker\";\nimport { useData } from \"../context-definitions/DataProvider\";\nimport { DataSource } from \"@vuu-ui/vuu-data-types\";\nimport { isRpcSuccess } from \"../protocol-message-utils\";\n\nexport type EditMode = \"edit\" | \"view\";\n\nexport const useEditableTable = ({ table }: { table: VuuTable }) => {\n const { VuuDataSource } = useData();\n const [editMode, setEditMode] = useState<EditMode>(\"view\");\n const [sessionDataSource, setSessionDataSource] = useState<\n DataSource | undefined\n >(undefined);\n\n const dataSource = useMemo(() => {\n return new VuuDataSource({ table });\n }, [table, VuuDataSource]);\n\n const editTracker = useMemo(() => new EditTracker(), []);\n\n useMemo(() => {\n if (dataSource) {\n editTracker.dataSource = dataSource;\n }\n }, [dataSource, editTracker]);\n\n const onCancel = useCallback(() => {\n editTracker.dataSource = dataSource;\n editTracker.cancelChanges();\n setEditMode(\"view\");\n setSessionDataSource(undefined);\n dataSource.resume?.();\n }, [dataSource, editTracker]);\n\n const onSave = useCallback(async () => {\n editTracker.dataSource = dataSource;\n const response = await editTracker.saveChanges();\n if (isRpcSuccess(response)) {\n setEditMode(\"view\");\n setSessionDataSource(undefined);\n dataSource.resume?.();\n }\n }, [dataSource, editTracker]);\n\n const onToggleEditMode = useCallback(\n async (e: SyntheticEvent<HTMLButtonElement>) => {\n const toggleButton = e.target as HTMLButtonElement;\n const editMode = toggleButton.value as EditMode;\n setEditMode(editMode);\n if (editMode === \"edit\") {\n const sessionTable = await editTracker.enterEditMode();\n if (sessionTable && dataSource.tableSchema) {\n dataSource.suspend?.(false);\n const sessionDataSource = new VuuDataSource({\n columns: dataSource.columns,\n table: sessionTable,\n viewport: sessionTable.table,\n });\n setSessionDataSource(sessionDataSource);\n editTracker.dataSource = sessionDataSource;\n }\n }\n },\n [VuuDataSource, dataSource, editTracker],\n );\n\n return {\n dataSource: sessionDataSource ?? dataSource,\n editMode,\n editTracker,\n onCancel,\n onSave,\n onToggleEditMode,\n };\n};\n"],"names":["useData","useState","useMemo","EditTracker","useCallback","isRpcSuccess","editMode","sessionDataSource"],"mappings":";;;;;;;AASO,MAAM,gBAAmB,GAAA,CAAC,EAAE,KAAA,EAAiC,KAAA;AAClE,EAAM,MAAA,EAAE,aAAc,EAAA,GAAIA,oBAAQ,EAAA;AAClC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIC,eAAmB,MAAM,CAAA;AACzD,EAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,CAAA,GAAIA,eAEhD,KAAS,CAAA,CAAA;AAEX,EAAM,MAAA,UAAA,GAAaC,cAAQ,MAAM;AAC/B,IAAA,OAAO,IAAI,aAAA,CAAc,EAAE,KAAA,EAAO,CAAA;AAAA,GACjC,EAAA,CAAC,KAAO,EAAA,aAAa,CAAC,CAAA;AAEzB,EAAA,MAAM,cAAcA,aAAQ,CAAA,MAAM,IAAIC,uBAAY,EAAA,EAAG,EAAE,CAAA;AAEvD,EAAAD,aAAA,CAAQ,MAAM;AACZ,IAAA,IAAI,UAAY,EAAA;AACd,MAAA,WAAA,CAAY,UAAa,GAAA,UAAA;AAAA;AAC3B,GACC,EAAA,CAAC,UAAY,EAAA,WAAW,CAAC,CAAA;AAE5B,EAAM,MAAA,QAAA,GAAWE,kBAAY,MAAM;AACjC,IAAA,WAAA,CAAY,UAAa,GAAA,UAAA;AACzB,IAAA,WAAA,CAAY,aAAc,EAAA;AAC1B,IAAA,WAAA,CAAY,MAAM,CAAA;AAClB,IAAA,oBAAA,CAAqB,KAAS,CAAA,CAAA;AAC9B,IAAA,UAAA,CAAW,MAAS,IAAA;AAAA,GACnB,EAAA,CAAC,UAAY,EAAA,WAAW,CAAC,CAAA;AAE5B,EAAM,MAAA,MAAA,GAASA,kBAAY,YAAY;AACrC,IAAA,WAAA,CAAY,UAAa,GAAA,UAAA;AACzB,IAAM,MAAA,QAAA,GAAW,MAAM,WAAA,CAAY,WAAY,EAAA;AAC/C,IAAI,IAAAC,iCAAA,CAAa,QAAQ,CAAG,EAAA;AAC1B,MAAA,WAAA,CAAY,MAAM,CAAA;AAClB,MAAA,oBAAA,CAAqB,KAAS,CAAA,CAAA;AAC9B,MAAA,UAAA,CAAW,MAAS,IAAA;AAAA;AACtB,GACC,EAAA,CAAC,UAAY,EAAA,WAAW,CAAC,CAAA;AAE5B,EAAA,MAAM,gBAAmB,GAAAD,iBAAA;AAAA,IACvB,OAAO,CAAyC,KAAA;AAC9C,MAAA,MAAM,eAAe,CAAE,CAAA,MAAA;AACvB,MAAA,MAAME,YAAW,YAAa,CAAA,KAAA;AAC9B,MAAA,WAAA,CAAYA,SAAQ,CAAA;AACpB,MAAA,IAAIA,cAAa,MAAQ,EAAA;AACvB,QAAM,MAAA,YAAA,GAAe,MAAM,WAAA,CAAY,aAAc,EAAA;AACrD,QAAI,IAAA,YAAA,IAAgB,WAAW,WAAa,EAAA;AAC1C,UAAA,UAAA,CAAW,UAAU,KAAK,CAAA;AAC1B,UAAMC,MAAAA,kBAAAA,GAAoB,IAAI,aAAc,CAAA;AAAA,YAC1C,SAAS,UAAW,CAAA,OAAA;AAAA,YACpB,KAAO,EAAA,YAAA;AAAA,YACP,UAAU,YAAa,CAAA;AAAA,WACxB,CAAA;AACD,UAAA,oBAAA,CAAqBA,kBAAiB,CAAA;AACtC,UAAA,WAAA,CAAY,UAAaA,GAAAA,kBAAAA;AAAA;AAC3B;AACF,KACF;AAAA,IACA,CAAC,aAAe,EAAA,UAAA,EAAY,WAAW;AAAA,GACzC;AAEA,EAAO,OAAA;AAAA,IACL,YAAY,iBAAqB,IAAA,UAAA;AAAA,IACjC,QAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
@@ -12,6 +12,9 @@ var commonTypes = require('./common-types.js');
12
12
  var componentRegistry = require('./component-registry.js');
13
13
  var cookieUtils = require('./cookie-utils.js');
14
14
  var cssUtils = require('./css-utils.js');
15
+ var DataEditingProvider = require('./data-editing/DataEditingProvider.js');
16
+ var EditTracker = require('./data-editing/EditTracker.js');
17
+ var useEditableTable = require('./data-editing/useEditableTable.js');
15
18
  var dataUtils = require('./data-utils.js');
16
19
  var BaseDataSource = require('./datasource/BaseDataSource.js');
17
20
  var datasourceActionUtils = require('./datasource/datasource-action-utils.js');
@@ -198,6 +201,10 @@ exports.registerConfigurationEditor = componentRegistry.registerConfigurationEdi
198
201
  exports.getCookieValue = cookieUtils.getCookieValue;
199
202
  exports.setCookieValue = cookieUtils.setCookieValue;
200
203
  exports.importCSS = cssUtils.importCSS;
204
+ exports.DataEditingProvider = DataEditingProvider.DataEditingProvider;
205
+ exports.useEditTracker = DataEditingProvider.useEditTracker;
206
+ exports.EditTracker = EditTracker.EditTracker;
207
+ exports.useEditableTable = useEditableTable.useEditableTable;
201
208
  exports.DOWN1 = dataUtils.DOWN1;
202
209
  exports.DOWN2 = dataUtils.DOWN2;
203
210
  exports.UP1 = dataUtils.UP1;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,22 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { createContext, useContext } from 'react';
3
+
4
+ const DataEditingContext = createContext(void 0);
5
+ const DataEditingProvider = ({
6
+ children,
7
+ editTracker
8
+ }) => {
9
+ return /* @__PURE__ */ jsx(DataEditingContext.Provider, { value: editTracker, children });
10
+ };
11
+ const useEditTracker = () => {
12
+ const editTracker = useContext(DataEditingContext);
13
+ if (editTracker === void 0) {
14
+ console.warn(
15
+ "[useEditTracker] no DataEditingContext in scope. You need to enclose editable component(s) with DataEditingProvider"
16
+ );
17
+ }
18
+ return editTracker;
19
+ };
20
+
21
+ export { DataEditingProvider, useEditTracker };
22
+ //# sourceMappingURL=DataEditingProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataEditingProvider.js","sources":["../../../../../../../packages/vuu-utils/src/data-editing/DataEditingProvider.tsx"],"sourcesContent":["import { createContext, ReactNode, useContext } from \"react\";\nimport { EditTracker } from \"./EditTracker\";\n\nconst DataEditingContext = createContext<EditTracker | undefined>(undefined);\n\nexport const DataEditingProvider = ({\n children,\n editTracker,\n}: {\n children: ReactNode;\n editTracker: EditTracker;\n}) => {\n return (\n <DataEditingContext.Provider value={editTracker}>\n {children}\n </DataEditingContext.Provider>\n );\n};\n\nexport const useEditTracker = () => {\n const editTracker = useContext(DataEditingContext);\n if (editTracker === undefined) {\n console.warn(\n \"[useEditTracker] no DataEditingContext in scope. You need to enclose editable component(s) with DataEditingProvider\",\n );\n }\n return editTracker;\n};\n"],"names":[],"mappings":";;;AAGA,MAAM,kBAAA,GAAqB,cAAuC,KAAS,CAAA,CAAA;AAEpE,MAAM,sBAAsB,CAAC;AAAA,EAClC,QAAA;AAAA,EACA;AACF,CAGM,KAAA;AACJ,EAAA,2BACG,kBAAmB,CAAA,QAAA,EAAnB,EAA4B,KAAA,EAAO,aACjC,QACH,EAAA,CAAA;AAEJ;AAEO,MAAM,iBAAiB,MAAM;AAClC,EAAM,MAAA,WAAA,GAAc,WAAW,kBAAkB,CAAA;AACjD,EAAA,IAAI,gBAAgB,KAAW,CAAA,EAAA;AAC7B,IAAQ,OAAA,CAAA,IAAA;AAAA,MACN;AAAA,KACF;AAAA;AAEF,EAAO,OAAA,WAAA;AACT;;;;"}
@@ -0,0 +1,152 @@
1
+ import { EventEmitter } from '../event-emitter.js';
2
+ import { isRpcSuccess } from '../protocol-message-utils.js';
3
+
4
+ var __typeError = (msg) => {
5
+ throw TypeError(msg);
6
+ };
7
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
8
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
9
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
10
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
11
+ var _active, _rowEdits, _editCount, _dataSource, _inEditMode;
12
+ class EditTracker extends EventEmitter {
13
+ constructor() {
14
+ super(...arguments);
15
+ __privateAdd(this, _active, false);
16
+ /**
17
+ * Row key => row edits
18
+ */
19
+ __privateAdd(this, _rowEdits, /* @__PURE__ */ new Map());
20
+ __privateAdd(this, _editCount, 0);
21
+ __privateAdd(this, _dataSource);
22
+ __privateAdd(this, _inEditMode, false);
23
+ }
24
+ get active() {
25
+ return __privateGet(this, _active);
26
+ }
27
+ set active(isActive) {
28
+ __privateSet(this, _active, isActive);
29
+ }
30
+ get editCount() {
31
+ return __privateGet(this, _editCount);
32
+ }
33
+ set editCount(val) {
34
+ if (val !== __privateGet(this, _editCount)) {
35
+ const oldCount = __privateGet(this, _editCount);
36
+ __privateSet(this, _editCount, val);
37
+ if (val === 0) {
38
+ this.emit("editState", "clean");
39
+ } else if (oldCount === 0) {
40
+ this.emit("editState", "dirty");
41
+ }
42
+ }
43
+ }
44
+ set dataSource(ds) {
45
+ __privateSet(this, _dataSource, ds);
46
+ }
47
+ clear() {
48
+ __privateGet(this, _rowEdits).clear();
49
+ __privateSet(this, _editCount, 0);
50
+ }
51
+ async enterEditMode() {
52
+ __privateSet(this, _inEditMode, true);
53
+ const rpcResponse = await __privateGet(this, _dataSource)?.rpcRequest?.({
54
+ type: "RPC_REQUEST",
55
+ rpcName: "ENTER_EDIT_MODE",
56
+ params: {}
57
+ });
58
+ if (isRpcSuccess(rpcResponse)) {
59
+ const { table: sessionTable } = rpcResponse.data;
60
+ return sessionTable;
61
+ } else {
62
+ console.log("fail");
63
+ }
64
+ }
65
+ get inEditMode() {
66
+ return __privateGet(this, _inEditMode);
67
+ }
68
+ get editState() {
69
+ return this.editCount === 0 ? "clean" : "dirty";
70
+ }
71
+ async cancelChanges() {
72
+ const rpcResponse = await __privateGet(this, _dataSource)?.rpcRequest?.({
73
+ type: "RPC_REQUEST",
74
+ rpcName: "EXIT_EDIT_MODE",
75
+ params: {}
76
+ });
77
+ this.clear();
78
+ return rpcResponse;
79
+ }
80
+ async saveChanges() {
81
+ const rpcResponse = await __privateGet(this, _dataSource)?.rpcRequest?.({
82
+ type: "RPC_REQUEST",
83
+ rpcName: "EXIT_EDIT_MODE",
84
+ params: { save: true }
85
+ });
86
+ this.clear();
87
+ return rpcResponse;
88
+ }
89
+ // TODO how do we deal with the '_edited' pattern
90
+ edit(key, columnName, originalValue, newValue) {
91
+ const rowEditDetails = __privateGet(this, _rowEdits).get(key);
92
+ if (rowEditDetails) {
93
+ const { cellEdits } = rowEditDetails;
94
+ const cellEdit = cellEdits.get(columnName);
95
+ if (cellEdit) {
96
+ if (newValue === cellEdit.originalValue) {
97
+ if (cellEdits.size === 1) {
98
+ __privateGet(this, _rowEdits).delete(key);
99
+ } else {
100
+ cellEdits.delete(columnName);
101
+ }
102
+ this.editCount = __privateGet(this, _editCount) - 1;
103
+ } else {
104
+ cellEdit.editedValue = newValue;
105
+ }
106
+ } else {
107
+ cellEdits.set(columnName, {
108
+ originalValue,
109
+ editedValue: newValue
110
+ });
111
+ this.editCount = __privateGet(this, _editCount) + 1;
112
+ }
113
+ } else {
114
+ __privateGet(this, _rowEdits).set(key, {
115
+ cellEdits: /* @__PURE__ */ new Map([
116
+ [columnName, { originalValue, editedValue: newValue }]
117
+ ])
118
+ });
119
+ this.editCount = __privateGet(this, _editCount) + 1;
120
+ }
121
+ }
122
+ async commit(key, columnName) {
123
+ const rowEditDetails = __privateGet(this, _rowEdits).get(key);
124
+ if (rowEditDetails) {
125
+ const { cellEdits } = rowEditDetails;
126
+ const cellEditValues = cellEdits.get(columnName);
127
+ if (cellEditValues) {
128
+ const { editedValue } = cellEditValues;
129
+ const rpcResponse = await __privateGet(this, _dataSource)?.rpcRequest?.({
130
+ type: "RPC_REQUEST",
131
+ rpcName: "editCell",
132
+ params: {
133
+ column: `${columnName}`,
134
+ data: editedValue,
135
+ key
136
+ }
137
+ });
138
+ return rpcResponse;
139
+ }
140
+ } else {
141
+ throw Error(`[EditTracker] commit, key ${key} not found `);
142
+ }
143
+ }
144
+ }
145
+ _active = new WeakMap();
146
+ _rowEdits = new WeakMap();
147
+ _editCount = new WeakMap();
148
+ _dataSource = new WeakMap();
149
+ _inEditMode = new WeakMap();
150
+
151
+ export { EditTracker };
152
+ //# sourceMappingURL=EditTracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EditTracker.js","sources":["../../../../../../../packages/vuu-utils/src/data-editing/EditTracker.tsx"],"sourcesContent":["import { DataSource } from \"@vuu-ui/vuu-data-types\";\nimport type { VuuRowDataItemType, VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport { EventEmitter } from \"../event-emitter\";\nimport { isRpcSuccess } from \"../protocol-message-utils\";\n\nexport type EditState = \"clean\" | \"dirty\";\n\ntype CellEdit = {\n originalValue: VuuRowDataItemType;\n editedValue: VuuRowDataItemType;\n};\n\ntype RowEditDetails = {\n /**\n * Column name => cell edit details\n */\n cellEdits: Map<string, CellEdit>;\n};\n\ntype EditTrackerEvents = {\n editState: (editState: EditState) => void;\n};\n\nexport class EditTracker extends EventEmitter<EditTrackerEvents> {\n #active = false;\n /**\n * Row key => row edits\n */\n #rowEdits = new Map<string, RowEditDetails>();\n #editCount = 0;\n #dataSource?: DataSource;\n #inEditMode = false;\n\n get active() {\n return this.#active;\n }\n set active(isActive: boolean) {\n this.#active = isActive;\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) {\n this.emit(\"editState\", \"clean\");\n } else if (oldCount === 0) {\n this.emit(\"editState\", \"dirty\");\n }\n }\n }\n\n set dataSource(ds: DataSource) {\n this.#dataSource = ds;\n }\n\n clear() {\n this.#rowEdits.clear();\n this.#editCount = 0;\n }\n\n async enterEditMode() {\n this.#inEditMode = true;\n\n const rpcResponse = await this.#dataSource?.rpcRequest?.({\n type: \"RPC_REQUEST\",\n rpcName: \"ENTER_EDIT_MODE\",\n params: {},\n });\n\n if (isRpcSuccess(rpcResponse)) {\n const { table: sessionTable } = rpcResponse.data as { table: VuuTable };\n return sessionTable;\n } else {\n console.log(\"fail\");\n }\n }\n\n get inEditMode() {\n return this.#inEditMode;\n }\n\n get editState(): EditState {\n return this.editCount === 0 ? \"clean\" : \"dirty\";\n }\n\n async cancelChanges() {\n const rpcResponse = await this.#dataSource?.rpcRequest?.({\n type: \"RPC_REQUEST\",\n rpcName: \"EXIT_EDIT_MODE\",\n params: {},\n });\n this.clear();\n return rpcResponse;\n }\n\n async saveChanges() {\n const rpcResponse = await this.#dataSource?.rpcRequest?.({\n type: \"RPC_REQUEST\",\n rpcName: \"EXIT_EDIT_MODE\",\n params: { save: true },\n });\n this.clear();\n return rpcResponse;\n }\n\n // TODO how do we deal with the '_edited' pattern\n edit(\n key: string,\n columnName: string,\n originalValue: VuuRowDataItemType,\n newValue: VuuRowDataItemType,\n ) {\n const rowEditDetails = this.#rowEdits.get(key);\n if (rowEditDetails) {\n const { cellEdits } = rowEditDetails;\n const cellEdit = cellEdits.get(columnName);\n if (cellEdit) {\n if (newValue === cellEdit.originalValue) {\n if (cellEdits.size === 1) {\n this.#rowEdits.delete(key);\n } else {\n // re-editing a cell had removed the edit\n cellEdits.delete(columnName);\n }\n this.editCount = this.#editCount - 1;\n } else {\n cellEdit.editedValue = newValue;\n }\n } else {\n // row has already been edited, but this column has not\n cellEdits.set(columnName, {\n originalValue,\n editedValue: newValue,\n });\n this.editCount = this.#editCount + 1;\n }\n } else {\n this.#rowEdits.set(key, {\n cellEdits: new Map([\n [columnName, { originalValue, editedValue: newValue }],\n ]),\n });\n this.editCount = this.#editCount + 1;\n }\n }\n\n async commit(key: string, columnName: string) {\n const rowEditDetails = this.#rowEdits.get(key);\n if (rowEditDetails) {\n const { cellEdits } = rowEditDetails;\n const cellEditValues = cellEdits.get(columnName);\n if (cellEditValues) {\n const { editedValue } = cellEditValues;\n const rpcResponse = await this.#dataSource?.rpcRequest?.({\n type: \"RPC_REQUEST\",\n rpcName: \"editCell\",\n params: {\n column: `${columnName}`,\n data: editedValue,\n key,\n },\n });\n\n return rpcResponse;\n }\n } else {\n throw Error(`[EditTracker] commit, key ${key} not found `);\n }\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import { useState, useMemo, useCallback } from 'react';
2
+ import { EditTracker } from './EditTracker.js';
3
+ import { useData } from '../context-definitions/DataProvider.js';
4
+ import { isRpcSuccess } from '../protocol-message-utils.js';
5
+
6
+ const useEditableTable = ({ table }) => {
7
+ const { VuuDataSource } = useData();
8
+ const [editMode, setEditMode] = useState("view");
9
+ const [sessionDataSource, setSessionDataSource] = useState(void 0);
10
+ const dataSource = useMemo(() => {
11
+ return new VuuDataSource({ table });
12
+ }, [table, VuuDataSource]);
13
+ const editTracker = useMemo(() => new EditTracker(), []);
14
+ useMemo(() => {
15
+ if (dataSource) {
16
+ editTracker.dataSource = dataSource;
17
+ }
18
+ }, [dataSource, editTracker]);
19
+ const onCancel = useCallback(() => {
20
+ editTracker.dataSource = dataSource;
21
+ editTracker.cancelChanges();
22
+ setEditMode("view");
23
+ setSessionDataSource(void 0);
24
+ dataSource.resume?.();
25
+ }, [dataSource, editTracker]);
26
+ const onSave = useCallback(async () => {
27
+ editTracker.dataSource = dataSource;
28
+ const response = await editTracker.saveChanges();
29
+ if (isRpcSuccess(response)) {
30
+ setEditMode("view");
31
+ setSessionDataSource(void 0);
32
+ dataSource.resume?.();
33
+ }
34
+ }, [dataSource, editTracker]);
35
+ const onToggleEditMode = useCallback(
36
+ async (e) => {
37
+ const toggleButton = e.target;
38
+ const editMode2 = toggleButton.value;
39
+ setEditMode(editMode2);
40
+ if (editMode2 === "edit") {
41
+ const sessionTable = await editTracker.enterEditMode();
42
+ if (sessionTable && dataSource.tableSchema) {
43
+ dataSource.suspend?.(false);
44
+ const sessionDataSource2 = new VuuDataSource({
45
+ columns: dataSource.columns,
46
+ table: sessionTable,
47
+ viewport: sessionTable.table
48
+ });
49
+ setSessionDataSource(sessionDataSource2);
50
+ editTracker.dataSource = sessionDataSource2;
51
+ }
52
+ }
53
+ },
54
+ [VuuDataSource, dataSource, editTracker]
55
+ );
56
+ return {
57
+ dataSource: sessionDataSource ?? dataSource,
58
+ editMode,
59
+ editTracker,
60
+ onCancel,
61
+ onSave,
62
+ onToggleEditMode
63
+ };
64
+ };
65
+
66
+ export { useEditableTable };
67
+ //# sourceMappingURL=useEditableTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useEditableTable.js","sources":["../../../../../../../packages/vuu-utils/src/data-editing/useEditableTable.ts"],"sourcesContent":["import { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport { SyntheticEvent, useCallback, useMemo, useState } from \"react\";\nimport { EditTracker } from \"./EditTracker\";\nimport { useData } from \"../context-definitions/DataProvider\";\nimport { DataSource } from \"@vuu-ui/vuu-data-types\";\nimport { isRpcSuccess } from \"../protocol-message-utils\";\n\nexport type EditMode = \"edit\" | \"view\";\n\nexport const useEditableTable = ({ table }: { table: VuuTable }) => {\n const { VuuDataSource } = useData();\n const [editMode, setEditMode] = useState<EditMode>(\"view\");\n const [sessionDataSource, setSessionDataSource] = useState<\n DataSource | undefined\n >(undefined);\n\n const dataSource = useMemo(() => {\n return new VuuDataSource({ table });\n }, [table, VuuDataSource]);\n\n const editTracker = useMemo(() => new EditTracker(), []);\n\n useMemo(() => {\n if (dataSource) {\n editTracker.dataSource = dataSource;\n }\n }, [dataSource, editTracker]);\n\n const onCancel = useCallback(() => {\n editTracker.dataSource = dataSource;\n editTracker.cancelChanges();\n setEditMode(\"view\");\n setSessionDataSource(undefined);\n dataSource.resume?.();\n }, [dataSource, editTracker]);\n\n const onSave = useCallback(async () => {\n editTracker.dataSource = dataSource;\n const response = await editTracker.saveChanges();\n if (isRpcSuccess(response)) {\n setEditMode(\"view\");\n setSessionDataSource(undefined);\n dataSource.resume?.();\n }\n }, [dataSource, editTracker]);\n\n const onToggleEditMode = useCallback(\n async (e: SyntheticEvent<HTMLButtonElement>) => {\n const toggleButton = e.target as HTMLButtonElement;\n const editMode = toggleButton.value as EditMode;\n setEditMode(editMode);\n if (editMode === \"edit\") {\n const sessionTable = await editTracker.enterEditMode();\n if (sessionTable && dataSource.tableSchema) {\n dataSource.suspend?.(false);\n const sessionDataSource = new VuuDataSource({\n columns: dataSource.columns,\n table: sessionTable,\n viewport: sessionTable.table,\n });\n setSessionDataSource(sessionDataSource);\n editTracker.dataSource = sessionDataSource;\n }\n }\n },\n [VuuDataSource, dataSource, editTracker],\n );\n\n return {\n dataSource: sessionDataSource ?? dataSource,\n editMode,\n editTracker,\n onCancel,\n onSave,\n onToggleEditMode,\n };\n};\n"],"names":["editMode","sessionDataSource"],"mappings":";;;;;AASO,MAAM,gBAAmB,GAAA,CAAC,EAAE,KAAA,EAAiC,KAAA;AAClE,EAAM,MAAA,EAAE,aAAc,EAAA,GAAI,OAAQ,EAAA;AAClC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAmB,MAAM,CAAA;AACzD,EAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,CAAA,GAAI,SAEhD,KAAS,CAAA,CAAA;AAEX,EAAM,MAAA,UAAA,GAAa,QAAQ,MAAM;AAC/B,IAAA,OAAO,IAAI,aAAA,CAAc,EAAE,KAAA,EAAO,CAAA;AAAA,GACjC,EAAA,CAAC,KAAO,EAAA,aAAa,CAAC,CAAA;AAEzB,EAAA,MAAM,cAAc,OAAQ,CAAA,MAAM,IAAI,WAAY,EAAA,EAAG,EAAE,CAAA;AAEvD,EAAA,OAAA,CAAQ,MAAM;AACZ,IAAA,IAAI,UAAY,EAAA;AACd,MAAA,WAAA,CAAY,UAAa,GAAA,UAAA;AAAA;AAC3B,GACC,EAAA,CAAC,UAAY,EAAA,WAAW,CAAC,CAAA;AAE5B,EAAM,MAAA,QAAA,GAAW,YAAY,MAAM;AACjC,IAAA,WAAA,CAAY,UAAa,GAAA,UAAA;AACzB,IAAA,WAAA,CAAY,aAAc,EAAA;AAC1B,IAAA,WAAA,CAAY,MAAM,CAAA;AAClB,IAAA,oBAAA,CAAqB,KAAS,CAAA,CAAA;AAC9B,IAAA,UAAA,CAAW,MAAS,IAAA;AAAA,GACnB,EAAA,CAAC,UAAY,EAAA,WAAW,CAAC,CAAA;AAE5B,EAAM,MAAA,MAAA,GAAS,YAAY,YAAY;AACrC,IAAA,WAAA,CAAY,UAAa,GAAA,UAAA;AACzB,IAAM,MAAA,QAAA,GAAW,MAAM,WAAA,CAAY,WAAY,EAAA;AAC/C,IAAI,IAAA,YAAA,CAAa,QAAQ,CAAG,EAAA;AAC1B,MAAA,WAAA,CAAY,MAAM,CAAA;AAClB,MAAA,oBAAA,CAAqB,KAAS,CAAA,CAAA;AAC9B,MAAA,UAAA,CAAW,MAAS,IAAA;AAAA;AACtB,GACC,EAAA,CAAC,UAAY,EAAA,WAAW,CAAC,CAAA;AAE5B,EAAA,MAAM,gBAAmB,GAAA,WAAA;AAAA,IACvB,OAAO,CAAyC,KAAA;AAC9C,MAAA,MAAM,eAAe,CAAE,CAAA,MAAA;AACvB,MAAA,MAAMA,YAAW,YAAa,CAAA,KAAA;AAC9B,MAAA,WAAA,CAAYA,SAAQ,CAAA;AACpB,MAAA,IAAIA,cAAa,MAAQ,EAAA;AACvB,QAAM,MAAA,YAAA,GAAe,MAAM,WAAA,CAAY,aAAc,EAAA;AACrD,QAAI,IAAA,YAAA,IAAgB,WAAW,WAAa,EAAA;AAC1C,UAAA,UAAA,CAAW,UAAU,KAAK,CAAA;AAC1B,UAAMC,MAAAA,kBAAAA,GAAoB,IAAI,aAAc,CAAA;AAAA,YAC1C,SAAS,UAAW,CAAA,OAAA;AAAA,YACpB,KAAO,EAAA,YAAA;AAAA,YACP,UAAU,YAAa,CAAA;AAAA,WACxB,CAAA;AACD,UAAA,oBAAA,CAAqBA,kBAAiB,CAAA;AACtC,UAAA,WAAA,CAAY,UAAaA,GAAAA,kBAAAA;AAAA;AAC3B;AACF,KACF;AAAA,IACA,CAAC,aAAe,EAAA,UAAA,EAAY,WAAW;AAAA,GACzC;AAEA,EAAO,OAAA;AAAA,IACL,YAAY,iBAAqB,IAAA,UAAA;AAAA,IACjC,QAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
@@ -10,6 +10,9 @@ export { MEASURES } from './common-types.js';
10
10
  export { getCellConfigPanelRenderer, getCellRenderer, getCellRendererOptions, getColumnHeaderContentRenderer, getColumnHeaderLabelRenderer, getConfigurationEditor, getEditRuleValidator, getLayoutComponent, getRegisteredCellRenderers, getRowClassNameGenerator, isContainer, isLayoutComponent, isView, registerComponent, registerConfigurationEditor } from './component-registry.js';
11
11
  export { getCookieValue, setCookieValue } from './cookie-utils.js';
12
12
  export { importCSS } from './css-utils.js';
13
+ export { DataEditingProvider, useEditTracker } from './data-editing/DataEditingProvider.js';
14
+ export { EditTracker } from './data-editing/EditTracker.js';
15
+ export { useEditableTable } from './data-editing/useEditableTable.js';
13
16
  export { DOWN1, DOWN2, UP1, UP2, asInteger, getMovingValueDirection, isValidNumber, numericTypeOfStringValue, shallowEquals, stringIsValidDecimal, stringIsValidInt, stringIsValidNumber } from './data-utils.js';
14
17
  export { BaseDataSource, defaultSuspenseProps } from './datasource/BaseDataSource.js';
15
18
  export { isViewportMenusAction, isVisualLinkCreatedAction, isVisualLinkRemovedAction, isVisualLinksAction, isVuuFeatureAction } from './datasource/datasource-action-utils.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
- "version": "2.0.0",
2
+ "version": "2.1.0-alpha.1",
3
3
  "author": "heswell",
4
4
  "license": "Apache-2.0",
5
5
  "types": "types/index.d.ts",
6
6
  "devDependencies": {
7
- "@vuu-ui/vuu-data-types": "2.0.0",
8
- "@vuu-ui/vuu-table-types": "2.0.0",
9
- "@vuu-ui/vuu-filter-types": "2.0.0",
10
- "@vuu-ui/vuu-protocol-types": "2.0.0"
7
+ "@vuu-ui/vuu-data-types": "2.1.0-alpha.1",
8
+ "@vuu-ui/vuu-table-types": "2.1.0-alpha.1",
9
+ "@vuu-ui/vuu-filter-types": "2.1.0-alpha.1",
10
+ "@vuu-ui/vuu-protocol-types": "2.1.0-alpha.1"
11
11
  },
12
12
  "peerDependencies": {
13
13
  "@internationalized/date": "^3.0.0",
14
- "@vuu-ui/vuu-filter-parser": "2.0.0",
14
+ "@vuu-ui/vuu-filter-parser": "2.1.0-alpha.1",
15
15
  "clsx": "^2.0.0",
16
16
  "react": "^19.2.3",
17
17
  "react-dom": "^19.2.3"
@@ -0,0 +1,7 @@
1
+ import { ReactNode } from "react";
2
+ import { EditTracker } from "./EditTracker";
3
+ export declare const DataEditingProvider: ({ children, editTracker, }: {
4
+ children: ReactNode;
5
+ editTracker: EditTracker;
6
+ }) => import("react/jsx-runtime").JSX.Element;
7
+ export declare const useEditTracker: () => EditTracker | undefined;
@@ -0,0 +1,7 @@
1
+ import { EditTracker } from "./EditTracker";
2
+ export interface EditButtonProps {
3
+ editTracker?: EditTracker;
4
+ onCancel: () => void;
5
+ onSave: () => void;
6
+ }
7
+ export declare const EditButtons: ({ editTracker, onCancel, onSave, }: EditButtonProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,24 @@
1
+ import { DataSource } from "@vuu-ui/vuu-data-types";
2
+ import type { VuuRowDataItemType, VuuTable } from "@vuu-ui/vuu-protocol-types";
3
+ import { EventEmitter } from "../event-emitter";
4
+ export type EditState = "clean" | "dirty";
5
+ type EditTrackerEvents = {
6
+ editState: (editState: EditState) => void;
7
+ };
8
+ export declare class EditTracker extends EventEmitter<EditTrackerEvents> {
9
+ #private;
10
+ get active(): boolean;
11
+ set active(isActive: boolean);
12
+ get editCount(): number;
13
+ set editCount(val: number);
14
+ set dataSource(ds: DataSource);
15
+ clear(): void;
16
+ enterEditMode(): Promise<VuuTable | undefined>;
17
+ get inEditMode(): boolean;
18
+ get editState(): EditState;
19
+ cancelChanges(): Promise<import("@vuu-ui/vuu-protocol-types").RpcResultSuccess | import("@vuu-ui/vuu-protocol-types").RpcResultError | undefined>;
20
+ saveChanges(): Promise<import("@vuu-ui/vuu-protocol-types").RpcResultSuccess | import("@vuu-ui/vuu-protocol-types").RpcResultError | undefined>;
21
+ edit(key: string, columnName: string, originalValue: VuuRowDataItemType, newValue: VuuRowDataItemType): void;
22
+ commit(key: string, columnName: string): Promise<import("@vuu-ui/vuu-protocol-types").RpcResultSuccess | import("@vuu-ui/vuu-protocol-types").RpcResultError | undefined>;
23
+ }
24
+ export {};
@@ -0,0 +1,15 @@
1
+ import { VuuTable } from "@vuu-ui/vuu-protocol-types";
2
+ import { SyntheticEvent } from "react";
3
+ import { EditTracker } from "./EditTracker";
4
+ import { DataSource } from "@vuu-ui/vuu-data-types";
5
+ export type EditMode = "edit" | "view";
6
+ export declare const useEditableTable: ({ table }: {
7
+ table: VuuTable;
8
+ }) => {
9
+ dataSource: DataSource;
10
+ editMode: EditMode;
11
+ editTracker: EditTracker;
12
+ onCancel: () => void;
13
+ onSave: () => Promise<void>;
14
+ onToggleEditMode: (e: SyntheticEvent<HTMLButtonElement>) => Promise<void>;
15
+ };
package/types/index.d.ts CHANGED
@@ -12,6 +12,9 @@ export * from "./common-types";
12
12
  export * from "./component-registry";
13
13
  export * from "./cookie-utils";
14
14
  export * from "./css-utils";
15
+ export { DataEditingProvider, useEditTracker, } from "./data-editing/DataEditingProvider";
16
+ export { EditTracker, type EditState } from "./data-editing/EditTracker";
17
+ export { useEditableTable } from "./data-editing/useEditableTable";
15
18
  export * from "./data-utils";
16
19
  export * from "./datasource/BaseDataSource";
17
20
  export * from "./datasource/datasource-action-utils";
@@ -62,7 +65,7 @@ export * from "./url-utils";
62
65
  export * from "./useId";
63
66
  export * from "./useLayoutEffectSkipFirst";
64
67
  export * from "./user-types";
65
- export { WidthHeight, WidthOnly, useResizeObserver, type measurements, type ResizeHandler, } from "./useResizeObserver";
68
+ export { useResizeObserver, WidthHeight, WidthOnly, type measurements, type ResizeHandler, } from "./useResizeObserver";
66
69
  export * from "./useStateRef";
67
70
  /** Context declarations hosted in utils to minimize intra package dependencies */
68
71
  export { DataContext } from "./context-definitions/DataContext";