feat(ui): add searchable selects to compare and transfer dialogs
This commit is contained in:
parent
2e8d399dab
commit
f1f99f6f10
|
|
@ -6,6 +6,7 @@ import { Button } from "@/components/ui/button";
|
|||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import SearchableSelect from "@/components/ui/searchable-select/SearchableSelect.vue";
|
||||
import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import { useToast } from "@/composables/useToast";
|
||||
import { databaseOptionsForConnection } from "@/composables/useDatabaseOptions";
|
||||
|
|
@ -889,31 +890,46 @@ watch(
|
|||
<div class="grid grid-cols-[1fr_auto_1fr] gap-4 items-start">
|
||||
<div class="space-y-2">
|
||||
<Label class="text-xs font-medium">{{ t("diff.source") }}</Label>
|
||||
<Select :model-value="sourceConnectionId" @update:model-value="(v: any) => (sourceConnectionId = String(v))">
|
||||
<SelectTrigger class="h-8 text-xs">
|
||||
<SearchableSelect
|
||||
v-model="sourceConnectionId"
|
||||
:options="sqlConnections.map((c) => c.id)"
|
||||
:placeholder="t('diff.selectConnection')"
|
||||
:search-placeholder="t('diff.searchConnection')"
|
||||
:empty-text="t('common.noResults')"
|
||||
:display-name="(id) => sqlConnections.find((c) => c.id === id)?.name ?? id"
|
||||
trigger-variant="outline"
|
||||
trigger-class="h-8 w-full justify-between text-xs"
|
||||
content-class="w-[var(--reka-popover-trigger-width)]"
|
||||
>
|
||||
<template #option-label="{ option, label }">
|
||||
<div class="flex items-center gap-2">
|
||||
<DatabaseIcon v-if="sourceConnectionId" :db-type="connectionIconType(sourceConnectionId)" class="w-3.5 h-3.5" />
|
||||
<SelectValue :placeholder="t('diff.selectConnection')" />
|
||||
<DatabaseIcon :db-type="connectionIconType(option)" class="w-3.5 h-3.5" />
|
||||
{{ label }}
|
||||
</div>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="connection in sqlConnections" :key="connection.id" :value="connection.id">
|
||||
{{ connection.name }}
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Select :model-value="sourceDatabase" @update:model-value="(v: any) => (sourceDatabase = String(v))">
|
||||
<SelectTrigger class="h-8 text-xs"><SelectValue :placeholder="t('diff.selectDatabase')" /></SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="database in sourceDatabases" :key="database" :value="database">{{ database }}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Select v-if="sourceSchemas.length" :model-value="sourceSchema" @update:model-value="(v: any) => (sourceSchema = String(v))">
|
||||
<SelectTrigger class="h-8 text-xs"><SelectValue :placeholder="t('diff.selectSchema')" /></SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="schema in sourceSchemas" :key="schema" :value="schema">{{ schema }}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</template>
|
||||
</SearchableSelect>
|
||||
<SearchableSelect
|
||||
v-model="sourceDatabase"
|
||||
:options="sourceDatabases"
|
||||
:placeholder="t('diff.selectDatabase')"
|
||||
:search-placeholder="t('diff.searchDatabase')"
|
||||
:empty-text="t('common.noResults')"
|
||||
:disabled="!sourceDatabases.length"
|
||||
trigger-variant="outline"
|
||||
trigger-class="h-8 w-full justify-between text-xs"
|
||||
content-class="w-[var(--reka-popover-trigger-width)]"
|
||||
/>
|
||||
<SearchableSelect
|
||||
v-if="sourceSchemas.length"
|
||||
v-model="sourceSchema"
|
||||
:options="sourceSchemas"
|
||||
:placeholder="t('diff.selectSchema')"
|
||||
:search-placeholder="t('diff.searchSchema')"
|
||||
:empty-text="t('common.noResults')"
|
||||
trigger-variant="outline"
|
||||
trigger-class="h-8 w-full justify-between text-xs"
|
||||
content-class="w-[var(--reka-popover-trigger-width)]"
|
||||
/>
|
||||
|
||||
<div class="space-y-2 rounded-lg border p-2">
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
|
|
@ -960,42 +976,59 @@ watch(
|
|||
|
||||
<div class="space-y-2">
|
||||
<Label class="text-xs font-medium">{{ t("diff.target") }}</Label>
|
||||
<Select :model-value="targetConnectionId" @update:model-value="(v: any) => (targetConnectionId = String(v))">
|
||||
<SelectTrigger class="h-8 text-xs">
|
||||
<SearchableSelect
|
||||
v-model="targetConnectionId"
|
||||
:options="sqlConnections.map((c) => c.id)"
|
||||
:placeholder="t('diff.selectConnection')"
|
||||
:search-placeholder="t('diff.searchConnection')"
|
||||
:empty-text="t('common.noResults')"
|
||||
:display-name="(id) => sqlConnections.find((c) => c.id === id)?.name ?? id"
|
||||
trigger-variant="outline"
|
||||
trigger-class="h-8 w-full justify-between text-xs"
|
||||
content-class="w-[var(--reka-popover-trigger-width)]"
|
||||
>
|
||||
<template #option-label="{ option, label }">
|
||||
<div class="flex items-center gap-2">
|
||||
<DatabaseIcon v-if="targetConnectionId" :db-type="connectionIconType(targetConnectionId)" class="w-3.5 h-3.5" />
|
||||
<SelectValue :placeholder="t('diff.selectConnection')" />
|
||||
<DatabaseIcon :db-type="connectionIconType(option)" class="w-3.5 h-3.5" />
|
||||
{{ label }}
|
||||
</div>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="connection in sqlConnections" :key="connection.id" :value="connection.id">
|
||||
{{ connection.name }}
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Select :model-value="targetDatabase" @update:model-value="(v: any) => (targetDatabase = String(v))">
|
||||
<SelectTrigger class="h-8 text-xs"><SelectValue :placeholder="t('diff.selectDatabase')" /></SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="database in targetDatabases" :key="database" :value="database">{{ database }}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Select v-if="targetSchemas.length" :model-value="targetSchema" @update:model-value="(v: any) => (targetSchema = String(v))">
|
||||
<SelectTrigger class="h-8 text-xs"><SelectValue :placeholder="t('diff.selectSchema')" /></SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="schema in targetSchemas" :key="schema" :value="schema">{{ schema }}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</template>
|
||||
</SearchableSelect>
|
||||
<SearchableSelect
|
||||
v-model="targetDatabase"
|
||||
:options="targetDatabases"
|
||||
:placeholder="t('diff.selectDatabase')"
|
||||
:search-placeholder="t('diff.searchDatabase')"
|
||||
:empty-text="t('common.noResults')"
|
||||
:disabled="!targetDatabases.length"
|
||||
trigger-variant="outline"
|
||||
trigger-class="h-8 w-full justify-between text-xs"
|
||||
content-class="w-[var(--reka-popover-trigger-width)]"
|
||||
/>
|
||||
<SearchableSelect
|
||||
v-if="targetSchemas.length"
|
||||
v-model="targetSchema"
|
||||
:options="targetSchemas"
|
||||
:placeholder="t('diff.selectSchema')"
|
||||
:search-placeholder="t('diff.searchSchema')"
|
||||
:empty-text="t('common.noResults')"
|
||||
trigger-variant="outline"
|
||||
trigger-class="h-8 w-full justify-between text-xs"
|
||||
content-class="w-[var(--reka-popover-trigger-width)]"
|
||||
/>
|
||||
|
||||
<div v-if="!isBatchCompare" class="space-y-1">
|
||||
<Label class="text-xs font-medium">{{ t("dataCompare.targetTable") }}</Label>
|
||||
<Select :model-value="targetTable" @update:model-value="(v: any) => (targetTable = String(v))">
|
||||
<SelectTrigger class="h-8 text-xs">
|
||||
<SelectValue :placeholder="t('dataCompare.selectTable')" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="table in targetTables" :key="table" :value="table">{{ table }}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<SearchableSelect
|
||||
v-model="targetTable"
|
||||
:options="targetTables"
|
||||
:placeholder="t('dataCompare.selectTable')"
|
||||
:search-placeholder="t('dataCompare.searchTable')"
|
||||
:empty-text="t('common.noResults')"
|
||||
trigger-variant="outline"
|
||||
trigger-class="h-8 w-full justify-between text-xs"
|
||||
content-class="w-[var(--reka-popover-trigger-width)]"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="space-y-2 rounded-lg border p-3 text-xs">
|
||||
<div class="font-medium">{{ t("dataCompare.autoMatchHint") }}</div>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { useI18n } from "vue-i18n";
|
|||
import { Label } from "@/components/ui/label";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import SearchableSelect from "@/components/ui/searchable-select/SearchableSelect.vue";
|
||||
import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import DatabaseIcon from "@/components/icons/DatabaseIcon.vue";
|
||||
import * as api from "@/lib/api";
|
||||
|
|
@ -253,46 +254,57 @@ async function fetchDbVersion(connectionId: string, database: string, schema: st
|
|||
|
||||
<div class="space-y-1.5">
|
||||
<Label class="text-xs">{{ t("diff.connection") }}</Label>
|
||||
<Select :model-value="sourceConnectionId" @update:model-value="(v: any) => $emit('update:sourceConnectionId', String(v))">
|
||||
<SelectTrigger class="h-8 text-xs">
|
||||
<SearchableSelect
|
||||
:model-value="sourceConnectionId"
|
||||
@update:model-value="(v: string) => $emit('update:sourceConnectionId', v)"
|
||||
:options="sqlConnections.map((c) => c.id)"
|
||||
:placeholder="t('diff.selectConnection')"
|
||||
:search-placeholder="t('diff.searchConnection')"
|
||||
:empty-text="t('common.noResults')"
|
||||
:display-name="(id) => sqlConnections.find((c) => c.id === id)?.name ?? id"
|
||||
trigger-variant="outline"
|
||||
trigger-class="h-8 w-full justify-between text-xs"
|
||||
content-class="w-[var(--reka-popover-trigger-width)]"
|
||||
>
|
||||
<template #option-label="{ option, label }">
|
||||
<div class="flex items-center gap-2">
|
||||
<DatabaseIcon v-if="sourceConnectionId" :db-type="connectionIconType(sourceConnectionId)" class="w-3.5 h-3.5" />
|
||||
<SelectValue :placeholder="t('diff.selectConnection')" />
|
||||
<DatabaseIcon :db-type="sqlConnections.find((c) => c.id === option)?.driver_profile || sqlConnections.find((c) => c.id === option)?.db_type || 'mysql'" class="w-3.5 h-3.5" />
|
||||
{{ label }}
|
||||
</div>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="c in sqlConnections" :key="c.id" :value="c.id">
|
||||
<div class="flex items-center gap-2">
|
||||
<DatabaseIcon :db-type="c.driver_profile || c.db_type" class="w-3.5 h-3.5" />
|
||||
{{ c.name }}
|
||||
</div>
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</template>
|
||||
</SearchableSelect>
|
||||
</div>
|
||||
|
||||
<div class="space-y-1.5">
|
||||
<Label class="text-xs">{{ t("diff.database") }}</Label>
|
||||
<Select :model-value="sourceDatabase" @update:model-value="(v: any) => $emit('update:sourceDatabase', String(v))">
|
||||
<SelectTrigger class="h-8 text-xs" :disabled="!sourceDatabases.length">
|
||||
<SelectValue :placeholder="t('diff.selectDatabase')" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="db in sourceDatabases" :key="db" :value="db">{{ db }}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<SearchableSelect
|
||||
:model-value="sourceDatabase"
|
||||
@update:model-value="(v: string) => $emit('update:sourceDatabase', v)"
|
||||
:options="sourceDatabases"
|
||||
:placeholder="t('diff.selectDatabase')"
|
||||
:search-placeholder="t('diff.searchDatabase')"
|
||||
:empty-text="t('common.noResults')"
|
||||
:disabled="!sourceDatabases.length"
|
||||
trigger-variant="outline"
|
||||
trigger-class="h-8 w-full justify-between text-xs"
|
||||
content-class="w-[var(--reka-popover-trigger-width)]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="isSchemaAware(sourceConfig?.db_type)" class="space-y-1.5">
|
||||
<Label class="text-xs">{{ t("diff.schema") }}</Label>
|
||||
<Select :model-value="sourceSchema" @update:model-value="(v: any) => $emit('update:sourceSchema', String(v))">
|
||||
<SelectTrigger class="h-8 text-xs" :disabled="!sourceSchemas.length">
|
||||
<SelectValue :placeholder="t('diff.selectSchema')" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="schema in sourceSchemas" :key="schema" :value="schema">{{ schema }}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<SearchableSelect
|
||||
:model-value="sourceSchema"
|
||||
@update:model-value="(v: string) => $emit('update:sourceSchema', v)"
|
||||
:options="sourceSchemas"
|
||||
:placeholder="t('diff.selectSchema')"
|
||||
:search-placeholder="t('diff.searchSchema')"
|
||||
:empty-text="t('common.noResults')"
|
||||
:disabled="!sourceSchemas.length"
|
||||
trigger-variant="outline"
|
||||
trigger-class="h-8 w-full justify-between text-xs"
|
||||
content-class="w-[var(--reka-popover-trigger-width)]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Source Info -->
|
||||
|
|
@ -326,46 +338,57 @@ async function fetchDbVersion(connectionId: string, database: string, schema: st
|
|||
|
||||
<div class="space-y-1.5">
|
||||
<Label class="text-xs">{{ t("diff.connection") }}</Label>
|
||||
<Select :model-value="targetConnectionId" @update:model-value="(v: any) => $emit('update:targetConnectionId', String(v))">
|
||||
<SelectTrigger class="h-8 text-xs">
|
||||
<SearchableSelect
|
||||
:model-value="targetConnectionId"
|
||||
@update:model-value="(v: string) => $emit('update:targetConnectionId', v)"
|
||||
:options="sqlConnections.map((c) => c.id)"
|
||||
:placeholder="t('diff.selectConnection')"
|
||||
:search-placeholder="t('diff.searchConnection')"
|
||||
:empty-text="t('common.noResults')"
|
||||
:display-name="(id) => sqlConnections.find((c) => c.id === id)?.name ?? id"
|
||||
trigger-variant="outline"
|
||||
trigger-class="h-8 w-full justify-between text-xs"
|
||||
content-class="w-[var(--reka-popover-trigger-width)]"
|
||||
>
|
||||
<template #option-label="{ option, label }">
|
||||
<div class="flex items-center gap-2">
|
||||
<DatabaseIcon v-if="targetConnectionId" :db-type="connectionIconType(targetConnectionId)" class="w-3.5 h-3.5" />
|
||||
<SelectValue :placeholder="t('diff.selectConnection')" />
|
||||
<DatabaseIcon :db-type="sqlConnections.find((c) => c.id === option)?.driver_profile || sqlConnections.find((c) => c.id === option)?.db_type || 'mysql'" class="w-3.5 h-3.5" />
|
||||
{{ label }}
|
||||
</div>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="c in sqlConnections" :key="c.id" :value="c.id">
|
||||
<div class="flex items-center gap-2">
|
||||
<DatabaseIcon :db-type="c.driver_profile || c.db_type" class="w-3.5 h-3.5" />
|
||||
{{ c.name }}
|
||||
</div>
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</template>
|
||||
</SearchableSelect>
|
||||
</div>
|
||||
|
||||
<div class="space-y-1.5">
|
||||
<Label class="text-xs">{{ t("diff.database") }}</Label>
|
||||
<Select :model-value="targetDatabase" @update:model-value="(v: any) => $emit('update:targetDatabase', String(v))">
|
||||
<SelectTrigger class="h-8 text-xs" :disabled="!targetDatabases.length">
|
||||
<SelectValue :placeholder="t('diff.selectDatabase')" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="db in targetDatabases" :key="db" :value="db">{{ db }}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<SearchableSelect
|
||||
:model-value="targetDatabase"
|
||||
@update:model-value="(v: string) => $emit('update:targetDatabase', v)"
|
||||
:options="targetDatabases"
|
||||
:placeholder="t('diff.selectDatabase')"
|
||||
:search-placeholder="t('diff.searchDatabase')"
|
||||
:empty-text="t('common.noResults')"
|
||||
:disabled="!targetDatabases.length"
|
||||
trigger-variant="outline"
|
||||
trigger-class="h-8 w-full justify-between text-xs"
|
||||
content-class="w-[var(--reka-popover-trigger-width)]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="isSchemaAware(targetConfig?.db_type)" class="space-y-1.5">
|
||||
<Label class="text-xs">{{ t("diff.schema") }}</Label>
|
||||
<Select :model-value="targetSchema" @update:model-value="(v: any) => $emit('update:targetSchema', String(v))">
|
||||
<SelectTrigger class="h-8 text-xs" :disabled="!targetSchemas.length">
|
||||
<SelectValue :placeholder="t('diff.selectSchema')" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="schema in targetSchemas" :key="schema" :value="schema">{{ schema }}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<SearchableSelect
|
||||
:model-value="targetSchema"
|
||||
@update:model-value="(v: string) => $emit('update:targetSchema', v)"
|
||||
:options="targetSchemas"
|
||||
:placeholder="t('diff.selectSchema')"
|
||||
:search-placeholder="t('diff.searchSchema')"
|
||||
:empty-text="t('common.noResults')"
|
||||
:disabled="!targetSchemas.length"
|
||||
trigger-variant="outline"
|
||||
trigger-class="h-8 w-full justify-between text-xs"
|
||||
content-class="w-[var(--reka-popover-trigger-width)]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Target Info -->
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { Button } from "@/components/ui/button";
|
|||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import SearchableSelect from "@/components/ui/searchable-select/SearchableSelect.vue";
|
||||
import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import DatabaseIcon from "@/components/icons/DatabaseIcon.vue";
|
||||
import * as api from "@/lib/api";
|
||||
|
|
@ -15,7 +16,7 @@ import type { DatabaseType } from "@/types/database";
|
|||
import { isSchemaAware, supportsTransfer } from "@/lib/databaseCapabilities";
|
||||
import { databaseOptionsForConnection } from "@/composables/useDatabaseOptions";
|
||||
import { useExportTracker } from "@/composables/useExportTracker";
|
||||
import { ArrowRightLeft, Loader2, Square, CheckSquare } from "@lucide/vue";
|
||||
import { ArrowRightLeft, ArrowLeftRight, Loader2, Square, CheckSquare } from "@lucide/vue";
|
||||
|
||||
const { t } = useI18n();
|
||||
const { startDataTransferTask } = useExportTracker();
|
||||
|
|
@ -289,15 +290,11 @@ async function startTransfer() {
|
|||
function getConnectionName(id: string) {
|
||||
return store.connections.find((c) => c.id === id)?.name ?? id;
|
||||
}
|
||||
|
||||
function getConnectionType(id: string): DatabaseType {
|
||||
return store.connections.find((c) => c.id === id)?.db_type ?? "mysql";
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Dialog v-model:open="open">
|
||||
<DialogContent class="sm:max-w-[560px] max-h-[80vh] flex flex-col overflow-hidden" @interact-outside.prevent>
|
||||
<DialogContent class="sm:max-w-[780px] max-h-[80vh] flex flex-col overflow-hidden" @interact-outside.prevent>
|
||||
<DialogHeader>
|
||||
<DialogTitle class="flex items-center gap-2">
|
||||
<ArrowRightLeft class="w-4 h-4" />
|
||||
|
|
@ -307,111 +304,127 @@ function getConnectionType(id: string): DatabaseType {
|
|||
|
||||
<div class="flex-1 min-h-0 overflow-auto">
|
||||
<div class="grid gap-4 py-3">
|
||||
<!-- Source Section -->
|
||||
<div class="space-y-3">
|
||||
<div class="text-xs font-medium text-muted-foreground uppercase tracking-wider">
|
||||
{{ t("transfer.source") }}
|
||||
</div>
|
||||
<!-- Source / Target Side by Side -->
|
||||
<div class="grid grid-cols-[1fr_auto_1fr] gap-4 items-start">
|
||||
<!-- Source Section -->
|
||||
<div class="space-y-3">
|
||||
<div class="text-sm font-medium text-blue-500">
|
||||
{{ t("transfer.source") }}
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<div class="space-y-1.5">
|
||||
<Label class="text-xs">{{ t("transfer.sourceConnection") }}</Label>
|
||||
<Select v-model="sourceConnectionId">
|
||||
<SelectTrigger class="h-8 text-xs">
|
||||
<div v-if="sourceConnectionId" class="flex items-center gap-1.5">
|
||||
<DatabaseIcon :db-type="getConnectionType(sourceConnectionId)" class="w-3.5 h-3.5" />
|
||||
<span class="truncate">{{ getConnectionName(sourceConnectionId) }}</span>
|
||||
<SearchableSelect
|
||||
v-model="sourceConnectionId"
|
||||
:options="sqlConnections.map((c) => c.id)"
|
||||
:placeholder="t('transfer.selectConnection')"
|
||||
:search-placeholder="t('transfer.searchConnection')"
|
||||
:empty-text="t('common.noResults')"
|
||||
:display-name="getConnectionName"
|
||||
trigger-variant="outline"
|
||||
trigger-class="h-8 w-full justify-between text-xs"
|
||||
content-class="w-[var(--reka-popover-trigger-width)]"
|
||||
>
|
||||
<template #option-label="{ option, label }">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<DatabaseIcon :db-type="sqlConnections.find((c) => c.id === option)?.db_type ?? 'mysql'" class="w-3.5 h-3.5" />
|
||||
{{ label }}
|
||||
</div>
|
||||
<SelectValue v-else />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="c in sqlConnections" :key="c.id" :value="c.id">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<DatabaseIcon :db-type="c.db_type" class="w-3.5 h-3.5" />
|
||||
{{ c.name }}
|
||||
</div>
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</template>
|
||||
</SearchableSelect>
|
||||
</div>
|
||||
|
||||
<div class="space-y-1.5">
|
||||
<Label class="text-xs">{{ t("transfer.sourceDatabase") }}</Label>
|
||||
<Select v-model="sourceDatabase" :disabled="!sourceDatabases.length">
|
||||
<SelectTrigger class="h-8 text-xs">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="db in sourceDatabases" :key="db" :value="db">{{ db }}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<SearchableSelect
|
||||
v-model="sourceDatabase"
|
||||
:options="sourceDatabases"
|
||||
:placeholder="t('transfer.selectDatabase')"
|
||||
:search-placeholder="t('transfer.searchDatabase')"
|
||||
:empty-text="t('common.noResults')"
|
||||
:disabled="!sourceDatabases.length"
|
||||
trigger-variant="outline"
|
||||
trigger-class="h-8 w-full justify-between text-xs"
|
||||
content-class="w-[var(--reka-popover-trigger-width)]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="sourceSchemas.length" class="space-y-1.5">
|
||||
<Label class="text-xs">{{ t("transfer.sourceSchema") }}</Label>
|
||||
<SearchableSelect
|
||||
v-model="sourceSchema"
|
||||
:options="sourceSchemas"
|
||||
:placeholder="t('transfer.selectSchema')"
|
||||
:search-placeholder="t('transfer.searchSchema')"
|
||||
:empty-text="t('common.noResults')"
|
||||
trigger-variant="outline"
|
||||
trigger-class="h-8 w-full justify-between text-xs"
|
||||
content-class="w-[var(--reka-popover-trigger-width)]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="sourceSchemas.length" class="space-y-1.5">
|
||||
<Label class="text-xs">{{ t("transfer.sourceSchema") }}</Label>
|
||||
<Select v-model="sourceSchema">
|
||||
<SelectTrigger class="h-8 text-xs">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="schema in sourceSchemas" :key="schema" :value="schema">{{ schema }}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Target Section -->
|
||||
<div class="space-y-3">
|
||||
<div class="text-xs font-medium text-muted-foreground uppercase tracking-wider">
|
||||
{{ t("transfer.target") }}
|
||||
<!-- Arrow -->
|
||||
<div class="flex items-center pt-8">
|
||||
<ArrowLeftRight class="w-5 h-5 text-muted-foreground" />
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<!-- Target Section -->
|
||||
<div class="space-y-3">
|
||||
<div class="text-sm font-medium text-green-500">
|
||||
{{ t("transfer.target") }}
|
||||
</div>
|
||||
|
||||
<div class="space-y-1.5">
|
||||
<Label class="text-xs">{{ t("transfer.targetConnection") }}</Label>
|
||||
<Select v-model="targetConnectionId">
|
||||
<SelectTrigger class="h-8 text-xs">
|
||||
<div v-if="targetConnectionId" class="flex items-center gap-1.5">
|
||||
<DatabaseIcon :db-type="getConnectionType(targetConnectionId)" class="w-3.5 h-3.5" />
|
||||
<span class="truncate">{{ getConnectionName(targetConnectionId) }}</span>
|
||||
<SearchableSelect
|
||||
v-model="targetConnectionId"
|
||||
:options="sqlConnections.map((c) => c.id)"
|
||||
:placeholder="t('transfer.selectConnection')"
|
||||
:search-placeholder="t('transfer.searchConnection')"
|
||||
:empty-text="t('common.noResults')"
|
||||
:display-name="getConnectionName"
|
||||
trigger-variant="outline"
|
||||
trigger-class="h-8 w-full justify-between text-xs"
|
||||
content-class="w-[var(--reka-popover-trigger-width)]"
|
||||
>
|
||||
<template #option-label="{ option, label }">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<DatabaseIcon :db-type="sqlConnections.find((c) => c.id === option)?.db_type ?? 'mysql'" class="w-3.5 h-3.5" />
|
||||
{{ label }}
|
||||
</div>
|
||||
<SelectValue v-else />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="c in sqlConnections" :key="c.id" :value="c.id">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<DatabaseIcon :db-type="c.db_type" class="w-3.5 h-3.5" />
|
||||
{{ c.name }}
|
||||
</div>
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</template>
|
||||
</SearchableSelect>
|
||||
</div>
|
||||
|
||||
<div class="space-y-1.5">
|
||||
<Label class="text-xs">{{ t("transfer.targetDatabase") }}</Label>
|
||||
<Select v-model="targetDatabase" :disabled="!targetDatabases.length">
|
||||
<SelectTrigger class="h-8 text-xs">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="db in targetDatabases" :key="db" :value="db">{{ db }}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<SearchableSelect
|
||||
v-model="targetDatabase"
|
||||
:options="targetDatabases"
|
||||
:placeholder="t('transfer.selectDatabase')"
|
||||
:search-placeholder="t('transfer.searchDatabase')"
|
||||
:empty-text="t('common.noResults')"
|
||||
:disabled="!targetDatabases.length"
|
||||
trigger-variant="outline"
|
||||
trigger-class="h-8 w-full justify-between text-xs"
|
||||
content-class="w-[var(--reka-popover-trigger-width)]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="targetSchemas.length" class="space-y-1.5">
|
||||
<Label class="text-xs">{{ t("transfer.targetSchema") }}</Label>
|
||||
<Select v-model="targetSchema">
|
||||
<SelectTrigger class="h-8 text-xs">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-for="schema in targetSchemas" :key="schema" :value="schema">{{ schema }}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<div v-if="targetSchemas.length" class="space-y-1.5">
|
||||
<Label class="text-xs">{{ t("transfer.targetSchema") }}</Label>
|
||||
<SearchableSelect
|
||||
v-model="targetSchema"
|
||||
:options="targetSchemas"
|
||||
:placeholder="t('transfer.selectSchema')"
|
||||
:search-placeholder="t('transfer.searchSchema')"
|
||||
:empty-text="t('common.noResults')"
|
||||
trigger-variant="outline"
|
||||
trigger-class="h-8 w-full justify-between text-xs"
|
||||
content-class="w-[var(--reka-popover-trigger-width)]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, nextTick, ref, watch } from "vue";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { Check, ChevronDown, Search } from "@lucide/vue";
|
||||
import { Check, ChevronDown, Search, X } from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import type { ButtonVariants } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
|
|
@ -16,8 +16,9 @@ const props = withDefaults(
|
|||
placeholder: string;
|
||||
searchPlaceholder: string;
|
||||
emptyText: string;
|
||||
loadingText: string;
|
||||
loadingText?: string;
|
||||
loading?: boolean;
|
||||
disabled?: boolean;
|
||||
allowCustom?: boolean;
|
||||
triggerVariant?: ButtonVariants["variant"];
|
||||
triggerClass?: HTMLAttributes["class"];
|
||||
|
|
@ -25,10 +26,14 @@ const props = withDefaults(
|
|||
itemClass?: HTMLAttributes["class"];
|
||||
displayName?: (option: string) => string;
|
||||
normalizeCustom?: (value: string) => string;
|
||||
clearable?: boolean;
|
||||
}>(),
|
||||
{
|
||||
loading: false,
|
||||
disabled: false,
|
||||
allowCustom: false,
|
||||
clearable: false,
|
||||
loadingText: "Loading...",
|
||||
triggerVariant: "ghost",
|
||||
displayName: (option: string) => option,
|
||||
normalizeCustom: (value: string) => value,
|
||||
|
|
@ -149,11 +154,12 @@ function handleKeydown(event: KeyboardEvent) {
|
|||
<template>
|
||||
<Popover v-model:open="open">
|
||||
<PopoverTrigger as-child>
|
||||
<Button type="button" :variant="triggerVariant" :title="selectedLabel" :class="cn('h-6 w-auto max-w-56 min-w-0 justify-between gap-1 border-0 bg-transparent px-1 text-xs font-normal shadow-none hover:bg-muted/50 focus-visible:ring-0', triggerClass)">
|
||||
<Button type="button" :variant="triggerVariant" :disabled="disabled" :title="selectedLabel" :class="cn('h-6 w-auto max-w-56 min-w-0 justify-between gap-1 border-0 bg-transparent px-1 text-xs font-normal shadow-none hover:bg-muted/50 focus-visible:ring-0', triggerClass)">
|
||||
<slot name="trigger-label" :value="modelValue" :label="selectedLabel" :loading="loading">
|
||||
<span class="truncate">{{ loading ? loadingText : selectedLabel }}</span>
|
||||
</slot>
|
||||
<ChevronDown class="h-3 w-3 shrink-0 opacity-60" />
|
||||
<X v-if="clearable && !disabled && modelValue" class="h-3 w-3 shrink-0 opacity-60 hover:opacity-100" @pointerdown.stop.prevent="emit('update:modelValue', '')" />
|
||||
<ChevronDown v-else class="h-3 w-3 shrink-0 opacity-60" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent align="end" :class="cn('w-52 gap-1 p-1.5', contentClass)">
|
||||
|
|
@ -182,8 +188,8 @@ function handleKeydown(event: KeyboardEvent) {
|
|||
@click="selectOption(option)"
|
||||
>
|
||||
<Check :class="cn('h-3.5 w-3.5 shrink-0', option === modelValue ? 'opacity-100' : 'opacity-0')" />
|
||||
<slot name="option-label" :option="option" :label="displayName(option)">
|
||||
<span class="truncate">{{ displayName(option) }}</span>
|
||||
<slot name="option-label" :option="option" :label="displayName?.(option)">
|
||||
<span class="truncate">{{ displayName?.(option) }}</span>
|
||||
</slot>
|
||||
</button>
|
||||
<button
|
||||
|
|
|
|||
|
|
@ -934,6 +934,7 @@ export default {
|
|||
sequence: "Sequence",
|
||||
package: "Package",
|
||||
packageBody: "Package Body",
|
||||
noResults: "No results",
|
||||
},
|
||||
quickOpen: {
|
||||
placeholder: "Search connections, databases, tables, and other objects...",
|
||||
|
|
@ -2015,6 +2016,12 @@ export default {
|
|||
editConfig: "Edit config",
|
||||
retry: "Retry",
|
||||
targetTableBusy: "Another transfer is already writing target table(s): {tables}",
|
||||
selectConnection: "Select connection",
|
||||
selectDatabase: "Select database",
|
||||
selectSchema: "Select schema",
|
||||
searchConnection: "Search connections...",
|
||||
searchDatabase: "Search databases...",
|
||||
searchSchema: "Search schemas...",
|
||||
},
|
||||
tableImport: {
|
||||
title: "Import Table Data",
|
||||
|
|
@ -2328,6 +2335,9 @@ export default {
|
|||
copied: "Copied to clipboard",
|
||||
saveConfigPrompt: "Please enter config name:",
|
||||
close: "Close",
|
||||
searchConnection: "Search connections...",
|
||||
searchDatabase: "Search databases...",
|
||||
searchSchema: "Search schemas...",
|
||||
},
|
||||
schemaDiff: {
|
||||
optionsTitle: "Compare Options",
|
||||
|
|
@ -2381,6 +2391,7 @@ export default {
|
|||
dataCompare: {
|
||||
title: "Compare Data",
|
||||
selectTable: "Select table",
|
||||
searchTable: "Search tables...",
|
||||
sourceTables: "Source tables",
|
||||
targetTable: "Target table",
|
||||
searchTables: "Search tables...",
|
||||
|
|
|
|||
|
|
@ -919,6 +919,7 @@ export default withEnglishFallback({
|
|||
sequence: "Secuencia",
|
||||
package: "Paquete",
|
||||
packageBody: "Cuerpo del Paquete",
|
||||
noResults: "Sin resultados",
|
||||
},
|
||||
quickOpen: {
|
||||
placeholder: "Buscar conexiones, bases de datos, tablas y otros objetos...",
|
||||
|
|
@ -1996,6 +1997,12 @@ export default withEnglishFallback({
|
|||
editConfig: "Editar config",
|
||||
retry: "Reintentar",
|
||||
targetTableBusy: "Otra transferencia ya está escribiendo en la(s) tabla(s) de destino: {tables}",
|
||||
selectConnection: "Seleccionar conexión",
|
||||
selectDatabase: "Seleccionar base de datos",
|
||||
selectSchema: "Seleccionar esquema",
|
||||
searchConnection: "Buscar conexiones...",
|
||||
searchDatabase: "Buscar bases de datos...",
|
||||
searchSchema: "Buscar esquemas...",
|
||||
},
|
||||
tableImport: {
|
||||
title: "Importar datos a tabla",
|
||||
|
|
@ -2309,6 +2316,9 @@ export default withEnglishFallback({
|
|||
copied: "Copiado al portapapeles",
|
||||
saveConfigPrompt: "Por favor ingresa el nombre de la config:",
|
||||
close: "Cerrar",
|
||||
searchConnection: "Buscar conexiones...",
|
||||
searchDatabase: "Buscar bases de datos...",
|
||||
searchSchema: "Buscar esquemas...",
|
||||
},
|
||||
schemaDiff: {
|
||||
optionsTitle: "Opciones de comparación",
|
||||
|
|
@ -2362,6 +2372,7 @@ export default withEnglishFallback({
|
|||
dataCompare: {
|
||||
title: "Comparar datos",
|
||||
selectTable: "Seleccionar tabla",
|
||||
searchTable: "Buscar tablas...",
|
||||
sourceTables: "Tablas de origen",
|
||||
targetTable: "Tabla de destino",
|
||||
searchTables: "Buscar tablas...",
|
||||
|
|
|
|||
|
|
@ -922,6 +922,7 @@ export default withEnglishFallback({
|
|||
sequence: "Sequenza",
|
||||
package: "Pacchetto",
|
||||
packageBody: "Corpo Pacchetto",
|
||||
noResults: "Nessun risultato",
|
||||
},
|
||||
quickOpen: {
|
||||
placeholder: "Cerca connessioni, database, tabelle e altri oggetti...",
|
||||
|
|
@ -1999,6 +2000,12 @@ export default withEnglishFallback({
|
|||
editConfig: "Modifica config",
|
||||
retry: "Riprova",
|
||||
targetTableBusy: "Un altro trasferimento sta gia scrivendo le tabelle di destinazione: {tables}",
|
||||
selectConnection: "Seleziona connessione",
|
||||
selectDatabase: "Seleziona database",
|
||||
selectSchema: "Seleziona schema",
|
||||
searchConnection: "Cerca connessioni...",
|
||||
searchDatabase: "Cerca database...",
|
||||
searchSchema: "Cerca schemi...",
|
||||
},
|
||||
tableImport: {
|
||||
title: "Importa Dati Tabella",
|
||||
|
|
@ -2312,6 +2319,9 @@ export default withEnglishFallback({
|
|||
copied: "Copiato negli appunti",
|
||||
saveConfigPrompt: "Inserisci nome configurazione:",
|
||||
close: "Chiudi",
|
||||
searchConnection: "Cerca connessioni...",
|
||||
searchDatabase: "Cerca database...",
|
||||
searchSchema: "Cerca schemi...",
|
||||
},
|
||||
schemaDiff: {
|
||||
optionsTitle: "Opzioni di Confronto",
|
||||
|
|
@ -2365,6 +2375,7 @@ export default withEnglishFallback({
|
|||
dataCompare: {
|
||||
title: "Confronta Dati",
|
||||
selectTable: "Seleziona tabella",
|
||||
searchTable: "Cerca tabelle...",
|
||||
sourceTables: "Tabelle sorgente",
|
||||
targetTable: "Tabella di destinazione",
|
||||
searchTables: "Cerca tabelle...",
|
||||
|
|
|
|||
|
|
@ -920,6 +920,7 @@ export default withEnglishFallback({
|
|||
copy: "コピー",
|
||||
import: "インポート",
|
||||
remove: "削除",
|
||||
noResults: "結果なし",
|
||||
},
|
||||
quickOpen: {
|
||||
placeholder: "接続、データベース、テーブル、その他のオブジェクトを検索...",
|
||||
|
|
@ -1997,6 +1998,12 @@ export default withEnglishFallback({
|
|||
editConfig: "設定を編集",
|
||||
retry: "リトライ",
|
||||
targetTableBusy: "別の転送がすでにターゲットテーブルに書き込み中です: {tables}",
|
||||
selectConnection: "接続を選択",
|
||||
selectDatabase: "データベースを選択",
|
||||
selectSchema: "スキーマを選択",
|
||||
searchConnection: "接続を検索...",
|
||||
searchDatabase: "データベースを検索...",
|
||||
searchSchema: "スキーマを検索...",
|
||||
},
|
||||
tableImport: {
|
||||
title: "テーブルデータをインポート",
|
||||
|
|
@ -2310,6 +2317,9 @@ export default withEnglishFallback({
|
|||
port: "ポート",
|
||||
copied: "クリップボードにコピーしました",
|
||||
saveConfigPrompt: "設定名を入力してください:",
|
||||
searchConnection: "接続を検索...",
|
||||
searchDatabase: "データベースを検索...",
|
||||
searchSchema: "スキーマを検索...",
|
||||
},
|
||||
schemaDiff: {
|
||||
optionsTitle: "比較オプション",
|
||||
|
|
@ -2363,6 +2373,7 @@ export default withEnglishFallback({
|
|||
dataCompare: {
|
||||
title: "データを比較",
|
||||
selectTable: "テーブルを選択",
|
||||
searchTable: "テーブルを検索...",
|
||||
sourceTables: "ソーステーブル",
|
||||
targetTable: "対象テーブル",
|
||||
searchTables: "テーブルを検索...",
|
||||
|
|
|
|||
|
|
@ -931,6 +931,7 @@ export default withEnglishFallback({
|
|||
sequence: "Sequência",
|
||||
package: "Pacote",
|
||||
packageBody: "Corpo do Pacote",
|
||||
noResults: "Sem resultados",
|
||||
},
|
||||
quickOpen: {
|
||||
placeholder: "Pesquisar conexões, bancos de dados, tabelas e outros objetos...",
|
||||
|
|
@ -2008,6 +2009,12 @@ export default withEnglishFallback({
|
|||
editConfig: "Editar configuração",
|
||||
retry: "Tentar novamente",
|
||||
targetTableBusy: "Outra transferência já está gravando na(s) tabela(s) de destino: {tables}",
|
||||
selectConnection: "Selecionar conexão",
|
||||
selectDatabase: "Selecionar banco de dados",
|
||||
selectSchema: "Selecionar schema",
|
||||
searchConnection: "Pesquisar conexões...",
|
||||
searchDatabase: "Pesquisar bancos de dados...",
|
||||
searchSchema: "Pesquisar schemas...",
|
||||
},
|
||||
tableImport: {
|
||||
title: "Importar Dados da Tabela",
|
||||
|
|
@ -2321,6 +2328,9 @@ export default withEnglishFallback({
|
|||
copied: "Copiado para a área de transferência",
|
||||
saveConfigPrompt: "Digite o nome da configuração:",
|
||||
close: "Fechar",
|
||||
searchConnection: "Pesquisar conexões...",
|
||||
searchDatabase: "Pesquisar bancos de dados...",
|
||||
searchSchema: "Pesquisar schemas...",
|
||||
},
|
||||
schemaDiff: {
|
||||
optionsTitle: "Opções de Comparação",
|
||||
|
|
@ -2374,6 +2384,7 @@ export default withEnglishFallback({
|
|||
dataCompare: {
|
||||
title: "Comparar Dados",
|
||||
selectTable: "Selecionar tabela",
|
||||
searchTable: "Pesquisar tabelas...",
|
||||
sourceTables: "Tabelas de origem",
|
||||
targetTable: "Tabela de destino",
|
||||
searchTables: "Pesquisar tabelas...",
|
||||
|
|
|
|||
|
|
@ -937,6 +937,7 @@ export default withEnglishFallback({
|
|||
sequence: "序列",
|
||||
package: "包",
|
||||
packageBody: "包体",
|
||||
noResults: "无结果",
|
||||
},
|
||||
quickOpen: {
|
||||
placeholder: "搜索连接、数据库、表和其他对象...",
|
||||
|
|
@ -2018,6 +2019,12 @@ export default withEnglishFallback({
|
|||
editConfig: "编辑配置",
|
||||
retry: "重新传输",
|
||||
targetTableBusy: "已有传输任务正在写入目标表:{tables}",
|
||||
selectConnection: "选择连接",
|
||||
selectDatabase: "选择数据库",
|
||||
selectSchema: "选择模式",
|
||||
searchConnection: "搜索连接...",
|
||||
searchDatabase: "搜索数据库...",
|
||||
searchSchema: "搜索模式...",
|
||||
},
|
||||
tableImport: {
|
||||
title: "导入表数据",
|
||||
|
|
@ -2335,6 +2342,9 @@ export default withEnglishFallback({
|
|||
configDeleted: "配置已删除",
|
||||
noDeployScriptAll: "暂无所选对象的部署脚本",
|
||||
saveConfigPrompt: "请输入配置名称:",
|
||||
searchConnection: "搜索连接...",
|
||||
searchDatabase: "搜索数据库...",
|
||||
searchSchema: "搜索模式...",
|
||||
},
|
||||
schemaDiff: {
|
||||
optionsTitle: "比较选项",
|
||||
|
|
@ -2388,6 +2398,7 @@ export default withEnglishFallback({
|
|||
dataCompare: {
|
||||
title: "比较数据",
|
||||
selectTable: "选择表",
|
||||
searchTable: "搜索表名...",
|
||||
sourceTables: "源表",
|
||||
targetTable: "目标表",
|
||||
searchTables: "搜索表名...",
|
||||
|
|
|
|||
|
|
@ -920,6 +920,7 @@ export default withEnglishFallback({
|
|||
sequence: "序列",
|
||||
package: "套件",
|
||||
packageBody: "套件本體",
|
||||
noResults: "無結果",
|
||||
},
|
||||
quickOpen: {
|
||||
placeholder: "搜尋連線、資料庫、資料表和其他物件……",
|
||||
|
|
@ -1900,6 +1901,12 @@ export default withEnglishFallback({
|
|||
editConfig: "編輯配置",
|
||||
retry: "重試",
|
||||
targetTableBusy: "另一個傳輸正在寫入目標資料表:{tables}",
|
||||
selectConnection: "選擇連線",
|
||||
selectDatabase: "選擇資料庫",
|
||||
selectSchema: "選擇結構描述",
|
||||
searchConnection: "搜尋連線...",
|
||||
searchDatabase: "搜尋資料庫...",
|
||||
searchSchema: "搜尋結構描述...",
|
||||
},
|
||||
tableImport: {
|
||||
title: "匯入資料表資料",
|
||||
|
|
@ -2213,6 +2220,9 @@ export default withEnglishFallback({
|
|||
host: "主機",
|
||||
copied: "已複製到剪貼簿",
|
||||
close: "關閉",
|
||||
searchConnection: "搜尋連線...",
|
||||
searchDatabase: "搜尋資料庫...",
|
||||
searchSchema: "搜尋結構描述...",
|
||||
},
|
||||
schemaDiff: {
|
||||
optionsTitle: "比較選項",
|
||||
|
|
@ -2266,6 +2276,7 @@ export default withEnglishFallback({
|
|||
dataCompare: {
|
||||
title: "比較資料",
|
||||
selectTable: "選擇資料表",
|
||||
searchTable: "搜尋資料表……",
|
||||
sourceTables: "來源資料表",
|
||||
targetTable: "目標資料表",
|
||||
searchTables: "搜尋資料表名稱……",
|
||||
|
|
|
|||
Loading…
Reference in New Issue