@nocobase/plugin-action-import 1.0.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 (76) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +222 -0
  3. package/README.zh-CN.md +222 -0
  4. package/client.d.ts +2 -0
  5. package/client.js +1 -0
  6. package/dist/client/ImportActionInitializer.d.ts +9 -0
  7. package/dist/client/ImportDesigner.d.ts +2 -0
  8. package/dist/client/ImportModal.d.ts +6 -0
  9. package/dist/client/ImportPluginProvider.d.ts +3 -0
  10. package/dist/client/constants.d.ts +1 -0
  11. package/dist/client/context.d.ts +29 -0
  12. package/dist/client/index.d.ts +9 -0
  13. package/dist/client/index.js +24 -0
  14. package/dist/client/locale/index.d.ts +2 -0
  15. package/dist/client/schemaSettings.d.ts +2 -0
  16. package/dist/client/useFields.d.ts +1 -0
  17. package/dist/client/useImportAction.d.ts +6 -0
  18. package/dist/client/useShared.d.ts +76 -0
  19. package/dist/externalVersion.js +18 -0
  20. package/dist/index.d.ts +3 -0
  21. package/dist/index.js +43 -0
  22. package/dist/locale/en-US.json +28 -0
  23. package/dist/locale/es-ES.json +27 -0
  24. package/dist/locale/ko_KR.json +28 -0
  25. package/dist/locale/pt-BR.json +27 -0
  26. package/dist/locale/zh-CN.json +29 -0
  27. package/dist/node_modules/node-xlsx/lib/helpers.js +142 -0
  28. package/dist/node_modules/node-xlsx/lib/index.js +6 -0
  29. package/dist/node_modules/node-xlsx/lib/workbook.js +16 -0
  30. package/dist/node_modules/node-xlsx/package.json +1 -0
  31. package/dist/node_modules/xlsx/LICENSE +201 -0
  32. package/dist/node_modules/xlsx/bin/xlsx.njs +302 -0
  33. package/dist/node_modules/xlsx/bower.json +22 -0
  34. package/dist/node_modules/xlsx/dist/cpexcel.js +1506 -0
  35. package/dist/node_modules/xlsx/dist/jszip.js +9000 -0
  36. package/dist/node_modules/xlsx/dist/shim.min.js +2 -0
  37. package/dist/node_modules/xlsx/dist/xlsx.core.min.js +18 -0
  38. package/dist/node_modules/xlsx/dist/xlsx.extendscript.js +31850 -0
  39. package/dist/node_modules/xlsx/dist/xlsx.full.min.js +24 -0
  40. package/dist/node_modules/xlsx/dist/xlsx.js +22693 -0
  41. package/dist/node_modules/xlsx/dist/xlsx.min.js +15 -0
  42. package/dist/node_modules/xlsx/dist/xlsx.mini.min.js +9 -0
  43. package/dist/node_modules/xlsx/jszip.js +9000 -0
  44. package/dist/node_modules/xlsx/package.json +1 -0
  45. package/dist/node_modules/xlsx/types/index.d.ts +853 -0
  46. package/dist/node_modules/xlsx/xlsx.js +6 -0
  47. package/dist/node_modules/xlsx/xlsx.mini.js +10709 -0
  48. package/dist/node_modules/xlsx/xlsxworker.js +15 -0
  49. package/dist/server/actions/downloadXlsxTemplate.d.ts +2 -0
  50. package/dist/server/actions/downloadXlsxTemplate.js +62 -0
  51. package/dist/server/actions/importXlsx.d.ts +2 -0
  52. package/dist/server/actions/importXlsx.js +185 -0
  53. package/dist/server/actions/index.d.ts +2 -0
  54. package/dist/server/actions/index.js +23 -0
  55. package/dist/server/index.d.ts +7 -0
  56. package/dist/server/index.js +59 -0
  57. package/dist/server/locale/en-US.d.ts +11 -0
  58. package/dist/server/locale/en-US.js +32 -0
  59. package/dist/server/locale/fr-FR.d.ts +11 -0
  60. package/dist/server/locale/fr-FR.js +32 -0
  61. package/dist/server/locale/index.d.ts +2 -0
  62. package/dist/server/locale/index.js +40 -0
  63. package/dist/server/locale/zh-CN.d.ts +12 -0
  64. package/dist/server/locale/zh-CN.js +33 -0
  65. package/dist/server/middleware/index.d.ts +2 -0
  66. package/dist/server/middleware/index.js +34 -0
  67. package/dist/server/migrations/20240425223956-change-locale-module.d.ts +6 -0
  68. package/dist/server/migrations/20240425223956-change-locale-module.js +42 -0
  69. package/dist/server/utils/index.d.ts +6 -0
  70. package/dist/server/utils/index.js +54 -0
  71. package/dist/server/utils/transform.d.ts +84 -0
  72. package/dist/server/utils/transform.js +226 -0
  73. package/dist/swagger/index.json +33 -0
  74. package/package.json +41 -0
  75. package/server.d.ts +2 -0
  76. package/server.js +1 -0
