diff --git a/packages/client/src/components/schema-renderer/index.tsx b/packages/client/src/components/schema-renderer/index.tsx index a1af135b3..27302294a 100644 --- a/packages/client/src/components/schema-renderer/index.tsx +++ b/packages/client/src/components/schema-renderer/index.tsx @@ -30,6 +30,7 @@ import { Space, Card, Modal, Spin } from 'antd'; import { ArrayTable } from '../../schemas/array-table'; import { Action } from '../../schemas/action'; import { AddNew } from '../../schemas/add-new'; +import { Calendar } from '../../schemas/calendar'; import { Cascader } from '../../schemas/cascader'; import { Checkbox } from '../../schemas/checkbox'; import { ColorSelect } from '../../schemas/color-select'; @@ -46,6 +47,7 @@ import { IconPicker } from '../../schemas/icon-picker'; import { Input } from '../../schemas/input'; import { InputNumber } from '../../schemas/input-number'; import { Markdown } from '../../schemas/markdown'; +import { Kanban } from '../../schemas/kanban'; import { Menu } from '../../schemas/menu'; import { Password } from '../../schemas/password'; import { Radio } from '../../schemas/radio'; @@ -170,6 +172,7 @@ export const SchemaField = createSchemaField({ Action, AddNew, + Calendar, Cascader, Checkbox, ColorSelect, @@ -182,6 +185,7 @@ export const SchemaField = createSchemaField({ IconPicker, Input, InputNumber, + Kanban, Markdown, Menu, Password, diff --git a/packages/client/src/schemas/add-new/index.tsx b/packages/client/src/schemas/add-new/index.tsx index dad87cac8..9551343ac 100644 --- a/packages/client/src/schemas/add-new/index.tsx +++ b/packages/client/src/schemas/add-new/index.tsx @@ -347,6 +347,123 @@ function generateCardItemSchema(component) { }, }, }, + Kanban: { + type: 'array', + name: 'kanban1', + 'x-decorator': 'CardItem', + 'x-decorator-props': { + style: { + background: 'none', + }, + bodyStyle: { + padding: 0, + }, + }, + 'x-designable-bar': 'Kanban.DesignableBar', + 'x-component': 'Kanban', + default: [ + { + id: '1', + type: 'A', + title: 'A1', + }, + { + id: '2', + type: 'A', + title: 'A2', + }, + { + id: '3', + type: 'A', + title: 'A3', + }, + { + id: '4', + type: 'B', + title: 'B4', + }, + { + id: '5', + type: 'B', + title: 'B5', + }, + { + id: '6', + type: 'B', + title: 'B6', + }, + { + id: '7', + type: 'C', + title: 'C7', + }, + { + id: '8', + type: 'C', + title: 'C8', + }, + { + id: '9', + type: 'C', + title: 'C9', + }, + ], + properties: { + card1: { + type: 'void', + 'x-component': 'Kanban.Card', + properties: { + item1: { + type: 'void', + 'x-component': 'Kanban.Item', + properties: { + title: { + type: 'string', + // title: '标题', + 'x-read-pretty': true, + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + }, + }, + }, + }, + view1: { + type: 'void', + 'x-component': 'Kanban.Card.View', + properties: { + item1: { + type: 'void', + 'x-component': 'Kanban.Item', + properties: { + title: { + type: 'string', + title: '标题', + 'x-read-pretty': true, + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + }, + }, + }, + }, + }, + }, + Calendar: { + type: 'array', + name: 'calendar1', + 'x-component': 'Calendar', + 'x-designable-bar': 'Calendar.DesignableBar', + 'x-decorator': 'CardItem', + default: [], + properties: { + event: { + type: 'void', + 'x-component': 'Calendar.Event', + properties: {}, + }, + }, + }, 'Chart.Column': { type: 'void', 'x-decorator': 'CardItem', @@ -733,6 +850,12 @@ AddNew.CardItem = observer((props: any) => { overlay={ { + if (info.key.startsWith('Calendar.')) { + return; + } + if (info.key.startsWith('Kanban.')) { + return; + } let data: ISchema; let collectionName = null; let isNew = false; @@ -801,22 +924,10 @@ AddNew.CardItem = observer((props: any) => { {[ { key: 'Table', title: '表格', icon: 'TableOutlined' }, { key: 'Form', title: '表单', icon: 'FormOutlined' }, - { - key: 'Calendar', - title: '日历', - icon: 'CalendarOutlined', - disabled: true, - }, - { - key: 'Kanban', - title: '看板', - icon: 'CreditCardOutlined', - disabled: true, - }, ].map((view) => ( } - disabled={view.disabled} + // disabled={view.disabled} key={view.key} title={view.title} > @@ -840,6 +951,220 @@ AddNew.CardItem = observer((props: any) => { ))} + {[ + { + key: 'Calendar', + title: '日历', + icon: 'CalendarOutlined', + // disabled: true, + }, + ].map((view) => ( + } + // disabled={view.disabled} + key={view.key} + title={view.title} + > + + {collections?.map((item) => ( + { + const values = await FormDialog(`日历配置`, () => { + return ( + + { + return { + label: field?.uiSchema.title, + name: field?.name, + }; + }, + ), + }, + startTimeField: { + title: '开始日期字段', + required: true, + 'x-decorator': 'FormItem', + 'x-component': 'Select', + enum: item?.generalFields + ?.filter( + (field) => field.dataType === 'date', + ) + ?.map((field) => { + return { + label: field?.uiSchema.title, + name: field?.name, + }; + }), + }, + endTimeField: { + title: '结束日期字段', + 'x-decorator': 'FormItem', + 'x-component': 'Select', + enum: item?.generalFields + ?.filter( + (field) => field.dataType === 'date', + ) + ?.map((field) => { + return { + label: field?.uiSchema.title, + name: field?.name, + }; + }), + }, + }, + }} + /> + + ); + }).open({}); + let data = generateCardItemSchema('Calendar'); + const collectionName = item.name; + if (schema['key']) { + data['key'] = uid(); + } + if (collectionName) { + data['x-component-props'] = + data['x-component-props'] || {}; + data['x-component-props']['resource'] = + collectionName; + data['x-component-props']['collectionName'] = + collectionName; + data['x-component-props']['titleField'] = + values.titleField; + data['x-component-props']['startTimeField'] = + values.startTimeField; + data['x-component-props']['endTimeField'] = + values.endTimeField; + } + if (isGridBlock(schema)) { + path.pop(); + path.pop(); + data = generateGridBlock(data); + } else if (isGrid(schema)) { + data = generateGridBlock(data); + } + if (data) { + let s; + if (isGrid(schema)) { + s = appendChild(data, [...path]); + } else if (defaultAction === 'insertAfter') { + s = insertAfter(data, [...path]); + } else { + s = insertBefore(data, [...path]); + } + await createSchema(s); + } + }} + > + {item.title} + + ))} + + {/* */} + {/* } key={`addNew${view.key}`}> + 新建数据表 + */} + + ))} + {[ + { + key: 'Kanban', + title: '看板', + icon: 'CreditCardOutlined', + // disabled: true, + }, + ].map((view) => ( + } + // disabled={view.disabled} + key={view.key} + title={view.title} + > + + {collections?.map((item) => ( + + + { + let data = generateCardItemSchema('Kanban'); + const collectionName = item.name; + if (schema['key']) { + data['key'] = uid(); + } + if (collectionName) { + data['x-component-props'] = + data['x-component-props'] || {}; + data['x-component-props']['resource'] = + collectionName; + data['x-component-props']['collectionName'] = + collectionName; + // data['x-component-props']['groupField'] = ''; + } + if (isGridBlock(schema)) { + path.pop(); + path.pop(); + data = generateGridBlock(data); + } else if (isGrid(schema)) { + data = generateGridBlock(data); + } + if (data) { + let s; + if (isGrid(schema)) { + s = appendChild(data, [...path]); + } else if (defaultAction === 'insertAfter') { + s = insertAfter(data, [...path]); + } else { + s = insertBefore(data, [...path]); + } + await createSchema(s); + } + }} + > + 分组字段1 + + + + // + // {item.title} + // + ))} + + + } key={`addNew${view.key}`}> + 新建数据表 + + + ))} @@ -887,7 +1212,7 @@ AddNew.CardItem = observer((props: any) => { - + } title={'引用模板'}> 操作日志 diff --git a/packages/client/src/schemas/calendar/DesignableBar.tsx b/packages/client/src/schemas/calendar/DesignableBar.tsx new file mode 100644 index 000000000..171d31585 --- /dev/null +++ b/packages/client/src/schemas/calendar/DesignableBar.tsx @@ -0,0 +1,91 @@ +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 } from '../'; +import get from 'lodash/get'; +import { Button, Dropdown, Menu, Space } from 'antd'; +import { MenuOutlined, DragOutlined } from '@ant-design/icons'; +import cls from 'classnames'; +import { 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 { useCollection, useCollectionContext } from '../../constate'; +import { useTable } from '../table'; + +export const DesignableBar = observer((props) => { + const field = useField(); + const { designable, schema, refresh, deepRemove } = useDesignable(); + const [visible, setVisible] = useState(false); + const { dragRef } = useContext(DraggableBlockContext); + const { props: tableProps } = useTable(); + const collectionName = field.componentProps?.collectionName || tableProps?.collectionName; + const { collection } = useCollection({ collectionName }); + return ( +
+
{collection?.title || collection?.name}
+ { + e.stopPropagation(); + }} + className={cls('designable-bar-actions', { active: visible })} + > + + + {dragRef && } + { + setVisible(visible); + }} + overlay={ + + {/* { + field.readPretty = true; + }} + > + 编辑表单配置 + */} + {/* */} + { + const removed = deepRemove(); + // console.log({ removed }) + const last = removed.pop(); + if (isGridRowOrCol(last)) { + await removeSchema(last); + } + }} + > + 移除 + + + } + > + + + + +
+ ); +}); diff --git a/packages/client/src/schemas/calendar/index.tsx b/packages/client/src/schemas/calendar/index.tsx index 924964846..d98fdaf73 100644 --- a/packages/client/src/schemas/calendar/index.tsx +++ b/packages/client/src/schemas/calendar/index.tsx @@ -11,6 +11,7 @@ import { LeftOutlined, RightOutlined } from '@ant-design/icons'; import { Space, Button, Radio, Select } from 'antd'; import './style2.less'; import { observer, useField } from '@formily/react'; +import { DesignableBar } from './DesignableBar'; const localizer = momentLocalizer(moment); @@ -71,7 +72,7 @@ function Toolbar(props: ToolbarProps) { ); } -export const Calendar = observer((props: any) => { +export const Calendar: any = observer((props: any) => { const field = useField(); return (
@@ -130,3 +131,5 @@ export const Calendar = observer((props: any) => {
); }); + +Calendar.DesignableBar = DesignableBar; diff --git a/packages/client/src/schemas/kanban/DesignableBar.tsx b/packages/client/src/schemas/kanban/DesignableBar.tsx new file mode 100644 index 000000000..e054d28f6 --- /dev/null +++ b/packages/client/src/schemas/kanban/DesignableBar.tsx @@ -0,0 +1,91 @@ +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 } from '../'; +import get from 'lodash/get'; +import { Button, Dropdown, Menu, Space } from 'antd'; +import { MenuOutlined, DragOutlined } from '@ant-design/icons'; +import cls from 'classnames'; +import { 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 { useCollection, useCollectionContext } from '../../constate'; +import { useTable } from '../table'; + +export const DesignableBar = observer((props) => { + const field = useField(); + const { designable, schema, refresh, deepRemove } = useDesignable(); + const [visible, setVisible] = useState(false); + const { dragRef } = useContext(DraggableBlockContext); + const { props: tableProps } = useTable(); + const collectionName = field.componentProps?.collectionName || tableProps?.collectionName; + const { collection } = useCollection({ collectionName }); + return ( +
+
{collection?.title || collection?.name}
+ { + e.stopPropagation(); + }} + className={cls('designable-bar-actions', { active: visible })} + > + + + {dragRef && } + { + setVisible(visible); + }} + overlay={ + + {/* { + field.readPretty = true; + }} + > + 编辑表单配置 + */} + {/* */} + { + const removed = deepRemove(); + // console.log({ removed }) + const last = removed.pop(); + if (isGridRowOrCol(last)) { + await removeSchema(last); + } + }} + > + 移除 + + + } + > + + + + +
+ ); +}); diff --git a/packages/client/src/schemas/kanban/index.tsx b/packages/client/src/schemas/kanban/index.tsx index 121e261c5..1de48be03 100644 --- a/packages/client/src/schemas/kanban/index.tsx +++ b/packages/client/src/schemas/kanban/index.tsx @@ -22,6 +22,7 @@ import { createContext } from 'react'; import { useContext } from 'react'; import { PlusOutlined } from '@ant-design/icons'; import { uid } from '@formily/shared'; +import { DesignableBar } from './DesignableBar'; export function SortableItem(props) { const { @@ -95,109 +96,114 @@ export const Kanban: any = observer(() => { return prev; }, null); return ( -
- { - const source = values.find((item) => item.id === active?.id); - const target = values.find((item) => item.id === over?.id); - if (source && target) { - const fromIndex = values.findIndex( - (item) => item.id === active?.id, - ); - const toIndex = values.findIndex((item) => item.id === over?.id); - // setValues((items) => { - // const fromIndex = items.findIndex( - // (item) => item.id === active?.id, - // ); - // const toIndex = items.findIndex( - // (item) => item.id === over?.id, - // ); - // return arrayMove(items, fromIndex, toIndex); - // }); - field.move(fromIndex, toIndex); - } - }} - onDragOver={({ active, over }) => { - if (!over) { - return; - } - if (active?.id === over?.id) { - return; - } - const source = values.find((item) => item.id === active?.id); - if (source && over?.data?.current?.type === 'column') { - source.type = over.id; - return; - } - console.log('active.id', active.id, over?.data?.current); - const target = values.find((item) => item.id === over?.id); - if (source && target) { - if (source.type !== target.type) { - source.type = target.type; +
+ {/*
+ +
*/} +
+ { + const source = values.find((item) => item.id === active?.id); + const target = values.find((item) => item.id === over?.id); + if (source && target) { + const fromIndex = values.findIndex( + (item) => item.id === active?.id, + ); + const toIndex = values.findIndex((item) => item.id === over?.id); + // setValues((items) => { + // const fromIndex = items.findIndex( + // (item) => item.id === active?.id, + // ); + // const toIndex = items.findIndex( + // (item) => item.id === over?.id, + // ); + // return arrayMove(items, fromIndex, toIndex); + // }); + field.move(fromIndex, toIndex); } - } - }} - > - aaa - - { + if (!over) { + return; + } + if (active?.id === over?.id) { + return; + } + const source = values.find((item) => item.id === active?.id); + if (source && over?.data?.current?.type === 'column') { + source.type = over.id; + return; + } + console.log('active.id', active.id, over?.data?.current); + const target = values.find((item) => item.id === over?.id); + if (source && target) { + if (source.type !== target.type) { + source.type = target.type; + } + } + }} > - {columns.map((column) => ( - -
{column.title}
- aaa + + + {columns.map((column) => ( + - {column.items.map((item) => { - const index = values.findIndex( - (value) => value.id === item.id, - ); - return ( - - {column.title}
+ + {column.items.map((item) => { + const index = values.findIndex( + (value) => value.id === item.id, + ); + return ( + - - - - ); - })} - - - - ))} - - + + + + + ); + })} + + + + ))} + + +
); }); @@ -232,3 +238,5 @@ Kanban.Card = observer((props) => { Kanban.Card.View = observer((props) => { return
{props.children}
; }); + +Kanban.DesignableBar = DesignableBar; diff --git a/packages/client/src/schemas/kanban/style.less b/packages/client/src/schemas/kanban/style.less index 528c9daff..e17a966c6 100644 --- a/packages/client/src/schemas/kanban/style.less +++ b/packages/client/src/schemas/kanban/style.less @@ -2,7 +2,7 @@ position: relative; width: 25vw; background: #f9f9f9; - margin: 0 1%; + margin: 0 12px; padding: 24px; } @@ -14,6 +14,7 @@ .kanban { display: flex; + margin: 0 -12px; } .item { diff --git a/packages/client/src/schemas/table/index.tsx b/packages/client/src/schemas/table/index.tsx index 223ed7859..b1a683716 100644 --- a/packages/client/src/schemas/table/index.tsx +++ b/packages/client/src/schemas/table/index.tsx @@ -374,6 +374,12 @@ const useTableColumns = () => { const columnSchemas = schema.reduceProperties((columns, current) => { if (isColumn(current)) { + if (current['x-hidden']) { + return columns; + } + if (current['x-display'] && current['x-display'] !== 'visible') { + return columns; + } return [...columns, current]; } return [...columns]; @@ -1409,6 +1415,7 @@ Table.Filter.DesignableBar = () => { { + setVisible(false); const values = await FormDialog('修改名称和图标', () => { return ( @@ -1531,6 +1538,7 @@ Table.ExportActionDesignableBar = () => { { + setVisible(false); const values = await FormDialog('修改名称和图标', () => { return ( @@ -1721,6 +1729,7 @@ Table.Action.DesignableBar = () => { { + setVisible(false); const values = await FormDialog('修改名称和图标', () => { return ( @@ -1901,6 +1910,7 @@ Table.Column.DesignableBar = () => { { + setVisible(false); const values = await FormDialog('修改列标题', () => { return ( @@ -1940,7 +1950,6 @@ Table.Column.DesignableBar = () => { key: schema['key'], title: title, }); - setVisible(false); }} > 修改列标题 @@ -1948,14 +1957,20 @@ Table.Column.DesignableBar = () => { { - const s = remove(); const fieldName = schema['x-component-props']?.['fieldName']; displayed.remove(fieldName); - await removeSchema(s); + schema['x-hidden'] = true; + refresh(); + await updateSchema({ + key: schema['key'], + ['x-hidden']: true, + }); + // const s = remove(); + // await removeSchema(s); }} > - 移除 + 隐藏 }