@vuu-ui/vuu-table-extras 2.3.0 → 3.0.0-beta.2

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.
Files changed (66) hide show
  1. package/cjs/packages/vuu-table-extras/src/cell-renderers/dropdown-cell/DropdownCell.js +3 -0
  2. package/cjs/packages/vuu-table-extras/src/cell-renderers/dropdown-cell/DropdownCell.js.map +1 -1
  3. package/cjs/packages/vuu-table-extras/src/csv-upload/CsvUpload.js +62 -48
  4. package/cjs/packages/vuu-table-extras/src/csv-upload/CsvUpload.js.map +1 -1
  5. package/cjs/packages/vuu-table-extras/src/csv-upload/data-upload-preview/DataUploadPreview.css.js +6 -0
  6. package/cjs/packages/vuu-table-extras/src/csv-upload/data-upload-preview/DataUploadPreview.css.js.map +1 -0
  7. package/cjs/packages/vuu-table-extras/src/csv-upload/data-upload-preview/DataUploadPreview.js +118 -0
  8. package/cjs/packages/vuu-table-extras/src/csv-upload/data-upload-preview/DataUploadPreview.js.map +1 -0
  9. package/cjs/packages/vuu-table-extras/src/csv-upload/data-upload-preview/useDataUploadPreview.js +76 -0
  10. package/cjs/packages/vuu-table-extras/src/csv-upload/data-upload-preview/useDataUploadPreview.js.map +1 -0
  11. package/cjs/packages/vuu-table-extras/src/csv-upload/parse/csv-upload-utils.js +1 -44
  12. package/cjs/packages/vuu-table-extras/src/csv-upload/parse/csv-upload-utils.js.map +1 -1
  13. package/cjs/packages/vuu-table-extras/src/csv-upload/useCsvUpload.js +154 -66
  14. package/cjs/packages/vuu-table-extras/src/csv-upload/useCsvUpload.js.map +1 -1
  15. package/cjs/packages/vuu-table-extras/src/index.js +6 -2
  16. package/cjs/packages/vuu-table-extras/src/index.js.map +1 -1
  17. package/cjs/packages/vuu-table-extras/src/inline-add-row/InlineAddRow.css.js +6 -0
  18. package/cjs/packages/vuu-table-extras/src/inline-add-row/InlineAddRow.css.js.map +1 -0
  19. package/cjs/packages/vuu-table-extras/src/inline-add-row/InlineAddRow.js +44 -0
  20. package/cjs/packages/vuu-table-extras/src/inline-add-row/InlineAddRow.js.map +1 -0
  21. package/cjs/packages/vuu-table-extras/src/inline-add-row/useInlineAddRow.js +137 -0
  22. package/cjs/packages/vuu-table-extras/src/inline-add-row/useInlineAddRow.js.map +1 -0
  23. package/cjs/packages/vuu-table-extras/src/table-footer/TableFooter.css.js +1 -1
  24. package/cjs/packages/vuu-table-extras/src/table-footer/TableFooter.js +5 -2
  25. package/cjs/packages/vuu-table-extras/src/table-footer/TableFooter.js.map +1 -1
  26. package/esm/packages/vuu-table-extras/src/cell-renderers/dropdown-cell/DropdownCell.js +3 -0
  27. package/esm/packages/vuu-table-extras/src/cell-renderers/dropdown-cell/DropdownCell.js.map +1 -1
  28. package/esm/packages/vuu-table-extras/src/csv-upload/CsvUpload.js +63 -49
  29. package/esm/packages/vuu-table-extras/src/csv-upload/CsvUpload.js.map +1 -1
  30. package/esm/packages/vuu-table-extras/src/csv-upload/data-upload-preview/DataUploadPreview.css.js +4 -0
  31. package/esm/packages/vuu-table-extras/src/csv-upload/data-upload-preview/DataUploadPreview.css.js.map +1 -0
  32. package/esm/packages/vuu-table-extras/src/csv-upload/data-upload-preview/DataUploadPreview.js +116 -0
  33. package/esm/packages/vuu-table-extras/src/csv-upload/data-upload-preview/DataUploadPreview.js.map +1 -0
  34. package/esm/packages/vuu-table-extras/src/csv-upload/data-upload-preview/useDataUploadPreview.js +73 -0
  35. package/esm/packages/vuu-table-extras/src/csv-upload/data-upload-preview/useDataUploadPreview.js.map +1 -0
  36. package/esm/packages/vuu-table-extras/src/csv-upload/parse/csv-upload-utils.js +2 -43
  37. package/esm/packages/vuu-table-extras/src/csv-upload/parse/csv-upload-utils.js.map +1 -1
  38. package/esm/packages/vuu-table-extras/src/csv-upload/useCsvUpload.js +157 -69
  39. package/esm/packages/vuu-table-extras/src/csv-upload/useCsvUpload.js.map +1 -1
  40. package/esm/packages/vuu-table-extras/src/index.js +3 -1
  41. package/esm/packages/vuu-table-extras/src/index.js.map +1 -1
  42. package/esm/packages/vuu-table-extras/src/inline-add-row/InlineAddRow.css.js +4 -0
  43. package/esm/packages/vuu-table-extras/src/inline-add-row/InlineAddRow.css.js.map +1 -0
  44. package/esm/packages/vuu-table-extras/src/inline-add-row/InlineAddRow.js +42 -0
  45. package/esm/packages/vuu-table-extras/src/inline-add-row/InlineAddRow.js.map +1 -0
  46. package/esm/packages/vuu-table-extras/src/inline-add-row/useInlineAddRow.js +135 -0
  47. package/esm/packages/vuu-table-extras/src/inline-add-row/useInlineAddRow.js.map +1 -0
  48. package/esm/packages/vuu-table-extras/src/table-footer/TableFooter.css.js +1 -1
  49. package/esm/packages/vuu-table-extras/src/table-footer/TableFooter.js +5 -2
  50. package/esm/packages/vuu-table-extras/src/table-footer/TableFooter.js.map +1 -1
  51. package/package.json +12 -11
  52. package/types/csv-upload/CsvUpload.d.ts +9 -1
  53. package/types/csv-upload/data-upload-preview/DataUploadPreview.d.ts +10 -0
  54. package/types/csv-upload/data-upload-preview/useDataUploadPreview.d.ts +17 -0
  55. package/types/csv-upload/index.d.ts +2 -2
  56. package/types/csv-upload/useCsvUpload.d.ts +6 -3
  57. package/types/index.d.ts +1 -0
  58. package/types/inline-add-row/InlineAddRow.d.ts +3 -0
  59. package/types/inline-add-row/index.d.ts +2 -0
  60. package/types/inline-add-row/useInlineAddRow.d.ts +57 -0
  61. package/types/table-footer/TableFooter.d.ts +3 -2
  62. package/cjs/packages/vuu-table-extras/src/csv-upload/useCsvUploadSessionPreview.js +0 -73
  63. package/cjs/packages/vuu-table-extras/src/csv-upload/useCsvUploadSessionPreview.js.map +0 -1
  64. package/esm/packages/vuu-table-extras/src/csv-upload/useCsvUploadSessionPreview.js +0 -71
  65. package/esm/packages/vuu-table-extras/src/csv-upload/useCsvUploadSessionPreview.js.map +0 -1
  66. package/types/csv-upload/useCsvUploadSessionPreview.d.ts +0 -10
