refactor: block init names and design icons (#1553)

Co-authored-by: sealday <sealday@gmail.com>
Reviewed-on: daoyoucloud/tachybase#1553
This commit is contained in:
sealday 2024-09-20 05:48:11 +08:00
parent bdf994e5b7
commit ae42c95484
31 changed files with 149 additions and 377 deletions

View File

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { useContextMenu, useDesignable, useHotkeys } from '@tachybase/client'; import { Icon, useContextMenu, useDesignable, useHotkeys } from '@tachybase/client';
import { import {
CalculatorOutlined, CalculatorOutlined,
@ -30,7 +30,7 @@ export const AssistantProvider = ({ children }) => {
<FloatButton.Group trigger="hover" type="default" style={{ right: 24, zIndex: 1250 }} icon={<ToolOutlined />}> <FloatButton.Group trigger="hover" type="default" style={{ right: 24, zIndex: 1250 }} icon={<ToolOutlined />}>
<FloatButton icon={<SearchOutlined />} onClick={() => setOpen(true)} /> <FloatButton icon={<SearchOutlined />} onClick={() => setOpen(true)} />
<FloatButton <FloatButton
icon={<HighlightOutlined />} icon={<Icon type="Design" />}
type={designable ? 'primary' : 'default'} type={designable ? 'primary' : 'default'}
onClick={() => setDesignable(!designable)} onClick={() => setDesignable(!designable)}
/> />

View File

@ -149,6 +149,7 @@
"Select grouping field": "Select grouping field", "Select grouping field": "Select grouping field",
"Media": "Media", "Media": "Media",
"Markdown": "Markdown", "Markdown": "Markdown",
"Demonstration text": "Demonstration text",
"Wysiwyg": "Wysiwyg", "Wysiwyg": "Wysiwyg",
"Chart blocks": "Chart blocks", "Chart blocks": "Chart blocks",
"Column chart": "Column chart", "Column chart": "Column chart",
@ -157,7 +158,7 @@
"Pie chart": "Pie chart", "Pie chart": "Pie chart",
"Area chart": "Area chart", "Area chart": "Area chart",
"Other chart": "Other chart", "Other chart": "Other chart",
"Other blocks": "Other blocks", "Other blocks": "Advanced blocks",
"In configuration": "In configuration", "In configuration": "In configuration",
"Chart title": "Chart title", "Chart title": "Chart title",
"Chart type": "Chart type", "Chart type": "Chart type",
@ -843,5 +844,6 @@
"Disable Right Menu":"Disable Right Menu", "Disable Right Menu":"Disable Right Menu",
"Full Screen":"Full Screen", "Full Screen":"Full Screen",
"Designer Mode":"Designer Mode", "Designer Mode":"Designer Mode",
"Embedded page": "Embedded page",
"There are no full screen blocks available at the current location":"There are no full screen blocks available at the current location" "There are no full screen blocks available at the current location":"There are no full screen blocks available at the current location"
} }

View File

@ -176,7 +176,7 @@
"Pie chart": "饼图", "Pie chart": "饼图",
"Area chart": "面积图", "Area chart": "面积图",
"Other chart": "其他图表", "Other chart": "其他图表",
"Other blocks": "其他区块", "Other blocks": "高级区块",
"In configuration": "配置中", "In configuration": "配置中",
"Chart title": "图表标题", "Chart title": "图表标题",
"Chart type": "图表类型", "Chart type": "图表类型",
@ -958,5 +958,7 @@
"Designer Mode":"设计者模式", "Designer Mode":"设计者模式",
"There are no full screen blocks available at the current location":"当前位置没有可全屏区块", "There are no full screen blocks available at the current location":"当前位置没有可全屏区块",
"Exit Full Screen":"退出全屏", "Exit Full Screen":"退出全屏",
"Embedded page": "嵌入页面",
"Demonstration text": "演示文本",
"User settings":"个人设置" "User settings":"个人设置"
} }

View File

