diff --git a/examples/blocks/src/market/market.js b/examples/blocks/src/market/market.js index 2267848d8d..3d97a420d6 100644 --- a/examples/blocks/src/market/market.js +++ b/examples/blocks/src/market/market.js @@ -255,7 +255,7 @@ async function init_tables() { name: "gui", }); - return { market_table, gui_table }; + return { market_table, gui_table, gui_worker }; } async function init_layouts() { @@ -265,13 +265,14 @@ async function init_layouts() { const INIT_TASK = [init_tables(), init_layouts()]; -const [{ market_table, gui_table }, layouts] = await Promise.all(INIT_TASK); +const [{ market_table, gui_table, gui_worker }, layouts] = + await Promise.all(INIT_TASK); const market = new Market(market_table, skew_model); const settings = !/(iPad|iPhone|iPod)/g.test(navigator.userAgent); const select = document.querySelector("select"); const button = document.querySelector("button"); const viewer = document.querySelector("perspective-viewer"); -viewer.load(gui_table); +viewer.load(gui_worker); viewer.restore({ theme: "Pro Dark", table: "gui", settings, ...layouts[0] }); await market.poll(progress); for (const layout of layouts) { diff --git a/packages/viewer-datagrid/src/ts/color_utils.ts b/packages/viewer-datagrid/src/ts/color_utils.ts index aac279abe4..c935bd2934 100644 --- a/packages/viewer-datagrid/src/ts/color_utils.ts +++ b/packages/viewer-datagrid/src/ts/color_utils.ts @@ -57,7 +57,6 @@ export function make_color_record(color: string): ColorRecord { const chroma_neg = chroma(color); const _neg_grad = make_gradient(chroma_neg); const rgb = chroma_neg.rgb(); - return [ color, rgb[0], diff --git a/packages/viewer-datagrid/src/ts/event_handlers/click/edit_click.ts b/packages/viewer-datagrid/src/ts/event_handlers/click/edit_click.ts index bfe1e2c3bb..f83cc403a7 100644 --- a/packages/viewer-datagrid/src/ts/event_handlers/click/edit_click.ts +++ b/packages/viewer-datagrid/src/ts/event_handlers/click/edit_click.ts @@ -10,10 +10,12 @@ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ -import type { - RegularTable, - DatagridModel, - PerspectiveViewerElement, +import { CellMetadataBody } from "regular-table/dist/esm/types.js"; +import { + type RegularTable, + type DatagridModel, + type PerspectiveViewerElement, + get_psp_type, } from "../../types.js"; export function write_cell( @@ -21,13 +23,13 @@ export function write_cell( model: DatagridModel, active_cell: HTMLElement, ): boolean { - const meta = table.getMeta(active_cell); + const meta = table.getMeta(active_cell) as CellMetadataBody; if (!meta) { return false; } - const type = model._schema[model._column_paths[meta.x]]; + const type = model._schema[model._column_paths[meta.x!]]; let text: string | number | boolean | null = active_cell.textContent || ""; - const id = model._ids[meta.y - meta.y0][0]; + const id = model._ids[meta.y! - meta.y0][0]; if (type === "float" || type === "integer") { const parsed = parseFloat(text.replace(/,/g, "")); if (isNaN(parsed)) { @@ -59,13 +61,14 @@ export function clickListener( _viewer: PerspectiveViewerElement, event: MouseEvent, ): void { - const meta = table.getMeta(event.target as Element); - if (typeof meta?.x !== "undefined") { + const meta = table.getMeta(event.target as HTMLElement); + if (meta?.type === "body" || meta?.type === "column_header") { const is_editable2 = this._is_editable[meta.x]; - const is_bool = this.get_psp_type(meta) === "boolean"; + const is_bool = get_psp_type(this, meta) === "boolean"; const is_null = (event.target as Element).classList.contains( "psp-null", ); + if (is_editable2 && is_bool && !is_null) { write_cell(table, this, event.target as HTMLElement); } diff --git a/packages/viewer-datagrid/src/ts/event_handlers/dispatch_click.ts b/packages/viewer-datagrid/src/ts/event_handlers/dispatch_click.ts index 659efe6275..c82ef347b2 100644 --- a/packages/viewer-datagrid/src/ts/event_handlers/dispatch_click.ts +++ b/packages/viewer-datagrid/src/ts/event_handlers/dispatch_click.ts @@ -24,12 +24,10 @@ export async function dispatch_click_listener( viewer: PerspectiveViewerElement, event: MouseEvent, ): Promise { - const meta = table.getMeta(event.target as Element); - if (!meta) return; + const meta = table.getMeta(event.target as HTMLElement); + if (!meta || meta.type !== "body") return; const { x, y } = meta; - const { row, column_names, config } = await getCellConfig(this, y, x); - viewer.dispatchEvent( new CustomEvent("perspective-click", { bubbles: true, diff --git a/packages/viewer-datagrid/src/ts/event_handlers/expand_collapse.ts b/packages/viewer-datagrid/src/ts/event_handlers/expand_collapse.ts index 233700202f..b04b46a83d 100644 --- a/packages/viewer-datagrid/src/ts/event_handlers/expand_collapse.ts +++ b/packages/viewer-datagrid/src/ts/event_handlers/expand_collapse.ts @@ -17,12 +17,12 @@ export async function expandCollapseHandler( regularTable: RegularTable, event: MouseEvent, ): Promise { - const meta = regularTable.getMeta(event.target as Element); - if (!meta?.row_header) return; - + const meta = regularTable.getMeta(event.target as HTMLElement); + if (!meta || meta.type !== "row_header") return; const is_collapse = (event.target as Element).classList.contains( "psp-tree-label-collapse", ); + if (event.shiftKey && is_collapse) { this._view.set_depth( (meta.row_header as unknown[]).filter((x) => x !== undefined) @@ -38,6 +38,7 @@ export async function expandCollapseHandler( } else { this._view.expand(meta.y); } + this._num_rows = await this._view.num_rows(); this._num_columns = await this._view.num_columns(); regularTable.draw(); diff --git a/packages/viewer-datagrid/src/ts/event_handlers/focus.ts b/packages/viewer-datagrid/src/ts/event_handlers/focus.ts index 955a9b1682..d6f4ba34b6 100644 --- a/packages/viewer-datagrid/src/ts/event_handlers/focus.ts +++ b/packages/viewer-datagrid/src/ts/event_handlers/focus.ts @@ -52,7 +52,7 @@ export function focusinListener( ): void { const target = event.target as HTMLElement; const meta = table.getMeta(target); - if (meta) { + if (meta?.type === "body") { const new_state: SelectedPosition = { x: meta.x, y: meta.y, diff --git a/packages/viewer-datagrid/src/ts/event_handlers/header_click.ts b/packages/viewer-datagrid/src/ts/event_handlers/header_click.ts index 03a21977b3..5a4eded6c0 100644 --- a/packages/viewer-datagrid/src/ts/event_handlers/header_click.ts +++ b/packages/viewer-datagrid/src/ts/event_handlers/header_click.ts @@ -50,7 +50,7 @@ export async function mousedown_listener( if (target.classList.contains("psp-menu-enabled")) { const meta = regularTable.getMeta(target); const column_name = meta?.column_header?.[this._config.split_by.length]; - await viewer.toggleColumnSettings(column_name); + await viewer.toggleColumnSettings(`${column_name}`); } else if (target.classList.contains("psp-sort-enabled")) { sortHandler.call(this, regularTable, viewer, event, target); } diff --git a/packages/viewer-datagrid/src/ts/event_handlers/keydown/edit_keydown.ts b/packages/viewer-datagrid/src/ts/event_handlers/keydown/edit_keydown.ts index 6c09c3f762..cd0cddbc58 100644 --- a/packages/viewer-datagrid/src/ts/event_handlers/keydown/edit_keydown.ts +++ b/packages/viewer-datagrid/src/ts/event_handlers/keydown/edit_keydown.ts @@ -76,7 +76,7 @@ const moveSelection = lock(async function ( dy: number, ): Promise { const meta = table.getMeta(active_cell); - if (!meta) return; + if (!meta || meta.type !== "body") return; const num_columns = this._column_paths.length; const num_rows = this._num_rows; const selected_position = selected_position_map.get(table); @@ -118,7 +118,7 @@ function isLastCell( target: HTMLElement, ): boolean { const meta = table.getMeta(target); - return meta !== undefined && meta.y === model._num_rows - 1; + return meta?.type === "body" && meta.y === model._num_rows - 1; } export function keydownListener( diff --git a/packages/viewer-datagrid/src/ts/event_handlers/row_select_click.ts b/packages/viewer-datagrid/src/ts/event_handlers/row_select_click.ts index 303f245c4c..193e00210a 100644 --- a/packages/viewer-datagrid/src/ts/event_handlers/row_select_click.ts +++ b/packages/viewer-datagrid/src/ts/event_handlers/row_select_click.ts @@ -28,21 +28,22 @@ export async function selectionListener( selected_rows_map: SelectedRowsMap, event: HandledMouseEvent, ): Promise { - const meta = regularTable.getMeta(event.target as Element); + const meta = regularTable.getMeta(event.target as HTMLElement); if (!viewer.hasAttribute("selectable")) return; if (event.handled) return; if (event.shiftKey) return; if (event.button !== 0) { return; } + event.stopImmediatePropagation(); if (!meta) { return; } - const id = this._ids?.[meta.y - meta.y0]; - if (meta && meta.y >= 0) { + if ((meta.type === "body" || meta.type === "row_header") && meta.y >= 0) { + const id = this._ids?.[meta.y - meta.y0]; const selected = selected_rows_map.get(regularTable); const key_match = !!selected && @@ -56,10 +57,11 @@ export async function selectionListener( row: {}, config: { filter: [] }, }; + const { row, column_names, config } = await getCellConfig( this, meta.y, - meta.x, + meta.type === "body" ? meta.x : 0, ); if (is_deselect) { diff --git a/packages/viewer-datagrid/src/ts/event_handlers/select_region.ts b/packages/viewer-datagrid/src/ts/event_handlers/select_region.ts index 3d17509f30..40f5276fbe 100644 --- a/packages/viewer-datagrid/src/ts/event_handlers/select_region.ts +++ b/packages/viewer-datagrid/src/ts/event_handlers/select_region.ts @@ -75,8 +75,12 @@ const getMousedownListener = datagrid.model!._edit_mode === "SELECT_COLUMN") ) { datagrid.model!._selection_state.CURRENT_MOUSEDOWN_COORDINATES = {}; - const meta = table.getMeta(mouseEvent.target as Element); - if (meta && meta.x !== undefined && meta.y !== undefined) { + const meta = table.getMeta(mouseEvent.target as HTMLElement); + if ( + meta?.type === "body" && + meta.x !== undefined && + meta.y !== undefined + ) { datagrid.model!._selection_state.CURRENT_MOUSEDOWN_COORDINATES = { x: meta.x, @@ -129,8 +133,12 @@ const getMouseoverListener = datagrid.model!._selection_state.CURRENT_MOUSEDOWN_COORDINATES .x !== undefined ) { - const meta = table.getMeta(mouseEvent.target as Element); - if (meta && meta.x !== undefined && meta.y !== undefined) { + const meta = table.getMeta(mouseEvent.target as HTMLElement); + if ( + meta?.type === "body" && + meta.x !== undefined && + meta.y !== undefined + ) { const potentialSelection: SelectionArea = { x0: Math.min( meta.x, @@ -183,7 +191,7 @@ const getMouseupListener = datagrid.model!._edit_mode === "SELECT_ROW" || datagrid.model!._edit_mode === "SELECT_COLUMN" ) { - const meta = table.getMeta(mouseEvent.target as Element); + const meta = table.getMeta(mouseEvent.target as HTMLElement); if (!meta) return; if ( @@ -195,6 +203,7 @@ const getMouseupListener = if ( selected.x0 === selected.x1 && selected.y0 === selected.y1 && + meta?.type === "body" && selected.x0 === meta.x && selected.y0 === meta.y ) { @@ -216,6 +225,7 @@ const getMouseupListener = .CURRENT_MOUSEDOWN_COORDINATES && datagrid.model!._selection_state.CURRENT_MOUSEDOWN_COORDINATES .x !== undefined && + meta?.type === "body" && meta.x !== undefined && meta.y !== undefined ) { @@ -338,8 +348,8 @@ const applyMouseAreaSelection = ( const tds = table.querySelectorAll("tbody td"); for (const td of tds) { - const meta = table.getMeta(td); - if (!meta) continue; + const meta = table.getMeta(td as HTMLElement); + if (!meta || meta.type !== "body") continue; let rendered = false; for (const { x0, x1, y0, y1 } of selected) { if ( @@ -372,7 +382,7 @@ const applyMouseAreaSelection = ( const tds = table.querySelectorAll("tbody td"); for (const td of tds) { - const meta = table.getMeta(td); + const meta = table.getMeta(td as HTMLElement); if (!meta) continue; let rendered = false; for (const { x0, x1, y0, y1 } of selected) { @@ -380,7 +390,8 @@ const applyMouseAreaSelection = ( x0 !== undefined && y0 !== undefined && x1 !== undefined && - y1 !== undefined + y1 !== undefined && + meta?.type === "body" ) { if (y0 <= meta.y && meta.y <= y1) { datagrid.model!._selection_state.dirty = true; @@ -401,7 +412,7 @@ const applyMouseAreaSelection = ( const tds = table.querySelectorAll("tbody td"); for (const td of tds) { - const meta = table.getMeta(td); + const meta = table.getMeta(td as HTMLElement); if (!meta) continue; let rendered = false; for (const { x0, x1, y0, y1 } of selected) { @@ -409,7 +420,8 @@ const applyMouseAreaSelection = ( x0 !== undefined && y0 !== undefined && x1 !== undefined && - y1 !== undefined + y1 !== undefined && + meta?.type === "body" ) { if (x0 <= meta.x && meta.x <= x1) { datagrid.model!._selection_state.dirty = true; diff --git a/packages/viewer-datagrid/src/ts/event_handlers/sort.ts b/packages/viewer-datagrid/src/ts/event_handlers/sort.ts index 8c0ddc7700..b4965cd540 100644 --- a/packages/viewer-datagrid/src/ts/event_handlers/sort.ts +++ b/packages/viewer-datagrid/src/ts/event_handlers/sort.ts @@ -55,7 +55,7 @@ export async function sortHandler( : override_sort; const abs = event.shiftKey; - const sort = sort_method.call(this, column_name, abs); + const sort = sort_method.call(this, `${column_name}`, abs); await viewer.restore({ sort }); } diff --git a/packages/viewer-datagrid/src/ts/get_cell_config.ts b/packages/viewer-datagrid/src/ts/get_cell_config.ts index 602cb8a05b..10e756e1fb 100644 --- a/packages/viewer-datagrid/src/ts/get_cell_config.ts +++ b/packages/viewer-datagrid/src/ts/get_cell_config.ts @@ -49,6 +49,7 @@ export default async function getCellConfig( column_names: [], config: { filter: [] }, }; + let column_filters: Filter[] = []; if (column_paths) { const split_by_values = column_paths.split("|"); diff --git a/packages/viewer-datagrid/src/ts/model/create.ts b/packages/viewer-datagrid/src/ts/model/create.ts index 76915d3a93..c81dfc9990 100644 --- a/packages/viewer-datagrid/src/ts/model/create.ts +++ b/packages/viewer-datagrid/src/ts/model/create.ts @@ -19,16 +19,17 @@ import type { View, ViewConfig, } from "@perspective-dev/client"; -import type { - DatagridModel, - DatagridPluginElement, - RegularTable, - Schema, - CellMeta, - ElemFactory, - EditMode, - PerspectiveViewerElement, +import { + type DatagridModel, + type DatagridPluginElement, + type RegularTable, + type Schema, + type ElemFactory, + type EditMode, + type PerspectiveViewerElement, + get_psp_type, } from "../types.js"; +import { CellMetadata } from "regular-table/dist/esm/types.js"; function get_rule(regular: HTMLElement, tag: string, def: string): string { const color = window.getComputedStyle(regular).getPropertyValue(tag).trim(); @@ -64,14 +65,6 @@ class ElemFactoryImpl implements ElemFactory { } } -function get_psp_type(this: DatagridModel, metadata: CellMeta): ColumnType { - if (metadata.x !== undefined && metadata.x >= 0) { - return this._column_types[metadata.x]; - } else { - return this._row_header_types[metadata.row_header_x! - 1]; - } -} - export async function createModel( this: DatagridPluginElement, regular: RegularTable, @@ -222,7 +215,7 @@ export async function createModel( }), _series_color_map: new Map(), _series_color_seed: new Map(), - get_psp_type, + // get_psp_type, _div_factory: extend._div_factory || new ElemFactoryImpl("div"), }) as DatagridModel; diff --git a/packages/viewer-datagrid/src/ts/style_handlers/body.ts b/packages/viewer-datagrid/src/ts/style_handlers/body.ts index 6c479401f3..91023b8ccf 100644 --- a/packages/viewer-datagrid/src/ts/style_handlers/body.ts +++ b/packages/viewer-datagrid/src/ts/style_handlers/body.ts @@ -12,11 +12,12 @@ import { RegularTableElement } from "regular-table"; -import type { - DatagridModel, - PerspectiveViewerElement, - ColumnsConfig, - DatagridPluginElement, +import { + type DatagridModel, + type PerspectiveViewerElement, + type ColumnsConfig, + type DatagridPluginElement, + get_psp_type, } from "../types.js"; import { cell_style_numeric } from "./table_cell/numeric.js"; @@ -28,20 +29,7 @@ import { CollectedCell, LocalSelectedPositionMap, LocalSelectedRowsMap, - CellMetaExtended, } from "./types.js"; -import { ColumnType } from "@perspective-dev/client"; - -function get_psp_type( - model: DatagridModel, - metadata: CellMetaExtended, -): ColumnType { - if (metadata.x !== undefined && metadata.x >= 0) { - return model._column_types[metadata.x]; - } else { - return model._row_header_types[(metadata.row_header_x ?? 0) - 1]; - } -} /** * Apply styles to all body cells in a single pass. @@ -71,6 +59,7 @@ export function applyBodyCellStyles( const is_numeric = type === "integer" || type === "float"; // Calculate aggregate depth visibility + // @ts-ignore metadata._is_hidden_by_aggregate_depth = ((x?: number) => x === 0 || x === undefined ? false @@ -109,6 +98,7 @@ export function applyBodyCellStyles( "psp-bool-type", type === "boolean" && metadata.user !== null, ); + td.classList.toggle("psp-null", metadata.value === null); td.classList.toggle("psp-align-right", !isHeader && is_numeric); td.classList.toggle("psp-align-left", isHeader || !is_numeric); @@ -138,14 +128,18 @@ export function applyBodyCellStyles( } if ( - metadata.row_header_x === undefined || + metadata.type !== "row_header" || metadata.row_header_x === (metadata.row_header as unknown[]).length - 1 || (metadata.row_header as unknown[])[metadata.row_header_x + 1] === undefined ) { td.dataset.y = String(metadata.y); - td.dataset.x = String(metadata.x); + if (metadata.type !== "row_header") { + td.dataset.x = String(metadata.x); + } else { + delete td.dataset.x; + } } else { delete td.dataset.y; delete td.dataset.x; @@ -166,6 +160,7 @@ export function applyBodyCellStyles( const selectedArr = selected as unknown[]; if (isHeader) { if ( + metadata.type === "row_header" && metadata.row_header_x !== undefined && !!id[metadata.row_header_x] ) { @@ -195,7 +190,7 @@ export function applyBodyCellStyles( } // Apply editable styling (if editable) - if (!isHeader && metadata.x !== undefined) { + if (!isHeader && metadata.type === "body") { if (isEditable && this._is_editable[metadata.x]) { const col_name = metadata.column_header?.[this._config.split_by.length]; diff --git a/packages/viewer-datagrid/src/ts/style_handlers/column_header.ts b/packages/viewer-datagrid/src/ts/style_handlers/column_header.ts index ba11f76d05..e68d7ba9e0 100644 --- a/packages/viewer-datagrid/src/ts/style_handlers/column_header.ts +++ b/packages/viewer-datagrid/src/ts/style_handlers/column_header.ts @@ -11,7 +11,11 @@ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ import { RegularTableElement } from "regular-table"; -import type { DatagridModel, PerspectiveViewerElement } from "../types.js"; +import { + get_psp_type, + type DatagridModel, + type PerspectiveViewerElement, +} from "../types.js"; import { CollectedHeaderRow } from "./types.js"; /** @@ -97,12 +101,19 @@ export function styleColumnHeaderRow( const selectedColumn = this._column_settings_selected_column; for (const { element: td, metadata } of headerRow.cells) { - if (!metadata) continue; + if ( + !metadata || + metadata.type === "body" || + metadata.type === "row_header" + ) + continue; const column_name = metadata.column_header?.[this._config.split_by.length]; const sort = this._config.sort.find((x) => x[0] === column_name); - let needs_border = metadata.row_header_x === header_depth; + let needs_border = + metadata.type === "corner" && + metadata.row_header_x === header_depth; const is_corner = typeof metadata.x === "undefined"; needs_border = needs_border || @@ -147,7 +158,7 @@ export function styleColumnHeaderRow( !is_menu_row && !!sort && sort[1] === "col desc abs", ); - const type = this.get_psp_type(metadata); + const type = get_psp_type(this, metadata); const is_numeric = type === "integer" || type === "float"; const is_string = type === "string"; const is_date = type === "date"; diff --git a/packages/viewer-datagrid/src/ts/style_handlers/consolidated.ts b/packages/viewer-datagrid/src/ts/style_handlers/consolidated.ts index 7a51bbc0a3..1dc10b65a5 100644 --- a/packages/viewer-datagrid/src/ts/style_handlers/consolidated.ts +++ b/packages/viewer-datagrid/src/ts/style_handlers/consolidated.ts @@ -11,8 +11,6 @@ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ import { RegularTableElement } from "regular-table"; -import { CellMetadata } from "regular-table/dist/esm/types.js"; -import { ColumnType } from "@perspective-dev/client"; import { PRIVATE_PLUGIN_SYMBOL } from "../model/index.js"; import type { DatagridModel, @@ -27,14 +25,11 @@ import { styleColumnHeaderRow } from "./column_header.js"; import { applyColumnHeaderStyles } from "./editable.js"; import { applyGroupHeaderStyles } from "./group_header.js"; import { applyBodyCellStyles } from "./body.js"; - -interface CellMetaExtended extends CellMetadata { - _is_hidden_by_aggregate_depth?: boolean; -} +import { CellMetadata } from "regular-table/dist/esm/types.js"; interface CollectedCell { element: HTMLElement; - metadata: CellMetaExtended; + metadata: CellMetadata; isHeader: boolean; } @@ -118,9 +113,9 @@ export function createConsolidatedStyleListener( if (tbody) { for (const tr of tbody.children) { for (const cell of tr.children) { - const metadata = regularTable.getMeta(cell) as - | CellMetaExtended - | undefined; + const metadata = regularTable.getMeta( + cell as HTMLElement, + ) as CellMetadata | undefined; if (metadata) { const isHeader = cell.tagName === "TH"; @@ -144,9 +139,9 @@ export function createConsolidatedStyleListener( }; for (const cell of tr.children) { - const metadata = regularTable.getMeta(cell) as - | CellMetadata - | undefined; + const metadata = regularTable.getMeta( + cell as HTMLElement, + ) as CellMetadata | undefined; rowData.cells.push({ element: cell as HTMLTableCellElement, diff --git a/packages/viewer-datagrid/src/ts/style_handlers/focus.ts b/packages/viewer-datagrid/src/ts/style_handlers/focus.ts index 1b8f056c03..71cfa3021d 100644 --- a/packages/viewer-datagrid/src/ts/style_handlers/focus.ts +++ b/packages/viewer-datagrid/src/ts/style_handlers/focus.ts @@ -12,12 +12,7 @@ import { RegularTableElement } from "regular-table"; import type { DatagridModel, SelectedPosition } from "../types.js"; - -import { - CollectedCell, - LocalSelectedPositionMap, - CellMetaExtended, -} from "./types.js"; +import { CollectedCell, LocalSelectedPositionMap } from "./types.js"; /** * Apply focus style to the selected cell. @@ -35,6 +30,7 @@ export function applyFocusStyle( if (selected_position) { for (const { element: td, metadata } of cells) { if ( + metadata.type === "body" && metadata.x === selected_position.x && metadata.y === selected_position.y ) { @@ -77,11 +73,9 @@ export function focusSelectedCell( if (tbody) { for (const tr of tbody.children) { for (const cell of tr.children) { - const metadata = regularTable.getMeta(cell) as - | CellMetaExtended - | undefined; + const metadata = regularTable.getMeta(cell as HTMLElement); if ( - metadata && + metadata?.type === "body" && metadata.x === selected_position.x && metadata.y === selected_position.y ) { diff --git a/packages/viewer-datagrid/src/ts/style_handlers/group_header.ts b/packages/viewer-datagrid/src/ts/style_handlers/group_header.ts index 6bf5901d92..00befe849b 100644 --- a/packages/viewer-datagrid/src/ts/style_handlers/group_header.ts +++ b/packages/viewer-datagrid/src/ts/style_handlers/group_header.ts @@ -38,8 +38,10 @@ export function applyGroupHeaderStyles( td.style.backgroundColor = ""; const needs_border = - (header_depth > 0 && metadata.row_header_x === header_depth) || - (metadata.x ?? -1) >= 0; + (metadata.type === "corner" && + header_depth > 0 && + metadata.row_header_x === header_depth) || + (metadata.type === "column_header" && metadata.x >= 0); td.classList.toggle("psp-align-right", false); td.classList.toggle("psp-align-left", false); @@ -48,8 +50,9 @@ export function applyGroupHeaderStyles( td.classList.toggle("psp-header-border", needs_border); td.classList.toggle( "psp-header-group-corner", - typeof metadata.x === "undefined", + metadata.type === "corner", ); + td.classList.toggle("psp-color-mode-bar", false); td.classList.toggle("psp-header-sort-asc", false); td.classList.toggle("psp-header-sort-desc", false); diff --git a/packages/viewer-datagrid/src/ts/style_handlers/table_cell/boolean.ts b/packages/viewer-datagrid/src/ts/style_handlers/table_cell/boolean.ts index d772d9defc..d11d6ac959 100644 --- a/packages/viewer-datagrid/src/ts/style_handlers/table_cell/boolean.ts +++ b/packages/viewer-datagrid/src/ts/style_handlers/table_cell/boolean.ts @@ -13,16 +13,13 @@ import { CellMetadata } from "regular-table/dist/esm/types.js"; import type { DatagridModel, ColumnConfig, ColorRecord } from "../../types.js"; -interface CellMetaWithFlags extends CellMetadata { - _is_hidden_by_aggregate_depth?: boolean; -} - export function cell_style_boolean( this: DatagridModel, _plugin: ColumnConfig | undefined, td: HTMLElement, - metadata: CellMetaWithFlags, + metadata: CellMetadata, ): void { + // @ts-ignore if (metadata._is_hidden_by_aggregate_depth) { td.style.backgroundColor = ""; td.style.color = ""; diff --git a/packages/viewer-datagrid/src/ts/style_handlers/table_cell/cell_flash.ts b/packages/viewer-datagrid/src/ts/style_handlers/table_cell/cell_flash.ts index 1b1190da88..90f23cca3e 100644 --- a/packages/viewer-datagrid/src/ts/style_handlers/table_cell/cell_flash.ts +++ b/packages/viewer-datagrid/src/ts/style_handlers/table_cell/cell_flash.ts @@ -10,12 +10,12 @@ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ -import { CellMetadata } from "regular-table/dist/esm/types.js"; +import { CellMetadataBody } from "regular-table/dist/esm/types.js"; import type { DatagridModel, ColorRecord } from "../../types.js"; export function style_cell_flash( this: DatagridModel, - metadata: CellMetadata, + metadata: CellMetadataBody, td: HTMLElement, [, , , , , pos_s, pos_e]: ColorRecord, [, , , , , neg_s, neg_e]: ColorRecord, diff --git a/packages/viewer-datagrid/src/ts/style_handlers/table_cell/datetime.ts b/packages/viewer-datagrid/src/ts/style_handlers/table_cell/datetime.ts index 7366f8a0f1..37764db082 100644 --- a/packages/viewer-datagrid/src/ts/style_handlers/table_cell/datetime.ts +++ b/packages/viewer-datagrid/src/ts/style_handlers/table_cell/datetime.ts @@ -17,15 +17,11 @@ import { } from "../../color_utils.js"; import type { DatagridModel, ColumnConfig, ColorRecord } from "../../types.js"; -interface CellMetaWithFlags extends CellMetadata { - _is_hidden_by_aggregate_depth?: boolean; -} - export function cell_style_datetime( this: DatagridModel, plugin: ColumnConfig, td: HTMLElement, - metadata: CellMetaWithFlags, + metadata: CellMetadata, ): void { const colorRecord: ColorRecord = //(() => { // if (plugin?.color !== undefined) { @@ -38,6 +34,7 @@ export function cell_style_datetime( const [hex, r, g, b] = colorRecord; + // @ts-ignore if (metadata._is_hidden_by_aggregate_depth) { td.style.backgroundColor = ""; td.style.color = ""; diff --git a/packages/viewer-datagrid/src/ts/style_handlers/table_cell/row_header.ts b/packages/viewer-datagrid/src/ts/style_handlers/table_cell/row_header.ts index fed00dc875..ed60f62dc5 100644 --- a/packages/viewer-datagrid/src/ts/style_handlers/table_cell/row_header.ts +++ b/packages/viewer-datagrid/src/ts/style_handlers/table_cell/row_header.ts @@ -10,19 +10,18 @@ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ -import { CellMetadata } from "regular-table/dist/esm/types.js"; +import { + CellMetadata, + CellMetadataRowHeader, +} from "regular-table/dist/esm/types.js"; import type { DatagridModel } from "../../types.js"; import { RegularTableElement } from "regular-table"; -interface NextMeta { - row_header?: unknown[]; -} - export function cell_style_row_header( this: DatagridModel, regularTable: RegularTableElement, td: HTMLElement, - metadata: CellMetadata, + metadata: CellMetadataRowHeader, ): void { const is_not_empty = metadata.value !== undefined && @@ -33,12 +32,14 @@ export function cell_style_row_header( const next = regularTable.getMeta({ dx: 0, dy: (metadata.y ?? 0) - (metadata.y0 ?? 0) + 1, - } as unknown as Element) as NextMeta | undefined; + } as CellMetadata); + const is_collapse = next && next.row_header && typeof next.row_header[(metadata.row_header_x ?? 0) + 1] !== "undefined"; + td.classList.toggle("psp-tree-label", is_not_empty && !is_leaf); td.classList.toggle( "psp-tree-label-expand", diff --git a/packages/viewer-datagrid/src/ts/style_handlers/types.ts b/packages/viewer-datagrid/src/ts/style_handlers/types.ts index 4182b5c945..f57cac0d2e 100644 --- a/packages/viewer-datagrid/src/ts/style_handlers/types.ts +++ b/packages/viewer-datagrid/src/ts/style_handlers/types.ts @@ -11,16 +11,16 @@ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ import { RegularTableElement } from "regular-table"; -import { CellMetadata } from "regular-table/dist/esm/types.js"; +import { + CellMetadata, + CellMetadataBody, + CellMetadataRowHeader, +} from "regular-table/dist/esm/types.js"; import type { SelectedPosition } from "../types.js"; -export interface CellMetaExtended extends CellMetadata { - _is_hidden_by_aggregate_depth?: boolean; -} - export interface CollectedCell { element: HTMLElement; - metadata: CellMetaExtended; + metadata: CellMetadataRowHeader | CellMetadataBody; isHeader: boolean; } diff --git a/packages/viewer-datagrid/src/ts/types.ts b/packages/viewer-datagrid/src/ts/types.ts index df6cfb1b63..fb0dede2c6 100644 --- a/packages/viewer-datagrid/src/ts/types.ts +++ b/packages/viewer-datagrid/src/ts/types.ts @@ -23,7 +23,21 @@ import { CellMetadata, DataResponse } from "regular-table/dist/esm/types"; // Re-export types from regular-table for use throughout the codebase export type { RegularTableElement as RegularTable }; -export type { CellMetadata as CellMeta }; + +export function get_psp_type( + model: DatagridModel, + metadata: CellMetadata, +): ColumnType { + if ( + metadata.type === "body" || + metadata.type === "column_header" || + metadata.type === "corner" + ) { + return model._column_types[metadata.x]; + } else { + return model._row_header_types[(metadata.row_header_x ?? 0) - 1]; + } +} // Edit mode for the datagrid export type EditMode = diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bd82f8747a..9c5f433b72 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -154,8 +154,8 @@ catalogs: specifier: ^18 version: 18.3.1 regular-table: - specifier: '=0.8.0' - version: 0.8.0 + specifier: '=0.8.1' + version: 0.8.1 stoppable: specifier: '=1.1.0' version: 1.1.0 @@ -813,7 +813,7 @@ importers: version: 3.1.2 regular-table: specifier: 'catalog:' - version: 0.8.0 + version: 0.8.1 devDependencies: '@perspective-dev/esbuild-plugin': specifier: 'workspace:' @@ -7794,8 +7794,8 @@ packages: resolution: {integrity: sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==} hasBin: true - regular-table@0.8.0: - resolution: {integrity: sha512-J0MnudDsbIkPQ5cW0Xo0DV/vb+kPr7R74I4oN++tM+KBssRKnbwvJSzczLmpsboXg6gNBbJI8zTVwk78NZX8pg==} + regular-table@0.8.1: + resolution: {integrity: sha512-+HZgc1CFER+M5dFhsL5MYEU6WKRhLwxRT85h7OCJM0kfuZiYZBi2kSH4/HRc4aCNGiczQbp1EvuEhTgjSdBl7w==} engines: {node: '>=16'} rehype-raw@7.0.0: @@ -17727,7 +17727,7 @@ snapshots: dependencies: jsesc: 3.1.0 - regular-table@0.8.0: {} + regular-table@0.8.1: {} rehype-raw@7.0.0: dependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 9cfeed061d..099630e602 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -39,7 +39,7 @@ catalog: "pro_self_extracting_wasm": "0.0.9" "react-dom": "^18" "react": "^18" - "regular-table": "=0.8.0" + "regular-table": "=0.8.1" "stoppable": "=1.1.0" "ws": "^8.17.0" diff --git a/rust/perspective-js/test/js/multi_server.spec.js b/rust/perspective-js/test/js/multi_server.spec.js index 26e4687f6b..31ac348f10 100644 --- a/rust/perspective-js/test/js/multi_server.spec.js +++ b/rust/perspective-js/test/js/multi_server.spec.js @@ -51,7 +51,10 @@ import perspective from "./perspective_client"; const view0 = await table0.view(); const table1 = await worker1.table(view0); const view1 = await table1.view(); + const { promise, resolve } = Promise.withResolvers(); + await view1.on_update(() => resolve()); await table0.update([{ x: 6 }]); + await promise; const json0 = await view0.to_json(); const json1 = await view1.to_json(); return [json0, json1]; diff --git a/tools/test/results.tar.gz b/tools/test/results.tar.gz index 2af5bde41b..df0165f9f0 100644 Binary files a/tools/test/results.tar.gz and b/tools/test/results.tar.gz differ