Skip to content

Commit 8ed95da

Browse files
Merge pull request #1867 from kyoto/4.19-mode-switcher-menu
OLS-2892: Use separate menu for the Ask/Troubleshooting mode
2 parents 7c47d2e + 7fd8f37 commit 8ed95da

3 files changed

Lines changed: 75 additions & 62 deletions

File tree

locales/en/plugin__lightspeed-console-plugin.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"Approve": "Approve",
99
"Are you sure you want to erase the current chat conversation and start a new chat? This action cannot be undone.": "Are you sure you want to erase the current chat conversation and start a new chat? This action cannot be undone.",
1010
"Ask": "Ask",
11+
"Ask a question...": "Ask a question...",
1112
"Attach": "Attach",
1213
"Attach cluster info": "Attach cluster info",
1314
"Bad response": "Bad response",
@@ -31,6 +32,7 @@
3132
"Copy to clipboard": "Copy to clipboard",
3233
"Currently viewing": "Currently viewing",
3334
"Denial failed:": "Denial failed:",
35+
"Describe the issue you're troubleshooting...": "Describe the issue you're troubleshooting...",
3436
"Diagnosing issues and finding solutions": "Diagnosing issues and finding solutions",
3537
"Dismiss": "Dismiss",
3638
"Do not include personal information or other sensitive information in your feedback. Feedback may be used to improve Red Hat's products or services.": "Do not include personal information or other sensitive information in your feedback. Feedback may be used to improve Red Hat's products or services.",
@@ -103,12 +105,10 @@
103105
"Red Hat OpenShift Lightspeed": "Red Hat OpenShift Lightspeed",
104106
"Refresh": "Refresh",
105107
"Reject": "Reject",
106-
"Remove Troubleshooting mode": "Remove Troubleshooting mode",
107108
"Restore": "Restore",
108109
"Revert to original": "Revert to original",
109110
"Review required": "Review required",
110111
"Save": "Save",
111-
"Send a message...": "Send a message...",
112112
"Status": "Status",
113113
"Stay": "Stay",
114114
"Structured content": "Structured content",

src/components/Prompt.tsx

