feat: add drawerSelect component for linkTo

This commit is contained in:
chenos 2020-12-22 19:12:30 +08:00
parent 8d3e94e86b
commit 0edb148db2
7 changed files with 132 additions and 21 deletions

View File

@ -18,3 +18,4 @@
/src/.umi-production /src/.umi-production
/src/.umi-test /src/.umi-test
/.env.local /.env.local
report.*.json

View File

@ -1,7 +1,6 @@
import React from 'react' import React, { useState } from 'react'
import { connect } from '@formily/react-schema-renderer' import { connect } from '@formily/react-schema-renderer'
import moment from 'moment' import { Select, Drawer, Button } from 'antd'
import { Select } from 'antd'
import { import {
mapStyledProps, mapStyledProps,
mapTextComponent, mapTextComponent,
@ -9,14 +8,93 @@ import {
isStr, isStr,
isArr isArr
} from '../shared' } 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) { 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 ( return (
<> <>
<Select> <Select
<Select.Option value={'aaa'}>aaa</Select.Option> open={false}
</Select> mode={multiple ? 'tags' : undefined}
labelInValue
value={options}
notFoundContent={''}
onChange={(data) => {
setOptions(data);
if (Array.isArray(data)) {
const srks = data.map(item => item.value);
onChange(srks);
setSelectedRowKeys(srks);
console.log('datadatadatadata', {data, srks});
} else if (data && typeof data === 'object') {
onChange(data.value);
setSelectedRowKeys([data.value]);
} else {
onChange(data);
setSelectedRowKeys([]);
}
}}
onClick={() => {
setVisible(true);
}}
></Select>
<Drawer
width={'40%'}
title={'关联数据'}
visible={visible}
bodyStyle={{padding: 0}}
onClose={() => {
setVisible(false);
}}
footer={[
<Button type={'primary'} onClick={() => {
setOptions(selectedRows);
// console.log('valuevaluevaluevaluevaluevalue', {selectedRowKeys});
onChange(multiple ? selectedRowKeys : selectedRowKeys.shift());
setVisible(false);
}}></Button>
]}
>
<ViewFactory
multiple={multiple}
resourceName={target}
isFieldComponent={true}
selectedRowKeys={selectedRowKeys}
onSelected={(values) => {
const [selectedKeys, selectedValue] = transform({value: values, multiple, labelField, valueField });
setSelectedRows(selectedValue);
setSelectedRowKeys(selectedKeys);
// console.log('valuevaluevaluevaluevaluevalue', {values, selectedKeys, selectedValue});
}}
// associatedKey={}
associatedName={associatedName}
viewName={'table'}
/>
</Drawer>
</> </>
); );
} }

View File

@ -15,6 +15,7 @@ import { Rating } from './rating'
import { Upload } from './upload' import { Upload } from './upload'
import { Filter } from './filter' import { Filter } from './filter'
import { RemoteSelect } from './remote-select' import { RemoteSelect } from './remote-select'
import { DrawerSelect } from './drawer-select'
import { SubTable } from './sub-table' import { SubTable } from './sub-table'
import { Icon } from './icons' import { Icon } from './icons'
@ -47,7 +48,7 @@ export const setup = () => {
upload: Upload, upload: Upload,
filter: Filter, filter: Filter,
remoteSelect: RemoteSelect, remoteSelect: RemoteSelect,
drawerSelect: RemoteSelect, drawerSelect: DrawerSelect,
subTable: SubTable, subTable: SubTable,
}) })
} }

View File

