diff --git a/packages/dgrid-shim/src/gridHelper.ts b/packages/dgrid-shim/src/gridHelper.ts index adea1d8237..2241013633 100644 --- a/packages/dgrid-shim/src/gridHelper.ts +++ b/packages/dgrid-shim/src/gridHelper.ts @@ -13,6 +13,35 @@ export const GridHelper = declare(null, { postCreate: function postCreate(inherited) { this.inherited(postCreate, arguments); + // Emit dgrid-column-autofit on double-mousedown over a resize handle. + // A native dblclick is never fired because dgrid calls e.preventDefault() + // on every mousedown on .dgrid-resize-handle. + // We use a capture-phase listener on headerNode so we fire BEFORE dgrid's + // bubble-phase delegated handler, allowing us to stopPropagation on the + // second click to prevent dgrid from starting a resize drag. + const self = this; + let _lastResizeDownTime = 0; + let _lastResizeColId: string | null = null; + this.headerNode.addEventListener("mousedown", function (evt: MouseEvent) { + const target = evt.target as any; + if (!target.classList.contains("dgrid-resize-handle")) return; + const colId: string = target.columnId; + const now = Date.now(); + const delta = now - _lastResizeDownTime; + if (colId === _lastResizeColId && delta <= 300) { + _lastResizeDownTime = 0; + _lastResizeColId = null; + evt.stopPropagation(); + evt.preventDefault(); + const detail = self.columns[colId]; + if (!detail) return; + self.domNode.dispatchEvent(new CustomEvent("dgrid-column-autofit", { detail, bubbles: true, cancelable: true })); + } else { + _lastResizeDownTime = now; + _lastResizeColId = colId; + } + }, { capture: true }); + this.__hpcc_tooltip_header = new Tooltip({ connectId: [this.id], selector: ".dgrid-resize-header-container", @@ -53,6 +82,26 @@ export const GridHelper = declare(null, { node.checked = false; node.indeterminate = false; }); + }, + + applyWidth: function (id: string, cssWidth: string) { + const existingRule = this._columnSizes?.[id]; + if (existingRule?.set) { + existingRule.set("width", cssWidth); + } else { + this.styleColumn(id, `width: ${cssWidth}`); + } + }, + + resizeColumn: function resizeColumn(colId: string, widthPx: number) { + this.applyWidth(colId, `${widthPx}px`); + + // Reset the last visible column to auto so it fills remaining space. + const lastColId: string | undefined = this._getResizedColumnWidths?.()?.lastColId; + if (lastColId && lastColId !== colId) { + this.applyWidth(lastColId, "auto"); + } + this.resize(); }/*, _onNotify(object, existingId) { diff --git a/packages/dgrid/src/Common.ts b/packages/dgrid/src/Common.ts index 91abcc2e7b..c179ace1ab 100644 --- a/packages/dgrid/src/Common.ts +++ b/packages/dgrid/src/Common.ts @@ -1,15 +1,16 @@ -import { HTMLWidget } from "@hpcc-js/common"; +import { HTMLWidget, Selection } from "@hpcc-js/common"; import { Grid, PagingGrid } from "./dgrid-shim.ts"; import { DBStore } from "./DBStore.ts"; +import { type ColumnType } from "./RowFormatter.ts"; import "../src/Common.css"; export class Common extends HTMLWidget { - protected _columns = []; + protected _columns: ColumnType[] = []; protected _store = new DBStore(this._db); - protected _dgridDiv; - protected _dgrid; - protected _prevPaging; + protected _dgridDiv: Selection; + protected _dgrid: typeof PagingGrid | typeof Grid; + protected _prevPaging: boolean; private _prevSortBy: string; private _prevSortByDescending: boolean; private _prevMultiSelect: boolean; @@ -107,6 +108,14 @@ export class Common extends HTMLWidget { this.click(this.rowToObj(evt.rows[0].data.__origRow), "", false, { selection: this.selection() }); } }); + this._dgrid.on("dgrid-column-autofit", (evt) => { + if (this._supressEvents) return; + if (evt.detail?.label) { + const column = this._columns.find(c => c.label === evt.detail.label); + if (!column) return; + this.dblclickColResize(column.label, column); + } + }); this._dgrid.refresh({}); } this._dgrid.noDataMessage = `${this.noDataMessage()}`; @@ -130,6 +139,9 @@ export class Common extends HTMLWidget { click(row, col, sel, more) { } + + dblclickColResize(column, dgridColumn) { + } } Common.prototype._class += " dgrid_Common"; diff --git a/packages/dgrid/src/DBStore.ts b/packages/dgrid/src/DBStore.ts index c31d77fb3e..be3a4c6f52 100644 --- a/packages/dgrid/src/DBStore.ts +++ b/packages/dgrid/src/DBStore.ts @@ -28,6 +28,7 @@ export class DBStore { idx, className: "resultGridCell", sortable, + hidden: false, isSet: false }; switch (field.type()) { diff --git a/packages/dgrid/src/DatasourceStore.ts b/packages/dgrid/src/DatasourceStore.ts index 5b4d5a4cf9..e474b6d1a1 100644 --- a/packages/dgrid/src/DatasourceStore.ts +++ b/packages/dgrid/src/DatasourceStore.ts @@ -79,6 +79,7 @@ export class DatasourceStore { idx, className: "resultGridCell", sortable: true, + hidden: false, isSet: false }; if (field.type === "dataset") { diff --git a/packages/dgrid/src/RowFormatter.ts b/packages/dgrid/src/RowFormatter.ts index c497c98577..fcea319cdd 100644 --- a/packages/dgrid/src/RowFormatter.ts +++ b/packages/dgrid/src/RowFormatter.ts @@ -30,6 +30,7 @@ export interface ColumnType { idx: number; className: string; sortable: boolean; + hidden: boolean; isSet: boolean; width?: number; formatter?: CellFormatter; diff --git a/packages/dgrid/src/Table.ts b/packages/dgrid/src/Table.ts index 25d906a64d..36ee226955 100644 --- a/packages/dgrid/src/Table.ts +++ b/packages/dgrid/src/Table.ts @@ -235,6 +235,11 @@ export class Table extends Common { // Events --- click(row, col, sel) { } + + dblclickColResize(column: string, dgridColumn: any): void { + this.guessWidth([dgridColumn], this.data()); + this._dgrid.resizeColumn(dgridColumn.id, dgridColumn.width); + } } Table.prototype._class += " dgrid_Table"; diff --git a/packages/dgrid/src/dgrid-shim.ts b/packages/dgrid/src/dgrid-shim.ts index 974d9dda51..f20c7ce7dd 100644 --- a/packages/dgrid/src/dgrid-shim.ts +++ b/packages/dgrid/src/dgrid-shim.ts @@ -1,7 +1,7 @@ import type * as dgrid_shim from "@hpcc-js/dgrid-shim"; // Note: Resolved at build time and inlined into the dgrid bundle. -// @ts-ignore +// @ts-expect-error import dgridShimBundle from "@hpcc-js/dgrid-shim/dist/index.js?raw"; const loadDgridShim = new Function("globalThis", "var self = globalThis; var window = globalThis;" + dgridShimBundle); diff --git a/packages/eclwatch/src/WUResultStore.ts b/packages/eclwatch/src/WUResultStore.ts index 3bec6b4d16..923b459818 100644 --- a/packages/eclwatch/src/WUResultStore.ts +++ b/packages/eclwatch/src/WUResultStore.ts @@ -14,7 +14,7 @@ function safeEncode(item) { case "[object String]": return entitiesEncode(item); default: - console.warn("Unknown cell type: " + Object.prototype.toString.call(item)); + console.warn("Unknown cell type: " + Object.prototype.toString.call(item)); } return item; } @@ -52,6 +52,7 @@ export class Store { idx, label: label + (keyed ? " (i)" : ""), className: "resultGridCell", + hidden: false, sortable: false, width: keyed ? 16 : 0, isSet: node.isSet