@ -32,7 +32,7 @@ export const createFormBlockInitializers_deprecated = new CompatibleSchemaInitia
children: [ children: [
{ {
name: 'markdown', name: 'markdown',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
Component: 'MarkdownBlockInitializer', Component: 'MarkdownBlockInitializer',
}, },
], ],
@ -89,7 +89,7 @@ export const createFormBlockInitializers = new CompatibleSchemaInitializer(
children: [ children: [
{ {
name: 'markdown', name: 'markdown',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
Component: 'MarkdownBlockInitializer', Component: 'MarkdownBlockInitializer',
}, },
], ],

View File

@ -30,7 +30,7 @@ export const customizeCreateFormBlockInitializers_deprecated = new CompatibleSch
children: [ children: [
{ {
name: 'markdown', name: 'markdown',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
Component: 'MarkdownBlockInitializer', Component: 'MarkdownBlockInitializer',
}, },
], ],
@ -65,7 +65,7 @@ export const customizeCreateFormBlockInitializers = new CompatibleSchemaInitiali
children: [ children: [
{ {
name: 'markdown', name: 'markdown',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
Component: 'MarkdownBlockInitializer', Component: 'MarkdownBlockInitializer',
}, },
], ],

View File

@ -29,7 +29,7 @@ export const recordFormBlockInitializers = new SchemaInitializer({
children: [ children: [
{ {
name: 'markdown', name: 'markdown',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
Component: 'MarkdownBlockInitializer', Component: 'MarkdownBlockInitializer',
}, },
], ],

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { FormOutlined } from '@ant-design/icons'; import { FileTextOutlined } from '@ant-design/icons';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '../../../../application'; import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '../../../../application';
@ -13,7 +13,7 @@ export const MarkdownBlockInitializer = () => {
return ( return (
<SchemaInitializerItem <SchemaInitializerItem
{...itemConfig} {...itemConfig}
icon={<FormOutlined />} icon={<FileTextOutlined />}
onClick={() => { onClick={() => {
insert({ insert({
type: 'void', type: 'void',

View File

@ -66,7 +66,7 @@ export const blockInitializers_deprecated = new CompatibleSchemaInitializer({
children: [ children: [
{ {
name: 'markdown', name: 'markdown',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
Component: 'MarkdownBlockInitializer', Component: 'MarkdownBlockInitializer',
}, },
], ],
@ -137,7 +137,7 @@ export const blockInitializers = new CompatibleSchemaInitializer(
children: [ children: [
{ {
name: 'markdown', name: 'markdown',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
Component: 'MarkdownBlockInitializer', Component: 'MarkdownBlockInitializer',
}, },
], ],

View File

@ -11,8 +11,8 @@ import {
} from '@tachybase/schema'; } from '@tachybase/schema';
import { error } from '@tachybase/utils/client'; import { error } from '@tachybase/utils/client';
import { AppstoreOutlined, InsertRowAboveOutlined, MoreOutlined } from '@ant-design/icons'; import { AppstoreAddOutlined } from '@ant-design/icons';
import { Menu as AntdMenu, Button, Card, Col, Dropdown, MenuProps, Popover, Row } from 'antd'; import { Menu as AntdMenu, Button, Card, MenuProps, Popover } from 'antd';
import { createPortal } from 'react-dom'; import { createPortal } from 'react-dom';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -203,7 +203,7 @@ const HeaderMenu = ({
); );
}} }}
> >
<Button className="iconButton" icon={<AppstoreOutlined style={{ color: token.colorTextHeaderMenu }} />} /> <Button className="iconButton" icon={<AppstoreAddOutlined style={{ color: token.colorTextHeaderMenu }} />} />
</Popover> </Popover>
<Component /> <Component />
</div> </div>

View File

@ -6,6 +6,7 @@ import { useHotkeys } from 'react-hotkeys-hook';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useDesignable } from '..'; import { useDesignable } from '..';
import { Icon } from '../../icon';
import { useToken } from '../../style'; import { useToken } from '../../style';
export const DesignableSwitch = () => { export const DesignableSwitch = () => {
@ -24,7 +25,7 @@ export const DesignableSwitch = () => {
<Tooltip title={t('UI Editor')}> <Tooltip title={t('UI Editor')}>
<Button <Button
data-testid={'ui-editor-button'} data-testid={'ui-editor-button'}
icon={<HighlightOutlined style={{ color: token.colorTextHeaderMenu }} />} icon={<Icon type="Design" style={{ color: token.colorTextHeaderMenu, fill: token.colorTextHeaderMenu }} />}
title={t('UI Editor')} title={t('UI Editor')}
style={style} style={style}
onClick={() => { onClick={() => {

View File

@ -353,7 +353,7 @@ export const recordBlockInitializers_deprecated = new CompatibleSchemaInitialize
children: [ children: [
{ {
name: 'markdown', name: 'markdown',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
Component: 'MarkdownBlockInitializer', Component: 'MarkdownBlockInitializer',
}, },
], ],
@ -450,7 +450,7 @@ export const recordBlockInitializers = new CompatibleSchemaInitializer(
children: [ children: [
{ {
name: 'markdown', name: 'markdown',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
Component: 'MarkdownBlockInitializer', Component: 'MarkdownBlockInitializer',
}, },
], ],

View File

@ -31,7 +31,7 @@ export const CreateFormBulkEditBlockInitializers: SchemaInitializer = new Schema
children: [ children: [
{ {
name: 'markdown', name: 'markdown',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
Component: 'MarkdownBlockInitializer', Component: 'MarkdownBlockInitializer',
}, },
], ],
@ -67,7 +67,7 @@ export const BulkEditBlockInitializers_deprecated = new CompatibleSchemaInitiali
children: [ children: [
{ {
name: 'markdown', name: 'markdown',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
Component: 'MarkdownBlockInitializer', Component: 'MarkdownBlockInitializer',
}, },
], ],
@ -101,7 +101,7 @@ export const bulkEditBlockInitializers = new CompatibleSchemaInitializer(
children: [ children: [
{ {
name: 'markdown', name: 'markdown',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
Component: 'MarkdownBlockInitializer', Component: 'MarkdownBlockInitializer',
}, },
], ],

View File

@ -14,7 +14,7 @@ import {
import { FormLayout } from '@tachybase/components'; import { FormLayout } from '@tachybase/components';
import { SchemaOptionsContext } from '@tachybase/schema'; import { SchemaOptionsContext } from '@tachybase/schema';
import { FormOutlined } from '@ant-design/icons'; import { CalendarOutlined } from '@ant-design/icons';
import { useTranslation } from '../../../locale'; import { useTranslation } from '../../../locale';
import { createCalendarBlockUISchema } from '../createCalendarBlockUISchema'; import { createCalendarBlockUISchema } from '../createCalendarBlockUISchema';
@ -39,7 +39,7 @@ export const CalendarBlockInitializer = ({
<DataBlockInitializer <DataBlockInitializer
{...itemConfig} {...itemConfig}
componentType={'Calendar'} componentType={'Calendar'}
icon={<FormOutlined />} icon={<CalendarOutlined />}
onCreateBlockSchema={async (options) => { onCreateBlockSchema={async (options) => {
if (createBlockSchema) { if (createBlockSchema) {
return createBlockSchema(options); return createBlockSchema(options);

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '@tachybase/client'; import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '@tachybase/client';
import { FormOutlined } from '@ant-design/icons'; import { Html5Outlined } from '@ant-design/icons';
export const IframeBlockInitializer = () => { export const IframeBlockInitializer = () => {
const { insert } = useSchemaInitializer(); const { insert } = useSchemaInitializer();
@ -9,7 +9,7 @@ export const IframeBlockInitializer = () => {
return ( return (
<SchemaInitializerItem <SchemaInitializerItem
{...itemConfig} {...itemConfig}
icon={<FormOutlined />} icon={<Html5Outlined />}
onClick={() => { onClick={() => {
insert({ insert({
type: 'void', type: 'void',

View File

@ -1,34 +1,33 @@
import { Plugin } from '@tachybase/client'; import { Plugin } from '@tachybase/client';
import { IframeBlockProvider } from './IframeBlockProvider'; import { IframeBlockProvider } from './IframeBlockProvider';
import { iframeBlockSchemaSettings, iframeBlockSchemaSettings_deprecated } from './schemaSettings'; import { iframeBlockSchemaSettings } from './schemaSettings';
export class IframeBlockPlugin extends Plugin { export class IframeBlockPlugin extends Plugin {
async load() { async load() {
this.app.schemaSettingsManager.add(iframeBlockSchemaSettings_deprecated);
this.app.schemaSettingsManager.add(iframeBlockSchemaSettings); this.app.schemaSettingsManager.add(iframeBlockSchemaSettings);
this.app.use(IframeBlockProvider); this.app.use(IframeBlockProvider);
const blockInitializers = this.app.schemaInitializerManager.get('page:addBlock'); const blockInitializers = this.app.schemaInitializerManager.get('page:addBlock');
blockInitializers?.add('otherBlocks.iframe', { blockInitializers?.add('otherBlocks.iframe', {
title: '{{t("Iframe")}}', title: '{{t("Embedded page")}}',
Component: 'IframeBlockInitializer', Component: 'IframeBlockInitializer',
}); });
const createFormBlockInitializers = this.app.schemaInitializerManager.get('popup:addNew:addBlock'); const createFormBlockInitializers = this.app.schemaInitializerManager.get('popup:addNew:addBlock');
createFormBlockInitializers?.add('otherBlocks.iframe', { createFormBlockInitializers?.add('otherBlocks.iframe', {
title: '{{t("Iframe")}}', title: '{{t("Embedded page")}}',
Component: 'IframeBlockInitializer', Component: 'IframeBlockInitializer',
}); });
const recordBlockInitializers = this.app.schemaInitializerManager.get('popup:common:addBlock'); const recordBlockInitializers = this.app.schemaInitializerManager.get('popup:common:addBlock');
recordBlockInitializers?.add('otherBlocks.iframe', { recordBlockInitializers?.add('otherBlocks.iframe', {
title: '{{t("Iframe")}}', title: '{{t("Embedded page")}}',
Component: 'IframeBlockInitializer', Component: 'IframeBlockInitializer',
}); });
const recordFormBlockInitializers = this.app.schemaInitializerManager.get('RecordFormBlockInitializers'); const recordFormBlockInitializers = this.app.schemaInitializerManager.get('RecordFormBlockInitializers');
recordFormBlockInitializers?.add('otherBlocks.iframe', { recordFormBlockInitializers?.add('otherBlocks.iframe', {
title: '{{t("Iframe")}}', title: '{{t("Embedded page")}}',
Component: 'IframeBlockInitializer', Component: 'IframeBlockInitializer',
}); });
} }

View File

@ -3,150 +3,6 @@ import { ISchema, uid, useField, useFieldSchema } from '@tachybase/schema';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
/**
* @deprecated
*/
export const iframeBlockSchemaSettings_deprecated = new SchemaSettings({
name: 'iframeBlockSchemaSettings',
items: [
{
name: 'EditIframe',
type: 'modal',
useComponentProps() {
const field = useField();
const fieldSchema = useFieldSchema();
const { t } = useTranslation();
const { dn } = useDesignable();
const api = useAPIClient();
const { mode, url, htmlId, height = '60vh' } = fieldSchema['x-component-props'] || {};
const saveHtml = async (html: string) => {
const options = {
values: { html },
};
if (htmlId) {
// eslint-disable-next-line no-unsafe-optional-chaining
const { data } = await api.resource('iframeHtml').update?.({ ...options, filterByTk: htmlId });
return data?.data?.[0] || { id: htmlId };
} else {
// eslint-disable-next-line no-unsafe-optional-chaining
const { data } = await api.resource('iframeHtml').create?.(options);
return data?.data;
}
};
const submitHandler = async ({ mode, url, html, height }) => {
const componentProps = fieldSchema['x-component-props'] || {};
componentProps['mode'] = mode;
componentProps['height'] = height;
componentProps['url'] = url;
if (mode === 'html') {
const data = await saveHtml(html);
componentProps['htmlId'] = data.id;
}
fieldSchema['x-component-props'] = componentProps;
field.componentProps = { ...componentProps };
field.data = { v: uid() };
dn.emit('patch', {
schema: {
'x-uid': fieldSchema['x-uid'],
'x-component-props': componentProps,
},
});
};
return {
title: t('Edit iframe'),
asyncGetInitialValues: async () => {
const values = {
mode,
url,
height,
};
if (htmlId) {
// eslint-disable-next-line no-unsafe-optional-chaining
const { data } = await api.resource('iframeHtml').get?.({ filterByTk: htmlId });
values['html'] = data?.data?.html || '';
}
return values;
},
schema: {
type: 'object',
title: t('Edit iframe'),
properties: {
mode: {
title: '{{t("Mode")}}',
'x-component': 'Radio.Group',
'x-decorator': 'FormItem',
required: true,
default: 'url',
enum: [
{ value: 'url', label: t('URL') },
{ value: 'html', label: t('html') },
],
},
url: {
title: t('URL'),
type: 'string',
'x-decorator': 'FormItem',
'x-component': 'Input',
required: true,
'x-reactions': {
dependencies: ['mode'],
fulfill: {
state: {
hidden: '{{$deps[0] === "html"}}',
},
},
},
},
html: {
title: t('html'),
type: 'string',
'x-decorator': 'FormItem',
'x-component': 'Input.TextArea',
required: true,
'x-reactions': {
dependencies: ['mode'],
fulfill: {
state: {
hidden: '{{$deps[0] === "url"}}',
},
},
},
},
height: {
title: t('Height'),
type: 'string',
'x-decorator': 'FormItem',
'x-component': 'Input',
required: true,
},
},
} as ISchema,
onSubmit: submitHandler,
};
},
},
{
name: 'divider',
type: 'divider',
},
{
name: 'delete',
type: 'remove',
useComponentProps() {
return {
removeParentsIfNoChildren: true,
breakRemoveOn: {
'x-component': 'Grid',
},
};
},
},
],
});
export const iframeBlockSchemaSettings = new SchemaSettings({ export const iframeBlockSchemaSettings = new SchemaSettings({
name: 'blockSettings:iframe', name: 'blockSettings:iframe',
items: [ items: [

View File

@ -61,7 +61,7 @@ export const mBlockInitializers_deprecated = new CompatibleSchemaInitializer({
}, },
{ {
name: 'markdown', name: 'markdown',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
Component: 'MarkdownBlockInitializer', Component: 'MarkdownBlockInitializer',
}, },
{ {
@ -148,7 +148,7 @@ export const mBlockInitializers = new CompatibleSchemaInitializer(
}, },
{ {
name: 'markdown', name: 'markdown',
title: tval('Markdown'), title: tval('Demonstration text'),
Component: 'MarkdownBlockInitializer', Component: 'MarkdownBlockInitializer',
}, },
{ {

View File

@ -31,7 +31,7 @@ export const snapshotBlockInitializers_deprecated = new CompatibleSchemaInitiali
children: [ children: [
{ {
name: 'markdown', name: 'markdown',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
Component: 'MarkdownBlockInitializer', Component: 'MarkdownBlockInitializer',
}, },
], ],
@ -66,7 +66,7 @@ export const snapshotBlockInitializers = new CompatibleSchemaInitializer(
children: [ children: [
{ {
name: 'markdown', name: 'markdown',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
Component: 'MarkdownBlockInitializer', Component: 'MarkdownBlockInitializer',
}, },
], ],

View File

@ -76,7 +76,7 @@ export const ApproverAddBlockInitializer = new SchemaInitializer({
const values = Array.from(approvalFormOptions.getValues()); const values = Array.from(approvalFormOptions.getValues());
return values.map((item: ApprovalFormType) => { return values.map((item: ApprovalFormType) => {
// NOTE: 这里通过赋别名,避免 eslint 检查 hooks 语法,无法提交 // NOTE: 这里通过赋别名,避免 eslint 检查 hooks 语法,无法提交
// eslint-disable-next-line react-hooks/rules-of-hooks
const { useInitializer: getInitializer } = item.config; const { useInitializer: getInitializer } = item.config;
return getInitializer({ allCollections }); return getInitializer({ allCollections });
}); });
@ -90,7 +90,7 @@ export const ApproverAddBlockInitializer = new SchemaInitializer({
{ {
name: 'markdown', name: 'markdown',
type: 'item', type: 'item',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
component: 'MarkdownBlockInitializer', component: 'MarkdownBlockInitializer',
}, },
], ],

View File

@ -66,7 +66,7 @@ export const CarbonCopyDetailInitializer = new SchemaInitializer({
{ {
name: 'markdown', name: 'markdown',
type: 'item', type: 'item',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
component: 'MarkdownBlockInitializer', component: 'MarkdownBlockInitializer',
}, },
], ],

View File

@ -30,7 +30,7 @@ export const LauncherAddBlockButtonIntializer = new SchemaInitializer({
{ {
name: 'markdown', name: 'markdown',
type: 'item', type: 'item',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
Component: 'MarkdownBlockInitializer', Component: 'MarkdownBlockInitializer',
}, },
], ],

View File

@ -26,41 +26,45 @@ export class SCApprovalBlock extends Plugin {
} }
} }
const schemaItems = [ export const schemaItems = [
{ {
type: 'itemGroup', type: 'item',
name: 'Launch', icon: 'ClockCircleOutlined',
title: `{{t("Launch", { ns: "${NAMESPACE}" })}}`, title: `{{t("Initiate Request", { ns: "${NAMESPACE}" })}}`,
children: [ 'x-component': 'ApprovalBlock.Launch.Application',
{ collection: 'workflows',
type: 'item', action: 'list',
title: `{{t("Launch", { ns: "${NAMESPACE}" })}}`, Component: 'ApprovalBlock.BlockInitializer',
'x-component': 'ApprovalBlock.Launch.Application', useInsert: () => {
collection: 'workflows', return (schema) => {
action: 'list', console.log('🚀 ~ file: ApprovalBlock.schema.tsx:45 ~ return ~ schema:', schema);
}, };
{ },
type: 'item',
title: `{{t("MyLaunch", { ns: "${NAMESPACE}" })}}`,
'x-component': 'ApprovalBlock.Launch',
collection: 'approvals',
params: {
appends: [
'createdBy.nickname',
'workflow.title',
'workflow.enabled',
'records.id',
'records.status',
'records.node.title',
],
except: ['data'],
},
},
],
}, },
{ {
type: 'item', type: 'item',
title: `{{t("Todos", { ns: "${NAMESPACE}" })}}`, icon: 'AuditOutlined',
Component: 'ApprovalBlock.BlockInitializer',
title: `{{t("My Requests", { ns: "${NAMESPACE}" })}}`,
'x-component': 'ApprovalBlock.Launch',
collection: 'approvals',
params: {
appends: [
'createdBy.nickname',
'workflow.title',
'workflow.enabled',
'records.id',
'records.status',
'records.node.title',
],
except: ['data'],
},
},
{
type: 'item',
icon: 'FormOutlined',
Component: 'ApprovalBlock.BlockInitializer',
title: `{{t("My Pending Tasks", { ns: "${NAMESPACE}" })}}`,
'x-component': 'ApprovalBlock.Todos', 'x-component': 'ApprovalBlock.Todos',
collection: 'approvalRecords', collection: 'approvalRecords',
params: { params: {
@ -84,7 +88,9 @@ const schemaItems = [
}, },
{ {
type: 'item', type: 'item',
title: `{{t("CarbonCopy", { ns: "${NAMESPACE}" })}}`, icon: 'MailOutlined',
Component: 'ApprovalBlock.BlockInitializer',
title: `{{t("CC'd to Me", { ns: "${NAMESPACE}" })}}`,
'x-decorator': 'CarbonCopyBlockProvider', 'x-decorator': 'CarbonCopyBlockProvider',
'x-component': 'CarbonCopyCenter', 'x-component': 'CarbonCopyCenter',
'x-toolbar': 'BlockSchemaToolbar', 'x-toolbar': 'BlockSchemaToolbar',
@ -112,7 +118,7 @@ const schemaItems = [
}, },
]; ];
const getSchemaInsert = ({ item }) => { export const getSchemaInsert = ({ item }) => {
const id = uid(); const id = uid();
const { const {
collection, collection,
@ -156,7 +162,5 @@ export const ApprovalBlockComponent = () => {
insert(schema); insert(schema);
}; };
return ( return <SchemaInitializerItem {...schemaInitializerItem} onClick={onClick} />;
<SchemaInitializerItem icon={<TableOutlined />} {...schemaInitializerItem} items={schemaItems} onClick={onClick} />
);
}; };

View File

@ -1,8 +1,8 @@
import { Plugin } from '@tachybase/client'; import { Plugin, useSchemaInitializer } from '@tachybase/client';
import { tval } from '../../locale'; import { tval } from '../../locale';
import { KitApprovalCommon } from '../approval-common/plugin'; import { KitApprovalCommon } from '../approval-common/plugin';
import { ApprovalBlockComponent, SCApprovalBlock } from './ApprovalBlock.schema'; import { ApprovalBlockComponent, getSchemaInsert, SCApprovalBlock, schemaItems } from './ApprovalBlock.schema';
import { ViewActionLaunch } from './launch/VC.ViewActionLaunch'; import { ViewActionLaunch } from './launch/VC.ViewActionLaunch';
import { ProviderApprovalUpdateForm } from './todos/ApprovalUpdateForm.provider'; import { ProviderApprovalUpdateForm } from './todos/ApprovalUpdateForm.provider';
import { ViewActionTodos } from './todos/VC.ViewActionTodos'; import { ViewActionTodos } from './todos/VC.ViewActionTodos';
@ -22,12 +22,12 @@ export class KitApprovalBlock extends Plugin {
ProviderApprovalUpdateForm: ProviderApprovalUpdateForm, ProviderApprovalUpdateForm: ProviderApprovalUpdateForm,
}); });
this.app.schemaInitializerManager.get('page:addBlock').add('otherBlocks.approval', { this.app.schemaInitializerManager.get('page:addBlock').add('otherBlocks.workflow.approval', {
key: 'approvalBlock', key: 'approvalBlock',
name: 'approvalBlock', name: 'approvalBlock',
type: 'item', type: 'itemGroup',
title: tval('Approval'), title: tval('Approval'),
Component: 'ApprovalBlock.BlockInitializer', children: schemaItems,
icon: 'AuditOutlined', icon: 'AuditOutlined',
}); });
} }

View File

@ -1,15 +1,13 @@
import React from 'react';
import { Plugin } from '@tachybase/client'; import { Plugin } from '@tachybase/client';
import { PartitionOutlined } from '@ant-design/icons';
import WorkflowPlugin from '../..'; import WorkflowPlugin from '../..';
import { NAMESPACE } from '../../locale'; import { NAMESPACE } from '../../locale';
import Manual from './instruction'; import Manual from './instruction';
import { addCustomFormField, addCustomFormField_deprecated } from './instruction/forms/custom'; import { addCustomFormField } from './instruction/forms/custom';
import { import { addActionButton, addBlockButton } from './instruction/SchemaConfig';
addActionButton,
addActionButton_deprecated,
addBlockButton,
addBlockButton_deprecated,
} from './instruction/SchemaConfig';
import { WorkflowTodo } from './WorkflowTodo'; import { WorkflowTodo } from './WorkflowTodo';
import { WorkflowTodoBlockInitializer } from './WorkflowTodoBlockInitializer'; import { WorkflowTodoBlockInitializer } from './WorkflowTodoBlockInitializer';
@ -20,18 +18,31 @@ export class PluginManual extends Plugin {
const workflow = this.app.pm.get('workflow') as WorkflowPlugin; const workflow = this.app.pm.get('workflow') as WorkflowPlugin;
workflow.registerInstruction('manual', Manual); workflow.registerInstruction('manual', Manual);
this.app.schemaInitializerManager.add(addBlockButton_deprecated);
this.app.schemaInitializerManager.add(addBlockButton); this.app.schemaInitializerManager.add(addBlockButton);
this.app.schemaInitializerManager.add(addActionButton_deprecated);
this.app.schemaInitializerManager.add(addActionButton); this.app.schemaInitializerManager.add(addActionButton);
this.app.schemaInitializerManager.add(addCustomFormField_deprecated);
this.app.schemaInitializerManager.add(addCustomFormField); this.app.schemaInitializerManager.add(addCustomFormField);
const blockInitializers = this.app.schemaInitializerManager.get('page:addBlock'); const blockInitializers = this.app.schemaInitializerManager.get('page:addBlock');
blockInitializers.add('otherBlocks.workflowTodos', { blockInitializers.add('otherBlocks.workflow', {
title: `{{t("Workflow todos", { ns: "${NAMESPACE}" })}}`, name: 'workflow',
Component: 'WorkflowTodoBlockInitializer', title: `{{t("Workflow", { ns: "${NAMESPACE}" })}}`,
icon: 'CheckSquareOutlined', type: 'subMenu',
icon: <PartitionOutlined />,
children: [
{
name: 'common',
title: `{{t("Common", { ns: "${NAMESPACE}" })}}`,
type: 'itemGroup',
children: [
{
name: 'todos',
title: `{{t("Workflow todos", { ns: "${NAMESPACE}" })}}`,
Component: 'WorkflowTodoBlockInitializer',
icon: 'CheckSquareOutlined',
},
],
},
],
}); });
} }

View File

@ -12,6 +12,7 @@ import {
InitializerWithSwitch, InitializerWithSwitch,
SchemaComponent, SchemaComponent,
SchemaComponentContext, SchemaComponentContext,
SchemaInitializer,
SchemaInitializerItem, SchemaInitializerItem,
SchemaInitializerItemType, SchemaInitializerItemType,
SchemaSettingsBlockTitleItem, SchemaSettingsBlockTitleItem,
@ -104,11 +105,8 @@ const blockTypeNames = {
record: `{{t("Data record", { ns: "${NAMESPACE}" })}}`, record: `{{t("Data record", { ns: "${NAMESPACE}" })}}`,
}; };
/** export const addBlockButton = new SchemaInitializer({
* @deprecated name: 'workflowManual:popup:configureUserInterface:addBlock',
*/
export const addBlockButton_deprecated = new CompatibleSchemaInitializer({
name: 'AddBlockButton',
wrap: gridRowColWrap, wrap: gridRowColWrap,
title: '{{t("Add block")}}', title: '{{t("Add block")}}',
items: [ items: [
@ -135,7 +133,7 @@ export const addBlockButton_deprecated = new CompatibleSchemaInitializer({
{ {
name: 'nodes', name: 'nodes',
type: 'subMenu', type: 'subMenu',
title: `{{t("Node result", { ns: "workflow" })}}`, title: `{{t("Node result", { ns: "${NAMESPACE}" })}}`,
children: nodeBlockInitializers, children: nodeBlockInitializers,
}, },
] ]
@ -164,7 +162,7 @@ export const addBlockButton_deprecated = new CompatibleSchemaInitializer({
children: [ children: [
{ {
name: 'markdown', name: 'markdown',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
Component: 'MarkdownBlockInitializer', Component: 'MarkdownBlockInitializer',
}, },
], ],
@ -172,74 +170,6 @@ export const addBlockButton_deprecated = new CompatibleSchemaInitializer({
], ],
}); });
export const addBlockButton = new CompatibleSchemaInitializer(
{
name: 'workflowManual:popup:configureUserInterface:addBlock',
wrap: gridRowColWrap,
title: '{{t("Add block")}}',
items: [
{
type: 'itemGroup',
name: 'dataBlocks',
title: '{{t("Data blocks")}}',
hideIfNoChildren: true,
useChildren() {
const workflowPlugin = usePlugin(WorkflowPlugin);
const current = useNodeContext();
const nodes = useAvailableUpstreams(current);
const triggerInitializers = [useTriggerInitializers()].filter(Boolean);
const nodeBlockInitializers = nodes
.map((node) => {
const instruction = workflowPlugin.instructions.get(node.type);
return instruction?.useInitializers?.(node);
})
.filter(Boolean);
const dataBlockInitializers: any = [
...triggerInitializers,
...(nodeBlockInitializers.length
? [
{
name: 'nodes',
type: 'subMenu',
title: `{{t("Node result", { ns: "${NAMESPACE}" })}}`,
children: nodeBlockInitializers,
},
]
: []),
].filter(Boolean);
return dataBlockInitializers;
},
},
{
type: 'itemGroup',
name: 'form',
title: '{{t("Form")}}',
useChildren() {
const dm = useDataSourceManager();
const allCollections = dm.getAllCollections();
return Array.from(manualFormTypes.getValues()).map((item: ManualFormType) => {
const { useInitializer: getInitializer } = item.config;
return getInitializer({ allCollections });
});
},
},
{
type: 'itemGroup',
name: 'otherBlocks',
title: '{{t("Other blocks")}}',
children: [
{
name: 'markdown',
title: '{{t("Markdown")}}',
Component: 'MarkdownBlockInitializer',
},
],
},
],
},
addBlockButton_deprecated,
);
function AssignedFieldValues() { function AssignedFieldValues() {
const ctx = useContext(SchemaComponentContext); const ctx = useContext(SchemaComponentContext);
const { t } = useTranslation(); const { t } = useTranslation();
@ -418,11 +348,8 @@ function ActionInitializer() {
); );
} }
/** export const addActionButton = new SchemaInitializer({
* @deprecated name: 'workflowManual:form:configureActions',
*/
export const addActionButton_deprecated = new CompatibleSchemaInitializer({
name: 'AddActionButton',
title: '{{t("Configure actions")}}', title: '{{t("Configure actions")}}',
items: [ items: [
{ {
@ -452,40 +379,6 @@ export const addActionButton_deprecated = new CompatibleSchemaInitializer({
], ],
}); });
export const addActionButton = new CompatibleSchemaInitializer(
{
name: 'workflowManual:form:configureActions',
title: '{{t("Configure actions")}}',
items: [
{
name: 'jobStatusResolved',
title: `{{t("Continue the process", { ns: "${NAMESPACE}" })}}`,
Component: ContinueInitializer,
action: JOB_STATUS.RESOLVED,
actionProps: {
type: 'primary',
},
},
{
name: 'jobStatusRejected',
title: `{{t("Terminate the process", { ns: "${NAMESPACE}" })}}`,
Component: ActionInitializer,
action: JOB_STATUS.REJECTED,
actionProps: {
danger: true,
},
},
{
name: 'jobStatusPending',
title: `{{t("Save temporarily", { ns: "${NAMESPACE}" })}}`,
Component: ActionInitializer,
action: JOB_STATUS.PENDING,
},
],
},
addActionButton_deprecated,
);
// NOTE: fake useAction for ui configuration // NOTE: fake useAction for ui configuration
function useSubmit() { function useSubmit() {
// const { values, submit, id: formId } = useForm(); // const { values, submit, id: formId } = useForm();

View File

@ -7,6 +7,7 @@ import {
gridRowColWrap, gridRowColWrap,
RecordProvider, RecordProvider,
SchemaComponent, SchemaComponent,
SchemaInitializer,
SchemaInitializerItem, SchemaInitializerItem,
SchemaInitializerItems, SchemaInitializerItems,
SchemaInitializerItemType, SchemaInitializerItemType,
@ -336,28 +337,14 @@ const CustomItemsComponent = (props) => {
); );
}; };
/** export const addCustomFormField = new SchemaInitializer({
* @deprecated name: 'workflowManual:customForm:configureFields',
*/
export const addCustomFormField_deprecated = new CompatibleSchemaInitializer({
name: 'AddCustomFormField',
wrap: gridRowColWrap, wrap: gridRowColWrap,
insertPosition: 'beforeEnd', insertPosition: 'beforeEnd',
title: "{{t('Configure fields')}}", title: "{{t('Configure fields')}}",
ItemsComponent: CustomItemsComponent, ItemsComponent: CustomItemsComponent,
}); });
export const addCustomFormField = new CompatibleSchemaInitializer(
{
name: 'workflowManual:customForm:configureFields',
wrap: gridRowColWrap,
insertPosition: 'beforeEnd',
title: "{{t('Configure fields')}}",
ItemsComponent: CustomItemsComponent,
},
addCustomFormField_deprecated,
);
function CustomFormFieldInitializer() { function CustomFormFieldInitializer() {
const itemConfig = useSchemaInitializerItem(); const itemConfig = useSchemaInitializerItem();
const { insert, setVisible } = useSchemaInitializer(); const { insert, setVisible } = useSchemaInitializer();

View File

@ -66,7 +66,7 @@ export const NoticeDetailInitializer = new SchemaInitializer({
{ {
name: 'markdown', name: 'markdown',
type: 'item', type: 'item',
title: '{{t("Markdown")}}', title: '{{t("Demonstration text")}}',
component: 'MarkdownBlockInitializer', component: 'MarkdownBlockInitializer',
}, },
], ],

View File

@ -14,7 +14,7 @@ export class KitUsage extends Plugin {
NoticeBlockInitializer: NoticeBlockInitializer, NoticeBlockInitializer: NoticeBlockInitializer,
}); });
this.app.schemaInitializerManager.get('page:addBlock').add('otherBlocks.notice', { this.app.schemaInitializerManager.get('page:addBlock').add('otherBlocks.workflow.common.notice', {
key: 'noticeBlock', key: 'noticeBlock',
name: 'noticeBlock', name: 'noticeBlock',
type: 'item', type: 'item',

View File

@ -8,15 +8,22 @@ const DispatcherSvg = () => (
<svg viewBox="0 0 1024 1024" width="1em" height="1em"> <svg viewBox="0 0 1024 1024" width="1em" height="1em">
<path <path
d="M979.689326 108.982857H356.219611A144.530286 144.530286 0 0 0 217.028754 0c-64.804571 0.731429-121.124571 45.348571-137.654857 108.982857H44.045897a36.571429 36.571429 0 0 0-37.814857 15.798857 37.741714 37.741714 0 0 0 0 41.545143 36.571429 36.571429 0 0 0 37.814857 15.798857h35.328c15.945143 64.219429 72.411429 109.494857 137.654857 110.445715a144.530286 144.530286 0 0 0 139.117715-108.982858h623.542857a37.156571 37.156571 0 0 0 29.549714-36.571428 37.156571 37.156571 0 0 0-29.549714-36.571429v-1.462857zM144.909897 146.285714c0-40.374857 32.329143-73.142857 72.118857-73.142857s72.118857 32.768 72.118857 73.142857c0 19.382857-7.606857 38.034286-21.211428 51.712A71.533714 71.533714 0 0 1 217.101897 219.428571a72.630857 72.630857 0 0 1-72.118857-73.142857z m834.779429 694.125715H356.219611A144.530286 144.530286 0 0 0 217.028754 731.428571c-64.804571 0.731429-121.124571 45.348571-137.654857 108.982858H44.045897a36.571429 36.571429 0 0 0-37.814857 15.798857 37.741714 37.741714 0 0 0 0 41.545143 36.571429 36.571429 0 0 0 37.814857 15.798857h35.328c15.945143 64.219429 72.411429 109.494857 137.654857 110.445714a144.530286 144.530286 0 0 0 139.117715-108.982857h623.542857a36.571429 36.571429 0 0 0 37.814857-15.798857 37.741714 37.741714 0 0 0 0-41.545143 36.571429 36.571429 0 0 0-37.814857-15.798857v-1.462857zM144.909897 877.714286c0-40.374857 32.329143-73.142857 72.118857-73.142857s72.118857 32.768 72.118857 73.142857c0 19.382857-7.606857 38.034286-21.211428 51.712a71.533714 71.533714 0 0 1-50.907429 21.430857 72.630857 72.630857 0 0 1-72.118857-73.142857zM43.972754 474.697143h623.616A144.530286 144.530286 0 0 1 806.706469 365.714286c64.804571 0.731429 121.124571 45.348571 137.654857 108.982857h34.596571a36.571429 36.571429 0 0 1 37.814857 15.798857 37.741714 37.741714 0 0 1 0 41.545143 36.571429 36.571429 0 0 1-37.814857 15.798857h-34.596571A144.603429 144.603429 0 0 1 806.779611 658.285714a144.530286 144.530286 0 0 1-139.117714-108.982857H44.045897a36.571429 36.571429 0 0 1-37.814857-15.798857 37.741714 37.741714 0 0 1 0-41.545143 36.571429 36.571429 0 0 1 37.814857-15.798857v-1.462857zM807.803611 585.142857a73.142857 73.142857 0 1 0 0-146.285714 73.142857 73.142857 0 0 0 0 146.285714z" d="M979.689326 108.982857H356.219611A144.530286 144.530286 0 0 0 217.028754 0c-64.804571 0.731429-121.124571 45.348571-137.654857 108.982857H44.045897a36.571429 36.571429 0 0 0-37.814857 15.798857 37.741714 37.741714 0 0 0 0 41.545143 36.571429 36.571429 0 0 0 37.814857 15.798857h35.328c15.945143 64.219429 72.411429 109.494857 137.654857 110.445715a144.530286 144.530286 0 0 0 139.117715-108.982858h623.542857a37.156571 37.156571 0 0 0 29.549714-36.571428 37.156571 37.156571 0 0 0-29.549714-36.571429v-1.462857zM144.909897 146.285714c0-40.374857 32.329143-73.142857 72.118857-73.142857s72.118857 32.768 72.118857 73.142857c0 19.382857-7.606857 38.034286-21.211428 51.712A71.533714 71.533714 0 0 1 217.101897 219.428571a72.630857 72.630857 0 0 1-72.118857-73.142857z m834.779429 694.125715H356.219611A144.530286 144.530286 0 0 0 217.028754 731.428571c-64.804571 0.731429-121.124571 45.348571-137.654857 108.982858H44.045897a36.571429 36.571429 0 0 0-37.814857 15.798857 37.741714 37.741714 0 0 0 0 41.545143 36.571429 36.571429 0 0 0 37.814857 15.798857h35.328c15.945143 64.219429 72.411429 109.494857 137.654857 110.445714a144.530286 144.530286 0 0 0 139.117715-108.982857h623.542857a36.571429 36.571429 0 0 0 37.814857-15.798857 37.741714 37.741714 0 0 0 0-41.545143 36.571429 36.571429 0 0 0-37.814857-15.798857v-1.462857zM144.909897 877.714286c0-40.374857 32.329143-73.142857 72.118857-73.142857s72.118857 32.768 72.118857 73.142857c0 19.382857-7.606857 38.034286-21.211428 51.712a71.533714 71.533714 0 0 1-50.907429 21.430857 72.630857 72.630857 0 0 1-72.118857-73.142857zM43.972754 474.697143h623.616A144.530286 144.530286 0 0 1 806.706469 365.714286c64.804571 0.731429 121.124571 45.348571 137.654857 108.982857h34.596571a36.571429 36.571429 0 0 1 37.814857 15.798857 37.741714 37.741714 0 0 1 0 41.545143 36.571429 36.571429 0 0 1-37.814857 15.798857h-34.596571A144.603429 144.603429 0 0 1 806.779611 658.285714a144.530286 144.530286 0 0 1-139.117714-108.982857H44.045897a36.571429 36.571429 0 0 1-37.814857-15.798857 37.741714 37.741714 0 0 1 0-41.545143 36.571429 36.571429 0 0 1 37.814857-15.798857v-1.462857zM807.803611 585.142857a73.142857 73.142857 0 1 0 0-146.285714 73.142857 73.142857 0 0 0 0 146.285714z"
fill="#4A4A4A" fill="#000000"
opacity=".65" opacity=".65"
></path> ></path>
</svg> </svg>
); );
const Dispatcher = (props) => <Icon component={DispatcherSvg} {...props} />; const DesignSvg = () => (
<svg viewBox="0 0 1024 1024" width="1em" height="1em">
<path d="M832.256 133.162667l60.330667 60.373333a128 128 0 0 1 0 180.992l-108.16 108.202667 119.765333 119.765333a128 128 0 0 1 0 181.034667l-120.661333 120.661333a128 128 0 0 1-181.034667 0l-119.765333-119.765333-93.866667 93.866666a42.666667 42.666667 0 0 1-21.802667 11.648L140.757333 935.253333a42.666667 42.666667 0 0 1-50.176-50.218666l45.226667-226.261334a42.666667 42.666667 0 0 1 11.690667-21.76L651.221333 133.12a128 128 0 0 1 181.034667 0z m-93.098667 394.794666l-211.2 211.2 36.821334 36.821334 45.269333-45.226667a32 32 0 0 1 48.341333 41.642667l-3.072 3.584-45.226666 45.226666 37.674666 37.76a64 64 0 0 0 85.632 4.394667l4.864-4.394667 120.704-120.704a64 64 0 0 0 4.394667-85.632l-4.394667-4.864-119.808-119.808z m-155.818666-236.373333l-386.048 386.048-37.674667 188.586667 188.544-37.76 386.048-386.048-150.869333-150.826667zM415.36 114.048l6.144 5.76 121.557333 121.557333-45.226666 45.226667-121.6-121.557333a64 64 0 0 0-85.632-4.394667l-4.864 4.394667-120.704 120.704a64 64 0 0 0-4.394667 85.632l4.394667 4.864 37.717333 37.717333L278.186667 338.517333a32 32 0 0 1 48.341333 41.685334l-3.072 3.584-75.434667 75.434666 38.613334 38.570667-45.269334 45.226667-121.6-121.514667a128 128 0 0 1-5.717333-174.890667l5.76-6.144 120.661333-120.661333a128 128 0 0 1 174.890667-5.76z m281.173333 64.384l-67.925333 67.882667 150.869333 150.869333 67.84-67.882667a64 64 0 0 0 0-90.538666l-60.330666-60.330667a64 64 0 0 0-90.453334 0z"></path>
</svg>
);
Icon.register({ Dispatcher }); const Dispatcher = (props) => <Icon component={DispatcherSvg} {...props} />;
const Design = (props) => <Icon component={DesignSvg} {...props} />;
Icon.register({ Dispatcher, Design });
export class PluginWebhook extends Plugin { export class PluginWebhook extends Plugin {
async load() { async load() {

View File

@ -282,7 +282,12 @@
"Are you sure you want to resubmit it?": "Are you sure you want to resubmit it?", "Are you sure you want to resubmit it?": "Are you sure you want to resubmit it?",
"MyLaunch": "MyLaunch", "MyLaunch": "MyLaunch",
"CarbonCopy": "CarbonCopy", "CarbonCopy": "CarbonCopy",
"Initiate Request": "Initiate Request",
"My Requests": "My Requests",
"CC'd to Me": "CC'd to Me",
"My Pending Tasks": "My Pending Tasks",
"Common": "Common",
"ApprovalCarbonCopy": "Approval:CarbonCopy", "ApprovalCarbonCopy": "Approval:CarbonCopy",
"Approval Launch": "Approval Launch", "Approval Launch": "Approval Launch",
"needAuthorization": "needAuthorization" "needAuthorization": "needAuthorization"
} }

View File

@ -211,7 +211,7 @@
"No repeat": "不重复", "No repeat": "不重复",
"Node result": "节点数据", "Node result": "节点数据",
"Node type": "节点类型", "Node type": "节点类型",
"Notice Center": "工作流:通知中心", "Notice Center": "通知中心",
"Notice blocks": "通知区块", "Notice blocks": "通知区块",
"Notice": "通知", "Notice": "通知",
"Off": "停用", "Off": "停用",
@ -366,5 +366,10 @@
"CarbonCopy": "抄送", "CarbonCopy": "抄送",
"ApprovalCarbonCopy": "审批:抄送", "ApprovalCarbonCopy": "审批:抄送",
"Approval Launch": "审批发起", "Approval Launch": "审批发起",
"Initiate Request": "发起申请",
"My Requests": "我的申请",
"CC'd to Me": "抄送我的",
"My Pending Tasks": "我的代办",
"Common": "通用",
"needAuthorization": "是否携带权限校验" "needAuthorization": "是否携带权限校验"
} }