@vuu-ui/vuu-table-extras 0.8.8-debug → 0.8.9-debug
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/index.js +1598 -1159
- package/cjs/index.js.map +4 -4
- package/esm/index.js +1632 -1143
- package/esm/index.js.map +4 -4
- package/index.css +653 -211
- package/index.css.map +3 -3
- package/package.json +11 -11
- package/types/cell-edit-validators/CaseValidator.d.ts +2 -0
- package/types/cell-edit-validators/PatternValidator.d.ts +2 -0
- package/types/cell-edit-validators/index.d.ts +2 -0
- package/types/cell-renderers/background-cell/index.d.ts +1 -0
- package/types/cell-renderers/background-cell/useDirection.d.ts +3 -0
- package/types/cell-renderers-next/background-cell/BackgroundCell.d.ts +5 -0
- package/types/cell-renderers-next/index.d.ts +1 -0
- package/types/{vuu-table-extras/src/column-expression-input → column-expression-input}/ColumnExpressionInput.d.ts +4 -3
- package/types/{vuu-table-extras/src/column-expression-input → column-expression-input}/useColumnExpressionEditor.d.ts +2 -7
- package/types/column-expression-panel/ColumnExpressionPanel.d.ts +8 -0
- package/types/column-expression-panel/index.d.ts +1 -0
- package/types/column-expression-panel/useColumnExpression.d.ts +11 -0
- package/types/column-formatting-settings/ColumnFormattingPanel.d.ts +12 -0
- package/types/column-formatting-settings/NumericFormattingSettings.d.ts +7 -0
- package/types/column-formatting-settings/index.d.ts +2 -0
- package/types/column-settings/ColumnSettingsPanel.d.ts +12 -0
- package/types/column-settings/useColumnSettings.d.ts +17 -0
- package/types/index.d.ts +11 -0
- package/types/{vuu-table-extras/src/table-settings → table-settings}/TableSettingsPanel.d.ts +6 -4
- package/types/table-settings/useTableSettings.d.ts +17 -0
- package/types/useTableAndColumnSettings.d.ts +15 -0
- package/types/vuu-data/src/array-data-source/array-data-source.d.ts +0 -65
- package/types/vuu-data/src/array-data-source/group-utils.d.ts +0 -10
- package/types/vuu-data/src/array-data-source/sort-utils.d.ts +0 -4
- package/types/vuu-data/src/authenticate.d.ts +0 -1
- package/types/vuu-data/src/connection-manager.d.ts +0 -46
- package/types/vuu-data/src/connectionTypes.d.ts +0 -5
- package/types/vuu-data/src/constants.d.ts +0 -41
- package/types/vuu-data/src/data-source.d.ts +0 -172
- package/types/vuu-data/src/index.d.ts +0 -10
- package/types/vuu-data/src/inlined-worker.d.ts +0 -1
- package/types/vuu-data/src/json-data-source.d.ts +0 -53
- package/types/vuu-data/src/message-utils.d.ts +0 -26
- package/types/vuu-data/src/remote-data-source.d.ts +0 -56
- package/types/vuu-data/src/server-proxy/messages.d.ts +0 -43
- package/types/vuu-data/src/vuuUIMessageTypes.d.ts +0 -202
- package/types/vuu-data/src/websocket-connection.d.ts +0 -25
- package/types/vuu-table-extras/src/datagrid-configuration-ui/calculated-column-panel/CalculatedColumnPanel.d.ts +0 -11
- package/types/vuu-table-extras/src/datagrid-configuration-ui/calculated-column-panel/index.d.ts +0 -1
- package/types/vuu-table-extras/src/datagrid-configuration-ui/column-picker/ColumnListItem.d.ts +0 -4
- package/types/vuu-table-extras/src/datagrid-configuration-ui/column-picker/ColumnPicker.d.ts +0 -13
- package/types/vuu-table-extras/src/datagrid-configuration-ui/column-picker/index.d.ts +0 -1
- package/types/vuu-table-extras/src/datagrid-configuration-ui/column-settings-panel/ColumnSettingsPanel.d.ts +0 -9
- package/types/vuu-table-extras/src/datagrid-configuration-ui/column-type-panel/ColumnTypePanel.d.ts +0 -10
- package/types/vuu-table-extras/src/datagrid-configuration-ui/column-type-panel/NumericColumnPanel.d.ts +0 -4
- package/types/vuu-table-extras/src/datagrid-configuration-ui/column-type-panel/StringColumnPanel.d.ts +0 -4
- package/types/vuu-table-extras/src/datagrid-configuration-ui/column-type-panel/index.d.ts +0 -1
- package/types/vuu-table-extras/src/datagrid-configuration-ui/index.d.ts +0 -1
- package/types/vuu-table-extras/src/datagrid-configuration-ui/settings-panel/DatagridSettingsPanel.d.ts +0 -10
- package/types/vuu-table-extras/src/datagrid-configuration-ui/settings-panel/GridSettingsPanel.d.ts +0 -9
- package/types/vuu-table-extras/src/datagrid-configuration-ui/settings-panel/index.d.ts +0 -1
- package/types/vuu-table-extras/src/datagrid-configuration-ui/settings-panel/useGridSettings.d.ts +0 -59
- package/types/vuu-table-extras/src/index.d.ts +0 -6
- package/types/vuu-table-extras/src/table-settings/useTableSettings.d.ts +0 -14
- package/types/vuu-table-extras/src/table-settings-deprecated/calculated-column-panel/CalculatedColumnPanel.d.ts +0 -11
- package/types/vuu-table-extras/src/table-settings-deprecated/calculated-column-panel/index.d.ts +0 -1
- package/types/vuu-table-extras/src/table-settings-deprecated/column-settings-panel/ColumnSettingsPanel.d.ts +0 -9
- package/types/vuu-table-extras/src/table-settings-deprecated/column-settings-panel/index.d.ts +0 -1
- package/types/vuu-table-extras/src/table-settings-deprecated/column-type-panel/ColumnTypePanel.d.ts +0 -10
- package/types/vuu-table-extras/src/table-settings-deprecated/column-type-panel/NumericColumnPanel.d.ts +0 -4
- package/types/vuu-table-extras/src/table-settings-deprecated/column-type-panel/StringColumnPanel.d.ts +0 -4
- package/types/vuu-table-extras/src/table-settings-deprecated/column-type-panel/index.d.ts +0 -1
- package/types/vuu-table-extras/src/table-settings-deprecated/index.d.ts +0 -1
- package/types/vuu-table-extras/src/table-settings-deprecated/settings-panel/DatagridSettingsPanel.d.ts +0 -10
- package/types/vuu-table-extras/src/table-settings-deprecated/settings-panel/GridSettingsPanel.d.ts +0 -9
- package/types/vuu-table-extras/src/table-settings-deprecated/settings-panel/index.d.ts +0 -1
- package/types/vuu-table-extras/src/table-settings-deprecated/settings-panel/useGridSettings.d.ts +0 -59
- /package/types/{vuu-table-extras/src/cell-renderers → cell-renderers}/background-cell/BackgroundCell.d.ts +0 -0
- /package/types/{vuu-table-extras/src/cell-renderers → cell-renderers}/index.d.ts +0 -0
- /package/types/{vuu-table-extras/src/cell-renderers → cell-renderers}/progress-cell/ProgressCell.d.ts +0 -0
- /package/types/{vuu-table-extras/src/cell-renderers → cell-renderers}/progress-cell/index.d.ts +0 -0
- /package/types/{vuu-table-extras/src/cell-renderers → cell-renderers-next}/background-cell/index.d.ts +0 -0
- /package/types/{vuu-table-extras/src/cell-renderers → cell-renderers-next}/background-cell/useDirection.d.ts +0 -0
- /package/types/{vuu-table-extras/src/column-expression-input → column-expression-input}/column-function-descriptors.d.ts +0 -0
- /package/types/{vuu-table-extras/src/column-expression-input → column-expression-input}/column-language-parser/ColumnExpressionLanguage.d.ts +0 -0
- /package/types/{vuu-table-extras/src/column-expression-input → column-expression-input}/column-language-parser/ColumnExpressionTreeWalker.d.ts +0 -0
- /package/types/{vuu-table-extras/src/column-expression-input → column-expression-input}/column-language-parser/column-expression-parse-utils.d.ts +0 -0
- /package/types/{vuu-table-extras/src/column-expression-input → column-expression-input}/column-language-parser/generated/column-parser.d.ts +0 -0
- /package/types/{vuu-table-extras/src/column-expression-input → column-expression-input}/column-language-parser/generated/column-parser.terms.d.ts +0 -0
- /package/types/{vuu-table-extras/src/column-expression-input → column-expression-input}/column-language-parser/index.d.ts +0 -0
- /package/types/{vuu-table-extras/src/column-expression-input → column-expression-input}/column-language-parser/test.d.mts +0 -0
- /package/types/{vuu-table-extras/src/column-expression-input → column-expression-input}/functionDocInfo.d.ts +0 -0
- /package/types/{vuu-table-extras/src/column-expression-input → column-expression-input}/highlighting.d.ts +0 -0
- /package/types/{vuu-table-extras/src/column-expression-input → column-expression-input}/index.d.ts +0 -0
- /package/types/{vuu-table-extras/src/column-expression-input → column-expression-input}/theme.d.ts +0 -0
- /package/types/{vuu-table-extras/src/column-expression-input → column-expression-input}/useColumnAutoComplete.d.ts +0 -0
- /package/types/{vuu-table-extras/src/column-expression-input → column-expression-input}/useColumnExpressionSuggestionProvider.d.ts +0 -0
- /package/types/{vuu-table-extras/src/column-list → column-list}/ColumnList.d.ts +0 -0
- /package/types/{vuu-table-extras/src/column-list → column-list}/index.d.ts +0 -0
- /package/types/{vuu-table-extras/src/datagrid-configuration-ui/column-settings-panel → column-settings}/index.d.ts +0 -0
- /package/types/{vuu-table-extras/src/datasource-stats → datasource-stats}/DatasourceStats.d.ts +0 -0
- /package/types/{vuu-table-extras/src/datasource-stats → datasource-stats}/index.d.ts +0 -0
- /package/types/{vuu-table-extras/src/table-settings → table-settings}/index.d.ts +0 -0
package/esm/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../../packages/vuu-table-extras/src/cell-renderers/background-cell/BackgroundCell.tsx", "../../../packages/vuu-table-extras/src/cell-renderers/background-cell/useDirection.ts", "../../../packages/vuu-table-extras/src/cell-renderers/progress-cell/ProgressCell.tsx", "../../../packages/vuu-table-extras/src/
|
|
4
|
-
"sourcesContent": ["import { ColumnType, TableCellProps } from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n DOWN1,\n DOWN2,\n isTypeDescriptor,\n metadataKeys,\n registerComponent,\n UP1,\n UP2,\n} from \"@vuu-ui/vuu-utils\";\nimport cx from \"classnames\";\nimport { useDirection } from \"./useDirection\";\n\nimport \"./BackgroundCell.css\";\nimport \"./FlashingBackground.css\";\n\nconst CHAR_ARROW_UP = String.fromCharCode(11014);\nconst CHAR_ARROW_DOWN = String.fromCharCode(11015);\n\nconst { KEY } = metadataKeys;\n\nconst classBase = \"vuuBackgroundCell\";\n\n// TODO these sre repeated from PriceFormatter - where shoud they live ?\nconst FlashStyle = {\n ArrowOnly: \"arrow\",\n BackgroundOnly: \"bg-only\",\n ArrowBackground: \"arrow-bg\",\n};\n\nconst getFlashStyle = (colType?: ColumnType) => {\n if (isTypeDescriptor(colType) && colType.renderer) {\n if (\"flashStyle\" in colType.renderer) {\n return colType.renderer[\"flashStyle\"];\n }\n }\n return FlashStyle.BackgroundOnly;\n};\n\nconst BackgroundCell = ({ column, row }: TableCellProps) => {\n //TODO what about click handling\n\n const { key, type, valueFormatter } = column;\n const value = row[key];\n const flashStyle = getFlashStyle(type);\n const direction = useDirection(row[KEY], value, column);\n const arrow =\n flashStyle === FlashStyle.ArrowOnly ||\n flashStyle === FlashStyle.ArrowBackground\n ? direction === UP1 || direction === UP2\n ? CHAR_ARROW_UP\n : direction === DOWN1 || direction === DOWN2\n ? CHAR_ARROW_DOWN\n : null\n : null;\n\n const dirClass = direction ? ` ` + direction : \"\";\n\n const className = cx(classBase, dirClass, {\n [`${classBase}-arrowOnly`]: flashStyle === FlashStyle.ArrowOnly,\n [`${classBase}-arrowBackground`]: flashStyle === FlashStyle.ArrowBackground,\n });\n\n return (\n <div className={className} tabIndex={-1}>\n <div className={`${classBase}-flasher`}>{arrow}</div>\n {valueFormatter(row[column.key])}\n </div>\n );\n};\n\nregisterComponent(\"background\", BackgroundCell, \"cell-renderer\", {\n serverDataType: [\"long\", \"int\", \"double\"],\n});\n", "import { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n getMovingValueDirection,\n isTypeDescriptor,\n isValidNumber,\n valueChangeDirection,\n} from \"@vuu-ui/vuu-utils\";\nimport { useEffect, useRef } from \"react\";\n\nconst INITIAL_VALUE = [undefined, undefined, undefined, undefined];\n\ntype State = [string, unknown, KeyedColumnDescriptor, valueChangeDirection];\n\nexport function useDirection(\n key: string,\n value: unknown,\n column: KeyedColumnDescriptor\n) {\n const ref = useRef<State>();\n const [prevKey, prevValue, prevColumn, prevDirection] =\n ref.current || INITIAL_VALUE;\n\n const { type: dataType } = column;\n const decimals = isTypeDescriptor(dataType)\n ? dataType.formatting?.decimals\n : undefined;\n\n const direction =\n key === prevKey &&\n isValidNumber(value) &&\n isValidNumber(prevValue) &&\n column === prevColumn\n ? getMovingValueDirection(value, prevDirection, prevValue, decimals)\n : \"\";\n\n useEffect(() => {\n ref.current = [key, value, column, direction];\n });\n\n return direction;\n}\n", "import { TableCellProps } from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n isColumnTypeRenderer,\n isTypeDescriptor,\n registerComponent,\n} from \"@vuu-ui/vuu-utils\";\nimport cx from \"classnames\";\nimport { CSSProperties } from \"react\";\n\nimport \"./ProgressCell.css\";\n\nconst classBase = \"vuuProgressCell\";\n\nconst ProgressCell = ({ column, columnMap, row }: TableCellProps) => {\n //TODO what about click handling\n\n const { type } = column;\n const value = row[column.key];\n let showProgress = false;\n let percentage = 0;\n\n if (isTypeDescriptor(type) && isColumnTypeRenderer(type.renderer)) {\n const { associatedField } = type.renderer;\n const associatedValue = row[columnMap[associatedField]];\n if (typeof value === \"number\" && typeof associatedValue === \"number\") {\n percentage = Math.min(Math.round((value / associatedValue) * 100), 100);\n showProgress = isFinite(percentage);\n } else {\n // Temp workaround for bug on server that sends aggregated values as strings\n const floatValue = parseFloat(value as string);\n if (Number.isFinite(floatValue)) {\n const floatOtherValue = parseFloat(associatedValue as string);\n if (Number.isFinite(floatOtherValue)) {\n percentage = Math.min(\n Math.round((floatValue / floatOtherValue) * 100),\n 100\n );\n showProgress = isFinite(percentage);\n }\n }\n }\n }\n\n const className = cx(classBase, {});\n\n return (\n <div className={className} tabIndex={-1}>\n {showProgress ? (\n <span className={`${classBase}-track`}>\n <span className={`${classBase}-bg`} />\n <span\n className={`${classBase}-bar`}\n style={\n { \"--progress-bar-pct\": `-${100 - percentage}%` } as CSSProperties\n }\n />\n </span>\n ) : null}\n <span className={`${classBase}-text`}>{`${percentage} %`}</span>\n </div>\n );\n};\n\nregisterComponent(\"vuu.progress\", ProgressCell, \"cell-renderer\", {\n serverDataType: [\"long\", \"int\", \"double\"],\n});\n", "import {\n List,\n ListItem,\n ListItemProps,\n ListProps,\n} from \"@vuu-ui/vuu-ui-controls\";\nimport { Checkbox } from \"@salt-ds/core\";\nimport { Switch } from \"@salt-ds/lab\";\nimport cx from \"classnames\";\nimport { ColumnDescriptor } from \"packages/vuu-datagrid-types\";\nimport { HTMLAttributes, SyntheticEvent, useCallback } from \"react\";\nimport { ColumnItem } from \"../table-settings\";\n\nimport \"./ColumnList.css\";\n\nconst classBase = \"vuuColumnList\";\nconst classBaseListItem = \"vuuColumnListItem\";\n\nexport type ColumnChangeHandler = (\n columnName: string,\n propertyName: keyof ColumnDescriptor | \"subscribed\",\n value: string | number | boolean\n) => void;\n\nexport interface ColumnListProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n columnItems: ColumnItem[];\n onChange: ColumnChangeHandler;\n onMoveListItem: ListProps[\"onMoveListItem\"];\n}\n\nconst ColumnListItem = ({\n className: classNameProp,\n item,\n ...listItemProps\n}: ListItemProps<ColumnItem>) => {\n return (\n <ListItem\n {...listItemProps}\n className={cx(classNameProp, classBaseListItem)}\n data-name={item?.name}\n >\n <Switch className={`${classBase}-switch`} checked={item?.subscribed} />\n <span className={`${classBase}-text`}>{item?.label ?? item?.name}</span>\n <Checkbox\n className={`${classBase}-checkBox`}\n checked={item?.hidden !== true}\n disabled={item?.subscribed !== true}\n />\n </ListItem>\n );\n};\n\nexport const ColumnList = ({\n columnItems,\n onChange,\n onMoveListItem,\n ...htmlAttributes\n}: ColumnListProps) => {\n const handleChange = useCallback(\n (evt: SyntheticEvent) => {\n const input = evt.target as HTMLInputElement;\n const listItem = input.closest(`.${classBaseListItem}`) as HTMLElement;\n const {\n dataset: { name },\n } = listItem;\n if (name) {\n const saltSwitch = input.closest(`.${classBase}-switch`) as HTMLElement;\n const saltCheckbox = input.closest(\n `.${classBase}-checkBox`\n ) as HTMLElement;\n\n if (saltSwitch) {\n onChange(name, \"subscribed\", input.checked);\n } else if (saltCheckbox) {\n onChange(name, \"hidden\", input.checked === false);\n }\n }\n },\n [onChange]\n );\n return (\n <div {...htmlAttributes} className={classBase}>\n <div className={`${classBase}-header`}>\n <span>Column Selection</span>\n </div>\n <div className={`${classBase}-colHeadings`}>\n <span>Column subscription</span>\n <span>Visibility</span>\n </div>\n <List<ColumnItem, \"none\">\n ListItem={ColumnListItem}\n allowDragDrop\n height=\"100%\"\n onChange={handleChange}\n onMoveListItem={onMoveListItem}\n selectionStrategy=\"none\"\n source={columnItems}\n itemHeight={33}\n />\n </div>\n );\n};\n", "import {\n autocompletion,\n Completion,\n defaultKeymap,\n EditorState,\n EditorView,\n ensureSyntaxTree,\n keymap,\n minimalSetup,\n startCompletion,\n} from \"@vuu-ui/vuu-codemirror\";\nimport { createEl } from \"@vuu-ui/vuu-utils\";\nimport { MutableRefObject, useEffect, useMemo, useRef } from \"react\";\nimport { columnExpressionLanguageSupport } from \"./column-language-parser\";\nimport {\n ColumnDefinitionExpression,\n walkTree,\n} from \"./column-language-parser/ColumnExpressionTreeWalker\";\nimport { vuuHighlighting } from \"./highlighting\";\nimport { vuuTheme } from \"./theme\";\nimport {\n ApplyCompletion,\n useColumnAutoComplete,\n} from \"./useColumnAutoComplete\";\n\nexport type ColumnExpressionOperator = \"Times\" | \"Divide\" | \"Minus\" | \"Plus\";\n\nexport type ColumnExpressionSuggestionType =\n | \"column\"\n | \"columnValue\"\n | \"expression\"\n | \"condition-operator\"\n | \"operator\"\n | \"relational-operator\";\n\nexport type ColumnExpressionSuggestionOptions = {\n columnName?: string;\n functionName?: string;\n operator?: ColumnExpressionOperator;\n prefix?: string;\n startsWith?: string;\n selection?: string[];\n};\n\n// TODO move this somewhere neutral\nexport interface IExpressionSuggestionProvider {\n getSuggestions: (\n valueType: ColumnExpressionSuggestionType,\n options?: ColumnExpressionSuggestionOptions\n ) => Promise<Completion[]>;\n isPartialMatch: (\n valueType: ColumnExpressionSuggestionType,\n columnName?: string,\n text?: string | undefined\n ) => Promise<boolean>;\n}\n\nexport interface ExpressionSuggestionConsumer {\n suggestionProvider: IExpressionSuggestionProvider;\n}\n\nconst getView = (ref: MutableRefObject<EditorView | undefined>): EditorView => {\n if (ref.current == undefined) {\n throw Error(\"EditorView not defined\");\n }\n return ref.current;\n};\n\nconst getOptionClass = (/*completion: Completion*/) => {\n return \"vuuSuggestion\";\n};\n\nconst noop = () => console.log(\"noooop\");\n\nconst hasExpressionType = (\n completion: Completion\n): completion is Completion & { expressionType: string } =>\n \"expressionType\" in completion;\n\nconst injectOptionContent = (\n completion: Completion /*, state: EditorState*/\n) => {\n if (hasExpressionType(completion)) {\n const div = createEl(\"div\", \"expression-type-container\");\n const span = createEl(\"span\", \"expression-type\", completion.expressionType);\n div.appendChild(span);\n return div;\n } else {\n return null;\n }\n};\n\nexport interface ColumnExpressionEditorProps {\n onChange?: (\n source: string,\n expression: ColumnDefinitionExpression | undefined\n ) => void;\n onSubmitExpression?: (\n source: string,\n expression: ColumnDefinitionExpression | undefined\n ) => void;\n suggestionProvider: IExpressionSuggestionProvider;\n}\n\nexport const useColumnExpressionEditor = ({\n onChange,\n onSubmitExpression,\n suggestionProvider,\n}: ColumnExpressionEditorProps) => {\n const editorRef = useRef<HTMLDivElement>(null);\n const onSubmit = useRef<ApplyCompletion>(noop);\n const viewRef = useRef<EditorView>();\n const completionFn = useColumnAutoComplete(suggestionProvider, onSubmit);\n\n const [createState, clearInput] = useMemo(() => {\n const parseExpression = ():\n | [string, ColumnDefinitionExpression]\n | [\"\", undefined] => {\n const view = getView(viewRef);\n const source = view.state.doc.toString();\n const tree = ensureSyntaxTree(view.state, view.state.doc.length, 5000);\n if (tree) {\n const expression = walkTree(tree, source);\n return [source, expression];\n } else {\n return [\"\", undefined];\n }\n };\n\n const clearInput = () => {\n getView(viewRef).setState(createState());\n };\n\n const submitExpressionAndClearInput = () => {\n const [source, expression] = parseExpression();\n onSubmitExpression?.(source, expression);\n clearInput();\n };\n\n const submitFilter = (key: string) => {\n return keymap.of([\n {\n key,\n run() {\n submitExpressionAndClearInput();\n return true;\n },\n },\n ]);\n };\n\n const showSuggestions = (key: string) => {\n return keymap.of([\n {\n key,\n run() {\n startCompletion(getView(viewRef));\n return true;\n },\n },\n ]);\n };\n\n const createState = (): EditorState =>\n EditorState.create({\n doc: \"\",\n extensions: [\n minimalSetup,\n autocompletion({\n addToOptions: [\n {\n render: injectOptionContent,\n position: 70,\n },\n ],\n override: [completionFn],\n optionClass: getOptionClass,\n }),\n columnExpressionLanguageSupport(),\n keymap.of(defaultKeymap),\n submitFilter(\"Ctrl-Enter\"),\n showSuggestions(\"ArrowDown\"),\n EditorView.updateListener.of((v) => {\n const view = getView(viewRef);\n if (v.docChanged) {\n startCompletion(view);\n const source = view.state.doc.toString();\n onChange?.(source, undefined);\n }\n }),\n // Enforces single line view\n // EditorState.transactionFilter.of((tr) =>\n // tr.newDoc.lines > 1 ? [] : tr\n // ),\n vuuTheme,\n vuuHighlighting,\n ],\n });\n\n onSubmit.current = () => {\n submitExpressionAndClearInput();\n // TODO refocu sthe editor\n setTimeout(() => {\n getView(viewRef).focus();\n }, 100);\n };\n\n return [createState, clearInput];\n }, [completionFn, onChange, onSubmitExpression]);\n\n useEffect(() => {\n if (!editorRef.current) {\n throw Error(\"editor not in dom\");\n }\n\n viewRef.current = new EditorView({\n state: createState(),\n parent: editorRef.current,\n });\n\n return () => {\n viewRef.current?.destroy();\n };\n }, [completionFn, createState]);\n\n return { editorRef, clearInput };\n};\n", "import {\n LanguageSupport,\n LRLanguage,\n styleTags,\n tags as tag,\n} from \"@vuu-ui/vuu-codemirror\";\nimport { parser } from \"./generated/column-parser\";\n\nconst columnExpressionLanguage = LRLanguage.define({\n name: \"VuuColumnExpression\",\n parser: parser.configure({\n props: [\n styleTags({\n Function: tag.variableName,\n String: tag.string,\n Or: tag.emphasis,\n Operator: tag.operator,\n }),\n ],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n }) as any,\n});\n\nexport const columnExpressionLanguageSupport = () => {\n return new LanguageSupport(\n columnExpressionLanguage /*, [exampleCompletion]*/\n );\n};\n", "// This file was generated by lezer-generator. You probably shouldn't edit it.\nimport {LRParser} from \"@lezer/lr\"\nexport const parser = LRParser.deserialize({\n version: 14,\n states: \"&fOVQPOOO!SQPO'#C^OVQPO'#CcQ!pQPOOO#OQPO'#CkO#TQPO'#CrOOQO'#Cy'#CyO#YQPO,58}OVQPO,59QOVQPO,59QOVQPO,59VOVQPO'#CtOOQO,59^,59^OOQO1G.i1G.iOOQO1G.l1G.lO#kQPO1G.lO$fQPO'#CmO%WQQO1G.qOOQO'#C{'#C{O%cQPO,59`OOQO'#Cn'#CnO%wQPO,59XOVQPO,59ZOVQPO,59[OVQPO7+$]OVQPO'#CuO&`QPO1G.zOOQO1G.z1G.zO&hQQO'#C^O&rQQO1G.sO'ZQQO1G.uOOQO1G.v1G.vO'fQPO<<GwO'wQPO,59aOOQO-E6s-E6sOOQO7+$f7+$fOVQPOAN=cO(]QQO1G.lO(tQPOG22}OOQOLD(iLD(iO%wQPO,59QO%wQPO,59Q\",\n stateData: \")[~OlOS~ORUOSUOTUOUUOWQO`SOnPO~OWgXZQX[QX]QX^QXeQX~OjQXXQXpQXqQXrQXsQXtQXuQX~PnOZWO[WO]XO^XO~OWYO~OWZO~OX]OZWO[WO]XO^XO~OZWO[WO]Yi^YijYiXYipYiqYirYisYitYiuYieYi~OZWO[WO]XO^XOpdOqdOrdOsdOtdOudO~OehOvfOwgO~OXkOZWO[WO]XO^XOeiO~ORUOSUOTUOUUOWQO`SOnlO~OXsOeiO~OvQXwQX~PnOZxO[xO]yO^yOeaivaiwai~OwgOecivci~OZWO[WO]XO^XOetO~OZWO[WO]XO^XOXiaeia~OZxO[xO]Yi^YieYivYiwYi~OXwOZWO[WO]XO^XO~O`UTn~\",\n goto: \"#spPPqPPPPqPPqPPPPqP!R!W!R!RPq!Z!k!nPPP!tP#jmUOQWXYZefghitxyVbYfgRe`mTOQWXYZefghitxyR[TQjcRrjQROQVQS^WxQ_XU`YfgQcZQmeQphQqiQuyRvtQaYQnfRog\",\n nodeNames: \"\u26A0 ColumnDefinitionExpression Column Number String True False ParenthesizedExpression OpenBrace CloseBrace ArithmeticExpression Divide Times Plus Minus ConditionalExpression If RelationalExpression RelationalOperator AndCondition OrCondition Comma CallExpression Function ArgList\",\n maxTerm: 39,\n skippedNodes: [0],\n repeatNodeCount: 1,\n tokenData: \".^~RnXY#PYZ#P]^#Ppq#Pqr#brs#mxy$eyz$jz{$o{|$t|}$y}!O%O!O!P%T!P!Q%c!Q![%h!^!_%s!_!`&Q!`!a&V!c!}&d#R#S&d#T#U&u#U#Y&d#Y#Z(Y#Z#]&d#]#^*j#^#c&d#c#d+f#d#h&d#h#i,b#i#o&d~#USl~XY#PYZ#P]^#Ppq#P~#eP!_!`#h~#mOu~~#pWOX#mZ]#m^r#mrs$Ys#O#m#P;'S#m;'S;=`$_<%lO#m~$_OS~~$bP;=`<%l#m~$jOW~~$oOX~~$tO[~~$yO]~~%OOe~~%TO^~~%WP!Q![%Z~%`PR~!Q![%Z~%hOZ~~%mQR~!O!P%Z!Q![%h~%xPr~!_!`%{~&QOt~~&VOp~~&[Pq~!_!`&_~&dOs~P&iSnP!Q![&d!c!}&d#R#S&d#T#o&dR&zUnP!Q![&d!c!}&d#R#S&d#T#b&d#b#c'^#c#o&dR'cUnP!Q![&d!c!}&d#R#S&d#T#W&d#W#X'u#X#o&dR'|SvQnP!Q![&d!c!}&d#R#S&d#T#o&d~(_TnP!Q![&d!c!}&d#R#S&d#T#U(n#U#o&d~(sUnP!Q![&d!c!}&d#R#S&d#T#`&d#`#a)V#a#o&d~)[UnP!Q![&d!c!}&d#R#S&d#T#g&d#g#h)n#h#o&d~)sUnP!Q![&d!c!}&d#R#S&d#T#X&d#X#Y*V#Y#o&d~*^SU~nP!Q![&d!c!}&d#R#S&d#T#o&d~*oUnP!Q![&d!c!}&d#R#S&d#T#Y&d#Y#Z+R#Z#o&d~+YS`~nP!Q![&d!c!}&d#R#S&d#T#o&dR+kUnP!Q![&d!c!}&d#R#S&d#T#f&d#f#g+}#g#o&dR,USwQnP!Q![&d!c!}&d#R#S&d#T#o&d~,gUnP!Q![&d!c!}&d#R#S&d#T#f&d#f#g,y#g#o&d~-OUnP!Q![&d!c!}&d#R#S&d#T#i&d#i#j-b#j#o&d~-gUnP!Q![&d!c!}&d#R#S&d#T#X&d#X#Y-y#Y#o&d~.QST~nP!Q![&d!c!}&d#R#S&d#T#o&d\",\n tokenizers: [0, 1],\n topRules: {\"ColumnDefinitionExpression\":[0,1]},\n tokenPrec: 375\n})\n", "import { Tree } from \"@vuu-ui/vuu-codemirror\";\nimport { RelationalExpression } from \"./generated/column-parser.terms\";\ntype expressionType =\n | \"arithmeticExpression\"\n | \"booleanCondition\"\n | \"booleanLiteralExpression\"\n | \"callExpression\"\n | \"colExpression\"\n | \"conditionalExpression\"\n | \"numericLiteralExpression\"\n | \"relationalExpression\"\n | \"stringLiteralExpression\"\n | \"unknown\";\n\ntype arithmeticOp = \"*\" | \"/\" | \"+\" | \"-\" | \"unknown\";\ntype booleanOp = \"and\" | \"or\";\ntype relationalOp = \"=\" | \"!=\" | \">\" | \">=\" | \"<\" | \"<=\" | \"unknown\";\n\nexport interface Expression {\n type: expressionType;\n expressions?: Expression[];\n toJSON?: () => unknown;\n value?: string | number | boolean;\n}\n\ninterface UnknownExpression extends Expression {\n type: \"unknown\";\n}\n\ninterface BooleanLiteralExpression {\n type: \"booleanLiteralExpression\";\n value: boolean;\n}\n\ninterface NumericLiteralExpression {\n type: \"numericLiteralExpression\";\n value: number;\n}\ninterface StringLiteralExpression {\n type: \"stringLiteralExpression\";\n value: string;\n}\n\ninterface ArithmeticExpression extends Expression {\n expressions: [Expression, Expression];\n op: arithmeticOp;\n type: \"arithmeticExpression\";\n}\n\ninterface BooleanCondition extends Expression {\n expressions: Expression[];\n op: booleanOp;\n type: \"booleanCondition\";\n}\ninterface RelationalExpression extends Expression {\n expressions: Expression[];\n op: relationalOp;\n type: \"relationalExpression\";\n}\n\ninterface ColExpression extends Expression {\n column?: string;\n type: \"colExpression\";\n}\n\ninterface CallExpression extends Expression {\n arguments: Expression[];\n functionName?: string;\n type: \"callExpression\";\n}\n\ntype ConditionExpression = RelationalExpression | BooleanCondition;\n\ninterface ConditionalExpression extends Expression {\n type: \"conditionalExpression\";\n condition: ConditionExpression;\n truthyExpression: Expression;\n falsyExpression: Expression;\n}\n\nexport type ColumnDefinitionExpression =\n | ArithmeticExpression\n | BooleanLiteralExpression\n | CallExpression\n | ColExpression\n | ConditionalExpression\n | NumericLiteralExpression\n | StringLiteralExpression;\n\nclass LiteralExpressionImpl implements Expression {\n type:\n | \"booleanLiteralExpression\"\n | \"numericLiteralExpression\"\n | \"stringLiteralExpression\";\n value: boolean | number | string;\n constructor(value: boolean | number | string) {\n this.value = value;\n switch (typeof value) {\n case \"boolean\":\n this.type = \"booleanLiteralExpression\";\n break;\n case \"number\":\n this.type = \"numericLiteralExpression\";\n break;\n default:\n this.type = \"stringLiteralExpression\";\n }\n }\n toJSON() {\n return {\n type: this.type,\n value: this.value,\n } as\n | StringLiteralExpression\n | BooleanLiteralExpression\n | NumericLiteralExpression;\n }\n}\nclass ColumnExpressionImpl implements ColExpression {\n type = \"colExpression\" as const;\n column: string;\n constructor(columnName: string) {\n this.column = columnName;\n }\n toJSON() {\n return {\n type: this.type,\n column: this.column,\n } as ColExpression;\n }\n}\nclass ArithmeticExpressionImpl implements ArithmeticExpression {\n #expressions: [Expression, Expression] = [\n { type: \"unknown\" },\n { type: \"unknown\" },\n ];\n #op: arithmeticOp | \"unknown\";\n type = \"arithmeticExpression\" as const;\n constructor(op: arithmeticOp | \"unknown\" = \"unknown\") {\n this.#op = op;\n }\n get op() {\n return this.#op;\n }\n set op(op: arithmeticOp) {\n this.#op = op;\n }\n get expressions() {\n return this.#expressions;\n }\n\n toJSON() {\n return {\n type: this.type,\n op: this.#op,\n expressions: this.#expressions,\n };\n }\n}\n\nclass CallExpressionImpl implements CallExpression {\n #expressions: Expression[] = [];\n functionName: string;\n type = \"callExpression\" as const;\n constructor(functionName: string) {\n this.functionName = functionName;\n }\n\n get expressions() {\n return this.#expressions;\n }\n get arguments() {\n return this.#expressions;\n }\n\n toJSON() {\n return {\n type: this.type,\n functionName: this.functionName,\n arguments: this.#expressions.map((e) => e.toJSON?.()),\n } as CallExpression;\n }\n}\n\nclass RelationalExpressionImpl implements RelationalExpression {\n #expressions: [Expression, Expression] = [\n { type: \"unknown\" },\n { type: \"unknown\" },\n ];\n #op: relationalOp = \"unknown\";\n type = \"relationalExpression\" as const;\n\n get op() {\n return this.#op;\n }\n set op(op: relationalOp) {\n this.#op = op;\n }\n get expressions() {\n return this.#expressions;\n }\n\n toJSON() {\n return {\n type: this.type,\n op: this.#op,\n expressions: this.#expressions,\n } as RelationalExpression;\n }\n}\n\nclass BooleanConditionImp implements BooleanCondition {\n #expressions: [Expression, Expression] = [\n { type: \"unknown\" },\n { type: \"unknown\" },\n ];\n #op: \"and\" | \"or\";\n type = \"booleanCondition\" as const;\n constructor(booleanOperator: \"and\" | \"or\") {\n this.#op = booleanOperator;\n }\n get op() {\n return this.#op;\n }\n get expressions() {\n return this.#expressions;\n }\n toJSON() {\n return {\n type: this.type,\n op: this.#op,\n expressions: this.#expressions.map((e) => e.toJSON?.()),\n };\n }\n}\n\nclass ConditionalExpressionImpl implements ConditionalExpression {\n #expressions: [ConditionExpression, Expression, Expression];\n type = \"conditionalExpression\" as const;\n\n constructor(booleanOperator?: \"and\" | \"or\") {\n this.#expressions = [\n booleanOperator\n ? new BooleanConditionImp(booleanOperator)\n : new RelationalExpressionImpl(),\n { type: \"unknown\" },\n { type: \"unknown\" },\n ];\n }\n\n get expressions() {\n return this.#expressions;\n }\n\n get condition(): ConditionExpression {\n return this.#expressions[0];\n }\n get truthyExpression(): Expression {\n return this.#expressions[1];\n }\n set truthyExpression(expression: Expression) {\n this.#expressions[1] = expression;\n }\n get falsyExpression(): Expression {\n return this.#expressions[2];\n }\n set falsyExpression(expression: Expression) {\n this.#expressions[2] = expression;\n }\n\n toJSON() {\n return {\n type: this.type,\n condition: this.condition.toJSON?.(),\n truthyExpression: this.truthyExpression,\n falsyExpression: this.falsyExpression?.toJSON?.() ?? this.falsyExpression,\n };\n }\n}\n\ntype PartialExpression =\n | ArithmeticExpression\n | RelationalExpression\n | ColExpression\n | CallExpression\n | BooleanCondition\n | Partial<ConditionalExpression>;\n\nconst isUnknown = (e: Expression): e is UnknownExpression =>\n e.type === \"unknown\";\n\nconst isArithmeticExpression = (\n expression: PotentiallyUnresolvedExpression\n): expression is ArithmeticExpression =>\n expression.type === \"arithmeticExpression\";\n\nconst isCallExpression = (\n expression: PotentiallyUnresolvedExpression\n): expression is CallExpression => expression.type === \"callExpression\";\n\nconst isConditionalExpression = (\n expression: PotentiallyUnresolvedExpression\n): expression is ConditionalExpression =>\n expression.type === \"conditionalExpression\";\n\nconst isCondition = (\n expression: Expression | PartialExpression\n): expression is ConditionExpression =>\n expression.type === \"relationalExpression\" ||\n expression.type === \"booleanCondition\";\n\nconst booleanConditionIsIncomplete = (\n condition: ConditionExpression\n): boolean =>\n condition.expressions.length < 2 ||\n condition.expressions.some((e) => conditionIsIncomplete(e));\n\nconst isBooleanCondition = (\n expression: Expression\n): expression is BooleanCondition => expression.type === \"booleanCondition\";\n\nconst isRelationalExpression = (\n expression?: Expression\n): expression is RelationalExpression =>\n expression?.type === \"relationalExpression\";\n\nconst conditionIsIncomplete = (\n condition: Expression\n): condition is ConditionExpression =>\n (isBooleanCondition(condition) && booleanConditionIsIncomplete(condition)) ||\n (isRelationalExpression(condition) && condition.expressions.length < 2);\n\nconst firstIncompleteExpression = (\n expression: Expression\n): Expression | undefined => {\n if (isUnknown(expression)) {\n return expression;\n } else if (isRelationalExpression(expression)) {\n const [operand1, operand2] = expression.expressions;\n if (expressionIsIncomplete(operand1)) {\n return firstIncompleteExpression(operand1);\n } else if (expression.op === \"unknown\") {\n return expression;\n } else if (expressionIsIncomplete(operand2)) {\n return firstIncompleteExpression(operand2);\n }\n } else if (isCondition(expression)) {\n const { expressions = [] } = expression;\n for (const e of expressions) {\n if (expressionIsIncomplete(e)) {\n return firstIncompleteExpression(e);\n }\n }\n } else if (isConditionalExpression(expression)) {\n const { condition, truthyExpression, falsyExpression } = expression;\n if (expressionIsIncomplete(condition)) {\n return firstIncompleteExpression(condition);\n } else if (expressionIsIncomplete(truthyExpression)) {\n return firstIncompleteExpression(truthyExpression);\n } else if (expressionIsIncomplete(falsyExpression)) {\n return firstIncompleteExpression(falsyExpression);\n }\n } else if (isArithmeticExpression(expression)) {\n const { expressions = [] } = expression;\n for (const e of expressions) {\n if (expressionIsIncomplete(e)) {\n return firstIncompleteExpression(e);\n }\n }\n }\n};\nconst replaceUnknownExpression = (\n incompleteExpression: Expression,\n unknownExpression: UnknownExpression,\n expression: Expression\n): boolean => {\n const { expressions = [] } = incompleteExpression;\n if (expressions.includes(unknownExpression)) {\n const pos = expressions.indexOf(unknownExpression);\n expressions.splice(pos, 1, expression);\n return true;\n } else {\n for (const e of expressions) {\n if (replaceUnknownExpression(e, unknownExpression, expression)) {\n return true;\n }\n }\n }\n return false;\n};\n\nconst expressionIsIncomplete = (expression: Expression): boolean => {\n if (isUnknown(expression)) {\n return true;\n } else if (isConditionalExpression(expression)) {\n return (\n expressionIsIncomplete(expression.condition) ||\n expressionIsIncomplete(expression.truthyExpression) ||\n expressionIsIncomplete(expression.falsyExpression)\n );\n } else if (\n isRelationalExpression(expression) ||\n isBooleanCondition(expression)\n ) {\n return (\n expression.op === undefined ||\n expression.expressions.some((e) => expressionIsIncomplete(e))\n );\n }\n // TODO missing cases\n return false;\n};\n\ntype ExpressionImpl =\n | ArithmeticExpressionImpl\n | CallExpressionImpl\n | ColumnExpressionImpl\n | ConditionalExpressionImpl\n | LiteralExpressionImpl;\n\ntype PotentiallyUnresolvedExpression = Expression | PartialExpression;\n\nconst addExpression = (\n expression: Expression,\n subExpression: PartialExpression | Expression\n) => {\n const targetExpression = firstIncompleteExpression(expression);\n if (targetExpression) {\n if (targetExpression.expressions) {\n targetExpression.expressions.push(subExpression as Expression);\n } else {\n console.warn(\"don't know how to treat targetExpression\");\n }\n } else {\n console.error(\"no target expression found\");\n }\n};\n\nclass ColumnExpression {\n #expression: ExpressionImpl | undefined;\n\n #callStack: CallExpression[] = [];\n\n setCondition(booleanOperator?: \"and\" | \"or\") {\n if (this.#expression === undefined) {\n this.addExpression(new ConditionalExpressionImpl(booleanOperator));\n } else if (isConditionalExpression(this.#expression)) {\n if (expressionIsIncomplete(this.#expression.condition)) {\n const condition = booleanOperator\n ? new BooleanConditionImp(booleanOperator)\n : new RelationalExpressionImpl();\n this.addExpression(condition);\n } else if (isUnknown(this.#expression.truthyExpression)) {\n this.#expression.truthyExpression = new ConditionalExpressionImpl(\n booleanOperator\n );\n } else if (expressionIsIncomplete(this.#expression.truthyExpression)) {\n const condition = booleanOperator\n ? new BooleanConditionImp(booleanOperator)\n : new RelationalExpressionImpl();\n this.addExpression(condition);\n } else if (isUnknown(this.#expression.falsyExpression)) {\n this.#expression.falsyExpression = new ConditionalExpressionImpl(\n booleanOperator\n );\n } else if (expressionIsIncomplete(this.#expression.falsyExpression)) {\n const condition = booleanOperator\n ? new BooleanConditionImp(booleanOperator)\n : new RelationalExpressionImpl();\n this.addExpression(condition);\n }\n } else {\n console.error(\"setCondition called unexpectedly\");\n }\n }\n\n addExpression(expression: ExpressionImpl | Expression) {\n if (this.#callStack.length > 0) {\n const currentCallExpression = this.#callStack.at(-1);\n currentCallExpression?.arguments.push(expression as Expression);\n } else if (this.#expression === undefined) {\n this.#expression = expression as ExpressionImpl;\n } else if (isArithmeticExpression(this.#expression)) {\n const targetExpression = firstIncompleteExpression(this.#expression);\n if (targetExpression && isUnknown(targetExpression)) {\n replaceUnknownExpression(\n this.#expression,\n targetExpression,\n expression\n );\n }\n } else if (isConditionalExpression(this.#expression)) {\n if (expressionIsIncomplete(this.#expression)) {\n const targetExpression = firstIncompleteExpression(this.#expression);\n if (targetExpression && isUnknown(targetExpression)) {\n replaceUnknownExpression(\n this.#expression,\n targetExpression,\n expression\n );\n } else if (targetExpression) {\n addExpression(targetExpression, expression);\n }\n }\n }\n }\n\n setFunction(functionName: string) {\n const callExpression = new CallExpressionImpl(functionName);\n this.addExpression(callExpression);\n this.#callStack.push(callExpression);\n }\n\n setColumn(columnName: string) {\n this.addExpression(new ColumnExpressionImpl(columnName));\n }\n\n setArithmeticOp(value: string) {\n const op = value as arithmeticOp;\n const expression = this.#expression as Expression;\n if (isArithmeticExpression(expression)) {\n expression.op = op;\n }\n // else {\n // const targetExpression = firstIncompleteExpression(this.#expression);\n // if (targetExpression) {\n // targetExpression.op = op;\n // }\n // }\n }\n\n setRelationalOperator(value: string) {\n const op = value as relationalOp;\n if (this.#expression && isConditionalExpression(this.#expression)) {\n const targetExpression = firstIncompleteExpression(this.#expression);\n if (isRelationalExpression(targetExpression)) {\n targetExpression.op = op;\n } else {\n console.error(`no target expression found (op = ${value})`);\n }\n }\n }\n\n setValue(value: string | number | boolean) {\n const literalExpression = new LiteralExpressionImpl(value);\n if (this.#expression === undefined) {\n this.#expression = literalExpression;\n } else if (isArithmeticExpression(this.#expression)) {\n this.addExpression(literalExpression);\n } else if (isCallExpression(this.#expression)) {\n // TODO this might not be correct if call arguments include nested expression(s)\n this.#expression.arguments.push(literalExpression);\n } else if (isConditionalExpression(this.#expression)) {\n if (expressionIsIncomplete(this.#expression)) {\n const targetExpression = firstIncompleteExpression(this.#expression);\n if (targetExpression && isUnknown(targetExpression)) {\n replaceUnknownExpression(\n this.#expression,\n targetExpression,\n literalExpression\n );\n } else if (targetExpression) {\n addExpression(targetExpression, literalExpression);\n }\n } else {\n console.log(\"what do we do with value, in a complete expression\");\n }\n }\n }\n\n closeBrace() {\n this.#callStack.pop();\n }\n\n get expression() {\n return this.#expression;\n }\n\n toJSON() {\n return this.#expression?.toJSON() as ColumnDefinitionExpression;\n }\n}\n\nexport const walkTree = (tree: Tree, source: string) => {\n const columnExpression = new ColumnExpression();\n const cursor = tree.cursor();\n do {\n const { name, from, to } = cursor;\n switch (name) {\n case \"AndCondition\":\n columnExpression.setCondition(\"and\");\n break;\n\n case \"OrCondition\":\n columnExpression.setCondition(\"or\");\n break;\n\n case \"RelationalExpression\":\n columnExpression.setCondition();\n break;\n\n case \"ArithmeticExpression\":\n columnExpression.addExpression(new ArithmeticExpressionImpl());\n break;\n\n case \"Column\":\n {\n const columnName = source.substring(from, to);\n columnExpression.setColumn(columnName);\n }\n break;\n\n case \"Function\":\n {\n const functionName = source.substring(from, to);\n columnExpression.setFunction(functionName);\n }\n break;\n\n case \"Times\":\n case \"Divide\":\n case \"Plus\":\n case \"Minus\":\n {\n const op = source.substring(from, to);\n columnExpression.setArithmeticOp(op);\n }\n break;\n\n case \"RelationalOperator\":\n {\n const op = source.substring(from, to);\n columnExpression.setRelationalOperator(op);\n }\n break;\n\n case \"False\":\n case \"True\":\n {\n const value = source.substring(from, to);\n columnExpression.setValue(value === \"true\" ? true : false);\n }\n break;\n\n case \"String\":\n columnExpression.setValue(source.substring(from + 1, to - 1));\n break;\n\n case \"Number\":\n columnExpression.setValue(parseFloat(source.substring(from, to)));\n break;\n\n case \"CloseBrace\":\n columnExpression.closeBrace();\n break;\n\n default:\n }\n } while (cursor.next());\n\n return columnExpression.toJSON();\n};\n", "import type { SyntaxNode } from \"@vuu-ui/vuu-codemirror\";\nimport { parser } from \"./generated/column-parser\";\n\nconst strictParser = parser.configure({ strict: true });\n\nconst RelationalOperands = [\"Number\", \"String\"];\n\nexport const ColumnNamedTerms: readonly string[] = [\n ...RelationalOperands,\n \"AndCondition\",\n \"ArithmeticExpression\",\n \"BooleanOperator\",\n \"RelationalOperatorOperator\",\n \"CallExpression\",\n \"CloseBrace\",\n \"Column\",\n \"Comma\",\n \"ConditionalExpression\",\n \"Divide\",\n \"Equal\",\n \"If\",\n \"Minus\",\n \"OpenBrace\",\n \"OrCondition\",\n \"ParenthesizedExpression\",\n \"Plus\",\n \"RelationalExpression\",\n \"RelationalOperator\",\n \"Times\",\n];\n\nexport const isCompleteExpression = (src: string) => {\n try {\n strictParser.parse(src);\n return true;\n } catch (err) {\n return false;\n }\n};\n\nexport const lastNamedChild = (node: SyntaxNode): SyntaxNode | null => {\n let { lastChild } = node;\n while (lastChild && !ColumnNamedTerms.includes(lastChild.name)) {\n lastChild = lastChild.prevSibling;\n console.log(lastChild?.name);\n }\n return lastChild;\n};\n\nexport const isCompleteRelationalExpression = (node?: SyntaxNode) => {\n if (node?.name === \"RelationalExpression\") {\n const { firstChild } = node;\n const lastChild = lastNamedChild(node);\n if (\n firstChild?.name === \"Column\" &&\n typeof lastChild?.name === \"string\" &&\n RelationalOperands.includes(lastChild.name)\n ) {\n return true;\n }\n }\n\n return false;\n};\n", "import {\n HighlightStyle,\n syntaxHighlighting,\n tags,\n} from \"@vuu-ui/vuu-codemirror\";\n\nconst myHighlightStyle = HighlightStyle.define([\n { tag: tags.variableName, color: \"var(--vuuFilterEditor-variableColor)\" },\n { tag: tags.comment, color: \"green\", fontStyle: \"italic\" },\n]);\n\nexport const vuuHighlighting = syntaxHighlighting(myHighlightStyle);\n", "import { EditorView } from \"@vuu-ui/vuu-codemirror\";\n\nexport const vuuTheme = EditorView.theme(\n {\n \"&\": {\n border: \"solid 1px var(--salt-container-primary-borderColor)\",\n color: \"var(--vuuFilterEditor-color)\",\n backgroundColor: \"var(--vuuFilterEditor-background)\",\n },\n \".cm-content\": {\n caretColor: \"var(--vuuFilterEditor-cursorColor)\",\n },\n \"&.cm-focused .cm-cursor\": {\n borderLeftColor: \"var(--vuuFilterEditor-cursorColor)\",\n },\n \"&.cm-focused .cm-selectionBackground, ::selection\": {\n backgroundColor: \"var(--vuuFilterEditor-selectionBackground)\",\n },\n \".cm-selectionBackground, ::selection\": {\n backgroundColor: \"var(--vuuFilterEditor-selectionBackground)\",\n },\n \".cm-scroller\": {\n fontFamily: \"var(--vuuFilterEditor-fontFamily)\",\n },\n \".cm-tooltip\": {\n background: \"var(--vuuFilterEditor-tooltipBackground)\",\n border: \"var(--vuuFilterEditor-tooltipBorder)\",\n boxShadow: \"var(--vuuFilterEditor-tooltipElevation)\",\n \"&.cm-tooltip-autocomplete > ul\": {\n fontFamily: \"var(--vuuFilterEditor-fontFamily)\",\n fontSize: \"var(--vuuFilterEditor-fontSize)\",\n maxHeight: \"240px\",\n },\n \"&.cm-tooltip-autocomplete > ul > li\": {\n height: \"var(--vuuFilterEditor-suggestion-height)\",\n padding: \"0 3px\",\n lineHeight: \"var(--vuuFilterEditor-suggestion-height)\",\n },\n \"&.cm-tooltip-autocomplete li[aria-selected]\": {\n background: \"var(--vuuFilterEditor-suggestion-selectedBackground)\",\n color: \"var(--vuuFilterEditor-suggestion-selectedColor)\",\n },\n \"&.cm-tooltip-autocomplete li .cm-completionDetail\": {\n color: \"var(--vuuFilterEditor-suggestion-detailColor)\",\n },\n },\n },\n { dark: false }\n);\n", "import {\n booleanJoinSuggestions,\n Completion,\n CompletionContext,\n CompletionSource,\n EditorState,\n getNamedParentNode,\n getPreviousNode,\n getValue,\n SyntaxNode,\n syntaxTree,\n} from \"@vuu-ui/vuu-codemirror\";\nimport { MutableRefObject, useCallback } from \"react\";\nimport {\n ColumnNamedTerms,\n isCompleteExpression,\n isCompleteRelationalExpression,\n} from \"./column-language-parser\";\nimport {\n ColumnExpressionOperator,\n ColumnExpressionSuggestionOptions,\n ColumnExpressionSuggestionType,\n IExpressionSuggestionProvider,\n} from \"./useColumnExpressionEditor\";\nimport { lastNamedChild } from \"./column-language-parser\";\n\nexport type ApplyCompletion = (mode?: \"add\" | \"replace\") => void;\n\nexport type Operator = \"\";\n\nconst applyPrefix = (completions: Completion[], prefix?: string) =>\n prefix\n ? completions.map((completion) => ({\n ...completion,\n apply:\n typeof completion.apply === \"function\"\n ? completion.apply\n : `${prefix}${completion.apply ?? completion.label}`,\n }))\n : completions;\n\nconst isOperator = (node?: SyntaxNode): node is SyntaxNode =>\n node === undefined\n ? false\n : [\"Times\", \"Divide\", \"Plus\", \"Minus\"].includes(node.name);\n\nconst getLastChild = (node: SyntaxNode, context: CompletionContext) => {\n let { lastChild: childNode } = node;\n const { pos } = context;\n while (childNode) {\n const isBeforeCursor = childNode.from < pos;\n if (isBeforeCursor && ColumnNamedTerms.includes(childNode.name)) {\n if (childNode.name === \"ParenthesizedExpression\") {\n // extract the parenthesized expression\n const expression = childNode.firstChild?.nextSibling;\n if (expression) {\n childNode = expression;\n }\n }\n return childNode;\n } else {\n childNode = childNode.prevSibling;\n }\n }\n};\nconst getFunctionName = (node: SyntaxNode, state: EditorState) => {\n if (node.name === \"ArgList\") {\n const functionNode = node.prevSibling;\n if (functionNode) {\n return getValue(functionNode, state);\n }\n } else if (node.name === \"OpenBrace\") {\n const maybeFunction = node.parent?.prevSibling;\n if (maybeFunction?.name === \"Function\") {\n return getValue(maybeFunction, state);\n }\n }\n};\n\nconst getRelationalOperator = (node: SyntaxNode, state: EditorState) => {\n if (node.name === \"RelationalExpression\") {\n const lastNode = lastNamedChild(node);\n if (lastNode?.name === \"RelationalOperator\") {\n return getValue(lastNode, state);\n }\n } else {\n const prevNode = node.prevSibling;\n if (prevNode?.name === \"RelationalOperator\") {\n return getValue(prevNode, state) as ColumnExpressionOperator;\n }\n }\n};\n\nconst getColumnName = (\n node: SyntaxNode,\n state: EditorState\n): string | undefined => {\n if (node.name === \"RelationalExpression\") {\n if (node.firstChild?.name === \"Column\") {\n return getValue(node.firstChild, state);\n }\n } else {\n const prevNode = node.prevSibling;\n if (prevNode?.name === \"Column\") {\n return getValue(prevNode, state);\n } else if (prevNode?.name === \"RelationalOperator\") {\n return getColumnName(prevNode, state);\n }\n }\n};\n\nconst makeSuggestions = async (\n context: CompletionContext,\n suggestionProvider: IExpressionSuggestionProvider,\n suggestionType: ColumnExpressionSuggestionType,\n optionalArgs: ColumnExpressionSuggestionOptions = {}\n) => {\n const options = await suggestionProvider.getSuggestions(\n suggestionType,\n optionalArgs\n );\n const { startsWith = \"\" } = optionalArgs;\n return { from: context.pos - startsWith.length, options };\n};\n\nconst handleConditionalExpression = (\n node: SyntaxNode,\n context: CompletionContext,\n suggestionProvider: IExpressionSuggestionProvider,\n maybeComplete?: boolean,\n onSubmit?: () => void\n) => {\n const lastChild = getLastChild(node, context);\n console.log(`conditional expression last child ${lastChild?.name}`);\n switch (lastChild?.name) {\n case \"If\":\n return makeSuggestions(context, suggestionProvider, \"expression\", {\n prefix: \"( \",\n });\n case \"OpenBrace\":\n return makeSuggestions(context, suggestionProvider, \"expression\");\n case \"Condition\":\n return makeSuggestions(context, suggestionProvider, \"expression\", {\n prefix: \", \",\n });\n case \"CloseBrace\":\n if (maybeComplete) {\n const options: Completion[] = [\n {\n apply: () => {\n onSubmit?.();\n },\n label: \"Save Expression\",\n boost: 10,\n },\n ];\n return { from: context.pos, options };\n }\n }\n};\n\nconst promptToSave = (context: CompletionContext, onSubmit: () => void) => {\n const options: Completion[] = [\n {\n apply: () => {\n onSubmit?.();\n },\n label: \"Save Expression\",\n boost: 10,\n },\n ];\n return { from: context.pos, options };\n};\n\nexport const useColumnAutoComplete = (\n suggestionProvider: IExpressionSuggestionProvider,\n onSubmit: MutableRefObject<ApplyCompletion>\n) => {\n const makeSuggestions = useCallback(\n async (\n context: CompletionContext,\n suggestionType: ColumnExpressionSuggestionType,\n optionalArgs: ColumnExpressionSuggestionOptions = {}\n ) => {\n const options = await suggestionProvider.getSuggestions(\n suggestionType,\n optionalArgs\n );\n const { startsWith = \"\" } = optionalArgs;\n return { from: context.pos - startsWith.length, options };\n },\n [suggestionProvider]\n );\n\n return useCallback(\n async (context: CompletionContext) => {\n const { state, pos } = context;\n const word = context.matchBefore(/\\w*/) ?? {\n from: 0,\n to: 0,\n text: undefined,\n };\n\n const tree = syntaxTree(state);\n const nodeBefore = tree.resolveInner(pos, -1);\n const text = state.doc.toString();\n const maybeComplete = isCompleteExpression(text);\n\n console.log({ nodeBeforeName: nodeBefore.name });\n\n switch (nodeBefore.name) {\n case \"If\": {\n console.log(`conditional expression If`);\n return makeSuggestions(context, \"expression\", { prefix: \"( \" });\n }\n case \"Condition\":\n {\n const lastChild = getLastChild(nodeBefore, context);\n if (lastChild?.name === \"Column\") {\n // is this the first term ?\n const prevChild = getPreviousNode(lastChild);\n if (prevChild?.name !== \"RelationalOperator\") {\n return makeSuggestions(context, \"condition-operator\", {\n columnName: getValue(lastChild, state),\n });\n }\n console.log(\n `Condition last child Column, prev child ${prevChild?.name}`\n );\n } else if (lastChild?.name === \"RelationalOperator\") {\n // we need the type of the expression on the other side of the operator\n return makeSuggestions(context, \"expression\");\n }\n console.log(`condition last child ${lastChild?.name}`);\n }\n break;\n case \"ConditionalExpression\":\n return handleConditionalExpression(\n nodeBefore,\n context,\n suggestionProvider\n );\n case \"RelationalExpression\":\n {\n if (isCompleteRelationalExpression(nodeBefore)) {\n return {\n from: context.pos,\n options: booleanJoinSuggestions.concat({\n label: \", <truthy expression>, <falsy expression>\",\n apply: \", \",\n }),\n };\n } else {\n const operator = getRelationalOperator(nodeBefore, state);\n const columnName = getColumnName(nodeBefore, state);\n if (!operator) {\n const options = await suggestionProvider.getSuggestions(\n \"condition-operator\",\n {\n columnName,\n }\n );\n return { from: context.pos, options };\n } else {\n return makeSuggestions(context, \"expression\");\n }\n }\n }\n break;\n\n case \"RelationalOperator\":\n // we need the type of the expression on the other side of the operator\n return makeSuggestions(context, \"expression\");\n\n case \"String\":\n {\n // we only encounter a string as the right hand operand of a conditional expression\n const operator = getRelationalOperator(\n nodeBefore,\n state\n ) as ColumnExpressionOperator;\n const columnName = getColumnName(nodeBefore, state);\n // are we inside the string or immediately after it\n const { from, to } = nodeBefore;\n if (to - from === 2 && context.pos === from + 1) {\n // We are in an empty string, i.e between two quotes\n if (columnName && operator) {\n return makeSuggestions(context, \"columnValue\", {\n columnName,\n operator,\n startsWith: word.text,\n });\n }\n } else if (to - from > 2 && context.pos === to) {\n // NOte we couls also offer AND/OR to extend the condition\n return makeSuggestions(context, \"expression\", {\n prefix: \", \",\n });\n }\n console.log(\n `we have a string, column is ${columnName} ${from} ${to}`\n );\n }\n break;\n\n case \"ArithmeticExpression\":\n {\n const lastChild = getLastChild(nodeBefore, context);\n if (lastChild?.name === \"Column\") {\n return makeSuggestions(context, \"expression\");\n } else if (isOperator(lastChild)) {\n const operator = lastChild.name as ColumnExpressionOperator;\n return makeSuggestions(context, \"column\", { operator });\n }\n }\n\n break;\n case \"OpenBrace\":\n {\n // Might be a function expression, might be parenthesized\n const functionName = getFunctionName(nodeBefore, state);\n // If not function, what came before - if it's an operator\n // we restrict to numerics\n return makeSuggestions(context, \"expression\", { functionName });\n }\n break;\n case \"ArgList\": {\n const functionName = getFunctionName(nodeBefore, state);\n const lastArgument = getLastChild(nodeBefore, context);\n const prefix = lastArgument?.name === \"OpenBrace\" ? undefined : \",\";\n let options = await suggestionProvider.getSuggestions(\"expression\", {\n functionName,\n });\n options = prefix ? applyPrefix(options, \", \") : options;\n // TODO per function check for number of arguments expected\n if (\n lastArgument?.name !== \"OpenBrace\" &&\n lastArgument?.name !== \"Comma\"\n ) {\n options = [\n {\n apply: \") \",\n boost: 10,\n label: \"Done - no more arguments\",\n } as Completion,\n ].concat(options);\n }\n return { from: context.pos, options };\n }\n case \"Equal\":\n if (text.trim() === \"=\") {\n return makeSuggestions(context, \"expression\");\n }\n break;\n case \"ParenthesizedExpression\":\n case \"ColumnDefinitionExpression\":\n if (context.pos === 0) {\n return makeSuggestions(context, \"expression\");\n } else {\n const lastChild = getLastChild(nodeBefore, context);\n if (lastChild?.name === \"Column\") {\n if (maybeComplete) {\n // We come in here is the columns IS complete, too (ie has space after)\n const options: Completion[] = [\n {\n apply: () => {\n onSubmit.current();\n },\n label: \"Save Expression\",\n boost: 10,\n },\n ];\n const columnName = getValue(lastChild, state);\n const columnOptions: Completion[] =\n await suggestionProvider.getSuggestions(\"operator\", {\n columnName,\n });\n\n return {\n from: context.pos,\n options: options.concat(columnOptions),\n };\n }\n } else if (lastChild?.name === \"CallExpression\") {\n if (maybeComplete) {\n const options = [\n {\n apply: () => {\n onSubmit.current();\n },\n label: \"Save Expression\",\n boost: 10,\n },\n ];\n return {\n from: context.pos,\n options,\n };\n }\n } else if (lastChild?.name === \"ArithmeticExpression\") {\n if (maybeComplete) {\n let options: Completion[] = [\n {\n apply: () => {\n onSubmit.current();\n },\n label: \"Save Expression\",\n boost: 10,\n },\n ];\n\n const lastExpressionChild = getLastChild(lastChild, context);\n if (lastExpressionChild?.name === \"Column\") {\n const columnName = getValue(lastExpressionChild, state);\n // TODO need to exclude columns already included in expression\n\n const suggestions = await suggestionProvider.getSuggestions(\n \"operator\",\n { columnName }\n );\n options = options.concat(suggestions);\n }\n\n return {\n from: context.pos,\n options,\n };\n }\n } else if (lastChild?.name === \"ConditionalExpression\") {\n return handleConditionalExpression(\n lastChild,\n context,\n suggestionProvider,\n maybeComplete,\n onSubmit.current\n );\n }\n break;\n }\n case \"Column\":\n {\n const isPartialMatch = await suggestionProvider.isPartialMatch(\n \"expression\",\n undefined,\n word.text\n );\n\n if (isPartialMatch) {\n return makeSuggestions(context, \"expression\", {\n startsWith: word.text,\n });\n }\n }\n break;\n case \"Comma\":\n {\n const parentNode = getNamedParentNode(nodeBefore);\n if (parentNode?.name === \"ConditionalExpression\") {\n return makeSuggestions(context, \"expression\");\n }\n }\n break;\n\n case \"CloseBrace\":\n {\n const parentNode = getNamedParentNode(nodeBefore);\n if (parentNode?.name === \"ConditionalExpression\") {\n return handleConditionalExpression(\n parentNode,\n context,\n suggestionProvider,\n maybeComplete,\n onSubmit.current\n );\n } else if (parentNode?.name === \"ArgList\") {\n if (maybeComplete) {\n return promptToSave(context, onSubmit.current);\n }\n }\n console.log(\n `does closebrace denote an ARgList or a parenthetised expression ? ${parentNode}`\n );\n }\n break;\n\n default: {\n if (nodeBefore?.prevSibling?.name === \"FilterClause\") {\n console.log(\"looks like we ight be a or|and operator\");\n }\n }\n }\n },\n [makeSuggestions, onSubmit, suggestionProvider]\n ) as CompletionSource;\n};\n", "import { HTMLAttributes } from \"react\";\nimport {\n ExpressionSuggestionConsumer,\n useColumnExpressionEditor,\n} from \"./useColumnExpressionEditor\";\n\nimport \"./ColumnExpressionInput.css\";\nimport { ColumnDefinitionExpression } from \"./column-language-parser\";\n\nconst classBase = \"vuuColumnExpressionInput\";\n\nexport interface ColumnExpressionInputProps\n extends ExpressionSuggestionConsumer,\n Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n onChange?: (\n source: string,\n expression: ColumnDefinitionExpression | undefined\n ) => void;\n onSubmitExpression?: (\n source: string,\n expression: ColumnDefinitionExpression | undefined\n ) => void;\n}\n\nexport const ColumnExpressionInput = ({\n onChange,\n onSubmitExpression,\n suggestionProvider,\n}: ColumnExpressionInputProps) => {\n const { editorRef } = useColumnExpressionEditor({\n onChange,\n onSubmitExpression,\n suggestionProvider,\n });\n\n return <div className={`${classBase}`} ref={editorRef} />;\n};\n", "import {\n AnnotationType,\n Completion,\n EditorView,\n getRelationalOperators,\n numericOperators,\n stringOperators,\n toSuggestions,\n} from \"@vuu-ui/vuu-codemirror\";\nimport {\n getTypeaheadParams,\n useTypeaheadSuggestions,\n} from \"@vuu-ui/vuu-data-react\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n ColumnExpressionOperator,\n ColumnExpressionSuggestionType,\n IExpressionSuggestionProvider,\n} from \"@vuu-ui/vuu-table-extras\";\nimport { isNumericColumn, isTextColumn } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useRef } from \"react\";\nimport {\n ColumnFunctionDescriptor,\n columnFunctionDescriptors,\n} from \"./column-function-descriptors\";\nimport { functionDocInfo } from \"./functionDocInfo\";\n\nconst NO_OPERATORS = [] as Completion[];\n\nconst withApplySpace = (suggestions: Completion[]): Completion[] =>\n suggestions.map((suggestion) => ({\n ...suggestion,\n apply: (suggestion.apply ?? suggestion.label) + \" \",\n }));\n\ntype ColumnOptions = {\n functionName?: string;\n operator?: ColumnExpressionOperator;\n prefix?: string;\n};\n\nconst getValidColumns = (\n columns: ColumnDescriptor[],\n { functionName, operator }: ColumnOptions\n) => {\n if (operator) {\n return columns.filter(isNumericColumn);\n } else if (functionName) {\n const fn = columnFunctionDescriptors.find((f) => f.name === functionName);\n if (fn) {\n switch (fn.accepts) {\n case \"string\":\n return columns.filter(isTextColumn);\n case \"number\":\n return columns.filter(isNumericColumn);\n default:\n return columns;\n }\n }\n }\n return columns;\n};\n\nconst getColumns = (columns: ColumnDescriptor[], options: ColumnOptions) => {\n const validColumns = getValidColumns(columns, options);\n return validColumns.map((column) => {\n const label = column.label ?? column.name;\n return {\n apply: options.prefix ? `${options.prefix}${label}` : label,\n label,\n boost: 5,\n type: \"column\",\n expressionType: column.serverDataType,\n };\n });\n};\n\n// prettier-ignore\nconst arithmeticOperators = [\n { apply: \"* \", boost: 2, label: \"*\", type: \"operator\" },\n { apply: \"/ \", boost: 2, label: \"/\", type: \"operator\" },\n { apply: \"+ \", boost: 2, label: \"+\", type: \"operator\" },\n { apply: \"- \", boost: 2, label: \"-\", type: \"operator\" },\n];\n\nconst getOperators = (column?: ColumnDescriptor) => {\n if (column === undefined || isNumericColumn(column)) {\n return arithmeticOperators;\n } else {\n return NO_OPERATORS;\n }\n};\n\nconst getConditionOperators = (column: ColumnDescriptor) => {\n switch (column.serverDataType) {\n case \"string\":\n case \"char\":\n return withApplySpace(stringOperators /*, startsWith*/);\n case \"int\":\n case \"long\":\n case \"double\":\n return withApplySpace(numericOperators);\n }\n};\n\nconst toFunctionCompletion = (\n functionDescriptor: ColumnFunctionDescriptor\n) => ({\n apply: `${functionDescriptor.name}( `,\n boost: 2,\n expressionType: functionDescriptor.type,\n info: () => functionDocInfo(functionDescriptor),\n label: functionDescriptor.name,\n type: \"function\",\n});\n\nconst getAcceptedTypes = (fn?: ColumnFunctionDescriptor) => {\n if (fn) {\n if (typeof fn.accepts === \"string\") {\n return fn.accepts;\n } else if (Array.isArray(fn.accepts)) {\n if (fn.accepts.every((s) => s === \"string\")) {\n return \"string\";\n } else {\n return \"any\";\n }\n }\n }\n return \"any\";\n};\n\nconst functions: Completion[] =\n columnFunctionDescriptors.map(toFunctionCompletion);\n\nconst getFunctions = ({ functionName }: ColumnOptions) => {\n if (functionName) {\n const fn = columnFunctionDescriptors.find((f) => f.name === functionName);\n const acceptedTypes = getAcceptedTypes(fn);\n if (fn) {\n switch (acceptedTypes) {\n case \"string\":\n return columnFunctionDescriptors\n .filter((f) => f.type === \"string\" || f.type === \"variable\")\n .map(toFunctionCompletion);\n case \"number\":\n return columnFunctionDescriptors\n .filter((f) => f.type === \"number\" || f.type === \"variable\")\n .map(toFunctionCompletion);\n default:\n }\n }\n }\n return functions;\n};\n\nexport interface SuggestionProviderHookProps {\n columns: ColumnDescriptor[];\n table: VuuTable;\n}\n\nconst NONE = {};\n\nexport const useColumnExpressionSuggestionProvider = ({\n columns,\n table,\n}: SuggestionProviderHookProps): IExpressionSuggestionProvider => {\n const findColumn = useCallback(\n (name?: string) =>\n name ? columns.find((col) => col.name === name) : undefined,\n [columns]\n );\n\n const latestSuggestionsRef = useRef<Completion[]>();\n const getTypeaheadSuggestions = useTypeaheadSuggestions();\n\n const getSuggestions: IExpressionSuggestionProvider[\"getSuggestions\"] =\n useCallback(\n async (suggestionType, options = NONE): Promise<Completion[]> => {\n const { columnName, functionName, operator, prefix } = options;\n\n switch (suggestionType) {\n case \"expression\": {\n const suggestions = await withApplySpace(\n getColumns(columns, { functionName, prefix })\n ).concat(getFunctions(options));\n return (latestSuggestionsRef.current = suggestions);\n }\n case \"column\": {\n const suggestions = await getColumns(columns, options);\n return (latestSuggestionsRef.current = withApplySpace(suggestions));\n }\n case \"operator\": {\n const suggestions = await getOperators(findColumn(columnName));\n return (latestSuggestionsRef.current = withApplySpace(suggestions));\n }\n case \"relational-operator\": {\n const suggestions = await getRelationalOperators(\n findColumn(columnName)\n );\n return (latestSuggestionsRef.current = withApplySpace(suggestions));\n }\n case \"condition-operator\":\n {\n const column = findColumn(columnName);\n if (column) {\n const suggestions = await getConditionOperators(column);\n if (suggestions) {\n return (latestSuggestionsRef.current =\n withApplySpace(suggestions));\n }\n }\n }\n break;\n case \"columnValue\":\n if (columnName && operator) {\n // const column = findColumn(columnName);\n const params = getTypeaheadParams(\n table,\n columnName /*, startsWith*/\n );\n const suggestions = await getTypeaheadSuggestions(params);\n latestSuggestionsRef.current = toSuggestions(suggestions, {\n suffix: \"\",\n });\n\n latestSuggestionsRef.current.forEach((suggestion) => {\n suggestion.apply = (\n view: EditorView,\n completion: Completion,\n from: number\n ) => {\n const annotation = new AnnotationType<Completion>();\n const cursorPos = from + completion.label.length + 1;\n view.dispatch({\n changes: { from, insert: completion.label },\n selection: { anchor: cursorPos, head: cursorPos },\n annotations: annotation.of(completion),\n });\n };\n });\n return latestSuggestionsRef.current;\n }\n break;\n }\n\n return [];\n },\n [columns, findColumn, getTypeaheadSuggestions, table]\n );\n\n const isPartialMatch = useCallback(\n async (\n valueType: ColumnExpressionSuggestionType,\n columnName?: string,\n pattern?: string\n ) => {\n const { current: latestSuggestions } = latestSuggestionsRef;\n let maybe = false;\n const suggestions =\n latestSuggestions || (await getSuggestions(valueType, { columnName }));\n if (pattern && suggestions) {\n for (const option of suggestions) {\n if (option.label === pattern) {\n return false;\n } else if (option.label.startsWith(pattern)) {\n maybe = true;\n }\n }\n }\n return maybe;\n },\n [getSuggestions]\n );\n\n return {\n getSuggestions,\n isPartialMatch,\n };\n};\n", "export type ColumnFunctionDescriptor = {\n accepts: \"string\" | \"number\" | \"any\" | Array<\"string\" | \"number\">;\n description: string;\n example: {\n expression: string;\n result: string;\n };\n name: string;\n params: {\n count?: number;\n description: string;\n };\n type: \"string\" | \"number\" | \"boolean\" | \"variable\";\n};\n\nexport const columnFunctionDescriptors: ColumnFunctionDescriptor[] = [\n /**\n * concatenate()\n */\n {\n accepts: \"string\",\n description:\n \"Returns multiple string values as a single joined string. Arguments may be string literal values, string columns or other string expressions. Non string arguments may also be included, these will be converted to strings.\",\n example: {\n expression: 'concatenate(\"example\", \"-test\")',\n result: '\"example-test\"',\n },\n name: \"concatenate\",\n params: {\n description: \"( string, string, [ string* ] )\",\n },\n type: \"string\",\n },\n /**\n * contains()\n */\n {\n accepts: [\"string\", \"string\"],\n description:\n \"Tests a string value to determine whether it contains a given substring. Accepts two arguments: source text and target substring. Returns true if <source text> contains one or more occurrences of <target subscring>\",\n example: {\n expression: 'contains(\"Royal Bank of Scotland\", \"bank\")',\n result: \"true\",\n },\n name: \"contains\",\n params: {\n description: \"( string )\",\n },\n type: \"boolean\",\n },\n\n /**\n * left()\n */\n {\n accepts: [\"string\", \"number\"],\n description:\n \"Returns the leftmost <number> characters from <string>. First argument may be a string literal, string column or other string expression.\",\n example: {\n expression: 'left(\"USD Benchmark Report\", 3)',\n result: '\"USD\"',\n },\n name: \"left\",\n params: {\n count: 2,\n description: \"( string, number )\",\n },\n type: \"string\",\n },\n /**\n * len()\n */\n {\n accepts: \"string\",\n description:\n \"Returns the number of characters in <string>. Argument may be a string literal, string column or other string expression.\",\n example: {\n expression: 'len(\"example\")',\n result: \"7\",\n },\n name: \"len\",\n params: {\n description: \"(string)\",\n },\n type: \"number\",\n },\n /**\n * lower()\n */\n {\n accepts: \"string\",\n description:\n \"Convert a string value to lowercase. Argument may be a string column or other string expression.\",\n example: {\n expression: 'lower(\"examPLE\")',\n result: '\"example\"',\n },\n name: \"lower\",\n params: {\n description: \"( string )\",\n },\n type: \"string\",\n },\n /**\n * upper()\n */\n {\n accepts: \"string\",\n description:\n \"Convert a string value to uppercase. Argument may be a string column or other string expression.\",\n example: {\n expression: 'upper(\"example\")',\n result: '\"EXAMPLE\"',\n },\n name: \"upper\",\n params: {\n description: \"( string )\",\n },\n type: \"string\",\n },\n /**\n * right()\n */\n {\n accepts: [\"string\", \"number\"],\n description:\n \"Returns the rightmost <number> characters from <string>. First argument may be a string literal, string column or other string expression.\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"right\",\n params: {\n description: \"( string )\",\n },\n type: \"string\",\n },\n /**\n * replace()\n */\n {\n accepts: [\"string\", \"string\", \"string\"],\n description:\n \"Replace characters within a string. Accepts three arguments: source text, text to replace and replacement text. Returns a copy of <source text> with any occurrences of <text to replace> replaced by <replacement text>\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"replace\",\n params: {\n description: \"( string )\",\n },\n type: \"string\",\n },\n /**\n * text()\n */\n {\n accepts: \"number\",\n description: \"Converts a number to a string.\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"text\",\n params: {\n description: \"( string )\",\n },\n type: \"string\",\n },\n /**\n * starts()\n */\n {\n accepts: \"string\",\n description:\n \"Tests a string value to determine whether it starts with a given substring. Accepts two arguments: source text and target substring. Returns true if <source text> starts with <target subscring>.\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"starts\",\n params: {\n description: \"( string )\",\n },\n type: \"boolean\",\n },\n /**\n * starts()\n */\n {\n accepts: \"string\",\n description:\n \"Tests a string value to determine whether it ends with a given substring. Accepts two arguments: source text and target substring. Returns true if <source text> ends with <target subscring>.\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"ends\",\n params: {\n description: \"( string )\",\n },\n type: \"boolean\",\n },\n {\n accepts: \"number\",\n description: \"blah\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"min\",\n params: {\n description: \"( string )\",\n },\n type: \"number\",\n },\n {\n accepts: \"number\",\n description: \"blah\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"max\",\n params: {\n description: \"( string )\",\n },\n type: \"number\",\n },\n {\n accepts: \"number\",\n description: \"blah\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"sum\",\n params: {\n description: \"( string )\",\n },\n type: \"number\",\n },\n {\n accepts: \"number\",\n description: \"blah\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"round\",\n params: {\n description: \"( string )\",\n },\n type: \"number\",\n },\n {\n accepts: \"any\",\n description: \"blah\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"or\",\n params: {\n description: \"( string )\",\n },\n type: \"boolean\",\n },\n {\n accepts: \"any\",\n description: \"blah\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"and\",\n params: {\n description: \"( string )\",\n },\n type: \"boolean\",\n },\n {\n accepts: \"any\",\n description:\n \"Return one of two possible result values, depending on the evaluation of a filter expression. If <filterExpression> resolves to true, result is <expression1>, otherwise <expression2>. \",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"if\",\n params: {\n description: \"( filterExpression, expression1, expression 2)\",\n },\n type: \"variable\",\n },\n];\n", "import { createEl } from \"@vuu-ui/vuu-utils\";\nimport { ColumnFunctionDescriptor } from \"./column-function-descriptors\";\n\nexport const functionDocInfo = ({\n name,\n description,\n example,\n params,\n type,\n}: ColumnFunctionDescriptor) => {\n const rootElement = createEl(\"div\", \"vuuFunctionDoc\");\n const headingElement = createEl(\"div\", \"function-heading\");\n\n const nameElement = createEl(\"span\", \"function-name\", name);\n const paramElement = createEl(\"span\", \"param-list\", params.description);\n const typeElement = createEl(\"span\", \"function-type\", type);\n\n headingElement.appendChild(nameElement);\n headingElement.appendChild(paramElement);\n headingElement.appendChild(typeElement);\n\n const child2 = createEl(\"p\", undefined, description);\n\n rootElement.appendChild(headingElement);\n rootElement.appendChild(child2);\n\n if (example) {\n const exampleElement = createEl(\"div\", \"example-container\", \"Example:\");\n const expressionElement = createEl(\n \"div\",\n \"example-expression\",\n example.expression\n );\n const resultElement = createEl(\"div\", \"example-result\", example.result);\n\n exampleElement.appendChild(expressionElement);\n exampleElement.appendChild(resultElement);\n\n rootElement.appendChild(exampleElement);\n }\n\n return rootElement;\n};\n", "import { ColumnDescriptor, GridConfig } from \"@vuu-ui/vuu-datagrid-types\";\nimport { Button, Panel } from \"@salt-ds/core\";\nimport cx from \"classnames\";\nimport {\n HTMLAttributes,\n MouseEvent,\n ReactElement,\n useCallback,\n useState,\n} from \"react\";\nimport { ColumnSettingsPanel } from \"../column-settings-panel\";\nimport { GridSettingsPanel } from \"./GridSettingsPanel\";\nimport { useGridSettings } from \"./useGridSettings\";\n\nimport { Stack, StackProps } from \"@vuu-ui/vuu-layout\";\nimport { CalculatedColumnPanel } from \"../calculated-column-panel\";\n\nimport \"./DatagridSettingsPanel.css\";\n\nexport interface DatagridSettingsPanelProps\n extends HTMLAttributes<HTMLDivElement> {\n availableColumns: ColumnDescriptor[];\n gridConfig: Omit<GridConfig, \"headings\">;\n onCancel?: () => void;\n onConfigChange?: (\n config: Omit<GridConfig, \"headings\">,\n closePanel?: boolean\n ) => void;\n}\n\nconst classBase = \"vuuDatagridSettingsPanel\";\n\nconst getTabLabel = () => undefined;\nconst icons = [\n \"table-settings\",\n \"column-chooser\",\n \"column-settings\",\n \"define-column\",\n];\nconst getTabIcon = (component: ReactElement, tabIndex: number) =>\n icons[tabIndex];\n\n// component.props?.title ?? `Tab ${tabIndex + 1}`;\n\nexport const DatagridSettingsPanel = ({\n availableColumns,\n className,\n gridConfig,\n onCancel,\n onConfigChange,\n ...props\n}: DatagridSettingsPanelProps) => {\n console.log(`DatagridSettingsPanel render`);\n\n const [selectedTabIndex, setSelectedTabIndex] = useState(0);\n\n const { gridSettings, dispatchColumnAction } = useGridSettings(gridConfig);\n\n const [selectedColumnName, setSelectedColumnName] = useState<string | null>(\n null\n );\n const handleColumnSelected = useCallback(\n (selected: ColumnDescriptor | null) => {\n setSelectedColumnName(selected ? selected.name : null);\n },\n []\n );\n\n const handleApply = useCallback(\n (evt: MouseEvent, closePanel = false) => {\n console.log(`1) DataGridSettingsPanel fire onConfigChange`);\n onConfigChange?.(gridSettings, closePanel);\n },\n [gridSettings, onConfigChange]\n );\n\n const handleTabSelectionChanged = useCallback((selectedTabIndex: number) => {\n setSelectedTabIndex(selectedTabIndex);\n }, []);\n\n const handleSave = useCallback(\n (evt: MouseEvent) => handleApply(evt, true),\n [handleApply]\n );\n\n const selectedColumn =\n selectedColumnName === null\n ? null\n : gridSettings.columns.find((col) => col.name === selectedColumnName) ??\n null;\n\n const tabstripProps: StackProps[\"TabstripProps\"] = {\n activeTabIndex: selectedTabIndex,\n allowRenameTab: false,\n orientation: \"vertical\",\n };\n\n const handleAddCalculatedColumn = useCallback(\n () => setSelectedTabIndex(3),\n []\n );\n\n const panelShift = selectedTabIndex === 2 ? \"right\" : undefined;\n\n return (\n <div {...props} className={cx(classBase, className)}>\n <Stack\n TabstripProps={tabstripProps}\n className={`${classBase}-stack`}\n getTabIcon={getTabIcon}\n getTabLabel={getTabLabel}\n active={selectedTabIndex === 2 ? 1 : selectedTabIndex}\n onTabSelectionChanged={handleTabSelectionChanged}\n >\n <GridSettingsPanel\n config={gridSettings}\n dispatchColumnAction={dispatchColumnAction}\n />\n\n <div className={`${classBase}-columnPanels`} data-align={panelShift}>\n {selectedColumn === null ? (\n <Panel className=\"vuuColumnSettingsPanel\">Select a column</Panel>\n ) : (\n <ColumnSettingsPanel\n column={selectedColumn}\n dispatchColumnAction={dispatchColumnAction}\n style={{ background: \"white\", flex: \"1 0 150px\" }}\n />\n )}\n </div>\n <div title=\"Column Settings\">Column Settings</div>\n <CalculatedColumnPanel\n columns={gridSettings.columns}\n dispatchColumnAction={dispatchColumnAction}\n table={{ module: \"SIMUL\", table: \"instruments\" }}\n />\n </Stack>\n <div className={`${classBase}-buttonBar`}>\n <Button onClick={onCancel}>Cancel</Button>\n <Button onClick={handleApply}>Apply</Button>\n <Button onClick={handleSave}>Save</Button>\n </div>\n </div>\n );\n};\n", "import { ColumnDescriptor, PinLocation } from \"@vuu-ui/vuu-datagrid-types\";\nimport { Stack } from \"@vuu-ui/vuu-layout\";\nimport { StepperInput } from \"@salt-ds/lab\";\nimport {\n Checkbox,\n FormField,\n FormFieldLabel,\n Input,\n Panel,\n RadioButton,\n RadioButtonGroup,\n Text,\n} from \"@salt-ds/core\";\nimport cx from \"classnames\";\nimport {\n ChangeEvent,\n Dispatch,\n HTMLAttributes,\n useCallback,\n useState,\n} from \"react\";\nimport { ColumnTypePanel } from \"../column-type-panel\";\n\nimport { ColumnAction } from \"../settings-panel/useGridSettings\";\nimport \"./ColumnSettingsPanel.css\";\n\nconst classBase = \"vuuColumnSettingsPanel\";\n\nconst tabstripProps = {\n className: \"salt-density-high\",\n};\n\nexport interface ColumnSettingsPanelProps\n extends HTMLAttributes<HTMLDivElement> {\n column: ColumnDescriptor;\n dispatchColumnAction: Dispatch<ColumnAction>;\n}\nexport const ColumnSettingsPanel = ({\n column,\n dispatchColumnAction,\n style: styleProp,\n ...props\n}: ColumnSettingsPanelProps) => {\n const [activeTab, setActiveTab] = useState(0);\n\n const dispatchUpdate = useCallback(\n (\n values: Partial<\n Pick<ColumnDescriptor, \"align\" | \"hidden\" | \"label\" | \"pin\" | \"width\">\n >\n ) =>\n dispatchColumnAction({\n type: \"updateColumnProp\",\n column,\n ...values,\n }),\n [column, dispatchColumnAction]\n );\n\n const handleChangeAlign = useCallback(\n (evt: ChangeEvent<HTMLInputElement>) =>\n dispatchUpdate({ align: evt.target.value as \"left\" | \"right\" }),\n [dispatchUpdate]\n );\n\n const handleChangePin = useCallback(\n (evt: ChangeEvent<HTMLInputElement>) =>\n dispatchUpdate({ pin: evt.target.value as PinLocation | undefined }),\n [dispatchUpdate]\n );\n\n const handleChangeHidden = useCallback(\n (evt: ChangeEvent<HTMLInputElement>) =>\n dispatchUpdate({ hidden: evt.target.checked }),\n [dispatchUpdate]\n );\n\n const handleChangeLabel = useCallback(\n (evt: ChangeEvent<HTMLInputElement>) =>\n dispatchUpdate({ label: evt.target.value }),\n [dispatchUpdate]\n );\n\n const handleChangeWidth = useCallback(\n (value: string | number) =>\n dispatchUpdate({ width: parseInt(value.toString(), 10) }),\n [dispatchUpdate]\n );\n\n return (\n <div\n className={classBase}\n {...props}\n style={{\n ...styleProp,\n }}\n >\n <Text as=\"h4\">Column Settings</Text>\n <Stack\n active={activeTab}\n className={cx(`${classBase}-columnTabs`)}\n onTabSelectionChanged={setActiveTab}\n TabstripProps={tabstripProps}\n >\n <Panel title=\"Column\">\n <FormField labelPlacement=\"left\">\n <FormFieldLabel>Hidden</FormFieldLabel>\n <Checkbox\n checked={column.hidden === true}\n onChange={handleChangeHidden}\n />\n </FormField>\n <FormField labelPlacement=\"left\">\n <FormFieldLabel>Label</FormFieldLabel>\n <Input\n value={column.label ?? column.name}\n onChange={handleChangeLabel}\n />\n </FormField>\n <FormField labelPlacement=\"left\">\n <FormFieldLabel>Width</FormFieldLabel>\n <StepperInput\n value={column.width ?? 100}\n onChange={handleChangeWidth}\n />\n </FormField>\n <FormField labelPlacement=\"left\">\n <FormFieldLabel>ALign</FormFieldLabel>\n <RadioButtonGroup\n aria-label=\"Column Align\"\n value={column.align ?? \"left\"}\n onChange={handleChangeAlign}\n >\n <RadioButton label=\"Left\" value=\"left\" />\n <RadioButton label=\"Right\" value=\"right\" />\n </RadioButtonGroup>\n </FormField>\n <FormField labelPlacement=\"left\">\n <FormFieldLabel>Pin Column</FormFieldLabel>\n <RadioButtonGroup\n aria-label=\"Pin Column\"\n value={column.pin ?? \"\"}\n onChange={handleChangePin}\n >\n <RadioButton label=\"Do not pin\" value={\"\"} />\n <RadioButton label=\"Left\" value=\"left\" />\n <RadioButton label=\"Right\" value=\"right\" />\n </RadioButtonGroup>\n </FormField>\n </Panel>\n <ColumnTypePanel\n column={column}\n dispatchColumnAction={dispatchColumnAction}\n title=\"Data Cell\"\n />\n <Panel title=\"Vuu\" variant=\"secondary\">\n <FormField labelPlacement=\"top\" readOnly>\n <FormFieldLabel>Name</FormFieldLabel>\n <Input value={column.name} />\n </FormField>\n <FormField labelPlacement=\"top\" readOnly>\n <FormFieldLabel>Vuu Type</FormFieldLabel>\n <Input value={column.serverDataType} />\n </FormField>\n </Panel>\n </Stack>\n </div>\n );\n};\n", "import { ColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { getRegisteredCellRenderers } from \"@vuu-ui/vuu-utils\";\nimport { Dropdown } from \"@salt-ds/lab\";\nimport { Panel, PanelProps } from \"@salt-ds/core\";\nimport cx from \"classnames\";\nimport { Dispatch, useMemo } from \"react\";\nimport { ColumnAction } from \"../settings-panel/useGridSettings\";\nimport { NumericColumnPanel } from \"./NumericColumnPanel\";\nimport { StringColumnPanel } from \"./StringColumnPanel\";\n\nimport \"./ColumnTypePanel.css\";\n\nconst classBase = \"vuuColumnTypePanel\";\n\nexport interface ColumnTypePanelProps extends PanelProps {\n column: ColumnDescriptor;\n dispatchColumnAction: Dispatch<ColumnAction>;\n}\n\nconst integerCellRenderers = [\"Default Renderer (int, long)\"];\nconst doubleCellRenderers = [\"Default Renderer (double)\"];\nconst stringCellRenderers = [\"Default Renderer (string)\"];\n\nconst getAvailableCellRenderers = (column: ColumnDescriptor) => {\n const customCellRenderers = getRegisteredCellRenderers(column.serverDataType);\n const customRendererNames = customCellRenderers.map((r) => r.name);\n console.log({ customRendererNames });\n\n switch (column.serverDataType) {\n case \"char\":\n case \"string\":\n return stringCellRenderers;\n case \"int\":\n case \"long\":\n return integerCellRenderers;\n case \"double\":\n return doubleCellRenderers.concat(customRendererNames);\n default:\n return stringCellRenderers;\n }\n};\n\nexport const ColumnTypePanel = ({\n className,\n column,\n dispatchColumnAction,\n ...props\n}: ColumnTypePanelProps) => {\n const content = useMemo(() => {\n switch (column.serverDataType) {\n case \"double\":\n case \"int\":\n case \"long\":\n return (\n <NumericColumnPanel\n column={column}\n dispatchColumnAction={dispatchColumnAction}\n />\n );\n default:\n return (\n <StringColumnPanel\n column={column}\n dispatchColumnAction={dispatchColumnAction}\n />\n );\n }\n }, [column, dispatchColumnAction]);\n\n const { serverDataType = \"string\" } = column;\n const availableRenderers = getAvailableCellRenderers(column);\n\n return (\n <>\n <Dropdown\n className={cx(`${classBase}-renderer`)}\n fullWidth\n selected={availableRenderers[0]}\n source={availableRenderers}\n />\n <Panel\n {...props}\n className={cx(classBase, className, `${classBase}-${serverDataType}`)}\n >\n {content}\n </Panel>\n </>\n );\n};\n", "import { ColumnType } from \"@vuu-ui/vuu-datagrid-types\";\nimport { StepperInput, Switch } from \"@salt-ds/lab\";\nimport { FormField, FormFieldLabel, Text } from \"@salt-ds/core\";\nimport { ChangeEventHandler, useCallback } from \"react\";\nimport { ColumnTypePanelProps } from \"./ColumnTypePanel\";\n\nimport \"./ColumnTypePanel.css\";\n\ntype NumericColumnConfig = {\n alignOnDecimals: boolean;\n decimals: number;\n zeroPad: boolean;\n};\n\nconst defaultValues = {\n alignOnDecimals: false,\n decimals: 4,\n zeroPad: false,\n} as NumericColumnConfig;\n\nconst getColumnValues = (\n columnType?: ColumnType,\n gridDefaultValues?: Partial<NumericColumnConfig>\n) => {\n const columnValue =\n typeof columnType === \"object\" && columnType.formatting\n ? columnType.formatting\n : {};\n\n const properties = [\"alignOnDecimals\", \"decimals\", \"zeroPad\"] as Array<\n keyof NumericColumnConfig\n >;\n return properties.reduce<NumericColumnConfig>((configValues, property) => {\n if (columnValue[property] !== undefined) {\n return {\n ...configValues,\n [property]: columnValue[property],\n };\n } else if (gridDefaultValues?.[property] !== undefined) {\n return {\n ...configValues,\n [property]: gridDefaultValues[property],\n };\n }\n return configValues;\n }, defaultValues);\n};\n\nexport const NumericColumnPanel = ({\n column,\n dispatchColumnAction,\n}: ColumnTypePanelProps) => {\n const { decimals, alignOnDecimals, zeroPad } = getColumnValues(column?.type);\n\n const dispatchUpdate = useCallback(\n (values: Partial<NumericColumnConfig>) =>\n dispatchColumnAction({\n type: \"updateColumnTypeFormatting\",\n column,\n ...values,\n }),\n [column, dispatchColumnAction]\n );\n\n const handleChangeDecimals = useCallback(\n (value: string | number) =>\n dispatchUpdate({ decimals: parseInt(value.toString(), 10) }),\n [dispatchUpdate]\n );\n const handleChangeAlignOnDecimals = useCallback<\n ChangeEventHandler<HTMLInputElement>\n >(\n (evt) => dispatchUpdate({ alignOnDecimals: Boolean(evt.target.value) }),\n [dispatchUpdate]\n );\n const handleChangeZeroPad = useCallback<ChangeEventHandler<HTMLInputElement>>(\n (evt) => dispatchUpdate({ zeroPad: Boolean(evt.target.value) }),\n [dispatchUpdate]\n );\n\n switch (column.serverDataType) {\n case \"double\":\n return (\n <>\n <FormField labelPlacement=\"top\">\n <FormFieldLabel>No of Decimals</FormFieldLabel>\n <StepperInput value={decimals} onChange={handleChangeDecimals} />\n </FormField>\n <Switch\n checked={alignOnDecimals}\n label=\"Align on decimals\"\n onChange={handleChangeAlignOnDecimals}\n />\n <Switch\n checked={zeroPad}\n label=\"Zero pad\"\n onChange={handleChangeZeroPad}\n />\n </>\n );\n case \"long\":\n case \"int\":\n return (\n <>\n <Text>Work in progress</Text>\n </>\n );\n default:\n return null;\n }\n};\n", "import \"./ColumnTypePanel.css\";\nimport { ColumnTypePanelProps } from \"./ColumnTypePanel\";\n\nexport const StringColumnPanel = ({\n column,\n dispatchColumnAction,\n}: ColumnTypePanelProps) => {\n console.log({ column, dispatchColumnAction });\n return <>what</>;\n};\n", "import { GridConfig } from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n FormField,\n FormFieldLabel,\n Panel,\n RadioButton,\n RadioButtonGroup,\n Text,\n} from \"@salt-ds/core\";\nimport { StepperInput } from \"@salt-ds/lab\";\nimport { ChangeEvent, Dispatch, HTMLAttributes, useCallback } from \"react\";\n\nimport \"./GridSettingsPanel.css\";\nimport { ColumnAction } from \"./useGridSettings\";\n\nconst classBase = \"vuuGridSettingsPanel\";\n\nexport interface GridSettingsPanelProps extends HTMLAttributes<HTMLDivElement> {\n config: Omit<GridConfig, \"headings\">;\n dispatchColumnAction: Dispatch<ColumnAction>;\n}\nexport const GridSettingsPanel = ({\n config,\n dispatchColumnAction,\n style: styleProp,\n ...props\n}: GridSettingsPanelProps) => {\n const dispatchUpdate = useCallback(\n (\n values: Partial<\n Pick<GridConfig, \"columnDefaultWidth\" | \"columnFormatHeader\">\n >\n ) =>\n dispatchColumnAction({\n type: \"updateGridSettings\",\n ...values,\n }),\n [dispatchColumnAction]\n );\n\n const handleChangeLabelFormatting = useCallback(\n (evt: ChangeEvent<HTMLInputElement>) =>\n dispatchUpdate({\n columnFormatHeader: evt.target.value as \"capitalize\" | \"uppercase\",\n }),\n [dispatchUpdate]\n );\n\n const handleChangeWidth = useCallback(\n (value: string | number) =>\n dispatchUpdate({ columnDefaultWidth: parseInt(value.toString(), 10) }),\n [dispatchUpdate]\n );\n\n return (\n <div\n className={classBase}\n {...props}\n style={{\n ...styleProp,\n }}\n >\n <Text as=\"h4\">Grid Settings</Text>\n <Panel>\n <FormField labelPlacement=\"left\">\n <FormFieldLabel>Format column labels</FormFieldLabel>\n <RadioButtonGroup\n aria-label=\"Format column labels\"\n value={config.columnFormatHeader}\n onChange={handleChangeLabelFormatting}\n >\n <RadioButton label=\"No Formatting\" value={undefined} />\n <RadioButton label=\"Capitalize\" value=\"capitalize\" />\n <RadioButton label=\"Uppercase\" value=\"uppercase\" />\n </RadioButtonGroup>\n </FormField>\n <FormField labelPlacement=\"left\">\n <FormFieldLabel>Default Column Width</FormFieldLabel>\n <StepperInput\n value={config.columnDefaultWidth ?? 100}\n onChange={handleChangeWidth}\n />\n </FormField>\n </Panel>\n </div>\n );\n};\n", "import {\n ColumnDescriptor,\n ColumnTypeDescriptor,\n GridConfig,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport { Reducer, useReducer } from \"react\";\nimport { moveItem } from \"@vuu-ui/vuu-ui-controls\";\nimport { fromServerDataType } from \"@vuu-ui/vuu-utils\";\n\nexport type CalculatedColumnExpression = {\n columName: string;\n expression: string;\n};\n\nexport interface ColumnActionAdd {\n type: \"addColumn\";\n columns?: ColumnDescriptor[];\n column?: ColumnDescriptor;\n index?: number;\n}\nexport interface ColumnActionAddCalculatedColumn {\n columnName: string;\n columnType: \"string\" | \"int\" | \"double\" | \"boolean\";\n expression: string;\n type: \"addCalculatedColumn\";\n}\n\nexport interface ColumnActionMove {\n type: \"moveColumn\";\n column?: ColumnDescriptor;\n moveBy?: 1 | -1;\n moveTo?: number;\n moveFrom?: number;\n}\n\nexport interface ColumnActionRemove {\n type: \"removeColumn\";\n column: ColumnDescriptor;\n}\n\nexport interface ColumnActionUpdate {\n type: \"updateColumn\";\n column: ColumnDescriptor;\n}\nexport interface ColumnActionUpdateProp {\n align?: ColumnDescriptor[\"align\"];\n column: ColumnDescriptor;\n hidden?: ColumnDescriptor[\"hidden\"];\n label?: ColumnDescriptor[\"label\"];\n type: \"updateColumnProp\";\n width?: ColumnDescriptor[\"width\"];\n}\n\nexport interface ColumnActionUpdateGridSettings {\n type: \"updateGridSettings\";\n columnDefaultWidth?: number;\n columnFormatHeader?: \"capitalize\" | \"uppercase\";\n}\n\nexport interface ColumnActionUpdateTypeFormatting {\n type: \"updateColumnTypeFormatting\";\n column: ColumnDescriptor;\n alignOnDecimals?: boolean;\n decimals?: number;\n zeroPad?: boolean;\n}\n\nexport type ColumnAction =\n | ColumnActionAdd\n | ColumnActionAddCalculatedColumn\n | ColumnActionUpdateGridSettings\n | ColumnActionMove\n | ColumnActionRemove\n | ColumnActionUpdate\n | ColumnActionUpdateProp\n | ColumnActionUpdateTypeFormatting;\n\nexport type GridSettingsReducer = Reducer<\n Omit<GridConfig, \"headings\">,\n ColumnAction\n>;\n\nconst gridSettingsReducer: GridSettingsReducer = (state, action) => {\n console.log(`gridSettingsReducer ${action.type}`);\n switch (action.type) {\n case \"addColumn\":\n return addColumn(state, action);\n case \"addCalculatedColumn\":\n return addCalculatedColumn(state, action);\n case \"moveColumn\":\n return moveColumn(state, action);\n case \"removeColumn\":\n return removeColumn(state, action);\n case \"updateColumn\":\n return state;\n case \"updateColumnProp\":\n return updateColumnProp(state, action);\n case \"updateGridSettings\":\n return updateGridSettings(state, action);\n case \"updateColumnTypeFormatting\":\n return updateColumnTypeFormatting(state, action);\n default:\n return state;\n }\n};\n\nexport const useGridSettings = (config: Omit<GridConfig, \"headings\">) => {\n const [state, dispatchColumnAction] = useReducer<GridSettingsReducer>(\n gridSettingsReducer,\n config\n );\n\n return {\n gridSettings: state,\n dispatchColumnAction,\n };\n};\n\nfunction addColumn(\n state: Omit<GridConfig, \"headings\">,\n { column, columns, index = -1 }: ColumnActionAdd\n) {\n const { columns: stateColumns } = state;\n if (index === -1) {\n if (Array.isArray(columns)) {\n return { ...state, columns: stateColumns.concat(columns) };\n } else if (column) {\n return { ...state, columns: stateColumns.concat(column) };\n }\n }\n return state;\n}\n\nfunction addCalculatedColumn(\n state: Omit<GridConfig, \"headings\">,\n { columnName, columnType, expression }: ColumnActionAddCalculatedColumn\n) {\n const { columns: stateColumns } = state;\n const calculatedColumn = {\n name: columnName,\n expression,\n serverDataType: columnType,\n };\n return { ...state, columns: stateColumns.concat(calculatedColumn) };\n}\n\nfunction removeColumn(\n state: Omit<GridConfig, \"headings\">,\n { column }: ColumnActionRemove\n) {\n const { columns: stateColumns } = state;\n return {\n ...state,\n columns: stateColumns.filter((col) => col.name !== column.name),\n };\n}\n\nfunction moveColumn(\n state: Omit<GridConfig, \"headings\">,\n { column, moveBy, moveFrom, moveTo }: ColumnActionMove\n) {\n const { columns: stateColumns } = state;\n if (column && typeof moveBy === \"number\") {\n const idx = stateColumns.indexOf(column);\n const newColumns = stateColumns.slice();\n const [movedColumns] = newColumns.splice(idx, 1);\n newColumns.splice(idx + moveBy, 0, movedColumns);\n return {\n ...state,\n columns: newColumns,\n };\n } else if (typeof moveFrom === \"number\" && typeof moveTo === \"number\") {\n return {\n ...state,\n columns: moveItem(stateColumns, moveFrom, moveTo),\n };\n } else {\n return state;\n }\n}\n\nfunction updateColumnProp(\n state: Omit<GridConfig, \"headings\">,\n { align, column, hidden, label, width }: ColumnActionUpdateProp\n) {\n let { columns: stateColumns } = state;\n if (align === \"left\" || align === \"right\") {\n stateColumns = replaceColumn(stateColumns, { ...column, align });\n }\n if (typeof hidden === \"boolean\") {\n stateColumns = replaceColumn(stateColumns, { ...column, hidden });\n }\n if (typeof label === \"string\") {\n stateColumns = replaceColumn(stateColumns, { ...column, label });\n }\n if (typeof width === \"number\") {\n stateColumns = replaceColumn(stateColumns, { ...column, width });\n }\n return {\n ...state,\n columns: stateColumns,\n };\n}\n\nfunction updateGridSettings(\n state: Omit<GridConfig, \"headings\">,\n { columnFormatHeader }: ColumnActionUpdateGridSettings\n) {\n return {\n ...state,\n columnFormatHeader: columnFormatHeader ?? state.columnFormatHeader,\n };\n}\n\nfunction updateColumnTypeFormatting(\n state: Omit<GridConfig, \"headings\">,\n {\n alignOnDecimals,\n column,\n decimals,\n zeroPad,\n }: ColumnActionUpdateTypeFormatting\n) {\n const { columns: stateColumns } = state;\n const targetColumn = stateColumns.find((col) => col.name === column.name);\n if (targetColumn) {\n const {\n serverDataType = \"string\",\n type: columnType = fromServerDataType(serverDataType),\n } = column;\n const type: ColumnTypeDescriptor =\n typeof columnType === \"string\"\n ? {\n name: columnType,\n }\n : {\n ...columnType,\n };\n if (typeof alignOnDecimals === \"boolean\") {\n type.formatting = {\n ...type.formatting,\n alignOnDecimals,\n };\n }\n if (typeof decimals === \"number\") {\n type.formatting = {\n ...type.formatting,\n decimals,\n };\n }\n if (typeof zeroPad === \"boolean\") {\n type.formatting = {\n ...type.formatting,\n zeroPad,\n };\n }\n\n return {\n ...state,\n columns: replaceColumn(stateColumns, { ...column, type }),\n };\n } else {\n return state;\n }\n}\n\nfunction replaceColumn(columns: ColumnDescriptor[], column: ColumnDescriptor) {\n return columns.map((col) => (col.name === column.name ? column : col));\n}\n", "import { ColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n Button,\n FormField,\n FormFieldLabel,\n Input,\n Panel,\n Text,\n} from \"@salt-ds/core\";\nimport {\n ChangeEventHandler,\n Dispatch,\n HTMLAttributes,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport {\n ColumnDefinitionExpression,\n ColumnExpressionInput,\n useColumnExpressionSuggestionProvider,\n} from \"../../column-expression-input\";\nimport { ColumnAction } from \"../settings-panel/useGridSettings\";\n\nimport \"./CalculatedColumnPanel.css\";\n\nexport interface CalculatedColumnPanelProps\n extends HTMLAttributes<HTMLDivElement> {\n columns: ColumnDescriptor[];\n dispatchColumnAction: Dispatch<ColumnAction>;\n table: VuuTable;\n}\n\nexport const CalculatedColumnPanel = ({\n columns,\n dispatchColumnAction,\n table,\n}: CalculatedColumnPanelProps) => {\n const [columnName, setColumnName] = useState(\"\");\n const [, setExpression] = useState<ColumnDefinitionExpression>();\n const sourceRef = useRef<string>(\"\");\n\n const suggestionProvider = useColumnExpressionSuggestionProvider({\n columns,\n table,\n });\n\n const handleChangeName: ChangeEventHandler<HTMLInputElement> = useCallback(\n (evt) => {\n const { value } = evt.target as HTMLInputElement;\n setColumnName(value);\n },\n []\n );\n const handleChangeExpression = useCallback((source: string) => {\n sourceRef.current = source;\n }, []);\n\n const handleSubmitExpression = useCallback(\n (source: string, expression: ColumnDefinitionExpression | undefined) => {\n console.log({ source });\n setExpression(expression);\n },\n []\n );\n\n const handleSave = useCallback(() => {\n if (sourceRef.current) {\n console.log(\n `save expression ${JSON.stringify(sourceRef.current, null, 2)}`\n );\n dispatchColumnAction({\n type: \"addCalculatedColumn\",\n columnName,\n expression: sourceRef.current,\n columnType: \"string\",\n });\n }\n }, [columnName, dispatchColumnAction]);\n\n return (\n <Panel className=\"vuuCalculatedColumnPanel\" title=\"Define Computed Column\">\n <Text styleAs=\"h4\">Define Computed Column</Text>\n <FormField labelPlacement=\"left\">\n <FormFieldLabel>Column Name</FormFieldLabel>\n <Input value={columnName} onChange={handleChangeName} />\n </FormField>\n <ColumnExpressionInput\n onChange={handleChangeExpression}\n onSubmitExpression={handleSubmitExpression}\n suggestionProvider={suggestionProvider}\n />\n <div style={{ marginTop: 12 }}>\n <Button onClick={handleSave}>Add Column</Button>\n </div>\n </Panel>\n );\n};\n", "import { DataSource } from \"@vuu-ui/vuu-data\";\nimport { HTMLAttributes, useEffect, useState } from \"react\";\nimport cx from \"classnames\";\n\nimport \"./DatasourceStats.css\";\nimport { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\n\ninterface DataSourceStatsProps extends HTMLAttributes<HTMLSpanElement> {\n dataSource: DataSource;\n}\n\nconst classBase = \"vuuDatasourceStats\";\n\nconst numberFormatter = new Intl.NumberFormat();\n\nexport const DataSourceStats = ({\n className: classNameProp,\n dataSource,\n}: DataSourceStatsProps) => {\n const [range, setRange] = useState<VuuRange>(dataSource.range);\n const [size, setSize] = useState(dataSource.size);\n useEffect(() => {\n setSize(dataSource.size);\n\n dataSource.on(\"resize\", setSize);\n dataSource.on(\"range\", setRange);\n }, [dataSource]);\n\n const className = cx(classBase, classNameProp);\n const from = numberFormatter.format(range.from);\n const to = numberFormatter.format(range.to - 1);\n const value = numberFormatter.format(size);\n return (\n <div className={className}>\n <span>Showing rows</span>\n <span className={`${classBase}-range`}>{from}</span>\n <span className={`${classBase}-range`}>{to}</span>\n <span>of</span>\n <span className={`${classBase}-size`}>{value}</span>\n </div>\n );\n};\n", "import {\n FormField,\n FormFieldLabel,\n Input,\n ToggleButton,\n ToggleButtonGroup,\n} from \"@salt-ds/core\";\nimport { SchemaColumn } from \"packages/vuu-data/src\";\nimport { TableConfig } from \"packages/vuu-datagrid-types\";\nimport { HTMLAttributes } from \"react\";\nimport { ColumnList } from \"../column-list\";\nimport { useTableSettings } from \"./useTableSettings\";\n\nimport \"./TableSettingsPanel.css\";\n\nconst classBase = \"vuuTableSettingsPanel\";\n\nexport interface TableSettingsProps extends HTMLAttributes<HTMLDivElement> {\n availableColumns: SchemaColumn[];\n onConfigChange: (config: TableConfig) => void;\n tableConfig: TableConfig;\n}\n\n/**\n The TableSettingsPanel assumes 'ownership' of the tableSettings.\n It updates the settings in state locally and notifies caller of\n every change vis onChange callback\n */\nexport const TableSettingsPanel = ({\n availableColumns,\n onConfigChange,\n tableConfig,\n ...htmlAttributes\n}: TableSettingsProps) => {\n const {\n columnItems,\n columnLabelsValue,\n onChangeColumnLabels,\n onColumnChange,\n onMoveListItem,\n } = useTableSettings({\n availableColumns,\n onConfigChange,\n tableConfig,\n });\n\n return (\n <div {...htmlAttributes} className={classBase}>\n <FormField>\n <FormFieldLabel>Column Labels</FormFieldLabel>\n <ToggleButtonGroup\n className=\"vuuToggleButtonGroup\"\n onChange={onChangeColumnLabels}\n value={columnLabelsValue}\n >\n <ToggleButton\n className=\"vuuIconToggleButton\"\n data-icon=\"text-strikethrough\"\n value={0}\n />\n <ToggleButton\n className=\"vuuIconToggleButton\"\n data-icon=\"text-Tt\"\n value={1}\n />\n <ToggleButton\n className=\"vuuIconToggleButton\"\n data-icon=\"text-T\"\n value={2}\n />\n </ToggleButtonGroup>\n </FormField>\n <FormField>\n <FormFieldLabel>Default Column Width</FormFieldLabel>\n <Input className=\"vuuInput\" />\n </FormField>\n <ColumnList\n columnItems={columnItems}\n onChange={onColumnChange}\n onMoveListItem={onMoveListItem}\n />\n </div>\n );\n};\n", "import { SchemaColumn } from \"@vuu-ui/vuu-data\";\nimport { ColumnDescriptor, TableConfig } from \"@vuu-ui/vuu-datagrid-types\";\nimport { useLayoutEffectSkipFirst } from \"@vuu-ui/vuu-layout\";\nimport { updateTableConfig } from \"@vuu-ui/vuu-table\";\nimport { SyntheticEvent, useCallback, useMemo, useState } from \"react\";\nimport { ColumnChangeHandler } from \"../column-list\";\nimport { TableSettingsProps } from \"./TableSettingsPanel\";\n\nexport type ColumnItem = Pick<\n ColumnDescriptor,\n \"hidden\" | \"label\" | \"name\" | \"serverDataType\"\n> & {\n subscribed: boolean;\n};\n\nconst buildColumnItems = (\n availableColumns: SchemaColumn[],\n configuredColumns: ColumnDescriptor[]\n): ColumnItem[] => {\n return availableColumns.map<ColumnItem>(({ name, serverDataType }) => {\n const configuredColumn = configuredColumns.find((col) => col.name === name);\n return {\n hidden: configuredColumn?.hidden,\n label: configuredColumn?.label,\n name,\n serverDataType,\n subscribed: configuredColumn !== undefined,\n };\n });\n};\n\nexport const useTableSettings = ({\n availableColumns,\n onConfigChange,\n tableConfig: tableConfigProp,\n}: TableSettingsProps) => {\n const [tableConfig, setTableConfig] = useState<TableConfig>(tableConfigProp);\n\n const columnItems = useMemo(\n () => buildColumnItems(availableColumns, tableConfig.columns),\n [availableColumns, tableConfig.columns]\n );\n\n const handleMoveListItem = useCallback(\n (fromIndex: number, toIndex: number) => {\n console.log(`move list item from ${fromIndex} to ${toIndex}`);\n },\n []\n );\n\n const handleColumnChange = useCallback<ColumnChangeHandler>(\n (name, property, value) => {\n // to be applied immediately\n const columnItem = columnItems.find((col) => col.name === name);\n if (property === \"subscribed\") {\n console.log(`unsubscribe from ${name}`);\n } else if (columnItem?.subscribed) {\n const column = tableConfig.columns.find((col) => col.name === name);\n if (column) {\n const newConfig = updateTableConfig(tableConfig, {\n type: \"column-prop\",\n property,\n column,\n value,\n });\n setTableConfig(newConfig);\n }\n }\n },\n [columnItems, tableConfig]\n );\n\n const handleChangeColumnLabels = useCallback((evt: SyntheticEvent) => {\n const { value } = evt.target as HTMLFormElement;\n const columnFormatHeader =\n value === \"0\" ? undefined : value === \"1\" ? \"capitalize\" : \"uppercase\";\n setTableConfig((config) => ({\n ...config,\n columnFormatHeader,\n }));\n }, []);\n\n useLayoutEffectSkipFirst(() => {\n onConfigChange?.(tableConfig);\n }, [onConfigChange, tableConfig]);\n\n const columnLabelsValue =\n tableConfig.columnFormatHeader === undefined\n ? 0\n : tableConfig.columnFormatHeader === \"capitalize\"\n ? 1\n : 2;\n\n return {\n columnItems,\n columnLabelsValue,\n onChangeColumnLabels: handleChangeColumnLabels,\n onColumnChange: handleColumnChange,\n onMoveListItem: handleMoveListItem,\n };\n};\n", "// export interface ColumnResizerProps {}\nimport { useCallback, useRef } from \"react\";\nimport \"./ColumnResizer.css\";\n\nconst NOOP = () => undefined;\n\nconst baseClass = \"vuuColumnResizer\";\nexport interface TableColumnResizerProps {\n onDrag: (evt: MouseEvent, moveBy: number) => void;\n onDragEnd: (evt: MouseEvent) => void;\n onDragStart: (evt: React.MouseEvent) => void;\n}\n\nexport const ColumnResizer = ({\n onDrag,\n onDragEnd = NOOP,\n onDragStart = NOOP,\n}: TableColumnResizerProps) => {\n const position = useRef(0);\n\n const onMouseMove = useCallback(\n (e: MouseEvent) => {\n if (e.stopPropagation) {\n e.stopPropagation();\n }\n\n if (e.preventDefault) {\n e.preventDefault();\n }\n\n const x = Math.round(e.clientX);\n const moveBy = x - position.current;\n position.current = x;\n\n if (moveBy !== 0) {\n onDrag(e, moveBy);\n }\n },\n [onDrag]\n );\n\n const onMouseUp = useCallback(\n (e: MouseEvent) => {\n window.removeEventListener(\"mouseup\", onMouseUp);\n window.removeEventListener(\"mousemove\", onMouseMove);\n onDragEnd(e);\n },\n [onDragEnd, onMouseMove]\n );\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n onDragStart(e);\n position.current = Math.round(e.clientX);\n\n window.addEventListener(\"mouseup\", onMouseUp);\n window.addEventListener(\"mousemove\", onMouseMove);\n\n if (e.stopPropagation) {\n e.stopPropagation();\n }\n\n if (e.preventDefault) {\n e.preventDefault();\n }\n },\n [onDragStart, onMouseMove, onMouseUp]\n );\n\n return (\n <div className={baseClass} data-align=\"end\" onMouseDown={handleMouseDown} />\n );\n};\n", "import { DataSource } from \"@vuu-ui/vuu-data\";\nimport { ContextMenuItemDescriptor, MenuBuilder } from \"@vuu-ui/vuu-data-types\";\nimport { KeyedColumnDescriptor, PinLocation } from \"@vuu-ui/vuu-datagrid-types\";\nimport { Filter } from \"@vuu-ui/vuu-filter-types\";\nimport { isNumericColumn } from \"@vuu-ui/vuu-utils\";\n\nexport type ContextMenuLocation = \"header\" | \"filter\" | \"grid\";\n\ntype MaybeColumn = { column?: KeyedColumnDescriptor };\ntype MaybeFilter = { filter?: Filter };\n\nexport const buildContextMenuDescriptors =\n (dataSource?: DataSource): MenuBuilder =>\n (location, options) => {\n const descriptors: ContextMenuItemDescriptor[] = [];\n if (dataSource === undefined) {\n return descriptors;\n }\n //TODO which should it be ?\n if (location === \"header\" || location === \"column-menu\") {\n descriptors.push(\n ...buildSortMenuItems(options as MaybeColumn, dataSource)\n );\n descriptors.push(\n ...buildGroupMenuItems(options as MaybeColumn, dataSource)\n );\n descriptors.push(\n ...buildAggregationMenuItems(options as MaybeColumn, dataSource)\n );\n descriptors.push(...buildColumnDisplayMenuItems(options as MaybeColumn));\n descriptors.push({\n action: \"column-settings\",\n icon: \"cog\",\n label: `Column Settings`,\n options,\n });\n descriptors.push({\n action: \"table-settings\",\n icon: \"cog\",\n label: `DataGrid Settings`,\n options,\n });\n } else if (location === \"filter\") {\n const { column, filter } = options as MaybeFilter & MaybeColumn;\n const colIsOnlyFilter = filter?.column === column?.name;\n descriptors.push({\n label: \"Edit filter\",\n action: \"filter-edit\",\n options,\n });\n\n descriptors.push({\n label: \"Remove filter\",\n action: \"filter-remove-column\",\n options,\n });\n\n if (column && !colIsOnlyFilter) {\n // TODO col might still be the only column in the filter if it is\n // involved in all clauses\n descriptors.push({\n label: `Remove all filters`,\n action: \"remove-filters\",\n options,\n });\n }\n }\n\n // if (options?.selectedRowCount){\n // // TODO pass the table name\n // const rpcActions = getRpcActions();\n // for (let {label, method} of rpcActions){\n // descriptors.push({action: Action.RpcCall, label, options: {method}})\n // }\n // }\n\n return descriptors;\n };\n\nfunction buildSortMenuItems(\n options: MaybeColumn,\n { sort: { sortDefs } }: DataSource\n): ContextMenuItemDescriptor[] {\n const { column } = options;\n const menuItems: ContextMenuItemDescriptor[] = [];\n if (column === undefined) {\n return menuItems;\n }\n\n const hasSort = sortDefs.length > 0;\n\n if (column.sorted === \"A\") {\n menuItems.push({\n label: \"Reverse Sort (DSC)\",\n action: \"sort-dsc\",\n options,\n });\n } else if (column.sorted === \"D\") {\n menuItems.push({\n label: \"Reverse Sort (ASC)\",\n action: \"sort-asc\",\n options,\n });\n } else if (typeof column.sorted === \"number\") {\n if (column.sorted > 0) {\n menuItems.push({\n label: \"Reverse Sort (DSC)\",\n action: \"sort-add-dsc\",\n options,\n });\n } else {\n menuItems.push({\n label: \"Reverse Sort (ASC)\",\n action: \"sort-add-asc\",\n options,\n });\n }\n\n // removing the last column from a sort would be a no-op, so pointless\n if (hasSort && Math.abs(column.sorted) < sortDefs.length) {\n menuItems.push({\n label: \"Remove from sort\",\n action: \"sort-remove\",\n options,\n });\n }\n\n menuItems.push({\n label: \"New Sort\",\n children: [\n { label: \"Ascending\", action: \"sort-asc\", options },\n { label: \"Descending\", action: \"sort-dsc\", options },\n ],\n });\n } else if (hasSort) {\n menuItems.push({\n label: \"Add to sort\",\n children: [\n { label: \"Ascending\", action: \"sort-add-asc\", options },\n { label: \"Descending\", action: \"sort-add-dsc\", options },\n ],\n });\n menuItems.push({\n label: \"New Sort\",\n children: [\n { label: \"Ascending\", action: \"sort-asc\", options },\n { label: \"Descending\", action: \"sort-dsc\", options },\n ],\n });\n } else {\n menuItems.push({\n label: \"Sort\",\n children: [\n { label: \"Ascending\", action: \"sort-asc\", options },\n { label: \"Descending\", action: \"sort-dsc\", options },\n ],\n });\n }\n return menuItems;\n}\n\nfunction buildAggregationMenuItems(\n options: MaybeColumn,\n dataSource: DataSource\n): ContextMenuItemDescriptor[] {\n const { column } = options;\n if (column === undefined || dataSource.groupBy.length === 0) {\n return [];\n }\n const { name, label = name } = column;\n\n return [\n {\n label: `Aggregate ${label}`,\n children: [\n { label: \"Count\", action: \"agg-count\", options },\n { label: \"Distinct\", action: \"agg-distinct\", options },\n ].concat(\n isNumericColumn(column)\n ? [\n { label: \"Sum\", action: \"agg-sum\", options },\n { label: \"Avg\", action: \"agg-avg\", options },\n { label: \"High\", action: \"agg-high\", options },\n { label: \"Low\", action: \"agg-low\", options },\n ]\n : []\n ),\n },\n ];\n}\n\nconst pinColumn = (options: unknown, pinLocation: PinLocation) =>\n ({\n label: `Pin ${pinLocation}`,\n action: `column-pin-${pinLocation}`,\n options,\n } as ContextMenuItemDescriptor);\n\nconst pinLeft = (options: unknown) => pinColumn(options, \"left\");\nconst pinFloating = (options: unknown) => pinColumn(options, \"floating\");\nconst pinRight = (options: unknown) => pinColumn(options, \"right\");\n\nfunction buildColumnDisplayMenuItems(\n options: MaybeColumn\n): ContextMenuItemDescriptor[] {\n const { column } = options;\n if (column === undefined) {\n return [];\n }\n const { pin } = column;\n\n const menuItems: ContextMenuItemDescriptor[] = [\n {\n label: `Hide column`,\n action: \"column-hide\",\n options,\n },\n {\n label: `Remove column`,\n action: \"column-remove\",\n options,\n },\n ];\n\n if (pin === undefined) {\n menuItems.push({\n label: `Pin column`,\n children: [pinLeft(options), pinFloating(options), pinRight(options)],\n });\n } else if (pin === \"left\") {\n menuItems.push(\n { label: \"Unpin column\", action: \"column-unpin\", options },\n {\n label: `Pin column`,\n children: [pinFloating(options), pinRight(options)],\n }\n );\n } else if (pin === \"right\") {\n menuItems.push(\n { label: \"Unpin column\", action: \"column-unpin\", options },\n {\n label: `Pin column`,\n children: [pinLeft(options), pinFloating(options)],\n }\n );\n } else if (pin === \"floating\") {\n menuItems.push(\n { label: \"Unpin column\", action: \"column-unpin\", options },\n {\n label: `Pin column`,\n children: [pinLeft(options), pinRight(options)],\n }\n );\n }\n\n return menuItems;\n}\n\nfunction buildGroupMenuItems(\n options: MaybeColumn,\n { groupBy }: DataSource\n): ContextMenuItemDescriptor[] {\n const { column } = options;\n const menuItems: ContextMenuItemDescriptor[] = [];\n if (column === undefined) {\n return menuItems;\n }\n\n const { name, label = name } = column;\n\n if (groupBy.length === 0) {\n menuItems.push({\n label: `Group by ${label}`,\n action: \"group\",\n options,\n });\n } else {\n menuItems.push({\n label: `Add ${label} to group by`,\n action: \"group-add\",\n options,\n });\n }\n\n return menuItems;\n}\n", "/* eslint-disable no-sequences */\nimport { DataSource } from \"@vuu-ui/vuu-data\";\nimport { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { Filter } from \"@vuu-ui/vuu-filter-types\";\nimport { removeColumnFromFilter } from \"@vuu-ui/vuu-utils\";\nimport { VuuFilter } from \"@vuu-ui/vuu-protocol-types\";\nimport { DataSourceFilter, MenuActionHandler } from \"@vuu-ui/vuu-data-types\";\nimport { PersistentColumnAction } from \"../useTableModel\";\nimport {\n addGroupColumn,\n addSortColumn,\n AggregationType,\n setAggregations,\n setSortColumn,\n} from \"@vuu-ui/vuu-utils\";\n\nexport interface ContextMenuOptions {\n column?: KeyedColumnDescriptor;\n filter?: Filter;\n sort?: VuuFilter;\n}\nexport interface ContextMenuHookProps {\n dataSource?: DataSource;\n onPersistentColumnOperation: (action: PersistentColumnAction) => void;\n}\n\nconst removeFilterColumn = (\n dataSourceFilter: DataSourceFilter,\n column: KeyedColumnDescriptor\n) => {\n if (dataSourceFilter.filterStruct && column) {\n const [filterStruct, filter] = removeColumnFromFilter(\n column,\n dataSourceFilter.filterStruct\n );\n return {\n filter,\n filterStruct,\n };\n } else {\n return dataSourceFilter;\n }\n};\n\nconst { Average, Count, Distinct, High, Low, Sum } = AggregationType;\n\nexport const useTableContextMenu = ({\n dataSource,\n onPersistentColumnOperation,\n}: ContextMenuHookProps) => {\n /** return {boolean} used by caller to determine whether to forward to additional installed context menu handlers */\n const handleContextMenuAction: MenuActionHandler = (action): boolean => {\n const gridOptions = action.options as ContextMenuOptions;\n if (gridOptions.column && dataSource) {\n const { column } = gridOptions;\n // prettier-ignore\n switch(action.menuId){\n case \"sort-asc\": return (dataSource.sort = setSortColumn(dataSource.sort, column, \"A\")), true;\n case \"sort-dsc\": return (dataSource.sort = setSortColumn(dataSource.sort, column, \"D\")), true;\n case \"sort-add-asc\": return (dataSource.sort = addSortColumn(dataSource.sort, column, \"A\")), true;\n case \"sort-add-dsc\": return (dataSource.sort = addSortColumn(dataSource.sort, column, \"D\")), true;\n case \"group\": return (dataSource.groupBy = addGroupColumn(dataSource.groupBy, column)), true;\n case \"group-add\": return (dataSource.groupBy = addGroupColumn(dataSource.groupBy, column)), true;\n case \"column-hide\": return onPersistentColumnOperation({type: \"hideColumns\", columns: [column]}), true;\n case \"column-remove\": return (dataSource.columns = dataSource.columns.filter(name => name !== column.name)), true\n case \"filter-remove-column\": return (dataSource.filter = removeFilterColumn(dataSource.filter, column)), true;\n case \"remove-filters\": return (dataSource.filter = {filter:\"\"}), true;\n case \"agg-avg\": return dataSource.aggregations = (setAggregations(dataSource.aggregations, column, Average)), true;\n case \"agg-high\": return dataSource.aggregations = (setAggregations(dataSource.aggregations, column, High)), true;\n case \"agg-low\": return dataSource.aggregations = (setAggregations(dataSource.aggregations, column, Low)), true;\n case \"agg-count\": return dataSource.aggregations = (setAggregations(dataSource.aggregations, column, Count)), true;\n case \"agg-distinct\": return dataSource.aggregations = (setAggregations(dataSource.aggregations, column, Distinct)), true;\n case \"agg-sum\": return dataSource.aggregations = (setAggregations(dataSource.aggregations, column, Sum)), true;\n case \"column-pin-floating\": return onPersistentColumnOperation({type: \"pinColumn\", column, pin: \"floating\"}), true;\n case \"column-pin-left\": return onPersistentColumnOperation({type: \"pinColumn\", column, pin: \"left\"}), true;\n case \"column-pin-right\": return onPersistentColumnOperation({type: \"pinColumn\", column, pin: \"right\"}), true;\n case \"column-unpin\": return onPersistentColumnOperation({type: \"pinColumn\", column, pin: undefined}), true\n case \"column-settings\": return onPersistentColumnOperation({type: \"columnSettings\", column}), true\n case \"table-settings\": return onPersistentColumnOperation({type: \"tableSettings\"}), true\n default:\n }\n }\n return false;\n };\n\n return handleContextMenuAction;\n};\n", "import { ContextMenuProvider } from \"@vuu-ui/vuu-popups\";\nimport { Button, useIdMemo } from \"@salt-ds/core\";\nimport { CSSProperties } from \"react\";\nimport { buildContextMenuDescriptors } from \"./context-menu\";\nimport { TableProps } from \"./dataTableTypes\";\n// import { RowBasedTable } from \"./RowBasedTable\";\nimport { RowBasedTable } from \"./RowBasedTable\";\nimport { useTable } from \"./useTable\";\nimport cx from \"classnames\";\n\nimport \"./Table.css\";\nimport \"./Table-loading.css\";\n\nimport { isDataLoading } from \"@vuu-ui/vuu-utils\";\n\nconst classBase = \"vuuTable\";\n\nexport const Table = ({\n allowConfigEditing: showSettings = false,\n className: classNameProp,\n config,\n dataSource,\n headerHeight = 25,\n height,\n id: idProp,\n onConfigChange,\n onFeatureEnabled,\n onFeatureInvocation,\n onSelectionChange,\n onShowConfigEditor: onShowSettings,\n renderBufferSize = 0,\n rowHeight = 20,\n selectionModel = \"extended\",\n style: styleProp,\n width,\n zebraStripes = false,\n ...htmlAttributes\n}: TableProps) => {\n const id = useIdMemo(idProp);\n const {\n containerMeasurements: { containerRef, innerSize, outerSize },\n containerProps,\n dispatchColumnAction,\n draggable,\n draggedItemIndex,\n handleContextMenuAction,\n scrollProps,\n viewportMeasurements,\n ...tableProps\n } = useTable({\n config,\n dataSource,\n renderBufferSize,\n headerHeight,\n height,\n onConfigChange,\n onFeatureEnabled,\n onFeatureInvocation,\n onSelectionChange,\n rowHeight,\n selectionModel,\n width,\n });\n\n const style = {\n ...outerSize,\n \"--content-height\": `${viewportMeasurements.contentHeight}px`,\n \"--horizontal-scrollbar-height\": `${viewportMeasurements.horizontalScrollbarHeight}px`,\n \"--content-width\": `${viewportMeasurements.contentWidth}px`,\n \"--pinned-width-left\": `${viewportMeasurements.pinnedWidthLeft}px`,\n \"--pinned-width-right\": `${viewportMeasurements.pinnedWidthRight}px`,\n \"--header-height\": `${headerHeight}px`,\n \"--row-height\": `${rowHeight}px`,\n \"--table-height\": `${innerSize?.height}px`,\n \"--table-width\": `${innerSize?.width}px`,\n \"--total-header-height\": `${viewportMeasurements.totalHeaderHeight}px`,\n \"--vertical-scrollbar-width\": `${viewportMeasurements.verticalScrollbarWidth}px`,\n \"--viewport-body-height\": `${viewportMeasurements.viewportBodyHeight}px`,\n } as CSSProperties;\n\n const className = cx(classBase, classNameProp, {\n [`${classBase}-zebra`]: zebraStripes,\n [`${classBase}-loading`]: isDataLoading(tableProps.columns),\n });\n\n return (\n <ContextMenuProvider\n menuActionHandler={handleContextMenuAction}\n menuBuilder={buildContextMenuDescriptors(dataSource)}\n >\n <div\n {...htmlAttributes}\n {...containerProps}\n className={className}\n id={id}\n ref={containerRef}\n style={style}\n tabIndex={-1}\n >\n {innerSize ? (\n <div\n className={`${classBase}-scrollbarContainer`}\n ref={scrollProps.scrollbarContainerRef}\n >\n <div className={`${classBase}-scrollbarContent`} />\n </div>\n ) : null}\n {innerSize ? (\n <div\n className={`${classBase}-contentContainer`}\n ref={scrollProps.contentContainerRef}\n >\n <RowBasedTable\n {...tableProps}\n headerHeight={headerHeight}\n tableId={id}\n />\n {draggable}\n </div>\n ) : null}\n {showSettings && innerSize ? (\n <Button\n className={`${classBase}-settings`}\n data-icon=\"settings\"\n onClick={onShowSettings}\n variant=\"secondary\"\n />\n ) : null}\n </div>\n </ContextMenuProvider>\n );\n};\n", "import {\n buildColumnMap,\n getColumnStyle,\n isGroupColumn,\n metadataKeys,\n notHidden,\n visibleColumnAtIndex,\n} from \"@vuu-ui/vuu-utils\";\nimport { MouseEvent, useCallback, useMemo } from \"react\";\nimport { TableImplementationProps } from \"./dataTableTypes\";\nimport { TableRow } from \"./TableRow\";\nimport { TableGroupHeaderCell } from \"./TableGroupHeaderCell\";\nimport { TableHeaderCell } from \"./TableHeaderCell\";\n\nimport \"./RowBasedTable.css\";\n\nconst classBase = \"vuuTable\";\nconst { RENDER_IDX } = metadataKeys;\n\nexport const RowBasedTable = ({\n columns,\n columnsWithinViewport,\n data,\n getRowOffset,\n headings,\n onColumnResize,\n onHeaderCellDragStart,\n onContextMenu,\n onRemoveColumnFromGroupBy,\n onRowClick,\n onSort,\n onToggleGroup,\n tableId,\n virtualColSpan = 0,\n rowCount,\n}: TableImplementationProps) => {\n const handleDragStart = useCallback(\n (evt: MouseEvent) => {\n onHeaderCellDragStart?.(evt);\n },\n [onHeaderCellDragStart]\n );\n\n const visibleColumns = useMemo(() => {\n return columns.filter(notHidden);\n }, [columns]);\n\n const columnMap = useMemo(() => buildColumnMap(columns), [columns]);\n\n const handleHeaderClick = useCallback(\n (evt: MouseEvent) => {\n const targetElement = evt.target as HTMLElement;\n const headerCell = targetElement.closest(\n \".vuuTable-headerCell\"\n ) as HTMLElement;\n const colIdx = parseInt(headerCell?.dataset.idx ?? \"-1\");\n const column = visibleColumnAtIndex(columns, colIdx);\n const isAdditive = evt.shiftKey;\n column && onSort(column, isAdditive);\n },\n [columns, onSort]\n );\n\n return (\n <div aria-rowcount={rowCount} className={`${classBase}-table`} role=\"table\">\n <div className={`${classBase}-headers`} role=\"rowGroup\">\n {headings.map((colHeaders, i) => (\n <div className=\"vuuTable-heading\" key={i}>\n {colHeaders.map(({ label, width }, j) => (\n <div key={j} className=\"vuuTable-headingCell\" style={{ width }}>\n {label}\n </div>\n ))}\n </div>\n ))}\n <div role=\"row\">\n {visibleColumns.map((column, i) => {\n const style = getColumnStyle(column);\n return isGroupColumn(column) ? (\n <TableGroupHeaderCell\n column={column}\n data-idx={i}\n key={i}\n onRemoveColumn={onRemoveColumnFromGroupBy}\n onResize={onColumnResize}\n role=\"columnHeader\"\n style={style}\n />\n ) : (\n <TableHeaderCell\n column={column}\n data-idx={i}\n id={`${tableId}-${i}`}\n key={i}\n onClick={handleHeaderClick}\n onDragStart={handleDragStart}\n onResize={onColumnResize}\n role=\"columnHeader\"\n style={style}\n />\n );\n })}\n </div>\n </div>\n <div\n className={`${classBase}-body`}\n onContextMenu={onContextMenu}\n role=\"rowGroup\"\n >\n {data?.map((row) => (\n <TableRow\n columnMap={columnMap}\n columns={columnsWithinViewport}\n offset={getRowOffset(row)}\n key={row[RENDER_IDX]}\n onClick={onRowClick}\n virtualColSpan={virtualColSpan}\n onToggleGroup={onToggleGroup}\n row={row}\n />\n ))}\n </div>\n </div>\n );\n};\n", "import { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\nimport { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n ColumnMap,\n isGroupColumn,\n isJsonColumn,\n isJsonGroup,\n metadataKeys,\n notHidden,\n} from \"@vuu-ui/vuu-utils\";\nimport cx from \"classnames\";\nimport { HTMLAttributes, memo, MouseEvent, useCallback } from \"react\";\nimport { RowClickHandler } from \"./dataTableTypes\";\nimport { TableCell } from \"./TableCell\";\nimport { TableGroupCell } from \"./TableGroupCell\";\n\nimport \"./TableRow.css\";\n\nconst { IDX, IS_EXPANDED, SELECTED } = metadataKeys;\nconst classBase = \"vuuTableRow\";\n\nexport interface RowProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\" | \"onClick\"> {\n columnMap: ColumnMap;\n columns: KeyedColumnDescriptor[];\n offset: number;\n onClick?: RowClickHandler;\n onToggleGroup?: (row: DataSourceRow, column: KeyedColumnDescriptor) => void;\n row: DataSourceRow;\n virtualColSpan?: number;\n}\n\nexport const TableRow = memo(function Row({\n columnMap,\n columns,\n offset,\n onClick,\n onToggleGroup,\n virtualColSpan = 0,\n row,\n}: RowProps) {\n const {\n [IDX]: rowIndex,\n [IS_EXPANDED]: isExpanded,\n [SELECTED]: isSelected,\n } = row;\n\n const className = cx(classBase, {\n [`${classBase}-even`]: rowIndex % 2 === 0,\n [`${classBase}-expanded`]: isExpanded,\n [`${classBase}-preSelected`]: isSelected === 2,\n });\n\n const handleRowClick = useCallback(\n (evt: MouseEvent) => {\n const rangeSelect = evt.shiftKey;\n const keepExistingSelection = evt.ctrlKey || evt.metaKey; /* mac only */\n onClick?.(row, rangeSelect, keepExistingSelection);\n },\n [onClick, row]\n );\n\n const handleGroupCellClick = useCallback(\n (evt: MouseEvent, column: KeyedColumnDescriptor) => {\n if (isGroupColumn(column) || isJsonGroup(column, row)) {\n evt.stopPropagation();\n onToggleGroup?.(row, column);\n }\n },\n [onToggleGroup, row]\n );\n\n return (\n <div\n aria-selected={isSelected === 1 ? true : undefined}\n aria-rowindex={rowIndex}\n className={className}\n onClick={handleRowClick}\n role=\"row\"\n style={{\n transform: `translate3d(0px, ${offset}px, 0px)`,\n }}\n >\n {virtualColSpan > 0 ? (\n <div role=\"cell\" style={{ width: virtualColSpan }} />\n ) : null}\n {columns.filter(notHidden).map((column) => {\n const isGroup = isGroupColumn(column);\n const isJsonCell = isJsonColumn(column);\n const Cell = isGroup ? TableGroupCell : TableCell;\n return (\n <Cell\n column={column}\n columnMap={columnMap}\n key={column.name}\n onClick={isGroup || isJsonCell ? handleGroupCellClick : undefined}\n row={row}\n />\n );\n })}\n </div>\n );\n});\n", "import { TableCellProps } from \"@vuu-ui/vuu-datagrid-types\";\nimport { getColumnStyle, metadataKeys } from \"@vuu-ui/vuu-utils\";\nimport { EditableLabel } from \"@vuu-ui/vuu-ui-controls\";\nimport cx from \"classnames\";\nimport {\n KeyboardEvent,\n memo,\n MouseEvent,\n useCallback,\n useRef,\n useState,\n} from \"react\";\n\nimport \"./TableCell.css\";\n\nconst { KEY } = metadataKeys;\n\nexport const TableCell = memo(\n ({\n className: classNameProp,\n column,\n columnMap,\n onClick,\n row,\n }: TableCellProps) => {\n const labelFieldRef = useRef<HTMLDivElement>(null);\n const {\n align,\n CellRenderer,\n key,\n pin,\n editable,\n resizing,\n valueFormatter,\n } = column;\n const [editing, setEditing] = useState<boolean>(false);\n const value = valueFormatter(row[key]);\n const [editableValue, setEditableValue] = useState<string>(value);\n const handleTitleMouseDown = () => {\n labelFieldRef.current?.focus();\n };\n const handleTitleKeyDown = (evt: KeyboardEvent<HTMLTableCellElement>) => {\n if (evt.key === \"Enter\") {\n setEditing(true);\n }\n };\n\n const handleClick = useCallback(\n (evt: MouseEvent) => {\n onClick?.(evt, column);\n },\n [column, onClick]\n );\n\n const handleEnterEditMode = () => {\n setEditing(true);\n };\n\n const handleExitEditMode = (\n originalValue = \"\",\n finalValue = \"\",\n allowDeactivation = true,\n editCancelled = false\n ) => {\n setEditing(false);\n if (editCancelled) {\n setEditableValue(originalValue);\n } else if (finalValue !== originalValue) {\n setEditableValue(finalValue);\n }\n if (allowDeactivation === false) {\n labelFieldRef.current?.focus();\n }\n };\n\n // might want to useMemo here, this won't change often\n const className =\n cx(classNameProp, {\n vuuAlignRight: align === \"right\",\n vuuPinFloating: pin === \"floating\",\n vuuPinLeft: pin === \"left\",\n vuuPinRight: pin === \"right\",\n \"vuuTableCell-resizing\": resizing,\n }) || undefined;\n const style = getColumnStyle(column);\n return editable ? (\n <div\n className={className}\n data-editable\n role=\"cell\"\n style={style}\n onKeyDown={handleTitleKeyDown}\n >\n <EditableLabel\n editing={editing}\n key=\"title\"\n value={editableValue}\n onChange={setEditableValue}\n onMouseDownCapture={handleTitleMouseDown}\n onEnterEditMode={handleEnterEditMode}\n onExitEditMode={handleExitEditMode}\n onKeyDown={handleTitleKeyDown}\n ref={labelFieldRef}\n tabIndex={0}\n />\n </div>\n ) : (\n <div\n className={className}\n role=\"cell\"\n style={style}\n onClick={handleClick}\n >\n {CellRenderer ? (\n <CellRenderer column={column} columnMap={columnMap} row={row} />\n ) : (\n value\n )}\n </div>\n );\n },\n cellValuesAreEqual\n);\nTableCell.displayName = \"TableCell\";\n\nfunction cellValuesAreEqual(prev: TableCellProps, next: TableCellProps) {\n return (\n prev.column === next.column &&\n prev.onClick === next.onClick &&\n prev.row[KEY] === next.row[KEY] &&\n prev.row[prev.column.key] === next.row[next.column.key]\n );\n}\n", "import {\n GroupColumnDescriptor,\n TableCellProps,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n getColumnStyle,\n getGroupValueAndOffset,\n metadataKeys,\n} from \"@vuu-ui/vuu-utils\";\nimport { MouseEvent, useCallback } from \"react\";\n\nimport \"./TableGroupCell.css\";\n\nconst { IS_LEAF } = metadataKeys;\n\nexport const TableGroupCell = ({ column, onClick, row }: TableCellProps) => {\n const { columns } = column as GroupColumnDescriptor;\n const [value, offset] = getGroupValueAndOffset(columns, row);\n\n const handleClick = useCallback(\n (evt: MouseEvent) => {\n onClick?.(evt, column);\n },\n [column, onClick]\n );\n\n const style = getColumnStyle(column);\n const isLeaf = row[IS_LEAF];\n const spacers = Array(offset)\n .fill(0)\n .map((n, i) => <span className=\"vuuTableGroupCell-spacer\" key={i} />);\n return (\n <div\n className={\"vuuTableGroupCell vuuPinLeft\"}\n onClick={isLeaf ? undefined : handleClick}\n role=\"cell\"\n style={style}\n >\n {spacers}\n {isLeaf ? null : (\n <span className=\"vuuTableGroupCell-toggle\" data-icon=\"triangle-right\" />\n )}\n <span>{value}</span>\n </div>\n );\n};\n", "import cx from \"classnames\";\nimport { HTMLAttributes, useRef } from \"react\";\nimport { ColumnResizer } from \"./ColumnResizer\";\nimport { TableHeaderCellProps } from \"./TableHeaderCell\";\nimport {\n GroupColumnDescriptor,\n KeyedColumnDescriptor,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport { useTableColumnResize } from \"./useTableColumnResize\";\n\nimport \"./TableGroupHeaderCell.css\";\n\nconst classBase = \"vuuTable-groupHeaderCell\";\n\ninterface RemoveButtonProps\n extends Omit<HTMLAttributes<HTMLSpanElement>, \"onClick\"> {\n column?: KeyedColumnDescriptor;\n onClick?: (column?: KeyedColumnDescriptor) => void;\n}\nconst RemoveButton = ({\n column,\n onClick,\n ...htmlAttributes\n}: RemoveButtonProps) => {\n return (\n <span\n {...htmlAttributes}\n className={`${classBase}-close`}\n data-icon=\"close-circle\"\n onClick={() => onClick?.(column)}\n />\n );\n};\n\nexport interface ColHeaderProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onClick\"> {\n column: KeyedColumnDescriptor;\n onRemove?: (column?: KeyedColumnDescriptor) => void;\n}\n\nconst ColHeader = (props: ColHeaderProps) => {\n const { children, column, className } = props;\n return (\n <div className={cx(`${classBase}-col`, className)} role=\"columnheader\">\n <span className={`${classBase}-label`}>{column.name}</span>\n {children}\n </div>\n );\n};\n\nexport interface TableGroupHeaderCellProps\n extends Omit<TableHeaderCellProps, \"onDragStart\" | \"onDrag\" | \"onDragEnd\"> {\n column: GroupColumnDescriptor;\n onRemoveColumn?: (column?: KeyedColumnDescriptor) => void;\n}\n\nexport const TableGroupHeaderCell = ({\n column: groupColumn,\n className: classNameProp,\n onRemoveColumn,\n onResize,\n ...props\n}: TableGroupHeaderCellProps) => {\n const rootRef = useRef<HTMLTableCellElement>(null);\n const { isResizing, ...resizeProps } = useTableColumnResize({\n column: groupColumn,\n onResize,\n rootRef,\n });\n const className = cx(classBase, classNameProp, {\n vuuPinLeft: groupColumn.pin === \"left\",\n [`${classBase}-right`]: groupColumn.align === \"right\",\n [`${classBase}-resizing`]: groupColumn.resizing,\n [`${classBase}-pending`]: groupColumn.groupConfirmed === false,\n });\n const { columns } = groupColumn;\n\n return (\n <div className={className} ref={rootRef} {...props}>\n <div className={`${classBase}-inner`}>\n {columns.map((column) => (\n <ColHeader key={column.key} column={column}>\n {columns.length > 1 ? (\n <RemoveButton column={column} onClick={onRemoveColumn} />\n ) : null}\n </ColHeader>\n ))}\n <RemoveButton data-align=\"end\" onClick={onRemoveColumn} />\n {groupColumn.resizeable !== false ? (\n <ColumnResizer {...resizeProps} />\n ) : null}\n </div>\n </div>\n );\n};\n", "import { Heading, KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { RefObject, useCallback, useRef } from \"react\";\n\nexport type ResizeHandler = (evt: MouseEvent, moveBy: number) => void;\nexport interface CellResizeHookProps {\n column: KeyedColumnDescriptor | Heading;\n onResize?: (phase: resizePhase, columnName: string, width?: number) => void;\n rootRef: RefObject<HTMLDivElement>;\n}\n\ntype resizePhase = \"begin\" | \"resize\" | \"end\";\n\nexport interface CellResizeHookResult {\n isResizing: boolean;\n onDrag: (evt: MouseEvent, moveBy: number) => void;\n onDragStart: (evt: React.MouseEvent) => void;\n onDragEnd: (evt: MouseEvent) => void;\n}\n\nexport const useTableColumnResize = ({\n column,\n onResize,\n rootRef,\n}: CellResizeHookProps): CellResizeHookResult => {\n const widthRef = useRef(0);\n const isResizing = useRef(false);\n const { name } = column;\n\n const handleResizeStart = useCallback(() => {\n if (onResize && rootRef.current) {\n console.log(\"handleResizeStart\");\n const { width } = rootRef.current.getBoundingClientRect();\n widthRef.current = Math.round(width);\n isResizing.current = true;\n onResize?.(\"begin\", name);\n }\n }, [name, onResize, rootRef]);\n\n const handleResize = useCallback(\n (_evt: MouseEvent, moveBy: number) => {\n if (rootRef.current) {\n if (onResize) {\n const { width } = rootRef.current.getBoundingClientRect();\n const newWidth = Math.round(width) + moveBy;\n if (newWidth !== widthRef.current && newWidth > 0) {\n onResize(\"resize\", name, newWidth);\n widthRef.current = newWidth;\n }\n }\n }\n },\n [name, onResize, rootRef]\n );\n\n const handleResizeEnd = useCallback(() => {\n if (onResize) {\n onResize(\"end\", name, widthRef.current);\n setTimeout(() => {\n // set in a timeout to prevent the click event from firing and triggering a sort\n isResizing.current = false;\n }, 100);\n }\n }, [name, onResize]);\n\n return {\n isResizing: isResizing.current,\n onDrag: handleResize,\n onDragStart: handleResizeStart,\n onDragEnd: handleResizeEnd,\n };\n};\n", "import { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport cx from \"classnames\";\nimport { HTMLAttributes, MouseEvent, useCallback, useRef } from \"react\";\nimport { ColumnResizer } from \"./ColumnResizer\";\nimport { SortIndicator } from \"./SortIndicator\";\nimport { useTableColumnResize } from \"./useTableColumnResize\";\nimport { TableColumnResizeHandler } from \"./dataTableTypes\";\n\nimport \"./TableHeaderCell.css\";\nimport { useContextMenu } from \"@vuu-ui/vuu-popups\";\nimport { FilterIndicator } from \"./filter-indicator\";\n\nconst classBase = \"vuuTable-headerCell\";\n\nexport interface TableHeaderCellProps\n extends HTMLAttributes<HTMLTableCellElement> {\n column: KeyedColumnDescriptor;\n debugString?: string;\n onDragStart?: (evt: MouseEvent) => void;\n onResize?: TableColumnResizeHandler;\n}\n\nexport const TableHeaderCell = ({\n column,\n className: classNameProp,\n onClick,\n onDragStart,\n onResize,\n ...props\n}: TableHeaderCellProps) => {\n const rootRef = useRef<HTMLTableCellElement>(null);\n const { isResizing, ...resizeProps } = useTableColumnResize({\n column,\n onResize,\n rootRef,\n });\n\n const [showContextMenu] = useContextMenu();\n const dragTimerRef = useRef<number | null>(null);\n\n const handleContextMenu = (e: MouseEvent<HTMLElement>) => {\n showContextMenu(e, \"header\", { column });\n };\n\n const handleClick = useCallback(\n (evt: MouseEvent<HTMLTableCellElement>) => !isResizing && onClick?.(evt),\n [isResizing, onClick]\n );\n\n const handleMouseDown = useCallback(\n (evt: MouseEvent) => {\n dragTimerRef.current = window.setTimeout(() => {\n onDragStart?.(evt);\n dragTimerRef.current = null;\n }, 500);\n },\n [onDragStart]\n );\n const handleMouseUp = useCallback(() => {\n if (dragTimerRef.current !== null) {\n window.clearTimeout(dragTimerRef.current);\n dragTimerRef.current = null;\n }\n }, []);\n\n const className = cx(classBase, classNameProp, {\n vuuPinFloating: column.pin === \"floating\",\n vuuPinLeft: column.pin === \"left\",\n vuuPinRight: column.pin === \"right\",\n vuuEndPin: column.endPin,\n [`${classBase}-resizing`]: column.resizing,\n [`${classBase}-right`]: column.align === \"right\",\n });\n return (\n <div\n className={className}\n {...props}\n onClick={handleClick}\n onContextMenu={handleContextMenu}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n ref={rootRef}\n >\n <div className={`${classBase}-inner`}>\n <FilterIndicator column={column} />\n <div className={`${classBase}-label`}>{column.label}</div>\n <SortIndicator sorted={column.sorted} />\n {column.resizeable !== false ? (\n <ColumnResizer {...resizeProps} />\n ) : null}\n </div>\n </div>\n );\n};\n", "import { ColumnSort } from \"@vuu-ui/vuu-datagrid-types\";\nimport cx from \"classnames\";\n\nimport \"./SortIndicator.css\";\n\nexport interface SortIndicatorProps {\n sorted?: ColumnSort;\n}\n\nconst classBase = \"vuuSortIndicator\";\n\nexport const SortIndicator = ({ sorted }: SortIndicatorProps) => {\n if (!sorted) {\n return null;\n }\n\n const direction =\n typeof sorted === \"number\"\n ? sorted < 0\n ? \"dsc\"\n : \"asc\"\n : sorted === \"A\"\n ? \"asc\"\n : \"dsc\";\n\n return typeof sorted === \"number\" ? (\n <div className={cx(classBase, \"multi-col\", direction)}>\n <span data-icon={`sorted-${direction}`} />\n <span className={\"vuuSortPosition\"}>{Math.abs(sorted)}</span>\n </div>\n ) : (\n <div className={cx(classBase, \"single-col\")}>\n <span data-icon={`sorted-${direction}`} />\n </div>\n );\n};\n", "import { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { Filter } from \"@vuu-ui/vuu-filter-types\";\nimport { useContextMenu } from \"@vuu-ui/vuu-popups\";\nimport cx from \"classnames\";\nimport { HTMLAttributes, useCallback } from \"react\";\n\nimport \"./filter-indicator.css\";\n\nexport const Direction = {\n ASC: \"asc\",\n DSC: \"dsc\",\n};\n\nexport interface FilterIndicatorProps extends HTMLAttributes<HTMLDivElement> {\n column: KeyedColumnDescriptor;\n filter?: Filter;\n}\n\nexport const FilterIndicator = ({ column, filter }: FilterIndicatorProps) => {\n //TODO handle this at header level\n const [showContextMenu] = useContextMenu();\n\n const handleClick = useCallback(\n (evt) => {\n // if we do this through keyboard, need to get co-ords\n evt.stopPropagation();\n showContextMenu(evt, \"filter\", { column, filter });\n },\n [column, filter, showContextMenu]\n );\n\n if (!column.filter) {\n return null;\n }\n\n return (\n <div\n className={cx(\"vuuFilterIndicator\")}\n data-icon=\"filter\"\n onClick={handleClick}\n />\n );\n};\n", "import {\n DataSource,\n DataSourceSubscribedMessage,\n JsonDataSource,\n VuuFeatureInvocationMessage,\n VuuFeatureMessage,\n} from \"@vuu-ui/vuu-data\";\nimport { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\nimport {\n GridConfig,\n KeyedColumnDescriptor,\n SelectionChangeHandler,\n TableSelectionModel,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport { useContextMenu as usePopupContextMenu } from \"@vuu-ui/vuu-popups\";\nimport { VuuSortType } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n applySort,\n buildColumnMap,\n isJsonGroup,\n metadataKeys,\n moveItem,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n MouseEvent,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useTableContextMenu } from \"./context-menu\";\nimport { TableColumnResizeHandler } from \"./dataTableTypes\";\nimport { useDataSource } from \"./useDataSource\";\nimport { useDraggableColumn } from \"./useDraggableColumn\";\nimport { useKeyboardNavigation } from \"./useKeyboardNavigation\";\nimport { MeasuredProps, useMeasuredContainer } from \"./useMeasuredContainer\";\nimport { useSelection } from \"./useSelection\";\nimport { PersistentColumnAction, useTableModel } from \"./useTableModel\";\nimport { useTableScroll } from \"./useTableScroll\";\nimport { useTableViewport } from \"./useTableViewport\";\nimport { useVirtualViewport } from \"./useVirtualViewport\";\n\nconst NO_ROWS = [] as const;\n\nexport interface TableHookProps extends MeasuredProps {\n config: Omit<GridConfig, \"headings\">;\n dataSource: DataSource;\n headerHeight: number;\n onConfigChange?: (config: Omit<GridConfig, \"headings\">) => void;\n onFeatureEnabled?: (message: VuuFeatureMessage) => void;\n onFeatureInvocation?: (message: VuuFeatureInvocationMessage) => void;\n renderBufferSize?: number;\n rowHeight: number;\n onSelectionChange?: SelectionChangeHandler;\n selectionModel: TableSelectionModel;\n}\n\nconst { KEY, IS_EXPANDED, IS_LEAF } = metadataKeys;\n\nexport const useTable = ({\n config,\n dataSource,\n headerHeight,\n onConfigChange,\n onFeatureEnabled,\n onFeatureInvocation,\n onSelectionChange,\n renderBufferSize = 0,\n rowHeight,\n selectionModel,\n ...measuredProps\n}: TableHookProps) => {\n const [rowCount, setRowCount] = useState<number>(dataSource.size);\n const expectConfigChangeRef = useRef(false);\n\n // When we detect and respond to changes to config below, we need\n // to include current dataSource config when we refresh the model.\n const dataSourceRef = useRef<DataSource>();\n dataSourceRef.current = dataSource;\n\n if (dataSource === undefined) {\n throw Error(\"no data source provided to Vuu Table\");\n }\n\n const containerMeasurements = useMeasuredContainer(measuredProps);\n\n const onDataRowcountChange = useCallback((size: number) => {\n setRowCount(size);\n }, []);\n\n const { columns, dispatchColumnAction, headings } = useTableModel(\n config,\n dataSource.config\n );\n\n const {\n getRowAtPosition,\n getRowOffset,\n setPctScrollTop,\n ...viewportMeasurements\n } = useTableViewport({\n columns,\n headerHeight,\n headings,\n rowCount,\n rowHeight,\n size: containerMeasurements.innerSize,\n });\n\n const onSubscribed = useCallback(\n ({ tableSchema }: DataSourceSubscribedMessage) => {\n if (tableSchema) {\n expectConfigChangeRef.current = true;\n dispatchColumnAction({\n type: \"setTableSchema\",\n tableSchema,\n });\n } else {\n console.log(\"usbscription message with no schema\");\n }\n },\n [dispatchColumnAction]\n );\n\n const handleSelectionChange: SelectionChangeHandler = useCallback(\n (selected) => {\n dataSource.select(selected);\n onSelectionChange?.(selected);\n },\n [dataSource, onSelectionChange]\n );\n\n const handleRowClick = useSelection({\n onSelectionChange: handleSelectionChange,\n selectionModel,\n });\n\n const { data, getSelectedRows, range, setRange } = useDataSource({\n dataSource,\n onFeatureEnabled,\n onFeatureInvocation,\n onSubscribed,\n onSizeChange: onDataRowcountChange,\n renderBufferSize,\n viewportRowCount: viewportMeasurements.rowCount,\n });\n\n // Keep a ref to current data. We use it to provide row for context menu actions.\n // We don't want to introduce data as a dependency on the context menu handler, just\n // needs to be correct at runtime when the row is right clicked.\n const dataRef = useRef<DataSourceRow[]>();\n dataRef.current = data;\n\n const onPersistentColumnOperation = useCallback(\n (action: PersistentColumnAction) => {\n expectConfigChangeRef.current = true;\n console.log(`onPersistentColumnOperation, dispatchColumnAction`, {\n action,\n });\n dispatchColumnAction(action as any);\n },\n [dispatchColumnAction]\n );\n\n const handleContextMenuAction = useTableContextMenu({\n dataSource,\n onPersistentColumnOperation,\n });\n\n const handleSort = useCallback(\n (\n column: KeyedColumnDescriptor,\n extendSort = false,\n sortType?: VuuSortType\n ) => {\n if (dataSource) {\n dataSource.sort = applySort(\n dataSource.sort,\n column,\n extendSort,\n sortType\n );\n }\n },\n [dataSource]\n );\n\n const handleColumnResize: TableColumnResizeHandler = useCallback(\n (phase, columnName, width) => {\n const column = columns.find((column) => column.name === columnName);\n if (column) {\n if (phase === \"end\") {\n expectConfigChangeRef.current = true;\n }\n dispatchColumnAction({\n type: \"resizeColumn\",\n phase,\n column,\n width,\n });\n } else {\n throw Error(\n `useDataTable.handleColumnResize, column ${columnName} not found`\n );\n }\n },\n [columns, dispatchColumnAction]\n );\n\n const handleToggleGroup = useCallback(\n (row: DataSourceRow, column: KeyedColumnDescriptor) => {\n const isJson = isJsonGroup(column, row);\n const key = row[KEY];\n\n if (row[IS_EXPANDED]) {\n (dataSource as JsonDataSource).closeTreeNode(key, true);\n if (isJson) {\n const idx = columns.indexOf(column);\n const rows = (dataSource as JsonDataSource).getRowsAtDepth(idx + 1);\n if (!rows.some((row) => row[IS_EXPANDED] || row[IS_LEAF])) {\n dispatchColumnAction({\n type: \"hideColumns\",\n columns: columns.slice(idx + 2),\n });\n }\n }\n } else {\n dataSource.openTreeNode(key);\n if (isJson) {\n const childRows = (dataSource as JsonDataSource).getChildRows(key);\n const idx = columns.indexOf(column) + 1;\n const columnsToShow = [columns[idx]];\n if (childRows.some((row) => row[IS_LEAF])) {\n columnsToShow.push(columns[idx + 1]);\n }\n if (columnsToShow.some((col) => col.hidden)) {\n dispatchColumnAction({\n type: \"showColumns\",\n columns: columnsToShow,\n });\n }\n }\n }\n },\n [columns, dataSource, dispatchColumnAction]\n );\n\n const {\n onVerticalScroll,\n onHorizontalScroll,\n columnsWithinViewport,\n virtualColSpan,\n } = useVirtualViewport({\n columns,\n getRowAtPosition,\n setRange,\n viewportMeasurements,\n });\n\n const handleVerticalScroll = useCallback(\n (scrollTop: number, pctScrollTop: number) => {\n setPctScrollTop(pctScrollTop);\n onVerticalScroll(scrollTop);\n },\n [onVerticalScroll, setPctScrollTop]\n );\n\n const { requestScroll, ...scrollProps } = useTableScroll({\n onHorizontalScroll,\n onVerticalScroll: handleVerticalScroll,\n viewport: viewportMeasurements,\n viewportHeight:\n (containerMeasurements.innerSize?.height ?? 0) - headerHeight,\n });\n\n const containerProps = useKeyboardNavigation({\n columnCount: columns.length,\n containerRef: containerMeasurements.containerRef,\n data,\n requestScroll,\n rowCount: dataSource?.size,\n viewportRange: range,\n });\n\n const handleRemoveColumnFromGroupBy = useCallback(\n (column?: KeyedColumnDescriptor) => {\n if (column) {\n if (dataSource && dataSource.groupBy.includes(column.name)) {\n dataSource.groupBy = dataSource.groupBy.filter(\n (columnName) => columnName !== column.name\n );\n }\n } else {\n dataSource.groupBy = [];\n }\n },\n [dataSource]\n );\n\n const handleDropColumn = useCallback(\n (fromIndex: number, toIndex: number) => {\n const column = dataSource.columns[fromIndex];\n const columns = moveItem(dataSource.columns, column, toIndex);\n if (columns !== dataSource.columns) {\n dataSource.columns = columns;\n dispatchColumnAction({ type: \"tableConfig\", columns });\n }\n },\n [dataSource, dispatchColumnAction]\n );\n\n const draggableHook = useDraggableColumn({\n onDrop: handleDropColumn,\n });\n\n useEffect(() => {\n // External config has changed\n if (dataSourceRef.current) {\n expectConfigChangeRef.current = true;\n dispatchColumnAction({\n type: \"init\",\n tableConfig: config,\n dataSourceConfig: dataSourceRef.current.config,\n });\n }\n }, [config, dispatchColumnAction]);\n\n useEffect(() => {\n dataSource.on(\"config\", (config, confirmed) => {\n expectConfigChangeRef.current = true;\n dispatchColumnAction({\n type: \"tableConfig\",\n ...config,\n confirmed,\n });\n });\n }, [dataSource, dispatchColumnAction]);\n\n useMemo(() => {\n if (expectConfigChangeRef.current) {\n onConfigChange?.({\n ...config,\n columns,\n });\n expectConfigChangeRef.current = false;\n }\n }, [columns, config, onConfigChange]);\n\n const [showContextMenu] = usePopupContextMenu();\n\n const onContextMenu = useCallback(\n (evt: MouseEvent<HTMLElement>) => {\n const { current: currentData } = dataRef;\n const { current: currentDataSource } = dataSourceRef;\n const target = evt.target as HTMLElement;\n const cellEl = target?.closest(\"div[role='cell']\");\n const rowEl = target?.closest(\".vuuTableRow\");\n\n if (cellEl && rowEl && currentData && currentDataSource) {\n const { columns, selectedRowsCount } = currentDataSource;\n const columnMap = buildColumnMap(columns);\n const rowIndex = parseInt(rowEl.ariaRowIndex ?? \"-1\");\n const cellIndex = Array.from(rowEl.childNodes).indexOf(cellEl);\n const row = currentData.find(([idx]) => idx === rowIndex);\n const columnName = columns[cellIndex];\n\n showContextMenu(evt, \"grid\", {\n columnMap,\n columnName,\n row,\n selectedRows: selectedRowsCount === 0 ? NO_ROWS : getSelectedRows(),\n viewport: dataSource?.viewport,\n });\n }\n },\n [dataSource?.viewport, getSelectedRows, showContextMenu]\n );\n\n return {\n columns,\n columnsWithinViewport,\n containerMeasurements,\n containerProps,\n data,\n dispatchColumnAction,\n getRowOffset,\n handleContextMenuAction,\n headings,\n onColumnResize: handleColumnResize,\n onContextMenu,\n onRemoveColumnFromGroupBy: handleRemoveColumnFromGroupBy,\n onRowClick: handleRowClick,\n onSort: handleSort,\n onToggleGroup: handleToggleGroup,\n virtualColSpan,\n scrollProps,\n rowCount,\n viewportMeasurements,\n ...draggableHook,\n };\n};\n", "import {\n DataSource,\n DataSourceConfigMessage,\n DataSourceSubscribedMessage,\n SubscribeCallback,\n VuuFeatureInvocationMessage,\n VuuFeatureMessage,\n} from \"@vuu-ui/vuu-data\";\nimport { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\n\nimport {\n isVuuFeatureAction,\n isVuuFeatureInvocation,\n} from \"@vuu-ui/vuu-data-react\";\nimport { VuuRange, VuuSortCol } from \"@vuu-ui/vuu-protocol-types\";\nimport { getFullRange, metadataKeys, WindowRange } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nconst { SELECTED } = metadataKeys;\n\n// const byKey = (row1: VuuDataRow, row2: VuuDataRow) =>\n// ((row1[RENDER_IDX] as number) - row2[RENDER_IDX]) as number;\n\nexport type SubscriptionDetails = {\n columnNames?: string[];\n range: { from: number; to: number };\n sort?: VuuSortCol[];\n};\n\nexport interface DataSourceHookProps {\n dataSource: DataSource;\n onConfigChange?: (message: DataSourceConfigMessage) => void;\n onFeatureEnabled?: (message: VuuFeatureMessage) => void;\n onFeatureInvocation?: (message: VuuFeatureInvocationMessage) => void;\n onSizeChange: (size: number) => void;\n onSubscribed: (subscription: DataSourceSubscribedMessage) => void;\n range?: VuuRange;\n renderBufferSize?: number;\n viewportRowCount: number;\n}\n\n//TODO allow subscription details to be set before subscribe call\nexport function useDataSource({\n dataSource,\n onConfigChange,\n onFeatureEnabled,\n onFeatureInvocation,\n onSizeChange,\n onSubscribed,\n range = { from: 0, to: 0 },\n renderBufferSize = 0,\n viewportRowCount,\n}: DataSourceHookProps) {\n const [, forceUpdate] = useState<unknown>(null);\n const isMounted = useRef(true);\n const hasUpdated = useRef(false);\n const rangeRef = useRef<VuuRange>({ from: 0, to: 0 });\n const rafHandle = useRef<number | null>(null);\n const data = useRef<DataSourceRow[]>([]);\n\n const dataWindow = useMemo(\n () => new MovingWindow(getFullRange(range)),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n []\n );\n\n const setData = useCallback(\n (updates: DataSourceRow[]) => {\n for (const row of updates) {\n dataWindow.add(row);\n }\n data.current = dataWindow.data;\n hasUpdated.current = true;\n },\n [dataWindow]\n );\n\n const datasourceMessageHandler: SubscribeCallback = useCallback(\n (message) => {\n if (message.type === \"subscribed\") {\n onSubscribed?.(message);\n } else if (message.type === \"viewport-update\") {\n if (typeof message.size === \"number\") {\n onSizeChange?.(message.size);\n dataWindow.setRowCount(message.size);\n }\n if (message.rows) {\n setData(message.rows);\n } else if (typeof message.size === \"number\") {\n // TODO is this right ??????\n data.current = dataWindow.data;\n // data.current = dataWindow.data.slice().sort(byKey);\n hasUpdated.current = true;\n }\n } else if (isVuuFeatureAction(message)) {\n onFeatureEnabled?.(message);\n } else if (isVuuFeatureInvocation(message)) {\n onFeatureInvocation?.(message);\n } else {\n console.log(`useDataSource unexpected message ${message.type}`);\n }\n },\n [\n dataWindow,\n onFeatureEnabled,\n onFeatureInvocation,\n onSizeChange,\n onSubscribed,\n setData,\n ]\n );\n\n useEffect(\n () => () => {\n if (rafHandle.current) {\n cancelAnimationFrame(rafHandle.current);\n rafHandle.current = null;\n }\n isMounted.current = false;\n },\n []\n );\n\n const refreshIfUpdated = useCallback(() => {\n if (isMounted.current) {\n if (hasUpdated.current) {\n forceUpdate({});\n hasUpdated.current = false;\n }\n rafHandle.current = requestAnimationFrame(refreshIfUpdated);\n }\n }, [forceUpdate]);\n\n useEffect(() => {\n rafHandle.current = requestAnimationFrame(refreshIfUpdated);\n }, [refreshIfUpdated]);\n\n const adjustRange = useCallback(\n (rowCount: number) => {\n const { from } = dataSource.range;\n const rowRange = { from, to: from + rowCount };\n const fullRange = getFullRange(rowRange, renderBufferSize);\n dataWindow.setRange(fullRange);\n dataSource.range = rangeRef.current = fullRange;\n // seems a bit naughty to emit from outside, but the datasource doesn't\n // know about the buffer size we add to the base range\n dataSource.emit(\"range\", rowRange);\n },\n [dataSource, dataWindow, renderBufferSize]\n );\n\n const setRange = useCallback(\n (range: VuuRange) => {\n const fullRange = getFullRange(range, renderBufferSize);\n dataWindow.setRange(fullRange);\n dataSource.range = rangeRef.current = fullRange;\n dataSource.emit(\"range\", range);\n },\n [dataSource, dataWindow, renderBufferSize]\n );\n\n const getSelectedRows = useCallback(() => {\n return dataWindow.getSelectedRows();\n }, [dataWindow]);\n\n // Note: we do not call unsubscribe in a cleanup function here.\n // Thats because we do not want to unsubscribe in the event that\n // our view is unmounts due to a layout drag drop operation. In\n // that scenario, we disable the viewport. THis is handles at the\n // View level. Might need to revisit this - what if Table is not\n // nested within a View ?\n useEffect(() => {\n dataSource?.subscribe(\n {\n range: rangeRef.current,\n },\n datasourceMessageHandler\n );\n }, [dataSource, datasourceMessageHandler, onConfigChange]);\n\n useEffect(() => {\n adjustRange(viewportRowCount);\n }, [adjustRange, viewportRowCount]);\n\n return {\n data: data.current,\n getSelectedRows,\n range: rangeRef.current,\n setRange,\n dataSource,\n };\n}\n\nexport class MovingWindow {\n public data: DataSourceRow[];\n public rowCount = 0;\n private range: WindowRange;\n\n constructor({ from, to }: VuuRange) {\n this.range = new WindowRange(from, to);\n //internal data is always 0 based, we add range.from to determine an offset\n this.data = new Array(to - from);\n this.rowCount = 0;\n }\n\n setRowCount = (rowCount: number) => {\n if (rowCount < this.data.length) {\n this.data.length = rowCount;\n }\n\n this.rowCount = rowCount;\n };\n\n add(data: DataSourceRow) {\n const [index] = data;\n if (this.isWithinRange(index)) {\n const internalIndex = index - this.range.from;\n this.data[internalIndex] = data;\n\n // assign 'pre-selected' selection state. This allows us to assign a className\n // to a non selected row that immediately precedes a selected row. Useful for\n // styling. This cannot be achieved any other way as document order of row\n // elements does not necessarily reflect data order.\n const isSelected = data[SELECTED];\n const preSelected = this.data[internalIndex - 1]?.[SELECTED];\n if (preSelected === 0 && isSelected) {\n this.data[internalIndex - 1][SELECTED] = 2;\n } else if (preSelected === 2 && !isSelected) {\n this.data[internalIndex - 1][SELECTED] = 0;\n }\n }\n }\n\n getAtIndex(index: number) {\n return this.range.isWithin(index) &&\n this.data[index - this.range.from] != null\n ? this.data[index - this.range.from]\n : undefined;\n }\n\n isWithinRange(index: number) {\n return this.range.isWithin(index);\n }\n\n setRange({ from, to }: VuuRange) {\n if (from !== this.range.from || to !== this.range.to) {\n const [overlapFrom, overlapTo] = this.range.overlap(from, to);\n const newData = new Array(Math.max(0, to - from));\n for (let i = overlapFrom; i < overlapTo; i++) {\n const data = this.getAtIndex(i);\n if (data) {\n const index = i - from;\n newData[index] = data;\n }\n }\n this.data = newData;\n this.range.from = from;\n this.range.to = to;\n }\n }\n\n getSelectedRows() {\n return this.data.filter((row) => row[SELECTED] === 1);\n }\n}\n", "import { useDragDropNext as useDragDrop } from \"@vuu-ui/vuu-ui-controls\";\nimport { MouseEvent, useCallback, useRef } from \"react\";\n\ntype MousePos = {\n clientX: number;\n clientY: number;\n idx: string;\n};\n\nexport interface DraggableColumnHookProps {\n onDrop: (fromIndex: number, toIndex: number) => void;\n}\n\nexport const useDraggableColumn = ({ onDrop }: DraggableColumnHookProps) => {\n const mousePosRef = useRef<MousePos>();\n const containerRef = useRef<HTMLElement | null>(null);\n\n const handleDropSettle = useCallback(() => {\n console.log(`handleDropSettle`);\n mousePosRef.current = undefined;\n containerRef.current = null;\n }, []);\n\n const { draggable, draggedItemIndex, onMouseDown } = useDragDrop({\n // allowDragDrop: \"drop-indicator\",\n allowDragDrop: true,\n draggableClassName: \"vuuTable-headerCell\",\n orientation: \"horizontal\",\n containerRef,\n itemQuery: \".vuuTable-headerCell\",\n onDrop,\n onDropSettle: handleDropSettle,\n });\n\n const onHeaderCellDragStart = useCallback(\n (evt: MouseEvent) => {\n const { clientX, clientY } = evt;\n console.log(\n `useDraggableColumn handleHeaderCellDragStart means mouseDown fired on a column in RowBasedTable`\n );\n const sourceElement = evt.target as HTMLElement;\n const columnHeaderCell = sourceElement.closest(\".vuuTable-headerCell\");\n containerRef.current = columnHeaderCell?.closest(\n \"[role='row']\"\n ) as HTMLDivElement;\n const {\n dataset: { idx = \"-1\" },\n } = columnHeaderCell as HTMLElement;\n mousePosRef.current = {\n clientX,\n clientY,\n idx,\n };\n onMouseDown?.(evt);\n },\n [onMouseDown]\n );\n\n // useLayoutEffect(() => {\n // if (tableLayout === \"column\" && mousePosRef.current && !draggable) {\n // const { clientX, clientY, idx } = mousePosRef.current;\n // const target = tableContainerRef.current?.querySelector(\n // `.vuuTable-table[data-idx=\"${idx}\"]`\n // ) as HTMLElement;\n // if (target) {\n // const evt = {\n // persist: () => undefined,\n // nativeEvent: {\n // clientX,\n // clientY,\n // target,\n // },\n // };\n // onMouseDown?.(evt as unknown as MouseEvent);\n // }\n // }\n // }, [draggable, onMouseDown, tableContainerRef, tableLayout]);\n\n return {\n draggable,\n draggedItemIndex,\n onHeaderCellDragStart,\n };\n};\n", "import { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\nimport { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { withinRange } from \"@vuu-ui/vuu-utils\";\nimport {\n KeyboardEvent,\n MouseEvent,\n RefObject,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport {\n ArrowDown,\n ArrowKey,\n ArrowLeft,\n ArrowRight,\n ArrowUp,\n End,\n Home,\n isNavigationKey,\n isPagingKey,\n NavigationKey,\n PageDown,\n PageUp,\n} from \"./keyUtils\";\nimport { ScrollRequestHandler } from \"./useTableScroll\";\n\nexport type CellPos = [number, number];\n\nconst headerCellQuery = (colIdx: number) =>\n `.vuuTable-headers .vuuTable-headerCell:nth-child(${colIdx + 1})`;\nconst dataCellQuery = (rowIdx: number, colIdx: number) =>\n `.vuuTable-body > [aria-rowindex='${rowIdx}'] > [role='cell']:nth-child(${\n colIdx + 1\n })`;\n\nconst NULL_CELL_POS: CellPos = [-1, -1];\n\nfunction nextCellPos(\n key: ArrowKey,\n [rowIdx, colIdx]: CellPos,\n columnCount: number,\n rowCount: number\n): CellPos {\n if (key === ArrowUp) {\n if (rowIdx > -1) {\n return [rowIdx - 1, colIdx];\n } else {\n return [rowIdx, colIdx];\n }\n } else if (key === ArrowDown) {\n if (rowIdx === -1) {\n return [0, colIdx];\n } else if (rowIdx === rowCount - 1) {\n return [rowIdx, colIdx];\n } else {\n return [rowIdx + 1, colIdx];\n }\n } else if (key === ArrowRight) {\n if (colIdx < columnCount - 1) {\n return [rowIdx, colIdx + 1];\n } else {\n return [rowIdx, colIdx];\n }\n } else if (key === ArrowLeft) {\n if (colIdx > 0) {\n return [rowIdx, colIdx - 1];\n } else {\n return [rowIdx, colIdx];\n }\n }\n return [rowIdx, colIdx];\n}\n\nexport interface NavigationHookProps {\n containerRef: RefObject<HTMLElement>;\n columnCount?: number;\n data: DataSourceRow[];\n disableHighlightOnFocus?: boolean;\n label?: string;\n viewportRange: VuuRange;\n requestScroll?: ScrollRequestHandler;\n restoreLastFocus?: boolean;\n rowCount?: number;\n selected?: unknown;\n}\n\nexport const useKeyboardNavigation = ({\n columnCount = 0,\n containerRef,\n disableHighlightOnFocus,\n data,\n requestScroll,\n rowCount = 0,\n viewportRange,\n}: NavigationHookProps) => {\n const { from: viewportFirstRow, to: viewportLastRow } = viewportRange;\n const focusedCellPos = useRef<CellPos>([-1, -1]);\n const focusableCell = useRef<HTMLTableCellElement>();\n const activeCellPos = useRef<CellPos>([-1, 0]);\n\n const getTableCell = useCallback(\n ([rowIdx, colIdx]: CellPos) => {\n const cssQuery =\n rowIdx === -1 ? headerCellQuery(colIdx) : dataCellQuery(rowIdx, colIdx);\n return containerRef.current?.querySelector(\n cssQuery\n ) as HTMLTableCellElement;\n },\n [containerRef]\n );\n\n const getFocusedCell = (element: HTMLElement | Element | null) =>\n element?.closest(\n \"[role='columnHeader'],[role='cell']\"\n ) as HTMLTableCellElement | null;\n\n const getTableCellPos = (tableCell: HTMLTableCellElement): CellPos => {\n if (tableCell.role === \"columnHeader\") {\n const colIdx = parseInt(tableCell.dataset.idx ?? \"-1\", 10);\n return [-1, colIdx];\n } else {\n const focusedRow = tableCell.closest(\"[role='row']\");\n if (focusedRow) {\n const rowIdx = parseInt(focusedRow.ariaRowIndex ?? \"-1\", 10);\n // TODO will get trickier when we introduce horizontal virtualisation\n const colIdx = Array.from(focusedRow.childNodes).indexOf(tableCell);\n return [rowIdx, colIdx];\n }\n }\n return NULL_CELL_POS;\n };\n\n const focusCell = useCallback(\n (cellPos: CellPos) => {\n if (containerRef.current) {\n const activeCell = getTableCell(cellPos);\n if (activeCell) {\n if (activeCell !== focusableCell.current) {\n focusableCell.current?.setAttribute(\"tabindex\", \"\");\n focusableCell.current = activeCell;\n activeCell.setAttribute(\"tabindex\", \"0\");\n }\n activeCell.focus();\n } else if (!withinRange(cellPos[0], viewportRange)) {\n focusableCell.current = undefined;\n requestScroll?.({ type: \"scroll-page\", direction: \"up\" });\n }\n }\n },\n // TODO we recreate this function whenever viewportRange changes, which will\n // be often whilst scrolling - store range in a a ref ?\n [containerRef, getTableCell, requestScroll, viewportRange]\n );\n\n const setActiveCell = useCallback(\n (rowIdx: number, colIdx: number, fromKeyboard = false) => {\n const pos: CellPos = [rowIdx, colIdx];\n activeCellPos.current = pos;\n focusCell(pos);\n if (fromKeyboard) {\n focusedCellPos.current = pos;\n }\n },\n [focusCell]\n );\n\n const virtualizeActiveCell = useCallback(() => {\n focusableCell.current?.setAttribute(\"tabindex\", \"\");\n focusableCell.current = undefined;\n }, []);\n\n const nextPageItemIdx = useCallback(\n async (\n key: \"PageDown\" | \"PageUp\" | \"Home\" | \"End\",\n cellPos: CellPos\n ): Promise<CellPos> => {\n switch (key) {\n case PageDown:\n requestScroll?.({ type: \"scroll-page\", direction: \"down\" });\n break;\n case PageUp:\n requestScroll?.({ type: \"scroll-page\", direction: \"up\" });\n break;\n case Home:\n requestScroll?.({ type: \"scroll-end\", direction: \"home\" });\n break;\n case End:\n requestScroll?.({ type: \"scroll-end\", direction: \"end\" });\n break;\n }\n // TODO set up a scroll listener here, reset focused cell once scroll completes\n return cellPos;\n },\n [requestScroll]\n );\n\n const handleFocus = useCallback(() => {\n if (disableHighlightOnFocus !== true) {\n if (containerRef.current?.contains(document.activeElement)) {\n // IF focus arrives via keyboard, a cell will have received focus,\n // we handle that here. If focus arrives via click on a cell with\n // no tabindex (i.e all cells except one) we leave that to the\n // click handler.\n const focusedCell = getFocusedCell(document.activeElement);\n if (focusedCell) {\n focusedCellPos.current = getTableCellPos(focusedCell);\n }\n }\n }\n }, [disableHighlightOnFocus, containerRef]);\n\n const navigateChildItems = useCallback(\n async (key: NavigationKey) => {\n const [nextRowIdx, nextColIdx] = isPagingKey(key)\n ? await nextPageItemIdx(key, activeCellPos.current)\n : nextCellPos(key, activeCellPos.current, columnCount, rowCount);\n\n const [rowIdx, colIdx] = activeCellPos.current;\n if (nextRowIdx !== rowIdx || nextColIdx !== colIdx) {\n setActiveCell(nextRowIdx, nextColIdx, true);\n }\n },\n [columnCount, nextPageItemIdx, rowCount, setActiveCell]\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (data.length > 0 && isNavigationKey(e.key)) {\n e.preventDefault();\n e.stopPropagation();\n void navigateChildItems(e.key);\n }\n },\n [data, navigateChildItems]\n );\n\n const handleClick = useCallback(\n // Might not be a cell e.g the Settings button\n (evt: MouseEvent) => {\n const target = evt.target as HTMLElement;\n const focusedCell = getFocusedCell(target);\n if (focusedCell) {\n const [rowIdx, colIdx] = getTableCellPos(focusedCell);\n setActiveCell(rowIdx, colIdx);\n }\n },\n [setActiveCell]\n );\n\n const containerProps = useMemo(() => {\n return {\n onClick: handleClick,\n onFocus: handleFocus,\n onKeyDown: handleKeyDown,\n };\n }, [handleClick, handleFocus, handleKeyDown]);\n\n useLayoutEffect(() => {\n const { current: cellPos } = activeCellPos;\n const withinViewport =\n cellPos[0] >= viewportFirstRow && cellPos[0] <= viewportLastRow;\n\n if (focusableCell.current && !withinViewport) {\n virtualizeActiveCell();\n } else if (!focusableCell.current && withinViewport) {\n focusCell(cellPos);\n }\n }, [focusCell, viewportFirstRow, viewportLastRow, virtualizeActiveCell]);\n\n // First render will only render the outer container when explicit\n // sizing has not been provided. Outer container is measured and\n // only then, on second render, is content rendered.\n const fullyRendered = containerRef.current?.firstChild != null;\n useEffect(() => {\n if (fullyRendered && focusableCell.current === undefined) {\n const headerCell = containerRef.current?.querySelector(\n headerCellQuery(0)\n ) as HTMLTableCellElement;\n if (headerCell) {\n headerCell.setAttribute(\"tabindex\", \"0\");\n focusableCell.current = headerCell;\n }\n }\n }, [containerRef, fullyRendered]);\n\n return containerProps;\n};\n", "import React from \"react\";\n\nfunction union<T>(set1: Set<T>, ...sets: Set<T>[]) {\n const result = new Set(set1);\n for (let set of sets) {\n for (let element of set) {\n result.add(element);\n }\n }\n return result;\n}\n\nexport const ArrowUp = \"ArrowUp\";\nexport const ArrowDown = \"ArrowDown\";\nexport const ArrowLeft = \"ArrowLeft\";\nexport const ArrowRight = \"ArrowRight\";\nexport const Enter = \"Enter\";\nexport const Escape = \"Escape\";\nexport const Home = \"Home\";\nexport const End = \"End\";\nexport const PageUp = \"PageUp\";\nexport const PageDown = \"PageDown\";\nexport const Space = \" \";\nexport const Tab = \"Tab\";\n\nconst actionKeys = new Set([\"Enter\", \"Delete\", \" \"]);\nconst focusKeys = new Set([\"Tab\"]);\nconst arrowLeftRightKeys = new Set([\"ArrowRight\", \"ArrowLeft\"]);\nconst navigationKeys = new Set<NavigationKey>([\n Home,\n End,\n PageUp,\n PageDown,\n ArrowDown,\n ArrowLeft,\n ArrowRight,\n ArrowUp,\n]);\nconst functionKeys = new Set([\n \"F1\",\n \"F2\",\n \"F3\",\n \"F4\",\n \"F5\",\n \"F6\",\n \"F7\",\n \"F8\",\n \"F9\",\n \"F10\",\n \"F11\",\n \"F12\",\n]);\nconst specialKeys = union(\n actionKeys,\n navigationKeys,\n arrowLeftRightKeys,\n functionKeys,\n focusKeys\n);\nexport const isCharacterKey = (evt: React.KeyboardEvent): boolean => {\n if (specialKeys.has(evt.key)) {\n return false;\n }\n return evt.key.length === 1 && !evt.ctrlKey && !evt.metaKey && !evt.altKey;\n};\n\nexport type ArrowKey = \"ArrowUp\" | \"ArrowDown\" | \"ArrowLeft\" | \"ArrowRight\";\nexport type PageKey = \"Home\" | \"End\" | \"PageUp\" | \"PageDown\";\nexport type NavigationKey = PageKey | ArrowKey;\nconst PageKeys = [\"Home\", \"End\", \"PageUp\", \"PageDown\"];\nexport const isPagingKey = (key: string): key is PageKey =>\n PageKeys.includes(key);\n\nexport const isNavigationKey = (key: string): key is NavigationKey => {\n return navigationKeys.has(key as NavigationKey);\n};\n", "import { isValidNumber } from \"@vuu-ui/vuu-utils\";\nimport { RefObject, useCallback, useMemo, useRef, useState } from \"react\";\nimport { useResizeObserver, ResizeHandler } from \"./useResizeObserver\";\n\nconst ClientWidthHeight = [\"clientHeight\", \"clientWidth\"];\n\nexport interface ClientSize {\n clientHeight: number;\n clientWidth: number;\n}\n\nexport interface MeasuredProps {\n defaultHeight?: number;\n defaultWidth?: number;\n height?: number;\n width?: number;\n}\n\nexport interface Size {\n height: number | \"100%\";\n width: number | \"100%\";\n}\n\nexport interface MeasuredSize {\n height: number;\n width: number;\n}\n\ninterface MeasuredState {\n css: CssSize;\n outer: Size;\n inner?: MeasuredSize;\n}\n\nconst isNumber = (val: unknown): val is number => Number.isFinite(val);\n\nexport type CssSize = {\n height: string;\n width: string;\n};\nconst FULL_SIZE: CssSize = { height: \"100%\", width: \"100%\" };\n\nexport interface MeasuredContainerHookResult {\n containerRef: RefObject<HTMLDivElement>;\n cssSize: CssSize;\n outerSize: Size;\n innerSize?: MeasuredSize;\n}\n\n// If (outer) height and width are known at initialisation (i.e. they\n// were passed as props), use as initial values for inner size. If there\n// is no border on Table, these values will not change. If there is a border,\n// inner values will be updated once measured.\nconst getInitialCssSize = (height: unknown, width: unknown): CssSize => {\n if (isValidNumber(height) && isValidNumber(width)) {\n return {\n height: `${height}px`,\n width: `${width}px`,\n };\n } else {\n return FULL_SIZE;\n }\n};\n\nconst getInitialInnerSize = (\n height: unknown,\n width: unknown\n): MeasuredSize | undefined => {\n if (isValidNumber(height) && isValidNumber(width)) {\n return {\n height,\n width,\n };\n }\n};\n\nexport const useMeasuredContainer = ({\n defaultHeight = 0,\n defaultWidth = 0,\n height,\n width,\n}: MeasuredProps): MeasuredContainerHookResult => {\n const containerRef = useRef<HTMLDivElement>(null);\n const [size, setSize] = useState<MeasuredState>({\n css: getInitialCssSize(height, width),\n inner: getInitialInnerSize(height, width),\n outer: {\n height: height ?? \"100%\",\n width: width ?? \"100%\",\n },\n });\n\n useMemo(() => {\n setSize((currentSize) => {\n const { inner, outer } = currentSize;\n if (isValidNumber(height) && isValidNumber(width) && inner && outer) {\n const { height: innerHeight, width: innerWidth } = inner;\n const { height: outerHeight, width: outerWidth } = outer;\n\n if (outerHeight !== height || outerWidth !== width) {\n const heightDiff = isValidNumber(outerHeight)\n ? outerHeight - innerHeight\n : 0;\n const widthDiff = isValidNumber(outerWidth)\n ? outerWidth - innerWidth\n : 0;\n return {\n ...currentSize,\n outer: { height, width },\n inner: { height: height - heightDiff, width: width - widthDiff },\n };\n }\n }\n return currentSize;\n });\n }, [height, width]);\n\n const onResize: ResizeHandler = useCallback(\n ({ clientWidth, clientHeight }: Partial<ClientSize>) => {\n setSize((currentSize) => {\n const { css, inner, outer } = currentSize;\n return isNumber(clientHeight) &&\n isNumber(clientWidth) &&\n (clientWidth !== inner?.width || clientHeight !== inner?.height)\n ? {\n css,\n outer,\n inner: {\n width: Math.floor(clientWidth) || defaultWidth,\n height: Math.floor(clientHeight) || defaultHeight,\n },\n }\n : currentSize;\n });\n },\n [defaultHeight, defaultWidth]\n );\n\n useResizeObserver(containerRef, ClientWidthHeight, onResize, true);\n\n return {\n containerRef,\n cssSize: size.css,\n outerSize: size.outer,\n innerSize: size.inner,\n };\n};\n", "import { RefObject, useCallback, useEffect, useRef } from \"react\";\n\nexport const WidthHeight = [\"height\", \"width\"];\nexport const WidthOnly = [\"width\"];\n\nexport type measurements<T = string | number> = {\n height?: T;\n clientHeight?: number;\n clientWidth?: number;\n contentHeight?: number;\n contentWidth?: number;\n scrollHeight?: number;\n scrollWidth?: number;\n width?: T;\n};\ntype measuredDimension = keyof measurements<number>;\n\nexport type ResizeHandler = (measurements: measurements<number>) => void;\n\ntype observedDetails = {\n onResize?: ResizeHandler;\n measurements: measurements<number>;\n};\nconst observedMap = new Map<HTMLElement, observedDetails>();\n\nconst getTargetSize = (\n element: HTMLElement,\n size: {\n height: number;\n width: number;\n contentHeight: number;\n contentWidth: number;\n },\n dimension: measuredDimension\n): number => {\n switch (dimension) {\n case \"height\":\n return size.height;\n case \"clientHeight\":\n return element.clientHeight;\n case \"clientWidth\":\n return element.clientWidth;\n case \"contentHeight\":\n return size.contentHeight;\n case \"contentWidth\":\n return size.contentWidth;\n case \"scrollHeight\":\n return Math.ceil(element.scrollHeight);\n case \"scrollWidth\":\n return Math.ceil(element.scrollWidth);\n case \"width\":\n return size.width;\n default:\n return 0;\n }\n};\n\n// TODO should we make this create-on-demand\nconst resizeObserver = new ResizeObserver((entries: ResizeObserverEntry[]) => {\n for (const entry of entries) {\n const { target, borderBoxSize, contentBoxSize } = entry;\n const observedTarget = observedMap.get(target as HTMLElement);\n if (observedTarget) {\n const [{ blockSize: height, inlineSize: width }] = borderBoxSize;\n const [{ blockSize: contentHeight, inlineSize: contentWidth }] =\n contentBoxSize;\n const { onResize, measurements } = observedTarget;\n let sizeChanged = false;\n for (const [dimension, size] of Object.entries(measurements)) {\n const newSize = getTargetSize(\n target as HTMLElement,\n { height, width, contentHeight, contentWidth },\n dimension as measuredDimension\n );\n\n if (newSize !== size) {\n sizeChanged = true;\n measurements[dimension as measuredDimension] = newSize;\n }\n }\n if (sizeChanged) {\n // TODO only return measured sizes\n onResize && onResize(measurements);\n }\n }\n }\n});\n\n// TODO use an optional lag (default to false) to ask to fire onResize\n// with initial size\nexport function useResizeObserver(\n ref: RefObject<Element | HTMLElement | null>,\n dimensions: string[],\n onResize: ResizeHandler,\n reportInitialSize = false\n) {\n const dimensionsRef = useRef(dimensions);\n\n const measure = useCallback((target: HTMLElement): measurements<number> => {\n const { width, height } = target.getBoundingClientRect();\n const { clientWidth: contentWidth, clientHeight: contentHeight } = target;\n return dimensionsRef.current.reduce(\n (map: { [key: string]: number }, dim) => {\n map[dim] = getTargetSize(\n target,\n { width, height, contentHeight, contentWidth },\n dim as measuredDimension\n );\n return map;\n },\n {}\n );\n }, []);\n\n // TODO use ref to store resizeHandler here\n // resize handler registered with REsizeObserver will never change\n // use ref to store user onResize callback here\n // resizeHandler will call user callback.current\n\n // Keep this effect separate in case user inadvertently passes different\n // dimensions or callback instance each time - we only ever want to\n // initiate new observation when ref changes.\n useEffect(() => {\n const target = ref.current as HTMLElement;\n async function registerObserver() {\n // Create the map entry immediately. useEffect may fire below\n // before fonts are ready and attempt to update entry\n observedMap.set(target, { measurements: {} as measurements<number> });\n await document.fonts.ready;\n const observedTarget = observedMap.get(target);\n if (observedTarget) {\n const measurements = measure(target);\n observedTarget.measurements = measurements;\n resizeObserver.observe(target);\n if (reportInitialSize) {\n onResize(measurements);\n }\n } else {\n console.log(\n `%cuseResizeObserver an target expected to be under observation wa snot found. This warrants investigation`,\n \"font-weight:bold; color:red;\"\n );\n }\n }\n\n if (target) {\n // TODO might we want multiple callers to attach a listener to the same element ?\n if (observedMap.has(target)) {\n throw Error(\n \"useResizeObserver attemping to observe same element twice\"\n );\n }\n // TODO set a pending entry on map\n registerObserver();\n }\n return () => {\n if (target && observedMap.has(target)) {\n resizeObserver.unobserve(target);\n observedMap.delete(target);\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [measure, ref]);\n\n useEffect(() => {\n const target = ref.current as HTMLElement;\n const record = observedMap.get(target);\n if (record) {\n if (dimensionsRef.current !== dimensions) {\n dimensionsRef.current = dimensions;\n const measurements = measure(target);\n record.measurements = measurements;\n }\n // Might not have changed, but no harm ...\n record.onResize = onResize;\n }\n }, [dimensions, measure, ref, onResize]);\n}\n", "import {\n Selection,\n SelectionChangeHandler,\n TableSelectionModel,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n deselectItem,\n isRowSelected,\n metadataKeys,\n selectItem,\n} from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useRef } from \"react\";\nimport { RowClickHandler } from \"./dataTableTypes\";\n\nconst { IDX } = metadataKeys;\n\nconst NO_SELECTION: Selection = [];\n\nexport interface SelectionHookProps {\n selectionModel: TableSelectionModel;\n onSelectionChange: SelectionChangeHandler;\n}\n\nexport const useSelection = ({\n selectionModel,\n onSelectionChange,\n}: SelectionHookProps) => {\n selectionModel === \"extended\" || selectionModel === \"checkbox\";\n const lastActiveRef = useRef(-1);\n const selectedRef = useRef<Selection>(NO_SELECTION);\n\n const handleSelectionChange: RowClickHandler = useCallback(\n (row, rangeSelect, keepExistingSelection) => {\n const { [IDX]: idx } = row;\n const { current: active } = lastActiveRef;\n const { current: selected } = selectedRef;\n\n const selectOperation = isRowSelected(row) ? deselectItem : selectItem;\n\n const newSelected = selectOperation(\n selectionModel,\n selected,\n idx,\n rangeSelect,\n keepExistingSelection,\n active\n );\n\n selectedRef.current = newSelected;\n lastActiveRef.current = idx;\n\n if (onSelectionChange) {\n onSelectionChange(newSelected);\n }\n },\n [onSelectionChange, selectionModel]\n );\n\n return handleSelectionChange;\n};\n", "import {\n ColumnDescriptor,\n GridConfig,\n KeyedColumnDescriptor,\n PinLocation,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n applyFilterToColumns,\n applyGroupByToColumns,\n applySortToColumns,\n findColumn,\n getCellRenderer,\n getColumnName,\n getTableHeadings,\n getValueFormatter,\n isFilteredColumn,\n isGroupColumn,\n isPinned,\n isTypeDescriptor,\n metadataKeys,\n updateColumn,\n sortPinnedColumns,\n stripFilterFromColumns,\n moveItem,\n} from \"@vuu-ui/vuu-utils\";\n\nimport { Reducer, useReducer } from \"react\";\nimport { VuuColumnDataType } from \"@vuu-ui/vuu-protocol-types\";\nimport { DataSourceConfig } from \"@vuu-ui/vuu-data\";\nimport { TableSchema } from \"@vuu-ui/vuu-data/src/message-utils\";\n\nconst DEFAULT_COLUMN_WIDTH = 100;\nconst KEY_OFFSET = metadataKeys.count;\n\nconst columnWithoutDataType = ({ serverDataType }: ColumnDescriptor) =>\n serverDataType === undefined;\n\nconst getCellRendererForColumn = (column: ColumnDescriptor) => {\n if (isTypeDescriptor(column.type)) {\n return getCellRenderer(column.type?.renderer);\n }\n};\n\nconst getServerDataTypeForColumn = (\n column: ColumnDescriptor,\n tableSchema?: TableSchema\n): VuuColumnDataType => {\n if (column.serverDataType) {\n return column.serverDataType;\n } else if (tableSchema) {\n const schemaColumn = tableSchema.columns.find(\n (col) => col.name === column.name\n );\n if (schemaColumn) {\n return schemaColumn.serverDataType;\n }\n }\n return \"string\";\n};\n\nexport interface TableModel extends Omit<GridConfig, \"columns\"> {\n columns: KeyedColumnDescriptor[];\n tableSchema?: Readonly<TableSchema>;\n}\n\nconst numericTypes = [\"int\", \"long\", \"double\"];\nconst getDefaultAlignment = (serverDataType?: VuuColumnDataType) =>\n serverDataType === undefined\n ? undefined\n : numericTypes.includes(serverDataType)\n ? \"right\"\n : \"left\";\n\nexport interface ColumnActionInit {\n type: \"init\";\n tableConfig: Omit<GridConfig, \"headings\">;\n dataSourceConfig?: DataSourceConfig;\n}\n\nexport interface ColumnActionHide {\n type: \"hideColumns\";\n columns: KeyedColumnDescriptor[];\n}\n\nexport interface ColumnActionShow {\n type: \"showColumns\";\n columns: KeyedColumnDescriptor[];\n}\nexport interface ColumnActionMove {\n type: \"moveColumn\";\n column: KeyedColumnDescriptor;\n moveBy?: 1 | -1;\n moveTo?: number;\n}\n\nexport interface ColumnActionPin {\n type: \"pinColumn\";\n column: ColumnDescriptor;\n pin?: PinLocation;\n}\nexport interface ColumnActionResize {\n type: \"resizeColumn\";\n column: KeyedColumnDescriptor;\n phase: \"begin\" | \"resize\" | \"end\";\n width?: number;\n}\n\nexport interface ColumnActionSetTableSchema {\n type: \"setTableSchema\";\n tableSchema: TableSchema;\n}\n\nexport interface ColumnActionUpdate {\n type: \"updateColumn\";\n column: ColumnDescriptor;\n}\n\nexport interface ColumnActionUpdateProp {\n align?: ColumnDescriptor[\"align\"];\n column: KeyedColumnDescriptor;\n hidden?: ColumnDescriptor[\"hidden\"];\n label?: ColumnDescriptor[\"label\"];\n resizing?: KeyedColumnDescriptor[\"resizing\"];\n type: \"updateColumnProp\";\n width?: ColumnDescriptor[\"width\"];\n}\n\nexport interface ColumnActionTableConfig extends DataSourceConfig {\n confirmed?: boolean;\n type: \"tableConfig\";\n}\nexport interface ColumnActionColumnSettings extends DataSourceConfig {\n type: \"columnSettings\";\n column: KeyedColumnDescriptor;\n}\n\nexport interface ColumnActionTableSettings extends DataSourceConfig {\n type: \"tableSettings\";\n}\n\n/**\n * PersistentColumnActions are those actions that require us to persist user changes across sessions\n */\nexport type PersistentColumnAction =\n | ColumnActionPin\n | ColumnActionHide\n | ColumnActionColumnSettings\n | ColumnActionTableSettings;\n\nexport const isShowColumnSettings = (\n action: PersistentColumnAction\n): action is ColumnActionColumnSettings => action.type === \"columnSettings\";\n\nexport const isShowTableSettings = (\n action: PersistentColumnAction\n): action is ColumnActionTableSettings => action.type === \"tableSettings\";\n\nexport type GridModelAction =\n | ColumnActionColumnSettings\n | ColumnActionHide\n | ColumnActionInit\n | ColumnActionMove\n | ColumnActionPin\n | ColumnActionResize\n | ColumnActionSetTableSchema\n | ColumnActionShow\n | ColumnActionUpdate\n | ColumnActionUpdateProp\n | ColumnActionTableConfig;\n\nexport type GridModelReducer = Reducer<TableModel, GridModelAction>;\n\nexport type ColumnActionDispatch = (action: GridModelAction) => void;\n\nconst columnReducer: GridModelReducer = (state, action) => {\n // info?.(`GridModelReducer ${action.type}`);\n switch (action.type) {\n case \"init\":\n return init(action);\n case \"moveColumn\":\n return moveColumn(state, action);\n case \"resizeColumn\":\n return resizeColumn(state, action);\n case \"setTableSchema\":\n return setTableSchema(state, action);\n case \"hideColumns\":\n return hideColumns(state, action);\n case \"showColumns\":\n return showColumns(state, action);\n case \"pinColumn\":\n return pinColumn(state, action);\n case \"updateColumnProp\":\n return updateColumnProp(state, action);\n case \"tableConfig\":\n return updateTableConfig(state, action);\n default:\n console.log(`unhandled action ${action.type}`);\n return state;\n }\n};\n\nexport const useTableModel = (\n tableConfig: Omit<GridConfig, \"headings\">,\n dataSourceConfig?: DataSourceConfig\n) => {\n const [state, dispatchColumnAction] = useReducer<\n GridModelReducer,\n InitialConfig\n >(columnReducer, { tableConfig, dataSourceConfig }, init);\n\n return {\n columns: state.columns,\n dispatchColumnAction,\n headings: state.headings,\n };\n};\n\ntype InitialConfig = {\n dataSourceConfig?: DataSourceConfig;\n tableConfig: Omit<GridConfig, \"headings\">;\n};\n\nfunction init({ dataSourceConfig, tableConfig }: InitialConfig): TableModel {\n const columns = tableConfig.columns.map(\n toKeyedColumWithDefaults(tableConfig)\n );\n const maybePinnedColumns = columns.some(isPinned)\n ? sortPinnedColumns(columns)\n : columns;\n const state = {\n columns: maybePinnedColumns,\n headings: getTableHeadings(maybePinnedColumns),\n };\n if (dataSourceConfig) {\n const { columns, ...rest } = dataSourceConfig;\n return updateTableConfig(state, {\n type: \"tableConfig\",\n ...rest,\n });\n } else {\n return state;\n }\n}\n\nconst getLabel = (\n label: string,\n columnFormatHeader?: \"uppercase\" | \"capitalize\"\n): string => {\n if (columnFormatHeader === \"uppercase\") {\n return label.toUpperCase();\n } else if (columnFormatHeader === \"capitalize\") {\n return label[0].toUpperCase() + label.slice(1).toLowerCase();\n }\n return label;\n};\n\nconst toKeyedColumWithDefaults =\n (options: Partial<TableModel> | Partial<GridConfig>) =>\n (\n column: ColumnDescriptor & { key?: number },\n index: number\n ): KeyedColumnDescriptor => {\n const serverDataType = getServerDataTypeForColumn(\n column,\n (options as Partial<TableModel>).tableSchema\n );\n const { columnDefaultWidth = DEFAULT_COLUMN_WIDTH, columnFormatHeader } =\n options;\n const {\n align = getDefaultAlignment(serverDataType),\n key,\n name,\n label = name,\n width = columnDefaultWidth,\n ...rest\n } = column;\n\n const keyedColumnWithDefaults = {\n ...rest,\n align,\n CellRenderer: getCellRendererForColumn(column),\n label: getLabel(label, columnFormatHeader),\n key: key ?? index + KEY_OFFSET,\n name,\n originalIdx: index,\n serverDataType,\n valueFormatter: getValueFormatter(column),\n width: width,\n };\n\n if (isGroupColumn(keyedColumnWithDefaults)) {\n keyedColumnWithDefaults.columns = keyedColumnWithDefaults.columns.map(\n (col) => toKeyedColumWithDefaults(options)(col, col.key)\n );\n }\n\n return keyedColumnWithDefaults;\n };\n\nfunction moveColumn(\n state: TableModel,\n { column, moveBy, moveTo }: ColumnActionMove\n) {\n const { columns } = state;\n if (typeof moveBy === \"number\") {\n const idx = columns.indexOf(column);\n const newColumns = columns.slice();\n const [movedColumns] = newColumns.splice(idx, 1);\n newColumns.splice(idx + moveBy, 0, movedColumns);\n return {\n ...state,\n columns: newColumns,\n };\n } else if (typeof moveTo === \"number\") {\n return {\n ...state,\n columns: moveItem(columns, column, moveTo),\n };\n }\n return state;\n}\n\nfunction hideColumns(state: TableModel, { columns }: ColumnActionHide) {\n if (columns.some((col) => col.hidden !== true)) {\n return columns.reduce<TableModel>((s, c) => {\n if (c.hidden !== true) {\n return updateColumnProp(s, {\n type: \"updateColumnProp\",\n column: c,\n hidden: true,\n });\n } else {\n return s;\n }\n }, state);\n } else {\n return state;\n }\n}\nfunction showColumns(state: TableModel, { columns }: ColumnActionShow) {\n if (columns.some((col) => col.hidden)) {\n return columns.reduce<TableModel>((s, c) => {\n if (c.hidden) {\n return updateColumnProp(s, {\n type: \"updateColumnProp\",\n column: c,\n hidden: false,\n });\n } else {\n return s;\n }\n }, state);\n } else {\n return state;\n }\n}\n\nfunction resizeColumn(\n state: TableModel,\n { column, phase, width }: ColumnActionResize\n) {\n const type = \"updateColumnProp\";\n const resizing = phase !== \"end\";\n\n switch (phase) {\n case \"begin\":\n return updateColumnProp(state, { type, column, resizing });\n case \"end\":\n return updateColumnProp(state, { type, column, resizing, width });\n case \"resize\":\n return updateColumnProp(state, { type, column, width });\n default:\n throw Error(`useTableModel.resizeColumn, invalid resizePhase ${phase}`);\n }\n}\n\nfunction setTableSchema(\n state: TableModel,\n { tableSchema }: ColumnActionSetTableSchema\n) {\n const { columns } = state;\n if (columns.some(columnWithoutDataType)) {\n const cols = columns.map((column) => {\n const serverDataType = getServerDataTypeForColumn(column, tableSchema);\n return {\n ...column,\n align: column.align ?? getDefaultAlignment(serverDataType),\n serverDataType,\n };\n });\n\n return {\n ...state,\n columns: cols,\n tableSchema,\n };\n } else {\n return {\n ...state,\n tableSchema,\n };\n }\n}\n\nfunction pinColumn(state: TableModel, action: ColumnActionPin) {\n let { columns } = state;\n const { column, pin } = action;\n columns = updateColumn(columns, column.name, { pin });\n columns = sortPinnedColumns(columns);\n console.log({ withPins: columns });\n return {\n ...state,\n columns,\n };\n}\nfunction updateColumnProp(state: TableModel, action: ColumnActionUpdateProp) {\n let { columns } = state;\n const { align, column, hidden, label, resizing, width } = action;\n const options: Partial<KeyedColumnDescriptor> = {};\n\n if (align === \"left\" || align === \"right\") {\n options.align = align;\n }\n if (typeof label === \"string\") {\n options.label = label;\n }\n if (typeof resizing === \"boolean\") {\n options.resizing = resizing;\n }\n if (typeof hidden === \"boolean\") {\n options.hidden = hidden;\n }\n if (typeof width === \"number\") {\n options.width = width;\n }\n\n columns = updateColumn(columns, column.name, options);\n\n return {\n ...state,\n columns,\n };\n}\n\nfunction updateTableConfig(\n state: TableModel,\n { columns, confirmed, filter, groupBy, sort }: ColumnActionTableConfig\n) {\n const hasColumns = columns && columns.length > 0;\n const hasGroupBy = groupBy !== undefined;\n const hasFilter = typeof filter?.filter === \"string\";\n const hasSort = sort && sort.sortDefs.length > 0;\n\n //TODO check if just confirmed has changed\n\n let result = state;\n\n if (hasColumns) {\n result = {\n ...state,\n columns: columns.map((colName, index) => {\n const columnName = getColumnName(colName);\n const key: number = index + KEY_OFFSET;\n const col = findColumn(result.columns, columnName);\n if (col) {\n if (col.key === key) {\n return col;\n } else {\n return {\n ...col,\n key,\n };\n }\n } else {\n // we have a column which was not previously included.\n // TODO How do we get the serverDataType\n // TODO it needs to be available in availableCOlumns or allColumns in state\n return toKeyedColumWithDefaults(state)(\n {\n name: colName,\n },\n index\n );\n }\n throw Error(`useTableModel column ${colName} not found`);\n }),\n };\n }\n\n if (hasGroupBy) {\n result = {\n ...state,\n columns: applyGroupByToColumns(result.columns, groupBy, confirmed),\n };\n }\n\n if (hasSort) {\n result = {\n ...state,\n columns: applySortToColumns(result.columns, sort),\n };\n }\n\n if (hasFilter) {\n result = {\n ...state,\n columns: applyFilterToColumns(result.columns, filter),\n };\n } else if (result.columns.some(isFilteredColumn)) {\n result = {\n ...state,\n columns: stripFilterFromColumns(result.columns),\n };\n }\n\n return result;\n}\n", "import { useCallback, useRef } from \"react\";\nimport { Viewport } from \"./dataTableTypes\";\n\nexport interface ScrollRequestEnd {\n type: \"scroll-end\";\n direction: \"home\" | \"end\";\n}\n\nexport interface ScrollRequestPage {\n type: \"scroll-page\";\n direction: \"up\" | \"down\";\n}\n\nexport interface ScrollRequestDistance {\n type: \"scroll-distance\";\n distance: number;\n}\n\nexport type ScrollRequest =\n | ScrollRequestPage\n | ScrollRequestDistance\n | ScrollRequestEnd;\n\nexport type ScrollRequestHandler = (request: ScrollRequest) => void;\n\nconst getPctScroll = (container: HTMLElement) => {\n const { scrollLeft, scrollTop } = container;\n const { clientHeight, clientWidth, scrollHeight, scrollWidth } = container;\n const pctScrollLeft = scrollLeft / (scrollWidth - clientWidth);\n const pctScrollTop = scrollTop / (scrollHeight - clientHeight);\n\n return [pctScrollLeft, pctScrollTop];\n};\n\nconst getMaxScroll = (container: HTMLElement) => {\n const { clientHeight, clientWidth, scrollHeight, scrollWidth } = container;\n return [scrollWidth - clientWidth, scrollHeight - clientHeight];\n};\n\ninterface CallbackRefHookProps<T = HTMLElement> {\n onAttach?: (el: T) => void;\n onDetach: (el: T) => void;\n label?: string;\n}\n\nconst useCallbackRef = <T = HTMLElement>({\n onAttach,\n onDetach,\n}: CallbackRefHookProps<T>) => {\n const ref = useRef<T | null>(null);\n const callbackRef = useCallback(\n (el: T | null) => {\n if (el) {\n ref.current = el;\n onAttach?.(el);\n } else if (ref.current) {\n const { current: originalRef } = ref;\n ref.current = el;\n onDetach?.(originalRef);\n }\n },\n [onAttach, onDetach]\n );\n return callbackRef;\n};\n\nexport interface TableScrollHookProps {\n onHorizontalScroll?: (scrollLeft: number) => void;\n onVerticalScroll?: (scrollTop: number, pctScrollTop: number) => void;\n viewportHeight: number;\n viewport: Viewport;\n}\n\nexport const useTableScroll = ({\n onHorizontalScroll,\n onVerticalScroll,\n viewport,\n}: TableScrollHookProps) => {\n const contentContainerScrolledRef = useRef(false);\n\n const scrollPosRef = useRef({ scrollTop: 0, scrollLeft: 0 });\n const scrollbarContainerRef = useRef<HTMLDivElement | null>(null);\n const contentContainerRef = useRef<HTMLDivElement | null>(null);\n const {\n maxScrollContainerScrollHorizontal: maxScrollLeft,\n maxScrollContainerScrollVertical: maxScrollTop,\n } = viewport;\n\n const handleScrollbarContainerScroll = useCallback(() => {\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n const { current: contentContainerScrolled } = contentContainerScrolledRef;\n if (contentContainerScrolled) {\n contentContainerScrolledRef.current = false;\n } else if (contentContainer && scrollbarContainer) {\n const [pctScrollLeft, pctScrollTop] = getPctScroll(scrollbarContainer);\n const [maxScrollLeft, maxScrollTop] = getMaxScroll(contentContainer);\n const rootScrollLeft = Math.round(pctScrollLeft * maxScrollLeft);\n const rootScrollTop = Math.round(pctScrollTop * maxScrollTop);\n console.log(\n `pctScrollTop ${pctScrollTop}, maxScrollTop ${maxScrollTop} rootScrollTop ${rootScrollTop}`\n );\n\n contentContainer.scrollTo({\n left: rootScrollLeft,\n top: rootScrollTop,\n behavior: \"auto\",\n });\n }\n }, []);\n\n const handleContentContainerScroll = useCallback(() => {\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n const { current: scrollPos } = scrollPosRef;\n\n if (contentContainer && scrollbarContainer) {\n const { scrollLeft, scrollTop } = contentContainer;\n const [pctScrollLeft, pctScrollTop] = getPctScroll(contentContainer);\n contentContainerScrolledRef.current = true;\n\n scrollbarContainer.scrollLeft = Math.round(pctScrollLeft * maxScrollLeft);\n scrollbarContainer.scrollTop = Math.round(pctScrollTop * maxScrollTop);\n\n if (scrollPos.scrollTop !== scrollTop) {\n scrollPos.scrollTop = scrollTop;\n onVerticalScroll?.(scrollTop, pctScrollTop);\n }\n if (scrollPos.scrollLeft !== scrollLeft) {\n scrollPos.scrollLeft = scrollLeft;\n onHorizontalScroll?.(scrollLeft);\n }\n }\n }, [maxScrollLeft, maxScrollTop, onHorizontalScroll, onVerticalScroll]);\n\n const handleAttachScrollbarContainer = useCallback(\n (el: HTMLDivElement) => {\n scrollbarContainerRef.current = el;\n el.addEventListener(\"scroll\", handleScrollbarContainerScroll, {\n passive: true,\n });\n },\n [handleScrollbarContainerScroll]\n );\n\n const handleDetachScrollbarContainer = useCallback(\n (el: HTMLDivElement) => {\n scrollbarContainerRef.current = null;\n el.removeEventListener(\"scroll\", handleScrollbarContainerScroll);\n },\n [handleScrollbarContainerScroll]\n );\n\n const handleAttachContentContainer = useCallback(\n (el: HTMLDivElement) => {\n contentContainerRef.current = el;\n el.addEventListener(\"scroll\", handleContentContainerScroll, {\n passive: true,\n });\n },\n [handleContentContainerScroll]\n );\n\n const handleDetachContentContainer = useCallback(\n (el: HTMLDivElement) => {\n contentContainerRef.current = null;\n el.removeEventListener(\"scroll\", handleContentContainerScroll);\n },\n [handleContentContainerScroll]\n );\n\n const contentContainerCallbackRef = useCallbackRef({\n onAttach: handleAttachContentContainer,\n onDetach: handleDetachContentContainer,\n });\n\n const scrollbarContainerCallbackRef = useCallbackRef({\n onAttach: handleAttachScrollbarContainer,\n onDetach: handleDetachScrollbarContainer,\n });\n\n const requestScroll: ScrollRequestHandler = useCallback(\n (scrollRequest) => {\n const { current: scrollbarContainer } = contentContainerRef;\n if (scrollbarContainer) {\n contentContainerScrolledRef.current = false;\n if (scrollRequest.type === \"scroll-page\") {\n const { clientHeight, scrollLeft, scrollTop } = scrollbarContainer;\n const { direction } = scrollRequest;\n const scrollBy = direction === \"down\" ? clientHeight : -clientHeight;\n const newScrollTop = Math.min(\n Math.max(0, scrollTop + scrollBy),\n maxScrollTop\n );\n scrollbarContainer.scrollTo({\n top: newScrollTop,\n left: scrollLeft,\n behavior: \"auto\",\n });\n } else if (scrollRequest.type === \"scroll-end\") {\n const { direction } = scrollRequest;\n const scrollTo = direction === \"end\" ? maxScrollTop : 0;\n scrollbarContainer.scrollTo({\n top: scrollTo,\n left: scrollbarContainer.scrollLeft,\n behavior: \"auto\",\n });\n }\n }\n },\n [maxScrollTop]\n );\n\n return {\n /** Ref to be assigned to ScrollbarContainer */\n scrollbarContainerRef: scrollbarContainerCallbackRef,\n /** Ref to be assigned to ContentContainer */\n contentContainerRef: contentContainerCallbackRef,\n /** Scroll the table */\n requestScroll,\n };\n};\n", "/**\n * This hook measures and calculates the values needed to manage layout\n * and virtualisation of the table. This includes measurements required\n * to support pinned columns.\n */\nimport {\n KeyedColumnDescriptor,\n TableHeadings,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport { useCallback, useMemo, useRef } from \"react\";\nimport { MeasuredSize, Size } from \"./useMeasuredContainer\";\nimport {\n actualRowPositioning,\n RowAtPositionFunc,\n RowOffsetFunc,\n RowPositioning,\n virtualRowPositioning,\n} from \"@vuu-ui/vuu-utils\";\n\nexport interface TableViewportHookProps {\n columns: KeyedColumnDescriptor[];\n headerHeight: number;\n headings: TableHeadings;\n rowCount: number;\n rowHeight: number;\n size?: MeasuredSize;\n}\n\nexport interface ViewportMeasurements {\n contentHeight: number;\n horizontalScrollbarHeight: number;\n maxScrollContainerScrollHorizontal: number;\n maxScrollContainerScrollVertical: number;\n pinnedWidthLeft: number;\n pinnedWidthRight: number;\n rowCount: number;\n contentWidth: number;\n totalHeaderHeight: number;\n verticalScrollbarWidth: number;\n viewportBodyHeight: number;\n}\n\nexport interface TableViewportHookResult extends ViewportMeasurements {\n getRowAtPosition: RowAtPositionFunc;\n getRowOffset: RowOffsetFunc;\n setPctScrollTop: (scrollPct: number) => void;\n}\n\n// Too simplistic, it depends on rowHeight\nconst MAX_RAW_ROWS = 1_500_000;\n\nconst UNMEASURED_VIEWPORT: TableViewportHookResult = {\n contentHeight: 0,\n contentWidth: 0,\n getRowAtPosition: () => -1,\n getRowOffset: () => -1,\n horizontalScrollbarHeight: 0,\n maxScrollContainerScrollHorizontal: 0,\n maxScrollContainerScrollVertical: 0,\n pinnedWidthLeft: 0,\n pinnedWidthRight: 0,\n rowCount: 0,\n setPctScrollTop: () => undefined,\n totalHeaderHeight: 0,\n verticalScrollbarWidth: 0,\n viewportBodyHeight: 0,\n};\n\nconst measurePinnedColumns = (columns: KeyedColumnDescriptor[]) => {\n let pinnedWidthLeft = 0;\n let pinnedWidthRight = 0;\n let unpinnedWidth = 0;\n for (const column of columns) {\n const { hidden, pin, width } = column;\n const visibleWidth = hidden ? 0 : width;\n if (pin === \"left\") {\n pinnedWidthLeft += visibleWidth;\n } else if (pin === \"right\") {\n pinnedWidthRight += visibleWidth;\n } else {\n unpinnedWidth += visibleWidth;\n }\n }\n return {\n pinnedWidthLeft: pinnedWidthLeft + 4,\n pinnedWidthRight: pinnedWidthRight + 4,\n unpinnedWidth,\n };\n};\n\nexport const useTableViewport = ({\n columns,\n headerHeight,\n headings,\n rowCount,\n rowHeight,\n size,\n}: TableViewportHookProps): TableViewportHookResult => {\n const pctScrollTopRef = useRef(0);\n const appliedRowCount = Math.min(rowCount, MAX_RAW_ROWS);\n const appliedContentHeight = appliedRowCount * rowHeight;\n const virtualContentHeight = rowCount * rowHeight;\n const virtualisedExtent = virtualContentHeight - appliedContentHeight;\n\n const { pinnedWidthLeft, pinnedWidthRight, unpinnedWidth } = useMemo(\n () => measurePinnedColumns(columns),\n [columns]\n );\n\n const [actualRowOffset, actualRowAtPosition] = useMemo<RowPositioning>(\n () => actualRowPositioning(rowHeight),\n [rowHeight]\n );\n\n const [getRowOffset, getRowAtPosition] = useMemo<RowPositioning>(() => {\n if (virtualisedExtent) {\n return virtualRowPositioning(\n rowHeight,\n virtualisedExtent,\n pctScrollTopRef\n );\n } else {\n return [actualRowOffset, actualRowAtPosition];\n }\n }, [actualRowAtPosition, actualRowOffset, virtualisedExtent, rowHeight]);\n\n const setPctScrollTop = useCallback((scrollPct: number) => {\n pctScrollTopRef.current = scrollPct;\n }, []);\n\n return useMemo(() => {\n if (size) {\n const headingsDepth = headings.length;\n const scrollbarSize = 15;\n const contentWidth = pinnedWidthLeft + unpinnedWidth + pinnedWidthRight;\n const horizontalScrollbarHeight =\n contentWidth > size.width ? scrollbarSize : 0;\n const totalHeaderHeight = headerHeight * (1 + headingsDepth);\n const maxScrollContainerScrollVertical =\n appliedContentHeight -\n ((size?.height ?? 0) - horizontalScrollbarHeight) +\n totalHeaderHeight;\n const maxScrollContainerScrollHorizontal =\n contentWidth - size.width + pinnedWidthLeft;\n const visibleRows = (size.height - headerHeight) / rowHeight;\n const count = Number.isInteger(visibleRows)\n ? visibleRows + 1\n : Math.ceil(visibleRows);\n const viewportBodyHeight = size.height - totalHeaderHeight;\n const verticalScrollbarWidth =\n appliedContentHeight > viewportBodyHeight ? scrollbarSize : 0;\n\n return {\n contentHeight: appliedContentHeight,\n getRowAtPosition,\n getRowOffset,\n horizontalScrollbarHeight,\n maxScrollContainerScrollHorizontal,\n maxScrollContainerScrollVertical,\n pinnedWidthLeft,\n pinnedWidthRight,\n rowCount: count,\n contentWidth,\n setPctScrollTop,\n totalHeaderHeight,\n verticalScrollbarWidth,\n viewportBodyHeight,\n };\n } else {\n return UNMEASURED_VIEWPORT;\n }\n }, [\n size,\n headings.length,\n pinnedWidthLeft,\n unpinnedWidth,\n pinnedWidthRight,\n appliedContentHeight,\n headerHeight,\n rowHeight,\n getRowAtPosition,\n getRowOffset,\n setPctScrollTop,\n ]);\n};\n", "import { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n getColumnsInViewport,\n itemsChanged,\n RowAtPositionFunc,\n} from \"@vuu-ui/vuu-utils\";\nimport { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { ViewportMeasurements } from \"./useTableViewport\";\n\nexport interface VirtualViewportHookProps {\n columns: KeyedColumnDescriptor[];\n getRowAtPosition: RowAtPositionFunc;\n setRange: (range: VuuRange) => void;\n viewportMeasurements: ViewportMeasurements;\n}\nexport interface VirtualViewportHookResult {\n onHorizontalScroll: (scrollLeft: number) => void;\n onVerticalScroll: (scrollTop: number) => void;\n columnsWithinViewport: KeyedColumnDescriptor[];\n virtualColSpan: number;\n}\n\nexport const useVirtualViewport = ({\n columns,\n getRowAtPosition,\n setRange,\n viewportMeasurements,\n}: VirtualViewportHookProps): VirtualViewportHookResult => {\n const firstRowRef = useRef<number>(-1);\n const {\n rowCount: viewportRowCount,\n contentWidth,\n maxScrollContainerScrollHorizontal,\n } = viewportMeasurements;\n // double check this ...\n const availableWidth = contentWidth - maxScrollContainerScrollHorizontal;\n const scrollLeftRef = useRef(0);\n\n const [visibleColumns, preSpan] = useMemo(\n () =>\n getColumnsInViewport(\n columns,\n scrollLeftRef.current,\n scrollLeftRef.current + availableWidth\n ),\n [availableWidth, columns]\n );\n\n const preSpanRef = useRef(preSpan);\n\n useEffect(() => {\n setColumnsWithinViewport(visibleColumns);\n }, [visibleColumns]);\n\n const [columnsWithinViewport, setColumnsWithinViewport] =\n useState<KeyedColumnDescriptor[]>(visibleColumns);\n\n const handleHorizontalScroll = useCallback(\n (scrollLeft: number) => {\n scrollLeftRef.current = scrollLeft;\n const [visibleColumns, pre] = getColumnsInViewport(\n columns,\n scrollLeft,\n scrollLeft + availableWidth\n );\n if (itemsChanged(columnsWithinViewport, visibleColumns)) {\n preSpanRef.current = pre;\n\n setColumnsWithinViewport(visibleColumns);\n }\n },\n [availableWidth, columns, columnsWithinViewport]\n );\n\n const handleVerticalScroll = useCallback(\n (scrollTop: number) => {\n const firstRow = getRowAtPosition(scrollTop);\n if (firstRow !== firstRowRef.current) {\n firstRowRef.current = firstRow;\n setRange({ from: firstRow, to: firstRow + viewportRowCount });\n }\n },\n [getRowAtPosition, setRange, viewportRowCount]\n );\n\n return {\n columnsWithinViewport,\n onHorizontalScroll: handleHorizontalScroll,\n onVerticalScroll: handleVerticalScroll,\n /** number of leading columns not rendered because of virtualization */\n virtualColSpan: preSpanRef.current,\n };\n};\n", "import { TableCellProps } from \"@vuu-ui/vuu-datagrid-types\";\nimport cx from \"classnames\";\nimport {\n isJsonAttribute,\n metadataKeys,\n registerComponent,\n} from \"@vuu-ui/vuu-utils\";\n\nimport \"./JsonCell.css\";\n\nconst classBase = \"vuuJsonCell\";\n\nconst { IS_EXPANDED, KEY } = metadataKeys;\n\nconst localKey = (key: string) => {\n const pos = key.lastIndexOf(\"|\");\n if (pos === -1) {\n return \"\";\n } else {\n return key.slice(pos + 1);\n }\n};\n\nconst JsonCell = ({ column, row }: TableCellProps) => {\n const { key: columnKey /*, type, valueFormatter */ } = column;\n let value = row[columnKey];\n let isToggle = false;\n if (isJsonAttribute(value)) {\n value = value.slice(0, -1);\n isToggle = true;\n }\n const rowKey = localKey(row[KEY]);\n const className = cx({\n [`${classBase}-name`]: rowKey === value,\n [`${classBase}-value`]: rowKey !== value,\n [`${classBase}-group`]: isToggle,\n });\n\n if (isToggle) {\n const toggleIcon = row[IS_EXPANDED] ? \"minus-box\" : \"plus-box\";\n return (\n <span className={className}>\n <span className={`${classBase}-value`}>{value}</span>\n <span className={`${classBase}-toggle`} data-icon={toggleIcon} />\n </span>\n );\n } else if (value) {\n return <span className={className}>{value}</span>;\n } else {\n return null;\n }\n};\n\nregisterComponent(\"json\", JsonCell, \"cell-renderer\", {});\n", "import { ContextMenuProvider } from \"@vuu-ui/vuu-popups\";\nimport { TableProps } from \"@vuu-ui/vuu-table\";\nimport { metadataKeys, notHidden } from \"@vuu-ui/vuu-utils\";\nimport { CSSProperties } from \"react\";\nimport { HeaderCell } from \"./HeaderCell\";\nimport { Row } from \"./Row\";\nimport { useTable } from \"./useTableNext\";\n\nimport \"./TableNext.css\";\n\nconst classBase = \"vuuTableNext\";\n\nconst { IDX, RENDER_IDX } = metadataKeys;\n\nexport const TableNext = ({\n className: classNameProp,\n config,\n dataSource,\n headerHeight = 25,\n height,\n id: idProp,\n onConfigChange,\n onFeatureEnabled,\n onFeatureInvocation,\n onSelectionChange,\n onShowConfigEditor: onShowSettings,\n renderBufferSize = 0,\n rowHeight = 20,\n selectionModel = \"extended\",\n style: styleProp,\n width,\n ...htmlAttributes\n}: TableProps) => {\n const {\n columnMap,\n columns,\n containerMeasurements: { cssSize, innerSize },\n containerRef,\n data,\n handleContextMenuAction,\n onHeaderClick,\n onHeaderResize,\n onRowClick,\n menuBuilder,\n scrollProps,\n viewportMeasurements,\n ...tableProps\n } = useTable({\n config,\n dataSource,\n renderBufferSize,\n headerHeight,\n height,\n onConfigChange,\n onFeatureEnabled,\n onFeatureInvocation,\n onSelectionChange,\n rowHeight,\n selectionModel,\n width,\n });\n\n const unmeasured = innerSize === undefined;\n\n const getStyle = () => {\n return unmeasured\n ? ({\n \"--table-css-height\": `${cssSize.height}`,\n \"--table-css-width\": `${cssSize.width}`,\n } as CSSProperties)\n : ({\n ...styleProp,\n \"--content-height\": `${viewportMeasurements.contentHeight}px`,\n \"--horizontal-scrollbar-height\": `${viewportMeasurements.horizontalScrollbarHeight}px`,\n \"--content-width\": `${viewportMeasurements.contentWidth}px`,\n \"--pinned-width-left\": `${viewportMeasurements.pinnedWidthLeft}px`,\n \"--pinned-width-right\": `${viewportMeasurements.pinnedWidthRight}px`,\n \"--header-height\": `${headerHeight}px`,\n \"--row-height\": `${rowHeight}px`,\n \"--table-css-height\": `${cssSize?.height}`,\n \"--table-css-width\": `${cssSize?.width}`,\n \"--table-height\": `${innerSize?.height}px`,\n \"--table-width\": `${innerSize?.width}px`,\n \"--total-header-height\": `${viewportMeasurements.totalHeaderHeight}px`,\n \"--vertical-scrollbar-width\": `${viewportMeasurements.verticalScrollbarWidth}px`,\n \"--viewport-body-height\": `${viewportMeasurements.viewportBodyHeight}px`,\n } as CSSProperties);\n };\n // console.log(`%cTableNext render`, \"color:red;font-weight:bold;\");\n // useEffect(() => {\n // console.log(\n // `%cTableNext actual render`,\n // \"background-color:red;color: white;font-weight:bold;\"\n // );\n // });\n return (\n <ContextMenuProvider\n menuActionHandler={handleContextMenuAction}\n menuBuilder={menuBuilder}\n >\n {unmeasured ? (\n <div\n {...htmlAttributes}\n className={classBase}\n style={getStyle()}\n ref={containerRef}\n />\n ) : (\n <div\n {...htmlAttributes}\n className={classBase}\n style={getStyle()}\n ref={containerRef}\n >\n <div\n className={`${classBase}-scrollbarContainer`}\n ref={scrollProps.scrollbarContainerRef}\n >\n <div className={`${classBase}-scrollbarContent`} />\n </div>\n <div\n className={`${classBase}-contentContainer`}\n ref={scrollProps.contentContainerRef}\n >\n <div {...tableProps} className={`${classBase}-table`}>\n <div className={`${classBase}-col-headings`}>\n <div className={`${classBase}-col-headers`} role=\"row\">\n {columns.filter(notHidden).map((col, i) => (\n <HeaderCell\n classBase={classBase}\n column={col}\n idx={i}\n key={col.name}\n onClick={onHeaderClick}\n onResize={onHeaderResize}\n />\n ))}\n </div>\n </div>\n <div className={`${classBase}-body`}>\n {data.map((data) => (\n <Row\n columnMap={columnMap}\n columns={columns}\n key={data[RENDER_IDX]}\n onClick={onRowClick}\n row={data}\n offset={rowHeight * data[IDX] + headerHeight}\n />\n ))}\n </div>\n </div>\n </div>\n </div>\n )}\n </ContextMenuProvider>\n );\n};\n", "import { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { HTMLAttributes, MouseEvent, useCallback, useRef } from \"react\";\nimport { useCell } from \"./useCell\";\nimport { ColumnMenu } from \"./ColumnMenu\";\nimport { SortIndicator } from \"@vuu-ui/vuu-table/src/table/SortIndicator\";\nimport {\n ColumnResizer,\n TableColumnResizeHandler,\n useTableColumnResize,\n} from \"./column-resizing\";\n\nimport \"./HeaderCell.css\";\n\nexport interface HeaderCellProps extends HTMLAttributes<HTMLDivElement> {\n classBase?: string;\n column: KeyedColumnDescriptor;\n idx: number;\n onResize?: TableColumnResizeHandler;\n}\n\nexport const HeaderCell = ({\n classBase: classBaseProp,\n column,\n onClick,\n onResize,\n idx,\n}: HeaderCellProps) => {\n const rootRef = useRef<HTMLDivElement>(null);\n const { isResizing, ...resizeProps } = useTableColumnResize({\n column,\n onResize,\n rootRef,\n });\n\n const classBase = `${classBaseProp}-col-header`;\n\n const handleClick = useCallback(\n (evt: MouseEvent<HTMLTableCellElement>) => !isResizing && onClick?.(evt),\n [isResizing, onClick]\n );\n\n const { className, style } = useCell(column, classBase, true);\n\n return (\n <div\n className={className}\n data-idx={idx}\n onClick={handleClick}\n ref={rootRef}\n role=\"cell\"\n style={style}\n >\n <ColumnMenu column={column} />\n <div className={`${classBase}-label`}>{column.name}</div>\n <SortIndicator sorted={column.sorted} />\n {column.resizeable !== false ? <ColumnResizer {...resizeProps} /> : null}\n </div>\n );\n};\n", "import { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { getColumnStyle } from \"@vuu-ui/vuu-utils\";\nimport cx from \"classnames\";\nimport { useMemo } from \"react\";\n\nexport const useCell = (\n column: KeyedColumnDescriptor,\n classBase: string,\n isHeader?: boolean\n) =>\n // TODO measure perf without the memo, might not be worth the cost\n useMemo(() => {\n const className = cx(classBase, {\n vuuPinFloating: column.pin === \"floating\",\n vuuPinLeft: column.pin === \"left\",\n vuuPinRight: column.pin === \"right\",\n vuuEndPin: isHeader && column.endPin,\n [`${classBase}-resizing`]: column.resizing,\n [`${classBase}-right`]: column.align === \"right\",\n });\n\n const style = getColumnStyle(column);\n return {\n className,\n style,\n };\n }, [column, classBase, isHeader]);\n", "import { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { useContextMenu } from \"@vuu-ui/vuu-popups\";\nimport cx from \"classnames\";\nimport {\n HTMLAttributes,\n MouseEvent,\n useCallback,\n useRef,\n useState,\n} from \"react\";\n\nimport \"./ColumnMenu.css\";\n\nexport interface ColumnMenuProps extends HTMLAttributes<HTMLSpanElement> {\n column: KeyedColumnDescriptor;\n}\n\nconst getPosition = (element: HTMLElement | null) => {\n if (element) {\n const { bottom, left } = element.getBoundingClientRect();\n return { x: left, y: bottom + 6 };\n }\n};\n\nexport const ColumnMenu = ({\n className,\n column,\n ...props\n}: ColumnMenuProps) => {\n const rootRef = useRef<HTMLSpanElement>(null);\n const [menuOpen, setMenuOpen] = useState(false);\n const [showContextMenu] = useContextMenu();\n\n const handleMenuClose = useCallback(() => {\n setMenuOpen(false);\n }, []);\n\n const showColumnMenu = useCallback(\n (e: MouseEvent<HTMLElement>) => {\n setMenuOpen(true);\n showContextMenu(e, \"column-menu\", {\n column,\n ContextMenuProps: {\n onClose: handleMenuClose,\n position: getPosition(rootRef.current),\n },\n });\n },\n [column, handleMenuClose, showContextMenu]\n );\n\n return (\n <span\n {...props}\n className={cx(\"vuuTable-columnMenu\", className, {\n \"vuuTable-columnMenu-open\": menuOpen,\n })}\n data-icon=\"more-vert\"\n onClick={showColumnMenu}\n ref={rootRef}\n />\n );\n};\n", "// export interface ColumnResizerProps {}\nimport { useCallback, useRef } from \"react\";\nimport \"./ColumnResizer.css\";\n\nconst NOOP = () => undefined;\n\nconst baseClass = \"vuuColumnResizer\";\nexport interface TableColumnResizerProps {\n onDrag: (evt: MouseEvent, moveBy: number) => void;\n onDragEnd: (evt: MouseEvent) => void;\n onDragStart: (evt: React.MouseEvent) => void;\n}\n\nexport const ColumnResizer = ({\n onDrag,\n onDragEnd = NOOP,\n onDragStart = NOOP,\n}: TableColumnResizerProps) => {\n const position = useRef(0);\n\n const onMouseMove = useCallback(\n (e: MouseEvent) => {\n if (e.stopPropagation) {\n e.stopPropagation();\n }\n\n if (e.preventDefault) {\n e.preventDefault();\n }\n\n const x = Math.round(e.clientX);\n const moveBy = x - position.current;\n position.current = x;\n\n if (moveBy !== 0) {\n onDrag(e, moveBy);\n }\n },\n [onDrag]\n );\n\n const onMouseUp = useCallback(\n (e: MouseEvent) => {\n window.removeEventListener(\"mouseup\", onMouseUp);\n window.removeEventListener(\"mousemove\", onMouseMove);\n onDragEnd(e);\n },\n [onDragEnd, onMouseMove]\n );\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n onDragStart(e);\n position.current = Math.round(e.clientX);\n\n window.addEventListener(\"mouseup\", onMouseUp);\n window.addEventListener(\"mousemove\", onMouseMove);\n\n if (e.stopPropagation) {\n e.stopPropagation();\n }\n\n if (e.preventDefault) {\n e.preventDefault();\n }\n },\n [onDragStart, onMouseMove, onMouseUp]\n );\n\n return (\n <div className={baseClass} data-align=\"end\" onMouseDown={handleMouseDown} />\n );\n};\n", "import { Heading, KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { RefObject, useCallback, useRef } from \"react\";\n\nexport type TableColumnResizeHandler = (\n phase: \"begin\" | \"resize\" | \"end\",\n columnName: string,\n width?: number\n) => void;\n\nexport type ResizeHandler = (evt: MouseEvent, moveBy: number) => void;\nexport interface CellResizeHookProps {\n column: KeyedColumnDescriptor | Heading;\n onResize?: (phase: resizePhase, columnName: string, width?: number) => void;\n rootRef: RefObject<HTMLDivElement>;\n}\n\ntype resizePhase = \"begin\" | \"resize\" | \"end\";\n\nexport interface CellResizeHookResult {\n isResizing: boolean;\n onDrag: (evt: MouseEvent, moveBy: number) => void;\n onDragStart: (evt: React.MouseEvent) => void;\n onDragEnd: (evt: MouseEvent) => void;\n}\n\nexport const useTableColumnResize = ({\n column,\n onResize,\n rootRef,\n}: CellResizeHookProps): CellResizeHookResult => {\n const widthRef = useRef(0);\n const isResizing = useRef(false);\n const { name } = column;\n\n const handleResizeStart = useCallback(() => {\n if (onResize && rootRef.current) {\n console.log(\"handleResizeStart\");\n const { width } = rootRef.current.getBoundingClientRect();\n widthRef.current = Math.round(width);\n isResizing.current = true;\n onResize?.(\"begin\", name);\n }\n }, [name, onResize, rootRef]);\n\n const handleResize = useCallback(\n (_evt: MouseEvent, moveBy: number) => {\n if (rootRef.current) {\n if (onResize) {\n const { width } = rootRef.current.getBoundingClientRect();\n const newWidth = Math.round(width) + moveBy;\n if (newWidth !== widthRef.current && newWidth > 0) {\n onResize(\"resize\", name, newWidth);\n widthRef.current = newWidth;\n }\n }\n }\n },\n [name, onResize, rootRef]\n );\n\n const handleResizeEnd = useCallback(() => {\n if (onResize) {\n onResize(\"end\", name, widthRef.current);\n setTimeout(() => {\n // set in a timeout to prevent the click event from firing and triggering a sort\n isResizing.current = false;\n }, 100);\n }\n }, [name, onResize]);\n\n return {\n isResizing: isResizing.current,\n onDrag: handleResize,\n onDragStart: handleResizeStart,\n onDragEnd: handleResizeEnd,\n };\n};\n", "import { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\nimport { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { RowClickHandler } from \"@vuu-ui/vuu-table\";\nimport {\n ColumnMap,\n isGroupColumn,\n metadataKeys,\n notHidden,\n RowSelected,\n} from \"@vuu-ui/vuu-utils\";\nimport cx from \"classnames\";\nimport { CSSProperties, memo, MouseEvent, useCallback } from \"react\";\nimport { TableCell } from \"./TableCell\";\nimport { TableGroupCell } from \"./TableGroupCell\";\n\nimport \"./Row.css\";\n\nexport type HtmlRowProps = {\n className?: string;\n columnMap: ColumnMap;\n columns: KeyedColumnDescriptor[];\n row: DataSourceRow;\n offset?: number;\n onClick?: RowClickHandler;\n onToggleGroup?: (row: DataSourceRow, column: KeyedColumnDescriptor) => void;\n style?: CSSProperties;\n};\n\nconst { IDX, IS_EXPANDED, SELECTED } = metadataKeys;\nconst classBase = \"vuuTableNextRow\";\n\nexport const Row = memo(\n ({\n className: classNameProp,\n columnMap,\n columns,\n row,\n offset,\n onClick,\n onToggleGroup,\n ...htmlAttributes\n }: HtmlRowProps) => {\n // useEffect(() => {\n // console.log(\"row mounted\");\n // return () => {\n // console.log(\"row unmounted\");\n // };\n // }, []);\n\n const {\n [IDX]: rowIndex,\n [IS_EXPANDED]: isExpanded,\n [SELECTED]: selectionStatus,\n } = row;\n\n const handleRowClick = useCallback(\n (evt: MouseEvent<HTMLDivElement>) => {\n const rangeSelect = evt.shiftKey;\n const keepExistingSelection = evt.ctrlKey || evt.metaKey; /* mac only */\n onClick?.(row, rangeSelect, keepExistingSelection);\n },\n [onClick, row]\n );\n\n const { True, First, Last } = RowSelected;\n\n const className = cx(classBase, classNameProp, {\n [`${classBase}-even`]: rowIndex % 2 === 0,\n [`${classBase}-expanded`]: isExpanded,\n [`${classBase}-selected`]: selectionStatus & True,\n [`${classBase}-selectedStart`]: selectionStatus & First,\n [`${classBase}-selectedEnd`]: selectionStatus & Last,\n });\n\n const style =\n typeof offset === \"number\"\n ? { transform: `translate3d(0px, ${offset}px, 0px)` }\n : undefined;\n\n return (\n <div\n {...htmlAttributes}\n key={`row-${row[0]}`}\n role=\"row\"\n className={className}\n onClick={handleRowClick}\n style={style}\n >\n <span className={`${classBase}-selectionDecorator vuuStickyLeft`} />\n {columns.filter(notHidden).map((column) => {\n const isGroup = isGroupColumn(column);\n const Cell = isGroup ? TableGroupCell : TableCell;\n\n return <Cell key={column.key} column={column} row={row} />;\n })}\n <span className={`${classBase}-selectionDecorator vuuStickyRight`} />\n </div>\n );\n }\n);\nRow.displayName = \"Row\";\n", "import { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\nimport { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { MouseEvent } from \"react\";\nimport { useCell } from \"./useCell\";\n\nexport interface TableCellProps {\n column: KeyedColumnDescriptor;\n onClick?: (\n evt: MouseEvent<HTMLDivElement>,\n column: KeyedColumnDescriptor\n ) => void;\n row: DataSourceRow;\n}\n\nexport const TableCell = ({ column, row }: TableCellProps) => {\n const { className, style } = useCell(column, \"vuuTableNextCell\");\n\n return (\n <div className={className} role=\"cell\" style={style}>\n {row[column.key]}\n </div>\n );\n};\n", "import { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\nimport {\n GroupColumnDescriptor,\n KeyedColumnDescriptor,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport { getGroupValueAndOffset, metadataKeys } from \"@vuu-ui/vuu-utils\";\nimport { MouseEvent, useCallback } from \"react\";\nimport { useCell } from \"./useCell\";\n\nexport interface TableCellProps {\n column: KeyedColumnDescriptor;\n onClick?: (evt: MouseEvent, column: KeyedColumnDescriptor) => void;\n row: DataSourceRow;\n}\n\nconst { IS_LEAF } = metadataKeys;\n\nexport const TableGroupCell = ({ column, onClick, row }: TableCellProps) => {\n const { columns } = column as GroupColumnDescriptor;\n const [value, offset] = getGroupValueAndOffset(columns, row);\n const { className, style } = useCell(column, \"vuuTable2-groupCell\");\n\n const handleClick = useCallback(\n (evt: MouseEvent) => {\n onClick?.(evt, column);\n },\n [column, onClick]\n );\n\n const isLeaf = row[IS_LEAF];\n const spacers = Array(offset)\n .fill(0)\n .map((n, i) => <span className=\"vuuTable2-groupCell-spacer\" key={i} />);\n\n return (\n <div\n className={className}\n role=\"cell\"\n style={style}\n onClick={isLeaf ? undefined : handleClick}\n >\n {spacers}\n {isLeaf ? null : (\n <span\n className=\"vuuTable2-groupCell-toggle\"\n data-icon=\"vuu-triangle-right\"\n />\n )}\n <span>{value}</span>\n </div>\n );\n};\n", "import {\n DataSource,\n VuuFeatureInvocationMessage,\n VuuFeatureMessage,\n} from \"@vuu-ui/vuu-data\";\nimport {\n GridConfig,\n KeyedColumnDescriptor,\n SelectionChangeHandler,\n TableConfig,\n TableSelectionModel,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n SetPropsAction,\n useLayoutEffectSkipFirst,\n useLayoutProviderDispatch,\n} from \"@vuu-ui/vuu-layout\";\nimport { useContextMenu as usePopupContextMenu } from \"@vuu-ui/vuu-popups\";\nimport { VuuRange, VuuSortType } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n applySort,\n buildColumnMap,\n isValidNumber,\n updateColumn,\n visibleColumnAtIndex,\n} from \"@vuu-ui/vuu-utils\";\nimport { MouseEvent, useCallback, useMemo, useState } from \"react\";\nimport {\n MeasuredProps,\n useMeasuredContainer,\n useSelection,\n useTableViewport,\n} from \"../table\";\nimport { buildContextMenuDescriptors, useTableContextMenu } from \"../table\";\nimport { TableColumnResizeHandler } from \"./column-resizing\";\nimport { updateTableConfig } from \"./table-config\";\nimport { useDataSource } from \"./useDataSource\";\nimport { useInitialValue } from \"./useInitialValue\";\nimport {\n isShowColumnSettings,\n isShowTableSettings,\n PersistentColumnAction,\n useTableModel,\n} from \"./useTableModel\";\nimport { useTableScroll } from \"./useTableScroll\";\nimport { useVirtualViewport } from \"./useVirtualViewport\";\n\nexport interface TableHookProps extends MeasuredProps {\n config: Omit<GridConfig, \"headings\">;\n dataSource: DataSource;\n headerHeight: number;\n onConfigChange?: (config: TableConfig) => void;\n onFeatureEnabled?: (message: VuuFeatureMessage) => void;\n onFeatureInvocation?: (message: VuuFeatureInvocationMessage) => void;\n renderBufferSize?: number;\n rowHeight: number;\n onSelectionChange?: SelectionChangeHandler;\n selectionModel: TableSelectionModel;\n}\n\nexport const useTable = ({\n config,\n dataSource,\n headerHeight,\n onConfigChange,\n onFeatureEnabled,\n onFeatureInvocation,\n onSelectionChange,\n rowHeight,\n selectionModel,\n ...measuredProps\n}: TableHookProps) => {\n const [rowCount] = useState<number>(dataSource.size);\n const dispatchLayoutAction = useLayoutProviderDispatch();\n if (dataSource === undefined) {\n throw Error(\"no data source provided to Vuu Table\");\n }\n\n const menuBuilder = useMemo(\n () => buildContextMenuDescriptors(dataSource),\n [dataSource]\n );\n\n const { containerRef, ...containerMeasurements } =\n useMeasuredContainer(measuredProps);\n\n const {\n columns: modelColumns,\n dispatchColumnAction,\n headings,\n } = useTableModel(config, dataSource.config);\n\n useLayoutEffectSkipFirst(() => {\n dispatchColumnAction({\n type: \"init\",\n dataSourceConfig: dataSource.config,\n tableConfig: config,\n });\n }, [config, dataSource.config, dispatchColumnAction]);\n\n const [stateColumns, setStateColumns] = useState<KeyedColumnDescriptor[]>();\n const [columns, setColumnSize] = useMemo(() => {\n const setSize = (columnName: string, width: number) => {\n const cols = updateColumn(modelColumns, columnName, { width });\n setStateColumns(cols);\n };\n return [stateColumns ?? modelColumns, setSize];\n }, [modelColumns, stateColumns]);\n\n const columnMap = useMemo(\n () => buildColumnMap(config.columns.map((col) => col.name)),\n [config.columns]\n );\n\n const {\n getRowAtPosition,\n getRowOffset,\n setPctScrollTop,\n ...viewportMeasurements\n } = useTableViewport({\n columns,\n headerHeight,\n headings,\n rowCount,\n rowHeight,\n // Note: innerSize will take border into account, whereas outerSize will not\n // size: containerMeasurements.innerSize ?? containerMeasurements.outerSize,\n size: containerMeasurements.innerSize,\n });\n\n const initialRange = useInitialValue<VuuRange>({\n from: 0,\n to: viewportMeasurements.rowCount + 1,\n });\n\n const { data, setRange } = useDataSource({\n dataSource,\n initialRange,\n });\n\n useMemo(() => {\n const {\n range: { from, to },\n } = dataSource;\n if (viewportMeasurements.rowCount !== to - 1 - from) {\n dataSource.range = {\n from,\n to: from + viewportMeasurements.rowCount + 1,\n };\n }\n }, [dataSource, viewportMeasurements.rowCount]);\n\n const onPersistentColumnOperation = useCallback(\n (action: PersistentColumnAction) => {\n if (isShowColumnSettings(action)) {\n dispatchLayoutAction({\n type: \"set-props\",\n path: \"#context-panel\",\n props: {\n expanded: true,\n context: \"column-settings\",\n column: action.column,\n title: \"Column Settings\",\n },\n } as SetPropsAction);\n } else if (isShowTableSettings(action)) {\n dispatchLayoutAction({\n type: \"set-props\",\n path: \"#context-panel\",\n props: {\n expanded: true,\n content: {\n type: \"TableSettings\",\n props: {\n // TODO get this from dataSource\n availableColumns: config.columns.map(\n ({ name, serverDataType }) => ({ name, serverDataType })\n ),\n onConfigChange,\n tableConfig: config,\n },\n },\n title: \"DataGrid Settings\",\n },\n } as SetPropsAction);\n } else {\n // expectConfigChangeRef.current = true;\n dispatchColumnAction(action);\n }\n },\n [config, dispatchColumnAction, dispatchLayoutAction, onConfigChange]\n );\n\n const handleContextMenuAction = useTableContextMenu({\n dataSource,\n onPersistentColumnOperation,\n });\n\n const { onVerticalScroll } = useVirtualViewport({\n columns,\n getRowAtPosition,\n setRange,\n viewportMeasurements,\n });\n\n const handleVerticalScroll = useCallback(\n (scrollTop: number) => {\n onVerticalScroll(scrollTop);\n },\n [onVerticalScroll]\n );\n\n const { requestScroll, ...scrollProps } = useTableScroll({\n // contentHeight: viewportMeasurements.contentHeight,\n // contentWidth: viewportMeasurements.contentWidth,\n // height: containerMeasurements.innerSize?.height ?? 0,\n // width: containerMeasurements.innerSize?.width ?? 0,\n\n maxScrollLeft: viewportMeasurements.maxScrollContainerScrollHorizontal,\n maxScrollTop: viewportMeasurements.maxScrollContainerScrollVertical,\n onVerticalScroll: handleVerticalScroll,\n });\n\n // TOSO ship this out into a hook\n const [showContextMenu] = usePopupContextMenu();\n\n const onContextMenu = useCallback(\n (evt: MouseEvent<HTMLElement>) => {\n // const { current: currentData } = dataRef;\n // const { current: currentDataSource } = dataSourceRef;\n const target = evt.target as HTMLElement;\n const cellEl = target?.closest(\"div[role='cell']\");\n const rowEl = target?.closest(\"div[role='row']\");\n if (cellEl && rowEl /*&& currentData && currentDataSource*/) {\n // const { columns, selectedRowsCount } = currentDataSource;\n const columnMap = buildColumnMap(columns);\n // const rowIndex = parseInt(rowEl.ariaRowIndex ?? \"-1\");\n const cellIndex = Array.from(rowEl.childNodes).indexOf(cellEl);\n // const row = currentData.find(([idx]) => idx === rowIndex);\n const columnName = columns[cellIndex];\n showContextMenu(evt, \"grid\", {\n columnMap,\n columnName,\n // row,\n // selectedRows: selectedRowsCount === 0 ? NO_ROWS : getSelectedRows(),\n // viewport: dataSource?.viewport,\n });\n }\n },\n [columns, showContextMenu]\n );\n\n const handleSort = useCallback(\n (\n column: KeyedColumnDescriptor,\n extendSort = false,\n sortType?: VuuSortType\n ) => {\n if (dataSource) {\n dataSource.sort = applySort(\n dataSource.sort,\n column,\n extendSort,\n sortType\n );\n }\n },\n [dataSource]\n );\n\n const onHeaderClick = useCallback(\n (evt: MouseEvent) => {\n const targetElement = evt.target as HTMLElement;\n const headerCell = targetElement.closest(\n \".TableNext-col-header\"\n ) as HTMLElement;\n const colIdx = parseInt(headerCell?.dataset.idx ?? \"-1\");\n const column = visibleColumnAtIndex(columns, colIdx);\n const isAdditive = evt.shiftKey;\n column && handleSort(column, isAdditive);\n },\n [columns, handleSort]\n );\n\n const handleSelectionChange: SelectionChangeHandler = useCallback(\n (selected) => {\n dataSource.select(selected);\n onSelectionChange?.(selected);\n },\n [dataSource, onSelectionChange]\n );\n\n const onRowClick = useSelection({\n onSelectionChange: handleSelectionChange,\n selectionModel,\n });\n\n const onHeaderResize: TableColumnResizeHandler = useCallback(\n (phase, columnName, width) => {\n const column = columns.find((column) => column.name === columnName);\n if (column) {\n if (phase === \"resize\") {\n if (isValidNumber(width)) {\n setColumnSize(columnName, width);\n }\n } else if (phase === \"end\") {\n if (isValidNumber(width)) {\n onConfigChange?.(\n updateTableConfig(config, {\n type: \"col-size\",\n column,\n width,\n })\n );\n }\n } else {\n setStateColumns(undefined);\n dispatchColumnAction({\n type: \"resizeColumn\",\n phase,\n column,\n width,\n });\n }\n } else {\n throw Error(\n `useDataTable.handleColumnResize, column ${columnName} not found`\n );\n }\n },\n [columns, config, dispatchColumnAction, onConfigChange, setColumnSize]\n );\n\n return {\n columnMap,\n columns,\n containerRef,\n containerMeasurements,\n data,\n handleContextMenuAction,\n menuBuilder,\n onContextMenu,\n onHeaderClick,\n onHeaderResize,\n onRowClick,\n scrollProps,\n viewportMeasurements,\n };\n};\n", "import { ColumnDescriptor, TableConfig } from \"packages/vuu-datagrid-types\";\n\nexport type MoveColumnTableConfigAction = {\n type: \"col-move\";\n column: ColumnDescriptor;\n fromIndex: number;\n toIndex: number;\n};\n\nexport type ResizeColumnTableConfigAction = {\n type: \"col-size\";\n column: ColumnDescriptor;\n width: number;\n};\n\nexport type SubscribeColumnTableConfigAction = {\n type: \"subscribed\";\n column: ColumnDescriptor;\n value: boolean;\n};\n\nexport type UpdateColumnPropertyTableConfigAction = {\n type: \"column-prop\";\n column: ColumnDescriptor;\n property: keyof ColumnDescriptor;\n value: boolean | number | string;\n};\n\nexport type TableConfigAction =\n | MoveColumnTableConfigAction\n | ResizeColumnTableConfigAction\n | UpdateColumnPropertyTableConfigAction;\n\nexport const updateTableConfig = (\n config: TableConfig,\n action: TableConfigAction\n): TableConfig => {\n switch (action.type) {\n case \"col-size\":\n return {\n ...config,\n columns: config.columns.map((col) =>\n col.name === action.column.name\n ? { ...col, width: action.width }\n : col\n ),\n };\n case \"column-prop\":\n return {\n ...config,\n columns: config.columns.map((col) =>\n col.name === action.column.name\n ? { ...col, [action.property]: action.value }\n : col\n ),\n };\n\n default:\n return config;\n }\n};\n", "import { DataSource } from \"@vuu-ui/vuu-data\";\nimport { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\nimport { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { useCallback, useMemo, useState } from \"react\";\n\nexport const useDataSource = ({\n dataSource,\n initialRange,\n}: {\n dataSource: DataSource;\n initialRange: VuuRange;\n}) => {\n const [data, setData] = useState<DataSourceRow[]>([]);\n // useEffect(() => {\n useMemo(() => {\n dataSource?.subscribe({ range: initialRange }, (message) => {\n if (message.type === \"viewport-update\") {\n // if (message.size) {\n // console.log(`useDataSourcesize = ${message.size}`);\n // }\n if (message.rows) {\n setData(message.rows);\n }\n }\n });\n }, [dataSource, initialRange]);\n\n const setRange = useCallback(\n (range: VuuRange) => {\n dataSource.range = range;\n },\n [dataSource]\n );\n\n return {\n data,\n setRange,\n };\n};\n", "import { useMemo, useRef } from \"react\";\n\nexport const useInitialValue = <T = unknown>(value: T): T => {\n const ref = useRef<T>(value);\n return useMemo(() => ref.current, []);\n};\n", "import {\n ColumnDescriptor,\n GridConfig,\n KeyedColumnDescriptor,\n PinLocation,\n TableConfig,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport { moveItem } from \"@vuu-ui/vuu-ui-controls\";\nimport {\n applyFilterToColumns,\n applyGroupByToColumns,\n applySortToColumns,\n findColumn,\n getCellRenderer,\n getColumnName,\n getTableHeadings,\n getValueFormatter,\n isFilteredColumn,\n isGroupColumn,\n isPinned,\n isTypeDescriptor,\n logger,\n metadataKeys,\n sortPinnedColumns,\n stripFilterFromColumns,\n} from \"@vuu-ui/vuu-utils\";\n\nimport { Reducer, useReducer } from \"react\";\nimport { VuuColumnDataType } from \"@vuu-ui/vuu-protocol-types\";\nimport { DataSourceConfig } from \"@vuu-ui/vuu-data\";\nimport { TableSchema } from \"@vuu-ui/vuu-data/src/message-utils\";\n\nconst { info } = logger(\"useTableModel\");\n\nconst DEFAULT_COLUMN_WIDTH = 100;\nconst KEY_OFFSET = metadataKeys.count;\n\nconst columnWithoutDataType = ({ serverDataType }: ColumnDescriptor) =>\n serverDataType === undefined;\n\nconst getCellRendererForColumn = (column: ColumnDescriptor) => {\n if (isTypeDescriptor(column.type)) {\n return getCellRenderer(column.type?.renderer);\n }\n};\n\nconst getDataType = (\n column: ColumnDescriptor,\n tableSchema: TableSchema\n): VuuColumnDataType => {\n const schemaColumn = tableSchema.columns.find(\n ({ name }) => name === column.name\n );\n if (schemaColumn) {\n return schemaColumn.serverDataType;\n } else {\n return column.serverDataType ?? \"string\";\n }\n};\n\n// TODO should headings live here and this extend TableConfig ?\nexport interface TableModel extends Omit<GridConfig, \"columns\"> {\n columns: KeyedColumnDescriptor[];\n}\n\nconst numericTypes = [\"int\", \"long\", \"double\"];\nconst getDefaultAlignment = (serverDataType?: VuuColumnDataType) =>\n serverDataType === undefined\n ? undefined\n : numericTypes.includes(serverDataType)\n ? \"right\"\n : \"left\";\n\nexport interface ColumnActionInit {\n type: \"init\";\n tableConfig: TableConfig;\n dataSourceConfig?: DataSourceConfig;\n}\n\nexport interface ColumnActionHide {\n type: \"hideColumns\";\n columns: KeyedColumnDescriptor[];\n}\n\nexport interface ColumnActionShow {\n type: \"showColumns\";\n columns: KeyedColumnDescriptor[];\n}\nexport interface ColumnActionMove {\n type: \"moveColumn\";\n column: KeyedColumnDescriptor;\n moveBy?: 1 | -1;\n moveTo?: number;\n}\n\nexport interface ColumnActionPin {\n type: \"pinColumn\";\n column: ColumnDescriptor;\n pin?: PinLocation;\n}\nexport interface ColumnActionResize {\n type: \"resizeColumn\";\n column: KeyedColumnDescriptor;\n phase: \"begin\" | \"resize\" | \"end\";\n width?: number;\n}\n\nexport interface ColumnActionSetTableSchema {\n type: \"setTableSchema\";\n tableSchema: TableSchema;\n}\n\nexport interface ColumnActionUpdate {\n type: \"updateColumn\";\n column: ColumnDescriptor;\n}\n\nexport interface ColumnActionUpdateProp {\n align?: ColumnDescriptor[\"align\"];\n column: KeyedColumnDescriptor;\n hidden?: ColumnDescriptor[\"hidden\"];\n label?: ColumnDescriptor[\"label\"];\n resizing?: KeyedColumnDescriptor[\"resizing\"];\n type: \"updateColumnProp\";\n width?: ColumnDescriptor[\"width\"];\n}\n\nexport interface ColumnActionTableConfig extends DataSourceConfig {\n confirmed?: boolean;\n type: \"tableConfig\";\n}\n\nexport interface ColumnActionColumnSettings extends DataSourceConfig {\n type: \"columnSettings\";\n column: KeyedColumnDescriptor;\n}\n\nexport interface ColumnActionTableSettings extends DataSourceConfig {\n type: \"tableSettings\";\n}\n\nexport const isShowColumnSettings = (\n action: PersistentColumnAction\n): action is ColumnActionColumnSettings => action.type === \"columnSettings\";\n\nexport const isShowTableSettings = (\n action: PersistentColumnAction\n): action is ColumnActionTableSettings => action.type === \"tableSettings\";\n\n/**\n * PersistentColumnActions are those actions that require us to persist user changes across sessions\n */\nexport type PersistentColumnAction =\n | ColumnActionPin\n | ColumnActionHide\n | ColumnActionColumnSettings\n | ColumnActionTableSettings;\n\nexport type GridModelAction =\n | ColumnActionHide\n | ColumnActionInit\n | ColumnActionMove\n | ColumnActionPin\n | ColumnActionResize\n | ColumnActionSetTableSchema\n | ColumnActionShow\n | ColumnActionUpdate\n | ColumnActionUpdateProp\n | ColumnActionTableConfig;\n\nexport type GridModelReducer = Reducer<TableModel, GridModelAction>;\n\nexport type ColumnActionDispatch = (action: GridModelAction) => void;\n\nconst columnReducer: GridModelReducer = (state, action) => {\n info?.(`GridModelReducer ${action.type}`);\n switch (action.type) {\n case \"init\":\n return init(action);\n case \"moveColumn\":\n return moveColumn(state, action);\n case \"resizeColumn\":\n return resizeColumn(state, action);\n case \"setTableSchema\":\n return setTableSchema(state, action);\n case \"hideColumns\":\n return hideColumns(state, action);\n case \"showColumns\":\n return showColumns(state, action);\n case \"pinColumn\":\n return pinColumn(state, action);\n case \"updateColumnProp\":\n return updateColumnProp(state, action);\n case \"tableConfig\":\n return updateTableConfig(state, action);\n default:\n console.log(`unhandled action ${action.type}`);\n return state;\n }\n};\n\nexport const useTableModel = (\n tableConfig: TableConfig,\n dataSourceConfig?: DataSourceConfig\n) => {\n const [state, dispatchColumnAction] = useReducer<\n GridModelReducer,\n InitialConfig\n >(columnReducer, { tableConfig, dataSourceConfig }, init);\n\n return {\n columns: state.columns,\n dispatchColumnAction,\n headings: state.headings,\n };\n};\n\ntype InitialConfig = {\n dataSourceConfig?: DataSourceConfig;\n tableConfig: TableConfig;\n};\n\nfunction init({ dataSourceConfig, tableConfig }: InitialConfig): TableModel {\n const columns = tableConfig.columns.map(\n toKeyedColumWithDefaults(tableConfig)\n );\n const maybePinnedColumns = columns.some(isPinned)\n ? sortPinnedColumns(columns)\n : columns;\n const state = {\n columns: maybePinnedColumns,\n headings: getTableHeadings(maybePinnedColumns),\n };\n if (dataSourceConfig) {\n const { columns, ...rest } = dataSourceConfig;\n return updateTableConfig(state, {\n type: \"tableConfig\",\n ...rest,\n });\n } else {\n return state;\n }\n}\n\nconst getLabel = (\n label: string,\n columnFormatHeader?: \"uppercase\" | \"capitalize\"\n): string => {\n if (columnFormatHeader === \"uppercase\") {\n return label.toUpperCase();\n } else if (columnFormatHeader === \"capitalize\") {\n return label[0].toUpperCase() + label.slice(1).toLowerCase();\n }\n return label;\n};\n\nconst toKeyedColumWithDefaults =\n (options: Omit<GridConfig, \"headings\">) =>\n (\n column: ColumnDescriptor & { key?: number },\n index: number\n ): KeyedColumnDescriptor => {\n const { columnDefaultWidth = DEFAULT_COLUMN_WIDTH, columnFormatHeader } =\n options;\n const {\n align = getDefaultAlignment(column.serverDataType),\n key,\n name,\n label = name,\n width = columnDefaultWidth,\n ...rest\n } = column;\n\n const keyedColumnWithDefaults = {\n ...rest,\n align,\n CellRenderer: getCellRendererForColumn(column),\n label: getLabel(label, columnFormatHeader),\n key: key ?? index + KEY_OFFSET,\n name,\n originalIdx: index,\n valueFormatter: getValueFormatter(column),\n width: width,\n };\n\n if (isGroupColumn(keyedColumnWithDefaults)) {\n keyedColumnWithDefaults.columns = keyedColumnWithDefaults.columns.map(\n (col) => toKeyedColumWithDefaults(options)(col, col.key)\n );\n }\n\n return keyedColumnWithDefaults;\n };\n\nfunction moveColumn(\n state: TableModel,\n { column, moveBy, moveTo }: ColumnActionMove\n) {\n const { columns } = state;\n if (typeof moveBy === \"number\") {\n const idx = columns.indexOf(column);\n const newColumns = columns.slice();\n const [movedColumns] = newColumns.splice(idx, 1);\n newColumns.splice(idx + moveBy, 0, movedColumns);\n return {\n ...state,\n columns: newColumns,\n };\n } else if (typeof moveTo === \"number\") {\n const index = columns.indexOf(column);\n return {\n ...state,\n columns: moveItem(columns, index, moveTo),\n };\n }\n return state;\n}\n\nfunction hideColumns(state: TableModel, { columns }: ColumnActionHide) {\n if (columns.some((col) => col.hidden !== true)) {\n return columns.reduce<TableModel>((s, c) => {\n if (c.hidden !== true) {\n return updateColumnProp(s, {\n type: \"updateColumnProp\",\n column: c,\n hidden: true,\n });\n } else {\n return s;\n }\n }, state);\n } else {\n return state;\n }\n}\nfunction showColumns(state: TableModel, { columns }: ColumnActionShow) {\n if (columns.some((col) => col.hidden)) {\n return columns.reduce<TableModel>((s, c) => {\n if (c.hidden) {\n return updateColumnProp(s, {\n type: \"updateColumnProp\",\n column: c,\n hidden: false,\n });\n } else {\n return s;\n }\n }, state);\n } else {\n return state;\n }\n}\n\nfunction resizeColumn(\n state: TableModel,\n { column, phase, width }: ColumnActionResize\n) {\n const type = \"updateColumnProp\";\n const resizing = phase !== \"end\";\n\n switch (phase) {\n case \"begin\":\n return updateColumnProp(state, { type, column, resizing });\n case \"end\":\n return updateColumnProp(state, { type, column, resizing, width });\n case \"resize\":\n return updateColumnProp(state, { type, column, width });\n default:\n throw Error(`useTableModel.resizeColumn, invalid resizePhase ${phase}`);\n }\n}\n\nfunction setTableSchema(\n state: TableModel,\n { tableSchema }: ColumnActionSetTableSchema\n) {\n const { columns } = state;\n if (columns.some(columnWithoutDataType)) {\n const cols = columns.map((column) => {\n const serverDataType = getDataType(column, tableSchema);\n return {\n ...column,\n align: column.align ?? getDefaultAlignment(serverDataType),\n serverDataType,\n };\n });\n\n return {\n ...state,\n columns: cols,\n };\n } else {\n return state;\n }\n}\n\nfunction pinColumn(state: TableModel, action: ColumnActionPin) {\n let { columns } = state;\n const { column, pin } = action;\n const targetColumn = columns.find((col) => col.name === column.name);\n if (targetColumn) {\n columns = replaceColumn(columns, { ...targetColumn, pin });\n columns = sortPinnedColumns(columns);\n return {\n ...state,\n columns,\n };\n } else {\n return state;\n }\n}\nfunction updateColumnProp(state: TableModel, action: ColumnActionUpdateProp) {\n let { columns } = state;\n const { align, column, hidden, label, resizing, width } = action;\n const targetColumn = columns.find((col) => col.name === column.name);\n if (targetColumn) {\n if (align === \"left\" || align === \"right\") {\n columns = replaceColumn(columns, { ...targetColumn, align });\n }\n if (typeof label === \"string\") {\n columns = replaceColumn(columns, { ...targetColumn, label });\n }\n if (typeof resizing === \"boolean\") {\n columns = replaceColumn(columns, { ...targetColumn, resizing });\n }\n if (typeof hidden === \"boolean\") {\n columns = replaceColumn(columns, { ...targetColumn, hidden });\n }\n if (typeof width === \"number\") {\n columns = replaceColumn(columns, { ...targetColumn, width });\n }\n }\n return {\n ...state,\n columns,\n };\n}\n\nfunction updateTableConfig(\n state: TableModel,\n { columns, confirmed, filter, groupBy, sort }: ColumnActionTableConfig\n) {\n const hasColumns = columns && columns.length > 0;\n const hasGroupBy = groupBy !== undefined;\n const hasFilter = typeof filter?.filter === \"string\";\n const hasSort = sort && sort.sortDefs.length > 0;\n\n //TODO check if just confirmed has changed\n\n let result = state;\n\n if (hasColumns) {\n result = {\n ...state,\n columns: columns.map((colName, index) => {\n const columnName = getColumnName(colName);\n const key = index + KEY_OFFSET;\n const col = findColumn(result.columns, columnName);\n if (col) {\n if (col.key === key) {\n return col;\n } else {\n return {\n ...col,\n key,\n };\n }\n }\n throw Error(`useTableModel column ${colName} not found`);\n }),\n };\n }\n\n if (hasGroupBy) {\n result = {\n ...state,\n columns: applyGroupByToColumns(result.columns, groupBy, confirmed),\n };\n }\n\n if (hasSort) {\n result = {\n ...state,\n columns: applySortToColumns(result.columns, sort),\n };\n }\n\n if (hasFilter) {\n result = {\n ...state,\n columns: applyFilterToColumns(result.columns, filter),\n };\n } else if (result.columns.some(isFilteredColumn)) {\n result = {\n ...state,\n columns: stripFilterFromColumns(result.columns),\n };\n }\n\n return result;\n}\n\nfunction replaceColumn(\n state: KeyedColumnDescriptor[],\n column: KeyedColumnDescriptor\n) {\n return state.map((col) => (col.name === column.name ? column : col));\n}\n", "import { useCallback, useRef } from \"react\";\n\nexport interface ScrollRequestEnd {\n type: \"scroll-end\";\n direction: \"home\" | \"end\";\n}\n\nexport interface ScrollRequestPage {\n type: \"scroll-page\";\n direction: \"up\" | \"down\";\n}\n\nexport interface ScrollRequestDistance {\n type: \"scroll-distance\";\n distance: number;\n}\n\nexport type ScrollRequest =\n | ScrollRequestPage\n | ScrollRequestDistance\n | ScrollRequestEnd;\n\nexport type ScrollRequestHandler = (request: ScrollRequest) => void;\n\nconst getPctScroll = (container: HTMLElement) => {\n const { scrollLeft, scrollTop } = container;\n const { clientHeight, clientWidth, scrollHeight, scrollWidth } = container;\n const pctScrollLeft = scrollLeft / (scrollWidth - clientWidth);\n const pctScrollTop = scrollTop / (scrollHeight - clientHeight);\n return [pctScrollLeft, pctScrollTop];\n};\n\ninterface CallbackRefHookProps<T = HTMLElement> {\n onAttach?: (el: T) => void;\n onDetach: (el: T) => void;\n label?: string;\n}\n\nconst useCallbackRef = <T = HTMLElement>({\n onAttach,\n onDetach,\n}: CallbackRefHookProps<T>) => {\n const ref = useRef<T | null>(null);\n const callbackRef = useCallback(\n (el: T | null) => {\n if (el) {\n ref.current = el;\n onAttach?.(el);\n } else if (ref.current) {\n const { current: originalRef } = ref;\n ref.current = el;\n onDetach?.(originalRef);\n }\n },\n [onAttach, onDetach]\n );\n return callbackRef;\n};\n\nexport interface TableScrollHookProps {\n maxScrollLeft: number;\n maxScrollTop: number;\n onHorizontalScroll?: (scrollLeft: number) => void;\n onVerticalScroll?: (scrollTop: number, pctScrollTop: number) => void;\n}\n\nexport const useTableScroll = ({\n // height,\n // width,\n // contentHeight,\n // contentWidth,\n\n maxScrollLeft,\n maxScrollTop,\n onHorizontalScroll,\n onVerticalScroll,\n}: TableScrollHookProps) => {\n const contentContainerScrolledRef = useRef(false);\n\n // console.log(`useTableScroll\n // viewport : ${width} x ${height}\n // content ${contentWidth} x ${contentHeight}\n // `);\n\n const scrollPosRef = useRef({ scrollTop: 0, scrollLeft: 0 });\n const scrollbarContainerRef = useRef<HTMLDivElement | null>(null);\n const contentContainerRef = useRef<HTMLDivElement | null>(null);\n\n const handleScrollbarContainerScroll = useCallback(() => {\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n const { current: contentContainerScrolled } = contentContainerScrolledRef;\n if (contentContainerScrolled) {\n contentContainerScrolledRef.current = false;\n } else if (contentContainer && scrollbarContainer) {\n const [pctScrollLeft, pctScrollTop] = getPctScroll(scrollbarContainer);\n const rootScrollLeft = Math.round(pctScrollLeft * maxScrollLeft);\n const rootScrollTop = Math.round(pctScrollTop * maxScrollTop);\n contentContainer.scrollTo({\n left: rootScrollLeft,\n top: rootScrollTop,\n behavior: \"auto\",\n });\n }\n }, [maxScrollLeft, maxScrollTop]);\n\n const handleContentContainerScroll = useCallback(() => {\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n const { current: scrollPos } = scrollPosRef;\n\n if (contentContainer && scrollbarContainer) {\n const { scrollLeft, scrollTop } = contentContainer;\n const [pctScrollLeft, pctScrollTop] = getPctScroll(contentContainer);\n contentContainerScrolledRef.current = true;\n\n scrollbarContainer.scrollLeft = Math.round(pctScrollLeft * maxScrollLeft);\n scrollbarContainer.scrollTop = Math.round(pctScrollTop * maxScrollTop);\n\n if (scrollPos.scrollTop !== scrollTop) {\n scrollPos.scrollTop = scrollTop;\n onVerticalScroll?.(scrollTop, pctScrollTop);\n }\n if (scrollPos.scrollLeft !== scrollLeft) {\n scrollPos.scrollLeft = scrollLeft;\n onHorizontalScroll?.(scrollLeft);\n }\n }\n }, [maxScrollLeft, maxScrollTop, onHorizontalScroll, onVerticalScroll]);\n\n const handleAttachScrollbarContainer = useCallback(\n (el: HTMLDivElement) => {\n scrollbarContainerRef.current = el;\n el.addEventListener(\"scroll\", handleScrollbarContainerScroll, {\n passive: true,\n });\n },\n [handleScrollbarContainerScroll]\n );\n\n const handleDetachScrollbarContainer = useCallback(\n (el: HTMLDivElement) => {\n scrollbarContainerRef.current = null;\n el.removeEventListener(\"scroll\", handleScrollbarContainerScroll);\n },\n [handleScrollbarContainerScroll]\n );\n\n const handleAttachContentContainer = useCallback(\n (el: HTMLDivElement) => {\n contentContainerRef.current = el;\n el.addEventListener(\"scroll\", handleContentContainerScroll, {\n passive: true,\n });\n },\n [handleContentContainerScroll]\n );\n\n const handleDetachContentContainer = useCallback(\n (el: HTMLDivElement) => {\n contentContainerRef.current = null;\n el.removeEventListener(\"scroll\", handleContentContainerScroll);\n },\n [handleContentContainerScroll]\n );\n\n const contentContainerCallbackRef = useCallbackRef({\n onAttach: handleAttachContentContainer,\n onDetach: handleDetachContentContainer,\n });\n\n const scrollbarContainerCallbackRef = useCallbackRef({\n onAttach: handleAttachScrollbarContainer,\n onDetach: handleDetachScrollbarContainer,\n });\n\n const requestScroll: ScrollRequestHandler = useCallback((scrollRequest) => {\n const { current: scrollbarContainer } = contentContainerRef;\n if (scrollbarContainer) {\n contentContainerScrolledRef.current = false;\n if (scrollRequest.type === \"scroll-page\") {\n const { clientHeight, scrollLeft, scrollTop } = scrollbarContainer;\n const { direction } = scrollRequest;\n const scrollBy = direction === \"down\" ? clientHeight : -clientHeight;\n const newScrollTop = Math.min(\n Math.max(0, scrollTop + scrollBy),\n maxScrollTop\n );\n scrollbarContainer.scrollTo({\n top: newScrollTop,\n left: scrollLeft,\n behavior: \"auto\",\n });\n } else if (scrollRequest.type === \"scroll-end\") {\n const { direction } = scrollRequest;\n const scrollTo = direction === \"end\" ? maxScrollTop : 0;\n scrollbarContainer.scrollTo({\n top: scrollTo,\n left: scrollbarContainer.scrollLeft,\n behavior: \"auto\",\n });\n }\n }\n }, []);\n\n return {\n /** Ref to be assigned to ScrollbarContainer */\n scrollbarContainerRef: scrollbarContainerCallbackRef,\n /** Ref to be assigned to ContentContainer */\n contentContainerRef: contentContainerCallbackRef,\n /** Scroll the table */\n requestScroll,\n };\n};\n", "import { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { RowAtPositionFunc } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useRef } from \"react\";\nimport { ViewportMeasurements } from \"@vuu-ui/vuu-table\";\n\nexport interface VirtualViewportHookProps {\n columns: KeyedColumnDescriptor[];\n getRowAtPosition: RowAtPositionFunc;\n setRange: (range: VuuRange) => void;\n viewportMeasurements: ViewportMeasurements;\n}\n\nexport const useVirtualViewport = ({\n columns,\n getRowAtPosition,\n setRange,\n viewportMeasurements,\n}: VirtualViewportHookProps) => {\n const firstRowRef = useRef<number>(-1);\n const { contentWidth, rowCount: viewportRowCount } = viewportMeasurements;\n\n const handleVerticalScroll = useCallback(\n (scrollTop: number) => {\n const firstRow = getRowAtPosition(scrollTop);\n if (firstRow !== firstRowRef.current) {\n firstRowRef.current = firstRow;\n setRange({ from: firstRow, to: firstRow + viewportRowCount });\n }\n },\n [getRowAtPosition, setRange, viewportRowCount]\n );\n\n return {\n onVerticalScroll: handleVerticalScroll,\n };\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["isTypeDescriptor", "isTypeDescriptor", "isTypeDescriptor", "registerComponent", "cx", "jsx", "jsxs", "classBase", "isTypeDescriptor", "cx", "registerComponent", "
|
|
3
|
+
"sources": ["../../../packages/vuu-table-extras/src/cell-edit-validators/CaseValidator.ts", "../../../packages/vuu-table-extras/src/cell-edit-validators/PatternValidator.ts", "../../../packages/vuu-table-extras/src/cell-renderers/background-cell/BackgroundCell.tsx", "../../../packages/vuu-table-extras/src/cell-renderers/background-cell/useDirection.ts", "../../../packages/vuu-table-extras/src/cell-renderers/progress-cell/ProgressCell.tsx", "../../../packages/vuu-table-extras/src/cell-renderers-next/background-cell/BackgroundCell.tsx", "../../../packages/vuu-table-extras/src/cell-renderers-next/background-cell/useDirection.ts", "../../../packages/vuu-table-extras/src/column-list/ColumnList.tsx", "../../../packages/vuu-table-extras/src/column-settings/ColumnSettingsPanel.tsx", "../../../packages/vuu-table-extras/src/column-formatting-settings/ColumnFormattingPanel.tsx", "../../../packages/vuu-table-extras/src/column-formatting-settings/NumericFormattingSettings.tsx", "../../../packages/vuu-table-extras/src/column-settings/useColumnSettings.ts", "../../../packages/vuu-table-extras/src/column-expression-panel/ColumnExpressionPanel.tsx", "../../../packages/vuu-table-extras/src/column-expression-input/useColumnExpressionEditor.ts", "../../../packages/vuu-table-extras/src/column-expression-input/column-language-parser/ColumnExpressionLanguage.ts", "../../../packages/vuu-table-extras/src/column-expression-input/column-language-parser/generated/column-parser.js", "../../../packages/vuu-table-extras/src/column-expression-input/column-language-parser/ColumnExpressionTreeWalker.ts", "../../../packages/vuu-table-extras/src/column-expression-input/column-language-parser/column-expression-parse-utils.ts", "../../../packages/vuu-table-extras/src/column-expression-input/highlighting.ts", "../../../packages/vuu-table-extras/src/column-expression-input/theme.ts", "../../../packages/vuu-table-extras/src/column-expression-input/useColumnAutoComplete.ts", "../../../packages/vuu-table-extras/src/column-expression-input/ColumnExpressionInput.tsx", "../../../packages/vuu-table-extras/src/column-expression-input/useColumnExpressionSuggestionProvider.ts", "../../../packages/vuu-table-extras/src/column-expression-input/column-function-descriptors.ts", "../../../packages/vuu-table-extras/src/column-expression-input/functionDocInfo.ts", "../../../packages/vuu-table-extras/src/column-expression-panel/useColumnExpression.ts", "../../../packages/vuu-table-extras/src/datasource-stats/DatasourceStats.tsx", "../../../packages/vuu-table-extras/src/table-settings/TableSettingsPanel.tsx", "../../../packages/vuu-table-extras/src/table-settings/useTableSettings.ts", "../../../packages/vuu-table/src/table/ColumnResizer.tsx", "../../../packages/vuu-table/src/table/context-menu/buildContextMenuDescriptors.ts", "../../../packages/vuu-table/src/table/context-menu/useTableContextMenu.ts", "../../../packages/vuu-table/src/table/Table.tsx", "../../../packages/vuu-table/src/table/RowBasedTable.tsx", "../../../packages/vuu-table/src/table/TableRow.tsx", "../../../packages/vuu-table/src/table/TableCell.tsx", "../../../packages/vuu-table/src/table/TableGroupCell.tsx", "../../../packages/vuu-table/src/table/TableGroupHeaderCell.tsx", "../../../packages/vuu-table/src/table/useTableColumnResize.tsx", "../../../packages/vuu-table/src/table/TableHeaderCell.tsx", "../../../packages/vuu-table/src/table/SortIndicator.tsx", "../../../packages/vuu-table/src/table/filter-indicator.tsx", "../../../packages/vuu-table/src/table/useTable.ts", "../../../packages/vuu-table/src/table/useDataSource.ts", "../../../packages/vuu-table/src/table/useDraggableColumn.ts", "../../../packages/vuu-table/src/table/useKeyboardNavigation.ts", "../../../packages/vuu-table/src/table/keyUtils.ts", "../../../packages/vuu-table/src/table/useMeasuredContainer.ts", "../../../packages/vuu-table/src/table/useResizeObserver.ts", "../../../packages/vuu-table/src/table/useSelection.ts", "../../../packages/vuu-table/src/table/useTableModel.ts", "../../../packages/vuu-table/src/table/useTableScroll.ts", "../../../packages/vuu-table/src/table-next/useTableViewport.ts", "../../../packages/vuu-table/src/table/useVirtualViewport.ts", "../../../packages/vuu-table/src/table/cell-renderers/json-cell/JsonCell.tsx", "../../../packages/vuu-table/src/table-next/header-cell/GroupHeaderCell.tsx", "../../../packages/vuu-table/src/table-next/column-resizing/ColumnResizer.tsx", "../../../packages/vuu-table/src/table-next/column-resizing/useTableColumnResize.tsx", "../../../packages/vuu-table/src/table-next/useCell.ts", "../../../packages/vuu-table/src/table-next/column-header-pill/ColumnHeaderPill.tsx", "../../../packages/vuu-table/src/table-next/column-header-pill/GroupColumnPill.tsx", "../../../packages/vuu-table/src/table-next/column-header-pill/SortIndicator.tsx", "../../../packages/vuu-table/src/table-next/header-cell/GroupHeaderCellNext.tsx", "../../../packages/vuu-table/src/table-next/header-cell/HeaderCell.tsx", "../../../packages/vuu-table/src/table-next/column-menu/ColumnMenu.tsx", "../../../packages/vuu-table/src/table-next/TableNext.tsx", "../../../packages/vuu-table/src/table-next/Row.tsx", "../../../packages/vuu-table/src/table-next/table-cell/TableCell.tsx", "../../../packages/vuu-table/src/table-next/table-cell/TableGroupCell.tsx", "../../../packages/vuu-table/src/table-next/useTableNext.ts", "../../../packages/vuu-table/src/table-next/useKeyboardNavigation.ts", "../../../packages/vuu-table/src/table-next/table-config.ts", "../../../packages/vuu-table/src/table-next/useDataSource.ts", "../../../packages/vuu-table/src/table-next/moving-window.ts", "../../../packages/vuu-table/src/table-next/useInitialValue.ts", "../../../packages/vuu-table/src/table-next/useTableContextMenu.ts", "../../../packages/vuu-table/src/table-next/useCellEditing.ts", "../../../packages/vuu-table/src/table-next/useTableModel.ts", "../../../packages/vuu-table/src/table-next/useTableScroll.ts", "../../../packages/vuu-table/src/table-next/useVirtualViewport.ts", "../../../packages/vuu-table/src/table-next/cell-renderers/dropdown-cell/DropdownCell.tsx", "../../../packages/vuu-table/src/table-next/cell-renderers/input-cell/InputCell.tsx", "../../../packages/vuu-table-extras/src/useTableAndColumnSettings.ts"],
|
|
4
|
+
"sourcesContent": ["import { EditRuleValidator, registerComponent } from \"@vuu-ui/vuu-utils\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\n\nconst isString = (value: VuuRowDataItemType): value is string =>\n typeof value === \"string\";\n\nexport const CaseValidator: EditRuleValidator = (rule, value) => {\n if (isString(value)) {\n if (value === \"\") {\n return true;\n } else if (rule.value === \"lower\" && value.toLowerCase() !== value) {\n return \"value must be all lowercase\";\n } else if (rule.value === \"upper\" && value.toUpperCase() !== value) {\n return \"value must be all uppercase\";\n } else {\n return true;\n }\n } else {\n return \"value must be a string\";\n }\n};\n\nregisterComponent(\"vuu-case\", CaseValidator, \"data-edit-validator\", {});\n", "import { EditRuleValidator, registerComponent } from \"@vuu-ui/vuu-utils\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\n\nconst isString = (value: VuuRowDataItemType): value is string =>\n typeof value === \"string\";\n\nconst defaultMessage = \"value does not match expected pattern\";\n\nexport const PatternValidator: EditRuleValidator = (rule, value) => {\n if (typeof rule.value !== \"string\") {\n throw Error(\"Pattern validation rule must provide pattern\");\n }\n if (isString(value)) {\n if (value === \"\") {\n return true;\n } else {\n const { message = defaultMessage } = rule;\n const pattern = new RegExp(rule.value);\n return pattern.test(value) || message;\n }\n } else {\n return \"value must be a string\";\n }\n};\n\nregisterComponent(\"vuu-pattern\", PatternValidator, \"data-edit-validator\", {});\n", "import { ColumnType, TableCellProps } from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n DOWN1,\n DOWN2,\n isTypeDescriptor,\n metadataKeys,\n registerComponent,\n UP1,\n UP2,\n} from \"@vuu-ui/vuu-utils\";\nimport cx from \"classnames\";\nimport { useDirection } from \"./useDirection\";\n\nimport \"./BackgroundCell.css\";\nimport \"./FlashingBackground.css\";\n\nconst CHAR_ARROW_UP = String.fromCharCode(11014);\nconst CHAR_ARROW_DOWN = String.fromCharCode(11015);\n\nconst { KEY } = metadataKeys;\n\nconst classBase = \"vuuBackgroundCellDeprecated\";\n\n// TODO these sre repeated from PriceFormatter - where shoud they live ?\nconst FlashStyle = {\n ArrowOnly: \"arrow\",\n BackgroundOnly: \"bg-only\",\n ArrowBackground: \"arrow-bg\",\n};\n\nconst getFlashStyle = (colType?: ColumnType) => {\n if (isTypeDescriptor(colType) && colType.renderer) {\n if (\"flashStyle\" in colType.renderer) {\n return colType.renderer[\"flashStyle\"];\n }\n }\n return FlashStyle.BackgroundOnly;\n};\n\nconst BackgroundCell = ({ column, row }: TableCellProps) => {\n //TODO what about click handling\n\n const { key, type, valueFormatter } = column;\n const value = row[key];\n const flashStyle = getFlashStyle(type);\n const direction = useDirection(row[KEY], value, column);\n const arrow =\n flashStyle === FlashStyle.ArrowOnly ||\n flashStyle === FlashStyle.ArrowBackground\n ? direction === UP1 || direction === UP2\n ? CHAR_ARROW_UP\n : direction === DOWN1 || direction === DOWN2\n ? CHAR_ARROW_DOWN\n : null\n : null;\n\n const dirClass = direction ? ` ` + direction : \"\";\n\n const className = cx(classBase, dirClass, {\n [`${classBase}-arrowOnly`]: flashStyle === FlashStyle.ArrowOnly,\n [`${classBase}-arrowBackground`]: flashStyle === FlashStyle.ArrowBackground,\n });\n\n return (\n <div className={className} tabIndex={-1}>\n <div className={`${classBase}-flasher`}>{arrow}</div>\n {valueFormatter(row[column.key])}\n </div>\n );\n};\n\nregisterComponent(\"background\", BackgroundCell, \"cell-renderer\", {\n description: \"Background Cell renderer for VuuTable\",\n label: \"Background Cell (deprecated)\",\n serverDataType: [\"long\", \"int\", \"double\"],\n});\n", "import { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n getMovingValueDirection,\n isTypeDescriptor,\n isValidNumber,\n valueChangeDirection,\n} from \"@vuu-ui/vuu-utils\";\nimport { useEffect, useRef } from \"react\";\n\nconst INITIAL_VALUE = [undefined, undefined, undefined, undefined];\n\ntype State = [string, unknown, KeyedColumnDescriptor, valueChangeDirection];\n\nexport function useDirection(\n key: string,\n value: unknown,\n column: KeyedColumnDescriptor\n) {\n const ref = useRef<State>();\n const [prevKey, prevValue, prevColumn, prevDirection] =\n ref.current || INITIAL_VALUE;\n\n const { type: dataType } = column;\n const decimals = isTypeDescriptor(dataType)\n ? dataType.formatting?.decimals\n : undefined;\n\n const direction =\n key === prevKey &&\n isValidNumber(value) &&\n isValidNumber(prevValue) &&\n column === prevColumn\n ? getMovingValueDirection(value, prevDirection, prevValue, decimals)\n : \"\";\n\n useEffect(() => {\n ref.current = [key, value, column, direction];\n });\n\n return direction;\n}\n", "import { TableCellProps } from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n isColumnTypeRenderer,\n isTypeDescriptor,\n isValidNumber,\n registerComponent,\n} from \"@vuu-ui/vuu-utils\";\nimport cx from \"classnames\";\nimport { CSSProperties } from \"react\";\n\nimport \"./ProgressCell.css\";\n\nconst classBase = \"vuuProgressCell\";\n\nconst ProgressCell = ({ column, columnMap, row }: TableCellProps) => {\n //TODO what about click handling\n\n const { type } = column;\n const value = row[column.key];\n let showProgress = false;\n let percentage = 0;\n\n if (isTypeDescriptor(type) && isColumnTypeRenderer(type.renderer)) {\n const { associatedField } = type.renderer;\n if (associatedField) {\n const associatedValue = row[columnMap[associatedField]];\n if (typeof isValidNumber(value) && isValidNumber(associatedValue)) {\n percentage = Math.min(Math.round((value / associatedValue) * 100), 100);\n percentage = Math.min(Math.round((value / associatedValue) * 100), 100);\n showProgress = isFinite(percentage);\n } else {\n // Temp workaround for bug on server that sends aggregated values as strings\n const floatValue = parseFloat(value as string);\n if (Number.isFinite(floatValue)) {\n const floatOtherValue = parseFloat(associatedValue as string);\n if (Number.isFinite(floatOtherValue)) {\n percentage = Math.min(\n Math.round((floatValue / floatOtherValue) * 100),\n 100\n );\n showProgress = isFinite(percentage);\n }\n }\n }\n } else {\n throw Error(\"ProgressCell associatedField is required to render\");\n }\n }\n\n const className = cx(classBase, {});\n\n return (\n <div className={className} tabIndex={-1}>\n {showProgress ? (\n <span className={`${classBase}-track`}>\n <span className={`${classBase}-bg`} />\n <span\n className={`${classBase}-bar`}\n style={\n { \"--progress-bar-pct\": `-${100 - percentage}%` } as CSSProperties\n }\n />\n </span>\n ) : null}\n <span className={`${classBase}-text`}>{`${percentage} %`}</span>\n </div>\n );\n};\n\nregisterComponent(\"vuu.progress\", ProgressCell, \"cell-renderer\", {\n description: \"Progress formatter\",\n label: \"Progress formatter\",\n serverDataType: [\"long\", \"int\", \"double\"],\n});\n", "import { ColumnType, TableCellProps } from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n DOWN1,\n DOWN2,\n isTypeDescriptor,\n metadataKeys,\n registerComponent,\n UP1,\n UP2,\n} from \"@vuu-ui/vuu-utils\";\nimport cx from \"classnames\";\nimport { useDirection } from \"./useDirection\";\n\nimport \"./BackgroundCell.css\";\nimport \"./FlashingBackground.css\";\n\nconst CHAR_ARROW_UP = String.fromCharCode(11014);\nconst CHAR_ARROW_DOWN = String.fromCharCode(11015);\n\nconst { KEY } = metadataKeys;\n\nconst classBase = \"vuuBackgroundCell\";\n\n// TODO these sre repeated from PriceFormatter - where shoud they live ?\nconst FlashStyle = {\n ArrowOnly: \"arrow\",\n BackgroundOnly: \"bg-only\",\n ArrowBackground: \"arrow-bg\",\n};\n\nconst getFlashStyle = (colType?: ColumnType) => {\n if (isTypeDescriptor(colType) && colType.renderer) {\n if (\"flashStyle\" in colType.renderer) {\n return colType.renderer[\"flashStyle\"];\n }\n }\n return FlashStyle.BackgroundOnly;\n};\n\n// export to avoid tree shaking, component is not consumed directly\nexport const BackgroundCell = ({ column, row }: TableCellProps) => {\n //TODO what about click handling\n\n const { key, type, valueFormatter } = column;\n const value = row[key];\n const flashStyle = getFlashStyle(type);\n const direction = useDirection(row[KEY], value, column);\n const arrow =\n flashStyle === FlashStyle.ArrowOnly ||\n flashStyle === FlashStyle.ArrowBackground\n ? direction === UP1 || direction === UP2\n ? CHAR_ARROW_UP\n : direction === DOWN1 || direction === DOWN2\n ? CHAR_ARROW_DOWN\n : null\n : null;\n\n const dirClass = direction ? ` ` + direction : \"\";\n\n const className = cx(classBase, dirClass, {\n [`${classBase}-arrowOnly`]: flashStyle === FlashStyle.ArrowOnly,\n [`${classBase}-arrowBackground`]: flashStyle === FlashStyle.ArrowBackground,\n });\n\n return (\n <div className={className} tabIndex={-1}>\n <div className={`${classBase}-flasher`}>{arrow}</div>\n {valueFormatter(row[column.key])}\n </div>\n );\n};\n\nconsole.log(\"register BackgroundCellNext\");\n\nregisterComponent(\"background-next\", BackgroundCell, \"cell-renderer\", {\n description: \"Change background color of cell when value changes\",\n label: \"Background Flash\",\n serverDataType: [\"long\", \"int\", \"double\"],\n});\n", "import { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n getMovingValueDirection,\n isTypeDescriptor,\n isValidNumber,\n valueChangeDirection,\n} from \"@vuu-ui/vuu-utils\";\nimport { useEffect, useRef } from \"react\";\n\nconst INITIAL_VALUE = [undefined, undefined, undefined, undefined];\n\ntype State = [string, unknown, KeyedColumnDescriptor, valueChangeDirection];\n\nexport function useDirection(\n key: string,\n value: unknown,\n column: KeyedColumnDescriptor\n) {\n const ref = useRef<State>();\n const [prevKey, prevValue, prevColumn, prevDirection] =\n ref.current || INITIAL_VALUE;\n\n const { type: dataType } = column;\n const decimals = isTypeDescriptor(dataType)\n ? dataType.formatting?.decimals\n : undefined;\n\n const direction =\n key === prevKey &&\n isValidNumber(value) &&\n isValidNumber(prevValue) &&\n column === prevColumn\n ? getMovingValueDirection(value, prevDirection, prevValue, decimals)\n : \"\";\n\n useEffect(() => {\n ref.current = [key, value, column, direction];\n });\n\n return direction;\n}\n", "import {\n List,\n ListItem,\n ListItemProps,\n ListProps,\n} from \"@vuu-ui/vuu-ui-controls\";\nimport { Checkbox } from \"@salt-ds/core\";\nimport { Switch } from \"@salt-ds/lab\";\nimport cx from \"classnames\";\nimport { ColumnDescriptor } from \"packages/vuu-datagrid-types\";\nimport { HTMLAttributes, SyntheticEvent, useCallback } from \"react\";\nimport { ColumnItem } from \"../table-settings\";\n\nimport \"./ColumnList.css\";\n\nconst classBase = \"vuuColumnList\";\nconst classBaseListItem = \"vuuColumnListItem\";\n\nexport type ColumnChangeHandler = (\n columnName: string,\n propertyName: keyof ColumnDescriptor | \"subscribed\",\n value: string | number | boolean\n) => void;\n\nexport interface ColumnListProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n columnItems: ColumnItem[];\n onChange: ColumnChangeHandler;\n onMoveListItem: ListProps[\"onMoveListItem\"];\n}\n\nconst ColumnListItem = ({\n className: classNameProp,\n item,\n ...listItemProps\n}: ListItemProps<ColumnItem>) => {\n return (\n <ListItem\n {...listItemProps}\n className={cx(classNameProp, classBaseListItem)}\n data-name={item?.name}\n >\n {item?.isCalculated ? (\n <span className={`${classBase}-icon`} data-icon=\"function\" />\n ) : (\n <Switch className={`${classBase}-switch`} checked={item?.subscribed} />\n )}\n <span className={`${classBase}-text`}>{item?.label ?? item?.name}</span>\n <Checkbox\n className={`${classBase}-checkBox`}\n checked={item?.hidden !== true}\n disabled={item?.subscribed !== true}\n />\n </ListItem>\n );\n};\n\nexport const ColumnList = ({\n columnItems,\n onChange,\n onMoveListItem,\n ...htmlAttributes\n}: ColumnListProps) => {\n const handleChange = useCallback(\n (evt: SyntheticEvent) => {\n const input = evt.target as HTMLInputElement;\n const listItem = input.closest(`.${classBaseListItem}`) as HTMLElement;\n const {\n dataset: { name },\n } = listItem;\n if (name) {\n const saltSwitch = input.closest(`.${classBase}-switch`) as HTMLElement;\n const saltCheckbox = input.closest(\n `.${classBase}-checkBox`\n ) as HTMLElement;\n\n if (saltSwitch) {\n onChange(name, \"subscribed\", input.checked);\n } else if (saltCheckbox) {\n onChange(name, \"hidden\", input.checked === false);\n }\n }\n },\n [onChange]\n );\n return (\n <div {...htmlAttributes} className={classBase}>\n <div className={`${classBase}-header`}>\n <span>Column Selection</span>\n </div>\n <div className={`${classBase}-colHeadings`}>\n <span>Column subscription</span>\n <span>Visibility</span>\n </div>\n <List<ColumnItem, \"none\">\n ListItem={ColumnListItem}\n allowDragDrop\n height=\"100%\"\n onChange={handleChange}\n onMoveListItem={onMoveListItem}\n selectionStrategy=\"none\"\n source={columnItems}\n itemHeight={33}\n />\n </div>\n );\n};\n", "import { ColumnDescriptor, TableConfig } from \"@vuu-ui/vuu-datagrid-types\";\nimport { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport { getDefaultAlignment, isCalculatedColumn } from \"@vuu-ui/vuu-utils\";\nimport {\n Button,\n FormField,\n FormFieldLabel,\n ToggleButton,\n ToggleButtonGroup,\n} from \"@salt-ds/core\";\nimport { HTMLAttributes } from \"react\";\nimport { ColumnFormattingPanel } from \"../column-formatting-settings\";\nimport { useColumnSettings } from \"./useColumnSettings\";\nimport { ColumnExpressionPanel } from \"../column-expression-panel\";\nimport { VuuInput } from \"@vuu-ui/vuu-ui-controls\";\n\nimport \"./ColumnSettingsPanel.css\";\n\nconst classBase = \"vuuColumnSettingsPanel\";\n\nexport interface ColumnSettingsProps extends HTMLAttributes<HTMLDivElement> {\n column: ColumnDescriptor;\n onConfigChange: (config: TableConfig) => void;\n onCreateCalculatedColumn: (column: ColumnDescriptor) => void;\n tableConfig: TableConfig;\n vuuTable: VuuTable;\n}\n\nexport const ColumnSettingsPanel = ({\n column: columnProp,\n onConfigChange,\n onCreateCalculatedColumn,\n tableConfig,\n vuuTable,\n}: ColumnSettingsProps) => {\n const isNewCalculatedColumn = columnProp.name === \"::\";\n const {\n availableRenderers,\n selectedCellRenderer,\n column,\n navigateNextColumn,\n navigatePrevColumn,\n onChange,\n onChangeFormatting,\n onChangeRenderer,\n onInputCommit,\n onSave,\n } = useColumnSettings({\n column: columnProp,\n onConfigChange,\n onCreateCalculatedColumn,\n tableConfig,\n });\n\n const {\n serverDataType,\n align = getDefaultAlignment(serverDataType),\n name,\n label = name,\n pin,\n width,\n } = column;\n\n return (\n <div className={classBase}>\n <div className={`${classBase}-header`}>\n <span>{name}</span>\n </div>\n\n <FormField data-field=\"column-label\">\n <FormFieldLabel>Column Label</FormFieldLabel>\n <VuuInput\n className=\"vuuInput\"\n onChange={onChange}\n onCommit={onInputCommit}\n value={label}\n />\n </FormField>\n\n <FormField data-field=\"column-width\">\n <FormFieldLabel>Column Width</FormFieldLabel>\n <VuuInput\n className=\"vuuInput\"\n onChange={onChange}\n value={width}\n onCommit={onInputCommit}\n />\n </FormField>\n <FormField data-field=\"column-alignment\">\n <FormFieldLabel>Alignment</FormFieldLabel>\n <ToggleButtonGroup\n className=\"vuuToggleButtonGroup\"\n onChange={onChange}\n value={align}\n >\n <ToggleButton\n data-icon=\"align-left\"\n className=\"vuuIconToggleButton\"\n value=\"left\"\n />\n <ToggleButton\n data-icon=\"align-right\"\n className=\"vuuIconToggleButton\"\n value=\"right\"\n />\n </ToggleButtonGroup>\n </FormField>\n <FormField data-field=\"column-pin\">\n <FormFieldLabel>Pin Column</FormFieldLabel>\n <ToggleButtonGroup\n className=\"vuuToggleButtonGroup\"\n onChange={onChange}\n value={pin ?? \"\"}\n >\n <ToggleButton\n className=\"vuuIconToggleButton\"\n data-icon=\"cross-circle\"\n value=\"\"\n />\n <ToggleButton\n className=\"vuuIconToggleButton\"\n data-icon=\"pin-left\"\n value=\"left\"\n />\n <ToggleButton\n className=\"vuuIconToggleButton\"\n data-icon=\"pin-float\"\n value=\"floating\"\n />\n <ToggleButton\n className=\"vuuIconToggleButton\"\n data-icon=\"pin-right\"\n value=\"right\"\n />\n </ToggleButtonGroup>\n </FormField>\n <ColumnFormattingPanel\n availableRenderers={availableRenderers}\n selectedCellRenderer={selectedCellRenderer}\n column={column}\n onChangeFormatting={onChangeFormatting}\n onChangeRenderer={onChangeRenderer}\n />\n\n {isCalculatedColumn(column.name) ? (\n <ColumnExpressionPanel\n column={column}\n onSave={onSave}\n tableConfig={tableConfig}\n vuuTable={vuuTable}\n />\n ) : (\n <div\n className={`${classBase}-buttonBar`}\n data-align={isNewCalculatedColumn ? \"right\" : undefined}\n >\n <Button\n className={`${classBase}-buttonNavPrev`}\n variant=\"secondary\"\n data-icon=\"arrow-left\"\n onClick={navigatePrevColumn}\n >\n PREVIOUS\n </Button>\n <Button\n className={`${classBase}-buttonNavNext`}\n variant=\"secondary\"\n data-icon=\"arrow-right\"\n onClick={navigateNextColumn}\n >\n NEXT\n </Button>\n </div>\n )}\n </div>\n );\n};\n", "import { ColumnDescriptor, TypeFormatting } from \"@vuu-ui/vuu-datagrid-types\";\nimport { Dropdown, SelectionChangeHandler } from \"@vuu-ui/vuu-ui-controls\";\nimport { CellRendererDescriptor } from \"@vuu-ui/vuu-utils\";\nimport { FormField, FormFieldLabel } from \"@salt-ds/core\";\nimport cx from \"classnames\";\nimport { HTMLAttributes, useMemo } from \"react\";\nimport { NumericFormattingSettings } from \"./NumericFormattingSettings\";\n\n// import \"./ColumnTypePanel.css\";\n\nconst classBase = \"vuuColumnFormattingPanel\";\n\nexport interface ColumnFormattingPanelProps\n extends HTMLAttributes<HTMLDivElement> {\n availableRenderers: CellRendererDescriptor[];\n selectedCellRenderer: CellRendererDescriptor | null;\n column: ColumnDescriptor;\n onChangeFormatting: (formatting: TypeFormatting) => void;\n onChangeRenderer: SelectionChangeHandler<CellRendererDescriptor>;\n}\n\nconst itemToString = (item: CellRendererDescriptor) => item.label ?? item.name;\n\nexport const ColumnFormattingPanel = ({\n availableRenderers,\n selectedCellRenderer,\n className,\n column,\n onChangeFormatting,\n onChangeRenderer,\n ...htmlAttributes\n}: ColumnFormattingPanelProps) => {\n const content = useMemo(() => {\n switch (column.serverDataType) {\n case \"double\":\n case \"int\":\n case \"long\":\n return (\n <NumericFormattingSettings\n column={column}\n onChange={onChangeFormatting}\n />\n );\n default:\n return null;\n }\n }, [column, onChangeFormatting]);\n\n const { serverDataType = \"string\" } = column;\n\n return (\n <div {...htmlAttributes} className={`vuuColumnSettingsPanel-header`}>\n <div>Formatting</div>\n\n <FormField>\n <FormFieldLabel>Renderer</FormFieldLabel>\n <Dropdown<CellRendererDescriptor>\n className={cx(`${classBase}-renderer`)}\n itemToString={itemToString}\n onSelectionChange={onChangeRenderer}\n selected={selectedCellRenderer}\n source={availableRenderers}\n width=\"100%\"\n />\n </FormField>\n <div\n className={cx(classBase, className, `${classBase}-${serverDataType}`)}\n >\n {content}\n </div>\n </div>\n );\n};\n", "import { FormField, FormFieldLabel, Input } from \"@salt-ds/core\";\nimport { Switch } from \"@salt-ds/lab\";\nimport { ColumnDescriptor, TypeFormatting } from \"packages/vuu-datagrid-types\";\nimport { getTypeSettingsFromColumn } from \"@vuu-ui/vuu-utils\";\nimport {\n ChangeEvent,\n KeyboardEvent,\n SyntheticEvent,\n useCallback,\n useState,\n} from \"react\";\n\nconst classBase = \"vuuFormattingSettings\";\n\nexport interface NumericFormattingSettingsProps {\n column: ColumnDescriptor;\n onChange: (formatting: TypeFormatting) => void;\n}\n\nexport const NumericFormattingSettings = ({\n column,\n onChange,\n}: NumericFormattingSettingsProps) => {\n const [formattingSettings, setFormattingSettings] = useState<TypeFormatting>(\n getTypeSettingsFromColumn(column)\n );\n\n const handleInputKeyDown = useCallback(\n (evt: KeyboardEvent<HTMLInputElement>) => {\n if (evt.key === \"Enter\" || evt.key === \"Tab\") {\n onChange(formattingSettings);\n }\n },\n [formattingSettings, onChange]\n );\n\n const handleChangeDecimals = useCallback(\n (evt: SyntheticEvent) => {\n const { value } = evt.target as HTMLFormElement;\n const numericValue: number | undefined =\n value === \"\"\n ? undefined\n : isNaN(parseInt(value))\n ? undefined\n : parseInt(value);\n\n const newFormattingSettings = {\n ...formattingSettings,\n decimals: numericValue,\n };\n setFormattingSettings(newFormattingSettings);\n },\n [formattingSettings]\n );\n\n const handleChangeAlignDecimals = useCallback(\n (evt: ChangeEvent<HTMLInputElement>) => {\n const { checked } = evt.target as HTMLInputElement;\n const newFormattingSettings = {\n ...formattingSettings,\n alignOnDecimals: checked,\n };\n setFormattingSettings(newFormattingSettings);\n onChange(newFormattingSettings);\n },\n [formattingSettings, onChange]\n );\n\n const handleChangeZeroPad = useCallback(\n (evt: ChangeEvent<HTMLInputElement>) => {\n const { checked } = evt.target as HTMLInputElement;\n const newFormattingSettings = {\n ...formattingSettings,\n zeroPad: checked,\n };\n setFormattingSettings(newFormattingSettings);\n onChange(newFormattingSettings);\n },\n [formattingSettings, onChange]\n );\n\n return (\n <div className={classBase}>\n <FormField data-field=\"decimals\">\n <FormFieldLabel>Number of decimals</FormFieldLabel>\n <Input\n className=\"vuuInput\"\n onChange={handleChangeDecimals}\n onKeyDown={handleInputKeyDown}\n value={formattingSettings.decimals ?? \"\"}\n />\n </FormField>\n\n <FormField labelPlacement=\"left\">\n <FormFieldLabel>Align on decimals</FormFieldLabel>\n <Switch\n checked={formattingSettings.alignOnDecimals}\n onChange={handleChangeAlignDecimals}\n value=\"align-decimals\"\n />\n </FormField>\n <FormField labelPlacement=\"left\">\n <FormFieldLabel>Zero pad decimals</FormFieldLabel>\n <Switch\n checked={formattingSettings.zeroPad}\n onChange={handleChangeZeroPad}\n value=\"zero-pad\"\n />\n </FormField>\n </div>\n );\n};\n", "import {\n ColumnDescriptor,\n TableConfig,\n TypeFormatting,\n} from \"@vuu-ui/vuu-datagrid-types\";\n\nimport {\n CellRendererDescriptor,\n getRegisteredCellRenderers,\n isColumnTypeRenderer,\n isTypeDescriptor,\n isValidColumnAlignment,\n isValidPinLocation,\n setCalculatedColumnName,\n updateColumnRenderer,\n updateColumnType,\n} from \"@vuu-ui/vuu-utils\";\nimport { SelectionChangeHandler } from \"@vuu-ui/vuu-ui-controls\";\nimport {\n FormEventHandler,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { ColumnSettingsProps } from \"./ColumnSettingsPanel\";\n\nconst integerCellRenderers: CellRendererDescriptor[] = [\n {\n description: \"Default formatter for columns with data type integer\",\n label: \"Default Renderer (data type int, long)\",\n name: \"default-int\",\n },\n];\nconst doubleCellRenderers: CellRendererDescriptor[] = [\n {\n description: \"Default formatter for columns with data type double\",\n label: \"Default Renderer (data type double)\",\n name: \"default-double\",\n },\n ...getRegisteredCellRenderers(\"double\"),\n];\n\nconst stringCellRenderers: CellRendererDescriptor[] = [\n {\n description: \"Default formatter for columns with data type string\",\n label: \"Default Renderer (data type string)\",\n name: \"default-string\",\n },\n];\n\nconst getAvailableCellRenderers = (\n column: ColumnDescriptor\n): CellRendererDescriptor[] => {\n switch (column.serverDataType) {\n case \"char\":\n case \"string\":\n return stringCellRenderers;\n case \"int\":\n case \"long\":\n return integerCellRenderers;\n case \"double\":\n return doubleCellRenderers;\n default:\n return stringCellRenderers;\n }\n};\n\nconst getCellRendererDescriptor = (\n availableRenderers: CellRendererDescriptor[],\n column: ColumnDescriptor\n) => {\n if (isTypeDescriptor(column.type)) {\n const { renderer } = column.type;\n if (isColumnTypeRenderer(renderer)) {\n const cellRenderer = availableRenderers.find(\n (r) => r.name === renderer.name\n );\n if (cellRenderer) {\n return cellRenderer;\n }\n }\n }\n // retur the appropriate default value for the column\n const typedAvailableRenderers = getAvailableCellRenderers(column);\n return typedAvailableRenderers[0];\n};\n\nconst getFieldName = (input: HTMLInputElement): string => {\n const saltFormField = input.closest(\".saltFormField\") as HTMLElement;\n if (saltFormField && saltFormField.dataset.field) {\n const {\n dataset: { field },\n } = saltFormField;\n return field;\n } else {\n throw Error(\"named form field not found\");\n }\n};\n\nconst getColumn = (columns: ColumnDescriptor[], column: ColumnDescriptor) => {\n if (column.name === \"::\") {\n // this is a new calculated column\n return column;\n } else {\n const col = columns.find((col) => col.name === column.name);\n if (col) {\n return col;\n }\n throw Error(`columns does not contain column ${name}`);\n }\n};\n\nconst replaceColumn = (\n tableConfig: TableConfig,\n column: ColumnDescriptor\n): TableConfig => ({\n ...tableConfig,\n columns: tableConfig.columns.map((col) =>\n col.name === column.name ? column : col\n ),\n});\n\nexport const useColumnSettings = ({\n column: columnProp,\n onConfigChange,\n onCreateCalculatedColumn,\n tableConfig,\n}: Omit<ColumnSettingsProps, \"vuuTable\">) => {\n const [column, setColumn] = useState<ColumnDescriptor>(\n getColumn(tableConfig.columns, columnProp)\n );\n\n const availableRenderers = useMemo(() => {\n return getAvailableCellRenderers(column);\n }, [column]);\n\n const selectedCellRendererRef = useRef<CellRendererDescriptor | null>(\n getCellRendererDescriptor(availableRenderers, column)\n );\n\n const handleInputCommit = useCallback(() => {\n onConfigChange(replaceColumn(tableConfig, column));\n }, [column, onConfigChange, tableConfig]);\n\n const handleChange = useCallback<FormEventHandler>(\n (evt) => {\n const input = evt.target as HTMLInputElement;\n const fieldName = getFieldName(input);\n const { value } = input;\n switch (fieldName) {\n case \"column-label\":\n setColumn((state) => ({ ...state, label: value }));\n break;\n case \"column-name\":\n setColumn((state) => setCalculatedColumnName(state, value));\n break;\n case \"column-width\":\n setColumn((state) => ({ ...state, width: parseInt(value) }));\n break;\n case \"column-alignment\":\n if (isValidColumnAlignment(value)) {\n const newColumn: ColumnDescriptor = {\n ...column,\n align: value || undefined,\n };\n setColumn(newColumn);\n onConfigChange(replaceColumn(tableConfig, newColumn));\n }\n break;\n case \"column-pin\":\n if (isValidPinLocation(value)) {\n const newColumn: ColumnDescriptor = {\n ...column,\n pin: value || undefined,\n };\n setColumn(newColumn);\n onConfigChange(replaceColumn(tableConfig, newColumn));\n\n break;\n }\n }\n },\n [column, onConfigChange, tableConfig]\n );\n\n const handleChangeRenderer = useCallback<\n SelectionChangeHandler<CellRendererDescriptor>\n >(\n (evt, cellRenderer) => {\n if (cellRenderer) {\n const newColumn: ColumnDescriptor = updateColumnRenderer(\n column,\n cellRenderer\n );\n selectedCellRendererRef.current = cellRenderer;\n setColumn(newColumn);\n onConfigChange(replaceColumn(tableConfig, newColumn));\n }\n },\n [column, onConfigChange, tableConfig]\n );\n\n const handleChangeFormatting = useCallback(\n (formatting: TypeFormatting) => {\n const newColumn: ColumnDescriptor = updateColumnType(column, formatting);\n setColumn(newColumn);\n onConfigChange(replaceColumn(tableConfig, newColumn));\n },\n [column, onConfigChange, tableConfig]\n );\n\n const navigateColumn = useCallback(\n ({ moveBy }: { moveBy: number }) => {\n const { columns } = tableConfig;\n const index = columns.indexOf(column) + moveBy;\n const newColumn = columns[index];\n if (newColumn) {\n selectedCellRendererRef.current = getCellRendererDescriptor(\n availableRenderers,\n newColumn\n );\n setColumn(newColumn);\n }\n },\n [availableRenderers, column, tableConfig]\n );\n const navigateNextColumn = useCallback(() => {\n navigateColumn({ moveBy: 1 });\n }, [navigateColumn]);\n\n const navigatePrevColumn = useCallback(() => {\n navigateColumn({ moveBy: -1 });\n }, [navigateColumn]);\n\n const handleSaveCalculatedColumn = useCallback(\n (calculatedColumn: ColumnDescriptor) => {\n // TODO validate expression, unique name\n onCreateCalculatedColumn({\n ...column,\n ...calculatedColumn,\n });\n },\n [column, onCreateCalculatedColumn]\n );\n\n return {\n availableRenderers,\n selectedCellRenderer: selectedCellRendererRef.current,\n column,\n navigateNextColumn,\n navigatePrevColumn,\n onChange: handleChange,\n onChangeFormatting: handleChangeFormatting,\n onChangeRenderer: handleChangeRenderer,\n onInputCommit: handleInputCommit,\n onSave: handleSaveCalculatedColumn,\n };\n};\n", "import { ColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { Dropdown } from \"@vuu-ui/vuu-ui-controls\";\nimport {\n getCalculatedColumnExpression,\n getCalculatedColumnName,\n getCalculatedColumnType,\n} from \"@vuu-ui/vuu-utils\";\nimport { Button, FormField, FormFieldLabel, Input } from \"@salt-ds/core\";\nimport { HTMLAttributes, useCallback, useRef } from \"react\";\nimport {\n ColumnExpressionInput,\n useColumnExpressionSuggestionProvider,\n} from \"../column-expression-input\";\nimport { ColumnSettingsProps } from \"../column-settings\";\nimport { useColumnExpression } from \"./useColumnExpression\";\n\nconst classBase = \"vuuColumnExpressionPanel\";\n\nexport interface ColumnExpressionPanelProps\n extends HTMLAttributes<HTMLDivElement>,\n Pick<ColumnSettingsProps, \"tableConfig\" | \"vuuTable\"> {\n column: ColumnDescriptor;\n onSave: (column: ColumnDescriptor) => void;\n}\n\nexport const ColumnExpressionPanel = ({\n column: columnProp,\n onSave: onSaveProp,\n tableConfig,\n vuuTable,\n}: ColumnExpressionPanelProps) => {\n const typeRef = useRef<HTMLDivElement>(null);\n const { column, onChangeExpression, onChangeName, onChangeType, onSave } =\n useColumnExpression({ column: columnProp, onSave: onSaveProp });\n\n const suggestionProvider = useColumnExpressionSuggestionProvider({\n columns: tableConfig.columns,\n table: vuuTable,\n });\n\n const handleSubmitExpression = useCallback(() => {\n requestAnimationFrame(() => {\n typeRef.current?.querySelector(\"button\")?.focus();\n });\n }, []);\n\n return (\n <div className={classBase}>\n <div className=\"vuuColumnSettingsPanel-header\">\n <span>Calculation</span>\n </div>\n\n <FormField data-field=\"column-name\">\n <FormFieldLabel>Column Name</FormFieldLabel>\n <Input\n className=\"vuuInput\"\n onChange={onChangeName}\n // onKeyDown={onKeyDownColumnName}\n value={getCalculatedColumnName(column)}\n />\n </FormField>\n\n <FormField data-field=\"column-expression\">\n <FormFieldLabel>Expression</FormFieldLabel>\n <ColumnExpressionInput\n onChange={onChangeExpression}\n onSubmitExpression={handleSubmitExpression}\n source={getCalculatedColumnExpression(column)}\n suggestionProvider={suggestionProvider}\n />\n </FormField>\n <FormField data-field=\"type\">\n <FormFieldLabel>Column type</FormFieldLabel>\n <Dropdown\n className={`${classBase}-type`}\n onSelectionChange={onChangeType}\n ref={typeRef}\n selected={getCalculatedColumnType(column) || null}\n source={[\"double\", \"long\", \"string\"]}\n width=\"100%\"\n />\n </FormField>\n\n <div className=\"vuuColumnSettingsPanel-buttonBar\" data-align=\"right\">\n <Button className={`${classBase}-buttonCancel`} tabIndex={-1}>\n cancel\n </Button>\n <Button className={`${classBase}-buttonApply`} tabIndex={-1}>\n apply\n </Button>\n <Button\n className={`${classBase}-buttonSave`}\n onClick={onSave}\n variant=\"cta\"\n >\n save\n </Button>\n </div>\n </div>\n );\n};\n", "import {\n autocompletion,\n Completion,\n defaultKeymap,\n EditorState,\n EditorView,\n ensureSyntaxTree,\n keymap,\n minimalSetup,\n startCompletion,\n} from \"@vuu-ui/vuu-codemirror\";\nimport { createEl } from \"@vuu-ui/vuu-utils\";\nimport { MutableRefObject, useEffect, useMemo, useRef } from \"react\";\nimport { columnExpressionLanguageSupport } from \"./column-language-parser\";\nimport {\n ColumnDefinitionExpression,\n walkTree,\n} from \"./column-language-parser/ColumnExpressionTreeWalker\";\nimport { ColumnExpressionInputProps } from \"./ColumnExpressionInput\";\nimport { vuuHighlighting } from \"./highlighting\";\nimport { vuuTheme } from \"./theme\";\nimport {\n ApplyCompletion,\n useColumnAutoComplete,\n} from \"./useColumnAutoComplete\";\n\nexport type ColumnExpressionOperator = \"Times\" | \"Divide\" | \"Minus\" | \"Plus\";\n\nexport type ColumnExpressionSuggestionType =\n | \"column\"\n | \"columnValue\"\n | \"expression\"\n | \"condition-operator\"\n | \"operator\"\n | \"relational-operator\";\n\nexport type ColumnExpressionSuggestionOptions = {\n columnName?: string;\n functionName?: string;\n operator?: ColumnExpressionOperator;\n prefix?: string;\n startsWith?: string;\n selection?: string[];\n};\n\n// TODO move this somewhere neutral\nexport interface IExpressionSuggestionProvider {\n getSuggestions: (\n valueType: ColumnExpressionSuggestionType,\n options?: ColumnExpressionSuggestionOptions\n ) => Promise<Completion[]>;\n isPartialMatch: (\n valueType: ColumnExpressionSuggestionType,\n columnName?: string,\n text?: string | undefined\n ) => Promise<boolean>;\n}\n\nexport interface ExpressionSuggestionConsumer {\n suggestionProvider: IExpressionSuggestionProvider;\n}\n\nconst getView = (ref: MutableRefObject<EditorView | undefined>): EditorView => {\n if (ref.current == undefined) {\n throw Error(\"EditorView not defined\");\n }\n return ref.current;\n};\n\nconst getOptionClass = (/*completion: Completion*/) => {\n return \"vuuSuggestion\";\n};\n\nconst noop = () => console.log(\"noooop\");\n\nconst hasExpressionType = (\n completion: Completion\n): completion is Completion & { expressionType: string } =>\n \"expressionType\" in completion;\n\nconst injectOptionContent = (\n completion: Completion /*, state: EditorState*/\n) => {\n if (hasExpressionType(completion)) {\n const div = createEl(\"div\", \"expression-type-container\");\n const span = createEl(\"span\", \"expression-type\", completion.expressionType);\n div.appendChild(span);\n return div;\n } else {\n return null;\n }\n};\n\nexport const useColumnExpressionEditor = ({\n onChange,\n onSubmitExpression,\n source,\n suggestionProvider,\n}: ColumnExpressionInputProps) => {\n const editorRef = useRef<HTMLDivElement>(null);\n const onSubmitRef = useRef<ApplyCompletion>(noop);\n const viewRef = useRef<EditorView>();\n const completionFn = useColumnAutoComplete(suggestionProvider, onSubmitRef);\n\n const [createState, clearInput] = useMemo(() => {\n const parseExpression = ():\n | [string, ColumnDefinitionExpression]\n | [\"\", undefined] => {\n const view = getView(viewRef);\n const source = view.state.doc.toString();\n const tree = ensureSyntaxTree(view.state, view.state.doc.length, 5000);\n if (tree) {\n const expression = walkTree(tree, source);\n return [source, expression];\n } else {\n return [\"\", undefined];\n }\n };\n\n const clearInput = () => {\n getView(viewRef).setState(createState());\n };\n\n const submitExpression = () => {\n const [source, expression] = parseExpression();\n onSubmitExpression?.(source, expression);\n };\n\n const showSuggestions = (key: string) => {\n return keymap.of([\n {\n key,\n run() {\n startCompletion(getView(viewRef));\n return true;\n },\n },\n ]);\n };\n\n const createState = (): EditorState =>\n EditorState.create({\n doc: source,\n extensions: [\n minimalSetup,\n autocompletion({\n addToOptions: [\n {\n render: injectOptionContent,\n position: 70,\n },\n ],\n override: [completionFn],\n optionClass: getOptionClass,\n }),\n columnExpressionLanguageSupport(),\n keymap.of(defaultKeymap),\n showSuggestions(\"ArrowDown\"),\n EditorView.updateListener.of((v) => {\n const view = getView(viewRef);\n if (v.docChanged) {\n startCompletion(view);\n const source = view.state.doc.toString();\n onChange?.(source);\n }\n }),\n // Enforces single line view\n // EditorState.transactionFilter.of((tr) =>\n // tr.newDoc.lines > 1 ? [] : tr\n // ),\n vuuTheme,\n vuuHighlighting,\n ],\n });\n\n onSubmitRef.current = () => {\n submitExpression();\n };\n\n return [createState, clearInput];\n }, [completionFn, onChange, onSubmitExpression, source]);\n\n useEffect(() => {\n if (!editorRef.current) {\n throw Error(\"editor not in dom\");\n }\n\n viewRef.current = new EditorView({\n state: createState(),\n parent: editorRef.current,\n });\n\n return () => {\n viewRef.current?.destroy();\n };\n }, [completionFn, createState]);\n\n return { editorRef, clearInput };\n};\n", "import {\n LanguageSupport,\n LRLanguage,\n styleTags,\n tags as tag,\n} from \"@vuu-ui/vuu-codemirror\";\nimport { parser } from \"./generated/column-parser\";\n\nconst columnExpressionLanguage = LRLanguage.define({\n name: \"VuuColumnExpression\",\n parser: parser.configure({\n props: [\n styleTags({\n Function: tag.variableName,\n String: tag.string,\n Or: tag.emphasis,\n Operator: tag.operator,\n }),\n ],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n }) as any,\n});\n\nexport const columnExpressionLanguageSupport = () => {\n return new LanguageSupport(\n columnExpressionLanguage /*, [exampleCompletion]*/\n );\n};\n", "// This file was generated by lezer-generator. You probably shouldn't edit it.\nimport {LRParser} from \"@lezer/lr\"\nexport const parser = LRParser.deserialize({\n version: 14,\n states: \"&fOVQPOOO!SQPO'#C^OVQPO'#CcQ!pQPOOO#OQPO'#CkO#TQPO'#CrOOQO'#Cy'#CyO#YQPO,58}OVQPO,59QOVQPO,59QOVQPO,59VOVQPO'#CtOOQO,59^,59^OOQO1G.i1G.iOOQO1G.l1G.lO#kQPO1G.lO$fQPO'#CmO%WQQO1G.qOOQO'#C{'#C{O%cQPO,59`OOQO'#Cn'#CnO%wQPO,59XOVQPO,59ZOVQPO,59[OVQPO7+$]OVQPO'#CuO&`QPO1G.zOOQO1G.z1G.zO&hQQO'#C^O&rQQO1G.sO'ZQQO1G.uOOQO1G.v1G.vO'fQPO<<GwO'wQPO,59aOOQO-E6s-E6sOOQO7+$f7+$fOVQPOAN=cO(]QQO1G.lO(tQPOG22}OOQOLD(iLD(iO%wQPO,59QO%wQPO,59Q\",\n stateData: \")[~OlOS~ORUOSUOTUOUUOWQO`SOnPO~OWgXZQX[QX]QX^QXeQX~OjQXXQXpQXqQXrQXsQXtQXuQX~PnOZWO[WO]XO^XO~OWYO~OWZO~OX]OZWO[WO]XO^XO~OZWO[WO]Yi^YijYiXYipYiqYirYisYitYiuYieYi~OZWO[WO]XO^XOpdOqdOrdOsdOtdOudO~OehOvfOwgO~OXkOZWO[WO]XO^XOeiO~ORUOSUOTUOUUOWQO`SOnlO~OXsOeiO~OvQXwQX~PnOZxO[xO]yO^yOeaivaiwai~OwgOecivci~OZWO[WO]XO^XOetO~OZWO[WO]XO^XOXiaeia~OZxO[xO]Yi^YieYivYiwYi~OXwOZWO[WO]XO^XO~O`UTn~\",\n goto: \"#spPPqPPPPqPPqPPPPqP!R!W!R!RPq!Z!k!nPPP!tP#jmUOQWXYZefghitxyVbYfgRe`mTOQWXYZefghitxyR[TQjcRrjQROQVQS^WxQ_XU`YfgQcZQmeQphQqiQuyRvtQaYQnfRog\",\n nodeNames: \"\u26A0 ColumnDefinitionExpression Column Number String True False ParenthesizedExpression OpenBrace CloseBrace ArithmeticExpression Divide Times Plus Minus ConditionalExpression If RelationalExpression RelationalOperator AndCondition OrCondition Comma CallExpression Function ArgList\",\n maxTerm: 39,\n skippedNodes: [0],\n repeatNodeCount: 1,\n tokenData: \".^~RnXY#PYZ#P]^#Ppq#Pqr#brs#mxy$eyz$jz{$o{|$t|}$y}!O%O!O!P%T!P!Q%c!Q![%h!^!_%s!_!`&Q!`!a&V!c!}&d#R#S&d#T#U&u#U#Y&d#Y#Z(Y#Z#]&d#]#^*j#^#c&d#c#d+f#d#h&d#h#i,b#i#o&d~#USl~XY#PYZ#P]^#Ppq#P~#eP!_!`#h~#mOu~~#pWOX#mZ]#m^r#mrs$Ys#O#m#P;'S#m;'S;=`$_<%lO#m~$_OS~~$bP;=`<%l#m~$jOW~~$oOX~~$tO[~~$yO]~~%OOe~~%TO^~~%WP!Q![%Z~%`PR~!Q![%Z~%hOZ~~%mQR~!O!P%Z!Q![%h~%xPr~!_!`%{~&QOt~~&VOp~~&[Pq~!_!`&_~&dOs~P&iSnP!Q![&d!c!}&d#R#S&d#T#o&dR&zUnP!Q![&d!c!}&d#R#S&d#T#b&d#b#c'^#c#o&dR'cUnP!Q![&d!c!}&d#R#S&d#T#W&d#W#X'u#X#o&dR'|SvQnP!Q![&d!c!}&d#R#S&d#T#o&d~(_TnP!Q![&d!c!}&d#R#S&d#T#U(n#U#o&d~(sUnP!Q![&d!c!}&d#R#S&d#T#`&d#`#a)V#a#o&d~)[UnP!Q![&d!c!}&d#R#S&d#T#g&d#g#h)n#h#o&d~)sUnP!Q![&d!c!}&d#R#S&d#T#X&d#X#Y*V#Y#o&d~*^SU~nP!Q![&d!c!}&d#R#S&d#T#o&d~*oUnP!Q![&d!c!}&d#R#S&d#T#Y&d#Y#Z+R#Z#o&d~+YS`~nP!Q![&d!c!}&d#R#S&d#T#o&dR+kUnP!Q![&d!c!}&d#R#S&d#T#f&d#f#g+}#g#o&dR,USwQnP!Q![&d!c!}&d#R#S&d#T#o&d~,gUnP!Q![&d!c!}&d#R#S&d#T#f&d#f#g,y#g#o&d~-OUnP!Q![&d!c!}&d#R#S&d#T#i&d#i#j-b#j#o&d~-gUnP!Q![&d!c!}&d#R#S&d#T#X&d#X#Y-y#Y#o&d~.QST~nP!Q![&d!c!}&d#R#S&d#T#o&d\",\n tokenizers: [0, 1],\n topRules: {\"ColumnDefinitionExpression\":[0,1]},\n tokenPrec: 375\n})\n", "import { Tree } from \"@vuu-ui/vuu-codemirror\";\nimport { RelationalExpression } from \"./generated/column-parser.terms\";\ntype expressionType =\n | \"arithmeticExpression\"\n | \"booleanCondition\"\n | \"booleanLiteralExpression\"\n | \"callExpression\"\n | \"colExpression\"\n | \"conditionalExpression\"\n | \"numericLiteralExpression\"\n | \"relationalExpression\"\n | \"stringLiteralExpression\"\n | \"unknown\";\n\ntype arithmeticOp = \"*\" | \"/\" | \"+\" | \"-\" | \"unknown\";\ntype booleanOp = \"and\" | \"or\";\ntype relationalOp = \"=\" | \"!=\" | \">\" | \">=\" | \"<\" | \"<=\" | \"unknown\";\n\nexport interface Expression {\n type: expressionType;\n expressions?: Expression[];\n toJSON?: () => unknown;\n value?: string | number | boolean;\n}\n\ninterface UnknownExpression extends Expression {\n type: \"unknown\";\n}\n\ninterface BooleanLiteralExpression {\n type: \"booleanLiteralExpression\";\n value: boolean;\n}\n\ninterface NumericLiteralExpression {\n type: \"numericLiteralExpression\";\n value: number;\n}\ninterface StringLiteralExpression {\n type: \"stringLiteralExpression\";\n value: string;\n}\n\ninterface ArithmeticExpression extends Expression {\n expressions: [Expression, Expression];\n op: arithmeticOp;\n type: \"arithmeticExpression\";\n}\n\ninterface BooleanCondition extends Expression {\n expressions: Expression[];\n op: booleanOp;\n type: \"booleanCondition\";\n}\ninterface RelationalExpression extends Expression {\n expressions: Expression[];\n op: relationalOp;\n type: \"relationalExpression\";\n}\n\ninterface ColExpression extends Expression {\n column?: string;\n type: \"colExpression\";\n}\n\ninterface CallExpression extends Expression {\n arguments: Expression[];\n functionName?: string;\n type: \"callExpression\";\n}\n\ntype ConditionExpression = RelationalExpression | BooleanCondition;\n\ninterface ConditionalExpression extends Expression {\n type: \"conditionalExpression\";\n condition: ConditionExpression;\n truthyExpression: Expression;\n falsyExpression: Expression;\n}\n\nexport type ColumnDefinitionExpression =\n | ArithmeticExpression\n | BooleanLiteralExpression\n | CallExpression\n | ColExpression\n | ConditionalExpression\n | NumericLiteralExpression\n | StringLiteralExpression;\n\nclass LiteralExpressionImpl implements Expression {\n type:\n | \"booleanLiteralExpression\"\n | \"numericLiteralExpression\"\n | \"stringLiteralExpression\";\n value: boolean | number | string;\n constructor(value: boolean | number | string) {\n this.value = value;\n switch (typeof value) {\n case \"boolean\":\n this.type = \"booleanLiteralExpression\";\n break;\n case \"number\":\n this.type = \"numericLiteralExpression\";\n break;\n default:\n this.type = \"stringLiteralExpression\";\n }\n }\n toJSON() {\n return {\n type: this.type,\n value: this.value,\n } as\n | StringLiteralExpression\n | BooleanLiteralExpression\n | NumericLiteralExpression;\n }\n}\nclass ColumnExpressionImpl implements ColExpression {\n type = \"colExpression\" as const;\n column: string;\n constructor(columnName: string) {\n this.column = columnName;\n }\n toJSON() {\n return {\n type: this.type,\n column: this.column,\n } as ColExpression;\n }\n}\nclass ArithmeticExpressionImpl implements ArithmeticExpression {\n #expressions: [Expression, Expression] = [\n { type: \"unknown\" },\n { type: \"unknown\" },\n ];\n #op: arithmeticOp | \"unknown\";\n type = \"arithmeticExpression\" as const;\n constructor(op: arithmeticOp | \"unknown\" = \"unknown\") {\n this.#op = op;\n }\n get op() {\n return this.#op;\n }\n set op(op: arithmeticOp) {\n this.#op = op;\n }\n get expressions() {\n return this.#expressions;\n }\n\n toJSON() {\n return {\n type: this.type,\n op: this.#op,\n expressions: this.#expressions,\n };\n }\n}\n\nclass CallExpressionImpl implements CallExpression {\n #expressions: Expression[] = [];\n functionName: string;\n type = \"callExpression\" as const;\n constructor(functionName: string) {\n this.functionName = functionName;\n }\n\n get expressions() {\n return this.#expressions;\n }\n get arguments() {\n return this.#expressions;\n }\n\n toJSON() {\n return {\n type: this.type,\n functionName: this.functionName,\n arguments: this.#expressions.map((e) => e.toJSON?.()),\n } as CallExpression;\n }\n}\n\nclass RelationalExpressionImpl implements RelationalExpression {\n #expressions: [Expression, Expression] = [\n { type: \"unknown\" },\n { type: \"unknown\" },\n ];\n #op: relationalOp = \"unknown\";\n type = \"relationalExpression\" as const;\n\n get op() {\n return this.#op;\n }\n set op(op: relationalOp) {\n this.#op = op;\n }\n get expressions() {\n return this.#expressions;\n }\n\n toJSON() {\n return {\n type: this.type,\n op: this.#op,\n expressions: this.#expressions,\n } as RelationalExpression;\n }\n}\n\nclass BooleanConditionImp implements BooleanCondition {\n #expressions: [Expression, Expression] = [\n { type: \"unknown\" },\n { type: \"unknown\" },\n ];\n #op: \"and\" | \"or\";\n type = \"booleanCondition\" as const;\n constructor(booleanOperator: \"and\" | \"or\") {\n this.#op = booleanOperator;\n }\n get op() {\n return this.#op;\n }\n get expressions() {\n return this.#expressions;\n }\n toJSON() {\n return {\n type: this.type,\n op: this.#op,\n expressions: this.#expressions.map((e) => e.toJSON?.()),\n };\n }\n}\n\nclass ConditionalExpressionImpl implements ConditionalExpression {\n #expressions: [ConditionExpression, Expression, Expression];\n type = \"conditionalExpression\" as const;\n\n constructor(booleanOperator?: \"and\" | \"or\") {\n this.#expressions = [\n booleanOperator\n ? new BooleanConditionImp(booleanOperator)\n : new RelationalExpressionImpl(),\n { type: \"unknown\" },\n { type: \"unknown\" },\n ];\n }\n\n get expressions() {\n return this.#expressions;\n }\n\n get condition(): ConditionExpression {\n return this.#expressions[0];\n }\n get truthyExpression(): Expression {\n return this.#expressions[1];\n }\n set truthyExpression(expression: Expression) {\n this.#expressions[1] = expression;\n }\n get falsyExpression(): Expression {\n return this.#expressions[2];\n }\n set falsyExpression(expression: Expression) {\n this.#expressions[2] = expression;\n }\n\n toJSON() {\n return {\n type: this.type,\n condition: this.condition.toJSON?.(),\n truthyExpression: this.truthyExpression,\n falsyExpression: this.falsyExpression?.toJSON?.() ?? this.falsyExpression,\n };\n }\n}\n\ntype PartialExpression =\n | ArithmeticExpression\n | RelationalExpression\n | ColExpression\n | CallExpression\n | BooleanCondition\n | Partial<ConditionalExpression>;\n\nconst isUnknown = (e: Expression): e is UnknownExpression =>\n e.type === \"unknown\";\n\nconst isArithmeticExpression = (\n expression: PotentiallyUnresolvedExpression\n): expression is ArithmeticExpression =>\n expression.type === \"arithmeticExpression\";\n\nconst isCallExpression = (\n expression: PotentiallyUnresolvedExpression\n): expression is CallExpression => expression.type === \"callExpression\";\n\nconst isConditionalExpression = (\n expression: PotentiallyUnresolvedExpression\n): expression is ConditionalExpression =>\n expression.type === \"conditionalExpression\";\n\nconst isCondition = (\n expression: Expression | PartialExpression\n): expression is ConditionExpression =>\n expression.type === \"relationalExpression\" ||\n expression.type === \"booleanCondition\";\n\nconst booleanConditionIsIncomplete = (\n condition: ConditionExpression\n): boolean =>\n condition.expressions.length < 2 ||\n condition.expressions.some((e) => conditionIsIncomplete(e));\n\nconst isBooleanCondition = (\n expression: Expression\n): expression is BooleanCondition => expression.type === \"booleanCondition\";\n\nconst isRelationalExpression = (\n expression?: Expression\n): expression is RelationalExpression =>\n expression?.type === \"relationalExpression\";\n\nconst conditionIsIncomplete = (\n condition: Expression\n): condition is ConditionExpression =>\n (isBooleanCondition(condition) && booleanConditionIsIncomplete(condition)) ||\n (isRelationalExpression(condition) && condition.expressions.length < 2);\n\nconst firstIncompleteExpression = (\n expression: Expression\n): Expression | undefined => {\n if (isUnknown(expression)) {\n return expression;\n } else if (isRelationalExpression(expression)) {\n const [operand1, operand2] = expression.expressions;\n if (expressionIsIncomplete(operand1)) {\n return firstIncompleteExpression(operand1);\n } else if (expression.op === \"unknown\") {\n return expression;\n } else if (expressionIsIncomplete(operand2)) {\n return firstIncompleteExpression(operand2);\n }\n } else if (isCondition(expression)) {\n const { expressions = [] } = expression;\n for (const e of expressions) {\n if (expressionIsIncomplete(e)) {\n return firstIncompleteExpression(e);\n }\n }\n } else if (isConditionalExpression(expression)) {\n const { condition, truthyExpression, falsyExpression } = expression;\n if (expressionIsIncomplete(condition)) {\n return firstIncompleteExpression(condition);\n } else if (expressionIsIncomplete(truthyExpression)) {\n return firstIncompleteExpression(truthyExpression);\n } else if (expressionIsIncomplete(falsyExpression)) {\n return firstIncompleteExpression(falsyExpression);\n }\n } else if (isArithmeticExpression(expression)) {\n const { expressions = [] } = expression;\n for (const e of expressions) {\n if (expressionIsIncomplete(e)) {\n return firstIncompleteExpression(e);\n }\n }\n }\n};\nconst replaceUnknownExpression = (\n incompleteExpression: Expression,\n unknownExpression: UnknownExpression,\n expression: Expression\n): boolean => {\n const { expressions = [] } = incompleteExpression;\n if (expressions.includes(unknownExpression)) {\n const pos = expressions.indexOf(unknownExpression);\n expressions.splice(pos, 1, expression);\n return true;\n } else {\n for (const e of expressions) {\n if (replaceUnknownExpression(e, unknownExpression, expression)) {\n return true;\n }\n }\n }\n return false;\n};\n\nconst expressionIsIncomplete = (expression: Expression): boolean => {\n if (isUnknown(expression)) {\n return true;\n } else if (isConditionalExpression(expression)) {\n return (\n expressionIsIncomplete(expression.condition) ||\n expressionIsIncomplete(expression.truthyExpression) ||\n expressionIsIncomplete(expression.falsyExpression)\n );\n } else if (\n isRelationalExpression(expression) ||\n isBooleanCondition(expression)\n ) {\n return (\n expression.op === undefined ||\n expression.expressions.some((e) => expressionIsIncomplete(e))\n );\n }\n // TODO missing cases\n return false;\n};\n\ntype ExpressionImpl =\n | ArithmeticExpressionImpl\n | CallExpressionImpl\n | ColumnExpressionImpl\n | ConditionalExpressionImpl\n | LiteralExpressionImpl;\n\ntype PotentiallyUnresolvedExpression = Expression | PartialExpression;\n\nconst addExpression = (\n expression: Expression,\n subExpression: PartialExpression | Expression\n) => {\n const targetExpression = firstIncompleteExpression(expression);\n if (targetExpression) {\n if (targetExpression.expressions) {\n targetExpression.expressions.push(subExpression as Expression);\n } else {\n console.warn(\"don't know how to treat targetExpression\");\n }\n } else {\n console.error(\"no target expression found\");\n }\n};\n\nclass ColumnExpression {\n #expression: ExpressionImpl | undefined;\n\n #callStack: CallExpression[] = [];\n\n setCondition(booleanOperator?: \"and\" | \"or\") {\n if (this.#expression === undefined) {\n this.addExpression(new ConditionalExpressionImpl(booleanOperator));\n } else if (isConditionalExpression(this.#expression)) {\n if (expressionIsIncomplete(this.#expression.condition)) {\n const condition = booleanOperator\n ? new BooleanConditionImp(booleanOperator)\n : new RelationalExpressionImpl();\n this.addExpression(condition);\n } else if (isUnknown(this.#expression.truthyExpression)) {\n this.#expression.truthyExpression = new ConditionalExpressionImpl(\n booleanOperator\n );\n } else if (expressionIsIncomplete(this.#expression.truthyExpression)) {\n const condition = booleanOperator\n ? new BooleanConditionImp(booleanOperator)\n : new RelationalExpressionImpl();\n this.addExpression(condition);\n } else if (isUnknown(this.#expression.falsyExpression)) {\n this.#expression.falsyExpression = new ConditionalExpressionImpl(\n booleanOperator\n );\n } else if (expressionIsIncomplete(this.#expression.falsyExpression)) {\n const condition = booleanOperator\n ? new BooleanConditionImp(booleanOperator)\n : new RelationalExpressionImpl();\n this.addExpression(condition);\n }\n } else {\n console.error(\"setCondition called unexpectedly\");\n }\n }\n\n addExpression(expression: ExpressionImpl | Expression) {\n if (this.#callStack.length > 0) {\n const currentCallExpression = this.#callStack.at(-1);\n currentCallExpression?.arguments.push(expression as Expression);\n } else if (this.#expression === undefined) {\n this.#expression = expression as ExpressionImpl;\n } else if (isArithmeticExpression(this.#expression)) {\n const targetExpression = firstIncompleteExpression(this.#expression);\n if (targetExpression && isUnknown(targetExpression)) {\n replaceUnknownExpression(\n this.#expression,\n targetExpression,\n expression\n );\n }\n } else if (isConditionalExpression(this.#expression)) {\n if (expressionIsIncomplete(this.#expression)) {\n const targetExpression = firstIncompleteExpression(this.#expression);\n if (targetExpression && isUnknown(targetExpression)) {\n replaceUnknownExpression(\n this.#expression,\n targetExpression,\n expression\n );\n } else if (targetExpression) {\n addExpression(targetExpression, expression);\n }\n }\n }\n }\n\n setFunction(functionName: string) {\n const callExpression = new CallExpressionImpl(functionName);\n this.addExpression(callExpression);\n this.#callStack.push(callExpression);\n }\n\n setColumn(columnName: string) {\n this.addExpression(new ColumnExpressionImpl(columnName));\n }\n\n setArithmeticOp(value: string) {\n const op = value as arithmeticOp;\n const expression = this.#expression as Expression;\n if (isArithmeticExpression(expression)) {\n expression.op = op;\n }\n // else {\n // const targetExpression = firstIncompleteExpression(this.#expression);\n // if (targetExpression) {\n // targetExpression.op = op;\n // }\n // }\n }\n\n setRelationalOperator(value: string) {\n const op = value as relationalOp;\n if (this.#expression && isConditionalExpression(this.#expression)) {\n const targetExpression = firstIncompleteExpression(this.#expression);\n if (isRelationalExpression(targetExpression)) {\n targetExpression.op = op;\n } else {\n console.error(`no target expression found (op = ${value})`);\n }\n }\n }\n\n setValue(value: string | number | boolean) {\n const literalExpression = new LiteralExpressionImpl(value);\n if (this.#expression === undefined) {\n this.#expression = literalExpression;\n } else if (isArithmeticExpression(this.#expression)) {\n this.addExpression(literalExpression);\n } else if (isCallExpression(this.#expression)) {\n // TODO this might not be correct if call arguments include nested expression(s)\n this.#expression.arguments.push(literalExpression);\n } else if (isConditionalExpression(this.#expression)) {\n if (expressionIsIncomplete(this.#expression)) {\n const targetExpression = firstIncompleteExpression(this.#expression);\n if (targetExpression && isUnknown(targetExpression)) {\n replaceUnknownExpression(\n this.#expression,\n targetExpression,\n literalExpression\n );\n } else if (targetExpression) {\n addExpression(targetExpression, literalExpression);\n }\n } else {\n console.log(\"what do we do with value, in a complete expression\");\n }\n }\n }\n\n closeBrace() {\n this.#callStack.pop();\n }\n\n get expression() {\n return this.#expression;\n }\n\n toJSON() {\n return this.#expression?.toJSON() as ColumnDefinitionExpression;\n }\n}\n\nexport const walkTree = (tree: Tree, source: string) => {\n const columnExpression = new ColumnExpression();\n const cursor = tree.cursor();\n do {\n const { name, from, to } = cursor;\n switch (name) {\n case \"AndCondition\":\n columnExpression.setCondition(\"and\");\n break;\n\n case \"OrCondition\":\n columnExpression.setCondition(\"or\");\n break;\n\n case \"RelationalExpression\":\n columnExpression.setCondition();\n break;\n\n case \"ArithmeticExpression\":\n columnExpression.addExpression(new ArithmeticExpressionImpl());\n break;\n\n case \"Column\":\n {\n const columnName = source.substring(from, to);\n columnExpression.setColumn(columnName);\n }\n break;\n\n case \"Function\":\n {\n const functionName = source.substring(from, to);\n columnExpression.setFunction(functionName);\n }\n break;\n\n case \"Times\":\n case \"Divide\":\n case \"Plus\":\n case \"Minus\":\n {\n const op = source.substring(from, to);\n columnExpression.setArithmeticOp(op);\n }\n break;\n\n case \"RelationalOperator\":\n {\n const op = source.substring(from, to);\n columnExpression.setRelationalOperator(op);\n }\n break;\n\n case \"False\":\n case \"True\":\n {\n const value = source.substring(from, to);\n columnExpression.setValue(value === \"true\" ? true : false);\n }\n break;\n\n case \"String\":\n columnExpression.setValue(source.substring(from + 1, to - 1));\n break;\n\n case \"Number\":\n columnExpression.setValue(parseFloat(source.substring(from, to)));\n break;\n\n case \"CloseBrace\":\n columnExpression.closeBrace();\n break;\n\n default:\n }\n } while (cursor.next());\n\n return columnExpression.toJSON();\n};\n", "import type { SyntaxNode } from \"@vuu-ui/vuu-codemirror\";\nimport { parser } from \"./generated/column-parser\";\n\nconst strictParser = parser.configure({ strict: true });\n\nconst RelationalOperands = [\"Number\", \"String\"];\n\nexport const ColumnNamedTerms: readonly string[] = [\n ...RelationalOperands,\n \"AndCondition\",\n \"ArithmeticExpression\",\n \"BooleanOperator\",\n \"RelationalOperatorOperator\",\n \"CallExpression\",\n \"CloseBrace\",\n \"Column\",\n \"Comma\",\n \"ConditionalExpression\",\n \"Divide\",\n \"Equal\",\n \"If\",\n \"Minus\",\n \"OpenBrace\",\n \"OrCondition\",\n \"ParenthesizedExpression\",\n \"Plus\",\n \"RelationalExpression\",\n \"RelationalOperator\",\n \"Times\",\n];\n\nexport const isCompleteExpression = (src: string) => {\n try {\n strictParser.parse(src);\n return true;\n } catch (err) {\n return false;\n }\n};\n\nexport const lastNamedChild = (node: SyntaxNode): SyntaxNode | null => {\n let { lastChild } = node;\n while (lastChild && !ColumnNamedTerms.includes(lastChild.name)) {\n lastChild = lastChild.prevSibling;\n console.log(lastChild?.name);\n }\n return lastChild;\n};\n\nexport const isCompleteRelationalExpression = (node?: SyntaxNode) => {\n if (node?.name === \"RelationalExpression\") {\n const { firstChild } = node;\n const lastChild = lastNamedChild(node);\n if (\n firstChild?.name === \"Column\" &&\n typeof lastChild?.name === \"string\" &&\n RelationalOperands.includes(lastChild.name)\n ) {\n return true;\n }\n }\n\n return false;\n};\n", "import {\n HighlightStyle,\n syntaxHighlighting,\n tags,\n} from \"@vuu-ui/vuu-codemirror\";\n\nconst myHighlightStyle = HighlightStyle.define([\n { tag: tags.variableName, color: \"var(--vuuFilterEditor-variableColor)\" },\n { tag: tags.comment, color: \"green\", fontStyle: \"italic\" },\n]);\n\nexport const vuuHighlighting = syntaxHighlighting(myHighlightStyle);\n", "import { EditorView } from \"@vuu-ui/vuu-codemirror\";\n\nexport const vuuTheme = EditorView.theme(\n {\n \"&\": {\n border: \"solid 1px var(--salt-container-primary-borderColor)\",\n color: \"var(--vuuFilterEditor-color)\",\n backgroundColor: \"var(--vuuFilterEditor-background)\",\n },\n \".cm-content\": {\n caretColor: \"var(--vuuFilterEditor-cursorColor)\",\n },\n \"&.cm-focused .cm-cursor\": {\n borderLeftColor: \"var(--vuuFilterEditor-cursorColor)\",\n },\n \"&.cm-focused .cm-selectionBackground, ::selection\": {\n backgroundColor: \"var(--vuuFilterEditor-selectionBackground)\",\n },\n \".cm-selectionBackground, ::selection\": {\n backgroundColor: \"var(--vuuFilterEditor-selectionBackground)\",\n },\n \".cm-scroller\": {\n fontFamily: \"var(--vuuFilterEditor-fontFamily)\",\n },\n \".cm-tooltip\": {\n background: \"var(--vuuFilterEditor-tooltipBackground)\",\n border: \"var(--vuuFilterEditor-tooltipBorder)\",\n boxShadow: \"var(--vuuFilterEditor-tooltipElevation)\",\n \"&.cm-tooltip-autocomplete > ul\": {\n fontFamily: \"var(--vuuFilterEditor-fontFamily)\",\n fontSize: \"var(--vuuFilterEditor-fontSize)\",\n maxHeight: \"240px\",\n },\n \"&.cm-tooltip-autocomplete > ul > li\": {\n height: \"var(--vuuFilterEditor-suggestion-height)\",\n padding: \"0 3px\",\n lineHeight: \"var(--vuuFilterEditor-suggestion-height)\",\n },\n \"&.cm-tooltip-autocomplete li[aria-selected]\": {\n background: \"var(--vuuFilterEditor-suggestion-selectedBackground)\",\n color: \"var(--vuuFilterEditor-suggestion-selectedColor)\",\n },\n \"&.cm-tooltip-autocomplete li .cm-completionDetail\": {\n color: \"var(--vuuFilterEditor-suggestion-detailColor)\",\n },\n },\n },\n { dark: false }\n);\n", "import {\n booleanJoinSuggestions,\n Completion,\n CompletionContext,\n CompletionSource,\n EditorState,\n getNamedParentNode,\n getPreviousNode,\n getValue,\n SyntaxNode,\n syntaxTree,\n} from \"@vuu-ui/vuu-codemirror\";\nimport { MutableRefObject, useCallback } from \"react\";\nimport {\n ColumnNamedTerms,\n isCompleteExpression,\n isCompleteRelationalExpression,\n} from \"./column-language-parser\";\nimport {\n ColumnExpressionOperator,\n ColumnExpressionSuggestionOptions,\n ColumnExpressionSuggestionType,\n IExpressionSuggestionProvider,\n} from \"./useColumnExpressionEditor\";\nimport { lastNamedChild } from \"./column-language-parser\";\n\nexport type ApplyCompletion = (mode?: \"add\" | \"replace\") => void;\n\nexport type Operator = \"\";\n\nconst applyPrefix = (completions: Completion[], prefix?: string) =>\n prefix\n ? completions.map((completion) => ({\n ...completion,\n apply:\n typeof completion.apply === \"function\"\n ? completion.apply\n : `${prefix}${completion.apply ?? completion.label}`,\n }))\n : completions;\n\nconst isOperator = (node?: SyntaxNode): node is SyntaxNode =>\n node === undefined\n ? false\n : [\"Times\", \"Divide\", \"Plus\", \"Minus\"].includes(node.name);\n\nconst completionDone = (onSubmit?: () => void): Completion => ({\n apply: () => {\n onSubmit?.();\n },\n label: \"Done\",\n boost: 10,\n});\n\nconst getLastChild = (node: SyntaxNode, context: CompletionContext) => {\n let { lastChild: childNode } = node;\n const { pos } = context;\n while (childNode) {\n const isBeforeCursor = childNode.from < pos;\n if (isBeforeCursor && ColumnNamedTerms.includes(childNode.name)) {\n if (childNode.name === \"ParenthesizedExpression\") {\n // extract the parenthesized expression\n const expression = childNode.firstChild?.nextSibling;\n if (expression) {\n childNode = expression;\n }\n }\n return childNode;\n } else {\n childNode = childNode.prevSibling;\n }\n }\n};\nconst getFunctionName = (node: SyntaxNode, state: EditorState) => {\n if (node.name === \"ArgList\") {\n const functionNode = node.prevSibling;\n if (functionNode) {\n return getValue(functionNode, state);\n }\n } else if (node.name === \"OpenBrace\") {\n const maybeFunction = node.parent?.prevSibling;\n if (maybeFunction?.name === \"Function\") {\n return getValue(maybeFunction, state);\n }\n }\n};\n\nconst getRelationalOperator = (node: SyntaxNode, state: EditorState) => {\n if (node.name === \"RelationalExpression\") {\n const lastNode = lastNamedChild(node);\n if (lastNode?.name === \"RelationalOperator\") {\n return getValue(lastNode, state);\n }\n } else {\n const prevNode = node.prevSibling;\n if (prevNode?.name === \"RelationalOperator\") {\n return getValue(prevNode, state) as ColumnExpressionOperator;\n }\n }\n};\n\nconst getColumnName = (\n node: SyntaxNode,\n state: EditorState\n): string | undefined => {\n if (node.name === \"RelationalExpression\") {\n if (node.firstChild?.name === \"Column\") {\n return getValue(node.firstChild, state);\n }\n } else {\n const prevNode = node.prevSibling;\n if (prevNode?.name === \"Column\") {\n return getValue(prevNode, state);\n } else if (prevNode?.name === \"RelationalOperator\") {\n return getColumnName(prevNode, state);\n }\n }\n};\n\nconst makeSuggestions = async (\n context: CompletionContext,\n suggestionProvider: IExpressionSuggestionProvider,\n suggestionType: ColumnExpressionSuggestionType,\n optionalArgs: ColumnExpressionSuggestionOptions = {}\n) => {\n const options = await suggestionProvider.getSuggestions(\n suggestionType,\n optionalArgs\n );\n const { startsWith = \"\" } = optionalArgs;\n return { from: context.pos - startsWith.length, options };\n};\n\nconst handleConditionalExpression = (\n node: SyntaxNode,\n context: CompletionContext,\n suggestionProvider: IExpressionSuggestionProvider,\n maybeComplete?: boolean,\n onSubmit?: () => void\n) => {\n const lastChild = getLastChild(node, context);\n console.log(`conditional expression last child ${lastChild?.name}`);\n switch (lastChild?.name) {\n case \"If\":\n return makeSuggestions(context, suggestionProvider, \"expression\", {\n prefix: \"( \",\n });\n case \"OpenBrace\":\n return makeSuggestions(context, suggestionProvider, \"expression\");\n case \"Condition\":\n return makeSuggestions(context, suggestionProvider, \"expression\", {\n prefix: \", \",\n });\n case \"CloseBrace\":\n if (maybeComplete) {\n const options: Completion[] = [completionDone(onSubmit)];\n return { from: context.pos, options };\n }\n }\n};\n\nconst promptToSave = (context: CompletionContext, onSubmit: () => void) => {\n const options: Completion[] = [completionDone(onSubmit)];\n return { from: context.pos, options };\n};\n\nexport const useColumnAutoComplete = (\n suggestionProvider: IExpressionSuggestionProvider,\n onSubmit: MutableRefObject<ApplyCompletion>\n) => {\n const makeSuggestions = useCallback(\n async (\n context: CompletionContext,\n suggestionType: ColumnExpressionSuggestionType,\n optionalArgs: ColumnExpressionSuggestionOptions = {}\n ) => {\n const options = await suggestionProvider.getSuggestions(\n suggestionType,\n optionalArgs\n );\n const { startsWith = \"\" } = optionalArgs;\n return { from: context.pos - startsWith.length, options };\n },\n [suggestionProvider]\n );\n\n return useCallback(\n async (context: CompletionContext) => {\n const { state, pos } = context;\n const word = context.matchBefore(/\\w*/) ?? {\n from: 0,\n to: 0,\n text: undefined,\n };\n\n const tree = syntaxTree(state);\n const nodeBefore = tree.resolveInner(pos, -1);\n const text = state.doc.toString();\n const maybeComplete = isCompleteExpression(text);\n\n switch (nodeBefore.name) {\n case \"If\": {\n console.log(`conditional expression If`);\n return makeSuggestions(context, \"expression\", { prefix: \"( \" });\n }\n case \"Condition\":\n {\n const lastChild = getLastChild(nodeBefore, context);\n if (lastChild?.name === \"Column\") {\n // is this the first term ?\n const prevChild = getPreviousNode(lastChild);\n if (prevChild?.name !== \"RelationalOperator\") {\n return makeSuggestions(context, \"condition-operator\", {\n columnName: getValue(lastChild, state),\n });\n }\n } else if (lastChild?.name === \"RelationalOperator\") {\n // we need the type of the expression on the other side of the operator\n return makeSuggestions(context, \"expression\");\n }\n console.log(`condition last child ${lastChild?.name}`);\n }\n break;\n case \"ConditionalExpression\":\n return handleConditionalExpression(\n nodeBefore,\n context,\n suggestionProvider\n );\n case \"RelationalExpression\":\n {\n if (isCompleteRelationalExpression(nodeBefore)) {\n return {\n from: context.pos,\n options: booleanJoinSuggestions.concat({\n label: \", <truthy expression>, <falsy expression>\",\n apply: \", \",\n }),\n };\n } else {\n const operator = getRelationalOperator(nodeBefore, state);\n const columnName = getColumnName(nodeBefore, state);\n if (!operator) {\n const options = await suggestionProvider.getSuggestions(\n \"condition-operator\",\n {\n columnName,\n }\n );\n return { from: context.pos, options };\n } else {\n return makeSuggestions(context, \"expression\");\n }\n }\n }\n break;\n\n case \"RelationalOperator\":\n // we need the type of the expression on the other side of the operator\n return makeSuggestions(context, \"expression\");\n\n case \"String\":\n {\n // we only encounter a string as the right hand operand of a conditional expression\n const operator = getRelationalOperator(\n nodeBefore,\n state\n ) as ColumnExpressionOperator;\n const columnName = getColumnName(nodeBefore, state);\n // are we inside the string or immediately after it\n const { from, to } = nodeBefore;\n if (to - from === 2 && context.pos === from + 1) {\n // We are in an empty string, i.e between two quotes\n if (columnName && operator) {\n return makeSuggestions(context, \"columnValue\", {\n columnName,\n operator,\n startsWith: word.text,\n });\n }\n } else if (to - from > 2 && context.pos === to) {\n // NOte we couls also offer AND/OR to extend the condition\n return makeSuggestions(context, \"expression\", {\n prefix: \", \",\n });\n }\n }\n break;\n\n case \"ArithmeticExpression\":\n {\n const lastChild = getLastChild(nodeBefore, context);\n if (lastChild?.name === \"Column\") {\n return makeSuggestions(context, \"expression\");\n } else if (isOperator(lastChild)) {\n const operator = lastChild.name as ColumnExpressionOperator;\n return makeSuggestions(context, \"column\", { operator });\n }\n }\n\n break;\n case \"OpenBrace\":\n {\n // Might be a function expression, might be parenthesized\n const functionName = getFunctionName(nodeBefore, state);\n // If not function, what came before - if it's an operator\n // we restrict to numerics\n return makeSuggestions(context, \"expression\", { functionName });\n }\n break;\n case \"ArgList\": {\n const functionName = getFunctionName(nodeBefore, state);\n const lastArgument = getLastChild(nodeBefore, context);\n const prefix = lastArgument?.name === \"OpenBrace\" ? undefined : \",\";\n let options = await suggestionProvider.getSuggestions(\"expression\", {\n functionName,\n });\n options = prefix ? applyPrefix(options, \", \") : options;\n // TODO per function check for number of arguments expected\n if (\n lastArgument?.name !== \"OpenBrace\" &&\n lastArgument?.name !== \"Comma\"\n ) {\n options = [\n {\n apply: \") \",\n boost: 10,\n label: \"Done - no more arguments\",\n } as Completion,\n ].concat(options);\n }\n return { from: context.pos, options };\n }\n case \"Equal\":\n if (text.trim() === \"=\") {\n return makeSuggestions(context, \"expression\");\n }\n break;\n case \"ParenthesizedExpression\":\n case \"ColumnDefinitionExpression\":\n if (context.pos === 0) {\n return makeSuggestions(context, \"expression\");\n } else {\n const lastChild = getLastChild(nodeBefore, context);\n if (lastChild?.name === \"Column\") {\n if (maybeComplete) {\n // We come in here is the columns IS complete, too (ie has space after)\n const options: Completion[] = [\n completionDone(onSubmit.current),\n ];\n const columnName = getValue(lastChild, state);\n const columnOptions: Completion[] =\n await suggestionProvider.getSuggestions(\"operator\", {\n columnName,\n });\n\n return {\n from: context.pos,\n options: options.concat(columnOptions),\n };\n }\n } else if (lastChild?.name === \"CallExpression\") {\n if (maybeComplete) {\n return {\n from: context.pos,\n options: [completionDone(onSubmit.current)],\n };\n }\n } else if (lastChild?.name === \"ArithmeticExpression\") {\n if (maybeComplete) {\n let options: Completion[] = [completionDone(onSubmit.current)];\n\n const lastExpressionChild = getLastChild(lastChild, context);\n if (lastExpressionChild?.name === \"Column\") {\n const columnName = getValue(lastExpressionChild, state);\n // TODO need to exclude columns already included in expression\n\n const suggestions = await suggestionProvider.getSuggestions(\n \"operator\",\n { columnName }\n );\n options = options.concat(suggestions);\n }\n\n return {\n from: context.pos,\n options,\n };\n }\n } else if (lastChild?.name === \"ConditionalExpression\") {\n return handleConditionalExpression(\n lastChild,\n context,\n suggestionProvider,\n maybeComplete,\n onSubmit.current\n );\n }\n break;\n }\n case \"Column\":\n {\n const isPartialMatch = await suggestionProvider.isPartialMatch(\n \"expression\",\n undefined,\n word.text\n );\n\n if (isPartialMatch) {\n return makeSuggestions(context, \"expression\", {\n startsWith: word.text,\n });\n }\n }\n break;\n case \"Comma\":\n {\n const parentNode = getNamedParentNode(nodeBefore);\n if (parentNode?.name === \"ConditionalExpression\") {\n return makeSuggestions(context, \"expression\");\n }\n }\n break;\n\n case \"CloseBrace\":\n {\n const parentNode = getNamedParentNode(nodeBefore);\n if (parentNode?.name === \"ConditionalExpression\") {\n return handleConditionalExpression(\n parentNode,\n context,\n suggestionProvider,\n maybeComplete,\n onSubmit.current\n );\n } else if (parentNode?.name === \"ArgList\") {\n if (maybeComplete) {\n return promptToSave(context, onSubmit.current);\n }\n }\n }\n break;\n\n default: {\n if (nodeBefore?.prevSibling?.name === \"FilterClause\") {\n console.log(\"looks like we ight be a or|and operator\");\n }\n }\n }\n },\n [makeSuggestions, onSubmit, suggestionProvider]\n ) as CompletionSource;\n};\n", "import { HTMLAttributes } from \"react\";\nimport { ColumnDefinitionExpression } from \"./column-language-parser\";\nimport {\n ExpressionSuggestionConsumer,\n useColumnExpressionEditor,\n} from \"./useColumnExpressionEditor\";\n\nimport \"./ColumnExpressionInput.css\";\n\nconst classBase = \"vuuColumnExpressionInput\";\n\nexport interface ColumnExpressionInputProps\n extends ExpressionSuggestionConsumer,\n Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n onChange?: (source: string) => void;\n onSubmitExpression?: (\n source: string,\n expression: ColumnDefinitionExpression | undefined\n ) => void;\n source?: string;\n}\n\nexport const ColumnExpressionInput = ({\n onChange,\n onSubmitExpression,\n source = \"\",\n suggestionProvider,\n}: ColumnExpressionInputProps) => {\n const { editorRef } = useColumnExpressionEditor({\n onChange,\n onSubmitExpression,\n source,\n suggestionProvider,\n });\n\n return <div className={`${classBase}`} ref={editorRef} />;\n};\n", "import {\n AnnotationType,\n Completion,\n EditorView,\n getRelationalOperators,\n numericOperators,\n stringOperators,\n toSuggestions,\n} from \"@vuu-ui/vuu-codemirror\";\nimport {\n getTypeaheadParams,\n useTypeaheadSuggestions,\n} from \"@vuu-ui/vuu-data-react\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n ColumnExpressionOperator,\n ColumnExpressionSuggestionType,\n IExpressionSuggestionProvider,\n} from \"@vuu-ui/vuu-table-extras\";\nimport { isNumericColumn, isTextColumn } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useRef } from \"react\";\nimport {\n ColumnFunctionDescriptor,\n columnFunctionDescriptors,\n} from \"./column-function-descriptors\";\nimport { functionDocInfo } from \"./functionDocInfo\";\n\nconst NO_OPERATORS = [] as Completion[];\n\nconst withApplySpace = (suggestions: Completion[]): Completion[] =>\n suggestions.map((suggestion) => ({\n ...suggestion,\n apply: (suggestion.apply ?? suggestion.label) + \" \",\n }));\n\ntype ColumnOptions = {\n functionName?: string;\n operator?: ColumnExpressionOperator;\n prefix?: string;\n};\n\nconst getValidColumns = (\n columns: ColumnDescriptor[],\n { functionName, operator }: ColumnOptions\n) => {\n if (operator) {\n return columns.filter(isNumericColumn);\n } else if (functionName) {\n const fn = columnFunctionDescriptors.find((f) => f.name === functionName);\n if (fn) {\n switch (fn.accepts) {\n case \"string\":\n return columns.filter(isTextColumn);\n case \"number\":\n return columns.filter(isNumericColumn);\n default:\n return columns;\n }\n }\n }\n return columns;\n};\n\nconst getColumns = (columns: ColumnDescriptor[], options: ColumnOptions) => {\n const validColumns = getValidColumns(columns, options);\n return validColumns.map((column) => {\n const label = column.label ?? column.name;\n return {\n apply: options.prefix ? `${options.prefix}${label}` : label,\n label,\n boost: 5,\n type: \"column\",\n expressionType: column.serverDataType,\n };\n });\n};\n\n// prettier-ignore\nconst arithmeticOperators = [\n { apply: \"* \", boost: 2, label: \"*\", type: \"operator\" },\n { apply: \"/ \", boost: 2, label: \"/\", type: \"operator\" },\n { apply: \"+ \", boost: 2, label: \"+\", type: \"operator\" },\n { apply: \"- \", boost: 2, label: \"-\", type: \"operator\" },\n];\n\nconst getOperators = (column?: ColumnDescriptor) => {\n if (column === undefined || isNumericColumn(column)) {\n return arithmeticOperators;\n } else {\n return NO_OPERATORS;\n }\n};\n\nconst getConditionOperators = (column: ColumnDescriptor) => {\n switch (column.serverDataType) {\n case \"string\":\n case \"char\":\n return withApplySpace(stringOperators /*, startsWith*/);\n case \"int\":\n case \"long\":\n case \"double\":\n return withApplySpace(numericOperators);\n }\n};\n\nconst toFunctionCompletion = (\n functionDescriptor: ColumnFunctionDescriptor\n) => ({\n apply: `${functionDescriptor.name}( `,\n boost: 2,\n expressionType: functionDescriptor.type,\n info: () => functionDocInfo(functionDescriptor),\n label: functionDescriptor.name,\n type: \"function\",\n});\n\nconst getAcceptedTypes = (fn?: ColumnFunctionDescriptor) => {\n if (fn) {\n if (typeof fn.accepts === \"string\") {\n return fn.accepts;\n } else if (Array.isArray(fn.accepts)) {\n if (fn.accepts.every((s) => s === \"string\")) {\n return \"string\";\n } else {\n return \"any\";\n }\n }\n }\n return \"any\";\n};\n\nconst functions: Completion[] =\n columnFunctionDescriptors.map(toFunctionCompletion);\n\nconst getFunctions = ({ functionName }: ColumnOptions) => {\n if (functionName) {\n const fn = columnFunctionDescriptors.find((f) => f.name === functionName);\n const acceptedTypes = getAcceptedTypes(fn);\n if (fn) {\n switch (acceptedTypes) {\n case \"string\":\n return columnFunctionDescriptors\n .filter((f) => f.type === \"string\" || f.type === \"variable\")\n .map(toFunctionCompletion);\n case \"number\":\n return columnFunctionDescriptors\n .filter((f) => f.type === \"number\" || f.type === \"variable\")\n .map(toFunctionCompletion);\n default:\n }\n }\n }\n return functions;\n};\n\nexport interface SuggestionProviderHookProps {\n columns: ColumnDescriptor[];\n table: VuuTable;\n}\n\nconst NONE = {};\n\nexport const useColumnExpressionSuggestionProvider = ({\n columns,\n table,\n}: SuggestionProviderHookProps): IExpressionSuggestionProvider => {\n const findColumn = useCallback(\n (name?: string) =>\n name ? columns.find((col) => col.name === name) : undefined,\n [columns]\n );\n\n const latestSuggestionsRef = useRef<Completion[]>();\n const getTypeaheadSuggestions = useTypeaheadSuggestions();\n\n const getSuggestions: IExpressionSuggestionProvider[\"getSuggestions\"] =\n useCallback(\n async (suggestionType, options = NONE): Promise<Completion[]> => {\n const { columnName, functionName, operator, prefix } = options;\n\n switch (suggestionType) {\n case \"expression\": {\n const suggestions = await withApplySpace(\n getColumns(columns, { functionName, prefix })\n ).concat(getFunctions(options));\n return (latestSuggestionsRef.current = suggestions);\n }\n case \"column\": {\n const suggestions = await getColumns(columns, options);\n return (latestSuggestionsRef.current = withApplySpace(suggestions));\n }\n case \"operator\": {\n const suggestions = await getOperators(findColumn(columnName));\n return (latestSuggestionsRef.current = withApplySpace(suggestions));\n }\n case \"relational-operator\": {\n const suggestions = await getRelationalOperators(\n findColumn(columnName)\n );\n return (latestSuggestionsRef.current = withApplySpace(suggestions));\n }\n case \"condition-operator\":\n {\n const column = findColumn(columnName);\n if (column) {\n const suggestions = await getConditionOperators(column);\n if (suggestions) {\n return (latestSuggestionsRef.current =\n withApplySpace(suggestions));\n }\n }\n }\n break;\n case \"columnValue\":\n if (columnName && operator) {\n // const column = findColumn(columnName);\n const params = getTypeaheadParams(\n table,\n columnName /*, startsWith*/\n );\n const suggestions = await getTypeaheadSuggestions(params);\n latestSuggestionsRef.current = toSuggestions(suggestions, {\n suffix: \"\",\n });\n\n latestSuggestionsRef.current.forEach((suggestion) => {\n suggestion.apply = (\n view: EditorView,\n completion: Completion,\n from: number\n ) => {\n const annotation = new AnnotationType<Completion>();\n const cursorPos = from + completion.label.length + 1;\n view.dispatch({\n changes: { from, insert: completion.label },\n selection: { anchor: cursorPos, head: cursorPos },\n annotations: annotation.of(completion),\n });\n };\n });\n return latestSuggestionsRef.current;\n }\n break;\n }\n\n return [];\n },\n [columns, findColumn, getTypeaheadSuggestions, table]\n );\n\n const isPartialMatch = useCallback(\n async (\n valueType: ColumnExpressionSuggestionType,\n columnName?: string,\n pattern?: string\n ) => {\n const { current: latestSuggestions } = latestSuggestionsRef;\n let maybe = false;\n const suggestions =\n latestSuggestions || (await getSuggestions(valueType, { columnName }));\n if (pattern && suggestions) {\n for (const option of suggestions) {\n if (option.label === pattern) {\n return false;\n } else if (option.label.startsWith(pattern)) {\n maybe = true;\n }\n }\n }\n return maybe;\n },\n [getSuggestions]\n );\n\n return {\n getSuggestions,\n isPartialMatch,\n };\n};\n", "export type ColumnFunctionDescriptor = {\n accepts: \"string\" | \"number\" | \"any\" | Array<\"string\" | \"number\">;\n description: string;\n example: {\n expression: string;\n result: string;\n };\n name: string;\n params: {\n count?: number;\n description: string;\n };\n type: \"string\" | \"number\" | \"boolean\" | \"variable\";\n};\n\nexport const columnFunctionDescriptors: ColumnFunctionDescriptor[] = [\n /**\n * concatenate()\n */\n {\n accepts: \"string\",\n description:\n \"Returns multiple string values as a single joined string. Arguments may be string literal values, string columns or other string expressions. Non string arguments may also be included, these will be converted to strings.\",\n example: {\n expression: 'concatenate(\"example\", \"-test\")',\n result: '\"example-test\"',\n },\n name: \"concatenate\",\n params: {\n description: \"( string, string, [ string* ] )\",\n },\n type: \"string\",\n },\n /**\n * contains()\n */\n {\n accepts: [\"string\", \"string\"],\n description:\n \"Tests a string value to determine whether it contains a given substring. Accepts two arguments: source text and target substring. Returns true if <source text> contains one or more occurrences of <target subscring>\",\n example: {\n expression: 'contains(\"Royal Bank of Scotland\", \"bank\")',\n result: \"true\",\n },\n name: \"contains\",\n params: {\n description: \"( string )\",\n },\n type: \"boolean\",\n },\n\n /**\n * left()\n */\n {\n accepts: [\"string\", \"number\"],\n description:\n \"Returns the leftmost <number> characters from <string>. First argument may be a string literal, string column or other string expression.\",\n example: {\n expression: 'left(\"USD Benchmark Report\", 3)',\n result: '\"USD\"',\n },\n name: \"left\",\n params: {\n count: 2,\n description: \"( string, number )\",\n },\n type: \"string\",\n },\n /**\n * len()\n */\n {\n accepts: \"string\",\n description:\n \"Returns the number of characters in <string>. Argument may be a string literal, string column or other string expression.\",\n example: {\n expression: 'len(\"example\")',\n result: \"7\",\n },\n name: \"len\",\n params: {\n description: \"(string)\",\n },\n type: \"number\",\n },\n /**\n * lower()\n */\n {\n accepts: \"string\",\n description:\n \"Convert a string value to lowercase. Argument may be a string column or other string expression.\",\n example: {\n expression: 'lower(\"examPLE\")',\n result: '\"example\"',\n },\n name: \"lower\",\n params: {\n description: \"( string )\",\n },\n type: \"string\",\n },\n /**\n * upper()\n */\n {\n accepts: \"string\",\n description:\n \"Convert a string value to uppercase. Argument may be a string column or other string expression.\",\n example: {\n expression: 'upper(\"example\")',\n result: '\"EXAMPLE\"',\n },\n name: \"upper\",\n params: {\n description: \"( string )\",\n },\n type: \"string\",\n },\n /**\n * right()\n */\n {\n accepts: [\"string\", \"number\"],\n description:\n \"Returns the rightmost <number> characters from <string>. First argument may be a string literal, string column or other string expression.\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"right\",\n params: {\n description: \"( string )\",\n },\n type: \"string\",\n },\n /**\n * replace()\n */\n {\n accepts: [\"string\", \"string\", \"string\"],\n description:\n \"Replace characters within a string. Accepts three arguments: source text, text to replace and replacement text. Returns a copy of <source text> with any occurrences of <text to replace> replaced by <replacement text>\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"replace\",\n params: {\n description: \"( string )\",\n },\n type: \"string\",\n },\n /**\n * text()\n */\n {\n accepts: \"number\",\n description: \"Converts a number to a string.\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"text\",\n params: {\n description: \"( string )\",\n },\n type: \"string\",\n },\n /**\n * starts()\n */\n {\n accepts: \"string\",\n description:\n \"Tests a string value to determine whether it starts with a given substring. Accepts two arguments: source text and target substring. Returns true if <source text> starts with <target subscring>.\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"starts\",\n params: {\n description: \"( string )\",\n },\n type: \"boolean\",\n },\n /**\n * starts()\n */\n {\n accepts: \"string\",\n description:\n \"Tests a string value to determine whether it ends with a given substring. Accepts two arguments: source text and target substring. Returns true if <source text> ends with <target subscring>.\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"ends\",\n params: {\n description: \"( string )\",\n },\n type: \"boolean\",\n },\n {\n accepts: \"number\",\n description: \"blah\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"min\",\n params: {\n description: \"( string )\",\n },\n type: \"number\",\n },\n {\n accepts: \"number\",\n description: \"blah\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"max\",\n params: {\n description: \"( string )\",\n },\n type: \"number\",\n },\n {\n accepts: \"number\",\n description: \"blah\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"sum\",\n params: {\n description: \"( string )\",\n },\n type: \"number\",\n },\n {\n accepts: \"number\",\n description: \"blah\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"round\",\n params: {\n description: \"( string )\",\n },\n type: \"number\",\n },\n {\n accepts: \"any\",\n description: \"blah\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"or\",\n params: {\n description: \"( string )\",\n },\n type: \"boolean\",\n },\n {\n accepts: \"any\",\n description: \"blah\",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"and\",\n params: {\n description: \"( string )\",\n },\n type: \"boolean\",\n },\n {\n accepts: \"any\",\n description:\n \"Return one of two possible result values, depending on the evaluation of a filter expression. If <filterExpression> resolves to true, result is <expression1>, otherwise <expression2>. \",\n example: {\n expression: \"blah\",\n result: \"blah\",\n },\n name: \"if\",\n params: {\n description: \"( filterExpression, expression1, expression 2)\",\n },\n type: \"variable\",\n },\n];\n", "import { createEl } from \"@vuu-ui/vuu-utils\";\nimport { ColumnFunctionDescriptor } from \"./column-function-descriptors\";\n\nexport const functionDocInfo = ({\n name,\n description,\n example,\n params,\n type,\n}: ColumnFunctionDescriptor) => {\n const rootElement = createEl(\"div\", \"vuuFunctionDoc\");\n const headingElement = createEl(\"div\", \"function-heading\");\n\n const nameElement = createEl(\"span\", \"function-name\", name);\n const paramElement = createEl(\"span\", \"param-list\", params.description);\n const typeElement = createEl(\"span\", \"function-type\", type);\n\n headingElement.appendChild(nameElement);\n headingElement.appendChild(paramElement);\n headingElement.appendChild(typeElement);\n\n const child2 = createEl(\"p\", undefined, description);\n\n rootElement.appendChild(headingElement);\n rootElement.appendChild(child2);\n\n if (example) {\n const exampleElement = createEl(\"div\", \"example-container\", \"Example:\");\n const expressionElement = createEl(\n \"div\",\n \"example-expression\",\n example.expression\n );\n const resultElement = createEl(\"div\", \"example-result\", example.result);\n\n exampleElement.appendChild(expressionElement);\n exampleElement.appendChild(resultElement);\n\n rootElement.appendChild(exampleElement);\n }\n\n return rootElement;\n};\n", "import { ColumnDescriptor } from \"packages/vuu-datagrid-types\";\nimport {\n getCalculatedColumnDetails,\n setCalculatedColumnExpression,\n setCalculatedColumnName,\n setCalculatedColumnType,\n} from \"@vuu-ui/vuu-utils\";\nimport { FormEventHandler, useCallback, useRef, useState } from \"react\";\nimport { ColumnExpressionPanelProps } from \"./ColumnExpressionPanel\";\n\nexport type ColumnExpressionHookProps = Pick<\n ColumnExpressionPanelProps,\n \"column\" | \"onSave\"\n>;\n\nconst applyDefaults = (column: ColumnDescriptor) => {\n const [name, expression, type] = getCalculatedColumnDetails(column);\n if (type === \"\") {\n return {\n ...column,\n name: `${name}:${expression}:string`,\n };\n } else {\n return column;\n }\n};\n\nexport const useColumnExpression = ({\n column: columnProp,\n onSave: onSaveProp,\n}: ColumnExpressionHookProps) => {\n const [column, setColumn] = useState<ColumnDescriptor>(\n applyDefaults(columnProp)\n );\n const expressionRef = useRef(getCalculatedColumnDetails(column)[1]);\n\n const onChangeName = useCallback<FormEventHandler>((evt) => {\n const { value } = evt.target as HTMLInputElement;\n setColumn((state) => setCalculatedColumnName(state, value));\n }, []);\n\n const onChangeExpression = useCallback((value: string) => {\n // we do not set state when this changes as the codemirror editor\n // manages state of the expression for us until complete\n expressionRef.current = value.trim();\n }, []);\n\n const onChangeType = useCallback((evt, value: string | null) => {\n if (typeof value === \"string\") {\n setColumn((state) => setCalculatedColumnType(state, value));\n }\n }, []);\n\n const onSave = useCallback(() => {\n const newColumn = setCalculatedColumnExpression(\n column,\n expressionRef.current\n );\n setColumn(newColumn);\n onSaveProp(newColumn);\n }, [column, onSaveProp]);\n\n return {\n column,\n onChangeExpression,\n onChangeName,\n onChangeType,\n onSave,\n };\n};\n", "import { DataSource } from \"@vuu-ui/vuu-data\";\nimport { HTMLAttributes, useEffect, useState } from \"react\";\nimport cx from \"classnames\";\n\nimport \"./DatasourceStats.css\";\nimport { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\n\ninterface DataSourceStatsProps extends HTMLAttributes<HTMLSpanElement> {\n dataSource: DataSource;\n}\n\nconst classBase = \"vuuDatasourceStats\";\n\nconst numberFormatter = new Intl.NumberFormat();\n\nexport const DataSourceStats = ({\n className: classNameProp,\n dataSource,\n}: DataSourceStatsProps) => {\n const [range, setRange] = useState<VuuRange>(dataSource.range);\n const [size, setSize] = useState(dataSource.size);\n useEffect(() => {\n setSize(dataSource.size);\n\n dataSource.on(\"resize\", setSize);\n dataSource.on(\"range\", setRange);\n }, [dataSource]);\n\n const className = cx(classBase, classNameProp);\n const from = numberFormatter.format(range.from);\n const to = numberFormatter.format(range.to - 1);\n const value = numberFormatter.format(size);\n return (\n <div className={className}>\n <span className={`${classBase}-label`}>Row count</span>\n <span className={`${classBase}-range`}>{from}</span>\n <span>-</span>\n <span className={`${classBase}-range`}>{to}</span>\n <span>of</span>\n <span className={`${classBase}-size`}>{value}</span>\n </div>\n );\n};\n", "import {\n Button,\n FormField,\n FormFieldLabel,\n Input,\n ToggleButton,\n ToggleButtonGroup,\n} from \"@salt-ds/core\";\nimport { DataSourceConfig, SchemaColumn } from \"@vuu-ui/vuu-data\";\nimport { TableConfig } from \"@vuu-ui/vuu-datagrid-types\";\nimport { HTMLAttributes } from \"react\";\nimport { ColumnList } from \"../column-list\";\nimport { useTableSettings } from \"./useTableSettings\";\n\nimport \"./TableSettingsPanel.css\";\n\nconst classBase = \"vuuTableSettingsPanel\";\n\nexport interface TableSettingsProps extends HTMLAttributes<HTMLDivElement> {\n availableColumns: SchemaColumn[];\n onAddCalculatedColumn: () => void;\n onConfigChange: (config: TableConfig) => void;\n onDataSourceConfigChange: (dataSOurceConfig: DataSourceConfig) => void;\n tableConfig: TableConfig;\n}\n\n/**\n The TableSettingsPanel assumes 'ownership' of the tableSettings.\n It updates the settings in state locally and notifies caller of\n every change via onChange callback\n */\nexport const TableSettingsPanel = ({\n availableColumns,\n onAddCalculatedColumn,\n onConfigChange,\n onDataSourceConfigChange,\n tableConfig: tableConfigProp,\n ...htmlAttributes\n}: TableSettingsProps) => {\n const {\n columnItems,\n columnLabelsValue,\n onChangeColumnLabels,\n onChangeTableAttribute,\n onColumnChange,\n onMoveListItem,\n tableConfig,\n } = useTableSettings({\n availableColumns,\n onConfigChange,\n onDataSourceConfigChange,\n tableConfig: tableConfigProp,\n });\n\n return (\n <div {...htmlAttributes} className={classBase}>\n <FormField>\n <FormFieldLabel>Column Labels</FormFieldLabel>\n <ToggleButtonGroup\n className=\"vuuToggleButtonGroup\"\n onChange={onChangeColumnLabels}\n value={columnLabelsValue}\n >\n <ToggleButton\n className=\"vuuIconToggleButton\"\n data-icon=\"text-strikethrough\"\n value={0}\n />\n <ToggleButton\n className=\"vuuIconToggleButton\"\n data-icon=\"text-Tt\"\n value={1}\n />\n <ToggleButton\n className=\"vuuIconToggleButton\"\n data-icon=\"text-T\"\n value={2}\n />\n </ToggleButtonGroup>\n </FormField>\n\n <FormField>\n <FormFieldLabel>Grid separators</FormFieldLabel>\n <div className=\"saltToggleButtonGroup vuuToggleButtonGroup saltToggleButtonGroup-horizontal vuuGridSeparators\">\n <ToggleButton\n className=\"vuuIconToggleButton\"\n data-icon=\"row-striping\"\n selected={tableConfig.zebraStripes}\n onChange={onChangeTableAttribute}\n value=\"zebraStripes\"\n />\n <ToggleButton\n className=\"vuuIconToggleButton\"\n data-icon=\"row-lines\"\n selected={tableConfig.rowSeparators}\n onChange={onChangeTableAttribute}\n value=\"rowSeparators\"\n />\n <ToggleButton\n className=\"vuuIconToggleButton\"\n data-icon=\"col-lines\"\n selected={tableConfig.columnSeparators}\n onChange={onChangeTableAttribute}\n value=\"columnSeparators\"\n />\n </div>\n </FormField>\n\n <FormField>\n <FormFieldLabel>Default Column Width</FormFieldLabel>\n <Input className=\"vuuInput\" />\n </FormField>\n\n <ColumnList\n columnItems={columnItems}\n onChange={onColumnChange}\n onMoveListItem={onMoveListItem}\n />\n\n <div className={`${classBase}-calculatedButtonbar`}>\n <Button data-icon=\"plus\" onClick={onAddCalculatedColumn} />\n <span className={`${classBase}-calculatedLabel`}>\n Add calculated column\n </span>\n </div>\n </div>\n );\n};\n", "import { SchemaColumn } from \"@vuu-ui/vuu-data\";\nimport { ColumnDescriptor, TableConfig } from \"@vuu-ui/vuu-datagrid-types\";\nimport { useLayoutEffectSkipFirst } from \"@vuu-ui/vuu-layout\";\nimport { updateTableConfig } from \"@vuu-ui/vuu-table\";\nimport {\n addColumnToSubscribedColumns,\n isCalculatedColumn,\n moveItem,\n subscribedOnly,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n MouseEvent,\n SyntheticEvent,\n useCallback,\n useMemo,\n useState,\n} from \"react\";\nimport { ColumnChangeHandler } from \"../column-list\";\nimport { TableSettingsProps } from \"./TableSettingsPanel\";\n\nconst sortOrderFromAvailableColumns = (\n availableColumns: SchemaColumn[],\n columns: ColumnDescriptor[]\n) => {\n const sortedColumns: ColumnDescriptor[] = [];\n for (const { name } of availableColumns) {\n const column = columns.find((col) => col.name === name);\n if (column) {\n sortedColumns.push(column);\n }\n }\n return sortedColumns;\n};\n\nexport type ColumnItem = Pick<\n ColumnDescriptor,\n \"hidden\" | \"label\" | \"name\" | \"serverDataType\"\n> & {\n isCalculated: boolean;\n subscribed: boolean;\n};\n\nconst buildColumnItems = (\n availableColumns: SchemaColumn[],\n configuredColumns: ColumnDescriptor[]\n): ColumnItem[] => {\n return availableColumns.map<ColumnItem>(({ name, serverDataType }) => {\n const configuredColumn = configuredColumns.find((col) => col.name === name);\n return {\n hidden: configuredColumn?.hidden,\n isCalculated: isCalculatedColumn(name),\n label: configuredColumn?.label,\n name,\n serverDataType,\n subscribed: configuredColumn !== undefined,\n };\n });\n};\n\ntype ColumnState = {\n availableColumns: SchemaColumn[];\n tableConfig: TableConfig;\n};\n\nexport const useTableSettings = ({\n availableColumns: availableColumnsProp,\n onConfigChange,\n onDataSourceConfigChange,\n tableConfig: tableConfigProp,\n}: Omit<TableSettingsProps, \"onAddCalculatedColumn\">) => {\n const [{ availableColumns, tableConfig }, setColumnState] =\n useState<ColumnState>({\n availableColumns: availableColumnsProp,\n tableConfig: tableConfigProp,\n });\n\n const columnItems = useMemo(\n () => buildColumnItems(availableColumns, tableConfig.columns),\n [availableColumns, tableConfig.columns]\n );\n\n const handleMoveListItem = useCallback(\n (fromIndex: number, toIndex: number) => {\n setColumnState((state) => {\n const newAvailableColumns = moveItem(\n state.availableColumns,\n fromIndex,\n toIndex\n );\n const newColumns = sortOrderFromAvailableColumns(\n newAvailableColumns,\n tableConfig.columns\n );\n\n return {\n availableColumns: newAvailableColumns,\n tableConfig: {\n ...state.tableConfig,\n columns: newColumns,\n },\n };\n });\n },\n [tableConfig.columns]\n );\n\n const handleColumnChange = useCallback<ColumnChangeHandler>(\n (name, property, value) => {\n // to be applied immediately\n const columnItem = columnItems.find((col) => col.name === name);\n if (property === \"subscribed\") {\n if (columnItem?.subscribed) {\n const subscribedColumns = tableConfig.columns\n .filter((col) => col.name !== name)\n .map((col) => col.name);\n setColumnState((state) => ({\n ...state,\n tableConfig: {\n ...tableConfig,\n columns: tableConfig.columns.filter(\n subscribedOnly(subscribedColumns)\n ),\n },\n }));\n onDataSourceConfigChange({\n columns: subscribedColumns,\n });\n } else {\n const newConfig = {\n ...tableConfig,\n columns: addColumnToSubscribedColumns(\n tableConfig.columns,\n availableColumns,\n name\n ),\n };\n setColumnState((state) => ({\n ...state,\n tableConfig: newConfig,\n }));\n\n const subscribedColumns = newConfig.columns.map((col) => col.name);\n\n onDataSourceConfigChange({\n columns: subscribedColumns,\n });\n }\n } else if (columnItem?.subscribed) {\n const column = tableConfig.columns.find((col) => col.name === name);\n if (column) {\n const newConfig = updateTableConfig(tableConfig, {\n type: \"column-prop\",\n property,\n column,\n value,\n });\n setColumnState((state) => ({\n ...state,\n tableConfig: newConfig,\n }));\n }\n }\n },\n [availableColumns, columnItems, onDataSourceConfigChange, tableConfig]\n );\n\n const handleChangeColumnLabels = useCallback((evt: SyntheticEvent) => {\n const { value } = evt.target as HTMLFormElement;\n const columnFormatHeader =\n value === \"0\" ? undefined : value === \"1\" ? \"capitalize\" : \"uppercase\";\n setColumnState((state) => ({\n ...state,\n tableConfig: {\n ...state.tableConfig,\n columnFormatHeader,\n },\n }));\n }, []);\n\n const handleChangeTableAttribute = useCallback(\n (evt: MouseEvent<HTMLButtonElement>) => {\n const { ariaChecked, value } = evt.target as HTMLInputElement;\n setColumnState((state) => ({\n ...state,\n tableConfig: {\n ...state.tableConfig,\n [value]: ariaChecked !== \"true\",\n },\n }));\n },\n []\n );\n\n useLayoutEffectSkipFirst(() => {\n onConfigChange?.(tableConfig);\n }, [onConfigChange, tableConfig]);\n\n const columnLabelsValue =\n tableConfig.columnFormatHeader === undefined\n ? 0\n : tableConfig.columnFormatHeader === \"capitalize\"\n ? 1\n : 2;\n\n return {\n columnItems,\n columnLabelsValue,\n onChangeColumnLabels: handleChangeColumnLabels,\n onChangeTableAttribute: handleChangeTableAttribute,\n onColumnChange: handleColumnChange,\n onMoveListItem: handleMoveListItem,\n tableConfig,\n };\n};\n", "// export interface ColumnResizerProps {}\nimport { useCallback, useRef } from \"react\";\nimport \"./ColumnResizer.css\";\n\nconst NOOP = () => undefined;\n\nconst baseClass = \"vuuColumnResizer\";\nexport interface TableColumnResizerProps {\n onDrag: (evt: MouseEvent, moveBy: number) => void;\n onDragEnd: (evt: MouseEvent) => void;\n onDragStart: (evt: React.MouseEvent) => void;\n}\n\nexport const ColumnResizer = ({\n onDrag,\n onDragEnd = NOOP,\n onDragStart = NOOP,\n}: TableColumnResizerProps) => {\n const position = useRef(0);\n\n const onMouseMove = useCallback(\n (e: MouseEvent) => {\n if (e.stopPropagation) {\n e.stopPropagation();\n }\n\n if (e.preventDefault) {\n e.preventDefault();\n }\n\n const x = Math.round(e.clientX);\n const moveBy = x - position.current;\n position.current = x;\n\n if (moveBy !== 0) {\n onDrag(e, moveBy);\n }\n },\n [onDrag]\n );\n\n const onMouseUp = useCallback(\n (e: MouseEvent) => {\n window.removeEventListener(\"mouseup\", onMouseUp);\n window.removeEventListener(\"mousemove\", onMouseMove);\n onDragEnd(e);\n },\n [onDragEnd, onMouseMove]\n );\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n onDragStart(e);\n position.current = Math.round(e.clientX);\n\n window.addEventListener(\"mouseup\", onMouseUp);\n window.addEventListener(\"mousemove\", onMouseMove);\n\n if (e.stopPropagation) {\n e.stopPropagation();\n }\n\n if (e.preventDefault) {\n e.preventDefault();\n }\n },\n [onDragStart, onMouseMove, onMouseUp]\n );\n\n return (\n <div className={baseClass} data-align=\"end\" onMouseDown={handleMouseDown} />\n );\n};\n", "import { DataSource } from \"@vuu-ui/vuu-data\";\nimport { ContextMenuItemDescriptor, MenuBuilder } from \"@vuu-ui/vuu-data-types\";\nimport { KeyedColumnDescriptor, PinLocation } from \"@vuu-ui/vuu-datagrid-types\";\nimport { Filter } from \"@vuu-ui/vuu-filter-types\";\nimport { isNumericColumn } from \"@vuu-ui/vuu-utils\";\n\nexport type ContextMenuLocation = \"header\" | \"filter\" | \"grid\";\n\ntype MaybeColumn = { column?: KeyedColumnDescriptor };\ntype MaybeFilter = { filter?: Filter };\n\nexport const buildContextMenuDescriptors =\n (dataSource?: DataSource): MenuBuilder =>\n (location, options) => {\n const descriptors: ContextMenuItemDescriptor[] = [];\n if (dataSource === undefined) {\n return descriptors;\n }\n //TODO which should it be ?\n if (location === \"header\" || location === \"column-menu\") {\n descriptors.push(\n ...buildSortMenuItems(options as MaybeColumn, dataSource)\n );\n descriptors.push(\n ...buildGroupMenuItems(options as MaybeColumn, dataSource)\n );\n descriptors.push(\n ...buildAggregationMenuItems(options as MaybeColumn, dataSource)\n );\n descriptors.push(...buildColumnDisplayMenuItems(options as MaybeColumn));\n descriptors.push({\n action: \"column-settings\",\n icon: \"cog\",\n label: `Column Settings`,\n options,\n });\n descriptors.push({\n action: \"table-settings\",\n icon: \"cog\",\n label: `DataGrid Settings`,\n options,\n });\n } else if (location === \"filter\") {\n const { column, filter } = options as MaybeFilter & MaybeColumn;\n const colIsOnlyFilter = filter?.column === column?.name;\n descriptors.push({\n label: \"Edit filter\",\n action: \"filter-edit\",\n options,\n });\n\n descriptors.push({\n label: \"Remove filter\",\n action: \"filter-remove-column\",\n options,\n });\n\n if (column && !colIsOnlyFilter) {\n // TODO col might still be the only column in the filter if it is\n // involved in all clauses\n descriptors.push({\n label: `Remove all filters`,\n action: \"remove-filters\",\n options,\n });\n }\n }\n\n // if (options?.selectedRowCount){\n // // TODO pass the table name\n // const rpcActions = getRpcActions();\n // for (let {label, method} of rpcActions){\n // descriptors.push({action: Action.RpcCall, label, options: {method}})\n // }\n // }\n\n return descriptors;\n };\n\nfunction buildSortMenuItems(\n options: MaybeColumn,\n { sort: { sortDefs } }: DataSource\n): ContextMenuItemDescriptor[] {\n const { column } = options;\n const menuItems: ContextMenuItemDescriptor[] = [];\n if (column === undefined) {\n return menuItems;\n }\n\n const hasSort = sortDefs.length > 0;\n\n if (column.sorted === \"A\") {\n menuItems.push({\n label: \"Reverse Sort (DSC)\",\n action: \"sort-dsc\",\n options,\n });\n } else if (column.sorted === \"D\") {\n menuItems.push({\n label: \"Reverse Sort (ASC)\",\n action: \"sort-asc\",\n options,\n });\n } else if (typeof column.sorted === \"number\") {\n if (column.sorted > 0) {\n menuItems.push({\n label: \"Reverse Sort (DSC)\",\n action: \"sort-add-dsc\",\n options,\n });\n } else {\n menuItems.push({\n label: \"Reverse Sort (ASC)\",\n action: \"sort-add-asc\",\n options,\n });\n }\n\n // removing the last column from a sort would be a no-op, so pointless\n if (hasSort && Math.abs(column.sorted) < sortDefs.length) {\n menuItems.push({\n label: \"Remove from sort\",\n action: \"sort-remove\",\n options,\n });\n }\n\n menuItems.push({\n label: \"New Sort\",\n children: [\n { label: \"Ascending\", action: \"sort-asc\", options },\n { label: \"Descending\", action: \"sort-dsc\", options },\n ],\n });\n } else if (hasSort) {\n menuItems.push({\n label: \"Add to sort\",\n children: [\n { label: \"Ascending\", action: \"sort-add-asc\", options },\n { label: \"Descending\", action: \"sort-add-dsc\", options },\n ],\n });\n menuItems.push({\n label: \"New Sort\",\n children: [\n { label: \"Ascending\", action: \"sort-asc\", options },\n { label: \"Descending\", action: \"sort-dsc\", options },\n ],\n });\n } else {\n menuItems.push({\n label: \"Sort\",\n children: [\n { label: \"Ascending\", action: \"sort-asc\", options },\n { label: \"Descending\", action: \"sort-dsc\", options },\n ],\n });\n }\n return menuItems;\n}\n\nfunction buildAggregationMenuItems(\n options: MaybeColumn,\n dataSource: DataSource\n): ContextMenuItemDescriptor[] {\n const { column } = options;\n if (column === undefined || dataSource.groupBy.length === 0) {\n return [];\n }\n const { name, label = name } = column;\n\n return [\n {\n label: `Aggregate ${label}`,\n children: [\n { label: \"Count\", action: \"agg-count\", options },\n { label: \"Distinct\", action: \"agg-distinct\", options },\n ].concat(\n isNumericColumn(column)\n ? [\n { label: \"Sum\", action: \"agg-sum\", options },\n { label: \"Avg\", action: \"agg-avg\", options },\n { label: \"High\", action: \"agg-high\", options },\n { label: \"Low\", action: \"agg-low\", options },\n ]\n : []\n ),\n },\n ];\n}\n\nconst pinColumn = (options: unknown, pinLocation: PinLocation) =>\n ({\n label: `Pin ${pinLocation}`,\n action: `column-pin-${pinLocation}`,\n options,\n } as ContextMenuItemDescriptor);\n\nconst pinLeft = (options: unknown) => pinColumn(options, \"left\");\nconst pinFloating = (options: unknown) => pinColumn(options, \"floating\");\nconst pinRight = (options: unknown) => pinColumn(options, \"right\");\n\nfunction buildColumnDisplayMenuItems(\n options: MaybeColumn\n): ContextMenuItemDescriptor[] {\n const { column } = options;\n if (column === undefined) {\n return [];\n }\n const { pin } = column;\n\n const menuItems: ContextMenuItemDescriptor[] = [\n {\n label: `Hide column`,\n action: \"column-hide\",\n options,\n },\n {\n label: `Remove column`,\n action: \"column-remove\",\n options,\n },\n ];\n\n if (pin === undefined) {\n menuItems.push({\n label: `Pin column`,\n children: [pinLeft(options), pinFloating(options), pinRight(options)],\n });\n } else if (pin === \"left\") {\n menuItems.push(\n { label: \"Unpin column\", action: \"column-unpin\", options },\n {\n label: `Pin column`,\n children: [pinFloating(options), pinRight(options)],\n }\n );\n } else if (pin === \"right\") {\n menuItems.push(\n { label: \"Unpin column\", action: \"column-unpin\", options },\n {\n label: `Pin column`,\n children: [pinLeft(options), pinFloating(options)],\n }\n );\n } else if (pin === \"floating\") {\n menuItems.push(\n { label: \"Unpin column\", action: \"column-unpin\", options },\n {\n label: `Pin column`,\n children: [pinLeft(options), pinRight(options)],\n }\n );\n }\n\n return menuItems;\n}\n\nfunction buildGroupMenuItems(\n options: MaybeColumn,\n { groupBy }: DataSource\n): ContextMenuItemDescriptor[] {\n const { column } = options;\n const menuItems: ContextMenuItemDescriptor[] = [];\n if (column === undefined) {\n return menuItems;\n }\n\n const { name, label = name } = column;\n\n if (groupBy.length === 0) {\n menuItems.push({\n label: `Group by ${label}`,\n action: \"group\",\n options,\n });\n } else {\n menuItems.push({\n label: `Add ${label} to group by`,\n action: \"group-add\",\n options,\n });\n }\n\n return menuItems;\n}\n", "/* eslint-disable no-sequences */\nimport { DataSource } from \"@vuu-ui/vuu-data\";\nimport { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { Filter } from \"@vuu-ui/vuu-filter-types\";\nimport { removeColumnFromFilter } from \"@vuu-ui/vuu-utils\";\nimport { VuuFilter } from \"@vuu-ui/vuu-protocol-types\";\nimport { DataSourceFilter, MenuActionHandler } from \"@vuu-ui/vuu-data-types\";\nimport { PersistentColumnAction } from \"../useTableModel\";\nimport {\n addGroupColumn,\n addSortColumn,\n AggregationType,\n setAggregations,\n setSortColumn,\n} from \"@vuu-ui/vuu-utils\";\n\nexport interface ContextMenuOptions {\n column?: KeyedColumnDescriptor;\n filter?: Filter;\n sort?: VuuFilter;\n}\nexport interface ContextMenuHookProps {\n dataSource?: DataSource;\n onPersistentColumnOperation: (action: PersistentColumnAction) => void;\n}\n\nconst removeFilterColumn = (\n dataSourceFilter: DataSourceFilter,\n column: KeyedColumnDescriptor\n) => {\n if (dataSourceFilter.filterStruct && column) {\n const [filterStruct, filter] = removeColumnFromFilter(\n column,\n dataSourceFilter.filterStruct\n );\n return {\n filter,\n filterStruct,\n };\n } else {\n return dataSourceFilter;\n }\n};\n\nconst { Average, Count, Distinct, High, Low, Sum } = AggregationType;\n\nexport const useTableContextMenu = ({\n dataSource,\n onPersistentColumnOperation,\n}: ContextMenuHookProps) => {\n /** return {boolean} used by caller to determine whether to forward to additional installed context menu handlers */\n const handleContextMenuAction: MenuActionHandler = (action): boolean => {\n const gridOptions = action.options as ContextMenuOptions;\n if (gridOptions.column && dataSource) {\n const { column } = gridOptions;\n // prettier-ignore\n switch(action.menuId){\n case \"sort-asc\": return (dataSource.sort = setSortColumn(dataSource.sort, column, \"A\")), true;\n case \"sort-dsc\": return (dataSource.sort = setSortColumn(dataSource.sort, column, \"D\")), true;\n case \"sort-add-asc\": return (dataSource.sort = addSortColumn(dataSource.sort, column, \"A\")), true;\n case \"sort-add-dsc\": return (dataSource.sort = addSortColumn(dataSource.sort, column, \"D\")), true;\n case \"group\": return (dataSource.groupBy = addGroupColumn(dataSource.groupBy, column)), true;\n case \"group-add\": return (dataSource.groupBy = addGroupColumn(dataSource.groupBy, column)), true;\n case \"column-hide\": return onPersistentColumnOperation({type: \"hideColumns\", columns: [column]}), true;\n case \"column-remove\": return (dataSource.columns = dataSource.columns.filter(name => name !== column.name)), true\n case \"filter-remove-column\": return (dataSource.filter = removeFilterColumn(dataSource.filter, column)), true;\n case \"remove-filters\": return (dataSource.filter = {filter:\"\"}), true;\n case \"agg-avg\": return dataSource.aggregations = (setAggregations(dataSource.aggregations, column, Average)), true;\n case \"agg-high\": return dataSource.aggregations = (setAggregations(dataSource.aggregations, column, High)), true;\n case \"agg-low\": return dataSource.aggregations = (setAggregations(dataSource.aggregations, column, Low)), true;\n case \"agg-count\": return dataSource.aggregations = (setAggregations(dataSource.aggregations, column, Count)), true;\n case \"agg-distinct\": return dataSource.aggregations = (setAggregations(dataSource.aggregations, column, Distinct)), true;\n case \"agg-sum\": return dataSource.aggregations = (setAggregations(dataSource.aggregations, column, Sum)), true;\n case \"column-pin-floating\": return onPersistentColumnOperation({type: \"pinColumn\", column, pin: \"floating\"}), true;\n case \"column-pin-left\": return onPersistentColumnOperation({type: \"pinColumn\", column, pin: \"left\"}), true;\n case \"column-pin-right\": return onPersistentColumnOperation({type: \"pinColumn\", column, pin: \"right\"}), true;\n case \"column-unpin\": return onPersistentColumnOperation({type: \"pinColumn\", column, pin: undefined}), true\n case \"column-settings\": return onPersistentColumnOperation({type: \"columnSettings\", column}), true\n case \"table-settings\": return onPersistentColumnOperation({type: \"tableSettings\"}), true\n default:\n }\n }\n return false;\n };\n\n return handleContextMenuAction;\n};\n", "import { ContextMenuProvider } from \"@vuu-ui/vuu-popups\";\nimport { Button, useIdMemo } from \"@salt-ds/core\";\nimport { CSSProperties } from \"react\";\nimport { buildContextMenuDescriptors } from \"./context-menu\";\nimport { TableProps } from \"./dataTableTypes\";\n// import { RowBasedTable } from \"./RowBasedTable\";\nimport { RowBasedTable } from \"./RowBasedTable\";\nimport { useTable } from \"./useTable\";\nimport cx from \"classnames\";\n\nimport \"./Table.css\";\nimport \"./Table-loading.css\";\n\nimport { isDataLoading } from \"@vuu-ui/vuu-utils\";\n\nconst classBase = \"vuuTable\";\n\nexport const Table = ({\n allowConfigEditing: showSettings = false,\n className: classNameProp,\n config,\n dataSource,\n headerHeight = 25,\n height,\n id: idProp,\n onConfigChange,\n onFeatureEnabled,\n onFeatureInvocation,\n onSelectionChange,\n onShowConfigEditor: onShowSettings,\n renderBufferSize = 0,\n rowHeight = 20,\n selectionModel = \"extended\",\n style: styleProp,\n width,\n ...htmlAttributes\n}: TableProps) => {\n const id = useIdMemo(idProp);\n const {\n containerMeasurements: { containerRef, innerSize, outerSize },\n containerProps,\n dispatchColumnAction,\n draggable,\n draggedItemIndex,\n handleContextMenuAction,\n scrollProps,\n viewportMeasurements,\n ...tableProps\n } = useTable({\n config,\n dataSource,\n renderBufferSize,\n headerHeight,\n height,\n onConfigChange,\n onFeatureEnabled,\n onFeatureInvocation,\n onSelectionChange,\n rowHeight,\n selectionModel,\n width,\n });\n\n const style = {\n ...outerSize,\n \"--content-height\": `${viewportMeasurements.contentHeight}px`,\n \"--horizontal-scrollbar-height\": `${viewportMeasurements.horizontalScrollbarHeight}px`,\n \"--content-width\": `${viewportMeasurements.contentWidth}px`,\n \"--pinned-width-left\": `${viewportMeasurements.pinnedWidthLeft}px`,\n \"--pinned-width-right\": `${viewportMeasurements.pinnedWidthRight}px`,\n \"--header-height\": `${headerHeight}px`,\n \"--row-height\": `${rowHeight}px`,\n \"--table-height\": `${innerSize?.height}px`,\n \"--table-width\": `${innerSize?.width}px`,\n \"--total-header-height\": `${viewportMeasurements.totalHeaderHeight}px`,\n \"--vertical-scrollbar-width\": `${viewportMeasurements.verticalScrollbarWidth}px`,\n \"--viewport-body-height\": `${viewportMeasurements.viewportBodyHeight}px`,\n } as CSSProperties;\n\n const className = cx(classBase, classNameProp, {\n [`${classBase}-zebra`]: config.zebraStripes,\n [`${classBase}-loading`]: isDataLoading(tableProps.columns),\n });\n\n return (\n <ContextMenuProvider\n menuActionHandler={handleContextMenuAction}\n menuBuilder={buildContextMenuDescriptors(dataSource)}\n >\n <div\n {...htmlAttributes}\n {...containerProps}\n className={className}\n id={id}\n ref={containerRef}\n style={style}\n tabIndex={-1}\n >\n {innerSize ? (\n <div\n className={`${classBase}-scrollbarContainer`}\n ref={scrollProps.scrollbarContainerRef}\n >\n <div className={`${classBase}-scrollbarContent`} />\n </div>\n ) : null}\n {innerSize ? (\n <div\n className={`${classBase}-contentContainer`}\n ref={scrollProps.contentContainerRef}\n >\n <RowBasedTable\n {...tableProps}\n headerHeight={headerHeight}\n tableId={id}\n />\n {draggable}\n </div>\n ) : null}\n {showSettings && innerSize ? (\n <Button\n className={`${classBase}-settings`}\n data-icon=\"settings\"\n onClick={onShowSettings}\n variant=\"secondary\"\n />\n ) : null}\n </div>\n </ContextMenuProvider>\n );\n};\n", "import {\n buildColumnMap,\n getColumnStyle,\n isGroupColumn,\n metadataKeys,\n notHidden,\n visibleColumnAtIndex,\n} from \"@vuu-ui/vuu-utils\";\nimport { MouseEvent, useCallback, useMemo } from \"react\";\nimport { TableImplementationProps } from \"./dataTableTypes\";\nimport { TableRow } from \"./TableRow\";\nimport { TableGroupHeaderCell } from \"./TableGroupHeaderCell\";\nimport { TableHeaderCell } from \"./TableHeaderCell\";\n\nimport \"./RowBasedTable.css\";\n\nconst classBase = \"vuuTable\";\nconst { RENDER_IDX } = metadataKeys;\n\nexport const RowBasedTable = ({\n columns,\n columnsWithinViewport,\n data,\n getRowOffset,\n headings,\n onColumnResize,\n onHeaderCellDragStart,\n onContextMenu,\n onRemoveColumnFromGroupBy,\n onRowClick,\n onSort,\n onToggleGroup,\n tableId,\n virtualColSpan = 0,\n rowCount,\n}: TableImplementationProps) => {\n const handleDragStart = useCallback(\n (evt: MouseEvent) => {\n onHeaderCellDragStart?.(evt);\n },\n [onHeaderCellDragStart]\n );\n\n const visibleColumns = useMemo(() => {\n return columns.filter(notHidden);\n }, [columns]);\n\n const columnMap = useMemo(() => buildColumnMap(columns), [columns]);\n\n const handleHeaderClick = useCallback(\n (evt: MouseEvent) => {\n const targetElement = evt.target as HTMLElement;\n const headerCell = targetElement.closest(\n \".vuuTable-headerCell\"\n ) as HTMLElement;\n const colIdx = parseInt(headerCell?.dataset.idx ?? \"-1\");\n const column = visibleColumnAtIndex(columns, colIdx);\n const isAdditive = evt.shiftKey;\n column && onSort(column, isAdditive);\n },\n [columns, onSort]\n );\n\n return (\n <div aria-rowcount={rowCount} className={`${classBase}-table`} role=\"table\">\n <div className={`${classBase}-headers`} role=\"rowGroup\">\n {headings.map((colHeaders, i) => (\n <div className=\"vuuTable-heading\" key={i}>\n {colHeaders.map(({ label, width }, j) => (\n <div key={j} className=\"vuuTable-headingCell\" style={{ width }}>\n {label}\n </div>\n ))}\n </div>\n ))}\n <div role=\"row\">\n {visibleColumns.map((column, i) => {\n const style = getColumnStyle(column);\n return isGroupColumn(column) ? (\n <TableGroupHeaderCell\n column={column}\n data-idx={i}\n key={i}\n onRemoveColumn={onRemoveColumnFromGroupBy}\n onResize={onColumnResize}\n role=\"columnHeader\"\n style={style}\n />\n ) : (\n <TableHeaderCell\n column={column}\n data-idx={i}\n id={`${tableId}-${i}`}\n key={i}\n onClick={handleHeaderClick}\n onDragStart={handleDragStart}\n onResize={onColumnResize}\n role=\"columnHeader\"\n style={style}\n />\n );\n })}\n </div>\n </div>\n <div\n className={`${classBase}-body`}\n onContextMenu={onContextMenu}\n role=\"rowGroup\"\n >\n {data?.map((row) => (\n <TableRow\n columnMap={columnMap}\n columns={columnsWithinViewport}\n offset={getRowOffset(row)}\n key={row[RENDER_IDX]}\n onClick={onRowClick}\n virtualColSpan={virtualColSpan}\n onToggleGroup={onToggleGroup}\n row={row}\n />\n ))}\n </div>\n </div>\n );\n};\n", "import { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\nimport { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n ColumnMap,\n isGroupColumn,\n isJsonColumn,\n isJsonGroup,\n metadataKeys,\n notHidden,\n RowSelected,\n} from \"@vuu-ui/vuu-utils\";\nimport cx from \"classnames\";\nimport { HTMLAttributes, memo, MouseEvent, useCallback } from \"react\";\nimport { RowClickHandler } from \"./dataTableTypes\";\nimport { TableCell } from \"./TableCell\";\nimport { TableGroupCell } from \"./TableGroupCell\";\n\nimport \"./TableRow.css\";\n\nconst { IDX, IS_EXPANDED, SELECTED } = metadataKeys;\nconst { True, First, Last } = RowSelected;\n\nconst classBase = \"vuuTableRow\";\n\nexport interface RowProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\" | \"onClick\"> {\n columnMap: ColumnMap;\n columns: KeyedColumnDescriptor[];\n offset: number;\n onClick?: RowClickHandler;\n onToggleGroup?: (row: DataSourceRow, column: KeyedColumnDescriptor) => void;\n row: DataSourceRow;\n virtualColSpan?: number;\n}\n\nexport const TableRow = memo(function Row({\n columnMap,\n columns,\n offset,\n onClick,\n onToggleGroup,\n virtualColSpan = 0,\n row,\n}: RowProps) {\n const {\n [IDX]: rowIndex,\n [IS_EXPANDED]: isExpanded,\n [SELECTED]: selectionStatus,\n } = row;\n\n const className = cx(classBase, {\n [`${classBase}-even`]: rowIndex % 2 === 0,\n [`${classBase}-expanded`]: isExpanded,\n [`${classBase}-selected`]: selectionStatus & True,\n [`${classBase}-selectedStart`]: selectionStatus & First,\n [`${classBase}-selectedEnd`]: selectionStatus & Last,\n });\n\n const handleRowClick = useCallback(\n (evt: MouseEvent) => {\n const rangeSelect = evt.shiftKey;\n const keepExistingSelection = evt.ctrlKey || evt.metaKey; /* mac only */\n onClick?.(row, rangeSelect, keepExistingSelection);\n },\n [onClick, row]\n );\n\n const handleGroupCellClick = useCallback(\n (evt: MouseEvent, column: KeyedColumnDescriptor) => {\n if (isGroupColumn(column) || isJsonGroup(column, row)) {\n evt.stopPropagation();\n onToggleGroup?.(row, column);\n }\n },\n [onToggleGroup, row]\n );\n\n return (\n <div\n aria-selected={selectionStatus & True ? true : undefined}\n aria-rowindex={rowIndex}\n className={className}\n onClick={handleRowClick}\n role=\"row\"\n style={{\n transform: `translate3d(0px, ${offset}px, 0px)`,\n }}\n >\n {virtualColSpan > 0 ? (\n <div role=\"cell\" style={{ width: virtualColSpan }} />\n ) : null}\n {columns.filter(notHidden).map((column) => {\n const isGroup = isGroupColumn(column);\n const isJsonCell = isJsonColumn(column);\n const Cell = isGroup ? TableGroupCell : TableCell;\n return (\n <Cell\n column={column}\n columnMap={columnMap}\n key={column.name}\n onClick={isGroup || isJsonCell ? handleGroupCellClick : undefined}\n row={row}\n />\n );\n })}\n </div>\n );\n});\n", "import { TableCellProps } from \"@vuu-ui/vuu-datagrid-types\";\nimport { getColumnStyle, metadataKeys } from \"@vuu-ui/vuu-utils\";\nimport { EditableLabel } from \"@vuu-ui/vuu-ui-controls\";\nimport cx from \"classnames\";\nimport {\n KeyboardEvent,\n memo,\n MouseEvent,\n useCallback,\n useRef,\n useState,\n} from \"react\";\n\nimport \"./TableCell.css\";\n\nconst { KEY } = metadataKeys;\n\nexport const TableCell = memo(\n ({\n className: classNameProp,\n column,\n columnMap,\n onClick,\n row,\n }: TableCellProps) => {\n const labelFieldRef = useRef<HTMLDivElement>(null);\n const {\n align,\n CellRenderer,\n key,\n pin,\n editable,\n resizing,\n valueFormatter,\n } = column;\n const [editing, setEditing] = useState<boolean>(false);\n const value = valueFormatter(row[key]);\n const [editableValue, setEditableValue] = useState<string>(value);\n const handleTitleMouseDown = () => {\n labelFieldRef.current?.focus();\n };\n const handleTitleKeyDown = (evt: KeyboardEvent<HTMLTableCellElement>) => {\n if (evt.key === \"Enter\") {\n setEditing(true);\n }\n };\n\n const handleClick = useCallback(\n (evt: MouseEvent) => {\n onClick?.(evt, column);\n },\n [column, onClick]\n );\n\n const handleEnterEditMode = () => {\n setEditing(true);\n };\n\n const handleExitEditMode = (\n originalValue = \"\",\n finalValue = \"\",\n allowDeactivation = true,\n editCancelled = false\n ) => {\n setEditing(false);\n if (editCancelled) {\n setEditableValue(originalValue);\n } else if (finalValue !== originalValue) {\n setEditableValue(finalValue);\n }\n if (allowDeactivation === false) {\n labelFieldRef.current?.focus();\n }\n };\n\n // might want to useMemo here, this won't change often\n const className =\n cx(classNameProp, {\n vuuAlignRight: align === \"right\",\n vuuPinFloating: pin === \"floating\",\n vuuPinLeft: pin === \"left\",\n vuuPinRight: pin === \"right\",\n \"vuuTableCell-resizing\": resizing,\n }) || undefined;\n const style = getColumnStyle(column);\n return editable ? (\n <div\n className={className}\n data-editable\n role=\"cell\"\n style={style}\n onKeyDown={handleTitleKeyDown}\n >\n <EditableLabel\n editing={editing}\n key=\"title\"\n value={editableValue}\n onChange={setEditableValue}\n onMouseDownCapture={handleTitleMouseDown}\n onEnterEditMode={handleEnterEditMode}\n onExitEditMode={handleExitEditMode}\n onKeyDown={handleTitleKeyDown}\n ref={labelFieldRef}\n tabIndex={0}\n />\n </div>\n ) : (\n <div\n className={className}\n role=\"cell\"\n style={style}\n onClick={handleClick}\n >\n {CellRenderer ? (\n <CellRenderer column={column} columnMap={columnMap} row={row} />\n ) : (\n value\n )}\n </div>\n );\n },\n cellValuesAreEqual\n);\nTableCell.displayName = \"TableCell\";\n\nfunction cellValuesAreEqual(prev: TableCellProps, next: TableCellProps) {\n return (\n prev.column === next.column &&\n prev.onClick === next.onClick &&\n prev.row[KEY] === next.row[KEY] &&\n prev.row[prev.column.key] === next.row[next.column.key]\n );\n}\n", "import {\n GroupColumnDescriptor,\n TableCellProps,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n getColumnStyle,\n getGroupValueAndOffset,\n metadataKeys,\n} from \"@vuu-ui/vuu-utils\";\nimport { MouseEvent, useCallback } from \"react\";\n\nimport \"./TableGroupCell.css\";\n\nconst { IS_LEAF } = metadataKeys;\n\nexport const TableGroupCell = ({ column, onClick, row }: TableCellProps) => {\n const { columns } = column as GroupColumnDescriptor;\n const [value, offset] = getGroupValueAndOffset(columns, row);\n\n const handleClick = useCallback(\n (evt: MouseEvent) => {\n onClick?.(evt, column);\n },\n [column, onClick]\n );\n\n const style = getColumnStyle(column);\n const isLeaf = row[IS_LEAF];\n const spacers = Array(offset)\n .fill(0)\n .map((n, i) => <span className=\"vuuTableGroupCell-spacer\" key={i} />);\n return (\n <div\n className={\"vuuTableGroupCell vuuPinLeft\"}\n onClick={isLeaf ? undefined : handleClick}\n role=\"cell\"\n style={style}\n >\n {spacers}\n {isLeaf ? null : (\n <span className=\"vuuTableGroupCell-toggle\" data-icon=\"triangle-right\" />\n )}\n <span>{value}</span>\n </div>\n );\n};\n", "import cx from \"classnames\";\nimport { HTMLAttributes, useRef } from \"react\";\nimport { ColumnResizer } from \"./ColumnResizer\";\nimport { TableHeaderCellProps } from \"./TableHeaderCell\";\nimport {\n GroupColumnDescriptor,\n KeyedColumnDescriptor,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport { useTableColumnResize } from \"./useTableColumnResize\";\n\nimport \"./TableGroupHeaderCell.css\";\n\nconst classBase = \"vuuTable-groupHeaderCell\";\n\ninterface RemoveButtonProps\n extends Omit<HTMLAttributes<HTMLSpanElement>, \"onClick\"> {\n column?: KeyedColumnDescriptor;\n onClick?: (column?: KeyedColumnDescriptor) => void;\n}\nconst RemoveButton = ({\n column,\n onClick,\n ...htmlAttributes\n}: RemoveButtonProps) => {\n return (\n <span\n {...htmlAttributes}\n className={`${classBase}-close`}\n data-icon=\"close-circle\"\n onClick={() => onClick?.(column)}\n />\n );\n};\n\nexport interface ColHeaderProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onClick\"> {\n column: KeyedColumnDescriptor;\n onRemove?: (column?: KeyedColumnDescriptor) => void;\n}\n\nconst ColHeader = (props: ColHeaderProps) => {\n const { children, column, className } = props;\n return (\n <div className={cx(`${classBase}-col`, className)} role=\"columnheader\">\n <span className={`${classBase}-label`}>{column.name}</span>\n {children}\n </div>\n );\n};\n\nexport interface TableGroupHeaderCellProps\n extends Omit<TableHeaderCellProps, \"onDragStart\" | \"onDrag\" | \"onDragEnd\"> {\n column: GroupColumnDescriptor;\n onRemoveColumn?: (column?: KeyedColumnDescriptor) => void;\n}\n\nexport const TableGroupHeaderCell = ({\n column: groupColumn,\n className: classNameProp,\n onRemoveColumn,\n onResize,\n ...props\n}: TableGroupHeaderCellProps) => {\n const rootRef = useRef<HTMLTableCellElement>(null);\n const { isResizing, ...resizeProps } = useTableColumnResize({\n column: groupColumn,\n onResize,\n rootRef,\n });\n const className = cx(classBase, classNameProp, {\n vuuPinLeft: groupColumn.pin === \"left\",\n [`${classBase}-right`]: groupColumn.align === \"right\",\n [`${classBase}-resizing`]: groupColumn.resizing,\n [`${classBase}-pending`]: groupColumn.groupConfirmed === false,\n });\n const { columns } = groupColumn;\n\n return (\n <div className={className} ref={rootRef} {...props}>\n <div className={`${classBase}-inner`}>\n {columns.map((column) => (\n <ColHeader key={column.key} column={column}>\n {columns.length > 1 ? (\n <RemoveButton column={column} onClick={onRemoveColumn} />\n ) : null}\n </ColHeader>\n ))}\n <RemoveButton data-align=\"end\" onClick={onRemoveColumn} />\n {groupColumn.resizeable !== false ? (\n <ColumnResizer {...resizeProps} />\n ) : null}\n </div>\n </div>\n );\n};\n", "import { Heading, KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { RefObject, useCallback, useRef } from \"react\";\n\nexport type ResizeHandler = (evt: MouseEvent, moveBy: number) => void;\nexport interface CellResizeHookProps {\n column: KeyedColumnDescriptor | Heading;\n onResize?: (phase: resizePhase, columnName: string, width?: number) => void;\n rootRef: RefObject<HTMLDivElement>;\n}\n\ntype resizePhase = \"begin\" | \"resize\" | \"end\";\n\nexport interface CellResizeHookResult {\n isResizing: boolean;\n onDrag: (evt: MouseEvent, moveBy: number) => void;\n onDragStart: (evt: React.MouseEvent) => void;\n onDragEnd: (evt: MouseEvent) => void;\n}\n\nexport const useTableColumnResize = ({\n column,\n onResize,\n rootRef,\n}: CellResizeHookProps): CellResizeHookResult => {\n const widthRef = useRef(0);\n const isResizing = useRef(false);\n const { name } = column;\n\n const handleResizeStart = useCallback(() => {\n if (onResize && rootRef.current) {\n console.log(\"handleResizeStart\");\n const { width } = rootRef.current.getBoundingClientRect();\n widthRef.current = Math.round(width);\n isResizing.current = true;\n onResize?.(\"begin\", name);\n }\n }, [name, onResize, rootRef]);\n\n const handleResize = useCallback(\n (_evt: MouseEvent, moveBy: number) => {\n if (rootRef.current) {\n if (onResize) {\n const { width } = rootRef.current.getBoundingClientRect();\n const newWidth = Math.round(width) + moveBy;\n if (newWidth !== widthRef.current && newWidth > 0) {\n onResize(\"resize\", name, newWidth);\n widthRef.current = newWidth;\n }\n }\n }\n },\n [name, onResize, rootRef]\n );\n\n const handleResizeEnd = useCallback(() => {\n if (onResize) {\n onResize(\"end\", name, widthRef.current);\n setTimeout(() => {\n // set in a timeout to prevent the click event from firing and triggering a sort\n isResizing.current = false;\n }, 100);\n }\n }, [name, onResize]);\n\n return {\n isResizing: isResizing.current,\n onDrag: handleResize,\n onDragStart: handleResizeStart,\n onDragEnd: handleResizeEnd,\n };\n};\n", "import { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport cx from \"classnames\";\nimport { HTMLAttributes, MouseEvent, useCallback, useRef } from \"react\";\nimport { ColumnResizer } from \"./ColumnResizer\";\nimport { SortIndicator } from \"./SortIndicator\";\nimport { useTableColumnResize } from \"./useTableColumnResize\";\nimport { TableColumnResizeHandler } from \"./dataTableTypes\";\n\nimport \"./TableHeaderCell.css\";\nimport { useContextMenu } from \"@vuu-ui/vuu-popups\";\nimport { FilterIndicator } from \"./filter-indicator\";\n\nconst classBase = \"vuuTable-headerCell\";\n\nexport interface TableHeaderCellProps\n extends HTMLAttributes<HTMLTableCellElement> {\n column: KeyedColumnDescriptor;\n debugString?: string;\n onDragStart?: (evt: MouseEvent) => void;\n onResize?: TableColumnResizeHandler;\n}\n\nexport const TableHeaderCell = ({\n column,\n className: classNameProp,\n onClick,\n onDragStart,\n onResize,\n ...props\n}: TableHeaderCellProps) => {\n const rootRef = useRef<HTMLTableCellElement>(null);\n const { isResizing, ...resizeProps } = useTableColumnResize({\n column,\n onResize,\n rootRef,\n });\n\n const [showContextMenu] = useContextMenu();\n const dragTimerRef = useRef<number | null>(null);\n\n const handleContextMenu = (e: MouseEvent<HTMLElement>) => {\n showContextMenu(e, \"header\", { column });\n };\n\n const handleClick = useCallback(\n (evt: MouseEvent<HTMLTableCellElement>) => !isResizing && onClick?.(evt),\n [isResizing, onClick]\n );\n\n const handleMouseDown = useCallback(\n (evt: MouseEvent) => {\n dragTimerRef.current = window.setTimeout(() => {\n onDragStart?.(evt);\n dragTimerRef.current = null;\n }, 500);\n },\n [onDragStart]\n );\n const handleMouseUp = useCallback(() => {\n if (dragTimerRef.current !== null) {\n window.clearTimeout(dragTimerRef.current);\n dragTimerRef.current = null;\n }\n }, []);\n\n const className = cx(classBase, classNameProp, {\n vuuPinFloating: column.pin === \"floating\",\n vuuPinLeft: column.pin === \"left\",\n vuuPinRight: column.pin === \"right\",\n vuuEndPin: column.endPin,\n [`${classBase}-resizing`]: column.resizing,\n [`${classBase}-right`]: column.align === \"right\",\n });\n return (\n <div\n className={className}\n {...props}\n onClick={handleClick}\n onContextMenu={handleContextMenu}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n ref={rootRef}\n >\n <div className={`${classBase}-inner`}>\n <FilterIndicator column={column} />\n <div className={`${classBase}-label`}>{column.label}</div>\n <SortIndicator sorted={column.sorted} />\n {column.resizeable !== false ? (\n <ColumnResizer {...resizeProps} />\n ) : null}\n </div>\n </div>\n );\n};\n", "import { ColumnSort } from \"@vuu-ui/vuu-datagrid-types\";\nimport cx from \"classnames\";\n\nimport \"./SortIndicator.css\";\n\nexport interface SortIndicatorProps {\n sorted?: ColumnSort;\n}\n\nconst classBase = \"vuuSortIndicator\";\n\nexport const SortIndicator = ({ sorted }: SortIndicatorProps) => {\n if (!sorted) {\n return null;\n }\n\n const direction =\n typeof sorted === \"number\"\n ? sorted < 0\n ? \"dsc\"\n : \"asc\"\n : sorted === \"A\"\n ? \"asc\"\n : \"dsc\";\n\n return typeof sorted === \"number\" ? (\n <div className={cx(classBase, \"multi-col\", direction)}>\n <span data-icon={`sorted-${direction}`} />\n <span className={\"vuuSortPosition\"}>{Math.abs(sorted)}</span>\n </div>\n ) : (\n <div className={cx(classBase, \"single-col\")}>\n <span data-icon={`sorted-${direction}`} />\n </div>\n );\n};\n", "import { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { Filter } from \"@vuu-ui/vuu-filter-types\";\nimport { useContextMenu } from \"@vuu-ui/vuu-popups\";\nimport cx from \"classnames\";\nimport { HTMLAttributes, useCallback } from \"react\";\n\nimport \"./filter-indicator.css\";\n\nexport const Direction = {\n ASC: \"asc\",\n DSC: \"dsc\",\n};\n\nexport interface FilterIndicatorProps extends HTMLAttributes<HTMLDivElement> {\n column: KeyedColumnDescriptor;\n filter?: Filter;\n}\n\nexport const FilterIndicator = ({ column, filter }: FilterIndicatorProps) => {\n //TODO handle this at header level\n const [showContextMenu] = useContextMenu();\n\n const handleClick = useCallback(\n (evt) => {\n // if we do this through keyboard, need to get co-ords\n evt.stopPropagation();\n showContextMenu(evt, \"filter\", { column, filter });\n },\n [column, filter, showContextMenu]\n );\n\n if (!column.filter) {\n return null;\n }\n\n return (\n <div\n className={cx(\"vuuFilterIndicator\")}\n data-icon=\"filter\"\n onClick={handleClick}\n />\n );\n};\n", "import {\n DataSource,\n DataSourceSubscribedMessage,\n JsonDataSource,\n VuuFeatureInvocationMessage,\n VuuFeatureMessage,\n} from \"@vuu-ui/vuu-data\";\nimport { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\nimport {\n GridConfig,\n KeyedColumnDescriptor,\n SelectionChangeHandler,\n TableSelectionModel,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport { useContextMenu as usePopupContextMenu } from \"@vuu-ui/vuu-popups\";\nimport { VuuSortType } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n applySort,\n buildColumnMap,\n isJsonGroup,\n metadataKeys,\n moveItemDeprecated,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n MouseEvent,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useTableContextMenu } from \"./context-menu\";\nimport { TableColumnResizeHandler } from \"./dataTableTypes\";\nimport { useDataSource } from \"./useDataSource\";\nimport { useDraggableColumn } from \"./useDraggableColumn\";\nimport { useKeyboardNavigation } from \"./useKeyboardNavigation\";\nimport { MeasuredProps, useMeasuredContainer } from \"./useMeasuredContainer\";\nimport { useSelection } from \"./useSelection\";\nimport { PersistentColumnAction, useTableModel } from \"./useTableModel\";\nimport { useTableScroll } from \"./useTableScroll\";\nimport { useTableViewport } from \"../table-next/useTableViewport\";\nimport { useVirtualViewport } from \"./useVirtualViewport\";\n\nconst NO_ROWS = [] as const;\n\nexport interface TableHookProps extends MeasuredProps {\n config: Omit<GridConfig, \"headings\">;\n dataSource: DataSource;\n headerHeight: number;\n onConfigChange?: (config: Omit<GridConfig, \"headings\">) => void;\n onFeatureEnabled?: (message: VuuFeatureMessage) => void;\n onFeatureInvocation?: (message: VuuFeatureInvocationMessage) => void;\n renderBufferSize?: number;\n rowHeight: number;\n onSelectionChange?: SelectionChangeHandler;\n selectionModel: TableSelectionModel;\n}\n\nconst { KEY, IS_EXPANDED, IS_LEAF } = metadataKeys;\n\nexport const useTable = ({\n config,\n dataSource,\n headerHeight,\n onConfigChange,\n onFeatureEnabled,\n onFeatureInvocation,\n onSelectionChange,\n renderBufferSize = 0,\n rowHeight,\n selectionModel,\n ...measuredProps\n}: TableHookProps) => {\n const [rowCount, setRowCount] = useState<number>(dataSource.size);\n const expectConfigChangeRef = useRef(false);\n\n // When we detect and respond to changes to config below, we need\n // to include current dataSource config when we refresh the model.\n const dataSourceRef = useRef<DataSource>();\n dataSourceRef.current = dataSource;\n\n if (dataSource === undefined) {\n throw Error(\"no data source provided to Vuu Table\");\n }\n\n const containerMeasurements = useMeasuredContainer(measuredProps);\n\n const onDataRowcountChange = useCallback((size: number) => {\n setRowCount(size);\n }, []);\n\n const { columns, dispatchColumnAction, headings } = useTableModel(\n config,\n dataSource.config\n );\n\n const {\n getRowAtPosition,\n getRowOffset,\n setPctScrollTop,\n ...viewportMeasurements\n } = useTableViewport({\n columns,\n headerHeight,\n headings,\n rowCount,\n rowHeight,\n size: containerMeasurements.innerSize,\n });\n\n console.log(\n `rowCount from viewportMeasurements ${viewportMeasurements.rowCount}`\n );\n\n const onSubscribed = useCallback(\n ({ tableSchema }: DataSourceSubscribedMessage) => {\n if (tableSchema) {\n expectConfigChangeRef.current = true;\n dispatchColumnAction({\n type: \"setTableSchema\",\n tableSchema,\n });\n } else {\n console.log(\"usbscription message with no schema\");\n }\n },\n [dispatchColumnAction]\n );\n\n const handleSelectionChange: SelectionChangeHandler = useCallback(\n (selected) => {\n dataSource.select(selected);\n onSelectionChange?.(selected);\n },\n [dataSource, onSelectionChange]\n );\n\n const handleRowClick = useSelection({\n onSelectionChange: handleSelectionChange,\n selectionModel,\n });\n\n const { data, getSelectedRows, range, setRange } = useDataSource({\n dataSource,\n onFeatureEnabled,\n onFeatureInvocation,\n onSubscribed,\n onSizeChange: onDataRowcountChange,\n renderBufferSize,\n viewportRowCount: viewportMeasurements.rowCount,\n });\n\n // Keep a ref to current data. We use it to provide row for context menu actions.\n // We don't want to introduce data as a dependency on the context menu handler, just\n // needs to be correct at runtime when the row is right clicked.\n const dataRef = useRef<DataSourceRow[]>();\n dataRef.current = data;\n\n const onPersistentColumnOperation = useCallback(\n (action: PersistentColumnAction) => {\n expectConfigChangeRef.current = true;\n console.log(`onPersistentColumnOperation, dispatchColumnAction`, {\n action,\n });\n dispatchColumnAction(action as any);\n },\n [dispatchColumnAction]\n );\n\n const handleContextMenuAction = useTableContextMenu({\n dataSource,\n onPersistentColumnOperation,\n });\n\n const handleSort = useCallback(\n (\n column: KeyedColumnDescriptor,\n extendSort = false,\n sortType?: VuuSortType\n ) => {\n if (dataSource) {\n dataSource.sort = applySort(\n dataSource.sort,\n column,\n extendSort,\n sortType\n );\n }\n },\n [dataSource]\n );\n\n const handleColumnResize: TableColumnResizeHandler = useCallback(\n (phase, columnName, width) => {\n const column = columns.find((column) => column.name === columnName);\n if (column) {\n if (phase === \"end\") {\n expectConfigChangeRef.current = true;\n }\n dispatchColumnAction({\n type: \"resizeColumn\",\n phase,\n column,\n width,\n });\n } else {\n throw Error(\n `useDataTable.handleColumnResize, column ${columnName} not found`\n );\n }\n },\n [columns, dispatchColumnAction]\n );\n\n const handleToggleGroup = useCallback(\n (row: DataSourceRow, column: KeyedColumnDescriptor) => {\n const isJson = isJsonGroup(column, row);\n const key = row[KEY];\n\n if (row[IS_EXPANDED]) {\n (dataSource as JsonDataSource).closeTreeNode(key, true);\n if (isJson) {\n const idx = columns.indexOf(column);\n const rows = (dataSource as JsonDataSource).getRowsAtDepth(idx + 1);\n if (!rows.some((row) => row[IS_EXPANDED] || row[IS_LEAF])) {\n dispatchColumnAction({\n type: \"hideColumns\",\n columns: columns.slice(idx + 2),\n });\n }\n }\n } else {\n dataSource.openTreeNode(key);\n if (isJson) {\n const childRows = (dataSource as JsonDataSource).getChildRows(key);\n const idx = columns.indexOf(column) + 1;\n const columnsToShow = [columns[idx]];\n if (childRows.some((row) => row[IS_LEAF])) {\n columnsToShow.push(columns[idx + 1]);\n }\n if (columnsToShow.some((col) => col.hidden)) {\n dispatchColumnAction({\n type: \"showColumns\",\n columns: columnsToShow,\n });\n }\n }\n }\n },\n [columns, dataSource, dispatchColumnAction]\n );\n\n const {\n onVerticalScroll,\n onHorizontalScroll,\n columnsWithinViewport,\n virtualColSpan,\n } = useVirtualViewport({\n columns,\n getRowAtPosition,\n setRange,\n viewportMeasurements,\n });\n\n const handleVerticalScroll = useCallback(\n (scrollTop: number, pctScrollTop: number) => {\n setPctScrollTop(pctScrollTop);\n onVerticalScroll(scrollTop);\n },\n [onVerticalScroll, setPctScrollTop]\n );\n\n const { requestScroll, ...scrollProps } = useTableScroll({\n onHorizontalScroll,\n onVerticalScroll: handleVerticalScroll,\n viewport: viewportMeasurements,\n viewportHeight:\n (containerMeasurements.innerSize?.height ?? 0) - headerHeight,\n });\n\n const containerProps = useKeyboardNavigation({\n columnCount: columns.length,\n containerRef: containerMeasurements.containerRef,\n data,\n requestScroll,\n rowCount: dataSource?.size,\n viewportRange: range,\n });\n\n const handleRemoveColumnFromGroupBy = useCallback(\n (column?: KeyedColumnDescriptor) => {\n if (column) {\n if (dataSource && dataSource.groupBy.includes(column.name)) {\n dataSource.groupBy = dataSource.groupBy.filter(\n (columnName) => columnName !== column.name\n );\n }\n } else {\n dataSource.groupBy = [];\n }\n },\n [dataSource]\n );\n\n const handleDropColumn = useCallback(\n (fromIndex: number, toIndex: number) => {\n const column = dataSource.columns[fromIndex];\n const columns = moveItemDeprecated(dataSource.columns, column, toIndex);\n if (columns !== dataSource.columns) {\n dataSource.columns = columns;\n dispatchColumnAction({ type: \"tableConfig\", columns });\n }\n },\n [dataSource, dispatchColumnAction]\n );\n\n const draggableHook = useDraggableColumn({\n onDrop: handleDropColumn,\n });\n\n useEffect(() => {\n // External config has changed\n if (dataSourceRef.current) {\n expectConfigChangeRef.current = true;\n dispatchColumnAction({\n type: \"init\",\n tableConfig: config,\n dataSourceConfig: dataSourceRef.current.config,\n });\n }\n }, [config, dispatchColumnAction]);\n\n useEffect(() => {\n dataSource.on(\"config\", (config, confirmed) => {\n expectConfigChangeRef.current = true;\n dispatchColumnAction({\n type: \"tableConfig\",\n ...config,\n confirmed,\n });\n });\n }, [dataSource, dispatchColumnAction]);\n\n useMemo(() => {\n if (expectConfigChangeRef.current) {\n onConfigChange?.({\n ...config,\n columns,\n });\n expectConfigChangeRef.current = false;\n }\n }, [columns, config, onConfigChange]);\n\n const [showContextMenu] = usePopupContextMenu();\n\n const onContextMenu = useCallback(\n (evt: MouseEvent<HTMLElement>) => {\n const { current: currentData } = dataRef;\n const { current: currentDataSource } = dataSourceRef;\n const target = evt.target as HTMLElement;\n const cellEl = target?.closest(\"div[role='cell']\");\n const rowEl = target?.closest(\".vuuTableRow\");\n\n if (cellEl && rowEl && currentData && currentDataSource) {\n const { columns, selectedRowsCount } = currentDataSource;\n const columnMap = buildColumnMap(columns);\n const rowIndex = parseInt(rowEl.ariaRowIndex ?? \"-1\");\n const cellIndex = Array.from(rowEl.childNodes).indexOf(cellEl);\n const row = currentData.find(([idx]) => idx === rowIndex);\n const columnName = columns[cellIndex];\n\n showContextMenu(evt, \"grid\", {\n columnMap,\n columnName,\n row,\n selectedRows: selectedRowsCount === 0 ? NO_ROWS : getSelectedRows(),\n viewport: dataSource?.viewport,\n });\n }\n },\n [dataSource?.viewport, getSelectedRows, showContextMenu]\n );\n\n return {\n columns,\n columnsWithinViewport,\n containerMeasurements,\n containerProps,\n data,\n dispatchColumnAction,\n getRowOffset,\n handleContextMenuAction,\n headings,\n onColumnResize: handleColumnResize,\n onContextMenu,\n onRemoveColumnFromGroupBy: handleRemoveColumnFromGroupBy,\n onRowClick: handleRowClick,\n onSort: handleSort,\n onToggleGroup: handleToggleGroup,\n virtualColSpan,\n scrollProps,\n rowCount,\n viewportMeasurements,\n ...draggableHook,\n };\n};\n", "import {\n DataSource,\n DataSourceConfigMessage,\n DataSourceSubscribedMessage,\n SubscribeCallback,\n VuuFeatureInvocationMessage,\n VuuFeatureMessage,\n} from \"@vuu-ui/vuu-data\";\nimport { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\n\nimport {\n isVuuFeatureAction,\n isVuuFeatureInvocation,\n} from \"@vuu-ui/vuu-data-react\";\nimport { VuuRange, VuuSortCol } from \"@vuu-ui/vuu-protocol-types\";\nimport { getFullRange, metadataKeys, WindowRange } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nconst { SELECTED } = metadataKeys;\n\nexport type SubscriptionDetails = {\n columnNames?: string[];\n range: { from: number; to: number };\n sort?: VuuSortCol[];\n};\n\nexport interface DataSourceHookProps {\n dataSource: DataSource;\n onConfigChange?: (message: DataSourceConfigMessage) => void;\n onFeatureEnabled?: (message: VuuFeatureMessage) => void;\n onFeatureInvocation?: (message: VuuFeatureInvocationMessage) => void;\n onSizeChange: (size: number) => void;\n onSubscribed: (subscription: DataSourceSubscribedMessage) => void;\n range?: VuuRange;\n renderBufferSize?: number;\n viewportRowCount: number;\n}\n\n//TODO allow subscription details to be set before subscribe call\nexport function useDataSource({\n dataSource,\n onConfigChange,\n onFeatureEnabled,\n onFeatureInvocation,\n onSizeChange,\n onSubscribed,\n range = { from: 0, to: 0 },\n renderBufferSize = 0,\n viewportRowCount,\n}: DataSourceHookProps) {\n const [, forceUpdate] = useState<unknown>(null);\n const isMounted = useRef(true);\n const hasUpdated = useRef(false);\n const rangeRef = useRef<VuuRange>({ from: 0, to: 0 });\n const rafHandle = useRef<number | null>(null);\n const data = useRef<DataSourceRow[]>([]);\n\n const dataWindow = useMemo(\n () => new MovingWindow(getFullRange(range)),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n []\n );\n\n const setData = useCallback(\n (updates: DataSourceRow[]) => {\n for (const row of updates) {\n dataWindow.add(row);\n }\n data.current = dataWindow.data;\n hasUpdated.current = true;\n },\n [dataWindow]\n );\n\n const datasourceMessageHandler: SubscribeCallback = useCallback(\n (message) => {\n if (message.type === \"subscribed\") {\n onSubscribed?.(message);\n } else if (message.type === \"viewport-update\") {\n if (typeof message.size === \"number\") {\n onSizeChange?.(message.size);\n dataWindow.setRowCount(message.size);\n }\n if (message.rows) {\n setData(message.rows);\n } else if (typeof message.size === \"number\") {\n data.current = dataWindow.data;\n hasUpdated.current = true;\n }\n } else if (isVuuFeatureAction(message)) {\n onFeatureEnabled?.(message);\n } else if (isVuuFeatureInvocation(message)) {\n onFeatureInvocation?.(message);\n } else {\n console.log(`useDataSource unexpected message ${message.type}`);\n }\n },\n [\n dataWindow,\n onFeatureEnabled,\n onFeatureInvocation,\n onSizeChange,\n onSubscribed,\n setData,\n ]\n );\n\n useEffect(\n () => () => {\n if (rafHandle.current) {\n cancelAnimationFrame(rafHandle.current);\n rafHandle.current = null;\n }\n isMounted.current = false;\n },\n []\n );\n\n const refreshIfUpdated = useCallback(() => {\n if (isMounted.current) {\n if (hasUpdated.current) {\n forceUpdate({});\n hasUpdated.current = false;\n }\n rafHandle.current = requestAnimationFrame(refreshIfUpdated);\n }\n }, [forceUpdate]);\n\n useEffect(() => {\n rafHandle.current = requestAnimationFrame(refreshIfUpdated);\n }, [refreshIfUpdated]);\n\n const adjustRange = useCallback(\n (rowCount: number) => {\n const { from } = dataSource.range;\n const rowRange = { from, to: from + rowCount };\n const fullRange = getFullRange(rowRange, renderBufferSize);\n dataWindow.setRange(fullRange);\n dataSource.range = rangeRef.current = fullRange;\n // seems a bit naughty to emit from outside, but the datasource doesn't\n // know about the buffer size we add to the base range\n dataSource.emit(\"range\", rowRange);\n },\n [dataSource, dataWindow, renderBufferSize]\n );\n\n const setRange = useCallback(\n (range: VuuRange) => {\n const fullRange = getFullRange(range, renderBufferSize);\n dataWindow.setRange(fullRange);\n dataSource.range = rangeRef.current = fullRange;\n dataSource.emit(\"range\", range);\n },\n [dataSource, dataWindow, renderBufferSize]\n );\n\n const getSelectedRows = useCallback(() => {\n return dataWindow.getSelectedRows();\n }, [dataWindow]);\n\n // Note: we do not call unsubscribe in a cleanup function here.\n // Thats because we do not want to unsubscribe in the event that\n // our view is unmounts due to a layout drag drop operation. In\n // that scenario, we disable the viewport. This is handles at the\n // View level. Might need to revisit this - what if Table is not\n // nested within a View ?\n\n useEffect(() => {\n dataSource?.subscribe(\n {\n range: rangeRef.current,\n },\n datasourceMessageHandler\n );\n }, [dataSource, datasourceMessageHandler, onConfigChange]);\n\n useEffect(() => {\n console.log(`adjust range as rowCount chnaged ${viewportRowCount}`);\n adjustRange(viewportRowCount);\n }, [adjustRange, viewportRowCount]);\n\n return {\n data: data.current,\n getSelectedRows,\n range: rangeRef.current,\n setRange,\n dataSource,\n };\n}\n\nexport class MovingWindow {\n public data: DataSourceRow[];\n public rowCount = 0;\n private range: WindowRange;\n\n constructor({ from, to }: VuuRange) {\n this.range = new WindowRange(from, to);\n //internal data is always 0 based, we add range.from to determine an offset\n this.data = new Array(to - from);\n this.rowCount = 0;\n }\n\n setRowCount = (rowCount: number) => {\n if (rowCount < this.data.length) {\n this.data.length = rowCount;\n }\n\n this.rowCount = rowCount;\n };\n\n add(data: DataSourceRow) {\n const [index] = data;\n if (this.isWithinRange(index)) {\n const internalIndex = index - this.range.from;\n this.data[internalIndex] = data;\n\n // assign 'pre-selected' selection state. This allows us to assign a className\n // to a non selected row that immediately precedes a selected row. Useful for\n // styling. This cannot be achieved any other way as document order of row\n // elements does not necessarily reflect data order.\n const isSelected = data[SELECTED];\n const preSelected = this.data[internalIndex - 1]?.[SELECTED];\n if (preSelected === 0 && isSelected) {\n this.data[internalIndex - 1][SELECTED] = 2;\n } else if (preSelected === 2 && !isSelected) {\n this.data[internalIndex - 1][SELECTED] = 0;\n }\n }\n }\n\n getAtIndex(index: number) {\n return this.range.isWithin(index) &&\n this.data[index - this.range.from] != null\n ? this.data[index - this.range.from]\n : undefined;\n }\n\n isWithinRange(index: number) {\n return this.range.isWithin(index);\n }\n\n setRange({ from, to }: VuuRange) {\n if (from !== this.range.from || to !== this.range.to) {\n const [overlapFrom, overlapTo] = this.range.overlap(from, to);\n const newData = new Array(Math.max(0, to - from));\n for (let i = overlapFrom; i < overlapTo; i++) {\n const data = this.getAtIndex(i);\n if (data) {\n const index = i - from;\n newData[index] = data;\n }\n }\n this.data = newData;\n this.range.from = from;\n this.range.to = to;\n }\n }\n\n getSelectedRows() {\n return this.data.filter((row) => row[SELECTED] === 1);\n }\n}\n", "import { useDragDropNext as useDragDrop } from \"@vuu-ui/vuu-ui-controls\";\nimport { MouseEvent, useCallback, useRef } from \"react\";\n\ntype MousePos = {\n clientX: number;\n clientY: number;\n idx: string;\n};\n\nexport interface DraggableColumnHookProps {\n onDrop: (fromIndex: number, toIndex: number) => void;\n}\n\nexport const useDraggableColumn = ({ onDrop }: DraggableColumnHookProps) => {\n const mousePosRef = useRef<MousePos>();\n const containerRef = useRef<HTMLElement | null>(null);\n\n const handleDropSettle = useCallback(() => {\n console.log(`handleDropSettle`);\n mousePosRef.current = undefined;\n containerRef.current = null;\n }, []);\n\n const { draggable, draggedItemIndex, onMouseDown } = useDragDrop({\n // allowDragDrop: \"drop-indicator\",\n allowDragDrop: true,\n draggableClassName: \"vuuTable-headerCell\",\n orientation: \"horizontal\",\n containerRef,\n itemQuery: \".vuuTable-headerCell\",\n onDrop,\n onDropSettle: handleDropSettle,\n });\n\n const onHeaderCellDragStart = useCallback(\n (evt: MouseEvent) => {\n const { clientX, clientY } = evt;\n console.log(\n `useDraggableColumn handleHeaderCellDragStart means mouseDown fired on a column in RowBasedTable`\n );\n const sourceElement = evt.target as HTMLElement;\n const columnHeaderCell = sourceElement.closest(\".vuuTable-headerCell\");\n containerRef.current = columnHeaderCell?.closest(\n \"[role='row']\"\n ) as HTMLDivElement;\n const {\n dataset: { idx = \"-1\" },\n } = columnHeaderCell as HTMLElement;\n mousePosRef.current = {\n clientX,\n clientY,\n idx,\n };\n onMouseDown?.(evt);\n },\n [onMouseDown]\n );\n\n // useLayoutEffect(() => {\n // if (tableLayout === \"column\" && mousePosRef.current && !draggable) {\n // const { clientX, clientY, idx } = mousePosRef.current;\n // const target = tableContainerRef.current?.querySelector(\n // `.vuuTable-table[data-idx=\"${idx}\"]`\n // ) as HTMLElement;\n // if (target) {\n // const evt = {\n // persist: () => undefined,\n // nativeEvent: {\n // clientX,\n // clientY,\n // target,\n // },\n // };\n // onMouseDown?.(evt as unknown as MouseEvent);\n // }\n // }\n // }, [draggable, onMouseDown, tableContainerRef, tableLayout]);\n\n return {\n draggable,\n draggedItemIndex,\n onHeaderCellDragStart,\n };\n};\n", "import { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\nimport { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { withinRange } from \"@vuu-ui/vuu-utils\";\nimport {\n KeyboardEvent,\n MouseEvent,\n RefObject,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport {\n ArrowDown,\n ArrowKey,\n ArrowLeft,\n ArrowRight,\n ArrowUp,\n End,\n Home,\n isNavigationKey,\n isPagingKey,\n NavigationKey,\n PageDown,\n PageUp,\n} from \"./keyUtils\";\nimport { ScrollRequestHandler } from \"./useTableScroll\";\n\nexport type CellPos = [number, number];\n\nconst headerCellQuery = (colIdx: number) =>\n `.vuuTable-headers .vuuTable-headerCell:nth-child(${colIdx + 1})`;\nconst dataCellQuery = (rowIdx: number, colIdx: number) =>\n `.vuuTable-body > [aria-rowindex='${rowIdx}'] > [role='cell']:nth-child(${\n colIdx + 1\n })`;\n\nconst NULL_CELL_POS: CellPos = [-1, -1];\n\nfunction nextCellPos(\n key: ArrowKey,\n [rowIdx, colIdx]: CellPos,\n columnCount: number,\n rowCount: number\n): CellPos {\n if (key === ArrowUp) {\n if (rowIdx > -1) {\n return [rowIdx - 1, colIdx];\n } else {\n return [rowIdx, colIdx];\n }\n } else if (key === ArrowDown) {\n if (rowIdx === -1) {\n return [0, colIdx];\n } else if (rowIdx === rowCount - 1) {\n return [rowIdx, colIdx];\n } else {\n return [rowIdx + 1, colIdx];\n }\n } else if (key === ArrowRight) {\n if (colIdx < columnCount - 1) {\n return [rowIdx, colIdx + 1];\n } else {\n return [rowIdx, colIdx];\n }\n } else if (key === ArrowLeft) {\n if (colIdx > 0) {\n return [rowIdx, colIdx - 1];\n } else {\n return [rowIdx, colIdx];\n }\n }\n return [rowIdx, colIdx];\n}\n\nexport interface NavigationHookProps {\n containerRef: RefObject<HTMLElement>;\n columnCount?: number;\n data: DataSourceRow[];\n disableHighlightOnFocus?: boolean;\n label?: string;\n viewportRange: VuuRange;\n requestScroll?: ScrollRequestHandler;\n restoreLastFocus?: boolean;\n rowCount?: number;\n selected?: unknown;\n}\n\nexport const useKeyboardNavigation = ({\n columnCount = 0,\n containerRef,\n disableHighlightOnFocus,\n data,\n requestScroll,\n rowCount = 0,\n viewportRange,\n}: NavigationHookProps) => {\n const { from: viewportFirstRow, to: viewportLastRow } = viewportRange;\n const focusedCellPos = useRef<CellPos>([-1, -1]);\n const focusableCell = useRef<HTMLTableCellElement>();\n const activeCellPos = useRef<CellPos>([-1, 0]);\n\n const getTableCell = useCallback(\n ([rowIdx, colIdx]: CellPos) => {\n const cssQuery =\n rowIdx === -1 ? headerCellQuery(colIdx) : dataCellQuery(rowIdx, colIdx);\n return containerRef.current?.querySelector(\n cssQuery\n ) as HTMLTableCellElement;\n },\n [containerRef]\n );\n\n const getFocusedCell = (element: HTMLElement | Element | null) =>\n element?.closest(\n \"[role='columnHeader'],[role='cell']\"\n ) as HTMLTableCellElement | null;\n\n const getTableCellPos = (tableCell: HTMLTableCellElement): CellPos => {\n if (tableCell.role === \"columnHeader\") {\n const colIdx = parseInt(tableCell.dataset.idx ?? \"-1\", 10);\n return [-1, colIdx];\n } else {\n const focusedRow = tableCell.closest(\"[role='row']\");\n if (focusedRow) {\n const rowIdx = parseInt(focusedRow.ariaRowIndex ?? \"-1\", 10);\n // TODO will get trickier when we introduce horizontal virtualisation\n const colIdx = Array.from(focusedRow.childNodes).indexOf(tableCell);\n return [rowIdx, colIdx];\n }\n }\n return NULL_CELL_POS;\n };\n\n const focusCell = useCallback(\n (cellPos: CellPos) => {\n if (containerRef.current) {\n const activeCell = getTableCell(cellPos);\n if (activeCell) {\n if (activeCell !== focusableCell.current) {\n focusableCell.current?.setAttribute(\"tabindex\", \"\");\n focusableCell.current = activeCell;\n activeCell.setAttribute(\"tabindex\", \"0\");\n }\n activeCell.focus();\n } else if (!withinRange(cellPos[0], viewportRange)) {\n focusableCell.current = undefined;\n requestScroll?.({ type: \"scroll-page\", direction: \"up\" });\n }\n }\n },\n // TODO we recreate this function whenever viewportRange changes, which will\n // be often whilst scrolling - store range in a a ref ?\n [containerRef, getTableCell, requestScroll, viewportRange]\n );\n\n const setActiveCell = useCallback(\n (rowIdx: number, colIdx: number, fromKeyboard = false) => {\n const pos: CellPos = [rowIdx, colIdx];\n activeCellPos.current = pos;\n focusCell(pos);\n if (fromKeyboard) {\n focusedCellPos.current = pos;\n }\n },\n [focusCell]\n );\n\n const virtualizeActiveCell = useCallback(() => {\n focusableCell.current?.setAttribute(\"tabindex\", \"\");\n focusableCell.current = undefined;\n }, []);\n\n const nextPageItemIdx = useCallback(\n async (\n key: \"PageDown\" | \"PageUp\" | \"Home\" | \"End\",\n cellPos: CellPos\n ): Promise<CellPos> => {\n switch (key) {\n case PageDown:\n requestScroll?.({ type: \"scroll-page\", direction: \"down\" });\n break;\n case PageUp:\n requestScroll?.({ type: \"scroll-page\", direction: \"up\" });\n break;\n case Home:\n requestScroll?.({ type: \"scroll-end\", direction: \"home\" });\n break;\n case End:\n requestScroll?.({ type: \"scroll-end\", direction: \"end\" });\n break;\n }\n // TODO set up a scroll listener here, reset focused cell once scroll completes\n return cellPos;\n },\n [requestScroll]\n );\n\n const handleFocus = useCallback(() => {\n if (disableHighlightOnFocus !== true) {\n if (containerRef.current?.contains(document.activeElement)) {\n // IF focus arrives via keyboard, a cell will have received focus,\n // we handle that here. If focus arrives via click on a cell with\n // no tabindex (i.e all cells except one) we leave that to the\n // click handler.\n const focusedCell = getFocusedCell(document.activeElement);\n if (focusedCell) {\n focusedCellPos.current = getTableCellPos(focusedCell);\n }\n }\n }\n }, [disableHighlightOnFocus, containerRef]);\n\n const navigateChildItems = useCallback(\n async (key: NavigationKey) => {\n const [nextRowIdx, nextColIdx] = isPagingKey(key)\n ? await nextPageItemIdx(key, activeCellPos.current)\n : nextCellPos(key, activeCellPos.current, columnCount, rowCount);\n\n const [rowIdx, colIdx] = activeCellPos.current;\n if (nextRowIdx !== rowIdx || nextColIdx !== colIdx) {\n setActiveCell(nextRowIdx, nextColIdx, true);\n }\n },\n [columnCount, nextPageItemIdx, rowCount, setActiveCell]\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (data.length > 0 && isNavigationKey(e.key)) {\n e.preventDefault();\n e.stopPropagation();\n void navigateChildItems(e.key);\n }\n },\n [data, navigateChildItems]\n );\n\n const handleClick = useCallback(\n // Might not be a cell e.g the Settings button\n (evt: MouseEvent) => {\n const target = evt.target as HTMLElement;\n const focusedCell = getFocusedCell(target);\n if (focusedCell) {\n const [rowIdx, colIdx] = getTableCellPos(focusedCell);\n setActiveCell(rowIdx, colIdx);\n }\n },\n [setActiveCell]\n );\n\n const containerProps = useMemo(() => {\n return {\n onClick: handleClick,\n onFocus: handleFocus,\n onKeyDown: handleKeyDown,\n };\n }, [handleClick, handleFocus, handleKeyDown]);\n\n useLayoutEffect(() => {\n const { current: cellPos } = activeCellPos;\n const withinViewport =\n cellPos[0] >= viewportFirstRow && cellPos[0] <= viewportLastRow;\n\n if (focusableCell.current && !withinViewport) {\n virtualizeActiveCell();\n } else if (!focusableCell.current && withinViewport) {\n focusCell(cellPos);\n }\n }, [focusCell, viewportFirstRow, viewportLastRow, virtualizeActiveCell]);\n\n // First render will only render the outer container when explicit\n // sizing has not been provided. Outer container is measured and\n // only then, on second render, is content rendered.\n const fullyRendered = containerRef.current?.firstChild != null;\n useEffect(() => {\n if (fullyRendered && focusableCell.current === undefined) {\n const headerCell = containerRef.current?.querySelector(\n headerCellQuery(0)\n ) as HTMLTableCellElement;\n if (headerCell) {\n headerCell.setAttribute(\"tabindex\", \"0\");\n focusableCell.current = headerCell;\n }\n }\n }, [containerRef, fullyRendered]);\n\n return containerProps;\n};\n", "import React from \"react\";\n\nfunction union<T>(set1: Set<T>, ...sets: Set<T>[]) {\n const result = new Set(set1);\n for (let set of sets) {\n for (let element of set) {\n result.add(element);\n }\n }\n return result;\n}\n\nexport const ArrowUp = \"ArrowUp\";\nexport const ArrowDown = \"ArrowDown\";\nexport const ArrowLeft = \"ArrowLeft\";\nexport const ArrowRight = \"ArrowRight\";\nexport const Enter = \"Enter\";\nexport const Escape = \"Escape\";\nexport const Home = \"Home\";\nexport const End = \"End\";\nexport const PageUp = \"PageUp\";\nexport const PageDown = \"PageDown\";\nexport const Space = \" \";\nexport const Tab = \"Tab\";\n\nconst actionKeys = new Set([\"Enter\", \"Delete\", \" \"]);\nconst focusKeys = new Set([\"Tab\"]);\nconst arrowLeftRightKeys = new Set([\"ArrowRight\", \"ArrowLeft\"]);\nconst navigationKeys = new Set<NavigationKey>([\n Home,\n End,\n PageUp,\n PageDown,\n ArrowDown,\n ArrowLeft,\n ArrowRight,\n ArrowUp,\n]);\nconst functionKeys = new Set([\n \"F1\",\n \"F2\",\n \"F3\",\n \"F4\",\n \"F5\",\n \"F6\",\n \"F7\",\n \"F8\",\n \"F9\",\n \"F10\",\n \"F11\",\n \"F12\",\n]);\nconst specialKeys = union(\n actionKeys,\n navigationKeys,\n arrowLeftRightKeys,\n functionKeys,\n focusKeys\n);\nexport const isCharacterKey = (evt: React.KeyboardEvent): boolean => {\n if (specialKeys.has(evt.key)) {\n return false;\n }\n return evt.key.length === 1 && !evt.ctrlKey && !evt.metaKey && !evt.altKey;\n};\n\nexport type ArrowKey = \"ArrowUp\" | \"ArrowDown\" | \"ArrowLeft\" | \"ArrowRight\";\nexport type PageKey = \"Home\" | \"End\" | \"PageUp\" | \"PageDown\";\nexport type NavigationKey = PageKey | ArrowKey;\nconst PageKeys = [\"Home\", \"End\", \"PageUp\", \"PageDown\"];\nexport const isPagingKey = (key: string): key is PageKey =>\n PageKeys.includes(key);\n\nexport const isNavigationKey = (key: string): key is NavigationKey => {\n return navigationKeys.has(key as NavigationKey);\n};\n", "import { isValidNumber } from \"@vuu-ui/vuu-utils\";\nimport { RefObject, useCallback, useMemo, useRef, useState } from \"react\";\nimport { useResizeObserver, ResizeHandler } from \"./useResizeObserver\";\n\nconst ClientWidthHeight = [\"clientHeight\", \"clientWidth\"];\n\nexport interface ClientSize {\n clientHeight: number;\n clientWidth: number;\n}\n\nexport interface MeasuredProps {\n defaultHeight?: number;\n defaultWidth?: number;\n height?: number;\n width?: number;\n}\n\nexport interface Size {\n height: number | \"100%\";\n width: number | \"100%\";\n}\n\nexport interface MeasuredSize {\n height: number;\n width: number;\n}\n\ninterface MeasuredState {\n css: CssSize;\n outer: Size;\n inner?: MeasuredSize;\n}\n\nconst isNumber = (val: unknown): val is number => Number.isFinite(val);\n\nexport type CssSize = {\n height: string;\n width: string;\n};\nconst FULL_SIZE: CssSize = { height: \"100%\", width: \"100%\" };\n\nexport interface MeasuredContainerHookResult {\n containerRef: RefObject<HTMLDivElement>;\n cssSize: CssSize;\n outerSize: Size;\n innerSize?: MeasuredSize;\n}\n\n// If (outer) height and width are known at initialisation (i.e. they\n// were passed as props), use as initial values for inner size. If there\n// is no border on Table, these values will not change. If there is a border,\n// inner values will be updated once measured.\nconst getInitialCssSize = (height: unknown, width: unknown): CssSize => {\n if (isValidNumber(height) && isValidNumber(width)) {\n return {\n height: `${height}px`,\n width: `${width}px`,\n };\n } else {\n return FULL_SIZE;\n }\n};\n\nconst getInitialInnerSize = (\n height: unknown,\n width: unknown\n): MeasuredSize | undefined => {\n if (isValidNumber(height) && isValidNumber(width)) {\n return {\n height,\n width,\n };\n }\n};\n\nexport const useMeasuredContainer = ({\n defaultHeight = 0,\n defaultWidth = 0,\n height,\n width,\n}: MeasuredProps): MeasuredContainerHookResult => {\n const containerRef = useRef<HTMLDivElement>(null);\n const [size, setSize] = useState<MeasuredState>({\n css: getInitialCssSize(height, width),\n inner: getInitialInnerSize(height, width),\n outer: {\n height: height ?? \"100%\",\n width: width ?? \"100%\",\n },\n });\n\n useMemo(() => {\n setSize((currentSize) => {\n const { inner, outer } = currentSize;\n if (isValidNumber(height) && isValidNumber(width) && inner && outer) {\n const { height: innerHeight, width: innerWidth } = inner;\n const { height: outerHeight, width: outerWidth } = outer;\n\n if (outerHeight !== height || outerWidth !== width) {\n const heightDiff = isValidNumber(outerHeight)\n ? outerHeight - innerHeight\n : 0;\n const widthDiff = isValidNumber(outerWidth)\n ? outerWidth - innerWidth\n : 0;\n return {\n ...currentSize,\n outer: { height, width },\n inner: { height: height - heightDiff, width: width - widthDiff },\n };\n }\n }\n return currentSize;\n });\n }, [height, width]);\n\n const onResize: ResizeHandler = useCallback(\n ({ clientWidth, clientHeight }: Partial<ClientSize>) => {\n setSize((currentSize) => {\n const { css, inner, outer } = currentSize;\n return isNumber(clientHeight) &&\n isNumber(clientWidth) &&\n (clientWidth !== inner?.width || clientHeight !== inner?.height)\n ? {\n css,\n outer,\n inner: {\n width: Math.floor(clientWidth) || defaultWidth,\n height: Math.floor(clientHeight) || defaultHeight,\n },\n }\n : currentSize;\n });\n },\n [defaultHeight, defaultWidth]\n );\n\n useResizeObserver(containerRef, ClientWidthHeight, onResize, true);\n\n return {\n containerRef,\n cssSize: size.css,\n outerSize: size.outer,\n innerSize: size.inner,\n };\n};\n", "import { RefObject, useCallback, useEffect, useRef } from \"react\";\n\nexport const WidthHeight = [\"height\", \"width\"];\nexport const WidthOnly = [\"width\"];\n\nexport type measurements<T = string | number> = {\n height?: T;\n clientHeight?: number;\n clientWidth?: number;\n contentHeight?: number;\n contentWidth?: number;\n scrollHeight?: number;\n scrollWidth?: number;\n width?: T;\n};\ntype measuredDimension = keyof measurements<number>;\n\nexport type ResizeHandler = (measurements: measurements<number>) => void;\n\ntype observedDetails = {\n onResize?: ResizeHandler;\n measurements: measurements<number>;\n};\nconst observedMap = new Map<HTMLElement, observedDetails>();\n\nconst getTargetSize = (\n element: HTMLElement,\n size: {\n height: number;\n width: number;\n contentHeight: number;\n contentWidth: number;\n },\n dimension: measuredDimension\n): number => {\n switch (dimension) {\n case \"height\":\n return size.height;\n case \"clientHeight\":\n return element.clientHeight;\n case \"clientWidth\":\n return element.clientWidth;\n case \"contentHeight\":\n return size.contentHeight;\n case \"contentWidth\":\n return size.contentWidth;\n case \"scrollHeight\":\n return Math.ceil(element.scrollHeight);\n case \"scrollWidth\":\n return Math.ceil(element.scrollWidth);\n case \"width\":\n return size.width;\n default:\n return 0;\n }\n};\n\n// TODO should we make this create-on-demand\nconst resizeObserver = new ResizeObserver((entries: ResizeObserverEntry[]) => {\n for (const entry of entries) {\n const { target, borderBoxSize, contentBoxSize } = entry;\n const observedTarget = observedMap.get(target as HTMLElement);\n if (observedTarget) {\n const [{ blockSize: height, inlineSize: width }] = borderBoxSize;\n const [{ blockSize: contentHeight, inlineSize: contentWidth }] =\n contentBoxSize;\n const { onResize, measurements } = observedTarget;\n let sizeChanged = false;\n for (const [dimension, size] of Object.entries(measurements)) {\n const newSize = getTargetSize(\n target as HTMLElement,\n { height, width, contentHeight, contentWidth },\n dimension as measuredDimension\n );\n\n if (newSize !== size) {\n sizeChanged = true;\n measurements[dimension as measuredDimension] = newSize;\n }\n }\n if (sizeChanged) {\n // TODO only return measured sizes\n onResize && onResize(measurements);\n }\n }\n }\n});\n\n// TODO use an optional lag (default to false) to ask to fire onResize\n// with initial size\nexport function useResizeObserver(\n ref: RefObject<Element | HTMLElement | null>,\n dimensions: string[],\n onResize: ResizeHandler,\n reportInitialSize = false\n) {\n const dimensionsRef = useRef(dimensions);\n\n const measure = useCallback((target: HTMLElement): measurements<number> => {\n const { width, height } = target.getBoundingClientRect();\n const { clientWidth: contentWidth, clientHeight: contentHeight } = target;\n return dimensionsRef.current.reduce(\n (map: { [key: string]: number }, dim) => {\n map[dim] = getTargetSize(\n target,\n { width, height, contentHeight, contentWidth },\n dim as measuredDimension\n );\n return map;\n },\n {}\n );\n }, []);\n\n // TODO use ref to store resizeHandler here\n // resize handler registered with REsizeObserver will never change\n // use ref to store user onResize callback here\n // resizeHandler will call user callback.current\n\n // Keep this effect separate in case user inadvertently passes different\n // dimensions or callback instance each time - we only ever want to\n // initiate new observation when ref changes.\n useEffect(() => {\n const target = ref.current as HTMLElement;\n async function registerObserver() {\n // Create the map entry immediately. useEffect may fire below\n // before fonts are ready and attempt to update entry\n observedMap.set(target, { measurements: {} as measurements<number> });\n await document.fonts.ready;\n const observedTarget = observedMap.get(target);\n if (observedTarget) {\n const measurements = measure(target);\n observedTarget.measurements = measurements;\n resizeObserver.observe(target);\n if (reportInitialSize) {\n onResize(measurements);\n }\n } else {\n console.log(\n `%cuseResizeObserver an target expected to be under observation wa snot found. This warrants investigation`,\n \"font-weight:bold; color:red;\"\n );\n }\n }\n\n if (target) {\n // TODO might we want multiple callers to attach a listener to the same element ?\n if (observedMap.has(target)) {\n throw Error(\n \"useResizeObserver attemping to observe same element twice\"\n );\n }\n // TODO set a pending entry on map\n registerObserver();\n }\n return () => {\n if (target && observedMap.has(target)) {\n resizeObserver.unobserve(target);\n observedMap.delete(target);\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [measure, ref]);\n\n useEffect(() => {\n const target = ref.current as HTMLElement;\n const record = observedMap.get(target);\n if (record) {\n if (dimensionsRef.current !== dimensions) {\n dimensionsRef.current = dimensions;\n const measurements = measure(target);\n record.measurements = measurements;\n }\n // Might not have changed, but no harm ...\n record.onResize = onResize;\n }\n }, [dimensions, measure, ref, onResize]);\n}\n", "import {\n Selection,\n SelectionChangeHandler,\n TableSelectionModel,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n deselectItem,\n isRowSelected,\n metadataKeys,\n selectItem,\n} from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useRef } from \"react\";\nimport { RowClickHandler } from \"./dataTableTypes\";\n\nconst { IDX } = metadataKeys;\n\nconst NO_SELECTION: Selection = [];\n\nexport interface SelectionHookProps {\n selectionModel: TableSelectionModel;\n onSelectionChange: SelectionChangeHandler;\n}\n\nexport const useSelection = ({\n selectionModel,\n onSelectionChange,\n}: SelectionHookProps) => {\n selectionModel === \"extended\" || selectionModel === \"checkbox\";\n const lastActiveRef = useRef(-1);\n const selectedRef = useRef<Selection>(NO_SELECTION);\n\n const handleSelectionChange: RowClickHandler = useCallback(\n (row, rangeSelect, keepExistingSelection) => {\n const { [IDX]: idx } = row;\n const { current: active } = lastActiveRef;\n const { current: selected } = selectedRef;\n\n const selectOperation = isRowSelected(row) ? deselectItem : selectItem;\n\n const newSelected = selectOperation(\n selectionModel,\n selected,\n idx,\n rangeSelect,\n keepExistingSelection,\n active\n );\n\n selectedRef.current = newSelected;\n lastActiveRef.current = idx;\n\n if (onSelectionChange) {\n onSelectionChange(newSelected);\n }\n },\n [onSelectionChange, selectionModel]\n );\n\n return handleSelectionChange;\n};\n", "import {\n ColumnDescriptor,\n GridConfig,\n KeyedColumnDescriptor,\n PinLocation,\n TableConfig,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n applyFilterToColumns,\n applyGroupByToColumns,\n applySortToColumns,\n findColumn,\n getCellRenderer,\n getColumnName,\n getTableHeadings,\n getValueFormatter,\n isFilteredColumn,\n isGroupColumn,\n isPinned,\n isTypeDescriptor,\n metadataKeys,\n updateColumn,\n sortPinnedColumns,\n stripFilterFromColumns,\n moveItemDeprecated,\n getDefaultAlignment,\n} from \"@vuu-ui/vuu-utils\";\n\nimport { Reducer, useReducer } from \"react\";\nimport { VuuColumnDataType } from \"@vuu-ui/vuu-protocol-types\";\nimport { DataSourceConfig } from \"@vuu-ui/vuu-data\";\nimport { TableSchema } from \"@vuu-ui/vuu-data/src/message-utils\";\n\nconst DEFAULT_COLUMN_WIDTH = 100;\nconst KEY_OFFSET = metadataKeys.count;\n\nconst columnWithoutDataType = ({ serverDataType }: ColumnDescriptor) =>\n serverDataType === undefined;\n\nconst getCellRendererForColumn = (column: ColumnDescriptor) => {\n if (isTypeDescriptor(column.type)) {\n return getCellRenderer(column.type?.renderer);\n }\n};\n\nconst getServerDataTypeForColumn = (\n column: ColumnDescriptor,\n tableSchema?: TableSchema\n): VuuColumnDataType => {\n if (column.serverDataType) {\n return column.serverDataType;\n } else if (tableSchema) {\n const schemaColumn = tableSchema.columns.find(\n (col) => col.name === column.name\n );\n if (schemaColumn) {\n return schemaColumn.serverDataType;\n }\n }\n return \"string\";\n};\n\nexport interface TableModel extends Omit<GridConfig, \"columns\"> {\n columns: KeyedColumnDescriptor[];\n tableSchema?: Readonly<TableSchema>;\n}\n\nexport interface ColumnActionInit {\n type: \"init\";\n tableConfig: TableConfig;\n dataSourceConfig?: DataSourceConfig;\n}\n\nexport interface ColumnActionHide {\n type: \"hideColumns\";\n columns: KeyedColumnDescriptor[];\n}\n\nexport interface ColumnActionShow {\n type: \"showColumns\";\n columns: KeyedColumnDescriptor[];\n}\nexport interface ColumnActionMove {\n type: \"moveColumn\";\n column: KeyedColumnDescriptor;\n moveBy?: 1 | -1;\n moveTo?: number;\n}\n\nexport interface ColumnActionPin {\n type: \"pinColumn\";\n column: ColumnDescriptor;\n pin?: PinLocation;\n}\nexport interface ColumnActionResize {\n type: \"resizeColumn\";\n column: KeyedColumnDescriptor;\n phase: \"begin\" | \"resize\" | \"end\";\n width?: number;\n}\n\nexport interface ColumnActionSetTableSchema {\n type: \"setTableSchema\";\n tableSchema: TableSchema;\n}\n\nexport interface ColumnActionUpdate {\n type: \"updateColumn\";\n column: ColumnDescriptor;\n}\n\nexport interface ColumnActionUpdateProp {\n align?: ColumnDescriptor[\"align\"];\n column: KeyedColumnDescriptor;\n hidden?: ColumnDescriptor[\"hidden\"];\n label?: ColumnDescriptor[\"label\"];\n resizing?: KeyedColumnDescriptor[\"resizing\"];\n type: \"updateColumnProp\";\n width?: ColumnDescriptor[\"width\"];\n}\n\nexport interface ColumnActionTableConfig extends DataSourceConfig {\n confirmed?: boolean;\n type: \"tableConfig\";\n}\nexport interface ColumnActionColumnSettings extends DataSourceConfig {\n type: \"columnSettings\";\n column: KeyedColumnDescriptor;\n}\n\nexport interface ColumnActionTableSettings extends DataSourceConfig {\n type: \"tableSettings\";\n}\n\n/**\n * PersistentColumnActions are those actions that require us to persist user changes across sessions\n */\nexport type PersistentColumnAction =\n | ColumnActionPin\n | ColumnActionHide\n | ColumnActionColumnSettings\n | ColumnActionTableSettings;\n\nexport const isShowColumnSettings = (\n action: PersistentColumnAction\n): action is ColumnActionColumnSettings => action.type === \"columnSettings\";\n\nexport const isShowTableSettings = (\n action: PersistentColumnAction\n): action is ColumnActionTableSettings => action.type === \"tableSettings\";\n\nexport type GridModelAction =\n | ColumnActionColumnSettings\n | ColumnActionHide\n | ColumnActionInit\n | ColumnActionMove\n | ColumnActionPin\n | ColumnActionResize\n | ColumnActionSetTableSchema\n | ColumnActionShow\n | ColumnActionUpdate\n | ColumnActionUpdateProp\n | ColumnActionTableConfig;\n\nexport type GridModelReducer = Reducer<TableModel, GridModelAction>;\n\nexport type ColumnActionDispatch = (action: GridModelAction) => void;\n\nconst columnReducer: GridModelReducer = (state, action) => {\n // info?.(`GridModelReducer ${action.type}`);\n switch (action.type) {\n case \"init\":\n return init(action);\n case \"moveColumn\":\n return moveColumn(state, action);\n case \"resizeColumn\":\n return resizeColumn(state, action);\n case \"setTableSchema\":\n return setTableSchema(state, action);\n case \"hideColumns\":\n return hideColumns(state, action);\n case \"showColumns\":\n return showColumns(state, action);\n case \"pinColumn\":\n return pinColumn(state, action);\n case \"updateColumnProp\":\n return updateColumnProp(state, action);\n case \"tableConfig\":\n return updateTableConfig(state, action);\n default:\n console.log(`unhandled action ${action.type}`);\n return state;\n }\n};\n\nexport const useTableModel = (\n tableConfig: Omit<GridConfig, \"headings\">,\n dataSourceConfig?: DataSourceConfig\n) => {\n const [state, dispatchColumnAction] = useReducer<\n GridModelReducer,\n InitialConfig\n >(columnReducer, { tableConfig, dataSourceConfig }, init);\n\n return {\n columns: state.columns,\n dispatchColumnAction,\n headings: state.headings,\n };\n};\n\ntype InitialConfig = {\n dataSourceConfig?: DataSourceConfig;\n tableConfig: TableConfig;\n};\n\nfunction init({ dataSourceConfig, tableConfig }: InitialConfig): TableModel {\n const columns = tableConfig.columns.map(\n toKeyedColumWithDefaults(tableConfig)\n );\n const maybePinnedColumns = columns.some(isPinned)\n ? sortPinnedColumns(columns)\n : columns;\n const state = {\n columns: maybePinnedColumns,\n headings: getTableHeadings(maybePinnedColumns),\n };\n if (dataSourceConfig) {\n const { columns, ...rest } = dataSourceConfig;\n return updateTableConfig(state, {\n type: \"tableConfig\",\n ...rest,\n });\n } else {\n return state;\n }\n}\n\nconst getLabel = (\n label: string,\n columnFormatHeader?: \"uppercase\" | \"capitalize\"\n): string => {\n if (columnFormatHeader === \"uppercase\") {\n return label.toUpperCase();\n } else if (columnFormatHeader === \"capitalize\") {\n return label[0].toUpperCase() + label.slice(1).toLowerCase();\n }\n return label;\n};\n\nconst toKeyedColumWithDefaults =\n (options: Partial<TableModel> | Partial<GridConfig>) =>\n (\n column: ColumnDescriptor & { key?: number },\n index: number\n ): KeyedColumnDescriptor => {\n const serverDataType = getServerDataTypeForColumn(\n column,\n (options as Partial<TableModel>).tableSchema\n );\n const { columnDefaultWidth = DEFAULT_COLUMN_WIDTH, columnFormatHeader } =\n options;\n const {\n align = getDefaultAlignment(serverDataType),\n key,\n name,\n label = name,\n width = columnDefaultWidth,\n ...rest\n } = column;\n\n const keyedColumnWithDefaults = {\n ...rest,\n align,\n CellRenderer: getCellRendererForColumn(column),\n label: getLabel(label, columnFormatHeader),\n key: key ?? index + KEY_OFFSET,\n name,\n originalIdx: index,\n serverDataType,\n valueFormatter: getValueFormatter(column),\n width: width,\n };\n\n if (isGroupColumn(keyedColumnWithDefaults)) {\n keyedColumnWithDefaults.columns = keyedColumnWithDefaults.columns.map(\n (col) => toKeyedColumWithDefaults(options)(col, col.key)\n );\n }\n\n return keyedColumnWithDefaults;\n };\n\nfunction moveColumn(\n state: TableModel,\n { column, moveBy, moveTo }: ColumnActionMove\n) {\n const { columns } = state;\n if (typeof moveBy === \"number\") {\n const idx = columns.indexOf(column);\n const newColumns = columns.slice();\n const [movedColumns] = newColumns.splice(idx, 1);\n newColumns.splice(idx + moveBy, 0, movedColumns);\n return {\n ...state,\n columns: newColumns,\n };\n } else if (typeof moveTo === \"number\") {\n return {\n ...state,\n columns: moveItemDeprecated(columns, column, moveTo),\n };\n }\n return state;\n}\n\nfunction hideColumns(state: TableModel, { columns }: ColumnActionHide) {\n if (columns.some((col) => col.hidden !== true)) {\n return columns.reduce<TableModel>((s, c) => {\n if (c.hidden !== true) {\n return updateColumnProp(s, {\n type: \"updateColumnProp\",\n column: c,\n hidden: true,\n });\n } else {\n return s;\n }\n }, state);\n } else {\n return state;\n }\n}\nfunction showColumns(state: TableModel, { columns }: ColumnActionShow) {\n if (columns.some((col) => col.hidden)) {\n return columns.reduce<TableModel>((s, c) => {\n if (c.hidden) {\n return updateColumnProp(s, {\n type: \"updateColumnProp\",\n column: c,\n hidden: false,\n });\n } else {\n return s;\n }\n }, state);\n } else {\n return state;\n }\n}\n\nfunction resizeColumn(\n state: TableModel,\n { column, phase, width }: ColumnActionResize\n) {\n const type = \"updateColumnProp\";\n const resizing = phase !== \"end\";\n\n switch (phase) {\n case \"begin\":\n return updateColumnProp(state, { type, column, resizing });\n case \"end\":\n return updateColumnProp(state, { type, column, resizing, width });\n case \"resize\":\n return updateColumnProp(state, { type, column, width });\n default:\n throw Error(`useTableModel.resizeColumn, invalid resizePhase ${phase}`);\n }\n}\n\nfunction setTableSchema(\n state: TableModel,\n { tableSchema }: ColumnActionSetTableSchema\n) {\n const { columns } = state;\n if (columns.some(columnWithoutDataType)) {\n const cols = columns.map((column) => {\n const serverDataType = getServerDataTypeForColumn(column, tableSchema);\n return {\n ...column,\n align: column.align ?? getDefaultAlignment(serverDataType),\n serverDataType,\n };\n });\n\n return {\n ...state,\n columns: cols,\n tableSchema,\n };\n } else {\n return {\n ...state,\n tableSchema,\n };\n }\n}\n\nfunction pinColumn(state: TableModel, action: ColumnActionPin) {\n let { columns } = state;\n const { column, pin } = action;\n columns = updateColumn(columns, column.name, { pin });\n columns = sortPinnedColumns(columns);\n console.log({ withPins: columns });\n return {\n ...state,\n columns,\n };\n}\nfunction updateColumnProp(state: TableModel, action: ColumnActionUpdateProp) {\n let { columns } = state;\n const { align, column, hidden, label, resizing, width } = action;\n const options: Partial<KeyedColumnDescriptor> = {};\n\n if (align === \"left\" || align === \"right\") {\n options.align = align;\n }\n if (typeof label === \"string\") {\n options.label = label;\n }\n if (typeof resizing === \"boolean\") {\n options.resizing = resizing;\n }\n if (typeof hidden === \"boolean\") {\n options.hidden = hidden;\n }\n if (typeof width === \"number\") {\n options.width = width;\n }\n\n columns = updateColumn(columns, column.name, options);\n\n return {\n ...state,\n columns,\n };\n}\n\nfunction updateTableConfig(\n state: TableModel,\n { columns, confirmed, filter, groupBy, sort }: ColumnActionTableConfig\n) {\n const hasColumns = columns && columns.length > 0;\n const hasGroupBy = groupBy !== undefined;\n const hasFilter = typeof filter?.filter === \"string\";\n const hasSort = sort && sort.sortDefs.length > 0;\n\n //TODO check if just confirmed has changed\n\n let result = state;\n\n if (hasColumns) {\n result = {\n ...state,\n columns: columns.map((colName, index) => {\n const columnName = getColumnName(colName);\n const key: number = index + KEY_OFFSET;\n const col = findColumn(result.columns, columnName);\n if (col) {\n if (col.key === key) {\n return col;\n } else {\n return {\n ...col,\n key,\n };\n }\n } else {\n // we have a column which was not previously included.\n // TODO How do we get the serverDataType\n // TODO it needs to be available in availableCOlumns or allColumns in state\n return toKeyedColumWithDefaults(state)(\n {\n name: colName,\n },\n index\n );\n }\n throw Error(`useTableModel column ${colName} not found`);\n }),\n };\n }\n\n if (hasGroupBy) {\n result = {\n ...state,\n columns: applyGroupByToColumns(result.columns, groupBy, confirmed),\n };\n }\n\n if (hasSort) {\n result = {\n ...state,\n columns: applySortToColumns(result.columns, sort),\n };\n }\n\n if (hasFilter) {\n result = {\n ...state,\n columns: applyFilterToColumns(result.columns, filter),\n };\n } else if (result.columns.some(isFilteredColumn)) {\n result = {\n ...state,\n columns: stripFilterFromColumns(result.columns),\n };\n }\n\n return result;\n}\n", "import { useCallback, useRef } from \"react\";\nimport { Viewport } from \"./dataTableTypes\";\n\nexport interface ScrollRequestEnd {\n type: \"scroll-end\";\n direction: \"home\" | \"end\";\n}\n\nexport interface ScrollRequestPage {\n type: \"scroll-page\";\n direction: \"up\" | \"down\";\n}\n\nexport interface ScrollRequestDistance {\n type: \"scroll-distance\";\n distance: number;\n}\n\nexport type ScrollRequest =\n | ScrollRequestPage\n | ScrollRequestDistance\n | ScrollRequestEnd;\n\nexport type ScrollRequestHandler = (request: ScrollRequest) => void;\n\nconst getPctScroll = (container: HTMLElement) => {\n const { scrollLeft, scrollTop } = container;\n const { clientHeight, clientWidth, scrollHeight, scrollWidth } = container;\n const pctScrollLeft = scrollLeft / (scrollWidth - clientWidth);\n const pctScrollTop = scrollTop / (scrollHeight - clientHeight);\n\n return [pctScrollLeft, pctScrollTop];\n};\n\nconst getMaxScroll = (container: HTMLElement) => {\n const { clientHeight, clientWidth, scrollHeight, scrollWidth } = container;\n return [scrollWidth - clientWidth, scrollHeight - clientHeight];\n};\n\ninterface CallbackRefHookProps<T = HTMLElement> {\n onAttach?: (el: T) => void;\n onDetach: (el: T) => void;\n label?: string;\n}\n\nconst useCallbackRef = <T = HTMLElement>({\n onAttach,\n onDetach,\n}: CallbackRefHookProps<T>) => {\n const ref = useRef<T | null>(null);\n const callbackRef = useCallback(\n (el: T | null) => {\n if (el) {\n ref.current = el;\n onAttach?.(el);\n } else if (ref.current) {\n const { current: originalRef } = ref;\n ref.current = el;\n onDetach?.(originalRef);\n }\n },\n [onAttach, onDetach]\n );\n return callbackRef;\n};\n\nexport interface TableScrollHookProps {\n onHorizontalScroll?: (scrollLeft: number) => void;\n onVerticalScroll?: (scrollTop: number, pctScrollTop: number) => void;\n viewportHeight: number;\n viewport: Viewport;\n}\n\nexport const useTableScroll = ({\n onHorizontalScroll,\n onVerticalScroll,\n viewport,\n}: TableScrollHookProps) => {\n const contentContainerScrolledRef = useRef(false);\n\n const scrollPosRef = useRef({ scrollTop: 0, scrollLeft: 0 });\n const scrollbarContainerRef = useRef<HTMLDivElement | null>(null);\n const contentContainerRef = useRef<HTMLDivElement | null>(null);\n const {\n maxScrollContainerScrollHorizontal: maxScrollLeft,\n maxScrollContainerScrollVertical: maxScrollTop,\n } = viewport;\n\n const handleScrollbarContainerScroll = useCallback(() => {\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n const { current: contentContainerScrolled } = contentContainerScrolledRef;\n if (contentContainerScrolled) {\n contentContainerScrolledRef.current = false;\n } else if (contentContainer && scrollbarContainer) {\n const [pctScrollLeft, pctScrollTop] = getPctScroll(scrollbarContainer);\n const [maxScrollLeft, maxScrollTop] = getMaxScroll(contentContainer);\n const rootScrollLeft = Math.round(pctScrollLeft * maxScrollLeft);\n const rootScrollTop = Math.round(pctScrollTop * maxScrollTop);\n console.log(\n `pctScrollTop ${pctScrollTop}, maxScrollTop ${maxScrollTop} rootScrollTop ${rootScrollTop}`\n );\n\n contentContainer.scrollTo({\n left: rootScrollLeft,\n top: rootScrollTop,\n behavior: \"auto\",\n });\n }\n }, []);\n\n const handleContentContainerScroll = useCallback(() => {\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n const { current: scrollPos } = scrollPosRef;\n\n if (contentContainer && scrollbarContainer) {\n const { scrollLeft, scrollTop } = contentContainer;\n const [pctScrollLeft, pctScrollTop] = getPctScroll(contentContainer);\n contentContainerScrolledRef.current = true;\n\n scrollbarContainer.scrollLeft = Math.round(pctScrollLeft * maxScrollLeft);\n scrollbarContainer.scrollTop = Math.round(pctScrollTop * maxScrollTop);\n\n if (scrollPos.scrollTop !== scrollTop) {\n scrollPos.scrollTop = scrollTop;\n onVerticalScroll?.(scrollTop, pctScrollTop);\n }\n if (scrollPos.scrollLeft !== scrollLeft) {\n scrollPos.scrollLeft = scrollLeft;\n onHorizontalScroll?.(scrollLeft);\n }\n }\n }, [maxScrollLeft, maxScrollTop, onHorizontalScroll, onVerticalScroll]);\n\n const handleAttachScrollbarContainer = useCallback(\n (el: HTMLDivElement) => {\n scrollbarContainerRef.current = el;\n el.addEventListener(\"scroll\", handleScrollbarContainerScroll, {\n passive: true,\n });\n },\n [handleScrollbarContainerScroll]\n );\n\n const handleDetachScrollbarContainer = useCallback(\n (el: HTMLDivElement) => {\n scrollbarContainerRef.current = null;\n el.removeEventListener(\"scroll\", handleScrollbarContainerScroll);\n },\n [handleScrollbarContainerScroll]\n );\n\n const handleAttachContentContainer = useCallback(\n (el: HTMLDivElement) => {\n contentContainerRef.current = el;\n el.addEventListener(\"scroll\", handleContentContainerScroll, {\n passive: true,\n });\n },\n [handleContentContainerScroll]\n );\n\n const handleDetachContentContainer = useCallback(\n (el: HTMLDivElement) => {\n contentContainerRef.current = null;\n el.removeEventListener(\"scroll\", handleContentContainerScroll);\n },\n [handleContentContainerScroll]\n );\n\n const contentContainerCallbackRef = useCallbackRef({\n onAttach: handleAttachContentContainer,\n onDetach: handleDetachContentContainer,\n });\n\n const scrollbarContainerCallbackRef = useCallbackRef({\n onAttach: handleAttachScrollbarContainer,\n onDetach: handleDetachScrollbarContainer,\n });\n\n const requestScroll: ScrollRequestHandler = useCallback(\n (scrollRequest) => {\n const { current: scrollbarContainer } = contentContainerRef;\n if (scrollbarContainer) {\n contentContainerScrolledRef.current = false;\n if (scrollRequest.type === \"scroll-page\") {\n const { clientHeight, scrollLeft, scrollTop } = scrollbarContainer;\n const { direction } = scrollRequest;\n const scrollBy = direction === \"down\" ? clientHeight : -clientHeight;\n const newScrollTop = Math.min(\n Math.max(0, scrollTop + scrollBy),\n maxScrollTop\n );\n scrollbarContainer.scrollTo({\n top: newScrollTop,\n left: scrollLeft,\n behavior: \"auto\",\n });\n } else if (scrollRequest.type === \"scroll-end\") {\n const { direction } = scrollRequest;\n const scrollTo = direction === \"end\" ? maxScrollTop : 0;\n scrollbarContainer.scrollTo({\n top: scrollTo,\n left: scrollbarContainer.scrollLeft,\n behavior: \"auto\",\n });\n }\n }\n },\n [maxScrollTop]\n );\n\n return {\n /** Ref to be assigned to ScrollbarContainer */\n scrollbarContainerRef: scrollbarContainerCallbackRef,\n /** Ref to be assigned to ContentContainer */\n contentContainerRef: contentContainerCallbackRef,\n /** Scroll the table */\n requestScroll,\n };\n};\n", "/**\n * This hook measures and calculates the values needed to manage layout\n * and virtualisation of the table. This includes measurements required\n * to support pinned columns.\n */\nimport {\n KeyedColumnDescriptor,\n TableHeadings,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport { useCallback, useMemo, useRef } from \"react\";\nimport { MeasuredSize } from \"@vuu-ui/vuu-layout\";\nimport {\n actualRowPositioning,\n RowAtPositionFunc,\n RowOffsetFunc,\n RowPositioning,\n virtualRowPositioning,\n} from \"@vuu-ui/vuu-utils\";\n\nexport interface TableViewportHookProps {\n columns: KeyedColumnDescriptor[];\n headerHeight: number;\n headings: TableHeadings;\n rowCount: number;\n rowHeight: number;\n size: MeasuredSize | undefined;\n}\n\nexport interface ViewportMeasurements {\n contentHeight: number;\n horizontalScrollbarHeight: number;\n maxScrollContainerScrollHorizontal: number;\n maxScrollContainerScrollVertical: number;\n pinnedWidthLeft: number;\n pinnedWidthRight: number;\n rowCount: number;\n contentWidth: number;\n totalHeaderHeight: number;\n verticalScrollbarWidth: number;\n viewportBodyHeight: number;\n}\n\nexport interface TableViewportHookResult extends ViewportMeasurements {\n getRowAtPosition: RowAtPositionFunc;\n getRowOffset: RowOffsetFunc;\n setPctScrollTop: (scrollPct: number) => void;\n}\n\n// Too simplistic, it depends on rowHeight\nconst MAX_RAW_ROWS = 1_500_000;\n\nconst UNMEASURED_VIEWPORT: TableViewportHookResult = {\n contentHeight: 0,\n contentWidth: 0,\n getRowAtPosition: () => -1,\n getRowOffset: () => -1,\n horizontalScrollbarHeight: 0,\n maxScrollContainerScrollHorizontal: 0,\n maxScrollContainerScrollVertical: 0,\n pinnedWidthLeft: 0,\n pinnedWidthRight: 0,\n rowCount: 0,\n setPctScrollTop: () => undefined,\n totalHeaderHeight: 0,\n verticalScrollbarWidth: 0,\n viewportBodyHeight: 0,\n};\n\nconst measurePinnedColumns = (columns: KeyedColumnDescriptor[]) => {\n let pinnedWidthLeft = 0;\n let pinnedWidthRight = 0;\n let unpinnedWidth = 0;\n for (const column of columns) {\n const { hidden, pin, width } = column;\n const visibleWidth = hidden ? 0 : width;\n if (pin === \"left\") {\n pinnedWidthLeft += visibleWidth;\n } else if (pin === \"right\") {\n pinnedWidthRight += visibleWidth;\n } else {\n unpinnedWidth += visibleWidth;\n }\n }\n return {\n pinnedWidthLeft: pinnedWidthLeft + 4,\n pinnedWidthRight: pinnedWidthRight + 4,\n unpinnedWidth,\n };\n};\n\nexport const useTableViewport = ({\n columns,\n headerHeight,\n headings,\n rowCount,\n rowHeight,\n size,\n}: TableViewportHookProps): TableViewportHookResult => {\n const pctScrollTopRef = useRef(0);\n const appliedRowCount = Math.min(rowCount, MAX_RAW_ROWS);\n const appliedContentHeight = appliedRowCount * rowHeight;\n const virtualContentHeight = rowCount * rowHeight;\n const virtualisedExtent = virtualContentHeight - appliedContentHeight;\n\n const { pinnedWidthLeft, pinnedWidthRight, unpinnedWidth } = useMemo(\n () => measurePinnedColumns(columns),\n [columns]\n );\n\n const [actualRowOffset, actualRowAtPosition] = useMemo<RowPositioning>(\n () => actualRowPositioning(rowHeight),\n [rowHeight]\n );\n\n const [getRowOffset, getRowAtPosition] = useMemo<RowPositioning>(() => {\n if (virtualisedExtent) {\n return virtualRowPositioning(\n rowHeight,\n virtualisedExtent,\n pctScrollTopRef\n );\n } else {\n return [actualRowOffset, actualRowAtPosition];\n }\n }, [actualRowAtPosition, actualRowOffset, virtualisedExtent, rowHeight]);\n\n const setPctScrollTop = useCallback((scrollPct: number) => {\n pctScrollTopRef.current = scrollPct;\n }, []);\n\n return useMemo(() => {\n if (size) {\n const headingsDepth = headings.length;\n const scrollbarSize = 15;\n const contentWidth = pinnedWidthLeft + unpinnedWidth + pinnedWidthRight;\n const horizontalScrollbarHeight =\n contentWidth > size.width ? scrollbarSize : 0;\n const totalHeaderHeight = headerHeight * (1 + headingsDepth);\n const maxScrollContainerScrollVertical =\n appliedContentHeight -\n ((size?.height ?? 0) - horizontalScrollbarHeight) +\n totalHeaderHeight;\n const maxScrollContainerScrollHorizontal =\n contentWidth - size.width + pinnedWidthLeft;\n const visibleRows = (size.height - headerHeight) / rowHeight;\n const count = Number.isInteger(visibleRows)\n ? visibleRows + 1\n : Math.ceil(visibleRows);\n const viewportBodyHeight = size.height - totalHeaderHeight;\n const verticalScrollbarWidth =\n appliedContentHeight > viewportBodyHeight ? scrollbarSize : 0;\n\n return {\n contentHeight: appliedContentHeight,\n getRowAtPosition,\n getRowOffset,\n horizontalScrollbarHeight,\n maxScrollContainerScrollHorizontal,\n maxScrollContainerScrollVertical,\n pinnedWidthLeft,\n pinnedWidthRight,\n rowCount: count,\n contentWidth,\n setPctScrollTop,\n totalHeaderHeight,\n verticalScrollbarWidth,\n viewportBodyHeight,\n };\n } else {\n return UNMEASURED_VIEWPORT;\n }\n }, [\n size,\n headings.length,\n pinnedWidthLeft,\n unpinnedWidth,\n pinnedWidthRight,\n appliedContentHeight,\n headerHeight,\n rowHeight,\n getRowAtPosition,\n getRowOffset,\n setPctScrollTop,\n ]);\n};\n", "import { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n getColumnsInViewport,\n itemsChanged,\n RowAtPositionFunc,\n} from \"@vuu-ui/vuu-utils\";\nimport { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { ViewportMeasurements } from \"../table-next/useTableViewport\";\n\nexport interface VirtualViewportHookProps {\n columns: KeyedColumnDescriptor[];\n getRowAtPosition: RowAtPositionFunc;\n setRange: (range: VuuRange) => void;\n viewportMeasurements: ViewportMeasurements;\n}\nexport interface VirtualViewportHookResult {\n onHorizontalScroll: (scrollLeft: number) => void;\n onVerticalScroll: (scrollTop: number) => void;\n columnsWithinViewport: KeyedColumnDescriptor[];\n virtualColSpan: number;\n}\n\nexport const useVirtualViewport = ({\n columns,\n getRowAtPosition,\n setRange,\n viewportMeasurements,\n}: VirtualViewportHookProps): VirtualViewportHookResult => {\n const firstRowRef = useRef<number>(-1);\n const {\n rowCount: viewportRowCount,\n contentWidth,\n maxScrollContainerScrollHorizontal,\n } = viewportMeasurements;\n // double check this ...\n const availableWidth = contentWidth - maxScrollContainerScrollHorizontal;\n const scrollLeftRef = useRef(0);\n\n const [visibleColumns, preSpan] = useMemo(\n () =>\n getColumnsInViewport(\n columns,\n scrollLeftRef.current,\n scrollLeftRef.current + availableWidth\n ),\n [availableWidth, columns]\n );\n\n const preSpanRef = useRef(preSpan);\n\n useEffect(() => {\n setColumnsWithinViewport(visibleColumns);\n }, [visibleColumns]);\n\n const [columnsWithinViewport, setColumnsWithinViewport] =\n useState<KeyedColumnDescriptor[]>(visibleColumns);\n\n const handleHorizontalScroll = useCallback(\n (scrollLeft: number) => {\n scrollLeftRef.current = scrollLeft;\n const [visibleColumns, pre] = getColumnsInViewport(\n columns,\n scrollLeft,\n scrollLeft + availableWidth\n );\n if (itemsChanged(columnsWithinViewport, visibleColumns)) {\n preSpanRef.current = pre;\n\n setColumnsWithinViewport(visibleColumns);\n }\n },\n [availableWidth, columns, columnsWithinViewport]\n );\n\n const handleVerticalScroll = useCallback(\n (scrollTop: number) => {\n const firstRow = getRowAtPosition(scrollTop);\n if (firstRow !== firstRowRef.current) {\n firstRowRef.current = firstRow;\n console.log(\"setRange from handleVerticalScroll\");\n setRange({ from: firstRow, to: firstRow + viewportRowCount });\n }\n },\n [getRowAtPosition, setRange, viewportRowCount]\n );\n\n return {\n columnsWithinViewport,\n onHorizontalScroll: handleHorizontalScroll,\n onVerticalScroll: handleVerticalScroll,\n /** number of leading columns not rendered because of virtualization */\n virtualColSpan: preSpanRef.current,\n };\n};\n", "import { TableCellProps } from \"@vuu-ui/vuu-datagrid-types\";\nimport cx from \"classnames\";\nimport {\n isJsonAttribute,\n metadataKeys,\n registerComponent,\n} from \"@vuu-ui/vuu-utils\";\n\nimport \"./JsonCell.css\";\n\nconst classBase = \"vuuJsonCell\";\n\nconst { IS_EXPANDED, KEY } = metadataKeys;\n\nconst localKey = (key: string) => {\n const pos = key.lastIndexOf(\"|\");\n if (pos === -1) {\n return \"\";\n } else {\n return key.slice(pos + 1);\n }\n};\n\nconst JsonCell = ({ column, row }: TableCellProps) => {\n const { key: columnKey /*, type, valueFormatter */ } = column;\n let value = row[columnKey];\n let isToggle = false;\n if (isJsonAttribute(value)) {\n value = value.slice(0, -1);\n isToggle = true;\n }\n const rowKey = localKey(row[KEY]);\n const className = cx({\n [`${classBase}-name`]: rowKey === value,\n [`${classBase}-value`]: rowKey !== value,\n [`${classBase}-group`]: isToggle,\n });\n\n if (isToggle) {\n const toggleIcon = row[IS_EXPANDED] ? \"minus-box\" : \"plus-box\";\n return (\n <span className={className}>\n <span className={`${classBase}-value`}>{value}</span>\n <span className={`${classBase}-toggle`} data-icon={toggleIcon} />\n </span>\n );\n } else if (value) {\n return <span className={className}>{value}</span>;\n } else {\n return null;\n }\n};\n\nregisterComponent(\"json\", JsonCell, \"cell-renderer\", {\n description: \"JSON formatter\",\n label: \"JSON formatter\",\n serverDataType: \"json\",\n});\n", "import {\n GroupColumnDescriptor,\n KeyedColumnDescriptor,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport cx from \"classnames\";\nimport { useRef } from \"react\";\nimport { ColumnResizer, useTableColumnResize } from \"../column-resizing\";\nimport { HeaderCellProps } from \"./HeaderCell\";\nimport { useCell } from \"../useCell\";\nimport { ColumnHeaderPill, GroupColumnPill } from \"../column-header-pill\";\n\nimport \"./GroupHeaderCell.css\";\n\nconst classBase = \"vuuTableNextGroupHeaderCell\";\n\nexport interface GroupHeaderCellProps\n extends Omit<HeaderCellProps, \"onDragStart\" | \"onDrag\" | \"onDragEnd\"> {\n column: GroupColumnDescriptor;\n onRemoveColumn: (column: KeyedColumnDescriptor) => void;\n}\n\nexport const GroupHeaderCell = ({\n column: groupColumn,\n className: classNameProp,\n onRemoveColumn,\n onResize,\n ...htmlAttributes\n}: GroupHeaderCellProps) => {\n console.log({ groupColumn });\n const rootRef = useRef<HTMLTableCellElement>(null);\n const { isResizing, ...resizeProps } = useTableColumnResize({\n column: groupColumn,\n onResize,\n rootRef,\n });\n\n const { className, style } = useCell(groupColumn, classBase, true);\n\n const { columns } = groupColumn;\n\n const columnPillProps =\n columns.length > 1\n ? {\n removable: true,\n onRemove: onRemoveColumn,\n }\n : undefined;\n\n return (\n <div\n {...htmlAttributes}\n className={cx(className, \"vuuTableNextHeaderCell\", {\n [`${classBase}-pending`]: groupColumn.groupConfirmed === false,\n })}\n ref={rootRef}\n role=\"columnheader\"\n style={style}\n >\n <div className={`${classBase}-inner`}>\n {columns.map((column) => {\n return (\n <GroupColumnPill\n {...columnPillProps}\n column={column}\n key={column.key}\n />\n );\n })}\n <ColumnHeaderPill\n column={groupColumn}\n removable\n onRemove={onRemoveColumn}\n />\n {groupColumn.resizeable !== false ? (\n <ColumnResizer {...resizeProps} />\n ) : null}\n </div>\n </div>\n );\n};\n", "import { useCallback, useRef } from \"react\";\n\nimport \"./ColumnResizer.css\";\n\nconst NOOP = () => undefined;\n\nconst baseClass = \"vuuColumnResizerNext\";\nexport interface TableColumnResizerProps {\n onDrag: (evt: MouseEvent, moveBy: number) => void;\n onDragEnd: (evt: MouseEvent) => void;\n onDragStart: (evt: React.MouseEvent) => void;\n}\n\nexport const ColumnResizer = ({\n onDrag,\n onDragEnd = NOOP,\n onDragStart = NOOP,\n}: TableColumnResizerProps) => {\n const position = useRef(0);\n\n const onMouseMove = useCallback(\n (e: MouseEvent) => {\n if (e.stopPropagation) {\n e.stopPropagation();\n }\n\n if (e.preventDefault) {\n e.preventDefault();\n }\n\n const x = Math.round(e.clientX);\n const moveBy = x - position.current;\n position.current = x;\n\n if (moveBy !== 0) {\n onDrag(e, moveBy);\n }\n },\n [onDrag]\n );\n\n const onMouseUp = useCallback(\n (e: MouseEvent) => {\n window.removeEventListener(\"mouseup\", onMouseUp);\n window.removeEventListener(\"mousemove\", onMouseMove);\n onDragEnd(e);\n },\n [onDragEnd, onMouseMove]\n );\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n onDragStart(e);\n position.current = Math.round(e.clientX);\n\n window.addEventListener(\"mouseup\", onMouseUp);\n window.addEventListener(\"mousemove\", onMouseMove);\n\n if (e.stopPropagation) {\n e.stopPropagation();\n }\n\n if (e.preventDefault) {\n e.preventDefault();\n }\n },\n [onDragStart, onMouseMove, onMouseUp]\n );\n\n return <div className={baseClass} onMouseDown={handleMouseDown} />;\n};\n", "import { Heading, KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { RefObject, useCallback, useRef, useState } from \"react\";\nimport { ResizePhase } from \"../useTableModel\";\n\nexport type TableColumnResizeHandler = (\n phase: ResizePhase,\n columnName: string,\n width?: number\n) => void;\n\nexport type ResizeHandler = (evt: MouseEvent, moveBy: number) => void;\nexport interface CellResizeHookProps {\n column: KeyedColumnDescriptor | Heading;\n onResize?: (phase: ResizePhase, columnName: string, width?: number) => void;\n rootRef: RefObject<HTMLDivElement>;\n}\n\nexport interface CellResizeHookResult {\n isResizing: boolean;\n onDrag: (evt: MouseEvent, moveBy: number) => void;\n onDragStart: (evt: React.MouseEvent) => void;\n onDragEnd: (evt: MouseEvent) => void;\n}\n\nexport const useTableColumnResize = ({\n column,\n onResize,\n rootRef,\n}: CellResizeHookProps): CellResizeHookResult => {\n const widthRef = useRef(0);\n const [isResizing, setResizing] = useState(false);\n const { name } = column;\n\n const handleResizeStart = useCallback(() => {\n console.log(\"onResizeStart\");\n\n if (onResize && rootRef.current) {\n console.log(\"handleResizeStart\");\n const { width } = rootRef.current.getBoundingClientRect();\n widthRef.current = Math.round(width);\n setResizing(true);\n onResize?.(\"begin\", name);\n }\n }, [name, onResize, rootRef]);\n\n const handleResize = useCallback(\n (_evt: MouseEvent, moveBy: number) => {\n if (rootRef.current) {\n if (onResize) {\n const { width } = rootRef.current.getBoundingClientRect();\n const newWidth = Math.round(width) + moveBy;\n if (newWidth !== widthRef.current && newWidth > 0) {\n onResize(\"resize\", name, newWidth);\n widthRef.current = newWidth;\n }\n }\n }\n },\n [name, onResize, rootRef]\n );\n\n const handleResizeEnd = useCallback(() => {\n if (onResize) {\n onResize(\"end\", name, widthRef.current);\n setTimeout(() => {\n // clickHandler in HeaderCell checks isResizing before firing. Because onMouseUp\n // fires before click, we need to delay setting isResizing back to false, just\n // long enough that the click ghandler will have fired.\n setResizing(false);\n }, 80);\n }\n }, [name, onResize]);\n\n return {\n isResizing,\n onDrag: handleResize,\n onDragStart: handleResizeStart,\n onDragEnd: handleResizeEnd,\n };\n};\n", "import { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { getColumnStyle } from \"@vuu-ui/vuu-utils\";\nimport cx from \"classnames\";\nimport { useMemo } from \"react\";\n\nexport const useCell = (\n column: KeyedColumnDescriptor,\n classBase: string,\n isHeader?: boolean\n) =>\n // TODO measure perf without the memo, might not be worth the cost\n useMemo(() => {\n const className = cx(classBase, {\n vuuPinFloating: column.pin === \"floating\",\n vuuPinLeft: column.pin === \"left\",\n vuuPinRight: column.pin === \"right\",\n vuuEndPin: isHeader && column.endPin,\n // [`${classBase}-resizing`]: column.resizing,\n [`${classBase}-editable`]: column.editable,\n [`${classBase}-right`]: column.align === \"right\",\n });\n\n const style = getColumnStyle(column);\n return {\n className,\n style,\n };\n }, [column, classBase, isHeader]);\n", "import cx from \"classnames\";\nimport { KeyedColumnDescriptor } from \"packages/vuu-datagrid-types\";\nimport { HTMLAttributes, MouseEvent, useCallback } from \"react\";\n\nimport \"./ColumnHeaderPill.css\";\n\nexport interface ColumnHeaderPillProps extends HTMLAttributes<HTMLDivElement> {\n column: KeyedColumnDescriptor;\n removable?: boolean;\n onRemove?: (column: KeyedColumnDescriptor) => void;\n}\n\nconst classBase = \"vuuColumnHeaderPill\";\n\nexport const ColumnHeaderPill = ({\n children,\n className,\n column,\n onRemove,\n removable,\n ...htmlAttributes\n}: ColumnHeaderPillProps) => {\n if (removable && typeof onRemove !== \"function\") {\n throw Error(\n \"ColumnHeaderPill onRemove prop must be provided if Pill is removable\"\n );\n }\n\n const handleClickRemove = useCallback(\n (evt: MouseEvent<HTMLSpanElement>) => {\n evt.preventDefault();\n evt.stopPropagation();\n onRemove?.(column);\n },\n [column, onRemove]\n );\n\n return (\n <div {...htmlAttributes} className={cx(classBase, className)}>\n {children}\n {removable ? (\n <span\n className={`${classBase}-removeButton`}\n role=\"button\"\n data-icon=\"cross\"\n onClick={handleClickRemove}\n />\n ) : null}\n </div>\n );\n};\n", "import { KeyedColumnDescriptor } from \"packages/vuu-datagrid-types\";\nimport { ColumnHeaderPill, ColumnHeaderPillProps } from \"./ColumnHeaderPill\";\n\nimport \"./GroupColumnPill.css\";\n\nexport interface GroupColumnPillProps extends ColumnHeaderPillProps {\n column: KeyedColumnDescriptor;\n}\n\nexport const GroupColumnPill = ({\n column,\n ...columnHeaderProps\n}: GroupColumnPillProps) => {\n const { name, sorted } = column;\n const icon =\n typeof sorted === \"number\"\n ? sorted < 0\n ? \"arrow-down\"\n : \"arrow-up\"\n : sorted === \"A\"\n ? \"arrow-up\"\n : sorted === \"D\"\n ? \"arrow-down\"\n : undefined;\n\n return (\n <ColumnHeaderPill {...columnHeaderProps} column={column}>\n <span className=\"vuuGroupColumnPill-label\">{name}</span>\n {icon !== undefined ? <span data-icon={icon} /> : null}\n {typeof sorted === \"number\" ? (\n <span className={\"vuuSortPosition\"}>{Math.abs(sorted)}</span>\n ) : null}\n </ColumnHeaderPill>\n );\n};\n", "import { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { ColumnHeaderPill } from \"./ColumnHeaderPill\";\n\nimport \"./SortIndicator.css\";\n\nexport interface SortIndicatorProps {\n column: KeyedColumnDescriptor;\n}\n\nexport const SortIndicator = ({ column }: SortIndicatorProps) => {\n if (!column.sorted) {\n return null;\n }\n\n const icon =\n typeof column.sorted === \"number\"\n ? column.sorted < 0\n ? \"arrow-down\"\n : \"arrow-up\"\n : column.sorted === \"A\"\n ? \"arrow-up\"\n : \"arrow-down\";\n\n return (\n <ColumnHeaderPill column={column}>\n <span data-icon={icon} />\n {typeof column.sorted === \"number\" ? (\n <span className={\"vuuSortPosition\"}>{Math.abs(column.sorted)}</span>\n ) : null}\n </ColumnHeaderPill>\n );\n};\n", "import {\n GroupColumnDescriptor,\n KeyedColumnDescriptor,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport cx from \"classnames\";\nimport { useCallback, useRef, useState } from \"react\";\nimport { ColumnResizer, useTableColumnResize } from \"../column-resizing\";\nimport { HeaderCellProps } from \"./HeaderCell\";\nimport { useCell } from \"../useCell\";\nimport { ColumnHeaderPill, GroupColumnPill } from \"../column-header-pill\";\nimport {\n OverflowContainer,\n useLayoutEffectSkipFirst,\n} from \"@vuu-ui/vuu-layout\";\n\nimport \"./GroupHeaderCell.css\";\n\nconst classBase = \"vuuTableNextGroupHeaderCell\";\n\nconst switchIfChanged = (\n columns: KeyedColumnDescriptor[],\n newColumns: KeyedColumnDescriptor[]\n) => {\n if (columns === newColumns) {\n return columns;\n } else {\n return newColumns;\n }\n};\n\nexport interface GroupHeaderCellNextProps\n extends Omit<HeaderCellProps, \"onDragStart\" | \"onDrag\" | \"onDragEnd\"> {\n column: GroupColumnDescriptor;\n onRemoveColumn: (column: KeyedColumnDescriptor) => void;\n}\n\nexport const GroupHeaderCellNext = ({\n column: groupColumn,\n className: classNameProp,\n onRemoveColumn,\n onResize,\n ...htmlAttributes\n}: GroupHeaderCellNextProps) => {\n const rootRef = useRef<HTMLTableCellElement>(null);\n const { isResizing, ...resizeProps } = useTableColumnResize({\n column: groupColumn,\n onResize,\n rootRef,\n });\n\n const [columns, setColumns] = useState(groupColumn.columns);\n const { className, style } = useCell(groupColumn, classBase, true);\n const columnPillProps =\n columns.length > 1\n ? {\n removable: true,\n onRemove: onRemoveColumn,\n }\n : undefined;\n\n const handleMoveItem = useCallback((fromIndex, toIndex) => {\n setColumns((cols) => {\n const newCols = cols.slice();\n const [tab] = newCols.splice(fromIndex, 1);\n if (toIndex === -1) {\n return newCols.concat(tab);\n } else {\n newCols.splice(toIndex, 0, tab);\n return newCols;\n }\n });\n }, []);\n\n useLayoutEffectSkipFirst(() => {\n setColumns((cols) => switchIfChanged(cols, groupColumn.columns));\n }, [groupColumn.columns]);\n\n return (\n <div\n {...htmlAttributes}\n className={cx(className, \"vuuTableNextHeaderCell\", classNameProp, {\n [`${classBase}-pending`]: groupColumn.groupConfirmed === false,\n })}\n ref={rootRef}\n role=\"columnheader\"\n style={style}\n >\n <OverflowContainer\n allowDragDrop\n className={`${classBase}-inner`}\n height={24}\n onMoveItem={handleMoveItem}\n overflowPosition=\"start\"\n >\n {columns.map((column) => {\n return (\n <GroupColumnPill\n {...columnPillProps}\n column={column}\n key={column.key}\n />\n );\n })}\n </OverflowContainer>\n <ColumnHeaderPill\n column={groupColumn}\n removable\n onRemove={onRemoveColumn}\n />\n\n {groupColumn.resizeable !== false ? (\n <ColumnResizer {...resizeProps} />\n ) : null}\n </div>\n );\n};\n", "import { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { HTMLAttributes, MouseEvent, useCallback, useRef } from \"react\";\nimport { useCell } from \"../useCell\";\nimport { ColumnMenu } from \"../column-menu\";\nimport { SortIndicator } from \"../column-header-pill\";\nimport cx from \"classnames\";\nimport {\n ColumnResizer,\n TableColumnResizeHandler,\n useTableColumnResize,\n} from \"../column-resizing\";\n\nimport \"./HeaderCell.css\";\n\nconst classBase = \"vuuTableNextHeaderCell\";\n\nexport interface HeaderCellProps extends HTMLAttributes<HTMLDivElement> {\n classBase?: string;\n column: KeyedColumnDescriptor;\n onResize?: TableColumnResizeHandler;\n}\n\nexport const HeaderCell = ({\n className: classNameProp,\n column,\n onClick,\n onResize,\n ...htmlAttributes\n}: HeaderCellProps) => {\n const rootRef = useRef<HTMLDivElement>(null);\n const { isResizing, ...resizeProps } = useTableColumnResize({\n column,\n onResize,\n rootRef,\n });\n\n const handleClick = useCallback(\n (evt: MouseEvent<HTMLTableCellElement>) => {\n console.log(`click isResizing ${isResizing}`);\n !isResizing && onClick?.(evt);\n },\n [isResizing, onClick]\n );\n\n const { className, style } = useCell(column, classBase, true);\n\n const columnMenu = <ColumnMenu column={column} />;\n const columnLabel = (\n <div className={`${classBase}-label`}>{column.label ?? column.name}</div>\n );\n const sortIndicator = <SortIndicator column={column} />;\n const headerItems =\n column.align === \"right\"\n ? [sortIndicator, columnLabel, columnMenu]\n : [columnMenu, columnLabel, sortIndicator];\n\n return (\n <div\n {...htmlAttributes}\n className={cx(className, classNameProp, {\n [`${classBase}-resizing`]: isResizing,\n })}\n onClick={handleClick}\n ref={rootRef}\n role=\"columnheader\"\n style={style}\n >\n {...headerItems}\n {column.resizeable !== false ? <ColumnResizer {...resizeProps} /> : null}\n </div>\n );\n};\n", "import { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { useContextMenu } from \"@vuu-ui/vuu-popups\";\nimport cx from \"classnames\";\nimport {\n HTMLAttributes,\n MouseEvent,\n useCallback,\n useRef,\n useState,\n} from \"react\";\n\nimport \"./ColumnMenu.css\";\n\nexport interface ColumnMenuProps extends HTMLAttributes<HTMLSpanElement> {\n column: KeyedColumnDescriptor;\n}\n\nconst getPosition = (element: HTMLElement | null) => {\n if (element) {\n const { bottom, left } = element.getBoundingClientRect();\n return { x: left, y: bottom + 6 };\n }\n};\n\nexport const ColumnMenu = ({\n className,\n column,\n ...props\n}: ColumnMenuProps) => {\n const rootRef = useRef<HTMLSpanElement>(null);\n const [menuOpen, setMenuOpen] = useState(false);\n const [showContextMenu] = useContextMenu();\n\n const handleMenuClose = useCallback(() => {\n setMenuOpen(false);\n }, []);\n\n const showColumnMenu = useCallback(\n (e: MouseEvent<HTMLElement>) => {\n setMenuOpen(true);\n showContextMenu(e, \"column-menu\", {\n column,\n ContextMenuProps: {\n className: \"vuuColumnMenuList\",\n onClose: handleMenuClose,\n position: getPosition(rootRef.current),\n },\n });\n },\n [column, handleMenuClose, showContextMenu]\n );\n\n return (\n <span\n {...props}\n className={cx(\"vuuTable-columnMenu\", className, {\n \"vuuTable-columnMenu-open\": menuOpen,\n })}\n data-icon=\"more-vert\"\n onClick={showColumnMenu}\n ref={rootRef}\n />\n );\n};\n", "import { ContextMenuProvider } from \"@vuu-ui/vuu-popups\";\nimport { TableProps } from \"@vuu-ui/vuu-table\";\nimport { isGroupColumn, metadataKeys, notHidden } from \"@vuu-ui/vuu-utils\";\nimport cx from \"classnames\";\nimport { CSSProperties, useEffect, useRef } from \"react\";\nimport {\n GroupHeaderCellNext as GroupHeaderCell,\n HeaderCell,\n} from \"./header-cell\";\nimport { Row as DefaultRow } from \"./Row\";\nimport { useTable } from \"./useTableNext\";\nimport { MeasuredContainer, useId } from \"@vuu-ui/vuu-layout\";\n\nimport \"./TableNext.css\";\n\nconst classBase = \"vuuTableNext\";\n\nconst { IDX, RENDER_IDX } = metadataKeys;\n\nexport const TableNext = ({\n Row = DefaultRow,\n availableColumns,\n className: classNameProp,\n config,\n dataSource,\n id: idProp,\n onAvailableColumnsChange,\n onConfigChange,\n onFeatureEnabled,\n onFeatureInvocation,\n onRowClick: onRowClickProp,\n onSelectionChange,\n onShowConfigEditor: onShowSettings,\n renderBufferSize = 0,\n rowHeight = 20,\n selectionModel = \"extended\",\n showColumnHeaders = true,\n headerHeight = showColumnHeaders ? 25 : 0,\n style: styleProp,\n ...htmlAttributes\n}: TableProps) => {\n const id = useId(idProp);\n const containerRef = useRef<HTMLDivElement>(null);\n const {\n columnMap,\n columns,\n data,\n dragDropHook,\n handleContextMenuAction,\n headerProps,\n onDataEdited,\n onRemoveGroupColumn,\n onResize,\n onRowClick,\n onToggleGroup,\n menuBuilder,\n scrollProps,\n tableAttributes,\n viewportMeasurements,\n ...tableProps\n } = useTable({\n availableColumns,\n config,\n containerRef,\n dataSource,\n headerHeight,\n onAvailableColumnsChange,\n onConfigChange,\n onFeatureEnabled,\n onFeatureInvocation,\n onRowClick: onRowClickProp,\n onSelectionChange,\n renderBufferSize,\n rowHeight,\n selectionModel,\n });\n\n const getStyle = () => {\n return {\n ...styleProp,\n \"--content-height\": `${viewportMeasurements.contentHeight}px`,\n \"--horizontal-scrollbar-height\": `${viewportMeasurements.horizontalScrollbarHeight}px`,\n \"--content-width\": `${viewportMeasurements.contentWidth}px`,\n \"--pinned-width-left\": `${viewportMeasurements.pinnedWidthLeft}px`,\n \"--pinned-width-right\": `${viewportMeasurements.pinnedWidthRight}px`,\n \"--header-height\": `${headerHeight}px`,\n \"--row-height\": `${rowHeight}px`,\n \"--total-header-height\": `${viewportMeasurements.totalHeaderHeight}px`,\n \"--vertical-scrollbar-width\": `${viewportMeasurements.verticalScrollbarWidth}px`,\n \"--viewport-body-height\": `${viewportMeasurements.viewportBodyHeight}px`,\n } as CSSProperties;\n };\n const className = cx(classBase, classNameProp, {\n [`${classBase}-colLines`]: tableAttributes.columnSeparators,\n [`${classBase}-rowLines`]: tableAttributes.rowSeparators,\n [`${classBase}-zebra`]: tableAttributes.zebraStripes,\n // [`${classBase}-loading`]: isDataLoading(tableProps.columns),\n });\n\n return (\n <ContextMenuProvider\n menuActionHandler={handleContextMenuAction}\n menuBuilder={menuBuilder}\n >\n <MeasuredContainer\n {...htmlAttributes}\n className={className}\n onResize={onResize}\n ref={containerRef}\n style={getStyle()}\n >\n <div\n className={`${classBase}-scrollbarContainer`}\n ref={scrollProps.scrollbarContainerRef}\n >\n <div className={`${classBase}-scrollbarContent`} />\n </div>\n <div\n className={`${classBase}-contentContainer`}\n ref={scrollProps.contentContainerRef}\n >\n <div {...tableProps} className={`${classBase}-table`} tabIndex={-1}>\n {showColumnHeaders ? (\n <div className={`${classBase}-col-headings`}>\n <div className={`${classBase}-col-headers`} role=\"row\">\n {columns.filter(notHidden).map((col, i) =>\n isGroupColumn(col) ? (\n <GroupHeaderCell\n {...headerProps}\n column={col}\n data-index={i}\n key={col.name}\n onRemoveColumn={onRemoveGroupColumn}\n />\n ) : (\n <HeaderCell\n {...headerProps}\n className={cx({\n \"vuuDraggable-dragAway\":\n i === dragDropHook.draggedItemIndex,\n })}\n column={col}\n data-index={i}\n id={`${id}-col-${i}`}\n key={col.name}\n />\n )\n )}\n {dragDropHook.draggable}\n </div>\n </div>\n ) : null}\n <div className={`${classBase}-body`}>\n {data.map((data) => (\n <Row\n columnMap={columnMap}\n columns={columns}\n key={data[RENDER_IDX]}\n onClick={onRowClick}\n onDataEdited={onDataEdited}\n row={data}\n offset={rowHeight * data[IDX] + headerHeight}\n onToggleGroup={onToggleGroup}\n zebraStripes={tableAttributes.zebraStripes}\n />\n ))}\n </div>\n </div>\n </div>\n </MeasuredContainer>\n </ContextMenuProvider>\n );\n};\n", "import { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\nimport {\n DataCellEditHandler,\n KeyedColumnDescriptor,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport { RowClickHandler } from \"@vuu-ui/vuu-table\";\nimport {\n ColumnMap,\n isGroupColumn,\n isJsonColumn,\n isJsonGroup,\n metadataKeys,\n notHidden,\n RowSelected,\n} from \"@vuu-ui/vuu-utils\";\nimport cx from \"classnames\";\nimport { CSSProperties, memo, MouseEvent, useCallback } from \"react\";\nimport { TableCell, TableGroupCell } from \"./table-cell\";\n\nimport \"./Row.css\";\n\nexport interface RowProps {\n className?: string;\n columnMap: ColumnMap;\n columns: KeyedColumnDescriptor[];\n row: DataSourceRow;\n offset: number;\n onClick?: RowClickHandler;\n onDataEdited?: DataCellEditHandler;\n onToggleGroup?: (row: DataSourceRow, column: KeyedColumnDescriptor) => void;\n style?: CSSProperties;\n zebraStripes?: boolean;\n}\n\nconst { IDX, IS_EXPANDED, SELECTED } = metadataKeys;\nconst classBase = \"vuuTableNextRow\";\n\n// export const Row = memo(\nexport const Row = memo(\n ({\n className: classNameProp,\n columnMap,\n columns,\n row,\n offset,\n onClick,\n onDataEdited,\n onToggleGroup,\n zebraStripes = false,\n ...htmlAttributes\n }: RowProps) => {\n const {\n [IDX]: rowIndex,\n [IS_EXPANDED]: isExpanded,\n [SELECTED]: selectionStatus,\n } = row;\n\n const handleRowClick = useCallback(\n (evt: MouseEvent<HTMLDivElement>) => {\n const rangeSelect = evt.shiftKey;\n const keepExistingSelection = evt.ctrlKey || evt.metaKey; /* mac only */\n onClick?.(row, rangeSelect, keepExistingSelection);\n },\n [onClick, row]\n );\n\n const { True, First, Last } = RowSelected;\n\n const className = cx(classBase, classNameProp, {\n [`${classBase}-even`]: zebraStripes && rowIndex % 2 === 0,\n [`${classBase}-expanded`]: isExpanded,\n [`${classBase}-selected`]: selectionStatus & True,\n [`${classBase}-selectedStart`]: selectionStatus & First,\n [`${classBase}-selectedEnd`]: selectionStatus & Last,\n });\n\n const style = { transform: `translate3d(0px, ${offset}px, 0px)` };\n\n const handleGroupCellClick = useCallback(\n (evt: MouseEvent, column: KeyedColumnDescriptor) => {\n if (isGroupColumn(column) || isJsonGroup(column, row)) {\n evt.stopPropagation();\n onToggleGroup?.(row, column);\n }\n },\n [onToggleGroup, row]\n );\n\n return (\n <div\n {...htmlAttributes}\n aria-rowindex={row[0]}\n key={`row-${row[0]}`}\n role=\"row\"\n className={className}\n onClick={handleRowClick}\n style={style}\n >\n <span className={`${classBase}-selectionDecorator vuuStickyLeft`} />\n {columns.filter(notHidden).map((column) => {\n const isGroup = isGroupColumn(column);\n const isJsonCell = isJsonColumn(column);\n\n const Cell = isGroup ? TableGroupCell : TableCell;\n\n return (\n <Cell\n column={column}\n columnMap={columnMap}\n key={column.key}\n onClick={isGroup || isJsonCell ? handleGroupCellClick : undefined}\n onDataEdited={onDataEdited}\n row={row}\n />\n );\n })}\n <span className={`${classBase}-selectionDecorator vuuStickyRight`} />\n </div>\n );\n }\n);\nRow.displayName = \"Row\";\n", "import { TableCellProps } from \"@vuu-ui/vuu-datagrid-types\";\nimport { metadataKeys } from \"@vuu-ui/vuu-utils\";\nimport { VuuColumnDataType } from \"packages/vuu-protocol-types\";\nimport { useCallback } from \"react\";\nimport { useCell } from \"../useCell\";\n\nimport \"./TableCell.css\";\n\nconst { IDX } = metadataKeys;\nconst classBase = \"vuuTableNextCell\";\n\nexport const TableCell = ({\n column,\n columnMap,\n onDataEdited,\n row,\n}: TableCellProps) => {\n const { className, style } = useCell(column, classBase);\n const { CellRenderer, name, valueFormatter } = column;\n const dataIdx = columnMap[name];\n\n const handleDataItemEdited = useCallback(\n (value: VuuColumnDataType) => {\n onDataEdited?.(row[IDX], name, value);\n // TODO will only return false in case of server rejection\n return true;\n },\n [name, onDataEdited, row]\n );\n\n return (\n <div className={className} role=\"cell\" style={style}>\n {CellRenderer ? (\n <CellRenderer\n column={column}\n columnMap={columnMap}\n onCommit={handleDataItemEdited}\n row={row}\n />\n ) : (\n valueFormatter(row[dataIdx])\n )}\n </div>\n );\n};\n", "import {\n GroupColumnDescriptor,\n TableCellProps,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport { getGroupValueAndOffset, metadataKeys } from \"@vuu-ui/vuu-utils\";\nimport { MouseEvent, useCallback } from \"react\";\nimport { useCell } from \"../useCell\";\nimport cx from \"classnames\";\n\nimport \"./TableGroupCell.css\";\n\nconst { IS_LEAF } = metadataKeys;\n\nconst classBase = \"vuuTableNextGroupCell\";\n\nexport const TableGroupCell = ({ column, onClick, row }: TableCellProps) => {\n const { columns } = column as GroupColumnDescriptor;\n const [value, offset] = getGroupValueAndOffset(columns, row);\n const { className, style } = useCell(column, classBase);\n\n const handleClick = useCallback(\n (evt: MouseEvent<HTMLDivElement>) => {\n onClick?.(evt, column);\n },\n [column, onClick]\n );\n\n const isLeaf = row[IS_LEAF];\n const spacers = Array(offset)\n .fill(0)\n .map((n, i) => <span className={`${classBase}-spacer`} key={i} />);\n\n return (\n <div\n className={cx(className, \"vuuTableNextCell\")}\n role=\"cell\"\n style={style}\n onClick={isLeaf ? undefined : handleClick}\n >\n {spacers}\n {isLeaf ? null : (\n <span className={`${classBase}-toggle`} data-icon=\"triangle-right\" />\n )}\n <span>{value}</span>\n </div>\n );\n};\n", "import {\n DataSourceConfig,\n DataSourceSubscribedMessage,\n JsonDataSource,\n} from \"@vuu-ui/vuu-data\";\nimport { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\nimport {\n ColumnDescriptor,\n DataCellEditHandler,\n KeyedColumnDescriptor,\n SelectionChangeHandler,\n TableConfig,\n TableSelectionModel,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport { MeasuredSize, useLayoutEffectSkipFirst } from \"@vuu-ui/vuu-layout\";\nimport { VuuRange, VuuSortType } from \"@vuu-ui/vuu-protocol-types\";\nimport { useTableAndColumnSettings } from \"@vuu-ui/vuu-table-extras\";\nimport { useDragDropNext as useDragDrop } from \"@vuu-ui/vuu-ui-controls\";\nimport { useKeyboardNavigation } from \"./useKeyboardNavigation\";\nimport {\n applySort,\n buildColumnMap,\n isGroupColumn,\n isJsonGroup,\n isValidNumber,\n metadataKeys,\n updateColumn,\n visibleColumnAtIndex,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n KeyboardEvent,\n MouseEvent,\n RefObject,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport {\n buildContextMenuDescriptors,\n MeasuredProps,\n RowClickHandler,\n TableProps,\n useSelection,\n useTableContextMenu,\n} from \"../table\";\nimport { TableColumnResizeHandler } from \"./column-resizing\";\nimport { updateTableConfig } from \"./table-config\";\nimport { useDataSource } from \"./useDataSource\";\nimport { useInitialValue } from \"./useInitialValue\";\nimport { useTableContextMenu as useTableContextMenuNext } from \"./useTableContextMenu\";\nimport { useCellEditing } from \"./useCellEditing\";\nimport {\n isShowColumnSettings,\n isShowTableSettings,\n PersistentColumnAction,\n useTableModel,\n} from \"./useTableModel\";\nimport { useTableScroll } from \"./useTableScroll\";\nimport { useVirtualViewport } from \"./useVirtualViewport\";\nimport { useTableViewport } from \"./useTableViewport\";\n\nexport interface TableHookProps\n extends MeasuredProps,\n Pick<\n TableProps,\n | \"availableColumns\"\n | \"config\"\n | \"dataSource\"\n | \"onAvailableColumnsChange\"\n | \"onConfigChange\"\n | \"onFeatureEnabled\"\n | \"onFeatureInvocation\"\n | \"onSelectionChange\"\n | \"onRowClick\"\n | \"renderBufferSize\"\n > {\n containerRef: RefObject<HTMLDivElement>;\n headerHeight: number;\n rowHeight: number;\n selectionModel: TableSelectionModel;\n}\n\nconst { KEY, IS_EXPANDED, IS_LEAF } = metadataKeys;\n\nconst addColumn = (\n tableConfig: TableConfig,\n column: ColumnDescriptor\n): TableConfig => ({\n ...tableConfig,\n columns: tableConfig.columns.concat(column),\n});\n\nexport const useTable = ({\n availableColumns,\n config,\n containerRef,\n dataSource,\n headerHeight = 25,\n onAvailableColumnsChange,\n onConfigChange,\n onFeatureEnabled,\n onFeatureInvocation,\n onRowClick: onRowClickProp,\n onSelectionChange,\n renderBufferSize = 0,\n rowHeight = 20,\n selectionModel,\n}: TableHookProps) => {\n const [rowCount, setRowCount] = useState<number>(dataSource.size);\n if (dataSource === undefined) {\n throw Error(\"no data source provided to Vuu Table\");\n }\n\n const [size, setSize] = useState<MeasuredSize | undefined>();\n const handleResize = useCallback((size: MeasuredSize) => {\n setSize(size);\n }, []);\n\n const menuBuilder = useMemo(\n () => buildContextMenuDescriptors(dataSource),\n [dataSource]\n );\n\n const onDataRowcountChange = useCallback((size: number) => {\n setRowCount(size);\n }, []);\n\n const {\n columns: modelColumns,\n dispatchColumnAction,\n headings,\n tableAttributes,\n tableConfig,\n } = useTableModel(config, dataSource.config);\n\n useLayoutEffectSkipFirst(() => {\n dispatchColumnAction({\n type: \"init\",\n dataSourceConfig: dataSource.config,\n tableConfig,\n });\n }, [tableConfig, dataSource.config, dispatchColumnAction]);\n\n const [stateColumns, setStateColumns] = useState<KeyedColumnDescriptor[]>();\n const [columns, setColumnSize] = useMemo(() => {\n const setSize = (columnName: string, width: number) => {\n const cols = updateColumn(modelColumns, columnName, { width });\n setStateColumns(cols);\n };\n return [stateColumns ?? modelColumns, setSize];\n }, [modelColumns, stateColumns]);\n\n const columnMap = useMemo(\n () => buildColumnMap(dataSource.columns),\n [dataSource.columns]\n );\n\n const {\n getRowAtPosition,\n getRowOffset,\n setPctScrollTop,\n ...viewportMeasurements\n } = useTableViewport({\n columns,\n headerHeight,\n headings,\n rowCount,\n rowHeight,\n size,\n });\n\n const initialRange = useInitialValue<VuuRange>({\n from: 0,\n to: viewportMeasurements.rowCount,\n });\n\n const onSubscribed = useCallback(\n ({ tableSchema }: DataSourceSubscribedMessage) => {\n if (tableSchema) {\n // expectConfigChangeRef.current = true;\n // dispatchColumnAction({\n // type: \"setTableSchema\",\n // tableSchema,\n // });\n } else {\n console.log(\"usbscription message with no schema\");\n }\n },\n []\n );\n\n const { data, range, setRange } = useDataSource({\n dataSource,\n onFeatureEnabled,\n onFeatureInvocation,\n renderBufferSize,\n onSizeChange: onDataRowcountChange,\n onSubscribed,\n range: initialRange,\n });\n\n const handleConfigChanged = useCallback(\n (tableConfig: TableConfig) => {\n console.log(`useTableNext handleConfigChanged`, {\n tableConfig,\n });\n dispatchColumnAction({\n type: \"init\",\n tableConfig,\n dataSourceConfig: dataSource.config,\n });\n onConfigChange?.(tableConfig);\n },\n [dataSource.config, dispatchColumnAction, onConfigChange]\n );\n\n const handleDataSourceConfigChanged = useCallback(\n (dataSourceConfig: DataSourceConfig) => {\n console.log(\"config changed\", {\n dataSourceConfig,\n });\n dataSource.config = {\n ...dataSource.config,\n ...dataSourceConfig,\n };\n },\n [dataSource]\n );\n\n const handleCreateCalculatedColumn = useCallback(\n (column: ColumnDescriptor) => {\n console.log(`useTableNext handleCreateCalculatedColumn`, {\n column,\n });\n dataSource.columns = dataSource.columns.concat(column.name);\n const newTableConfig = addColumn(tableConfig, column);\n dispatchColumnAction({\n type: \"init\",\n tableConfig: newTableConfig,\n dataSourceConfig: dataSource.config,\n });\n onConfigChange?.(newTableConfig);\n },\n [dataSource, dispatchColumnAction, onConfigChange, tableConfig]\n );\n\n useEffect(() => {\n dataSource.on(\"config\", (config, confirmed) => {\n // expectConfigChangeRef.current = true;\n dispatchColumnAction({\n type: \"tableConfig\",\n ...config,\n confirmed,\n });\n });\n }, [dataSource, dispatchColumnAction]);\n\n const { showColumnSettingsPanel, showTableSettingsPanel } =\n useTableAndColumnSettings({\n availableColumns:\n availableColumns ??\n tableConfig.columns.map(({ name, serverDataType = \"string\" }) => ({\n name,\n serverDataType,\n })),\n onAvailableColumnsChange,\n onConfigChange: handleConfigChanged,\n onCreateCalculatedColumn: handleCreateCalculatedColumn,\n onDataSourceConfigChange: handleDataSourceConfigChanged,\n tableConfig,\n });\n\n const onPersistentColumnOperation = useCallback(\n (action: PersistentColumnAction) => {\n if (isShowColumnSettings(action)) {\n showColumnSettingsPanel(action);\n } else if (isShowTableSettings(action)) {\n showTableSettingsPanel();\n } else {\n // expectConfigChangeRef.current = true;\n dispatchColumnAction(action);\n }\n },\n [dispatchColumnAction, showColumnSettingsPanel, showTableSettingsPanel]\n );\n\n const handleContextMenuAction = useTableContextMenu({\n dataSource,\n onPersistentColumnOperation,\n });\n\n const handleSort = useCallback(\n (\n column: KeyedColumnDescriptor,\n extendSort = false,\n sortType?: VuuSortType\n ) => {\n if (dataSource) {\n dataSource.sort = applySort(\n dataSource.sort,\n column,\n extendSort,\n sortType\n );\n }\n },\n [dataSource]\n );\n\n const onHeaderResize: TableColumnResizeHandler = useCallback(\n (phase, columnName, width) => {\n const column = columns.find((column) => column.name === columnName);\n if (column) {\n if (phase === \"resize\") {\n if (isValidNumber(width)) {\n setColumnSize(columnName, width);\n }\n } else if (phase === \"end\") {\n if (isValidNumber(width)) {\n dispatchColumnAction({\n type: \"resizeColumn\",\n phase,\n column,\n width,\n });\n onConfigChange?.(\n updateTableConfig(tableConfig, {\n type: \"col-size\",\n column,\n width,\n })\n );\n }\n } else {\n setStateColumns(undefined);\n dispatchColumnAction({\n type: \"resizeColumn\",\n phase,\n column,\n width,\n });\n }\n } else {\n throw Error(\n `useDataTable.handleColumnResize, column ${columnName} not found`\n );\n }\n },\n [columns, tableConfig, dispatchColumnAction, onConfigChange, setColumnSize]\n );\n\n const onToggleGroup = useCallback(\n (row: DataSourceRow, column: KeyedColumnDescriptor) => {\n const isJson = isJsonGroup(column, row);\n const key = row[KEY];\n\n if (row[IS_EXPANDED]) {\n (dataSource as JsonDataSource).closeTreeNode(key, true);\n if (isJson) {\n const idx = columns.indexOf(column);\n const rows = (dataSource as JsonDataSource).getRowsAtDepth(idx + 1);\n if (!rows.some((row) => row[IS_EXPANDED] || row[IS_LEAF])) {\n dispatchColumnAction({\n type: \"hideColumns\",\n columns: columns.slice(idx + 2),\n });\n }\n }\n } else {\n dataSource.openTreeNode(key);\n if (isJson) {\n const childRows = (dataSource as JsonDataSource).getChildRows(key);\n const idx = columns.indexOf(column) + 1;\n const columnsToShow = [columns[idx]];\n if (childRows.some((row) => row[IS_LEAF])) {\n columnsToShow.push(columns[idx + 1]);\n }\n if (columnsToShow.some((col) => col.hidden)) {\n dispatchColumnAction({\n type: \"showColumns\",\n columns: columnsToShow,\n });\n }\n }\n }\n },\n [columns, dataSource, dispatchColumnAction]\n );\n\n const { onVerticalScroll } = useVirtualViewport({\n columns,\n getRowAtPosition,\n setRange,\n viewportMeasurements,\n });\n\n const handleVerticalScroll = useCallback(\n (scrollTop: number) => {\n onVerticalScroll(scrollTop);\n },\n [onVerticalScroll]\n );\n\n const { requestScroll, ...scrollProps } = useTableScroll({\n maxScrollLeft: viewportMeasurements.maxScrollContainerScrollHorizontal,\n maxScrollTop: viewportMeasurements.maxScrollContainerScrollVertical,\n rowHeight,\n onVerticalScroll: handleVerticalScroll,\n viewportRowCount: viewportMeasurements.rowCount,\n });\n\n const {\n navigate,\n onKeyDown: navigationKeyDown,\n ...containerProps\n } = useKeyboardNavigation({\n columnCount: columns.filter((c) => c.hidden !== true).length,\n containerRef,\n requestScroll,\n rowCount: dataSource?.size,\n viewportRange: range,\n viewportRowCount: viewportMeasurements.rowCount,\n });\n\n const { onKeyDown: editingKeyDown } = useCellEditing({ navigate });\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLElement>) => {\n navigationKeyDown(e);\n if (!e.defaultPrevented) {\n editingKeyDown(e);\n }\n },\n [navigationKeyDown, editingKeyDown]\n );\n\n const onContextMenu = useTableContextMenuNext({ columns, data });\n\n const onHeaderClick = useCallback(\n (evt: MouseEvent) => {\n const targetElement = evt.target as HTMLElement;\n const headerCell = targetElement.closest(\n \".vuuTableNextHeaderCell\"\n ) as HTMLElement;\n const colIdx = parseInt(headerCell?.dataset.index ?? \"-1\");\n const column = visibleColumnAtIndex(columns, colIdx);\n const isAdditive = evt.shiftKey;\n column && handleSort(column, isAdditive);\n },\n [columns, handleSort]\n );\n\n const onRemoveGroupColumn = useCallback(\n (column: KeyedColumnDescriptor) => {\n if (isGroupColumn(column)) {\n dataSource.groupBy = [];\n } else {\n if (dataSource && dataSource.groupBy.includes(column.name)) {\n dataSource.groupBy = dataSource.groupBy.filter(\n (columnName) => columnName !== column.name\n );\n }\n }\n },\n [dataSource]\n );\n\n const handleSelectionChange: SelectionChangeHandler = useCallback(\n (selected) => {\n dataSource.select(selected);\n onSelectionChange?.(selected);\n },\n [dataSource, onSelectionChange]\n );\n\n const selectionHookOnRowClick = useSelection({\n onSelectionChange: handleSelectionChange,\n selectionModel,\n });\n\n const handleRowClick = useCallback<RowClickHandler>(\n (row, rangeSelect, keepExistingSelection) => {\n selectionHookOnRowClick(row, rangeSelect, keepExistingSelection);\n onRowClickProp?.(row);\n },\n [onRowClickProp, selectionHookOnRowClick]\n );\n\n useEffect(() => {\n dataSource.on(\"config\", (config, confirmed) => {\n // expectConfigChangeRef.current = true;\n dispatchColumnAction({\n type: \"tableConfig\",\n ...config,\n confirmed,\n });\n });\n }, [dataSource, dispatchColumnAction]);\n\n const handleDrop = useCallback(\n (moveFrom: number, moveTo: number) => {\n // onMoveColumn?.(fromIndex, toIndex);\n const column = columns[moveFrom];\n\n dispatchColumnAction({\n type: \"moveColumn\",\n column,\n moveTo,\n });\n },\n [columns, dispatchColumnAction]\n );\n\n const handleDataEdited = useCallback<DataCellEditHandler>(\n (rowIndex, columnName, value) => {\n return dataSource.applyEdit(rowIndex, columnName, value);\n },\n [dataSource]\n );\n\n const { onMouseDown: dragDropHookHandleMouseDown, ...dragDropHook } =\n useDragDrop({\n allowDragDrop: true,\n containerRef,\n // this is for useDragDropNext\n draggableClassName: `vuuTableNext`,\n // extendedDropZone: overflowedItems.length > 0,\n onDrop: handleDrop,\n orientation: \"horizontal\",\n itemQuery: \".vuuTableNextHeaderCell\",\n });\n\n const headerProps = {\n onClick: onHeaderClick,\n onMouseDown: dragDropHookHandleMouseDown,\n onResize: onHeaderResize,\n };\n\n return {\n ...containerProps,\n onKeyDown: handleKeyDown,\n columnMap,\n columns,\n data,\n handleContextMenuAction,\n headerProps,\n menuBuilder,\n onContextMenu,\n onDataEdited: handleDataEdited,\n onRemoveGroupColumn,\n onResize: handleResize,\n onRowClick: handleRowClick,\n onToggleGroup,\n scrollProps,\n tableAttributes,\n viewportMeasurements,\n dragDropHook,\n };\n};\n", "import { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n KeyboardEvent,\n MouseEvent,\n RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport { ScrollDirection, ScrollRequestHandler } from \"./useTableScroll\";\nimport {\n CellPos,\n dataCellQuery,\n getTableCell,\n headerCellQuery,\n} from \"./table-dom-utils\";\n\nconst navigationKeys = new Set<NavigationKey>([\n \"Home\",\n \"End\",\n \"PageUp\",\n \"PageDown\",\n \"ArrowDown\",\n \"ArrowLeft\",\n \"ArrowRight\",\n \"ArrowUp\",\n]);\n\nexport const isNavigationKey = (key: string): key is NavigationKey => {\n return navigationKeys.has(key as NavigationKey);\n};\n\ntype ArrowKey = \"ArrowUp\" | \"ArrowDown\" | \"ArrowLeft\" | \"ArrowRight\";\ntype PageKey = \"Home\" | \"End\" | \"PageUp\" | \"PageDown\";\ntype NavigationKey = PageKey | ArrowKey;\n\nconst PageKeys = [\"Home\", \"End\", \"PageUp\", \"PageDown\"];\nexport const isPagingKey = (key: string): key is PageKey =>\n PageKeys.includes(key);\n\nconst NULL_CELL_POS: CellPos = [-1, -1];\n\nconst NO_SCROLL_NECESSARY = [undefined, undefined] as const;\n\nconst howFarIsCellOutsideViewport = (\n cellEl: HTMLElement\n): readonly [ScrollDirection | undefined, number | undefined] => {\n //TODO lots of scope for optimisation here\n const scrollbarContainer = cellEl\n .closest(\".vuuTableNext\")\n ?.querySelector(\".vuuTableNext-scrollbarContainer\");\n if (scrollbarContainer) {\n const viewport = scrollbarContainer?.getBoundingClientRect();\n const cell = cellEl.closest(\".vuuTableNextCell\")?.getBoundingClientRect();\n if (cell) {\n if (cell.bottom > viewport.bottom) {\n return [\"down\", cell.bottom - viewport.bottom];\n } else if (cell.top < viewport.top) {\n return [\"up\", cell.top - viewport.top];\n } else if (cell.right < viewport.right) {\n return [\"right\", cell.right - viewport.right];\n } else if (cell.left < viewport.left) {\n return [\"left\", cell.left - viewport.left];\n } else {\n return NO_SCROLL_NECESSARY;\n }\n } else {\n throw Error(\"Whats going on, cell not found\");\n }\n } else {\n throw Error(\"Whats going on, scrollbar container not found\");\n }\n};\n\nfunction nextCellPos(\n key: ArrowKey,\n [rowIdx, colIdx]: CellPos,\n columnCount: number,\n rowCount: number\n): CellPos {\n if (key === \"ArrowUp\") {\n if (rowIdx > -1) {\n return [rowIdx - 1, colIdx];\n } else {\n return [rowIdx, colIdx];\n }\n } else if (key === \"ArrowDown\") {\n if (rowIdx === -1) {\n return [0, colIdx];\n } else if (rowIdx === rowCount - 1) {\n return [rowIdx, colIdx];\n } else {\n return [rowIdx + 1, colIdx];\n }\n } else if (key === \"ArrowRight\") {\n if (colIdx < columnCount - 1) {\n return [rowIdx, colIdx + 1];\n } else {\n return [rowIdx, colIdx];\n }\n } else if (key === \"ArrowLeft\") {\n if (colIdx > 1) {\n return [rowIdx, colIdx - 1];\n } else {\n return [rowIdx, colIdx];\n }\n }\n return [rowIdx, colIdx];\n}\n\nexport interface NavigationHookProps {\n containerRef: RefObject<HTMLElement>;\n columnCount?: number;\n disableHighlightOnFocus?: boolean;\n label?: string;\n viewportRange: VuuRange;\n requestScroll?: ScrollRequestHandler;\n restoreLastFocus?: boolean;\n rowCount?: number;\n selected?: unknown;\n viewportRowCount: number;\n}\n\nexport const useKeyboardNavigation = ({\n columnCount = 0,\n containerRef,\n disableHighlightOnFocus,\n requestScroll,\n rowCount = 0,\n viewportRowCount,\n}: // viewportRange,\nNavigationHookProps) => {\n // const { from: viewportFirstRow, to: viewportLastRow } = viewportRange;\n const focusedCellPos = useRef<CellPos>([-1, -1]);\n const focusableCell = useRef<HTMLElement>();\n const activeCellPos = useRef<CellPos>([-1, 0]);\n\n const getFocusedCell = (element: HTMLElement | Element | null) =>\n element?.closest(\n \"[role='columnHeader'],[role='cell']\"\n ) as HTMLDivElement | null;\n\n const getTableCellPos = (tableCell: HTMLDivElement): CellPos => {\n if (tableCell.role === \"columnHeader\") {\n const colIdx = parseInt(tableCell.dataset.idx ?? \"-1\", 10);\n return [-1, colIdx];\n } else {\n const focusedRow = tableCell.closest(\"[role='row']\");\n if (focusedRow) {\n const rowIdx = parseInt(focusedRow.ariaRowIndex ?? \"-1\", 10);\n // TODO will get trickier when we introduce horizontal virtualisation\n const colIdx = Array.from(focusedRow.childNodes).indexOf(tableCell);\n return [rowIdx, colIdx];\n }\n }\n return NULL_CELL_POS;\n };\n\n const focusCell = useCallback(\n (cellPos: CellPos) => {\n if (containerRef.current) {\n const activeCell = getTableCell(containerRef, cellPos);\n if (activeCell) {\n if (activeCell !== focusableCell.current) {\n focusableCell.current?.removeAttribute(\"tabindex\");\n focusableCell.current = activeCell;\n activeCell.setAttribute(\"tabindex\", \"0\");\n }\n const [direction, distance] = howFarIsCellOutsideViewport(activeCell);\n if (direction && distance) {\n requestScroll?.({ type: \"scroll-distance\", distance, direction });\n }\n activeCell.focus();\n }\n }\n },\n // TODO we recreate this function whenever viewportRange changes, which will\n // be often whilst scrolling - store range in a a ref ?\n [containerRef, requestScroll]\n );\n\n const setActiveCell = useCallback(\n (rowIdx: number, colIdx: number, fromKeyboard = false) => {\n const pos: CellPos = [rowIdx, colIdx];\n activeCellPos.current = pos;\n focusCell(pos);\n if (fromKeyboard) {\n focusedCellPos.current = pos;\n }\n },\n [focusCell]\n );\n\n const nextPageItemIdx = useCallback(\n (\n key: \"PageDown\" | \"PageUp\" | \"Home\" | \"End\",\n [rowIdx, colIdx]: CellPos\n ): Promise<CellPos> =>\n new Promise((resolve) => {\n let newRowIdx = rowIdx;\n switch (key) {\n case \"PageDown\":\n newRowIdx = Math.min(rowCount - 1, rowIdx + viewportRowCount);\n requestScroll?.({ type: \"scroll-page\", direction: \"down\" });\n break;\n case \"PageUp\":\n newRowIdx = Math.max(0, rowIdx - viewportRowCount);\n requestScroll?.({ type: \"scroll-page\", direction: \"up\" });\n break;\n case \"Home\":\n newRowIdx = 0;\n requestScroll?.({ type: \"scroll-end\", direction: \"home\" });\n break;\n case \"End\":\n newRowIdx = rowCount - 1;\n requestScroll?.({ type: \"scroll-end\", direction: \"end\" });\n break;\n }\n setTimeout(() => {\n resolve([newRowIdx, colIdx]);\n }, 90);\n }),\n [requestScroll, rowCount, viewportRowCount]\n );\n\n const handleFocus = useCallback(() => {\n if (disableHighlightOnFocus !== true) {\n if (containerRef.current?.contains(document.activeElement)) {\n // IF focus arrives via keyboard, a cell will have received focus,\n // we handle that here. If focus arrives via click on a cell with\n // no tabindex (i.e all cells except one) we leave that to the\n // click handler.\n const focusedCell = getFocusedCell(document.activeElement);\n if (focusedCell) {\n console.log({ focusedCell });\n focusedCellPos.current = getTableCellPos(focusedCell);\n }\n }\n }\n }, [disableHighlightOnFocus, containerRef]);\n\n const navigateChildItems = useCallback(\n async (key: NavigationKey) => {\n console.log(`navigate child items ${key}`);\n const [nextRowIdx, nextColIdx] = isPagingKey(key)\n ? await nextPageItemIdx(key, activeCellPos.current)\n : nextCellPos(key, activeCellPos.current, columnCount, rowCount);\n console.log(`nextRowIdx ${nextRowIdx} nextColIdx ${nextColIdx}`);\n\n const [rowIdx, colIdx] = activeCellPos.current;\n if (nextRowIdx !== rowIdx || nextColIdx !== colIdx) {\n setActiveCell(nextRowIdx, nextColIdx, true);\n }\n },\n [columnCount, nextPageItemIdx, rowCount, setActiveCell]\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (rowCount > 0 && isNavigationKey(e.key)) {\n e.preventDefault();\n e.stopPropagation();\n void navigateChildItems(e.key);\n }\n },\n [rowCount, navigateChildItems]\n );\n\n const handleClick = useCallback(\n // Might not be a cell e.g the Settings button\n (evt: MouseEvent) => {\n const target = evt.target as HTMLElement;\n const focusedCell = getFocusedCell(target);\n if (focusedCell) {\n const [rowIdx, colIdx] = getTableCellPos(focusedCell);\n setActiveCell(rowIdx, colIdx);\n }\n },\n [setActiveCell]\n );\n\n const navigate = useCallback(() => {\n navigateChildItems(\"ArrowDown\");\n }, [navigateChildItems]);\n\n const containerProps = useMemo(() => {\n return {\n navigate,\n onClick: handleClick,\n onFocus: handleFocus,\n onKeyDown: handleKeyDown,\n };\n }, [handleClick, handleFocus, handleKeyDown, navigate]);\n\n // First render will only render the outer container when explicit\n // sizing has not been provided. Outer container is measured and\n // only then, on second render, is content rendered.\n const fullyRendered = containerRef.current?.firstChild != null;\n useEffect(() => {\n if (fullyRendered && focusableCell.current === undefined) {\n const { current: container } = containerRef;\n const cell = (container?.querySelector(headerCellQuery(0)) ||\n container?.querySelector(dataCellQuery(0, 0))) as HTMLElement;\n if (cell) {\n cell.setAttribute(\"tabindex\", \"0\");\n focusableCell.current = cell;\n }\n }\n }, [containerRef, fullyRendered]);\n\n return containerProps;\n};\n", "import { ColumnDescriptor, TableConfig } from \"@vuu-ui/vuu-datagrid-types\";\n\nexport type MoveColumnTableConfigAction = {\n type: \"col-move\";\n column: ColumnDescriptor;\n fromIndex: number;\n toIndex: number;\n};\n\nexport type ResizeColumnTableConfigAction = {\n type: \"col-size\";\n column: ColumnDescriptor;\n width: number;\n};\n\nexport type SubscribeColumnTableConfigAction = {\n type: \"subscribed\";\n column: ColumnDescriptor;\n value: boolean;\n};\n\nexport type UpdateColumnPropertyTableConfigAction = {\n type: \"column-prop\";\n column: ColumnDescriptor;\n property: keyof ColumnDescriptor;\n value: boolean | number | string;\n};\n\nexport type TableConfigAction =\n | MoveColumnTableConfigAction\n | ResizeColumnTableConfigAction\n | UpdateColumnPropertyTableConfigAction;\n\nexport const updateTableConfig = (\n config: TableConfig,\n action: TableConfigAction\n): TableConfig => {\n switch (action.type) {\n case \"col-size\":\n return {\n ...config,\n columns: config.columns.map((col) =>\n col.name === action.column.name\n ? { ...col, width: action.width }\n : col\n ),\n };\n case \"column-prop\":\n return {\n ...config,\n columns: config.columns.map((col) =>\n col.name === action.column.name\n ? { ...col, [action.property]: action.value }\n : col\n ),\n };\n\n default:\n return config;\n }\n};\n", "import {\n DataSource,\n DataSourceSubscribedMessage,\n SubscribeCallback,\n VuuFeatureInvocationMessage,\n VuuFeatureMessage,\n} from \"@vuu-ui/vuu-data\";\nimport {\n isVuuFeatureAction,\n isVuuFeatureInvocation,\n} from \"@vuu-ui/vuu-data-react/src\";\nimport { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\nimport { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { getFullRange, NULL_RANGE } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { MovingWindow } from \"./moving-window\";\n\nexport interface DataSourceHookProps {\n dataSource: DataSource;\n // onConfigChange?: (message: DataSourceConfigMessage) => void;\n onFeatureEnabled?: (message: VuuFeatureMessage) => void;\n onFeatureInvocation?: (message: VuuFeatureInvocationMessage) => void;\n onSizeChange: (size: number) => void;\n onSubscribed: (subscription: DataSourceSubscribedMessage) => void;\n range?: VuuRange;\n renderBufferSize?: number;\n}\n\nexport const useDataSource = ({\n dataSource,\n onFeatureEnabled,\n onFeatureInvocation,\n onSizeChange,\n onSubscribed,\n range = NULL_RANGE,\n renderBufferSize = 0,\n}: DataSourceHookProps) => {\n const [, forceUpdate] = useState<unknown>(null);\n const data = useRef<DataSourceRow[]>([]);\n const isMounted = useRef(true);\n const hasUpdated = useRef(false);\n // const rafHandle = useRef<number | null>(null);\n const rangeRef = useRef<VuuRange>(NULL_RANGE);\n\n const dataWindow = useMemo(\n () => new MovingWindow(getFullRange(range, renderBufferSize)),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n []\n );\n\n const setData = useCallback(\n (updates: DataSourceRow[]) => {\n for (const row of updates) {\n dataWindow.add(row);\n }\n data.current = dataWindow.data;\n if (isMounted.current) {\n // TODO do we ever need to worry about missing updates here ?\n forceUpdate({});\n }\n },\n [dataWindow]\n );\n\n const datasourceMessageHandler: SubscribeCallback = useCallback(\n (message) => {\n if (message.type === \"subscribed\") {\n onSubscribed?.(message);\n } else if (message.type === \"viewport-update\") {\n if (typeof message.size === \"number\") {\n onSizeChange?.(message.size);\n dataWindow.setRowCount(message.size);\n }\n if (message.rows) {\n setData(message.rows);\n } else if (typeof message.size === \"number\") {\n data.current = dataWindow.data;\n hasUpdated.current = true;\n }\n } else if (isVuuFeatureAction(message)) {\n onFeatureEnabled?.(message);\n } else if (isVuuFeatureInvocation(message)) {\n onFeatureInvocation?.(message);\n } else {\n console.log(`useDataSource unexpected message ${message.type}`);\n }\n },\n [\n dataWindow,\n onFeatureEnabled,\n onFeatureInvocation,\n onSizeChange,\n onSubscribed,\n setData,\n ]\n );\n\n useEffect(\n () => () => {\n isMounted.current = true;\n // if (rafHandle.current) {\n // cancelAnimationFrame(rafHandle.current);\n // rafHandle.current = null;\n // }\n isMounted.current = false;\n },\n []\n );\n\n // Keep until we'tre sure we don't need it for updates\n // const refreshIfUpdated = useCallback(() => {\n // if (isMounted.current) {\n // console.log(`RAF updated data ? ${hasUpdated.current}`);\n // if (hasUpdated.current) {\n // forceUpdate({});\n // hasUpdated.current = false;\n // }\n // rafHandle.current = requestAnimationFrame(refreshIfUpdated);\n // }\n // }, [forceUpdate]);\n // useEffect(() => {\n // rafHandle.current = requestAnimationFrame(refreshIfUpdated);\n // }, [refreshIfUpdated]);\n\n useEffect(() => {\n //TODO could we improve this by using a ref for range ?\n dataSource?.subscribe(\n { range: getFullRange(range, renderBufferSize) },\n datasourceMessageHandler\n );\n }, [dataSource, datasourceMessageHandler, range, renderBufferSize]);\n\n const setRange = useCallback(\n (range: VuuRange) => {\n const fullRange = getFullRange(range, renderBufferSize);\n dataWindow.setRange(fullRange);\n dataSource.range = rangeRef.current = fullRange;\n dataSource.emit(\"range\", range);\n },\n [dataSource, dataWindow, renderBufferSize]\n );\n\n return {\n data: data.current,\n range: rangeRef.current,\n setRange,\n };\n};\n", "import { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\nimport { metadataKeys, WindowRange } from \"@vuu-ui/vuu-utils\";\nimport { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\n\nconst { SELECTED } = metadataKeys;\n\nexport class MovingWindow {\n public data: DataSourceRow[];\n public rowCount = 0;\n private range: WindowRange;\n\n constructor({ from, to }: VuuRange) {\n this.range = new WindowRange(from, to);\n //internal data is always 0 based, we add range.from to determine an offset\n this.data = new Array(to - from);\n this.rowCount = 0;\n }\n\n setRowCount = (rowCount: number) => {\n if (rowCount < this.data.length) {\n this.data.length = rowCount;\n }\n\n this.rowCount = rowCount;\n };\n\n add(data: DataSourceRow) {\n const [index] = data;\n if (this.isWithinRange(index)) {\n const internalIndex = index - this.range.from;\n this.data[internalIndex] = data;\n }\n }\n\n getAtIndex(index: number) {\n return this.range.isWithin(index) &&\n this.data[index - this.range.from] != null\n ? this.data[index - this.range.from]\n : undefined;\n }\n\n isWithinRange(index: number) {\n return this.range.isWithin(index);\n }\n\n setRange({ from, to }: VuuRange) {\n if (from !== this.range.from || to !== this.range.to) {\n const [overlapFrom, overlapTo] = this.range.overlap(from, to);\n const newData = new Array(Math.max(0, to - from));\n for (let i = overlapFrom; i < overlapTo; i++) {\n const data = this.getAtIndex(i);\n if (data) {\n const index = i - from;\n newData[index] = data;\n }\n }\n this.data = newData;\n this.range.from = from;\n this.range.to = to;\n }\n }\n\n getSelectedRows() {\n return this.data.filter((row) => row[SELECTED] === 1);\n }\n}\n", "import { useMemo, useRef } from \"react\";\n\nexport const useInitialValue = <T = unknown>(value: T): T => {\n const ref = useRef<T>(value);\n return useMemo(() => ref.current, []);\n};\n", "import { buildColumnMap } from \"@vuu-ui/vuu-utils\";\nimport { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\nimport { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { MouseEvent, useCallback } from \"react\";\nimport { useContextMenu as usePopupContextMenu } from \"@vuu-ui/vuu-popups\";\n\nexport interface TableContextMenuHookProps {\n columns: KeyedColumnDescriptor[];\n data: DataSourceRow[];\n}\n\nexport const useTableContextMenu = ({\n columns,\n data,\n}: TableContextMenuHookProps) => {\n const [showContextMenu] = usePopupContextMenu();\n\n const onContextMenu = useCallback(\n (evt: MouseEvent<HTMLElement>) => {\n // const { current: currentData } = dataRef;\n // const { current: currentDataSource } = dataSourceRef;\n const target = evt.target as HTMLElement;\n const cellEl = target?.closest(\"div[role='cell']\");\n const rowEl = target?.closest(\"div[role='row']\");\n if (cellEl && rowEl /*&& currentData && currentDataSource*/) {\n // const { columns, selectedRowsCount } = currentDataSource;\n const columnMap = buildColumnMap(columns);\n const rowIndex = parseInt(rowEl.ariaRowIndex ?? \"-1\");\n const cellIndex = Array.from(rowEl.childNodes).indexOf(cellEl);\n const row = data.find(([idx]) => idx === rowIndex);\n const columnName = columns[cellIndex];\n showContextMenu(evt, \"grid\", {\n columnMap,\n columnName,\n row,\n // selectedRows: selectedRowsCount === 0 ? NO_ROWS : getSelectedRows(),\n // viewport: dataSource?.viewport,\n });\n }\n },\n [columns, data, showContextMenu]\n );\n\n return onContextMenu;\n};\n", "import { isCharacterKey } from \"@vuu-ui/vuu-utils\";\nimport { KeyboardEvent as ReactKeyboardEvent, useCallback } from \"react\";\nimport { cellIsTextInput } from \"./table-dom-utils\";\n\nexport interface CellEditingHookProps {\n navigate: () => void;\n}\n\nexport const useCellEditing = ({ navigate }: CellEditingHookProps) => {\n const commitHandler = useCallback(() => {\n navigate();\n }, [navigate]);\n\n const editInput = useCallback(\n (evt: ReactKeyboardEvent<HTMLElement>) => {\n const cellEl = evt.target as HTMLDivElement;\n const input = cellEl.querySelector(\"input\");\n if (input) {\n input.focus();\n input.select();\n }\n // TODO dergister on blur\n // TODO need a custom event\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore commit is a custom event fired by vuu inputs\n cellEl.addEventListener(\"vuu-commit\", commitHandler, true);\n },\n [commitHandler]\n );\n\n const focusInput = useCallback(\n (evt: ReactKeyboardEvent<HTMLElement>) => {\n const cellEl = evt.target as HTMLDivElement;\n const input = cellEl.querySelector(\"input\");\n if (input) {\n input.focus();\n input.select();\n }\n cellEl.addEventListener(\"vuu-commit\", commitHandler, true);\n },\n [commitHandler]\n );\n\n const handleKeyDown = useCallback(\n (e: ReactKeyboardEvent<HTMLElement>) => {\n if (cellIsTextInput(e.target as HTMLDivElement)) {\n if (isCharacterKey(e.key)) {\n editInput(e);\n } else if (e.key === \"Enter\") {\n focusInput(e);\n }\n }\n },\n [editInput, focusInput]\n );\n\n return {\n onKeyDown: handleKeyDown,\n };\n};\n", "import {\n ColumnDescriptor,\n KeyedColumnDescriptor,\n PinLocation,\n TableAttributes,\n TableConfig,\n TableHeadings,\n} from \"@vuu-ui/vuu-datagrid-types\";\nimport {\n applyFilterToColumns,\n applyGroupByToColumns,\n applySortToColumns,\n getCellRenderer,\n getTableHeadings,\n getValueFormatter,\n hasValidationRules,\n isFilteredColumn,\n isGroupColumn,\n isPinned,\n isTypeDescriptor,\n logger,\n metadataKeys,\n moveItem,\n sortPinnedColumns,\n stripFilterFromColumns,\n subscribedOnly,\n} from \"@vuu-ui/vuu-utils\";\n\nimport { DataSourceConfig } from \"@vuu-ui/vuu-data\";\nimport { TableSchema } from \"@vuu-ui/vuu-data/src/message-utils\";\nimport { VuuColumnDataType, VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport { buildValidationChecker } from \"@vuu-ui/vuu-ui-controls\";\nimport { Reducer, useReducer } from \"react\";\n\nconst { info } = logger(\"useTableModel\");\n\nconst DEFAULT_COLUMN_WIDTH = 100;\nconst KEY_OFFSET = metadataKeys.count;\n\nconst columnWithoutDataType = ({ serverDataType }: ColumnDescriptor) =>\n serverDataType === undefined;\n\nconst getCellRendererForColumn = (column: ColumnDescriptor) => {\n if (isTypeDescriptor(column.type)) {\n return getCellRenderer(column.type?.renderer);\n }\n};\n\nconst getDataType = (\n column: ColumnDescriptor,\n tableSchema: TableSchema\n): VuuColumnDataType => {\n const schemaColumn = tableSchema.columns.find(\n ({ name }) => name === column.name\n );\n if (schemaColumn) {\n return schemaColumn.serverDataType;\n } else {\n return column.serverDataType ?? \"string\";\n }\n};\n\n/**\n * TableModel represents state used internally to manage Table. It is\n * derived initially from the TableConfig provided by user, along with the\n * data-related config from DataSource.\n */\nexport interface TableModel extends TableAttributes {\n columns: KeyedColumnDescriptor[];\n headings: TableHeadings;\n}\n\n/**\n * InternalTableModel describes the state managed within the TableModel\n * reducer. It is the same as TableModel but with the addition of a\n * readonly copy of the original TableConfig.\n */\ninterface InternalTableModel extends TableModel {\n tableConfig: Readonly<TableConfig>;\n}\n\nconst numericTypes = [\"int\", \"long\", \"double\"];\nconst getDefaultAlignment = (serverDataType?: VuuColumnDataType) =>\n serverDataType === undefined\n ? undefined\n : numericTypes.includes(serverDataType)\n ? \"right\"\n : \"left\";\n\nexport interface ColumnActionInit {\n type: \"init\";\n tableConfig: TableConfig;\n dataSourceConfig?: DataSourceConfig;\n}\n\nexport interface ColumnActionHide {\n type: \"hideColumns\";\n columns: KeyedColumnDescriptor[];\n}\n\nexport interface ColumnActionShow {\n type: \"showColumns\";\n columns: KeyedColumnDescriptor[];\n}\nexport interface ColumnActionMove {\n type: \"moveColumn\";\n column: KeyedColumnDescriptor;\n moveBy?: 1 | -1;\n moveTo?: number;\n}\n\nexport interface ColumnActionPin {\n type: \"pinColumn\";\n column: ColumnDescriptor;\n pin?: PinLocation;\n}\n\nexport type ResizePhase = \"begin\" | \"resize\" | \"end\";\n\nexport interface ColumnActionResize {\n type: \"resizeColumn\";\n column: KeyedColumnDescriptor;\n phase: ResizePhase;\n width?: number;\n}\n\nexport interface ColumnActionSetTableSchema {\n type: \"setTableSchema\";\n tableSchema: TableSchema;\n}\n\nexport interface ColumnActionUpdate {\n type: \"updateColumn\";\n column: ColumnDescriptor;\n}\n\nexport interface ColumnActionUpdateProp {\n align?: ColumnDescriptor[\"align\"];\n column: KeyedColumnDescriptor;\n hidden?: ColumnDescriptor[\"hidden\"];\n label?: ColumnDescriptor[\"label\"];\n resizing?: KeyedColumnDescriptor[\"resizing\"];\n type: \"updateColumnProp\";\n width?: ColumnDescriptor[\"width\"];\n}\n\nexport interface ColumnActionTableConfig extends DataSourceConfig {\n confirmed?: boolean;\n type: \"tableConfig\";\n}\n\nexport interface ColumnActionColumnSettings extends DataSourceConfig {\n type: \"columnSettings\";\n column: ColumnDescriptor;\n /** required only for calculated coplumns */\n vuuTable?: VuuTable;\n}\n\nexport interface ColumnActionTableSettings extends DataSourceConfig {\n type: \"tableSettings\";\n}\n\nexport const isShowColumnSettings = (\n action: PersistentColumnAction\n): action is ColumnActionColumnSettings => action.type === \"columnSettings\";\n\nexport const isShowTableSettings = (\n action: PersistentColumnAction\n): action is ColumnActionTableSettings => action.type === \"tableSettings\";\n\n/**\n * PersistentColumnActions are those actions that require us to persist user changes across sessions\n */\nexport type PersistentColumnAction =\n | ColumnActionPin\n | ColumnActionHide\n | ColumnActionColumnSettings\n | ColumnActionTableSettings;\n\nexport type GridModelAction =\n | ColumnActionHide\n | ColumnActionInit\n | ColumnActionMove\n | ColumnActionPin\n | ColumnActionResize\n | ColumnActionSetTableSchema\n | ColumnActionShow\n | ColumnActionUpdate\n | ColumnActionUpdateProp\n | ColumnActionTableConfig;\n\nexport type GridModelReducer = Reducer<InternalTableModel, GridModelAction>;\n\nexport type ColumnActionDispatch = (action: GridModelAction) => void;\n\nconst columnReducer: GridModelReducer = (state, action) => {\n info?.(`TableModelReducer ${action.type}`);\n console.log(`TableModelReducer ${action.type}`);\n switch (action.type) {\n case \"init\":\n console.log({ init: action });\n return init(action);\n case \"moveColumn\":\n return moveColumn(state, action);\n case \"resizeColumn\":\n return resizeColumn(state, action);\n case \"setTableSchema\":\n return setTableSchema(state, action);\n case \"hideColumns\":\n return hideColumns(state, action);\n case \"showColumns\":\n return showColumns(state, action);\n case \"pinColumn\":\n return pinColumn(state, action);\n case \"updateColumnProp\":\n return updateColumnProp(state, action);\n case \"tableConfig\":\n return updateTableConfig(state, action);\n default:\n console.log(`unhandled action ${action.type}`);\n return state;\n }\n};\n\nexport const useTableModel = (\n tableConfigProp: TableConfig,\n dataSourceConfig?: DataSourceConfig\n) => {\n const [state, dispatchColumnAction] = useReducer<\n GridModelReducer,\n InitialConfig\n >(columnReducer, { tableConfig: tableConfigProp, dataSourceConfig }, init);\n\n const { columns, headings, tableConfig, ...tableAttributes } = state;\n\n return {\n columns,\n dispatchColumnAction,\n headings,\n tableAttributes,\n tableConfig,\n };\n};\n\ntype InitialConfig = {\n dataSourceConfig?: DataSourceConfig;\n tableConfig: TableConfig;\n};\n\nfunction init({\n dataSourceConfig,\n tableConfig,\n}: InitialConfig): InternalTableModel {\n const { columns, ...tableAttributes } = tableConfig;\n const keyedColumns = columns\n .filter(subscribedOnly(dataSourceConfig?.columns))\n .map(columnDescriptorToKeyedColumDescriptor(tableAttributes));\n const maybePinnedColumns = keyedColumns.some(isPinned)\n ? sortPinnedColumns(keyedColumns)\n : keyedColumns;\n let state: InternalTableModel = {\n columns: maybePinnedColumns,\n headings: getTableHeadings(maybePinnedColumns),\n tableConfig,\n ...tableAttributes,\n };\n if (dataSourceConfig) {\n const { columns: _, ...rest } = dataSourceConfig;\n state = updateTableConfig(state, {\n type: \"tableConfig\",\n ...rest,\n });\n }\n return state;\n}\n\nconst getLabel = (\n label: string,\n columnFormatHeader?: \"uppercase\" | \"capitalize\"\n): string => {\n if (columnFormatHeader === \"uppercase\") {\n return label.toUpperCase();\n } else if (columnFormatHeader === \"capitalize\") {\n return label[0].toUpperCase() + label.slice(1).toLowerCase();\n }\n return label;\n};\n\nconst columnDescriptorToKeyedColumDescriptor =\n (tableAttributes: TableAttributes) =>\n (\n column: ColumnDescriptor & { key?: number },\n index: number\n ): KeyedColumnDescriptor => {\n const { columnDefaultWidth = DEFAULT_COLUMN_WIDTH, columnFormatHeader } =\n tableAttributes;\n const {\n align = getDefaultAlignment(column.serverDataType),\n key,\n name,\n label = name,\n width = columnDefaultWidth,\n ...rest\n } = column;\n\n const keyedColumnWithDefaults = {\n ...rest,\n align,\n CellRenderer: getCellRendererForColumn(column),\n clientSideEditValidationCheck: hasValidationRules(column.type)\n ? buildValidationChecker(column.type.renderer.rules)\n : undefined,\n label: getLabel(label, columnFormatHeader),\n key: key ?? index + KEY_OFFSET,\n name,\n originalIdx: index,\n valueFormatter: getValueFormatter(column),\n width: width,\n };\n\n if (isGroupColumn(keyedColumnWithDefaults)) {\n keyedColumnWithDefaults.columns = keyedColumnWithDefaults.columns.map(\n (col) =>\n columnDescriptorToKeyedColumDescriptor(tableAttributes)(col, col.key)\n );\n }\n\n return keyedColumnWithDefaults;\n };\n\nfunction moveColumn(\n state: InternalTableModel,\n { column, moveBy, moveTo }: ColumnActionMove\n) {\n const { columns } = state;\n if (typeof moveBy === \"number\") {\n const idx = columns.indexOf(column);\n const newColumns = columns.slice();\n const [movedColumns] = newColumns.splice(idx, 1);\n newColumns.splice(idx + moveBy, 0, movedColumns);\n return {\n ...state,\n columns: newColumns,\n };\n } else if (typeof moveTo === \"number\") {\n const index = columns.indexOf(column);\n return {\n ...state,\n columns: moveItem(columns, index, moveTo),\n };\n }\n return state;\n}\n\nfunction hideColumns(state: InternalTableModel, { columns }: ColumnActionHide) {\n if (columns.some((col) => col.hidden !== true)) {\n return columns.reduce<InternalTableModel>((s, c) => {\n if (c.hidden !== true) {\n return updateColumnProp(s, {\n type: \"updateColumnProp\",\n column: c,\n hidden: true,\n });\n } else {\n return s;\n }\n }, state);\n } else {\n return state;\n }\n}\nfunction showColumns(state: InternalTableModel, { columns }: ColumnActionShow) {\n if (columns.some((col) => col.hidden)) {\n return columns.reduce<InternalTableModel>((s, c) => {\n if (c.hidden) {\n return updateColumnProp(s, {\n type: \"updateColumnProp\",\n column: c,\n hidden: false,\n });\n } else {\n return s;\n }\n }, state);\n } else {\n return state;\n }\n}\n\nfunction resizeColumn(\n state: InternalTableModel,\n { column, phase, width }: ColumnActionResize\n) {\n const type = \"updateColumnProp\";\n const resizing = phase !== \"end\";\n switch (phase) {\n case \"begin\":\n return updateColumnProp(state, { type, column, resizing });\n case \"end\":\n return updateColumnProp(state, { type, column, resizing, width });\n case \"resize\":\n return updateColumnProp(state, { type, column, width });\n default:\n throw Error(`useTableModel.resizeColumn, invalid resizePhase ${phase}`);\n }\n}\n\nfunction setTableSchema(\n state: InternalTableModel,\n { tableSchema }: ColumnActionSetTableSchema\n) {\n const { columns } = state;\n if (columns.some(columnWithoutDataType)) {\n const cols = columns.map((column) => {\n const serverDataType = getDataType(column, tableSchema);\n return {\n ...column,\n align: column.align ?? getDefaultAlignment(serverDataType),\n serverDataType,\n };\n });\n\n return {\n ...state,\n columns: cols,\n };\n } else {\n return state;\n }\n}\n\nfunction pinColumn(state: InternalTableModel, action: ColumnActionPin) {\n let { columns } = state;\n const { column, pin } = action;\n const targetColumn = columns.find((col) => col.name === column.name);\n if (targetColumn) {\n columns = replaceColumn(columns, { ...targetColumn, pin });\n columns = sortPinnedColumns(columns);\n return {\n ...state,\n columns,\n };\n } else {\n return state;\n }\n}\nfunction updateColumnProp(\n state: InternalTableModel,\n action: ColumnActionUpdateProp\n) {\n let { columns } = state;\n const { align, column, hidden, label, resizing, width } = action;\n const targetColumn = columns.find((col) => col.name === column.name);\n if (targetColumn) {\n if (align === \"left\" || align === \"right\") {\n columns = replaceColumn(columns, { ...targetColumn, align });\n }\n if (typeof label === \"string\") {\n columns = replaceColumn(columns, { ...targetColumn, label });\n }\n if (typeof resizing === \"boolean\") {\n columns = replaceColumn(columns, { ...targetColumn, resizing });\n }\n if (typeof hidden === \"boolean\") {\n columns = replaceColumn(columns, { ...targetColumn, hidden });\n }\n if (typeof width === \"number\") {\n columns = replaceColumn(columns, { ...targetColumn, width });\n }\n }\n return {\n ...state,\n columns,\n } as InternalTableModel;\n}\n\nfunction updateTableConfig(\n state: InternalTableModel,\n { confirmed, filter, groupBy, sort }: ColumnActionTableConfig\n) {\n const hasGroupBy = groupBy !== undefined;\n const hasFilter = typeof filter?.filter === \"string\";\n const hasSort = sort && sort.sortDefs.length > 0;\n\n let result = state;\n\n if (hasGroupBy) {\n result = {\n ...state,\n columns: applyGroupByToColumns(result.columns, groupBy, confirmed),\n };\n }\n\n if (hasSort) {\n result = {\n ...state,\n columns: applySortToColumns(result.columns, sort),\n };\n }\n\n if (hasFilter) {\n result = {\n ...state,\n columns: applyFilterToColumns(result.columns, filter),\n };\n } else if (result.columns.some(isFilteredColumn)) {\n result = {\n ...state,\n columns: stripFilterFromColumns(result.columns),\n };\n }\n\n return result;\n}\n\nfunction replaceColumn(\n state: KeyedColumnDescriptor[],\n column: KeyedColumnDescriptor\n) {\n return state.map((col) => (col.name === column.name ? column : col));\n}\n", "import { useCallback, useRef } from \"react\";\n\nexport type ScrollDirectionVertical = \"up\" | \"down\";\nexport type ScrollDirectionHorizontal = \"left\" | \"right\";\nexport type ScrollDirection =\n | ScrollDirectionVertical\n | ScrollDirectionHorizontal;\n\nexport interface ScrollRequestEnd {\n type: \"scroll-end\";\n direction: \"home\" | \"end\";\n}\n\nexport interface ScrollRequestPage {\n type: \"scroll-page\";\n direction: ScrollDirectionVertical;\n}\n\nexport interface ScrollRequestDistance {\n direction: ScrollDirection;\n type: \"scroll-distance\";\n distance: number;\n}\n\nexport type ScrollRequest =\n | ScrollRequestPage\n | ScrollRequestDistance\n | ScrollRequestEnd;\n\nexport type ScrollRequestHandler = (request: ScrollRequest) => void;\n\nconst getPctScroll = (container: HTMLElement) => {\n const { scrollLeft, scrollTop } = container;\n const { clientHeight, clientWidth, scrollHeight, scrollWidth } = container;\n const pctScrollLeft = scrollLeft / (scrollWidth - clientWidth);\n const pctScrollTop = scrollTop / (scrollHeight - clientHeight);\n return [pctScrollLeft, pctScrollTop];\n};\n\ninterface CallbackRefHookProps<T = HTMLElement> {\n onAttach?: (el: T) => void;\n onDetach: (el: T) => void;\n label?: string;\n}\n\nconst useCallbackRef = <T = HTMLElement>({\n onAttach,\n onDetach,\n}: CallbackRefHookProps<T>) => {\n const ref = useRef<T | null>(null);\n const callbackRef = useCallback(\n (el: T | null) => {\n if (el) {\n ref.current = el;\n onAttach?.(el);\n } else if (ref.current) {\n const { current: originalRef } = ref;\n ref.current = el;\n onDetach?.(originalRef);\n }\n },\n [onAttach, onDetach]\n );\n return callbackRef;\n};\n\nexport interface TableScrollHookProps {\n maxScrollLeft: number;\n maxScrollTop: number;\n onHorizontalScroll?: (scrollLeft: number) => void;\n onVerticalScroll?: (scrollTop: number, pctScrollTop: number) => void;\n rowHeight: number;\n viewportRowCount: number;\n}\n\nexport const useTableScroll = ({\n maxScrollLeft,\n maxScrollTop,\n onHorizontalScroll,\n onVerticalScroll,\n rowHeight,\n viewportRowCount,\n}: TableScrollHookProps) => {\n const contentContainerScrolledRef = useRef(false);\n const scrollPosRef = useRef({ scrollTop: 0, scrollLeft: 0 });\n const scrollbarContainerRef = useRef<HTMLDivElement | null>(null);\n const contentContainerRef = useRef<HTMLDivElement | null>(null);\n\n const handleScrollbarContainerScroll = useCallback(() => {\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n const { current: contentContainerScrolled } = contentContainerScrolledRef;\n if (contentContainerScrolled) {\n contentContainerScrolledRef.current = false;\n } else if (contentContainer && scrollbarContainer) {\n const [pctScrollLeft, pctScrollTop] = getPctScroll(scrollbarContainer);\n const rootScrollLeft = Math.round(pctScrollLeft * maxScrollLeft);\n const rootScrollTop = Math.round(pctScrollTop * maxScrollTop);\n contentContainer.scrollTo({\n left: rootScrollLeft,\n top: rootScrollTop,\n behavior: \"auto\",\n });\n }\n }, [maxScrollLeft, maxScrollTop]);\n\n const handleContentContainerScroll = useCallback(() => {\n const { current: contentContainer } = contentContainerRef;\n const { current: scrollbarContainer } = scrollbarContainerRef;\n const { current: scrollPos } = scrollPosRef;\n\n if (contentContainer && scrollbarContainer) {\n const { scrollLeft, scrollTop } = contentContainer;\n const [pctScrollLeft, pctScrollTop] = getPctScroll(contentContainer);\n contentContainerScrolledRef.current = true;\n\n scrollbarContainer.scrollLeft = Math.round(pctScrollLeft * maxScrollLeft);\n scrollbarContainer.scrollTop = Math.round(pctScrollTop * maxScrollTop);\n\n if (scrollPos.scrollTop !== scrollTop) {\n scrollPos.scrollTop = scrollTop;\n onVerticalScroll?.(scrollTop, pctScrollTop);\n }\n if (scrollPos.scrollLeft !== scrollLeft) {\n scrollPos.scrollLeft = scrollLeft;\n onHorizontalScroll?.(scrollLeft);\n }\n }\n }, [maxScrollLeft, maxScrollTop, onHorizontalScroll, onVerticalScroll]);\n\n const handleAttachScrollbarContainer = useCallback(\n (el: HTMLDivElement) => {\n scrollbarContainerRef.current = el;\n el.addEventListener(\"scroll\", handleScrollbarContainerScroll, {\n passive: true,\n });\n },\n [handleScrollbarContainerScroll]\n );\n\n const handleDetachScrollbarContainer = useCallback(\n (el: HTMLDivElement) => {\n scrollbarContainerRef.current = null;\n el.removeEventListener(\"scroll\", handleScrollbarContainerScroll);\n },\n [handleScrollbarContainerScroll]\n );\n\n const handleAttachContentContainer = useCallback(\n (el: HTMLDivElement) => {\n contentContainerRef.current = el;\n el.addEventListener(\"scroll\", handleContentContainerScroll, {\n passive: true,\n });\n },\n [handleContentContainerScroll]\n );\n\n const handleDetachContentContainer = useCallback(\n (el: HTMLDivElement) => {\n contentContainerRef.current = null;\n el.removeEventListener(\"scroll\", handleContentContainerScroll);\n },\n [handleContentContainerScroll]\n );\n\n const contentContainerCallbackRef = useCallbackRef({\n onAttach: handleAttachContentContainer,\n onDetach: handleDetachContentContainer,\n });\n\n const scrollbarContainerCallbackRef = useCallbackRef({\n onAttach: handleAttachScrollbarContainer,\n onDetach: handleDetachScrollbarContainer,\n });\n\n //TODO should this be async ?\n const requestScroll: ScrollRequestHandler = useCallback(\n (scrollRequest) => {\n const { current: scrollbarContainer } = contentContainerRef;\n if (scrollbarContainer) {\n const { scrollLeft, scrollTop } = scrollbarContainer;\n contentContainerScrolledRef.current = false;\n if (scrollRequest.type === \"scroll-distance\") {\n let newScrollLeft = scrollLeft;\n let newScrollTop = scrollTop;\n if (\n scrollRequest.direction === \"up\" ||\n scrollRequest.direction === \"down\"\n ) {\n newScrollTop = Math.min(\n Math.max(0, scrollTop + scrollRequest.distance),\n maxScrollTop\n );\n } else {\n newScrollLeft = Math.min(\n Math.max(0, scrollLeft + scrollRequest.distance),\n maxScrollLeft\n );\n }\n scrollbarContainer.scrollTo({\n top: newScrollTop,\n left: newScrollLeft,\n behavior: \"auto\",\n });\n } else if (scrollRequest.type === \"scroll-page\") {\n const { direction } = scrollRequest;\n const scrollBy =\n viewportRowCount * (direction === \"down\" ? rowHeight : -rowHeight);\n const newScrollTop = Math.min(\n Math.max(0, scrollTop + scrollBy),\n maxScrollTop\n );\n scrollbarContainer.scrollTo({\n top: newScrollTop,\n left: scrollLeft,\n behavior: \"auto\",\n });\n } else if (scrollRequest.type === \"scroll-end\") {\n const { direction } = scrollRequest;\n const scrollTo = direction === \"end\" ? maxScrollTop : 0;\n scrollbarContainer.scrollTo({\n top: scrollTo,\n left: scrollbarContainer.scrollLeft,\n behavior: \"auto\",\n });\n }\n }\n },\n [maxScrollLeft, maxScrollTop, rowHeight, viewportRowCount]\n );\n\n return {\n /** Ref to be assigned to ScrollbarContainer */\n scrollbarContainerRef: scrollbarContainerCallbackRef,\n /** Ref to be assigned to ContentContainer */\n contentContainerRef: contentContainerCallbackRef,\n /** Scroll the table */\n requestScroll,\n };\n};\n", "import { KeyedColumnDescriptor } from \"@vuu-ui/vuu-datagrid-types\";\nimport { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { RowAtPositionFunc } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useEffect, useRef } from \"react\";\nimport { ViewportMeasurements } from \"@vuu-ui/vuu-table\";\n\nexport interface VirtualViewportHookProps {\n columns: KeyedColumnDescriptor[];\n getRowAtPosition: RowAtPositionFunc;\n setRange: (range: VuuRange) => void;\n viewportMeasurements: ViewportMeasurements;\n}\n\nexport const useVirtualViewport = ({\n columns,\n getRowAtPosition,\n setRange,\n viewportMeasurements,\n}: VirtualViewportHookProps) => {\n const firstRowRef = useRef<number>(0);\n const { contentWidth, rowCount: viewportRowCount } = viewportMeasurements;\n\n const handleVerticalScroll = useCallback(\n (scrollTop: number) => {\n const firstRow = getRowAtPosition(scrollTop);\n if (firstRow !== firstRowRef.current) {\n firstRowRef.current = firstRow;\n setRange({ from: firstRow, to: firstRow + viewportRowCount });\n }\n },\n [getRowAtPosition, setRange, viewportRowCount]\n );\n\n useEffect(() => {\n const { current: from } = firstRowRef;\n const rowRange = { from, to: from + viewportRowCount };\n setRange(rowRange);\n }, [setRange, viewportRowCount]);\n\n return {\n onVerticalScroll: handleVerticalScroll,\n };\n};\n", "import {\n Dropdown,\n DropdownOpenKey,\n SelectionChangeHandler,\n} from \"@vuu-ui/vuu-ui-controls\";\nimport {\n isColumnTypeRenderer,\n isTypeDescriptor,\n registerComponent,\n} from \"@vuu-ui/vuu-utils\";\nimport { TableCellProps } from \"@vuu-ui/vuu-datagrid-types\";\n// import { dispatchCommitEvent } from \"@vuu-ui/vuu-ui-controls\";\n\nimport \"./DropdownCell.css\";\nimport { useCallback, useState } from \"react\";\n\nconst classBase = \"vuuTableDropdownCell\";\n\nconst openKeys: DropdownOpenKey[] = [\"Enter\", \" \"];\n\nexport const DropdownCell = ({ column, columnMap, row }: TableCellProps) => {\n const values =\n isTypeDescriptor(column.type) && isColumnTypeRenderer(column.type?.renderer)\n ? column.type?.renderer?.values\n : [];\n\n const dataIdx = columnMap[column.name];\n const [value, setValue] = useState(row[dataIdx]);\n\n const handleSelectionChange = useCallback<SelectionChangeHandler>(\n (evt, selectedItem) => {\n if (selectedItem) {\n setValue(selectedItem);\n // dispatchCommitEvent(evt.target as HTMLElement);\n }\n },\n []\n );\n\n return (\n <Dropdown\n className={classBase}\n onSelectionChange={handleSelectionChange}\n openKeys={openKeys}\n selected={value}\n source={values}\n width={column.width - 17} // temp hack\n />\n );\n};\n\nregisterComponent(\"dropdown-cell\", DropdownCell, \"cell-renderer\", {});\n", "import { TableCellRendererProps } from \"@vuu-ui/vuu-datagrid-types\";\nimport { registerComponent } from \"@vuu-ui/vuu-utils\";\nimport { Input } from \"@salt-ds/core\";\nimport { useEditableText } from \"@vuu-ui/vuu-ui-controls\";\nimport cx from \"classnames\";\n// make sure all validators are loaded - how do we manage this ?\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { CaseValidator, PatternValidator } from \"@vuu-ui/vuu-table-extras\";\n\nimport \"./InputCell.css\";\n\nconst classBase = \"vuuTableInputCell\";\n\nconst WarnCommit = () => {\n console.warn(\n \"onCommit handler has not been provided to InputCell cell renderer\"\n );\n return true;\n};\nexport const InputCell = ({\n column,\n columnMap,\n onCommit = WarnCommit,\n row,\n}: TableCellRendererProps) => {\n const dataIdx = columnMap[column.name];\n const {\n align = \"left\",\n clientSideEditValidationCheck,\n valueFormatter,\n } = column;\n\n const { warningMessage, ...editProps } = useEditableText({\n initialValue: valueFormatter(row[dataIdx]),\n onCommit,\n clientSideEditValidationCheck,\n });\n\n const endAdornment =\n warningMessage && align === \"left\" ? (\n <span className={`${classBase}-icon`} data-icon=\"error\" />\n ) : undefined;\n\n const startAdornment =\n warningMessage && align === \"right\" ? (\n <span className={`${classBase}-icon`} data-icon=\"error\" />\n ) : undefined;\n\n return (\n <Input\n {...editProps}\n className={cx(classBase, {\n [`${classBase}-error`]: warningMessage !== undefined,\n })}\n endAdornment={endAdornment}\n startAdornment={startAdornment}\n />\n );\n};\n\nregisterComponent(\"input-cell\", InputCell, \"cell-renderer\", {});\n", "import { DataSourceConfig, SchemaColumn } from \"@vuu-ui/vuu-data\";\nimport { ColumnDescriptor, TableConfig } from \"@vuu-ui/vuu-datagrid-types\";\nimport { useLayoutProviderDispatch } from \"@vuu-ui/vuu-layout\";\nimport {\n ColumnSettingsProps,\n TableSettingsProps,\n} from \"@vuu-ui/vuu-table-extras\";\nimport { ColumnActionColumnSettings } from \"@vuu-ui/vuu-table/src/table-next/useTableModel\";\nimport { getCalculatedColumnType } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useRef, useState } from \"react\";\n\nexport interface TableAndColumnSettingsHookProps {\n availableColumns: SchemaColumn[];\n onAvailableColumnsChange?: (columns: SchemaColumn[]) => void;\n onConfigChange: (config: TableConfig) => void;\n onCreateCalculatedColumn: (column: ColumnDescriptor) => void;\n onDataSourceConfigChange: (dataSourceConfig: DataSourceConfig) => void;\n tableConfig: TableConfig;\n}\nexport const useTableAndColumnSettings = ({\n availableColumns: availableColumnsProps,\n onAvailableColumnsChange,\n onConfigChange,\n onCreateCalculatedColumn,\n onDataSourceConfigChange,\n tableConfig,\n}: TableAndColumnSettingsHookProps) => {\n const dispatchLayoutAction = useLayoutProviderDispatch();\n const showTableSettingsRef = useRef<() => void>();\n\n const [availableColumns, setAvailableColumns] = useState<SchemaColumn[]>(\n availableColumnsProps\n );\n\n const showContextPanel = useCallback(\n (\n componentType: string,\n title: string,\n props: TableSettingsProps | ColumnSettingsProps\n ) => {\n dispatchLayoutAction({\n type: \"set-props\",\n path: \"#context-panel\",\n props: {\n expanded: true,\n content: {\n type: componentType,\n props,\n },\n title,\n },\n });\n },\n [dispatchLayoutAction]\n );\n\n const handleCreateCalculatedColumn = useCallback(\n (column: ColumnDescriptor) => {\n const newAvailableColumns = availableColumns.concat({\n name: column.name,\n serverDataType: getCalculatedColumnType(column),\n });\n setAvailableColumns(newAvailableColumns);\n onAvailableColumnsChange?.(newAvailableColumns);\n requestAnimationFrame(() => {\n showTableSettingsRef.current?.();\n });\n onCreateCalculatedColumn(column);\n },\n [availableColumns, onAvailableColumnsChange, onCreateCalculatedColumn]\n );\n\n const showColumnSettingsPanel = useCallback(\n (action: ColumnActionColumnSettings) => {\n showContextPanel(\"ColumnSettings\", \"Column Settings\", {\n column: action.column,\n onConfigChange,\n onCreateCalculatedColumn: handleCreateCalculatedColumn,\n tableConfig,\n vuuTable: action.vuuTable,\n } as ColumnSettingsProps);\n },\n [\n handleCreateCalculatedColumn,\n onConfigChange,\n showContextPanel,\n tableConfig,\n ]\n );\n\n const handleAddCalculatedColumn = useCallback(() => {\n showColumnSettingsPanel({\n column: {\n name: \"::\",\n serverDataType: \"string\",\n },\n type: \"columnSettings\",\n vuuTable: { module: \"SIMUL\", table: \"instruments\" },\n });\n }, [showColumnSettingsPanel]);\n\n showTableSettingsRef.current = useCallback(() => {\n showContextPanel(\"TableSettings\", \"DataGrid Settings\", {\n availableColumns:\n availableColumns ??\n tableConfig.columns.map(({ name, serverDataType }) => ({\n name,\n serverDataType,\n })),\n onAddCalculatedColumn: handleAddCalculatedColumn,\n onConfigChange,\n onDataSourceConfigChange,\n tableConfig,\n } as TableSettingsProps);\n }, [\n availableColumns,\n handleAddCalculatedColumn,\n onConfigChange,\n onDataSourceConfigChange,\n showContextPanel,\n tableConfig,\n ]);\n\n return {\n showColumnSettingsPanel,\n showTableSettingsPanel: showTableSettingsRef.current,\n };\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["registerComponent", "isString", "isTypeDescriptor", "registerComponent", "isTypeDescriptor", "registerComponent", "isTypeDescriptor", "isValidNumber", "registerComponent", "cx", "jsx", "jsxs", "classBase", "isTypeDescriptor", "isValidNumber", "cx", "registerComponent", "DOWN1", "DOWN2", "isTypeDescriptor", "metadataKeys", "registerComponent", "UP1", "UP2", "cx", "getMovingValueDirection", "isTypeDescriptor", "isValidNumber", "useEffect", "useRef", "INITIAL_VALUE", "useDirection", "jsx", "jsxs", "CHAR_ARROW_UP", "CHAR_ARROW_DOWN", "KEY", "metadataKeys", "classBase", "FlashStyle", "getFlashStyle", "isTypeDescriptor", "BackgroundCell", "useDirection", "UP1", "UP2", "DOWN1", "DOWN2", "cx", "registerComponent", "cx", "jsx", "jsxs", "classBase", "cx", "name", "Button", "FormField", "FormFieldLabel", "FormField", "FormFieldLabel", "cx", "Switch", "useCallback", "jsx", "jsxs", "classBase", "jsx", "jsxs", "classBase", "FormField", "FormFieldLabel", "cx", "isColumnTypeRenderer", "isTypeDescriptor", "useCallback", "useMemo", "useRef", "useState", "col", "Dropdown", "FormField", "FormFieldLabel", "Input", "useCallback", "useRef", "EditorState", "EditorView", "useEffect", "useMemo", "useRef", "_expressions", "_op", "name", "useCallback", "makeSuggestions", "useCallback", "useRef", "useMemo", "source", "clearInput", "createState", "EditorState", "EditorView", "useEffect", "jsx", "classBase", "useCallback", "useRef", "createEl", "name", "findColumn", "useCallback", "name", "useRef", "setCalculatedColumnName", "useCallback", "useRef", "useState", "name", "jsx", "jsxs", "classBase", "useRef", "useCallback", "FormField", "FormFieldLabel", "Input", "Dropdown", "jsx", "jsxs", "classBase", "name", "FormField", "FormFieldLabel", "Button", "useEffect", "useState", "cx", "jsx", "jsxs", "classBase", "useState", "useEffect", "cx", "Button", "FormField", "FormFieldLabel", "Input", "ToggleButton", "ToggleButtonGroup", "useLayoutEffectSkipFirst", "useCallback", "useRef", "jsx", "isNumericColumn", "Button", "getColumnStyle", "isGroupColumn", "metadataKeys", "notHidden", "useCallback", "useMemo", "metadataKeys", "cx", "memo", "useCallback", "metadataKeys", "cx", "useCallback", "useRef", "useState", "jsx", "KEY", "metadataKeys", "useRef", "useState", "useCallback", "cx", "getColumnStyle", "metadataKeys", "useCallback", "jsx", "jsxs", "metadataKeys", "useCallback", "getColumnStyle", "jsx", "jsxs", "metadataKeys", "classBase", "memo", "cx", "useCallback", "cx", "useRef", "useCallback", "useRef", "jsx", "jsxs", "cx", "useCallback", "useRef", "cx", "jsx", "jsxs", "useContextMenu", "cx", "useCallback", "jsx", "jsx", "jsxs", "jsx", "jsxs", "metadataKeys", "buildColumnMap", "isJsonGroup", "metadataKeys", "moveItemDeprecated", "useCallback", "useEffect", "useMemo", "useRef", "useState", "metadataKeys", "useCallback", "useEffect", "useMemo", "useRef", "useState", "SELECTED", "useCallback", "useRef", "useCallback", "useEffect", "useMemo", "useRef", "isValidNumber", "useCallback", "useMemo", "useRef", "useState", "useCallback", "useEffect", "useRef", "metadataKeys", "useCallback", "useRef", "IDX", "getColumnName", "isGroupColumn", "isTypeDescriptor", "metadataKeys", "getDefaultAlignment", "metadataKeys", "useCallback", "useRef", "useCallback", "useMemo", "useRef", "useCallback", "useEffect", "useMemo", "useRef", "useState", "KEY", "IS_EXPANDED", "IS_LEAF", "metadataKeys", "cx", "jsx", "jsxs", "cx", "metadataKeys", "registerComponent", "jsx", "jsxs", "classBase", "IS_EXPANDED", "KEY", "metadataKeys", "cx", "registerComponent", "cx", "useRef", "useCallback", "useRef", "jsx", "useCallback", "useRef", "useState", "getColumnStyle", "cx", "useMemo", "classBase", "cx", "useCallback", "jsx", "jsxs", "jsx", "jsxs", "jsx", "jsxs", "jsx", "jsxs", "cx", "useCallback", "useRef", "useState", "jsx", "jsxs", "createElement", "useCallback", "useRef", "useContextMenu", "cx", "useCallback", "useRef", "useState", "jsx", "cx", "jsx", "jsxs", "ContextMenuProvider", "isGroupColumn", "metadataKeys", "notHidden", "cx", "useRef", "isGroupColumn", "isJsonColumn", "isJsonGroup", "metadataKeys", "notHidden", "RowSelected", "cx", "memo", "useCallback", "metadataKeys", "useCallback", "jsx", "IDX", "metadataKeys", "classBase", "TableCell", "name", "useCallback", "getGroupValueAndOffset", "metadataKeys", "useCallback", "cx", "jsx", "jsxs", "IS_LEAF", "metadataKeys", "classBase", "TableGroupCell", "getGroupValueAndOffset", "useCallback", "cx", "jsx", "createElement", "IDX", "IS_EXPANDED", "SELECTED", "metadataKeys", "classBase", "Row", "memo", "useCallback", "True", "First", "Last", "RowSelected", "cx", "isGroupColumn", "isJsonGroup", "notHidden", "isJsonColumn", "TableGroupCell", "TableCell", "useLayoutEffectSkipFirst", "useDragDrop", "useCallback", "useEffect", "useMemo", "useRef", "applySort", "buildColumnMap", "isGroupColumn", "isJsonGroup", "isValidNumber", "metadataKeys", "updateColumn", "visibleColumnAtIndex", "useCallback", "useEffect", "useMemo", "useState", "isVuuFeatureAction", "isVuuFeatureInvocation", "getFullRange", "useCallback", "useEffect", "useMemo", "useRef", "useState", "metadataKeys", "WindowRange", "SELECTED", "useMemo", "useRef", "buildColumnMap", "useCallback", "usePopupContextMenu", "useCallback", "applyFilterToColumns", "applyGroupByToColumns", "applySortToColumns", "getCellRenderer", "getTableHeadings", "getValueFormatter", "isFilteredColumn", "isGroupColumn", "isPinned", "isTypeDescriptor", "metadataKeys", "sortPinnedColumns", "stripFilterFromColumns", "useReducer", "KEY_OFFSET", "metadataKeys", "useCallback", "useRef", "useCallback", "useEffect", "useRef", "KEY", "IS_EXPANDED", "IS_LEAF", "metadataKeys", "jsx", "jsxs", "createElement", "IDX", "RENDER_IDX", "metadataKeys", "Dropdown", "isColumnTypeRenderer", "isTypeDescriptor", "registerComponent", "useCallback", "useState", "jsx", "classBase", "isTypeDescriptor", "isColumnTypeRenderer", "Dropdown", "registerComponent", "registerComponent", "Input", "cx", "jsx", "classBase", "Input", "cx", "registerComponent", "isCalculatedColumn", "moveItem", "subscribedOnly", "useCallback", "useMemo", "useState", "name", "useLayoutEffectSkipFirst", "jsx", "jsxs", "classBase", "FormField", "FormFieldLabel", "ToggleButtonGroup", "ToggleButton", "Input", "Button", "getCalculatedColumnType", "useCallback", "useRef", "useState", "name"]
|
|
7
7
|
}
|