From 6c05b57410fa012545ad52e09a1cdc6d7c73c242 Mon Sep 17 00:00:00 2001 From: tygao Date: Mon, 22 Jan 2024 15:48:24 +0800 Subject: [PATCH] update sidecar menu Signed-off-by: tygao --- public/chat_flyout.tsx | 10 +- public/chat_header_button.tsx | 42 +------ public/components/sidecar_icon_menu.tsx | 152 +++++++++++++----------- public/tabs/chat_window_header.tsx | 37 +----- 4 files changed, 88 insertions(+), 153 deletions(-) diff --git a/public/chat_flyout.tsx b/public/chat_flyout.tsx index f0c538c7..f792e19a 100644 --- a/public/chat_flyout.tsx +++ b/public/chat_flyout.tsx @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { EuiFlyout, EuiFlyoutHeader, EuiResizableContainer } from '@elastic/eui'; +import { EuiFlyoutHeader, EuiResizableContainer } from '@elastic/eui'; import cs from 'classnames'; import React, { useRef } from 'react'; import { useChatContext } from './contexts/chat_context'; @@ -16,9 +16,7 @@ import { TAB_ID } from './utils/constants'; interface ChatFlyoutProps { flyoutVisible: boolean; overrideComponent: React.ReactNode | null; - flyoutProps: Partial>; flyoutFullScreen: boolean; - toggleFlyoutFullScreen: (direction: string) => void; } export const ChatFlyout = (props: ChatFlyoutProps) => { @@ -85,14 +83,10 @@ export const ChatFlyout = (props: ChatFlyoutProps) => { className={cs('llm-chat-flyout', { 'llm-chat-fullscreen': props.flyoutFullScreen, })} - {...props.flyoutProps} > <> - + {props.overrideComponent} diff --git a/public/chat_header_button.tsx b/public/chat_header_button.tsx index 50bd53ba..6a72e979 100644 --- a/public/chat_header_button.tsx +++ b/public/chat_header_button.tsx @@ -6,7 +6,7 @@ import { EuiBadge, EuiFieldText, EuiIcon } from '@elastic/eui'; import classNames from 'classnames'; import React, { useCallback, useMemo, useRef, useState, useEffect } from 'react'; -import { useEffectOnce } from 'react-use'; +import { useEffectOnce, useObservable } from 'react-use'; import { ApplicationStart } from '../../../src/core/public'; import { ChatFlyout } from './chat_flyout'; import { ChatContext, IChatContext } from './contexts/chat_context'; @@ -43,46 +43,20 @@ export const HeaderChatButton = (props: HeaderChatButtonProps) => { const [selectedTabId, setSelectedTabId] = useState(TAB_ID.CHAT); const [preSelectedTabId, setPreSelectedTabId] = useState(undefined); const [interactionId, setInteractionId] = useState(undefined); - const [dockedDirection, setDockedDirection] = useState( - 'right' - ); const [query, setQuery] = useState(''); const [inputFocus, setInputFocus] = useState(false); - const flyoutFullScreen = dockedDirection === 'bottom'; const inputRef = useRef(null); // const [flyoutLoaded, setFlyoutLoaded] = useState(false); const core = useCore(); // if (!flyoutLoaded && flyoutVisible) flyoutLoaded = true; + const sidecarConfig = useObservable(core.overlays.sidecar().getSidecarConfig$()); + const flyoutFullScreen = sidecarConfig?.dockedMode === 'takeover'; useEffectOnce(() => { const subscription = props.application.currentAppId$.subscribe((id) => setAppId(id)); return () => subscription.unsubscribe(); }); - const toggleFlyoutFullScreen = useCallback( - (direction: ISidecarConfig['dockedDirection']) => { - setDockedDirection((prevDirection) => { - if (prevDirection === direction) { - return prevDirection; - } else { - if (direction === 'bottom') { - core.overlays.sidecar().setSidecarConfig({ - dockedDirection: 'bottom', - paddingSize: window.innerHeight - 136, - }); - } else { - core.overlays.sidecar().setSidecarConfig({ - dockedDirection: direction, - paddingSize: 460, - }); - } - return direction; - } - }); - }, - [flyoutFullScreen] - ); - const chatContextValue: IChatContext = useMemo( () => ({ appId, @@ -154,9 +128,7 @@ export const HeaderChatButton = (props: HeaderChatButtonProps) => { @@ -164,24 +136,18 @@ export const HeaderChatButton = (props: HeaderChatButtonProps) => { ); useEffect(() => { - console.log('visa', flyoutVisible, flyoutLoaded); if (!flyoutLoaded && flyoutVisible) { - console.log('mounut'); core.overlays.sidecar().open(toMountPoint(Chat), { className: 'chatbot-sidecar', config: { - dockedDirection: 'right', + dockedMode: 'right', paddingSize: 460, }, }); flyoutLoaded = true; } else if (flyoutLoaded && flyoutVisible) { - console.log('show'); - core.overlays.sidecar().show(); } else if (flyoutLoaded && !flyoutVisible) { - console.log('hide'); - core.overlays.sidecar().hide(); } }, [flyoutVisible, flyoutLoaded]); diff --git a/public/components/sidecar_icon_menu.tsx b/public/components/sidecar_icon_menu.tsx index 4445afb9..a12c35cd 100644 --- a/public/components/sidecar_icon_menu.tsx +++ b/public/components/sidecar_icon_menu.tsx @@ -3,40 +3,38 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { - EuiContextMenuItem, - EuiContextMenuPanel, - EuiFlexGroup, - EuiFlexItem, - EuiPopover, - EuiButtonIcon, -} from '@elastic/eui'; -import React, { useCallback, useState } from 'react'; +import { EuiContextMenuItem, EuiContextMenuPanel, EuiPopover, EuiButtonIcon } from '@elastic/eui'; +import React, { useCallback, useMemo, useState } from 'react'; +import { useObservable } from 'react-use'; +import { useCore } from '../contexts/core_context'; +import { ISidecarConfig } from '../../../../src/core/public'; -const dockBottom = () => ( - - - - - - -); +const ALL_SIDECAR_DIRECTIONS: Array<{ + mode: ISidecarConfig['dockedMode']; + name: string; + icon: string; +}> = [ + { + mode: 'right', + name: 'Dock Right', + icon: 'dockedRight', + }, + { + mode: 'left', + name: 'Dock Left', + icon: 'dockedLeft', + }, + { + mode: 'takeover', + name: 'Dock Full Width', + icon: 'dockedTakeover', + }, +]; -const dockRight = () => ( - - - - - - -); - -interface Props { - setDockedDirection: (direction: string) => void; -} - -export const SidecarIconMenu = ({ setDockedDirection }) => { +export const SidecarIconMenu = () => { const [isPopoverOpen, setPopoverOpen] = useState(false); + const core = useCore(); + const sidecarConfig = useObservable(core.overlays.sidecar().getSidecarConfig$()); const onButtonClick = useCallback(() => { setPopoverOpen((flag) => !flag); @@ -46,58 +44,68 @@ export const SidecarIconMenu = ({ setDockedDirection }) => { setPopoverOpen(false); }, []); - const button = ( - + const setDockedMode = useCallback( + (mode: ISidecarConfig['dockedMode']) => { + const currentMode = sidecarConfig?.dockedMode; + if (currentMode === mode) { + return; + } else { + if (mode === 'takeover') { + core.overlays.sidecar().setSidecarConfig({ + dockedMode: 'takeover', + paddingSize: window.innerHeight - 136, + }); + } else { + core.overlays.sidecar().setSidecarConfig({ + dockedMode: mode, + paddingSize: 460, + }); + } + } + }, + [sidecarConfig] + ); + + const menuItems = useMemo( + () => + ALL_SIDECAR_DIRECTIONS.map(({ name, icon, mode }) => ( + { + closePopover(); + setDockedMode(mode); + }} + icon={sidecarConfig?.dockedMode === mode ? 'check' : icon} + > + {name} + + )), + [sidecarConfig] ); - const items = [ - { - closePopover(); - setDockedDirection('right'); - }} - > - Dock Right - , - { - closePopover(); - setDockedDirection('left'); - }} - > - Dock Left - , - { - closePopover(); - setDockedDirection('bottom'); - }} - > - Dock Full Width - , - ]; + const selectMenuItemIndex = useMemo(() => { + const dockedMode = sidecarConfig?.dockedMode ?? 'right'; + return ALL_SIDECAR_DIRECTIONS.findIndex((item) => item.mode === dockedMode); + }, [sidecarConfig]); return ( <> + } isOpen={isPopoverOpen} closePopover={closePopover} panelPaddingSize="none" anchorPosition="downRight" > - + ); diff --git a/public/tabs/chat_window_header.tsx b/public/tabs/chat_window_header.tsx index 2cbd75a0..db44c61a 100644 --- a/public/tabs/chat_window_header.tsx +++ b/public/tabs/chat_window_header.tsx @@ -11,32 +11,9 @@ import chatIcon from '../assets/chat.svg'; import { TAB_ID } from '../utils/constants'; import { SidecarIconMenu } from '../components/sidecar_icon_menu'; -export interface ChatWindowHeaderProps { - flyoutFullScreen: boolean; - toggleFlyoutFullScreen: (direction: string) => void; -} - -export const ChatWindowHeader = React.memo((props: ChatWindowHeaderProps) => { +export const ChatWindowHeader = React.memo(() => { const chatContext = useChatContext(); - const dockBottom = () => ( - - - - - - - ); - - const dockRight = () => ( - - - - - - - ); - return ( <> { - - {/* - - */} +