mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-07 14:39:25 +08:00
* chore(versions): 😊 publish v1.6.0-alpha.24 * chore(versions): 😊 publish v1.6.0-alpha.25 * feat: support extending frontend filter operators (#6085) * feat: operator extension * fix: bug * refactor: code improve * fix: jsonLogic --------- Co-authored-by: chenos <chenlinxh@gmail.com> * refactor: remove registerOperators (#6224) * refactor(plugin-workflow): trigger workflow action settings (#6143) * refactor(plugin-workflow): move bind workflow settings to plugin * refactor(plugin-block-workbench): move component to core * refactor(plugin-block-workbench): adjust component api * fix(plugin-workflow-action-trigger): fix test cases * fix(plugin-workflow): fix component scope * fix(plugin-workflow-action-trigger): fix test cases * chore(versions): 😊 publish v1.6.0-alpha.26 * feat: support the extension of preset fields in collections (#6183) * feat: support the extension of preset fields in collections * fix: bug * fix: bug * fix: bug * refactor: create collection * fix: config * fix: test case * refactor: code improve * refactor: code improve * fix: bug * fix: bug --------- Co-authored-by: chenos <chenlinxh@gmail.com> * feat: support for the extension of optional fields for Kanban, Calendar, and Formula Field plugins (#6076) * feat: kanban field extention * fix: bug * fix: bug * fix: bug * fix: bug * feat: calender title fields * feat: background color fields * fix: bug * fix: bug * feat: formula field expression support field * feat: preset fields * fix: bug * fix: bug * fix: bug * fix: bug * fix: bug * fix: bug * fix: bug * fix: bug * refactor: code improve * fix: bug * fix: bug * fix: bug * fix: bug * refactor: code improve * revert: preset fields * refactor: code improve * refactor: code improve * fix: bug * fix: bug * fix: bug * refactor: code improve * fix: bug * refactor: code improve * refactor: code improve * fix: bug * fix: locale * refactor: code improve * fix: bug * refactor: code improve * refactor: code improve * refactor: code improve * refactor: locale * fix: test * fix: bug * fix: test * fix: test --------- Co-authored-by: chenos <chenlinxh@gmail.com> * chore(versions): 😊 publish v1.6.0-alpha.27 * fix(data-source-main): update order * fix: improve code * fix: getFontColor (#6241) * chore(versions): 😊 publish v1.6.0-alpha.28 * fix: print action e2e test (#6256) * fix: print action e2e test * fix: test * fix: version --------- Co-authored-by: katherinehhh <katherine_15995@163.com> Co-authored-by: nocobase[bot] <179432756+nocobase[bot]@users.noreply.github.com> Co-authored-by: Junyi <mytharcher@users.noreply.github.com>
178 lines
5.0 KiB
TypeScript
178 lines
5.0 KiB
TypeScript
/**
|
|
* This file is part of the NocoBase (R) project.
|
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
* Authors: NocoBase Team.
|
|
*
|
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
*/
|
|
|
|
import { ArrayField } from '@formily/core';
|
|
import { useField, useFieldSchema } from '@formily/react';
|
|
import {
|
|
BlockProvider,
|
|
useACLRoleContext,
|
|
useAPIClient,
|
|
useBlockRequestContext,
|
|
useCollection,
|
|
useCollection_deprecated,
|
|
useApp,
|
|
} from '@nocobase/client';
|
|
import { Spin } from 'antd';
|
|
import { isEqual } from 'lodash';
|
|
import React, { createContext, useCallback, useContext, useEffect, useState } from 'react';
|
|
|
|
export const KanbanBlockContext = createContext<any>({});
|
|
KanbanBlockContext.displayName = 'KanbanBlockContext';
|
|
|
|
const useGroupField = (props) => {
|
|
const { getField } = useCollection_deprecated();
|
|
const { groupField } = props;
|
|
if (typeof groupField === 'string') {
|
|
return getField(groupField);
|
|
}
|
|
if (groupField?.name) {
|
|
return getField(groupField?.name);
|
|
}
|
|
};
|
|
|
|
const InternalKanbanBlockProvider = (props) => {
|
|
const field = useField<any>();
|
|
const { resource, service } = useBlockRequestContext();
|
|
const groupField = useGroupField(props);
|
|
if (!groupField) {
|
|
return null;
|
|
}
|
|
if (service.loading && !field.loaded) {
|
|
return <Spin />;
|
|
}
|
|
field.loaded = true;
|
|
return (
|
|
<KanbanBlockContext.Provider
|
|
value={{
|
|
props: {
|
|
resource: props.resource,
|
|
},
|
|
field,
|
|
service,
|
|
resource,
|
|
groupField,
|
|
// fixedBlock: field?.decoratorProps?.fixedBlock,
|
|
sortField: props?.sortField,
|
|
}}
|
|
>
|
|
{props.children}
|
|
</KanbanBlockContext.Provider>
|
|
);
|
|
};
|
|
|
|
export const KanbanBlockProvider = (props) => {
|
|
const params = { ...props.params };
|
|
return (
|
|
<BlockProvider name="kanban" {...props} params={params}>
|
|
<InternalKanbanBlockProvider {...props} params={params} />
|
|
</BlockProvider>
|
|
);
|
|
};
|
|
|
|
export const useKanbanBlockContext = () => {
|
|
return useContext(KanbanBlockContext);
|
|
};
|
|
|
|
const useDisableCardDrag = () => {
|
|
const fieldSchema = useFieldSchema();
|
|
const { dragSort } = fieldSchema?.parent?.['x-component-props'] || {};
|
|
const ctx = useKanbanBlockContext();
|
|
const { allowAll, allowConfigure, parseAction } = useACLRoleContext();
|
|
if (dragSort === false) {
|
|
return true;
|
|
}
|
|
if (allowAll || allowConfigure) {
|
|
return false;
|
|
}
|
|
const result = parseAction(`${ctx?.props?.resource}:update`, { ignoreScope: true });
|
|
return !result;
|
|
};
|
|
|
|
export const toColumns = (groupCollectionField: any, dataSource: Array<any> = [], primaryKey, options) => {
|
|
const columns = {
|
|
__unknown__: {
|
|
id: '__unknown__',
|
|
title: 'Unknown',
|
|
color: 'default',
|
|
cards: [],
|
|
},
|
|
};
|
|
options?.forEach((item) => {
|
|
columns[item.value] = {
|
|
id: item.value,
|
|
title: item.label,
|
|
color: item.color,
|
|
cards: [],
|
|
};
|
|
});
|
|
dataSource.forEach((ds) => {
|
|
const value = ds[groupCollectionField.name];
|
|
if (value && columns[value]) {
|
|
columns[value].cards.push({ ...ds, id: ds[primaryKey] });
|
|
} else {
|
|
columns.__unknown__.cards.push(ds);
|
|
}
|
|
});
|
|
if (columns.__unknown__.cards.length === 0) {
|
|
delete columns.__unknown__;
|
|
}
|
|
return Object.values(columns);
|
|
};
|
|
|
|
export const useKanbanBlockProps = () => {
|
|
const field = useField<ArrayField>();
|
|
const ctx = useKanbanBlockContext();
|
|
const [dataSource, setDataSource] = useState([]);
|
|
const primaryKey = useCollection()?.getPrimaryKey();
|
|
const app = useApp();
|
|
const plugin = app.pm.get('kanban') as any;
|
|
const targetGroupField = plugin.getGroupFieldInterface(ctx.groupField.interface);
|
|
const { options } = targetGroupField?.useGetGroupOptions(ctx.groupField) || { options: [] };
|
|
useEffect(() => {
|
|
const data = toColumns(ctx.groupField, ctx?.service?.data?.data, primaryKey, options);
|
|
if (isEqual(field.value, data) && dataSource === field.value) {
|
|
return;
|
|
}
|
|
field.value = data;
|
|
setDataSource(field.value);
|
|
}, [ctx?.service?.loading, options]);
|
|
|
|
const disableCardDrag = useDisableCardDrag();
|
|
|
|
const onCardDragEnd = useCallback(
|
|
async ({ columns, groupField }, { fromColumnId, fromPosition }, { toColumnId, toPosition }) => {
|
|
const sourceColumn = columns.find((column) => column.id === fromColumnId);
|
|
const destinationColumn = columns.find((column) => column.id === toColumnId);
|
|
const sourceCard = sourceColumn?.cards?.[fromPosition];
|
|
const targetCard = destinationColumn?.cards?.[toPosition];
|
|
const values = {
|
|
sourceId: sourceCard.id,
|
|
sortField: ctx?.sortField || `${groupField.name}_sort`,
|
|
};
|
|
if (targetCard) {
|
|
values['targetId'] = targetCard.id;
|
|
} else {
|
|
values['targetScope'] = {
|
|
[groupField.name]: toColumnId,
|
|
};
|
|
}
|
|
await ctx.resource.move(values);
|
|
},
|
|
[ctx?.sortField],
|
|
);
|
|
|
|
return {
|
|
setDataSource,
|
|
dataSource,
|
|
groupField: ctx.groupField,
|
|
disableCardDrag,
|
|
onCardDragEnd,
|
|
};
|
|
};
|