diff --git a/apps/desktop/src/components/grid/DataGrid.vue b/apps/desktop/src/components/grid/DataGrid.vue index 095e5f0a8..34e26c347 100644 --- a/apps/desktop/src/components/grid/DataGrid.vue +++ b/apps/desktop/src/components/grid/DataGrid.vue @@ -138,7 +138,7 @@ import { buildDataGridCellDetail, buildDataGridColumnDetail, buildDataGridRowDet import { applyColumnFormatter, buildColumnFormatterKey, getSupportedTimeZoneOptions, normalizeColumnFormatter, resolveColumnFormatter, type ColumnFormatterConfig, type DateTimeFormatterUnit, DateTimePatterns } from "@/lib/dataGrid/columnFormatter"; 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 { resolveDataGridColumnsByResultIndex } from "@/lib/dataGrid/dataGridColumnMetadata"; +import { resolveDataGridColumnNullability, resolveDataGridColumnsByResultIndex } from "@/lib/dataGrid/dataGridColumnMetadata"; 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"; @@ -538,6 +538,10 @@ function headerColumnType(column: string, actualColIdx: number): string { return resolved ? shortTypeName(compactHeaderColumnType(resolved)) : ""; } +function headerColumnNullability(actualColIdx: number): "nullable" | "required" | undefined { + return resolveDataGridColumnNullability(props.context, tableColumnForGridColumn(actualColIdx)); +} + const reserveColumnTypeLine = computed(() => reserveDataGridHeaderLine(showColumnTypesInHeader.value, props.result.columns, (column, index) => headerColumnType(column, index))); // Match the rendered header columns so comments from unprojected metadata cannot add an empty row. const reserveColumnCommentLine = computed(() => reserveDataGridHeaderLine(showColumnCommentsInHeader.value, props.result.columns, (column) => headerColumnComment(column))); @@ -9355,6 +9359,7 @@ const gridContextMenuItems = computed(() => { :show-comment-line="reserveColumnCommentLine" :tooltip-column-type="columnTypeMap.get(col.name)" :tooltip-column-comment="columnCommentMap.get(col.name)" + :column-nullability="headerColumnNullability(col.actualColIdx)" :type-class="typeColorClass(headerColumnType(col.name, col.actualColIdx))" :drag-class="columnHeaderDragClass(col.visibleColIdx)" :column-style="columnHeaderStyle(col.visibleColIdx)" @@ -9362,6 +9367,9 @@ const gridContextMenuItems = computed(() => { :column-name-label="t('grid.columnName')" :column-type-label="t('grid.columnType')" :column-comment-label="t('grid.columnComment')" + :nullable-label="t('structureEditor.nullable')" + :yes-label="t('structureEditor.yes')" + :no-label="t('structureEditor.no')" :column-index-label="t('grid.tableInfoIndexes')" :column-primary-index-label="t('grid.columnPrimaryIndex')" :column-unique-index-label="t('grid.columnUniqueIndex')" diff --git a/apps/desktop/src/components/grid/DataGridColumnHeader.vue b/apps/desktop/src/components/grid/DataGridColumnHeader.vue index 42e202995..6589ff2e6 100644 --- a/apps/desktop/src/components/grid/DataGridColumnHeader.vue +++ b/apps/desktop/src/components/grid/DataGridColumnHeader.vue @@ -18,6 +18,7 @@ const props = defineProps<{ columnComment?: string; tooltipColumnType?: string; tooltipColumnComment?: string; + columnNullability?: "nullable" | "required"; showTypeLine?: boolean; showCommentLine?: boolean; typeClass?: HTMLAttributes["class"]; @@ -27,6 +28,9 @@ const props = defineProps<{ columnNameLabel: string; columnTypeLabel: string; columnCommentLabel: string; + nullableLabel?: string; + yesLabel?: string; + noLabel?: string; columnIndexLabel: string; columnPrimaryIndexLabel: string; columnUniqueIndexLabel: string; @@ -71,7 +75,10 @@ const emit = defineEmits<{ - {{ name }} + + {{ name }} + NULL + {{ columnType }} {{ columnComment @@ -98,6 +105,10 @@ const emit = defineEmits<{ {{ columnCommentLabel }} {{ tooltipColumnComment ?? columnComment }} +