package/README.md ADDED
@@ -0,0 +1,222 @@
1
+ # import
2
+
3
+ English | [中文](./README.zh-CN.md)
4
+
5
+ Excel 数据导入插件。
6
+
7
+ ## 安装激活
8
+
9
+ 内置插件无需手动安装激活。
10
+
11
+ ## 导入说明
12
+
13
+ ### 数字类型字段
14
+
15
+ 支持数字和百分比,`N/A` 或 `-` 的文案会被过滤掉
16
+
17
+ | 数字1 | 百分比 | 数字2 | 数字3 |
18
+ | -- | -- | -- | -- |
19
+ | 123 | 25% | N/A | - |
20
+
21
+ 转 JSON 之后为
22
+
23
+ ```ts
24
+ {
25
+ "数字1": 123,
26
+ "百分比": 0.25,
27
+ "数字2": null,
28
+ "数字3": null,
29
+ }
30
+ ```
31
+
32
+ ### 布尔类型字段
33
+
34
+ 输入文案支持(英文不区分大小写):
35
+
36
+ - `Yes` `Y` `True` `1` `是`
37
+ - `No` `N` `False` `0` `否`
38
+
39
+ | 字段1 | 字段2 | 字段3 | 字段4 | 字段4 |
40
+ | -- | -- | -- | -- | -- |
41
+ | 否 | 是 | Y | true | 0 |
42
+
43
+ 转 JSON 之后为
44
+
45
+ ```ts
46
+ {
47
+ "字段1": false,
48
+ "字段2": true,
49
+ "字段3": true,
50
+ "字段4": true,
51
+ "字段5": false,
52
+ }
53
+ ```
54
+
55
+ ### 日期类型字段
56
+
57
+ | DateOnly | Local(+08:00) | GMT |
58
+ | -- | -- | -- |
59
+ | 2023-01-18 22:22:22 | 2023-01-18 22:22:22 | 2023-01-18 22:22:22 |
60
+
61
+ 转 JSON 之后为
62
+
63
+ ```ts
64
+ {
65
+ "DateOnly": "2023-01-18T00:00:00.000Z",
66
+ "Local(+08:00)": "2023-01-18T14:22:22.000Z",
67
+ "GMT": "2023-01-18T22:22:22.000Z",
68
+ }
69
+ ```
70
+
71
+ ### 选择类型字段
72
+
73
+ 选项值和选项标签都可作为导入文案,多个选项之间以以逗号(`,` `,`)或顿号(`、`)区分
74
+
75
+ 如字段 `优先级` 的可选项包括:
76
+
77
+ | 选项值 | 选项标签 |
78
+ | -- | -- |
79
+ | low | 低 |
80
+ | medium | 中 |
81
+ | high | 低 |
82
+
83
+ 选项值和选项标签都可作为导入文案
84
+
85
+ | 优先级 |
86
+ | -- |
87
+ | 高 |
88
+ | low |
89
+
90
+ 转 JSON 之后为
91
+
92
+ ```ts
93
+ [
94
+ { "优先级": "high" },
95
+ { "优先级": "low" },
96
+ ]
97
+ ```
98
+
99
+ ### 中国行政区字段
100
+
101
+ | 地区1 | 地区2 |
102
+ | -- | -- |
103
+ | 北京市/市辖区 | 天津市/市辖区 |
104
+
105
+ 转 JSON 之后为
106
+
107
+ ```ts
108
+ {
109
+ "地区1": ["11","1101"],
110
+ "地区2": ["12","1201"]
111
+ }
112
+ ```
113
+
114
+ ### 附件字段
115
+
116
+ | 附件 |
117
+ | --|
118
+ | https://www.nocobase.com/images/logo.png |
119
+
120
+ 转 JSON 之后为
121
+
122
+ ```ts
123
+ {
124
+ "附件": [
125
+ {
126
+ "filename": "logo.png",
127
+ "title": "logo.png",
128
+ "extname": ".png",
129
+ "url": "https://www.nocobase.com/images/logo.png"
130
+ }
131
+ ]
132
+ }
133
+ ```
134
+
135
+ ### 关系类型字段
136
+
137
+ 多条数据以逗号(`,` `,`)或顿号(`、`)区分
138
+
139
+ | 部门/名称 | 分类/标题 |
140
+ | -- | -- |
141
+ | 开发组 | 分类1、分类2 |
142
+
143
+ 转 JSON 之后为
144
+
145
+ ```ts
146
+ {
147
+ "部门": [1], // 1 为部门名称为「开发组」的记录 ID
148
+ "分类": [1,2], // 1,2 为分类标题为「分类1」和「分类2」的记录 ID
149
+ }
150
+ ```
151
+
152
+ ### JSON 类型字段
153
+
154
+ | JSON1 |
155
+ | -- |
156
+ | {"key":"value"} |
157
+
158
+ 转 JSON 之后为
159
+
160
+ ```ts
161
+ {
162
+ "JSON": {"key":"value"}
163
+ }
164
+ ```
165
+
166
+ ### 地图几何图形类型
167
+
168
+ | Point | Line | Polygon | Circle |
169
+ | -- | -- | -- | -- |
170
+ | 1,2 | (1,2),(3,4) | (1,2),(3,4),(1,2) | 1,2,3 |
171
+
172
+ 转 JSON 之后为
173
+
174
+ ```ts
175
+ {
176
+ "Point": [1,2],
177
+ "Line": [[1,2], [3,4]],
178
+ "Polygon": [[1,2], [3,4], [1,2]],
179
+ "Circle": [1,2,3]
180
+ }
181
+ ```
182
+
183
+ ## 自定义导入格式
184
+
185
+ 通过 `db.registerFieldValueParsers()` 方法注册自定义的 `ValueParser`,如:
186
+
187
+ ```ts
188
+ import { BaseValueParser } from '@nocobase/database';
189
+
190
+ class PointValueParser extends BaseValueParser {
191
+ async setValue(value) {
192
+ if (Array.isArray(value)) {
193
+ this.value = value;
194
+ } else if (typeof value === 'string') {
195
+ this.value = value.split(',');
196
+ } else {
197
+ this.errors.push('Value invalid');
198
+ }
199
+ }
200
+ }
201
+
202
+ const db = new Database();
203
+
204
+ // type=point 的字段导入时,将通过 PointValueParser 解析数据
205
+ db.registerFieldValueParsers({
206
+ point: PointValueParser,
207
+ });
208
+ ```
209
+
210
+ 导入示例
211
+
212
+ | Point |
213
+ | --|
214
+ | 1,2 |
215
+
216
+ 转 JSON 之后为
217
+
218
+ ```ts
219
+ {
220
+ "Point": [1,2]
221
+ }
222
+ ```
@@ -0,0 +1,222 @@
1
+ # import
2
+
3
+ [English](./README.md) | 中文
4
+
5
+ Excel 数据导入插件。
6
+
7
+ ## 安装激活
8
+
9
+ 内置插件无需手动安装激活。
10
+
11
+ ## 导入说明
12
+
13
+ ### 数字类型字段
14
+
15
+ 支持数字和百分比,`N/A` 或 `-` 的文案会被过滤掉
16
+
17
+ | 数字1 | 百分比 | 数字2 | 数字3 |
18
+ | -- | -- | -- | -- |
19
+ | 123 | 25% | N/A | - |
20
+
21
+ 转 JSON 之后为
22
+
23
+ ```ts
24
+ {
25
+ "数字1": 123,
26
+ "百分比": 0.25,
27
+ "数字2": null,
28
+ "数字3": null,
29
+ }
30
+ ```
31
+
32
+ ### 布尔类型字段
33
+
34
+ 输入文案支持(英文不区分大小写):
35
+
36
+ - `Yes` `Y` `True` `1` `是`
37
+ - `No` `N` `False` `0` `否`
38
+
39
+ | 字段1 | 字段2 | 字段3 | 字段4 | 字段4 |
40
+ | -- | -- | -- | -- | -- |
41
+ | 否 | 是 | Y | true | 0 |
42
+
43
+ 转 JSON 之后为
44
+
45
+ ```ts
46
+ {
47
+ "字段1": false,
48
+ "字段2": true,
49
+ "字段3": true,
50
+ "字段4": true,
51
+ "字段5": false,
52
+ }
53
+ ```
54
+
55
+ ### 日期类型字段
56
+
57
+ | DateOnly | Local(+08:00) | GMT |
58
+ | -- | -- | -- |
59
+ | 2023-01-18 22:22:22 | 2023-01-18 22:22:22 | 2023-01-18 22:22:22 |
60
+
61
+ 转 JSON 之后为
62
+
63
+ ```ts
64
+ {
65
+ "DateOnly": "2023-01-18T00:00:00.000Z",
66
+ "Local(+08:00)": "2023-01-18T14:22:22.000Z",
67
+ "GMT": "2023-01-18T22:22:22.000Z",
68
+ }
69
+ ```
70
+
71
+ ### 选择类型字段
72
+
73
+ 选项值和选项标签都可作为导入文案,多个选项之间以以逗号(`,` `,`)或顿号(`、`)区分
74
+
75
+ 如字段 `优先级` 的可选项包括:
76
+
77
+ | 选项值 | 选项标签 |
78
+ | -- | -- |
79
+ | low | 低 |
80
+ | medium | 中 |
81
+ | high | 低 |
82
+
83
+ 选项值和选项标签都可作为导入文案
84
+
85
+ | 优先级 |
86
+ | -- |
87
+ | 高 |
88
+ | low |
89
+
90
+ 转 JSON 之后为
91
+
92
+ ```ts
93
+ [
94
+ { "优先级": "high" },
95
+ { "优先级": "low" },
96
+ ]
97
+ ```
98
+
99
+ ### 中国行政区字段
100
+
101
+ | 地区1 | 地区2 |
102
+ | -- | -- |
103
+ | 北京市/市辖区 | 天津市/市辖区 |
104
+
105
+ 转 JSON 之后为
106
+
107
+ ```ts
108
+ {
109
+ "地区1": ["11","1101"],
110
+ "地区2": ["12","1201"]
111
+ }
112
+ ```
113
+
114
+ ### 附件字段
115
+
116
+ | 附件 |
117
+ | --|
118
+ | https://www.nocobase.com/images/logo.png |
119
+
120
+ 转 JSON 之后为
121
+
122
+ ```ts
123
+ {
124
+ "附件": [
125
+ {
126
+ "filename": "logo.png",
127
+ "title": "logo.png",
128
+ "extname": ".png",
129
+ "url": "https://www.nocobase.com/images/logo.png"
130
+ }
131
+ ]
132
+ }
133
+ ```
134
+
135
+ ### 关系类型字段
136
+
137
+ 多条数据以逗号(`,` `,`)或顿号(`、`)区分
138
+
139
+ | 部门/名称 | 分类/标题 |
140
+ | -- | -- |
141
+ | 开发组 | 分类1、分类2 |
142
+
143
+ 转 JSON 之后为
144
+
145
+ ```ts
146
+ {
147
+ "部门": [1], // 1 为部门名称为「开发组」的记录 ID
148
+ "分类": [1,2], // 1,2 为分类标题为「分类1」和「分类2」的记录 ID
149
+ }
150
+ ```
151
+
152
+ ### JSON 类型字段
153
+
154
+ | JSON1 |
155
+ | -- |
156
+ | {"key":"value"} |
157
+
158
+ 转 JSON 之后为
159
+
160
+ ```ts
161
+ {
162
+ "JSON": {"key":"value"}
163
+ }
164
+ ```
165
+
166
+ ### 地图几何图形类型
167
+
168
+ | Point | Line | Polygon | Circle |
169
+ | -- | -- | -- | -- |
170
+ | 1,2 | (1,2),(3,4) | (1,2),(3,4),(1,2) | 1,2,3 |
171
+
172
+ 转 JSON 之后为
173
+
174
+ ```ts
175
+ {
176
+ "Point": [1,2],
177
+ "Line": [[1,2], [3,4]],
178
+ "Polygon": [[1,2], [3,4], [1,2]],
179
+ "Circle": [1,2,3]
180
+ }
181
+ ```
182
+
183
+ ## 自定义导入格式
184
+
185
+ 通过 `db.registerFieldValueParsers()` 方法注册自定义的 `ValueParser`,如:
186
+
187
+ ```ts
188
+ import { BaseValueParser } from '@nocobase/database';
189
+
190
+ class PointValueParser extends BaseValueParser {
191
+ async setValue(value) {
192
+ if (Array.isArray(value)) {
193
+ this.value = value;
194
+ } else if (typeof value === 'string') {
195
+ this.value = value.split(',');
196
+ } else {
197
+ this.errors.push('Value invalid');
198
+ }
199
+ }
200
+ }
201
+
202
+ const db = new Database();
203
+
204
+ // type=point 的字段导入时,将通过 PointValueParser 解析数据
205
+ db.registerFieldValueParsers({
206
+ point: PointValueParser,
207
+ });
208
+ ```
209
+
210
+ 导入示例
211
+
212
+ | Point |
213
+ | --|
214
+ | 1,2 |
215
+
216
+ 转 JSON 之后为
217
+
218
+ ```ts
219
+ {
220
+ "Point": [1,2]
221
+ }
222
+ ```
package/client.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './dist/client';
2
+ export { default } from './dist/client';
package/client.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./dist/client/index.js');
@@ -0,0 +1,9 @@
1
+ import { Schema } from '@formily/react';
2
+ import React from 'react';
3
+ export declare const useCurrentSchema: (action: string, key: string, find?: (schema: Schema, key: string, action: string) => any, rm?: (schema: any, cb: any) => any) => {
4
+ schema: any;
5
+ exists: boolean;
6
+ remove(): void;
7
+ };
8
+ export declare const ImportWarning: () => React.JSX.Element;
9
+ export declare const ImportActionInitializer: () => React.JSX.Element;
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare const ImportDesigner: () => React.JSX.Element;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export declare const ImportStatus: {
3
+ IMPORTING: number;
4
+ IMPORTED: number;
5
+ };
6
+ export declare const ImportModal: (props: any) => React.JSX.Element;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ export declare const ImportPluginProvider: (props: any) => React.JSX.Element;
3
+ export declare const ImportContextProvider: (props: any) => React.JSX.Element;
@@ -0,0 +1 @@
1
+ export declare const NAMESPACE = "action-import";
@@ -0,0 +1,29 @@
1
+ /// <reference types="react" />
2
+ export interface ImportContextType {
3
+ importModalVisible: boolean;
4
+ setImportModalVisible: (visible: boolean) => void;
5
+ importStatus: number;
6
+ setImportStatus: (status: number) => void;
7
+ importResult: {
8
+ data: {
9
+ type: string;
10
+ data: any[];
11
+ };
12
+ meta: {
13
+ successCount: number;
14
+ failureCount: number;
15
+ };
16
+ };
17
+ setImportResult: (result: {
18
+ data: {
19
+ type: string;
20
+ data: any[];
21
+ };
22
+ meta: {
23
+ successCount: number;
24
+ failureCount: number;
25
+ };
26
+ }) => void;
27
+ }
28
+ export declare const ImportContext: import("react").Context<ImportContextType>;
29
+ export declare const useImportContext: () => ImportContextType;
@@ -0,0 +1,9 @@
1
+ export * from './ImportActionInitializer';
2
+ export * from './ImportDesigner';
3
+ export * from './ImportPluginProvider';
4
+ export * from './useImportAction';
5
+ import { Plugin } from '@nocobase/client';
6
+ export declare class PluginActionImportClient extends Plugin {
7
+ load(): Promise<void>;
8
+ }
9
+ export default PluginActionImportClient;
@@ -0,0 +1,24 @@
1
+ (function(l,c){typeof exports=="object"&&typeof module!="undefined"?c(exports,require("react/jsx-runtime"),require("@formily/react"),require("@formily/shared"),require("@nocobase/client"),require("antd"),require("react-i18next"),require("@formily/antd-v5"),require("react"),require("react-dom"),require("@ant-design/icons"),require("lodash")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","@formily/react","@formily/shared","@nocobase/client","antd","react-i18next","@formily/antd-v5","react","react-dom","@ant-design/icons","lodash"],c):(l=typeof globalThis!="undefined"?globalThis:l||self,c(l["@nocobase/plugin-action-import"]={},l.jsxRuntime,l["@formily/react"],l["@formily/shared"],l["@nocobase/client"],l.antd,l["react-i18next"],l["@formily/antd-v5"],l.react,l["react-dom"],l["@ant-design/icons"],l.lodash))})(this,function(l,c,f,q,p,F,E,B,y,U,V,H){"use strict";var Ae=Object.defineProperty,we=Object.defineProperties;var Ce=Object.getOwnPropertyDescriptors;var ue=Object.getOwnPropertySymbols;var Te=Object.prototype.hasOwnProperty,Ee=Object.prototype.propertyIsEnumerable;var xe=(l,c,f)=>c in l?Ae(l,c,{enumerable:!0,configurable:!0,writable:!0,value:f}):l[c]=f,D=(l,c)=>{for(var f in c||(c={}))Te.call(c,f)&&xe(l,f,c[f]);if(ue)for(var f of ue(c))Ee.call(c,f)&&xe(l,f,c[f]);return l},R=(l,c)=>we(l,Ce(c));var _=(l,c,f)=>new Promise((q,p)=>{var F=y=>{try{B(f.next(y))}catch(U){p(U)}},E=y=>{try{B(f.throw(y))}catch(U){p(U)}},B=y=>y.done?q(y.value):Promise.resolve(y.value).then(F,E);B((f=f.apply(l,c)).next())});const w="action-import",fe=["id","createdAt","createdBy","updatedAt","updatedBy"],X=t=>{const{getCollectionFields:e}=p.useCollectionManager_deprecated(),s=e(t),o=(a,n)=>{var h;if(!a.interface||fe.includes(a.interface))return;const d={name:a.name,title:((h=a==null?void 0:a.uiSchema)==null?void 0:h.title)||a.name,schema:a==null?void 0:a.uiSchema};if(!a.target||n>=2)return d;if(a.target){const r=e(a.target),i=x(r,n+1).filter(Boolean);d.children=d.children||[],d.children.push(...i)}return d},x=(a,n)=>{const d=[];return a.forEach(h=>{const r=o(h,n);r&&d.push(r)}),d};return x(s,1)},he="action-import";function ge(){return E.useTranslation([he,"client"],{nsMode:"fallback"})}const G=(t,e,s)=>t.reduceProperties((o,x)=>{if(x[e]===s)return x;const a=G(x,e,s);return a||o}),ye=(t,e)=>e(t),W=(t,e,s=G,o=ye)=>{const x=f.useFieldSchema(),{remove:a}=p.useDesignable(),n=s(x,e,t);return{schema:n,exists:!!n,remove(){n&&o(n,a)}}},ve=t=>({importColumns:t==null?void 0:t.filter(s=>!s.children).map(s=>({dataIndex:[s.name]})),explain:""}),J=()=>{const{t}=ge();return c.jsx(F.Alert,{type:"warning",style:{marginBottom:"10px"},message:t("Import warning")})},K=()=>{const t=p.useSchemaInitializerItem(),{insert:e}=p.useSchemaInitializer(),{exists:s,remove:o}=W("importXlsx","x-action",t.find,t.remove),{name:x}=p.useCollection_deprecated(),a=X(x),n={type:"void",title:'{{ t("Import") }}',"x-action":"importXlsx","x-action-settings":{importSettings:{importColumns:[],explain:""}},"x-toolbar":"ActionSchemaToolbar","x-settings":"actionSettings:import","x-component":"Action","x-component-props":{icon:"CloudUploadOutlined",openMode:"modal"},properties:{modal:{type:"void",title:`{{ t("Import Data", {ns: "${w}" }) }}`,"x-component":"Action.Container","x-decorator":"Form","x-component-props":{width:"50%",className:p.css`
2
+ .ant-formily-item-label {
3
+ height: var(--controlHeightLG);
4
+ }
5
+ `},properties:{formLayout:{type:"void","x-component":"FormLayout",properties:{warning:{type:"void","x-component":"ImportWarning"},download:{type:"void",title:`{{ t("Step 1: Download template", {ns: "${w}" }) }}`,"x-component":"FormItem","x-acl-ignore":!0,properties:{tip:{type:"void","x-component":"Markdown.Void","x-editable":!1,"x-component-props":{style:{padding:"var(--paddingContentVerticalSM)",backgroundColor:"var(--colorInfoBg)",border:"1px solid var(--colorInfoBorder)",color:"var(--colorText)",marginBottom:"var(--marginSM)"},content:`{{ t("Download tip", {ns: "${w}" }) }}`}},downloadAction:{type:"void",title:`{{ t("Download template", {ns: "${w}" }) }}`,"x-component":"Action","x-component-props":{className:p.css`
6
+ margin-top: 5px;
7
+ `,useAction:"{{ useDownloadXlsxTemplateAction }}"}}}},upload:{type:"array",title:`{{ t("Step 2: Upload Excel", {ns: "${w}" }) }}`,"x-decorator":"FormItem","x-acl-ignore":!0,"x-component":"Upload.Dragger","x-validator":"{{ uploadValidator }}","x-component-props":{action:"",height:"150px",tipContent:`{{ t("Upload placeholder", {ns: "${w}" }) }}`,beforeUpload:"{{ beforeUploadHandler }}"}}}},footer:{"x-component":"Action.Container.Footer","x-component-props":{},properties:{actions:{type:"void","x-component":"ActionBar","x-component-props":{},properties:{cancel:{type:"void",title:'{{ t("Cancel") }}',"x-component":"Action","x-component-props":{useAction:"{{ cm.useCancelAction }}"}},startImport:{type:"void",title:`{{ t("Start import", {ns: "${w}" }) }}`,"x-component":"Action","x-component-props":{type:"primary",htmlType:"submit",useAction:"{{ useImportStartAction }}"},"x-reactions":{dependencies:["upload"],fulfill:{run:"validateUpload($form, $self, $deps)"}}}}}}}}}}};return c.jsx(p.SchemaInitializerSwitch,R(D({},t),{checked:s,title:t.title,onClick:()=>{var h;if(s)return o();n["x-action-settings"].importSettings=ve(a);const d=q.merge(n||{},t.schema||{});(h=t==null?void 0:t.schemaInitialize)==null||h.call(t,d),e(d)}}))},Se=["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/vnd.ms-excel"],$=()=>{const{t}=E.useTranslation(w),{name:e}=p.useCollection_deprecated(),s=X(e);return{importSettingsSchema:{type:"void","x-component":"Grid",properties:{explain:{type:"string",title:`{{ t("Import explain", {ns: "${w}"}) }}`,"x-decorator":"FormItem","x-component":"Input.TextArea"},importColumns:{type:"array","x-component":"ArrayItems","x-decorator":"FormItem",items:{type:"object",properties:{space:{type:"void","x-component":"Space","x-component-props":{className:p.css`
8
+ width: 100%;
9
+ & .ant-space-item:nth-child(2) {
10
+ flex: 1;
11
+ }
12
+ `},properties:{sort:{type:"void","x-decorator":"FormItem","x-component":"ArrayItems.SortHandle"},dataIndex:{type:"array","x-decorator":"FormItem","x-component":p.Cascader,required:!0,enum:s,"x-component-props":{fieldNames:{label:"title",value:"name",children:"children"},changeOnSelect:!1}},remove:{type:"void","x-decorator":"FormItem","x-component":"ArrayItems.Remove"}}}}},properties:{add:{type:"void",title:`{{ t("Add importable field", {ns: "${w}"}) }}`,"x-component":"ArrayItems.Addition","x-component-props":{className:p.css`
13
+ border-color: var(--colorSettings);
14
+ color: var(--colorSettings);
15
+ &.ant-btn-dashed:hover {
16
+ border-color: var(--colorSettings);
17
+ color: var(--colorSettings);
18
+ }
19
+ `}}}}}},beforeUploadHandler(){return!1},uploadValidator(o,x){var n;if(o.length>1)return{type:"error",message:t("Only one file is allowed to be uploaded")};const a=(n=o[0])!=null?n:{};return a.size>10*1024*1024?{type:"error",message:t("File size cannot exceed 10M")}:Se.includes(a.type)?"":{type:"error",message:t("Please upload the file of Excel")}},validateUpload(o,x,a){var d;const[n]=a;x.disabled=(n==null?void 0:n.length)===0,x.componentProps=R(D({},x.componentProps),{disabled:(n==null?void 0:n.length)===0||((d=o.errors)==null?void 0:d.length)>0})}}},Y=()=>{var d,h,r,i,g,m;const t=f.useField(),e=f.useFieldSchema(),{t:s}=E.useTranslation(),{dn:o}=p.useDesignable(),[x,a]=y.useState(),{importSettingsSchema:n}=$();return y.useEffect(()=>{a(n)},[t.address,(d=e==null?void 0:e["x-action-settings"])==null?void 0:d.importSettings]),c.jsxs(p.GeneralSchemaDesigner,{disableInitializer:!0,children:[c.jsx(p.SchemaSettingsModalItem,{title:s("Edit button"),schema:{type:"object",title:s("Edit button"),properties:{title:{"x-decorator":"FormItem","x-component":"Input",title:s("Button title"),default:e.title,"x-component-props":{}},icon:{"x-decorator":"FormItem","x-component":"IconPicker",title:s("Button icon"),default:(h=e==null?void 0:e["x-component-props"])==null?void 0:h.icon,"x-component-props":{}},type:{"x-decorator":"FormItem","x-component":"Radio.Group",title:s("Button background color"),default:(r=e==null?void 0:e["x-component-props"])!=null&&r.danger?"danger":((i=e==null?void 0:e["x-component-props"])==null?void 0:i.type)==="primary"?"primary":"default",enum:[{value:"default",label:'{{t("Default")}}'},{value:"primary",label:'{{t("Highlight")}}'},{value:"danger",label:'{{t("Danger red")}}'}]}}},onSubmit:({title:u,icon:v,type:S})=>{e.title=u,t.title=u,t.componentProps.icon=v,t.componentProps.danger=S==="danger",t.componentProps.type=S,e["x-component-props"]=e["x-component-props"]||{},e["x-component-props"].icon=v,e["x-component-props"].danger=S==="danger",e["x-component-props"].type=S,o.emit("patch",{schema:{"x-uid":e["x-uid"],title:u,"x-component-props":D({},e["x-component-props"])}}),o.refresh()}}),c.jsx(p.SchemaSettingsActionModalItem,{title:s("Importable fields"),schema:x,initialValues:D({},(m=(g=e==null?void 0:e["x-action-settings"])==null?void 0:g.importSettings)!=null?m:{}),components:{ArrayItems:B.ArrayItems},onSubmit:({importColumns:u,explain:v})=>{const S=u==null?void 0:u.filter(b=>{var T;return(T=b==null?void 0:b.dataIndex)==null?void 0:T.length}).map(b=>({dataIndex:b.dataIndex.map(T=>{var I;return(I=T.name)!=null?I:T}),title:b.title}));e["x-action-settings"].importSettings={importColumns:S,explain:v},o.emit("patch",{schema:{"x-uid":e["x-uid"],"x-action-settings":e["x-action-settings"]}}),o.refresh()}}),c.jsx(p.SchemaSettingsDivider,{}),c.jsx(p.SchemaSettingsRemove,{removeParentsIfNoChildren:!0,breakRemoveOn:u=>u["x-component"]==="Space"||u["x-component"].endsWith("ActionBar"),confirm:{title:s("Delete action")}})]})},z=y.createContext(null);z.displayName="ImportContext";const Q=()=>y.useContext(z);var k=typeof globalThis!="undefined"?globalThis:typeof window!="undefined"?window:typeof global!="undefined"?global:typeof self!="undefined"?self:{},Z={exports:{}};(function(t,e){(function(s,o){o()})(k,function(){function s(r,i){return typeof i=="undefined"?i={autoBom:!1}:typeof i!="object"&&(console.warn("Deprecated: Expected third argument to be a object"),i={autoBom:!i}),i.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(r.type)?new Blob(["\uFEFF",r],{type:r.type}):r}function o(r,i,g){var m=new XMLHttpRequest;m.open("GET",r),m.responseType="blob",m.onload=function(){h(m.response,i,g)},m.onerror=function(){console.error("could not download file")},m.send()}function x(r){var i=new XMLHttpRequest;i.open("HEAD",r,!1);try{i.send()}catch(g){}return 200<=i.status&&299>=i.status}function a(r){try{r.dispatchEvent(new MouseEvent("click"))}catch(g){var i=document.createEvent("MouseEvents");i.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),r.dispatchEvent(i)}}var n=typeof window=="object"&&window.window===window?window:typeof self=="object"&&self.self===self?self:typeof k=="object"&&k.global===k?k:void 0,d=n.navigator&&/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),h=n.saveAs||(typeof window!="object"||window!==n?function(){}:"download"in HTMLAnchorElement.prototype&&!d?function(r,i,g){var m=n.URL||n.webkitURL,u=document.createElement("a");i=i||r.name||"download",u.download=i,u.rel="noopener",typeof r=="string"?(u.href=r,u.origin===location.origin?a(u):x(u.href)?o(r,i,g):a(u,u.target="_blank")):(u.href=m.createObjectURL(r),setTimeout(function(){m.revokeObjectURL(u.href)},4e4),setTimeout(function(){a(u)},0))}:"msSaveOrOpenBlob"in navigator?function(r,i,g){if(i=i||r.name||"download",typeof r!="string")navigator.msSaveOrOpenBlob(s(r,g),i);else if(x(r))o(r,i,g);else{var m=document.createElement("a");m.href=r,m.target="_blank",setTimeout(function(){a(m)})}}:function(r,i,g,m){if(m=m||open("","_blank"),m&&(m.document.title=m.document.body.innerText="downloading..."),typeof r=="string")return o(r,i,g);var u=r.type==="application/octet-stream",v=/constructor/i.test(n.HTMLElement)||n.safari,S=/CriOS\/[\d]+/.test(navigator.userAgent);if((S||u&&v||d)&&typeof FileReader!="undefined"){var b=new FileReader;b.onloadend=function(){var A=b.result;A=S?A:A.replace(/^data:[^;]*;/,"data:attachment/file;"),m?m.location.href=A:location=A,m=null},b.readAsDataURL(r)}else{var T=n.URL||n.webkitURL,I=T.createObjectURL(r);m?m.location=I:location.href=I,m=null,setTimeout(function(){T.revokeObjectURL(I)},4e4)}});n.saveAs=h.saveAs=h,t.exports=h})})(Z);var ee=Z.exports;const O={IMPORTING:1,IMPORTED:2},Ie=t=>{const{t:e}=E.useTranslation(w),{importModalVisible:s,importStatus:o,importResult:x,setImportModalVisible:a}=Q(),{data:n,meta:d}=x!=null?x:{},h=()=>{a(!1)},r=()=>{const i=new Int8Array(n==null?void 0:n.data),g=new Blob([i],{type:"application/x-xls"});ee.saveAs(g,"fail.xlsx")};return c.jsx(F.Modal,{title:e("Import Data"),width:"50%",styles:{body:{height:"calc(80vh - 200px)"}},open:s,footer:null,closable:o===O.IMPORTED,onCancel:h,children:c.jsxs("div",{className:p.css`
20
+ display: flex;
21
+ justify-content: center;
22
+ align-items: center;
23
+ height: 100%;
24
+ `,children:[o===O.IMPORTING&&c.jsx(F.Spin,{indicator:c.jsx(V.LoadingOutlined,{style:{fontSize:24},spin:!0}),tip:e("Excel data importing")}),o===O.IMPORTED&&c.jsxs(F.Space,{direction:"vertical",align:"center",children:[c.jsx(V.ExclamationCircleFilled,{style:{fontSize:72,color:"#1890ff"}}),c.jsx("p",{children:e("Import done, total success have {{successCount}} , total failure have {{failureCount}}",D({},d!=null?d:{}))}),c.jsxs(F.Space,{children:[(d==null?void 0:d.failureCount)>0&&c.jsx(F.Button,{onClick:r,children:e("To download the failure data")}),c.jsx(F.Button,{type:"primary",onClick:h,children:e("Done")})]})]})]})})},te=t=>{let e=t;for(;e&&e["x-action"]!=="importXlsx";)e=e.parent;return{schema:e}},oe=t=>!t||!Array.isArray(t)?[]:t,ne=()=>{const{service:t,resource:e}=p.useBlockRequestContext();p.useAPIClient();const s=f.useFieldSchema(),o=p.useCompile(),{getCollectionJoinField:x,getCollectionField:a}=p.useCollectionManager_deprecated(),{name:n,title:d,getField:h}=p.useCollection_deprecated();E.useTranslation(w);const{schema:r}=te(s);return{run(){return _(this,null,function*(){var b,T;const{importColumns:g,explain:m}=H.cloneDeep((T=(b=r==null?void 0:r["x-action-settings"])==null?void 0:b.importSettings)!=null?T:{}),u=oe(g).map(I=>{var N,M;const A=a(`${n}.${I.dataIndex[0]}`);if(A){if(I.defaultTitle=o((N=A==null?void 0:A.uiSchema)==null?void 0:N.title)||A.name,I.dataIndex.length>1){const P=x(`${n}.${I.dataIndex.join(".")}`);if(!P)return;I.defaultTitle=I.defaultTitle+"/"+o((M=P==null?void 0:P.uiSchema)==null?void 0:M.title)||P.name}return A.interface==="chinaRegion"&&I.dataIndex.push("name"),I}}).filter(Boolean),{data:v}=yield e.downloadXlsxTemplate({values:{title:o(d),explain:m,columns:o(u)}},{method:"post",responseType:"blob"}),S=new Blob([v],{type:"application/x-xls"});ee.saveAs(S,`${o(d)}.xlsx`)})}}},re=()=>{const{service:t,resource:e}=p.useBlockRequestContext(),s=p.useAPIClient(),o=f.useFieldSchema(),x=p.useCompile(),{getCollectionJoinField:a,getCollectionField:n}=p.useCollectionManager_deprecated(),{name:d,title:h,getField:r}=p.useCollection_deprecated();E.useTranslation(w);const{schema:i}=te(o),g=f.useForm(),{setVisible:m,fieldSchema:u}=p.useActionContext(),{setImportModalVisible:v,setImportStatus:S,setImportResult:b}=Q();return{run(){return _(this,null,function*(){var ce,pe,le;const{importColumns:I,explain:A}=H.cloneDeep((pe=(ce=i==null?void 0:i["x-action-settings"])==null?void 0:ce.importSettings)!=null?pe:{}),N=oe(I).map(C=>{var de,me;const j=n(`${d}.${C.dataIndex[0]}`);if(j){if(C.defaultTitle=x((de=j==null?void 0:j.uiSchema)==null?void 0:de.title)||j.name,C.dataIndex.length>1){const L=a(`${d}.${C.dataIndex.join(".")}`);if(!L)return;C.defaultTitle=C.defaultTitle+"/"+x((me=L==null?void 0:L.uiSchema)==null?void 0:me.title)||L.name}return j.interface==="chinaRegion"&&C.dataIndex.push("name"),C}}).filter(Boolean),M=new FormData,P=g.values.upload.map(C=>C.originFileObj);M.append("file",P[0]),M.append("columns",JSON.stringify(N)),M.append("explain",A),m(!1),v(!0),S(O.IMPORTING);try{const{data:C}=yield s.axios.post(`${d}:importXlsx`,M,{timeout:6e5});b(C),g.reset(),yield(le=t==null?void 0:t.refresh)==null?void 0:le.call(t),S(O.IMPORTED)}catch(C){v(!1),m(!0)}})}}},ae=t=>{const{uploadValidator:e,beforeUploadHandler:s,validateUpload:o}=$();return c.jsx(p.SchemaComponentOptions,{components:{ImportActionInitializer:K,ImportDesigner:Y,ImportWarning:J},scope:{uploadValidator:e,validateUpload:o,beforeUploadHandler:s,useDownloadXlsxTemplateAction:ne,useImportStartAction:re},children:c.jsx(ie,{children:t.children})})},ie=t=>{const[e,s]=y.useState(!1),[o,x]=y.useState(O.IMPORTING),[a,n]=y.useState(null);return c.jsxs(z.Provider,{value:{importModalVisible:e,setImportModalVisible:s,importStatus:o,setImportStatus:x,importResult:a,setImportResult:n},children:[U.createPortal(c.jsx(Ie,{}),document.body),t.children]})},be=new p.SchemaSettings({name:"actionSettings:import",items:[{name:"editButton",Component:p.ButtonEditor,useComponentProps(){const{buttonEditorProps:t}=p.useSchemaToolbar();return t}},{name:"importableFields",type:"actionModal",useComponentProps(){var d,h,r;const t=f.useField(),e=f.useFieldSchema(),{t:s}=E.useTranslation(),{dn:o}=p.useDesignable(),[x,a]=y.useState(),{importSettingsSchema:n}=$();return y.useEffect(()=>{a(n)},[t.address,(d=e==null?void 0:e["x-action-settings"])==null?void 0:d.importSettings]),{title:s("Importable fields"),schema:x,initialValues:D({},(r=(h=e==null?void 0:e["x-action-settings"])==null?void 0:h.importSettings)!=null?r:{}),components:{ArrayItems:B.ArrayItems},onSubmit:({importColumns:i,explain:g})=>{const m=i==null?void 0:i.filter(u=>{var v;return(v=u==null?void 0:u.dataIndex)==null?void 0:v.length}).map(u=>({dataIndex:u.dataIndex.map(v=>{var S;return(S=v.name)!=null?S:v}),title:u.title}));e["x-action-settings"].importSettings={importColumns:m,explain:g},o.emit("patch",{schema:{"x-uid":e["x-uid"],"x-action-settings":e["x-action-settings"]}}),o.refresh()}}}},{name:"divider",type:"divider"},{name:"delete",type:"remove",useComponentProps(){const{t}=E.useTranslation();return{removeParentsIfNoChildren:!0,breakRemoveOn:e=>e["x-component"]==="Space"||e["x-component"].endsWith("ActionBar"),confirm:{title:t("Delete action")}}}}]});class se extends p.Plugin{load(){return _(this,null,function*(){this.app.use(ae);const e={title:"{{t('Import')}}",Component:"ImportActionInitializer",schema:{"x-align":"right","x-decorator":"ACLActionProvider","x-acl-action":"importXlsx","x-acl-action-props":{skipScopeCheck:!0}},useVisible(){const o=p.useCollection_deprecated();return(o.template!=="view"||(o==null?void 0:o.writableView))&&o.template!=="file"&&o.template!=="sql"}},s=this.app.schemaInitializerManager.get("table:configureActions");s==null||s.add("enableActions.import",e),this.app.schemaInitializerManager.addItem("gantt:configureActions","enableActions.import",e),this.app.schemaSettingsManager.add(be)})}}l.ImportActionInitializer=K,l.ImportContextProvider=ie,l.ImportDesigner=Y,l.ImportPluginProvider=ae,l.ImportWarning=J,l.PluginActionImportClient=se,l.default=se,l.useCurrentSchema=W,l.useDownloadXlsxTemplateAction=ne,l.useImportStartAction=re,Object.defineProperties(l,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
@@ -0,0 +1,2 @@
1
+ export declare const NAMESPACE = "action-import";
2
+ export declare function useImportTranslation(): import("react-i18next").UseTranslationResponse<("action-import" | "client")[], undefined>;
@@ -0,0 +1,2 @@
1
+ import { SchemaSettings } from '@nocobase/client';
2
+ export declare const importActionSchemaSettings: SchemaSettings<{}>;
@@ -0,0 +1 @@
1
+ export declare const useFields: (collectionName: string) => any[];
@@ -0,0 +1,6 @@
1
+ export declare const useDownloadXlsxTemplateAction: () => {
2
+ run(): Promise<void>;
3
+ };
4
+ export declare const useImportStartAction: () => {
5
+ run(): Promise<void>;
6
+ };
@@ -0,0 +1,76 @@
1
+ /// <reference types="react" />
2
+ import type { VoidField } from '@formily/core';
3
+ export declare const useShared: () => {
4
+ importSettingsSchema: {
5
+ type: string;
6
+ 'x-component': string;
7
+ properties: {
8
+ explain: {
9
+ type: string;
10
+ title: string;
11
+ 'x-decorator': string;
12
+ 'x-component': string;
13
+ };
14
+ importColumns: {
15
+ type: string;
16
+ 'x-component': string;
17
+ 'x-decorator': string;
18
+ items: {
19
+ type: string;
20
+ properties: {
21
+ space: {
22
+ type: string;
23
+ 'x-component': string;
24
+ 'x-component-props': {
25
+ className: string;
26
+ };
27
+ properties: {
28
+ sort: {
29
+ type: string;
30
+ 'x-decorator': string;
31
+ 'x-component': string;
32
+ };
33
+ dataIndex: {
34
+ type: string;
35
+ 'x-decorator': string;
36
+ 'x-component': import("react").ForwardRefExoticComponent<Omit<Partial<any>, "ref"> & import("react").RefAttributes<unknown>>;
37
+ required: boolean;
38
+ enum: any[];
39
+ 'x-component-props': {
40
+ fieldNames: {
41
+ label: string;
42
+ value: string;
43
+ children: string;
44
+ };
45
+ changeOnSelect: boolean;
46
+ };
47
+ };
48
+ remove: {
49
+ type: string;
50
+ 'x-decorator': string;
51
+ 'x-component': string;
52
+ };
53
+ };
54
+ };
55
+ };
56
+ };
57
+ properties: {
58
+ add: {
59
+ type: string;
60
+ title: string;
61
+ 'x-component': string;
62
+ 'x-component-props': {
63
+ className: string;
64
+ };
65
+ };
66
+ };
67
+ };
68
+ };
69
+ };
70
+ beforeUploadHandler(): boolean;
71
+ uploadValidator(value: any, rule: any): "" | {
72
+ type: string;
73
+ message: string;
74
+ };
75
+ validateUpload(form: any, submitField: VoidField, deps: any): void;
76
+ };