fix(structure): default edit view to DDL
This commit is contained in:
1 parent
34cf69132d
commit
2f3d1de46a
4 files changed
+139
-31
No files matched your search
@@ -25,7 +25,7 @@ import { queryTimeoutSecsForConnection } from "@/lib/sql/queryTimeout";
|
||||
import { safeLocalStorageGet, safeLocalStorageSet } from "@/lib/backend/safeStorage";
|
||||
import { type EditableStructureColumn, type EditableStructureForeignKey, type EditableStructureIndex, type EditableStructureTrigger } from "@/lib/table/tableStructureEditorSql";
|
||||
import { PRESET_FIELDS_TEMPLATE_ID, createTableColumnTemplateDrafts } from "@/lib/table/tableColumnTemplates";
|
||||
import { getTableMetadataCapabilities } from "@/lib/table/tableMetadataCapabilities";
|
||||
import { getTableMetadataCapabilities, firstStructureMetadataTab, isStructureMetadataTabSupported } from "@/lib/table/tableMetadataCapabilities";
|
||||
import { canAddTableStructureColumn, getTableStructureCapabilities } from "@/lib/table/tableStructureCapabilities";
|
||||
import { connectionObjectTreeQuerySchema, tableStructureDatabaseTypeForConnection } from "@/lib/database/jdbcDialect";
|
||||
import type { TableInfoTab, TableStructureEditorDraft, TableStructureEditorTarget, TableStructureEditorViewport } from "@/types/database";
|
||||
@@ -107,7 +107,7 @@ const emit = defineEmits<{
|
||||
openSettings: [initialTab?: string, initialSection?: string];
|
||||
}>();
|
||||
|
||||
const activeTab = ref<TableInfoTab>("columns");
|
||||
const activeTab = ref<TableInfoTab>("ddl");
|
||||
const loading = ref(false);
|
||||
const saving = ref(false);
|
||||
const postSaveRefreshing = ref(false);
|
||||
@@ -117,6 +117,19 @@ const foreignKeysLoading = ref(false);
|
||||
const triggersLoading = ref(false);
|
||||
const ddlContent = ref("");
|
||||
const ddlLoading = ref(false);
|
||||
const ddlPreRef = ref<HTMLPreElement | null>(null);
|
||||
function onDdlKeydown(e: KeyboardEvent) {
|
||||
if ((e.ctrlKey || e.metaKey) && e.key === "a") {
|
||||
e.preventDefault();
|
||||
const el = ddlPreRef.value;
|
||||
if (!el) return;
|
||||
const range = document.createRange();
|
||||
range.selectNodeContents(el);
|
||||
const sel = window.getSelection();
|
||||
sel?.removeAllRanges();
|
||||
sel?.addRange(range);
|
||||
}
|
||||
}
|
||||
const ddlFetched = ref(false);
|
||||
|
||||
async function fetchDdl() {
|
||||
@@ -1095,7 +1108,6 @@ function clearDraft() {
|
||||
}
|
||||
|
||||
function resetState() {
|
||||
activeTab.value = "columns";
|
||||
loading.value = false;
|
||||
saving.value = false;
|
||||
postSaveRefreshing.value = false;
|
||||
@@ -2075,7 +2087,8 @@ onMounted(() => {
|
||||
void loadDynamicDataTypeOptions();
|
||||
if (props.draft?.initialized) {
|
||||
restoreDraft(props.draft);
|
||||
applyInitialStructureTab();
|
||||
// A restored draft owns its saved tab unless navigation explicitly requested another one.
|
||||
applyInitialStructureTab(false);
|
||||
applyInitialStructureTarget();
|
||||
void hydrateRestoredDraftFromDatabase().then(() => applyInitialStructureTarget());
|
||||
} else if (isCreateMode.value) {
|
||||
@@ -2106,27 +2119,25 @@ onBeforeUnmount(() => {
|
||||
persistStructureDensity();
|
||||
});
|
||||
|
||||
function firstStructureMetadataTab(capabilities = tableMetadataCapabilities.value) {
|
||||
if (capabilities.columns) return "columns";
|
||||
if (capabilities.indexes) return "indexes";
|
||||
if (capabilities.foreignKeys) return "foreignKeys";
|
||||
if (capabilities.triggers) return "triggers";
|
||||
if (capabilities.ddl && !isCreateMode.value) return "ddl";
|
||||
return "columns";
|
||||
function localFirstStructureMetadataTab(capabilities = tableMetadataCapabilities.value) {
|
||||
return firstStructureMetadataTab(capabilities, isCreateMode.value);
|
||||
}
|
||||
|
||||
function isStructureMetadataTabSupported(tab: TableInfoTab, capabilities = tableMetadataCapabilities.value) {
|
||||
return (tab === "columns" && capabilities.columns) || (tab === "indexes" && capabilities.indexes) || (tab === "foreignKeys" && capabilities.foreignKeys) || (tab === "triggers" && capabilities.triggers) || (tab === "ddl" && capabilities.ddl && !isCreateMode.value);
|
||||
function localIsStructureMetadataTabSupported(tab: TableInfoTab, capabilities = tableMetadataCapabilities.value) {
|
||||
return isStructureMetadataTabSupported(tab, capabilities, isCreateMode.value);
|
||||
}
|
||||
|
||||
function resolveStructureMetadataTab(tab: TableInfoTab | undefined, capabilities = tableMetadataCapabilities.value): TableInfoTab {
|
||||
if (tab && isStructureMetadataTabSupported(tab, capabilities)) return tab;
|
||||
return firstStructureMetadataTab(capabilities);
|
||||
if (tab && localIsStructureMetadataTabSupported(tab, capabilities)) return tab;
|
||||
return localFirstStructureMetadataTab(capabilities);
|
||||
}
|
||||
|
||||
function applyInitialStructureTab() {
|
||||
if (!props.initialTab) return;
|
||||
activeTab.value = resolveStructureMetadataTab(props.initialTab);
|
||||
function applyInitialStructureTab(useDefault = true) {
|
||||
if (props.initialTab) {
|
||||
activeTab.value = resolveStructureMetadataTab(props.initialTab);
|
||||
} else if (useDefault) {
|
||||
activeTab.value = resolveStructureMetadataTab(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
function initialTargetKey(target: TableStructureEditorTarget): string {
|
||||
@@ -2166,7 +2177,7 @@ function applyInitialStructureTarget() {
|
||||
}
|
||||
|
||||
watch(tableMetadataCapabilities, (capabilities) => {
|
||||
if (!isStructureMetadataTabSupported(activeTab.value, capabilities)) activeTab.value = firstStructureMetadataTab(capabilities);
|
||||
if (!localIsStructureMetadataTabSupported(activeTab.value, capabilities)) activeTab.value = localFirstStructureMetadataTab(capabilities);
|
||||
});
|
||||
|
||||
watch([() => props.initialTab, () => props.initialTabRequestId, () => props.initialTarget], () => {
|
||||
@@ -2218,9 +2229,21 @@ watch(refreshVersion, (version, previous) => {
|
||||
void loadStructure(true);
|
||||
});
|
||||
|
||||
watch(activeTab, (tab) => {
|
||||
if (tab === "ddl") {
|
||||
void fetchDdl();
|
||||
watch(
|
||||
activeTab,
|
||||
(tab) => {
|
||||
if (tab === "ddl") {
|
||||
void fetchDdl();
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
watch([activeTab, ddlLoading], ([tab, loading]) => {
|
||||
if (tab === "ddl" && !loading) {
|
||||
void nextTick(() => {
|
||||
ddlPreRef.value?.focus();
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -2263,11 +2286,11 @@ watch(activeTab, (tab) => {
|
||||
<Tabs v-model="activeTab" class="flex h-full min-h-0 flex-col">
|
||||
<div class="flex shrink-0 items-center justify-between gap-2 border-b px-2 py-[var(--structure-header-py)]">
|
||||
<TabsList>
|
||||
<TabsTrigger v-if="tableMetadataCapabilities.ddl && !isCreateMode" value="ddl">DDL</TabsTrigger>
|
||||
<TabsTrigger v-if="tableMetadataCapabilities.columns" value="columns">{{ t("structureEditor.columns") }}</TabsTrigger>
|
||||
<TabsTrigger v-if="tableMetadataCapabilities.indexes" value="indexes">{{ t("structureEditor.indexes") }}</TabsTrigger>
|
||||
<TabsTrigger v-if="tableMetadataCapabilities.foreignKeys" value="foreignKeys">{{ t("structureEditor.foreignKeys") }}</TabsTrigger>
|
||||
<TabsTrigger v-if="tableMetadataCapabilities.triggers" value="triggers">{{ t("structureEditor.triggers") }}</TabsTrigger>
|
||||
<TabsTrigger v-if="tableMetadataCapabilities.ddl && !isCreateMode" value="ddl">DDL</TabsTrigger>
|
||||
</TabsList>
|
||||
<div class="flex shrink-0 items-center gap-1.5">
|
||||
<div class="flex items-center gap-1.5">
|
||||
@@ -2896,7 +2919,7 @@ watch(activeTab, (tab) => {
|
||||
<Loader2 class="h-4 w-4 animate-spin" />
|
||||
{{ t("common.loading") }}
|
||||
</div>
|
||||
<pre v-else class="m-0 min-h-0 flex-1 whitespace-pre p-3 font-mono text-xs leading-5 select-text" v-html="ddlContent ? (sqlHighlighter?.(ddlContent) ?? ddlContent) : t('structureEditor.emptyReadonly')"></pre>
|
||||
<pre v-else ref="ddlPreRef" tabindex="0" class="m-0 min-h-0 flex-1 whitespace-pre p-3 font-mono text-xs leading-5 select-text outline-none" v-html="ddlContent ? (sqlHighlighter?.(ddlContent) ?? ddlContent) : t('structureEditor.emptyReadonly')" @keydown="onDdlKeydown"></pre>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user