@cloudtower/eagle 0.34.25 → 0.35.2

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.
@@ -0,0 +1,63 @@
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ const useFileValidation = ({
4
+ fileList,
5
+ setFileList,
6
+ validate,
7
+ createNewFile = false
8
+ }) => {
9
+ useEffect(() => {
10
+ if (!validate)
11
+ return;
12
+ const updateFile = (fileId, file) => {
13
+ const index = fileList.findIndex((f) => f.uid === fileId);
14
+ if (index !== -1) {
15
+ const newList = [...fileList];
16
+ const fileToUpdate = createNewFile ? (() => {
17
+ const newFile = new File([file], file.name, { type: file.type });
18
+ Object.assign(newFile, file);
19
+ return newFile;
20
+ })() : file;
21
+ newList.splice(index, 1, fileToUpdate);
22
+ setFileList(newList);
23
+ }
24
+ };
25
+ for (const _file of fileList) {
26
+ if (_file.fileStatus !== "need-validate") {
27
+ continue;
28
+ }
29
+ _file.fileStatus = "validating";
30
+ updateFile(_file.uid, _file);
31
+ validate(_file, fileList).then((result) => {
32
+ if (result.error) {
33
+ _file.error = result.error;
34
+ _file.fileStatus = "error";
35
+ } else {
36
+ _file.error = void 0;
37
+ _file.fileStatus = "success";
38
+ _file.data = result.data;
39
+ }
40
+ updateFile(_file.uid, _file);
41
+ return;
42
+ });
43
+ }
44
+ }, [fileList, setFileList, validate, createNewFile]);
45
+ };
46
+ const useFileCountErrorClear = ({
47
+ fileList,
48
+ maxCount,
49
+ setError
50
+ }) => {
51
+ const fileCountRef = useRef(fileList.length);
52
+ useEffect(() => {
53
+ if (fileList.length === fileCountRef.current) {
54
+ return;
55
+ }
56
+ fileCountRef.current = fileList.length;
57
+ if (fileCountRef.current <= maxCount) {
58
+ setError("");
59
+ }
60
+ }, [fileList.length, maxCount, setError]);
61
+ };
62
+
63
+ export { useFileCountErrorClear, useFileValidation };
@@ -0,0 +1,97 @@
1
+ import useParrotTranslation from '../../hooks/useParrotTranslation.js';
2
+ import React__default from 'react';
3
+ import { UploadWrapper } from './LocalUpload.style.js';
4
+ import { UploadLabel, UploadDescription, UploadButton, UploadDragger, UploadFileList, UploadFileInfo } from './LocalUpload.widget.js';
5
+
6
+ var __defProp = Object.defineProperty;
7
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
+ var __spreadValues = (a, b) => {
12
+ for (var prop in b || (b = {}))
13
+ if (__hasOwnProp.call(b, prop))
14
+ __defNormalProp(a, prop, b[prop]);
15
+ if (__getOwnPropSymbols)
16
+ for (var prop of __getOwnPropSymbols(b)) {
17
+ if (__propIsEnum.call(b, prop))
18
+ __defNormalProp(a, prop, b[prop]);
19
+ }
20
+ return a;
21
+ };
22
+ const UploadComp = React__default.forwardRef(
23
+ ({
24
+ className,
25
+ label,
26
+ description,
27
+ type = "dragger",
28
+ multiple = false,
29
+ accept,
30
+ disabled,
31
+ maxCount,
32
+ info,
33
+ fileList,
34
+ setFileList,
35
+ validate,
36
+ buttonProps,
37
+ listType = "list",
38
+ disableRemoveList = false,
39
+ onRemove
40
+ }, ref) => {
41
+ const { t } = useParrotTranslation();
42
+ const removeFile = (id) => {
43
+ const index = fileList.findIndex((f) => f.uid === id);
44
+ if (index !== -1) {
45
+ const file = fileList[index];
46
+ fileList.splice(index, 1);
47
+ setFileList([...fileList]);
48
+ onRemove == null ? void 0 : onRemove(file);
49
+ }
50
+ };
51
+ const _maxCount = multiple ? maxCount || Infinity : 1;
52
+ const isSingleSelect = _maxCount === 1;
53
+ return /* @__PURE__ */ React__default.createElement(UploadComp.Wrapper, { className, ref }, label ? /* @__PURE__ */ React__default.createElement(UploadComp.Label, null, label) : null, description ? /* @__PURE__ */ React__default.createElement(UploadComp.Description, null, description) : null, type === "button" ? /* @__PURE__ */ React__default.createElement(
54
+ UploadComp.Button,
55
+ __spreadValues({}, __spreadValues({
56
+ accept,
57
+ multiple,
58
+ disabled,
59
+ maxCount,
60
+ fileList,
61
+ setFileList,
62
+ validate
63
+ }, buttonProps)),
64
+ t("components.select_file")
65
+ ) : /* @__PURE__ */ React__default.createElement(
66
+ UploadComp.Dragger,
67
+ __spreadValues({}, {
68
+ accept,
69
+ multiple,
70
+ disabled,
71
+ maxCount,
72
+ fileList,
73
+ setFileList,
74
+ validate
75
+ })
76
+ ), info != null ? info : /* @__PURE__ */ React__default.createElement(React__default.Fragment, null), type === "button" || !isSingleSelect ? /* @__PURE__ */ React__default.createElement(
77
+ UploadComp.FileList,
78
+ {
79
+ fileList,
80
+ removeFile,
81
+ type: listType,
82
+ disableRemove: disableRemoveList,
83
+ onRemove
84
+ }
85
+ ) : null);
86
+ }
87
+ );
88
+ UploadComp.Wrapper = UploadWrapper;
89
+ UploadComp.Label = UploadLabel;
90
+ UploadComp.Description = UploadDescription;
91
+ UploadComp.Button = UploadButton;
92
+ UploadComp.Dragger = UploadDragger;
93
+ UploadComp.FileList = UploadFileList;
94
+ UploadComp.FileInfo = UploadFileInfo;
95
+ const LocalUpload = UploadComp;
96
+
97
+ export { LocalUpload };
@@ -0,0 +1,10 @@
1
+ import { styled } from '@linaria/react';
2
+
3
+ const UploadWrapper = /*#__PURE__*/styled('div')({
4
+ name: "UploadWrapper",
5
+ class: "E_u3l9ivi",
6
+ propsAsIs: false
7
+ });
8
+ const FileInfoWrapperStyle = "E_ftdwz1g";
9
+
10
+ export { FileInfoWrapperStyle, UploadWrapper };
@@ -0,0 +1,365 @@
1
+ import { Uploading16GradientGrayIcon, Uploading16GradientBlueIcon, Upload24GradientGrayIcon, Upload24GradientBlueIcon, Upload48GradientBlueIcon, XmarkRemove16SecondaryIcon, ExclamationErrorCircleFill16RedIcon, File16GradientBlueIcon, Loading16GradientBlueIcon, XmarkRemove24SecondaryIcon } from '@cloudtower/icons-react';
2
+ import { cx } from '@linaria/core';
3
+ import Button from '../Button/index.js';
4
+ import Byte from '../Byte/index.js';
5
+ import Icon from '../Icon/index.js';
6
+ import Tooltip from '../Tooltip/index.js';
7
+ import { Typo } from '../Typo/index.js';
8
+ import OverflowTooltip from '../../coreX/OverflowTooltip/index.js';
9
+ import useParrotTranslation from '../../hooks/useParrotTranslation.js';
10
+ import cs from 'classnames';
11
+ import _ from 'lodash';
12
+ import React__default, { useState } from 'react';
13
+ import { useFileValidation, useFileCountErrorClear } from './LocalUpload.hooks.js';
14
+ import { FileInfoWrapperStyle } from './LocalUpload.style.js';
15
+ import { Upload } from 'antd';
16
+
17
+ var __defProp = Object.defineProperty;
18
+ var __defProps = Object.defineProperties;
19
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
20
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
21
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
22
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
23
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
24
+ var __spreadValues = (a, b) => {
25
+ for (var prop in b || (b = {}))
26
+ if (__hasOwnProp.call(b, prop))
27
+ __defNormalProp(a, prop, b[prop]);
28
+ if (__getOwnPropSymbols)
29
+ for (var prop of __getOwnPropSymbols(b)) {
30
+ if (__propIsEnum.call(b, prop))
31
+ __defNormalProp(a, prop, b[prop]);
32
+ }
33
+ return a;
34
+ };
35
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
36
+ const STATUS_ICON_MAP = {
37
+ error: ExclamationErrorCircleFill16RedIcon,
38
+ success: File16GradientBlueIcon,
39
+ validating: Loading16GradientBlueIcon,
40
+ "need-validate": Loading16GradientBlueIcon
41
+ };
42
+ const createBeforeUploadHandler = ({
43
+ fileList,
44
+ setFileList,
45
+ validate,
46
+ maxCount,
47
+ isSingleSelect,
48
+ setError,
49
+ t,
50
+ checkSingleSelectCount = false
51
+ }) => {
52
+ return (file, _fileList) => {
53
+ if (isSingleSelect) {
54
+ if (checkSingleSelectCount && _fileList.length > 1) {
55
+ setError(t("components.exceed_max_count", { count: 1 }) || "");
56
+ return false;
57
+ } else {
58
+ setError("");
59
+ }
60
+ const _file2 = file;
61
+ _file2.fileStatus = validate ? "need-validate" : "success";
62
+ setFileList([_file2]);
63
+ return false;
64
+ }
65
+ if (fileList.length + _fileList.length > maxCount) {
66
+ setError(t("components.exceed_max_count", { count: maxCount }) || "");
67
+ } else {
68
+ setError("");
69
+ }
70
+ const _file = file;
71
+ _file.fileStatus = validate ? "need-validate" : "success";
72
+ const index = _fileList.findIndex((f) => f.uid === _file.uid);
73
+ if (index !== -1) {
74
+ const newList = _.uniqBy(
75
+ [...fileList, ..._fileList.slice(0, index + 1)],
76
+ "uid"
77
+ );
78
+ setFileList(newList);
79
+ }
80
+ return false;
81
+ };
82
+ };
83
+ const UploadLabel = ({ className, children }) => {
84
+ return /* @__PURE__ */ React__default.createElement("label", { className: cx("upload-label", Typo.Label.l2_regular, className) }, children);
85
+ };
86
+ const UploadDescription = ({ className, children }) => {
87
+ return /* @__PURE__ */ React__default.createElement("div", { className: cx("upload-description", Typo.Label.l4_regular, className) }, children);
88
+ };
89
+ const UploadButton = ({
90
+ children,
91
+ hideIcon = false,
92
+ className,
93
+ fileList,
94
+ setFileList,
95
+ validate,
96
+ maxCount,
97
+ multiple = false,
98
+ disabled,
99
+ accept
100
+ }) => {
101
+ const { t } = useParrotTranslation();
102
+ const [error, setError] = useState("");
103
+ const _maxCount = multiple ? maxCount || Infinity : 1;
104
+ const isSingleSelect = _maxCount === 1;
105
+ useFileValidation({
106
+ fileList,
107
+ setFileList,
108
+ validate,
109
+ createNewFile: false
110
+ });
111
+ useFileCountErrorClear({
112
+ fileList,
113
+ maxCount: _maxCount,
114
+ setError
115
+ });
116
+ const props = {
117
+ accept,
118
+ fileList,
119
+ showUploadList: false,
120
+ beforeUpload: createBeforeUploadHandler({
121
+ fileList,
122
+ setFileList,
123
+ validate,
124
+ maxCount: _maxCount,
125
+ isSingleSelect,
126
+ setError,
127
+ t,
128
+ checkSingleSelectCount: false
129
+ }),
130
+ multiple
131
+ };
132
+ return /* @__PURE__ */ React__default.createElement(Upload, __spreadProps(__spreadValues({}, props), { className: cs("upload-button", className) }), /* @__PURE__ */ React__default.createElement(
133
+ Button,
134
+ {
135
+ disabled,
136
+ prefixIcon: !hideIcon ? /* @__PURE__ */ React__default.createElement(Icon, { src: Uploading16GradientGrayIcon }) : void 0,
137
+ hoverPrefixIcon: !hideIcon ? /* @__PURE__ */ React__default.createElement(Icon, { src: Uploading16GradientBlueIcon }) : void 0
138
+ },
139
+ children
140
+ ), error ? /* @__PURE__ */ React__default.createElement("div", { className: cx("upload-error", Typo.Label.l4_regular) }, error) : null);
141
+ };
142
+ const UploadDragger = ({
143
+ children,
144
+ className,
145
+ fileList,
146
+ setFileList,
147
+ validate,
148
+ maxCount,
149
+ multiple = false,
150
+ disabled,
151
+ accept
152
+ }) => {
153
+ var _a;
154
+ const { t } = useParrotTranslation();
155
+ const [error, setError] = useState("");
156
+ const _maxCount = multiple ? maxCount || Infinity : 1;
157
+ const isSingleSelect = _maxCount === 1;
158
+ const reachMaxCount = !!maxCount && !isSingleSelect && fileList.length >= maxCount;
159
+ useFileValidation({
160
+ fileList,
161
+ setFileList,
162
+ validate,
163
+ createNewFile: true
164
+ });
165
+ useFileCountErrorClear({
166
+ fileList,
167
+ maxCount: _maxCount,
168
+ setError
169
+ });
170
+ const props = {
171
+ accept,
172
+ fileList,
173
+ showUploadList: false,
174
+ beforeUpload: createBeforeUploadHandler({
175
+ fileList,
176
+ setFileList,
177
+ validate,
178
+ maxCount: _maxCount,
179
+ isSingleSelect,
180
+ setError,
181
+ t,
182
+ checkSingleSelectCount: true
183
+ }),
184
+ disabled,
185
+ multiple
186
+ };
187
+ const DefaultChildren = /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(
188
+ Icon,
189
+ {
190
+ src: (fileList == null ? void 0 : fileList.length) ? reachMaxCount ? Upload24GradientGrayIcon : Upload24GradientBlueIcon : Upload48GradientBlueIcon,
191
+ iconHeight: (fileList == null ? void 0 : fileList.length) ? 24 : 48,
192
+ iconWidth: (fileList == null ? void 0 : fileList.length) ? 24 : 48
193
+ }
194
+ ), /* @__PURE__ */ React__default.createElement("div", { className: cx("upload-drag-text", Typo.Label.l2_regular) }, t("components.upload_file_desc")));
195
+ const fileStatus = isSingleSelect ? ((_a = fileList[0]) == null ? void 0 : _a.fileStatus) || "success" : void 0;
196
+ const FileInfo = ({ file }) => {
197
+ const fileStatus2 = file.fileStatus || "success";
198
+ return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement("div", { className: "file-info", onClick: (e) => e.preventDefault() }, /* @__PURE__ */ React__default.createElement(
199
+ Icon,
200
+ {
201
+ src: STATUS_ICON_MAP[fileStatus2],
202
+ isRotate: fileStatus2 === "validating" || fileStatus2 === "need-validate"
203
+ }
204
+ ), /* @__PURE__ */ React__default.createElement("div", { className: cx("file-name", Typo.Label.l4_regular) }, file.name || file.fileName)), /* @__PURE__ */ React__default.createElement(Button, { className: Typo.Label.l2_regular, type: "link" }, t("components.reselect_file")));
205
+ };
206
+ const Error2 = () => {
207
+ if (error) {
208
+ return /* @__PURE__ */ React__default.createElement("div", { className: cx("upload-error", Typo.Label.l4_regular) }, error);
209
+ }
210
+ const file = fileList[0];
211
+ if (isSingleSelect && (file == null ? void 0 : file.fileStatus) === "error" && file.error) {
212
+ return /* @__PURE__ */ React__default.createElement("div", { className: cx("upload-error", Typo.Label.l4_regular) }, file.error);
213
+ }
214
+ return null;
215
+ };
216
+ return /* @__PURE__ */ React__default.createElement("div", { className: cs("upload-drag", className) }, /* @__PURE__ */ React__default.createElement(
217
+ Upload.Dragger,
218
+ __spreadProps(__spreadValues({}, props), {
219
+ disabled: disabled || fileStatus === "validating",
220
+ className: cs(
221
+ "upload-drag-area",
222
+ fileList.length ? "has-file" : "",
223
+ reachMaxCount && "reach-max-count",
224
+ isSingleSelect && "single",
225
+ fileStatus === "error" && "file-error",
226
+ fileStatus === "validating" && "file-validating"
227
+ )
228
+ }),
229
+ isSingleSelect && fileList.length ? /* @__PURE__ */ React__default.createElement(FileInfo, { file: fileList[0] }) : children || DefaultChildren
230
+ ), /* @__PURE__ */ React__default.createElement(Error2, null));
231
+ };
232
+ const UploadFileInfo = ({
233
+ file,
234
+ removeFile,
235
+ disabled,
236
+ onRemove
237
+ }) => {
238
+ const fileStatus = file.fileStatus || "success";
239
+ const handleRemove = () => {
240
+ var _a;
241
+ removeFile((_a = file.uid) != null ? _a : "");
242
+ if (onRemove && "fileStatus" in file) {
243
+ onRemove(file);
244
+ }
245
+ };
246
+ return /* @__PURE__ */ React__default.createElement(
247
+ "div",
248
+ {
249
+ className: cs(FileInfoWrapperStyle, {
250
+ "file-error-wrapper": fileStatus === "error",
251
+ disabled
252
+ })
253
+ },
254
+ /* @__PURE__ */ React__default.createElement(
255
+ Icon,
256
+ {
257
+ src: STATUS_ICON_MAP[fileStatus],
258
+ isRotate: fileStatus === "validating" || fileStatus === "need-validate"
259
+ }
260
+ ),
261
+ /* @__PURE__ */ React__default.createElement("div", { className: cx("file-info", Typo.Label.l4_regular) }, /* @__PURE__ */ React__default.createElement(
262
+ OverflowTooltip,
263
+ {
264
+ className: "file-name",
265
+ content: file.name || file.fileName,
266
+ tooltip: file.name || file.fileName
267
+ }
268
+ ), file.size ? /* @__PURE__ */ React__default.createElement("div", { className: "file-info" }, /* @__PURE__ */ React__default.createElement(
269
+ Byte,
270
+ {
271
+ rawValue: file.size,
272
+ valueClassName: "file-size",
273
+ unitClassName: "file-size-unit"
274
+ }
275
+ )) : /* @__PURE__ */ React__default.createElement(React__default.Fragment, null), file.fileStatus === "error" && !!file.error && /* @__PURE__ */ React__default.createElement("div", { className: cx("upload-file-error", Typo.Footnote.f2_regular) }, file.error)),
276
+ /* @__PURE__ */ React__default.createElement(
277
+ Icon,
278
+ {
279
+ src: XmarkRemove16SecondaryIcon,
280
+ onClick: disabled ? void 0 : handleRemove
281
+ }
282
+ )
283
+ );
284
+ };
285
+ const FileListItem = ({ file, removeFile, onRemove }) => {
286
+ const fileStatus = file.fileStatus || "success";
287
+ const { t } = useParrotTranslation();
288
+ const handleRemove = (e) => {
289
+ e.stopPropagation();
290
+ removeFile(file.uid);
291
+ onRemove == null ? void 0 : onRemove(file);
292
+ };
293
+ return /* @__PURE__ */ React__default.createElement(
294
+ "div",
295
+ {
296
+ className: cx("upload-file-item", Typo.Label.l4_regular),
297
+ key: file.uid
298
+ },
299
+ /* @__PURE__ */ React__default.createElement("div", { className: "upload-file-info" }, /* @__PURE__ */ React__default.createElement("div", { className: "file-info" }, /* @__PURE__ */ React__default.createElement(
300
+ Icon,
301
+ {
302
+ src: STATUS_ICON_MAP[fileStatus],
303
+ isRotate: fileStatus === "validating" || fileStatus === "need-validate"
304
+ }
305
+ ), /* @__PURE__ */ React__default.createElement(
306
+ "div",
307
+ {
308
+ className: fileStatus === "validating" || fileStatus === "need-validate" ? "validating" : ""
309
+ },
310
+ file.name || file.fileName
311
+ )), /* @__PURE__ */ React__default.createElement(Tooltip, { title: t("common.remove") }, /* @__PURE__ */ React__default.createElement(
312
+ Icon,
313
+ {
314
+ className: "remove-button",
315
+ src: XmarkRemove24SecondaryIcon,
316
+ onClick: handleRemove
317
+ }
318
+ ))),
319
+ file.fileStatus === "error" && !!file.error && /* @__PURE__ */ React__default.createElement("div", { className: cx("upload-file-error", Typo.Footnote.f2_regular) }, file.error)
320
+ );
321
+ };
322
+ const UploadFileList = ({
323
+ className,
324
+ fileList,
325
+ removeFile,
326
+ type = "list",
327
+ disableRemove = false,
328
+ onRemove
329
+ }) => {
330
+ if (!fileList.length) {
331
+ return null;
332
+ }
333
+ return /* @__PURE__ */ React__default.createElement(
334
+ "div",
335
+ {
336
+ className: cs(
337
+ "upload-file-list",
338
+ type === "list" ? "" : "upload-file-info-list",
339
+ className
340
+ )
341
+ },
342
+ fileList.map(
343
+ (file) => type === "list" ? /* @__PURE__ */ React__default.createElement(
344
+ FileListItem,
345
+ {
346
+ key: file.uid,
347
+ file,
348
+ removeFile,
349
+ onRemove
350
+ }
351
+ ) : /* @__PURE__ */ React__default.createElement(
352
+ UploadFileInfo,
353
+ {
354
+ key: file.uid,
355
+ file,
356
+ removeFile,
357
+ disabled: disableRemove,
358
+ onRemove
359
+ }
360
+ )
361
+ )
362
+ );
363
+ };
364
+
365
+ export { FileListItem, UploadButton, UploadDescription, UploadDragger, UploadFileInfo, UploadFileList, UploadLabel };
package/dist/esm/index.js CHANGED
@@ -97,6 +97,7 @@ export { ImmersiveDialog } from './core/ImmersiveDialog/index.js';
97
97
  export { LineChartColorBlock, default as LineChartLegend } from './core/LineChart/LineChartLegend.js';
98
98
  export { ILineChartGraphType, ILineChartMetricUnit, ILineChartTimeUnit } from './core/LineChart/type.js';
99
99
  export { UNIT_FORMATTER, addMissingDataWithZero, convertLineChartDataStruct, convertLineChartUnit, deletePointsOutOfRange, filterLineChartDataOverlapping, filterLineChartOverlappingMetric, filterLineChartPointsByDateRange, getFirstExpectedTimestamp, getLineChartRangeTimestamp, getLineChartStep, getLineChartXAxisDomain, getLineChartYDataMax, getYAxisDomain, getYAxisUpperBound, lineChartTickFormatter, lineChartXaxisCal, lineChartYaxisTickFormatter, parseLineChartRange } from './core/LineChart/utils.js';
100
+ export { LocalUpload } from './core/LocalUpload/LocalUpload.js';
100
101
  export { MediumDialog } from './core/MediumDialog/MediumDialog.js';
101
102
  export { Batcher, createBatchMessageMethods, makeUUID } from './core/message-group/index.js';
102
103
  export { default as MetricActions } from './core/Metric/MetricActions.js';