diff --git a/packages/app/.gitignore b/packages/app/.gitignore index e9b162c8e..88ce629c4 100644 --- a/packages/app/.gitignore +++ b/packages/app/.gitignore @@ -18,3 +18,4 @@ /src/.umi-production /src/.umi-test /.env.local +report.*.json \ No newline at end of file diff --git a/packages/app/src/components/form.fields/drawer-select/index.tsx b/packages/app/src/components/form.fields/drawer-select/index.tsx index 2db84c974..f36bf752f 100644 --- a/packages/app/src/components/form.fields/drawer-select/index.tsx +++ b/packages/app/src/components/form.fields/drawer-select/index.tsx @@ -1,7 +1,6 @@ -import React from 'react' +import React, { useState } from 'react' import { connect } from '@formily/react-schema-renderer' -import moment from 'moment' -import { Select } from 'antd' +import { Select, Drawer, Button } from 'antd' import { mapStyledProps, mapTextComponent, @@ -9,14 +8,93 @@ import { isStr, isArr } from '../shared' +import ViewFactory from '@/components/views' + +function transform({value, multiple, labelField, valueField = 'id'}) { + let selectedKeys = []; + let selectedValue = []; + const values = Array.isArray(value) ? value : []; + selectedKeys = values.map(item => item[valueField]); + selectedValue = values.map(item => { + return { + value: item[valueField], + label: item[labelField], + } + }); + if (!multiple) { + return [selectedKeys.shift(), selectedValue.shift()]; + } + return [selectedKeys, selectedValue]; +} function DrawerSelectComponent(props) { - console.log(props); + const { target, multiple, associatedName, labelField, valueField = 'id', value, onChange } = props; + const [selectedKeys, selectedValue] = transform({value, multiple, labelField, valueField }); + const [visible, setVisible] = useState(false); + const [selectedRowKeys, setSelectedRowKeys] = useState(selectedKeys); + const [selectedRows, setSelectedRows] = useState(selectedValue); + const [options, setOptions] = useState(selectedValue); + // console.log('valuevaluevaluevaluevaluevalue', value); return ( <> - + + { + setVisible(false); + }} + footer={[ + + ]} + > + { + const [selectedKeys, selectedValue] = transform({value: values, multiple, labelField, valueField }); + setSelectedRows(selectedValue); + setSelectedRowKeys(selectedKeys); + // console.log('valuevaluevaluevaluevaluevalue', {values, selectedKeys, selectedValue}); + }} + // associatedKey={} + associatedName={associatedName} + viewName={'table'} + /> + ); } diff --git a/packages/app/src/components/form.fields/registry.ts b/packages/app/src/components/form.fields/registry.ts index 5cb3a86a5..7139ef068 100644 --- a/packages/app/src/components/form.fields/registry.ts +++ b/packages/app/src/components/form.fields/registry.ts @@ -15,6 +15,7 @@ import { Rating } from './rating' import { Upload } from './upload' import { Filter } from './filter' import { RemoteSelect } from './remote-select' +import { DrawerSelect } from './drawer-select' import { SubTable } from './sub-table' import { Icon } from './icons' @@ -47,7 +48,7 @@ export const setup = () => { upload: Upload, filter: Filter, remoteSelect: RemoteSelect, - drawerSelect: RemoteSelect, + drawerSelect: DrawerSelect, subTable: SubTable, }) } diff --git a/packages/app/src/components/form.fields/remote-select/index.tsx b/packages/app/src/components/form.fields/remote-select/index.tsx index 3b0efc13b..07bbaa1dc 100644 --- a/packages/app/src/components/form.fields/remote-select/index.tsx +++ b/packages/app/src/components/form.fields/remote-select/index.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useEffect } from 'react' import { connect } from '@formily/react-schema-renderer' import moment from 'moment' import { Select } from 'antd' @@ -11,18 +11,21 @@ import { } from '../shared' import { useRequest } from 'umi'; import api from '@/api-client'; +import { Spin } from '@nocobase/client' function RemoteSelectComponent(props) { - const { value, onChange, resourceName, associatedKey, labelField, valueField } = props; - const { data = [], loading } = useRequest(() => api.resource(resourceName).list({ - associatedKey, - }), { + const { value, onChange, disabled, resourceName, associatedKey, labelField, valueField } = props; + const { data = [], loading = true } = useRequest(() => { + return api.resource(resourceName).list({ + associatedKey, + }); + }, { refreshDeps: [resourceName, associatedKey] }); return ( <> - : undefined} allowClear loading={loading} value={value} onChange={onChange}> + {!loading && data.map(item => ({item[labelField]}))} ); diff --git a/packages/app/src/components/views/SimpleTable.tsx b/packages/app/src/components/views/SimpleTable.tsx index 5e79772f0..fde68097f 100644 --- a/packages/app/src/components/views/SimpleTable.tsx +++ b/packages/app/src/components/views/SimpleTable.tsx @@ -24,6 +24,9 @@ export function SimpleTable(props: SimpleTableProps) { resourceName, associatedName, associatedKey, + isFieldComponent, + onSelected, + selectedRowKeys: srk, } = props; const { rowKey = 'id', name: viewName, actionDefaultParams = {}, fields = [], rowViewName, actions = [], paginated = true, defaultPerPage = 10 } = schema; const { sourceKey = 'id' } = activeTab.field||{}; @@ -53,10 +56,14 @@ export function SimpleTable(props: SimpleTableProps) { defaultPageSize: defaultPerPage, }); console.log(schema, data); - const [selectedRowKeys, setSelectedRowKeys] = useState([]); - const onChange = (selectedRowKeys: React.ReactText[]) => { + const [selectedRowKeys, setSelectedRowKeys] = useState(srk||[]); + const onChange = (selectedRowKeys: React.ReactText[], selectedRows: React.ReactText[]) => { setSelectedRowKeys(selectedRowKeys); + onSelected && onSelected(selectedRows); } + useEffect(() => { + setSelectedRowKeys(srk); + }, [srk]); const tableProps: any = {}; if (actions.length) { tableProps.rowSelection = { @@ -130,6 +137,9 @@ export function SimpleTable(props: SimpleTableProps) { })} onRow={(record) => ({ onClick: () => { + if (isFieldComponent) { + return; + } drawerRef.current.setVisible(true); drawerRef.current.getData(record[rowKey]); } diff --git a/packages/app/src/components/views/Table.tsx b/packages/app/src/components/views/Table.tsx index 66eaf7449..2bb18adc8 100644 --- a/packages/app/src/components/views/Table.tsx +++ b/packages/app/src/components/views/Table.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { Table as AntdTable, Card, Pagination } from 'antd'; import { redirectTo } from '@/components/pages/CollectionLoader/utils'; import { Actions } from '@/components/actions'; @@ -22,6 +22,9 @@ export function Table(props: TableProps) { resourceName, associatedName, associatedKey, + isFieldComponent, + onSelected, + selectedRowKeys: srk, } = props; const { name: viewName, fields, actionDefaultParams = {}, defaultTabName, rowKey = 'id', actions = [], paginated = true, defaultPerPage = 10 } = schema; // const { data, mutate } = useRequest(() => api.resource(name).list({ @@ -55,10 +58,15 @@ export function Table(props: TableProps) { }); const { sourceKey = 'id' } = activeTab.field||{}; console.log(props); - const [selectedRowKeys, setSelectedRowKeys] = useState([]); - const onChange = (selectedRowKeys: React.ReactText[]) => { + const [selectedRowKeys, setSelectedRowKeys] = useState(srk||[]); + const onChange = (selectedRowKeys: React.ReactText[], selectedRows: React.ReactText[]) => { setSelectedRowKeys(selectedRowKeys); + onSelected && onSelected(selectedRows); } + useEffect(() => { + setSelectedRowKeys(srk); + }, [srk]); + console.log(srk); const tableProps: any = {}; if (actions.length) { tableProps.rowSelection = { @@ -121,6 +129,9 @@ export function Table(props: TableProps) { })} onRow={(data) => ({ onClick: () => { + if (isFieldComponent) { + return; + } redirectTo({ ...props.match.params, [activeTab ? 'newItem' : 'lastItem']: { diff --git a/packages/plugin-pages/src/actions/getView.ts b/packages/plugin-pages/src/actions/getView.ts index 68c3ee923..749a3ec9a 100644 --- a/packages/plugin-pages/src/actions/getView.ts +++ b/packages/plugin-pages/src/actions/getView.ts @@ -76,6 +76,12 @@ const transforms = { set(prop, 'x-component-props.children', prop.title); delete prop.title; } + if (interfaceType === 'linkTo') { + set(prop, 'x-component-props.associatedName', field.get('collection_name')); + set(prop, 'x-component-props.target', field.get('target')); + set(prop, 'x-component-props.multiple', field.get('multiple')); + set(prop, 'x-component-props.labelField', field.get('labelField')); + } if (interfaceType === 'multipleSelect') { set(prop, 'x-component-props.mode', 'multiple'); } @@ -178,6 +184,7 @@ export default async (ctx, next) => { }); view.setDataValue('defaultTabName', get(defaultTabs, [0, 'name'])); } + if (view.get('template') === 'SimpleTable') { view.setDataValue('rowViewName', 'form'); } @@ -196,7 +203,7 @@ export default async (ctx, next) => { const viewType = view.get('type'); const actionDefaultParams:any = {}; const appends = fields.filter(field => { - if (field.get('interface') !== 'subTable') { + if (!['subTable', 'linkTo'].includes(field.get('interface'))) { return false; } if (viewType === 'table') {