feat: table supports row drag and drop sorting
This commit is contained in:
parent
b1aee77d10
commit
9ff0361336
@ -1,3 +1,4 @@
|
|||||||
|
import { useField } from '@formily/react';
|
||||||
import { Result } from 'ahooks/lib/useRequest/src/types';
|
import { Result } from 'ahooks/lib/useRequest/src/types';
|
||||||
import React, { createContext, useContext, useEffect } from 'react';
|
import React, { createContext, useContext, useEffect } from 'react';
|
||||||
import { useCollectionManager } from '.';
|
import { useCollectionManager } from '.';
|
||||||
@ -5,20 +6,21 @@ import { CollectionProvider, useRecord } from '..';
|
|||||||
import { useAPIClient, useRequest } from '../api-client';
|
import { useAPIClient, useRequest } from '../api-client';
|
||||||
|
|
||||||
export const ResourceActionContext = createContext<
|
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);
|
>(null);
|
||||||
|
|
||||||
interface ResourceActionProviderProps {
|
interface ResourceActionProviderProps {
|
||||||
type?: 'association' | 'collection';
|
type?: 'association' | 'collection';
|
||||||
collection?: any;
|
collection?: any;
|
||||||
request?: any;
|
request?: any;
|
||||||
|
dragSort?: boolean;
|
||||||
uid?: string;
|
uid?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ResourceContext = createContext<any>(null);
|
const ResourceContext = createContext<any>(null);
|
||||||
|
|
||||||
const CollectionResourceActionProvider = (props) => {
|
const CollectionResourceActionProvider = (props) => {
|
||||||
let { collection, request, uid } = props;
|
let { collection, request, uid, dragSort } = props;
|
||||||
const api = useAPIClient();
|
const api = useAPIClient();
|
||||||
const record = useRecord();
|
const record = useRecord();
|
||||||
const actionName = request?.action;
|
const actionName = request?.action;
|
||||||
@ -33,6 +35,7 @@ const CollectionResourceActionProvider = (props) => {
|
|||||||
...others,
|
...others,
|
||||||
...request?.params,
|
...request?.params,
|
||||||
appends: collection.fields.filter((field) => field.target).map((field) => field.name),
|
appends: collection.fields.filter((field) => field.target).map((field) => field.name),
|
||||||
|
sort: dragSort ? [collection.sortable === true ? 'sort' : collection.sortable] : request?.params?.sort,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ uid },
|
{ uid },
|
||||||
@ -40,7 +43,7 @@ const CollectionResourceActionProvider = (props) => {
|
|||||||
const resource = api.resource(request.resource);
|
const resource = api.resource(request.resource);
|
||||||
return (
|
return (
|
||||||
<ResourceContext.Provider value={{ type: 'collection', resource, collection }}>
|
<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>
|
<CollectionProvider collection={collection}>{props.children}</CollectionProvider>
|
||||||
</ResourceActionContext.Provider>
|
</ResourceActionContext.Provider>
|
||||||
</ResourceContext.Provider>
|
</ResourceContext.Provider>
|
||||||
@ -48,7 +51,7 @@ const CollectionResourceActionProvider = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const AssociationResourceActionProvider = (props) => {
|
const AssociationResourceActionProvider = (props) => {
|
||||||
let { collection, association, request, uid } = props;
|
let { collection, association, request, uid, dragSort } = props;
|
||||||
const api = useAPIClient();
|
const api = useAPIClient();
|
||||||
const record = useRecord();
|
const record = useRecord();
|
||||||
const resourceOf = record[association.sourceKey];
|
const resourceOf = record[association.sourceKey];
|
||||||
@ -69,7 +72,7 @@ const AssociationResourceActionProvider = (props) => {
|
|||||||
const resource = api.resource(request.resource, resourceOf);
|
const resource = api.resource(request.resource, resourceOf);
|
||||||
return (
|
return (
|
||||||
<ResourceContext.Provider value={{ type: 'association', resource, association }}>
|
<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>
|
<CollectionProvider collection={collection}>{props.children}</CollectionProvider>
|
||||||
</ResourceActionContext.Provider>
|
</ResourceActionContext.Provider>
|
||||||
</ResourceContext.Provider>
|
</ResourceContext.Provider>
|
||||||
@ -97,9 +100,11 @@ export const useResourceActionContext = () => {
|
|||||||
|
|
||||||
export const useDataSourceFromRAC = (options: any) => {
|
export const useDataSourceFromRAC = (options: any) => {
|
||||||
const service = useContext(ResourceActionContext);
|
const service = useContext(ResourceActionContext);
|
||||||
|
const field = useField();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!service.loading) {
|
if (!service.loading) {
|
||||||
options?.onSuccess(service.data);
|
options?.onSuccess(service.data);
|
||||||
|
field.componentProps.dragSort = !!service.dragSort;
|
||||||
}
|
}
|
||||||
}, [service.loading]);
|
}, [service.loading]);
|
||||||
return service;
|
return service;
|
||||||
|
@ -148,11 +148,11 @@ export const useMoveAction = () => {
|
|||||||
const { refresh } = useResourceActionContext();
|
const { refresh } = useResourceActionContext();
|
||||||
return {
|
return {
|
||||||
async move(from, to) {
|
async move(from, to) {
|
||||||
// await resource.move({
|
await resource.move({
|
||||||
// sourceId: from.id,
|
sourceId: from.id,
|
||||||
// targetId: to.id,
|
targetId: to.id,
|
||||||
// });
|
});
|
||||||
// refresh();
|
refresh();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -13,8 +13,24 @@ export const TableVoidDesigner = () => {
|
|||||||
const ctx = useResourceActionContext();
|
const ctx = useResourceActionContext();
|
||||||
const { dn } = useDesignable();
|
const { dn } = useDesignable();
|
||||||
const defaultFilter = fieldSchema?.['x-decorator-props']?.request?.params?.filter || {};
|
const defaultFilter = fieldSchema?.['x-decorator-props']?.request?.params?.filter || {};
|
||||||
|
const defaultSort = fieldSchema?.['x-decorator-props']?.request?.params?.sort || [];
|
||||||
return (
|
return (
|
||||||
<GeneralSchemaDesigner title={title || name}>
|
<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
|
<SchemaSettings.ModalItem
|
||||||
title={'设置数据范围'}
|
title={'设置数据范围'}
|
||||||
schema={
|
schema={
|
||||||
|
@ -12,6 +12,7 @@ const createSchema = (collectionName) => {
|
|||||||
'x-decorator': 'ResourceActionProvider',
|
'x-decorator': 'ResourceActionProvider',
|
||||||
'x-decorator-props': {
|
'x-decorator-props': {
|
||||||
collection: collectionName,
|
collection: collectionName,
|
||||||
|
dragSort: false,
|
||||||
request: {
|
request: {
|
||||||
resource: collectionName,
|
resource: collectionName,
|
||||||
action: 'list',
|
action: 'list',
|
||||||
|
@ -2,7 +2,7 @@ import { FormDialog, FormLayout } from '@formily/antd';
|
|||||||
import { GeneralField } from '@formily/core';
|
import { GeneralField } from '@formily/core';
|
||||||
import { ISchema, Schema, SchemaOptionsContext } from '@formily/react';
|
import { ISchema, Schema, SchemaOptionsContext } from '@formily/react';
|
||||||
import { uid } from '@formily/shared';
|
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 React, { createContext, useContext, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ActionContext, Designable, SchemaComponent, SchemaComponentOptions, useActionContext } from '..';
|
import { ActionContext, Designable, SchemaComponent, SchemaComponentOptions, useActionContext } from '..';
|
||||||
@ -152,7 +152,22 @@ SchemaSettings.SelectItem = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SchemaSettings.SwitchItem = (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) => {
|
SchemaSettings.PopupItem = (props) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user