Handle GroupMenu better

This commit is contained in:
Piotr Rogowski 2022-11-01 19:17:36 +01:00
parent 3fb11d5eed
commit b2b1a83e3e
No known key found for this signature in database
GPG Key ID: 4A842D702D9C6F8F
4 changed files with 74 additions and 23 deletions

View File

@ -54,7 +54,8 @@ import {
NavigationState,
} from '../types/state';
import {
buildUrl,
buildDialogUrl,
buildGroupMenuDialogUrl,
SKIP_MENUS,
SKIP_SUB_MENUS,
} from './Tune/SideBar';
@ -261,7 +262,12 @@ const ActionsProvider = (props: CommandPaletteProps) => {
},
];
const mapSubMenuItems = (rootMenuName: string, rootMenu: MenuType, subMenus: { [name: string]: SubMenuType | GroupMenuType | GroupChildMenuType }) => {
const mapSubMenuItems = (
rootMenuName: string,
rootMenu: MenuType,
subMenus: { [name: string]: SubMenuType | GroupMenuType | GroupChildMenuType },
groupMenuName: string | null = null,
) => {
Object
.keys(subMenus)
.forEach((subMenuName: string) => {
@ -276,17 +282,22 @@ const ActionsProvider = (props: CommandPaletteProps) => {
const subMenu = subMenus[subMenuName];
if ((subMenu as GroupMenuType).type === 'groupMenu') {
mapSubMenuItems(rootMenuName, rootMenu, (subMenu as GroupMenuType).groupChildMenus);
// recurrence
mapSubMenuItems(rootMenuName, rootMenu, (subMenu as GroupMenuType).groupChildMenus, (subMenu as GroupMenuType).title);
return;
}
const url = groupMenuName ?
buildGroupMenuDialogUrl(navigation.tuneId!, rootMenuName, groupMenuName, subMenuName) :
buildDialogUrl(navigation.tuneId!, rootMenuName, subMenuName);
newActions.push({
id: buildUrl(navigation.tuneId!, rootMenuName, subMenuName),
id: url,
section: rootMenu.title,
name: subMenu.title,
icon: <Icon name={subMenuName} />,
perform: () => navigate(buildUrl(navigation.tuneId!, rootMenuName, subMenuName)),
perform: () => navigate(url),
});
});
};

View File

@ -48,10 +48,17 @@ export const SKIP_SUB_MENUS = [
'tuning/std_realtime',
];
export const buildUrl = (tuneId: string, main: string, sub: string) => generatePath(Routes.TUNE_DIALOG, {
export const buildDialogUrl = (tuneId: string, main: string, dialog: string) => generatePath(Routes.TUNE_DIALOG, {
tuneId,
category: main,
dialog: sub,
dialog: dialog.replaceAll(' ', '-'),
});
export const buildGroupMenuDialogUrl = (tuneId: string, main: string, groupMenu: string, dialog: string) => generatePath(Routes.TUNE_GROUP_MENU_DIALOG, {
tuneId,
category: main,
groupMenu: groupMenu.replaceAll(' ', '-'),
dialog,
});
const mapStateToProps = (state: AppState) => ({
@ -66,13 +73,14 @@ interface SideBarProps {
tune: TuneType | null;
ui: UIState;
navigation: NavigationState;
matchedPath: PathMatch<'dialog' | 'tuneId' | 'category'>;
matchedPath: PathMatch<'dialog' | 'tuneId' | 'category'> | null;
matchedGroupMenuDialogPath: PathMatch<'dialog' | 'groupMenu' | 'tuneId' | 'category'> | null;
};
export const sidebarWidth = 250;
export const collapsedSidebarWidth = 50;
const SideBar = ({ config, tune, ui, navigation, matchedPath }: SideBarProps) => {
const SideBar = ({ config, tune, ui, navigation, matchedPath, matchedGroupMenuDialogPath }: SideBarProps) => {
const siderProps = {
width: sidebarWidth,
collapsedWidth: collapsedSidebarWidth,
@ -84,7 +92,11 @@ const SideBar = ({ config, tune, ui, navigation, matchedPath }: SideBarProps) =>
const [menus, setMenus] = useState<ItemType[]>([]);
const navigate = useNavigate();
const mapSubMenuItems = useCallback((rootMenuName: string, subMenus: { [name: string]: SubMenuType | GroupMenuType | GroupChildMenuType }): ItemType[] => {
const mapSubMenuItems = useCallback((
rootMenuName: string,
subMenus: { [name: string]: SubMenuType | GroupMenuType | GroupChildMenuType },
groupMenuName: string | null = null,
): ItemType[] => {
const items: ItemType[] = [];
Object
@ -105,16 +117,26 @@ const SideBar = ({ config, tune, ui, navigation, matchedPath }: SideBarProps) =>
const subMenu = subMenus[subMenuName];
if ((subMenu as GroupMenuType).type === 'groupMenu') {
items.push(...mapSubMenuItems(rootMenuName, (subMenu as GroupMenuType).groupChildMenus));
// recurrence
items.push({
key: buildDialogUrl(navigation.tuneId!, rootMenuName, (subMenu as GroupMenuType).title),
icon: <Icon name={subMenuName} />,
label: (subMenu as GroupMenuType).title,
children: mapSubMenuItems(rootMenuName, (subMenu as GroupMenuType).groupChildMenus, (subMenu as GroupMenuType).title),
});
return;
}
const url = groupMenuName ?
buildGroupMenuDialogUrl(navigation.tuneId!, rootMenuName, groupMenuName, subMenuName) :
buildDialogUrl(navigation.tuneId!, rootMenuName, subMenuName);
items.push({
key: buildUrl(navigation.tuneId!, rootMenuName, subMenuName),
key: url,
icon: <Icon name={subMenuName} />,
label: subMenu.title,
onClick: () => navigate(buildUrl(navigation.tuneId!, rootMenuName, subMenuName)),
onClick: () => navigate(url),
});
});
@ -144,15 +166,30 @@ const SideBar = ({ config, tune, ui, navigation, matchedPath }: SideBarProps) =>
}
}, [config, config?.menus, menusList, tune, tune?.constants]);
const defaultOpenSubmenus = () => {
if (matchedGroupMenuDialogPath) {
return [
`/${matchedGroupMenuDialogPath.params.category}`,
buildDialogUrl(
navigation.tuneId!,
matchedGroupMenuDialogPath.params.category!,
matchedGroupMenuDialogPath.params.groupMenu!,
),
];
}
return [`/${matchedPath!.params.category}`];
};
return (
<Sider {...siderProps} className="app-sidebar">
<PerfectScrollbar options={{ suppressScrollX: true }}>
<Menu
defaultSelectedKeys={[matchedPath.pathname]}
defaultOpenKeys={ui.sidebarCollapsed ? [] : [`/${matchedPath.params.category}`]}
defaultSelectedKeys={[matchedGroupMenuDialogPath ? matchedGroupMenuDialogPath.pathname : matchedPath!.pathname]}
defaultOpenKeys={ui.sidebarCollapsed ? [] : defaultOpenSubmenus()}
mode="inline"
style={{ height: '100%' }}
key={matchedPath.pathname}
key={matchedGroupMenuDialogPath ? matchedGroupMenuDialogPath.pathname : matchedPath!.pathname}
items={menus}
/>
</PerfectScrollbar>

View File

@ -26,8 +26,7 @@ const mapStateToProps = (state: AppState) => ({
const Tune = ({ config, tune }: { config: ConfigType | null, tune: TuneState }) => {
const dialogMatch = useMatch(Routes.TUNE_DIALOG);
const tuneRootMatch = useMatch(Routes.TUNE_TUNE);
// const { storageGetSync } = useBrowserStorage();
// const lastDialogPath = storageGetSync('lastDialog');
const groupMenuDialogMatch = useMatch(Routes.TUNE_GROUP_MENU_DIALOG);
const { isConfigReady } = useConfig(config);
const navigate = useNavigate();
@ -47,18 +46,21 @@ const Tune = ({ config, tune }: { config: ConfigType | null, tune: TuneState })
navigate(firstDialogPath, { replace: true });
}
}, [navigate, tuneRootMatch, isConfigReady, config?.menus, tuneId, config, tune, dialogMatch]);
}, [navigate, tuneRootMatch, isConfigReady, config?.menus, tuneId, config, tune, dialogMatch, groupMenuDialogMatch]);
if (!tune || !config || !dialogMatch) {
if (!tune || !config || (!dialogMatch && !groupMenuDialogMatch)) {
return <Loader />;
}
return (
<>
<SideBar matchedPath={dialogMatch!} />
<SideBar
matchedPath={dialogMatch!}
matchedGroupMenuDialogPath={groupMenuDialogMatch}
/>
<Dialog
name={dialogMatch?.params.dialog!}
url={dialogMatch?.pathname || ''}
name={groupMenuDialogMatch ? groupMenuDialogMatch.params.dialog! : dialogMatch?.params.dialog!}
url={groupMenuDialogMatch ? groupMenuDialogMatch.pathname : dialogMatch?.pathname || ''}
/>
</>
);

View File

@ -7,6 +7,7 @@ export enum Routes {
TUNE_TAB = '/t/:tuneId/:tab',
TUNE_TUNE = '/t/:tuneId/tune',
TUNE_DIALOG = '/t/:tuneId/tune/:category/:dialog',
TUNE_GROUP_MENU_DIALOG = '/t/:tuneId/tune/:category/:groupMenu/:dialog',
TUNE_LOGS = '/t/:tuneId/logs',
TUNE_LOGS_FILE = '/t/:tuneId/logs/:fileName',
TUNE_DIAGNOSE = '/t/:tuneId/diagnose',