@vuu-ui/vuu-table-extras 4.0.0-alpha.2 → 4.0.0-alpha.21

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 (79) hide show
  1. package/package.json +18 -17
  2. package/src/calculated-column/CalculatedColumnPanel.js +2 -2
  3. package/src/calculated-column/useEditCalculatedColumn.js +1 -1
  4. package/src/cell-renderers/pct-progress-cell/PctProgressCell.css.js +2 -2
  5. package/src/cell-renderers/progress-cell/ProgressCell.css.js +2 -2
  6. package/src/column-expression-input/ColumnExpressionInput.css.js +5 -5
  7. package/src/column-expression-input/theme.js +1 -1
  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 +14 -25
  13. package/src/column-picker/ColumnPicker.css.js +0 -86
  14. package/src/column-picker/ColumnPicker.js +12 -180
  15. package/src/column-picker/useColumnPicker.js +28 -22
  16. package/src/column-settings-panel/ColumnNameLabel.css.js +1 -1
  17. package/src/csv-export/export-utils.js +76 -20
  18. package/src/csv-export/index.js +1 -1
  19. package/src/csv-export/useCsvExport.js +9 -1
  20. package/src/csv-upload/CsvUpload.css.js +36 -2
  21. package/src/csv-upload/CsvUpload.js +107 -63
  22. package/src/csv-upload/parse/csv-errors.js +1 -1
  23. package/src/csv-upload/parse/csv-parse.js +1 -1
  24. package/src/csv-upload/parse/csv-schema-validation.js +46 -7
  25. package/src/csv-upload/parse/csv-upload-utils.js +47 -2
  26. package/src/csv-upload/session/index.js +2 -0
  27. package/src/csv-upload/session/useImportSchema.js +44 -0
  28. package/src/csv-upload/session/useImportSession.js +204 -0
  29. package/src/csv-upload/useCsvUpload.js +54 -199
  30. package/src/freeze-control/FreezeControl.css.js +4 -4
  31. package/src/freeze-control/FrozenBanner.css.js +2 -2
  32. package/src/tabbed-table-config-panel/TabbedTableConfigPanel.js +17 -8
  33. package/src/tabbed-table-config-panel/useTabbedTableConfigPanel.js +1 -1
  34. package/src/table-footer/TableFooter.js +3 -3
  35. package/types/calculated-column/CalculatedColumnPanel.d.ts +3 -3
  36. package/types/cell-renderers/background-cell/BackgroundCell.d.ts +1 -1
  37. package/types/cell-renderers/background-cell/BackgroundCellConfigurationEditor.d.ts +1 -1
  38. package/types/cell-renderers/button-cell/IconButtonCell.d.ts +1 -1
  39. package/types/cell-renderers/dropdown-cell/DropdownCell.d.ts +1 -1
  40. package/types/cell-renderers/lookup-cell/LookupCell.d.ts +1 -1
  41. package/types/cell-renderers/pct-progress-cell/PctProgressCell.d.ts +1 -1
  42. package/types/column-expression-input/ColumnExpressionInput.d.ts +1 -1
  43. package/types/column-expression-input/column-language-parser/test.d.mts +1 -1
  44. package/types/column-formatting-settings/BaseNumericFormattingSettings.d.ts +1 -1
  45. package/types/column-formatting-settings/ColumnFormattingPanel.d.ts +1 -1
  46. package/types/column-formatting-settings/DateTimeFormattingSettings.d.ts +1 -1
  47. package/types/column-formatting-settings/LongTypeFormattingSettings.d.ts +1 -2
  48. package/types/column-menu/ColumnMenu.d.ts +1 -1
  49. package/types/column-picker/ColumnModel.d.ts +4 -3
  50. package/types/column-picker/ColumnPicker.d.ts +4 -6
  51. package/types/column-picker/ColumnPickerAction.d.ts +1 -1
  52. package/types/column-picker/useColumnPicker.d.ts +7 -10
  53. package/types/column-settings-panel/ColumnNameLabel.d.ts +1 -1
  54. package/types/column-settings-panel/ColumnSettingsPanel.d.ts +1 -1
  55. package/types/column-settings-panel/useColumnSettings.d.ts +3 -3
  56. package/types/csv-export/export-utils.d.ts +22 -9
  57. package/types/csv-export/index.d.ts +1 -1
  58. package/types/csv-export/useCsvExport.d.ts +5 -2
  59. package/types/csv-upload/CsvUpload.d.ts +2 -6
  60. package/types/csv-upload/data-upload-preview/DataUploadPreview.d.ts +1 -1
  61. package/types/csv-upload/parse/csv-errors.d.ts +1 -1
  62. package/types/csv-upload/parse/csv-schema-validation.d.ts +8 -2
  63. package/types/csv-upload/parse/csv-upload-utils.d.ts +9 -0
  64. package/types/csv-upload/session/index.d.ts +2 -0
  65. package/types/csv-upload/session/useImportSchema.d.ts +13 -0
  66. package/types/csv-upload/session/useImportSession.d.ts +26 -0
  67. package/types/csv-upload/useCsvUpload.d.ts +3 -3
  68. package/types/datasource-stats/DatasourceStats.d.ts +1 -1
  69. package/types/freeze-control/FreezeControl.d.ts +1 -1
  70. package/types/freeze-control/FrozenBanner.d.ts +1 -1
  71. package/types/index.d.ts +0 -1
  72. package/types/inline-add-row/InlineAddRow.d.ts +1 -1
  73. package/types/inline-add-row/useInlineAddRow.d.ts +2 -1
  74. package/types/tabbed-table-config-panel/TabbedTableConfigPanel.d.ts +1 -1
  75. package/types/tabbed-table-config-panel/TabbedTableSettingsAction.d.ts +1 -1
  76. package/types/tabbed-table-config-panel/useTabbedTableConfigPanel.d.ts +4 -3
  77. package/types/table-footer/TableFooter.d.ts +4 -4
  78. package/types/table-provider/TableProvider.d.ts +1 -1
  79. package/types/table-settings-panel/TableSettingsPanel.d.ts +1 -1
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.0.0-alpha.2",
2
+ "version": "4.0.0-alpha.21",
3
3
  "author": "heswell",
