Revert "feat(sidebar): expose visible object filter"
This reverts commit 580b70e1d4.
This commit is contained in:
26 files changed
+7
-532
No files matched your search
@@ -4802,11 +4802,6 @@ function handleRowKeydown(node: TreeNode, event: KeyboardEvent) {
|
||||
onKeydown(event);
|
||||
}
|
||||
|
||||
function openPrimaryVisibleFilter(node: TreeNode) {
|
||||
activateRuntimeNode(node);
|
||||
openVisibleDatabasesDialog();
|
||||
}
|
||||
|
||||
function openDataInNewTab(node: TreeNode) {
|
||||
activateRuntimeNode(node);
|
||||
openDataInNewTabImmediately(node);
|
||||
@@ -4827,7 +4822,6 @@ defineExpose({
|
||||
handleRowClick,
|
||||
handleRowDoubleClick,
|
||||
handleRowKeydown,
|
||||
openPrimaryVisibleFilter,
|
||||
openDataInNewTab,
|
||||
requestPaste,
|
||||
toggleNode,
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, inject } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { ListFilter } from "@lucide/vue";
|
||||
import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import type { TreeNode } from "@/types/database";
|
||||
import { sidebarTreeRuntimeKey } from "@/lib/sidebar/sidebarTreeRuntime";
|
||||
import { connectionCanConfigureSidebarVisibleDatabases } from "@/lib/sidebar/sidebarVisibleFilterMenu";
|
||||
|
||||
const props = defineProps<{
|
||||
node: TreeNode;
|
||||
}>();
|
||||
|
||||
const { t } = useI18n();
|
||||
const connectionStore = useConnectionStore();
|
||||
const sidebarTreeRuntime = inject(sidebarTreeRuntimeKey);
|
||||
if (!sidebarTreeRuntime) throw new Error("SidebarVisibleFilterControl must be rendered inside ConnectionTree");
|
||||
const treeRuntime = sidebarTreeRuntime;
|
||||
|
||||
const control = computed(() => {
|
||||
const connectionId = props.node.connectionId;
|
||||
if (props.node.type !== "connection" || !connectionId) return null;
|
||||
const config = connectionStore.getConfig(connectionId);
|
||||
if (!config || !connectionCanConfigureSidebarVisibleDatabases(config.db_type)) return null;
|
||||
const summary = connectionStore.getSidebarVisibleFilterSummary(connectionId);
|
||||
if (!summary) return null;
|
||||
const count = summary.selected == null || summary.total == null ? "" : ` (${summary.selected}/${summary.total})`;
|
||||
const labelKey = summary.mode === "schema" ? "visibleSchemas.sidebarControlLabel" : "visibleDatabases.sidebarControlLabel";
|
||||
return {
|
||||
...summary,
|
||||
label: t(labelKey, { connection: config.name, count }),
|
||||
};
|
||||
});
|
||||
|
||||
function openPrimaryVisibleFilter() {
|
||||
if (!control.value) return;
|
||||
treeRuntime.openPrimaryVisibleFilter(props.node);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button
|
||||
v-if="control"
|
||||
type="button"
|
||||
data-sidebar-visible-filter
|
||||
class="flex h-5 min-w-5 shrink-0 items-center justify-center rounded px-1 text-[10px] leading-none tabular-nums text-muted-foreground transition-colors hover:bg-secondary/60 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
||||
:class="{ 'bg-primary/10 text-primary': control.isExplicit }"
|
||||
:aria-label="control.label"
|
||||
:title="control.label"
|
||||
@mousedown.stop
|
||||
@click.stop="openPrimaryVisibleFilter"
|
||||
@dblclick.stop
|
||||
>
|
||||
<span v-if="control.selected != null && control.total != null">{{ control.selected }}/{{ control.total }}</span>
|
||||
<ListFilter v-else class="h-3 w-3" aria-hidden="true" />
|
||||
</button>
|
||||
</template>
|
||||
@@ -70,7 +70,6 @@ import { useDragSort } from "@/composables/useDragSort";
|
||||
import { sidebarTreeRuntimeKey } from "@/lib/sidebar/sidebarTreeRuntime";
|
||||
import { treeNodePinKey } from "@/lib/app/pinnedItems";
|
||||
import { isTreeGroupNodeType } from "@/lib/sidebar/treeNodeGroup";
|
||||
import SidebarVisibleFilterControl from "./SidebarVisibleFilterControl.vue";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -1197,7 +1196,6 @@ function onKeydown(event: KeyboardEvent) {
|
||||
>{{ trailingComment }}</span
|
||||
>
|
||||
</div>
|
||||
<SidebarVisibleFilterControl v-if="node.type === 'connection'" :node="node" />
|
||||
<span v-if="node.type === 'connection' && node.connectionId && connectionStore.connectedIds.has(node.connectionId)" class="w-1.5 h-1.5 rounded-full bg-green-500 shrink-0" />
|
||||
<span v-if="databaseOpenVisual.showsIndicator" class="w-1.5 h-1.5 rounded-full bg-green-500 shrink-0" />
|
||||
<Badge v-if="isConnectionReadonly" variant="secondary" class="h-4 px-1.5 text-[10px] gap-0.5"><Lock class="w-2.5 h-2.5" />{{ t("connection.readOnlyBadge") }}</Badge>
|
||||
|
||||
@@ -84,7 +84,6 @@ async function loadDatabases() {
|
||||
searchText.value = "";
|
||||
try {
|
||||
const names = await loadObjectNames();
|
||||
connectionStore.recordPrimaryVisibleObjectNames(props.connectionId, names);
|
||||
objectNames.value = names;
|
||||
showSystemDatabases.value = false;
|
||||
const configured = isSchemaFilterMode.value ? connection.value?.visible_schemas?.[databaseKey.value] : connection.value?.visible_databases;
|
||||
|
||||
-95
@@ -1,95 +0,0 @@
|
||||
// @vitest-environment happy-dom
|
||||
|
||||
import { createApp, defineComponent, h, nextTick, type App } from "vue";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import i18n from "@/i18n";
|
||||
import SidebarVisibleFilterControl from "@/components/sidebar/SidebarVisibleFilterControl.vue";
|
||||
import { createSidebarTreeRuntime, sidebarTreeRuntimeKey, type SidebarTreeRuntimeHost } from "@/lib/sidebar/sidebarTreeRuntime";
|
||||
import type { SidebarVisibleFilterSummary } from "@/lib/sidebar/sidebarVisibleFilterSummary";
|
||||
import type { ConnectionConfig, TreeNode } from "@/types/database";
|
||||
|
||||
const state: {
|
||||
config: Pick<ConnectionConfig, "db_type" | "name">;
|
||||
summary: SidebarVisibleFilterSummary;
|
||||
} = {
|
||||
config: { db_type: "mysql", name: "MySQL" },
|
||||
summary: { mode: "database", isExplicit: true, selected: 1, total: 6 },
|
||||
};
|
||||
|
||||
vi.mock("@/stores/connectionStore", () => ({
|
||||
useConnectionStore: () => ({
|
||||
getConfig: () => state.config,
|
||||
getSidebarVisibleFilterSummary: () => state.summary,
|
||||
}),
|
||||
}));
|
||||
|
||||
const mountedApps: App[] = [];
|
||||
|
||||
function runtimeHost(): SidebarTreeRuntimeHost {
|
||||
return {
|
||||
buildContextMenu: vi.fn(() => []),
|
||||
handleRowClick: vi.fn(),
|
||||
handleRowDoubleClick: vi.fn(),
|
||||
handleRowKeydown: vi.fn(),
|
||||
openPrimaryVisibleFilter: vi.fn(),
|
||||
openDataInNewTab: vi.fn(),
|
||||
requestPaste: vi.fn(() => false),
|
||||
toggleNode: vi.fn(),
|
||||
};
|
||||
}
|
||||
|
||||
async function mountControl() {
|
||||
const node: TreeNode = { id: "connection-1", label: "MySQL", type: "connection", connectionId: "connection-1" };
|
||||
const container = document.createElement("div");
|
||||
document.body.append(container);
|
||||
const runtime = createSidebarTreeRuntime();
|
||||
const host = runtimeHost();
|
||||
runtime.bindHost(host);
|
||||
const app = createApp(
|
||||
defineComponent({
|
||||
setup: () => () => h(SidebarVisibleFilterControl, { node }),
|
||||
}),
|
||||
);
|
||||
mountedApps.push(app);
|
||||
app.use(i18n);
|
||||
app.provide(sidebarTreeRuntimeKey, runtime);
|
||||
app.mount(container);
|
||||
await nextTick();
|
||||
return { container, host, node };
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
for (const app of mountedApps.splice(0)) app.unmount();
|
||||
document.body.innerHTML = "";
|
||||
state.config = { db_type: "mysql", name: "MySQL" };
|
||||
state.summary = { mode: "database", isExplicit: true, selected: 1, total: 6 };
|
||||
});
|
||||
|
||||
describe("SidebarVisibleFilterControl", () => {
|
||||
it("shows the selected/total count and opens the existing primary filter route", async () => {
|
||||
const { container, host, node } = await mountControl();
|
||||
const button = container.querySelector<HTMLButtonElement>("[data-sidebar-visible-filter]");
|
||||
|
||||
expect(button?.textContent).toBe("1/6");
|
||||
expect(button?.getAttribute("aria-label")).toContain("MySQL");
|
||||
button?.click();
|
||||
expect(host.openPrimaryVisibleFilter).toHaveBeenCalledWith(node);
|
||||
});
|
||||
|
||||
it("keeps an accessible filter control before counts are available", async () => {
|
||||
state.summary = { mode: "database", isExplicit: false, selected: null, total: null };
|
||||
const { container } = await mountControl();
|
||||
const button = container.querySelector<HTMLButtonElement>("[data-sidebar-visible-filter]");
|
||||
|
||||
expect(button).not.toBeNull();
|
||||
expect(button?.textContent).toBe("");
|
||||
expect(button?.getAttribute("aria-label")).toContain("MySQL");
|
||||
});
|
||||
|
||||
it("does not render for unsupported connection types", async () => {
|
||||
state.config = { db_type: "elasticsearch", name: "Search" };
|
||||
const { container } = await mountControl();
|
||||
|
||||
expect(container.querySelector("[data-sidebar-visible-filter]")).toBeNull();
|
||||
});
|
||||
});
|
||||
-1
@@ -61,7 +61,6 @@ function runtimeHost(): SidebarTreeRuntimeHost {
|
||||
handleRowClick: vi.fn(),
|
||||
handleRowDoubleClick: vi.fn(),
|
||||
handleRowKeydown: vi.fn(),
|
||||
openPrimaryVisibleFilter: vi.fn(),
|
||||
openDataInNewTab: vi.fn(),
|
||||
requestPaste: vi.fn(() => false),
|
||||
toggleNode: vi.fn(),
|
||||
|
||||
Reference in new issue
Block a user