Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 60 additions & 1 deletion packages/viewer-datagrid/src/ts/custom_elements/datagrid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { sourceColumn } from "@perspective-dev/viewer/src/ts/column-format.js";

import type { View, ViewWindow } from "@perspective-dev/client";
import type {
HTMLPerspectiveViewerElement,
IPerspectiveViewerPlugin,
PluginStaticConfig,
} from "@perspective-dev/viewer";
Expand Down Expand Up @@ -73,6 +74,50 @@ export class HTMLPerspectiveViewerDatagridPluginElement
_reset_scroll_left?: boolean;
_reset_select?: boolean;
_reset_column_size?: boolean;
_columns_config: ColumnsConfig = {};

private _persist_column_sizes = (): void => {
if (!this.model || this.model._config.split_by?.length > 0) {
return;
}

const columns_config = structuredClone(this._columns_config);
for (const column of [...this.model._column_paths, "__ROW_PATH__"]) {
if (columns_config[column]) {
delete columns_config[column].column_size_override;
}
}

const overrides = save_column_size_overrides.call(this);
for (const [column, width] of Object.entries(overrides)) {
if (width !== undefined) {
columns_config[column] ??= {};
columns_config[column].column_size_override = width;
}
}

this._columns_config = columns_config;
const viewer = this.parentElement as HTMLPerspectiveViewerElement;
void viewer?.restore?.(
{ columns_config: JSON.parse(JSON.stringify(columns_config)) },
{ panel: this.model._panel },
);
};

private _on_column_resize = (event: MouseEvent): void => {
const is_resize = event.composedPath().some((target) => {
return (
target instanceof HTMLElement &&
target.classList.contains("rt-column-resize")
);
});

if (is_resize) {
document.addEventListener("mouseup", this._persist_column_sizes, {
once: true,
});
}
};

constructor() {
super();
Expand Down Expand Up @@ -101,6 +146,11 @@ export class HTMLPerspectiveViewerDatagridPluginElement
}

