fix(mysql): edit enum column values
This commit is contained in:
1 parent
ea8b3f9800
commit
8c7e34a6de
14 files changed
+283
-54
No files matched your search
@@ -90,7 +90,7 @@ import { createColumnDrafts } from "@/lib/table/tableStructureEditorState";
|
||||
import type { BuildSingleColumnAlterSqlOptions } from "@/lib/table/tableStructureEditorSql";
|
||||
import { buildTableSelectSql, quoteTableIdentifier } from "@/lib/table/tableSelectSql";
|
||||
import { uuid } from "@/lib/common/utils";
|
||||
import { resolveHeaderColumnType } from "@/lib/dataGrid/dataGridColumnType";
|
||||
import { compactHeaderColumnType, resolveHeaderColumnType } from "@/lib/dataGrid/dataGridColumnType";
|
||||
import { canEditExistingTableRows, canInsertTableRows, canUseKeylessRowPredicate, hiveTablePropertiesIndicateTransactional, isClickHouseExistingRowReadonlyColumn, isHiddenGridColumn, isTdengineExistingRowReadonlyColumn, usesSyntheticRowIdKey } from "@/lib/table/tableEditing";
|
||||
import { buildDataGridColumnDistinctValuesSql, buildDataGridContextFilterCondition, buildDataGridCountSql, buildHiveTablePropertiesSql, type DataGridContextFilterMode } from "@/lib/dataGrid/dataGridSql";
|
||||
import {
|
||||
@@ -379,7 +379,7 @@ function headerColumnType(column: string, actualColIdx: number): string {
|
||||
resultColumnTypes: props.result.column_types,
|
||||
actualColIdx,
|
||||
});
|
||||
return resolved ? shortTypeName(resolved) : "";
|
||||
return resolved ? shortTypeName(compactHeaderColumnType(resolved)) : "";
|
||||
}
|
||||
|
||||
function shortTypeName(t: string): string {
|
||||
@@ -4124,6 +4124,11 @@ function isEnumGridColumnNullable(columnIndex: number): boolean {
|
||||
return tableColumnForGridColumn(columnIndex)?.is_nullable ?? false;
|
||||
}
|
||||
|
||||
function isEnumEditorInitialNull(rowId: number | undefined, columnIndex: number): boolean {
|
||||
if (rowId === undefined) return false;
|
||||
return getRowItem(rowId)?.data[columnIndex] === null;
|
||||
}
|
||||
|
||||
function cellEditInputModeForColumn(columnIndex: number): "decimal" | "numeric" | undefined {
|
||||
const dataType = normalizedColumnDataType(tableColumnForGridColumn(columnIndex));
|
||||
if (isIntegerColumnType(dataType)) return "numeric";
|
||||
@@ -6752,8 +6757,8 @@ function deleteCurrentRow(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
function commitGridEdit() {
|
||||
void commitEditAndMaybeAutoSave().finally(() => nextTick(() => gridRef.value?.focus({ preventScroll: true })));
|
||||
function commitGridEdit(value?: string | null) {
|
||||
void commitEditAndMaybeAutoSave(value === undefined ? undefined : { explicitValue: value }).finally(() => nextTick(() => gridRef.value?.focus({ preventScroll: true })));
|
||||
}
|
||||
|
||||
async function commitEditFromCellBlur() {
|
||||
@@ -9257,7 +9262,16 @@ const gridContextMenuItems = computed<ContextMenuItem[]>(() => {
|
||||
@cancel="cancelEdit"
|
||||
@commit="commitGridEdit"
|
||||
/>
|
||||
<EnumCellEditor v-else-if="isEnumGridColumn(cell.valueIndex)" v-model="editValue" :values="enumValuesForGridColumn(cell.valueIndex)" :nullable="isEnumGridColumnNullable(cell.valueIndex)" cell-layout="transpose" @cancel="cancelEdit" @commit="commitGridEdit" />
|
||||
<EnumCellEditor
|
||||
v-else-if="isEnumGridColumn(cell.valueIndex)"
|
||||
v-model="editValue"
|
||||
:values="enumValuesForGridColumn(cell.valueIndex)"
|
||||
:nullable="isEnumGridColumnNullable(cell.valueIndex)"
|
||||
:initial-null="isEnumEditorInitialNull(displayItems[cell.recordIndex]?.id, cell.valueIndex)"
|
||||
cell-layout="transpose"
|
||||
@cancel="cancelEdit"
|
||||
@commit="commitGridEdit"
|
||||
/>
|
||||
<textarea
|
||||
v-else-if="cellUsesExpandedEditor(displayItems[cell.recordIndex]?.id, cell.valueIndex)"
|
||||
v-model="editValue"
|
||||
@@ -9744,6 +9758,7 @@ const gridContextMenuItems = computed<ContextMenuItem[]>(() => {
|
||||
v-model="editValue"
|
||||
:values="enumValuesForGridColumn(canvasEditingCell.actualColIdx)"
|
||||
:nullable="isEnumGridColumnNullable(canvasEditingCell.actualColIdx)"
|
||||
:initial-null="isEnumEditorInitialNull(canvasEditingCell.rowId, canvasEditingCell.actualColIdx)"
|
||||
@cancel="cancelEdit"
|
||||
@commit="commitGridEdit"
|
||||
/>
|
||||
@@ -9889,7 +9904,15 @@ const gridContextMenuItems = computed<ContextMenuItem[]>(() => {
|
||||
@cancel="cancelEdit"
|
||||
@commit="commitGridEdit"
|
||||
/>
|
||||
<EnumCellEditor v-else-if="isEnumGridColumn(col.actualColIdx)" v-model="editValue" :values="enumValuesForGridColumn(col.actualColIdx)" :nullable="isEnumGridColumnNullable(col.actualColIdx)" @cancel="cancelEdit" @commit="commitGridEdit" />
|
||||
<EnumCellEditor
|
||||
v-else-if="isEnumGridColumn(col.actualColIdx)"
|
||||
v-model="editValue"
|
||||
:values="enumValuesForGridColumn(col.actualColIdx)"
|
||||
:nullable="isEnumGridColumnNullable(col.actualColIdx)"
|
||||
:initial-null="isEnumEditorInitialNull(item.id, col.actualColIdx)"
|
||||
@cancel="cancelEdit"
|
||||
@commit="commitGridEdit"
|
||||
/>
|
||||
<textarea
|
||||
v-else-if="cellUsesExpandedEditor(item.id, col.actualColIdx)"
|
||||
v-model="editValue"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, nextTick, onMounted, ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import type { FocusOutsideEvent, PointerDownOutsideEvent } from "reka-ui";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
|
||||
@@ -8,40 +9,47 @@ const props = withDefaults(
|
||||
modelValue: string;
|
||||
values: string[];
|
||||
nullable?: boolean;
|
||||
initialNull?: boolean;
|
||||
cellLayout?: "grid" | "transpose";
|
||||
}>(),
|
||||
{
|
||||
nullable: false,
|
||||
initialNull: false,
|
||||
cellLayout: "grid",
|
||||
},
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
"update:modelValue": [value: string];
|
||||
commit: [];
|
||||
commit: [value?: string | null];
|
||||
cancel: [];
|
||||
}>();
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const open = ref(true);
|
||||
const triggerRef = ref<HTMLButtonElement | null>(null);
|
||||
let closeHandled = false;
|
||||
|
||||
const triggerClass = computed(() => ["cell-edit-input absolute inset-0 z-10 flex items-center gap-1 border-2 border-primary bg-background py-0 text-left text-xs outline-none", props.cellLayout === "transpose" ? "px-1.5" : "px-2.5"].join(" "));
|
||||
|
||||
const displayValue = computed(() => props.modelValue || "(NULL)");
|
||||
const displayValue = computed(() => {
|
||||
if (props.initialNull && props.modelValue === "") return t("grid.nullValue");
|
||||
return props.modelValue === "" ? "''" : props.modelValue;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => triggerRef.value?.focus());
|
||||
});
|
||||
|
||||
function selectValue(value: string) {
|
||||
emit("update:modelValue", value);
|
||||
finishCommit();
|
||||
function selectValue(value: string | null) {
|
||||
if (value !== null) emit("update:modelValue", value);
|
||||
finishCommit(value);
|
||||
}
|
||||
|
||||
function finishCommit() {
|
||||
function finishCommit(value?: string | null) {
|
||||
closeHandled = true;
|
||||
emit("commit");
|
||||
emit("commit", value);
|
||||
}
|
||||
|
||||
function finishCancel() {
|
||||
@@ -87,9 +95,22 @@ function onPopoverInteractOutside(event: PointerDownOutsideEvent | FocusOutsideE
|
||||
</PopoverTrigger>
|
||||
<PopoverContent align="start" side="bottom" class="w-auto min-w-[120px] rounded-md p-1" @click.stop @keydown.stop="onKeydown" @interact-outside="onPopoverInteractOutside">
|
||||
<div class="flex flex-col gap-0.5">
|
||||
<button v-if="nullable" type="button" class="flex items-center rounded-sm px-2 py-1 text-xs text-muted-foreground hover:bg-accent hover:text-accent-foreground" :class="{ 'bg-accent text-accent-foreground': modelValue === '' }" @click="selectValue('')">(NULL)</button>
|
||||
<button v-for="val in values" :key="val" type="button" class="flex items-center rounded-sm px-2 py-1 text-xs hover:bg-accent hover:text-accent-foreground" :class="{ 'bg-accent text-accent-foreground': modelValue === val }" @click="selectValue(val)">
|
||||
{{ val }}
|
||||
<button v-if="nullable" type="button" class="flex min-h-7 w-full items-center rounded-sm px-2 py-1 text-left text-xs italic text-muted-foreground hover:bg-accent hover:text-accent-foreground" :class="{ 'bg-accent text-accent-foreground': initialNull }" @click="selectValue(null)">
|
||||
{{ t("grid.nullValue") }}
|
||||
</button>
|
||||
<button
|
||||
v-for="val in values"
|
||||
:key="val"
|
||||
type="button"
|
||||
class="flex min-h-7 w-full items-center rounded-sm px-2 py-1 text-left text-xs hover:bg-accent hover:text-accent-foreground"
|
||||
:class="{ 'bg-accent text-accent-foreground': modelValue === val && !(initialNull && val === '') }"
|
||||
@click="selectValue(val)"
|
||||
>
|
||||
<template v-if="val === ''">
|
||||
<code>''</code>
|
||||
<span class="ml-2 text-muted-foreground">{{ t("grid.emptyStringValue") }}</span>
|
||||
</template>
|
||||
<template v-else>{{ val }}</template>
|
||||
</button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
|
||||
Reference in new issue
Block a user