updates
This commit is contained in:
		
							parent
							
								
									e53a1edf7d
								
							
						
					
					
						commit
						708afa059c
					
				@ -1,7 +1,7 @@
 | 
				
			|||||||
export default {
 | 
					export default {
 | 
				
			||||||
  type: 'object',
 | 
					  type: 'object',
 | 
				
			||||||
  properties: {
 | 
					  properties: {
 | 
				
			||||||
    input: {
 | 
					    email: {
 | 
				
			||||||
      type: 'string',
 | 
					      type: 'string',
 | 
				
			||||||
      required: true,
 | 
					      required: true,
 | 
				
			||||||
      'x-decorator': 'FormItem',
 | 
					      'x-decorator': 'FormItem',
 | 
				
			||||||
@ -13,7 +13,7 @@ export default {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    textarea: {
 | 
					    password: {
 | 
				
			||||||
      type: 'string',
 | 
					      type: 'string',
 | 
				
			||||||
      required: true,
 | 
					      required: true,
 | 
				
			||||||
      'x-decorator': 'FormItem',
 | 
					      'x-decorator': 'FormItem',
 | 
				
			||||||
@ -27,7 +27,6 @@ export default {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    actions: {
 | 
					    actions: {
 | 
				
			||||||
      type: 'void',
 | 
					      type: 'void',
 | 
				
			||||||
      // 'x-decorator': 'Div',
 | 
					 | 
				
			||||||
      'x-component': 'Div',
 | 
					      'x-component': 'Div',
 | 
				
			||||||
      properties: {
 | 
					      properties: {
 | 
				
			||||||
        submit: {
 | 
					        submit: {
 | 
				
			||||||
 | 
				
			|||||||
@ -2,15 +2,18 @@ import { uid } from '@formily/shared';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  type: 'void',
 | 
					  type: 'void',
 | 
				
			||||||
  name: `m_${uid()}`,
 | 
					  name: `menu_${uid()}`,
 | 
				
			||||||
  'x-component': 'Menu',
 | 
					  'x-component': 'Menu',
 | 
				
			||||||
  'x-designable-bar': 'Menu.DesignableBar',
 | 
					  'x-designable-bar': 'Menu.DesignableBar',
 | 
				
			||||||
  'x-component-props': {
 | 
					  'x-component-props': {
 | 
				
			||||||
    mode: 'mix',
 | 
					    mode: 'mix',
 | 
				
			||||||
    theme: 'dark',
 | 
					    theme: 'dark',
 | 
				
			||||||
 | 
					    defaultSelectedKeys: '{{ selectedKeys }}',
 | 
				
			||||||
 | 
					    sideMenuRef: '{{ sideMenuRef }}',
 | 
				
			||||||
 | 
					    onSelect: '{{ onSelect }}',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  properties: {
 | 
					  properties: {
 | 
				
			||||||
    item2: {
 | 
					    [uid()]: {
 | 
				
			||||||
      type: 'void',
 | 
					      type: 'void',
 | 
				
			||||||
      title: `菜单2`,
 | 
					      title: `菜单2`,
 | 
				
			||||||
      'x-component': 'Menu.Link',
 | 
					      'x-component': 'Menu.Link',
 | 
				
			||||||
@ -18,7 +21,7 @@ export default {
 | 
				
			|||||||
        icon: 'MailOutlined',
 | 
					        icon: 'MailOutlined',
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    item22: {
 | 
					    [uid()]: {
 | 
				
			||||||
      type: 'void',
 | 
					      type: 'void',
 | 
				
			||||||
      title: `菜单22`,
 | 
					      title: `菜单22`,
 | 
				
			||||||
      'x-component': 'Menu.Link',
 | 
					      'x-component': 'Menu.Link',
 | 
				
			||||||
@ -27,15 +30,23 @@ export default {
 | 
				
			|||||||
        // url: 'https://www.google.com',
 | 
					        // url: 'https://www.google.com',
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    item3: {
 | 
					    [uid()]: {
 | 
				
			||||||
      type: 'void',
 | 
					      type: 'void',
 | 
				
			||||||
      title: '菜单组',
 | 
					      title: '菜单组1',
 | 
				
			||||||
 | 
					      'x-component': 'Menu.SubMenu',
 | 
				
			||||||
 | 
					      'x-component-props': {
 | 
				
			||||||
 | 
					        icon: 'SettingOutlined',
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    [uid()]: {
 | 
				
			||||||
 | 
					      type: 'void',
 | 
				
			||||||
 | 
					      title: '菜单组2',
 | 
				
			||||||
      'x-component': 'Menu.SubMenu',
 | 
					      'x-component': 'Menu.SubMenu',
 | 
				
			||||||
      'x-component-props': {
 | 
					      'x-component-props': {
 | 
				
			||||||
        icon: 'SettingOutlined',
 | 
					        icon: 'SettingOutlined',
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      properties: {
 | 
					      properties: {
 | 
				
			||||||
        item6: {
 | 
					        [uid()]: {
 | 
				
			||||||
          type: 'void',
 | 
					          type: 'void',
 | 
				
			||||||
          title: '菜单6',
 | 
					          title: '菜单6',
 | 
				
			||||||
          'x-component': 'Menu.SubMenu',
 | 
					          'x-component': 'Menu.SubMenu',
 | 
				
			||||||
@ -43,55 +54,48 @@ export default {
 | 
				
			|||||||
            icon: 'AppstoreOutlined',
 | 
					            icon: 'AppstoreOutlined',
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          properties: {
 | 
					          properties: {
 | 
				
			||||||
            item9: {
 | 
					            [uid()]: {
 | 
				
			||||||
              type: 'void',
 | 
					              type: 'void',
 | 
				
			||||||
              title: '菜单9',
 | 
					              title: '菜单9',
 | 
				
			||||||
              'x-component': 'Menu.SubMenu',
 | 
					              'x-component': 'Menu.SubMenu',
 | 
				
			||||||
              properties: {
 | 
					              properties: {
 | 
				
			||||||
                item10: {
 | 
					                [uid()]: {
 | 
				
			||||||
                  type: 'void',
 | 
					                  type: 'void',
 | 
				
			||||||
                  title: `子菜单10`,
 | 
					                  title: `子菜单10`,
 | 
				
			||||||
                  'x-component': 'Menu.Link',
 | 
					                  'x-component': 'Menu.Link',
 | 
				
			||||||
                  // properties: {
 | 
					 | 
				
			||||||
                  //   action1: {
 | 
					 | 
				
			||||||
                  //     type: 'void',
 | 
					 | 
				
			||||||
                  //     title: '页面标题2',
 | 
					 | 
				
			||||||
                  //     'x-component': 'Action.Page',
 | 
					 | 
				
			||||||
                  //   },
 | 
					 | 
				
			||||||
                  // },
 | 
					 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                item11: {
 | 
					                [uid()]: {
 | 
				
			||||||
                  type: 'void',
 | 
					                  type: 'void',
 | 
				
			||||||
                  title: `子菜单11`,
 | 
					                  title: `子菜单11`,
 | 
				
			||||||
                  'x-component': 'Menu.Link',
 | 
					                  'x-component': 'Menu.Link',
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            item7: {
 | 
					            [uid()]: {
 | 
				
			||||||
              type: 'void',
 | 
					              type: 'void',
 | 
				
			||||||
              title: `子菜单7`,
 | 
					              title: `子菜单7`,
 | 
				
			||||||
              'x-component': 'Menu.Link',
 | 
					              'x-component': 'Menu.Link',
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            item8: {
 | 
					            [uid()]: {
 | 
				
			||||||
              type: 'void',
 | 
					              type: 'void',
 | 
				
			||||||
              title: `子菜单8`,
 | 
					              title: `子菜单8`,
 | 
				
			||||||
              'x-component': 'Menu.Link',
 | 
					              'x-component': 'Menu.Link',
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        item4: {
 | 
					        [uid()]: {
 | 
				
			||||||
          type: 'void',
 | 
					          type: 'void',
 | 
				
			||||||
          title: `子菜单1`,
 | 
					          title: `子菜单1`,
 | 
				
			||||||
          'x-component': 'Menu.Link',
 | 
					          'x-component': 'Menu.Link',
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        item5: {
 | 
					        [uid()]: {
 | 
				
			||||||
          type: 'void',
 | 
					          type: 'void',
 | 
				
			||||||
          title: `子菜单2`,
 | 
					          title: `子菜单2`,
 | 
				
			||||||
          'x-component': 'Menu.Link',
 | 
					          'x-component': 'Menu.Link',
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    item1: {
 | 
					    [uid()]: {
 | 
				
			||||||
      type: 'void',
 | 
					      type: 'void',
 | 
				
			||||||
      title: `菜单1`,
 | 
					      title: `菜单1`,
 | 
				
			||||||
      'x-component': 'Menu.Link',
 | 
					      'x-component': 'Menu.Link',
 | 
				
			||||||
 | 
				
			|||||||
@ -15,6 +15,7 @@ import {
 | 
				
			|||||||
  FormProvider,
 | 
					  FormProvider,
 | 
				
			||||||
  useField,
 | 
					  useField,
 | 
				
			||||||
  useFieldSchema,
 | 
					  useFieldSchema,
 | 
				
			||||||
 | 
					  useForm,
 | 
				
			||||||
} from '@formily/react';
 | 
					} from '@formily/react';
 | 
				
			||||||
import { observable } from '@formily/reactive';
 | 
					import { observable } from '@formily/reactive';
 | 
				
			||||||
import { uid, clone } from '@formily/shared';
 | 
					import { uid, clone } from '@formily/shared';
 | 
				
			||||||
@ -304,8 +305,7 @@ export function useDesignable(path?: any) {
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function useSchemaPath() {
 | 
					export function getSchemaPath(schema: Schema) {
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					 | 
				
			||||||
  const path = [schema.name];
 | 
					  const path = [schema.name];
 | 
				
			||||||
  let parent = schema.parent;
 | 
					  let parent = schema.parent;
 | 
				
			||||||
  while (parent) {
 | 
					  while (parent) {
 | 
				
			||||||
@ -315,7 +315,13 @@ export function useSchemaPath() {
 | 
				
			|||||||
    path.unshift(parent.name);
 | 
					    path.unshift(parent.name);
 | 
				
			||||||
    parent = parent.parent;
 | 
					    parent = parent.parent;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  console.log('useSchemaPath', path, schema);
 | 
					  console.log('getSchemaPath', path, schema);
 | 
				
			||||||
 | 
					  return [...path];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function useSchemaPath() {
 | 
				
			||||||
 | 
					  const schema = useFieldSchema();
 | 
				
			||||||
 | 
					  const path = getSchemaPath(schema);
 | 
				
			||||||
  return [...path];
 | 
					  return [...path];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -325,6 +331,7 @@ export const createDesignableSchemaField = (options) => {
 | 
				
			|||||||
  const SchemaField = createSchemaField(options);
 | 
					  const SchemaField = createSchemaField(options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const DesignableSchemaField = (props) => {
 | 
					  const DesignableSchemaField = (props) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const schema = useMemo(() => new Schema(props.schema), [props.schema]);
 | 
					    const schema = useMemo(() => new Schema(props.schema), [props.schema]);
 | 
				
			||||||
    const [, refresh] = useState(0);
 | 
					    const [, refresh] = useState(0);
 | 
				
			||||||
    if (props.designable === false) {
 | 
					    if (props.designable === false) {
 | 
				
			||||||
@ -340,8 +347,9 @@ export const createDesignableSchemaField = (options) => {
 | 
				
			|||||||
          },
 | 
					          },
 | 
				
			||||||
        }}
 | 
					        }}
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        <SchemaField schema={schema} />
 | 
					        <SchemaField scope={props.scope} components={props.components} schema={schema} />
 | 
				
			||||||
        <CodePreview schema={schema} />
 | 
					        <CodePreview schema={schema} />
 | 
				
			||||||
 | 
					        <FormValues />
 | 
				
			||||||
      </DesignableContext.Provider>
 | 
					      </DesignableContext.Provider>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
@ -349,11 +357,34 @@ export const createDesignableSchemaField = (options) => {
 | 
				
			|||||||
  return DesignableSchemaField;
 | 
					  return DesignableSchemaField;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const CodePreview = ({ schema }) => {
 | 
					const FormValues = () => {
 | 
				
			||||||
 | 
					  const form = useForm();
 | 
				
			||||||
  const [visible, setVisible] = useState(false);
 | 
					  const [visible, setVisible] = useState(false);
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <>
 | 
					    <>
 | 
				
			||||||
      <CodeOutlined onClick={() => setVisible(true)} />
 | 
					      <CodeOutlined onClick={() => setVisible(true)} />
 | 
				
			||||||
 | 
					      <Modal
 | 
				
			||||||
 | 
					        width={'50%'}
 | 
				
			||||||
 | 
					        onOk={() => setVisible(false)}
 | 
				
			||||||
 | 
					        onCancel={() => setVisible(false)}
 | 
				
			||||||
 | 
					        visible={visible}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <Editor
 | 
				
			||||||
 | 
					          height="60vh"
 | 
				
			||||||
 | 
					          defaultLanguage="json"
 | 
				
			||||||
 | 
					          value={JSON.stringify(form.values, null, 2)}
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					        {/* <pre>{JSON.stringify(schema.toJSON(), null, 2)}</pre> */}
 | 
				
			||||||
 | 
					      </Modal>
 | 
				
			||||||
 | 
					    </>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const CodePreview = ({ schema }) => {
 | 
				
			||||||
 | 
					  const [visible, setVisible] = useState(false);
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <>
 | 
				
			||||||
 | 
					      <CodeOutlined style={{position: 'relative', zIndex: 100}} onClick={() => setVisible(true)} />
 | 
				
			||||||
      <Modal
 | 
					      <Modal
 | 
				
			||||||
        width={'50%'}
 | 
					        width={'50%'}
 | 
				
			||||||
        onOk={() => setVisible(false)}
 | 
					        onOk={() => setVisible(false)}
 | 
				
			||||||
@ -387,6 +418,8 @@ export interface SchemaRendererProps {
 | 
				
			|||||||
  designable?: boolean;
 | 
					  designable?: boolean;
 | 
				
			||||||
  onRefresh?: any;
 | 
					  onRefresh?: any;
 | 
				
			||||||
  onlyRenderProperties?: boolean;
 | 
					  onlyRenderProperties?: boolean;
 | 
				
			||||||
 | 
					  scope?: any;
 | 
				
			||||||
 | 
					  components?: any;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SchemaRenderer = (props: SchemaRendererProps) => {
 | 
					export const SchemaRenderer = (props: SchemaRendererProps) => {
 | 
				
			||||||
@ -415,6 +448,8 @@ export const SchemaRenderer = (props: SchemaRendererProps) => {
 | 
				
			|||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <FormProvider form={form}>
 | 
					    <FormProvider form={form}>
 | 
				
			||||||
      <DesignableSchemaField
 | 
					      <DesignableSchemaField
 | 
				
			||||||
 | 
					        scope={props.scope}
 | 
				
			||||||
 | 
					        components={props.components}
 | 
				
			||||||
        onRefresh={props.onRefresh}
 | 
					        onRefresh={props.onRefresh}
 | 
				
			||||||
        designable={props.designable}
 | 
					        designable={props.designable}
 | 
				
			||||||
        schema={schema}
 | 
					        schema={schema}
 | 
				
			||||||
 | 
				
			|||||||
@ -13,11 +13,13 @@ group:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
操作有三类:
 | 
					操作有三类:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- 常规操作
 | 
					- 常规操作:Action
 | 
				
			||||||
- 弹出层操作,弹出层有 Drawer、Modal、Popover
 | 
					- 弹出层操作,弹出层可以是 Action.Drawer、Action.Modal、Action.Popover
 | 
				
			||||||
- 指定容器内操作 Container
 | 
					- 指定容器内打开: Action.Container
 | 
				
			||||||
- 下拉菜单,用于收纳多种操作
 | 
					- 下拉菜单:Action.Dropdown,用于收纳多种操作
 | 
				
			||||||
- 跳转操作
 | 
					- 跳转操作:Action.Link、Action.URL 和 Action.Route
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Action.Drawer、Action.Modal、Action.Popover 和 Action.Container 需要和 Action 搭配使用
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Action - 常规操作
 | 
					## Action - 常规操作
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -106,12 +106,18 @@ const [VisibleProvider, useVisibleContext] = constate((props: any = {}) => {
 | 
				
			|||||||
export { VisibleProvider, useVisibleContext };
 | 
					export { VisibleProvider, useVisibleContext };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const BaseAction = observer((props: any) => {
 | 
					const BaseAction = observer((props: any) => {
 | 
				
			||||||
  const { useAction = useDefaultAction, ...others } = props;
 | 
					  const {
 | 
				
			||||||
 | 
					    ButtonComponent = Button,
 | 
				
			||||||
 | 
					    className,
 | 
				
			||||||
 | 
					    useAction = useDefaultAction,
 | 
				
			||||||
 | 
					    ...others
 | 
				
			||||||
 | 
					  } = props;
 | 
				
			||||||
  const field = useField();
 | 
					  const field = useField();
 | 
				
			||||||
  const { run } = useAction();
 | 
					  const { run } = useAction();
 | 
				
			||||||
  const { DesignableBar } = useDesignableBar();
 | 
					  const { DesignableBar } = useDesignableBar();
 | 
				
			||||||
  const { setVisible } = useVisibleContext();
 | 
					  const { setVisible } = useVisibleContext();
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					  // const schema = useFieldSchema();
 | 
				
			||||||
 | 
					  const { schema } = useDesignable();
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
    field.componentProps.setVisible = setVisible;
 | 
					    field.componentProps.setVisible = setVisible;
 | 
				
			||||||
  }, []);
 | 
					  }, []);
 | 
				
			||||||
@ -119,17 +125,18 @@ const BaseAction = observer((props: any) => {
 | 
				
			|||||||
  console.log('BaseAction', { field, schema }, field.title);
 | 
					  console.log('BaseAction', { field, schema }, field.title);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const renderButton = () => (
 | 
					  const renderButton = () => (
 | 
				
			||||||
    <Button
 | 
					    <ButtonComponent
 | 
				
			||||||
      {...others}
 | 
					      {...others}
 | 
				
			||||||
 | 
					      className={classNames(className, `name-${schema.name}`)}
 | 
				
			||||||
      onClick={async (e) => {
 | 
					      onClick={async (e) => {
 | 
				
			||||||
        e.stopPropagation();
 | 
					        e.stopPropagation && e.stopPropagation();
 | 
				
			||||||
        setVisible && setVisible(true);
 | 
					        setVisible && setVisible(true);
 | 
				
			||||||
        await run();
 | 
					        await run();
 | 
				
			||||||
      }}
 | 
					      }}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      {field.title}
 | 
					      {schema.title}
 | 
				
			||||||
      <DesignableBar />
 | 
					      <DesignableBar />
 | 
				
			||||||
    </Button>
 | 
					    </ButtonComponent>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const popover = schema.reduceProperties((items, current) => {
 | 
					  const popover = schema.reduceProperties((items, current) => {
 | 
				
			||||||
@ -268,6 +275,7 @@ Action.Dropdown = observer((props) => {
 | 
				
			|||||||
  // const { visible, setVisible } = useVisibleContext();
 | 
					  // const { visible, setVisible } = useVisibleContext();
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					  const schema = useFieldSchema();
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
 | 
					    <>
 | 
				
			||||||
    <Popover
 | 
					    <Popover
 | 
				
			||||||
      // visible={visible}
 | 
					      // visible={visible}
 | 
				
			||||||
      // onVisibleChange={(visible) => {
 | 
					      // onVisibleChange={(visible) => {
 | 
				
			||||||
@ -281,13 +289,16 @@ Action.Dropdown = observer((props) => {
 | 
				
			|||||||
    >
 | 
					    >
 | 
				
			||||||
      <Button>{schema.title}</Button>
 | 
					      <Button>{schema.title}</Button>
 | 
				
			||||||
    </Popover>
 | 
					    </Popover>
 | 
				
			||||||
 | 
					    {/* popover 的按钮初始化时并未渲染,暂时先这么处理 */}
 | 
				
			||||||
 | 
					    <div style={{display: 'none'}}>{props.children}</div>
 | 
				
			||||||
 | 
					    </>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Action.DesignableBar = () => {
 | 
					Action.DesignableBar = () => {
 | 
				
			||||||
  const field = useField();
 | 
					  const field = useField();
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					  // const schema = useFieldSchema();
 | 
				
			||||||
  const { insertAfter } = useDesignable();
 | 
					  const { schema, insertAfter } = useDesignable();
 | 
				
			||||||
  const [visible, setVisible] = useState(false);
 | 
					  const [visible, setVisible] = useState(false);
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div className={classNames('designable-bar', { active: visible })}>
 | 
					    <div className={classNames('designable-bar', { active: visible })}>
 | 
				
			||||||
 | 
				
			|||||||
@ -186,10 +186,15 @@ import { MenuContainerContext } from './';
 | 
				
			|||||||
import { Layout } from 'antd';
 | 
					import { Layout } from 'antd';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default () => {
 | 
					export default () => {
 | 
				
			||||||
  const ref = useRef();
 | 
					  const sideMenuRef = useRef();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const [activeKey, setActiveKey] = useState('item3');
 | 
					  const [activeKey, setActiveKey] = useState('item3');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const onSelect = (info) => {
 | 
				
			||||||
 | 
					    setActiveKey(info.key);
 | 
				
			||||||
 | 
					    console.log({ info })
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const schema = {
 | 
					  const schema = {
 | 
				
			||||||
    type: 'object',
 | 
					    type: 'object',
 | 
				
			||||||
    properties: {
 | 
					    properties: {
 | 
				
			||||||
@ -197,13 +202,11 @@ export default () => {
 | 
				
			|||||||
        type: 'void',
 | 
					        type: 'void',
 | 
				
			||||||
        'x-component': 'Menu',
 | 
					        'x-component': 'Menu',
 | 
				
			||||||
        'x-component-props': {
 | 
					        'x-component-props': {
 | 
				
			||||||
 | 
					          sideMenuRef: '{{ sideMenuRef }}',
 | 
				
			||||||
          defaultSelectedKeys: [activeKey],
 | 
					          defaultSelectedKeys: [activeKey],
 | 
				
			||||||
          mode: 'mix',
 | 
					          mode: 'mix',
 | 
				
			||||||
          theme: 'dark',
 | 
					          theme: 'dark',
 | 
				
			||||||
          onSelect(info) {
 | 
					          onSelect: '{{ onSelect }}',
 | 
				
			||||||
            setActiveKey(info.key);
 | 
					 | 
				
			||||||
            console.log({ info })
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        properties: {
 | 
					        properties: {
 | 
				
			||||||
          item1: {
 | 
					          item1: {
 | 
				
			||||||
@ -271,14 +274,13 @@ export default () => {
 | 
				
			|||||||
    <div>
 | 
					    <div>
 | 
				
			||||||
      <Layout>
 | 
					      <Layout>
 | 
				
			||||||
        <Layout.Header>
 | 
					        <Layout.Header>
 | 
				
			||||||
          <MenuContainerContext.Provider value={{
 | 
					          <SchemaRenderer 
 | 
				
			||||||
            sideMenuRef: ref,
 | 
					            schema={schema}
 | 
				
			||||||
          }}>
 | 
					            scope={{ onSelect, sideMenuRef }}
 | 
				
			||||||
            <SchemaRenderer schema={schema} />
 | 
					          />
 | 
				
			||||||
          </MenuContainerContext.Provider>
 | 
					 | 
				
			||||||
        </Layout.Header>
 | 
					        </Layout.Header>
 | 
				
			||||||
        <Layout>
 | 
					        <Layout>
 | 
				
			||||||
          <Layout.Sider ref={ref} theme={'light'} width={200}>
 | 
					          <Layout.Sider ref={sideMenuRef} theme={'light'} width={200}>
 | 
				
			||||||
          </Layout.Sider>
 | 
					          </Layout.Sider>
 | 
				
			||||||
          <Layout.Content>
 | 
					          <Layout.Content>
 | 
				
			||||||
            {activeKey}
 | 
					            {activeKey}
 | 
				
			||||||
@ -299,10 +301,15 @@ import { MenuContainerContext } from './';
 | 
				
			|||||||
import { Layout } from 'antd';
 | 
					import { Layout } from 'antd';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default () => {
 | 
					export default () => {
 | 
				
			||||||
  const ref = useRef();
 | 
					  const sideMenuRef = useRef();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const [activeKey, setActiveKey] = useState('item3');
 | 
					  const [activeKey, setActiveKey] = useState('item3');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const onSelect = (info) => {
 | 
				
			||||||
 | 
					    setActiveKey(info.key);
 | 
				
			||||||
 | 
					    console.log({ info })
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const schema = {
 | 
					  const schema = {
 | 
				
			||||||
    type: 'object',
 | 
					    type: 'object',
 | 
				
			||||||
    properties: {
 | 
					    properties: {
 | 
				
			||||||
@ -314,10 +321,8 @@ export default () => {
 | 
				
			|||||||
          defaultSelectedKeys: [activeKey],
 | 
					          defaultSelectedKeys: [activeKey],
 | 
				
			||||||
          mode: 'mix',
 | 
					          mode: 'mix',
 | 
				
			||||||
          theme: 'dark',
 | 
					          theme: 'dark',
 | 
				
			||||||
          onSelect(info) {
 | 
					          sideMenuRef: '{{ sideMenuRef }}',
 | 
				
			||||||
            setActiveKey(info.key);
 | 
					          onSelect: '{{ onSelect }}',
 | 
				
			||||||
            console.log({ info })
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        properties: {
 | 
					        properties: {
 | 
				
			||||||
          item1: {
 | 
					          item1: {
 | 
				
			||||||
@ -385,14 +390,17 @@ export default () => {
 | 
				
			|||||||
    <div>
 | 
					    <div>
 | 
				
			||||||
      <Layout>
 | 
					      <Layout>
 | 
				
			||||||
        <Layout.Header>
 | 
					        <Layout.Header>
 | 
				
			||||||
          <MenuContainerContext.Provider value={{
 | 
					          <SchemaRenderer
 | 
				
			||||||
            sideMenuRef: ref,
 | 
					            schema={schema}
 | 
				
			||||||
          }}>
 | 
					            scope={{ onSelect, sideMenuRef }}
 | 
				
			||||||
            <SchemaRenderer schema={schema} />
 | 
					          />
 | 
				
			||||||
          </MenuContainerContext.Provider>
 | 
					 | 
				
			||||||
        </Layout.Header>
 | 
					        </Layout.Header>
 | 
				
			||||||
        <Layout>
 | 
					        <Layout>
 | 
				
			||||||
          <Layout.Sider ref={ref} theme={'light'} width={200}>
 | 
					          <Layout.Sider 
 | 
				
			||||||
 | 
					            ref={sideMenuRef}
 | 
				
			||||||
 | 
					            theme={'light'}
 | 
				
			||||||
 | 
					            width={200}
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
          </Layout.Sider>
 | 
					          </Layout.Sider>
 | 
				
			||||||
          <Layout.Content>
 | 
					          <Layout.Content>
 | 
				
			||||||
            {activeKey}
 | 
					            {activeKey}
 | 
				
			||||||
@ -403,3 +411,82 @@ export default () => {
 | 
				
			|||||||
  )
 | 
					  )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Menu.Action
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```tsx
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * title: 横向菜单
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import { SchemaRenderer } from '../';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const schema = {
 | 
				
			||||||
 | 
					  type: 'object',
 | 
				
			||||||
 | 
					  properties: {
 | 
				
			||||||
 | 
					    menu1: {
 | 
				
			||||||
 | 
					      type: 'void',
 | 
				
			||||||
 | 
					      'x-component': 'Menu',
 | 
				
			||||||
 | 
					      'x-designable-bar': 'Menu.DesignableBar',
 | 
				
			||||||
 | 
					      'x-component-props': {
 | 
				
			||||||
 | 
					        mode: 'horizontal',
 | 
				
			||||||
 | 
					        theme: 'dark',
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      properties: {
 | 
				
			||||||
 | 
					        item1: {
 | 
				
			||||||
 | 
					          type: 'void',
 | 
				
			||||||
 | 
					          title: `菜单1`,
 | 
				
			||||||
 | 
					          'x-component': 'Menu.Item',
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        item2: {
 | 
				
			||||||
 | 
					          type: 'void',
 | 
				
			||||||
 | 
					          title: `菜单1`,
 | 
				
			||||||
 | 
					          'x-component': 'Menu.Action',
 | 
				
			||||||
 | 
					          properties: {
 | 
				
			||||||
 | 
					            drawer1: {
 | 
				
			||||||
 | 
					              type: 'void',
 | 
				
			||||||
 | 
					              title: '抽屉标题',
 | 
				
			||||||
 | 
					              'x-component': 'Action.Drawer',
 | 
				
			||||||
 | 
					              'x-component-props': {},
 | 
				
			||||||
 | 
					              properties: {
 | 
				
			||||||
 | 
					                input: {
 | 
				
			||||||
 | 
					                  type: 'string',
 | 
				
			||||||
 | 
					                  'x-decorator': 'FormItem',
 | 
				
			||||||
 | 
					                  'x-component': 'Input',
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                action2: {
 | 
				
			||||||
 | 
					                  type: 'void',
 | 
				
			||||||
 | 
					                  title: '打开二级抽屉',
 | 
				
			||||||
 | 
					                  // 'x-decorator': 'FormItem',
 | 
				
			||||||
 | 
					                  'x-component': 'Action',
 | 
				
			||||||
 | 
					                  properties: {
 | 
				
			||||||
 | 
					                    drawer1: {
 | 
				
			||||||
 | 
					                      type: 'void',
 | 
				
			||||||
 | 
					                      title: '二级抽屉标题',
 | 
				
			||||||
 | 
					                      'x-component': 'Action.Drawer',
 | 
				
			||||||
 | 
					                      'x-component-props': {},
 | 
				
			||||||
 | 
					                      properties: {
 | 
				
			||||||
 | 
					                        input: {
 | 
				
			||||||
 | 
					                          type: 'string',
 | 
				
			||||||
 | 
					                          'x-component': 'Input',
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                      },
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                  },
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default () => {
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <SchemaRenderer schema={schema} />
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
				
			|||||||
@ -51,10 +51,10 @@ import cls from 'classnames';
 | 
				
			|||||||
import ReactDOM from 'react-dom';
 | 
					import ReactDOM from 'react-dom';
 | 
				
			||||||
import { useMount } from 'ahooks';
 | 
					import { useMount } from 'ahooks';
 | 
				
			||||||
import { useDesignable, SchemaRenderer } from '..';
 | 
					import { useDesignable, SchemaRenderer } from '..';
 | 
				
			||||||
import { Router } from "react-router";
 | 
					import { Router } from 'react-router';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { useLifecycle } from 'beautiful-react-hooks';
 | 
					import { useLifecycle } from 'beautiful-react-hooks';
 | 
				
			||||||
import { useDefaultAction } from '../action';
 | 
					import { Action, useDefaultAction } from '../action';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type MenuType = React.FC<MenuProps & { hideSubMenu?: boolean }> & {
 | 
					export type MenuType = React.FC<MenuProps & { hideSubMenu?: boolean }> & {
 | 
				
			||||||
  Item?: React.FC<MenuItemProps>;
 | 
					  Item?: React.FC<MenuItemProps>;
 | 
				
			||||||
@ -63,6 +63,7 @@ export type MenuType = React.FC<MenuProps & { hideSubMenu?: boolean }> & {
 | 
				
			|||||||
  DesignableBar?: React.FC<any>;
 | 
					  DesignableBar?: React.FC<any>;
 | 
				
			||||||
  AddNew?: React.FC<any>;
 | 
					  AddNew?: React.FC<any>;
 | 
				
			||||||
  Link?: React.FC<MenuItemProps>;
 | 
					  Link?: React.FC<MenuItemProps>;
 | 
				
			||||||
 | 
					  Action?: React.FC<MenuItemProps>;
 | 
				
			||||||
  Url?: React.FC<MenuItemProps & { url: string }>;
 | 
					  Url?: React.FC<MenuItemProps & { url: string }>;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -92,9 +93,9 @@ function useDesignableBar() {
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Menu: MenuType = observer((props) => {
 | 
					export const Menu: MenuType = observer((props: any) => {
 | 
				
			||||||
  const { onSelect, mode, defaultSelectedKeys, ...others } = props;
 | 
					  const { sideMenuRef, onSelect, mode, defaultSelectedKeys, ...others } = props;
 | 
				
			||||||
  const { sideMenuRef } = useContext(MenuContainerContext);
 | 
					  let defaultSelectedKey = defaultSelectedKeys ? defaultSelectedKeys[0] : null;
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					  const schema = useFieldSchema();
 | 
				
			||||||
  const { schema: designableSchema, refresh } = useDesignable();
 | 
					  const { schema: designableSchema, refresh } = useDesignable();
 | 
				
			||||||
  const designableBar = schema['x-designable-bar'];
 | 
					  const designableBar = schema['x-designable-bar'];
 | 
				
			||||||
@ -109,33 +110,41 @@ export const Menu: MenuType = observer((props) => {
 | 
				
			|||||||
    if (!sideMenuRef || !sideMenuRef.current) {
 | 
					    if (!sideMenuRef || !sideMenuRef.current) {
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    const properties = schema.properties[selectedKey].properties;
 | 
					    const subSchema = schema.properties[selectedKey];
 | 
				
			||||||
    console.log({ selectedKey, properties });
 | 
					    if (!subSchema) {
 | 
				
			||||||
    sideMenuRef.current.style.display = properties ? 'block' : 'none';
 | 
					      sideMenuRef.current.style.display = 'none';
 | 
				
			||||||
 | 
					      ReactDOM.render(null, sideMenuRef.current);
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (subSchema['x-component'] !== 'Menu.SubMenu') {
 | 
				
			||||||
 | 
					      sideMenuRef.current.style.display = 'none';
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const properties = subSchema.properties || {};
 | 
				
			||||||
 | 
					    sideMenuRef.current.style.display = 'block';
 | 
				
			||||||
    const newProps = {};
 | 
					    const newProps = {};
 | 
				
			||||||
    Object.keys(properties || {}).forEach((name) => {
 | 
					    Object.keys(properties || {}).forEach((name) => {
 | 
				
			||||||
      newProps[name] = properties[name].toJSON();
 | 
					      newProps[name] = properties[name].toJSON();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    ReactDOM.render(
 | 
					    ReactDOM.render(
 | 
				
			||||||
      properties ? (
 | 
					 | 
				
			||||||
      <Router history={history}>
 | 
					      <Router history={history}>
 | 
				
			||||||
        <SchemaRenderer
 | 
					        <SchemaRenderer
 | 
				
			||||||
          key={`${Math.random()}`}
 | 
					          key={`${Math.random()}`}
 | 
				
			||||||
          onRefresh={(subSchema: Schema) => {
 | 
					          onRefresh={(subSchema: Schema) => {
 | 
				
			||||||
            const selected = designableSchema.properties[selectedKey];
 | 
					            const selected = designableSchema.properties[selectedKey];
 | 
				
			||||||
            const diff = subSchema.properties[`${schema.name}.${selectedKey}`];
 | 
					            const diff = subSchema.properties[`${schema.name}.${selectedKey}`];
 | 
				
			||||||
            Object.keys(selected.properties).forEach((name) => {
 | 
					            Object.keys(selected.properties || {}).forEach((name) => {
 | 
				
			||||||
              selected.properties[name].parent.removeProperty(name);
 | 
					              selected.properties[name].parent.removeProperty(name);
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            Object.keys(diff.properties).forEach((name) => {
 | 
					            Object.keys(diff.properties).forEach((name) => {
 | 
				
			||||||
              if (name.endsWith('-add-new')) {
 | 
					              if (name.endsWith('-add-new')) {
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
              console.log('diff', name)
 | 
					              console.log('diff', name);
 | 
				
			||||||
              const current = diff.properties[name];
 | 
					              const current = diff.properties[name];
 | 
				
			||||||
              selected.addProperty(current.name, current.toJSON());
 | 
					              selected.addProperty(current.name, current.toJSON());
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            console.log({selected })
 | 
					            console.log({ selected });
 | 
				
			||||||
            refresh();
 | 
					            refresh();
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
          schema={{
 | 
					          schema={{
 | 
				
			||||||
@ -155,15 +164,13 @@ export const Menu: MenuType = observer((props) => {
 | 
				
			|||||||
              },
 | 
					              },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
        /></Router>
 | 
					        />
 | 
				
			||||||
      ) : null,
 | 
					      </Router>,
 | 
				
			||||||
      sideMenuRef.current,
 | 
					      sideMenuRef.current,
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  useMount(() => {
 | 
					  useMount(() => {
 | 
				
			||||||
    const defaultSelectedKey = defaultSelectedKeys
 | 
					    console.log({ defaultSelectedKey }, schema.properties);
 | 
				
			||||||
      ? defaultSelectedKeys[0]
 | 
					 | 
				
			||||||
      : null;
 | 
					 | 
				
			||||||
    renderSideMenu(defaultSelectedKey);
 | 
					    renderSideMenu(defaultSelectedKey);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
@ -197,13 +204,16 @@ const AddNewAction = () => {
 | 
				
			|||||||
      trigger={['click']}
 | 
					      trigger={['click']}
 | 
				
			||||||
      overlay={
 | 
					      overlay={
 | 
				
			||||||
        <AntdMenu>
 | 
					        <AntdMenu>
 | 
				
			||||||
          <AntdMenu.Item onClick={() => {
 | 
					          <AntdMenu.Item
 | 
				
			||||||
 | 
					            onClick={() => {
 | 
				
			||||||
              insertBefore({
 | 
					              insertBefore({
 | 
				
			||||||
                type: 'void',
 | 
					                type: 'void',
 | 
				
			||||||
                title: uid(),
 | 
					                title: uid(),
 | 
				
			||||||
              "x-component": 'Menu.Item',
 | 
					                'x-component': 'Menu.Item',
 | 
				
			||||||
            })
 | 
					              });
 | 
				
			||||||
          }} style={{ minWidth: 150 }}>
 | 
					            }}
 | 
				
			||||||
 | 
					            style={{ minWidth: 150 }}
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
            <MenuOutlined /> 新建菜单
 | 
					            <MenuOutlined /> 新建菜单
 | 
				
			||||||
          </AntdMenu.Item>
 | 
					          </AntdMenu.Item>
 | 
				
			||||||
          <AntdMenu.Item>
 | 
					          <AntdMenu.Item>
 | 
				
			||||||
@ -298,6 +308,25 @@ Menu.Item = observer((props: any) => {
 | 
				
			|||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Menu.Action = observer((props: any) => {
 | 
				
			||||||
 | 
					  const { icon, ...others } = props;
 | 
				
			||||||
 | 
					  const schema = useFieldSchema();
 | 
				
			||||||
 | 
					  const { DesignableBar } = useDesignableBar();
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <Action
 | 
				
			||||||
 | 
					      // @ts-ignore
 | 
				
			||||||
 | 
					      eventKey={schema.name}
 | 
				
			||||||
 | 
					      key={schema.name}
 | 
				
			||||||
 | 
					      icon={icon ? <Icon type={icon as string} /> : undefined}
 | 
				
			||||||
 | 
					      ButtonComponent={AntdMenu.Item}
 | 
				
			||||||
 | 
					      {...others}
 | 
				
			||||||
 | 
					    />
 | 
				
			||||||
 | 
					    // <Action {...others}/>
 | 
				
			||||||
 | 
					    // <DesignableBar />
 | 
				
			||||||
 | 
					    // </AntdMenu.Item>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Menu.SubMenu = observer((props) => {
 | 
					Menu.SubMenu = observer((props) => {
 | 
				
			||||||
  const { DesignableBar } = useDesignableBar();
 | 
					  const { DesignableBar } = useDesignableBar();
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					  const schema = useFieldSchema();
 | 
				
			||||||
@ -372,11 +401,13 @@ Menu.DesignableBar = (props) => {
 | 
				
			|||||||
                  const title = uid();
 | 
					                  const title = uid();
 | 
				
			||||||
                  field.title = title;
 | 
					                  field.title = title;
 | 
				
			||||||
                  field.componentProps['icon'] = 'DeleteOutlined';
 | 
					                  field.componentProps['icon'] = 'DeleteOutlined';
 | 
				
			||||||
                  schema['x-component-props'] = schema['x-component-props'] || {};
 | 
					                  schema['x-component-props'] =
 | 
				
			||||||
 | 
					                    schema['x-component-props'] || {};
 | 
				
			||||||
                  schema['x-component-props']['icon'] = 'DeleteOutlined';
 | 
					                  schema['x-component-props']['icon'] = 'DeleteOutlined';
 | 
				
			||||||
                  schema.title = title;
 | 
					                  schema.title = title;
 | 
				
			||||||
                  fieldSchema.title = title;
 | 
					                  fieldSchema.title = title;
 | 
				
			||||||
                  fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
 | 
					                  fieldSchema['x-component-props'] =
 | 
				
			||||||
 | 
					                    fieldSchema['x-component-props'] || {};
 | 
				
			||||||
                  fieldSchema['x-component-props']['icon'] = 'DeleteOutlined';
 | 
					                  fieldSchema['x-component-props']['icon'] = 'DeleteOutlined';
 | 
				
			||||||
                  refresh();
 | 
					                  refresh();
 | 
				
			||||||
                }}
 | 
					                }}
 | 
				
			||||||
@ -396,6 +427,9 @@ Menu.DesignableBar = (props) => {
 | 
				
			|||||||
              >
 | 
					              >
 | 
				
			||||||
                <DeleteOutlined /> 删除菜单
 | 
					                <DeleteOutlined /> 删除菜单
 | 
				
			||||||
              </AntdMenu.Item>
 | 
					              </AntdMenu.Item>
 | 
				
			||||||
 | 
					              <AntdMenu.Item>
 | 
				
			||||||
 | 
					                <ModalButton />
 | 
				
			||||||
 | 
					              </AntdMenu.Item>
 | 
				
			||||||
            </AntdMenu>
 | 
					            </AntdMenu>
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
@ -406,4 +440,27 @@ Menu.DesignableBar = (props) => {
 | 
				
			|||||||
  );
 | 
					  );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function ModalButton() {
 | 
				
			||||||
 | 
					  const [visible, setVisible] = useState(false);
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <>
 | 
				
			||||||
 | 
					      <div
 | 
				
			||||||
 | 
					        onClick={() => {
 | 
				
			||||||
 | 
					          setVisible(true);
 | 
				
			||||||
 | 
					        }}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        按钮
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <Modal
 | 
				
			||||||
 | 
					        visible={visible}
 | 
				
			||||||
 | 
					        onCancel={() => {
 | 
				
			||||||
 | 
					          setVisible(false);
 | 
				
			||||||
 | 
					        }}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        aaa
 | 
				
			||||||
 | 
					      </Modal>
 | 
				
			||||||
 | 
					    </>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Menu;
 | 
					export default Menu;
 | 
				
			||||||
 | 
				
			|||||||
@ -35,10 +35,12 @@
 | 
				
			|||||||
    left: 0;
 | 
					    left: 0;
 | 
				
			||||||
    bottom: 0;
 | 
					    bottom: 0;
 | 
				
			||||||
    border: 2px solid #1890ff;
 | 
					    border: 2px solid #1890ff;
 | 
				
			||||||
 | 
					    pointer-events: none;
 | 
				
			||||||
    &.active {
 | 
					    &.active {
 | 
				
			||||||
      display: block;
 | 
					      display: block;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    .designable-bar-actions {
 | 
					    .designable-bar-actions {
 | 
				
			||||||
 | 
					      pointer-events: auto;
 | 
				
			||||||
      position: absolute;
 | 
					      position: absolute;
 | 
				
			||||||
      right: 0;
 | 
					      right: 0;
 | 
				
			||||||
      line-height: 1rem;
 | 
					      line-height: 1rem;
 | 
				
			||||||
@ -61,3 +63,15 @@
 | 
				
			|||||||
    border: 2px solid #1890ff;
 | 
					    border: 2px solid #1890ff;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.ant-menu-title-content {
 | 
				
			||||||
 | 
					  .ant-btn {
 | 
				
			||||||
 | 
					    background: none;
 | 
				
			||||||
 | 
					    border: 0;
 | 
				
			||||||
 | 
					    border-radius: 0;
 | 
				
			||||||
 | 
					    color: inherit;
 | 
				
			||||||
 | 
					    padding: 0 20px;
 | 
				
			||||||
 | 
					    height: 100%;
 | 
				
			||||||
 | 
					    margin: 0 -20px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -14,7 +14,7 @@ function useAction() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const schema = {
 | 
					const schema = {
 | 
				
			||||||
  name: `t_${uid()}`,
 | 
					  name: `table_${uid()}`,
 | 
				
			||||||
  type: 'array',
 | 
					  type: 'array',
 | 
				
			||||||
  'x-component': 'Table',
 | 
					  'x-component': 'Table',
 | 
				
			||||||
  // default: [
 | 
					  // default: [
 | 
				
			||||||
@ -36,7 +36,7 @@ const schema = {
 | 
				
			|||||||
    // isRemoteDataSource: true,
 | 
					    // isRemoteDataSource: true,
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  properties: {
 | 
					  properties: {
 | 
				
			||||||
    [`a_${uid()}`]: {
 | 
					    [`action_bar_${uid()}`]: {
 | 
				
			||||||
      type: 'void',
 | 
					      type: 'void',
 | 
				
			||||||
      'x-component': 'Table.ActionBar',
 | 
					      'x-component': 'Table.ActionBar',
 | 
				
			||||||
      properties: {
 | 
					      properties: {
 | 
				
			||||||
@ -132,22 +132,22 @@ const schema = {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    [`a_${uid()}`]: {
 | 
					    // [`a_${uid()}`]: {
 | 
				
			||||||
      type: 'void',
 | 
					    //   type: 'void',
 | 
				
			||||||
      'x-component': 'Table.ActionBar',
 | 
					    //   'x-component': 'Table.ActionBar',
 | 
				
			||||||
      'x-component-props': {
 | 
					    //   'x-component-props': {
 | 
				
			||||||
        align: 'bottom',
 | 
					    //     align: 'bottom',
 | 
				
			||||||
      },
 | 
					    //   },
 | 
				
			||||||
      properties: {
 | 
					    //   properties: {
 | 
				
			||||||
        pagination: {
 | 
					    //     pagination: {
 | 
				
			||||||
          type: 'void',
 | 
					    //       type: 'void',
 | 
				
			||||||
          'x-component': 'Table.Pagination',
 | 
					    //       'x-component': 'Table.Pagination',
 | 
				
			||||||
          'x-component-props': {
 | 
					    //       'x-component-props': {
 | 
				
			||||||
            defaultPageSize: 5,
 | 
					    //         defaultPageSize: 5,
 | 
				
			||||||
          },
 | 
					    //       },
 | 
				
			||||||
        },
 | 
					    //     },
 | 
				
			||||||
      },
 | 
					    //   },
 | 
				
			||||||
    },
 | 
					    // },
 | 
				
			||||||
    [`a_${uid()}`]: {
 | 
					    [`a_${uid()}`]: {
 | 
				
			||||||
      type: 'void',
 | 
					      type: 'void',
 | 
				
			||||||
      'x-component': 'Table.ActionBar',
 | 
					      'x-component': 'Table.ActionBar',
 | 
				
			||||||
@ -163,7 +163,7 @@ const schema = {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    [`c_${uid()}`]: {
 | 
					    [`column_${uid()}`]: {
 | 
				
			||||||
      type: 'void',
 | 
					      type: 'void',
 | 
				
			||||||
      title: '排序',
 | 
					      title: '排序',
 | 
				
			||||||
      'x-component': 'Table.Column',
 | 
					      'x-component': 'Table.Column',
 | 
				
			||||||
@ -174,7 +174,7 @@ const schema = {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    [`c_${uid()}`]: {
 | 
					    [`column_${uid()}`]: {
 | 
				
			||||||
      type: 'void',
 | 
					      type: 'void',
 | 
				
			||||||
      title: '序号',
 | 
					      title: '序号',
 | 
				
			||||||
      'x-component': 'Table.Column',
 | 
					      'x-component': 'Table.Column',
 | 
				
			||||||
@ -185,7 +185,7 @@ const schema = {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    [`c_${uid()}`]: {
 | 
					    [`column_${uid()}`]: {
 | 
				
			||||||
      type: 'void',
 | 
					      type: 'void',
 | 
				
			||||||
      title: '字段1',
 | 
					      title: '字段1',
 | 
				
			||||||
      'x-component': 'Table.Column',
 | 
					      'x-component': 'Table.Column',
 | 
				
			||||||
@ -197,7 +197,7 @@ const schema = {
 | 
				
			|||||||
        field1: {
 | 
					        field1: {
 | 
				
			||||||
          type: 'string',
 | 
					          type: 'string',
 | 
				
			||||||
          required: true,
 | 
					          required: true,
 | 
				
			||||||
          // 'x-read-pretty': true,
 | 
					          'x-read-pretty': true,
 | 
				
			||||||
          'x-decorator-props': {
 | 
					          'x-decorator-props': {
 | 
				
			||||||
            feedbackLayout: 'popover',
 | 
					            feedbackLayout: 'popover',
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
@ -206,16 +206,17 @@ const schema = {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    [`c_${uid()}`]: {
 | 
					    [`column_${uid()}`]: {
 | 
				
			||||||
      type: 'void',
 | 
					      type: 'void',
 | 
				
			||||||
      title: '字段2',
 | 
					      title: '字段2',
 | 
				
			||||||
      'x-component': 'Table.Column',
 | 
					      'x-component': 'Table.Column',
 | 
				
			||||||
 | 
					      'x-designable-bar': 'Table.Column.DesignableBar',
 | 
				
			||||||
      properties: {
 | 
					      properties: {
 | 
				
			||||||
        field2: {
 | 
					        field2: {
 | 
				
			||||||
          type: 'string',
 | 
					          type: 'string',
 | 
				
			||||||
          // title: '字段2',
 | 
					          // title: '字段2',
 | 
				
			||||||
          required: true,
 | 
					          required: true,
 | 
				
			||||||
          // 'x-read-pretty': true,
 | 
					          'x-read-pretty': true,
 | 
				
			||||||
          'x-decorator-props': {
 | 
					          'x-decorator-props': {
 | 
				
			||||||
            feedbackLayout: 'popover',
 | 
					            feedbackLayout: 'popover',
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
@ -224,18 +225,18 @@ const schema = {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    [`col_${uid()}`]: {
 | 
					    [`column_${uid()}`]: {
 | 
				
			||||||
      type: 'void',
 | 
					      type: 'void',
 | 
				
			||||||
      title: '操作',
 | 
					      title: '操作',
 | 
				
			||||||
      'x-component': 'Table.Column',
 | 
					      'x-component': 'Table.Column',
 | 
				
			||||||
      properties: {
 | 
					      properties: {
 | 
				
			||||||
        action1: {
 | 
					        [uid()]: {
 | 
				
			||||||
          type: 'void',
 | 
					          type: 'void',
 | 
				
			||||||
          name: 'action1',
 | 
					          name: 'action1',
 | 
				
			||||||
          title: '查看',
 | 
					          title: '查看',
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
          'x-component': 'Action',
 | 
					          'x-component': 'Action',
 | 
				
			||||||
          'x-default-action': true,
 | 
					          'x-designable-bar': 'Table.Action.DesignableBar',
 | 
				
			||||||
          'x-designable-bar': 'Action.DesignableBar',
 | 
					 | 
				
			||||||
          properties: {
 | 
					          properties: {
 | 
				
			||||||
            drawer1: {
 | 
					            drawer1: {
 | 
				
			||||||
              type: 'void',
 | 
					              type: 'void',
 | 
				
			||||||
@ -285,13 +286,12 @@ const schema = {
 | 
				
			|||||||
            },
 | 
					            },
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        action2: {
 | 
					        [uid()]: {
 | 
				
			||||||
          type: 'void',
 | 
					          type: 'void',
 | 
				
			||||||
          name: 'action1',
 | 
					          name: 'action1',
 | 
				
			||||||
          title: '修改',
 | 
					          title: '修改',
 | 
				
			||||||
          'x-component': 'Action',
 | 
					          'x-component': 'Action',
 | 
				
			||||||
          'x-default-action': true,
 | 
					          'x-designable-bar': 'Table.Action.DesignableBar',
 | 
				
			||||||
          'x-designable-bar': 'Action.DesignableBar',
 | 
					 | 
				
			||||||
          properties: {
 | 
					          properties: {
 | 
				
			||||||
            drawer1: {
 | 
					            drawer1: {
 | 
				
			||||||
              type: 'void',
 | 
					              type: 'void',
 | 
				
			||||||
@ -333,7 +333,7 @@ const schema = {
 | 
				
			|||||||
            },
 | 
					            },
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        action3: {
 | 
					        [uid()]: {
 | 
				
			||||||
          type: 'void',
 | 
					          type: 'void',
 | 
				
			||||||
          title: '删除',
 | 
					          title: '删除',
 | 
				
			||||||
          'x-component': 'Action',
 | 
					          'x-component': 'Action',
 | 
				
			||||||
@ -341,12 +341,12 @@ const schema = {
 | 
				
			|||||||
            useAction: '{{ useTableDestroyAction }}',
 | 
					            useAction: '{{ useTableDestroyAction }}',
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        action4: {
 | 
					        [uid()]: {
 | 
				
			||||||
          type: 'void',
 | 
					          type: 'void',
 | 
				
			||||||
          title: '...',
 | 
					          title: '...',
 | 
				
			||||||
          'x-component': 'Action.Dropdown',
 | 
					          'x-component': 'Action.Dropdown',
 | 
				
			||||||
          properties: {
 | 
					          properties: {
 | 
				
			||||||
            action5: {
 | 
					            [uid()]: {
 | 
				
			||||||
              type: 'void',
 | 
					              type: 'void',
 | 
				
			||||||
              title: '操作 1',
 | 
					              title: '操作 1',
 | 
				
			||||||
              'x-component': 'Action',
 | 
					              'x-component': 'Action',
 | 
				
			||||||
@ -355,21 +355,22 @@ const schema = {
 | 
				
			|||||||
                disabled: true,
 | 
					                disabled: true,
 | 
				
			||||||
              },
 | 
					              },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            action4: {
 | 
					            [uid()]: {
 | 
				
			||||||
              type: 'void',
 | 
					              type: 'void',
 | 
				
			||||||
              title: '操作 2',
 | 
					              title: '操作 2',
 | 
				
			||||||
              'x-component': 'Action',
 | 
					              'x-component': 'Action',
 | 
				
			||||||
 | 
					              'x-default-action': true,
 | 
				
			||||||
              'x-component-props': {
 | 
					              'x-component-props': {
 | 
				
			||||||
                useAction,
 | 
					                useAction,
 | 
				
			||||||
              },
 | 
					              },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            action1: {
 | 
					            [uid()]: {
 | 
				
			||||||
              type: 'void',
 | 
					              type: 'void',
 | 
				
			||||||
              name: 'action1',
 | 
					              name: 'action1',
 | 
				
			||||||
              title: '查看',
 | 
					              title: '查看',
 | 
				
			||||||
              'x-component': 'Action',
 | 
					              'x-component': 'Action',
 | 
				
			||||||
              // 'x-default-action': true,
 | 
					              // 'x-default-action': true,
 | 
				
			||||||
              'x-designable-bar': 'Action.DesignableBar',
 | 
					              'x-designable-bar': 'Table.Action.DesignableBar',
 | 
				
			||||||
              properties: {
 | 
					              properties: {
 | 
				
			||||||
                drawer1: {
 | 
					                drawer1: {
 | 
				
			||||||
                  type: 'void',
 | 
					                  type: 'void',
 | 
				
			||||||
@ -419,13 +420,12 @@ const schema = {
 | 
				
			|||||||
                },
 | 
					                },
 | 
				
			||||||
              },
 | 
					              },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            action2: {
 | 
					            [uid()]: {
 | 
				
			||||||
              type: 'void',
 | 
					              type: 'void',
 | 
				
			||||||
              name: 'action1',
 | 
					              name: 'action1',
 | 
				
			||||||
              title: '修改',
 | 
					              title: '修改',
 | 
				
			||||||
              'x-component': 'Action',
 | 
					              'x-component': 'Action',
 | 
				
			||||||
              'x-default-action': true,
 | 
					              'x-designable-bar': 'Table.Action.DesignableBar',
 | 
				
			||||||
              'x-designable-bar': 'Action.DesignableBar',
 | 
					 | 
				
			||||||
              properties: {
 | 
					              properties: {
 | 
				
			||||||
                drawer1: {
 | 
					                drawer1: {
 | 
				
			||||||
                  type: 'void',
 | 
					                  type: 'void',
 | 
				
			||||||
@ -467,7 +467,7 @@ const schema = {
 | 
				
			|||||||
                },
 | 
					                },
 | 
				
			||||||
              },
 | 
					              },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            action3: {
 | 
					            [uid()]: {
 | 
				
			||||||
              type: 'void',
 | 
					              type: 'void',
 | 
				
			||||||
              title: '删除',
 | 
					              title: '删除',
 | 
				
			||||||
              'x-component': 'Action',
 | 
					              'x-component': 'Action',
 | 
				
			||||||
@ -482,17 +482,14 @@ const schema = {
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const form = createForm();
 | 
					const form = createForm({
 | 
				
			||||||
 | 
					  // designable: true,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default observer(() => {
 | 
					export default observer(() => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div>
 | 
					    <div>
 | 
				
			||||||
      <SchemaRenderer form={form} schema={schema} />
 | 
					      <SchemaRenderer form={form} schema={schema} />
 | 
				
			||||||
      {/* <Editor
 | 
					 | 
				
			||||||
        height="200px"
 | 
					 | 
				
			||||||
        defaultLanguage="json"
 | 
					 | 
				
			||||||
        value={JSON.stringify(form.values, null, 2)}
 | 
					 | 
				
			||||||
      /> */}
 | 
					 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,7 @@ import {
 | 
				
			|||||||
  useForm,
 | 
					  useForm,
 | 
				
			||||||
  FormProvider,
 | 
					  FormProvider,
 | 
				
			||||||
  createSchemaField,
 | 
					  createSchemaField,
 | 
				
			||||||
 | 
					  SchemaOptionsContext,
 | 
				
			||||||
} from '@formily/react';
 | 
					} from '@formily/react';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  Button,
 | 
					  Button,
 | 
				
			||||||
@ -16,24 +17,32 @@ import {
 | 
				
			|||||||
  Space,
 | 
					  Space,
 | 
				
			||||||
  Spin,
 | 
					  Spin,
 | 
				
			||||||
  Table as AntdTable,
 | 
					  Table as AntdTable,
 | 
				
			||||||
 | 
					  Dropdown,
 | 
				
			||||||
 | 
					  Menu,
 | 
				
			||||||
} from 'antd';
 | 
					} from 'antd';
 | 
				
			||||||
import { findIndex } from 'lodash';
 | 
					import { findIndex, get } from 'lodash';
 | 
				
			||||||
import constate from 'constate';
 | 
					import constate from 'constate';
 | 
				
			||||||
import useRequest from '@ahooksjs/use-request';
 | 
					import useRequest from '@ahooksjs/use-request';
 | 
				
			||||||
import { BaseResult } from '@ahooksjs/use-request/lib/types';
 | 
					import { BaseResult } from '@ahooksjs/use-request/lib/types';
 | 
				
			||||||
import { uid, clone } from '@formily/shared';
 | 
					import { uid, clone } from '@formily/shared';
 | 
				
			||||||
import { MenuOutlined } from '@ant-design/icons';
 | 
					import { MenuOutlined } from '@ant-design/icons';
 | 
				
			||||||
import { useVisibleContext } from '../action';
 | 
					import { useVisibleContext } from '../action';
 | 
				
			||||||
import { SortableHandle, SortableContainer, SortableElement } from 'react-sortable-hoc'
 | 
					import {
 | 
				
			||||||
 | 
					  SortableHandle,
 | 
				
			||||||
 | 
					  SortableContainer,
 | 
				
			||||||
 | 
					  SortableElement,
 | 
				
			||||||
 | 
					} from 'react-sortable-hoc';
 | 
				
			||||||
import cls from 'classnames';
 | 
					import cls from 'classnames';
 | 
				
			||||||
 | 
					import { getSchemaPath, useDesignable, useSchemaPath } from '../DesignableSchemaField';
 | 
				
			||||||
 | 
					import './style.less';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface TableRowProps {
 | 
					interface TableRowProps {
 | 
				
			||||||
  index: number;
 | 
					  index: number;
 | 
				
			||||||
  data: any;
 | 
					  data: any;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const SortableRow = SortableElement((props: any) => <tr {...props} />)
 | 
					const SortableRow = SortableElement((props: any) => <tr {...props} />);
 | 
				
			||||||
const SortableBody = SortableContainer((props: any) => <tbody {...props} />)
 | 
					const SortableBody = SortableContainer((props: any) => <tbody {...props} />);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const TableRowContext = createContext<TableRowProps>(null);
 | 
					const TableRowContext = createContext<TableRowProps>(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -105,7 +114,8 @@ function useTableActionBars() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function useTableColumns(props?: any) {
 | 
					function useTableColumns(props?: any) {
 | 
				
			||||||
  const schema = useFieldSchema();
 | 
					  const { schema } = useDesignable();
 | 
				
			||||||
 | 
					  // const schema = useFieldSchema();
 | 
				
			||||||
  const { dataSource } = props || {};
 | 
					  const { dataSource } = props || {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function findColumns(schema: Schema): Schema[] {
 | 
					  function findColumns(schema: Schema): Schema[] {
 | 
				
			||||||
@ -120,7 +130,7 @@ function useTableColumns(props?: any) {
 | 
				
			|||||||
  return findColumns(schema).map((item) => {
 | 
					  return findColumns(schema).map((item) => {
 | 
				
			||||||
    const columnProps = item['x-component-props'] || {};
 | 
					    const columnProps = item['x-component-props'] || {};
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      title: item.title,
 | 
					      title: <RecursionField name={item.name} schema={item} onlyRenderSelf />,
 | 
				
			||||||
      dataIndex: item.name,
 | 
					      dataIndex: item.name,
 | 
				
			||||||
      ...columnProps,
 | 
					      ...columnProps,
 | 
				
			||||||
      render(value, record, recordIndex) {
 | 
					      render(value, record, recordIndex) {
 | 
				
			||||||
@ -282,23 +292,22 @@ const TableContainer = observer((props) => {
 | 
				
			|||||||
    useTableContext();
 | 
					    useTableContext();
 | 
				
			||||||
  const rowKey = field.componentProps.rowKey || 'id';
 | 
					  const rowKey = field.componentProps.rowKey || 'id';
 | 
				
			||||||
  const defaultAction = useDefaultAction();
 | 
					  const defaultAction = useDefaultAction();
 | 
				
			||||||
  console.log({ defaultAction });
 | 
					 | 
				
			||||||
  const dataSource = Array.isArray(field.value) ? field.value.slice() : [];
 | 
					  const dataSource = Array.isArray(field.value) ? field.value.slice() : [];
 | 
				
			||||||
  const columns = useTableColumns({ dataSource });
 | 
					  const columns = useTableColumns({ dataSource });
 | 
				
			||||||
  const ref = useRef<HTMLDivElement>()
 | 
					  const ref = useRef<HTMLDivElement>();
 | 
				
			||||||
  const addTdStyles = (node: HTMLElement) => {
 | 
					  const addTdStyles = (node: HTMLElement) => {
 | 
				
			||||||
    const helper = document.body.querySelector(`.nb-table-sort-helper`)
 | 
					    const helper = document.body.querySelector(`.nb-table-sort-helper`);
 | 
				
			||||||
    if (helper) {
 | 
					    if (helper) {
 | 
				
			||||||
      const tds = node.querySelectorAll('td')
 | 
					      const tds = node.querySelectorAll('td');
 | 
				
			||||||
      requestAnimationFrame(() => {
 | 
					      requestAnimationFrame(() => {
 | 
				
			||||||
        helper.querySelectorAll('td').forEach((td, index) => {
 | 
					        helper.querySelectorAll('td').forEach((td, index) => {
 | 
				
			||||||
          if (tds[index]) {
 | 
					          if (tds[index]) {
 | 
				
			||||||
            td.style.width = getComputedStyle(tds[index]).width
 | 
					            td.style.width = getComputedStyle(tds[index]).width;
 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div ref={ref} className={'nb-table'}>
 | 
					    <div ref={ref} className={'nb-table'}>
 | 
				
			||||||
      {actionBars.top.map((actionBarSchema) => {
 | 
					      {actionBars.top.map((actionBarSchema) => {
 | 
				
			||||||
@ -339,10 +348,10 @@ const TableContainer = observer((props) => {
 | 
				
			|||||||
                // disableAutoscroll
 | 
					                // disableAutoscroll
 | 
				
			||||||
                helperClass={`nb-table-sort-helper`}
 | 
					                helperClass={`nb-table-sort-helper`}
 | 
				
			||||||
                helperContainer={() => {
 | 
					                helperContainer={() => {
 | 
				
			||||||
                  return ref.current?.querySelector('tbody')
 | 
					                  return ref.current?.querySelector('tbody');
 | 
				
			||||||
                }}
 | 
					                }}
 | 
				
			||||||
                onSortStart={({ node }) => {
 | 
					                onSortStart={({ node }) => {
 | 
				
			||||||
                  addTdStyles(node)
 | 
					                  addTdStyles(node);
 | 
				
			||||||
                }}
 | 
					                }}
 | 
				
			||||||
                onSortEnd={({ oldIndex, newIndex }) => {
 | 
					                onSortEnd={({ oldIndex, newIndex }) => {
 | 
				
			||||||
                  field.move(oldIndex, newIndex);
 | 
					                  field.move(oldIndex, newIndex);
 | 
				
			||||||
@ -352,13 +361,11 @@ const TableContainer = observer((props) => {
 | 
				
			|||||||
              />
 | 
					              />
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            row: (props: any) => {
 | 
					            row: (props: any) => {
 | 
				
			||||||
              const index = findIndex(field.value, item => item[rowKey] === props['data-row-key']);
 | 
					              const index = findIndex(
 | 
				
			||||||
              return (
 | 
					                field.value,
 | 
				
			||||||
                <SortableRow
 | 
					                (item) => item[rowKey] === props['data-row-key'],
 | 
				
			||||||
                  index={index}
 | 
					              );
 | 
				
			||||||
                  {...props}
 | 
					              return <SortableRow index={index} {...props} />;
 | 
				
			||||||
                />
 | 
					 | 
				
			||||||
              )
 | 
					 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
        }}
 | 
					        }}
 | 
				
			||||||
@ -366,20 +373,17 @@ const TableContainer = observer((props) => {
 | 
				
			|||||||
          const index = dataSource.indexOf(data);
 | 
					          const index = dataSource.indexOf(data);
 | 
				
			||||||
          return {
 | 
					          return {
 | 
				
			||||||
            onClick(e) {
 | 
					            onClick(e) {
 | 
				
			||||||
              console.log('onRow', (e.target as HTMLElement), (e.target as HTMLElement).classList.contains('ant-table-cell'));
 | 
					 | 
				
			||||||
              if (!(e.target as HTMLElement).classList.contains('ant-table-cell')) {
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
              if (!defaultAction) {
 | 
					              if (!defaultAction) {
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
              // console.log('defaultAction');
 | 
					              const el = (e.target as HTMLElement);
 | 
				
			||||||
              field
 | 
					              if (
 | 
				
			||||||
                .query(`.${schema.name}.${index}.${defaultAction.name}`)
 | 
					                !el.classList.contains('ant-table-cell')
 | 
				
			||||||
                .take((f) => {
 | 
					              ) {
 | 
				
			||||||
                  const setVisible = f.componentProps.setVisible;
 | 
					                return;
 | 
				
			||||||
                  setVisible && setVisible(true);
 | 
					              }
 | 
				
			||||||
                });
 | 
					              const btn = el.parentElement.querySelector<HTMLElement>(`.name-${defaultAction.name}`);
 | 
				
			||||||
 | 
					              btn && btn.click();
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
          };
 | 
					          };
 | 
				
			||||||
        }}
 | 
					        }}
 | 
				
			||||||
@ -411,7 +415,99 @@ export const Table: any = observer((props) => {
 | 
				
			|||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Table.Column = () => null;
 | 
					function Blank() {
 | 
				
			||||||
 | 
					  return null;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function useDesignableBar() {
 | 
				
			||||||
 | 
					  const schema = useFieldSchema();
 | 
				
			||||||
 | 
					  const options = useContext(SchemaOptionsContext);
 | 
				
			||||||
 | 
					  const DesignableBar = get(options.components, schema['x-designable-bar']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    DesignableBar: DesignableBar || Blank,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Table.Column = observer((props) => {
 | 
				
			||||||
 | 
					  const schema = useFieldSchema();
 | 
				
			||||||
 | 
					  const field = useField();
 | 
				
			||||||
 | 
					  console.log('Table.Column', schema, field.title);
 | 
				
			||||||
 | 
					  const { DesignableBar } = useDesignableBar();
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <div className={'nb-table-column'}>
 | 
				
			||||||
 | 
					      {field.title}
 | 
				
			||||||
 | 
					      <DesignableBar />
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Table.Column.DesignableBar = () => {
 | 
				
			||||||
 | 
					  const field = useField();
 | 
				
			||||||
 | 
					  // const fieldSchema = useFieldSchema();
 | 
				
			||||||
 | 
					  const { schema, remove, refresh, insertAfter } = useDesignable();
 | 
				
			||||||
 | 
					  const [visible, setVisible] = useState(false);
 | 
				
			||||||
 | 
					  console.log('Table.Column.DesignableBar', { schema });
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <div className={cls('designable-bar', { active: visible })}>
 | 
				
			||||||
 | 
					      <span
 | 
				
			||||||
 | 
					        onClick={(e) => {
 | 
				
			||||||
 | 
					          e.stopPropagation();
 | 
				
			||||||
 | 
					        }}
 | 
				
			||||||
 | 
					        className={cls('designable-bar-actions', { active: visible })}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <Dropdown
 | 
				
			||||||
 | 
					          trigger={['click']}
 | 
				
			||||||
 | 
					          visible={visible}
 | 
				
			||||||
 | 
					          onVisibleChange={(visible) => {
 | 
				
			||||||
 | 
					            setVisible(visible);
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					          overlay={
 | 
				
			||||||
 | 
					            <Menu>
 | 
				
			||||||
 | 
					              <Menu.Item onClick={(e) => {
 | 
				
			||||||
 | 
					                const title = uid();
 | 
				
			||||||
 | 
					                field.title = title;
 | 
				
			||||||
 | 
					                schema.title = title;
 | 
				
			||||||
 | 
					                setVisible(false);
 | 
				
			||||||
 | 
					              }}>点击修改按钮文案</Menu.Item>
 | 
				
			||||||
 | 
					              <Menu.Item onClick={() => {
 | 
				
			||||||
 | 
					                remove();
 | 
				
			||||||
 | 
					                console.log('Table.Column.DesignableBar', { schema });
 | 
				
			||||||
 | 
					              }}>删除列</Menu.Item>
 | 
				
			||||||
 | 
					              <Menu.Item onClick={() => {
 | 
				
			||||||
 | 
					                const name = uid();
 | 
				
			||||||
 | 
					                insertAfter({
 | 
				
			||||||
 | 
					                  name: `column_${name}`,
 | 
				
			||||||
 | 
					                  type: 'void',
 | 
				
			||||||
 | 
					                  title: `字段 ${name}`,
 | 
				
			||||||
 | 
					                  'x-component': 'Table.Column',
 | 
				
			||||||
 | 
					                  'x-component-props': {
 | 
				
			||||||
 | 
					                    // title: 'z1',
 | 
				
			||||||
 | 
					                  },
 | 
				
			||||||
 | 
					                  'x-designable-bar': 'Table.Column.DesignableBar',
 | 
				
			||||||
 | 
					                  properties: {
 | 
				
			||||||
 | 
					                    [name]: {
 | 
				
			||||||
 | 
					                      type: 'string',
 | 
				
			||||||
 | 
					                      required: true,
 | 
				
			||||||
 | 
					                      // 'x-read-pretty': true,
 | 
				
			||||||
 | 
					                      'x-decorator-props': {
 | 
				
			||||||
 | 
					                        feedbackLayout: 'popover',
 | 
				
			||||||
 | 
					                      },
 | 
				
			||||||
 | 
					                      'x-decorator': 'FormItem',
 | 
				
			||||||
 | 
					                      'x-component': 'Input',
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                  },
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					              }}>插入列</Menu.Item>
 | 
				
			||||||
 | 
					            </Menu>
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <MenuOutlined />
 | 
				
			||||||
 | 
					        </Dropdown>
 | 
				
			||||||
 | 
					      </span>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Table.ActionBar = observer((props) => {
 | 
					Table.ActionBar = observer((props) => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
@ -447,17 +543,20 @@ const SortHandle = SortableHandle((props: any) => {
 | 
				
			|||||||
      className={cls(`nb-table-sort-handle`, props.className)}
 | 
					      className={cls(`nb-table-sort-handle`, props.className)}
 | 
				
			||||||
      style={{ ...props.style }}
 | 
					      style={{ ...props.style }}
 | 
				
			||||||
    />
 | 
					    />
 | 
				
			||||||
  )
 | 
					  );
 | 
				
			||||||
}) as any
 | 
					}) as any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Table.SortHandle = observer((props) => {
 | 
					Table.SortHandle = observer((props) => {
 | 
				
			||||||
  const field = useField<Formily.Core.Models.Field>();
 | 
					  const field = useField<Formily.Core.Models.Field>();
 | 
				
			||||||
  console.log('SortHandle', field.value);
 | 
					  console.log('SortHandle', field.value);
 | 
				
			||||||
  return <SortHandle {...props}/>;
 | 
					  return <SortHandle {...props} />;
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Table.Index = observer((props) => {
 | 
					Table.Index = observer((props) => {
 | 
				
			||||||
  const index = useTableIndex();
 | 
					  const index = useTableIndex();
 | 
				
			||||||
 | 
					  const schema = useFieldSchema();
 | 
				
			||||||
 | 
					  const field = useField<Formily.Core.Models.Field>();
 | 
				
			||||||
 | 
					  const path = useSchemaPath();
 | 
				
			||||||
  return <div>#{index + 1}</div>;
 | 
					  return <div>#{index + 1}</div>;
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -484,3 +583,41 @@ Table.Addition = observer((props: any) => {
 | 
				
			|||||||
    </Button>
 | 
					    </Button>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Table.Action = () => null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Table.Action.DesignableBar = () => {
 | 
				
			||||||
 | 
					  const field = useField();
 | 
				
			||||||
 | 
					  const path = useSchemaPath();
 | 
				
			||||||
 | 
					  const { schema, remove, refresh, insertAfter } = useDesignable();
 | 
				
			||||||
 | 
					  const [visible, setVisible] = useState(false);
 | 
				
			||||||
 | 
					  console.log('Table.Action.DesignableBar', path, field.address.entire, { schema, field });
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <div className={cls('designable-bar', { active: visible })}>
 | 
				
			||||||
 | 
					      <span
 | 
				
			||||||
 | 
					        onClick={(e) => {
 | 
				
			||||||
 | 
					          e.stopPropagation();
 | 
				
			||||||
 | 
					        }}
 | 
				
			||||||
 | 
					        className={cls('designable-bar-actions', { active: visible })}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <Dropdown
 | 
				
			||||||
 | 
					          trigger={['click']}
 | 
				
			||||||
 | 
					          visible={visible}
 | 
				
			||||||
 | 
					          onVisibleChange={(visible) => {
 | 
				
			||||||
 | 
					            setVisible(visible);
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					          overlay={
 | 
				
			||||||
 | 
					            <Menu>
 | 
				
			||||||
 | 
					              <Menu.Item onClick={(e) => {
 | 
				
			||||||
 | 
					                schema.title = uid();
 | 
				
			||||||
 | 
					                refresh();
 | 
				
			||||||
 | 
					              }}>点击修改按钮文案</Menu.Item>
 | 
				
			||||||
 | 
					            </Menu>
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <MenuOutlined />
 | 
				
			||||||
 | 
					        </Dropdown>
 | 
				
			||||||
 | 
					      </span>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										61
									
								
								packages/client/src/schemas/table/style.less
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								packages/client/src/schemas/table/style.less
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					.nb-table-column {
 | 
				
			||||||
 | 
					  &:hover {
 | 
				
			||||||
 | 
					    > .designable-bar {
 | 
				
			||||||
 | 
					      display: block;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  > .designable-bar {
 | 
				
			||||||
 | 
					    display: none;
 | 
				
			||||||
 | 
					    position: absolute;
 | 
				
			||||||
 | 
					    top: 0;
 | 
				
			||||||
 | 
					    right: 0;
 | 
				
			||||||
 | 
					    left: 0;
 | 
				
			||||||
 | 
					    bottom: 0;
 | 
				
			||||||
 | 
					    border-radius: 0;
 | 
				
			||||||
 | 
					    border: 2px solid #1890ff;
 | 
				
			||||||
 | 
					    &.active {
 | 
				
			||||||
 | 
					      display: block;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .designable-bar-actions {
 | 
				
			||||||
 | 
					      position: absolute;
 | 
				
			||||||
 | 
					      right: 0;
 | 
				
			||||||
 | 
					      line-height: 1rem;
 | 
				
			||||||
 | 
					      background-color: #1890ff;
 | 
				
			||||||
 | 
					      color: #fff;
 | 
				
			||||||
 | 
					      z-index: 10;
 | 
				
			||||||
 | 
					      padding: 0 3px;
 | 
				
			||||||
 | 
					      .anticon {
 | 
				
			||||||
 | 
					        font-size: 10px;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.ant-popover.nb-action-group {
 | 
				
			||||||
 | 
					  z-index: 1000;
 | 
				
			||||||
 | 
					  padding-top: 0;
 | 
				
			||||||
 | 
					  .ant-popover-arrow {
 | 
				
			||||||
 | 
					    display: none;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  .ant-popover-inner-content {
 | 
				
			||||||
 | 
					    padding: 4px 0;
 | 
				
			||||||
 | 
					    .ant-btn {
 | 
				
			||||||
 | 
					      display: block;
 | 
				
			||||||
 | 
					      min-width: 100px;
 | 
				
			||||||
 | 
					      width: 100%;
 | 
				
			||||||
 | 
					      border: 0;
 | 
				
			||||||
 | 
					      border-radius: 0;
 | 
				
			||||||
 | 
					      text-align: left;
 | 
				
			||||||
 | 
					      padding: 5px 12px;
 | 
				
			||||||
 | 
					      color: #000;
 | 
				
			||||||
 | 
					      &:hover {
 | 
				
			||||||
 | 
					        background-color: #f5f5f5;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      &[disabled] {
 | 
				
			||||||
 | 
					        color: #00000040;
 | 
				
			||||||
 | 
					        background-color:#fff;
 | 
				
			||||||
 | 
					        cursor:not-allowed;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -161,33 +161,36 @@ function Database() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function LayoutWithMenu({ schema }) {
 | 
					function LayoutWithMenu({ schema }) {
 | 
				
			||||||
 | 
					  const match = useRouteMatch<any>();
 | 
				
			||||||
  const location = useLocation();
 | 
					  const location = useLocation();
 | 
				
			||||||
  const ref = useRef();
 | 
					  const sideMenuRef = useRef();
 | 
				
			||||||
  const [activeKey, setActiveKey] = useState('item3');
 | 
					  const [activeKey, setActiveKey] = useState(match.params.name);
 | 
				
			||||||
  schema['x-component-props']['defaultSelectedKeys'] = [activeKey];
 | 
					  const onSelect = (info) => {
 | 
				
			||||||
  schema['x-component-props']['onSelect'] = (info) => {
 | 
					    console.log('LayoutWithMenu', schema);
 | 
				
			||||||
    console.log('LayoutWithMenu', schema)
 | 
					 | 
				
			||||||
    setActiveKey(info.key);
 | 
					    setActiveKey(info.key);
 | 
				
			||||||
  }
 | 
					  };
 | 
				
			||||||
 | 
					  console.log({ match });
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <Layout>
 | 
					    <Layout>
 | 
				
			||||||
      <Layout.Header>
 | 
					      <Layout.Header>
 | 
				
			||||||
          <MenuContainerContext.Provider value={{
 | 
					        <SchemaRenderer
 | 
				
			||||||
            sideMenuRef: ref,
 | 
					          schema={schema}
 | 
				
			||||||
          }}>
 | 
					          scope={{ sideMenuRef, onSelect, selectedKeys: [activeKey].filter(Boolean) }}
 | 
				
			||||||
            <SchemaRenderer schema={schema} />
 | 
					        />
 | 
				
			||||||
          </MenuContainerContext.Provider>
 | 
					 | 
				
			||||||
      </Layout.Header>
 | 
					      </Layout.Header>
 | 
				
			||||||
      <Layout>
 | 
					      <Layout>
 | 
				
			||||||
          <Layout.Sider ref={ref} theme={'light'} width={200}>
 | 
					        <Layout.Sider
 | 
				
			||||||
          </Layout.Sider>
 | 
					          ref={sideMenuRef}
 | 
				
			||||||
 | 
					          theme={'light'}
 | 
				
			||||||
 | 
					          width={200}
 | 
				
			||||||
 | 
					        ></Layout.Sider>
 | 
				
			||||||
        <Layout.Content>
 | 
					        <Layout.Content>
 | 
				
			||||||
          {location.pathname}
 | 
					          {location.pathname}
 | 
				
			||||||
            <Content activeKey={activeKey}/>
 | 
					          <Content activeKey={activeKey} />
 | 
				
			||||||
        </Layout.Content>
 | 
					        </Layout.Content>
 | 
				
			||||||
      </Layout>
 | 
					      </Layout>
 | 
				
			||||||
    </Layout>
 | 
					    </Layout>
 | 
				
			||||||
  )
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Content({ activeKey }) {
 | 
					function Content({ activeKey }) {
 | 
				
			||||||
@ -207,7 +210,6 @@ function Content({ activeKey }) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function AdminLayout({ route, children }: any) {
 | 
					export function AdminLayout({ route, children }: any) {
 | 
				
			||||||
  const match = useRouteMatch<any>();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const { data = {}, loading } = useRequest(
 | 
					  const { data = {}, loading } = useRequest(
 | 
				
			||||||
    `/api/blocks:getSchema/${route.blockId}`,
 | 
					    `/api/blocks:getSchema/${route.blockId}`,
 | 
				
			||||||
@ -220,9 +222,7 @@ export function AdminLayout({ route, children }: any) {
 | 
				
			|||||||
    return <Spin />;
 | 
					    return <Spin />;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return <LayoutWithMenu schema={data} />;
 | 
				
			||||||
    <LayoutWithMenu schema={data}/>
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default AdminLayout;
 | 
					export default AdminLayout;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user