connectedCallback(): void {
this.regular_table.addEventListener(
"mousedown",
this._on_column_resize,
);

if (!this._toolbar) {
this._toolbar = document.createElement(
"perspective-viewer-datagrid-toolbar",
Expand All @@ -113,6 +163,11 @@ export class HTMLPerspectiveViewerDatagridPluginElement
}

disconnectedCallback(): void {
this.regular_table.removeEventListener(
"mousedown",
this._on_column_resize,
);
document.removeEventListener("mouseup", this._persist_column_sizes);
this._toolbar?.parentElement?.removeChild?.(this._toolbar);
}

Expand Down Expand Up @@ -173,7 +228,11 @@ export class HTMLPerspectiveViewerDatagridPluginElement
group: string | undefined,
column_name: string,
current_value: Record<string, unknown> | null,
viewer_config?: { group_by?: string[]; group_rollup_mode?: string },
viewer_config?: {
group_by?: string[];
split_by?: string[];
group_rollup_mode?: string;
},
column_stats?: { abs_max: number },
): ColumnConfigSchema {
return column_config_schema.call(
Expand Down
8 changes: 4 additions & 4 deletions packages/viewer-datagrid/src/ts/model/column_overrides.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ export function restore_column_size_overrides(
old_sizes: ColumnOverrides,
cache = false,
): void {
if (!this._initialized) {
return;
}

if (cache) {
this._cached_column_sizes = old_sizes;
}

if (!this._initialized) {
return;
}

const regular_table = this.regular_table as RegularTableWithOverrides;
const overrides: Record<number, number | undefined> = {
...regular_table.saveColumnSizes(),
Expand Down
10 changes: 10 additions & 0 deletions packages/viewer-datagrid/src/ts/plugin/column_config_schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type { ColumnConfig, DatagridPluginElement } from "../types.js";

interface ViewerConfigLike {
group_by?: string[];
split_by?: string[];
group_rollup_mode?: string;
}

Expand Down Expand Up @@ -53,6 +54,15 @@ export default function column_config_schema(
): ColumnConfigSchema {
const fields: ControlSpec[] = [];

if ((viewer_config?.split_by?.length ?? 0) === 0) {
fields.push({
kind: "Number",
key: "column_size_override" satisfies keyof ColumnConfig,
default: 0,
min: 1,
});
}

if (type === "integer" || type === "float") {
const pos_fg = this.model!._pos_fg_color[0];
const neg_fg = this.model!._neg_fg_color[0];
Expand Down
3 changes: 3 additions & 0 deletions packages/viewer-datagrid/src/ts/plugin/draw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ export async function draw(

restore_column_size_overrides.call(this, old_sizes);
await drawPromise;
if (Object.keys(old_sizes).length > 0) {
restore_column_size_overrides.call(this, old_sizes);
}

this._toolbar?.classList.toggle(
"aggregated",
Expand Down
12 changes: 7 additions & 5 deletions packages/viewer-datagrid/src/ts/plugin/restore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import type {
} from "../types.js";

interface RestoreToken {
columns?: Record<string, { column_size_override?: number }>;
edit_mode?: EditMode;
scroll_lock?: boolean;
}
Expand Down Expand Up @@ -59,15 +58,18 @@ export function restore(
columns = JSON.parse(JSON.stringify(columns));
const overrides: ColumnOverrides = {};

if (token.columns) {
for (const [col, value] of Object.entries(token.columns)) {
if (value.column_size_override !== undefined) {
for (const [col, value] of Object.entries(columns)) {
if (value.column_size_override !== undefined) {
if (!this.model?._config.split_by?.length) {
overrides[col] = value.column_size_override;
delete value["column_size_override"];
}

delete value.column_size_override;
}
}

this._columns_config = structuredClone(columns);

const styles: Record<string, StylesConfig> = {};
if (columns) {
for (const [col_name, controls] of Object.entries(columns)) {
Expand Down
14 changes: 0 additions & 14 deletions packages/viewer-datagrid/src/ts/plugin/save.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,17 @@
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

import { save_column_size_overrides } from "../model/column_overrides.js";
import type { DatagridPluginElement, DatagridPluginConfig } from "../types.js";

export function save(
this: DatagridPluginElement,
): DatagridPluginConfig | Record<string, never> {
if (this.regular_table) {
const token: DatagridPluginConfig = {
columns: {},
scroll_lock: !!this._is_scroll_lock,
edit_mode: this._edit_mode,
};

const column_size_overrides = save_column_size_overrides.call(this);

for (const col of Object.keys(column_size_overrides || {})) {
if (!token.columns?.[col]) {
token.columns = token.columns || {};
token.columns[col] = {};
}

token.columns[col].column_size_override =
column_size_overrides[col];
}

return JSON.parse(JSON.stringify(token));
}

Expand Down
7 changes: 1 addition & 6 deletions packages/viewer-datagrid/src/ts/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,6 @@ export type ColumnsConfig = Record<string, ColumnConfig>;
* `save()`/`restore()` token).
*/
export interface DatagridPluginConfig {
/**
* Per-column state keyed by column name, e.g.
* `{ "Sales": { "column_size_override": 180 } }`.
*/
columns?: ColumnsConfig;

/** Legacy alias for `edit_mode: "EDIT"`. */
editable?: boolean;

Expand Down Expand Up @@ -342,6 +336,7 @@ export type SortRotationOrder = Record<string, SortDir | undefined>;
export interface DatagridPluginElement extends HTMLElement {
regular_table: RegularTableElement;
model?: DatagridModel;
_columns_config: ColumnsConfig;
_toolbar?: DatagridToolbarElement;
_edit_button?: HTMLElement;
_scroll_lock?: HTMLElement;
Expand Down
66 changes: 61 additions & 5 deletions packages/viewer-datagrid/test/js/column_settings.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ test.describe("Datagrid Column Styles", function () {
});
});

test.skip("Interacting with column settings does not override column width", async function ({
test("Interacting with column settings does not override column width", async function ({
page,
}) {
const view = new PspViewer(page);
Expand All @@ -41,6 +41,14 @@ test.describe("Datagrid Column Styles", function () {
await page.mouse.down();
await page.mouse.move(pos!.x + 100, pos!.y + 5);
await page.mouse.up();
await page.waitForFunction(async () => {
const viewer = document.querySelector("perspective-viewer")!;
const token = await viewer.save();
return (
token.columns_config?.["Row ID"]?.column_size_override !==
undefined
);
});

const editBtn = view.dataGrid.regularTable.editBtnRow
.locator("th.psp-menu-enabled span")
Expand All @@ -54,16 +62,64 @@ test.describe("Datagrid Column Styles", function () {
const token = await view.save();
test.expect(token.columns_config).toEqual({
"Row ID": {
column_size_override: 150,
number_string_format: {
style: "percent",
},
},
});
test.expect(token.plugin_config.columns).toEqual({
"Row ID": {
column_size_override: 150,
},
test.expect(token.plugin_config.columns).toBeUndefined();
});

test("First restore applies and preserves column width overrides", async function ({
page,
}) {
const result = await page.evaluate(async () => {
const viewer = document.querySelector("perspective-viewer")!;
await viewer.restore({
plugin: "Datagrid",
columns: ["Row ID", "Sales"],
columns_config: {
Sales: { column_size_override: 311.1875 },
},
});

const plugin = document.querySelector(
"perspective-viewer-datagrid",
) as any;
const index = plugin.model._column_paths.indexOf("Sales");
const widths = plugin.regular_table.saveColumnSizes();

return {
config: (await viewer.save()).columns_config,
width: widths[index],
};
});

expect(result.config).toEqual({
Sales: { column_size_override: 311.1875 },
});
expect(result.width).toBe(311.1875);
});

test("Column width persistence is disabled with split-by", async function ({
page,
}) {
const result = await page.evaluate(async () => {
const viewer = document.querySelector("perspective-viewer")!;
await viewer.restore({
plugin: "Datagrid",
columns: ["Row ID", "Sales"],
split_by: ["Category"],
columns_config: {
Sales: { column_size_override: 311.1875 },
},
});

return (await viewer.save()).columns_config?.Sales;
});

expect(result?.column_size_override).toBeUndefined();
});
});

Expand Down