mirror of
https://github.com/t8y2/dbx.git
synced 2026-11-13 02:33:39 +08:00
@@ -1007,6 +1007,7 @@ useScheduledDatabaseBackups({ scheduler: true });
|
||||
|
||||
const appVersion = ref("");
|
||||
const isClassicLayout = computed(() => settingsStore.editorSettings.appLayout === "classic");
|
||||
const isVerticalTabPlacement = computed(() => settingsStore.editorSettings.tabPlacement === "left" || settingsStore.editorSettings.tabPlacement === "right");
|
||||
|
||||
// Every pane's vertical strip writes back to this shared width/collapse state.
|
||||
function startTabBarResize(event: PointerEvent) {
|
||||
@@ -3748,8 +3749,12 @@ onUnmounted(() => {
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
<div v-show="!driverStoreActive && !pluginCenterActive && !settingsStore.settingsPageActive" class="flex min-h-0 min-w-0 flex-1 flex-col">
|
||||
<div class="flex flex-col min-h-0" :class="activeTab?.mode === 'plugin-workbench' ? 'flex-none' : 'flex-1'">
|
||||
<div
|
||||
v-show="!driverStoreActive && !pluginCenterActive && !settingsStore.settingsPageActive"
|
||||
class="flex min-h-0 min-w-0 flex-1"
|
||||
:class="activeTab?.mode === 'plugin-workbench' && isVerticalTabPlacement ? (settingsStore.editorSettings.tabPlacement === 'right' ? 'flex-row-reverse' : 'flex-row') : 'flex-col'"
|
||||
>
|
||||
<div class="flex min-h-0" :class="activeTab?.mode === 'plugin-workbench' ? (isVerticalTabPlacement ? 'h-full flex-none flex-col' : 'flex-none flex-col') : 'flex-1 flex-col'">
|
||||
<SqlEditorWorkspace
|
||||
ref="contentAreaRef"
|
||||
:content-suppressed="activeTab?.mode === 'plugin-workbench'"
|
||||
|
||||
@@ -114,6 +114,7 @@ const { t } = useI18n();
|
||||
const queryStore = useQueryStore();
|
||||
const settingsStore = useSettingsStore();
|
||||
const isVerticalTabLayout = computed(() => settingsStore.editorSettings.tabPlacement === "left" || settingsStore.editorSettings.tabPlacement === "right");
|
||||
const verticalTabsWithSuppressedContent = computed(() => props.contentSuppressed && isVerticalTabLayout.value);
|
||||
const globalTabBarPortal = inject(GROUP_TAB_BAR_PORTAL, null);
|
||||
const workspaceTabBarPortal = createGroupTabBarPortal(isVerticalTabLayout);
|
||||
// A special page owns navigation while active. Otherwise side tabs stay
|
||||
@@ -257,16 +258,14 @@ function handleFocusStatement(tabId: string, range: StatementRange | null): bool
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- contentSuppressed (plugin workbench tab active): the App.vue wrapper is
|
||||
flex-none with indefinite height, so h-full/flex-1 here would collapse
|
||||
the workspace to 0 and clip the group tab strips (overflow-hidden).
|
||||
Size to content instead — same contract as EditorGroup's suppressed
|
||||
h-auto; normal mode keeps h-full/flex-1 to fill the column. -->
|
||||
<div class="sql-editor-workspace relative flex min-h-0 min-w-0 overflow-hidden" :class="[contentSuppressed ? 'h-auto' : 'h-full flex-1', workspaceClass, settingsStore.editorSettings.tabPlacement === 'right' ? 'flex-row-reverse' : 'flex-row']">
|
||||
<div
|
||||
class="sql-editor-workspace relative flex min-h-0 min-w-0 overflow-hidden"
|
||||
:class="[verticalTabsWithSuppressedContent ? 'h-full flex-none' : contentSuppressed ? 'h-auto' : 'h-full flex-1', workspaceClass, settingsStore.editorSettings.tabPlacement === 'right' ? 'flex-row-reverse' : 'flex-row']"
|
||||
>
|
||||
<div v-show="isVerticalTabLayout && showTabNavigation !== false" data-workspace-tab-navigation class="flex min-h-0 shrink-0 flex-col overflow-hidden" :style="tabNavigationStyle">
|
||||
<div v-for="group in queryStore.groups" :key="group.id" :ref="(element) => setTabBarTarget(group.id, element)" :data-workspace-tab-target="group.id" class="flex min-h-0 min-w-0 flex-1" @pointerdown.capture="queryStore.focusGroup(group.id)" @focusin="queryStore.focusGroup(group.id)" />
|
||||
</div>
|
||||
<div data-workspace-content class="relative flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden">
|
||||
<div data-workspace-content class="relative flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden" :class="{ hidden: verticalTabsWithSuppressedContent }">
|
||||
<!-- Suppressed mode: a plugin workbench tab owns the layout. Render the
|
||||
groups' tab strips directly (no Splitpanes, no shared result pane) so
|
||||
App.vue's always-mounted plugin layer can fill the remaining column
|
||||
|
||||
+9
-7
@@ -87,6 +87,7 @@ vi.mock("@/components/layout/QueryResultSurface.vue", () => ({
|
||||
|
||||
import SqlEditorWorkspace from "../SqlEditorWorkspace.vue";
|
||||
import { useQueryStore } from "@/stores/queryStore";
|
||||
import { useSettingsStore } from "@/stores/settingsStore";
|
||||
import type { QueryTab } from "@/types/database";
|
||||
|
||||
function tab(id: string): QueryTab {
|
||||
@@ -338,6 +339,7 @@ describe("SqlEditorWorkspace mount contract", () => {
|
||||
|
||||
it("keeps group tab strips mounted and drops the splitpanes workspace while suppressed", async () => {
|
||||
const store = useQueryStore();
|
||||
const settingsStore = useSettingsStore();
|
||||
store.tabs = [tab("tab-a"), { ...tab("tab-b"), mode: "plugin-workbench" } as unknown as ReturnType<typeof tab>];
|
||||
store.activeTabId = "tab-b";
|
||||
store.groups = [
|
||||
@@ -347,6 +349,7 @@ describe("SqlEditorWorkspace mount contract", () => {
|
||||
store.focusedGroupId = "g2";
|
||||
store.orientation = "vertical";
|
||||
store.sizes = [50, 50];
|
||||
settingsStore.editorSettings.tabPlacement = "left";
|
||||
|
||||
const host = createHost();
|
||||
const app = createApp(SqlEditorWorkspace, {
|
||||
@@ -376,14 +379,13 @@ describe("SqlEditorWorkspace mount contract", () => {
|
||||
expect(groups[1]?.getAttribute("data-group-id")).toBe("g2");
|
||||
expect(groups[1]?.getAttribute("data-content-suppressed")).toBe("true");
|
||||
|
||||
// The App.vue wrapper is flex-none with indefinite height while a plugin
|
||||
// tab is active: the workspace must size to its strip content, or the
|
||||
// h-full/flex-1 fill contract collapses it to zero height and clips the
|
||||
// strips away (overflow-hidden) — the "plugin tab bar vanishes" regression.
|
||||
// Vertical plugin tabs share the row with the plugin workbench, so their
|
||||
// workspace must keep the full-height contract while content is suppressed.
|
||||
const workspaceRoot = host.querySelector<HTMLElement>(".sql-editor-workspace");
|
||||
expect(workspaceRoot?.classList.contains("h-auto")).toBe(true);
|
||||
expect(workspaceRoot?.classList.contains("h-full")).toBe(false);
|
||||
expect(workspaceRoot?.classList.contains("flex-1")).toBe(false);
|
||||
expect(workspaceRoot?.classList.contains("h-full")).toBe(true);
|
||||
expect(workspaceRoot?.classList.contains("flex-none")).toBe(true);
|
||||
expect(workspaceRoot?.classList.contains("h-auto")).toBe(false);
|
||||
expect(host.querySelector<HTMLElement>("[data-workspace-content]")?.classList.contains("hidden")).toBe(true);
|
||||
|
||||
app.unmount();
|
||||
host.remove();
|
||||
|
||||
Reference in New Issue
Block a user