@vuu-ui/vuu-table-extras 4.0.0-alpha.9 → 4.0.0-beta.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.
Files changed (158) hide show
  1. package/package.json +18 -18
  2. package/src/cell-renderers/pct-progress-cell/PctProgressCell.css.js +2 -2
  3. package/src/cell-renderers/progress-cell/ProgressCell.css.js +2 -2
  4. package/src/column-expression-input/ColumnExpressionInput.css.js +5 -5
  5. package/src/column-expression-input/column-language-parser/column-expression-parse-utils.js +1 -1
  6. package/src/column-expression-input/theme.js +1 -1
  7. package/src/column-expression-input/useColumnExpressionEditor.js +1 -0
  8. package/src/column-expression-input/useColumnExpressionSuggestionProvider.js +2 -2
  9. package/src/column-formatting-settings/ColumnFormattingPanel.js +12 -9
  10. package/src/column-formatting-settings/DateTimeFormattingSettings.js +107 -3
  11. package/src/column-formatting-settings/LongTypeFormattingSettings.js +8 -3
  12. package/src/column-picker/ColumnModel.js +3 -2
  13. package/src/column-picker/ColumnPicker.js +1 -3
  14. package/src/column-settings-panel/ColumnNameLabel.css.js +1 -1
  15. package/src/csv-export/export-utils.js +76 -20
  16. package/src/csv-export/index.js +1 -1
  17. package/src/csv-export/useCsvExport.js +9 -1
  18. package/src/csv-upload/CsvUpload.css.js +36 -2
  19. package/src/csv-upload/CsvUpload.js +107 -63
  20. package/src/csv-upload/data-upload-preview/DataUploadPreview.js +1 -1
  21. package/src/csv-upload/parse/csv-errors.js +1 -1
  22. package/src/csv-upload/parse/csv-parse.js +1 -1
  23. package/src/csv-upload/parse/csv-schema-validation.js +46 -7
  24. package/src/csv-upload/parse/csv-upload-utils.js +47 -2
  25. package/src/csv-upload/session/index.js +2 -0
  26. package/src/csv-upload/session/useImportSchema.js +44 -0
  27. package/src/csv-upload/session/useImportSession.js +204 -0
  28. package/src/csv-upload/useCsvUpload.js +54 -199
  29. package/src/freeze-control/FreezeControl.css.js +4 -4
  30. package/src/freeze-control/FrozenBanner.css.js +2 -2
  31. package/src/table-footer/TableFooter.js +3 -3
  32. package/types/calculated-column/CalculatedColumnPanel.d.ts +1 -1
  33. package/types/cell-renderers/background-cell/BackgroundCell.d.ts +1 -1
  34. package/types/cell-renderers/background-cell/BackgroundCellConfigurationEditor.d.ts +1 -1
  35. package/types/cell-renderers/button-cell/IconButtonCell.d.ts +1 -1
  36. package/types/cell-renderers/dropdown-cell/DropdownCell.d.ts +1 -1
  37. package/types/cell-renderers/lookup-cell/LookupCell.d.ts +1 -1
  38. package/types/cell-renderers/pct-progress-cell/PctProgressCell.d.ts +1 -1
  39. package/types/column-expression-input/ColumnExpressionInput.d.ts +1 -1
  40. package/types/column-expression-input/column-language-parser/column-expression-parse-utils.d.ts +1 -1
  41. package/types/column-expression-input/column-language-parser/test.d.mts +1 -1
  42. package/types/column-expression-input/useColumnExpressionEditor.d.ts +4 -4
  43. package/types/column-formatting-settings/BaseNumericFormattingSettings.d.ts +1 -1
  44. package/types/column-formatting-settings/ColumnFormattingPanel.d.ts +1 -1
  45. package/types/column-formatting-settings/DateTimeFormattingSettings.d.ts +1 -1
  46. package/types/column-formatting-settings/LongTypeFormattingSettings.d.ts +1 -2
  47. package/types/column-menu/ColumnMenu.d.ts +1 -1
  48. package/types/column-picker/ColumnPicker.d.ts +4 -4
  49. package/types/column-picker/ColumnPickerAction.d.ts +1 -1
  50. package/types/column-settings-panel/ColumnNameLabel.d.ts +1 -1
  51. package/types/column-settings-panel/ColumnSettingsPanel.d.ts +1 -1
  52. package/types/csv-export/export-utils.d.ts +22 -9
  53. package/types/csv-export/index.d.ts +1 -1
  54. package/types/csv-export/useCsvExport.d.ts +5 -2
  55. package/types/csv-upload/CsvUpload.d.ts +2 -6
  56. package/types/csv-upload/data-upload-preview/DataUploadPreview.d.ts +1 -1
  57. package/types/csv-upload/parse/csv-errors.d.ts +1 -1
  58. package/types/csv-upload/parse/csv-schema-validation.d.ts +8 -2
  59. package/types/csv-upload/parse/csv-upload-utils.d.ts +9 -0
  60. package/types/csv-upload/session/index.d.ts +2 -0
  61. package/types/csv-upload/session/useImportSchema.d.ts +13 -0
  62. package/types/csv-upload/session/useImportSession.d.ts +26 -0
  63. package/types/csv-upload/useCsvUpload.d.ts +3 -3
  64. package/types/datasource-stats/DatasourceStats.d.ts +1 -1
  65. package/types/freeze-control/FreezeControl.d.ts +1 -1
  66. package/types/freeze-control/FrozenBanner.d.ts +1 -1
  67. package/types/inline-add-row/InlineAddRow.d.ts +1 -1
  68. package/types/inline-add-row/useInlineAddRow.d.ts +2 -1
  69. package/types/tabbed-table-config-panel/TabbedTableConfigPanel.d.ts +5 -5
  70. package/types/tabbed-table-config-panel/TabbedTableSettingsAction.d.ts +1 -1
  71. package/types/table-footer/TableFooter.d.ts +4 -4
  72. package/types/table-provider/TableProvider.d.ts +1 -1
  73. package/types/table-settings-panel/TableSettingsPanel.d.ts +1 -1
  74. package/types/src/calculated-column/CalculatedColumnPanel.d.ts +0 -12
  75. package/types/src/calculated-column/useCalculatedColumnPanel.d.ts +0 -10
  76. package/types/src/calculated-column/useEditCalculatedColumn.d.ts +0 -13
  77. package/types/src/cell-edit-validators/CaseValidator.d.ts +0 -2
  78. package/types/src/cell-edit-validators/PatternValidator.d.ts +0 -2
  79. package/types/src/cell-edit-validators/index.d.ts +0 -2
  80. package/types/src/cell-renderers/background-cell/BackgroundCell.d.ts +0 -2
  81. package/types/src/cell-renderers/background-cell/BackgroundCellConfigurationEditor.d.ts +0 -2
  82. package/types/src/cell-renderers/background-cell/index.d.ts +0 -2
  83. package/types/src/cell-renderers/background-cell/useDirection.d.ts +0 -3
  84. package/types/src/cell-renderers/button-cell/IconButtonCell.d.ts +0 -6
  85. package/types/src/cell-renderers/dropdown-cell/DropdownCell.d.ts +0 -2
  86. package/types/src/cell-renderers/dropdown-cell/index.d.ts +0 -1
  87. package/types/src/cell-renderers/index.d.ts +0 -6
  88. package/types/src/cell-renderers/lookup-cell/LookupCell.d.ts +0 -2
  89. package/types/src/cell-renderers/lookup-cell/index.d.ts +0 -1
  90. package/types/src/cell-renderers/pct-progress-cell/PctProgressCell.d.ts +0 -2
  91. package/types/src/cell-renderers/pct-progress-cell/index.d.ts +0 -1
  92. package/types/src/cell-renderers/progress-cell/ProgressCell.d.ts +0 -1
  93. package/types/src/cell-renderers/progress-cell/index.d.ts +0 -1
  94. package/types/src/column-expression-input/ColumnExpressionInput.d.ts +0 -10
  95. package/types/src/column-expression-input/column-function-descriptors.d.ts +0 -15
  96. package/types/src/column-expression-input/column-language-parser/ColumnExpressionLanguage.d.ts +0 -2
  97. package/types/src/column-expression-input/column-language-parser/ColumnExpressionTreeWalker.d.ts +0 -57
  98. package/types/src/column-expression-input/column-language-parser/column-expression-parse-utils.d.ts +0 -5
  99. package/types/src/column-expression-input/column-language-parser/generated/column-parser.d.ts +0 -2
  100. package/types/src/column-expression-input/column-language-parser/generated/column-parser.terms.d.ts +0 -1
  101. package/types/src/column-expression-input/column-language-parser/index.d.ts +0 -3
  102. package/types/src/column-expression-input/column-language-parser/test.d.mts +0 -1
  103. package/types/src/column-expression-input/functionDocInfo.d.ts +0 -2
  104. package/types/src/column-expression-input/highlighting.d.ts +0 -1
  105. package/types/src/column-expression-input/index.d.ts +0 -4
  106. package/types/src/column-expression-input/theme.d.ts +0 -1
  107. package/types/src/column-expression-input/useColumnAutoComplete.d.ts +0 -6
  108. package/types/src/column-expression-input/useColumnExpressionEditor.d.ts +0 -25
  109. package/types/src/column-expression-input/useColumnExpressionSuggestionProvider.d.ts +0 -8
  110. package/types/src/column-formatting-settings/BaseNumericFormattingSettings.d.ts +0 -2
  111. package/types/src/column-formatting-settings/ColumnFormattingPanel.d.ts +0 -9
  112. package/types/src/column-formatting-settings/DateTimeFormattingSettings.d.ts +0 -3
  113. package/types/src/column-formatting-settings/LongTypeFormattingSettings.d.ts +0 -3
  114. package/types/src/column-formatting-settings/index.d.ts +0 -3
  115. package/types/src/column-menu/ColumnMenu.d.ts +0 -10
  116. package/types/src/column-menu/column-action-types.d.ts +0 -11
  117. package/types/src/column-menu/column-menu-utils.d.ts +0 -19
  118. package/types/src/column-menu/useColumnActions.d.ts +0 -16
  119. package/types/src/column-picker/ColumnModel.d.ts +0 -81
  120. package/types/src/column-picker/ColumnPicker.d.ts +0 -10
  121. package/types/src/column-picker/ColumnPickerAction.d.ts +0 -5
  122. package/types/src/column-picker/useColumnPicker.d.ts +0 -16
  123. package/types/src/column-picker/useTableColumnPicker.d.ts +0 -7
  124. package/types/src/column-picker/useTableColumnPickerDeprecated.d.ts +0 -14
  125. package/types/src/column-settings-panel/ColumnNameLabel.d.ts +0 -7
  126. package/types/src/column-settings-panel/ColumnSettingsPanel.d.ts +0 -5
  127. package/types/src/column-settings-panel/useColumnSettings.d.ts +0 -30
  128. package/types/src/csv-export/export-utils.d.ts +0 -42
  129. package/types/src/csv-export/index.d.ts +0 -2
  130. package/types/src/csv-export/useCsvExport.d.ts +0 -14
  131. package/types/src/csv-upload/CsvUpload.d.ts +0 -69
  132. package/types/src/csv-upload/data-upload-preview/DataUploadPreview.d.ts +0 -10
  133. package/types/src/csv-upload/data-upload-preview/useDataUploadPreview.d.ts +0 -17
  134. package/types/src/csv-upload/index.d.ts +0 -7
  135. package/types/src/csv-upload/parse/csv-constants.d.ts +0 -3
  136. package/types/src/csv-upload/parse/csv-errors.d.ts +0 -47
  137. package/types/src/csv-upload/parse/csv-parse.d.ts +0 -11
  138. package/types/src/csv-upload/parse/csv-schema-validation.d.ts +0 -18
  139. package/types/src/csv-upload/parse/csv-upload-utils.d.ts +0 -21
  140. package/types/src/csv-upload/parse/index.d.ts +0 -5
  141. package/types/src/csv-upload/useCsvUpload.d.ts +0 -43
  142. package/types/src/datasource-stats/DatasourceStats.d.ts +0 -17
  143. package/types/src/datasource-stats/useDatasourceStats.d.ts +0 -15
  144. package/types/src/freeze-control/FreezeControl.d.ts +0 -15
  145. package/types/src/freeze-control/FrozenBanner.d.ts +0 -6
  146. package/types/src/freeze-control/freezeControlBadge.d.ts +0 -11
  147. package/types/src/freeze-control/useFreezeControl.d.ts +0 -10
  148. package/types/src/index.d.ts +0 -26
  149. package/types/src/inline-add-row/InlineAddRow.d.ts +0 -3
  150. package/types/src/inline-add-row/index.d.ts +0 -2
  151. package/types/src/inline-add-row/useInlineAddRow.d.ts +0 -59
  152. package/types/src/tabbed-table-config-panel/TabbedTableConfigPanel.d.ts +0 -17
  153. package/types/src/tabbed-table-config-panel/TabbedTableSettingsAction.d.ts +0 -7
  154. package/types/src/tabbed-table-config-panel/useTabbedTableConfigPanel.d.ts +0 -13
  155. package/types/src/table-footer/TableFooter.d.ts +0 -10
  156. package/types/src/table-provider/TableProvider.d.ts +0 -18
  157. package/types/src/table-settings-panel/TableSettingsPanel.d.ts +0 -22
  158. package/types/src/table-settings-panel/useTableSettings.d.ts +0 -14
