feat: improve code

This commit is contained in:
chenos 2021-08-23 09:51:19 +08:00
parent 3d5c81618f
commit 99635025a8
6 changed files with 278 additions and 13 deletions

View File

@ -183,9 +183,7 @@ export const FieldDesignableBar = observer((props) => {
console.log({ schema, removed, fieldName }); console.log({ schema, removed, fieldName });
const last = removed.pop(); const last = removed.pop();
displayed.remove(fieldName); displayed.remove(fieldName);
if (isGridRowOrCol(last)) {
await removeSchema(last); await removeSchema(last);
}
}} }}
> >

View File

@ -205,7 +205,7 @@ Form.Field = observer((props: any) => {
Form.Field.Item = observer((props) => { Form.Field.Item = observer((props) => {
return ( return (
<RandomNameContext.Provider value={uid()}> <RandomNameContext.Provider value={uid()}>
<BlockItem>{props.children}</BlockItem> <BlockItem {...props}>{props.children}</BlockItem>
</RandomNameContext.Provider> </RandomNameContext.Provider>
); );
}); });

View File

@ -91,7 +91,10 @@ export const CardDesignableBar = observer((props) => {
name: uid(), name: uid(),
type: 'void', type: 'void',
'x-decorator': 'Form.Field.Item', 'x-decorator': 'Form.Field.Item',
// 'x-designable-bar': 'Form.Field.DesignableBar', 'x-decorator-props': {
draggable: false,
},
'x-designable-bar': 'Kanban.FieldDesignableBar',
'x-component': 'Form.Field', 'x-component': 'Form.Field',
'x-component-props': { 'x-component-props': {
fieldName: field.name, fieldName: field.name,

View File

@ -12,12 +12,12 @@ import {
useForm, useForm,
RecursionField, RecursionField,
} from '@formily/react'; } from '@formily/react';
import { useSchemaPath, SchemaField, useDesignable, removeSchema } from '../'; import { useSchemaPath, SchemaField, useDesignable, removeSchema, updateSchema } from '../';
import get from 'lodash/get'; import get from 'lodash/get';
import { Button, Dropdown, Menu, Space } from 'antd'; import { Button, Dropdown, Menu, Space } from 'antd';
import { MenuOutlined, DragOutlined } from '@ant-design/icons'; import { MenuOutlined, DragOutlined } from '@ant-design/icons';
import cls from 'classnames'; import cls from 'classnames';
import { FormLayout } from '@formily/antd'; import { FormDialog, FormLayout } from '@formily/antd';
import './style.less'; import './style.less';
import AddNew from '../add-new'; import AddNew from '../add-new';
import { DraggableBlockContext } from '../../components/drag-and-drop'; import { DraggableBlockContext } from '../../components/drag-and-drop';
@ -29,6 +29,7 @@ import { getSchemaPath } from '../../components/schema-renderer';
import { useCollection, useCollectionContext } from '../../constate'; import { useCollection, useCollectionContext } from '../../constate';
import { useTable } from '../table'; import { useTable } from '../table';
import { DragHandle } from '../../components/Sortable'; import { DragHandle } from '../../components/Sortable';
import { fieldsToFilterColumns } from '../calendar';
export const DesignableBar = observer((props) => { export const DesignableBar = observer((props) => {
const field = useField(); const field = useField();
@ -37,7 +38,7 @@ export const DesignableBar = observer((props) => {
const { dragRef } = useContext(DraggableBlockContext); const { dragRef } = useContext(DraggableBlockContext);
const { props: tableProps } = useTable(); const { props: tableProps } = useTable();
const collectionName = field.componentProps?.collectionName || tableProps?.collectionName; const collectionName = field.componentProps?.collectionName || tableProps?.collectionName;
const { collection } = useCollection({ collectionName }); const { collection, fields } = useCollection({ collectionName });
return ( return (
<div className={cls('designable-bar', { active: visible })}> <div className={cls('designable-bar', { active: visible })}>
<div className={'designable-info'}>{collection?.title || collection?.name}</div> <div className={'designable-info'}>{collection?.title || collection?.name}</div>
@ -66,7 +67,44 @@ export const DesignableBar = observer((props) => {
> >
</Menu.Item> */} </Menu.Item> */}
{/* <Menu.Divider /> */} <Menu.Item
key={'defaultFilter'}
onClick={async () => {
const { defaultFilter } = await FormDialog(
'设置筛选范围',
() => {
return (
<FormLayout layout={'vertical'}>
<SchemaField
schema={{
type: 'object',
properties: {
defaultFilter: {
type: 'object',
'x-component': 'Filter',
properties: fieldsToFilterColumns(fields),
},
},
}}
/>
</FormLayout>
);
},
).open({
initialValues: {
defaultFilter:
field?.componentProps?.defaultFilter || {},
},
});
schema['x-component-props']['defaultFilter'] =
defaultFilter;
field.componentProps.defaultFilter = defaultFilter;
await updateSchema(schema);
}}
>
</Menu.Item>
<Menu.Divider />
<Menu.Item <Menu.Item
key={'delete'} key={'delete'}
onClick={async () => { onClick={async () => {

View File

@ -0,0 +1,151 @@
import React, { useContext, useMemo, useRef, useState } from 'react';
import { createForm } from '@formily/core';
import {
SchemaOptionsContext,
Schema,
useFieldSchema,
observer,
SchemaExpressionScopeContext,
FormProvider,
ISchema,
useField,
useForm,
RecursionField,
} from '@formily/react';
import {
useSchemaPath,
SchemaField,
useDesignable,
removeSchema,
updateSchema,
} from '../';
import get from 'lodash/get';
import { Button, Dropdown, Menu, Space, Switch } from 'antd';
import { MenuOutlined, DragOutlined } from '@ant-design/icons';
import cls from 'classnames';
import { FormDialog, FormLayout } from '@formily/antd';
import './style.less';
import AddNew from '../add-new';
import { DraggableBlockContext } from '../../components/drag-and-drop';
import { isGridRowOrCol } from '../grid';
import constate from 'constate';
import { useEffect } from 'react';
import { uid } from '@formily/shared';
import { getSchemaPath } from '../../components/schema-renderer';
import { RandomNameContext } from '../form';
import { useCollectionContext, useDisplayedMapContext } from '../../constate';
import SwitchMenuItem from '../../components/SwitchMenuItem';
import { DragHandle } from '../../components/Sortable';
export const FieldDesignableBar = observer((props) => {
const field = useField();
const { schema, deepRemove } = useDesignable();
const [visible, setVisible] = useState(false);
const { dragRef } = useContext(DraggableBlockContext);
const randomName = useContext(RandomNameContext);
const displayed = useDisplayedMapContext();
const fieldName = schema['x-component-props']?.['fieldName'];
const { getField } = useCollectionContext();
const collectionField = getField(fieldName);
console.log({ collectionField });
const realField = field
.query(field.address.concat(randomName, fieldName))
.take();
return (
<div className={cls('designable-bar', { active: visible })}>
<span
onClick={(e) => {
e.stopPropagation();
}}
className={cls('designable-bar-actions', { active: visible })}
>
<Space size={2}>
{/* <AddNew.FormItem defaultAction={'insertAfter'} ghost />
<DragHandle /> */}
<Dropdown
placement={'bottomRight'}
trigger={['click']}
visible={visible}
onVisibleChange={(visible) => {
setVisible(visible);
}}
overlay={
<Menu>
<Menu.Item
key={'update'}
onClick={async () => {
const values = await FormDialog('修改字段名称', () => {
return (
<FormLayout layout={'vertical'}>
<SchemaField
schema={{
type: 'object',
properties: {
fieldName: {
type: 'string',
title: '原字段名称',
'x-read-pretty': true,
'x-decorator': 'FormItem',
'x-component': 'Input',
},
title: {
type: 'string',
title: '自定义名称',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
},
}}
/>
</FormLayout>
);
}).open({
initialValues: {
fieldName: collectionField?.uiSchema?.title,
title: schema['title'],
},
});
const title = values.title || null;
field
.query(field.address.concat(randomName, fieldName))
.take((f) => {
f.title = title || collectionField?.uiSchema?.title;
});
schema['title'] = title;
await updateSchema({
key: schema['key'],
title,
});
}}
>
</Menu.Item>
<Menu.Divider />
<Menu.Item
key={'delete'}
onClick={async () => {
const removed = deepRemove();
const fieldName =
schema['x-component-props']?.['fieldName'];
console.log({ schema, removed, fieldName });
const last = removed.pop();
displayed.remove(fieldName);
await removeSchema(last);
}}
>
</Menu.Item>
</Menu>
}
>
<MenuOutlined />
</Dropdown>
</Space>
</span>
</div>
);
});

View File

@ -21,7 +21,7 @@ import {
} from '@formily/react'; } from '@formily/react';
import { Card, Spin, Tag } from 'antd'; import { Card, Spin, Tag } from 'antd';
import { groupBy } from 'lodash'; import { groupBy } from 'lodash';
import React, { createContext, useContext, useRef } from 'react'; import React, { createContext, useContext, useEffect, useRef } from 'react';
import { useState } from 'react'; import { useState } from 'react';
import { CSS } from '@dnd-kit/utilities'; import { CSS } from '@dnd-kit/utilities';
import cls from 'classnames'; import cls from 'classnames';
@ -34,6 +34,8 @@ import { CardDesignableBar } from './CardDesignableBar';
import { VisibleContext } from '../../context'; import { VisibleContext } from '../../context';
import { DesignableBar } from './DesignableBar'; import { DesignableBar } from './DesignableBar';
import { useDesignable } from '../../components/schema-renderer'; import { useDesignable } from '../../components/schema-renderer';
import { Form } from '../form';
import { FieldDesignableBar } from './FieldDesignableBar';
function Droppable(props) { function Droppable(props) {
const { id, data, ...others } = props; const { id, data, ...others } = props;
@ -169,6 +171,7 @@ const InternalKanban = observer((props: any) => {
return resource.list({ return resource.list({
...params, ...params,
perPage: -1, perPage: -1,
sort: 'sort',
}); });
}, },
{ {
@ -176,10 +179,15 @@ const InternalKanban = observer((props: any) => {
onSuccess(data) { onSuccess(data) {
field.setValue(data); field.setValue(data);
}, },
// manual: true, manual: true,
// refreshDeps: [props.fieldNames], // refreshDeps: [props.fieldNames],
}, },
); );
useEffect(() => {
service.run({
defaultFilter: props?.defaultFilter,
});
}, [props.defaultFilter]);
const { schema } = useDesignable(); const { schema } = useDesignable();
const [schemas, setSchemas] = useState(() => { const [schemas, setSchemas] = useState(() => {
const schemas = new Map<string, Schema>(); const schemas = new Map<string, Schema>();
@ -198,6 +206,8 @@ const InternalKanban = observer((props: any) => {
return schemas; return schemas;
}); });
const addNewCardSchema = schemas.get('Kanban.Card.AddNew'); const addNewCardSchema = schemas.get('Kanban.Card.AddNew');
const [dragOverlayContent, setDragOverlayContent] = useState('');
const [lastId, setLastId] = useState(null);
console.log('field.value', schemas); console.log('field.value', schemas);
return ( return (
<KanbanContext.Provider <KanbanContext.Provider
@ -205,6 +215,11 @@ const InternalKanban = observer((props: any) => {
> >
<DndContext <DndContext
sensors={sensors} sensors={sensors}
onDragStart={(event) => {
const el = event?.active?.data?.current?.nodeRef
?.current as HTMLElement;
setDragOverlayContent(el?.outerHTML);
}}
onDragMove={({ active, over }) => { onDragMove={({ active, over }) => {
const overId = over?.id; const overId = over?.id;
const activeId = active?.id; const activeId = active?.id;
@ -223,6 +238,7 @@ const InternalKanban = observer((props: any) => {
const len = groups?.[overId]?.length; const len = groups?.[overId]?.length;
if (len > 0) { if (len > 0) {
const last = groups?.[overId]?.[len - 1]; const last = groups?.[overId]?.[len - 1];
setLastId(last.id);
const activeIndex = field.value.findIndex( const activeIndex = field.value.findIndex(
(item) => item.id === activeId, (item) => item.id === activeId,
); );
@ -252,13 +268,33 @@ const InternalKanban = observer((props: any) => {
} }
} }
}} }}
onDragEnd={({ active, over }) => { onDragEnd={async ({ active, over }) => {
console.log('onDragEnd', { lastId, active, over });
const overId = over?.id; const overId = over?.id;
const activeId = active?.id; const activeId = active?.id;
if (!overId || !activeId) { if (!overId || !activeId) {
return; return;
} }
if (overId === activeId) { if (overId === activeId) {
const overColumnId = over?.data?.current?.columnId;
await resource.save(
{
[groupField.name]: overColumnId,
},
{
resourceKey: activeId,
},
);
await resource.sort({
resourceKey: activeId,
field: 'sort',
target: lastId
? {
id: lastId,
}
: {},
});
setLastId(null);
return; return;
} }
const overType = over?.data?.current?.type; const overType = over?.data?.current?.type;
@ -278,11 +314,49 @@ const InternalKanban = observer((props: any) => {
(item) => item.id === overId, (item) => item.id === overId,
); );
field.move(activeIndex, overIndex); field.move(activeIndex, overIndex);
await resource.save(
{
[groupField.name]: overColumnId,
},
{
resourceKey: activeId,
},
);
await resource.sort({
resourceKey: activeId,
field: 'sort',
target: {
id: overId,
},
});
} else {
await resource.save(
{
[groupField.name]: overId,
},
{
resourceKey: activeId,
},
);
await resource.sort({
resourceKey: activeId,
field: 'sort',
target: lastId
? {
id: lastId,
}
: {},
});
setLastId(null);
} }
}} }}
> >
<DragOverlay style={{ background: 'yellow' }}> <DragOverlay style={{ background: 'yellow' }}>
<div>aaa</div> {/* <div>aaa</div> */}
<div
className={'nb-kanban-drag-overlay'}
dangerouslySetInnerHTML={{ __html: dragOverlayContent }}
/>
</DragOverlay> </DragOverlay>
<Spin spinning={service.loading}> <Spin spinning={service.loading}>
<div <div
@ -418,3 +492,4 @@ Kanban.Card.View = Action.Drawer;
Kanban.Card.AddNew = Action; Kanban.Card.AddNew = Action;
Kanban.DesignableBar = DesignableBar; Kanban.DesignableBar = DesignableBar;
Kanban.Card.DesignableBar = CardDesignableBar; Kanban.Card.DesignableBar = CardDesignableBar;
Kanban.FieldDesignableBar = FieldDesignableBar;