@nocobase/plugin-ui-templates 2.0.0-alpha.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/LICENSE.txt +172 -0
  2. package/build.config.ts +12 -0
  3. package/client.js +1 -0
  4. package/dist/client/collections/flowModelTemplates.d.ts +67 -0
  5. package/dist/client/components/FlowModelTemplatesPage.d.ts +12 -0
  6. package/dist/client/components/TemplateSelectOption.d.ts +20 -0
  7. package/dist/client/constants.d.ts +9 -0
  8. package/dist/client/hooks/useFlowModelTemplateActions.d.ts +24 -0
  9. package/dist/client/index.d.ts +13 -0
  10. package/dist/client/index.js +10 -0
  11. package/dist/client/locale.d.ts +18 -0
  12. package/dist/client/menuExtensions.d.ts +9 -0
  13. package/dist/client/models/ReferenceBlockModel.d.ts +47 -0
  14. package/dist/client/models/ReferenceFormGridModel.d.ts +38 -0
  15. package/dist/client/models/SubModelTemplateImporterModel.d.ts +55 -0
  16. package/dist/client/models/referenceShared.d.ts +23 -0
  17. package/dist/client/openViewActionExtensions.d.ts +10 -0
  18. package/dist/client/schemas/flowModelTemplates.d.ts +11 -0
  19. package/dist/client/subModelMenuExtensions.d.ts +10 -0
  20. package/dist/client/utils/infiniteSelect.d.ts +28 -0
  21. package/dist/client/utils/refHost.d.ts +20 -0
  22. package/dist/client/utils/templateCompatibility.d.ts +91 -0
  23. package/dist/client.d.ts +9 -0
  24. package/dist/client.js +42 -0
  25. package/dist/externalVersion.js +24 -0
  26. package/dist/index.d.ts +10 -0
  27. package/dist/index.js +48 -0
  28. package/dist/locale/de-DE.json +14 -0
  29. package/dist/locale/en-US.json +72 -0
  30. package/dist/locale/es-ES.json +14 -0
  31. package/dist/locale/fr-FR.json +14 -0
  32. package/dist/locale/hu-HU.json +14 -0
  33. package/dist/locale/id-ID.json +14 -0
  34. package/dist/locale/it-IT.json +14 -0
  35. package/dist/locale/ja-JP.json +14 -0
  36. package/dist/locale/ko-KR.json +14 -0
  37. package/dist/locale/nl-NL.json +14 -0
  38. package/dist/locale/pt-BR.json +14 -0
  39. package/dist/locale/ru-RU.json +14 -0
  40. package/dist/locale/tr-TR.json +14 -0
  41. package/dist/locale/uk-UA.json +14 -0
  42. package/dist/locale/vi-VN.json +14 -0
  43. package/dist/locale/zh-CN.json +71 -0
  44. package/dist/locale/zh-TW.json +14 -0
  45. package/dist/server/collections/flowModelTemplateUsages.d.ts +11 -0
  46. package/dist/server/collections/flowModelTemplateUsages.js +71 -0
  47. package/dist/server/collections/flowModelTemplates.d.ts +11 -0
  48. package/dist/server/collections/flowModelTemplates.js +96 -0
  49. package/dist/server/index.d.ts +9 -0
  50. package/dist/server/index.js +42 -0
  51. package/dist/server/plugin.d.ts +17 -0
  52. package/dist/server/plugin.js +242 -0
  53. package/dist/server/resources/flowModelTemplateUsages.d.ts +19 -0
  54. package/dist/server/resources/flowModelTemplateUsages.js +91 -0
  55. package/dist/server/resources/flowModelTemplates.d.ts +20 -0
  56. package/dist/server/resources/flowModelTemplates.js +267 -0
  57. package/package.json +37 -0
  58. package/server.js +1 -0
  59. package/src/client/__tests__/openViewActionExtensions.test.ts +1208 -0
  60. package/src/client/collections/flowModelTemplates.ts +131 -0
  61. package/src/client/components/FlowModelTemplatesPage.tsx +78 -0
  62. package/src/client/components/TemplateSelectOption.tsx +106 -0
  63. package/src/client/constants.ts +10 -0
  64. package/src/client/hooks/useFlowModelTemplateActions.tsx +137 -0
  65. package/src/client/index.ts +54 -0
  66. package/src/client/locale.ts +40 -0
  67. package/src/client/menuExtensions.tsx +1033 -0
  68. package/src/client/models/ReferenceBlockModel.tsx +793 -0
  69. package/src/client/models/ReferenceFormGridModel.tsx +302 -0
  70. package/src/client/models/SubModelTemplateImporterModel.tsx +634 -0
  71. package/src/client/models/__tests__/ReferenceBlockModel.test.tsx +482 -0
  72. package/src/client/models/__tests__/ReferenceFormGridModel.test.tsx +175 -0
  73. package/src/client/models/__tests__/SubModelTemplateImporterModel.test.ts +447 -0
  74. package/src/client/models/referenceShared.tsx +99 -0
  75. package/src/client/openViewActionExtensions.tsx +981 -0
  76. package/src/client/schemas/flowModelTemplates.ts +264 -0
  77. package/src/client/subModelMenuExtensions.ts +103 -0
  78. package/src/client/utils/infiniteSelect.ts +150 -0
  79. package/src/client/utils/refHost.ts +44 -0
  80. package/src/client/utils/templateCompatibility.ts +374 -0
  81. package/src/client.ts +10 -0
  82. package/src/index.ts +11 -0
  83. package/src/locale/de-DE.json +14 -0
  84. package/src/locale/en-US.json +72 -0
  85. package/src/locale/es-ES.json +14 -0
  86. package/src/locale/fr-FR.json +14 -0
  87. package/src/locale/hu-HU.json +14 -0
  88. package/src/locale/id-ID.json +14 -0
  89. package/src/locale/it-IT.json +14 -0
  90. package/src/locale/ja-JP.json +14 -0
  91. package/src/locale/ko-KR.json +14 -0
  92. package/src/locale/nl-NL.json +14 -0
  93. package/src/locale/pt-BR.json +14 -0
  94. package/src/locale/ru-RU.json +14 -0
  95. package/src/locale/tr-TR.json +14 -0
  96. package/src/locale/uk-UA.json +14 -0
  97. package/src/locale/vi-VN.json +14 -0
  98. package/src/locale/zh-CN.json +71 -0
  99. package/src/locale/zh-TW.json +14 -0
  100. package/src/server/__tests__/template-usage.test.ts +351 -0
  101. package/src/server/collections/flowModelTemplateUsages.ts +51 -0
  102. package/src/server/collections/flowModelTemplates.ts +76 -0
  103. package/src/server/index.ts +10 -0
  104. package/src/server/plugin.ts +236 -0
  105. package/src/server/resources/flowModelTemplateUsages.ts +61 -0
  106. package/src/server/resources/flowModelTemplates.ts +251 -0
