improve(tabs): suffix duplicate tab titles with numbers
This commit is contained in:
8 files changed
+94
-15
No files matched your search
@@ -15,6 +15,7 @@ import {
|
||||
tabColorStyle,
|
||||
tabDatabaseIconType,
|
||||
tabDisplayTitle,
|
||||
tabDisplayTitles,
|
||||
tabIconClass,
|
||||
tabTooltipLines,
|
||||
tabularResultItems,
|
||||
@@ -191,6 +192,37 @@ describe("query result grid identity", () => {
|
||||
});
|
||||
|
||||
describe("tab group presentation", () => {
|
||||
it("numbers colliding query tab titles so several tabs stay distinguishable", () => {
|
||||
const store = useConnectionStore();
|
||||
store.connections = [{ id: "conn-1", name: "PostgreSQL", db_type: "postgres", driver_profile: "postgres", database: "app" } as ConnectionConfig];
|
||||
const tabs = [queryTab({ id: "tab-1" }), queryTab({ id: "tab-2" }), queryTab({ id: "tab-3" })];
|
||||
|
||||
const titles = tabDisplayTitles(tabs, translate);
|
||||
expect([...titles.values()]).toEqual(["PostgreSQL@db 1", "PostgreSQL@db 2", "PostgreSQL@db 3"]);
|
||||
});
|
||||
|
||||
it("leaves tab titles untouched while they are unique", () => {
|
||||
const store = useConnectionStore();
|
||||
store.connections = [{ id: "conn-1", name: "PostgreSQL", db_type: "postgres", driver_profile: "postgres", database: "app" } as ConnectionConfig];
|
||||
const tabs = [queryTab({ id: "tab-1" }), queryTab({ id: "tab-2", database: "other" }), queryTab({ id: "tab-3", customTitle: true, title: "orders.sql", savedSqlId: "sql-1" })];
|
||||
|
||||
const titles = tabDisplayTitles(tabs, translate);
|
||||
expect(titles.get("tab-1")).toBe("PostgreSQL@db");
|
||||
expect(titles.get("tab-2")).toBe("PostgreSQL@other");
|
||||
expect(titles.get("tab-3")).toBe("orders.sql");
|
||||
});
|
||||
|
||||
it("numbers duplicate custom titles in strip order and skips preview tabs", () => {
|
||||
const store = useConnectionStore();
|
||||
store.connections = [{ id: "conn-1", name: "PostgreSQL", db_type: "postgres", driver_profile: "postgres", database: "app" } as ConnectionConfig, { id: "conn-preview", name: "[Preview] PostgreSQL", db_type: "postgres", driver_profile: "postgres", database: "app" } as ConnectionConfig];
|
||||
const tabs = [queryTab({ id: "tab-1", customTitle: true, title: "orders.sql", savedSqlId: "sql-1" }), queryTab({ id: "tab-preview", connectionId: "conn-preview" }), queryTab({ id: "tab-2", customTitle: true, title: "orders.sql", savedSqlId: "sql-2" })];
|
||||
|
||||
const titles = tabDisplayTitles(tabs, translate);
|
||||
expect(titles.get("tab-1")).toBe("orders.sql 1");
|
||||
expect(titles.get("tab-2")).toBe("orders.sql 2");
|
||||
expect(titles.get("tab-preview")).toBe("SQL");
|
||||
});
|
||||
|
||||
it("does not expose the internal objects mode in object browser tab titles", () => {
|
||||
const store = useConnectionStore();
|
||||
store.connections = [{ id: "conn-1", name: "PostgreSQL", db_type: "postgres", driver_profile: "postgres", database: "app" } as ConnectionConfig];
|
||||
|
||||
@@ -78,6 +78,37 @@ export function isEventObjectBrowserTab(tab: QueryTab): boolean {
|
||||
return tab.mode === "objects" && (tab.objectBrowser?.initialObjectFilter === "events" || tab.objectBrowser?.eventName !== undefined || tab.objectBrowser?.eventCreateRequestId !== undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display titles for a whole tab list.
|
||||
*
|
||||
* Tabs whose plain title collides (most obviously several query tabs on the
|
||||
* same connection and database, which all render `connection@database`) get a
|
||||
* 1-based numeric suffix so the strip stays readable. The first tab keeps no
|
||||
* suffix when its title is unique, so single-tab windows look exactly as
|
||||
* before.
|
||||
*/
|
||||
export function tabDisplayTitles(tabs: QueryTab[], t: Translate): Map<string, string> {
|
||||
const titles = new Map<string, string>();
|
||||
for (const tab of tabs) titles.set(tab.id, tabDisplayTitle(tab, t));
|
||||
|
||||
const collisions = new Map<string, number>();
|
||||
for (const tab of tabs) {
|
||||
if (isPreviewTab(tab)) continue;
|
||||
const title = titles.get(tab.id) ?? "";
|
||||
collisions.set(title, (collisions.get(title) ?? 0) + 1);
|
||||
}
|
||||
|
||||
const seen = new Map<string, number>();
|
||||
for (const tab of tabs) {
|
||||
const title = titles.get(tab.id) ?? "";
|
||||
if (isPreviewTab(tab) || (collisions.get(title) ?? 0) < 2) continue;
|
||||
const index = (seen.get(title) ?? 0) + 1;
|
||||
seen.set(title, index);
|
||||
titles.set(tab.id, `${title} ${index}`);
|
||||
}
|
||||
return titles;
|
||||
}
|
||||
|
||||
export function tabDisplayTitle(tab: QueryTab, t: Translate): string {
|
||||
const database = databaseDisplayNameForTab(tab.connectionId, tab.database, t);
|
||||
const settingsStore = useSettingsStore();
|
||||
|
||||
Reference in new issue
Block a user