diff --git a/packages/app/src/components/form.fields/draggable-table/index.tsx b/packages/app/src/components/form.fields/draggable-table/index.tsx new file mode 100644 index 000000000..d9957256a --- /dev/null +++ b/packages/app/src/components/form.fields/draggable-table/index.tsx @@ -0,0 +1,86 @@ +import React, { useState } from 'react' +import { connect } from '@formily/react-schema-renderer' +import moment from 'moment' +import { Select, Table } from 'antd' +import get from 'lodash/get'; +import { + mapStyledProps, + mapTextComponent, + compose, + isStr, + isArr +} from '../shared' +import { useRequest } from 'umi'; +import api from '@/api-client'; +import { Spin } from '@nocobase/client' +import { fields2columns, components } from '@/components/views/SortableTable' + +function DraggableTableComponent(props) { + const { value, onChange, disabled, rowKey = 'id', fields = [], resourceName, associatedKey, filter, labelField, valueField = 'id', objectValue, placeholder } = props; + const { data = [], loading = true, mutate } = useRequest(() => { + return api.resource(resourceName).list({ + associatedKey, + filter, + }); + }, { + refreshDeps: [resourceName, associatedKey] + }); + const [selectedRowKeys, setSelectedRowKeys] = useState([]); + const onTableChange = (selectedRowKeys: React.ReactText[]) => { + onChange(selectedRowKeys); + } + const tableProps: any = {}; + tableProps.rowSelection = { + selectedRowKeys: Array.isArray(value) ? value : data.map(item => item[rowKey]), + onChange: onTableChange, + } + const dataSource = data.filter(item => get(item, ['component', 'showInDetail'])); + // const sortIds = get(value, 'sort')||[]; + // let values = []; + // sortIds.forEach(id => { + // const item = dataSource.find(item => item[rowKey] === id); + // if (item) { + // values.push(item); + // } + // }); + // if (values.length === 0) { + // values = dataSource; + // } + return ( + <> + { + // onChange({ + // sort: values.list.map(item => item[rowKey]), + // selectedRowKeys: get(value, 'selectedRowKeys')||data.map(item => item[rowKey]), + // }); + // mutate(values.list); + // // setDataSource(values.list); + // console.log('mutate', values); + // }, + // rowKey, + // onMoved: async ({resourceKey, target}) => { + // } + // })} + /> + + ); +} + +export const DraggableTable = connect({ + getProps: mapStyledProps, + getComponent: mapTextComponent, +})(DraggableTableComponent) + +export default DraggableTable diff --git a/packages/app/src/components/form.fields/registry.ts b/packages/app/src/components/form.fields/registry.ts index 8e0af0b6a..4206a3734 100644 --- a/packages/app/src/components/form.fields/registry.ts +++ b/packages/app/src/components/form.fields/registry.ts @@ -20,6 +20,7 @@ import { SubTable } from './sub-table' import { Icon } from './icons' import { ColorSelect } from './color-select' import { Permissions } from './permissions' +import { DraggableTable } from './draggable-table' export const setup = () => { registerFormFields({ @@ -53,6 +54,7 @@ export const setup = () => { drawerSelect: DrawerSelect, colorSelect: ColorSelect, subTable: SubTable, + draggableTable: DraggableTable, 'permissions.actions': Permissions.Actions, 'permissions.fields': Permissions.Fields, 'permissions.tabs': Permissions.Tabs, diff --git a/packages/app/src/components/views/Details.tsx b/packages/app/src/components/views/Details.tsx index 83038f8b7..7d037d00e 100644 --- a/packages/app/src/components/views/Details.tsx +++ b/packages/app/src/components/views/Details.tsx @@ -16,6 +16,7 @@ configResponsive({ export function Details(props: any) { const dom = document.querySelector('body'); const responsive = useResponsive(); + console.log('Details.props', props) const { activeTab = {}, @@ -45,6 +46,7 @@ export function Details(props: any) { } } console.log(props); + const { displayFields = [] } = activeTab; return ( {fields.map((field: any) => { + if (Array.isArray(displayFields) && displayFields.length && displayFields.indexOf(field.id) === -1) { + return null; + } return ( diff --git a/packages/plugin-collections/src/collections/tabs.ts b/packages/plugin-collections/src/collections/tabs.ts index ef3a51859..c131a451a 100644 --- a/packages/plugin-collections/src/collections/tabs.ts +++ b/packages/plugin-collections/src/collections/tabs.ts @@ -74,6 +74,11 @@ export default { target: "associationField", condition: "{{ $self.value === 'association' }}" }, + { + type: "value:visible", + target: "displayFields", + condition: "{{ $self.value === 'details' }}", + }, // { // type: "value:schema", // target: "association", @@ -84,6 +89,16 @@ export default { // }, // }, // }, + { + type: "value:schema", + target: "displayFields", + condition: "{{ $self.value === 'details' }}", + schema: { + "x-component-props": { + associatedKey: "{{ $form.values && $form.values.associatedKey }}" + }, + }, + }, { type: "value:schema", target: "associationField", @@ -123,6 +138,7 @@ export default { target: 'fields', title: '相关数据表', labelField: 'title', + required: true, // valueField: 'name', component: { type: 'remoteSelect', @@ -156,6 +172,43 @@ export default { ], }, }, + { + interface: 'json', + type: 'json', + name: 'displayFields', + title: '显示的字段', + labelField: 'title', + // valueField: 'name', + component: { + type: 'draggableTable', + showInDetail: true, + showInForm: true, + 'x-component-props': { + resourceName: 'collections.fields', + labelField: 'title', + valueField: 'name', + showInDetail: true, + fields: [ + // { + // interface: 'sort', + // name: 'sort', + // title: '排序', + // type: 'sort', + // dataIndex: ['sort'], + // className: 'drag-visible', + // }, + { + interface: 'string', + name: 'title', + title: '字段名称', + type: 'string', + className: 'drag-visible', + dataIndex: ['title'], + } + ], + }, + }, + }, { interface: 'string', type: 'string',