mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-19 16:16:45 +00:00
fix(objects): sync detail panel when switching objects with auto-open
This commit is contained in:
@@ -277,6 +277,7 @@ const compileErrorMessage = ref("");
|
||||
const sidePanelRow = ref<ObjectBrowserRow | null>(null);
|
||||
const openedInitialEvent = ref("");
|
||||
const isEventEditor = computed(() => sidePanelMode.value === "event-editor");
|
||||
const isSidePanelOpen = computed(() => !!sidePanelRow.value || isEventEditor.value);
|
||||
const sidePanelMode = ref<"table-info" | "source" | "type-info" | "event-editor">("source");
|
||||
const eventEditorKey = computed(() =>
|
||||
eventEditorInstanceKey({
|
||||
@@ -1189,13 +1190,13 @@ function onRowClick(row: ObjectBrowserRow, event: MouseEvent) {
|
||||
clearTimeout(singleClickTimer);
|
||||
singleClickTimer = null;
|
||||
}
|
||||
const firstClickRan = settingsStore.editorSettings.objectBrowserAutoOpenDetailPanel !== false;
|
||||
const firstClickRan = settingsStore.editorSettings.objectBrowserAutoOpenDetailPanel !== false || isSidePanelOpen.value;
|
||||
if (!firstClickRan || action !== singleClickRowAction(row, effectiveDatabaseType.value)) {
|
||||
executeRowAction(row, action);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (settingsStore.editorSettings.objectBrowserAutoOpenDetailPanel === false) {
|
||||
if (settingsStore.editorSettings.objectBrowserAutoOpenDetailPanel === false && !isSidePanelOpen.value) {
|
||||
return;
|
||||
}
|
||||
// Single click: defer when the row has a distinct double-click action so a
|
||||
@@ -1314,11 +1315,15 @@ async function openTableInfo(row: ObjectBrowserRow, initialTab?: TableInfoTab) {
|
||||
selectedRowId.value = row.id;
|
||||
// Toggle off if clicking the same table
|
||||
if (sidePanelRow.value?.id === row.id && sidePanelMode.value === "table-info" && !initialTab) {
|
||||
if (settingsStore.editorSettings.objectBrowserAutoOpenDetailPanel === false) {
|
||||
return;
|
||||
}
|
||||
closeSidePanel();
|
||||
return;
|
||||
}
|
||||
sidePanelRow.value = row;
|
||||
sidePanelMode.value = "table-info";
|
||||
sourceRow.value = null;
|
||||
const epoch = sidePanelGuard.start();
|
||||
// Reset state
|
||||
tableColumns.value = [];
|
||||
@@ -1706,12 +1711,11 @@ function onSidePanelResizeEnd() {
|
||||
|
||||
function closeSidePanel() {
|
||||
sidePanelRow.value = null;
|
||||
sourceRow.value = null;
|
||||
sidePanelMode.value = "source";
|
||||
sidePanelGuard.bump();
|
||||
}
|
||||
|
||||
const isSidePanelOpen = computed(() => !!sidePanelRow.value || isEventEditor.value);
|
||||
|
||||
function toggleSidePanel() {
|
||||
if (isSidePanelOpen.value) {
|
||||
if (selectedRowId.value && sidePanelRow.value && sidePanelRow.value.id !== selectedRowId.value) {
|
||||
@@ -1740,11 +1744,15 @@ function toggleAutoOpenDetailPanel() {
|
||||
async function openTypeInfo(row: ObjectBrowserRow) {
|
||||
selectedRowId.value = row.id;
|
||||
if (sidePanelRow.value?.id === row.id && sidePanelMode.value === "type-info") {
|
||||
if (settingsStore.editorSettings.objectBrowserAutoOpenDetailPanel === false) {
|
||||
return;
|
||||
}
|
||||
closeSidePanel();
|
||||
return;
|
||||
}
|
||||
sidePanelRow.value = row;
|
||||
sidePanelMode.value = "type-info";
|
||||
sourceRow.value = null;
|
||||
sidePanelGuard.bump();
|
||||
}
|
||||
|
||||
@@ -1752,6 +1760,7 @@ function openTypeDdl(row: ObjectBrowserRow) {
|
||||
selectedRowId.value = row.id;
|
||||
sidePanelRow.value = row;
|
||||
sidePanelMode.value = "type-info";
|
||||
sourceRow.value = null;
|
||||
sidePanelGuard.bump();
|
||||
// DDL tab is selected by the panel once details load; switching the tab is
|
||||
// deferred via a dedicated request so the panel can focus it.
|
||||
@@ -1790,6 +1799,9 @@ function openSourceTab(row: ObjectBrowserRow) {
|
||||
async function openSource(row: ObjectBrowserRow) {
|
||||
// Toggle off if clicking the same source row
|
||||
if (sidePanelRow.value?.id === row.id && sidePanelMode.value === "source") {
|
||||
if (settingsStore.editorSettings.objectBrowserAutoOpenDetailPanel === false) {
|
||||
return;
|
||||
}
|
||||
closeSidePanel();
|
||||
return;
|
||||
}
|
||||
|
||||
Vendored
+34
@@ -290,4 +290,38 @@ describe("ObjectBrowser routine double click", () => {
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("switches side panel when clicking different objects while detail panel is open and auto-open is false", async () => {
|
||||
mocks.editorSettings.objectBrowserAutoOpenDetailPanel = false;
|
||||
const host = await mountBrowser();
|
||||
vi.useFakeTimers();
|
||||
|
||||
const spRow = rowFor(host, "sp_daily_report");
|
||||
click(spRow, 1);
|
||||
await vi.advanceTimersByTimeAsync(SINGLE_CLICK_DELAY * 2);
|
||||
expect(mocks.getObjectSource).not.toHaveBeenCalled();
|
||||
|
||||
// Manually open the side panel
|
||||
const toggleBtn = host.querySelector<HTMLButtonElement>('button[title="objects.openDetailPanel"]');
|
||||
expect(toggleBtn).not.toBeNull();
|
||||
toggleBtn?.click();
|
||||
await vi.advanceTimersByTimeAsync(SINGLE_CLICK_DELAY * 2);
|
||||
|
||||
expect(mocks.getObjectSource).toHaveBeenCalledWith("mysql-routines", "app", "app", "sp_daily_report", "PROCEDURE", "IN day DATE");
|
||||
expect(spRow.style.boxShadow).toBe("inset 3px 0 0 var(--primary)");
|
||||
|
||||
// Switch to another object: sequence
|
||||
const seqRow = rowFor(host, "seq_invoice");
|
||||
click(seqRow, 1);
|
||||
await vi.advanceTimersByTimeAsync(SINGLE_CLICK_DELAY * 2);
|
||||
|
||||
expect(mocks.getObjectSource).toHaveBeenCalledWith("mysql-routines", "app", "app", "seq_invoice", "SEQUENCE", undefined);
|
||||
expect(spRow.style.boxShadow).toBe("");
|
||||
expect(seqRow.style.boxShadow).toBe("inset 3px 0 0 var(--primary)");
|
||||
|
||||
// Clicking the same row again does not close the panel when auto-open is false
|
||||
click(seqRow, 1);
|
||||
await vi.advanceTimersByTimeAsync(SINGLE_CLICK_DELAY * 2);
|
||||
expect(seqRow.style.boxShadow).toBe("inset 3px 0 0 var(--primary)");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user