fix: menu item highlight
This commit is contained in:
		
							parent
							
								
									b7be09efd7
								
							
						
					
					
						commit
						9560276fa1
					
				@ -45,6 +45,7 @@ import {
 | 
			
		||||
} from './SiteTitle';
 | 
			
		||||
import { AuthProvider } from './Auth';
 | 
			
		||||
import { Helmet } from 'react-helmet';
 | 
			
		||||
import { MenuSelectedKeysContext } from '../../schemas/menu';
 | 
			
		||||
 | 
			
		||||
function DesignableToggle() {
 | 
			
		||||
  const { designable, setDesignable } = useDesignableSwitchContext();
 | 
			
		||||
@ -77,17 +78,58 @@ function LayoutWithMenu(props: LayoutWithMenuProps) {
 | 
			
		||||
  const { title } = useSystemSettings();
 | 
			
		||||
  const [activeKey, setActiveKey] = useState(match.params.name);
 | 
			
		||||
  const { setPageTitle } = usePageTitleContext();
 | 
			
		||||
 | 
			
		||||
  const [selectedKeys, setSelectedKeys] = useState(defaultSelectedKeys);
 | 
			
		||||
  const onSelect = (info) => {
 | 
			
		||||
    if (!info.schema) {
 | 
			
		||||
      setActiveKey(null);
 | 
			
		||||
    } else if (info.schema['x-component'] === 'Menu.SubMenu') {
 | 
			
		||||
      const findMenuItem = (schema: Schema) => {
 | 
			
		||||
        const first = Object.values(schema.properties || {}).shift();
 | 
			
		||||
        if (!first) {
 | 
			
		||||
          return null;
 | 
			
		||||
        }
 | 
			
		||||
        if (['Menu.Link', 'Menu.URL'].includes(first['x-component'])) {
 | 
			
		||||
          return first;
 | 
			
		||||
        }
 | 
			
		||||
        return findMenuItem(first);
 | 
			
		||||
      };
 | 
			
		||||
      console.log('info.schema', findMenuItem(info.schema));
 | 
			
		||||
      // 实际应该取第一个子元素
 | 
			
		||||
      setActiveKey(null);
 | 
			
		||||
      const node = findMenuItem(info.schema);
 | 
			
		||||
      setActiveKey(node?.key);
 | 
			
		||||
      if (node?.key) {
 | 
			
		||||
        history.push(`/admin/${node?.key}`);
 | 
			
		||||
        const keys = [node?.name];
 | 
			
		||||
        let parent = node?.parent;
 | 
			
		||||
        while (parent) {
 | 
			
		||||
          if (parent['x-component'] === 'Menu') {
 | 
			
		||||
            break;
 | 
			
		||||
          }
 | 
			
		||||
          keys.unshift(parent.name);
 | 
			
		||||
          parent = parent.parent;
 | 
			
		||||
        }
 | 
			
		||||
        setSelectedKeys(keys);
 | 
			
		||||
        if (node.title) {
 | 
			
		||||
          setPageTitle(node.title);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      setActiveKey(info.schema.key);
 | 
			
		||||
      history.push(`/admin/${info.schema.key}`);
 | 
			
		||||
      if (info.schema.title) {
 | 
			
		||||
        setPageTitle(info.schema.title);
 | 
			
		||||
        const keys = [info.schema?.name];
 | 
			
		||||
        let parent = info.schema?.parent;
 | 
			
		||||
        while (parent) {
 | 
			
		||||
          if (parent['x-component'] === 'Menu') {
 | 
			
		||||
            break;
 | 
			
		||||
          }
 | 
			
		||||
          keys.unshift(parent.name);
 | 
			
		||||
          parent = parent.parent;
 | 
			
		||||
        }
 | 
			
		||||
        setSelectedKeys(keys);
 | 
			
		||||
        // setSelectedKeys([info.schema.name]);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
@ -97,20 +139,26 @@ function LayoutWithMenu(props: LayoutWithMenuProps) {
 | 
			
		||||
  const onMenuItemRemove = () => {
 | 
			
		||||
    history.push(`/admin`);
 | 
			
		||||
  };
 | 
			
		||||
  console.log({ activeKey });
 | 
			
		||||
  console.log({ activeKey, selectedKeys });
 | 
			
		||||
  return (
 | 
			
		||||
    <Layout>
 | 
			
		||||
      <Layout.Header className={'site-header'} style={{ display: 'flex' }}>
 | 
			
		||||
        <SiteTitle />
 | 
			
		||||
        <SchemaRenderer
 | 
			
		||||
          schema={schema}
 | 
			
		||||
          scope={{
 | 
			
		||||
            sideMenuRef,
 | 
			
		||||
            onSelect,
 | 
			
		||||
            onMenuItemRemove,
 | 
			
		||||
            selectedKeys: defaultSelectedKeys.filter(Boolean),
 | 
			
		||||
          }}
 | 
			
		||||
        />
 | 
			
		||||
        <MenuSelectedKeysContext.Provider value={selectedKeys}>
 | 
			
		||||
          <SchemaRenderer
 | 
			
		||||
            schema={schema}
 | 
			
		||||
            scope={{
 | 
			
		||||
              sideMenuRef,
 | 
			
		||||
              onSelect,
 | 
			
		||||
              onMenuItemRemove,
 | 
			
		||||
              getSelectedKeys: () => {
 | 
			
		||||
                console.log('getSelectedKeys', schema);
 | 
			
		||||
                return selectedKeys.filter(Boolean);
 | 
			
		||||
              },
 | 
			
		||||
              selectedKeys: selectedKeys.filter(Boolean),
 | 
			
		||||
            }}
 | 
			
		||||
          />
 | 
			
		||||
        </MenuSelectedKeysContext.Provider>
 | 
			
		||||
        <DesignableToggle />
 | 
			
		||||
        <Database />
 | 
			
		||||
        <Permissions />
 | 
			
		||||
 | 
			
		||||
@ -50,6 +50,14 @@ export const linkTo: FieldOptions = {
 | 
			
		||||
      'x-decorator': 'FormItem',
 | 
			
		||||
      'x-component': 'Select',
 | 
			
		||||
    },
 | 
			
		||||
    // 'uiSchema.x-component-props.fieldNames.label': {
 | 
			
		||||
    //   type: 'string',
 | 
			
		||||
    //   title: '要显示的标题字段',
 | 
			
		||||
    //   required: true,
 | 
			
		||||
    //   'x-reactions': ['{{useAsyncDataSource(loadCollectionFields)}}'],
 | 
			
		||||
    //   'x-decorator': 'FormItem',
 | 
			
		||||
    //   'x-component': 'Select',
 | 
			
		||||
    // },
 | 
			
		||||
    'uiSchema.x-component-props.multiple': {
 | 
			
		||||
      type: 'boolean',
 | 
			
		||||
      'x-content': '允许关联多条记录',
 | 
			
		||||
 | 
			
		||||
@ -82,6 +82,10 @@ export const MenuContext = createContext<MenuContextProps>(null);
 | 
			
		||||
const SideMenu = (props: any) => {
 | 
			
		||||
  const { selectedKey, defaultSelectedKeys, onSelect, path } = props;
 | 
			
		||||
  const { schema } = useDesignable();
 | 
			
		||||
  const [selectedKeys, setSelectedKeys] = useState(defaultSelectedKeys);
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    setSelectedKeys(defaultSelectedKeys);
 | 
			
		||||
  }, [defaultSelectedKeys]);
 | 
			
		||||
  if (!selectedKey) {
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
@ -89,10 +93,17 @@ const SideMenu = (props: any) => {
 | 
			
		||||
  if (!child || child['x-component'] !== 'Menu.SubMenu') {
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <MenuModeContext.Provider value={'inline'}>
 | 
			
		||||
      <AntdMenu mode={'inline'} onSelect={onSelect}>
 | 
			
		||||
      <AntdMenu
 | 
			
		||||
        mode={'inline'}
 | 
			
		||||
        onSelect={onSelect}
 | 
			
		||||
        onOpenChange={(openKeys) => {
 | 
			
		||||
          setSelectedKeys(openKeys);
 | 
			
		||||
        }}
 | 
			
		||||
        openKeys={selectedKeys}
 | 
			
		||||
        selectedKeys={selectedKeys}
 | 
			
		||||
      >
 | 
			
		||||
        <RecursionField schema={child} onlyRenderProperties />
 | 
			
		||||
        <Menu.AddNew key={uid()} path={[...path, selectedKey]}>
 | 
			
		||||
          <Button
 | 
			
		||||
@ -109,15 +120,19 @@ const SideMenu = (props: any) => {
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const MenuSelectedKeysContext = createContext<any>([]);
 | 
			
		||||
 | 
			
		||||
export const Menu: any = observer((props: any) => {
 | 
			
		||||
  const {
 | 
			
		||||
    mode,
 | 
			
		||||
    onSelect,
 | 
			
		||||
    sideMenuRef,
 | 
			
		||||
    defaultSelectedKeys = [],
 | 
			
		||||
    defaultSelectedKeys: keys,
 | 
			
		||||
    getSelectedKeys,
 | 
			
		||||
    onRemove,
 | 
			
		||||
    ...others
 | 
			
		||||
  } = props;
 | 
			
		||||
  const defaultSelectedKeys = useContext(MenuSelectedKeysContext);
 | 
			
		||||
  const { root, schema, insertAfter, remove } = useDesignable();
 | 
			
		||||
  const moveToAfter = (path1, path2) => {
 | 
			
		||||
    if (!path1 || !path2) {
 | 
			
		||||
@ -163,7 +178,7 @@ export const Menu: any = observer((props: any) => {
 | 
			
		||||
  }, [selectedKey]);
 | 
			
		||||
 | 
			
		||||
  const [dragOverlayContent, setDragOverlayContent] = useState('');
 | 
			
		||||
  console.log('onRemove', onRemove);
 | 
			
		||||
  // console.log('defaultSelectedKeys', defaultSelectedKeys, getSelectedKeys);
 | 
			
		||||
  return (
 | 
			
		||||
    <MenuContext.Provider value={{ schema, onRemove }}>
 | 
			
		||||
      <DndContext
 | 
			
		||||
@ -193,6 +208,7 @@ export const Menu: any = observer((props: any) => {
 | 
			
		||||
        )}
 | 
			
		||||
        <MenuModeContext.Provider value={mode}>
 | 
			
		||||
          <AntdMenu
 | 
			
		||||
            defaultOpenKeys={defaultSelectedKeys}
 | 
			
		||||
            defaultSelectedKeys={defaultSelectedKeys}
 | 
			
		||||
            {...others}
 | 
			
		||||
            mode={mode === 'mix' ? 'horizontal' : mode}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user