Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
71cfdbc
fix(intelligent-assistant): restore IA UI styling for RHDHBUGS-3733
ciiay Sep 14, 2026
75d2710
fix(intelligent-assistant): align notebook document row controls
ciiay Sep 14, 2026
7d2ce77
chore(intelligent-assistant): add changeset for RHDHBUGS-3733 UI fix
ciiay Sep 14, 2026
b1c7053
test(intelligent-assistant): fix MCP configure modal close button loc…
Sep 15, 2026
0b6ce5c
fix(intelligent-assistant): restore jump buttons after Chat/Notebooks…
ciiay Sep 14, 2026
ad83523
style(intelligent-assistant): fix Prettier in McpConfigureServerModal
ciiay Sep 15, 2026
9ce40b0
fix(intelligent-assistant): i18n for MCP configure modal close button
ciiay Sep 16, 2026
37e5d62
fix(intelligent-assistant): restore ChatbotContent import after rebase
ciiay Sep 16, 2026
b195fd5
test(intelligent-assistant): fix fullscreen history drawer close locator
ciiay Sep 16, 2026
1340611
fix(intelligent-assistant): restore LightSpeedChat shell styling on s…
ciiay Sep 16, 2026
5b38c90
fix(intelligent-assistant): use PF plain icon controls and trim CSS o…
ciiay Sep 16, 2026
2280297
fix(intelligent-assistant): MCP settings table UI and shared shell to…
ciiay Sep 16, 2026
27a317d
fix(intelligent-assistant): refine MCP settings table layout and PF t…
ciiay Sep 16, 2026
9a900cd
fix(intelligent-assistant): trim redundant MCP table cell CSS
ciiay Sep 16, 2026
2e42752
fix(intelligent-assistant): MCP table sort hover and row alignment
ciiay Sep 16, 2026
2fcc83a
fix(intelligent-assistant): import PF table styles for MCP sort headers
ciiay Sep 17, 2026
bcf3add
fix(intelligent-assistant): scope PF6 icon dedupe to settings shell
ciiay Sep 17, 2026
73e3d3e
fix(intelligent-assistant): scope MCP configure modal backdrop z-index
ciiay Sep 17, 2026
617c4ac
fix(intelligent-assistant): rely on PF table sort icon styling
ciiay Sep 17, 2026
853ee14
fix(intelligent-assistant): trim message bar and footer CSS overrides
ciiay Sep 17, 2026
d65ba18
test(intelligent-assistant): align e2e with chat history drawer a11y …
ciiay Sep 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@red-hat-developer-hub/backstage-plugin-intelligent-assistant': patch
---

Restore Intelligent Assistant UI styling after PatternFly updates: plain icon buttons, chat shell borders and message bar alignment, MCP settings/modal layout, notebook sidebar dividers, and related e2e test selectors.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
openMcpSettingsPanel,
closeMcpSettingsPanel,
mcpConfigureModalSaveButton,
mcpConfigureModalCloseButton,
mcpCredentialConfigureModal,
mcpEditServerButton,
mcpPersonalAccessTokenInput,
Expand Down Expand Up @@ -402,11 +403,7 @@ test.describe('Intelligent assistant MCP', () => {
).toBeVisible();
}

