@daoyi/nmtl-ui 2.0.1-beta.45 → 2.0.1-beta.47

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 (72) hide show
  1. package/lib/components/Autocomplete-5439ff22.js +333 -1
  2. package/lib/components/Autocomplete.js +12 -1
  3. package/lib/components/Avatar.js +51 -1
  4. package/lib/components/BackTop.js +82 -1
  5. package/lib/components/BarChart.js +132 -1
  6. package/lib/components/Breadcrumbs.js +124 -1
  7. package/lib/components/Button-63c7e9f3.js +91 -1
  8. package/lib/components/Button.js +8 -1
  9. package/lib/components/Carousel.js +61 -1
  10. package/lib/components/Checkbox.js +37 -1
  11. package/lib/components/CollapseContent.js +181 -1
  12. package/lib/components/ContactModal-a59bc808.js +924 -0
  13. package/lib/components/ContactModal.js +17 -1
  14. package/lib/components/Drawer-af3ed21a.js +157 -1
  15. package/lib/components/Drawer.js +13 -1
  16. package/lib/components/Dropdown.js +135 -1
  17. package/lib/components/Empty-70f040a9.js +44 -1
  18. package/lib/components/Empty.js +7 -1
  19. package/lib/components/ExportButton.js +114 -1
  20. package/lib/components/ExtraTools-f10a66a8.js +818 -1
  21. package/lib/components/ExtraTools.js +11 -1
  22. package/lib/components/Filter.js +90 -1
  23. package/lib/components/Footer.js +266 -1
  24. package/lib/components/ForwardLink.js +106 -1
  25. package/lib/components/Header.js +186 -1
  26. package/lib/components/Image.js +58 -1
  27. package/lib/components/Input.js +79 -1
  28. package/lib/components/InputMethod.js +23106 -1
  29. package/lib/components/KeywordSearch-224f84c1.js +138 -1
  30. package/lib/components/KeywordSearch.js +14 -1
  31. package/lib/components/KeywordTicker.js +182 -1
  32. package/lib/components/Keywords.js +292 -1
  33. package/lib/components/Loading.js +30 -1
  34. package/lib/components/MUITheme.js +255 -1
  35. package/lib/components/Modal-a7591b98.js +107 -1
  36. package/lib/components/Modal.js +11 -1
  37. package/lib/components/MoreButton-f15ca38e.js +109 -1
  38. package/lib/components/MoreButton.js +8 -1
  39. package/lib/components/Radio.js +81 -1
  40. package/lib/components/SNA.js +324 -1
  41. package/lib/components/Select-98a8e973.js +114 -1
  42. package/lib/components/Select.js +10 -1
  43. package/lib/components/Spin-690a3597.js +74 -1
  44. package/lib/components/Spin.js +8 -1
  45. package/lib/components/Table.js +51 -1
  46. package/lib/components/Tooltip-b7eb966d.js +69 -1
  47. package/lib/components/Tooltip.js +9 -1
  48. package/lib/components/_rollupPluginBabelHelpers-fde6d1c6.js +491 -1
  49. package/lib/components/dataExport-f418e6fe.js +56 -1
  50. package/lib/components/globalConfig.js +186 -1
  51. package/lib/components/vendor-851c6356.js +41893 -16
  52. package/lib/index.d.ts +1 -3
  53. package/lib/index.js +1 -3
  54. package/lib/utils/_rollupPluginBabelHelpers-a6e0e6e3.js +139 -1
  55. package/lib/utils/arrayMerge.js +100 -1
  56. package/lib/utils/chunkArray.js +15 -1
  57. package/lib/utils/convert2HtmlEntities.js +42 -1
  58. package/lib/utils/domToImage.js +32 -1
  59. package/lib/utils/downloadGephi.js +106 -1
  60. package/lib/utils/exportXlsx.js +184 -1
  61. package/lib/utils/historyAppendSearch.js +23 -1
  62. package/lib/utils/isDevelopMode.js +5 -1
  63. package/lib/utils/parseYMD.js +36 -1
  64. package/lib/utils/removeDuplicateItem.js +11 -1
  65. package/lib/utils/sendEmail.js +39 -1
  66. package/lib/utils/snaDefine-6a2bcd94.js +5 -1
  67. package/lib/utils/snaDefine.js +1 -1
  68. package/lib/utils/snaPreProcess.js +84 -1
  69. package/lib/utils/vendor-3ec75cc9.js +1289 -1
  70. package/package.json +1 -1
  71. package/lib/components/ContactModal-d7e2f8bb.js +0 -1
  72. package/lib/components/globalConfig-40069b54.js +0 -1
