fix: menu item highlight
This commit is contained in:
parent
b7be09efd7
commit
9560276fa1
@ -45,6 +45,7 @@ import {
|
|||||||
} from './SiteTitle';
|
} from './SiteTitle';
|
||||||
import { AuthProvider } from './Auth';
|
import { AuthProvider } from './Auth';
|
||||||
import { Helmet } from 'react-helmet';
|
import { Helmet } from 'react-helmet';
|
||||||
|
import { MenuSelectedKeysContext } from '../../schemas/menu';
|
||||||
|
|
||||||
function DesignableToggle() {
|
function DesignableToggle() {
|
||||||
const { designable, setDesignable } = useDesignableSwitchContext();
|
const { designable, setDesignable } = useDesignableSwitchContext();
|
||||||
@ -77,17 +78,58 @@ function LayoutWithMenu(props: LayoutWithMenuProps) {
|
|||||||
const { title } = useSystemSettings();
|
const { title } = useSystemSettings();
|
||||||
const [activeKey, setActiveKey] = useState(match.params.name);
|
const [activeKey, setActiveKey] = useState(match.params.name);
|
||||||
const { setPageTitle } = usePageTitleContext();
|
const { setPageTitle } = usePageTitleContext();
|
||||||
|
|
||||||
|
const [selectedKeys, setSelectedKeys] = useState(defaultSelectedKeys);
|
||||||
const onSelect = (info) => {
|
const onSelect = (info) => {
|
||||||
if (!info.schema) {
|
if (!info.schema) {
|
||||||
setActiveKey(null);
|
setActiveKey(null);
|
||||||
} else if (info.schema['x-component'] === 'Menu.SubMenu') {
|
} 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 {
|
} else {
|
||||||
setActiveKey(info.schema.key);
|
setActiveKey(info.schema.key);
|
||||||
history.push(`/admin/${info.schema.key}`);
|
history.push(`/admin/${info.schema.key}`);
|
||||||
if (info.schema.title) {
|
if (info.schema.title) {
|
||||||
setPageTitle(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 = () => {
|
const onMenuItemRemove = () => {
|
||||||
history.push(`/admin`);
|
history.push(`/admin`);
|
||||||
};
|
};
|
||||||
console.log({ activeKey });
|
console.log({ activeKey, selectedKeys });
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<Layout.Header className={'site-header'} style={{ display: 'flex' }}>
|
<Layout.Header className={'site-header'} style={{ display: 'flex' }}>
|
||||||
<SiteTitle />
|
<SiteTitle />
|
||||||
|
<MenuSelectedKeysContext.Provider value={selectedKeys}>
|
||||||
<SchemaRenderer
|
<SchemaRenderer
|
||||||
schema={schema}
|
schema={schema}
|
||||||
scope={{
|
scope={{
|
||||||
sideMenuRef,
|
sideMenuRef,
|
||||||
onSelect,
|
onSelect,
|
||||||
onMenuItemRemove,
|
onMenuItemRemove,
|
||||||
selectedKeys: defaultSelectedKeys.filter(Boolean),
|
getSelectedKeys: () => {
|
||||||
|
console.log('getSelectedKeys', schema);
|
||||||
|
return selectedKeys.filter(Boolean);
|
||||||
|
},
|
||||||
|
selectedKeys: selectedKeys.filter(Boolean),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</MenuSelectedKeysContext.Provider>
|
||||||
<DesignableToggle />
|
<DesignableToggle />
|
||||||
<Database />
|
<Database />
|
||||||
<Permissions />
|
<Permissions />
|
||||||
|
@ -50,6 +50,14 @@ export const linkTo: FieldOptions = {
|
|||||||
'x-decorator': 'FormItem',
|
'x-decorator': 'FormItem',
|
||||||
'x-component': 'Select',
|
'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': {
|
'uiSchema.x-component-props.multiple': {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
'x-content': '允许关联多条记录',
|
'x-content': '允许关联多条记录',
|
||||||
|
@ -82,6 +82,10 @@ export const MenuContext = createContext<MenuContextProps>(null);
|
|||||||
const SideMenu = (props: any) => {
|
const SideMenu = (props: any) => {
|
||||||
const { selectedKey, defaultSelectedKeys, onSelect, path } = props;
|
const { selectedKey, defaultSelectedKeys, onSelect, path } = props;
|
||||||
const { schema } = useDesignable();
|
const { schema } = useDesignable();
|
||||||
|
const [selectedKeys, setSelectedKeys] = useState(defaultSelectedKeys);
|
||||||
|
useEffect(() => {
|
||||||
|
setSelectedKeys(defaultSelectedKeys);
|
||||||
|
}, [defaultSelectedKeys]);
|
||||||
if (!selectedKey) {
|
if (!selectedKey) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -89,10 +93,17 @@ const SideMenu = (props: any) => {
|
|||||||
if (!child || child['x-component'] !== 'Menu.SubMenu') {
|
if (!child || child['x-component'] !== 'Menu.SubMenu') {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MenuModeContext.Provider value={'inline'}>
|
<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 />
|
<RecursionField schema={child} onlyRenderProperties />
|
||||||
<Menu.AddNew key={uid()} path={[...path, selectedKey]}>
|
<Menu.AddNew key={uid()} path={[...path, selectedKey]}>
|
||||||
<Button
|
<Button
|
||||||
@ -109,15 +120,19 @@ const SideMenu = (props: any) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const MenuSelectedKeysContext = createContext<any>([]);
|
||||||
|
|
||||||
export const Menu: any = observer((props: any) => {
|
export const Menu: any = observer((props: any) => {
|
||||||
const {
|
const {
|
||||||
mode,
|
mode,
|
||||||
onSelect,
|
onSelect,
|
||||||
sideMenuRef,
|
sideMenuRef,
|
||||||
defaultSelectedKeys = [],
|
defaultSelectedKeys: keys,
|
||||||
|
getSelectedKeys,
|
||||||
onRemove,
|
onRemove,
|
||||||
...others
|
...others
|
||||||
} = props;
|
} = props;
|
||||||
|
const defaultSelectedKeys = useContext(MenuSelectedKeysContext);
|
||||||
const { root, schema, insertAfter, remove } = useDesignable();
|
const { root, schema, insertAfter, remove } = useDesignable();
|
||||||
const moveToAfter = (path1, path2) => {
|
const moveToAfter = (path1, path2) => {
|
||||||
if (!path1 || !path2) {
|
if (!path1 || !path2) {
|
||||||
@ -163,7 +178,7 @@ export const Menu: any = observer((props: any) => {
|
|||||||
}, [selectedKey]);
|
}, [selectedKey]);
|
||||||
|
|
||||||
const [dragOverlayContent, setDragOverlayContent] = useState('');
|
const [dragOverlayContent, setDragOverlayContent] = useState('');
|
||||||
console.log('onRemove', onRemove);
|
// console.log('defaultSelectedKeys', defaultSelectedKeys, getSelectedKeys);
|
||||||
return (
|
return (
|
||||||
<MenuContext.Provider value={{ schema, onRemove }}>
|
<MenuContext.Provider value={{ schema, onRemove }}>
|
||||||
<DndContext
|
<DndContext
|
||||||
@ -193,6 +208,7 @@ export const Menu: any = observer((props: any) => {
|
|||||||
)}
|
)}
|
||||||
<MenuModeContext.Provider value={mode}>
|
<MenuModeContext.Provider value={mode}>
|
||||||
<AntdMenu
|
<AntdMenu
|
||||||
|
defaultOpenKeys={defaultSelectedKeys}
|
||||||
defaultSelectedKeys={defaultSelectedKeys}
|
defaultSelectedKeys={defaultSelectedKeys}
|
||||||
{...others}
|
{...others}
|
||||||
mode={mode === 'mix' ? 'horizontal' : mode}
|
mode={mode === 'mix' ? 'horizontal' : mode}
|
||||||
|
Loading…
Reference in New Issue
Block a user