feat(grid): show column defaults in new row placeholders

Closes #3096
This commit is contained in:
t8y2 committed 2026-08-24 18:22:10 +00:00
1 parent 9e135f7609
commit 6b5b33540f
6 files changed
+117 -17

No files matched your search

+18 -8
View File
@@ -181,6 +181,7 @@ import {
import { temporalCellEditorConfig, type TemporalCellEditorConfig } from "@/lib/dataGrid/dataGridTemporalEditor";
import { BOOLEAN_CELL_EDITOR_VALUES, booleanCellEditorValue, isBooleanCellValue, isBooleanColumnType, isPointInBooleanCheckbox, nextBooleanCellValue, normalizeBooleanCellValue, parseBooleanCellEditorValue } from "@/lib/dataGrid/dataGridBooleanColumn";
import { resolveDataGridColumnNullability, resolveDataGridColumnsByResultIndex } from "@/lib/dataGrid/dataGridColumnMetadata";
import { resolveDataGridNewRowCellPlaceholder } from "@/lib/dataGrid/dataGridDefaultPlaceholder";
import { isCancelSearchShortcut, isCopyCurrentRowShortcut, isDeleteCurrentRowShortcut, isFocusSearchShortcut, isModRShortcut, isSaveShortcut, isToggleTransposeShortcut } from "@/lib/editor/keyboardShortcuts";
import { dataGridHeaderContentWidth, scrollbarGutterWidth } from "@/lib/dataGrid/dataGridScrollGutter";
import { canFetchNextDataGridSegment, canGoNextDataGridPage, dataGridTotalRowCountLabelKey, dataGridTruncationHintKey, hasCompleteLocalDataGridResult, resolveDataGridPaginationTotal, type DataGridInexactTotalRowCountMode } from "@/lib/dataGrid/dataGridPagination";
@@ -6580,8 +6581,15 @@ function rowNumberText(item: RowItem | undefined): string {
return String(item.displayIndex + 1 + rowNumberPageOffset());
}
function draftCellPlaceholder(item: RowItem | undefined, columnIndex: number): string | null {
return item?.isDraft && item.data[columnIndex] === null ? t("grid.quickEntryDraftPlaceholder") : null;
const quickEntryDraftPlaceholder = computed(() => t("grid.quickEntryDraftPlaceholder"));
function newRowCellPlaceholder(item: RowItem | undefined, columnIndex: number): string | null {
return resolveDataGridNewRowCellPlaceholder({
row: item,
columnIndex,
column: tableColumnsByResultIndex.value[columnIndex],
draftFallback: quickEntryDraftPlaceholder.value,
});
}
function columnTypeCacheSignature(): string {
@@ -7349,7 +7357,7 @@ function drawCanvasGrid() {
searchMatchKeys: searchMatchSet.value,
currentSearchMatch: currentSearchMatch.value,
formatCell: (value, columnIndex, row) => formatCellCached(visibleLargeValuePreviewValue(row, columnIndex, value), columnIndex, largeValueOriginalBytes(row, columnIndex)),
draftCellPlaceholder: t("grid.quickEntryDraftPlaceholder"),
newRowCellPlaceholder,
isRowActive,
rowCellsUseSelectionVisual,
cellIsSelected,
@@ -12036,8 +12044,8 @@ function currentGridContextMenuItems(): ContextMenuItem[] {
/>
</template>
<template v-else>
<template v-if="draftCellPlaceholder(displayItems[cell.recordIndex], cell.valueIndex)">
<span class="text-muted-foreground/70 italic">{{ draftCellPlaceholder(displayItems[cell.recordIndex], cell.valueIndex) }}</span>
<template v-if="newRowCellPlaceholder(displayItems[cell.recordIndex], cell.valueIndex)">
<span class="text-muted-foreground/70 italic">{{ firstLineCellDisplayValue(newRowCellPlaceholder(displayItems[cell.recordIndex], cell.valueIndex) ?? "", flatteningMultiLineEnabled) }}</span>
</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">
@@ -12979,11 +12987,13 @@ function currentGridContextMenuItems(): 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), flatteningMultiLineEnabled) }}</span>
<span class="italic text-muted-foreground cursor-pointer select-none" @click.stop="cycleBooleanGridCell(item, col.actualColIdx, $event)">{{
firstLineCellDisplayValue(newRowCellPlaceholder(item, col.actualColIdx) ?? 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 v-if="newRowCellPlaceholder(item, col.actualColIdx)">
<span class="text-muted-foreground/70 italic">{{ firstLineCellDisplayValue(newRowCellPlaceholder(item, col.actualColIdx) ?? "", flatteningMultiLineEnabled) }}</span>
</template>
<template v-else>{{ firstLineCellDisplayValue(formatGridItemCell(item, 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">