@nocobase/plugin-multi-app-manager 0.11.1-alpha.4 → 0.12.0-alpha.1

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 (61) hide show
  1. package/client.d.ts +1 -3
  2. package/client.js +1 -1
  3. package/dist/client/index.js +500 -0
  4. package/{lib → dist}/index.d.ts +1 -0
  5. package/dist/index.js +18 -0
  6. package/dist/locale/es-ES.js +13 -0
  7. package/dist/locale/pt-BR.js +13 -0
  8. package/dist/locale/zh-CN.js +15 -0
  9. package/dist/server/collections/applications.js +49 -0
  10. package/dist/server/index.js +21 -0
  11. package/dist/server/models/application.js +22 -0
  12. package/dist/server/server.js +260 -0
  13. package/package.json +15 -24
  14. package/server.d.ts +2 -3
  15. package/server.js +1 -1
  16. package/lib/client/AppManager.js +0 -61
  17. package/lib/client/AppNameInput.js +0 -40
  18. package/lib/client/MultiAppManagerProvider.js +0 -119
  19. package/lib/client/Settings.js +0 -39
  20. package/lib/client/index.js +0 -34
  21. package/lib/client/settings/schemas/applications.js +0 -404
  22. package/lib/client/utils.js +0 -25
  23. package/lib/index.js +0 -13
  24. package/lib/locale/es-ES.js +0 -16
  25. package/lib/locale/pt-BR.js +0 -16
  26. package/lib/locale/zh-CN.js +0 -18
  27. package/lib/server/collections/applications.js +0 -49
  28. package/lib/server/index.js +0 -19
  29. package/lib/server/models/application.js +0 -39
  30. package/lib/server/server.js +0 -367
  31. package/src/client/AppManager.tsx +0 -31
  32. package/src/client/AppNameInput.tsx +0 -22
  33. package/src/client/MultiAppManagerProvider.tsx +0 -93
  34. package/src/client/Settings.tsx +0 -15
  35. package/src/client/index.ts +0 -11
  36. package/src/client/settings/schemas/applications.ts +0 -376
  37. package/src/client/utils.tsx +0 -10
  38. package/src/index.ts +0 -1
  39. package/src/locale/es-ES.ts +0 -9
  40. package/src/locale/pt-BR.ts +0 -9
  41. package/src/locale/zh-CN.ts +0 -11
  42. package/src/server/__tests__/mock-get-schema.test.ts +0 -146
  43. package/src/server/__tests__/multiple-apps.test.ts +0 -209
  44. package/src/server/collections/applications.ts +0 -45
  45. package/src/server/index.ts +0 -4
  46. package/src/server/models/application.ts +0 -28
  47. package/src/server/server.ts +0 -297
  48. package/{lib → dist}/client/AppManager.d.ts +0 -0
  49. package/{lib → dist}/client/AppNameInput.d.ts +0 -0
  50. package/{lib → dist}/client/MultiAppManagerProvider.d.ts +0 -0
  51. package/{lib → dist}/client/Settings.d.ts +0 -0
  52. package/{lib → dist}/client/index.d.ts +1 -1
  53. /package/{lib → dist}/client/settings/schemas/applications.d.ts +0 -0
  54. /package/{lib → dist}/client/utils.d.ts +0 -0
  55. /package/{lib → dist}/locale/es-ES.d.ts +0 -0
  56. /package/{lib → dist}/locale/pt-BR.d.ts +0 -0
  57. /package/{lib → dist}/locale/zh-CN.d.ts +0 -0
  58. /package/{lib → dist}/server/collections/applications.d.ts +0 -0
  59. /package/{lib → dist}/server/index.d.ts +0 -0
  60. /package/{lib → dist}/server/models/application.d.ts +0 -0
  61. /package/{lib → dist}/server/server.d.ts +0 -0