4
4
  "main": "./src/index.js",
5
5
  "license": "Apache-2.0",
@@ -12,24 +12,24 @@
12
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"
13
13
  },
14
14
  "devDependencies": {
15
- "@vuu-ui/vuu-filter-types": "4.0.0-alpha.2",
16
- "@vuu-ui/vuu-protocol-types": "4.0.0-alpha.2"
15
+ "@vuu-ui/vuu-filter-types": "4.0.0-alpha.21",
16
+ "@vuu-ui/vuu-protocol-types": "4.0.0-alpha.21"
17
17
  },
18
18
  "dependencies": {
19
- "@vuu-ui/vuu-codemirror": "4.0.0-alpha.2",
20
- "@vuu-ui/vuu-data-editing": "4.0.0-alpha.2",
21
- "@vuu-ui/vuu-data-react": "4.0.0-alpha.2",
22
- "@vuu-ui/vuu-data-types": "4.0.0-alpha.2",
23
- "@vuu-ui/vuu-table-types": "4.0.0-alpha.2",
24
- "@vuu-ui/vuu-popups": "4.0.0-alpha.2",
25
- "@vuu-ui/vuu-table": "4.0.0-alpha.2",
26
- "@vuu-ui/vuu-utils": "4.0.0-alpha.2",
27
- "@vuu-ui/vuu-ui-controls": "4.0.0-alpha.2",
19
+ "@vuu-ui/core": "4.0.0-alpha.21",
20
+ "@vuu-ui/vuu-codemirror": "4.0.0-alpha.21",
21
+ "@vuu-ui/vuu-data-editing": "4.0.0-alpha.21",
22
+ "@vuu-ui/vuu-data-react": "4.0.0-alpha.21",
23
+ "@vuu-ui/vuu-data-types": "4.0.0-alpha.21",
24
+ "@vuu-ui/vuu-table-types": "4.0.0-alpha.21",
25
+ "@vuu-ui/vuu-popups": "4.0.0-alpha.21",
26
+ "@vuu-ui/vuu-table": "4.0.0-alpha.21",
27
+ "@vuu-ui/vuu-utils": "4.0.0-alpha.21",
28
+ "@vuu-ui/vuu-ui-controls": "4.0.0-alpha.21",
28
29
  "@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",
30
+ "@salt-ds/core": "1.72.0",
31
+ "@salt-ds/styles": "0.4.1",
32
+ "@salt-ds/window": "0.1.2",
33
33
  "csv-parse": "^7.0.0"
34
34
  },
35
35
  "peerDependencies": {
@@ -45,8 +45,9 @@
45
45
  ],
46
46
  "exports": {
47
47
  ".": {
48
+ "types": "./types/index.d.ts",
48
49
  "import": "./src/index.js",
49
- "types": "./types/index.d.ts"
50
+ "default": "./src/index.js"
50
51
  }
51
52
  },
