Skip to content

Commit c70bde0

Browse files
authored
Merge pull request RedHatInsights#309 from apinkert/rework-tabs
Remove help panel tabs in favor of static sections
2 parents 887dd4a + 345de07 commit c70bde0

16 files changed

Lines changed: 808 additions & 2401 deletions

cypress/component/HelpPanel.cy.tsx

Lines changed: 92 additions & 203 deletions
Large diffs are not rendered by default.

playwright/help-panel.spec.ts

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,27 +34,33 @@ test.describe('help panel', async () => {
3434
await expect(helpPanelTitle).not.toBeVisible();
3535
});
3636

37-
test('displays subtabs', async ({page}) => {
37+
test('displays main tabs', async ({page}) => {
3838
await page.getByLabel('Toggle help panel').click();
3939

4040
// Tier 2: Wait for help panel to finish loading
41-
const subtabs = page.locator('[data-ouia-component-id="help-panel-subtabs"]');
42-
await expect(subtabs).toBeVisible();
41+
const tabs = page.locator('[data-ouia-component-id="help-panel-tabs"]');
42+
await expect(tabs).toBeVisible();
43+
44+
// Verify main tabs are present (Learn, APIs, Support, Feedback)
45+
await expect(page.getByRole('tab', { name: 'Learn' })).toBeVisible();
46+
await expect(page.getByRole('tab', { name: 'APIs' })).toBeVisible();
47+
await expect(page.getByRole('tab', { name: 'Support' })).toBeVisible();
48+
await expect(page.getByRole('tab', { name: 'Feedback' })).toBeVisible();
4349
});
4450

45-
test('allows switching between subtabs', async ({page}) => {
51+
test('allows switching between main tabs', async ({page}) => {
4652
await page.getByLabel('Toggle help panel').click();
4753

4854
// Tier 2: Wait for help panel to finish loading
4955
const helpPanelTitle = page.locator('[data-ouia-component-id="help-panel-title"]');
5056
await expect(helpPanelTitle).toBeVisible();
5157

52-
// Click on APIs subtab
53-
const apiTab = page.locator('[data-ouia-component-id="help-panel-subtab-api"]');
58+
// Click on APIs tab
59+
const apiTab = page.locator('[data-ouia-component-id="help-panel-tab-api"]');
5460
await apiTab.click();
5561

56-
// Verify API documentation content is shown by checking for unique content in that tab
57-
await expect(page.getByText('No API documentation found matching your criteria.')).toBeVisible();
62+
// Verify API documentation content is shown by checking for the description text
63+
await expect(page.getByText(/Browse the APIs for Hybrid Cloud Console services/i)).toBeVisible({ timeout: 10000 });
5864
});
5965

6066
test('displays status page link in header', async ({page}) => {
@@ -70,16 +76,5 @@ test.describe('help panel', async () => {
7076
await expect(statusPageLink).toHaveText('Red Hat status page');
7177
});
7278

73-
test('can add a new tab', async ({page}) => {
74-
await page.getByLabel('Toggle help panel').click();
75-
76-
// Tier 2: Wait for help panel to finish loading
77-
const addTabButton = page.locator('[data-ouia-component-id="help-panel-add-tab-button"]');
78-
await expect(addTabButton).toBeVisible();
79-
80-
await addTabButton.click();
81-
82-
// Verify a new tab appears
83-
await expect(page.getByText('New tab')).toBeVisible();
84-
});
79+
// Test removed: Add tab functionality no longer exists in single-tier tab structure
8580
});

src/components/HelpPanel/HelpPanelContent.stories.tsx

Lines changed: 9 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,13 @@ const mockHelpPanelHandlers = [
129129
http.post('/api/quickstarts/v1/favorites', async () => {
130130
return HttpResponse.json({ success: true });
131131
}),
132+
// Support cases API (empty state) - prevents "Failed to fetch" errors
133+
http.post('https://api.access.redhat.com/support/v1/cases/filter', () =>
134+
HttpResponse.json({ cases: [] })
135+
),
136+
http.post('https://api.access.stage.redhat.com/support/v1/cases/filter', () =>
137+
HttpResponse.json({ cases: [] })
138+
),
132139
];
133140

134141
const meta: Meta<typeof HelpPanelWrapper> = {
@@ -213,185 +220,9 @@ export const StatusPageLink: Story = {
213220
},
214221
};
215222

216-
/**
217-
* Test opening and closing custom tabs
218-
*/
219-
export const OpenAndCloseTabs: Story = {
220-
play: async ({ canvasElement }) => {
221-
const canvas = within(canvasElement);
222-
223-
// Wait for page to load and find the Help button in the header
224-
const helpButton = await canvas.findByLabelText(
225-
'Toggle help panel',
226-
{},
227-
{ timeout: 5000 }
228-
);
229-
expect(helpButton).toBeInTheDocument();
230-
231-
// Click the Help button to open the panel
232-
await userEvent.click(helpButton);
233-
234-
// Wait for the help panel drawer to open
235-
await waitFor(
236-
() => {
237-
const drawer = document.querySelector('.pf-v6-c-drawer.pf-m-expanded');
238-
expect(drawer).toBeInTheDocument();
239-
},
240-
{ timeout: 5000 }
241-
);
242-
243-
// Wait for the help panel to be visible
244-
await waitFor(
245-
() => {
246-
const helpPanelTitle = document.querySelector(
247-
'[data-ouia-component-id="help-panel-title"]'
248-
);
249-
expect(helpPanelTitle).toBeInTheDocument();
250-
},
251-
{ timeout: 5000 }
252-
);
253-
254-
// Find the add tab button
255-
const addTabButton = document.querySelector(
256-
'[data-ouia-component-id="help-panel-add-tab-button"]'
257-
) as HTMLElement;
258-
expect(addTabButton).toBeInTheDocument();
259-
260-
// Click to add a new tab
261-
await userEvent.click(addTabButton);
262-
263-
// Wait for the new tab to appear
264-
await waitFor(
265-
() => {
266-
const newTab = canvas.getByText('New tab');
267-
expect(newTab).toBeInTheDocument();
268-
},
269-
{ timeout: 3000 }
270-
);
271-
272-
// Verify the tab is now active by checking for the tab content
273-
const newTabButton = canvas.getByRole('tab', { name: 'New tab' });
274-
expect(newTabButton).toHaveAttribute('aria-selected', 'true');
275-
276-
// Find the close button for the new tab
277-
// The close button is a sibling of the tab link
278-
const tabItem = newTabButton.closest('.pf-v6-c-tabs__item');
279-
const closeButton = tabItem?.querySelector(
280-
'.pf-v6-c-tabs__item-action button'
281-
) as HTMLElement;
282-
expect(closeButton).toBeInTheDocument();
283-
284-
// Click the close button
285-
await userEvent.click(closeButton);
286-
287-
// Verify the tab is removed
288-
await waitFor(
289-
() => {
290-
const removedTab = canvas.queryByRole('tab', { name: 'New tab' });
291-
expect(removedTab).not.toBeInTheDocument();
292-
},
293-
{ timeout: 3000 }
294-
);
295-
},
296-
};
297-
298-
/**
299-
* Test opening multiple tabs and verify overflow dropdown appears
300-
*/
301-
export const OpenMultipleTabs: Story = {
302-
play: async ({ canvasElement }) => {
303-
const canvas = within(canvasElement);
304-
305-
// Wait for page to load and find the Help button in the header
306-
const helpButton = await canvas.findByLabelText(
307-
'Toggle help panel',
308-
{},
309-
{ timeout: 5000 }
310-
);
311-
expect(helpButton).toBeInTheDocument();
223+
// Story removed: Add/close tab functionality no longer exists in single-tier tab structure
312224

313-
// Click the Help button to open the panel
314-
await userEvent.click(helpButton);
315-
316-
// Wait for the help panel drawer to open
317-
await waitFor(
318-
() => {
319-
const drawer = document.querySelector('.pf-v6-c-drawer.pf-m-expanded');
320-
expect(drawer).toBeInTheDocument();
321-
},
322-
{ timeout: 5000 }
323-
);
324-
325-
// Wait for the help panel to be visible
326-
await waitFor(
327-
() => {
328-
const helpPanelTitle = document.querySelector(
329-
'[data-ouia-component-id="help-panel-title"]'
330-
);
331-
expect(helpPanelTitle).toBeInTheDocument();
332-
},
333-
{ timeout: 5000 }
334-
);
335-
336-
// Find the add tab button
337-
const addTabButton = document.querySelector(
338-
'[data-ouia-component-id="help-panel-add-tab-button"]'
339-
) as HTMLElement;
340-
341-
// Keep adding tabs until overflow occurs (max 10 attempts to prevent infinite loop)
342-
let overflowItem = null;
343-
let attempts = 0;
344-
const maxAttempts = 10;
345-
346-
while (!overflowItem && attempts < maxAttempts) {
347-
await userEvent.click(addTabButton);
348-
attempts++;
349-
350-
// Wait briefly for the tab to be added
351-
await waitFor(
352-
() => {
353-
const tabs = canvas.queryAllByRole('tab', { name: 'New tab' });
354-
expect(tabs.length).toBeGreaterThanOrEqual(attempts);
355-
},
356-
{ timeout: 1000 }
357-
).catch(() => {
358-
// Ignore timeout, we'll check overflow anyway
359-
});
360-
361-
// Check if overflow has appeared
362-
overflowItem = document.querySelector(
363-
'.pf-v6-c-tabs__item.pf-m-overflow'
364-
);
365-
}
366-
367-
// Assert that overflow menu appeared
368-
expect(overflowItem).toBeTruthy();
369-
370-
// Find and close the visible new tab(s)
371-
const visibleNewTabs = canvas.queryAllByRole('tab', { name: 'New tab' });
372-
373-
if (visibleNewTabs.length > 0) {
374-
// Close the first visible new tab
375-
const firstTabItem = visibleNewTabs[0].closest('.pf-v6-c-tabs__item');
376-
const closeButton = firstTabItem?.querySelector(
377-
'.pf-v6-c-tabs__item-action button'
378-
) as HTMLElement;
379-
380-
if (closeButton) {
381-
await userEvent.click(closeButton);
382-
383-
// Wait a bit for the tab to close
384-
await waitFor(
385-
() => {
386-
const tabs = canvas.queryAllByRole('tab', { name: 'New tab' });
387-
expect(tabs.length).toBeLessThan(visibleNewTabs.length);
388-
},
389-
{ timeout: 3000 }
390-
);
391-
}
392-
}
393-
},
394-
};
225+
// Story removed: Tab overflow functionality testing no longer relevant with static tabs
395226

396227
/**
397228
* Test that the drawer close button works

src/components/HelpPanel/HelpPanelContent.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ const HelpPanelContent = ({
3838
<DrawerHead>
3939
<Title headingLevel="h2" data-ouia-component-id="help-panel-title">
4040
Help
41+
</Title>
42+
<DrawerActions>
4143
<Button
4244
variant="link"
4345
component="a"
@@ -52,8 +54,6 @@ const HelpPanelContent = ({
5254
>
5355
{intl.formatMessage(messages.statusPage)}
5456
</Button>
55-
</Title>
56-
<DrawerActions>
5757
<DrawerCloseButton
5858
onClick={toggleDrawer}
5959
data-ouia-component-id="help-panel-close-button"

src/components/HelpPanel/HelpPanelCustomTabs.scss

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,7 @@
4646
background-color: var(--pf-t--global--background--color--primary--default);
4747
}
4848

49-
// Sub-tabs row (Learn, APIs, etc.): white background on the subtabs container.
50-
[data-ouia-component-id="help-panel-subtabs"] {
51-
background-color: var(--pf-t--global--background--color--primary--default);
52-
}
49+
// No sub-tabs in single-tier structure
5350

5451
// Content container (Learn, APIs, Support, etc.) has no background by default; set white
5552
// so the tab content area does not show the drawer's default background when scrolling.
@@ -63,37 +60,37 @@
6360
width: calc(100% + 2 * var(--pf-t--global--spacer--md, 1rem));
6461
}
6562

66-
.lr-c-help-panel-custom-tab {
67-
&.persistent-tab {
68-
// the disabled close tab action does not hide the action button
69-
// has to be hidden by CSS and the width has to be adjusted
70-
.pf-v6-c-tabs__item-action {
71-
visibility: hidden;
72-
width: 0;
73-
}
63+
.lr-c-help-panel-custom-tabs {
64+
.pf-v6-c-tabs__list {
65+
background-color: var(--pf-t--global--background--color--primary--default);
7466
}
7567

76-
// Add max-width to tab titles while keeping them dynamically sized
68+
// Make tab titles smaller to fit all tabs without scrolling
7769
.pf-v6-c-tabs__item-text {
78-
max-width: 120px;
79-
overflow: hidden;
80-
text-overflow: ellipsis;
81-
white-space: nowrap;
70+
font-size: 0.75rem !important;
8271
}
83-
}
8472

85-
.lr-c-help-panel-custom-tabs.pf-v6-c-tabs {
86-
.pf-v6-c-tabs__item.pf-m-overflow {
87-
.pf-v6-c-tabs__link-toggle-icon {
88-
// fixes strange alignment of the expand/collapse icon
89-
align-self: auto;
90-
}
73+
// Reduce padding on tab items to fit more tabs
74+
.pf-v6-c-tabs__link {
75+
padding-left: 0.5rem !important;
76+
padding-right: 0.5rem !important;
9177
}
9278

93-
}
79+
// Ensure tabs have the same background as the panel
80+
.pf-v6-c-tabs__item {
81+
background-color: var(--pf-t--global--background--color--primary--default);
82+
}
83+
84+
// Active tab should also use the primary background
85+
.pf-v6-c-tabs__link {
86+
background-color: var(--pf-t--global--background--color--primary--default);
87+
}
9488

95-
.pf-v6-c-tabs__list {
96-
overflow-y: hidden;
89+
// Move the active tab indicator from top to bottom
90+
.pf-v6-c-tabs__link::after {
91+
top: auto !important;
92+
bottom: 0 !important;
93+
}
9794
}
9895

9996
// Tab content area: flex column so the drawer child can fill height (flex: 1).
@@ -128,21 +125,31 @@
128125
}
129126
}
130127

131-
// Status page link styling (in header next to Help title)
128+
// Status page link styling (in header actions, before close button)
132129
.lr-c-status-page-link {
133130
font-size: var(--pf-t--global--font--size--sm) !important;
134-
font-weight: var(--pf-t--global--font--weight--normal) !important;
135131
text-decoration: none !important;
136-
margin-left: var(--pf-t--global--spacer--md) !important;
132+
margin-right: var(--pf-t--global--spacer--md) !important;
133+
// Align with close button vertically
134+
align-self: center !important;
135+
padding-top: var(--pf-t--global--spacer--sm) !important;
137136

138137
&:hover {
139138
text-decoration: none !important;
140139
}
141140
}
142141

143-
// Prevent horizontal overflow in subtabs by hiding overflow scrollbars
144-
[data-ouia-component-id="help-panel-subtabs"] {
145-
.pf-v6-c-tabs__scroll-button {
146-
display: none !important;
147-
}
142+
// Quickstart overlay: positioned above tabs to show quickstart content
143+
.lr-c-help-panel-quickstart-overlay {
144+
position: absolute;
145+
top: 0;
146+
left: 0;
147+
right: 0;
148+
bottom: 0;
149+
background-color: var(--pf-t--global--background--color--primary--default);
150+
z-index: 100;
151+
display: flex;
152+
flex-direction: column;
153+
min-height: 0;
154+
height: 100%;
148155
}

0 commit comments

Comments
 (0)