@@ -1,376 +0,0 @@
1
- import { ISchema } from '@formily/react';
2
- import { uid } from '@formily/shared';
3
- import {
4
- useActionContext,
5
- useRecord,
6
- useRequest,
7
- useResourceActionContext,
8
- useResourceContext,
9
- } from '@nocobase/client';
10
- import { i18nText } from '../../utils';
11
-
12
- const collection = {
13
- name: 'applications',
14
- targetKey: 'name',
15
- fields: [
16
- {
17
- type: 'uid',
18
- name: 'name',
19
- primaryKey: true,
20
- prefix: 'a',
21
- interface: 'input',
22
- uiSchema: {
23
- type: 'string',
24
- title: i18nText('App ID'),
25
- required: true,
26
- 'x-component': 'Input',
27
- 'x-validator': 'uid',
28
- },
29
- },
30
- {
31
- type: 'string',
32
- name: 'displayName',
33
- interface: 'input',
34
- uiSchema: {
35
- type: 'string',
36
- title: i18nText('App display name'),
37
- required: true,
38
- 'x-component': 'Input',
39
- },
40
- },
41
- {
42
- type: 'string',
43
- name: 'pinned',
44
- interface: 'checkbox',
45
- uiSchema: {
46
- type: 'boolean',
47
- 'x-content': i18nText('Pin to menu'),
48
- 'x-component': 'Checkbox',
49
- },
50
- },
51
- {
52
- type: 'string',
53
- name: 'status',
54
- interface: 'radioGroup',
55
- defaultValue: 'pending',
56
- uiSchema: {
57
- type: 'string',
58
- title: i18nText('App status'),
59
- enum: [
60
- { label: 'Pending', value: 'pending' },
61
- { label: 'Running', value: 'running' },
62
- ],
63
- 'x-component': 'Radio.Group',
64
- },
65
- },
66
- ],
67
- };
68
-
69
- export const useDestroy = () => {
70
- const { refresh } = useResourceActionContext();
71
- const { resource, targetKey } = useResourceContext();
72
- const { [targetKey]: filterByTk } = useRecord();
73
- return {
74
- async run() {
75
- await resource.destroy({ filterByTk });
76
- refresh();
77
- },
78
- };
79
- };
80
-
81
- export const useDestroyAll = () => {
82
- const { state, setState, refresh } = useResourceActionContext();
83
- const { resource } = useResourceContext();
84
- return {
85
- async run() {
86
- await resource.destroy({
87
- filterByTk: state?.selectedRowKeys || [],
88
- });
89
- setState?.({ selectedRowKeys: [] });
90
- refresh();
91
- },
92
- };
93
- };
94
-
95
- export const tableActionColumnSchema = {
96
- properties: {
97
- view: {
98
- type: 'void',
99
- 'x-component': 'AppVisitor',
100
- 'x-component-props': {},
101
- },
102
- update: {
103
- type: 'void',
104
- title: '{{t("Edit")}}',
105
- 'x-component': 'Action.Link',
106
- 'x-component-props': {},
107
- properties: {
108
- drawer: {
109
- type: 'void',
110
- 'x-component': 'Action.Drawer',
111
- 'x-decorator': 'Form',
112
- 'x-decorator-props': {
113
- useValues: '{{ cm.useValuesFromRecord }}',
114
- },
115
- title: '{{t("Edit")}}',
116
- properties: {
117
- displayName: {
118
- 'x-component': 'CollectionField',
119
- 'x-decorator': 'FormItem',
120
- },
121
- pinned: {
122
- 'x-component': 'CollectionField',
123
- 'x-decorator': 'FormItem',
124
- },
125
- 'options.standaloneDeployment': {
126
- 'x-component': 'Checkbox',
127
- 'x-decorator': 'FormItem',
128
- 'x-content': i18nText('Standalone deployment'),
129
- },
130
- 'options.autoStart': {
131
- 'x-component': 'Checkbox',
132
- 'x-decorator': 'FormItem',
133
- 'x-content': i18nText('Auto start'),
134
- },
135
- cname: {
136
- title: i18nText('Custom domain'),
137
- 'x-component': 'Input',
138
- 'x-decorator': 'FormItem',
139
- },
140
- footer: {
141
- type: 'void',
142
- 'x-component': 'Action.Drawer.Footer',
143
- properties: {
144
- cancel: {
145
- title: '{{t("Cancel")}}',
146
- 'x-component': 'Action',
147
- 'x-component-props': {
148
- useAction: '{{ cm.useCancelAction }}',
149
- },
150
- },
151
- submit: {
152
- title: '{{t("Submit")}}',
153
- 'x-component': 'Action',
154
- 'x-component-props': {
155
- type: 'primary',
156
- useAction: '{{ cm.useUpdateAction }}',
157
- },
158
- },
159
- },
160
- },
161
- },
162
- },
163
- },
164
- },
165
- delete: {
166
- type: 'void',
167
- title: '{{ t("Delete") }}',
168
- 'x-component': 'Action.Link',
169
- 'x-component-props': {
170
- confirm: {
171
- title: "{{t('Delete')}}",
172
- content: "{{t('Are you sure you want to delete it?')}}",
173
- },
174
- useAction: '{{cm.useDestroyAction}}',
175
- },
176
- },
177
- },
178
- };
179
-
180
- export const schema: ISchema = {
181
- type: 'object',
182
- properties: {
183
- [uid()]: {
184
- type: 'void',
185
- 'x-decorator': 'ResourceActionProvider',
186
- 'x-decorator-props': {
187
- collection,
188
- resourceName: 'applications',
189
- request: {
190
- resource: 'applications',
191
- action: 'list',
192
- params: {
193
- pageSize: 50,
194
- sort: ['-createdAt'],
195
- appends: [],
196
- },
197
- },
198
- },
199
- 'x-component': 'CollectionProvider',
200
- 'x-component-props': {
201
- collection,
202
- },
203
- properties: {
204
- actions: {
205
- type: 'void',
206
- 'x-component': 'ActionBar',
207
- 'x-component-props': {
208
- style: {
209
- marginBottom: 16,
210
- },
211
- },
212
- properties: {
213
- delete: {
214
- type: 'void',
215
- title: '{{ t("Delete") }}',
216
- 'x-component': 'Action',
217
- 'x-component-props': {
218
- useAction: useDestroyAll,
219
- confirm: {
220
- title: "{{t('Delete')}}",
221
- content: "{{t('Are you sure you want to delete it?')}}",
222
- },
223
- },
224
- },
225
- create: {
226
- type: 'void',
227
- title: '{{t("Add new")}}',
228
- 'x-component': 'Action',
229
- 'x-component-props': {
230
- type: 'primary',
231
- },
232
- properties: {
233
- drawer: {
234
- type: 'void',
235
- 'x-component': 'Action.Drawer',
236
- 'x-decorator': 'Form',
237
- 'x-decorator-props': {
238
- useValues(options) {
239
- const ctx = useActionContext();
240
- return useRequest(
241
- () =>
242
- Promise.resolve({
243
- data: {
244
- name: `a_${uid()}`,
245
- },
246
- }),
247
- { ...options, refreshDeps: [ctx.visible] },
248
- );
249
- },
250
- },
251
- title: '{{t("Add new")}}',
252
- properties: {
253
- displayName: {
254
- 'x-component': 'CollectionField',
255
- 'x-decorator': 'FormItem',
256
- },
257
- name: {
258
- 'x-component': 'CollectionField',
259
- 'x-decorator': 'FormItem',
260
- },
261
- pinned: {
262
- 'x-component': 'CollectionField',
263
- 'x-decorator': 'FormItem',
264
- },
265
- 'options.standaloneDeployment': {
266
- 'x-component': 'Checkbox',
267
- 'x-decorator': 'FormItem',
268
- 'x-content': i18nText('Standalone deployment'),
269
- },
270
- 'options.autoStart': {
271
- 'x-component': 'Checkbox',
272
- 'x-decorator': 'FormItem',
273
- 'x-content': i18nText('Auto start'),
274
- },
275
- cname: {
276
- title: i18nText('Custom domain'),
277
- 'x-component': 'Input',
278
- 'x-decorator': 'FormItem',
279
- },
280
- footer: {
281
- type: 'void',
282
- 'x-component': 'Action.Drawer.Footer',
283
- properties: {
284
- cancel: {
285
- title: '{{t("Cancel")}}',
286
- 'x-component': 'Action',
287
- 'x-component-props': {
288
- useAction: '{{ cm.useCancelAction }}',
289
- },
290
- },
291
- submit: {
292
- title: '{{t("Submit")}}',
293
- 'x-component': 'Action',
294
- 'x-component-props': {
295
- type: 'primary',
296
- useAction: '{{ cm.useCreateAction }}',
297
- },
298
- },
299
- },
300
- },
301
- },
302
- },
303
- },
304
- },
305
- },
306
- },
307
- table: {
308
- type: 'void',
309
- 'x-uid': 'input',
310
- 'x-component': 'Table.Void',
311
- 'x-component-props': {
312
- rowKey: 'name',
313
- rowSelection: {
314
- type: 'checkbox',
315
- },
316
- useDataSource: '{{ cm.useDataSourceFromRAC }}',
317
- },
318
- properties: {
319
- displayName: {
320
- type: 'void',
321
- 'x-decorator': 'Table.Column.Decorator',
322
- 'x-component': 'Table.Column',
323
- properties: {
324
- displayName: {
325
- type: 'string',
326
- 'x-component': 'CollectionField',
327
- 'x-read-pretty': true,
328
- },
329
- },
330
- },
331
- name: {
332
- type: 'void',
333
- 'x-decorator': 'Table.Column.Decorator',
334
- 'x-component': 'Table.Column',
335
- properties: {
336
- name: {
337
- type: 'string',
338
- 'x-component': 'CollectionField',
339
- 'x-read-pretty': true,
340
- },
341
- },
342
- },
343
- pinned: {
344
- type: 'void',
345
- title: i18nText('Pin to menu'),
346
- 'x-decorator': 'Table.Column.Decorator',
347
- 'x-component': 'Table.Column',
348
- properties: {
349
- pinned: {
350
- type: 'string',
351
- 'x-component': 'CollectionField',
352
- 'x-read-pretty': true,
353
- },
354
- },
355
- },
356
- actions: {
357
- type: 'void',
358
- title: '{{t("Actions")}}',
359
- 'x-component': 'Table.Column',
360
- properties: {
361
- actions: {
362
- type: 'void',
363
- 'x-component': 'Space',
364
- 'x-component-props': {
365
- split: '|',
366
- },
367
- ...tableActionColumnSchema,
368
- },
369
- },
370
- },
371
- },
372
- },
373
- },
374
- },
375
- },
376
- };
@@ -1,10 +0,0 @@
1
- import { useTranslation } from 'react-i18next';
2
-
3
- export const usePluginUtils = () => {
4
- const { t } = useTranslation('multi-app-manager');
5
- return { t };
6
- };
7
-
8
- export const i18nText = (text) => {
9
- return `{{t("${text}", { ns: 'multi-app-manager' })}}`;
10
- };
package/src/index.ts DELETED
@@ -1 +0,0 @@
1
- export { default } from './server';
@@ -1,9 +0,0 @@
1
- export default {
2
- 'Multi-app manager': 'Gestor de aplicaciones múltiples',
3
- Applications: 'Aplicaciones',
4
- 'App display name': 'Mostrar nombre de aplicación',
5
- 'App ID': 'ID de aplicación',
6
- 'Pin to menu': ' Fijar al menú',
7
- 'Custom domain': 'Dominio personalizado',
8
- 'Manage applications': 'Gestionar aplicaciones',
9
- };
@@ -1,9 +0,0 @@
1
- export default {
2
- 'Multi-app manager': 'Gerenciador de aplicativos múltiplos',
3
- Applications: 'Aplicativos',
4
- 'App display name': 'Nome de exibição do aplicativo',
5
- 'App ID': 'ID do aplicativo',
6
- 'Pin to menu': 'Fixar no menu',
7
- 'Custom domain': 'Domínio personalizado',
8
- 'Manage applications': 'Gerenciar aplicativos',
9
- };
@@ -1,11 +0,0 @@
1
- export default {
2
- 'Multi-app manager': '多应用管理',
3
- Applications: '应用',
4
- 'App display name': '应用名称',
5
- 'App ID': '应用标识',
6
- 'Pin to menu': '在菜单上显示',
7
- 'Custom domain': '自定义域名',
8
- 'Manage applications': '管理应用',
9
- 'Standalone deployment': '独立部署',
10
- 'Auto start': '自动启动',
11
- };
@@ -1,146 +0,0 @@
1
- import { Plugin, PluginManager } from '@nocobase/server';
2
- import { mockServer } from '@nocobase/test';
3
- import { uid } from '@nocobase/utils';
4
- import { PluginMultiAppManager } from '../server';
5
-
6
- describe('test with start', () => {
7
- it('should load subApp on create', async () => {
8
- const loadFn = jest.fn();
9
- const installFn = jest.fn();
10
-
11
- class TestPlugin extends Plugin {
12
- getName(): string {
13
- return 'test-package';
14
- }
15
-
16
- async load(): Promise<void> {
17
- loadFn();
18
- }
19
-
20
- async install() {
21
- installFn();
22
- }
23
- }
24
-
25
- const mockGetPluginByName = jest.fn();
26
- mockGetPluginByName.mockReturnValue(TestPlugin);
27
- PluginManager.resolvePlugin = mockGetPluginByName;
28
-
29
- const app = mockServer();
30
- await app.cleanDb();
31
-
32
- app.plugin(PluginMultiAppManager);
33
-
34
- await app.loadAndInstall();
35
- await app.start();
36
-
37
- const db = app.db;
38
-
39
- const name = `d_${uid()}`;
40
-
41
- await db.getRepository('applications').create({
42
- values: {
43
- name,
44
- options: {
45
- plugins: ['test-package'],
46
- },
47
- },
48
- });
49
-
50
- expect(loadFn).toHaveBeenCalled();
51
- expect(installFn).toHaveBeenCalledTimes(1);
52
-
53
- const subApp = await app.appManager.getApplication(name);
54
- await subApp.destroy();
55
- await app.destroy();
56
- });
57
-
58
- it('should install into difference database', async () => {
59
- const app = mockServer();
60
- await app.cleanDb();
61
- app.plugin(PluginMultiAppManager);
62
-
63
- await app.loadAndInstall();
64
- await app.start();
65
-
66
- const db = app.db;
67
-
68
- const name = `d_${uid()}`;
69
-
70
- await db.getRepository('applications').create({
71
- values: {
72
- name,
73
- options: {
74
- plugins: ['ui-schema-storage'],
75
- },
76
- },
77
- });
78
- const subApp = await app.appManager.getApplication(name);
79
- await subApp.destroy();
80
- await app.destroy();
81
- });
82
-
83
- it('should lazy load applications', async () => {
84
- class TestPlugin extends Plugin {
85
- getName(): string {
86
- return 'test-package';
87
- }
88
- }
89
-
90
- const app = mockServer();
91
- await app.cleanDb();
92
-
93
- app.plugin(PluginMultiAppManager);
94
-
95
- await app.loadAndInstall();
96
- await app.start();
97
-
98
- const db = app.db;
99
-
100
- const mockGetPluginByName = jest.fn();
101
- mockGetPluginByName.mockReturnValue(TestPlugin);
102
- PluginManager.resolvePlugin = mockGetPluginByName;
103
-
104
- const name = `d_${uid()}`;
105
- console.log(name);
106
-
107
- await db.getRepository('applications').create({
108
- values: {
109
- name,
110
- options: {
111
- plugins: ['test-package'],
112
- },
113
- },
114
- });
115
-
116
- expect(app.appManager.applications.get(name)).toBeDefined();
117
-
118
- await app.appManager.applications.get(name).destroy();
119
- await app.stop();
120
-
121
- const newApp = mockServer({
122
- database: app.db,
123
- });
124
-
125
- newApp.plugin(PluginMultiAppManager);
126
- await newApp.db.reconnect();
127
-
128
- await newApp.load();
129
- await newApp.start();
130
-
131
- expect(await newApp.db.getRepository('applications').count()).toEqual(1);
132
- expect(newApp.appManager.applications.get(name)).not.toBeDefined();
133
-
134
- newApp.appManager.setAppSelector(() => {
135
- return name;
136
- });
137
-
138
- await newApp.agent().resource('test').test();
139
- expect(newApp.appManager.applications.get(name)).toBeDefined();
140
-
141
- await newApp.appManager.applications.get(name).destroy();
142
-
143
- await newApp.destroy();
144
- await app.destroy();
145
- });
146
- });