@@ -0,0 +1,137 @@
1
+ 'use strict';
2
+
3
+ var vuuDataEditing = require('@vuu-ui/vuu-data-editing');
4
+ var vuuUtils = require('@vuu-ui/vuu-utils');
5
+ var react = require('react');
6
+
7
+ const createSyntheticDataRow = (newRowState, columns) => vuuDataEditing.withDataRowEditErrors(
8
+ {
9
+ ...newRowState.values,
10
+ childCount: 0,
11
+ depth: 1,
12
+ hasColumn: (name) => columns.some((column) => column.name === name),
13
+ index: -1,
14
+ isExpanded: false,
15
+ isLeaf: true,
16
+ isSelected: false,
17
+ key: vuuDataEditing.EditSession.newRowKey,
18
+ renderIndex: -1
19
+ },
20
+ newRowState.errors
21
+ );
22
+ const useInlineAddRow = ({ columns }) => {
23
+ const editSession = vuuDataEditing.useEditSession(true);
24
+ const containerRef = react.useRef(null);
25
+ const inlineAddColumns = react.useMemo(
26
+ () => columns.map((column) => {
27
+ const editable = vuuUtils.isDataValueEditable(column, "insert");
28
+ const inlineAddColumn = { ...column, editable };
29
+ return {
30
+ ...inlineAddColumn,
31
+ CellRenderer: editable ? vuuUtils.getCellRenderer(inlineAddColumn) : void 0
32
+ };
33
+ }),
34
+ [columns]
35
+ );
36
+ const visibleColumns = react.useMemo(
37
+ () => inlineAddColumns.filter(vuuUtils.isNotHidden),
38
+ [inlineAddColumns]
39
+ );
40
+ const visibleInsertColumns = react.useMemo(
41
+ () => visibleColumns.filter((column) => vuuUtils.isDataValueEditable(column, "insert")),
42
+ [visibleColumns]
43
+ );
44
+ const subscribeToNewRow = react.useCallback(
45
+ (onStoreChange) => {
46
+ editSession.on("newRow", onStoreChange);
47
+ return () => editSession.removeListener("newRow", onStoreChange);
48
+ },
49
+ [editSession]
50
+ );
51
+ const newRowState = react.useSyncExternalStore(
52
+ subscribeToNewRow,
53
+ () => editSession.newRowState,
54
+ () => editSession.newRowState
55
+ );
56
+ const dataRow = react.useMemo(
57
+ () => createSyntheticDataRow(newRowState, inlineAddColumns),
58
+ [inlineAddColumns, newRowState]
59
+ );
60
+ const previousValuesRef = react.useRef(newRowState.values);
61
+ const focusEditor = react.useCallback((index) => {
62
+ const cell = containerRef.current?.querySelectorAll("[data-field]")[index];
63
+ cell?.querySelector("input, button, [tabindex]")?.focus();
64
+ }, []);
65
+ react.useEffect(() => {
66
+ editSession.configureNewRow(visibleInsertColumns.map(({ name }) => name));
67
+ }, [editSession, visibleInsertColumns]);
68
+ react.useEffect(() => {
69
+ visibleInsertColumns.filter(
70
+ (column) => column.serverDataType === "boolean" && newRowState.values[column.name] === void 0
71
+ ).forEach((column) => {
72
+ editSession.setNewRowValue(column.name, false);
73
+ });
74
+ }, [editSession, newRowState.values, visibleInsertColumns]);
75
+ react.useEffect(() => {
76
+ const firstInvalidIndex = visibleColumns.findIndex(
77
+ ({ name }) => newRowState.errors[name] !== void 0
78
+ );
79
+ if (firstInvalidIndex !== -1) {
80
+ focusEditor(firstInvalidIndex);
81
+ }
82
+ }, [focusEditor, newRowState.errors, visibleColumns]);
83
+ react.useEffect(() => {
84
+ const previousValues = previousValuesRef.current;
85
+ previousValuesRef.current = newRowState.values;
86
+ if (Object.keys(previousValues).length > 0 && Object.keys(newRowState.values).length === 0 && Object.keys(newRowState.errors).length === 0) {
87
+ const firstEditableIndex = visibleColumns.findIndex(
88
+ (column) => vuuUtils.isDataValueEditable(column, "insert")
89
+ );
90
+ if (firstEditableIndex !== -1) {
91
+ requestAnimationFrame(() => focusEditor(firstEditableIndex));
92
+ }
93
+ }
94
+ }, [focusEditor, newRowState.errors, newRowState.values, visibleColumns]);
95
+ react.useEffect(() => {
96
+ const container = containerRef.current;
97
+ if (!container) {
98
+ return;
99
+ }
100
+ const handleCommit = (event) => {
101
+ const target = event.target;
102
+ if (!(target instanceof Element)) {
103
+ return;
104
+ }
105
+ const cell = target.closest("[data-field]");
106
+ const cells = container.querySelectorAll("[data-field]");
107
+ const currentIndex = Array.from(cells).indexOf(cell ?? container);
108
+ const firstInvalidIndex = visibleColumns.findIndex(
109
+ ({ name }) => editSession.newRowState.errors[name] !== void 0
110
+ );
111
+ const firstEditableIndex = visibleColumns.findIndex(
112
+ (column) => vuuUtils.isDataValueEditable(column, "insert")
113
+ );
114
+ const nextEditableIndex = visibleColumns.findIndex(
115
+ (column, index) => index > currentIndex && vuuUtils.isDataValueEditable(column, "insert")
116
+ );
117
+ if (firstInvalidIndex !== -1) {
118
+ requestAnimationFrame(() => focusEditor(firstInvalidIndex));
119
+ } else if (nextEditableIndex !== -1) {
120
+ focusEditor(nextEditableIndex);
121
+ } else if (firstEditableIndex !== -1) {
122
+ requestAnimationFrame(() => focusEditor(firstEditableIndex));
123
+ }
124
+ };
125
+ container.addEventListener("vuu-commit", handleCommit);
126
+ return () => container.removeEventListener("vuu-commit", handleCommit);
127
+ }, [editSession, focusEditor, visibleColumns]);
128
+ return {
129
+ containerRef,
130
+ dataRow,
131
+ draftRevision: newRowState.draftRevision,
132
+ inlineAddColumns
133
+ };
134
+ };
135
+
136
+ exports.useInlineAddRow = useInlineAddRow;
137
+ //# sourceMappingURL=useInlineAddRow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInlineAddRow.js","sources":["../../../../../../../packages/vuu-table-extras/src/inline-add-row/useInlineAddRow.ts"],"sourcesContent":["import {\n EditSession,\n useEditSession,\n withDataRowEditErrors,\n type NewRowState,\n} from \"@vuu-ui/vuu-data-editing\";\nimport type { DataRow, RuntimeColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport {\n getCellRenderer,\n isDataValueEditable,\n isNotHidden,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useSyncExternalStore,\n} from \"react\";\n\nconst createSyntheticDataRow = (\n newRowState: NewRowState,\n columns: RuntimeColumnDescriptor[],\n): DataRow =>\n withDataRowEditErrors(\n {\n ...newRowState.values,\n childCount: 0,\n depth: 1,\n hasColumn: (name: string) =>\n columns.some((column) => column.name === name),\n index: -1,\n isExpanded: false,\n isLeaf: true,\n isSelected: false,\n key: EditSession.newRowKey,\n renderIndex: -1,\n } as DataRow,\n newRowState.errors,\n );\n\nexport interface UseInlineAddRowProps {\n columns: RuntimeColumnDescriptor[];\n}\n\nexport const useInlineAddRow = ({ columns }: UseInlineAddRowProps) => {\n const editSession = useEditSession(true);\n const containerRef = useRef<HTMLDivElement>(null);\n const inlineAddColumns = useMemo(\n () =>\n columns.map((column) => {\n const editable = isDataValueEditable(column, \"insert\");\n const inlineAddColumn = { ...column, editable };\n return {\n ...inlineAddColumn,\n CellRenderer: editable ? getCellRenderer(inlineAddColumn) : undefined,\n };\n }),\n [columns],\n );\n const visibleColumns = useMemo(\n () => inlineAddColumns.filter(isNotHidden),\n [inlineAddColumns],\n );\n const visibleInsertColumns = useMemo(\n () =>\n visibleColumns.filter((column) => isDataValueEditable(column, \"insert\")),\n [visibleColumns],\n );\n const subscribeToNewRow = useCallback(\n (onStoreChange: () => void) => {\n editSession.on(\"newRow\", onStoreChange);\n return () => editSession.removeListener(\"newRow\", onStoreChange);\n },\n [editSession],\n );\n const newRowState = useSyncExternalStore(\n subscribeToNewRow,\n () => editSession.newRowState,\n () => editSession.newRowState,\n );\n const dataRow = useMemo(\n () => createSyntheticDataRow(newRowState, inlineAddColumns),\n [inlineAddColumns, newRowState],\n );\n const previousValuesRef = useRef(newRowState.values);\n\n const focusEditor = useCallback((index: number) => {\n const cell =\n containerRef.current?.querySelectorAll<HTMLElement>(\"[data-field]\")[\n index\n ];\n cell?.querySelector<HTMLElement>(\"input, button, [tabindex]\")?.focus();\n }, []);\n\n useEffect(() => {\n editSession.configureNewRow(visibleInsertColumns.map(({ name }) => name));\n }, [editSession, visibleInsertColumns]);\n\n useEffect(() => {\n visibleInsertColumns\n .filter(\n (column) =>\n column.serverDataType === \"boolean\" &&\n newRowState.values[column.name] === undefined,\n )\n .forEach((column) => {\n editSession.setNewRowValue(column.name, false);\n });\n }, [editSession, newRowState.values, visibleInsertColumns]);\n\n useEffect(() => {\n const firstInvalidIndex = visibleColumns.findIndex(\n ({ name }) => newRowState.errors[name] !== undefined,\n );\n if (firstInvalidIndex !== -1) {\n focusEditor(firstInvalidIndex);\n }\n }, [focusEditor, newRowState.errors, visibleColumns]);\n\n useEffect(() => {\n const previousValues = previousValuesRef.current;\n previousValuesRef.current = newRowState.values;\n if (\n Object.keys(previousValues).length > 0 &&\n Object.keys(newRowState.values).length === 0 &&\n Object.keys(newRowState.errors).length === 0\n ) {\n const firstEditableIndex = visibleColumns.findIndex((column) =>\n isDataValueEditable(column, \"insert\"),\n );\n if (firstEditableIndex !== -1) {\n requestAnimationFrame(() => focusEditor(firstEditableIndex));\n }\n }\n }, [focusEditor, newRowState.errors, newRowState.values, visibleColumns]);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n const handleCommit = (event: Event) => {\n const target = event.target;\n if (!(target instanceof Element)) {\n return;\n }\n const cell = target.closest<HTMLElement>(\"[data-field]\");\n const cells = container.querySelectorAll<HTMLElement>(\"[data-field]\");\n const currentIndex = Array.from(cells).indexOf(cell ?? container);\n const firstInvalidIndex = visibleColumns.findIndex(\n ({ name }) => editSession.newRowState.errors[name] !== undefined,\n );\n const firstEditableIndex = visibleColumns.findIndex((column) =>\n isDataValueEditable(column, \"insert\"),\n );\n const nextEditableIndex = visibleColumns.findIndex(\n (column, index) =>\n index > currentIndex && isDataValueEditable(column, \"insert\"),\n );\n if (firstInvalidIndex !== -1) {\n requestAnimationFrame(() => focusEditor(firstInvalidIndex));\n } else if (nextEditableIndex !== -1) {\n focusEditor(nextEditableIndex);\n } else if (firstEditableIndex !== -1) {\n requestAnimationFrame(() => focusEditor(firstEditableIndex));\n }\n };\n\n container.addEventListener(\"vuu-commit\", handleCommit);\n return () => container.removeEventListener(\"vuu-commit\", handleCommit);\n }, [editSession, focusEditor, visibleColumns]);\n\n return {\n containerRef,\n dataRow,\n draftRevision: newRowState.draftRevision,\n inlineAddColumns,\n };\n};\n"],"names":["withDataRowEditErrors","EditSession","useEditSession","useRef","useMemo","isDataValueEditable","getCellRenderer","isNotHidden","useCallback","useSyncExternalStore","useEffect"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var tableFooterCss = ".vuuTableFooter {\n background-color: var(--salt-container-secondary-background);\n display: grid;\n --table-footer-height: var(--vuuTableFooter-height, 32px);\n flex: 0 0 var(--table-footer-height);\n grid-template-areas: \"panel-start panel-center panel-end\";\n grid-template-columns: 1fr 1fr 1fr;\n grid-template-rows: auto;\n\n height: var(--table-footer-height);\n\n .vuuTableFooterTray {\n align-items: center;\n display: flex;\n justify-self: end;;\n margin: 0 var(--salt-spacing-200);\n grid-area: panel-end;\n }\n\n}\n";
3
+ var tableFooterCss = ".vuuTableFooter {\n background-color: var(--salt-container-secondary-background);\n display: grid;\n --table-footer-height: var(--vuuTableFooter-height, 32px);\n flex: 0 0 var(--table-footer-height);\n grid-template-areas: \"panel-start panel-center panel-end\";\n grid-template-columns: 1fr 1fr 1fr;\n grid-template-rows: auto;\n\n height: var(--table-footer-height);\n\n .vuuTableFooterTray {\n align-items: center;\n display: flex;\n gap: var(--salt-spacing-100);\n margin: 0 var(--salt-spacing-200);\n\n &.vuuTableFooterTray-center {\n grid-area: panel-center;\n justify-self: center;\n }\n &.vuuTableFooterTray-end {\n grid-area: panel-end;\n justify-self: end;\n }\n }\n}\n";
4
4
 
