@nocobase/plugin-multi-app-share-collection 0.11.1-alpha.5 → 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 (56) hide show
  1. package/client.d.ts +2 -3
  2. package/client.js +1 -1
  3. package/dist/client/index.js +510 -0
  4. package/{lib → dist}/index.d.ts +1 -0
  5. package/dist/index.js +18 -0
  6. package/dist/locale/es-ES.js +16 -0
  7. package/dist/locale/pt-BR.js +16 -0
  8. package/dist/locale/zh-CN.js +16 -0
  9. package/dist/server/collections/applications.js +21 -0
  10. package/dist/server/collections/collections.js +21 -0
  11. package/dist/server/index.js +11 -0
  12. package/{src/server/migrations/20230319111111-update-apps-collections.ts → dist/server/migrations/20230319111111-update-apps-collections.js} +26 -33
  13. package/dist/server/plugin.js +278 -0
  14. package/package.json +16 -25
  15. package/server.d.ts +2 -3
  16. package/server.js +1 -1
  17. package/lib/client/MultiAppShareCollectionProvider.js +0 -122
  18. package/lib/client/TableTransfer.js +0 -487
  19. package/lib/client/index.js +0 -27
  20. package/lib/client/utils.js +0 -25
  21. package/lib/index.js +0 -13
  22. package/lib/locale/es-ES.js +0 -19
  23. package/lib/locale/pt-BR.js +0 -19
  24. package/lib/locale/zh-CN.js +0 -19
  25. package/lib/server/collections/applications.js +0 -27
  26. package/lib/server/collections/collections.js +0 -27
  27. package/lib/server/index.js +0 -13
  28. package/lib/server/migrations/20230319111111-update-apps-collections.js +0 -110
  29. package/lib/server/plugin.js +0 -408
  30. package/src/client/MultiAppShareCollectionProvider.tsx +0 -86
  31. package/src/client/TableTransfer.tsx +0 -398
  32. package/src/client/index.tsx +0 -10
  33. package/src/client/utils.tsx +0 -11
  34. package/src/index.ts +0 -1
  35. package/src/locale/es-ES.ts +0 -12
  36. package/src/locale/pt-BR.ts +0 -12
  37. package/src/locale/zh-CN.ts +0 -12
  38. package/src/server/__tests__/collection-sync.test.ts +0 -514
  39. package/src/server/__tests__/index.ts +0 -25
  40. package/src/server/collections/.gitkeep +0 -0
  41. package/src/server/collections/applications.ts +0 -17
  42. package/src/server/collections/collections.ts +0 -17
  43. package/src/server/index.ts +0 -1
  44. package/src/server/plugin.ts +0 -332
  45. /package/{lib → dist}/client/MultiAppShareCollectionProvider.d.ts +0 -0
  46. /package/{lib → dist}/client/TableTransfer.d.ts +0 -0
  47. /package/{lib → dist}/client/index.d.ts +0 -0
  48. /package/{lib → dist}/client/utils.d.ts +0 -0
  49. /package/{lib → dist}/locale/es-ES.d.ts +0 -0
  50. /package/{lib → dist}/locale/pt-BR.d.ts +0 -0
  51. /package/{lib → dist}/locale/zh-CN.d.ts +0 -0
  52. /package/{lib → dist}/server/collections/applications.d.ts +0 -0
  53. /package/{lib → dist}/server/collections/collections.d.ts +0 -0
  54. /package/{lib → dist}/server/index.d.ts +0 -0
  55. /package/{lib → dist}/server/migrations/20230319111111-update-apps-collections.d.ts +0 -0
  56. /package/{lib → dist}/server/plugin.d.ts +0 -0