@@ -0,0 +1,131 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ import { tStr } from '../locale';
11
+
12
+ export const flowModelTemplatesCollection = {
13
+ name: 'flowModelTemplates',
14
+ filterTargetKey: 'uid',
15
+ fields: [
16
+ {
17
+ type: 'string',
18
+ name: 'name',
19
+ interface: 'input',
20
+ uiSchema: {
21
+ type: 'string',
22
+ title: tStr('Template name'),
23
+ required: true,
24
+ 'x-component': 'Input',
25
+ },
26
+ },
27
+ {
28
+ type: 'string',
29
+ name: 'description',
30
+ interface: 'textarea',
31
+ uiSchema: {
32
+ type: 'string',
33
+ title: tStr('Template description'),
34
+ 'x-component': 'Input.TextArea',
35
+ 'x-component-props': {
36
+ rows: 3,
37
+ },
38
+ },
39
+ },
40
+ {
41
+ type: 'string',
42
+ name: 'targetUid',
43
+ interface: 'input',
44
+ uiSchema: {
45
+ type: 'string',
46
+ title: 'targetUid',
47
+ 'x-component': 'Input',
48
+ 'x-disabled': true,
49
+ },
50
+ },
51
+ {
52
+ type: 'string',
53
+ name: 'useModel',
54
+ interface: 'input',
55
+ uiSchema: {
56
+ type: 'string',
57
+ title: 'useModel',
58
+ 'x-component': 'Input',
59
+ 'x-disabled': true,
60
+ 'x-hidden': true,
61
+ },
62
+ },
63
+ {
64
+ type: 'string',
65
+ name: 'dataSourceKey',
66
+ interface: 'input',
67
+ uiSchema: {
68
+ type: 'string',
69
+ title: 'dataSourceKey',
70
+ 'x-component': 'Input',
71
+ 'x-disabled': true,
72
+ },
73
+ },
74
+ {
75
+ type: 'string',
76
+ name: 'collectionName',
77
+ interface: 'input',
78
+ uiSchema: {
79
+ type: 'string',
80
+ title: 'collectionName',
81
+ 'x-component': 'Input',
82
+ 'x-disabled': true,
83
+ },
84
+ },
85
+ {
86
+ type: 'string',
87
+ name: 'associationName',
88
+ interface: 'input',
89
+ uiSchema: {
90
+ type: 'string',
91
+ title: 'associationName',
92
+ 'x-component': 'Input',
93
+ 'x-disabled': true,
94
+ 'x-hidden': true,
95
+ },
96
+ },
97
+ {
98
+ type: 'string',
99
+ name: 'filterByTk',
100
+ interface: 'input',
101
+ uiSchema: {
102
+ type: 'string',
103
+ title: 'filterByTk',
104
+ 'x-component': 'Input',
105
+ 'x-disabled': true,
106
+ },
107
+ },
108
+ {
109
+ type: 'string',
110
+ name: 'sourceId',
111
+ interface: 'input',
112
+ uiSchema: {
113
+ type: 'string',
114
+ title: 'sourceId',
115
+ 'x-component': 'Input',
116
+ 'x-disabled': true,
117
+ },
118
+ },
119
+ {
120
+ type: 'number',
121
+ name: 'usageCount',
122
+ interface: 'number',
123
+ uiSchema: {
124
+ type: 'number',
125
+ title: tStr('Usage count'),
126
+ 'x-component': 'InputNumber',
127
+ 'x-disabled': true,
128
+ },
129
+ },
130
+ ],
131
+ };
@@ -0,0 +1,78 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ import React, { useMemo } from 'react';
11
+ import {
12
+ ExtendCollectionsProvider,
13
+ SchemaComponent,
14
+ SchemaComponentContext,
15
+ useSchemaComponentContext,
16
+ } from '@nocobase/client';
17
+ import { createFlowModelTemplatesSchema } from '../schemas/flowModelTemplates';
18
+ import {
19
+ useFlowModelTemplateDeleteActionProps,
20
+ useFlowModelTemplateEditActionProps,
21
+ useFlowModelTemplateEditFormProps,
22
+ useFlowModelTemplateSearchProps,
23
+ } from '../hooks/useFlowModelTemplateActions';
24
+ import { flowModelTemplatesCollection } from '../collections/flowModelTemplates';
25
+
26
+ const TemplateTable: React.FC<{ filter?: Record<string, any> }> = ({ filter }) => {
27
+ const scCtx = useSchemaComponentContext();
28
+ const schema = useMemo(() => createFlowModelTemplatesSchema(filter), [filter]);
29
+
30
+ return (
31
+ <SchemaComponentContext.Provider value={{ ...scCtx, designable: false }}>
32
+ <SchemaComponent
33
+ schema={schema}
34
+ scope={{
35
+ useFlowModelTemplateSearchProps,
36
+ useFlowModelTemplateEditFormProps,
37
+ useFlowModelTemplateEditActionProps,
38
+ useFlowModelTemplateDeleteActionProps,
39
+ }}
40
+ />
41
+ </SchemaComponentContext.Provider>
42
+ );
43
+ };
44
+
45
+ // 区块模板页面: type 不是 popup 的(包括 null 和空)
46
+ export const BlockTemplatesPage: React.FC = () => {
47
+ const blockTemplateFilter = useMemo(
48
+ () => ({
49
+ $or: [{ type: { $ne: 'popup' } }, { type: { $empty: true } }],
50
+ }),
51
+ [],
52
+ );
53
+
54
+ return (
55
+ <ExtendCollectionsProvider collections={[flowModelTemplatesCollection]}>
56
+ <TemplateTable filter={blockTemplateFilter} />
57
+ </ExtendCollectionsProvider>
58
+ );
59
+ };
60
+
61
+ // 弹窗模板页面: type 是 popup 的
62
+ export const PopupTemplatesPage: React.FC = () => {
63
+ const popupTemplateFilter = useMemo(
64
+ () => ({
65
+ type: 'popup',
66
+ }),
67
+ [],
68
+ );
69
+
70
+ return (
71
+ <ExtendCollectionsProvider collections={[flowModelTemplatesCollection]}>
72
+ <TemplateTable filter={popupTemplateFilter} />
73
+ </ExtendCollectionsProvider>
74
+ );
75
+ };
76
+
77
+ // 保留原来的导出以兼容
78
+ export const FlowModelTemplatesPage = BlockTemplatesPage;
@@ -0,0 +1,106 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ import React from 'react';
11
+ import { Tooltip, Typography } from 'antd';
12
+
13
+ const NAME_MAX_WIDTH = 480;
14
+ const OPTION_MAX_WIDTH = 520;
15
+ const TOOLTIP_MAX_WIDTH = 400;
16
+
17
+ export function renderTemplateSelectLabel(name: React.ReactNode, maxWidth = NAME_MAX_WIDTH) {
18
+ return (
19
+ <span
20
+ style={{
21
+ display: 'inline-block',
22
+ maxWidth,
23
+ overflow: 'hidden',
24
+ textOverflow: 'ellipsis',
25
+ whiteSpace: 'nowrap',
26
+ verticalAlign: 'middle',
27
+ }}
28
+ >
29
+ {name}
30
+ </span>
31
+ );
32
+ }
33
+
34
+ export type TemplateSelectOptionData = {
35
+ rawName?: React.ReactNode;
36
+ description?: React.ReactNode;
37
+ disabledReason?: React.ReactNode;
38
+ };
39
+
40
+ export type TemplateSelectOptionRenderArg = {
41
+ label?: React.ReactNode;
42
+ data?: TemplateSelectOptionData;
43
+ };
44
+
45
+ export function renderTemplateSelectOption(option: TemplateSelectOptionRenderArg) {
46
+ const desc = option?.data?.description;
47
+ const disabledReason = option?.data?.disabledReason;
48
+ const isDisabled = !!disabledReason;
49
+ const name = option?.data?.rawName || option?.label;
50
+
51
+ const content = (
52
+ <div
53
+ style={{
54
+ display: 'flex',
55
+ flexDirection: 'column',
56
+ gap: 4,
57
+ padding: '4px 0',
58
+ maxWidth: OPTION_MAX_WIDTH,
59
+ opacity: isDisabled ? 0.5 : 1,
60
+ width: '100%',
61
+ cursor: isDisabled ? 'not-allowed' : 'pointer',
62
+ }}
63
+ >
64
+ <Typography.Text
65
+ strong
66
+ style={{
67
+ maxWidth: NAME_MAX_WIDTH,
68
+ overflow: 'hidden',
69
+ textOverflow: 'ellipsis',
70
+ whiteSpace: 'nowrap',
71
+ }}
72
+ >
73
+ {name}
74
+ </Typography.Text>
75
+ {desc && (
76
+ <Typography.Text
77
+ type="secondary"
78
+ style={{
79
+ fontSize: 12,
80
+ lineHeight: 1.4,
81
+ whiteSpace: 'normal',
82
+ wordBreak: 'break-word',
83
+ }}
84
+ >
85
+ {desc}
86
+ </Typography.Text>
87
+ )}
88
+ </div>
89
+ );
90
+
91
+ if (isDisabled && disabledReason) {
92
+ return (
93
+ <Tooltip
94
+ title={disabledReason}
95
+ placement="right"
96
+ zIndex={9999}
97
+ overlayStyle={{ maxWidth: TOOLTIP_MAX_WIDTH }}
98
+ mouseEnterDelay={0.1}
99
+ >
100
+ <div style={{ width: '100%' }}>{content}</div>
101
+ </Tooltip>
102
+ );
103
+ }
104
+
105
+ return content;
106
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ export const REF_HOST_CTX_KEY = '__subModelReferenceHost';
@@ -0,0 +1,137 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ import { createForm } from '@formily/core';
11
+ import { useForm } from '@formily/react';
12
+ import {
13
+ ActionProps,
14
+ useActionContext,
15
+ useBlockRequestContext,
16
+ useCollection,
17
+ useCollectionRecordData,
18
+ useDataBlockResource,
19
+ } from '@nocobase/client';
20
+ import { App as AntdApp } from 'antd';
21
+ import { useCallback, useEffect, useMemo, useState } from 'react';
22
+ import { useT } from '../locale';
23
+
24
+ export const useFlowModelTemplateSearchProps = () => {
25
+ const { service } = useBlockRequestContext();
26
+ const t = useT();
27
+ const [keyword, setKeyword] = useState('');
28
+
29
+ useEffect(() => {
30
+ const current = service?.params?.[0]?.search;
31
+ setKeyword(current || '');
32
+ }, [service?.params]);
33
+
34
+ const doSearch = useCallback(
35
+ (value: string) => {
36
+ const params = { ...(service?.params?.[0] || {}) };
37
+ if (value) {
38
+ params.search = value;
39
+ } else {
40
+ delete params.search;
41
+ }
42
+ service?.run?.({ ...params, page: 1 });
43
+ },
44
+ [service],
45
+ );
46
+
47
+ return {
48
+ placeholder: t('Search templates'),
49
+ value: keyword,
50
+ onChange: (e: any) => {
51
+ const next = e?.target?.value ?? '';
52
+ setKeyword(next);
53
+ if (!next) {
54
+ doSearch('');
55
+ }
56
+ },
57
+ onSearch: (value: string) => doSearch(value?.trim?.() || ''),
58
+ allowClear: true,
59
+ style: { width: 260 },
60
+ };
61
+ };
62
+
63
+ export const useFlowModelTemplateEditFormProps = () => {
64
+ const recordData = useCollectionRecordData();
65
+ const form = useMemo(
66
+ () =>
67
+ createForm({
68
+ initialValues: recordData,
69
+ }),
70
+ [recordData],
71
+ );
72
+
73
+ return {
74
+ form,
75
+ };
76
+ };
77
+
78
+ export const useFlowModelTemplateEditActionProps = (): ActionProps => {
79
+ const { setVisible } = useActionContext();
80
+ const { message } = AntdApp.useApp();
81
+ const form = useForm();
82
+ const resource = useDataBlockResource();
83
+ const collection = useCollection();
84
+ const { service } = useBlockRequestContext();
85
+ const t = useT();
86
+
87
+ return {
88
+ type: 'primary',
89
+ async onClick() {
90
+ await form.submit();
91
+ const values = form.values;
92
+ await resource.update({
93
+ values: {
94
+ name: values.name,
95
+ description: values.description,
96
+ },
97
+ filterByTk: values[collection.filterTargetKey],
98
+ });
99
+ await service?.refresh?.();
100
+ message.success(t('Saved'));
101
+ setVisible?.(false);
102
+ },
103
+ };
104
+ };
105
+
106
+ export const useFlowModelTemplateDeleteActionProps = (): ActionProps => {
107
+ const record = useCollectionRecordData();
108
+ const collection = useCollection();
109
+ const resource = useDataBlockResource();
110
+ const { service } = useBlockRequestContext();
111
+ const { message } = AntdApp.useApp();
112
+ const t = useT();
113
+
114
+ const inUse = (record?.usageCount || 0) > 0;
115
+
116
+ return {
117
+ danger: true,
118
+ disabled: inUse,
119
+ confirm: inUse
120
+ ? undefined
121
+ : {
122
+ title: t('Delete template'),
123
+ content: t('Are you sure you want to delete this item? This action cannot be undone.'),
124
+ },
125
+ async onClick() {
126
+ if (inUse) {
127
+ message.warning(t('Template is in use and cannot be deleted'));
128
+ return;
129
+ }
130
+ await resource.destroy({
131
+ filterByTk: record?.[collection.filterTargetKey],
132
+ });
133
+ await service?.refresh?.();
134
+ message.success(t('Deleted'));
135
+ },
136
+ };
137
+ };
@@ -0,0 +1,54 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ import { Plugin } from '@nocobase/client';
11
+ import { ReferenceBlockModel } from './models/ReferenceBlockModel';
12
+ import { ReferenceFormGridModel } from './models/ReferenceFormGridModel';
13
+ import { SubModelTemplateImporterModel } from './models/SubModelTemplateImporterModel';
14
+ import { BlockTemplatesPage, PopupTemplatesPage } from './components/FlowModelTemplatesPage';
15
+ // @ts-ignore
16
+ import pkg from '../../package.json';
17
+ import { registerMenuExtensions } from './menuExtensions';
18
+ import { registerSubModelMenuExtensions } from './subModelMenuExtensions';
19
+ import { registerOpenViewPopupTemplateAction } from './openViewActionExtensions';
20
+
21
+ const NAMESPACE = 'ui-templates';
22
+
23
+ export class PluginBlockReferenceClient extends Plugin {
24
+ async load() {
25
+ this.flowEngine.registerModels({
26
+ ReferenceBlockModel,
27
+ ReferenceFormGridModel,
28
+ SubModelTemplateImporterModel,
29
+ });
30
+ registerSubModelMenuExtensions(this.flowEngine);
31
+ registerOpenViewPopupTemplateAction(this.flowEngine);
32
+
33
+ // 父级菜单(只有标题,无组件)
34
+ this.app.pluginSettingsManager.add(NAMESPACE, {
35
+ title: `{{t("UI templates", { ns: "${pkg.name}", nsMode: "fallback" })}}`,
36
+ icon: 'ProfileOutlined',
37
+ });
38
+
39
+ // 子级:区块模板 (v2)
40
+ this.app.pluginSettingsManager.add(`${NAMESPACE}.block`, {
41
+ title: `{{t("Block templates (v2)", { ns: "${pkg.name}", nsMode: "fallback" })}}`,
42
+ Component: BlockTemplatesPage,
43
+ });
44
+
45
+ // 子级:弹窗模板 (v2)
46
+ this.app.pluginSettingsManager.add(`${NAMESPACE}.popup`, {
47
+ title: `{{t("Popup templates (v2)", { ns: "${pkg.name}", nsMode: "fallback" })}}`,
48
+ Component: PopupTemplatesPage,
49
+ });
50
+ registerMenuExtensions();
51
+ }
52
+ }
53
+
54
+ export default PluginBlockReferenceClient;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ // @ts-ignore
11
+ import pkg from '../../package.json';
12
+ import { useApp } from '@nocobase/client';
13
+ import type { FlowModel } from '@nocobase/flow-engine';
14
+
15
+ export const NAMESPACE = pkg.name;
16
+
17
+ export function useT() {
18
+ const app = useApp();
19
+ return (str: string, options?: Record<string, any>) =>
20
+ app.i18n.t(str, { ns: [pkg.name, 'client'], ...(options || {}) });
21
+ }
22
+
23
+ export function tStr(key: string) {
24
+ return `{{t(${JSON.stringify(key)}, { ns: ['${pkg.name}', 'client'], nsMode: 'fallback' })}}`;
25
+ }
26
+
27
+ /**
28
+ * 获取带有插件命名空间的翻译函数(用于非组件环境)
29
+ * @param model FlowModel 实例
30
+ * @returns 翻译函数,使用插件命名空间
31
+ */
32
+ export function getPluginT(model: FlowModel): (key: string, options?: any) => string {
33
+ if (model.flowEngine?.translate) {
34
+ return (key: string, options?: any) => {
35
+ return model.flowEngine.translate(key, { ns: [pkg.name, 'client'], nsMode: 'fallback', ...options });
36
+ };
37
+ }
38
+ // 回退到原始键值
39
+ return (key: string) => key;
40
+ }