feat: table supports row drag and drop sorting

This commit is contained in:
chenos 2022-03-07 11:31:40 +08:00
parent b1aee77d10
commit 9ff0361336
5 changed files with 49 additions and 12 deletions

View File

@ -1,3 +1,4 @@
import { useField } from '@formily/react';
import { Result } from 'ahooks/lib/useRequest/src/types';
import React, { createContext, useContext, useEffect } from 'react';
import { useCollectionManager } from '.';
@ -5,20 +6,21 @@ import { CollectionProvider, useRecord } from '..';
import { useAPIClient, useRequest } from '../api-client';
export const ResourceActionContext = createContext<
Result<any, any> & { state?: any; setState?: any; defaultRequest?: any }
Result<any, any> & { state?: any; setState?: any; dragSort?: boolean; defaultRequest?: any }
>(null);
interface ResourceActionProviderProps {
type?: 'association' | 'collection';
collection?: any;
request?: any;
dragSort?: boolean;
uid?: string;
}
const ResourceContext = createContext<any>(null);
const CollectionResourceActionProvider = (props) => {
let { collection, request, uid } = props;
let { collection, request, uid, dragSort } = props;
const api = useAPIClient();
const record = useRecord();
const actionName = request?.action;
@ -33,6 +35,7 @@ const CollectionResourceActionProvider = (props) => {
...others,
...request?.params,
appends: collection.fields.filter((field) => field.target).map((field) => field.name),
sort: dragSort ? [collection.sortable === true ? 'sort' : collection.sortable] : request?.params?.sort,
},
},
{ uid },
@ -40,7 +43,7 @@ const CollectionResourceActionProvider = (props) => {
const resource = api.resource(request.resource);
return (
<ResourceContext.Provider value={{ type: 'collection', resource, collection }}>
<ResourceActionContext.Provider value={{ ...service, defaultRequest: request }}>
<ResourceActionContext.Provider value={{ ...service, defaultRequest: request, dragSort }}>
<CollectionProvider collection={collection}>{props.children}</CollectionProvider>
</ResourceActionContext.Provider>
</ResourceContext.Provider>
@ -48,7 +51,7 @@ const CollectionResourceActionProvider = (props) => {
};
const AssociationResourceActionProvider = (props) => {
let { collection, association, request, uid } = props;
let { collection, association, request, uid, dragSort } = props;
const api = useAPIClient();
const record = useRecord();
const resourceOf = record[association.sourceKey];
@ -69,7 +72,7 @@ const AssociationResourceActionProvider = (props) => {
const resource = api.resource(request.resource, resourceOf);
return (
<ResourceContext.Provider value={{ type: 'association', resource, association }}>
<ResourceActionContext.Provider value={{ ...service, defaultRequest: request }}>
<ResourceActionContext.Provider value={{ ...service, defaultRequest: request, dragSort }}>
<CollectionProvider collection={collection}>{props.children}</CollectionProvider>
</ResourceActionContext.Provider>
</ResourceContext.Provider>
@ -97,9 +100,11 @@ export const useResourceActionContext = () => {
export const useDataSourceFromRAC = (options: any) => {
const service = useContext(ResourceActionContext);
const field = useField();
useEffect(() => {
if (!service.loading) {
options?.onSuccess(service.data);
field.componentProps.dragSort = !!service.dragSort;
}
}, [service.loading]);
return service;

View File

@ -148,11 +148,11 @@ export const useMoveAction = () => {
const { refresh } = useResourceActionContext();
return {
async move(from, to) {
// await resource.move({
// sourceId: from.id,
// targetId: to.id,
// });
// refresh();
await resource.move({
sourceId: from.id,
targetId: to.id,
});
refresh();
},
};
};

View File

@ -13,8 +13,24 @@ export const TableVoidDesigner = () => {
const ctx = useResourceActionContext();
const { dn } = useDesignable();
const defaultFilter = fieldSchema?.['x-decorator-props']?.request?.params?.filter || {};
const defaultSort = fieldSchema?.['x-decorator-props']?.request?.params?.sort || [];
return (
<GeneralSchemaDesigner title={title || name}>
<SchemaSettings.SwitchItem
title={'启用手动排序'}
checked={field.decoratorProps.dragSort}
onChange={(dragSort) => {
field.decoratorProps.dragSort = dragSort;
fieldSchema['x-decorator-props'].dragSort = dragSort;
ctx.run({ ...ctx.params?.[0], sort: defaultSort });
dn.emit('patch', {
schema: {
['x-uid']: fieldSchema['x-uid'],
'x-decorator-props': fieldSchema['x-decorator-props'],
},
});
}}
/>
<SchemaSettings.ModalItem
title={'设置数据范围'}
schema={

View File

@ -12,6 +12,7 @@ const createSchema = (collectionName) => {
'x-decorator': 'ResourceActionProvider',
'x-decorator-props': {
collection: collectionName,
dragSort: false,
request: {
resource: collectionName,
action: 'list',

View File

@ -2,7 +2,7 @@ import { FormDialog, FormLayout } from '@formily/antd';
import { GeneralField } from '@formily/core';
import { ISchema, Schema, SchemaOptionsContext } from '@formily/react';
import { uid } from '@formily/shared';
import { Dropdown, Menu, MenuItemProps, Modal, Select } from 'antd';
import { Dropdown, Menu, MenuItemProps, Modal, Select, Switch } from 'antd';
import React, { createContext, useContext, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { ActionContext, Designable, SchemaComponent, SchemaComponentOptions, useActionContext } from '..';
@ -152,7 +152,22 @@ SchemaSettings.SelectItem = (props) => {
};
SchemaSettings.SwitchItem = (props) => {
return null;
const { title, onChange, ...others } = props;
const [checked, setChecked] = useState(!!props.checked);
return (
<SchemaSettings.Item
{...others}
onClick={() => {
onChange?.(!checked);
setChecked(!checked);
}}
>
<div style={{ alignItems: 'center', display: 'flex', justifyContent: 'space-between' }}>
{title}
<Switch size={'small'} checked={checked} />
</div>
</SchemaSettings.Item>
);
};
SchemaSettings.PopupItem = (props) => {