feat(grid): flatten multiline cell text

This commit is contained in:
ptma authored and GitHub committed 2026-08-13 11:40:22 +08:00
1 parent 01e67ee9a4
commit ee08f356e9
17 files changed
+97 -30

No files matched your search

@@ -321,6 +321,7 @@ const editQueryResultMaxRows = ref(settingsStore.editorSettings.queryResultMaxRo
const editInfiniteScroll = ref(settingsStore.editorSettings.infiniteScroll);
const editRegexMaxMatchCount = ref(settingsStore.editorSettings.regexMaxMatchCount);
const editAutoCalculateTotalRows = ref(settingsStore.editorSettings.autoCalculateTotalRows);
const editFlatteningMultiLineText = ref(settingsStore.editorSettings.flatteningMultiLineText);
const editTableColumnTemplateRows = ref<TableColumnTemplateGridRow[]>(tableColumnTemplateRowsFromSettings(settingsStore.editorSettings.tableColumnTemplateFields));
const editTableColumnTemplateDatabaseType = ref<DatabaseType>(TABLE_COLUMN_TEMPLATE_DATABASE_TYPES[0] ?? "mysql");
const editSqlVariableSyntaxOverrides = ref<SqlVariableSyntaxOverrides>(normalizeSqlVariableSyntaxOverrides(settingsStore.editorSettings.sqlVariableSyntaxOverrides));
@@ -488,6 +489,7 @@ function currentEditorSettingsDraft(): EditorSettingsDraft {
compactColumnHeaderActions: editCompactColumnHeaderActions.value,
dataGridQuickEntry: editDataGridQuickEntry.value,
dataGridAutoTransposeSingleRow: editDataGridAutoTransposeSingleRow.value,
flatteningMultiLineText: editFlatteningMultiLineText.value,
pageSize: editPageSize.value,
tableOpenPageSize: editTableOpenPageSize.value,
queryResultMaxRowsEnabled: editQueryResultMaxRowsEnabled.value,
@@ -761,6 +763,7 @@ function syncEditorSettingsDraftFromStore() {
editCompactColumnHeaderActions.value = settingsStore.editorSettings.compactColumnHeaderActions;
editDataGridQuickEntry.value = settingsStore.editorSettings.dataGridQuickEntry;
editDataGridAutoTransposeSingleRow.value = settingsStore.editorSettings.dataGridAutoTransposeSingleRow;
editFlatteningMultiLineText.value = settingsStore.editorSettings.flatteningMultiLineText;
editPageSize.value = settingsStore.editorSettings.pageSize;
editTableOpenPageSize.value = settingsStore.editorSettings.tableOpenPageSize;
editQueryResultMaxRowsEnabled.value = settingsStore.editorSettings.queryResultMaxRowsEnabled;
@@ -1006,6 +1009,7 @@ function resetDefaultsForTab(tab: SettingsCategory) {
editCompactColumnHeaderActions.value = DEFAULT_EDITOR_SETTINGS.compactColumnHeaderActions;
editDataGridQuickEntry.value = DEFAULT_EDITOR_SETTINGS.dataGridQuickEntry;
editDataGridAutoTransposeSingleRow.value = DEFAULT_EDITOR_SETTINGS.dataGridAutoTransposeSingleRow;
editFlatteningMultiLineText.value = DEFAULT_EDITOR_SETTINGS.flatteningMultiLineText;
editPageSize.value = DEFAULT_EDITOR_SETTINGS.pageSize;
editTableOpenPageSize.value = DEFAULT_EDITOR_SETTINGS.tableOpenPageSize;
editQueryResultMaxRowsEnabled.value = DEFAULT_EDITOR_SETTINGS.queryResultMaxRowsEnabled;
@@ -1074,6 +1078,7 @@ function resetAllDefaults() {
editCompactColumnHeaderActions.value = DEFAULT_EDITOR_SETTINGS.compactColumnHeaderActions;
editDataGridQuickEntry.value = DEFAULT_EDITOR_SETTINGS.dataGridQuickEntry;
editDataGridAutoTransposeSingleRow.value = DEFAULT_EDITOR_SETTINGS.dataGridAutoTransposeSingleRow;
editFlatteningMultiLineText.value = DEFAULT_EDITOR_SETTINGS.flatteningMultiLineText;
editPageSize.value = DEFAULT_EDITOR_SETTINGS.pageSize;
editTableOpenPageSize.value = DEFAULT_EDITOR_SETTINGS.tableOpenPageSize;
editQueryResultMaxRowsEnabled.value = DEFAULT_EDITOR_SETTINGS.queryResultMaxRowsEnabled;
@@ -4877,6 +4882,17 @@ onUnmounted(() => {
</div>
<Switch id="data-grid-auto-transpose-single-row" v-model="editDataGridAutoTransposeSingleRow" />
</div>
<div class="flex items-center justify-between gap-4 rounded-md border bg-muted/20 px-3 py-2">
<div class="space-y-1">
<Label for="flattening-multi-line">
{{ t("settings.flatteningMultiLineText") }}
</Label>
<p class="text-xs text-muted-foreground">
{{ t("settings.flatteningMultiLineTextDescription") }}
</p>
</div>
<Switch id="flattening-multi-line" v-model="editFlatteningMultiLineText" />
</div>
</div>
<template v-if="!isWeb">
@@ -557,6 +557,7 @@ const dataGridSearchMode = computed(() => settingsStore.editorSettings.dataGridS
const compactDataGridToolbar = computed(() => isDataGridToolbarCompact(dataGridTopbarWidth.value, dataGridViewportWidth.value, DATA_GRID_CONDITION_TOOLBAR_MIN_WIDTH));
const infiniteScrollEnabled = computed(() => props.paginationEnabled && settingsStore.editorSettings.infiniteScroll);
const infiniteScrollMaxRows = computed(() => continuousQueryResultMaxRows(settingsStore.editorSettings.queryResultMaxRowsEnabled, settingsStore.editorSettings.queryResultMaxRows));
const flatteningMultiLineEnabled = computed(() => settingsStore.editorSettings.flatteningMultiLineText);
const expandedCellEditor = ref<{ rowId: number; col: number } | null>(null);
function headerColumnComment(column: string): string {
@@ -5840,7 +5841,7 @@ function booleanNullTextHitFromCanvasEvent(item: RowItem, hit: { rowIndex: numbe
const canvasRect = canvas?.getBoundingClientRect();
const cellRect = canvasCellViewportRect(hit.rowIndex, hit.visibleColIdx);
if (!canvasRect || !cellRect) return false;
const text = firstLineCellDisplayValue(formatCellCached(item.data[actualColIdx], actualColIdx));
const text = firstLineCellDisplayValue(formatCellCached(item.data[actualColIdx], actualColIdx), flatteningMultiLineEnabled.value);
if (!text) return false;
const textWidth = measureCellTextWidthCached(text, `italic 400 ${tableFontSize.value}px ${tableFontFamily.value}`);
if (textWidth <= 0) return false;
@@ -6105,6 +6106,7 @@ function drawCanvasGrid() {
rightAlignedActionCell: canvasRightAlignedActionCell.value,
columnIsBoolean: isBooleanGridColumn,
booleanDisplayMode: booleanDisplayMode.value,
flatteningMultiLineEnabled: flatteningMultiLineEnabled.value,
});
}
@@ -6122,6 +6124,7 @@ watch(showDataGridTopbar, () => nextTick(observeDataGridTopbarWidth), {
});
watch(columnAligns, () => scheduleCanvasDraw());
watch(booleanDisplayMode, () => scheduleCanvasDraw());
watch(flatteningMultiLineEnabled, () => scheduleCanvasDraw());
watch(colorizeDataGridCellTypes, () => scheduleCanvasDraw());
watch(
[
@@ -10284,7 +10287,7 @@ const gridContextMenuItems = computed<ContextMenuItem[]>(() => {
<template v-if="draftCellPlaceholder(displayItems[cell.recordIndex], cell.valueIndex)">
<span class="text-muted-foreground/70 italic">{{ draftCellPlaceholder(displayItems[cell.recordIndex], cell.valueIndex) }}</span>
</template>
<template v-else>{{ firstLineCellDisplayValue(cell.display) }}</template>
<template v-else>{{ firstLineCellDisplayValue(cell.display, flatteningMultiLineEnabled) }}</template>
<div v-if="cellDetailButtonVisible(cell.recordIndex, cell.valueIndex)" class="absolute right-2 top-1/2 flex -translate-y-1/2 items-center gap-1">
<LightDropdownMenu
v-if="canQuickDownloadCellValue(cell.recordIndex, cell.valueIndex)"
@@ -11051,13 +11054,13 @@ const gridContextMenuItems = computed<ContextMenuItem[]>(() => {
</div>
</template>
<template v-else-if="booleanCellsUseCheckbox && isBooleanGridCell(item, col.actualColIdx) && item.data[col.actualColIdx] === null && canEditCellItem(item, col.actualColIdx)">
<span class="italic text-muted-foreground cursor-pointer select-none" @click.stop="cycleBooleanGridCell(item, col.actualColIdx, $event)">{{ firstLineCellDisplayValue(formatCellCached(item.data[col.actualColIdx], col.actualColIdx)) }}</span>
<span class="italic text-muted-foreground cursor-pointer select-none" @click.stop="cycleBooleanGridCell(item, col.actualColIdx, $event)">{{ firstLineCellDisplayValue(formatCellCached(item.data[col.actualColIdx], col.actualColIdx), flatteningMultiLineEnabled) }}</span>
</template>
<template v-else>
<template v-if="draftCellPlaceholder(item, col.actualColIdx)">
<span class="text-muted-foreground/70 italic">{{ draftCellPlaceholder(item, col.actualColIdx) }}</span>
</template>
<template v-else>{{ firstLineCellDisplayValue(formatCellCached(item.data[col.actualColIdx], col.actualColIdx)) }}</template>
<template v-else>{{ firstLineCellDisplayValue(formatCellCached(item.data[col.actualColIdx], col.actualColIdx), flatteningMultiLineEnabled) }}</template>
<div v-if="cellDetailButtonVisible(item.displayIndex, col.actualColIdx)" class="absolute right-2 top-1/2 flex -translate-y-1/2 items-center gap-1">
<LightDropdownMenu
v-if="canQuickDownloadCellValue(item.displayIndex, col.actualColIdx)"