@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.
- package/LICENSE.txt +172 -0
- package/build.config.ts +12 -0
- package/client.js +1 -0
- package/dist/client/collections/flowModelTemplates.d.ts +67 -0
- package/dist/client/components/FlowModelTemplatesPage.d.ts +12 -0
- package/dist/client/components/TemplateSelectOption.d.ts +20 -0
- package/dist/client/constants.d.ts +9 -0
- package/dist/client/hooks/useFlowModelTemplateActions.d.ts +24 -0
- package/dist/client/index.d.ts +13 -0
- package/dist/client/index.js +10 -0
- package/dist/client/locale.d.ts +18 -0
- package/dist/client/menuExtensions.d.ts +9 -0
- package/dist/client/models/ReferenceBlockModel.d.ts +47 -0
- package/dist/client/models/ReferenceFormGridModel.d.ts +38 -0
- package/dist/client/models/SubModelTemplateImporterModel.d.ts +55 -0
- package/dist/client/models/referenceShared.d.ts +23 -0
- package/dist/client/openViewActionExtensions.d.ts +10 -0
- package/dist/client/schemas/flowModelTemplates.d.ts +11 -0
- package/dist/client/subModelMenuExtensions.d.ts +10 -0
- package/dist/client/utils/infiniteSelect.d.ts +28 -0
- package/dist/client/utils/refHost.d.ts +20 -0
- package/dist/client/utils/templateCompatibility.d.ts +91 -0
- package/dist/client.d.ts +9 -0
- package/dist/client.js +42 -0
- package/dist/externalVersion.js +24 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +48 -0
- package/dist/locale/de-DE.json +14 -0
- package/dist/locale/en-US.json +72 -0
- package/dist/locale/es-ES.json +14 -0
- package/dist/locale/fr-FR.json +14 -0
- package/dist/locale/hu-HU.json +14 -0
- package/dist/locale/id-ID.json +14 -0
- package/dist/locale/it-IT.json +14 -0
- package/dist/locale/ja-JP.json +14 -0
- package/dist/locale/ko-KR.json +14 -0
- package/dist/locale/nl-NL.json +14 -0
- package/dist/locale/pt-BR.json +14 -0
- package/dist/locale/ru-RU.json +14 -0
- package/dist/locale/tr-TR.json +14 -0
- package/dist/locale/uk-UA.json +14 -0
- package/dist/locale/vi-VN.json +14 -0
- package/dist/locale/zh-CN.json +71 -0
- package/dist/locale/zh-TW.json +14 -0
- package/dist/server/collections/flowModelTemplateUsages.d.ts +11 -0
- package/dist/server/collections/flowModelTemplateUsages.js +71 -0
- package/dist/server/collections/flowModelTemplates.d.ts +11 -0
- package/dist/server/collections/flowModelTemplates.js +96 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.js +42 -0
- package/dist/server/plugin.d.ts +17 -0
- package/dist/server/plugin.js +242 -0
- package/dist/server/resources/flowModelTemplateUsages.d.ts +19 -0
- package/dist/server/resources/flowModelTemplateUsages.js +91 -0
- package/dist/server/resources/flowModelTemplates.d.ts +20 -0
- package/dist/server/resources/flowModelTemplates.js +267 -0
- package/package.json +37 -0
- package/server.js +1 -0
- package/src/client/__tests__/openViewActionExtensions.test.ts +1208 -0
- package/src/client/collections/flowModelTemplates.ts +131 -0
- package/src/client/components/FlowModelTemplatesPage.tsx +78 -0
- package/src/client/components/TemplateSelectOption.tsx +106 -0
- package/src/client/constants.ts +10 -0
- package/src/client/hooks/useFlowModelTemplateActions.tsx +137 -0
- package/src/client/index.ts +54 -0
- package/src/client/locale.ts +40 -0
- package/src/client/menuExtensions.tsx +1033 -0
- package/src/client/models/ReferenceBlockModel.tsx +793 -0
- package/src/client/models/ReferenceFormGridModel.tsx +302 -0
- package/src/client/models/SubModelTemplateImporterModel.tsx +634 -0
- package/src/client/models/__tests__/ReferenceBlockModel.test.tsx +482 -0
- package/src/client/models/__tests__/ReferenceFormGridModel.test.tsx +175 -0
- package/src/client/models/__tests__/SubModelTemplateImporterModel.test.ts +447 -0
- package/src/client/models/referenceShared.tsx +99 -0
- package/src/client/openViewActionExtensions.tsx +981 -0
- package/src/client/schemas/flowModelTemplates.ts +264 -0
- package/src/client/subModelMenuExtensions.ts +103 -0
- package/src/client/utils/infiniteSelect.ts +150 -0
- package/src/client/utils/refHost.ts +44 -0
- package/src/client/utils/templateCompatibility.ts +374 -0
- package/src/client.ts +10 -0
- package/src/index.ts +11 -0
- package/src/locale/de-DE.json +14 -0
- package/src/locale/en-US.json +72 -0
- package/src/locale/es-ES.json +14 -0
- package/src/locale/fr-FR.json +14 -0
- package/src/locale/hu-HU.json +14 -0
- package/src/locale/id-ID.json +14 -0
- package/src/locale/it-IT.json +14 -0
- package/src/locale/ja-JP.json +14 -0
- package/src/locale/ko-KR.json +14 -0
- package/src/locale/nl-NL.json +14 -0
- package/src/locale/pt-BR.json +14 -0
- package/src/locale/ru-RU.json +14 -0
- package/src/locale/tr-TR.json +14 -0
- package/src/locale/uk-UA.json +14 -0
- package/src/locale/vi-VN.json +14 -0
- package/src/locale/zh-CN.json +71 -0
- package/src/locale/zh-TW.json +14 -0
- package/src/server/__tests__/template-usage.test.ts +351 -0
- package/src/server/collections/flowModelTemplateUsages.ts +51 -0
- package/src/server/collections/flowModelTemplates.ts +76 -0
- package/src/server/index.ts +10 -0
- package/src/server/plugin.ts +236 -0
- package/src/server/resources/flowModelTemplateUsages.ts +61 -0
- 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');
|