diff --git a/apps/desktop/src/components/grid/DataGrid.vue b/apps/desktop/src/components/grid/DataGrid.vue index 5733f1c5ca..cf4095ae5d 100644 --- a/apps/desktop/src/components/grid/DataGrid.vue +++ b/apps/desktop/src/components/grid/DataGrid.vue @@ -2091,7 +2091,8 @@ const columnStructureSignature = computed(() => createDataGridColumnStructureSig // Bumped once the configured header font is ready, so widths measured against a temporary fallback // font get re-measured without reacting to unrelated fonts loaded elsewhere in the application. const dataGridFontReadyTick = ref(0); -const columnHeaderMeasurementKey = computed(() => [tableFontSize.value, tableFontFamily.value, dataGridFontReadyTick.value]); +const columnFormatterReadyTick = ref(0); +const columnHeaderMeasurementKey = computed(() => [tableFontSize.value, tableFontFamily.value, dataGridFontReadyTick.value, columnFormatterReadyTick.value]); let columnHeaderMeasureContext: CanvasRenderingContext2D | null | undefined; if (typeof document !== "undefined" && document.fonts) { @@ -2121,8 +2122,10 @@ function measureColumnHeaderText(text: string): number | undefined { return Math.ceil(columnHeaderMeasureContext.measureText(text).width); } +let columnFormatterForWidth: ((columnIndex: number) => ColumnFormatterConfig | undefined) | undefined; + function columnWidthDisplayValue(value: CellValue, columnIndex: number): CellValue { - const formatter = columnFormatter(columnIndex); + const formatter = columnFormatterForWidth?.(columnIndex); return formatter ? applyColumnFormatter(value, formatter) : value; } @@ -2748,8 +2751,6 @@ watch(isScrolling, (scrolling) => { } }); -initColumnWidths(); -watch([visibleColumnIndexes, () => renderedColumnWidths.value.length], () => scheduleColumnLayoutRefresh()); const localFilterScopeKey = computed(() => [ props.connectionId ?? "", @@ -4377,6 +4378,11 @@ const { formatForeignKeyCellDisplay, toast, }); +columnFormatterForWidth = columnFormatter; +columnFormatterReadyTick.value++; + +initColumnWidths(); +watch([visibleColumnIndexes, () => renderedColumnWidths.value.length], () => scheduleColumnLayoutRefresh()); watch( () => displayRowCount.value, diff --git a/apps/desktop/src/components/grid/__tests__/DataGridInitializationOrder.spec.ts b/apps/desktop/src/components/grid/__tests__/DataGridInitializationOrder.spec.ts index 3cde354a5b..4d92edde88 100644 --- a/apps/desktop/src/components/grid/__tests__/DataGridInitializationOrder.spec.ts +++ b/apps/desktop/src/components/grid/__tests__/DataGridInitializationOrder.spec.ts @@ -12,6 +12,15 @@ describe("DataGrid setup initialization order", () => { expect(columnResizeInitialization).toBeGreaterThan(tableColumnMetadataDeclaration); }); + it("initializes column formatters before measuring formatted column widths", () => { + const columnFormatterDeclaration = dataGridSource.indexOf("} = useDataGridColumnFormatter({"); + const columnWidthInitialization = dataGridSource.lastIndexOf("initColumnWidths();"); + + expect(columnFormatterDeclaration).toBeGreaterThanOrEqual(0); + expect(columnWidthInitialization).toBeGreaterThan(columnFormatterDeclaration); + expect(dataGridSource).toContain("columnFormatterForWidth?.(columnIndex)"); + }); + it("initializes where-search capability before the immediate filter preview watcher", () => { const canUseWhereSearchDeclaration = dataGridSource.indexOf("const canUseWhereSearch = computed"); const filterPreviewDeclaration = dataGridSource.indexOf("const filterPreviewVisible = computed");