@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,267 @@
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
+ var __create = Object.create;
11
+ var __defProp = Object.defineProperty;
12
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
+ var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __getProtoOf = Object.getPrototypeOf;
15
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
16
+ var __export = (target, all) => {
17
+ for (var name in all)
18
+ __defProp(target, name, { get: all[name], enumerable: true });
19
+ };
20
+ var __copyProps = (to, from, except, desc) => {
21
+ if (from && typeof from === "object" || typeof from === "function") {
22
+ for (let key of __getOwnPropNames(from))
23
+ if (!__hasOwnProp.call(to, key) && key !== except)
24
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
25
+ }
26
+ return to;
27
+ };
28
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
29
+ // If the importer is in node compatibility mode or this is not an ESM
30
+ // file that has been converted to a CommonJS file using a Babel-
31
+ // compatible transform (i.e. "__esModule" has not been set), then set
32
+ // "default" to the CommonJS "module.exports" for node compatibility.
33
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
34
+ mod
35
+ ));
36
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
+ var flowModelTemplates_exports = {};
38
+ __export(flowModelTemplates_exports, {
39
+ default: () => flowModelTemplates_default
40
+ });
41
+ module.exports = __toCommonJS(flowModelTemplates_exports);
42
+ var import_actions = __toESM(require("@nocobase/actions"));
43
+ var import_lodash = __toESM(require("lodash"));
44
+ var import_utils = require("@nocobase/utils");
45
+ const toPlain = (row) => {
46
+ if (!row) return row;
47
+ if (typeof row.toJSON === "function") return row.toJSON();
48
+ return row;
49
+ };
50
+ const buildSearchFilter = (existing, search) => {
51
+ const filters = [];
52
+ if (existing) {
53
+ filters.push(existing);
54
+ }
55
+ if (search) {
56
+ filters.push({
57
+ $or: [{ name: { $includes: search } }, { description: { $includes: search } }]
58
+ });
59
+ }
60
+ if (!filters.length) return void 0;
61
+ if (filters.length === 1) return filters[0];
62
+ return { $and: filters };
63
+ };
64
+ const withUsageCounts = async (ctx, rows) => {
65
+ const data = rows.map(toPlain).filter(Boolean);
66
+ const uids = data.map((item) => item == null ? void 0 : item.uid).filter(Boolean);
67
+ if (!uids.length) return data;
68
+ const UsageModel = ctx.db.getModel("flowModelTemplateUsages");
69
+ const usageRows = await UsageModel.findAll({
70
+ attributes: ["templateUid", [UsageModel.sequelize.fn("COUNT", "*"), "count"]],
71
+ where: {
72
+ templateUid: uids
73
+ },
74
+ group: ["templateUid"],
75
+ raw: true,
76
+ transaction: ctx.transaction
77
+ });
78
+ const usageMap = /* @__PURE__ */ new Map();
79
+ for (const row of usageRows) {
80
+ usageMap.set(row.templateUid, Number(row.count) || 0);
81
+ }
82
+ return data.map((item) => ({
83
+ ...item,
84
+ usageCount: usageMap.get(item.uid) || 0
85
+ }));
86
+ };
87
+ const resolveTemplateUid = (ctx) => {
88
+ var _a, _b, _c;
89
+ const params = ((_a = ctx.action) == null ? void 0 : _a.params) || {};
90
+ if (params.filterByTk) return params.filterByTk;
91
+ if (typeof ((_b = params == null ? void 0 : params.filter) == null ? void 0 : _b.uid) === "string") return params.filter.uid;
92
+ if ((_c = params.values) == null ? void 0 : _c.uid) return params.values.uid;
93
+ return void 0;
94
+ };
95
+ const normalizeOptions = (options) => {
96
+ if (!options) return {};
97
+ if (typeof options === "string") {
98
+ try {
99
+ return JSON.parse(options);
100
+ } catch (e) {
101
+ return {};
102
+ }
103
+ }
104
+ return options;
105
+ };
106
+ const syncTemplateMetaToReferenceBlocks = async (ctx, template) => {
107
+ const usageRepo = ctx.db.getRepository("flowModelTemplateUsages");
108
+ const usages = await usageRepo.find({
109
+ filter: { templateUid: template.uid },
110
+ fields: ["modelUid"],
111
+ transaction: ctx.transaction,
112
+ context: ctx
113
+ });
114
+ if (!Array.isArray(usages) || usages.length === 0) return;
115
+ const modelUids = import_lodash.default.uniq(usages.map((u) => u == null ? void 0 : u.modelUid).filter(Boolean));
116
+ if (!modelUids.length) return;
117
+ const flowRepo = ctx.db.getRepository("flowModels");
118
+ for (const modelUid of modelUids) {
119
+ const record = await flowRepo.findOne({
120
+ filter: { uid: modelUid },
121
+ transaction: ctx.transaction
122
+ });
123
+ if (!record) continue;
124
+ const options = normalizeOptions(record.get("options"));
125
+ if ((options == null ? void 0 : options.use) !== "ReferenceBlockModel") continue;
126
+ const stepParams = (options == null ? void 0 : options.stepParams) || {};
127
+ const useTemplate = import_lodash.default.get(stepParams, ["referenceSettings", "useTemplate"]);
128
+ if (!useTemplate || useTemplate.templateUid !== template.uid) continue;
129
+ const nextOptions = import_lodash.default.cloneDeep(options);
130
+ import_lodash.default.set(nextOptions, ["stepParams", "referenceSettings", "useTemplate"], {
131
+ ...useTemplate,
132
+ templateName: template.name,
133
+ templateDescription: template.description
134
+ });
135
+ if (template.targetUid) {
136
+ const currentTarget = import_lodash.default.get(nextOptions, ["stepParams", "referenceSettings", "target", "targetUid"]);
137
+ if (!currentTarget) {
138
+ import_lodash.default.set(nextOptions, ["stepParams", "referenceSettings", "target", "targetUid"], template.targetUid);
139
+ }
140
+ }
141
+ await flowRepo.update({
142
+ filter: { uid: modelUid },
143
+ values: {
144
+ options: nextOptions
145
+ },
146
+ transaction: ctx.transaction,
147
+ context: ctx
148
+ });
149
+ }
150
+ };
151
+ var flowModelTemplates_default = {
152
+ name: "flowModelTemplates",
153
+ actions: {
154
+ async list(ctx, next) {
155
+ var _a, _b, _c, _d;
156
+ const search = (_b = (_a = ctx.action) == null ? void 0 : _a.params) == null ? void 0 : _b.search;
157
+ const mergedFilter = buildSearchFilter((_c = ctx.action.params) == null ? void 0 : _c.filter, search);
158
+ if (mergedFilter) {
159
+ ctx.action.mergeParams({ filter: mergedFilter });
160
+ }
161
+ await import_actions.default.list(ctx, next);
162
+ if (Array.isArray(ctx.body)) {
163
+ ctx.body = await withUsageCounts(ctx, ctx.body);
164
+ return;
165
+ }
166
+ const rows = Array.isArray((_d = ctx.body) == null ? void 0 : _d.rows) ? ctx.body.rows : [];
167
+ const rowsWithCount = await withUsageCounts(ctx, rows);
168
+ ctx.body = {
169
+ ...ctx.body,
170
+ rows: rowsWithCount
171
+ };
172
+ },
173
+ async get(ctx, next) {
174
+ await import_actions.default.get(ctx, next);
175
+ if (!ctx.body) return;
176
+ const [rowWithCount] = await withUsageCounts(ctx, [ctx.body]);
177
+ ctx.body = rowWithCount;
178
+ },
179
+ async create(ctx, next) {
180
+ var _a, _b;
181
+ const values = ((_a = ctx.action.params) == null ? void 0 : _a.values) || {};
182
+ const detachParent = !!values.detachParent || !!values.detachFromParent;
183
+ if (!values.uid) {
184
+ values.uid = (0, import_utils.uid)();
185
+ }
186
+ if (values.targetUid && typeof values.targetUid === "object") {
187
+ values.targetUid = values.targetUid.uid || ((_b = values.targetUid.data) == null ? void 0 : _b.uid) || String(values.targetUid);
188
+ }
189
+ ctx.action.mergeParams({
190
+ values: import_lodash.default.pick(values, [
191
+ "uid",
192
+ "name",
193
+ "description",
194
+ "targetUid",
195
+ "useModel",
196
+ "type",
197
+ "dataSourceKey",
198
+ "collectionName",
199
+ "associationName",
200
+ "filterByTk",
201
+ "sourceId"
202
+ ])
203
+ });
204
+ await import_actions.default.create(ctx, next);
205
+ if (ctx.body) {
206
+ ctx.body = {
207
+ ...toPlain(ctx.body),
208
+ usageCount: 0
209
+ };
210
+ if (detachParent && ctx.body.targetUid) {
211
+ const flowRepo = ctx.db.getRepository("flowModels");
212
+ await flowRepo.clearAncestor(ctx.body.targetUid, { transaction: ctx.transaction });
213
+ }
214
+ }
215
+ },
216
+ async update(ctx, next) {
217
+ var _a, _b, _c;
218
+ const values = ((_a = ctx.action.params) == null ? void 0 : _a.values) || {};
219
+ ctx.action.mergeParams({
220
+ values: import_lodash.default.pick(values, ["name", "description"])
221
+ });
222
+ await import_actions.default.update(ctx, next);
223
+ if (ctx.body) {
224
+ const rawData = ((_b = ctx.body) == null ? void 0 : _b.data) ?? ctx.body;
225
+ const rows = Array.isArray(rawData) ? rawData : [rawData];
226
+ const rowsWithCount = await withUsageCounts(ctx, rows);
227
+ const normalizedRow = Array.isArray(rawData) ? rowsWithCount : rowsWithCount == null ? void 0 : rowsWithCount[0];
228
+ ctx.body = ((_c = ctx.body) == null ? void 0 : _c.data) ? { ...ctx.body, data: normalizedRow } : normalizedRow;
229
+ const templateRow = Array.isArray(rowsWithCount) ? rowsWithCount[0] : rowsWithCount;
230
+ const templateUid = resolveTemplateUid(ctx) || (templateRow == null ? void 0 : templateRow.uid);
231
+ await syncTemplateMetaToReferenceBlocks(ctx, {
232
+ uid: templateUid,
233
+ name: templateRow == null ? void 0 : templateRow.name,
234
+ description: templateRow == null ? void 0 : templateRow.description,
235
+ targetUid: templateRow == null ? void 0 : templateRow.targetUid
236
+ });
237
+ }
238
+ },
239
+ async destroy(ctx, next) {
240
+ const templateUid = resolveTemplateUid(ctx);
241
+ if (!templateUid) {
242
+ return ctx.throw(400, "template uid is required");
243
+ }
244
+ const usageRepo = ctx.db.getRepository("flowModelTemplateUsages");
245
+ const usageCount = await usageRepo.count({
246
+ filter: {
247
+ templateUid
248
+ },
249
+ context: ctx
250
+ });
251
+ if (usageCount > 0) {
252
+ return ctx.throw(400, {
253
+ code: "TEMPLATE_IN_USE",
254
+ message: "Template is in use and cannot be deleted",
255
+ data: { usageCount }
256
+ });
257
+ }
258
+ await import_actions.default.destroy(ctx, next);
259
+ await usageRepo.destroy({
260
+ filter: {
261
+ templateUid
262
+ },
263
+ context: ctx
264
+ });
265
+ }
266
+ }
267
+ };
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@nocobase/plugin-ui-templates",
3
+ "displayName": "UI templates",
4
+ "displayName.zh-CN": "界面模板",
5
+ "description": "Provides block templates and popup templates for UI reuse.",
6
+ "description.zh-CN": "提供区块模板和弹窗模板复用的能力。",
7
+ "version": "2.0.0-alpha.57",
8
+ "license": "AGPL-3.0",
9
+ "main": "./dist/server/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "devDependencies": {
12
+ "@formily/shared": "2.x",
13
+ "antd": "5.x",
14
+ "react": "^18.2.0"
15
+ },
16
+ "peerDependencies": {
17
+ "@nocobase/client": "2.x",
18
+ "@nocobase/flow-engine": "2.x",
19
+ "@nocobase/plugin-flow-engine": "2.x",
20
+ "@nocobase/server": "2.x",
21
+ "@nocobase/test": "2.x"
22
+ },
23
+ "nocobase": {
24
+ "supportedVersions": [
25
+ "2.x"
26
+ ]
27
+ },
28
+ "keywords": [
29
+ "nocobase",
30
+ "plugin",
31
+ "ui",
32
+ "templates",
33
+ "block",
34
+ "popup"
35
+ ],
36
+ "gitHead": "b9ec8bc83fd86a9cadfc4fb2f87a4e015061b289"
37
+ }
package/server.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./dist/server/index.js');