mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
refactor: CB-1548 useMenu options
This commit is contained in:
@@ -23,7 +23,6 @@
|
||||
hs_err_pid*
|
||||
|
||||
# web
|
||||
/sources/web/node_modules/
|
||||
dist/
|
||||
|
||||
## IDEA configs
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ export const TreeNodeMenu = observer<Props>(function TreeNodeMenu({
|
||||
selected,
|
||||
}) {
|
||||
const connectionsInfoResource = useService(ConnectionInfoResource);
|
||||
const menu = useMenu(MENU_NAV_TREE);
|
||||
const menu = useMenu({ menu: MENU_NAV_TREE });
|
||||
menu.context.set(DATA_CONTEXT_NAV_NODE, node);
|
||||
menu.context.set(DATA_CONTEXT_NAV_NODE_ACTIONS, actions);
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ const MenuBarElement = observer<IMenuBarElementProps>(function MenuBarElement({
|
||||
item,
|
||||
menuData,
|
||||
nestedMenuSettings,
|
||||
style
|
||||
style,
|
||||
}) {
|
||||
const styles = useStyles(style);
|
||||
|
||||
@@ -165,11 +165,11 @@ const SubMenuItem = observer<ISubMenuItemProps>(function SubmenuItem({
|
||||
item,
|
||||
menuData,
|
||||
nestedMenuSettings,
|
||||
style
|
||||
style,
|
||||
}) {
|
||||
const styles = useStyles(style);
|
||||
const menuService = useService(MenuService);
|
||||
const subMenuData = useMenu(item.menu, menuData.context);
|
||||
const subMenuData = useMenu({ menu: item.menu, context: menuData.context });
|
||||
|
||||
const handler = menuService.getHandler(menuData.context);
|
||||
const loading = handler?.isLoading?.(menuData.context);
|
||||
|
||||
@@ -348,7 +348,7 @@ export const MenuInnerTrigger = observer<IMenuInnerTriggerProps, HTMLButtonEleme
|
||||
) {
|
||||
const menuService = useService(MenuService);
|
||||
const menu = useMenuState();
|
||||
const subMenuData = useMenu(subMenu.menu, menuData.context);
|
||||
const subMenuData = useMenu({ menu: subMenu.menu, context: menuData.context });
|
||||
subMenuData.context.set(DATA_CONTEXT_MENU_NESTED, true);
|
||||
|
||||
const handler = menuService.getHandler(subMenuData.context);
|
||||
|
||||
@@ -39,7 +39,10 @@ export const Tab = observer<TabProps>(function Tab({
|
||||
const translate = useTranslate();
|
||||
const tabContext = useMemo(() => ({ tabId }), [tabId]);
|
||||
const { state, getInfo, handleClose, handleOpen } = useTab(tabId, onOpen, onClose, onClick);
|
||||
const menu = useMenu(MENU_TAB, menuContext);
|
||||
const menu = useMenu({
|
||||
menu: MENU_TAB,
|
||||
context: menuContext,
|
||||
});
|
||||
const info = getInfo();
|
||||
|
||||
const [menuOpened, switchState] = useState(false);
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2021 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { createDataContext } from '../DataContext/createDataContext';
|
||||
|
||||
export const DATA_CONTEXT_MENU_LOCAL = createDataContext<boolean | undefined>('menu-local', false);
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
import type { IAction } from '../Action/IAction';
|
||||
import type { DataContextGetter } from '../DataContext/DataContextGetter';
|
||||
import type { IDataContextProvider } from '../DataContext/IDataContextProvider';
|
||||
import type { IMenu } from './IMenu';
|
||||
import type { IMenuItem } from './MenuItem/IMenuItem';
|
||||
@@ -14,6 +15,8 @@ import type { IMenuItem } from './MenuItem/IMenuItem';
|
||||
export type MenuCreatorItem = IMenuItem | IAction | IMenu;
|
||||
|
||||
export interface IMenuItemsCreator {
|
||||
menus?: IMenu[];
|
||||
contexts?: DataContextGetter<any>[];
|
||||
isApplicable?: (context: IDataContextProvider) => boolean;
|
||||
getItems: (
|
||||
context: IDataContextProvider,
|
||||
|
||||
@@ -13,6 +13,8 @@ import { isAction } from '../Action/createAction';
|
||||
import type { IAction } from '../Action/IAction';
|
||||
import type { IDataContextProvider } from '../DataContext/IDataContextProvider';
|
||||
import { isMenu } from './createMenu';
|
||||
import { DATA_CONTEXT_MENU } from './DATA_CONTEXT_MENU';
|
||||
import { DATA_CONTEXT_MENU_LOCAL } from './DATA_CONTEXT_MENU_LOCAL';
|
||||
import type { IMenuHandler } from './IMenuHandler';
|
||||
import type { IMenuItemsCreator, MenuCreatorItem } from './IMenuItemsCreator';
|
||||
import type { IMenuActionItem } from './MenuItem/IMenuActionItem';
|
||||
@@ -22,8 +24,8 @@ import { MenuSubMenuItem } from './MenuItem/MenuSubMenuItem';
|
||||
|
||||
@injectable()
|
||||
export class MenuService {
|
||||
private handlers: Map<string, IMenuHandler>;
|
||||
private creators: IMenuItemsCreator[];
|
||||
private readonly handlers: Map<string, IMenuHandler>;
|
||||
private readonly creators: IMenuItemsCreator[];
|
||||
|
||||
constructor(
|
||||
private readonly actionService: ActionService,
|
||||
@@ -102,6 +104,32 @@ export class MenuService {
|
||||
}
|
||||
}
|
||||
|
||||
function filterApplicable(context: IDataContextProvider): (creator: IMenuItemsCreator) => boolean {
|
||||
return (creator: IMenuItemsCreator) => creator.isApplicable?.(context) ?? true;
|
||||
function filterApplicable(contexts: IDataContextProvider): (creator: IMenuItemsCreator) => boolean {
|
||||
const local = contexts.get(DATA_CONTEXT_MENU_LOCAL);
|
||||
|
||||
return (creator: IMenuItemsCreator) => {
|
||||
if (local) {
|
||||
if (!creator.menus && !creator.contexts) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (creator.menus) {
|
||||
const applicable = creator.menus.some(menu => contexts.find(DATA_CONTEXT_MENU, menu));
|
||||
|
||||
if (!applicable) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (creator.contexts) {
|
||||
const applicable = creator.contexts.some(context => contexts.has(context));
|
||||
|
||||
if (!applicable) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return creator.isApplicable?.(contexts) ?? true;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useObjectRef } from '@cloudbeaver/core-blocks';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
|
||||
import type { IDataContext } from '../DataContext/IDataContext';
|
||||
import { DATA_CONTEXT_MENU_LOCAL } from './DATA_CONTEXT_MENU_LOCAL';
|
||||
import type { IMenu } from './IMenu';
|
||||
import type { IMenuItem } from './MenuItem/IMenuItem';
|
||||
import { MenuService } from './MenuService';
|
||||
@@ -22,9 +23,17 @@ export interface IMenuData {
|
||||
getItems: () => IMenuItem[];
|
||||
}
|
||||
|
||||
export function useMenu(menu: IMenu, menuContext?: IDataContext): IMenuData {
|
||||
interface IMenuOptions {
|
||||
menu: IMenu;
|
||||
context?: IDataContext;
|
||||
local?: boolean;
|
||||
}
|
||||
|
||||
export function useMenu(options: IMenuOptions): IMenuData {
|
||||
const menuService = useService(MenuService);
|
||||
const context = useMenuContext(menu, menuContext);
|
||||
const context = useMenuContext(options.menu, options.context);
|
||||
|
||||
context.set(DATA_CONTEXT_MENU_LOCAL, options.local);
|
||||
|
||||
return useObjectRef(() => ({
|
||||
isAvailable() {
|
||||
@@ -34,7 +43,7 @@ export function useMenu(menu: IMenu, menuContext?: IDataContext): IMenuData {
|
||||
return menuService.getMenu(this.context);
|
||||
},
|
||||
}), {
|
||||
menu,
|
||||
menu: options.menu,
|
||||
context,
|
||||
}, ['isAvailable', 'getItems']);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ export * from './Menu/MenuItem/MenuLazyItem';
|
||||
export * from './Menu/MenuItem/MenuSeparatorItem';
|
||||
export * from './Menu/MenuItem/MenuSubMenuItem';
|
||||
export * from './Menu/createMenu';
|
||||
export * from './Menu/DATA_CONTEXT_MENU_LOCAL';
|
||||
export * from './Menu/DATA_CONTEXT_MENU_NESTED';
|
||||
export * from './Menu/DATA_CONTEXT_MENU';
|
||||
export * from './Menu/IMenu';
|
||||
|
||||
@@ -87,7 +87,7 @@ export const TableHeaderMenu: PlaceholderComponent<ITableHeaderPlaceholderProps>
|
||||
model,
|
||||
resultIndex,
|
||||
}) {
|
||||
const menu = useMenu(DATA_VIEWER_DATA_MODEL_TOOLS_MENU);
|
||||
const menu = useMenu({ menu: DATA_VIEWER_DATA_MODEL_TOOLS_MENU });
|
||||
|
||||
menu.context.set(DATA_CONTEXT_DATA_VIEWER_DATABASE_DATA_MODEL, model);
|
||||
menu.context.set(DATA_CONTEXT_DATA_VIEWER_DATABASE_DATA_MODEL_RESULT_INDEX, resultIndex);
|
||||
|
||||
@@ -46,7 +46,7 @@ const styles = css`
|
||||
export const DDLViewerTabPanel: NavNodeTransformViewComponent = observer(function DDLViewerTabPanel({ nodeId, folderId }) {
|
||||
const style = useStyles(styles);
|
||||
const controller = useController(DdlViewerController, nodeId);
|
||||
const menu = useMenu(MENU_DDL_VIEWER_FOOTER);
|
||||
const menu = useMenu({ menu: MENU_DDL_VIEWER_FOOTER });
|
||||
|
||||
useEffect(() => {
|
||||
controller.load();
|
||||
|
||||
+1
-1
@@ -150,7 +150,7 @@ const ItemName = observer<IItemNameProps>(function ItemName({
|
||||
property,
|
||||
}) {
|
||||
const connectionsInfoResource = useService(ConnectionInfoResource);
|
||||
const menu = useMenu(MENU_NAV_TREE);
|
||||
const menu = useMenu({ menu: MENU_NAV_TREE });
|
||||
menu.context.set(DATA_CONTEXT_NAV_NODE, node);
|
||||
|
||||
const connection = connectionsInfoResource.getConnectionForNode(node.id);
|
||||
|
||||
@@ -9,17 +9,17 @@
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import styled from 'reshadow';
|
||||
|
||||
import { topMenuStyles } from '@cloudbeaver/core-app';
|
||||
import { Icon } from '@cloudbeaver/core-blocks';
|
||||
import { useStyles } from '@cloudbeaver/core-theming';
|
||||
import { ContextMenu } from '@cloudbeaver/core-ui';
|
||||
import { useMenu } from '@cloudbeaver/core-view';
|
||||
import { Icon } from '@cloudbeaver/core-blocks';
|
||||
import { topMenuStyles } from '@cloudbeaver/core-app';
|
||||
|
||||
import { settingsMenuStyles } from './settingsMenuStyles';
|
||||
import { TOP_NAV_BAR_SETTINGS_MENU } from './TOP_NAV_BAR_SETTINGS_MENU';
|
||||
|
||||
export const SettingsMenu = observer(function SettingsMenu() {
|
||||
const menu = useMenu(TOP_NAV_BAR_SETTINGS_MENU);
|
||||
const menu = useMenu({ menu: TOP_NAV_BAR_SETTINGS_MENU });
|
||||
|
||||
return styled(useStyles(settingsMenuStyles))(
|
||||
<ContextMenu
|
||||
|
||||
@@ -24,7 +24,7 @@ import { userMenuStyles } from './userMenuStyles';
|
||||
export const UserMenu = observer(function UserMenu() {
|
||||
const style = useStyles(userMenuStyles);
|
||||
const authInfoService = useService(AuthInfoService);
|
||||
const menu = useMenu(MENU_USER_PROFILE);
|
||||
const menu = useMenu({ menu: MENU_USER_PROFILE });
|
||||
|
||||
menu.context.set(DATA_CONTEXT_USER, authInfoService.userInfo);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user