chenos 5fbc7697c6
feat: release 202502 (#6259)
* 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>
2025-02-21 13:25:17 +08:00

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,
};
};