fix(grid): show comments for joined query results
This commit is contained in:
1 parent
d5f18034f9
commit
64e5e88c27
11 files changed
+867
-9
No files matched your search
@@ -71,7 +71,7 @@ import DataGridTextFilterWorkbench from "@/components/grid/DataGridTextFilterWor
|
||||
import TemporalCellEditor from "@/components/grid/TemporalCellEditor.vue";
|
||||
import EnumCellEditor from "@/components/grid/EnumCellEditor.vue";
|
||||
import DataGridReadonlyTextSelection from "@/components/grid/DataGridReadonlyTextSelection.vue";
|
||||
import type { QueryResult, ColumnInfo, DatabaseType, ForeignKeyInfo, IndexInfo, TriggerInfo, TableInfoTab } from "@/types/database";
|
||||
import type { QueryResult, ColumnInfo, DatabaseType, ForeignKeyInfo, IndexInfo, TriggerInfo, TableInfoTab, QueryResultSourceColumnRef } from "@/types/database";
|
||||
import { isQueryExecutionErrorResult } from "@/lib/query/queryResultError";
|
||||
import { tableObjectSourceKind } from "@/lib/table/tableObjectSourceKind";
|
||||
import { tableColumnDefaultDisplayValue } from "@/lib/table/tableColumnDefaultPresentation";
|
||||
@@ -346,6 +346,22 @@ interface DataGridProps {
|
||||
context?: "results" | "table-data";
|
||||
autoTransposeSingleRow?: boolean;
|
||||
sourceColumns?: Array<string | undefined>;
|
||||
/**
|
||||
* Column comments for a multi-source query result (e.g. JOIN), indexed by
|
||||
* result-column ordinal (projection order). Populated even when the result is
|
||||
* not editable, so joined results still show comments. `undefined` for a
|
||||
* column that cannot be resolved back to exactly one base column (ambiguous
|
||||
* or computed) — the grid shows no comment instead of a wrong one.
|
||||
*/
|
||||
resultColumnComments?: Array<string | undefined>;
|
||||
/**
|
||||
* Display-only result-column -> source mapping for multi-source results,
|
||||
* indexed by result-column ordinal; each entry carries the source identity
|
||||
* (sourceKey + canonical source column name). Used to resolve column
|
||||
* comments per source instead of first-source-wins; never used for row
|
||||
* identity or editing.
|
||||
*/
|
||||
queryDisplaySourceColumns?: Array<QueryResultSourceColumnRef | undefined>;
|
||||
initialWhereInput?: string;
|
||||
initialOrderByInput?: string;
|
||||
sortColumn?: string;
|
||||
@@ -586,6 +602,11 @@ const readonlyTextCell = ref<{
|
||||
} | null>(null);
|
||||
|
||||
function resolvedColumnComment(column: string, actualColIdx: number): string | undefined {
|
||||
// Multi-source results resolve comments per result ordinal; ambiguous or
|
||||
// unresolved columns yield undefined instead of falling back to a
|
||||
// first-source-wins name map.
|
||||
const ordinalComments = props.resultColumnComments;
|
||||
if (ordinalComments) return ordinalComments[actualColIdx];
|
||||
return dataGridColumnCommentFor(columnCommentMap.value, column, props.sourceColumns?.[actualColIdx]);
|
||||
}
|
||||
|
||||
@@ -2116,7 +2137,13 @@ const allColumnTypes = computed(() =>
|
||||
const visibleColumnTypes = computed(() => visibleColumnIndexes.value.map((index) => allColumnTypes.value[index]));
|
||||
const allColumnTypeVisualKinds = computed(() => allColumnTypes.value.map((type) => resolveDataGridTypeVisualKind(type, resolvedDatabaseType.value)));
|
||||
const visibleColumnTypeVisualKinds = computed(() => visibleColumnIndexes.value.map((index) => allColumnTypeVisualKinds.value[index] ?? "unknown"));
|
||||
const visibleColumnComments = computed(() => visibleColumnIndexes.value.map((index) => dataGridColumnCommentFor(columnCommentMap.value, props.result.columns[index] ?? "", props.sourceColumns?.[index])));
|
||||
const visibleColumnComments = computed(() =>
|
||||
visibleColumnIndexes.value.map((index) => {
|
||||
const ordinalComments = props.resultColumnComments;
|
||||
if (ordinalComments) return ordinalComments[index];
|
||||
return dataGridColumnCommentFor(columnCommentMap.value, props.result.columns[index] ?? "", props.sourceColumns?.[index]);
|
||||
}),
|
||||
);
|
||||
const visibleColumnCount = computed(() => visibleColumnIndexes.value.length);
|
||||
|
||||
const numericColumnRightAlign = computed(() => (settingsStore.editorSettings.numericColumnRightAlign ?? true) && !showTranspose.value);
|
||||
|
||||
@@ -4,8 +4,10 @@ import { describe, expect, it } from "vitest";
|
||||
const dataGridSource = readFileSync(new URL("../DataGrid.vue", import.meta.url), "utf8");
|
||||
|
||||
describe("DataGrid column comments", () => {
|
||||
it("uses source column metadata for both inline and tooltip header comments", () => {
|
||||
expect(dataGridSource).toMatch(/function resolvedColumnComment\(column: string, actualColIdx: number\)[\s\S]*?dataGridColumnCommentFor\([\s\S]*?props\.sourceColumns\?\.\[actualColIdx\][\s\S]*?\);\s*\}/);
|
||||
it("uses per-ordinal multi-source comments, falling back to source metadata for single-source grids", () => {
|
||||
expect(dataGridSource).toMatch(
|
||||
/function resolvedColumnComment\(column: string, actualColIdx: number\)[\s\S]*?const ordinalComments = props\.resultColumnComments;[\s\S]*?if \(ordinalComments\) return ordinalComments\[actualColIdx\];[\s\S]*?dataGridColumnCommentFor\([\s\S]*?props\.sourceColumns\?\.\[actualColIdx\][\s\S]*?\);\s*\}/,
|
||||
);
|
||||
expect(dataGridSource).toContain(':column-comment="headerColumnComment(col.name, col.actualColIdx)"');
|
||||
expect(dataGridSource).toContain(':tooltip-column-comment="resolvedColumnComment(col.name, col.actualColIdx)"');
|
||||
expect(dataGridSource).toContain("(column, index) => headerColumnComment(column, index)");
|
||||
|
||||
@@ -1568,6 +1568,8 @@ defineExpose({ focusSearch, refreshData, refreshQueryEditorCompletionCache, hand
|
||||
:loading="activeTab.isExecuting"
|
||||
:editable="!!activeTab.queryAnalysis || !!mongoQueryResultSaveHandler"
|
||||
:source-columns="activeTab.querySourceColumns"
|
||||
:result-column-comments="activeTab.resultColumnComments"
|
||||
:query-display-source-columns="activeTab.queryDisplaySourceColumns"
|
||||
:custom-save-handler="mongoQueryResultSaveHandler"
|
||||
:mongo-update-target="mongoQueryResultSaveHandler && activeTab.result.mongo_copy_documents?.length === activeTab.result.rows.length ? activeTab.mongoEditTarget : undefined"
|
||||
:query-editability-reason="activeTab.queryEditabilityReason"
|
||||
|
||||
Reference in new issue
Block a user