Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Runtime drawers default active #2870

Merged
merged 10 commits into from
Oct 16, 2024
106 changes: 106 additions & 0 deletions src/app-layout/__tests__/runtime-drawers.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1042,5 +1042,111 @@ describe('toolbar mode only features', () => {

expect(wrapper.findActiveDrawer()!.getElement()).toHaveTextContent('runtime drawer content');
});

describe('dynamically registered drawers with defaultActive: true', () => {
test('should open if there are already open local drawer on the page', async () => {
const { wrapper, globalDrawersWrapper } = await renderComponent(<AppLayout drawers={[testDrawer]} />);

wrapper.findDrawerTriggerById('security')!.click();
expect(wrapper.findActiveDrawer()!.getElement()).toHaveTextContent('Security');

awsuiPlugins.appLayout.registerDrawer({
...drawerDefaults,
id: 'global1',
type: 'global',
defaultActive: true,
});

await delay();

expect(globalDrawersWrapper.findDrawerById('global1')!.isActive()).toBe(true);

awsuiPlugins.appLayout.registerDrawer({
...drawerDefaults,
id: 'global2',
type: 'global',
defaultActive: true,
});

await delay();

expect(wrapper.findActiveDrawer()!.getElement()).toHaveTextContent('Security');
expect(globalDrawersWrapper.findDrawerById('global1')!.isActive()).toBe(true);
expect(globalDrawersWrapper.findDrawerById('global2')!.isActive()).toBe(true);
});

test('should not open if there are already global drawers opened by user action on the page', async () => {
const { wrapper, globalDrawersWrapper } = await renderComponent(<AppLayout drawers={[testDrawer]} />);

wrapper.findDrawerTriggerById('security')!.click();
expect(wrapper.findActiveDrawer()!.getElement()).toHaveTextContent('Security');

awsuiPlugins.appLayout.registerDrawer({
...drawerDefaults,
id: 'global1',
type: 'global',
});

await delay();

wrapper.findDrawerTriggerById('global1')!.click();
expect(globalDrawersWrapper.findDrawerById('global1')!.isActive()).toBe(true);

awsuiPlugins.appLayout.registerDrawer({
...drawerDefaults,
id: 'global2',
type: 'global',
defaultActive: true,
});

await delay();

expect(wrapper.findActiveDrawer()!.getElement()).toHaveTextContent('Security');
expect(globalDrawersWrapper.findDrawerById('global1')!.isActive()).toBe(true);
expect(globalDrawersWrapper.findDrawerById('global2')).toBeFalsy();
});

test('should not open if the maximum number (2) of global drawers is already open on the page', async () => {
const { wrapper, globalDrawersWrapper } = await renderComponent(<AppLayout drawers={[testDrawer]} />);

wrapper.findDrawerTriggerById('security')!.click();
expect(wrapper.findActiveDrawer()!.getElement()).toHaveTextContent('Security');

awsuiPlugins.appLayout.registerDrawer({
...drawerDefaults,
id: 'global1',
type: 'global',
defaultActive: true,
});

await delay();

expect(globalDrawersWrapper.findDrawerById('global1')!.isActive()).toBe(true);

awsuiPlugins.appLayout.registerDrawer({
...drawerDefaults,
id: 'global2',
type: 'global',
defaultActive: true,
});

await delay();

// this drawer should not open because there are already two global drawers open on the page, which is the maximum limit
awsuiPlugins.appLayout.registerDrawer({
...drawerDefaults,
id: 'global3',
type: 'global',
defaultActive: true,
});

await delay();

expect(wrapper.findActiveDrawer()!.getElement()).toHaveTextContent('Security');
expect(globalDrawersWrapper.findDrawerById('global1')!.isActive()).toBe(true);
expect(globalDrawersWrapper.findDrawerById('global2')!.isActive()).toBe(true);
expect(globalDrawersWrapper.findDrawerById('global3')).toBeFalsy();
});
});
});
});
26 changes: 19 additions & 7 deletions src/app-layout/utils/use-drawers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,10 @@ function useRuntimeDrawers(
const onLocalDrawerChangeStable = useStableCallback(onActiveDrawerChange);
const onGlobalDrawersChangeStable = useStableCallback(onActiveGlobalDrawersChange);

const drawersWereOpenRef = useRef(false);
drawersWereOpenRef.current = drawersWereOpenRef.current || !!activeDrawerId || !!activeGlobalDrawersIds.length;
const localDrawerWasOpenRef = useRef(false);
localDrawerWasOpenRef.current = localDrawerWasOpenRef.current || !!activeDrawerId;
const activeGlobalDrawersIdsRef = useRef<Array<string>>([]);
activeGlobalDrawersIdsRef.current = activeGlobalDrawersIds;

useEffect(() => {
if (disableRuntimeDrawers) {
Expand All @@ -74,17 +76,27 @@ function useRuntimeDrawers(
const localDrawers = drawers.filter(drawer => drawer.type !== 'global');
const globalDrawers = drawers.filter(drawer => drawer.type === 'global');
setRuntimeDrawers(convertRuntimeDrawers(localDrawers, globalDrawers));
if (!drawersWereOpenRef.current) {
if (!localDrawerWasOpenRef.current) {
const defaultActiveLocalDrawer = sortByPriority(localDrawers).find(drawer => drawer.defaultActive);
if (defaultActiveLocalDrawer) {
onLocalDrawerChangeStable(defaultActiveLocalDrawer.id);
}
}

const defaultActiveGlobalDrawers = sortByPriority(globalDrawers).filter(drawer => drawer.defaultActive);
defaultActiveGlobalDrawers.forEach(drawer => {
onGlobalDrawersChangeStable(drawer.id);
});
const drawersNotActiveByDefault = globalDrawers.filter(drawer => !drawer.defaultActive);
const hasDrawersOpenByUserAction = drawersNotActiveByDefault.find(drawer =>
activeGlobalDrawersIdsRef.current.includes(drawer.id)
);
if (hasDrawersOpenByUserAction || activeGlobalDrawersIdsRef.current.length === DRAWERS_LIMIT) {
return;
}

const defaultActiveGlobalDrawers = sortByPriority(globalDrawers).filter(
drawer => !activeGlobalDrawersIdsRef.current.includes(drawer.id) && drawer.defaultActive
);
defaultActiveGlobalDrawers.forEach(drawer => {
onGlobalDrawersChangeStable(drawer.id);
});
});
return () => {
unsubscribe();
Expand Down
Loading