mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-19 16:16:45 +00:00
perf(tabs): retain bounded hot tab surfaces
This commit is contained in:
@@ -33,6 +33,8 @@ const props = defineProps<
|
||||
}
|
||||
>();
|
||||
|
||||
const HOT_TAB_SURFACE_CACHE_SIZE = 3;
|
||||
|
||||
const emit = defineEmits<
|
||||
ContentAreaSurfaceEmits & {
|
||||
"focus-group": [groupId: string];
|
||||
@@ -209,8 +211,10 @@ const groupExecutableSql = computed(() => {
|
||||
@clear-default-database="activeTab && toolbar.clearDefaultDatabase(activeTab.id)"
|
||||
/>
|
||||
<div class="relative flex-1 min-h-0">
|
||||
<QueryEditorSurface v-if="activeTab?.mode === 'query'" ref="activeSurfaceRef" v-bind="surfaceBindings" :auto-focus="groupId === queryStore.focusedGroupId" class="h-full" />
|
||||
<ContentArea v-else-if="activeTab" ref="activeSurfaceRef" v-bind="surfaceBindings" class="h-full" />
|
||||
<KeepAlive v-if="activeTab" :max="HOT_TAB_SURFACE_CACHE_SIZE">
|
||||
<QueryEditorSurface v-if="activeTab?.mode === 'query'" :key="`query:${activeTab.id}`" ref="activeSurfaceRef" v-bind="surfaceBindings" :auto-focus="groupId === queryStore.focusedGroupId" class="h-full" />
|
||||
<ContentArea v-else :key="`content:${activeTab.id}`" ref="activeSurfaceRef" v-bind="surfaceBindings" class="h-full" />
|
||||
</KeepAlive>
|
||||
<slot v-else name="empty">
|
||||
<div class="flex h-full items-center justify-center text-sm text-muted-foreground">
|
||||
{{ t("tabs.emptyGroup") }}
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
// @vitest-environment happy-dom
|
||||
import { createApp, nextTick } from "vue";
|
||||
import { createApp, defineComponent, h, nextTick, ref } from "vue";
|
||||
import { createPinia, setActivePinia } from "pinia";
|
||||
import { createI18n } from "vue-i18n";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const lifecycle = vi.hoisted(() => ({
|
||||
queryCreated: 0,
|
||||
queryUnmounted: 0,
|
||||
}));
|
||||
|
||||
vi.mock("@/components/layout/EditorGroupTabBar.vue", () => ({
|
||||
default: {
|
||||
name: "EditorGroupTabBarStub",
|
||||
@@ -23,6 +28,12 @@ vi.mock("@/components/layout/QueryEditorSurface.vue", () => ({
|
||||
default: {
|
||||
name: "QueryEditorSurfaceStub",
|
||||
props: ["activeTab", "autoFocus"],
|
||||
created() {
|
||||
lifecycle.queryCreated += 1;
|
||||
},
|
||||
unmounted() {
|
||||
lifecycle.queryUnmounted += 1;
|
||||
},
|
||||
template: `<div data-test="query-editor">{{ activeTab.id }}</div>`,
|
||||
},
|
||||
}));
|
||||
@@ -66,6 +77,8 @@ describe("EditorGroup mount contract", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
document.body.innerHTML = "";
|
||||
lifecycle.queryCreated = 0;
|
||||
lifecycle.queryUnmounted = 0;
|
||||
pinia = createPinia();
|
||||
setActivePinia(pinia);
|
||||
i18n = createI18n({
|
||||
@@ -75,6 +88,49 @@ describe("EditorGroup mount contract", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps a bounded hot surface cache while switching query tabs", async () => {
|
||||
const store = useQueryStore();
|
||||
store.tabs = [tab("tab-a"), tab("tab-b")];
|
||||
const activeTabId = ref("tab-a");
|
||||
const host = createHost();
|
||||
const root = defineComponent({
|
||||
setup() {
|
||||
return () =>
|
||||
h(EditorGroup, {
|
||||
groupId: "group-1",
|
||||
tabIds: ["tab-a", "tab-b"],
|
||||
activeTabId: activeTabId.value,
|
||||
activeTab: tab(activeTabId.value),
|
||||
activeConnection: undefined,
|
||||
executableSql: "SELECT 1",
|
||||
activeOutputView: "result",
|
||||
formatSqlRequest: null,
|
||||
compressSqlRequest: null,
|
||||
selectedSql: "",
|
||||
cursorPos: 0,
|
||||
blockDangerousRedisCommands: false,
|
||||
});
|
||||
},
|
||||
});
|
||||
const app = createApp(root);
|
||||
app.use(pinia);
|
||||
app.use(i18n);
|
||||
app.mount(host);
|
||||
await nextTick();
|
||||
|
||||
activeTabId.value = "tab-b";
|
||||
await nextTick();
|
||||
activeTabId.value = "tab-a";
|
||||
await nextTick();
|
||||
|
||||
expect(lifecycle.queryCreated).toBe(2);
|
||||
expect(lifecycle.queryUnmounted).toBe(0);
|
||||
|
||||
app.unmount();
|
||||
expect(lifecycle.queryUnmounted).toBe(2);
|
||||
host.remove();
|
||||
});
|
||||
|
||||
it("passes the group active tab to the query editor surface instead of the global active tab", async () => {
|
||||
const store = useQueryStore();
|
||||
store.tabs = [tab("tab-a"), tab("tab-b")];
|
||||
|
||||
Reference in New Issue
Block a user