52
53
  "module": "./src/index.js",
@@ -1,9 +1,9 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { Dropdown, FormField, FormFieldLabel, Input, Option } from "@salt-ds/core";
3
- import { useCalculatedColumnPanel } from "./useCalculatedColumnPanel.js";
4
- import { useCallback, useRef } from "react";
5
3
  import { getCalculatedColumnDetails } from "@vuu-ui/vuu-utils";
4
+ import { useCallback, useRef } from "react";
6
5
  import { ColumnExpressionInput, useColumnExpressionSuggestionProvider } from "../column-expression-input/index.js";
6
+ import { useCalculatedColumnPanel } from "./useCalculatedColumnPanel.js";
7
7
  const classBase = "vuuCalculatedColumnPanel";
8
8
  const CalculatedColumnPanel = ({ column: columnProp, columnModel, onChangeColumn, onChangeServerDataType: onChangeServerDataTypeProp, vuuTable })=>{
9
9
  const typeRef = useRef(null);
@@ -1,5 +1,5 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { useModal } from "@vuu-ui/vuu-ui-controls";
2
+ import { useModal } from "@vuu-ui/core";
3
3
  import { useCallback, useRef } from "react";
4
4
  import { CalculatedColumnPanel } from "./CalculatedColumnPanel.js";
5
5
  const useEditCalculatedColumn = ({ calculatedColumn, columnModel, onSaveColumn, vuuTable })=>{
@@ -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;
@@ -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
  },
@@ -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 };
@@ -1,4 +1,4 @@
1
- import { EventEmitter, reorderItems } from "@vuu-ui/vuu-utils";
1
+ import { EventEmitter, getAddedItems, getRemovedItems, itemsOrOrderChanged, reorderItems } from "@vuu-ui/vuu-utils";
2
2
  const ColumnChangeSource = {
3
3
  ColumnPicker: "column-picker",
4
4
  ColumnSettings: "column-settings",
@@ -15,37 +15,16 @@ 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 byColumnName = ({ name: n1, label: l1 = n1 }, { name: n2, label: l2 = n2 })=>l1 > l2 ? 1 : l2 > l1 ? -1 : 0;
19
- const filterColumns = (columns, pattern)=>{
20
- if (!pattern) return columns;
21
- {
22
- const lowerCasePattern = pattern.toLowerCase();
23
- return columns.filter(({ name, label = name })=>-1 !== label.toLowerCase().indexOf(lowerCasePattern));
24
- }
25
- };
18
+ const columnDescriptorComparator = (col1, col2)=>col1.name === col2.name;
26
19
  class ColumnModel extends EventEmitter {
27
20
  allColumns;
28
- #searchPattern = "";
29
21
  #selectedColumns;
30
22
  constructor(allColumns, selectedColumns){
31
23
  super(), this.allColumns = allColumns;
32
24
  this.#selectedColumns = selectedColumns;
33
25
  }
34
- get availableColumns() {
35
- return filterColumns(this.allColumns, this.#searchPattern).filter(({ name })=>-1 === this.#selectedColumns.findIndex((c)=>c.name === name)).toSorted(byColumnName);
36
- }
37
- set searchPattern(pattern) {
38
- const searchPattern = pattern;
39
- if (searchPattern !== this.#searchPattern) {
40
- this.#searchPattern = searchPattern;
41
- this.emit("render", {});
42
- }
43
- }
44
- get searchPattern() {
45
- return this.#searchPattern ?? "";
46
- }
47
26
  get selectedColumns() {
48
- return filterColumns(this.#selectedColumns, this.#searchPattern);
27
+ return this.#selectedColumns;
49
28
  }
50
29
  setSelectedColumns(selectedColumns, source, changeDescriptor) {
51
30
  this.#selectedColumns = selectedColumns;
@@ -56,6 +35,16 @@ class ColumnModel extends EventEmitter {
56
35
  if (col) return col;
57
36
  throw Error(`[ColumnModel] columns does not contain column ${name}`);
58
37
  }
38
+ addRemoveOrReorderSelectedColumns(newSelectedColumns, source) {
39
+ if (!itemsOrOrderChanged(this.#selectedColumns, newSelectedColumns)) throw Error("[ColumnModel] addRemoveOrReorderSelectedColumns no change detected between current and new selected columns");
40
+ const addedColumns = getAddedItems(this.#selectedColumns, newSelectedColumns, columnDescriptorComparator);
41
+ if (addedColumns.length > 0) if (1 == addedColumns.length) return void this.addItemToSelectedColumns(addedColumns[0].name, source);
42
+ else throw Error("[ColumnModel] addRemoveOrReorderSelectedColumns attempt to add multiple selected columns in a single call");
43
+ const removedColumns = getRemovedItems(this.#selectedColumns, newSelectedColumns, columnDescriptorComparator);
44
+ if (removedColumns.length > 0) if (1 == removedColumns.length) return void this.removeItemFromSelectedColumns(removedColumns[0].name, source);
45
+ else throw Error("[ColumnModel] addRemoveOrReorderSelectedColumns attempt to remove multiple selected columns in a single call");
46
+ this.reorderSelectedColumns(newSelectedColumns.map(({ name })=>name), source);
47
+ }
59
48
  addItemToSelectedColumns(name, source) {
60
49
  const column = this.allColumns.find((col)=>col.name === name);
61
50
  if (column) {
@@ -97,7 +86,7 @@ class ColumnModel extends EventEmitter {
97
86
  }
98
87
  addColumn(column, addToSelectedColumns = false) {
99
88
  console.log(`[ColumnModel] add column ${JSON.stringify(column)}`);
100
- if (addToSelectedColumns) console.log("add it to selected coliumns");
89
+ if (addToSelectedColumns) console.log("add it to selected columns");
101
90
  this.allColumns = this.allColumns.concat(column);
102
91
  this.#selectedColumns = this.#selectedColumns.concat(column);
103
92
  this.notifyListeners(this.#selectedColumns, "column-picker", {
@@ -1,94 +1,8 @@
1
1
  const css = `
2
2
  .vuuColumnPicker {
3
- --label-margin-left: 0px;
4
- --columnpicker-background: var(--vuuColumnPicker-background, var(--salt-container-primary-background));
5
- background: var(--columnpicker-background);
6
- gap: var(--salt-spacing-300);
7
- height: var(--vuuColumnPicker-height, 100%);
8
- padding: var(--salt-spacing-300) 0;
9
- flex-direction: column;
10
- display: flex;
11
- overflow: hidden;
12
- container-type: inline-size;
13
-
14
3
  &.vuuColumnPicker-withCalculated {
15
4
  --label-margin-left: 8px;
16
5
  }
17
-
18
- & .saltListBox {
19
- background-color: inherit;
20
- }
21
-
22
- & .saltOption {
23
- background-color: inherit;
24
- border-bottom: var(--vuuColumnListItem-border, solid) 1px
25
- var(--salt-separable-tertiary-borderColor);
26
- align-items: center;
27
- gap: var(--salt-spacing-200);
28
- height: calc(var(--salt-size-base) + var(--salt-spacing-200));
29
-
30
- & .vuuIcon {
31
- --vuu-icon-color: var(--salt-content-secondary-foreground);
32
- }
33
-
34
- & .vuuCalculatedColumnIcon {
35
- --vuu-icon-color: var(--salt-content-secondary-foreground);
36
- position: absolute;
37
- top: 8px;
38
- left: 32px;
39
- }
40
-
41
- & .vuuHighlight {
42
- color: var(--vuu-color-blue-40);
43
- text-decoration: underline;
44
- }
45
-
46
- & .vuuColumnPicker-text {
47
- margin-left: var(--label-margin-left);
48
- }
49
- }
50
-
51
- & .vuuColumnPickerListItem-action {
52
- visibility: hidden;
53
- margin-left: auto;
54
- }
55
-
56
- & .saltOption:hover {
57
- & .vuuColumnPickerListItem-action {
58
- visibility: visible;
59
- }
60
- }
61
-
62
- & .vuuColumnPicker-search {
63
- --saltInput-paddingLeft: var(--salt-spacing-300);
64
- padding: var(--salt-spacing-200) var(--salt-spacing-300) 0 var(--salt-spacing-300);
65
- }
66
-
67
- & .vuuColumnPicker-scrollContainer {
68
- flex: 1 1 0;
69
- overflow: auto;
70
-
71
- & .vuuColumnPicker-sectionHeader {
72
- background: var(--columnpicker-background);
73
- height: 32px;
74
- padding: 0 var(--salt-spacing-300);
75
- z-index: 1;
76
- align-items: center;
77
- display: flex;
78
- position: sticky;
79
- top: 0;
80
- }
81
-
82
- & .vuuColumnPicker-availableHeader {
83
- top: 32px;
84
- }
85
-
86
- & .vuuColumnPicker-availableList {
87
- & .saltOption {
88
- padding-left: var(--salt-spacing-300);
89
- }
90
- }
91
- }
92
6
  }
93
7
 
94
8