Lines changed: 62 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@ import { MessageBar } from '@patternfly/chatbot';
1414
import {
1515
Alert,
1616
AlertActionCloseButton,
17-
Divider,
1817
DropdownItem,
1918
DropdownList,
2019
Label,
20+
MenuToggle,
21+
Select,
22+
SelectList,
23+
SelectOption,
2124
Spinner,
2225
Title,
2326
Tooltip,
@@ -26,7 +29,7 @@ import {
2629
FileCodeIcon,
2730
FileUploadIcon,
2831
InfoCircleIcon,
29-
OutlinedQuestionCircleIcon,
32+
OutlinedCommentIcon,
3033
PlusIcon,
3134
TaskIcon,
3235
WrenchIcon,
@@ -130,6 +133,7 @@ const Prompt: React.FC<PromptProps> = ({ scrollIntoView }) => {
130133
const [isLogModalOpen, , openLogModal, closeLogModal] = useBoolean(false);
131134
const [isLoading, , setLoading, setLoaded] = useBoolean(false);
132135
const [isOpen, setIsOpen] = React.useState<boolean>(false);
136+
const [isModeMenuOpen, setIsModeMenuOpen] = React.useState<boolean>(false);
133137
const [streamController, setStreamController] = React.useState(new AbortController());
134138
const [validated, setValidated] = React.useState<'default' | 'error'>('default');
135139

@@ -294,34 +298,13 @@ const Prompt: React.FC<PromptProps> = ({ scrollIntoView }) => {
294298
<DropdownItem icon={<FileUploadIcon />} key="upload" value={AttachmentTypes.YAMLUpload}>
295299
{t('Upload from computer')}
296300
</DropdownItem>
297-
<Divider key="divider-1" />
298-
{isTroubleshooting ? (
299-
<DropdownItem
300-
description={t('Expert guidance and clear answers')}
301-
icon={<OutlinedQuestionCircleIcon />}
302-
id="ask"
303-
value="ask"
304-
>
305-
{t('Ask')}
306-
</DropdownItem>
307-
) : (
308-
<DropdownItem
309-
description={t('Diagnosing issues and finding solutions')}
310-
icon={<WrenchIcon />}
311-
id="troubleshooting"
312-
value="troubleshooting"
313-
>
314-
{t('Troubleshooting')}
315-
</DropdownItem>
316-
)}
317301
</DropdownList>,
318302
],
319303
[
320304
events.length,
321305
isEventsLoading,
322306
isLoading,
323307
isResourceContext,
324-
isTroubleshooting,
325308
kind,
326309
name,
327310
namespace,
@@ -335,17 +318,7 @@ const Prompt: React.FC<PromptProps> = ({ scrollIntoView }) => {
335318
(_ev: React.MouseEvent, attachmentType: string | number) => {
336319
setIsOpen(false);
337320

338-
if (attachmentType === 'ask') {
339-
// Delay update until menu fade out is complete
340-
requestAnimationFrame(() => {
341-
setTimeout(() => dispatch(setIsTroubleshooting(false)), 0);
342-
});
343-
} else if (attachmentType === 'troubleshooting') {
344-
// Delay update until menu fade out is complete
345-
requestAnimationFrame(() => {
346-
setTimeout(() => dispatch(setIsTroubleshooting(true)), 0);
347-
});
348-
} else if (attachmentType === AttachmentTypes.Events) {
321+
if (attachmentType === AttachmentTypes.Events) {
349322
openEventsModal();
350323
} else if (attachmentType === AttachmentTypes.Log) {
351324
openLogModal();
@@ -765,23 +738,61 @@ const Prompt: React.FC<PromptProps> = ({ scrollIntoView }) => {
765738
[dispatch, streamController, streamingResponseID],
766739
);
767740

741+
const modeMenuToggle = React.useCallback(
742+
(toggleRef: React.Ref<HTMLButtonElement>) => (
743+
<MenuToggle
744+
data-test="ols-plugin__mode-toggle"
745+
icon={isTroubleshooting ? <WrenchIcon /> : <OutlinedCommentIcon />}
746+
isExpanded={isModeMenuOpen}
747+
onClick={() => setIsModeMenuOpen(!isModeMenuOpen)}
748+
ref={toggleRef}
749+
variant="plainText"
750+
>
751+
{isTroubleshooting ? t('Troubleshooting') : t('Ask')}
752+
</MenuToggle>
753+
),
754+
[isModeMenuOpen, isTroubleshooting, t],
755+
);
756+
757+
const onModeMenuSelect = React.useCallback(
758+
(_ev: React.MouseEvent, value: string | number) => {
759+
dispatch(setIsTroubleshooting(value === 'troubleshooting'));
760+
setIsModeMenuOpen(false);
761+
},
762+
[dispatch],
763+
);
764+
768765
return (
769766
<div>
770767
{/* @ts-expect-error: TS2786 */}
771768
<MessageBar
772769
additionalActions={
773-
isTroubleshooting ? (
774-
<Label
775-
closeBtnAriaLabel={t('Remove Troubleshooting mode')}
776-
onClose={() => dispatch(setIsTroubleshooting(false))}
777-
>
778-
{t('Troubleshooting')}
779-
</Label>
780-
) : (
781-
// TODO: Workaround for PatternFly bug that causes attach menu to move. Remove once
782-
// issue is addressed in PatternFly.
783-
<div></div>
784-
)
770+
<Select
771+
isOpen={isModeMenuOpen}
772+
onOpenChange={setIsModeMenuOpen}
773+
onSelect={onModeMenuSelect}
774+
selected={isTroubleshooting ? 'troubleshooting' : 'ask'}
775+
toggle={modeMenuToggle}
776+
>
777+
<SelectList>
778+
<SelectOption
779+
description={t('Expert guidance and clear answers')}
780+
icon={<OutlinedCommentIcon />}
781+
isSelected={!isTroubleshooting}
782+
value="ask"
783+
>
784+
{t('Ask')}
785+
</SelectOption>
786+
<SelectOption
787+
description={t('Diagnosing issues and finding solutions')}
788+
icon={<WrenchIcon />}
789+
isSelected={isTroubleshooting}
790+
value="troubleshooting"
791+
>
792+
{t('Troubleshooting')}
793+
</SelectOption>
794+
</SelectList>
795+
</Select>
785796
}
786797
alwayShowSendButton
787798
attachButtonPosition="start"
@@ -806,7 +817,11 @@ const Prompt: React.FC<PromptProps> = ({ scrollIntoView }) => {
806817
isSendButtonDisabled={!query || query.trim().length === 0}
807818
onChange={(e) => onChange(e, e.target.value)}
808819
onSendMessage={onSubmit}
809-
placeholder={t('Send a message...')}
820+
placeholder={
821+
isTroubleshooting
822+
? t("Describe the issue you're troubleshooting...")
823+
: t('Ask a question...')
824+
}
810825
validated={validated}
811826
value={query}
812827
/>

tests/tests/lightspeed-install.cy.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const modal = '.ols-plugin__modal';
3737
const promptArea = `${popover} .ols-plugin__prompt`;
3838
const attachButton = `${promptArea} .pf-chatbot__button--attach`;
3939
const promptInput = `${promptArea} textarea`;
40-
const troubleshootingLabel = `${popover} [aria-label="Remove Troubleshooting mode"]`;
40+
const modeToggle = `${popover} [data-test="ols-plugin__mode-toggle"]`;
4141

4242
const podNamePrefix = 'console';
4343

@@ -361,34 +361,32 @@ spec:
361361
cy.get(promptInput).should('contain', PROMPT_NOT_SUBMITTED);
362362
});
363363

364-
it('Test Troubleshooting mode label persists after reopening the UI', () => {
364+
it('Test Troubleshooting mode persists after reopening the UI', () => {
365365
cy.visit('/search/all-namespaces');
366366
cy.get('h1').contains('Search').should('exist');
367367
cy.get(mainButton).click();
368368
cy.get(popover).should('exist');
369369

370-
cy.get(troubleshootingLabel).should('not.exist');
371-
cy.get(attachButton).click();
372-
cy.get(attachMenu).find('button').contains('Troubleshooting').click();
373-
cy.get(troubleshootingLabel).should('exist');
374-
cy.get(popover).should('include.text', 'Troubleshooting');
370+
cy.get(modeToggle).should('include.text', 'Ask');
371+
cy.get(modeToggle).click();
372+
cy.contains('[role="option"]', 'Troubleshooting').click();
373+
cy.get(modeToggle).should('include.text', 'Troubleshooting');
375374

376375
cy.get(minimizeButton).click();
377376
cy.get(popover).should('not.exist');
378377
cy.get(mainButton).click();
379378
cy.get(popover).should('exist');
380-
cy.get(troubleshootingLabel).should('exist');
381-
cy.get(popover).should('include.text', 'Troubleshooting');
379+
cy.get(modeToggle).should('include.text', 'Troubleshooting');
382380

383-
cy.get(attachButton).click();
384-
cy.get(attachMenu).find('button').contains('Ask').click();
385-
cy.get(troubleshootingLabel).should('not.exist');
381+
cy.get(modeToggle).click();
382+
cy.contains('[role="option"]', 'Ask').click();
383+
cy.get(modeToggle).should('include.text', 'Ask');
386384

387385
cy.get(minimizeButton).click();
388386
cy.get(popover).should('not.exist');
389387
cy.get(mainButton).click();
390388
cy.get(popover).should('exist');
391-
cy.get(troubleshootingLabel).should('not.exist');
389+
cy.get(modeToggle).should('include.text', 'Ask');
392390
});
393391

394392
describe('Streamed response', { tags: ['@response'] }, () => {

0 commit comments

Comments
 (0)