5
5
  module.exports = tableFooterCss;
6
6
  //# sourceMappingURL=TableFooter.css.js.map
@@ -7,8 +7,11 @@ var window = require('@salt-ds/window');
7
7
  var TableFooter$1 = require('./TableFooter.css.js');
8
8
 
9
9
  const classBase = "vuuTableFooter";
10
- const TableFooterTray = ({ children }) => {
11
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${classBase}Tray`, children });
10
+ const TableFooterTray = ({ children, position = "end" }) => {
11
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx(`${classBase}Tray`, {
12
+ [`${classBase}Tray-center`]: position === "center",
13
+ [`${classBase}Tray-end`]: position === "end"
14
+ }), children });
12
15
  };
13
16
  const TableFooter = ({
14
17
  children,
@@ -1 +1 @@
1
- {"version":3,"file":"TableFooter.js","sources":["../../../../../../../packages/vuu-table-extras/src/table-footer/TableFooter.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport { HTMLAttributes, ReactNode } from \"react\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nimport tableFooterCss from \"./TableFooter.css\";\n\nexport interface TableFooterProps extends HTMLAttributes<HTMLDivElement> {\n onInvokeAction?: (action: string) => void;\n tooltrayActions?: ReactNode;\n}\n\nconst classBase = \"vuuTableFooter\";\n\nexport const TableFooterTray = ({ children }: { children: ReactNode }) => {\n return <div className={`${classBase}Tray`}>{children}</div>;\n};\n\nexport const TableFooter = ({\n children,\n className,\n onInvokeAction,\n tooltrayActions,\n ...htmlAttributes\n}: TableFooterProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-table-footer\",\n css: tableFooterCss,\n window: targetWindow,\n });\n\n return (\n <div {...htmlAttributes} className={cx(classBase, className)}>\n {children}\n {tooltrayActions ? (\n <div className={`${classBase}-tooltray`}>{tooltrayActions}</div>\n ) : null}\n </div>\n );\n};\n"],"names":["useWindow","useComponentCssInjection","tableFooterCss","jsxs"],"mappings":";;;;;;;;AAYA,MAAM,SAAY,GAAA,gBAAA;AAEX,MAAM,eAAkB,GAAA,CAAC,EAAE,QAAA,EAAwC,KAAA;AACxE,EAAA,sCAAQ,KAAI,EAAA,EAAA,SAAA,EAAW,CAAG,EAAA,SAAS,QAAS,QAAS,EAAA,CAAA;AACvD;AAEO,MAAM,cAAc,CAAC;AAAA,EAC1B,QAAA;AAAA,EACA,SAAA;AAAA,EACA,cAAA;AAAA,EACA,eAAA;AAAA,EACA,GAAG;AACL,CAAwB,KAAA;AACtB,EAAA,MAAM,eAAeA,gBAAU,EAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,kBAAA;AAAA,IACR,GAAK,EAAAC,aAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EACE,uBAAAC,eAAA,CAAC,SAAK,GAAG,cAAA,EAAgB,WAAW,EAAG,CAAA,SAAA,EAAW,SAAS,CACxD,EAAA,QAAA,EAAA;AAAA,IAAA,QAAA;AAAA,IACA,eAAA,kCACE,KAAI,EAAA,EAAA,SAAA,EAAW,GAAG,SAAS,CAAA,SAAA,CAAA,EAAc,2BAAgB,CACxD,GAAA;AAAA,GACN,EAAA,CAAA;AAEJ;;;;;"}
1
+ {"version":3,"file":"TableFooter.js","sources":["../../../../../../../packages/vuu-table-extras/src/table-footer/TableFooter.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nimport tableFooterCss from \"./TableFooter.css\";\n\nexport interface TableFooterProps extends HTMLAttributes<HTMLDivElement> {\n onInvokeAction?: (action: string) => void;\n tooltrayActions?: ReactNode;\n}\n\nconst classBase = \"vuuTableFooter\";\n\nexport const TableFooterTray = ({ children, position = 'end' }: { children: ReactNode, position?: 'center' | 'end' }) => {\n return <div className={cx(`${classBase}Tray`, {\n [`${classBase}Tray-center`]: position === 'center',\n [`${classBase}Tray-end`]: position === 'end'\n })}>{children}</div>;\n};\n\nexport const TableFooter = ({\n children,\n className,\n onInvokeAction,\n tooltrayActions,\n ...htmlAttributes\n}: TableFooterProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-table-footer\",\n css: tableFooterCss,\n window: targetWindow,\n });\n\n return (\n <div {...htmlAttributes} className={cx(classBase, className)}>\n {children}\n {tooltrayActions ? (\n <div className={`${classBase}-tooltray`}>{tooltrayActions}</div>\n ) : null}\n </div>\n );\n};\n"],"names":["useWindow","useComponentCssInjection","tableFooterCss","jsxs"],"mappings":";;;;;;;;AAYA,MAAM,SAAY,GAAA,gBAAA;AAEX,MAAM,kBAAkB,CAAC,EAAE,QAAU,EAAA,QAAA,GAAW,OAAkE,KAAA;AACvH,EAAA,sCAAQ,KAAI,EAAA,EAAA,SAAA,EAAW,EAAG,CAAA,CAAA,EAAG,SAAS,CAAQ,IAAA,CAAA,EAAA;AAAA,IAC5C,CAAC,CAAA,EAAG,SAAS,CAAA,WAAA,CAAa,GAAG,QAAa,KAAA,QAAA;AAAA,IAC1C,CAAC,CAAA,EAAG,SAAS,CAAA,QAAA,CAAU,GAAG,QAAa,KAAA;AAAA,GACxC,GAAI,QAAS,EAAA,CAAA;AAChB;AAEO,MAAM,cAAc,CAAC;AAAA,EAC1B,QAAA;AAAA,EACA,SAAA;AAAA,EACA,cAAA;AAAA,EACA,eAAA;AAAA,EACA,GAAG;AACL,CAAwB,KAAA;AACtB,EAAA,MAAM,eAAeA,gBAAU,EAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,kBAAA;AAAA,IACR,GAAK,EAAAC,aAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EACE,uBAAAC,eAAA,CAAC,SAAK,GAAG,cAAA,EAAgB,WAAW,EAAG,CAAA,SAAA,EAAW,SAAS,CACxD,EAAA,QAAA,EAAA;AAAA,IAAA,QAAA;AAAA,IACA,eAAA,kCACE,KAAI,EAAA,EAAA,SAAA,EAAW,GAAG,SAAS,CAAA,SAAA,CAAA,EAAc,2BAAgB,CACxD,GAAA;AAAA,GACN,EAAA,CAAA;AAEJ;;;;;"}
@@ -1,6 +1,7 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { useLookupValues } from '@vuu-ui/vuu-data-react';
3
3
  import { getSelectedOption, isRpcSuccess, dispatchCustomEvent, dataColumnAndKeyUnchanged, registerComponent } from '@vuu-ui/vuu-utils';
4
+ import { isEditRowReadOnly } from '@vuu-ui/vuu-data-editing';
4
5
  import cx from 'clsx';
5
6
  import { Dropdown, Option } from '@salt-ds/core';
6
7
  import { useComponentCssInjection } from '@salt-ds/styles';
@@ -27,6 +28,7 @@ const DropdownCell = memo(
27
28
  }
28
29
  const [open, setOpen] = useState(false);
29
30
  const dataValue = dataRow[column.name];
31
+ const readOnly = isEditRowReadOnly(dataRow);
30
32
  const { values } = useLookupValues(column, dataValue);
31
33
  const valueRef = useRef(void 0);
32
34
  useMemo(() => {
@@ -85,6 +87,7 @@ const DropdownCell = memo(
85
87
  onOpenChange: handleOpenChange,
86
88
  onSelectionChange: handleSelectionChange,
87
89
  open,
90
+ readOnly,
88
91
  selected: selectedOption ? [selectedOption] : [],
89
92
  value: selectedOption?.label,
90
93
  children: values.map((listOption, i) => /* @__PURE__ */ jsx(Option, { value: listOption, children: listOption.label }, i))
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownCell.js","sources":["../../../../../../../../packages/vuu-table-extras/src/cell-renderers/dropdown-cell/DropdownCell.tsx"],"sourcesContent":["import { useLookupValues } from \"@vuu-ui/vuu-data-react\";\nimport type { VuuColumnDataType } from \"@vuu-ui/vuu-protocol-types\";\nimport { ListOption, TableCellRendererProps } from \"@vuu-ui/vuu-table-types\";\nimport {\n dataColumnAndKeyUnchanged,\n dispatchCustomEvent,\n getSelectedOption,\n isRpcSuccess,\n registerComponent,\n} from \"@vuu-ui/vuu-utils\";\nimport cx from \"clsx\";\nimport { Dropdown, Option } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport {\n KeyboardEventHandler,\n MouseEventHandler,\n SyntheticEvent,\n memo,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport dropdownCellCss from \"./DropdownCell.css\";\n\nconst classBase = \"vuuTableDropdownCell\";\n\nexport const DropdownCell = memo(\n function DropdownCell({\n column,\n dataRow,\n editedDuringCurrentSession,\n onEdit,\n }: TableCellRendererProps) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-dropdown-cell\",\n css: dropdownCellCss,\n window: targetWindow,\n });\n\n if (editedDuringCurrentSession) {\n console.log(`${column.name} edited ${editedDuringCurrentSession}`);\n }\n\n const [open, setOpen] = useState(false);\n const dataValue = dataRow[column.name] as string | number;\n const { values } = useLookupValues(column, dataValue);\n const valueRef = useRef<ListOption>(undefined);\n\n useMemo(() => {\n valueRef.current = getSelectedOption(values, dataValue);\n }, [dataValue, values]);\n\n const handleOpenChange = useCallback((isOpen: boolean) => {\n console.log(`handleOpenChange ${isOpen}`);\n if (isOpen === false) {\n setOpen(false);\n }\n }, []);\n\n const handleSelectionChange = useCallback(\n async (evt: SyntheticEvent, [selectedOption]: ListOption[]) => {\n if (selectedOption) {\n // Note, we do not setState locally when a selection is made, we just send the update\n // to the server. We rely on the update coming back in from a server response which\n // we handle in the useMemo above. If we worry that server repsonses might be too slow\n // we can extend this logic with some kind of pending update state.\n const response = await onEdit?.(\n {\n editType: \"commit\",\n isValid: true,\n previousValue: valueRef.current?.value,\n value: selectedOption.value as VuuColumnDataType,\n },\n \"commit\",\n );\n if (isRpcSuccess(response)) {\n // TODO this should be done in TableCell\n dispatchCustomEvent(evt.target as HTMLElement, \"vuu-commit\");\n }\n }\n },\n [onEdit],\n );\n\n const handleClick = useCallback<\n MouseEventHandler<HTMLButtonElement>\n >(() => {\n if (!open) {\n setOpen(true);\n }\n }, [open]);\n\n const handleKeyDown = useCallback<KeyboardEventHandler>(\n (e) => {\n if (e.key === \"Enter\" && !open) {\n e.preventDefault();\n e.stopPropagation();\n setOpen(true);\n }\n },\n [open],\n );\n\n const { current: selectedOption } = valueRef;\n return (\n <Dropdown<ListOption>\n className={cx(classBase, {\n [`${classBase}-edited`]: editedDuringCurrentSession === true,\n })}\n data-icon=\"triangle-down\"\n onClick={handleClick}\n onKeyDownCapture={handleKeyDown}\n onOpenChange={handleOpenChange}\n onSelectionChange={handleSelectionChange}\n open={open}\n selected={selectedOption ? [selectedOption] : []}\n value={selectedOption?.label}\n >\n {values.map((listOption, i) => (\n <Option key={i} value={listOption}>\n {listOption.label}\n </Option>\n ))}\n </Dropdown>\n );\n },\n (p: TableCellRendererProps, p1: TableCellRendererProps) =>\n p.editedDuringCurrentSession !== p1.editedDuringCurrentSession &&\n dataColumnAndKeyUnchanged(p, p1),\n);\nregisterComponent(\"dropdown-cell\", DropdownCell, \"cell-renderer\", {\n userCanAssign: false,\n});\n"],"names":["DropdownCell","selectedOption"],"mappings":"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"}
1
+ {"version":3,"file":"DropdownCell.js","sources":["../../../../../../../../packages/vuu-table-extras/src/cell-renderers/dropdown-cell/DropdownCell.tsx"],"sourcesContent":["import { useLookupValues } from \"@vuu-ui/vuu-data-react\";\nimport type { VuuColumnDataType } from \"@vuu-ui/vuu-protocol-types\";\nimport { ListOption, TableCellRendererProps } from \"@vuu-ui/vuu-table-types\";\nimport {\n dataColumnAndKeyUnchanged,\n dispatchCustomEvent,\n getSelectedOption,\n isRpcSuccess,\n registerComponent,\n} from \"@vuu-ui/vuu-utils\";\nimport { isEditRowReadOnly } from \"@vuu-ui/vuu-data-editing\";\nimport cx from \"clsx\";\nimport { Dropdown, Option } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport {\n KeyboardEventHandler,\n MouseEventHandler,\n SyntheticEvent,\n memo,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport dropdownCellCss from \"./DropdownCell.css\";\n\nconst classBase = \"vuuTableDropdownCell\";\n\nexport const DropdownCell = memo(\n function DropdownCell({\n column,\n dataRow,\n editedDuringCurrentSession,\n onEdit,\n }: TableCellRendererProps) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-dropdown-cell\",\n css: dropdownCellCss,\n window: targetWindow,\n });\n\n if (editedDuringCurrentSession) {\n console.log(`${column.name} edited ${editedDuringCurrentSession}`);\n }\n\n const [open, setOpen] = useState(false);\n const dataValue = dataRow[column.name] as string | number;\n const readOnly = isEditRowReadOnly(dataRow);\n const { values } = useLookupValues(column, dataValue);\n const valueRef = useRef<ListOption>(undefined);\n\n useMemo(() => {\n valueRef.current = getSelectedOption(values, dataValue);\n }, [dataValue, values]);\n\n const handleOpenChange = useCallback((isOpen: boolean) => {\n console.log(`handleOpenChange ${isOpen}`);\n if (isOpen === false) {\n setOpen(false);\n }\n }, []);\n\n const handleSelectionChange = useCallback(\n async (evt: SyntheticEvent, [selectedOption]: ListOption[]) => {\n if (selectedOption) {\n // Note, we do not setState locally when a selection is made, we just send the update\n // to the server. We rely on the update coming back in from a server response which\n // we handle in the useMemo above. If we worry that server repsonses might be too slow\n // we can extend this logic with some kind of pending update state.\n const response = await onEdit?.(\n {\n editType: \"commit\",\n isValid: true,\n previousValue: valueRef.current?.value,\n value: selectedOption.value as VuuColumnDataType,\n },\n \"commit\",\n );\n if (isRpcSuccess(response)) {\n // TODO this should be done in TableCell\n dispatchCustomEvent(evt.target as HTMLElement, \"vuu-commit\");\n }\n }\n },\n [onEdit],\n );\n\n const handleClick = useCallback<\n MouseEventHandler<HTMLButtonElement>\n >(() => {\n if (!open) {\n setOpen(true);\n }\n }, [open]);\n\n const handleKeyDown = useCallback<KeyboardEventHandler>(\n (e) => {\n if (e.key === \"Enter\" && !open) {\n e.preventDefault();\n e.stopPropagation();\n setOpen(true);\n }\n },\n [open],\n );\n\n const { current: selectedOption } = valueRef;\n return (\n <Dropdown<ListOption>\n className={cx(classBase, {\n [`${classBase}-edited`]: editedDuringCurrentSession === true,\n })}\n data-icon=\"triangle-down\"\n onClick={handleClick}\n onKeyDownCapture={handleKeyDown}\n onOpenChange={handleOpenChange}\n onSelectionChange={handleSelectionChange}\n open={open}\n readOnly={readOnly}\n selected={selectedOption ? [selectedOption] : []}\n value={selectedOption?.label}\n >\n {values.map((listOption, i) => (\n <Option key={i} value={listOption}>\n {listOption.label}\n </Option>\n ))}\n </Dropdown>\n );\n },\n (p: TableCellRendererProps, p1: TableCellRendererProps) =>\n p.editedDuringCurrentSession !== p1.editedDuringCurrentSession &&\n dataColumnAndKeyUnchanged(p, p1),\n);\nregisterComponent(\"dropdown-cell\", DropdownCell, \"cell-renderer\", {\n userCanAssign: false,\n});\n"],"names":["DropdownCell","selectedOption"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
- import { Dialog, DialogHeader, DialogContent, FileDropZone, FileDropZoneIcon, FileDropZoneTrigger, DialogActions, Button } from '@salt-ds/core';
2
+ import { FileDropZone, FileDropZoneIcon, FileDropZoneTrigger, Dialog, DialogHeader, DialogContent, DialogActions, Button } from '@salt-ds/core';
3
3
  import { useComponentCssInjection } from '@salt-ds/styles';
4
4
  import { useWindow } from '@salt-ds/window';
5
5
  import { useState, useCallback } from 'react';
@@ -11,18 +11,13 @@ const CsvUpload = (props) => {
11
11
  const {
12
12
  children,
13
13
  dialogTitle = "Import CSV",
14
+ embedded = false,
14
15
  onCancel,
15
16
  onClose,
16
17
  open
17
18
  } = props;
18
19
  const isControlledOpen = open !== void 0;
19
20
  const [internalOpen, setInternalOpen] = useState(open ?? true);
20
- const handleCancel = useCallback(() => {
21
- if (!isControlledOpen) {
22
- setInternalOpen(false);
23
- }
24
- onCancel?.();
25
- }, [isControlledOpen, onCancel]);
26
21
  const dialogOpen = isControlledOpen ? open : internalOpen;
27
22
  const targetWindow = useWindow();
28
23
  useComponentCssInjection({
@@ -32,6 +27,7 @@ const CsvUpload = (props) => {
32
27
  });
33
28
  const {
34
29
  canImport,
30
+ cancelImport,
35
31
  isProcessingFile,
36
32
  isImporting,
37
33
  importData,
@@ -40,52 +36,70 @@ const CsvUpload = (props) => {
40
36
  schema,
41
37
  validation
42
38
  } = useCsvUpload(props);
39
+ const handleCancel = useCallback(async () => {
40
+ await cancelImport();
41
+ if (!isControlledOpen) {
42
+ setInternalOpen(false);
43
+ }
44
+ onCancel?.();
45
+ }, [cancelImport, isControlledOpen, onCancel]);
43
46
  const handleImport = useCallback(async () => {
44
- await importData();
45
- onClose?.();
47
+ if (await importData()) {
48
+ onClose?.();
49
+ }
46
50
  }, [importData, onClose]);
51
+ const content = /* @__PURE__ */ jsxs("div", { className: classBase, children: [
52
+ /* @__PURE__ */ jsxs(
53
+ FileDropZone,
54
+ {
55
+ className: `${classBase}-dropZone`,
56
+ disabled: schema === void 0 || isProcessingFile || isImporting,
57
+ onDrop,
58
+ status: validation && validation.errors.length > 0 ? "error" : void 0,
59
+ children: [
60
+ /* @__PURE__ */ jsx(FileDropZoneIcon, {}),
61
+ validation && validation.errors.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
62
+ /* @__PURE__ */ jsx("div", { children: "Your file contains errors" }),
63
+ /* @__PURE__ */ jsx("div", { children: " Please rectify and reupload" })
64
+ ] }) : /* @__PURE__ */ jsx("div", { children: "Drop a file here or" }),
65
+ /* @__PURE__ */ jsx(FileDropZoneTrigger, { accept: ".csv,text/csv", onChange: onTriggerChange, children: "BROWSE FILES" })
66
+ ]
67
+ }
68
+ ),
69
+ children
70
+ ] });
71
+ const actions = /* @__PURE__ */ jsxs(DialogActions, { children: [
72
+ /* @__PURE__ */ jsx(
73
+ Button,
74
+ {
75
+ appearance: "solid",
76
+ disabled: isImporting,
77
+ sentiment: "negative",
78
+ onClick: handleCancel,
79
+ children: "Cancel"
80
+ }
81
+ ),
82
+ /* @__PURE__ */ jsx(
83
+ Button,
84
+ {
85
+ disabled: !canImport,
86
+ appearance: "solid",
87
+ sentiment: "accented",
88
+ onClick: handleImport,
89
+ children: isProcessingFile ? "Validating..." : isImporting ? "Importing..." : "Import"
90
+ }
91
+ )
92
+ ] });
93
+ if (embedded) {
94
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
95
+ content,
96
+ actions
97
+ ] });
98
+ }
47
99
  return /* @__PURE__ */ jsxs(Dialog, { open: dialogOpen, children: [
48
100
  /* @__PURE__ */ jsx(DialogHeader, { header: dialogTitle }),
49
- /* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsxs("div", { className: classBase, children: [
50
- /* @__PURE__ */ jsxs(
51
- FileDropZone,
52
- {
53
- className: `${classBase}-dropZone`,
54
- disabled: schema === void 0 || isProcessingFile || isImporting,
55
- onDrop,
56
- status: validation && validation.errors.length > 0 ? "error" : void 0,
57
- children: [
58
- /* @__PURE__ */ jsx(FileDropZoneIcon, {}),
59
- validation && validation.errors.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
60
- /* @__PURE__ */ jsx("div", { children: "Your file contains errors" }),
61
- /* @__PURE__ */ jsx("div", { children: " Please rectify and reupload" })
62
- ] }) : /* @__PURE__ */ jsx("div", { children: "Drop a file here or" }),
63
- /* @__PURE__ */ jsx(
64
- FileDropZoneTrigger,
65
- {
66
- accept: ".csv,text/csv",
67
- onChange: onTriggerChange,
68
- children: "BROWSE FILES"
69
- }
70
- )
71
- ]
72
- }
73
- ),
74
- children
75
- ] }) }),
76
- /* @__PURE__ */ jsxs(DialogActions, { children: [
77
- /* @__PURE__ */ jsx(Button, { appearance: "solid", sentiment: "negative", onClick: handleCancel, children: "Cancel" }),
78
- /* @__PURE__ */ jsx(
79
- Button,
80
- {
81
- disabled: !canImport,
82
- appearance: "solid",
83
- sentiment: "accented",
84
- onClick: handleImport,
85
- children: isProcessingFile ? "Validating..." : isImporting ? "Importing..." : "Import"
86
- }
87
- )
88
- ] })
101
+ /* @__PURE__ */ jsx(DialogContent, { children: content }),
102
+ actions
89
103
  ] });
90
104
  };
91
105
 
@@ -1 +1 @@
1
- {"version":3,"file":"CsvUpload.js","sources":["../../../../../../../packages/vuu-table-extras/src/csv-upload/CsvUpload.tsx"],"sourcesContent":["import {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogHeader,\n FileDropZone,\n FileDropZoneIcon,\n FileDropZoneTrigger,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { type ReactNode, useCallback, useState } from \"react\";\nimport type { DataSource } from \"@vuu-ui/vuu-data-types\";\nimport type { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport type { CsvParseError, CsvParseOptions } from \"./parse/csv-parse\";\nimport type { CsvValidationStructuredError } from \"./parse/csv-schema-validation\";\nimport type { CsvUploadTableData } from \"./parse/csv-upload-utils\";\nimport { useCsvUpload } from \"./useCsvUpload\";\nimport css from \"./CsvUpload.css\";\n\nexport type CsvUploadImportedResult = {\n rpcResult: unknown;\n tableData: CsvUploadTableData;\n};\n\nexport type CsvUploadErrors = {\n schemaError?: CsvUploadError;\n validationError?: CsvUploadError;\n importError?: CsvUploadError;\n};\n\nexport type CsvUploadError = {\n message: string;\n parseError?: CsvParseError;\n validationError?: CsvValidationStructuredError;\n source: \"schema\" | \"validation\" | \"import\";\n};\n\nexport type CsvUploadErrorResult = {\n errors: CsvUploadErrors;\n};\n\nexport type CsvUploadSessionTable = VuuTable;\n\nexport type CsvUploadSessionEndReason = \"saved\" | \"discarded\" | \"failed\";\n\nexport type CsvUploadSessionEndResult = {\n reason: CsvUploadSessionEndReason;\n sessionTable?: CsvUploadSessionTable;\n};\n\nexport type CsvUploadPhase =\n | \"idle\"\n | \"processing\"\n | \"preview-ready\"\n | \"importing\"\n | \"imported\"\n | \"failed\";\n\nexport interface CsvUploadProps {\n children?: ReactNode;\n dataSource: DataSource;\n onImportSessionStarted?: (dataSource: DataSource) => void;\n onImportSessionEnded?: (result: CsvUploadSessionEndResult) => void;\n onError?: (result: CsvUploadErrorResult | undefined) => void;\n onImported?: (result: CsvUploadImportedResult) => void;\n onProcessingStarted?: () => void;\n dialogTitle?: string;\n maxRows?: number;\n onCancel?: () => void;\n onClose?: () => void;\n open?: boolean;\n parseOptions?: CsvParseOptions;\n}\n\nconst classBase = \"vuuCsvUpload\";\n\nexport const CsvUpload = (props: CsvUploadProps) => {\n const {\n children,\n dialogTitle = \"Import CSV\",\n onCancel,\n onClose,\n open,\n } = props;\n const isControlledOpen = open !== undefined;\n const [internalOpen, setInternalOpen] = useState(open ?? true);\n\n const handleCancel = useCallback(() => {\n if (!isControlledOpen) {\n setInternalOpen(false);\n }\n onCancel?.();\n }, [isControlledOpen, onCancel]);\n\n const dialogOpen = isControlledOpen ? open : internalOpen;\n\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-csv-upload\",\n css,\n window: targetWindow,\n });\n\n const {\n canImport,\n isProcessingFile,\n isImporting,\n importData,\n onDrop,\n onTriggerChange,\n schema,\n validation,\n } = useCsvUpload(props);\n\n const handleImport = useCallback(async () => {\n await importData();\n onClose?.();\n }, [importData, onClose]);\n\n return (\n <Dialog open={dialogOpen}>\n <DialogHeader header={dialogTitle} />\n <DialogContent>\n <div className={classBase}>\n <FileDropZone\n className={`${classBase}-dropZone`}\n disabled={schema === undefined || isProcessingFile || isImporting}\n onDrop={onDrop}\n status={\n validation && validation.errors.length > 0 ? \"error\" : undefined\n }\n >\n <FileDropZoneIcon />\n {validation && validation.errors.length > 0 ? (\n <>\n <div>Your file contains errors</div>\n <div> Please rectify and reupload</div>\n </>\n ) : (\n <div>Drop a file here or</div>\n )}\n <FileDropZoneTrigger\n accept=\".csv,text/csv\"\n onChange={onTriggerChange}\n >\n BROWSE FILES\n </FileDropZoneTrigger>\n </FileDropZone>\n {children}\n </div>\n </DialogContent>\n <DialogActions>\n <Button appearance=\"solid\" sentiment=\"negative\" onClick={handleCancel}>\n Cancel\n </Button>\n <Button\n disabled={!canImport}\n appearance=\"solid\"\n sentiment=\"accented\"\n onClick={handleImport}\n >\n {isProcessingFile\n ? \"Validating...\"\n : isImporting\n ? \"Importing...\"\n : \"Import\"}\n </Button>\n </DialogActions>\n </Dialog>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CsvUpload.js","sources":["../../../../../../../packages/vuu-table-extras/src/csv-upload/CsvUpload.tsx"],"sourcesContent":["import {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogHeader,\n FileDropZone,\n FileDropZoneIcon,\n FileDropZoneTrigger,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { type ReactNode, useCallback, useState } from \"react\";\nimport type { DataSource } from \"@vuu-ui/vuu-data-types\";\nimport type { EditSession } from \"@vuu-ui/vuu-data-editing\";\nimport type { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport type { CsvParseError, CsvParseOptions } from \"./parse/csv-parse\";\nimport type { CsvValidationStructuredError } from \"./parse/csv-schema-validation\";\nimport type { CsvUploadTableData } from \"./parse/csv-upload-utils\";\nimport { useCsvUpload } from \"./useCsvUpload\";\nimport css from \"./CsvUpload.css\";\n\nexport type CsvUploadImportedResult = {\n tableData: CsvUploadTableData;\n};\n\nexport type CsvUploadPreviewResult = {\n dataSource: DataSource;\n editSession: EditSession;\n tableData: CsvUploadTableData;\n};\n\nexport type CsvUploadErrors = {\n schemaError?: CsvUploadError;\n validationError?: CsvUploadError;\n importError?: CsvUploadError;\n};\n\nexport type CsvUploadError = {\n message: string;\n parseError?: CsvParseError;\n validationError?: CsvValidationStructuredError;\n source: \"schema\" | \"validation\" | \"import\";\n};\n\nexport type CsvUploadErrorResult = {\n errors: CsvUploadErrors;\n};\n\nexport type CsvUploadSessionTable = VuuTable;\n\nexport type CsvUploadSessionEndReason = \"saved\" | \"discarded\" | \"failed\";\n\nexport type CsvUploadSessionEndResult = {\n reason: CsvUploadSessionEndReason;\n sessionTable?: CsvUploadSessionTable;\n};\n\nexport type CsvUploadPhase =\n | \"idle\"\n | \"processing\"\n | \"preview-ready\"\n | \"importing\"\n | \"imported\"\n | \"failed\";\n\nexport interface CsvUploadProps {\n children?: ReactNode;\n dataSource: DataSource;\n embedded?: boolean;\n onImportSessionStarted?: (dataSource: DataSource) => void;\n onImportSessionEnded?: (result: CsvUploadSessionEndResult) => void;\n onError?: (result: CsvUploadErrorResult | undefined) => void;\n onImported?: (result: CsvUploadImportedResult) => void;\n onPreview?: (result: CsvUploadPreviewResult) => void;\n onProcessingStarted?: () => void;\n dialogTitle?: string;\n maxRows?: number;\n onCancel?: () => void;\n onClose?: () => void;\n open?: boolean;\n parseOptions?: CsvParseOptions;\n importMode?: \"direct\" | \"preview\";\n}\n\nconst classBase = \"vuuCsvUpload\";\n\nexport const CsvUpload = (props: CsvUploadProps) => {\n const {\n children,\n dialogTitle = \"Import CSV\",\n embedded = false,\n onCancel,\n onClose,\n open,\n } = props;\n const isControlledOpen = open !== undefined;\n const [internalOpen, setInternalOpen] = useState(open ?? true);\n\n const dialogOpen = isControlledOpen ? open : internalOpen;\n\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-csv-upload\",\n css,\n window: targetWindow,\n });\n\n const {\n canImport,\n cancelImport,\n isProcessingFile,\n isImporting,\n importData,\n onDrop,\n onTriggerChange,\n schema,\n validation,\n } = useCsvUpload(props);\n\n const handleCancel = useCallback(async () => {\n await cancelImport();\n if (!isControlledOpen) {\n setInternalOpen(false);\n }\n onCancel?.();\n }, [cancelImport, isControlledOpen, onCancel]);\n\n const handleImport = useCallback(async () => {\n if (await importData()) {\n onClose?.();\n }\n }, [importData, onClose]);\n\n const content = (\n <div className={classBase}>\n <FileDropZone\n className={`${classBase}-dropZone`}\n disabled={schema === undefined || isProcessingFile || isImporting}\n onDrop={onDrop}\n status={\n validation && validation.errors.length > 0 ? \"error\" : undefined\n }\n >\n <FileDropZoneIcon />\n {validation && validation.errors.length > 0 ? (\n <>\n <div>Your file contains errors</div>\n <div> Please rectify and reupload</div>\n </>\n ) : (\n <div>Drop a file here or</div>\n )}\n <FileDropZoneTrigger accept=\".csv,text/csv\" onChange={onTriggerChange}>\n BROWSE FILES\n </FileDropZoneTrigger>\n </FileDropZone>\n {children}\n </div>\n );\n\n const actions = (\n <DialogActions>\n <Button\n appearance=\"solid\"\n disabled={isImporting}\n sentiment=\"negative\"\n onClick={handleCancel}\n >\n Cancel\n </Button>\n <Button\n disabled={!canImport}\n appearance=\"solid\"\n sentiment=\"accented\"\n onClick={handleImport}\n >\n {isProcessingFile\n ? \"Validating...\"\n : isImporting\n ? \"Importing...\"\n : \"Import\"}\n </Button>\n </DialogActions>\n );\n\n if (embedded) {\n return (\n <>\n {content}\n {actions}\n </>\n );\n }\n\n return (\n <Dialog open={dialogOpen}>\n <DialogHeader header={dialogTitle} />\n <DialogContent>{content}</DialogContent>\n {actions}\n </Dialog>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ var css = ".vuuDataUploadPreview {\n display: flex;\n flex-direction: column;\n height: 420px;\n width: 900px;\n\n .vuuDataUploadPreview-content {\n flex: 1 1 auto;\n }\n}\n";
2
+
3
+ export { css as default };
4
+ //# sourceMappingURL=DataUploadPreview.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataUploadPreview.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,116 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useComponentCssInjection } from '@salt-ds/styles';
3
+ import { useWindow } from '@salt-ds/window';
4
+ import { DataEditingProvider, EditButtons, UNDO_CELL_RENDERER, EDIT_ACTION_ROW_CLASS_NAME_GENERATOR } from '@vuu-ui/vuu-data-editing';
5
+ import { Table } from '@vuu-ui/vuu-table';
6
+ import cx from 'clsx';
7
+ import { useMemo, useCallback } from 'react';
8
+ import { TableFooter, TableFooterTray } from '../../table-footer/TableFooter.js';
9
+ import css from './DataUploadPreview.css.js';
10
+ import { getSessionDataSource, useDataUploadPreview } from './useDataUploadPreview.js';
11
+
12
+ const classBase = "vuuDataUploadPreview";
13
+ const undoColumn = {
14
+ name: "undo",
15
+ source: "client",
16
+ width: 80,
17
+ type: {
18
+ name: "string",
19
+ renderer: {
20
+ name: UNDO_CELL_RENDERER
21
+ }
22
+ }
23
+ };
24
+ const rowClassNameGenerators = [EDIT_ACTION_ROW_CLASS_NAME_GENERATOR];
25
+ const DataUploadPreview = ({
26
+ className,
27
+ editSession,
28
+ onClose,
29
+ saveLabel = "Submit",
30
+ tableSchema,
31
+ ...htmlAttributes
32
+ }) => {
33
+ const dataSource = useMemo(
34
+ () => getSessionDataSource(editSession),
35
+ [editSession]
36
+ );
37
+ const targetWindow = useWindow();
38
+ useComponentCssInjection({
39
+ testId: "vuu-data-upload-preview",
40
+ css,
41
+ window: targetWindow
42
+ });
43
+ const {
44
+ canCancel,
45
+ canSave,
46
+ hasSelection,
47
+ onCancel,
48
+ onDelete,
49
+ onSave,
50
+ sessionError
51
+ } = useDataUploadPreview({ dataSource, editSession, onClose });
52
+ const isRowSelectable = useCallback(
53
+ (dataRow) => dataRow.vuu_action !== "deleteRow",
54
+ []
55
+ );
56
+ const config = useMemo(() => {
57
+ const columns = tableSchema.columns.map(
58
+ (column) => column.name === "vuuMsg" ? {
59
+ ...column,
60
+ editable: false,
61
+ hidden: false,
62
+ label: "Error",
63
+ width: 300
64
+ } : {
65
+ ...column,
66
+ editable: true
67
+ }
68
+ );
69
+ if (!columns.some(({ name }) => name === "vuuMsg")) {
70
+ columns.push({
71
+ editable: false,
72
+ label: "Error",
73
+ name: "vuuMsg",
74
+ serverDataType: "string",
75
+ width: 300
76
+ });
77
+ }
78
+ return {
79
+ columns: columns.concat({ hidden: true, name: "vuu_action" }, undoColumn),
80
+ columnDefaultWidth: 150,
81
+ rowClassNameGenerators,
82
+ rowSeparators: true,
83
+ zebraStripes: true
84
+ };
85
+ }, [tableSchema.columns]);
86
+ return /* @__PURE__ */ jsxs("div", { ...htmlAttributes, className: cx(classBase, className), children: [
87
+ sessionError ? /* @__PURE__ */ jsx("div", { role: "alert", children: sessionError }) : null,
88
+ /* @__PURE__ */ jsx("div", { className: `${classBase}-content`, children: /* @__PURE__ */ jsx(DataEditingProvider, { editSession, children: /* @__PURE__ */ jsx(
89
+ Table,
90
+ {
91
+ config,
92
+ "data-viewport": dataSource.viewport,
93
+ dataSource,
94
+ isRowSelectable,
95
+ renderBufferSize: 10,
96
+ selectionModel: "checkbox"
97
+ }
98
+ ) }) }),
99
+ /* @__PURE__ */ jsx(TableFooter, { children: /* @__PURE__ */ jsx(TableFooterTray, { position: "center", children: /* @__PURE__ */ jsx(
100
+ EditButtons,
101
+ {
102
+ canCancel,
103
+ canSave,
104
+ editSession,
105
+ hasSelection,
106
+ onCancel,
107
+ onDelete,
108
+ onSave,
109
+ saveLabel
110
+ }
111
+ ) }) })
112
+ ] });
113
+ };
114
+
115
+ export { DataUploadPreview };
116
+ //# sourceMappingURL=DataUploadPreview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataUploadPreview.js","sources":["../../../../../../../../packages/vuu-table-extras/src/csv-upload/data-upload-preview/DataUploadPreview.tsx"],"sourcesContent":["import { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport type { TableSchema } from \"@vuu-ui/vuu-data-types\";\nimport {\n DataEditingProvider,\n EDIT_ACTION_ROW_CLASS_NAME_GENERATOR,\n EditButtons,\n type EditSession,\n UNDO_CELL_RENDERER,\n} from \"@vuu-ui/vuu-data-editing\";\nimport { Table } from \"@vuu-ui/vuu-table\";\nimport type {\n ColumnDescriptor,\n DataRow,\n TableConfig,\n} from \"@vuu-ui/vuu-table-types\";\nimport cx from \"clsx\";\nimport type { HTMLAttributes } from \"react\";\nimport { useCallback, useMemo } from \"react\";\nimport { TableFooter, TableFooterTray } from \"../../table-footer/TableFooter\";\nimport css from \"./DataUploadPreview.css\";\nimport {\n getSessionDataSource,\n useDataUploadPreview,\n} from \"./useDataUploadPreview\";\n\nconst classBase = \"vuuDataUploadPreview\";\n\nconst undoColumn: ColumnDescriptor = {\n name: \"undo\",\n source: \"client\",\n width: 80,\n type: {\n name: \"string\",\n renderer: {\n name: UNDO_CELL_RENDERER,\n },\n },\n};\n\nconst rowClassNameGenerators = [EDIT_ACTION_ROW_CLASS_NAME_GENERATOR];\n\nexport interface DataUploadPreviewProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onSelect\"> {\n editSession: EditSession;\n onClose: () => void;\n saveLabel?: string;\n tableSchema: TableSchema;\n}\n\nexport const DataUploadPreview = ({\n className,\n editSession,\n onClose,\n saveLabel = \"Submit\",\n tableSchema,\n ...htmlAttributes\n}: DataUploadPreviewProps) => {\n const dataSource = useMemo(\n () => getSessionDataSource(editSession),\n [editSession],\n );\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-data-upload-preview\",\n css,\n window: targetWindow,\n });\n\n const {\n canCancel,\n canSave,\n hasSelection,\n onCancel,\n onDelete,\n onSave,\n sessionError,\n } = useDataUploadPreview({ dataSource, editSession, onClose });\n\n const isRowSelectable = useCallback(\n (dataRow: DataRow) => dataRow.vuu_action !== \"deleteRow\",\n [],\n );\n const config = useMemo<TableConfig>(() => {\n const columns = tableSchema.columns.map<ColumnDescriptor>((column) =>\n column.name === \"vuuMsg\"\n ? {\n ...column,\n editable: false,\n hidden: false,\n label: \"Error\",\n width: 300,\n }\n : {\n ...column,\n editable: true,\n },\n );\n if (!columns.some(({ name }) => name === \"vuuMsg\")) {\n columns.push({\n editable: false,\n label: \"Error\",\n name: \"vuuMsg\",\n serverDataType: \"string\",\n width: 300,\n });\n }\n\n return {\n columns: columns.concat({ hidden: true, name: \"vuu_action\" }, undoColumn),\n columnDefaultWidth: 150,\n rowClassNameGenerators,\n rowSeparators: true,\n zebraStripes: true,\n };\n }, [tableSchema.columns]);\n\n return (\n <div {...htmlAttributes} className={cx(classBase, className)}>\n {sessionError ? <div role=\"alert\">{sessionError}</div> : null}\n <div className={`${classBase}-content`}>\n <DataEditingProvider editSession={editSession}>\n <Table\n config={config}\n data-viewport={dataSource.viewport}\n dataSource={dataSource}\n isRowSelectable={isRowSelectable}\n renderBufferSize={10}\n selectionModel=\"checkbox\"\n />\n </DataEditingProvider>\n </div>\n <TableFooter>\n <TableFooterTray position=\"center\">\n <EditButtons\n canCancel={canCancel}\n canSave={canSave}\n editSession={editSession}\n hasSelection={hasSelection}\n onCancel={onCancel}\n onDelete={onDelete}\n onSave={onSave}\n saveLabel={saveLabel}\n />\n </TableFooterTray>\n </TableFooter>\n </div>\n );\n};\n"],"names":[],"mappings":"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"}