await modal
.getByRole('button', {
name: translations['mcp.settings.closeConfigureModalAriaLabel'],
})
.click();
await mcpConfigureModalCloseButton(sharedPage, translations).click();
await mcpToken.closeMcpPanel();
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ import {
type McpServersListMock,
} from '../fixtures/responses';
import { waitForChatbotVisible } from '../utils/testHelper';
import { chatHistoryMenuButton } from '../utils/chatHistoryDrawer';
export {
openChatHistoryDrawer,
closeChatHistoryDrawer,
} from '../utils/chatHistoryDrawer';
import {
LightspeedMessages,
evaluateMessage,
Expand Down Expand Up @@ -57,41 +62,6 @@ export async function selectDisplayMode(
await page.getByRole('menuitem', { name: modeMap[mode] }).click();
}

export async function openChatHistoryDrawer(page: Page, t: LightspeedMessages) {
const closeButton = page.getByRole('button', {
name: t['aria.closeDrawerPanel'],
});
const chatHistoryMenuButton = page.getByRole('button', {
name: t['aria.chatHistoryMenu'],
});
const expandHistoryButton = page.getByRole('button', {
name: t['tooltip.expandHistoryPanel'],
});

if (await closeButton.isVisible().catch(() => false)) {
return;
}

await expect(chatHistoryMenuButton.or(expandHistoryButton)).toBeVisible({
timeout: 10000,
});

if (await chatHistoryMenuButton.isVisible().catch(() => false)) {
await chatHistoryMenuButton.click();
} else {
await expandHistoryButton.click();
}

await expect(closeButton).toBeVisible({ timeout: 5000 });
}

export async function closeChatHistoryDrawer(
page: Page,
t: LightspeedMessages,
) {
await page.getByRole('button', { name: t['aria.closeDrawerPanel'] }).click();
}

// Legacy app-legacy uses BackstagePage; NFS uses BUI header titles.
const backstagePageContent = (page: Page) =>
page.locator('main[class*="BackstagePage-root"], .bui-HeaderTitle').first();
Expand Down Expand Up @@ -144,11 +114,9 @@ export async function expectChatbotControlsVisible(
t: LightspeedMessages,
) {
await expect(page.locator('.pf-chatbot__header')).toBeVisible();
const chatHistoryMenuButton = page.getByRole('button', {
name: t['aria.chatHistoryMenu'],
});
if (await chatHistoryMenuButton.isVisible().catch(() => false)) {
await expect(chatHistoryMenuButton).toBeVisible();
const menu = chatHistoryMenuButton(page, t);
if (await menu.isVisible().catch(() => false)) {
await expect(menu).toBeVisible();
}
await expect(
page.getByRole('button', { name: t['aria.options.label'] }),
Expand Down Expand Up @@ -301,6 +269,15 @@ export function mcpConfigureModalCancelButton(
});
}

export function mcpConfigureModalCloseButton(
page: Page,
t: LightspeedMessages,
): Locator {
return mcpCredentialConfigureModal(page).getByRole('button', {
name: t['mcp.settings.closeConfigureModalAriaLabel'],
});
}

/** Validation/helper line under the PAT field after Save (matches i18n `mcp.settings.token.*` copy). */
export function mcpConfigureModalMessage(
page: Page,
Expand All @@ -318,11 +295,7 @@ export async function expectMcpConfigureModalReady(
page: Page,
t: LightspeedMessages,
) {
await expect(
mcpCredentialConfigureModal(page).getByRole('button', {
name: t['mcp.settings.closeConfigureModalAriaLabel'],
}),
).toBeVisible();
await expect(mcpConfigureModalCloseButton(page, t)).toBeVisible();
await expect(mcpClearTokenInputButton(page, t)).toBeVisible();
await expect(mcpConfigureModalSaveButton(page, t)).toBeVisible();
await expect(mcpConfigureModalCancelButton(page, t)).toBeVisible();
Expand All @@ -348,7 +321,7 @@ export async function clickMcpServersNameColumn(
}

function mcpServersSettingsHeading(page: Page, t: LightspeedMessages): Locator {
return page.getByRole('heading', {
return page.getByRole('button', {
name: t['mcp.settings.title'],
exact: true,
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { Page, expect } from '@playwright/test';
import { LightspeedMessages } from './translations';

/** Header control in overlay/docked modes (`aria.chatHistoryMenu`). */
export function chatHistoryMenuButton(page: Page, t: LightspeedMessages) {
return page.getByRole('button', { name: t['aria.chatHistoryMenu'] });
}

/** Drawer panel close control (`aria.closeDrawerPanel`). */
export function chatHistoryDrawerCloseButton(
page: Page,
t: LightspeedMessages,
) {
return page.getByRole('button', { name: t['aria.closeDrawerPanel'] });
}

/** Fullscreen collapsed strip expand control. */
export function expandChatHistoryButton(page: Page, t: LightspeedMessages) {
return page.getByRole('button', { name: t['tooltip.expandHistoryPanel'] });
}

export async function isChatHistoryDrawerOpen(
page: Page,
t: LightspeedMessages,
): Promise<boolean> {
return page
.getByPlaceholder(t['chatbox.search.placeholder'])
.isVisible()
.catch(() => false);
}

export async function openChatHistoryDrawer(page: Page, t: LightspeedMessages) {
if (await isChatHistoryDrawerOpen(page, t)) {
return;
}

const menu = chatHistoryMenuButton(page, t);
const expand = expandChatHistoryButton(page, t);

await expect(menu.or(expand)).toBeVisible({ timeout: 10_000 });

if (await menu.isVisible().catch(() => false)) {
await menu.click();
} else {
await expand.click();
}

await expect(
page.getByPlaceholder(t['chatbox.search.placeholder']),
).toBeVisible({ timeout: 5000 });
}

export async function closeChatHistoryDrawer(
page: Page,
t: LightspeedMessages,
) {
if (!(await isChatHistoryDrawerOpen(page, t))) {
return;
}

const drawerClose = chatHistoryDrawerCloseButton(page, t);
if (await drawerClose.isVisible().catch(() => false)) {
await drawerClose.click();
} else {
await chatHistoryMenuButton(page, t).click();
}

await expect(
page.getByPlaceholder(t['chatbox.search.placeholder']),
).toBeHidden({ timeout: 5000 });
}
79 changes: 30 additions & 49 deletions workspaces/intelligent-assistant/e2e-tests/utils/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@
* limitations under the License.
*/
import { Page, expect, Locator } from '@playwright/test';
import {
chatHistoryDrawerCloseButton,
chatHistoryMenuButton,
closeChatHistoryDrawer,
isChatHistoryDrawerOpen,
openChatHistoryDrawer,
} from './chatHistoryDrawer';
import { LightspeedMessages } from './translations';

export async function assertChatDialogInitialState(
Expand All @@ -24,17 +31,13 @@ export async function assertChatDialogInitialState(
translations['chatbox.header.title'],
);

const chatHistoryMenuButton = page.getByRole('button', {
name: translations['aria.chatHistoryMenu'],
});
const closeDrawerButton = page.getByRole('button', {
name: translations['aria.closeDrawerPanel'],
});
const menu = chatHistoryMenuButton(page, translations);
const drawerClose = chatHistoryDrawerCloseButton(page, translations);

if (await chatHistoryMenuButton.isVisible().catch(() => false)) {
await expect(chatHistoryMenuButton).toBeVisible();
if (await menu.isVisible().catch(() => false)) {
await expect(menu).toBeVisible();
} else {
await expect(closeDrawerButton).toBeVisible();
await expect(drawerClose).toBeVisible();
}

await assertDrawerState(page, 'open', translations);
Expand Down Expand Up @@ -91,41 +94,14 @@ export async function closeChatDrawer(
page: Page,
translations: LightspeedMessages,
) {
const closeButton = page.getByRole('button', {
name: translations['aria.closeDrawerPanel'],
});
await closeButton.click();
await closeChatHistoryDrawer(page, translations);
}

export async function openChatDrawer(
page: Page,
translations: LightspeedMessages,
) {
const closeButton = page.getByRole('button', {
name: translations['aria.closeDrawerPanel'],
});
const chatHistoryMenuButton = page.getByRole('button', {
name: translations['aria.chatHistoryMenu'],
});
const expandHistoryButton = page.getByRole('button', {
name: translations['tooltip.expandHistoryPanel'],
});

if (await closeButton.isVisible().catch(() => false)) {
return;
}

await expect(chatHistoryMenuButton.or(expandHistoryButton)).toBeVisible({
timeout: 10000,
});

if (await chatHistoryMenuButton.isVisible().catch(() => false)) {
await chatHistoryMenuButton.click();
} else {
await expandHistoryButton.click();
}

await expect(closeButton).toBeVisible({ timeout: 5000 });
await openChatHistoryDrawer(page, translations);
}

export async function assertDrawerState(
Expand All @@ -138,19 +114,24 @@ export async function assertDrawerState(
closed: (locator: Locator) => expect(locator).toBeHidden(),
};

const checks = [
page.getByRole('button', {
name: translations['aria.closeDrawerPanel'],
}),
page.getByPlaceholder(translations['chatbox.search.placeholder']),
];

for (const locator of checks) {
await expectations[state](locator);
}

const search = page.getByPlaceholder(
translations['chatbox.search.placeholder'],
);
const drawerClose = chatHistoryDrawerCloseButton(page, translations);
const resizeSeparator = page.locator('.pf-v6-c-drawer__splitter');

await expectations[state](search);
await expectations[state](resizeSeparator);

if (state === 'open' && (await isChatHistoryDrawerOpen(page, translations))) {
if (await drawerClose.isVisible().catch(() => false)) {
await expect(drawerClose).toBeVisible();
} else {
await expect(chatHistoryMenuButton(page, translations)).toBeVisible();
}
} else if (state === 'closed') {
await expect(drawerClose).toBeHidden();
}
}

export async function verifySidePanelConversation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"@patternfly/chatbot": "6.9.0-prerelease.2",
"@patternfly/react-core": "6.6.0",
"@patternfly/react-icons": "^6.5.0",
"@patternfly/react-styles": "^6.6.1",
"@patternfly/react-table": "^6.4.1",
"@red-hat-developer-hub/backstage-plugin-app-react": "^1.0.0",
"@red-hat-developer-hub/backstage-plugin-intelligent-assistant-common": "workspace:^",
Expand Down
Loading
Loading