fix(schema-diff): align table selection layout

This commit is contained in:
jearhe authored and GitHub committed 2026-08-23 18:08:17 +08:00
1 parent 6a06a12455
commit 351dc81a30
2 files changed
+52 -33

No files matched your search

@@ -448,28 +448,6 @@ async function fetchDbVersion(connectionId: string, database: string, schema: st
/>
</div>
<!-- Source Table Selection -->
<div class="mt-3 space-y-1.5">
<div class="flex items-center justify-between gap-2">
<Label class="text-xs font-medium">{{ t("diff.tableSelection") }}</Label>
<Button v-if="restrictTables || canConfigureTableSelection" variant="ghost" size="sm" class="h-6 px-2 text-xs" @click="handleToggleRestrict(!restrictTables)">
{{ restrictTables ? t("diff.compareAllTables") : t("diff.chooseTables") }}
</Button>
</div>
<div v-if="!restrictTables" class="text-[11px] text-muted-foreground">
{{ t("diff.tableSelectionUnrestricted") }}
</div>
<TableMultiSelect
v-if="restrictTables && canConfigureTableSelection"
:key="`${sourceConnectionId}.${sourceDatabase}.${sourceSchema}`"
:model-value="localSelectedTables"
@update:model-value="handleUpdateSelectedTables"
:tables="sourceTableList"
:title="t('diff.sourceTables')"
:empty-text="t('dataCompare.noTables')"
/>
</div>
<!-- Source Info -->
<div v-if="getConnectionInfo(sourceConnectionId)" class="mt-4 p-3 rounded-lg bg-muted/30 border space-y-1.5">
<div class="text-xs font-medium text-blue-500">{{ t("diff.info") }}</div>
@@ -555,17 +533,6 @@ async function fetchDbVersion(connectionId: string, database: string, schema: st
/>
</div>
<!-- Target Same-Name Match -->
<div v-if="restrictTables && localSelectedTables.length && canConfigureTableSelection && isTableIdentityReady('target')" class="mt-3 space-y-1.5 rounded-lg border p-3 text-xs">
<div class="font-medium">{{ t("diff.autoMatchHint") }}</div>
<div class="text-muted-foreground">
{{ t("diff.matchedTables", { matched: matchResult.matched.length, total: localSelectedTables.length }) }}
</div>
<div v-if="missingTargetTables.length" class="text-destructive">
{{ t("diff.missingTargetTables", { tables: missingTargetTables.join(", ") }) }}
</div>
</div>
<!-- Target Info -->
<div v-if="getConnectionInfo(targetConnectionId)" class="mt-4 p-3 rounded-lg bg-muted/30 border space-y-1.5">
<div class="text-xs font-medium text-green-500">{{ t("diff.info") }}</div>
@@ -585,6 +552,41 @@ async function fetchDbVersion(connectionId: string, database: string, schema: st
</div>
</div>
<!-- Comparison Scope -->
<div class="space-y-3 rounded-lg border bg-muted/20 p-3">
<div class="space-y-1.5">
<div class="flex items-center justify-between gap-2">
<Label class="text-xs font-medium">{{ t("diff.tableSelection") }}</Label>
<Button v-if="restrictTables || canConfigureTableSelection" variant="ghost" size="sm" class="h-6 px-2 text-xs" @click="handleToggleRestrict(!restrictTables)">
{{ restrictTables ? t("diff.compareAllTables") : t("diff.chooseTables") }}
</Button>
</div>
<div v-if="!restrictTables" class="text-[11px] text-muted-foreground">
{{ t("diff.tableSelectionUnrestricted") }}
</div>
<TableMultiSelect
v-if="restrictTables && canConfigureTableSelection"
:key="`${sourceConnectionId}.${sourceDatabase}.${sourceSchema}`"
:model-value="localSelectedTables"
@update:model-value="handleUpdateSelectedTables"
:tables="sourceTableList"
:title="t('diff.sourceTables')"
:empty-text="t('dataCompare.noTables')"
/>
</div>
<!-- Target Same-Name Match -->
<div v-if="restrictTables && localSelectedTables.length && canConfigureTableSelection && isTableIdentityReady('target')" class="space-y-1.5 rounded-lg border p-3 text-xs">
<div class="font-medium">{{ t("diff.autoMatchHint") }}</div>
<div class="text-muted-foreground">
{{ t("diff.matchedTables", { matched: matchResult.matched.length, total: localSelectedTables.length }) }}
</div>
<div v-if="missingTargetTables.length" class="text-destructive">
{{ t("diff.missingTargetTables", { tables: missingTargetTables.join(", ") }) }}
</div>
</div>
</div>
<!-- Options -->
<div class="flex items-center gap-2 p-3 rounded-lg border bg-muted/20">
<input id="schema-diff-ignore-comments" :checked="ignoreComments" type="checkbox" class="accent-primary" @change="$emit('update:ignoreComments', ($event.target as HTMLInputElement).checked)" />
@@ -54,4 +54,21 @@ describe("SchemaDiffDialog fullscreen layout", () => {
expect(configStepSource).toContain('v-if="restrictTables && canConfigureTableSelection"');
expect(configStepSource).toContain("restrictTables && localSelectedTables.length && canConfigureTableSelection && isTableIdentityReady('target')");
});
it("keeps explicit table selection in a shared scope below both sides", () => {
const comparisonScope = configStepSource.indexOf("<!-- Comparison Scope -->");
const targetInfo = configStepSource.indexOf("<!-- Target Info -->");
const options = configStepSource.indexOf("<!-- Options -->");
const tableSelectors = configStepSource.match(/<TableMultiSelect\b/g) ?? [];
const tableSelector = configStepSource.indexOf("<TableMultiSelect", comparisonScope);
const targetMatch = configStepSource.indexOf("<!-- Target Same-Name Match -->", comparisonScope);
expect(comparisonScope).toBeGreaterThan(targetInfo);
expect(comparisonScope).toBeLessThan(options);
expect(tableSelectors).toHaveLength(1);
expect(tableSelector).toBeGreaterThan(comparisonScope);
expect(tableSelector).toBeLessThan(options);
expect(targetMatch).toBeGreaterThan(comparisonScope);
expect(targetMatch).toBeLessThan(options);
});
});