package/package.json CHANGED
@@ -1,35 +1,33 @@
1
1
  {
2
- "version": "4.0.0-alpha.9",
2
+ "version": "4.0.0-beta.1",
3
3
  "author": "heswell",
4
4
  "main": "./src/index.js",
5
5
  "license": "Apache-2.0",
6
- "type": "module",
7
6
  "scripts": {
8
7
  "prebuild": "npm run lezer-generate:column",
9
8
  "build:dev": "node ../../scripts/run-build.mjs",
10
9
  "build": "node ../../scripts/run-build-rslib.ts",
11
10
  "type-defs": "node ../../scripts/build-type-defs.mjs",
12
- "lezer-generate:column": "lezer-generator --output ./src/column-expression-input/column-language-parser/generated/column-parser.ts ./src/column-expression-input/column-language-parser/grammar/column.grammar"
11
+ "lezer-generate:column": "lezer-generator --output ./src/column-expression-input/column-language-parser/generated/column-parser.js ./src/column-expression-input/column-language-parser/grammar/column.grammar"
13
12
  },
14
13
  "devDependencies": {
15
- "@vuu-ui/vuu-filter-types": "4.0.0-alpha.9",
16
- "@vuu-ui/vuu-protocol-types": "4.0.0-alpha.9"
14
+ "@vuu-ui/vuu-filter-types": "4.0.0-beta.1",
15
+ "@vuu-ui/vuu-protocol-types": "4.0.0-beta.1"
17
16
  },
18
17
  "dependencies": {
19
- "@vuu-ui/vuu-codemirror": "4.0.0-alpha.9",
20
- "@vuu-ui/vuu-data-editing": "4.0.0-alpha.9",
21
- "@vuu-ui/vuu-data-react": "4.0.0-alpha.9",
22
- "@vuu-ui/vuu-data-types": "4.0.0-alpha.9",
23
- "@vuu-ui/vuu-table-types": "4.0.0-alpha.9",
24
- "@vuu-ui/vuu-popups": "4.0.0-alpha.9",
25
- "@vuu-ui/vuu-table": "4.0.0-alpha.9",
26
- "@vuu-ui/vuu-utils": "4.0.0-alpha.9",
27
- "@vuu-ui/vuu-ui-controls": "4.0.0-alpha.9",
18
+ "@vuu-ui/vuu-codemirror": "4.0.0-beta.1",
19
+ "@vuu-ui/vuu-data-editing": "4.0.0-beta.1",
20
+ "@vuu-ui/vuu-data-react": "4.0.0-beta.1",
21
+ "@vuu-ui/vuu-data-types": "4.0.0-beta.1",
22
+ "@vuu-ui/vuu-table-types": "4.0.0-beta.1",
23
+ "@vuu-ui/vuu-popups": "4.0.0-beta.1",
24
+ "@vuu-ui/vuu-table": "4.0.0-beta.1",
25
+ "@vuu-ui/vuu-utils": "4.0.0-beta.1",
26
+ "@vuu-ui/vuu-ui-controls": "4.0.0-beta.1",
28
27
  "@lezer/lr": "1.4.2",
29
- "@salt-ds/core": "1.67.0",
30
- "@salt-ds/lab": "1.0.0-alpha.99",
31
- "@salt-ds/styles": "0.2.1",
32
- "@salt-ds/window": "0.1.1",
28
+ "@salt-ds/core": "1.72.0",
29
+ "@salt-ds/styles": "0.4.1",
30
+ "@salt-ds/window": "0.1.2",
33
31
  "csv-parse": "^7.0.0"
34
32
  },
35
33
  "peerDependencies": {
@@ -38,6 +36,7 @@
38
36
  "react": "^19.2.3",
39
37
  "react-dom": "^19.2.3"
40
38
  },
39
+ "type": "module",
41
40
  "files": [
42
41
  "README.md",
43
42
  "src",
@@ -46,6 +45,7 @@
46
45
  "exports": {
47
46
  ".": {
48
47
  "import": "./src/index.js",
48
+ "default": "./src/index.js",
49
49
  "types": "./types/index.d.ts"
50
50
  }
51
51
  },
@@ -9,8 +9,8 @@ const css = `
9
9
  }
10
10
 
11
11
  .vuuPctProgressCell-progressBar {
12
- background-color: var(--vuu-color-green-60-fade-30);
13
- border-right: solid var(--progress-bar-width) var(--vuu-color-green-60);
12
+ background-color: var(--salt-color-green-600-40a);
13
+ border-right: solid var(--progress-bar-width) var(--salt-color-green-600);
14
14
  height: 20px;
15
15
  width: var(--progress-bar-pct, 0);
16
16
  display: inline-block;
@@ -13,7 +13,7 @@ const css = `
13
13
  }
14
14
 
15
15
  .vuuProgressCell-bg {
16
- background-color: var(--salt-measured-background);
16
+ background-color: var(--salt-sentiment-neutral-track);
17
17
  width: 100%;
18
18
  height: 2px;
19
19
  display: inline-block;
@@ -23,7 +23,7 @@ const css = `
23
23
  }
24
24
 
25
25
  .vuuProgressCell-bar {
26
- background-color: var(--salt-measured-fill);
26
+ background-color: var(--salt-sentiment-accent-background);
27
27
  height: 100%;
28
28
  transform: translateX(var(--progress-bar-pct, -100%));
29
29
  width: 100%;
@@ -5,15 +5,15 @@ const css = `
5
5
  --vuuFilterEditor-fontFamily: var(--salt-typography-fontFamily);
6
6
  --vuuFilterEditor-fontSize: var(--salt-text-fontSize);
7
7
  --vuuFilterEditor-cursorColor: var(--salt-content-secondary-foreground);
8
- --vuuFilterEditor-selectionBackground: var(--salt-text-background-selected);
8
+ --vuuFilterEditor-selectionBackground: var(--salt-selectable-background-selected);
9
9
  --vuuFilterEditor-tooltipBackground: var(--salt-container-primary-background);
10
- --vuuFilterEditor-tooltipBorder: solid 1px var(--vuu-color-purple-10);
10
+ --vuuFilterEditor-tooltipBorder: solid 1px var(--vuu-color-purple);
11
11
  --vuuFilterEditor-tooltipElevation: var(--salt-overlayable-shadow-popout);
12
12
  --vuuFilterEditor-suggestion-selectedBackground: var(--vuu-color-gray-10);
13
13
  --vuuFilterEditor-suggestion-selectedColor: var(--salt-content-primary-foreground);
14
14
  --vuuFilterEditor-suggestion-detailColor: var(--salt-content-secondary-foreground-disabled);
15
15
  --vuuFilterEditor-suggestion-height: 24px;
16
- --vuuFilterEditor-variableColor: var(--vuu-color-purple-10);
16
+ --vuuFilterEditor-variableColor: var(--vuu-color-purple);
17
17
  box-sizing: border-box;
18
18
  align-items: center;
19
19
  height: 30px;
@@ -72,13 +72,13 @@ const css = `
72
72
  }
73
73
 
74
74
  .vuuFunctionDoc .example-container {
75
- background-color: var(--vuu-color-gray-03);
75
+ background-color: var(--salt-color-gray-100);
76
76
  margin: 6px 0;
77
77
  padding: 3px;
78
78
  }
79
79
 
80
80
  .vuuFunctionDoc .example-expression {
81
- color: var(--vuu-color-gray-80);
81
+ color: var(--salt-color-gray-800);
82
82
  font-family: var(--salt-typography-fontFamily-code);
83
83
  padding: 8px;
84
84
  font-weight: 500;
@@ -33,7 +33,7 @@ const isCompleteExpression = (src)=>{
33
33
  try {
34
34
  strictParser.parse(src);
35
35
  return true;
36
- } catch (_err) {
36
+ } catch (err) {
37
37
  return false;
38
38
  }
39
39
  };
@@ -24,7 +24,7 @@ const vuuTheme = EditorView.theme({
24
24
  color: "var(--vuu-color-gray-50)"
25
25
  },
26
26
  ".cm-completionMatchedText": {
27
- color: "var(--vuu-color-gray-80)",
27
+ color: "var(--salt-color-gray-800)",
28
28
  fontWeight: 700,
29
29
  textDecoration: "none"
30
30
  },
@@ -116,6 +116,7 @@ const useColumnExpressionEditor = ({ onChange, onSubmitExpression, source, sugge
116
116
  viewRef.current?.destroy();
117
117
  };
118
118
  }, [
119
+ completionFn,
119
120
  createState
120
121
  ]);
121
122
  const handleBlur = useCallback(()=>{
@@ -1,6 +1,6 @@
1
1
  import { AnnotationType, getRelationalOperators, numericOperators, stringOperators, toSuggestions } from "@vuu-ui/vuu-codemirror";
2
2
  import { getTypeaheadParams, useTypeaheadSuggestions } from "@vuu-ui/vuu-data-react";
3
- import { isNumericColumn, isTextColumn } from "@vuu-ui/vuu-utils";
3
+ import { isNumericColumn, isTemporalColumn, isTextColumn } from "@vuu-ui/vuu-utils";
4
4
  import { useCallback, useRef } from "react";
5
5
  import { columnFunctionDescriptors } from "./column-function-descriptors.js";
6
6
  import { functionDocInfo } from "./functionDocInfo.js";
@@ -64,7 +64,7 @@ const arithmeticOperators = [
64
64
  }
65
65
  ];
66
66
  const getOperators = (column)=>{
67
- if (void 0 === column || isNumericColumn(column)) return arithmeticOperators;
67
+ if (void 0 === column || isNumericColumn(column) || isTemporalColumn(column)) return arithmeticOperators;
68
68
  return NO_OPERATORS;
69
69
  };
70
70
  const getConditionOperators = (column)=>{
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { getCellRendererOptions, getConfigurationEditor, isColumnTypeRenderer, isTypeDescriptor } from "@vuu-ui/vuu-utils";
2
+ import { getCellRendererOptions, getConfigurationEditor, isColumnTypeRenderer, isTemporalColumn, isTypeDescriptor } from "@vuu-ui/vuu-utils";
3
3
  import { Dropdown, FormField, FormFieldLabel, Option } from "@salt-ds/core";
4
4
  import clsx from "clsx";
5
5
  import { useCallback, useMemo } from "react";
@@ -88,21 +88,24 @@ const ColumnFormattingPanel = ({ availableRenderers, className, column, onChange
88
88
  function getFormattingSettingsComponent(props) {
89
89
  const { column } = props;
90
90
  switch(column.serverDataType){
91
+ case "long":
92
+ return /*#__PURE__*/ jsx(LongTypeFormattingSettings, {
93
+ ...props
94
+ });
95
+ case "epochtimestamp":
96
+ case "epochtimestampnano":
97
+ return /*#__PURE__*/ jsx(DateTimeFormattingSettings, {
98
+ ...props
99
+ });
91
100
  case "double":
92
101
  case "scaleddecimal2":
93
102
  case "scaleddecimal4":
94
103
  case "scaleddecimal6":
95
104
  case "scaleddecimal8":
96
105
  case "int":
97
- return /*#__PURE__*/ jsx(BaseNumericFormattingSettings, {
106
+ return isTemporalColumn(column) ? /*#__PURE__*/ jsx(DateTimeFormattingSettings, {
98
107
  ...props
99
- });
100
- case "long":
101
- return /*#__PURE__*/ jsx(LongTypeFormattingSettings, {
102
- ...props
103
- });
104
- case "epochtimestamp":
105
- return /*#__PURE__*/ jsx(DateTimeFormattingSettings, {
108
+ }) : /*#__PURE__*/ jsx(BaseNumericFormattingSettings, {
106
109
  ...props
107
110
  });
108
111
  default:
@@ -1,5 +1,5 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
- import { dateTimeLabelByType, defaultPatternsByType, fallbackDateTimePattern, getTypeFormattingFromColumn, isDatePattern, isTimePattern, supportedDateTimePatterns } from "@vuu-ui/vuu-utils";
2
+ import { dateTimeLabelByType, dateTimePattern, defaultPatternsByType, fallbackDateTimePattern, getTemporalInfo, getTypeFormattingFromColumn, isDatePattern, isTimePattern, supportedDateTimePatterns } from "@vuu-ui/vuu-utils";
3
3
  import { Dropdown, FormField, FormFieldLabel, Option, ToggleButton, ToggleButtonGroup } from "@salt-ds/core";
4
4
  import { useCallback, useMemo, useState } from "react";
5
5
  const toggleValues = [
@@ -7,6 +7,32 @@ const toggleValues = [
7
7
  "time",
8
8
  "both"
9
9
  ];
10
+ const DEFAULT = "default";
11
+ const fractionalSecondDigitOptions = [
12
+ DEFAULT,
13
+ "0",
14
+ "3",
15
+ "6",
16
+ "9"
17
+ ];
18
+ const timeZoneOptions = [
19
+ DEFAULT,
20
+ "local",
21
+ "UTC",
22
+ "Europe/London",
23
+ "Europe/Paris",
24
+ "America/New_York",
25
+ "Asia/Tokyo",
26
+ "Asia/Hong_Kong"
27
+ ];
28
+ const localeOptions = [
29
+ DEFAULT,
30
+ "en-GB",
31
+ "en-US",
32
+ "de-DE",
33
+ "fr-FR",
34
+ "ja-JP"
35
+ ];
10
36
  function getToggleValue(pattern) {
11
37
  return pattern.time ? pattern.date ? "both" : "time" : "date";
12
38
  }
@@ -20,7 +46,8 @@ const getSelectedPattern = (pattern)=>{
20
46
  };
21
47
  const DateTimeFormattingSettings = ({ column, onChangeFormatting: onChange })=>{
22
48
  const formatting = getTypeFormattingFromColumn(column);
23
- const { pattern = fallbackDateTimePattern } = formatting;
49
+ const temporalInfo = getTemporalInfo(column);
50
+ const { pattern = temporalInfo ? dateTimePattern(column.type, temporalInfo.kind) : fallbackDateTimePattern } = formatting;
24
51
  const toggleValue = useMemo(()=>getToggleValue(pattern), [
25
52
  pattern
26
53
  ]);
@@ -28,6 +55,26 @@ const DateTimeFormattingSettings = ({ column, onChangeFormatting: onChange })=>{
28
55
  time: pattern.time ?? defaultPatternsByType.time,
29
56
  date: pattern.date ?? defaultPatternsByType.date
30
57
  });
58
+ const onFractionalSecondDigitsChange = useCallback((_, [value])=>{
59
+ const { fractionalSecondDigits, ...rest } = formatting;
60
+ onChange(value === DEFAULT ? rest : {
61
+ ...rest,
62
+ fractionalSecondDigits: parseInt(value, 10)
63
+ });
64
+ }, [
65
+ formatting,
66
+ onChange
67
+ ]);
68
+ const onFormattingOptionChange = useCallback((key)=>(_, [value])=>{
69
+ const { [key]: _previous, ...rest } = formatting;
70
+ onChange(value === DEFAULT ? rest : {
71
+ ...rest,
72
+ [key]: value
73
+ });
74
+ }, [
75
+ formatting,
76
+ onChange
77
+ ]);
31
78
  const onPatternChange = useCallback((pattern)=>onChange({
32
79
  ...formatting,
33
80
  pattern
@@ -109,7 +156,64 @@ const DateTimeFormattingSettings = ({ column, onChangeFormatting: onChange })=>{
109
156
  }, i))
110
157
  })
111
158
  ]
112
- }, v))
159
+ }, v)),
160
+ pattern.time ? /*#__PURE__*/ jsxs(FormField, {
161
+ labelPlacement: "top",
162
+ children: [
163
+ /*#__PURE__*/ jsx(FormFieldLabel, {
164
+ children: "Fractional second digits"
165
+ }),
166
+ /*#__PURE__*/ jsx(Dropdown, {
167
+ onSelectionChange: onFractionalSecondDigitsChange,
168
+ selected: [
169
+ `${formatting.fractionalSecondDigits ?? DEFAULT}`
170
+ ],
171
+ value: `${formatting.fractionalSecondDigits ?? DEFAULT}`,
172
+ children: fractionalSecondDigitOptions.filter((digits)=>temporalInfo?.precision === "ns" || "6" !== digits && "9" !== digits).map((digits)=>/*#__PURE__*/ jsx(Option, {
173
+ value: digits,
174
+ children: digits
175
+ }, digits))
176
+ })
177
+ ]
178
+ }) : null,
179
+ /*#__PURE__*/ jsxs(FormField, {
180
+ labelPlacement: "top",
181
+ children: [
182
+ /*#__PURE__*/ jsx(FormFieldLabel, {
183
+ children: "Time zone"
184
+ }),
185
+ /*#__PURE__*/ jsx(Dropdown, {
186
+ onSelectionChange: onFormattingOptionChange("timeZone"),
187
+ selected: [
188
+ formatting.timeZone ?? DEFAULT
189
+ ],
190
+ value: formatting.timeZone ?? DEFAULT,
191
+ children: timeZoneOptions.map((timeZone)=>/*#__PURE__*/ jsx(Option, {
192
+ value: timeZone,
193
+ children: timeZone
194
+ }, timeZone))
195
+ })
196
+ ]
197
+ }),
198
+ /*#__PURE__*/ jsxs(FormField, {
199
+ labelPlacement: "top",
200
+ children: [
201
+ /*#__PURE__*/ jsx(FormFieldLabel, {
202
+ children: "Locale"
203
+ }),
204
+ /*#__PURE__*/ jsx(Dropdown, {
205
+ onSelectionChange: onFormattingOptionChange("locale"),
206
+ selected: [
207
+ formatting.locale ?? DEFAULT
208
+ ],
209
+ value: formatting.locale ?? DEFAULT,
210
+ children: localeOptions.map((locale)=>/*#__PURE__*/ jsx(Option, {
211
+ value: locale,
212
+ children: locale
213
+ }, locale))
214
+ })
215
+ ]
216
+ })
113
217
  ]
114
218
  });
115
219
  };
@@ -5,7 +5,8 @@ import { useWindow } from "@salt-ds/window";
5
5
  import { useCallback } from "react";
6
6
  import { BaseNumericFormattingSettings } from "./BaseNumericFormattingSettings.js";
7
7
  import LongTypeFormattingSettings from "./LongTypeFormattingSettings.css";
8
- import { isTypeDescriptor } from "@vuu-ui/vuu-utils";
8
+ import { isTemporalColumn, isTypeDescriptor } from "@vuu-ui/vuu-utils";
9
+ import { DateTimeFormattingSettings } from "./DateTimeFormattingSettings.js";
9
10
  const classBase = "vuuLongColumnFormattingSettings";
10
11
  const LongTypeFormattingSettings_LongTypeFormattingSettings = (props)=>{
11
12
  const targetWindow = useWindow();
@@ -41,7 +42,9 @@ const LongTypeFormattingSettings_LongTypeFormattingSettings = (props)=>{
41
42
  })
42
43
  ]
43
44
  }),
44
- /*#__PURE__*/ jsx(BaseNumericFormattingSettings, {
45
+ isTemporalColumn(column) ? /*#__PURE__*/ jsx(DateTimeFormattingSettings, {
46
+ ...props
47
+ }) : /*#__PURE__*/ jsx(BaseNumericFormattingSettings, {
45
48
  ...props
46
49
  })
47
50
  ]
@@ -49,6 +52,8 @@ const LongTypeFormattingSettings_LongTypeFormattingSettings = (props)=>{
49
52
  };
50
53
  const toggleValues = [
51
54
  "number",
52
- "date/time"
55
+ "date/time",
56
+ "date",
57
+ "time"
53
58
  ];
54
59
  export { LongTypeFormattingSettings_LongTypeFormattingSettings as LongTypeFormattingSettings };
@@ -15,6 +15,7 @@ const isColumnAdded = (change)=>change?.type === SelectedColumnChangeType.Column
15
15
  const isColumnRemoved = (change)=>change?.type === SelectedColumnChangeType.ColumnRemoved;
16
16
  const isColumnUpdated = (change)=>change?.type === SelectedColumnChangeType.ColumnUpdated;
17
17
  const isColumnsReordered = (change)=>change?.type === SelectedColumnChangeType.ColumnsReordered;
18
+ const columnDescriptorComparator = (col1, col2)=>col1.name === col2.name;
18
19
  class ColumnModel extends EventEmitter {
19
20
  allColumns;
20
21
  #selectedColumns;
@@ -36,10 +37,10 @@ class ColumnModel extends EventEmitter {
36
37
  }
37
38
  addRemoveOrReorderSelectedColumns(newSelectedColumns, source) {
38
39
  if (!itemsOrOrderChanged(this.#selectedColumns, newSelectedColumns)) throw Error("[ColumnModel] addRemoveOrReorderSelectedColumns no change detected between current and new selected columns");
39
- const addedColumns = getAddedItems(this.#selectedColumns, newSelectedColumns);
40
+ const addedColumns = getAddedItems(this.#selectedColumns, newSelectedColumns, columnDescriptorComparator);
40
41
  if (addedColumns.length > 0) if (1 == addedColumns.length) return void this.addItemToSelectedColumns(addedColumns[0].name, source);
41
42
  else throw Error("[ColumnModel] addRemoveOrReorderSelectedColumns attempt to add multiple selected columns in a single call");
42
- const removedColumns = getRemovedItems(this.#selectedColumns, newSelectedColumns);
43
+ const removedColumns = getRemovedItems(this.#selectedColumns, newSelectedColumns, columnDescriptorComparator);
43
44
  if (removedColumns.length > 0) if (1 == removedColumns.length) return void this.removeItemFromSelectedColumns(removedColumns[0].name, source);
44
45
  else throw Error("[ColumnModel] addRemoveOrReorderSelectedColumns attempt to remove multiple selected columns in a single call");
45
46
  this.reorderSelectedColumns(newSelectedColumns.map(({ name })=>name), source);
@@ -28,9 +28,7 @@ const ColumnPicker_ColumnPicker = /*#__PURE__*/ forwardRef(function({ columnMode
28
28
  selectedItems: selectedItems,
29
29
  itemTypeName: "column",
30
30
  onSelectedItemsChange: handleSelectedItemsChange,
31
- onSelectionChange: onSelectionChange,
32
- ref: forwardedRef,
33
- selected: selected
31
+ ref: forwardedRef
34
32
  });
35
33
  });
36
34
  export { ColumnPicker_ColumnPicker as ColumnPicker, classBaseListItem };
@@ -10,7 +10,7 @@ const css = `
10
10
  }
11
11
 
12
12
  .vuuColumnNameLabel-placeholder {
13
- color: var(--vuu-color-gray-35);
13
+ color: var(--salt-color-gray-400);
14
14
  }
15
15
 
16
16
 
@@ -1,4 +1,4 @@
1
- import { Range, isSessionTable, metadataKeys } from "@vuu-ui/vuu-utils";
1
+ import { Range, buildColumnMap, getValueFormatter, isSessionTable, metadataKeys } from "@vuu-ui/vuu-utils";
2
2
  const EXPORT_EXCLUDED_COLUMNS = new Set([
3
3
  "vuuMsg",
4
4
  "vuuAction",
@@ -28,10 +28,32 @@ const triggerCsvDownload = (csv, filename)=>{
28
28
  document.body.removeChild(a);
29
29
  setTimeout(()=>URL.revokeObjectURL(url), 10000);
30
30
  };
31
+ const createRowAccessor = (row, columnMap)=>new Proxy({}, {
32
+ get (_, prop) {
33
+ if ("string" == typeof prop) {
34
+ const idx = columnMap[prop];
35
+ if (void 0 !== idx) return row[idx];
36
+ }
37
+ },
38
+ has (_, prop) {
39
+ return "string" == typeof prop && void 0 !== columnMap[prop];
40
+ }
41
+ });
42
+ const isExportableColumn = (descriptor)=>{
43
+ if (!descriptor) return true;
44
+ if (false === descriptor.exportable) return false;
45
+ if (descriptor.hidden) return false;
46
+ if (descriptor.isSystemColumn) return false;
47
+ if (true === descriptor.exportable) return true;
48
+ if ("client" === descriptor.source && !descriptor.exportFormatter) return false;
49
+ return true;
50
+ };
31
51
  const exportCsvTemplate = async (dataSource, options = {})=>{
32
52
  const { filename = "template.csv", excludeColumns = [], columns, overrides, timeout = DEFAULT_TEMPLATE_TIMEOUT, onError, onSuccess } = options;
33
- const sessionOverrides = overrides ?? (columns ? {
34
- columns
53
+ const targetColumnNames = columns ? columns.filter((col)=>"string" == typeof col ? true : isExportableColumn(col) && "client" !== col.source).map((col)=>"string" == typeof col ? col : col.name) : void 0;
54
+ const targetColumns = targetColumnNames ?? overrides?.columns;
55
+ const sessionOverrides = overrides ?? (targetColumns ? {
56
+ columns: targetColumns
35
57
  } : void 0);
36
58
  if (!isSessionTable(dataSource.table) && dataSource.createSessionDataSource && "initialising" !== dataSource.status && "unsubscribed" !== dataSource.status) try {
37
59
  const sessionDataSource = await dataSource.createSessionDataSource("Empty", "export", sessionOverrides);
@@ -59,7 +81,16 @@ const exportCsvTemplate = async (dataSource, options = {})=>{
59
81
  }, (message)=>{
60
82
  if ("subscribed" === message.type) {
61
83
  const { columns: subColumns } = message;
62
- const exportCols = subColumns.filter((name)=>!excluded.has(name));
84
+ const exportCols = targetColumns ? targetColumns.filter((name)=>!excluded.has(name)) : subColumns.filter((name)=>!excluded.has(name));
85
+ if (0 === exportCols.length) {
86
+ cleanup();
87
+ const error = new Error("exportCsvTemplate: no columns available for export");
88
+ if (onError) {
89
+ onError(error);
90
+ resolve();
91
+ } else reject(error);
92
+ return;
93
+ }
63
94
  const header = exportCols.map(csvCell).join(",");
64
95
  triggerCsvDownload(`${header}\r\n`, filename);
65
96
  cleanup();
@@ -72,7 +103,6 @@ const exportCsvTemplate = async (dataSource, options = {})=>{
72
103
  console.warn("[exportCsvTemplate] createSessionDataSource failed, falling back to tableSchema", error);
73
104
  }
74
105
  const schema = dataSource.tableSchema;
75
- const targetColumns = columns ?? overrides?.columns;
76
106
  if (void 0 !== targetColumns) {
77
107
  if (schema) {
78
108
  const schemaColumnNames = new Set(schema.columns.map((col)=>col.name));
@@ -99,7 +129,18 @@ const exportCsvTemplate = async (dataSource, options = {})=>{
99
129
  onSuccess?.();
100
130
  };
101
131
  const exportSessionTableToCsv = async (dataSource, options = {})=>{
102
- const { filename = "export.csv", copyOption = "All", excludeColumns = [], maxRows = MAX_EXPORT_ROWS, columnDescriptors, overrides, timeout = DEFAULT_EXPORT_TIMEOUT, onError, onSuccess } = options;
132
+ const { filename = "export.csv", copyOption = "All", excludeColumns = [], maxRows = MAX_EXPORT_ROWS, columnDescriptors: rawColumnDescriptors, columns: rawColumns, overrides, timeout = DEFAULT_EXPORT_TIMEOUT, onError, onSuccess } = options;
133
+ const rawInputColumns = rawColumns ?? rawColumnDescriptors;
134
+ const columnDescriptors = rawInputColumns?.map((col)=>"string" == typeof col ? {
135
+ name: col
136
+ } : col);
137
+ const sessionOverrides = overrides ? {
138
+ ...overrides,
139
+ columns: overrides.columns?.filter((name)=>{
140
+ const desc = columnDescriptors?.find((d)=>d.name === name);
141
+ return desc?.source !== "client";
142
+ })
143
+ } : void 0;
103
144
  const isRemote = !!dataSource.isRemote;
104
145
  if (isRemote && !isSessionTable(dataSource.table) && ("initialising" === dataSource.status || "unsubscribed" === dataSource.status)) {
105
146
  const error = new Error(`exportSessionTableToCsv: dataSource must be subscribed before exporting (current status: "${dataSource.status}")`);
@@ -108,7 +149,7 @@ const exportSessionTableToCsv = async (dataSource, options = {})=>{
108
149
  }
109
150
  let sessionDataSource;
110
151
  if (!isSessionTable(dataSource.table) && dataSource.createSessionDataSource) try {
111
- sessionDataSource = await dataSource.createSessionDataSource(copyOption, "export", overrides);
152
+ sessionDataSource = await dataSource.createSessionDataSource(copyOption, "export", sessionOverrides);
112
153
  } catch (err) {
113
154
  const error = err instanceof Error ? err : new Error(String(err));
114
155
  if (onError) return void onError(error);
@@ -152,18 +193,23 @@ const exportSessionTableToCsv = async (dataSource, options = {})=>{
152
193
  const { columns } = message;
153
194
  if (columnDescriptors) {
154
195
  const subscribedSet = new Set(columns);
155
- const unknown = columnDescriptors.filter((d)=>!excluded.has(d.name) && !subscribedSet.has(d.name)).map((d)=>d.name);
196
+ const unknown = columnDescriptors.filter((d)=>"client" !== d.source && !excluded.has(d.name) && !subscribedSet.has(d.name)).map((d)=>d.name);
156
197
  if (unknown.length > 0) return void fail(new Error(`exportToCsv: unknown column(s) in columnDescriptors: ${unknown.join(", ")}`));
157
198
  descriptorMap = Object.fromEntries(columnDescriptors.map((d)=>[
158
199
  d.name,
159
200
  d
160
201
  ]));
161
202
  }
162
- exportCols = columns.filter((name)=>!excluded.has(name));
163
- colNameToRowIdx = Object.fromEntries(columns.map((name, i)=>[
164
- name,
165
- metadataKeys.count + i
166
- ]));
203
+ if (rawColumns) exportCols = rawColumns.map((c)=>"string" == typeof c ? c : c.name).filter((name)=>!excluded.has(name) && isExportableColumn(descriptorMap[name]));
204
+ else if (columnDescriptors?.some((d)=>"client" === d.source)) {
205
+ const definedNames = new Set(columnDescriptors.map((d)=>d.name));
206
+ const remainingSubscribed = columns.filter((name)=>!excluded.has(name) && !definedNames.has(name) && isExportableColumn(descriptorMap[name]));
207
+ exportCols = [
208
+ ...columnDescriptors.filter((d)=>!excluded.has(d.name) && isExportableColumn(d)).map((d)=>d.name),
209
+ ...remainingSubscribed
210
+ ];
211
+ } else exportCols = columns.filter((name)=>!excluded.has(name) && isExportableColumn(descriptorMap[name]));
212
+ colNameToRowIdx = buildColumnMap(columns);
167
213
  } else if ("viewport-update" === message.type) {
168
214
  if ("size-only" === message.mode) {
169
215
  totalSize = message.size ?? 0;
@@ -191,11 +237,21 @@ const exportSessionTableToCsv = async (dataSource, options = {})=>{
191
237
  ];
192
238
  for(let i = 0; i < totalSize; i++){
193
239
  const row = collectedRows.get(i);
194
- if (row) lines.push(exportCols.map((c)=>{
195
- const raw = row[colNameToRowIdx[c]];
196
- const formatter = descriptorMap[c]?.exportFormatter;
197
- return csvCell(formatter ? formatter(raw) : raw);
198
- }).join(","));
240
+ if (row) {
241
+ const rowAccessor = createRowAccessor(row, colNameToRowIdx);
242
+ lines.push(exportCols.map((c)=>{
243
+ const descriptor = descriptorMap[c];
244
+ const isClientCol = descriptor?.source === "client";
245
+ const raw = isClientCol ? void 0 : void 0 !== colNameToRowIdx[c] ? row[colNameToRowIdx[c]] : void 0;
246
+ let formatted;
247
+ if (descriptor?.exportFormatter) formatted = descriptor.exportFormatter(raw, rowAccessor);
248
+ else if (descriptor && ("type" in descriptor || "serverDataType" in descriptor)) {
249
+ const tableFormatter = getValueFormatter(descriptor);
250
+ formatted = tableFormatter(raw);
251
+ } else formatted = raw;
252
+ return csvCell(formatted);
253
+ }).join(","));
254
+ }
199
255
  }
200
256
  triggerCsvDownload(lines.join("\r\n"), filename);
201
257
  onSuccess?.();
@@ -213,9 +269,9 @@ const exportSessionTableToCsv = async (dataSource, options = {})=>{
213
269
  };
214
270
  activeSessionDataSource.subscribe({
215
271
  range: Range(0, 0),
216
- columns: overrides?.columns
272
+ columns: sessionOverrides?.columns
217
273
  }, handleMessage);
218
274
  });
219
275
  };
220
276
  const exportToCsv = async (dataSource, options)=>exportSessionTableToCsv(dataSource, options);
221
- export { exportCsvTemplate, exportSessionTableToCsv, exportToCsv };
277
+ export { exportCsvTemplate, exportSessionTableToCsv, exportToCsv, isExportableColumn };
@@ -1,2 +1,2 @@
1
- export { exportCsvTemplate, exportSessionTableToCsv, exportToCsv } from "./export-utils.js";
1
+ export { exportCsvTemplate, exportSessionTableToCsv, exportToCsv, isExportableColumn } from "./export-utils.js";
2
2
  export { useCsvExport } from "./useCsvExport.js";
@@ -6,7 +6,7 @@ function useCsvExport(propsOrDataSource) {
6
6
  const config = propsOrDataSource && "table" in propsOrDataSource ? {
7
7
  dataSource: propsOrDataSource
8
8
  } : propsOrDataSource ?? {};
9
- const { dataSource: defaultDataSource, onError, onSuccess } = config;
9
+ const { dataSource: defaultDataSource, tableConfig, columns: defaultColumns, onError, onSuccess } = config;
10
10
  const exportCsv = useCallback(async (options, overrideDataSource)=>{
11
11
  const activeDataSource = overrideDataSource ?? defaultDataSource;
12
12
  if (!activeDataSource) {
@@ -19,7 +19,9 @@ function useCsvExport(propsOrDataSource) {
19
19
  setIsExporting(true);
20
20
  setError(null);
21
21
  try {
22
+ const columnsToExport = options?.columns ?? options?.columnDescriptors ?? defaultColumns ?? tableConfig?.columns;
22
23
  await exportToCsv(activeDataSource, {
24
+ columns: columnsToExport,
23
25
  ...options,
24
26
  onError: (err)=>{
25
27
  setError(err);
@@ -42,6 +44,8 @@ function useCsvExport(propsOrDataSource) {
42
44
  }
43
45
  }, [
44
46
  defaultDataSource,
47
+ defaultColumns,
48
+ tableConfig,
45
49
  onError,
46
50
  onSuccess
47
51
  ]);
@@ -57,7 +61,9 @@ function useCsvExport(propsOrDataSource) {
57
61
  setIsExporting(true);
58
62
  setError(null);
59
63
  try {
64
+ const templateColumns = options?.columns ?? defaultColumns ?? tableConfig?.columns;
60
65
  await exportCsvTemplate(activeDataSource, {
66
+ columns: templateColumns,
61
67
  ...options,
62
68
  onError: (err)=>{
63
69
  setError(err);
@@ -80,6 +86,8 @@ function useCsvExport(propsOrDataSource) {
80
86
  }
81
87
  }, [
82
88
  defaultDataSource,
89
+ defaultColumns,
90
+ tableConfig,
83
91
  onError,
84
92
  onSuccess
85
93
  ]);