-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathDetachedTabWindow.vue
More file actions
101 lines (95 loc) · 4.68 KB
/
Copy pathDetachedTabWindow.vue
File metadata and controls
101 lines (95 loc) · 4.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<script setup lang="ts">
import { computed, ref, useAttrs } from "vue";
import { useI18n } from "vue-i18n";
import { X } from "@lucide/vue";
import EditorToolbar from "@/components/layout/EditorToolbar.vue";
import ContentArea from "@/components/layout/ContentArea.vue";
import { tabDisplayTitle } from "@/lib/tabs/tabPresentation";
import type { ConnectionConfig, QueryTab } from "@/types/database";
defineOptions({ inheritAttrs: false });
const props = defineProps<{
activeTab?: QueryTab;
activeConnection?: ConnectionConfig;
executableSql: string;
activeOutputView: "result" | "summary" | "explain" | "chart";
formatSqlRequest: { id: number; tabId: string } | null;
compressSqlRequest: { id: number; tabId: string } | null;
selectedSql: string;
cursorPos: number;
blockDangerousRedisCommands: boolean;
explainMode: "explain" | "autotrace";
sqlKeywordCase: "preserve" | "upper" | "lower";
autoCommit: boolean;
txnSessionId?: string;
txnAutoRolledBack?: boolean;
}>();
const emit = defineEmits<{
close: [];
}>();
const { t } = useI18n();
const attrs = useAttrs();
const contentAreaRef = ref<InstanceType<typeof ContentArea> | null>(null);
// useAttrs() exposes listeners as onXxx properties. Forward them through
// v-bind so object-form v-on does not transform their event names again.
const toolbarListeners = computed(() => Object.fromEntries(Object.entries(attrs).filter(([key]) => key.startsWith("on") && key !== "onExecute" && key !== "onExecuteInNewResultTab")));
defineExpose({
focusSearch: () => contentAreaRef.value?.focusSearch(),
refreshData: () => contentAreaRef.value?.refreshData(),
refreshQueryEditorCompletionCache: () => contentAreaRef.value?.refreshQueryEditorCompletionCache(),
handleModRTarget: (target: Element) => contentAreaRef.value?.handleModRTarget(target),
requestQueryEditorExecute: () => contentAreaRef.value?.requestQueryEditorExecute(),
requestQueryEditorExecuteInNewResultTab: () => contentAreaRef.value?.requestQueryEditorExecuteInNewResultTab(),
pasteClipboardAsSqlInCondition: () => contentAreaRef.value?.pasteClipboardAsSqlInCondition(),
applyTableStructureChanges: () => contentAreaRef.value?.applyTableStructureChanges(),
hasPendingDataGridChanges: () => contentAreaRef.value?.hasPendingDataGridChanges() ?? false,
savePendingDataGridChanges: () => contentAreaRef.value?.savePendingDataGridChanges() ?? Promise.resolve(false),
discardPendingDataGridChanges: () => contentAreaRef.value?.discardPendingDataGridChanges() ?? true,
insertRedisCommand: (command: string) => contentAreaRef.value?.insertRedisCommand(command),
executeRedisCommand: (command: string) => contentAreaRef.value?.executeRedisCommand(command),
});
</script>
<template>
<div class="fixed inset-0 flex h-screen w-screen min-w-0 flex-col overflow-hidden bg-background text-foreground">
<header class="flex h-10 shrink-0 items-center gap-2 border-b bg-muted/50 px-3" data-tauri-drag-region>
<span class="min-w-0 flex-1 truncate text-sm font-medium" data-tauri-drag-region>
{{ activeTab ? tabDisplayTitle(activeTab, t) : t("contextMenu.openInNewWindow") }}
</span>
<button type="button" class="rounded p-1.5 text-muted-foreground hover:bg-muted hover:text-foreground" :aria-label="t('contextMenu.closeTab')" @click="emit('close')">
<X class="h-4 w-4" />
</button>
</header>
<div v-if="activeTab" class="flex min-h-0 flex-1 flex-col">
<EditorToolbar
v-if="activeTab.mode === 'query'"
:active-tab="activeTab"
:active-connection="activeConnection"
:executable-sql="executableSql"
:explain-mode="explainMode"
:sql-keyword-case="sqlKeywordCase"
:block-dangerous-redis-commands="blockDangerousRedisCommands"
:auto-commit="autoCommit"
:txn-session-id="txnSessionId"
:txn-auto-rolled-back="txnAutoRolledBack"
v-bind="toolbarListeners"
@execute="contentAreaRef?.requestQueryEditorExecute()"
/>
<ContentArea
ref="contentAreaRef"
class="min-h-0 flex-1"
:active-tab="activeTab"
:active-connection="activeConnection"
:executable-sql="executableSql"
:active-output-view="activeOutputView"
:format-sql-request="formatSqlRequest"
:compress-sql-request="compressSqlRequest"
:selected-sql="selectedSql"
:cursor-pos="cursorPos"
:block-dangerous-redis-commands="blockDangerousRedisCommands"
v-bind="$attrs"
/>
</div>
<div v-else class="flex flex-1 items-center justify-center" role="status" aria-label="Loading detached tab">
<span class="h-4 w-4 animate-spin rounded-full border-2 border-muted-foreground/25 border-t-primary" />
</div>
</div>
</template>