@deephaven/embed-grid 0.38.1 → 0.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App-c3f46fd0.js","sources":["../../../utils/src/ColorUtils.ts","../../../utils/src/DbNameValidator.ts","../../../utils/src/DOMUtils.ts","../../../utils/src/Pending.ts","../../../utils/src/ValidationError.ts","../../../filters/src/Utils.ts","../../../grid/src/errors/AssertionError.ts","../../../grid/src/errors/assertIsDefined.ts","../../../grid/src/errors/PasteError.ts","../../../grid/src/EditableGridModel.ts","../../../grid/src/ExpandableGridModel.ts","../../../grid/src/GridRange.ts","../../../grid/src/GridAxisRange.ts","../../../grid/src/GridUtils.ts","../../../grid/src/GridMetricCalculator.ts","../../../grid/src/GridTheme.ts","../../../grid/src/memoizeClear.ts","../../../grid/src/GridColorUtils.ts","../../../grid/src/GridMouseHandler.ts","../../../grid/src/mouse-handlers/GridSeparatorMouseHandler.ts","../../../grid/src/mouse-handlers/GridColumnSeparatorMouseHandler.ts","../../../grid/src/GridRenderer.ts","../../../grid/src/mouse-handlers/GridSelectionMouseHandler.ts","../../../grid/src/mouse-handlers/GridColumnMoveMouseHandler.ts","../../../grid/src/mouse-handlers/GridHorizontalScrollBarMouseHandler.ts","../../../grid/src/mouse-handlers/GridRowMoveMouseHandler.ts","../../../grid/src/mouse-handlers/GridRowSeparatorMouseHandler.ts","../../../grid/src/mouse-handlers/GridRowTreeMouseHandler.ts","../../../grid/src/mouse-handlers/GridScrollBarCornerMouseHandler.ts","../../../grid/src/mouse-handlers/GridVerticalScrollBarMouseHandler.ts","../../../grid/src/mouse-handlers/EditMouseHandler.ts","../../../grid/src/mouse-handlers/GridTokenMouseHandler.ts","../../../grid/src/KeyHandler.ts","../../../grid/src/key-handlers/SelectionKeyHandler.ts","../../../grid/src/key-handlers/TreeKeyHandler.ts","../../../grid/src/key-handlers/EditKeyHandler.ts","../../../grid/src/key-handlers/PasteKeyHandler.ts","../../../grid/src/CellInputField.tsx","../../../grid/src/ThemeContext.ts","../../../grid/src/Grid.tsx","../../../grid/src/GridModel.ts","../../../iris-grid/src/sidebar/conditional-formatting/ConditionalFormattingAPIUtils.ts","../../../iris-grid/src/sidebar/conditional-formatting/ConditionalFormattingUtils.ts","../../../iris-grid/src/IrisGridBottomBar.tsx","../../../iris-grid/src/PendingDataBottomBar.tsx","../../../iris-grid/src/sidebar/aggregations/AggregationOperation.ts","../../../iris-grid/src/sidebar/aggregations/AggregationUtils.ts","../../../iris-grid/src/sidebar/AdvancedSettingsType.ts","../../../iris-grid/src/sidebar/AdvancedSettings.ts","../../../iris-grid/src/ColumnHeaderGroup.ts","../../../iris-grid/src/IrisGridUtils.ts","../../../iris-grid/src/IrisGridCopyHandler.tsx","../../../iris-grid/src/FilterInputField.tsx","../../../iris-grid/src/key-handlers/CopyKeyHandler.ts","../../../iris-grid/src/IrisGridShortcuts.ts","../../../iris-grid/src/key-handlers/ReverseKeyHandler.ts","../../../iris-grid/src/key-handlers/ClearFilterKeyHandler.ts","../../../iris-grid/src/mousehandlers/IrisGridCellOverflowMouseHandler.ts","../../../iris-grid/src/mousehandlers/IrisGridColumnSelectMouseHandler.ts","../../../iris-grid/src/mousehandlers/IrisGridColumnTooltipMouseHandler.ts","../../../iris-grid/src/format-context-menus/CustomFormatAction.tsx","../../../iris-grid/src/format-context-menus/FormatContextMenuUtils.tsx","../../../iris-grid/src/format-context-menus/DateTimeFormatContextMenu.ts","../../../iris-grid/src/format-context-menus/DecimalFormatContextMenu.ts","../../../iris-grid/src/format-context-menus/IntegerFormatContextMenu.ts","../../../iris-grid/src/mousehandlers/IrisGridContextMenuHandler.tsx","../../../iris-grid/src/mousehandlers/IrisGridDataSelectMouseHandler.ts","../../../iris-grid/src/mousehandlers/IrisGridFilterMouseHandler.ts","../../../iris-grid/src/mousehandlers/IrisGridRowTreeMouseHandler.ts","../../../iris-grid/src/mousehandlers/IrisGridSortMouseHandler.ts","../../../iris-grid/src/mousehandlers/PendingMouseHandler.ts","../../../iris-grid/src/mousehandlers/IrisGridTokenMouseHandler.ts","../../../iris-grid/src/ToastBottomBar.tsx","../../../iris-grid/src/IrisGridMetricCalculator.ts","../../../iris-grid/src/IrisGridModelUpdater.tsx","../../../iris-grid/src/IrisGridRenderer.ts","../../../iris-grid/src/IrisGridTheme.ts","../../../iris-grid/src/ColumnStatistics.tsx","../../../iris-grid/src/AdvancedFilterCreatorFilterItem.tsx","../../../iris-grid/src/AdvancedFilterCreatorSelectValueList.tsx","../../../iris-grid/src/AdvancedFilterCreatorSelectValue.tsx","../../../iris-grid/src/AdvancedFilterCreator.tsx","../../../iris-grid/src/sidebar/aggregations/Aggregations.tsx","../../../iris-grid/src/sidebar/aggregations/AggregationEdit.tsx","../../../iris-grid/src/sidebar/icons/BarIcon.tsx","../../../iris-grid/src/sidebar/icons/HistogramIcon.tsx","../../../iris-grid/src/sidebar/icons/LineIcon.tsx","../../../iris-grid/src/sidebar/icons/PieIcon.tsx","../../../iris-grid/src/sidebar/icons/ScatterIcon.tsx","../../../iris-grid/src/sidebar/icons/FormatColumnWhereIcon.tsx","../../../iris-grid/src/sidebar/icons/FormatRowWhereIcon.tsx","../../../iris-grid/src/sidebar/ChartBuilder.tsx","../../../iris-grid/src/sidebar/InputEditor.tsx","../../../iris-grid/src/sidebar/CustomColumnInput.tsx","../../../iris-grid/src/IrisGridModel.ts","../../../iris-grid/src/sidebar/CustomColumnBuilder.tsx","../../../iris-grid/src/sidebar/OptionType.ts","../../../iris-grid/src/sidebar/RollupRows.tsx","../../../iris-grid/src/sidebar/TableCsvExporter.tsx","../../../iris-grid/src/sidebar/TableSaver.tsx","../../../iris-grid/src/sidebar/visibility-ordering-builder/VisibilityOrderingGroup.tsx","../../../iris-grid/src/sidebar/visibility-ordering-builder/VisibilityOrderingItem.tsx","../../../iris-grid/src/sidebar/visibility-ordering-builder/sortable-tree/types.ts","../../../iris-grid/src/sidebar/visibility-ordering-builder/sortable-tree/utilities.ts","../../../iris-grid/src/sidebar/visibility-ordering-builder/sortable-tree/keyboardCoordinates.ts","../../../iris-grid/src/sidebar/visibility-ordering-builder/sortable-tree/PointerSensorWithInteraction.ts","../../../iris-grid/src/sidebar/visibility-ordering-builder/sortable-tree/TreeItem.tsx","../../../iris-grid/src/sidebar/visibility-ordering-builder/sortable-tree/SortableTreeItem.tsx","../../../iris-grid/src/sidebar/visibility-ordering-builder/sortable-tree/SortableTreeInner.tsx","../../../iris-grid/src/sidebar/visibility-ordering-builder/sortable-tree/SortableTree.tsx","../../../iris-grid/src/sidebar/visibility-ordering-builder/VisibilityOrderingBuilderUtils.ts","../../../iris-grid/src/sidebar/visibility-ordering-builder/VisibilityOrderingBuilder.tsx","../../../iris-grid/src/CrossColumnSearch.tsx","../../../iris-grid/src/PartitionSelectorSearch.tsx","../../../iris-grid/src/IrisGridPartitionSelector.tsx","../../../iris-grid/src/sidebar/SelectDistinctBuilder.tsx","../../../iris-grid/src/sidebar/AdvancedSettingsMenu.tsx","../../../iris-grid/src/sidebar/conditional-formatting/ConditionalFormattingMenu.tsx","../../../iris-grid/src/sidebar/conditional-formatting/ConditionEditor.tsx","../../../iris-grid/src/sidebar/conditional-formatting/StyleEditor.tsx","../../../iris-grid/src/sidebar/conditional-formatting/ColumnFormatEditor.tsx","../../../iris-grid/src/sidebar/conditional-formatting/RowFormatEditor.tsx","../../../iris-grid/src/sidebar/conditional-formatting/ConditionalFormatEditor.tsx","../../../console/src/monaco/lang/python.ts","../../../console/src/monaco/lang/groovy.ts","../../../console/src/monaco/lang/scala.ts","../../../console/src/monaco/lang/db.ts","../../../console/src/monaco/lang/log.ts","../../../console/src/monaco/MonacoUtils.ts","../../../console/src/notebook/Editor.tsx","../../../iris-grid/src/IrisGridCellOverflowModal.tsx","../../../iris-grid/src/GotoRow.tsx","../../../iris-grid/src/IrisGrid.tsx","../../../iris-grid/src/MissingKeyError.ts","../../../iris-grid/src/IrisGridTableModelTemplate.ts","../../../iris-grid/src/IrisGridTableModel.ts","../../../iris-grid/src/IrisGridTreeTableModel.ts","../../../iris-grid/src/IrisGridProxyModel.ts","../../../iris-grid/src/IrisGridModelFactory.ts","../../../jsapi-shim/src/dh.ts","../../src/App.tsx"],"sourcesContent":["class ColorUtils {\n /**\n * THIS HAS POOR PERFORMANCE DUE TO DOM MANIPULATION\n * DO NOT USE HEAVILY\n * Checks if a background color is dark (i.e. should use a light foreground).\n *\n * @param background the background color\n */\n static isDark(background: string): boolean {\n const d = document.createElement('div');\n d.style.display = 'none';\n d.style.color = background;\n\n const computedColor = getComputedStyle(document.body.appendChild(d)).color;\n const colorTokens = computedColor.match(/\\d+/g);\n let color: number[] = [];\n\n if (colorTokens) {\n color = colorTokens.map(a => parseInt(a, 10));\n } else {\n throw new Error(`Invalid color received. Got ${computedColor}`);\n }\n document.body.removeChild(d);\n const brightness = ColorUtils.getBrightness(color);\n return brightness < 125;\n }\n\n // Note: leaving this as arbitrary length number[] in case of RGBA().\n static getBrightness(color: number[]): number {\n // http://www.w3.org/TR/AERT#color-contrast\n return Math.round(\n (color[0] * 299 + color[1] * 587 + color[2] * 114) / 1000\n );\n }\n}\nexport default ColorUtils;\n","const TABLE_PREFIX = 'table_';\n\nconst COLUMN_PREFIX = 'column_';\n\n// From io.deephaven.db.tables.utils.DBNameValidator#DB_RESERVED_VARIABLE_NAMES\nconst DB_RESERVED_VARIABLE_NAMES = new Set(['in', 'not', 'i', 'ii', 'k']);\n\n// From javax.lang.model.SourceVersion#keywords\nconst JAVA_KEYWORDS = new Set([\n 'abstract',\n 'continue',\n 'for',\n 'new',\n 'switch',\n 'assert',\n 'default',\n 'if',\n 'package',\n 'synchronized',\n 'boolean',\n 'do',\n 'goto',\n 'private',\n 'this',\n 'break',\n 'double',\n 'implements',\n 'protected',\n 'throw',\n 'byte',\n 'else',\n 'import',\n 'public',\n 'throws',\n 'case',\n 'enum',\n 'instanceof',\n 'return',\n 'transient',\n 'catch',\n 'extends',\n 'int',\n 'short',\n 'try',\n 'char',\n 'final',\n 'interface',\n 'static',\n 'void',\n 'class',\n 'finally',\n 'long',\n 'strictfp',\n 'volatile',\n 'const',\n 'float',\n 'native',\n 'super',\n 'while',\n 'null',\n 'true',\n 'false',\n]);\n\n// From io.deephaven.db.tables.utils.DBNameValidator#STERILE_TABLE_AND_NAMESPACE_REGEX\nconst STERILE_TABLE_AND_NAMESPACE_REGEX = /[^a-zA-Z0-9_$+@-]/g;\n\n// From io.deephaven.db.tables.utils.DBNameValidator#STERILE_COLUMN_AND_QUERY_REGEX\nconst STERILE_COLUMN_AND_QUERY_REGEX = /[^A-Za-z0-9_$]/g;\n\n/**\n * Similar to DBNameValidator.java, this class has utilities for validating and legalizing\n * Table and Column names.\n */\nclass DbNameValidator {\n static legalize = (\n name: string,\n prefix: string,\n regex: RegExp,\n checkReserved: boolean,\n i: number\n ): string => {\n // Replace all dashes and spaces with underscores\n let legalName = name.trim().replace(/[- ]/g, '_');\n\n // Add prefix to reserved names\n if (\n checkReserved &&\n (DB_RESERVED_VARIABLE_NAMES.has(legalName) ||\n JAVA_KEYWORDS.has(legalName))\n ) {\n legalName = prefix + legalName;\n }\n\n // Remove illegal characters\n legalName = legalName.replace(regex, '');\n\n // Check if the name ended up blank\n if (!legalName) {\n legalName = prefix + i;\n }\n\n // If name starts with a number, append prefix to the front\n if (!Number.isNaN(Number(legalName.charAt(0)))) {\n legalName = prefix + legalName;\n }\n\n return legalName;\n };\n\n static legalizeTableName = (name: string): string =>\n DbNameValidator.legalize(\n name,\n TABLE_PREFIX,\n STERILE_TABLE_AND_NAMESPACE_REGEX,\n false,\n 0\n );\n\n static legalizeColumnNames = (headers: string[]): string[] => {\n const legalHeaders: string[] = [];\n headers.forEach((header, i) => {\n let legalHeader = DbNameValidator.legalizeColumnName(header, i);\n\n // Check if the name is already in use\n if (legalHeaders.includes(legalHeader)) {\n legalHeader = COLUMN_PREFIX + i;\n }\n\n legalHeaders.push(legalHeader);\n });\n return legalHeaders;\n };\n\n static legalizeColumnName = (header: string, i = 0): string =>\n // Replace all dashes and spaces with underscores\n DbNameValidator.legalize(\n header,\n COLUMN_PREFIX,\n STERILE_COLUMN_AND_QUERY_REGEX,\n true,\n i\n );\n\n static isValidTableName = (name: string): boolean =>\n DbNameValidator.legalizeTableName(name) === name;\n\n static isValidColumnName = (name: string): boolean =>\n DbNameValidator.legalizeColumnName(name) === name;\n}\n\nexport default DbNameValidator;\n","/**\n * Find the first element that matches the given className\n * by testing the element itself and traversing up\n * through its ancestors in the DOM tree.\n *\n * @param element Starting element\n * @param className Class name without the '.'\n * @returns DOM element matching the given class or null if not found\n */\n\nexport function getClosestByClassName(\n element: Element | null,\n className: string\n): Element | null {\n if (!element) {\n return null;\n }\n return element.closest(`.${className}`);\n}\n\nexport default { getClosestByClassName };\n","import { PromiseUtils, CancelablePromise } from './PromiseUtils';\n\n/**\n * Helper class for managing pending promises.\n * DH-6167 When cancel is called, it calls cancel on ALL promises, including ones that have already resolved.\n * This behaviour may change when DH-9464 is implemented.\n */\nclass Pending {\n pending: Array<CancelablePromise<unknown>> = [];\n\n resolved: Array<CancelablePromise<unknown>> = [];\n\n /**\n * Begins tracking a promise. After the promise has resolved, it's removed from tracking.\n * @param item Item to track.\n * @param cleanup The cleanup function to use when the promise is cancelled\n * @returns CancelablePromise Returns a cancelable promise.\n */\n add<T>(\n item: Promise<T> | T,\n cleanup?: (val: T) => void | null\n ): CancelablePromise<T> {\n const promise = PromiseUtils.makeCancelable(item, cleanup);\n this.pending.push(promise);\n promise.then(\n () => {\n this.resolve(promise);\n },\n () => {\n this.resolve(promise);\n }\n );\n return promise;\n }\n\n /**\n * Remove a promise from tracking.\n * @param promise Promise to stop tracking\n */\n remove(promise: CancelablePromise<unknown>): void {\n for (let i = 0; i < this.pending.length; i += 1) {\n if (this.pending[i] === promise) {\n this.pending.splice(i, 1);\n return;\n }\n }\n }\n\n resolve(promise: CancelablePromise<unknown>): void {\n this.remove(promise);\n this.resolved.push(promise);\n }\n\n /**\n * Cancel all pending promises and remove them from tracking.\n */\n cancel(): void {\n const allPromises = [...this.pending, ...this.resolved];\n for (let i = 0; i < allPromises.length; i += 1) {\n allPromises[i].cancel();\n }\n this.pending = [];\n this.resolved = [];\n }\n}\n\nexport default Pending;\n","class ValidationError extends Error {\n isInvalid = true;\n}\n\nexport default ValidationError;\n","import { Type, TypeValue } from './Type';\n\nexport function getLabelForTextFilter(filterType: TypeValue): string {\n switch (filterType) {\n case Type.eq:\n return 'is exactly';\n case Type.eqIgnoreCase:\n return 'is exactly (ignore case)';\n case Type.notEq:\n return 'is not exactly';\n case Type.notEqIgnoreCase:\n return 'is not exactly (ignore case)';\n case Type.contains:\n return 'contains';\n case Type.notContains:\n return 'does not contain';\n case Type.startsWith:\n return 'starts with';\n case Type.endsWith:\n return 'ends with';\n default:\n throw new Error(`Unrecognized text filter type ${filterType}`);\n }\n}\n\nexport function getLabelForNumberFilter(filterType: TypeValue): string {\n switch (filterType) {\n case Type.eq:\n return 'is equal to';\n case Type.notEq:\n return 'is not equal to';\n case Type.greaterThan:\n return 'greater than';\n case Type.greaterThanOrEqualTo:\n return 'greater than or equal to';\n case Type.lessThan:\n return 'less than';\n case Type.lessThanOrEqualTo:\n return 'less than or equal to';\n default:\n throw new Error(`Unrecognized number filter type ${filterType}`);\n }\n}\n\nexport function getLabelForDateFilter(filterType: TypeValue): string {\n switch (filterType) {\n case Type.eq:\n return 'date is';\n case Type.notEq:\n return 'date is not';\n case Type.notEqIgnoreCase:\n case Type.greaterThan:\n return 'date is after';\n case Type.greaterThanOrEqualTo:\n return 'date is after or equal';\n case Type.lessThan:\n return 'date is before';\n case Type.lessThanOrEqualTo:\n return 'date is before or equal';\n default:\n throw new Error(`Unrecognized date filter type ${filterType}`);\n }\n}\n\nexport function getLabelForBooleanFilter(filterType: TypeValue): string {\n switch (filterType) {\n case Type.isTrue:\n return 'Is True';\n case Type.isFalse:\n return 'Is False';\n case Type.isNull:\n return 'Is Null';\n default:\n throw new Error(`Unrecognized boolean filter type ${filterType}`);\n }\n}\n","export class AssertionError extends Error {\n isAssertionFailed = true;\n}\n\nexport default AssertionError;\n","import AssertionError from './AssertionError';\n\nexport function assertIsDefined<T>(val: T): asserts val is NonNullable<T> {\n if (val === undefined || val === null) {\n throw new AssertionError(\n `Expected 'val' to be defined, but received ${val}`\n );\n }\n}\n\nexport default assertIsDefined;\n","export class PasteError extends Error {\n isPasteError = true;\n}\n\nexport default PasteError;\n","import GridRange from './GridRange';\nimport { ModelIndex } from './GridMetrics';\nimport GridModel from './GridModel';\nimport { AssertionError } from './errors';\n\nexport function isEditableGridModel(\n model: GridModel\n): model is EditableGridModel {\n return (model as EditableGridModel)?.isEditable !== undefined;\n}\n\nexport function assertIsEditableGridModel(\n model: GridModel\n): asserts model is EditableGridModel {\n if (!isEditableGridModel(model)) {\n throw new AssertionError(\n `Expected 'model' to be editable, but received ${model}`\n );\n }\n}\n\n/**\n * Edit operation when applying multiple edits\n */\nexport type EditOperation = {\n /** Column to set the value for */\n column: ModelIndex;\n\n /** Row to set the value for */\n row: ModelIndex;\n\n /** Text value to set */\n text: string;\n\n /** @deprecated use `column` instead */\n x?: ModelIndex;\n /** @deprecated use `row` instead */\n y?: ModelIndex;\n};\n\n/**\n * Model for an editable grid\n */\nexport interface EditableGridModel extends GridModel {\n isEditable: boolean;\n\n /**\n * Check if a given range is editable\n * @param range The range to check if it is editable\n * @returns True if the range is editable\n */\n isEditableRange(range: GridRange): boolean;\n\n /**\n * Get the edit text for a cell as a string\n * @param column Column to get\n * @param row Row to get\n * @returns The value to use for editing\n */\n editValueForCell(column: ModelIndex, row: ModelIndex): string;\n\n /**\n * Set value in an editable table\n * @param column Column to set\n * @param row Row to set\n * @param value The value to set\n * @returns A promise that resolves successfully when the operation is complete, or rejects if there's an error\n */\n setValueForCell(\n column: ModelIndex,\n row: ModelIndex,\n value: string\n ): Promise<void>;\n\n /**\n * Set value in an editable table\n * @param ranges The ranges to set\n * @param value The value to set\n * @returns A promise that resolves successfully when the operation is complete, or rejects if there's an error\n */\n setValueForRanges(ranges: readonly GridRange[], value: string): Promise<void>;\n\n /**\n * Apply edits to the model\n * @param edits Edits to apply to the model\n * @returns A promise that resolves successfully when the operation is complete or rejects if there's an error\n */\n setValues(edits: readonly EditOperation[]): Promise<void>;\n\n /**\n * Check if a text value is a valid edit for a cell\n * @param column Column to check\n * @param row Row to check\n * @param value Value to check if it's a valid value or not\n * @returns True if it's a valid value, false otherwise\n */\n isValidForCell(column: ModelIndex, row: ModelIndex, value: string): boolean;\n}\n\nexport default EditableGridModel;\n","import GridModel from './GridModel';\nimport { ModelIndex } from './GridMetrics';\n\nexport function isExpandableGridModel(\n model: GridModel\n): model is ExpandableGridModel {\n return (model as ExpandableGridModel)?.hasExpandableRows !== undefined;\n}\n\n/**\n * Expandable grid model. Allows for a grid with rows that can expand (e.g. A Tree Table)\n */\nexport interface ExpandableGridModel extends GridModel {\n /** Whether the grid has rows that can be expanded */\n hasExpandableRows: boolean;\n\n /** Whether the grid can expand all */\n isExpandAllAvailable: boolean;\n\n /**\n * @param row Row to check\n * @returns True if the row is expandable\n */\n isRowExpandable(row: ModelIndex): boolean;\n\n /**\n * @param row Row to check\n * @returns True if the row is currently expanded\n */\n isRowExpanded(row: ModelIndex): boolean;\n\n /**\n * Change the expanded status of an expandable row\n * @param row Row to expand\n * @param isExpanded True to expand the row, false to collapse\n * @param expandDescendants True to expand nested rows, false otherwise\n */\n setRowExpanded(\n row: ModelIndex,\n isExpanded: boolean,\n expandDescendants?: boolean\n ): void;\n\n /**\n * Expand all rows\n */\n expandAll(): void;\n\n /**\n * Collapse all rows\n */\n collapseAll(): void;\n\n /**\n * Get the depth of a row (ie. How indented the row should be)\n * @param row Row to check\n * @returns Depth of the row\n */\n depthForRow(row: ModelIndex): number;\n}\n\nexport default ExpandableGridModel;\n","export type GridRangeIndex = number | null;\ntype LeftIndex = GridRangeIndex;\ntype RightIndex = GridRangeIndex;\ntype TopIndex = GridRangeIndex;\ntype BottomIndex = GridRangeIndex;\n\nexport type GridCell = { column: number; row: number };\n\nexport interface BoundedGridRange extends GridRange {\n startColumn: number;\n startRow: number;\n endColumn: number;\n endRow: number;\n}\n\n// Also exported via GridRange.SELECTION_DIRECTION\nexport enum SELECTION_DIRECTION {\n DOWN = 'DOWN',\n UP = 'UP',\n LEFT = 'LEFT',\n RIGHT = 'RIGHT',\n}\n\nexport class GridRange {\n startColumn: GridRangeIndex;\n\n startRow: GridRangeIndex;\n\n endColumn: GridRangeIndex;\n\n endRow: GridRangeIndex;\n\n static SELECTION_DIRECTION = SELECTION_DIRECTION;\n\n /**\n * Returns a normalized array of indexes ensuring left <= right and top <= bottom\n * @param startColumn Start column index\n * @param startRow Start row index\n * @param endColumn End column index\n * @param endRow End row index\n * @returns Array containing normalized indexes [left, top, right, bottom]\n */\n static normalize(\n startColumn: GridRangeIndex,\n startRow: GridRangeIndex,\n endColumn: GridRangeIndex,\n endRow: GridRangeIndex\n ): [LeftIndex, TopIndex, RightIndex, BottomIndex] {\n let left = startColumn;\n let top = startRow;\n let right = endColumn;\n let bottom = endRow;\n\n if (left != null && right != null && right < left) {\n left = right;\n right = startColumn;\n }\n\n if (top != null && bottom != null && bottom < top) {\n top = bottom;\n bottom = startRow;\n }\n\n return [left, top, right, bottom];\n }\n\n /**\n * Makes a GridRange ensuring startColumn <= endColumn, startRow <= endRow\n * @param startColumn Start column index\n * @param startRow Start row index\n * @param endColumn End column index\n * @param endRow End row index\n * @returns Normalized GridRange\n */\n static makeNormalized(\n startColumn: GridRangeIndex,\n startRow: GridRangeIndex,\n endColumn: GridRangeIndex,\n endRow: GridRangeIndex\n ): GridRange {\n return new GridRange(\n ...GridRange.normalize(startColumn, startRow, endColumn, endRow)\n );\n }\n\n /**\n * Creates a GridRange representing a single cell\n * @param column Column index\n * @param row Row index\n * @returns GridRange representing the cell\n */\n static makeCell(column: GridRangeIndex, row: GridRangeIndex): GridRange {\n return new GridRange(column, row, column, row);\n }\n\n /**\n * Creates a GridRange representing an infinite length column\n * @param column Column index\n * @returns GridRange representing the column\n */\n static makeColumn(column: GridRangeIndex): GridRange {\n return new GridRange(column, null, column, null);\n }\n\n /**\n * Creates a GridRange representing an infinite length row\n * @param row Row index\n * @returns GridRange representing the row\n */\n static makeRow(row: GridRangeIndex): GridRange {\n return new GridRange(null, row, null, row);\n }\n\n /**\n * Returns the minimum value between 2 range indexes or null if at least 1 is null\n * @param index1 First grid range index\n * @param index2 Second grid range index\n * @returns Minimum index or null if either index is null\n */\n static minOrNull(\n index1: GridRangeIndex,\n index2: GridRangeIndex\n ): number | null {\n if (index1 == null || index2 == null) {\n return null;\n }\n\n return Math.min(index1, index2);\n }\n\n /**\n * Returns the maximum value between 2 range indexes or null if at least 1 is null\n * @param index1 First grid range index\n * @param index2 Second grid range index\n * @returns Maximum index or null if either index is null\n */\n static maxOrNull(\n index1: GridRangeIndex,\n index2: GridRangeIndex\n ): number | null {\n if (index1 == null || index2 == null) {\n return null;\n }\n\n return Math.max(index1, index2);\n }\n\n /**\n * Consolidate the passed in ranges to the minimum set, merging overlapping ranges.\n * @param ranges The ranges to consolidate\n * @returns Consolidated ranges\n */\n static consolidate(ranges: readonly GridRange[]): GridRange[] {\n const result = ranges.slice();\n\n let wasModified = true;\n while (wasModified) {\n wasModified = false;\n for (let i = 0; i < result.length && !wasModified; i += 1) {\n const range = result[i];\n for (let j = result.length - 1; j > i; j -= 1) {\n const other = result[j];\n\n // If one contains the other, we can just keep the bigger one\n if (range.contains(other)) {\n result.splice(j, 1);\n } else if (other.contains(range)) {\n wasModified = true;\n result[i] = other;\n result.splice(j, 1);\n break;\n } else if (\n range.startRow === other.startRow &&\n range.endRow === other.endRow\n ) {\n if (range.touches(other)) {\n // If the start/end rows match, and columns touch, consolidate\n const { startRow, endRow } = range;\n const startColumn = GridRange.minOrNull(\n range.startColumn,\n other.startColumn\n );\n const endColumn = GridRange.maxOrNull(\n range.endColumn,\n other.endColumn\n );\n\n wasModified = true;\n result[i] = new GridRange(\n startColumn,\n startRow,\n endColumn,\n endRow\n );\n result.splice(j, 1);\n break;\n }\n } else if (\n range.startColumn === other.startColumn &&\n range.endColumn === other.endColumn\n ) {\n if (range.touches(other)) {\n // If the start/end rows match, and columns touch, consolidate\n const { startColumn, endColumn } = range;\n const startRow = GridRange.minOrNull(\n range.startRow,\n other.startRow\n );\n const endRow = GridRange.maxOrNull(range.endRow, other.endRow);\n\n wasModified = true;\n result[i] = new GridRange(\n startColumn,\n startRow,\n endColumn,\n endRow\n );\n result.splice(j, 1);\n break;\n }\n }\n }\n }\n }\n\n return result;\n }\n\n /**\n * Checks if the 1-D ranges between 2 index pairs overlap or are continuous.\n * For example ranges [0, 1] and [2, 3] are continuous and will return true.\n * [0, 1] and [1, 3] overlap and return true.\n * [0, 1] and [3, 4] do not overlap and have a gap so this will return false.\n * @param start1 Start of 1st range\n * @param end1 End of 1st range\n * @param start2 Start of 2nd range\n * @param end2 End of 2nd range\n * @returns True if the ranges overlap or touch, else false\n */\n static isAxisRangeTouching(\n start1: GridRangeIndex,\n end1: GridRangeIndex,\n start2: GridRangeIndex,\n end2: GridRangeIndex\n ): boolean {\n if (start1 == null) {\n if (end1 == null) {\n return true;\n }\n\n if (start2 == null) {\n return true;\n }\n\n return start2 <= end1 + 1;\n }\n\n if (end1 == null) {\n if (end2 == null) {\n return true;\n }\n\n return end2 >= start1 - 1;\n }\n\n if (start2 == null) {\n if (end2 == null) {\n return true;\n }\n\n return start1 <= end2 + 1;\n }\n\n if (end2 == null) {\n return end1 >= start2 - 1;\n }\n\n if (start2 >= start1 - 1) {\n return start2 <= end1 + 1;\n }\n\n return end2 >= start1 - 1;\n }\n\n /**\n * Checks if 2 arrays of ranges are the same ranges\n * @param ranges1 First array of ranges\n * @param ranges2 Second array of ranges\n * @returns True if the arrays contain the same ranges in the same order\n */\n static rangeArraysEqual(\n ranges1: readonly GridRange[],\n ranges2: readonly GridRange[]\n ): boolean {\n if (ranges1 === ranges2) {\n return true;\n }\n\n if (\n ranges1 == null ||\n ranges2 == null ||\n ranges1.length !== ranges2.length\n ) {\n return false;\n }\n\n for (let i = 0; i < ranges1.length; i += 1) {\n if (!ranges1[i].equals(ranges2[i])) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Get the intersection (overlapping area) of two ranges\n * @param range One range to check for the intersection\n * @param otherRange The other range to check for the intersection\n * @returns Intersection of the two ranges. If they do not intersect, returns `null`.\n */\n static intersection(\n range: GridRange,\n otherRange: GridRange\n ): GridRange | null {\n if (range.equals(otherRange)) {\n return range;\n }\n\n let { startColumn, startRow, endColumn, endRow } = range;\n startColumn =\n startColumn != null && otherRange.startColumn != null\n ? Math.max(startColumn, otherRange.startColumn)\n : startColumn ?? otherRange.startColumn;\n endColumn =\n endColumn != null && otherRange.endColumn != null\n ? Math.min(endColumn, otherRange.endColumn)\n : endColumn ?? otherRange.endColumn;\n startRow =\n startRow != null && otherRange.startRow != null\n ? Math.max(startRow, otherRange.startRow)\n : startRow ?? otherRange.startRow;\n endRow =\n endRow != null && otherRange.endRow != null\n ? Math.min(endRow, otherRange.endRow)\n : endRow ?? otherRange.endRow;\n\n if (\n (startColumn != null && startColumn > (endColumn ?? -1)) ||\n (startRow != null && startRow > (endRow ?? -1))\n ) {\n return null;\n }\n\n return new GridRange(startColumn, startRow, endColumn, endRow);\n }\n\n /**\n * Subtracts 1 range from another\n * @param range The range to be subtracted from\n * @param subtractRange The range to subtract from within this range\n * @returns The ranges needed to represent the remaining\n */\n static subtractFromRange(\n range: GridRange,\n subtractRange: GridRange\n ): GridRange[] {\n const result = [];\n\n // Make it a little easier by finding only the part the subtraction range intersects\n const subtract = GridRange.intersection(range, subtractRange);\n if (subtract == null) {\n return [range];\n }\n\n // Go through each of the quadrants for deselection, there can be up to 4\n // Top quadrant (above the subtracted area)\n if (\n subtract.startRow != null &&\n (range.startRow == null || range.startRow < subtract.startRow)\n ) {\n result.push(\n new GridRange(\n range.startColumn,\n range.startRow,\n range.endColumn,\n subtract.startRow - 1\n )\n );\n }\n\n // middle left\n if (\n subtract.startColumn != null &&\n (range.startColumn == null || range.startColumn < subtract.startColumn)\n ) {\n result.push(\n new GridRange(\n range.startColumn,\n subtract.startRow,\n subtract.startColumn - 1,\n subtract.endRow\n )\n );\n }\n\n // middle right\n if (\n subtract.endColumn != null &&\n (range.endColumn == null || range.endColumn > subtract.endColumn)\n ) {\n result.push(\n new GridRange(\n subtract.endColumn + 1,\n subtract.startRow,\n range.endColumn,\n subtract.endRow\n )\n );\n }\n\n // Bottom quadrant\n if (\n subtract.endRow != null &&\n (range.endRow == null || range.endRow > subtract.endRow)\n ) {\n result.push(\n new GridRange(\n range.startColumn,\n subtract.endRow + 1,\n range.endColumn,\n range.endRow\n )\n );\n }\n\n return result;\n }\n\n /**\n * Subtract a range from multiple ranges\n * @param ranges The ranges to be subtracted from\n * @param subtractRange The range to subtract from within these ranges\n * @returns The ranges needed to represent the remaining\n */\n static subtractFromRanges(\n ranges: readonly GridRange[],\n subtractRange: GridRange\n ): GridRange[] {\n const result: GridRange[] = [];\n for (let i = 0; i < ranges.length; i += 1) {\n result.push(...GridRange.subtractFromRange(ranges[i], subtractRange));\n }\n\n return result;\n }\n\n /**\n * Subtract multiple ranges from multiple ranges\n * @param ranges The ranges to be subtracted from\n * @param subtractRanges The ranges to subtract from within these ranges\n * @returns The ranges needed to represent the remaining\n */\n static subtractRangesFromRanges(\n ranges: readonly GridRange[],\n subtractRanges: readonly GridRange[]\n ): GridRange[] {\n let result = [...ranges];\n for (let i = 0; i < subtractRanges.length; i += 1) {\n result = GridRange.subtractFromRanges(result, subtractRanges[i]);\n }\n\n return result;\n }\n\n /**\n * Test if a given range is bounded (all values are non-null)\n * @param range The range to test\n * @returns True if this range is bounded, false otherwise\n */\n static isBounded(range: GridRange): range is BoundedGridRange {\n return (\n range.startRow != null &&\n range.startColumn != null &&\n range.endRow != null &&\n range.endColumn != null\n );\n }\n\n /**\n * Converts any GridRange passed in that is a full row or column selection to be bound\n * to the `columnCount` and `rowCount` passed in\n *\n * @param range The range to get the bounded range of\n * @param columnCount The number of columns\n * @param rowCount The number of rows\n * @returns The passed in GridRange with any null values filled in\n */\n static boundedRange(\n range: GridRange,\n columnCount: number,\n rowCount: number\n ): GridRange {\n if (GridRange.isBounded(range)) {\n return range;\n }\n\n return new GridRange(\n range.startColumn ?? 0,\n range.startRow ?? 0,\n range.endColumn ?? columnCount - 1,\n range.endRow ?? rowCount - 1\n );\n }\n\n /**\n * Converts the GridRanges passed in to be bound to the `columnCount` and `rowCount` passed in\n *\n * @param ranges The ranges to get the bounded ranges of\n * @param columnCount The number of columns\n * @param rowCount The number of rows\n * @returns The passed in GridRange with any null values filled in\n */\n static boundedRanges(\n ranges: readonly GridRange[],\n columnCount: number,\n rowCount: number\n ): GridRange[] {\n return ranges.map(r => GridRange.boundedRange(r, columnCount, rowCount));\n }\n\n /**\n * Offsets a GridRange by the specified amount in the x and y directions\n *\n * @param range The range to offset\n * @param columnOffset The number of columns to offset\n * @param rowOffset The number of rows to offset\n * @returns The new grid range offset from the original\n */\n static offset(\n range: GridRange,\n columnOffset: number,\n rowOffset: number\n ): GridRange {\n return new GridRange(\n range.startColumn != null ? range.startColumn + columnOffset : null,\n range.startRow != null ? range.startRow + rowOffset : null,\n range.endColumn != null ? range.endColumn + columnOffset : null,\n range.endRow != null ? range.endRow + rowOffset : null\n );\n }\n\n /**\n * Get the next cell given the selected ranges and the current cell\n * @param ranges The selected bounded ranges within the grid\n * @param column The cursor column, or null if none focused\n * @param row The cursor row, or null if none focused\n * @param direction The direction in which to select next\n * @returns The next cell to focus, or null if there should be no more focus\n */\n static nextCell(\n ranges: readonly GridRange[],\n column: GridRangeIndex = null,\n row: GridRangeIndex = null,\n direction = GridRange.SELECTION_DIRECTION.DOWN\n ): GridCell | null {\n if (ranges.length === 0) {\n return null;\n }\n\n let rangeIndex = -1;\n if (column != null && row != null) {\n rangeIndex = ranges.findIndex(r => r.containsCell(column, row));\n\n if (rangeIndex >= 0) {\n const range = ranges[rangeIndex];\n const nextCell = range.nextCell(column, row, direction);\n if (nextCell != null) {\n return nextCell;\n }\n }\n }\n\n // Otherwise go to the start of the next range (could be same range if only one range)\n switch (direction) {\n case GridRange.SELECTION_DIRECTION.DOWN:\n case GridRange.SELECTION_DIRECTION.RIGHT: {\n const nextRangeIndex =\n rangeIndex < ranges.length - 1 ? rangeIndex + 1 : 0;\n const nextRange = ranges[nextRangeIndex];\n return nextRange.startCell(direction);\n }\n case GridRange.SELECTION_DIRECTION.LEFT:\n case GridRange.SELECTION_DIRECTION.UP: {\n const nextRangeIndex =\n rangeIndex > 0 ? rangeIndex - 1 : ranges.length - 1;\n const nextRange = ranges[nextRangeIndex];\n return nextRange.startCell(direction);\n }\n default:\n throw new Error(`Invalid direction: ${direction}`);\n }\n }\n\n /**\n * Count the number of cells in the provided grid ranges\n * @param ranges The ranges to count the rows of\n * @returns The number of cells in the ranges, or `NaN` if any of the ranges were unbounded\n */\n static cellCount(ranges: readonly GridRange[]): number {\n return ranges.reduce(\n (cellCount, range) =>\n cellCount +\n ((range.endRow ?? NaN) - (range.startRow ?? NaN) + 1) *\n ((range.endColumn ?? NaN) - (range.startColumn ?? NaN) + 1),\n 0\n );\n }\n\n /**\n * Count the number of rows in the provided grid ranges\n * @param ranges The ranges to count the rows of\n * @returns The number of rows in the ranges, or `NaN` if any of the ranges were unbounded\n */\n static rowCount(ranges: readonly GridRange[]): number {\n return ranges.reduce(\n (rowCount, range) =>\n rowCount + (range.endRow ?? NaN) - (range.startRow ?? NaN) + 1,\n 0\n );\n }\n\n /**\n * Count the number of columns in the provided grid ranges\n * @param ranges The ranges to count the columns of\n * @returns The number of columns in the ranges, or `NaN` if any of the ranges were unbounded\n */\n static columnCount(ranges: readonly GridRange[]): number {\n return ranges.reduce(\n (columnCount, range) =>\n columnCount + (range.endColumn ?? NaN) - (range.startColumn ?? NaN) + 1,\n 0\n );\n }\n\n /**\n * Check if the provided ranges contain the provided cell\n * @param ranges The ranges to check\n * @param column The column index\n * @param row The row index\n * @returns True if the cell is within the provided ranges, false otherwise.\n */\n static containsCell(\n ranges: readonly GridRange[],\n column: GridRangeIndex,\n row: GridRangeIndex\n ): boolean {\n for (let i = 0; i < ranges.length; i += 1) {\n const range = ranges[i];\n if (range.containsCell(column, row)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Iterate through each cell in the provided ranges\n * @param ranges The ranges to iterate through\n * @param {(column: number, row: number, index: number) => void} callback The callback to execute. `index` is the index within that range\n * @param {GridRange.SELECTION_DIRECTION} direction The direction to iterate in\n */\n static forEachCell(\n ranges: readonly GridRange[],\n callback: (column: number, row: number, index: number) => void,\n direction = GridRange.SELECTION_DIRECTION.RIGHT\n ): void {\n for (let i = 0; i < ranges.length; i += 1) {\n ranges[i].forEach(callback, direction);\n }\n }\n\n constructor(\n startColumn: GridRangeIndex,\n startRow: GridRangeIndex,\n endColumn: GridRangeIndex,\n endRow: GridRangeIndex\n ) {\n this.startColumn = startColumn;\n this.startRow = startRow;\n this.endColumn = endColumn;\n this.endRow = endRow;\n }\n\n /**\n * Checks if the provided range is equivalent to this range (same start and end column/row indexes)\n * @param other Grid range to check against\n * @returns True if the ranges cover the same area\n */\n equals(other: GridRange): boolean {\n return (\n this.startColumn === other.startColumn &&\n this.startRow === other.startRow &&\n this.endColumn === other.endColumn &&\n this.endRow === other.endRow\n );\n }\n\n /**\n * Checks if this GridRange contains another range\n * @param other The range to check\n * @returns True if this GridRange completely contains `other`\n * */\n contains(other: GridRange): boolean {\n return (\n (this.startColumn == null ||\n (other.startColumn != null && this.startColumn <= other.startColumn)) &&\n (this.startRow == null ||\n (other.startRow != null && this.startRow <= other.startRow)) &&\n (this.endColumn == null ||\n (other.endColumn != null && this.endColumn >= other.endColumn)) &&\n (this.endRow == null ||\n (other.endRow != null && this.endRow >= other.endRow))\n );\n }\n\n /**\n * Check if the provided cell is in this range\n * @param column The column to check\n * @param row The row to check\n * @returns True if this cell is within this range\n */\n containsCell(column: GridRangeIndex, row: GridRangeIndex): boolean {\n if (column == null || row == null) {\n return false;\n }\n\n return (\n (this.startColumn == null || this.startColumn <= column) &&\n (this.endColumn == null || this.endColumn >= column) &&\n (this.startRow == null || this.startRow <= row) &&\n (this.endRow == null || this.endRow >= row)\n );\n }\n\n /**\n * Check if the provided range touches (or overlaps) this GridRange\n * Effectively checks if the 2 ranges could be represented by 1 continuous range\n * @param other The range to check\n * @returns True if this GridRange touches `other`\n * */\n touches(other: GridRange): boolean {\n return (\n GridRange.isAxisRangeTouching(\n this.startRow,\n this.endRow,\n other.startRow,\n other.endRow\n ) &&\n GridRange.isAxisRangeTouching(\n this.startColumn,\n this.endColumn,\n other.startColumn,\n other.endColumn\n )\n );\n }\n\n /**\n * Subtracts a range from this range\n * @param other The range to deselect from within this range\n * @returns The ranges needed to represent the remaining\n */\n subtract(other: GridRange): GridRange[] {\n return GridRange.subtractFromRange(this, other);\n }\n\n /**\n * Get the first cell in this range. Throws if this range is unbounded.\n *\n * @param direction The direction to get the starting cell in. Defaults to DOWN\n * @returns The first cell in this range in the direction specified\n */\n startCell(direction = GridRange.SELECTION_DIRECTION.DOWN): GridCell {\n if (!GridRange.isBounded(this)) {\n throw new Error('Cannot get the startCell of an unbounded range');\n }\n\n switch (direction) {\n case GridRange.SELECTION_DIRECTION.DOWN:\n case GridRange.SELECTION_DIRECTION.RIGHT:\n return { column: this.startColumn, row: this.startRow };\n case GridRange.SELECTION_DIRECTION.LEFT:\n case GridRange.SELECTION_DIRECTION.UP: {\n return { column: this.endColumn, row: this.endRow };\n }\n default:\n throw new Error(`Invalid direction: ${direction}`);\n }\n }\n\n /**\n * Get the next cell in the direction specified. Throws if this range is unbounded.\n * If already at the bounds of the range in that direction, wrap to the next column or row\n * If at the end of the entire range, return null\n * If outside of the range, returns the next cell closest within this range.\n *\n * @param column The cursor column\n * @param row The cursor row\n * @param direction The direction to go in\n * @returns The next cell in the direction specified, or `null` if at the end of the range\n */\n nextCell(\n column: GridRangeIndex,\n row: GridRangeIndex,\n direction: SELECTION_DIRECTION\n ): GridCell | null {\n if (!GridRange.isBounded(this)) {\n throw new Error('Bounded range required');\n }\n if (column == null || row == null) {\n throw new Error('Require a non-null cursor');\n }\n\n const { startColumn, endColumn, startRow, endRow } = this;\n\n switch (direction) {\n case GridRange.SELECTION_DIRECTION.DOWN:\n if (row < endRow) {\n return { column, row: Math.max(row + 1, startRow) };\n }\n\n if (column < endColumn) {\n return { column: Math.max(column + 1, startColumn), row: startRow };\n }\n break;\n case GridRange.SELECTION_DIRECTION.UP:\n if (row > startRow) {\n return { column, row: Math.min(row - 1, endRow) };\n }\n\n if (column > startColumn) {\n return { column: Math.min(column - 1, endColumn), row: endRow };\n }\n break;\n case GridRange.SELECTION_DIRECTION.RIGHT:\n if (column < endColumn) {\n return { column: Math.max(column + 1, startColumn), row };\n }\n\n if (row < endRow) {\n return { column: startColumn, row: Math.max(row + 1, startRow) };\n }\n break;\n case GridRange.SELECTION_DIRECTION.LEFT:\n if (column > startColumn) {\n return { column: Math.min(column - 1, endColumn), row };\n }\n\n if (row > startRow) {\n return { column: endColumn, row: Math.min(row - 1, endRow) };\n }\n break;\n default:\n throw new Error(`Invalid direction: ${direction}`);\n }\n\n return null;\n }\n\n /**\n * Iterate through each cell in the range\n * @param callback Callback to execute. `index` is the index within this range\n * @param direction The direction to iterate in\n */\n forEach(\n callback: (column: number, row: number, index: number) => void,\n direction = GridRange.SELECTION_DIRECTION.RIGHT\n ): void {\n let i = 0;\n let {\n column: c,\n row: r,\n }: { column?: number; row?: number } = this.startCell(direction);\n while (c != null && r != null) {\n callback(c, r, i);\n i += 1;\n\n ({ column: c, row: r } = this.nextCell(c, r, direction) ?? {});\n }\n }\n}\n\nexport default GridRange;\n","import type { GridRangeIndex } from './GridRange';\nimport type { VisibleIndex } from './GridMetrics';\n\nexport type Range<T> = [start: T, end: T];\n\nexport type AxisRange = Range<GridRangeIndex>;\nexport type BoundedAxisRange = Range<VisibleIndex>;\n\nexport function isAxisRange(range: unknown): range is AxisRange {\n return (\n Array.isArray(range) &&\n range.length === 2 &&\n (range[0] === null || typeof range[0] === 'number') &&\n (range[1] === null || typeof range[1] === 'number')\n );\n}\n\nexport function assertAxisRange(range: unknown): asserts range is AxisRange {\n if (!isAxisRange(range)) {\n throw new Error(`Expected axis range. Received: ${range}`);\n }\n}\n\nexport function isBoundedAxisRange(range: unknown): range is BoundedAxisRange {\n return isAxisRange(range) && range[0] != null && range[1] != null;\n}\n\nexport function assertBoundedAxisRange(\n range: unknown\n): asserts range is BoundedAxisRange {\n if (!isBoundedAxisRange(range)) {\n throw new Error(`Expected bounded axis range. Received: ${range}`);\n }\n}\n","import React from 'react';\nimport clamp from 'lodash.clamp';\nimport { find as linkifyFind } from 'linkifyjs';\nimport { EMPTY_ARRAY } from '@deephaven/utils';\nimport GridRange, { GridRangeIndex } from './GridRange';\nimport {\n BoxCoordinates,\n Coordinate,\n CoordinateMap,\n VisibleIndex,\n VisibleToModelMap,\n ModelIndex,\n ModelSizeMap,\n MoveOperation,\n SizeMap,\n} from './GridMetrics';\nimport type { GridMetrics } from './GridMetrics';\nimport { GridTheme } from './GridTheme';\nimport { GridWheelEvent } from './GridMouseHandler';\nimport {\n AxisRange,\n BoundedAxisRange,\n isBoundedAxisRange,\n Range,\n} from './GridAxisRange';\n\nexport type GridPoint = {\n x: Coordinate;\n y: Coordinate;\n column: GridRangeIndex;\n row: GridRangeIndex;\n columnHeaderDepth?: number;\n};\n\nexport interface CellInfo {\n row: VisibleIndex | null;\n column: VisibleIndex | null;\n modelRow: ModelIndex | null;\n modelColumn: ModelIndex | null;\n left: Coordinate | null;\n top: Coordinate | null;\n columnWidth: number | null;\n rowHeight: number | null;\n}\n\nexport type Token = {\n value: string;\n type: string;\n start: number;\n end: number;\n isLink?: boolean;\n};\nexport type LinkToken = Token & { href: string };\nexport type URLToken = Token & { type: 'url' };\nexport type EmailToken = Token & { type: 'email' };\n\nexport function isLinkToken(token: Token): token is LinkToken {\n return (token as LinkToken)?.href !== undefined;\n}\n\nexport type TokenBox = BoxCoordinates & { token: Token };\n\nexport type IndexCallback<T> = (itemIndex: VisibleIndex) => T | undefined;\n\nexport class GridUtils {\n // use same constant as chrome source for windows\n // https://github.com/chromium/chromium/blob/973af9d461b6b5dc60208c8d3d66adc27e53da78/ui/events/blink/web_input_event_builders_win.cc#L285\n static PIXELS_PER_LINE = 100 / 3;\n\n /**\n * Get the GridPoint for the coordinates provided\n * @param x The grid x coordinate\n * @param y The grid y coordinate\n * @param metrics The grid metrics\n * @returns The GridPoint including the column/row information\n */\n static getGridPointFromXY(\n x: Coordinate,\n y: Coordinate,\n metrics: GridMetrics\n ): GridPoint {\n const column = GridUtils.getColumnAtX(x, metrics);\n const row = GridUtils.getRowAtY(y, metrics);\n const columnHeaderDepth = GridUtils.getColumnHeaderDepthAtY(y, metrics);\n\n return { x, y, row, column, columnHeaderDepth };\n }\n\n static getCellInfoFromXY(\n x: Coordinate,\n y: Coordinate,\n metrics: GridMetrics\n ): CellInfo {\n const { row, column } = GridUtils.getGridPointFromXY(x, y, metrics);\n\n const {\n allColumnWidths,\n allRowHeights,\n allColumnXs,\n allRowYs,\n modelColumns,\n modelRows,\n } = metrics;\n\n const modelRow = row !== null ? modelRows.get(row) : null;\n const modelColumn = column !== null ? modelColumns.get(column) : null;\n const left = column !== null ? allColumnXs.get(column) : null;\n const top = row !== null ? allRowYs.get(row) : null;\n const columnWidth = column !== null ? allColumnWidths.get(column) : null;\n const rowHeight = row !== null ? allRowHeights.get(row) : null;\n\n return {\n row,\n column,\n modelRow: modelRow ?? null,\n modelColumn: modelColumn ?? null,\n left: left ?? null,\n top: top ?? null,\n columnWidth: columnWidth ?? null,\n rowHeight: rowHeight ?? null,\n };\n }\n\n static getColumnHeaderDepthAtY(\n y: Coordinate,\n metrics: GridMetrics\n ): number | undefined {\n const row = GridUtils.getRowAtY(y, metrics);\n const { columnHeaderHeight, columnHeaderMaxDepth } = metrics;\n\n if (row === null && y <= columnHeaderHeight * columnHeaderMaxDepth) {\n return clamp(\n columnHeaderMaxDepth - Math.ceil(y / columnHeaderHeight),\n 0,\n columnHeaderMaxDepth - 1\n );\n }\n\n return undefined;\n }\n\n /**\n * Iterate through each floating item at the start and call a callback, returning the first result\n * @param start The count of floating items at the start\n * @param total The total number of items\n * @param callback Function to call for each item\n * @returns The result from the callback\n */\n static iterateFloatingStart<T>(\n start: number,\n total: number,\n callback: IndexCallback<T>\n ): T | undefined {\n for (let i = 0; i < start && i < total; i += 1) {\n const result = callback(i);\n if (result !== undefined) {\n return result;\n }\n }\n\n return undefined;\n }\n\n /**\n * Iterate through floating items at the end. Iterates in increasing order.\n * @param end The count of floating items at the end\n * @param total The total number of items\n * @param callback Function to call for each item\n * @returns The result from the callback\n */\n static iterateFloatingEnd<T>(\n end: number,\n total: number,\n callback: IndexCallback<T>\n ): T | undefined {\n for (let i = 0; i < end && total - (end - i) >= 0; i += 1) {\n const result = callback(total - (end - i));\n if (result !== undefined) {\n return result;\n }\n }\n\n return undefined;\n }\n\n /**\n * Iterate through all floating items in increasing order, starting with the top items.\n * @param start Count of start floating rows, e.g. floatingTopRowCount\n * @param end Count of end floating rows, e.g. floatingBottomRowCount\n * @param total Total number of items\n * @param callback Callback called for each value, stopping the iterating and returning the value if one is returned\n */\n static iterateFloating<T>(\n start: number,\n end: number,\n total: number,\n callback: IndexCallback<T>\n ): T | undefined {\n const result = GridUtils.iterateFloatingStart(start, total, callback);\n if (result !== undefined) {\n return result;\n }\n return GridUtils.iterateFloatingEnd(end, total, callback);\n }\n\n /**\n * Iterate through all items in one dimension on the grid - first floating, then visible.\n * Call the callback for each item, break if a result is returned and return that result.\n * @param visibleStart Index of the start of the visible viewport\n * @param visibleEnd Index of the end of the visible viewport\n * @param floatingStartCount Number of items floating at the start\n * @param floatingEndCount Number of items floating at the end\n * @param totalCount Total number of items\n * @param callback Callback to call for each item\n * @returns The first result from the callback called, or undefined\n */\n static iterateAllItems<T>(\n visibleStart: VisibleIndex,\n visibleEnd: VisibleIndex,\n floatingStartCount: number,\n floatingEndCount: number,\n totalCount: number,\n callback: IndexCallback<T>\n ): T | undefined {\n const visibleStartIndex = Math.max(visibleStart, floatingStartCount);\n const visibleEndIndex = Math.min(\n visibleEnd,\n totalCount - floatingEndCount - 1\n );\n let result = GridUtils.iterateFloating(\n floatingStartCount,\n floatingEndCount,\n totalCount,\n callback\n );\n if (result !== undefined) {\n return result;\n }\n\n for (let i = visibleStartIndex; i <= visibleEndIndex; i += 1) {\n result = callback(i);\n if (result !== undefined) {\n return result;\n }\n }\n\n return undefined;\n }\n\n /**\n * Check if the coordinate is within the item specified in this dimension\n * @param itemIndex Index of the item to check\n * @param itemCoordinatess Coordinate of all items in this dimension\n * @param itemSizes Size of all items in this dimension\n * @param coordinate The coordinate to check\n * @returns True if the coordinate is within the item specified, false otherwise\n */\n static isInItem(\n itemIndex: VisibleIndex,\n itemCoordinates: CoordinateMap,\n itemSizes: SizeMap,\n coordinate: Coordinate\n ): boolean {\n const itemX = itemCoordinates.get(itemIndex) ?? 0;\n const itemSize = itemSizes.get(itemIndex) ?? 0;\n return itemX <= coordinate && coordinate <= itemX + itemSize;\n }\n\n /**\n * Get the Index of the item at the provided offset\n * @param offset Coordinate of the offset to get the item of\n * @param itemCount The total count of items\n * @param floatingStart Count of floating items at the start\n * @param floatingEnd Count of floating items at the end\n * @param items Index of all items\n * @param itemCoordinates The coordinate of each item\n * @param itemSizes The size of each item\n * @returns The item index, or null if no item matches\n */\n static getItemAtOffset(\n offset: Coordinate,\n itemCount: number,\n floatingStart: number,\n floatingEnd: number,\n items: readonly VisibleIndex[],\n itemCoordinates: CoordinateMap,\n itemSizes: SizeMap,\n ignoreFloating = false\n ): VisibleIndex | null {\n const floatingItem = ignoreFloating\n ? undefined\n : GridUtils.iterateFloating(\n floatingStart,\n floatingEnd,\n itemCount,\n item => {\n if (GridUtils.isInItem(item, itemCoordinates, itemSizes, offset)) {\n return item;\n }\n return undefined;\n }\n );\n if (!ignoreFloating && floatingItem !== undefined) {\n return floatingItem;\n }\n\n for (let i = 0; i < items.length; i += 1) {\n const item = items[i];\n if (GridUtils.isInItem(item, itemCoordinates, itemSizes, offset)) {\n return item;\n }\n }\n\n return null;\n }\n\n /**\n * Get the index of the column at the specified x coordinate\n * @param x Coordinate to get the item of\n * @param metrics Grid metrics\n * @returns Index of the column at that coordinate, or null if no column matches\n */\n static getColumnAtX(\n x: Coordinate,\n metrics: GridMetrics,\n ignoreFloating = false\n ): VisibleIndex | null {\n const {\n columnCount,\n floatingLeftColumnCount,\n floatingRightColumnCount,\n visibleColumns,\n allColumnXs,\n allColumnWidths,\n gridX,\n } = metrics;\n\n if (x < gridX) {\n return null;\n }\n\n return this.getItemAtOffset(\n x - gridX,\n columnCount,\n floatingLeftColumnCount,\n floatingRightColumnCount,\n visibleColumns,\n allColumnXs,\n allColumnWidths,\n ignoreFloating\n );\n }\n\n /**\n * Get the index of the row at the specified y coordinate\n * @param y Coordinate to get the item of\n * @param metrics Grid metrics\n * @returns Index of the row at that coordinate, or null if no row matches\n */\n static getRowAtY(y: Coordinate, metrics: GridMetrics): VisibleIndex | null {\n const {\n floatingTopRowCount,\n floatingBottomRowCount,\n rowCount,\n visibleRows,\n allRowYs,\n allRowHeights,\n gridY,\n } = metrics;\n\n if (y < gridY) {\n return null;\n }\n\n return this.getItemAtOffset(\n y - gridY,\n rowCount,\n floatingTopRowCount,\n floatingBottomRowCount,\n visibleRows,\n allRowYs,\n allRowHeights\n );\n }\n\n /**\n * Iterate backward through the visible items until a shown item is hit\n * @param startIndex The index to start from\n * @param modelIndexes The mapping of model indexes\n * @param visibleItems The visible items\n * @param userSizes The user set sizes\n * @returns Index of the next visible item, or null if no more are visible\n */\n static getNextShownItem(\n startIndex: VisibleIndex,\n modelIndexes: VisibleToModelMap,\n visibleItems: readonly VisibleIndex[],\n userSizes: ModelSizeMap\n ): VisibleIndex | null {\n let visibleItemIndex =\n visibleItems.findIndex(value => value === startIndex) || 0;\n visibleItemIndex -= 1;\n while (visibleItemIndex != null && visibleItemIndex >= 0) {\n const item = visibleItems[visibleItemIndex];\n const modelIndex = modelIndexes.get(item);\n if (modelIndex != null && userSizes.get(modelIndex) !== 0) {\n return item;\n }\n\n visibleItemIndex -= 1;\n }\n\n return null;\n }\n\n /**\n * Iterate backward through the visible columns until a shown column is hit\n * @param columnIndex The column index to start iterating backward from\n * @param metrics The GridMetricCalculator metrics\n * @returns Index of the next visible item, or null if no more are visible\n */\n static getNextShownColumn(\n startIndex: VisibleIndex,\n metrics: GridMetrics\n ): VisibleIndex | null {\n const { modelColumns, visibleColumns, userColumnWidths } = metrics;\n return GridUtils.getNextShownItem(\n startIndex,\n modelColumns,\n visibleColumns,\n userColumnWidths\n );\n }\n\n /**\n * Iterate backward through the visible rows until a shown row is hit\n * @param rowIndex The row index to start iterating backward from\n * @param metrics The GridMetricCalculator metrics\n * @returns Index of the next visible item, or null if no more are visible\n */\n static getNextShownRow(\n startIndex: VisibleIndex,\n metrics: GridMetrics\n ): VisibleIndex | null {\n const { modelRows, visibleRows, userRowHeights } = metrics;\n return GridUtils.getNextShownItem(\n startIndex,\n modelRows,\n visibleRows,\n userRowHeights\n );\n }\n\n /**\n * Gets the column index if the x/y coordinates provided are close enough to the separator, otherwise null\n * @param x Mouse x coordinate\n * @param y Mouse y coordinate\n * @param metrics The grid metrics\n * @param theme The grid theme with potential user overrides\n * @returns Index of the column separator at the coordinates provided, or null if none match\n */\n static getColumnSeparatorIndex(\n x: Coordinate,\n y: Coordinate,\n metrics: GridMetrics,\n theme: GridTheme\n ): VisibleIndex | null {\n const {\n rowHeaderWidth,\n columnHeaderHeight,\n floatingColumns,\n floatingLeftWidth,\n visibleColumns,\n allColumnXs,\n allColumnWidths,\n columnHeaderMaxDepth,\n } = metrics;\n const { allowColumnResize, headerSeparatorHandleSize } = theme;\n\n if (\n columnHeaderMaxDepth * columnHeaderHeight < y ||\n !allowColumnResize ||\n headerSeparatorHandleSize <= 0\n ) {\n return null;\n }\n\n const gridX = x - rowHeaderWidth;\n const halfSeparatorSize = headerSeparatorHandleSize * 0.5;\n\n // Iterate through the floating columns first since they're on top\n let isPreviousColumnHidden = false;\n for (let i = floatingColumns.length - 1; i >= 0; i -= 1) {\n const column = floatingColumns[i];\n const columnX = allColumnXs.get(column) ?? 0;\n const columnWidth = allColumnWidths.get(column) ?? 0;\n const isColumnHidden = columnWidth === 0;\n if (!isPreviousColumnHidden || !isColumnHidden) {\n let midX = columnX + columnWidth;\n if (isColumnHidden) {\n midX += halfSeparatorSize;\n } else if (isPreviousColumnHidden) {\n midX -= halfSeparatorSize;\n }\n\n const minX = midX - halfSeparatorSize;\n const maxX = midX + halfSeparatorSize;\n if (minX <= gridX && gridX <= maxX) {\n return column;\n }\n\n isPreviousColumnHidden = isColumnHidden;\n }\n }\n\n // Iterate backward so that you can reveal hidden columns properly\n isPreviousColumnHidden = false;\n for (let i = visibleColumns.length - 1; i >= 0; i -= 1) {\n const column = visibleColumns[i];\n const columnX = allColumnXs.get(column) ?? 0;\n const columnWidth = allColumnWidths.get(column) ?? 0;\n const isColumnHidden = columnWidth === 0;\n\n // If this column is under the floating columns \"layer\". Terminate early.\n if (columnX < floatingLeftWidth - columnWidth) {\n return null;\n }\n\n if (!isPreviousColumnHidden || !isColumnHidden) {\n let midX = columnX + columnWidth;\n if (isColumnHidden) {\n midX += halfSeparatorSize;\n } else if (isPreviousColumnHidden) {\n midX -= halfSeparatorSize;\n }\n\n const minX = midX - halfSeparatorSize;\n const maxX = midX + halfSeparatorSize;\n if (minX <= gridX && gridX <= maxX) {\n return column;\n }\n\n isPreviousColumnHidden = isColumnHidden;\n }\n }\n\n return null;\n }\n\n /**\n * Check if the item specified is hidden\n * @param itemIndex Index of the item to check\n * @param visibleSizes Sizes of all visible items\n * @returns True if the item is hidden, false otherwise\n */\n static isItemHidden(itemIndex: VisibleIndex, visibleSizes: SizeMap): boolean {\n return visibleSizes.get(itemIndex) === 0;\n }\n\n /**\n * Check if the column specified is hidden\n * @param columnIndex Index of the column to check\n * @param metrics Grid metrics\n * @returns True if the column is hidden, false otherwise\n */\n static isColumnHidden(\n columnIndex: VisibleIndex,\n metrics: GridMetrics\n ): boolean {\n const { allColumnWidths } = metrics;\n return GridUtils.isItemHidden(columnIndex, allColumnWidths);\n }\n\n /**\n * Check if the provided row is a floating row\n * @param row The row index to check\n * @param metrics The grid metrics to check against\n * @returns True if it's a floating row, false otherwise\n */\n static isFloatingRow(row: VisibleIndex, metrics: GridMetrics): boolean {\n if (row == null) {\n return false;\n }\n\n const { floatingTopRowCount, floatingBottomRowCount, rowCount } = metrics;\n return (\n row < floatingTopRowCount || row >= rowCount - floatingBottomRowCount\n );\n }\n\n /**\n * Check if the provided column is a floating column\n * @param column The column index to check\n * @param metrics The grid metrics to check against\n * @returns True if it's a floating column, false otherwise\n */\n static isFloatingColumn(column: VisibleIndex, metrics: GridMetrics): boolean {\n if (column == null) {\n return false;\n }\n\n const {\n floatingLeftColumnCount,\n floatingRightColumnCount,\n columnCount,\n } = metrics;\n return (\n column < floatingLeftColumnCount ||\n column >= columnCount - floatingRightColumnCount\n );\n }\n\n /**\n * Get all the items that are hidden under the same Index\n * E.g. If columns are 1, 2, 3, 4, 5, and column 2, 3, 4 are hidden, and we check for item 4, the return will be [2, 3, 4]\n * @param itemIndex Index of the item to start at\n * @param visibleSizes Visible size map\n * @param visibleItems Visible items\n * @returns Array of items that are hidden\n */\n static getHiddenItems(\n itemIndex: VisibleIndex,\n visibleSizes: SizeMap,\n visibleItems: readonly VisibleIndex[]\n ): VisibleIndex[] {\n if (!GridUtils.isItemHidden(itemIndex, visibleSizes)) {\n return [];\n }\n\n const hiddenItems = [itemIndex];\n const visibleItemIndex = visibleItems.findIndex(\n value => value === itemIndex\n );\n for (let i = visibleItemIndex - 1; i >= 0; i -= 1) {\n const item = visibleItems[i];\n if (!GridUtils.isItemHidden(item, visibleSizes)) {\n break;\n }\n\n hiddenItems.push(item);\n }\n\n return hiddenItems;\n }\n\n /**\n * Get all the columns that are hidden under the same Index\n * @param columnIndex Index of the item to start at\n * @param metrics Grid metrics\n * @returns Array of items that are hidden\n */\n static getHiddenColumns(\n columnIndex: VisibleIndex,\n metrics: GridMetrics\n ): VisibleIndex[] {\n const { visibleColumns, allColumnWidths } = metrics;\n return GridUtils.getHiddenItems(\n columnIndex,\n allColumnWidths,\n visibleColumns\n );\n }\n\n /**\n * Returns the row index if the x/y coordinates provided are close enough to the separator, otherwise null\n * @param x X coordinate to check\n * @param y Y coordinate to check\n * @param metrics The grid metrics\n * @param theme The grid theme\n * @returns Index of the row separator at the coordinates provided, or null if none match\n */\n static getRowSeparatorIndex(\n x: Coordinate,\n y: Coordinate,\n metrics: GridMetrics,\n theme: GridTheme\n ): VisibleIndex | null {\n const {\n rowHeaderWidth,\n columnHeaderHeight,\n visibleRows,\n allRowYs,\n allRowHeights,\n } = metrics;\n const { allowRowResize, headerSeparatorHandleSize } = theme;\n\n if (\n rowHeaderWidth < x ||\n !allowRowResize ||\n headerSeparatorHandleSize <= 0\n ) {\n return null;\n }\n\n const gridY = y - columnHeaderHeight;\n const halfSeparatorSize = headerSeparatorHandleSize * 0.5;\n\n // Iterate backward so you can reveal hidden rows properly\n let isPreviousRowHidden = false;\n for (let i = visibleRows.length - 1; i >= 0; i -= 1) {\n const row = visibleRows[i];\n const rowY = allRowYs.get(row) ?? 0;\n const rowHeight = allRowHeights.get(row) ?? 0;\n const isRowHidden = rowHeight === 0;\n if (!isPreviousRowHidden || !isRowHidden) {\n let midY = rowY + rowHeight;\n if (isRowHidden) {\n midY += halfSeparatorSize;\n } else if (isPreviousRowHidden) {\n midY -= halfSeparatorSize;\n }\n\n const minY = midY - halfSeparatorSize;\n const maxY = midY + halfSeparatorSize;\n\n if (minY <= gridY && gridY <= maxY) {\n return row;\n }\n\n isPreviousRowHidden = isRowHidden;\n }\n }\n\n return null;\n }\n\n /**\n * Check if the row specified is hidden\n * @param rowIndex Index of the row to check\n * @param metrics Grid metrics\n * @returns True if the row is hidden, false otherwise\n */\n static isRowHidden(rowIndex: VisibleIndex, metrics: GridMetrics): boolean {\n const { allRowHeights } = metrics;\n return GridUtils.isItemHidden(rowIndex, allRowHeights);\n }\n\n /**\n * Get all the rows that are hidden under the same Index\n * @param rowIndex Index of the item to start at\n * @param metrics Grid metrics\n * @returns Array of items that are hidden\n */\n static getHiddenRows(\n rowIndex: VisibleIndex,\n metrics: GridMetrics\n ): VisibleIndex[] {\n const { visibleRows, allRowHeights } = metrics;\n return GridUtils.getHiddenItems(rowIndex, allRowHeights, visibleRows);\n }\n\n /**\n * Set a new order for items in the grid\n * @param from The visible index to move from\n * @param to The visible index to move the item to\n * @param oldMovedItems The old reordered items\n * @returns The new reordered items\n */\n static moveItem(\n from: VisibleIndex,\n to: VisibleIndex,\n oldMovedItems: readonly MoveOperation[]\n ): MoveOperation[] {\n if (from === to) {\n return [...oldMovedItems];\n }\n\n const movedItems: MoveOperation[] = [...oldMovedItems];\n const lastMovedItem = movedItems[movedItems.length - 1];\n\n // Check if we should combine with the previous move\n // E.g. 1 -> 2, 2 -> 3 can just be 1 -> 3\n if (\n lastMovedItem != null &&\n !isBoundedAxisRange(lastMovedItem.from) &&\n lastMovedItem.to === from\n ) {\n // Remove the move if it is now a no-op\n if (lastMovedItem.from === to) {\n movedItems.pop();\n } else {\n movedItems[movedItems.length - 1] = {\n ...lastMovedItem,\n to,\n };\n }\n } else {\n movedItems.push({ from, to });\n }\n\n return movedItems;\n }\n\n /**\n * Move a visible range in the grid\n *\n * This will effectively slice the range out of the grid,\n * re-index the remaining columns,\n * then insert the range with the first element at the provided index\n *\n * @param from The visible axis range to move\n * @param to The visible index to move the start of the range to\n * @param oldMovedItems The old reordered items\n * @param isPreMoveTo If toParam is the index before the movement\n * If true, this will account for the shift when moving\n * a range before the drop positin\n * E.g. Move range [0, 2] 1 item down (after element 3)\n * The move is [0, 2] -> 1 if this is false. [0, 2] -> 3 if this is true\n * Both will result in [0, 2] -> 1\n * @returns The new reordered items\n */\n static moveRange(\n from: BoundedAxisRange,\n toParam: VisibleIndex,\n oldMovedItems: readonly MoveOperation[],\n isPreMoveTo = false\n ): MoveOperation[] {\n if (from[0] === from[1]) {\n return GridUtils.moveItem(from[0], toParam, oldMovedItems);\n }\n\n let to = toParam;\n\n if (isPreMoveTo && from[0] < toParam) {\n to -= from[1] - from[0];\n }\n\n if (from[0] === to) {\n return [...oldMovedItems];\n }\n\n const movedItems: MoveOperation[] = [...oldMovedItems];\n const lastMovedItem = movedItems[movedItems.length - 1];\n\n // Check if we should combine with the previous move\n // E.g. [1, 2] -> 2, [2, 3] -> 3 can just be [1, 2] -> 3\n if (\n lastMovedItem != null &&\n isBoundedAxisRange(lastMovedItem.from) &&\n lastMovedItem.from[1] - lastMovedItem.from[0] === from[1] - from[0] &&\n lastMovedItem.to === from[0]\n ) {\n movedItems[movedItems.length - 1] = {\n ...lastMovedItem,\n to,\n };\n } else {\n movedItems.push({ from, to });\n }\n\n const newLastMovedItem = movedItems[movedItems.length - 1];\n // Remove the move if it is now a no-op\n if (\n isBoundedAxisRange(newLastMovedItem.from) &&\n newLastMovedItem.from[0] === newLastMovedItem.to\n ) {\n movedItems.pop();\n }\n\n return movedItems;\n }\n\n static moveItemOrRange(\n from: VisibleIndex | BoundedAxisRange,\n to: VisibleIndex,\n oldMovedItems: MoveOperation[],\n isPreMoveTo = false\n ): MoveOperation[] {\n return Array.isArray(from)\n ? GridUtils.moveRange(from, to, oldMovedItems, isPreMoveTo)\n : GridUtils.moveItem(from, to, oldMovedItems);\n }\n\n /**\n * Applies the items moves to the AxisRange\n * @param start The start index of the range\n * @param end The end index of the range\n * @param movedItems The move operations to apply\n * @param reverse If the moved items should be applied in reverse (this reverses the effects of the moves)\n * @returns A list of AxisRanges in the translated space. Possibly multiple non-continuous ranges\n */\n static applyItemMoves<T extends number | GridRangeIndex>(\n start: T,\n end: T,\n movedItems: readonly MoveOperation[],\n reverse = false\n ): Range<T>[] {\n let result: Range<T>[] = [[start, end]];\n\n for (\n let i = reverse ? movedItems.length - 1 : 0;\n reverse ? i >= 0 : i < movedItems.length;\n reverse ? (i -= 1) : (i += 1)\n ) {\n const { from: fromItemOrRange, to: toItem } = movedItems[i];\n let length = 1;\n let fromItem: number;\n if (isBoundedAxisRange(fromItemOrRange)) {\n length = fromItemOrRange[1] - fromItemOrRange[0] + 1; // Ranges are inclusive\n [fromItem] = fromItemOrRange;\n } else {\n fromItem = fromItemOrRange;\n }\n\n const fromStart = reverse ? toItem : fromItem;\n const fromEnd = fromStart + length - 1;\n const toStart = reverse ? fromItem : toItem;\n const moveDistance = toStart - fromStart;\n\n const nextResult: Range<number>[] = [];\n for (let j = 0; j < result.length; j += 1) {\n const currentStart = result[j][0] ?? Number.NEGATIVE_INFINITY;\n const currentEnd = result[j][1] ?? Number.POSITIVE_INFINITY;\n\n let movedRange: Range<number> | undefined;\n const currentResult: Range<number>[] = [\n [currentStart, fromStart - 1],\n [fromStart, fromEnd],\n [fromEnd + 1, currentEnd],\n ]\n .map(\n ([s, e]): Range<number> => [\n // Cap the ranges to within the current range bounds\n Math.max(s, currentStart),\n Math.min(e, currentEnd),\n ]\n )\n .filter(([s, e]) => s <= e) // Remove invalid ranges\n .map(\n (range): Range<number> => {\n const [s, e] = range;\n if (fromStart <= s && fromEnd >= e) {\n // Current range in moved range\n movedRange = [s + moveDistance, e + moveDistance];\n return movedRange;\n }\n\n if (fromEnd < s) {\n // Current range is after moved range\n return [s - length, e - length];\n }\n return range;\n }\n )\n .map((range): Range<number>[] => {\n const [s, e] = range;\n if (toStart > s && toStart <= e) {\n // Moved range splits this range\n return [\n [s, toStart - 1],\n [toStart + length, e + length],\n ];\n }\n\n if (range === movedRange) {\n // Moved range has already been shifted\n return [range];\n }\n\n if (toStart <= s) {\n // Moved range shifts this range right\n return [[s + length, e + length]];\n }\n return [range];\n })\n .flat();\n\n nextResult.push(...currentResult);\n }\n\n // Return infinity values back to null\n result = nextResult.map(([s, e]) => [\n Number.isFinite(s) ? s : null,\n Number.isFinite(e) ? e : null,\n ]) as Range<T>[];\n }\n return result;\n }\n\n /**\n * Applies the items moves to the givengrid range\n * @param range The grid range to translate\n * @param movedColumns The moved columns\n * @param movedRows The moved rows\n * @param reverse If the moved items should be reversed (i.e. visible to model range)\n * @returns A list of grid ranges in the translated space. Possibly multiple non-continuous ranges\n */\n static translateRange(\n range: GridRange,\n movedColumns: readonly MoveOperation[],\n movedRows: readonly MoveOperation[],\n reverse: boolean\n ): GridRange[] {\n const columnRanges = GridUtils.applyItemMoves(\n range.startColumn,\n range.endColumn,\n movedColumns,\n reverse\n );\n const rowRanges = GridUtils.applyItemMoves(\n range.startRow,\n range.endRow,\n movedRows,\n reverse\n );\n const ranges: GridRange[] = [];\n for (let i = 0; i < columnRanges.length; i += 1) {\n const c = columnRanges[i];\n for (let j = 0; j < rowRanges.length; j += 1) {\n const r = rowRanges[j];\n ranges.push(new GridRange(c[0], r[0], c[1], r[1]));\n }\n }\n return ranges;\n }\n\n /**\n * Retrieve the model index given the currently moved items\n * @param visibleIndex The visible index of the item to get the model index for\n * @param movedItems The moved items\n * @returns The model index of the item\n */\n static getModelIndex(\n visibleIndex: VisibleIndex,\n movedItems: readonly MoveOperation[]\n ): ModelIndex {\n const modelIndex = GridUtils.applyItemMoves(\n visibleIndex,\n visibleIndex,\n movedItems,\n true\n )[0][0];\n\n return modelIndex;\n }\n\n /**\n * Retrieve the model indexes given the currently moved items\n * @param visibleIndexes The visible indexes of the item to get the model indexes for\n * @param movedItems The moved items\n * @returns The model indexes of the item\n */\n static getModelIndexes(\n visibleIndexes: ModelIndex[],\n movedItems: MoveOperation[]\n ): VisibleIndex[] {\n return visibleIndexes.map(i => GridUtils.getModelIndex(i, movedItems));\n }\n\n /**\n * Translate the provided UI start/end indexes to the model start/end indexes by applying the `movedItems` transformations.\n * Since moved items can split apart a range, multiple pairs of indexes are returned\n *\n * @param start Start item in one dimension\n * @param end End item in one dimension\n * @param movedItems Moved item pairs in this dimension\n * @returns Array of start/end pairs of the indexes after transformations applied.\n */\n static getModelRangeIndexes(\n start: GridRangeIndex,\n end: GridRangeIndex,\n movedItems: readonly MoveOperation[]\n ): AxisRange[] {\n return GridUtils.applyItemMoves(start, end, movedItems, true);\n }\n\n /**\n * Translate the provided UI range into model range, using the `movedColumns` and `movedRows` to apply the necessary transforms.\n * `movedColumns` and `movedRows` are array of operations done to the UI indexes to re-order items\n *\n * @param uiRange The currently selected UI ranges\n * @param movedColumns The moved column pairs\n * @param movedRows The moved row pairs\n * @returns The model ranges after translation.\n */\n static getModelRange(\n uiRange: GridRange,\n movedColumns: readonly MoveOperation[] = EMPTY_ARRAY,\n movedRows: readonly MoveOperation[] = EMPTY_ARRAY\n ): GridRange[] {\n return GridUtils.translateRange(uiRange, movedColumns, movedRows, true);\n }\n\n /**\n * Translate the provided UI range into model ranges, using the `movedColumns` and `movedRows` to apply the necessary transforms.\n * `movedColumns` and `movedRows` are array of operations done to the UI indexes to re-order items\n *\n * @param uiRanges The currently selected UI ranges\n * @param movedColumns The moved column pairs\n * @param movedRows The moved row pairs\n * @returns The model ranges after translation.\n */\n static getModelRanges(\n uiRanges: readonly GridRange[],\n movedColumns: readonly MoveOperation[] = EMPTY_ARRAY,\n movedRows: readonly MoveOperation[] = EMPTY_ARRAY\n ): GridRange[] {\n const modelRanges = [];\n for (let i = 0; i < uiRanges.length; i += 1) {\n modelRanges.push(\n ...GridUtils.getModelRange(uiRanges[i], movedColumns, movedRows)\n );\n }\n return modelRanges;\n }\n\n /**\n * Translate the provided UI start/end indexes to the visible start/end indexes by applying the `movedItems` transformations.\n * Since moved items can split apart a range, multiple pairs of indexes are returned\n *\n * @param start Start item in one dimension\n * @param end End item in one dimension\n * @param movedItems Moved item pairs in this dimension\n * @returns Array of start/end pairs of the indexes after transformations applied.\n */\n static getVisibleRangeIndexes(\n start: GridRangeIndex,\n end: GridRangeIndex,\n movedItems: readonly MoveOperation[]\n ): AxisRange[] {\n return GridUtils.applyItemMoves(start, end, movedItems, false);\n }\n\n /**\n * Translate the provided UI range into visible range, using the `movedColumns` and `movedRows` to apply the necessary transforms.\n * `movedColumns` and `movedRows` are array of operations done to the UI indexes to re-order items\n *\n * @param uiRange The currently selected UI ranges\n * @param movedColumns The moved column pairs\n * @param movedRows The moved row pairs\n * @returns The model ranges after translation.\n */\n static getVisibleRange(\n modelRange: GridRange,\n movedColumns: readonly MoveOperation[] = EMPTY_ARRAY,\n movedRows: readonly MoveOperation[] = EMPTY_ARRAY\n ): GridRange[] {\n return this.translateRange(modelRange, movedColumns, movedRows, false);\n }\n\n /**\n * Translate the provided model ranges into visible ranges, using the `movedColumns` and `movedRows` to apply the necessary transforms.\n * `movedColumns` and `movedRows` are array of operations done to the UI indexes to re-order items\n *\n * @param modelRanges The model ranges\n * @param movedColumns The moved column pairs\n * @param movedRows The moved row pairs\n * @returns The model ranges after translation.\n */\n static getVisibleRanges(\n modelRanges: readonly GridRange[],\n movedColumns: readonly MoveOperation[] = EMPTY_ARRAY,\n movedRows: readonly MoveOperation[] = EMPTY_ARRAY\n ): GridRange[] {\n const visibleRanges = [];\n for (let i = 0; i < modelRanges.length; i += 1) {\n visibleRanges.push(\n ...GridUtils.getVisibleRange(modelRanges[i], movedColumns, movedRows)\n );\n }\n return visibleRanges;\n }\n\n /**\n * Retrieve the visible index given the currently moved items\n * @param modelIndex The model index to get the visible index for\n * @param movedItems Moved items\n * @returns The visible index of the item\n */\n static getVisibleIndex(\n modelIndex: ModelIndex,\n movedItems: readonly MoveOperation[]\n ): VisibleIndex {\n const visibleIndex = GridUtils.applyItemMoves(\n modelIndex,\n modelIndex,\n movedItems\n )[0][0];\n\n return visibleIndex;\n }\n\n /**\n * Retrieve the visible indexes given the currently moved items\n * @param modelIndexes The model indexes to get the visible indexes for\n * @param movedItems Moved items\n * @returns The visible indexes of the item\n */\n static getVisibleIndexes(\n modelIndexes: readonly ModelIndex[],\n movedItems: readonly MoveOperation[]\n ): VisibleIndex[] {\n return modelIndexes.map(i => GridUtils.getVisibleIndex(i, movedItems));\n }\n\n /**\n * Check if the current platform is Mac\n * @returns True if this platform is a Mac, false otherwise\n */\n static isMacPlatform(): boolean {\n const { platform } = window.navigator;\n return platform.startsWith('Mac');\n }\n\n /**\n * Get the modifier key for the current platform\n * @returns The modifier key for the current platform\n */\n static getModifierKey(): 'metaKey' | 'ctrlKey' {\n if (GridUtils.isMacPlatform()) {\n return 'metaKey';\n }\n\n return 'ctrlKey';\n }\n\n /**\n * Check if the modifier key is down for the given event\n * @param event The event to check\n * @returns True if the modifier key is down, false otherwise\n */\n static isModifierKeyDown(\n event: MouseEvent | KeyboardEvent | React.KeyboardEvent | React.MouseEvent\n ): boolean {\n const modifierKey = GridUtils.getModifierKey();\n return event[modifierKey];\n }\n\n /**\n * Check if the user has hidden the specified column\n * @param modelIndex The model index to check\n * @param userColumnWidths The user set column widths\n * @returns True if the user has hidden the column\n */\n static checkColumnHidden(\n modelIndex: ModelIndex,\n userColumnWidths: ModelSizeMap\n ): boolean {\n return userColumnWidths.get(modelIndex) === 0;\n }\n\n /**\n * Check if all the columns specified are hidden\n * @param columns Columns to check\n * @param userColumnWidths The user set column widths\n * @returns True if the user has hidden all of the columns\n */\n static checkAllColumnsHidden(\n columns: readonly ModelIndex[],\n userColumnWidths: ModelSizeMap\n ): boolean {\n if (userColumnWidths.size === 0) {\n return false;\n }\n return columns.every(column => userColumnWidths.get(column) === 0);\n }\n\n /**\n * Get the bounds the mouse needs to be dragged outside of from an initial selection before scrolling occurs.\n * Taking into account any floating rows that may be covering the viewport.\n * @param metrics Grid metrics\n * @param row The row they started dragging in\n * @param column The column they started the drag from\n * @returns Dimensions of the drag area in relation to the canvas they need to drag outside of to start scrolling\n */\n static getScrollDragBounds(\n metrics: GridMetrics,\n row: GridRangeIndex,\n column: GridRangeIndex\n ): BoxCoordinates {\n const {\n gridX,\n gridY,\n width,\n height,\n floatingTopRowCount,\n floatingBottomRowCount,\n floatingLeftColumnCount,\n floatingRightColumnCount,\n floatingLeftWidth,\n floatingRightWidth,\n floatingTopHeight,\n floatingBottomHeight,\n columnCount,\n rowCount,\n } = metrics;\n let x1 = gridX;\n let y1 = gridY;\n let x2 = width;\n let y2 = height;\n if (column != null) {\n if (column > floatingLeftColumnCount) {\n x1 += floatingLeftWidth;\n }\n if (column < columnCount - floatingRightColumnCount) {\n x2 -= floatingRightWidth;\n }\n }\n\n if (row != null) {\n if (row > floatingTopRowCount) {\n y1 += floatingTopHeight;\n }\n if (row < rowCount - floatingBottomRowCount) {\n y2 -= floatingBottomHeight;\n }\n }\n return { x1, y1, x2, y2 };\n }\n\n /**\n * Converts the delta coordinates from the provided wheel event to pixels\n * Different platforms have different ways of providing the delta so this normalizes it\n * @param wheelEvent The mouse wheel event to get the scrolling delta for\n * @param pageWidth The width of the page that is scrolling\n * @param pageHeight The height of the page that is scrolling\n * @param lineWidth The width of the line scrolling in line mode\n * @param lineHeight The height of the line scrolling in line mode\n * @returns The delta coordinates normalized to pixels\n */\n static getScrollDelta(\n wheelEvent: GridWheelEvent,\n pageWidth = 1024,\n pageHeight = 768,\n lineWidth = 20,\n lineHeight = 20\n ): { deltaX: number; deltaY: number } {\n let { deltaX, deltaY } = wheelEvent;\n\n // Flip scroll direction if shiftKey is held on windows/linux.\n // On mac, deltaX/Y values are switched at the event level when shiftKey=true.\n // Guard on strictly Y only changing, to ignore trackpad diagonal motion,\n // through that guard may not be necessary, but it is difficult to determine for\n // all platforms/browser/scroll method combos.\n if (\n !GridUtils.isMacPlatform() &&\n wheelEvent.shiftKey &&\n wheelEvent.deltaX === 0 &&\n wheelEvent.deltaY !== 0\n ) {\n deltaX = wheelEvent.deltaY;\n deltaY = wheelEvent.deltaX;\n }\n\n // Normalize other deltaMode values to pixel units\n // deltaMode 0, is already in pixel units\n if (wheelEvent?.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n // Users can set OS to be in deltaMode page\n // scrolly by page units as pixels\n deltaX *= pageWidth;\n deltaY *= pageHeight;\n } else if (wheelEvent?.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n // Firefox reports deltaMode line\n // Normalize distance travelled between browsers\n // but remain ~platform/browser combo consistent\n if (GridUtils.isMacPlatform()) {\n // for mac treat lines as a standard row height\n // on mac, firefox travels less distance then chrome per tick\n deltaX = Math.round(deltaX * lineWidth);\n deltaY = Math.round(deltaY * lineHeight);\n } else {\n // for windows convert to pixels using the same method as chrome\n // chrome goes 100 per 3 lines, and firefox would go 102 per 3 (17 lineheight * 3 lines * 2)\n // make the behaviour the same between as it's close enough\n deltaX = Math.round(deltaX * this.PIXELS_PER_LINE);\n deltaY = Math.round(deltaY * this.PIXELS_PER_LINE);\n }\n }\n\n return { deltaX, deltaY };\n }\n\n static compareRanges(range1: AxisRange, range2: AxisRange): number {\n if (\n range1[0] == null ||\n range1[1] == null ||\n range2[0] == null ||\n range2[1] == null\n ) {\n return 0;\n }\n return range1[0] !== range2[0]\n ? range1[0] - range2[0]\n : range1[1] - range2[1];\n }\n\n static mergeSortedRanges(ranges: BoundedAxisRange[]): BoundedAxisRange[] {\n const mergedRanges: BoundedAxisRange[] = [];\n\n for (let i = 0; i < ranges.length; i += 1) {\n const range = ranges[i];\n const start = range[0];\n const end = range[1];\n if (i === 0) {\n mergedRanges.push([start, end]);\n } else if (start - 1 <= mergedRanges[mergedRanges.length - 1][1]) {\n mergedRanges[mergedRanges.length - 1][1] = Math.max(\n mergedRanges[mergedRanges.length - 1][1],\n end\n );\n } else {\n mergedRanges.push([start, end]);\n }\n }\n return mergedRanges;\n }\n\n /**\n * Translates coordinates that are relative to gridX/gridY to be translated by gridX and gridY\n * @param tokenBox The token box to translate\n * @param metrics The grid metrics\n * @returns The token box with translated coordinates\n */\n static translateTokenBox(tokenBox: TokenBox, metrics: GridMetrics): TokenBox {\n const { x1: left, y1: top, x2: right, y2: bottom } = tokenBox;\n const {\n gridX,\n gridY,\n width: gridWidth,\n height: gridHeight,\n verticalBarWidth,\n horizontalBarHeight,\n } = metrics;\n\n // Clamp the values within the grid\n const newLeft = clamp(gridX + left, gridX, gridWidth - verticalBarWidth);\n const newRight = clamp(gridX + right, gridX, gridWidth - verticalBarWidth);\n const newTop = clamp(gridY + top, gridY, gridHeight - horizontalBarHeight);\n const newBottom = clamp(\n gridY + bottom,\n gridY,\n gridHeight - horizontalBarHeight\n );\n\n return {\n x1: newLeft,\n y1: newTop,\n x2: newRight,\n y2: newBottom,\n token: tokenBox.token,\n };\n }\n\n /**\n * Finds tokens in text (urls, emails) that start with https:// or http://\n * @param text The text to search in\n * @returns An array of tokens\n */\n static findTokensWithProtocolInText(text: string): Token[] {\n const tokens = linkifyFind(text);\n\n return tokens.filter(token => {\n if (token.type === 'url') {\n return /^https?:\\/\\//.test(token.value);\n }\n return true;\n });\n }\n}\n\nexport default GridUtils;\n","import clamp from 'lodash.clamp';\nimport { getOrThrow } from '@deephaven/utils';\nimport GridModel from './GridModel';\nimport type {\n GridMetrics,\n BoxCoordinates,\n Coordinate,\n CoordinateMap,\n VisibleIndex,\n VisibleToModelMap,\n ModelIndex,\n ModelSizeMap,\n MoveOperation,\n SizeMap,\n} from './GridMetrics';\nimport GridUtils from './GridUtils';\nimport { GridFont, GridTheme } from './GridTheme';\nimport { isExpandableGridModel } from './ExpandableGridModel';\nimport { DraggingColumn } from './mouse-handlers/GridColumnMoveMouseHandler';\n\nexport { getOrThrow } from '@deephaven/utils';\n/* eslint class-methods-use-this: \"off\" */\n/* eslint react/destructuring-assignment: \"off\" */\n\nexport interface GridMetricState {\n // The top/left cell of the scrolled viewport\n left: VisibleIndex;\n top: VisibleIndex;\n\n // The scroll offset within the top/left of the viewport\n leftOffset: Coordinate;\n topOffset: Coordinate;\n\n // Width and height of the total canvas area\n width: number;\n height: number;\n\n // The canvas context\n context: CanvasRenderingContext2D;\n\n // The grid theme\n theme: GridTheme;\n\n // The model used by the grid\n model: GridModel;\n\n // Moved columns/rows in the grid\n movedColumns: readonly MoveOperation[];\n movedRows: readonly MoveOperation[];\n\n // Whether the scrollbars are currently being dragged\n isDraggingHorizontalScrollBar: boolean;\n isDraggingVerticalScrollBar: boolean;\n\n draggingColumn: DraggingColumn | null;\n}\n\n/**\n * Trim the provided map in place. Trims oldest inserted items down to the target size if the cache size is exceeded.\n * Instead of trimming one item on every tick, we trim half the items so there isn't a cache clear on every new item.\n * @param map The map to trim\n * @param cacheSize The maximum number of elements to cache\n * @param targetSize The number of elements to reduce the cache down to if `cacheSize` is exceeded\n */\nexport function trimMap(\n map: Map<unknown, unknown>,\n cacheSize = GridMetricCalculator.CACHE_SIZE,\n targetSize = Math.floor(cacheSize / 2)\n): void {\n if (map.size > cacheSize) {\n const iter = map.keys();\n while (map.size > targetSize) {\n map.delete(iter.next().value);\n }\n }\n}\n\n/**\n * Get the coordinates of floating items in one dimension.\n * Can be used for getting the y coordinates of floating rows, or x coordinates of floating columns, calculated using the `sizeMap` passed in.\n * @param startCount The number of floating items at the start (ie. `floatingTopRowCount` for rows, `floatingLeftColumnCount` for columns)\n * @param endCount The number of floating items at the end (ie. `floatingBottomRowCount` for rows, `floatingRightColumnCount` for columns)\n * @param totalCount Total number of items in this dimension (ie. `rowCount` for rows, `columnCount` for columns)\n * @param max The max coordinate value (ie. `maxY` for rows, `maxX` for columns)\n * @param sizeMap Map from index to size of item (ie. `rowHeightMap` for rows, `columnWidthMap` for columns)\n */\nexport function getFloatingCoordinates(\n startCount: number,\n endCount: number,\n totalCount: number,\n max: number,\n sizeMap: SizeMap\n): CoordinateMap {\n const coordinates = new Map();\n let x = 0;\n for (let i = 0; i < startCount && i < totalCount; i += 1) {\n coordinates.set(i, x);\n x += getOrThrow(sizeMap, i);\n }\n\n x = max;\n for (let i = 0; i < endCount && totalCount - i - 1 >= 0; i += 1) {\n x -= getOrThrow(sizeMap, totalCount - i - 1);\n coordinates.set(totalCount - i - 1, x);\n }\n return coordinates;\n}\n\n/**\n * Class to calculate all the metrics for drawing a grid.\n * Call getMetrics() with the state to get the full metrics.\n * Override this class and override the individual methods to provide additional functionality.\n */\nexport class GridMetricCalculator {\n /** The size of the caches this calculator stores */\n static CACHE_SIZE = 10000;\n\n /** The maximum column width as a percentage of the full grid */\n static MAX_COLUMN_WIDTH = 0.8;\n\n /** The initial row heights if any overrides from the default calculated values */\n public initialRowHeights: ReadonlyMap<ModelIndex, number>; // Readonly so it should be safe to make public\n\n /** The initial column widths if any overrides from the default calculated values */\n public initialColumnWidths: ReadonlyMap<ModelIndex, number>; // Readonly so it should be safe to make public\n\n /** User set column widths */\n protected userColumnWidths: ModelSizeMap;\n\n /** User set row heights */\n protected userRowHeights: ModelSizeMap;\n\n /** Calculated column widths based on cell contents */\n protected calculatedColumnWidths: ModelSizeMap;\n\n /** Calculated row heights based on cell contents */\n protected calculatedRowHeights: ModelSizeMap;\n\n /** Cache of fonts to estimated width of one char */\n protected fontWidths: Map<string, number>;\n\n /** Map from visible index to model index for rows (e.g. reversing movedRows operations) */\n protected modelRows: VisibleToModelMap;\n\n /** Map from visible index to model index for columns (e.g. reversing movedColumns operations) */\n protected modelColumns: VisibleToModelMap;\n\n /** List of moved row operations. Need to track the previous value so we know if modelRows needs to be cleared. */\n protected movedRows: readonly MoveOperation[];\n\n /** List of moved column operations. Need to track the previous value so we know if modelColumns needs to be cleared. */\n protected movedColumns: readonly MoveOperation[];\n\n constructor({\n userColumnWidths = new Map(),\n userRowHeights = new Map(),\n calculatedColumnWidths = new Map(),\n calculatedRowHeights = new Map(),\n fontWidths = new Map(),\n modelRows = new Map(),\n modelColumns = new Map(),\n movedRows = [] as readonly MoveOperation[],\n movedColumns = [] as readonly MoveOperation[],\n initialRowHeights = new Map(),\n initialColumnWidths = new Map(),\n } = {}) {\n this.userColumnWidths = userColumnWidths;\n this.userRowHeights = userRowHeights;\n this.calculatedRowHeights = calculatedRowHeights;\n this.calculatedColumnWidths = calculatedColumnWidths;\n this.fontWidths = fontWidths;\n\n // Need to track the last moved rows/columns array so we know if we need to reset our models cache\n this.modelRows = modelRows;\n this.modelColumns = modelColumns;\n this.movedRows = movedRows;\n this.movedColumns = movedColumns;\n this.initialRowHeights = initialRowHeights;\n this.initialColumnWidths = initialColumnWidths;\n }\n\n /**\n * Get the metrics for the provided metric state\n * @params state The state to get metrics for\n * @returns The full metrics\n */\n getMetrics(state: GridMetricState): GridMetrics {\n const {\n left,\n top,\n leftOffset,\n topOffset,\n width,\n height,\n theme,\n model,\n movedRows,\n movedColumns,\n draggingColumn,\n } = state;\n const {\n rowHeight,\n rowHeaderWidth,\n rowFooterWidth,\n columnWidth,\n columnHeaderHeight,\n minScrollHandleSize,\n scrollBarSize,\n } = theme;\n\n if (movedRows !== this.movedRows) {\n this.movedRows = movedRows;\n this.modelRows.clear();\n }\n\n if (movedColumns !== this.movedColumns) {\n this.movedColumns = movedColumns;\n this.modelColumns.clear();\n }\n\n const {\n columnCount,\n rowCount,\n floatingTopRowCount,\n floatingBottomRowCount,\n floatingLeftColumnCount,\n floatingRightColumnCount,\n columnHeaderMaxDepth,\n } = model;\n\n // Get some basic metrics\n const firstRow = this.getFirstRow(state);\n const firstColumn = this.getFirstColumn(state);\n\n const gridX = this.getGridX(state);\n const gridY = this.getGridY(state);\n\n const treePaddingX =\n isExpandableGridModel(model) && model.hasExpandableRows\n ? this.calculateTreePaddingX(state)\n : 0;\n const treePaddingY = 0; // We don't support trees on columns (at least not yet)\n\n const visibleRowHeights = this.getVisibleRowHeights(state);\n const visibleColumnWidths = this.getVisibleColumnWidths(\n state,\n firstColumn,\n treePaddingX\n );\n\n // Calculate the metrics for the main grid\n const visibleRows = Array.from(visibleRowHeights.keys());\n const visibleColumns = Array.from(visibleColumnWidths.keys());\n\n // Add the floating row heights/column widths\n const allRowHeights = new Map([\n ...visibleRowHeights,\n ...this.getFloatingRowHeights(state),\n ]);\n const allColumnWidths = new Map([\n ...visibleColumnWidths,\n ...this.getFloatingColumnWidths(state),\n ]);\n\n const visibleColumnXs = this.getVisibleColumnXs(\n allColumnWidths,\n visibleColumns,\n leftOffset\n );\n const visibleRowYs = this.getVisibleRowYs(\n allRowHeights,\n visibleRows,\n topOffset\n );\n\n const bottom =\n visibleRows.length > 0 ? visibleRows[visibleRows.length - 1] : top;\n const right =\n visibleColumns.length > 0\n ? visibleColumns[visibleColumns.length - 1]\n : left;\n\n const bottomViewport = this.getBottomViewport(\n state,\n visibleRows,\n visibleRowYs,\n allRowHeights\n );\n const rightViewport = this.getRightViewport(\n state,\n visibleColumns,\n visibleColumnXs,\n allColumnWidths\n );\n\n const floatingTopHeight = this.getFloatingTopHeight(state, allRowHeights);\n const floatingBottomHeight = this.getFloatingBottomHeight(\n state,\n allRowHeights\n );\n const floatingLeftWidth = this.getFloatingLeftWidth(state, allColumnWidths);\n const floatingRightWidth = this.getFloatingRightWidth(\n state,\n allColumnWidths\n );\n\n const columnWidthValues = Array.from(allColumnWidths.values());\n const rowHeightValues = Array.from(allRowHeights.values());\n const maxX = columnWidthValues.reduce((x, w) => x + w, 0) - leftOffset;\n const maxY = rowHeightValues.reduce((y, h) => y + h, 0) - topOffset;\n\n // How much total space the content will take\n const scrollableContentWidth = leftOffset + maxX + rowFooterWidth;\n const scrollableContentHeight = topOffset + maxY;\n\n // Visible space available in the canvas viewport\n const scrollableViewportWidth = width - gridX;\n const scrollableViewportHeight = height - gridY;\n\n const lastLeftWithoutScroll = this.getLastLeft(\n state,\n null,\n scrollableViewportWidth - rowFooterWidth\n );\n const lastLeftWithScroll = this.getLastLeft(\n state,\n null,\n scrollableViewportWidth - rowFooterWidth - scrollBarSize\n );\n\n const lastTopWithoutScroll = this.getLastTop(\n state,\n null,\n scrollableViewportHeight - floatingBottomHeight\n );\n const lastTopWithScroll = this.getLastTop(\n state,\n null,\n scrollableViewportHeight - floatingBottomHeight - scrollBarSize\n );\n\n let lastLeft = lastLeftWithScroll;\n let lastTop = lastTopWithScroll;\n if (lastLeftWithoutScroll === 0 && lastTopWithoutScroll === 0) {\n // Fully visible without any scroll bars\n lastLeft = 0;\n lastTop = 0;\n }\n\n // Calculate some metrics for the scroll bars\n const hasHorizontalBar = lastLeft > 0;\n const horizontalBarHeight = hasHorizontalBar ? scrollBarSize : 0;\n const hasVerticalBar = lastTop > 0;\n const verticalBarWidth = hasVerticalBar ? scrollBarSize : 0;\n const barLeft = gridX;\n const barTop = columnHeaderMaxDepth * columnHeaderHeight;\n const barWidth = width - barLeft - verticalBarWidth;\n const barHeight = height - barTop - horizontalBarHeight;\n\n // How big the scroll handle is relative to the bar\n const horizontalHandlePercent =\n columnCount === 1\n ? barWidth / scrollableContentWidth\n : (columnCount - lastLeft) / columnCount;\n\n const verticalHandlePercent =\n rowCount === 1\n ? barHeight / scrollableContentHeight\n : (rowCount - lastTop) / rowCount;\n\n const handleWidth = hasHorizontalBar\n ? clamp(\n barWidth * horizontalHandlePercent,\n minScrollHandleSize,\n barWidth - 1\n )\n : 0;\n const handleHeight = hasVerticalBar\n ? clamp(\n barHeight * verticalHandlePercent,\n minScrollHandleSize,\n barHeight - 1\n )\n : 0;\n\n const leftColumnWidth = getOrThrow(allColumnWidths, left, 0);\n const topRowHeight = getOrThrow(allRowHeights, top, 0);\n const leftOffsetPercent =\n leftColumnWidth > 0 ? leftOffset / leftColumnWidth : 0;\n const topOffsetPercent = topRowHeight > 0 ? topOffset / topRowHeight : 0;\n\n // How much of the available space has been scrolled\n const horizontalScrollPercent =\n columnCount === 1\n ? leftOffset / (scrollableContentWidth - scrollableViewportWidth)\n : (left + leftOffsetPercent) / lastLeft;\n const verticalScrollPercent =\n rowCount === 1\n ? topOffset / (scrollableContentHeight - scrollableViewportHeight)\n : (top + topOffsetPercent) / lastTop;\n\n const scrollX = hasHorizontalBar\n ? horizontalScrollPercent * (barWidth - handleWidth)\n : 0;\n const scrollY = hasVerticalBar\n ? verticalScrollPercent * (barHeight - handleHeight)\n : 0;\n\n // Now add the floating sections positions\n const floatingRows: ModelIndex[] = [\n ...Array(floatingTopRowCount).keys(),\n ...[...Array(floatingBottomRowCount).keys()].map(i => rowCount - i - 1),\n ];\n const allRowYs = new Map([\n ...visibleRowYs,\n ...this.getFloatingRowYs(\n state,\n allRowHeights,\n Math.floor(height - gridY - horizontalBarHeight)\n ),\n ]);\n\n const floatingColumns: ModelIndex[] = [\n ...Array(floatingLeftColumnCount).keys(),\n ...[...Array(floatingRightColumnCount).keys()].map(\n i => columnCount - i - 1\n ),\n ];\n\n const allColumnXs = new Map([\n ...visibleColumnXs,\n ...this.getFloatingColumnXs(\n state,\n allColumnWidths,\n Math.floor(width - gridX - verticalBarWidth)\n ),\n ]);\n\n const draggingColumns: VisibleIndex[] = [];\n if (draggingColumn) {\n for (\n let i = draggingColumn.range[0];\n i <= draggingColumn.range[1];\n i += 1\n ) {\n draggingColumns.push(i);\n if (!allColumnWidths.has(i)) {\n allColumnWidths.set(i, this.getVisibleColumnWidth(i, state));\n }\n\n if (!allColumnXs.has(i)) {\n allColumnXs.set(i, 0);\n }\n }\n }\n\n const allRows = visibleRows.concat(floatingRows);\n const allColumns = visibleColumns\n .concat(floatingColumns)\n .concat(draggingColumns);\n const modelRows = this.getModelRows(allRows, state);\n const modelColumns = this.getModelColumns(allColumns, state);\n\n const visibleRowTreeBoxes = this.getVisibleRowTreeBoxes(\n allRowHeights,\n modelRows,\n state\n );\n\n // Calculate the visible viewport based on scroll position and floating sections\n const topVisible = this.getTopVisible(\n state,\n allRowYs,\n allRowHeights,\n visibleRows\n );\n const leftVisible = this.getLeftVisible(\n state,\n allColumnXs,\n allColumnWidths,\n visibleColumns\n );\n const bottomVisible =\n lastTop > 0\n ? this.getBottomVisible(\n state,\n allRowYs,\n allRowHeights,\n visibleRows,\n gridY\n )\n : bottom;\n const rightVisible =\n lastLeft > 0\n ? this.getRightVisible(\n state,\n allColumnXs,\n allColumnWidths,\n visibleColumns,\n gridX\n )\n : right;\n\n const {\n fontWidths,\n userColumnWidths,\n userRowHeights,\n calculatedRowHeights,\n calculatedColumnWidths,\n } = this;\n\n return {\n // Row/Column metrics from model\n rowHeight,\n rowHeaderWidth,\n rowFooterWidth,\n rowCount,\n columnWidth,\n columnCount,\n columnHeaderHeight,\n\n // Floating row and column counts\n floatingTopRowCount,\n floatingBottomRowCount,\n floatingLeftColumnCount,\n floatingRightColumnCount,\n\n // The grid offset from the top left\n gridX,\n gridY,\n\n // Index of non-hidden row/columns\n firstRow,\n firstColumn,\n\n // The amount of padding for tree (if applicable)\n treePaddingX,\n treePaddingY,\n\n // What viewport is currently visible, limited by data size\n left,\n top,\n bottom,\n right,\n topOffset,\n leftOffset,\n\n // Bottom and right that are fully visible, not overlapped by scroll bars or anything\n topVisible,\n leftVisible,\n bottomVisible,\n rightVisible,\n\n // Bottom and right of the viewport, not limited by data size\n bottomViewport,\n rightViewport,\n\n // Canvas width/height\n width,\n height,\n\n // Max x/y coordinate of the grid (does not include headers)\n maxX,\n maxY,\n\n // Last valid column/row that can be the left/top of the grid\n lastLeft,\n lastTop,\n\n // Scroll bar metrics\n barHeight,\n barTop,\n barWidth,\n barLeft,\n handleHeight,\n handleWidth,\n hasHorizontalBar,\n hasVerticalBar,\n verticalBarWidth,\n horizontalBarHeight,\n\n // The vertical x/y scroll amount\n scrollX,\n scrollY,\n\n scrollableContentWidth,\n scrollableContentHeight,\n\n scrollableViewportWidth,\n scrollableViewportHeight,\n\n // Array of visible rows/columns, by grid index\n visibleRows,\n visibleColumns,\n\n // Map of the height/width of visible rows/columns\n visibleRowHeights,\n visibleColumnWidths,\n\n // Array of floating rows/columns, by grid index\n floatingRows,\n floatingColumns,\n\n // Array of all rows/columns, visible and floating, by grid index\n allRows,\n allColumns,\n\n // Map of the height/width of visible rows/columns\n allRowHeights,\n allColumnWidths,\n\n // Floating metrics\n floatingTopHeight,\n floatingBottomHeight,\n floatingLeftWidth,\n floatingRightWidth,\n\n // Map of the X/Y coordinates of the visible rows/columns, from the top left of the grid\n visibleRowYs,\n visibleColumnXs,\n\n // Map of the X/Y coordinates of all rows/columns, visible and floating, from the top left of the grid\n allRowYs,\n allColumnXs,\n\n // The boxes user can click on for expanding/collapsing tree rows\n visibleRowTreeBoxes,\n\n // Mapping from visible row indexes to the model row/columns they pull from\n modelRows,\n modelColumns,\n\n movedRows,\n movedColumns,\n\n // Map of the width of the fonts\n fontWidths,\n\n // Map of user set column/row width/height\n userColumnWidths,\n userRowHeights,\n\n // Map of calculated row/column height/width\n calculatedRowHeights,\n calculatedColumnWidths,\n\n columnHeaderMaxDepth,\n };\n }\n\n /**\n * The x offset of the grid\n * @param state The current grid state\n * @returns x value of the left side of the first cell\n */\n getGridX(state: GridMetricState): Coordinate {\n const { theme } = state;\n const { rowHeaderWidth } = theme;\n\n return rowHeaderWidth;\n }\n\n /**\n * The y offset of the grid\n * @param state The current grid state\n * @returns y value of the top side of the first cell\n */\n getGridY(state: GridMetricState): Coordinate {\n const { theme, model } = state;\n const { columnHeaderHeight } = theme;\n const { columnHeaderMaxDepth } = model;\n\n return columnHeaderMaxDepth * columnHeaderHeight;\n }\n\n /**\n * The height of the \"visible\" area (excludes floating areas)\n * @param state The current grid state\n * @param visibleRowHeights All the visible row heights\n * @returns The visible height in pixels\n */\n getVisibleHeight(\n state: GridMetricState,\n visibleRowHeights: SizeMap = this.getFloatingRowHeights(state)\n ): number {\n const { height, theme } = state;\n const { scrollBarSize } = theme;\n const gridY = this.getGridY(state);\n const floatingBottomHeight = this.getFloatingBottomHeight(\n state,\n visibleRowHeights\n );\n const floatingTopHeight = this.getFloatingTopHeight(\n state,\n visibleRowHeights\n );\n\n return (\n height - floatingBottomHeight - floatingTopHeight - gridY - scrollBarSize\n );\n }\n\n /**\n * The width of the \"visible\" area (excludes floating areas)\n * @param state The current grid state\n * @param visibleColumnWidths All the visible column widths\n * @returns The visible width in pixels\n */\n getVisibleWidth(\n state: GridMetricState,\n visibleColumnWidths: SizeMap = this.getFloatingColumnWidths(state)\n ): number {\n const { width, theme } = state;\n const { scrollBarSize, rowFooterWidth } = theme;\n const gridX = this.getGridX(state);\n const floatingRightWidth = this.getFloatingRightWidth(\n state,\n visibleColumnWidths\n );\n const floatingLeftWidth = this.getFloatingLeftWidth(\n state,\n visibleColumnWidths\n );\n\n return (\n width -\n floatingLeftWidth -\n floatingRightWidth -\n gridX -\n scrollBarSize -\n rowFooterWidth\n );\n }\n\n /**\n * Retrieve the index of the first non-hidden item\n * @param itemSizes The size of the items in this dimension\n * @param getModelIndex A function to map from the Index to the ModelIndex\n * @param state The current grid state\n * @returns The first item that is not hidden\n */\n getFirstIndex(\n itemSizes: ModelSizeMap,\n getModelIndex: (\n visibleIndex: VisibleIndex,\n state: GridMetricState\n ) => ModelIndex,\n state: GridMetricState\n ): VisibleIndex {\n // We only need to check at the very most the number of items the user has hidden + 1\n const max = itemSizes.size + 1;\n for (let i = 0; i < max; i += 1) {\n const modelIndex = getModelIndex(i, state);\n if (itemSizes.get(modelIndex) !== 0) {\n return i;\n }\n }\n return 0;\n }\n\n /**\n * Get the first column index that isn't hidden\n * @param state The current grid state\n * @returns The first column that is not hidden\n */\n getFirstColumn(state: GridMetricState): VisibleIndex {\n return this.getFirstIndex(\n this.userColumnWidths,\n this.getModelColumn.bind(this),\n state\n );\n }\n\n /**\n * Get the first row index that isn't hidden\n * @param state The current grid state\n * @returns The first row that is not hidden\n */\n getFirstRow(state: GridMetricState): VisibleIndex {\n return this.getFirstIndex(\n this.userRowHeights,\n this.getModelRow.bind(this),\n state\n );\n }\n\n /**\n * Get the last column that can be the left most column (e.g. scrolled to the right)\n * If no right column is provided, then the last column is used.\n * @param state The current grid state\n * @param right The right-most column to be visible, or null to default to last cell\n * @param visibleWidth The width of the \"visible\" area (excluding floating items)\n * @returns The index of the last left visible column\n */\n getLastLeft(\n state: GridMetricState,\n right: VisibleIndex | null,\n visibleWidth: number\n ): VisibleIndex {\n const { model } = state;\n const { columnCount, floatingRightColumnCount } = model;\n\n let lastLeft = Math.max(0, columnCount - floatingRightColumnCount - 1);\n if (right != null) {\n lastLeft = right;\n }\n let x = 0;\n while (lastLeft >= 0) {\n const columnWidth = this.getVisibleColumnWidth(lastLeft, state);\n x += columnWidth;\n\n if (x >= visibleWidth) {\n return clamp(lastLeft + 1, 0, right ?? columnCount - 1);\n }\n\n lastLeft -= 1;\n }\n\n return 0;\n }\n\n /**\n * The last row that can be the top row (e.g. scrolled to the bottom)\n * If no bottom row is provided, then the last row that is not floating is used\n * @param state The current grid state\n * @param bottom The bottom-most row to be visible, or null to default to last cell\n * @param visibleHeight The height of the \"visible\" area (excluding floating items)\n * @returns The index of the last top visible row\n */\n getLastTop(\n state: GridMetricState,\n bottom: VisibleIndex | null,\n visibleHeight: number\n ): VisibleIndex {\n const { model } = state;\n const { rowCount, floatingBottomRowCount } = model;\n\n let lastTop = Math.max(0, rowCount - floatingBottomRowCount - 1);\n if (bottom != null) {\n lastTop = bottom;\n }\n let y = 0;\n while (lastTop >= 0) {\n const rowHeight = this.getVisibleRowHeight(lastTop, state);\n y += rowHeight;\n\n if (y >= visibleHeight) {\n return clamp(lastTop + 1, 0, rowCount - 1);\n }\n\n lastTop -= 1;\n }\n\n return 0;\n }\n\n /**\n * Retrieve the top row to scroll to so the passed in `topVisible` is completely visible, taking the floating rows into account.\n * The `top` row is at the top underneath any floating rows, whereas `topVisible` is visible below the floating rows.\n * If there are no floating rows, they should be the same value.\n * @param state The grid metric state\n * @param topVisible The top row to be visible\n * @returns The index of the top row to scroll to (under the floating top rows)\n */\n getTopForTopVisible(\n state: GridMetricState,\n topVisible: VisibleIndex\n ): VisibleIndex {\n const floatingTopHeight = this.getFloatingTopHeight(state);\n let top = topVisible;\n let y = 0;\n while (top > 0 && y < floatingTopHeight) {\n top -= 1;\n y += this.getVisibleRowHeight(top, state);\n }\n return top;\n }\n\n /**\n * Retrieve the top row to scroll to so the passed in `bottomVisible` is completely visible\n * at the bottom of the visible viewport, taking the floating rows into account.\n * @param state The grid metric state\n * @param bottomVisible The bottom row to be visible\n * @returns The index of the top row to scroll to (under the floating top rows)\n */\n getTopForBottomVisible(\n state: GridMetricState,\n bottomVisible: VisibleIndex\n ): VisibleIndex {\n const { height } = state;\n const gridY = this.getGridY(state);\n const floatingBottomHeight = this.getFloatingBottomHeight(state);\n const availableHeight = height - gridY - floatingBottomHeight;\n return this.getLastTop(state, bottomVisible, availableHeight);\n }\n\n /**\n * Retrieve the left column to scroll to so the passed in `leftVisible` is completely visible\n * at the left of the visible viewport, taking the floating columns into account.\n * @param state The grid metric state\n * @param leftVisible The left column to be visible\n * @returns The index of the left column to scroll to (under the floating left columns)\n */\n getLeftForLeftVisible(\n state: GridMetricState,\n leftVisible: VisibleIndex\n ): VisibleIndex {\n const floatingLeftWidth = this.getFloatingLeftWidth(state);\n let left = leftVisible;\n let x = 0;\n while (left > 0 && x < floatingLeftWidth) {\n left -= 1;\n x += this.getVisibleColumnWidth(left, state);\n }\n return left;\n }\n\n /**\n * Retrieve the left column to scroll to so the passed in `rightVisible` is completely visible\n * at the right of the visible viewport, taking the floating columns into account.\n * @param state The grid metric state\n * @param rightVisible The right column to be visible\n * @returns The index of the left column to scroll to (under the floating left columns)\n */\n getLeftForRightVisible(\n state: GridMetricState,\n rightVisible: VisibleIndex\n ): VisibleIndex {\n const { width } = state;\n const gridX = this.getGridX(state);\n const floatingRightWidth = this.getFloatingRightWidth(state);\n const availableWidth = width - gridX - floatingRightWidth;\n return this.getLastLeft(state, rightVisible, availableWidth);\n }\n\n /**\n * Retrieve a map of the height of each floating row\n * @param state The grid metric state\n * @returns The heights of all the floating rows\n */\n getFloatingRowHeights(state: GridMetricState): SizeMap {\n const { model } = state;\n const { floatingTopRowCount, floatingBottomRowCount, rowCount } = model;\n\n const rowHeights = new Map();\n for (let i = 0; i < floatingTopRowCount && i < rowCount; i += 1) {\n rowHeights.set(i, this.getVisibleRowHeight(i, state));\n }\n\n for (\n let i = 0;\n i < floatingBottomRowCount && rowCount - i - 1 >= 0;\n i += 1\n ) {\n const row = rowCount - i - 1;\n rowHeights.set(row, this.getVisibleRowHeight(row, state));\n }\n\n return rowHeights;\n }\n\n /**\n * Retrieve a map of the height of all the visible rows (non-floating)\n * @param state The grid metric state\n * @returns The heights of all the visible rows\n */\n getVisibleRowHeights(state: GridMetricState): SizeMap {\n const { top, topOffset, height, model } = state;\n\n let y = 0;\n let row = top;\n const rowHeights = new Map();\n const { rowCount } = model;\n while (y < height + topOffset && row < rowCount) {\n const rowHeight = this.getVisibleRowHeight(row, state);\n rowHeights.set(row, rowHeight);\n y += rowHeight;\n row += 1;\n }\n\n return rowHeights;\n }\n\n /**\n * Retrieve a map of the width of each floating column\n * @param state The grid metric state\n * @param firstColumn The first non-hidden column\n * @param treePaddingX The amount of padding taken up for the tree expansion buttons\n * @returns The widths of all the floating columns\n */\n getFloatingColumnWidths(\n state: GridMetricState,\n firstColumn: VisibleIndex = this.getFirstColumn(state),\n treePaddingX: number = this.calculateTreePaddingX(state)\n ): SizeMap {\n const { model } = state;\n const {\n columnCount,\n floatingLeftColumnCount,\n floatingRightColumnCount,\n } = model;\n\n const columnWidths = new Map();\n for (let i = 0; i < floatingLeftColumnCount && i < columnCount; i += 1) {\n columnWidths.set(\n i,\n this.getVisibleColumnWidth(i, state, firstColumn, treePaddingX)\n );\n }\n\n for (\n let i = 0;\n i < floatingRightColumnCount && columnCount - i - 1 >= 0;\n i += 1\n ) {\n const column = columnCount - i - 1;\n columnWidths.set(\n column,\n this.getVisibleColumnWidth(column, state, firstColumn, treePaddingX)\n );\n }\n\n return columnWidths;\n }\n\n /**\n * Retrieve a map of the width of all the visible columns (non-floating)\n * @param state The grid metric state\n * @returns The widths of all the visible columns\n */\n getVisibleColumnWidths(\n state: GridMetricState,\n firstColumn: VisibleIndex = this.getFirstColumn(state),\n treePaddingX: number = this.calculateTreePaddingX(state)\n ): SizeMap {\n const { left, leftOffset, width, model } = state;\n\n let x = 0;\n let column = left;\n const columnWidths = new Map();\n const { columnCount } = model;\n while (x < width + leftOffset && column < columnCount) {\n const columnWidth = this.getVisibleColumnWidth(\n column,\n state,\n firstColumn,\n treePaddingX\n );\n columnWidths.set(column, columnWidth);\n x += columnWidth;\n column += 1;\n }\n\n return columnWidths;\n }\n\n /**\n * Retrieve a map of all the floating columns to their x coordinate\n * @param state The grid metric state\n * @param columnWidthMap Map from visible index to column width\n * @param maxX The maximum X size for the grid\n * @returns Map of the x coordinate of all floating columns\n */\n getFloatingColumnXs(\n state: GridMetricState,\n columnWidthMap: SizeMap,\n maxX: Coordinate\n ): CoordinateMap {\n const { model } = state;\n const {\n columnCount,\n floatingLeftColumnCount,\n floatingRightColumnCount,\n } = model;\n\n return getFloatingCoordinates(\n floatingLeftColumnCount,\n floatingRightColumnCount,\n columnCount,\n maxX,\n columnWidthMap\n );\n }\n\n /**\n * Retrieve a map of all the visible columns to their x coordinate.\n * Starts at leftOffset with the first index in `visibleColumns`, then\n * calculates all the coordinates from there\n * @param visibleColumnWidths Map of visible column index to widths\n * @param visibleColumns All visible columns\n * @param leftOffset The left scroll offset\n * @returns Map of the x coordinate of all visible columns\n */\n getVisibleColumnXs(\n visibleColumnWidths: SizeMap,\n visibleColumns: VisibleIndex[],\n leftOffset: number\n ): CoordinateMap {\n const visibleColumnXs = new Map();\n let x = -leftOffset;\n for (let i = 0; i < visibleColumns.length; i += 1) {\n const column = visibleColumns[i];\n const columnWidth = getOrThrow(visibleColumnWidths, column);\n visibleColumnXs.set(column, x);\n x += columnWidth;\n }\n\n return visibleColumnXs;\n }\n\n /**\n * Retrieve a map of all the floating rows to their y coordinate\n * @param state The grid metric state\n * @param rowHeightMap Map of visible index to row height\n * @param maxY The maximum Y size for the grid\n * @returns Map of the y coordinate of all floating rows\n */\n getFloatingRowYs(\n state: GridMetricState,\n rowHeightMap: SizeMap,\n maxY: Coordinate\n ): CoordinateMap {\n const { model } = state;\n const { floatingTopRowCount, floatingBottomRowCount, rowCount } = model;\n\n return getFloatingCoordinates(\n floatingTopRowCount,\n floatingBottomRowCount,\n rowCount,\n maxY,\n rowHeightMap\n );\n }\n\n /**\n * Retrieve a map of all the visible rows to their y coordinate.\n * Starts at topOffset with the first index in `visibleRows`, then\n * calculates all the coordinates from there\n * @param visibleRowHeights Map of visible row index to heights\n * @param visibleRows All visible rows\n * @param topOffset The top scroll offset\n * @returns Map of the y coordinate of all visible rows\n */\n getVisibleRowYs(\n visibleRowHeights: SizeMap,\n visibleRows: VisibleIndex[],\n topOffset: number\n ): CoordinateMap {\n const visibleRowYs = new Map();\n let y = -topOffset;\n for (let i = 0; i < visibleRows.length; i += 1) {\n const row = visibleRows[i];\n const rowHeight = getOrThrow(visibleRowHeights, row);\n visibleRowYs.set(row, y);\n y += rowHeight;\n }\n\n return visibleRowYs;\n }\n\n /**\n * Calculates the tree box click areas that are visible. In relation to the columnX/rowY\n * @param visibleRowHeights Map of visible index to row height\n * @param modelRows Map from visible `Index` to `ModelIndex`\n * @param state The grid metric state\n * @returns Coordinates of tree boxes for each row\n */\n getVisibleRowTreeBoxes(\n visibleRowHeights: SizeMap,\n modelRows: VisibleToModelMap,\n state: GridMetricState\n ): Map<VisibleIndex, BoxCoordinates> {\n const visibleRowTreeBoxes = new Map();\n const { model, theme } = state;\n const { treeDepthIndent, treeHorizontalPadding } = theme;\n\n if (isExpandableGridModel(model) && model.hasExpandableRows) {\n visibleRowHeights.forEach((rowHeight, row) => {\n const modelRow = getOrThrow(modelRows, row);\n if (model.isRowExpandable(modelRow)) {\n const depth = model.depthForRow(modelRow);\n const x1 = depth * treeDepthIndent + treeHorizontalPadding;\n const x2 = (depth + 1) * treeDepthIndent + treeHorizontalPadding;\n const y1 = 0;\n const y2 = rowHeight;\n visibleRowTreeBoxes.set(row, { x1, y1, x2, y2 });\n }\n });\n }\n\n return visibleRowTreeBoxes;\n }\n\n /**\n * Get the total width of the floating columns on the left\n * @param state The grid metric state\n * @param columnWidths Map of column index to width\n * @returns The total width of the floating left section\n */\n getFloatingLeftWidth(\n state: GridMetricState,\n columnWidths: SizeMap = this.getFloatingColumnWidths(state)\n ): number {\n const { model } = state;\n const { floatingLeftColumnCount } = model;\n let floatingWidth = 0;\n for (let i = 0; i < floatingLeftColumnCount; i += 1) {\n floatingWidth += getOrThrow(columnWidths, i);\n }\n return floatingWidth;\n }\n\n /**\n * Get the total width of the floating columns on the right\n * @param state The grid metric state\n * @param columnWidths Map of column index to width\n * @returns The total width of the floating right section\n */\n getFloatingRightWidth(\n state: GridMetricState,\n columnWidths: SizeMap = this.getFloatingColumnWidths(state)\n ): number {\n const { model } = state;\n const { floatingRightColumnCount, columnCount } = model;\n let floatingWidth = 0;\n for (let i = 0; i < floatingRightColumnCount; i += 1) {\n floatingWidth += getOrThrow(columnWidths, columnCount - i - 1);\n }\n\n return floatingWidth;\n }\n\n /**\n * Get the total height of the floating rows on the top\n * @param state The grid metric state\n * @param rowHeights Map of row index to height\n * @returns The total height of the floating top section\n */\n getFloatingTopHeight(\n state: GridMetricState,\n rowHeights: SizeMap = this.getFloatingRowHeights(state)\n ): number {\n const { model } = state;\n const { floatingTopRowCount } = model;\n let floatingHeight = 0;\n for (let i = 0; i < floatingTopRowCount; i += 1) {\n floatingHeight += getOrThrow(rowHeights, i);\n }\n return floatingHeight;\n }\n\n /**\n * Get the total height of the floating rows on the bottom\n * @param state The grid metric state\n * @param rowHeights Map of row index to height\n * @returns The total height of the floating bottom section\n */\n getFloatingBottomHeight(\n state: GridMetricState,\n rowHeights: SizeMap = this.getFloatingRowHeights(state)\n ): number {\n const { model } = state;\n const { floatingBottomRowCount, rowCount } = model;\n let floatingHeight = 0;\n for (let i = 0; i < floatingBottomRowCount; i += 1) {\n floatingHeight += getOrThrow(rowHeights, rowCount - i - 1);\n }\n return floatingHeight;\n }\n\n /**\n * Retrieve the index of the first fully visible row in the \"visible\" viewport of the grid.\n * E.g. First row visible after the floating rows, provided the visible rows.\n * @param state The grid metric state\n * @param visibleRowYs Map of row index to y coordinate\n * @param visibleRowHeights Map of row index to height\n * @param visibleRows Array of visible row indexes\n * @returns Index of the top visible row\n */\n getTopVisible(\n state: GridMetricState,\n visibleRowYs: CoordinateMap,\n visibleRowHeights: SizeMap,\n visibleRows: VisibleIndex[]\n ): VisibleIndex {\n const floatingHeight = this.getFloatingTopHeight(state, visibleRowHeights);\n for (let i = 0; i < visibleRows.length; i += 1) {\n const row = visibleRows[i];\n const y = getOrThrow(visibleRowYs, row);\n if (y >= floatingHeight) {\n return row;\n }\n }\n return 0;\n }\n\n /**\n * Retrieve the index of the first fully visible column in the \"visible\" viewport of the grid.\n * E.g. First column visible after the floating columns, provided the visible columns.\n * @param state The grid metric state\n * @param visibleColumnXs Map of column index to x coordinate\n * @param visibleColumnWidths Map of column index to widths\n * @param visibleColumns Array of visible row indexes\n * @returns Index of the left visible column\n */\n getLeftVisible(\n state: GridMetricState,\n visibleColumnXs: CoordinateMap,\n visibleColumnWidths: SizeMap,\n visibleColumns: VisibleIndex[]\n ): VisibleIndex {\n const floatingWidth = this.getFloatingLeftWidth(state, visibleColumnWidths);\n for (let i = 0; i < visibleColumns.length; i += 1) {\n const column = visibleColumns[i];\n const x = getOrThrow(visibleColumnXs, column);\n if (x >= floatingWidth) {\n return column;\n }\n }\n return 0;\n }\n\n /**\n * Retrieve the index of the last fully visible row in the \"visible\" viewport of the grid.\n * E.g. Last row visible before the bottom floating rows, provided the visible rows.\n * @param state The grid metric state\n * @param visibleRowYs Map of row index to y coordinate\n * @param visibleRowHeights Map of row index to height\n * @param visibleRows Array of visible row indexes\n * @param gridY The starting y coordinate of the grid\n * @returns Index of the bottom visible row\n */\n getBottomVisible(\n state: GridMetricState,\n visibleRowYs: CoordinateMap,\n visibleRowHeights: SizeMap,\n visibleRows: VisibleIndex[],\n gridY: Coordinate\n ): VisibleIndex {\n const { height, theme } = state;\n const { scrollBarSize } = theme;\n const floatingHeight = this.getFloatingBottomHeight(\n state,\n visibleRowHeights\n );\n const visibleHeight = height - gridY - scrollBarSize - floatingHeight;\n for (let i = visibleRows.length - 1; i >= 0; i -= 1) {\n const row = visibleRows[i];\n const rowY = getOrThrow(visibleRowYs, row);\n const rowHeight = getOrThrow(visibleRowHeights, row);\n if (rowY + rowHeight <= visibleHeight) {\n return row;\n }\n }\n\n return 0;\n }\n\n /**\n * Retrieve the index of the last fully visible column in the \"visible\" viewport of the grid.\n * E.g. Last column visible before the floating columns, provided the visible columns.\n * @param state The grid metric state\n * @param visibleColumnXs Map of column index to x coordinate\n * @param visibleColumnWidths Map of column index to widths\n * @param visibleColumns Array of visible column indexes\n * @returns Index of the right visible column\n */\n getRightVisible(\n state: GridMetricState,\n visibleColumnXs: CoordinateMap,\n visibleColumnWidths: SizeMap,\n visibleColumns: VisibleIndex[],\n gridX: Coordinate\n ): VisibleIndex {\n const { width, theme } = state;\n const { scrollBarSize } = theme;\n const floatingWidth = this.getFloatingRightWidth(\n state,\n visibleColumnWidths\n );\n const visibleWidth = width - gridX - scrollBarSize - floatingWidth;\n for (let i = visibleColumns.length - 1; i >= 0; i -= 1) {\n const column = visibleColumns[i];\n const columnX = getOrThrow(visibleColumnXs, column);\n const columnWidth = getOrThrow(visibleColumnWidths, column);\n if (columnX + columnWidth <= visibleWidth) {\n return column;\n }\n }\n\n return 0;\n }\n\n /**\n * Retrieve the possible bottom of the visible viewport (not limited by data size)\n * @param state The grid metric state\n * @param visibleRows Array of visible row indexes\n * @param visibleRowYs Map of row index to y coordinate\n * @param visibleRowHeights Map of row index to height\n * @returns The index of the bottom viewport possible\n */\n getBottomViewport(\n state: GridMetricState,\n visibleRows: VisibleIndex[],\n visibleRowYs: CoordinateMap,\n visibleRowHeights: SizeMap\n ): VisibleIndex {\n const { height, theme } = state;\n const { rowHeight } = theme;\n\n return this.getLastIndexViewport(\n visibleRows,\n visibleRowYs,\n visibleRowHeights,\n height,\n rowHeight\n );\n }\n\n /**\n * Retrieve the possible right of the visible viewport (not limited by data size)\n * @param state The grid metric state\n * @param visibleColumns Array of visible column indexes\n * @param visibleColumnXs Map of column index to x coordinate\n * @param visibleColumnWidths Map of column index to width\n * @returns The index of the right viewport possible\n */\n getRightViewport(\n state: GridMetricState,\n visibleColumns: VisibleIndex[],\n visibleColumnXs: CoordinateMap,\n visibleColumnWidths: SizeMap\n ): VisibleIndex {\n const { width, theme } = state;\n const { columnWidth } = theme;\n\n return this.getLastIndexViewport(\n visibleColumns,\n visibleColumnXs,\n visibleColumnWidths,\n width,\n columnWidth\n );\n }\n\n /**\n * Get the Index of the of the last index visible\n * @param items Array of visible item indexes\n * @param itemXs Map of index to coordinate\n * @param itemSizes Map of index to size\n * @param maxSize Full size of the grid\n * @param defaultItemSize Default size of an item\n * @returns The Index of the last index visible\n */\n getLastIndexViewport(\n items: VisibleIndex[],\n itemXs: CoordinateMap,\n itemSizes: SizeMap,\n maxSize: number,\n defaultItemSize: number\n ): VisibleIndex {\n let lastIndex = 0;\n let dataSize = 0;\n if (items.length > 0) {\n lastIndex = items[items.length - 1];\n dataSize =\n getOrThrow(itemXs, lastIndex) + getOrThrow(itemSizes, lastIndex);\n }\n\n if (dataSize < maxSize) {\n lastIndex += Math.ceil((maxSize - dataSize) / defaultItemSize);\n }\n\n return lastIndex;\n }\n\n /**\n * Get the size from the provided size map of the specified item\n * @param modelIndex The model index to get the size for\n * @param userSizes The user set sizes\n * @param getDefaultSize Method to get the default size for this item\n * @returns The size from the provided size map of the specified item\n */\n getVisibleItemSize(\n modelIndex: ModelIndex,\n userSizes: ModelSizeMap,\n getDefaultSize: () => number\n ): number {\n return userSizes.get(modelIndex) ?? getDefaultSize();\n }\n\n /**\n * Get the height of the specified row\n * @param row Index of the row to get the height of\n * @param state The grid metric state\n * @returns The height of the row specified\n */\n getVisibleRowHeight(row: VisibleIndex, state: GridMetricState): number {\n const modelRow = this.getModelRow(row, state);\n const calculatedHeight = this.calculateRowHeight(row, modelRow, state); // Need to call this so calculated map is always populated\n\n return this.getVisibleItemSize(modelRow, this.userRowHeights, () => {\n const initialHeight = this.initialRowHeights.get(modelRow);\n if (initialHeight !== undefined) {\n return initialHeight;\n }\n return calculatedHeight;\n });\n }\n\n /**\n * Get the width of the specified column\n * @param column Index of the column to get the width of\n * @param state The grid metric state\n * @param firstColumn Index of first visible column\n * @param treePaddingX The amount of tree padding to add to the first visible column\n * @returns The width of the column\n */\n getVisibleColumnWidth(\n column: VisibleIndex,\n state: GridMetricState,\n firstColumn: VisibleIndex = this.getFirstColumn(state),\n treePaddingX: number = this.calculateTreePaddingX(state)\n ): number {\n const modelColumn = this.getModelColumn(column, state);\n\n // Need to call this so calculated map is always populated\n const calculatedWidth = this.calculateColumnWidth(\n column,\n modelColumn,\n state,\n firstColumn,\n treePaddingX\n );\n\n return this.getVisibleItemSize(modelColumn, this.userColumnWidths, () => {\n const initialWidth = this.initialColumnWidths.get(modelColumn);\n if (initialWidth !== undefined) {\n return initialWidth;\n }\n return calculatedWidth;\n });\n }\n\n /**\n * Get a map of VisibleIndex to ModelIndex\n * @param visibleRows Array of visible row indexes\n * @param state The grid metric state\n * @returns Map of VisibleIndex to ModelIndex\n */\n getModelRows(\n visibleRows: VisibleIndex[],\n state: GridMetricState\n ): VisibleToModelMap {\n const modelRows = new Map();\n for (let i = 0; i < visibleRows.length; i += 1) {\n const visibleRow = visibleRows[i];\n const modelRow = this.getModelRow(visibleRow, state);\n modelRows.set(visibleRow, modelRow);\n }\n return modelRows;\n }\n\n /**\n * Get the ModelIndex of the specified row\n * @param visibleRow Index of the row\n * @param state The grid metric state\n * @returns ModelIndex of the row\n */\n getModelRow(visibleRow: VisibleIndex, state: GridMetricState): ModelIndex {\n if (this.modelRows.has(visibleRow)) {\n return getOrThrow(this.modelRows, visibleRow);\n }\n const { movedRows } = state;\n const modelRow = GridUtils.getModelIndex(visibleRow, movedRows);\n this.modelRows.set(visibleRow, modelRow);\n return modelRow;\n }\n\n /**\n * Get a map of Index to ModelIndex. Applies the move operations to get the transformation.\n * @param visibleColumns Array of visible column indexes\n * @param state The grid metric state\n * @returns Map of Index to ModelIndex\n */\n getModelColumns(\n visibleColumns: VisibleIndex[],\n state: GridMetricState\n ): VisibleToModelMap {\n const modelColumns = new Map();\n for (let i = 0; i < visibleColumns.length; i += 1) {\n const visibleColumn = visibleColumns[i];\n const modelColumn = this.getModelColumn(visibleColumn, state);\n modelColumns.set(visibleColumn, modelColumn);\n }\n return modelColumns;\n }\n\n /**\n * Get the ModelIndex of the specified column\n * @param visibleColumn Index of the column\n * @param state The grid metric state\n * @returns ModelIndex of the column\n */\n getModelColumn(\n visibleColumn: VisibleIndex,\n state: GridMetricState\n ): ModelIndex {\n const hasVisibleColumn = this.modelColumns.has(visibleColumn);\n if (hasVisibleColumn) {\n return getOrThrow(this.modelColumns, visibleColumn);\n }\n const { movedColumns } = state;\n const modelColumn = GridUtils.getModelIndex(visibleColumn, movedColumns);\n this.modelColumns.set(visibleColumn, modelColumn);\n return modelColumn;\n }\n\n /**\n * Calculate the height of the row specified.\n * @param row Index of the row to calculate the height for\n * @param modelRow ModelIndex of the row to calculate the height\n * @param state The grid metric state\n * @returns The height of the row\n */\n calculateRowHeight(\n row: VisibleIndex,\n modelRow: ModelIndex,\n state: GridMetricState\n ): number {\n const { theme } = state;\n const { autoSizeRows, rowHeight } = theme;\n if (!autoSizeRows) {\n return rowHeight;\n }\n\n const cachedValue = this.calculatedRowHeights.get(modelRow);\n if (cachedValue != null) {\n return cachedValue;\n }\n\n // Not sure how to accurately get the height of text. For now just return the theme height.\n this.calculatedRowHeights.set(modelRow, Math.ceil(rowHeight));\n trimMap(this.calculatedRowHeights);\n return rowHeight;\n }\n\n /**\n * Calculates the column width based on the provided column model index\n * @param column Index of the column to calculate the width for\n * @param modelColumn ModelIndex of the column to calculate the width\n * @param state The grid metric state\n * @param firstColumn The first visible column\n * @param treePaddingX Tree padding offset for expandable rows\n * @returns The width of the column\n */\n calculateColumnWidth(\n column: VisibleIndex,\n modelColumn: ModelIndex,\n state: GridMetricState,\n firstColumn: VisibleIndex = this.getFirstColumn(state),\n treePaddingX: number = this.calculateTreePaddingX(state)\n ): number {\n const { theme } = state;\n const { autoSizeColumns, minColumnWidth } = theme;\n if (!autoSizeColumns) {\n const { columnWidth } = theme;\n return columnWidth;\n }\n\n const headerWidth = this.calculateColumnHeaderWidth(modelColumn, state);\n const dataWidth = this.calculateColumnDataWidth(modelColumn, state);\n const cachedValue = this.calculatedColumnWidths.get(modelColumn);\n let columnWidth = Math.ceil(Math.max(headerWidth, dataWidth));\n columnWidth = Math.max(minColumnWidth, columnWidth);\n if (cachedValue != null && cachedValue > columnWidth) {\n columnWidth = cachedValue;\n } else {\n this.calculatedColumnWidths.set(modelColumn, columnWidth);\n trimMap(this.calculatedColumnWidths);\n }\n\n if (column === firstColumn) {\n columnWidth += treePaddingX;\n }\n\n return columnWidth;\n }\n\n /**\n * Calculate the width of the specified column's header\n * @param modelColumn ModelIndex of the column to get the header width for\n * @param state The grid metric state\n * @returns The calculated width of the column header\n */\n calculateColumnHeaderWidth(\n modelColumn: ModelIndex,\n state: GridMetricState\n ): number {\n const { model, theme } = state;\n const { headerFont, headerHorizontalPadding } = theme;\n\n const headerText = model.textForColumnHeader(modelColumn, 0);\n if (headerText !== undefined && headerText !== '') {\n const headerFontWidth = this.getWidthForFont(headerFont, state);\n return headerText.length * headerFontWidth + headerHorizontalPadding * 2;\n }\n\n return headerHorizontalPadding * 2;\n }\n\n /**\n * Calculate the width of the specified column's data\n * @param modelColumn ModelIndex of the column to get the data width for\n * @param state The grid metric state\n * @returns The calculated width of the column data\n */\n calculateColumnDataWidth(\n modelColumn: ModelIndex,\n state: GridMetricState\n ): number {\n const { top, height, width, model, theme } = state;\n const { floatingTopRowCount, floatingBottomRowCount, rowCount } = model;\n const {\n font,\n cellHorizontalPadding,\n rowHeight,\n rowHeaderWidth,\n rowFooterWidth,\n scrollBarSize,\n } = theme;\n\n let columnWidth = 0;\n\n const fontWidth = this.getWidthForFont(font, state);\n const rowsPerPage = height / rowHeight;\n const bottom = Math.ceil(top + rowsPerPage);\n GridUtils.iterateAllItems(\n top,\n bottom,\n floatingTopRowCount,\n floatingBottomRowCount,\n rowCount,\n row => {\n const modelRow = this.getModelRow(row, state);\n const text = model.textForCell(modelColumn, modelRow);\n if (text) {\n const cellPadding = cellHorizontalPadding * 2;\n columnWidth = Math.max(\n columnWidth,\n text.length * fontWidth + cellPadding\n );\n }\n }\n );\n\n columnWidth = Math.max(\n Math.min(\n columnWidth,\n (width - rowHeaderWidth - scrollBarSize - rowFooterWidth) *\n GridMetricCalculator.MAX_COLUMN_WIDTH\n ),\n cellHorizontalPadding * 2\n );\n\n return columnWidth;\n }\n\n /**\n * The coordinate for where the tree padding should be drawn\n * @param state The grid metric state\n * @returns The coordinate for tree padding\n */\n calculateTreePaddingX(state: GridMetricState): Coordinate {\n const { top, height, model, theme } = state;\n const { rowHeight, treeDepthIndent } = theme;\n if (!isExpandableGridModel(model) || !model.hasExpandableRows) {\n return 0;\n }\n let treePadding = 0;\n\n const rowsPerPage = height / rowHeight;\n const bottom = Math.ceil(top + rowsPerPage);\n for (let row = top; row <= bottom; row += 1) {\n const modelRow = this.getModelRow(row, state);\n const depth = model.depthForRow(modelRow);\n treePadding = Math.max(treePadding, treeDepthIndent * (depth + 1));\n }\n\n return treePadding;\n }\n\n /**\n * Get the width of the provided font. Exploits the fact that we're\n * using tabular figures so every character is same width\n * @param font The font to get the width for\n * @param state The grid metric state\n * @returns Width of the char `8` for the specified font\n */\n getWidthForFont(font: GridFont, state: GridMetricState): number {\n if (this.fontWidths.has(font)) {\n return getOrThrow(this.fontWidths, font);\n }\n const { context } = state;\n context.font = font;\n const textMetrics = context.measureText('8');\n const { width } = textMetrics;\n\n // context.font changes the string a little bit, e.g. '10px Arial, sans serif' => '10px Arial, \"sans serif\"'\n // Rather than require checking with the correct font def (theme, or context font), just key it to both\n this.fontWidths.set(font, width);\n this.fontWidths.set(context.font, width);\n\n return width;\n }\n\n /**\n * Sets the width for the specified column\n * @param column The column model index to set\n * @param size The size to set it to\n */\n setColumnWidth(column: ModelIndex, size: number): void {\n // Always use a new instance of the map so any consumer of the metrics knows there has been a change\n const userColumnWidths = new Map(this.userColumnWidths);\n userColumnWidths.set(column, Math.ceil(size));\n trimMap(userColumnWidths);\n this.userColumnWidths = userColumnWidths;\n }\n\n /**\n * Resets the column width for the specified column to the calculated width\n * @param column The column model index to reset\n */\n resetColumnWidth(column: ModelIndex): void {\n // Always use a new instance of the map so any consumer of the metrics knows there has been a change\n const userColumnWidths = new Map(this.userColumnWidths);\n userColumnWidths.delete(column);\n this.userColumnWidths = userColumnWidths;\n }\n\n /**\n * Sets the width for the specified row\n * @param row The row model index to set\n * @param size The size to set it to\n */\n setRowHeight(row: ModelIndex, size: number): void {\n // Always use a new instance of the map so any consumer of the metrics knows there has been a change\n const userRowHeights = new Map(this.userRowHeights);\n userRowHeights.set(row, Math.ceil(size));\n trimMap(userRowHeights);\n this.userRowHeights = userRowHeights;\n }\n\n /**\n * Resets the row height for the specified row to the calculated height\n * @param row The row model index to reset\n */\n resetRowHeight(row: ModelIndex): void {\n // Always use a new instance of the map so any consumer of the metrics knows there has been a change\n const userRowHeights = new Map(this.userRowHeights);\n userRowHeights.delete(row);\n this.userRowHeights = userRowHeights;\n this.calculatedRowHeights.delete(row);\n }\n}\n\nexport default GridMetricCalculator;\n","/** A color parsed as CSS color value, eg. '#FF0000' */\nexport type GridColor = string;\n\n/** A nullable color, eg. pass `null` to skip drawing this item */\nexport type NullableGridColor = GridColor | null;\n\n/** One or more colors parsed as CSS color value separated by space, eg. '#FF0000 #00FF00' */\nexport type GridColorWay = string;\n\n/** A font parsed as CSS font value */\nexport type GridFont = string;\n\nexport type GridTheme = {\n // Allow column/row resizing\n allowColumnResize: boolean;\n allowRowResize: boolean;\n\n // Select the full row/column upon selection\n autoSelectRow: boolean;\n autoSelectColumn: boolean;\n\n // Automatically size rows/columns to fit contents\n autoSizeColumns: boolean;\n autoSizeRows: boolean;\n\n // The background color for the whole grid\n backgroundColor: GridColor;\n\n // Color to draw text\n textColor: GridColor;\n hyperlinkColor: GridColor;\n\n // Black and white to use if needed\n black: GridColor;\n white: GridColor;\n\n // Amount of padding within a cell and header\n cellHorizontalPadding: number;\n headerHorizontalPadding: number;\n\n // The font to use in the grid\n font: GridFont;\n\n // Colors to draw grid lines between columns and rows\n gridColumnColor: NullableGridColor;\n gridRowColor: NullableGridColor;\n\n // Colors for drawing the column and row headers\n headerBackgroundColor: GridColor;\n headerSeparatorColor: GridColor;\n headerSeparatorHoverColor: GridColor;\n headerSeparatorHandleSize: number;\n headerHiddenSeparatorSize: number;\n headerHiddenSeparatorHoverColor: GridColor;\n headerColor: GridColor;\n headerFont: GridFont;\n\n // Background color to highlight entire column/row if set\n columnHoverBackgroundColor: NullableGridColor;\n selectedColumnHoverBackgroundColor: NullableGridColor;\n rowHoverBackgroundColor: NullableGridColor;\n selectedRowHoverBackgroundColor: NullableGridColor;\n\n // Background colors to draw for each row, cycling through each value (eg. alternating stripes)\n rowBackgroundColors: GridColorWay;\n\n // Scroll bar look and sizing\n minScrollHandleSize: number;\n scrollBarBackgroundColor: GridColor;\n scrollBarHoverBackgroundColor: GridColor;\n scrollBarCasingColor: GridColor;\n scrollBarCornerColor: GridColor;\n scrollBarColor: GridColor;\n scrollBarHoverColor: GridColor;\n scrollBarActiveColor: GridColor;\n scrollBarSize: number;\n scrollBarHoverSize: number;\n scrollBarCasingWidth: number;\n scrollSnapToColumn: boolean;\n scrollSnapToRow: boolean;\n\n scrollBarSelectionTick: boolean;\n scrollBarSelectionTickColor: NullableGridColor;\n scrollBarActiveSelectionTickColor: NullableGridColor;\n\n // Look of the current selection\n selectionColor: GridColor;\n selectionOutlineColor: GridColor;\n selectionOutlineCasingColor: GridColor;\n\n // Shadows to draw when representing a hierarchy, eg. when one row is a higher \"depth\" than the row above it\n shadowBlur: number;\n shadowColor: GridColor;\n maxDepth: number; // max depth of the shadowing\n\n // Other tree table metrics\n treeDepthIndent: number;\n treeHorizontalPadding: number;\n treeLineColor: GridColor;\n treeMarkerColor: GridColor;\n treeMarkerHoverColor: GridColor;\n\n // Default row height/column width\n rowHeight: number;\n columnWidth: number;\n minRowHeight: number;\n minColumnWidth: number;\n\n // Default row/column header/footers width/height\n columnHeaderHeight: number;\n rowHeaderWidth: number;\n rowFooterWidth: number;\n\n // When resizing the header, will snap to the auto size of the header within this threshold\n headerResizeSnapThreshold: number;\n headerResizeHiddenSnapThreshold: number;\n\n // Allow moving/reordering columns/rows\n allowColumnReorder: boolean;\n allowRowReorder: boolean;\n\n // The number of pixels to offset a column/row while it is being dragged to move\n reorderOffset: number;\n\n // Colors for the grid in floating sections\n floatingGridColumnColor: NullableGridColor;\n floatingGridRowColor: NullableGridColor;\n\n // Background row colors for grid in the floating sections\n floatingRowBackgroundColors: GridColorWay;\n\n // Divider colors between the floating parts and the grid\n floatingDividerOuterColor: GridColor;\n floatingDividerInnerColor: GridColor;\n};\n\n/**\n * Default theme for a Grid.\n */\nconst defaultTheme: GridTheme = Object.freeze({\n allowColumnResize: true,\n allowRowResize: true,\n autoSelectRow: false, // Select the full row upon selection\n autoSelectColumn: false, // Select the full column upon selection\n autoSizeColumns: true, // Automatically size the columns to fit content\n autoSizeRows: true,\n backgroundColor: '#000000',\n black: '#000000',\n white: '#ffffff',\n cellHorizontalPadding: 5,\n headerHorizontalPadding: 5,\n font: '12px Arial, sans serif',\n gridColumnColor: '#8f8f8f66',\n gridRowColor: '#8f8f8f66',\n headerBackgroundColor: '#222222',\n headerSeparatorColor: '#000000',\n headerSeparatorHoverColor: '#888888',\n headerSeparatorHandleSize: 5,\n headerHiddenSeparatorSize: 5,\n headerHiddenSeparatorHoverColor: '#8888FF',\n headerColor: '#d5d5d5',\n headerFont: '10px Arial, sans serif',\n columnHoverBackgroundColor: '#444444',\n selectedColumnHoverBackgroundColor: '#494949',\n rowBackgroundColors: '#333333 #222222',\n rowHoverBackgroundColor: '#444444',\n selectedRowHoverBackgroundColor: '#494949',\n minScrollHandleSize: 50,\n scrollBarBackgroundColor: '#111111',\n scrollBarHoverBackgroundColor: '#333333',\n scrollBarCasingColor: '#000000',\n scrollBarCornerColor: '#000000',\n scrollBarColor: '#555555',\n scrollBarHoverColor: '#888888',\n scrollBarActiveColor: '#AAAAAA',\n scrollBarSize: 12,\n scrollBarHoverSize: 16,\n scrollBarCasingWidth: 1,\n scrollSnapToColumn: false,\n scrollSnapToRow: false,\n selectionColor: '#4286f433',\n selectionOutlineColor: '#4286f4',\n selectionOutlineCasingColor: '#222222',\n scrollBarSelectionTick: true,\n scrollBarSelectionTickColor: '#4286f433',\n scrollBarActiveSelectionTickColor: '#4286f480',\n shadowBlur: 8,\n shadowColor: '#000000',\n textColor: '#ffffff',\n hyperlinkColor: '#4878ea',\n maxDepth: 6,\n treeDepthIndent: 10,\n treeHorizontalPadding: 5,\n treeLineColor: '#888888',\n treeMarkerColor: '#cccccc',\n treeMarkerHoverColor: '#ffffff',\n\n rowHeight: 20,\n columnWidth: 100,\n minRowHeight: 20,\n minColumnWidth: 55,\n columnHeaderHeight: 20,\n rowHeaderWidth: 30,\n rowFooterWidth: 0,\n\n // When resizing the header, will snap to the auto size of the header within this threshold\n headerResizeSnapThreshold: 10,\n headerResizeHiddenSnapThreshold: 8,\n\n allowColumnReorder: true,\n allowRowReorder: true,\n reorderOffset: 2,\n\n // Colors for the grid in floating sections\n floatingGridColumnColor: '#8f8f8f66',\n floatingGridRowColor: '#8f8f8f66',\n\n // Background row colors for grid in the floating sections\n floatingRowBackgroundColors: '#393939 #292929',\n\n // Divider colors between the floating parts and the grid\n floatingDividerOuterColor: '#000000',\n floatingDividerInnerColor: '#cccccc',\n});\n\nexport default defaultTheme;\n","/**\n * Extension of memoizee that clears the entire cache when it's full.\n * This avoids the situation where LRU cache starts thrashing when it fills up.\n * Could look at writing our own memoize with a smarter cache to avoid overhead of\n * LRU queue, but this should be sufficient for now.\n */\nimport memoizee from 'memoizee';\n\n/**\n * @param fn The function to memoize\n * @param options The options to set for memoization\n */\nexport const memoizeClear: typeof memoizee = (fn, options) => {\n let isClearingCache = false;\n const memoizedFn = memoizee(fn, {\n ...options,\n dispose: () => {\n // Need to track when we're clearing because dispose gets called for all items removed\n if (!isClearingCache) {\n isClearingCache = true;\n memoizedFn.clear();\n isClearingCache = false;\n }\n },\n });\n\n return memoizedFn;\n};\n\nexport default memoizeClear;\n","import convert from 'color-convert';\nimport { HEX } from 'color-convert/conversions';\nimport { GridColor } from './GridTheme';\n\n/**\n * Darken the provided colour\n * @param color Color in hex format to convert (with #)\n * @param depth Depth to convert the color to\n * @param maxDepth Maximum depth. Defaults to 6\n * @returns Darkened colour in hex format\n */\nexport function darkenForDepth(\n color: HEX,\n depth: number,\n maxDepth = 6\n): GridColor {\n const lab = convert.hex.lab.raw(color);\n lab[0] = Math.max(lab[0] - (lab[0] / maxDepth) * depth, 0);\n return `#${convert.lab.hex(lab)}`;\n}\n\n/**\n * Convert a hex colour to an rgba with specified alpha\n * @param color Color in hex format to convert (with #)\n * @param alpha Alpha to apply to the color\n * @returns Color with the newly applied alpha in rgba format\n */\nexport function colorWithAlpha(color: HEX, alpha: number): GridColor {\n const [r, g, b] = convert.hex.rgb(color);\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n}\n\nexport default { colorWithAlpha, darkenForDepth };\n","/* eslint class-methods-use-this: \"off\" */\n/* eslint no-unused-vars: \"off\" */\nimport { EventHandlerResult } from './EventHandlerResult';\nimport Grid from './Grid';\nimport { GridPoint } from './GridUtils';\n\n/**\n * Some events we listen to are a native mouse event, and others are wrapped with React's SyntheticEvent.\n * The GridMouseHandler shouldn't care though - the properties it accesses should be common on both types of events.\n */\nexport type GridMouseEvent = MouseEvent | React.MouseEvent;\n\nexport type GridWheelEvent = WheelEvent | React.WheelEvent;\n\nexport type GridMouseHandlerFunctionName =\n | 'onDown'\n | 'onMove'\n | 'onDrag'\n | 'onLeave'\n | 'onClick'\n | 'onContextMenu'\n | 'onDoubleClick'\n | 'onUp'\n | 'onWheel';\n\n/**\n * Define a region in the grid that interacts with the mouse on a grid.\n * Return true from any of the events to indicate they're consumed, and stopPropagation/preventDefault will be called.\n */\nexport class GridMouseHandler {\n order: number;\n\n // What order this mouse handler should trigger in. Smaller numbers trigger first\n // Default to well below any of the GRID mouse handlers 100-1000+\n constructor(order = 5000) {\n this.order = order;\n }\n\n // Cursor to use if this returns any truthy value including { stopPropagation: false, preventDefault: false }\n cursor: string | null = null;\n\n onDown(\n gridPoint: GridPoint,\n grid: Grid,\n event: GridMouseEvent\n ): EventHandlerResult {\n return false;\n }\n\n onMove(\n gridPoint: GridPoint,\n grid: Grid,\n event: GridMouseEvent\n ): EventHandlerResult {\n return false;\n }\n\n onDrag(\n gridPoint: GridPoint,\n grid: Grid,\n event: GridMouseEvent\n ): EventHandlerResult {\n return false;\n }\n\n onLeave(\n gridPoint: GridPoint,\n grid: Grid,\n event: GridMouseEvent\n ): EventHandlerResult {\n return false;\n }\n\n onClick(\n gridPoint: GridPoint,\n grid: Grid,\n event: GridMouseEvent\n ): EventHandlerResult {\n return false;\n }\n\n onContextMenu(\n gridPoint: GridPoint,\n grid: Grid,\n event: GridMouseEvent\n ): EventHandlerResult {\n return false;\n }\n\n onDoubleClick(\n gridPoint: GridPoint,\n grid: Grid,\n event: GridMouseEvent\n ): EventHandlerResult {\n return false;\n }\n\n onUp(\n gridPoint: GridPoint,\n grid: Grid,\n event: GridMouseEvent\n ): EventHandlerResult {\n return false;\n }\n\n onWheel(\n gridPoint: GridPoint,\n grid: Grid,\n event: GridMouseEvent\n ): EventHandlerResult {\n return false;\n }\n}\n\nexport default GridMouseHandler;\n","import { getOrThrow } from '@deephaven/utils';\nimport type Grid from '../Grid';\nimport type { GridMetricCalculator } from '../GridMetricCalculator';\nimport type GridModel from '../GridModel';\nimport { EventHandlerResult } from '../EventHandlerResult';\nimport GridMetrics, { ModelIndex, VisibleIndex } from '../GridMetrics';\nimport GridMouseHandler from '../GridMouseHandler';\nimport type { GridTheme } from '../GridTheme';\nimport type { GridPoint } from '../GridUtils';\n\n// The different properties that can be used by implementing classes, whether for rows or columns\nexport type PointProperty = 'x' | 'y';\nexport type UserSizeProperty = 'userRowHeights' | 'userColumnWidths';\nexport type VisibleOffsetProperty = 'visibleRowYs' | 'visibleColumnXs';\nexport type VisibleSizeProperty = 'visibleRowHeights' | 'visibleColumnWidths';\nexport type MarginProperty = 'columnHeaderHeight' | 'rowHeaderWidth';\nexport type CalculatedSizeProperty =\n | 'calculatedRowHeights'\n | 'calculatedColumnWidths';\nexport type InitialSizeProperty = 'initialRowHeights' | 'initialColumnWidths';\nexport type ModelIndexesProperty = 'modelRows' | 'modelColumns';\nexport type FirstIndexProperty = 'firstRow' | 'firstColumn';\nexport type TreePaddingProperty = 'treePaddingX' | 'treePaddingY';\nexport interface GridSeparator {\n index: VisibleIndex;\n depth: number;\n}\n\n/**\n * Abstract class that should be extended for column/row behaviour\n * Override the necessary functions/properties\n */\nabstract class GridSeparatorMouseHandler extends GridMouseHandler {\n // The index where dragging the column separator started\n protected draggingIndex?: VisibleIndex;\n\n // The columns in the order they're being resized\n protected resizingItems: VisibleIndex[] = [];\n\n // Columns that were hidden under the separator when starting a drag\n protected hiddenItems: VisibleIndex[] = [];\n\n // The target width of the columns being resized\n protected targetSizes: Map<ModelIndex, number> = new Map();\n\n protected dragOffset = 0;\n\n // Override/Implement these properties/functions\n abstract hiddenCursor: string;\n\n abstract defaultCursor: string;\n\n abstract pointProperty: PointProperty;\n\n abstract userSizesProperty: UserSizeProperty;\n\n abstract visibleOffsetProperty: VisibleOffsetProperty;\n\n abstract visibleSizesProperty: VisibleSizeProperty;\n\n abstract marginProperty: MarginProperty;\n\n abstract calculatedSizesProperty: CalculatedSizeProperty;\n\n abstract initialSizesProperty: InitialSizeProperty;\n\n abstract modelIndexesProperty: ModelIndexesProperty;\n\n abstract firstIndexProperty: FirstIndexProperty;\n\n abstract treePaddingProperty: TreePaddingProperty;\n\n abstract getHiddenItems(\n itemIndex: VisibleIndex,\n metrics: GridMetrics\n ): VisibleIndex[];\n\n abstract getNextShownItem(\n itemIndex: VisibleIndex,\n metrics: GridMetrics\n ): VisibleIndex | null;\n\n abstract setSize(\n metricCalculator: GridMetricCalculator,\n modelIndex: ModelIndex,\n size: number\n ): void;\n\n abstract resetSize(\n metricCalculator: GridMetricCalculator,\n modelIndex: ModelIndex\n ): void;\n\n abstract updateSeparator(grid: Grid, separator: GridSeparator | null): void;\n\n abstract getSeparator(\n gridPoint: GridPoint,\n metrics: GridMetrics,\n model: GridModel,\n theme: GridTheme\n ): GridSeparator | null;\n // End of overrides\n\n onDown(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n const { metrics } = grid;\n const { model } = grid.props;\n const theme = grid.getTheme();\n if (!metrics) throw new Error('metrics not set');\n\n const separator = this.getSeparator(gridPoint, metrics, model, theme);\n if (separator != null) {\n const separatorIndex = separator.index;\n\n this.dragOffset = 0;\n this.draggingIndex = separatorIndex;\n this.resizingItems = [separatorIndex];\n this.hiddenItems = this.getHiddenItems(separatorIndex, metrics).reverse();\n this.targetSizes.clear();\n\n this.addTargetSize(metrics, separatorIndex);\n\n this.updateCursor(metrics, separatorIndex);\n\n this.updateSeparator(grid, separator);\n\n return true;\n }\n return false;\n }\n\n onMove(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n const { metrics } = grid;\n const { model } = grid.props;\n const theme = grid.getTheme();\n if (!metrics) throw new Error('metrics not set');\n\n const separator = this.getSeparator(gridPoint, metrics, model, theme);\n\n if (separator != null) {\n this.updateCursor(metrics, separator.index);\n return true;\n }\n return false;\n }\n\n onDrag(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n if (this.draggingIndex == null) {\n return false;\n }\n\n const point = gridPoint[this.pointProperty];\n const { metricCalculator, metrics } = grid;\n if (!metrics) throw new Error('metrics not set');\n\n const theme = grid.getTheme();\n\n const visibleOffsets = metrics[this.visibleOffsetProperty];\n const margin = metrics[this.marginProperty];\n const calculatedSizes = metrics[this.calculatedSizesProperty];\n const modelIndexes = metrics[this.modelIndexesProperty];\n const firstIndex = metrics[this.firstIndexProperty];\n const treePadding = metrics[this.treePaddingProperty];\n\n // New sizes are batched and applied after the loop to avoid updating state while calculating next step\n const newSizes: Map<ModelIndex, number> = new Map();\n\n // Use a loop as we may need to resize multiple items if they drag quickly\n let resizeIndex: number | null = this.resizingItems[\n this.resizingItems.length - 1\n ];\n while (resizeIndex != null) {\n const itemOffset = getOrThrow(visibleOffsets, resizeIndex);\n const itemSize = point - margin - itemOffset - this.dragOffset;\n const modelIndex = getOrThrow(modelIndexes, resizeIndex);\n const targetSize = this.targetSizes.get(modelIndex);\n const isResizingMultiple = this.resizingItems.length > 1;\n const hiddenIndex = this.hiddenItems.indexOf(resizeIndex);\n let calculatedSize = getOrThrow(calculatedSizes, modelIndex);\n if (resizeIndex === firstIndex) {\n calculatedSize += treePadding;\n }\n let newSize = itemSize;\n if (\n Math.abs(itemSize - calculatedSize) <= theme.headerResizeSnapThreshold\n ) {\n // Snapping behaviour to \"natural\" width\n newSize = calculatedSize;\n } else if (\n targetSize !== undefined &&\n itemSize > targetSize &&\n ((isResizingMultiple && hiddenIndex !== 0) || hiddenIndex > 0)\n ) {\n newSize = targetSize;\n } else if (itemSize <= theme.headerResizeHiddenSnapThreshold) {\n // Snapping to hidden item\n newSize = 0;\n }\n\n newSizes.set(modelIndex, newSize);\n\n if (itemSize < -theme.headerResizeSnapThreshold && newSize === 0) {\n if (hiddenIndex >= 0 && isResizingMultiple) {\n this.resizingItems.pop();\n this.removeTargetSize(metrics, resizeIndex);\n resizeIndex = this.resizingItems[this.resizingItems.length - 1];\n this.dragOffset -=\n this.targetSizes.get(getOrThrow(modelIndexes, resizeIndex)) ?? 0;\n } else {\n resizeIndex = this.getNextShownItem(resizeIndex, metrics);\n if (resizeIndex !== null) {\n this.resizingItems.push(resizeIndex);\n this.addTargetSize(metrics, resizeIndex);\n }\n }\n } else if (\n targetSize !== undefined &&\n itemSize > targetSize + theme.headerResizeSnapThreshold &&\n newSize === targetSize\n ) {\n if (hiddenIndex > 0) {\n this.dragOffset += newSize;\n resizeIndex = this.hiddenItems[hiddenIndex - 1];\n this.resizingItems.push(resizeIndex);\n this.addTargetSize(metrics, resizeIndex);\n } else if (isResizingMultiple) {\n this.resizingItems.pop();\n this.removeTargetSize(metrics, resizeIndex);\n resizeIndex = this.resizingItems[this.resizingItems.length - 1];\n } else {\n resizeIndex = null;\n }\n } else {\n resizeIndex = null;\n }\n }\n\n newSizes.forEach((newSize, modelIndex) => {\n const defaultSize =\n metricCalculator[this.initialSizesProperty].get(modelIndex) ??\n calculatedSizes.get(modelIndex);\n\n if (newSize === defaultSize) {\n this.resetSize(metricCalculator, modelIndex);\n } else {\n this.setSize(metricCalculator, modelIndex, newSize);\n }\n });\n\n this.updateCursor(metrics, this.draggingIndex);\n\n return true;\n }\n\n onUp(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n if (this.draggingIndex != null) {\n this.draggingIndex = undefined;\n this.resizingItems = [];\n this.hiddenItems = [];\n this.targetSizes.clear();\n\n this.updateSeparator(grid, null);\n }\n\n return false;\n }\n\n onDoubleClick(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n const { metrics, metricCalculator } = grid;\n const { model } = grid.props;\n const theme = grid.getTheme();\n if (!metrics) throw new Error('metrics not set');\n\n const separator = this.getSeparator(gridPoint, metrics, model, theme);\n\n if (separator != null) {\n const modelIndexes = metrics[this.modelIndexesProperty];\n const modelIndex = getOrThrow(modelIndexes, separator.index);\n\n const calculatedSize = getOrThrow(\n metrics[this.calculatedSizesProperty],\n modelIndex\n );\n const defaultSize = metricCalculator[this.initialSizesProperty].get(\n modelIndex\n );\n\n if (calculatedSize === defaultSize) {\n this.resetSize(metricCalculator, modelIndex);\n } else {\n this.setSize(metricCalculator, modelIndex, calculatedSize);\n }\n\n grid.forceUpdate();\n\n return true;\n }\n return false;\n }\n\n updateCursor(metrics: GridMetrics, itemIndex: VisibleIndex): void {\n const visibleSizes = metrics[this.visibleSizesProperty];\n const itemSize = getOrThrow(visibleSizes, itemIndex);\n if (itemSize === 0) {\n this.cursor = this.hiddenCursor;\n } else {\n this.cursor = this.defaultCursor;\n }\n }\n\n addTargetSize(metrics: GridMetrics, itemIndex: VisibleIndex): void {\n const modelIndexes = metrics[this.modelIndexesProperty];\n const userSizes = metrics[this.userSizesProperty];\n const calculatedSizes = metrics[this.calculatedSizesProperty];\n const treePadding = itemIndex === 0 ? metrics[this.treePaddingProperty] : 0;\n\n const modelIndex = getOrThrow(modelIndexes, itemIndex);\n let targetSize = userSizes.get(modelIndex);\n if (targetSize == null || targetSize === 0) {\n targetSize = getOrThrow(calculatedSizes, modelIndex) + treePadding;\n }\n this.targetSizes.set(modelIndex, targetSize);\n }\n\n removeTargetSize(metrics: GridMetrics, itemIndex: VisibleIndex): void {\n const modelIndexes = metrics[this.modelIndexesProperty];\n const modelIndex = getOrThrow(modelIndexes, itemIndex);\n this.targetSizes.delete(modelIndex);\n }\n}\n\nexport default GridSeparatorMouseHandler;\n","/* eslint class-methods-use-this: \"off\" */\nimport Grid from '../Grid';\nimport GridMetricCalculator from '../GridMetricCalculator';\nimport type { ModelIndex, GridMetrics } from '../GridMetrics';\nimport type GridModel from '../GridModel';\nimport type { GridTheme } from '../GridTheme';\nimport GridUtils, { GridPoint } from '../GridUtils';\nimport GridSeparatorMouseHandler, {\n GridSeparator,\n} from './GridSeparatorMouseHandler';\n\nclass GridColumnSeparatorMouseHandler extends GridSeparatorMouseHandler {\n static getColumnSeparator(\n gridPoint: GridPoint,\n metrics: GridMetrics,\n model: GridModel,\n theme: GridTheme\n ): GridSeparator | null {\n if (!theme.allowColumnResize) {\n return null;\n }\n\n const { x, y, columnHeaderDepth } = gridPoint;\n\n const { modelColumns } = metrics;\n\n const separatorIndex = GridUtils.getColumnSeparatorIndex(\n x,\n y,\n metrics,\n theme\n );\n\n // TODO #695: Allow resizing of column groups as well. Right now just allow resizing from base columns\n if (\n separatorIndex == null ||\n columnHeaderDepth == null ||\n columnHeaderDepth > 0\n ) {\n return null;\n }\n\n const columnIndex = modelColumns.get(separatorIndex);\n if (columnIndex != null) {\n return { index: separatorIndex, depth: 0 };\n }\n\n return null;\n }\n\n hiddenCursor = 'e-resize';\n\n defaultCursor = 'col-resize';\n\n pointProperty = 'x' as const;\n\n userSizesProperty = 'userColumnWidths' as const;\n\n visibleOffsetProperty = 'visibleColumnXs' as const;\n\n visibleSizesProperty = 'visibleColumnWidths' as const;\n\n marginProperty = 'rowHeaderWidth' as const;\n\n calculatedSizesProperty = 'calculatedColumnWidths' as const;\n\n initialSizesProperty = 'initialColumnWidths' as const;\n\n modelIndexesProperty = 'modelColumns' as const;\n\n firstIndexProperty = 'firstColumn' as const;\n\n treePaddingProperty = 'treePaddingX' as const;\n\n getHiddenItems = GridUtils.getHiddenColumns;\n\n getNextShownItem = GridUtils.getNextShownColumn;\n\n setSize(\n metricCalculator: GridMetricCalculator,\n modelIndex: ModelIndex,\n size: number\n ): void {\n metricCalculator.setColumnWidth(modelIndex, size);\n }\n\n resetSize(\n metricCalculator: GridMetricCalculator,\n modelIndex: ModelIndex\n ): void {\n metricCalculator.resetColumnWidth(modelIndex);\n }\n\n updateSeparator(grid: Grid, separator: GridSeparator | null): void {\n grid.setState({\n draggingColumnSeparator: separator,\n isDragging: separator !== null,\n });\n }\n\n getSeparator = GridColumnSeparatorMouseHandler.getColumnSeparator;\n}\n\nexport default GridColumnSeparatorMouseHandler;\n","import clamp from 'lodash.clamp';\nimport { ColorUtils, EMPTY_ARRAY, getOrThrow } from '@deephaven/utils';\nimport memoizeClear from './memoizeClear';\nimport GridUtils, { Token, TokenBox } from './GridUtils';\nimport GridColorUtils from './GridColorUtils';\nimport { isExpandableGridModel } from './ExpandableGridModel';\nimport { GridColor, GridColorWay, NullableGridColor } from './GridTheme';\nimport { BoxCoordinates, Coordinate, VisibleIndex } from './GridMetrics';\nimport { isEditableGridModel } from './EditableGridModel';\nimport GridColumnSeparatorMouseHandler from './mouse-handlers/GridColumnSeparatorMouseHandler';\nimport { BoundedAxisRange } from './GridAxisRange';\nimport { GridRenderState } from './GridRendererTypes';\n\ntype NoneNullColumnRange = { startColumn: number; endColumn: number };\n\ntype NoneNullRowRange = { startRow: number; endRow: number };\n\n/* eslint react/destructuring-assignment: \"off\" */\n/* eslint class-methods-use-this: \"off\" */\n/* eslint no-param-reassign: \"off\" */\n/**\n * A GridRenderer handles rendering the different parts of the grid\n * This default rendering just renders a basic grid. Extend this class and implement\n * your own methods to customize drawing of the grid (eg. Draw icons or special features)\n */\nexport class GridRenderer {\n // Default font width in pixels if it cannot be retrieved from the context\n static DEFAULT_FONT_WIDTH = 10;\n\n // Default radius in pixels for corners for some elements (like the active cell)\n static DEFAULT_EDGE_RADIUS = 2;\n\n // Default width in pixels for the border of the active cell\n static ACTIVE_CELL_BORDER_WIDTH = 2;\n\n /**\n * Truncate a string to the specified length and add ellipses if necessary\n * @param str The string to truncate\n * @param len The length to truncate the string to. If longer than the actual string, just returns the string\n * @returns The truncated string\n */\n static truncate(str: string, len: number): string {\n if (len < str.length) {\n // eslint-disable-next-line prefer-template\n return str.substr(0, len) + '…';\n }\n return str;\n }\n\n /**\n * Uses binary search to truncate a string to fit in the provided width\n * @param context The drawing context to measure the text in\n * @param str The string to get the maximum length it can draw\n * @param width The width to truncate it to\n * @param start The low boundary to start the search\n * @param end The high boundary to start the search\n * @param truncationChar This char will be repeated as the display string if the string is truncated instead of just adding an ellipsis\n * @returns The truncated string\n */\n static binaryTruncateToWidth(\n context: CanvasRenderingContext2D,\n str: string,\n width: number,\n start = 0,\n end = str.length,\n truncationChar?: string\n ): string {\n if (end >= str.length && context.measureText(str).width <= width) {\n // IDS-6069 If the whole string can fit, don't bother checking for truncation\n // The ellipses are actually slightly wider than other chars, and it's possible\n // that the \"truncation\" ends up being slightly longer, which messes up the search\n // algorithm below.\n // Besides, if we already fit, it's just faster to not bother checking other truncations.\n return str;\n }\n\n if (truncationChar !== undefined) {\n const charWidth = context.measureText(truncationChar).width;\n return truncationChar.repeat(Math.max(1, Math.floor(width / charWidth)));\n }\n\n let lo = start;\n let hi = Math.min(str.length - 1, end);\n let result = str;\n while (hi >= lo) {\n const mid = Math.ceil((hi + lo) / 2);\n const truncatedStr = GridRenderer.truncate(str, mid);\n if (context.measureText(truncatedStr).width <= width) {\n result = truncatedStr;\n if (lo === mid) {\n break;\n }\n lo = mid;\n } else if (mid === 0) {\n // We already truncated to zero chars and it still doesn't fit, no need to keep looking\n result = truncatedStr;\n break;\n } else {\n hi = mid - 1;\n }\n }\n\n return result;\n }\n\n /**\n * Truncate a string (if necessary) to fit in the specified width.\n * First uses the estimated font width to calculate a lower/upper bound\n * Then uses binary search within those bounds to find the exact max length\n * @param context The drawing context\n * @param str The string to calculate max length for\n * @param width The width to truncate within\n * @param fontWidth The estimated width of each character\n * @param truncationChar This char will be repeated as the display string if the string is truncated instead of just adding an ellipsis\n * @returns The truncated string that fits within the width provided\n */\n static truncateToWidth(\n context: CanvasRenderingContext2D,\n str: string,\n width: number,\n fontWidth = GridRenderer.DEFAULT_FONT_WIDTH,\n truncationChar?: string\n ): string {\n if (width <= 0 || str.length <= 0) {\n return '';\n }\n\n // Estimate the possible low and high boundaries for truncating the text\n // Use the width of the space divided by the estimated width of each character,\n // and take half that as the low (minus 5 just to be extra safe), and double that as the high.\n const lo = Math.min(\n Math.max(0, Math.floor(width / fontWidth / 2) - 5),\n str.length\n );\n const hi = Math.min(Math.ceil((width / fontWidth) * 2), str.length);\n\n return GridRenderer.binaryTruncateToWidth(\n context,\n str,\n width,\n lo,\n hi,\n truncationChar\n );\n }\n\n /**\n * Draw the grid canvas with the state provided\n * @param state The state of the grid\n */\n drawCanvas(state: GridRenderState): void {\n const { context } = state;\n\n context.save();\n\n this.configureContext(context, state);\n\n this.drawBackground(context, state);\n\n this.drawGrid(context, state);\n\n this.drawHeaders(context, state);\n\n this.drawFooters(context, state);\n\n this.drawDraggingColumn(context, state);\n\n this.drawDraggingRow(context, state);\n\n this.drawScrollBars(context, state);\n\n context.restore();\n }\n\n configureContext(\n context: CanvasRenderingContext2D,\n state: GridRenderState\n ): void {\n const { theme } = state;\n context.font = theme.font;\n context.textBaseline = 'middle';\n context.lineCap = 'butt';\n }\n\n drawBackground(\n context: CanvasRenderingContext2D,\n state: GridRenderState\n ): void {\n const { theme, metrics } = state;\n const { width, height } = metrics;\n context.fillStyle = theme.backgroundColor;\n context.fillRect(0, 0, width, height);\n }\n\n drawGrid(context: CanvasRenderingContext2D, state: GridRenderState): void {\n const { metrics, draggingRow, draggingColumn } = state;\n const { gridX, gridY } = metrics;\n\n context.translate(gridX, gridY);\n\n this.drawGridBackground(\n context,\n state,\n draggingRow == null && draggingColumn == null\n );\n\n this.drawCellContents(context, state);\n\n this.drawFloatingRows(context, state);\n\n this.drawFloatingColumns(context, state);\n\n context.translate(-gridX, -gridY);\n }\n\n drawFloatingRows(\n context: CanvasRenderingContext2D,\n state: GridRenderState\n ): void {\n const { draggingRow, draggingColumn, metrics, theme } = state;\n const {\n floatingTopRowCount,\n floatingBottomRowCount,\n floatingRows,\n rowCount,\n visibleColumns,\n allRowYs,\n allRowHeights,\n } = metrics;\n\n if (floatingRows.length === 0) {\n return;\n }\n\n if (theme.floatingRowBackgroundColors) {\n this.drawRowStripesForRows(\n context,\n state,\n floatingRows,\n theme.floatingRowBackgroundColors\n );\n }\n\n if (draggingRow == null && draggingColumn == null) {\n this.drawFloatingMouseRowHover(context, state);\n }\n\n this.drawGridLinesForItems(\n context,\n state,\n visibleColumns,\n floatingRows,\n theme.floatingGridColumnColor,\n theme.floatingGridRowColor\n );\n\n this.drawCellBackgroundsForItems(\n context,\n state,\n visibleColumns,\n floatingRows\n );\n\n this.drawFloatingBorders(context, state);\n\n // Draw the floating row selection...\n if (floatingTopRowCount > 0) {\n this.drawSelectedRanges(context, state, {\n top: 0,\n bottom: floatingTopRowCount - 1,\n maxY:\n getOrThrow(allRowYs, floatingTopRowCount - 1) +\n getOrThrow(allRowHeights, floatingTopRowCount - 1) -\n 0.5,\n });\n }\n if (floatingBottomRowCount > 0) {\n this.drawSelectedRanges(context, state, {\n top: rowCount - floatingBottomRowCount - 1,\n bottom: rowCount - 1,\n minY: getOrThrow(allRowYs, rowCount - floatingBottomRowCount) + 0.5,\n maxY:\n getOrThrow(allRowYs, rowCount - 1) +\n getOrThrow(allRowHeights, rowCount - 1) -\n 0.5,\n });\n }\n\n // Draw the cell content...\n for (let c = 0; c < visibleColumns.length; c += 1) {\n const column = visibleColumns[c];\n for (let r = 0; r < floatingRows.length; r += 1) {\n const row = floatingRows[r];\n this.drawCellContent(context, state, column, row);\n }\n }\n }\n\n drawFloatingColumns(\n context: CanvasRenderingContext2D,\n state: GridRenderState\n ): void {\n const { draggingRow, draggingColumn, metrics, theme } = state;\n const {\n floatingLeftColumnCount,\n floatingRightColumnCount,\n floatingLeftWidth,\n floatingRightWidth,\n floatingColumns,\n gridX,\n maxX,\n columnCount,\n visibleRows,\n allColumnXs,\n allColumnWidths,\n width,\n height,\n } = metrics;\n\n if (floatingColumns.length === 0) {\n return;\n }\n\n if (theme.floatingRowBackgroundColors) {\n this.drawRowStripesForRows(\n context,\n state,\n visibleRows,\n theme.floatingRowBackgroundColors,\n 0,\n floatingLeftWidth\n );\n this.drawRowStripesForRows(\n context,\n state,\n visibleRows,\n theme.floatingRowBackgroundColors,\n width - gridX - floatingRightWidth,\n maxX\n );\n }\n\n if (draggingRow == null && draggingColumn == null) {\n this.drawFloatingMouseRowHover(context, state);\n }\n\n // Clip floated column grid lines.\n context.save();\n context.beginPath();\n context.rect(0, 0, floatingLeftWidth, height);\n context.clip();\n\n this.drawGridLinesForItems(\n context,\n state,\n floatingColumns,\n visibleRows,\n theme.floatingGridColumnColor,\n theme.floatingGridRowColor\n );\n\n context.restore();\n\n this.drawCellBackgroundsForItems(\n context,\n state,\n floatingColumns,\n visibleRows\n );\n\n this.drawFloatingBorders(context, state);\n\n // Draw the floating column selection...\n if (floatingLeftColumnCount > 0) {\n this.drawSelectedRanges(context, state, {\n left: 0,\n maxX:\n getOrThrow(allColumnXs, floatingLeftColumnCount - 1) +\n getOrThrow(allColumnWidths, floatingLeftColumnCount - 1),\n });\n }\n if (floatingRightColumnCount > 0) {\n this.drawSelectedRanges(context, state, {\n left: columnCount - floatingRightColumnCount,\n right: columnCount - 1,\n minX:\n getOrThrow(allColumnXs, columnCount - floatingRightColumnCount) + 0.5,\n maxX:\n getOrThrow(allColumnXs, columnCount - 1) +\n getOrThrow(allColumnWidths, columnCount - 1),\n });\n }\n\n // Draw the cell content...\n for (let c = 0; c < floatingColumns.length; c += 1) {\n const column = floatingColumns[c];\n for (let r = 0; r < visibleRows.length; r += 1) {\n const row = visibleRows[r];\n this.drawCellContent(context, state, column, row);\n }\n }\n }\n\n drawFloatingBorders(\n context: CanvasRenderingContext2D,\n state: GridRenderState\n ): void {\n const { metrics, theme } = state;\n const {\n floatingTopRowCount,\n floatingBottomRowCount,\n floatingLeftColumnCount,\n floatingRightColumnCount,\n rowCount,\n columnCount,\n allRowYs,\n allColumnXs,\n allRowHeights,\n allColumnWidths,\n maxX,\n maxY,\n } = metrics;\n const { floatingDividerOuterColor, floatingDividerInnerColor } = theme;\n\n context.lineWidth = 3;\n context.beginPath();\n context.strokeStyle = floatingDividerOuterColor;\n\n if (floatingTopRowCount > 0) {\n const y =\n getOrThrow(allRowYs, floatingTopRowCount - 1) +\n getOrThrow(allRowHeights, floatingTopRowCount - 1) +\n 0.5;\n context.moveTo(0, y);\n context.lineTo(maxX, y);\n }\n\n if (floatingBottomRowCount > 0) {\n const y = getOrThrow(allRowYs, rowCount - floatingBottomRowCount) - 0.5;\n context.moveTo(0, y);\n context.lineTo(maxX, y);\n }\n\n if (floatingLeftColumnCount > 0) {\n const x =\n getOrThrow(allColumnXs, floatingLeftColumnCount - 1) +\n getOrThrow(allColumnWidths, floatingLeftColumnCount - 1) +\n 0.5;\n context.moveTo(x, 0);\n context.lineTo(x, maxY);\n }\n\n if (floatingRightColumnCount > 0) {\n const x =\n getOrThrow(allColumnXs, columnCount - floatingRightColumnCount) - 0.5;\n context.moveTo(x, 0);\n context.lineTo(x, maxY);\n }\n\n context.stroke();\n\n context.beginPath();\n context.lineWidth = 1;\n context.strokeStyle = floatingDividerInnerColor;\n\n if (floatingTopRowCount > 0) {\n const y =\n getOrThrow(allRowYs, floatingTopRowCount - 1) +\n getOrThrow(allRowHeights, floatingTopRowCount - 1) +\n 0.5;\n context.moveTo(0, y);\n context.lineTo(maxX, y);\n }\n\n if (floatingBottomRowCount > 0) {\n const y = getOrThrow(allRowYs, rowCount - floatingBottomRowCount) - 0.5;\n context.moveTo(0, y);\n context.lineTo(maxX, y);\n }\n\n if (floatingLeftColumnCount > 0) {\n const x =\n getOrThrow(allColumnXs, floatingLeftColumnCount - 1) +\n getOrThrow(allColumnWidths, floatingLeftColumnCount - 1) +\n 0.5;\n context.moveTo(x, 0);\n context.lineTo(x, maxY);\n }\n\n if (floatingRightColumnCount > 0) {\n const x =\n getOrThrow(allColumnXs, columnCount - floatingRightColumnCount) - 0.5;\n context.moveTo(x, 0);\n context.lineTo(x, maxY);\n }\n\n context.stroke();\n }\n\n drawGridBackground(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n drawHover = false\n ): void {\n this.drawRowStripes(context, state);\n\n if (drawHover) {\n this.drawMouseColumnHover(context, state);\n\n this.drawMouseRowHover(context, state);\n }\n\n this.drawGridLines(context, state);\n\n this.drawCellBackgrounds(context, state);\n\n const { metrics } = state;\n const {\n bottom,\n right,\n floatingBottomRowCount,\n floatingLeftColumnCount,\n floatingRightColumnCount,\n floatingTopRowCount,\n columnCount,\n rowCount,\n allRowHeights,\n allRowYs,\n allColumnXs,\n allColumnWidths,\n width,\n height,\n } = metrics;\n this.drawSelectedRanges(context, state, {\n bottom: Math.min(bottom, rowCount - floatingBottomRowCount - 1),\n right: Math.min(right, columnCount - floatingRightColumnCount - 1),\n minX:\n floatingLeftColumnCount > 0 &&\n allColumnXs.has(floatingLeftColumnCount + 1)\n ? getOrThrow(allColumnXs, floatingLeftColumnCount + 1)\n : -10,\n minY:\n floatingTopRowCount > 0 && allRowYs.has(floatingTopRowCount + 1)\n ? getOrThrow(allRowYs, floatingTopRowCount + 1)\n : -10,\n maxX:\n floatingRightColumnCount > 0 &&\n allColumnXs.has(columnCount - floatingRightColumnCount - 1)\n ? getOrThrow(\n allColumnXs,\n columnCount - floatingRightColumnCount - 1\n ) +\n getOrThrow(\n allColumnWidths,\n columnCount - floatingRightColumnCount - 1\n ) -\n 0.5\n : width + 10,\n maxY:\n floatingBottomRowCount > 0 &&\n allRowYs.has(rowCount - floatingBottomRowCount - 1)\n ? getOrThrow(allRowYs, rowCount - floatingBottomRowCount - 1) +\n getOrThrow(allRowHeights, rowCount - floatingBottomRowCount - 1) -\n 0.5\n : height + 10,\n });\n }\n\n drawRowStripes(\n context: CanvasRenderingContext2D,\n state: GridRenderState\n ): void {\n const { metrics, theme } = state;\n const { visibleRows } = metrics;\n const { rowBackgroundColors } = theme;\n if (!rowBackgroundColors) {\n return;\n }\n this.drawRowStripesForRows(\n context,\n state,\n visibleRows,\n rowBackgroundColors\n );\n }\n\n drawRowStripesForRows(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n rows: readonly VisibleIndex[],\n rowBackgroundColors: GridColorWay,\n minX = 0,\n maxX = state.metrics.maxX\n ): void {\n const { theme, metrics, model } = state;\n const { maxDepth, shadowBlur, shadowColor } = theme;\n\n const colorSets = this.getCachedBackgroundColors(\n rowBackgroundColors,\n maxDepth\n );\n const { allRowYs, allRowHeights } = metrics;\n\n // Optimize by grouping together all rows that end up with the same color\n const colorRowMap = new Map();\n const topShadowRows: VisibleIndex[] = []; // Rows that are deeper than the row above them\n const bottomShadowRows: VisibleIndex[] = [];\n const addRowToColorMap = (\n row: VisibleIndex,\n rowAbove?: VisibleIndex\n ): void => {\n const depth = isExpandableGridModel(model) ? model.depthForRow(row) : 0;\n const colorSet = colorSets[row % colorSets.length];\n const color = colorSet[Math.min(depth, colorSet.length - 1)];\n if (!colorRowMap.has(color)) {\n colorRowMap.set(color, []);\n }\n colorRowMap.get(color).push(row);\n if (rowAbove != null) {\n const depthAbove = isExpandableGridModel(model)\n ? model.depthForRow(rowAbove)\n : 0;\n if (depthAbove < depth) {\n topShadowRows.push(row);\n } else if (depthAbove > depth) {\n bottomShadowRows.push(rowAbove);\n }\n }\n };\n\n // Add all the regular row stripes\n for (let i = 0; i < rows.length; i += 1) {\n const row = rows[i];\n const rowAbove = i > 0 ? rows[i - 1] : undefined;\n addRowToColorMap(row, rowAbove);\n }\n\n colorRowMap.forEach((colorRows, color) => {\n context.fillStyle = color;\n\n context.beginPath();\n\n for (let i = 0; i < colorRows.length; i += 1) {\n const row = colorRows[i];\n const y = getOrThrow(allRowYs, row);\n const rowHeight = getOrThrow(allRowHeights, row);\n context.rect(minX, y, maxX, rowHeight);\n }\n\n context.fill();\n });\n\n if (topShadowRows.length > 0) {\n context.save();\n\n const startColor = this.getCachedColorWithAlpha(shadowColor, 0.15);\n const endColor = this.getCachedColorWithAlpha(shadowColor, 0);\n const gradient = context.createLinearGradient(0, 0, 0, shadowBlur);\n gradient.addColorStop(0, startColor);\n gradient.addColorStop(1, endColor);\n context.fillStyle = gradient;\n\n for (let i = 0; i < topShadowRows.length; i += 1) {\n const row = topShadowRows[i];\n const y = getOrThrow(allRowYs, row);\n // Use a translate so we can reuse the gradient\n context.translate(0, y);\n context.fillRect(minX, 0, maxX, shadowBlur);\n context.translate(0, -y);\n }\n\n context.restore();\n }\n\n if (bottomShadowRows.length > 0) {\n context.save();\n\n const startColor = this.getCachedColorWithAlpha(shadowColor, 0);\n const endColor = this.getCachedColorWithAlpha(shadowColor, 0.15);\n const gradient = context.createLinearGradient(0, 0, 0, shadowBlur);\n gradient.addColorStop(0, startColor);\n gradient.addColorStop(1, endColor);\n context.fillStyle = gradient;\n\n for (let i = 0; i < bottomShadowRows.length; i += 1) {\n const row = bottomShadowRows[i];\n const y = getOrThrow(allRowYs, row);\n const rowHeight = getOrThrow(allRowHeights, row);\n const gradientY = y + rowHeight - shadowBlur;\n // Use a translate so we can reuse the gradient\n context.translate(0, gradientY);\n context.fillRect(minX, 0, maxX, shadowBlur);\n context.translate(0, -gradientY);\n }\n\n context.restore();\n }\n }\n\n drawMouseColumnHover(\n context: CanvasRenderingContext2D,\n state: GridRenderState\n ): void {\n const { mouseX, mouseY, theme, metrics } = state;\n if (mouseX == null || mouseY == null) return;\n\n const mouseColumn = GridUtils.getColumnAtX(mouseX, metrics);\n if (mouseColumn == null || theme.columnHoverBackgroundColor == null) {\n return;\n }\n\n const { allColumnWidths, allColumnXs, maxY } = metrics;\n if (mouseY > maxY) {\n return;\n }\n\n const x = getOrThrow(allColumnXs, mouseColumn);\n const columnWidth = getOrThrow(allColumnWidths, mouseColumn);\n\n context.fillStyle = theme.columnHoverBackgroundColor;\n context.fillRect(x, 0, columnWidth, maxY);\n }\n\n drawMouseRowHover(\n context: CanvasRenderingContext2D,\n state: GridRenderState\n ): void {\n const { mouseX, mouseY, theme, metrics } = state;\n if (mouseX == null || mouseY == null) return;\n\n const { maxX } = metrics;\n if (mouseX > maxX || theme.rowHoverBackgroundColor == null) {\n return;\n }\n\n const mouseRow = GridUtils.getRowAtY(mouseY, metrics);\n if (mouseRow == null) {\n return;\n }\n\n this.drawMouseRowHoverForRow(context, state, mouseRow);\n }\n\n drawFloatingMouseRowHover(\n context: CanvasRenderingContext2D,\n state: GridRenderState\n ): void {\n const { mouseX, mouseY, theme, metrics } = state;\n const {\n maxX,\n floatingTopRowCount,\n floatingBottomRowCount,\n rowCount,\n rowFooterWidth,\n } = metrics;\n if (\n mouseX == null ||\n mouseY == null ||\n mouseX > maxX + rowFooterWidth ||\n theme.rowHoverBackgroundColor == null\n ) {\n return;\n }\n\n const mouseRow = GridUtils.getRowAtY(mouseY, metrics);\n if (\n mouseRow != null &&\n (mouseRow < floatingTopRowCount ||\n rowCount - floatingBottomRowCount <= mouseRow)\n ) {\n this.drawMouseRowHoverForRow(context, state, mouseRow);\n }\n }\n\n drawMouseRowHoverForRow(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n row: VisibleIndex\n ): void {\n const { metrics, selectedRanges, theme } = state;\n const { allRowHeights, allRowYs, maxX } = metrics;\n\n const y = getOrThrow(allRowYs, row);\n const rowHeight = getOrThrow(allRowHeights, row);\n\n if (theme.rowHoverBackgroundColor != null) {\n context.fillStyle = theme.rowHoverBackgroundColor;\n }\n for (let i = 0; i < selectedRanges.length; i += 1) {\n const { startRow, endRow } = selectedRanges[i];\n if (\n startRow != null &&\n endRow != null &&\n startRow <= row &&\n endRow >= row\n ) {\n if (theme.selectedRowHoverBackgroundColor != null) {\n context.fillStyle = theme.selectedRowHoverBackgroundColor;\n }\n break;\n }\n }\n context.fillRect(0, y, maxX, rowHeight);\n }\n\n drawGridLines(\n context: CanvasRenderingContext2D,\n state: GridRenderState\n ): void {\n const { metrics, theme } = state;\n const { visibleColumns, visibleRows } = metrics;\n\n this.drawGridLinesForItems(\n context,\n state,\n visibleColumns,\n visibleRows,\n theme.gridColumnColor,\n theme.gridRowColor\n );\n }\n\n drawGridLinesForItems(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n columns: readonly VisibleIndex[],\n rows: readonly VisibleIndex[],\n columnColor: NullableGridColor,\n rowColor: NullableGridColor\n ): void {\n if (columnColor == null && rowColor == null) {\n return;\n }\n\n context.lineWidth = 1;\n context.beginPath();\n\n if (columnColor != null) {\n context.strokeStyle = columnColor;\n this.drawGridLinesForColumns(context, state, columns);\n }\n if (rowColor != null) {\n context.strokeStyle = rowColor;\n this.drawGridLinesForRows(context, state, rows);\n }\n\n context.stroke();\n }\n\n drawGridLinesForColumns(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n columns: readonly VisibleIndex[]\n ): void {\n const { metrics } = state;\n const { allColumnXs, maxY } = metrics;\n for (let i = 0; i < columns.length; i += 1) {\n const column = columns[i];\n const x = getOrThrow(allColumnXs, column) + 0.5;\n context.moveTo(x, 0);\n context.lineTo(x, maxY);\n }\n }\n\n drawGridLinesForRows(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n rows: readonly VisibleIndex[]\n ): void {\n const { metrics } = state;\n const { allRowYs, maxX: metricsMaxX } = metrics;\n const maxX = metricsMaxX;\n\n // Draw row lines\n for (let i = 0; i < rows.length; i += 1) {\n const row = rows[i];\n const y = getOrThrow(allRowYs, row) + 0.5;\n context.moveTo(0.5, y);\n context.lineTo(maxX - 0.5, y);\n }\n }\n\n drawCellBackgrounds(\n context: CanvasRenderingContext2D,\n state: GridRenderState\n ): void {\n const { metrics } = state;\n const { visibleColumns, visibleRows } = metrics;\n this.drawCellBackgroundsForItems(\n context,\n state,\n visibleColumns,\n visibleRows\n );\n }\n\n drawCellBackgroundsForItems(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n columns: readonly VisibleIndex[],\n rows: readonly VisibleIndex[]\n ): void {\n context.save();\n\n for (let i = 0; i < columns.length; i += 1) {\n const column = columns[i];\n\n for (let j = 0; j < rows.length; j += 1) {\n const row = rows[j];\n const rowAfter = j + 1 < rows.length ? rows[j + 1] : undefined;\n this.drawCellBackground(context, state, column, row, rowAfter);\n }\n }\n\n context.restore();\n }\n\n drawCellBackground(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n column: VisibleIndex,\n row: VisibleIndex,\n rowAfter?: VisibleIndex\n ): void {\n const { metrics, model, theme } = state;\n const {\n firstColumn,\n modelColumns,\n modelRows,\n allColumnXs,\n allColumnWidths,\n allRowYs,\n allRowHeights,\n } = metrics;\n const modelRow = getOrThrow(modelRows, row);\n const modelColumn = getOrThrow(modelColumns, column);\n const backgroundColor = model.backgroundColorForCell(\n modelColumn,\n modelRow,\n theme\n );\n const isFirstColumn = column === firstColumn;\n const hasExpandableRows =\n isExpandableGridModel(model) && model.hasExpandableRows;\n\n if (backgroundColor != null) {\n const x = getOrThrow(allColumnXs, column) + 1;\n const y = getOrThrow(allRowYs, row) + 1;\n const columnWidth = getOrThrow(allColumnWidths, column) - 1;\n const rowHeight = getOrThrow(allRowHeights, row) - 1;\n context.fillStyle = backgroundColor;\n context.fillRect(x, y, columnWidth, rowHeight);\n }\n\n if (isFirstColumn && hasExpandableRows) {\n this.drawCellRowTreeDepthLines(context, state, row, rowAfter);\n }\n }\n\n drawCellContents(\n context: CanvasRenderingContext2D,\n state: GridRenderState\n ): void {\n const { metrics } = state;\n const { visibleColumns } = metrics;\n\n for (let i = 0; i < visibleColumns.length; i += 1) {\n const column = visibleColumns[i];\n this.drawColumnCellContents(context, state, column);\n }\n }\n\n drawColumnCellContents(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n column: VisibleIndex\n ): void {\n const { metrics } = state;\n const { allColumnXs, allColumnWidths, visibleRows, height } = metrics;\n const x = getOrThrow(allColumnXs, column);\n const columnWidth = getOrThrow(allColumnWidths, column);\n\n context.save();\n\n context.beginPath();\n context.rect(x, 0, columnWidth, height);\n context.clip();\n\n for (let i = 0; i < visibleRows.length; i += 1) {\n const row = visibleRows[i];\n this.drawCellContent(context, state, column, row);\n }\n context.restore();\n }\n\n /**\n * Gets textWidth and X-Y position for a specific cell\n * The textWidth returned is the width that the text can occupy accounting for any other cell markings\n * The width accounts for tree table indents and cell padding, so it is the width the text may consume\n *\n * @param state GridRenderState to get the text metrics for\n * @param column Column of cell to get text metrics for\n * @param row Row of cell to get text metrics for\n * @returns Object with width, x, and y of the text\n */\n getTextRenderMetrics(\n state: GridRenderState,\n column: VisibleIndex,\n row: VisibleIndex\n ): {\n width: number;\n x: number;\n y: number;\n } {\n const { metrics, model, theme } = state;\n const {\n firstColumn,\n allColumnXs,\n allColumnWidths,\n allRowYs,\n allRowHeights,\n modelRows,\n modelColumns,\n } = metrics;\n const {\n cellHorizontalPadding,\n treeDepthIndent,\n treeHorizontalPadding,\n } = theme;\n\n const modelRow = getOrThrow(modelRows, row);\n const modelColumn = getOrThrow(modelColumns, column);\n const textAlign = model.textAlignForCell(modelColumn, modelRow);\n const x = getOrThrow(allColumnXs, column);\n const y = getOrThrow(allRowYs, row);\n const columnWidth = getOrThrow(allColumnWidths, column);\n const rowHeight = getOrThrow(allRowHeights, row);\n const isFirstColumn = column === firstColumn;\n let treeIndent = 0;\n if (\n isExpandableGridModel(model) &&\n model.hasExpandableRows &&\n isFirstColumn\n ) {\n treeIndent =\n treeDepthIndent * (model.depthForRow(row) + 1) + treeHorizontalPadding;\n }\n const textWidth = columnWidth - treeIndent;\n let textX = x + cellHorizontalPadding;\n const textY = y + rowHeight * 0.5;\n if (textAlign === 'right') {\n textX = x + textWidth - cellHorizontalPadding;\n } else if (textAlign === 'center') {\n textX = x + textWidth * 0.5;\n }\n textX += treeIndent;\n\n return {\n width: textWidth - cellHorizontalPadding * 2,\n x: textX,\n y: textY,\n };\n }\n\n drawCellContent(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n column: VisibleIndex,\n row: VisibleIndex,\n textOverride?: string\n ): void {\n const { metrics, model, theme } = state;\n const {\n firstColumn,\n fontWidths,\n modelColumns,\n modelRows,\n allRowHeights,\n } = metrics;\n const { textColor } = theme;\n const rowHeight = getOrThrow(allRowHeights, row);\n const modelRow = getOrThrow(modelRows, row);\n const modelColumn = getOrThrow(modelColumns, column);\n const text = textOverride ?? model.textForCell(modelColumn, modelRow);\n const truncationChar = model.truncationCharForCell(modelColumn, modelRow);\n const isFirstColumn = column === firstColumn;\n\n if (text && rowHeight > 0) {\n const textAlign = model.textAlignForCell(modelColumn, modelRow) || 'left';\n context.textAlign = textAlign;\n\n const color =\n model.colorForCell(modelColumn, modelRow, theme) || textColor;\n context.fillStyle = color;\n\n context.save();\n\n const {\n width: textWidth,\n x: textX,\n y: textY,\n } = this.getTextRenderMetrics(state, column, row);\n\n const fontWidth =\n fontWidths.get(context.font) ?? GridRenderer.DEFAULT_FONT_WIDTH;\n const truncatedText = this.getCachedTruncatedString(\n context,\n text,\n textWidth,\n fontWidth,\n truncationChar\n );\n\n const tokens = model.tokensForCell(\n modelColumn,\n modelRow,\n truncatedText.length\n );\n\n if (truncatedText) {\n let tokenIndex = 0;\n let textStart = 0;\n let left = textX;\n const { actualBoundingBoxDescent } = context.measureText(truncatedText);\n\n while (textStart < truncatedText.length) {\n const nextToken = tokens[tokenIndex];\n const token = textStart === nextToken?.start ? nextToken : null;\n const textEnd =\n token?.end ?? nextToken?.start ?? truncatedText.length;\n const value = truncatedText.substring(textStart, textEnd);\n const { width } = context.measureText(value);\n const widthOfUnderline = value.endsWith('…')\n ? context.measureText(value.substring(0, value.length - 1)).width\n : width;\n\n // Set the styling based on the token, then draw the text\n if (token != null) {\n context.fillStyle = theme.hyperlinkColor;\n context.fillText(value, left, textY);\n context.fillRect(\n left,\n textY + actualBoundingBoxDescent,\n widthOfUnderline,\n 1\n );\n } else {\n context.fillStyle = color;\n context.fillText(value, left, textY);\n }\n\n left += width;\n textStart = textEnd;\n if (token != null) tokenIndex += 1;\n }\n }\n context.restore();\n }\n\n if (\n isFirstColumn &&\n isExpandableGridModel(model) &&\n model.hasExpandableRows\n ) {\n this.drawCellRowTreeMarker(context, state, row);\n }\n }\n\n drawCellRowTreeMarker(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n row: VisibleIndex\n ): void {\n const { metrics, model, mouseX, mouseY, theme } = state;\n const {\n firstColumn,\n gridX,\n gridY,\n allColumnXs,\n allColumnWidths,\n allRowYs,\n allRowHeights,\n visibleRowTreeBoxes,\n } = metrics;\n const { treeMarkerColor, treeMarkerHoverColor } = theme;\n const columnX = getOrThrow(allColumnXs, firstColumn);\n const columnWidth = getOrThrow(allColumnWidths, firstColumn);\n const rowY = getOrThrow(allRowYs, row);\n const rowHeight = getOrThrow(allRowHeights, row);\n if (!isExpandableGridModel(model) || !model.isRowExpandable(row)) {\n return;\n }\n\n const treeBox = getOrThrow(visibleRowTreeBoxes, row);\n const color =\n mouseX != null &&\n mouseY != null &&\n mouseX >= gridX + columnX &&\n mouseX <= gridX + columnX + columnWidth &&\n mouseY >= gridY + rowY &&\n mouseY <= gridY + rowY + rowHeight\n ? treeMarkerHoverColor\n : treeMarkerColor;\n\n this.drawTreeMarker(\n context,\n state,\n columnX,\n rowY,\n treeBox,\n color,\n model.isRowExpanded(row)\n );\n }\n\n drawTreeMarker(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n columnX: Coordinate,\n rowY: Coordinate,\n treeBox: BoxCoordinates,\n color: GridColor,\n isExpanded: boolean\n ): void {\n const { x1, y1, x2, y2 } = treeBox;\n const markerText = isExpanded ? '⊟' : '⊞';\n const textX = columnX + (x1 + x2) * 0.5 + 0.5;\n const textY = rowY + (y1 + y2) * 0.5 + 0.5;\n context.fillStyle = color;\n context.textAlign = 'center';\n context.fillText(markerText, textX, textY);\n }\n\n drawCellRowTreeDepthLines(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n row: VisibleIndex,\n rowAfter?: VisibleIndex\n ): void {\n const { metrics, model, theme } = state;\n\n if (!isExpandableGridModel(model)) return;\n\n const depth = model.depthForRow(row);\n if (depth === 0) return;\n\n const { firstColumn, allColumnXs, allRowYs, allRowHeights } = metrics;\n const { treeDepthIndent, treeHorizontalPadding, treeLineColor } = theme;\n const columnX = getOrThrow(allColumnXs, firstColumn);\n const rowY = getOrThrow(allRowYs, row);\n const rowHeight = getOrThrow(allRowHeights, row);\n const depthRowAfter =\n rowAfter !== undefined ? model.depthForRow(rowAfter) : 0;\n const depthDiff = depth > depthRowAfter ? depth - depthRowAfter : 0;\n\n context.strokeStyle = treeLineColor;\n context.lineWidth = 1;\n\n // draw normal depth lines\n if (depth - depthDiff > 0) {\n context.beginPath();\n for (let i = 0; i < depth - depthDiff; i += 1) {\n const lineX =\n columnX +\n i * treeDepthIndent +\n treeDepthIndent * 0.5 +\n treeHorizontalPadding +\n 0.5;\n context.moveTo(lineX, rowY);\n context.lineTo(lineX, rowY + rowHeight);\n }\n context.stroke();\n }\n\n // draw as hockey stick if last row at depth\n if (depthDiff > 0) {\n context.beginPath();\n for (let i = depth - depthDiff; i < depth; i += 1) {\n const lineX =\n columnX +\n i * treeDepthIndent +\n treeDepthIndent * 0.5 +\n treeHorizontalPadding +\n 0.5;\n context.moveTo(lineX, rowY);\n context.lineTo(lineX, rowY + Math.ceil(rowHeight / 2));\n // extra moveTo prevents halfpixel in corner\n context.moveTo(lineX - 0.5, rowY + Math.ceil(rowHeight / 2) + 0.5);\n context.lineTo(\n lineX + treeDepthIndent - 0.5,\n rowY + Math.ceil(rowHeight / 2) + 0.5\n );\n }\n context.stroke();\n }\n }\n\n getCachedTruncatedString = memoizeClear(\n (\n context: CanvasRenderingContext2D,\n text: string,\n width: number,\n fontWidth: number,\n truncationChar?: string\n ): string =>\n GridRenderer.truncateToWidth(\n context,\n text,\n width,\n fontWidth,\n truncationChar\n ),\n { max: 10000 }\n );\n\n getCachedBackgroundColors = memoizeClear(\n (backgroundColors: GridColorWay, maxDepth: number): GridColor[][] =>\n backgroundColors.split(' ').map(color => {\n const colors = [];\n for (let i = 0; i < maxDepth; i += 1) {\n colors.push(GridColorUtils.darkenForDepth(color, i, maxDepth));\n }\n return colors;\n }),\n { max: 1000 }\n );\n\n getCachedColorWithAlpha = memoizeClear(\n (color: string, alpha: number) =>\n GridColorUtils.colorWithAlpha(color, alpha),\n { max: 1000 }\n );\n\n getCachedColorIsDark = memoizeClear(\n (color: string) => ColorUtils.isDark(color),\n { max: 1000 }\n );\n\n drawHeaders(context: CanvasRenderingContext2D, state: GridRenderState): void {\n const { theme } = state;\n\n context.font = theme.headerFont;\n\n this.drawColumnHeaders(context, state);\n\n this.drawRowHeaders(context, state);\n }\n\n drawFooters(context: CanvasRenderingContext2D, state: GridRenderState): void {\n const { theme } = state;\n\n context.font = theme.headerFont;\n\n this.drawRowFooters(context, state);\n }\n\n drawColumnHeaders(\n context: CanvasRenderingContext2D,\n state: GridRenderState\n ): void {\n const {\n mouseX,\n mouseY,\n theme,\n metrics,\n draggingColumnSeparator,\n isDragging,\n model,\n } = state;\n const {\n columnHeaderHeight,\n floatingColumns,\n gridX,\n width,\n visibleColumns,\n allColumnWidths,\n allColumnXs,\n floatingLeftColumnCount,\n floatingLeftWidth,\n floatingRightWidth,\n modelColumns,\n columnHeaderMaxDepth,\n } = metrics;\n if (columnHeaderHeight <= 0) {\n return;\n }\n\n const {\n headerHiddenSeparatorSize,\n headerHiddenSeparatorHoverColor,\n headerSeparatorColor,\n headerSeparatorHoverColor,\n } = theme;\n const hiddenSeparatorHeight = columnHeaderHeight * 0.5;\n const hiddenY =\n columnHeaderHeight * (columnHeaderMaxDepth - 1) +\n columnHeaderHeight * 0.5 -\n hiddenSeparatorHeight * 0.5;\n const containsFrozenColumns = floatingLeftColumnCount > 0;\n\n context.save();\n\n this.drawColumnHeadersForRange(\n context,\n state,\n [visibleColumns[0], visibleColumns[visibleColumns.length - 1]],\n {\n minX: gridX + floatingLeftWidth,\n maxX: width - floatingRightWidth,\n }\n );\n\n if (containsFrozenColumns) {\n this.drawColumnHeadersForRange(\n context,\n state,\n [floatingColumns[0], floatingColumns[floatingColumns.length - 1]],\n {\n minX: gridX,\n maxX: gridX + floatingLeftWidth,\n }\n );\n }\n\n if (headerSeparatorColor) {\n context.strokeStyle = headerSeparatorColor;\n\n const hiddenColumns = [...allColumnWidths.entries()]\n .filter(([_, w]) => w === 0)\n .map(([index]) => index);\n\n // Now draw the hidden column separator boxes\n context.beginPath();\n context.fillStyle = headerSeparatorColor;\n for (let i = 0; i < hiddenColumns.length; i += 1) {\n const column = hiddenColumns[i];\n const columnX = getOrThrow(allColumnXs, column);\n const columnWidth = getOrThrow(allColumnWidths, column);\n const minX =\n gridX + columnX + columnWidth + 0.5 - headerHiddenSeparatorSize * 0.5;\n context.rect(\n minX,\n hiddenY,\n headerHiddenSeparatorSize,\n hiddenSeparatorHeight\n );\n }\n context.fill();\n }\n\n if (headerSeparatorHoverColor) {\n let { index: highlightedSeparator, depth } =\n draggingColumnSeparator ?? {};\n\n if (highlightedSeparator == null && mouseX != null && mouseY != null) {\n const separator = GridColumnSeparatorMouseHandler.getColumnSeparator(\n GridUtils.getGridPointFromXY(mouseX, mouseY, metrics),\n metrics,\n model,\n theme\n );\n highlightedSeparator = separator?.index;\n depth = separator?.depth;\n }\n\n let shouldDrawSeparator: boolean;\n\n if (highlightedSeparator == null) {\n shouldDrawSeparator = false;\n } else {\n const columnIndex = modelColumns.get(highlightedSeparator);\n const nextColumnIndex = modelColumns.get(highlightedSeparator + 1);\n if (columnIndex == null || nextColumnIndex == null) {\n shouldDrawSeparator = false;\n } else {\n shouldDrawSeparator =\n model.textForColumnHeader(columnIndex, depth) !==\n model.textForColumnHeader(nextColumnIndex, depth);\n }\n }\n\n if (\n shouldDrawSeparator &&\n highlightedSeparator != null &&\n depth != null &&\n (!isDragging || draggingColumnSeparator != null)\n ) {\n context.strokeStyle = headerSeparatorHoverColor;\n\n const columnX = getOrThrow(allColumnXs, highlightedSeparator);\n const columnWidth = getOrThrow(allColumnWidths, highlightedSeparator);\n const x = gridX + columnX + columnWidth + 0.5;\n const visibleColumnIndex = visibleColumns.indexOf(highlightedSeparator);\n const nextColumn =\n visibleColumnIndex < visibleColumns.length - 1\n ? visibleColumns[visibleColumnIndex + 1]\n : null;\n const nextColumnWidth =\n nextColumn != null ? allColumnWidths.get(nextColumn) : null;\n const isColumnHidden = columnWidth === 0;\n const isNextColumnHidden =\n nextColumnWidth != null && nextColumnWidth === 0;\n if (isColumnHidden) {\n context.strokeStyle = headerHiddenSeparatorHoverColor;\n context.fillStyle = headerHiddenSeparatorHoverColor;\n context.fillRect(\n x,\n hiddenY,\n headerHiddenSeparatorSize * 0.5,\n hiddenSeparatorHeight\n );\n } else if (isNextColumnHidden) {\n context.fillStyle = headerSeparatorHoverColor;\n context.fillRect(\n x - headerHiddenSeparatorSize * 0.5,\n hiddenY,\n headerHiddenSeparatorSize * 0.5,\n hiddenSeparatorHeight\n );\n }\n\n // column seperator hover line\n context.beginPath();\n context.moveTo(\n x,\n (columnHeaderMaxDepth - depth - 1) * columnHeaderHeight\n );\n context.lineTo(\n x,\n (columnHeaderMaxDepth - depth) * columnHeaderHeight - 1\n );\n context.stroke();\n }\n }\n\n context.restore();\n }\n\n drawColumnHeadersForRange(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n range: BoundedAxisRange,\n bounds: { minX: number; maxX: number }\n ): void {\n const { model } = state;\n const { columnHeaderMaxDepth } = model;\n\n if (columnHeaderMaxDepth === 0) {\n return;\n }\n\n for (let d = 0; d <= columnHeaderMaxDepth; d += 1) {\n this.drawColumnHeadersAtDepth(context, state, range, bounds, d);\n }\n }\n\n drawColumnHeadersAtDepth(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n range: BoundedAxisRange,\n bounds: { minX: number; maxX: number },\n depth: number\n ): void {\n const { metrics, model, theme } = state;\n const {\n modelColumns,\n allColumnXs,\n gridX,\n userColumnWidths,\n allColumnWidths,\n movedColumns,\n } = metrics;\n const { columnHeaderHeight, columnWidth } = theme;\n const { columnHeaderMaxDepth } = model;\n const { minX, maxX } = bounds;\n const visibleWidth = maxX - minX;\n\n if (columnHeaderMaxDepth === 0) {\n return;\n }\n\n const startIndex = range[0];\n const endIndex = range[1];\n\n context.save();\n context.translate(\n 0,\n (columnHeaderMaxDepth - depth - 1) * columnHeaderHeight\n );\n\n if (depth === 0) {\n // Make sure base column header background always goes to the right edge\n this.drawColumnHeader(context, state, '', minX, maxX);\n\n // Draw base column headers\n for (let i = startIndex; i <= endIndex; i += 1) {\n this.drawColumnHeaderAtIndex(context, state, i, bounds);\n }\n }\n\n // Draw column header group\n if (depth > 0) {\n let columnIndex = startIndex;\n\n while (columnIndex <= endIndex) {\n const { columnCount } = metrics;\n const modelColumn = getOrThrow(modelColumns, columnIndex);\n const columnGroupName = model.textForColumnHeader(modelColumn, depth);\n const columnGroupColor = model.colorForColumnHeader(modelColumn, depth);\n let columnGroupLeft = getOrThrow(allColumnXs, columnIndex) + gridX;\n let columnGroupRight =\n columnGroupLeft + getOrThrow(allColumnWidths, columnIndex);\n\n if (columnGroupName != null) {\n // Need to determine if the column group is at least the width of the bounds\n // And if the left/right of the group extend past the bounds\n // The group will be drawn as if it were a column with a max width of the bounds width\n let prevColumnIndex = columnIndex - 1;\n while (\n prevColumnIndex >= 0 &&\n (columnGroupRight - columnGroupLeft < visibleWidth ||\n columnGroupLeft > minX)\n ) {\n const prevModelIndex =\n modelColumns.get(prevColumnIndex) ??\n GridUtils.getModelIndex(prevColumnIndex, movedColumns);\n if (\n prevModelIndex == null ||\n model.textForColumnHeader(prevModelIndex, depth) !==\n columnGroupName\n ) {\n // Previous column not in the same group\n break;\n }\n\n const prevColumnWidth =\n userColumnWidths.get(prevModelIndex) ??\n allColumnWidths.get(prevColumnIndex) ??\n columnWidth;\n\n columnGroupLeft -= prevColumnWidth;\n prevColumnIndex -= 1;\n }\n\n let nextColumnIndex = columnIndex + 1;\n while (\n nextColumnIndex < columnCount &&\n (columnGroupRight - columnGroupLeft < visibleWidth ||\n columnGroupRight < maxX)\n ) {\n const nextModelIndex =\n modelColumns.get(nextColumnIndex) ??\n GridUtils.getModelIndex(nextColumnIndex, movedColumns);\n if (\n model.textForColumnHeader(nextModelIndex, depth) !==\n columnGroupName\n ) {\n // Next column not in the same group\n break;\n }\n\n const nextColumnWidth =\n userColumnWidths.get(nextModelIndex) ??\n allColumnWidths.get(nextColumnIndex) ??\n columnWidth;\n\n columnGroupRight += nextColumnWidth;\n nextColumnIndex += 1;\n }\n\n // Set column index to end of the current group\n columnIndex = nextColumnIndex - 1;\n\n const isFullWidth =\n columnGroupRight - columnGroupLeft >= visibleWidth;\n let x = columnGroupLeft;\n if (isFullWidth) {\n if (columnGroupRight < maxX) {\n x = columnGroupRight - visibleWidth;\n } else if (columnGroupLeft < minX) {\n x = minX;\n }\n }\n\n this.drawColumnHeader(\n context,\n state,\n columnGroupName,\n x,\n Math.min(columnGroupRight - columnGroupLeft, visibleWidth),\n {\n backgroundColor: columnGroupColor ?? undefined,\n },\n bounds\n );\n }\n columnIndex += 1;\n }\n }\n context.restore();\n }\n\n /**\n * Draws the column header for the given visible index\n * @param context Canvas context\n * @param state Grid render state\n * @param index Visible index of the column header to draw\n * @param bounds The horizontal bounds the header can be drawn in\n */\n drawColumnHeaderAtIndex(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n index: VisibleIndex,\n bounds: { minX: number; maxX: number }\n ): void {\n const { metrics, model } = state;\n const { modelColumns, allColumnWidths, allColumnXs, gridX } = metrics;\n const width = getOrThrow(allColumnWidths, index);\n const x = getOrThrow(allColumnXs, index) + gridX;\n const modelColumn = getOrThrow(modelColumns, index);\n const text = model.textForColumnHeader(modelColumn);\n\n if (text == null) {\n return;\n }\n\n this.drawColumnHeader(\n context,\n state,\n text,\n x,\n width,\n {\n backgroundColor: model.colorForColumnHeader(modelColumn) ?? undefined,\n },\n bounds\n );\n }\n\n drawColumnHeader(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n columnText: string,\n columnX: Coordinate,\n columnWidth: number,\n style?: {\n backgroundColor?: string;\n textColor?: string;\n separatorColor?: string;\n },\n bounds?: { minX?: number; maxX?: number }\n ): void {\n if (columnWidth <= 0) {\n return;\n }\n const { metrics, theme } = state;\n\n const {\n headerHorizontalPadding,\n columnHeaderHeight,\n headerBackgroundColor,\n headerColor,\n headerSeparatorColor,\n black,\n white,\n } = theme;\n const { fontWidths, width } = metrics;\n const fontWidth =\n fontWidths.get(context.font) ?? GridRenderer.DEFAULT_FONT_WIDTH;\n\n const maxWidth = columnWidth - headerHorizontalPadding * 2;\n const maxLength = maxWidth / fontWidth;\n\n const {\n backgroundColor = headerBackgroundColor,\n separatorColor = headerSeparatorColor,\n } = style ?? {};\n\n let { textColor = headerColor } = style ?? {};\n\n try {\n const isDarkBackground = this.getCachedColorIsDark(backgroundColor);\n const isDarkText = this.getCachedColorIsDark(textColor);\n if (isDarkBackground && isDarkText) {\n textColor = white;\n } else if (!isDarkBackground && !isDarkText) {\n textColor = black;\n }\n } catch {\n // Invalid color provided\n // no-op since we don't use logging in base grid\n }\n\n let { minX = 0, maxX = width } = bounds ?? {};\n\n context.save();\n context.rect(minX, 0, maxX - minX, columnHeaderHeight);\n context.clip();\n\n // Fill background color if specified\n if (backgroundColor != null) {\n context.fillStyle = backgroundColor;\n context.fillRect(columnX, 0, columnWidth, columnHeaderHeight);\n }\n\n if (separatorColor != null) {\n context.strokeStyle = separatorColor;\n context.beginPath();\n\n // Don't draw left separator if column touches the left edge\n if (columnX > 0) {\n context.moveTo(columnX + 0.5, 0);\n context.lineTo(columnX + 0.5, columnHeaderHeight);\n }\n context.moveTo(columnX + columnWidth + 0.5, 0);\n context.lineTo(columnX + columnWidth + 0.5, columnHeaderHeight);\n\n // Bottom Border, should be interior to the header height\n context.moveTo(columnX, columnHeaderHeight - 0.5);\n context.lineTo(columnX + columnWidth, columnHeaderHeight - 0.5);\n context.stroke();\n }\n\n context.beginPath();\n context.rect(columnX, 0, columnWidth, columnHeaderHeight);\n context.clip();\n context.fillStyle = textColor;\n\n let renderText = columnText;\n\n if (maxLength <= 0) {\n renderText = '';\n } else if (renderText.length > maxLength) {\n renderText = `${renderText.substring(0, maxLength - 1)}…`;\n }\n\n const textWidth = renderText.length * fontWidth;\n let x = columnX + columnWidth * 0.5;\n const y = columnHeaderHeight * 0.5;\n minX += headerHorizontalPadding;\n maxX -= headerHorizontalPadding;\n\n const columnLeft = columnX + headerHorizontalPadding;\n const visibleLeft = clamp(columnLeft, minX, maxX);\n const columnRight = columnX + columnWidth - headerHorizontalPadding;\n const visibleRight = clamp(columnRight, minX, maxX);\n const visibleWidth = visibleRight - visibleLeft;\n\n const isBeyondLeft = x - textWidth * 0.5 < minX;\n const isBeyondRight = x + textWidth * 0.5 > maxX;\n\n if (isBeyondLeft) {\n // Column name would be off the left side of the canvas\n if (textWidth < visibleWidth) {\n // Can render the entire text in the visible space. Stick to left\n x = minX + textWidth * 0.5;\n } else {\n x = columnRight - textWidth * 0.5;\n }\n } else if (isBeyondRight) {\n if (textWidth < visibleWidth) {\n // Can render the entire text in the visible space. Stick to right\n x = maxX - textWidth * 0.5;\n } else {\n x = columnLeft + textWidth * 0.5;\n }\n }\n context.textAlign = 'center';\n context.fillText(renderText, x, y);\n\n context.restore();\n }\n\n drawRowHeaders(\n context: CanvasRenderingContext2D,\n state: GridRenderState\n ): void {\n const { mouseX, mouseY, metrics, theme, draggingRowSeparator } = state;\n const {\n gridY,\n rowHeaderWidth,\n height,\n visibleRows,\n allRowHeights,\n allRowYs,\n } = metrics;\n if (rowHeaderWidth <= 0) {\n return;\n }\n\n const {\n headerBackgroundColor,\n headerColor,\n headerHiddenSeparatorSize,\n headerHiddenSeparatorHoverColor,\n headerSeparatorColor,\n headerSeparatorHoverColor,\n } = theme;\n const hiddenSeparatorWidth = rowHeaderWidth * 0.5;\n const hiddenX = rowHeaderWidth * 0.5 - hiddenSeparatorWidth * 0.5;\n\n context.save();\n\n context.beginPath();\n\n // Fill in the background\n context.fillStyle = headerBackgroundColor;\n context.fillRect(0, 0, rowHeaderWidth, height);\n\n // Draw the separators\n if (headerSeparatorColor) {\n context.strokeStyle = headerSeparatorColor;\n context.beginPath();\n context.moveTo(0, gridY + 0.5);\n context.lineTo(rowHeaderWidth, gridY + 0.5);\n\n const hiddenRows = [];\n let isPreviousRowHidden = false;\n for (let i = 0; i < visibleRows.length; i += 1) {\n const row = visibleRows[i];\n const rowY = getOrThrow(allRowYs, row);\n const rowHeight = getOrThrow(allRowHeights, row);\n if (rowHeight > 0) {\n const y = gridY + rowY + rowHeight + 0.5;\n\n context.moveTo(0, y);\n context.lineTo(rowHeaderWidth, y);\n\n isPreviousRowHidden = false;\n } else if (!isPreviousRowHidden) {\n isPreviousRowHidden = true;\n hiddenRows.push(row);\n }\n }\n\n // border right, interior to the headerWidth\n context.moveTo(rowHeaderWidth - 0.5, 0);\n context.lineTo(rowHeaderWidth - 0.5, height);\n\n context.stroke();\n\n // Draw the hidden column separators\n context.beginPath();\n context.fillStyle = headerSeparatorColor;\n for (let i = 0; i < hiddenRows.length; i += 1) {\n const row = hiddenRows[i];\n const rowY = getOrThrow(allRowYs, row);\n const rowHeight = getOrThrow(allRowHeights, row);\n const minY =\n gridY + rowY + rowHeight + 0.5 - headerHiddenSeparatorSize * 0.5;\n context.rect(\n hiddenX,\n minY,\n hiddenSeparatorWidth,\n headerHiddenSeparatorSize\n );\n }\n\n context.fill();\n }\n\n if (headerSeparatorHoverColor) {\n let { index: highlightedSeparator = null } = draggingRowSeparator ?? {};\n if (highlightedSeparator == null && mouseX != null && mouseY != null) {\n highlightedSeparator = GridUtils.getRowSeparatorIndex(\n mouseX,\n mouseY,\n metrics,\n theme\n );\n }\n\n if (highlightedSeparator != null) {\n context.strokeStyle = headerSeparatorHoverColor;\n\n const rowY = getOrThrow(allRowYs, highlightedSeparator);\n const rowHeight = getOrThrow(allRowHeights, highlightedSeparator);\n const y = gridY + rowY + rowHeight + 0.5;\n\n const visibleRowIndex = visibleRows.indexOf(highlightedSeparator);\n const nextRow =\n visibleRowIndex < visibleRows.length - 1\n ? visibleRows[visibleRowIndex + 1]\n : null;\n const nextRowHeight =\n nextRow != null ? allRowHeights.get(nextRow) : null;\n const isRowHidden = rowHeight === 0;\n const isNextRowHidden = nextRowHeight != null && nextRowHeight === 0;\n if (isRowHidden) {\n context.strokeStyle = headerHiddenSeparatorHoverColor;\n context.fillStyle = headerHiddenSeparatorHoverColor;\n context.fillRect(\n hiddenX,\n y,\n hiddenSeparatorWidth,\n headerHiddenSeparatorSize * 0.5\n );\n } else if (isNextRowHidden) {\n context.fillStyle = headerSeparatorHoverColor;\n context.fillRect(\n hiddenX,\n y - headerHiddenSeparatorSize * 0.5,\n hiddenSeparatorWidth,\n headerHiddenSeparatorSize * 0.5\n );\n }\n\n context.beginPath();\n context.moveTo(0.5, y);\n context.lineTo(rowHeaderWidth + 0.5, y);\n context.stroke();\n }\n }\n\n // Fill in the text\n context.beginPath();\n context.rect(0, gridY, rowHeaderWidth, height);\n context.clip();\n\n context.fillStyle = headerColor;\n context.textAlign = 'right';\n\n for (let i = 0; i < visibleRows.length; i += 1) {\n const row = visibleRows[i];\n const rowHeight = getOrThrow(allRowHeights, row);\n const y = getOrThrow(allRowYs, row) + gridY;\n this.drawRowHeader(context, state, row, y, rowHeight);\n }\n\n context.restore();\n }\n\n drawRowHeader(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n row: VisibleIndex,\n rowY: Coordinate,\n rowHeight: number\n ): void {\n if (rowHeight <= 0) {\n return;\n }\n const { metrics, model, theme } = state;\n const { modelRows, rowHeaderWidth } = metrics;\n const modelRow = getOrThrow(modelRows, row);\n const x = rowHeaderWidth - theme.cellHorizontalPadding;\n const y = rowY + rowHeight * 0.5;\n context.fillText(model.textForRowHeader(modelRow), x, y);\n }\n\n drawRowFooters(\n context: CanvasRenderingContext2D,\n state: GridRenderState\n ): void {\n const {\n mouseX,\n mouseY,\n metrics,\n model,\n theme,\n draggingRowSeparator,\n } = state;\n const {\n gridY,\n gridX,\n maxX,\n modelRows,\n rowFooterWidth,\n height,\n verticalBarWidth,\n visibleRows,\n allRowHeights,\n allRowYs,\n width,\n } = metrics;\n if (rowFooterWidth <= 0) {\n return;\n }\n\n const {\n cellHorizontalPadding,\n headerBackgroundColor,\n headerColor,\n headerHiddenSeparatorSize,\n headerHiddenSeparatorHoverColor,\n headerSeparatorColor,\n headerSeparatorHoverColor,\n } = theme;\n const hiddenSeparatorWidth = rowFooterWidth * 0.5;\n const hiddenX = rowFooterWidth * 0.5 - hiddenSeparatorWidth * 0.5;\n const x = Math.min(gridX + maxX, width - rowFooterWidth - verticalBarWidth);\n\n context.save();\n\n context.beginPath();\n\n // Fill in the background\n context.fillStyle = headerBackgroundColor;\n context.fillRect(x, gridY, rowFooterWidth, height);\n\n // Draw the separators\n if (headerSeparatorColor) {\n context.strokeStyle = headerSeparatorColor;\n context.beginPath();\n context.moveTo(x, gridY + 0.5);\n context.lineTo(rowFooterWidth, gridY + 0.5);\n\n const hiddenRows = [];\n let isPreviousRowHidden = false;\n for (let i = 0; i < visibleRows.length; i += 1) {\n const row = visibleRows[i];\n const rowY = getOrThrow(allRowYs, row);\n const rowHeight = getOrThrow(allRowHeights, row);\n if (rowHeight > 0) {\n const y = gridY + rowY + rowHeight + 0.5;\n\n context.moveTo(x + 0.5, y);\n context.lineTo(x + rowFooterWidth - 0.5, y);\n\n isPreviousRowHidden = false;\n } else if (!isPreviousRowHidden) {\n isPreviousRowHidden = true;\n hiddenRows.push(row);\n }\n }\n\n // border left, interior to the headerWidth\n context.moveTo(x + 0.5, gridY);\n context.lineTo(x + 0.5, height);\n\n context.stroke();\n\n // Draw the hidden column separators\n context.beginPath();\n context.fillStyle = headerSeparatorColor;\n for (let i = 0; i < hiddenRows.length; i += 1) {\n const row = hiddenRows[i];\n const rowY = getOrThrow(allRowYs, row);\n const rowHeight = getOrThrow(allRowHeights, row);\n const minY =\n gridY + rowY + rowHeight + 0.5 - headerHiddenSeparatorSize * 0.5;\n context.rect(\n x + hiddenX,\n minY,\n hiddenSeparatorWidth,\n headerHiddenSeparatorSize\n );\n }\n\n context.fill();\n }\n\n if (headerSeparatorHoverColor) {\n let { index: highlightedSeparator = null } = draggingRowSeparator ?? {};\n if (highlightedSeparator == null && mouseX != null && mouseY != null) {\n highlightedSeparator = GridUtils.getRowSeparatorIndex(\n mouseX,\n mouseY,\n metrics,\n theme\n );\n }\n\n if (highlightedSeparator != null) {\n context.strokeStyle = headerSeparatorHoverColor;\n\n const rowY = getOrThrow(allRowYs, highlightedSeparator);\n const rowHeight = getOrThrow(allRowHeights, highlightedSeparator);\n const y = gridY + rowY + rowHeight + 0.5;\n\n const visibleRowIndex = visibleRows.indexOf(highlightedSeparator);\n const nextRow =\n visibleRowIndex < visibleRows.length - 1\n ? visibleRows[visibleRowIndex + 1]\n : null;\n const nextRowHeight =\n nextRow != null ? allRowHeights.get(nextRow) : null;\n const isRowHidden = rowHeight === 0;\n const isNextRowHidden = nextRowHeight != null && nextRowHeight === 0;\n if (isRowHidden) {\n context.strokeStyle = headerHiddenSeparatorHoverColor;\n context.fillStyle = headerHiddenSeparatorHoverColor;\n context.fillRect(\n hiddenX,\n y,\n hiddenSeparatorWidth,\n headerHiddenSeparatorSize * 0.5\n );\n } else if (isNextRowHidden) {\n context.fillStyle = headerSeparatorHoverColor;\n context.fillRect(\n hiddenX,\n y - headerHiddenSeparatorSize * 0.5,\n hiddenSeparatorWidth,\n headerHiddenSeparatorSize * 0.5\n );\n }\n\n context.beginPath();\n context.moveTo(x + 0.5, y);\n context.lineTo(x + rowFooterWidth + 0.5, y);\n context.stroke();\n }\n }\n\n // Fill in the text\n context.beginPath();\n context.rect(x, gridY, rowFooterWidth, height);\n context.clip();\n\n context.fillStyle = headerColor;\n context.textAlign = 'left';\n\n const textX = x + cellHorizontalPadding;\n for (let i = 0; i < visibleRows.length; i += 1) {\n const row = visibleRows[i];\n const rowHeight = getOrThrow(allRowHeights, row);\n if (rowHeight > 0) {\n const rowY = getOrThrow(allRowYs, row) + gridY;\n const modelRow = getOrThrow(modelRows, row);\n const textY = rowY + rowHeight * 0.5;\n context.fillText(model.textForRowFooter(modelRow), textX, textY);\n }\n }\n\n context.restore();\n }\n\n drawSelectedRanges(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n viewport: {\n left?: VisibleIndex;\n top?: VisibleIndex;\n right?: VisibleIndex;\n bottom?: VisibleIndex;\n minX?: Coordinate;\n minY?: Coordinate;\n maxX?: Coordinate;\n maxY?: Coordinate;\n } = {}\n ): void {\n const {\n cursorColumn: column,\n cursorRow: row,\n draggingRow,\n draggingColumn,\n editingCell,\n metrics,\n model,\n selectedRanges,\n theme,\n } = state;\n const {\n allColumnWidths,\n allColumnXs,\n allRowHeights,\n allRowYs,\n width,\n height,\n } = metrics;\n const {\n left = metrics.left,\n top = metrics.top,\n right = metrics.right,\n bottom = metrics.bottom,\n minY = -10,\n maxY = height + 10,\n minX = -10,\n maxX = width + 10,\n } = viewport;\n if (selectedRanges.length === 0) {\n return;\n }\n\n const isCursorVisible =\n isEditableGridModel(model) &&\n model.isEditable &&\n editingCell == null &&\n draggingRow == null &&\n draggingColumn == null &&\n column != null &&\n row != null &&\n allColumnXs.has(column) &&\n allRowYs.has(row);\n if (isCursorVisible) {\n // Punch a hole out where the active cell is, it gets styled differently.\n const x = getOrThrow(allColumnXs, column);\n const y = getOrThrow(allRowYs, row);\n const w = getOrThrow(allColumnWidths, column);\n const h = getOrThrow(allRowHeights, row);\n\n context.save();\n\n context.beginPath();\n\n context.rect(0, 0, width, height);\n context.rect(x, y, w, h);\n\n context.clip('evenodd');\n }\n\n // Draw selection ranges\n context.beginPath();\n for (let i = 0; i < selectedRanges.length; i += 1) {\n const selectedRange = selectedRanges[i];\n const startColumn =\n selectedRange.startColumn !== null ? selectedRange.startColumn : left;\n const startRow =\n selectedRange.startRow !== null ? selectedRange.startRow : top;\n const endColumn =\n selectedRange.endColumn !== null ? selectedRange.endColumn : right;\n const endRow =\n selectedRange.endRow !== null ? selectedRange.endRow : bottom;\n if (\n endRow >= top &&\n bottom >= startRow &&\n endColumn >= left &&\n right >= startColumn\n ) {\n // Need to offset the x/y coordinates so that the line draws nice and crisp\n const x =\n startColumn >= left && allColumnXs.has(startColumn)\n ? Math.round(getOrThrow(allColumnXs, startColumn)) + 0.5\n : minX;\n const y =\n startRow >= top && allRowYs.has(startRow)\n ? Math.max(Math.round(getOrThrow(allRowYs, startRow)) + 0.5, 0.5)\n : minY;\n\n const endX =\n endColumn <= right && allColumnXs.has(endColumn)\n ? Math.round(\n getOrThrow(allColumnXs, endColumn) +\n getOrThrow(allColumnWidths, endColumn)\n ) - 0.5\n : maxX;\n const endY =\n endRow <= bottom && allRowYs.has(endRow)\n ? Math.round(\n getOrThrow(allRowYs, endRow) + getOrThrow(allRowHeights, endRow)\n ) - 0.5\n : maxY;\n\n context.rect(x, y, endX - x, endY - y);\n }\n\n // draw the inner transparent fill\n context.fillStyle = theme.selectionColor;\n context.fill();\n\n /**\n * draw an \"inner stroke\" that's clipped to just inside of the rects\n * to act as a casing to the outer stroke. 3px width because 1px is outside\n * the rect (but clipped), 1px is \"on\" the rect (technically this pixel is\n * a half pixel clip as well due to rects offset, but we are immediately painting\n * over it), and then the 1px inside (which is the desired pixel).\n */\n context.save();\n context.clip();\n context.strokeStyle = theme.selectionOutlineCasingColor;\n context.lineWidth = 3;\n context.stroke();\n context.restore();\n\n // draw the outerstroke border on top of the inner stroke\n context.strokeStyle = theme.selectionOutlineColor;\n context.lineWidth = 1;\n context.stroke();\n }\n\n if (isCursorVisible && column != null && row != null) {\n context.restore();\n\n this.drawActiveCell(context, state, column, row);\n }\n }\n\n drawActiveCell(\n context: CanvasRenderingContext2D,\n state: GridRenderState,\n column: VisibleIndex,\n row: VisibleIndex,\n borderWidth = GridRenderer.ACTIVE_CELL_BORDER_WIDTH\n ): void {\n const { metrics, theme } = state;\n const { allColumnWidths, allColumnXs, allRowHeights, allRowYs } = metrics;\n const cellX = getOrThrow(allColumnXs, column);\n const cellY = getOrThrow(allRowYs, row);\n const cellW = getOrThrow(allColumnWidths, column);\n const cellH = getOrThrow(allRowHeights, row);\n\n // Now get the outline for the active cell\n let x = cellX - borderWidth * 0.5;\n let y = cellY - borderWidth * 0.5;\n let w = cellW + borderWidth;\n let h = cellH + borderWidth;\n\n // Make sure the outline is interior on the edge\n if (x <= 0) {\n w += x - 1;\n x = 1;\n }\n if (y <= 0) {\n h += y - 1;\n y = 1;\n }\n\n const { lineWidth } = context;\n context.beginPath();\n context.lineWidth = borderWidth;\n context.strokeStyle = theme.selectionOutlineColor;\n this.drawRoundedRect(context, x, y, w, h);\n context.stroke();\n context.lineWidth = lineWidth;\n }\n\n /**\n * Draws a rounded rectangle using the current state of the canvas.\n *\n * @param context The canvas context\n * @param x coordinate of the left side\n * @param y coordinate of the top side\n * @param w width of the rectangle\n * @param h height of the rectangle\n * @param r corner radius of the rectangle\n */\n drawRoundedRect(\n context: CanvasRenderingContext2D,\n x: Coordinate,\n y: Coordinate,\n w: number,\n h: number,\n r = GridRenderer.DEFAULT_EDGE_RADIUS\n ): void {\n context.beginPath();\n context.moveTo(x + r, y);\n context.lineTo(x + w - r, y);\n context.quadraticCurveTo(x + w, y, x + w, y + r);\n context.lineTo(x + w, y + h - r);\n context.quadraticCurveTo(x + w, y + h, x + w - r, y + h);\n context.lineTo(x + r, y + h);\n context.quadraticCurveTo(x, y + h, x, y + h - r);\n context.lineTo(x, y + r);\n context.quadraticCurveTo(x, y, x + r, y);\n context.closePath();\n }\n\n drawDraggingColumn(\n context: CanvasRenderingContext2D,\n state: GridRenderState\n ): void {\n const { draggingColumn, metrics, mouseX, theme, model } = state;\n if (draggingColumn == null || mouseX == null) {\n return;\n }\n\n const {\n range: draggingColumnVisibleRange,\n depth: draggingColumnDepth,\n } = draggingColumn;\n\n const {\n gridX,\n gridY,\n allColumnXs,\n allColumnWidths,\n height,\n width,\n columnHeaderMaxDepth,\n columnHeaderHeight,\n movedColumns,\n modelColumns,\n floatingLeftWidth,\n } = metrics;\n\n const draggingModelIndex =\n modelColumns.get(draggingColumnVisibleRange[0]) ??\n GridUtils.getModelIndex(draggingColumnVisibleRange[0], movedColumns);\n\n const draggingGroup = model.getColumnHeaderGroup(\n draggingModelIndex,\n draggingColumnDepth\n );\n\n if (draggingColumnDepth > 0 && !draggingGroup) {\n return;\n }\n\n const [startIndex, endIndex] = draggingColumnVisibleRange;\n\n const originalLeft = getOrThrow(allColumnXs, startIndex);\n const originalRight =\n getOrThrow(allColumnXs, endIndex) + getOrThrow(allColumnWidths, endIndex);\n const originalWidth = originalRight - originalLeft;\n\n const draggingLeft = draggingColumn.left;\n\n const {\n backgroundColor,\n font,\n headerFont,\n reorderOffset,\n shadowBlur,\n shadowColor,\n } = theme;\n\n const columnHeaderOffset =\n (columnHeaderMaxDepth - draggingColumnDepth - 1) * columnHeaderHeight;\n\n context.save();\n\n context.translate(gridX, 0);\n\n context.save();\n context.beginPath();\n\n // Don't draw over frozen columns\n context.rect(floatingLeftWidth, 0, width, height);\n context.clip();\n\n // First, we need to draw over where the column is coming from\n context.fillStyle = backgroundColor;\n context.fillRect(originalLeft, columnHeaderOffset, originalWidth, height);\n context.restore();\n\n // Then draw the shadow of the moving column\n context.translate(0, reorderOffset);\n\n context.save();\n context.shadowColor = shadowColor;\n context.shadowBlur = shadowBlur;\n\n context.fillStyle = backgroundColor;\n context.fillRect(\n draggingColumn.left,\n columnHeaderOffset + reorderOffset,\n draggingColumn.width,\n height\n );\n context.restore(); // Reset style\n\n // Now set the clipping region and pretty much just redraw this column and all it's contents\n context.beginPath();\n context.rect(\n draggingColumn.left,\n columnHeaderOffset,\n draggingColumn.width + 1,\n height\n );\n context.clip();\n\n context.translate(draggingLeft - originalLeft, 0);\n context.font = headerFont;\n\n const visibleColumns: VisibleIndex[] = [];\n for (\n let i = draggingColumn.range[0];\n i <= draggingColumn.range[1];\n i += 1\n ) {\n visibleColumns.push(i);\n }\n\n /**\n * This will not draw the header text properly, but extensions of Grid\n * may draw extra things in the header like sorts and filters\n */\n this.drawColumnHeaders(context, state);\n\n // Ensure the column header gets drawn\n this.drawColumnHeadersForRange(\n context,\n state,\n [visibleColumns[0], visibleColumns[visibleColumns.length - 1]],\n {\n minX: originalLeft,\n maxX: width,\n }\n );\n\n context.translate(0, gridY);\n context.font = font;\n\n this.drawGridBackground(context, state);\n\n for (let i = startIndex; i <= endIndex; i += 1) {\n this.drawColumnCellContents(context, state, i);\n }\n\n context.restore();\n }\n\n drawDraggingRow(\n context: CanvasRenderingContext2D,\n state: GridRenderState\n ): void {\n const { draggingRow, draggingRowOffset, metrics, mouseY, theme } = state;\n if (draggingRow == null || mouseY == null) {\n return;\n }\n\n const { gridX, gridY, allRowYs, allRowHeights, width } = metrics;\n const y = getOrThrow(allRowYs, draggingRow);\n const rowHeight = getOrThrow(allRowHeights, draggingRow) + 1;\n const {\n backgroundColor,\n font,\n headerFont,\n reorderOffset,\n shadowBlur,\n shadowColor,\n } = theme;\n\n context.save();\n\n context.translate(0, gridY);\n\n // First, we need to draw over the row stripes where the row is coming from\n context.fillStyle = backgroundColor;\n context.fillRect(0, y, width, rowHeight);\n\n context.translate(\n gridX + reorderOffset,\n mouseY - y - gridY - (draggingRowOffset ?? 0)\n );\n\n // Then draw the shadow of the moving row\n context.save();\n\n context.shadowColor = shadowColor;\n context.shadowBlur = shadowBlur;\n\n context.fillStyle = backgroundColor;\n context.fillRect(-gridX, y, width, rowHeight);\n\n context.restore();\n\n // Now set the clipping region and pretty much just redraw this row and all it's contents\n context.beginPath();\n context.rect(-gridX, y, width, rowHeight);\n context.clip();\n\n context.font = font;\n\n this.drawGridBackground(context, state);\n\n this.drawCellContents(context, state);\n\n // Now translate it back up and draw the header\n context.translate(-gridX, -gridY);\n\n context.font = headerFont;\n\n this.drawRowHeaders(context, state);\n\n context.restore();\n }\n\n drawScrollBars(\n context: CanvasRenderingContext2D,\n state: GridRenderState\n ): void {\n const {\n isDraggingHorizontalScrollBar,\n isDraggingVerticalScrollBar,\n isDragging,\n metrics,\n mouseX,\n mouseY,\n theme,\n } = state;\n if (theme.scrollBarSize <= 0) {\n return;\n }\n\n const {\n width,\n height,\n handleHeight,\n handleWidth,\n scrollX,\n scrollY,\n hasHorizontalBar,\n hasVerticalBar,\n barWidth,\n barHeight,\n barLeft,\n barTop,\n } = metrics;\n const {\n scrollBarBackgroundColor,\n scrollBarHoverBackgroundColor,\n scrollBarCasingColor,\n scrollBarCornerColor,\n scrollBarColor,\n scrollBarHoverColor,\n scrollBarActiveColor,\n scrollBarSize,\n scrollBarHoverSize,\n scrollBarCasingWidth,\n scrollBarSelectionTick,\n scrollBarSelectionTickColor,\n scrollBarActiveSelectionTickColor,\n autoSelectRow,\n autoSelectColumn,\n } = theme;\n\n const isInbounds =\n mouseX != null && mouseY != null && mouseX <= width && mouseY <= height;\n\n const isVerticalBarHover =\n isDraggingVerticalScrollBar ||\n (hasVerticalBar &&\n !isDraggingHorizontalScrollBar &&\n !isDragging &&\n mouseX != null &&\n mouseY != null &&\n mouseX >= width - scrollBarHoverSize &&\n mouseY >= barTop &&\n isInbounds);\n\n const isHorizontalBarHover =\n isDraggingHorizontalScrollBar ||\n (hasHorizontalBar &&\n !isDraggingVerticalScrollBar &&\n !isDragging &&\n !isVerticalBarHover && // vert bar gets priorty in overlapped corner hover area\n mouseX != null &&\n mouseY != null &&\n mouseY >= height - scrollBarHoverSize &&\n mouseX >= barLeft &&\n isInbounds);\n\n const hScrollBarSize = isHorizontalBarHover\n ? scrollBarHoverSize\n : scrollBarSize;\n const vScrollBarSize = isVerticalBarHover\n ? scrollBarHoverSize\n : scrollBarSize;\n\n context.translate(barLeft, barTop);\n\n if (hasHorizontalBar && hasVerticalBar) {\n // That little corner in the bottom right\n context.fillStyle = scrollBarCasingColor;\n context.fillRect(\n width - barLeft - scrollBarSize,\n height - barTop - scrollBarSize,\n scrollBarSize,\n scrollBarSize\n );\n context.fillStyle = scrollBarCornerColor;\n context.fillRect(\n width - barLeft - scrollBarSize + scrollBarCasingWidth,\n height - barTop - scrollBarSize + scrollBarCasingWidth,\n scrollBarSize - scrollBarCasingWidth,\n scrollBarSize - scrollBarCasingWidth\n );\n }\n\n if (hasHorizontalBar) {\n const x = scrollX;\n const y = height - barTop - hScrollBarSize;\n\n // scrollbar casing\n context.fillStyle = scrollBarCasingColor;\n context.fillRect(0, y, barWidth, hScrollBarSize - scrollBarCasingWidth);\n\n // scrollbar track\n context.fillStyle = isHorizontalBarHover\n ? scrollBarHoverBackgroundColor\n : scrollBarBackgroundColor;\n context.fillRect(\n 0,\n y + scrollBarCasingWidth,\n barWidth,\n hScrollBarSize - scrollBarCasingWidth\n );\n\n // scrollbar thumb\n if (isDraggingHorizontalScrollBar) {\n context.fillStyle = scrollBarActiveColor;\n } else if (isHorizontalBarHover) {\n context.fillStyle = scrollBarHoverColor;\n } else {\n context.fillStyle = scrollBarColor;\n }\n\n context.fillRect(\n x,\n y + scrollBarCasingWidth,\n handleWidth,\n hScrollBarSize - scrollBarCasingWidth\n );\n\n if (\n !autoSelectRow &&\n scrollBarSelectionTick &&\n scrollBarSelectionTickColor != null &&\n scrollBarActiveSelectionTickColor != null\n ) {\n context.fillStyle = scrollBarSelectionTickColor;\n // Scrollbar Selection Tick\n const { selectedRanges, cursorColumn } = state;\n const { lastLeft, columnCount } = metrics;\n\n const filteredRanges = [...selectedRanges].filter(\n value => value.startColumn != null && value.endColumn != null\n ) as NoneNullColumnRange[];\n\n const sortedRanges = filteredRanges\n .map(\n (value): BoundedAxisRange => [value.startColumn, value.endColumn]\n )\n .sort(GridUtils.compareRanges);\n\n const mergedRanges = GridUtils.mergeSortedRanges(sortedRanges);\n\n const getTickX = (index: number): number => {\n if (index <= lastLeft) {\n return (index / lastLeft) * (barWidth - handleWidth);\n }\n return (\n barWidth -\n handleWidth +\n ((index - lastLeft) / (columnCount - lastLeft)) * handleWidth\n );\n };\n for (let i = 0; i < mergedRanges.length; i += 1) {\n const range = mergedRanges[i];\n const startColumn = range[0];\n const endColumn = range[1];\n\n if (\n startColumn != null &&\n endColumn != null &&\n (startColumn !== cursorColumn || endColumn !== cursorColumn)\n ) {\n const tickX = getTickX(startColumn);\n const tickWidth = Math.max(\n 1,\n Math.round(getTickX(endColumn + 1) - tickX)\n );\n const trackHeight = hScrollBarSize - scrollBarCasingWidth;\n context.fillRect(\n tickX,\n y + scrollBarCasingWidth + Math.round(trackHeight / 3),\n tickWidth,\n Math.round(trackHeight / 3)\n );\n }\n }\n\n // Current Active Tick\n if (cursorColumn != null) {\n const tickX = getTickX(cursorColumn);\n const tickWidth = 2;\n const trackHeight = hScrollBarSize - scrollBarCasingWidth;\n context.fillStyle = scrollBarActiveSelectionTickColor;\n context.fillRect(\n tickX,\n y + scrollBarCasingWidth,\n tickWidth,\n trackHeight\n );\n }\n }\n }\n\n if (hasVerticalBar) {\n const x = width - barLeft - vScrollBarSize;\n const y = scrollY;\n\n // scrollbar casing\n context.fillStyle = scrollBarCasingColor;\n context.fillRect(x, 0, vScrollBarSize - scrollBarCasingWidth, barHeight);\n\n // scrollbar track\n context.fillStyle = isVerticalBarHover\n ? scrollBarHoverBackgroundColor\n : scrollBarBackgroundColor;\n context.fillRect(\n x + scrollBarCasingWidth,\n 0,\n vScrollBarSize - scrollBarCasingWidth,\n barHeight\n );\n\n // scrollbar thumb\n if (isDraggingVerticalScrollBar) {\n context.fillStyle = scrollBarActiveColor;\n } else if (isVerticalBarHover) {\n context.fillStyle = scrollBarHoverColor;\n } else {\n context.fillStyle = scrollBarColor;\n }\n\n context.fillRect(\n x + scrollBarCasingWidth,\n y,\n vScrollBarSize - scrollBarCasingWidth,\n handleHeight\n );\n\n if (\n !autoSelectColumn &&\n scrollBarSelectionTick &&\n scrollBarSelectionTickColor != null &&\n scrollBarActiveSelectionTickColor != null\n ) {\n // Scrollbar Selection Tick\n const { selectedRanges, cursorRow } = state;\n const { lastTop, rowCount } = metrics;\n\n const getTickY = (index: number): number => {\n if (index <= lastTop) {\n return (index / lastTop) * (barHeight - handleHeight);\n }\n return (\n barHeight -\n handleHeight +\n ((index - lastTop) / (rowCount - lastTop)) * handleHeight\n );\n };\n\n context.fillStyle = scrollBarSelectionTickColor;\n\n const filteredRanges = [...selectedRanges].filter(\n value => value.startRow != null && value.endRow != null\n ) as NoneNullRowRange[];\n\n const sortedRanges = filteredRanges\n .map((value): BoundedAxisRange => [value.startRow, value.endRow])\n .sort(GridUtils.compareRanges);\n\n const mergedRanges = GridUtils.mergeSortedRanges(sortedRanges);\n\n for (let i = 0; i < mergedRanges.length; i += 1) {\n const range = mergedRanges[i];\n const startRow = range[0];\n const endRow = range[1];\n if (\n startRow != null &&\n endRow != null &&\n (startRow !== cursorRow || endRow !== cursorRow)\n ) {\n const tickY = getTickY(startRow);\n const trackWidth = vScrollBarSize - scrollBarCasingWidth;\n const tickHeight = Math.max(\n 1,\n Math.round(getTickY(endRow + 1) - tickY)\n );\n context.fillRect(\n x + scrollBarCasingWidth + Math.round(trackWidth / 3),\n tickY,\n Math.round(trackWidth / 3),\n tickHeight\n );\n }\n }\n\n // Current Active Tick\n if (cursorRow != null) {\n const tickY = Math.round(getTickY(cursorRow));\n\n const trackWidth = vScrollBarSize - scrollBarCasingWidth;\n const tickHeight = 2;\n\n context.fillStyle = scrollBarActiveSelectionTickColor;\n context.fillRect(\n x + scrollBarCasingWidth,\n tickY,\n trackWidth,\n tickHeight\n );\n }\n }\n }\n\n context.translate(-barLeft, -barTop);\n }\n\n /**\n * Gets the token boxes that are visible in the cell\n * @param column The visible column\n * @param row The visible row\n * @param state The GridRenderState\n * @returns An array of TokenBox of visible tokens or empty array with coordinates relative to gridX and gridY\n */\n getTokenBoxesForVisibleCell(\n column: VisibleIndex,\n row: VisibleIndex,\n state: GridRenderState\n ): TokenBox[] {\n const { metrics, context, model, theme } = state;\n\n if (context == null || metrics == null) {\n return (EMPTY_ARRAY as unknown) as TokenBox[];\n }\n\n const { modelRows, modelColumns } = metrics;\n const modelRow = getOrThrow(modelRows, row);\n const modelColumn = getOrThrow(modelColumns, column);\n\n const text = model.textForCell(modelColumn, modelRow);\n const { width: textWidth, x: textX, y: textY } = this.getTextRenderMetrics(\n state,\n column,\n row\n );\n\n const { fontWidths } = metrics;\n\n // Set the font and baseline and change it back after\n context.save();\n this.configureContext(context, state);\n\n const fontWidth =\n fontWidths?.get(context.font) ?? GridRenderer.DEFAULT_FONT_WIDTH;\n const truncationChar = model.truncationCharForCell(modelColumn, modelRow);\n const truncatedText = this.getCachedTruncatedString(\n context,\n text,\n textWidth,\n fontWidth,\n truncationChar\n );\n\n const {\n actualBoundingBoxAscent,\n actualBoundingBoxDescent,\n } = context.measureText(truncatedText);\n const textHeight = actualBoundingBoxAscent + actualBoundingBoxDescent;\n\n const tokens = model.tokensForCell(\n modelColumn,\n modelRow,\n truncatedText.length\n );\n\n // Check if the truncated text contains a link\n if (tokens.length === 0) {\n context.restore();\n return (EMPTY_ARRAY as unknown) as TokenBox[];\n }\n\n const cachedTokenBoxes = this.getCachedTokenBoxesForVisibleCell(\n truncatedText,\n tokens,\n theme.font,\n 'middle',\n textHeight,\n context\n ).map(tokenBox => ({\n x1: tokenBox.x1 + textX,\n y1: tokenBox.y1 + (textY - actualBoundingBoxAscent),\n x2: tokenBox.x2 + textX,\n y2: tokenBox.y2 + (textY - actualBoundingBoxAscent),\n token: tokenBox.token,\n }));\n\n context.restore();\n\n return cachedTokenBoxes;\n }\n\n /**\n * Returns an array of token boxes with the coordinates relative to the top left corner of the text\n */\n getCachedTokenBoxesForVisibleCell = memoizeClear(\n (\n truncatedText: string,\n tokens: Token[],\n // _font and _baseline are passed in so value is re-calculated when they change\n // They should already be set on the `context`, so they are not used in this method\n _font: string,\n _baseline: CanvasTextBaseline,\n textHeight: number,\n context: CanvasRenderingContext2D\n ): TokenBox[] => {\n const top = 0;\n const bottom = textHeight;\n\n const tokenBoxes: TokenBox[] = [];\n\n // The index where the last token ended\n let lastTokenEnd = 0;\n // The width of the text preceding the current token\n let currentTextWidth = 0;\n // Loop through array and push them to array\n for (let i = 0; i < tokens.length; i += 1) {\n const token = tokens[i];\n const { start, end } = token;\n // The last token value is calculated based on the full text so the value needs to be truncated\n const value =\n end > truncatedText.length\n ? truncatedText.substring(start)\n : token.value;\n\n // Add the width of the text in between this token and the last token\n currentTextWidth += context.measureText(\n truncatedText.substring(lastTokenEnd, start)\n ).width;\n const tokenWidth = context.measureText(value).width;\n\n // Check if the x position is less than the grid x, then tokenWidth should be shifted by gridX - startX\n\n const left = currentTextWidth;\n const right = left + tokenWidth;\n\n const newTokenBox: TokenBox = {\n x1: left,\n y1: top,\n x2: right,\n y2: bottom,\n token,\n };\n\n tokenBoxes.push(newTokenBox);\n\n lastTokenEnd = end;\n currentTextWidth += tokenWidth;\n }\n\n return tokenBoxes;\n },\n { max: 10000 }\n );\n}\n\nexport default GridRenderer;\n","import { EventHandlerResult } from '../EventHandlerResult';\nimport Grid from '../Grid';\nimport { BoxCoordinates } from '../GridMetrics';\nimport GridMouseHandler, { GridMouseEvent } from '../GridMouseHandler';\nimport GridUtils, { GridPoint } from '../GridUtils';\n\nconst DEFAULT_INTERVAL_MS = 100;\n\nclass GridSelectionMouseHandler extends GridMouseHandler {\n private startPoint?: GridPoint;\n\n private hasExtendedFloating = false;\n\n // Timer used when holding a drag past the end of the grid\n private timer?: ReturnType<typeof setTimeout>;\n\n private lastTriggerTime?: number;\n\n private dragBounds?: BoxCoordinates;\n\n onDown(\n gridPoint: GridPoint,\n grid: Grid,\n event: GridMouseEvent\n ): EventHandlerResult {\n const { x, y, column, row } = gridPoint;\n const { metrics } = grid;\n if (!metrics) throw new Error('metrics not set');\n\n const { gridX, gridY, maxX, maxY } = metrics;\n const gridMouseX = x - gridX;\n const gridMouseY = y - gridY;\n if (\n gridMouseX < 0 ||\n gridMouseY < 0 ||\n (column == null && gridMouseX > maxX) ||\n (row == null && gridMouseY > maxY)\n ) {\n return false;\n }\n\n const isModifierKey = GridUtils.isModifierKeyDown(event);\n const isShiftKey = event.shiftKey;\n if (!isModifierKey) {\n if (isShiftKey) {\n grid.trimSelectedRanges();\n } else {\n grid.clearSelectedRanges();\n }\n }\n\n const theme = grid.getTheme();\n const { autoSelectRow, autoSelectColumn } = theme;\n // If they click a column/row header, don't want to select the whole table if auto select column/row is on\n if (\n (column !== null || !autoSelectColumn) &&\n (row !== null || !autoSelectRow)\n ) {\n grid.focus();\n grid.moveCursorToPosition(\n column,\n row,\n isShiftKey,\n false,\n isShiftKey && isModifierKey\n );\n }\n\n this.startPoint = gridPoint;\n this.hasExtendedFloating = false;\n this.dragBounds = GridUtils.getScrollDragBounds(metrics, row, column);\n\n return true;\n }\n\n onDrag(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n if (this.startPoint === undefined) {\n return false;\n }\n\n this.stopTimer();\n\n const { row: startRow, column: startColumn } = this.startPoint;\n const { x, y } = gridPoint;\n let { row, column } = gridPoint;\n const { metrics } = grid;\n if (!metrics) throw new Error('metrics not set');\n\n const { left, lastLeft, top, lastTop, columnWidth, rowHeight } = metrics;\n const dragBounds = GridUtils.getScrollDragBounds(\n metrics,\n startRow,\n startColumn\n );\n\n // If we're dragging outside of the grid entirely, then we should start scrolling\n let deltaX = 0;\n let deltaY = 0;\n if (left < lastLeft) {\n if (x < dragBounds.x1) {\n deltaX = x - dragBounds.x1;\n } else if (x > dragBounds.x2) {\n deltaX = x - dragBounds.x2;\n }\n }\n if (top < lastTop) {\n if (y < dragBounds.y1) {\n deltaY = y - dragBounds.y1;\n } else if (y > dragBounds.y2) {\n deltaY = y - dragBounds.y2;\n }\n }\n\n if (deltaX !== 0 || deltaY !== 0) {\n // Have it go faster depending on how far out they've dragged\n this.startTimer(\n grid,\n gridPoint,\n deltaX > 0\n ? Math.ceil(deltaX / columnWidth)\n : Math.floor(deltaX / columnWidth),\n deltaY > 0\n ? Math.ceil(deltaY / rowHeight)\n : Math.floor(deltaY / rowHeight)\n );\n } else if (row != null && column != null) {\n const {\n floatingTopRowCount,\n floatingBottomRowCount,\n floatingLeftColumnCount,\n floatingRightColumnCount,\n columnCount,\n rowCount,\n bottom,\n right,\n topVisible,\n bottomVisible,\n leftVisible,\n rightVisible,\n } = metrics;\n // When selection crosses from a floating area to a non floating area, we need to scroll instead of jumping to the floating area\n // So when that happens, just adjust the point to be past the new boundary\n if (!this.hasExtendedFloating) {\n if (\n startRow !== null &&\n startRow < floatingTopRowCount &&\n row >= floatingTopRowCount\n ) {\n // Extending from floating top into the view\n row = floatingTopRowCount;\n this.hasExtendedFloating = true;\n } else if (\n startRow !== null &&\n startRow >= rowCount - floatingBottomRowCount &&\n row < rowCount - floatingBottomRowCount\n ) {\n // Extending from floating bottom into the view\n row = rowCount - floatingBottomRowCount - 1;\n this.hasExtendedFloating = true;\n }\n\n if (\n startColumn !== null &&\n startColumn < floatingLeftColumnCount &&\n column >= floatingLeftColumnCount\n ) {\n // Extending from floating left into the view\n column = floatingLeftColumnCount;\n this.hasExtendedFloating = true;\n } else if (\n startColumn !== null &&\n startColumn >= columnCount - floatingRightColumnCount &&\n column < columnCount - floatingRightColumnCount\n ) {\n // Extending from floating right into the view\n column = columnCount - floatingRightColumnCount - 1;\n this.hasExtendedFloating = true;\n }\n }\n\n // When a selection is dragging from within the main area to over a floating area, scroll.\n if (\n startRow !== null &&\n !GridUtils.isFloatingRow(startRow, metrics) &&\n GridUtils.isFloatingRow(row, metrics)\n ) {\n // Need to scroll\n if (startRow > row && row < top) {\n row = topVisible - 1;\n } else if (startRow < row && row > bottom) {\n row = bottomVisible + 1;\n }\n }\n if (\n startColumn !== null &&\n !GridUtils.isFloatingColumn(startColumn, metrics) &&\n GridUtils.isFloatingColumn(column, metrics)\n ) {\n if (startColumn > column && column < left) {\n column = leftVisible - 1;\n } else if (startColumn < column && column > right) {\n column = rightVisible + 1;\n }\n }\n grid.moveCursorToPosition(column, row, true, true);\n }\n return true;\n }\n\n onUp(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n if (this.startPoint !== undefined) {\n this.startPoint = undefined;\n this.dragBounds = undefined;\n this.stopTimer();\n grid.commitSelection();\n }\n\n return false;\n }\n\n moveSelection(\n grid: Grid,\n gridPoint: GridPoint,\n deltaX: number,\n deltaY: number\n ): void {\n const { row, column } = gridPoint;\n const { metrics } = grid;\n if (!metrics) throw new Error('metrics not set');\n\n const { selectionEndRow, selectionEndColumn } = grid.state;\n if (selectionEndRow == null || selectionEndColumn == null) {\n throw new Error('selection not set');\n }\n\n const { rowCount, columnCount } = metrics;\n const minX = deltaX < 0 && column != null ? column : 0;\n const maxX = deltaX > 0 && column != null ? column : columnCount - 1;\n const minY = deltaY < 0 && row != null ? row : 0;\n const maxY = deltaY > 0 && row != null ? row : rowCount - 1;\n grid.moveCursorToPosition(\n Math.min(Math.max(minX, selectionEndColumn + deltaX), maxX),\n Math.min(Math.max(minY, selectionEndRow + deltaY), maxY),\n true\n );\n this.lastTriggerTime = Date.now();\n }\n\n startTimer(\n grid: Grid,\n gridPoint: GridPoint,\n deltaX: number,\n deltaY: number\n ): void {\n this.stopTimer();\n\n const timeout =\n this.lastTriggerTime != null\n ? DEFAULT_INTERVAL_MS -\n Math.min(DEFAULT_INTERVAL_MS, Date.now() - this.lastTriggerTime)\n : 0;\n this.timer = setTimeout(() => {\n this.moveSelection(grid, gridPoint, deltaX, deltaY);\n this.startTimer(grid, gridPoint, deltaX, deltaY);\n }, timeout);\n }\n\n stopTimer(): void {\n if (this.timer !== undefined) {\n clearTimeout(this.timer);\n this.timer = undefined;\n }\n }\n}\n\nexport default GridSelectionMouseHandler;\n","import clamp from 'lodash.clamp';\nimport Grid from '../Grid';\nimport GridUtils, { GridPoint } from '../GridUtils';\nimport GridMouseHandler, { GridMouseEvent } from '../GridMouseHandler';\nimport { EventHandlerResult } from '../EventHandlerResult';\nimport type {\n VisibleIndex,\n ModelIndex,\n GridMetrics,\n MoveOperation,\n Coordinate,\n} from '../GridMetrics';\nimport type { BoundedAxisRange } from '../GridAxisRange';\nimport type GridModel from '../GridModel';\nimport type { IColumnHeaderGroup } from '../ColumnHeaderGroup';\n\nconst SLOPPY_CLICK_DISTANCE = 5;\nconst SCROLL_INTERVAL = 1000 / 60;\nconst SCROLL_DELTA = 10;\n\nexport interface DraggingColumn {\n range: BoundedAxisRange;\n depth: number;\n left: Coordinate;\n width: number;\n}\n\ninterface ColumnInfo {\n visibleIndex: VisibleIndex;\n modelIndex: ModelIndex;\n left: number;\n right: number;\n width: number;\n isColumnGroup: boolean;\n range: BoundedAxisRange;\n depth: number;\n}\n\n/**\n * Gets info about a visible column\n * @param visibleIndex The visible index to get info for\n * @param depth The header depth to get info for\n * @param metrics Grid metrics\n * @param model Grid model\n * @returns The column info at the depth.\n * If the column is not in a group at that depth, returns the info for the base column.\n * Returns null if the column is not visible.\n */\nfunction getColumnInfo(\n visibleIndex: VisibleIndex | null,\n depth: number | undefined,\n metrics: GridMetrics,\n model: GridModel\n): ColumnInfo | null {\n const {\n modelColumns,\n movedColumns,\n allColumnXs,\n columnCount,\n allColumnWidths,\n userColumnWidths,\n calculatedColumnWidths,\n floatingLeftWidth,\n maxX,\n } = metrics;\n\n if (\n depth == null ||\n visibleIndex == null ||\n visibleIndex > columnCount ||\n visibleIndex < 0\n ) {\n return null;\n }\n\n const modelIndex =\n modelColumns.get(visibleIndex) ??\n GridUtils.getModelIndex(visibleIndex, movedColumns);\n\n const group = model.getColumnHeaderGroup(modelIndex, depth);\n const isColumnGroup = group != null;\n\n let left: number;\n let right: number;\n let range: BoundedAxisRange;\n\n if (group != null) {\n const [startVisibleIndex, endVisibleIndex] = group.getVisibleRange(\n movedColumns\n );\n\n left = allColumnXs.get(startVisibleIndex) ?? floatingLeftWidth;\n right =\n (allColumnXs.get(endVisibleIndex) ?? maxX) +\n (allColumnWidths.get(endVisibleIndex) ?? 0);\n range = [startVisibleIndex, endVisibleIndex];\n } else {\n const possibleLeft = allColumnXs.get(visibleIndex);\n if (possibleLeft == null) {\n return null;\n }\n\n left = possibleLeft;\n right =\n left +\n (allColumnWidths.get(visibleIndex) ??\n userColumnWidths.get(modelIndex) ??\n calculatedColumnWidths.get(modelIndex) ??\n 0);\n range = [visibleIndex, visibleIndex];\n }\n\n return {\n visibleIndex,\n modelIndex,\n left,\n right,\n width: right - left,\n isColumnGroup,\n range,\n depth,\n };\n}\n\nclass GridColumnMoveMouseHandler extends GridMouseHandler {\n cursor: string | null = null;\n\n private draggingOffset?: number;\n\n private initialOffset?: number;\n\n private initialGridPoint?: GridPoint;\n\n private scrollingInterval?: number;\n\n private scrollingDirection?: 'left' | 'right';\n\n private draggingColumn: DraggingColumn | null = null;\n\n private setScrollInterval(grid: Grid, direction: 'left' | 'right'): void {\n if (\n this.scrollingInterval != null &&\n direction === this.scrollingDirection\n ) {\n return;\n }\n\n this.scrollingDirection = direction;\n this.scrollingInterval = window.setInterval(() => {\n const { metrics } = grid;\n if (!metrics) {\n return;\n }\n\n const {\n left,\n lastLeft,\n leftOffset,\n userColumnWidths,\n calculatedColumnWidths,\n movedColumns,\n allColumnWidths,\n } = metrics;\n\n let nextLeft = left;\n let nextOffset = leftOffset;\n if (direction === 'left') {\n nextOffset -= SCROLL_DELTA;\n while (nextOffset < 0) {\n nextLeft -= 1;\n const modelIndex = GridUtils.getModelIndex(left - 1, movedColumns);\n const prevColumnWidth =\n userColumnWidths.get(modelIndex) ??\n calculatedColumnWidths.get(modelIndex);\n if (prevColumnWidth === undefined) {\n nextOffset = 0;\n } else {\n nextOffset += prevColumnWidth;\n }\n if (nextLeft < 0) {\n nextOffset = 0;\n nextLeft = 0;\n }\n }\n } else {\n nextOffset += SCROLL_DELTA;\n let leftColumnWidth = allColumnWidths.get(left);\n while (leftColumnWidth !== undefined && nextOffset > leftColumnWidth) {\n nextLeft += 1;\n nextOffset -= leftColumnWidth;\n const modelIndex = GridUtils.getModelIndex(left + 1, movedColumns);\n leftColumnWidth =\n userColumnWidths.get(modelIndex) ??\n calculatedColumnWidths.get(modelIndex);\n\n if (nextLeft > lastLeft) {\n nextOffset = 0;\n nextLeft = lastLeft;\n }\n }\n }\n\n const { mouseX, mouseY } = grid.state;\n\n if (metrics == null || mouseX == null || mouseY == null) {\n return;\n }\n\n this.moveDraggingColumn(\n mouseX,\n grid,\n direction === 'left' ? -SCROLL_DELTA : SCROLL_DELTA\n );\n grid.setState({ left: nextLeft, leftOffset: nextOffset });\n\n if (\n (direction === 'left' && nextLeft === 0 && leftOffset === 0) ||\n (direction === 'right' && nextLeft === lastLeft)\n ) {\n this.clearScrollInterval();\n }\n }, SCROLL_INTERVAL);\n }\n\n private clearScrollInterval(): void {\n this.scrollingDirection = undefined;\n window.clearInterval(this.scrollingInterval);\n this.scrollingInterval = undefined;\n }\n\n onLeave(): EventHandlerResult {\n this.clearScrollInterval();\n return false;\n }\n\n onDown(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n const { model } = grid.props;\n const { x, column, columnHeaderDepth } = gridPoint;\n const { metrics } = grid;\n if (!metrics) throw new Error('Metrics not set');\n\n const columnInfo = getColumnInfo(column, columnHeaderDepth, metrics, model);\n\n if (column == null || columnInfo == null || columnHeaderDepth == null) {\n return false;\n }\n\n // Can't drag a base column from the empty group area\n if (columnHeaderDepth > 0 && !columnInfo.isColumnGroup) {\n return false;\n }\n\n const { rowHeaderWidth } = metrics;\n\n this.initialGridPoint = gridPoint;\n this.draggingColumn = null;\n this.cursor = null;\n\n if (\n columnInfo.modelIndex != null &&\n columnHeaderDepth != null &&\n model.isColumnMovable(columnInfo.modelIndex, columnHeaderDepth)\n ) {\n this.draggingOffset = x - columnInfo.left - rowHeaderWidth;\n this.initialOffset = this.draggingOffset;\n }\n return false;\n }\n\n onDrag(\n gridPoint: GridPoint,\n grid: Grid,\n event: GridMouseEvent\n ): EventHandlerResult {\n if (\n this.draggingOffset === undefined ||\n this.initialGridPoint === undefined ||\n this.initialOffset === undefined\n ) {\n return false;\n }\n\n const { x: mouseX, y: mouseY } = gridPoint;\n const { columnHeaderDepth } = this.initialGridPoint;\n\n const { model } = grid.props;\n let { draggingColumn } = this;\n const { metrics } = grid;\n\n if (!metrics) throw new Error('Metrics not set');\n\n // before considering it a drag, the mouse must have moved a minimum distance\n // this prevents click actions from triggering a drag state\n if (\n !draggingColumn &&\n Math.abs(this.initialGridPoint.x - mouseX) < SLOPPY_CLICK_DISTANCE &&\n Math.abs(this.initialGridPoint.y - mouseY) < SLOPPY_CLICK_DISTANCE\n ) {\n return false;\n }\n\n // Get the initial dragging column info\n if (draggingColumn == null) {\n const initialColumnInfo = getColumnInfo(\n this.initialGridPoint.column,\n columnHeaderDepth,\n metrics,\n model\n );\n\n if (!initialColumnInfo || columnHeaderDepth == null) {\n return false;\n }\n\n if (!model.isColumnMovable(initialColumnInfo.modelIndex)) {\n return false;\n }\n\n // Disallow dragging from the blank space in column header groups\n if (columnHeaderDepth > 0 && !initialColumnInfo.isColumnGroup) {\n return false;\n }\n\n if (initialColumnInfo.range[0] == null) {\n return false;\n }\n\n draggingColumn = {\n range: initialColumnInfo.range,\n depth: columnHeaderDepth,\n left: initialColumnInfo.left,\n width: initialColumnInfo.width,\n };\n\n const startColumn = getColumnInfo(\n draggingColumn.range[0],\n 0,\n metrics,\n model\n );\n const endColumn = getColumnInfo(\n draggingColumn.range[1],\n 0,\n metrics,\n model\n );\n\n // Group goes off the table. Drag and drop could be wonky here\n // Column draws only use columns that are partially visible too\n // So this could cause rendering errors if we tried dragging it\n if (!startColumn || !endColumn) {\n return false;\n }\n\n this.draggingColumn = draggingColumn;\n grid.setState({ draggingColumn, isDragging: true });\n }\n\n /**\n * At this point, we have determined we are actually dragging a column\n */\n this.cursor = 'move';\n\n this.moveDraggingColumn(gridPoint.x, grid, event.movementX);\n\n return true;\n }\n\n /**\n * Moves a dragging column, if possible, the specified distance\n * @param mouseX The point the move was initiated from\n * @param grid The Grid component\n * @param deltaX The distance of the move\n */\n moveDraggingColumn(mouseX: number, grid: Grid, deltaX: number): void {\n if (\n this.draggingOffset === undefined ||\n this.initialGridPoint === undefined ||\n this.initialOffset === undefined ||\n this.draggingColumn == null ||\n deltaX === 0\n ) {\n return;\n }\n\n // Cursor has moved past the column drag bounds, don't move the column until we hit the initial offset point again\n if (this.initialOffset !== this.draggingOffset) {\n // Pre move < Initial < Post move or vice-versa\n // User crossed back past the iniital offset point, so we can start moving again\n if (\n (this.draggingOffset < this.initialOffset &&\n this.initialOffset < this.draggingOffset + deltaX) ||\n (this.draggingOffset > this.initialOffset &&\n this.initialOffset > this.draggingOffset + deltaX)\n ) {\n this.draggingOffset = this.initialOffset;\n } else {\n // Column can't move since we aren't back at the initial offset yet\n this.draggingOffset += deltaX;\n }\n\n this.draggingColumn = {\n ...this.draggingColumn,\n left: mouseX - this.draggingOffset,\n };\n grid.setState({ draggingColumn: this.draggingColumn });\n return;\n }\n\n const { depth: draggingColumnDepth } = this.draggingColumn;\n\n const { model } = grid.props;\n const { movedColumns } = grid.state;\n const { metrics } = grid;\n if (!metrics) throw new Error('Metrics not set');\n\n const {\n floatingLeftWidth,\n width,\n columnHeaderMaxDepth,\n allColumnXs,\n } = metrics;\n\n const isDraggingLeft = deltaX < 0;\n\n const draggingColumn = getColumnInfo(\n this.draggingColumn.range[0],\n draggingColumnDepth,\n metrics,\n model\n );\n\n if (!draggingColumn) {\n return;\n }\n\n // The returned left/right are the original position, not dragged position\n // This is where the dragging column's floating position accounting for dragged distance\n const floatingDraggingLeft = mouseX - this.draggingOffset;\n const floatingDraggingRight = floatingDraggingLeft + draggingColumn.width;\n\n this.draggingColumn = {\n ...this.draggingColumn,\n left: floatingDraggingLeft,\n };\n grid.setState({\n draggingColumn: this.draggingColumn,\n });\n\n const swapColumn = getColumnInfo(\n GridUtils.getColumnAtX(\n clamp(\n isDraggingLeft ? floatingDraggingLeft : floatingDraggingRight,\n floatingLeftWidth,\n width\n ),\n metrics,\n true\n ),\n draggingColumnDepth,\n metrics,\n model\n );\n\n const parentGroup = model.getColumnHeaderParentGroup(\n draggingColumn.modelIndex,\n draggingColumn.depth\n );\n\n if (!swapColumn) {\n return;\n }\n\n // Check if we should pin to the edge of the parent\n if (parentGroup !== undefined) {\n const parentVisibleRange = parentGroup.getVisibleRange(movedColumns);\n // Cannot move to this left position, pin to left of parent\n if (swapColumn.visibleIndex < parentVisibleRange[0]) {\n const newMovedColumns = this.moveColumn(\n draggingColumn,\n parentVisibleRange[0],\n movedColumns\n );\n\n this.draggingOffset =\n mouseX - (allColumnXs.get(parentVisibleRange[0]) ?? 0);\n this.draggingColumn = {\n ...this.draggingColumn,\n left: mouseX - this.draggingOffset,\n };\n this.clearScrollInterval();\n grid.setState({\n draggingColumn: this.draggingColumn,\n movedColumns: newMovedColumns,\n });\n return;\n }\n\n // Pin to the right of parent\n if (swapColumn.visibleIndex > parentVisibleRange[1]) {\n const newMovedColumns = this.moveColumn(\n draggingColumn,\n parentVisibleRange[1] -\n (draggingColumn.range[1] - draggingColumn.range[0]),\n movedColumns\n );\n\n const { right: parentRight = 0 } =\n getColumnInfo(parentVisibleRange[1], 0, metrics, model) ?? {};\n\n this.draggingOffset = mouseX - (parentRight - draggingColumn.width);\n this.draggingColumn = {\n ...this.draggingColumn,\n left: mouseX - this.draggingOffset,\n };\n this.clearScrollInterval();\n grid.setState({\n draggingColumn: this.draggingColumn,\n movedColumns: newMovedColumns,\n });\n return;\n }\n }\n\n // Hit an unmovable column, move to the first available position next to it\n if (!model.isColumnMovable(swapColumn.modelIndex)) {\n let toVisibleIndex = swapColumn.visibleIndex;\n if (isDraggingLeft) {\n toVisibleIndex += 1;\n while (\n toVisibleIndex < draggingColumn.visibleIndex &&\n !model.isColumnMovable(\n GridUtils.getModelIndex(toVisibleIndex, movedColumns)\n )\n ) {\n toVisibleIndex += 1;\n }\n } else {\n toVisibleIndex -= 1;\n while (\n toVisibleIndex > draggingColumn.visibleIndex &&\n !model.isColumnMovable(\n GridUtils.getModelIndex(toVisibleIndex, movedColumns)\n )\n ) {\n toVisibleIndex -= 1;\n }\n }\n\n if (toVisibleIndex !== draggingColumn.visibleIndex) {\n if (!isDraggingLeft) {\n // Offset for range if dragging right\n toVisibleIndex -= draggingColumn.range[1] - draggingColumn.range[0];\n }\n\n const newMovedColumns = this.moveColumn(\n draggingColumn,\n toVisibleIndex,\n movedColumns\n );\n\n grid.setState({\n movedColumns: newMovedColumns,\n draggingColumn: this.draggingColumn,\n });\n }\n\n const toColumnInfo = getColumnInfo(toVisibleIndex, 0, metrics, model);\n if (isDraggingLeft) {\n this.draggingOffset = mouseX - (toColumnInfo?.left ?? 0);\n } else {\n this.draggingOffset =\n mouseX - ((toColumnInfo?.right ?? 0) - draggingColumn.width);\n }\n\n this.draggingColumn = {\n ...this.draggingColumn,\n left: mouseX - this.draggingOffset,\n };\n\n grid.setState({\n draggingColumn: this.draggingColumn,\n });\n\n return;\n }\n\n if (floatingDraggingLeft <= floatingLeftWidth) {\n this.setScrollInterval(grid, 'left');\n } else if (floatingDraggingRight > width) {\n this.setScrollInterval(grid, 'right');\n } else {\n this.clearScrollInterval();\n }\n\n // Can't swap a column with itself\n if (swapColumn.visibleIndex === draggingColumn.visibleIndex) {\n return;\n }\n\n // Can't swap a column to the left when dragging right or vice versa\n if (\n (isDraggingLeft &&\n draggingColumn.visibleIndex < swapColumn.visibleIndex) ||\n (!isDraggingLeft && draggingColumn.visibleIndex > swapColumn.visibleIndex)\n ) {\n return;\n }\n\n const switchPoint = swapColumn.left + swapColumn.width * 0.5;\n const draggingParentGroup = model.getColumnHeaderParentGroup(\n draggingColumn.modelIndex,\n draggingColumn.depth\n );\n\n // Get the highest level group that is not the common base group\n // This group is what we need to drag past\n let maxDepthSwapGroup: IColumnHeaderGroup | undefined;\n let maxSwapDepth = (draggingParentGroup?.depth ?? columnHeaderMaxDepth) - 1;\n while (maxSwapDepth >= 0 && maxDepthSwapGroup === undefined) {\n maxDepthSwapGroup = model.getColumnHeaderGroup(\n swapColumn.modelIndex,\n maxSwapDepth\n );\n maxSwapDepth -= 1;\n }\n\n let newMovedColumns: readonly MoveOperation[] | undefined;\n\n if (\n isDraggingLeft &&\n floatingDraggingLeft < switchPoint &&\n (!maxDepthSwapGroup ||\n swapColumn.visibleIndex ===\n maxDepthSwapGroup.getVisibleRange(movedColumns)[0])\n ) {\n newMovedColumns = this.moveColumn(\n draggingColumn,\n swapColumn.range[0],\n movedColumns\n );\n }\n\n if (\n !isDraggingLeft &&\n floatingDraggingRight > switchPoint &&\n (!maxDepthSwapGroup ||\n swapColumn.visibleIndex ===\n maxDepthSwapGroup.getVisibleRange(movedColumns)[1])\n ) {\n newMovedColumns = this.moveColumn(\n draggingColumn,\n swapColumn.range[1] -\n (draggingColumn.range[1] - draggingColumn.range[0]),\n movedColumns\n );\n }\n\n if (!newMovedColumns) {\n return;\n }\n\n this.draggingColumn = {\n ...this.draggingColumn,\n left: floatingDraggingLeft,\n };\n\n grid.setState({\n movedColumns: newMovedColumns,\n draggingColumn: this.draggingColumn,\n });\n }\n\n /**\n * Applies the column move and updates draggingColumn in the mouse handler\n * Does not check if the move is valid\n * @param draggingColumn The dragging column info\n * @param to The index to move the column or range to\n * @param movedColumns The array of column moves\n * @returns A new array of column moves\n */\n moveColumn(\n draggingColumn: ColumnInfo,\n to: number,\n movedColumns: readonly MoveOperation[]\n ): MoveOperation[] {\n const newMovedColumns = draggingColumn.isColumnGroup\n ? GridUtils.moveRange(draggingColumn.range, to, movedColumns)\n : GridUtils.moveItem(draggingColumn.visibleIndex, to, movedColumns);\n\n const moveDistance = to - draggingColumn.range[0];\n const newDraggingRange: BoundedAxisRange = [\n draggingColumn.range[0] + moveDistance,\n draggingColumn.range[1] + moveDistance,\n ];\n\n if (this.draggingColumn) {\n this.draggingColumn = {\n ...this.draggingColumn,\n range: newDraggingRange,\n };\n }\n\n return newMovedColumns;\n }\n\n onUp(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n this.cursor = null;\n\n this.clearScrollInterval();\n\n if (this.draggingOffset != null) {\n this.draggingOffset = undefined;\n grid.setState({\n draggingColumn: null,\n isDragging: false,\n });\n return true;\n }\n\n return false;\n }\n}\n\nexport default GridColumnMoveMouseHandler;\n","import clamp from 'lodash.clamp';\nimport { EventHandlerResult } from '../EventHandlerResult';\nimport Grid from '../Grid';\nimport { VisibleIndex } from '../GridMetrics';\nimport GridMouseHandler from '../GridMouseHandler';\nimport { GridPoint } from '../GridUtils';\n\n/* eslint class-methods-use-this: \"off\" */\nclass GridHorizontalScrollBarMouseHandler extends GridMouseHandler {\n static getLeftWithOffsetFromRawLeft(\n grid: Grid,\n rawLeft: number\n ): { left: VisibleIndex; leftOffset: number } {\n const theme = grid.getTheme();\n const { metrics, metricCalculator } = grid;\n if (!metrics) throw new Error('metrics not set');\n\n if (theme.scrollSnapToColumn) {\n const left = Math.round(rawLeft);\n const leftOffset = 0;\n\n return { left, leftOffset };\n }\n const left = Math.floor(rawLeft);\n const leftOffsetPercent = rawLeft - left;\n let columnWidth = metrics.allColumnWidths.get(left);\n if (columnWidth == null) {\n const metricState = grid.getMetricState();\n columnWidth = metricCalculator.getVisibleColumnWidth(left, metricState);\n }\n const leftOffset = columnWidth * leftOffsetPercent;\n\n return { left, leftOffset };\n }\n\n private dragOffset?: number;\n\n // to trigger pointer event blocking\n cursor = 'default';\n\n isInScrollBar(gridPoint: GridPoint, grid: Grid): boolean {\n const theme = grid.getTheme();\n\n const { scrollBarSize, scrollBarHoverSize } = theme;\n const { metrics } = grid;\n if (!metrics) throw new Error('metrics not set');\n\n const { x, y } = gridPoint;\n const { barLeft, barWidth, height, hasHorizontalBar } = metrics;\n\n return (\n hasHorizontalBar &&\n scrollBarSize > 0 &&\n y >= height - scrollBarHoverSize &&\n y < height &&\n x > barLeft &&\n x < barLeft + barWidth\n );\n }\n\n getLeftWithOffset(\n gridPoint: GridPoint,\n grid: Grid\n ): { left: number; leftOffset: number } {\n const { metrics } = grid;\n if (!metrics) throw new Error('metrics not set');\n\n const { x } = gridPoint;\n const {\n barWidth,\n handleWidth,\n lastLeft,\n barLeft,\n columnCount,\n scrollableContentWidth,\n scrollableViewportWidth,\n } = metrics;\n\n const mouseBarX = x - barLeft;\n const scrollPercent = clamp(\n (mouseBarX - (this.dragOffset ?? 0)) / (barWidth - handleWidth),\n 0,\n 1\n );\n\n if (columnCount === 1) {\n return {\n left: 0,\n leftOffset:\n scrollPercent * (scrollableContentWidth - scrollableViewportWidth),\n };\n }\n\n const rawLeft = scrollPercent * lastLeft;\n return GridHorizontalScrollBarMouseHandler.getLeftWithOffsetFromRawLeft(\n grid,\n rawLeft\n );\n }\n\n onDown(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n const { metrics } = grid;\n if (!metrics) throw new Error('metrics not set');\n\n const { x } = gridPoint;\n const { handleWidth, barLeft, scrollX } = metrics;\n if (!this.isInScrollBar(gridPoint, grid)) {\n return false;\n }\n\n const mouseBarX = x - barLeft;\n if (mouseBarX >= scrollX && mouseBarX <= scrollX + handleWidth) {\n // Grabbed the horizontal handle\n this.dragOffset = mouseBarX - scrollX;\n grid.setState({ isDraggingHorizontalScrollBar: true });\n } else {\n this.dragOffset = 0;\n\n const {\n left: newLeft,\n leftOffset: newLeftOffset,\n } = this.getLeftWithOffset(gridPoint, grid);\n\n grid.setViewState({\n left: newLeft,\n leftOffset: newLeftOffset,\n isDraggingHorizontalScrollBar: true,\n isDragging: true,\n });\n }\n\n return true;\n }\n\n onDrag(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n if (this.dragOffset != null) {\n const {\n left: newLeft,\n leftOffset: newLeftOffset,\n } = this.getLeftWithOffset(gridPoint, grid);\n\n grid.setViewState({\n left: newLeft,\n leftOffset: newLeftOffset,\n isDraggingHorizontalScrollBar: true,\n isDragging: true,\n });\n\n return true;\n }\n return false;\n }\n\n onMove(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n return this.isInScrollBar(gridPoint, grid);\n }\n\n onUp(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n if (this.dragOffset !== undefined) {\n this.dragOffset = undefined;\n grid.setState({\n isDraggingHorizontalScrollBar: false,\n isDragging: false,\n });\n }\n\n return this.isInScrollBar(gridPoint, grid);\n }\n\n onClick(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n return this.isInScrollBar(gridPoint, grid);\n }\n}\n\nexport default GridHorizontalScrollBarMouseHandler;\n","import { getOrThrow } from '@deephaven/utils';\nimport { EventHandlerResult } from '../EventHandlerResult';\nimport Grid from '../Grid';\nimport GridMouseHandler from '../GridMouseHandler';\nimport GridUtils, { GridPoint } from '../GridUtils';\n\nclass GridRowMoveMouseHandler extends GridMouseHandler {\n cursor = 'move';\n\n private draggingOffset?: number;\n\n onDown(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n const { model } = grid.props;\n const { x, y, row } = gridPoint;\n const { metrics } = grid;\n if (!metrics) throw new Error('metrics not set');\n\n const { columnHeaderHeight, rowHeaderWidth, allRowYs } = metrics;\n\n if (x <= rowHeaderWidth && row !== null && model.isRowMovable(row)) {\n const rowY = getOrThrow(allRowYs, row);\n this.draggingOffset = y - rowY - columnHeaderHeight;\n grid.setState({ draggingRowOffset: this.draggingOffset });\n }\n return false;\n }\n\n onDrag(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n if (this.draggingOffset == null) {\n return false;\n }\n\n const { model } = grid.props;\n let { draggingRow } = grid.state;\n const { mouseX, mouseY } = grid.state;\n if (mouseX == null || mouseY == null) {\n return false;\n }\n\n if (draggingRow == null) {\n const { row } = grid.getGridPointFromXY(mouseX, mouseY);\n if (row != null && !model.isRowMovable(row)) {\n return false;\n }\n\n draggingRow = row;\n\n grid.setState({ draggingRow, isDragging: true });\n\n if (draggingRow == null) {\n return false;\n }\n }\n\n const { metrics } = grid;\n if (!metrics) throw new Error('metrics not set');\n\n const {\n top,\n lastTop,\n bottom,\n bottomVisible,\n rowCount,\n columnHeaderHeight,\n allRowHeights,\n allRowYs,\n height,\n } = metrics;\n let minY = columnHeaderHeight;\n if (top < draggingRow) {\n const topRow = draggingRow - 1;\n minY =\n getOrThrow(allRowYs, topRow) +\n getOrThrow(allRowHeights, topRow) * 0.5 +\n columnHeaderHeight;\n }\n\n let maxY = height;\n if (draggingRow < bottom) {\n const bottomRow = draggingRow + 1;\n maxY =\n getOrThrow(allRowYs, bottomRow) +\n getOrThrow(allRowHeights, bottomRow) * 0.5 +\n columnHeaderHeight;\n }\n\n let { movedRows } = grid.state;\n if (\n mouseY < minY &&\n draggingRow > 0 &&\n model.isRowMovable(draggingRow - 1)\n ) {\n movedRows = GridUtils.moveItem(draggingRow, draggingRow - 1, movedRows);\n draggingRow -= 1;\n } else if (\n maxY < mouseY &&\n draggingRow < rowCount - 1 &&\n model.isRowMovable(draggingRow + 1)\n ) {\n movedRows = GridUtils.moveItem(draggingRow, draggingRow + 1, movedRows);\n draggingRow += 1;\n }\n grid.setState({ movedRows, draggingRow });\n\n const minMoveY = columnHeaderHeight + getOrThrow(allRowHeights, top) * 0.5;\n const maxMoveY =\n columnHeaderHeight +\n getOrThrow(allRowYs, bottomVisible) +\n getOrThrow(allRowHeights, bottomVisible) * 0.5;\n if (mouseY < minMoveY && top > 0) {\n grid.setState({ top: top - 1 });\n } else if (mouseY > maxMoveY && top < lastTop) {\n grid.setState({ top: top + 1 });\n }\n\n return true;\n }\n\n onUp(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n if (this.draggingOffset !== undefined) {\n this.draggingOffset = undefined;\n grid.setState({\n draggingRowOffset: null,\n draggingRow: null,\n isDragging: false,\n });\n return true;\n }\n\n return false;\n }\n}\n\nexport default GridRowMoveMouseHandler;\n","/* eslint class-methods-use-this: \"off\" */\nimport Grid from '../Grid';\nimport GridMetricCalculator from '../GridMetricCalculator';\nimport type { ModelIndex, GridMetrics } from '../GridMetrics';\nimport type GridModel from '../GridModel';\nimport { GridTheme } from '../GridTheme';\nimport GridUtils, { GridPoint } from '../GridUtils';\nimport GridSeparatorMouseHandler, {\n GridSeparator,\n} from './GridSeparatorMouseHandler';\n\nclass GridRowSeparatorMouseHandler extends GridSeparatorMouseHandler {\n static getRowSeparator(\n gridPoint: GridPoint,\n metrics: GridMetrics,\n model: GridModel,\n theme: GridTheme\n ): GridSeparator | null {\n if (!theme.allowRowResize) {\n return null;\n }\n\n const { x, y } = gridPoint;\n\n const index = GridUtils.getRowSeparatorIndex(x, y, metrics, theme);\n\n return index != null ? { index, depth: 0 } : null;\n }\n\n hiddenCursor = 's-resize';\n\n defaultCursor = 'row-resize';\n\n pointProperty = 'y' as const;\n\n userSizesProperty = 'userRowHeights' as const;\n\n visibleOffsetProperty = 'visibleRowYs' as const;\n\n visibleSizesProperty = 'visibleRowHeights' as const;\n\n marginProperty = 'columnHeaderHeight' as const;\n\n calculatedSizesProperty = 'calculatedRowHeights' as const;\n\n initialSizesProperty = 'initialRowHeights' as const;\n\n modelIndexesProperty = 'modelRows' as const;\n\n firstIndexProperty = 'firstRow' as const;\n\n treePaddingProperty = 'treePaddingY' as const;\n\n getHiddenItems = GridUtils.getHiddenRows;\n\n getNextShownItem = GridUtils.getNextShownRow;\n\n setSize(\n metricCalculator: GridMetricCalculator,\n modelIndex: ModelIndex,\n size: number\n ): void {\n metricCalculator.setRowHeight(modelIndex, size);\n }\n\n resetSize(\n metricCalculator: GridMetricCalculator,\n modelIndex: ModelIndex\n ): void {\n metricCalculator.resetRowHeight(modelIndex);\n }\n\n updateSeparator(grid: Grid, separator: GridSeparator | null): void {\n grid.setState({\n draggingRowSeparator: separator,\n isDragging: separator !== null,\n });\n }\n\n getSeparator = GridRowSeparatorMouseHandler.getRowSeparator;\n}\n\nexport default GridRowSeparatorMouseHandler;\n","/* eslint class-methods-use-this: \"off\" */\nimport { getOrThrow } from '@deephaven/utils';\nimport { EventHandlerResult } from '../EventHandlerResult';\nimport Grid from '../Grid';\nimport GridMouseHandler from '../GridMouseHandler';\nimport GridUtils, { GridPoint } from '../GridUtils';\n\n/**\n * Detect when the tree expand/collapse button is clicked\n */\nclass GridRowTreeMouseHandler extends GridMouseHandler {\n static isInTreeBox(gridPoint: GridPoint, grid: Grid): boolean {\n const { column, row, x, y } = gridPoint;\n const { metrics } = grid;\n if (!metrics) throw new Error('metrics not set');\n\n const {\n gridX,\n gridY,\n firstColumn,\n allColumnXs,\n allColumnWidths,\n allRowHeights,\n allRowYs,\n visibleRowTreeBoxes,\n } = metrics;\n\n if (\n column === firstColumn &&\n row != null &&\n visibleRowTreeBoxes.get(row) != null &&\n x > gridX &&\n y > gridY\n ) {\n const columnX = getOrThrow(allColumnXs, column);\n const width = getOrThrow(allColumnWidths, column);\n const rowY = getOrThrow(allRowYs, row);\n const height = getOrThrow(allRowHeights, row);\n if (\n x >= gridX + columnX &&\n x <= gridX + columnX + width &&\n y >= gridY + rowY &&\n y <= gridY + rowY + height\n ) {\n return true;\n }\n }\n return false;\n }\n\n onDown(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n return GridRowTreeMouseHandler.isInTreeBox(gridPoint, grid);\n }\n\n onClick(\n gridPoint: GridPoint,\n grid: Grid,\n event: React.MouseEvent\n ): EventHandlerResult {\n if (GridRowTreeMouseHandler.isInTreeBox(gridPoint, grid)) {\n const { row } = gridPoint;\n if (row !== null) {\n grid.toggleRowExpanded(row, GridUtils.isModifierKeyDown(event));\n return true;\n }\n }\n return false;\n }\n}\n\nexport default GridRowTreeMouseHandler;\n","/* eslint class-methods-use-this: \"off\" */\nimport { EventHandlerResult } from '../EventHandlerResult';\nimport Grid from '../Grid';\nimport GridMouseHandler from '../GridMouseHandler';\nimport { GridPoint } from '../GridUtils';\n\n/**\n * Used to eat the mouse event in the bottom right corner of the scroll bar\n */\nclass GridScrollBarCornerMouseHandler extends GridMouseHandler {\n isInCorner(gridPoint: GridPoint, grid: Grid): boolean {\n const theme = grid.getTheme();\n const { scrollBarSize } = theme;\n const { metrics } = grid;\n if (!metrics) throw new Error('metrics not set');\n\n const { x, y } = gridPoint;\n const { width, height, hasVerticalBar, hasHorizontalBar } = metrics;\n return (\n scrollBarSize > 0 &&\n hasVerticalBar &&\n hasHorizontalBar &&\n x >= width - scrollBarSize &&\n y >= height - scrollBarSize &&\n x <= width &&\n y <= height\n );\n }\n\n onDown(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n return this.isInCorner(gridPoint, grid);\n }\n\n onUp(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n return this.isInCorner(gridPoint, grid);\n }\n\n onClick(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n return this.isInCorner(gridPoint, grid);\n }\n}\n\nexport default GridScrollBarCornerMouseHandler;\n","import clamp from 'lodash.clamp';\nimport { EventHandlerResult } from '../EventHandlerResult';\nimport Grid from '../Grid';\nimport { VisibleIndex } from '../GridMetrics';\nimport GridMouseHandler from '../GridMouseHandler';\nimport { GridPoint } from '../GridUtils';\n\n/* eslint class-methods-use-this: \"off\" */\nclass GridVerticalScrollBarMouseHandler extends GridMouseHandler {\n static getTopWithOffsetFromRawTop(\n grid: Grid,\n rawTop: number\n ): { top: VisibleIndex; topOffset: number } {\n const theme = grid.getTheme();\n const { metrics, metricCalculator } = grid;\n if (!metrics) throw new Error('metrics not set');\n\n if (theme.scrollSnapToRow) {\n const top = Math.round(rawTop);\n const topOffset = 0;\n\n return { top, topOffset };\n }\n const top = Math.floor(rawTop);\n const topOffsetPercent = rawTop - top;\n let rowHeight = metrics.allRowHeights.get(top);\n if (rowHeight == null) {\n const metricState = grid.getMetricState();\n rowHeight = metricCalculator.getVisibleRowHeight(top, metricState);\n }\n const topOffset = rowHeight * topOffsetPercent;\n\n return { top, topOffset };\n }\n\n private dragOffset?: number;\n\n // to trigger pointer event blocking\n cursor = 'default';\n\n isInScrollBar(gridPoint: GridPoint, grid: Grid): boolean {\n const theme = grid.getTheme();\n\n const { scrollBarSize, scrollBarHoverSize } = theme;\n const { metrics } = grid;\n if (!metrics) throw new Error('metrics not set');\n\n const { x, y } = gridPoint;\n const { barTop, barHeight, width, hasVerticalBar } = metrics;\n\n return (\n hasVerticalBar &&\n scrollBarSize > 0 &&\n x >= width - scrollBarHoverSize &&\n x < width &&\n y > barTop &&\n y < barTop + barHeight\n );\n }\n\n getTopWithOffset(\n gridPoint: GridPoint,\n grid: Grid\n ): { top: number; topOffset: number } {\n const { metrics } = grid;\n if (!metrics) throw new Error('metrics not set');\n\n const { y } = gridPoint;\n const {\n barHeight,\n handleHeight,\n lastTop,\n barTop,\n rowCount,\n scrollableContentHeight,\n scrollableViewportHeight,\n } = metrics;\n\n const mouseBarY = y - barTop;\n const scrollPercent = clamp(\n (mouseBarY - (this.dragOffset ?? 0)) / (barHeight - handleHeight),\n 0,\n 1\n );\n\n if (rowCount === 1) {\n return {\n top: 0,\n topOffset:\n scrollPercent * (scrollableContentHeight - scrollableViewportHeight),\n };\n }\n\n const rawTop = scrollPercent * lastTop;\n return GridVerticalScrollBarMouseHandler.getTopWithOffsetFromRawTop(\n grid,\n rawTop\n );\n }\n\n onDown(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n const { metrics } = grid;\n if (!metrics) throw new Error('metrics not set');\n\n const { y } = gridPoint;\n const { handleHeight, barTop, scrollY } = metrics;\n if (!this.isInScrollBar(gridPoint, grid)) {\n return false;\n }\n\n const mouseBarY = y - barTop;\n if (mouseBarY >= scrollY && mouseBarY <= scrollY + handleHeight) {\n // Grabbed the vertical handle\n this.dragOffset = mouseBarY - scrollY;\n grid.setState({ isDraggingVerticalScrollBar: true });\n } else {\n // clicked elsewhere in bar\n this.dragOffset = 0;\n\n const { top: newTop, topOffset: newTopOffset } = this.getTopWithOffset(\n gridPoint,\n grid\n );\n\n grid.setViewState({\n top: newTop,\n topOffset: newTopOffset,\n isDraggingVerticalScrollBar: true,\n isDragging: true,\n });\n }\n\n return true;\n }\n\n onMove(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n return this.isInScrollBar(gridPoint, grid);\n }\n\n onDrag(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n if (this.dragOffset != null) {\n const { top: newTop, topOffset: newTopOffset } = this.getTopWithOffset(\n gridPoint,\n grid\n );\n\n grid.setViewState({\n top: newTop,\n topOffset: newTopOffset,\n isDraggingVerticalScrollBar: true,\n isDragging: true,\n });\n return true;\n }\n return false;\n }\n\n onUp(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n if (this.dragOffset !== undefined) {\n this.dragOffset = undefined;\n grid.setState({ isDraggingVerticalScrollBar: false, isDragging: false });\n }\n\n return this.isInScrollBar(gridPoint, grid);\n }\n\n onClick(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n return this.isInScrollBar(gridPoint, grid);\n }\n}\n\nexport default GridVerticalScrollBarMouseHandler;\n","/* eslint class-methods-use-this: \"off\" */\nimport { isEditableGridModel } from '../EditableGridModel';\nimport { EventHandlerResult } from '../EventHandlerResult';\nimport Grid from '../Grid';\nimport GridMouseHandler from '../GridMouseHandler';\nimport GridRange from '../GridRange';\nimport { GridPoint } from '../GridUtils';\n\n/**\n * Handles clicking on a cell to edit it in an editable grid\n */\nclass EditMouseHandler extends GridMouseHandler {\n onDoubleClick({ column, row }: GridPoint, grid: Grid): EventHandlerResult {\n const { model } = grid.props;\n if (\n isEditableGridModel(model) &&\n column != null &&\n row != null &&\n model.isEditableRange(GridRange.makeCell(column, row))\n ) {\n grid.startEditing(column, row);\n return true;\n }\n return false;\n }\n}\n\nexport default EditMouseHandler;\n","/* eslint class-methods-use-this: \"off\" */\n\nimport { isEditableGridModel } from '../EditableGridModel';\nimport { EventHandlerResult } from '../EventHandlerResult';\nimport Grid from '../Grid';\nimport GridMouseHandler, { GridMouseEvent } from '../GridMouseHandler';\nimport GridRange from '../GridRange';\nimport GridUtils, { GridPoint, isLinkToken, TokenBox } from '../GridUtils';\n\nclass GridTokenMouseHandler extends GridMouseHandler {\n timeoutId?: ReturnType<typeof setTimeout>;\n\n private isHold = false;\n\n private isDown = false;\n\n // Stores the current hovered token box if it exists with translated coordinates\n private currentLinkBox?: TokenBox;\n\n private static HOLD_LENGTH = 1000;\n\n isHoveringLink(gridPoint: GridPoint, grid: Grid): boolean {\n const { column, row, x, y } = gridPoint;\n const { renderer, metrics } = grid;\n\n if (column == null || row == null || metrics == null) {\n this.currentLinkBox = undefined;\n return false;\n }\n\n if (this.currentLinkBox != null) {\n const { x1: left, y1: top, x2: right, y2: bottom } = this.currentLinkBox;\n if (x >= left && x <= right && y >= top && y <= bottom) {\n return true;\n }\n }\n\n const renderState = grid.updateRenderState();\n const tokensInCell = renderer.getTokenBoxesForVisibleCell(\n column,\n row,\n renderState\n );\n\n // Loop through each link and check if cursor is in bounds\n for (let i = 0; i < tokensInCell.length; i += 1) {\n if (isLinkToken(tokensInCell[i].token)) {\n const translatedTokenBox = GridUtils.translateTokenBox(\n tokensInCell[i],\n metrics\n );\n const { x1: left, x2: right, y1: top, y2: bottom } = translatedTokenBox;\n if (x >= left && x <= right && y >= top && y <= bottom) {\n this.currentLinkBox = translatedTokenBox;\n return true;\n }\n }\n }\n\n // If this point is reached, that means the cursor was not hovering any of the links or there are no links\n this.currentLinkBox = undefined;\n return false;\n }\n\n /**\n * Set the cursor to pointer when hovering over a link\n * @param gridPoint Mouse position information\n * @param grid The grid\n * @returns False\n */\n private setCursor(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n if (this.isHoveringLink(gridPoint, grid)) {\n this.cursor = 'pointer';\n } else {\n this.cursor = null;\n }\n return false;\n }\n\n onMove(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n return this.setCursor(gridPoint, grid);\n }\n\n onDown(\n gridPoint: GridPoint,\n grid: Grid,\n event: GridMouseEvent\n ): EventHandlerResult {\n const isUserHoveringLink = this.isHoveringLink(gridPoint, grid);\n\n // If a modifier key or shift is down, we don't want to handle it and set isDown to false so onUp won't handle it either\n if (\n GridUtils.isModifierKeyDown(event) ||\n event.shiftKey ||\n !isUserHoveringLink\n ) {\n return false;\n }\n\n this.isDown = true;\n\n if (this.timeoutId != null) {\n clearTimeout(this.timeoutId);\n }\n this.isHold = false;\n this.timeoutId = setTimeout(() => {\n this.isHold = true;\n const { column, row } = gridPoint;\n const { model } = grid.props;\n\n // After 1 second, select the row and if it is an input table, start editing\n grid.clearSelectedRanges();\n grid.focus();\n grid.moveCursorToPosition(column, row);\n if (\n isEditableGridModel(model) &&\n column != null &&\n row != null &&\n model.isEditableRange(GridRange.makeCell(column, row))\n ) {\n grid.startEditing(column, row);\n }\n }, GridTokenMouseHandler.HOLD_LENGTH);\n\n return true;\n }\n\n onClick(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n const isUserHoveringLink = this.isHoveringLink(gridPoint, grid);\n\n if (!isUserHoveringLink || !this.isDown || this.currentLinkBox == null) {\n this.isDown = false;\n this.isHold = false;\n return false;\n }\n\n // User is hovering a link, isDown is true\n // If isHold is true, then the select already happened so onUp shouldn't do anything\n if (!this.isHold) {\n // Cancel the timeout and open a new tab with the link\n if (this.timeoutId != null) {\n clearTimeout(this.timeoutId);\n }\n this.timeoutId = undefined;\n grid.props.onTokenClicked(this.currentLinkBox?.token);\n }\n\n this.isHold = false;\n this.isDown = false;\n\n return true;\n }\n}\n\nexport default GridTokenMouseHandler;\n","/* eslint class-methods-use-this: \"off\" */\n/* eslint @typescript-eslint/no-unused-vars: \"off\" */\n/**\n * Handle keys in a grid\n * Return true from any of the events to indicate they're consumed, and stopPropagation/preventDefault will be called.\n */\n\nimport React from 'react';\nimport { EventHandlerResult } from './EventHandlerResult';\nimport type Grid from './Grid';\n\n/**\n * Some events we listen to are a native keyboard event, and others are wrapped with React's SyntheticEvent.\n * The KeyHandler shouldn't care though - the properties it accesses should be common on both types of events.\n */\nexport type GridKeyboardEvent = KeyboardEvent | React.KeyboardEvent;\n\nexport class KeyHandler {\n order: number;\n\n // What order this key handler should trigger in\n // Default to well below any of the GRID key handlers 100-1000+\n constructor(order = 5000) {\n this.order = order;\n }\n\n /**\n * Handle a keydown event on the grid.\n * @param event The keyboard event\n * @param grid The grid component the key press is on\n * @returns Response indicating if the key was consumed\n */\n onDown(event: GridKeyboardEvent, grid: Grid): EventHandlerResult {\n return false;\n }\n}\n\nexport default KeyHandler;\n","/* eslint class-methods-use-this: \"off\" */\nimport clamp from 'lodash.clamp';\nimport { EventHandlerResult } from '../EventHandlerResult';\nimport Grid from '../Grid';\nimport GridRange from '../GridRange';\nimport GridUtils from '../GridUtils';\nimport KeyHandler, { GridKeyboardEvent } from '../KeyHandler';\n\nclass SelectionKeyHandler extends KeyHandler {\n onDown(event: GridKeyboardEvent, grid: Grid): EventHandlerResult {\n switch (event.key) {\n case 'a':\n if (GridUtils.isModifierKeyDown(event)) {\n grid.selectAll();\n return true;\n }\n break;\n case 'ArrowUp':\n return this.handleArrowMove(0, -1, event, grid);\n case 'ArrowDown':\n return this.handleArrowMove(0, 1, event, grid);\n case 'ArrowRight':\n return this.handleArrowMove(1, 0, event, grid);\n case 'ArrowLeft':\n return this.handleArrowMove(-1, 0, event, grid);\n /**\n * h/j/k/l keys are grouped together for quick navigation by power users.\n * Bender added these as shortcuts in the original commit of keyboard shortcuts.\n * We have no idea why, or what might have inspired them (not excel, not swing, vim?).\n * Maybe lack of page up keys on a laptop at the time?\n */\n case 'k':\n case 'K':\n if (GridUtils.isModifierKeyDown(event)) return false;\n return this.handlePageUp(event, grid);\n case 'j':\n case 'J':\n if (GridUtils.isModifierKeyDown(event)) return false;\n return this.handlePageDown(event, grid);\n case 'h':\n case 'H':\n if (GridUtils.isModifierKeyDown(event)) return false;\n if (!event.shiftKey) {\n grid.clearSelectedRanges();\n }\n grid.moveCursorToPosition(0, grid.state.cursorRow, event.shiftKey);\n return true;\n case 'l':\n case 'L': {\n if (GridUtils.isModifierKeyDown(event)) return false;\n const { model } = grid.props;\n const { columnCount } = model;\n if (!event.shiftKey) {\n grid.clearSelectedRanges();\n }\n grid.moveCursorToPosition(\n columnCount - 1,\n grid.state.cursorRow,\n event.shiftKey\n );\n return true;\n }\n case 'PageDown':\n return this.handlePageDown(event, grid);\n case 'PageUp':\n return this.handlePageUp(event, grid);\n case 'Home':\n if (!event.shiftKey) {\n grid.clearSelectedRanges();\n }\n grid.moveCursorToPosition(\n GridUtils.isModifierKeyDown(event) ? grid.state.cursorColumn : 0,\n GridUtils.isModifierKeyDown(event) ? 0 : grid.state.cursorRow,\n event.shiftKey,\n true,\n true\n );\n return true;\n case 'End': {\n const { model } = grid.props;\n const { columnCount, rowCount } = model;\n if (!event.shiftKey) {\n grid.clearSelectedRanges();\n }\n grid.moveCursorToPosition(\n GridUtils.isModifierKeyDown(event)\n ? grid.state.cursorColumn\n : columnCount - 1,\n GridUtils.isModifierKeyDown(event)\n ? rowCount - 1\n : grid.state.cursorRow,\n event.shiftKey,\n true,\n true\n );\n return true;\n }\n case 'Escape':\n grid.clearSelectedRanges();\n // Event consumed, but propagation not stopped\n // so the shortcut could be handled by the global handler\n return { preventDefault: false, stopPropagation: false };\n case 'Enter':\n if (grid.state.selectedRanges.length > 0) {\n grid.moveCursorInDirection(\n event.shiftKey\n ? GridRange.SELECTION_DIRECTION.UP\n : GridRange.SELECTION_DIRECTION.DOWN\n );\n return true;\n }\n break;\n case 'Tab':\n if (grid.state.selectedRanges.length > 0) {\n grid.moveCursorInDirection(\n event.shiftKey\n ? GridRange.SELECTION_DIRECTION.LEFT\n : GridRange.SELECTION_DIRECTION.RIGHT\n );\n return true;\n }\n break;\n default:\n break;\n }\n return false;\n }\n\n handleArrowMove(\n deltaColumn: number,\n deltaRow: number,\n event: GridKeyboardEvent,\n grid: Grid\n ): boolean {\n const isShiftKey = event.shiftKey;\n const isModifierKey = GridUtils.isModifierKeyDown(event);\n if (isShiftKey) {\n grid.trimSelectedRanges();\n } else {\n grid.clearSelectedRanges();\n }\n\n const {\n cursorRow,\n cursorColumn,\n selectionEndColumn,\n selectionEndRow,\n } = grid.state;\n const column = isShiftKey ? selectionEndColumn : cursorColumn;\n const row = isShiftKey ? selectionEndRow : cursorRow;\n if (isModifierKey) {\n const { model } = grid.props;\n const { columnCount, rowCount } = model;\n const maximizePreviousRange = isModifierKey && isShiftKey;\n let moveToColumn = null;\n let moveToRow = null;\n if (deltaColumn < 0) {\n moveToColumn = 0;\n moveToRow = row;\n } else if (deltaColumn > 0) {\n moveToColumn = columnCount - 1;\n moveToRow = row;\n } else if (deltaRow < 0) {\n moveToColumn = column;\n moveToRow = 0;\n } else if (deltaRow > 0) {\n moveToColumn = column;\n moveToRow = rowCount - 1;\n }\n if (moveToColumn != null && moveToRow != null) {\n grid.moveCursorToPosition(\n moveToColumn,\n moveToRow,\n isShiftKey,\n true,\n maximizePreviousRange\n );\n }\n } else {\n if (!grid.metrics) throw new Error('grid.metrics are not set');\n\n const { theme } = grid.props;\n const { autoSelectRow = false, autoSelectColumn = false } = theme;\n if (autoSelectRow && deltaColumn !== 0) {\n const { lastLeft } = grid.metrics;\n let { left } = grid.state;\n\n left = clamp(left + deltaColumn, 0, lastLeft);\n\n grid.moveCursorToPosition(left, cursorRow, isShiftKey, false);\n\n grid.setViewState({ left });\n } else if (autoSelectColumn && deltaRow !== 0) {\n const { lastTop } = grid.metrics;\n let { top } = grid.state;\n\n top = clamp(top + deltaRow, 0, lastTop);\n\n grid.moveCursorToPosition(top, cursorColumn, isShiftKey, false);\n\n grid.setViewState({ top });\n } else {\n grid.moveCursor(deltaColumn, deltaRow, isShiftKey);\n }\n }\n return true;\n }\n\n handlePageUp(e: GridKeyboardEvent, grid: Grid): boolean {\n const isShiftKey = e.shiftKey;\n\n if (isShiftKey) {\n grid.trimSelectedRanges();\n } else {\n grid.clearSelectedRanges();\n }\n\n const { cursorColumn, selectionEndRow } = grid.state;\n const row: number | null = selectionEndRow;\n const column: number | null = cursorColumn;\n if (row == null) {\n return false;\n }\n const metricState = grid.getMetricState();\n const { metricCalculator } = grid;\n const {\n bottomVisible,\n topVisible,\n hasHorizontalBar,\n } = metricCalculator.getMetrics(metricState);\n\n let selectRangeEndPosition = row - (bottomVisible - topVisible);\n selectRangeEndPosition -= hasHorizontalBar ? 0 : 1;\n\n // Don't move beyond the top table row.\n selectRangeEndPosition = Math.max(selectRangeEndPosition, 0);\n const viewportPosition = Math.max(\n selectRangeEndPosition - (row - topVisible),\n 0\n );\n\n grid.moveCursorToPosition(\n column,\n selectRangeEndPosition,\n isShiftKey,\n false\n );\n grid.setViewState({ top: viewportPosition });\n return true;\n }\n\n handlePageDown(e: GridKeyboardEvent, grid: Grid): boolean {\n const isShiftKey = e.shiftKey;\n\n if (isShiftKey) {\n grid.trimSelectedRanges();\n } else {\n grid.clearSelectedRanges();\n }\n\n const { selectionEndRow, cursorColumn } = grid.state;\n const row: number | null = selectionEndRow;\n const column: number | null = cursorColumn;\n if (row === null) {\n return false;\n }\n const metricState = grid.getMetricState();\n const { metricCalculator } = grid;\n const {\n bottomVisible,\n topVisible,\n hasHorizontalBar,\n rowCount,\n lastTop,\n } = metricCalculator.getMetrics(metricState);\n const lastRowIndex = rowCount - 1;\n\n let selectRangeEndPosition = bottomVisible - topVisible + row;\n selectRangeEndPosition += hasHorizontalBar ? 0 : 1;\n\n // Don't move beyond the bottom table row.\n selectRangeEndPosition = Math.min(selectRangeEndPosition, lastRowIndex);\n\n const viewportPosition = Math.min(\n lastTop,\n selectRangeEndPosition - (row - topVisible)\n );\n grid.moveCursorToPosition(\n column,\n selectRangeEndPosition,\n isShiftKey,\n false\n );\n grid.setViewState({ top: viewportPosition });\n\n return true;\n }\n}\n\nexport default SelectionKeyHandler;\n","/* eslint class-methods-use-this: \"off\" */\nimport { isExpandableGridModel } from '../ExpandableGridModel';\nimport Grid from '../Grid';\nimport GridRange from '../GridRange';\nimport KeyHandler from '../KeyHandler';\n\nclass TreeKeyHandler extends KeyHandler {\n onDown(event: KeyboardEvent, grid: Grid): boolean {\n switch (event.key) {\n case 'Enter':\n case ' ': {\n return this.handleExpandKey(event, grid);\n }\n default:\n break;\n }\n return false;\n }\n\n handleExpandKey(event: KeyboardEvent, grid: Grid): boolean {\n const { selectedRanges } = grid.state;\n if (selectedRanges.length === 1) {\n const range = selectedRanges[0] as GridRange;\n if (\n range.startRow === range.endRow &&\n range.startColumn === range.endColumn\n ) {\n if (!grid.metrics) throw new Error('grid.metrics not set');\n\n const { model } = grid.props;\n const { startRow: row, startColumn: column } = range;\n if (row != null) {\n const modelRow = grid.getModelRow(row);\n if (\n (column === 0 || column == null) &&\n isExpandableGridModel(model) &&\n model.isRowExpandable(modelRow)\n ) {\n grid.toggleRowExpanded(row);\n return true;\n }\n }\n }\n }\n return false;\n }\n}\n\nexport default TreeKeyHandler;\n","/* eslint class-methods-use-this: \"off\" */\nimport GridUtils from '../GridUtils';\nimport Grid from '../Grid';\nimport GridRange from '../GridRange';\nimport KeyHandler, { GridKeyboardEvent } from '../KeyHandler';\nimport { isEditableGridModel } from '../EditableGridModel';\nimport { EventHandlerResult } from '../EventHandlerResult';\n\nclass EditKeyHandler extends KeyHandler {\n onDown(event: GridKeyboardEvent, grid: Grid): EventHandlerResult {\n if (GridUtils.isModifierKeyDown(event)) {\n return false;\n }\n\n const { model } = grid.props;\n const { cursorColumn, cursorRow } = grid.state;\n if (\n cursorColumn == null ||\n cursorRow == null ||\n !isEditableGridModel(model) ||\n !model.isEditableRange(GridRange.makeCell(cursorColumn, cursorRow))\n ) {\n return false;\n }\n const column: number | null = cursorColumn;\n const row: number | null = cursorRow;\n if (column == null || row == null) {\n return false;\n }\n\n if (event.key.length === 1) {\n grid.startEditing(column, row, true, [1, 1], event.key);\n return true;\n }\n\n if (event.key === 'F2') {\n grid.startEditing(column, row);\n return true;\n }\n\n if (event.key === 'Backspace') {\n grid.startEditing(column, row, true, undefined, '');\n return true;\n }\n\n if (event.key === 'Delete') {\n grid.setValueForCell(column, row, '');\n return true;\n }\n return false;\n }\n}\n\nexport default EditKeyHandler;\n","/* eslint class-methods-use-this: \"off\" */\nimport { EventHandlerResult } from '../EventHandlerResult';\nimport Grid from '../Grid';\nimport GridUtils from '../GridUtils';\nimport KeyHandler, { GridKeyboardEvent } from '../KeyHandler';\n\n/**\n * Parse out data from an HTML table. Currently does not support colspan/rowspan\n * @param table HTML Table\n * @returns A two dimensional array with the data found in the table\n */\nexport function parseValueFromTable(table: HTMLTableElement): string[][] {\n const data = [];\n const rows = table.querySelectorAll('tr');\n for (let r = 0; r < rows.length; r += 1) {\n const row = rows[r];\n const cells = row.querySelectorAll('td');\n const rowData = [];\n for (let c = 0; c < cells.length; c += 1) {\n const cell = cells[c];\n rowData.push(cell.textContent?.trim() ?? '');\n }\n data.push(rowData);\n }\n\n return data;\n}\n\n/**\n * Parses out a table of data from HTML elements. Treats each element as one rows.\n * Filters out blank rows.\n * @param rows The elements to parse out\n * @returns A string table of data\n */\nexport function parseValueFromNodes(nodes: NodeListOf<ChildNode>): string[][] {\n const result = [] as string[][];\n nodes.forEach(node => {\n const text = node.textContent ?? '';\n if (text.length > 0) {\n // When Chrome pastes a table from text, it preserves the tab characters\n // In Firefox, it breaks it into a combination of non-breaking spaces and spaces\n result.push(text.split(/\\t|\\u00a0\\u00a0 \\u00a0/));\n }\n });\n\n return result;\n}\n\nexport function parseValueFromElement(\n element: HTMLElement\n): string | string[][] | null {\n // Check first if there's an HTML table element that we can use\n const table = element.querySelector('table');\n if (table != null) {\n return parseValueFromTable(table);\n }\n\n // Otherwise check if there's any text content at all\n const text = element.textContent?.trim() ?? '';\n if (text.length > 0) {\n // If there's text content, try and parse out a table from the child nodes. Each node is a row.\n // If there's only one row and it doesn't contain a tab, then just treat it as a regular value\n const { childNodes } = element;\n const hasTabChar = text.includes('\\t');\n const hasFirefoxTab = text.includes('\\u00a0\\u00a0 \\u00a0');\n if (\n hasTabChar &&\n childNodes.length !== 0 &&\n (childNodes.length === 1 ||\n (childNodes.length > 1 &&\n (childNodes[0].textContent == null ||\n !childNodes[0].textContent.includes('\\t'))))\n ) {\n // When Chrome pastes a single row, it gets split into multiple child nodes\n // If we check the first child node and it doesn't have a tab character, but the full element text content does, then\n // just parse the text out separated by the tab chars\n return text.split('\\n').map(row => row.split('\\t'));\n }\n if (childNodes.length > 1 || hasFirefoxTab) {\n return parseValueFromNodes(element.childNodes);\n }\n // If there's no tabs or no multiple rows, than just treat it as one value\n return text;\n }\n return null;\n}\n\n/**\n * Handles the paste key combination\n */\nclass PasteKeyHandler extends KeyHandler {\n onDown(event: GridKeyboardEvent, grid: Grid): EventHandlerResult {\n switch (event.key) {\n case 'v':\n if (GridUtils.isModifierKeyDown(event)) {\n // Chrome doesn't allow the paste event on canvas elements\n // Instead, we capture the ctrl+v keydown, then do this to capture the input\n const dummyInput = document.createElement('div');\n document.body.appendChild(dummyInput);\n dummyInput.setAttribute('contenteditable', 'true');\n\n // Give it invisible styling\n dummyInput.setAttribute(\n 'style',\n 'clip-path: \"inset(50%)\"; height: 1px; width: 1px; margin: -1px; overflow: hidden; padding 0; position: absolute;'\n );\n\n const listener = () => {\n dummyInput.removeEventListener('input', listener);\n dummyInput.remove();\n\n grid.focus();\n const value = parseValueFromElement(dummyInput);\n if (value != null) {\n grid.pasteValue(value);\n }\n };\n\n // Listen for the `input` event, when there's a change to the HTML\n // We could also listen to the `paste` event to get the clipboard data, but that's just text data\n // By listening to `input`, we can get a table that's already parsed in HTML, which is easier to consume\n dummyInput.addEventListener('input', listener);\n\n // Focus the element so it receives the paste event\n dummyInput.focus();\n\n // Don't block the paste event from updating our dummy input\n return { preventDefault: false, stopPropagation: true };\n }\n break;\n }\n return false;\n }\n}\n\nexport default PasteKeyHandler;\n","import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport { SELECTION_DIRECTION } from './GridRange';\nimport GridUtils from './GridUtils';\nimport './CellInputField.scss';\n\nexport type CellInputFieldProps = {\n selectionRange?: number[];\n className?: string;\n disabled?: boolean;\n isQuickEdit?: boolean;\n value?: string;\n onChange?: (value: string) => void;\n onCancel?: () => void;\n onDone?: (\n value: string,\n options: {\n direction?: SELECTION_DIRECTION | null;\n fillRange?: boolean;\n }\n ) => void;\n onContextMenu?: React.MouseEventHandler<HTMLTextAreaElement>;\n style?: React.CSSProperties;\n};\n\nconst directionForKey = (key: string): SELECTION_DIRECTION | undefined => {\n switch (key) {\n case 'ArrowDown':\n return SELECTION_DIRECTION.DOWN;\n case 'ArrowUp':\n return SELECTION_DIRECTION.UP;\n case 'ArrowLeft':\n return SELECTION_DIRECTION.LEFT;\n case 'ArrowRight':\n return SELECTION_DIRECTION.RIGHT;\n default:\n return undefined;\n }\n};\n\nexport function CellInputField({\n selectionRange = undefined,\n className = '',\n disabled = false,\n value: propsValue = '',\n isQuickEdit: propsIsQuickEdit = true,\n onChange = () => undefined,\n onCancel = () => undefined,\n onDone = () => undefined,\n onContextMenu = () => undefined,\n style = {},\n}: CellInputFieldProps): JSX.Element {\n const inputField = useRef<HTMLTextAreaElement>(null);\n // Use a ref for `isCancelled` as we need to know when it's cancelled after it's called by the event handlers as well\n const isCancelled = useRef<boolean>(false);\n const [initialValue] = useState(propsValue);\n const [isChanged, setIsChanged] = useState(false);\n const [isQuickEdit, setIsQuickEdit] = useState(propsIsQuickEdit);\n const [value, setValue] = useState(propsValue);\n\n // Init field selection\n useEffect(\n function selectInputField() {\n const { current: field } = inputField;\n if (field == null) {\n return;\n }\n\n field.focus();\n if (selectionRange) {\n field.setSelectionRange(selectionRange[0], selectionRange[1]);\n } else {\n field.setSelectionRange(field.value.length, field.value.length);\n }\n },\n [selectionRange]\n );\n\n const sendUpdate = useCallback(\n (newValue: string) => {\n onChange(newValue);\n },\n [onChange]\n );\n\n const handleChange = useCallback(\n (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n const { value: newValue } = event.target;\n setValue(newValue);\n setIsChanged(true);\n sendUpdate(newValue);\n },\n [sendUpdate, setValue, setIsChanged]\n );\n\n const handleCancel = useCallback(() => {\n isCancelled.current = true;\n if (isChanged) {\n sendUpdate(initialValue);\n }\n\n setIsChanged(false);\n onCancel();\n }, [initialValue, isChanged, onCancel, sendUpdate]);\n\n const handleClick = useCallback(() => {\n setIsQuickEdit(false);\n }, [setIsQuickEdit]);\n\n const handleCommit = useCallback(\n (direction?: SELECTION_DIRECTION | null, fillRange = false) => {\n onDone(value, { direction, fillRange });\n },\n [onDone, value]\n );\n\n const handleBlur = useCallback(() => {\n if (isCancelled.current) {\n return;\n }\n\n handleCommit(null);\n }, [isCancelled, handleCommit]);\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n event.stopPropagation();\n\n switch (event.key) {\n case 'Escape':\n event.preventDefault();\n handleCancel();\n break;\n case 'Enter':\n event.preventDefault();\n if (GridUtils.isModifierKeyDown(event)) {\n handleCommit(undefined, true);\n } else if (event.altKey) {\n const newValue = `${value}\\n`;\n setValue(newValue);\n setIsChanged(true);\n sendUpdate(newValue);\n } else {\n handleCommit(\n event.shiftKey ? SELECTION_DIRECTION.UP : SELECTION_DIRECTION.DOWN\n );\n }\n break;\n case 'Tab':\n event.preventDefault();\n handleCommit(\n event.shiftKey\n ? SELECTION_DIRECTION.LEFT\n : SELECTION_DIRECTION.RIGHT\n );\n break;\n case 'ArrowDown':\n case 'ArrowUp':\n case 'ArrowLeft':\n case 'ArrowRight':\n if (isQuickEdit) {\n event.preventDefault();\n handleCommit(directionForKey(event.key));\n }\n break;\n default:\n break;\n }\n },\n [\n handleCancel,\n handleCommit,\n isQuickEdit,\n setValue,\n setIsChanged,\n sendUpdate,\n value,\n ]\n );\n\n const handleContextMenu = useCallback(\n (event: React.MouseEvent<HTMLTextAreaElement, MouseEvent>) => {\n onContextMenu(event);\n },\n [onContextMenu]\n );\n\n return (\n <textarea\n ref={inputField}\n className={classNames('grid-cell-input-field', className)}\n value={value}\n onBlur={handleBlur}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onContextMenu={handleContextMenu}\n onClick={handleClick}\n autoComplete=\"off\"\n autoCorrect=\"off\"\n autoCapitalize=\"off\"\n spellCheck=\"false\"\n disabled={disabled}\n style={style}\n />\n );\n}\n\nCellInputField.propTypes = {\n selectionRange: PropTypes.arrayOf(PropTypes.number),\n className: PropTypes.string,\n disabled: PropTypes.bool,\n isQuickEdit: PropTypes.bool,\n value: PropTypes.string,\n onChange: PropTypes.func,\n onCancel: PropTypes.func,\n onDone: PropTypes.func,\n onContextMenu: PropTypes.func,\n style: PropTypes.shape({}),\n};\n\nCellInputField.defaultProps = {\n selectionRange: null,\n className: '',\n disabled: false,\n value: '',\n isQuickEdit: true,\n onChange: () => undefined,\n onCancel: () => undefined,\n onDone: () => undefined,\n onContextMenu: () => undefined,\n style: {},\n};\n\nexport default CellInputField;\n","import React from 'react';\nimport { GridTheme as GridThemeType } from './GridTheme';\n\nexport const ThemeContext: React.Context<\n Partial<GridThemeType>\n> = React.createContext({});\n\nexport default ThemeContext;\n","/* eslint react/no-did-update-set-state: \"off\" */\nimport React, { CSSProperties, PureComponent, ReactNode } from 'react';\nimport classNames from 'classnames';\nimport memoize from 'memoize-one';\nimport clamp from 'lodash.clamp';\nimport { assertNotNull, EMPTY_ARRAY } from '@deephaven/utils';\nimport GridMetricCalculator, { GridMetricState } from './GridMetricCalculator';\nimport GridModel from './GridModel';\nimport GridMouseHandler, {\n GridMouseEvent,\n GridMouseHandlerFunctionName,\n} from './GridMouseHandler';\nimport GridTheme, { GridTheme as GridThemeType } from './GridTheme';\nimport GridRange, { GridRangeIndex, SELECTION_DIRECTION } from './GridRange';\nimport GridRenderer from './GridRenderer';\nimport GridUtils, { GridPoint, isLinkToken, Token } from './GridUtils';\nimport {\n GridSelectionMouseHandler,\n GridColumnMoveMouseHandler,\n GridColumnSeparatorMouseHandler,\n GridHorizontalScrollBarMouseHandler,\n GridRowMoveMouseHandler,\n GridRowSeparatorMouseHandler,\n GridRowTreeMouseHandler,\n GridScrollBarCornerMouseHandler,\n GridVerticalScrollBarMouseHandler,\n EditMouseHandler,\n GridSeparator,\n GridTokenMouseHandler,\n} from './mouse-handlers';\nimport './Grid.scss';\nimport KeyHandler, { GridKeyboardEvent } from './KeyHandler';\nimport {\n EditKeyHandler,\n PasteKeyHandler,\n SelectionKeyHandler,\n TreeKeyHandler,\n} from './key-handlers';\nimport CellInputField from './CellInputField';\nimport PasteError from './errors/PasteError';\nimport GridMetrics, {\n Coordinate,\n ModelIndex,\n MoveOperation,\n VisibleIndex,\n} from './GridMetrics';\nimport { isExpandableGridModel } from './ExpandableGridModel';\nimport {\n assertIsEditableGridModel,\n EditOperation,\n isEditableGridModel,\n} from './EditableGridModel';\nimport { EventHandlerResultOptions } from './EventHandlerResult';\nimport { assertIsDefined } from './errors';\nimport ThemeContext from './ThemeContext';\nimport { DraggingColumn } from './mouse-handlers/GridColumnMoveMouseHandler';\nimport {\n EditingCell,\n GridRenderState,\n EditingCellTextSelectionRange,\n} from './GridRendererTypes';\n\ntype LegacyCanvasRenderingContext2D = CanvasRenderingContext2D & {\n webkitBackingStorePixelRatio?: number;\n mozBackingStorePixelRatio?: number;\n msBackingStorePixelRatio?: number;\n oBackingStorePixelRatio?: number;\n backingStorePixelRatio?: number;\n};\n\nexport type GridProps = typeof Grid.defaultProps & {\n // Options to set on the canvas\n canvasOptions?: CanvasRenderingContext2DSettings;\n\n // Whether the grid should stick to the bottom or the right once scrolled to the end\n // Only matters with ticking grids\n isStickyBottom?: boolean;\n isStickyRight?: boolean;\n\n // Whether the grid is currently stuck to the bottom or the right\n isStuckToBottom?: boolean;\n isStuckToRight?: boolean;\n\n // Calculate all the metrics required for drawing the grid\n metricCalculator?: GridMetricCalculator;\n\n // The model to pull data from\n model: GridModel;\n\n // Optional key and mouse handlers\n keyHandlers?: readonly KeyHandler[];\n mouseHandlers?: readonly GridMouseHandler[];\n\n // Initial state of moved columns or rows\n movedColumns?: readonly MoveOperation[];\n movedRows?: readonly MoveOperation[];\n\n // Callback for if an error occurs\n onError?: (e: Error) => void;\n\n // Callback when the selection within the grid changes\n onSelectionChanged?: (ranges: readonly GridRange[]) => void;\n\n // Callback when the moved columns or rows have changed\n onMovedColumnsChanged?: (movedColumns: readonly MoveOperation[]) => void;\n onMovedRowsChanged?: (movedRows: readonly MoveOperation[]) => void;\n\n // Callback when a move operation is completed\n onMoveColumnComplete?: (movedColumns: readonly MoveOperation[]) => void;\n onMoveRowComplete?: (movedRows: readonly MoveOperation[]) => void;\n\n // Callback when the viewport has scrolled or changed\n onViewChanged?: (metrics: GridMetrics) => void;\n\n // Callback when a token is clicked\n // eslint-disable-next-line react/no-unused-prop-types\n onTokenClicked?: (token: Token) => void;\n\n // Renderer for the grid canvas\n renderer?: GridRenderer;\n\n // Optional state override to pass in to the metric and render state\n // Can be used to add custom properties as well\n stateOverride?: Record<string, unknown>;\n\n theme?: Partial<GridThemeType>;\n};\n\nexport type GridState = {\n // Top/left visible cell in the grid. Note that it's visible row/column index, not the model index (ie. if columns are re-ordered)\n top: VisibleIndex;\n left: VisibleIndex;\n\n // The scroll offset of the top/left cell. 0,0 means the cell is at the top left\n topOffset: number; // Should be less than the height of the row\n leftOffset: number; // Should be less than the width of the column\n\n // current column/row that user is dragging\n draggingColumn: DraggingColumn | null;\n draggingRow: VisibleIndex | null;\n\n // Offset when dragging a row\n draggingRowOffset: number | null;\n\n // When drawing header separators for resizing\n // Keeps hover style when mouse is in buffer before resize starts\n draggingColumnSeparator: GridSeparator | null;\n draggingRowSeparator: GridSeparator | null;\n\n // Dragging a scroll bar status\n isDraggingHorizontalScrollBar: boolean;\n isDraggingVerticalScrollBar: boolean;\n\n // Anything is performing a drag, for blocking hover rendering\n isDragging: boolean;\n\n // The coordinates of the mouse. May be outside of the canvas\n mouseX: number | null;\n mouseY: number | null;\n\n // Move operations the user has performed on this grids columns/rows\n movedColumns: readonly MoveOperation[];\n movedRows: readonly MoveOperation[];\n\n // Cursor (highlighted cell) location and active selected range\n cursorRow: VisibleIndex | null;\n cursorColumn: VisibleIndex | null;\n selectionStartRow: VisibleIndex | null;\n selectionStartColumn: VisibleIndex | null;\n selectionEndRow: VisibleIndex | null;\n selectionEndColumn: VisibleIndex | null;\n\n // Currently selected ranges and previously selected ranges\n // Store the previously selected ranges to determine if the new selection should\n // deselect again (if it's the same range)\n selectedRanges: readonly GridRange[];\n lastSelectedRanges: readonly GridRange[];\n\n // The mouse cursor style to use when hovering over the grid element\n cursor: string | null;\n\n // { column: number, row: number, selectionRange: [number, number], value: string | null, isQuickEdit?: boolean }\n // The cell that is currently being edited\n editingCell: EditingCell | null;\n\n // Whether we're stuck to the bottom or the right\n isStuckToBottom: boolean;\n isStuckToRight: boolean;\n};\n\n/**\n * High performance, extendible, themeable grid component.\n * Architectured to be fast and handle billions of rows/columns by default.\n * The base model does not provide support for sorting, filtering, etc.\n * To get that functionality, extend GridModel/GridRenderer, and add onClick/onContextMenu handlers to implement your own sort.\n *\n * Extend GridModel with your own data model to provide the data for the grid.\n * Extend GridTheme to change the appearance if the grid. See GridTheme for all the settable values.\n * Extend GridMetricCalculator to provide different metrics for the grid, such as column sizing, header sizing, etc.\n * Extend GridRenderer to have complete control over the rendering process. Can override just one method such as drawColumnHeader, or override the whole drawCanvas process.\n *\n * Add an onViewChanged callback to page in/out data as user moves around the grid\n * Can also add onClick and onContextMenu handlers to add custom functionality and menus.\n */\nclass Grid extends PureComponent<GridProps, GridState> {\n static contextType = ThemeContext;\n\n static defaultProps = {\n canvasOptions: { alpha: false } as CanvasRenderingContext2DSettings,\n isStickyBottom: false,\n isStickyRight: false,\n isStuckToBottom: false,\n isStuckToRight: false,\n keyHandlers: EMPTY_ARRAY as readonly KeyHandler[],\n mouseHandlers: EMPTY_ARRAY as readonly GridMouseHandler[],\n movedColumns: EMPTY_ARRAY as readonly MoveOperation[],\n movedRows: EMPTY_ARRAY as readonly MoveOperation[],\n onError: (): void => undefined,\n onSelectionChanged: (): void => undefined,\n onMovedColumnsChanged: (moveOperations: readonly MoveOperation[]): void =>\n undefined,\n onMoveColumnComplete: (): void => undefined,\n onMovedRowsChanged: (): void => undefined,\n onMoveRowComplete: (): void => undefined,\n onViewChanged: (): void => undefined,\n onTokenClicked: (token: Token) => {\n if (isLinkToken(token)) {\n window.open(token.href, '_blank', 'noopener,noreferrer');\n }\n },\n stateOverride: {} as Record<string, unknown>,\n theme: {\n autoSelectColumn: false,\n autoSelectRow: false,\n } as Partial<GridThemeType>,\n };\n\n // use same constant as chrome source for windows\n // https://github.com/chromium/chromium/blob/973af9d461b6b5dc60208c8d3d66adc27e53da78/ui/events/blink/web_input_event_builders_win.cc#L285\n static pixelsPerLine = 100 / 3;\n\n static dragTimeout = 1000;\n\n static getTheme = memoize(\n (\n contextTheme: Partial<GridThemeType>,\n userTheme: Partial<GridThemeType>\n ) => ({\n ...GridTheme,\n ...contextTheme,\n ...userTheme,\n })\n );\n\n /**\n * On some devices there may be different scaling required for high DPI. Get the scale required for the canvas.\n * @param context The canvas context\n * @returns The scale to use\n */\n static getScale(context: CanvasRenderingContext2D): number {\n const devicePixelRatio = window.devicePixelRatio || 1;\n\n // backingStorePixelRatio is deprecated, but check it just in case\n const legacyContext = context as LegacyCanvasRenderingContext2D;\n\n const backingStorePixelRatio =\n // Not worth converting to a massive if structure\n // Converting would reduce readability and maintainability\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n legacyContext.webkitBackingStorePixelRatio ??\n legacyContext.mozBackingStorePixelRatio ??\n legacyContext.msBackingStorePixelRatio ??\n legacyContext.oBackingStorePixelRatio ??\n legacyContext.backingStorePixelRatio ??\n 1;\n return devicePixelRatio / backingStorePixelRatio;\n }\n\n /**\n * Get the class name from the cursor provided\n * @param cursor The grid cursor to use\n * @returns Class name with the grid-cursor prefix or null if no cursor provided\n */\n static getCursorClassName(cursor: string | null): string | null {\n return cursor != null && cursor !== '' ? `grid-cursor-${cursor}` : null;\n }\n\n // Need to disable react/sort-comp so I can put the fields here\n /* eslint-disable react/sort-comp */\n renderer: GridRenderer;\n\n metricCalculator: GridMetricCalculator;\n\n canvas: HTMLCanvasElement | null;\n\n canvasContext: CanvasRenderingContext2D | null;\n\n // We draw the canvas on the next animation frame, keep track of the next one\n animationFrame: number | null;\n\n // Keep track of previous metrics and new metrics for comparison\n prevMetrics: GridMetrics | null;\n\n metrics: GridMetrics | null;\n\n renderState: GridRenderState;\n\n // Track the cursor that is currently added to the document\n // Add to document so that when dragging the cursor stays, even if mouse leaves the canvas\n // Note: on document, not body so that cursor styling can be combined with\n // blocked pointer events that would otherwise prevent cursor styling from showing\n documentCursor: string | null;\n\n dragTimer: ReturnType<typeof setTimeout> | null;\n\n keyHandlers: readonly KeyHandler[];\n\n mouseHandlers: readonly GridMouseHandler[];\n\n /* eslint-enable react/sort-comp */\n\n constructor(props: GridProps) {\n super(props);\n\n this.handleClick = this.handleClick.bind(this);\n this.handleContextMenu = this.handleContextMenu.bind(this);\n this.handleEditCellCancel = this.handleEditCellCancel.bind(this);\n this.handleEditCellChange = this.handleEditCellChange.bind(this);\n this.handleEditCellCommit = this.handleEditCellCommit.bind(this);\n this.handleDoubleClick = this.handleDoubleClick.bind(this);\n this.handleKeyDown = this.handleKeyDown.bind(this);\n this.handleMouseDown = this.handleMouseDown.bind(this);\n this.handleMouseDrag = this.handleMouseDrag.bind(this);\n this.handleMouseMove = this.handleMouseMove.bind(this);\n this.handleMouseLeave = this.handleMouseLeave.bind(this);\n this.handleMouseUp = this.handleMouseUp.bind(this);\n this.handleResize = this.handleResize.bind(this);\n this.handleWheel = this.handleWheel.bind(this);\n\n const {\n isStuckToBottom,\n isStuckToRight,\n metricCalculator,\n movedColumns,\n movedRows,\n renderer,\n } = props;\n\n this.renderer = renderer || new GridRenderer();\n this.metricCalculator = metricCalculator || new GridMetricCalculator();\n\n this.canvas = null;\n this.canvasContext = null;\n this.animationFrame = null;\n\n this.prevMetrics = null;\n this.metrics = null;\n\n this.renderState = {} as GridRenderState;\n\n // Track the cursor that is currently added to the document\n // Add to document so that when dragging the cursor stays, even if mouse leaves the canvas\n // Note: on document, not body so that cursor styling can be combined with\n // blocked pointer events that would otherwise prevent cursor styling from showing\n this.documentCursor = null;\n\n this.dragTimer = null;\n\n // specify handler ordering, such that any extensions can insert handlers in between\n this.keyHandlers = [\n new EditKeyHandler(400),\n new PasteKeyHandler(450),\n new SelectionKeyHandler(500),\n new TreeKeyHandler(900),\n ];\n this.mouseHandlers = [\n new GridRowSeparatorMouseHandler(100),\n new GridColumnSeparatorMouseHandler(200),\n new GridRowMoveMouseHandler(300),\n new GridColumnMoveMouseHandler(400),\n new EditMouseHandler(450),\n new GridVerticalScrollBarMouseHandler(500),\n new GridHorizontalScrollBarMouseHandler(600),\n new GridScrollBarCornerMouseHandler(700),\n new GridRowTreeMouseHandler(800),\n new GridTokenMouseHandler(825),\n new GridSelectionMouseHandler(900),\n ];\n\n this.state = {\n // Top/left visible cell in the grid. Note that it's visible row/column index, not the model index (ie. if columns are re-ordered)\n top: 0,\n left: 0,\n\n // The scroll offset of the top/left cell. 0,0 means the cell is at the top left\n // Should be less than the width of the column\n topOffset: 0,\n leftOffset: 0,\n\n // current column/row that user is dragging\n draggingColumn: null,\n draggingRow: null,\n\n // Offset when dragging a row\n draggingRowOffset: null,\n\n // When drawing header separators for resizing\n draggingColumnSeparator: null,\n draggingRowSeparator: null,\n\n isDraggingHorizontalScrollBar: false,\n isDraggingVerticalScrollBar: false,\n\n // Anything is performing a drag, for blocking hover rendering\n isDragging: false,\n\n // The coordinates of the mouse. May be outside of the canvas\n mouseX: null,\n mouseY: null,\n\n // Move operations the user has performed on this grids columns/rows\n movedColumns,\n movedRows,\n\n // Cursor (highlighted cell) location and active selected range\n cursorRow: null,\n cursorColumn: null,\n selectionStartRow: null,\n selectionStartColumn: null,\n selectionEndRow: null,\n selectionEndColumn: null,\n\n // Currently selected ranges and previously selected ranges\n // Store the previously selected ranges to determine if the new selection should\n // deselect again (if it's the same range)\n selectedRanges: EMPTY_ARRAY,\n lastSelectedRanges: EMPTY_ARRAY,\n\n // The mouse cursor style to use when hovering over the grid element\n cursor: null,\n\n // { column: number, row: number, selectionRange: [number, number], value: string | null, isQuickEdit?: boolean }\n // The cell that is currently being edited\n editingCell: null,\n\n isStuckToBottom,\n isStuckToRight,\n };\n }\n\n componentDidMount(): void {\n this.initContext();\n\n // Need to explicitly add wheel event to canvas so we can preventDefault/avoid passive listener issue\n // Otherwise React attaches listener at doc level and you can't prevent default\n // https://github.com/facebook/react/issues/14856\n this.canvas?.addEventListener('wheel', this.handleWheel, {\n passive: false,\n });\n window.addEventListener('resize', this.handleResize);\n\n this.updateCanvas();\n\n // apply on mount, so that it works with a static model\n // https://github.com/deephaven/web-client-ui/issues/581\n const { isStuckToBottom, isStuckToRight } = this.props;\n if (isStuckToBottom) {\n this.scrollToBottom();\n }\n if (isStuckToRight) {\n this.scrollToRight();\n }\n }\n\n componentDidUpdate(prevProps: GridProps, prevState: GridState): void {\n const {\n isStickyBottom,\n isStickyRight,\n movedColumns,\n movedRows,\n onMovedColumnsChanged,\n onMoveColumnComplete,\n onMovedRowsChanged,\n onMoveRowComplete,\n } = this.props;\n\n const {\n isStickyBottom: prevIsStickyBottom,\n isStickyRight: prevIsStickyRight,\n movedColumns: prevPropMovedColumns,\n movedRows: prevPropMovedRows,\n } = prevProps;\n const {\n movedColumns: prevStateMovedColumns,\n movedRows: prevStateMovedRows,\n } = prevState;\n const {\n draggingColumn,\n draggingRow,\n movedColumns: currentStateMovedColumns,\n movedRows: currentStateMovedRows,\n } = this.state;\n\n if (prevPropMovedColumns !== movedColumns) {\n this.setState({ movedColumns });\n }\n\n if (prevPropMovedRows !== movedRows) {\n this.setState({ movedRows });\n }\n\n if (prevStateMovedColumns !== currentStateMovedColumns) {\n onMovedColumnsChanged(currentStateMovedColumns);\n }\n\n if (prevState.draggingColumn != null && draggingColumn == null) {\n onMoveColumnComplete(currentStateMovedColumns);\n }\n\n if (prevStateMovedRows !== currentStateMovedRows) {\n onMovedRowsChanged(currentStateMovedRows);\n }\n\n if (prevState.draggingRow != null && draggingRow == null) {\n onMoveRowComplete(currentStateMovedRows);\n }\n\n if (isStickyBottom !== prevIsStickyBottom) {\n this.setState({ isStuckToBottom: false });\n }\n\n if (isStickyRight !== prevIsStickyRight) {\n this.setState({ isStuckToRight: false });\n }\n\n this.updateMetrics();\n\n this.requestUpdateCanvas();\n\n this.checkStickyScroll();\n\n if (this.validateSelection()) {\n this.checkSelectionChange(prevState);\n }\n }\n\n componentWillUnmount(): void {\n if (this.animationFrame != null) {\n cancelAnimationFrame(this.animationFrame);\n }\n\n this.canvas?.removeEventListener('wheel', this.handleWheel);\n\n window.removeEventListener(\n 'mousemove',\n (this.handleMouseDrag as unknown) as EventListenerOrEventListenerObject,\n true\n );\n window.removeEventListener(\n 'mouseup',\n (this.handleMouseUp as unknown) as EventListenerOrEventListenerObject,\n true\n );\n window.removeEventListener('resize', this.handleResize);\n\n this.stopDragTimer();\n }\n\n getTheme(): GridThemeType {\n const { theme } = this.props;\n return Grid.getTheme(this.context, theme);\n }\n\n getGridPointFromEvent(event: GridMouseEvent): GridPoint {\n assertIsDefined(this.canvas);\n\n const rect = this.canvas.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n return this.getGridPointFromXY(x, y);\n }\n\n getGridPointFromXY(x: Coordinate, y: Coordinate): GridPoint {\n if (!this.metrics) throw new Error('metrics must be set');\n\n return GridUtils.getGridPointFromXY(x, y, this.metrics);\n }\n\n getMetricState(state = this.state): GridMetricState {\n const theme = this.getTheme();\n const { model, stateOverride } = this.props;\n if (!this.canvasContext || !this.canvas) {\n throw new Error('Canvas and context must be defined to get metrics');\n }\n const context = this.canvasContext;\n const width = this.canvas.clientWidth;\n const height = this.canvas.clientHeight;\n const {\n left,\n top,\n leftOffset,\n topOffset,\n movedColumns,\n movedRows,\n isDraggingHorizontalScrollBar,\n isDraggingVerticalScrollBar,\n draggingColumn,\n } = state;\n\n return {\n left,\n top,\n leftOffset,\n topOffset,\n width,\n height,\n context,\n theme,\n model,\n movedColumns,\n movedRows,\n isDraggingHorizontalScrollBar,\n isDraggingVerticalScrollBar,\n draggingColumn,\n ...stateOverride,\n };\n }\n\n getCachedKeyHandlers = memoize((keyHandlers: readonly KeyHandler[]) =>\n [...keyHandlers, ...this.keyHandlers].sort((a, b) => a.order - b.order)\n );\n\n getKeyHandlers(): readonly KeyHandler[] {\n const { keyHandlers } = this.props;\n return this.getCachedKeyHandlers(keyHandlers);\n }\n\n getCachedMouseHandlers = memoize(\n (mouseHandlers: readonly GridMouseHandler[]): readonly GridMouseHandler[] =>\n [...mouseHandlers, ...this.mouseHandlers].sort(\n (a, b) => a.order - b.order\n )\n );\n\n getMouseHandlers(): readonly GridMouseHandler[] {\n const { mouseHandlers } = this.props;\n return this.getCachedMouseHandlers(mouseHandlers);\n }\n\n /**\n * Translate from the provided visible index to the model index\n * @param columnIndex The column index to get the model for\n * @returns The model index\n */\n getModelColumn(columnIndex: VisibleIndex): ModelIndex {\n const modelIndex = this.metrics?.modelColumns?.get(columnIndex);\n if (modelIndex === undefined) {\n throw new Error(`Unable to get ModelIndex for column ${columnIndex}`);\n }\n return modelIndex;\n }\n\n /**\n * Translate from the provided visible index to the model index\n * @param rowIndex The row index to get the model for\n * @returns The model index\n */\n getModelRow(rowIndex: VisibleIndex): ModelIndex {\n const modelIndex = this.metrics?.modelRows?.get(rowIndex);\n if (modelIndex === undefined) {\n throw new Error(`Unable to get ModelIndex for row ${rowIndex}`);\n }\n return modelIndex;\n }\n\n /**\n * Toggle a row between expanded and collapsed states\n * @param row The row to toggle expansion for\n * @param expandDescendants True if nested rows should be expanded, false otherwise\n */\n toggleRowExpanded(row: VisibleIndex, expandDescendants = false): void {\n const modelRow = this.getModelRow(row);\n const { model } = this.props;\n // We only want to set expansion if the row is expandable\n // If it's not, still move the cursor to that position, as it may be outside of the current viewport and we don't know if it's expandable yet\n if (isExpandableGridModel(model) && model.isRowExpandable(modelRow)) {\n model.setRowExpanded(\n modelRow,\n !model.isRowExpanded(modelRow),\n expandDescendants\n );\n }\n this.clearSelectedRanges();\n this.commitSelection(); // Need to commit before moving in case we're selecting same row again\n this.moveCursorToPosition(0, row);\n this.commitSelection();\n\n this.setState({ isStuckToBottom: false });\n }\n\n /**\n * Scrolls to bottom, if not already at bottom\n */\n scrollToBottom(): void {\n if (!this.metrics) return;\n const { bottomVisible, rowCount, top, lastTop } = this.metrics;\n if ((bottomVisible < rowCount - 1 && bottomVisible > 0) || top > lastTop) {\n this.setState({ top: lastTop });\n }\n }\n\n /**\n * Scrolls to right, if not already at right\n */\n scrollToRight(): void {\n if (!this.metrics) return;\n const { rightVisible, columnCount, left, lastLeft } = this.metrics;\n if (\n (rightVisible < columnCount - 1 && rightVisible > 0) ||\n left > lastLeft\n ) {\n this.setState({ left: lastLeft });\n }\n }\n\n /**\n * Allows the selected ranges to be set programatically\n * Will update the cursor and selection start/end based on the new ranges\n * @param gridRanges The new selected ranges to set\n */\n setSelectedRanges(gridRanges: readonly GridRange[]): void {\n const { model } = this.props;\n const { columnCount, rowCount } = model;\n const { cursorRow, cursorColumn, selectedRanges } = this.state;\n this.setState({\n selectedRanges: gridRanges,\n lastSelectedRanges: selectedRanges,\n });\n if (gridRanges.length > 0) {\n const range = GridRange.boundedRange(\n gridRanges[0],\n columnCount,\n rowCount\n );\n let newCursorRow = cursorRow;\n let newCursorColumn = cursorColumn;\n if (!range.containsCell(cursorColumn, cursorRow)) {\n ({ row: newCursorRow, column: newCursorColumn } = range.startCell());\n }\n\n this.setState({\n selectionStartColumn: range.startColumn,\n selectionStartRow: range.startRow,\n selectionEndColumn: range.endColumn,\n selectionEndRow: range.endRow,\n cursorColumn: newCursorColumn,\n cursorRow: newCursorRow,\n });\n }\n }\n\n initContext(): void {\n const { canvas } = this;\n const { canvasOptions } = this.props;\n\n if (!canvas) throw new Error('Canvas not set');\n\n this.canvasContext = canvas.getContext('2d', canvasOptions);\n }\n\n requestUpdateCanvas(): void {\n if (this.animationFrame != null) {\n return;\n }\n\n this.animationFrame = requestAnimationFrame(() => {\n this.animationFrame = null;\n\n this.updateCanvas();\n });\n }\n\n updateCanvas(): void {\n this.updateCanvasScale();\n\n this.updateMetrics();\n\n this.updateRenderState();\n\n const { canvasContext, metrics, renderState } = this;\n assertNotNull(canvasContext);\n assertNotNull(metrics);\n assertNotNull(renderState);\n\n this.renderer.configureContext(canvasContext, renderState);\n\n const { onViewChanged } = this.props;\n onViewChanged(metrics);\n\n this.drawCanvas(metrics);\n }\n\n private updateCanvasScale(): void {\n const { canvas, canvasContext } = this;\n if (!canvas) throw new Error('canvas not set');\n if (!canvasContext) throw new Error('canvasContext not set');\n if (!canvas.parentElement) throw new Error('Canvas has no parent element');\n\n const scale = Grid.getScale(canvasContext);\n // the parent wrapper has 100% width/height, and is used for determining size\n // we don't want to stretch the canvas to 100%, to avoid fractional pixels.\n // A wrapper element must be used for sizing, and canvas size must be\n // set manually to a floored value in css and a scaled value in width/height\n const rect = canvas.parentElement.getBoundingClientRect();\n const width = Math.floor(rect.width);\n const height = Math.floor(rect.height);\n canvas.style.width = `${width}px`;\n canvas.style.height = `${height}px`;\n canvas.width = width * scale;\n canvas.height = height * scale;\n canvasContext.scale(scale, scale);\n }\n\n updateScrollBounds(): void {\n if (!this.metrics) throw new Error('metrics not set');\n const { left, top } = this.state;\n const { lastLeft, lastTop } = this.metrics;\n if (left > lastLeft) {\n this.setState({ left: lastLeft, leftOffset: 0 });\n }\n if (top > lastTop) {\n this.setState({ top: lastTop, topOffset: 0 });\n }\n }\n\n /**\n * Compares the current metrics with the previous metrics to see if we need to scroll when it is stuck to the bottom or the right\n */\n checkStickyScroll() {\n if (!this.metrics) {\n return;\n }\n\n if (this.prevMetrics) {\n const { rowCount, columnCount, height, width } = this.metrics;\n const {\n rowCount: prevRowCount,\n columnCount: prevColumnCount,\n height: prevHeight,\n width: prevWidth,\n } = this.prevMetrics;\n\n if (prevRowCount !== rowCount || height !== prevHeight) {\n const { isStuckToBottom } = this.state;\n if (isStuckToBottom) {\n this.scrollToBottom();\n }\n }\n\n if (prevColumnCount !== columnCount || width !== prevWidth) {\n const { isStuckToRight } = this.state;\n if (isStuckToRight) {\n this.scrollToRight();\n }\n }\n }\n this.prevMetrics = this.metrics;\n }\n\n updateMetrics(state = this.state): GridMetrics {\n this.prevMetrics = this.metrics;\n\n const { metricCalculator } = this;\n const metricState = this.getMetricState(state);\n this.metrics = metricCalculator.getMetrics(metricState);\n this.updateScrollBounds();\n\n return this.metrics;\n }\n\n /**\n * Check if the selection state has changed, and call the onSelectionChanged callback if they have\n * @param prevState The previous grid state\n */\n checkSelectionChange(prevState: GridState): void {\n const { selectedRanges: oldSelectedRanges } = prevState;\n const { selectedRanges } = this.state;\n\n if (selectedRanges !== oldSelectedRanges) {\n const { onSelectionChanged } = this.props;\n onSelectionChanged(selectedRanges);\n }\n }\n\n /**\n * Validate the current selection, and reset if it is invalid\n * @returns True if the selection is valid, false if the selection was invalid and has been reset\n */\n validateSelection(): boolean {\n const { model } = this.props;\n const { selectedRanges } = this.state;\n const { columnCount, rowCount } = model;\n\n for (let i = 0; i < selectedRanges.length; i += 1) {\n const range = selectedRanges[i];\n if (\n (range.endColumn != null && range.endColumn >= columnCount) ||\n (range.endRow != null && range.endRow >= rowCount)\n ) {\n // Just clear the selection rather than trying to trim it.\n this.setState({ selectedRanges: [], lastSelectedRanges: [] });\n return false;\n }\n }\n return true;\n }\n\n /**\n * Clears all selected ranges\n */\n clearSelectedRanges(): void {\n const { selectedRanges } = this.state;\n this.setState({ selectedRanges: [], lastSelectedRanges: selectedRanges });\n }\n\n /** Clears all but the last selected range */\n trimSelectedRanges(): void {\n const { selectedRanges } = this.state;\n if (selectedRanges.length > 0) {\n this.setState({\n selectedRanges: selectedRanges.slice(selectedRanges.length - 1),\n });\n }\n }\n\n /**\n * Begin a selection operation at the provided location\n * @param column Column where the selection is beginning\n * @param row Row where the selection is beginning\n */\n beginSelection(column: GridRangeIndex, row: GridRangeIndex): void {\n this.setState({\n selectionStartColumn: column,\n selectionStartRow: row,\n selectionEndColumn: column,\n selectionEndRow: row,\n cursorColumn: column,\n cursorRow: row,\n });\n }\n\n /**\n * Moves the selection to the cell specified\n * @param column The column index to move the cursor to\n * @param row The row index to move the cursor to\n * @param extendSelection Whether to extend the current selection (eg. holding Shift)\n * @param maximizePreviousRange When true, maximize/add to the previous range only, ignoring where the selection was started.\n */\n moveSelection(\n column: GridRangeIndex,\n row: GridRangeIndex,\n extendSelection = false,\n maximizePreviousRange = false\n ): void {\n this.setState(state => {\n const { selectedRanges, selectionStartRow, selectionStartColumn } = state;\n const { theme } = this.props;\n const { autoSelectRow, autoSelectColumn } = theme;\n\n if (extendSelection && selectedRanges.length > 0) {\n const lastSelectedRange = selectedRanges[selectedRanges.length - 1];\n let left = null;\n let top = null;\n let right = null;\n let bottom = null;\n if (maximizePreviousRange) {\n left =\n autoSelectRow !== undefined && autoSelectRow\n ? null\n : Math.min(column ?? 0, lastSelectedRange.startColumn ?? 0);\n top =\n autoSelectColumn !== undefined && autoSelectColumn\n ? null\n : Math.min(row ?? 0, lastSelectedRange.startRow ?? 0);\n right =\n autoSelectRow !== undefined && autoSelectRow\n ? null\n : Math.max(column ?? 0, lastSelectedRange.endColumn ?? 0);\n bottom =\n autoSelectColumn !== undefined && autoSelectColumn\n ? null\n : Math.max(row ?? 0, lastSelectedRange.endRow ?? 0);\n } else {\n left = lastSelectedRange.startColumn;\n top = lastSelectedRange.startRow;\n\n if (selectionStartColumn != null || selectionStartRow != null) {\n if (autoSelectRow === undefined || !autoSelectRow) {\n left = selectionStartColumn;\n }\n if (autoSelectColumn === undefined || !autoSelectColumn) {\n top = selectionStartRow;\n }\n }\n right = autoSelectRow !== undefined && autoSelectRow ? null : column;\n bottom =\n autoSelectColumn !== undefined && autoSelectColumn ? null : row;\n }\n const selectedRange = GridRange.makeNormalized(\n left,\n top,\n right,\n bottom\n );\n\n if (lastSelectedRange.equals(selectedRange)) {\n return null;\n }\n\n const newRanges = [...selectedRanges];\n newRanges[newRanges.length - 1] = selectedRange;\n return {\n selectedRanges: newRanges,\n selectionEndColumn: column,\n selectionEndRow: row,\n };\n }\n const newRanges = [...selectedRanges];\n const selectedColumn =\n autoSelectRow !== undefined && autoSelectRow ? null : column;\n const selectedRow =\n autoSelectColumn !== undefined && autoSelectColumn ? null : row;\n\n newRanges.push(\n GridRange.makeNormalized(\n selectedColumn,\n selectedRow,\n selectedColumn,\n selectedRow\n )\n );\n return {\n selectedRanges: newRanges,\n selectionEndColumn: column,\n selectionEndRow: row,\n };\n });\n }\n\n /**\n * Commits the last selected range to the selected ranges.\n * First checks if the last range is completely contained within another range, and if it\n * is then it blows those ranges apart.\n * Then it consolidates all the selected ranges, reducing them.\n */\n commitSelection(): void {\n this.setState((state: GridState) => {\n const { theme } = this.props;\n const { autoSelectRow } = theme;\n const {\n selectedRanges,\n lastSelectedRanges,\n cursorRow,\n cursorColumn,\n } = state;\n\n if (\n selectedRanges.length === 1 &&\n (autoSelectRow !== undefined && autoSelectRow\n ? GridRange.rowCount(selectedRanges) === 1\n : GridRange.cellCount(selectedRanges) === 1) &&\n GridRange.rangeArraysEqual(selectedRanges, lastSelectedRanges)\n ) {\n // If it's the exact same single selection, then deselect.\n // For if we click on one cell multiple times.\n return {\n selectedRanges: [],\n lastSelectedRanges: [],\n cursorColumn: null,\n cursorRow: null,\n };\n }\n\n let newSelectedRanges = selectedRanges.slice();\n if (newSelectedRanges.length > 1) {\n // Check if the latest selection is entirely within a previously selected range\n // If that's the case, then deselect that section instead\n const lastRange = newSelectedRanges[newSelectedRanges.length - 1];\n for (let i = 0; i < newSelectedRanges.length - 1; i += 1) {\n const selectedRange = newSelectedRanges[i];\n if (selectedRange.contains(lastRange)) {\n // We found a match, now remove the two matching ranges, and add back\n // the remainder of the two\n const remainder = selectedRange.subtract(lastRange);\n newSelectedRanges.pop();\n newSelectedRanges.splice(i, 1);\n newSelectedRanges = newSelectedRanges.concat(remainder);\n break;\n }\n }\n\n newSelectedRanges = GridRange.consolidate(newSelectedRanges);\n }\n\n let newCursorColumn = cursorColumn;\n let newCursorRow = cursorRow;\n if (!GridRange.containsCell(newSelectedRanges, cursorColumn, cursorRow)) {\n const { model } = this.props;\n const { columnCount, rowCount } = model;\n const nextCursor = GridRange.nextCell(\n GridRange.boundedRanges(selectedRanges, columnCount, rowCount)\n );\n if (nextCursor != null) {\n ({ column: newCursorColumn, row: newCursorRow } = nextCursor);\n } else {\n newCursorColumn = null;\n newCursorRow = null;\n }\n }\n\n if (newSelectedRanges.length === 0) {\n newCursorColumn = null;\n newCursorRow = null;\n }\n\n return {\n cursorRow: newCursorRow,\n cursorColumn: newCursorColumn,\n selectedRanges: newSelectedRanges,\n lastSelectedRanges: selectedRanges,\n };\n });\n }\n\n setFocusRow(focusedRow: number): void {\n if (!this.metrics || !this.prevMetrics) {\n return;\n }\n\n const { gridY, height, lastTop, userRowHeights, rowHeight } = this.metrics;\n\n const tableHeight = height - gridY;\n\n const halfViewportHeight =\n Math.round(tableHeight / 2) +\n (userRowHeights.get(focusedRow) ?? rowHeight);\n\n const metricState = this.getMetricState();\n const newTop = this.metricCalculator.getLastTop(\n metricState,\n focusedRow + 1,\n halfViewportHeight\n );\n this.setState({\n top: Math.min(lastTop, newTop),\n selectedRanges: [new GridRange(null, focusedRow, null, focusedRow)],\n isStuckToBottom: false,\n });\n const { cursorColumn } = this.state;\n this.moveCursorToPosition(cursorColumn, focusedRow, false, false);\n }\n\n /**\n * Set the selection to the entire grid\n */\n selectAll(): void {\n const { model, theme } = this.props;\n const { autoSelectRow, autoSelectColumn } = theme;\n\n const top = autoSelectColumn !== undefined && autoSelectColumn ? null : 0;\n const bottom =\n autoSelectColumn !== undefined && autoSelectColumn\n ? null\n : model.rowCount - 1;\n const left = autoSelectRow !== undefined && autoSelectRow ? null : 0;\n const right =\n autoSelectRow !== undefined && autoSelectRow\n ? null\n : model.columnCount - 1;\n this.setSelectedRanges([new GridRange(left, top, right, bottom)]);\n }\n\n /**\n * Move the cursor in relation to the current cursor position\n * @param deltaColumn Number of columns to move the cursor\n * @param deltaRow Number of rows to move the cursor\n * @param extendSelection True if the current selection should be extended, false to start a new selection\n */\n moveCursor(\n deltaColumn: number,\n deltaRow: number,\n extendSelection: boolean\n ): void {\n const {\n cursorRow,\n cursorColumn,\n selectionEndColumn,\n selectionEndRow,\n } = this.state;\n const column = extendSelection ? selectionEndColumn : cursorColumn;\n const row = extendSelection ? selectionEndRow : cursorRow;\n if (row === null || column === null) {\n const { left, top } = this.state;\n this.moveCursorToPosition(left, top, extendSelection);\n } else {\n const { model } = this.props;\n const { columnCount, rowCount } = model;\n\n const left = clamp(column + deltaColumn, 0, columnCount - 1);\n const top = clamp(row + deltaRow, 0, rowCount - 1);\n this.moveCursorToPosition(left, top, extendSelection);\n }\n }\n\n /**\n * Move the cursor in the provided selection direction\n * @param direction The direction to move the cursor in\n */\n moveCursorInDirection(direction = GridRange.SELECTION_DIRECTION.DOWN): void {\n const { model } = this.props;\n const { columnCount, rowCount } = model;\n const { cursorRow, cursorColumn, selectedRanges } = this.state;\n const ranges =\n selectedRanges.length > 0\n ? selectedRanges\n : [GridRange.makeCell(cursorColumn, cursorRow)];\n let nextCursor = null;\n if (ranges.length === 1 && GridRange.cellCount(ranges) === 1) {\n // If we only have one cell selected, we want to update the cursor and we want to update the selected cells\n const gridRange = new GridRange(0, 0, columnCount - 1, rowCount - 1);\n nextCursor =\n gridRange.nextCell(cursorColumn, cursorRow, direction) ??\n gridRange.startCell(direction);\n } else {\n nextCursor = GridRange.nextCell(\n GridRange.boundedRanges(ranges, columnCount, rowCount),\n cursorColumn,\n cursorRow,\n direction\n );\n }\n\n if (nextCursor != null) {\n const { column, row } = nextCursor;\n this.setState({\n cursorColumn: column,\n cursorRow: row,\n });\n\n if (!GridRange.containsCell(selectedRanges, column, row)) {\n this.setState({\n selectedRanges: [GridRange.makeCell(column, row)],\n selectionStartColumn: column,\n selectionStartRow: row,\n selectionEndColumn: column,\n selectionEndRow: row,\n });\n }\n\n this.moveViewToCell(nextCursor.column, nextCursor.row);\n }\n }\n\n /**\n * Move a cursor to the specified position in the grid.\n * @param column The column index to move the cursor to\n * @param row The row index to move the cursor to\n * @param extendSelection Whether to extend the current selection (eg. holding Shift)\n * @param keepCursorInView Whether to move the viewport so that the cursor is in view\n * @param maximizePreviousRange With this and `extendSelection` true, it will maximize/add to the previous range only, ignoring where the selection was started\n */\n moveCursorToPosition(\n column: GridRangeIndex,\n row: GridRangeIndex,\n extendSelection = false,\n keepCursorInView = true,\n maximizePreviousRange = false\n ): void {\n if (!extendSelection) {\n this.beginSelection(column, row);\n }\n\n this.moveSelection(column, row, extendSelection, maximizePreviousRange);\n\n if (keepCursorInView) {\n this.moveViewToCell(column, row);\n }\n }\n\n /**\n * Moves the view to make the specified cell visible\n *\n * @param column The column index to bring into view\n * @param row The row index to bring into view\n */\n moveViewToCell(column: GridRangeIndex, row: GridRangeIndex): void {\n if (!this.metrics) throw new Error('metrics not set');\n\n const { metricCalculator } = this;\n const {\n bottomVisible,\n rightVisible,\n topVisible,\n leftVisible,\n } = this.metrics;\n const metricState = this.getMetricState(this.state);\n let { top, left, topOffset, leftOffset } = this.state;\n\n if (row != null && !GridUtils.isFloatingRow(row, this.metrics)) {\n if (row < topVisible) {\n top = metricCalculator.getTopForTopVisible(metricState, row);\n topOffset = 0;\n } else if (row > bottomVisible) {\n top = metricCalculator.getTopForBottomVisible(metricState, row);\n topOffset = 0;\n }\n }\n\n if (column != null && !GridUtils.isFloatingColumn(column, this.metrics)) {\n if (column < leftVisible) {\n left = metricCalculator.getLeftForLeftVisible(metricState, column);\n leftOffset = 0;\n } else if (column > rightVisible) {\n left = metricCalculator.getLeftForRightVisible(metricState, column);\n leftOffset = 0;\n }\n }\n\n this.setViewState({ top, left, topOffset, leftOffset });\n }\n\n /**\n * Checks the `top` and `left` properties that are set and updates the isStuckToBottom/Right properties\n * Should be called when user interaction occurs\n * @param viewState New state properties to set.\n * @param forceUpdate Whether to force an update.\n */\n setViewState(viewState: Partial<GridState>, forceUpdate = false): void {\n if (!this.metrics) throw new Error('metrics not set');\n\n const { isStickyBottom, isStickyRight } = this.props;\n const { top, left } = viewState;\n const { lastTop, lastLeft } = this.metrics;\n if (top != null) {\n this.setState({ isStuckToBottom: isStickyBottom && top >= lastTop });\n }\n if (left != null) {\n this.setState({ isStuckToRight: isStickyRight && left >= lastLeft });\n }\n\n this.setState(viewState as GridState);\n if (forceUpdate) {\n this.forceUpdate();\n }\n }\n\n /**\n * Start editing the data at the given index\n *\n * @param column The visible column index to start editing\n * @param row The visible row index to start editing\n * @param isQuickEdit If this is a quick edit (the arrow keys can commit)\n * @param selectionRange The tuple [start,end] text selection range of the value to select when editing\n * @param value The value to start with in the edit field. Leave undefined to use the current value.\n */\n startEditing(\n column: VisibleIndex,\n row: VisibleIndex,\n isQuickEdit = false,\n selectionRange?: EditingCellTextSelectionRange,\n value?: string\n ): void {\n const { model } = this.props;\n if (!isEditableGridModel(model)) throw new Error('model is not editable');\n\n const modelColumn = this.getModelColumn(column);\n const modelRow = this.getModelRow(row);\n const cell = {\n column,\n row,\n selectionRange,\n value:\n value !== undefined\n ? value\n : model.editValueForCell(modelColumn, modelRow),\n isQuickEdit,\n };\n\n this.setState({ editingCell: cell, cursorColumn: column, cursorRow: row });\n this.moveViewToCell(column, row);\n }\n\n /**\n * Check if a value is valid for a specific cell\n * @param column Column index of the cell to check\n * @param row Row index of the cell to check\n * @param value Value to check\n * @returns True if the value is valid for the provided cell, false otherwise\n */\n isValidForCell(\n column: VisibleIndex,\n row: VisibleIndex,\n value: string\n ): boolean {\n const { model } = this.props;\n\n const modelColumn = this.getModelColumn(column);\n const modelRow = this.getModelRow(row);\n return (\n isEditableGridModel(model) &&\n model.isValidForCell(modelColumn, modelRow, value)\n );\n }\n\n /**\n * Paste a value with the current selection\n * It first needs to validate that the pasted table is valid for the given selection.\n * Also may update selection if single cells are selected and a table is pasted.\n * @param value Table or a string that is being pasted\n */\n async pasteValue(value: string[][] | string): Promise<void> {\n const { model } = this.props;\n const { movedColumns, movedRows, selectedRanges } = this.state;\n\n try {\n assertIsEditableGridModel(model);\n\n if (\n !model.isEditable ||\n !selectedRanges.every(range => model.isEditableRange(range))\n ) {\n throw new PasteError(\"Can't paste in to read-only area.\");\n }\n\n if (selectedRanges.length <= 0) {\n throw new PasteError('Select an area to paste to.');\n }\n\n if (typeof value === 'string') {\n // Just paste the value into all the selected cells\n const edits: EditOperation[] = [];\n\n const modelRanges = GridUtils.getModelRanges(\n selectedRanges,\n movedColumns,\n movedRows\n );\n GridRange.forEachCell(modelRanges, (column, row) => {\n edits.push({ column, row, text: value });\n });\n await model.setValues(edits);\n return;\n }\n\n // Otherwise it's a table of data\n const tableHeight = value.length;\n const tableWidth = value[0].length;\n const { columnCount, rowCount } = model;\n let ranges = selectedRanges;\n // If each cell is a single selection, we need to update the selection to map to the newly pasted data\n if (\n ranges.every(\n range =>\n GridRange.cellCount([range]) === 1 &&\n (range.startColumn ?? 0) + tableWidth <= columnCount &&\n (range.startRow ?? 0) + tableHeight <= rowCount\n )\n ) {\n // Remap the selected ranges\n ranges = ranges.map(\n range =>\n new GridRange(\n range.startColumn,\n range.startRow,\n (range.startColumn ?? 0) + tableWidth - 1,\n (range.startRow ?? 0) + tableHeight - 1\n )\n );\n this.setSelectedRanges(ranges);\n }\n\n if (\n !ranges.every(\n range =>\n GridRange.rowCount([range]) === tableHeight &&\n GridRange.columnCount([range]) === tableWidth\n )\n ) {\n throw new PasteError('Copy and paste area are not same size.');\n }\n\n const edits: EditOperation[] = [];\n ranges.forEach(range => {\n for (let x = 0; x < tableWidth; x += 1) {\n for (let y = 0; y < tableHeight; y += 1) {\n edits.push({\n column: (range.startColumn ?? 0) + x,\n row: (range.startRow ?? 0) + y,\n text: value[y][x],\n });\n }\n }\n });\n await model.setValues(edits);\n } catch (e) {\n const { onError } = this.props;\n onError(e instanceof Error ? e : new Error(`${e}`));\n }\n }\n\n /**\n * Set a value to a specific cell. If the value is not valid for that cell, do not set it\n * @param column Column index to set the value for\n * @param row Row index to set the value for\n * @param value Value to set at that cell\n * @returns true If the value was valid and attempted to be set, false is it was not valid\n */\n setValueForCell(\n column: VisibleIndex,\n row: VisibleIndex,\n value: string\n ): boolean {\n const { model } = this.props;\n assertIsEditableGridModel(model);\n\n const modelColumn = this.getModelColumn(column);\n const modelRow = this.getModelRow(row);\n if (model.isValidForCell(modelColumn, modelRow, value)) {\n model.setValueForCell(modelColumn, modelRow, value);\n return true;\n }\n return false;\n }\n\n /**\n * Set a value on all the ranges provided\n * @param ranges Ranges to set\n * @param value The value to set on all the ranges\n */\n setValueForRanges(ranges: readonly GridRange[], value: string): void {\n const { model } = this.props;\n const { movedColumns, movedRows } = this.state;\n\n const modelRanges = GridUtils.getModelRanges(\n ranges,\n movedColumns,\n movedRows\n );\n if (isEditableGridModel(model)) {\n model.setValueForRanges(modelRanges, value);\n }\n }\n\n /**\n * Check if a given cell is within the current selection\n * @param row Row to check\n * @param column Column to check\n * @returns True if the cell is in the current selection, false otherwise\n */\n isSelected(row: VisibleIndex, column: VisibleIndex): boolean {\n const { selectedRanges } = this.state;\n\n for (let i = 0; i < selectedRanges.length; i += 1) {\n const selectedRange = selectedRanges[i];\n const rowSelected =\n selectedRange.startRow === null ||\n (selectedRange.startRow <= row && row <= (selectedRange.endRow ?? 0));\n const columnSelected =\n selectedRange.startColumn === null ||\n (selectedRange.startColumn <= column &&\n column <= (selectedRange.endColumn ?? 0));\n if (rowSelected && columnSelected) {\n return true;\n }\n }\n\n return false;\n }\n\n addDocumentCursor(cursor: string | null = null): void {\n if (this.documentCursor === Grid.getCursorClassName(cursor)) return;\n if (this.documentCursor != null) {\n document.documentElement.classList.remove(this.documentCursor);\n }\n this.documentCursor = Grid.getCursorClassName(cursor);\n if (this.documentCursor != null) {\n document.documentElement.classList.add(this.documentCursor);\n }\n document.documentElement.classList.add('grid-block-events');\n }\n\n removeDocumentCursor(): void {\n if (this.documentCursor != null) {\n document.documentElement.classList.remove(this.documentCursor);\n document.documentElement.classList.remove('grid-block-events');\n this.documentCursor = null;\n }\n }\n\n startDragTimer(event: React.MouseEvent): void {\n this.stopDragTimer();\n\n const mouseEvent = new MouseEvent('custom', event.nativeEvent);\n\n this.dragTimer = setTimeout(() => {\n this.handleMouseDrag(mouseEvent);\n }, Grid.dragTimeout);\n }\n\n stopDragTimer(): void {\n if (this.dragTimer) {\n clearTimeout(this.dragTimer);\n this.dragTimer = null;\n }\n }\n\n /**\n * Draw the grid with the metrics provided\n * When scrolling you've have to re-draw the whole canvas. As a consequence, all these drawing methods\n * must be very quick.\n * @param metrics Metrics to use for rendering the grid\n */\n private drawCanvas(metrics = this.updateMetrics()): void {\n if (!this.canvas) throw new Error('canvas is not set');\n if (!this.canvasContext) throw new Error('context not set');\n\n const { renderer, canvasContext: context, renderState } = this;\n\n context.save();\n\n renderer.drawCanvas(renderState);\n\n context.restore();\n }\n\n /**\n * Set focus to this grid element\n */\n focus(): void {\n this.canvas?.focus();\n }\n\n /**\n * Check if this grid is currently focused\n * @returns True if the active element is this grid\n */\n isFocused(): boolean {\n return document.activeElement === this.canvas;\n }\n\n /**\n * Handle a mouse click event. Pass the event to the registered mouse handlers until one handles it.\n * Focuses the grid after the click.\n * @param event The mouse event\n */\n handleClick(event: React.MouseEvent): void {\n const gridPoint = this.getGridPointFromEvent(event);\n\n const mouseHandlers = this.getMouseHandlers();\n for (let i = 0; i < mouseHandlers.length; i += 1) {\n const mouseHandler = mouseHandlers[i];\n if (mouseHandler.onClick(gridPoint, this, event) !== false) {\n event.stopPropagation();\n event.preventDefault();\n break;\n }\n }\n\n this.canvas?.focus();\n }\n\n /**\n * Handle a mouse context menu event. Pass the event to the registered mouse handlers until one handles it.\n * @param event The mouse event triggering the context menu\n */\n handleContextMenu(event: React.MouseEvent): void {\n const gridPoint = this.getGridPointFromEvent(event);\n\n const mouseHandlers = this.getMouseHandlers();\n for (let i = 0; i < mouseHandlers.length; i += 1) {\n const mouseHandler = mouseHandlers[i];\n if (mouseHandler.onContextMenu(gridPoint, this, event) !== false) {\n event.stopPropagation();\n event.preventDefault();\n break;\n }\n }\n }\n\n /**\n * Handle a key down event from the keyboard. Pass the event to the registered keyboard handlers until one handles it.\n * @param event Keyboard event\n */\n handleKeyDown(event: GridKeyboardEvent): void {\n const keyHandlers = this.getKeyHandlers();\n for (let i = 0; i < keyHandlers.length; i += 1) {\n const keyHandler = keyHandlers[i];\n const result = keyHandler.onDown(event, this);\n if (result !== false) {\n const options = result as EventHandlerResultOptions;\n if (options?.stopPropagation ?? true) event.stopPropagation();\n if (options?.preventDefault ?? true) event.preventDefault();\n break;\n }\n }\n }\n\n /**\n * Notify all of the mouse handlers for this grid of a mouse event.\n * @param functionName The name of the function in the mouse handler to call\n * @param event The mouse event to notify\n * @param updateCoordinates Whether to update the mouse coordinates\n * @param addCursorToDocument Whether to add a cursor overlay or not (for dragging)\n */\n notifyMouseHandlers(\n functionName: GridMouseHandlerFunctionName,\n event: GridMouseEvent,\n updateCoordinates = true,\n addCursorToDocument = false\n ): void {\n const gridPoint = this.getGridPointFromEvent(event);\n const mouseHandlers = this.getMouseHandlers();\n let cursor = null;\n for (let i = 0; i < mouseHandlers.length; i += 1) {\n const mouseHandler = mouseHandlers[i];\n const result =\n mouseHandler[functionName] != null &&\n mouseHandler[functionName](gridPoint, this, event);\n if (result !== false) {\n if (mouseHandler.cursor != null) {\n ({ cursor } = mouseHandler);\n if (addCursorToDocument) {\n this.addDocumentCursor(cursor);\n }\n }\n\n // result is bool or object, events are stopped by default\n const options = result as EventHandlerResultOptions;\n if (options?.stopPropagation ?? true) event.stopPropagation();\n if (options?.preventDefault ?? true) event.preventDefault();\n break;\n }\n }\n\n this.setState({ cursor });\n\n if (updateCoordinates) {\n const { x, y } = gridPoint;\n this.setState({ mouseX: x, mouseY: y });\n }\n }\n\n handleMouseDown(event: React.MouseEvent): void {\n window.addEventListener('mousemove', this.handleMouseDrag, true);\n window.addEventListener('mouseup', this.handleMouseUp, true);\n\n if (event.button != null && event.button !== 0) {\n return;\n }\n\n this.notifyMouseHandlers('onDown', event);\n\n this.startDragTimer(event);\n }\n\n handleDoubleClick(event: React.MouseEvent): void {\n this.notifyMouseHandlers('onDoubleClick', event);\n }\n\n handleMouseMove(event: React.MouseEvent): void {\n this.notifyMouseHandlers('onMove', event);\n }\n\n handleMouseLeave(event: React.MouseEvent): void {\n this.notifyMouseHandlers('onLeave', event, false);\n this.setState({ mouseX: null, mouseY: null });\n }\n\n handleMouseDrag(event: MouseEvent): void {\n this.setState({ isDragging: true });\n this.notifyMouseHandlers('onDrag', event, true, true);\n\n this.stopDragTimer();\n }\n\n handleMouseUp(event: MouseEvent): void {\n window.removeEventListener('mousemove', this.handleMouseDrag, true);\n window.removeEventListener('mouseup', this.handleMouseUp, true);\n\n if (event.button != null && event.button !== 0) {\n return;\n }\n\n this.notifyMouseHandlers('onUp', event, false);\n\n this.stopDragTimer();\n\n this.removeDocumentCursor();\n }\n\n handleResize(): void {\n /**\n * We need to always redraw the canvas in the same frame as the updateCanvasScale\n * because it clears the canvas by nature of direct dom manipulation. However,\n * We also need to verify the state/metrics, which we currently have no way\n * of doing outside of a full componentDidUpdate() call, so we force the update.\n * Ideally, we could verify state/metrics without the forced update.\n */\n this.updateCanvas();\n\n if (!this.metrics) throw new Error('metrics not set');\n\n this.forceUpdate();\n }\n\n handleWheel(event: WheelEvent): void {\n this.notifyMouseHandlers('onWheel', event);\n\n if (event.defaultPrevented) {\n return;\n }\n\n const { metricCalculator, metrics } = this;\n const metricState = this.getMetricState();\n\n if (!metrics) throw new Error('metrics not set');\n\n const {\n lastTop,\n lastLeft,\n columnCount,\n rowCount,\n scrollableContentWidth,\n scrollableViewportWidth,\n scrollableContentHeight,\n scrollableViewportHeight,\n hasHorizontalBar,\n hasVerticalBar,\n } = metrics;\n let { top, left, topOffset, leftOffset } = metrics;\n\n const theme = this.getTheme();\n\n let { deltaX, deltaY } = GridUtils.getScrollDelta(\n event,\n metrics.barWidth,\n metrics.barHeight,\n metrics.rowHeight,\n metrics.rowHeight\n );\n\n // iterate through each column to determine column width and figure out how far to scroll\n // get column width of next column to scroll to, and subract it from the remaining distance to travel\n while (hasHorizontalBar && deltaX !== 0) {\n leftOffset += deltaX;\n deltaX = 0;\n\n if (columnCount > 1) {\n // no scrolling needed, at directional edge\n if (\n (leftOffset > 0 && left >= lastLeft) ||\n (leftOffset < 0 && left <= 0)\n ) {\n leftOffset = 0;\n break;\n }\n } else {\n // single column at edge\n if (leftOffset <= 0) {\n leftOffset = 0;\n break;\n }\n\n const maxLeftOffset = scrollableContentWidth - scrollableViewportWidth;\n if (leftOffset >= maxLeftOffset) {\n leftOffset = maxLeftOffset;\n break;\n }\n }\n\n if (leftOffset > 0) {\n // scroll right\n\n // get width of next column\n const columnWidth =\n metrics.allColumnWidths.get(left) ??\n metricCalculator.getVisibleColumnWidth(left, metricState);\n\n if (leftOffset >= columnWidth) {\n // remove width from balance and advance by 1 column\n deltaX = leftOffset - columnWidth;\n leftOffset = 0;\n left += 1;\n } else if (theme.scrollSnapToColumn && columnCount > 1) {\n // if there's still a balance to travel but its less then a column and snapping is on\n leftOffset = 0;\n left += 1;\n }\n } else if (leftOffset < 0) {\n // scroll left\n\n // get width of next column\n const columnWidth =\n metrics.allColumnWidths.get(left - 1) ??\n metricCalculator.getVisibleColumnWidth(left - 1, metricState);\n\n if (\n Math.abs(leftOffset) <= columnWidth &&\n theme.scrollSnapToColumn &&\n columnCount > 1\n ) {\n // if there's still a balance to travel but its less then a column and snapping is on\n leftOffset = 0;\n left -= 1;\n } else {\n // remove width from balance and advance by 1 column\n deltaX = leftOffset + columnWidth;\n leftOffset = 0;\n left -= 1;\n }\n }\n }\n\n // iterate through each row to determine row height and figure out how far to scroll\n // get row height of next row to scroll to, and subract it from the remaining distance to travel\n while (hasVerticalBar && deltaY !== 0) {\n topOffset += deltaY;\n deltaY = 0;\n\n if (rowCount > 1) {\n // no scrolling needed, at directional edge\n if ((topOffset > 0 && top >= lastTop) || (topOffset < 0 && top <= 0)) {\n topOffset = 0;\n break;\n }\n } else {\n // single row at edge\n if (topOffset <= 0) {\n topOffset = 0;\n break;\n }\n\n const maxTopOffset = scrollableContentHeight - scrollableViewportHeight;\n if (topOffset >= maxTopOffset) {\n topOffset = maxTopOffset;\n break;\n }\n }\n\n if (topOffset > 0) {\n // scroll direction down\n\n // get height of next row\n const rowHeight =\n metrics.allRowHeights.get(top) ??\n metricCalculator.getVisibleRowHeight(top, metricState);\n\n if (topOffset >= rowHeight) {\n // remove height from balance and advance by 1 row\n deltaY = topOffset - rowHeight;\n topOffset = 0;\n top += 1;\n } else if (theme.scrollSnapToRow && rowCount > 1) {\n // if there's still a balance to travel but its less then a row and snapping is on\n topOffset = 0;\n top += 1;\n }\n } else if (topOffset < 0) {\n // scroll direction up\n\n // get height of next row\n const rowHeight =\n metrics.allRowHeights.get(top - 1) ??\n metricCalculator.getVisibleRowHeight(top - 1, metricState);\n\n if (\n Math.abs(topOffset) <= rowHeight &&\n theme.scrollSnapToRow &&\n rowCount > 1\n ) {\n // if there's still a balance to travel but its less then a row and snapping is on\n topOffset = 0;\n top -= 1;\n } else {\n // remove height from balance and advance by 1 row\n deltaY = topOffset + rowHeight;\n topOffset = 0;\n top -= 1;\n }\n }\n }\n\n this.setViewState({ top, left, leftOffset, topOffset });\n\n event.stopPropagation();\n event.preventDefault();\n }\n\n /**\n * Handle cancelling the cell edit action\n */\n handleEditCellCancel(): void {\n this.setState({ editingCell: null });\n this.focus();\n }\n\n /**\n * Handle a change in the value in an editing cell\n * @param value New value set\n */\n handleEditCellChange(value: string): void {\n this.setState(({ editingCell }) => {\n try {\n assertIsDefined(editingCell);\n\n return {\n editingCell: { ...editingCell, value } as EditingCell,\n };\n } catch (e) {\n // This case should _never_ happen, since the editingCell shouldn't be null if this method is called\n const { onError } = this.props;\n onError(e instanceof Error ? e : new Error(`${e}`));\n return null;\n }\n });\n }\n\n /**\n * Commit an edit for the currently editing cell\n * @param value Value that was committed\n * @param options Options for committing\n */\n handleEditCellCommit(\n value: string,\n {\n direction = SELECTION_DIRECTION.DOWN,\n fillRange = false,\n }: { direction?: SELECTION_DIRECTION | null; fillRange?: boolean } = {}\n ): void {\n const { editingCell, selectedRanges } = this.state;\n if (!editingCell) throw new Error('editingCell not set');\n\n const { column, row } = editingCell;\n if (!this.isValidForCell(column, row, value)) {\n // Don't allow an invalid value to be commited, the editing cell should show an error\n if (direction === null) {\n // If they clicked off of the editing cell, just remove focus\n this.setState({ editingCell: null });\n }\n return;\n }\n\n if (fillRange) {\n this.setValueForRanges(selectedRanges, value);\n } else {\n this.setValueForCell(column, row, value);\n }\n\n if (direction !== null) {\n this.moveCursorInDirection(direction);\n }\n\n this.setState({ editingCell: null });\n\n this.focus();\n }\n\n renderInputField(): ReactNode {\n const { model } = this.props;\n const { editingCell } = this.state;\n const { metrics } = this;\n if (editingCell == null || metrics == null || !isEditableGridModel(model)) {\n return null;\n }\n const { selectionRange, value, isQuickEdit } = editingCell;\n const { column, row } = editingCell;\n const {\n gridX,\n gridY,\n allColumnXs,\n allRowYs,\n allColumnWidths,\n allRowHeights,\n } = metrics;\n\n const x = allColumnXs.get(column);\n const y = allRowYs.get(row);\n const w = allColumnWidths.get(column);\n const h = allRowHeights.get(row);\n\n // If the cell isn't visible, we still need to display an invisible cell for focus purposes\n const wrapperStyle: CSSProperties =\n x != null && y != null && w != null && h != null\n ? {\n position: 'absolute',\n left: gridX + x,\n top: gridY + y,\n width: w,\n height: h,\n }\n : { opacity: 0 };\n\n const modelColumn = this.getModelColumn(column);\n const modelRow = this.getModelRow(row);\n const inputStyle: CSSProperties | undefined =\n modelColumn != null && modelRow != null\n ? {\n textAlign: model.textAlignForCell(modelColumn, modelRow),\n }\n : undefined;\n const isValid = model.isValidForCell(modelColumn, modelRow, value);\n\n return (\n <div style={wrapperStyle}>\n <CellInputField\n key={`${column},${row}`}\n selectionRange={selectionRange}\n className={classNames({ error: !isValid })}\n onCancel={this.handleEditCellCancel}\n onChange={this.handleEditCellChange}\n onDone={this.handleEditCellCommit}\n isQuickEdit={isQuickEdit}\n style={inputStyle}\n value={value}\n />\n </div>\n );\n }\n\n /**\n * Gets the render state\n * @returns The render state\n */\n updateRenderState(): GridRenderState {\n if (!this.canvas) throw new Error('canvas is not set');\n if (!this.canvasContext) throw new Error('context not set');\n\n const {\n cursorColumn,\n cursorRow,\n draggingColumn,\n draggingColumnSeparator,\n draggingRow,\n draggingRowOffset,\n draggingRowSeparator,\n editingCell,\n isDraggingHorizontalScrollBar,\n isDraggingVerticalScrollBar,\n isDragging,\n mouseX,\n mouseY,\n selectedRanges,\n } = this.state;\n const { model, stateOverride } = this.props;\n const { metrics } = this;\n const context = this.canvasContext;\n const theme = this.getTheme();\n const width = this.canvas.clientWidth;\n const height = this.canvas.clientHeight;\n\n assertNotNull(metrics);\n\n this.renderState = {\n width,\n height,\n context,\n theme,\n model,\n metrics,\n mouseX,\n mouseY,\n selectedRanges,\n draggingColumn,\n draggingColumnSeparator,\n draggingRow,\n draggingRowOffset,\n draggingRowSeparator,\n editingCell,\n isDraggingHorizontalScrollBar,\n isDraggingVerticalScrollBar,\n isDragging,\n cursorColumn,\n cursorRow,\n ...stateOverride,\n };\n\n return this.renderState;\n }\n\n render(): ReactNode {\n const { cursor } = this.state;\n\n return (\n <>\n <canvas\n className={classNames('grid-canvas', Grid.getCursorClassName(cursor))}\n ref={canvas => {\n this.canvas = canvas;\n }}\n onClick={this.handleClick}\n onContextMenu={this.handleContextMenu}\n onDoubleClick={this.handleDoubleClick}\n onKeyDown={this.handleKeyDown}\n onMouseDown={this.handleMouseDown}\n onMouseMove={this.handleMouseMove}\n onMouseLeave={this.handleMouseLeave}\n tabIndex={0}\n >\n Your browser does not support HTML canvas. Update your browser?\n </canvas>\n {this.renderInputField()}\n </>\n );\n }\n}\n\nexport default Grid;\n","import { EventTarget, Event } from 'event-target-shim';\nimport type { IColumnHeaderGroup } from './ColumnHeaderGroup';\nimport { ModelIndex } from './GridMetrics';\nimport { GridColor, GridTheme, NullableGridColor } from './GridTheme';\nimport memoizeClear from './memoizeClear';\nimport GridUtils, { Token } from './GridUtils';\n\nconst LINK_TRUNCATION_LENGTH = 5000;\n\n/* eslint class-methods-use-this: \"off\" */\n/* eslint no-unused-vars: \"off\" */\n/**\n * Model for a Grid\n * All of these methods should return very quickly, as they will be called many times in the render cycle.\n * If data needs to be loaded asynchronously, return something immediately, then trigger an event for the table to refresh (Not yet implemented).\n */\nabstract class GridModel<\n TEventMap extends Record<string, Event<string>> = Record<\n string,\n Event<string>\n >,\n TMode extends 'standard' | 'strict' = 'standard'\n> extends EventTarget<TEventMap, TMode> {\n /** Count of rows in the grid */\n abstract get rowCount(): number;\n\n /** Count of columns in the grid */\n abstract get columnCount(): number;\n\n /** Count of rows that are frozen (or 'floating') at the top */\n get floatingTopRowCount(): number {\n return 0;\n }\n\n /** Count of rows that are frozen at the bottom */\n get floatingBottomRowCount(): number {\n return 0;\n }\n\n /** Count of columns that are frozen (or 'floating') at the left */\n get floatingLeftColumnCount(): number {\n return 0;\n }\n\n /** Count of columns that are frozen (or 'floating') at the right */\n get floatingRightColumnCount(): number {\n return 0;\n }\n\n /**\n * How many columns header levels are in the grid\n * Used for column grouping where columns at depth 0 are the base columns\n *\n * A grid with 1-level grouping would have a columnHeaderDepth of 2\n * and column headers at depths 0 and 1\n */\n get columnHeaderMaxDepth(): number {\n return 1;\n }\n\n /**\n * Get the text for the specified cell\n * @param column Column to get the text for\n * @param row Row to get the text for\n * @returns Text for the specified cell\n */\n abstract textForCell(column: ModelIndex, row: ModelIndex): string;\n\n /**\n * Get the character to replace text when truncated for a specific cell.\n * Leave undefined to show text truncated with ellipsis\n * @param column Column to get the truncation character for\n * @param row Row to get the truncation character for\n * @returns Truncation character for the specified cell\n */\n truncationCharForCell(\n column: ModelIndex,\n row: ModelIndex\n ): string | undefined {\n return undefined;\n }\n\n /**\n * Get the text alignment for the specified cell\n * @param column Column to get the alignment for\n * @param row Row to get the alignment for\n * @returns Text alignment for the specified cell\n */\n textAlignForCell(column: ModelIndex, row: ModelIndex): CanvasTextAlign {\n return 'left';\n }\n\n /**\n * Get the color for the text in the specified cell\n * @param column Column to get the color for\n * @param row Row to get the color for\n * @param theme Theme applied to the grid\n * @returns Color for the text in the cell\n */\n colorForCell(\n column: ModelIndex,\n row: ModelIndex,\n theme: GridTheme\n ): GridColor {\n return theme.textColor;\n }\n\n /**\n * Get the background color for the cell\n * @param column Column to get the background color for\n * @param row Row to get the background color for\n * @param theme Theme applied to the grid\n * @returns Background color for the cell\n */\n backgroundColorForCell(\n column: ModelIndex,\n row: ModelIndex,\n theme: GridTheme\n ): NullableGridColor {\n return null;\n }\n\n /**\n * Text for the column header\n * @param column Column to get the header for\n * @param depth Depth to get the header text for. 0 is base columns\n * @returns Text to put in the column header\n */\n abstract textForColumnHeader(\n column: ModelIndex,\n depth?: number\n ): string | undefined;\n\n /** Color for column header\n * @param column Column to get the color for\n * @param depth Header depth to get the color for\n * @returns Color for the header at the depth or null\n */\n colorForColumnHeader(column: ModelIndex, depth = 0): string | null {\n return null;\n }\n\n /**\n * Text for the row header\n * @param row Row to get the header for\n * @returns Text to put in the row header\n */\n textForRowHeader(row: ModelIndex): string {\n return '';\n }\n\n /**\n * Text for the row footer\n * @param row Row to get the footer for\n * @returns Text to put in the row footer\n */\n textForRowFooter(row: ModelIndex): string {\n return '';\n }\n\n /**\n * @param column Column to check\n * @returns True if the column is movable\n */\n isColumnMovable(column: ModelIndex, depth = 0): boolean {\n return true;\n }\n\n /**\n * @param row Row to check\n * @returns True if the row is movable\n */\n isRowMovable(row: ModelIndex): boolean {\n return true;\n }\n\n getColumnHeaderGroup(\n modelIndex: ModelIndex,\n depth: number\n ): IColumnHeaderGroup | undefined {\n return undefined;\n }\n\n getColumnHeaderParentGroup(\n modelIndex: ModelIndex,\n depth: number\n ): IColumnHeaderGroup | undefined {\n return undefined;\n }\n\n /**\n * Gets the tokens in the cell at column and row, based on the visible text\n * @param column The model column\n * @param row The model row\n * @param visibleLength The length of the visible text\n * @returns An array of Tokens in the cell\n */\n tokensForCell(\n column: ModelIndex,\n row: ModelIndex,\n visibleLength: number = LINK_TRUNCATION_LENGTH\n ): Token[] {\n const text = this.textForCell(column, row);\n return this.getCachedTokensInText(text, visibleLength);\n }\n\n getCachedTokensInText = memoizeClear(\n (text: string, visibleLength: number): Token[] => {\n // If no text is truncated, then directly search in text\n if (visibleLength >= text.length) {\n return GridUtils.findTokensWithProtocolInText(text);\n }\n\n // To check for links, we should check to the first space after the truncatedText length\n const indexOfProceedingWhitespace = text\n .slice(visibleLength - 1, LINK_TRUNCATION_LENGTH)\n .search(/\\s/); // index or -1 if not found\n\n let lengthOfContent = visibleLength + indexOfProceedingWhitespace;\n // If it doesn't exist, set lengthOfContent to the minimum between length of the original text and 5000\n if (indexOfProceedingWhitespace === -1) {\n lengthOfContent = Math.min(LINK_TRUNCATION_LENGTH, text.length);\n }\n const contentToCheckForLinks = text.substring(0, lengthOfContent);\n\n return GridUtils.findTokensWithProtocolInText(contentToCheckForLinks);\n }\n );\n}\n\nexport default GridModel;\n","import type {\n Column,\n dh as DhType,\n CustomColumn,\n} from '@deephaven/jsapi-types';\nimport {\n BaseFormatConfig,\n getConditionDBString,\n getStyleDBString,\n} from './ConditionalFormattingUtils';\n\n// Conditional formatting API utils in a separate file\n// to make ConditionalFormattingUtils.ts easier to test.\n// https://github.com/facebook/jest/issues/936#issuecomment-545080082\n\nexport function makeTernaryFormatRule(\n config: BaseFormatConfig,\n prevRule: string\n): string | undefined {\n const styleDBString = getStyleDBString(config);\n if (styleDBString === undefined) {\n return undefined;\n }\n const conditionDBString = getConditionDBString(config);\n return `${conditionDBString} ? ${styleDBString} : ${prevRule}`;\n}\n\nexport function makeRowFormatColumn(dh: DhType, rule: string): CustomColumn {\n return dh.Column.formatRowColor(rule);\n}\n\nexport function makeColumnFormatColumn(\n col: Column,\n rule: string\n): CustomColumn {\n return col.formatColor(rule);\n}\n","import Log from '@deephaven/log';\nimport type {\n Column,\n CustomColumn,\n dh as DhType,\n} from '@deephaven/jsapi-types';\nimport { DateUtils, TableUtils } from '@deephaven/jsapi-utils';\nimport {\n makeColumnFormatColumn,\n makeRowFormatColumn,\n makeTernaryFormatRule,\n} from './ConditionalFormattingAPIUtils';\nimport { ColumnName } from '../../CommonTypes';\n\nconst log = Log.module('ConditionalFormattingUtils');\n\nexport type ModelColumn = {\n name: string;\n type: string;\n};\n\nexport type Condition =\n | NumberCondition\n | StringCondition\n | DateCondition\n | BooleanCondition\n | CharCondition;\n\nexport interface BaseFormatConfig {\n column: ModelColumn;\n condition: Condition;\n value?: string;\n start?: string;\n end?: string;\n style: FormatStyleConfig;\n}\n\nexport interface ConditionConfig {\n condition: Condition;\n value?: string;\n start?: string;\n end?: string;\n}\n\nexport type ChangeCallback = (\n ruleConfig: BaseFormatConfig,\n isValid: boolean\n) => void;\n\nexport enum FormatterType {\n CONDITIONAL = 'conditional',\n ROWS = 'rows',\n}\n\nexport interface FormattingRule {\n type: FormatterType;\n config: BaseFormatConfig;\n}\n\nexport enum NumberCondition {\n IS_EQUAL = 'is-equal',\n IS_NOT_EQUAL = 'is-not-equal',\n IS_BETWEEN = 'is-between',\n GREATER_THAN = 'greater-than',\n GREATER_THAN_OR_EQUAL = 'greater-than-or-equal',\n LESS_THAN = 'less-than',\n LESS_THAN_OR_EQUAL = 'less-than-or-equal',\n IS_NULL = 'is-null',\n IS_NOT_NULL = 'is-not-null',\n}\n\nexport enum StringCondition {\n IS_EXACTLY = 'is-exactly',\n IS_NOT_EXACTLY = 'is-not-exactly',\n CONTAINS = 'contains',\n DOES_NOT_CONTAIN = 'does-not-contain',\n STARTS_WITH = 'starts-with',\n ENDS_WITH = 'ends-with',\n IS_NULL = 'is-null',\n IS_NOT_NULL = 'is-not-null',\n}\n\nexport enum DateCondition {\n IS_EXACTLY = 'is-exactly',\n IS_NOT_EXACTLY = 'is-not-exactly',\n IS_BEFORE = 'is-before',\n IS_BEFORE_OR_EQUAL = 'is-before-or-equal',\n IS_AFTER = 'is-after',\n IS_AFTER_OR_EQUAL = 'is-after-or-equal',\n IS_NULL = 'is-null',\n IS_NOT_NULL = 'is-not-null',\n}\n\nexport enum BooleanCondition {\n IS_TRUE = 'is-true',\n IS_FALSE = 'is-false',\n IS_NULL = 'is-null',\n IS_NOT_NULL = 'is-not-null',\n}\n\nexport enum CharCondition {\n IS_EQUAL = 'is-equal',\n IS_NOT_EQUAL = 'is-not-equal',\n IS_NULL = 'is-null',\n IS_NOT_NULL = 'is-not-null',\n}\n\nexport enum FormatStyleType {\n NO_FORMATTING = 'no-formatting',\n POSITIVE = 'positive',\n NEGATIVE = 'negative',\n WARN = 'warn',\n NEUTRAL = 'neutral',\n ACCENT_1 = 'accent-1',\n ACCENT_2 = 'accent-2',\n CUSTOM = 'custom',\n}\n\nexport interface FormatStyleConfig {\n type: FormatStyleType;\n customConfig?: {\n color: string;\n background: string;\n };\n}\n\nexport function getLabelForStyleType(option: FormatStyleType): string {\n switch (option) {\n case FormatStyleType.NO_FORMATTING:\n return 'No formatting';\n case FormatStyleType.POSITIVE:\n return 'Positive';\n case FormatStyleType.NEGATIVE:\n return 'Negative';\n case FormatStyleType.WARN:\n return 'Warn';\n case FormatStyleType.NEUTRAL:\n return 'Neutral';\n case FormatStyleType.ACCENT_1:\n return 'Accent 1';\n case FormatStyleType.ACCENT_2:\n return 'Accent 2';\n case FormatStyleType.CUSTOM:\n return 'Custom...';\n }\n}\n\nexport function getBackgroundForStyleConfig(\n config: FormatStyleConfig\n): string | undefined {\n const { type, customConfig } = config;\n switch (type) {\n case FormatStyleType.NO_FORMATTING:\n return undefined;\n case FormatStyleType.POSITIVE:\n return '#9fde6f';\n case FormatStyleType.NEGATIVE:\n return '#ff6087';\n case FormatStyleType.WARN:\n return '#f67f40';\n case FormatStyleType.NEUTRAL:\n return '#ffd95c';\n case FormatStyleType.ACCENT_1:\n return '#78dce8';\n case FormatStyleType.ACCENT_2:\n return '#ab9bf5';\n case FormatStyleType.CUSTOM:\n return customConfig?.background;\n default:\n return undefined;\n }\n}\n\nexport function getColorForStyleConfig(\n config: FormatStyleConfig\n): string | undefined {\n const { type, customConfig } = config;\n switch (type) {\n case FormatStyleType.NO_FORMATTING:\n return undefined;\n case FormatStyleType.POSITIVE:\n return '#526a3f';\n case FormatStyleType.NEGATIVE:\n return '#802f44';\n case FormatStyleType.WARN:\n return '#663318';\n case FormatStyleType.NEUTRAL:\n return '#63562b';\n case FormatStyleType.ACCENT_1:\n return '#3f6469';\n case FormatStyleType.ACCENT_2:\n return '#554d72';\n case FormatStyleType.CUSTOM:\n return customConfig?.color;\n default:\n return undefined;\n }\n}\n\nexport function getStyleDBString(config: BaseFormatConfig): string | undefined {\n const color = getColorForStyleConfig(config.style);\n const bg = getBackgroundForStyleConfig(config.style);\n if (color === undefined || bg === undefined) {\n return undefined;\n }\n return `bgfg(\\`${bg}\\`, \\`${color}\\`)`;\n}\n\nfunction getNumberConditionText(config: BaseFormatConfig): string {\n const { column, value, start, end } = config;\n return getTextForNumberCondition(\n column.name,\n config.condition as NumberCondition,\n value,\n start,\n end\n );\n}\n\nfunction getStringConditionText(config: BaseFormatConfig): string {\n const { column, value } = config;\n return getTextForStringCondition(\n column.name,\n config.condition as StringCondition,\n value\n );\n}\n\nfunction getDateConditionText(config: BaseFormatConfig): string {\n const { column, value } = config;\n return getTextForDateCondition(\n column.name,\n config.condition as DateCondition,\n value\n );\n}\n\nfunction getBooleanConditionText(config: BaseFormatConfig): string {\n const { column } = config;\n return getTextForBooleanCondition(\n column.name,\n config.condition as BooleanCondition\n );\n}\n\nfunction getCharConditionText(config: BaseFormatConfig): string {\n const { column, value } = config;\n return getTextForCharCondition(\n column.name,\n config.condition as CharCondition,\n value\n );\n}\n\nexport function getConditionDBString(config: BaseFormatConfig): string {\n const { column } = config;\n\n if (TableUtils.isNumberType(column.type)) {\n return getNumberConditionText(config);\n }\n if (TableUtils.isCharType(column.type)) {\n return getCharConditionText(config);\n }\n if (TableUtils.isStringType(column.type)) {\n return getStringConditionText(config);\n }\n if (TableUtils.isDateType(column.type)) {\n return getDateConditionText(config);\n }\n if (TableUtils.isBooleanType(column.type)) {\n return getBooleanConditionText(config);\n }\n\n throw new Error('Invalid column type');\n}\n\nexport function getLabelForNumberCondition(condition: NumberCondition): string {\n switch (condition) {\n case NumberCondition.IS_EQUAL:\n return 'is equal to';\n case NumberCondition.IS_NOT_EQUAL:\n return 'is not equal to';\n case NumberCondition.IS_BETWEEN:\n return 'is between';\n case NumberCondition.GREATER_THAN:\n return 'greater than';\n case NumberCondition.GREATER_THAN_OR_EQUAL:\n return 'greater than or equal to';\n case NumberCondition.LESS_THAN:\n return 'less than';\n case NumberCondition.LESS_THAN_OR_EQUAL:\n return 'less than or equal to';\n case NumberCondition.IS_NULL:\n return 'is null';\n case NumberCondition.IS_NOT_NULL:\n return 'is not null';\n }\n}\n\nexport function getLabelForStringCondition(condition: StringCondition): string {\n switch (condition) {\n case StringCondition.IS_EXACTLY:\n return 'is exactly';\n case StringCondition.IS_NOT_EXACTLY:\n return 'is not exactly';\n case StringCondition.CONTAINS:\n return 'contains';\n case StringCondition.DOES_NOT_CONTAIN:\n return 'does not contain';\n case StringCondition.STARTS_WITH:\n return 'starts with';\n case StringCondition.ENDS_WITH:\n return 'ends with';\n case StringCondition.IS_NULL:\n return 'is null';\n case StringCondition.IS_NOT_NULL:\n return 'is not null';\n }\n}\n\nexport function getLabelForDateCondition(condition: DateCondition): string {\n switch (condition) {\n case DateCondition.IS_EXACTLY:\n return 'is';\n case DateCondition.IS_NOT_EXACTLY:\n return 'is not';\n case DateCondition.IS_BEFORE:\n return 'is before';\n case DateCondition.IS_BEFORE_OR_EQUAL:\n return 'is before or equal';\n case DateCondition.IS_AFTER:\n return 'is after';\n case DateCondition.IS_AFTER_OR_EQUAL:\n return 'is after or equal';\n case DateCondition.IS_NULL:\n return 'is null';\n case DateCondition.IS_NOT_NULL:\n return 'is not null';\n }\n}\n\nexport function getLabelForBooleanCondition(\n condition: BooleanCondition\n): string {\n switch (condition) {\n case BooleanCondition.IS_TRUE:\n return 'is true';\n case BooleanCondition.IS_FALSE:\n return 'is false';\n case BooleanCondition.IS_NULL:\n return 'is null';\n case BooleanCondition.IS_NOT_NULL:\n return 'is not null';\n }\n}\n\nexport function getLabelForCharCondition(condition: CharCondition): string {\n switch (condition) {\n case CharCondition.IS_EQUAL:\n return 'is';\n case CharCondition.IS_NOT_EQUAL:\n return 'is not';\n case CharCondition.IS_NULL:\n return 'is null';\n case CharCondition.IS_NOT_NULL:\n return 'is not null';\n }\n}\n\nexport function getDefaultConditionForType(columnType: string): Condition {\n if (TableUtils.isNumberType(columnType)) {\n return NumberCondition.IS_EQUAL;\n }\n if (TableUtils.isCharType(columnType)) {\n return CharCondition.IS_EQUAL;\n }\n if (TableUtils.isStringType(columnType)) {\n return StringCondition.IS_EXACTLY;\n }\n if (TableUtils.isDateType(columnType)) {\n return DateCondition.IS_EXACTLY;\n }\n if (TableUtils.isBooleanType(columnType)) {\n return BooleanCondition.IS_TRUE;\n }\n\n throw new Error('Invalid column type');\n}\n\nexport function getDefaultValueForType(columnType: string): string | undefined {\n if (TableUtils.isCharType(columnType)) {\n return '';\n }\n if (TableUtils.isStringType(columnType)) {\n return '';\n }\n return undefined;\n}\n\nexport function getConditionConfig(config: BaseFormatConfig): ConditionConfig {\n const { condition, value, start, end } = config;\n return { condition, value, start, end };\n}\n\nexport function getDefaultConditionConfigForType(\n type: string\n): ConditionConfig {\n return {\n condition: getDefaultConditionForType(type),\n value: getDefaultValueForType(type),\n start: undefined,\n end: undefined,\n };\n}\n\nexport function getDefaultStyleConfig(): FormatStyleConfig {\n return {\n type: FormatStyleType.NO_FORMATTING,\n };\n}\n\nfunction getShortLabelForStringCondition(condition: StringCondition): string {\n switch (condition) {\n case StringCondition.IS_EXACTLY:\n return '==';\n case StringCondition.IS_NOT_EXACTLY:\n return '!=';\n case StringCondition.CONTAINS:\n return 'contains';\n case StringCondition.DOES_NOT_CONTAIN:\n return 'does not contain';\n case StringCondition.STARTS_WITH:\n return 'starts with';\n case StringCondition.ENDS_WITH:\n return 'ends with';\n case StringCondition.IS_NULL:\n return 'is null';\n case StringCondition.IS_NOT_NULL:\n return 'is not null';\n }\n}\n\nfunction getShortLabelForDateCondition(condition: DateCondition): string {\n switch (condition) {\n case DateCondition.IS_EXACTLY:\n return '==';\n case DateCondition.IS_NOT_EXACTLY:\n return '!=';\n case DateCondition.IS_BEFORE:\n return '<';\n case DateCondition.IS_BEFORE_OR_EQUAL:\n return '<=';\n case DateCondition.IS_AFTER:\n return '>';\n case DateCondition.IS_AFTER_OR_EQUAL:\n return '>=';\n case DateCondition.IS_NULL:\n return 'is null';\n case DateCondition.IS_NOT_NULL:\n return 'is not null';\n }\n}\n\nfunction getShortLabelForBooleanCondition(condition: BooleanCondition): string {\n switch (condition) {\n case BooleanCondition.IS_TRUE:\n return 'is true';\n case BooleanCondition.IS_FALSE:\n return 'is false';\n case BooleanCondition.IS_NULL:\n return 'is null';\n case BooleanCondition.IS_NOT_NULL:\n return 'is not null';\n }\n}\n\nfunction getShortLabelForCharCondition(condition: CharCondition): string {\n switch (condition) {\n case CharCondition.IS_EQUAL:\n return '==';\n case CharCondition.IS_NOT_EQUAL:\n return '!=';\n case CharCondition.IS_NULL:\n return 'is null';\n case CharCondition.IS_NOT_NULL:\n return 'is not null';\n }\n}\n\nexport function getShortLabelForNumberCondition(\n condition: NumberCondition\n): string {\n switch (condition) {\n case NumberCondition.IS_EQUAL:\n return '==';\n case NumberCondition.IS_NOT_EQUAL:\n return '!=';\n case NumberCondition.IS_BETWEEN:\n return '==';\n case NumberCondition.GREATER_THAN:\n return '>';\n case NumberCondition.GREATER_THAN_OR_EQUAL:\n return '>=';\n case NumberCondition.LESS_THAN:\n return '<';\n case NumberCondition.LESS_THAN_OR_EQUAL:\n return '<=';\n case NumberCondition.IS_NULL:\n return 'is null';\n case NumberCondition.IS_NOT_NULL:\n return 'is not null';\n }\n}\n\nexport function getTextForNumberCondition(\n columnName: ColumnName,\n condition: NumberCondition,\n value: unknown,\n start: unknown,\n end: unknown\n): string {\n switch (condition) {\n case NumberCondition.IS_EQUAL:\n return `${columnName} == ${value}`;\n case NumberCondition.IS_NOT_EQUAL:\n return `${columnName} != ${value}`;\n case NumberCondition.IS_BETWEEN:\n return `${columnName} > ${start} && ${columnName} < ${end}`;\n case NumberCondition.GREATER_THAN:\n return `${columnName} > ${value}`;\n case NumberCondition.GREATER_THAN_OR_EQUAL:\n return `${columnName} >= ${value}`;\n case NumberCondition.LESS_THAN:\n return `${columnName} < ${value}`;\n case NumberCondition.LESS_THAN_OR_EQUAL:\n return `${columnName} <= ${value}`;\n case NumberCondition.IS_NULL:\n return `${columnName} == null`;\n case NumberCondition.IS_NOT_NULL:\n return `${columnName} != null`;\n }\n}\n\nexport function getTextForStringCondition(\n columnName: ColumnName,\n condition: StringCondition,\n value: unknown\n): string {\n switch (condition) {\n case StringCondition.IS_EXACTLY:\n return `${columnName} == \"${value}\"`;\n case StringCondition.IS_NOT_EXACTLY:\n return `${columnName} != \"${value}\"`;\n case StringCondition.CONTAINS:\n return `${columnName} != null && ${columnName}.contains(\"${value}\")`;\n case StringCondition.DOES_NOT_CONTAIN:\n return `${columnName} != null && !${columnName}.contains(\"${value}\")`;\n case StringCondition.STARTS_WITH:\n return `${columnName} != null && ${columnName}.startsWith(\"${value}\")`;\n case StringCondition.ENDS_WITH:\n return `${columnName} != null && ${columnName}.endsWith(\"${value}\")`;\n case StringCondition.IS_NULL:\n return `${columnName} == null`;\n case StringCondition.IS_NOT_NULL:\n return `${columnName} != null`;\n }\n}\n\nexport function getTextForDateCondition(\n columnName: ColumnName,\n condition: DateCondition,\n value: unknown\n): string {\n switch (condition) {\n case DateCondition.IS_EXACTLY:\n return `${columnName} == convertDateTime(\"${value}\")`;\n case DateCondition.IS_NOT_EXACTLY:\n return `${columnName} != convertDateTime(\\`${value}\\`)`;\n case DateCondition.IS_BEFORE:\n return `${columnName} < convertDateTime(\\`${value}\\`)`;\n case DateCondition.IS_BEFORE_OR_EQUAL:\n return `${columnName} <= convertDateTime(\"${value}\")`;\n case DateCondition.IS_AFTER:\n return `${columnName} > convertDateTime(\\`${value}\\`)`;\n case DateCondition.IS_AFTER_OR_EQUAL:\n return `${columnName} >= convertDateTime(\\`${value}\\`)`;\n case DateCondition.IS_NULL:\n return `${columnName} == null`;\n case DateCondition.IS_NOT_NULL:\n return `${columnName} != null`;\n }\n}\n\nexport function getTextForBooleanCondition(\n columnName: ColumnName,\n condition: BooleanCondition\n): string {\n switch (condition) {\n case BooleanCondition.IS_TRUE:\n return `${columnName} == true`;\n case BooleanCondition.IS_FALSE:\n return `${columnName} == false`;\n case BooleanCondition.IS_NULL:\n return `${columnName} == null`;\n case BooleanCondition.IS_NOT_NULL:\n return `${columnName} != null`;\n }\n}\n\nexport function getTextForCharCondition(\n columnName: ColumnName,\n condition: CharCondition,\n value: unknown\n): string {\n switch (condition) {\n case CharCondition.IS_EQUAL:\n return `${columnName} == '${value}'`;\n case CharCondition.IS_NOT_EQUAL:\n return `${columnName} != '${value}'`;\n case CharCondition.IS_NULL:\n return `isNull(${columnName})`;\n case CharCondition.IS_NOT_NULL:\n return `!isNull(${columnName})`;\n }\n}\n\nexport function getShortLabelForConditionType(\n columnType: string,\n condition: Condition\n): string {\n if (TableUtils.isNumberType(columnType)) {\n return getShortLabelForNumberCondition(condition as NumberCondition);\n }\n if (TableUtils.isCharType(columnType)) {\n return getShortLabelForCharCondition(condition as CharCondition);\n }\n if (TableUtils.isStringType(columnType)) {\n return getShortLabelForStringCondition(condition as StringCondition);\n }\n if (TableUtils.isDateType(columnType)) {\n return getShortLabelForDateCondition(condition as DateCondition);\n }\n if (TableUtils.isBooleanType(columnType)) {\n return getShortLabelForBooleanCondition(condition as BooleanCondition);\n }\n\n throw new Error('Invalid column type');\n}\n\n/**\n * Get format columns array for the given columns and formatting rules\n * @param columns Available columns\n * @param rules Formatting rules to build the format columns from\n * @returns Array of format columns\n */\nexport function getFormatColumns(\n dh: DhType,\n columns: readonly Column[],\n rules: readonly FormattingRule[]\n): CustomColumn[] {\n if (rules === undefined) {\n log.debug(`no rules passed.`);\n return [];\n }\n const result: CustomColumn[] = [];\n // There can be only one row format custom column\n // and multiple column format custom columns (one per column)\n let rowFormatConfig: [string, CustomColumn];\n const columnFormatConfigMap = new Map<string, [string, CustomColumn]>();\n rules.forEach(({ config, type: formatterType }) => {\n const { column } = config;\n // Check both name and type because the type can change\n const col = columns.find(\n ({ name, type }) => name === column.name && type === column.type\n );\n if (col === undefined) {\n log.debug(\n `Column ${column.name}:${column.type} not found. Ignoring format rule.`,\n config\n );\n return;\n }\n // Stack ternary format conditions by column\n const [prevRule, prevFormatColumn] = (formatterType ===\n FormatterType.CONDITIONAL\n ? columnFormatConfigMap.get(col.name)\n : rowFormatConfig) ?? ['null', undefined];\n const rule = makeTernaryFormatRule(config, prevRule);\n if (rule === undefined) {\n log.debug(`Ignoring format rule.`, config);\n return;\n }\n // Replace existing formatColumn with the new stacked format\n const index =\n prevFormatColumn === undefined ? -1 : result.indexOf(prevFormatColumn);\n if (index > -1) {\n result.splice(index, 1);\n }\n const formatColumn =\n formatterType === FormatterType.CONDITIONAL\n ? makeColumnFormatColumn(col, rule)\n : makeRowFormatColumn(dh, rule);\n result.push(formatColumn);\n if (formatterType === FormatterType.CONDITIONAL) {\n columnFormatConfigMap.set(col.name, [rule, formatColumn]);\n } else {\n rowFormatConfig = [rule, formatColumn];\n }\n });\n\n return result;\n}\n\n/**\n * Validate that a given date condition + value pair is valid.\n * @param condition\n * @param value\n */\nexport function isDateConditionValid(\n dh: DhType,\n condition: DateCondition,\n value?: string\n) {\n switch (condition) {\n case DateCondition.IS_NULL:\n case DateCondition.IS_NOT_NULL:\n return true;\n\n default: {\n const [dateTimeString, ...rest] = (value ?? '').split(' ');\n // Reconstitute all tokens after the first ' ' in case the user included garbage data at the end\n // e.g. '2020-01-01 NY blah'\n const tzCode = rest.join(' ');\n\n try {\n DateUtils.parseDateTimeString(dateTimeString);\n } catch (e) {\n log.debug('Invalid datetime string', dateTimeString);\n return false;\n }\n\n try {\n dh.i18n.TimeZone.getTimeZone(tzCode);\n } catch (e) {\n log.debug('Invalid timezone string', tzCode);\n return false;\n }\n\n return true;\n }\n }\n}\n\nexport function isSupportedColumn({ type }: ModelColumn): boolean {\n return (\n TableUtils.isNumberType(type) ||\n TableUtils.isCharType(type) ||\n TableUtils.isStringType(type) ||\n TableUtils.isDateType(type) ||\n TableUtils.isBooleanType(type)\n );\n}\n","import React from 'react';\nimport classNames from 'classnames';\nimport { CSSTransition } from 'react-transition-group';\nimport { ThemeExport } from '@deephaven/components';\nimport './IrisGridBottomBar.scss';\n\nexport type IrisGridBottomBarProps = {\n animation?: string;\n children: React.ReactNode;\n onClick?: () => void;\n onEntering?: () => void;\n onEntered?: () => void;\n onExiting?: () => void;\n onExited?: () => void;\n isShown: boolean;\n className?: string;\n};\n\nexport function IrisGridBottomBar({\n animation = 'iris-grid-bottom-bar-slide-up',\n children,\n className,\n isShown,\n onClick,\n onEntering,\n onEntered,\n onExiting,\n onExited,\n}: IrisGridBottomBarProps): JSX.Element {\n return (\n <CSSTransition\n in={isShown}\n timeout={ThemeExport.transitionMs}\n classNames={animation}\n onEntering={onEntering}\n onEntered={onEntered}\n onExiting={onExiting}\n onExited={onExited}\n mountOnEnter\n unmountOnExit\n >\n <div\n className={classNames('iris-grid-bottom-bar', className)}\n role=\"presentation\"\n onClick={onClick}\n onKeyPress={onClick}\n >\n {children}\n </div>\n </CSSTransition>\n );\n}\n\nexport default IrisGridBottomBar;\n","import React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { vsPass, vsWarning } from '@deephaven/icons';\nimport { Button, LoadingSpinner } from '@deephaven/components';\nimport { usePrevious } from '@deephaven/react-hooks';\nimport IrisGridBottomBar from './IrisGridBottomBar';\nimport './PendingDataBottomBar.scss';\nimport { PendingDataErrorMap, PendingDataMap } from './CommonTypes';\n\nconst HIDE_TIMEOUT = 3000;\n\nconst MAX_NUMBER_ROWS_SHOWN = 5;\n\nexport type PendingDataBottomBarProps = {\n onSave: () => Promise<void>;\n onDiscard: () => Promise<void>;\n discardTooltip?: string;\n saveTooltip?: string;\n isSaving?: boolean;\n error?: string | null;\n pendingDataErrors: PendingDataErrorMap;\n pendingDataMap: PendingDataMap;\n onEntering?: () => void;\n onEntered?: () => void;\n onExiting?: () => void;\n onExited?: () => void;\n};\n\nexport function PendingDataBottomBar({\n isSaving = false,\n onSave,\n onDiscard,\n discardTooltip,\n saveTooltip,\n error,\n pendingDataErrors,\n pendingDataMap,\n onEntering,\n onEntered,\n onExiting,\n onExited,\n}: PendingDataBottomBarProps): JSX.Element {\n const [isSuccessShown, setIsSuccessShown] = useState(false);\n const [wasSuccessShown, setWasSuccessShown] = useState(false);\n const successTimeout = useRef<ReturnType<typeof setTimeout>>();\n const prevIsSaving = usePrevious(isSaving);\n const errorMessage = useMemo(() => {\n if (pendingDataErrors.size === 0) {\n return error;\n }\n if (pendingDataErrors.size <= MAX_NUMBER_ROWS_SHOWN) {\n return `Key can't be empty (on pending row${\n pendingDataErrors.size > 1 ? 's' : ''\n } ${Array.from(pendingDataErrors.keys()).join(', ').trim()})`;\n }\n return `Key can't be empty (on ${pendingDataErrors.size} rows)`;\n }, [error, pendingDataErrors]);\n\n useEffect(\n function showSuccessMessage() {\n if (\n prevIsSaving != null &&\n prevIsSaving &&\n !isSaving &&\n errorMessage == null\n ) {\n setIsSuccessShown(true);\n setWasSuccessShown(true);\n successTimeout.current = setTimeout(() => {\n setIsSuccessShown(false);\n }, HIDE_TIMEOUT);\n }\n },\n [errorMessage, isSaving, prevIsSaving]\n );\n\n useEffect(\n function hideSuccessMessage() {\n if (successTimeout.current && pendingDataMap.size > 0) {\n // A change just occurred while the success message was still being shown, just hide the success message\n clearTimeout(successTimeout.current);\n setIsSuccessShown(false);\n setWasSuccessShown(false);\n }\n },\n [pendingDataMap]\n );\n\n useEffect(function cleanupTimeout() {\n return () =>\n successTimeout.current ? clearTimeout(successTimeout.current) : undefined;\n }, []);\n\n const pendingRowCount = pendingDataMap.size;\n let commitIcon;\n if (isSaving) {\n commitIcon = <LoadingSpinner />;\n } else if (wasSuccessShown) {\n commitIcon = vsPass;\n }\n\n return (\n <IrisGridBottomBar\n className=\"pending-data-bottom-bar\"\n isShown={pendingRowCount > 0 || isSuccessShown || errorMessage != null}\n onEntering={onEntering}\n onEntered={onEntered}\n onExiting={onExiting}\n onExited={() => {\n setWasSuccessShown(false);\n if (onExited) {\n onExited();\n }\n }}\n >\n {errorMessage != null && errorMessage !== '' && (\n <div className=\"error-message\">\n <FontAwesomeIcon icon={vsWarning} />\n <span>{`${errorMessage}`}</span>\n </div>\n )}\n {(errorMessage == null || errorMessage === '') && (\n <div className=\"status-message\">\n {pendingRowCount > 0 && (\n <span>{`${pendingRowCount} row${\n pendingRowCount > 1 ? 's' : ''\n } pending`}</span>\n )}\n </div>\n )}\n <div className=\"buttons-container\">\n {!isSaving && !wasSuccessShown && (\n <Button kind=\"secondary\" onClick={onDiscard} tooltip={discardTooltip}>\n Discard\n </Button>\n )}\n <Button\n kind={wasSuccessShown ? 'success' : 'primary'}\n onClick={onSave}\n icon={commitIcon}\n disabled={isSaving || wasSuccessShown || errorMessage != null}\n tooltip={saveTooltip}\n >\n {isSaving && `Committing...`}\n {!isSaving && wasSuccessShown && `Success`}\n {!isSaving && !wasSuccessShown && `Commit`}\n </Button>\n </div>\n </IrisGridBottomBar>\n );\n}\n\nexport default PendingDataBottomBar;\n","enum AggregationOperation {\n COUNT = 'Count',\n MIN = 'Min',\n MAX = 'Max',\n SUM = 'Sum',\n ABS_SUM = 'AbsSum',\n VAR = 'Var',\n AVG = 'Avg',\n STD = 'Std',\n FIRST = 'First',\n LAST = 'Last',\n SKIP = 'Skip',\n COUNT_DISTINCT = 'CountDistinct',\n DISTINCT = 'Distinct',\n UNIQUE = 'Unique',\n}\n\nexport default AggregationOperation;\n","import type { Column } from '@deephaven/jsapi-types';\nimport { TableUtils } from '@deephaven/jsapi-utils';\nimport AggregationOperation from './AggregationOperation';\n\nexport const SELECTABLE_OPTIONS = [\n AggregationOperation.SUM,\n AggregationOperation.ABS_SUM,\n AggregationOperation.MIN,\n AggregationOperation.MAX,\n AggregationOperation.VAR,\n AggregationOperation.AVG,\n AggregationOperation.STD,\n AggregationOperation.FIRST,\n AggregationOperation.LAST,\n AggregationOperation.COUNT_DISTINCT,\n AggregationOperation.DISTINCT,\n AggregationOperation.COUNT,\n AggregationOperation.UNIQUE,\n];\n\n/**\n * Check if an operation requires a rollup/table grouping\n * @param type The operation to check\n * @returns True if this operation applies to the whole table, false if applies to columns\n */\nexport const isRollupOperation = (type: AggregationOperation): boolean => {\n switch (type) {\n // currently no rollup only operations, but there has been in the past\n default:\n return false;\n }\n};\n\n/**\n * Check if an operation is valid against the given column type\n * @param operationType The operation to check\n * @param columnType The column type to check against\n */\nexport const isValidOperation = (\n operationType: AggregationOperation,\n columnType: string\n): boolean => {\n switch (operationType) {\n case AggregationOperation.COUNT:\n case AggregationOperation.FIRST:\n case AggregationOperation.LAST:\n case AggregationOperation.COUNT_DISTINCT:\n case AggregationOperation.DISTINCT:\n case AggregationOperation.UNIQUE:\n return true;\n case AggregationOperation.MIN:\n case AggregationOperation.MAX:\n return (\n TableUtils.isNumberType(columnType) ||\n TableUtils.isDateType(columnType) ||\n TableUtils.isTextType(columnType)\n );\n case AggregationOperation.SUM:\n case AggregationOperation.ABS_SUM:\n case AggregationOperation.VAR:\n case AggregationOperation.AVG:\n case AggregationOperation.STD:\n return TableUtils.isNumberType(columnType);\n case AggregationOperation.SKIP:\n return false;\n // No default case - if AggregationOperation is added, we'll get a compile time error\n }\n};\n\nexport const filterValidColumns = (\n columns: readonly Column[],\n operationType: AggregationOperation\n): Column[] => columns.filter(c => isValidOperation(operationType, c.type));\n\nexport const getOperationColumnNames = (\n columns: readonly Column[],\n operationType: AggregationOperation,\n selected: readonly string[],\n invert: boolean\n): string[] =>\n filterValidColumns(columns, operationType)\n .map(({ name }) => name)\n .filter(name => (selected.includes(name) ? !invert : invert));\n\nexport default {\n isRollupOperation,\n filterValidColumns,\n getOperationColumnNames,\n};\n","enum AdvancedSettingsType {\n FILTER_CONTROL_CHANGE_CLEARS_ALL_FILTERS = 'filter-control-change-clears-all-filters',\n LINK_CHANGE_CLEARS_ALL_FILTERS = 'link-change-clears-all-filters',\n}\n\nexport default AdvancedSettingsType;\n","import AdvancedSettingsType from './AdvancedSettingsType';\n\nconst DEFAULTS = Object.freeze([\n [AdvancedSettingsType.FILTER_CONTROL_CHANGE_CLEARS_ALL_FILTERS, false],\n [AdvancedSettingsType.LINK_CHANGE_CLEARS_ALL_FILTERS, false],\n] as const);\n\nexport default { DEFAULTS };\n","import {\n MoveOperation,\n GridUtils,\n ModelIndex,\n BoundedAxisRange,\n IColumnHeaderGroup,\n} from '@deephaven/grid';\nimport memoizeOne from 'memoize-one';\nimport Log from '@deephaven/log';\n\nconst log = Log.module('ColumnHeaderGroup');\n\nexport function isColumnHeaderGroup(x: unknown): x is ColumnHeaderGroup {\n return x instanceof ColumnHeaderGroup;\n}\n\nexport default class ColumnHeaderGroup implements IColumnHeaderGroup {\n static NEW_GROUP_PREFIX = ':newGroup';\n\n name: string;\n\n children: string[];\n\n depth: number;\n\n parent?: string;\n\n color?: string;\n\n childIndexes: ModelIndex[];\n\n constructor({\n name,\n children,\n color,\n depth,\n childIndexes,\n parent,\n }: {\n name: string;\n children: string[];\n color?: string;\n depth: number;\n childIndexes: ModelIndex[];\n parent?: string;\n }) {\n this.name = name;\n this.children = children;\n this.color = color;\n this.depth = depth;\n this.childIndexes = childIndexes;\n this.parent = parent;\n }\n\n getVisibleRange = memoizeOne(\n (movedItems: readonly MoveOperation[]): BoundedAxisRange => {\n const flattenedIndexes = this.childIndexes.flat();\n const visibleIndexes = GridUtils.getVisibleIndexes(\n flattenedIndexes,\n movedItems\n );\n\n const start = Math.min(...visibleIndexes);\n const end = Math.max(...visibleIndexes);\n\n if (end - start !== flattenedIndexes.length - 1) {\n log.warn(`Column header group ${this.name} is not contiguous`);\n }\n\n return [start, end];\n }\n );\n\n setParent(parent: string | undefined): void {\n this.parent = parent;\n }\n\n addChildren(children: string[]): void {\n const newChildren = new Set(this.children.concat(children));\n this.children = [...newChildren];\n }\n\n removeChildren(children: string[]): void {\n const newChildren = new Set(this.children);\n children.forEach(name => newChildren.delete(name));\n this.children = [...newChildren];\n }\n\n get isNew(): boolean {\n return this.name.startsWith(ColumnHeaderGroup.NEW_GROUP_PREFIX);\n }\n}\n","import {\n GridMetrics,\n GridRange,\n GridUtils,\n ModelIndex,\n ModelSizeMap,\n MoveOperation,\n VisibleIndex,\n} from '@deephaven/grid';\nimport type {\n Column,\n ColumnGroup,\n DateWrapper,\n dh as DhType,\n FilterCondition,\n LongWrapper,\n RangeSet,\n RollupConfig,\n Sort,\n Table,\n TableData,\n} from '@deephaven/jsapi-types';\nimport {\n DateUtils,\n TableUtils,\n ReverseType,\n SortDirection,\n FormattingRule,\n} from '@deephaven/jsapi-utils';\nimport Log from '@deephaven/log';\nimport { assertNotNull, EMPTY_ARRAY, EMPTY_MAP } from '@deephaven/utils';\nimport AggregationUtils from './sidebar/aggregations/AggregationUtils';\nimport AggregationOperation from './sidebar/aggregations/AggregationOperation';\nimport { FilterData, IrisGridProps, IrisGridState } from './IrisGrid';\nimport {\n ColumnName,\n ReadonlyAdvancedFilterMap,\n ReadonlyQuickFilterMap,\n InputFilter,\n CellData,\n PendingDataMap,\n UIRow,\n AdvancedFilterOptions,\n} from './CommonTypes';\nimport { UIRollupConfig } from './sidebar/RollupRows';\nimport { AggregationSettings } from './sidebar/aggregations/Aggregations';\nimport { FormattingRule as SidebarFormattingRule } from './sidebar/conditional-formatting/ConditionalFormattingUtils';\nimport IrisGridModel from './IrisGridModel';\nimport type AdvancedSettingsType from './sidebar/AdvancedSettingsType';\nimport AdvancedSettings from './sidebar/AdvancedSettings';\nimport ColumnHeaderGroup from './ColumnHeaderGroup';\n\nconst log = Log.module('IrisGridUtils');\n\ntype HydratedIrisGridState = Pick<\n IrisGridState,\n | 'advancedFilters'\n | 'aggregationSettings'\n | 'customColumnFormatMap'\n | 'isFilterBarShown'\n | 'quickFilters'\n | 'customColumns'\n | 'reverseType'\n | 'rollupConfig'\n | 'showSearchBar'\n | 'searchValue'\n | 'selectDistinctColumns'\n | 'selectedSearchColumns'\n | 'sorts'\n | 'invertSearchColumns'\n | 'pendingDataMap'\n | 'frozenColumns'\n | 'conditionalFormats'\n | 'columnHeaderGroups'\n> & {\n metrics: Pick<GridMetrics, 'userColumnWidths' | 'userRowHeights'>;\n};\n\nexport type DehydratedPendingDataMap<T> = [number, { data: [string, T][] }][];\n\nexport type DehydratedAdvancedFilter = [\n number,\n {\n options: AdvancedFilterOptions;\n }\n];\n\nexport type DehydratedQuickFilter = [\n number,\n {\n text: string;\n }\n];\n\nexport type DehydratedCustomColumnFormat = [string, FormattingRule];\n\nexport type DehydratedUserColumnWidth = [ColumnName, number];\n\nexport type DehydratedUserRowHeight = [number, number];\n\n/** @deprecated Use `DehydratedSort` instead */\nexport interface LegacyDehydratedSort {\n column: ModelIndex;\n isAbs: boolean;\n direction: SortDirection;\n}\n\nexport interface DehydratedSort {\n column: ColumnName;\n isAbs: boolean;\n direction: SortDirection;\n}\n\nexport interface TableSettings {\n quickFilters?: readonly DehydratedQuickFilter[];\n advancedFilters?: readonly DehydratedAdvancedFilter[];\n inputFilters?: readonly InputFilter[];\n sorts?: readonly (DehydratedSort | LegacyDehydratedSort)[];\n partition?: unknown;\n partitionColumn?: ColumnName;\n}\n\nexport interface DehydratedIrisGridState {\n advancedFilters: readonly DehydratedAdvancedFilter[];\n aggregationSettings: AggregationSettings;\n customColumnFormatMap: readonly DehydratedCustomColumnFormat[];\n isFilterBarShown: boolean;\n quickFilters: readonly DehydratedQuickFilter[];\n sorts: readonly DehydratedSort[];\n userColumnWidths: readonly DehydratedUserColumnWidth[];\n userRowHeights: readonly DehydratedUserRowHeight[];\n customColumns: readonly ColumnName[];\n conditionalFormats: readonly SidebarFormattingRule[];\n reverseType: ReverseType;\n rollupConfig?: UIRollupConfig;\n showSearchBar: boolean;\n searchValue: string;\n selectDistinctColumns: readonly ColumnName[];\n selectedSearchColumns: readonly ColumnName[];\n invertSearchColumns: boolean;\n pendingDataMap: DehydratedPendingDataMap<string | CellData | null>;\n frozenColumns: readonly ColumnName[];\n columnHeaderGroups?: readonly ColumnGroup[];\n}\n\n/**\n * Checks if an index is valid for the given array\n * @param x The index to check\n * @param array The array\n * @returns True if the index if valid within the array\n */\nfunction isValidIndex(x: number, array: readonly unknown[]): boolean {\n return x >= 0 && x < array.length;\n}\n\nfunction isDateWrapper(value: unknown): value is DateWrapper {\n return (value as DateWrapper).asDate != null;\n}\n\nclass IrisGridUtils {\n /**\n * Exports the state from Grid component to a JSON stringifiable object\n * @param model The table model to export the Grid state for\n * @param gridState The state of the Grid to export\n * @returns An object that can be stringified and imported with {{@link hydrateGridState}}\n */\n static dehydrateGridState(\n model: IrisGridModel,\n gridState: Pick<\n IrisGridProps,\n 'isStuckToBottom' | 'isStuckToRight' | 'movedColumns' | 'movedRows'\n >\n ): {\n isStuckToBottom: boolean;\n isStuckToRight: boolean;\n movedColumns: { from: string | [string, string]; to: string }[];\n movedRows: MoveOperation[];\n } {\n const {\n isStuckToBottom,\n isStuckToRight,\n movedColumns,\n movedRows,\n } = gridState;\n\n const { columns } = model;\n\n return {\n isStuckToBottom,\n isStuckToRight,\n movedColumns: [...movedColumns]\n .filter(\n ({ to, from }) =>\n isValidIndex(to, columns) &&\n ((typeof from === 'number' && isValidIndex(from, columns)) ||\n (Array.isArray(from) &&\n isValidIndex(from[0], columns) &&\n isValidIndex(from[1], columns)))\n )\n .map(({ to, from }) => ({\n to: columns[to].name,\n from: Array.isArray(from)\n ? [columns[from[0]].name, columns[from[1]].name]\n : columns[from].name,\n })),\n movedRows: [...movedRows],\n };\n }\n\n /**\n * Import a state for Grid that was exported with {{@link dehydrateGridState}}\n * @param model The table model to import the state for\n * @param gridState The state of the panel that was saved\n * @returns The gridState props to set on the Grid\n */\n static hydrateGridState(\n model: IrisGridModel,\n gridState: {\n isStuckToBottom: boolean;\n isStuckToRight: boolean;\n movedColumns: readonly {\n from: string | [string, string] | ModelIndex | [ModelIndex, ModelIndex];\n to: string | ModelIndex;\n }[];\n movedRows: readonly MoveOperation[];\n },\n customColumns: readonly string[] = []\n ): Pick<\n IrisGridProps,\n 'isStuckToBottom' | 'isStuckToRight' | 'movedColumns' | 'movedRows'\n > {\n const {\n isStuckToBottom,\n isStuckToRight,\n movedColumns,\n movedRows,\n } = gridState;\n\n const { columns } = model;\n const customColumnNames = IrisGridUtils.parseCustomColumnNames(\n customColumns\n );\n const columnNames = columns\n .map(({ name }) => name)\n .concat(customColumnNames);\n\n return {\n isStuckToBottom,\n isStuckToRight,\n movedColumns: [...movedColumns]\n .map(({ to, from }) => {\n const getIndex = (x: string | number) =>\n typeof x === 'string'\n ? columnNames.findIndex(name => name === x)\n : x;\n\n return {\n to: getIndex(to),\n from: Array.isArray(from)\n ? ([getIndex(from[0]), getIndex(from[1])] as [number, number])\n : getIndex(from),\n };\n })\n .filter(\n ({ to, from }) =>\n isValidIndex(to, columnNames) &&\n ((typeof from === 'number' && isValidIndex(from, columnNames)) ||\n (Array.isArray(from) &&\n isValidIndex(from[0], columnNames) &&\n isValidIndex(from[1], columnNames)))\n ),\n movedRows: [...movedRows],\n };\n }\n\n /**\n * Export the IrisGridPanel state.\n * @param model The table model the state is being dehydrated with\n * @param irisGridPanelState The current IrisGridPanel state\n * @returns The dehydrated IrisGridPanel state\n */\n static dehydrateIrisGridPanelState(\n model: IrisGridModel,\n irisGridPanelState: {\n // This needs to be changed after IrisGridPanel is done\n isSelectingPartition: boolean;\n partition: string | undefined;\n partitionColumn: Column | undefined;\n advancedSettings: Map<AdvancedSettingsType, boolean>;\n }\n ): {\n isSelectingPartition: boolean;\n partition: string | undefined;\n partitionColumn: ColumnName | undefined;\n advancedSettings: [AdvancedSettingsType, boolean][];\n } {\n const {\n isSelectingPartition,\n partition,\n partitionColumn,\n advancedSettings,\n } = irisGridPanelState;\n\n return {\n isSelectingPartition,\n partition,\n partitionColumn:\n partitionColumn != null ? partitionColumn.name : undefined,\n advancedSettings: [...advancedSettings],\n };\n }\n\n /**\n * Import the saved IrisGridPanel state.\n * @param model The model the state is being hydrated with\n * @param irisGridPanelState Exported IrisGridPanel state\n * @returns The state to apply to the IrisGridPanel\n */\n static hydrateIrisGridPanelState(\n model: IrisGridModel,\n irisGridPanelState: {\n // This needs to be changed after IrisGridPanel is done\n isSelectingPartition: boolean;\n partition: string | undefined;\n partitionColumn: ColumnName | undefined;\n advancedSettings: [AdvancedSettingsType, boolean][];\n }\n ): {\n isSelectingPartition: boolean;\n partition?: string;\n partitionColumn?: Column;\n advancedSettings: Map<AdvancedSettingsType, boolean>;\n } {\n const {\n isSelectingPartition,\n partition,\n partitionColumn,\n advancedSettings,\n } = irisGridPanelState;\n\n const { columns } = model;\n return {\n isSelectingPartition,\n partition,\n partitionColumn:\n partitionColumn != null\n ? IrisGridUtils.getColumnByName(columns, partitionColumn)\n : undefined,\n advancedSettings: new Map([\n ...AdvancedSettings.DEFAULTS,\n ...advancedSettings,\n ]),\n };\n }\n\n /**\n * Export the quick filters to JSON striginfiable object\n * @param quickFilters The quick filters to dehydrate\n * @returns The dehydrated quick filters\n */\n static dehydrateQuickFilters(\n quickFilters: ReadonlyQuickFilterMap\n ): DehydratedQuickFilter[] {\n return [...quickFilters].map(([columnIndex, quickFilter]) => {\n const { text } = quickFilter;\n return [columnIndex, { text }];\n });\n }\n\n static dehydrateLong<T>(value: T): string | null {\n return value != null ? `${value}` : null;\n }\n\n /**\n * Export the sorts from the provided table sorts to JSON stringifiable object\n * @param sorts The table sorts\n * @returns The dehydrated sorts\n */\n static dehydrateSort(sorts: readonly Sort[]): DehydratedSort[] {\n return sorts.map(sort => {\n const { column, isAbs, direction } = sort;\n return {\n column: column.name,\n isAbs,\n direction,\n };\n });\n }\n\n /**\n * Pulls just the table settings from the panel state, eg. filters/sorts\n * @param panelState The dehydrated panel state\n * @returns A dehydrated table settings object, { partition, partitionColumn, advancedFilters, quickFilters, sorts }\n */\n static extractTableSettings<AF, QF, S>(\n panelState: {\n irisGridState: { advancedFilters: AF; quickFilters: QF; sorts: S };\n irisGridPanelState: {\n partitionColumn?: ColumnName;\n partition?: unknown;\n };\n },\n inputFilters: InputFilter[] = []\n ): {\n partitionColumn: ColumnName | undefined;\n partition: unknown;\n advancedFilters: AF;\n inputFilters: InputFilter[];\n quickFilters: QF;\n sorts: S;\n } {\n const { irisGridPanelState, irisGridState } = panelState;\n const { partitionColumn, partition } = irisGridPanelState;\n const { advancedFilters, quickFilters, sorts } = irisGridState;\n\n return {\n advancedFilters,\n inputFilters,\n partition,\n partitionColumn,\n quickFilters,\n sorts,\n };\n }\n\n static getInputFiltersForColumns(\n columns: readonly Column[],\n inputFilters: readonly InputFilter[] = []\n ): InputFilter[] {\n return inputFilters.filter(({ name, type }) =>\n columns.find(\n ({ name: columnName, type: columnType }) =>\n columnName === name && columnType === type\n )\n );\n }\n\n static getFiltersFromFilterMap(\n filterMap: ReadonlyAdvancedFilterMap | ReadonlyQuickFilterMap\n ): FilterCondition[] {\n const filters = [];\n\n const keys = Array.from(filterMap.keys());\n for (let i = 0; i < keys.length; i += 1) {\n const key = keys[i];\n const item = filterMap.get(key);\n if (item?.filter != null) {\n filters.push(item.filter);\n }\n }\n\n return filters;\n }\n\n /**\n * Get array of hidden column indexes\n * @param userColumnWidths Map of user column widths\n * @returns Array of hidden column indexes\n */\n static getHiddenColumns(userColumnWidths: ModelSizeMap): ModelIndex[] {\n return [...userColumnWidths.entries()]\n .filter(([, value]) => value === 0)\n .map(([key]) => key);\n }\n\n static parseCustomColumnNames(\n customColumns: readonly ColumnName[]\n ): ColumnName[] {\n return customColumns.map(customColumn => customColumn.split('=')[0]);\n }\n\n static getRemovedCustomColumnNames(\n oldCustomColumns: readonly ColumnName[],\n customColumns: readonly ColumnName[]\n ): ColumnName[] {\n const oldCustomColumnsNames = IrisGridUtils.parseCustomColumnNames(\n oldCustomColumns\n );\n const customColumnNames = IrisGridUtils.parseCustomColumnNames(\n customColumns\n );\n return oldCustomColumnsNames.filter(\n oldCustomColumnName => !customColumnNames.includes(oldCustomColumnName)\n );\n }\n\n static removeSortsInColumns(\n sorts: readonly Sort[],\n columnNames: readonly string[]\n ): Sort[] {\n return sorts.filter(sort => !columnNames.includes(sort.column.name));\n }\n\n static removeFiltersInColumns<T>(\n columns: readonly Column[],\n filters: ReadonlyMap<number, T>,\n removedColumnNames: readonly ColumnName[]\n ): Map<number, T> {\n const columnNames = columns.map(({ name }) => name);\n const newFilter = new Map(filters);\n removedColumnNames.forEach(columnName =>\n newFilter.delete(columnNames.indexOf(columnName))\n );\n return newFilter;\n }\n\n static removeColumnFromMovedColumns(\n columns: readonly Column[],\n movedColumns: readonly MoveOperation[],\n removedColumnNames: readonly ColumnName[]\n ): MoveOperation[] {\n const columnNames = columns.map(({ name }) => name);\n let newMoves = [...movedColumns];\n for (let i = 0; i < removedColumnNames.length; i += 1) {\n const removedColumnName = removedColumnNames[i];\n let removedColumnIndex = columnNames.findIndex(\n name => name === removedColumnName\n );\n const moves: MoveOperation[] = [];\n for (let j = 0; j < newMoves.length; j += 1) {\n const move = newMoves[j];\n const newMove = { ...move };\n let [fromStart, fromEnd] = Array.isArray(move.from)\n ? move.from\n : [move.from, move.from];\n\n if (removedColumnIndex <= move.to) {\n newMove.to -= 1;\n }\n\n // If equal to fromStart, the new fromStart would stay the same\n // It's just the next element in the range which will have the same index after deletion\n if (removedColumnIndex < fromStart) {\n fromStart -= 1;\n }\n\n if (removedColumnIndex <= fromEnd) {\n fromEnd -= 1;\n }\n\n if (fromStart <= fromEnd && fromStart !== newMove.to) {\n if (fromStart === fromEnd) {\n moves.push({ ...newMove, from: fromStart });\n } else {\n moves.push({ ...newMove, from: [fromStart, fromEnd] });\n }\n }\n\n // get the next index of the removed column after the move is applied\n // eslint-disable-next-line prefer-destructuring\n removedColumnIndex = GridUtils.applyItemMoves(\n removedColumnIndex,\n removedColumnIndex,\n [move]\n )[0][0];\n }\n\n newMoves = moves;\n columnNames.splice(\n columnNames.findIndex(name => name === removedColumnName),\n 1\n );\n }\n return newMoves;\n }\n\n static removeColumnsFromSelectDistinctColumns(\n selectDistinctColumns: readonly ColumnName[],\n removedColumnNames: readonly ColumnName[]\n ): ColumnName[] {\n return selectDistinctColumns.filter(\n columnName => !removedColumnNames.includes(columnName)\n );\n }\n\n static getVisibleColumnsInRange(\n tableColumns: readonly Column[],\n left: number,\n right: number,\n movedColumns: readonly MoveOperation[],\n hiddenColumns: readonly number[]\n ): Column[] {\n const columns: Column[] = [];\n for (let i = left; i <= right; i += 1) {\n const modelIndex = GridUtils.getModelIndex(i, movedColumns);\n if (\n modelIndex >= 0 &&\n modelIndex < tableColumns.length &&\n !hiddenColumns.includes(modelIndex)\n ) {\n columns.push(tableColumns[modelIndex]);\n }\n }\n return columns;\n }\n\n static getPrevVisibleColumns(\n tableColumns: readonly Column[],\n startIndex: VisibleIndex,\n count: number,\n movedColumns: readonly MoveOperation[],\n hiddenColumns: readonly VisibleIndex[]\n ): Column[] {\n const columns = [];\n let i = startIndex;\n while (i >= 0 && columns.length < count) {\n const modelIndex = GridUtils.getModelIndex(i, movedColumns);\n if (\n modelIndex >= 0 &&\n modelIndex < tableColumns.length &&\n !hiddenColumns.includes(modelIndex)\n ) {\n columns.unshift(tableColumns[modelIndex]);\n }\n i -= 1;\n }\n return columns;\n }\n\n static getNextVisibleColumns(\n tableColumns: readonly Column[],\n startIndex: VisibleIndex,\n count: number,\n movedColumns: readonly MoveOperation[],\n hiddenColumns: readonly VisibleIndex[]\n ): Column[] {\n const columns = [];\n let i = startIndex;\n while (i < tableColumns.length && columns.length < count) {\n const modelIndex = GridUtils.getModelIndex(i, movedColumns);\n if (\n modelIndex >= 0 &&\n modelIndex < tableColumns.length &&\n !hiddenColumns.includes(modelIndex)\n ) {\n columns.push(tableColumns[modelIndex]);\n }\n i += 1;\n }\n return columns;\n }\n\n static getColumnsToFetch(\n tableColumns: readonly Column[],\n viewportColumns: readonly Column[],\n alwaysFetchColumnNames: readonly ColumnName[]\n ): Column[] {\n const columnsToFetch = [...viewportColumns];\n alwaysFetchColumnNames.forEach(columnName => {\n const column = tableColumns.find(({ name }) => name === columnName);\n if (column != null && !viewportColumns.includes(column)) {\n columnsToFetch.push(column);\n }\n });\n return columnsToFetch;\n }\n\n static getModelViewportColumns(\n columns: readonly Column[],\n left: number | null,\n right: number | null,\n movedColumns: readonly MoveOperation[],\n hiddenColumns: readonly VisibleIndex[] = [],\n alwaysFetchColumnNames: readonly ColumnName[] = [],\n bufferPages = 0\n ): Column[] | null {\n if (left == null || right == null) {\n return null;\n }\n\n const columnsCenter = IrisGridUtils.getVisibleColumnsInRange(\n columns,\n left,\n right,\n movedColumns,\n hiddenColumns\n );\n const bufferWidth = columnsCenter.length * bufferPages;\n const columnsLeft = IrisGridUtils.getPrevVisibleColumns(\n columns,\n left - 1,\n bufferWidth,\n movedColumns,\n hiddenColumns\n );\n const columnsRight = IrisGridUtils.getNextVisibleColumns(\n columns,\n right + 1,\n bufferWidth,\n movedColumns,\n hiddenColumns\n );\n\n const bufferedColumns = [...columnsLeft, ...columnsCenter, ...columnsRight];\n\n return IrisGridUtils.getColumnsToFetch(\n columns,\n bufferedColumns,\n alwaysFetchColumnNames\n );\n }\n\n /**\n * Validate whether the ranges passed in are valid to take a snapshot from.\n * Multiple selections are valid if all of the selected rows have the same columns selected.\n *\n * @param ranges The ranges to validate\n * @returns True if the ranges are valid, false otherwise\n */\n static isValidSnapshotRanges(ranges: readonly GridRange[]): boolean {\n if (ranges == null || ranges.length === 0) {\n return false;\n }\n\n // To verify all the rows selected have the same set of columns selected, build a map with string representations\n // of each range.\n const rangeMap = new Map();\n for (let i = 0; i < ranges.length; i += 1) {\n const range = ranges[i];\n const rowMapIndex = `${range.startRow}:${range.endRow}`;\n const columnMapIndex = `${range.startColumn}:${range.endColumn}`;\n if (!rangeMap.has(rowMapIndex)) {\n rangeMap.set(rowMapIndex, []);\n }\n rangeMap.get(rowMapIndex).push(columnMapIndex);\n }\n\n const keys = [...rangeMap.keys()];\n const matchColumnRanges = rangeMap.get(keys[0]).sort().join(',');\n for (let i = 1; i < keys.length; i += 1) {\n if (rangeMap.get(keys[i]).sort().join(',') !== matchColumnRanges) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Check if the provided value is a valid table index\n * @param value A value to check if it's a valid table index\n */\n static isValidIndex(value: unknown): boolean {\n if (!Number.isInteger(value)) {\n return false;\n }\n if (!(typeof value === 'number')) {\n return false;\n }\n return value >= 0;\n }\n\n /**\n * Returns all columns used in any of the ranges provided\n * @param ranges The model ranges to get columns for\n * @param allColumns All the columns to pull from\n * @returns The columns selected in the range\n */\n static columnsFromRanges(\n ranges: readonly GridRange[],\n allColumns: readonly Column[]\n ): Column[] {\n if (ranges == null || ranges.length === 0) {\n return [];\n }\n if (ranges[0].startColumn === null && ranges[0].endColumn === null) {\n // Snapshot of all the columns\n return [...allColumns];\n }\n\n const columnSet = new Set<ModelIndex>();\n for (let i = 0; i < ranges.length; i += 1) {\n const range = ranges[i];\n assertNotNull(range.startColumn);\n assertNotNull(range.endColumn);\n for (\n let c = range.startColumn ?? 0;\n c <= (range.endColumn ?? allColumns.length - 1);\n c += 1\n ) {\n columnSet.add(c);\n }\n }\n return [...columnSet].map(c => allColumns[c]);\n }\n\n /**\n * Transforms an iris data snapshot into a simple data matrix\n * @param data The Iris formatted table data\n * @returns A matrix of the values of the data\n */\n static snapshotDataToMatrix(data: TableData): unknown[][] {\n const { columns, rows } = data;\n const result = [];\n for (let r = 0; r < rows.length; r += 1) {\n const row = rows[r];\n const rowData = [];\n for (let c = 0; c < columns.length; c += 1) {\n const column = columns[c];\n const value = row.get(column);\n rowData.push(value);\n }\n result.push(rowData);\n }\n return result;\n }\n\n /**\n * Hydrate model rollup config\n * @param originalColumns Original model columns\n * @param config Dehydrated rollup config\n * @param aggregationSettings Aggregation settings\n * @returns Rollup config for the model\n */\n static getModelRollupConfig(\n originalColumns: readonly Column[],\n config: UIRollupConfig | undefined,\n aggregationSettings: AggregationSettings\n ): RollupConfig | null {\n if ((config?.columns?.length ?? 0) === 0) {\n return null;\n }\n\n const {\n columns: groupingColumns = [],\n showConstituents: includeConstituents = true,\n showNonAggregatedColumns = true,\n includeDescriptions = true,\n } = config ?? {};\n const { aggregations = [] } = aggregationSettings ?? {};\n const aggregationColumns = aggregations.map(\n ({ operation, selected, invert }) =>\n AggregationUtils.isRollupOperation(operation)\n ? []\n : AggregationUtils.getOperationColumnNames(\n originalColumns,\n operation,\n selected,\n invert\n )\n );\n\n const aggregationMap = {} as Record<AggregationOperation, string[]>;\n // Aggregation columns should show first, add them first\n for (let i = 0; i < aggregations.length; i += 1) {\n aggregationMap[aggregations[i].operation] = aggregationColumns[i];\n }\n\n if (showNonAggregatedColumns) {\n // Filter out any column that already has an aggregation or grouping\n const nonAggregatedColumnSet = new Set(\n originalColumns\n .map(c => c.name)\n .filter(name => !groupingColumns.includes(name))\n );\n aggregationColumns.forEach(columns => {\n columns.forEach(name => nonAggregatedColumnSet.delete(name));\n });\n\n if (nonAggregatedColumnSet.size > 0) {\n const existingColumns =\n aggregationMap[AggregationOperation.FIRST] ?? [];\n aggregationMap[AggregationOperation.FIRST] = [\n ...existingColumns,\n ...nonAggregatedColumnSet,\n ];\n }\n }\n\n return {\n groupingColumns,\n includeConstituents,\n includeDescriptions,\n aggregations: aggregationMap,\n };\n }\n\n /**\n * @param pendingDataMap Map of pending data\n * @returns A map with the errors in the pending data\n */\n static getPendingErrors(pendingDataMap: Map<number, UIRow>): void {\n pendingDataMap.forEach((row, rowIndex) => {\n if (!IrisGridUtils.isValidIndex(rowIndex)) {\n throw new Error(`Invalid rowIndex ${rowIndex}`);\n }\n\n const { data } = row;\n data.forEach((value, columnIndex) => {\n if (!IrisGridUtils.isValidIndex(columnIndex)) {\n throw new Error(`Invalid columnIndex ${columnIndex}`);\n }\n });\n });\n }\n\n /**\n * Retrieves a column from the provided array at the index, or `null` and logs an error if it's invalid\n *\n * @param columns The columns to get the column from\n * @param columnIndex The column index to get\n */\n static getColumn(\n columns: readonly Column[],\n columnIndex: ModelIndex\n ): Column | null {\n if (columnIndex < columns.length) {\n return columns[columnIndex];\n }\n\n log.error('Unable to retrieve column', columnIndex, '>=', columns.length);\n\n return null;\n }\n\n /**\n * Retrieves a column from the provided array matching the name, or `null` and logs an error if not found\n * @param columns The columns to get the column from\n * @param columnName The column name to retrieve\n */\n static getColumnByName(\n columns: readonly Column[],\n columnName: ColumnName\n ): Column | undefined {\n const column = columns.find(({ name }) => name === columnName);\n if (column == null) {\n log.error(\n 'Unable to retrieve column by name',\n columnName,\n columns.map(({ name }) => name)\n );\n }\n\n return column;\n }\n\n /**\n * Get filter configs with column names changed to indexes, exclude missing columns\n * @param columns The columns to get column indexes from\n * @param filters Filter configs\n * @returns Updated filter configs with column names changed to indexes\n */\n static changeFilterColumnNamesToIndexes<T>(\n columns: readonly Column[],\n filters: { name: ColumnName; filter: T }[]\n ): [number, T][] {\n return filters\n .map(({ name, filter }): null | [number, T] => {\n const index = columns.findIndex(column => column.name === name);\n return index < 0 ? null : [index, filter];\n })\n .filter(filterConfig => filterConfig != null) as [number, T][];\n }\n\n /**\n * @param columnType The column type that the filters will be applied to.\n * @param filterList The list of filters to be combined.\n * @returns The combination of the filters in filterList as text.\n */\n static combineFiltersFromList(\n columnType: string,\n filterList: FilterData[]\n ): string {\n filterList.sort((a, b) => {\n // move all 'equals' comparisons to end of list\n if (a.operator === 'eq' && b.operator !== 'eq') {\n return 1;\n }\n if (a.operator !== 'eq' && b.operator === 'eq') {\n return -1;\n }\n return a.startColumnIndex - b.startColumnIndex;\n });\n\n let combinedText = '';\n for (let i = 0; i < filterList.length; i += 1) {\n const { text, value, operator } = filterList[i];\n if (value !== undefined) {\n let symbol = '';\n if (operator !== undefined) {\n if (value == null && operator === 'eq') {\n symbol = '=';\n } else if (operator !== 'eq') {\n if (operator === 'startsWith' || operator === 'endsWith') {\n symbol = '*';\n } else {\n symbol = TableUtils.getFilterOperatorString(operator);\n }\n }\n }\n\n let filterText = `${symbol}${text}`;\n if (operator === 'startsWith') {\n filterText = `${text}${symbol}`;\n }\n if (\n columnType != null &&\n value !== null &&\n TableUtils.isCharType(columnType)\n ) {\n filterText = `${symbol}${String.fromCharCode(parseInt(text, 10))}`;\n }\n if (i !== 0) {\n combinedText += operator === 'eq' ? ' || ' : ' && ';\n }\n combinedText += filterText;\n }\n }\n return combinedText;\n }\n\n /**\n * Parses the column header groups provided.\n * If undefined, should provide default groups such as from layoutHints\n *\n * @returns Object containing groups array, max depth, map of name to parent group, and map of name to group\n */\n static parseColumnHeaderGroups(\n model: IrisGridModel,\n groupsParam: readonly ColumnGroup[]\n ): {\n groups: ColumnHeaderGroup[];\n maxDepth: number;\n parentMap: Map<string, ColumnHeaderGroup>;\n groupMap: Map<string, ColumnHeaderGroup>;\n } {\n let maxDepth = 1;\n const parentMap: Map<string, ColumnHeaderGroup> = new Map();\n const groupMap: Map<string, ColumnHeaderGroup> = new Map();\n\n // Remove any empty groups before parsing\n const groups = groupsParam?.filter(({ children }) => children.length > 0);\n\n if (groups.length === 0) {\n return { groups: [], maxDepth, parentMap, groupMap };\n }\n\n const originalGroupMap = new Map(groups.map(group => [group.name, group]));\n const seenChildren = new Set<string>();\n\n const addGroup = (group: ColumnGroup): ColumnHeaderGroup => {\n const { name } = group;\n\n if (model.getColumnIndexByName(name) != null) {\n throw new Error(`Column header group has same name as column: ${name}`);\n }\n\n const existingGroup = groupMap.get(name);\n\n if (existingGroup) {\n return existingGroup;\n }\n\n const childIndexes: ColumnHeaderGroup['childIndexes'] = [];\n let depth = 1;\n\n group.children.forEach(childName => {\n if (seenChildren.has(childName)) {\n throw new Error(\n `Column group child ${childName} specified in multiple groups`\n );\n }\n seenChildren.add(childName);\n\n const childGroup = originalGroupMap.get(childName);\n const childIndex = model.getColumnIndexByName(childName);\n if (childGroup) {\n // Adding another column header group\n const addedGroup = addGroup(childGroup);\n childIndexes.push(...addedGroup.childIndexes);\n depth = Math.max(depth, addedGroup.depth + 1);\n } else if (childIndex != null) {\n // Adding a base column\n childIndexes.push(childIndex);\n depth = Math.max(depth, 1);\n } else {\n throw new Error(`Unknown child ${childName} in group ${name}`);\n }\n });\n\n const columnHeaderGroup = new ColumnHeaderGroup({\n ...group,\n depth,\n childIndexes: childIndexes.flat(),\n });\n\n groupMap.set(name, columnHeaderGroup);\n group.children.forEach(childName =>\n parentMap.set(childName, columnHeaderGroup)\n );\n\n maxDepth = Math.max(maxDepth, columnHeaderGroup.depth + 1);\n return columnHeaderGroup;\n };\n\n const groupNames = new Set();\n\n groups.forEach(group => {\n const { name } = group;\n if (groupNames.has(name)) {\n throw new Error(`Duplicate column group name: ${name}`);\n }\n groupNames.add(name);\n addGroup(group);\n });\n\n groupMap.forEach(group => {\n group.setParent(parentMap.get(group.name)?.name);\n });\n\n return { groups: [...groupMap.values()], maxDepth, groupMap, parentMap };\n }\n\n /**\n * @param value The value of the cell in a column\n * @param columnType The type of the column\n * @returns The value of the cell converted to text\n */\n static convertValueToText(value: unknown, columnType: string): string {\n if (\n columnType != null &&\n TableUtils.isCharType(columnType) &&\n value != null &&\n typeof value === 'number'\n ) {\n return String.fromCharCode(value);\n }\n if (TableUtils.isDateType(columnType) && isDateWrapper(value)) {\n const date = new Date(value.asDate());\n const offset = date.getTimezoneOffset();\n const offsetDate = new Date(date.getTime() - offset * 60 * 1000);\n const dateText = offsetDate.toISOString();\n const formattedText = dateText.replace('T', ' ').substring(0, 23);\n return formattedText;\n }\n if (value == null) {\n return '';\n }\n return `${value}`;\n }\n\n private dh: DhType;\n\n private tableUtils: TableUtils;\n\n constructor(dh: DhType) {\n this.dh = dh;\n this.tableUtils = new TableUtils(dh);\n }\n\n /**\n * Exports the state from IrisGrid to a JSON stringifiable object\n * @param model The table model to export the state for\n * @param irisGridState The current state of the IrisGrid\n */\n dehydrateIrisGridState(\n model: IrisGridModel,\n irisGridState: HydratedIrisGridState\n ): DehydratedIrisGridState {\n const {\n aggregationSettings = { aggregations: EMPTY_ARRAY, showOnTop: false },\n advancedFilters,\n customColumnFormatMap,\n isFilterBarShown,\n metrics,\n quickFilters,\n customColumns,\n conditionalFormats = EMPTY_ARRAY,\n reverseType,\n rollupConfig = undefined,\n showSearchBar,\n searchValue,\n selectDistinctColumns = EMPTY_ARRAY,\n selectedSearchColumns,\n sorts,\n invertSearchColumns,\n pendingDataMap = EMPTY_MAP,\n frozenColumns,\n columnHeaderGroups,\n } = irisGridState;\n assertNotNull(metrics);\n const { userColumnWidths, userRowHeights } = metrics;\n const { columns } = model;\n return {\n advancedFilters: this.dehydrateAdvancedFilters(columns, advancedFilters),\n aggregationSettings,\n customColumnFormatMap: [...customColumnFormatMap],\n isFilterBarShown,\n quickFilters: IrisGridUtils.dehydrateQuickFilters(quickFilters),\n sorts: IrisGridUtils.dehydrateSort(sorts),\n userColumnWidths: [...userColumnWidths]\n .filter(\n ([columnIndex]) =>\n columnIndex != null &&\n columnIndex >= 0 &&\n columnIndex < columns.length\n )\n .map(([columnIndex, width]) => [columns[columnIndex].name, width]),\n userRowHeights: [...userRowHeights],\n customColumns: [...customColumns],\n conditionalFormats: [...conditionalFormats],\n reverseType,\n rollupConfig,\n showSearchBar,\n searchValue,\n selectDistinctColumns: [...selectDistinctColumns],\n selectedSearchColumns,\n invertSearchColumns,\n pendingDataMap: this.dehydratePendingDataMap(columns, pendingDataMap),\n frozenColumns,\n columnHeaderGroups: columnHeaderGroups?.map(item => ({\n name: item.name,\n children: item.children,\n color: item.color,\n })),\n };\n }\n\n /**\n * Import a state for IrisGrid that was exported with {{@link dehydrateIrisGridState}}\n * @param model The table model to import the state with\n * @param irisGridState The saved IrisGrid state\n */\n hydrateIrisGridState(\n model: IrisGridModel,\n irisGridState: DehydratedIrisGridState\n ): Omit<HydratedIrisGridState, 'metrics'> & {\n userColumnWidths: ModelSizeMap;\n userRowHeights: ModelSizeMap;\n } {\n const {\n advancedFilters,\n aggregationSettings = { aggregations: [], showOnTop: false },\n customColumnFormatMap,\n isFilterBarShown,\n quickFilters,\n sorts,\n customColumns,\n conditionalFormats,\n userColumnWidths,\n userRowHeights,\n reverseType,\n rollupConfig = undefined,\n showSearchBar,\n searchValue,\n selectDistinctColumns,\n selectedSearchColumns,\n invertSearchColumns = true,\n pendingDataMap = [],\n frozenColumns,\n columnHeaderGroups,\n } = irisGridState;\n const { columns, formatter } = model;\n\n return {\n advancedFilters: this.hydrateAdvancedFilters(\n columns,\n advancedFilters,\n formatter.timeZone\n ),\n aggregationSettings,\n customColumnFormatMap: new Map(customColumnFormatMap),\n isFilterBarShown,\n quickFilters: this.hydrateQuickFilters(\n columns,\n quickFilters,\n formatter.timeZone\n ),\n sorts: this.hydrateSort(columns, sorts),\n userColumnWidths: new Map(\n userColumnWidths\n .map(([column, width]: [string | number, number]): [\n number,\n number\n ] => {\n if (\n typeof column === 'string' ||\n (column as unknown) instanceof String\n ) {\n return [columns.findIndex(({ name }) => name === column), width];\n }\n return [column, width];\n })\n .filter(\n ([column]) =>\n column != null && column >= 0 && column < columns.length\n )\n ),\n customColumns,\n conditionalFormats,\n userRowHeights: new Map(userRowHeights),\n reverseType,\n rollupConfig,\n showSearchBar,\n searchValue,\n selectDistinctColumns,\n selectedSearchColumns,\n invertSearchColumns,\n pendingDataMap: this.hydratePendingDataMap(\n columns,\n pendingDataMap\n ) as PendingDataMap<UIRow>,\n frozenColumns,\n columnHeaderGroups: IrisGridUtils.parseColumnHeaderGroups(\n model,\n columnHeaderGroups ?? model.layoutHints?.columnGroups ?? []\n ).groups,\n };\n }\n\n /**\n * Import the saved quick filters to apply to the columns. Does not actually apply the filters.\n * @param columns The columns the filters will be applied to\n * @param savedQuickFilters Exported quick filters definitions\n * @param timeZone The time zone to make this value in if it is a date type. E.g. America/New_York\n * @returns The quick filters to apply to the columns\n */\n hydrateQuickFilters(\n columns: readonly Column[],\n savedQuickFilters: readonly DehydratedQuickFilter[],\n timeZone?: string\n ): ReadonlyQuickFilterMap {\n const importedFilters = savedQuickFilters.map(\n ([columnIndex, quickFilter]: DehydratedQuickFilter): [\n number,\n { text: string; filter: FilterCondition | null }\n ] => {\n const { text } = quickFilter;\n\n let filter = null;\n try {\n const column = IrisGridUtils.getColumn(columns, columnIndex);\n if (column != null) {\n filter = this.tableUtils.makeQuickFilter(column, text, timeZone);\n }\n } catch (error) {\n log.error('hydrateQuickFilters error with', text, error);\n }\n\n return [columnIndex, { text, filter }];\n }\n );\n\n return new Map(importedFilters);\n }\n\n /**\n * Export the advanced filters from the provided columns to JSON striginfiable object\n * @param columns The columns for the filters\n * @param advancedFilters The advanced filters to dehydrate\n * @returns The dehydrated advanced filters\n */\n dehydrateAdvancedFilters(\n columns: readonly Column[],\n advancedFilters: ReadonlyAdvancedFilterMap\n ): DehydratedAdvancedFilter[] {\n return [...advancedFilters].map(([columnIndex, advancedFilter]) => {\n const column = IrisGridUtils.getColumn(columns, columnIndex);\n assertNotNull(column);\n const options = this.dehydrateAdvancedFilterOptions(\n column,\n advancedFilter.options\n );\n return [columnIndex, { options }];\n });\n }\n\n /**\n * Import the saved advanced filters to apply to the columns. Does not actually apply the filters.\n * @param columns The columns the filters will be applied to\n * @param savedAdvancedFilters Exported advanced filters definitions\n * @param timeZone The time zone to make this filter in if it is a date type. E.g. America/New_York\n * @returns The advanced filters to apply to the columns\n */\n hydrateAdvancedFilters(\n columns: readonly Column[],\n savedAdvancedFilters: readonly DehydratedAdvancedFilter[],\n timeZone: string\n ): ReadonlyAdvancedFilterMap {\n const importedFilters = savedAdvancedFilters.map(\n ([columnIndex, advancedFilter]: DehydratedAdvancedFilter): [\n number,\n { options: AdvancedFilterOptions; filter: FilterCondition | null }\n ] => {\n const column = IrisGridUtils.getColumn(columns, columnIndex);\n assertNotNull(column);\n const options = this.hydrateAdvancedFilterOptions(\n column,\n advancedFilter.options\n );\n let filter = null;\n\n try {\n const columnRetrieved = IrisGridUtils.getColumn(columns, columnIndex);\n if (columnRetrieved != null) {\n filter = this.tableUtils.makeAdvancedFilter(\n column,\n options,\n timeZone\n );\n }\n } catch (error) {\n log.error('hydrateAdvancedFilters error with', options, error);\n }\n\n return [columnIndex, { options, filter }];\n }\n );\n\n return new Map(importedFilters);\n }\n\n dehydrateAdvancedFilterOptions(\n column: Column,\n options: AdvancedFilterOptions\n ): AdvancedFilterOptions {\n const { selectedValues, ...otherOptions } = options;\n return {\n selectedValues: selectedValues?.map((value: unknown) =>\n this.dehydrateValue(value, column?.type)\n ),\n ...otherOptions,\n };\n }\n\n hydrateAdvancedFilterOptions(\n column: Column,\n options: AdvancedFilterOptions\n ): AdvancedFilterOptions {\n const { selectedValues, ...otherOptions } = options;\n return {\n selectedValues: selectedValues?.map(value =>\n this.hydrateValue(value, column?.type)\n ),\n ...otherOptions,\n };\n }\n\n dehydratePendingDataMap(\n columns: readonly Column[],\n pendingDataMap: ReadonlyMap<\n ModelIndex,\n {\n data: Map<ModelIndex, CellData | string>;\n }\n >\n ): DehydratedPendingDataMap<CellData | string | null> {\n return [...pendingDataMap].map(([rowIndex, { data }]) => [\n rowIndex,\n {\n data: [...data].map(([c, value]) => [\n columns[c].name,\n this.dehydrateValue(value, columns[c].type),\n ]),\n },\n ]);\n }\n\n hydratePendingDataMap(\n columns: readonly Column[],\n pendingDataMap: DehydratedPendingDataMap<CellData | string | null>\n ): Map<\n number,\n { data: Map<ModelIndex | null, string | CellData | LongWrapper | null> }\n > {\n const columnMap = new Map<ColumnName, number>();\n const getColumnIndex = (columnName: ColumnName) => {\n if (!columnMap.has(columnName)) {\n columnMap.set(\n columnName,\n columns.findIndex(({ name }) => name === columnName)\n );\n }\n return columnMap.get(columnName);\n };\n\n return new Map(\n pendingDataMap.map(\n ([rowIndex, { data }]: [\n number,\n { data: [string, CellData | string | null][] }\n ]) => [\n rowIndex,\n {\n data: new Map(\n data.map(([columnName, value]) => {\n const index = getColumnIndex(columnName);\n assertNotNull(index);\n return [\n getColumnIndex(columnName) ?? null,\n this.hydrateValue(value, columns[index].type),\n ];\n })\n ),\n },\n ]\n )\n );\n }\n\n /**\n * Dehydrates/serializes a value for storage.\n * @param value The value to dehydrate\n * @param columnType The column type\n */\n dehydrateValue<T>(value: T, columnType: string): string | T | null {\n if (TableUtils.isDateType(columnType)) {\n return this.dehydrateDateTime(\n (value as unknown) as number | DateWrapper | Date\n );\n }\n\n if (TableUtils.isLongType(columnType)) {\n return IrisGridUtils.dehydrateLong(value);\n }\n\n return value;\n }\n\n /**\n * Hydrate a value from it's serialized state\n * @param value The dehydrated value that needs to be hydrated\n * @param columnType The type of column\n */\n hydrateValue<T>(\n value: T,\n columnType: string\n ): DateWrapper | LongWrapper | T | null {\n if (TableUtils.isDateType(columnType)) {\n return this.hydrateDateTime((value as unknown) as string);\n }\n\n if (TableUtils.isLongType(columnType)) {\n return this.hydrateLong((value as unknown) as string);\n }\n\n return value;\n }\n\n dehydrateDateTime(value: number | DateWrapper | Date): string | null {\n return value != null\n ? this.dh.i18n.DateTimeFormat.format(DateUtils.FULL_DATE_FORMAT, value)\n : null;\n }\n\n hydrateDateTime(value: string): DateWrapper | null {\n return value != null\n ? this.dh.i18n.DateTimeFormat.parse(DateUtils.FULL_DATE_FORMAT, value)\n : null;\n }\n\n hydrateLong(value: string): LongWrapper | null {\n return value != null ? this.dh.LongWrapper.ofString(value) : null;\n }\n\n /**\n * Import the saved sorts to apply to the table. Does not actually apply the sort.\n * @param columns The columns the sorts will be applied to\n * @param sorts Exported sort definitions\n * @returns The sorts to apply to the table\n */\n hydrateSort(\n columns: readonly Column[],\n sorts: readonly (DehydratedSort | LegacyDehydratedSort)[]\n ): Sort[] {\n const { dh } = this;\n return (\n sorts\n .map(sort => {\n const { column: columnIndexOrName, isAbs, direction } = sort;\n if (direction === TableUtils.sortDirection.reverse) {\n return dh.Table.reverse();\n }\n\n const column =\n typeof columnIndexOrName === 'string'\n ? IrisGridUtils.getColumnByName(columns, columnIndexOrName)\n : IrisGridUtils.getColumn(columns, columnIndexOrName);\n\n if (column != null) {\n let columnSort = column.sort();\n if (isAbs) {\n columnSort = columnSort.abs();\n }\n if (direction === TableUtils.sortDirection.descending) {\n columnSort = columnSort.desc();\n } else {\n columnSort = columnSort.asc();\n }\n return columnSort;\n }\n\n return null;\n })\n // If we can't find the column any more, it's null, filter it out\n // If the item is a reverse sort item, filter it out - it will get applied with the `reverseType` property\n // This should only happen when loading a legacy dashboard\n .filter(\n item =>\n item != null && item.direction !== TableUtils.sortDirection.reverse\n ) as Sort[]\n );\n }\n\n /**\n * Applies the passed in table settings directly to the provided table\n * @param table The table to apply the settings to\n * @param tableSettings Dehydrated table settings extracted with `extractTableSettings`\n * @param timeZone The time zone to make this value in if it is a date type. E.g. America/New_York\n */\n applyTableSettings(\n table: Table,\n tableSettings: TableSettings,\n timeZone: string\n ): void {\n const { columns } = table;\n\n let quickFilters: FilterCondition[] = [];\n if (tableSettings.quickFilters) {\n quickFilters = IrisGridUtils.getFiltersFromFilterMap(\n this.hydrateQuickFilters(columns, tableSettings.quickFilters, timeZone)\n );\n }\n\n let advancedFilters: FilterCondition[] = [];\n if (tableSettings.advancedFilters) {\n advancedFilters = IrisGridUtils.getFiltersFromFilterMap(\n this.hydrateAdvancedFilters(\n columns,\n tableSettings.advancedFilters,\n timeZone\n )\n );\n }\n const inputFilters = this.getFiltersFromInputFilters(\n columns,\n tableSettings.inputFilters,\n timeZone\n );\n\n let sorts: Sort[] = [];\n if (tableSettings.sorts) {\n sorts = this.hydrateSort(columns, tableSettings.sorts);\n }\n\n let filters = [...quickFilters, ...advancedFilters];\n const { partition, partitionColumn: partitionColumnName } = tableSettings;\n if (partition != null && partitionColumnName != null) {\n const partitionColumn = IrisGridUtils.getColumnByName(\n columns,\n partitionColumnName\n );\n if (partitionColumn) {\n const partitionFilter = partitionColumn\n .filter()\n .eq(this.dh.FilterValue.ofString(partition));\n filters = [partitionFilter, ...filters];\n }\n }\n filters = [...inputFilters, ...filters];\n\n table.applyFilter(filters);\n table.applySort(sorts);\n }\n\n getFiltersFromInputFilters(\n columns: readonly Column[],\n inputFilters: readonly InputFilter[] = [],\n timeZone?: string\n ): FilterCondition[] {\n return inputFilters\n .map(({ name, type, value }) => {\n const column = columns.find(\n ({ name: columnName, type: columnType }) =>\n columnName === name && columnType === type\n );\n if (column) {\n try {\n return this.tableUtils.makeQuickFilter(column, value, timeZone);\n } catch (e) {\n // It may be unable to create it because user hasn't completed their input\n log.debug('Unable to create input filter', e);\n }\n }\n\n return null;\n })\n .filter(filter => filter != null) as FilterCondition[];\n }\n\n /**\n * Get the dh.RangeSet representation of the provided ranges.\n * Ranges are sorted prior to creating the RangeSet. Only the rows are taken into account,\n * RangeSet does not have an option for columns.\n * @param ranges The ranges to get the range set for\n * @returns The rangeset for the provided ranges\n */\n rangeSetFromRanges(ranges: readonly GridRange[]): RangeSet {\n const { dh } = this;\n const rangeSets = ranges\n .slice()\n .sort((a, b): number => {\n assertNotNull(a.startRow);\n assertNotNull(b.startRow);\n return a.startRow - b.startRow;\n })\n .map(range => {\n const { startRow, endRow } = range;\n assertNotNull(startRow);\n assertNotNull(endRow);\n return dh.RangeSet.ofRange(startRow, endRow);\n });\n return dh.RangeSet.ofRanges(rangeSets);\n }\n}\n\nexport default IrisGridUtils;\n","import React, { Component } from 'react';\nimport classNames from 'classnames';\nimport { CSSTransition } from 'react-transition-group';\nimport { Button, LoadingSpinner, ThemeExport } from '@deephaven/components';\nimport {\n GridRange,\n GridUtils,\n ModelSizeMap,\n MoveOperation,\n} from '@deephaven/grid';\nimport {\n CancelablePromise,\n CanceledPromiseError,\n copyToClipboard,\n PromiseUtils,\n} from '@deephaven/utils';\nimport Log from '@deephaven/log';\nimport type { Column } from '@deephaven/jsapi-types';\nimport IrisGridUtils from './IrisGridUtils';\nimport IrisGridBottomBar from './IrisGridBottomBar';\nimport './IrisGridCopyHandler.scss';\nimport IrisGridModel from './IrisGridModel';\n\nconst log = Log.module('IrisGridCopyHandler');\n\ntype Values<T> = T[keyof T];\n\ntype ButtonStateType = Values<typeof IrisGridCopyHandler.BUTTON_STATES>;\n\nexport type CopyOperation = {\n ranges: readonly GridRange[];\n includeHeaders: boolean;\n formatValues?: boolean;\n movedColumns: readonly MoveOperation[];\n userColumnWidths: ModelSizeMap;\n error?: string;\n};\n\ninterface IrisGridCopyHandlerProps {\n model: IrisGridModel;\n copyOperation: CopyOperation;\n onEntering: () => void;\n onEntered: () => void;\n onExiting: () => void;\n onExited: () => void;\n}\n\ninterface IrisGridCopyHandlerState {\n error?: string;\n copyState: string;\n buttonState: string;\n isShown: boolean;\n rowCount: number;\n}\n/**\n * Component for handling copying of data from the Iris Grid.\n * - Prompts if necessary (large amount of rows copied)\n * - Tries to async copy, falls back to showing a \"Click to Copy\" button if that fails\n */\nclass IrisGridCopyHandler extends Component<\n IrisGridCopyHandlerProps,\n IrisGridCopyHandlerState\n> {\n static NO_PROMPT_THRESHOLD = 10000;\n\n static HIDE_TIMEOUT = 3000;\n\n /**\n * Different states for the current copy operation\n */\n static COPY_STATES = {\n // No copy operation in progress\n IDLE: 'IDLE',\n\n // Large copy operation, confirmation required\n CONFIRMATION_REQUIRED: 'CONFIRMATION_REQUIRED',\n\n // Fetch is currently in progress\n FETCH_IN_PROGRESS: 'FETCH_IN_PROGRESS',\n\n // There was an error fetching the data\n FETCH_ERROR: 'FETCH_ERROR',\n\n // Click is required to copy\n CLICK_REQUIRED: 'CLICK_REQUIRED',\n\n // The copy operation is completed and successfully copied to the clipboard\n DONE: 'DONE',\n };\n\n static BUTTON_STATES = {\n COPY: 'COPY',\n FETCH_IN_PROGRESS: 'FETCH_IN_PROGRESS',\n CLICK_TO_COPY: 'CLICK_TO_COPY',\n RETRY: 'RETRY',\n };\n\n static defaultProps = {\n copyOperation: null,\n onEntering: (): void => undefined,\n onEntered: (): void => undefined,\n onExiting: (): void => undefined,\n onExited: (): void => undefined,\n };\n\n static getStatusMessageText(copyState: string, rowCount: number): string {\n switch (copyState) {\n case IrisGridCopyHandler.COPY_STATES.CONFIRMATION_REQUIRED:\n return `Are you sure you want to copy ${rowCount.toLocaleString()} rows to your clipboard?`;\n case IrisGridCopyHandler.COPY_STATES.CLICK_REQUIRED:\n return `Fetched ${rowCount.toLocaleString()} rows!`;\n case IrisGridCopyHandler.COPY_STATES.FETCH_ERROR:\n return 'Unable to copy data.';\n case IrisGridCopyHandler.COPY_STATES.FETCH_IN_PROGRESS:\n return `Fetching ${rowCount.toLocaleString()} rows for clipboard...`;\n case IrisGridCopyHandler.COPY_STATES.DONE:\n return 'Copied to Clipboard!';\n default:\n return '';\n }\n }\n\n static getCopyButtonText(buttonState: ButtonStateType): string {\n switch (buttonState) {\n case IrisGridCopyHandler.BUTTON_STATES.FETCH_IN_PROGRESS:\n return 'Fetching';\n case IrisGridCopyHandler.BUTTON_STATES.CLICK_TO_COPY:\n return 'Click to Copy';\n case IrisGridCopyHandler.BUTTON_STATES.RETRY:\n return 'Retry';\n default:\n return 'Copy';\n }\n }\n\n constructor(props: IrisGridCopyHandlerProps) {\n super(props);\n\n this.handleBackgroundClick = this.handleBackgroundClick.bind(this);\n this.handleCancelClick = this.handleCancelClick.bind(this);\n this.handleCopyClick = this.handleCopyClick.bind(this);\n this.handleHideTimeout = this.handleHideTimeout.bind(this);\n\n this.state = {\n error: undefined,\n copyState: IrisGridCopyHandler.COPY_STATES.IDLE,\n buttonState: IrisGridCopyHandler.BUTTON_STATES.COPY,\n isShown: false,\n rowCount: 0,\n };\n }\n\n componentDidMount(): void {\n const { copyOperation } = this.props;\n if (copyOperation != null) {\n this.startCopy();\n }\n }\n\n componentDidUpdate(prevProps: IrisGridCopyHandlerProps): void {\n const { copyOperation } = this.props;\n if (prevProps.copyOperation !== copyOperation) {\n this.startCopy();\n }\n }\n\n componentWillUnmount(): void {\n this.stopCopy();\n }\n\n textData?: string;\n\n hideTimer?: ReturnType<typeof setTimeout>;\n\n fetchPromise?: CancelablePromise<string>;\n\n startCopy(): void {\n log.debug2('startCopy');\n\n this.stopCopy();\n\n const { copyOperation } = this.props;\n if (copyOperation == null) {\n log.debug2('No copy operation set, cancelling out');\n this.setState({ isShown: false });\n return;\n }\n\n const { ranges, error } = copyOperation;\n if (error != null) {\n log.debug('Showing copy error', error);\n this.setState({\n isShown: true,\n copyState: IrisGridCopyHandler.COPY_STATES.DONE,\n error,\n });\n this.startHideTimer();\n return;\n }\n\n const rowCount = GridRange.rowCount(ranges);\n\n this.setState({ rowCount, isShown: true, error: undefined });\n\n if (rowCount > IrisGridCopyHandler.NO_PROMPT_THRESHOLD) {\n this.setState({\n buttonState: IrisGridCopyHandler.BUTTON_STATES.COPY,\n copyState: IrisGridCopyHandler.COPY_STATES.CONFIRMATION_REQUIRED,\n });\n } else {\n this.startFetch();\n }\n }\n\n stopCopy(): void {\n this.textData = undefined;\n this.stopFetch();\n this.stopHideTimer();\n }\n\n handleBackgroundClick(): void {\n log.debug2('handleBackgroundClick');\n\n const { copyState } = this.state;\n if (copyState === IrisGridCopyHandler.COPY_STATES.DONE) {\n this.setState({ isShown: false });\n }\n }\n\n handleCancelClick(): void {\n log.debug2('handleCancelClick');\n\n this.stopFetch();\n this.setState({ isShown: false });\n }\n\n handleCopyClick(): void {\n log.debug2('handleCopyClick');\n\n if (this.textData != null) {\n this.copyText(this.textData);\n } else {\n this.startFetch();\n }\n }\n\n handleHideTimeout(): void {\n log.debug2('handleHideTimeout');\n\n this.stopHideTimer();\n\n this.setState({ isShown: false });\n }\n\n copyText(text: string): void {\n log.debug2('copyText', text);\n\n this.textData = text;\n\n copyToClipboard(text).then(\n () => {\n this.setState({ copyState: IrisGridCopyHandler.COPY_STATES.DONE });\n this.startHideTimer();\n },\n error => {\n log.error('copyText error', error);\n this.setState({\n buttonState: IrisGridCopyHandler.BUTTON_STATES.CLICK_TO_COPY,\n copyState: IrisGridCopyHandler.COPY_STATES.CLICK_REQUIRED,\n });\n }\n );\n }\n\n startFetch(): void {\n this.stopFetch();\n\n this.setState({\n buttonState: IrisGridCopyHandler.BUTTON_STATES.FETCH_IN_PROGRESS,\n copyState: IrisGridCopyHandler.COPY_STATES.FETCH_IN_PROGRESS,\n });\n\n const { model, copyOperation } = this.props;\n const {\n ranges,\n includeHeaders,\n userColumnWidths,\n movedColumns,\n formatValues,\n } = copyOperation;\n log.debug('startFetch', ranges);\n\n const hiddenColumns = IrisGridUtils.getHiddenColumns(userColumnWidths);\n let modelRanges = GridUtils.getModelRanges(ranges, movedColumns);\n if (hiddenColumns.length > 0) {\n const subtractRanges = hiddenColumns.map(GridRange.makeColumn);\n modelRanges = GridRange.subtractRangesFromRanges(\n modelRanges,\n subtractRanges\n );\n }\n\n // Remove the hidden columns from the snapshot\n const formatValue =\n formatValues != null && formatValues\n ? (value: unknown, column: Column) =>\n model.displayString(value, column.type, column.name)\n : (value: unknown) => `${value}`;\n\n this.fetchPromise = PromiseUtils.makeCancelable(\n model.textSnapshot(modelRanges, includeHeaders, formatValue)\n );\n this.fetchPromise\n .then((text: string) => {\n this.fetchPromise = undefined;\n this.copyText(text);\n })\n .catch((error: unknown) => {\n if (error instanceof CanceledPromiseError) {\n log.debug('User cancelled copy.');\n } else {\n log.error('Error fetching contents', error);\n this.fetchPromise = undefined;\n this.setState({\n buttonState: IrisGridCopyHandler.BUTTON_STATES.RETRY,\n copyState: IrisGridCopyHandler.COPY_STATES.FETCH_ERROR,\n });\n }\n });\n }\n\n stopFetch(): void {\n if (this.fetchPromise) {\n log.debug2('stopFetch');\n this.fetchPromise.cancel();\n this.fetchPromise = undefined;\n }\n }\n\n startHideTimer(): void {\n this.stopHideTimer();\n\n this.hideTimer = setTimeout(\n this.handleHideTimeout,\n IrisGridCopyHandler.HIDE_TIMEOUT\n );\n }\n\n stopHideTimer(): void {\n if (this.hideTimer != null) {\n clearTimeout(this.hideTimer);\n this.hideTimer = undefined;\n }\n }\n\n render(): JSX.Element {\n const { onEntering, onEntered, onExiting, onExited } = this.props;\n const { buttonState, copyState, isShown, rowCount, error } = this.state;\n\n const animation =\n copyState === IrisGridCopyHandler.COPY_STATES.DONE\n ? 'fade'\n : 'copy-slide-up';\n const copyButtonText = IrisGridCopyHandler.getCopyButtonText(buttonState);\n const statusMessageText =\n error ?? IrisGridCopyHandler.getStatusMessageText(copyState, rowCount);\n const isButtonContainerVisible =\n copyState !== IrisGridCopyHandler.COPY_STATES.DONE;\n const isFetching =\n buttonState === IrisGridCopyHandler.BUTTON_STATES.FETCH_IN_PROGRESS;\n const isDone = copyState === IrisGridCopyHandler.COPY_STATES.DONE;\n\n return (\n <IrisGridBottomBar\n animation={animation}\n isShown={isShown}\n className={classNames('iris-grid-copy-handler', {\n 'copy-done': isDone,\n })}\n onClick={this.handleBackgroundClick}\n onEntering={onEntering}\n onEntered={onEntered}\n onExiting={onExiting}\n onExited={onExited}\n >\n <div className=\"status-message\">\n <span>{statusMessageText}</span>\n </div>\n <CSSTransition\n in={isButtonContainerVisible}\n timeout={ThemeExport.transitionMs}\n classNames=\"fade\"\n mountOnEnter\n unmountOnExit\n >\n <div className=\"buttons-container\">\n <button\n type=\"button\"\n className=\"btn btn-outline-secondary btn-cancel\"\n onClick={this.handleCancelClick}\n >\n Cancel\n </button>\n <Button\n kind={isFetching ? 'tertiary' : 'primary'}\n className={classNames('btn-copy', {\n 'btn-spinner': isFetching,\n })}\n onClick={this.handleCopyClick}\n disabled={isFetching}\n >\n {isFetching && <LoadingSpinner />}\n {copyButtonText}\n </Button>\n </div>\n </CSSTransition>\n </IrisGridBottomBar>\n );\n }\n}\n\nexport default IrisGridCopyHandler;\n","import React, { ChangeEvent, PureComponent, ReactElement } from 'react';\nimport classNames from 'classnames';\nimport debounce from 'lodash.debounce';\nimport { vsFilter, dhFilterFilled } from '@deephaven/icons';\nimport './FilterInputField.scss';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport type { DebouncedFunc } from 'lodash';\nimport { Button } from '@deephaven/components';\n\ninterface FilterInputFieldProps {\n className: string;\n style: React.CSSProperties;\n value: string;\n isAdvancedFilterSet: boolean;\n onAdvancedFiltersTriggered: React.MouseEventHandler<HTMLButtonElement>;\n onChange: (value: string) => void;\n onDone: (setGridFocus?: boolean, defocusInput?: boolean) => void;\n onTab: (backward: boolean) => void;\n onContextMenu: React.MouseEventHandler<HTMLInputElement | HTMLButtonElement>;\n debounceMs: number;\n}\ninterface FilterInputFieldState {\n isChanged: boolean;\n value: string;\n}\n/**\n * An input field showing a input field and button.\n * Debounces changes.\n */\nclass FilterInputField extends PureComponent<\n FilterInputFieldProps,\n FilterInputFieldState\n> {\n static defaultProps = {\n style: {},\n className: '',\n value: '',\n isAdvancedFilterSet: false,\n onAdvancedFiltersTriggered: (): void => undefined,\n onChange: (): void => undefined,\n onDone: (): void => undefined,\n onTab: (): void => undefined,\n onContextMenu: (): void => undefined,\n debounceMs: 150,\n };\n\n constructor(props: FilterInputFieldProps) {\n super(props);\n\n const { debounceMs } = props;\n\n this.debouncedSendUpdate = debounce(this.sendUpdate.bind(this), debounceMs);\n this.handleCancel = this.handleCancel.bind(this);\n this.handleChange = this.handleChange.bind(this);\n this.handleCommit = this.handleCommit.bind(this);\n this.handleFocus = this.handleFocus.bind(this);\n this.handleBlur = this.handleBlur.bind(this);\n this.handleKeyDown = this.handleKeyDown.bind(this);\n this.handleContextMenu = this.handleContextMenu.bind(this);\n\n this.inputField = null;\n\n const { value } = props;\n this.initialValue = value;\n this.state = {\n isChanged: false,\n value,\n };\n }\n\n componentDidMount(): void {\n this.inputField?.focus();\n }\n\n componentDidUpdate(prevProps: FilterInputFieldProps): void {\n const { debounceMs } = this.props;\n if (prevProps.debounceMs !== debounceMs) {\n this.debouncedSendUpdate.flush();\n this.debouncedSendUpdate = debounce(\n this.sendUpdate.bind(this),\n debounceMs\n );\n }\n }\n\n componentWillUnmount(): void {\n this.debouncedSendUpdate.cancel();\n }\n\n inputField: HTMLInputElement | null;\n\n initialValue: string;\n\n debouncedSendUpdate: DebouncedFunc<(value: string) => void>;\n\n // clear filters needs to be able to reset the value externally\n // and due to the way this component handles its own debouncing\n // this was easier than moving state up.\n setValue(value: string): void {\n this.initialValue = value;\n this.setState({ value });\n }\n\n focus(): void {\n this.inputField?.focus();\n }\n\n handleChange(event: ChangeEvent<HTMLInputElement>): void {\n const { value } = event.target;\n this.setState({ value, isChanged: true });\n\n this.debouncedSendUpdate(value);\n }\n\n handleCancel(): void {\n this.debouncedSendUpdate.cancel();\n const { initialValue } = this;\n const { isChanged } = this.state;\n if (isChanged) {\n this.sendUpdate(initialValue);\n }\n\n const { onDone } = this.props;\n onDone();\n }\n\n handleCommit(setGridFocus = true, defocusInput = true): void {\n this.debouncedSendUpdate.flush();\n\n const { onDone } = this.props;\n onDone(setGridFocus, defocusInput);\n }\n\n handleFocus(): void {\n this.inputField?.select();\n }\n\n handleBlur(event: React.FocusEvent<HTMLInputElement>): void {\n const { relatedTarget } = event;\n // handleCommit results in a call that steals focus\n if (\n relatedTarget != null &&\n relatedTarget.classList.contains('context-menu-container')\n ) {\n // input blurred by calling context-menu\n // don't set grid focus, but do null column focus\n this.handleCommit(false, true);\n } else if (\n relatedTarget != null &&\n relatedTarget.classList.contains('advanced-filter-button')\n ) {\n // blurred by clicking an advanced filter button\n // don't set grid focus, maintain focusedFilterBarColumn state\n this.handleCommit(false, false);\n } else {\n // clear both, blurred elsewhere\n this.handleCommit(true, true);\n }\n }\n\n handleTab(backward = false): void {\n this.debouncedSendUpdate.flush();\n\n const { onTab } = this.props;\n onTab(backward);\n }\n\n handleKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {\n switch (event.key) {\n case 'Escape':\n event.stopPropagation();\n event.preventDefault();\n this.handleCancel();\n break;\n case 'Enter':\n event.stopPropagation();\n event.preventDefault();\n this.handleCommit();\n break;\n case 'Tab':\n event.stopPropagation();\n event.preventDefault();\n this.handleTab(event.shiftKey);\n break;\n default:\n break;\n }\n }\n\n handleContextMenu(\n event: React.MouseEvent<HTMLInputElement | HTMLButtonElement>\n ): void {\n const { onContextMenu } = this.props;\n onContextMenu(event);\n }\n\n sendUpdate(value: string): void {\n const { onChange } = this.props;\n onChange(value);\n }\n\n render(): ReactElement {\n const {\n className,\n style,\n isAdvancedFilterSet,\n onAdvancedFiltersTriggered,\n } = this.props;\n const { value } = this.state;\n return (\n <div\n style={style}\n className=\"iris-grid-input-autosized-wrapper\"\n data-value={value} // used by css based autosizer\n >\n <input\n ref={inputField => {\n this.inputField = inputField;\n }}\n className={classNames('iris-grid-input-field', className)}\n type=\"text\"\n value={value}\n onBlur={this.handleBlur}\n onFocus={this.handleFocus}\n onChange={this.handleChange}\n onKeyDown={this.handleKeyDown}\n onContextMenu={this.handleContextMenu}\n autoComplete=\"off\"\n autoCorrect=\"off\"\n autoCapitalize=\"off\"\n spellCheck=\"false\"\n />\n <div className=\"advanced-filter-button-container\">\n <Button\n kind=\"ghost\"\n className={classNames('btn-link-icon advanced-filter-button', {\n 'filter-set': isAdvancedFilterSet,\n })}\n onClick={onAdvancedFiltersTriggered}\n onContextMenu={this.handleContextMenu}\n >\n <div className=\"fa-layers \">\n <FontAwesomeIcon icon={dhFilterFilled} className=\"filter-solid\" />\n <FontAwesomeIcon icon={vsFilter} className=\"filter-light\" />\n </div>\n </Button>\n </div>\n </div>\n );\n }\n}\n\nexport default FilterInputField;\n","/* eslint class-methods-use-this: \"off\" */\nimport { KeyboardEvent } from 'react';\nimport { ContextActionUtils } from '@deephaven/components';\nimport { KeyHandler } from '@deephaven/grid';\nimport { IrisGrid } from '../IrisGrid';\nimport IrisGridUtils from '../IrisGridUtils';\n\nclass CopyKeyHandler extends KeyHandler {\n private irisGrid: IrisGrid;\n\n constructor(irisGrid: IrisGrid) {\n super();\n\n this.irisGrid = irisGrid;\n }\n\n onDown(event: KeyboardEvent): boolean {\n const { selectedRanges } = this.irisGrid.state;\n if (event.key === 'c' && ContextActionUtils.isModifierKeyDown(event)) {\n if (IrisGridUtils.isValidSnapshotRanges(selectedRanges)) {\n this.irisGrid.copyRanges(selectedRanges);\n } else {\n this.irisGrid.copyRanges(\n selectedRanges,\n false,\n false,\n 'Invalid copy ranges'\n );\n }\n return true;\n }\n return false;\n }\n}\n\nexport default CopyKeyHandler;\n","import { ShortcutRegistry, MODIFIER, KEY } from '@deephaven/components';\n\nconst TABLE = {\n TOGGLE_QUICK_FILTER: ShortcutRegistry.createAndAdd({\n id: 'TABLE.TOGGLE_QUICK_FILTER',\n name: 'Toggle Quick Filter',\n shortcut: [MODIFIER.CTRL, KEY.F],\n macShortcut: [MODIFIER.CMD, KEY.F],\n }),\n CLEAR_ALL_FILTERS: ShortcutRegistry.createAndAdd({\n id: 'TABLE.CLEAR_ALL_FILTERS',\n name: 'Clear All Table Filters',\n shortcut: [MODIFIER.CTRL, KEY.E],\n macShortcut: [MODIFIER.CMD, KEY.E],\n }),\n CLEAR_FILTERS: ShortcutRegistry.createAndAdd({\n id: 'TABLE.CLEAR_FILTERS',\n name: 'Clear Active Table Filters',\n shortcut: [MODIFIER.CTRL, MODIFIER.SHIFT, KEY.E],\n macShortcut: [MODIFIER.CMD, MODIFIER.SHIFT, KEY.E],\n }),\n REVERSE: ShortcutRegistry.createAndAdd({\n id: 'TABLE.REVERSE',\n name: 'Reverse',\n shortcut: [MODIFIER.CTRL, KEY.I],\n macShortcut: [MODIFIER.CMD, KEY.I],\n }),\n TOGGLE_SEARCH: ShortcutRegistry.createAndAdd({\n id: 'TABLE.TOGGLE_SEARCH',\n name: 'Toggle Search',\n shortcut: [MODIFIER.CTRL, MODIFIER.SHIFT, KEY.F],\n macShortcut: [MODIFIER.CMD, MODIFIER.SHIFT, KEY.F],\n }),\n GOTO_ROW: ShortcutRegistry.createAndAdd({\n id: 'TABLE.GOTO_ROW',\n name: 'Go to Row',\n shortcut: [MODIFIER.CTRL, KEY.G],\n macShortcut: [MODIFIER.CMD, KEY.G],\n }),\n};\n\nconst INPUT_TABLE = {\n COMMIT: ShortcutRegistry.createAndAdd({\n id: 'INPUT_TABLE.COMMIT',\n name: 'Commit',\n shortcut: [MODIFIER.CTRL, KEY.S],\n macShortcut: [MODIFIER.CMD, KEY.S],\n }),\n DISCARD: ShortcutRegistry.createAndAdd({\n id: 'INPUT_TABLE.DISCARD',\n name: 'Discard',\n shortcut: [MODIFIER.CTRL, MODIFIER.ALT, KEY.S],\n macShortcut: [MODIFIER.CMD, MODIFIER.OPTION, KEY.S],\n }),\n};\n\nconst IRIS_GRID_SHORTCUTS = {\n TABLE,\n INPUT_TABLE,\n};\n\nexport default IRIS_GRID_SHORTCUTS;\n","import { KeyboardEvent } from 'react';\nimport { KeyHandler } from '@deephaven/grid';\nimport { TableUtils } from '@deephaven/jsapi-utils';\nimport { IrisGrid } from '../IrisGrid';\nimport IrisGridShortcuts from '../IrisGridShortcuts';\n\nclass ReverseKeyHandler extends KeyHandler {\n private irisGrid: IrisGrid;\n\n constructor(irisGrid: IrisGrid) {\n super();\n\n this.irisGrid = irisGrid;\n }\n\n onDown(event: KeyboardEvent): boolean {\n if (IrisGridShortcuts.TABLE.REVERSE.matchesEvent(event)) {\n if (!this.irisGrid.isReversible()) {\n return false;\n }\n const { reverseType } = this.irisGrid.state;\n if (reverseType === TableUtils.REVERSE_TYPE.NONE) {\n this.irisGrid.reverse(TableUtils.REVERSE_TYPE.POST_SORT);\n } else {\n this.irisGrid.reverse(TableUtils.REVERSE_TYPE.NONE);\n }\n return true;\n }\n return false;\n }\n}\n\nexport default ReverseKeyHandler;\n","import { KeyboardEvent } from 'react';\nimport { KeyHandler } from '@deephaven/grid';\nimport { IrisGrid } from '../IrisGrid';\nimport IrisGridShortcuts from '../IrisGridShortcuts';\n\nclass ClearFilterKeyHandler extends KeyHandler {\n private irisGrid: IrisGrid;\n\n constructor(irisGrid: IrisGrid) {\n super();\n\n this.irisGrid = irisGrid;\n }\n\n onDown(event: KeyboardEvent): boolean {\n if (IrisGridShortcuts.TABLE.CLEAR_FILTERS.matchesEvent(event)) {\n this.irisGrid.clearAllFilters();\n return true;\n }\n return false;\n }\n}\n\nexport default ClearFilterKeyHandler;\n","import {\n GridPoint,\n GridMouseHandler,\n EventHandlerResult,\n} from '@deephaven/grid';\nimport deepEqual from 'deep-equal';\nimport type IrisGrid from '../IrisGrid';\nimport { IrisGridRenderState } from '../IrisGridRenderer';\n\n/**\n * Handles cursor and click action for cell overflow button\n * The button is rendered via IrisGridRenderer\n */\nclass IrisGridCellOverflowMouseHandler extends GridMouseHandler {\n private irisGrid: IrisGrid;\n\n constructor(irisGrid: IrisGrid) {\n super(850); // Needs to be before GridSelectionMouseHandler\n\n this.irisGrid = irisGrid;\n }\n\n private destroyColumnTooltip(): void {\n this.irisGrid.setState({ overflowButtonTooltipProps: null });\n }\n\n private setCursor(point: GridPoint): EventHandlerResult {\n if (this.isHoveringOverflowButton(point)) {\n this.cursor = 'pointer';\n return { stopPropagation: false, preventDefault: false };\n }\n\n this.cursor = null;\n return false;\n }\n\n private getButtonPosition({\n x,\n y,\n column,\n row,\n }: GridPoint): {\n left: number;\n top: number;\n width: number;\n height: number;\n } | null {\n if (column == null || row == null) {\n return null;\n }\n const { renderer, grid, state, props } = this.irisGrid;\n if (!grid) {\n return null;\n }\n const { metrics } = state;\n const { model } = props;\n\n const { canvasContext: context } = grid;\n const theme = grid.getTheme();\n const rendererState = {\n context,\n mouseX: x,\n mouseY: y,\n metrics,\n model,\n theme,\n };\n\n const { left, top, width, height } = renderer.getCellOverflowButtonPosition(\n rendererState\n );\n if (left == null || width == null || top == null || height == null) {\n return null;\n }\n\n return { left, top, width, height };\n }\n\n private isHoveringOverflowButton(point: GridPoint): boolean {\n const { x, y } = point;\n const { left, top, width, height } = this.getButtonPosition(point) ?? {};\n if (left == null || width == null || top == null || height == null) {\n return false;\n }\n\n const { renderer, grid, state, props } = this.irisGrid;\n if (!grid) {\n return false;\n }\n const { metrics } = state;\n const { model } = props;\n const { canvasContext: context } = grid;\n const theme = grid.getTheme();\n const rendererState = {\n context,\n mouseX: x,\n mouseY: y,\n metrics,\n model,\n theme,\n } as IrisGridRenderState;\n\n return (\n renderer.shouldRenderOverflowButton(rendererState) &&\n x >= left &&\n x <= left + width &&\n y >= top &&\n y <= top + height\n );\n }\n\n onMove(point: GridPoint): EventHandlerResult {\n if (this.isHoveringOverflowButton(point)) {\n const { overflowButtonTooltipProps } = this.irisGrid.state;\n const newProps = this.getButtonPosition(point);\n if (!deepEqual(overflowButtonTooltipProps, newProps)) {\n this.irisGrid.setState({ overflowButtonTooltipProps: newProps });\n }\n } else {\n this.destroyColumnTooltip();\n }\n return this.setCursor(point);\n }\n\n onWheel(point: GridPoint): EventHandlerResult {\n this.destroyColumnTooltip();\n return this.onMove(point);\n }\n\n // Needs to be onDown and not onClick b/c of GridSelectionMouseHandler shifting cell onDown\n onDown(point: GridPoint): boolean {\n this.destroyColumnTooltip();\n const { column, row } = point;\n\n if (this.isHoveringOverflowButton(point)) {\n this.irisGrid.setState({\n showOverflowModal: true,\n overflowText: this.irisGrid.getValueForCell(column, row) as string,\n });\n }\n\n return false;\n }\n\n onContextMenu(): EventHandlerResult {\n this.destroyColumnTooltip();\n return false;\n }\n\n onLeave(): EventHandlerResult {\n this.destroyColumnTooltip();\n return false;\n }\n}\n\nexport default IrisGridCellOverflowMouseHandler;\n","/* eslint class-methods-use-this: \"off\" */\nimport {\n GridMouseHandler,\n GridPoint,\n EventHandlerResult,\n} from '@deephaven/grid';\nimport type { Column } from '@deephaven/jsapi-types';\nimport { IrisGrid } from '../IrisGrid';\n\n/**\n * Handles interaction with tables when the Linker tool is active\n */\nclass IrisGridColumnSelectMouseHandler extends GridMouseHandler {\n constructor(irisGrid: IrisGrid) {\n super();\n\n this.irisGrid = irisGrid;\n this.cursor = null;\n }\n\n private irisGrid: IrisGrid;\n\n private isActive(): boolean {\n const { isSelectingColumn } = this.irisGrid.props;\n return isSelectingColumn;\n }\n\n private isValidColumn(tableColumn: Column | null): boolean {\n if (tableColumn == null) {\n return false;\n }\n\n const { columnSelectionValidator } = this.irisGrid.props;\n if (columnSelectionValidator != null) {\n return columnSelectionValidator(tableColumn);\n }\n return true;\n }\n\n private updateColumnSelectionStatus(): void {\n const { columnSelectionValidator } = this.irisGrid.props;\n if (columnSelectionValidator != null) {\n columnSelectionValidator(null);\n }\n }\n\n private getTableColumn(columnIndex: number | null): Column | null {\n if (columnIndex == null) {\n return null;\n }\n\n const { model } = this.irisGrid.props;\n const modelColumn = this.irisGrid.getModelColumn(columnIndex);\n if (modelColumn == null) {\n return null;\n }\n\n return model.columns[modelColumn];\n }\n\n onMove(gridPoint: GridPoint): EventHandlerResult {\n if (!this.isActive()) {\n return false;\n }\n\n const { columnAllowedCursor, columnNotAllowedCursor } = this.irisGrid.props;\n const { column } = gridPoint;\n const tableColumn = this.getTableColumn(column);\n\n if (this.isValidColumn(tableColumn)) {\n this.cursor = columnAllowedCursor;\n this.irisGrid.setState({ hoverSelectColumn: column });\n } else {\n this.cursor = columnNotAllowedCursor;\n this.irisGrid.setState({ hoverSelectColumn: null });\n }\n\n return true;\n }\n\n // keeps linker cursor state during wheel event\n onWheel(gridPoint: GridPoint): EventHandlerResult {\n if (!this.isActive()) {\n return false;\n }\n\n const { columnAllowedCursor, columnNotAllowedCursor } = this.irisGrid.props;\n const { column } = gridPoint;\n const tableColumn = this.getTableColumn(column);\n\n if (this.isValidColumn(tableColumn)) {\n this.cursor = columnAllowedCursor;\n this.irisGrid.setState({ hoverSelectColumn: column });\n } else {\n this.cursor = columnNotAllowedCursor;\n this.irisGrid.setState({ hoverSelectColumn: null });\n }\n\n // don't block wheel event from scrolling\n return { preventDefault: false, stopPropagation: false };\n }\n\n onLeave(): EventHandlerResult {\n if (this.isActive()) {\n this.irisGrid.setState({ hoverSelectColumn: null });\n }\n\n this.updateColumnSelectionStatus();\n\n return false;\n }\n\n onDown(): EventHandlerResult {\n return this.isActive();\n }\n\n onClick(gridPoint: GridPoint): EventHandlerResult {\n if (!this.isActive()) {\n return false;\n }\n\n const { column } = gridPoint;\n const tableColumn = this.getTableColumn(column);\n if (tableColumn != null && this.isValidColumn(tableColumn)) {\n this.irisGrid.selectColumn(tableColumn);\n }\n\n return true;\n }\n}\n\nexport default IrisGridColumnSelectMouseHandler;\n","/* eslint class-methods-use-this: \"off\" */\nimport {\n GridMouseHandler,\n GridPoint,\n EventHandlerResult,\n Grid,\n GridMouseEvent,\n} from '@deephaven/grid';\nimport type { IrisGrid } from '../IrisGrid';\n\n/**\n * Detects mouse hover over column headers and displays the appropriate tooltip\n */\nclass IrisGridColumnTooltipMouseHandler extends GridMouseHandler {\n constructor(irisGrid: IrisGrid) {\n super();\n\n this.irisGrid = irisGrid;\n }\n\n private irisGrid: IrisGrid;\n\n private hideColumnTooltip(): void {\n const { tooltip } = this.irisGrid;\n if (tooltip) {\n tooltip.stopTimer();\n tooltip.hide();\n }\n }\n\n onDown(): EventHandlerResult {\n this.hideColumnTooltip();\n return false;\n }\n\n onContextMenu(): EventHandlerResult {\n this.hideColumnTooltip();\n return false;\n }\n\n onWheel(): EventHandlerResult {\n this.hideColumnTooltip();\n return false;\n }\n\n onLeave(\n gridPoint: GridPoint,\n grid: Grid,\n event: GridMouseEvent\n ): EventHandlerResult {\n /**\n * This should always be a react event\n * React seems to be handling onMouseLeave incorrectly at times\n * When moving to the padding between the column and popper, React sets\n * event.relatedTarget to window, but event.nativeEvent.relatedTarget is the popper.\n * It's possibly related to popper being rendered in a portal\n */\n const { relatedTarget } =\n event instanceof MouseEvent ? event : event.nativeEvent;\n\n const { tooltip } = this.irisGrid;\n if (!tooltip) {\n return false;\n }\n\n const popper = tooltip.popper.current;\n\n if (\n popper &&\n relatedTarget instanceof Element &&\n popper.element.contains(relatedTarget)\n ) {\n // Do not hide the popper if we moved the cursor from canvas to popper\n return false;\n }\n this.hideColumnTooltip();\n return false;\n }\n\n onMove(gridPoint: GridPoint): EventHandlerResult {\n const { column, row, columnHeaderDepth } = gridPoint;\n const { shownColumnTooltip } = this.irisGrid.state;\n let newTooltip = null;\n if (column !== null && row === null && columnHeaderDepth === 0) {\n newTooltip = column;\n }\n\n if (newTooltip !== shownColumnTooltip) {\n this.irisGrid.setState({ shownColumnTooltip: newTooltip });\n }\n\n return false;\n }\n}\n\nexport default IrisGridColumnTooltipMouseHandler;\n","import React, { Component } from 'react';\nimport { Tooltip } from '@deephaven/components';\nimport { DOMUtils } from '@deephaven/utils';\n\nimport './CustomFormatAction.scss';\n\ntype CustomFormatActionProps = typeof CustomFormatAction.defaultProps & {\n forwardedProps: {\n menuItem: {\n title?: string;\n description?: string;\n };\n };\n};\n\n/**\n * Renders menuElement option with custom format input for use in formatting context menus\n *\n * TODO:\n * - capture focus when this menu action is selected via ArrowUp/ArrowDown keys\n * - dynamically update selected menu item when clicking on the input box\n */\nclass CustomFormatAction extends Component<CustomFormatActionProps> {\n static defaultProps = {\n formatString: '',\n forwardedProps: {\n menuItem: {},\n closeMenu(focusInput: boolean): void {\n // no-op\n },\n iconElement: null,\n },\n placeholder: '',\n title: '',\n onChange(value: string | null): void {\n // no-op\n },\n };\n\n constructor(\n props: CustomFormatActionProps = CustomFormatAction.defaultProps\n ) {\n super(props);\n\n this.handleInputChange = this.handleInputChange.bind(this);\n this.handleKeyDown = this.handleKeyDown.bind(this);\n\n this.inputRef = React.createRef();\n }\n\n inputRef: React.RefObject<HTMLInputElement>;\n\n handleInputChange(): void {\n const { onChange } = this.props;\n if (this.inputRef.current) {\n onChange(this.inputRef.current.value);\n }\n }\n\n closeContextMenu(): void {\n const { forwardedProps } = this.props;\n const { closeMenu } = forwardedProps;\n closeMenu(true);\n }\n\n revertToDefault(): void {\n const { onChange } = this.props;\n onChange(null);\n }\n\n returnFocusToContextMenu(): void {\n const parentContextMenu = DOMUtils.getClosestByClassName(\n this.inputRef.current,\n 'context-menu-container'\n );\n if (parentContextMenu instanceof HTMLElement) {\n parentContextMenu.focus();\n }\n }\n\n handleKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {\n switch (event.key) {\n case 'Enter':\n event.stopPropagation();\n this.closeContextMenu();\n break;\n case 'Escape':\n event.stopPropagation();\n this.revertToDefault();\n this.closeContextMenu();\n break;\n case 'ArrowRight':\n case 'ArrowLeft':\n event.stopPropagation();\n break;\n case 'ArrowUp':\n case 'ArrowDown':\n this.returnFocusToContextMenu();\n break;\n default:\n event.stopPropagation();\n }\n }\n\n render(): JSX.Element {\n const { formatString, forwardedProps, placeholder, title } = this.props;\n const {\n menuItem: { description },\n iconElement,\n } = forwardedProps;\n return (\n <div className=\"form-group flex-grow mb-0\">\n <div className=\"custom-format-title\">\n <span className=\"icon\">{iconElement}</span>\n <label className=\"title mb-0\" htmlFor=\"custom-format-input\">\n {title}\n {description != null && <Tooltip>{description}</Tooltip>}\n </label>\n </div>\n <div className=\"pl-2 pr-2 pb-2\">\n <input\n id=\"custom-format-input\"\n className=\"form-control text-right mb-0\"\n type=\"text\"\n defaultValue={formatString}\n ref={this.inputRef}\n placeholder={placeholder}\n onKeyDown={this.handleKeyDown}\n onChange={this.handleInputChange}\n autoComplete=\"off\"\n autoCorrect=\"off\"\n autoCapitalize=\"off\"\n spellCheck=\"false\"\n />\n </div>\n </div>\n );\n }\n}\n\nexport default CustomFormatAction;\n","import React from 'react';\nimport {\n TableColumnFormat,\n TableColumnFormatter,\n} from '@deephaven/jsapi-utils';\nimport CustomFormatAction from './CustomFormatAction';\n\nexport interface FormatContextMenuOption {\n title: string;\n description: string;\n group: number;\n format: TableColumnFormat | null;\n isSelected: boolean;\n}\n\nexport interface CustomFormatOption extends FormatContextMenuOption {\n menuElement: React.ReactElement;\n}\n\nclass FormatContextMenuUtils {\n /**\n * Returns true if default option should be active in the context menu\n * @param selectedFormat selected format object or null\n */\n static isDefaultSelected(selectedFormat: TableColumnFormat | null): boolean {\n return (\n !selectedFormat ||\n ![\n TableColumnFormatter.TYPE_CONTEXT_CUSTOM,\n TableColumnFormatter.TYPE_CONTEXT_PRESET,\n ].includes(selectedFormat.type)\n );\n }\n\n /**\n * Returns true if custom format option should be active in the context menu\n * @param selectedFormat selected format object or null\n */\n static isCustomSelected(selectedFormat: TableColumnFormat): boolean {\n return (\n selectedFormat != null &&\n selectedFormat.type === TableColumnFormatter.TYPE_CONTEXT_CUSTOM\n );\n }\n\n /**\n * Creates context menu option\n * @param title Context menu title\n * @param format Format object\n * @param group Context menu group\n * @param isSelected Is current option selected\n */\n static makeOption(\n title: string,\n format: TableColumnFormat | null,\n group: number,\n isSelected: boolean\n ): FormatContextMenuOption {\n return {\n title,\n description: title,\n group,\n format,\n isSelected,\n };\n }\n\n /**\n * Creates context menu option with an input element\n * @param format Format object\n * @param group Context menu group\n * @param placeholder Input element placeholder\n * @param isSelected Is current option selected\n * @param onChange Input element onChange callback\n */\n static makeCustomFormatOption(\n format: TableColumnFormat,\n group: number,\n placeholder: string,\n isSelected: boolean,\n onChange: (value: string | null) => void\n ): CustomFormatOption {\n return {\n title: format.label,\n description: format.label,\n format,\n group,\n isSelected,\n menuElement: (\n <CustomFormatAction\n formatString={format.formatString}\n title={format.label}\n placeholder={placeholder}\n onChange={onChange}\n />\n ),\n };\n }\n}\n\nexport default FormatContextMenuUtils;\n","import {\n DateTimeColumnFormatter,\n Formatter,\n TableColumnFormat,\n TableUtils,\n} from '@deephaven/jsapi-utils';\nimport FormatContextMenuUtils, {\n FormatContextMenuOption,\n} from './FormatContextMenuUtils';\n\nclass DateTimeFormatContextMenu {\n static dateGroup = 10;\n\n static timeGroup = 20;\n\n static dateTimeGroup = 30;\n\n /**\n * Creates list of formatting options for DateTime context menu\n * @param formatter Formatter instance\n * @param selectedFormat Selected format object, null for no selected format\n * @returns Array of formatting options for the context menu\n */\n static getOptions(\n formatter: Formatter,\n selectedFormat: TableColumnFormat | null\n ): FormatContextMenuOption[] {\n const currentTime = new Date();\n const formatItems = [\n {\n group: DateTimeFormatContextMenu.dateGroup,\n formatString: 'yyyy-MM-dd',\n },\n {\n group: DateTimeFormatContextMenu.dateGroup,\n formatString: 'MM-dd-yyyy',\n },\n\n {\n group: DateTimeFormatContextMenu.timeGroup,\n formatString: 'HH:mm:ss',\n },\n {\n group: DateTimeFormatContextMenu.timeGroup,\n formatString: 'HH:mm:ss.SSS',\n },\n {\n group: DateTimeFormatContextMenu.timeGroup,\n formatString: 'HH:mm:ss.SSSSSSSSS',\n },\n\n {\n group: DateTimeFormatContextMenu.dateTimeGroup,\n formatString: `yyyy-MM-dd HH:mm:ss`,\n },\n {\n group: DateTimeFormatContextMenu.dateTimeGroup,\n formatString: `yyyy-MM-dd HH:mm:ss.SSS`,\n },\n {\n group: DateTimeFormatContextMenu.dateTimeGroup,\n formatString: `yyyy-MM-dd HH:mm:ss.SSSSSSSSS`,\n },\n ];\n\n const presetFormatOptions = formatItems.map(item => {\n const format = DateTimeColumnFormatter.makeFormat(\n '',\n item.formatString,\n DateTimeColumnFormatter.TYPE_CONTEXT_PRESET\n );\n const title = formatter.getFormattedString(\n currentTime,\n TableUtils.dataType.DATETIME,\n '',\n format\n );\n\n return FormatContextMenuUtils.makeOption(\n title,\n format,\n item.group,\n DateTimeColumnFormatter.isSameFormat(format, selectedFormat)\n );\n });\n\n const defaultOption = FormatContextMenuUtils.makeOption(\n 'Default',\n null,\n DateTimeFormatContextMenu.dateGroup,\n FormatContextMenuUtils.isDefaultSelected(selectedFormat)\n );\n\n return [defaultOption, ...presetFormatOptions];\n }\n}\n\nexport default DateTimeFormatContextMenu;\n","import {\n DecimalColumnFormat,\n DecimalColumnFormatter,\n} from '@deephaven/jsapi-utils';\nimport type { dh as DhType } from '@deephaven/jsapi-types';\nimport FormatContextMenuUtils, {\n FormatContextMenuOption,\n} from './FormatContextMenuUtils';\n\nclass DecimalFormatContextMenu {\n static defaultGroup = 10;\n\n static presetGroup = 20;\n\n static presetRoundGroup = 30;\n\n static customGroup = 40;\n\n /**\n * Creates list of formatting options for Decimal context menu\n * @param dh JSAPI instance\n * @param selectedFormat Selected format object, null for no selected format\n * @param onCustomFormatChange Callback to call when the custom format is changed\n * @returns Array of formatting options for the context menu\n */\n static getOptions(\n dh: DhType,\n selectedFormat: DecimalColumnFormat,\n onCustomFormatChange: (value: DecimalColumnFormat | null) => void\n ): FormatContextMenuOption[] {\n const formatItems = [\n {\n format: DecimalColumnFormatter.FORMAT_PERCENT,\n group: DecimalFormatContextMenu.presetGroup,\n },\n {\n format: DecimalColumnFormatter.FORMAT_BASIS_POINTS,\n group: DecimalFormatContextMenu.presetGroup,\n },\n {\n format: DecimalColumnFormatter.FORMAT_MILLIONS,\n group: DecimalFormatContextMenu.presetGroup,\n },\n {\n format: DecimalColumnFormatter.FORMAT_SCIENTIFIC_NOTATION,\n group: DecimalFormatContextMenu.presetGroup,\n },\n {\n format: DecimalColumnFormatter.FORMAT_ROUND,\n group: DecimalFormatContextMenu.presetRoundGroup,\n },\n {\n format: DecimalColumnFormatter.FORMAT_ROUND_TWO_DECIMALS,\n group: DecimalFormatContextMenu.presetRoundGroup,\n },\n {\n format: DecimalColumnFormatter.FORMAT_ROUND_FOUR_DECIMALS,\n group: DecimalFormatContextMenu.presetRoundGroup,\n },\n ];\n\n const defaultFormatOption = FormatContextMenuUtils.makeOption(\n 'Default',\n null,\n DecimalFormatContextMenu.defaultGroup,\n FormatContextMenuUtils.isDefaultSelected(selectedFormat)\n );\n\n const presetFormatOptions = formatItems.map(item =>\n FormatContextMenuUtils.makeOption(\n item.format.label,\n item.format,\n item.group,\n DecimalColumnFormatter.isSameFormat(item.format, selectedFormat)\n )\n );\n\n const isCustomSelected = FormatContextMenuUtils.isCustomSelected(\n selectedFormat\n );\n\n const customFormat = isCustomSelected\n ? selectedFormat\n : DecimalColumnFormatter.makeCustomFormat();\n\n const customFormatOption = FormatContextMenuUtils.makeCustomFormatOption(\n customFormat,\n DecimalFormatContextMenu.customGroup,\n DecimalColumnFormatter.DEFAULT_FORMAT_STRING,\n isCustomSelected,\n formatString => {\n if (formatString != null) {\n const newCustomFormat = DecimalColumnFormatter.makeCustomFormat(\n formatString\n );\n if (DecimalColumnFormatter.isValid(dh, newCustomFormat)) {\n onCustomFormatChange(newCustomFormat);\n }\n } else {\n onCustomFormatChange(null);\n }\n }\n );\n\n return [defaultFormatOption, ...presetFormatOptions, customFormatOption];\n }\n}\n\nexport default DecimalFormatContextMenu;\n","import {\n IntegerColumnFormat,\n IntegerColumnFormatter,\n} from '@deephaven/jsapi-utils';\nimport type { dh as DhType } from '@deephaven/jsapi-types';\nimport FormatContextMenuUtils, {\n FormatContextMenuOption,\n} from './FormatContextMenuUtils';\n\nclass IntegerFormatContextMenu {\n static defaultGroup = 10;\n\n static presetGroup = 20;\n\n static customGroup = 30;\n\n /**\n * Creates list of formatting options for Integer context menu\n * @param dh JSAPI instance\n * @param selectedFormat Selected format object, null for no selected format\n * @param onCustomFormatChange Callback to call when the custom format is changed\n * @returns Array of formatting options for the context menu\n */\n static getOptions(\n dh: DhType,\n selectedFormat: IntegerColumnFormat,\n onCustomFormatChange: (value: IntegerColumnFormat | null) => void\n ): FormatContextMenuOption[] {\n const formatItems = [\n {\n format: IntegerColumnFormatter.FORMAT_MILLIONS,\n group: IntegerFormatContextMenu.presetGroup,\n },\n {\n format: IntegerColumnFormatter.FORMAT_SCIENTIFIC_NOTATION,\n group: IntegerFormatContextMenu.presetGroup,\n },\n ];\n\n const defaultFormatOption = FormatContextMenuUtils.makeOption(\n 'Default',\n null,\n IntegerFormatContextMenu.defaultGroup,\n FormatContextMenuUtils.isDefaultSelected(selectedFormat)\n );\n\n const presetFormatOptions = formatItems.map(item =>\n FormatContextMenuUtils.makeOption(\n item.format.label,\n item.format,\n item.group,\n IntegerColumnFormatter.isSameFormat(item.format, selectedFormat)\n )\n );\n\n const isCustomSelected = FormatContextMenuUtils.isCustomSelected(\n selectedFormat\n );\n\n const customFormat = isCustomSelected\n ? selectedFormat\n : IntegerColumnFormatter.makeCustomFormat();\n\n const customFormatOption = FormatContextMenuUtils.makeCustomFormatOption(\n customFormat,\n IntegerFormatContextMenu.customGroup,\n IntegerColumnFormatter.DEFAULT_FORMAT_STRING,\n isCustomSelected,\n formatString => {\n if (formatString != null) {\n const newCustomFormat = IntegerColumnFormatter.makeCustomFormat(\n formatString\n );\n if (IntegerColumnFormatter.isValid(dh, newCustomFormat)) {\n onCustomFormatChange(newCustomFormat);\n }\n } else {\n onCustomFormatChange(null);\n }\n }\n );\n\n return [defaultFormatOption, ...presetFormatOptions, customFormatOption];\n }\n}\n\nexport default IntegerFormatContextMenu;\n","/* eslint class-methods-use-this: \"off\" */\nimport React from 'react';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport {\n dhFilterFilled,\n vsRemove,\n vsCheck,\n vsFilter,\n IconDefinition,\n} from '@deephaven/icons';\nimport debounce from 'lodash.debounce';\nimport {\n ContextAction,\n ContextActions,\n ContextActionUtils,\n GLOBAL_SHORTCUTS,\n} from '@deephaven/components';\nimport {\n EventHandlerResult,\n Grid,\n GridMouseHandler,\n GridPoint,\n GridRenderer,\n isEditableGridModel,\n isExpandableGridModel,\n ModelIndex,\n} from '@deephaven/grid';\nimport type {\n Column,\n dh as DhType,\n FilterCondition,\n FilterValue,\n Sort,\n} from '@deephaven/jsapi-types';\nimport {\n TableColumnFormatter,\n DateTimeColumnFormatter,\n TableUtils,\n TableColumnFormat,\n IntegerColumnFormat,\n SortDirection,\n} from '@deephaven/jsapi-utils';\nimport Log from '@deephaven/log';\nimport type { DebouncedFunc } from 'lodash';\nimport { assertNotNull, copyToClipboard } from '@deephaven/utils';\nimport {\n DateTimeFormatContextMenu,\n DecimalFormatContextMenu,\n IntegerFormatContextMenu,\n} from '../format-context-menus';\nimport './IrisGridContextMenuHandler.scss';\nimport SHORTCUTS from '../IrisGridShortcuts';\nimport IrisGrid from '../IrisGrid';\nimport { QuickFilter } from '../CommonTypes';\n\nconst log = Log.module('IrisGridContextMenuHandler');\n\nconst DEBOUNCE_UPDATE_FORMAT = 150;\nconst CONTEXT_MENU_DATE_FORMAT = 'yyyy-MM-dd HH:mm:ss.SSSSSSSSS';\n\n/**\n * Used to eat the mouse event in the bottom right corner of the scroll bar\n */\nclass IrisGridContextMenuHandler extends GridMouseHandler {\n static GROUP_EDIT = ContextActions.groups.high + 10;\n\n static GROUP_HIDE_COLUMNS = ContextActions.groups.high + 25;\n\n static GROUP_FILTER = ContextActions.groups.high + 50;\n\n static GROUP_EXPAND_COLLAPSE = ContextActions.groups.high + 55;\n\n static GROUP_GOTO = ContextActions.groups.high + 60;\n\n static GROUP_SORT = ContextActions.groups.high + 75;\n\n static GROUP_COPY = ContextActions.groups.high + 100;\n\n static GROUP_FORMAT = ContextActions.groups.high + 150;\n\n static COLUMN_SORT_DIRECTION = {\n ascending: 'ASC',\n descending: 'DESC',\n none: null,\n } as const;\n\n /**\n * Get filter condition for quick filter and combines with a new filter using the operator specified,\n * returns new filter if no operator supplied.\n * @param columnFilter\n * @param newColumnFilter\n * @param operator\n */\n static getQuickFilterCondition(\n columnFilter: FilterCondition | null | undefined,\n newColumnFilter: FilterCondition,\n operator?: '&&' | '||' | null\n ): FilterCondition {\n if (columnFilter && operator === '&&') {\n return columnFilter.and(newColumnFilter);\n }\n if (columnFilter && operator === '||') {\n return columnFilter.or(newColumnFilter);\n }\n return newColumnFilter;\n }\n\n /**\n * combines filter text with operator if declared\n * @param filterText\n * @param newFilterText\n * @param operator\n */\n static getQuickFilterText(\n filterText: string | null | undefined,\n newFilterText: string,\n operator?: '&&' | '||' | null\n ): string {\n return operator && filterText != null\n ? `${filterText} ${operator} ${newFilterText}`\n : newFilterText;\n }\n\n /**\n * Converts operator to text string,\n */\n static getOperatorAsText(operator: '&&' | '||'): 'And' | 'Or' {\n return operator === '&&' ? 'And' : 'Or';\n }\n\n static getRowOptionFormatted(\n command: string,\n cellValue: string,\n len = 30\n ): string {\n return `${command} \"${GridRenderer.truncate(\n cellValue,\n len - command.length - 3\n )}\"`;\n }\n\n irisGrid: IrisGrid;\n\n debouncedUpdateCustomFormat: DebouncedFunc<\n (modelIndex: number, selectedFormat: TableColumnFormat | null) => void\n >;\n\n constructor(irisGrid: IrisGrid, dh: DhType) {\n super();\n\n this.debouncedUpdateCustomFormat = debounce(\n irisGrid.handleFormatSelection,\n DEBOUNCE_UPDATE_FORMAT\n );\n\n this.dh = dh;\n this.irisGrid = irisGrid;\n }\n\n componentWillUnmount(): void {\n this.debouncedUpdateCustomFormat.flush();\n }\n\n dh: DhType;\n\n getHeaderActions(\n modelIndex: ModelIndex,\n gridPoint: GridPoint\n ): ContextAction[] {\n const { irisGrid } = this;\n const { column: visibleIndex } = gridPoint;\n assertNotNull(visibleIndex);\n const { model } = irisGrid.props;\n const { columns } = model;\n const column = columns[modelIndex];\n\n const actions = [] as ContextAction[];\n\n const {\n metrics,\n reverseType,\n quickFilters,\n advancedFilters,\n searchFilter,\n } = irisGrid.state;\n const theme = irisGrid.getTheme();\n assertNotNull(metrics);\n const {\n filterIconColor,\n filterBarActiveColor,\n contextMenuSortIconColor,\n contextMenuReverseIconColor,\n } = theme;\n\n const modelSort = model.sort;\n const columnSort = TableUtils.getSortForColumn(modelSort, column.name);\n const hasReverse = reverseType !== TableUtils.REVERSE_TYPE.NONE;\n const { userColumnWidths } = metrics;\n const isColumnHidden = [...userColumnWidths.values()].some(\n columnWidth => columnWidth === 0\n );\n const isColumnFreezable =\n model.getColumnHeaderParentGroup(modelIndex, 0) === undefined &&\n !(isExpandableGridModel(model) && model.hasExpandableRows);\n const isColumnFrozen = model.isColumnFrozen(modelIndex);\n actions.push({\n title: 'Hide Column',\n group: IrisGridContextMenuHandler.GROUP_HIDE_COLUMNS,\n action: () => {\n this.irisGrid.hideColumnByVisibleIndex(visibleIndex);\n },\n });\n actions.push({\n title: isColumnFrozen ? 'Unfreeze Column' : 'Freeze Column',\n group: IrisGridContextMenuHandler.GROUP_HIDE_COLUMNS,\n disabled: !isColumnFreezable,\n action: () => {\n if (isColumnFrozen) {\n this.irisGrid.unFreezeColumnByColumnName(column.name);\n } else {\n this.irisGrid.freezeColumnByColumnName(column.name);\n }\n },\n order: 10,\n });\n actions.push({\n title: 'Show All Columns',\n group: IrisGridContextMenuHandler.GROUP_HIDE_COLUMNS,\n action: () => {\n this.irisGrid.showAllColumns();\n },\n disabled: !isColumnHidden,\n });\n actions.push({\n title: 'Quick Filters',\n icon: vsRemove,\n iconColor: filterBarActiveColor,\n shortcut: SHORTCUTS.TABLE.TOGGLE_QUICK_FILTER,\n group: IrisGridContextMenuHandler.GROUP_FILTER,\n order: 10,\n action: () => {\n this.irisGrid.toggleFilterBar(visibleIndex);\n },\n });\n actions.push({\n title: 'Advanced Filters',\n icon: advancedFilters.get(modelIndex) ? dhFilterFilled : vsFilter,\n iconColor: filterIconColor,\n group: IrisGridContextMenuHandler.GROUP_FILTER,\n order: 20,\n action: () => {\n this.irisGrid.handleAdvancedMenuOpened(visibleIndex);\n },\n });\n actions.push({\n title: 'Clear Table Filters',\n group: IrisGridContextMenuHandler.GROUP_FILTER,\n order: 40,\n // this just displays the shortcut, the actual listener is in irisgrid handleKeyDown\n shortcut: SHORTCUTS.TABLE.CLEAR_FILTERS,\n action: () => {\n this.irisGrid.clearAllFilters();\n },\n disabled: !(\n quickFilters.size > 0 ||\n advancedFilters.size > 0 ||\n searchFilter != null\n ),\n });\n actions.push({\n title: 'Sort by',\n icon: vsRemove,\n iconColor: contextMenuSortIconColor,\n group: IrisGridContextMenuHandler.GROUP_SORT,\n order: 10,\n actions: this.sortByActions(column, modelIndex, columnSort),\n });\n actions.push({\n title: 'Add Additional Sort',\n /**\n * disable conditions:\n * 1. table is sorted only by this column\n * 2. table is only reversed\n * 3. 1 & 2 combined\n * 4. table has no sort\n * reverse is a type of sort, so needs to be accounted for in exclusions\n * */\n disabled:\n (columnSort && modelSort.length === 1) ||\n (hasReverse && modelSort.length === 1) ||\n (columnSort && hasReverse && modelSort.length === 2) ||\n modelSort.length === 0,\n group: IrisGridContextMenuHandler.GROUP_SORT,\n order: 20,\n actions: this.additionalSortActions(column, modelIndex),\n });\n actions.push({\n title: 'Clear Table Sorting',\n disabled:\n // reverse is a type of sort, but special and needs to be exluded despite being part of model.sort\n modelSort.length === 0 || (hasReverse && modelSort.length === 1),\n group: IrisGridContextMenuHandler.GROUP_SORT,\n action: () => {\n this.irisGrid.sortColumn(\n visibleIndex,\n IrisGridContextMenuHandler.COLUMN_SORT_DIRECTION.none\n );\n },\n order: 30,\n });\n actions.push({\n title:\n reverseType === TableUtils.REVERSE_TYPE.NONE\n ? 'Reverse Table'\n : 'Clear Reverse Table',\n icon: vsRemove,\n iconColor: contextMenuReverseIconColor,\n group: IrisGridContextMenuHandler.GROUP_SORT,\n order: 40,\n disabled: !model.isReversible,\n // this just displays the shortcut, the actual listener is in irisgrid handleKeyDown\n shortcut: SHORTCUTS.TABLE.REVERSE,\n action: () => {\n if (reverseType === TableUtils.REVERSE_TYPE.NONE) {\n this.irisGrid.reverse(TableUtils.REVERSE_TYPE.POST_SORT);\n } else {\n this.irisGrid.reverse(TableUtils.REVERSE_TYPE.NONE);\n }\n },\n });\n actions.push({\n title: 'Copy Column Name',\n group: IrisGridContextMenuHandler.GROUP_COPY,\n action: () => {\n copyToClipboard(model.textForColumnHeader(modelIndex) ?? '').catch(e =>\n log.error('Unable to copy header', e)\n );\n },\n });\n\n if (TableUtils.isDateType(column.type)) {\n actions.push({\n title: 'Date/Time Format',\n group: IrisGridContextMenuHandler.GROUP_FORMAT,\n actions: this.dateFormatActions(column),\n });\n } else if (TableUtils.isNumberType(column.type)) {\n actions.push({\n title: 'Number Format',\n group: IrisGridContextMenuHandler.GROUP_FORMAT,\n actions: this.numberFormatActions(column) ?? undefined,\n });\n }\n return actions;\n }\n\n getCellActions(\n modelColumn: number | undefined | null,\n grid: Grid,\n gridPoint: GridPoint\n ): ContextAction[] {\n assertNotNull(modelColumn);\n const { dh, irisGrid } = this;\n const { column: columnIndex, row: rowIndex } = gridPoint;\n const { model, canCopy } = irisGrid.props;\n const { columns } = model;\n const modelRow = irisGrid.getModelRow(rowIndex);\n assertNotNull(modelRow);\n const value = model.valueForCell(modelColumn, modelRow);\n\n const valueText = model.textForCell(modelColumn, modelRow);\n const column = columns[modelColumn];\n\n const actions = [] as ContextAction[];\n\n const { quickFilters } = irisGrid.state;\n const theme = irisGrid.getTheme();\n const { filterIconColor } = theme;\n const { settings } = irisGrid.props;\n\n const dateFilterFormatter = new DateTimeColumnFormatter(dh, {\n timeZone: settings?.timeZone,\n showTimeZone: false,\n showTSeparator: true,\n defaultDateTimeFormatString: CONTEXT_MENU_DATE_FORMAT,\n });\n const previewFilterFormatter = new DateTimeColumnFormatter(dh, {\n timeZone: settings?.timeZone,\n showTimeZone: settings?.showTimeZone,\n showTSeparator: settings?.showTSeparator,\n defaultDateTimeFormatString: CONTEXT_MENU_DATE_FORMAT,\n });\n\n if (column == null || rowIndex == null) return actions;\n\n // grid data area context menu options\n if (model.isFilterable(modelColumn)) {\n // cell data area contextmenu options\n const filterMenu = {\n title: 'Filter by Value',\n icon: vsRemove,\n iconColor: filterIconColor,\n group: IrisGridContextMenuHandler.GROUP_FILTER,\n order: 10,\n actions: [],\n } as {\n title: string;\n icon: IconDefinition;\n iconColor: string;\n group: number;\n order: number;\n actions: ContextAction[];\n };\n\n if (value == null) {\n if (quickFilters.get(modelColumn)) {\n filterMenu.actions.push({\n title: 'And',\n actions: this.nullFilterActions(\n column,\n quickFilters.get(modelColumn),\n '&&'\n ),\n order: 2,\n group: ContextActions.groups.high,\n });\n }\n filterMenu.actions.push(...this.nullFilterActions(column));\n } else if (TableUtils.isBooleanType(column.type)) {\n // boolean should have OR condition, and handles it's own null menu options\n if (quickFilters.get(modelColumn)) {\n filterMenu.actions.push({\n title: 'Or',\n actions: this.booleanFilterActions(\n column,\n valueText,\n quickFilters.get(modelColumn),\n '||'\n ),\n order: 2,\n group: ContextActions.groups.high,\n });\n }\n filterMenu.actions.push(\n ...this.booleanFilterActions(column, valueText)\n );\n } else if (\n TableUtils.isNumberType(column.type) ||\n TableUtils.isCharType(column.type)\n ) {\n // Chars get treated like numbers in terms of which filters are available\n assertNotNull(modelColumn);\n // We want to show the full unformatted value if it's a number, so user knows which value they are matching\n // If it's a Char we just show the char\n const numberValueText = TableUtils.isCharType(column.type)\n ? String.fromCharCode(value as number)\n : `${value}`;\n\n if (quickFilters.get(modelColumn)) {\n filterMenu.actions.push({\n title: 'And',\n actions: this.numberFilterActions(\n column,\n numberValueText,\n value,\n quickFilters.get(modelColumn),\n '&&'\n ),\n order: 2,\n group: ContextActions.groups.high,\n });\n }\n filterMenu.actions.push(\n ...this.numberFilterActions(\n column,\n numberValueText,\n value,\n quickFilters.get(modelColumn)\n )\n );\n } else if (TableUtils.isDateType(column.type)) {\n const dateValueText = dateFilterFormatter.format(value as Date);\n const previewValue = previewFilterFormatter.format(value as Date);\n if (quickFilters.get(modelColumn)) {\n filterMenu.actions.push({\n title: 'And',\n actions: this.dateFilterActions(\n column,\n dateValueText,\n previewValue,\n value,\n quickFilters.get(modelColumn),\n '&&'\n ),\n order: 2,\n group: ContextActions.groups.high,\n });\n }\n filterMenu.actions.push(\n ...this.dateFilterActions(\n column,\n dateValueText,\n previewValue,\n value,\n quickFilters.get(modelColumn)\n )\n );\n } else {\n if (quickFilters.get(modelColumn)) {\n filterMenu.actions.push({\n title: 'And',\n\n actions: this.stringFilterActions(\n column,\n valueText,\n value,\n quickFilters.get(modelColumn),\n '&&'\n ),\n order: 2,\n group: ContextActions.groups.high,\n });\n }\n filterMenu.actions.push(\n ...this.stringFilterActions(column, valueText, value)\n );\n }\n\n if (filterMenu.actions != null && filterMenu.actions.length > 0) {\n actions.push(filterMenu);\n }\n }\n\n // Expand/Collapse options\n if (isExpandableGridModel(model) && model.isRowExpandable(modelRow)) {\n // If there are grouped columns, then it is a rollup\n // For rollups, the column number will be the depth minus one\n const expandingColumn =\n model.groupedColumns.length > 0 ? model.depthForRow(modelRow) - 1 : 0;\n const cellValue = model.valueForCell(expandingColumn, modelRow);\n const cellText =\n cellValue == null\n ? 'null'\n : model.textForCell(expandingColumn, modelRow);\n\n actions.push({\n title: IrisGridContextMenuHandler.getRowOptionFormatted(\n model.isRowExpanded(modelRow) ? 'Collapse' : 'Expand',\n cellText\n ),\n group: IrisGridContextMenuHandler.GROUP_EXPAND_COLLAPSE,\n order: 10,\n action: () => {\n model.setRowExpanded(modelRow, !model.isRowExpanded(modelRow));\n },\n });\n\n if (model.isExpandAllAvailable === true) {\n actions.push({\n title: IrisGridContextMenuHandler.getRowOptionFormatted(\n 'Expand All in',\n cellText\n ),\n group: IrisGridContextMenuHandler.GROUP_EXPAND_COLLAPSE,\n order: 20,\n action: () => {\n model.setRowExpanded(modelRow, true, true);\n },\n });\n }\n }\n\n if (\n isExpandableGridModel(model) &&\n model.hasExpandableRows &&\n model.isExpandAllAvailable === true\n ) {\n actions.push({\n title: 'Expand Entire Table',\n group: IrisGridContextMenuHandler.GROUP_EXPAND_COLLAPSE,\n order: 30,\n action: () => {\n model.expandAll();\n },\n });\n\n actions.push({\n title: 'Collapse Entire Table',\n group: IrisGridContextMenuHandler.GROUP_EXPAND_COLLAPSE,\n order: 40,\n action: () => {\n model.collapseAll();\n },\n });\n }\n\n const gotoRow = {\n title: 'Go to',\n iconColor: filterIconColor,\n shortcut: SHORTCUTS.TABLE.GOTO_ROW,\n group: IrisGridContextMenuHandler.GROUP_GOTO,\n order: 10,\n action: () =>\n this.irisGrid.toggleGotoRow(`${rowIndex + 1}`, `${value}`, column.name),\n };\n actions.push(gotoRow);\n\n if (canCopy) {\n actions.push({\n title: 'Copy Cell',\n group: IrisGridContextMenuHandler.GROUP_COPY,\n order: 10,\n action: () => {\n irisGrid.copyCell(columnIndex, rowIndex);\n },\n });\n\n actions.push({\n title: 'Copy Cell Unformatted',\n group: IrisGridContextMenuHandler.GROUP_COPY,\n order: 20,\n action: () => {\n irisGrid.copyCell(columnIndex, rowIndex, true);\n },\n });\n }\n\n return actions;\n }\n\n /**\n * Gets an equality filter for the provided numeric value\n * @param column The column to make the filter for\n * @param value The value to get the equality filter for\n */\n getNumberValueEqualsFilter(column: Column, value: number): FilterCondition {\n const { dh } = this;\n const columnFilter = column.filter();\n if (value === Number.POSITIVE_INFINITY) {\n return dh.FilterCondition.invoke('isInf', columnFilter).and(\n columnFilter.greaterThan(dh.FilterValue.ofNumber(0))\n );\n }\n if (value === Number.NEGATIVE_INFINITY) {\n return dh.FilterCondition.invoke('isInf', columnFilter).and(\n columnFilter.lessThan(dh.FilterValue.ofNumber(0))\n );\n }\n if (Number.isNaN(value)) {\n return dh.FilterCondition.invoke('isNaN', columnFilter);\n }\n\n const filterValue = this.getFilterValueForNumberOrChar(column.type, value);\n return columnFilter.eq(filterValue);\n }\n\n getFilterValueForNumberOrChar(\n columnType: string,\n value: unknown\n ): FilterValue {\n const { dh } = this;\n return TableUtils.isCharType(columnType)\n ? dh.FilterValue.ofString(String.fromCharCode(value as number))\n : dh.FilterValue.ofNumber(value);\n }\n\n onContextMenu(\n gridPoint: GridPoint,\n grid: Grid,\n event: React.MouseEvent<Element, MouseEvent>\n ): EventHandlerResult {\n const { irisGrid } = this;\n const {\n y,\n column: columnIndex,\n row: rowIndex,\n columnHeaderDepth,\n } = gridPoint;\n const modelColumn = irisGrid.getModelColumn(columnIndex);\n const modelRow = irisGrid.getModelRow(rowIndex);\n\n const { model, canCopy } = irisGrid.props;\n const { columns } = model;\n\n const {\n metrics,\n isFilterBarShown,\n quickFilters,\n advancedFilters,\n selectedRanges,\n } = irisGrid.state;\n\n assertNotNull(metrics);\n\n const { columnHeaderHeight, gridY, columnHeaderMaxDepth } = metrics;\n\n const actions = [] as ContextAction[];\n\n if (modelColumn != null && modelRow != null) {\n const value = model.valueForCell(modelColumn, modelRow);\n\n const valueText = model.textForCell(modelColumn, modelRow);\n const column = columns[modelColumn];\n\n const { onContextMenu } = irisGrid.props;\n\n if (column != null) {\n actions.push(\n onContextMenu({\n model,\n value,\n valueText,\n column,\n rowIndex,\n columnIndex,\n modelRow,\n modelColumn,\n })\n );\n }\n }\n\n if (modelColumn != null && model.isFilterable(modelColumn)) {\n // Clear column filter should still be available after last row\n // And should be available in both header and body context menus\n actions.push({\n title: 'Clear Column Filter',\n group: IrisGridContextMenuHandler.GROUP_FILTER,\n order: 30,\n action: () => {\n this.irisGrid.removeColumnFilter(modelColumn);\n },\n disabled: !(\n quickFilters.has(modelColumn) || advancedFilters.has(modelColumn)\n ),\n });\n }\n\n if (\n isFilterBarShown\n ? y <= gridY\n : y <= columnHeaderHeight * columnHeaderMaxDepth &&\n columnHeaderDepth === 0\n ) {\n // grid header context menu options\n if (modelColumn != null) {\n actions.push(...this.getHeaderActions(modelColumn, gridPoint));\n }\n } else {\n // grid body context menu options\n if (modelColumn != null && modelRow != null) {\n actions.push(...this.getCellActions(modelColumn, grid, gridPoint));\n }\n\n // blank space context menu options\n if (canCopy && selectedRanges.length > 0) {\n actions.push({\n title: 'Copy Selection',\n shortcut: GLOBAL_SHORTCUTS.COPY,\n group: IrisGridContextMenuHandler.GROUP_COPY,\n order: 30,\n action: () => {\n irisGrid.copyRanges(selectedRanges);\n },\n });\n\n actions.push({\n title: 'Copy Selection w/ Headers',\n group: IrisGridContextMenuHandler.GROUP_COPY,\n order: 40,\n action: () => {\n irisGrid.copyRanges(selectedRanges, true);\n },\n });\n }\n\n if (\n isEditableGridModel(model) &&\n model.isEditable &&\n selectedRanges.length > 0\n ) {\n actions.push({\n title: 'Delete Selected Rows',\n group: IrisGridContextMenuHandler.GROUP_EDIT,\n order: 50,\n action: () => {\n this.irisGrid.deleteRanges(selectedRanges);\n },\n });\n }\n }\n\n if (actions.length === 0) {\n return false;\n }\n\n assertNotNull(irisGrid.gridWrapper);\n\n ContextActions.triggerMenu(\n irisGrid.gridWrapper,\n event.clientX,\n event.clientY,\n actions\n );\n return true;\n }\n\n dateFormatActions(column: Column): ContextAction[] {\n const { model } = this.irisGrid.props;\n const { formatter } = model;\n const selectedFormat = formatter.getColumnFormat(column.type, column.name);\n\n const formatOptions = DateTimeFormatContextMenu.getOptions(\n formatter,\n selectedFormat\n );\n\n const actions = [];\n\n for (let i = 0; i < formatOptions.length; i += 1) {\n const { description, format, group, isSelected, title } = formatOptions[\n i\n ];\n actions.push({\n title,\n description,\n icon: isSelected ? vsCheck : undefined,\n group,\n order: i,\n action: () => {\n const modelIndex = model.getColumnIndexByName(column.name);\n assertNotNull(modelIndex);\n this.irisGrid.handleFormatSelection(modelIndex, format);\n },\n });\n }\n return actions;\n }\n\n numberFormatActions(column: Column): ContextAction[] | null {\n const { model } = this.irisGrid.props;\n const { formatter } = model;\n const { dh } = this;\n const selectedFormat = formatter.getColumnFormat(\n column.type,\n column.name\n ) as IntegerColumnFormat;\n let formatOptions;\n\n const columnIndex = model.getColumnIndexByName(column.name);\n if (TableUtils.isDecimalType(column.type)) {\n formatOptions = DecimalFormatContextMenu.getOptions(\n dh,\n selectedFormat,\n format => {\n assertNotNull(columnIndex);\n this.debouncedUpdateCustomFormat(columnIndex, format);\n }\n );\n } else if (TableUtils.isIntegerType(column.type)) {\n formatOptions = IntegerFormatContextMenu.getOptions(\n dh,\n selectedFormat,\n format => {\n assertNotNull(columnIndex);\n this.debouncedUpdateCustomFormat(columnIndex, format);\n }\n );\n } else {\n log.error('Invalid column type in numberFormatActions');\n return null;\n }\n\n const actions = [];\n\n for (let i = 0; i < formatOptions.length; i += 1) {\n const { format, isSelected } = formatOptions[i];\n actions.push({\n ...formatOptions[i],\n icon: isSelected ? vsCheck : undefined,\n order: i,\n action: () => {\n if (\n columnIndex === undefined &&\n format &&\n format.type === TableColumnFormatter.TYPE_CONTEXT_CUSTOM\n ) {\n return;\n }\n assertNotNull(columnIndex);\n this.irisGrid.handleFormatSelection(columnIndex, format);\n },\n });\n }\n return actions;\n }\n\n stringFilterActions(\n column: Column,\n valueText: string | null,\n value?: unknown,\n quickFilter?: QuickFilter,\n operator?: '&&' | '||' | null\n ): ContextAction[] {\n const { dh } = this;\n const filterValue = dh.FilterValue.ofString(value);\n let newQuickFilter:\n | {\n filter: null | FilterCondition | undefined;\n text: string | null;\n }\n | undefined\n | null = quickFilter;\n if (!newQuickFilter) {\n newQuickFilter = { filter: null, text: null };\n }\n const { filter, text: filterText } = newQuickFilter;\n const actions = [];\n const { model } = this.irisGrid.props;\n const columnIndex = model.getColumnIndexByName(column.name);\n assertNotNull(columnIndex);\n\n actions.push({\n menuElement: (\n <div className=\"iris-grid-filter-menu-item-value\">\n {operator\n ? IrisGridContextMenuHandler.getOperatorAsText(operator)\n : ''}{' '}\n &quot;{valueText}&quot;\n </div>\n ),\n order: 1,\n group: ContextActions.groups.high,\n });\n\n actions.push({\n title: 'text is exactly',\n description: `Show only rows where ${column.name} is ${value} (case sensitive)`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().eq(filterValue),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n `=${valueText}`,\n operator\n )\n );\n },\n order: 10,\n group: ContextActions.groups.low,\n });\n actions.push({\n title: 'text is not exactly',\n description: `Show only rows where ${column.name} is not ${valueText} (case sensitive)`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().notEq(filterValue),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n `!=${valueText}`,\n operator\n )\n );\n },\n order: 20,\n group: ContextActions.groups.low,\n });\n actions.push({\n title: `text contains`,\n description: `Show only rows where ${column.name} contains ${valueText}`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().contains(filterValue),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n `~${valueText}`,\n operator\n )\n );\n },\n order: 30,\n group: ContextActions.groups.low,\n });\n actions.push({\n title: 'text does not contain',\n description: `Show only rows where ${column.name} does not contain ${value}`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().contains(filterValue).not(),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n `!~${valueText}`,\n operator\n )\n );\n },\n order: 40,\n group: ContextActions.groups.low,\n });\n actions.push({\n title: 'text starts with',\n description: `Show only rows where ${column.name} starts with ${valueText}`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().invoke('startsWith', filterValue),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n `${valueText}*`,\n operator\n )\n );\n },\n order: 50,\n group: ContextActions.groups.low,\n });\n actions.push({\n title: 'text ends with',\n description: `Show only rows where ${column.name} ends with ${valueText}`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().invoke('endsWith', filterValue),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n `*${valueText}`,\n operator\n )\n );\n },\n order: 60,\n group: ContextActions.groups.low,\n });\n return actions;\n }\n\n numberFilterActions(\n column: Column,\n valueText: string,\n value: unknown,\n quickFilter?: QuickFilter | null,\n operator?: '&&' | '||' | null\n ): ContextAction[] {\n const filterValue = this.getFilterValueForNumberOrChar(column.type, value);\n let filter: FilterCondition | null = null;\n let filterText: string | null = null;\n if (quickFilter) {\n filter = quickFilter.filter;\n filterText = quickFilter.text;\n }\n const actions = [];\n const isFinite =\n value !== Number.POSITIVE_INFINITY &&\n value !== Number.NEGATIVE_INFINITY &&\n !Number.isNaN(value);\n const { model } = this.irisGrid.props;\n const columnIndex = model.getColumnIndexByName(column.name);\n assertNotNull(columnIndex);\n actions.push({\n menuElement: (\n <div className=\"iris-grid-filter-menu-item-value\">\n {operator\n ? IrisGridContextMenuHandler.getOperatorAsText(operator)\n : ''}{' '}\n &quot;{valueText}&quot;\n </div>\n ),\n order: 1,\n group: ContextActions.groups.high,\n });\n actions.push({\n title: 'is equal to',\n description: `Show only rows where ${column.name} is ${valueText}`,\n action: () => {\n const valueFilter = this.getNumberValueEqualsFilter(\n column,\n value as number\n );\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n valueFilter,\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n `=${valueText}`,\n operator\n )\n );\n },\n order: 10,\n group: ContextActions.groups.low,\n });\n actions.push({\n title: 'is not equal to',\n description: `Show only rows where ${column.name} is not ${valueText}`,\n action: () => {\n const valueFilter = this.getNumberValueEqualsFilter(\n column,\n value as number\n ).not();\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n valueFilter,\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n `!=${valueText}`,\n operator\n )\n );\n },\n order: 20,\n group: ContextActions.groups.low,\n });\n\n // IDS-6092 Less/greater than filters don't make sense for Infinite/NaN\n // TODO (DH-11799): These char filters should work in Bard, with the merge for DH-11040: https://gitlab.eng.illumon.com/illumon/iris/merge_requests/5801\n // They do not work in Powell though, so disable them.\n if (isFinite && !TableUtils.isCharType(column.type)) {\n actions.push({\n title: 'greater than',\n description: `Show only rows where ${column.name} is greater than ${valueText}`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().greaterThan(filterValue),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n `>${valueText}`,\n operator\n )\n );\n },\n order: 30,\n group: ContextActions.groups.low,\n });\n actions.push({\n title: 'greater than or equal to',\n description: `Show only rows where ${column.name} is greater than or equal to ${valueText}`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().greaterThanOrEqualTo(filterValue),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n `>=${valueText}`,\n operator\n )\n );\n },\n order: 40,\n group: ContextActions.groups.low,\n });\n actions.push({\n title: 'less than',\n description: `Show only rows where ${column.name} is less than ${valueText}`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().lessThan(filterValue),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n `<${valueText}`,\n operator\n )\n );\n },\n order: 50,\n group: ContextActions.groups.low,\n });\n actions.push({\n title: 'less than or equal to',\n description: `Show only rows where ${column.name} is less than or equal to ${valueText}`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().lessThanOrEqualTo(filterValue),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n `<=${valueText}`,\n operator\n )\n );\n },\n order: 60,\n group: ContextActions.groups.low,\n });\n }\n return actions;\n }\n\n booleanFilterActions(\n column: Column,\n valueText: string | null,\n quickFilter?: QuickFilter | null,\n operator?: '&&' | '||' | null\n ): ContextAction[] {\n const actions: ContextAction[] = [];\n\n const { model } = this.irisGrid.props;\n const { filter, text: filterText } = quickFilter || {};\n const columnIndex = model.getColumnIndexByName(column.name);\n assertNotNull(columnIndex);\n\n actions.push({\n menuElement: (\n <div className=\"iris-grid-filter-menu-item-value\">\n {operator\n ? IrisGridContextMenuHandler.getOperatorAsText(operator)\n : ''}{' '}\n &quot;{valueText ?? 'null'}&quot;\n </div>\n ),\n order: 1,\n group: ContextActions.groups.high,\n });\n\n actions.push({\n title: 'true',\n description: `Show only rows where ${column.name} is true`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().isTrue(),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n 'true',\n operator\n )\n );\n },\n order: 10,\n group: ContextActions.groups.low,\n });\n actions.push({\n title: 'false',\n description: `Show only rows where ${column.name} is false`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().isFalse(),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n 'false',\n operator\n )\n );\n },\n order: 20,\n group: ContextActions.groups.low,\n });\n actions.push({\n title: 'is null',\n description: `Show only rows where ${column.name} is null`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().isNull(),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n 'null',\n operator\n )\n );\n },\n order: 30,\n group: ContextActions.groups.low,\n });\n\n actions.push({\n title: 'is not null',\n description: `Show only rows where ${column.name} is not null`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().isNull().not(),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n '!null',\n operator\n )\n );\n },\n order: 40,\n group: ContextActions.groups.low,\n });\n\n return actions;\n }\n\n dateFilterActions(\n column: Column,\n valueText: string,\n previewValue: unknown,\n value: unknown,\n quickFilter?: QuickFilter | null,\n operator?: '&&' | '||' | null\n ): ContextAction[] {\n const { dh } = this;\n const filterValue = dh.FilterValue.ofNumber(value);\n\n let filter: FilterCondition | null = null;\n let filterText: string | null = null;\n if (quickFilter) {\n filter = quickFilter.filter;\n filterText = quickFilter.text;\n }\n const { model } = this.irisGrid.props;\n const columnIndex = model.getColumnIndexByName(column.name);\n assertNotNull(columnIndex);\n\n const actions = [];\n\n actions.push({\n menuElement: (\n <div className=\"iris-grid-filter-menu-item-value\">\n {operator\n ? IrisGridContextMenuHandler.getOperatorAsText(operator)\n : ''}{' '}\n &quot;{previewValue}&quot;\n </div>\n ),\n order: 1,\n group: ContextActions.groups.high,\n });\n actions.push({\n title: 'date is',\n description: `Show only rows where ${column.name} is ${previewValue}`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().eq(filterValue),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n `=${valueText}`,\n operator\n )\n );\n },\n order: 10,\n group: ContextActions.groups.low,\n });\n actions.push({\n title: 'date is not',\n description: `Show only rows where ${column.name} is not ${previewValue}`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().notEq(filterValue),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n `!=${valueText}`,\n operator\n )\n );\n },\n order: 20,\n group: ContextActions.groups.low,\n });\n actions.push({\n title: 'date is before',\n description: `Show only rows where ${column.name} is before ${previewValue}`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().lessThan(filterValue),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n `<${valueText}`,\n operator\n )\n );\n },\n order: 30,\n group: ContextActions.groups.low,\n });\n actions.push({\n title: 'date is before or equal',\n description: `Show only rows where ${column.name} is before or equal to ${previewValue}`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().lessThanOrEqualTo(filterValue),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n `<=${valueText}`,\n operator\n )\n );\n },\n order: 40,\n group: ContextActions.groups.low,\n });\n actions.push({\n title: 'date is after',\n description: `Show only rows where ${column.name} is greater than ${previewValue}`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().greaterThan(filterValue),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n `>${valueText}`,\n operator\n )\n );\n },\n order: 50,\n group: ContextActions.groups.low,\n });\n actions.push({\n title: 'date is after or equal',\n description: `Show only rows where ${column.name} is after or equal to ${previewValue}`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().greaterThanOrEqualTo(filterValue),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n `>=${valueText}`,\n operator\n )\n );\n },\n order: 60,\n group: ContextActions.groups.low,\n });\n return actions;\n }\n\n nullFilterActions(\n column: Column,\n quickFilter?: QuickFilter,\n operator?: '&&' | '||' | null\n ): ContextAction[] {\n let filter: FilterCondition | null = null;\n let filterText: string | null = null;\n if (quickFilter) {\n filter = quickFilter.filter;\n filterText = quickFilter.text;\n }\n const actions = [];\n const { model } = this.irisGrid.props;\n const columnIndex = model.getColumnIndexByName(column.name);\n assertNotNull(columnIndex);\n\n actions.push({\n menuElement: (\n <div className=\"iris-grid-filter-menu-item-value\">\n {operator\n ? IrisGridContextMenuHandler.getOperatorAsText(operator)\n : ''}{' '}\n &quot;null&quot;\n </div>\n ),\n order: 1,\n group: ContextActions.groups.high,\n });\n actions.push({\n title: 'is null',\n description: `Show only rows where ${column.name} is null`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().isNull(),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n 'null',\n operator\n )\n );\n },\n order: 10,\n group: ContextActions.groups.low,\n });\n actions.push({\n title: 'is not null',\n description: `Show only rows where ${column.name} is not null`,\n action: () => {\n this.irisGrid.setQuickFilter(\n columnIndex,\n IrisGridContextMenuHandler.getQuickFilterCondition(\n filter,\n column.filter().isNull().not(),\n operator\n ),\n IrisGridContextMenuHandler.getQuickFilterText(\n filterText,\n '!null',\n operator\n )\n );\n },\n order: 20,\n group: ContextActions.groups.low,\n });\n\n return actions;\n }\n\n sortByActions(\n column: Column,\n modelColumn: ModelIndex,\n columnSort: Sort | null\n ): ContextAction[] {\n const theme = this.irisGrid.getTheme();\n const { contextMenuSortIconColor } = theme;\n const sortActions = [\n {\n title: `${column.name} Ascending`,\n order: 10,\n action: () => {\n this.irisGrid.sortColumn(\n modelColumn,\n IrisGridContextMenuHandler.COLUMN_SORT_DIRECTION.ascending\n );\n },\n icon: this.checkColumnSort(\n columnSort,\n IrisGridContextMenuHandler.COLUMN_SORT_DIRECTION.ascending\n )\n ? vsRemove\n : undefined,\n iconColor: contextMenuSortIconColor,\n },\n {\n title: `${column.name} Descending`,\n order: 20,\n action: () => {\n this.irisGrid.sortColumn(\n modelColumn,\n IrisGridContextMenuHandler.COLUMN_SORT_DIRECTION.descending\n );\n },\n icon: this.checkColumnSort(\n columnSort,\n IrisGridContextMenuHandler.COLUMN_SORT_DIRECTION.descending\n )\n ? vsRemove\n : undefined,\n iconColor: contextMenuSortIconColor,\n },\n {\n title: `Remove Sort`,\n order: 50,\n action: () => {\n this.irisGrid.sortColumn(\n modelColumn,\n IrisGridContextMenuHandler.COLUMN_SORT_DIRECTION.none,\n false,\n true\n );\n },\n disabled: !columnSort,\n },\n ];\n if (TableUtils.isNumberType(column.type)) {\n sortActions.push({\n title: `ABS(${column.name}) Ascending`,\n order: 30,\n action: () => {\n this.irisGrid.sortColumn(\n modelColumn,\n IrisGridContextMenuHandler.COLUMN_SORT_DIRECTION.ascending,\n true\n );\n },\n icon: this.checkColumnSort(\n columnSort,\n IrisGridContextMenuHandler.COLUMN_SORT_DIRECTION.ascending,\n true\n )\n ? vsRemove\n : undefined,\n iconColor: contextMenuSortIconColor,\n });\n sortActions.push({\n title: `ABS(${column.name}) Descending`,\n order: 40,\n action: () => {\n this.irisGrid.sortColumn(\n modelColumn,\n IrisGridContextMenuHandler.COLUMN_SORT_DIRECTION.descending,\n true\n );\n },\n icon: this.checkColumnSort(\n columnSort,\n IrisGridContextMenuHandler.COLUMN_SORT_DIRECTION.descending,\n true\n )\n ? vsRemove\n : undefined,\n iconColor: contextMenuSortIconColor,\n });\n }\n return sortActions;\n }\n\n additionalSortActions(\n column: Column,\n columnIndex: ModelIndex\n ): ContextAction[] {\n const theme = this.irisGrid.getTheme();\n const { contextMenuSortIconColor } = theme;\n const additionalSortActions = [\n {\n title: 'Add Sort By',\n menuElement: (\n <div className=\"btn-context-menu menu-title\">\n <span className=\"icon\">\n <FontAwesomeIcon\n icon={vsRemove}\n style={{ color: contextMenuSortIconColor ?? undefined }}\n />\n </span>\n <span className=\"title\">Add Additional Sort</span>\n <span className=\"shortcut\">\n {ContextActionUtils.isMacPlatform() ? '⌘Click' : 'Ctrl+Click'}\n </span>\n </div>\n ),\n order: 1,\n },\n {\n title: `${column.name} Ascending`,\n order: 10,\n action: () => {\n this.irisGrid.sortColumn(\n columnIndex,\n IrisGridContextMenuHandler.COLUMN_SORT_DIRECTION.ascending,\n false,\n true\n );\n },\n },\n {\n title: `${column.name} Descending`,\n order: 20,\n action: () => {\n this.irisGrid.sortColumn(\n columnIndex,\n IrisGridContextMenuHandler.COLUMN_SORT_DIRECTION.descending,\n false,\n true\n );\n },\n },\n ];\n if (TableUtils.isNumberType(column.type)) {\n additionalSortActions.push({\n title: `ABS(${column.name}) Ascending`,\n order: 30,\n action: () => {\n this.irisGrid.sortColumn(\n columnIndex,\n IrisGridContextMenuHandler.COLUMN_SORT_DIRECTION.ascending,\n true,\n true\n );\n },\n });\n additionalSortActions.push({\n title: `ABS(${column.name}) Descending`,\n order: 40,\n action: () => {\n this.irisGrid.sortColumn(\n columnIndex,\n IrisGridContextMenuHandler.COLUMN_SORT_DIRECTION.descending,\n true,\n true\n );\n },\n });\n }\n return additionalSortActions;\n }\n\n checkColumnSort(\n columnSort?: Sort | null,\n direction: SortDirection = null,\n isAbs = false\n ): boolean {\n if (!columnSort) {\n return false;\n }\n return columnSort.direction === direction && columnSort.isAbs === isAbs;\n }\n}\n\nexport default IrisGridContextMenuHandler;\n","/* eslint class-methods-use-this: \"off\" */\nimport {\n GridMouseHandler,\n GridPoint,\n EventHandlerResult,\n} from '@deephaven/grid';\nimport type { IrisGrid } from '../IrisGrid';\n\n/**\n * Handles sending data selected via double click\n */\nclass IrisGridDataSelectMouseHandler extends GridMouseHandler {\n constructor(irisGrid: IrisGrid) {\n super();\n\n this.irisGrid = irisGrid;\n }\n\n irisGrid: IrisGrid;\n\n onDoubleClick(gridPoint: GridPoint): EventHandlerResult {\n const { column, row } = gridPoint;\n if (row == null || column == null) {\n return false;\n }\n\n this.irisGrid.selectData(column, row);\n\n return true;\n }\n}\n\nexport default IrisGridDataSelectMouseHandler;\n","/* eslint class-methods-use-this: \"off\" */\nimport {\n GridMouseHandler,\n GridPoint,\n EventHandlerResult,\n} from '@deephaven/grid';\nimport type { IrisGrid } from '../IrisGrid';\n\n/**\n * Trigger quick filters and advanced filters\n */\nclass IrisGridFilterMouseHandler extends GridMouseHandler {\n constructor(irisGrid: IrisGrid) {\n super();\n\n this.irisGrid = irisGrid;\n }\n\n irisGrid: IrisGrid;\n\n onDown(gridPoint: GridPoint): EventHandlerResult {\n const { y, column, row } = gridPoint;\n if (column !== null && row === null) {\n const { isFilterBarShown, metrics } = this.irisGrid.state;\n if (!metrics) throw new Error('Metrics not set');\n\n const { columnHeaderMaxDepth } = metrics;\n const theme = this.irisGrid.getTheme();\n if (\n isFilterBarShown &&\n theme.columnHeaderHeight != null &&\n theme.filterBarHeight != null &&\n y > theme.columnHeaderHeight * columnHeaderMaxDepth &&\n y <=\n theme.columnHeaderHeight * columnHeaderMaxDepth +\n theme.filterBarHeight\n ) {\n this.irisGrid.focusFilterBar(column);\n return true;\n }\n }\n\n return false;\n }\n\n onMove(gridPoint: GridPoint): EventHandlerResult {\n const { y, column } = gridPoint;\n const {\n isFilterBarShown,\n hoverAdvancedFilter,\n metrics,\n } = this.irisGrid.state;\n if (!metrics) throw new Error('Metrics not set');\n const { columnHeaderMaxDepth } = metrics;\n const theme = this.irisGrid.getTheme();\n\n let newHoverAdvancedFilter = null;\n if (\n isFilterBarShown &&\n theme.columnHeaderHeight != null &&\n theme.filterBarHeight != null &&\n column !== null &&\n y >= theme.columnHeaderHeight * columnHeaderMaxDepth &&\n y <=\n theme.columnHeaderHeight * columnHeaderMaxDepth + theme.filterBarHeight\n ) {\n newHoverAdvancedFilter = column;\n }\n\n if (newHoverAdvancedFilter !== hoverAdvancedFilter) {\n this.irisGrid.setState({ hoverAdvancedFilter: newHoverAdvancedFilter });\n }\n\n return false;\n }\n\n onLeave(gridPoint: GridPoint): EventHandlerResult {\n const { column } = gridPoint;\n const { hoverAdvancedFilter } = this.irisGrid.state;\n if (hoverAdvancedFilter !== null && column !== hoverAdvancedFilter) {\n this.irisGrid.setState({ hoverAdvancedFilter: null });\n }\n\n return false;\n }\n}\n\nexport default IrisGridFilterMouseHandler;\n","import {\n EventHandlerResult,\n Grid,\n GridMouseHandler,\n GridPoint,\n GridRowTreeMouseHandler,\n isExpandableGridModel,\n} from '@deephaven/grid';\nimport { assertNotNull } from '@deephaven/utils';\nimport deepEqual from 'deep-equal';\nimport type IrisGrid from '../IrisGrid';\n\nclass IrisGridRowTreeMouseHandler extends GridMouseHandler {\n private irisGrid: IrisGrid;\n\n constructor(irisGrid: IrisGrid) {\n super(750); // Needs to be before GridRowTreeMouseHandler\n\n this.irisGrid = irisGrid;\n }\n\n private destroyTooltip(): void {\n this.irisGrid.setState({ expandCellTooltipProps: null });\n }\n\n private setCursor(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n if (GridRowTreeMouseHandler.isInTreeBox(gridPoint, grid)) {\n this.cursor = 'pointer';\n return { stopPropagation: false, preventDefault: false };\n }\n\n this.cursor = null;\n return false;\n }\n\n private getButtonPosition({\n x,\n y,\n column,\n row,\n }: GridPoint): {\n left: number;\n top: number;\n width: number;\n height: number;\n } | null {\n if (column == null || row == null) {\n return null;\n }\n const { renderer, grid, state, props } = this.irisGrid;\n if (!grid) {\n return null;\n }\n const { metrics } = state;\n const { model } = props;\n\n const { canvasContext: context } = grid;\n const theme = grid.getTheme();\n const rendererState = {\n context,\n mouseX: x,\n mouseY: y,\n metrics,\n model,\n theme,\n };\n\n const depth = isExpandableGridModel(model) ? model.depthForRow(row) : null;\n\n const { left, top, width, height } = renderer.getExpandButtonPosition(\n rendererState,\n depth\n );\n if (left == null || width == null || top == null || height == null) {\n return null;\n }\n\n return { left, top, width, height };\n }\n\n onMove(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n if (GridRowTreeMouseHandler.isInTreeBox(gridPoint, grid)) {\n const { expandCellTooltipProps } = this.irisGrid.state;\n const { model } = this.irisGrid.props;\n const newProps = this.getButtonPosition(gridPoint);\n const { row } = gridPoint;\n assertNotNull(row);\n const isRowExpanded =\n isExpandableGridModel(model) && model.isRowExpanded(row);\n if (!deepEqual(expandCellTooltipProps, newProps)) {\n this.irisGrid.setState({\n expandCellTooltipProps: newProps,\n expandTooltipDisplayValue: isRowExpanded ? 'collapse' : 'expand',\n });\n }\n } else {\n this.destroyTooltip();\n }\n return this.setCursor(gridPoint, grid);\n }\n\n onDown(): EventHandlerResult {\n this.destroyTooltip();\n return false;\n }\n\n onContextMenu(): EventHandlerResult {\n this.destroyTooltip();\n return false;\n }\n\n onWheel(): EventHandlerResult {\n this.destroyTooltip();\n return false;\n }\n\n onLeave(): EventHandlerResult {\n this.destroyTooltip();\n return false;\n }\n}\n\nexport default IrisGridRowTreeMouseHandler;\n","/* eslint class-methods-use-this: \"off\" */\nimport { ContextActionUtils } from '@deephaven/components';\nimport {\n Grid,\n GridMouseEvent,\n GridMouseHandler,\n GridPoint,\n GridRangeIndex,\n EventHandlerResult,\n} from '@deephaven/grid';\nimport type { IrisGrid } from '../IrisGrid';\n\n/**\n * Used to handle sorting on column header clicks\n */\nclass IrisGridSortMouseHandler extends GridMouseHandler {\n constructor(irisGrid: IrisGrid) {\n super();\n\n this.column = null;\n this.irisGrid = irisGrid;\n }\n\n irisGrid: IrisGrid;\n\n column: GridRangeIndex;\n\n getColumnFromGridPoint(gridPoint: GridPoint): GridRangeIndex {\n const { column, row, columnHeaderDepth } = gridPoint;\n if (column !== null && row === null && columnHeaderDepth === 0) {\n return column;\n }\n\n return null;\n }\n\n // We need to remember where the down started, because the canvas element will trigger a click whereever mouseUp is\n onDown(gridPoint: GridPoint): EventHandlerResult {\n this.column = this.getColumnFromGridPoint(gridPoint);\n return false;\n }\n\n onClick(\n gridPoint: GridPoint,\n grid: Grid,\n event: GridMouseEvent\n ): EventHandlerResult {\n const column = this.getColumnFromGridPoint(gridPoint);\n if (column != null && column === this.column) {\n const addToExisting = ContextActionUtils.isModifierKeyDown(event);\n this.irisGrid.toggleSort(column, addToExisting);\n return true;\n }\n\n return false;\n }\n}\n\nexport default IrisGridSortMouseHandler;\n","/* eslint class-methods-use-this: \"off\" */\nimport {\n Grid,\n GridMouseHandler,\n GridPoint,\n GridUtils,\n GridWheelEvent,\n isEditableGridModel,\n} from '@deephaven/grid';\nimport { assertNotNull } from '@deephaven/utils';\nimport IrisGrid from '../IrisGrid';\n\n/**\n * Handles sending data selected via double click\n */\n\ninterface PendingMouseHandler {\n irisGrid: IrisGrid;\n}\nclass PendingMouseHandler extends GridMouseHandler {\n constructor(irisGrid: IrisGrid) {\n super();\n\n this.irisGrid = irisGrid;\n }\n\n onWheel(gridPoint: GridPoint, grid: Grid, wheelEvent: GridWheelEvent): false {\n const { irisGrid } = this;\n const { model } = irisGrid.props;\n const { metrics, pendingRowCount } = irisGrid.state;\n assertNotNull(metrics);\n const { bottom, rowCount, rowHeight } = metrics;\n const { deltaY } = GridUtils.getScrollDelta(wheelEvent);\n if (\n isEditableGridModel(model) &&\n model.isEditable &&\n bottom >= rowCount - 1 &&\n deltaY > 0\n ) {\n // We add new rows onto the bottom, but we don't consume the event\n irisGrid.setState({\n pendingRowCount: pendingRowCount + Math.ceil(deltaY / rowHeight),\n });\n }\n return false;\n }\n}\n\nexport default PendingMouseHandler;\n","import {\n EventHandlerResult,\n Grid,\n GridMouseHandler,\n GridPoint,\n GridUtils,\n isLinkToken,\n TokenBox,\n} from '@deephaven/grid';\nimport deepEqual from 'deep-equal';\nimport IrisGrid from '../IrisGrid';\n\nclass IrisGridTokenMouseHandler extends GridMouseHandler {\n private irisGrid: IrisGrid;\n\n // Stores the current hovered token box if it exists with translated coordinates\n private currentLinkBox?: TokenBox;\n\n constructor(irisGrid: IrisGrid) {\n super();\n\n this.irisGrid = irisGrid;\n }\n\n private destroyTooltip(): void {\n this.irisGrid.setState({ linkHoverTooltipProps: null });\n }\n\n isHoveringLink(gridPoint: GridPoint, grid: Grid): boolean {\n const { column, row, x, y } = gridPoint;\n const { renderer, metrics } = grid;\n\n if (column == null || row == null || metrics == null) {\n this.currentLinkBox = undefined;\n return false;\n }\n\n if (this.currentLinkBox != null) {\n const { x1: left, y1: top, x2: right, y2: bottom } = this.currentLinkBox;\n if (x >= left && x <= right && y >= top && y <= bottom) {\n return true;\n }\n }\n\n const renderState = grid.updateRenderState();\n const tokensInCell = renderer.getTokenBoxesForVisibleCell(\n column,\n row,\n renderState\n );\n\n // Loop through each link and check if cursor is in bounds\n for (let i = 0; i < tokensInCell.length; i += 1) {\n if (isLinkToken(tokensInCell[i].token)) {\n const translatedTokenBox = GridUtils.translateTokenBox(\n tokensInCell[i],\n metrics\n );\n const { x1: left, x2: right, y1: top, y2: bottom } = translatedTokenBox;\n if (x >= left && x <= right && y >= top && y <= bottom) {\n this.currentLinkBox = translatedTokenBox;\n return true;\n }\n }\n }\n\n // If this point is reached, that means the cursor was not hovering any of the links or there are no links\n this.currentLinkBox = undefined;\n return false;\n }\n\n private setCursor(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n if (this.isHoveringLink(gridPoint, grid)) {\n this.cursor = 'pointer';\n return { stopPropagation: false, preventDefault: false };\n }\n this.cursor = null;\n return false;\n }\n\n onMove(gridPoint: GridPoint, grid: Grid): EventHandlerResult {\n const isUserHoveringLink = this.isHoveringLink(gridPoint, grid);\n if (\n isUserHoveringLink &&\n this.currentLinkBox != null &&\n isLinkToken(this.currentLinkBox.token)\n ) {\n const { linkHoverTooltipProps } = this.irisGrid.state;\n if (this.currentLinkBox == null) {\n return false;\n }\n const { x1: left, y1: top, x2: right, y2: bottom } = this.currentLinkBox;\n const { href } = this.currentLinkBox.token;\n const width = right - left;\n const height = bottom - top;\n const newProps = { left, top: top + 1, width, height };\n if (!deepEqual(linkHoverTooltipProps, newProps)) {\n this.irisGrid.setState({\n linkHoverTooltipProps: newProps,\n linkHoverDisplayValue: href,\n });\n }\n } else {\n this.destroyTooltip();\n }\n\n return this.setCursor(gridPoint, grid);\n }\n\n onDown(): EventHandlerResult {\n this.destroyTooltip();\n return false;\n }\n\n onContextMenu(): EventHandlerResult {\n this.destroyTooltip();\n return false;\n }\n\n onWheel(): EventHandlerResult {\n this.destroyTooltip();\n return false;\n }\n\n onLeave(): EventHandlerResult {\n this.destroyTooltip();\n return false;\n }\n}\n\nexport default IrisGridTokenMouseHandler;\n","import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { usePrevious } from '@deephaven/react-hooks';\nimport IrisGridBottomBar from './IrisGridBottomBar';\nimport './PendingDataBottomBar.scss';\n\nconst HIDE_TIMEOUT = 3000;\n\nexport type ToastBottomBarProps = {\n children?: React.ReactNode;\n onEntering?: () => void;\n onEntered?: () => void;\n onExiting?: () => void;\n onExited?: () => void;\n};\n\nexport function ToastBottomBar({\n children = null,\n onEntering,\n onEntered,\n onExiting,\n onExited,\n}: ToastBottomBarProps): JSX.Element {\n const [isShown, setIsShown] = useState(false);\n const timeout = useRef<ReturnType<typeof setTimeout>>();\n const prevChildren = usePrevious(children);\n\n const startTimer = useCallback(() => {\n setIsShown(true);\n if (timeout.current) {\n clearTimeout(timeout.current);\n }\n timeout.current = setTimeout(() => {\n setIsShown(false);\n }, HIDE_TIMEOUT);\n }, [setIsShown, timeout]);\n\n useEffect(() => {\n if (prevChildren !== children && children != null) {\n startTimer();\n }\n }, [children, prevChildren, setIsShown, startTimer]);\n\n useEffect(\n () => () => (timeout.current ? clearTimeout(timeout.current) : undefined),\n []\n );\n\n return (\n <IrisGridBottomBar\n className=\"toast-bottom-bar\"\n isShown={isShown}\n onEntering={onEntering}\n onEntered={onEntered}\n onExiting={onExiting}\n onExited={onExited}\n >\n {children}\n </IrisGridBottomBar>\n );\n}\n\nexport default ToastBottomBar;\n","import { GridMetricCalculator, ModelSizeMap } from '@deephaven/grid';\nimport type { GridMetricState } from '@deephaven/grid';\nimport type { FilterCondition, Sort } from '@deephaven/jsapi-types';\nimport { TableUtils } from '@deephaven/jsapi-utils';\nimport type IrisGridModel from './IrisGridModel';\nimport { IrisGridThemeType } from './IrisGridTheme';\n\nexport interface IrisGridMetricState extends GridMetricState {\n model: IrisGridModel;\n theme: IrisGridThemeType;\n isFilterBarShown: boolean;\n advancedFilters: Map<\n string,\n { options: unknown; filter: FilterCondition | null }\n >;\n quickFilters: Map<string, { text: string; filter: FilterCondition | null }>;\n sorts: Sort[];\n reverseType: string;\n}\n\n/**\n * Class to calculate all the metrics for a grid.\n * Call getMetrics() with the state to get metrics\n */\nclass IrisGridMetricCalculator extends GridMetricCalculator {\n getGridY(state: IrisGridMetricState): number {\n let gridY = super.getGridY(state);\n const {\n isFilterBarShown,\n theme,\n advancedFilters,\n quickFilters,\n sorts,\n reverseType,\n } = state;\n if (isFilterBarShown) {\n gridY += theme.filterBarHeight;\n } else if (\n (quickFilters != null && quickFilters.size > 0) ||\n (advancedFilters != null && advancedFilters.size > 0)\n ) {\n gridY += theme.filterBarCollapsedHeight;\n }\n if (\n reverseType !== TableUtils.REVERSE_TYPE.NONE &&\n sorts != null &&\n sorts.length > 0\n ) {\n gridY += theme.reverseHeaderBarHeight;\n }\n\n return gridY;\n }\n\n getUserColumnWidths(): ModelSizeMap {\n return this.userColumnWidths;\n }\n}\n\nexport default IrisGridMetricCalculator;\n","/* eslint-disable react/require-default-props */\n/* eslint-disable no-param-reassign */\nimport React, { useEffect, useMemo } from 'react';\nimport type {\n Column,\n CustomColumn,\n FilterCondition,\n RollupConfig,\n Sort,\n} from '@deephaven/jsapi-types';\nimport { ModelIndex, MoveOperation } from '@deephaven/grid';\nimport { Formatter, ReverseType, TableUtils } from '@deephaven/jsapi-utils';\nimport { EMPTY_ARRAY, EMPTY_MAP } from '@deephaven/utils';\nimport IrisGridUtils from './IrisGridUtils';\nimport { ColumnName, UITotalsTableConfig, PendingDataMap } from './CommonTypes';\nimport IrisGridModel from './IrisGridModel';\nimport type ColumnHeaderGroup from './ColumnHeaderGroup';\n\nconst COLUMN_BUFFER_PAGES = 1;\n\ninterface IrisGridModelUpdaterProps {\n model: IrisGridModel;\n modelColumns: readonly Column[];\n top: number;\n bottom: number;\n left: number | null;\n right: number | null;\n filter: readonly FilterCondition[];\n sorts: readonly Sort[];\n reverseType?: ReverseType;\n customColumns: readonly ColumnName[];\n movedColumns: readonly MoveOperation[];\n hiddenColumns: readonly ModelIndex[];\n frozenColumns?: readonly ColumnName[];\n columnHeaderGroups: readonly ColumnHeaderGroup[];\n formatColumns: readonly CustomColumn[];\n alwaysFetchColumns: readonly ColumnName[];\n formatter: Formatter;\n rollupConfig?: RollupConfig | null;\n totalsConfig?: UITotalsTableConfig | null;\n selectDistinctColumns?: readonly ColumnName[];\n pendingRowCount?: number;\n pendingDataMap?: PendingDataMap;\n}\n\n/**\n * React component to keep IrisGridModel in sync\n */\nconst IrisGridModelUpdater = React.memo(\n ({\n model,\n modelColumns,\n top,\n bottom,\n left,\n right,\n filter,\n formatter,\n reverseType = TableUtils.REVERSE_TYPE.NONE,\n sorts,\n customColumns,\n movedColumns,\n hiddenColumns,\n alwaysFetchColumns,\n rollupConfig = null,\n totalsConfig = null,\n selectDistinctColumns = EMPTY_ARRAY,\n pendingRowCount = 0,\n pendingDataMap = EMPTY_MAP,\n frozenColumns,\n formatColumns,\n columnHeaderGroups,\n }: IrisGridModelUpdaterProps) => {\n const columns = useMemo(\n () =>\n IrisGridUtils.getModelViewportColumns(\n modelColumns,\n left,\n right,\n movedColumns,\n hiddenColumns,\n alwaysFetchColumns,\n COLUMN_BUFFER_PAGES\n ),\n [\n modelColumns,\n left,\n right,\n movedColumns,\n hiddenColumns,\n alwaysFetchColumns,\n ]\n );\n\n useEffect(\n function updateFilter() {\n model.filter = filter;\n },\n [model, filter]\n );\n useEffect(\n function updateSorts() {\n const sortsForModel = [...sorts];\n if (reverseType !== TableUtils.REVERSE_TYPE.NONE) {\n sortsForModel.push(model.dh.Table.reverse());\n }\n model.sort = sortsForModel;\n },\n [model, sorts, reverseType]\n );\n useEffect(\n function updateFormatter() {\n model.formatter = formatter;\n },\n [model, formatter]\n );\n useEffect(\n function updateCustomColumns() {\n if (model.isCustomColumnsAvailable) {\n model.customColumns = customColumns;\n }\n },\n [model, customColumns]\n );\n useEffect(\n function updateFormatColumns() {\n if (model.isFormatColumnsAvailable) {\n model.formatColumns = formatColumns;\n }\n },\n [model, formatColumns]\n );\n useEffect(\n function updateViewport() {\n model.setViewport(top, bottom, columns);\n },\n [model, top, bottom, columns]\n );\n useEffect(\n function updateRollupCOnfig() {\n if (model.isRollupAvailable) {\n model.rollupConfig = rollupConfig;\n }\n },\n [model, model.isRollupAvailable, rollupConfig]\n );\n useEffect(\n function updateSelectDistinctColumns() {\n if (model.isSelectDistinctAvailable) {\n model.selectDistinctColumns = selectDistinctColumns;\n }\n },\n [model, selectDistinctColumns]\n );\n useEffect(\n function updateTotalsConfig() {\n if (model.isTotalsAvailable) {\n model.totalsConfig = totalsConfig;\n }\n },\n [model, model.isTotalsAvailable, totalsConfig]\n );\n useEffect(\n function updatePendingRowCount() {\n model.pendingRowCount = pendingRowCount;\n },\n [model, pendingRowCount]\n );\n useEffect(\n function updatePendingDataMap() {\n model.pendingDataMap = pendingDataMap;\n },\n [model, pendingDataMap]\n );\n useEffect(\n function updateFrozenColumns() {\n if (frozenColumns) {\n model.updateFrozenColumns(frozenColumns);\n }\n },\n [model, frozenColumns]\n );\n useEffect(\n function updateColumnHeaderGroups() {\n model.columnHeaderGroups = columnHeaderGroups;\n },\n [model, columnHeaderGroups]\n );\n\n return null;\n }\n);\n\nIrisGridModelUpdater.displayName = 'IrisGridModelUpdater';\n\nexport default IrisGridModelUpdater;\n","/* eslint react/destructuring-assignment: \"off\" */\n/* eslint class-methods-use-this: \"off\" */\n/* eslint no-param-reassign: \"off\" */\nimport {\n dhSortDown,\n dhSortUp,\n vsTriangleDown,\n vsTriangleRight,\n vsLinkExternal,\n IconDefinition,\n} from '@deephaven/icons';\nimport {\n BoundedAxisRange,\n BoxCoordinates,\n Coordinate,\n GridMetrics,\n GridRangeIndex,\n GridRenderer,\n GridRenderState,\n GridThemeType,\n GridUtils,\n VisibleIndex,\n} from '@deephaven/grid';\nimport type { Sort } from '@deephaven/jsapi-types';\nimport { TableUtils, ReverseType } from '@deephaven/jsapi-utils';\nimport { assertNotNull, getOrThrow } from '@deephaven/utils';\nimport {\n ReadonlyAdvancedFilterMap,\n ReadonlyQuickFilterMap,\n AdvancedFilter,\n QuickFilter,\n} from './CommonTypes';\nimport { IrisGridThemeType } from './IrisGridTheme';\nimport IrisGridModel from './IrisGridModel';\n\nconst ICON_NAMES = Object.freeze({\n SORT_UP: 'sortUp',\n SORT_DOWN: 'sortDown',\n CARET_DOWN: 'caretDown',\n CARET_RIGHT: 'caretRight',\n CELL_OVERFLOW: 'cellOverflow',\n});\n\nconst EXPAND_ICON_SIZE = 10;\nconst ICON_SIZE = 16;\n\nexport type IrisGridRenderState = GridRenderState & {\n model: IrisGridModel;\n theme: IrisGridThemeType;\n hoverSelectColumn: GridRangeIndex;\n isSelectingColumn: boolean;\n loadingScrimProgress: number;\n reverseType: ReverseType;\n isFilterBarShown: boolean;\n advancedFilters: ReadonlyAdvancedFilterMap;\n quickFilters: ReadonlyQuickFilterMap;\n isMenuShown: boolean;\n};\n/**\n * Handles rendering some of the Iris specific features, such as sorting icons, sort bar display\n * */\nclass IrisGridRenderer extends GridRenderer {\n static isFilterValid(\n advancedFilter: AdvancedFilter | undefined | null,\n quickFilter: QuickFilter | undefined | null\n ): boolean {\n const isAdvancedFilterValid =\n advancedFilter == null || advancedFilter.filter != null;\n const isQuickFilterValid =\n quickFilter == null || quickFilter.filter != null;\n return isAdvancedFilterValid && isQuickFilterValid;\n }\n\n constructor() {\n super();\n this.icons = {};\n\n this.initIcons();\n }\n\n icons: Record<string, Path2D>;\n\n initIcons(): void {\n this.setIcon(ICON_NAMES.SORT_UP, dhSortUp);\n this.setIcon(ICON_NAMES.SORT_DOWN, dhSortDown);\n this.setIcon(ICON_NAMES.CARET_DOWN, vsTriangleDown);\n this.setIcon(ICON_NAMES.CARET_RIGHT, vsTriangleRight);\n this.setIcon(ICON_NAMES.CELL_OVERFLOW, vsLinkExternal);\n }\n\n // Scales the icon to be square and match the global ICON_SIZE\n setIcon(name: string, faIcon: IconDefinition): void {\n const path = Array.isArray(faIcon.icon[4])\n ? faIcon.icon[4][0]\n : faIcon.icon[4];\n const icon = new Path2D(path);\n const scaledIcon = new Path2D();\n const scaleMatrix = {\n a: ICON_SIZE / faIcon.icon[0],\n d: ICON_SIZE / faIcon.icon[1],\n };\n scaledIcon.addPath(icon, scaleMatrix);\n this.icons[name] = scaledIcon;\n }\n\n getIcon(name: string): Path2D {\n return this.icons[name];\n }\n\n getSortIcon(sort: Sort | null): Path2D | null {\n if (!sort) {\n return null;\n }\n if (sort.direction === TableUtils.sortDirection.ascending) {\n return this.getIcon(ICON_NAMES.SORT_UP);\n }\n if (sort.direction === TableUtils.sortDirection.descending) {\n return this.getIcon(ICON_NAMES.SORT_DOWN);\n }\n return null;\n }\n\n drawCanvas(state: IrisGridRenderState): void {\n super.drawCanvas(state);\n\n this.drawScrim(state);\n }\n\n drawGrid(\n context: CanvasRenderingContext2D,\n state: IrisGridRenderState\n ): void {\n super.drawGrid(context, state);\n this.drawCellOverflowButton(state);\n }\n\n drawGridLines(\n context: CanvasRenderingContext2D,\n state: IrisGridRenderState\n ): void {\n super.drawGridLines(context, state);\n\n this.drawGroupedColumnLine(context, state);\n\n this.drawPendingRowLine(context, state);\n }\n\n drawCellContent(\n context: CanvasRenderingContext2D,\n state: IrisGridRenderState,\n column: VisibleIndex,\n row: VisibleIndex\n ): void {\n const { metrics, model } = state;\n const { modelColumns, modelRows } = metrics;\n const modelRow = getOrThrow(modelRows, row);\n const modelColumn = modelColumns.get(column);\n if (modelColumn === undefined) {\n return;\n }\n const value = model.valueForCell(modelColumn, modelRow);\n if (TableUtils.isTextType(model.columns[modelColumn]?.type)) {\n if (value === null || value === '') {\n const originalFont = context.font;\n context.font = `italic ${originalFont}`;\n const displayValue = value === null ? 'null' : 'empty';\n super.drawCellContent(context, state, column, row, displayValue);\n context.font = originalFont;\n return;\n }\n }\n super.drawCellContent(context, state, column, row);\n }\n\n drawGroupedColumnLine(\n context: CanvasRenderingContext2D,\n state: IrisGridRenderState\n ): void {\n const { metrics, model, theme } = state;\n const { groupedColumns } = model;\n const { maxY, allColumnWidths, allColumnXs } = metrics;\n if (\n groupedColumns.length === 0 ||\n theme.groupedColumnDividerColor == null\n ) {\n return;\n }\n\n // This assumes that the engine puts the grouped columns at the start of the\n // model, so model and visible index match for grouped columns. If we ever\n // add freeze support for tree tables or allow moving the grouped columns,\n // this assumption may no longer hold true. If such a change occurs, we'll\n // need to revisit this since a single vertical divider may no longer make\n // sense.\n const lastVisibleGroupColumnIndex = groupedColumns.length - 1;\n\n const columnX = allColumnXs.get(lastVisibleGroupColumnIndex);\n const columnWidth = allColumnWidths.get(lastVisibleGroupColumnIndex);\n if (columnX == null || columnWidth == null) {\n return;\n }\n\n const x = columnX + columnWidth + 0.5;\n\n context.strokeStyle = theme.groupedColumnDividerColor;\n context.lineWidth = 1;\n context.beginPath();\n context.moveTo(x, 0);\n context.lineTo(x, maxY);\n context.stroke();\n }\n\n drawPendingRowLine(\n context: CanvasRenderingContext2D,\n state: IrisGridRenderState\n ): void {\n const { metrics, model, theme } = state;\n const { allRowYs, maxX } = metrics;\n const { pendingRowCount } = model;\n if (pendingRowCount <= 0) {\n return;\n }\n\n const firstPendingRow =\n model.rowCount - model.pendingRowCount - model.floatingBottomRowCount;\n let y = allRowYs.get(firstPendingRow);\n if (y == null) {\n return;\n }\n\n y -= 0.5;\n context.save();\n context.setLineDash([4, 2]);\n context.strokeStyle = theme.pendingTextColor;\n\n context.lineWidth = 1;\n context.beginPath();\n context.moveTo(0, y);\n context.lineTo(maxX, y);\n context.stroke();\n context.restore();\n }\n\n drawMouseColumnHover(\n context: CanvasRenderingContext2D,\n state: IrisGridRenderState\n ): void {\n const { theme, metrics, hoverSelectColumn } = state;\n if (\n hoverSelectColumn == null ||\n theme.linkerColumnHoverBackgroundColor == null\n ) {\n return;\n }\n\n const { allColumnWidths, allColumnXs, maxY } = metrics;\n\n const x = getOrThrow(allColumnXs, hoverSelectColumn);\n const columnWidth = getOrThrow(allColumnWidths, hoverSelectColumn);\n\n context.fillStyle = theme.linkerColumnHoverBackgroundColor;\n context.fillRect(x, 0, columnWidth, maxY);\n }\n\n drawMouseRowHover(\n context: CanvasRenderingContext2D,\n state: IrisGridRenderState\n ): void {\n const { isSelectingColumn } = state;\n if (!isSelectingColumn) {\n super.drawMouseRowHover(context, state);\n }\n }\n\n drawScrim(state: IrisGridRenderState): void {\n const { context, loadingScrimProgress, metrics, theme } = state;\n if (loadingScrimProgress == null) {\n return;\n }\n\n const { width, height, gridY } = metrics;\n const { scrimBlurSize, scrimColor } = theme;\n\n context.save();\n\n // Use global composite so we can change the underlying layer to grayscale\n context.globalCompositeOperation = 'color';\n context.filter = `blur(${scrimBlurSize}px)`;\n if (scrimColor != null) {\n context.fillStyle = scrimColor;\n }\n\n // Clip the path so the top edge is hard edge, bottom edge is soft/blurry\n context.beginPath();\n context.rect(0, gridY, width, height - gridY);\n context.clip();\n\n // Extend the edges beyond the clip area so they're hard edges\n context.fillRect(\n -scrimBlurSize,\n -scrimBlurSize + gridY,\n scrimBlurSize * 2 + width,\n (scrimBlurSize * 2 + (height - gridY)) * loadingScrimProgress\n );\n\n // add an overlay of the scrim color to darken things a bit\n context.globalCompositeOperation = 'overlay';\n context.filter = `blur(${scrimBlurSize}px) opacity(15%)`;\n context.fillRect(\n -scrimBlurSize,\n -scrimBlurSize + gridY,\n scrimBlurSize * 2 + width,\n (scrimBlurSize * 2 + (height - gridY)) * loadingScrimProgress\n );\n\n context.restore();\n }\n\n drawColumnHeaders(\n context: CanvasRenderingContext2D,\n state: IrisGridRenderState\n ): void {\n super.drawColumnHeaders(context, state);\n\n const { theme, metrics, model, reverseType } = state;\n const { columnHeaderHeight } = metrics;\n\n this.drawFilterHeaders(context, state);\n\n if (columnHeaderHeight <= 0) {\n return;\n }\n\n const { sort } = model;\n // if there is only one sort bar, it is interior to the header to save space\n if (sort.length === 1) {\n const hasReverse = reverseType !== TableUtils.REVERSE_TYPE.NONE;\n\n let color;\n if (hasReverse) {\n color = theme.headerReverseBarColor;\n } else {\n color = theme.headerSortBarColor;\n }\n this.drawHeaderBar(\n context,\n state,\n color,\n hasReverse ? theme.reverseHeaderBarHeight : theme.sortHeaderBarHeight\n );\n } else if (sort.length > 1) {\n // if there's multiple bars, the sort is interior to header\n // and the reverse claims space in the table\n if (\n // has table reverse\n reverseType !== TableUtils.REVERSE_TYPE.NONE\n ) {\n this.drawHeaderBar(\n context,\n state,\n theme.headerReverseBarColor,\n theme.reverseHeaderBarHeight,\n false\n );\n }\n this.drawHeaderBar(\n context,\n state,\n theme.headerSortBarColor,\n theme.sortHeaderBarHeight\n );\n }\n }\n\n drawHeaderBar(\n context: CanvasRenderingContext2D,\n state: IrisGridRenderState,\n color: string | CanvasGradient | CanvasPattern,\n barHeight: number,\n interior = true\n ): void {\n const { theme, metrics, model } = state;\n const { columnHeaderHeight, width } = metrics;\n // Draw casing with 1 pixel above and below the bar,\n // 1px falls on the existing split between grid/headers\n // so don't need to be accounnted for in math elsewhere\n let offset = 0;\n if (!interior) {\n offset = barHeight;\n }\n context.fillStyle = theme.headerBarCasingColor;\n context.fillRect(\n 0,\n model.columnHeaderMaxDepth * columnHeaderHeight - barHeight - 2 + offset,\n width,\n barHeight + 2\n );\n\n context.fillStyle = color;\n context.fillRect(\n 0,\n model.columnHeaderMaxDepth * columnHeaderHeight - barHeight - 1 + offset,\n width,\n barHeight\n );\n }\n\n drawColumnHeadersAtDepth(\n context: CanvasRenderingContext2D,\n state: IrisGridRenderState,\n range: BoundedAxisRange,\n boundsProp: { minX: number; maxX: number },\n depth: number\n ): void {\n const { metrics, model, isMenuShown } = state;\n const { columnHeaderMaxDepth } = model;\n const { width } = metrics;\n const bounds = {\n ...boundsProp,\n maxX:\n depth === columnHeaderMaxDepth - 1 && boundsProp.maxX === width\n ? width - (isMenuShown ? 0 : 30) // Account for the menu button\n : boundsProp.maxX,\n };\n super.drawColumnHeadersAtDepth(context, state, range, bounds, depth);\n }\n\n drawColumnHeaderAtIndex(\n context: CanvasRenderingContext2D,\n state: IrisGridRenderState,\n index: VisibleIndex,\n bounds: { minX: number; maxX: number }\n ): void {\n super.drawColumnHeaderAtIndex(context, state, index, bounds);\n const { metrics, model, theme } = state;\n const {\n modelColumns,\n allColumnWidths,\n allColumnXs,\n gridX,\n columnHeaderHeight,\n fontWidths,\n } = metrics;\n\n const { headerHorizontalPadding } = theme;\n const columnWidth = getOrThrow(allColumnWidths, index, 0);\n const columnX = getOrThrow(allColumnXs, index) + gridX;\n const modelColumn = modelColumns.get(index);\n\n if (modelColumn == null) {\n return;\n }\n\n const columnName = model.columns[modelColumn]?.name;\n\n if (columnName == null) {\n return;\n }\n\n const sort = TableUtils.getSortForColumn(model.sort, columnName);\n\n if (!sort) {\n return;\n }\n\n const icon = this.getSortIcon(sort);\n if (!icon) {\n return;\n }\n\n const text = model.textForColumnHeader(modelColumn);\n if (text === undefined) {\n return;\n }\n\n const fontWidth =\n fontWidths.get(context.font) ?? GridRenderer.DEFAULT_FONT_WIDTH;\n assertNotNull(fontWidth);\n const textWidth = text.length * fontWidth;\n const textRight = gridX + columnX + textWidth + headerHorizontalPadding;\n let { maxX } = bounds;\n maxX -= headerHorizontalPadding;\n const defaultX =\n gridX + columnX + columnWidth - headerHorizontalPadding - 1;\n\n const x = textRight > maxX ? textRight + 1 : Math.min(maxX, defaultX);\n const yOffset =\n sort.direction === TableUtils.sortDirection.ascending ? -6 : -12;\n const y = columnHeaderHeight * 0.5 + yOffset;\n\n context.save();\n\n context.beginPath();\n context.rect(columnX, 0, columnWidth, columnHeaderHeight);\n context.clip();\n\n context.fillStyle = theme.headerSortBarColor;\n context.translate(x, y);\n context.fill(icon);\n\n context.restore();\n }\n\n drawFilterHeaders(\n context: CanvasRenderingContext2D,\n state: IrisGridRenderState\n ): void {\n const { isFilterBarShown, quickFilters, advancedFilters } = state;\n\n if (isFilterBarShown) {\n this.drawExpandedFilterHeaders(context, state);\n } else if (\n (quickFilters != null && quickFilters.size > 0) ||\n (advancedFilters != null && advancedFilters.size > 0)\n ) {\n this.drawCollapsedFilterHeaders(context, state);\n }\n }\n\n drawExpandedFilterHeaders(\n context: CanvasRenderingContext2D,\n state: IrisGridRenderState\n ): void {\n const { metrics, model, theme, quickFilters, advancedFilters } = state;\n const { filterBarHeight } = theme;\n\n if (filterBarHeight <= 0) {\n return;\n }\n\n const {\n gridX,\n gridY,\n maxX,\n modelColumns,\n visibleColumns,\n allColumnWidths,\n allColumnXs,\n } = metrics;\n\n const columnHeaderHeight = gridY - filterBarHeight;\n\n context.save();\n\n context.font = theme.font;\n context.textAlign = 'left';\n\n if (\n (quickFilters != null && quickFilters.size > 0) ||\n (advancedFilters != null && advancedFilters.size > 0)\n ) {\n // fill style if a fiter is set on any column\n context.fillStyle = theme.filterBarExpandedActiveBackgroundColor;\n } else {\n // fill style with no filters set\n context.fillStyle = theme.filterBarExpandedBackgroundColor;\n }\n\n // Draw the background\n context.fillRect(gridX, columnHeaderHeight, maxX, filterBarHeight - 1);\n\n // Draw the bottom border\n context.fillStyle = theme.headerBarCasingColor;\n\n context.fillRect(gridX, columnHeaderHeight + filterBarHeight - 1, maxX, 1);\n\n // Draw the filter input boxes\n const y1 = columnHeaderHeight;\n context.strokeStyle = theme.filterBarSeparatorColor;\n context.beginPath();\n\n for (let i = 0; i < visibleColumns.length; i += 1) {\n const column = visibleColumns[i];\n const modelColumn = getOrThrow(modelColumns, column);\n const columnX = getOrThrow(allColumnXs, column);\n const columnWidth = getOrThrow(allColumnWidths, column);\n if (model.isFilterable(modelColumn) && columnWidth > 0) {\n const x1 = gridX + (columnX ?? 0);\n context.rect(x1 + 0.5, y1 + 0.5, columnWidth, filterBarHeight - 2); // 1 for the border, 1 for the casing\n }\n }\n context.stroke();\n\n for (let i = 0; i < visibleColumns.length; i += 1) {\n const column = visibleColumns[i];\n const columnWidth = getOrThrow(allColumnWidths, column);\n const columnX = getOrThrow(allColumnXs, column);\n const x = columnX + gridX;\n this.drawExpandedFilterHeader(context, state, column, x, columnWidth);\n }\n\n context.restore();\n }\n\n drawExpandedFilterHeader(\n context: CanvasRenderingContext2D,\n state: IrisGridRenderState,\n column: VisibleIndex,\n columnX: Coordinate,\n columnWidth: number\n ): void {\n if (columnWidth <= 0) {\n return;\n }\n\n const { metrics, theme, quickFilters, advancedFilters } = state;\n const { modelColumns, gridY } = metrics;\n const {\n filterBarHeight,\n filterBarExpandedActiveCellBackgroundColor,\n filterBarErrorColor,\n filterBarHorizontalPadding,\n headerColor,\n } = theme;\n const columnHeaderHeight = gridY - filterBarHeight;\n const modelColumn = modelColumns.get(column);\n if (modelColumn === undefined) return;\n const quickFilter = quickFilters.get(modelColumn);\n const advancedFilter = advancedFilters.get(modelColumn);\n if (quickFilter == null && advancedFilter == null) {\n return;\n }\n\n let text = null;\n if (quickFilter != null) {\n const { text: filterText } = quickFilter;\n text = filterText;\n if (!text) {\n text = TableUtils.getFilterText(quickFilter.filter);\n }\n\n if (text != null) {\n const { fontWidths } = metrics;\n let fontWidth = fontWidths.get(context.font);\n if (fontWidth == null || fontWidth === 0) {\n fontWidth = context.measureText('8').width;\n if (!fontWidth) {\n fontWidth = 10;\n }\n }\n\n const maxLength =\n (columnWidth - filterBarHorizontalPadding * 2) / fontWidth;\n if (maxLength <= 0) {\n text = '';\n } else if (text.length > maxLength) {\n text = `${text.substring(0, maxLength - 1)}…`;\n }\n }\n }\n\n context.save();\n\n const isFilterValid = IrisGridRenderer.isFilterValid(\n advancedFilter,\n quickFilter\n );\n if (isFilterValid && filterBarExpandedActiveCellBackgroundColor != null) {\n // draw active filter background inside cell\n context.fillStyle = filterBarExpandedActiveCellBackgroundColor;\n context.fillRect(\n columnX + 1, // +1 left border\n columnHeaderHeight + 1, // +1 top border\n columnWidth - 1, // -1 right border\n filterBarHeight - 3 // -3 top, bottom border and bottom casing\n );\n } else if (filterBarErrorColor != null) {\n // draw error box inside cell\n context.fillStyle = filterBarErrorColor;\n context.lineWidth = 2;\n context.strokeStyle = filterBarErrorColor;\n // Because this is drawn with a strokeRect, we have to add/subtract half the,\n // linewidth from each side to make interior, in addition to accounting for any borders/casings\n const rectLeft = columnX + 2; // 1 for strokeRect, 1 for border\n const rectTop = columnHeaderHeight + 2; // 1 for strokeRect, 1 for border\n const rectWidth = columnWidth - 3; // for 2 border and 1 for strokeRect\n const rectHeight = filterBarHeight - 5; // -2 for strokeRect, -3 for top, bottom border and bottom casing\n context.strokeRect(rectLeft, rectTop, rectWidth, rectHeight);\n }\n\n if (text != null && text !== '') {\n const textX = columnX + filterBarHorizontalPadding;\n const textY = columnHeaderHeight + filterBarHeight * 0.5 + 1; // + 1 for border\n context.fillStyle = headerColor;\n context.fillText(text, textX, textY);\n }\n\n context.restore();\n }\n\n drawCollapsedFilterHeaders(\n context: CanvasRenderingContext2D,\n state: IrisGridRenderState\n ): void {\n const { metrics, theme } = state;\n const { headerSeparatorColor, filterBarCollapsedHeight } = theme;\n\n if (filterBarCollapsedHeight <= 0) {\n return;\n }\n\n const {\n gridX,\n gridY,\n maxX,\n visibleColumns,\n allColumnWidths,\n allColumnXs,\n } = metrics;\n const columnHeaderHeight = gridY - filterBarCollapsedHeight;\n\n context.save();\n\n // Draw the background of the collapsed filter bar\n context.fillStyle = headerSeparatorColor;\n context.fillRect(gridX, columnHeaderHeight, maxX, filterBarCollapsedHeight);\n\n for (let i = 0; i < visibleColumns.length; i += 1) {\n const column = visibleColumns[i];\n const columnWidth = allColumnWidths.get(column);\n const columnX = allColumnXs.get(column);\n if (columnX != null && columnWidth != null) {\n const x = columnX + gridX;\n // draw the collapsed cells\n this.drawCollapsedFilterHeader(context, state, column, x, columnWidth);\n }\n }\n\n context.restore();\n }\n\n drawCollapsedFilterHeader(\n context: CanvasRenderingContext2D,\n state: IrisGridRenderState,\n column: VisibleIndex,\n columnX: Coordinate,\n columnWidth: number\n ): void {\n if (columnWidth <= 0) {\n return;\n }\n\n const { metrics, theme, quickFilters, advancedFilters } = state;\n const { modelColumns, gridY } = metrics;\n const modelColumn = modelColumns.get(column);\n\n if (modelColumn === undefined) return;\n const quickFilter = quickFilters.get(modelColumn);\n const advancedFilter = advancedFilters.get(modelColumn);\n\n const {\n filterBarCollapsedHeight,\n filterBarActiveColor,\n filterBarActiveBackgroundColor,\n filterBarErrorColor,\n } = theme;\n\n context.save();\n\n const isFilterValid = IrisGridRenderer.isFilterValid(\n advancedFilter,\n quickFilter\n );\n\n if (\n filterBarActiveBackgroundColor != null &&\n quickFilter == null &&\n advancedFilter == null\n ) {\n context.fillStyle = filterBarActiveBackgroundColor;\n } else if (filterBarActiveColor != null && isFilterValid) {\n context.fillStyle = filterBarActiveColor;\n } else if (filterBarErrorColor != null) {\n context.fillStyle = filterBarErrorColor;\n }\n\n const x = columnX + 1; // for gap between columns\n const y = gridY - filterBarCollapsedHeight;\n const rectWidth = columnWidth - 1; // for gap between columns\n const rectHeight = filterBarCollapsedHeight - 1; // for casing bottom\n context.fillRect(x, y, rectWidth, rectHeight);\n\n context.restore();\n }\n\n drawTreeMarker(\n context: CanvasRenderingContext2D,\n state: IrisGridRenderState,\n columnX: Coordinate,\n rowY: Coordinate,\n treeBox: BoxCoordinates,\n color: string,\n isExpanded: boolean\n ): void {\n context.save();\n const { x1, y1 } = treeBox;\n const markerIcon = isExpanded\n ? this.getIcon(ICON_NAMES.CARET_DOWN)\n : this.getIcon(ICON_NAMES.CARET_RIGHT);\n const iconX = columnX + x1 - 2;\n const iconY = rowY + y1 + 2.5;\n\n context.fillStyle = color;\n context.textAlign = 'center';\n context.translate(iconX, iconY);\n context.fill(markerIcon);\n context.restore();\n }\n\n drawRowFooters(\n context: CanvasRenderingContext2D,\n state: IrisGridRenderState\n ): void {\n const { metrics, model, mouseX, mouseY, theme } = state;\n const {\n gridY,\n gridX,\n maxX,\n modelRows,\n floatingTopHeight,\n floatingBottomHeight,\n floatingRows,\n rowFooterWidth,\n height,\n horizontalBarHeight,\n verticalBarWidth,\n allRowHeights,\n allRowYs,\n width,\n } = metrics;\n // Only draw the footers on the floating rows\n if (rowFooterWidth <= 0 || floatingRows.length === 0) {\n return;\n }\n\n const {\n cellHorizontalPadding,\n floatingGridRowColor,\n floatingRowBackgroundColors,\n headerColor,\n rowHoverBackgroundColor,\n } = theme;\n\n context.translate(gridX, gridY);\n\n context.beginPath();\n const x = Math.min(maxX, width - rowFooterWidth - verticalBarWidth - gridX);\n context.fillStyle = floatingRowBackgroundColors;\n if (floatingTopHeight > 0) {\n context.rect(x, 0, rowFooterWidth, floatingTopHeight);\n }\n if (floatingBottomHeight > 0) {\n context.rect(\n x,\n height - gridY - horizontalBarHeight - floatingBottomHeight,\n rowFooterWidth,\n floatingBottomHeight\n );\n }\n context.fill();\n\n const mouseRow =\n mouseX != null &&\n mouseY != null &&\n mouseX >= gridX &&\n mouseX <= maxX + rowFooterWidth\n ? GridUtils.getRowAtY(mouseY, metrics)\n : null;\n if (\n rowHoverBackgroundColor != null &&\n mouseRow !== null &&\n floatingRows.includes(mouseRow)\n ) {\n context.fillStyle = rowHoverBackgroundColor;\n const y = allRowYs.get(mouseRow);\n const rowHeight = allRowHeights.get(mouseRow);\n assertNotNull(y);\n assertNotNull(rowHeight);\n context.fillRect(x, y, rowFooterWidth, rowHeight);\n }\n\n context.beginPath();\n if (floatingGridRowColor != null) {\n context.strokeStyle = floatingGridRowColor;\n }\n if (floatingTopHeight > 0) {\n context.moveTo(x + 0.5, 0.5);\n context.lineTo(x + 0.5, floatingTopHeight - 0.5);\n }\n if (floatingBottomHeight > 0) {\n const y = height - gridY - horizontalBarHeight - floatingBottomHeight;\n context.moveTo(x - 0.5, y + 0.5);\n context.lineTo(x - 0.5, y + floatingBottomHeight - 0.5);\n }\n context.stroke();\n\n context.fillStyle = headerColor;\n context.textAlign = 'left';\n\n const textX = x + cellHorizontalPadding;\n for (let i = 0; i < floatingRows.length; i += 1) {\n const row = floatingRows[i];\n const rowHeight = allRowHeights.get(row);\n const rowY = allRowYs.get(row);\n const modelRow = modelRows.get(row);\n if (rowY != null && rowHeight != null && modelRow != null) {\n const textY = rowY + rowHeight * 0.5;\n context.fillText(model.textForRowFooter(modelRow), textX, textY);\n }\n }\n\n context.translate(-gridX, -gridY);\n }\n\n // This will shrink the size the text may take when the overflow button is rendered\n // The text will truncate to a smaller width and won't overlap the button\n getTextRenderMetrics(\n state: IrisGridRenderState,\n column: VisibleIndex,\n row: VisibleIndex\n ): {\n width: number;\n x: Coordinate;\n y: Coordinate;\n } {\n const textMetrics = super.getTextRenderMetrics(state, column, row);\n\n const { mouseX, mouseY, metrics } = state;\n\n if (mouseX == null || mouseY == null) {\n return textMetrics;\n }\n\n const { column: mouseColumn, row: mouseRow } = GridUtils.getGridPointFromXY(\n mouseX,\n mouseY,\n metrics\n );\n\n if (column === mouseColumn && row === mouseRow) {\n const { left } = this.getCellOverflowButtonPosition(state);\n if (this.shouldRenderOverflowButton(state) && left != null) {\n textMetrics.width = left - metrics.gridX - textMetrics.x;\n }\n }\n return textMetrics;\n }\n\n shouldRenderOverflowButton(state: IrisGridRenderState): boolean {\n const { context, mouseX, mouseY, metrics, model, theme } = state;\n if (mouseX == null || mouseY == null) {\n return false;\n }\n\n const { row, column, modelRow, modelColumn } = GridUtils.getCellInfoFromXY(\n mouseX,\n mouseY,\n metrics\n );\n\n if (\n row == null ||\n column == null ||\n modelRow == null ||\n modelColumn == null ||\n !TableUtils.isStringType(model.columns[modelColumn].type)\n ) {\n return false;\n }\n\n const text = model.textForCell(modelColumn, modelRow) ?? '';\n const { width: textWidth } = super.getTextRenderMetrics(state, column, row);\n const fontWidth =\n metrics.fontWidths.get(theme.font) ?? IrisGridRenderer.DEFAULT_FONT_WIDTH;\n\n context.save();\n context.font = theme.font;\n\n const truncatedText = this.getCachedTruncatedString(\n context,\n text,\n textWidth,\n fontWidth,\n model.truncationCharForCell(modelColumn, modelRow)\n );\n context.restore();\n\n return text !== '' && truncatedText !== text;\n }\n\n getCellOverflowButtonPosition({\n mouseX,\n mouseY,\n metrics,\n theme,\n }: {\n mouseX: Coordinate | null;\n mouseY: Coordinate | null;\n metrics: GridMetrics | undefined;\n theme: GridThemeType;\n }): {\n left: Coordinate | null;\n top: Coordinate | null;\n width: number | null;\n height: number | null;\n } {\n const NULL_POSITION = { left: null, top: null, width: null, height: null };\n if (mouseX == null || mouseY == null || metrics == null) {\n return NULL_POSITION;\n }\n const { rowHeight, columnWidth, left, top } = GridUtils.getCellInfoFromXY(\n mouseX,\n mouseY,\n metrics\n );\n\n if (left == null || columnWidth == null || top == null) {\n return NULL_POSITION;\n }\n\n const { width: gridWidth, verticalBarWidth } = metrics;\n const { cellHorizontalPadding } = theme;\n\n const width = ICON_SIZE + 2 * cellHorizontalPadding;\n const height = rowHeight;\n // Right edge of column or of visible grid, whichever is smaller\n const right = Math.min(\n metrics.gridX + left + columnWidth,\n gridWidth - verticalBarWidth\n );\n const buttonLeft = right - width;\n const buttonTop = metrics.gridY + top;\n\n return { left: buttonLeft, top: buttonTop, width, height };\n }\n\n drawCellOverflowButton(state: IrisGridRenderState): void {\n const { context, mouseX, mouseY, theme } = state;\n if (mouseX == null || mouseY == null) return;\n\n if (!this.shouldRenderOverflowButton(state)) {\n return;\n }\n\n const {\n left: buttonLeft,\n top: buttonTop,\n width: buttonWidth,\n height: buttonHeight,\n } = this.getCellOverflowButtonPosition(state);\n\n const {\n cellHorizontalPadding,\n overflowButtonColor,\n overflowButtonHoverColor,\n } = theme;\n\n context.save();\n if (\n overflowButtonHoverColor != null &&\n buttonLeft != null &&\n buttonWidth != null &&\n buttonTop != null &&\n buttonHeight != null &&\n mouseX >= buttonLeft &&\n mouseX <= buttonLeft + buttonWidth &&\n mouseY >= buttonTop &&\n mouseY <= buttonTop + buttonHeight\n ) {\n context.fillStyle = overflowButtonHoverColor;\n } else if (overflowButtonColor != null) {\n context.fillStyle = overflowButtonColor;\n }\n const icon = this.getIcon(ICON_NAMES.CELL_OVERFLOW);\n if (buttonLeft != null && buttonTop != null) {\n context.translate(buttonLeft + cellHorizontalPadding, buttonTop + 2);\n }\n context.fill(icon);\n\n context.restore();\n }\n\n getExpandButtonPosition(\n {\n mouseX,\n mouseY,\n metrics,\n theme,\n }: {\n mouseX: Coordinate | null;\n mouseY: Coordinate | null;\n metrics: GridMetrics | undefined;\n theme: GridThemeType;\n },\n depth: number | null\n ): {\n left: Coordinate | null;\n top: Coordinate | null;\n width: number | null;\n height: number | null;\n } {\n const NULL_POSITION = { left: null, top: null, width: null, height: null };\n if (mouseX == null || mouseY == null || depth == null || !metrics) {\n return NULL_POSITION;\n }\n const { rowHeight, left, top } = GridUtils.getCellInfoFromXY(\n mouseX,\n mouseY,\n metrics\n );\n\n assertNotNull(left);\n assertNotNull(rowHeight);\n assertNotNull(top);\n const { cellHorizontalPadding } = theme;\n\n const width = EXPAND_ICON_SIZE + 2 * cellHorizontalPadding;\n\n const buttonLeft = Math.max(left + EXPAND_ICON_SIZE * depth, metrics.gridX);\n const buttonTop = metrics.gridY + top;\n\n return {\n left: buttonLeft,\n top: buttonTop,\n width,\n height: rowHeight,\n };\n }\n}\n\nexport default IrisGridRenderer;\n","import type { GridThemeType } from '@deephaven/grid';\nimport { GridColor, NullableGridColor } from '@deephaven/grid/src/GridTheme';\nimport IrisGridTheme from './IrisGridTheme.module.scss';\n\nexport type IrisGridThemeType = GridThemeType & {\n filterBarCollapsedHeight: number;\n filterBarHeight: number;\n reverseHeaderBarHeight: number;\n filterIconColor: string;\n filterBarActiveColor: GridColor;\n contextMenuSortIconColor: GridColor;\n contextMenuReverseIconColor: GridColor;\n minScrimTransitionTime: number;\n maxScrimTransitionTime: number;\n nullStringColor: GridColor;\n pendingTextColor: GridColor;\n dateColor: GridColor;\n positiveNumberColor: GridColor;\n negativeNumberColor: GridColor;\n zeroNumberColor: GridColor;\n errorTextColor: GridColor;\n groupedColumnDividerColor: GridColor;\n linkerColumnHoverBackgroundColor: GridColor;\n scrimBlurSize: number;\n scrimColor: GridColor;\n headerReverseBarColor: GridColor;\n sortHeaderBarHeight: number;\n headerSortBarColor: GridColor;\n headerBarCasingColor: GridColor;\n filterBarExpandedActiveBackgroundColor: GridColor;\n filterBarExpandedBackgroundColor: GridColor;\n filterBarSeparatorColor: GridColor;\n filterBarExpandedActiveCellBackgroundColor: GridColor;\n filterBarErrorColor: GridColor;\n filterBarHorizontalPadding: number;\n filterBarActiveBackgroundColor: GridColor;\n overflowButtonColor: GridColor;\n overflowButtonHoverColor: GridColor;\n floatingGridRowColor: NullableGridColor;\n};\n\nconst theme: Partial<IrisGridThemeType> = Object.freeze({\n backgroundColor: IrisGridTheme['grid-bg'],\n white: IrisGridTheme.white,\n black: IrisGridTheme.black,\n font: IrisGridTheme.font,\n headerBackgroundColor: IrisGridTheme['header-bg'],\n headerColor: IrisGridTheme['header-color'],\n headerSeparatorColor: IrisGridTheme['header-separator-color'],\n headerSeparatorHoverColor: IrisGridTheme['header-separator-hover-color'],\n headerHiddenSeparatorHoverColor:\n IrisGridTheme['header-hidden-separator-hover-color'],\n headerSortBarColor: IrisGridTheme['header-sort-bar-color'],\n headerReverseBarColor: IrisGridTheme['header-reverse-bar-color'],\n headerBarCasingColor: IrisGridTheme['header-bar-casing-color'],\n headerFont: IrisGridTheme['header-font'],\n rowBackgroundColors: IrisGridTheme['row-background-colors'],\n rowHoverBackgroundColor: IrisGridTheme['row-hover-bg'],\n selectionColor: IrisGridTheme['selection-color'],\n selectionOutlineColor: IrisGridTheme['selection-outline-color'],\n selectionOutlineCasingColor: IrisGridTheme['selection-outline-casing-color'],\n selectedRowHoverBackgroundColor: IrisGridTheme['selected-row-hover-bg'],\n scrollBarBackgroundColor: IrisGridTheme['scroll-bar-bg'],\n scrollBarHoverBackgroundColor: IrisGridTheme['scroll-bar-hover-bg'],\n scrollBarCasingColor: IrisGridTheme['scroll-bar-casing-color'],\n scrollBarCornerColor: IrisGridTheme['scroll-bar-corner-color'],\n scrollBarColor: IrisGridTheme['scroll-bar-color'],\n scrollBarHoverColor: IrisGridTheme['scroll-bar-hover-color'],\n scrollBarActiveColor: IrisGridTheme['scroll-bar-active-color'],\n scrollBarSelectionTickColor: IrisGridTheme['selected-row-hover-bg'],\n scrollBarActiveSelectionTickColor:\n IrisGridTheme['scroll-bar-active-selection-tick-color'],\n textColor: IrisGridTheme['text-color'],\n hyperlinkColor: IrisGridTheme['hyperlink-color'],\n positiveNumberColor: IrisGridTheme['positive-number-color'],\n negativeNumberColor: IrisGridTheme['negative-number-color'],\n zeroNumberColor: IrisGridTheme['zero-number-color'],\n dateColor: IrisGridTheme['date-color'],\n pendingTextColor: IrisGridTheme['pending-text-color'],\n errorTextColor: IrisGridTheme['error-text-color'],\n nullStringColor: IrisGridTheme['null-string-color'],\n filterBarActiveBackgroundColor: IrisGridTheme['filter-bar-active-bg'],\n filterBarExpandedBackgroundColor: IrisGridTheme['filter-bar-expanded-bg'],\n filterBarExpandedActiveBackgroundColor:\n IrisGridTheme['filter-bar-expanded-active-bg'],\n filterBarExpandedActiveCellBackgroundColor:\n IrisGridTheme['filter-bar-expanded-active-cell-bg'],\n filterBarSeparatorColor: IrisGridTheme['filter-bar-separator-color'],\n filterBarActiveColor: IrisGridTheme['filter-bar-active-color'],\n filterBarErrorColor: IrisGridTheme['filter-bar-error-color'],\n filterIconColor: IrisGridTheme['filter-icon-color'],\n scrimColor: IrisGridTheme['scrim-color'],\n contextMenuSortIconColor: IrisGridTheme['context-menu-sort-icon-color'],\n contextMenuReverseIconColor: IrisGridTheme['context-menu-reverse-icon-color'],\n\n allowRowResize: false,\n autoSelectRow: true,\n gridColumnColor: null,\n gridRowColor: null,\n groupedColumnDividerColor: IrisGridTheme['grouped-column-divider-color'],\n columnHoverBackgroundColor: null,\n headerHorizontalPadding: 12,\n scrollBarSize: 13,\n scrollBarHoverSize: 16, // system default scrollbar width is 17\n minScrollHandleSize: 24,\n rowHeight: parseInt(IrisGridTheme['row-height'], 10) || 19, // IrisGrid test breaks without the fallback value\n columnWidth: 100,\n rowHeaderWidth: 0,\n rowFooterWidth: 60,\n columnHeaderHeight: parseInt(IrisGridTheme['header-height'], 10) || 30,\n filterBarHeight: 30, // includes 1px casing at bottom\n filterBarCollapsedHeight: 5, // includes 1px casing at bottom\n sortHeaderBarHeight: 2,\n reverseHeaderBarHeight: 4,\n filterBarHorizontalPadding: 4,\n\n // Amount of blur to apply to the bottom of the scrim while animating in\n scrimBlurSize: 25,\n minScrimTransitionTime: 150,\n maxScrimTransitionTime: 350,\n\n scrollSnapToRow: true,\n\n linkerColumnHoverBackgroundColor: IrisGridTheme['linker-column-hover-bg'],\n\n treeLineColor: IrisGridTheme['tree-line-color'],\n treeMarkerColor: IrisGridTheme['tree-marker-color'],\n treeMarkerHoverColor: IrisGridTheme['tree-marker-hover-color'],\n\n floatingGridColumnColor: null,\n floatingGridRowColor: IrisGridTheme['floating-grid-row-color'],\n floatingRowBackgroundColors: IrisGridTheme['floating-row-background-colors'],\n floatingDividerInnerColor: IrisGridTheme['floating-divider-inner-color'],\n floatingDividerOuterColor: IrisGridTheme['floating-divider-outer-color'],\n\n overflowButtonColor: IrisGridTheme['overflow-button-color'],\n overflowButtonHoverColor: IrisGridTheme['overflow-button-hover-color'],\n});\n\nexport default theme;\n","import React, { Component, Key } from 'react';\nimport classNames from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { Button, CopyButton, LoadingSpinner } from '@deephaven/components';\nimport { dhFreeze, dhRefresh, vsLock } from '@deephaven/icons';\nimport type {\n Column,\n ColumnStatistics as APIColumnStatistics,\n} from '@deephaven/jsapi-types';\nimport Log from '@deephaven/log';\nimport { CancelablePromise, PromiseUtils } from '@deephaven/utils';\nimport { isExpandableGridModel } from '@deephaven/grid';\nimport './ColumnStatistics.scss';\nimport IrisGridModel from './IrisGridModel';\n\nconst log = Log.module('ColumnStatistics');\nconst STATS_LABEL_OVERRIDES: Record<string, string> = {\n SIZE: 'Number of Rows',\n};\n\ninterface Statistic {\n operation: Key;\n className?: string;\n value: unknown;\n type: string;\n}\n\ninterface ColumnStatisticsProps {\n column: Column;\n model: IrisGridModel;\n onStatistics: () => void;\n}\ninterface ColumnStatisticsState {\n error: unknown;\n loading: boolean;\n statistics: Statistic[] | null;\n numRows: number;\n}\n\nclass ColumnStatistics extends Component<\n ColumnStatisticsProps,\n ColumnStatisticsState\n> {\n /** Automatically generate the statistics when the row count is below this threshold */\n static AUTO_GENERATE_LIMIT = 100000;\n\n static getStatsLabel(operation: string): string {\n return (\n STATS_LABEL_OVERRIDES[operation] ??\n operation\n .split(' ')\n .map(w => w[0].toUpperCase() + w.substr(1).toLowerCase())\n .join(' ')\n );\n }\n\n constructor(props: ColumnStatisticsProps) {\n super(props);\n\n this.handleError = this.handleError.bind(this);\n this.handleGenerateStatistics = this.handleGenerateStatistics.bind(this);\n this.handleStatistics = this.handleStatistics.bind(this);\n\n this.cancelablePromise = null;\n\n this.state = {\n error: null,\n loading: false,\n statistics: null,\n numRows: 0,\n };\n }\n\n componentDidMount(): void {\n this.maybeGenerateStatistics();\n }\n\n componentWillUnmount(): void {\n if (this.cancelablePromise) {\n this.cancelablePromise.cancel();\n }\n }\n\n cancelablePromise: CancelablePromise<APIColumnStatistics> | null;\n\n maybeGenerateStatistics(): void {\n const { model } = this.props;\n\n const numRows = model.rowCount - model.pendingRowCount;\n this.setState({ numRows });\n if (!model.isColumnStatisticsAvailable) {\n this.setState({ loading: false });\n } else if (numRows < ColumnStatistics.AUTO_GENERATE_LIMIT) {\n this.handleGenerateStatistics();\n }\n }\n\n handleGenerateStatistics(): void {\n this.setState({ loading: true });\n\n const { column, model } = this.props;\n\n this.cancelablePromise = PromiseUtils.makeCancelable(\n model.columnStatistics(column)\n );\n\n this.cancelablePromise.then(this.handleStatistics).catch(this.handleError);\n }\n\n handleStatistics(stats: APIColumnStatistics): void {\n log.debug('Received statistics', stats);\n\n const { model, onStatistics } = this.props;\n const statistics: Statistic[] = [];\n\n stats.statisticsMap.forEach((value, operation) => {\n statistics.push({\n operation: ColumnStatistics.getStatsLabel(operation),\n value,\n type: stats.getType(operation),\n });\n });\n\n stats.uniqueValues.forEach((value, operation) => {\n statistics.push({\n operation,\n className: 'column-statistics-unique-value',\n value,\n type: 'long',\n });\n });\n\n this.setState({\n loading: false,\n statistics,\n numRows: model.rowCount - model.pendingRowCount,\n });\n\n onStatistics();\n }\n\n handleError(error: Error): void {\n if (error != null && PromiseUtils.isCanceled(error)) {\n log.debug('Called handleError on a cancelled promise result');\n return;\n }\n\n log.error('Error generating statistics', error);\n this.setState({\n error,\n loading: false,\n statistics: null,\n });\n }\n\n render(): React.ReactElement {\n const { column, model } = this.props;\n const { error, loading, statistics, numRows } = this.state;\n const showGenerateStatistics =\n !loading &&\n error == null &&\n statistics == null &&\n model.isColumnStatisticsAvailable;\n const statisticElements = [];\n const columnType = column.type.substring(column.type.lastIndexOf('.') + 1);\n const description = column.description === null ? null : column.description;\n if (statistics != null) {\n for (let i = 0; i < statistics.length; i += 1) {\n const { operation, className, value, type } = statistics[i];\n const formattedValue = !type\n ? model.displayString(value, column.type, column.name)\n : model.displayString(value, type);\n const statisticElement = (\n <React.Fragment key={operation}>\n <div\n className={classNames('column-statistic-operation', className)}\n >\n {operation}\n </div>\n <div className=\"column-statistic-value\">{formattedValue}</div>\n </React.Fragment>\n );\n statisticElements.push(statisticElement);\n }\n }\n const rowCountLabel =\n isExpandableGridModel(model) && model.hasExpandableRows\n ? 'Expanded Rows'\n : 'Number of Rows';\n const formattedRowCount = model.displayString(numRows, 'long');\n const columnIndex = model.getColumnIndexByName(column.name);\n return (\n <div className=\"column-statistics\">\n <div className=\"column-statistics-title\">\n {column.name}\n <span className=\"column-statistics-type\">&nbsp;({columnType})</span>\n <CopyButton\n className=\"column-statistics-copy\"\n tooltip=\"Copy column name\"\n copy={column.name}\n />\n </div>\n {description != null && (\n <div className=\"column-statistics-description\">{description}</div>\n )}\n {columnIndex != null && !model.isColumnMovable(columnIndex) && (\n <div className=\"column-statistics-status\">\n <FontAwesomeIcon\n icon={model.isColumnFrozen(columnIndex) ? dhFreeze : vsLock}\n className=\"mr-1\"\n />\n {model.isColumnFrozen(columnIndex) ? 'Frozen' : 'Not movable'}\n </div>\n )}\n <div className=\"column-statistics-grid\">\n {statistics == null && (\n <>\n <div className=\"column-statistic-operation\">{rowCountLabel}</div>\n <div className=\"column-statistic-value\">{formattedRowCount}</div>\n </>\n )}\n\n {statisticElements}\n </div>\n {showGenerateStatistics && (\n <Button\n kind=\"ghost\"\n className=\"px-0\"\n onClick={this.handleGenerateStatistics}\n >\n Generate Stats\n </Button>\n )}\n {error != null && <div className=\"error-message\">{`${error}`}</div>}\n {statistics && !loading && (\n <Button\n kind=\"ghost\"\n className=\"px-0\"\n onClick={this.handleGenerateStatistics}\n icon={<FontAwesomeIcon icon={dhRefresh} className=\"mr-1\" />}\n >\n Refresh\n </Button>\n )}\n {loading && (\n <div className=\"column-statistics-loading\">\n <LoadingSpinner className=\"mr-2\" />\n Calculating Stats...\n </div>\n )}\n </div>\n );\n }\n}\n\nexport default ColumnStatistics;\n","/* eslint react/no-did-update-set-state: \"off\" */\nimport React, { PureComponent } from 'react';\nimport { Button } from '@deephaven/components';\nimport {\n getLabelForBooleanFilter,\n getLabelForDateFilter,\n getLabelForNumberFilter,\n getLabelForTextFilter,\n TypeValue as FilterTypeValue,\n} from '@deephaven/filters';\nimport { vsTrash } from '@deephaven/icons';\nimport type { Column } from '@deephaven/jsapi-types';\nimport {\n AdvancedFilterItemType,\n Formatter,\n TableUtils,\n} from '@deephaven/jsapi-utils';\nimport Log from '@deephaven/log';\nimport classNames from 'classnames';\nimport memoizeOne from 'memoize-one';\nimport './AdvancedFilterCreatorFilterItem.scss';\n\nconst log = Log.module('AdvancedFilterCreatorFilterItem');\n\nexport interface AdvancedFilterCreatorFilterItemProps {\n column: Column;\n filterTypes: FilterTypeValue[];\n onChange(type: FilterTypeValue, value: string): void;\n onDelete(): void;\n selectedType?: FilterTypeValue;\n value?: string;\n formatter: Formatter;\n tableUtils: TableUtils;\n}\n\nexport type AdvancedFilterCreatorFilterItemState = AdvancedFilterItemType;\n\nexport class AdvancedFilterCreatorFilterItem extends PureComponent<\n AdvancedFilterCreatorFilterItemProps,\n AdvancedFilterCreatorFilterItemState\n> {\n static getLabelForFilter(\n columnType: string,\n filterType: FilterTypeValue\n ): string {\n try {\n if (\n TableUtils.isNumberType(columnType) ||\n TableUtils.isCharType(columnType)\n ) {\n return getLabelForNumberFilter(filterType);\n }\n if (TableUtils.isTextType(columnType)) {\n return getLabelForTextFilter(filterType);\n }\n if (TableUtils.isDateType(columnType)) {\n return getLabelForDateFilter(filterType);\n }\n if (TableUtils.isBooleanType(columnType)) {\n return getLabelForBooleanFilter(filterType);\n }\n throw new Error(`Unrecognized column type: ${columnType}`);\n } catch (e) {\n log.warn(e);\n return '';\n }\n }\n\n constructor(props: AdvancedFilterCreatorFilterItemProps) {\n super(props);\n\n this.handleDelete = this.handleDelete.bind(this);\n this.handleTypeChange = this.handleTypeChange.bind(this);\n this.handleValueChange = this.handleValueChange.bind(this);\n this.typeDropdown = null;\n\n const { value = '', filterTypes, selectedType = filterTypes[0] } = props;\n\n this.state = {\n selectedType,\n value,\n };\n }\n\n componentDidMount(): void {\n this.typeDropdown?.focus();\n }\n\n componentDidUpdate(prevProps: AdvancedFilterCreatorFilterItemProps): void {\n const { value, selectedType } = this.props;\n if (selectedType !== undefined && prevProps.selectedType !== selectedType) {\n this.setState({ selectedType });\n }\n if (value !== undefined && prevProps.value !== value) {\n this.setState({ value });\n }\n }\n\n typeDropdown: HTMLSelectElement | null;\n\n handleTypeChange(event: React.ChangeEvent<HTMLSelectElement>): void {\n const selectedType = event.target.value as FilterTypeValue;\n log.debug2('typeChange', selectedType);\n this.setState({ selectedType });\n\n const { onChange } = this.props;\n const { value } = this.state;\n if (value != null && value.length > 0) {\n // Don't send an update unless there's already a value entered\n onChange(selectedType, value);\n }\n }\n\n handleValueChange(event: React.ChangeEvent<HTMLInputElement>): void {\n log.debug2('valueChange');\n const { value } = event.target;\n this.setState({ value });\n\n const { onChange } = this.props;\n const { selectedType } = this.state;\n if (selectedType != null) {\n // Don't send an update unless they've already selected a type\n onChange(selectedType, value);\n }\n }\n\n handleDelete(): void {\n log.debug('delete');\n\n const { onDelete } = this.props;\n onDelete();\n }\n\n getCachedIsValid = memoizeOne(\n (\n column: Column,\n operation: FilterTypeValue,\n value: string,\n timeZone: string,\n tableUtils: TableUtils\n ): boolean => {\n try {\n // We don't want to show an error for an empty value\n return (\n !value ||\n tableUtils.makeAdvancedValueFilter(\n column,\n operation,\n value,\n timeZone\n ) != null\n );\n } catch (e) {\n return false;\n }\n }\n );\n\n render(): JSX.Element {\n const { column, filterTypes, formatter, tableUtils } = this.props;\n const { selectedType, value } = this.state;\n const showValueInput = !TableUtils.isBooleanType(column.type);\n const typeOptionElements = [];\n const isValid = this.getCachedIsValid(\n column,\n selectedType,\n value,\n formatter.timeZone,\n tableUtils\n );\n for (let i = 0; i < filterTypes.length; i += 1) {\n const type = filterTypes[i];\n const label = AdvancedFilterCreatorFilterItem.getLabelForFilter(\n column.type,\n type\n );\n const element = (\n <option key={type} value={type}>\n {label}\n </option>\n );\n typeOptionElements.push(element);\n }\n\n return (\n <div className=\"advanced-filter-creator-filter-item\">\n <div className=\"form-row\">\n <div className=\"form-group col\">\n <select\n className=\"form-control custom-select\"\n value={selectedType}\n onChange={this.handleTypeChange}\n ref={typeDropdown => {\n this.typeDropdown = typeDropdown;\n }}\n >\n {typeOptionElements}\n </select>\n </div>\n {showValueInput && (\n <div className=\"form-group col\">\n <div className=\"input-group\">\n <input\n type=\"text\"\n className={classNames('form-control', { error: !isValid })}\n placeholder=\"Enter value\"\n value={value}\n onChange={this.handleValueChange}\n />\n </div>\n </div>\n )}\n <div className=\"form-group col-1 px-0\">\n <Button\n kind=\"ghost\"\n className=\"w-100 h-100 p-0 m-0\"\n onClick={this.handleDelete}\n icon={vsTrash}\n tooltip=\"Remove Filter\"\n />\n </div>\n </div>\n </div>\n );\n }\n}\n\nexport default AdvancedFilterCreatorFilterItem;\n","/* eslint react/no-did-update-set-state: \"off\" */\nimport React, { PureComponent } from 'react';\nimport { CSSTransition } from 'react-transition-group';\nimport type {\n dh as DhType,\n FilterCondition,\n Table,\n} from '@deephaven/jsapi-types';\nimport { Formatter } from '@deephaven/jsapi-utils';\nimport {\n LoadingSpinner,\n SelectValueList,\n SelectItem,\n} from '@deephaven/components';\nimport Log from '@deephaven/log';\n\nconst log = Log.module('AdvancedFilterCreatorSelectValueList');\n\ninterface AdvancedFilterCreatorSelectValueListProps<T> {\n dh: DhType;\n selectedValues: T[];\n table?: Table;\n filters: FilterCondition[];\n invertSelection: boolean;\n onChange: (selectedValues: T[], invertSelection: boolean) => void;\n formatter: Formatter;\n}\n\ninterface AdvancedFilterCreatorSelectValueListState<T> {\n itemCount: number;\n items: SelectItem<T>[];\n offset: number;\n selectedValues: T[];\n isLoading: boolean;\n}\n/**\n * Select values from a long scrollable list.\n * Swaps items in and out for infinite scrolling\n */\nclass AdvancedFilterCreatorSelectValueList<T = unknown> extends PureComponent<\n AdvancedFilterCreatorSelectValueListProps<T>,\n AdvancedFilterCreatorSelectValueListState<T>\n> {\n static defaultProps = {\n invertSelection: true,\n selectedValues: [],\n onChange: (): void => undefined,\n };\n\n /**\n * Get the index of a value in an array. Has some special handling for some types, like DateTimes and Longs.\n * @param value The value to search for\n * @param values The array of values to search within\n */\n static indexOf(value: unknown, values: unknown[]): number {\n for (let i = 0; i < values.length; i += 1) {\n const v = values[i];\n if (\n v === value ||\n (v != null &&\n v.valueOf != null &&\n value != null &&\n value.valueOf != null &&\n v.valueOf() === value.valueOf())\n ) {\n return i;\n }\n }\n\n return -1;\n }\n\n constructor(props: AdvancedFilterCreatorSelectValueListProps<T>) {\n super(props);\n\n this.handleSelect = this.handleSelect.bind(this);\n this.handleViewportChange = this.handleViewportChange.bind(this);\n this.handleSelectionUpdate = this.handleSelectionUpdate.bind(this);\n this.handleTableUpdate = this.handleTableUpdate.bind(this);\n\n const { selectedValues, dh } = this.props;\n\n this.dh = dh;\n this.list = null;\n\n this.state = {\n itemCount: 0,\n items: [],\n offset: 0,\n selectedValues,\n isLoading: true,\n };\n }\n\n componentDidMount(): void {\n const { table } = this.props;\n if (table) this.startListening(table);\n }\n\n componentDidUpdate(\n prevProps: AdvancedFilterCreatorSelectValueListProps<T>\n ): void {\n const { filters, invertSelection, selectedValues, table } = this.props;\n if (prevProps.table !== table) {\n if (prevProps.table) this.stopListening(prevProps.table);\n if (table) this.startListening(table);\n this.resetViewport();\n }\n\n if (prevProps.invertSelection !== invertSelection) {\n this.setState({ selectedValues: [] }, this.handleSelectionUpdate);\n }\n\n if (prevProps.selectedValues !== selectedValues) {\n this.setState({ selectedValues }, this.handleSelectionUpdate);\n }\n\n if (prevProps.filters !== filters) {\n table?.applyFilter(filters);\n this.resetViewport();\n }\n }\n\n componentWillUnmount(): void {\n const { table } = this.props;\n if (table) this.stopListening(table);\n }\n\n dh: DhType;\n\n list: SelectValueList<T> | null;\n\n handleSelect(itemIndex: number, value: T): void {\n const { invertSelection } = this.props;\n let { selectedValues } = this.state;\n selectedValues = [...selectedValues];\n const selectedIndex = AdvancedFilterCreatorSelectValueList.indexOf(\n value,\n selectedValues\n );\n if (selectedIndex >= 0) {\n selectedValues.splice(selectedIndex, 1);\n } else {\n selectedValues.push(value);\n }\n\n let isSelected = selectedIndex < 0;\n if (invertSelection) {\n isSelected = !isSelected;\n }\n\n const { offset } = this.state;\n let { items } = this.state;\n items = [...items];\n const visibleItemIndex = itemIndex - offset;\n if (visibleItemIndex >= 0 && visibleItemIndex < items.length) {\n items[visibleItemIndex].isSelected = isSelected;\n }\n\n this.setState({ items, selectedValues });\n\n const { onChange } = this.props;\n onChange(selectedValues, invertSelection);\n }\n\n handleViewportChange(top: number, bottom: number): void {\n this.updateViewport(top, bottom);\n }\n\n handleSelectionUpdate(): void {\n this.updateItemSelection();\n }\n\n handleTableUpdate(event: CustomEvent): void {\n const { table, formatter } = this.props;\n if (!table) return;\n\n const data = event.detail;\n const { offset } = data;\n const items = [];\n const column = table.columns[0];\n for (let r = 0; r < data.rows.length; r += 1) {\n const row = data.rows[r];\n const value = row.get(column);\n const displayValue = formatter.getFormattedString(\n value,\n column.type,\n column.name\n );\n const isSelected = this.isValueSelected(value);\n items.push({\n displayValue,\n value,\n isSelected,\n });\n }\n\n log.debug2('Received table update:', offset, items.length);\n\n const itemCount = table.size;\n this.setState({ itemCount, items, offset, isLoading: false });\n }\n\n isValueSelected(value: T): boolean {\n const { invertSelection } = this.props;\n const { selectedValues } = this.state;\n\n // Need to check if any of the valueOf matches, timestamp value that is equal\n const selectedIndex = AdvancedFilterCreatorSelectValueList.indexOf(\n value,\n selectedValues\n );\n\n return invertSelection ? selectedIndex < 0 : selectedIndex >= 0;\n }\n\n startListening(table: Table): void {\n table.addEventListener(this.dh.Table.EVENT_UPDATED, this.handleTableUpdate);\n }\n\n stopListening(table: Table): void {\n table.removeEventListener(\n this.dh.Table.EVENT_UPDATED,\n this.handleTableUpdate\n );\n }\n\n resetViewport(): void {\n if (this.list && this.list.topRow != null && this.list.bottomRow != null) {\n this.updateViewport(this.list.topRow, this.list.bottomRow, true);\n }\n }\n\n updateItemSelection(): void {\n let { items } = this.state;\n\n items = [...items];\n\n for (let i = 0; i < items.length; i += 1) {\n const item = items[i];\n const { value } = item;\n item.isSelected = this.isValueSelected(value);\n }\n\n this.setState({ items });\n }\n\n updateViewport(top: number, bottom: number, isLoading = false): void {\n const { table } = this.props;\n if (table == null) {\n return;\n }\n\n if (isLoading) {\n this.setState({ isLoading: true });\n }\n\n const viewportSize = bottom - top + 1;\n const topRow = Math.max(0, top - viewportSize * 3);\n const bottomRow = Math.max(topRow, bottom + viewportSize * 3);\n\n log.debug2('Setting viewport', topRow, ',', bottomRow);\n table.setViewport(topRow, bottomRow);\n }\n\n render(): React.ReactElement {\n const { offset, isLoading, items, itemCount } = this.state;\n\n return (\n <div className=\"select-value-list-wrapper\">\n <SelectValueList\n itemCount={itemCount}\n items={items}\n offset={offset}\n onSelect={this.handleSelect}\n onViewportChange={this.handleViewportChange}\n ref={list => {\n this.list = list;\n }}\n />\n <CSSTransition\n in={isLoading}\n timeout={250}\n classNames=\"fade\"\n mountOnEnter\n unmountOnExit\n >\n <div className=\"loading-list\">\n <LoadingSpinner className=\"loading-spinner-large\" />\n </div>\n </CSSTransition>\n </div>\n );\n }\n}\n\nexport default AdvancedFilterCreatorSelectValueList;\n","/* eslint react/no-did-update-set-state: \"off\" */\nimport React, { PureComponent } from 'react';\nimport { CSSTransition } from 'react-transition-group';\nimport classNames from 'classnames';\nimport { Formatter, TableUtils } from '@deephaven/jsapi-utils';\nimport type {\n dh as DhType,\n FilterCondition,\n Table,\n} from '@deephaven/jsapi-types';\nimport { Button } from '@deephaven/components';\nimport AdvancedFilterCreatorSelectValueList from './AdvancedFilterCreatorSelectValueList';\nimport './AdvancedFilterCreatorSelectValue.scss';\nimport { ColumnName } from './CommonTypes';\n\ninterface AdvancedFilterCreatorSelectValueProps<T> {\n dh: DhType;\n invertSelection: boolean;\n selectedValues: T[];\n table?: Table;\n formatter: Formatter;\n onChange: (selectedValues: T[], invertSelection: boolean) => void;\n showSearch: boolean;\n timeZone: string;\n}\n\ninterface AdvancedFilterCreatorSelectValueState<T> {\n error?: string;\n filters: FilterCondition[];\n invertSelection: boolean;\n selectedValues: T[];\n searchText: string;\n table?: Table;\n}\n\nclass AdvancedFilterCreatorSelectValue<T = unknown> extends PureComponent<\n AdvancedFilterCreatorSelectValueProps<T>,\n AdvancedFilterCreatorSelectValueState<T>\n> {\n static searchDebounceTime = 250;\n\n static defaultProps = {\n invertSelection: true,\n selectedValues: [],\n onChange: (): void => undefined,\n showSearch: true,\n };\n\n constructor(props: AdvancedFilterCreatorSelectValueProps<T>) {\n super(props);\n\n this.handleSelectAllClick = this.handleSelectAllClick.bind(this);\n this.handleClearAllClick = this.handleClearAllClick.bind(this);\n this.handleListChange = this.handleListChange.bind(this);\n this.handleSearchChange = this.handleSearchChange.bind(this);\n this.handleUpdateFilterTimeout = this.handleUpdateFilterTimeout.bind(this);\n\n const { dh, invertSelection, selectedValues } = props;\n\n this.tableUtils = new TableUtils(dh);\n\n this.state = {\n filters: [],\n invertSelection,\n selectedValues,\n searchText: '',\n };\n }\n\n componentDidMount(): void {\n this.initSearchTable();\n }\n\n componentDidUpdate(\n prevProps: AdvancedFilterCreatorSelectValueProps<T>,\n prevState: AdvancedFilterCreatorSelectValueState<T>\n ): void {\n const { invertSelection, selectedValues, table } = this.props;\n if (prevProps.table !== table) {\n this.initSearchTable();\n }\n\n if (prevProps.invertSelection !== invertSelection) {\n this.setState({ invertSelection });\n }\n\n if (prevProps.selectedValues !== selectedValues) {\n this.setState({ selectedValues });\n }\n\n const { table: searchTable, searchText } = this.state;\n\n if (searchTable !== prevState.table) {\n if (prevState.table != null) {\n prevState.table.close();\n }\n if (searchTable != null) {\n this.startUpdateFilterTimer();\n }\n }\n\n if (searchText !== prevState.searchText) {\n this.startUpdateFilterTimer();\n }\n }\n\n componentWillUnmount(): void {\n const { table } = this.state;\n if (table != null) {\n table.close();\n }\n this.searchTablePromise = undefined;\n\n this.stopUpdateFilterTimer();\n }\n\n searchTablePromise?: Promise<Table>;\n\n tableUtils: TableUtils;\n\n updateFilterTimer?: ReturnType<typeof setTimeout>;\n\n getColumnName(): ColumnName {\n const { table } = this.props;\n if (table != null) {\n return table.columns[0].name;\n }\n return '';\n }\n\n getDisplayedValuesCount(): number | null {\n const { invertSelection, selectedValues, table } = this.state;\n if (table == null) {\n return null;\n }\n\n if (invertSelection) {\n return table.totalSize - selectedValues.length;\n }\n return selectedValues.length;\n }\n\n getDisplayedValueText(): string | null {\n const count = this.getDisplayedValuesCount();\n const { table } = this.state;\n\n const { formatter } = this.props;\n\n if (count != null && table != null) {\n const formattedCount = formatter.getFormattedString(count, 'long');\n const formattedTableSize = formatter.getFormattedString(\n table.totalSize,\n 'long'\n );\n let prefix = '';\n if (count < 1000000) {\n prefix = 'Displaying ';\n }\n return `${prefix}${formattedCount} of ${formattedTableSize}`;\n }\n return null;\n }\n\n initSearchTable(): void {\n const { table } = this.props;\n if (table == null) {\n return;\n }\n\n const searchTablePromise = table.copy();\n this.searchTablePromise = searchTablePromise;\n this.searchTablePromise.then(searchTable => {\n if (this.searchTablePromise === searchTablePromise) {\n this.setState({ table: searchTable });\n this.searchTablePromise = undefined;\n } else {\n searchTable.close();\n }\n });\n }\n\n handleListChange(selectedValues: T[], invertSelection: boolean): void {\n this.setState({ selectedValues, invertSelection });\n\n const { onChange } = this.props;\n onChange(selectedValues, invertSelection);\n }\n\n handleSearchChange(event: React.ChangeEvent<HTMLInputElement>): void {\n const searchText = event.target.value;\n this.setState({ searchText });\n }\n\n handleSelectAllClick(): void {\n this.resetSelection(true);\n }\n\n handleClearAllClick(): void {\n this.resetSelection(false);\n }\n\n handleUpdateFilterTimeout(): void {\n this.updateFilterTimer = undefined;\n this.updateTableFilter();\n }\n\n resetSelection(invertSelection: boolean): void {\n const selectedValues: T[] = [];\n\n this.setState({ invertSelection, selectedValues });\n\n const { onChange } = this.props;\n onChange(selectedValues, invertSelection);\n }\n\n startUpdateFilterTimer(): void {\n this.stopUpdateFilterTimer();\n\n this.updateFilterTimer = setTimeout(\n this.handleUpdateFilterTimeout,\n AdvancedFilterCreatorSelectValue.searchDebounceTime\n );\n }\n\n stopUpdateFilterTimer(): void {\n if (this.updateFilterTimer != null) {\n clearTimeout(this.updateFilterTimer);\n this.updateFilterTimer = undefined;\n }\n }\n\n updateTableFilter(): void {\n const { table, searchText } = this.state;\n const { timeZone } = this.props;\n const { tableUtils } = this;\n const column = table?.columns[0];\n const filters = [];\n if (column == null) {\n return;\n }\n let error;\n if (searchText.length > 0) {\n let filter = null;\n if (TableUtils.isCharType(column.type)) {\n // Just exact match for char\n filter = tableUtils.makeQuickFilter(column, searchText);\n } else if (TableUtils.isTextType(column.type)) {\n // case insensitive & contains search text\n filter = tableUtils.makeQuickFilter(column, `~${searchText}`, timeZone);\n } else {\n // greater than or equal search for everything else\n // we may want to be smarter with some other types (like dates)\n filter = tableUtils.makeQuickFilter(\n column,\n `>=${searchText}`,\n timeZone\n );\n }\n\n if (filter != null) {\n filters.push(filter);\n } else {\n error = 'Invalid search text';\n }\n }\n\n this.setState({ filters, error });\n }\n\n render(): React.ReactElement {\n const {\n error,\n filters,\n invertSelection,\n selectedValues,\n searchText,\n table,\n } = this.state;\n const { dh, formatter, showSearch } = this.props;\n const columnName = this.getColumnName();\n const displayedValuesText = this.getDisplayedValueText();\n const placeholderText = columnName ? `Find ${columnName}...` : '';\n\n return (\n <div className=\"advanced-filter-creator-select-value\">\n <div className={showSearch ? 'form-group' : ''}>\n <label htmlFor=\"advanced-filter-creator-select-value-input\">\n Select Values\n </label>\n {showSearch && (\n <input\n type=\"text\"\n className={classNames('form-control', {\n 'is-invalid': error != null,\n })}\n id=\"advanced-filter-creator-select-value-input\"\n placeholder={placeholderText}\n value={searchText}\n onChange={this.handleSearchChange}\n />\n )}\n </div>\n <AdvancedFilterCreatorSelectValueList\n dh={dh}\n table={table}\n filters={filters}\n invertSelection={invertSelection}\n selectedValues={selectedValues}\n formatter={formatter}\n onChange={this.handleListChange}\n />\n <div className=\"advanced-filter-creator-select-meta-row\">\n <div>\n <Button kind=\"ghost\" onClick={this.handleSelectAllClick}>\n Select All\n </Button>\n <Button kind=\"ghost\" onClick={this.handleClearAllClick}>\n Clear\n </Button>\n </div>\n <CSSTransition\n in={displayedValuesText != null}\n timeout={250}\n classNames=\"fade\"\n mountOnEnter\n unmountOnExit\n >\n <div className=\"row-count-info\">{displayedValuesText}</div>\n </CSSTransition>\n </div>\n </div>\n );\n }\n}\n\nexport default AdvancedFilterCreatorSelectValue;\n","/* eslint-disable jsx-a11y/no-noninteractive-tabindex */\n// disabled for tab-index on focus traps, which are intentionally non-interactive\n\nimport React, { PureComponent } from 'react';\nimport classNames from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport memoize from 'memoize-one';\nimport {\n Operator as FilterOperator,\n OperatorValue as FilterOperatorValue,\n TypeValue as FilterTypeValue,\n assertOperatorValue as assertFilterOperatorValue,\n} from '@deephaven/filters';\nimport { dhSortAmountDown, dhNewCircleLargeFilled } from '@deephaven/icons';\nimport {\n Formatter,\n TableUtils,\n SortDirection,\n FilterItem,\n} from '@deephaven/jsapi-utils';\nimport { Button, ContextActionUtils } from '@deephaven/components';\nimport Log from '@deephaven/log';\nimport { CancelablePromise, PromiseUtils } from '@deephaven/utils';\nimport type { Column, FilterCondition, Table } from '@deephaven/jsapi-types';\nimport shortid from 'shortid';\nimport AdvancedFilterCreatorFilterItem from './AdvancedFilterCreatorFilterItem';\nimport AdvancedFilterCreatorSelectValue from './AdvancedFilterCreatorSelectValue';\nimport './AdvancedFilterCreator.scss';\nimport IrisGridModel from './IrisGridModel';\nimport { AdvancedFilterOptions } from './CommonTypes';\n\nconst log = Log.module('AdvancedFilterCreator');\n\ntype FilterChangeHandler = (\n selectedType: FilterTypeValue,\n value: string\n) => void;\n\ninterface AdvancedFilterCreatorProps {\n model: IrisGridModel;\n column: Column;\n onFilterChange: (\n column: Column,\n filter: FilterCondition | null,\n options: AdvancedFilterOptions\n ) => void;\n onSortChange: (\n column: Column,\n direction: SortDirection,\n addToExisting?: boolean\n ) => void;\n onDone: () => void;\n options: AdvancedFilterOptions;\n sortDirection: SortDirection;\n formatter: Formatter;\n tableUtils: TableUtils;\n}\n\ninterface AdvancedFilterItem {\n selectedType?: FilterTypeValue;\n value?: string;\n key: string;\n}\n\ninterface AdvancedFilterCreatorState {\n // Filter items\n filterItems: AdvancedFilterItem[];\n\n // And/Or between the filter items\n filterOperators: FilterOperatorValue[];\n\n invertSelection: boolean;\n\n selectedValues: unknown[];\n\n valuesTableError: null;\n valuesTable?: Table;\n}\n\nclass AdvancedFilterCreator extends PureComponent<\n AdvancedFilterCreatorProps,\n AdvancedFilterCreatorState\n> {\n static debounceFilterUpdate = 250;\n\n static defaultProps = {\n options: {\n filterItems: null,\n filterOperators: null,\n invertSelection: true,\n selectedValues: [],\n },\n sortDirection: null,\n };\n\n static makeFilterItem(): AdvancedFilterItem {\n return { key: shortid() };\n }\n\n constructor(props: AdvancedFilterCreatorProps) {\n super(props);\n\n this.handleAddAnd = this.handleAddAnd.bind(this);\n this.handleAddOr = this.handleAddOr.bind(this);\n this.handleChangeFilterOperator = this.handleChangeFilterOperator.bind(\n this\n );\n this.handleDone = this.handleDone.bind(this);\n this.handleFilterChange = this.handleFilterChange.bind(this);\n this.handleFilterDelete = this.handleFilterDelete.bind(this);\n this.handleSelectValueChange = this.handleSelectValueChange.bind(this);\n this.handleReset = this.handleReset.bind(this);\n this.handleSortDown = this.handleSortDown.bind(this);\n this.handleSortUp = this.handleSortUp.bind(this);\n this.handleSubmit = this.handleSubmit.bind(this);\n this.handleFocusTrapStart = this.handleFocusTrapStart.bind(this);\n this.handleFocusTrapEnd = this.handleFocusTrapEnd.bind(this);\n this.handleUpdateTimeout = this.handleUpdateTimeout.bind(this);\n\n this.focusTrapContainer = React.createRef();\n\n const { options } = props;\n let { filterOperators, invertSelection, selectedValues } = options;\n\n // can be null or an empty array\n const filterItems: AdvancedFilterItem[] =\n options.filterItems?.map(({ selectedType, value }) => ({\n selectedType,\n value,\n key: shortid(),\n })) ?? [];\n if (filterItems.length === 0) {\n filterItems.push(AdvancedFilterCreator.makeFilterItem());\n }\n if (filterOperators == null) {\n filterOperators = [];\n }\n if (invertSelection == null) {\n invertSelection = true;\n }\n if (selectedValues == null) {\n selectedValues = [];\n }\n\n this.state = {\n // Filter items\n filterItems,\n\n // And/Or between the filter items\n filterOperators,\n\n invertSelection,\n\n selectedValues,\n\n valuesTableError: null,\n valuesTable: undefined,\n };\n }\n\n componentDidMount(): void {\n this.initValuesTable();\n }\n\n componentWillUnmount(): void {\n if (this.debounceTimeout != null) {\n clearTimeout(this.debounceTimeout);\n this.sendUpdate();\n }\n if (this.valuesTablePromise != null) {\n this.valuesTablePromise.cancel();\n }\n }\n\n focusTrapContainer: React.RefObject<HTMLFormElement>;\n\n debounceTimeout?: ReturnType<typeof setTimeout>;\n\n valuesTablePromise?: CancelablePromise<Table>;\n\n getFilterChangeHandler(index: number): FilterChangeHandler {\n return this.handleFilterChange.bind(this, index);\n }\n\n getFilterDeleteHandler(index: number): () => void {\n return this.handleFilterDelete.bind(this, index);\n }\n\n getFilterTypes = memoize((columnType: string): FilterTypeValue[] =>\n TableUtils.getFilterTypes(columnType)\n );\n\n initValuesTable(): void {\n const { model, column } = this.props;\n if (!model.isValuesTableAvailable) {\n log.debug('No values table for this model, just ignore');\n return;\n }\n\n this.valuesTablePromise = TableUtils.makeCancelableTablePromise(\n model.valuesTable(column)\n );\n this.valuesTablePromise\n .then(valuesTable => {\n const sort = valuesTable.columns[0].sort().asc();\n valuesTable.applySort([sort]);\n\n this.setState({ valuesTable });\n })\n .catch(error => {\n if (PromiseUtils.isCanceled(error)) {\n return;\n }\n\n log.error('Unable to open values table', error);\n this.setState({ valuesTableError: error });\n });\n }\n\n handleFocusTrapEnd(): void {\n (this.focusTrapContainer?.current?.querySelector(\n 'button,select,input,textarea'\n ) as HTMLElement).focus();\n }\n\n handleFocusTrapStart(): void {\n const inputs = this.focusTrapContainer?.current?.querySelectorAll(\n 'button,select,input,textarea'\n );\n if (inputs && inputs.length > 0) {\n const element = inputs[inputs.length - 1] as HTMLElement;\n element.focus();\n }\n }\n\n handleAddAnd(): void {\n let { filterItems, filterOperators } = this.state;\n filterItems = filterItems.concat(AdvancedFilterCreator.makeFilterItem());\n filterOperators = filterOperators.concat(FilterOperator.and);\n this.setState({ filterItems, filterOperators });\n }\n\n handleAddOr(): void {\n let { filterItems, filterOperators } = this.state;\n filterItems = filterItems.concat(AdvancedFilterCreator.makeFilterItem());\n filterOperators = filterOperators.concat(FilterOperator.or);\n this.setState({ filterItems, filterOperators });\n }\n\n handleChangeFilterOperator(index: number, operator: string): void {\n let { filterOperators } = this.state;\n filterOperators = [...filterOperators];\n\n assertFilterOperatorValue(operator);\n\n filterOperators[index] = operator;\n\n this.setState({ filterOperators });\n\n this.startUpdateTimer();\n }\n\n handleFilterChange(\n filterIndex: number,\n selectedType: FilterTypeValue,\n value: string\n ): void {\n let { filterItems } = this.state;\n filterItems = [...filterItems];\n const { key } = filterItems[filterIndex];\n filterItems[filterIndex] = { key, selectedType, value };\n\n this.setState({ filterItems });\n\n this.startUpdateTimer();\n }\n\n handleFilterDelete(filterIndex: number): void {\n let { filterItems, filterOperators } = this.state;\n filterItems = [...filterItems];\n filterOperators = [...filterOperators];\n if (filterIndex < filterItems.length) {\n filterItems.splice(filterIndex, 1);\n }\n\n if (filterIndex < filterOperators.length) {\n filterOperators.splice(filterIndex, 1);\n } else if (filterIndex === filterOperators.length) {\n // When deleting the last filter item, we also need to remove the last filter operator\n filterOperators.splice(filterOperators.length - 1, 1);\n }\n\n if (filterItems.length === 0) {\n filterItems.push(AdvancedFilterCreator.makeFilterItem());\n }\n\n this.setState({ filterItems, filterOperators });\n\n this.startUpdateTimer();\n }\n\n handleSelectValueChange(\n selectedValues: unknown[],\n invertSelection: boolean\n ): void {\n this.setState({ selectedValues, invertSelection });\n\n this.startUpdateTimer();\n }\n\n handleReset(): void {\n log.debug('Resetting Advanced Filter');\n\n this.setState({\n filterItems: [AdvancedFilterCreator.makeFilterItem()],\n filterOperators: [],\n selectedValues: [],\n invertSelection: true,\n });\n\n this.startUpdateTimer();\n }\n\n handleSortDown(event: React.MouseEvent<HTMLButtonElement>): void {\n const addToExisting = ContextActionUtils.isModifierKeyDown(event);\n this.sortTable(TableUtils.sortDirection.descending, addToExisting);\n }\n\n handleSortUp(event: React.MouseEvent<HTMLButtonElement>): void {\n const addToExisting = ContextActionUtils.isModifierKeyDown(event);\n this.sortTable(TableUtils.sortDirection.ascending, addToExisting);\n }\n\n handleSubmit(event: React.FormEvent<HTMLFormElement>): void {\n log.debug('Submitting Advanced Filter');\n this.stopUpdateTimer();\n this.sendUpdate();\n\n event.preventDefault();\n }\n\n handleDone(event: React.MouseEvent<HTMLButtonElement>): void {\n log.debug('Submitting and Closing Advanced Filter');\n this.stopUpdateTimer();\n this.sendUpdate();\n\n const { onDone } = this.props;\n onDone();\n\n event.preventDefault();\n }\n\n handleUpdateTimeout(): void {\n this.debounceTimeout = undefined;\n this.sendUpdate();\n }\n\n /**\n * Convenience function to check if the previous filter has been inputted, and\n * we should show the add filter buttons (+ AND OR)\n * @returns true If the add filter buttons should be shown, false otherwise\n */\n shouldShowAddFilter(): boolean {\n const { filterItems } = this.state;\n if (filterItems.length === 0) {\n return false;\n }\n\n const filterItem = filterItems[filterItems.length - 1];\n const { selectedType, value } = filterItem;\n\n return (\n selectedType != null &&\n selectedType.length > 0 &&\n value != null &&\n value.length > 0\n );\n }\n\n /**\n * Sorts the table in the specified direction. If already sorted in that direction, remove it.\n * @param direction The sort direction, ASC or DESC\n * @param addToExisting Add to the existing sort, or replace the existing table sort\n */\n sortTable(direction: SortDirection, addToExisting = false): void {\n const { column, onSortChange } = this.props;\n onSortChange(column, direction, addToExisting);\n }\n\n startUpdateTimer(): void {\n this.stopUpdateTimer();\n\n this.debounceTimeout = setTimeout(\n this.handleUpdateTimeout,\n AdvancedFilterCreator.debounceFilterUpdate\n );\n }\n\n stopUpdateTimer(): void {\n if (this.debounceTimeout !== undefined) {\n clearTimeout(this.debounceTimeout);\n this.debounceTimeout = undefined;\n }\n }\n\n sendUpdate(): void {\n const {\n filterItems,\n filterOperators,\n invertSelection,\n selectedValues,\n } = this.state;\n const { column, onFilterChange, model, tableUtils } = this.props;\n const { formatter } = model;\n\n const items = filterItems.filter(\n ({ selectedType, value }) =>\n selectedType != null && value != null && value !== ''\n ) as FilterItem[];\n\n const operators = filterOperators\n .filter(\n (operator, i) =>\n operator != null &&\n filterItems[i].selectedType != null &&\n filterItems[i].value != null &&\n filterItems[i].value !== ''\n )\n .slice(0, items.length - 1);\n // slice last operator, user may have set an operator but not a value\n\n const options = {\n filterItems: items,\n filterOperators: operators,\n invertSelection,\n selectedValues,\n };\n\n const filter = tableUtils.makeAdvancedFilter(\n column,\n options,\n formatter.timeZone\n );\n\n onFilterChange(column, filter, options);\n }\n\n render(): JSX.Element {\n const { column, model, sortDirection, formatter, tableUtils } = this.props;\n const {\n filterItems,\n filterOperators,\n invertSelection,\n selectedValues,\n valuesTable,\n valuesTableError,\n } = this.state;\n const { dh, isValuesTableAvailable } = model;\n const isBoolean = TableUtils.isBooleanType(column.type);\n const isDateType = TableUtils.isDateType(column.type);\n const filterTypes = this.getFilterTypes(column.type);\n const columnType = column.type.substring(column.type.lastIndexOf('.') + 1);\n const filterItemElements = [];\n if (!isBoolean && filterTypes.length) {\n for (let i = 0; i < filterItems.length; i += 1) {\n const filterItem = filterItems[i];\n const { key, selectedType, value } = filterItem;\n\n const element = (\n <AdvancedFilterCreatorFilterItem\n key={key}\n column={column}\n filterTypes={filterTypes}\n onChange={this.getFilterChangeHandler(i)}\n onDelete={this.getFilterDeleteHandler(i)}\n selectedType={selectedType}\n value={value}\n formatter={formatter}\n tableUtils={tableUtils}\n />\n );\n filterItemElements.push(element);\n\n if (i < filterOperators.length) {\n const filterOperator = filterOperators[i];\n const isAndFilter = filterOperator === FilterOperator.and;\n const operatorElement = (\n <div\n key={`filterOperator${key}`}\n className=\"form-row justify-content-end advanced-filter-creator-filter-operator\"\n >\n <Button\n kind=\"ghost\"\n className={classNames('filter-operator', {\n active: isAndFilter,\n })}\n onClick={() =>\n this.handleChangeFilterOperator(i, FilterOperator.and)\n }\n >\n AND\n </Button>\n <Button\n kind=\"ghost\"\n className={classNames('filter-operator', {\n active: !isAndFilter,\n })}\n onClick={() =>\n this.handleChangeFilterOperator(i, FilterOperator.or)\n }\n >\n OR\n </Button>\n </div>\n );\n filterItemElements.push(operatorElement);\n }\n }\n }\n const showAddFilterItem = this.shouldShowAddFilter();\n const addFilterItem = (\n <div\n key=\"addFilterItem\"\n className={classNames('form-row justify-content-end add-filter-item', {\n hidden: !showAddFilterItem,\n })}\n >\n <span className=\"text-muted\">\n <FontAwesomeIcon icon={dhNewCircleLargeFilled} />\n </span>\n <Button\n kind=\"ghost\"\n className=\"btn-filter-item\"\n onClick={this.handleAddAnd}\n disabled={!showAddFilterItem}\n tooltip=\"Add filter with AND\"\n >\n AND\n </Button>\n <Button\n kind=\"ghost\"\n className=\"btn-filter-item\"\n onClick={this.handleAddOr}\n disabled={!showAddFilterItem}\n tooltip=\"Add filter with OR\"\n >\n OR\n </Button>\n </div>\n );\n filterItemElements.push(addFilterItem);\n\n return (\n <div className=\"advanced-filter-creator\" role=\"presentation\">\n <div tabIndex={0} onFocus={this.handleFocusTrapStart} />\n <form onSubmit={this.handleSubmit} ref={this.focusTrapContainer}>\n <div className=\"title-bar\">\n <h6 className=\"advanced-filter-title\">Advanced Filters</h6>\n <div className=\"advanced-filter-menu-buttons\">\n <Button\n kind=\"ghost\"\n className={classNames('sort-operator', {\n active: sortDirection === TableUtils.sortDirection.descending,\n })}\n onClick={this.handleSortDown}\n icon={dhSortAmountDown}\n tooltip={`Sort ${column.name} Descending`}\n />\n <Button\n kind=\"ghost\"\n className={classNames('sort-operator', {\n active: sortDirection === TableUtils.sortDirection.ascending,\n })}\n onClick={this.handleSortUp}\n icon={\n <FontAwesomeIcon icon={dhSortAmountDown} rotation={180} />\n }\n tooltip={`Sort ${column.name} Ascending`}\n />\n </div>\n </div>\n <hr />\n <div className=\"advanced-filter-column-name\">\n {column.name}&nbsp;\n <span className=\"column-type\">({columnType})</span>\n </div>\n {filterItemElements}\n {isValuesTableAvailable && valuesTableError == null && (\n <>\n {!isBoolean && <hr />}\n <div className=\"form-group\">\n <AdvancedFilterCreatorSelectValue\n dh={dh}\n table={valuesTable}\n onChange={this.handleSelectValueChange}\n invertSelection={invertSelection}\n selectedValues={selectedValues}\n formatter={formatter}\n showSearch={!isDateType}\n timeZone={formatter.timeZone}\n />\n </div>\n </>\n )}\n <div className=\"form-row justify-content-end\">\n <Button\n kind=\"secondary\"\n className=\"mr-2\"\n onClick={this.handleReset}\n >\n Reset\n </Button>\n <Button kind=\"primary\" onClick={this.handleDone}>\n Done\n </Button>\n </div>\n </form>\n <div tabIndex={0} onFocus={this.handleFocusTrapEnd} />\n </div>\n );\n }\n}\n\nexport default AdvancedFilterCreator;\n","import React, {\n ChangeEvent,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport { DragDropContext } from 'react-beautiful-dnd';\nimport classNames from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport {\n dhNewCircleLargeFilled,\n vsTrash,\n vsEdit,\n dhWarningFilled,\n} from '@deephaven/icons';\nimport Log from '@deephaven/log';\nimport {\n DraggableItemList,\n DragUtils,\n Option,\n Select,\n RadioItem,\n RadioGroup,\n Button,\n} from '@deephaven/components';\nimport type { DraggableRenderItemProps, Range } from '@deephaven/components';\nimport { ModelIndex } from '@deephaven/grid';\nimport AggregationOperation from './AggregationOperation';\nimport AggregationUtils, { SELECTABLE_OPTIONS } from './AggregationUtils';\nimport './Aggregations.scss';\n\nconst log = Log.module('Aggregations');\n\nexport type Aggregation = {\n operation: AggregationOperation;\n selected: readonly string[];\n invert: boolean;\n};\n\nexport type AggregationSettings = {\n aggregations: readonly Aggregation[];\n showOnTop: boolean;\n};\n\nexport type AggregationsProps = {\n isRollup: boolean;\n settings: AggregationSettings;\n onChange: (settings: AggregationSettings) => void;\n onEdit: (aggregation: Aggregation) => void;\n};\n\nfunction Aggregations({\n isRollup,\n settings,\n onChange,\n onEdit,\n}: AggregationsProps): JSX.Element {\n const { aggregations, showOnTop } = settings;\n const options = useMemo(\n () =>\n SELECTABLE_OPTIONS.filter(\n option =>\n !aggregations.some(aggregation => aggregation.operation === option)\n ),\n [aggregations]\n );\n const [selectedOperation, setSelectedOperation] = useState(options[0]);\n const [selectedRanges, setSelectedRanges] = useState<Range[]>([]);\n const changeSettings = useCallback(\n changedSettings => {\n onChange({ ...settings, ...changedSettings });\n },\n [onChange, settings]\n );\n const changeAggregations = useCallback(\n newAggregations => {\n changeSettings({ aggregations: newAggregations });\n },\n [changeSettings]\n );\n\n const changeShowOnTop = useCallback(\n newShowOnTop => {\n changeSettings({ showOnTop: newShowOnTop });\n },\n [changeSettings]\n );\n\n const handleDragStart = useCallback(() => {\n log.debug('handleDragStart');\n\n DragUtils.startDragging();\n }, []);\n\n const handleDragEnd = useCallback(\n ({ destination, source }) => {\n log.debug('handleDragEnd', destination, source);\n\n DragUtils.stopDragging();\n\n if (destination === null) {\n return;\n }\n\n let destinationIndex = destination.index;\n if (source.index < destination.index) {\n destinationIndex += 1;\n }\n\n const newAggregations = [...aggregations];\n const draggedItems = DragUtils.reorder(\n newAggregations,\n selectedRanges,\n newAggregations,\n destinationIndex\n );\n const insertIndex = DragUtils.adjustDestinationIndex(\n destinationIndex,\n selectedRanges\n );\n const newSelectedRanges: Range[] = [\n [insertIndex, insertIndex + draggedItems.length - 1],\n ];\n changeAggregations(newAggregations);\n setSelectedRanges(newSelectedRanges);\n },\n [changeAggregations, aggregations, selectedRanges, setSelectedRanges]\n );\n\n const handleOperationChange = useCallback(\n operation => {\n setSelectedOperation(operation);\n },\n [setSelectedOperation]\n );\n\n const handleAdd = useCallback(() => {\n changeAggregations([\n ...aggregations,\n { operation: selectedOperation, selected: [], invert: true },\n ]);\n }, [aggregations, selectedOperation, changeAggregations]);\n\n const handleDeleteClicked = useCallback(\n (itemIndex: ModelIndex) => {\n changeAggregations(\n aggregations.filter((aggregation, index) => index !== itemIndex)\n );\n },\n [aggregations, changeAggregations]\n );\n\n const handleAggregationSelectionChange = useCallback(\n newSelectedRanges => {\n setSelectedRanges(newSelectedRanges);\n },\n [setSelectedRanges]\n );\n\n const handleAggregationSelect = useCallback(\n itemIndex => {\n const aggregation = aggregations[itemIndex];\n if (!AggregationUtils.isRollupOperation(aggregation.operation)) {\n onEdit(aggregation);\n }\n },\n [aggregations, onEdit]\n );\n\n const handleShowOnTopChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n changeShowOnTop(event.target.value === 'true');\n },\n [changeShowOnTop]\n );\n\n useEffect(\n function setDefaultOperation() {\n if (options.length > 0 && !options.includes(selectedOperation)) {\n setSelectedOperation(options[0]);\n }\n },\n [options, selectedOperation]\n );\n\n const renderAggregation = useCallback(\n ({\n item,\n itemIndex,\n isClone = false,\n selectedCount,\n }: DraggableRenderItemProps<Aggregation>) => {\n const text = item.operation;\n const badgeText = isClone ? `${selectedCount}` : undefined;\n const className = isClone ? 'item-list-item-clone' : undefined;\n const isRollupOperation = AggregationUtils.isRollupOperation(\n item.operation\n );\n const isEditable = !isClone && !isRollupOperation;\n return (\n <>\n <div\n className={classNames(\n 'item-list-item-content',\n 'draggable-item-list-item-content',\n className\n )}\n >\n <span className=\"title\">\n {text}\n {!isRollup && isRollupOperation && (\n <span className=\"small text-warning\">\n <FontAwesomeIcon icon={dhWarningFilled} /> Requires rollup\n </span>\n )}\n </span>\n {DraggableItemList.renderBadge({ text: badgeText })}\n {DraggableItemList.renderHandle()}\n </div>\n {!isClone && (\n <>\n <Button\n kind=\"ghost\"\n className=\"btn-edit\"\n icon={vsEdit}\n tooltip=\"Edit Columns\"\n onClick={() => onEdit(item)}\n disabled={!isEditable}\n />\n <Button\n kind=\"ghost\"\n className=\"btn-delete\"\n icon={vsTrash}\n tooltip=\"Delete Aggregation\"\n onClick={() => handleDeleteClicked(itemIndex)}\n />\n </>\n )}\n </>\n );\n },\n [handleDeleteClicked, onEdit, isRollup]\n );\n\n const isOptionsShown = options.length > 0;\n const isAggregationsShown = aggregations.length > 0;\n\n return (\n <div className=\"aggregations\">\n {isOptionsShown && (\n <div className=\"form-inline\">\n <Select onChange={handleOperationChange} value={selectedOperation}>\n {options.map(option => (\n <Option value={option} key={option}>\n {option}\n </Option>\n ))}\n </Select>\n <button\n type=\"button\"\n className=\"btn btn-link btn-add\"\n onClick={handleAdd}\n >\n <FontAwesomeIcon icon={dhNewCircleLargeFilled} />\n Add Aggregation\n </button>\n </div>\n )}\n {isOptionsShown && isAggregationsShown && <hr />}\n {isAggregationsShown && (\n <>\n {!isRollup && (\n <div className=\"form-inline\">\n <label>Placement:&nbsp;</label>\n <RadioGroup\n onChange={handleShowOnTopChange}\n value={`${showOnTop}`}\n >\n <RadioItem value=\"true\">Top</RadioItem>\n <RadioItem value=\"false\">Bottom</RadioItem>\n </RadioGroup>\n </div>\n )}\n <DragDropContext\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n >\n <DraggableItemList<Aggregation>\n className=\"selected-aggregations\"\n itemCount={aggregations.length}\n items={aggregations}\n renderItem={renderAggregation}\n offset={0}\n onSelectionChange={handleAggregationSelectionChange}\n onSelect={handleAggregationSelect}\n selectedRanges={selectedRanges}\n isMultiSelect\n />\n </DragDropContext>\n </>\n )}\n </div>\n );\n}\n\nexport default Aggregations;\n","import React, { useCallback, useMemo, useRef, useState } from 'react';\nimport classNames from 'classnames';\nimport { CSSTransition } from 'react-transition-group';\nimport { Button, Checkbox, ItemList, ThemeExport } from '@deephaven/components';\nimport { dhSortAlphaDown, dhSortAlphaUp } from '@deephaven/icons';\nimport type { Column } from '@deephaven/jsapi-types';\nimport { TableUtils } from '@deephaven/jsapi-utils';\nimport { Aggregation } from './Aggregations';\nimport { filterValidColumns } from './AggregationUtils';\nimport './AggregationEdit.scss';\n\ninterface AggregationEditItem {\n value: string;\n displayValue: string;\n}\n\nexport type AggregationEditProps = {\n aggregation: Aggregation;\n columns: readonly Column[];\n onChange: (aggregation: Aggregation) => void;\n};\n\nenum SortType {\n NONE,\n ASCENDING,\n DESCENDING,\n}\n\nconst DEFAULT_ROW_HEIGHT = 30;\n\nfunction AggregationEdit({\n aggregation,\n columns,\n onChange,\n}: AggregationEditProps): JSX.Element {\n const [top, setTop] = useState(-1);\n const [bottom, setBottom] = useState(-1);\n const [sort, setSort] = useState(SortType.NONE);\n const { invert, selected } = aggregation;\n const list = useRef<ItemList<AggregationEditItem>>(null);\n\n const isSelected = useCallback(\n name => (selected.includes(name) ? !invert : invert),\n [invert, selected]\n );\n\n const validColumns = useMemo(() => {\n let filteredColumns = filterValidColumns(columns, aggregation.operation);\n if (sort !== SortType.NONE) {\n filteredColumns = TableUtils.sortColumns(\n filteredColumns,\n sort === SortType.ASCENDING\n );\n }\n return filteredColumns;\n }, [columns, aggregation.operation, sort]);\n\n const items = useMemo(\n () =>\n top >= 0\n ? validColumns.slice(top, bottom + 1).map(c => ({\n value: c.name,\n displayValue: c.name,\n isSelected: isSelected(c.name),\n }))\n : [],\n [validColumns, isSelected, bottom, top]\n );\n\n const handleSelect = useCallback(\n itemIndex => {\n const { name } = validColumns[itemIndex];\n const selectedIndex = selected.indexOf(name);\n let newSelected = [...selected];\n let newInvert = invert;\n if (selectedIndex >= 0) {\n newSelected.splice(selectedIndex, 1);\n } else {\n newSelected.push(name);\n if (newSelected.length === validColumns.length) {\n // Every item is either selected or deselected, flip the inversion bit\n newSelected = [];\n newInvert = !invert;\n }\n }\n\n onChange({ ...aggregation, selected: newSelected, invert: newInvert });\n },\n [aggregation, invert, validColumns, selected, onChange]\n );\n\n const handleReset = useCallback(() => {\n setSort(SortType.NONE);\n onChange({ ...aggregation, selected: [], invert: true });\n }, [aggregation, onChange]);\n\n const handleViewportChange = useCallback(\n (newTop, newBottom) => {\n setTop(newTop);\n setBottom(newBottom);\n },\n [setTop, setBottom]\n );\n\n const toggleAll = useCallback(() => {\n if (selected.length === 0) {\n onChange({ ...aggregation, invert: !invert });\n } else {\n onChange({ ...aggregation, selected: [], invert: true });\n }\n }, [aggregation, invert, onChange, selected]);\n\n const checked = selected.length === 0 ? invert : null;\n const isModified = selected.length !== 0 || !invert || sort !== SortType.NONE;\n\n return (\n <div role=\"menu\" className=\"aggregation-edit\">\n <div className=\"top-menu\">\n <div className=\"form-inline\">\n <Checkbox checked={checked} onChange={toggleAll}>\n Toggle All\n </Checkbox>\n <div className=\"spacer\" />\n <CSSTransition\n in={isModified}\n timeout={ThemeExport.transitionSlowMs}\n classNames=\"fade\"\n mountOnEnter\n unmountOnExit\n >\n <Button kind=\"ghost\" className=\"btn-reset\" onClick={handleReset}>\n Reset\n </Button>\n </CSSTransition>\n <Button\n kind=\"ghost\"\n className={classNames({\n active: sort === SortType.ASCENDING,\n })}\n icon={dhSortAlphaDown}\n tooltip=\"Sort ascending\"\n onClick={() => setSort(SortType.ASCENDING)}\n />\n <Button\n kind=\"ghost\"\n className={classNames({\n active: sort === SortType.DESCENDING,\n })}\n icon={dhSortAlphaUp}\n tooltip=\"Sort descending\"\n onClick={() => setSort(SortType.DESCENDING)}\n />\n </div>\n </div>\n <div className=\"aggregation-edit-item-list\">\n <ItemList\n itemCount={validColumns.length}\n items={items}\n offset={top}\n renderItem={({ item }) => (\n <Checkbox checked={isSelected(item.value)}>\n {item.displayValue}\n </Checkbox>\n )}\n onSelect={handleSelect}\n onViewportChange={handleViewportChange}\n rowHeight={DEFAULT_ROW_HEIGHT}\n focusSelector=\"input\"\n ref={list}\n />\n </div>\n </div>\n );\n}\n\nexport default AggregationEdit;\n","import * as React from 'react';\n\nfunction SvgBarIcon(\n props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>\n): JSX.Element {\n return (\n // eslint-disable-next-line react/jsx-props-no-spreading\n <svg width={48} height={48} xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <g fill=\"none\" fillRule=\"evenodd\">\n <path fill=\"#C1C0C0\" d=\"M44 43v1H4v-1z\" />\n <path\n fill=\"#7DA4FF\"\n d=\"M8 26h4v15H8zM15 17h4v24h-4zM22 21h4v20h-4zM29 17h4v24h-4zM36 11h4v30h-4z\"\n />\n </g>\n </svg>\n );\n}\n\nexport default SvgBarIcon;\n","import * as React from 'react';\n\nfunction SvgHistogramIcon(\n props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>\n): JSX.Element {\n return (\n // eslint-disable-next-line react/jsx-props-no-spreading\n <svg width={48} height={48} xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <g fill=\"none\" fillRule=\"evenodd\">\n <path fill=\"#C1C0C0\" d=\"M44 43v1H4v-1z\" />\n <path\n fill=\"#7DA4FF\"\n d=\"M7 34h4v8H7zM12 31h4v11h-4zM17 27h4v15h-4zM22 22h4v20h-4zM27 27h4v15h-4zM32 29h4v13h-4zM37 31h4v11h-4z\"\n />\n </g>\n </svg>\n );\n}\n\nexport default SvgHistogramIcon;\n","import * as React from 'react';\n\nfunction SvgLineIcon(\n props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>\n): JSX.Element {\n return (\n // eslint-disable-next-line react/jsx-props-no-spreading\n <svg width={48} height={48} xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <g fill=\"none\" fillRule=\"evenodd\">\n <path fill=\"#C1C0C0\" d=\"M4 4h1v40H4zM44 43v1H5v-1z\" />\n <path\n stroke=\"#7DA4FF\"\n d=\"M7.984 32.44l7.982-11.378 5.273 3.739 9.952-10.838 2.826 1.894 7.45-5.802\"\n />\n <path\n stroke=\"#BECDEF\"\n d=\"M8.244 37.926L17 33.496l5 .87 10.637-10.35 10.615-1.381\"\n />\n </g>\n </svg>\n );\n}\n\nexport default SvgLineIcon;\n","import * as React from 'react';\n\nfunction SvgPieIcon(\n props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>\n): JSX.Element {\n return (\n // eslint-disable-next-line react/jsx-props-no-spreading\n <svg width={48} height={48} xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <g fill=\"none\" fillRule=\"evenodd\">\n <path\n d=\"M24 10c7.732 0 14 6.268 14 14s-6.268 14-14 14-14-6.268-14-14h14V10z\"\n fill=\"#80A6FF\"\n />\n <path d=\"M10 24c0-7.732 6.268-14 14-14v14H10z\" fill=\"#C1C0C0\" />\n </g>\n </svg>\n );\n}\n\nexport default SvgPieIcon;\n","import * as React from 'react';\n\nfunction SvgScatterIcon(\n props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>\n): JSX.Element {\n return (\n // eslint-disable-next-line react/jsx-props-no-spreading\n <svg width={48} height={48} xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <g fill=\"none\" fillRule=\"evenodd\">\n <path fill=\"#C1C0C0\" d=\"M44 43v1H4v-1z\" />\n <path fill=\"#939293\" d=\"M44 34v1H4v-1zM44 25v1H4v-1zM44 16v1H4v-1z\" />\n <circle fill=\"#7DA4FF\" cx={9.5} cy={37.5} r={1.5} />\n <circle fill=\"#7DA4FF\" cx={16.5} cy={30.5} r={1.5} />\n <circle fill=\"#7DA4FF\" cx={22.5} cy={36.5} r={1.5} />\n <circle fill=\"#7DA4FF\" cx={28.5} cy={30.5} r={1.5} />\n <circle fill=\"#7DA4FF\" cx={15.5} cy={38.5} r={1.5} />\n <circle fill=\"#7DA4FF\" cx={23.5} cy={25.5} r={1.5} />\n <circle fill=\"#7DA4FF\" cx={19.5} cy={19.5} r={1.5} />\n <circle fill=\"#7DA4FF\" cx={29.5} cy={19.5} r={1.5} />\n <circle fill=\"#7DA4FF\" cx={32.5} cy={26.5} r={1.5} />\n <circle fill=\"#7DA4FF\" cx={36.5} cy={13.5} r={1.5} />\n </g>\n </svg>\n );\n}\n\nexport default SvgScatterIcon;\n","import * as React from 'react';\n\nfunction FormatColumnWhereIcon(\n props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>\n): JSX.Element {\n return (\n <svg\n width=\"48\"\n height=\"48\"\n viewBox=\"0 0 48 48\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...props}\n >\n <rect width=\"48\" height=\"48\" fill=\"none\" />\n <rect x=\"26\" y=\"10\" width=\"15\" height=\"4\" fill=\"#9FDE70\" />\n <rect x=\"26\" y=\"22\" width=\"15\" height=\"4\" fill=\"#9FDE70\" />\n <rect x=\"26\" y=\"28\" width=\"15\" height=\"4\" fill=\"#FFD95C\" />\n <rect x=\"26\" y=\"34\" width=\"15\" height=\"4\" fill=\"#9FDE70\" />\n </svg>\n );\n}\n\nexport default FormatColumnWhereIcon;\n","import * as React from 'react';\n\nfunction FormatRowWhereIcon(\n props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>\n): JSX.Element {\n return (\n <svg\n width=\"48\"\n height=\"48\"\n viewBox=\"0 0 48 48\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...props}\n >\n <rect width=\"48\" height=\"48\" fill=\"none\" />\n <rect x=\"4\" y=\"16\" width=\"40\" height=\"4\" fill=\"#FFD95C\" />\n <rect x=\"4\" y=\"10\" width=\"40\" height=\"4\" fill=\"#78DCE8\" />\n <rect x=\"4\" y=\"34\" width=\"40\" height=\"4\" fill=\"#78DCE8\" />\n </svg>\n );\n}\n\nexport default FormatRowWhereIcon;\n","import React, { PureComponent } from 'react';\nimport classNames from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { Button, RadioGroup, RadioItem } from '@deephaven/components';\nimport {\n vsLink,\n dhUnlink,\n dhTable,\n dhNewCircleLargeFilled,\n vsCircleLargeFilled,\n vsTrash,\n} from '@deephaven/icons';\nimport type {\n Column,\n dh as DhType,\n SeriesPlotStyle,\n} from '@deephaven/jsapi-types';\nimport Log from '@deephaven/log';\nimport shortid from 'shortid';\nimport {\n BarIcon,\n HistogramIcon,\n LineIcon,\n PieIcon,\n ScatterIcon,\n} from './icons';\nimport './ChartBuilder.scss';\nimport IrisGridModel from '../IrisGridModel';\n\nconst log = Log.module('ChartBuilder');\n\nexport type ChartBuilderSettings = {\n type: SeriesPlotStyle;\n series: unknown;\n xAxis: string;\n isLinked: boolean;\n};\nexport type SeriesItem = {\n id: string;\n value: string;\n};\n\ninterface ChartBuilderProps {\n model: IrisGridModel;\n onSubmit: (obj: ChartBuilderSettings) => void;\n onChange: (obj: ChartBuilderSettings) => void;\n}\ninterface ChartBuilderState {\n /** The selected chart type */\n type: SeriesPlotStyle;\n\n /** Array of column names of the series to display */\n seriesItems: readonly SeriesItem[];\n\n /** The column name to use as the x-axis */\n xAxis: string;\n\n /** Whether the newly created chart should be linked with the table (update when filters update) */\n isLinked: boolean;\n}\n/**\n * Form for configuring all the settings when creating a console.\n */\nclass ChartBuilder extends PureComponent<ChartBuilderProps, ChartBuilderState> {\n static getMaxSeriesCount(dh: DhType, type: SeriesPlotStyle): number {\n switch (type) {\n case dh.plot.SeriesPlotStyle.PIE:\n return 1;\n case dh.plot.SeriesPlotStyle.HISTOGRAM:\n return 0;\n default:\n return 100;\n }\n }\n\n static makeSeriesItem(value: string): SeriesItem {\n return { id: shortid.generate(), value };\n }\n\n static makeDefaultSeriesItems(\n dh: DhType,\n type: SeriesPlotStyle,\n columns: readonly Column[]\n ): SeriesItem[] {\n const maxSeriesCount = ChartBuilder.getMaxSeriesCount(dh, type);\n if (maxSeriesCount === 0 || columns == null || columns.length === 0) {\n return [];\n }\n\n const value = columns.length > 1 ? columns[1].name : columns[0].name;\n return [ChartBuilder.makeSeriesItem(value)];\n }\n\n static getDefaultXAxis(\n type: SeriesPlotStyle,\n columns: readonly Column[]\n ): string | null {\n if (columns != null && columns.length > 0) {\n return columns[0].name;\n }\n\n return null;\n }\n\n constructor(props: ChartBuilderProps) {\n super(props);\n\n this.handleAddSeries = this.handleAddSeries.bind(this);\n this.handleLinkStateChange = this.handleLinkStateChange.bind(this);\n this.handleReset = this.handleReset.bind(this);\n this.handleSeriesChange = this.handleSeriesChange.bind(this);\n this.handleSeriesDeleteClick = this.handleSeriesDeleteClick.bind(this);\n this.handleSubmit = this.handleSubmit.bind(this);\n this.handleTypeClick = this.handleTypeClick.bind(this);\n this.handleXAxisChange = this.handleXAxisChange.bind(this);\n this.sendChange = this.sendChange.bind(this);\n\n const { model } = props;\n const { columns, dh } = model;\n\n const type = this.getTypes()[0];\n const xAxis = ChartBuilder.getDefaultXAxis(type, columns) as string;\n const seriesItems = ChartBuilder.makeDefaultSeriesItems(dh, type, columns);\n\n this.state = {\n /** The selected chart type */\n type,\n\n /** Array of column names of the series to display */\n seriesItems,\n\n /** The column name to use as the x-axis */\n xAxis,\n\n /** Whether the newly created chart should be linked with the table (update when filters update) */\n isLinked: true,\n };\n }\n\n getTypes() {\n const { model } = this.props;\n const { dh } = model;\n return [\n dh.plot.SeriesPlotStyle.LINE,\n dh.plot.SeriesPlotStyle.BAR,\n dh.plot.SeriesPlotStyle.SCATTER,\n dh.plot.SeriesPlotStyle.PIE,\n // IDS-6808: Disable Histogram in Chart Builder until we pipe histogram creation through the API\n // dh.plot.SeriesPlotStyle.HISTOGRAM,\n ];\n }\n\n /**\n * Converts the provided chart type into a readable type.\n * Just replaces underscores with spaces and capitals the first letter of each word.\n */\n getTypeName(type: SeriesPlotStyle): string | SeriesPlotStyle {\n const { model } = this.props;\n const { dh } = model;\n switch (type) {\n case dh.plot.SeriesPlotStyle.LINE:\n return 'Line';\n case dh.plot.SeriesPlotStyle.BAR:\n return 'Bar';\n case dh.plot.SeriesPlotStyle.SCATTER:\n return 'Scatter';\n case dh.plot.SeriesPlotStyle.PIE:\n return 'Pie';\n case dh.plot.SeriesPlotStyle.HISTOGRAM:\n return 'Histogram';\n default:\n return type;\n }\n }\n\n getTypeIcon(type: SeriesPlotStyle): React.ReactElement | null {\n const { model } = this.props;\n const { dh } = model;\n switch (type) {\n case dh.plot.SeriesPlotStyle.LINE:\n return <LineIcon />;\n case dh.plot.SeriesPlotStyle.BAR:\n return <BarIcon />;\n case dh.plot.SeriesPlotStyle.SCATTER:\n return <ScatterIcon />;\n case dh.plot.SeriesPlotStyle.PIE:\n return <PieIcon />;\n case dh.plot.SeriesPlotStyle.HISTOGRAM:\n return <HistogramIcon />;\n default:\n return null;\n }\n }\n\n getXAxisLabel(type: SeriesPlotStyle): string {\n const { model } = this.props;\n const { dh } = model;\n switch (type) {\n case dh.plot.SeriesPlotStyle.PIE:\n return 'Labels';\n case dh.plot.SeriesPlotStyle.HISTOGRAM:\n return 'Data';\n default:\n return 'X-Axis';\n }\n }\n\n getSeriesLabel(type: SeriesPlotStyle): string {\n const { model } = this.props;\n const { dh } = model;\n switch (type) {\n case dh.plot.SeriesPlotStyle.PIE:\n return 'Values';\n default:\n return 'Series';\n }\n }\n\n handleAddSeries(): void {\n this.setState(state => {\n const { seriesItems } = state;\n const newSeriesItems = [...seriesItems];\n\n const { model } = this.props;\n const { columns } = model;\n newSeriesItems.push({\n id: shortid.generate(),\n value: columns[0].name,\n });\n\n return { seriesItems: newSeriesItems };\n }, this.sendChange);\n }\n\n handleLinkStateChange(event: React.ChangeEvent<HTMLInputElement>): void {\n this.setState({ isLinked: event.target.value === 'true' }, this.sendChange);\n }\n\n handleReset(): void {\n const { model } = this.props;\n const { columns, dh } = model;\n\n const type = this.getTypes()[0];\n const xAxis = ChartBuilder.getDefaultXAxis(type, columns) as string;\n const seriesItems = ChartBuilder.makeDefaultSeriesItems(dh, type, columns);\n const isLinked = true;\n\n this.setState({ type, seriesItems, xAxis, isLinked }, this.sendChange);\n }\n\n handleSeriesChange(event: React.ChangeEvent<HTMLSelectElement>): void {\n const { value } = event.target;\n const index = event.target.getAttribute('data-index') as string;\n const intIndex = parseInt(index, 10);\n\n this.setState(state => {\n let { seriesItems } = state;\n\n seriesItems = [...seriesItems];\n seriesItems[intIndex].value = value;\n\n return { seriesItems };\n }, this.sendChange);\n }\n\n handleSeriesDeleteClick(event: React.MouseEvent<HTMLButtonElement>): void {\n const changeEvent = (event as unknown) as React.ChangeEvent<HTMLButtonElement>;\n const index = changeEvent.target.getAttribute('data-index') as string;\n const intIndex = parseInt(index, 10);\n\n this.setState(state => {\n const { seriesItems } = state;\n const newSeriesItems = [...seriesItems];\n\n newSeriesItems.splice(intIndex, 1);\n\n return { seriesItems: newSeriesItems };\n }, this.sendChange);\n }\n\n handleSubmit(event: React.FormEvent<HTMLFormElement>): void {\n event.preventDefault();\n\n const { onSubmit } = this.props;\n const { type, seriesItems, xAxis, isLinked } = this.state;\n const series = seriesItems.map(item => item.value);\n onSubmit({\n type: (`${type}` as unknown) as SeriesPlotStyle,\n series,\n xAxis,\n isLinked,\n });\n }\n\n handleTypeClick(event: React.MouseEvent<HTMLButtonElement>): void {\n const changeEvent = (event as unknown) as React.ChangeEvent<HTMLButtonElement>;\n const index = changeEvent.target.getAttribute('data-index') as string;\n const intIndex = parseInt(index, 10);\n\n const type = this.getTypes()[intIndex];\n\n log.debug2('handleTypeSelect', type);\n\n this.setState(state => {\n const { model } = this.props;\n const { dh } = model;\n const maxSeriesCount = ChartBuilder.getMaxSeriesCount(dh, type);\n let { seriesItems } = state;\n seriesItems = seriesItems.slice(0, maxSeriesCount);\n if (seriesItems.length === 0 && maxSeriesCount > 0) {\n const { columns } = model;\n seriesItems = ChartBuilder.makeDefaultSeriesItems(dh, type, columns);\n }\n\n return { type, seriesItems };\n }, this.sendChange);\n }\n\n handleXAxisChange(event: React.ChangeEvent<HTMLSelectElement>): void {\n const xAxis = event.target.value;\n log.debug2('x-axis change', xAxis);\n\n this.setState({ xAxis }, this.sendChange);\n }\n\n sendChange(): void {\n const { onChange } = this.props;\n const { isLinked, type, seriesItems, xAxis } = this.state;\n const series = seriesItems.map(item => item.value);\n\n onChange({ type, series, xAxis, isLinked });\n }\n\n render(): JSX.Element {\n const { model } = this.props;\n const { columns, dh } = model;\n const { seriesItems, type, xAxis, isLinked } = this.state;\n const maxSeriesCount = ChartBuilder.getMaxSeriesCount(dh, type);\n const xAxisLabel = this.getXAxisLabel(type);\n const seriesLabel = this.getSeriesLabel(type);\n const isSeriesVisible = seriesItems.length > 0;\n const isAddSeriesVisible = seriesItems.length < maxSeriesCount;\n\n return (\n <div className=\"chart-builder\">\n <form onSubmit={this.handleSubmit}>\n <div className=\"form-row\">\n <label>Select Chart Type</label>\n <div className=\"form-row\">\n {this.getTypes().map((chartType, index) => {\n const key = (chartType as unknown) as React.Key;\n return (\n <div key={key} className=\"col col-chart-type\">\n <button\n type=\"button\"\n className={classNames(\n 'btn',\n 'btn-icon',\n 'btn-chart-type',\n {\n active: chartType === type,\n }\n )}\n data-index={index}\n onClick={this.handleTypeClick}\n >\n {this.getTypeIcon(chartType)}\n {this.getTypeName(chartType)}\n </button>\n </div>\n );\n })}\n </div>\n </div>\n <hr />\n <div className=\"form-row form-inline\">\n <label className=\"col-2 label-left\">{xAxisLabel}</label>\n <select\n className=\"form-control custom-select select-x-axis col\"\n value={xAxis}\n onChange={this.handleXAxisChange}\n >\n {columns.map(column => (\n <option key={column.name} value={column.name}>\n {column.name}\n </option>\n ))}\n </select>\n </div>\n {isSeriesVisible && <hr />}\n {seriesItems.map((seriesItem, i) => (\n <div\n className=\"form-row form-inline form-series-item\"\n key={seriesItem.id}\n data-testid={`form-series-item-${i}`}\n >\n <label className=\"col-2 label-left\">\n {i === 0 ? seriesLabel : ''}\n </label>\n <select\n className=\"form-control custom-select select-series col\"\n value={seriesItem.value}\n onChange={this.handleSeriesChange}\n data-testid={`select-series-item-${i}`}\n data-index={i}\n >\n {columns.map(column => (\n <option key={column.name} value={column.name} data-index={i}>\n {column.name}\n </option>\n ))}\n </select>\n {seriesItems.length > 1 && (\n <Button\n kind=\"ghost\"\n className=\"btn-delete-series ml-2 px-2\"\n data-index={i}\n data-testid={`delete-series-${i}`}\n onClick={this.handleSeriesDeleteClick}\n icon={vsTrash}\n tooltip=\"Delete\"\n />\n )}\n </div>\n ))}\n {isAddSeriesVisible && (\n <div className=\"form-row\">\n <div className=\"col-2\" />\n <Button\n kind=\"ghost\"\n className=\"btn-add-series mt-1\"\n onClick={this.handleAddSeries}\n icon={dhNewCircleLargeFilled}\n >\n Add Series\n </Button>\n </div>\n )}\n <div className=\"form-row chart-builder-link\">\n <label className=\"col-2 label-right\">\n <div className=\"fa-md fa-layers\">\n <FontAwesomeIcon\n mask={dhTable}\n icon={vsCircleLargeFilled}\n transform=\"right-5 down-5\"\n />\n <FontAwesomeIcon\n icon={isLinked ? vsLink : dhUnlink}\n transform=\"grow-2 right-8 down-6\"\n />\n </div>\n </label>\n <RadioGroup\n onChange={this.handleLinkStateChange}\n value={`${isLinked}`}\n >\n <RadioItem value=\"true\">Sync State</RadioItem>\n <RadioItem value=\"false\">Freeze State</RadioItem>\n </RadioGroup>\n </div>\n <div className=\"form-row\">\n <div className=\"col-2 label-right\" />\n <div className=\"col chart-builder-link-info\">\n {isLinked\n ? 'Charts with synced state will update to match any filters or user modifications applied to the parent table.'\n : 'Freeze State disconnects the chart state from the parent table. New filters or user modifications on the parent table will not be applied.'}\n </div>\n </div>\n <div\n className={classNames('form-row', 'justify-content-end', 'my-3')}\n >\n <Button\n kind=\"secondary\"\n className=\"btn-reset\"\n onClick={this.handleReset}\n >\n Reset\n </Button>\n <Button kind=\"primary\" type=\"submit\" className=\"btn-submit\">\n Create\n </Button>\n </div>\n </form>\n </div>\n );\n }\n}\n\nexport default ChartBuilder;\n","import React, { Component, ReactElement } from 'react';\nimport * as monaco from 'monaco-editor';\nimport classNames from 'classnames';\nimport './InputEditor.scss';\n\ninterface InputEditorProps {\n value: string;\n onContentChanged: (value?: string) => void;\n editorSettings: Partial<monaco.editor.IStandaloneEditorConstructionOptions>;\n editorIndex: number;\n onTab: (editorIndex: number, shiftKey: boolean) => void;\n invalid: boolean;\n}\n\ninterface InputEditorState {\n isEditorFocused: boolean;\n isEditorEmpty: boolean;\n}\n/**\n * A monaco editor that looks like an general input\n */\n\nexport default class InputEditor extends Component<\n InputEditorProps,\n InputEditorState\n> {\n static defaultProps = {\n value: '',\n onContentChanged: (): void => undefined,\n editorSettings: {},\n editorIndex: 0,\n onTab: (): void => undefined,\n invalid: false,\n };\n\n constructor(props: InputEditorProps) {\n super(props);\n\n this.handleContentChanged = this.handleContentChanged.bind(this);\n this.handleEditorFocus = this.handleEditorFocus.bind(this);\n this.handleEditorBlur = this.handleEditorBlur.bind(this);\n this.handleContainerClick = this.handleContainerClick.bind(this);\n this.handleKeyDown = this.handleKeyDown.bind(this);\n\n this.state = {\n isEditorFocused: false,\n isEditorEmpty: true,\n };\n this.editorContainer = null;\n }\n\n componentDidMount(): void {\n this.initEditor();\n }\n\n componentWillUnmount(): void {\n this.destroyEditor();\n }\n\n editorContainer: HTMLDivElement | null;\n\n editor?: monaco.editor.IStandaloneCodeEditor;\n\n initEditor(): void {\n const { value, editorSettings } = this.props;\n const inputEditorSettings = {\n copyWithSyntaxHighlighting: 'false',\n fixedOverflowWidgets: true,\n folding: false,\n fontFamily: 'Fira Mono',\n glyphMargin: false,\n language: 'groovyDB',\n lineDecorationsWidth: 8,\n lineNumbers: 'off',\n minimap: { enabled: false },\n renderLineHighlight: 'none',\n scrollbar: {\n arrowSize: 0,\n horizontal: 'hidden',\n horizontalScrollbarSize: 0,\n },\n scrollBeyondLastLine: false,\n padding: {\n top: 6,\n bottom: 6,\n },\n tabCompletion: 'off',\n useTabStops: true,\n value,\n wordWrap: 'on',\n automaticLayout: true,\n ...editorSettings,\n } as monaco.editor.IStandaloneEditorConstructionOptions;\n if (!this.editorContainer) {\n throw new Error('editorContainer is null');\n }\n this.editor = monaco.editor.create(\n this.editorContainer,\n inputEditorSettings\n );\n this.editor.layout();\n\n // disable tab to spaces in this editor to improve tab navigation\n this.editor.getModel()?.updateOptions({ tabSize: 0 });\n\n // monaco does not propagate tab or enter events\n this.editor.onKeyDown(this.handleKeyDown);\n\n this.editor.onDidChangeModelContent(this.handleContentChanged);\n this.editor.onDidFocusEditorText(this.handleEditorFocus);\n this.editor.onDidBlurEditorText(this.handleEditorBlur);\n }\n\n destroyEditor(): void {\n this.editor?.dispose();\n this.editor = undefined;\n }\n\n handleContentChanged(): void {\n const { onContentChanged } = this.props;\n const value = this.editor?.getModel()?.getValue();\n if (value !== undefined) {\n this.setState({ isEditorEmpty: value.length === 0 });\n }\n onContentChanged(value);\n }\n\n handleEditorFocus(): void {\n this.setState({ isEditorFocused: true });\n }\n\n handleEditorBlur(): void {\n const value = this.editor?.getModel()?.getValue() ?? '';\n this.setState({\n isEditorEmpty: value.length === 0,\n isEditorFocused: false,\n });\n }\n\n // force editor to focus if clicked\n handleContainerClick(): void {\n const { isEditorFocused } = this.state;\n if (isEditorFocused) {\n return;\n }\n this.editor?.focus();\n }\n\n handleKeyDown(event: monaco.IKeyboardEvent): void {\n const { onTab, editorIndex } = this.props;\n if (event.code === 'Tab') {\n event.stopPropagation();\n event.preventDefault();\n onTab(editorIndex, event.shiftKey);\n }\n }\n\n render(): ReactElement {\n const { value, invalid } = this.props;\n const { isEditorFocused, isEditorEmpty } = this.state;\n return (\n <div\n className={classNames('input-editor-wrapper', {\n focused: isEditorFocused,\n invalid,\n })}\n role=\"presentation\"\n onClick={this.handleContainerClick}\n >\n <div\n className=\"editor-container\"\n ref={editorContainer => {\n this.editorContainer = editorContainer;\n }}\n />\n {isEditorEmpty && !value && (\n <div className=\"editor-placeholder text-muted\">Column Formula</div>\n )}\n </div>\n );\n }\n}\n","import React, { useCallback } from 'react';\nimport classNames from 'classnames';\nimport { Draggable } from 'react-beautiful-dnd';\nimport { Button } from '@deephaven/components';\nimport { vsTrash, vsGripper } from '@deephaven/icons';\nimport { DbNameValidator } from '@deephaven/utils';\nimport InputEditor from './InputEditor';\nimport { CustomColumnKey } from './CustomColumnBuilder';\n\nexport interface CustomColumnInputProps {\n eventKey: string;\n inputIndex: number;\n name: string;\n formula: string;\n onChange: (\n eventKey: string,\n inputType: CustomColumnKey,\n value: string\n ) => void;\n onDeleteColumn: (eventKey: string) => void;\n onTabInEditor: (editorIndex: number, shiftKey: boolean) => void;\n invalid: boolean;\n isDuplicate: boolean;\n}\n\nconst INPUT_TYPE = Object.freeze({\n NAME: 'name',\n FORMULA: 'formula',\n});\n\nconst EMPTY_FN = () => {\n // no-op\n};\n\nfunction CustomColumnInput({\n eventKey,\n name,\n inputIndex,\n formula,\n onChange,\n onDeleteColumn,\n onTabInEditor,\n invalid,\n isDuplicate,\n}: CustomColumnInputProps): JSX.Element {\n const isValidName = name === '' || DbNameValidator.isValidColumnName(name);\n const handleFormulaEditorContentChanged = useCallback(\n (formulaValue?: string) => {\n if (formulaValue !== undefined) {\n formulaValue.replace(/(\\r\\n|\\n|\\r)/gm, ''); // remove line break\n onChange(eventKey, INPUT_TYPE.FORMULA, formulaValue);\n }\n },\n [onChange, eventKey]\n );\n\n return (\n <Draggable\n draggableId={eventKey}\n index={inputIndex}\n disableInteractiveElementBlocking\n >\n {(provided, snapshot) => (\n <div\n className={classNames('draggable-container', {\n dragging: snapshot.isDragging,\n })}\n ref={provided.innerRef}\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...provided.draggableProps}\n >\n <div className=\"custom-column-input-container\">\n <div className=\"pb-3\">\n <div className=\"d-flex flex-row custom-column-name\">\n <input\n className={classNames('form-control custom-column-input', {\n 'is-invalid': invalid || !isValidName || isDuplicate,\n })}\n placeholder=\"Column Name\"\n value={name}\n onChange={event => {\n onChange(eventKey, INPUT_TYPE.NAME, event.target.value);\n }}\n />\n <Button\n kind=\"ghost\"\n className=\"ml-1 px-2\"\n onClick={() => {\n onDeleteColumn(eventKey);\n }}\n icon={vsTrash}\n tooltip=\"Delete custom column\"\n />\n\n <Button\n kind=\"ghost\"\n className=\"btn-drag-handle\"\n onClick={EMPTY_FN}\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...provided.dragHandleProps}\n icon={vsGripper}\n tooltip=\"Drag column to re-order\"\n />\n </div>\n {(!isValidName || isDuplicate) && (\n <p className=\"validate-label-error text-danger mb-0 mt-2 pl-1\">\n {!isValidName ? 'Invalid name' : 'Duplicate name'}\n </p>\n )}\n </div>\n <InputEditor\n editorSettings={{ language: 'deephavenDb' }}\n editorIndex={inputIndex}\n value={formula}\n onContentChanged={handleFormulaEditorContentChanged}\n onTab={onTabInEditor}\n invalid={invalid}\n />\n </div>\n <hr />\n </div>\n )}\n </Draggable>\n );\n}\n\nexport default CustomColumnInput;\n","/* eslint-disable class-methods-use-this */\nimport type { Event, EventTarget } from 'event-target-shim';\nimport {\n GridModel,\n GridRange,\n ModelIndex,\n MoveOperation,\n VisibleIndex,\n} from '@deephaven/grid';\nimport type {\n Column,\n ColumnStatistics,\n CustomColumn,\n dh as DhType,\n FilterCondition,\n Format,\n LayoutHints,\n RollupConfig,\n Row,\n Sort,\n Table,\n ValueTypeUnion,\n} from '@deephaven/jsapi-types';\nimport { Formatter } from '@deephaven/jsapi-utils';\nimport {\n ColumnName,\n UITotalsTableConfig,\n PendingDataMap,\n PendingDataErrorMap,\n} from './CommonTypes';\nimport ColumnHeaderGroup from './ColumnHeaderGroup';\n\ntype IrisGridModelEventNames = typeof IrisGridModel.EVENT[keyof typeof IrisGridModel.EVENT];\n\ntype IrisGridModelEventMap = {\n [E in IrisGridModelEventNames]: Event<E>;\n};\n\nconst EMPTY_ARRAY: never[] = [];\n\n/**\n * Abstract class that extends the GridModel to have more functionality, like filtering and sorting.\n * For use from IrisGrid.\n * Provides some abstraction from the dh.Table and dh.TreeTable classes, so we can treat them somewhat the same.\n * Note that it still uses dh.Column, dh.FilterCondition, dh.Sort, etc., still. Theoretically should abstract\n * those out as well, so there's no dependency on IrisAPI at all, but it's a lot of work for no real gain at this time.\n */\nabstract class IrisGridModel<\n TEventMap extends Record<string, Event<string>> = Record<\n string,\n Event<string>\n >,\n TMode extends 'standard' | 'strict' = 'standard'\n> extends GridModel<TEventMap & IrisGridModelEventMap, TMode> {\n static EVENT = Object.freeze({\n UPDATED: 'UPDATED',\n FORMATTER_UPDATED: 'FORMATTER_UPDATED',\n REQUEST_FAILED: 'REQUEST_FAILED',\n COLUMNS_CHANGED: 'COLUMNS_CHANGED',\n TABLE_CHANGED: 'TABLE_CHANGED',\n FILTERS_CHANGED: 'FILTERS_CHANGED',\n SORTS_CHANGED: 'SORTS_CHANGED',\n DISCONNECT: 'DISCONNECT',\n RECONNECT: 'RECONNECT',\n TOTALS_UPDATED: 'TOTALS_UPDATED',\n PENDING_DATA_UPDATED: 'PENDING_DATA_UPDATED',\n } as const);\n\n constructor(dh: DhType) {\n super();\n\n this.dh = dh;\n this.listenerCount = 0;\n }\n\n dh: DhType;\n\n listenerCount: number;\n\n // Pulled directly from event-target-shim implementation signature\n // https://github.com/mysticatea/event-target-shim/blob/master/src/lib/event-target.ts#L99\n // Using Parameters<GridModel['addEventListener']> doesn't work\n addEventListener<T extends string & keyof TEventMap>(\n type0: T,\n callback0?: EventTarget.EventListener<this, TEventMap[T]> | null,\n options0?: boolean | EventTarget.AddOptions\n ): void {\n super.addEventListener(type0, callback0 as never, options0 as never);\n\n this.listenerCount += 1;\n if (this.listenerCount === 1) {\n this.startListening();\n }\n }\n\n removeEventListener<T extends string & keyof TEventMap>(\n type0: T,\n callback0?: EventTarget.EventListener<this, TEventMap[T]> | null,\n options0?: boolean | EventTarget.Options\n ): void {\n super.removeEventListener(type0, callback0 as never, options0 as never);\n\n this.listenerCount -= 1;\n if (this.listenerCount === 0) {\n this.stopListening();\n }\n }\n\n /**\n * Function called when first listener is added.\n * Override for implementation specific behaviour.\n */\n startListening(): void {\n // no-op\n }\n\n /**\n * Function called when last listener is removed.\n * Override for implementation specific behaviour.\n */\n stopListening(): void {\n // no-op\n }\n\n /**\n * Gets the columns for this model\n * @returns All columns in the model\n */\n abstract get columns(): readonly Column[];\n\n /**\n * Gets the column index for this model\n * @param name The model column name.\n * @returns The numeric index of the requested column.\n */\n abstract getColumnIndexByName(name: string): ModelIndex | undefined;\n\n /**\n * Gets the columns for the model before any transformations (such as rollups) are applied.\n * @returns All original columns in the model.\n */\n get originalColumns(): readonly Column[] {\n return this.columns;\n }\n\n abstract get initialMovedColumns(): readonly MoveOperation[];\n\n /** List of row movements defined by the model. Used as initial movements for IrisGrid */\n abstract get initialMovedRows(): readonly MoveOperation[];\n\n /** List of column header groups defined by the model */\n abstract get initialColumnHeaderGroups(): readonly ColumnHeaderGroup[];\n\n /**\n * Retrieve the grouped columns for this model\n * @returns The columns that are groupe\n */\n abstract get groupedColumns(): readonly Column[];\n\n /**\n * @param column The model column index\n * @param row The model row index\n * @returns The format stored for that cell\n */\n abstract formatForCell(\n column: ModelIndex,\n row: ModelIndex\n ): Format | undefined;\n\n /**\n * @param column The model column index\n * @param row The model row index\n * @returns The value stored for that cell\n */\n abstract valueForCell(column: ModelIndex, row: ModelIndex): unknown;\n\n /**\n * @returns The filters set on this model\n */\n abstract get filter(): readonly FilterCondition[];\n\n /**\n * @param filter The filters to set\n */\n abstract set filter(filter: readonly FilterCondition[]);\n\n /**\n * @returns The formatter used when formatting data\n */\n abstract get formatter(): Formatter;\n\n /**\n * @param formatter The formatter to set\n */\n abstract set formatter(formatter: Formatter);\n\n /**\n * @param value The value to format\n * @param columnType The column type to format\n * @param columnName The column name to format\n */\n abstract displayString(\n value: unknown,\n columnType: string,\n columnName?: ColumnName\n ): string;\n\n /**\n * @returns The sorts used on this model\n */\n abstract get sort(): readonly Sort[];\n\n /**\n * @param sort The sorts to use on this model\n */\n abstract set sort(sort: readonly Sort[]);\n\n /**\n /**\n * @returns The custom columns on this model\n */\n abstract get customColumns(): readonly ColumnName[];\n\n /**\n * @param customColumns The custom columns to use\n */\n abstract set customColumns(customColumns: readonly ColumnName[]);\n\n /**\n * @returns The format columns on this model\n */\n abstract get formatColumns(): readonly CustomColumn[];\n\n /**\n * @param formatColumns The format columns to use\n */\n abstract set formatColumns(formatColumns: readonly CustomColumn[]);\n\n /**\n * @param columns The columns to treat as frozen\n */\n abstract updateFrozenColumns(columns: readonly ColumnName[]): void;\n\n /**\n * @returns The config to use for rolling up this table\n */\n abstract get rollupConfig(): RollupConfig | null;\n\n abstract set rollupConfig(rollupConfig: RollupConfig | null);\n\n /**\n * @returns The config to use for the totals table of this model\n */\n abstract get totalsConfig(): UITotalsTableConfig | null;\n\n abstract set totalsConfig(totalsConfig: UITotalsTableConfig | null);\n\n /**\n * @returns The LayoutHints to use for the columns of this table model\n */\n get layoutHints(): LayoutHints | null {\n return null;\n }\n\n /**\n * @returns Names of columns which should be locked to the front, but not floating\n */\n get frontColumns(): readonly ColumnName[] {\n return EMPTY_ARRAY;\n }\n\n /**\n * @returns Names of columns which should be locked to the back, but not floating\n */\n get backColumns(): readonly ColumnName[] {\n return EMPTY_ARRAY;\n }\n\n /**\n * @returns Names of columns which should be frozen to the front and floating\n */\n get frozenColumns(): readonly ColumnName[] {\n return EMPTY_ARRAY;\n }\n\n /**\n * @param index The column index to check\n * @returns Whether the column is one of LayoutHints' frozen columns\n */\n isColumnFrozen(index: ModelIndex): boolean {\n return false;\n }\n\n /**\n * @returns True if this model requires a filter to be set\n */\n get isFilterRequired(): boolean {\n return false;\n }\n\n get isReversible(): boolean {\n return true;\n }\n\n /**\n * @returns Returns a raw table that is frozen and can be used for exporting data\n */\n abstract export(): Promise<Table>;\n\n /**\n * @returns True if this model supports the columnStatistics(column) function\n */\n get isColumnStatisticsAvailable(): boolean {\n return false;\n }\n\n /**\n * The description for this model.\n * @returns The description of the model\n */\n get description(): string {\n return '';\n }\n\n /**\n * @param column The column to get statistics for\n * @returns The column statistics\n */\n abstract columnStatistics(column: Column): Promise<ColumnStatistics>;\n\n /**\n * @returns True if this model supports customColumns\n */\n get isCustomColumnsAvailable(): boolean {\n return false;\n }\n\n /**\n * @returns True if this model supports customColumns\n */\n get isFormatColumnsAvailable(): boolean {\n return false;\n }\n\n /**\n * @returns True if this model supports the export() function\n */\n get isExportAvailable(): boolean {\n return false;\n }\n\n /**\n * @returns True if this model supports the valuesTable(column) function\n */\n get isValuesTableAvailable(): boolean {\n return false;\n }\n\n /**\n * @returns True if this model should allow the chart builder\n */\n get isChartBuilderAvailable(): boolean {\n return false;\n }\n\n /**\n * @returns True if the rollup rows functionality is available\n */\n get isRollupAvailable(): boolean {\n return false;\n }\n\n /**\n * @returns True if select distinct functionality is available\n */\n get isSelectDistinctAvailable(): boolean {\n return false;\n }\n\n /**\n * @returns True if the totals functionality is available\n */\n get isTotalsAvailable(): boolean {\n return false;\n }\n\n /**\n * The names of columns with select distinct enabled\n * @returns An array of column names\n */\n abstract get selectDistinctColumns(): readonly ColumnName[];\n\n /**\n * Set the columns with select distinct enabled\n * @param names The array of column names to enable select distinct on\n */\n abstract set selectDistinctColumns(names: readonly ColumnName[]);\n\n /**\n * The pending data for this model\n * @returns A map of row index to a map of column name/value pairs\n */\n abstract get pendingDataMap(): PendingDataMap;\n\n /**\n * Set the pending data for this model\n * @param A map of row index to a map of column name/value pairs\n */\n abstract set pendingDataMap(map: PendingDataMap);\n\n /**\n * @returns The count of pending rows to show\n */\n abstract get pendingRowCount(): number;\n\n /**\n * Set the count of pending rows to show\n * @param count The count of pending rows to show\n */\n abstract set pendingRowCount(count: number);\n\n /**\n * Errors for the pending data\n * @returns Map from row number to the error\n */\n abstract get pendingDataErrors(): PendingDataErrorMap;\n\n /**\n * Commit pending data and save all data to the table\n */\n abstract commitPending(): Promise<void>;\n\n /**\n * Check if a column is filterable\n * @param columnIndex The column index to check for filterability\n * @returns True if the current provided column index is filterable, false otherwise\n */\n isFilterable(columnIndex: ModelIndex): boolean {\n return false;\n }\n\n /**\n * Set the indices of the viewport\n * @param top Top of viewport\n * @param bottom Bottom of viewport\n * @param columns The columns in the viewport. `null` for all columns\n */\n abstract setViewport(\n top: VisibleIndex,\n bottom: VisibleIndex,\n columns: Column[] | null\n ): void;\n\n /**\n * Takes a snapshot of the provided ranges\n * @param ranges The model ranges to take the snapshot of\n * @returns Returns the data in a row/column matrix\n */\n abstract snapshot(\n ranges: readonly GridRange[]\n ): Promise<readonly unknown[][]>;\n\n /**\n * @param ranges The ranges to take a snapshot of\n * @param includeHeaders Whether to include the headers in the snapshot or not\n * @param formatValue A function to format a value for a cell. Defaults to model format value.\n * @returns A text formatted snapshot of the data for the specified range set\n */\n abstract textSnapshot(\n ranges: readonly GridRange[],\n includeHeaders?: boolean,\n formatValue?: (value: unknown, column: Column, row?: Row) => string\n ): Promise<string>;\n\n /**\n * @param column The column to get the distinct values for\n * @returns A table partitioned on the column specified\n */\n abstract valuesTable(column: Column): Promise<Table>;\n\n /**\n * Close this model. It can no longer be used after being closed\n */\n close(): void {\n // no-op\n }\n\n /**\n * Don't allow any rows to be movable in any IrisGrids by default. Just columns.\n */\n isRowMovable(): boolean {\n return false;\n }\n\n /**\n * Delete ranges from an input grid. Will delete the entire row, causing data to shift up\n * @param ranges The ranges to delete\n * @returns A promise that resolves successfully when the operation is complete or rejects if there's an error\n */\n abstract delete(ranges: readonly GridRange[]): Promise<void>;\n\n abstract seekRow(\n startRow: number,\n column: Column,\n valueType: ValueTypeUnion,\n value: unknown,\n insensitive?: boolean,\n contains?: boolean,\n isBackwards?: boolean\n ): Promise<number>;\n\n get isSeekRowAvailable(): boolean {\n return false;\n }\n\n abstract get columnHeaderGroups(): readonly ColumnHeaderGroup[];\n\n abstract get columnHeaderGroupMap(): ReadonlyMap<string, ColumnHeaderGroup>;\n\n abstract set columnHeaderGroups(groups: readonly ColumnHeaderGroup[]);\n\n abstract getColumnHeaderParentGroup(\n modelIndex: ModelIndex,\n depth: number\n ): ColumnHeaderGroup | undefined;\n}\n\nexport default IrisGridModel;\n","import React, { Component, ReactElement } from 'react';\nimport classNames from 'classnames';\nimport shortid from 'shortid';\nimport memoize from 'memoize-one';\nimport { DragDropContext, Droppable, DropResult } from 'react-beautiful-dnd';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { Button, DragUtils, LoadingSpinner } from '@deephaven/components';\nimport { dhNewCircleLargeFilled, vsWarning, vsPass } from '@deephaven/icons';\nimport { DbNameValidator } from '@deephaven/utils';\nimport CustomColumnInput from './CustomColumnInput';\nimport './CustomColumnBuilder.scss';\nimport IrisGridModel from '../IrisGridModel';\n\nexport type CustomColumnKey = 'eventKey' | 'name' | 'formula';\n\ntype Input = {\n eventKey: string;\n name: string;\n formula: string;\n};\nexport interface CustomColumnBuilderProps {\n model: IrisGridModel;\n customColumns: readonly string[];\n onSave: (columns: readonly string[]) => void;\n onCancel: () => void;\n}\n\ninterface CustomColumnBuilderState {\n inputs: readonly Input[];\n isCustomColumnApplying: boolean;\n errorMessage: ReactElement | null;\n hasRequestFailed: boolean;\n isSuccessShowing: boolean;\n}\nclass CustomColumnBuilder extends Component<\n CustomColumnBuilderProps,\n CustomColumnBuilderState\n> {\n static SUCCESS_SHOW_DURATION = 750;\n\n static makeCustomColumnInputEventKey(): string {\n return shortid.generate();\n }\n\n static createCustomColumnInput(): Input {\n return {\n eventKey: shortid.generate(),\n name: '',\n formula: '',\n };\n }\n\n constructor(props: CustomColumnBuilderProps) {\n super(props);\n\n this.handleAddColumnClick = this.handleAddColumnClick.bind(this);\n this.handleSaveClick = this.handleSaveClick.bind(this);\n this.handleInputChange = this.handleInputChange.bind(this);\n this.handleDeleteColumn = this.handleDeleteColumn.bind(this);\n this.handleCustomColumnUpdated = this.handleCustomColumnUpdated.bind(this);\n this.handleRequestFailed = this.handleRequestFailed.bind(this);\n this.handleDragEnd = this.handleDragEnd.bind(this);\n this.resetRequestFailed = this.resetRequestFailed.bind(this);\n\n this.handleEditorTabNavigation = this.handleEditorTabNavigation.bind(this);\n\n this.state = {\n inputs: [],\n isCustomColumnApplying: false,\n errorMessage: null,\n hasRequestFailed: false,\n isSuccessShowing: false,\n };\n this.container = null;\n this.successButtonTimer = null;\n }\n\n componentDidMount(): void {\n const { customColumns } = this.props;\n this.parseCustomColumns(customColumns);\n this.startListening();\n }\n\n componentWillUnmount(): void {\n this.stopListening();\n if (this.successButtonTimer) {\n clearTimeout(this.successButtonTimer);\n }\n }\n\n container: HTMLDivElement | null;\n\n successButtonTimer: ReturnType<typeof setTimeout> | null;\n\n getInput = memoize((inputs: readonly Input[], key: string) =>\n inputs.find(input => input.eventKey === key)\n );\n\n getInputIndex = memoize((inputs: readonly Input[], key: string) =>\n inputs.findIndex(input => input.eventKey === key)\n );\n\n resetErrorMessage(): void {\n this.setState({ errorMessage: null });\n }\n\n startListening(): void {\n const { model } = this.props;\n model.addEventListener(\n IrisGridModel.EVENT.COLUMNS_CHANGED,\n this.handleCustomColumnUpdated\n );\n model.addEventListener(\n IrisGridModel.EVENT.UPDATED,\n this.handleCustomColumnUpdated\n );\n model.addEventListener(\n IrisGridModel.EVENT.REQUEST_FAILED,\n this.handleRequestFailed\n );\n }\n\n stopListening(): void {\n const { model } = this.props;\n model.removeEventListener(\n IrisGridModel.EVENT.COLUMNS_CHANGED,\n this.handleCustomColumnUpdated\n );\n model.removeEventListener(\n IrisGridModel.EVENT.UPDATED,\n this.handleCustomColumnUpdated\n );\n model.removeEventListener(\n IrisGridModel.EVENT.REQUEST_FAILED,\n this.handleRequestFailed\n );\n }\n\n parseCustomColumns(customColumns: readonly string[]): void {\n if (customColumns.length > 0) {\n const customColumnInputs = customColumns.map(customColumn => {\n const input = customColumn.split(/=(.+)/, 2);\n return {\n eventKey: CustomColumnBuilder.makeCustomColumnInputEventKey(),\n name: input[0],\n formula: input[1],\n };\n });\n this.setState({ inputs: customColumnInputs });\n } else {\n this.setState({\n inputs: [CustomColumnBuilder.createCustomColumnInput()],\n });\n }\n }\n\n handleAddColumnClick(): void {\n const { inputs } = this.state;\n const newInputs = [...inputs];\n newInputs.push(CustomColumnBuilder.createCustomColumnInput());\n this.setState({\n inputs: newInputs,\n });\n }\n\n handleDeleteColumn(eventKey: string): void {\n const { inputs } = this.state;\n const customColumnIndex = this.getInputIndex(inputs, eventKey);\n const newInputs = [...inputs];\n newInputs.splice(customColumnIndex, 1);\n if (newInputs.length === 0) {\n newInputs.push(CustomColumnBuilder.createCustomColumnInput());\n }\n this.setState({\n inputs: newInputs,\n });\n }\n\n handleInputChange(\n eventKey: string,\n type: CustomColumnKey,\n value: string\n ): void {\n const { inputs } = this.state;\n const customColumnIndex = this.getInputIndex(inputs, eventKey);\n const customColumnInput = this.getInput(inputs, eventKey);\n\n const newCustomInput = { ...customColumnInput } as Input;\n newCustomInput[type] = value;\n\n const newInputs = [...inputs];\n newInputs.splice(customColumnIndex, 1, newCustomInput);\n this.setState({\n inputs: newInputs,\n });\n }\n\n handleCustomColumnUpdated(): void {\n const { isCustomColumnApplying } = this.state;\n if (!isCustomColumnApplying) {\n return;\n }\n this.setState(\n { isCustomColumnApplying: false, isSuccessShowing: true },\n () => {\n this.successButtonTimer = setTimeout(\n () => this.setState({ isSuccessShowing: false }),\n CustomColumnBuilder.SUCCESS_SHOW_DURATION\n );\n }\n );\n }\n\n handleRequestFailed(event: Event): void {\n const customEvent = event as CustomEvent;\n const { isCustomColumnApplying } = this.state;\n if (!isCustomColumnApplying) {\n return;\n }\n\n this.setState({\n isCustomColumnApplying: false,\n errorMessage: (\n <>\n <p>\n <FontAwesomeIcon icon={vsWarning} /> Failed to apply custom columns.\n </p>\n <div className=\"error-box\">\n {customEvent.detail.errorMessage}\n <br />\n Table configuration:{' '}\n {JSON.stringify(customEvent.detail.configuration)}\n </div>\n </>\n ),\n hasRequestFailed: true,\n });\n }\n\n handleDragEnd(result: DropResult): void {\n DragUtils.stopDragging();\n\n // if dropped outside the list\n if (!result.destination) {\n return;\n }\n const { inputs } = this.state;\n const sourceIndex = result.source.index;\n const destinationIndex = result.destination.index;\n const newInputs = [...inputs];\n const sourceInput = inputs[sourceIndex];\n\n newInputs.splice(sourceIndex, 1);\n newInputs.splice(destinationIndex, 0, sourceInput);\n\n this.setState({ inputs: newInputs });\n }\n\n handleEditorTabNavigation(focusEditorIndex: number, shiftKey: boolean): void {\n const { inputs } = this.state;\n // focus on drag handle\n if (shiftKey) {\n (this.container?.querySelectorAll('.btn-drag-handle')[\n focusEditorIndex\n ] as HTMLButtonElement).focus();\n return;\n }\n if (focusEditorIndex === inputs.length - 1) {\n (this.container?.querySelector(\n '.btn-add-column'\n ) as HTMLButtonElement)?.focus();\n } else {\n // focus on next column name input\n const nextFocusIndex = focusEditorIndex + 1;\n (this.container?.querySelectorAll(`.custom-column-input`)[\n nextFocusIndex\n ] as HTMLInputElement).focus();\n }\n }\n\n handleSaveClick(): void {\n const { onSave, customColumns: originalCustomColumns } = this.props;\n const { inputs, isCustomColumnApplying } = this.state;\n if (isCustomColumnApplying) {\n return;\n }\n const customColumns = [] as string[];\n inputs.forEach(input => {\n const { name, formula } = input;\n if (name && formula) {\n customColumns.push(`${name}=${formula}`);\n }\n });\n this.resetErrorMessage();\n this.setState({\n // If both are 0, then moving from no custom to no custom. The parent won't re-render to cancel the loading state\n isCustomColumnApplying:\n customColumns.length > 0 || originalCustomColumns.length > 0,\n });\n onSave(customColumns);\n }\n\n resetRequestFailed(): void {\n this.setState(({ hasRequestFailed }) => {\n if (hasRequestFailed) {\n return { hasRequestFailed: false };\n }\n return null;\n });\n }\n\n renderInputs(): ReactElement[] {\n const { inputs, hasRequestFailed } = this.state;\n\n const nameCount = new Map();\n inputs.forEach(({ name }) =>\n nameCount.set(name, (nameCount.get(name) ?? 0) + 1)\n );\n\n return inputs.map((input, index) => {\n const { eventKey, name, formula } = input;\n const isDuplicate = (nameCount.get(name) ?? 0) > 1;\n return (\n <CustomColumnInput\n key={eventKey}\n inputIndex={index}\n eventKey={eventKey}\n name={name}\n formula={formula}\n onChange={this.handleInputChange}\n onDeleteColumn={this.handleDeleteColumn}\n onTabInEditor={this.handleEditorTabNavigation}\n invalid={hasRequestFailed}\n isDuplicate={isDuplicate}\n />\n );\n });\n }\n\n renderSaveButton(): ReactElement {\n const { inputs, isCustomColumnApplying, isSuccessShowing } = this.state;\n const saveText = inputs.length > 1 ? 'Save Columns' : 'Save Column';\n const areNamesValid = inputs.every(\n ({ name }) => name === '' || DbNameValidator.isValidColumnName(name)\n );\n const filteredNames = inputs\n .filter(({ name }) => name !== '')\n .map(({ name }) => name);\n const areNamesUnique = new Set(filteredNames).size === filteredNames.length;\n\n return (\n <Button\n kind={isSuccessShowing ? 'success' : 'primary'}\n className={classNames('btn-apply', {\n 'btn-spinner': isCustomColumnApplying,\n })}\n disabled={\n isSuccessShowing ||\n isCustomColumnApplying ||\n !areNamesValid ||\n !areNamesUnique\n }\n onClick={this.handleSaveClick}\n >\n {isCustomColumnApplying && (\n <span>\n <LoadingSpinner />\n <span className=\"btn-normal-content\">Applying</span>\n </span>\n )}\n {!isSuccessShowing && !isCustomColumnApplying && saveText}\n {isSuccessShowing && (\n <>\n <FontAwesomeIcon icon={vsPass} /> Success\n </>\n )}\n </Button>\n );\n }\n\n render(): JSX.Element {\n const { onCancel } = this.props;\n const { errorMessage } = this.state;\n return (\n <div\n role=\"presentation\"\n className=\"custom-column-builder-container\"\n ref={container => {\n this.container = container;\n }}\n onClick={this.resetRequestFailed}\n onFocus={this.resetRequestFailed}\n >\n <hr />\n <DragDropContext\n onDragStart={DragUtils.startDragging}\n onDragEnd={this.handleDragEnd}\n >\n <Droppable droppableId=\"droppable-custom-columns\">\n {(provided, snapshot) => (\n <div\n ref={provided.innerRef}\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...provided.droppableProps}\n className={classNames('droppable-container', {\n dragging: snapshot.draggingFromThisWith,\n })}\n >\n {this.renderInputs()}\n {provided.placeholder}\n </div>\n )}\n </Droppable>\n </DragDropContext>\n\n <div className=\"pt-1 px-3\">\n <Button\n kind=\"ghost\"\n className=\"btn-add-column\"\n onClick={this.handleAddColumnClick}\n icon={dhNewCircleLargeFilled}\n >\n Add Another Column\n </Button>\n </div>\n\n <div className=\"custom-column-builder-footer\">\n {errorMessage && <div className=\"error-message\">{errorMessage}</div>}\n\n <div className=\"d-flex justify-content-end\">\n <Button kind=\"secondary\" className=\"mr-2\" onClick={onCancel}>\n Cancel\n </Button>\n {this.renderSaveButton()}\n </div>\n </div>\n </div>\n );\n }\n}\n\nexport default CustomColumnBuilder;\n","enum OptionType {\n ADVANCED_SETTINGS = 'ADVANCED_SETTINGS',\n AGGREGATIONS = 'AGGREGATIONS',\n AGGREGATION_EDIT = 'AGGREGATIONS_EDIT',\n CHART_BUILDER = 'CHART_BUILDER',\n CUSTOM_COLUMN_BUILDER = 'CUSTOM_COLUMN_BUILDER',\n QUICK_FILTERS = 'QUICK_FILTERS',\n ROLLUP_ROWS = 'ROLLUP_ROWS',\n SEARCH_BAR = 'SEARCH_BAR',\n SELECT_DISTINCT = 'SELECT_DISTINCT',\n TABLE_EXPORTER = 'TABLE_EXPORTER',\n VISIBILITY_ORDERING_BUILDER = 'VISIBILITY_ORDERING_BUILDER',\n CONDITIONAL_FORMATTING = 'CONDITIONAL_FORMATTING',\n CONDITIONAL_FORMATTING_EDIT = 'CONDITIONAL_FORMATTING_EDIT',\n GOTO = 'GOTO',\n}\n\nexport default OptionType;\n","/* eslint-disable jsx-a11y/click-events-have-key-events */\nimport React, { ChangeEvent, Component, ReactElement, RefObject } from 'react';\nimport classNames from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport {\n DragDropContext,\n DraggableLocation,\n DragStart,\n Droppable,\n DropResult,\n} from 'react-beautiful-dnd';\nimport {\n Checkbox,\n DraggableItemList,\n DragUtils,\n SearchInput,\n Tooltip,\n Range,\n RenderItemProps,\n Button,\n} from '@deephaven/components';\nimport { vsTrash, dhSortAlphaDown, dhSortAlphaUp } from '@deephaven/icons';\nimport { TableUtils, SortDirection } from '@deephaven/jsapi-utils';\nimport memoize from 'memoizee';\nimport debounce from 'lodash.debounce';\nimport Log from '@deephaven/log';\nimport { assertNotNull } from '@deephaven/utils';\nimport './RollupRows.scss';\nimport type { Column } from '@deephaven/jsapi-types';\nimport IrisGridModel from '../IrisGridModel';\nimport { ColumnName } from '../CommonTypes';\n\nconst log = Log.module('RollupRows');\nconst DEBOUNCE_SEARCH = 150;\nconst GROUPED_LIST_ID = 'grouped-rollup-rows';\nconst UNGROUPED_LIST_ID = 'ungrouped-rollup-rows';\n\nexport interface UIRollupConfig {\n columns: ColumnName[];\n showConstituents: boolean;\n showNonAggregatedColumns: boolean;\n includeDescriptions: true;\n}\n\ninterface RollupRowsProps {\n model: IrisGridModel;\n onChange: (rollupConfig: UIRollupConfig) => void;\n config: UIRollupConfig | null;\n}\n\ninterface RollupRowsState {\n ungroupedSelectedRanges: Range[];\n columns: ColumnName[];\n groupedSelectedRanges: Range[];\n searchFilter: string;\n showConstituents: boolean;\n showNonAggregatedColumns: boolean;\n dragSource: DraggableLocation | null;\n sort: SortDirection;\n}\n\nclass RollupRows extends Component<RollupRowsProps, RollupRowsState> {\n static SORT = Object.freeze({\n ASCENDING: 'ASC',\n DESCENDING: 'DESC',\n });\n\n static defaultProps = {\n config: null,\n onChange: (): void => undefined,\n };\n\n static renderColumn({\n item,\n isClone,\n selectedCount,\n }: RenderItemProps<Column> & {\n isClone?: boolean;\n selectedCount?: number;\n }): ReactElement {\n const text = item?.name;\n const badgeText =\n isClone !== undefined && isClone ? `${selectedCount}` : undefined;\n const className =\n isClone !== undefined && isClone ? 'item-list-item-clone' : '';\n return DraggableItemList.renderTextItem({ text, badgeText, className });\n }\n\n static addGroupings(\n currentGroupings: string[],\n newGroupings: string[],\n index: number = currentGroupings.length\n ): string[] {\n if (newGroupings == null || newGroupings.length === 0) {\n return currentGroupings;\n }\n\n let insertIndex = index;\n const groupings = currentGroupings.filter((grouping, i) => {\n if (newGroupings.includes(grouping)) {\n if (i < insertIndex) {\n insertIndex -= 1;\n }\n return false;\n }\n return true;\n });\n groupings.splice(insertIndex, 0, ...newGroupings);\n return groupings;\n }\n\n static isGroupable(column: Column): boolean {\n return !TableUtils.isDecimalType(column.type);\n }\n\n constructor(props: RollupRowsProps) {\n super(props);\n\n this.handleDeleteClicked = this.handleDeleteClicked.bind(this);\n this.handleSearchChange = this.handleSearchChange.bind(this);\n this.handleUngroupedSelect = this.handleUngroupedSelect.bind(this);\n this.handleUngroupedSelectionChange = this.handleUngroupedSelectionChange.bind(\n this\n );\n this.handleDragStart = this.handleDragStart.bind(this);\n this.handleDragEnd = this.handleDragEnd.bind(this);\n this.handleGroupedSelectionChange = this.handleGroupedSelectionChange.bind(\n this\n );\n this.handleShowConstituentsChange = this.handleShowConstituentsChange.bind(\n this\n );\n this.handleShowNonAggregatedColumnsChange = this.handleShowNonAggregatedColumnsChange.bind(\n this\n );\n this.handleSortAscending = this.handleSortAscending.bind(this);\n this.handleSortDescending = this.handleSortDescending.bind(this);\n this.renderGroupedItem = this.renderGroupedItem.bind(this);\n\n this.ungroupedList = React.createRef();\n this.groupedList = React.createRef();\n\n const { config } = props;\n const {\n columns = [],\n showConstituents = true,\n showNonAggregatedColumns = true,\n } = config ?? {};\n\n this.state = {\n ungroupedSelectedRanges: [],\n columns,\n groupedSelectedRanges: [],\n searchFilter: '',\n showConstituents,\n showNonAggregatedColumns,\n dragSource: null,\n sort: null,\n };\n }\n\n componentDidUpdate(\n prevProps: RollupRowsProps,\n prevState: RollupRowsState\n ): void {\n const { config } = this.props;\n const { columns, showConstituents, showNonAggregatedColumns } = this.state;\n if (config !== prevProps.config) {\n this.updateFromConfig();\n } else if (\n columns !== prevState.columns ||\n showConstituents !== prevState.showConstituents ||\n showNonAggregatedColumns !== prevState.showNonAggregatedColumns\n ) {\n if (\n config == null ||\n columns !== config.columns ||\n showConstituents !== config.showConstituents ||\n showNonAggregatedColumns !== config.showNonAggregatedColumns\n ) {\n this.sendChange();\n }\n }\n }\n\n componentWillUnmount(): void {\n this.search.cancel();\n }\n\n ungroupedList: RefObject<DraggableItemList<Column>>;\n\n groupedList: RefObject<DraggableItemList<string>>;\n\n handleSearchChange(event: ChangeEvent<HTMLInputElement>): void {\n const searchFilter = event.target.value;\n this.setState({ searchFilter });\n if (!searchFilter) {\n this.search.cancel();\n this.resetSelection();\n return;\n }\n this.search(searchFilter);\n }\n\n handleSortAscending(): void {\n this.setState(({ sort }) => ({\n sort:\n sort === RollupRows.SORT.ASCENDING\n ? null\n : (RollupRows.SORT.ASCENDING as SortDirection),\n }));\n }\n\n handleSortDescending(): void {\n this.setState(({ sort }) => ({\n sort:\n sort === RollupRows.SORT.DESCENDING\n ? null\n : (RollupRows.SORT.DESCENDING as SortDirection),\n }));\n }\n\n resetSelection(): void {\n this.setState({ ungroupedSelectedRanges: [], groupedSelectedRanges: [] });\n }\n\n search = debounce((searchFilter: string) => {\n const columns = this.getSortedUngroupedColumns();\n const selectedRanges = [] as Range[];\n let focusIndex = null;\n for (let i = 0; i < columns.length; i += 1) {\n const column = columns[i];\n if (column.name.toLowerCase().includes(searchFilter.toLowerCase())) {\n if (focusIndex == null) {\n focusIndex = i;\n }\n selectedRanges.push([i, i]);\n }\n }\n assertNotNull(focusIndex);\n this.setState({ ungroupedSelectedRanges: selectedRanges });\n\n if (selectedRanges.length > 0 && this.ungroupedList.current) {\n this.ungroupedList.current.scrollToItem(focusIndex);\n }\n }, DEBOUNCE_SEARCH);\n\n handleDragStart(e: DragStart): void {\n log.debug('handleDragStart', e);\n\n document.documentElement.classList.add('drag-pointer-events-none');\n\n this.setState({ dragSource: e.source });\n }\n\n handleDragEnd(e: DropResult): void {\n log.debug('handleDragEnd', e);\n\n document.documentElement.classList.remove('drag-pointer-events-none');\n\n this.setState({ dragSource: null });\n\n const { destination, source } = e;\n if (destination == null || source == null) {\n return;\n }\n\n // We don't allow dragging within the ungrouped list, so if we're dragging into the ungrouped list,\n // it must have came from the grouped list. Remove those grouped columns.\n if (destination.droppableId === UNGROUPED_LIST_ID) {\n this.setState(({ groupedSelectedRanges, columns }) => {\n const newColumns = [...columns];\n DragUtils.reorder(newColumns, groupedSelectedRanges, [], 0);\n return {\n columns: newColumns,\n ungroupedSelectedRanges: [],\n groupedSelectedRanges: [],\n };\n });\n return;\n }\n\n // Otherwise, it must be dropping into the grouped list, so we just need to check the source\n const isSameList = source.droppableId === GROUPED_LIST_ID;\n let destinationIndex = destination.index;\n if (isSameList && source.index < destination.index) {\n // react-beautiful-dnd adjusts the index when dragging within a list already, however that only supports single selection\n // We need to change it back to the index we actually want it to drop at before adjusting for the removed source index, as\n // we adjust the index based on all the selected ranges, not just the source.index.\n destinationIndex += 1;\n }\n this.setState(\n ({ columns, ungroupedSelectedRanges, groupedSelectedRanges }) => {\n const newColumns = [...columns];\n const sourceItems = isSameList\n ? newColumns\n : this.getSortedUngroupedColumns().map(c => c.name);\n const sourceRanges = isSameList\n ? groupedSelectedRanges\n : ungroupedSelectedRanges;\n const draggedItems = DragUtils.reorder(\n sourceItems,\n sourceRanges,\n newColumns,\n destinationIndex\n );\n\n // Select the newly dropped items\n const insertIndex = isSameList\n ? DragUtils.adjustDestinationIndex(\n destinationIndex,\n groupedSelectedRanges\n )\n : destinationIndex;\n const newSelectedRanges = [\n [insertIndex, insertIndex + draggedItems.length - 1] as Range,\n ];\n return {\n columns: newColumns,\n ungroupedSelectedRanges: [] as Range[],\n groupedSelectedRanges: newSelectedRanges,\n };\n }\n );\n this.resetSelection();\n }\n\n handleUngroupedSelect(itemIndex: number): void {\n log.debug('handleUngroupedSelect');\n\n this.setState(({ columns }) => ({\n columns: RollupRows.addGroupings(columns, [\n this.getSortedUngroupedColumns()[itemIndex].name,\n ]),\n ungroupedSelectedRanges: [],\n groupedSelectedRanges: [],\n }));\n }\n\n handleUngroupedSelectionChange(ungroupedSelectedRanges: Range[]): void {\n log.debug2('handleUngroupedSelectionChange', ungroupedSelectedRanges);\n this.setState(\n ({ ungroupedSelectedRanges: stateUngroupedSelectedRanges }) => {\n if (ungroupedSelectedRanges === stateUngroupedSelectedRanges) {\n return null;\n }\n\n return { ungroupedSelectedRanges, groupedSelectedRanges: [] };\n }\n );\n }\n\n handleGroupedSelectionChange(groupedSelectedRanges: Range[]): void {\n log.debug2('handleGroupedSelectedRanges', groupedSelectedRanges);\n this.setState(({ groupedSelectedRanges: stateGroupedSelectedRanges }) => {\n if (groupedSelectedRanges === stateGroupedSelectedRanges) {\n return null;\n }\n\n return { groupedSelectedRanges, ungroupedSelectedRanges: [] };\n });\n }\n\n handleDeleteClicked(index: number): void {\n this.setState(({ columns }) => {\n const newColumns = columns.slice();\n newColumns.splice(index, 1);\n return { columns: newColumns };\n });\n }\n\n handleShowConstituentsChange(): void {\n this.setState(({ showConstituents }) => ({\n showConstituents: !showConstituents,\n }));\n }\n\n handleShowNonAggregatedColumnsChange(): void {\n this.setState(({ showNonAggregatedColumns }) => ({\n showNonAggregatedColumns: !showNonAggregatedColumns,\n }));\n }\n\n updateFromConfig(): void {\n const { config } = this.props;\n const {\n columns = [],\n showConstituents = true,\n showNonAggregatedColumns = true,\n } = config ?? {};\n this.setState({ columns, showConstituents, showNonAggregatedColumns });\n }\n\n sendChange(): void {\n const { onChange } = this.props;\n const { columns, showConstituents, showNonAggregatedColumns } = this.state;\n onChange({\n columns,\n showConstituents,\n showNonAggregatedColumns,\n } as UIRollupConfig);\n }\n\n getCachedUngroupedColumns = memoize(\n (\n columns: readonly Column[],\n groupedColumns: readonly ColumnName[]\n ): readonly Column[] =>\n columns.filter(\n column =>\n RollupRows.isGroupable(column) &&\n groupedColumns.find(name => name === column.name) == null\n )\n );\n\n getCachedSortedColumns = memoize(\n (columns: readonly Column[], sort?: SortDirection): readonly Column[] =>\n sort == null\n ? [...columns]\n : TableUtils.sortColumns(columns, sort === RollupRows.SORT.ASCENDING)\n );\n\n getUngroupedColumns(): readonly Column[] {\n const { model } = this.props;\n const { columns } = this.state;\n const { originalColumns } = model;\n\n return this.getCachedUngroupedColumns(originalColumns, columns);\n }\n\n getSortedUngroupedColumns(): readonly Column[] {\n const { sort } = this.state;\n const columns = this.getUngroupedColumns();\n return this.getCachedSortedColumns(columns, sort);\n }\n\n renderGroupedItem({\n item,\n itemIndex,\n isClone,\n selectedCount,\n }: RenderItemProps<string> & {\n isClone?: boolean;\n selectedCount?: number;\n }): ReactElement {\n const indent =\n isClone !== undefined && isClone ? '' : '\\u00A0\\u00A0'.repeat(itemIndex);\n const text = `${indent}${item}`;\n const badgeText =\n isClone !== undefined && isClone ? `${selectedCount}` : undefined;\n const className =\n isClone !== undefined && isClone ? 'item-list-item-clone' : '';\n return (\n <>\n {DraggableItemList.renderTextItem({ text, badgeText, className })}\n {(isClone === undefined || !isClone) && (\n <Button\n kind=\"ghost\"\n className=\"btn btn-link btn-link-icon btn-delete-grouping float-right\"\n onClick={() => this.handleDeleteClicked(itemIndex)}\n >\n <FontAwesomeIcon icon={vsTrash} />\n </Button>\n )}\n </>\n );\n }\n\n render(): ReactElement {\n const {\n columns,\n dragSource,\n searchFilter,\n groupedSelectedRanges,\n ungroupedSelectedRanges,\n showConstituents,\n showNonAggregatedColumns,\n sort,\n } = this.state;\n\n const ungroupedColumns = this.getSortedUngroupedColumns();\n let groupListHeight = columns.length * DraggableItemList.DEFAULT_ROW_HEIGHT;\n if (dragSource?.droppableId === UNGROUPED_LIST_ID) {\n groupListHeight += DraggableItemList.DEFAULT_ROW_HEIGHT;\n }\n const ungroupMaxListHeight =\n ungroupedColumns.length * DraggableItemList.DEFAULT_ROW_HEIGHT + 10;\n const ungroupMinListHeight = Math.min(\n 3 * DraggableItemList.DEFAULT_ROW_HEIGHT,\n ungroupMaxListHeight\n );\n\n return (\n <div\n role=\"menu\"\n className={classNames('rollup-rows', {\n 'is-dragging': dragSource != null,\n })}\n tabIndex={0}\n >\n <DragDropContext\n onDragEnd={this.handleDragEnd}\n onDragStart={this.handleDragStart}\n >\n <div className=\"rollup-rows-group-by\">\n <div className=\"section-title\">Group By</div>\n {columns.length === 0 && (\n <Droppable droppableId=\"placeholder\">\n {(provided, snapshot) => (\n <div\n className={classNames('placeholder', 'text-muted', {\n 'is-dragging-from-this': snapshot.draggingFromThisWith,\n 'is-dragging-over': snapshot.isDraggingOver,\n 'is-dropping': snapshot.draggingOverWith,\n })}\n ref={provided.innerRef}\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...provided.droppableProps}\n >\n To create a rollup, drag columns from the list below and\n drop them into this area.\n </div>\n )}\n </Droppable>\n )}\n {columns.length > 0 && (\n <DraggableItemList\n draggingItemClassName=\"rollup-rows-dragging-grouped-item\"\n draggablePrefix={GROUPED_LIST_ID}\n droppableId={GROUPED_LIST_ID}\n itemCount={columns.length}\n items={columns}\n offset={0}\n onSelectionChange={this.handleGroupedSelectionChange}\n ref={this.groupedList}\n renderItem={this.renderGroupedItem}\n selectedRanges={groupedSelectedRanges}\n style={{ height: groupListHeight }}\n isMultiSelect\n />\n )}\n </div>\n <div className=\"rollup-rows-available-columns\">\n <div className=\"section-title\">Available Grouping Columns</div>\n <div className=\"top-menu\">\n <SearchInput\n className=\"w-100\"\n value={searchFilter}\n matchCount={\n searchFilter ? ungroupedSelectedRanges.length : undefined\n }\n placeholder=\"Find column...\"\n onChange={this.handleSearchChange}\n />\n <Button\n kind=\"ghost\"\n className={classNames('btn-link btn-link-icon', {\n active: sort === RollupRows.SORT.ASCENDING,\n })}\n onClick={this.handleSortAscending}\n >\n <FontAwesomeIcon icon={dhSortAlphaDown} />\n <Tooltip>Sort ascending</Tooltip>\n </Button>\n <Button\n kind=\"ghost\"\n className={classNames('btn-link btn-link-icon', {\n active: sort === RollupRows.SORT.DESCENDING,\n })}\n onClick={this.handleSortDescending}\n >\n <FontAwesomeIcon icon={dhSortAlphaUp} />\n <Tooltip>Sort descending</Tooltip>\n </Button>\n </div>\n <DraggableItemList\n className=\"rollup-available-grouping-columns\"\n draggablePrefix={UNGROUPED_LIST_ID}\n droppableId={UNGROUPED_LIST_ID}\n itemCount={ungroupedColumns.length}\n items={ungroupedColumns}\n renderItem={RollupRows.renderColumn}\n offset={0}\n onSelect={this.handleUngroupedSelect}\n onSelectionChange={this.handleUngroupedSelectionChange}\n ref={this.ungroupedList}\n selectedRanges={ungroupedSelectedRanges}\n style={{\n maxHeight: ungroupMaxListHeight,\n minHeight: ungroupMinListHeight,\n }}\n isDropDisabled={dragSource?.droppableId !== GROUPED_LIST_ID}\n isMultiSelect\n />\n <div className=\"bottom-menu\">\n <div className=\"label\">Show:</div>\n <Checkbox\n checked={showConstituents}\n onChange={this.handleShowConstituentsChange}\n >\n Constituents\n </Checkbox>\n <Checkbox\n checked={showNonAggregatedColumns}\n onChange={this.handleShowNonAggregatedColumnsChange}\n >\n Non-Aggregated Columns\n </Checkbox>\n </div>\n </div>\n </DragDropContext>\n </div>\n );\n }\n}\n\nexport default RollupRows;\n","import React, { Component, ReactElement } from 'react';\nimport ClassNames from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport {\n Button,\n Checkbox,\n LoadingSpinner,\n RadioGroup,\n RadioItem,\n} from '@deephaven/components';\nimport {\n GridRange,\n GridUtils,\n ModelSizeMap,\n MoveOperation,\n} from '@deephaven/grid';\nimport { vsWarning } from '@deephaven/icons';\nimport type {\n dh as DhType,\n Table,\n TableViewportSubscription,\n} from '@deephaven/jsapi-types';\nimport { TimeUtils } from '@deephaven/utils';\nimport shortid from 'shortid';\nimport './TableCsvExporter.scss';\nimport Log from '@deephaven/log';\nimport IrisGridModel from '../IrisGridModel';\nimport IrisGridUtils from '../IrisGridUtils';\n\nconst log = Log.module('TableCsvExporter');\ninterface TableCsvExporterProps {\n model: IrisGridModel;\n name: string;\n userColumnWidths: ModelSizeMap;\n movedColumns: readonly MoveOperation[];\n isDownloading: boolean;\n tableDownloadStatus: string;\n tableDownloadProgress: number;\n tableDownloadEstimatedTime: number;\n onDownloadStart: () => void;\n onDownload: (\n fileName: string,\n frozenTable: Table,\n tableSubscription: TableViewportSubscription,\n snapshotRanges: readonly GridRange[],\n modelRanges: readonly GridRange[],\n includeColumnHeaders: boolean,\n useUnformattedValues: boolean\n ) => void;\n onCancel: () => void;\n selectedRanges: readonly GridRange[];\n}\n\ninterface TableCsvExporterState {\n fileName: string;\n\n downloadRowOption: string;\n customizedDownloadRowOption: string;\n customizedDownloadRows: number;\n\n includeColumnHeaders: boolean;\n includeHiddenColumns: boolean;\n useUnformattedValues: boolean;\n\n errorMessage: React.ReactNode;\n id: string;\n}\nclass TableCsvExporter extends Component<\n TableCsvExporterProps,\n TableCsvExporterState\n> {\n static FILENAME_DATE_FORMAT = 'yyyy-MM-dd-HHmmss';\n\n static DOWNLOAD_STATUS = {\n INITIATING: 'INITIATING',\n DOWNLOADING: 'DOWNLOADING',\n FINISHED: 'FINISHED',\n CANCELED: 'CANCELED',\n };\n\n static DOWNLOAD_ROW_OPTIONS = {\n ALL_ROWS: 'ALL_ROWS',\n SELECTED_ROWS: 'SELECTED_ROWS',\n CUSTOMIZED_ROWS: 'CUSTOMIZED_ROWS',\n };\n\n static CUSTOMIZED_ROWS_OPTIONS = {\n FIRST: 'FIRST',\n LAST: 'LAST',\n };\n\n static DEFAULT_DOWNLOAD_ROWS = 100;\n\n static defaultProps = {\n onDownloadStart: (): void => undefined,\n isDownloading: false,\n tableDownloadStatus: '',\n tableDownloadProgress: 0,\n tableDownloadEstimatedTime: null,\n selectedRanges: [],\n };\n\n static getDateString(dh: DhType): string {\n return dh.i18n.DateTimeFormat.format(\n TableCsvExporter.FILENAME_DATE_FORMAT,\n new Date()\n );\n }\n\n constructor(props: TableCsvExporterProps) {\n super(props);\n\n this.handleDownloadClick = this.handleDownloadClick.bind(this);\n this.handleDownloadRowOptionChanged = this.handleDownloadRowOptionChanged.bind(\n this\n );\n this.handleCustomizedDownloadRowOptionChanged = this.handleCustomizedDownloadRowOptionChanged.bind(\n this\n );\n this.handleCustomizedDownloadRowsChanged = this.handleCustomizedDownloadRowsChanged.bind(\n this\n );\n this.handleIncludeColumnHeadersChanged = this.handleIncludeColumnHeadersChanged.bind(\n this\n );\n this.handleIncludeHiddenColumnsChanged = this.handleIncludeHiddenColumnsChanged.bind(\n this\n );\n this.handleUseUnformattedValuesChanged = this.handleUseUnformattedValuesChanged.bind(\n this\n );\n\n const { model, name } = props;\n this.state = {\n fileName: `${name}-${TableCsvExporter.getDateString(model.dh)}.csv`,\n\n downloadRowOption: TableCsvExporter.DOWNLOAD_ROW_OPTIONS.ALL_ROWS,\n customizedDownloadRowOption:\n TableCsvExporter.CUSTOMIZED_ROWS_OPTIONS.FIRST,\n customizedDownloadRows: TableCsvExporter.DEFAULT_DOWNLOAD_ROWS,\n\n includeColumnHeaders: true,\n includeHiddenColumns: false,\n useUnformattedValues: false,\n\n errorMessage: null,\n id: shortid.generate(),\n };\n }\n\n getSnapshotRanges(): GridRange[] {\n const { model, selectedRanges } = this.props;\n const {\n downloadRowOption,\n customizedDownloadRowOption,\n customizedDownloadRows,\n } = this.state;\n const { rowCount, columnCount } = model;\n let snapshotRanges = [] as GridRange[];\n switch (downloadRowOption) {\n case TableCsvExporter.DOWNLOAD_ROW_OPTIONS.ALL_ROWS:\n snapshotRanges.push(new GridRange(0, 0, columnCount - 1, rowCount - 1));\n break;\n case TableCsvExporter.DOWNLOAD_ROW_OPTIONS.SELECTED_ROWS:\n snapshotRanges = selectedRanges\n .map(range => ({\n ...range,\n startColumn: 0,\n endColumn: columnCount - 1,\n }))\n .sort((rangeA, rangeB) => {\n if (rangeA.startRow != null && rangeB.startRow != null) {\n return rangeA.startRow - rangeB.startRow;\n }\n return 0;\n }) as GridRange[];\n break;\n case TableCsvExporter.DOWNLOAD_ROW_OPTIONS.CUSTOMIZED_ROWS:\n switch (customizedDownloadRowOption) {\n case TableCsvExporter.CUSTOMIZED_ROWS_OPTIONS.FIRST:\n snapshotRanges.push(\n new GridRange(\n 0,\n 0,\n columnCount - 1,\n Math.min(customizedDownloadRows - 1, rowCount - 1)\n )\n );\n break;\n case TableCsvExporter.CUSTOMIZED_ROWS_OPTIONS.LAST:\n snapshotRanges.push(\n new GridRange(\n 0,\n Math.max(0, rowCount - customizedDownloadRows),\n columnCount - 1,\n rowCount - 1\n )\n );\n break;\n default:\n break;\n }\n break;\n default:\n break;\n }\n return snapshotRanges;\n }\n\n getModelRanges(ranges: readonly GridRange[]): GridRange[] {\n const { userColumnWidths, movedColumns } = this.props;\n const { includeHiddenColumns } = this.state;\n const hiddenColumns = IrisGridUtils.getHiddenColumns(userColumnWidths);\n let modelRanges = GridUtils.getModelRanges(ranges, movedColumns);\n if (!includeHiddenColumns && hiddenColumns.length > 0) {\n const subtractRanges = hiddenColumns.map(GridRange.makeColumn);\n modelRanges = GridRange.subtractRangesFromRanges(\n modelRanges,\n subtractRanges\n );\n }\n return modelRanges;\n }\n\n resetDownloadState(): void {\n this.setState({ errorMessage: null });\n }\n\n async handleDownloadClick(): Promise<void> {\n const {\n model,\n isDownloading,\n onDownloadStart,\n onDownload,\n onCancel,\n } = this.props;\n const { fileName, includeColumnHeaders, useUnformattedValues } = this.state;\n\n if (isDownloading) {\n onCancel();\n return;\n }\n\n this.resetDownloadState();\n\n const snapshotRanges = this.getSnapshotRanges();\n const modelRanges = this.getModelRanges(snapshotRanges);\n if (this.validateOptionInput()) {\n onDownloadStart();\n try {\n const frozenTable = await model.export();\n const tableSubscription = frozenTable.setViewport(0, 0);\n await tableSubscription.getViewportData();\n onDownload(\n fileName,\n frozenTable,\n tableSubscription,\n snapshotRanges,\n modelRanges,\n includeColumnHeaders,\n useUnformattedValues\n );\n } catch (error) {\n log.error('CSV download failed', error);\n\n this.setState({\n errorMessage: (\n <p>\n <FontAwesomeIcon icon={vsWarning} /> {`${error}`}\n </p>\n ),\n });\n onCancel();\n }\n }\n }\n\n handleDownloadRowOptionChanged(\n event: React.ChangeEvent<HTMLInputElement>\n ): void {\n this.setState({ downloadRowOption: event.target.value });\n }\n\n handleCustomizedDownloadRowOptionChanged(\n event: React.ChangeEvent<HTMLSelectElement>\n ): void {\n this.setState({ customizedDownloadRowOption: event.target.value });\n }\n\n handleCustomizedDownloadRowsChanged(\n event: React.ChangeEvent<HTMLInputElement>\n ): void {\n this.setState({ customizedDownloadRows: parseInt(event.target.value, 10) });\n }\n\n handleIncludeColumnHeadersChanged(): void {\n this.setState(({ includeColumnHeaders }) => ({\n includeColumnHeaders: !includeColumnHeaders,\n }));\n }\n\n handleIncludeHiddenColumnsChanged(): void {\n this.setState(({ includeHiddenColumns }) => ({\n includeHiddenColumns: !includeHiddenColumns,\n }));\n }\n\n handleUseUnformattedValuesChanged(): void {\n this.setState(({ useUnformattedValues }) => ({\n useUnformattedValues: !useUnformattedValues,\n }));\n }\n\n validateOptionInput(): boolean {\n const { selectedRanges } = this.props;\n const { downloadRowOption, customizedDownloadRows } = this.state;\n\n if (\n downloadRowOption ===\n TableCsvExporter.DOWNLOAD_ROW_OPTIONS.SELECTED_ROWS &&\n selectedRanges.length === 0\n ) {\n this.setState({\n errorMessage: (\n <p>\n <FontAwesomeIcon icon={vsWarning} /> No rows selected. Please select\n some rows in the table.\n </p>\n ),\n });\n return false;\n }\n\n if (\n downloadRowOption ===\n TableCsvExporter.DOWNLOAD_ROW_OPTIONS.CUSTOMIZED_ROWS &&\n customizedDownloadRows <= 0\n ) {\n this.setState({\n errorMessage: (\n <p>\n <FontAwesomeIcon icon={vsWarning} /> Number of rows to output must\n be greater than 0\n </p>\n ),\n });\n return false;\n }\n return true;\n }\n\n render(): ReactElement {\n const {\n model,\n isDownloading,\n tableDownloadProgress,\n tableDownloadEstimatedTime,\n selectedRanges,\n tableDownloadStatus,\n } = this.props;\n const {\n fileName,\n downloadRowOption,\n customizedDownloadRowOption,\n customizedDownloadRows,\n includeColumnHeaders,\n includeHiddenColumns,\n useUnformattedValues,\n errorMessage,\n id,\n } = this.state;\n const { rowCount } = model;\n return (\n <div className=\"table-csv-exporter\">\n <div className=\"section-title\">Download Rows</div>\n <div className=\"form-group\">\n <RadioGroup\n onChange={this.handleDownloadRowOptionChanged}\n value={downloadRowOption}\n disabled={isDownloading}\n >\n <RadioItem\n value={TableCsvExporter.DOWNLOAD_ROW_OPTIONS.ALL_ROWS}\n data-testid=\"radio-csv-exporter-download-all\"\n >\n All Rows\n <span className=\"text-muted ml-2\">\n {`(${rowCount\n .toString()\n .replace(/(\\d)(?=(\\d{3})+(?!\\d))/g, '$1,')} rows)`}\n </span>\n </RadioItem>\n <RadioItem\n value={TableCsvExporter.DOWNLOAD_ROW_OPTIONS.SELECTED_ROWS}\n data-testid=\"radio-csv-exporter-only-selected\"\n >\n Only Selected Rows\n <span className=\"text-muted ml-2\">\n {selectedRanges.length > 0\n ? `(${GridRange.rowCount(selectedRanges)\n .toString()\n .replace(/(\\d)(?=(\\d{3})+(?!\\d))/g, '$1,')} rows)`\n : null}\n </span>\n </RadioItem>\n <RadioItem\n value={TableCsvExporter.DOWNLOAD_ROW_OPTIONS.CUSTOMIZED_ROWS}\n data-testid=\"radio-csv-exporter-customized-rows\"\n >\n <div\n className=\"radio-input-row\"\n role=\"presentation\"\n onClick={() => {\n this.setState({\n downloadRowOption:\n TableCsvExporter.DOWNLOAD_ROW_OPTIONS.CUSTOMIZED_ROWS,\n });\n }}\n >\n <select\n value={customizedDownloadRowOption}\n data-testid=\"select-csv-exporter-customized-rows\"\n className=\"custom-select\"\n disabled={isDownloading}\n onChange={this.handleCustomizedDownloadRowOptionChanged}\n >\n <option value=\"FIRST\">First</option>\n <option value=\"LAST\">Last</option>\n </select>\n <input\n type=\"number\"\n className=\"form-control\"\n id={`customizedRows-${id}`}\n data-testid=\"input-csv-exporter-customized-rows\"\n name={`customizedRows-${id}`}\n placeholder=\"100\"\n value={customizedDownloadRows}\n disabled={isDownloading}\n onChange={this.handleCustomizedDownloadRowsChanged}\n />\n <div>Rows</div>\n </div>\n </RadioItem>\n </RadioGroup>\n </div>\n <div className=\"form-group\">\n <label htmlFor={`customizedRows-${id}`}>File Name</label>\n <input\n type=\"text\"\n className=\"form-control\"\n id={`filename-${id}`}\n data-testid=\"input-csv-exporter-file-name\"\n name={`filename-${id}`}\n value={fileName}\n onChange={event => {\n this.setState({ fileName: event.target.value });\n }}\n disabled={isDownloading}\n />\n </div>\n <div className=\"checkbox-options\">\n <Checkbox\n checked={includeColumnHeaders}\n onChange={this.handleIncludeColumnHeadersChanged}\n >\n Include column headers\n </Checkbox>\n <Checkbox\n checked={includeHiddenColumns}\n onChange={this.handleIncludeHiddenColumnsChanged}\n >\n Include hidden columns\n </Checkbox>\n <Checkbox\n checked={useUnformattedValues}\n onChange={this.handleUseUnformattedValuesChanged}\n >\n Use unformatted values\n </Checkbox>\n </div>\n <div className=\"section-footer flex-column\">\n {errorMessage != null && (\n <div className=\"error-message\">{errorMessage}</div>\n )}\n {tableDownloadStatus && (\n <div className=\"download-status\">\n {(tableDownloadStatus ===\n TableCsvExporter.DOWNLOAD_STATUS.DOWNLOADING ||\n tableDownloadStatus ===\n TableCsvExporter.DOWNLOAD_STATUS.INITIATING) && (\n <>\n {tableDownloadStatus ===\n TableCsvExporter.DOWNLOAD_STATUS.INITIATING && (\n <div className=\"text-muted\">Starting Download...</div>\n )}\n {tableDownloadStatus ===\n TableCsvExporter.DOWNLOAD_STATUS.DOWNLOADING && (\n <div className=\"text-muted d-flex justify-content-between\">\n <span>\n {tableDownloadEstimatedTime ||\n tableDownloadEstimatedTime === 0\n ? `Estimated time: ${TimeUtils.formatElapsedTime(\n tableDownloadEstimatedTime\n )}`\n : null}\n </span>\n <span>{`${tableDownloadProgress}%`}</span>\n </div>\n )}\n </>\n )}\n {tableDownloadStatus ===\n TableCsvExporter.DOWNLOAD_STATUS.FINISHED && (\n <div className=\"text-muted text-right\">Download Completed</div>\n )}\n {tableDownloadStatus ===\n TableCsvExporter.DOWNLOAD_STATUS.CANCELED && (\n <div className=\"text-muted\">Download Canceled</div>\n )}\n\n {(tableDownloadStatus ===\n TableCsvExporter.DOWNLOAD_STATUS.DOWNLOADING ||\n tableDownloadStatus ===\n TableCsvExporter.DOWNLOAD_STATUS.INITIATING) && (\n <div className=\"progress\">\n <div\n className=\"progress-bar progress-bar-striped progress-bar-animated\"\n style={{ width: `${tableDownloadProgress}%` }}\n />\n </div>\n )}\n {tableDownloadStatus ===\n TableCsvExporter.DOWNLOAD_STATUS.FINISHED && (\n <div className=\"progress\">\n <div\n className=\"progress-bar bg-success\"\n style={{ width: `${tableDownloadProgress}%` }}\n />\n </div>\n )}\n </div>\n )}\n <Button\n kind=\"primary\"\n data-testid=\"btn-csv-exporter-download\"\n className={ClassNames('btn-downloading', {\n 'btn-spinner btn-cancelable': isDownloading,\n })}\n onClick={this.handleDownloadClick}\n >\n {isDownloading && (\n <span>\n <LoadingSpinner />\n <span className=\"btn-normal-content\">Downloading</span>\n <span className=\"btn-hover-content\">Cancel</span>\n </span>\n )}\n {!isDownloading && 'Download'}\n </Button>\n </div>\n </div>\n );\n }\n}\n\nexport default TableCsvExporter;\n","import { PureComponent } from 'react';\nimport type {\n Column,\n dh as DhType,\n DateWrapper,\n Table,\n TableData,\n TableViewportSubscription,\n UpdateEventData,\n} from '@deephaven/jsapi-types';\nimport Log from '@deephaven/log';\nimport { GridRange, GridRangeIndex, memoizeClear } from '@deephaven/grid';\nimport { Formatter, FormatterUtils, TableUtils } from '@deephaven/jsapi-utils';\nimport {\n CancelablePromise,\n PromiseUtils,\n assertNotNull,\n} from '@deephaven/utils';\nimport IrisGridUtils from '../IrisGridUtils';\n\nconst log = Log.module('TableSaver');\n\nconst UNFORMATTED_DATE_PATTERN = `yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS z`;\n\ninterface TableSaverProps {\n dh: DhType;\n getDownloadWorker: () => Promise<ServiceWorker>;\n isDownloading: boolean;\n onDownloadCompleted: () => void;\n onDownloadCanceled: () => void;\n onDownloadProgressUpdate: (\n progress: number,\n estimatedTime: number | null\n ) => void;\n formatter: Formatter;\n}\n\nfunction isUpdateEventData(data: TableData): data is UpdateEventData {\n return (data as UpdateEventData).added !== undefined;\n}\n\nfunction assertIsUpdateEventData(\n data: TableData\n): asserts data is UpdateEventData {\n if (!isUpdateEventData(data)) {\n throw new Error('event is not UpdateEventData');\n }\n}\n\nexport default class TableSaver extends PureComponent<\n TableSaverProps,\n Record<string, never>\n> {\n static DOWNLOAD_CELL_CHUNK = 6000;\n\n static SNAPSHOT_BUFFER_SIZE = 5;\n\n static STREAM_TIMEOUT = 8000;\n\n static SNAPSHOT_HANDLER_TIMEOUT = 5;\n\n static defaultProps = {\n getDownloadWorker: (): Promise<never> =>\n Promise.reject(new Error('Download worker not provided')),\n isDownloading: false,\n onDownloadCompleted: (): void => undefined,\n onDownloadCanceled: (): void => undefined,\n onDownloadProgressUpdate: (): void => undefined,\n };\n\n static csvEscapeString(str: string): string {\n return `\"${str.replace(/\"/g, '\"\"')}\"`;\n }\n\n constructor(props: TableSaverProps) {\n super(props);\n\n this.handlePortMessage = this.handlePortMessage.bind(this);\n this.handleSnapshotResolved = this.handleSnapshotResolved.bind(this);\n this.handleDownloadTimeout = this.handleDownloadTimeout.bind(this);\n\n this.state = {};\n\n this.gridRanges = [];\n this.gridRangeCounter = 0;\n this.rangedSnapshotsTotal = [];\n this.rangedSnapshotCounter = 0;\n\n this.includeColumnHeaders = true;\n this.useUnformattedValues = false;\n\n this.snapshotsTotal = 0;\n this.snapshotCounter = 0;\n this.snapshotsBuffer = new Map();\n\n this.currentSnapshotIndex = 0;\n this.snapshotPending = 0;\n this.cancelableSnapshots = [];\n\n // Due to an open issue in Chromium, readableStream.cancel() is never called when a user cancel the stream from Chromium's UI and the stream goes on even it's canceled.\n // Instead, we monitor the pull() behavior from the readableStream called when the stream wants more data to write.\n // If the stream doesn't pull for long enough time, chances are the stream is already canceled, so we stop the stream.\n // Issue ticket on Chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=638494\n\n this.iframes = [];\n\n this.useBlobFallback = false;\n }\n\n componentDidMount(): void {\n const { getDownloadWorker } = this.props;\n getDownloadWorker()\n .then(sw => {\n log.info('found active service worker');\n this.sw = sw;\n this.sw.postMessage('ping'); // just to activate the service worker\n })\n .catch(error => {\n // if service worker is not available, use blob as fallback to download table csv\n log.warn('Download csv is not optimized.', error);\n this.useBlobFallback = true;\n });\n }\n\n componentWillUnmount(): void {\n if (this.iframes.length > 0) {\n this.iframes.forEach(iframe => {\n iframe.remove();\n });\n }\n if (this.streamTimeout) clearTimeout(this.streamTimeout);\n if (this.snapshotHandlerTimeout) clearTimeout(this.snapshotHandlerTimeout);\n }\n\n sw?: ServiceWorker;\n\n port?: MessagePort;\n\n fileWriter?: WritableStreamDefaultWriter<unknown>;\n\n table?: Table;\n\n tableSubscription?: TableViewportSubscription;\n\n columns?: readonly Column[];\n\n fileName?: string;\n\n includeColumnHeaders: boolean;\n\n useUnformattedValues: boolean;\n\n chunkRows?: number;\n\n gridRanges: readonly GridRange[];\n\n gridRangeCounter?: number;\n\n rangedSnapshotsTotal: readonly number[];\n\n rangedSnapshotCounter?: number;\n\n snapshotsTotal: number;\n\n snapshotCounter: number;\n\n snapshotsBuffer: Map<number, UpdateEventData>;\n\n currentSnapshotIndex: number;\n\n snapshotPending: number;\n\n cancelableSnapshots: (CancelablePromise<unknown> | null)[];\n\n // Due to an open issue in Chromium, readableStream.cancel() is never called when a user cancel the stream from Chromium's UI and the stream goes on even it's canceled.\n // Instead, we monitor the pull() behavior from the readableStream called when the stream wants more data to write.\n // If the stream doesn't pull for long enough time, chances are the stream is already canceled, so we stop the stream.\n // Issue ticket on Chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=638494\n streamTimeout?: ReturnType<typeof setTimeout>;\n\n snapshotHandlerTimeout?: ReturnType<typeof setTimeout>;\n\n downloadStartTime?: number;\n\n iframes: HTMLIFrameElement[];\n\n useBlobFallback: boolean;\n\n getCachedCustomColumnFormatFlag = memoizeClear(\n FormatterUtils.isCustomColumnFormatDefined,\n { max: 10000 }\n );\n\n createWriterStream(\n port: MessagePort\n ): WritableStream<{\n rows?: string | undefined;\n header?: string | undefined;\n }> {\n // use blob fall back if it's safari\n const useBlob = this.useBlobFallback;\n const chunks = [] as BlobPart[];\n let encode: ((input?: string) => Uint8Array) | null = null;\n if (useBlob) {\n encode = TextEncoder.prototype.encode.bind(new TextEncoder());\n }\n const { fileName } = this;\n\n const streamConfig = {} as UnderlyingSink<{\n rows?: string | undefined;\n header?: string | undefined;\n }>;\n if (useBlob) {\n streamConfig.write = (chunk: { rows?: string; header?: string }) => {\n assertNotNull(encode);\n if (chunk.header !== undefined) {\n chunks.push(encode(chunk.header));\n }\n if (chunk.rows !== undefined) {\n chunks.push(encode(chunk.rows));\n }\n };\n streamConfig.close = () => {\n assertNotNull(fileName);\n const blob = new Blob(chunks, {\n type: 'application/octet-stream; charset=utf-8',\n });\n const link = document.createElement('a');\n link.href = URL.createObjectURL(blob);\n link.download = fileName;\n link.click();\n };\n streamConfig.abort = () => {\n port.postMessage({ cancel: true });\n port.close();\n };\n } else {\n streamConfig.write = (chunk: unknown) => {\n port.postMessage(chunk);\n };\n streamConfig.close = () => {\n port.postMessage({ end: true });\n port.close();\n };\n streamConfig.abort = () => {\n port.postMessage({ cancel: true });\n port.close();\n };\n }\n\n return new WritableStream(streamConfig);\n }\n\n startDownload(\n fileName: string,\n frozenTable: Table,\n tableSubscription: TableViewportSubscription,\n snapshotRanges: readonly GridRange[],\n modelRanges: readonly GridRange[],\n includeColumnHeaders: boolean,\n useUnformattedValues: boolean\n ): void {\n // don't trigger another download when a download is ongoing\n const { isDownloading } = this.props;\n if (isDownloading) {\n return;\n }\n\n this.downloadStartTime = Date.now();\n log.info(`start downloading ${fileName}`);\n\n this.table = frozenTable;\n this.columns = IrisGridUtils.columnsFromRanges(\n modelRanges,\n frozenTable.columns\n );\n this.tableSubscription = tableSubscription;\n this.gridRanges = snapshotRanges;\n this.includeColumnHeaders = includeColumnHeaders;\n this.useUnformattedValues = useUnformattedValues;\n\n // Make filename RFC5987 compatible\n const encodedFileName = encodeURIComponent(fileName.replace(/\\//g, ':'))\n .replace(/['()]/g, escape)\n .replace(/\\*/g, '%2A');\n\n const messageChannel = new MessageChannel();\n this.port = messageChannel.port1;\n this.fileName = fileName;\n this.fileWriter = this.createWriterStream(this.port).getWriter();\n\n // if the browser doesn't support stream or there's no active service worker, use blobs for table download\n if (this.useBlobFallback) {\n this.writeCsvTable(includeColumnHeaders);\n return;\n }\n\n if (this.sw) {\n // send file name and port to service worker\n this.sw.postMessage({ encodedFileName }, [messageChannel.port2]);\n }\n this.port.onmessage = this.handlePortMessage;\n }\n\n finishDownload(): void {\n if (this.table) {\n this.table.close();\n }\n if (this.tableSubscription) {\n this.tableSubscription.close();\n }\n if (this.fileWriter) {\n this.fileWriter.close();\n }\n\n const { onDownloadCompleted } = this.props;\n onDownloadCompleted();\n this.resetTableSaver();\n\n if (this.downloadStartTime !== undefined) {\n log.info(\n `download finished, total elapsed time ${\n (Date.now() - this.downloadStartTime) / 1000\n } seconds`\n );\n }\n }\n\n cancelDownload(): void {\n if (this.table) {\n this.table.close();\n }\n if (this.tableSubscription) {\n this.tableSubscription.close();\n }\n if (this.fileWriter) {\n this.fileWriter.abort();\n }\n\n this.cancelableSnapshots.forEach(cancelable => {\n if (cancelable) {\n cancelable.catch(() => null);\n cancelable.cancel();\n }\n });\n const { onDownloadCanceled } = this.props;\n onDownloadCanceled();\n this.resetTableSaver();\n }\n\n resetTableSaver(): void {\n this.table = undefined;\n this.tableSubscription = undefined;\n this.columns = undefined;\n this.chunkRows = undefined;\n\n this.gridRanges = [];\n this.gridRangeCounter = 0;\n this.rangedSnapshotsTotal = [];\n this.rangedSnapshotCounter = 0;\n\n this.includeColumnHeaders = true;\n this.useUnformattedValues = false;\n\n this.snapshotsTotal = 0;\n this.snapshotCounter = 0;\n this.snapshotsBuffer = new Map();\n\n this.currentSnapshotIndex = 0;\n this.snapshotPending = 0;\n this.cancelableSnapshots = [];\n\n if (this.streamTimeout != null) {\n clearTimeout(this.streamTimeout);\n }\n\n if (this.snapshotHandlerTimeout != null) {\n clearTimeout(this.snapshotHandlerTimeout);\n }\n this.streamTimeout = undefined;\n this.snapshotHandlerTimeout = undefined;\n }\n\n handleDownloadTimeout(): void {\n log.info('download canceled');\n this.cancelDownload();\n }\n\n writeTableHeader(): void {\n let headerString = '';\n if (this.columns) {\n for (let i = 0; i < this.columns.length; i += 1) {\n headerString += this.columns[i].name;\n headerString += i === this.columns.length - 1 ? '\\n' : ',';\n }\n }\n this.fileWriter?.write({ header: headerString }).then(() => null);\n }\n\n startWriteTableBody(): void {\n if (this.columns && this.gridRanges != null) {\n this.chunkRows = Math.floor(\n TableSaver.DOWNLOAD_CELL_CHUNK / this.columns.length\n );\n\n this.rangedSnapshotsTotal = this.gridRanges.map((range: GridRange) => {\n assertNotNull(range.endRow);\n assertNotNull(range.startRow);\n assertNotNull(this.chunkRows);\n\n return Math.ceil((range.endRow - range.startRow + 1) / this.chunkRows);\n });\n this.snapshotsTotal = this.rangedSnapshotsTotal.reduce(\n (total: number, snapshotCount: number) => total + snapshotCount\n );\n\n log.info(`start writing table, total snapshots: `, this.snapshotsTotal);\n\n this.makeSnapshot(\n Math.min(TableSaver.SNAPSHOT_BUFFER_SIZE, this.snapshotsTotal)\n );\n }\n }\n\n writeCsvTable(includeColumnHeaders: boolean): void {\n if (includeColumnHeaders) {\n this.writeTableHeader();\n }\n this.startWriteTableBody();\n }\n\n writeSnapshot(\n snapshotIndex: number,\n snapshotStartRow: GridRangeIndex,\n snapshotEndRow: GridRangeIndex\n ): void {\n if (this.currentSnapshotIndex === snapshotIndex && this.fileWriter) {\n while (this.snapshotsBuffer.has(this.currentSnapshotIndex)) {\n const n = this.snapshotsBuffer.get(this.currentSnapshotIndex);\n assertNotNull(n);\n this.fileWriter.write({\n rows: this.convertSnapshotIntoCsv(n),\n });\n this.snapshotsBuffer.delete(this.currentSnapshotIndex);\n this.currentSnapshotIndex += 1;\n\n this.updateDownloadProgress(snapshotIndex);\n }\n if (\n this.snapshotsTotal &&\n this.currentSnapshotIndex >= this.snapshotsTotal\n ) {\n this.finishDownload();\n return;\n }\n }\n\n if (\n this.snapshotCounter &&\n this.snapshotsTotal &&\n this.snapshotCounter < this.snapshotsTotal\n ) {\n log.debug2(\n `\n current range index: ${this.gridRangeCounter}, \n snapshotIndexCounter: ${this.snapshotCounter}, \n currentRangedSnapshotIndex : ${this.rangedSnapshotCounter}, \n snapshotpending: ${this.snapshotPending}, \n buffered ${this.snapshotsBuffer.size}\n making ${Math.min(\n TableSaver.SNAPSHOT_BUFFER_SIZE -\n this.snapshotsBuffer.size -\n this.snapshotPending,\n this.snapshotsTotal - this.snapshotCounter\n )} more snapshots\n `\n );\n this.makeSnapshot(\n Math.min(\n TableSaver.SNAPSHOT_BUFFER_SIZE -\n this.snapshotsBuffer.size -\n this.snapshotPending,\n this.snapshotsTotal - this.snapshotCounter\n )\n );\n }\n }\n\n updateDownloadProgress(snapshotIndex: GridRangeIndex): void {\n if (\n snapshotIndex != null &&\n this.snapshotsTotal != null &&\n this.downloadStartTime != null\n ) {\n const { onDownloadProgressUpdate } = this.props;\n const downloadProgress = Math.floor(\n (snapshotIndex * 100) / this.snapshotsTotal\n );\n const estimateTime =\n snapshotIndex > 1\n ? Math.floor(\n ((Date.now() - this.downloadStartTime) *\n (this.snapshotsTotal - snapshotIndex)) /\n snapshotIndex /\n 1000\n )\n : null;\n\n onDownloadProgressUpdate(downloadProgress, estimateTime);\n }\n }\n\n convertSnapshotIntoCsv(snapshot: UpdateEventData): string {\n let csvString = '';\n const snapshotIterator = snapshot.added.iterator();\n const { dh, formatter } = this.props;\n\n const rows = [];\n while (snapshotIterator.hasNext()) {\n rows.push(snapshotIterator.next().value);\n }\n\n assertNotNull(this.columns);\n\n const { useUnformattedValues } = this;\n for (let i = 0; i < rows.length; i += 1) {\n const rowIdx = rows[i];\n for (let j = 0; j < this.columns.length; j += 1) {\n const { type, name } = this.columns[j];\n let cellData = null;\n if (useUnformattedValues) {\n let value = snapshot.getData(rowIdx, this.columns[j]) ?? '';\n if (value !== '' && TableUtils.isDateType(type)) {\n // value is just a long value, we should return the value formatted as a full date string\n value = dh.i18n.DateTimeFormat.format(\n UNFORMATTED_DATE_PATTERN,\n value as number | Date | DateWrapper,\n dh.i18n.TimeZone.getTimeZone(formatter.timeZone)\n );\n }\n cellData = value.toString();\n } else {\n const hasCustomColumnFormat = this.getCachedCustomColumnFormatFlag(\n formatter,\n name,\n type\n );\n let formatOverride = null;\n if (!hasCustomColumnFormat) {\n const cellFormat = snapshot.getFormat(rowIdx, this.columns[j]);\n formatOverride =\n cellFormat?.formatString != null ? cellFormat : null;\n }\n if (formatOverride) {\n cellData = formatter.getFormattedString(\n snapshot.getData(rowIdx, this.columns[j]),\n type,\n name,\n formatOverride\n );\n } else {\n cellData = formatter.getFormattedString(\n snapshot.getData(rowIdx, this.columns[j]),\n type,\n name\n );\n }\n }\n csvString += TableSaver.csvEscapeString(cellData);\n csvString += j === this.columns.length - 1 ? '\\n' : ',';\n }\n }\n\n return csvString;\n }\n\n makeSnapshot(n: number): void {\n if (n <= 0) {\n return;\n }\n const { dh } = this.props;\n assertNotNull(this.gridRangeCounter);\n let i = 0;\n let currentGridRange = this.gridRanges[this.gridRangeCounter];\n\n assertNotNull(this.tableSubscription);\n assertNotNull(this.columns);\n while (i < n) {\n assertNotNull(currentGridRange);\n assertNotNull(currentGridRange.startRow);\n assertNotNull(currentGridRange.endRow);\n assertNotNull(this.rangedSnapshotCounter);\n assertNotNull(this.chunkRows);\n const snapshotStartRow =\n currentGridRange.startRow + this.rangedSnapshotCounter * this.chunkRows;\n const snapshotEndRow = Math.min(\n snapshotStartRow + this.chunkRows - 1,\n currentGridRange.endRow\n );\n\n const snapshotIndex = this.snapshotCounter;\n this.cancelableSnapshots.push(\n PromiseUtils.makeCancelable(\n this.tableSubscription\n .snapshot(\n dh.RangeSet.ofRange(snapshotStartRow, snapshotEndRow),\n this.columns\n )\n .then(snapshot => {\n assertIsUpdateEventData(snapshot);\n this.handleSnapshotResolved(\n snapshot,\n snapshotIndex,\n snapshotStartRow,\n snapshotEndRow\n );\n\n return snapshotIndex;\n })\n .catch(err => {\n log.error(err);\n }),\n val => {\n log.info(`snapshot ${val} has been canceled`);\n }\n )\n );\n\n this.rangedSnapshotCounter += 1;\n this.snapshotCounter += 1;\n this.snapshotPending += 1;\n\n if (\n this.rangedSnapshotCounter >=\n this.rangedSnapshotsTotal[this.gridRangeCounter]\n ) {\n this.gridRangeCounter += 1;\n this.rangedSnapshotCounter = 0;\n currentGridRange = this.gridRanges[this.gridRangeCounter];\n }\n i += 1;\n }\n }\n\n handlePortMessage({\n data,\n }: MessageEvent<{\n download: unknown;\n readableStreamPulling: unknown;\n }>): void {\n const { download, readableStreamPulling } = data;\n if (this.useBlobFallback) {\n return;\n }\n if (download != null) {\n const { includeColumnHeaders } = this;\n this.makeIframe(`${download}`);\n this.writeCsvTable(includeColumnHeaders);\n }\n if (readableStreamPulling != null) {\n if (!this.useBlobFallback) {\n if (this.streamTimeout != null) {\n clearTimeout(this.streamTimeout);\n }\n this.streamTimeout = setTimeout(\n this.handleDownloadTimeout,\n TableSaver.STREAM_TIMEOUT\n );\n }\n }\n }\n\n handleSnapshotResolved(\n snapshot: UpdateEventData,\n snapshotIndex: number,\n snapshotStartRow: GridRangeIndex,\n snapshotEndRow: GridRangeIndex\n ): void {\n // use time out to break writeSnapshot into an individual task in browser with timeout, so there's window for the browser to update table in needed.\n this.snapshotHandlerTimeout = setTimeout(() => {\n this.snapshotsBuffer.set(snapshotIndex, snapshot);\n this.snapshotPending -= 1;\n this.writeSnapshot(snapshotIndex, snapshotStartRow, snapshotEndRow);\n this.cancelableSnapshots[snapshotIndex] = null;\n }, TableSaver.SNAPSHOT_HANDLER_TIMEOUT);\n }\n\n makeIframe(src: string): void {\n // make a return value and make it static method\n const iframe = document.createElement('iframe');\n iframe.hidden = true;\n iframe.src = `download/${src}`;\n iframe.name = 'iframe';\n document.body.appendChild(iframe);\n this.iframes.push(iframe);\n }\n\n render(): null {\n return null;\n }\n}\n","import React, { useEffect, useRef, useState, useCallback } from 'react';\nimport classNames from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { Button, ThemeExport } from '@deephaven/components';\nimport {\n dhSquareFilled,\n vsCheck,\n vsChromeClose,\n vsEdit,\n vsPaintcan,\n vsTrash,\n} from '@deephaven/icons';\nimport type ColumnHeaderGroup from '../../ColumnHeaderGroup';\nimport './VisibilityOrderingGroup.scss';\n\ninterface VisibilityOrderingGroupProps {\n group: ColumnHeaderGroup;\n onDelete(group: ColumnHeaderGroup): void;\n onColorChange(group: ColumnHeaderGroup, color: string | undefined): void;\n onNameChange(group: ColumnHeaderGroup, name: string): void;\n validateName(name: string): string;\n}\n\nexport default function VisibilityOrderingGroup(\n props: VisibilityOrderingGroupProps\n): JSX.Element {\n const { group, onDelete, onColorChange, onNameChange, validateName } = props;\n const { isNew } = group;\n const groupRef = useRef(group);\n const nameInputRef = useRef<HTMLInputElement>(null);\n const colorInputRef = useRef<HTMLInputElement>(null);\n const [isColorInputOpen, setIsColorInputOpen] = useState(false);\n const [name, setName] = useState(isNew ? '' : group.name);\n const [isEditing, setIsEditing] = useState(isNew);\n const [shouldValidate, setShouldValidate] = useState(false);\n const nameValidationError = name !== group.name ? validateName(name) : '';\n const isValid = (isNew && !shouldValidate) || nameValidationError === '';\n const colorInputBlurHandler = useCallback(() => {\n setIsColorInputOpen(false);\n }, []);\n\n useEffect(\n function focusEditInput() {\n if (isEditing && nameInputRef.current) {\n // This is solely b/c RTL doesn't count select as focusing the element\n // Might be fixed in v13+ of RTL\n nameInputRef.current.focus();\n nameInputRef.current.select();\n }\n },\n [isEditing]\n );\n\n useEffect(\n function deleteNewOnUnmount() {\n return () => {\n if (groupRef.current.isNew) {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n onDelete(groupRef.current);\n }\n };\n },\n [onDelete]\n );\n\n useEffect(\n function openColorInput() {\n if (isColorInputOpen) {\n colorInputRef.current?.click();\n // Mostly for testing. Chrome seems to not give the hidden input focus\n // Really would only affect screen readers\n colorInputRef.current?.focus();\n\n /**\n * Adding this event handler is for Firefox on Mac\n * There seems to be buggy behavior when multiple color inputs are on the same page\n * Clicking between the inputs without closing the previous causes a bad state\n * The user gets to a point where they can't open most of the pickers\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1618418\n * https://bugzilla.mozilla.org/show_bug.cgi?id=975468\n * Instead, we remove the color input when any focus is returned to the window\n * This causes Firefox on Mac to mostly operate correctly\n * Firefox seems to ignore the first click back into the window and emit no event\n * So opening a color picker when another is open requires 2 clicks in Firefox\n */\n window.addEventListener('click', colorInputBlurHandler, true);\n }\n\n return () =>\n window.removeEventListener('click', colorInputBlurHandler, true);\n },\n [isColorInputOpen, colorInputBlurHandler]\n );\n\n const handleConfirm = () => {\n if (isValid) {\n onNameChange(group, name);\n setIsEditing(false);\n }\n };\n\n const handleCancel = () => {\n if (isNew) {\n onDelete(group);\n return;\n }\n setName(group.name);\n setIsEditing(false);\n };\n\n const handleEditKeyDown = (e: React.KeyboardEvent): void => {\n setShouldValidate(true);\n if (e.key === 'Enter') {\n e.stopPropagation();\n handleConfirm();\n }\n\n if (e.key === ' ') {\n e.stopPropagation();\n }\n\n if (e.key === 'Escape') {\n handleCancel();\n }\n };\n\n if (isEditing) {\n return (\n <>\n <div className=\"editing-container\">\n <input\n ref={nameInputRef}\n className={classNames('form-control', {\n 'is-invalid': !isValid,\n })}\n value={name}\n placeholder=\"Group Name\"\n onChange={e => setName(e.target.value)}\n onKeyDown={handleEditKeyDown}\n onBlur={() => setShouldValidate(true)}\n />\n <Button\n kind=\"ghost\"\n icon={vsCheck}\n tooltip=\"Confirm\"\n onClick={handleConfirm}\n />\n <Button\n kind=\"ghost\"\n icon={vsChromeClose}\n tooltip=\"Cancel\"\n onClick={handleCancel}\n />\n </div>\n {!isValid && (\n <p className=\"mb-0 validate-label-error text-danger\">\n {nameValidationError}\n </p>\n )}\n </>\n );\n }\n\n return (\n <div className=\"group-name-wrapper\">\n <span className=\"column-name\">{name}</span>\n <Button\n className=\"p-1 mx-1\"\n kind=\"ghost\"\n icon={vsEdit}\n tooltip=\"Edit\"\n onClick={() => {\n setIsEditing(true);\n }}\n />\n\n <span className=\"right-buttons\">\n <Button\n kind=\"ghost\"\n icon={vsTrash}\n tooltip=\"Delete group\"\n onClick={() => onDelete(group)}\n />\n <Button\n kind=\"ghost\"\n className=\"color-swatch mr-1\"\n icon={\n group.color !== undefined ? (\n <span className=\"fa-layers\">\n <FontAwesomeIcon\n className=\"color-swatch\"\n icon={dhSquareFilled}\n color={ThemeExport.white}\n transform=\"down-1\"\n />\n <FontAwesomeIcon\n className=\"color-swatch\"\n icon={dhSquareFilled}\n color={group.color}\n transform=\"shrink-2 down-1\"\n />\n </span>\n ) : (\n vsPaintcan\n )\n }\n tooltip=\"Set color\"\n /**\n * Toggle to close the picker on Chrome\n * Prevents Firefox on Mac from getting into a stuck state\n * Does not close on Firefox b/c the picker stays open when the element is removed\n */\n onClick={() => setIsColorInputOpen(val => !val)}\n />\n {isColorInputOpen && (\n <>\n <input\n aria-label=\"Color input\"\n ref={colorInputRef}\n type=\"color\"\n list=\"presetColors\"\n value={group.color ?? ThemeExport['content-bg']}\n style={{\n visibility: 'hidden',\n width: 0,\n height: 0,\n padding: 0,\n border: 0,\n }}\n onChange={e => {\n group.color = e.target.value;\n onColorChange(group, e.target.value);\n }}\n />\n <datalist id=\"presetColors\">\n <option>{ThemeExport['content-bg']}</option>\n <option>{ThemeExport.primary}</option>\n <option>{ThemeExport.foreground}</option>\n <option>{ThemeExport.green}</option>\n <option>{ThemeExport.yellow}</option>\n <option>{ThemeExport.orange}</option>\n <option>{ThemeExport.red}</option>\n <option>{ThemeExport.purple}</option>\n <option>{ThemeExport.blue}</option>\n <option>{ThemeExport['gray-400']}</option>\n </datalist>\n </>\n )}\n </span>\n </div>\n );\n}\n","/* eslint-disable react/prop-types */\nimport React, { forwardRef, useCallback, useRef } from 'react';\nimport classNames from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { dhEye, dhEyeSlash, vsGripper } from '@deephaven/icons';\nimport { Button, Tooltip } from '@deephaven/components';\nimport VisibilityOrderingGroup from './VisibilityOrderingGroup';\nimport { FlattenedIrisGridTreeItem } from './sortable-tree/utilities';\nimport type ColumnHeaderGroup from '../../ColumnHeaderGroup';\n\ntype VisibilityOrderingItemProps = {\n value: string;\n clone: boolean;\n childCount: number;\n item: FlattenedIrisGridTreeItem;\n onVisibilityChange(modelIndexes: number[], isVisible: boolean): void;\n onClick(name: string, event: React.MouseEvent): void;\n onGroupDelete(group: ColumnHeaderGroup): void;\n onGroupColorChange(group: ColumnHeaderGroup, color: string | undefined): void;\n onGroupNameChange(group: ColumnHeaderGroup, name: string): void;\n validateGroupName(name: string): string;\n handleProps: Record<string, unknown>;\n};\n\nfunction emptyOnClick() {\n // no-op\n}\n\nconst VisibilityOrderingItem = forwardRef<\n HTMLDivElement,\n VisibilityOrderingItemProps\n>(function VisibilityOrderingItem(props, ref) {\n const {\n value,\n clone,\n childCount,\n item,\n onVisibilityChange,\n onClick,\n onGroupDelete,\n onGroupColorChange,\n onGroupNameChange,\n validateGroupName,\n handleProps,\n } = props;\n const { group, modelIndex, isVisible } = item.data;\n const buttonRef = useRef<HTMLButtonElement>(null);\n\n const handleVisibilityChange = useCallback(\n (e: React.MouseEvent) => {\n if (e.buttons === 1) {\n onVisibilityChange([modelIndex].flat(), !isVisible);\n buttonRef.current?.focus();\n }\n },\n [onVisibilityChange, modelIndex, isVisible]\n );\n\n const handleClick = useCallback(\n (event: React.MouseEvent) => {\n onClick(value, event);\n },\n [onClick, value]\n );\n\n return (\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions\n <div\n ref={ref}\n className={classNames('tree-item', {\n isSelected: item.selected,\n 'two-dragged': childCount === 2,\n 'multiple-dragged': childCount > 2,\n })}\n onClick={handleClick}\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...handleProps}\n >\n <Button\n ref={buttonRef}\n kind=\"ghost\"\n className=\"px-1\"\n // We PropType validate onClick for Button\n onClick={emptyOnClick}\n onMouseDown={handleVisibilityChange}\n onMouseEnter={handleVisibilityChange}\n icon={isVisible ? dhEye : dhEyeSlash}\n tooltip=\"Toggle visibility\"\n />\n <span className={classNames('column-name', group && 'column-group')}>\n {/* Display a normal item if this is the drag overlay clone, even if it's a group */}\n {group && !clone ? (\n <VisibilityOrderingGroup\n group={group}\n onDelete={onGroupDelete}\n onColorChange={onGroupColorChange}\n onNameChange={onGroupNameChange}\n validateName={validateGroupName}\n />\n ) : (\n value\n )}\n </span>\n <div>\n {clone && childCount > 1 && (\n <span className=\"item-count\">{childCount}</span>\n )}\n <Tooltip>Drag to re-order</Tooltip>\n <FontAwesomeIcon icon={vsGripper} />\n </div>\n </div>\n );\n});\n\nexport default VisibilityOrderingItem;\n","import type { MutableRefObject } from 'react';\n\nexport type TreeItem<T = undefined> = {\n id: string;\n children: TreeItem<T>[];\n selected: boolean;\n} & (T extends undefined\n ? // eslint-disable-next-line @typescript-eslint/ban-types\n {}\n : {\n data: T;\n });\n\nexport type TreeItems<T = undefined> = TreeItem<T>[];\nexport type ReadonlyTreeItems<T = undefined> = readonly TreeItem<T>[];\n\nexport type FlattenedItem<T = undefined> = TreeItem<T> & {\n parentId: string | null;\n depth: number;\n index: number;\n};\n\nexport function isFlattenedTreeItem<T>(\n item: TreeItem<T>\n): item is FlattenedItem<T> {\n return (item as FlattenedItem<T>).parentId !== undefined;\n}\n\nexport type SensorContext = MutableRefObject<{\n items: FlattenedItem[];\n offset: number;\n}>;\n","import { arrayMove } from '@dnd-kit/sortable';\nimport type { Column } from '@deephaven/jsapi-types';\nimport { GridUtils, ModelIndex, MoveOperation } from '@deephaven/grid';\nimport type ColumnHeaderGroup from '../../../ColumnHeaderGroup';\nimport { isFlattenedTreeItem, ReadonlyTreeItems } from './types';\nimport type { FlattenedItem, TreeItem } from './types';\n\n/**\n * Gets the depth of an item dragged with a given x-axis offset\n *\n * @param offset x-axis offset of the dragging item\n * @param indentationWidth Width of indentation for each depth\n * @returns The drag depth for the given offset\n */\nfunction getDragDepth(offset: number, indentationWidth: number) {\n return Math.round(offset / indentationWidth);\n}\n\ninterface IrisGridTreeItemData {\n modelIndex: number | number[];\n visibleIndex: number | [number, number];\n isVisible: boolean;\n group?: ColumnHeaderGroup;\n}\n\nexport type IrisGridTreeItem = TreeItem<IrisGridTreeItemData>;\n\nexport type FlattenedIrisGridTreeItem = FlattenedItem<IrisGridTreeItemData>;\n\nfunction getTreeItem(\n columns: readonly Column[],\n movedColumns: readonly MoveOperation[],\n columnHeaderGroupMap: Map<string, ColumnHeaderGroup>,\n name: string,\n hiddenColumnSet: Set<ModelIndex>,\n selectedItems: Set<string>\n): IrisGridTreeItem {\n const modelIndex = columns.findIndex(col => col.name === name);\n if (modelIndex === -1) {\n const group = columnHeaderGroupMap.get(name);\n\n if (group == null) {\n throw new Error(`Column or header group not found: ${name}`);\n }\n\n const modelIndexes = group.childIndexes.flat();\n\n return {\n id: name,\n selected: selectedItems.has(name),\n children: group.children\n .map(childName =>\n getTreeItem(\n columns,\n movedColumns,\n columnHeaderGroupMap,\n childName,\n hiddenColumnSet,\n selectedItems\n )\n )\n .sort((a, b) => {\n const aVal = Array.isArray(a.data.visibleIndex)\n ? a.data.visibleIndex[0]\n : a.data.visibleIndex;\n const bVal = Array.isArray(b.data.visibleIndex)\n ? b.data.visibleIndex[0]\n : b.data.visibleIndex;\n return aVal - bVal;\n }),\n data: {\n modelIndex: modelIndexes,\n visibleIndex: group.getVisibleRange(movedColumns),\n group,\n isVisible: modelIndexes.some(index => !hiddenColumnSet.has(index)),\n },\n };\n }\n\n return {\n id: name,\n children: [],\n selected: selectedItems.has(name),\n data: {\n modelIndex,\n visibleIndex: GridUtils.getVisibleIndex(modelIndex, movedColumns),\n isVisible: !hiddenColumnSet.has(modelIndex),\n },\n };\n}\n\nexport function getTreeItems(\n columns: readonly Column[],\n movedColumns: readonly MoveOperation[],\n columnHeaderGroups: readonly ColumnHeaderGroup[],\n hiddenColumns: readonly ModelIndex[],\n selectedItems: readonly string[]\n): IrisGridTreeItem[] {\n const items: IrisGridTreeItem[] = [];\n const selectedItemsSet = new Set(selectedItems);\n const groupMap = new Map(\n columnHeaderGroups.map(group => [group.name, group])\n );\n const hiddenColumnSet = new Set(hiddenColumns);\n\n let visibleIndex = 0;\n while (visibleIndex < columns.length) {\n const modelIndex = GridUtils.getModelIndex(visibleIndex, movedColumns);\n const columnName = columns[modelIndex].name;\n\n let group = columnHeaderGroups.find(({ children }) =>\n children.includes(columnName)\n );\n while (group !== undefined && group.parent !== undefined) {\n group = groupMap.get(group.parent);\n }\n\n const item = getTreeItem(\n columns,\n movedColumns,\n groupMap,\n group ? group.name : columnName,\n hiddenColumnSet,\n selectedItemsSet\n );\n\n items.push(item);\n\n if (Array.isArray(item.data.visibleIndex)) {\n visibleIndex += item.data.visibleIndex[1] - item.data.visibleIndex[0] + 1;\n } else {\n visibleIndex += 1;\n }\n }\n\n return items;\n}\n\n/**\n * Gets the projected drop position and depth of the dragged item\n *\n * @param items List of flattened items\n * @param activeId ID of the actively dragged item\n * @param overId ID of the item currently being dragged over\n * @param dragOffset The x-axis offset of the dragged item\n * @param indentationWidth The width for each level of the tree\n * @returns The projected position and depth if the item were to be dropped\n */\nexport function getProjection(\n items: FlattenedItem[],\n activeId: string,\n overId: string,\n dragOffset: number,\n indentationWidth: number\n) {\n const overItemIndex = items.findIndex(({ id }) => id === overId);\n const activeItemIndex = items.findIndex(({ id }) => id === activeId);\n const activeItem = items[activeItemIndex];\n const newItems = arrayMove(items, activeItemIndex, overItemIndex);\n const previousItem: FlattenedItem | undefined = newItems[overItemIndex - 1];\n const nextItem = newItems[overItemIndex + 1];\n const dragDepth = getDragDepth(dragOffset, indentationWidth);\n const projectedDepth = activeItem.depth + dragDepth;\n const maxDepth = getMaxDepth({\n previousItem,\n nextItem,\n });\n const minDepth = getMinDepth({ nextItem });\n let depth = projectedDepth;\n\n if (projectedDepth >= maxDepth) {\n depth = maxDepth;\n } else if (projectedDepth < minDepth) {\n depth = minDepth;\n }\n\n return { depth, maxDepth, minDepth, parentId: getParentId() };\n\n function getParentId() {\n if (depth === 0 || !previousItem) {\n return null;\n }\n\n if (depth === previousItem.depth) {\n return previousItem.parentId;\n }\n\n if (depth > previousItem.depth) {\n return previousItem.id;\n }\n\n const newParent = newItems\n .slice(0, overItemIndex)\n .reverse()\n .find(item => item.depth === depth)?.parentId;\n\n return newParent ?? null;\n }\n}\n\nfunction getMaxDepth({\n previousItem,\n nextItem,\n}: {\n previousItem?: FlattenedItem;\n nextItem?: FlattenedItem;\n}) {\n return Math.max(previousItem?.depth ?? 0, nextItem?.depth ?? 0);\n}\n\nfunction getMinDepth({ nextItem }: { nextItem: FlattenedItem | undefined }) {\n if (nextItem) {\n return nextItem.depth;\n }\n\n return 0;\n}\n\n/**\n * Helper function to recursively flatten a tree\n *\n * @param items Items to flatten\n * @param parentId The current parentId of the items\n * @param depth The current depth of the items\n * @returns Flattened items\n */\nfunction flatten<T>(\n items: ReadonlyTreeItems<T>,\n parentId: string | null = null,\n depth = 0\n): FlattenedItem<T>[] {\n return items.reduce<FlattenedItem<T>[]>(\n (acc, item, index) => [\n ...acc,\n { ...item, parentId, depth, index },\n ...flatten(item.children, item.id, depth + 1),\n ],\n []\n );\n}\n\n/**\n * Flattens a tree into a 1D array given the items\n * @param items The tree items to flatten\n * @returns The flattened tree items list\n */\nexport function flattenTree<T>(\n items: ReadonlyTreeItems<T>\n): FlattenedItem<T>[] {\n // Should help prevent double flattening since FlattenedItems are valid TreeItems\n if (items.every(isFlattenedTreeItem)) {\n return [...items];\n }\n return flatten(items);\n}\n\n/**\n * Recursively checks for the item in a list of items.\n * The list does not have to be flattened prior to searching.\n *\n * @param items Items to search\n * @param itemId Item to find\n * @returns The item if found\n */\nexport function findItemDeep(\n items: ReadonlyTreeItems,\n itemId: string\n): TreeItem | undefined {\n for (let i = 0; i < items.length; i += 1) {\n const item = items[i];\n const { id, children } = item;\n\n if (id === itemId) {\n return item;\n }\n\n if (children.length) {\n const child = findItemDeep(children, itemId);\n\n if (child) {\n return child;\n }\n }\n }\n\n return undefined;\n}\n\nfunction countChildren(items: TreeItem[], count = 0): number {\n return items.reduce((acc, { children }) => {\n if (children.length) {\n return countChildren(children, acc + 1);\n }\n\n return acc + 1;\n }, count);\n}\n\nexport function getChildCount(items: ReadonlyTreeItems, id: string): number {\n const item = findItemDeep(items, id);\n\n return item ? countChildren(item.children) : 0;\n}\n\n/**\n * Removes the children of the list of parents from the list of flattened items\n *\n * @param items The flattened items to remove from\n * @param ids The parents we want to remove the children of\n * @returns The flattened items without the children of the parents\n */\nexport function removeChildrenOf<T>(\n items: FlattenedItem<T>[],\n ids: string[]\n): FlattenedItem<T>[] {\n const excludeParentIds = new Set(ids);\n\n return items.filter(item => {\n if (item.parentId != null && excludeParentIds.has(item.parentId)) {\n if (item.children.length) {\n excludeParentIds.add(item.id);\n }\n return false;\n }\n\n return true;\n });\n}\n","/* eslint-disable import/prefer-default-export */\nimport {\n closestCorners,\n getFirstCollision,\n KeyboardCode,\n KeyboardCoordinateGetter,\n DroppableContainer,\n} from '@dnd-kit/core';\nimport type { SensorContext } from './types';\nimport { getProjection } from './utilities';\n\nconst DIRECTIONS: string[] = [\n KeyboardCode.Down,\n KeyboardCode.Right,\n KeyboardCode.Up,\n KeyboardCode.Left,\n];\n\nconst HORIZONTAL: string[] = [KeyboardCode.Left, KeyboardCode.Right];\n\nexport function sortableTreeKeyboardCoordinates(\n context: SensorContext,\n indicator: boolean,\n indentationWidth: number\n): KeyboardCoordinateGetter {\n return (\n event,\n {\n currentCoordinates,\n context: {\n active,\n over,\n collisionRect,\n droppableRects,\n droppableContainers,\n },\n }\n ) => {\n if (DIRECTIONS.includes(event.code)) {\n if (!active || !collisionRect) {\n return;\n }\n\n event.preventDefault();\n\n const {\n current: { items, offset },\n } = context;\n\n if (HORIZONTAL.includes(event.code) && over?.id != null) {\n const { depth, maxDepth, minDepth } = getProjection(\n items,\n active.id as string,\n over.id as string,\n offset,\n indentationWidth\n );\n\n switch (event.code) {\n case KeyboardCode.Left:\n if (depth > minDepth) {\n return {\n ...currentCoordinates,\n x: currentCoordinates.x - indentationWidth,\n };\n }\n break;\n case KeyboardCode.Right:\n if (depth < maxDepth) {\n return {\n ...currentCoordinates,\n x: currentCoordinates.x + indentationWidth,\n };\n }\n break;\n }\n\n return undefined;\n }\n\n const containers: DroppableContainer[] = [];\n\n droppableContainers.forEach(container => {\n if (container?.disabled || container.id === over?.id) {\n return;\n }\n\n const rect = droppableRects.get(container.id);\n\n if (!rect) {\n return;\n }\n\n switch (event.code) {\n case KeyboardCode.Down:\n if (collisionRect.top < rect.top) {\n containers.push(container);\n }\n break;\n case KeyboardCode.Up:\n if (collisionRect.top > rect.top) {\n containers.push(container);\n }\n break;\n }\n });\n\n const collisions = closestCorners({\n active,\n collisionRect,\n pointerCoordinates: null,\n droppableRects,\n droppableContainers: containers,\n });\n let closestId = getFirstCollision(collisions, 'id');\n\n if (closestId === over?.id && collisions.length > 1) {\n closestId = collisions[1].id;\n }\n\n if (closestId != null && over?.id != null) {\n const activeRect = droppableRects.get(active.id);\n const newRect = droppableRects.get(closestId);\n const newDroppable = droppableContainers.get(closestId);\n\n if (activeRect && newRect && newDroppable) {\n const newIndex = items.findIndex(({ id }) => id === closestId);\n const newItem = items[newIndex];\n const activeIndex = items.findIndex(({ id }) => id === active.id);\n const activeItem = items[activeIndex];\n\n if (newItem != null && activeItem != null) {\n const { depth } = getProjection(\n items,\n active.id as string,\n closestId as string,\n (newItem.depth - activeItem.depth) * indentationWidth,\n indentationWidth\n );\n const isBelow = newIndex > activeIndex;\n const modifier = isBelow ? 1 : -1;\n const nextOffset = indicator\n ? (collisionRect.height - activeRect.height) / 2\n : 0;\n\n const newCoordinates = {\n x: newRect.left + depth * indentationWidth,\n y: newRect.top + modifier * nextOffset,\n };\n\n return newCoordinates;\n }\n }\n }\n }\n\n return undefined;\n };\n}\n","import type { PointerEvent } from 'react';\nimport { PointerSensor } from '@dnd-kit/core';\n\n/**\n * An extended \"PointerSensor\" that prevent some\n * interactive html element(button, input, textarea, select, option...) from dragging\n */\nexport default class PointerSensorWithInteraction extends PointerSensor {\n static activators = [\n {\n eventName: 'onPointerDown' as const,\n handler: ({ nativeEvent: event }: PointerEvent) => {\n if (\n !event.isPrimary ||\n event.button !== 0 ||\n isInteractiveElement(event.target as Element)\n ) {\n return false;\n }\n\n return true;\n },\n },\n ];\n}\n\nconst INTERACTIVE_ELEMENTS = [\n 'button',\n 'input',\n 'textarea',\n 'select',\n 'option',\n];\n\nfunction isInteractiveElement(element: Element | null) {\n if (\n element?.tagName != null &&\n INTERACTIVE_ELEMENTS.includes(element.tagName.toLowerCase())\n ) {\n return true;\n }\n\n return false;\n}\n","/* eslint-disable react/jsx-props-no-spreading */\nimport React, { useMemo } from 'react';\nimport classNames from 'classnames';\nimport type { FlattenedItem, TreeItem as TreeItemType } from './types';\nimport './TreeItem.scss';\n\nexport interface Props<T> {\n childCount?: number;\n clone?: boolean;\n depth: number;\n disableInteraction?: boolean;\n ghost?: boolean;\n handleProps?: unknown;\n value: string;\n item: FlattenedItem<T>;\n dragRef?: React.Ref<HTMLDivElement> | null;\n wrapperRef?: React.Ref<HTMLLIElement> | null;\n renderItem(props: {\n ref: React.Ref<HTMLDivElement> | null;\n clone: boolean;\n childCount?: number;\n value: string;\n item: FlattenedItem<T>;\n handleProps: unknown;\n }): JSX.Element;\n}\n\nexport type TreeItemRenderFn<T> = (props: {\n ref: React.Ref<HTMLDivElement> | null;\n clone: boolean;\n childCount?: number;\n value: string;\n item: T extends TreeItemType<infer D> ? FlattenedItem<D> : FlattenedItem<T>;\n handleProps: Record<string, unknown>;\n}) => JSX.Element;\n\nexport function TreeItem<T>(props: Props<T>) {\n const {\n clone = false,\n depth,\n disableInteraction = false,\n ghost = false,\n handleProps,\n value,\n dragRef = null,\n wrapperRef = null,\n renderItem,\n item,\n childCount,\n } = props;\n\n const depthMarkers = useMemo(\n () =>\n Array(depth)\n .fill(0)\n // eslint-disable-next-line react/no-array-index-key\n .map((_, i) => <span key={`depth-line-${i}`} className=\"depth-line\" />),\n [depth]\n );\n\n const renderItemProps = useMemo(\n () => ({\n ref: dragRef,\n clone,\n value,\n item,\n childCount,\n handleProps,\n }),\n [dragRef, clone, value, item, childCount, handleProps]\n );\n\n return (\n <li\n key={value}\n className={classNames('item-wrapper', {\n clone,\n ghost,\n disableInteraction,\n })}\n ref={wrapperRef}\n >\n {!clone && depthMarkers}\n {renderItem(renderItemProps)}\n </li>\n );\n}\n\nTreeItem.displayName = 'TreeItem';\n","/* eslint-disable import/prefer-default-export */\nimport React, { CSSProperties, useMemo } from 'react';\nimport { AnimateLayoutChanges, useSortable } from '@dnd-kit/sortable';\nimport { CSS } from '@dnd-kit/utilities';\nimport { TreeItem, Props as TreeItemProps } from './TreeItem';\n\nexport interface Props<T> extends Omit<TreeItemProps<T>, 'style'> {\n id: string;\n}\n\nconst animateLayoutChanges: AnimateLayoutChanges = ({\n isSorting,\n wasDragging,\n}) => !(isSorting || wasDragging);\n\nexport function SortableTreeItem<T>({\n id,\n depth,\n ...props\n}: Props<T>): JSX.Element {\n const {\n attributes,\n isDragging,\n isSorting,\n listeners,\n setDraggableNodeRef,\n setDroppableNodeRef,\n transform,\n transition,\n } = useSortable({\n id,\n animateLayoutChanges,\n });\n\n const transformString = CSS.Translate.toString(transform);\n\n const style: CSSProperties = useMemo(\n () => ({\n transform: transformString,\n transition,\n }),\n [transformString, transition]\n );\n\n const handleProps = useMemo(\n () => ({\n ...attributes,\n ...listeners,\n style,\n }),\n [attributes, listeners, style]\n );\n\n return (\n <TreeItem\n dragRef={setDraggableNodeRef}\n wrapperRef={setDroppableNodeRef}\n depth={depth}\n ghost={isDragging}\n disableInteraction={isSorting}\n handleProps={handleProps}\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...props}\n />\n );\n}\n","import React, { useEffect, useRef } from 'react';\nimport { createPortal } from 'react-dom';\nimport classNames from 'classnames';\nimport {\n DragOverlay,\n DropAnimation,\n Modifier,\n defaultDropAnimation,\n useDndContext,\n} from '@dnd-kit/core';\nimport { CSS } from '@dnd-kit/utilities';\nimport { getProjection, getChildCount } from './utilities';\nimport type { FlattenedItem, SensorContext } from './types';\nimport { SortableTreeItem } from './SortableTreeItem';\n\nconst dropAnimationConfig: DropAnimation = {\n keyframes({ transform }) {\n return [\n { opacity: 1, transform: CSS.Transform.toString(transform.initial) },\n {\n opacity: 0,\n transform: CSS.Transform.toString({\n ...transform.final,\n x: transform.final.x + 5,\n y: transform.final.y + 5,\n }),\n },\n ];\n },\n easing: 'ease-out',\n sideEffects({ active }) {\n active.node.animate([{ opacity: 0 }, { opacity: 1 }], {\n duration: defaultDropAnimation.duration,\n easing: defaultDropAnimation.easing,\n });\n },\n};\n\n// Used to track the offset for adjustToCursor\n// Once drag starts, set this. Once it ends, null this\nlet offsetY: number | null = null;\n\n/**\n * This adjusts the transform to move to the cursor if it gets shifted due to multi-select.\n * With multi-select, the selected items (except dragged) are removed on drag.\n * This can cause the overlay item to disconnect from the cursor in some cases.\n * E.g. select first 3 items, start dragging from 3rd item.\n * Without this modifier, the drag overlay will be shifted 60px up from the cursor after the items are removed.\n *\n * This assumes all items are the same height as the dragged item\n * @param args Modifier args from dnd-kit\n * @returns Transform so that the dragged item stays on the cursor\n */\nfunction adjustToCursor(args: Parameters<Modifier>[0]) {\n if (\n offsetY == null &&\n args.activeNodeRect &&\n args.activatorEvent instanceof PointerEvent\n ) {\n offsetY =\n Math.floor(\n (args.activatorEvent.clientY - args.activeNodeRect.top) /\n args.activeNodeRect.height\n ) * args.activeNodeRect.height;\n }\n\n if (!args.activeNodeRect) {\n offsetY = null;\n }\n\n return { ...args.transform, y: args.transform.y + (offsetY ?? 0) };\n}\n\ninterface Props<T> {\n items: FlattenedItem<T>[];\n indentationWidth?: number;\n indicator?: boolean;\n renderItem(props: {\n clone: boolean;\n childCount?: number;\n value: string;\n item: FlattenedItem<T>;\n }): JSX.Element;\n activeId: string | null;\n overId: string | null;\n offsetLeft: number;\n}\n\nexport default function SortableTreeInner<T>({\n items,\n renderItem,\n indentationWidth = 30,\n indicator = false,\n activeId,\n overId,\n offsetLeft,\n}: Props<T>): JSX.Element {\n const context = useDndContext();\n const contextRef = useRef(context);\n\n useEffect(\n function updateContextRef() {\n contextRef.current = context;\n },\n [context]\n );\n\n // Without this, animations are funky when using the move/sort buttons\n // dnd-kit only remeasures on drag/drop by default\n // The context object changes while dragging (items don't)\n // Using the context ref allows this to trigger properly on only items changes\n useEffect(\n function remeasureContainers() {\n contextRef.current.measureDroppableContainers(items.map(({ id }) => id));\n },\n [items]\n );\n\n const projected =\n activeId != null && overId != null\n ? getProjection(items, activeId, overId, offsetLeft, indentationWidth)\n : null;\n const sensorContext: SensorContext = useRef({\n items,\n offset: offsetLeft,\n });\n\n const activeItem =\n activeId != null ? items.find(({ id }) => id === activeId) : null;\n\n useEffect(() => {\n sensorContext.current = {\n items,\n offset: offsetLeft,\n };\n }, [items, offsetLeft]);\n\n return (\n <>\n <div\n className={classNames(\n 'tree-container',\n activeId != null && 'marching-ants'\n )}\n >\n {items.map(item => {\n const { id, depth } = item;\n return (\n <SortableTreeItem\n key={id}\n id={id}\n value={id}\n depth={id === activeId && projected ? projected.depth : depth}\n item={item}\n renderItem={renderItem}\n />\n );\n })}\n </div>\n {createPortal(\n <DragOverlay\n dropAnimation={dropAnimationConfig}\n modifiers={[adjustToCursor]}\n className=\"visibility-ordering-list\"\n >\n {activeId != null && activeItem ? (\n <SortableTreeItem\n id={activeId}\n depth={activeItem.depth}\n clone\n childCount={getChildCount(items, activeId) + 1}\n value={activeId.toString()}\n renderItem={renderItem}\n item={activeItem}\n />\n ) : null}\n </DragOverlay>,\n document.body\n )}\n </>\n );\n}\n","import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n DndContext,\n closestCenter,\n KeyboardSensor,\n useSensor,\n useSensors,\n DragStartEvent,\n DragMoveEvent,\n DragEndEvent,\n DragOverEvent,\n MeasuringStrategy,\n} from '@dnd-kit/core';\nimport {\n SortableContext,\n verticalListSortingStrategy,\n} from '@dnd-kit/sortable';\nimport { flattenTree, getProjection } from './utilities';\nimport type { FlattenedItem, SensorContext, TreeItem } from './types';\nimport { sortableTreeKeyboardCoordinates } from './keyboardCoordinates';\nimport PointerSensorWithInteraction from './PointerSensorWithInteraction';\nimport SortableTreeInner from './SortableTreeInner';\n\nconst MEASURING = {\n droppable: {\n strategy: MeasuringStrategy.Always,\n },\n};\n\nconst CONSTRAINT = {\n activationConstraint: {\n distance: 5,\n },\n};\n\ninterface Props<T> {\n items: TreeItem<T>[];\n indentationWidth?: number;\n indicator?: boolean;\n onDragStart?(id: string): void;\n onDragEnd?(from: FlattenedItem<T>, to: FlattenedItem<T>): void;\n renderItem(props: {\n clone: boolean;\n childCount?: number;\n value: string;\n item: FlattenedItem<T>;\n }): JSX.Element;\n}\n\nexport default function SortableTree<T>({\n items,\n indicator = false,\n indentationWidth = 30,\n onDragStart,\n onDragEnd,\n renderItem,\n}: Props<T>): JSX.Element {\n const [activeId, setActiveId] = useState<string | null>(null);\n const [overId, setOverId] = useState<string | null>(null);\n const [offsetLeft, setOffsetLeft] = useState(0);\n\n const flattenedItems = useMemo(() => {\n const flattenedTree = flattenTree(items);\n\n if (activeId != null) {\n return flattenedTree.filter(\n ({ id, selected }) => id === activeId || !selected\n );\n }\n\n return flattenedTree;\n }, [activeId, items]);\n\n const projected =\n activeId != null && overId != null\n ? getProjection(\n flattenedItems,\n activeId,\n overId,\n offsetLeft,\n indentationWidth\n )\n : null;\n const sensorContext: SensorContext = useRef({\n items: flattenedItems,\n offset: offsetLeft,\n });\n const keyboardOptions = useMemo(\n () => ({\n coordinateGetter: sortableTreeKeyboardCoordinates(\n sensorContext,\n indicator,\n indentationWidth\n ),\n }),\n [indentationWidth, indicator]\n );\n\n const sensors = useSensors(\n useSensor(PointerSensorWithInteraction, CONSTRAINT),\n useSensor(KeyboardSensor, keyboardOptions)\n );\n\n const sortedIds = useMemo(() => flattenedItems.map(({ id }) => id), [\n flattenedItems,\n ]);\n\n useEffect(() => {\n sensorContext.current = {\n items: flattenedItems,\n offset: offsetLeft,\n };\n }, [flattenedItems, offsetLeft]);\n\n const handleDragStart = useCallback(\n ({ active: { id: newActiveId } }: DragStartEvent) => {\n setActiveId(newActiveId as string);\n setOverId(newActiveId as string);\n onDragStart?.(newActiveId as string);\n\n document.body.style.setProperty('cursor', 'grabbing');\n },\n [onDragStart]\n );\n\n const handleDragMove = useCallback(({ delta }: DragMoveEvent) => {\n setOffsetLeft(delta.x);\n }, []);\n\n const handleDragOver = useCallback(({ over }: DragOverEvent) => {\n setOverId((over?.id as string) ?? null);\n }, []);\n\n const resetState = useCallback(() => {\n setOverId(null);\n setActiveId(null);\n setOffsetLeft(0);\n\n document.body.style.setProperty('cursor', '');\n }, []);\n\n const handleDragEnd = useCallback(\n ({ active, over }: DragEndEvent) => {\n resetState();\n\n if (projected && over) {\n const { depth, parentId } = projected;\n\n const clonedItems: FlattenedItem<T>[] = JSON.parse(\n JSON.stringify(flattenTree(items))\n );\n const overIndex = clonedItems.findIndex(({ id }) => id === over.id);\n const activeIndex = clonedItems.findIndex(({ id }) => id === active.id);\n const activeTreeItem = clonedItems[activeIndex];\n\n clonedItems[activeIndex] = { ...activeTreeItem, depth, parentId };\n\n onDragEnd?.(activeTreeItem, {\n ...clonedItems[overIndex],\n parentId: projected.parentId,\n });\n }\n },\n [items, onDragEnd, projected, resetState]\n );\n\n const handleDragCancel = useCallback(() => {\n resetState();\n }, [resetState]);\n\n return (\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n measuring={MEASURING}\n onDragStart={handleDragStart}\n onDragMove={handleDragMove}\n onDragOver={handleDragOver}\n onDragEnd={handleDragEnd}\n onDragCancel={handleDragCancel}\n >\n <SortableContext items={sortedIds} strategy={verticalListSortingStrategy}>\n <SortableTreeInner\n items={flattenedItems}\n renderItem={renderItem}\n indicator={indicator}\n indentationWidth={indentationWidth}\n activeId={activeId}\n overId={overId}\n offsetLeft={offsetLeft}\n />\n </SortableContext>\n </DndContext>\n );\n}\n","import { GridUtils, MoveOperation } from '@deephaven/grid';\nimport clamp from 'lodash.clamp';\nimport ColumnHeaderGroup from '../../ColumnHeaderGroup';\nimport { FlattenedItem } from './sortable-tree/types';\nimport { FlattenedIrisGridTreeItem } from './sortable-tree/utilities';\n\n/**\n * Moves an item as the result of drag and drop in the visibility ordering builder\n * This is extracted from the component mostly for testing purposes\n * Drag and drop interactions are not easily testable\n *\n * @param from The item being dragged\n * @param to The item being dropped on\n * @param movedColumns The existing moved columns\n * @param columnHeaderGroups The column header groups pre-drag\n * @param flattenedItems Flattened tree items representing the list\n * @param selectedParentItems The user selected items in tree order. Should not include items if their parent item is selected\n * @param firstMovableIndex The first visible index that can be moved\n * @param lastMovableIndex The last visible index that can be moved\n * @returns Object containing the updated column header groups and updated movedColumns array\n * The movedColumns returned is complete and does not need to be combined with the existing movedColumns\n */\nexport function moveItemsFromDrop(\n from: FlattenedIrisGridTreeItem,\n to: FlattenedIrisGridTreeItem,\n movedColumns: readonly MoveOperation[],\n columnHeaderGroups: readonly ColumnHeaderGroup[],\n flattenedItems: readonly FlattenedIrisGridTreeItem[],\n selectedParentItems: readonly FlattenedIrisGridTreeItem[],\n firstMovableIndex: number,\n lastMovableIndex: number\n): {\n groups: readonly ColumnHeaderGroup[];\n movedColumns: readonly MoveOperation[];\n} {\n const treeItems = flattenedItems.map((item, i) => ({\n ...item,\n index: i,\n }));\n\n let newMoves: MoveOperation[] = [];\n let newGroups = columnHeaderGroups;\n\n const firstVisibleIndex = selectedParentItems[0].data.visibleIndex;\n\n const fromItemIndex = treeItems.findIndex(({ id }) => id === from.id);\n const toItemIndex = treeItems.findIndex(({ id }) => id === to.id);\n\n let toIndex = Array.isArray(firstVisibleIndex)\n ? firstVisibleIndex[1] + 1\n : firstVisibleIndex + 1;\n\n newGroups = moveToGroup(selectedParentItems[0], to.parentId, newGroups);\n\n // Move the items after to all after the first selected item\n for (let i = 1; i < selectedParentItems.length; i += 1) {\n const {\n data: { visibleIndex },\n } = selectedParentItems[i];\n\n newMoves = GridUtils.moveItemOrRange(visibleIndex, toIndex, newMoves, true);\n\n toIndex += Array.isArray(visibleIndex)\n ? visibleIndex[1] - visibleIndex[0] + 1\n : 1;\n\n newGroups = moveToGroup(selectedParentItems[i], to.parentId, newGroups);\n }\n\n const selectedRange = [\n Array.isArray(firstVisibleIndex) ? firstVisibleIndex[0] : firstVisibleIndex,\n toIndex - 1,\n ] as [number, number];\n\n const originalDropIndex = Array.isArray(to.data.visibleIndex)\n ? to.data.visibleIndex[0]\n : to.data.visibleIndex;\n let dropIndex = GridUtils.getVisibleIndex(originalDropIndex, newMoves);\n\n // When moving up from multi-select\n // And the items caused the drop index to shift (disjoint multi-select)\n // The drop index will be off by 1\n if (fromItemIndex > toItemIndex && dropIndex > originalDropIndex) {\n dropIndex -= 1;\n }\n // Dropping as first item in a group\n // Need to adjust visible index if dragging from before this group or it is off by 1\n if (\n to.children.length > 0 &&\n (Array.isArray(firstVisibleIndex)\n ? firstVisibleIndex[0]\n : firstVisibleIndex) < dropIndex\n ) {\n dropIndex -= 1;\n }\n\n if (selectedRange[0] < dropIndex) {\n dropIndex -= selectedRange[1] - selectedRange[0];\n }\n\n newMoves = GridUtils.moveItemOrRange(\n selectedRange,\n clamp(dropIndex, firstMovableIndex, lastMovableIndex),\n newMoves\n );\n\n return { groups: newGroups, movedColumns: movedColumns.concat(newMoves) };\n}\n\nexport function moveToGroup<T>(\n item: FlattenedItem<T>,\n toName: string | null,\n columnGroups: readonly ColumnHeaderGroup[]\n): ColumnHeaderGroup[] {\n if (item.parentId === toName) {\n // Don't need to move an item if it is already in the group\n return [...columnGroups];\n }\n\n let newGroups = columnGroups.map(group => new ColumnHeaderGroup(group));\n const newGroupMap = new Map(newGroups.map(group => [group.name, group]));\n const fromGroup = newGroups.find(g => g.name === item.parentId);\n const toGroup = newGroups.find(g => g.name === toName);\n const movedGroup = newGroups.find(g => g.name === item.id);\n\n if (fromGroup != null) {\n // Moved out of a group\n fromGroup.children = fromGroup.children.filter(name => name !== item.id);\n\n // Moved all children out of a group\n if (fromGroup.children.length === 0) {\n const deleteNames = new Set([fromGroup.name]);\n const { parent: parentName = '' } = fromGroup;\n let parent = newGroupMap.get(parentName);\n parent?.removeChildren([fromGroup.name]);\n\n // Might need to delete parents if their only child is the now empty group\n while (parent && parent.children.length === 0) {\n deleteNames.add(parent.name);\n const nextParentName = parent?.parent ?? '';\n const nextParent = newGroupMap.get(nextParentName);\n nextParent?.removeChildren([parent.name]);\n parent = nextParent;\n }\n\n // Delete all groups that are now empty\n newGroups = newGroups.filter(({ name }) => !deleteNames.has(name));\n }\n }\n\n if (toGroup != null) {\n // Moved into a group\n toGroup.addChildren([item.id]);\n }\n\n movedGroup?.setParent(toName ?? undefined);\n\n return newGroups;\n}\n","import React, { ChangeEvent, Component, ReactElement } from 'react';\nimport classNames from 'classnames';\nimport {\n GridUtils,\n ModelIndex,\n MoveOperation,\n VisibleIndex,\n} from '@deephaven/grid';\nimport { TextUtils, assertNotNull, DbNameValidator } from '@deephaven/utils';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport {\n dhEye,\n dhEyeSlash,\n dhSortAlphaDown,\n dhSortAlphaUp,\n dhArrowToTop,\n dhArrowToBottom,\n vsChevronUp,\n vsChevronDown,\n vsSymbolStructure,\n vsRefresh,\n vsCircleLargeFilled,\n vsAdd,\n} from '@deephaven/icons';\nimport type { Column } from '@deephaven/jsapi-types';\nimport memoize from 'memoizee';\nimport debounce from 'lodash.debounce';\nimport { Button, SearchInput } from '@deephaven/components';\nimport clamp from 'lodash.clamp';\nimport throttle from 'lodash.throttle';\nimport './VisibilityOrderingBuilder.scss';\nimport IrisGridModel from '../../IrisGridModel';\nimport { ColumnName } from '../../CommonTypes';\nimport ColumnHeaderGroup from '../../ColumnHeaderGroup';\nimport VisibilityOrderingItem from './VisibilityOrderingItem';\nimport {\n FlattenedIrisGridTreeItem,\n flattenTree,\n getTreeItems,\n IrisGridTreeItem,\n} from './sortable-tree/utilities';\nimport SortableTree from './sortable-tree/SortableTree';\nimport { TreeItemRenderFn } from './sortable-tree/TreeItem';\nimport {\n moveItemsFromDrop,\n moveToGroup,\n} from './VisibilityOrderingBuilderUtils';\n\nconst DEBOUNCE_SEARCH_COLUMN = 150;\n\ninterface VisibilityOrderingBuilderProps {\n model: IrisGridModel;\n movedColumns: readonly MoveOperation[];\n hiddenColumns: readonly ModelIndex[];\n columnHeaderGroups: readonly ColumnHeaderGroup[];\n onColumnVisibilityChanged: (\n columns: readonly VisibleIndex[],\n isVisible: boolean\n ) => void;\n onReset: () => void;\n onMovedColumnsChanged: (\n operations: readonly MoveOperation[],\n cb?: () => void\n ) => void;\n onColumnHeaderGroupChanged: (groups: readonly ColumnHeaderGroup[]) => void;\n}\n\ninterface VisibilityOrderingBuilderState {\n selectedColumns: Set<string>;\n lastSelectedColumn: string;\n searchFilter: string;\n}\n\nclass VisibilityOrderingBuilder extends Component<\n VisibilityOrderingBuilderProps,\n VisibilityOrderingBuilderState\n> {\n static SORTING_OPTIONS = { DSC: 'DSC', ASC: 'ASC' } as const;\n\n static MOVE_OPTIONS = {\n TOP: 'TOP',\n BOTTOM: 'BOTTOM',\n UP: 'UP',\n DOWN: 'DOWN',\n } as const;\n\n constructor(props: VisibilityOrderingBuilderProps) {\n super(props);\n\n this.handleSearchInputChange = this.handleSearchInputChange.bind(this);\n this.searchColumns = this.searchColumns.bind(this);\n this.handleItemClick = this.handleItemClick.bind(this);\n this.handleDragEnd = this.handleDragEnd.bind(this);\n this.handleGroupDelete = this.handleGroupDelete.bind(this);\n this.handleGroupNameChange = this.handleGroupNameChange.bind(this);\n this.handleGroupCreate = this.handleGroupCreate.bind(this);\n this.validateGroupName = this.validateGroupName.bind(this);\n this.addColumnToSelected = this.addColumnToSelected.bind(this);\n this.handleDragStart = this.handleDragStart.bind(this);\n\n this.state = {\n selectedColumns: new Set(),\n lastSelectedColumn: '',\n searchFilter: '',\n };\n\n this.list = null;\n }\n\n componentWillUnmount(): void {\n this.debouncedSearchColumns.cancel();\n }\n\n list: HTMLDivElement | null;\n\n debouncedSearchColumns = debounce(this.searchColumns, DEBOUNCE_SEARCH_COLUMN);\n\n resetVisibilityOrdering(): void {\n const {\n model,\n onReset,\n onMovedColumnsChanged,\n onColumnHeaderGroupChanged,\n } = this.props;\n\n this.setState({\n selectedColumns: new Set(),\n lastSelectedColumn: '',\n searchFilter: '',\n });\n\n onReset();\n onColumnHeaderGroupChanged(model.initialColumnHeaderGroups);\n onMovedColumnsChanged(model.initialMovedColumns);\n }\n\n resetSelection(): void {\n this.setState({ selectedColumns: new Set(), lastSelectedColumn: '' });\n }\n\n handleSearchInputChange(event: ChangeEvent<HTMLInputElement>): void {\n const searchFilter = event.target.value;\n this.setState({ searchFilter });\n if (!searchFilter) {\n this.debouncedSearchColumns.cancel();\n this.resetSelection();\n return;\n }\n this.debouncedSearchColumns(searchFilter);\n }\n\n searchColumns(searchFilter: string): void {\n const flattenedItems = flattenTree(this.getTreeItems());\n const itemsMatch = flattenedItems.filter(\n ({ id, data }) =>\n !(data.group?.isNew ?? false) &&\n id.toLowerCase().includes(searchFilter.toLowerCase())\n );\n\n const columnsMatch = itemsMatch.map(({ id }) => id);\n const visibleIndexToFocus = flattenedItems.findIndex(({ id }) =>\n id.toLowerCase().includes(searchFilter.toLowerCase())\n );\n\n this.addColumnToSelected(columnsMatch, false);\n if (columnsMatch.length > 0) {\n const columnItemToFocus = this.list?.querySelectorAll('.item-wrapper')[\n visibleIndexToFocus\n ];\n columnItemToFocus?.scrollIntoView({ block: 'center' });\n }\n }\n\n /**\n * Moves the currently selected columns in the direction specified.\n * Does not commit any changes to any state, just gets the required modifications.\n *\n * Items that are part of a selected group should not be moved separate from the group.\n *\n * Items moved to top or bottom should be removed from any groups they are within,\n * unless part of a group that is also selected. The highest level selected group will\n * be moved to the root level of the tree.\n *\n * Items moved up or down should move into and out of groups when applicable.\n * They should never move more than 1 depth level at a time.\n *\n * Multiple selected items should move to the top or bottom in their existing order,\n * but become one block of continuous columns.\n *\n * Multiple selected items moving up or down should move independently,\n * unless they are at the same depth and contiguous. In that case, they should\n * move in and out of groups together. I.e. if the 2 items above a group are selected,\n * and the move down button is pressed, then both items should be moved into the group.\n *\n * @param option The movement option\n * @returns A new copy of the movedColumns including moves required to perform the operation.\n *\n */\n moveSelectedColumns(\n option: keyof typeof VisibilityOrderingBuilder.MOVE_OPTIONS\n ): { newMoves: MoveOperation[]; groups: readonly ColumnHeaderGroup[] } {\n const { columnHeaderGroups } = this.props;\n const { selectedColumns } = this.state;\n\n const treeItems = flattenTree(this.getTreeItems());\n let firstMovableIndex = this.getFirstMovableIndex();\n let lastMovableIndex = this.getLastMovableIndex();\n assertNotNull(firstMovableIndex);\n assertNotNull(lastMovableIndex);\n\n const selectedItems = this.getSelectedParentItems();\n\n const isMovingUpward =\n option === VisibilityOrderingBuilder.MOVE_OPTIONS.UP ||\n option === VisibilityOrderingBuilder.MOVE_OPTIONS.TOP;\n\n // for moving up and to the top, move column(s) in visibility index order\n // for moving down and to the bottom, move column(s) in reverse visibility index order\n if (!isMovingUpward) {\n selectedItems.reverse();\n }\n\n let newMoves = [] as MoveOperation[];\n let updatedGroups = columnHeaderGroups;\n\n for (let i = 0; i < selectedItems.length; i += 1) {\n const {\n id,\n parentId,\n depth,\n data: { visibleIndex },\n } = selectedItems[i];\n\n switch (option) {\n case VisibilityOrderingBuilder.MOVE_OPTIONS.TOP: {\n newMoves = GridUtils.moveItemOrRange(\n visibleIndex,\n firstMovableIndex,\n newMoves,\n true\n );\n const size = Array.isArray(visibleIndex)\n ? visibleIndex[1] - visibleIndex[0] + 1\n : 1;\n firstMovableIndex += size;\n // Moving items to top should move out of any groups\n updatedGroups = moveToGroup(selectedItems[i], null, updatedGroups);\n break;\n }\n case VisibilityOrderingBuilder.MOVE_OPTIONS.BOTTOM: {\n newMoves = GridUtils.moveItemOrRange(\n visibleIndex,\n lastMovableIndex,\n newMoves,\n true\n );\n const size = Array.isArray(visibleIndex)\n ? visibleIndex[1] - visibleIndex[0] + 1\n : 1;\n lastMovableIndex -= size;\n // Moving items to bottom should move out of any groups\n updatedGroups = moveToGroup(selectedItems[i], null, updatedGroups);\n break;\n }\n case VisibilityOrderingBuilder.MOVE_OPTIONS.UP: {\n const itemIndex = treeItems.findIndex(item => item.id === id);\n // Array.findLast would be better here, but it's too new for our browser support\n const prevItemIndex = treeItems\n .map(\n (item, idx) => idx < itemIndex && !selectedColumns.has(item.id)\n )\n .lastIndexOf(true);\n const prevItem = treeItems[prevItemIndex];\n\n if (prevItem != null && prevItem.parentId !== parentId) {\n // Moving into a different parent\n if (Math.abs(prevItem.depth - depth) > 1) {\n // Prev item is more than 1 level away\n // Find prev parent at same depth as current\n // This way we only ever move 1 depth level per event\n const newParentItemIndex = treeItems\n .map((item, idx) => idx < prevItemIndex && item.depth === depth)\n .lastIndexOf(true);\n const newParentItem = treeItems[newParentItemIndex];\n updatedGroups = moveToGroup(\n selectedItems[i],\n newParentItem.id,\n updatedGroups\n );\n } else {\n updatedGroups = moveToGroup(\n selectedItems[i],\n prevItem.parentId,\n updatedGroups\n );\n }\n } else {\n const toIndex = clamp(\n Array.isArray(visibleIndex)\n ? visibleIndex[0] - 1\n : visibleIndex - 1,\n firstMovableIndex,\n lastMovableIndex\n );\n newMoves = GridUtils.moveItemOrRange(\n visibleIndex,\n toIndex,\n newMoves,\n false\n );\n const size = Array.isArray(visibleIndex)\n ? visibleIndex[1] - visibleIndex[0] + 1\n : 1;\n firstMovableIndex += size;\n }\n break;\n }\n case VisibilityOrderingBuilder.MOVE_OPTIONS.DOWN: {\n const itemIndex = treeItems.findIndex(item => item.id === id);\n const nextItem = treeItems.find(\n (item, idx) => idx > itemIndex && !selectedColumns.has(item.id)\n );\n\n if (nextItem?.parentId !== parentId) {\n // Moving out of our group\n // Move to the parent of our parent\n // That way we only ever move 1 level at a time\n const parentItem = treeItems.find(item => item.id === parentId);\n updatedGroups = moveToGroup(\n selectedItems[i],\n parentItem?.parentId ?? null,\n updatedGroups\n );\n break;\n } else if (nextItem?.children.length > 0) {\n // Moving into a group as 1st item\n updatedGroups = moveToGroup(\n selectedItems[i],\n nextItem.id,\n updatedGroups\n );\n break;\n }\n\n const toIndex = clamp(\n Array.isArray(visibleIndex)\n ? visibleIndex[0] + 1\n : visibleIndex + 1,\n firstMovableIndex,\n lastMovableIndex\n );\n newMoves = GridUtils.moveItemOrRange(\n visibleIndex,\n toIndex,\n newMoves,\n false\n );\n const size = Array.isArray(visibleIndex)\n ? visibleIndex[1] - visibleIndex[0] + 1\n : 1;\n lastMovableIndex -= size;\n\n break;\n }\n }\n }\n\n return { newMoves, groups: updatedGroups };\n }\n\n /**\n * Moves the selected columns according to the option.\n * Commits changes to state and scrolls the list if moving to top or bottom.\n *\n * @param option The move operation\n */\n handleMoveColumns(\n option: keyof typeof VisibilityOrderingBuilder.MOVE_OPTIONS\n ): void {\n const {\n onMovedColumnsChanged,\n movedColumns,\n onColumnHeaderGroupChanged,\n } = this.props;\n\n const { newMoves, groups } = this.moveSelectedColumns(option);\n let scrollListAfterMove: (() => void) | undefined;\n\n if (option === VisibilityOrderingBuilder.MOVE_OPTIONS.TOP) {\n scrollListAfterMove = () => {\n this.list?.parentElement?.scroll({ top: 0 });\n };\n }\n if (option === VisibilityOrderingBuilder.MOVE_OPTIONS.BOTTOM) {\n scrollListAfterMove = () => {\n this.list?.parentElement?.scroll({\n top: this.list.parentElement.scrollHeight,\n });\n };\n }\n\n onColumnHeaderGroupChanged(groups);\n\n if (newMoves.length > 0) {\n onMovedColumnsChanged(movedColumns.concat(newMoves), scrollListAfterMove);\n }\n }\n\n /**\n * Get the move operations required to recursively sort the grid\n * Column header groups are sorted using their name\n * Children of column header groups are then sorted within each group\n *\n * @param items The tree items to sort\n * @param option Direction of the sort\n * @param movedColumns The existing moved columns for the sort\n * Grids may use an initial move list from the model (e.g. column header groups)\n * Also used to recursively sort header groups\n * @returns The moves required to sort the grid. Includes the starting movedColumns in the array\n */\n getSortMoves(\n itemsParam: readonly IrisGridTreeItem[],\n option: keyof typeof VisibilityOrderingBuilder.SORTING_OPTIONS,\n movedColumns: readonly MoveOperation[]\n ): MoveOperation[] {\n const items = [...itemsParam];\n // Sort all the movable columns\n const isAscending =\n option === VisibilityOrderingBuilder.SORTING_OPTIONS.ASC;\n items.sort((a, b) => {\n const aName = a.id.toUpperCase();\n const bName = b.id.toUpperCase();\n return TextUtils.sort(aName, bName, isAscending);\n });\n\n let newMoves = [...movedColumns]; // Start with the base state moves by the model\n let moveToIndex = Math.min(\n ...items.flatMap(item => {\n const { modelIndex } = item.data;\n return Array.isArray(modelIndex)\n ? GridUtils.getVisibleIndexes(modelIndex, newMoves)\n : GridUtils.getVisibleIndex(modelIndex, newMoves);\n })\n );\n\n for (let i = 0; i < items.length; i += 1) {\n const item = items[i];\n const { modelIndex } = item.data;\n const visibleIndex = Array.isArray(modelIndex)\n ? GridUtils.getVisibleIndexes(modelIndex, newMoves)\n : GridUtils.getVisibleIndex(modelIndex, newMoves);\n newMoves = Array.isArray(visibleIndex)\n ? GridUtils.moveRange(\n [Math.min(...visibleIndex), Math.max(...visibleIndex)],\n moveToIndex,\n newMoves,\n true\n )\n : GridUtils.moveItem(visibleIndex, moveToIndex, newMoves);\n\n if (Array.isArray(visibleIndex)) {\n // Recursively sort groups\n newMoves = this.getSortMoves(item.children, option, newMoves);\n }\n\n moveToIndex += Array.isArray(modelIndex) ? modelIndex.length : 1;\n }\n\n return newMoves;\n }\n\n handleSortColumns(\n option: keyof typeof VisibilityOrderingBuilder.SORTING_OPTIONS\n ): void {\n const { model, onMovedColumnsChanged } = this.props;\n\n const newMoves = this.getSortMoves(\n this.getTreeItems(),\n option,\n model.initialMovedColumns\n );\n\n onMovedColumnsChanged(newMoves);\n }\n\n handleItemClick(\n name: string,\n event: React.MouseEvent<HTMLElement, MouseEvent>\n ): void {\n event.stopPropagation();\n\n // Click was triggered by an interactive element. Ignore select\n if (\n event.target instanceof HTMLElement &&\n (event.target.tagName === 'BUTTON' || event.target.tagName === 'INPUT')\n ) {\n return;\n }\n\n event.currentTarget.focus();\n\n const { selectedColumns, lastSelectedColumn } = this.state;\n const isModifierKeyDown = GridUtils.isModifierKeyDown(event);\n const isShiftKeyDown = event.shiftKey;\n const isSelected = selectedColumns.has(name);\n const columnsToBeAdded = [name];\n\n if (isSelected && isModifierKeyDown) {\n this.removeColumnFromSelected(name);\n return;\n }\n\n const movableItems = flattenTree(this.getTreeItems());\n\n if (isSelected && !isShiftKeyDown && lastSelectedColumn === name) {\n const selectedItem = movableItems.find(({ id }) => id === name);\n assertNotNull(selectedItem);\n const childCount = flattenTree(selectedItem.children).length;\n // If clicking on an item and it's the only thing selected, deselect it\n if (childCount + 1 === selectedColumns.size) {\n this.resetSelection();\n return;\n }\n }\n\n if (isShiftKeyDown) {\n const selectedIndex = movableItems.findIndex(item => item.id === name);\n const lastSelectedIndex = movableItems.findIndex(\n item => item.id === lastSelectedColumn\n );\n\n columnsToBeAdded.push(\n ...movableItems\n .slice(\n Math.min(lastSelectedIndex, selectedIndex),\n Math.max(lastSelectedIndex, selectedIndex) + 1\n )\n .map(item => item.id)\n );\n }\n\n this.addColumnToSelected(\n columnsToBeAdded,\n isModifierKeyDown || isShiftKeyDown\n );\n\n this.setState({\n lastSelectedColumn: name,\n });\n }\n\n /**\n * Adds columns or groups to the selected column set\n * Groups being added will add all of their children to the selection as well\n *\n * @param columnsToBeAdded Array of column or group names to add\n * @param addToExisting If these should be added to the existing selection or overwrite it\n */\n addColumnToSelected(\n columnsToBeAdded: string[],\n addToExisting: boolean\n ): void {\n const { selectedColumns } = this.state;\n const newSelectedColumns = new Set(\n addToExisting\n ? [...selectedColumns.values()].concat(columnsToBeAdded)\n : columnsToBeAdded\n );\n\n const flattenedItems = flattenTree(this.getTreeItems());\n\n // Add all children of selected groups to the selected columns\n // The treeItems array will always be parent -> child in the order\n // We don't need to recursively iterate because of this\n // The parent will always be added before any children for nested selections\n flattenedItems.forEach(({ id, children }) => {\n if (newSelectedColumns.has(id)) {\n children.forEach(child => newSelectedColumns.add(child.id));\n }\n });\n\n this.setState({\n selectedColumns: newSelectedColumns,\n });\n }\n\n /**\n * Removes a column or group from selected columns set.\n *\n * Removing a group will deselect all of its children.\n *\n * Removing a child will deselect all parent groups.\n * Other children in those parents will stay selected, just not the group item.\n *\n * @param name Name of the column to remove\n */\n removeColumnFromSelected(name: string): void {\n const { selectedColumns } = this.state;\n const flattenedItems = flattenTree(this.getTreeItems());\n\n const item = flattenedItems.find(({ id }) => id === name);\n assertNotNull(item);\n let parentItem = flattenedItems.find(({ id }) => id === item.parentId);\n\n // Remove all children of deselected groups\n flattenTree(item?.children).forEach(child =>\n selectedColumns.delete(child.id)\n );\n\n // Remove all parents of the removed group since it is no longer fully selected\n while (parentItem != null) {\n selectedColumns.delete(parentItem.id);\n const newParentId = parentItem.parentId;\n parentItem = flattenedItems.find(({ id }) => id === newParentId);\n }\n\n selectedColumns.delete(name);\n\n this.setState({\n selectedColumns: new Set(selectedColumns),\n });\n }\n\n handleDragStart(id: string): void {\n const { selectedColumns } = this.state;\n if (!selectedColumns.has(id)) {\n this.addColumnToSelected([id], false);\n }\n }\n\n handleDragEnd(\n from: FlattenedIrisGridTreeItem,\n to: FlattenedIrisGridTreeItem\n ): void {\n const {\n movedColumns,\n onMovedColumnsChanged,\n columnHeaderGroups,\n onColumnHeaderGroupChanged,\n } = this.props;\n\n const selectedParentItems = this.getSelectedParentItems();\n const flattenedItems = flattenTree(this.getTreeItems()).map((item, i) => ({\n ...item,\n index: i,\n }));\n const firstMovableIndex = this.getFirstMovableIndex();\n const lastMovableIndex = this.getLastMovableIndex();\n\n assertNotNull(firstMovableIndex);\n assertNotNull(lastMovableIndex);\n\n const { groups: newGroups, movedColumns: newMoves } = moveItemsFromDrop(\n from,\n to,\n movedColumns,\n columnHeaderGroups,\n flattenedItems,\n selectedParentItems,\n firstMovableIndex,\n lastMovableIndex\n );\n\n onColumnHeaderGroupChanged(newGroups);\n onMovedColumnsChanged(newMoves);\n }\n\n handleGroupNameChange(group: ColumnHeaderGroup, newName: string): void {\n const { columnHeaderGroups, onColumnHeaderGroupChanged } = this.props;\n const newGroups = [...columnHeaderGroups];\n\n const oldName = group.name;\n const groupIndex = newGroups.findIndex(({ name }) => name === oldName);\n const oldGroup = newGroups[groupIndex];\n assertNotNull(oldGroup); // Also means groupIndex >= 0\n\n const newGroup = new ColumnHeaderGroup(oldGroup);\n newGroup.name = newName;\n newGroups.splice(groupIndex, 1, newGroup);\n\n const parentIndex = newGroups.findIndex(\n ({ name }) => name === newGroup.parent\n );\n\n if (parentIndex >= 0) {\n const newParent = new ColumnHeaderGroup(newGroups[parentIndex]);\n newParent.removeChildren([oldName]);\n newParent.addChildren([newName]);\n newGroups.splice(parentIndex, 1, newParent);\n }\n\n onColumnHeaderGroupChanged(newGroups);\n }\n\n handleGroupColorChange = throttle(\n (group: ColumnHeaderGroup, color: string | undefined): void => {\n const { columnHeaderGroups, onColumnHeaderGroupChanged } = this.props;\n const newGroups = [...columnHeaderGroups];\n const newGroup = new ColumnHeaderGroup({ ...group, color });\n\n newGroups.splice(\n newGroups.findIndex(({ name }) => name === group.name),\n 1,\n newGroup\n );\n\n onColumnHeaderGroupChanged(newGroups);\n },\n 250\n );\n\n handleGroupDelete(group: ColumnHeaderGroup): void {\n const { columnHeaderGroups, onColumnHeaderGroupChanged } = this.props;\n const newGroups = columnHeaderGroups.filter(g => g.name !== group.name);\n const parentIndex = newGroups.findIndex(g => g.name === group.parent);\n if (parentIndex >= 0) {\n const newParent = new ColumnHeaderGroup(newGroups[parentIndex]);\n newParent.addChildren(group.children);\n newParent.removeChildren([group.name]);\n newGroups.splice(parentIndex, 1, newParent);\n }\n onColumnHeaderGroupChanged(newGroups);\n }\n\n handleGroupCreate(): void {\n const {\n movedColumns,\n onMovedColumnsChanged,\n onColumnHeaderGroupChanged,\n } = this.props;\n\n const { newMoves, groups } = this.moveSelectedColumns(\n VisibilityOrderingBuilder.MOVE_OPTIONS.TOP\n );\n\n const newGroups = groups.filter(group => !group.isNew);\n\n const selectedItems = this.getSelectedParentItems();\n\n const childIndexes = selectedItems\n .map(item => item.data.modelIndex)\n .flat()\n .filter(index => index >= 0);\n\n // We don't care about this name really as long as it's unique\n // The user must change it and we display a placeholder instead\n const name = `${ColumnHeaderGroup.NEW_GROUP_PREFIX}-${Date.now()}`;\n\n const newGroup = new ColumnHeaderGroup({\n name,\n children: selectedItems.map(({ id }) => id),\n depth: 0,\n childIndexes: [...new Set(childIndexes)], // Remove any duplicates\n });\n\n onMovedColumnsChanged(movedColumns.concat(newMoves), () => {\n this.list?.parentElement?.scroll({ top: 0 });\n });\n\n onColumnHeaderGroupChanged(newGroups.concat([newGroup]));\n\n this.resetSelection();\n }\n\n /**\n * Validates if a header group name is valid and not in use by any header groups or columns\n * @param groupName The name to validate\n * @returns Error message if invalid\n */\n validateGroupName(groupName: string): string {\n const { model, columnHeaderGroups } = this.props;\n const { columns } = model;\n\n if (!DbNameValidator.isValidColumnName(groupName)) {\n return 'Invalid name';\n }\n\n if (\n columns.some(({ name }) => name === groupName) ||\n columnHeaderGroups.some(({ name }) => name === groupName)\n ) {\n return 'Duplicate name';\n }\n\n return '';\n }\n\n renderItem = memoize<TreeItemRenderFn<IrisGridTreeItem>>(\n ({ value, clone, item, ref, handleProps }) => {\n const { onColumnVisibilityChanged } = this.props;\n const { selectedColumns } = this.state;\n\n let displayString = value;\n\n // The cloned drag overlay we want to show the items being dragged\n if (clone) {\n const selectedItemNames = this.getSelectedParentItems().map(\n ({ id }) => id\n );\n displayString = selectedItemNames.join(', ');\n }\n\n return (\n <VisibilityOrderingItem\n ref={ref}\n value={displayString}\n clone={clone}\n item={item}\n childCount={selectedColumns.size}\n onVisibilityChange={onColumnVisibilityChanged}\n onClick={this.handleItemClick}\n onGroupDelete={this.handleGroupDelete}\n onGroupColorChange={this.handleGroupColorChange}\n onGroupNameChange={this.handleGroupNameChange}\n validateGroupName={this.validateGroupName}\n handleProps={handleProps}\n />\n );\n }\n );\n\n getMemoizedFirstMovableIndex = memoize(\n (\n model: IrisGridModel,\n columns: readonly Column[],\n movedColumns: readonly MoveOperation[]\n ) => {\n for (let i = 0; i < columns.length; i += 1) {\n const modelIndex = GridUtils.getModelIndex(i, movedColumns);\n\n if (model.isColumnMovable(modelIndex)) {\n return i;\n }\n }\n\n return null;\n }\n );\n\n /**\n * Gets the first movable visible index\n */\n getFirstMovableIndex() {\n const { model, movedColumns } = this.props;\n return this.getMemoizedFirstMovableIndex(\n model,\n model.columns,\n movedColumns\n );\n }\n\n getMemoizedLastMovableIndex = memoize(\n (\n model: IrisGridModel,\n columns: readonly Column[],\n movedColumns: readonly MoveOperation[]\n ) => {\n for (let i = columns.length - 1; i >= 0; i -= 1) {\n const modelIndex = GridUtils.getModelIndex(i, movedColumns);\n\n if (model.isColumnMovable(modelIndex)) {\n return i;\n }\n }\n\n return null;\n }\n );\n\n /**\n * Gets the last movable visible index\n */\n getLastMovableIndex() {\n const { model, movedColumns } = this.props;\n return this.getMemoizedLastMovableIndex(model, model.columns, movedColumns);\n }\n\n memoizedGetTreeItems = memoize(\n (\n columns: readonly Column[],\n movedColumns: readonly MoveOperation[],\n columnHeaderGroups: readonly ColumnHeaderGroup[],\n hiddenColumns: readonly ModelIndex[],\n selectedColumns: ReadonlySet<string>\n ): readonly IrisGridTreeItem[] =>\n getTreeItems(columns, movedColumns, columnHeaderGroups, hiddenColumns, [\n ...selectedColumns.values(),\n ])\n );\n\n /**\n * Gets the tree of movable items in order. Memoized for efficiency\n * Use flattenItems(this.getTreeItems()) if a flat list is needed\n * @returns The movable tree items in order\n */\n getTreeItems(): readonly IrisGridTreeItem[] {\n const {\n model,\n movedColumns,\n hiddenColumns,\n columnHeaderGroups,\n } = this.props;\n const { selectedColumns } = this.state;\n\n return this.memoizedGetTreeItems(\n model.columns,\n movedColumns,\n columnHeaderGroups,\n hiddenColumns,\n selectedColumns\n );\n }\n\n /**\n * Gets the selected items that are movable.\n * This is any item whose parent is not also selected.\n *\n * @returns The array of items whose parents are not selected\n */\n getSelectedParentItems(): FlattenedIrisGridTreeItem[] {\n const { selectedColumns } = this.state;\n const treeItems = flattenTree(this.getTreeItems());\n\n return treeItems.filter(\n ({ id, parentId }) =>\n // All items whose parents are not selected\n selectedColumns.has(id) && !selectedColumns.has(parentId ?? '')\n );\n }\n\n makeVisibilityOrderingList = memoize(\n (columns: readonly Column[], treeItems: readonly IrisGridTreeItem[]) => {\n const { movedColumns } = this.props;\n\n const elements = [];\n const firstMovableIndex = this.getFirstMovableIndex();\n const lastMovableIndex = this.getLastMovableIndex();\n\n const firstMovableTreeIndex = treeItems.findIndex(({ data }) =>\n Array.isArray(data.visibleIndex)\n ? data.visibleIndex[0] === firstMovableIndex\n : data.visibleIndex === firstMovableIndex\n );\n\n const lastMovableTreeIndex = treeItems.findIndex(({ data }) =>\n Array.isArray(data.visibleIndex)\n ? data.visibleIndex[1] === lastMovableIndex\n : data.visibleIndex === lastMovableIndex\n );\n\n const movableItems = treeItems.slice(\n firstMovableTreeIndex,\n lastMovableTreeIndex + 1\n );\n\n // No movable items. Render all as immovable\n if (firstMovableIndex == null || lastMovableIndex === null) {\n for (\n let visibleIndex = 0;\n visibleIndex < columns.length;\n visibleIndex += 1\n ) {\n const modelIndex = GridUtils.getModelIndex(\n visibleIndex,\n movedColumns\n );\n const column = columns[modelIndex];\n elements.push(this.renderImmovableItem(column.name));\n }\n\n return elements;\n }\n\n // Currently immovable groups are not supported\n for (\n let visibleIndex = 0;\n visibleIndex < firstMovableIndex;\n visibleIndex += 1\n ) {\n const modelIndex = GridUtils.getModelIndex(visibleIndex, movedColumns);\n const column = columns[modelIndex];\n elements.push(this.renderImmovableItem(column.name));\n }\n\n if (firstMovableIndex !== null && firstMovableIndex > 0) {\n elements.push(<hr key=\"top-horizontal-divider\" />);\n }\n\n elements.push(\n <SortableTree\n key=\"movable-items\"\n items={movableItems}\n renderItem={this.renderItem}\n onDragStart={this.handleDragStart}\n onDragEnd={this.handleDragEnd}\n />\n );\n\n if (lastMovableIndex != null && lastMovableIndex < columns.length - 1) {\n elements.push(<hr key=\"bottom-horizontal-divider\" />);\n }\n\n for (\n let visibleIndex = lastMovableIndex + 1;\n visibleIndex < columns.length;\n visibleIndex += 1\n ) {\n const modelIndex = GridUtils.getModelIndex(visibleIndex, movedColumns);\n const column = columns[modelIndex];\n elements.push(this.renderImmovableItem(column.name));\n }\n\n return elements;\n }\n );\n\n renderImmovableItem = memoize(\n (columnName: ColumnName): ReactElement => (\n <div className=\"visibility-ordering-list-item immovable\" key={columnName}>\n <div className=\"column-item\">\n <span className=\"column-name\">{columnName}</span>\n </div>\n </div>\n )\n );\n\n render(): ReactElement {\n const { model, hiddenColumns, onColumnVisibilityChanged } = this.props;\n const { selectedColumns, searchFilter } = this.state;\n const hasSelection = selectedColumns.size > 0;\n const treeItems = this.getTreeItems();\n const nameToIndexes = new Map(\n flattenTree(treeItems).map(item => [item.id, item.data.modelIndex])\n );\n const hiddenColumnsSet = new Set(hiddenColumns);\n\n const columnsToToggle = [\n // Pass through Set to dedupe model indexes\n ...new Set(\n hasSelection\n ? [...selectedColumns.values()]\n .map(name => nameToIndexes.get(name))\n .filter((i): i is number | number[] => i != null)\n .flat()\n : treeItems.map(item => item.data.modelIndex).flat()\n ),\n ];\n const areSomeVisible = columnsToToggle.some(\n column => !hiddenColumnsSet.has(column)\n );\n\n const allToggleText = areSomeVisible ? 'Hide All' : 'Show All';\n\n const selectedToggleText = areSomeVisible\n ? 'Hide Selected'\n : 'Show Selected';\n\n const visibilityOrderingList = this.makeVisibilityOrderingList(\n model.columns,\n treeItems\n );\n\n return (\n <div role=\"menu\" className=\"visibility-ordering-builder\" tabIndex={0}>\n <div className=\"top-menu\">\n <Button\n kind=\"ghost\"\n className=\"toggle-visibility-btn\"\n onClick={() => {\n onColumnVisibilityChanged(columnsToToggle, !areSomeVisible);\n }}\n icon={areSomeVisible ? dhEye : dhEyeSlash}\n tooltip=\"Toggle column visibility\"\n >\n {!hasSelection ? allToggleText : selectedToggleText}\n </Button>\n\n <SearchInput\n className=\"visibility-search\"\n value={searchFilter}\n matchCount={searchFilter ? selectedColumns.size : undefined}\n onChange={this.handleSearchInputChange}\n />\n </div>\n <div className=\"top-menu\">\n <Button\n kind=\"ghost\"\n icon={vsRefresh}\n tooltip=\"Reset to default\"\n onClick={() => {\n this.resetVisibilityOrdering();\n }}\n >\n Reset\n </Button>\n <span className=\"vertical-divider\" />\n <Button\n kind=\"ghost\"\n icon={dhSortAlphaDown}\n tooltip=\"Sort ascending\"\n onClick={() => {\n this.handleSortColumns(\n VisibilityOrderingBuilder.SORTING_OPTIONS.ASC\n );\n }}\n />\n <Button\n kind=\"ghost\"\n icon={dhSortAlphaUp}\n tooltip=\"Sort descending\"\n onClick={() => {\n this.handleSortColumns(\n VisibilityOrderingBuilder.SORTING_OPTIONS.DSC\n );\n }}\n />\n <span className=\"vertical-divider\" />\n <Button\n kind=\"ghost\"\n tooltip=\"Create group from selection\"\n disabled={!hasSelection}\n onClick={this.handleGroupCreate}\n >\n <span className=\"fa-layers\" style={{ marginRight: '0.75rem' }}>\n <FontAwesomeIcon\n mask={vsSymbolStructure}\n icon={vsCircleLargeFilled}\n transform=\"right-7 down-5 shrink-6\"\n />\n <FontAwesomeIcon\n icon={vsAdd}\n transform=\"right-8 down-6 shrink-8\"\n />\n </span>\n Group\n </Button>\n <span className=\"vertical-divider\" />\n <Button\n kind=\"ghost\"\n icon={vsChevronUp}\n tooltip=\"Move selection up\"\n onClick={() => {\n this.handleMoveColumns(VisibilityOrderingBuilder.MOVE_OPTIONS.UP);\n }}\n disabled={!hasSelection}\n />\n <Button\n kind=\"ghost\"\n icon={vsChevronDown}\n tooltip=\"Move selection down\"\n onClick={() => {\n this.handleMoveColumns(\n VisibilityOrderingBuilder.MOVE_OPTIONS.DOWN\n );\n }}\n disabled={!hasSelection}\n />\n <Button\n kind=\"ghost\"\n icon={dhArrowToTop}\n tooltip=\"Move selection to top\"\n onClick={() => {\n this.handleMoveColumns(\n VisibilityOrderingBuilder.MOVE_OPTIONS.TOP\n );\n }}\n disabled={!hasSelection}\n />\n <Button\n kind=\"ghost\"\n icon={dhArrowToBottom}\n tooltip=\"Move selection to bottom\"\n onClick={() => {\n this.handleMoveColumns(\n VisibilityOrderingBuilder.MOVE_OPTIONS.BOTTOM\n );\n }}\n disabled={!hasSelection}\n />\n </div>\n\n <div role=\"menu\" className={classNames('visibility-ordering-list')}>\n <div\n className=\"column-list\"\n ref={list => {\n this.list = list;\n }}\n >\n {visibilityOrderingList}\n </div>\n </div>\n </div>\n );\n }\n}\n\nexport default VisibilityOrderingBuilder;\n","import React, { PureComponent } from 'react';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { Checkbox, Popper, SearchInput, Tooltip } from '@deephaven/components';\nimport {\n dhGearFilled,\n dhCheckSquare,\n dhSquareFilled,\n dhRemoveSquareFilled,\n dhWarningCircleFilled,\n vsCircleLargeFilled,\n} from '@deephaven/icons';\nimport type {\n Column,\n dh as DhType,\n FilterCondition,\n} from '@deephaven/jsapi-types';\nimport { TableUtils } from '@deephaven/jsapi-utils';\nimport './CrossColumnSearch.scss';\nimport { ColumnName } from './CommonTypes';\n\ninterface CrossColumnSearchProps {\n value: string;\n selectedColumns: readonly ColumnName[];\n invertSelection: boolean;\n onChange: (\n value: string,\n selectedColumns: readonly ColumnName[],\n invertSelection: boolean\n ) => void;\n columns: readonly Column[];\n}\n\ninterface CrossColumnSearchState {\n isConfigureColumnsShown: boolean;\n}\nclass CrossColumnSearch extends PureComponent<\n CrossColumnSearchProps,\n CrossColumnSearchState\n> {\n static createSearchFilter(\n dh: DhType,\n searchValue: string,\n selectedColumns: readonly ColumnName[],\n columns: readonly Column[],\n invertSelection: boolean\n ): FilterCondition | undefined {\n const filterColumns = invertSelection\n ? columns\n .filter(column => !selectedColumns.includes(column.name))\n .map(column => column.name)\n : selectedColumns;\n if (searchValue && filterColumns.length > 0) {\n const filterValue = dh.FilterValue.ofString(searchValue);\n const searchFilter =\n filterColumns.length === columns.length\n ? dh.FilterCondition.search(filterValue)\n : dh.FilterCondition.search(\n filterValue,\n columns\n .filter(column => filterColumns.includes(column.name))\n .map(column => column.filter())\n );\n return searchFilter;\n }\n return undefined;\n }\n\n constructor(props: CrossColumnSearchProps) {\n super(props);\n this.handleSearchValueChange = this.handleSearchValueChange.bind(this);\n this.toggleColumn = this.toggleColumn.bind(this);\n this.selectAll = this.selectAll.bind(this);\n this.clear = this.clear.bind(this);\n this.selectNumbers = this.selectNumbers.bind(this);\n\n this.searchField = React.createRef();\n\n this.state = {\n isConfigureColumnsShown: false,\n };\n }\n\n searchField: React.RefObject<SearchInput>;\n\n focus(): void {\n this.searchField.current?.focus();\n }\n\n handleSearchValueChange(event: React.ChangeEvent<HTMLInputElement>): void {\n const { onChange, selectedColumns, invertSelection } = this.props;\n onChange(event.target.value, selectedColumns, invertSelection);\n }\n\n sendColumnChange(\n selectedColumns: readonly ColumnName[],\n invertSelection: boolean\n ): void {\n const { onChange, value } = this.props;\n onChange(value, selectedColumns, invertSelection);\n }\n\n setInvertSelection(invertSelection: boolean): void {\n const { onChange, value } = this.props;\n onChange(value, [], invertSelection);\n }\n\n toggleColumn(name: string): void {\n const { selectedColumns, invertSelection } = this.props;\n if (selectedColumns.includes(name)) {\n this.sendColumnChange(\n selectedColumns.filter(c => c !== name),\n invertSelection\n );\n } else {\n const update = selectedColumns.slice();\n update.push(name);\n this.sendColumnChange(update, invertSelection);\n }\n }\n\n selectAll(): void {\n this.setInvertSelection(true);\n }\n\n clear(): void {\n this.setInvertSelection(false);\n }\n\n selectNumbers(): void {\n const { columns } = this.props;\n this.sendColumnChange(\n columns\n .filter(c => TableUtils.isNumberType(c.type))\n .map(column => column.name),\n false\n );\n }\n\n render(): React.ReactElement {\n const { value, selectedColumns, invertSelection, columns } = this.props;\n const { isConfigureColumnsShown } = this.state;\n const hasAllColumnsSelected =\n (selectedColumns.length === 0 && invertSelection === true) ||\n (selectedColumns.length === columns.length && invertSelection === false);\n const hasNoColumnsSelected =\n (selectedColumns.length === 0 && invertSelection === false) ||\n (selectedColumns.length === columns.length && invertSelection === true);\n\n // set icon layers\n let icon;\n if (hasAllColumnsSelected) {\n // icon if all columns selected for search\n icon = (\n <>\n <FontAwesomeIcon\n icon={dhSquareFilled}\n mask={dhGearFilled}\n transform=\"shrink-2 down-5 right-7\"\n />\n <FontAwesomeIcon\n icon={dhCheckSquare}\n className=\"text-primary\"\n transform=\"shrink-4 down-5 right-7\"\n />\n </>\n );\n } else if (hasNoColumnsSelected) {\n // icon error, no columns selected for searching\n icon = (\n <>\n <FontAwesomeIcon\n icon={vsCircleLargeFilled}\n mask={dhGearFilled}\n transform=\"shrink-1 down-5 right-7\"\n />\n <FontAwesomeIcon\n icon={dhWarningCircleFilled}\n className=\"text-danger\"\n transform=\"shrink-4 down-5 right-7\"\n />\n </>\n );\n } else {\n // icon if some columns selected, but not all\n icon = (\n <>\n <FontAwesomeIcon\n icon={dhSquareFilled}\n mask={dhGearFilled}\n transform=\"shrink-2 down-5 right-7\"\n />\n <FontAwesomeIcon\n icon={dhRemoveSquareFilled}\n className=\"text-primary\"\n transform=\"shrink-4 down-5 right-7\"\n />\n </>\n );\n }\n\n return (\n <div className=\"cross-column-container\">\n <SearchInput\n className=\"cross-column-search\"\n placeholder=\"Search Data...\"\n value={value}\n onChange={this.handleSearchValueChange}\n ref={this.searchField}\n />\n <button\n type=\"button\"\n className=\"btn btn-link btn-link-icon px-2\"\n onClick={() => {\n if (isConfigureColumnsShown) {\n this.setState({ isConfigureColumnsShown: false });\n } else {\n this.setState({ isConfigureColumnsShown: true });\n }\n }}\n >\n <div className=\"fa-layers\">{icon}</div>\n <Tooltip>Configure Columns</Tooltip>\n <Popper\n isShown={isConfigureColumnsShown}\n className=\"cross-column-popper\"\n onExited={() => {\n this.setState({ isConfigureColumnsShown: false });\n }}\n closeOnBlur\n interactive\n >\n <div className=\"cross-column-popup\">\n Searched Columns\n <div className=\"cross-column-scroll\">\n {columns.map(column => (\n <React.Fragment key={column.name}>\n <Checkbox\n className=\"cross-column-checkbox\"\n checked={\n invertSelection\n ? !selectedColumns.includes(column.name)\n : selectedColumns.includes(column.name)\n }\n onChange={() => this.toggleColumn(column.name)}\n >\n {column.name}\n </Checkbox>\n\n {column.type.substring(column.type.lastIndexOf('.') + 1)}\n </React.Fragment>\n ))}\n </div>\n <div className=\"cross-column-button-bar\">\n <button\n type=\"button\"\n className=\"btn btn-link\"\n onClick={this.selectAll}\n >\n Select All\n </button>\n <button\n type=\"button\"\n className=\"btn btn-link\"\n onClick={this.clear}\n >\n Clear\n </button>\n <button\n type=\"button\"\n className=\"btn btn-link\"\n onClick={this.selectNumbers}\n >\n Numbers Only\n </button>\n </div>\n {hasNoColumnsSelected && (\n <p className=\"text-danger\">\n <FontAwesomeIcon icon={dhWarningCircleFilled} /> Select at\n least one column to search.\n </p>\n )}\n </div>\n </Popper>\n </button>\n </div>\n );\n }\n}\n\nexport default CrossColumnSearch;\n","import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport debounce from 'lodash.debounce';\nimport type { dh as DhType, Table } from '@deephaven/jsapi-types';\nimport { ItemList, LoadingSpinner } from '@deephaven/components';\nimport Log from '@deephaven/log';\nimport { CanceledPromiseError } from '@deephaven/utils';\nimport './PartitionSelectorSearch.scss';\nimport { ModelIndex } from '@deephaven/grid';\n\nconst log = Log.module('PartitionSelectorSearch');\nconst DEBOUNCE_UPDATE_FILTER = 150;\n\ninterface Item {\n value: string;\n displayValue: string;\n}\n\ninterface PartitionSelectorSearchProps<T> {\n dh: DhType;\n getFormattedString: (value: T, type: string, name: string) => string;\n table: Table;\n initialPageSize: number;\n onSelect: (value: string) => void;\n onListResized: () => void;\n}\ninterface PartitionSelectorSearchState {\n offset: number;\n itemCount: number;\n items: Item[];\n text: string;\n isLoading: boolean;\n}\nclass PartitionSelectorSearch<T> extends Component<\n PartitionSelectorSearchProps<T>,\n PartitionSelectorSearchState\n> {\n static MAX_VISIBLE_ITEMS = 12;\n\n static defaultProps = {\n initialPageSize: 100,\n onSelect: (): void => undefined,\n onListResized: (): void => undefined,\n };\n\n static propTypes = {\n getFormattedString: PropTypes.func.isRequired,\n table: PropTypes.shape({\n addEventListener: PropTypes.func.isRequired,\n removeEventListener: PropTypes.func.isRequired,\n columns: PropTypes.arrayOf(\n PropTypes.shape({\n name: PropTypes.string.isRequired,\n type: PropTypes.string.isRequired,\n filter: PropTypes.func.isRequired,\n })\n ),\n size: PropTypes.number.isRequired,\n applyFilter: PropTypes.func.isRequired,\n setViewport: PropTypes.func.isRequired,\n }).isRequired,\n initialPageSize: PropTypes.number,\n onSelect: PropTypes.func,\n onListResized: PropTypes.func,\n };\n\n static handleError(error: unknown): void {\n if (!(error instanceof CanceledPromiseError)) {\n log.error(error);\n }\n }\n\n constructor(props: PartitionSelectorSearchProps<T>) {\n super(props);\n\n this.handleFilterChange = this.handleFilterChange.bind(this);\n this.handleInputFocus = this.handleInputFocus.bind(this);\n this.handleKeyDown = this.handleKeyDown.bind(this);\n this.handleListKeydown = this.handleListKeydown.bind(this);\n this.handleSelect = this.handleSelect.bind(this);\n this.handleTableUpdate = this.handleTableUpdate.bind(this);\n this.handleTextChange = this.handleTextChange.bind(this);\n this.handleViewportChange = this.handleViewportChange.bind(this);\n\n this.itemList = null;\n this.searchInput = null;\n this.timer = null;\n\n this.state = {\n offset: 0,\n itemCount: 0,\n items: [],\n text: '',\n isLoading: true,\n };\n }\n\n componentDidMount(): void {\n this.startListening();\n }\n\n componentDidUpdate(\n prevProps: PartitionSelectorSearchProps<T>,\n prevState: PartitionSelectorSearchState\n ): void {\n const { isLoading, itemCount } = this.state;\n const { onListResized } = this.props;\n if (\n itemCount !== prevState.itemCount ||\n isLoading !== prevState.isLoading\n ) {\n onListResized();\n }\n }\n\n componentWillUnmount(): void {\n this.debounceUpdateFilter.cancel();\n\n this.stopListening();\n }\n\n itemList: ItemList<Item> | null;\n\n searchInput: HTMLInputElement | null;\n\n timer: null;\n\n handleKeyDown(event: React.KeyboardEvent<HTMLInputElement>): boolean {\n if (this.itemList == null) {\n return false;\n }\n\n const { items, itemCount } = this.state;\n switch (event.key) {\n case 'Enter': {\n let selectedValue = null;\n if (items.length > 0) {\n selectedValue = items[0].value;\n } else {\n const { text } = this.state;\n selectedValue = text.trim();\n }\n\n if (selectedValue.length > 0) {\n const { onSelect } = this.props;\n onSelect(selectedValue);\n }\n\n event.stopPropagation();\n event.preventDefault();\n return true;\n }\n case 'ArrowDown':\n if (itemCount > 0) {\n this.itemList.focusItem(1);\n }\n event.stopPropagation();\n event.preventDefault();\n return true;\n default:\n return false;\n }\n }\n\n handleListKeydown(event: React.KeyboardEvent<HTMLDivElement>): void {\n switch (event.key) {\n case 'Escape':\n // Do nothing\n break;\n default:\n this.focus();\n break;\n }\n }\n\n handleFilterChange(): void {\n log.debug2('handleFilterChange');\n\n const { table } = this.props;\n const itemCount = table.size;\n this.setState({ itemCount, isLoading: true });\n }\n\n handleInputFocus(): void {\n if (this.itemList) {\n this.itemList.focusItem(0);\n }\n }\n\n handleSelect(itemIndex: ModelIndex): void {\n log.debug2('handleSelect', itemIndex);\n\n const { onSelect } = this.props;\n const { offset, items } = this.state;\n const offsetIndex = itemIndex - offset;\n if (offsetIndex < 0 || items.length <= offsetIndex) {\n log.error('No data for item', itemIndex);\n return;\n }\n\n const { value } = items[offsetIndex];\n onSelect(value);\n }\n\n handleTableUpdate(event: CustomEvent): void {\n const data = event.detail;\n const { offset } = data;\n\n const items = [] as Item[];\n const { getFormattedString, table } = this.props;\n const column = table.columns[0];\n for (let r = 0; r < data.rows.length; r += 1) {\n const row = data.rows[r];\n const value = row.get(column);\n const displayValue = getFormattedString(value, column.type, column.name);\n items.push({\n displayValue,\n value,\n });\n }\n\n const itemCount = table.size;\n log.debug2('handleTableUpdate', itemCount, offset, items.length);\n this.setState({ itemCount, items, offset, isLoading: false });\n }\n\n handleTextChange(event: React.ChangeEvent<HTMLInputElement>): void {\n log.debug2('handleTextChange');\n\n const { value: text } = event.target;\n\n this.setState({ text });\n\n this.debounceUpdateFilter();\n }\n\n handleViewportChange(topRow: number, bottomRow: number): void {\n log.debug2('handleViewportChange', topRow, bottomRow);\n\n const delta = Math.max(1, bottomRow - topRow);\n const top = Math.max(0, topRow - delta);\n const bottom = bottomRow + delta;\n\n const { table } = this.props;\n table.setViewport(top, bottom);\n }\n\n debounceUpdateFilter = debounce((): void => {\n this.updateFilter();\n }, DEBOUNCE_UPDATE_FILTER);\n\n focus(): void {\n if (this.searchInput) {\n this.searchInput.focus();\n }\n }\n\n startListening(): void {\n const { dh, initialPageSize, table } = this.props;\n table.addEventListener(dh.Table.EVENT_UPDATED, this.handleTableUpdate);\n table.addEventListener(\n dh.Table.EVENT_FILTERCHANGED,\n this.handleFilterChange\n );\n table.setViewport(0, initialPageSize);\n }\n\n stopListening(): void {\n const { dh, table } = this.props;\n table.removeEventListener(dh.Table.EVENT_UPDATED, this.handleTableUpdate);\n table.removeEventListener(\n dh.Table.EVENT_FILTERCHANGED,\n this.handleFilterChange\n );\n }\n\n updateFilter(): void {\n const { dh, initialPageSize, table } = this.props;\n const { text } = this.state;\n const filterText = text.trim();\n const filters = [];\n if (filterText.length > 0) {\n const column = table.columns[0];\n const filter = column\n .filter()\n .invoke(\n 'matches',\n dh.FilterValue.ofString(`(?s)(?i).*\\\\Q${filterText}\\\\E.*`)\n );\n filters.push(filter);\n }\n\n log.debug2('updateFilter', filters);\n\n table.applyFilter(filters);\n table.setViewport(0, initialPageSize);\n }\n\n render(): JSX.Element {\n const { isLoading, itemCount, items, offset, text } = this.state;\n const listHeight =\n Math.min(itemCount, PartitionSelectorSearch.MAX_VISIBLE_ITEMS) *\n ItemList.DEFAULT_ROW_HEIGHT +\n // Adjust for ListItem vertical padding - .375rem ~ 5.25px\n 11;\n return (\n <div className=\"iris-grid-partition-selector-search\">\n <div className=\"search-container\">\n <input\n type=\"text\"\n ref={searchInput => {\n this.searchInput = searchInput;\n }}\n value={text}\n placeholder=\"Available Partitions\"\n onChange={this.handleTextChange}\n onFocus={this.handleInputFocus}\n onKeyDown={this.handleKeyDown}\n className=\"form-control input-partition\"\n />\n </div>\n {!isLoading && itemCount > 0 && (\n <div\n className=\"iris-grid-partition-selector-search-list\"\n onKeyDown={this.handleListKeydown}\n role=\"presentation\"\n style={{ height: listHeight }}\n >\n <ItemList\n ref={itemList => {\n this.itemList = itemList;\n }}\n itemCount={itemCount}\n items={items}\n offset={offset}\n onSelect={this.handleSelect}\n onViewportChange={this.handleViewportChange}\n />\n </div>\n )}\n {!isLoading && itemCount === 0 && (\n <div className=\"iris-grid-partition-selector-search-empty\">\n No results\n </div>\n )}\n {isLoading && (\n <div className=\"iris-grid-partition-selector-loading\">\n <LoadingSpinner />\n &nbsp;Loading...\n </div>\n )}\n </div>\n );\n }\n}\n\nexport default PartitionSelectorSearch;\n","import React, { Component } from 'react';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { DropdownMenu, Tooltip } from '@deephaven/components';\nimport { vsTriangleDown, vsClose } from '@deephaven/icons';\nimport Log from '@deephaven/log';\nimport debounce from 'lodash.debounce';\nimport type { dh as DhType, Table } from '@deephaven/jsapi-types';\nimport PartitionSelectorSearch from './PartitionSelectorSearch';\nimport './IrisGridPartitionSelector.scss';\nimport { ColumnName } from './CommonTypes';\n\nconst log = Log.module('IrisGridPartitionSelector');\n\nconst PARTITION_CHANGE_DEBOUNCE_MS = 250;\ninterface IrisGridPartitionSelectorProps<T> {\n dh: DhType;\n getFormattedString: (value: T, type: string, name: string) => string;\n table: Table;\n columnName: ColumnName;\n partition: string;\n onAppend: (partition: string) => void;\n onFetchAll: () => void;\n onDone: (event?: React.MouseEvent<HTMLButtonElement>) => void;\n onChange: (partition: string) => void;\n}\ninterface IrisGridPartitionSelectorState {\n partition: string;\n}\nclass IrisGridPartitionSelector<T> extends Component<\n IrisGridPartitionSelectorProps<T>,\n IrisGridPartitionSelectorState\n> {\n static defaultProps = {\n onAppend: (): void => undefined,\n onChange: (): void => undefined,\n onFetchAll: (): void => undefined,\n onDone: (): void => undefined,\n partition: '',\n };\n\n constructor(props: IrisGridPartitionSelectorProps<T>) {\n super(props);\n\n this.handleAppendClick = this.handleAppendClick.bind(this);\n this.handleCloseClick = this.handleCloseClick.bind(this);\n this.handleIgnoreClick = this.handleIgnoreClick.bind(this);\n this.handlePartitionChange = this.handlePartitionChange.bind(this);\n this.handlePartitionSelect = this.handlePartitionSelect.bind(this);\n this.handlePartitionListResized = this.handlePartitionListResized.bind(\n this\n );\n this.handleSearchOpened = this.handleSearchOpened.bind(this);\n this.handleSearchClosed = this.handleSearchClosed.bind(this);\n\n this.searchMenu = null;\n this.selectorSearch = null;\n\n const { partition } = props;\n this.state = {\n partition,\n };\n }\n\n componentWillUnmount(): void {\n this.debounceUpdate.cancel();\n }\n\n searchMenu: DropdownMenu | null;\n\n selectorSearch: PartitionSelectorSearch<T> | null;\n\n handleAppendClick(): void {\n log.debug2('handleAppendClick');\n\n const { onAppend } = this.props;\n const { partition } = this.state;\n onAppend(partition);\n }\n\n handleCloseClick(): void {\n log.debug2('handleCloseClick');\n\n this.sendDone();\n }\n\n handleIgnoreClick(): void {\n log.debug2('handleIgnoreClick');\n\n this.sendFetchAll();\n }\n\n handlePartitionChange(event: React.ChangeEvent<HTMLInputElement>): void {\n log.debug2('handlePartitionChange');\n\n const { value: partition } = event.target;\n\n this.setState({ partition });\n\n this.debounceUpdate();\n }\n\n handlePartitionSelect(partition: string): void {\n if (this.searchMenu) {\n this.searchMenu.closeMenu();\n }\n\n this.setState({ partition }, () => {\n this.sendUpdate();\n });\n }\n\n handlePartitionListResized(): void {\n if (this.searchMenu) {\n this.searchMenu.scheduleUpdate();\n }\n }\n\n handleSearchClosed(): void {\n // Reset the table filter so it's ready next time user opens search\n const { table } = this.props;\n table.applyFilter([]);\n }\n\n handleSearchOpened(): void {\n if (this.selectorSearch) {\n this.selectorSearch.focus();\n }\n }\n\n debounceUpdate = debounce((): void => {\n this.sendUpdate();\n }, PARTITION_CHANGE_DEBOUNCE_MS);\n\n sendDone(): void {\n this.debounceUpdate.flush();\n\n const { onDone } = this.props;\n onDone();\n }\n\n sendUpdate(): void {\n log.debug2('sendUpdate');\n\n const { onChange } = this.props;\n const { partition } = this.state;\n onChange(partition);\n }\n\n sendFetchAll(): void {\n log.debug2('sendFetchAll');\n\n this.debounceUpdate.cancel();\n\n const { onFetchAll } = this.props;\n onFetchAll();\n }\n\n render(): JSX.Element {\n const { columnName, dh, getFormattedString, onDone, table } = this.props;\n const { partition } = this.state;\n const partitionSelectorSearch = (\n <PartitionSelectorSearch\n dh={dh}\n key=\"search\"\n getFormattedString={getFormattedString}\n table={table}\n onSelect={this.handlePartitionSelect}\n onListResized={this.handlePartitionListResized}\n ref={selectorSearch => {\n this.selectorSearch = selectorSearch;\n }}\n />\n );\n return (\n <div className=\"iris-grid-partition-selector\">\n <div className=\"status-message\">\n <span>Filtering &quot;{columnName}&quot; partition to</span>\n </div>\n <div className=\"input-group\">\n <input\n type=\"text\"\n value={partition}\n onChange={this.handlePartitionChange}\n className=\"form-control input-partition\"\n />\n <div className=\"input-group-append\">\n <button type=\"button\" className=\"btn btn-outline-primary\">\n <FontAwesomeIcon icon={vsTriangleDown} />\n <Tooltip>Partitions</Tooltip>\n <DropdownMenu\n ref={searchMenu => {\n this.searchMenu = searchMenu;\n }}\n actions={[{ menuElement: partitionSelectorSearch }]}\n onMenuOpened={this.handleSearchOpened}\n onMenuClosed={this.handleSearchClosed}\n />\n </button>\n </div>\n </div>\n <div className=\"iris-grid-partition-selector-spacer\" />\n <button\n type=\"button\"\n className=\"btn btn-outline-primary btn-ignore\"\n onClick={this.handleIgnoreClick}\n >\n Ignore &amp; Fetch All\n </button>\n <button\n type=\"button\"\n className=\"btn btn-outline-primary btn-append\"\n onClick={this.handleAppendClick}\n >\n Append Command\n </button>\n <button\n type=\"button\"\n className=\"btn btn-link btn-link-icon btn-close\"\n onClick={onDone}\n >\n <FontAwesomeIcon icon={vsClose} />\n </button>\n </div>\n );\n }\n}\n\nexport default IrisGridPartitionSelector;\n","import React, { Component, ReactElement } from 'react';\nimport deepEqual from 'deep-equal';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { dhNewCircleLargeFilled, vsTrash } from '@deephaven/icons';\nimport { Button } from '@deephaven/components';\nimport Log from '@deephaven/log';\nimport type { Column } from '@deephaven/jsapi-types';\nimport { ModelIndex } from '@deephaven/grid';\nimport IrisGridModel from '../IrisGridModel';\n\nimport './SelectDistinctBuilder.scss';\nimport { ColumnName } from '../CommonTypes';\n\nconst log = Log.module('SelectDistinctBuilder');\n\ninterface SelectDistinctBuilderProps {\n model: IrisGridModel;\n selectDistinctColumns: readonly ColumnName[];\n onChange: (newStr: readonly string[]) => void;\n}\ninterface SelectDistinctBuilderState {\n inputs: readonly string[];\n columns: readonly Column[];\n}\nclass SelectDistinctBuilder extends Component<\n SelectDistinctBuilderProps,\n SelectDistinctBuilderState\n> {\n static defaultProps = {\n selectDistinctColumns: [],\n onChange: (): void => undefined,\n };\n\n constructor(props: SelectDistinctBuilderProps) {\n super(props);\n\n this.handleAddColumnClick = this.handleAddColumnClick.bind(this);\n this.handleDeleteColumn = this.handleDeleteColumn.bind(this);\n this.handleDropdownChanged = this.handleDropdownChanged.bind(this);\n\n const { model, selectDistinctColumns } = this.props;\n\n this.state = {\n inputs:\n selectDistinctColumns.length > 0 ? [...selectDistinctColumns] : [''],\n columns: model.originalColumns,\n };\n }\n\n componentDidUpdate(\n prevProps: SelectDistinctBuilderProps,\n prevState: SelectDistinctBuilderState\n ): void {\n const { inputs } = this.state;\n const { onChange } = this.props;\n if (prevState.inputs !== inputs) {\n const filteredInputs = inputs.filter(val => val !== '');\n if (\n !deepEqual(\n prevState.inputs.filter(val => val !== ''),\n filteredInputs\n )\n ) {\n onChange(filteredInputs);\n }\n }\n }\n\n handleAddColumnClick(): void {\n this.setState(({ inputs: prevInputs }) => ({\n inputs: [...prevInputs, ''],\n }));\n }\n\n handleDeleteColumn(index: ModelIndex): void {\n this.setState(({ inputs }) => ({\n inputs:\n inputs.length === 1 && index === 0\n ? ['']\n : inputs.filter((input, inputIndex) => index !== inputIndex),\n }));\n }\n\n handleDropdownChanged(\n index: number,\n event: React.ChangeEvent<HTMLSelectElement>\n ): void {\n log.debug('handleDropdownChanged', index, event);\n const { value } = event.target;\n this.setState(({ inputs: prevInputs }) => {\n const inputs = [...prevInputs];\n inputs[index] = value;\n return { inputs };\n });\n }\n\n renderInputs(): ReactElement[] {\n const { columns, inputs } = this.state;\n\n return inputs.map((value, index) => {\n const options = columns\n .filter(({ name }) => name === value || !inputs.includes(name))\n .map(({ name }) => (\n <option value={name} key={name}>\n {name}\n </option>\n ));\n return (\n // eslint-disable-next-line react/no-array-index-key\n <div className=\"form-inline px-3 pb-3\" key={index}>\n <select\n className=\"form-control custom-select col\"\n value={value}\n onChange={event => this.handleDropdownChanged(index, event)}\n >\n <option value=\"\">Select a column</option>\n {options}\n </select>\n\n {(inputs.length > 1 || value !== '') && (\n <Button\n kind=\"ghost\"\n className=\"ml-1 px-2\"\n onClick={() => {\n this.handleDeleteColumn(index);\n }}\n icon={<FontAwesomeIcon icon={vsTrash} transform=\"grow-3\" />}\n tooltip=\"Delete column\"\n />\n )}\n </div>\n );\n });\n }\n\n render(): React.ReactElement {\n const { columns, inputs } = this.state;\n const disableAddButton = inputs.length >= columns.length;\n return (\n <div\n role=\"presentation\"\n className=\"select-distinct-builder-container h-100\"\n >\n <div className=\"select-distinct-title\">Display Unique Values From</div>\n\n {this.renderInputs()}\n\n <hr />\n\n <div className=\"pt-1 px-3\">\n <Button\n kind=\"ghost\"\n className=\"btn-add-column\"\n onClick={this.handleAddColumnClick}\n disabled={disableAddButton}\n icon={dhNewCircleLargeFilled}\n >\n Add Additional Column\n </Button>\n </div>\n\n <div className=\"select-distinct-builder-footer\">\n <div className=\"select-distinct-builder-hint\">\n Display only unique values from the selected table columns. Note\n that this will reset any filters and display only the selected\n columns.\n </div>\n </div>\n </div>\n );\n }\n}\n\nexport default SelectDistinctBuilder;\n","import React from 'react';\nimport { Menu, SwitchMenuItemDef } from '@deephaven/components';\nimport AdvancedSettingsType from './AdvancedSettingsType';\n\nexport type AdvancedSettingsMenuCallback = (\n key: AdvancedSettingsType,\n isOn: boolean\n) => void;\n\nexport type AdvancedSettingsMenuProps = {\n items: Map<AdvancedSettingsType, boolean>;\n onChange?: AdvancedSettingsMenuCallback;\n};\n\nfunction AdvancedSettingsMenu({\n items,\n onChange = () => undefined,\n}: AdvancedSettingsMenuProps): JSX.Element {\n return (\n <Menu\n items={Array.from(items.entries()).map(\n ([key, isOn]): SwitchMenuItemDef => ({\n title: AdvancedSettingsMenu.getAdvancedSettingsTitleForKey(key),\n isOn,\n onChange: (value: boolean) => onChange(key, value),\n })\n )}\n />\n );\n}\n\nAdvancedSettingsMenu.getAdvancedSettingsTitleForKey = (\n key: AdvancedSettingsType\n): string => {\n switch (key) {\n case AdvancedSettingsType.FILTER_CONTROL_CHANGE_CLEARS_ALL_FILTERS:\n return 'Clear current table filters before applying new filters from a control';\n case AdvancedSettingsType.LINK_CHANGE_CLEARS_ALL_FILTERS:\n return 'Clear current table filters before applying new filters from an incoming link filter';\n }\n};\n\nexport default AdvancedSettingsMenu;\n","import React, { useCallback } from 'react';\nimport {\n DragDropContext,\n Draggable,\n Droppable,\n DropResult,\n} from 'react-beautiful-dnd';\nimport classNames from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { dhNewCircleLargeFilled, vsGripper, vsTrash } from '@deephaven/icons';\nimport { Button, DragUtils, Tooltip } from '@deephaven/components';\nimport { TableUtils } from '@deephaven/jsapi-utils';\nimport Log from '@deephaven/log';\nimport './ConditionalFormattingMenu.scss';\nimport {\n BaseFormatConfig,\n FormattingRule,\n FormatterType,\n getBackgroundForStyleConfig,\n getColorForStyleConfig,\n getShortLabelForConditionType,\n NumberCondition,\n StringCondition,\n DateCondition,\n} from './ConditionalFormattingUtils';\nimport { ColumnName } from '../../CommonTypes';\n\nconst log = Log.module('ConditionalFormattingMenu');\n\nexport type ChangeCallback = (rules: readonly FormattingRule[]) => void;\n\nexport type SelectCallback = (index: number) => void;\n\nexport type CreateCallback = () => void;\n\nexport type ConditionalFormattingMenuProps = {\n rules: readonly FormattingRule[];\n selectedColumn?: ColumnName;\n onChange?: ChangeCallback;\n onCreate?: CreateCallback;\n onSelect?: SelectCallback;\n};\n\nconst DEFAULT_CALLBACK = () => undefined;\n\nfunction getRuleValue(config: BaseFormatConfig): string {\n const {\n column: { type },\n } = config;\n if (TableUtils.isNumberType(type)) {\n return config.condition === NumberCondition.IS_NULL ||\n config.condition === NumberCondition.IS_NOT_NULL\n ? ''\n : `${config.value}`;\n }\n if (TableUtils.isCharType(type)) {\n return config.condition === DateCondition.IS_NULL ||\n config.condition === DateCondition.IS_NOT_NULL\n ? ''\n : `${config.value}`;\n }\n if (TableUtils.isStringType(type)) {\n return config.condition === StringCondition.IS_NULL ||\n config.condition === StringCondition.IS_NOT_NULL\n ? ''\n : `\"${config.value}\"`;\n }\n if (TableUtils.isDateType(type)) {\n return config.condition === DateCondition.IS_NULL ||\n config.condition === DateCondition.IS_NOT_NULL\n ? ''\n : `${config.value}`;\n }\n if (TableUtils.isBooleanType(type)) {\n return '';\n }\n throw new Error(`Invalid column type ${type} in getRuleValue`);\n}\n\nfunction getRuleTitle(config: BaseFormatConfig): string {\n if (\n TableUtils.isNumberType(config.column.type) &&\n config.condition === NumberCondition.IS_BETWEEN\n ) {\n return `${config.start} < ${config.column.name} < ${config.end}`;\n }\n return `${config.column.name} ${getShortLabelForConditionType(\n (config as BaseFormatConfig).column.type,\n (config as BaseFormatConfig).condition\n )} \n ${getRuleValue(config as BaseFormatConfig)}`;\n}\n\nfunction ConditionalFormattingMenu(\n props: ConditionalFormattingMenuProps\n): JSX.Element {\n const {\n rules = [],\n onChange = DEFAULT_CALLBACK,\n onCreate = DEFAULT_CALLBACK,\n onSelect = DEFAULT_CALLBACK,\n } = props;\n\n const handleRuleClick = useCallback(\n (e, rule, index) => {\n e.stopPropagation();\n log.debug('Rule clicked', rule, index);\n onSelect(index);\n },\n [onSelect]\n );\n\n const handleDeleteClick = useCallback(\n (e, rule, index) => {\n e.stopPropagation();\n log.debug('Delete button clicked', rule, index);\n const updatedRules = [...rules];\n updatedRules.splice(index, 1);\n onChange(updatedRules);\n },\n [onChange, rules]\n );\n\n const handleDragHandlerClick = useCallback(e => {\n e.stopPropagation();\n }, []);\n\n const handleDragEnd = useCallback(\n (result: DropResult) => {\n DragUtils.stopDragging();\n\n // if dropped outside the list\n if (result.destination == null) {\n return;\n }\n const sourceIndex = result.source.index;\n const destinationIndex = result.destination.index;\n const updatedRules = [...rules];\n const sourceInput = rules[sourceIndex];\n\n updatedRules.splice(sourceIndex, 1);\n updatedRules.splice(destinationIndex, 0, sourceInput);\n\n onChange(updatedRules);\n },\n [onChange, rules]\n );\n\n // Display list of rules\n return (\n <div className=\"conditional-formatting-rules\">\n <DragDropContext\n onDragStart={DragUtils.startDragging}\n onDragEnd={handleDragEnd}\n >\n <Droppable droppableId=\"droppable-custom-columns\">\n {(provided, snapshot) => (\n <div\n ref={provided.innerRef}\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...provided.droppableProps}\n className={classNames('droppable-container', {\n dragging: snapshot.draggingFromThisWith,\n })}\n >\n {rules.length === 0 && (\n <div className=\"text-muted pl-2\">No formats defined</div>\n )}\n {rules.map((rule, index) => (\n <Draggable\n // eslint-disable-next-line react/no-array-index-key\n key={`${index}-${rule.type}`}\n draggableId={`${index}-${rule.type}`}\n index={index}\n disableInteractiveElementBlocking\n >\n {\n // eslint-disable-next-line @typescript-eslint/no-shadow\n (provided, snapshot) => (\n <div\n role=\"menuitem\"\n tabIndex={0}\n onClick={e => handleRuleClick(e, rule, index)}\n className={classNames('draggable-container', {\n dragging: snapshot.isDragging,\n })}\n ref={provided.innerRef}\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...provided.draggableProps}\n >\n <div className=\"conditional-formatting-list-item\">\n <div className=\"formatting-item\">\n <div className=\"rule-icon\">\n <span\n className=\"rule-icon-bg\"\n style={{\n backgroundColor: getBackgroundForStyleConfig(\n (rule.config as BaseFormatConfig).style\n ),\n color: getColorForStyleConfig(\n (rule.config as BaseFormatConfig).style\n ),\n }}\n >\n {rule.type === FormatterType.ROWS\n ? 'row'\n : 'col'}\n </span>\n </div>\n <div className=\"rule-title\">\n {getRuleTitle(rule.config as BaseFormatConfig)}\n </div>\n <Button\n kind=\"ghost\"\n className=\"ml-1 px-2\"\n onClick={e => handleDeleteClick(e, rule, index)}\n icon={vsTrash}\n tooltip=\"Delete rule\"\n />\n <button\n type=\"button\"\n className=\"btn btn-link btn-link-icon px-2 btn-drag-handle\"\n onClick={handleDragHandlerClick}\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...provided.dragHandleProps}\n >\n <Tooltip>Drag to re-order</Tooltip>\n <FontAwesomeIcon icon={vsGripper} />\n </button>\n </div>\n </div>\n </div>\n )\n }\n </Draggable>\n ))}\n {provided.placeholder}\n </div>\n )}\n </Droppable>\n </DragDropContext>\n <hr />\n <Button kind=\"ghost\" onClick={onCreate} icon={dhNewCircleLargeFilled}>\n Add New Rule\n </Button>\n </div>\n );\n}\n\nexport default ConditionalFormattingMenu;\n","import React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport { TableUtils } from '@deephaven/jsapi-utils';\nimport type { dh as DhType } from '@deephaven/jsapi-types';\nimport Log from '@deephaven/log';\nimport {\n StringCondition,\n DateCondition,\n getLabelForNumberCondition,\n getLabelForDateCondition,\n getLabelForStringCondition,\n NumberCondition,\n ModelColumn,\n ConditionConfig,\n getDefaultConditionForType,\n getLabelForBooleanCondition,\n BooleanCondition,\n CharCondition,\n getLabelForCharCondition,\n isDateConditionValid,\n getDefaultValueForType,\n} from './ConditionalFormattingUtils';\n\nconst log = Log.module('ConditionEditor');\n\nexport interface ConditionEditorProps {\n dh: DhType;\n column: ModelColumn;\n config: ConditionConfig;\n onChange?: (config: ConditionConfig, isValid: boolean) => void;\n}\n\nconst DEFAULT_CALLBACK = () => undefined;\n\nconst numberConditionOptions = [\n NumberCondition.IS_EQUAL,\n NumberCondition.IS_NOT_EQUAL,\n NumberCondition.IS_BETWEEN,\n NumberCondition.GREATER_THAN,\n NumberCondition.GREATER_THAN_OR_EQUAL,\n NumberCondition.LESS_THAN,\n NumberCondition.LESS_THAN_OR_EQUAL,\n NumberCondition.IS_NULL,\n NumberCondition.IS_NOT_NULL,\n].map(option => (\n <option key={option} value={option}>\n {getLabelForNumberCondition(option)}\n </option>\n));\n\nconst stringConditions = [\n StringCondition.IS_EXACTLY,\n StringCondition.IS_NOT_EXACTLY,\n StringCondition.CONTAINS,\n StringCondition.DOES_NOT_CONTAIN,\n StringCondition.STARTS_WITH,\n StringCondition.ENDS_WITH,\n StringCondition.IS_NULL,\n StringCondition.IS_NOT_NULL,\n].map(option => (\n <option key={option} value={option}>\n {getLabelForStringCondition(option)}\n </option>\n));\n\nconst dateConditions = [\n DateCondition.IS_EXACTLY,\n DateCondition.IS_NOT_EXACTLY,\n DateCondition.IS_BEFORE,\n DateCondition.IS_BEFORE_OR_EQUAL,\n DateCondition.IS_AFTER,\n DateCondition.IS_AFTER_OR_EQUAL,\n DateCondition.IS_NULL,\n DateCondition.IS_NOT_NULL,\n].map(option => (\n <option key={option} value={option}>\n {getLabelForDateCondition(option)}\n </option>\n));\n\nconst booleanConditions = [\n BooleanCondition.IS_TRUE,\n BooleanCondition.IS_FALSE,\n BooleanCondition.IS_NULL,\n BooleanCondition.IS_NOT_NULL,\n].map(option => (\n <option key={option} value={option}>\n {getLabelForBooleanCondition(option)}\n </option>\n));\n\nconst charConditions = [\n CharCondition.IS_EQUAL,\n CharCondition.IS_NOT_EQUAL,\n CharCondition.IS_NULL,\n CharCondition.IS_NOT_NULL,\n].map(option => (\n <option key={option} value={option}>\n {getLabelForCharCondition(option)}\n </option>\n));\n\nfunction isNumberConditionValid(\n condition: NumberCondition,\n value?: string,\n startValue?: string,\n endValue?: string\n) {\n if (\n condition === NumberCondition.IS_NULL ||\n condition === NumberCondition.IS_NOT_NULL\n ) {\n return true;\n }\n if (\n condition === NumberCondition.IS_BETWEEN &&\n startValue != null &&\n startValue !== '' &&\n !Number.isNaN(Number.parseFloat(startValue)) &&\n endValue != null &&\n endValue !== '' &&\n !Number.isNaN(Number.parseFloat(endValue))\n ) {\n return true;\n }\n if (\n condition !== NumberCondition.IS_BETWEEN &&\n value !== undefined &&\n value !== '' &&\n !Number.isNaN(Number.parseFloat(value))\n ) {\n return true;\n }\n return false;\n}\n\nfunction getNumberInputs(\n selectedCondition: NumberCondition,\n handleValueChange: (e: unknown) => void,\n handleStartValueChange: (e: unknown) => void,\n handleEndValueChange: (e: unknown) => void,\n conditionValue?: string,\n startValue?: string,\n endValue?: string\n) {\n switch (selectedCondition) {\n case NumberCondition.IS_EQUAL:\n case NumberCondition.IS_NOT_EQUAL:\n case NumberCondition.GREATER_THAN:\n case NumberCondition.GREATER_THAN_OR_EQUAL:\n case NumberCondition.LESS_THAN:\n case NumberCondition.LESS_THAN_OR_EQUAL:\n return (\n <input\n type=\"number\"\n className=\"form-control\"\n placeholder=\"Enter value\"\n value={conditionValue ?? ''}\n onChange={handleValueChange}\n />\n );\n case NumberCondition.IS_BETWEEN:\n return (\n <div className=\"d-flex flex-row\">\n <input\n type=\"number\"\n className=\"form-control d-flex mr-2\"\n placeholder=\"Start value\"\n value={startValue ?? ''}\n onChange={handleStartValueChange}\n />\n <input\n type=\"number\"\n className=\"form-control d-flex\"\n placeholder=\"End value\"\n value={endValue ?? ''}\n onChange={handleEndValueChange}\n />\n </div>\n );\n case NumberCondition.IS_NULL:\n case NumberCondition.IS_NOT_NULL:\n return null;\n }\n}\n\nfunction getStringInputs(\n selectedCondition: StringCondition,\n handleValueChange: (e: unknown) => void,\n conditionValue?: string\n) {\n switch (selectedCondition) {\n case StringCondition.IS_NULL:\n case StringCondition.IS_NOT_NULL:\n return null;\n default:\n return (\n <input\n type=\"text\"\n className=\"form-control\"\n placeholder=\"Enter value\"\n value={conditionValue ?? ''}\n onChange={handleValueChange}\n />\n );\n }\n}\n\nfunction getDateInputs(\n selectedCondition: DateCondition,\n handleValueChange: (e: unknown) => void,\n conditionValue?: string\n) {\n switch (selectedCondition) {\n case DateCondition.IS_NULL:\n case DateCondition.IS_NOT_NULL:\n return null;\n default:\n return (\n <input\n type=\"text\"\n className=\"form-control\"\n placeholder=\"Enter value\"\n value={conditionValue ?? ''}\n onChange={handleValueChange}\n />\n );\n }\n}\n\nfunction getBooleanInputs() {\n return null;\n}\n\nfunction getCharInputs(\n selectedCondition: CharCondition,\n handleValueChange: (e: unknown) => void,\n conditionValue?: string\n) {\n switch (selectedCondition) {\n case CharCondition.IS_NULL:\n case CharCondition.IS_NOT_NULL:\n return null;\n default:\n return (\n <input\n type=\"text\"\n className=\"form-control\"\n maxLength={1}\n placeholder=\"Enter value\"\n value={conditionValue ?? ''}\n onChange={handleValueChange}\n />\n );\n }\n}\n\nfunction ConditionEditor(props: ConditionEditorProps): JSX.Element {\n const { column, config, dh, onChange = DEFAULT_CALLBACK } = props;\n const selectedColumnType = column.type;\n const [prevColumnType, setPrevColumnType] = useState(selectedColumnType);\n const [selectedCondition, setCondition] = useState(config.condition);\n const [conditionValue, setValue] = useState(config.value);\n const [startValue, setStartValue] = useState(config.start);\n const [endValue, setEndValue] = useState(config.end);\n\n if (selectedColumnType !== prevColumnType) {\n // Column type changed, reset condition and value fields\n setCondition(getDefaultConditionForType(selectedColumnType));\n setValue(getDefaultValueForType(selectedColumnType));\n setStartValue(undefined);\n setEndValue(undefined);\n setPrevColumnType(selectedColumnType);\n }\n\n const conditions = useMemo(() => {\n if (selectedColumnType === undefined) {\n return [];\n }\n if (TableUtils.isNumberType(selectedColumnType)) {\n return numberConditionOptions;\n }\n if (TableUtils.isCharType(selectedColumnType)) {\n return charConditions;\n }\n if (TableUtils.isStringType(selectedColumnType)) {\n return stringConditions;\n }\n if (TableUtils.isDateType(selectedColumnType)) {\n return dateConditions;\n }\n if (TableUtils.isBooleanType(selectedColumnType)) {\n return booleanConditions;\n }\n }, [selectedColumnType]);\n\n const handleConditionChange = useCallback(e => {\n const { value } = e.target;\n log.debug('handleConditionChange', value);\n setCondition(value);\n }, []);\n\n const handleValueChange = useCallback(e => {\n const { value } = e.target;\n log.debug('handleValueChange', value);\n setValue(value);\n }, []);\n\n const handleStartValueChange = useCallback(e => {\n const { value } = e.target;\n log.debug('handleStartValueChange', value);\n setStartValue(value);\n }, []);\n\n const handleEndValueChange = useCallback(e => {\n const { value } = e.target;\n log.debug('handleEndValueChange', value);\n setEndValue(value);\n }, []);\n\n useEffect(\n function changeCondition() {\n let isValid = true;\n\n if (selectedCondition === undefined) {\n log.debug(\n 'Unable to create formatting rule. Condition is not selected.'\n );\n isValid = false;\n } else if (\n TableUtils.isNumberType(column.type) &&\n !isNumberConditionValid(\n selectedCondition as NumberCondition,\n conditionValue,\n startValue,\n endValue\n )\n ) {\n log.debug(\n 'Unable to create formatting rule. Invalid value',\n conditionValue\n );\n isValid = false;\n } else if (\n TableUtils.isDateType(column.type) &&\n !isDateConditionValid(\n dh,\n selectedCondition as DateCondition,\n conditionValue\n )\n ) {\n log.debug(\n 'Unable to create formatting rule. Invalid date condition',\n conditionValue\n );\n isValid = false;\n }\n\n onChange(\n {\n condition: selectedCondition,\n value: conditionValue,\n start: startValue,\n end: endValue,\n },\n isValid\n );\n },\n [\n onChange,\n column.type,\n dh,\n selectedCondition,\n conditionValue,\n startValue,\n endValue,\n ]\n );\n\n const conditionInputs = useMemo(() => {\n if (selectedColumnType === undefined) {\n // Column not selected\n return null;\n }\n if (TableUtils.isNumberType(selectedColumnType)) {\n return getNumberInputs(\n selectedCondition as NumberCondition,\n handleValueChange,\n handleStartValueChange,\n handleEndValueChange,\n conditionValue,\n startValue,\n endValue\n );\n }\n if (TableUtils.isCharType(selectedColumnType)) {\n return getCharInputs(\n selectedCondition as CharCondition,\n handleValueChange,\n conditionValue\n );\n }\n if (TableUtils.isStringType(selectedColumnType)) {\n return getStringInputs(\n selectedCondition as StringCondition,\n handleValueChange,\n conditionValue\n );\n }\n if (TableUtils.isDateType(selectedColumnType)) {\n return getDateInputs(\n selectedCondition as DateCondition,\n handleValueChange,\n conditionValue\n );\n }\n if (TableUtils.isBooleanType(selectedColumnType)) {\n return getBooleanInputs();\n }\n }, [\n selectedColumnType,\n selectedCondition,\n conditionValue,\n startValue,\n endValue,\n handleValueChange,\n handleStartValueChange,\n handleEndValueChange,\n ]);\n\n return (\n <div className=\"condition-editor mb-2\">\n <select\n value={selectedCondition}\n id=\"condition-select\"\n className=\"custom-select mb-2\"\n onChange={handleConditionChange}\n >\n {conditions}\n </select>\n {conditionInputs}\n </div>\n );\n}\n\nexport default ConditionEditor;\n","import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport Log from '@deephaven/log';\nimport { ColorUtils } from '@deephaven/utils';\nimport { dhSort, vsCheck } from '@deephaven/icons';\nimport { Button, DropdownMenu } from '@deephaven/components';\nimport {\n FormatStyleType,\n getLabelForStyleType,\n FormatStyleConfig,\n getBackgroundForStyleConfig,\n getColorForStyleConfig,\n} from './ConditionalFormattingUtils';\n\nimport './StyleEditor.scss';\n\nconst log = Log.module('StyleEditor');\n\nconst DEFAULT_BACKGROUND = '#fcfcfa';\n\nconst DEFAULT_COLOR_LIGHT = '#f0f0ee';\n\nconst DEFAULT_COLOR_DARK = '#1a171a';\n\nconst DEFAULT_DROPDOWN_WIDTH = 200;\n\nexport interface ConditionEditorProps {\n config: FormatStyleConfig;\n onChange?: (config: FormatStyleConfig) => void;\n}\n\nconst DEFAULT_CALLBACK = () => undefined;\n\nfunction StyleEditor(props: ConditionEditorProps): JSX.Element {\n const { config, onChange = DEFAULT_CALLBACK } = props;\n const [styleType, setStyleType] = useState(config.type);\n const [background, setBackground] = useState(\n config.customConfig?.background ?? DEFAULT_BACKGROUND\n );\n const [isShown, setShown] = useState(false);\n const [dropdownWidth, setDropdownWidth] = useState(DEFAULT_DROPDOWN_WIDTH);\n const csContainer = useRef<HTMLDivElement>(null);\n\n const handleBackgroundChange = useCallback(e => {\n const { value } = e.target;\n log.debug('handleBackgroundChange', value);\n setBackground(value);\n }, []);\n\n const handleMenuClosed = useCallback(() => {\n if (isShown) {\n setShown(false);\n }\n }, [isShown]);\n\n const handleToggleClick = useCallback(() => {\n if (!isShown) {\n updateDropdownWidth();\n }\n setShown(!isShown);\n }, [isShown]);\n\n const styleOptions = useMemo(\n () => [\n FormatStyleType.NO_FORMATTING,\n FormatStyleType.POSITIVE,\n FormatStyleType.NEGATIVE,\n FormatStyleType.WARN,\n FormatStyleType.NEUTRAL,\n FormatStyleType.ACCENT_1,\n FormatStyleType.ACCENT_2,\n FormatStyleType.CUSTOM,\n ],\n []\n );\n\n function updateDropdownWidth(): void {\n if (csContainer.current) {\n setDropdownWidth(csContainer.current.getBoundingClientRect().width);\n }\n }\n\n useEffect(\n function updateTheme() {\n onChange({\n type: styleType,\n customConfig: {\n color: ColorUtils.isDark(background)\n ? DEFAULT_COLOR_LIGHT\n : DEFAULT_COLOR_DARK,\n background,\n },\n });\n },\n [onChange, styleType, background]\n );\n\n const renderOptions = useCallback(() => {\n let matchFound = false;\n const optionArray: JSX.Element[] = [];\n for (let index = 0; index < styleOptions.length; index += 1) {\n const option = styleOptions[index];\n const key = `option-${index}-${option}`;\n matchFound = matchFound || option === styleType;\n optionArray.push(\n <Button\n key={key}\n kind=\"inline\"\n className=\"style-option-btn\"\n onClick={() => {\n setStyleType(option);\n setShown(false);\n }}\n style={{\n color: getColorForStyleConfig({ type: option }),\n background: getBackgroundForStyleConfig({ type: option }),\n }}\n >\n {option === styleType && (\n <FontAwesomeIcon icon={vsCheck} className=\"mr-2\" />\n )}\n {option !== styleType && <span className=\"mr-4\" />}\n {getLabelForStyleType(option)}\n </Button>\n );\n }\n return optionArray;\n }, [styleOptions, styleType]);\n\n const renderMenuElement = useCallback(\n () => (\n <div\n className=\"style-menu-container\"\n role=\"presentation\"\n style={{ width: dropdownWidth }}\n >\n <div className=\"style-options\">{renderOptions()}</div>\n </div>\n ),\n [dropdownWidth, renderOptions]\n );\n\n return (\n <div className=\"style-editor\">\n <div className=\"mb-2\" ref={csContainer}>\n <label className=\"mb-0\">Style</label>\n <Button\n kind=\"inline\"\n className=\"cs-dropdown\"\n style={{\n color: getColorForStyleConfig({ type: styleType }),\n background: getBackgroundForStyleConfig({ type: styleType }),\n }}\n onClick={handleToggleClick}\n >\n {getLabelForStyleType(styleType)}\n\n <span>\n <FontAwesomeIcon icon={dhSort} className=\"cs-caret\" />\n </span>\n <DropdownMenu\n isShown={isShown}\n actions={{ menuElement: renderMenuElement() }}\n popperOptions={{ placement: 'bottom-start' }}\n popperClassName=\"style-dropdown-menu\"\n onMenuClosed={handleMenuClosed}\n menuStyle={{ maxWidth: '100rem' }}\n />\n </Button>\n </div>\n\n {styleType === FormatStyleType.CUSTOM && (\n <div className=\"mb-2\">\n <label className=\"mb-0\">Background</label>\n <input\n type=\"color\"\n value={background}\n className=\"custom-select color-select\"\n onChange={handleBackgroundChange}\n />\n </div>\n )}\n </div>\n );\n}\n\nexport default StyleEditor;\n","import React, { useCallback, useEffect, useState } from 'react';\nimport Log from '@deephaven/log';\nimport { ComboBox } from '@deephaven/components';\nimport type { dh as DhType } from '@deephaven/jsapi-types';\nimport {\n BaseFormatConfig,\n ChangeCallback,\n getDefaultConditionConfigForType,\n getConditionConfig,\n getDefaultStyleConfig,\n ModelColumn,\n FormatStyleType,\n} from './ConditionalFormattingUtils';\nimport ConditionEditor from './ConditionEditor';\nimport StyleEditor from './StyleEditor';\n\nconst log = Log.module('ColumnFormatEditor');\n\nexport interface ColumnFormatEditorProps {\n columns: ModelColumn[];\n config?: BaseFormatConfig;\n dh: DhType;\n onChange?: ChangeCallback;\n}\n\nconst DEFAULT_CALLBACK = () => undefined;\n\nfunction makeDefaultConfig(columns: ModelColumn[]): BaseFormatConfig {\n const { type, name } = columns[0];\n const column = { type, name };\n const config = {\n column,\n style: getDefaultStyleConfig(),\n ...getDefaultConditionConfigForType(type),\n };\n return config;\n}\n\nfunction ColumnFormatEditor(props: ColumnFormatEditorProps): JSX.Element {\n const {\n columns,\n config = makeDefaultConfig(columns),\n dh,\n onChange = DEFAULT_CALLBACK,\n } = props;\n\n const [selectedColumn, setColumn] = useState(\n columns.find(\n c => c.name === config.column.name && c.type === config.column.type\n ) ?? columns[0]\n );\n const [conditionConfig, setConditionConfig] = useState(\n getConditionConfig(config)\n );\n const [conditionValid, setConditionValid] = useState(false);\n const [selectedStyle, setStyle] = useState(config.style);\n\n const handleColumnChange = useCallback(\n value => {\n const newColumn = columns.find(({ name }) => name === value);\n if (newColumn !== undefined) {\n setColumn(newColumn);\n if (selectedColumn.type !== newColumn.type) {\n setConditionConfig(getDefaultConditionConfigForType(newColumn.type));\n setConditionValid(false);\n }\n } else {\n log.error(`Column ${value} not found.`);\n }\n },\n [columns, selectedColumn]\n );\n\n const handleConditionChange = useCallback(\n (updatedConditionConfig, isValid) => {\n log.debug('handleConditionChange', updatedConditionConfig, isValid);\n setConditionConfig(updatedConditionConfig);\n setConditionValid(isValid);\n },\n []\n );\n\n const handleStyleChange = useCallback(updatedStyleConfig => {\n log.debug('handleStyleChange', updatedStyleConfig);\n setStyle(updatedStyleConfig);\n }, []);\n\n useEffect(\n function updateColumnFormat() {\n let isValid = conditionValid;\n\n if (selectedColumn === undefined) {\n log.debug('Column is not selected, invalidating update.');\n isValid = false;\n }\n if (\n selectedStyle === undefined ||\n selectedStyle.type === FormatStyleType.NO_FORMATTING\n ) {\n log.debug('Style is not selected, invalidating update.');\n isValid = false;\n }\n\n const { type, name } = selectedColumn;\n const column = { type, name };\n onChange(\n {\n column,\n style: selectedStyle,\n ...conditionConfig,\n },\n isValid\n );\n },\n [onChange, selectedColumn, selectedStyle, conditionConfig, conditionValid]\n );\n\n const columnInputOptions = columns.map(({ name }) => ({\n title: name,\n value: name,\n }));\n\n return (\n <div className=\"conditional-rule-editor form\">\n <div className=\"mb-2\">\n <label className=\"mb-0\">Format Cell If</label>\n <ComboBox\n defaultValue={selectedColumn?.name}\n options={columnInputOptions}\n inputPlaceholder=\"Select a column\"\n spellCheck={false}\n onChange={handleColumnChange}\n searchPlaceholder=\"Filter columns\"\n />\n </div>\n\n {selectedColumn !== undefined && (\n <>\n <ConditionEditor\n dh={dh}\n column={selectedColumn}\n config={conditionConfig}\n onChange={handleConditionChange}\n />\n <StyleEditor config={selectedStyle} onChange={handleStyleChange} />\n </>\n )}\n </div>\n );\n}\n\nexport default ColumnFormatEditor;\n","import React, { useCallback, useEffect, useState } from 'react';\nimport Log from '@deephaven/log';\nimport type { dh as DhType } from '@deephaven/jsapi-types';\nimport { ComboBox } from '@deephaven/components';\nimport {\n BaseFormatConfig,\n ChangeCallback,\n getDefaultConditionConfigForType,\n getConditionConfig,\n getDefaultStyleConfig,\n ModelColumn,\n} from './ConditionalFormattingUtils';\nimport ConditionEditor from './ConditionEditor';\nimport StyleEditor from './StyleEditor';\n\nconst log = Log.module('RowFormatEditor');\n\nexport interface RowFormatEditorProps {\n columns: ModelColumn[];\n config?: BaseFormatConfig;\n dh: DhType;\n onChange?: ChangeCallback;\n}\n\nconst DEFAULT_CALLBACK = () => undefined;\n\nfunction makeDefaultConfig(columns: ModelColumn[]): BaseFormatConfig {\n const { type, name } = columns[0];\n const column = { type, name };\n const config = {\n column,\n style: getDefaultStyleConfig(),\n ...getDefaultConditionConfigForType(type),\n };\n return config;\n}\n\nfunction RowFormatEditor(props: RowFormatEditorProps): JSX.Element {\n const {\n columns,\n config = makeDefaultConfig(columns),\n dh,\n onChange = DEFAULT_CALLBACK,\n } = props;\n\n const [selectedColumn, setColumn] = useState(\n columns.find(\n c => c.name === config.column.name && c.type === config.column.type\n ) ?? columns[0]\n );\n const [conditionConfig, setConditionConfig] = useState(\n getConditionConfig(config)\n );\n const [conditionValid, setConditionValid] = useState(false);\n const [selectedStyle, setStyle] = useState(config.style);\n\n const handleColumnChange = useCallback(\n value => {\n const newColumn = columns.find(({ name }) => name === value);\n if (newColumn !== undefined) {\n setColumn(newColumn);\n if (selectedColumn.type !== newColumn.type) {\n setConditionConfig(getDefaultConditionConfigForType(newColumn.type));\n setConditionValid(false);\n }\n } else {\n log.error(`Column ${value} not found.`);\n }\n },\n [columns, selectedColumn]\n );\n\n const handleConditionChange = useCallback(\n (updatedConditionConfig, isValid) => {\n log.debug('handleConditionChange', updatedConditionConfig, isValid);\n setConditionConfig(updatedConditionConfig);\n setConditionValid(isValid);\n },\n []\n );\n\n const handleStyleChange = useCallback(updatedStyleConfig => {\n log.debug('handleStyleChange', updatedStyleConfig);\n setStyle(updatedStyleConfig);\n }, []);\n\n useEffect(\n function updateRowFormat() {\n if (selectedColumn === undefined) {\n log.debug('Column is not selected, skip update.');\n return;\n }\n if (selectedStyle === undefined) {\n log.debug('Style is not selected, skip update.');\n return;\n }\n const { type, name } = selectedColumn;\n const column = { type, name };\n onChange(\n {\n column,\n style: selectedStyle,\n ...conditionConfig,\n },\n conditionValid\n );\n },\n [onChange, selectedColumn, selectedStyle, conditionConfig, conditionValid]\n );\n\n const columnInputOptions = columns.map(({ name }) => ({\n title: name,\n value: name,\n }));\n\n return (\n <div className=\"conditional-rule-editor form\">\n <div className=\"mb-2\">\n <label className=\"mb-0\">Format Row If</label>\n <ComboBox\n defaultValue={selectedColumn?.name}\n options={columnInputOptions}\n inputPlaceholder=\"Select a column\"\n spellCheck={false}\n onChange={handleColumnChange}\n searchPlaceholder=\"Filter columns\"\n />\n </div>\n\n {selectedColumn !== undefined && (\n <>\n <ConditionEditor\n column={selectedColumn}\n config={conditionConfig}\n dh={dh}\n onChange={handleConditionChange}\n />\n <StyleEditor config={selectedStyle} onChange={handleStyleChange} />\n </>\n )}\n </div>\n );\n}\n\nexport default RowFormatEditor;\n","import React, { useCallback, useState } from 'react';\nimport classNames from 'classnames';\nimport { Button } from '@deephaven/components';\nimport type { dh as DhType } from '@deephaven/jsapi-types';\nimport Log from '@deephaven/log';\nimport { FormatColumnWhereIcon, FormatRowWhereIcon } from '../icons';\nimport ColumnFormatEditor from './ColumnFormatEditor';\nimport RowFormatEditor from './RowFormatEditor';\nimport {\n BaseFormatConfig,\n FormatterType,\n FormattingRule,\n isSupportedColumn,\n ModelColumn,\n} from './ConditionalFormattingUtils';\nimport './ConditionalFormatEditor.scss';\n\nconst log = Log.module('ConditionalFormatEditor');\n\nexport type SaveCallback = (rule: FormattingRule) => void;\n\nexport type UpdateCallback = (rule?: FormattingRule) => void;\n\nexport type CancelCallback = () => void;\n\nexport interface ConditionalFormatEditorProps {\n dh: DhType;\n columns: readonly ModelColumn[];\n rule?: FormattingRule;\n onCancel?: CancelCallback;\n onSave?: SaveCallback;\n onUpdate?: UpdateCallback;\n}\n\nconst DEFAULT_CALLBACK = () => undefined;\n\nfunction getFormatterTypeIcon(option: FormatterType): JSX.Element | undefined {\n switch (option) {\n case FormatterType.CONDITIONAL:\n return <FormatColumnWhereIcon />;\n case FormatterType.ROWS:\n return <FormatRowWhereIcon />;\n }\n}\n\nfunction getFormatterTypeLabel(option: FormatterType): string {\n switch (option) {\n case FormatterType.CONDITIONAL:\n return 'Conditional';\n case FormatterType.ROWS:\n return 'Rows';\n }\n}\n\nconst formatterTypes = [FormatterType.CONDITIONAL, FormatterType.ROWS];\n\nfunction ConditionalFormatEditor(\n props: ConditionalFormatEditorProps\n): JSX.Element {\n const {\n columns: originalColumns,\n dh,\n onSave = DEFAULT_CALLBACK,\n onUpdate = DEFAULT_CALLBACK,\n onCancel = DEFAULT_CALLBACK,\n rule: defaultRule,\n } = props;\n\n const columns = originalColumns.filter(isSupportedColumn);\n\n const [selectedFormatter, setFormatter] = useState(\n defaultRule?.type ?? formatterTypes[0]\n );\n const [rule, setRule] = useState(defaultRule);\n const [isValid, setIsValid] = useState(false);\n\n const handleCancel = useCallback(() => {\n onCancel();\n }, [onCancel]);\n\n const handleSave = useCallback(() => {\n if (rule === undefined) {\n log.error('Rule is not defined.');\n return;\n }\n onSave(rule);\n }, [onSave, rule]);\n\n const handleFormatterChange = useCallback(value => {\n log.debug('handleFormatterChange', value);\n setFormatter(value);\n }, []);\n\n const handleRuleChange = useCallback(\n (ruleConfig, isRuleValid: boolean) => {\n log.debug('handleRuleChange', ruleConfig, isRuleValid, selectedFormatter);\n const updatedRule = {\n type: selectedFormatter,\n config: ruleConfig as BaseFormatConfig,\n };\n setRule(updatedRule);\n setIsValid(isRuleValid);\n onUpdate(isRuleValid ? updatedRule : undefined);\n },\n [onUpdate, selectedFormatter]\n );\n\n return (\n <div className=\"conditional-format-editor form\">\n <div className=\"mb-2\">\n <label className=\"mb-0\" htmlFor=\"formatter-select\">\n Select Formatter\n </label>\n\n <div className=\"formatter-list\">\n {formatterTypes.map((type, index) => (\n <div key={type} className=\"formatter-type\">\n <button\n type=\"button\"\n className={classNames('btn', 'btn-icon', 'btn-formatter-type', {\n active: type === selectedFormatter,\n })}\n data-index={index}\n onClick={() => handleFormatterChange(type)}\n >\n {getFormatterTypeIcon(type)}\n {getFormatterTypeLabel(type)}\n </button>\n </div>\n ))}\n </div>\n </div>\n {selectedFormatter === FormatterType.CONDITIONAL && (\n <ColumnFormatEditor\n columns={columns}\n dh={dh}\n config={rule?.config}\n onChange={handleRuleChange}\n />\n )}\n {selectedFormatter === FormatterType.ROWS && (\n <RowFormatEditor\n columns={columns}\n config={rule?.config}\n dh={dh}\n onChange={handleRuleChange}\n />\n )}\n <hr />\n <div className=\"d-flex justify-content-end my-3\">\n <Button kind=\"secondary\" onClick={handleCancel} className=\"mr-2\">\n Cancel\n </Button>\n <Button\n kind=\"primary\"\n onClick={handleSave}\n disabled={rule === undefined || !isValid}\n >\n Done\n </Button>\n </div>\n </div>\n );\n}\n\nexport default ConditionalFormatEditor;\n","import * as monaco from 'monaco-editor';\nimport { Language } from './Language';\n\nconst id = 'python';\n\nconst conf: monaco.languages.LanguageConfiguration = {\n comments: {\n lineComment: '#',\n blockComment: [\"'''\", \"'''\"],\n },\n brackets: [\n ['{', '}'],\n ['[', ']'],\n ['(', ')'],\n ],\n autoClosingPairs: [\n { open: '{', close: '}' },\n { open: '[', close: ']' },\n { open: '(', close: ')' },\n { open: '\"', close: '\"', notIn: ['string'] },\n { open: \"'\", close: \"'\", notIn: ['string', 'comment'] },\n ],\n surroundingPairs: [\n { open: '{', close: '}' },\n { open: '[', close: ']' },\n { open: '(', close: ')' },\n { open: '\"', close: '\"' },\n { open: \"'\", close: \"'\" },\n ],\n onEnterRules: [\n {\n beforeText: /^\\s*(?:def|class|for|if|elif|else|while|try|with|finally|except|async).*?:\\s*$/,\n action: { indentAction: 1 }, // see monaco.languages.IndentAction.Indent\n },\n ],\n folding: {\n offSide: true,\n markers: {\n start: /^\\s*#region\\b/,\n end: /^\\s*#endregion\\b/,\n },\n },\n};\n\nconst language: monaco.languages.IMonarchLanguage = {\n // Set defaultToken to invalid to see what you do not tokenize yet\n // defaultToken: 'invalid',\n\n keywords: [\n 'and',\n 'del',\n 'from',\n 'not',\n 'while',\n 'as',\n 'elif',\n 'global',\n 'or',\n 'with',\n 'assert',\n 'else',\n 'if',\n 'pass',\n 'yield',\n 'break',\n 'except',\n 'import',\n 'print',\n 'exec',\n 'in',\n 'raise',\n 'continue',\n 'finally',\n 'is',\n 'return',\n 'for',\n 'try',\n ':',\n '=',\n 'isinstance',\n '__debug__',\n ],\n\n storage: ['class', 'def', 'async', 'lambda'],\n\n operators: [\n '+',\n '-',\n '*',\n '**',\n '/',\n '//',\n '%',\n '<<',\n '>>',\n '&',\n '|',\n '^',\n '~',\n '<',\n '>',\n '<=',\n '>=',\n '==',\n '!=',\n '<>',\n '+=',\n '-=',\n '*=',\n '/',\n '//=',\n '%=',\n '&=',\n '|=',\n '^=',\n '>>=',\n '<<=',\n '**=',\n ],\n brackets: [\n { open: '{', close: '}', token: 'delimiter.curly' },\n { open: '[', close: ']', token: 'delimiter.square' },\n { open: '(', close: ')', token: 'delimiter.parenthesis' },\n ],\n\n // operator symbols\n symbols: /[=><!~&|+\\-*/^%]+/,\n delimiters: /[;=.@:,`]/,\n\n // strings\n escapes: /\\\\(?:[abfnrtv\\\\\"'\\n\\r]|x[0-9A-Fa-f]{2}|[0-7]{3}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8}|N\\{\\w+\\})/,\n rawpre: /(?:[rR]|ur|Ur|uR|UR|br|Br|bR|BR)/,\n strpre: /(?:[buBU])/,\n\n // The main tokenizer for our languages\n tokenizer: {\n root: [\n // strings: need to check first due to the prefix\n [\n /@strpre?(\"\"\"|''')/,\n { token: 'string.delim', bracket: '@open', next: '@mstring.$1' },\n ],\n [/@strpre?\"([^\"\\\\]|\\\\.)*$/, 'string.invalid'], // non-teminated string\n [/@strpre?'([^'\\\\]|\\\\.)*$/, 'string.invalid'], // non-teminated string\n [\n /@strpre?([\"])/,\n {\n token: 'string.delim',\n bracket: '@open',\n next: '@sstring.$1',\n nextEmbedded: 'deephavenDb',\n },\n ],\n [\n /@strpre?([\"'])/,\n { token: 'string.delim', bracket: '@open', next: '@string.$1' },\n ],\n\n [\n /@rawpre(\"\"\"|''')/,\n { token: 'string.delim', bracket: '@open', next: '@mrawstring.$1' },\n ],\n [/@rawpre\"([^\"\\\\]|\\\\.)*$/, 'string.invalid'], // non-teminated string\n [/@rawpre'([^'\\\\]|\\\\.)*$/, 'string.invalid'], // non-teminated string\n [\n /@rawpre([\"'])/,\n { token: 'string.delim', bracket: '@open', next: '@rawstring.$1' },\n ],\n\n // identifiers and keywords\n [/__[\\w$]*/, 'predefined'],\n\n [\n /[a-z_$][\\w$]*/,\n {\n cases: {\n '@keywords': 'keyword',\n '@storage': 'storage',\n '@default': 'identifier',\n },\n },\n ],\n\n [\n /[A-Z][\\w]*/,\n {\n cases: {\n '~[A-Z0-9_]+': 'constructor.identifier',\n '@default': 'namespace.identifier',\n },\n },\n ], // to show class names nicely\n\n // whitespace\n { include: '@whitespace' },\n\n // delimiters and operators\n [/[{}()[\\]]/, '@brackets'],\n [\n /@symbols/,\n {\n cases: {\n '@keywords': 'keyword',\n '@operators': 'operator',\n '@default': '',\n },\n },\n ],\n\n // numbers\n [/\\d*\\.\\d+([eE][-+]?\\d+)?/, 'number.float'],\n [/0[xX][0-9a-fA-F]+[lL]?/, 'number.hex'],\n [/0[bB][0-1]+[lL]?/, 'number.binary'],\n [/(0[oO][0-7]+|0[0-7]+)[lL]?/, 'number.octal'],\n [/(0|[1-9]\\d*)[lL]?/, 'number'],\n\n // delimiter: after number because of .\\d floats\n [':', { token: 'keyword', bracket: '@open' }], // bracket for indentation\n [\n /@delimiters/,\n {\n cases: {\n '@keywords': 'keyword',\n '@default': 'delimiter',\n },\n },\n ],\n ],\n\n comment: [\n [/[^/*]+/, 'comment'],\n [/\\/\\*/, 'comment', '@push'], // nested comment\n ['\\\\*/', 'comment', '@pop'],\n [/[/*]/, 'comment'],\n ],\n\n // Regular strings\n mstring: [\n { include: '@strcontent' },\n [\n /\"\"\"|'''/,\n {\n cases: {\n '$#==$S2': {\n token: 'string.delim',\n bracket: '@close',\n next: '@pop',\n },\n '@default': { token: 'string' },\n },\n },\n ],\n [/[\"']/, 'string'],\n [/./, 'string.invalid'],\n ],\n\n sstring: [\n { include: '@strcontent' },\n [\n /[\"]/,\n {\n token: 'string.delim',\n bracket: '@close',\n next: '@pop',\n nextEmbedded: '@pop',\n },\n ],\n [/./, 'string.invalid'],\n ],\n\n string: [\n { include: '@strcontent' },\n [/[']/, { token: 'string.delim', bracket: '@close', next: '@pop' }],\n [/./, 'string.invalid'],\n ],\n\n strcontent: [\n [/[^\\\\\"']+/, 'string'],\n [/\\\\$/, 'string.escape'],\n [/@escapes/, 'string.escape'],\n [/\\\\./, 'string.escape.invalid'],\n ],\n\n // Raw strings: we distinguish them to color escape sequences correctly\n mrawstring: [\n { include: '@rawstrcontent' },\n [\n /\"\"\"|'''/,\n {\n cases: {\n '$#==$S2': {\n token: 'string.delim',\n bracket: '@close',\n next: '@pop',\n },\n '@default': { token: 'string' },\n },\n },\n ],\n [/[\"']/, 'string'],\n [/./, 'string.invalid'],\n ],\n\n rawstring: [\n { include: '@rawstrcontent' },\n [\n /[\"']/,\n {\n cases: {\n '$#==$S2': {\n token: 'string.delim',\n bracket: '@close',\n next: '@pop',\n },\n '@default': { token: 'string' },\n },\n },\n ],\n [/./, 'string.invalid'],\n ],\n\n rawstrcontent: [\n [/[^\\\\\"']+/, 'string'],\n [/\\\\[\"']/, 'string'],\n [/\\\\u[0-9A-Fa-f]{4}/, 'string.escape'],\n [/\\\\/, 'string'],\n ],\n\n whitespace: [\n [/\\s+/, 'white'],\n [/(^#.*$)/, 'comment'],\n [/'''/, 'string', '@endDocString'],\n [/\"\"\"/, 'string', '@endDblDocString'],\n ],\n endDocString: [\n [/[^']+/, 'string'],\n [/\\\\'/, 'string'],\n [/'''/, 'string', '@popall'],\n [/'/, 'string'],\n ],\n endDblDocString: [\n [/[^\"]+/, 'string'],\n [/\\\\\"/, 'string'],\n [/\"\"\"/, 'string', '@popall'],\n [/\"/, 'string'],\n ],\n },\n};\n\nconst lang: Language = { id, conf, language };\nexport default lang;\n","import * as monaco from 'monaco-editor';\nimport { Language } from './Language';\n\nconst id = 'groovy';\n\nconst conf: monaco.languages.LanguageConfiguration = {\n comments: {\n lineComment: '//',\n blockComment: ['/*', '*/'],\n },\n brackets: [\n ['{', '}'],\n ['[', ']'],\n ['(', ')'],\n ],\n autoClosingPairs: [\n { open: '{', close: '}' },\n { open: '[', close: ']' },\n { open: '(', close: ')' },\n { open: '\"', close: '\"', notIn: ['string'] },\n { open: \"'\", close: \"'\", notIn: ['string', 'comment'] },\n ],\n surroundingPairs: [\n { open: '{', close: '}' },\n { open: '[', close: ']' },\n { open: '(', close: ')' },\n { open: '\"', close: '\"' },\n { open: \"'\", close: \"'\" },\n ],\n onEnterRules: [\n {\n beforeText: /^\\s*(?:def|class|for|if|elif|else|while|try|with|finally|except|async).*?:\\s*$/,\n action: { indentAction: 1 }, // see monaco.languages.IndentAction.Indent\n },\n ],\n folding: {\n offSide: true,\n markers: {\n start: /^\\s*#region\\b/,\n end: /^\\s*#endregion\\b/,\n },\n },\n};\n\nconst language: monaco.languages.IMonarchLanguage = {\n // Set defaultToken to invalid to see what you do not tokenize yet\n // defaultToken: 'invalid',\n\n keywords: [\n 'and',\n 'del',\n 'from',\n 'not',\n 'while',\n 'as',\n 'elif',\n 'global',\n 'or',\n 'with',\n 'assert',\n 'else',\n 'if',\n 'pass',\n 'yield',\n 'break',\n 'except',\n 'import',\n 'print',\n 'println',\n 'class',\n 'exec',\n 'in',\n 'raise',\n 'continue',\n 'finally',\n 'is',\n 'return',\n 'def',\n 'for',\n 'lambda',\n 'try',\n ':',\n '=',\n 'isinstance',\n '__debug__',\n ],\n\n operators: [\n '+',\n '-',\n '*',\n '**',\n '/',\n '//',\n '%',\n '<<',\n '>>',\n '&',\n '|',\n '^',\n '~',\n '<',\n '>',\n '<=',\n '>=',\n '==',\n '!=',\n '<>',\n '+=',\n '-=',\n '*=',\n '/',\n '//=',\n '%=',\n '&=',\n '|=',\n '^=',\n '>>=',\n '<<=',\n '**=',\n ],\n\n brackets: [\n { open: '{', close: '}', token: 'delimiter.curly' },\n { open: '[', close: ']', token: 'delimiter.square' },\n { open: '(', close: ')', token: 'delimiter.parenthesis' },\n ],\n\n // operator symbols\n symbols: /[=><!~&|+\\-*/^%]+/,\n delimiters: /[;=.@:,`]/,\n\n // strings\n escapes: /\\\\(?:[abfnrtv\\\\\"'\\n\\r]|x[0-9A-Fa-f]{2}|[0-7]{3}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8}|N\\{\\w+\\})/,\n rawpre: /(?:[rR]|ur|Ur|uR|UR|br|Br|bR|BR)/,\n strpre: /(?:[buBU])/,\n\n // The main tokenizer for our languages\n tokenizer: {\n root: [\n // strings: need to check first due to the prefix\n [\n /@strpre?(\"\"\"|''')/,\n { token: 'string.delim', bracket: '@open', next: '@mstring.$1' },\n ],\n [/@strpre?\"([^\"\\\\]|\\\\.)*$/, 'string.invalid'], // non-teminated string\n [/@strpre?'([^'\\\\]|\\\\.)*$/, 'string.invalid'], // non-teminated string\n [\n /@strpre?([\"])/,\n {\n token: 'string.delim',\n bracket: '@open',\n next: '@sstring.$1',\n nextEmbedded: 'deephavenDb',\n },\n ],\n [\n /@strpre?([\"'])/,\n { token: 'string.delim', bracket: '@open', next: '@string.$1' },\n ],\n\n [\n /@rawpre(\"\"\"|''')/,\n { token: 'string.delim', bracket: '@open', next: '@mrawstring.$1' },\n ],\n [/@rawpre\"([^\"\\\\]|\\\\.)*$/, 'string.invalid'], // non-teminated string\n [/@rawpre'([^'\\\\]|\\\\.)*$/, 'string.invalid'], // non-teminated string\n [\n /@rawpre([\"'])/,\n { token: 'string.delim', bracket: '@open', next: '@rawstring.$1' },\n ],\n\n // identifiers and keywords\n [/__[\\w$]*/, 'predefined'],\n [\n /[a-z_$][\\w$]*/,\n {\n cases: {\n '@keywords': 'keyword',\n '@default': 'identifier',\n },\n },\n ],\n [\n /[A-Z][\\w]*/,\n {\n cases: {\n '~[A-Z0-9_]+': 'constructor.identifier',\n '@default': 'namespace.identifier',\n },\n },\n ], // to show class names nicely\n\n // whitespace\n { include: '@whitespace' },\n\n // delimiters and operators\n [/[{}()[\\]]/, '@brackets'],\n [\n /@symbols/,\n {\n cases: {\n '@keywords': 'keyword',\n '@operators': 'operator',\n '@default': '',\n },\n },\n ],\n\n // numbers\n [/\\d*\\.\\d+([eE][-+]?\\d+)?/, 'number.float'],\n [/0[xX][0-9a-fA-F]+[lL]?/, 'number.hex'],\n [/0[bB][0-1]+[lL]?/, 'number.binary'],\n [/(0[oO][0-7]+|0[0-7]+)[lL]?/, 'number.octal'],\n [/(0|[1-9]\\d*)[lL]?/, 'number'],\n\n // delimiter: after number because of .\\d floats\n [':', { token: 'keyword', bracket: '@open' }], // bracket for indentation\n [\n /@delimiters/,\n {\n cases: {\n '@keywords': 'keyword',\n '@default': 'delimiter',\n },\n },\n ],\n ],\n\n // Regular strings\n mstring: [\n { include: '@strcontent' },\n [\n /\"\"\"|'''/,\n {\n cases: {\n '$#==$S2': {\n token: 'string.delim',\n bracket: '@close',\n next: '@pop',\n },\n '@default': { token: 'string' },\n },\n },\n ],\n [/[\"']/, 'string'],\n [/./, 'string.invalid'],\n ],\n\n sstring: [\n { include: '@strcontent' },\n [\n /[\"]/,\n {\n token: 'string.delim',\n bracket: '@close',\n next: '@pop',\n nextEmbedded: '@pop',\n },\n ],\n [/./, 'string.invalid'],\n ],\n\n string: [\n { include: '@strcontent' },\n [/[']/, { token: 'string.delim', bracket: '@close', next: '@pop' }],\n [/./, 'string.invalid'],\n ],\n\n strcontent: [\n [/[^\\\\\"']+/, 'string'],\n [/\\\\$/, 'string.escape'],\n [/@escapes/, 'string.escape'],\n [/\\\\./, 'string.escape.invalid'],\n ],\n\n // Raw strings: we distinguish them to color escape sequences correctly\n mrawstring: [\n { include: '@rawstrcontent' },\n [\n /\"\"\"|'''/,\n {\n cases: {\n '$#==$S2': {\n token: 'string.delim',\n bracket: '@close',\n next: '@pop',\n },\n '@default': { token: 'string' },\n },\n },\n ],\n [/[\"']/, 'string'],\n [/./, 'string.invalid'],\n ],\n\n rawstring: [\n { include: '@rawstrcontent' },\n [\n /[\"']/,\n {\n cases: {\n '$#==$S2': {\n token: 'string.delim',\n bracket: '@close',\n next: '@pop',\n },\n '@default': { token: 'string' },\n },\n },\n ],\n [/./, 'string.invalid'],\n ],\n\n rawstrcontent: [\n [/[^\\\\\"']+/, 'string'],\n [/\\\\[\"']/, 'string'],\n [/\\\\u[0-9A-Fa-f]{4}/, 'string.escape'],\n [/\\\\/, 'string'],\n ],\n\n whitespace: [\n [/[ \\t\\r\\n]+/, ''],\n [/\\/\\*\\*(?!\\/)/, 'comment.doc', '@doccomment'],\n [/\\/\\*/, 'comment', '@comment'],\n [/\\/\\/.*$/, 'comment'],\n ],\n\n comment: [\n [/[^/*]+/, 'comment'],\n [/\\*\\//, 'comment', '@pop'],\n [/[/*]/, 'comment'],\n ],\n\n doccomment: [\n [/[^/*]+/, 'comment.doc'],\n [/\\*\\//, 'comment.doc', '@pop'],\n [/[/*]/, 'comment.doc'],\n ],\n },\n};\n\nconst lang: Language = { id, conf, language };\nexport default lang;\n","/*---------------------------------------------------------------------------------------------\n * The MIT License (MIT)\n *\n * Copyright (c) Microsoft Corporation\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n *\n * The base version of this file is licensed under the MIT License (as above)\n * and was sourced from microsoft's monaco languages repository:\n * - https://github.com/microsoft/monaco-languages/blob/main/src/scala/scala.ts\n *--------------------------------------------------------------------------------------------*/\n\nimport * as monaco from 'monaco-editor';\nimport { Language } from './Language';\n\nconst id = 'scala';\n\nconst conf: monaco.languages.LanguageConfiguration = {\n /*\n * `...` is allowed as an identifier.\n * $ is allowed in identifiers.\n * unary_<op> is allowed as an identifier.\n * <name>_= is allowed as an identifier.\n */\n wordPattern: /(unary_[@~!#%^&*()\\-=+\\\\|:<>/?]+)|([a-zA-Z_$][\\w$]*?_=)|(`[^`]+`)|([a-zA-Z_$][\\w$]*)/g,\n comments: {\n lineComment: '//',\n blockComment: ['/*', '*/'],\n },\n brackets: [\n ['{', '}'],\n ['[', ']'],\n ['(', ')'],\n ],\n autoClosingPairs: [\n { open: '{', close: '}' },\n { open: '[', close: ']' },\n { open: '(', close: ')' },\n { open: '\"', close: '\"' },\n { open: \"'\", close: \"'\" },\n ],\n surroundingPairs: [\n { open: '{', close: '}' },\n { open: '[', close: ']' },\n { open: '(', close: ')' },\n { open: '\"', close: '\"' },\n { open: \"'\", close: \"'\" },\n ],\n folding: {\n markers: {\n start: /^\\s*\\/\\/\\s*(?:(?:#?region\\b)|(?:<editor-fold\\b))/,\n end: /^\\s*\\/\\/\\s*(?:(?:#?endregion\\b)|(?:<\\/editor-fold>))/,\n },\n },\n};\n\nconst language: monaco.languages.IMonarchLanguage = {\n // tokenPostfix: '.scala',\n\n // We can't easily add everything from Dotty, but we can at least add some of its keywords\n keywords: [\n 'asInstanceOf',\n 'catch',\n 'class',\n 'classOf',\n 'def',\n 'do',\n 'else',\n 'extends',\n 'finally',\n 'for',\n 'foreach',\n 'forSome',\n 'if',\n 'import',\n 'isInstanceOf',\n 'macro',\n 'match',\n 'new',\n 'object',\n 'package',\n 'return',\n 'throw',\n 'trait',\n 'try',\n 'type',\n 'until',\n 'val',\n 'var',\n 'while',\n 'with',\n 'yield',\n\n // Dotty-specific:\n 'given',\n 'enum',\n 'then',\n ],\n\n // Dotty-specific:\n softKeywords: ['as', 'export', 'extension', 'end', 'derives', 'on'],\n\n constants: ['true', 'false', 'null', 'this', 'super'],\n\n modifiers: [\n 'abstract',\n 'final',\n 'implicit',\n 'lazy',\n 'override',\n 'private',\n 'protected',\n 'sealed',\n ],\n\n // Dotty-specific:\n softModifiers: ['inline', 'opaque', 'open', 'transparent', 'using'],\n\n name: /(?:[a-z_$][\\w$]*|`[^`]+`)/,\n type: /(?:[A-Z][\\w$]*)/,\n\n // we include these common regular expressions\n symbols: /[=><!~?:&|+\\-*/^\\\\%@#]+/,\n digits: /\\d+(_+\\d+)*/,\n hexdigits: /[[0-9a-fA-F]+(_+[0-9a-fA-F]+)*/,\n\n // C# style strings\n escapes: /\\\\(?:[btnfr\\\\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,\n\n fstring_conv: /[bBhHsScCdoxXeEfgGaAt]|[Tn](?:[HIklMSLNpzZsQ]|[BbhAaCYyjmde]|[RTrDFC])/,\n\n // The main tokenizer for our languages\n tokenizer: {\n root: [\n // strings\n [\n /\\braw\"\"\"/,\n { token: 'string.quote', bracket: '@open', next: '@rawstringt' },\n ],\n [\n /\\braw\"/,\n { token: 'string.quote', bracket: '@open', next: '@rawstring' },\n ],\n\n [\n /\\bs\"\"\"/,\n { token: 'string.quote', bracket: '@open', next: '@sstringt' },\n ],\n [/\\bs\"/, { token: 'string.quote', bracket: '@open', next: '@sstring' }],\n [\n /\\bf\"\"\"\"/,\n { token: 'string.quote', bracket: '@open', next: '@fstringt' },\n ],\n [/\\bf\"/, { token: 'string.quote', bracket: '@open', next: '@fstring' }],\n [/\"\"\"/, { token: 'string.quote', bracket: '@open', next: '@stringt' }],\n [/\"/, { token: 'string.quote', bracket: '@open', next: '@string' }],\n\n // numbers\n [/(@digits)[eE]([-+]?(@digits))?[fFdD]?/, 'number.float', '@allowMethod'],\n [\n /(@digits)\\.(@digits)([eE][-+]?(@digits))?[fFdD]?/,\n 'number.float',\n '@allowMethod',\n ],\n [/0[xX](@hexdigits)[Ll]?/, 'number.hex', '@allowMethod'],\n [/(@digits)[fFdD]/, 'number.float', '@allowMethod'],\n [/(@digits)[lL]?/, 'number', '@allowMethod'],\n [/\\b_\\*/, 'key'],\n [/\\b(_)\\b/, 'keyword', '@allowMethod'],\n\n // identifiers and keywords\n [/\\bimport\\b/, 'keyword', '@import'],\n [/\\b(case)([ \\t]+)(class)\\b/, ['keyword.modifier', 'white', 'keyword']],\n [/\\bcase\\b/, 'keyword', '@case'],\n [/\\bva[lr]\\b/, 'keyword', '@vardef'],\n [\n /\\b(def)([ \\t]+)((?:unary_)?@symbols|@name(?:_=)|@name)/,\n ['keyword', 'white', 'identifier'],\n ],\n [/@name(?=[ \\t]*:(?!:))/, 'variable'],\n [\n /(\\.)(@name|@symbols)/,\n [\n { token: 'operator' },\n {\n token: '@rematch',\n next: '@allowMethod',\n },\n ],\n ],\n [/([{(])(\\s*)(@name(?=\\s*=>))/, ['@brackets', 'white', 'variable']],\n [\n /@name/,\n {\n cases: {\n '@keywords': 'keyword',\n '@softKeywords': 'keyword',\n '@modifiers': 'keyword.modifier',\n '@softModifiers': 'keyword.modifier',\n '@constants': {\n token: 'constant',\n next: '@allowMethod',\n },\n '@default': {\n token: 'identifier',\n next: '@allowMethod',\n },\n },\n },\n ],\n [/@type/, 'type', '@allowMethod'],\n\n // whitespace\n { include: '@whitespace' },\n\n // @ annotations.\n [/@[a-zA-Z_$][\\w$]*(?:\\.[a-zA-Z_$][\\w$]*)*/, 'annotation'],\n\n // delimiters and operators\n [/[{(]/, '@brackets'],\n [/[})]/, '@brackets', '@allowMethod'],\n [/\\[/, 'operator.square'],\n [/](?!\\s*(?:va[rl]|def|type)\\b)/, 'operator.square', '@allowMethod'],\n [/]/, 'operator.square'],\n [/([=-]>|<-|>:|<:|:>|<%)(?=[\\s\\w()[\\]{},.\"'`])/, 'keyword'],\n [/@symbols/, 'operator'],\n\n // delimiter: after number because of .\\d floats\n [/[;,.]/, 'delimiter'],\n\n // symbols\n [/'[a-zA-Z$][\\w$]*(?!')/, 'attribute.name'],\n\n // characters\n [/'[^\\\\']'/, 'string', '@allowMethod'],\n [\n /(')(@escapes)(')/,\n [\n { token: 'string' },\n { token: 'string.escape' },\n {\n token: 'string',\n next: '@allowMethod',\n },\n ],\n ],\n [/'/, 'string.invalid'],\n ],\n\n import: [\n [/;/, 'delimiter', '@pop'],\n [/^|$/, '', '@pop'],\n [/[ \\t]+/, 'white'],\n [/[\\n\\r]+/, 'white', '@pop'],\n [/\\/\\*/, 'comment', '@comment'],\n [/@name|@type/, 'type'],\n [/[(){}]/, '@brackets'],\n [/[[\\]]/, 'operator.square'],\n [/[.,]/, 'delimiter'],\n ],\n\n allowMethod: [\n [/^|$/, '', '@pop'],\n [/[ \\t]+/, 'white'],\n [/[\\n\\r]+/, 'white', '@pop'],\n [/\\/\\*/, 'comment', '@comment'],\n [/(?==>[\\s\\w([{])/, 'keyword', '@pop'],\n [\n /(@name|@symbols)(?=[ \\t]*[[({\"'`]|[ \\t]+(?:[+-]?\\.?\\d|\\w))/,\n {\n cases: {\n '@keywords': { token: 'keyword', next: '@pop' },\n '->|<-|>:|<:|<%': { token: 'keyword', next: '@pop' },\n '@default': { token: '@rematch', next: '@pop' },\n },\n },\n ],\n ['', '', '@pop'],\n ],\n\n comment: [\n [/[^/*]+/, 'comment'],\n [/\\/\\*/, 'comment', '@push'], // nested comment\n [/\\*\\//, 'comment', '@pop'],\n [/[/*]/, 'comment'],\n ],\n\n case: [\n [/\\b_\\*/, 'key'],\n [/\\b(_|true|false|null|this|super)\\b/, 'keyword', '@allowMethod'],\n [/\\bif\\b|=>/, 'keyword', '@pop'],\n [/`[^`]+`/, 'identifier', '@allowMethod'],\n [/@name/, 'variable', '@allowMethod'],\n [/:::?|\\||@(?![a-z_$])/, 'keyword'],\n { include: '@root' },\n ],\n\n vardef: [\n [/\\b_\\*/, 'key'],\n [/\\b(_|true|false|null|this|super)\\b/, 'keyword'],\n [/@name/, 'variable'],\n [/:::?|\\||@(?![a-z_$])/, 'keyword'],\n [/=|:(?!:)/, 'operator', '@pop'],\n [/$/, 'white', '@pop'],\n { include: '@root' },\n ],\n\n string: [\n [/[^\\\\\"\\n\\r]+/, 'string'],\n [/@escapes/, 'string.escape'],\n [/\\\\./, 'string.escape.invalid'],\n [\n /\"/,\n {\n token: 'string.quote',\n bracket: '@close',\n switchTo: '@allowMethod',\n },\n ],\n ],\n\n stringt: [\n [/[^\\\\\"\\n\\r]+/, 'string'],\n [/@escapes/, 'string.escape'],\n [/\\\\./, 'string.escape.invalid'],\n [/\"(?=\"\"\")/, 'string'],\n [\n /\"\"\"/,\n {\n token: 'string.quote',\n bracket: '@close',\n switchTo: '@allowMethod',\n },\n ],\n [/\"/, 'string'],\n ],\n\n fstring: [\n [/@escapes/, 'string.escape'],\n [\n /\"/,\n {\n token: 'string.quote',\n bracket: '@close',\n switchTo: '@allowMethod',\n },\n ],\n [/\\$\\$/, 'string'],\n [/(\\$)([a-z_]\\w*)/, ['operator', 'identifier']],\n [/\\$\\{/, 'operator', '@interp'],\n [/%%/, 'string'],\n [\n /(%)([-#+ 0,(])(\\d+|\\.\\d+|\\d+\\.\\d+)(@fstring_conv)/,\n ['metatag', 'keyword.modifier', 'number', 'metatag'],\n ],\n [\n /(%)(\\d+|\\.\\d+|\\d+\\.\\d+)(@fstring_conv)/,\n ['metatag', 'number', 'metatag'],\n ],\n [\n /(%)([-#+ 0,(])(@fstring_conv)/,\n ['metatag', 'keyword.modifier', 'metatag'],\n ],\n [/(%)(@fstring_conv)/, ['metatag', 'metatag']],\n [/./, 'string'],\n ],\n\n fstringt: [\n [/@escapes/, 'string.escape'],\n [/\"(?=\"\"\")/, 'string'],\n [\n /\"\"\"/,\n {\n token: 'string.quote',\n bracket: '@close',\n switchTo: '@allowMethod',\n },\n ],\n [/\\$\\$/, 'string'],\n [/(\\$)([a-z_]\\w*)/, ['operator', 'identifier']],\n [/\\$\\{/, 'operator', '@interp'],\n [/%%/, 'string'],\n [\n /(%)([-#+ 0,(])(\\d+|\\.\\d+|\\d+\\.\\d+)(@fstring_conv)/,\n ['metatag', 'keyword.modifier', 'number', 'metatag'],\n ],\n [\n /(%)(\\d+|\\.\\d+|\\d+\\.\\d+)(@fstring_conv)/,\n ['metatag', 'number', 'metatag'],\n ],\n [\n /(%)([-#+ 0,(])(@fstring_conv)/,\n ['metatag', 'keyword.modifier', 'metatag'],\n ],\n [/(%)(@fstring_conv)/, ['metatag', 'metatag']],\n [/./, 'string'],\n ],\n\n sstring: [\n [/@escapes/, 'string.escape'],\n [\n /\"/,\n {\n token: 'string.quote',\n bracket: '@close',\n switchTo: '@allowMethod',\n },\n ],\n [/\\$\\$/, 'string'],\n [/(\\$)([a-z_]\\w*)/, ['operator', 'identifier']],\n [/\\$\\{/, 'operator', '@interp'],\n [/./, 'string'],\n ],\n\n sstringt: [\n [/@escapes/, 'string.escape'],\n [/\"(?=\"\"\")/, 'string'],\n [\n /\"\"\"/,\n {\n token: 'string.quote',\n bracket: '@close',\n switchTo: '@allowMethod',\n },\n ],\n [/\\$\\$/, 'string'],\n [/(\\$)([a-z_]\\w*)/, ['operator', 'identifier']],\n [/\\$\\{/, 'operator', '@interp'],\n [/./, 'string'],\n ],\n\n interp: [\n [/{/, 'operator', '@push'],\n [/}/, 'operator', '@pop'],\n { include: '@root' },\n ],\n\n rawstring: [\n [/[^\"]/, 'string'],\n [\n /\"/,\n {\n token: 'string.quote',\n bracket: '@close',\n switchTo: '@allowMethod',\n },\n ],\n ],\n\n rawstringt: [\n [/[^\"]/, 'string'],\n [/\"(?=\"\"\")/, 'string'],\n [\n /\"\"\"/,\n {\n token: 'string.quote',\n bracket: '@close',\n switchTo: '@allowMethod',\n },\n ],\n [/\"/, 'string'],\n ],\n\n whitespace: [\n [/[ \\t\\r\\n]+/, 'white'],\n [/\\/\\*/, 'comment', '@comment'],\n [/\\/\\/.*$/, 'comment'],\n ],\n },\n};\n\nconst lang: Language = { id, conf, language };\nexport default lang;\n","import * as monaco from 'monaco-editor';\nimport { Language } from './Language';\n\n/* eslint no-useless-escape: \"off\" */\nconst id = 'deephavenDb';\n\nconst conf: monaco.languages.LanguageConfiguration = {\n comments: {\n lineComment: '#',\n blockComment: [\"'''\", \"'''\"],\n },\n brackets: [\n ['{', '}'],\n ['[', ']'],\n ['(', ')'],\n ],\n autoClosingPairs: [\n { open: '{', close: '}' },\n { open: '[', close: ']' },\n { open: '(', close: ')' },\n { open: '\"', close: '\"', notIn: ['string'] },\n { open: \"'\", close: \"'\", notIn: ['string', 'comment'] },\n ],\n surroundingPairs: [\n { open: '{', close: '}' },\n { open: '[', close: ']' },\n { open: '(', close: ')' },\n { open: '\"', close: '\"' },\n { open: \"'\", close: \"'\" },\n ],\n onEnterRules: [\n {\n beforeText: /^\\s*(?:def|class|for|if|elif|else|while|try|with|finally|except|async).*?:\\s*$/,\n action: { indentAction: 1 }, // see monaco.languages.IndentAction.Indent\n },\n ],\n folding: {\n offSide: true,\n markers: {\n start: /^\\s*#region\\b/,\n end: /^\\s*#endregion\\b/,\n },\n },\n};\n\nconst language: monaco.languages.IMonarchLanguage = {\n tokenPostfix: '.js',\n\n keywords: [\n 'boolean',\n 'break',\n 'byte',\n 'case',\n 'catch',\n 'char',\n 'class',\n 'const',\n 'continue',\n 'debugger',\n 'default',\n 'delete',\n 'do',\n 'double',\n 'else',\n 'enum',\n 'export',\n 'extends',\n 'false',\n 'final',\n 'finally',\n 'float',\n 'for',\n 'function',\n 'goto',\n 'if',\n 'implements',\n 'import',\n 'in',\n 'instanceof',\n 'int',\n 'interface',\n 'long',\n 'native',\n 'new',\n 'null',\n 'package',\n 'private',\n 'protected',\n 'public',\n 'return',\n 'short',\n 'static',\n 'super',\n 'switch',\n 'synchronized',\n 'this',\n 'throw',\n 'throws',\n 'transient',\n 'true',\n 'try',\n 'typeof',\n 'var',\n 'void',\n 'volatile',\n 'while',\n 'with',\n ],\n\n builtins: ['define', 'require', 'window', 'document', 'undefined'],\n\n operators: [\n '=',\n '>',\n '<',\n '!',\n '~',\n '?',\n ':',\n '==',\n '<=',\n '>=',\n '!=',\n '&&',\n '||',\n '++',\n '--',\n '+',\n '-',\n '*',\n '/',\n '&',\n '|',\n '^',\n '%',\n '<<',\n '>>',\n '>>>',\n '+=',\n '-=',\n '*=',\n '/=',\n '&=',\n '|=',\n '^=',\n '%=',\n '<<=',\n '>>=',\n '>>>=',\n ],\n\n // define our own brackets as '<' and '>' do not match in javascript\n brackets: [\n { open: '{', close: '}', token: 'delimiter.curly' },\n { open: '[', close: ']', token: 'delimiter.bracket' },\n { open: '(', close: ')', token: 'delimiter.parenthesis' },\n ],\n\n // common regular expressions\n symbols: /[~!@#%\\^&*-+=|\\\\:`<>.?\\/]+/,\n escapes: /\\\\(?:[btnfr\\\\\"']|[0-7][0-7]?|[0-3][0-7]{2})/,\n exponent: /[eE][\\-+]?[0-9]+/,\n\n regexpctl: /[(){}\\[\\]\\$\\^|\\-*+?\\.]/,\n regexpesc: /\\\\(?:[bBdDfnrstvwWn0\\\\\\/]|@regexpctl|c[A-Z]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})/,\n\n tokenizer: {\n root: [\n // identifiers and keywords\n [\n /([a-zA-Z_\\$][\\w\\$]*)(\\s*)(:?)/,\n {\n cases: {\n '$1@keywords': ['keyword', 'white', 'delimiter'],\n $3: ['key.identifier', 'white', 'delimiter'], // followed by :\n '$1@builtins': ['predefined.identifier', 'white', 'delimiter'],\n '@default': ['identifier', 'white', 'delimiter'],\n },\n },\n ],\n\n // whitespace\n { include: '@whitespace' },\n\n // regular expression: ensure it is terminated before beginning (otherwise it is an opeator)\n [\n /\\/(?=([^\\\\\\/]|\\\\.)+\\/)/,\n { token: 'regexp.slash', bracket: '@open', next: '@regexp' },\n ],\n\n // delimiters and operators\n [/[{}()\\[\\]]/, '@brackets'],\n [/[;,.]/, 'delimiter'],\n [\n /@symbols/,\n {\n cases: {\n '@operators': 'operator',\n '@default': '',\n },\n },\n ],\n\n // numbers\n [/\\d+\\.\\d*(@exponent)?/, 'number.float'],\n [/\\.\\d+(@exponent)?/, 'number.float'],\n [/\\d+@exponent/, 'number.float'],\n [/0[xX][\\da-fA-F]+/, 'number.hex'],\n [/0[0-7]+/, 'number.octal'],\n [/\\d+/, 'number'],\n\n // strings: recover on non-terminated strings\n [/\"([^\"\\\\]|\\\\.)*$/, 'string.invalid'], // non-teminated string\n [/'([^'\\\\]|\\\\.)*$/, 'string.invalid'], // non-teminated string\n [/\"/, 'string', '@string.\"'],\n [/'/, 'string', \"@string.'\"],\n ],\n\n whitespace: [\n [/[ \\t\\r\\n]+/, 'white'],\n [/\\/\\*/, 'comment', '@comment'],\n [/\\/\\/.*$/, 'comment'],\n ],\n\n comment: [\n [/[^\\/*]+/, 'comment'],\n // [/\\/\\*/, 'comment', '@push' ], // nested comment not allowed :-(\n [/\\/\\*/, 'comment.invalid'],\n ['\\\\*/', 'comment', '@pop'],\n [/[\\/*]/, 'comment'],\n ],\n\n string: [\n [/[^\\\\\"']+/, 'string'],\n [/@escapes/, 'string.escape'],\n [/\\\\./, 'string.escape.invalid'],\n [\n /[\"']/,\n {\n cases: {\n '$#==$S2': { token: 'string', next: '@pop' },\n '@default': 'string',\n },\n },\n ],\n ],\n\n // We match regular expression quite precisely\n regexp: [\n [\n /(\\{)(\\d+(?:,\\d*)?)(\\})/,\n [\n '@brackets.regexp.escape.control',\n 'regexp.escape.control',\n '@brackets.regexp.escape.control',\n ],\n ],\n [\n /(\\[)(\\^?)(?=(?:[^\\]\\\\\\/]|\\\\.)+)/,\n [\n { token: '@brackets.regexp.escape.control' },\n {\n token: 'regexp.escape.control',\n next: '@regexrange',\n },\n ],\n ],\n [\n /(\\()(\\?:|\\?=|\\?!)/,\n ['@brackets.regexp.escape.control', 'regexp.escape.control'],\n ],\n [/[()]/, '@brackets.regexp.escape.control'],\n [/@regexpctl/, 'regexp.escape.control'],\n [/[^\\\\\\/]/, 'regexp'],\n [/@regexpesc/, 'regexp.escape'],\n [/\\\\\\./, 'regexp.invalid'],\n ['/', { token: 'regexp.slash', bracket: '@close' }, '@pop'],\n ],\n\n regexrange: [\n [/-/, 'regexp.escape.control'],\n [/\\^/, 'regexp.invalid'],\n [/@regexpesc/, 'regexp.escape'],\n [/[^\\]]/, 'regexp'],\n [/\\]/, '@brackets.regexp.escape.control', '@pop'],\n ],\n },\n};\n\nconst lang: Language = { id, conf, language };\nexport default lang;\n","/* eslint no-useless-escape: \"off\" */\nimport * as monaco from 'monaco-editor';\nimport { Language } from './Language';\n\nconst id = 'log';\n\nconst conf = {};\n\nconst language: monaco.languages.IMonarchLanguage = {\n tokenizer: {\n root: [\n [/ FATAL[\\s\\S]*/, { token: 'error', next: '@error' }],\n [/ ERROR[\\s\\S]*/, { token: 'error', next: '@error' }],\n [/ STDERR[\\s\\S]*/, { token: 'error', next: '@error' }],\n [/ STDOUT.*/, { token: 'stdout', next: '@stdout' }],\n [/ INFO[\\s\\S]*/, { token: 'info', next: '@info' }],\n [/ WARN.*/, { token: 'warn', next: '@warn' }],\n [/ TRACE[\\s\\S]*/, { token: 'trace', next: '@trace' }],\n [/ DEBUG[.\\s\\S]*/, { token: 'debug', next: '@debug' }],\n [/^\\d{2}:\\d{2}:\\d{2}.\\d{3}/, 'date'],\n ],\n error: [{ include: '@body' }],\n info: [{ include: '@body' }],\n warn: [{ include: '@body' }],\n stdout: [{ include: '@body' }],\n trace: [{ include: '@body' }],\n debug: [{ include: '@body' }],\n body: [\n [/^\\d{2}:\\d{2}:\\d{2}.\\d{3}/, { token: 'date', next: '@pop' }],\n [/[\\s\\S]*/, { token: '$S0' }],\n ],\n },\n};\n\nconst lang: Language = { id, conf, language };\nexport default lang;\n","/* eslint-disable @typescript-eslint/ban-ts-comment */\n/**\n * Exports a function for initializing monaco with the deephaven theme/config\n */\nimport { Shortcut } from '@deephaven/components';\nimport type { IdeSession } from '@deephaven/jsapi-types';\nimport { assertNotNull } from '@deephaven/utils';\nimport { find as linkifyFind } from 'linkifyjs';\nimport * as monaco from 'monaco-editor';\nimport type { Environment } from 'monaco-editor';\n// @ts-ignore\nimport { KeyCodeUtils } from 'monaco-editor/esm/vs/base/common/keyCodes.js';\nimport Log from '@deephaven/log';\nimport MonacoTheme from './MonacoTheme.module.scss';\nimport PyLang from './lang/python';\nimport GroovyLang from './lang/groovy';\nimport ScalaLang from './lang/scala';\nimport DbLang from './lang/db';\nimport LogLang from './lang/log';\nimport { Language } from './lang/Language';\n\nconst log = Log.module('MonacoUtils');\n\ndeclare global {\n interface Window {\n MonacoEnvironment?: Environment;\n }\n}\n\nclass MonacoUtils {\n /**\n * Initializes Monaco for the environment\n * @param getWorker The getWorker function Monaco should use\n * The workers should be provided by the caller and bundled by their build system (e.g. Vite, Webpack)\n */\n static init({\n getWorker,\n }: { getWorker?: Environment['getWorker'] } = {}): void {\n log.debug('Initializing Monaco...');\n\n if (getWorker !== undefined) {\n MonacoUtils.registerGetWorker(getWorker);\n }\n\n const { registerLanguages, removeHashtag } = MonacoUtils;\n\n const dhDarkRules = [\n { token: '', foreground: removeHashtag(MonacoTheme.foreground) },\n { token: 'string', foreground: removeHashtag(MonacoTheme.string) },\n {\n token: 'string.delim',\n foreground: removeHashtag(MonacoTheme['string-delim']),\n },\n { token: 'keyword', foreground: removeHashtag(MonacoTheme.keyword) },\n {\n token: 'identifier.js',\n foreground: removeHashtag(MonacoTheme['identifier-js']),\n },\n {\n token: 'delimiter',\n foreground: removeHashtag(MonacoTheme.delimiter),\n },\n { token: 'comment', foreground: removeHashtag(MonacoTheme.comment) },\n { token: 'number', foreground: removeHashtag(MonacoTheme.number) },\n { token: 'storage', foreground: removeHashtag(MonacoTheme.storage) },\n {\n token: 'identifier',\n foreground: removeHashtag(MonacoTheme.identifier),\n },\n {\n token: 'namespace.identifier',\n foreground: removeHashtag(MonacoTheme['namespace-identifier']),\n },\n { token: 'operator', foreground: removeHashtag(MonacoTheme.operator) },\n {\n token: 'predefined',\n foreground: removeHashtag(MonacoTheme.predefined),\n },\n {\n token: 'error.log',\n foreground: MonacoTheme['log-error'].substring(1),\n },\n {\n token: 'warn.log',\n foreground: removeHashtag(MonacoTheme['log-warn']),\n },\n {\n token: 'info.log',\n foreground: removeHashtag(MonacoTheme['log-info']),\n },\n {\n token: 'stdout.log',\n foreground: removeHashtag(MonacoTheme['log-stdout']),\n },\n {\n token: 'trace.log',\n foreground: removeHashtag(MonacoTheme['log-trace']),\n },\n {\n token: 'debug.log',\n foreground: removeHashtag(MonacoTheme['log-debug']),\n },\n {\n token: 'date.log',\n foreground: removeHashtag(MonacoTheme['log-date']),\n },\n ];\n\n const dhDarkColors = {\n errorForeground: MonacoTheme['error-foreground'],\n 'inputOption.activeBorder': MonacoTheme['input-option-active-border'],\n 'editor.background': MonacoTheme.background,\n 'editor.foreground': MonacoTheme.foreground,\n 'editor.lineHighlightBackground': MonacoTheme['editor-line-highlight-bg'],\n 'editorLineNumber.foreground':\n MonacoTheme['editor-line-number-foreground'],\n 'editor.selectionBackground': MonacoTheme['editor-selection-background'],\n 'editor.findMatchBackground': MonacoTheme['editor-find-match-background'],\n 'editor.findMatchHighlightBackground':\n MonacoTheme['editor-find-match-highlight-background'],\n 'editorSuggestWidget.background':\n MonacoTheme['editor-suggest-widget-background'],\n 'editorSuggestWidget.border': MonacoTheme['editor-suggest-widget-border'],\n 'editorSuggestWidget.foreground':\n MonacoTheme['editor-suggest-widget-foreground'],\n 'editorSuggestWidget.selectedBackground':\n MonacoTheme['editor-suggest-widget-selected-background'],\n 'editorSuggestWidget.highlightForeground':\n MonacoTheme['editor-suggest-widget-highlightForeground'],\n 'list.hoverBackground': MonacoTheme['list-hover-background'],\n 'dropdown.background': MonacoTheme['context-menu-background'],\n 'dropdown.foreground': MonacoTheme['context-menu-foreground'],\n 'menu.selectionBackground': MonacoTheme['menu-selection-background'],\n 'list.focusBackground': MonacoTheme['menu-selection-background'],\n 'editorWidget.background': MonacoTheme['editor-widget-background'],\n 'inputOption.activeBackground':\n MonacoTheme['input-option-active-background'],\n 'inputOption.activeForeground':\n MonacoTheme['input-option-active-foreground'],\n focusBorder: MonacoTheme['focus-border'],\n 'input.background': MonacoTheme['input-background'],\n 'input.foreground': MonacoTheme['input-foreground'],\n 'input.border': MonacoTheme['input-border'],\n 'textLink.foreground': MonacoTheme['text-link-foreground'],\n 'textLink.activeForeground': MonacoTheme['text-link-active-foreground'],\n 'editorLink.activeForeground':\n MonacoTheme['editor-link-active-foreground'],\n };\n\n monaco.editor.defineTheme('dh-dark', {\n base: 'vs-dark',\n inherit: true,\n rules: dhDarkRules,\n colors: dhDarkColors,\n });\n log.debug2('monaco theme: ', MonacoTheme);\n monaco.editor.setTheme('dh-dark');\n\n registerLanguages([DbLang, PyLang, GroovyLang, LogLang, ScalaLang]);\n\n log.debug('Monaco initialized.');\n }\n\n /**\n * Register the getWorker function for Monaco\n * @param getWorker The getWorker function for Monaco\n */\n static registerGetWorker(getWorker: Environment['getWorker']): void {\n window.MonacoEnvironment = {\n ...window.MonacoEnvironment,\n getWorker,\n };\n }\n\n /**\n * Remove the hashtag prefix from a CSS color string.\n * Monaco expects colors to be the value only, no hashtag.\n * @param color The hex color string to remove the hashtag from, eg. '#ffffff'\n */\n static removeHashtag(color: string): string {\n return color.substring(1);\n }\n\n static registerLanguages(languages: Language[]): void {\n // First override the default loader for any language we have a custom definition for\n // https://github.com/Microsoft/monaco-editor/issues/252#issuecomment-482786867\n const languageIds = languages.map(({ id }) => id);\n monaco.languages\n .getLanguages()\n .filter(({ id }) => languageIds.includes(id))\n .forEach(languageParam => {\n const language = languageParam;\n log.debug2('Overriding default language loader:', language.id);\n });\n\n // Then register our language definitions\n languages.forEach(language => {\n MonacoUtils.registerLanguage(language);\n });\n }\n\n static registerLanguage(language: Language): void {\n log.debug2('Registering language: ', language.id);\n monaco.languages.register(language);\n\n monaco.languages.onLanguage(language.id, () => {\n monaco.languages.setLanguageConfiguration(language.id, language.conf);\n monaco.languages.setMonarchTokensProvider(language.id, language.language);\n });\n }\n\n /**\n * Set EOL preference for the editor\n * @param editor The editor to set the EOL for\n * @param eolSequence EOL sequence\n */\n static setEOL(\n editor: monaco.editor.IStandaloneCodeEditor,\n eolSequence = monaco.editor.EndOfLineSequence.LF\n ): void {\n editor.getModel()?.setEOL(eolSequence);\n }\n\n /**\n * Links an editor with a provided session to provide completion items.\n * @param session The IdeSession to link\n * @param editor The editor to link the session to\n * @returns A cleanup function for disposing of the created listeners\n */\n static openDocument(\n editor: monaco.editor.IStandaloneCodeEditor,\n session: IdeSession\n ): monaco.IDisposable {\n const model = editor.getModel();\n assertNotNull(model);\n const didOpenDocumentParams = {\n textDocument: {\n uri: `${model.uri}`,\n languageId: model.getLanguageId(),\n version: model.getVersionId(),\n text: model.getValue(),\n },\n };\n log.debug2('didOpenDocumentParams: ', didOpenDocumentParams);\n\n session.openDocument(didOpenDocumentParams);\n\n const dispose = editor.onDidChangeModelContent(changedEvent => {\n const { changes, versionId } = changedEvent;\n\n const contentChanges = [];\n for (let i = 0; i < changes.length; i += 1) {\n const change = changes[i];\n const { range, rangeLength, text } = change;\n const contentChange = {\n range: {\n start: {\n line: range.startLineNumber - 1,\n character: range.startColumn - 1,\n },\n end: {\n line: range.endLineNumber - 1,\n character: range.endColumn - 1,\n },\n },\n rangeLength,\n text,\n };\n\n contentChanges.push(contentChange);\n }\n\n if (contentChanges.length > 0) {\n const didChangeDocumentParams = {\n textDocument: {\n version: versionId,\n uri: `${model.uri}`,\n },\n contentChanges,\n };\n log.debug2('didChangeDocumentParams', didChangeDocumentParams);\n session.changeDocument(didChangeDocumentParams);\n }\n });\n\n return dispose;\n }\n\n static closeDocument(\n editor: monaco.editor.IStandaloneCodeEditor,\n session: IdeSession\n ): void {\n const model = editor.getModel();\n assertNotNull(model);\n const didCloseDocumentParams = {\n textDocument: {\n uri: `${model.uri}`,\n },\n };\n session.closeDocument(didCloseDocumentParams);\n }\n\n /**\n * Register a paste handle to clean up any garbage code pasted.\n * Most of this comes from copying from Slack, which has a bad habit of injecting their own characters in your code snippets.\n * I've emailed Slack about the issue and they're working on it. I can't reference a ticket number because their ticket system is entirely internally facing.\n * @param editor The editor the register the paste handler for\n */\n static registerPasteHandler(\n editor: monaco.editor.IStandaloneCodeEditor\n ): void {\n editor.onDidPaste(pasteEvent => {\n const smartQuotes = /“|”/g;\n const invalidChars = /\\u200b/g; // zero width space\n const invalidSpaces = /\\u00A0/g; // non-breaking space\n const editorModel = editor.getModel();\n assertNotNull(editorModel);\n const pastedText = editorModel.getValueInRange(pasteEvent.range);\n if (\n smartQuotes.test(pastedText) ||\n invalidChars.test(pastedText) ||\n invalidSpaces.test(pastedText)\n ) {\n editorModel.applyEdits([\n {\n range: pasteEvent.range,\n text: pastedText\n .replace(smartQuotes, '\"')\n .replace(invalidChars, '')\n .replace(invalidSpaces, ' '),\n },\n ]);\n }\n });\n }\n\n static isMacPlatform(): boolean {\n const { platform } = window.navigator;\n return platform.startsWith('Mac');\n }\n\n /**\n * Remove any keybindings which are used for our own shortcuts.\n * This allows the key events to bubble up so a component higher up can capture them\n * @param editor The editor to remove the keybindings from\n */\n static removeConflictingKeybindings(\n editor: monaco.editor.IStandaloneCodeEditor\n ): void {\n // Multi-mod key events have a specific order\n // E.g. ctrl+alt+UpArrow is not found, but alt+ctrl+UpArrow is found\n // meta is WindowsKey on Windows and cmd on Mac\n // ctrl is ctrl Windows and ctrl on Mac\n // alt is alt on Windows and option on Mac\n const keybindings = [\n {\n windows: 'ctrl+D',\n mac: 'meta+D',\n },\n {\n windows: 'ctrl+H',\n },\n ];\n\n try {\n keybindings.forEach(keybinding => {\n if (\n (MonacoUtils.isMacPlatform() && keybinding.mac === '') ||\n (!MonacoUtils.isMacPlatform() && keybinding.windows === '')\n ) {\n return;\n }\n MonacoUtils.removeKeybinding(\n editor,\n MonacoUtils.isMacPlatform() ? keybinding.mac : keybinding.windows\n );\n });\n } catch (err) {\n // This is probably only caused by Monaco changing private methods used here\n log.error(err);\n }\n }\n\n /**\n * Remove a keybinding and allow the events to bubble up\n * If you want the keybinding removed for all editors, add it to removeConflictingKeybindings\n * Monaco still captures the event if you choose to override the keybinding with a no-op function\n *\n * Based on the following comment to remove a keybinding and let the event bubble up\n * https://github.com/microsoft/monaco-editor/issues/287#issuecomment-331447475\n * The issue for an API for this has apparently been open since 2016. Link below\n * https://github.com/microsoft/monaco-editor/issues/102\n * @param editor The editor to remove the keybinding from\n * @param keybinding The key string to remove. E.g. 'ctrl+C' for copy on Windows\n */\n static removeKeybinding(\n editor: monaco.editor.IStandaloneCodeEditor,\n keybinding: string | undefined\n ): void {\n if (keybinding === undefined) {\n return;\n }\n\n /* eslint-disable no-underscore-dangle */\n // It's possible a single keybinding has multiple commands depending on context\n // @ts-ignore\n const keybindings = editor._standaloneKeybindingService\n ._getResolver()\n ._map.get(keybinding);\n\n if (keybindings != null) {\n keybindings.forEach((elem: { command: unknown }) => {\n log.debug2(\n `Removing Monaco keybinding ${keybinding} for ${elem.command}`\n );\n // @ts-ignore\n editor._standaloneKeybindingService.addDynamicKeybinding(\n `-${elem.command}`,\n null,\n () => undefined\n );\n });\n } else {\n log.warn(`Did not find any keybindings to remove for ${keybinding}`);\n }\n /* eslint-enable no-underscore-dangle */\n }\n\n static getMonacoKeyCodeFromShortcut(shortcut: Shortcut): number {\n const { keyState } = shortcut;\n const { keyValue } = keyState;\n if (keyValue === null) {\n return 0;\n }\n\n const isMac = MonacoUtils.isMacPlatform();\n\n if (isMac) {\n return (\n // eslint-disable-next-line no-bitwise\n (keyState.metaKey ? monaco.KeyMod.CtrlCmd : 0) |\n (keyState.shiftKey ? monaco.KeyMod.Shift : 0) |\n (keyState.altKey ? monaco.KeyMod.Alt : 0) |\n (keyState.ctrlKey ? monaco.KeyMod.WinCtrl : 0) |\n KeyCodeUtils.fromString(keyValue)\n );\n }\n\n return (\n // eslint-disable-next-line no-bitwise\n (keyState.ctrlKey ? monaco.KeyMod.CtrlCmd : 0) |\n (keyState.shiftKey ? monaco.KeyMod.Shift : 0) |\n (keyState.altKey ? monaco.KeyMod.Alt : 0) |\n (keyState.metaKey ? monaco.KeyMod.WinCtrl : 0) |\n KeyCodeUtils.fromString(keyValue)\n );\n }\n\n static provideLinks(\n model: monaco.editor.ITextModel\n ): { links: monaco.languages.ILink[] } {\n const newTokens: monaco.languages.ILink[] = [];\n\n for (let i = 1; i <= model.getLineCount(); i += 1) {\n const lineText = model.getLineContent(i);\n const originalTokens = linkifyFind(lineText);\n\n const tokens = originalTokens.filter(token => {\n if (token.type === 'url') {\n return /^https?:\\/\\//.test(token.value);\n }\n return true;\n });\n // map the tokens to the ranges - you know the line number now, use the token start/end as the startColumn/endColumn\n tokens.forEach(token => {\n newTokens.push({\n url: token.href,\n range: new monaco.Range(i, token.start + 1, i, token.end + 1),\n });\n });\n }\n\n return {\n links: newTokens,\n };\n }\n}\n\nexport default MonacoUtils;\n","/**\n * Editor editor for large blocks of code\n */\nimport React, { Component, ReactElement } from 'react';\nimport classNames from 'classnames';\nimport * as monaco from 'monaco-editor';\nimport { assertNotNull } from '@deephaven/utils';\nimport MonacoUtils from '../monaco/MonacoUtils';\nimport './Editor.scss';\n\ninterface EditorProps {\n className: string;\n onEditorInitialized: (editor: monaco.editor.IStandaloneCodeEditor) => void;\n onEditorWillDestroy: (editor: monaco.editor.IStandaloneCodeEditor) => void;\n settings: monaco.editor.IStandaloneEditorConstructionOptions;\n}\n\nclass Editor extends Component<EditorProps, Record<string, never>> {\n static defaultProps = {\n className: 'fill-parent-absolute',\n onEditorInitialized: (): void => undefined,\n onEditorWillDestroy: (): void => undefined,\n settings: {},\n };\n\n constructor(props: EditorProps) {\n super(props);\n\n this.handleResize = this.handleResize.bind(this);\n\n this.container = null;\n this.state = {};\n }\n\n componentDidMount(): void {\n this.initEditor();\n\n window.addEventListener('resize', this.handleResize);\n }\n\n componentWillUnmount(): void {\n window.removeEventListener('resize', this.handleResize);\n\n this.destroyEditor();\n }\n\n container: HTMLDivElement | null;\n\n editor?: monaco.editor.IStandaloneCodeEditor;\n\n setLanguage(language: string): void {\n if (this.editor) {\n const model = this.editor.getModel();\n assertNotNull(model);\n monaco.editor.setModelLanguage(model, language);\n }\n }\n\n handleResize(): void {\n this.updateDimensions();\n }\n\n toggleFind(): void {\n if (this.editor) {\n // The actions.find action can no longer be triggered when the editor is not in focus, with monaco 0.22.x.\n // As a workaround, just focus the editor before triggering the action\n // https://github.com/microsoft/monaco-editor/issues/2355\n this.editor.focus();\n this.editor.trigger('toggleFind', 'actions.find', undefined);\n }\n }\n\n updateDimensions(): void {\n this.editor?.layout();\n }\n\n initEditor(): void {\n const { onEditorInitialized } = this.props;\n let { settings } = this.props;\n settings = {\n copyWithSyntaxHighlighting: false,\n fixedOverflowWidgets: true,\n folding: false,\n fontFamily: 'Fira Mono',\n glyphMargin: false,\n language: `python`,\n lineNumbersMinChars: 3,\n minimap: { enabled: false },\n scrollBeyondLastLine: false,\n tabCompletion: 'on',\n value: '',\n wordWrap: 'off',\n links: true,\n ...settings,\n };\n assertNotNull(this.container);\n this.editor = monaco.editor.create(this.container, settings);\n this.editor.addAction({\n id: 'find',\n label: 'Find',\n keybindings: [\n // eslint-disable-next-line no-bitwise\n monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyF,\n ],\n precondition: undefined,\n keybindingContext: undefined,\n contextMenuGroupId: 'navigation',\n contextMenuOrder: 1.0,\n\n run: () => {\n this.toggleFind();\n },\n });\n this.editor.layout();\n MonacoUtils.removeConflictingKeybindings(this.editor);\n\n monaco.languages.registerLinkProvider('plaintext', {\n provideLinks: MonacoUtils.provideLinks,\n });\n\n onEditorInitialized(this.editor);\n }\n\n destroyEditor(): void {\n const { onEditorWillDestroy } = this.props;\n assertNotNull(this.editor);\n onEditorWillDestroy(this.editor);\n this.editor.dispose();\n this.editor = undefined;\n }\n\n render(): ReactElement {\n const { className } = this.props;\n return (\n <div\n className={classNames('editor-container', className)}\n ref={container => {\n this.container = container;\n }}\n />\n );\n }\n}\n\nexport default Editor;\n","import React, { useEffect, useRef, useState } from 'react';\nimport { Editor } from '@deephaven/console';\nimport * as monaco from 'monaco-editor';\nimport {\n Button,\n CopyButton,\n Modal,\n ModalBody,\n ModalHeader,\n} from '@deephaven/components';\nimport { vsJson, vsListOrdered } from '@deephaven/icons';\nimport './IrisGridCellOverflowModal.scss';\n\ninterface IrisGridCellOverflowModalProps {\n text: string;\n isOpen: boolean;\n onClose: () => void;\n}\n\nexport default function IrisGridCellOverflowModal({\n text,\n isOpen,\n onClose,\n}: IrisGridCellOverflowModalProps): React.ReactElement | null {\n const [isOpened, setIsOpened] = useState(false);\n const [height, setHeight] = useState(0);\n const [showLineNumbers, setShowLineNumbers] = useState(false);\n const [isFormatted, setIsFormatted] = useState(false);\n const [canFormat, setCanFormat] = useState(false);\n const editorRef = useRef<monaco.editor.IStandaloneCodeEditor>();\n\n // Update format button on open\n useEffect(\n function enableFormatButtonWhenOpen() {\n if (!isOpen) {\n return;\n }\n\n try {\n JSON.parse(text);\n setCanFormat(true);\n } catch {\n setCanFormat(false);\n }\n setIsFormatted(false);\n },\n [isOpen, text]\n );\n\n // Re-layout editor on height change\n useEffect(\n function updateLayoutOnHeightChange() {\n if (editorRef.current) {\n editorRef.current.layout();\n }\n },\n [height]\n );\n\n // Update editor options on line number toggle\n useEffect(\n function toggleShowLineNumber() {\n if (editorRef.current) {\n editorRef.current.updateOptions({\n lineNumbers: showLineNumbers ? 'on' : 'off',\n });\n }\n },\n [showLineNumbers]\n );\n\n function toggleLineNumbers() {\n setShowLineNumbers(!showLineNumbers);\n }\n\n function formatAsJSON() {\n const model = editorRef.current?.getModel();\n if (!canFormat || !model) {\n return;\n }\n\n if (!isFormatted) {\n model.setValue(JSON.stringify(JSON.parse(text), undefined, 2));\n setIsFormatted(true);\n } else {\n model.setValue(text);\n setIsFormatted(false);\n }\n autoSetLineNumbers();\n }\n\n function autoSetLineNumbers() {\n const editor = editorRef.current;\n if (!editor) {\n return;\n }\n\n setShowLineNumbers((editor.getModel()?.getLineCount() ?? 0) > 1);\n }\n\n function handleToggle() {\n if (isOpened) {\n editorRef.current = undefined;\n onClose();\n }\n }\n\n function onEditorInitialized(editor: monaco.editor.IStandaloneCodeEditor) {\n editorRef.current = editor;\n setHeight(editor.getContentHeight());\n editor.onDidContentSizeChange(({ contentHeight }) =>\n setHeight(contentHeight)\n );\n autoSetLineNumbers();\n }\n\n if (!isOpen && !isOpened) {\n return null;\n }\n\n return (\n <Modal\n isOpen={isOpen}\n centered\n keyboard\n toggle={handleToggle}\n onOpened={() => setIsOpened(true)}\n onClosed={() => {\n setIsOpened(false);\n setHeight(0);\n }}\n className=\"theme-bg-dark cell-overflow-modal\"\n size=\"xl\"\n >\n <ModalHeader toggle={onClose}>\n <h5 className=\"overflow-modal-title\">Cell Contents</h5>\n <CopyButton\n kind=\"inline\"\n tooltip=\"Copy cell contents\"\n copy={editorRef.current?.getValue() ?? text}\n />\n <Button\n kind=\"inline\"\n active={showLineNumbers}\n icon={vsListOrdered}\n tooltip=\"Toggle line numbers\"\n onClick={toggleLineNumbers}\n />\n {canFormat && (\n <Button\n kind=\"inline\"\n icon={vsJson}\n active={isFormatted}\n tooltip=\"Format as JSON\"\n onClick={formatAsJSON}\n />\n )}\n </ModalHeader>\n <ModalBody style={{ height }}>\n <Editor\n onEditorInitialized={onEditorInitialized}\n settings={{\n value: text,\n readOnly: true,\n wordWrap: 'on',\n // Loading json language w/o the monaco workers causes UI freezes and monaco errors. TS colorizes the same\n language: canFormat ? 'typescript' : 'plaintext',\n folding: canFormat,\n padding: { bottom: 16 },\n lineNumbers: showLineNumbers ? 'on' : 'off',\n overviewRulerLanes: 0,\n renderLineHighlight: 'none',\n /*\n The entire string may be 1 giant line\n Monaco by default seeds find w/ that line\n On very long strings this hangs the browser, so never seed the search\n */\n find: { seedSearchStringFromSelection: 'never' },\n }}\n />\n </ModalBody>\n </Modal>\n );\n}\n","import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { vsClose, vsArrowUp, vsArrowDown } from '@deephaven/icons';\nimport React, {\n ChangeEvent,\n KeyboardEvent,\n ReactElement,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport type { Column } from '@deephaven/jsapi-types';\nimport {\n Type as FilterType,\n TypeValue as FilterTypeValue,\n} from '@deephaven/filters';\nimport { Button, DateTimeInput } from '@deephaven/components';\nimport { TableUtils } from '@deephaven/jsapi-utils';\nimport classNames from 'classnames';\nimport './GotoRow.scss';\nimport IrisGridModel from './IrisGridModel';\nimport IrisGridProxyModel from './IrisGridProxyModel';\nimport IrisGridBottomBar from './IrisGridBottomBar';\nimport { ColumnName } from './CommonTypes';\n\nfunction isIrisGridProxyModel(\n model: IrisGridModel\n): model is IrisGridProxyModel {\n return (model as IrisGridProxyModel).model !== undefined;\n}\n\nconst DEFAULT_FORMAT_STRING = '###,##0';\n\ninterface GotoRowProps {\n gotoRow: string;\n gotoRowError: string;\n gotoValueError: string;\n onGotoRowSubmit: () => void;\n model: IrisGridModel;\n onGotoRowNumberChanged: (event: ChangeEvent<HTMLInputElement>) => void;\n onClose: () => void;\n isShown: boolean;\n onEntering: () => void;\n onEntered: () => void;\n onExiting: () => void;\n onExited: () => void;\n\n gotoValueSelectedColumnName: ColumnName;\n gotoValue: string;\n gotoValueFilter: FilterTypeValue;\n onGotoValueSelectedColumnNameChanged: (columnName: ColumnName) => void;\n onGotoValueSelectedFilterChanged: (filter: FilterTypeValue) => void;\n onGotoValueChanged: (input: string) => void;\n onGotoValueSubmit: (isBackward?: boolean) => void;\n}\n\nfunction GotoRow({\n gotoRow,\n gotoRowError,\n gotoValueError,\n onGotoRowSubmit,\n isShown,\n onEntering,\n onEntered,\n onExiting,\n onExited,\n model,\n onGotoRowNumberChanged,\n onClose,\n gotoValueSelectedColumnName,\n gotoValue,\n gotoValueFilter,\n onGotoValueSelectedColumnNameChanged,\n onGotoValueSelectedFilterChanged,\n onGotoValueChanged,\n onGotoValueSubmit,\n}: GotoRowProps): ReactElement {\n const gotoRowInputRef = useRef<HTMLInputElement>(null);\n const gotoValueInputRef = useRef<HTMLInputElement>(null);\n\n const [isGotoRowActive, setIsGotoRowActive] = useState(false);\n let columns: Column[] = [];\n\n if (isIrisGridProxyModel(model) && model.table !== undefined) {\n ({ columns } = model.table);\n }\n\n const res = 'Row number';\n\n const { dh, rowCount } = model;\n\n const handleGotoValueNumberKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n e.stopPropagation();\n e.preventDefault();\n onGotoValueSubmit();\n } else if (\n (e.key === 'Backspace' || e.key === 'Delete') &&\n (gotoValue === `${Number.POSITIVE_INFINITY}` ||\n gotoValue === `${Number.NEGATIVE_INFINITY}`)\n ) {\n onGotoValueInputChanged('');\n }\n };\n\n const handleGotoValueKeySubmit = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n e.stopPropagation();\n e.preventDefault();\n onGotoValueSubmit(e.shiftKey);\n }\n };\n\n const index = model.getColumnIndexByName(gotoValueSelectedColumnName);\n\n const selectedColumn = columns[index ?? 0];\n\n const columnType = selectedColumn?.type;\n\n const normalizedType = TableUtils.getNormalizedType(columnType);\n const onGotoValueInputChanged = (value?: string) => {\n onGotoValueChanged(value ?? '');\n };\n const selectInput = () => {\n // when row changes without focus (i.e. via context menu), re-select input\n if (isGotoRowActive && document.activeElement !== gotoRowInputRef.current) {\n gotoRowInputRef.current?.select();\n } else if (\n !isGotoRowActive &&\n document.activeElement !== gotoValueInputRef.current\n ) {\n gotoValueInputRef.current?.select();\n }\n };\n useEffect(selectInput, [isGotoRowActive, gotoRow, gotoValue]);\n\n const renderValueInput = () => {\n switch (normalizedType) {\n case TableUtils.dataType.DECIMAL:\n case TableUtils.dataType.INT:\n return (\n <div className=\"goto-row-input\">\n <input\n ref={gotoValueInputRef}\n className={classNames('form-control', {\n 'is-invalid': gotoValueError !== '',\n })}\n onKeyDown={handleGotoValueNumberKeyDown}\n placeholder=\"value\"\n onChange={e => {\n const value = e.target.value.toLowerCase();\n // regex tests for\n if (/^-?[0-9]*\\.?[0-9]*$/.test(e.target.value)) {\n onGotoValueInputChanged(e.target.value);\n } else if (value === '-i' || value === '-infinity') {\n onGotoValueInputChanged(`${Number.NEGATIVE_INFINITY}`);\n } else if (value === 'i' || value === 'infinity') {\n onGotoValueInputChanged(`${Number.POSITIVE_INFINITY}`);\n }\n }}\n value={gotoValue}\n />\n </div>\n );\n case TableUtils.dataType.DATETIME:\n return (\n <div className=\"goto-value-date-time-input\">\n <DateTimeInput\n ref={gotoValueInputRef}\n className={classNames(\n 'form-control',\n 'goto-value-date-time-input',\n {\n 'is-invalid': gotoValueError !== '',\n }\n )}\n defaultValue={gotoValue}\n onChange={onGotoValueInputChanged}\n onSubmit={handleGotoValueKeySubmit}\n />\n </div>\n );\n case TableUtils.dataType.STRING:\n return (\n <>\n <div className=\"goto-row-input\">\n <select\n className=\"custom-select\"\n onChange={event => {\n onGotoValueSelectedFilterChanged(\n event.target.value as FilterTypeValue\n );\n }}\n value={gotoValueFilter}\n >\n <option key={FilterType.eq} value={FilterType.eq}>\n Equals\n </option>\n <option key={FilterType.contains} value={FilterType.contains}>\n Contains\n </option>\n <option\n key={FilterType.eqIgnoreCase}\n value={FilterType.eqIgnoreCase}\n >\n EqIgnoreCase\n </option>\n </select>\n </div>\n <div className=\"goto-row-input\">\n <input\n ref={gotoValueInputRef}\n className={classNames('form-control', {\n 'is-invalid': gotoValueError !== '',\n })}\n onKeyDown={handleGotoValueKeySubmit}\n placeholder=\"value\"\n onChange={e => onGotoValueInputChanged(e.target.value)}\n value={gotoValue}\n />\n </div>\n </>\n );\n case TableUtils.dataType.BOOLEAN:\n return (\n <div className=\"goto-row-input\">\n <select\n className=\"custom-select\"\n onChange={event => {\n onGotoValueInputChanged(event.target.value);\n }}\n value={gotoValue}\n >\n <option aria-label=\"null value\" key=\"null\" value=\"\" />\n <option key=\"true\" value=\"true\">\n true\n </option>\n <option key=\"false\" value=\"false\">\n false\n </option>\n </select>\n </div>\n );\n default:\n return (\n <div className=\"goto-row-input\">\n <input\n ref={gotoValueInputRef}\n className=\"form-control\"\n onKeyDown={handleGotoValueKeySubmit}\n placeholder=\"value\"\n onChange={e => onGotoValueInputChanged(e.target.value)}\n value={gotoValue}\n />\n </div>\n );\n }\n };\n return (\n <IrisGridBottomBar\n isShown={isShown}\n className={classNames('goto-row')}\n onEntering={onEntering}\n onEntered={() => {\n onEntered();\n selectInput();\n }}\n onExiting={onExiting}\n onExited={onExited}\n >\n <>\n <div className=\"goto-row-row\">\n <div\n className={classNames('goto-row-wrapper', {\n 'is-inactive': !isGotoRowActive,\n })}\n onClick={() => setIsGotoRowActive(true)}\n onFocus={() => setIsGotoRowActive(true)}\n role=\"group\"\n >\n <div className=\"goto-row-text\">Go to row</div>\n <div className=\"goto-row-input\">\n <input\n ref={gotoRowInputRef}\n type=\"number\"\n onKeyDown={e => {\n if (e.key === 'Enter') {\n e.stopPropagation();\n e.preventDefault();\n onGotoRowSubmit();\n }\n }}\n className={classNames('form-control', {\n 'is-invalid': gotoRowError !== '',\n })}\n placeholder={res}\n onChange={event => {\n onGotoRowNumberChanged(event);\n }}\n value={gotoRow}\n />\n </div>\n <div className=\"goto-row-text\">\n of {dh.i18n.NumberFormat.format(DEFAULT_FORMAT_STRING, rowCount)}\n </div>\n {gotoRowError && <div className=\"text-danger\">{gotoRowError}</div>}\n </div>\n <div className=\"goto-row-close\">\n <Button kind=\"ghost\" onClick={onClose}>\n <FontAwesomeIcon icon={vsClose} style={{ marginRight: '0' }} />\n </Button>\n </div>\n </div>\n {model.isSeekRowAvailable && (\n <div className=\"goto-row-row\">\n <div\n className={classNames('goto-row-wrapper', {\n 'is-inactive': isGotoRowActive,\n })}\n onClick={() => setIsGotoRowActive(false)}\n onFocus={() => setIsGotoRowActive(false)}\n role=\"group\"\n >\n <div className=\"goto-row-text\">Go to value</div>\n <div className=\"goto-row-input\">\n <select\n className=\"custom-select\"\n onChange={event => {\n const columnName = event.target.value;\n onGotoValueSelectedColumnNameChanged(columnName);\n }}\n value={gotoValueSelectedColumnName}\n >\n {columns.map(column => (\n <option key={column.name} value={column.name}>\n {column.name}\n </option>\n ))}\n </select>\n </div>\n\n {renderValueInput()}\n\n <div>\n <Button\n kind=\"ghost\"\n disabled={gotoValue === ''}\n onClick={() => {\n onGotoValueSubmit(true);\n }}\n >\n <FontAwesomeIcon icon={vsArrowUp} />\n </Button>\n <Button\n kind=\"ghost\"\n disabled={gotoValue === ''}\n onClick={() => {\n onGotoValueSubmit(false);\n }}\n >\n <FontAwesomeIcon icon={vsArrowDown} />\n </Button>\n </div>\n {gotoValueError && (\n <div className=\"text-danger\">{gotoValueError}</div>\n )}\n </div>\n </div>\n )}\n </>\n </IrisGridBottomBar>\n );\n}\n\nexport default GotoRow;\n","import React, {\n ChangeEvent,\n Component,\n CSSProperties,\n ReactElement,\n ReactNode,\n} from 'react';\nimport memoize from 'memoizee';\nimport classNames from 'classnames';\nimport { CSSTransition } from 'react-transition-group';\nimport PropTypes from 'prop-types';\nimport deepEqual from 'deep-equal';\nimport Log from '@deephaven/log';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport {\n ContextActions,\n Stack,\n Menu,\n Page,\n Popper,\n ThemeExport,\n Tooltip,\n ContextAction,\n PopperOptions,\n ReferenceObject,\n Button,\n ContextActionUtils,\n} from '@deephaven/components';\nimport {\n Grid,\n GridMetrics,\n GridMouseHandler,\n GridRange,\n GridRangeIndex,\n GridThemeType,\n GridUtils,\n KeyHandler,\n ModelIndex,\n ModelSizeMap,\n MoveOperation,\n VisibleIndex,\n GridState,\n isEditableGridModel,\n BoundedAxisRange,\n isExpandableGridModel,\n} from '@deephaven/grid';\nimport {\n dhEye,\n dhFilterFilled,\n dhGraphLineUp,\n dhTriangleDownSquare,\n vsClose,\n vsCloudDownload,\n vsEdit,\n vsFilter,\n vsMenu,\n vsReply,\n vsRuby,\n vsSearch,\n vsSplitHorizontal,\n vsSymbolOperator,\n vsTools,\n} from '@deephaven/icons';\nimport type {\n Column,\n ColumnGroup,\n CustomColumn,\n DateWrapper,\n dh as DhType,\n FilterCondition,\n Sort,\n Table,\n TableViewportSubscription,\n} from '@deephaven/jsapi-types';\nimport {\n DateUtils,\n Formatter,\n FormatterUtils,\n TableUtils,\n FormattingRule,\n ReverseType,\n RowDataMap,\n SortDirection,\n DateTimeColumnFormatterOptions,\n TableColumnFormat,\n Settings,\n} from '@deephaven/jsapi-utils';\nimport {\n assertNotNull,\n copyToClipboard,\n EMPTY_ARRAY,\n EMPTY_MAP,\n Pending,\n PromiseUtils,\n ValidationError,\n getOrThrow,\n} from '@deephaven/utils';\nimport {\n Type as FilterType,\n TypeValue as FilterTypeValue,\n} from '@deephaven/filters';\nimport throttle from 'lodash.throttle';\nimport debounce from 'lodash.debounce';\nimport clamp from 'lodash.clamp';\nimport {\n FormattingRule as SidebarFormattingRule,\n getFormatColumns,\n} from './sidebar/conditional-formatting/ConditionalFormattingUtils';\nimport PendingDataBottomBar from './PendingDataBottomBar';\nimport IrisGridCopyHandler, { CopyOperation } from './IrisGridCopyHandler';\nimport FilterInputField from './FilterInputField';\nimport {\n ClearFilterKeyHandler,\n CopyKeyHandler,\n ReverseKeyHandler,\n} from './key-handlers';\nimport {\n IrisGridCellOverflowMouseHandler,\n IrisGridColumnSelectMouseHandler,\n IrisGridColumnTooltipMouseHandler,\n IrisGridContextMenuHandler,\n IrisGridDataSelectMouseHandler,\n IrisGridFilterMouseHandler,\n IrisGridRowTreeMouseHandler,\n IrisGridSortMouseHandler,\n IrisGridTokenMouseHandler,\n PendingMouseHandler,\n} from './mousehandlers';\nimport ToastBottomBar from './ToastBottomBar';\nimport IrisGridMetricCalculator from './IrisGridMetricCalculator';\nimport IrisGridModelUpdater from './IrisGridModelUpdater';\nimport IrisGridRenderer from './IrisGridRenderer';\nimport IrisGridTheme, { IrisGridThemeType } from './IrisGridTheme';\nimport ColumnStatistics from './ColumnStatistics';\nimport './IrisGrid.scss';\nimport AdvancedFilterCreator from './AdvancedFilterCreator';\nimport {\n Aggregations,\n AggregationEdit,\n AggregationUtils,\n ChartBuilder,\n CustomColumnBuilder,\n OptionType,\n RollupRows,\n TableCsvExporter,\n TableSaver,\n VisibilityOrderingBuilder,\n} from './sidebar';\nimport IrisGridUtils from './IrisGridUtils';\nimport CrossColumnSearch from './CrossColumnSearch';\nimport IrisGridModel from './IrisGridModel';\nimport IrisGridPartitionSelector from './IrisGridPartitionSelector';\nimport SelectDistinctBuilder from './sidebar/SelectDistinctBuilder';\nimport AdvancedSettingsType from './sidebar/AdvancedSettingsType';\nimport AdvancedSettingsMenu, {\n AdvancedSettingsMenuCallback,\n} from './sidebar/AdvancedSettingsMenu';\nimport SHORTCUTS from './IrisGridShortcuts';\nimport ConditionalFormattingMenu from './sidebar/conditional-formatting/ConditionalFormattingMenu';\n\nimport ConditionalFormatEditor from './sidebar/conditional-formatting/ConditionalFormatEditor';\nimport IrisGridCellOverflowModal from './IrisGridCellOverflowModal';\nimport GotoRow from './GotoRow';\nimport {\n Aggregation,\n AggregationSettings,\n} from './sidebar/aggregations/Aggregations';\nimport { ChartBuilderSettings } from './sidebar/ChartBuilder';\nimport AggregationOperation from './sidebar/aggregations/AggregationOperation';\nimport { UIRollupConfig } from './sidebar/RollupRows';\nimport {\n ReadonlyAdvancedFilterMap,\n ColumnName,\n ReadonlyQuickFilterMap,\n ReadonlyAggregationMap,\n ReadonlyOperationMap,\n Action,\n OptionItem,\n UITotalsTableConfig,\n InputFilter,\n PendingDataMap,\n AdvancedFilterOptions,\n PendingDataErrorMap,\n QuickFilterMap,\n OperationMap,\n} from './CommonTypes';\nimport ColumnHeaderGroup from './ColumnHeaderGroup';\n\nconst log = Log.module('IrisGrid');\n\nconst UPDATE_DOWNLOAD_THROTTLE = 500;\n\nconst SET_FILTER_DEBOUNCE = 250;\n\nconst SEEK_ROW_DEBOUNCE = 250;\n\nconst SET_CONDITIONAL_FORMAT_DEBOUNCE = 250;\n\nconst DEFAULT_AGGREGATION_SETTINGS = Object.freeze({\n aggregations: EMPTY_ARRAY,\n showOnTop: false,\n});\n\nconst UNFORMATTED_DATE_PATTERN = `yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS z`;\n\nfunction isEmptyConfig({\n advancedFilters,\n aggregationSettings,\n customColumns,\n quickFilters,\n reverseType,\n rollupConfig,\n searchFilter,\n selectDistinctColumns,\n sorts,\n}: {\n advancedFilters: ReadonlyAdvancedFilterMap;\n aggregationSettings: AggregationSettings;\n customColumns: readonly ColumnName[];\n quickFilters: ReadonlyQuickFilterMap;\n reverseType: ReverseType;\n rollupConfig?: UIRollupConfig;\n searchFilter?: FilterCondition;\n selectDistinctColumns: readonly ColumnName[];\n sorts: readonly Sort[];\n}) {\n return (\n advancedFilters.size === 0 &&\n aggregationSettings.aggregations.length === 0 &&\n customColumns.length === 0 &&\n quickFilters.size === 0 &&\n reverseType === TableUtils.REVERSE_TYPE.NONE &&\n rollupConfig == null &&\n searchFilter == null &&\n selectDistinctColumns.length === 0 &&\n sorts.length === 0\n );\n}\nexport type FilterData = {\n operator: FilterTypeValue;\n text: string;\n value: unknown;\n startColumnIndex: number;\n};\n\nexport type FilterMap = Map<\n ColumnName,\n {\n columnType: string;\n filterList: FilterData[];\n }\n>;\nexport interface IrisGridProps {\n children: React.ReactNode;\n advancedFilters: ReadonlyAdvancedFilterMap;\n advancedSettings: Map<AdvancedSettingsType, boolean>;\n alwaysFetchColumns: readonly ColumnName[];\n isFilterBarShown: boolean;\n applyInputFiltersOnInit: boolean;\n conditionalFormats: readonly SidebarFormattingRule[];\n customColumnFormatMap: Map<ColumnName, FormattingRule>;\n movedColumns: readonly MoveOperation[];\n movedRows: readonly MoveOperation[];\n inputFilters: readonly InputFilter[];\n customFilters: readonly FilterCondition[];\n model: IrisGridModel;\n onCreateChart: (settings: ChartBuilderSettings, model: IrisGridModel) => void;\n onColumnSelected: (column: Column) => void;\n onError: (error: unknown) => void;\n onDataSelected: (index: ModelIndex, map: Record<ColumnName, unknown>) => void;\n onStateChange: (irisGridState: IrisGridState, gridState: GridState) => void;\n onPartitionAppend: (partitionColumn: Column, value: string) => void;\n onAdvancedSettingsChange: AdvancedSettingsMenuCallback;\n partition: string;\n partitionColumn: Column;\n sorts: readonly Sort[];\n reverseType: ReverseType;\n quickFilters: ReadonlyQuickFilterMap | null;\n customColumns: readonly ColumnName[];\n selectDistinctColumns: readonly ColumnName[];\n settings?: Settings;\n userColumnWidths: ModelSizeMap;\n userRowHeights: ModelSizeMap;\n onSelectionChanged: (gridRanges: readonly GridRange[]) => void;\n rollupConfig?: UIRollupConfig;\n aggregationSettings: AggregationSettings;\n\n isSelectingColumn: boolean;\n isSelectingPartition: boolean;\n isStuckToBottom: boolean;\n isStuckToRight: boolean;\n\n // eslint-disable-next-line react/no-unused-prop-types\n columnSelectionValidator: (value: Column | null) => boolean;\n columnAllowedCursor: string;\n\n // eslint-disable-next-line react/no-unused-prop-types\n columnNotAllowedCursor: string;\n name: string;\n onlyFetchVisibleColumns: boolean;\n\n showSearchBar: boolean;\n searchValue: string;\n selectedSearchColumns: readonly ColumnName[];\n invertSearchColumns: boolean;\n\n // eslint-disable-next-line react/no-unused-prop-types\n onContextMenu: (obj: {\n model: IrisGridModel;\n value: unknown;\n valueText: string | null;\n column: Column;\n rowIndex: GridRangeIndex;\n columnIndex: GridRangeIndex;\n modelRow: GridRangeIndex;\n modelColumn: GridRangeIndex;\n }) => ContextAction;\n\n pendingDataMap?: PendingDataMap;\n getDownloadWorker: () => Promise<ServiceWorker>;\n\n canCopy: boolean;\n canDownloadCsv: boolean;\n frozenColumns: readonly ColumnName[];\n\n // Theme override for IrisGridTheme\n theme: GridThemeType;\n\n canToggleSearch: boolean;\n\n columnHeaderGroups?: readonly ColumnHeaderGroup[];\n}\n\nexport interface IrisGridState {\n isFilterBarShown: boolean;\n isSelectingPartition: boolean;\n focusedFilterBarColumn: number | null;\n metricCalculator: IrisGridMetricCalculator;\n metrics?: GridMetrics;\n keyHandlers: readonly KeyHandler[];\n mouseHandlers: readonly GridMouseHandler[];\n\n partition: string | null;\n partitionColumn: Column | null;\n partitionTable: Table | null;\n partitionFilters: readonly FilterCondition[];\n // setAdvancedFilter and setQuickFilter mutate the arguments\n // so we want to always use map copies from the state instead of props\n quickFilters: ReadonlyQuickFilterMap;\n advancedFilters: ReadonlyAdvancedFilterMap;\n shownAdvancedFilter: number | null;\n hoverAdvancedFilter: number | null;\n\n sorts: readonly Sort[];\n reverseType: ReverseType;\n customColumns: readonly ColumnName[];\n selectDistinctColumns: readonly ColumnName[];\n\n // selected range in table\n selectedRanges: readonly GridRange[];\n\n // Current ongoing copy operation\n copyOperation: CopyOperation | null;\n\n // The filter that is currently being applied. Reset after update is received\n loadingText: string | null;\n loadingScrimProgress: number | null;\n loadingSpinnerShown: boolean;\n\n movedColumns: readonly MoveOperation[];\n movedRows: readonly MoveOperation[];\n\n shownColumnTooltip: number | null;\n\n formatter: Formatter;\n isMenuShown: boolean;\n customColumnFormatMap: Map<ColumnName, FormattingRule>;\n\n conditionalFormats: readonly SidebarFormattingRule[];\n conditionalFormatEditIndex: number | null;\n conditionalFormatPreview?: SidebarFormattingRule;\n\n // Column user is hovering over for selection\n hoverSelectColumn: GridRangeIndex;\n\n isTableDownloading: boolean;\n isReady: boolean;\n tableDownloadStatus: string;\n tableDownloadProgress: number;\n tableDownloadEstimatedTime: number | null;\n\n showSearchBar: boolean;\n searchFilter?: FilterCondition;\n searchValue: string;\n selectedSearchColumns: readonly ColumnName[];\n invertSearchColumns: boolean;\n\n rollupConfig?: UIRollupConfig;\n rollupSelectedColumns: readonly ColumnName[];\n aggregationSettings: AggregationSettings;\n selectedAggregation: Aggregation | null;\n\n openOptions: readonly OptionItem[];\n\n pendingRowCount: number;\n pendingDataMap: PendingDataMap;\n pendingDataErrors: PendingDataErrorMap;\n pendingSavePromise: Promise<void> | null;\n pendingSaveError: string | null;\n\n toastMessage: JSX.Element | null;\n frozenColumns: readonly ColumnName[];\n showOverflowModal: boolean;\n overflowText: string;\n overflowButtonTooltipProps: CSSProperties | null;\n expandCellTooltipProps: CSSProperties | null;\n expandTooltipDisplayValue: string;\n linkHoverTooltipProps: CSSProperties | null;\n linkHoverDisplayValue: string;\n\n gotoRow: string;\n gotoRowError: string;\n gotoValueError: string;\n isGotoShown: boolean;\n\n gotoValueSelectedColumnName: ColumnName;\n gotoValueSelectedFilter: FilterTypeValue;\n gotoValue: string;\n\n columnHeaderGroups: readonly ColumnHeaderGroup[];\n}\n\nexport class IrisGrid extends Component<IrisGridProps, IrisGridState> {\n static minDebounce = 150;\n\n static maxDebounce = 500;\n\n static loadingSpinnerDelay = 800;\n\n static defaultProps = {\n children: null,\n advancedFilters: EMPTY_MAP,\n advancedSettings: EMPTY_MAP,\n alwaysFetchColumns: EMPTY_ARRAY,\n conditionalFormats: EMPTY_ARRAY,\n customColumnFormatMap: EMPTY_MAP,\n isFilterBarShown: false,\n applyInputFiltersOnInit: false,\n movedColumns: EMPTY_ARRAY,\n movedRows: EMPTY_ARRAY,\n inputFilters: EMPTY_ARRAY,\n customFilters: EMPTY_ARRAY,\n onCreateChart: undefined,\n onColumnSelected: (): void => undefined,\n onDataSelected: (): void => undefined,\n onError: (): void => undefined,\n onStateChange: (): void => undefined,\n onPartitionAppend: (): void => undefined,\n onAdvancedSettingsChange: (): void => undefined,\n partition: null,\n partitionColumn: null,\n quickFilters: EMPTY_MAP,\n selectDistinctColumns: EMPTY_ARRAY,\n sorts: EMPTY_ARRAY,\n reverseType: TableUtils.REVERSE_TYPE.NONE,\n customColumns: EMPTY_ARRAY,\n aggregationSettings: DEFAULT_AGGREGATION_SETTINGS,\n rollupConfig: undefined,\n userColumnWidths: EMPTY_MAP,\n userRowHeights: EMPTY_MAP,\n onSelectionChanged: (): void => undefined,\n isSelectingColumn: false,\n isSelectingPartition: false,\n isStuckToBottom: false,\n isStuckToRight: false,\n columnSelectionValidator: null,\n columnAllowedCursor: null,\n columnNotAllowedCursor: null,\n name: 'table',\n onlyFetchVisibleColumns: true,\n showSearchBar: false,\n searchValue: '',\n selectedSearchColumns: null,\n invertSearchColumns: true,\n onContextMenu: (): void => undefined,\n pendingDataMap: EMPTY_MAP,\n getDownloadWorker: undefined,\n settings: {\n timeZone: 'America/New_York',\n defaultDateTimeFormat: DateUtils.FULL_DATE_FORMAT,\n showTimeZone: false,\n showTSeparator: true,\n truncateNumbersWithPound: false,\n formatter: EMPTY_ARRAY,\n decimalFormatOptions: PropTypes.shape({\n defaultFormatString: PropTypes.string,\n }),\n integerFormatOptions: PropTypes.shape({\n defaultFormatString: PropTypes.string,\n }),\n },\n canCopy: true,\n canDownloadCsv: true,\n frozenColumns: null,\n theme: IrisGridTheme,\n canToggleSearch: true,\n };\n\n constructor(props: IrisGridProps) {\n super(props);\n\n this.handleAdvancedFilterChange = this.handleAdvancedFilterChange.bind(\n this\n );\n this.handleAdvancedFilterSortChange = this.handleAdvancedFilterSortChange.bind(\n this\n );\n this.handleAdvancedFilterDone = this.handleAdvancedFilterDone.bind(this);\n this.handleAdvancedMenuOpened = this.handleAdvancedMenuOpened.bind(this);\n this.handleGotoRowOpened = this.handleGotoRowOpened.bind(this);\n this.handleGotoRowClosed = this.handleGotoRowClosed.bind(this);\n this.handleAdvancedMenuClosed = this.handleAdvancedMenuClosed.bind(this);\n this.handleAggregationChange = this.handleAggregationChange.bind(this);\n this.handleAggregationsChange = this.handleAggregationsChange.bind(this);\n this.handleAggregationEdit = this.handleAggregationEdit.bind(this);\n this.handleAnimationLoop = this.handleAnimationLoop.bind(this);\n this.handleAnimationStart = this.handleAnimationStart.bind(this);\n this.handleAnimationEnd = this.handleAnimationEnd.bind(this);\n this.handleChartChange = this.handleChartChange.bind(this);\n this.handleChartCreate = this.handleChartCreate.bind(this);\n this.handleGridError = this.handleGridError.bind(this);\n this.handleFilterBarChange = this.handleFilterBarChange.bind(this);\n this.handleFilterBarDone = this.handleFilterBarDone.bind(this);\n this.handleFilterBarTab = this.handleFilterBarTab.bind(this);\n this.handleCancel = this.handleCancel.bind(this);\n this.handleMenu = this.handleMenu.bind(this);\n this.handleMenuClose = this.handleMenuClose.bind(this);\n this.handleMenuSelect = this.handleMenuSelect.bind(this);\n this.handleMenuBack = this.handleMenuBack.bind(this);\n this.handleRequestFailed = this.handleRequestFailed.bind(this);\n this.handleSelectionChanged = this.handleSelectionChanged.bind(this);\n this.handleMovedColumnsChanged = this.handleMovedColumnsChanged.bind(this);\n this.handleHeaderGroupsChanged = this.handleHeaderGroupsChanged.bind(this);\n this.handleUpdate = this.handleUpdate.bind(this);\n this.handleTooltipRef = this.handleTooltipRef.bind(this);\n this.handleViewChanged = this.handleViewChanged.bind(this);\n this.handleFormatSelection = this.handleFormatSelection.bind(this);\n this.handleConditionalFormatCreate = this.handleConditionalFormatCreate.bind(\n this\n );\n this.handleConditionalFormatEdit = this.handleConditionalFormatEdit.bind(\n this\n );\n this.handleConditionalFormatsChange = this.handleConditionalFormatsChange.bind(\n this\n );\n this.handleConditionalFormatEditorSave = this.handleConditionalFormatEditorSave.bind(\n this\n );\n this.handleConditionalFormatEditorCancel = this.handleConditionalFormatEditorCancel.bind(\n this\n );\n this.handleUpdateCustomColumns = this.handleUpdateCustomColumns.bind(this);\n this.handleCustomColumnsChanged = this.handleCustomColumnsChanged.bind(\n this\n );\n this.handleSelectDistinctChanged = this.handleSelectDistinctChanged.bind(\n this\n );\n this.handlePendingDataUpdated = this.handlePendingDataUpdated.bind(this);\n this.handlePendingCommitClicked = this.handlePendingCommitClicked.bind(\n this\n );\n this.handlePendingDiscardClicked = this.handlePendingDiscardClicked.bind(\n this\n );\n this.handleGotoRowSelectedRowNumberSubmit = this.handleGotoRowSelectedRowNumberSubmit.bind(\n this\n );\n this.focusRowInGrid = this.focusRowInGrid.bind(this);\n this.handleDownloadTable = this.handleDownloadTable.bind(this);\n this.handleDownloadTableStart = this.handleDownloadTableStart.bind(this);\n this.handleCancelDownloadTable = this.handleCancelDownloadTable.bind(this);\n this.handleDownloadCanceled = this.handleDownloadCanceled.bind(this);\n this.handleDownloadCompleted = this.handleDownloadCompleted.bind(this);\n this.handlePartitionAppend = this.handlePartitionAppend.bind(this);\n this.handlePartitionChange = this.handlePartitionChange.bind(this);\n this.handlePartitionFetchAll = this.handlePartitionFetchAll.bind(this);\n this.handlePartitionDone = this.handlePartitionDone.bind(this);\n this.handleColumnVisibilityChanged = this.handleColumnVisibilityChanged.bind(\n this\n );\n this.handleColumnVisibilityReset = this.handleColumnVisibilityReset.bind(\n this\n );\n this.handleCrossColumnSearch = this.handleCrossColumnSearch.bind(this);\n this.handleRollupChange = this.handleRollupChange.bind(this);\n this.handleOverflowClose = this.handleOverflowClose.bind(this);\n this.getColumnBoundingRect = this.getColumnBoundingRect.bind(this);\n this.handleGotoRowSelectedRowNumberChanged = this.handleGotoRowSelectedRowNumberChanged.bind(\n this\n );\n this.handleGotoValueSelectedColumnNameChanged = this.handleGotoValueSelectedColumnNameChanged.bind(\n this\n );\n this.handleGotoValueSelectedFilterChanged = this.handleGotoValueSelectedFilterChanged.bind(\n this\n );\n this.handleGotoValueChanged = this.handleGotoValueChanged.bind(this);\n this.handleGotoValueSubmitted = this.handleGotoValueSubmitted.bind(this);\n\n this.grid = null;\n this.gridWrapper = null;\n this.lastLoadedConfig = null;\n this.pending = new Pending();\n this.globalColumnFormats = EMPTY_ARRAY;\n this.decimalFormatOptions = {};\n this.integerFormatOptions = {};\n this.truncateNumbersWithPound = false;\n\n // When the loading scrim started/when it should extend to the end of the screen.\n this.renderer = new IrisGridRenderer();\n this.tableSaver = null;\n this.crossColumnRef = React.createRef();\n this.isAnimating = false;\n this.filterInputRef = React.createRef();\n\n this.toggleFilterBarAction = {\n action: () => this.toggleFilterBar(),\n shortcut: SHORTCUTS.TABLE.TOGGLE_QUICK_FILTER,\n };\n\n this.toggleSearchBarAction = {\n action: () => this.toggleSearchBar(),\n shortcut: SHORTCUTS.TABLE.TOGGLE_SEARCH,\n };\n\n this.toggleGotoRowAction = {\n action: () => this.toggleGotoRow(),\n shortcut: SHORTCUTS.TABLE.GOTO_ROW,\n };\n\n this.discardAction = {\n action: () => {\n const { model } = this.props;\n if (\n isEditableGridModel(model) &&\n model.isEditable &&\n model.pendingDataMap.size > 0\n ) {\n this.discardPending().catch(log.error);\n }\n },\n shortcut: SHORTCUTS.INPUT_TABLE.DISCARD,\n };\n this.commitAction = {\n action: () => {\n const { model } = this.props;\n if (\n isEditableGridModel(model) &&\n model.isEditable &&\n model.pendingDataMap.size > 0 &&\n model.pendingDataErrors.size === 0\n ) {\n this.commitPending().catch(log.error);\n }\n },\n shortcut: SHORTCUTS.INPUT_TABLE.COMMIT,\n };\n this.contextActions = [\n this.toggleFilterBarAction,\n this.toggleSearchBarAction,\n this.toggleGotoRowAction,\n this.discardAction,\n this.commitAction,\n ];\n\n const {\n aggregationSettings,\n conditionalFormats,\n customColumnFormatMap,\n isFilterBarShown,\n isSelectingPartition,\n model,\n movedColumns: movedColumnsProp,\n movedRows: movedRowsProp,\n partition,\n partitionColumn,\n rollupConfig,\n userColumnWidths,\n userRowHeights,\n showSearchBar,\n searchValue,\n selectedSearchColumns,\n invertSearchColumns,\n advancedFilters,\n quickFilters,\n selectDistinctColumns,\n pendingDataMap,\n canCopy,\n frozenColumns,\n columnHeaderGroups,\n } = props;\n\n const keyHandlers: KeyHandler[] = [\n new ReverseKeyHandler(this),\n new ClearFilterKeyHandler(this),\n ];\n if (canCopy) {\n keyHandlers.push(new CopyKeyHandler(this));\n }\n const { dh } = model;\n const mouseHandlers = [\n new IrisGridCellOverflowMouseHandler(this),\n new IrisGridRowTreeMouseHandler(this),\n new IrisGridTokenMouseHandler(this),\n new IrisGridColumnSelectMouseHandler(this),\n new IrisGridColumnTooltipMouseHandler(this),\n new IrisGridSortMouseHandler(this),\n new IrisGridFilterMouseHandler(this),\n new IrisGridContextMenuHandler(this, dh),\n new IrisGridDataSelectMouseHandler(this),\n new PendingMouseHandler(this),\n ];\n\n const movedColumns =\n movedColumnsProp.length > 0\n ? movedColumnsProp\n : model.initialMovedColumns;\n const movedRows =\n movedRowsProp.length > 0 ? movedRowsProp : model.initialMovedRows;\n\n const metricCalculator = new IrisGridMetricCalculator({\n userColumnWidths: new Map(userColumnWidths),\n userRowHeights: new Map(userRowHeights),\n movedColumns,\n initialColumnWidths: new Map(\n model?.layoutHints?.hiddenColumns?.map(name => [\n model.getColumnIndexByName(name),\n 0,\n ])\n ),\n });\n const searchColumns = selectedSearchColumns ?? [];\n const searchFilter = CrossColumnSearch.createSearchFilter(\n dh,\n searchValue,\n searchColumns,\n model.columns,\n invertSearchColumns\n );\n\n this.tableUtils = new TableUtils(dh);\n\n this.state = {\n isFilterBarShown,\n isSelectingPartition,\n focusedFilterBarColumn: null,\n metricCalculator,\n metrics: undefined,\n keyHandlers,\n mouseHandlers,\n\n partition,\n partitionColumn,\n partitionTable: null,\n partitionFilters: [],\n // setAdvancedFilter and setQuickFilter mutate the arguments\n // so we want to always use map copies from the state instead of props\n quickFilters: quickFilters ? new Map(quickFilters) : new Map(),\n advancedFilters: new Map(advancedFilters),\n shownAdvancedFilter: null,\n hoverAdvancedFilter: null,\n sorts: [],\n reverseType: TableUtils.REVERSE_TYPE.NONE,\n customColumns: [],\n selectDistinctColumns,\n\n // selected range in table\n selectedRanges: [],\n\n // Current ongoing copy operation\n copyOperation: null,\n\n // The filter that is currently being applied. Reset after update is received\n loadingText: null,\n loadingScrimProgress: null,\n loadingSpinnerShown: false,\n\n movedColumns,\n movedRows,\n\n shownColumnTooltip: null,\n\n formatter: new Formatter(dh),\n isMenuShown: false,\n customColumnFormatMap: new Map(customColumnFormatMap),\n\n conditionalFormats,\n conditionalFormatEditIndex: null,\n conditionalFormatPreview: undefined,\n\n // Column user is hovering over for selection\n hoverSelectColumn: null,\n\n isTableDownloading: false,\n isReady: false,\n tableDownloadStatus: '',\n tableDownloadProgress: 0,\n tableDownloadEstimatedTime: 0,\n\n showSearchBar,\n searchFilter,\n searchValue,\n selectedSearchColumns: searchColumns,\n invertSearchColumns,\n\n rollupConfig,\n rollupSelectedColumns: [],\n aggregationSettings,\n selectedAggregation: null,\n\n openOptions: [],\n\n pendingRowCount: 0,\n pendingDataMap: pendingDataMap ?? new Map(),\n pendingDataErrors: new Map(),\n pendingSavePromise: null,\n pendingSaveError: null,\n\n toastMessage: null,\n frozenColumns,\n showOverflowModal: false,\n overflowText: '',\n overflowButtonTooltipProps: null,\n expandCellTooltipProps: null,\n expandTooltipDisplayValue: 'expand',\n linkHoverTooltipProps: null,\n linkHoverDisplayValue: '',\n isGotoShown: false,\n gotoRow: '',\n gotoRowError: '',\n gotoValueError: '',\n\n gotoValueSelectedColumnName: model.columns[0]?.name ?? '',\n gotoValueSelectedFilter: FilterType.eq,\n gotoValue: '',\n columnHeaderGroups: columnHeaderGroups ?? model.initialColumnHeaderGroups,\n };\n }\n\n componentDidMount(): void {\n const { partitionColumn, model } = this.props;\n const column =\n partitionColumn ?? model.columns.find(c => c.isPartitionColumn);\n if (\n model.isFilterRequired &&\n model.isValuesTableAvailable &&\n column != null\n ) {\n this.loadPartitionsTable(column);\n } else {\n this.initState();\n }\n this.startListening(model);\n }\n\n componentDidUpdate(prevProps: IrisGridProps): void {\n const {\n inputFilters,\n isSelectingColumn,\n settings,\n model,\n customFilters,\n sorts,\n } = this.props;\n\n if (model !== prevProps.model) {\n this.stopListening(prevProps.model);\n this.startListening(model);\n }\n\n const changedInputFilters =\n inputFilters !== prevProps.inputFilters\n ? inputFilters.filter(\n inputFilter => !prevProps.inputFilters.includes(inputFilter)\n )\n : [];\n if (changedInputFilters.length > 0) {\n const { advancedSettings } = this.props;\n const replaceExistingFilters =\n advancedSettings.get(\n AdvancedSettingsType.FILTER_CONTROL_CHANGE_CLEARS_ALL_FILTERS\n ) ?? false;\n if (replaceExistingFilters) {\n this.clearGridInputField();\n this.clearCrossColumSearch();\n }\n this.startLoading('Filtering...', true);\n this.applyInputFilters(changedInputFilters, replaceExistingFilters);\n }\n\n if (isSelectingColumn !== prevProps.isSelectingColumn) {\n this.resetColumnSelection();\n }\n if (settings !== prevProps.settings) {\n this.updateFormatterSettings(settings);\n }\n if (customFilters !== prevProps.customFilters) {\n this.startLoading('Filtering...', true);\n }\n if (sorts !== prevProps.sorts) {\n this.updateSorts(sorts);\n }\n const { loadingScrimStartTime, loadingScrimFinishTime } = this;\n if (loadingScrimStartTime != null && loadingScrimFinishTime != null) {\n window.requestAnimationFrame(() => {\n const now = Date.now();\n const currentTime = now - loadingScrimStartTime;\n const totalTime = loadingScrimFinishTime - loadingScrimStartTime;\n const loadingScrimProgress = Math.min(currentTime / totalTime, 1);\n if (loadingScrimFinishTime < now) {\n this.loadingScrimStartTime = undefined;\n this.loadingScrimFinishTime = undefined;\n }\n\n this.setState(state => {\n if (state.loadingScrimProgress == null) {\n log.debug2('Ignoring scrim update because loading cancelled.');\n return null;\n }\n\n return { loadingScrimProgress };\n });\n });\n }\n\n this.sendStateChange();\n }\n\n componentWillUnmount(): void {\n const { model } = this.props;\n this.stopListening(model);\n this.pending.cancel();\n this.updateSearchFilter.cancel();\n\n if (this.loadingTimer) {\n clearTimeout(this.loadingTimer);\n }\n this.handleDownloadProgressUpdate.cancel();\n if (this.animationFrame !== undefined) {\n cancelAnimationFrame(this.animationFrame);\n }\n }\n\n grid: Grid | null;\n\n gridWrapper: HTMLDivElement | null;\n\n lastFocusedFilterBarColumn?: number;\n\n lastLoadedConfig: Pick<\n IrisGridState,\n | 'advancedFilters'\n | 'aggregationSettings'\n | 'customColumns'\n | 'quickFilters'\n | 'reverseType'\n | 'rollupConfig'\n | 'searchFilter'\n | 'selectDistinctColumns'\n | 'sorts'\n > | null;\n\n tooltip?: Tooltip;\n\n pending: Pending;\n\n globalColumnFormats?: readonly FormattingRule[];\n\n dateTimeFormatterOptions?: DateTimeColumnFormatterOptions;\n\n decimalFormatOptions: { defaultFormatString?: string };\n\n integerFormatOptions: { defaultFormatString?: string };\n\n truncateNumbersWithPound: boolean;\n\n // When the loading scrim started/when it should extend to the end of the screen.\n loadingScrimStartTime?: number;\n\n loadingScrimFinishTime?: number;\n\n animationFrame?: number;\n\n loadingTimer?: ReturnType<typeof setTimeout>;\n\n renderer: IrisGridRenderer;\n\n tableSaver: TableSaver | null;\n\n crossColumnRef: React.RefObject<CrossColumnSearch>;\n\n isAnimating: boolean;\n\n filterInputRef: React.RefObject<FilterInputField>;\n\n toggleFilterBarAction: Action;\n\n toggleSearchBarAction: Action;\n\n toggleGotoRowAction: Action;\n\n discardAction: Action;\n\n commitAction: Action;\n\n contextActions: ContextAction[];\n\n tableUtils: TableUtils;\n\n getAdvancedMenuOpenedHandler = memoize(\n (column: ModelIndex) => this.handleAdvancedMenuOpened.bind(this, column),\n { max: 100 }\n );\n\n getCachedAdvancedFilterMenuActions = memoize(\n (\n model: IrisGridModel,\n column: Column,\n advancedFilterOptions: AdvancedFilterOptions | undefined,\n sortDirection: SortDirection | undefined,\n formatter: Formatter\n ) => (\n <AdvancedFilterCreator\n model={model}\n column={column}\n onFilterChange={this.handleAdvancedFilterChange}\n onSortChange={this.handleAdvancedFilterSortChange}\n onDone={this.handleAdvancedFilterDone}\n options={advancedFilterOptions}\n sortDirection={sortDirection}\n formatter={formatter}\n tableUtils={this.tableUtils}\n />\n ),\n { max: 50 }\n );\n\n getCachedOptionItems = memoize(\n (\n isChartBuilderAvailable: boolean,\n isCustomColumnsAvailable: boolean,\n isFormatColumnsAvailable: boolean,\n isRollupAvailable: boolean,\n isTotalsAvailable: boolean,\n isSelectDistinctAvailable: boolean,\n isExportAvailable: boolean,\n toggleFilterBarAction: Action,\n toggleSearchBarAction: Action,\n toggleGotoRowAction: Action,\n isFilterBarShown: boolean,\n showSearchBar: boolean,\n canDownloadCsv: boolean,\n canToggleSearch: boolean,\n showGotoRow: boolean,\n hasAdvancedSettings: boolean\n ): readonly OptionItem[] => {\n const optionItems: OptionItem[] = [];\n if (isChartBuilderAvailable) {\n optionItems.push({\n type: OptionType.CHART_BUILDER,\n title: 'Chart Builder',\n icon: dhGraphLineUp,\n });\n }\n optionItems.push({\n type: OptionType.VISIBILITY_ORDERING_BUILDER,\n title: 'Organize Columns',\n icon: dhEye,\n });\n if (isFormatColumnsAvailable) {\n optionItems.push({\n type: OptionType.CONDITIONAL_FORMATTING,\n title: 'Conditional Formatting',\n icon: vsEdit,\n });\n }\n if (isCustomColumnsAvailable) {\n optionItems.push({\n type: OptionType.CUSTOM_COLUMN_BUILDER,\n title: 'Custom Columns',\n icon: vsSplitHorizontal,\n });\n }\n if (isRollupAvailable) {\n optionItems.push({\n type: OptionType.ROLLUP_ROWS,\n title: 'Rollup Rows',\n icon: dhTriangleDownSquare,\n });\n }\n if (isTotalsAvailable) {\n optionItems.push({\n type: OptionType.AGGREGATIONS,\n title: 'Aggregate Columns',\n icon: vsSymbolOperator,\n });\n }\n if (isSelectDistinctAvailable) {\n optionItems.push({\n type: OptionType.SELECT_DISTINCT,\n title: 'Select Distinct Values',\n icon: vsRuby,\n });\n }\n if (isExportAvailable && canDownloadCsv) {\n optionItems.push({\n type: OptionType.TABLE_EXPORTER,\n title: 'Download CSV',\n icon: vsCloudDownload,\n });\n }\n if (hasAdvancedSettings) {\n optionItems.push({\n type: OptionType.ADVANCED_SETTINGS,\n title: 'Advanced Settings',\n icon: vsTools,\n });\n }\n optionItems.push({\n type: OptionType.QUICK_FILTERS,\n title: 'Quick Filters',\n subtitle: toggleFilterBarAction.shortcut.getDisplayText(),\n icon: vsFilter,\n isOn: isFilterBarShown,\n onChange: toggleFilterBarAction.action,\n });\n if (canToggleSearch) {\n optionItems.push({\n type: OptionType.SEARCH_BAR,\n title: 'Search Bar',\n subtitle: toggleSearchBarAction.shortcut.getDisplayText(),\n icon: vsSearch,\n isOn: showSearchBar,\n onChange: toggleSearchBarAction.action,\n });\n }\n optionItems.push({\n type: OptionType.GOTO,\n title: 'Go to',\n subtitle: toggleGotoRowAction.shortcut.getDisplayText(),\n icon: vsReply,\n isOn: showGotoRow,\n onChange: toggleGotoRowAction.action,\n });\n\n return Object.freeze(optionItems);\n },\n { max: 1 }\n );\n\n getCachedHiddenColumns = memoize(\n (\n metricCalculator: IrisGridMetricCalculator,\n userColumnWidths: ModelSizeMap\n ): readonly ModelIndex[] =>\n IrisGridUtils.getHiddenColumns(\n new Map([...metricCalculator.initialColumnWidths, ...userColumnWidths])\n ),\n { max: 1 }\n );\n\n getAggregationMap = memoize(\n (\n columns: readonly Column[],\n aggregations: readonly Aggregation[]\n ): ReadonlyAggregationMap => {\n const aggregationMap = {} as Record<AggregationOperation, string[]>;\n aggregations.forEach(({ operation, selected, invert }) => {\n aggregationMap[operation] = AggregationUtils.getOperationColumnNames(\n columns,\n operation,\n selected,\n invert\n );\n });\n return aggregationMap;\n }\n );\n\n getOperationMap = memoize(\n (\n columns: readonly Column[],\n aggregations: readonly Aggregation[]\n ): ReadonlyOperationMap => {\n const operationMap: OperationMap = {};\n aggregations\n .filter(\n (a: Aggregation) => !AggregationUtils.isRollupOperation(a.operation)\n )\n .forEach(({ operation, selected, invert }) => {\n AggregationUtils.getOperationColumnNames(\n columns,\n operation,\n selected,\n invert\n ).forEach(name => {\n const newOperations = [...(operationMap[name] ?? []), operation];\n operationMap[name] = Object.freeze(newOperations);\n });\n });\n return operationMap;\n }\n );\n\n getOperationOrder = memoize(\n (aggregations: readonly Aggregation[]): AggregationOperation[] =>\n aggregations\n .map((a: Aggregation) => a.operation)\n .filter(\n (o: AggregationOperation) => !AggregationUtils.isRollupOperation(o)\n )\n );\n\n getCachedFormatColumns = memoize(\n (\n dh: DhType,\n columns: readonly Column[],\n rules: readonly SidebarFormattingRule[]\n ) => getFormatColumns(dh, columns, rules)\n );\n\n /**\n * Builds formatColumns array based on the provided formatting rules with optional preview\n * @param columns Array of columns\n * @param rulesParam Array of formatting rules\n * @param preview Optional temporary formatting rule for previewing live changes\n * @param editIndex Index in the rulesParam array to replace with the preview, null if preview not applicable\n * @returns Format columns array\n */\n getCachedPreviewFormatColumns = memoize(\n (\n dh: DhType,\n columns: readonly Column[],\n rulesParam: readonly SidebarFormattingRule[],\n preview?: SidebarFormattingRule,\n editIndex?: number\n ): CustomColumn[] => {\n log.debug(\n 'getCachedPreviewFormatColumns',\n rulesParam,\n preview,\n editIndex\n );\n if (preview !== undefined && editIndex !== undefined) {\n const rules = [...rulesParam];\n rules[editIndex] = preview;\n return this.getCachedFormatColumns(dh, columns, rules);\n }\n\n return this.getCachedFormatColumns(dh, columns, rulesParam);\n }\n );\n\n getModelRollupConfig = memoize(\n (\n originalColumns: readonly Column[],\n config: UIRollupConfig | undefined,\n aggregationSettings: AggregationSettings\n ) =>\n IrisGridUtils.getModelRollupConfig(\n originalColumns,\n config,\n aggregationSettings\n )\n );\n\n getModelTotalsConfig = memoize(\n (\n columns: readonly Column[],\n config: UIRollupConfig | undefined,\n aggregationSettings: AggregationSettings\n ): UITotalsTableConfig | null => {\n const { aggregations, showOnTop } = aggregationSettings;\n // If we've got rollups, then aggregations are applied as part of that...\n if (\n (config?.columns?.length ?? 0) > 0 ||\n (aggregations?.length ?? 0) === 0\n ) {\n return null;\n }\n\n const operationMap = this.getOperationMap(columns, aggregations);\n const operationOrder = this.getOperationOrder(aggregations);\n\n return { operationMap, operationOrder, showOnTop };\n }\n );\n\n getCachedStateOverride = memoize(\n (\n hoverSelectColumn: GridRangeIndex,\n isFilterBarShown: boolean,\n isSelectingColumn: boolean,\n loadingScrimProgress: number | null,\n quickFilters: ReadonlyQuickFilterMap,\n advancedFilters: ReadonlyAdvancedFilterMap,\n sorts: readonly Sort[],\n reverseType: ReverseType,\n rollupConfig: UIRollupConfig | undefined,\n isMenuShown: boolean\n ) => ({\n hoverSelectColumn,\n isFilterBarShown,\n isSelectingColumn,\n loadingScrimProgress,\n quickFilters,\n advancedFilters,\n sorts,\n reverseType,\n rollupConfig,\n isMenuShown,\n }),\n { max: 1 }\n );\n\n getCachedFilter = memoize(\n (\n customFilters: readonly FilterCondition[],\n quickFilters: ReadonlyQuickFilterMap,\n advancedFilters: ReadonlyAdvancedFilterMap,\n partitionFilters: readonly FilterCondition[],\n searchFilter: FilterCondition | undefined\n ) => [\n ...(customFilters ?? []),\n ...(partitionFilters ?? []),\n ...IrisGridUtils.getFiltersFromFilterMap(quickFilters),\n ...IrisGridUtils.getFiltersFromFilterMap(advancedFilters),\n ...(searchFilter !== undefined ? [searchFilter] : []),\n ],\n { max: 1 }\n );\n\n getCachedTheme = memoize(\n (\n theme: GridThemeType,\n isEditable: boolean,\n floatingRowCount: number\n ): Partial<IrisGridThemeType> => ({\n ...IrisGridTheme,\n ...theme,\n autoSelectRow: !isEditable,\n // We only show the row footers when we have floating rows for aggregations\n rowFooterWidth: floatingRowCount > 0 ? theme.rowFooterWidth : 0,\n }),\n { max: 1 }\n );\n\n getValueForCell(\n columnIndex: GridRangeIndex,\n rowIndex: GridRangeIndex,\n rawValue = false\n ): string | unknown {\n const { model } = this.props;\n const { dh } = model;\n const modelColumn = this.getModelColumn(columnIndex);\n const modelRow = this.getModelRow(rowIndex);\n if (rawValue && modelColumn != null && modelRow != null) {\n const value = model.valueForCell(modelColumn, modelRow);\n if (TableUtils.isDateType(model.columns[modelColumn].type)) {\n // The returned value is just a long value, we should return the value formatted as a full date string\n const { formatter } = model;\n return dh.i18n.DateTimeFormat.format(\n UNFORMATTED_DATE_PATTERN,\n value as number | Date | DateWrapper,\n dh.i18n.TimeZone.getTimeZone(formatter.timeZone)\n );\n }\n return value;\n }\n if (rawValue) {\n return null;\n }\n if (modelColumn != null && modelRow != null) {\n return model.textForCell(modelColumn, modelRow);\n }\n return '';\n }\n\n getModelColumn(columnIndex: GridRangeIndex): ModelIndex | null | undefined {\n const { metrics } = this.state;\n assertNotNull(metrics);\n const { modelColumns } = metrics;\n if (modelColumns == null) {\n return null;\n }\n\n return columnIndex != null ? modelColumns.get(columnIndex) : null;\n }\n\n getModelRow(rowIndex: GridRangeIndex): ModelIndex | null | undefined {\n const { metrics } = this.state;\n assertNotNull(metrics);\n const { modelRows } = metrics;\n if (modelRows == null) {\n return null;\n }\n\n return rowIndex != null ? modelRows.get(rowIndex) : null;\n }\n\n getTheme(): Partial<IrisGridThemeType> {\n const { model, theme } = this.props;\n return this.getCachedTheme(\n theme,\n (isEditableGridModel(model) && model.isEditable) ?? false,\n model.floatingTopRowCount + model.floatingBottomRowCount\n );\n }\n\n getVisibleColumn(modelIndex: ModelIndex): VisibleIndex {\n const { movedColumns } = this.state;\n return GridUtils.getVisibleIndex(modelIndex, movedColumns);\n }\n\n makeQuickFilter(\n column: Column,\n text: string,\n timeZone: string\n ): FilterCondition | null {\n try {\n return this.tableUtils.makeQuickFilter(column, text, timeZone);\n } catch (err) {\n log.error('Error creating quick filter', err);\n }\n return null;\n }\n\n /**\n * Applies the provided input filters as quick filters,\n * and clears any existing quickFilters or advancedFilters on that column\n * @param inputFilters Array of input filters to apply\n * @param replaceExisting If true, new filters will replace the existing ones, instead of merging\n */\n applyInputFilters(\n inputFilters: InputFilter[],\n replaceExisting = false\n ): void {\n const { model } = this.props;\n const { advancedFilters, quickFilters } = this.state;\n const newAdvancedFilters = replaceExisting\n ? new Map()\n : new Map(advancedFilters);\n const newQuickFilters = replaceExisting ? new Map() : new Map(quickFilters);\n\n let isChanged = replaceExisting && advancedFilters.size > 0;\n inputFilters.forEach(({ name, type, value }) => {\n const modelIndex = model.columns.findIndex(\n ({ name: columnName, type: columnType }) =>\n columnName === name && columnType === type\n );\n if (modelIndex >= 0) {\n isChanged = newAdvancedFilters.delete(modelIndex) || isChanged;\n isChanged =\n this.applyQuickFilter(modelIndex, value, newQuickFilters) ||\n isChanged;\n } else {\n log.error('Unable to find column for inputFilter', name, type, value);\n }\n });\n if (isChanged) {\n this.setState({\n quickFilters: newQuickFilters,\n advancedFilters: newAdvancedFilters,\n });\n }\n }\n\n /**\n * Applies a quick filter\n * @param modelIndex The index in the model of the column to set\n * @param value The string value to set to the quick filter\n * @param quickFilters The quick filters map\n * @returns True if the filters have changed because this quick filter was applied\n */\n applyQuickFilter(\n modelIndex: ModelIndex,\n value: string | null,\n quickFilters: QuickFilterMap\n ): boolean {\n const { model } = this.props;\n const { formatter } = model;\n const column = model.columns[modelIndex];\n\n if (value != null && `${value}`.trim().length > 0) {\n const quickFilter = quickFilters.get(modelIndex);\n if (quickFilter != null) {\n const { text } = quickFilter;\n if (text === value) {\n log.debug2('Ignoring change to existing filter');\n return false;\n }\n }\n quickFilters.set(modelIndex, {\n text: value,\n filter: this.makeQuickFilter(column, value, formatter.timeZone),\n });\n return true;\n }\n return quickFilters.delete(modelIndex);\n }\n\n setAdvancedFilterMap(advancedFilters: ReadonlyAdvancedFilterMap): void {\n this.setState({ advancedFilters });\n }\n\n setAdvancedFilter(\n modelIndex: ModelIndex,\n filter: FilterCondition | null,\n options: AdvancedFilterOptions\n ): void {\n log.debug('Setting advanced filter', modelIndex, filter);\n\n this.startLoading('Filtering...', true);\n\n this.setState(({ advancedFilters }) => {\n const newAdvancedFilters = new Map(advancedFilters);\n if (filter == null) {\n newAdvancedFilters.delete(modelIndex);\n } else {\n newAdvancedFilters.set(modelIndex, {\n filter,\n options,\n });\n }\n return { advancedFilters: newAdvancedFilters };\n });\n }\n\n /**\n * Sets a quick filter against the provided column\n * @param modelIndex The index in the model for the column this filter is applied to\n * @param filter A filter to apply to the column, or null if there was an error\n * @param text The original text the filter was created with\n */\n setQuickFilter(\n modelIndex: ModelIndex,\n filter: FilterCondition | null,\n text: string\n ): void {\n log.debug('Setting quick filter', modelIndex, filter, text);\n\n this.startLoading('Filtering...', true);\n\n this.setState(({ quickFilters }) => {\n const newQuickFilters = new Map(quickFilters);\n newQuickFilters.set(modelIndex, { filter, text });\n return { quickFilters: newQuickFilters };\n });\n }\n\n /**\n * Set grid filters based on the filter map\n * @param filterMap Filter map\n */\n setFilterMap(filterMap: FilterMap): void {\n log.debug('setFilterMap', filterMap);\n\n const { advancedSettings } = this.props;\n const clearFiltersOnLinkerFilterUpdate =\n advancedSettings.get(\n AdvancedSettingsType.LINK_CHANGE_CLEARS_ALL_FILTERS\n ) ?? false;\n if (clearFiltersOnLinkerFilterUpdate) {\n this.clearAllFilters();\n }\n\n const { model } = this.props;\n filterMap.forEach(({ columnType, filterList }, columnName) => {\n const column = model.columns.find(\n c => c.name === columnName && c.type === columnType\n );\n if (column == null) {\n return;\n }\n const columnIndex = model.getColumnIndexByName(column.name);\n assertNotNull(columnIndex);\n const combinedText = IrisGridUtils.combineFiltersFromList(\n columnType,\n filterList\n );\n if (combinedText.length === 0) {\n this.removeQuickFilter(columnIndex);\n } else {\n const { formatter } = model;\n this.setQuickFilter(\n columnIndex,\n this.makeQuickFilter(column, combinedText, formatter.timeZone),\n `${combinedText}`\n );\n }\n });\n }\n\n removeColumnFilter(modelColumn: ModelIndex): void {\n this.startLoading('Filtering...', true);\n\n this.setState(\n ({ advancedFilters, quickFilters }: Partial<IrisGridState>) => {\n const newAdvancedFilters = advancedFilters\n ? new Map(advancedFilters)\n : new Map();\n const newQuickFilters = quickFilters\n ? new Map(quickFilters)\n : new Map();\n newQuickFilters.delete(modelColumn);\n newAdvancedFilters.delete(modelColumn);\n\n return {\n quickFilters: newQuickFilters,\n advancedFilters: newAdvancedFilters,\n };\n }\n );\n }\n\n removeQuickFilter(modelColumn: ModelIndex): void {\n this.startLoading('Clearing Filter...', true);\n\n this.setState(({ quickFilters }) => {\n const newQuickFilters = new Map(quickFilters);\n newQuickFilters.delete(modelColumn);\n\n return { quickFilters: newQuickFilters };\n });\n }\n\n clearAllFilters(): void {\n log.debug('Clearing all filters');\n\n const { advancedFilters, quickFilters, searchFilter } = this.state;\n if (\n quickFilters.size === 0 &&\n advancedFilters.size === 0 &&\n searchFilter === null\n ) {\n return;\n }\n\n // if there is an active quick filter input field, reset it as well\n this.clearGridInputField();\n\n this.startLoading('Clearing Filters...', true);\n this.setState({\n quickFilters: new Map(),\n advancedFilters: new Map(),\n searchValue: '',\n searchFilter: undefined,\n });\n }\n\n clearCrossColumSearch(): void {\n log.debug('Clearing cross-column search');\n\n this.setState({\n searchValue: '',\n searchFilter: undefined,\n });\n }\n\n clearGridInputField(): void {\n if (this.filterInputRef.current != null) {\n this.filterInputRef.current.setValue('');\n }\n }\n\n /**\n * Rebuilds all the current filters. Necessary if something like the time zone has changed.\n */\n rebuildFilters(): void {\n log.debug('Rebuilding filters');\n\n const { model } = this.props;\n const { advancedFilters, quickFilters } = this.state;\n const { columns, formatter } = model;\n\n const newAdvancedFilters = new Map();\n const newQuickFilters = new Map();\n\n advancedFilters.forEach((value, key) => {\n const { options } = value;\n const column = columns[key];\n const filter = this.tableUtils.makeAdvancedFilter(\n column,\n options,\n formatter.timeZone\n );\n newAdvancedFilters.set(key, {\n options,\n filter,\n });\n });\n\n quickFilters.forEach((value, key) => {\n const { text } = value;\n const column = columns[key];\n newQuickFilters.set(key, {\n text,\n filter: this.makeQuickFilter(column, text, formatter.timeZone),\n });\n });\n\n this.startLoading('Rebuilding filters...', true);\n this.setState({\n quickFilters: newQuickFilters,\n advancedFilters: newAdvancedFilters,\n });\n }\n\n setFilters({\n quickFilters,\n advancedFilters,\n }: Pick<IrisGridState, 'quickFilters' | 'advancedFilters'>): void {\n this.setState({\n quickFilters,\n advancedFilters,\n });\n }\n\n updateFormatterSettings(settings?: Settings, forceUpdate = true): void {\n const globalColumnFormats = FormatterUtils.getColumnFormats(settings);\n const dateTimeFormatterOptions = FormatterUtils.getDateTimeFormatterOptions(\n settings\n );\n\n const defaultDecimalFormatOptions =\n settings?.defaultDecimalFormatOptions ?? {};\n const defaultIntegerFormatOptions =\n settings?.defaultIntegerFormatOptions ?? {};\n const truncateNumbersWithPound =\n settings?.truncateNumbersWithPound ?? false;\n\n const isColumnFormatChanged = !deepEqual(\n this.globalColumnFormats,\n globalColumnFormats\n );\n const isDateFormattingChanged = !deepEqual(\n this.dateTimeFormatterOptions,\n dateTimeFormatterOptions\n );\n const isDecimalFormattingChanged = !deepEqual(\n this.decimalFormatOptions,\n settings?.defaultDecimalFormatOptions\n );\n const isIntegerFormattingChanged = !deepEqual(\n this.integerFormatOptions,\n defaultIntegerFormatOptions\n );\n const isTruncateNumbersChanged =\n this.truncateNumbersWithPound !== truncateNumbersWithPound;\n if (\n isColumnFormatChanged ||\n isDateFormattingChanged ||\n isDecimalFormattingChanged ||\n isIntegerFormattingChanged ||\n isTruncateNumbersChanged\n ) {\n this.globalColumnFormats = globalColumnFormats;\n this.dateTimeFormatterOptions = dateTimeFormatterOptions;\n this.decimalFormatOptions = defaultDecimalFormatOptions;\n this.integerFormatOptions = defaultIntegerFormatOptions;\n this.truncateNumbersWithPound = truncateNumbersWithPound;\n this.updateFormatter({}, forceUpdate);\n\n if (isDateFormattingChanged && forceUpdate) {\n this.rebuildFilters();\n }\n }\n }\n\n getAlwaysFetchColumns = memoize(\n (\n alwaysFetchColumns: readonly ColumnName[],\n columns: readonly Column[],\n movedColumns: readonly MoveOperation[],\n floatingLeftColumnCount: number,\n floatingRightColumnCount: number,\n draggingRange?: BoundedAxisRange\n ): readonly ColumnName[] => {\n const floatingColumns: ColumnName[] = [];\n\n for (let i = 0; i < floatingLeftColumnCount; i += 1) {\n floatingColumns.push(\n columns[GridUtils.getModelIndex(i, movedColumns)].name\n );\n }\n\n for (let i = 0; i < floatingRightColumnCount; i += 1) {\n floatingColumns.push(\n columns[GridUtils.getModelIndex(columns.length - 1 - i, movedColumns)]\n .name\n );\n }\n\n if (draggingRange) {\n for (let i = draggingRange[0]; i <= draggingRange[1]; i += 1) {\n floatingColumns.push(\n columns[GridUtils.getModelIndex(i, movedColumns)].name\n );\n }\n }\n\n const columnSet = new Set([...alwaysFetchColumns, ...floatingColumns]);\n\n return Object.freeze([...columnSet]);\n }\n );\n\n updateFormatter(\n updatedFormats: { customColumnFormatMap?: Map<ColumnName, FormattingRule> },\n forceUpdate = true\n ): void {\n const { customColumnFormatMap } = this.state;\n const { model } = this.props;\n const update = {\n customColumnFormatMap,\n ...updatedFormats,\n };\n const mergedColumnFormats = [\n ...(this.globalColumnFormats ?? []),\n ...update.customColumnFormatMap.values(),\n ];\n const formatter = new Formatter(\n model.dh,\n mergedColumnFormats,\n this.dateTimeFormatterOptions,\n this.decimalFormatOptions,\n this.integerFormatOptions,\n this.truncateNumbersWithPound\n );\n\n log.debug('updateFormatter', this.globalColumnFormats, mergedColumnFormats);\n\n this.setState({ ...update, formatter }, () => {\n if (forceUpdate && this.grid) {\n this.grid.forceUpdate();\n }\n });\n }\n\n initFormatter(): void {\n const { settings } = this.props;\n this.updateFormatterSettings(settings);\n }\n\n initState(): void {\n const {\n applyInputFiltersOnInit,\n inputFilters,\n sorts,\n model,\n reverseType,\n customColumns,\n searchValue,\n selectedSearchColumns,\n invertSearchColumns,\n } = this.props;\n\n const searchColumns = selectedSearchColumns ?? [];\n const searchFilter = CrossColumnSearch.createSearchFilter(\n model.dh,\n searchValue,\n searchColumns,\n model.columns,\n invertSearchColumns\n );\n\n if (applyInputFiltersOnInit) {\n // There may be more than one input filter on the same column with value === '' applied last\n // We don't want to skip it here, so only excluding the ones that were never applied (null)\n const inputFiltersWithValues = inputFilters.filter(\n inputFilter => inputFilter.value != null\n );\n this.applyInputFilters(inputFiltersWithValues);\n }\n\n this.setState({\n sorts,\n reverseType,\n customColumns,\n isReady: true,\n searchFilter,\n });\n this.initFormatter();\n }\n\n async loadPartitionsTable(partitionColumn: Column): Promise<void> {\n const { model } = this.props;\n this.setState({ isSelectingPartition: true });\n\n try {\n const partitionTable = await this.pending.add(\n model.valuesTable(partitionColumn),\n resolved => resolved.close()\n );\n\n const column = partitionTable.columns[0];\n const sort = column.sort().desc();\n partitionTable.applySort([sort]);\n partitionTable.setViewport(0, 0, [column]);\n\n const data = await this.pending.add(partitionTable.getViewportData());\n if (data.rows.length > 0) {\n const row = data.rows[0];\n const value = row.get(column);\n\n this.updatePartition(value, partitionColumn);\n\n this.setState({ isSelectingPartition: true });\n } else {\n log.info('Table does not have any data, just fetching all');\n this.setState({ isSelectingPartition: false });\n this.handlePartitionFetchAll();\n }\n this.setState({ partitionTable, partitionColumn }, () => {\n this.initState();\n });\n } catch (error) {\n this.handleTableLoadError(error);\n }\n }\n\n updatePartition(partition: string, partitionColumn: Column): void {\n const { model } = this.props;\n const partitionFilter = partitionColumn\n .filter()\n .eq(model.dh.FilterValue.ofString(partition));\n const partitionFilters = [partitionFilter];\n this.setState({\n partition,\n partitionFilters,\n });\n }\n\n copyCell(\n columnIndex: GridRangeIndex,\n rowIndex: GridRangeIndex,\n rawValue = false\n ): void {\n const { canCopy } = this.props;\n if (canCopy) {\n const value = String(\n this.getValueForCell(columnIndex, rowIndex, rawValue)\n );\n copyToClipboard(value).catch(e => log.error('Unable to copy cell', e));\n } else {\n log.error('Attempted to copyCell for user without copy permission.');\n }\n }\n\n /**\n * Copy the provided ranges to the clipboard\n * @paramranges The ranges to copy\n * @param includeHeaders Include the headers or not\n * @param formatValues Whether to format values or not\n * @param error Error message if one occurred\n */\n copyRanges(\n ranges: readonly GridRange[],\n includeHeaders = false,\n formatValues = true,\n error?: string\n ): void {\n const { model, canCopy } = this.props;\n const { metricCalculator, movedColumns } = this.state;\n const userColumnWidths = metricCalculator.getUserColumnWidths();\n\n if (canCopy) {\n const copyOperation = {\n ranges: GridRange.boundedRanges(\n ranges,\n model.columnCount,\n model.rowCount\n ),\n includeHeaders,\n formatValues,\n movedColumns,\n userColumnWidths,\n error,\n };\n\n this.setState({ copyOperation });\n } else {\n log.error('Attempted copyRanges for user without copy permission.');\n }\n }\n\n startLoading(loadingText: string, resetRanges = false): void {\n this.setState({ loadingText });\n\n const theme = this.getTheme();\n\n if (resetRanges && this.grid) {\n this.grid.clearSelectedRanges();\n this.grid.setViewState({ top: 0 }, true);\n }\n\n if (this.loadingScrimStartTime == null) {\n const { minScrimTransitionTime, maxScrimTransitionTime } = theme;\n assertNotNull(minScrimTransitionTime);\n assertNotNull(maxScrimTransitionTime);\n const height = this.gridWrapper?.getBoundingClientRect().height ?? 0;\n const scrimTransitionTime = Math.max(\n minScrimTransitionTime,\n Math.min(height / 2, maxScrimTransitionTime)\n );\n this.loadingScrimStartTime = Date.now();\n this.loadingScrimFinishTime =\n this.loadingScrimStartTime + scrimTransitionTime;\n this.setState({\n loadingScrimProgress: 0,\n });\n this.loadingTimer = setTimeout(() => {\n this.setState({\n loadingSpinnerShown: true,\n });\n }, IrisGrid.loadingSpinnerDelay);\n }\n }\n\n stopLoading(): void {\n this.loadingScrimStartTime = undefined;\n this.loadingScrimFinishTime = undefined;\n this.setState({\n loadingText: null,\n loadingScrimProgress: null,\n loadingSpinnerShown: false,\n });\n\n if (this.loadingTimer != null) {\n clearTimeout(this.loadingTimer);\n this.loadingTimer = undefined;\n }\n }\n\n /**\n * Rolls back the table state to the last known safe state, or if that's not available then clears all sorts/filters/custom columns.\n */\n rollback(): void {\n if (this.lastLoadedConfig) {\n log.debug('loading last loading config', this.lastLoadedConfig);\n const {\n advancedFilters,\n aggregationSettings,\n customColumns,\n quickFilters,\n reverseType,\n rollupConfig,\n searchFilter,\n selectDistinctColumns,\n sorts,\n } = this.lastLoadedConfig;\n\n this.lastLoadedConfig = null;\n this.setState({\n advancedFilters,\n aggregationSettings,\n customColumns,\n quickFilters,\n reverseType,\n rollupConfig,\n searchFilter,\n selectDistinctColumns,\n sorts,\n });\n } else {\n log.debug('remove all sorts, filters, and custom columns');\n this.setState({\n advancedFilters: new Map(),\n aggregationSettings: DEFAULT_AGGREGATION_SETTINGS,\n customColumns: [],\n quickFilters: new Map(),\n reverseType: TableUtils.REVERSE_TYPE.NONE,\n rollupConfig: undefined,\n selectDistinctColumns: [],\n sorts: [],\n });\n }\n }\n\n /**\n * Check if we can rollback the current state to a safe state.\n * @returns true if there's a previously known safe state or if some of the current state isn't empty.\n */\n canRollback(): boolean {\n return this.lastLoadedConfig != null || !isEmptyConfig(this.state);\n }\n\n startListening(model: IrisGridModel): void {\n model.addEventListener(IrisGridModel.EVENT.UPDATED, this.handleUpdate);\n model.addEventListener(\n IrisGridModel.EVENT.REQUEST_FAILED,\n this.handleRequestFailed\n );\n model.addEventListener(\n IrisGridModel.EVENT.COLUMNS_CHANGED,\n this.handleCustomColumnsChanged\n );\n model.addEventListener(\n IrisGridModel.EVENT.PENDING_DATA_UPDATED,\n this.handlePendingDataUpdated\n );\n }\n\n stopListening(model: IrisGridModel): void {\n model.removeEventListener(IrisGridModel.EVENT.UPDATED, this.handleUpdate);\n model.removeEventListener(\n IrisGridModel.EVENT.REQUEST_FAILED,\n this.handleRequestFailed\n );\n model.removeEventListener(\n IrisGridModel.EVENT.COLUMNS_CHANGED,\n this.handleCustomColumnsChanged\n );\n model.removeEventListener(\n IrisGridModel.EVENT.PENDING_DATA_UPDATED,\n this.handlePendingDataUpdated\n );\n }\n\n focus(): void {\n this.grid?.focus();\n }\n\n focusFilterBar(column: VisibleIndex): void {\n const { movedColumns } = this.state;\n const { model } = this.props;\n const { columnCount } = model;\n const modelColumn = GridUtils.getModelIndex(column, movedColumns);\n\n if (\n column == null ||\n column < 0 ||\n columnCount <= column ||\n !model.isFilterable(modelColumn)\n ) {\n this.setState({ focusedFilterBarColumn: null });\n return;\n }\n\n const { metricCalculator, metrics } = this.state;\n assertNotNull(metrics);\n const { left, rightVisible, lastLeft } = metrics;\n if (column < left) {\n this.grid?.setViewState({ left: column }, true);\n } else if (rightVisible < column) {\n const metricState = this.grid?.getMetricState();\n assertNotNull(metricState);\n const newLeft = metricCalculator.getLastLeft(\n metricState,\n column,\n metricCalculator.getVisibleWidth(metricState)\n );\n this.grid?.setViewState(\n { left: Math.min(newLeft, lastLeft), leftOffset: 0 },\n true\n );\n }\n this.lastFocusedFilterBarColumn = column;\n this.setState({ focusedFilterBarColumn: column, isFilterBarShown: true });\n }\n\n hideColumnByVisibleIndex(columnVisibleIndex: VisibleIndex): void {\n const { metricCalculator, movedColumns } = this.state;\n metricCalculator.setColumnWidth(\n GridUtils.getModelIndex(columnVisibleIndex, movedColumns),\n 0\n );\n\n this.grid?.forceUpdate();\n }\n\n freezeColumnByColumnName(columnName: ColumnName): void {\n const { frozenColumns, movedColumns } = this.state;\n const { model } = this.props;\n log.debug2('freezing column', columnName);\n\n const allFrozenColumns =\n frozenColumns == null\n ? new Set(model.frozenColumns)\n : new Set(frozenColumns);\n\n allFrozenColumns.add(columnName);\n\n const modelIndex = model.getColumnIndexByName(columnName);\n assertNotNull(modelIndex);\n const visibleIndex = GridUtils.getVisibleIndex(modelIndex, movedColumns);\n const newMovedColumns = GridUtils.moveItem(\n visibleIndex,\n allFrozenColumns.size - 1,\n movedColumns\n );\n\n this.setState({\n frozenColumns: [...allFrozenColumns],\n movedColumns: newMovedColumns,\n });\n }\n\n unFreezeColumnByColumnName(columnName: ColumnName): void {\n const { frozenColumns, movedColumns } = this.state;\n const { model } = this.props;\n log.debug2('unfreezing column', columnName);\n\n const allFrozenColumns =\n frozenColumns == null\n ? new Set(model.frozenColumns)\n : new Set(frozenColumns);\n\n allFrozenColumns.delete(columnName);\n\n const modelIndex = model.getColumnIndexByName(columnName);\n assertNotNull(modelIndex);\n const visibleIndex = GridUtils.getVisibleIndex(modelIndex, movedColumns);\n\n // Move to after remaining frozen columns and front columns\n const newMovedColumns = GridUtils.moveItem(\n visibleIndex,\n allFrozenColumns.size + model.frontColumns.length,\n movedColumns\n );\n\n this.setState({\n frozenColumns: [...allFrozenColumns],\n movedColumns: newMovedColumns,\n });\n }\n\n handleColumnVisibilityChanged(\n modelIndexes: readonly ModelIndex[],\n isVisible: boolean\n ): void {\n const { metricCalculator, metrics } = this.state;\n assertNotNull(metrics);\n if (isVisible) {\n modelIndexes.forEach(modelIndex => {\n const defaultWidth = metricCalculator.initialColumnWidths.get(\n modelIndex\n );\n const calculatedWidth = getOrThrow(\n metrics.calculatedColumnWidths,\n modelIndex\n );\n\n if (defaultWidth !== calculatedWidth) {\n metricCalculator.setColumnWidth(modelIndex, calculatedWidth);\n } else {\n metricCalculator.resetColumnWidth(modelIndex);\n }\n });\n } else {\n modelIndexes.forEach(modelIndex => {\n metricCalculator.setColumnWidth(modelIndex, 0);\n });\n }\n this.grid?.forceUpdate();\n }\n\n handleColumnVisibilityReset(): void {\n const { metricCalculator, metrics } = this.state;\n const { model } = this.props;\n assertNotNull(metrics);\n for (let i = 0; i < metrics.columnCount; i += 1) {\n metricCalculator.resetColumnWidth(i);\n }\n this.handleMovedColumnsChanged(model.initialMovedColumns);\n this.handleHeaderGroupsChanged(model.initialColumnHeaderGroups);\n this.setState({\n frozenColumns: model.layoutHints?.frozenColumns ?? [],\n });\n }\n\n handleCrossColumnSearch(\n searchValue: string,\n selectedSearchColumns: readonly ColumnName[],\n invertSearchColumns: boolean\n ): void {\n const { model } = this.props;\n\n this.updateSearchFilter(\n searchValue,\n selectedSearchColumns,\n model.columns,\n invertSearchColumns\n );\n\n this.setState({\n searchValue,\n selectedSearchColumns,\n invertSearchColumns,\n });\n }\n\n updateSearchFilter = debounce(\n (\n searchValue: string,\n selectedSearchColumns: readonly ColumnName[],\n columns: readonly Column[],\n invertSearchColumns: boolean\n ): void => {\n const { model } = this.props;\n const searchFilter = CrossColumnSearch.createSearchFilter(\n model.dh,\n searchValue,\n selectedSearchColumns,\n columns,\n invertSearchColumns\n );\n this.setState({ searchFilter });\n },\n SET_FILTER_DEBOUNCE\n );\n\n handleAnimationLoop(): void {\n this.grid?.updateCanvas();\n\n if (this.isAnimating) {\n this.animationFrame = requestAnimationFrame(this.handleAnimationLoop);\n }\n }\n\n handleAnimationStart(): void {\n log.debug2('handleAnimationStart');\n\n this.isAnimating = true;\n\n this.animationFrame = requestAnimationFrame(this.handleAnimationLoop);\n }\n\n handleAnimationEnd(): void {\n log.debug2('handleAnimationEnd');\n\n this.isAnimating = false;\n }\n\n handlePartitionAppend(value: string): void {\n const { onPartitionAppend } = this.props;\n const { partitionColumn } = this.state;\n if (partitionColumn == null) {\n return;\n }\n onPartitionAppend(partitionColumn, value);\n }\n\n handlePartitionChange(partition: string): void {\n const { partitionColumn } = this.state;\n if (partitionColumn == null) {\n return;\n }\n this.updatePartition(partition, partitionColumn);\n }\n\n handlePartitionFetchAll(): void {\n this.setState({\n partitionFilters: [],\n isSelectingPartition: false,\n });\n }\n\n handlePartitionDone(): void {\n this.setState({ isSelectingPartition: false });\n }\n\n handleTableLoadError(error: unknown): void {\n if (PromiseUtils.isCanceled(error)) {\n return;\n }\n\n log.error(error);\n\n const { onError } = this.props;\n onError(error);\n }\n\n showAllColumns(): void {\n const { metricCalculator } = this.state;\n const userColumnWidths = metricCalculator.getUserColumnWidths();\n const entries = [...userColumnWidths.entries()];\n for (let i = 0; i < entries.length; i += 1) {\n const [modelIndex, columnWidth] = entries[i];\n if (columnWidth === 0) {\n metricCalculator.resetColumnWidth(modelIndex);\n }\n }\n this.grid?.forceUpdate();\n }\n\n toggleSort(columnIndex: VisibleIndex, addToExisting: boolean): void {\n log.info('Toggling sort for column', columnIndex);\n\n const { model } = this.props;\n const { sorts: currentSorts } = this.state;\n const modelColumn = this.getModelColumn(columnIndex);\n assertNotNull(modelColumn);\n const sorts = TableUtils.toggleSortForColumn(\n currentSorts,\n model.columns,\n modelColumn,\n addToExisting\n );\n this.updateSorts(sorts);\n }\n\n updateSorts(sorts: readonly Sort[]): void {\n this.startLoading('Sorting...');\n this.setState({ sorts });\n this.grid?.forceUpdate();\n }\n\n sortColumn(\n modelColumn: ModelIndex,\n direction: SortDirection = TableUtils.sortDirection.none,\n isAbs = false,\n addToExisting = false\n ): void {\n assertNotNull(modelColumn);\n const { model } = this.props;\n const sorts = TableUtils.sortColumn(\n model.sort,\n model.columns,\n modelColumn,\n direction,\n isAbs,\n addToExisting\n );\n this.startLoading('Sorting...');\n this.setState({ sorts });\n this.grid?.forceUpdate();\n }\n\n reverse(reverseType: ReverseType): void {\n this.startLoading('Reversing...');\n this.setState({ reverseType });\n this.grid?.forceUpdate();\n }\n\n isReversible(): boolean {\n const { model } = this.props;\n return model.isReversible;\n }\n\n toggleFilterBar(focusIndex = this.lastFocusedFilterBarColumn): void {\n let { isFilterBarShown } = this.state;\n isFilterBarShown = !isFilterBarShown;\n this.setState({ isFilterBarShown });\n\n if (isFilterBarShown) {\n if (focusIndex != null) {\n this.focusFilterBar(focusIndex);\n } else {\n let columnIndex = 0;\n const { model } = this.props;\n const { columnCount } = model;\n for (let i = 0; i < columnCount; i += 1) {\n const modelColumn = this.getModelColumn(i);\n if (modelColumn != null) {\n const column = model.columns[modelColumn];\n if (column != null && TableUtils.isTextType(column.type)) {\n columnIndex = i;\n break;\n }\n }\n }\n this.focusFilterBar(columnIndex);\n }\n } else {\n this.grid?.focus();\n }\n }\n\n isTableSearchAvailable(): boolean {\n const { model, canToggleSearch } = this.props;\n const { dh } = model;\n const searchDisplayMode = model?.layoutHints?.searchDisplayMode;\n\n if (searchDisplayMode === dh.SearchDisplayMode?.SEARCH_DISPLAY_HIDE) {\n return false;\n }\n if (searchDisplayMode === dh.SearchDisplayMode?.SEARCH_DISPLAY_SHOW) {\n return true;\n }\n\n return canToggleSearch;\n }\n\n toggleSearchBar(): void {\n const { showSearchBar } = this.state;\n if (!this.isTableSearchAvailable()) {\n return;\n }\n\n const update = !showSearchBar;\n this.setState(\n {\n showSearchBar: update,\n },\n () => {\n if (update && this.crossColumnRef?.current) {\n this.crossColumnRef?.current.focus();\n } else {\n this.grid?.focus();\n }\n }\n );\n }\n\n toggleGotoRow(row = '', value = '', columnName = ''): void {\n const { isGotoShown } = this.state;\n if (row || value) {\n // if invoked with a row, keep open instead of toggle\n this.setState({\n isGotoShown: true,\n gotoRow: row,\n gotoValue: value,\n gotoValueSelectedColumnName: columnName,\n gotoRowError: '',\n gotoValueError: '',\n });\n this.focusRowInGrid(row);\n return;\n }\n\n const cursorRow = this.grid?.state.cursorRow;\n const cursorColumn = this.grid?.state.cursorColumn;\n\n if (cursorRow == null || cursorColumn == null) {\n // if a cell is not selected / grid is not rendered\n this.setState({\n isGotoShown: !isGotoShown,\n gotoRow: '',\n gotoValue: '',\n gotoRowError: '',\n gotoValueError: '',\n });\n return;\n }\n // if a row is selected\n const { model } = this.props;\n const { name, type } = model.columns[cursorColumn];\n\n const cellValue = model.valueForCell(cursorColumn, cursorRow);\n const text = IrisGridUtils.convertValueToText(cellValue, type);\n this.setState({\n isGotoShown: !isGotoShown,\n gotoRow: `${cursorRow}`,\n gotoValue: text,\n gotoValueSelectedColumnName: name,\n gotoRowError: '',\n gotoValueError: '',\n });\n }\n\n async commitPending(): Promise<void> {\n const { model } = this.props;\n if (!isEditableGridModel(model) || !model.isEditable) {\n throw new Error('Cannot save, table is not editable');\n }\n\n const { pendingSavePromise } = this.state;\n if (pendingSavePromise != null) {\n throw new Error('Save already in progress');\n }\n\n const containsGridCellInputField = document?.activeElement?.classList.contains(\n 'grid-cell-input-field'\n );\n if (containsGridCellInputField != null && containsGridCellInputField) {\n if (\n document.activeElement != null &&\n document.activeElement.classList.contains('error')\n ) {\n throw new ValidationError('Current input is invalid');\n }\n\n // Focus the grid again to commit any pending input changes\n this.grid?.focus();\n }\n\n const newPendingSavePromise = this.pending\n .add(model.commitPending())\n .then(() => {\n this.setState({ pendingSaveError: null, pendingSavePromise: null });\n })\n .catch(err => {\n if (!PromiseUtils.isCanceled(err)) {\n this.setState({ pendingSaveError: err, pendingSavePromise: null });\n }\n });\n this.setState({ pendingSavePromise: newPendingSavePromise });\n return newPendingSavePromise;\n }\n\n async discardPending(): Promise<void> {\n const { pendingSavePromise } = this.state;\n if (pendingSavePromise != null) {\n throw new Error('Cannot cancel a save in progress');\n }\n\n this.setState({\n pendingSavePromise: null,\n pendingSaveError: null,\n pendingDataMap: new Map(),\n pendingDataErrors: new Map(),\n });\n }\n\n /**\n * Select the passed in column and notify listener\n * @param column The column in this table to link\n */\n selectColumn(column: Column): void {\n const { onColumnSelected } = this.props;\n onColumnSelected(column);\n }\n\n /**\n * Select all the data for a given row and notify listener\n */\n selectData(columnIndex: ModelIndex, rowIndex: ModelIndex): void {\n const { model } = this.props;\n const { columns, groupedColumns } = model;\n const dataMap: RowDataMap = {};\n for (let i = 0; i < columns.length; i += 1) {\n const column = columns[i];\n const { name, type } = column;\n const value = model.valueForCell(i, rowIndex);\n const text = model.textForCell(i, rowIndex);\n const visibleIndex = this.getVisibleColumn(i);\n const isExpandable =\n isExpandableGridModel(model) && model.isRowExpandable(rowIndex);\n const isGrouped = groupedColumns.find(c => c.name === name) != null;\n dataMap[name] = {\n value,\n text,\n type,\n isGrouped,\n isExpandable,\n visibleIndex,\n };\n }\n const { onDataSelected } = this.props;\n onDataSelected(rowIndex, dataMap);\n }\n\n handleAdvancedFilterChange(\n column: Column,\n filter: FilterCondition | null,\n options: AdvancedFilterOptions\n ): void {\n const { model } = this.props;\n const index = model.getColumnIndexByName(column.name);\n assertNotNull(index);\n this.setAdvancedFilter(index, filter, options);\n }\n\n handleAdvancedFilterSortChange(\n column: Column,\n direction: SortDirection,\n addToExisting = false\n ): void {\n const { model } = this.props;\n const columnIndex = model.getColumnIndexByName(column.name);\n assertNotNull(columnIndex);\n const columnName = model.columns[columnIndex].name;\n const oldSort = TableUtils.getSortForColumn(model.sort, columnName);\n let newSort = null;\n\n if (oldSort == null || oldSort.direction !== direction) {\n if (direction === TableUtils.sortDirection.descending) {\n newSort = column.sort().desc();\n } else {\n newSort = column.sort().asc();\n }\n }\n\n const sorts = TableUtils.setSortForColumn(\n model.sort,\n columnName,\n newSort,\n addToExisting\n );\n log.info('Setting table sorts', sorts);\n\n this.startLoading('Sorting...');\n this.setState({ sorts });\n\n this.grid?.forceUpdate();\n }\n\n handleAdvancedFilterDone(): void {\n this.grid?.focus();\n }\n\n handleAdvancedMenuOpened(column: GridRangeIndex): void {\n this.setState({ shownAdvancedFilter: column });\n }\n\n handleGotoRowOpened(): void {\n this.setState({ isGotoShown: true });\n }\n\n handleGotoRowClosed(): void {\n this.setState({ isGotoShown: false });\n }\n\n handleAdvancedMenuClosed(columnIndex: number): void {\n const { focusedFilterBarColumn, isFilterBarShown } = this.state;\n if (\n isFilterBarShown &&\n focusedFilterBarColumn === columnIndex &&\n this.filterInputRef?.current !== null\n ) {\n this.filterInputRef?.current.focus();\n this.setState({ shownAdvancedFilter: null });\n } else {\n this.setState({\n focusedFilterBarColumn: null,\n shownAdvancedFilter: null,\n });\n }\n }\n\n handleCancel(): void {\n this.rollback();\n }\n\n // eslint-disable-next-line class-methods-use-this\n handleChartChange(): void {\n // TODO: IDS-4242 Update Chart Preview\n }\n\n handleChartCreate(settings: ChartBuilderSettings): void {\n const { model, onCreateChart } = this.props;\n onCreateChart(settings, model);\n }\n\n handleGridError(error?: Error): void {\n log.warn('Grid Error', error);\n this.setState({\n toastMessage: <div className=\"error-message\">{`${error}`}</div>,\n });\n }\n\n handleFilterBarChange(value: string): void {\n this.startLoading('Filtering...', true);\n\n this.setState(({ focusedFilterBarColumn, quickFilters }) => {\n const newQuickFilters = new Map(quickFilters);\n if (focusedFilterBarColumn != null) {\n const modelIndex = this.getModelColumn(focusedFilterBarColumn);\n assertNotNull(modelIndex);\n this.applyQuickFilter(modelIndex, value, newQuickFilters);\n }\n return { quickFilters: newQuickFilters };\n });\n }\n\n handleFilterBarDone(setGridFocus = true, defocusInput = true): void {\n if (setGridFocus) {\n this.grid?.focus();\n }\n if (defocusInput) {\n this.setState({ focusedFilterBarColumn: null });\n }\n }\n\n handleFilterBarTab(backward: boolean): void {\n const { focusedFilterBarColumn } = this.state;\n assertNotNull(focusedFilterBarColumn);\n if (backward) {\n this.focusFilterBar(focusedFilterBarColumn - 1);\n } else {\n this.focusFilterBar(focusedFilterBarColumn + 1);\n }\n }\n\n handleFormatSelection(\n modelIndex: ModelIndex,\n selectedFormat: TableColumnFormat | null\n ): void {\n const { model } = this.props;\n const column = model.columns[modelIndex];\n const { customColumnFormatMap: prevCustomColumnFormatMap } = this.state;\n const customColumnFormatMap = new Map(prevCustomColumnFormatMap);\n\n if (selectedFormat != null) {\n const normalizedType = TableUtils.getNormalizedType(column.type);\n assertNotNull(normalizedType);\n const columnFormattingRule = Formatter.makeColumnFormattingRule(\n normalizedType,\n column.name,\n selectedFormat\n );\n\n customColumnFormatMap.set(column.name, columnFormattingRule);\n } else {\n customColumnFormatMap.delete(column.name);\n }\n\n this.updateFormatter({ customColumnFormatMap });\n }\n\n handleMenu(e: React.MouseEvent<HTMLButtonElement>): void {\n e.stopPropagation();\n this.setState({ isMenuShown: true });\n }\n\n handleMenuClose(): void {\n this.setState({ isMenuShown: false, openOptions: [] });\n }\n\n handleMenuBack(): void {\n this.setState(({ openOptions }) => {\n const newOptions = [...openOptions];\n newOptions.pop();\n return { openOptions: newOptions };\n });\n }\n\n handleMenuSelect(option: OptionItem): void {\n this.setState(({ openOptions }) => ({\n openOptions: [...openOptions, option],\n }));\n }\n\n handleRequestFailed(event: Event): void {\n const customEvent = event as CustomEvent;\n log.error('request failed:', customEvent.detail);\n this.stopLoading();\n if (this.canRollback()) {\n this.startLoading('Rolling back changes...', true);\n this.rollback();\n } else {\n log.error('Table failed and unable to rollback');\n const { onError } = this.props;\n onError(new Error(`Error displaying table: ${customEvent.detail}`));\n }\n }\n\n handleUpdate(): void {\n this.stopLoading();\n log.debug2('Received model update');\n\n const {\n advancedFilters,\n aggregationSettings,\n customColumns,\n quickFilters,\n reverseType,\n rollupConfig,\n searchFilter,\n selectDistinctColumns,\n sorts,\n } = this.state;\n\n const config = {\n advancedFilters,\n aggregationSettings,\n customColumns,\n quickFilters,\n reverseType,\n rollupConfig,\n searchFilter,\n selectDistinctColumns,\n sorts,\n };\n\n if (!isEmptyConfig(config)) {\n this.lastLoadedConfig = config;\n } else {\n this.lastLoadedConfig = null;\n }\n\n this.grid?.forceUpdate();\n }\n\n handleViewChanged(metrics?: GridMetrics): void {\n const { model } = this.props;\n const { selectionEndRow = 0 } = this.grid?.state ?? {};\n let pendingRowCount = 0;\n if (isEditableGridModel(model) && model.isEditable) {\n assertNotNull(metrics);\n const { bottomViewport } = metrics;\n\n // We have an editable table that we can add new rows to\n // Display empty rows beneath the table rows that user can fill in\n const bottomNonFloating = model.rowCount - model.floatingBottomRowCount;\n if (selectionEndRow === bottomNonFloating - 1) {\n // Selection is in the last row, add another blank row\n pendingRowCount = model.pendingRowCount + 1;\n } else if (selectionEndRow === bottomNonFloating - 2) {\n // We may have just added a row based on selection moving, so just leave it as is\n pendingRowCount = model.pendingRowCount;\n } else {\n // Otherwise fill up the viewport with empty cells\n pendingRowCount = Math.max(\n 0,\n bottomViewport -\n (model.rowCount - model.pendingRowCount) -\n model.floatingTopRowCount -\n model.floatingBottomRowCount -\n 1\n );\n }\n }\n\n this.setState({ metrics, pendingRowCount });\n }\n\n handleSelectionChanged(selectedRanges?: readonly GridRange[]): void {\n assertNotNull(selectedRanges);\n const { onSelectionChanged } = this.props;\n const { copyOperation } = this.state;\n this.setState({ selectedRanges });\n if (copyOperation != null) {\n this.setState({ copyOperation: null });\n }\n onSelectionChanged(selectedRanges);\n }\n\n handleMovedColumnsChanged(\n movedColumns: readonly MoveOperation[],\n onChangeApplied?: () => void\n ): void {\n this.setState({ movedColumns }, onChangeApplied);\n }\n\n handleHeaderGroupsChanged(columnHeaderGroups: readonly ColumnGroup[]): void {\n const { model } = this.props;\n this.setState(\n {\n columnHeaderGroups: IrisGridUtils.parseColumnHeaderGroups(\n model,\n columnHeaderGroups\n ).groups,\n },\n () => this.grid?.forceUpdate()\n );\n }\n\n handleTooltipRef(tooltip: Tooltip): void {\n // Need to start the timer right away, since we're creating the tooltip when we want the timer to start\n if (tooltip != null) {\n tooltip.startTimer();\n }\n\n this.tooltip = tooltip;\n }\n\n handleConditionalFormatsChange(\n conditionalFormats: readonly SidebarFormattingRule[]\n ): void {\n log.debug('Updated conditional formats', conditionalFormats);\n this.setState({ conditionalFormats });\n }\n\n handleConditionalFormatCreate(): void {\n log.debug('Create new conditional format');\n const { openOptions, conditionalFormats } = this.state;\n this.setState({\n openOptions: [\n ...openOptions,\n {\n type: OptionType.CONDITIONAL_FORMATTING_EDIT,\n title: `Create Formatting Rule`,\n },\n ],\n conditionalFormatEditIndex: conditionalFormats.length,\n // Start with a blank rule\n conditionalFormatPreview: undefined,\n });\n }\n\n handleConditionalFormatEdit(index: number): void {\n log.debug('Edit conditional format', index);\n const { openOptions, conditionalFormats } = this.state;\n this.setState({\n openOptions: [\n ...openOptions,\n {\n type: OptionType.CONDITIONAL_FORMATTING_EDIT,\n title: `Edit Formatting Rule`,\n },\n ],\n conditionalFormatEditIndex: index,\n // Clone rule to preview temporary changes\n conditionalFormatPreview: { ...conditionalFormats[index] },\n });\n }\n\n // Apply live changes\n handleConditionalFormatEditorUpdate = debounce(\n (conditionalFormatPreview?: SidebarFormattingRule): void => {\n this.setState({ conditionalFormatPreview });\n },\n SET_CONDITIONAL_FORMAT_DEBOUNCE\n );\n\n handleConditionalFormatEditorSave(config: SidebarFormattingRule): void {\n log.debug('Save conditional format changes', config);\n this.setState(\n state => {\n if (state.conditionalFormatEditIndex === null) {\n log.debug('Invalid format index');\n return null;\n }\n const conditionalFormats = [...state.conditionalFormats];\n conditionalFormats[state.conditionalFormatEditIndex] = config;\n return { conditionalFormats };\n },\n () => {\n this.handleMenuBack();\n }\n );\n }\n\n handleConditionalFormatEditorCancel(): void {\n this.handleMenuBack();\n // Not resetting conditionalFormatPreview here\n // to prevent editor fields change during the menu transition\n this.setState({ conditionalFormatEditIndex: null });\n }\n\n handleUpdateCustomColumns(customColumns: readonly string[]): void {\n log.info(`handleUpdateCustomColumns:`, customColumns);\n\n const { model } = this.props;\n const {\n movedColumns,\n sorts,\n quickFilters,\n advancedFilters,\n selectDistinctColumns,\n } = this.state;\n\n const { columns } = model;\n const oldCustomColumns = model.customColumns.map(\n customColumn => `${customColumn}`\n );\n\n const removedColumnNames = IrisGridUtils.getRemovedCustomColumnNames(\n oldCustomColumns,\n customColumns\n );\n if (removedColumnNames.length > 0) {\n const newSorts = IrisGridUtils.removeSortsInColumns(\n sorts,\n removedColumnNames\n );\n const newQuickFilters = IrisGridUtils.removeFiltersInColumns(\n columns,\n quickFilters,\n removedColumnNames\n );\n const newAdvancedFilters = IrisGridUtils.removeFiltersInColumns(\n columns,\n advancedFilters,\n removedColumnNames\n );\n const newMovedColumns = IrisGridUtils.removeColumnFromMovedColumns(\n columns,\n movedColumns,\n removedColumnNames\n );\n const newSelectDistinctColumns = IrisGridUtils.removeColumnsFromSelectDistinctColumns(\n selectDistinctColumns,\n removedColumnNames\n );\n if (newSorts.length !== sorts.length) {\n log.debug('removing sorts from removed custom columns...');\n this.setState({ sorts: newSorts });\n }\n if (\n newQuickFilters.size !== quickFilters.size ||\n newAdvancedFilters.size !== advancedFilters.size\n ) {\n log.debug(`removing filters from removed custom columns...`);\n this.setState({\n quickFilters: newQuickFilters,\n advancedFilters: newAdvancedFilters,\n });\n }\n if (!deepEqual(movedColumns, newMovedColumns)) {\n log.debug(\n `change moved columns for removed custom columns`,\n newMovedColumns\n );\n this.setState({ movedColumns: newMovedColumns });\n }\n if (!deepEqual(selectDistinctColumns, newSelectDistinctColumns)) {\n log.debug(\n `change selectDistinct columns for removed custom columns`,\n newMovedColumns\n );\n this.setState({ selectDistinctColumns: newSelectDistinctColumns });\n }\n }\n\n this.setState({ customColumns });\n if (customColumns.length > 0) {\n // If there are no custom columns, the change handler never fires\n // This causes the loader to stay until canceled by the user\n this.startLoading('Applying custom columns...');\n }\n }\n\n handleCustomColumnsChanged(): void {\n log.debug('custom columns changed');\n const { isReady } = this.state;\n if (isReady) {\n this.stopLoading();\n this.grid?.forceUpdate();\n } else {\n this.initState();\n }\n }\n\n handlePendingCommitClicked(): Promise<void> {\n return this.commitPending();\n }\n\n handlePendingDiscardClicked(): Promise<void> {\n return this.discardPending();\n }\n\n handlePendingDataUpdated(): void {\n log.debug('pending data updated');\n const { model } = this.props;\n const { pendingDataMap, pendingDataErrors } = model;\n this.setState({\n pendingDataMap,\n pendingDataErrors,\n pendingSaveError: null,\n });\n this.grid?.forceUpdate();\n }\n\n /**\n * User added, removed, or changed the order of aggregations, or position\n * @param aggregationSettings The new aggregation settings\n */\n handleAggregationsChange(aggregationSettings: AggregationSettings): void {\n log.debug('handleAggregationsChange', aggregationSettings);\n\n this.startLoading(\n `Aggregating ${aggregationSettings.aggregations\n .map(a => a.operation)\n .join(', ')}...`\n );\n this.setState({ aggregationSettings });\n }\n\n /**\n * A specific aggregation has been modified\n * @param aggregation The new aggregation\n */\n handleAggregationChange(aggregation: Aggregation): void {\n log.debug('handleAggregationChange', aggregation);\n\n this.startLoading(`Aggregating ${aggregation.operation}...`);\n this.setState(({ aggregationSettings }) => ({\n selectedAggregation: aggregation,\n aggregationSettings: {\n ...aggregationSettings,\n aggregations: aggregationSettings.aggregations.map(a =>\n a.operation === aggregation.operation ? aggregation : a\n ),\n },\n }));\n }\n\n /**\n * An aggregations has been selected for editing\n * @param aggregation The aggregation to edit\n */\n handleAggregationEdit(aggregation: Aggregation): void {\n log.debug('handleAggregationEdit', aggregation);\n\n const { openOptions } = this.state;\n\n this.setState({\n openOptions: [\n ...openOptions,\n {\n type: OptionType.AGGREGATION_EDIT,\n title: `Edit Columns to ${aggregation.operation}`,\n },\n ],\n selectedAggregation: aggregation,\n });\n }\n\n handleRollupChange(rollupConfig: UIRollupConfig): void {\n log.info('Rollup change', rollupConfig);\n\n this.resetGridViewState();\n this.showAllColumns();\n this.clearAllFilters();\n\n this.startLoading(\n `Grouping by columns ${rollupConfig?.columns?.join(', ') ?? ''}...`\n );\n\n // Have to clear select distinct since rollup uses the original columns, not the current ones.\n // IrisGridProxyModel has a check to prevent model update\n // when selectDistinctModel is cleared and the rollupConfig is set on the model.\n this.setState({\n rollupConfig,\n movedColumns: [],\n frozenColumns: [],\n sorts: [],\n reverseType: TableUtils.REVERSE_TYPE.NONE,\n selectDistinctColumns: [],\n });\n }\n\n handleSelectDistinctChanged(columnNames: readonly ColumnName[]): void {\n log.debug('SelectDistinct change', columnNames);\n\n this.resetGridViewState();\n\n this.showAllColumns();\n this.clearAllFilters();\n\n this.startLoading(\n `Selecting distinct values in ${\n columnNames.length > 0 ? columnNames.join(', ') : ''\n }...`\n );\n\n this.setState({\n selectDistinctColumns: columnNames,\n movedColumns: [],\n sorts: [],\n reverseType: TableUtils.REVERSE_TYPE.NONE,\n });\n }\n\n handleDownloadTableStart(): void {\n const { canDownloadCsv } = this.props;\n if (canDownloadCsv) {\n this.setState({\n isTableDownloading: true,\n tableDownloadProgress: 0,\n tableDownloadEstimatedTime: null,\n tableDownloadStatus: TableCsvExporter.DOWNLOAD_STATUS.INITIATING,\n });\n } else {\n log.error(\n 'Attempted to handleDownloadTableStart for user without download CSV permission.'\n );\n }\n }\n\n handleDownloadTable(\n fileName: string,\n frozenTable: Table,\n tableSubscription: TableViewportSubscription,\n snapshotRanges: readonly GridRange[],\n modelRanges: readonly GridRange[],\n includeColumnHeaders: boolean,\n useUnformattedValues: boolean\n ): void {\n const { canDownloadCsv } = this.props;\n if (canDownloadCsv) {\n log.info(\n 'start table downloading',\n fileName,\n frozenTable,\n tableSubscription,\n snapshotRanges,\n modelRanges,\n includeColumnHeaders,\n useUnformattedValues\n );\n this.setState(() => {\n if (this.tableSaver) {\n this.tableSaver.startDownload(\n fileName,\n frozenTable,\n tableSubscription,\n snapshotRanges,\n modelRanges,\n includeColumnHeaders,\n useUnformattedValues\n );\n }\n return {\n tableDownloadStatus: TableCsvExporter.DOWNLOAD_STATUS.DOWNLOADING,\n };\n });\n } else {\n log.error(\n 'Attempted to handleDownloadTable for user without download CSV permission.'\n );\n }\n }\n\n async seekRow(inputString: string, isBackwards = false): Promise<void> {\n const {\n gotoValueSelectedColumnName: selectedColumnName,\n gotoValueSelectedFilter,\n } = this.state;\n const { model } = this.props;\n const { dh } = model;\n if (!model.isSeekRowAvailable) {\n return;\n }\n\n if (inputString === '') {\n return;\n }\n const selectedColumn = IrisGridUtils.getColumnByName(\n model.columns,\n selectedColumnName\n );\n\n if (selectedColumn === undefined) {\n return;\n }\n\n let searchFromRow = this.grid?.state.cursorRow;\n\n if (searchFromRow == null) {\n searchFromRow = 0;\n }\n\n const isContains = gotoValueSelectedFilter === FilterType.contains;\n const isEquals =\n gotoValueSelectedFilter === FilterType.eq ||\n gotoValueSelectedFilter === FilterType.eqIgnoreCase;\n\n try {\n const { formatter } = model;\n const columnDataType = TableUtils.getNormalizedType(selectedColumn.type);\n\n let rowIndex;\n\n switch (columnDataType) {\n case TableUtils.dataType.CHAR:\n case TableUtils.dataType.STRING: {\n rowIndex = await model.seekRow(\n searchFromRow,\n selectedColumn,\n dh.ValueType.STRING,\n inputString,\n isEquals,\n isContains,\n isBackwards ?? false\n );\n break;\n }\n case TableUtils.dataType.DATETIME: {\n const [startDate] = DateUtils.parseDateRange(\n dh,\n inputString,\n formatter.timeZone\n );\n rowIndex = await model.seekRow(\n searchFromRow,\n selectedColumn,\n dh.ValueType.DATETIME,\n startDate,\n undefined,\n undefined,\n isBackwards ?? false\n );\n break;\n }\n case TableUtils.dataType.DECIMAL:\n case TableUtils.dataType.INT: {\n if (\n !TableUtils.isBigDecimalType(selectedColumn.type) &&\n !TableUtils.isBigIntegerType(selectedColumn.type)\n ) {\n let inputValue = parseInt(inputString, 10);\n if (inputString === '-Infinity') {\n inputValue = Number.NEGATIVE_INFINITY;\n } else if (inputString === 'Infinity') {\n inputValue = Number.POSITIVE_INFINITY;\n }\n\n rowIndex = await model.seekRow(\n searchFromRow,\n selectedColumn,\n dh.ValueType.NUMBER,\n inputValue,\n undefined,\n undefined,\n isBackwards ?? false\n );\n } else {\n rowIndex = await model.seekRow(\n searchFromRow,\n selectedColumn,\n dh.ValueType.STRING,\n inputString,\n undefined,\n undefined,\n isBackwards ?? false\n );\n }\n break;\n }\n default: {\n rowIndex = await model.seekRow(\n searchFromRow,\n selectedColumn,\n dh.ValueType.STRING,\n this.tableUtils.makeValue(\n selectedColumn.type,\n inputString,\n formatter.timeZone\n ),\n undefined,\n undefined,\n isBackwards ?? false\n );\n }\n }\n\n this.grid?.setFocusRow(rowIndex);\n this.setState({ gotoValueError: '' });\n } catch (e: unknown) {\n this.setState({ gotoValueError: 'invalid input' });\n }\n }\n\n handleCancelDownloadTable(): void {\n this.tableSaver?.cancelDownload();\n this.setState({ isTableDownloading: false });\n }\n\n handleDownloadProgressUpdate = throttle(\n (\n tableDownloadProgress: number,\n tableDownloadEstimatedTime: number | null\n ) => {\n const { tableDownloadStatus } = this.state;\n if (\n tableDownloadStatus === TableCsvExporter.DOWNLOAD_STATUS.DOWNLOADING\n ) {\n this.setState({\n tableDownloadProgress,\n tableDownloadEstimatedTime,\n });\n }\n },\n UPDATE_DOWNLOAD_THROTTLE\n );\n\n handleDownloadCompleted(): void {\n this.setState({\n isTableDownloading: false,\n tableDownloadProgress: 100,\n tableDownloadStatus: TableCsvExporter.DOWNLOAD_STATUS.FINISHED,\n });\n }\n\n handleDownloadCanceled(): void {\n this.setState({\n isTableDownloading: false,\n tableDownloadProgress: 0,\n tableDownloadStatus: TableCsvExporter.DOWNLOAD_STATUS.CANCELED,\n });\n }\n\n /**\n * Delete the specified ranges from the table.\n * @param ranges The ranges to delete\n */\n deleteRanges(ranges: readonly GridRange[]): void {\n const { model } = this.props;\n this.pending.add(model.delete(ranges)).catch(e => {\n if (!PromiseUtils.isCanceled(e)) {\n log.error('Unable to delete ranges', ranges, e);\n }\n });\n }\n\n resetColumnSelection(): void {\n if (this.grid == null) {\n return;\n }\n const { isSelectingColumn } = this.props;\n if (isSelectingColumn) {\n const { columnAllowedCursor } = this.props;\n this.grid.setState({ cursor: columnAllowedCursor });\n } else {\n this.grid.setState({ cursor: null });\n this.setState({ hoverSelectColumn: null });\n }\n }\n\n resetGridViewState(forceUpdate = true): void {\n if (!this.grid) {\n return;\n }\n\n this.grid.clearSelectedRanges();\n this.grid.setViewState(\n { left: 0, top: 0, topOffset: 0, leftOffset: 0 },\n forceUpdate\n );\n }\n\n sendStateChange(): void {\n if (!this.grid) {\n return;\n }\n const { state: irisGridState } = this;\n const { state: gridState } = this.grid;\n const { onStateChange } = this.props;\n\n onStateChange(irisGridState, gridState);\n }\n\n handleOverflowClose(): void {\n this.setState({\n showOverflowModal: false,\n });\n }\n\n getColumnBoundingRect(): DOMRect {\n const { metrics, shownColumnTooltip } = this.state;\n assertNotNull(metrics);\n assertNotNull(shownColumnTooltip);\n const gridRect = this.gridWrapper?.getBoundingClientRect();\n const popperMargin = 20;\n assertNotNull(gridRect);\n const {\n columnHeaderHeight,\n allColumnXs,\n allColumnWidths,\n width,\n columnHeaderMaxDepth,\n } = metrics;\n const columnX = allColumnXs.get(shownColumnTooltip);\n const columnWidth = allColumnWidths.get(shownColumnTooltip);\n\n assertNotNull(columnX);\n assertNotNull(columnWidth);\n\n const left =\n gridRect.left +\n clamp(columnX + columnWidth / 2, popperMargin, width - popperMargin);\n\n return {\n top: gridRect.top + (columnHeaderMaxDepth - 1) * columnHeaderHeight,\n left:\n gridRect.left +\n clamp(columnX + columnWidth / 2, popperMargin, width - popperMargin),\n bottom: gridRect.top + columnHeaderMaxDepth * columnHeaderHeight,\n right:\n gridRect.left +\n clamp(columnX + columnWidth / 2, popperMargin, width - popperMargin) +\n 1,\n width: 1,\n height: columnHeaderHeight,\n x: left,\n y: gridRect.top,\n toJSON: () => {\n throw new Error('not implemented');\n },\n };\n }\n\n getOverflowButtonTooltip = memoize(\n (overflowButtonTooltipProps: CSSProperties): ReactNode => {\n if (overflowButtonTooltipProps == null) {\n return null;\n }\n\n const wrapperStyle: CSSProperties = {\n position: 'absolute',\n ...overflowButtonTooltipProps,\n pointerEvents: 'none',\n };\n\n const popperOptions: PopperOptions = {\n placement: 'left',\n modifiers: {\n flip: {\n behavior: ['left', 'right'],\n },\n },\n };\n\n return (\n <div style={wrapperStyle}>\n <Tooltip\n key={Date.now()}\n options={popperOptions}\n ref={this.handleTooltipRef}\n >\n View full contents\n </Tooltip>\n </div>\n );\n }\n );\n\n getExpandCellTooltip = memoize(\n (expandCellTooltipProps: CSSProperties): ReactNode => {\n if (expandCellTooltipProps == null) {\n return null;\n }\n\n const { expandTooltipDisplayValue } = this.state;\n\n const wrapperStyle: CSSProperties = {\n position: 'absolute',\n ...expandCellTooltipProps,\n pointerEvents: 'none',\n };\n\n const popperOptions: PopperOptions = {\n placement: 'bottom-start',\n };\n\n return (\n <div style={wrapperStyle}>\n <Tooltip\n key={Date.now()}\n options={popperOptions}\n ref={this.handleTooltipRef}\n >\n <div style={{ textAlign: 'left' }}>\n Click to {expandTooltipDisplayValue} row\n <br />\n {ContextActionUtils.isMacPlatform() ? '⌘' : 'Ctrl+'}Click to\n expand row and all children\n </div>\n </Tooltip>\n </div>\n );\n }\n );\n\n getLinkHoverTooltip = memoize(\n (linkHoverTooltipProps: CSSProperties): ReactNode => {\n if (linkHoverTooltipProps == null) {\n return null;\n }\n\n const { linkHoverDisplayValue } = this.state;\n\n const wrapperStyle: CSSProperties = {\n position: 'absolute',\n ...linkHoverTooltipProps,\n pointerEvents: 'none',\n };\n\n const popperOptions: PopperOptions = {\n placement: 'bottom',\n };\n\n return (\n <div style={wrapperStyle}>\n <Tooltip options={popperOptions} ref={this.handleTooltipRef}>\n <div className=\"link-hover-tooltip\">\n {linkHoverDisplayValue} - Click once to follow.\n <br />\n Click and hold to select this cell.\n </div>\n </Tooltip>\n </div>\n );\n }\n );\n\n handleGotoRowSelectedRowNumberSubmit(): void {\n const { gotoRow: rowNumber } = this.state;\n this.focusRowInGrid(rowNumber);\n }\n\n focusRowInGrid(rowNumber: string): void {\n const { model } = this.props;\n const { rowCount } = model;\n this.setState({ gotoRow: rowNumber });\n if (rowNumber === '') {\n this.setState({ gotoRowError: '', gotoValueError: '' });\n return;\n }\n const rowInt = parseInt(rowNumber, 10);\n if (rowInt > rowCount || rowInt < -rowCount) {\n this.setState({ gotoRowError: 'Invalid row index' });\n } else if (rowInt === 0) {\n this.setState({ gotoRowError: '', gotoValueError: '' });\n this.grid?.setFocusRow(0);\n } else if (rowInt < 0) {\n this.setState({ gotoRowError: '', gotoValueError: '' });\n this.grid?.setFocusRow(rowInt + rowCount);\n } else {\n this.grid?.setFocusRow(rowInt - 1);\n this.setState({ gotoRowError: '', gotoValueError: '' });\n }\n }\n\n handleGotoRowSelectedRowNumberChanged(\n event: ChangeEvent<HTMLInputElement>\n ): void {\n const rowNumber = event.target.value;\n this.focusRowInGrid(rowNumber);\n }\n\n getColumnTooltip(\n visibleIndex: VisibleIndex,\n metrics: GridMetrics,\n model: IrisGridModel\n ): ReactNode {\n const {\n columnHeaderHeight,\n columnHeaderMaxDepth,\n allColumnXs,\n allColumnWidths,\n width,\n } = metrics;\n const columnX = allColumnXs.get(visibleIndex);\n const columnWidth = allColumnWidths.get(visibleIndex);\n\n if (columnX == null || columnWidth == null) {\n return null;\n }\n\n /**\n * Create a wrapper dom element, the size of the column header.\n * The wrapper acts as tooltip parent, the tooltip component\n * will trigger hide on mouseleave of wrapper or tooltip.\n * The wrapper should be bound to within the grid dimensions,\n * so popper only remains triggered while mouse is inside the panel.\n */\n const boundedLeft = Math.max(0, columnX);\n let boundedWidth = columnWidth;\n if (columnX + columnWidth > width) {\n // column is extending past right edge\n boundedWidth = width - columnX;\n } else if (columnX < 0) {\n // column is extending past left edge\n boundedWidth = columnWidth - Math.abs(columnX);\n }\n\n const wrapperStyle: CSSProperties = {\n position: 'absolute',\n top: (columnHeaderMaxDepth - 1) * columnHeaderHeight,\n left: boundedLeft,\n width: boundedWidth,\n height: columnHeaderHeight,\n pointerEvents: 'none',\n };\n\n /**\n * Because the popper parent wrapper center is no longer the same as\n * the column label center, we create a popper virtual ref, to handle\n * positioning and keep the popper centered on the label. Creates a\n * 1px x headerHeight virtual object, placed centered on the column\n * label, clamped to 0 + margin to width - margin. We add a margin,\n * otherwise the arrow wants to escape the boundary.\n */\n const virtualReference: ReferenceObject = {\n clientWidth: 1,\n clientHeight: columnHeaderHeight,\n getBoundingClientRect: this.getColumnBoundingRect,\n };\n\n const popperOptions: PopperOptions = {\n placement: 'bottom',\n modifiers: {\n flip: {\n behavior: ['bottom', 'top'],\n },\n },\n };\n\n const modelColumn = this.getModelColumn(visibleIndex);\n if (modelColumn == null) return null;\n\n const column = model.columns[modelColumn];\n if (column == null) return null;\n\n return (\n <div style={wrapperStyle}>\n <Tooltip\n key={column.name}\n timeout={400}\n interactive\n options={popperOptions}\n ref={this.handleTooltipRef}\n referenceObject={virtualReference}\n onExited={() => {\n this.setState({ shownColumnTooltip: null });\n }}\n >\n <ColumnStatistics\n model={model}\n column={column}\n onStatistics={() => {\n this.tooltip?.update();\n }}\n />\n </Tooltip>\n </div>\n );\n }\n\n handleGotoValueSelectedColumnNameChanged(columnName: ColumnName): void {\n const { model } = this.props;\n const cursorRow = this.grid?.state.cursorRow;\n\n if (cursorRow != null) {\n const index = model.getColumnIndexByName(columnName);\n const column = IrisGridUtils.getColumnByName(model.columns, columnName);\n if (index == null || column == null) {\n return;\n }\n const value = model.valueForCell(index, cursorRow);\n const text = IrisGridUtils.convertValueToText(value, column.type);\n this.setState({\n gotoValueSelectedColumnName: columnName,\n gotoValue: text,\n gotoValueError: '',\n });\n }\n this.setState({\n gotoValueSelectedColumnName: columnName,\n gotoValueError: '',\n });\n }\n\n handleGotoValueSelectedFilterChanged(value: FilterTypeValue): void {\n this.setState({ gotoValueSelectedFilter: value, gotoValueError: '' });\n }\n\n handleGotoValueChanged = (input: string): void => {\n this.setState({ gotoValue: input });\n this.debouncedSeekRow(input);\n };\n\n debouncedSeekRow = debounce((input: string): void => {\n this.seekRow(input);\n }, SEEK_ROW_DEBOUNCE);\n\n handleGotoValueSubmitted(isBackwards?: boolean): void {\n const { gotoValue } = this.state;\n this.seekRow(gotoValue, isBackwards);\n }\n\n render(): ReactElement | null {\n const {\n children,\n customFilters,\n getDownloadWorker,\n isSelectingColumn,\n isStuckToBottom,\n isStuckToRight,\n model,\n name,\n onlyFetchVisibleColumns,\n alwaysFetchColumns,\n advancedSettings,\n onAdvancedSettingsChange,\n canDownloadCsv,\n onCreateChart,\n } = this.props;\n const {\n metricCalculator,\n metrics,\n isFilterBarShown,\n isSelectingPartition,\n isMenuShown,\n isReady,\n copyOperation,\n focusedFilterBarColumn,\n loadingText,\n loadingScrimProgress,\n loadingSpinnerShown,\n keyHandlers,\n mouseHandlers,\n shownColumnTooltip,\n hoverAdvancedFilter,\n shownAdvancedFilter,\n hoverSelectColumn,\n quickFilters,\n advancedFilters,\n partition,\n partitionFilters,\n partitionTable,\n partitionColumn,\n searchFilter,\n selectDistinctColumns,\n\n movedColumns,\n movedRows,\n\n formatter,\n conditionalFormats,\n conditionalFormatPreview,\n conditionalFormatEditIndex,\n\n sorts,\n reverseType,\n customColumns,\n\n selectedRanges,\n isTableDownloading,\n tableDownloadStatus,\n tableDownloadProgress,\n tableDownloadEstimatedTime,\n\n showSearchBar,\n searchValue,\n selectedSearchColumns,\n invertSearchColumns,\n\n aggregationSettings,\n selectedAggregation,\n rollupConfig,\n openOptions,\n pendingSavePromise,\n pendingSaveError,\n pendingRowCount,\n pendingDataErrors,\n pendingDataMap,\n toastMessage,\n frozenColumns,\n columnHeaderGroups,\n showOverflowModal,\n overflowText,\n overflowButtonTooltipProps,\n expandCellTooltipProps,\n linkHoverTooltipProps,\n isGotoShown,\n gotoRow,\n gotoRowError,\n gotoValueError,\n gotoValueSelectedColumnName,\n gotoValue,\n gotoValueSelectedFilter,\n } = this.state;\n if (!isReady) {\n return null;\n }\n\n const theme = this.getTheme();\n\n const filter = this.getCachedFilter(\n customFilters,\n quickFilters,\n advancedFilters,\n partitionFilters,\n searchFilter\n );\n\n const userColumnWidths = metricCalculator.getUserColumnWidths();\n const stateOverride = this.getCachedStateOverride(\n hoverSelectColumn,\n isFilterBarShown,\n isSelectingColumn,\n loadingScrimProgress,\n quickFilters,\n advancedFilters,\n sorts,\n reverseType,\n rollupConfig,\n isMenuShown\n );\n const top = metrics ? metrics.top : 0;\n const bottom = metrics ? metrics.bottomViewport : 0;\n let left = null;\n let right = null;\n if (onlyFetchVisibleColumns) {\n left = metrics ? metrics.left : 0;\n right = metrics ? metrics.right : 0;\n }\n const isVisible =\n metrics != null && metrics.width > 0 && metrics.height > 0;\n const isRollup = (rollupConfig?.columns?.length ?? 0) > 0;\n\n let focusField = null;\n\n const debounceMs = metrics\n ? Math.min(\n Math.max(IrisGrid.minDebounce, Math.round(metrics.rowCount / 200)),\n IrisGrid.maxDebounce\n )\n : IrisGrid.maxDebounce;\n\n if (isFilterBarShown && focusedFilterBarColumn != null && metrics != null) {\n const { gridX, gridY, allColumnXs, allColumnWidths, width } = metrics;\n const columnX = allColumnXs.get(focusedFilterBarColumn);\n const columnWidth = allColumnWidths.get(focusedFilterBarColumn);\n if (columnX != null && columnWidth != null) {\n const x = gridX + columnX;\n const y = gridY - (theme.filterBarHeight ?? 0);\n const fieldWidth = columnWidth + 1; // cover right border\n const fieldHeight = (theme.filterBarHeight ?? 0) - 1; // remove bottom border\n const style = {\n top: y,\n left: x,\n minWidth: Math.min(fieldWidth, width - x), // Don't cause overflow\n height: fieldHeight,\n };\n let value = '';\n let isValid = true;\n const modelColumn = this.getModelColumn(focusedFilterBarColumn);\n assertNotNull(modelColumn);\n const quickFilter = quickFilters.get(modelColumn);\n const advancedFilter = advancedFilters.get(modelColumn);\n if (quickFilter != null) {\n value = quickFilter.text;\n isValid = quickFilter.filter != null;\n }\n const isBarFiltered =\n quickFilters.size !== 0 || advancedFilters.size !== 0;\n focusField = (\n <FilterInputField\n ref={this.filterInputRef}\n style={style}\n className={classNames({\n error: !isValid,\n active: value !== '' || advancedFilter != null,\n 'iris-grid-has-filter': isBarFiltered,\n })}\n isAdvancedFilterSet={advancedFilter != null}\n onAdvancedFiltersTriggered={() => {\n this.setState({ shownAdvancedFilter: focusedFilterBarColumn });\n }}\n key={focusedFilterBarColumn}\n onChange={this.handleFilterBarChange}\n onDone={this.handleFilterBarDone}\n onTab={this.handleFilterBarTab}\n onContextMenu={this.grid?.handleContextMenu}\n debounceMs={debounceMs}\n value={value}\n />\n );\n }\n }\n\n let loadingElement = null;\n if (loadingText != null) {\n const loadingStatus = (\n <div className=\"iris-grid-loading-status\">\n <div\n className={classNames('iris-grid-loading-status-bar', {\n show: loadingSpinnerShown,\n })}\n >\n {loadingText}\n </div>\n <button\n type=\"button\"\n onClick={this.handleCancel}\n className={classNames('iris-grid-btn-cancel', {\n show: loadingSpinnerShown,\n })}\n >\n <FontAwesomeIcon icon={vsClose} transform=\"down-1\" />\n Cancel\n </button>\n </div>\n );\n const gridY = metrics ? metrics.gridY : 0;\n loadingElement = (\n <div className=\"iris-grid-loading\" style={{ top: gridY }}>\n {loadingStatus}\n </div>\n );\n }\n\n let columnTooltip: React.ReactNode = null;\n if (shownColumnTooltip != null && metrics) {\n columnTooltip = this.getColumnTooltip(shownColumnTooltip, metrics, model);\n // #510 We may need to update the position of the tooltip if it's already opened and columns are resized\n this.tooltip?.update();\n }\n\n const filterBar = [];\n if (metrics && isFilterBarShown) {\n const {\n gridX,\n gridY,\n visibleColumns,\n allColumnXs,\n allColumnWidths,\n } = metrics;\n const { filterBarHeight } = theme;\n\n for (let i = 0; i < visibleColumns.length; i += 1) {\n const columnIndex = visibleColumns[i];\n\n const columnX = allColumnXs.get(columnIndex);\n const columnWidth = allColumnWidths.get(columnIndex);\n const modelColumn = this.getModelColumn(columnIndex);\n if (modelColumn != null) {\n const isFilterable = model.isFilterable(modelColumn);\n if (\n isFilterable &&\n columnX != null &&\n columnWidth != null &&\n columnWidth > 0\n ) {\n const x = gridX + columnX + columnWidth - 24;\n const y = gridY - (filterBarHeight ?? 0) + 2; // 2 acts as top margin for the button\n const style: CSSProperties = {\n position: 'absolute',\n top: y,\n left: x,\n };\n const advancedFilter = advancedFilters.get(modelColumn);\n const isFilterSet = advancedFilter != null;\n const isFilterVisible =\n columnIndex === hoverAdvancedFilter ||\n columnIndex === focusedFilterBarColumn ||\n isFilterSet;\n const element = (\n <div\n className={classNames('advanced-filter-button-container', {\n hidden: !isFilterVisible,\n })}\n key={columnIndex}\n style={style}\n >\n {isFilterVisible && (\n <Button\n kind=\"ghost\"\n className={classNames(\n 'btn-link-icon advanced-filter-button',\n {\n 'filter-set': isFilterSet,\n }\n )}\n onClick={() => {\n this.setState({ shownAdvancedFilter: columnIndex });\n }}\n onContextMenu={event => {\n this.grid?.handleContextMenu(event);\n }}\n onMouseEnter={() => {\n this.setState({ hoverAdvancedFilter: columnIndex });\n }}\n onMouseLeave={() => {\n this.setState({ hoverAdvancedFilter: null });\n }}\n >\n <div className=\"fa-layers\">\n <FontAwesomeIcon\n icon={dhFilterFilled}\n className=\"filter-solid\"\n />\n <FontAwesomeIcon\n icon={vsFilter}\n className=\"filter-light\"\n />\n </div>\n </Button>\n )}\n </div>\n );\n filterBar.push(element);\n }\n }\n }\n }\n const advancedFilterMenus = [];\n if (metrics) {\n const {\n gridX,\n visibleColumns,\n allColumnXs,\n allColumnWidths,\n columnHeaderHeight,\n } = metrics;\n for (let i = 0; i < visibleColumns.length; i += 1) {\n const columnIndex = visibleColumns[i];\n const columnX = allColumnXs.get(columnIndex);\n const columnWidth = allColumnWidths.get(columnIndex);\n if (columnX != null && columnWidth != null && columnWidth > 0) {\n const xColumnHeader = gridX + columnX;\n const xFilterBar = gridX + columnX + columnWidth - 20;\n const style: CSSProperties = isFilterBarShown\n ? {\n position: 'absolute',\n top: columnHeaderHeight,\n left: xFilterBar,\n width: 20,\n height: theme.filterBarHeight,\n }\n : {\n position: 'absolute',\n top: 0,\n left: xColumnHeader,\n width: columnWidth,\n height: columnHeaderHeight,\n };\n const modelColumn = this.getModelColumn(columnIndex);\n if (modelColumn != null) {\n const column = model.columns[modelColumn];\n if (column == null) {\n // Grid metrics is likely out of sync with model\n log.warn(\n `Column does not exist at index ${modelColumn} for column array of length ${model.columns.length}`\n );\n // eslint-disable-next-line no-continue\n continue;\n }\n const advancedFilter = advancedFilters.get(modelColumn);\n const { options: advancedFilterOptions } = advancedFilter || {};\n const sort = TableUtils.getSortForColumn(model.sort, column.name);\n const sortDirection = sort ? sort.direction : null;\n const element = (\n <div\n key={columnIndex}\n className=\"advanced-filter-menu-container\"\n style={style}\n >\n <Popper\n className=\"advanced-filter-menu-popper\"\n onEntered={this.getAdvancedMenuOpenedHandler(columnIndex)}\n onExited={() => {\n this.handleAdvancedMenuClosed(columnIndex);\n }}\n isShown={shownAdvancedFilter === columnIndex}\n interactive\n closeOnBlur\n options={{\n positionFixed: true,\n }}\n >\n {this.getCachedAdvancedFilterMenuActions(\n model,\n column,\n advancedFilterOptions,\n sortDirection,\n formatter\n )}\n </Popper>\n </div>\n );\n advancedFilterMenus.push(element);\n }\n }\n }\n }\n\n const optionItems = this.getCachedOptionItems(\n onCreateChart !== undefined && model.isChartBuilderAvailable,\n model.isCustomColumnsAvailable,\n model.isFormatColumnsAvailable,\n model.isRollupAvailable,\n model.isTotalsAvailable || isRollup,\n model.isSelectDistinctAvailable,\n model.isExportAvailable,\n this.toggleFilterBarAction,\n this.toggleSearchBarAction,\n this.toggleGotoRowAction,\n isFilterBarShown,\n showSearchBar,\n canDownloadCsv,\n this.isTableSearchAvailable(),\n isGotoShown,\n advancedSettings.size > 0\n );\n\n const hiddenColumns = this.getCachedHiddenColumns(\n metricCalculator,\n userColumnWidths\n );\n\n const openOptionsStack = openOptions.map(option => {\n switch (option.type) {\n case OptionType.CHART_BUILDER:\n return (\n <ChartBuilder\n model={model}\n onChange={this.handleChartChange}\n onSubmit={this.handleChartCreate}\n key={OptionType.CHART_BUILDER}\n />\n );\n case OptionType.VISIBILITY_ORDERING_BUILDER:\n return (\n <VisibilityOrderingBuilder\n model={model}\n movedColumns={movedColumns}\n hiddenColumns={hiddenColumns}\n columnHeaderGroups={columnHeaderGroups}\n onColumnVisibilityChanged={this.handleColumnVisibilityChanged}\n onReset={this.handleColumnVisibilityReset}\n onMovedColumnsChanged={this.handleMovedColumnsChanged}\n onColumnHeaderGroupChanged={this.handleHeaderGroupsChanged}\n key={OptionType.VISIBILITY_ORDERING_BUILDER}\n />\n );\n case OptionType.CONDITIONAL_FORMATTING:\n return (\n <ConditionalFormattingMenu\n rules={conditionalFormats}\n onChange={this.handleConditionalFormatsChange}\n onCreate={this.handleConditionalFormatCreate}\n onSelect={this.handleConditionalFormatEdit}\n />\n );\n case OptionType.CONDITIONAL_FORMATTING_EDIT:\n assertNotNull(model.columns);\n assertNotNull(this.handleConditionalFormatEditorUpdate);\n return (\n <ConditionalFormatEditor\n dh={model.dh}\n columns={model.columns}\n rule={conditionalFormatPreview}\n onUpdate={this.handleConditionalFormatEditorUpdate}\n onSave={this.handleConditionalFormatEditorSave}\n onCancel={this.handleConditionalFormatEditorCancel}\n />\n );\n case OptionType.CUSTOM_COLUMN_BUILDER:\n return (\n <CustomColumnBuilder\n model={model}\n customColumns={customColumns}\n onSave={this.handleUpdateCustomColumns}\n onCancel={this.handleMenuBack}\n key={OptionType.CUSTOM_COLUMN_BUILDER}\n />\n );\n case OptionType.ROLLUP_ROWS:\n return (\n <RollupRows\n model={model}\n onChange={this.handleRollupChange}\n config={rollupConfig}\n key={OptionType.ROLLUP_ROWS}\n />\n );\n case OptionType.AGGREGATIONS:\n return (\n <Aggregations\n settings={aggregationSettings}\n isRollup={isRollup}\n onChange={this.handleAggregationsChange}\n onEdit={this.handleAggregationEdit}\n />\n );\n case OptionType.AGGREGATION_EDIT:\n return (\n selectedAggregation && (\n <AggregationEdit\n aggregation={selectedAggregation}\n columns={model.originalColumns}\n onChange={this.handleAggregationChange}\n />\n )\n );\n case OptionType.TABLE_EXPORTER:\n return (\n <TableCsvExporter\n model={model}\n name={name}\n userColumnWidths={userColumnWidths}\n movedColumns={movedColumns}\n isDownloading={isTableDownloading}\n tableDownloadStatus={tableDownloadStatus}\n tableDownloadProgress={tableDownloadProgress}\n tableDownloadEstimatedTime={\n tableDownloadEstimatedTime ?? undefined\n }\n onDownload={this.handleDownloadTable}\n onDownloadStart={this.handleDownloadTableStart}\n onCancel={this.handleCancelDownloadTable}\n selectedRanges={selectedRanges}\n key={OptionType.TABLE_EXPORTER}\n />\n );\n case OptionType.SELECT_DISTINCT:\n return (\n <SelectDistinctBuilder\n model={model}\n selectDistinctColumns={selectDistinctColumns}\n onChange={this.handleSelectDistinctChanged}\n />\n );\n case OptionType.ADVANCED_SETTINGS:\n return (\n <AdvancedSettingsMenu\n items={advancedSettings}\n onChange={onAdvancedSettingsChange}\n />\n );\n\n default:\n throw Error(`Unexpected option type ${option.type}`);\n }\n });\n\n return (\n <div className=\"iris-grid\" role=\"presentation\">\n <div className=\"iris-grid-column\">\n {children != null && <div className=\"iris-grid-bar\">{children}</div>}\n <CSSTransition\n in={isSelectingPartition}\n timeout={ThemeExport.transitionSlowMs}\n classNames=\"iris-grid-bar-horizontal\"\n onEnter={this.handleAnimationStart}\n onEntered={this.handleAnimationEnd}\n onExit={this.handleAnimationStart}\n onExited={this.handleAnimationEnd}\n mountOnEnter\n unmountOnExit\n >\n <div className=\"iris-grid-partition-selector-wrapper iris-grid-bar iris-grid-bar-primary\">\n {partitionTable && partitionColumn && partition != null && (\n <IrisGridPartitionSelector\n dh={model.dh}\n table={partitionTable}\n getFormattedString={(\n value: unknown,\n type: string,\n stringName: string\n ) => model.displayString(value, type, stringName)}\n columnName={partitionColumn.name}\n partition={partition}\n onChange={this.handlePartitionChange}\n onFetchAll={this.handlePartitionFetchAll}\n onAppend={this.handlePartitionAppend}\n onDone={this.handlePartitionDone}\n />\n )}\n </div>\n </CSSTransition>\n <CSSTransition\n in={showSearchBar}\n timeout={ThemeExport.transitionSlowMs}\n classNames=\"iris-grid-bar-horizontal\"\n onEnter={this.handleAnimationStart}\n onEntered={this.handleAnimationEnd}\n onExit={this.handleAnimationStart}\n onExited={this.handleAnimationEnd}\n mountOnEnter\n unmountOnExit\n >\n <div className=\"iris-grid-bar\">\n <CrossColumnSearch\n value={searchValue}\n selectedColumns={selectedSearchColumns}\n invertSelection={invertSearchColumns}\n onChange={this.handleCrossColumnSearch}\n columns={model.columns}\n ref={this.crossColumnRef}\n />\n </div>\n </CSSTransition>\n <div\n className=\"grid-wrapper\"\n ref={gridWrapper => {\n this.gridWrapper = gridWrapper;\n }}\n >\n <Grid\n ref={grid => {\n this.grid = grid;\n }}\n isStickyBottom={!isEditableGridModel(model) || !model.isEditable}\n isStuckToBottom={isStuckToBottom}\n isStuckToRight={isStuckToRight}\n metricCalculator={metricCalculator}\n model={model}\n keyHandlers={keyHandlers}\n mouseHandlers={mouseHandlers}\n movedColumns={movedColumns}\n movedRows={movedRows}\n onError={this.handleGridError}\n onViewChanged={this.handleViewChanged}\n onSelectionChanged={this.handleSelectionChanged}\n onMovedColumnsChanged={this.handleMovedColumnsChanged}\n renderer={this.renderer}\n stateOverride={stateOverride}\n theme={theme}\n />\n <IrisGridCellOverflowModal\n isOpen={showOverflowModal}\n text={overflowText}\n onClose={this.handleOverflowClose}\n />\n {isVisible && (\n <IrisGridModelUpdater\n model={model}\n modelColumns={model.columns}\n top={top}\n bottom={bottom}\n left={left}\n right={right}\n filter={filter}\n formatter={formatter}\n sorts={sorts}\n reverseType={reverseType}\n movedColumns={movedColumns}\n customColumns={customColumns}\n hiddenColumns={hiddenColumns}\n alwaysFetchColumns={this.getAlwaysFetchColumns(\n alwaysFetchColumns,\n model.columns,\n movedColumns,\n model.floatingLeftColumnCount,\n model.floatingRightColumnCount,\n this.grid?.state.draggingColumn?.range\n )}\n formatColumns={this.getCachedPreviewFormatColumns(\n model.dh,\n model.columns,\n conditionalFormats,\n conditionalFormatPreview,\n // Disable the preview format when we press Back on the format edit page\n openOptions[openOptions.length - 1]?.type ===\n OptionType.CONDITIONAL_FORMATTING_EDIT\n ? conditionalFormatEditIndex ?? undefined\n : undefined\n )}\n rollupConfig={this.getModelRollupConfig(\n model.originalColumns,\n rollupConfig,\n aggregationSettings\n )}\n totalsConfig={this.getModelTotalsConfig(\n model.columns,\n rollupConfig,\n aggregationSettings\n )}\n selectDistinctColumns={selectDistinctColumns}\n pendingRowCount={pendingRowCount}\n pendingDataMap={pendingDataMap}\n frozenColumns={frozenColumns}\n columnHeaderGroups={columnHeaderGroups}\n />\n )}\n {!isMenuShown && (\n <div className=\"grid-settings-button\">\n <Button\n kind=\"ghost\"\n data-testid={`btn-iris-grid-settings-button-${name}`}\n onClick={this.handleMenu}\n icon={<FontAwesomeIcon icon={vsMenu} transform=\"up-1\" />}\n tooltip=\"Table Options\"\n />\n </div>\n )}\n {focusField}\n {loadingElement}\n {filterBar}\n {columnTooltip}\n {advancedFilterMenus}\n {overflowButtonTooltipProps &&\n this.getOverflowButtonTooltip(overflowButtonTooltipProps)}\n {expandCellTooltipProps &&\n this.getExpandCellTooltip(expandCellTooltipProps)}\n {linkHoverTooltipProps &&\n this.getLinkHoverTooltip(linkHoverTooltipProps)}\n </div>\n <GotoRow\n model={model}\n isShown={isGotoShown}\n gotoRow={gotoRow}\n gotoRowError={gotoRowError}\n gotoValueError={gotoValueError}\n onGotoRowSubmit={this.handleGotoRowSelectedRowNumberSubmit}\n onGotoRowNumberChanged={this.handleGotoRowSelectedRowNumberChanged}\n onClose={this.handleGotoRowClosed}\n onEntering={this.handleAnimationStart}\n onEntered={this.handleAnimationEnd}\n onExiting={() => {\n this.handleAnimationStart();\n this.focus();\n }}\n onExited={this.handleAnimationEnd}\n gotoValueSelectedColumnName={gotoValueSelectedColumnName}\n gotoValue={gotoValue}\n gotoValueFilter={gotoValueSelectedFilter}\n onGotoValueSelectedColumnNameChanged={\n this.handleGotoValueSelectedColumnNameChanged\n }\n onGotoValueSelectedFilterChanged={\n this.handleGotoValueSelectedFilterChanged\n }\n onGotoValueChanged={this.handleGotoValueChanged}\n onGotoValueSubmit={this.handleGotoValueSubmitted}\n />\n\n <PendingDataBottomBar\n error={pendingSaveError}\n isSaving={pendingSavePromise != null}\n saveTooltip={`Commit (${this.commitAction.shortcut.getDisplayText()})`}\n discardTooltip={`Discard (${this.discardAction.shortcut.getDisplayText()})`}\n pendingDataErrors={pendingDataErrors}\n pendingDataMap={pendingDataMap}\n onEntering={this.handleAnimationStart}\n onEntered={this.handleAnimationEnd}\n onExiting={this.handleAnimationStart}\n onExited={this.handleAnimationEnd}\n onSave={this.handlePendingCommitClicked}\n onDiscard={this.handlePendingDiscardClicked}\n />\n <ToastBottomBar>{toastMessage}</ToastBottomBar>\n <IrisGridCopyHandler\n model={model}\n copyOperation={copyOperation ?? undefined}\n onEntering={this.handleAnimationStart}\n onEntered={this.handleAnimationEnd}\n onExiting={this.handleAnimationStart}\n onExited={this.handleAnimationEnd}\n />\n <TableSaver\n dh={model.dh}\n ref={tableSaver => {\n this.tableSaver = tableSaver;\n }}\n getDownloadWorker={getDownloadWorker}\n onDownloadCompleted={this.handleDownloadCompleted}\n onDownloadCanceled={this.handleDownloadCanceled}\n onDownloadProgressUpdate={this.handleDownloadProgressUpdate}\n isDownloading={\n tableDownloadStatus ===\n TableCsvExporter.DOWNLOAD_STATUS.DOWNLOADING\n }\n formatter={formatter}\n />\n </div>\n <CSSTransition\n in={isMenuShown}\n timeout={ThemeExport.transitionMidMs}\n classNames=\"slide-left\"\n onEntering={this.handleAnimationStart}\n onEntered={this.handleAnimationEnd}\n onExiting={this.handleAnimationStart}\n onExited={this.handleAnimationEnd}\n mountOnEnter\n unmountOnExit\n >\n <div className=\"table-sidebar\">\n <Stack>\n <Page title=\"Table Options\" onClose={this.handleMenuClose}>\n <Menu\n onSelect={i => this.handleMenuSelect(optionItems[i])}\n items={optionItems}\n />\n </Page>\n {openOptionsStack.map((option, i) => (\n <Page\n title={openOptions[i].title}\n onBack={this.handleMenuBack}\n onClose={this.handleMenuClose}\n key={openOptions[i].type}\n >\n {option}\n </Page>\n ))}\n </Stack>\n </div>\n </CSSTransition>\n <ContextActions actions={this.contextActions} />\n </div>\n );\n }\n}\n\nexport default IrisGrid;\n","import { ModelIndex } from '@deephaven/grid';\nimport { ColumnName } from './CommonTypes';\n\nclass MissingKeyError extends Error {\n isMissingKey = true;\n\n rowIndex: ModelIndex;\n\n columnName: ColumnName;\n\n constructor(rowIndex: ModelIndex, columnName: ColumnName) {\n super(`${columnName} can't be empty (on pending row ${rowIndex + 1})`);\n this.rowIndex = rowIndex;\n this.columnName = columnName;\n }\n}\n\nexport default MissingKeyError;\n","/* eslint-disable no-underscore-dangle */\n/* eslint class-methods-use-this: \"off\" */\nimport memoize from 'memoize-one';\nimport throttle from 'lodash.throttle';\nimport {\n EditOperation,\n GridRange,\n GridUtils,\n memoizeClear,\n ModelIndex,\n MoveOperation,\n VisibleIndex,\n} from '@deephaven/grid';\nimport type {\n Column,\n ColumnStatistics,\n CustomColumn,\n dh as DhType,\n FilterCondition,\n Format,\n InputTable,\n LayoutHints,\n RollupConfig,\n Row,\n Sort,\n Table,\n TableTemplate,\n TableViewportSubscription,\n TotalsTable,\n ValueTypeUnion,\n ViewportData,\n} from '@deephaven/jsapi-types';\nimport Log from '@deephaven/log';\nimport {\n CancelablePromise,\n EventShimCustomEvent,\n PromiseUtils,\n assertNotNull,\n} from '@deephaven/utils';\nimport { TableUtils, Formatter, FormatterUtils } from '@deephaven/jsapi-utils';\nimport IrisGridModel from './IrisGridModel';\nimport AggregationOperation from './sidebar/aggregations/AggregationOperation';\nimport IrisGridUtils from './IrisGridUtils';\nimport MissingKeyError from './MissingKeyError';\nimport {\n ColumnName,\n UITotalsTableConfig,\n UIRow,\n PendingDataMap,\n CellData,\n UIViewportData,\n PendingDataErrorMap,\n} from './CommonTypes';\nimport { IrisGridThemeType } from './IrisGridTheme';\nimport ColumnHeaderGroup, { isColumnHeaderGroup } from './ColumnHeaderGroup';\n\nconst log = Log.module('IrisGridTableModel');\n\nconst SET_VIEWPORT_THROTTLE = 150;\nconst APPLY_VIEWPORT_THROTTLE = 0;\n\nconst EMPTY_ARRAY: unknown[] = [];\n\nexport function isIrisGridTableModelTemplate(\n model: IrisGridModel\n): model is IrisGridTableModelTemplate {\n return (model as IrisGridTableModelTemplate).table !== undefined;\n}\n\n/**\n * Template model for a grid\n */\n\nclass IrisGridTableModelTemplate<\n T extends TableTemplate<T> = Table,\n R extends UIRow = UIRow\n> extends IrisGridModel {\n static ROW_BUFFER_PAGES = 1;\n\n seekRow(\n startRow: number,\n column: Column,\n valueType: ValueTypeUnion,\n value: unknown,\n insensitive?: boolean | undefined,\n contains?: boolean | undefined,\n isBackwards?: boolean | undefined\n ): Promise<number> {\n throw new Error('Method not implemented.');\n }\n\n export(): Promise<Table> {\n throw new Error('Method not implemented.');\n }\n\n columnStatistics(column: Column): Promise<ColumnStatistics> {\n throw new Error('Method not implemented.');\n }\n\n get customColumns(): ColumnName[] {\n return [];\n }\n\n set customColumns(customColumns: ColumnName[]) {\n throw new Error('Method not implemented.');\n }\n\n get formatColumns(): CustomColumn[] {\n return [];\n }\n\n set formatColumns(formatColumns: CustomColumn[]) {\n throw new Error('Method not implemented.');\n }\n\n updateFrozenColumns(columns: ColumnName[]): void {\n throw new Error('Method not implemented.');\n }\n\n get rollupConfig(): RollupConfig | null {\n throw new Error('Method not implemented.');\n }\n\n set rollupConfig(rollupConfig: RollupConfig | null) {\n throw new Error('Method not implemented.');\n }\n\n get selectDistinctColumns(): ColumnName[] {\n throw new Error('Method not implemented.');\n }\n\n set selectDistinctColumns(names: ColumnName[]) {\n throw new Error('Method not implemented.');\n }\n\n /**\n * Returns an array of the columns in the model\n * The order of model columns should never change once established\n */\n get columns(): Column[] {\n return this.table.columns;\n }\n\n dh: DhType;\n\n irisGridUtils: IrisGridUtils;\n\n tableUtils: TableUtils;\n\n private irisFormatter: Formatter;\n\n inputTable: InputTable | null;\n\n private subscription: TableViewportSubscription | null;\n\n table: T;\n\n viewport: {\n top: VisibleIndex;\n bottom: VisibleIndex;\n columns: Column[];\n } | null;\n\n viewportData: UIViewportData<R> | null;\n\n formattedStringData: (string | null)[][];\n\n private pendingStringData: (string | null)[][];\n\n private isSaveInProgress: boolean;\n\n private totalsTable: TotalsTable | null;\n\n totalsTablePromise: CancelablePromise<TotalsTable> | null;\n\n totals: UITotalsTableConfig | null;\n\n private totalsDataMap: Map<string, R> | null;\n\n // Map from new row index to their values. Only for input tables that can have new rows added.\n // The index of these rows start at 0, and they are appended at the end of the regular table data.\n // These rows can be sparse, so using a map instead of an array.\n private pendingNewDataMap: PendingDataMap<R>;\n\n private pendingNewRowCount = 0;\n\n private _columnHeaderGroupMap: Map<string, ColumnHeaderGroup> = new Map();\n\n private columnHeaderParentMap: Map<string, ColumnHeaderGroup> = new Map();\n\n private _columnHeaderMaxDepth: number | null = null;\n\n private _columnHeaderGroups: ColumnHeaderGroup[] = [];\n\n private _movedColumns: MoveOperation[] | null = null;\n\n /**\n * @param dh JSAPI instance\n * @param table Iris data table to be used in the model\n * @param formatter The formatter to use when getting formats\n * @param inputTable Iris input table associated with this table\n */\n constructor(\n dh: DhType,\n table: T,\n formatter = new Formatter(dh),\n inputTable: InputTable | null = null\n ) {\n super(dh);\n\n this.handleTableDisconnect = this.handleTableDisconnect.bind(this);\n this.handleTableReconnect = this.handleTableReconnect.bind(this);\n this.handleTableUpdate = this.handleTableUpdate.bind(this);\n this.handleTotalsUpdate = this.handleTotalsUpdate.bind(this);\n this.handleRequestFailed = this.handleRequestFailed.bind(this);\n this.handleCustomColumnsChanged = this.handleCustomColumnsChanged.bind(\n this\n );\n\n this.dh = dh;\n this.irisFormatter = formatter;\n this.irisGridUtils = new IrisGridUtils(dh);\n this.inputTable = inputTable;\n this.subscription = null;\n this.table = table;\n this.tableUtils = new TableUtils(dh);\n this.viewport = null;\n this.viewportData = null;\n this.formattedStringData = [];\n this.pendingStringData = [];\n this.isSaveInProgress = false;\n\n this.totalsTable = null;\n this.totalsTablePromise = null;\n this.totals = null;\n this.totalsDataMap = null;\n\n // Map from new row index to their values. Only for input tables that can have new rows added.\n // The index of these rows start at 0, and they are appended at the end of the regular table data.\n // These rows can be sparse, so using a map instead of an array.\n this.pendingNewDataMap = new Map();\n this.pendingNewRowCount = 0;\n\n this.columnHeaderGroups = IrisGridUtils.parseColumnHeaderGroups(\n this,\n this.layoutHints?.columnGroups ?? []\n ).groups;\n }\n\n close(): void {\n this.table.close();\n if (this.totalsTable !== null) {\n this.totalsTable.close();\n }\n if (this.totalsTablePromise !== null) {\n this.totalsTablePromise.cancel();\n }\n }\n\n startListening(): void {\n super.startListening();\n\n const { dh } = this;\n\n this.table.addEventListener(\n dh.Table.EVENT_DISCONNECT,\n this.handleTableDisconnect\n );\n this.table.addEventListener(\n dh.Table.EVENT_RECONNECT,\n this.handleTableReconnect\n );\n this.table.addEventListener(dh.Table.EVENT_UPDATED, this.handleTableUpdate);\n this.table.addEventListener(\n dh.Client.EVENT_REQUEST_FAILED,\n this.handleRequestFailed\n );\n this.table.addEventListener(\n dh.Table.EVENT_CUSTOMCOLUMNSCHANGED,\n this.handleCustomColumnsChanged\n );\n\n if (this.totalsTable != null) {\n this.addTotalsListeners(this.totalsTable);\n }\n\n this.applyViewport();\n }\n\n stopListening(): void {\n super.stopListening();\n\n const { dh } = this;\n\n this.table.removeEventListener(\n dh.Table.EVENT_DISCONNECT,\n this.handleTableDisconnect\n );\n this.table.removeEventListener(\n dh.Table.EVENT_RECONNECT,\n this.handleTableReconnect\n );\n this.table.removeEventListener(\n dh.Table.EVENT_UPDATED,\n this.handleTableUpdate\n );\n this.table.removeEventListener(\n dh.Client.EVENT_REQUEST_FAILED,\n this.handleRequestFailed\n );\n this.table.removeEventListener(\n dh.Table.EVENT_CUSTOMCOLUMNSCHANGED,\n this.handleCustomColumnsChanged\n );\n\n if (this.totalsTable != null) {\n this.removeTotalsListeners(this.totalsTable);\n }\n\n this.closeSubscription();\n }\n\n addTotalsListeners(totalsTable: TotalsTable): void {\n const { dh } = this;\n totalsTable.addEventListener(\n dh.Table.EVENT_UPDATED,\n this.handleTotalsUpdate\n );\n\n // Totals table only has one row of data\n totalsTable.setViewport(0, 0);\n }\n\n removeTotalsListeners(totalsTable: TotalsTable): void {\n const { dh } = this;\n totalsTable.removeEventListener(\n dh.Table.EVENT_UPDATED,\n this.handleTotalsUpdate\n );\n }\n\n handleTableDisconnect(): void {\n this.dispatchEvent(\n new EventShimCustomEvent(IrisGridModel.EVENT.DISCONNECT)\n );\n }\n\n handleTableReconnect(): void {\n this.dispatchEvent(new EventShimCustomEvent(IrisGridModel.EVENT.RECONNECT));\n }\n\n handleTableUpdate(event: CustomEvent): void {\n this.copyViewportData(event.detail);\n\n this.dispatchEvent(new EventShimCustomEvent(IrisGridModel.EVENT.UPDATED));\n }\n\n handleTotalsUpdate(event: CustomEvent): void {\n this.copyTotalsData(event.detail);\n\n this.dispatchEvent(new EventShimCustomEvent(IrisGridModel.EVENT.UPDATED));\n }\n\n handleRequestFailed(event: CustomEvent): void {\n this.dispatchEvent(\n new EventShimCustomEvent(IrisGridModel.EVENT.REQUEST_FAILED, event)\n );\n }\n\n handleCustomColumnsChanged(): void {\n this.dispatchEvent(\n new EventShimCustomEvent(IrisGridModel.EVENT.COLUMNS_CHANGED, {\n detail: this.columns,\n })\n );\n }\n\n get rowCount(): number {\n return (\n this.table.size +\n this.pendingNewRowCount +\n (this.totals?.operationOrder?.length ?? 0)\n );\n }\n\n get pendingDataErrors(): PendingDataErrorMap {\n return this.getCachedPendingErrors(\n this.pendingNewDataMap,\n this.columns,\n this.inputTable?.keyColumns.length ?? 0\n );\n }\n\n get pendingDataMap(): PendingDataMap<R> {\n return this.pendingNewDataMap;\n }\n\n set pendingDataMap(map: PendingDataMap<R>) {\n if (map === this.pendingNewDataMap) {\n return;\n }\n\n map.forEach((row, rowIndex) => {\n if (!IrisGridUtils.isValidIndex(rowIndex)) {\n throw new Error(`Invalid rowIndex ${rowIndex}`);\n }\n\n const { data } = row;\n data.forEach((value, columnIndex) => {\n if (!IrisGridUtils.isValidIndex(columnIndex)) {\n throw new Error(`Invalid columnIndex ${columnIndex}`);\n }\n });\n });\n\n this.pendingNewDataMap = map;\n\n this.pendingNewRowCount = Math.max(\n this.pendingNewRowCount,\n this.maxPendingDataRow\n );\n\n this.formattedStringData = [];\n\n this.dispatchEvent(\n new EventShimCustomEvent(IrisGridModel.EVENT.PENDING_DATA_UPDATED)\n );\n }\n\n get pendingRowCount(): number {\n return this.pendingNewRowCount;\n }\n\n set pendingRowCount(count: number) {\n if (count === this.pendingNewRowCount) {\n return;\n }\n\n this.pendingNewRowCount = Math.max(0, count, this.maxPendingDataRow);\n\n this.dispatchEvent(new EventShimCustomEvent(IrisGridModel.EVENT.UPDATED));\n }\n\n get maxPendingDataRow(): number {\n return this.pendingNewDataMap.size > 0\n ? Math.max(...this.pendingNewDataMap.keys()) + 1\n : 0;\n }\n\n get columnCount(): number {\n return this.columns.length;\n }\n\n get floatingBottomRowCount(): number {\n return this.totals != null && this.totals.showOnTop\n ? 0\n : this.totals?.operationOrder?.length ?? 0;\n }\n\n get floatingTopRowCount(): number {\n return this.totals != null && this.totals.showOnTop\n ? this.totals?.operationOrder?.length ?? 0\n : 0;\n }\n\n get isChartBuilderAvailable(): boolean {\n return true;\n }\n\n get isTotalsAvailable(): boolean {\n return this.table.getTotalsTable != null;\n }\n\n get isEditable(): boolean {\n return !this.isSaveInProgress && this.inputTable != null;\n }\n\n cacheFormattedValue(x: ModelIndex, y: ModelIndex, text: string | null): void {\n if (this.formattedStringData[x] == null) {\n this.formattedStringData[x] = [];\n }\n this.formattedStringData[x][y] = text;\n }\n\n cachePendingValue(x: ModelIndex, y: ModelIndex, text: string | null): void {\n if (this.pendingStringData[x] == null) {\n this.pendingStringData[x] = [];\n }\n this.pendingStringData[x][y] = text;\n }\n\n clearPendingValue(x: ModelIndex, y: ModelIndex): void {\n const column = this.pendingStringData[x];\n if (column != null) {\n delete column[y];\n }\n }\n\n textValueForCell(x: ModelIndex, y: ModelIndex): string | null {\n // First check if there's any pending values we should read from\n if (this.pendingStringData[x]?.[y] !== undefined) {\n return this.pendingStringData[x][y];\n }\n\n // Use a separate cache from memoization just for the strings that are currently displayed\n if (this.formattedStringData[x]?.[y] === undefined) {\n const value = this.valueForCell(x, y);\n if (value == null) {\n return null;\n }\n\n const column = this.totalsColumn(x, y) ?? this.columns[x];\n const hasCustomColumnFormat = this.getCachedCustomColumnFormatFlag(\n this.formatter,\n column.name,\n column.type\n );\n let formatOverride;\n if (!hasCustomColumnFormat) {\n const formatForCell = this.formatForCell(x, y);\n if (formatForCell?.formatString != null) {\n formatOverride = formatForCell;\n }\n }\n const text = this.displayString(\n value,\n column.type,\n column.name,\n formatOverride\n );\n this.cacheFormattedValue(x, y, text);\n }\n\n return this.formattedStringData[x][y];\n }\n\n textForCell(x: ModelIndex, y: ModelIndex): string {\n const text = this.textValueForCell(x, y);\n if (text == null && this.isKeyColumn(x)) {\n const pendingRow = this.pendingRow(y);\n if (pendingRow != null && this.pendingDataMap.has(pendingRow)) {\n // Asterisk to show a value is required for a key column on a row that has some data entered\n return '*';\n }\n }\n return text ?? '';\n }\n\n truncationCharForCell(x: ModelIndex): '#' | undefined {\n const column = this.columns[x];\n const { type } = column;\n if (\n TableUtils.isNumberType(type) &&\n this.formatter.truncateNumbersWithPound\n ) {\n return '#';\n }\n\n return undefined;\n }\n\n colorForCell(x: ModelIndex, y: ModelIndex, theme: IrisGridThemeType): string {\n const data = this.dataForCell(x, y);\n if (data) {\n const { format, value } = data;\n if (value == null || value === '') {\n assertNotNull(theme.nullStringColor);\n return theme.nullStringColor;\n }\n if (format && format.color) {\n return format.color;\n }\n\n if (this.isPendingRow(y)) {\n // Data entered in a pending row\n assertNotNull(theme.pendingTextColor);\n return theme.pendingTextColor;\n }\n\n // Fallback to formatting based on the value/type of the cell\n if (value != null) {\n const column = this.totalsColumn(x, y) ?? this.columns[x];\n if (TableUtils.isDateType(column.type) || column.name === 'Date') {\n assertNotNull(theme.dateColor);\n return theme.dateColor;\n }\n if (TableUtils.isNumberType(column.type)) {\n if ((value as number) > 0) {\n assertNotNull(theme.positiveNumberColor);\n return theme.positiveNumberColor;\n }\n if ((value as number) < 0) {\n assertNotNull(theme.negativeNumberColor);\n return theme.negativeNumberColor;\n }\n assertNotNull(theme.zeroNumberColor);\n return theme.zeroNumberColor;\n }\n }\n } else if (this.isPendingRow(y) && this.isKeyColumn(x)) {\n assertNotNull(theme.errorTextColor);\n return theme.errorTextColor;\n }\n\n return theme.textColor;\n }\n\n backgroundColorForCell(x: ModelIndex, y: ModelIndex): string | null {\n return this.formatForCell(x, y)?.backgroundColor ?? null;\n }\n\n textAlignForCell(x: ModelIndex): CanvasTextAlign {\n const column = this.columns[x];\n const { type } = column;\n\n if (TableUtils.isNumberType(type)) {\n return 'right';\n }\n if (TableUtils.isDateType(type) || column.name === 'Date') {\n return 'center';\n }\n return 'left';\n }\n\n textForColumnHeader(x: ModelIndex, depth = 0): string | undefined {\n const header = this.columnAtDepth(x, depth);\n if (isColumnHeaderGroup(header)) {\n return header.isNew ? '' : header.name;\n }\n return header?.name;\n }\n\n colorForColumnHeader(x: ModelIndex, depth = 0): string | null {\n const column = this.columnAtDepth(x, depth);\n if (isColumnHeaderGroup(column)) {\n return column.color ?? null;\n }\n return null;\n }\n\n getColumnHeaderGroup(\n modelIndex: ModelIndex,\n depth: number\n ): ColumnHeaderGroup | undefined {\n const group = this.columnAtDepth(modelIndex, depth);\n if (isColumnHeaderGroup(group)) {\n return group;\n }\n return undefined;\n }\n\n getColumnHeaderParentGroup(\n modelIndex: ModelIndex,\n depth: number\n ): ColumnHeaderGroup | undefined {\n return this.columnHeaderParentMap.get(\n this.columnAtDepth(modelIndex, depth)?.name ?? ''\n );\n }\n\n columnAtDepth(\n x: ModelIndex,\n depth = 0\n ): ColumnHeaderGroup | Column | undefined {\n if (depth === 0) {\n return this.columns[x];\n }\n\n const columnName = this.columns[x]?.name;\n let group = this.columnHeaderParentMap.get(columnName);\n\n if (!group) {\n return undefined;\n }\n\n let currentDepth = group.depth;\n while (currentDepth < depth) {\n group = this.columnHeaderParentMap.get(group.name);\n if (!group) {\n return undefined;\n }\n currentDepth = group.depth;\n }\n\n if (group.depth === depth) {\n return group;\n }\n\n return undefined;\n }\n\n textForRowFooter(y: ModelIndex): string {\n const totalsRow = this.totalsRow(y);\n if (totalsRow != null && this.totals) {\n return this.totals.operationOrder[totalsRow];\n }\n return '';\n }\n\n private getMemoizedInitialMovedColumns = memoize(\n (layoutHints?: LayoutHints): readonly MoveOperation[] => {\n if (!layoutHints) {\n return [];\n }\n let movedColumns: MoveOperation[] = [];\n const { groupMap } = IrisGridUtils.parseColumnHeaderGroups(\n this,\n layoutHints?.columnGroups ?? []\n );\n\n const moveColumn = (name: string, toIndex: VisibleIndex) => {\n const modelIndex = this.getColumnIndexByName(name);\n if (modelIndex == null) {\n throw new Error(`Unknown layout hint column: ${name}`);\n }\n const visibleIndex = GridUtils.getVisibleIndex(\n modelIndex,\n movedColumns\n );\n movedColumns = GridUtils.moveItem(visibleIndex, toIndex, movedColumns);\n };\n\n const moveGroup = (name: string, toIndex: VisibleIndex) => {\n const group = groupMap.get(name);\n if (group == null) {\n throw new Error(`Unknown layout hint group: ${name}`);\n }\n const visibleRange = group.getVisibleRange(movedColumns);\n movedColumns = GridUtils.moveRange(visibleRange, toIndex, movedColumns);\n };\n\n const {\n frontColumns = [],\n backColumns = [],\n frozenColumns = [],\n } = layoutHints;\n\n if (frontColumns.length || backColumns.length || frozenColumns.length) {\n const usedColumns = new Set();\n\n let frontIndex = 0;\n frozenColumns.forEach(name => {\n if (usedColumns.has(name)) {\n throw new Error(\n `Column specified in multiple layout hints: ${name}`\n );\n }\n moveColumn(name, frontIndex);\n frontIndex += 1;\n });\n frontColumns.forEach(name => {\n if (usedColumns.has(name)) {\n throw new Error(\n `Column specified in multiple layout hints: ${name}`\n );\n }\n moveColumn(name, frontIndex);\n frontIndex += 1;\n });\n\n let backIndex = this.columnMap.size - 1;\n backColumns.forEach(name => {\n if (usedColumns.has(name)) {\n throw new Error(\n `Column specified in multiple layout hints: ${name}`\n );\n }\n moveColumn(name, backIndex);\n backIndex -= 1;\n });\n }\n\n const layoutHintColumnGroups = layoutHints?.columnGroups;\n if (layoutHintColumnGroups) {\n const columnGroups = [...groupMap.values()];\n columnGroups.sort((a, b) => a.depth - b.depth);\n\n columnGroups.forEach(group => {\n const firstChildName = group.children[0];\n const rightModelIndex = this.getColumnIndexByName(firstChildName);\n\n let rightVisibleIndex: number;\n\n if (rightModelIndex != null) {\n rightVisibleIndex = GridUtils.getVisibleIndex(\n rightModelIndex,\n movedColumns\n );\n } else {\n const firstChildGroup = groupMap.get(firstChildName);\n if (!firstChildGroup) {\n throw new Error(\n `Unknown column ${firstChildName} in group ${group.name}`\n );\n }\n\n const visibleRange = firstChildGroup.getVisibleRange(movedColumns);\n // Columns will be moved to start at the end of the first child group\n [, rightVisibleIndex] = visibleRange;\n }\n\n for (let i = 1; i < group.children.length; i += 1) {\n const childName = group.children[i];\n const childGroup = groupMap.get(childName);\n const childColumn = this.getColumnIndexByName(childName);\n\n if (childGroup) {\n // All columns in the group will be before or after the start index\n // Lower level groups are re-arranged first, so they will be contiguous\n const isBeforeGroup =\n childGroup.getVisibleRange(movedColumns)[0] < rightVisibleIndex;\n\n const moveToIndex = isBeforeGroup\n ? rightVisibleIndex - childGroup.childIndexes.length + 1\n : rightVisibleIndex + 1;\n\n moveGroup(childName, moveToIndex);\n rightVisibleIndex =\n moveToIndex + childGroup.childIndexes.length - 1;\n } else if (childColumn != null) {\n const isBeforeGroup =\n GridUtils.getVisibleIndex(childColumn, movedColumns) <\n rightVisibleIndex;\n\n const moveToIndex = isBeforeGroup\n ? rightVisibleIndex\n : rightVisibleIndex + 1;\n moveColumn(childName, moveToIndex);\n rightVisibleIndex = moveToIndex;\n }\n }\n });\n }\n\n this._movedColumns = movedColumns;\n return movedColumns;\n }\n );\n\n /**\n * Used to get the initial moved columns based on layout hints\n */\n get initialMovedColumns(): readonly MoveOperation[] {\n return this.getMemoizedInitialMovedColumns(this.layoutHints ?? undefined);\n }\n\n /**\n * Not currently used by anything.\n */\n get initialMovedRows(): MoveOperation[] {\n return EMPTY_ARRAY as MoveOperation[];\n }\n\n getMemoizedInitialColumnHeaderGroups = memoize(\n (layoutHints?: LayoutHints) =>\n IrisGridUtils.parseColumnHeaderGroups(\n this,\n layoutHints?.columnGroups ?? []\n ).groups\n );\n\n get initialColumnHeaderGroups(): ColumnHeaderGroup[] {\n return this.getMemoizedInitialColumnHeaderGroups(\n this.layoutHints ?? undefined\n );\n }\n\n getMemoizedColumnMap = memoize(\n (tableColumns: Column[]): Map<string, Column> => {\n const columnMap = new Map();\n tableColumns.forEach(col => columnMap.set(col.name, col));\n return columnMap;\n }\n );\n\n get columnMap(): Map<ColumnName, Column> {\n return this.getMemoizedColumnMap(this.table.columns);\n }\n\n get columnHeaderMaxDepth(): number {\n return this._columnHeaderMaxDepth ?? 1;\n }\n\n private set columnHeaderMaxDepth(depth: number) {\n this._columnHeaderMaxDepth = depth;\n }\n\n get columnHeaderGroupMap(): Map<string, ColumnHeaderGroup> {\n return this._columnHeaderGroupMap;\n }\n\n get columnHeaderGroups(): ColumnHeaderGroup[] {\n return this._columnHeaderGroups;\n }\n\n set columnHeaderGroups(groups: ColumnHeaderGroup[]) {\n if (groups === this._columnHeaderGroups) {\n return;\n }\n\n const {\n groups: newGroups,\n maxDepth,\n parentMap,\n groupMap,\n } = IrisGridUtils.parseColumnHeaderGroups(\n this,\n groups ?? this.initialColumnHeaderGroups\n );\n\n this._columnHeaderGroups = newGroups;\n this.columnHeaderMaxDepth = maxDepth;\n this.columnHeaderParentMap = parentMap;\n this._columnHeaderGroupMap = groupMap;\n }\n\n get groupedColumns(): Column[] {\n return [];\n }\n\n row(y: ModelIndex): R | null {\n const totalsRowCount = this.totals?.operationOrder?.length ?? 0;\n const showOnTop = this.totals?.showOnTop ?? false;\n const totalsRow = this.totalsRow(y);\n if (totalsRow != null) {\n const operation = this.totals?.operationOrder[totalsRow];\n assertNotNull(operation);\n return this.totalsDataMap?.get(operation) ?? null;\n }\n const pendingRow = this.pendingRow(y);\n if (pendingRow != null) {\n return this.pendingNewDataMap.get(pendingRow) ?? null;\n }\n const offset = this.viewportData?.offset ?? 0;\n const viewportY = (showOnTop ? y - totalsRowCount : y) - offset;\n return this.viewportData?.rows?.[viewportY] ?? null;\n }\n\n /**\n * Retrieve the totals column if this is a totals row, or null otherwise\n * @param x Column index to get the totals column from\n * @param y Row index to get the totals column from\n */\n totalsColumn(x: ModelIndex, y: ModelIndex): Column | undefined | null {\n const totalsRow = this.totalsRow(y);\n if (totalsRow == null) return null;\n\n const operation = this.totals?.operationOrder[totalsRow];\n const defaultOperation =\n this.totals?.defaultOperation ?? AggregationOperation.SUM;\n const tableColumn = this.columns[x];\n\n // Find the matching totals table column for the operation\n // When there are multiple aggregations, the column name will be the original name of the column with the operation appended afterward\n // When the the operation is the default operation OR there is only one operation, then the totals column name is just the original column name\n return this.totalsTable?.columns.find(\n column =>\n column.name === `${tableColumn.name}__${operation}` ||\n ((operation === defaultOperation ||\n this.totals?.operationOrder.length === 1) &&\n column.name === tableColumn.name)\n );\n }\n\n /**\n * Translate from the row in the model to a row in the totals table.\n * If the row is not a totals row, return null\n * @param y The row in the model to get the totals row for\n * @returns The row within the totals table if it's a totals row, null otherwise\n */\n totalsRow(y: ModelIndex): ModelIndex | null {\n const totalsRowCount = this.totals?.operationOrder?.length ?? 0;\n const showOnTop = this.totals?.showOnTop ?? false;\n const totalsRow = showOnTop ? y : y - this.table.size;\n if (totalsRow >= 0 && totalsRow < totalsRowCount) {\n return totalsRow;\n }\n return null;\n }\n\n /**\n * Translate from the row in the model to a pending input row.\n * If the row is not a pending input row, return null\n * @param y The row in the model to get the pending row for\n * @returns The row within the pending input rows if it's a pending row, null otherwise\n */\n pendingRow(y: ModelIndex): ModelIndex | null {\n const pendingRow = y - this.floatingTopRowCount - this.table.size;\n if (pendingRow >= 0 && pendingRow < this.pendingNewRowCount) {\n return pendingRow;\n }\n\n return null;\n }\n\n /**\n * Check if a row is a totals table row\n * @param y The row in the model to check if it's a totals table row\n * @returns True if the row is a totals row, false if not\n */\n isTotalsRow(y: ModelIndex): boolean {\n return this.totalsRow(y) != null;\n }\n\n /**\n * Check if a row is a pending input row\n * @param y The row in the model to check if it's a pending new row\n * @returns True if the row is a pending new row, false if not\n */\n isPendingRow(y: ModelIndex): boolean {\n return this.pendingRow(y) != null;\n }\n\n dataForCell(x: ModelIndex, y: ModelIndex): CellData | undefined {\n return this.row(y)?.data.get(x);\n }\n\n formatForCell(x: ModelIndex, y: ModelIndex): Format | undefined {\n return this.dataForCell(x, y)?.format;\n }\n\n valueForCell(x: ModelIndex, y: ModelIndex): unknown {\n const data = this.dataForCell(x, y);\n\n /* JS API current sets null values as undefined in some instances. This means \n we need to nullish coaelesce so all undefined values from the API return null \n since the data has been fetched. undefined is used to indicate the API has not \n fetched data yet */\n if (data) {\n return data.value ?? null;\n }\n return undefined;\n }\n\n copyViewportData(data: ViewportData): void {\n if (data == null) {\n log.warn('invalid data!');\n return;\n }\n\n this.viewportData = this.extractViewportData(data);\n this.formattedStringData = [];\n }\n\n copyTotalsData(totalsData: ViewportData): void {\n if (totalsData == null) {\n log.warn('invalid data!');\n return;\n }\n\n const { columns, rows } = totalsData;\n if (rows.length !== 1) {\n log.error(\n 'Unexpected number of rows received for totals table, ignoring update'\n );\n return;\n }\n\n const dataMap = new Map();\n const row = rows[0];\n const defaultOperation =\n this.totals?.defaultOperation ?? AggregationOperation.SUM;\n const operationMap = this.totals?.operationMap;\n for (let c = 0; c < columns.length; c += 1) {\n const column = columns[c];\n const [\n name,\n operation = operationMap?.[name]?.[0] ?? defaultOperation,\n ] = column.name.split('__');\n if (!dataMap.has(operation)) {\n dataMap.set(operation, { data: new Map() });\n }\n const { data: rowData } = dataMap.get(operation);\n const columnIndex = this.columns.findIndex(col => col.name === name);\n rowData.set(columnIndex, {\n value: row.get(column),\n format: row.getFormat(column),\n });\n }\n\n log.debug2('copyTotalsData', dataMap);\n\n this.totalsDataMap = dataMap;\n this.formattedStringData = [];\n }\n\n /**\n * Use this as the canonical column index since things like layoutHints could have\n * changed the column order.\n */\n getColumnIndexByName(name: ColumnName): number | undefined {\n return this.getColumnIndicesByNameMap(this.columns).get(name);\n }\n\n getColumnIndicesByNameMap = memoize(\n (columns: Column[]): Map<ColumnName, ModelIndex> => {\n const indices = new Map();\n columns.forEach(({ name }, i) => indices.set(name, i));\n return indices;\n }\n );\n\n /**\n * Copies all the viewport data into an object that we can reference later.\n * @param data The data to copy from\n */\n extractViewportData(data: ViewportData): UIViewportData<R> {\n const newData: UIViewportData<R> = {\n offset: data.offset,\n rows: [],\n };\n\n const { columns } = data;\n for (let r = 0; r < data.rows.length; r += 1) {\n const row = data.rows[r];\n const newRow = this.extractViewportRow(row, columns);\n newData.rows.push(newRow);\n }\n\n return newData;\n }\n\n extractViewportRow(row: Row, columns: Column[]): R {\n const data = new Map<ModelIndex, CellData>();\n for (let c = 0; c < columns.length; c += 1) {\n const column = columns[c];\n\n const index = this.getColumnIndexByName(column.name);\n assertNotNull(index);\n data.set(index, {\n value: row.get(column),\n format: row.getFormat(column),\n });\n }\n\n return { data } as R;\n }\n\n closeSubscription(): void {\n log.debug2('closeSubscription', this.subscription);\n if (this.subscription) {\n this.subscription.close();\n this.subscription = null;\n }\n\n this.setViewport.cancel();\n this.applyViewport.cancel();\n }\n\n get filter(): FilterCondition[] {\n return this.table.filter;\n }\n\n set filter(filter: FilterCondition[]) {\n this.closeSubscription();\n this.table.applyFilter(filter);\n this.applyViewport();\n }\n\n get formatter(): Formatter {\n return this.irisFormatter;\n }\n\n set formatter(formatter: Formatter) {\n this.irisFormatter = formatter;\n this.formattedStringData = [];\n this.dispatchEvent(\n new EventShimCustomEvent(IrisGridModel.EVENT.FORMATTER_UPDATED)\n );\n }\n\n displayString(\n value: unknown,\n columnType: string,\n columnName = '',\n formatOverride?: { formatString: string }\n ): string {\n return this.getCachedFormattedString(\n this.formatter,\n value,\n columnType,\n columnName,\n formatOverride\n );\n }\n\n get sort(): Sort[] {\n return this.table.sort;\n }\n\n set sort(sort: Sort[]) {\n this.closeSubscription();\n this.table.applySort(sort);\n this.applyViewport();\n }\n\n set totalsConfig(totalsConfig: UITotalsTableConfig | null) {\n log.debug('set totalsConfig', totalsConfig);\n\n if (totalsConfig === this.totals) {\n // Totals already set, or it will be set when the next model actually gets set\n return;\n }\n\n this.totals = totalsConfig;\n this.formattedStringData = [];\n\n if (this.totalsTablePromise != null) {\n this.totalsTablePromise.cancel();\n }\n\n this.setTotalsTable(null);\n\n if (totalsConfig == null) {\n this.dispatchEvent(new EventShimCustomEvent(IrisGridModel.EVENT.UPDATED));\n return;\n }\n\n this.totalsTablePromise = PromiseUtils.makeCancelable(\n this.table.getTotalsTable(totalsConfig),\n table => table.close()\n );\n this.totalsTablePromise\n .then(totalsTable => {\n this.totalsTablePromise = null;\n this.setTotalsTable(totalsTable);\n })\n .catch(err => {\n if (PromiseUtils.isCanceled(err)) {\n return;\n }\n\n log.error('Unable to set next totalsTable', err);\n this.totalsTablePromise = null;\n\n this.dispatchEvent(\n new EventShimCustomEvent(IrisGridModel.EVENT.REQUEST_FAILED, {\n detail: err,\n })\n );\n });\n }\n\n setTotalsTable(totalsTable: TotalsTable | null): void {\n log.debug('setTotalsTable', totalsTable);\n\n if (this.totalsTable !== null) {\n if (this.listenerCount > 0) {\n this.removeTotalsListeners(this.totalsTable);\n }\n\n this.totalsTable.close();\n }\n\n this.totalsTable = totalsTable;\n this.totalsDataMap = null;\n\n if (this.listenerCount > 0 && this.totalsTable != null) {\n this.addTotalsListeners(this.totalsTable);\n }\n }\n\n setViewport = throttle(\n (top: VisibleIndex, bottom: VisibleIndex, columns: Column[]) => {\n if (bottom < top) {\n log.error('Invalid viewport', top, bottom);\n return;\n }\n\n const { viewport } = this;\n if (\n viewport != null &&\n viewport.top === top &&\n viewport.bottom === bottom &&\n viewport.columns === columns\n ) {\n log.debug2('Ignoring duplicate viewport', viewport);\n return;\n }\n\n this.viewport = {\n top,\n bottom,\n columns,\n };\n log.debug2('setViewport', this.viewport);\n\n this.applyViewport();\n },\n SET_VIEWPORT_THROTTLE\n );\n\n /**\n * Applies the current viewport to the underlying table.\n */\n applyViewport = throttle(\n (): void => {\n if (!this.viewport) {\n return;\n }\n\n log.debug2('applyViewport', this.viewport);\n const { top, bottom, columns } = this.viewport;\n const [viewportTop, viewportBottom] = this.getCachedViewportRowRange(\n top,\n bottom\n );\n this.applyBufferedViewport(viewportTop, viewportBottom, columns);\n },\n APPLY_VIEWPORT_THROTTLE,\n { leading: false }\n );\n\n applyBufferedViewport(\n viewportTop: number,\n viewportBottom: number,\n columns: Column[]\n ): void {\n log.debug2('applyBufferedViewport', viewportTop, viewportBottom, columns);\n if (this.subscription == null) {\n log.debug2('applyBufferedViewport creating new subscription');\n this.subscription = this.table.setViewport(\n viewportTop,\n viewportBottom,\n columns\n );\n } else {\n log.debug2('applyBufferedViewport using existing subscription');\n this.subscription.setViewport(viewportTop, viewportBottom, columns);\n }\n }\n\n async snapshot(\n ranges: GridRange[],\n includeHeaders = false,\n formatValue: (value: unknown, column: Column) => unknown = value => value,\n consolidateRanges = true\n ): Promise<unknown[][]> {\n if (this.subscription == null) {\n throw new Error('No subscription available');\n }\n\n const consolidated = consolidateRanges\n ? GridRange.consolidate(ranges)\n : ranges;\n if (!IrisGridUtils.isValidSnapshotRanges(consolidated)) {\n throw new Error(`Invalid snapshot ranges ${ranges}`);\n }\n\n // Need to separate out the floating ranges as they're from a different source\n const topFloatingRowsSet = new Set<number>();\n const tableRanges: GridRange[] = [];\n const bottomFloatingRowsSet = new Set<number>();\n for (let i = 0; i < consolidated.length; i += 1) {\n const range = consolidated[i];\n assertNotNull(range.endRow);\n assertNotNull(range.startRow);\n // Get the rows that are in the top aggregations section\n for (\n let r = range.startRow;\n r <= range.endRow && r < this.floatingTopRowCount;\n r += 1\n ) {\n topFloatingRowsSet.add(r);\n }\n\n // Separate out the range that is part of the actual table (ie. not the floating ranges, not aggregations)\n if (\n range.endRow >= this.floatingTopRowCount &&\n range.startRow <= this.floatingTopRowCount + this.table.size\n ) {\n tableRanges.push(\n new GridRange(\n range.startColumn,\n Math.min(Math.max(0, range.startRow - this.floatingTopRowCount)),\n range.endColumn,\n Math.min(\n Math.max(0, range.endRow - this.floatingTopRowCount),\n this.table.size - this.floatingTopRowCount\n )\n )\n );\n }\n // Get the rows that are in the bottom aggregations section\n for (\n let r = Math.max(\n range.startRow,\n this.floatingTopRowCount + this.table.size\n );\n r <= range.endRow &&\n r <\n this.floatingTopRowCount +\n this.table.size +\n this.floatingBottomRowCount;\n r += 1\n ) {\n bottomFloatingRowsSet.add(r);\n }\n }\n\n const columns = IrisGridUtils.columnsFromRanges(consolidated, this.columns);\n const result = [];\n if (includeHeaders) {\n result.push(columns.map(c => c.name));\n }\n const topFloatingRows = [...topFloatingRowsSet].sort();\n for (let i = 0; i < topFloatingRows.length; i += 1) {\n const row = topFloatingRows[i];\n const rowData = columns.map(column => {\n const index = this.getColumnIndexByName(column.name);\n assertNotNull(index);\n return formatValue(this.valueForCell(index, row), column);\n });\n if (includeHeaders) {\n rowData.push(this.textForRowFooter(row));\n }\n result.push(rowData);\n }\n\n if (tableRanges.length > 0) {\n const rangeSet = this.irisGridUtils.rangeSetFromRanges(tableRanges);\n const snapshot = await this.subscription.snapshot(rangeSet, columns);\n result.push(\n ...snapshot.rows.map(rowData =>\n columns.map(column => formatValue(rowData.get(column), column))\n )\n );\n }\n\n const bottomFloatingRows = [...bottomFloatingRowsSet].sort();\n for (let i = 0; i < bottomFloatingRows.length; i += 1) {\n const row = bottomFloatingRows[i];\n const rowData = columns.map(column => {\n const index = this.getColumnIndexByName(column.name);\n assertNotNull(index);\n return formatValue(this.valueForCell(index, row), column);\n });\n if (includeHeaders) {\n rowData.push(this.textForRowFooter(row));\n }\n result.push(rowData);\n }\n\n return result;\n }\n\n /**\n * Get a text snapshot of the provided ranges\n * @param ranges The ranges to get the snapshot for\n * @param includeHeaders Whether to include the headers in the snapshot or not\n * @param formatValue Function for formatting the raw value into a string\n * @returns A formatted string of all the data, columns separated by `\\t` and rows separated by `\\n`\n */\n async textSnapshot(\n ranges: GridRange[],\n includeHeaders = false,\n formatValue: (\n value: unknown,\n column: Column,\n row?: Row\n ) => string = value => `${value}`\n ): Promise<string> {\n log.debug2('textSnapshot', ranges, includeHeaders);\n\n const data = await this.snapshot(\n ranges,\n includeHeaders,\n formatValue,\n false\n );\n return data.map(row => row.join('\\t')).join('\\n');\n }\n\n async valuesTable(column: Column): Promise<Table> {\n let table = null;\n try {\n table = await this.table.copy();\n table.applyFilter([]);\n table.applySort([]);\n return table.selectDistinct([column]);\n } finally {\n if (table != null) {\n table.close();\n }\n }\n }\n\n getCachedFormattedString = memoizeClear(\n (\n formatter: Formatter,\n value: unknown,\n columnType: string,\n columnName: ColumnName,\n formatOverride?: { formatString: string }\n ): string =>\n formatter.getFormattedString(\n value,\n columnType,\n columnName,\n formatOverride\n ),\n { max: 10000 }\n );\n\n getCachedCustomColumnFormatFlag = memoizeClear(\n FormatterUtils.isCustomColumnFormatDefined,\n { max: 10000 }\n );\n\n getCachedViewportRowRange = memoize((top: number, bottom: number): [\n number,\n number\n ] => {\n const viewHeight = bottom - top;\n const viewportTop = Math.max(\n 0,\n top - viewHeight * IrisGridTableModelTemplate.ROW_BUFFER_PAGES\n );\n const viewportBottom =\n bottom + viewHeight * IrisGridTableModelTemplate.ROW_BUFFER_PAGES;\n return [viewportTop, viewportBottom];\n });\n\n getCachedPendingErrors = memoize(\n (\n pendingDataMap: PendingDataMap,\n columns: Column[],\n keyColumnCount: number\n ) => {\n const map = new Map<ModelIndex, MissingKeyError[]>();\n pendingDataMap.forEach((row, rowIndex) => {\n const { data: rowData } = row;\n for (let i = 0; i < keyColumnCount; i += 1) {\n if (!rowData.has(i)) {\n if (!map.has(rowIndex)) {\n map.set(rowIndex, []);\n }\n map\n .get(rowIndex)\n ?.push(new MissingKeyError(rowIndex, columns[i].name));\n }\n }\n });\n return map;\n }\n );\n\n isColumnMovable(modelIndex: ModelIndex, depth: number): boolean {\n if (modelIndex < 0 || modelIndex >= this.columnCount) {\n return false;\n }\n\n // All groups are movable\n if (depth > 0) {\n return true;\n }\n\n const columnName = this.columns[modelIndex].name;\n if (\n this.frontColumns.includes(columnName) ||\n this.backColumns.includes(columnName) ||\n this.frozenColumns.includes(columnName) ||\n !columnName\n ) {\n return false;\n }\n return !this.isKeyColumn(modelIndex);\n }\n\n isKeyColumn(x: ModelIndex): boolean {\n return x < (this.inputTable?.keyColumns.length ?? 0);\n }\n\n isRowMovable(): boolean {\n return false;\n }\n\n isEditableRange(range: GridRange): boolean {\n // Make sure we have an input table and a valid range\n if (this.inputTable == null || !GridRange.isBounded(range)) {\n return false;\n }\n\n // Check that the edit is in the editable range\n // If an input table has keyed columns, the non-key columns are always editable\n // If an input table does not have key columns, it is append only and existing rows cannot be editable\n // Pending rows are always editable\n const isPendingRange =\n this.isPendingRow(range.startRow) && this.isPendingRow(range.endRow);\n if (\n !(\n isPendingRange ||\n (this.inputTable.keyColumns.length !== 0 &&\n range.startColumn >= this.inputTable.keyColumns.length &&\n range.endColumn >= this.inputTable.keyColumns.length)\n )\n ) {\n return false;\n }\n\n // Editing the aggregations/totals which are floating above/below is not allowed\n if (\n range.startRow < this.floatingTopRowCount ||\n range.startRow >=\n this.floatingTopRowCount + this.table.size + this.pendingRowCount ||\n range.endRow >=\n this.floatingTopRowCount + this.table.size + this.pendingRowCount\n ) {\n return false;\n }\n\n return true;\n }\n\n isDeletableRange(range: GridRange): boolean {\n return (\n this.inputTable != null &&\n range.startRow != null &&\n range.endRow != null &&\n range.startRow >= this.floatingTopRowCount &&\n range.startRow <\n this.floatingTopRowCount + this.table.size + this.pendingRowCount &&\n range.endRow <\n this.floatingTopRowCount + this.table.size + this.pendingRowCount\n );\n }\n\n isEditableRanges(ranges: GridRange[]): boolean {\n return ranges.every(range => this.isEditableRange(range));\n }\n\n isDeletableRanges(ranges: GridRange[]): boolean {\n return ranges.every(range => this.isDeletableRange(range));\n }\n\n /**\n * @returns A range corresponding to the underlying table\n */\n getTableAreaRange(): GridRange {\n return new GridRange(\n null,\n this.floatingTopRowCount,\n null,\n this.floatingTopRowCount + this.table.size - 1\n );\n }\n\n /**\n * @returns A range corresponding to the pending new rows\n */\n getPendingAreaRange(): GridRange {\n return new GridRange(\n null,\n this.floatingTopRowCount + this.table.size,\n null,\n this.floatingTopRowCount + this.table.size + this.pendingNewRowCount - 1\n );\n }\n\n /**\n * Set value in an editable table\n * @param x The column to set\n * @param y The row to set\n * @param value The value to set\n * @returns A promise that resolves successfully when the operation is complete, or rejects if there's an error\n */\n async setValueForCell(\n x: ModelIndex,\n y: ModelIndex,\n text: string\n ): Promise<void> {\n // Cache the value in our pending string cache so that it stays displayed until our edit has been completed\n return this.setValueForRanges([new GridRange(x, y, x, y)], text);\n }\n\n /**\n * Set value in an editable table\n * @param ranges The ranges to set\n * @param value The values to set\n * @returns A promise that resolves successfully when the operation is complete, or rejects if there's an error\n */\n async setValueForRanges(ranges: GridRange[], text: string): Promise<void> {\n if (!this.isEditableRanges(ranges)) {\n throw new Error(`Uneditable ranges ${ranges}`);\n }\n\n try {\n // Cache the value in our pending string cache so that it stays displayed until our edit has been completed\n const columnSet = new Set<Column>();\n\n // Formatted text for each column\n // Since there could be different formatting for each column, but the value will be the same across rows\n const formattedText: (string | null)[] = [];\n GridRange.forEachCell(ranges, (x, y) => {\n const column = this.columns[x];\n columnSet.add(column);\n if (formattedText[x] === undefined) {\n const value = this.tableUtils.makeValue(\n column.type,\n text,\n this.formatter.timeZone\n );\n formattedText[x] =\n value != null\n ? this.displayString(value, column.type, column.name)\n : null;\n }\n this.cachePendingValue(x, y, formattedText[x]);\n });\n\n // Take care of updates to the pending new area first, as they can be updated synchronously\n const pendingAreaRange = this.getPendingAreaRange();\n const pendingRanges = ranges\n .map(range => GridRange.intersection(pendingAreaRange, range))\n .filter(range => range != null)\n .map(range => {\n assertNotNull(range);\n return GridRange.offset(\n range,\n 0,\n -(this.floatingTopRowCount + this.table.size)\n );\n });\n if (pendingRanges.length > 0) {\n const newDataMap = new Map(this.pendingNewDataMap);\n GridRange.forEachCell(pendingRanges, (columnIndex, rowIndex) => {\n if (!newDataMap.has(rowIndex)) {\n newDataMap.set(rowIndex, { data: new Map() } as R);\n }\n const column = this.columns[columnIndex];\n const row = newDataMap.get(rowIndex);\n assertNotNull(row);\n const { data: rowData } = row;\n const newRowData = new Map(rowData);\n const value = this.tableUtils.makeValue(\n column.type,\n text,\n this.formatter.timeZone\n );\n if (value != null) {\n newRowData.set(columnIndex, { value });\n } else {\n newRowData.delete(columnIndex);\n }\n if (newRowData.size > 0) {\n newDataMap.set(rowIndex, { ...row, data: newRowData });\n } else {\n newDataMap.delete(rowIndex);\n }\n });\n this.pendingDataMap = newDataMap;\n }\n\n this.dispatchEvent(new EventShimCustomEvent(IrisGridModel.EVENT.UPDATED));\n\n const tableAreaRange = this.getTableAreaRange();\n const tableRanges = ranges\n .map(range => GridRange.intersection(tableAreaRange, range))\n .filter(range => range != null);\n if (tableRanges.length > 0) {\n // Get a snapshot of the full rows, as we need to write a full row when editing\n const data = await this.snapshot(\n tableRanges.map(\n range =>\n new GridRange(\n null,\n range?.startRow ?? null,\n null,\n range?.endRow ?? null\n )\n )\n );\n const newRows = data.map(row => {\n const newRow: Record<ColumnName, unknown> = {};\n for (let c = 0; c < this.columns.length; c += 1) {\n newRow[this.columns[c].name] = row[c];\n }\n\n columnSet.forEach(column => {\n newRow[column.name] = this.tableUtils.makeValue(\n column.type,\n text,\n this.formatter.timeZone\n );\n });\n return newRow;\n });\n\n const result = await this.inputTable?.addRows(newRows);\n\n log.debug(\n 'setValueForRanges(',\n ranges,\n ',',\n text,\n ') set tableRanges',\n tableRanges,\n 'result',\n result\n );\n }\n\n // Add the changes to the formatted cache so it's still displayed until the update event is received\n // The update event could be received on the next tick, after the input rows have been committed,\n // so make sure we don't display stale data\n GridRange.forEachCell(ranges, (x, y) => {\n const cellText = formattedText[x];\n assertNotNull(cellText);\n this.cacheFormattedValue(x, y, cellText);\n });\n } catch (err) {\n log.error('Unable to set ranges', ranges, text, err);\n } finally {\n GridRange.forEachCell(ranges, (x, y) => {\n this.clearPendingValue(x, y);\n });\n }\n }\n\n async setValues(edits: EditOperation[] = []): Promise<void> {\n log.debug('setValues(', edits, ')');\n if (\n !edits.every(edit =>\n this.isEditableRange(\n GridRange.makeCell(edit.column ?? edit.x, edit.row ?? edit.y)\n )\n )\n ) {\n throw new Error(`Uneditable ranges ${edits}`);\n }\n\n try {\n const newDataMap = new Map(this.pendingNewDataMap);\n\n // Cache the display values\n edits.forEach(edit => {\n const { text } = edit;\n const x = edit.column ?? edit.x;\n const y = edit.row ?? edit.y;\n const column = this.columns[x];\n const value = this.tableUtils.makeValue(\n column.type,\n text,\n this.formatter.timeZone\n );\n const formattedText =\n value != null\n ? this.displayString(value, column.type, column.name)\n : null;\n this.cachePendingValue(x, y, formattedText);\n\n // Take care of updates to the pending new area as well, as that can be updated synchronously\n const pendingRow = this.pendingRow(y);\n if (pendingRow != null) {\n if (!newDataMap.has(pendingRow)) {\n newDataMap.set(pendingRow, { data: new Map() } as R);\n }\n\n const row = newDataMap.get(pendingRow);\n assertNotNull(row);\n const { data: rowData } = row;\n const newRowData = new Map(rowData);\n if (value != null) {\n newRowData.set(x, { value });\n } else {\n newRowData.delete(x);\n }\n if (newRowData.size > 0) {\n newDataMap.set(pendingRow, { ...row, data: newRowData });\n } else {\n newDataMap.delete(pendingRow);\n }\n }\n });\n\n this.pendingDataMap = newDataMap;\n\n // Send an update right after setting the pending map so the values are displayed immediately\n this.dispatchEvent(new EventShimCustomEvent(IrisGridModel.EVENT.UPDATED));\n\n // Need to group by row...\n const rowEditMap = edits.reduce((rowMap, edit) => {\n const y = edit.row ?? edit.y;\n if (!rowMap.has(y)) {\n rowMap.set(y, []);\n }\n rowMap.get(y)?.push(edit);\n return rowMap;\n }, new Map<ModelIndex, EditOperation[]>());\n\n const ranges = GridRange.consolidate(\n edits.map(edit =>\n GridRange.makeCell(edit.column ?? edit.x, edit.row ?? edit.y)\n )\n );\n const tableAreaRange = this.getTableAreaRange();\n const tableRanges = ranges\n .map(range => GridRange.intersection(tableAreaRange, range))\n .filter(range => range != null);\n\n if (tableRanges.length > 0) {\n // Get a snapshot of the full rows, as we need to write a full row when editing\n const data = await this.snapshot(\n tableRanges.map(range => {\n assertNotNull(range);\n return new GridRange(null, range.startRow, null, range.endRow);\n })\n );\n const newRows = data.map((row, dataIndex) => {\n let rowIndex = null;\n let r = dataIndex;\n for (let i = 0; i < tableRanges.length; i += 1) {\n const range = tableRanges[i];\n assertNotNull(range);\n const rangeRowCount = GridRange.rowCount([range]);\n if (r < rangeRowCount) {\n assertNotNull(range.startRow);\n rowIndex = range.startRow + r;\n break;\n }\n r -= rangeRowCount;\n }\n\n const newRow: Record<ColumnName, unknown> = {};\n for (let c = 0; c < this.columns.length; c += 1) {\n newRow[this.columns[c].name] = row[c];\n }\n assertNotNull(rowIndex);\n const rowEdits = rowEditMap.get(rowIndex);\n if (rowEdits != null) {\n rowEdits.forEach(edit => {\n const column = this.columns[edit.column ?? edit.x];\n newRow[column.name] = this.tableUtils.makeValue(\n column.type,\n edit.text,\n this.formatter.timeZone\n );\n });\n }\n return newRow;\n });\n\n log.info('setValues setting tableRanges', tableRanges);\n\n const result = await this.inputTable?.addRows(newRows);\n\n log.info('setValues set tableRanges', tableRanges, 'SUCCESS', result);\n }\n\n // We've sent the changes to the server, but have not yet got an update with those changes committed\n // Add the changes to the formatted cache so it's still displayed until the update event is received\n // The update event could be received on the next tick, after the input rows have been committed,\n // so make sure we don't display stale data\n edits.forEach(edit => {\n const { text } = edit;\n const x = edit.column ?? edit.x;\n const y = edit.row ?? edit.y;\n const column = this.columns[x];\n const value = this.tableUtils.makeValue(\n column.type,\n text,\n this.formatter.timeZone\n );\n const formattedText =\n value != null\n ? this.displayString(value, column.type, column.name)\n : null;\n\n this.cacheFormattedValue(x, y, formattedText);\n });\n } finally {\n edits.forEach(edit => {\n this.clearPendingValue(edit.column, edit.row);\n });\n }\n }\n\n async commitPending(): Promise<void> {\n if (this.pendingNewDataMap.size <= 0) {\n throw new Error('No pending changes to commit');\n }\n\n try {\n this.isSaveInProgress = true;\n\n const newRows: Record<ColumnName, unknown>[] = [];\n this.pendingNewDataMap.forEach(row => {\n const newRow: Record<ColumnName, unknown> = {};\n row.data.forEach(({ value }, columnIndex) => {\n const column = this.columns[columnIndex];\n newRow[column.name] = value;\n });\n newRows.push(newRow);\n });\n const result = await this.inputTable?.addRows(newRows);\n\n log.debug('commitPending()', this.pendingNewDataMap, 'result', result);\n\n this.pendingNewDataMap = new Map();\n this.pendingNewRowCount = Math.max(\n 0,\n (this.viewport?.bottom ?? 0) - this.table.size\n );\n this.formattedStringData = [];\n\n this.dispatchEvent(\n new EventShimCustomEvent(IrisGridModel.EVENT.PENDING_DATA_UPDATED)\n );\n } finally {\n this.isSaveInProgress = false;\n }\n }\n\n editValueForCell(x: ModelIndex, y: ModelIndex): string | null {\n return this.textValueForCell(x, y);\n }\n\n async delete(ranges: GridRange[]): Promise<void> {\n if (!this.isDeletableRanges(ranges)) {\n throw new Error(`Undeletable ranges ${ranges}`);\n }\n\n assertNotNull(this.inputTable);\n const { keyColumns } = this.inputTable;\n if (keyColumns.length === 0) {\n throw new Error('No key columns to allow deletion');\n }\n\n const pendingAreaRange = this.getPendingAreaRange();\n const pendingRanges = ranges\n .map(range => GridRange.intersection(pendingAreaRange, range))\n .filter(range => range != null)\n .map(range => {\n assertNotNull(range);\n\n return GridRange.offset(\n range,\n 0,\n -(this.floatingTopRowCount + this.table.size)\n );\n });\n\n if (pendingRanges.length > 0) {\n const newDataMap = new Map(this.pendingNewDataMap);\n for (let i = 0; i < pendingRanges.length; i += 1) {\n const pendingRange = pendingRanges[i];\n assertNotNull(pendingRange.startRow);\n assertNotNull(pendingRange.endRow);\n for (let r = pendingRange.startRow; r <= pendingRange.endRow; r += 1) {\n newDataMap.delete(r);\n }\n }\n this.pendingNewDataMap = newDataMap;\n\n this.formattedStringData = [];\n\n this.dispatchEvent(\n new EventShimCustomEvent(IrisGridModel.EVENT.PENDING_DATA_UPDATED)\n );\n\n this.dispatchEvent(new EventShimCustomEvent(IrisGridModel.EVENT.UPDATED));\n }\n\n const tableAreaRange = this.getTableAreaRange();\n const tableRanges = ranges\n .map(range => GridRange.intersection(tableAreaRange, range))\n .filter(range => range != null);\n if (tableRanges.length <= 0) {\n return;\n }\n const [data, deleteTable] = await Promise.all([\n // Need to get the key values of each row\n this.snapshot(\n tableRanges.map(range => {\n assertNotNull(range);\n return new GridRange(\n 0,\n range.startRow,\n keyColumns.length - 1,\n range.endRow\n );\n })\n ),\n this.table.copy(),\n ]);\n\n // Now copy the existing table and filter it on the values in the snapshot for the key columns in the input table\n const filters = data.map(row => {\n const columnFilters = [];\n for (let c = 0; c < keyColumns.length; c += 1) {\n const column = keyColumns[c];\n const value = row[c];\n const filterValue = this.tableUtils.makeFilterRawValue(\n column.type,\n value\n );\n const filter = column.filter().eq(filterValue);\n columnFilters.push(filter);\n }\n return columnFilters.reduce((agg, curr) => agg?.and(curr) ?? curr);\n });\n\n const filter = filters.reduce((agg, curr) => agg?.or(curr) ?? curr);\n deleteTable.applyFilter([filter]);\n\n // await this.inputTable?.deleteTable(deleteTable);\n deleteTable.close();\n }\n\n isValidForCell(x: ModelIndex, y: ModelIndex, value: string): boolean {\n try {\n const column = this.columns[x];\n this.tableUtils.makeValue(column.type, value, this.formatter.timeZone);\n return true;\n } catch (e) {\n return false;\n }\n }\n}\n\nexport default IrisGridTableModelTemplate;\n","/* eslint class-methods-use-this: \"off\" */\nimport memoize from 'memoize-one';\nimport { GridRange, ModelIndex } from '@deephaven/grid';\nimport type {\n Column,\n ColumnStatistics,\n CustomColumn,\n dh as DhType,\n InputTable,\n LayoutHints,\n Table,\n ValueTypeUnion,\n} from '@deephaven/jsapi-types';\nimport Log from '@deephaven/log';\nimport { Formatter } from '@deephaven/jsapi-utils';\nimport {\n EventShimCustomEvent,\n PromiseUtils,\n assertNotNull,\n} from '@deephaven/utils';\nimport IrisGridModel from './IrisGridModel';\nimport { ColumnName, UITotalsTableConfig, UIRow } from './CommonTypes';\nimport IrisGridTableModelTemplate from './IrisGridTableModelTemplate';\n\nconst log = Log.module('IrisGridTableModel');\n\n/**\n * Model for a grid showing an iris data table\n */\n\nclass IrisGridTableModel extends IrisGridTableModelTemplate<Table, UIRow> {\n userFrozenColumns?: ColumnName[];\n\n customColumnList: string[];\n\n formatColumnList: CustomColumn[];\n\n /**\n * @param dh JSAPI instance\n * @param table Iris data table to be used in the model\n * @param formatter The formatter to use when getting formats\n * @param inputTable Iris input table associated with this table\n */\n constructor(\n dh: DhType,\n table: Table,\n formatter = new Formatter(dh),\n inputTable: InputTable | null = null\n ) {\n super(dh, table, formatter, inputTable);\n this.customColumnList = [];\n this.formatColumnList = [];\n }\n\n get isExportAvailable(): boolean {\n return this.table.freeze != null;\n }\n\n get isColumnStatisticsAvailable(): boolean {\n return this.table.getColumnStatistics != null;\n }\n\n get isValuesTableAvailable(): boolean {\n return this.table.selectDistinct != null && this.table.copy != null;\n }\n\n get isRollupAvailable(): boolean {\n return this.table.rollup != null;\n }\n\n get isSelectDistinctAvailable(): boolean {\n return this.table.selectDistinct != null;\n }\n\n get isCustomColumnsAvailable(): boolean {\n return this.table.applyCustomColumns != null;\n }\n\n get isFormatColumnsAvailable(): boolean {\n return this.table.applyCustomColumns != null;\n }\n\n getMemoizedFrontColumns = memoize(\n (layoutHintsFrontColumns: ColumnName[] | undefined) =>\n layoutHintsFrontColumns ?? []\n );\n\n get frontColumns(): ColumnName[] {\n return this.getMemoizedFrontColumns(this.layoutHints?.frontColumns);\n }\n\n getMemoizedBackColumns = memoize(\n (layoutHintsBackColumns: ColumnName[] | undefined) =>\n layoutHintsBackColumns ?? []\n );\n\n get backColumns(): ColumnName[] {\n return this.getMemoizedBackColumns(this.layoutHints?.backColumns);\n }\n\n getMemoizedFrozenColumns = memoize(\n (\n layoutHintsFrozenColumns?: ColumnName[],\n userFrozenColumns?: ColumnName[]\n ): ColumnName[] => userFrozenColumns ?? layoutHintsFrozenColumns ?? []\n );\n\n get frozenColumns(): ColumnName[] {\n return this.getMemoizedFrozenColumns(\n this.layoutHints?.frozenColumns,\n this.userFrozenColumns\n );\n }\n\n get layoutHints(): LayoutHints {\n return this.table.layoutHints;\n }\n\n get floatingLeftColumnCount(): number {\n return this.frozenColumns.length;\n }\n\n get description(): string {\n return this.table.description;\n }\n\n get customColumns(): ColumnName[] {\n return this.customColumnList;\n }\n\n set customColumns(customColumns: ColumnName[]) {\n log.debug2(\n 'set customColumns',\n customColumns,\n this.customColumnList,\n customColumns === this.customColumnList\n );\n if (this.customColumnList.length === 0 && customColumns.length === 0) {\n log.debug('Ignore empty initial customColumns');\n this.customColumnList = customColumns;\n return;\n }\n if (this.customColumnList === customColumns) {\n log.debug('Ignore same customColumns');\n return;\n }\n this.closeSubscription();\n this.customColumnList = customColumns;\n this.table.applyCustomColumns([...customColumns, ...this.formatColumns]);\n this.applyViewport();\n }\n\n get formatColumns(): CustomColumn[] {\n return this.formatColumnList;\n }\n\n set formatColumns(formatColumns: CustomColumn[]) {\n log.debug2(\n 'set formatColumns',\n formatColumns,\n this.formatColumnList,\n formatColumns === this.formatColumnList\n );\n if (this.formatColumnList.length === 0 && formatColumns.length === 0) {\n log.debug('Ignore empty initial formatColumns');\n this.formatColumnList = formatColumns;\n return;\n }\n if (this.formatColumnList === formatColumns) {\n log.debug('Ignore same formatColumns');\n return;\n }\n this.closeSubscription();\n this.formatColumnList = formatColumns;\n this.table.applyCustomColumns([...this.customColumns, ...formatColumns]);\n this.applyViewport();\n }\n\n updateFrozenColumns(columns: ColumnName[]): void {\n this.userFrozenColumns = columns;\n this.dispatchEvent(\n new EventShimCustomEvent(IrisGridModel.EVENT.TABLE_CHANGED, {\n detail: this.table,\n })\n );\n }\n\n set totalsConfig(totalsConfig: UITotalsTableConfig | null) {\n log.debug('set totalsConfig', totalsConfig);\n\n if (totalsConfig === this.totals) {\n // Totals already set, or it will be set when the next model actually gets set\n return;\n }\n\n this.totals = totalsConfig;\n this.formattedStringData = [];\n\n if (this.totalsTablePromise != null) {\n this.totalsTablePromise.cancel();\n }\n\n this.setTotalsTable(null);\n\n if (totalsConfig == null) {\n this.dispatchEvent(new EventShimCustomEvent(IrisGridModel.EVENT.UPDATED));\n return;\n }\n\n this.totalsTablePromise = PromiseUtils.makeCancelable(\n this.table.getTotalsTable(totalsConfig),\n table => table.close()\n );\n this.totalsTablePromise\n .then(totalsTable => {\n this.totalsTablePromise = null;\n this.setTotalsTable(totalsTable);\n })\n .catch(err => {\n if (PromiseUtils.isCanceled(err)) {\n return;\n }\n\n log.error('Unable to set next totalsTable', err);\n this.totalsTablePromise = null;\n\n this.dispatchEvent(\n new EventShimCustomEvent(IrisGridModel.EVENT.REQUEST_FAILED, {\n detail: err,\n })\n );\n });\n }\n\n get isFilterRequired(): boolean {\n return this.table.isUncoalesced;\n }\n\n isFilterable(columnIndex: ModelIndex): boolean {\n return this.getCachedFilterableColumnSet(this.columns).has(columnIndex);\n }\n\n async export(): Promise<Table> {\n return this.table.freeze();\n }\n\n columnStatistics(column: Column): Promise<ColumnStatistics> {\n return this.table.getColumnStatistics(column);\n }\n\n getCachedFilterableColumnSet = memoize(\n (columns: Column[]) =>\n new Set(columns.map((_: Column, index: ModelIndex) => index))\n );\n\n isColumnMovable(modelIndex: ModelIndex): boolean {\n const columnName = this.columns[modelIndex].name;\n if (\n this.frontColumns.includes(columnName) ||\n this.backColumns.includes(columnName) ||\n this.frozenColumns.includes(columnName)\n ) {\n return false;\n }\n return !this.isKeyColumn(modelIndex);\n }\n\n isColumnFrozen(modelIndex: ModelIndex): boolean {\n return this.frozenColumns.includes(this.columns[modelIndex].name);\n }\n\n async delete(ranges: GridRange[]): Promise<void> {\n if (!this.isDeletableRanges(ranges)) {\n throw new Error(`Undeletable ranges ${ranges}`);\n }\n\n assertNotNull(this.inputTable);\n const { keyColumns } = this.inputTable;\n if (keyColumns.length === 0) {\n throw new Error('No key columns to allow deletion');\n }\n\n const pendingAreaRange = this.getPendingAreaRange();\n const pendingRanges = ranges\n .map(range => GridRange.intersection(pendingAreaRange, range))\n .filter(range => range != null)\n .map(range => {\n assertNotNull(range);\n\n return GridRange.offset(\n range,\n 0,\n -(this.floatingTopRowCount + this.table.size)\n );\n });\n\n if (pendingRanges.length > 0) {\n const newDataMap = new Map(super.pendingDataMap);\n for (let i = 0; i < pendingRanges.length; i += 1) {\n const pendingRange = pendingRanges[i];\n assertNotNull(pendingRange.startRow);\n assertNotNull(pendingRange.endRow);\n for (let r = pendingRange.startRow; r <= pendingRange.endRow; r += 1) {\n newDataMap.delete(r);\n }\n }\n super.pendingDataMap = newDataMap;\n\n this.formattedStringData = [];\n\n this.dispatchEvent(\n new EventShimCustomEvent(IrisGridModel.EVENT.PENDING_DATA_UPDATED)\n );\n\n this.dispatchEvent(new EventShimCustomEvent(IrisGridModel.EVENT.UPDATED));\n }\n\n const tableAreaRange = this.getTableAreaRange();\n const tableRanges = ranges\n .map(range => GridRange.intersection(tableAreaRange, range))\n .filter(range => range != null);\n if (tableRanges.length <= 0) {\n return;\n }\n const [data, deleteTable] = await Promise.all([\n // Need to get the key values of each row\n this.snapshot(\n tableRanges.map(range => {\n assertNotNull(range);\n return new GridRange(\n 0,\n range.startRow,\n keyColumns.length - 1,\n range.endRow\n );\n })\n ),\n this.table.copy(),\n ]);\n\n // Now copy the existing table and filter it on the values in the snapshot for the key columns in the input table\n const filters = data.map(row => {\n const columnFilters = [];\n for (let c = 0; c < keyColumns.length; c += 1) {\n const column = keyColumns[c];\n const value = row[c];\n const filterValue = this.tableUtils.makeFilterRawValue(\n column.type,\n value\n );\n const filter = column.filter().eq(filterValue);\n columnFilters.push(filter);\n }\n return columnFilters.reduce((agg, curr) => agg?.and(curr) ?? curr);\n });\n\n const filter = filters.reduce((agg, curr) => agg?.or(curr) ?? curr);\n\n deleteTable.applyFilter([filter]);\n\n await this.inputTable?.deleteTable(deleteTable);\n deleteTable.close();\n }\n\n async seekRow(\n startRow: number,\n column: Column,\n valueType: ValueTypeUnion,\n value: unknown,\n insensitive?: boolean,\n contains?: boolean,\n isBackwards?: boolean\n ): Promise<number> {\n return this.table.seekRow(\n startRow,\n column,\n valueType,\n value,\n insensitive,\n contains,\n isBackwards\n );\n }\n\n get isSeekRowAvailable(): boolean {\n return this.table.seekRow != null;\n }\n}\n\nexport default IrisGridTableModel;\n","/* eslint class-methods-use-this: \"off\" */\nimport memoize from 'memoize-one';\nimport { GridRange, ModelIndex } from '@deephaven/grid';\nimport type { Column, TreeRow, TreeTable } from '@deephaven/jsapi-types';\nimport { assertNotNull } from '@deephaven/utils';\nimport { UIRow, ColumnName } from './CommonTypes';\nimport IrisGridTableModelTemplate from './IrisGridTableModelTemplate';\n\nexport interface UITreeRow extends UIRow {\n isExpanded: boolean;\n hasChildren: boolean;\n depth: number;\n}\nclass IrisGridTreeTableModel extends IrisGridTableModelTemplate<\n TreeTable,\n UITreeRow\n> {\n // table: TreeTable\n\n applyBufferedViewport(\n viewportTop: number,\n viewportBottom: number,\n columns: Column[]\n ): void {\n this.table.setViewport(viewportTop, viewportBottom, columns);\n }\n\n textForCell(x: ModelIndex, y: ModelIndex): string {\n const column = this.columns[x];\n const row = this.row(y);\n if (row != null && column != null) {\n if (!row.hasChildren && column.constituentType != null) {\n const value = this.valueForCell(x, y);\n return this.displayString(value, column.constituentType, column.name);\n }\n }\n\n return super.textForCell(x, y);\n }\n\n extractViewportRow(row: TreeRow, columns: Column[]): UITreeRow {\n const { isExpanded, hasChildren, depth } = row;\n return {\n ...super.extractViewportRow(row, columns),\n isExpanded,\n hasChildren,\n depth,\n };\n }\n\n async snapshot(\n ranges: GridRange[],\n includeHeaders?: boolean,\n formatValue?: (value: unknown, column: Column) => unknown\n ): Promise<unknown[][]> {\n assertNotNull(this.viewport);\n assertNotNull(this.viewportData);\n const { columns } = this.viewport;\n const result = [];\n\n if (includeHeaders != null && includeHeaders) {\n result.push(columns.map(c => c.name));\n }\n\n const viewportRange = new GridRange(\n 0,\n this.viewportData?.offset,\n columns.length,\n this.viewportData.offset + this.viewportData.rows.length\n );\n\n for (let i = 0; i < ranges.length; i += 1) {\n const intersection = GridRange.intersection(viewportRange, ranges[i]);\n\n assertNotNull(intersection);\n assertNotNull(intersection.startRow);\n assertNotNull(intersection.endRow);\n\n for (let r = intersection.startRow; r <= intersection.endRow; r += 1) {\n const resultRow = [];\n const viewportRow = this.viewportData.rows[\n r - this.viewportData.offset\n ];\n assertNotNull(intersection.startColumn);\n assertNotNull(intersection.endColumn);\n for (\n let c = intersection.startColumn;\n c <= intersection.endColumn;\n c += 1\n ) {\n assertNotNull(formatValue);\n resultRow.push(\n formatValue(viewportRow.data.get(c)?.value, this.columns[c])\n );\n }\n result.push(resultRow);\n }\n }\n\n return result;\n }\n\n get groupedColumns(): Column[] {\n return this.table.groupedColumns;\n }\n\n get hasExpandableRows(): boolean {\n return true;\n }\n\n get isExpandAllAvailable(): boolean {\n return this.table.expandAll !== undefined;\n }\n\n get isChartBuilderAvailable(): boolean {\n return false;\n }\n\n get isSelectDistinctAvailable(): boolean {\n return false;\n }\n\n get isReversible(): boolean {\n return false;\n }\n\n isFilterable(columnIndex: ModelIndex): boolean {\n return this.getCachedFilterableColumnSet(\n this.columns,\n this.groupedColumns\n ).has(columnIndex);\n }\n\n isColumnMovable(column: ModelIndex): boolean {\n return column >= this.groupedColumns.length;\n }\n\n isRowExpandable(y: ModelIndex): boolean {\n const row = this.row(y);\n return row?.hasChildren ?? false;\n }\n\n isRowExpanded(y: ModelIndex): boolean {\n const row = this.row(y);\n return row?.isExpanded ?? false;\n }\n\n setRowExpanded(\n y: ModelIndex,\n isExpanded: boolean,\n expandDescendants = false\n ): void {\n if (this.isExpandAllAvailable) {\n this.table.setExpanded(y, isExpanded, expandDescendants);\n } else {\n this.table.setExpanded(y, isExpanded);\n }\n }\n\n expandAll(): void {\n if (this.table.expandAll) {\n this.table.expandAll();\n }\n }\n\n collapseAll(): void {\n if (this.table.collapseAll) {\n this.table.collapseAll();\n }\n }\n\n depthForRow(y: ModelIndex): ModelIndex {\n const row = this.row(y);\n return (row?.depth ?? 1) - 1;\n }\n\n getCachedFilterableColumnSet = memoize(\n (columns: Column[], groupedColumns: Column[]) =>\n new Set(\n (groupedColumns?.length > 0 ? groupedColumns : columns).map(c1 =>\n columns.findIndex(c2 => c1.name === c2.name)\n )\n )\n );\n\n updateFrozenColumns(columns: ColumnName[]): void {\n if (columns.length > 0) {\n throw new Error('Cannot freeze columns on a tree table');\n }\n }\n}\n\nexport default IrisGridTreeTableModel;\n","/* eslint class-methods-use-this: \"off\" */\nimport deepEqual from 'deep-equal';\nimport { Formatter, TableUtils } from '@deephaven/jsapi-utils';\nimport Log from '@deephaven/log';\nimport {\n CancelablePromise,\n EventShimCustomEvent,\n PromiseUtils,\n} from '@deephaven/utils';\nimport type {\n Column,\n ColumnStatistics,\n CustomColumn,\n dh as DhType,\n FilterCondition,\n InputTable,\n LayoutHints,\n RollupConfig,\n Sort,\n Table,\n TreeTable,\n ValueTypeUnion,\n} from '@deephaven/jsapi-types';\nimport {\n EditableGridModel,\n isEditableGridModel,\n isExpandableGridModel,\n ModelIndex,\n MoveOperation,\n} from '@deephaven/grid';\nimport IrisGridTableModel from './IrisGridTableModel';\nimport IrisGridTreeTableModel from './IrisGridTreeTableModel';\nimport IrisGridModel from './IrisGridModel';\nimport {\n ColumnName,\n UITotalsTableConfig,\n PendingDataMap,\n UIRow,\n PendingDataErrorMap,\n} from './CommonTypes';\nimport { isIrisGridTableModelTemplate } from './IrisGridTableModelTemplate';\nimport type ColumnHeaderGroup from './ColumnHeaderGroup';\n\nconst log = Log.module('IrisGridProxyModel');\n\nfunction makeModel(\n dh: DhType,\n table: Table | TreeTable,\n formatter?: Formatter,\n inputTable?: InputTable | null\n): IrisGridModel {\n if (TableUtils.isTreeTable(table)) {\n return new IrisGridTreeTableModel(dh, table, formatter);\n }\n return new IrisGridTableModel(dh, table, formatter, inputTable);\n}\n\n/**\n * Model which proxies calls to other IrisGridModels.\n * This allows for operations that generate new tables, like rollups.\n */\nclass IrisGridProxyModel extends IrisGridModel {\n /**\n * @param dh JSAPI instance\n * @param table Iris data table to be used in the model\n * @param formatter The formatter to use when getting formats\n * @param inputTable Iris input table associated with this table\n */\n\n dh: DhType;\n\n originalModel: IrisGridModel;\n\n model: IrisGridModel;\n\n modelPromise: CancelablePromise<IrisGridModel> | null;\n\n rollup: RollupConfig | null;\n\n selectDistinct: ColumnName[];\n\n constructor(\n dh: DhType,\n table: Table | TreeTable,\n formatter = new Formatter(dh),\n inputTable: InputTable | null = null\n ) {\n super(dh);\n\n this.handleModelEvent = this.handleModelEvent.bind(this);\n\n const model = makeModel(dh, table, formatter, inputTable);\n this.dh = dh;\n this.originalModel = model;\n this.model = model;\n this.modelPromise = null;\n this.rollup = null;\n this.selectDistinct = [];\n }\n\n close(): void {\n this.originalModel.close();\n if (this.model !== this.originalModel) {\n this.model.close();\n }\n if (this.modelPromise != null) {\n this.modelPromise.cancel();\n }\n }\n\n handleModelEvent(event: CustomEvent): void {\n log.debug2('handleModelEvent', event);\n\n const { detail, type } = event;\n this.dispatchEvent(new EventShimCustomEvent(type, { detail }));\n }\n\n setModel(model: IrisGridModel): void {\n log.debug('setModel', model);\n\n const oldModel = this.model;\n\n if (oldModel !== this.originalModel) {\n oldModel.close();\n }\n\n this.model = model;\n\n if (this.listenerCount > 0) {\n this.addListeners(model);\n }\n\n this.dispatchEvent(\n new EventShimCustomEvent(IrisGridModel.EVENT.COLUMNS_CHANGED, {\n detail: model.columns,\n })\n );\n\n if (isIrisGridTableModelTemplate(model)) {\n this.dispatchEvent(\n new EventShimCustomEvent(IrisGridModel.EVENT.TABLE_CHANGED, {\n detail: model.table,\n })\n );\n }\n }\n\n setNextModel(modelPromise: Promise<IrisGridModel>): void {\n log.debug2('setNextModel');\n\n if (this.modelPromise) {\n this.modelPromise.cancel();\n }\n\n if (this.listenerCount > 0) {\n this.removeListeners(this.model);\n }\n\n this.modelPromise = PromiseUtils.makeCancelable(\n modelPromise,\n (model: IrisGridModel) => model.close()\n );\n this.modelPromise\n .then(model => {\n this.modelPromise = null;\n this.setModel(model);\n })\n .catch((err: unknown) => {\n if (PromiseUtils.isCanceled(err)) {\n log.debug2('setNextModel cancelled');\n return;\n }\n\n log.error('Unable to set next model', err);\n this.modelPromise = null;\n\n this.dispatchEvent(\n new EventShimCustomEvent(IrisGridModel.EVENT.REQUEST_FAILED, {\n detail: err,\n })\n );\n });\n }\n\n startListening(): void {\n super.startListening();\n\n this.addListeners(this.model);\n }\n\n stopListening(): void {\n super.stopListening();\n\n this.removeListeners(this.model);\n }\n\n addListeners(model: IrisGridModel): void {\n const events = Object.keys(IrisGridModel.EVENT);\n for (let i = 0; i < events.length; i += 1) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n model.addEventListener(events[i], this.handleModelEvent);\n }\n }\n\n removeListeners(model: IrisGridModel): void {\n const events = Object.keys(IrisGridModel.EVENT);\n for (let i = 0; i < events.length; i += 1) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n model.removeEventListener(events[i], this.handleModelEvent);\n }\n }\n\n get rowCount(): number {\n return this.model.rowCount;\n }\n\n get columnCount(): number {\n return this.model.columnCount;\n }\n\n get floatingTopRowCount(): number {\n return this.model.floatingTopRowCount;\n }\n\n get floatingBottomRowCount(): number {\n return this.model.floatingBottomRowCount;\n }\n\n get floatingLeftColumnCount(): number {\n return this.model.floatingLeftColumnCount;\n }\n\n get floatingRightColumnCount(): number {\n return this.model.floatingRightColumnCount;\n }\n\n textForCell: IrisGridModel['textForCell'] = (...args) =>\n this.model.textForCell(...args);\n\n truncationCharForCell: IrisGridModel['truncationCharForCell'] = (...args) =>\n this.model.truncationCharForCell(...args);\n\n textAlignForCell: IrisGridModel['textAlignForCell'] = (...args) =>\n this.model.textAlignForCell(...args);\n\n colorForCell: IrisGridModel['colorForCell'] = (...args) =>\n this.model.colorForCell(...args);\n\n backgroundColorForCell: IrisGridModel['backgroundColorForCell'] = (...args) =>\n this.model.backgroundColorForCell(...args);\n\n textForColumnHeader: IrisGridModel['textForColumnHeader'] = (...args) =>\n this.model.textForColumnHeader(...args);\n\n colorForColumnHeader: IrisGridModel['colorForColumnHeader'] = (...args) =>\n this.model.colorForColumnHeader(...args);\n\n textForRowHeader: IrisGridModel['textForRowHeader'] = (...args) =>\n this.model.textForRowHeader(...args);\n\n textForRowFooter: IrisGridModel['textForRowFooter'] = (...args) =>\n this.model.textForRowFooter(...args);\n\n isRowMovable: IrisGridModel['isRowMovable'] = (...args) =>\n this.model.isRowMovable(...args);\n\n isColumnMovable: IrisGridModel['isColumnMovable'] = (...args) =>\n this.model.isColumnMovable(...args);\n\n isColumnFrozen(x: ModelIndex): boolean {\n return this.model.isColumnFrozen(x);\n }\n\n get hasExpandableRows(): boolean {\n if (isExpandableGridModel(this.model)) {\n return this.model.hasExpandableRows;\n }\n return false;\n }\n\n get isExpandAllAvailable(): boolean {\n if (isExpandableGridModel(this.model)) {\n return this.model.isExpandAllAvailable ?? false;\n }\n return false;\n }\n\n isRowExpandable: IrisGridTreeTableModel['isRowExpandable'] = (...args) => {\n if (isExpandableGridModel(this.model)) {\n return this.model.isRowExpandable(...args);\n }\n return false;\n };\n\n isRowExpanded: IrisGridTreeTableModel['isRowExpanded'] = (...args) => {\n if (isExpandableGridModel(this.model)) {\n return this.model.isRowExpanded(...args);\n }\n return false;\n };\n\n setRowExpanded: IrisGridTreeTableModel['setRowExpanded'] = (...args) => {\n if (isExpandableGridModel(this.model)) {\n return this.model.setRowExpanded(...args);\n }\n throw Error('Function setRowExpanded does not exist on IrisGridTableModel');\n };\n\n expandAll: IrisGridTreeTableModel['expandAll'] = () => {\n if (isExpandableGridModel(this.model)) {\n return this.model.expandAll();\n }\n throw Error('Function expandAll does not exist on IrisGridTableModel');\n };\n\n collapseAll: IrisGridTreeTableModel['collapseAll'] = () => {\n if (isExpandableGridModel(this.model)) {\n return this.model.collapseAll();\n }\n throw Error('Function collapseAll does not exist on IrisGridTableModel');\n };\n\n depthForRow: IrisGridTreeTableModel['depthForRow'] = (...args) => {\n if (isExpandableGridModel(this.model)) {\n return this.model.depthForRow(...args);\n }\n return 0;\n // throw Error('Function depthForRow does not exist on IrisGridTableModel');\n };\n\n get isExportAvailable(): boolean {\n return this.model.isExportAvailable;\n }\n\n get isColumnStatisticsAvailable(): boolean {\n return this.model.isColumnStatisticsAvailable;\n }\n\n get isValuesTableAvailable(): boolean {\n return this.model.isValuesTableAvailable;\n }\n\n get isCustomColumnsAvailable(): boolean {\n return (\n this.model.isCustomColumnsAvailable &&\n // Disable for selectDistinct tables\n !(this.isSelectDistinctAvailable && this.selectDistinctColumns.length > 0)\n );\n }\n\n get isFormatColumnsAvailable(): boolean {\n return this.model.isFormatColumnsAvailable;\n }\n\n get isChartBuilderAvailable(): boolean {\n return this.model.isChartBuilderAvailable;\n }\n\n get isRollupAvailable(): boolean {\n return (\n (this.originalModel.isRollupAvailable || this.rollup != null) &&\n this.selectDistinct.length === 0\n );\n }\n\n get isSelectDistinctAvailable(): boolean {\n return (\n (this.originalModel.isSelectDistinctAvailable ||\n this.selectDistinct.length > 0) &&\n this.rollup == null\n );\n }\n\n get isTotalsAvailable(): boolean {\n return this.model.isTotalsAvailable;\n }\n\n get isReversible(): boolean {\n return this.model.isReversible;\n }\n\n get columns(): readonly Column[] {\n return this.model.columns;\n }\n\n get initialMovedColumns(): readonly MoveOperation[] {\n return this.model.initialMovedColumns;\n }\n\n get initialMovedRows(): readonly MoveOperation[] {\n return this.model.initialMovedRows;\n }\n\n get layoutHints(): LayoutHints | null {\n return this.model.layoutHints;\n }\n\n get frontColumns(): readonly ColumnName[] {\n return this.model.frontColumns;\n }\n\n get backColumns(): readonly ColumnName[] {\n return this.model.backColumns;\n }\n\n get frozenColumns(): readonly ColumnName[] {\n return this.model.frozenColumns;\n }\n\n getColumnHeaderGroup: IrisGridModel['getColumnHeaderGroup'] = (...args) =>\n this.model.getColumnHeaderGroup(...args);\n\n get columnHeaderGroups(): readonly ColumnHeaderGroup[] {\n return this.model.columnHeaderGroups;\n }\n\n set columnHeaderGroups(groups: readonly ColumnHeaderGroup[]) {\n this.model.columnHeaderGroups = groups;\n }\n\n get initialColumnHeaderGroups(): readonly ColumnHeaderGroup[] {\n return this.model.initialColumnHeaderGroups;\n }\n\n getColumnHeaderParentGroup: IrisGridModel['getColumnHeaderParentGroup'] = (\n ...args\n ) => this.model.getColumnHeaderParentGroup(...args);\n\n get columnHeaderGroupMap(): ReadonlyMap<string, ColumnHeaderGroup> {\n return this.model.columnHeaderGroupMap;\n }\n\n get columnHeaderMaxDepth(): number {\n return this.model.columnHeaderMaxDepth;\n }\n\n updateFrozenColumns(columns: readonly ColumnName[]): void {\n return this.model.updateFrozenColumns(columns);\n }\n\n get originalColumns(): readonly Column[] {\n return this.originalModel.columns;\n }\n\n get groupedColumns(): readonly Column[] {\n return this.model.groupedColumns;\n }\n\n get description(): string {\n return this.model.description;\n }\n\n formatForCell: IrisGridModel['formatForCell'] = (...args) =>\n this.model.formatForCell(...args);\n\n valueForCell: IrisGridModel['valueForCell'] = (...args) =>\n this.model.valueForCell(...args);\n\n get filter(): readonly FilterCondition[] {\n return this.model.filter;\n }\n\n set filter(filter: readonly FilterCondition[]) {\n this.model.filter = filter;\n }\n\n get formatter(): Formatter {\n return this.model.formatter;\n }\n\n set formatter(formatter: Formatter) {\n this.model.formatter = formatter;\n }\n\n displayString: IrisGridModel['displayString'] = (...args) =>\n this.model.displayString(...args);\n\n get sort(): readonly Sort[] {\n return this.model.sort;\n }\n\n set sort(sort: readonly Sort[]) {\n this.model.sort = sort;\n }\n\n get customColumns(): readonly ColumnName[] {\n return this.model.customColumns;\n }\n\n set customColumns(customColumns: readonly ColumnName[]) {\n this.model.customColumns = customColumns;\n }\n\n get formatColumns(): readonly CustomColumn[] {\n return this.model.formatColumns;\n }\n\n set formatColumns(formatColumns: readonly CustomColumn[]) {\n this.model.formatColumns = formatColumns;\n }\n\n get rollupConfig(): RollupConfig | null {\n return this.rollup;\n }\n\n set rollupConfig(rollupConfig: RollupConfig | null) {\n log.debug('set rollupConfig', rollupConfig);\n\n if (!this.isRollupAvailable) {\n throw new Error('Rollup Rows are not available');\n }\n\n // Prevent model update when IrisGridModelUpdater is mounted\n // if rollup is already initialized in IrisGridPanel\n if (deepEqual(rollupConfig, this.rollup)) {\n return;\n }\n\n this.rollup = rollupConfig;\n\n let modelPromise = Promise.resolve(this.originalModel);\n\n if (\n isIrisGridTableModelTemplate(this.originalModel) &&\n rollupConfig != null\n ) {\n modelPromise = this.originalModel.table\n .rollup(rollupConfig)\n .then(table => makeModel(this.dh, table, this.formatter));\n }\n this.setNextModel(modelPromise);\n }\n\n get selectDistinctColumns(): ColumnName[] {\n return this.selectDistinct;\n }\n\n set selectDistinctColumns(columnNames: string[]) {\n log.debug('set selectDistinctColumns', columnNames);\n\n if (!this.isSelectDistinctAvailable) {\n throw new Error('Select distinct is not available');\n }\n\n if (\n columnNames === this.selectDistinctColumns ||\n (columnNames.length === 0 && this.selectDistinctColumns.length === 0)\n ) {\n log.debug('Ignore same selectDistinctColumns', columnNames);\n return;\n }\n\n this.selectDistinct = columnNames;\n\n const selectDistinctColumns = columnNames\n .map(name => this.originalColumns.find(column => column.name === name))\n .filter(column => column != null) as Column[];\n\n let modelPromise = Promise.resolve(this.originalModel);\n\n if (\n isIrisGridTableModelTemplate(this.originalModel) &&\n selectDistinctColumns.length > 0\n ) {\n modelPromise = this.originalModel.table\n .selectDistinct(selectDistinctColumns)\n .then(table => makeModel(this.dh, table, this.formatter));\n }\n this.setNextModel(modelPromise);\n }\n\n get table(): Table | TreeTable | undefined {\n if (isIrisGridTableModelTemplate(this.model)) {\n return this.model.table;\n }\n\n return undefined;\n }\n\n get totalsConfig(): UITotalsTableConfig | null {\n return this.model.totalsConfig;\n }\n\n set totalsConfig(totalsConfig: UITotalsTableConfig | null) {\n this.model.totalsConfig = totalsConfig;\n }\n\n get isFilterRequired(): boolean {\n return this.model.isFilterRequired;\n }\n\n get isEditable(): boolean {\n return isEditableGridModel(this.model) && this.model.isEditable;\n }\n\n isEditableRange: IrisGridTableModel['isEditableRange'] = (\n ...args\n ): boolean => {\n if (isEditableGridModel(this.model)) {\n return this.model.isEditableRange(...args);\n }\n return false;\n };\n\n isFilterable: IrisGridTableModel['isFilterable'] = (...args) =>\n this.model.isFilterable(...args);\n\n setViewport = (top: number, bottom: number, columns: Column[]): void =>\n this.model.setViewport(top, bottom, columns);\n\n snapshot: IrisGridModel['snapshot'] = (...args) =>\n this.model.snapshot(...args);\n\n textSnapshot: IrisGridTableModel['textSnapshot'] = (...args) =>\n this.model.textSnapshot(...args);\n\n export(): Promise<Table> {\n if (TableUtils.isTreeTable(this.model)) {\n throw new Error(\"TreeTable has no 'export' property\");\n }\n return (this.model as IrisGridTableModel).export();\n }\n\n valuesTable: IrisGridTableModel['valuesTable'] = (...args) =>\n this.model.valuesTable(...args);\n\n columnStatistics(column: Column): Promise<ColumnStatistics> {\n if (TableUtils.isTreeTable(this.model)) {\n throw new Error(\"TreeTable has no 'columnStatistics' function\");\n }\n return (this.model as IrisGridTableModel).columnStatistics(column);\n }\n\n editValueForCell: IrisGridTableModel['editValueForCell'] = (...args) => {\n if (isEditableGridModel(this.model)) {\n return this.model.editValueForCell(...args);\n }\n return '';\n };\n\n setValueForCell: IrisGridTableModel['setValueForCell'] = (...args) => {\n if (isEditableGridModel(this.model)) {\n return this.model.setValueForCell(...args);\n }\n return Promise.reject(new Error('Model is not editable'));\n };\n\n setValueForRanges: IrisGridTableModel['setValueForRanges'] = (...args) => {\n if (isEditableGridModel(this.model)) {\n return this.model.setValueForRanges(...args);\n }\n return Promise.reject(new Error('Model is not editable'));\n };\n\n setValues: EditableGridModel['setValues'] = (...args) => {\n if (isEditableGridModel(this.model)) {\n return this.model.setValues(...args);\n }\n return Promise.resolve();\n };\n\n isValidForCell: IrisGridTableModel['isValidForCell'] = (...args) => {\n if (isEditableGridModel(this.model)) {\n return this.model.isValidForCell(...args);\n }\n return false;\n };\n\n delete: IrisGridTableModel['delete'] = (...args) =>\n this.model.delete(...args);\n\n get pendingDataMap(): PendingDataMap<UIRow> {\n return this.model.pendingDataMap;\n }\n\n set pendingDataMap(map: PendingDataMap<UIRow>) {\n this.model.pendingDataMap = map;\n }\n\n get pendingRowCount(): number {\n return this.model.pendingRowCount;\n }\n\n set pendingRowCount(count: number) {\n this.model.pendingRowCount = count;\n }\n\n get pendingDataErrors(): PendingDataErrorMap {\n return this.model.pendingDataErrors;\n }\n\n commitPending: IrisGridTableModel['commitPending'] = (...args) =>\n this.model.commitPending(...args);\n\n getColumnIndexByName(name: ColumnName): number | undefined {\n return this.model.getColumnIndexByName(name);\n }\n\n async seekRow(\n startRow: number,\n column: Column,\n valueType: ValueTypeUnion,\n value: unknown,\n insensitive?: boolean,\n contains?: boolean,\n isBackwards?: boolean\n ): Promise<number> {\n return this.model.seekRow(\n startRow,\n column,\n valueType,\n value,\n insensitive,\n contains,\n isBackwards\n );\n }\n\n get isSeekRowAvailable(): boolean {\n return this.model.isSeekRowAvailable;\n }\n}\n\nexport default IrisGridProxyModel;\n","import type { dh as DhType, Table, TreeTable } from '@deephaven/jsapi-types';\nimport { Formatter, TableUtils } from '@deephaven/jsapi-utils';\nimport IrisGridModel from './IrisGridModel';\nimport IrisGridProxyModel from './IrisGridProxyModel';\n\n/**\n * Factory to create an IrisGridDataModel based on a table or tree table, whatever is passed in.\n */\nclass IrisGridModelFactory {\n /**\n * @param table The Table or TreeTable object to create the model with\n * @param formatter The formatter to use\n * @returns An IrisGridModel that uses the table provided\n */\n static async makeModel(\n dh: DhType,\n table: Table | TreeTable,\n formatter = new Formatter(dh)\n ): Promise<IrisGridModel> {\n let inputTable = null;\n if (!TableUtils.isTreeTable(table) && table.hasInputTable) {\n inputTable = await table.inputTable();\n }\n return new IrisGridProxyModel(dh, table, formatter, inputTable);\n }\n}\n\nexport default IrisGridModelFactory;\n","// The Deephaven API script isn't packaged as a module (yet), and is just included in index.html, exported to the global namespace\n// This include file is simply a wrapper so that it behaves like a module, and can be mocked easily for unit tests\nimport type { dh as DhType } from '@deephaven/jsapi-types';\n\ndeclare global {\n // eslint-disable-next-line vars-on-top,no-var\n var dh: DhType;\n}\n\nconst { dh } = globalThis;\n\nexport default dh;\n","import React, { useEffect, useMemo, useState } from 'react';\nimport { useConnection } from '@deephaven/app-utils';\nimport { ContextMenuRoot, LoadingOverlay } from '@deephaven/components'; // Use the loading spinner from the Deephaven components package\nimport {\n InputFilter,\n IrisGrid,\n IrisGridModel,\n IrisGridModelFactory,\n} from '@deephaven/iris-grid'; // iris-grid is used to display Deephaven tables\nimport dh from '@deephaven/jsapi-shim'; // Import the shim to use the JS API\nimport type { IdeConnection, Sort, Table } from '@deephaven/jsapi-types';\nimport { fetchVariableDefinition, TableUtils } from '@deephaven/jsapi-utils';\nimport Log from '@deephaven/log';\nimport './App.scss'; // Styles for in this app\n\nLog.setLogLevel(parseInt(import.meta.env.VITE_LOG_LEVEL ?? '', 10));\n\nconst log = Log.module('EmbedGrid.App');\n\nconst SUPPORTED_TYPES: string[] = [\n dh.VariableType.TABLE,\n dh.VariableType.TREETABLE,\n dh.VariableType.HIERARCHICALTABLE,\n dh.VariableType.PANDAS,\n];\n\nexport type Command = 'filter' | 'sort';\n\n/** Input value for filter commands */\nexport type FilterCommandType = {\n name: string;\n value: string;\n};\n\nexport type SortCommandType = {\n name: string;\n direction?: 'ASC' | 'DESC';\n};\n\n/**\n * Load an existing Deephaven table with the connection provided\n * @param connection The Deephaven session object\n * @param name Name of the table to load\n * @param type The type of table to load\n * @returns Deephaven table\n */\nasync function loadTable(\n connection: IdeConnection,\n name: string\n): Promise<Table> {\n log.info(`Fetching table ${name}...`);\n\n const definition = await fetchVariableDefinition(connection, name);\n if (!SUPPORTED_TYPES.includes(definition.type)) {\n throw new Error(\n `Unsupported type '${definition.type}' for variable named '${name}'`\n );\n }\n const object = await connection.getObject(definition);\n return object as Table;\n}\n\n/**\n * A functional React component that displays a Deephaven table in an IrisGrid using the @deephaven/iris-grid package.\n * It will attempt to open and display the table specified with the `name` parameter, expecting it to be present on the server.\n * E.g. http://localhost:3000/?name=myTable will attempt to open a table `myTable`\n * If no query param is provided, it will attempt to open a new session and create a basic time table and display that.\n * By default, tries to connect to the server defined in the VITE_CORE_API_URL variable, which is set to http://localhost:1000/jsapi\n * See create-react-app docs for how to update these env vars: https://create-react-app.dev/docs/adding-custom-environment-variables/\n */\nfunction App(): JSX.Element {\n const connection = useConnection();\n const [model, setModel] = useState<IrisGridModel>();\n const [error, setError] = useState<string>();\n const [inputFilters, setInputFilters] = useState<InputFilter[]>();\n const [sorts, setSorts] = useState<Sort[]>();\n const [isLoading, setIsLoading] = useState(true);\n const searchParams = useMemo(\n () => new URLSearchParams(window.location.search),\n []\n );\n const canCopy = searchParams.get('canCopy') != null;\n const canDownloadCsv = searchParams.get('canDownloadCsv') != null;\n\n useEffect(\n function initializeApp() {\n async function initApp() {\n try {\n // Get the table name from the query param `name`.\n const name = searchParams.get('name');\n if (name == null) {\n throw new Error('No name param provided');\n }\n log.debug('Loading table', name, '...');\n // Load the table up.\n const table = await loadTable(connection, name);\n // Create the `IrisGridModel` for use with the `IrisGrid` component\n log.debug(`Creating model...`);\n const newModel = await IrisGridModelFactory.makeModel(dh, table);\n setModel(newModel);\n log.debug('Table successfully loaded!');\n } catch (e: unknown) {\n log.error('Unable to load table', e);\n setError(`${e}`);\n }\n setIsLoading(false);\n }\n initApp();\n },\n [connection, searchParams]\n );\n\n useEffect(\n function initCommandListener() {\n function receiveMessage(e: MessageEvent) {\n const { command, value } = e.data as {\n command: Command;\n value: unknown;\n };\n switch (command) {\n case 'filter': {\n const filterCommandValues = value as FilterCommandType[];\n const newInputFilters = filterCommandValues.map(\n ({ name, value: filterValue }) => {\n const column = model?.columns.find(c => c.name === name);\n if (column == null) {\n throw new Error(`Could not find column named ${name}`);\n }\n return {\n name,\n value: filterValue,\n type: TableUtils.getNormalizedType(column.type),\n };\n }\n );\n setInputFilters(newInputFilters);\n break;\n }\n case 'sort': {\n const sortCommandValues = value as SortCommandType[];\n const newSorts = sortCommandValues.map(({ name, direction }) => {\n const column = model?.columns.find(c => c.name === name);\n if (column == null) {\n throw new Error(`Could not find column named ${name}`);\n }\n return direction === 'DESC'\n ? column.sort().desc()\n : column.sort().asc();\n });\n setSorts(newSorts);\n break;\n }\n }\n }\n window.addEventListener('message', receiveMessage);\n\n return () => {\n window.removeEventListener('message', receiveMessage);\n };\n },\n [model]\n );\n\n const isLoaded = model != null;\n\n return (\n <div className=\"App\">\n {isLoaded && (\n <IrisGrid\n canCopy={canCopy}\n canDownloadCsv={canDownloadCsv}\n model={model}\n inputFilters={inputFilters}\n sorts={sorts}\n />\n )}\n {!isLoaded && (\n <LoadingOverlay\n isLoaded={isLoaded}\n isLoading={isLoading}\n errorMessage={error ?? null}\n />\n )}\n <ContextMenuRoot />\n </div>\n );\n}\n\nexport default App;\n"],"names":["ColorUtils","background","d","computedColor","colorTokens","color","a","ColorUtils$1","TABLE_PREFIX","COLUMN_PREFIX","DB_RESERVED_VARIABLE_NAMES","JAVA_KEYWORDS","STERILE_TABLE_AND_NAMESPACE_REGEX","STERILE_COLUMN_AND_QUERY_REGEX","_DbNameValidator","DbNameValidator","__publicField","name","prefix","regex","checkReserved","i","legalName","headers","legalHeaders","header","legalHeader","DbNameValidator$1","getClosestByClassName","element","className","DOMUtils","Pending","item","cleanup","promise","PromiseUtils","allPromises","Pending$1","ValidationError","ValidationError$1","getLabelForTextFilter","filterType","Type","getLabelForNumberFilter","getLabelForDateFilter","getLabelForBooleanFilter","AssertionError","AssertionError$1","assertIsDefined","val","PasteError","PasteError$1","isEditableGridModel","model","assertIsEditableGridModel","isExpandableGridModel","SELECTION_DIRECTION","_GridRange","startColumn","startRow","endColumn","endRow","left","top","right","bottom","column","row","index1","index2","ranges","result","wasModified","range","j","other","start1","end1","start2","end2","ranges1","ranges2","otherRange","subtractRange","subtract","subtractRanges","columnCount","rowCount","r","columnOffset","rowOffset","direction","rangeIndex","nextCell","nextRangeIndex","cellCount","callback","c","GridRange","isAxisRange","isBoundedAxisRange","isLinkToken","token","_GridUtils","x","y","metrics","columnHeaderDepth","allColumnWidths","allRowHeights","allColumnXs","allRowYs","modelColumns","modelRows","modelRow","modelColumn","columnWidth","rowHeight","columnHeaderHeight","columnHeaderMaxDepth","clamp","start","total","end","visibleStart","visibleEnd","floatingStartCount","floatingEndCount","totalCount","visibleStartIndex","visibleEndIndex","itemIndex","itemCoordinates","itemSizes","coordinate","itemX","itemSize","offset","itemCount","floatingStart","floatingEnd","items","ignoreFloating","floatingItem","floatingLeftColumnCount","floatingRightColumnCount","visibleColumns","gridX","floatingTopRowCount","floatingBottomRowCount","visibleRows","gridY","startIndex","modelIndexes","visibleItems","userSizes","visibleItemIndex","value","modelIndex","userColumnWidths","userRowHeights","theme","rowHeaderWidth","floatingColumns","floatingLeftWidth","allowColumnResize","headerSeparatorHandleSize","halfSeparatorSize","isPreviousColumnHidden","columnX","isColumnHidden","midX","minX","maxX","visibleSizes","columnIndex","hiddenItems","allowRowResize","isPreviousRowHidden","rowY","isRowHidden","midY","minY","maxY","rowIndex","from","to","oldMovedItems","movedItems","lastMovedItem","toParam","isPreMoveTo","newLastMovedItem","reverse","fromItemOrRange","toItem","length","fromItem","fromStart","fromEnd","toStart","moveDistance","nextResult","currentStart","currentEnd","movedRange","currentResult","s","e","movedColumns","movedRows","columnRanges","rowRanges","visibleIndex","visibleIndexes","uiRange","EMPTY_ARRAY","uiRanges","modelRanges","modelRange","visibleRanges","platform","event","modifierKey","columns","width","height","floatingRightWidth","floatingTopHeight","floatingBottomHeight","x1","y1","x2","y2","wheelEvent","pageWidth","pageHeight","lineWidth","lineHeight","deltaX","deltaY","range1","range2","mergedRanges","tokenBox","gridWidth","gridHeight","verticalBarWidth","horizontalBarHeight","newLeft","newRight","newTop","newBottom","text","linkifyFind","GridUtils","GridUtils$1","trimMap","map","cacheSize","GridMetricCalculator","targetSize","iter","getFloatingCoordinates","startCount","endCount","max","sizeMap","coordinates","getOrThrow","_GridMetricCalculator","calculatedColumnWidths","calculatedRowHeights","fontWidths","initialRowHeights","initialColumnWidths","state","leftOffset","topOffset","draggingColumn","rowFooterWidth","minScrollHandleSize","scrollBarSize","firstRow","firstColumn","treePaddingX","treePaddingY","visibleRowHeights","visibleColumnWidths","visibleColumnXs","visibleRowYs","bottomViewport","rightViewport","columnWidthValues","rowHeightValues","w","h","scrollableContentWidth","scrollableContentHeight","scrollableViewportWidth","scrollableViewportHeight","lastLeftWithoutScroll","lastLeftWithScroll","lastTopWithoutScroll","lastTopWithScroll","lastLeft","lastTop","hasHorizontalBar","hasVerticalBar","barLeft","barTop","barWidth","barHeight","horizontalHandlePercent","verticalHandlePercent","handleWidth","handleHeight","leftColumnWidth","topRowHeight","leftOffsetPercent","topOffsetPercent","horizontalScrollPercent","verticalScrollPercent","scrollX","scrollY","floatingRows","draggingColumns","allRows","allColumns","visibleRowTreeBoxes","topVisible","leftVisible","bottomVisible","rightVisible","getModelIndex","visibleWidth","visibleHeight","availableHeight","availableWidth","rowHeights","columnWidths","columnWidthMap","rowHeightMap","treeDepthIndent","treeHorizontalPadding","depth","floatingWidth","floatingHeight","itemXs","maxSize","defaultItemSize","lastIndex","dataSize","getDefaultSize","calculatedHeight","initialHeight","calculatedWidth","initialWidth","visibleRow","visibleColumn","autoSizeRows","cachedValue","autoSizeColumns","minColumnWidth","headerWidth","dataWidth","headerFont","headerHorizontalPadding","headerText","headerFontWidth","font","cellHorizontalPadding","fontWidth","rowsPerPage","cellPadding","treePadding","context","textMetrics","size","GridMetricCalculator$1","defaultTheme","GridTheme","memoizeClear","fn","options","isClearingCache","memoizedFn","memoizee","memoizeClear$1","darkenForDepth","maxDepth","lab","convert","colorWithAlpha","alpha","g","b","GridColorUtils","GridMouseHandler","order","gridPoint","grid","GridSeparatorMouseHandler","separator","separatorIndex","point","metricCalculator","visibleOffsets","margin","calculatedSizes","firstIndex","newSizes","resizeIndex","itemOffset","isResizingMultiple","hiddenIndex","calculatedSize","newSize","defaultSize","GridSeparatorMouseHandler$1","GridColumnSeparatorMouseHandler","GridColumnSeparatorMouseHandler$1","_GridRenderer","truncationChar","backgroundColors","colors","truncatedText","tokens","_font","_baseline","textHeight","tokenBoxes","lastTokenEnd","currentTextWidth","tokenWidth","newTokenBox","str","len","charWidth","lo","hi","mid","truncatedStr","draggingRow","floatingDividerOuterColor","floatingDividerInnerColor","drawHover","rowBackgroundColors","rows","shadowBlur","shadowColor","colorSets","colorRowMap","topShadowRows","bottomShadowRows","addRowToColorMap","rowAbove","colorSet","depthAbove","colorRows","startColor","endColor","gradient","gradientY","mouseX","mouseY","mouseColumn","mouseRow","selectedRanges","columnColor","rowColor","metricsMaxX","rowAfter","backgroundColor","isFirstColumn","hasExpandableRows","textAlign","treeIndent","textWidth","textX","textY","textOverride","textColor","tokenIndex","textStart","actualBoundingBoxDescent","nextToken","textEnd","widthOfUnderline","treeMarkerColor","treeMarkerHoverColor","treeBox","isExpanded","markerText","treeLineColor","depthRowAfter","depthDiff","lineX","draggingColumnSeparator","isDragging","headerHiddenSeparatorSize","headerHiddenSeparatorHoverColor","headerSeparatorColor","headerSeparatorHoverColor","hiddenSeparatorHeight","hiddenY","containsFrozenColumns","hiddenColumns","_","index","highlightedSeparator","shouldDrawSeparator","nextColumnIndex","visibleColumnIndex","nextColumn","nextColumnWidth","isNextColumnHidden","bounds","endIndex","columnGroupName","columnGroupColor","columnGroupLeft","columnGroupRight","prevColumnIndex","prevModelIndex","prevColumnWidth","nextModelIndex","isFullWidth","columnText","style","headerBackgroundColor","headerColor","black","white","maxLength","separatorColor","isDarkBackground","isDarkText","renderText","columnLeft","visibleLeft","columnRight","isBeyondLeft","isBeyondRight","draggingRowSeparator","hiddenSeparatorWidth","hiddenX","hiddenRows","visibleRowIndex","nextRow","nextRowHeight","isNextRowHidden","viewport","editingCell","isCursorVisible","selectedRange","endX","endY","borderWidth","cellX","cellY","cellW","cellH","draggingColumnVisibleRange","draggingColumnDepth","draggingModelIndex","draggingGroup","originalLeft","originalWidth","draggingLeft","reorderOffset","columnHeaderOffset","draggingRowOffset","isDraggingHorizontalScrollBar","isDraggingVerticalScrollBar","scrollBarBackgroundColor","scrollBarHoverBackgroundColor","scrollBarCasingColor","scrollBarCornerColor","scrollBarColor","scrollBarHoverColor","scrollBarActiveColor","scrollBarHoverSize","scrollBarCasingWidth","scrollBarSelectionTick","scrollBarSelectionTickColor","scrollBarActiveSelectionTickColor","autoSelectRow","autoSelectColumn","isInbounds","isVerticalBarHover","isHorizontalBarHover","hScrollBarSize","vScrollBarSize","cursorColumn","sortedRanges","getTickX","tickX","tickWidth","trackHeight","cursorRow","getTickY","tickY","trackWidth","tickHeight","actualBoundingBoxAscent","cachedTokenBoxes","GridRenderer","GridRenderer$1","DEFAULT_INTERVAL_MS","GridSelectionMouseHandler","gridMouseX","gridMouseY","isModifierKey","isShiftKey","dragBounds","selectionEndRow","selectionEndColumn","timeout","GridSelectionMouseHandler$1","SLOPPY_CLICK_DISTANCE","SCROLL_INTERVAL","SCROLL_DELTA","getColumnInfo","group","isColumnGroup","startVisibleIndex","endVisibleIndex","possibleLeft","GridColumnMoveMouseHandler","nextLeft","nextOffset","columnInfo","initialColumnInfo","isDraggingLeft","floatingDraggingLeft","floatingDraggingRight","swapColumn","parentGroup","parentVisibleRange","newMovedColumns","parentRight","toVisibleIndex","toColumnInfo","switchPoint","draggingParentGroup","maxDepthSwapGroup","maxSwapDepth","newDraggingRange","GridColumnMoveMouseHandler$1","GridHorizontalScrollBarMouseHandler","rawLeft","metricState","mouseBarX","scrollPercent","newLeftOffset","GridHorizontalScrollBarMouseHandler$1","GridRowMoveMouseHandler","topRow","bottomRow","minMoveY","maxMoveY","GridRowMoveMouseHandler$1","GridRowSeparatorMouseHandler","GridRowSeparatorMouseHandler$1","GridRowTreeMouseHandler","GridRowTreeMouseHandler$1","GridScrollBarCornerMouseHandler","GridScrollBarCornerMouseHandler$1","GridVerticalScrollBarMouseHandler","rawTop","mouseBarY","newTopOffset","GridVerticalScrollBarMouseHandler$1","EditMouseHandler","EditMouseHandler$1","_GridTokenMouseHandler","renderer","renderState","tokensInCell","translatedTokenBox","isUserHoveringLink","_a","GridTokenMouseHandler","GridTokenMouseHandler$1","KeyHandler","KeyHandler$1","SelectionKeyHandler","deltaColumn","deltaRow","maximizePreviousRange","moveToColumn","moveToRow","selectRangeEndPosition","viewportPosition","lastRowIndex","SelectionKeyHandler$1","TreeKeyHandler","TreeKeyHandler$1","EditKeyHandler","EditKeyHandler$1","parseValueFromTable","table","data","cells","rowData","cell","parseValueFromNodes","nodes","node","parseValueFromElement","childNodes","hasTabChar","hasFirefoxTab","PasteKeyHandler","dummyInput","listener","PasteKeyHandler$1","directionForKey","key","CellInputField","selectionRange","disabled","propsValue","propsIsQuickEdit","onChange","onCancel","onDone","onContextMenu","inputField","useRef","isCancelled","initialValue","useState","isChanged","setIsChanged","isQuickEdit","setIsQuickEdit","setValue","useEffect","field","sendUpdate","useCallback","newValue","handleChange","handleCancel","handleClick","handleCommit","fillRange","handleBlur","handleKeyDown","handleContextMenu","jsx","classNames","PropTypes","ThemeContext","React","ThemeContext$1","_Grid","PureComponent","props","memoize","keyHandlers","mouseHandlers","isStuckToBottom","isStuckToRight","devicePixelRatio","legacyContext","backingStorePixelRatio","cursor","prevProps","prevState","isStickyBottom","isStickyRight","onMovedColumnsChanged","onMoveColumnComplete","onMovedRowsChanged","onMoveRowComplete","prevIsStickyBottom","prevIsStickyRight","prevPropMovedColumns","prevPropMovedRows","prevStateMovedColumns","prevStateMovedRows","currentStateMovedColumns","currentStateMovedRows","rect","stateOverride","_b","expandDescendants","gridRanges","newCursorRow","newCursorColumn","canvas","canvasOptions","canvasContext","assertNotNull","onViewChanged","scale","prevRowCount","prevColumnCount","prevHeight","prevWidth","oldSelectedRanges","onSelectionChanged","extendSelection","selectionStartRow","selectionStartColumn","lastSelectedRange","newRanges","selectedColumn","selectedRow","lastSelectedRanges","newSelectedRanges","lastRange","remainder","nextCursor","focusedRow","tableHeight","halfViewportHeight","gridRange","keepCursorInView","viewState","forceUpdate","edits","tableWidth","onError","rowSelected","columnSelected","mouseEvent","functionName","updateCoordinates","addCursorToDocument","mouseHandler","maxLeftOffset","maxTopOffset","wrapperStyle","inputStyle","isValid","jsxs","Fragment","Grid","moveOperations","contextTheme","userTheme","Grid$1","LINK_TRUNCATION_LENGTH","GridModel","EventTarget","visibleLength","indexOfProceedingWhitespace","lengthOfContent","contentToCheckForLinks","GridModel$1","makeTernaryFormatRule","config","prevRule","styleDBString","getStyleDBString","getConditionDBString","makeRowFormatColumn","dh","rule","makeColumnFormatColumn","col","log","Log","FormatterType","NumberCondition","StringCondition","DateCondition","BooleanCondition","CharCondition","FormatStyleType","getLabelForStyleType","option","getBackgroundForStyleConfig","type","customConfig","getColorForStyleConfig","bg","getNumberConditionText","getTextForNumberCondition","getStringConditionText","getTextForStringCondition","getDateConditionText","getTextForDateCondition","getBooleanConditionText","getTextForBooleanCondition","getCharConditionText","getTextForCharCondition","TableUtils","getLabelForNumberCondition","condition","getLabelForStringCondition","getLabelForDateCondition","getLabelForBooleanCondition","getLabelForCharCondition","getDefaultConditionForType","columnType","getDefaultValueForType","getConditionConfig","getDefaultConditionConfigForType","getDefaultStyleConfig","getShortLabelForStringCondition","getShortLabelForDateCondition","getShortLabelForBooleanCondition","getShortLabelForCharCondition","getShortLabelForNumberCondition","columnName","getShortLabelForConditionType","getFormatColumns","rules","rowFormatConfig","columnFormatConfigMap","formatterType","prevFormatColumn","formatColumn","isDateConditionValid","dateTimeString","rest","tzCode","DateUtils","isSupportedColumn","IrisGridBottomBar","animation","children","isShown","onClick","onEntering","onEntered","onExiting","onExited","CSSTransition","ThemeExport","HIDE_TIMEOUT","MAX_NUMBER_ROWS_SHOWN","PendingDataBottomBar","isSaving","onSave","onDiscard","discardTooltip","saveTooltip","error","pendingDataErrors","pendingDataMap","isSuccessShown","setIsSuccessShown","wasSuccessShown","setWasSuccessShown","successTimeout","prevIsSaving","usePrevious","errorMessage","useMemo","pendingRowCount","commitIcon","LoadingSpinner","vsPass","FontAwesomeIcon","vsWarning","Button","AggregationOperation","AggregationOperation$1","SELECTABLE_OPTIONS","isRollupOperation","isValidOperation","operationType","filterValidColumns","getOperationColumnNames","selected","invert","AggregationUtils","AdvancedSettingsType","AdvancedSettingsType$1","DEFAULTS","AdvancedSettings","isColumnHeaderGroup","ColumnHeaderGroup","_ColumnHeaderGroup","childIndexes","parent","memoizeOne","flattenedIndexes","newChildren","isValidIndex","array","isDateWrapper","IrisGridUtils","gridState","customColumns","customColumnNames","columnNames","getIndex","irisGridPanelState","isSelectingPartition","partition","partitionColumn","advancedSettings","quickFilters","quickFilter","sorts","sort","isAbs","panelState","inputFilters","irisGridState","advancedFilters","filterMap","filters","keys","customColumn","oldCustomColumns","oldCustomColumnsNames","oldCustomColumnName","removedColumnNames","newFilter","newMoves","removedColumnName","removedColumnIndex","moves","move","newMove","selectDistinctColumns","tableColumns","count","viewportColumns","alwaysFetchColumnNames","columnsToFetch","bufferPages","columnsCenter","bufferWidth","columnsLeft","columnsRight","bufferedColumns","rangeMap","rowMapIndex","columnMapIndex","matchColumnRanges","columnSet","originalColumns","aggregationSettings","groupingColumns","includeConstituents","showNonAggregatedColumns","includeDescriptions","aggregations","aggregationColumns","operation","aggregationMap","nonAggregatedColumnSet","existingColumns","filter","filterConfig","filterList","combinedText","operator","symbol","filterText","groupsParam","parentMap","groupMap","groups","originalGroupMap","seenChildren","addGroup","existingGroup","childName","childGroup","childIndex","addedGroup","columnHeaderGroup","groupNames","date","customColumnFormatMap","isFilterBarShown","conditionalFormats","reverseType","rollupConfig","showSearchBar","searchValue","selectedSearchColumns","invertSearchColumns","EMPTY_MAP","frozenColumns","columnHeaderGroups","formatter","savedQuickFilters","timeZone","importedFilters","advancedFilter","savedAdvancedFilters","selectedValues","otherOptions","columnMap","getColumnIndex","columnIndexOrName","columnSort","tableSettings","partitionColumnName","rangeSets","IrisGridUtils$1","_IrisGridCopyHandler","Component","copyState","buttonState","copyOperation","copyToClipboard","includeHeaders","formatValues","formatValue","CanceledPromiseError","copyButtonText","statusMessageText","isButtonContainerVisible","isFetching","isDone","IrisGridCopyHandler","IrisGridCopyHandler$1","FilterInputField","debounceMs","debounce","setGridFocus","defocusInput","relatedTarget","backward","onTab","isAdvancedFilterSet","onAdvancedFiltersTriggered","dhFilterFilled","vsFilter","FilterInputField$1","CopyKeyHandler","irisGrid","ContextActionUtils","CopyKeyHandler$1","TABLE","ShortcutRegistry","MODIFIER","KEY","INPUT_TABLE","IRIS_GRID_SHORTCUTS","SHORTCUTS","ReverseKeyHandler","IrisGridShortcuts","ReverseKeyHandler$1","ClearFilterKeyHandler","ClearFilterKeyHandler$1","IrisGridCellOverflowMouseHandler","rendererState","overflowButtonTooltipProps","newProps","deepEqual","IrisGridCellOverflowMouseHandler$1","IrisGridColumnSelectMouseHandler","isSelectingColumn","tableColumn","columnSelectionValidator","columnAllowedCursor","columnNotAllowedCursor","IrisGridColumnSelectMouseHandler$1","IrisGridColumnTooltipMouseHandler","tooltip","popper","shownColumnTooltip","newTooltip","IrisGridColumnTooltipMouseHandler$1","_CustomFormatAction","forwardedProps","closeMenu","parentContextMenu","formatString","placeholder","title","description","iconElement","Tooltip","CustomFormatAction","focusInput","CustomFormatAction$1","FormatContextMenuUtils","selectedFormat","TableColumnFormatter","format","isSelected","FormatContextMenuUtils$1","_DateTimeFormatContextMenu","currentTime","presetFormatOptions","DateTimeColumnFormatter","DateTimeFormatContextMenu","DateTimeFormatContextMenu$1","_DecimalFormatContextMenu","onCustomFormatChange","formatItems","DecimalColumnFormatter","defaultFormatOption","isCustomSelected","customFormat","customFormatOption","newCustomFormat","DecimalFormatContextMenu","DecimalFormatContextMenu$1","_IntegerFormatContextMenu","IntegerColumnFormatter","IntegerFormatContextMenu","IntegerFormatContextMenu$1","DEBOUNCE_UPDATE_FORMAT","CONTEXT_MENU_DATE_FORMAT","_IrisGridContextMenuHandler","columnFilter","newColumnFilter","newFilterText","command","cellValue","actions","searchFilter","filterIconColor","filterBarActiveColor","contextMenuSortIconColor","contextMenuReverseIconColor","modelSort","hasReverse","isColumnFreezable","isColumnFrozen","vsRemove","canCopy","valueText","settings","dateFilterFormatter","previewFilterFormatter","filterMenu","ContextActions","numberValueText","dateValueText","previewValue","expandingColumn","cellText","gotoRow","filterValue","GLOBAL_SHORTCUTS","formatOptions","vsCheck","newQuickFilter","isFinite","valueFilter","sortActions","additionalSortActions","IrisGridContextMenuHandler","IrisGridContextMenuHandler$1","IrisGridDataSelectMouseHandler","IrisGridDataSelectMouseHandler$1","IrisGridFilterMouseHandler","hoverAdvancedFilter","newHoverAdvancedFilter","IrisGridFilterMouseHandler$1","IrisGridRowTreeMouseHandler","expandCellTooltipProps","isRowExpanded","IrisGridRowTreeMouseHandler$1","IrisGridSortMouseHandler","addToExisting","IrisGridSortMouseHandler$1","PendingMouseHandler","PendingMouseHandler$1","IrisGridTokenMouseHandler","linkHoverTooltipProps","href","IrisGridTokenMouseHandler$1","ToastBottomBar","setIsShown","prevChildren","startTimer","IrisGridMetricCalculator","IrisGridMetricCalculator$1","COLUMN_BUFFER_PAGES","IrisGridModelUpdater","alwaysFetchColumns","totalsConfig","formatColumns","sortsForModel","IrisGridModelUpdater$1","ICON_NAMES","EXPAND_ICON_SIZE","ICON_SIZE","IrisGridRenderer","isAdvancedFilterValid","isQuickFilterValid","dhSortUp","dhSortDown","vsTriangleDown","vsTriangleRight","vsLinkExternal","faIcon","path","icon","scaledIcon","scaleMatrix","originalFont","displayValue","groupedColumns","lastVisibleGroupColumnIndex","firstPendingRow","hoverSelectColumn","loadingScrimProgress","scrimBlurSize","scrimColor","interior","boundsProp","isMenuShown","textRight","defaultX","yOffset","filterBarHeight","filterBarExpandedActiveCellBackgroundColor","filterBarErrorColor","filterBarHorizontalPadding","rectLeft","rectTop","rectWidth","rectHeight","filterBarCollapsedHeight","filterBarActiveBackgroundColor","isFilterValid","markerIcon","iconX","iconY","floatingGridRowColor","floatingRowBackgroundColors","rowHoverBackgroundColor","NULL_POSITION","buttonLeft","buttonTop","buttonWidth","buttonHeight","overflowButtonColor","overflowButtonHoverColor","IrisGridRenderer$1","IrisGridTheme","STATS_LABEL_OVERRIDES","_ColumnStatistics","numRows","stats","onStatistics","statistics","loading","showGenerateStatistics","statisticElements","formattedValue","statisticElement","rowCountLabel","formattedRowCount","CopyButton","dhFreeze","vsLock","dhRefresh","ColumnStatistics","ColumnStatistics$1","AdvancedFilterCreatorFilterItem","tableUtils","filterTypes","selectedType","onDelete","showValueInput","typeOptionElements","label","typeDropdown","vsTrash","AdvancedFilterCreatorFilterItem$1","_AdvancedFilterCreatorSelectValueList","values","v","invertSelection","selectedIndex","isLoading","viewportSize","SelectValueList","list","AdvancedFilterCreatorSelectValueList","AdvancedFilterCreatorSelectValueList$1","_AdvancedFilterCreatorSelectValue","searchTable","searchText","formattedCount","formattedTableSize","searchTablePromise","showSearch","displayedValuesText","placeholderText","AdvancedFilterCreatorSelectValue","AdvancedFilterCreatorSelectValue$1","_AdvancedFilterCreator","filterOperators","filterItems","shortid","valuesTable","inputs","FilterOperator","assertFilterOperatorValue","filterIndex","filterItem","onSortChange","onFilterChange","operators","sortDirection","valuesTableError","isValuesTableAvailable","isBoolean","isDateType","filterItemElements","isAndFilter","operatorElement","showAddFilterItem","addFilterItem","dhNewCircleLargeFilled","dhSortAmountDown","AdvancedFilterCreator","AdvancedFilterCreator$1","Aggregations","isRollup","onEdit","showOnTop","aggregation","selectedOperation","setSelectedOperation","setSelectedRanges","changeSettings","changedSettings","changeAggregations","newAggregations","changeShowOnTop","newShowOnTop","handleDragStart","DragUtils","handleDragEnd","destination","source","destinationIndex","draggedItems","insertIndex","handleOperationChange","handleAdd","handleDeleteClicked","handleAggregationSelectionChange","handleAggregationSelect","handleShowOnTopChange","renderAggregation","isClone","selectedCount","badgeText","isEditable","dhWarningFilled","DraggableItemList","vsEdit","isOptionsShown","isAggregationsShown","Select","Option","RadioGroup","RadioItem","DragDropContext","DEFAULT_ROW_HEIGHT","AggregationEdit","setTop","setBottom","setSort","validColumns","filteredColumns","handleSelect","newSelected","newInvert","handleReset","handleViewportChange","toggleAll","checked","isModified","Checkbox","dhSortAlphaDown","dhSortAlphaUp","ItemList","SvgBarIcon","SvgHistogramIcon","SvgLineIcon","SvgPieIcon","SvgScatterIcon","FormatColumnWhereIcon","FormatRowWhereIcon","ChartBuilder","xAxis","seriesItems","LineIcon","BarIcon","ScatterIcon","PieIcon","HistogramIcon","newSeriesItems","isLinked","intIndex","onSubmit","series","maxSeriesCount","xAxisLabel","seriesLabel","isSeriesVisible","isAddSeriesVisible","chartType","seriesItem","dhTable","vsCircleLargeFilled","vsLink","dhUnlink","ChartBuilder$1","InputEditor","editorSettings","inputEditorSettings","monaco.editor","onContentChanged","isEditorFocused","editorIndex","invalid","isEditorEmpty","editorContainer","INPUT_TYPE","EMPTY_FN","CustomColumnInput","eventKey","inputIndex","formula","onDeleteColumn","onTabInEditor","isDuplicate","isValidName","handleFormulaEditorContentChanged","formulaValue","Draggable","provided","snapshot","vsGripper","IrisGridModel","type0","callback0","options0","IrisGridModel$1","_CustomColumnBuilder","input","customColumnInputs","newInputs","customColumnIndex","newCustomInput","isCustomColumnApplying","customEvent","sourceIndex","sourceInput","focusEditorIndex","shiftKey","_c","nextFocusIndex","_d","originalCustomColumns","hasRequestFailed","nameCount","isSuccessShowing","saveText","areNamesValid","filteredNames","areNamesUnique","container","Droppable","CustomColumnBuilder","CustomColumnBuilder$1","OptionType","OptionType$1","DEBOUNCE_SEARCH","GROUPED_LIST_ID","UNGROUPED_LIST_ID","_RollupRows","focusIndex","showConstituents","currentGroupings","newGroupings","groupings","grouping","groupedSelectedRanges","newColumns","isSameList","ungroupedSelectedRanges","sourceItems","sourceRanges","stateUngroupedSelectedRanges","stateGroupedSelectedRanges","dragSource","ungroupedColumns","groupListHeight","ungroupMaxListHeight","ungroupMinListHeight","SearchInput","RollupRows","RollupRows$1","_TableCsvExporter","downloadRowOption","customizedDownloadRowOption","customizedDownloadRows","snapshotRanges","rangeA","rangeB","includeHiddenColumns","isDownloading","onDownloadStart","onDownload","fileName","includeColumnHeaders","useUnformattedValues","frozenTable","tableSubscription","tableDownloadProgress","tableDownloadEstimatedTime","tableDownloadStatus","id","TimeUtils","ClassNames","TableCsvExporter","TableCsvExporter$1","UNFORMATTED_DATE_PATTERN","isUpdateEventData","assertIsUpdateEventData","_TableSaver","FormatterUtils","getDownloadWorker","sw","iframe","port","useBlob","chunks","encode","streamConfig","chunk","blob","link","encodedFileName","messageChannel","onDownloadCompleted","cancelable","onDownloadCanceled","headerString","snapshotCount","snapshotIndex","snapshotStartRow","snapshotEndRow","n","onDownloadProgressUpdate","downloadProgress","estimateTime","csvString","snapshotIterator","rowIdx","cellData","hasCustomColumnFormat","formatOverride","cellFormat","currentGridRange","err","download","readableStreamPulling","src","TableSaver","VisibilityOrderingGroup","onColorChange","onNameChange","validateName","isNew","groupRef","nameInputRef","colorInputRef","isColorInputOpen","setIsColorInputOpen","setName","isEditing","setIsEditing","shouldValidate","setShouldValidate","nameValidationError","colorInputBlurHandler","handleConfirm","handleEditKeyDown","vsChromeClose","dhSquareFilled","vsPaintcan","emptyOnClick","VisibilityOrderingItem","forwardRef","ref","clone","childCount","onVisibilityChange","onGroupDelete","onGroupColorChange","onGroupNameChange","validateGroupName","handleProps","isVisible","buttonRef","handleVisibilityChange","dhEye","dhEyeSlash","VisibilityOrderingItem$1","isFlattenedTreeItem","getDragDepth","indentationWidth","getTreeItem","columnHeaderGroupMap","hiddenColumnSet","selectedItems","aVal","bVal","getTreeItems","selectedItemsSet","getProjection","activeId","overId","dragOffset","overItemIndex","activeItemIndex","activeItem","newItems","arrayMove","previousItem","nextItem","dragDepth","projectedDepth","getMaxDepth","minDepth","getMinDepth","getParentId","flatten","parentId","acc","flattenTree","findItemDeep","itemId","child","countChildren","getChildCount","DIRECTIONS","KeyboardCode","HORIZONTAL","sortableTreeKeyboardCoordinates","indicator","currentCoordinates","active","over","collisionRect","droppableRects","droppableContainers","containers","collisions","closestCorners","closestId","getFirstCollision","activeRect","newRect","newDroppable","newIndex","newItem","activeIndex","modifier","PointerSensorWithInteraction","PointerSensor","isInteractiveElement","INTERACTIVE_ELEMENTS","TreeItem","disableInteraction","ghost","dragRef","wrapperRef","renderItem","depthMarkers","renderItemProps","animateLayoutChanges","isSorting","wasDragging","SortableTreeItem","attributes","listeners","setDraggableNodeRef","setDroppableNodeRef","transform","transition","useSortable","transformString","CSS","dropAnimationConfig","defaultDropAnimation","offsetY","adjustToCursor","args","SortableTreeInner","offsetLeft","useDndContext","contextRef","projected","sensorContext","createPortal","DragOverlay","MEASURING","MeasuringStrategy","CONSTRAINT","SortableTree","onDragStart","onDragEnd","setActiveId","setOverId","setOffsetLeft","flattenedItems","flattenedTree","keyboardOptions","sensors","useSensors","useSensor","KeyboardSensor","sortedIds","newActiveId","handleDragMove","delta","handleDragOver","resetState","clonedItems","overIndex","activeTreeItem","handleDragCancel","DndContext","closestCenter","SortableContext","verticalListSortingStrategy","moveItemsFromDrop","selectedParentItems","firstMovableIndex","lastMovableIndex","treeItems","newGroups","firstVisibleIndex","fromItemIndex","toItemIndex","toIndex","moveToGroup","originalDropIndex","dropIndex","toName","columnGroups","newGroupMap","fromGroup","toGroup","movedGroup","deleteNames","parentName","nextParentName","nextParent","DEBOUNCE_SEARCH_COLUMN","_VisibilityOrderingBuilder","throttle","onColumnHeaderGroupChanged","newGroup","onColumnVisibilityChanged","selectedColumns","displayString","elements","firstMovableTreeIndex","lastMovableTreeIndex","movableItems","onReset","columnsMatch","visibleIndexToFocus","columnItemToFocus","updatedGroups","prevItemIndex","idx","prevItem","newParentItemIndex","newParentItem","parentItem","scrollListAfterMove","itemsParam","isAscending","aName","bName","TextUtils","moveToIndex","lastSelectedColumn","isModifierKeyDown","isShiftKeyDown","columnsToBeAdded","selectedItem","lastSelectedIndex","newSelectedColumns","newParentId","newName","oldName","groupIndex","oldGroup","parentIndex","newParent","groupName","hasSelection","nameToIndexes","hiddenColumnsSet","columnsToToggle","areSomeVisible","allToggleText","selectedToggleText","visibilityOrderingList","vsRefresh","vsSymbolStructure","vsAdd","vsChevronUp","vsChevronDown","dhArrowToTop","dhArrowToBottom","VisibilityOrderingBuilder","VisibilityOrderingBuilder$1","CrossColumnSearch","filterColumns","update","isConfigureColumnsShown","hasAllColumnsSelected","hasNoColumnsSelected","dhGearFilled","dhCheckSquare","dhWarningCircleFilled","dhRemoveSquareFilled","Popper","CrossColumnSearch$1","DEBOUNCE_UPDATE_FILTER","_PartitionSelectorSearch","onListResized","selectedValue","onSelect","offsetIndex","getFormattedString","initialPageSize","listHeight","searchInput","itemList","PartitionSelectorSearch","PartitionSelectorSearch$1","PARTITION_CHANGE_DEBOUNCE_MS","IrisGridPartitionSelector","onAppend","onFetchAll","partitionSelectorSearch","selectorSearch","DropdownMenu","searchMenu","vsClose","IrisGridPartitionSelector$1","SelectDistinctBuilder","filteredInputs","prevInputs","disableAddButton","SelectDistinctBuilder$1","AdvancedSettingsMenu","Menu","isOn","DEFAULT_CALLBACK","getRuleValue","getRuleTitle","ConditionalFormattingMenu","onCreate","handleRuleClick","handleDeleteClick","updatedRules","handleDragHandlerClick","numberConditionOptions","stringConditions","dateConditions","booleanConditions","charConditions","isNumberConditionValid","startValue","endValue","getNumberInputs","selectedCondition","handleValueChange","handleStartValueChange","handleEndValueChange","conditionValue","getStringInputs","getDateInputs","getBooleanInputs","getCharInputs","ConditionEditor","selectedColumnType","prevColumnType","setPrevColumnType","setCondition","setStartValue","setEndValue","conditions","handleConditionChange","conditionInputs","DEFAULT_BACKGROUND","DEFAULT_COLOR_LIGHT","DEFAULT_COLOR_DARK","DEFAULT_DROPDOWN_WIDTH","StyleEditor","styleType","setStyleType","setBackground","setShown","dropdownWidth","setDropdownWidth","csContainer","handleBackgroundChange","handleMenuClosed","handleToggleClick","updateDropdownWidth","styleOptions","renderOptions","optionArray","renderMenuElement","dhSort","makeDefaultConfig","ColumnFormatEditor","setColumn","conditionConfig","setConditionConfig","conditionValid","setConditionValid","selectedStyle","setStyle","handleColumnChange","newColumn","updatedConditionConfig","handleStyleChange","updatedStyleConfig","columnInputOptions","ComboBox","RowFormatEditor","getFormatterTypeIcon","getFormatterTypeLabel","formatterTypes","ConditionalFormatEditor","onUpdate","defaultRule","selectedFormatter","setFormatter","setRule","setIsValid","handleSave","handleFormatterChange","handleRuleChange","ruleConfig","isRuleValid","updatedRule","conf","language","lang","PyLang","GroovyLang","ScalaLang","DbLang","LogLang","MonacoUtils","getWorker","registerLanguages","removeHashtag","dhDarkRules","MonacoTheme","dhDarkColors","languages","languageIds","monaco.languages","languageParam","editor","eolSequence","session","didOpenDocumentParams","changedEvent","changes","versionId","contentChanges","change","rangeLength","contentChange","didChangeDocumentParams","didCloseDocumentParams","pasteEvent","smartQuotes","invalidChars","invalidSpaces","editorModel","pastedText","keybindings","keybinding","elem","shortcut","keyState","keyValue","monaco.KeyMod","KeyCodeUtils","newTokens","lineText","monaco.Range","MonacoUtils$1","Editor","onEditorInitialized","monaco.KeyCode","onEditorWillDestroy","Editor$1","IrisGridCellOverflowModal","isOpen","onClose","isOpened","setIsOpened","setHeight","showLineNumbers","setShowLineNumbers","isFormatted","setIsFormatted","canFormat","setCanFormat","editorRef","toggleLineNumbers","formatAsJSON","autoSetLineNumbers","handleToggle","contentHeight","Modal","ModalHeader","vsListOrdered","vsJson","ModalBody","isIrisGridProxyModel","DEFAULT_FORMAT_STRING","GotoRow","gotoRowError","gotoValueError","onGotoRowSubmit","onGotoRowNumberChanged","gotoValueSelectedColumnName","gotoValue","gotoValueFilter","onGotoValueSelectedColumnNameChanged","onGotoValueSelectedFilterChanged","onGotoValueChanged","onGotoValueSubmit","gotoRowInputRef","gotoValueInputRef","isGotoRowActive","setIsGotoRowActive","res","handleGotoValueNumberKeyDown","onGotoValueInputChanged","handleGotoValueKeySubmit","normalizedType","selectInput","renderValueInput","DateTimeInput","FilterType","vsArrowUp","vsArrowDown","UPDATE_DOWNLOAD_THROTTLE","SET_FILTER_DEBOUNCE","SEEK_ROW_DEBOUNCE","SET_CONDITIONAL_FORMAT_DEBOUNCE","DEFAULT_AGGREGATION_SETTINGS","isEmptyConfig","_IrisGrid","advancedFilterOptions","isChartBuilderAvailable","isCustomColumnsAvailable","isFormatColumnsAvailable","isRollupAvailable","isTotalsAvailable","isSelectDistinctAvailable","isExportAvailable","toggleFilterBarAction","toggleSearchBarAction","toggleGotoRowAction","canDownloadCsv","canToggleSearch","showGotoRow","hasAdvancedSettings","optionItems","dhGraphLineUp","vsSplitHorizontal","dhTriangleDownSquare","vsSymbolOperator","vsRuby","vsCloudDownload","vsTools","vsSearch","vsReply","operationMap","newOperations","o","rulesParam","preview","editIndex","operationOrder","customFilters","partitionFilters","floatingRowCount","draggingRange","conditionalFormatPreview","popperOptions","expandTooltipDisplayValue","linkHoverDisplayValue","movedColumnsProp","movedRowsProp","searchColumns","Formatter","changedInputFilters","inputFilter","replaceExistingFilters","loadingScrimStartTime","loadingScrimFinishTime","now","totalTime","rawValue","replaceExisting","newAdvancedFilters","newQuickFilters","globalColumnFormats","dateTimeFormatterOptions","defaultDecimalFormatOptions","defaultIntegerFormatOptions","truncateNumbersWithPound","isColumnFormatChanged","isDateFormattingChanged","isDecimalFormattingChanged","isIntegerFormattingChanged","isTruncateNumbersChanged","updatedFormats","mergedColumnFormats","applyInputFiltersOnInit","inputFiltersWithValues","partitionTable","resolved","loadingText","resetRanges","minScrimTransitionTime","maxScrimTransitionTime","scrimTransitionTime","columnVisibleIndex","allFrozenColumns","defaultWidth","onPartitionAppend","entries","currentSorts","searchDisplayMode","isGotoShown","pendingSavePromise","containsGridCellInputField","newPendingSavePromise","onColumnSelected","dataMap","isExpandable","isGrouped","onDataSelected","oldSort","newSort","focusedFilterBarColumn","onCreateChart","prevCustomColumnFormatMap","columnFormattingRule","openOptions","newOptions","bottomNonFloating","onChangeApplied","newSorts","newSelectDistinctColumns","isReady","inputString","isBackwards","selectedColumnName","gotoValueSelectedFilter","searchFromRow","isContains","isEquals","columnDataType","startDate","inputValue","onStateChange","gridRect","popperMargin","rowNumber","rowInt","boundedLeft","boundedWidth","virtualReference","onlyFetchVisibleColumns","onAdvancedSettingsChange","loadingSpinnerShown","shownAdvancedFilter","conditionalFormatEditIndex","isTableDownloading","selectedAggregation","pendingSaveError","toastMessage","showOverflowModal","overflowText","focusField","fieldWidth","fieldHeight","isBarFiltered","loadingElement","loadingStatus","columnTooltip","filterBar","isFilterSet","isFilterVisible","advancedFilterMenus","xColumnHeader","xFilterBar","openOptionsStack","stringName","gridWrapper","_e","_f","vsMenu","tableSaver","Stack","Page","IrisGrid","IrisGrid$1","MissingKeyError","MissingKeyError$1","SET_VIEWPORT_THROTTLE","APPLY_VIEWPORT_THROTTLE","isIrisGridTableModelTemplate","_IrisGridTableModelTemplate","inputTable","layoutHints","moveColumn","moveGroup","visibleRange","frontColumns","backColumns","usedColumns","frontIndex","backIndex","firstChildName","rightModelIndex","rightVisibleIndex","firstChildGroup","childColumn","indices","viewportTop","viewportBottom","viewHeight","keyColumnCount","valueType","insensitive","contains","names","totalsTable","EventShimCustomEvent","formatForCell","pendingRow","currentDepth","totalsRow","totalsRowCount","viewportY","_h","_g","defaultOperation","totalsData","newData","newRow","consolidateRanges","consolidated","topFloatingRowsSet","tableRanges","bottomFloatingRowsSet","topFloatingRows","rangeSet","bottomFloatingRows","formattedText","pendingAreaRange","pendingRanges","newDataMap","newRowData","tableAreaRange","newRows","edit","rowEditMap","rowMap","dataIndex","rangeRowCount","rowEdits","keyColumns","pendingRange","deleteTable","columnFilters","agg","curr","IrisGridTableModelTemplate","IrisGridTableModel","layoutHintsFrontColumns","layoutHintsBackColumns","layoutHintsFrozenColumns","userFrozenColumns","IrisGridTableModel$1","IrisGridTreeTableModel","c1","c2","hasChildren","viewportRange","intersection","resultRow","viewportRow","IrisGridTreeTableModel$1","makeModel","IrisGridProxyModel","detail","oldModel","modelPromise","events","IrisGridProxyModel$1","IrisGridModelFactory","IrisGridModelFactory$1","shim","SUPPORTED_TYPES","loadTable","connection","definition","fetchVariableDefinition","App","useConnection","setModel","setError","setInputFilters","setSorts","setIsLoading","searchParams","initApp","newModel","receiveMessage","newInputFilters","isLoaded","LoadingOverlay","ContextMenuRoot"],"mappings":"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M,IAAK,MAAO,GAAI,CAC1B,EACA,aAAc,CACZ,CACE,WAAY,iFACZ,OAAQ,CAAE,aAAc,CAAE,CAC5B,CACF,EACA,QAAS,CACP,QAAS,GACT,QAAS,CACP,MAAO,gBACP,IAAK,kBACP,CACF,CACF,EAEMC,GAA8C,CAClD,aAAc,MAEd,SAAU,CACR,UACA,QACA,OACA,OACA,QACA,OACA,QACA,QACA,WACA,WACA,UACA,SACA,KACA,SACA,OACA,OACA,SACA,UACA,QACA,QACA,UACA,QACA,MACA,WACA,OACA,KACA,aACA,SACA,KACA,aACA,MACA,YACA,OACA,SACA,MACA,OACA,UACA,UACA,YACA,SACA,SACA,QACA,SACA,QACA,SACA,eACA,OACA,QACA,SACA,YACA,OACA,MACA,SACA,MACA,OACA,WACA,QACA,MACF,EAEA,SAAU,CAAC,SAAU,UAAW,SAAU,WAAY,WAAW,EAEjE,UAAW,CACT,IACA,IACA,IACA,IACA,IACA,IACA,IACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,KACA,KACA,MACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,MACA,MACA,MACF,EAGA,SAAU,CACR,CAAE,KAAM,IAAK,MAAO,IAAK,MAAO,iBAAkB,EAClD,CAAE,KAAM,IAAK,MAAO,IAAK,MAAO,mBAAoB,EACpD,CAAE,KAAM,IAAK,MAAO,IAAK,MAAO,uBAAwB,CAC1D,EAGA,QAAS,6BACT,QAAS,8CACT,SAAU,mBAEV,UAAW,yBACX,UAAW,+EAEX,UAAW,CACT,KAAM,CAEJ,CACE,gCACA,CACE,MAAO,CACL,cAAe,CAAC,UAAW,QAAS,WAAW,EAC/C,GAAI,CAAC,iBAAkB,QAAS,WAAW,EAC3C,cAAe,CAAC,wBAAyB,QAAS,WAAW,EAC7D,WAAY,CAAC,aAAc,QAAS,WAAW,CACjD,CACF,CACF,EAGA,CAAE,QAAS,aAAc,EAGzB,CACE,yBACA,CAAE,MAAO,eAAgB,QAAS,QAAS,KAAM,SAAU,CAC7D,EAGA,CAAC,aA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"}