Skip to content

Commit

Permalink
Use controlled version of InlineEdit component (#174850)
Browse files Browse the repository at this point in the history
## Summary

The [Inline Edit component](https://eui.elastic.co/#/forms/inline-edit)
did not have a controlled version when we started using it, so we had to
implement some nasty workarounds to get the component to re-render.

The Eui Team has since then added props to make the component
controlled, so we don't need this anymore. This PR cleans up the hacks.
As well as some unused props.
  • Loading branch information
CoenWarmer authored Jan 25, 2024
1 parent 9fe5a66 commit e6d228d
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ const defaultProps: ComponentStoryObj<typeof Component> = {
selectConnector: () => {},
reloadConnectors: () => {},
},
connectorsManagementHref: '',
currentUser: {
username: 'elastic',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { ChatTimeline } from './chat_timeline';
import { Feedback } from '../feedback_buttons';
import { IncorrectLicensePanel } from './incorrect_license_panel';
import { WelcomeMessage } from './welcome_message';
import { EMPTY_CONVERSATION_TITLE } from '../../i18n';
import { ASSISTANT_SETUP_TITLE, EMPTY_CONVERSATION_TITLE, UPGRADE_LICENSE_TITLE } from '../../i18n';
import { ChatActionClickType } from './types';
import type { StartedFrom } from '../../utils/get_timeline_items_from_conversation';
import { TELEMETRY, sendEvent } from '../../analytics';
Expand Down Expand Up @@ -93,7 +93,6 @@ export function ChatBody({
initialConversationId,
connectors,
knowledgeBase,
connectorsManagementHref,
currentUser,
startedFrom,
onConversationUpdate,
Expand All @@ -103,7 +102,6 @@ export function ChatBody({
initialConversationId?: string;
connectors: UseGenAIConnectorsResult;
knowledgeBase: UseKnowledgeBaseResult;
connectorsManagementHref: string;
currentUser?: Pick<AuthenticatedUser, 'full_name' | 'username'>;
startedFrom?: StartedFrom;
onConversationUpdate: (conversation: { conversation: Conversation['conversation'] }) => void;
Expand Down Expand Up @@ -135,6 +133,18 @@ export function ChatBody({
conversation.loading
);

let title = conversation.value?.conversation.title || initialTitle;

if (!title) {
if (!connectors.selectedConnector) {
title = ASSISTANT_SETUP_TITLE;
} else if (!hasCorrectLicense && !initialConversationId) {
title = UPGRADE_LICENSE_TITLE;
} else {
title = EMPTY_CONVERSATION_TITLE;
}
}

const containerClassName = css`
max-height: 100%;
max-width: ${startedFrom === 'conversationView'
Expand Down Expand Up @@ -391,12 +401,9 @@ export function ChatBody({
? conversation.value.conversation.id
: undefined
}
connectorsManagementHref={connectorsManagementHref}
knowledgeBase={knowledgeBase}
licenseInvalid={!hasCorrectLicense && !initialConversationId}
loading={isLoading}
startedFrom={startedFrom}
title={conversation.value?.conversation.title || initialTitle || EMPTY_CONVERSATION_TITLE}
title={title}
onCopyConversation={handleCopyConversation}
onSaveTitle={(newTitle) => {
saveTitle(newTitle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@ import React, { useState } from 'react';
import type { Message } from '../../../common/types';
import { useCurrentUser } from '../../hooks/use_current_user';
import { useGenAIConnectors } from '../../hooks/use_genai_connectors';
import { useKibana } from '../../hooks/use_kibana';
import { useKnowledgeBase } from '../../hooks/use_knowledge_base';
import { useObservabilityAIAssistantRouter } from '../../hooks/use_observability_ai_assistant_router';
import { getConnectorsManagementHref } from '../../utils/get_connectors_management_href';
import { StartedFrom } from '../../utils/get_timeline_items_from_conversation';
import { ChatBody } from './chat_body';

Expand All @@ -39,10 +37,6 @@ export function ChatFlyout({
startedFrom: StartedFrom;
onClose: () => void;
}) {
const {
services: { http },
} = useKibana();

const { euiTheme } = useEuiTheme();

const currentUser = useCurrentUser();
Expand Down Expand Up @@ -105,7 +99,6 @@ export function ChatFlyout({
initialTitle={initialTitle}
initialMessages={initialMessages}
currentUser={currentUser}
connectorsManagementHref={getConnectorsManagementHref(http)}
knowledgeBase={knowledgeBase}
startedFrom={startedFrom}
onConversationUpdate={(conversation) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,6 @@ export const ChatHeaderLoaded: ComponentStoryObj<typeof Component> = {
selectConnector: () => {},
reloadConnectors: () => {},
},
knowledgeBase: {
status: {
loading: false,
value: {
ready: true,
},
refresh: () => {},
},
isInstalling: false,
installError: undefined,
install: async () => {},
},
},
render: (props) => {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React, { useRef } from 'react';
import React, { useEffect, useState } from 'react';
import {
EuiFlexGroup,
EuiFlexItem,
Expand All @@ -17,11 +17,7 @@ import { i18n } from '@kbn/i18n';
import { css } from '@emotion/css';
import { AssistantAvatar } from '../assistant_avatar';
import { ChatActionsMenu } from './chat_actions_menu';
import { ASSISTANT_SETUP_TITLE, EMPTY_CONVERSATION_TITLE, UPGRADE_LICENSE_TITLE } from '../../i18n';
import { useUnmountAndRemountWhenPropChanges } from '../../hooks/use_unmount_and_remount_when_prop_changes';
import type { UseGenAIConnectorsResult } from '../../hooks/use_genai_connectors';
import type { UseKnowledgeBaseResult } from '../../hooks/use_knowledge_base';
import { StartedFrom } from '../../utils/get_timeline_items_from_conversation';

// needed to prevent InlineTextEdit component from expanding container
const minWidthClassName = css`
Expand All @@ -38,39 +34,25 @@ export function ChatHeader({
loading,
licenseInvalid,
connectors,
connectorsManagementHref,
conversationId,
knowledgeBase,
startedFrom,
onSaveTitle,
onCopyConversation,
onSaveTitle,
}: {
title: string;
loading: boolean;
licenseInvalid: boolean;
connectors: UseGenAIConnectorsResult;
connectorsManagementHref: string;
conversationId?: string;
knowledgeBase: UseKnowledgeBaseResult;
startedFrom?: StartedFrom;
onCopyConversation: () => void;
onSaveTitle?: (title: string) => void;
onSaveTitle: (title: string) => void;
}) {
const hasTitle = !!title;

const displayedTitle = !connectors.selectedConnector
? ASSISTANT_SETUP_TITLE
: licenseInvalid
? UPGRADE_LICENSE_TITLE
: title || EMPTY_CONVERSATION_TITLE;

const theme = useEuiTheme();

// Component only works uncontrolled at the moment, so need to unmount and remount on prop change.
// https://github.com/elastic/eui/issues/7084
const shouldRender = useUnmountAndRemountWhenPropChanges(displayedTitle);
const [newTitle, setNewTitle] = useState(title);

const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
setNewTitle(title);
}, [title]);

return (
<EuiPanel
Expand All @@ -86,28 +68,35 @@ export function ChatHeader({
</EuiFlexItem>

<EuiFlexItem grow className={minWidthClassName}>
{shouldRender ? (
<EuiInlineEditTitle
heading="h2"
size="s"
defaultValue={displayedTitle}
className={css`
color: ${hasTitle ? theme.euiTheme.colors.text : theme.euiTheme.colors.subduedText};
`}
inputAriaLabel={i18n.translate(
'xpack.observabilityAiAssistant.chatHeader.editConversationInput',
{ defaultMessage: 'Edit conversation' }
)}
editModeProps={{ inputProps: { inputRef } }}
isReadOnly={
!conversationId ||
!connectors.selectedConnector ||
licenseInvalid ||
!Boolean(onSaveTitle)
<EuiInlineEditTitle
heading="h2"
size="s"
value={newTitle}
className={css`
color: ${!!title ? theme.euiTheme.colors.text : theme.euiTheme.colors.subduedText};
`}
inputAriaLabel={i18n.translate(
'xpack.observabilityAiAssistant.chatHeader.editConversationInput',
{ defaultMessage: 'Edit conversation' }
)}
isReadOnly={
!conversationId ||
!connectors.selectedConnector ||
licenseInvalid ||
!Boolean(onSaveTitle)
}
onChange={(e) => {
setNewTitle(e.currentTarget.nodeValue || '');
}}
onSave={(e) => {
if (onSaveTitle) {
onSaveTitle(e);
}
onSave={onSaveTitle}
/>
) : null}
}}
onCancel={(previousTitle: string) => {
setNewTitle(previousTitle);
}}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<ChatActionsMenu
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import { useObservabilityAIAssistant } from '../../hooks/use_observability_ai_as
import { useObservabilityAIAssistantParams } from '../../hooks/use_observability_ai_assistant_params';
import { useObservabilityAIAssistantRouter } from '../../hooks/use_observability_ai_assistant_router';
import { EMPTY_CONVERSATION_TITLE } from '../../i18n';
import { getConnectorsManagementHref } from '../../utils/get_connectors_management_href';

const containerClassName = css`
max-width: 100%;
Expand All @@ -51,7 +50,7 @@ export function ConversationView() {
const { path } = useObservabilityAIAssistantParams('/conversations/*');

const {
services: { http, notifications },
services: { notifications },
} = useKibana();

const { element: confirmDeleteElement, confirm: confirmDeleteFunction } = useConfirmModal({
Expand Down Expand Up @@ -227,7 +226,6 @@ export function ConversationView() {
key={chatBodyKeyRef.current}
currentUser={currentUser}
connectors={connectors}
connectorsManagementHref={getConnectorsManagementHref(http)}
initialConversationId={conversationId}
knowledgeBase={knowledgeBase}
startedFrom="conversationView"
Expand Down

0 comments on commit e6d228d

Please sign in to comment.