diff --git a/locales/en/plugin__lightspeed-console-plugin.json b/locales/en/plugin__lightspeed-console-plugin.json index 7e4adfc9..640b095b 100644 --- a/locales/en/plugin__lightspeed-console-plugin.json +++ b/locales/en/plugin__lightspeed-console-plugin.json @@ -8,6 +8,7 @@ "Approve": "Approve", "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.", "Ask": "Ask", + "Ask a question...": "Ask a question...", "Attach": "Attach", "Attach cluster info": "Attach cluster info", "Bad response": "Bad response", @@ -31,6 +32,7 @@ "Copy to clipboard": "Copy to clipboard", "Currently viewing": "Currently viewing", "Denial failed:": "Denial failed:", + "Describe the issue you're troubleshooting...": "Describe the issue you're troubleshooting...", "Diagnosing issues and finding solutions": "Diagnosing issues and finding solutions", "Dismiss": "Dismiss", "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 @@ "Red Hat OpenShift Lightspeed": "Red Hat OpenShift Lightspeed", "Refresh": "Refresh", "Reject": "Reject", - "Remove Troubleshooting mode": "Remove Troubleshooting mode", "Restore": "Restore", "Revert to original": "Revert to original", "Review required": "Review required", "Save": "Save", - "Send a message...": "Send a message...", "Status": "Status", "Stay": "Stay", "Structured content": "Structured content", diff --git a/src/components/Prompt.tsx b/src/components/Prompt.tsx index f0687d56..80e7e188 100644 --- a/src/components/Prompt.tsx +++ b/src/components/Prompt.tsx @@ -14,10 +14,13 @@ import { MessageBar } from '@patternfly/chatbot'; import { Alert, AlertActionCloseButton, - Divider, DropdownItem, DropdownList, Label, + MenuToggle, + Select, + SelectList, + SelectOption, Spinner, Title, Tooltip, @@ -26,7 +29,7 @@ import { FileCodeIcon, FileUploadIcon, InfoCircleIcon, - OutlinedQuestionCircleIcon, + OutlinedCommentIcon, PlusIcon, TaskIcon, WrenchIcon, @@ -130,6 +133,7 @@ const Prompt: React.FC = ({ scrollIntoView }) => { const [isLogModalOpen, , openLogModal, closeLogModal] = useBoolean(false); const [isLoading, , setLoading, setLoaded] = useBoolean(false); const [isOpen, setIsOpen] = React.useState(false); + const [isModeMenuOpen, setIsModeMenuOpen] = React.useState(false); const [streamController, setStreamController] = React.useState(new AbortController()); const [validated, setValidated] = React.useState<'default' | 'error'>('default'); @@ -294,26 +298,6 @@ const Prompt: React.FC = ({ scrollIntoView }) => { } key="upload" value={AttachmentTypes.YAMLUpload}> {t('Upload from computer')} - - {isTroubleshooting ? ( - } - id="ask" - value="ask" - > - {t('Ask')} - - ) : ( - } - id="troubleshooting" - value="troubleshooting" - > - {t('Troubleshooting')} - - )} , ], [ @@ -321,7 +305,6 @@ const Prompt: React.FC = ({ scrollIntoView }) => { isEventsLoading, isLoading, isResourceContext, - isTroubleshooting, kind, name, namespace, @@ -335,17 +318,7 @@ const Prompt: React.FC = ({ scrollIntoView }) => { (_ev: React.MouseEvent, attachmentType: string | number) => { setIsOpen(false); - if (attachmentType === 'ask') { - // Delay update until menu fade out is complete - requestAnimationFrame(() => { - setTimeout(() => dispatch(setIsTroubleshooting(false)), 0); - }); - } else if (attachmentType === 'troubleshooting') { - // Delay update until menu fade out is complete - requestAnimationFrame(() => { - setTimeout(() => dispatch(setIsTroubleshooting(true)), 0); - }); - } else if (attachmentType === AttachmentTypes.Events) { + if (attachmentType === AttachmentTypes.Events) { openEventsModal(); } else if (attachmentType === AttachmentTypes.Log) { openLogModal(); @@ -765,23 +738,61 @@ const Prompt: React.FC = ({ scrollIntoView }) => { [dispatch, streamController, streamingResponseID], ); + const modeMenuToggle = React.useCallback( + (toggleRef: React.Ref) => ( + : } + isExpanded={isModeMenuOpen} + onClick={() => setIsModeMenuOpen(!isModeMenuOpen)} + ref={toggleRef} + variant="plainText" + > + {isTroubleshooting ? t('Troubleshooting') : t('Ask')} + + ), + [isModeMenuOpen, isTroubleshooting, t], + ); + + const onModeMenuSelect = React.useCallback( + (_ev: React.MouseEvent, value: string | number) => { + dispatch(setIsTroubleshooting(value === 'troubleshooting')); + setIsModeMenuOpen(false); + }, + [dispatch], + ); + return (
{/* @ts-expect-error: TS2786 */} dispatch(setIsTroubleshooting(false))} - > - {t('Troubleshooting')} - - ) : ( - // TODO: Workaround for PatternFly bug that causes attach menu to move. Remove once - // issue is addressed in PatternFly. -
- ) + } alwayShowSendButton attachButtonPosition="start" @@ -806,7 +817,11 @@ const Prompt: React.FC = ({ scrollIntoView }) => { isSendButtonDisabled={!query || query.trim().length === 0} onChange={(e) => onChange(e, e.target.value)} onSendMessage={onSubmit} - placeholder={t('Send a message...')} + placeholder={ + isTroubleshooting + ? t("Describe the issue you're troubleshooting...") + : t('Ask a question...') + } validated={validated} value={query} /> diff --git a/tests/tests/lightspeed-install.cy.ts b/tests/tests/lightspeed-install.cy.ts index 944b5453..6071d86d 100644 --- a/tests/tests/lightspeed-install.cy.ts +++ b/tests/tests/lightspeed-install.cy.ts @@ -37,7 +37,7 @@ const modal = '.ols-plugin__modal'; const promptArea = `${popover} .ols-plugin__prompt`; const attachButton = `${promptArea} .pf-chatbot__button--attach`; const promptInput = `${promptArea} textarea`; -const troubleshootingLabel = `${popover} [aria-label="Remove Troubleshooting mode"]`; +const modeToggle = `${popover} [data-test="ols-plugin__mode-toggle"]`; const podNamePrefix = 'console'; @@ -361,34 +361,32 @@ spec: cy.get(promptInput).should('contain', PROMPT_NOT_SUBMITTED); }); - it('Test Troubleshooting mode label persists after reopening the UI', () => { + it('Test Troubleshooting mode persists after reopening the UI', () => { cy.visit('/search/all-namespaces'); cy.get('h1').contains('Search').should('exist'); cy.get(mainButton).click(); cy.get(popover).should('exist'); - cy.get(troubleshootingLabel).should('not.exist'); - cy.get(attachButton).click(); - cy.get(attachMenu).find('button').contains('Troubleshooting').click(); - cy.get(troubleshootingLabel).should('exist'); - cy.get(popover).should('include.text', 'Troubleshooting'); + cy.get(modeToggle).should('include.text', 'Ask'); + cy.get(modeToggle).click(); + cy.contains('[role="option"]', 'Troubleshooting').click(); + cy.get(modeToggle).should('include.text', 'Troubleshooting'); cy.get(minimizeButton).click(); cy.get(popover).should('not.exist'); cy.get(mainButton).click(); cy.get(popover).should('exist'); - cy.get(troubleshootingLabel).should('exist'); - cy.get(popover).should('include.text', 'Troubleshooting'); + cy.get(modeToggle).should('include.text', 'Troubleshooting'); - cy.get(attachButton).click(); - cy.get(attachMenu).find('button').contains('Ask').click(); - cy.get(troubleshootingLabel).should('not.exist'); + cy.get(modeToggle).click(); + cy.contains('[role="option"]', 'Ask').click(); + cy.get(modeToggle).should('include.text', 'Ask'); cy.get(minimizeButton).click(); cy.get(popover).should('not.exist'); cy.get(mainButton).click(); cy.get(popover).should('exist'); - cy.get(troubleshootingLabel).should('not.exist'); + cy.get(modeToggle).should('include.text', 'Ask'); }); describe('Streamed response', { tags: ['@response'] }, () => {