@@ -0,0 +1,924 @@
1
+ import { _ as _extends, a as _slicedToArray, b as _objectSpread2, e as _defineProperty, f as _asyncToGenerator, g as _regeneratorRuntime } from './_rollupPluginBabelHelpers-fde6d1c6.js';
2
+ import React__default, { useState, useEffect, useMemo } from 'react';
3
+ import PropTypes from 'prop-types';
4
+ import { G as moment, J as JSZip, s as styleInject, H as GoogleLogin, I as FacebookLogin, K as default_1, L as default_1$1, M as Field, c as classNames, N as ErrorMessage, O as useFormik, P as FormikProvider } from './vendor-851c6356.js';
5
+ import axios from 'axios';
6
+ import { M as Modal } from './Modal-a7591b98.js';
7
+ import { Input, Button, IconButton, Box, Typography, FormControl, RadioGroup, FormControlLabel, Radio, TextField, TextareaAutosize } from '@material-ui/core';
8
+ import { S as Select } from './Select-98a8e973.js';
9
+ import { getIntl } from './globalConfig';
10
+
11
+ // const sendMail = {
12
+ // from: "orient.cc.noreply@gmail.com",
13
+ // to: email,
14
+ // subject: `ATC_${card_id}`+" card status has been changed (Orient-CC)",
15
+ // text: context,
16
+ // };
17
+ //
18
+ // apiUrl: "https://api.daoyidh.com/mail"
19
+ const sendEmail = function (sendMail, apiUrl, onSuccess) {
20
+ let timeout = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 5000;
21
+ // timeout
22
+ axios.defaults.timeout = timeout;
23
+ try {
24
+ // axios api
25
+ return axios.post(apiUrl, {
26
+ sendMail
27
+ }).then(res => onSuccess({
28
+ state: res && res.status === 200
29
+ })).catch(err => {
30
+ console.error('api:axios:catch:error: ', err.message);
31
+ return {
32
+ state: false,
33
+ error: err.message
34
+ };
35
+ });
36
+ } catch (err) {
37
+ console.error('api:axios:try:catch:error: ', err.message);
38
+ return {
39
+ state: false,
40
+ error: err.message
41
+ };
42
+ }
43
+ };
44
+
45
+ const EMAIL_TYPE = {
46
+ PROVIDER: 'DATA_PROVIDER',
47
+ PROBLEM: 'PROBLEM'
48
+ };
49
+ const contactTemplate = _ref => {
50
+ let {
51
+ formatMessage,
52
+ formType
53
+ } = _ref;
54
+ const headerColumn = [
55
+ // 主旨
56
+ {
57
+ name: 'subject',
58
+ type: 'radio',
59
+ label: formatMessage({
60
+ id: 'common.form.subject'
61
+ }),
62
+ options: [{
63
+ label: formatMessage({
64
+ id: 'common.has.problem'
65
+ }),
66
+ value: EMAIL_TYPE.PROBLEM,
67
+ desc: formatMessage({
68
+ id: 'common.has.problem.hint'
69
+ })
70
+ }, {
71
+ label: formatMessage({
72
+ id: 'common.form.dataProvide'
73
+ }),
74
+ value: EMAIL_TYPE.PROVIDER,
75
+ desc: formatMessage({
76
+ id: 'common.form.dataProvide.hint'
77
+ })
78
+ }],
79
+ required: true,
80
+ initialValue: formType
81
+ },
82
+ // 姓名
83
+ {
84
+ name: 'name',
85
+ type: 'input',
86
+ label: formatMessage({
87
+ id: 'common.form.name'
88
+ }),
89
+ required: true
90
+ },
91
+ // 電話
92
+ {
93
+ name: 'phone',
94
+ type: 'input',
95
+ label: formatMessage({
96
+ id: 'common.form.phone'
97
+ })
98
+ },
99
+ // e-mail
100
+ {
101
+ name: 'email',
102
+ type: 'email',
103
+ label: 'e-mail',
104
+ required: true
105
+ },
106
+ // 年齡
107
+ {
108
+ name: 'age',
109
+ type: 'select',
110
+ label: formatMessage({
111
+ id: 'common.form.age'
112
+ }),
113
+ options: ['0-9', '10-19', '20-29', '30-39', '40-49', '50-59', '60-69', '70-79', '80-89', '90-99']
114
+ },
115
+ // 職業
116
+ {
117
+ name: 'job',
118
+ type: 'input',
119
+ label: formatMessage({
120
+ id: 'common.form.job'
121
+ })
122
+ }];
123
+
124
+ // 資料提供
125
+ const dataProvider = [
126
+ // 資料名稱
127
+ {
128
+ name: 'dataName',
129
+ type: 'input',
130
+ label: formatMessage({
131
+ id: 'common.form.dataname'
132
+ }),
133
+ placeholder: formatMessage({
134
+ id: 'common.form.dataname.placeholder'
135
+ })
136
+ },
137
+ // 作者
138
+ {
139
+ name: 'author',
140
+ type: 'input',
141
+ label: formatMessage({
142
+ id: 'common.form.author'
143
+ })
144
+ },
145
+ // 日期
146
+ {
147
+ name: 'date',
148
+ type: 'datePicker',
149
+ label: formatMessage({
150
+ id: 'common.form.datadate'
151
+ }),
152
+ initialValue: moment().format('yyyy-MM-DD')
153
+ },
154
+ // 提供者名稱
155
+ {
156
+ name: 'offer',
157
+ type: 'input',
158
+ label: formatMessage({
159
+ id: 'common.form.providername'
160
+ }),
161
+ placeholder: formatMessage({
162
+ id: 'common.form.provider.notice'
163
+ })
164
+ }];
165
+ const footerColumn = [
166
+ // 附件上傳
167
+ {
168
+ name: 'files',
169
+ type: 'upload',
170
+ label: formatMessage({
171
+ id: 'common.form.attachment'
172
+ }),
173
+ hint: formatMessage({
174
+ id: 'common.form.attachment.hint'
175
+ })
176
+ },
177
+ // 內容
178
+ {
179
+ name: 'message',
180
+ type: 'textarea',
181
+ label: formatMessage({
182
+ id: 'common.content'
183
+ })
184
+ },
185
+ // 驗證碼
186
+ {
187
+ name: 'vcode',
188
+ type: 'vcode',
189
+ label: formatMessage({
190
+ id: 'common.form.code'
191
+ }),
192
+ initialValue: false,
193
+ required: true
194
+ }];
195
+ return headerColumn.concat(formType === EMAIL_TYPE.PROVIDER ? dataProvider : []).concat(footerColumn);
196
+ };
197
+ const zipFiles = files => new Promise((resolve, reject) => {
198
+ const zip = new JSZip();
199
+ for (let i = 0; i < files.length; i += 1) {
200
+ const file = files[i];
201
+ zip.file(file.name, file);
202
+ }
203
+ zip.generateAsync({
204
+ type: 'base64'
205
+ }).then(resolve).catch(reject);
206
+ });
207
+
208
+ // eslint-disable-next-line no-nested-ternary
209
+ const convert = v => String.fromCharCode(v > 57 && v < 84 ? v + 7 : v < 57 ? v : v + 13);
210
+ const getRandom = (max, min, num) => {
211
+ // eslint-disable-next-line no-bitwise
212
+ const asciiNum = ~~(Math.random() * (max - min + 1) + min);
213
+ if (!num) {
214
+ return asciiNum;
215
+ }
216
+ const arr = [];
217
+ for (let i = 0; i < num; i += 1) {
218
+ arr.push(getRandom(max, min));
219
+ }
220
+ return arr;
221
+ };
222
+ const canvas = () => {
223
+ const canvasImg = document.getElementById('bgi');
224
+ const ctx = canvasImg.getContext('2d');
225
+ ctx.strokeStyle = `rgb(${getRandom(100, 10, 3).toString()})`;
226
+ for (let i = 0; i < 7; i += 1) {
227
+ ctx.lineTo(getRandom(200, 0), getRandom(200, 10));
228
+ ctx.moveTo(getRandom(200, 0), getRandom(200, 0));
229
+ ctx.stroke();
230
+ }
231
+ };
232
+ const getConfig = () => ({
233
+ data: getRandom(109, 48, 4),
234
+ rotate: getRandom(75, -75, 4),
235
+ fz: getRandom(24, 30, 4),
236
+ color: [getRandom(100, 255, 3), getRandom(100, 255, 4), getRandom(100, 255, 3), getRandom(100, 255, 3)]
237
+ });
238
+
239
+ var css_248z$2 = ".vcode {\n display: block;\n align-items: center; }\n .vcode__image {\n margin-top: 10px;\n background: rgba(0, 0, 0, 0.8);\n width: 160px;\n overflow: hidden;\n height: 50px;\n text-align: center;\n position: relative; }\n .vcode__image:hover .vcode__mask {\n opacity: 0.8; }\n .vcode__image__mask {\n position: absolute;\n width: 100%;\n top: 0;\n line-height: 50px;\n background-color: rgba(0, 0, 0, 0.95);\n opacity: 0;\n z-index: 1;\n transition: opacity 0.3s ease-in-out;\n cursor: pointer; }\n .vcode__image__itemStr {\n float: left;\n margin-left: 20px; }\n\n#bgi {\n top: 0;\n left: 0;\n position: absolute;\n width: 100%;\n height: 100%; }\n";
240
+ styleInject(css_248z$2);
241
+
242
+ const VCode = _ref => {
243
+ let {
244
+ visible,
245
+ placeholder,
246
+ onChange,
247
+ formatMessage
248
+ } = _ref;
249
+ const [codeConfig, setCodeConfig] = useState(getConfig());
250
+ const {
251
+ data,
252
+ rotate,
253
+ fz,
254
+ color
255
+ } = codeConfig;
256
+ const refresh = () => {
257
+ canvas();
258
+ setCodeConfig(getConfig());
259
+ };
260
+ useEffect(() => {
261
+ refresh();
262
+ }, [visible]);
263
+ const vcodeNumber = `${convert(data[0])}${convert(data[1])}${convert(data[2])}${convert(data[3])}`;
264
+ return /*#__PURE__*/React__default.createElement("div", {
265
+ className: "vcode"
266
+ }, /*#__PURE__*/React__default.createElement(Input, {
267
+ placeholder: placeholder,
268
+ onChange: e => onChange(e.target.value === vcodeNumber)
269
+ }), /*#__PURE__*/React__default.createElement("div", {
270
+ className: "vcode__image"
271
+ }, /*#__PURE__*/React__default.createElement("canvas", {
272
+ id: "bgi",
273
+ width: "200",
274
+ height: "200"
275
+ }), data.map((v, i) => /*#__PURE__*/React__default.createElement("div", {
276
+ key: i.toString(),
277
+ className: "vcode__image__itemStr",
278
+ style: {
279
+ transform: `rotate(${rotate[i]}deg)`,
280
+ fontSize: `${fz[i]}px`,
281
+ color: `rgb(${color[i].toString()})`
282
+ }
283
+ }, convert(v))), /*#__PURE__*/React__default.createElement("div", {
284
+ className: "vcode__image__mask",
285
+ onClick: refresh
286
+ }, formatMessage({
287
+ id: 'common.click.refresh'
288
+ }))));
289
+ };
290
+ VCode.defaultProps = {
291
+ visible: false,
292
+ placeholder: undefined,
293
+ onChange: () => {},
294
+ formatMessage: () => {}
295
+ };
296
+ VCode.propTypes = {
297
+ visible: PropTypes.bool,
298
+ placeholder: PropTypes.string,
299
+ onChange: PropTypes.func,
300
+ formatMessage: PropTypes.func
301
+ };
302
+
303
+ var css_248z$1 = ".emailInput__loginSDK {\n display: flex;\n align-items: center; }\n .emailInput__loginSDK__google {\n padding: 6px 10px 4px !important;\n border: 1px solid black !important; }\n .emailInput__loginSDK__google div {\n padding: 0 !important; }\n .emailInput__loginSDK__google span {\n padding: 0 !important; }\n .emailInput__loginSDK__fb {\n padding: 9px 10px !important;\n border-radius: 3px;\n margin-left: 10px;\n background-color: #4c69ba;\n border: 1px solid black;\n color: white; }\n .emailInput__loginSDK__fb i {\n margin-right: 10px; }\n\n.emailInput__operator {\n margin-top: 10px; }\n";
304
+ styleInject(css_248z$1);
305
+
306
+ const EmailInput = _ref => {
307
+ let {
308
+ value,
309
+ placeholder,
310
+ onChange,
311
+ onNotify
312
+ } = _ref;
313
+ const [init, setInit] = useState(false); // google login 在init時會先failed
314
+ useMemo(() => () => setTimeout(() => setInit(true), 1000), []); // 故延遲一秒後再給google call(最非最佳解 可優化)
315
+
316
+ const handleGoogleLogin = response => {
317
+ if (response && response.profileObj && response.profileObj.email) {
318
+ // setEmail(response.profileObj.email);
319
+ onChange(response.profileObj.email);
320
+ } else if (init) {
321
+ onNotify({
322
+ type: 'error',
323
+ message: 'common.action.failed'
324
+ });
325
+ }
326
+ };
327
+ const handleFBLogin = response => {
328
+ if (response && response.email) {
329
+ // setEmail(response.email);
330
+ onChange(response.email);
331
+ } else {
332
+ onNotify({
333
+ type: 'error',
334
+ message: 'common.action.failed'
335
+ });
336
+ }
337
+ };
338
+ return /*#__PURE__*/React__default.createElement("div", {
339
+ className: "emailInput"
340
+ }, /*#__PURE__*/React__default.createElement("div", {
341
+ className: "emailInput__loginSDK"
342
+ }, /*#__PURE__*/React__default.createElement(GoogleLogin, {
343
+ clientId: "593080210200-cfmvk6ikbfv0thudsidgi4n63stuqrrg.apps.googleusercontent.com",
344
+ buttonText: "Google",
345
+ onSuccess: handleGoogleLogin,
346
+ onFailure: handleGoogleLogin,
347
+ className: "emailInput__loginSDK__google",
348
+ cookiePolicy: "single_host_origin"
349
+ }), /*#__PURE__*/React__default.createElement(FacebookLogin, {
350
+ appId: "1391837967649911",
351
+ autoLoad: false,
352
+ fields: "name,email,picture",
353
+ callback: handleFBLogin,
354
+ icon: "fa-facebook",
355
+ cssClass: "emailInput__loginSDK__fb",
356
+ size: "small",
357
+ textButton: "Facebook"
358
+ })), /*#__PURE__*/React__default.createElement("div", {
359
+ className: "emailInput__operator"
360
+ }, /*#__PURE__*/React__default.createElement(Input, {
361
+ value: value,
362
+ placeholder: placeholder,
363
+ onChange: e => onChange(e.target.value)
364
+ })));
365
+ };
366
+ EmailInput.defaultProps = {
367
+ value: undefined,
368
+ placeholder: undefined,
369
+ onChange: () => {},
370
+ onNotify: () => {}
371
+ };
372
+ EmailInput.propTypes = {
373
+ value: PropTypes.string,
374
+ placeholder: PropTypes.string,
375
+ onChange: PropTypes.func,
376
+ onNotify: PropTypes.func
377
+ };
378
+
379
+ const Upload = _ref => {
380
+ let {
381
+ onChange
382
+ } = _ref;
383
+ const [selectedFiles, setSelectedFiles] = useState([]);
384
+ const handleFileInput = e => {
385
+ setSelectedFiles([...selectedFiles, ...e.target.files]);
386
+ onChange([...selectedFiles, ...e.target.files]);
387
+ };
388
+ const handleRemoveFile = index => {
389
+ const newFiles = [...selectedFiles];
390
+ newFiles.splice(index, 1);
391
+ setSelectedFiles(newFiles);
392
+ onChange(newFiles);
393
+ };
394
+ return /*#__PURE__*/React__default.createElement("div", null, /*#__PURE__*/React__default.createElement(Button, {
395
+ variant: "outlined",
396
+ color: "primary"
397
+ }, /*#__PURE__*/React__default.createElement("label", {
398
+ htmlFor: "fileInput",
399
+ style: {
400
+ display: 'flex',
401
+ cursor: 'pointer'
402
+ }
403
+ }, /*#__PURE__*/React__default.createElement(default_1, null), "Upload Files", /*#__PURE__*/React__default.createElement("input", {
404
+ id: "fileInput",
405
+ type: "file",
406
+ multiple: true,
407
+ onChange: handleFileInput,
408
+ style: {
409
+ display: 'none'
410
+ }
411
+ }))), selectedFiles.length > 0 && /*#__PURE__*/React__default.createElement("div", null, selectedFiles.map((file, index) => /*#__PURE__*/React__default.createElement("div", {
412
+ key: index.toString()
413
+ }, /*#__PURE__*/React__default.createElement("span", null, file.name), /*#__PURE__*/React__default.createElement(IconButton, {
414
+ "aria-label": "delete",
415
+ onClick: () => handleRemoveFile(index)
416
+ }, /*#__PURE__*/React__default.createElement(default_1$1, null))))));
417
+ };
418
+ Upload.propTypes = {
419
+ onChange: PropTypes.func.isRequired
420
+ };
421
+
422
+ var css_248z = ".formItem {\n width: 100%;\n margin-bottom: 16px; }\n .formItem:last-child {\n margin-bottom: initial; }\n .formItem__title {\n display: flex;\n font-size: 16px;\n font-weight: bold; }\n .formItem__title__star {\n margin-left: 3px;\n color: #d93333; }\n .formItem__operator {\n margin: 2px 0;\n font-size: 14px; }\n .formItem__operator__radio__desc {\n margin-left: 35px !important; }\n .formItem__operator--unsupport {\n border: 1px solid #d93333;\n background: pink;\n color: black;\n padding: 5px 10px; }\n .formItem__error {\n color: #d93333;\n font-weight: bold; }\n .formItem textarea {\n border: 1px solid #d9d9d9;\n border-radius: 3px;\n width: 100%;\n background: transparent;\n padding: 6px 10px; }\n .formItem ::-webkit-calendar-picker-indicator {\n filter: invert(1); }\n";
423
+ styleInject(css_248z);
424
+
425
+ const FormItem = _ref => {
426
+ let {
427
+ name,
428
+ type,
429
+ options,
430
+ label,
431
+ hint,
432
+ placeholder,
433
+ required,
434
+ setFieldValue,
435
+ formatMessage,
436
+ onNotify
437
+ } = _ref;
438
+ const currentPlaceholder = placeholder || `${formatMessage({
439
+ id: 'common.enter'
440
+ })} ${label}`;
441
+ const render = field => {
442
+ let component;
443
+ switch (type) {
444
+ case 'input':
445
+ component = /*#__PURE__*/React__default.createElement(Input, _extends({}, field, {
446
+ placeholder: currentPlaceholder
447
+ }));
448
+ break;
449
+ case 'textarea':
450
+ component = /*#__PURE__*/React__default.createElement(TextareaAutosize, _extends({}, field, {
451
+ minRows: 3,
452
+ placeholder: currentPlaceholder
453
+ }));
454
+ break;
455
+ case 'select':
456
+ component = /*#__PURE__*/React__default.createElement(Select, _extends({}, field, {
457
+ options: options,
458
+ placeholder: currentPlaceholder
459
+ }));
460
+ break;
461
+ case 'datePicker':
462
+ component = /*#__PURE__*/React__default.createElement(TextField, _extends({}, field, {
463
+ type: "date",
464
+ onChange: event => setFieldValue(field.name, event.target.value)
465
+ }));
466
+ break;
467
+ case 'email':
468
+ component = /*#__PURE__*/React__default.createElement(EmailInput, _extends({}, field, {
469
+ placeholder: currentPlaceholder,
470
+ onChange: email => setFieldValue(field.name, email),
471
+ onNotify: onNotify
472
+ }));
473
+ break;
474
+ case 'radio':
475
+ component = /*#__PURE__*/React__default.createElement(FormControl, {
476
+ component: "fieldset"
477
+ }, /*#__PURE__*/React__default.createElement(RadioGroup, field, options.map(option => /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(FormControlLabel, {
478
+ key: option.value,
479
+ value: option.value,
480
+ control: /*#__PURE__*/React__default.createElement(Radio, null),
481
+ label: option.label
482
+ }), option && option.desc && /*#__PURE__*/React__default.createElement(Typography, {
483
+ variant: "caption",
484
+ className: "formItem__operator__radio__desc"
485
+ }, option.desc)))));
486
+ break;
487
+ case 'upload':
488
+ component = /*#__PURE__*/React__default.createElement(Upload, _extends({}, field, {
489
+ onChange: files => setFieldValue(field.name, files)
490
+ }));
491
+ break;
492
+ case 'vcode':
493
+ component = /*#__PURE__*/React__default.createElement(VCode, {
494
+ placeholder: currentPlaceholder,
495
+ onChange: pass => setFieldValue(field.name, pass),
496
+ formatMessage: formatMessage
497
+ });
498
+ break;
499
+ default:
500
+ component = null;
501
+ }
502
+ return component;
503
+ };
504
+ return /*#__PURE__*/React__default.createElement(Field, {
505
+ name: name,
506
+ render: _ref2 => {
507
+ let {
508
+ field
509
+ } = _ref2;
510
+ const component = render(field);
511
+ return /*#__PURE__*/React__default.createElement("div", {
512
+ id: `form-${name}`,
513
+ className: "formItem"
514
+ }, label && /*#__PURE__*/React__default.createElement("div", {
515
+ className: "formItem__title"
516
+ }, label, required && /*#__PURE__*/React__default.createElement("div", {
517
+ className: "formItem__title__star"
518
+ }, "*")), hint && /*#__PURE__*/React__default.createElement(Box, {
519
+ my: 1
520
+ }, /*#__PURE__*/React__default.createElement(Typography, {
521
+ variant: "body2"
522
+ }, hint)), /*#__PURE__*/React__default.createElement("div", {
523
+ className: classNames('formItem__operator', {
524
+ 'formItem__operator--unsupport': !component
525
+ })
526
+ }, component || 'Check component type is support on FormItem'), /*#__PURE__*/React__default.createElement(ErrorMessage, {
527
+ className: "formItem__error",
528
+ name: name,
529
+ component: "div"
530
+ }));
531
+ }
532
+ });
533
+ };
534
+ FormItem.defaultProps = {
535
+ label: undefined,
536
+ placeholder: undefined,
537
+ hint: undefined,
538
+ options: [],
539
+ required: false,
540
+ setFieldValue: () => {},
541
+ formatMessage: () => {},
542
+ onNotify: () => {}
543
+ };
544
+ FormItem.propTypes = {
545
+ name: PropTypes.string.isRequired,
546
+ type: PropTypes.string.isRequired,
547
+ label: PropTypes.string,
548
+ hint: PropTypes.string,
549
+ options: PropTypes.arrayOf(PropTypes.any),
550
+ placeholder: PropTypes.string,
551
+ required: PropTypes.bool,
552
+ setFieldValue: PropTypes.func,
553
+ formatMessage: PropTypes.func,
554
+ onNotify: PropTypes.func
555
+ };
556
+
557
+ /* 資料提供 - 郵件內容 */
558
+ const dataProvideMail = _ref => {
559
+ let {
560
+ formatMessage,
561
+ values
562
+ } = _ref;
563
+ const body = [];
564
+ Object.keys(values).forEach(key => {
565
+ switch (key) {
566
+ case 'subject':
567
+ {
568
+ const title = formatMessage({
569
+ id: 'common.form.dataProvide'
570
+ });
571
+ if (values[key]) body.push(`${title}-${formatMessage({
572
+ id: 'header.title'
573
+ })}`);
574
+ break;
575
+ }
576
+ case 'name':
577
+ if (values[key]) body.push(`${formatMessage({
578
+ id: 'common.form.name'
579
+ })}:${values[key]}`);
580
+ break;
581
+ case 'email':
582
+ if (values[key]) body.push(`e-mail:${values[key]}`);
583
+ break;
584
+ case 'phone':
585
+ if (values[key]) body.push(`${formatMessage({
586
+ id: 'common.form.phone'
587
+ })}:${values[key]}`);
588
+ break;
589
+ case 'age':
590
+ if (values[key]) body.push(`${formatMessage({
591
+ id: 'common.form.age'
592
+ })}:${values[key]}`);
593
+ break;
594
+ case 'job':
595
+ if (values[key]) body.push(`${formatMessage({
596
+ id: 'common.form.job'
597
+ })}:${values[key]}`);
598
+ break;
599
+ case 'dataName':
600
+ if (values[key]) body.push(`${formatMessage({
601
+ id: 'common.form.dataname'
602
+ })}:${values[key]}`);
603
+ break;
604
+ case 'author':
605
+ if (values[key]) body.push(`${formatMessage({
606
+ id: 'common.form.author'
607
+ })}:${values[key]}`);
608
+ break;
609
+ case 'date':
610
+ if (values[key]) body.push(`${formatMessage({
611
+ id: 'common.form.datadate'
612
+ })}:${values[key]}`);
613
+ break;
614
+ case 'offer':
615
+ if (values[key]) body.push(`${formatMessage({
616
+ id: 'common.form.providername'
617
+ })}:${values[key]}`);
618
+ break;
619
+ case 'message':
620
+ if (values[key]) body.push(`${formatMessage({
621
+ id: 'common.content'
622
+ })}:${values[key]}`);
623
+ break;
624
+ }
625
+ });
626
+ return body.join('<br />');
627
+ };
628
+
629
+ /* 我有問題 - 郵件內容 */
630
+ const problemMail = _ref2 => {
631
+ let {
632
+ formatMessage,
633
+ values
634
+ } = _ref2;
635
+ const body = [];
636
+ Object.keys(values).forEach(key => {
637
+ switch (key) {
638
+ case 'subject':
639
+ {
640
+ const title = formatMessage({
641
+ id: 'common.has.problem'
642
+ });
643
+ if (values[key]) body.push(`${title}-${formatMessage({
644
+ id: 'header.title'
645
+ })}`);
646
+ break;
647
+ }
648
+ case 'name':
649
+ if (values[key]) body.push(`${formatMessage({
650
+ id: 'common.form.name'
651
+ })}:${values[key]}`);
652
+ break;
653
+ case 'email':
654
+ if (values[key]) body.push(`e-mail:${values[key]}`);
655
+ break;
656
+ case 'phone':
657
+ if (values[key]) body.push(`${formatMessage({
658
+ id: 'common.form.phone'
659
+ })}:${values[key]}`);
660
+ break;
661
+ case 'age':
662
+ if (values[key]) body.push(`${formatMessage({
663
+ id: 'common.form.age'
664
+ })}:${values[key]}`);
665
+ break;
666
+ case 'job':
667
+ if (values[key]) body.push(`${formatMessage({
668
+ id: 'common.form.job'
669
+ })}:${values[key]}`);
670
+ break;
671
+ case 'message':
672
+ if (values[key]) body.push(`${formatMessage({
673
+ id: 'common.content'
674
+ })}:${values[key]}`);
675
+ break;
676
+ }
677
+ });
678
+ return body.join('<br />');
679
+ };
680
+
681
+ var errorId;
682
+ var ContactModal = function ContactModal(_ref) {
683
+ var type = _ref.type,
684
+ mailto = _ref.mailto,
685
+ open = _ref.open,
686
+ emailAPI = _ref.emailAPI,
687
+ setOpen = _ref.setOpen,
688
+ onNotify = _ref.onNotify;
689
+ var _getIntl = getIntl(),
690
+ formatMessage = _getIntl.formatMessage;
691
+ var _useState = useState(false),
692
+ _useState2 = _slicedToArray(_useState, 2),
693
+ submitting = _useState2[0],
694
+ setSubmitting = _useState2[1];
695
+ var _useState3 = useState(type),
696
+ _useState4 = _slicedToArray(_useState3, 2),
697
+ formType = _useState4[0],
698
+ setFormType = _useState4[1];
699
+
700
+ /* 建立表單設定檔 */
701
+ var template = contactTemplate({
702
+ formatMessage: formatMessage,
703
+ formType: formType
704
+ });
705
+
706
+ /* 表單控制元件 */
707
+ var formik = useFormik({
708
+ initialValues: template.reduce(function (obj, item) {
709
+ return _objectSpread2(_objectSpread2({}, obj), {}, _defineProperty({}, item.name, item.initialValue || ''));
710
+ }, {}),
711
+ validate: function validate(values) {
712
+ var errors = {};
713
+ /* 取出必填的欄位 並檢查該欄位是否有填寫 若無則顯示錯誤訊息(請輸入xxx) */
714
+ var necessaryList = template.filter(function (_ref2) {
715
+ var required = _ref2.required;
716
+ return required;
717
+ });
718
+ necessaryList.forEach(function (_ref3) {
719
+ var name = _ref3.name,
720
+ label = _ref3.label;
721
+ if (!values[name]) errors[name] = "".concat(formatMessage({
722
+ id: 'common.enter'
723
+ }), " ").concat(label);
724
+ });
725
+
726
+ /* 檢查是否符合 email格式 - 您輸入無效的email */
727
+ if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
728
+ errors.email = formatMessage({
729
+ id: 'common.form.valid.error.email'
730
+ });
731
+ }
732
+ /* 檢查是否正確 - 驗證碼錯誤 */
733
+ if (!values.vcode) errors.vcode = formatMessage({
734
+ id: 'common.form.code.error'
735
+ });
736
+ setFormType(values.subject);
737
+
738
+ /* 如果附件Size超過10MB - 檔案大小上限為10MB! */
739
+ if (Array.isArray(values.files)) {
740
+ var totalsize = values.files.reduce(function (total, file) {
741
+ return total + file.size;
742
+ }, 0);
743
+ if (totalsize > 10 * 1024 * 1024) errors.files = formatMessage({
744
+ id: 'common.form.attachment.valid.error'
745
+ });
746
+ }
747
+
748
+ /* 取得第一個錯誤的id */
749
+ errorId = Object.keys(errors).length > 0 ? Object.keys(errors).shift() : null;
750
+ return errors;
751
+ },
752
+ onSubmit: function () {
753
+ var _onSubmit = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(values) {
754
+ var title, subject, body, zipFile;
755
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
756
+ while (1) switch (_context.prev = _context.next) {
757
+ case 0:
758
+ title = values.subject === EMAIL_TYPE.PROBLEM ? formatMessage({
759
+ id: 'common.has.problem'
760
+ }) : formatMessage({
761
+ id: 'common.form.dataProvide'
762
+ });
763
+ subject = "".concat(title, "-").concat(formatMessage({
764
+ id: 'header.title'
765
+ }), "-").concat(values.name);
766
+ body = formType === EMAIL_TYPE.PROBLEM ? problemMail({
767
+ formatMessage: formatMessage,
768
+ values: values
769
+ }) : dataProvideMail({
770
+ formatMessage: formatMessage,
771
+ values: values
772
+ });
773
+ setSubmitting(true);
774
+
775
+ // const fileName = values.files && values.files[0] && values.files[0].name;
776
+ if (!(values.files && values.files.length > 0)) {
777
+ _context.next = 11;
778
+ break;
779
+ }
780
+ _context.next = 7;
781
+ return zipFiles(values.files);
782
+ case 7:
783
+ zipFile = _context.sent;
784
+ sendEmail({
785
+ from: values.email,
786
+ to: mailto,
787
+ subject: subject,
788
+ html: body,
789
+ attachments: [{
790
+ // stream as an attachment
791
+ filename: 'zipFile.zip',
792
+ content: zipFile
793
+ }]
794
+ }, emailAPI, function (_ref4) {
795
+ var state = _ref4.state;
796
+ if (state) {
797
+ setSubmitting(false);
798
+ formik.resetForm();
799
+ setOpen(false);
800
+ onNotify({
801
+ message: 'common.action.success'
802
+ });
803
+ } else {
804
+ onNotify({
805
+ type: 'error',
806
+ message: 'common.action.error'
807
+ });
808
+ }
809
+ });
810
+ _context.next = 12;
811
+ break;
812
+ case 11:
813
+ sendEmail({
814
+ from: values.email,
815
+ to: mailto,
816
+ subject: subject,
817
+ html: body
818
+ }, emailAPI, function (_ref5) {
819
+ var state = _ref5.state;
820
+ if (state) {
821
+ setSubmitting(false);
822
+ formik.resetForm();
823
+ setOpen(false);
824
+ onNotify({
825
+ message: 'common.action.success'
826
+ });
827
+ } else {
828
+ onNotify({
829
+ type: 'error',
830
+ message: 'common.action.error'
831
+ });
832
+ }
833
+ });
834
+ case 12:
835
+ case "end":
836
+ return _context.stop();
837
+ }
838
+ }, _callee);
839
+ }));
840
+ function onSubmit(_x) {
841
+ return _onSubmit.apply(this, arguments);
842
+ }
843
+ return onSubmit;
844
+ }()
845
+ });
846
+
847
+ /* 關閉表單 */
848
+ var handleClose = function handleClose() {
849
+ formik.resetForm();
850
+ setOpen(false);
851
+ };
852
+
853
+ /* 送出郵件 */
854
+ var handleSubmit = function handleSubmit() {
855
+ formik.handleSubmit();
856
+ /* 滾動過去錯誤的地方 */
857
+ var errorElement = document.getElementById("form-".concat(errorId));
858
+ if (errorElement) {
859
+ var offsetY = errorElement.offsetTop - 65;
860
+ if (errorElement.parentElement.scrollTo) {
861
+ errorElement.parentElement.scrollTo({
862
+ top: offsetY,
863
+ behavior: 'smooth'
864
+ });
865
+ } else {
866
+ errorElement.parentElement.scrollTop = offsetY;
867
+ }
868
+ }
869
+ if (errorId) onNotify({
870
+ type: 'error',
871
+ message: 'common.form.error'
872
+ });
873
+ };
874
+ return /*#__PURE__*/React__default.createElement(Modal, {
875
+ fullWidth: true,
876
+ visible: open,
877
+ loading: submitting,
878
+ title: formatMessage({
879
+ id: 'common.form.contactUs'
880
+ }),
881
+ onCancel: handleClose,
882
+ onOk: handleSubmit,
883
+ cancelText: formatMessage({
884
+ id: 'common.cancel'
885
+ }),
886
+ okText: formatMessage({
887
+ id: 'common.submit'
888
+ })
889
+ }, /*#__PURE__*/React__default.createElement(FormikProvider, {
890
+ value: formik
891
+ }, template.map(function (schema) {
892
+ return /*#__PURE__*/React__default.createElement(FormItem, _extends({
893
+ key: schema.name
894
+ }, schema, {
895
+ setFieldValue: formik.setFieldValue,
896
+ formatMessage: formatMessage,
897
+ onNotify: onNotify
898
+ }));
899
+ })));
900
+ };
901
+ ContactModal.defaultProps = {
902
+ type: EMAIL_TYPE.PROBLEM,
903
+ mailto: 'twp@nmtl.gov.tw',
904
+ open: false,
905
+ emailAPI: 'https://api2.daoyidh.com/nmtl/mail',
906
+ setOpen: function setOpen() {},
907
+ onNotify: function onNotify() {}
908
+ };
909
+ ContactModal.propTypes = {
910
+ /** 我有問題的種類為(DATA_PROVIDER or PROBLEM) */
911
+ type: PropTypes.oneOf(['DATA_PROVIDER', 'PROBLEM']),
912
+ /** 傳送的email位置 */
913
+ mailto: PropTypes.string,
914
+ /** Modal是否開啟 */
915
+ open: PropTypes.bool,
916
+ /** 寄信用的api url */
917
+ emailAPI: PropTypes.string,
918
+ /** 設定Modal是否開啟 */
919
+ setOpen: PropTypes.func,
920
+ /** 錯誤或成功時的提示 */
921
+ onNotify: PropTypes.func
922
+ };
923
+
924
+ export { ContactModal as C };