Dashboards: Generate default tab title when converting rows with empty titles to tabs (#115256)

Generate default title for empty row titles
This commit is contained in:
Kristina Demeshchik
2025-12-12 13:14:56 -05:00
committed by GitHub
parent 644f7b7001
commit b29e8ccb45
2 changed files with 62 additions and 1 deletions
@@ -262,4 +262,57 @@ describe('TabsLayoutManager', () => {
expect(manager.getVizPanels().length).toBe(1);
});
});
describe('createFromLayout', () => {
it('should convert rows with titles to tabs', () => {
const rowsLayout = new RowsLayoutManager({
rows: [new RowItem({ title: 'Row 1' }), new RowItem({ title: 'Row 2' })],
});
const tabsManager = TabsLayoutManager.createFromLayout(rowsLayout);
expect(tabsManager.state.tabs).toHaveLength(2);
expect(tabsManager.state.tabs[0].state.title).toBe('Row 1');
expect(tabsManager.state.tabs[1].state.title).toBe('Row 2');
});
it('should use default title when row has empty title', () => {
const rowsLayout = new RowsLayoutManager({
rows: [new RowItem({ title: '' })],
});
const tabsManager = TabsLayoutManager.createFromLayout(rowsLayout);
expect(tabsManager.state.tabs).toHaveLength(1);
expect(tabsManager.state.tabs[0].state.title).toBe('New tab');
});
it('should generate unique titles for multiple rows with empty titles', () => {
const rowsLayout = new RowsLayoutManager({
rows: [new RowItem({ title: '' }), new RowItem({ title: '' }), new RowItem({ title: '' })],
});
const tabsManager = TabsLayoutManager.createFromLayout(rowsLayout);
expect(tabsManager.state.tabs).toHaveLength(3);
expect(tabsManager.state.tabs[0].state.title).toBe('New tab');
expect(tabsManager.state.tabs[1].state.title).toBe('New tab 1');
expect(tabsManager.state.tabs[2].state.title).toBe('New tab 2');
});
it('should generate unique titles when mixing empty and existing titles', () => {
const rowsLayout = new RowsLayoutManager({
rows: [
new RowItem({ title: 'New row' }), // existing title that matches default
new RowItem({ title: '' }), // empty, should get unique title
],
});
const tabsManager = TabsLayoutManager.createFromLayout(rowsLayout);
expect(tabsManager.state.tabs).toHaveLength(2);
expect(tabsManager.state.tabs[0].state.title).toBe('New row');
expect(tabsManager.state.tabs[1].state.title).toBe('New tab');
});
});
});
@@ -410,6 +410,10 @@ export class TabsLayoutManager extends SceneObjectBase<TabsLayoutManagerState> i
let tabs: TabItem[] = [];
if (layout instanceof RowsLayoutManager) {
const existingNames = new Set(
layout.state.rows.map((row) => row.state.title).filter((title): title is string => !!title)
);
for (const row of layout.state.rows) {
if (row.state.repeatSourceKey) {
continue;
@@ -420,10 +424,14 @@ export class TabsLayoutManager extends SceneObjectBase<TabsLayoutManagerState> i
// We need to clear the target since we don't want to point the original row anymore (if it was set)
conditionalRendering?.setTarget(undefined);
const newTitle =
row.state.title || generateUniqueTitle(t('dashboard.tabs-layout.tab.new', 'New tab'), existingNames);
existingNames.add(newTitle);
tabs.push(
new TabItem({
layout: row.state.layout.clone(),
title: row.state.title,
title: newTitle,
conditionalRendering,
repeatByVariable: row.state.repeatByVariable,
})