diff --git a/pages/app-layout/utils/external-global-left-panel-widget.tsx b/pages/app-layout/utils/external-global-left-panel-widget.tsx index 007fd959f0..182a5ea08b 100644 --- a/pages/app-layout/utils/external-global-left-panel-widget.tsx +++ b/pages/app-layout/utils/external-global-left-panel-widget.tsx @@ -3,8 +3,8 @@ import React from 'react'; import ReactDOM, { unmountComponentAtNode } from 'react-dom'; -import { Box } from '~components'; -import { registerLeftDrawer } from '~components/internal/plugins/widget'; +import { Box, Button } from '~components'; +import { registerLeftDrawer, updateDrawer } from '~components/internal/plugins/widget'; import styles from '../styles.scss'; @@ -14,6 +14,20 @@ const AIDrawer = () => { Chat demo + + {new Array(100).fill(null).map((_, index) => (
Tela content
))} diff --git a/src/app-layout/__tests__/runtime-drawers-widgetized.test.tsx b/src/app-layout/__tests__/runtime-drawers-widgetized.test.tsx index 7df9ba1aa2..9d25e38ebc 100644 --- a/src/app-layout/__tests__/runtime-drawers-widgetized.test.tsx +++ b/src/app-layout/__tests__/runtime-drawers-widgetized.test.tsx @@ -151,6 +151,23 @@ describeEachAppLayout({ themes: ['refresh-toolbar'] }, ({ size }) => { expect(globalDrawersWrapper.findDrawerById(drawerDefaults.id)!.isActive()).toBe(true); }); + test('should enter and exit focus mode in global ai drawer via API', () => { + awsuiWidgetPlugins.registerLeftDrawer({ ...drawerDefaults, isExpandable: true, defaultActive: true }); + + const { globalDrawersWrapper } = renderComponent(); + expect(globalDrawersWrapper.findDrawerById(drawerDefaults.id)).toBeTruthy(); + + act(() => awsuiWidgetPlugins.updateDrawer({ type: 'expandDrawer', payload: { id: drawerDefaults.id } })); + + expect(globalDrawersWrapper.findDrawerById(drawerDefaults.id)!.isDrawerInExpandedMode()).toBe(true); + expect(globalDrawersWrapper.isLayoutInDrawerExpandedMode()).toBe(true); + + act(() => awsuiWidgetPlugins.updateDrawer({ type: 'exitExpandedMode' })); + + expect(globalDrawersWrapper.findDrawerById(drawerDefaults.id)!.isDrawerInExpandedMode()).toBe(false); + expect(globalDrawersWrapper.isLayoutInDrawerExpandedMode()).toBe(false); + }); + test('onResize functionality', () => { const onResize = jest.fn(); awsuiWidgetPlugins.registerLeftDrawer({ diff --git a/src/app-layout/utils/use-ai-drawer.ts b/src/app-layout/utils/use-ai-drawer.ts index 7945db2fd6..745db7f881 100644 --- a/src/app-layout/utils/use-ai-drawer.ts +++ b/src/app-layout/utils/use-ai-drawer.ts @@ -21,7 +21,8 @@ function useRuntimeAiDrawer( isEnabled: boolean, activeAiDrawerId: string | null, onActiveAiDrawerChange: (newDrawerId: string | null, { initiatedByUserAction }: OnChangeParams) => void, - onActiveAiDrawerResize: (size: number) => void + onActiveAiDrawerResize: (size: number) => void, + setExpandedDrawerId: (value: string | null) => void ) { const [aiDrawer, setAiDrawer] = useState(null); const appLayoutMessageHandler = useStableCallback((event: AppLayoutMessage) => { @@ -32,7 +33,7 @@ function useRuntimeAiDrawer( } return; } - if (aiDrawer && aiDrawer.id !== event.payload.id) { + if (aiDrawer && 'payload' in event && aiDrawer.id !== event.payload.id) { metrics.sendOpsMetricObject('awsui-widget-drawer-incorrect-id', { oldId: aiDrawer?.id, newId: event.payload.id }); return; } @@ -49,6 +50,12 @@ function useRuntimeAiDrawer( case 'resizeDrawer': onActiveAiDrawerResizeStable(event.payload.size); break; + case 'expandDrawer': + setExpandedDrawerIdStable(event.payload.id); + break; + case 'exitExpandedMode': + setExpandedDrawerIdStable(null); + break; /* istanbul ignore next: this code is not intended to be visited */ default: assertNever(event); @@ -57,6 +64,7 @@ function useRuntimeAiDrawer( const onAiDrawersChangeStable = useStableCallback(onActiveAiDrawerChange); const onActiveAiDrawerResizeStable = useStableCallback(onActiveAiDrawerResize); const onActiveAiDrawerChangeStable = useStableCallback(onActiveAiDrawerChange); + const setExpandedDrawerIdStable = useStableCallback(setExpandedDrawerId); const aiDrawerWasOpenRef = useRef(false); aiDrawerWasOpenRef.current = aiDrawerWasOpenRef.current || !!activeAiDrawerId; @@ -122,7 +130,13 @@ export function useAiDrawer({ isEnabled, onAiDrawerFocus, expandedDrawerId, setE onAiDrawerFocus?.(); } - const aiDrawer = useRuntimeAiDrawer(isEnabled, activeAiDrawerId, onActiveAiDrawerChange, onActiveAiDrawerResize); + const aiDrawer = useRuntimeAiDrawer( + isEnabled, + activeAiDrawerId, + onActiveAiDrawerChange, + onActiveAiDrawerResize, + setExpandedDrawerId + ); const activeAiDrawer = activeAiDrawerId && activeAiDrawerId === aiDrawer?.id ? aiDrawer : null; const activeAiDrawerSize = activeAiDrawerId ? (size ?? activeAiDrawer?.defaultSize ?? MIN_DRAWER_SIZE) : 0; const minAiDrawerSize = Math.min(activeAiDrawer?.defaultSize ?? MIN_DRAWER_SIZE, MIN_DRAWER_SIZE); diff --git a/src/internal/plugins/widget/interfaces.ts b/src/internal/plugins/widget/interfaces.ts index 24a4c870a8..27fe080891 100644 --- a/src/internal/plugins/widget/interfaces.ts +++ b/src/internal/plugins/widget/interfaces.ts @@ -57,11 +57,17 @@ export type UpdateDrawerConfigMessage = Message< export type OpenDrawerMessage = Message<'openDrawer', { id: string }>; export type CloseDrawerMessage = Message<'closeDrawer', { id: string }>; export type ResizeDrawerMessage = Message<'resizeDrawer', { id: string; size: number }>; +export type ExpandDrawerMessage = Message<'expandDrawer', { id: string }>; +export interface ExitExpandedModeMessage { + type: 'exitExpandedMode'; +} export type AppLayoutUpdateMessage = | UpdateDrawerConfigMessage | OpenDrawerMessage | CloseDrawerMessage - | ResizeDrawerMessage; + | ResizeDrawerMessage + | ExpandDrawerMessage + | ExitExpandedModeMessage; export type AppLayoutMessage = RegisterDrawerMessage | AppLayoutUpdateMessage;