@@ -1,398 +0,0 @@
1
- import { connect } from '@formily/react';
2
- import { css, useCollectionManager, useRecord, useRequest, useToken } from '@nocobase/client';
3
- import { CollectionsGraph, lodash } from '@nocobase/utils/client';
4
- import { App, Col, Input, Row, Select, Spin, Table, Tag } from 'antd';
5
- import React, { useCallback, useMemo, useState } from 'react';
6
- import { useTranslation } from 'react-i18next';
7
-
8
- const excludeCollections = ['users', 'roles', 'applications'];
9
-
10
- const useCollectionsGraph = ({ removed = [] }) => {
11
- const { collections } = useCollectionManager();
12
-
13
- const findAddable = useCallback(
14
- (name) => {
15
- return CollectionsGraph.connectedNodes({
16
- collections,
17
- nodes: [name],
18
- excludes: excludeCollections,
19
- }).filter((name) => removed.includes(name));
20
- },
21
- [removed],
22
- );
23
-
24
- const findRemovable = useCallback(
25
- (name) => {
26
- return CollectionsGraph.connectedNodes({
27
- collections,
28
- nodes: [name],
29
- excludes: excludeCollections,
30
- direction: 'reverse',
31
- }).filter((name) => !removed.includes(name));
32
- },
33
- [removed],
34
- );
35
-
36
- return {
37
- findAddable,
38
- findRemovable,
39
- };
40
- };
41
-
42
- const useCollections = () => {
43
- const record = useRecord();
44
- const [selected, setSelected] = useState<any>([]);
45
-
46
- const res1 = useRequest(
47
- {
48
- url: `applications/${record.name}/collectionBlacklist:list`,
49
- params: {
50
- paginate: false,
51
- params: {
52
- fields: ['name'],
53
- },
54
- },
55
- },
56
- {
57
- onSuccess(data) {
58
- setSelected(data.data?.map((data) => data.name));
59
- },
60
- },
61
- );
62
-
63
- const res2 = useRequest<{
64
- data: any[];
65
- }>({
66
- url: `collections`,
67
- params: {
68
- fields: ['name', 'title', 'hidden', 'category.name', 'category.color', 'category.sort'],
69
- sort: 'sort',
70
- paginate: false,
71
- },
72
- });
73
-
74
- const res3 = useRequest<{
75
- data: any[];
76
- }>({
77
- url: `collectionCategories`,
78
- params: {
79
- sort: 'sort',
80
- paginate: false,
81
- },
82
- });
83
-
84
- return {
85
- loading: res1.loading || res2.loading || res3.loading,
86
- collections: (res2.data?.data || []).filter((item) => !item.hidden && !excludeCollections.includes(item.name)),
87
- removed: selected,
88
- setSelected,
89
- categories: (res3.data?.data || []).map((cat) => ({ label: cat.name, value: cat.name })),
90
- };
91
- };
92
-
93
- const includes = (text: string, s: string | string[]) => {
94
- const values = Array.isArray(s) ? s : [s];
95
- for (const val of values) {
96
- if (text.toLowerCase().includes(val)) {
97
- return true;
98
- }
99
- }
100
- return false;
101
- };
102
-
103
- const useRemovedDataSource = ({ collections, removed }) => {
104
- const [filter, setFilter] = useState({ name: '', category: [] });
105
- const dataSource = useMemo(() => {
106
- return collections.filter((collection) => {
107
- const { name, title, category = [] } = collection;
108
- const results = [removed.includes(collection.name)];
109
- if (filter.name) {
110
- results.push(includes(name, filter.name) || includes(title, filter.name));
111
- }
112
- if (filter.category.length > 0) {
113
- results.push(category.some((item) => includes(item.name, filter.category)));
114
- }
115
- return !results.includes(false);
116
- });
117
- }, [collections, removed, filter]);
118
- const setNameFilter = useMemo(
119
- () =>
120
- lodash.debounce((name) => {
121
- setFilter({
122
- ...filter,
123
- name,
124
- });
125
- }, 300),
126
- [],
127
- );
128
- return {
129
- dataSource,
130
- setNameFilter,
131
- setCategoryFilter: (category) => {
132
- setFilter({
133
- ...filter,
134
- category,
135
- });
136
- },
137
- };
138
- };
139
-
140
- const useAddedDataSource = ({ collections, removed }) => {
141
- const [filter, setFilter] = useState({ name: '', category: [] });
142
- const dataSource = collections.filter((collection) => {
143
- const { name, title, category = [] } = collection;
144
- const results = [!removed.includes(collection.name)];
145
- if (filter.name) {
146
- results.push(includes(name, filter.name) || includes(title, filter.name));
147
- }
148
- if (filter.category.length > 0) {
149
- results.push(category.some((item) => includes(item.name, filter.category)));
150
- }
151
- return !results.includes(false);
152
- });
153
- const setNameFilter = useMemo(
154
- () =>
155
- lodash.debounce((name) => {
156
- setFilter({
157
- ...filter,
158
- name,
159
- });
160
- }, 300),
161
- [],
162
- );
163
- return {
164
- dataSource,
165
- setNameFilter,
166
- setCategoryFilter: (category) => {
167
- setFilter({
168
- ...filter,
169
- category,
170
- });
171
- },
172
- };
173
- };
174
-
175
- export const TableTransfer = connect((props) => {
176
- const { onChange } = props;
177
- const { loading, collections, categories, removed, setSelected } = useCollections();
178
- const [selectedRowKeys1, setSelectedRowKeys1] = useState([]);
179
- const [selectedRowKeys2, setSelectedRowKeys2] = useState([]);
180
- const { findAddable, findRemovable } = useCollectionsGraph({ removed });
181
- const addedDataSource = useAddedDataSource({ collections, removed });
182
- const removedDataSource = useRemovedDataSource({ collections, removed });
183
- const { t } = useTranslation('multi-app-share-collection');
184
- const { modal } = App.useApp();
185
- const { token } = useToken();
186
- const columns = useMemo(
187
- () => [
188
- {
189
- title: t('Collection display name'),
190
- dataIndex: 'title',
191
- },
192
- {
193
- title: t('Collection name'),
194
- dataIndex: 'name',
195
- },
196
- {
197
- title: t('Collection category'),
198
- dataIndex: 'category',
199
- render: (categories) =>
200
- categories.map((category) => (
201
- <Tag key={category.name} color={category.color}>
202
- {category.name}
203
- </Tag>
204
- )),
205
- },
206
- ],
207
- [],
208
- );
209
- if (loading) {
210
- return <Spin />;
211
- }
212
- return (
213
- <div>
214
- <Row
215
- gutter={24}
216
- className={css`
217
- .ant-table-tbody > tr.ant-table-row:hover > td {
218
- background: #e6f7ff;
219
- cursor: pointer;
220
- }
221
- `}
222
- >
223
- <Col span={12}>
224
- <div
225
- className={css`
226
- display: flex;
227
- justify-content: space-between;
228
- align-items: center;
229
- width: 100%;
230
- margin-bottom: 8px;
231
- `}
232
- >
233
- <strong style={{ fontSize: token.fontSizeLG, color: token.colorText }}>{t('Unshared collections')}</strong>
234
- <Input.Group compact style={{ width: 360 }}>
235
- <Select
236
- popupMatchSelectWidth={false}
237
- onChange={(value) => {
238
- removedDataSource.setCategoryFilter(value);
239
- }}
240
- mode={'multiple'}
241
- style={{ width: '35%' }}
242
- size={'middle'}
243
- placeholder={t('All categories')}
244
- options={categories}
245
- allowClear
246
- />
247
- <Input
248
- onChange={(e) => removedDataSource.setNameFilter(e.target.value)}
249
- style={{ width: '65%' }}
250
- placeholder={t('Enter name or title...')}
251
- allowClear
252
- />
253
- </Input.Group>
254
- </div>
255
- <Table
256
- bordered
257
- rowKey={'name'}
258
- rowSelection={{
259
- type: 'checkbox',
260
- selectedRowKeys: selectedRowKeys1,
261
- onChange(selectedRowKeys) {
262
- const values = removed.filter((s) => !selectedRowKeys.includes(s));
263
- setSelected(values);
264
- onChange(values);
265
- setSelectedRowKeys1([]);
266
- },
267
- }}
268
- pagination={false}
269
- size={'small'}
270
- columns={columns}
271
- // dataSource={collections.filter((collection) => removed.includes(collection.name))}
272
- dataSource={removedDataSource.dataSource}
273
- scroll={{ y: 'calc(100vh - 260px)' }}
274
- onRow={({ name, disabled }: any) => ({
275
- onClick: () => {
276
- if (disabled) return;
277
- const adding = findAddable(name);
278
- const change = () => {
279
- const values = removed.filter((s) => !adding.includes(s));
280
- setSelected(values);
281
- onChange(values);
282
- };
283
- if (adding.length === 1) {
284
- return change();
285
- }
286
- modal.confirm({
287
- title: t('Are you sure to add the following collections?'),
288
- width: '60%',
289
- content: (
290
- <div>
291
- <Table
292
- size={'small'}
293
- columns={columns}
294
- dataSource={collections.filter((collection) => adding.includes(collection.name))}
295
- pagination={false}
296
- scroll={{ y: '60vh' }}
297
- />
298
- </div>
299
- ),
300
- onOk() {
301
- change();
302
- },
303
- });
304
- },
305
- })}
306
- />
307
- </Col>
308
- <Col span={12}>
309
- <div
310
- className={css`
311
- display: flex;
312
- justify-content: space-between;
313
- align-items: center;
314
- width: 100%;
315
- margin-bottom: 8px;
316
- `}
317
- >
318
- <strong style={{ fontSize: token.fontSizeLG, color: token.colorText }}>{t('Shared collections')}</strong>
319
- <Input.Group compact style={{ width: 360 }}>
320
- <Select
321
- popupMatchSelectWidth={false}
322
- onChange={(value) => {
323
- addedDataSource.setCategoryFilter(value);
324
- }}
325
- mode={'multiple'}
326
- style={{ width: '35%' }}
327
- size={'middle'}
328
- placeholder={t('All categories')}
329
- options={categories}
330
- allowClear
331
- />
332
- <Input
333
- onChange={(e) => addedDataSource.setNameFilter(e.target.value)}
334
- style={{ width: '65%' }}
335
- placeholder={t('Enter name or title...')}
336
- allowClear
337
- />
338
- </Input.Group>
339
- </div>
340
- <Table
341
- bordered
342
- rowKey={'name'}
343
- rowSelection={{
344
- type: 'checkbox',
345
- selectedRowKeys: selectedRowKeys2,
346
- onChange(selectedRowKeys) {
347
- const values = lodash.uniq(removed.concat(selectedRowKeys));
348
- setSelected(values);
349
- onChange(values);
350
- setSelectedRowKeys2([]);
351
- },
352
- }}
353
- pagination={false}
354
- size={'small'}
355
- columns={columns}
356
- dataSource={addedDataSource.dataSource}
357
- // dataSource={collections.filter((collection) => !selected.includes(collection.name))}
358
- scroll={{ y: 'calc(100vh - 260px)' }}
359
- onRow={({ name }) => ({
360
- onClick: () => {
361
- const removing = findRemovable(name);
362
- const change = () => {
363
- removed.push(...removing);
364
- const values = lodash.uniq([...removed]);
365
- setSelected(values);
366
- onChange(values);
367
- };
368
- if (removing.length === 1) {
369
- return change();
370
- }
371
- modal.confirm({
372
- title: t('Are you sure to remove the following collections?'),
373
- width: '60%',
374
- content: (
375
- <div>
376
- <Table
377
- size={'small'}
378
- columns={columns}
379
- dataSource={collections.filter((collection) => removing.includes(collection.name))}
380
- pagination={false}
381
- scroll={{ y: '60vh' }}
382
- />
383
- </div>
384
- ),
385
- onOk() {
386
- change();
387
- },
388
- });
389
- },
390
- })}
391
- />
392
- </Col>
393
- </Row>
394
- </div>
395
- );
396
- });
397
-
398
- export default TableTransfer;
@@ -1,10 +0,0 @@
1
- import { Plugin } from '@nocobase/client';
2
- import { MultiAppShareCollectionProvider } from './MultiAppShareCollectionProvider';
3
-
4
- export class MultiAppShareCollectionPlugin extends Plugin {
5
- async load() {
6
- this.app.use(MultiAppShareCollectionProvider);
7
- }
8
- }
9
-
10
- export default MultiAppShareCollectionPlugin;
@@ -1,11 +0,0 @@
1
- import { useTranslation } from 'react-i18next';
2
-
3
- export const usePluginUtils = () => {
4
- const { t } = useTranslation('multi-app-share-collection');
5
-
6
- return { t };
7
- };
8
-
9
- export const i18nText = (text) => {
10
- return `{{t("${text}", { ns: 'multi-app-share-collection' })}}`;
11
- };
package/src/index.ts DELETED
@@ -1 +0,0 @@
1
- export { default } from './server';
@@ -1,12 +0,0 @@
1
- export default {
2
- 'Share collections': 'Tablas compartidas',
3
- 'Unshared collections': 'Tablas no compartidas',
4
- 'Shared collections': 'Tablas compartidas',
5
- 'All categories': 'Todas las categorías',
6
- 'Enter name or title...': 'Introducir nombre o título...',
7
- 'Are you sure to add the following collections?': '¿Está seguro de que desea añadir las siguientes tablas?',
8
- 'Are you sure to remove the following collections?': '¿Está seguro de que desea eliminar las siguientes tablas?',
9
- 'Collection display name': 'Mostrar nombre de la tabla',
10
- 'Collection name': 'Nombre de la tabla',
11
- 'Collection category': 'Categoría de tabla',
12
- };
@@ -1,12 +0,0 @@
1
- export default {
2
- 'Share collections': 'Compartilhar tabelas',
3
- 'Unshared collections': 'Tabelas não compartilhadas',
4
- 'Shared collections': 'Tabelas compartilhadas',
5
- 'All categories': 'Todas as categorias',
6
- 'Enter name or title...': 'Digite o nome ou título...',
7
- 'Are you sure to add the following collections?': 'Tem certeza de que deseja adicionar as seguintes tabelas?',
8
- 'Are you sure to remove the following collections?': 'Tem certeza de que deseja remover as seguintes tabelas?',
9
- 'Collection display name': 'Nome de exibição da tabela',
10
- 'Collection name': 'Nome da tabela',
11
- 'Collection category': 'Categoria da tabela',
12
- };
@@ -1,12 +0,0 @@
1
- export default {
2
- 'Share collections': '共享数据表',
3
- 'Unshared collections': '未共享的数据表',
4
- 'Shared collections': '已共享的数据表',
5
- 'All categories': '所有分类',
6
- 'Enter name or title...': '输入数据表标题或标识',
7
- 'Are you sure to add the following collections?': '确定添加以下数据表?',
8
- 'Are you sure to remove the following collections?': '确定移除以下数据表?',
9
- 'Collection display name': '标题',
10
- 'Collection name': '标识',
11
- 'Collection category': '分类',
12
- };