@ -1,4 +1,4 @@
import React from 'react' import React, { useEffect } from 'react'
import { connect } from '@formily/react-schema-renderer' import { connect } from '@formily/react-schema-renderer'
import moment from 'moment' import moment from 'moment'
import { Select } from 'antd' import { Select } from 'antd'
@ -11,18 +11,21 @@ import {
} from '../shared' } from '../shared'
import { useRequest } from 'umi'; import { useRequest } from 'umi';
import api from '@/api-client'; import api from '@/api-client';
import { Spin } from '@nocobase/client'
function RemoteSelectComponent(props) { function RemoteSelectComponent(props) {
const { value, onChange, resourceName, associatedKey, labelField, valueField } = props; const { value, onChange, disabled, resourceName, associatedKey, labelField, valueField } = props;
const { data = [], loading } = useRequest(() => api.resource(resourceName).list({ const { data = [], loading = true } = useRequest(() => {
associatedKey, return api.resource(resourceName).list({
}), { associatedKey,
});
}, {
refreshDeps: [resourceName, associatedKey] refreshDeps: [resourceName, associatedKey]
}); });
return ( return (
<> <>
<Select allowClear loading={loading} value={value} onChange={onChange}> <Select disabled={disabled} notFoundContent={loading ? <Spin/> : undefined} allowClear loading={loading} value={value} onChange={onChange}>
{data.map(item => (<Select.Option value={item[valueField]}>{item[valueField]} - {item[labelField]}</Select.Option>))} {!loading && data.map(item => (<Select.Option value={item[valueField]}>{item[labelField]}</Select.Option>))}
</Select> </Select>
</> </>
); );

View File

@ -24,6 +24,9 @@ export function SimpleTable(props: SimpleTableProps) {
resourceName, resourceName,
associatedName, associatedName,
associatedKey, associatedKey,
isFieldComponent,
onSelected,
selectedRowKeys: srk,
} = props; } = props;
const { rowKey = 'id', name: viewName, actionDefaultParams = {}, fields = [], rowViewName, actions = [], paginated = true, defaultPerPage = 10 } = schema; const { rowKey = 'id', name: viewName, actionDefaultParams = {}, fields = [], rowViewName, actions = [], paginated = true, defaultPerPage = 10 } = schema;
const { sourceKey = 'id' } = activeTab.field||{}; const { sourceKey = 'id' } = activeTab.field||{};
@ -53,10 +56,14 @@ export function SimpleTable(props: SimpleTableProps) {
defaultPageSize: defaultPerPage, defaultPageSize: defaultPerPage,
}); });
console.log(schema, data); console.log(schema, data);
const [selectedRowKeys, setSelectedRowKeys] = useState([]); const [selectedRowKeys, setSelectedRowKeys] = useState(srk||[]);
const onChange = (selectedRowKeys: React.ReactText[]) => { const onChange = (selectedRowKeys: React.ReactText[], selectedRows: React.ReactText[]) => {
setSelectedRowKeys(selectedRowKeys); setSelectedRowKeys(selectedRowKeys);
onSelected && onSelected(selectedRows);
} }
useEffect(() => {
setSelectedRowKeys(srk);
}, [srk]);
const tableProps: any = {}; const tableProps: any = {};
if (actions.length) { if (actions.length) {
tableProps.rowSelection = { tableProps.rowSelection = {
@ -130,6 +137,9 @@ export function SimpleTable(props: SimpleTableProps) {
})} })}
onRow={(record) => ({ onRow={(record) => ({
onClick: () => { onClick: () => {
if (isFieldComponent) {
return;
}
drawerRef.current.setVisible(true); drawerRef.current.setVisible(true);
drawerRef.current.getData(record[rowKey]); drawerRef.current.getData(record[rowKey]);
} }

View File

@ -1,4 +1,4 @@
import React, { useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Table as AntdTable, Card, Pagination } from 'antd'; import { Table as AntdTable, Card, Pagination } from 'antd';
import { redirectTo } from '@/components/pages/CollectionLoader/utils'; import { redirectTo } from '@/components/pages/CollectionLoader/utils';
import { Actions } from '@/components/actions'; import { Actions } from '@/components/actions';
@ -22,6 +22,9 @@ export function Table(props: TableProps) {
resourceName, resourceName,
associatedName, associatedName,
associatedKey, associatedKey,
isFieldComponent,
onSelected,
selectedRowKeys: srk,
} = props; } = props;
const { name: viewName, fields, actionDefaultParams = {}, defaultTabName, rowKey = 'id', actions = [], paginated = true, defaultPerPage = 10 } = schema; const { name: viewName, fields, actionDefaultParams = {}, defaultTabName, rowKey = 'id', actions = [], paginated = true, defaultPerPage = 10 } = schema;
// const { data, mutate } = useRequest(() => api.resource(name).list({ // const { data, mutate } = useRequest(() => api.resource(name).list({
@ -55,10 +58,15 @@ export function Table(props: TableProps) {
}); });
const { sourceKey = 'id' } = activeTab.field||{}; const { sourceKey = 'id' } = activeTab.field||{};
console.log(props); console.log(props);
const [selectedRowKeys, setSelectedRowKeys] = useState([]); const [selectedRowKeys, setSelectedRowKeys] = useState(srk||[]);
const onChange = (selectedRowKeys: React.ReactText[]) => { const onChange = (selectedRowKeys: React.ReactText[], selectedRows: React.ReactText[]) => {
setSelectedRowKeys(selectedRowKeys); setSelectedRowKeys(selectedRowKeys);
onSelected && onSelected(selectedRows);
} }
useEffect(() => {
setSelectedRowKeys(srk);
}, [srk]);
console.log(srk);
const tableProps: any = {}; const tableProps: any = {};
if (actions.length) { if (actions.length) {
tableProps.rowSelection = { tableProps.rowSelection = {
@ -121,6 +129,9 @@ export function Table(props: TableProps) {
})} })}
onRow={(data) => ({ onRow={(data) => ({
onClick: () => { onClick: () => {
if (isFieldComponent) {
return;
}
redirectTo({ redirectTo({
...props.match.params, ...props.match.params,
[activeTab ? 'newItem' : 'lastItem']: { [activeTab ? 'newItem' : 'lastItem']: {

View File

@ -76,6 +76,12 @@ const transforms = {
set(prop, 'x-component-props.children', prop.title); set(prop, 'x-component-props.children', prop.title);
delete 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') { if (interfaceType === 'multipleSelect') {
set(prop, 'x-component-props.mode', 'multiple'); set(prop, 'x-component-props.mode', 'multiple');
} }
@ -178,6 +184,7 @@ export default async (ctx, next) => {
}); });
view.setDataValue('defaultTabName', get(defaultTabs, [0, 'name'])); view.setDataValue('defaultTabName', get(defaultTabs, [0, 'name']));
} }
if (view.get('template') === 'SimpleTable') { if (view.get('template') === 'SimpleTable') {
view.setDataValue('rowViewName', 'form'); view.setDataValue('rowViewName', 'form');
} }
@ -196,7 +203,7 @@ export default async (ctx, next) => {
const viewType = view.get('type'); const viewType = view.get('type');
const actionDefaultParams:any = {}; const actionDefaultParams:any = {};
const appends = fields.filter(field => { const appends = fields.filter(field => {
if (field.get('interface') !== 'subTable') { if (!['subTable', 'linkTo'].includes(field.get('interface'))) {
return false; return false;
} }
if (viewType === 'table') { if (viewType === 'table') {