@antscorp/antsomi-ui 2.0.121 → 2.0.122
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.
- package/CHANGELOG.md +92 -92
- package/es/components/organism/TicketEditor/Content.js +74 -35
- package/es/components/organism/TicketEditor/util.d.ts +1 -0
- package/es/components/organism/TicketEditor/util.js +1 -0
- package/es/components/organism/TicketEditorV2/Content.js +62 -28
- package/es/components/organism/TicketEditorV2/util.d.ts +1 -0
- package/es/components/organism/TicketEditorV2/util.js +1 -0
- package/es/utils/uploadEmbeddedImages.d.ts +7 -0
- package/es/utils/uploadEmbeddedImages.js +65 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,92 +1,92 @@
|
|
|
1
|
-
### Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
|
4
|
-
|
|
5
|
-
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
|
-
|
|
7
|
-
#### [v2.0.
|
|
8
|
-
|
|
9
|
-
- feat: update version antsomi-locales [`7d44aae`](https://bitbucket.org/git-vn/at.packages.frontend/commits/7d44aae3055b3b1bbfb772e2ed3afd5fa920fd05)
|
|
10
|
-
-
|
|
11
|
-
- feat:
|
|
12
|
-
|
|
13
|
-
#### [v2.0.64-staging.60](https://bitbucket.org/git-vn/at.packages.frontend/compare/v2.0.64-staging.60..v2.0.64-staging.58)
|
|
14
|
-
|
|
15
|
-
> 20 March 2026
|
|
16
|
-
|
|
17
|
-
- feat: update message activity timeline [`7a3bc15`](https://bitbucket.org/git-vn/at.packages.frontend/commits/7a3bc15dd2e2eb7caf91e6bf064edd48e97dcdb2)
|
|
18
|
-
- feat: add fallback scheme_code [`ecb8e67`](https://bitbucket.org/git-vn/at.packages.frontend/commits/ecb8e67a56b93610df913c2f7c37d89b8be98ad6)
|
|
19
|
-
- feat: update extra keys [`da5b04e`](https://bitbucket.org/git-vn/at.packages.frontend/commits/da5b04e9e1c6b5d0c3584c4e08ffe70733ad4e77)
|
|
20
|
-
|
|
21
|
-
#### [v2.0.64-staging.58](https://bitbucket.org/git-vn/at.packages.frontend/compare/v2.0.64-staging.58..v2.0.64-staging.54)
|
|
22
|
-
|
|
23
|
-
> 17 March 2026
|
|
24
|
-
|
|
25
|
-
- feat: add event tg [`3d5672b`](https://bitbucket.org/git-vn/at.packages.frontend/commits/3d5672bf798efc459cec8c2866692ecc48be1141)
|
|
26
|
-
- feat: update message activity timeline leads [`3b1590e`](https://bitbucket.org/git-vn/at.packages.frontend/commits/3b1590ee8c5aa8a1d671082f6fd72d9d85b6414b)
|
|
27
|
-
- feat: update message activity timeline leads [`8b4d22c`](https://bitbucket.org/git-vn/at.packages.frontend/commits/8b4d22cf8d1ad4a4cc0e7c36dcd8306ae9e2f7d7)
|
|
28
|
-
|
|
29
|
-
#### [v2.0.64-staging.54](https://bitbucket.org/git-vn/at.packages.frontend/compare/v2.0.64-staging.54..v2.0.22)
|
|
30
|
-
|
|
31
|
-
> 30 January 2026
|
|
32
|
-
|
|
33
|
-
- fix: build search logic [`#27`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/27)
|
|
34
|
-
- feat: add report area chart [`4a0fad4`](https://bitbucket.org/git-vn/at.packages.frontend/commits/4a0fad4b405425ef03b9cf6038f6e9389f44a366)
|
|
35
|
-
- chore: update storybook version [`d13f194`](https://bitbucket.org/git-vn/at.packages.frontend/commits/d13f19462c2fe117934df7fe2e09fd0aa95a0167)
|
|
36
|
-
- feat: init antsomi-genai [`d898d07`](https://bitbucket.org/git-vn/at.packages.frontend/commits/d898d07f09cf6436ff9ba2a5430e08fc44190781)
|
|
37
|
-
|
|
38
|
-
### [v2.0.22](https://bitbucket.org/git-vn/at.packages.frontend/compare/v2.0.22..v1.0.10)
|
|
39
|
-
|
|
40
|
-
> 19 January 2023
|
|
41
|
-
|
|
42
|
-
#### [v1.0.10](https://bitbucket.org/git-vn/at.packages.frontend/compare/v1.0.10..v1.0.9)
|
|
43
|
-
|
|
44
|
-
> 20 June 2024
|
|
45
|
-
|
|
46
|
-
#### [v1.0.9](https://bitbucket.org/git-vn/at.packages.frontend/compare/v1.0.9..v1.0.8)
|
|
47
|
-
|
|
48
|
-
> 20 June 2024
|
|
49
|
-
|
|
50
|
-
#### [v1.0.8](https://bitbucket.org/git-vn/at.packages.frontend/compare/v1.0.8..v1.0.3)
|
|
51
|
-
|
|
52
|
-
> 20 June 2024
|
|
53
|
-
|
|
54
|
-
- feat(SelectAccount): add component [`2f1dea0`](https://bitbucket.org/git-vn/at.packages.frontend/commits/2f1dea035af07a01a6be8da47b531d52d2977bbe)
|
|
55
|
-
- fix: update style for calendar selection [`4347b91`](https://bitbucket.org/git-vn/at.packages.frontend/commits/4347b91f5bbe31caeb64478116c1822fe443f359)
|
|
56
|
-
- feat(EditorTab): use modal async in onCloseTab [`76aece8`](https://bitbucket.org/git-vn/at.packages.frontend/commits/76aece8cc7a44385d63019058daa1f8477c8fbcb)
|
|
57
|
-
|
|
58
|
-
#### [v1.0.3](https://bitbucket.org/git-vn/at.packages.frontend/compare/v1.0.3..v1.0.2)
|
|
59
|
-
|
|
60
|
-
> 17 January 2023
|
|
61
|
-
|
|
62
|
-
- update timeline package [`e198927`](https://bitbucket.org/git-vn/at.packages.frontend/commits/e198927d83931f9155e90ab9a1d9d3a5ac2989c4)
|
|
63
|
-
- update-ticket-editor [`38dd7b0`](https://bitbucket.org/git-vn/at.packages.frontend/commits/38dd7b0a7b2b0b58a63e725419e9b057e053f44f)
|
|
64
|
-
- update-upload-file-ticket-editor [`bb2f2ef`](https://bitbucket.org/git-vn/at.packages.frontend/commits/bb2f2ef1c46f4239ad716c897e53856a6368ea7d)
|
|
65
|
-
|
|
66
|
-
#### v1.0.2
|
|
67
|
-
|
|
68
|
-
> 4 January 2023
|
|
69
|
-
|
|
70
|
-
- Sprint10/vinlt/feature/date advanced [`#24`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/24)
|
|
71
|
-
- Sprint10/sangndd/feature/extend value matches any [`#23`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/23)
|
|
72
|
-
- Sprint10/sangndd/feature/extend value matches any [`#22`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/22)
|
|
73
|
-
- [Scatter chart] Max X-axis giá trị bị lặp [`#20`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/20)
|
|
74
|
-
- Sprint8/vinlt/feature/show data label short [`#18`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/18)
|
|
75
|
-
- Fix duplicate axis max value [`#17`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/17)
|
|
76
|
-
- [Antalyser] Một số bug khi nhập axis giá trị thập phân [`#16`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/16)
|
|
77
|
-
- Sprint6/vinlt/fixbug/chart [`#15`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/15)
|
|
78
|
-
- - Axis allows input of decimal values [`#14`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/14)
|
|
79
|
-
- Sprint4/sangndd/feature/icons [`#12`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/12)
|
|
80
|
-
- Sprint4/sangndd/feature/icons [`#11`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/11)
|
|
81
|
-
- Sprint4/thanghn/fixbug/pivot alias border [`#10`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/10)
|
|
82
|
-
- fix scroll dimension and total column [`#9`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/9)
|
|
83
|
-
- [ANTALYSER][Filter][Khi filter filed có type date và semantic là "Month day" thì không load được danh sách các ngày trong tháng] [`#7`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/7)
|
|
84
|
-
- [ANTALYSER][Pivot chart][Tính năng Add border shadow chưa hoạt động] [`#8`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/8)
|
|
85
|
-
- Fix bug [ANTALYSER][Scatter chart][Label ở cột X và Y chưa đổi theo alias name đã change ở metric] [`#6`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/6)
|
|
86
|
-
- Fix bug [Pivot chart] Row color không hiển thị được khi chọn hiển thị data của metric là Bar [`#5`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/5)
|
|
87
|
-
- Fix bug package antscorp/charts [`#1`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/1)
|
|
88
|
-
- Fix bug package antscorp/chart [`#2`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/2)
|
|
89
|
-
- table component [`#1`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/1)
|
|
90
|
-
- Update map indonesia [`fc94208`](https://bitbucket.org/git-vn/at.packages.frontend/commits/fc9420838b3f4087a5763017e9bf7e72ee8c5e31)
|
|
91
|
-
- Update geomap [`43f3098`](https://bitbucket.org/git-vn/at.packages.frontend/commits/43f3098506f30a215dc2b30734590e5c55f8b490)
|
|
92
|
-
- sync package master [`7476118`](https://bitbucket.org/git-vn/at.packages.frontend/commits/7476118de2fcfa1bd6b0a9e3c0f887b29fd149b6)
|
|
1
|
+
### Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
|
4
|
+
|
|
5
|
+
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
|
+
|
|
7
|
+
#### [v2.0.122](https://bitbucket.org/git-vn/at.packages.frontend/compare/v2.0.122..v2.0.64-staging.60)
|
|
8
|
+
|
|
9
|
+
- feat: update version antsomi-locales [`7d44aae`](https://bitbucket.org/git-vn/at.packages.frontend/commits/7d44aae3055b3b1bbfb772e2ed3afd5fa920fd05)
|
|
10
|
+
- feat: scaffold antsomi ui v2 facade [`5bf7910`](https://bitbucket.org/git-vn/at.packages.frontend/commits/5bf7910250bbf5577bfb95b3f93c14f23c4f9584)
|
|
11
|
+
- feat: add antsomi light theme provider [`04e7fca`](https://bitbucket.org/git-vn/at.packages.frontend/commits/04e7fcae7ccb861d97e43392ab4966a11c7e8774)
|
|
12
|
+
|
|
13
|
+
#### [v2.0.64-staging.60](https://bitbucket.org/git-vn/at.packages.frontend/compare/v2.0.64-staging.60..v2.0.64-staging.58)
|
|
14
|
+
|
|
15
|
+
> 20 March 2026
|
|
16
|
+
|
|
17
|
+
- feat: update message activity timeline [`7a3bc15`](https://bitbucket.org/git-vn/at.packages.frontend/commits/7a3bc15dd2e2eb7caf91e6bf064edd48e97dcdb2)
|
|
18
|
+
- feat: add fallback scheme_code [`ecb8e67`](https://bitbucket.org/git-vn/at.packages.frontend/commits/ecb8e67a56b93610df913c2f7c37d89b8be98ad6)
|
|
19
|
+
- feat: update extra keys [`da5b04e`](https://bitbucket.org/git-vn/at.packages.frontend/commits/da5b04e9e1c6b5d0c3584c4e08ffe70733ad4e77)
|
|
20
|
+
|
|
21
|
+
#### [v2.0.64-staging.58](https://bitbucket.org/git-vn/at.packages.frontend/compare/v2.0.64-staging.58..v2.0.64-staging.54)
|
|
22
|
+
|
|
23
|
+
> 17 March 2026
|
|
24
|
+
|
|
25
|
+
- feat: add event tg [`3d5672b`](https://bitbucket.org/git-vn/at.packages.frontend/commits/3d5672bf798efc459cec8c2866692ecc48be1141)
|
|
26
|
+
- feat: update message activity timeline leads [`3b1590e`](https://bitbucket.org/git-vn/at.packages.frontend/commits/3b1590ee8c5aa8a1d671082f6fd72d9d85b6414b)
|
|
27
|
+
- feat: update message activity timeline leads [`8b4d22c`](https://bitbucket.org/git-vn/at.packages.frontend/commits/8b4d22cf8d1ad4a4cc0e7c36dcd8306ae9e2f7d7)
|
|
28
|
+
|
|
29
|
+
#### [v2.0.64-staging.54](https://bitbucket.org/git-vn/at.packages.frontend/compare/v2.0.64-staging.54..v2.0.22)
|
|
30
|
+
|
|
31
|
+
> 30 January 2026
|
|
32
|
+
|
|
33
|
+
- fix: build search logic [`#27`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/27)
|
|
34
|
+
- feat: add report area chart [`4a0fad4`](https://bitbucket.org/git-vn/at.packages.frontend/commits/4a0fad4b405425ef03b9cf6038f6e9389f44a366)
|
|
35
|
+
- chore: update storybook version [`d13f194`](https://bitbucket.org/git-vn/at.packages.frontend/commits/d13f19462c2fe117934df7fe2e09fd0aa95a0167)
|
|
36
|
+
- feat: init antsomi-genai [`d898d07`](https://bitbucket.org/git-vn/at.packages.frontend/commits/d898d07f09cf6436ff9ba2a5430e08fc44190781)
|
|
37
|
+
|
|
38
|
+
### [v2.0.22](https://bitbucket.org/git-vn/at.packages.frontend/compare/v2.0.22..v1.0.10)
|
|
39
|
+
|
|
40
|
+
> 19 January 2023
|
|
41
|
+
|
|
42
|
+
#### [v1.0.10](https://bitbucket.org/git-vn/at.packages.frontend/compare/v1.0.10..v1.0.9)
|
|
43
|
+
|
|
44
|
+
> 20 June 2024
|
|
45
|
+
|
|
46
|
+
#### [v1.0.9](https://bitbucket.org/git-vn/at.packages.frontend/compare/v1.0.9..v1.0.8)
|
|
47
|
+
|
|
48
|
+
> 20 June 2024
|
|
49
|
+
|
|
50
|
+
#### [v1.0.8](https://bitbucket.org/git-vn/at.packages.frontend/compare/v1.0.8..v1.0.3)
|
|
51
|
+
|
|
52
|
+
> 20 June 2024
|
|
53
|
+
|
|
54
|
+
- feat(SelectAccount): add component [`2f1dea0`](https://bitbucket.org/git-vn/at.packages.frontend/commits/2f1dea035af07a01a6be8da47b531d52d2977bbe)
|
|
55
|
+
- fix: update style for calendar selection [`4347b91`](https://bitbucket.org/git-vn/at.packages.frontend/commits/4347b91f5bbe31caeb64478116c1822fe443f359)
|
|
56
|
+
- feat(EditorTab): use modal async in onCloseTab [`76aece8`](https://bitbucket.org/git-vn/at.packages.frontend/commits/76aece8cc7a44385d63019058daa1f8477c8fbcb)
|
|
57
|
+
|
|
58
|
+
#### [v1.0.3](https://bitbucket.org/git-vn/at.packages.frontend/compare/v1.0.3..v1.0.2)
|
|
59
|
+
|
|
60
|
+
> 17 January 2023
|
|
61
|
+
|
|
62
|
+
- update timeline package [`e198927`](https://bitbucket.org/git-vn/at.packages.frontend/commits/e198927d83931f9155e90ab9a1d9d3a5ac2989c4)
|
|
63
|
+
- update-ticket-editor [`38dd7b0`](https://bitbucket.org/git-vn/at.packages.frontend/commits/38dd7b0a7b2b0b58a63e725419e9b057e053f44f)
|
|
64
|
+
- update-upload-file-ticket-editor [`bb2f2ef`](https://bitbucket.org/git-vn/at.packages.frontend/commits/bb2f2ef1c46f4239ad716c897e53856a6368ea7d)
|
|
65
|
+
|
|
66
|
+
#### v1.0.2
|
|
67
|
+
|
|
68
|
+
> 4 January 2023
|
|
69
|
+
|
|
70
|
+
- Sprint10/vinlt/feature/date advanced [`#24`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/24)
|
|
71
|
+
- Sprint10/sangndd/feature/extend value matches any [`#23`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/23)
|
|
72
|
+
- Sprint10/sangndd/feature/extend value matches any [`#22`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/22)
|
|
73
|
+
- [Scatter chart] Max X-axis giá trị bị lặp [`#20`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/20)
|
|
74
|
+
- Sprint8/vinlt/feature/show data label short [`#18`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/18)
|
|
75
|
+
- Fix duplicate axis max value [`#17`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/17)
|
|
76
|
+
- [Antalyser] Một số bug khi nhập axis giá trị thập phân [`#16`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/16)
|
|
77
|
+
- Sprint6/vinlt/fixbug/chart [`#15`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/15)
|
|
78
|
+
- - Axis allows input of decimal values [`#14`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/14)
|
|
79
|
+
- Sprint4/sangndd/feature/icons [`#12`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/12)
|
|
80
|
+
- Sprint4/sangndd/feature/icons [`#11`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/11)
|
|
81
|
+
- Sprint4/thanghn/fixbug/pivot alias border [`#10`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/10)
|
|
82
|
+
- fix scroll dimension and total column [`#9`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/9)
|
|
83
|
+
- [ANTALYSER][Filter][Khi filter filed có type date và semantic là "Month day" thì không load được danh sách các ngày trong tháng] [`#7`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/7)
|
|
84
|
+
- [ANTALYSER][Pivot chart][Tính năng Add border shadow chưa hoạt động] [`#8`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/8)
|
|
85
|
+
- Fix bug [ANTALYSER][Scatter chart][Label ở cột X và Y chưa đổi theo alias name đã change ở metric] [`#6`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/6)
|
|
86
|
+
- Fix bug [Pivot chart] Row color không hiển thị được khi chọn hiển thị data của metric là Bar [`#5`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/5)
|
|
87
|
+
- Fix bug package antscorp/charts [`#1`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/1)
|
|
88
|
+
- Fix bug package antscorp/chart [`#2`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/2)
|
|
89
|
+
- table component [`#1`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/1)
|
|
90
|
+
- Update map indonesia [`fc94208`](https://bitbucket.org/git-vn/at.packages.frontend/commits/fc9420838b3f4087a5763017e9bf7e72ee8c5e31)
|
|
91
|
+
- Update geomap [`43f3098`](https://bitbucket.org/git-vn/at.packages.frontend/commits/43f3098506f30a215dc2b30734590e5c55f8b490)
|
|
92
|
+
- sync package master [`7476118`](https://bitbucket.org/git-vn/at.packages.frontend/commits/7476118de2fcfa1bd6b0a9e3c0f887b29fd149b6)
|
|
@@ -10,7 +10,7 @@ import { Spin, Tooltip, Icon, Button, EditableName, SelectAccount, QuillEditor,
|
|
|
10
10
|
import Service from './Service';
|
|
11
11
|
import { MESSAGE_TYPE, TICKET_CUSTOM_MESSAGE_KEY } from './constant';
|
|
12
12
|
import { WrapperContent, WrapperContentInput, WrapperEditor, WrapperIconEditor, WrapperInputFile, WrapperLable, WrapperLeftContent, WrapperLinkItemFiles, WrapperMessageContent, WrapperRightContent, WrapperTextEdit, WrapperTextInput, DrawerHeader, } from './styled';
|
|
13
|
-
import { formatAccountId, formatDatarender, formatParams, handleValidateContent, postCustomEvent, } from './util';
|
|
13
|
+
import { formatAccountId, formatDatarender, formatParams, handleValidateContent, postCustomEvent, uploadEmbeddedImages, } from './util';
|
|
14
14
|
import { TCallBack } from '../../molecules/QuillEditor/QuillEditor';
|
|
15
15
|
import { isBoolean } from 'lodash';
|
|
16
16
|
const initValueInput = {
|
|
@@ -49,6 +49,7 @@ const Content = ({ portalId, token, action, ticketId, listUsers, domainTicket, d
|
|
|
49
49
|
isError: false,
|
|
50
50
|
message: '',
|
|
51
51
|
});
|
|
52
|
+
const [embeddedImageError, setEmbeddedImageError] = useState('');
|
|
52
53
|
const isUpdate = action === 'edit' && ticketId;
|
|
53
54
|
const valueInputRef = useRef(valueInput);
|
|
54
55
|
valueInputRef.current = valueInput;
|
|
@@ -94,20 +95,54 @@ const Content = ({ portalId, token, action, ticketId, listUsers, domainTicket, d
|
|
|
94
95
|
setIsLoading(false);
|
|
95
96
|
});
|
|
96
97
|
};
|
|
97
|
-
const
|
|
98
|
+
const uploadImagesBeforeSubmit = async (message) => {
|
|
99
|
+
setIsLoadingUpload(true);
|
|
100
|
+
setEmbeddedImageError('');
|
|
101
|
+
try {
|
|
102
|
+
const uploadedMessage = await uploadEmbeddedImages(message, Service.tickets.callApi.uploadImg({
|
|
103
|
+
domain: domainUpload,
|
|
104
|
+
token,
|
|
105
|
+
userId,
|
|
106
|
+
}));
|
|
107
|
+
if (uploadedMessage !== message) {
|
|
108
|
+
setTextValue(uploadedMessage);
|
|
109
|
+
updateValueInput({ message: uploadedMessage });
|
|
110
|
+
}
|
|
111
|
+
return uploadedMessage;
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
setEmbeddedImageError(error instanceof Error && error.message === 'FILE_TOO_LARGE'
|
|
115
|
+
? '*Maximum upload file size: 10MB'
|
|
116
|
+
: '*Image upload failed. Please try again.');
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
setIsLoadingUpload(false);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
const handleSubmit = async () => {
|
|
98
124
|
const { title, ownerId, message } = valueInputRef.current;
|
|
99
125
|
if (!title || !ownerId.length || !message) {
|
|
100
126
|
setIsEmptyField(true);
|
|
101
127
|
}
|
|
102
128
|
else {
|
|
103
129
|
if (!errFile.isError) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
130
|
+
try {
|
|
131
|
+
const uploadedMessage = await uploadImagesBeforeSubmit(message);
|
|
132
|
+
const params = formatParams({
|
|
133
|
+
...valueInputRef.current,
|
|
134
|
+
message: uploadedMessage,
|
|
135
|
+
});
|
|
136
|
+
const submitterEmail = listUsers?.find(user => user.userId === params.ownerId)?.email;
|
|
137
|
+
fetchCreateTicket({
|
|
138
|
+
...params,
|
|
139
|
+
submitterId: Number(userId),
|
|
140
|
+
submitterEmail,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
// The upload error is shown below the editor.
|
|
145
|
+
}
|
|
111
146
|
}
|
|
112
147
|
// handleSendData(valueInput)
|
|
113
148
|
}
|
|
@@ -231,6 +266,7 @@ const Content = ({ portalId, token, action, ticketId, listUsers, domainTicket, d
|
|
|
231
266
|
}
|
|
232
267
|
}, [isUpdate, openDrawer]);
|
|
233
268
|
const handleEditorChange = content => {
|
|
269
|
+
setEmbeddedImageError('');
|
|
234
270
|
setTextValue(content);
|
|
235
271
|
updateValueInput({ message: content });
|
|
236
272
|
// setIsLoadingUpload(content.includes('<img src="data:image/png;base64'));
|
|
@@ -244,32 +280,34 @@ const Content = ({ portalId, token, action, ticketId, listUsers, domainTicket, d
|
|
|
244
280
|
}
|
|
245
281
|
fetchUpdateFollwers(params);
|
|
246
282
|
};
|
|
247
|
-
const handleUpdateComment = () => {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
params.followers = formatAccountId(valueInput?.followers);
|
|
260
|
-
}
|
|
261
|
-
if (valueInput?.files?.length > 0) {
|
|
262
|
-
params.properties = {
|
|
263
|
-
attachments: valueInput?.files,
|
|
283
|
+
const handleUpdateComment = async () => {
|
|
284
|
+
const currentValueInput = valueInputRef.current;
|
|
285
|
+
try {
|
|
286
|
+
const uploadedMessage = await uploadImagesBeforeSubmit(currentValueInput.message);
|
|
287
|
+
const params = {
|
|
288
|
+
followers: [],
|
|
289
|
+
submitterId: userId,
|
|
290
|
+
ownerId: Number(currentValueInput?.ownerId[0]?.userId),
|
|
291
|
+
submitterEmail: listUsers?.find(user => +user.userId === +userId)?.email,
|
|
292
|
+
properties: {},
|
|
293
|
+
message: uploadedMessage,
|
|
294
|
+
attachmentsZendesk: currentValueInput.fileZendesk.map(file => file.token),
|
|
264
295
|
};
|
|
296
|
+
if (currentValueInput?.followers?.length) {
|
|
297
|
+
params.followers = formatAccountId(currentValueInput.followers);
|
|
298
|
+
}
|
|
299
|
+
if (currentValueInput?.files?.length > 0) {
|
|
300
|
+
params.properties = {
|
|
301
|
+
attachments: currentValueInput.files,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
setIsLoading(true);
|
|
305
|
+
fetchUpdateComment(params);
|
|
306
|
+
handleUpdateFollowers(currentValueInput?.followers?.map((fol) => fol.userId));
|
|
307
|
+
}
|
|
308
|
+
catch (error) {
|
|
309
|
+
// The upload error is shown below the editor.
|
|
265
310
|
}
|
|
266
|
-
params.submitterId = userId;
|
|
267
|
-
params.submitterEmail = listUsers?.find(user => +user.userId === +userId)?.email;
|
|
268
|
-
params.ownerId = Number(valueInput?.ownerId[0]?.userId);
|
|
269
|
-
params.message = valueInput?.message;
|
|
270
|
-
params.attachmentsZendesk = valueInput.fileZendesk.map(file => file.token);
|
|
271
|
-
fetchUpdateComment(params);
|
|
272
|
-
handleUpdateFollowers(valueInput?.followers?.map((fol) => fol.userId));
|
|
273
311
|
};
|
|
274
312
|
const handleUploadFile = async (file) => {
|
|
275
313
|
setIsLoading(true);
|
|
@@ -387,7 +425,8 @@ const Content = ({ portalId, token, action, ticketId, listUsers, domainTicket, d
|
|
|
387
425
|
isLoadingDetails ||
|
|
388
426
|
isLoadingDataSouce ||
|
|
389
427
|
isLoadingFollower ||
|
|
390
|
-
isLoadingSelectedAccount
|
|
428
|
+
isLoadingSelectedAccount ||
|
|
429
|
+
isLoadingUpload, children: [_jsxs(DrawerHeader, { children: [_jsx(EditableName, { value: valueInput.title, onChange: handleOnchangeTitle, readonly: isUpdate, error: isEmptyField && (!valueInput.title || !valueInput.title.trim())
|
|
391
430
|
? "Title can't be empty"
|
|
392
431
|
: '' }), _jsx("div", { id: "header-journey-right", className: "right-content", children: !isUpdate && (_jsx(Button, { disabled: isLoadingUpload, type: "primary", onClick: handleSubmit, children: "Save" })) })] }), _jsxs(WrapperContent, { style: { height: '100%' }, children: [_jsxs(WrapperLeftContent, { children: [_jsxs(WrapperContentInput, { style: { alignItems: 'flex-start' }, children: [_jsxs(WrapperLable, { children: ["Owner", _jsx("span", { style: { color: '#ff0000' }, children: "*" })] }), _jsxs("div", { children: [_jsx(SelectAccount, { type: "default", initData: (valueInput?.ownerId || []).map((item) => item.userId), nameKey: "userName", userIdKey: "userId", users: listUsers, isViewMode: isUpdate || !isAllAccount || accountEdit !== 4, onChange: (_, users) => updateValueInput({ ownerId: users }), onlyOne: true }), isEmptyField && !valueInput?.ownerId?.length && (_jsx("div", { className: "error-message", children: "*This field can't be empty" }))] })] }), _jsxs(WrapperContentInput, { style: { marginTop: '15px', alignItems: 'flex-start' }, children: [_jsx(WrapperLable, { children: "Follower(s)" }), _jsx(SelectAccount, { type: "default", initData: [
|
|
393
432
|
...accountManage,
|
|
@@ -404,7 +443,7 @@ const Content = ({ portalId, token, action, ticketId, listUsers, domainTicket, d
|
|
|
404
443
|
background: `${!handleValidateContent(textValue) || isLoadingUpload
|
|
405
444
|
? '#ccc'
|
|
406
445
|
: '#1f5fac'}`,
|
|
407
|
-
}, onClick: handleUpdateComment, children: "Reply" }))] })] })] }), errFile.isError ? (_jsx("div", { className: "error-message", children: errFile.message })) : (isEmptyField &&
|
|
446
|
+
}, onClick: handleUpdateComment, children: "Reply" }))] })] })] }), embeddedImageError ? (_jsx("div", { className: "error-message", children: embeddedImageError })) : errFile.isError ? (_jsx("div", { className: "error-message", children: errFile.message })) : (isEmptyField &&
|
|
408
447
|
!valueInput?.message && (_jsx("div", { className: "error-message", children: "*This field can't be empty" })))] }), isUpdate && (_jsx(Spin, { spinning: isLoadingComment, children: _jsx(WrapperMessageContent, { children: listComment?.map(comment => (_jsx(MessageComponent, { toUser: comment?.toUser, fromUser: comment?.fromUser, followers: comment?.followers, message: comment?.message, date: comment?.createdDate, attachments: comment?.attachments, timeZone: timeZone, submitterEmail: comment?.submitterEmail }, comment?.id))) }) }))] })] })] })] }));
|
|
409
448
|
};
|
|
410
449
|
export default Content;
|
|
@@ -27,6 +27,7 @@ export declare function getEntriesV2(res: any, def: any): {
|
|
|
27
27
|
messageAPI?: undefined;
|
|
28
28
|
};
|
|
29
29
|
export declare const formatAccountId: (data: any) => any;
|
|
30
|
+
export { dataUrlToFile, uploadEmbeddedImages } from '../../../utils/uploadEmbeddedImages';
|
|
30
31
|
export declare const formatParams: (data: any) => {
|
|
31
32
|
title: string;
|
|
32
33
|
ownerId: undefined;
|
|
@@ -294,6 +294,7 @@ export const formatAccountId = data => {
|
|
|
294
294
|
const results = data?.map(item => item?.userId);
|
|
295
295
|
return results;
|
|
296
296
|
};
|
|
297
|
+
export { dataUrlToFile, uploadEmbeddedImages } from '../../../utils/uploadEmbeddedImages';
|
|
297
298
|
export const formatParams = data => {
|
|
298
299
|
const params = {
|
|
299
300
|
title: '',
|
|
@@ -8,7 +8,7 @@ import MessageComponent from './components/MessageComponent';
|
|
|
8
8
|
import { Spin, Tooltip, Icon, Button, SelectAccount, QuillEditor, } from '@antscorp/antsomi-ui/es/components';
|
|
9
9
|
import Service from './Service';
|
|
10
10
|
import { WrapperContent, WrapperContentInput, WrapperEditor, WrapperIconEditor, WrapperInputFile, WrapperLable, WrapperLeftContent, WrapperLinkItemFiles, WrapperMessageContent, WrapperRightContent, WrapperTextEdit, WrapperTextInput, } from './styled';
|
|
11
|
-
import { formatDatarender, handleValidateContent } from './util';
|
|
11
|
+
import { formatDatarender, handleValidateContent, uploadEmbeddedImages, } from './util';
|
|
12
12
|
import { get, keyBy } from 'lodash';
|
|
13
13
|
import { TCallBack } from '../../molecules/QuillEditor/QuillEditor';
|
|
14
14
|
const initValueInput = {
|
|
@@ -44,6 +44,7 @@ const Content = ({ apiKey, domain, portalId, token, action, ticketId, listUsers,
|
|
|
44
44
|
isError: false,
|
|
45
45
|
message: '',
|
|
46
46
|
});
|
|
47
|
+
const [embeddedImageError, setEmbeddedImageError] = useState('');
|
|
47
48
|
const isUpdate = action === 'edit' && ticketId;
|
|
48
49
|
const valueInputRef = useRef(valueInput);
|
|
49
50
|
valueInputRef.current = valueInput;
|
|
@@ -136,6 +137,7 @@ const Content = ({ apiKey, domain, portalId, token, action, ticketId, listUsers,
|
|
|
136
137
|
}, 1000);
|
|
137
138
|
}, []);
|
|
138
139
|
const handleEditorChange = content => {
|
|
140
|
+
setEmbeddedImageError('');
|
|
139
141
|
setTextValue(content);
|
|
140
142
|
updateValueInput({ message: content });
|
|
141
143
|
// setIsLoadingUpload(content.includes('<img src="data:image/png;base64'));
|
|
@@ -147,33 +149,61 @@ const Content = ({ apiKey, domain, portalId, token, action, ticketId, listUsers,
|
|
|
147
149
|
params.followers = arrFolowers;
|
|
148
150
|
fetchUpdateFollwers(params);
|
|
149
151
|
};
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
|
|
152
|
+
const uploadImagesBeforeSubmit = async (message) => {
|
|
153
|
+
setIsLoadingUpload(true);
|
|
154
|
+
setEmbeddedImageError('');
|
|
155
|
+
try {
|
|
156
|
+
const uploadedMessage = await uploadEmbeddedImages(message, Service.tickets.callApi.uploadFile({
|
|
157
|
+
domain: domainUpload,
|
|
158
|
+
}));
|
|
159
|
+
if (uploadedMessage !== message) {
|
|
160
|
+
setTextValue(uploadedMessage);
|
|
161
|
+
updateValueInput({ message: uploadedMessage });
|
|
162
|
+
}
|
|
163
|
+
return uploadedMessage;
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
setEmbeddedImageError(error instanceof Error && error.message === 'FILE_TOO_LARGE'
|
|
167
|
+
? '*Maximum upload file size: 10MB'
|
|
168
|
+
: '*Image upload failed. Please try again.');
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
finally {
|
|
172
|
+
setIsLoadingUpload(false);
|
|
165
173
|
}
|
|
166
|
-
|
|
167
|
-
|
|
174
|
+
};
|
|
175
|
+
const handleUpdateComment = async () => {
|
|
176
|
+
const currentValueInput = valueInputRef.current;
|
|
177
|
+
try {
|
|
178
|
+
const uploadedMessage = await uploadImagesBeforeSubmit(currentValueInput.message);
|
|
179
|
+
const params = {
|
|
180
|
+
followers: [],
|
|
181
|
+
submitterId: null,
|
|
182
|
+
ownerId: null,
|
|
183
|
+
message: uploadedMessage,
|
|
184
|
+
properties: {
|
|
185
|
+
attachments: [],
|
|
186
|
+
},
|
|
187
|
+
submitterEmail: '',
|
|
188
|
+
attachmentsZendesk: [],
|
|
189
|
+
};
|
|
190
|
+
if (currentValueInput?.followers?.length) {
|
|
191
|
+
params.followers = currentValueInput.followers;
|
|
192
|
+
}
|
|
193
|
+
if (currentValueInput?.files?.length > 0) {
|
|
194
|
+
params.properties.attachments = currentValueInput.files;
|
|
195
|
+
}
|
|
196
|
+
const mapUsers = keyBy(listUsers, 'email');
|
|
197
|
+
params.submitterId = +mapUsers[email]?.userId || 0;
|
|
198
|
+
params.submitterEmail = email;
|
|
199
|
+
params.attachmentsZendesk = currentValueInput.fileZendesk?.map(file => file?.token);
|
|
200
|
+
setIsLoading(true);
|
|
201
|
+
fetchUpdateComment(params);
|
|
202
|
+
handleUpdateFollowers(currentValueInput.followers?.map((fol) => fol.userId));
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
// The upload error is shown below the editor.
|
|
168
206
|
}
|
|
169
|
-
const mapUsers = keyBy(listUsers, 'email');
|
|
170
|
-
params.submitterId = +mapUsers[email]?.userId || 0;
|
|
171
|
-
params.submitterEmail = email;
|
|
172
|
-
params.ownerId = null;
|
|
173
|
-
params.message = valueInput?.message;
|
|
174
|
-
params.attachmentsZendesk = valueInput?.fileZendesk?.map(file => file?.token);
|
|
175
|
-
fetchUpdateComment(params);
|
|
176
|
-
handleUpdateFollowers(valueInput?.followers?.map((fol) => fol.userId));
|
|
177
207
|
};
|
|
178
208
|
const onChangeFollowers = arrFolowers => {
|
|
179
209
|
updateValueInput({ followers: arrFolowers });
|
|
@@ -301,7 +331,11 @@ const Content = ({ apiKey, domain, portalId, token, action, ticketId, listUsers,
|
|
|
301
331
|
break;
|
|
302
332
|
}
|
|
303
333
|
};
|
|
304
|
-
return (_jsxs("div", { style: { height: '100%' }, children: [_jsxs(Helmet, { children: [_jsx("meta", { charSet: "utf-8" }), _jsx("title", { children: browserTitle })] }), _jsx(Spin, { style: { height: '100vh' }, spinning: isLoading ||
|
|
334
|
+
return (_jsxs("div", { style: { height: '100%' }, children: [_jsxs(Helmet, { children: [_jsx("meta", { charSet: "utf-8" }), _jsx("title", { children: browserTitle })] }), _jsx(Spin, { style: { height: '100vh' }, spinning: isLoading ||
|
|
335
|
+
isLoadingDetails ||
|
|
336
|
+
isLoadingDataSouce ||
|
|
337
|
+
isLoadingFollower ||
|
|
338
|
+
isLoadingUpload, children: _jsxs(WrapperContent, { style: { height: '100%' }, children: [_jsxs(WrapperLeftContent, { children: [_jsxs(WrapperContentInput, { style: { alignItems: 'flex-start' }, children: [_jsxs(WrapperLable, { children: ["Owner", _jsx("span", { style: { color: '#ff0000' }, children: "*" })] }), _jsx("div", { children: ownerEmail })] }), _jsxs(WrapperContentInput, { style: { marginTop: '15px', alignItems: 'flex-start' }, children: [_jsx(WrapperLable, { children: "Follower(s)" }), _jsx(SelectAccount, { type: "default", initData: ticketDetails?.followers || [], nameKey: "userName", userIdKey: "userId", users: listUsers, onChange: (_, followers) => onChangeFollowers(followers) })] }), dataSelects?.map((data) => _jsx(_Fragment, { children: renderOptions(data) })), _jsxs(WrapperContentInput, { style: { marginTop: '15px' }, children: [_jsx(WrapperLable, { htmlFor: "referenceUrl", children: "Reference URL" }), isUpdate ? (ticketDetails.referenceUrl ? (_jsx(Tooltip, { title: ticketDetails.referenceUrl, placement: "top", children: _jsx(WrapperTextEdit, { color: "#005fb8", href: ticketDetails.referenceUrl, target: "_blank", children: ticketDetails.referenceUrl }) })) : (_jsx(WrapperTextEdit, { color: "#005fb8", href: ticketDetails.referenceUrl, target: "_blank", children: ticketDetails.referenceUrl }))) : (_jsx(WrapperTextInput, { placeholder: "Reference URL", id: "referenceUrl",
|
|
305
339
|
// width="300px"
|
|
306
340
|
onChange: handleOnchangeInput, name: "referenceUrl", value: valueInput.referenceUrl }))] })] }), _jsxs(WrapperRightContent, { children: [_jsxs(WrapperEditor, { children: [_jsxs(_Fragment, { children: [_jsx(QuillEditor, { value: textValue, uploadService: Service.tickets.callApi.uploadFile({
|
|
307
341
|
domain: domainUpload,
|
|
@@ -309,7 +343,7 @@ const Content = ({ apiKey, domain, portalId, token, action, ticketId, listUsers,
|
|
|
309
343
|
background: `${!handleValidateContent(textValue) || isLoadingUpload
|
|
310
344
|
? '#ccc'
|
|
311
345
|
: '#1f5fac'}`,
|
|
312
|
-
}, onClick: handleUpdateComment, children: "Reply" }))] })] })] }), errFile.isError ? (_jsx("div", { className: "error-message", children: errFile.message })) : (isEmptyField &&
|
|
346
|
+
}, onClick: handleUpdateComment, children: "Reply" }))] })] })] }), embeddedImageError ? (_jsx("div", { className: "error-message", children: embeddedImageError })) : errFile.isError ? (_jsx("div", { className: "error-message", children: errFile.message })) : (isEmptyField &&
|
|
313
347
|
!valueInput?.message && (_jsx("div", { className: "error-message", children: "* This field can't be empty" })))] }), isUpdate && (_jsx(Spin, { spinning: isLoadingComment, children: _jsx(WrapperMessageContent, { children: listComment?.map(comment => (_jsx(MessageComponent, { toUser: comment?.toUser, fromUser: comment?.fromUser, followers: comment?.followers,
|
|
314
348
|
// mailFollower={comment?.mailFollower}
|
|
315
349
|
message: comment?.message, date: comment?.createdDate, attachments: comment?.attachments, timeZone: timeZone, submitterEmail: comment?.submitterEmail }, comment?.id))) }) }))] })] }) })] }));
|
|
@@ -28,6 +28,7 @@ export declare function getEntriesV2(res: any, def: any): {
|
|
|
28
28
|
messageAPI?: undefined;
|
|
29
29
|
};
|
|
30
30
|
export declare const formatAccountId: (data: any) => any;
|
|
31
|
+
export { dataUrlToFile, uploadEmbeddedImages } from '../../../utils/uploadEmbeddedImages';
|
|
31
32
|
export declare const formatParams: (data: any) => {
|
|
32
33
|
title: string;
|
|
33
34
|
ownerId: undefined;
|
|
@@ -287,6 +287,7 @@ export const formatAccountId = data => {
|
|
|
287
287
|
const results = data?.map(item => item?.userId);
|
|
288
288
|
return results;
|
|
289
289
|
};
|
|
290
|
+
export { dataUrlToFile, uploadEmbeddedImages } from '../../../utils/uploadEmbeddedImages';
|
|
290
291
|
export const formatParams = data => {
|
|
291
292
|
const params = {
|
|
292
293
|
title: '',
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type TUploadEmbeddedImages = (params: {
|
|
2
|
+
files: File[];
|
|
3
|
+
mode: 'file';
|
|
4
|
+
}) => Promise<unknown>;
|
|
5
|
+
export declare const dataUrlToFile: (dataUrl: string, index: number) => File;
|
|
6
|
+
export declare const uploadEmbeddedImages: (message: string, uploadService: TUploadEmbeddedImages) => Promise<string>;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const DATA_IMAGE_PREFIX = /^\s*data:image\//i;
|
|
2
|
+
const DATA_IMAGE_URL = /^data:(image\/[^;,]+);base64,(.+)$/i;
|
|
3
|
+
const getUploadedImageUrl = (uploadedImage) => {
|
|
4
|
+
if (!uploadedImage || typeof uploadedImage !== 'object' || !('url' in uploadedImage)) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
const { url } = uploadedImage;
|
|
8
|
+
if (typeof url !== 'string' || !url.trim() || /^\s*data:/i.test(url)) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
const parsedUrl = new URL(url.trim());
|
|
13
|
+
return parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:'
|
|
14
|
+
? parsedUrl.href
|
|
15
|
+
: null;
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
export const dataUrlToFile = (dataUrl, index) => {
|
|
22
|
+
const matches = dataUrl.trim().match(DATA_IMAGE_URL);
|
|
23
|
+
if (!matches) {
|
|
24
|
+
throw new Error('INVALID_IMAGE_DATA');
|
|
25
|
+
}
|
|
26
|
+
const [, rawMimeType, base64] = matches;
|
|
27
|
+
const mimeType = rawMimeType.toLowerCase();
|
|
28
|
+
const padding = base64.endsWith('==') ? 2 : base64.endsWith('=') ? 1 : 0;
|
|
29
|
+
const fileSize = (base64.length * 3) / 4 - padding;
|
|
30
|
+
if (fileSize > 10 * 1024 * 1024) {
|
|
31
|
+
throw new Error('FILE_TOO_LARGE');
|
|
32
|
+
}
|
|
33
|
+
const binary = atob(base64);
|
|
34
|
+
const bytes = new Uint8Array(binary.length);
|
|
35
|
+
for (let byteIndex = 0; byteIndex < binary.length; byteIndex += 1) {
|
|
36
|
+
bytes[byteIndex] = binary.charCodeAt(byteIndex);
|
|
37
|
+
}
|
|
38
|
+
const extension = mimeType.split('/')[1].replace('jpeg', 'jpg');
|
|
39
|
+
return new File([bytes], `ticket-image-${index + 1}.${extension}`, { type: mimeType });
|
|
40
|
+
};
|
|
41
|
+
export const uploadEmbeddedImages = async (message, uploadService) => {
|
|
42
|
+
const container = document.createElement('div');
|
|
43
|
+
container.innerHTML = message;
|
|
44
|
+
const images = Array.from(container.querySelectorAll('img')).filter(image => DATA_IMAGE_PREFIX.test(image.getAttribute('src') || ''));
|
|
45
|
+
if (!images.length) {
|
|
46
|
+
return message;
|
|
47
|
+
}
|
|
48
|
+
const files = images.map((image, index) => dataUrlToFile(image.getAttribute('src') || '', index));
|
|
49
|
+
const response = await uploadService({ files, mode: 'file' });
|
|
50
|
+
const uploadedImages = response && typeof response === 'object' && 'data' in response && Array.isArray(response.data)
|
|
51
|
+
? response.data
|
|
52
|
+
: [];
|
|
53
|
+
const uploadedUrls = uploadedImages.map(getUploadedImageUrl);
|
|
54
|
+
if (uploadedUrls.length !== images.length || uploadedUrls.some(uploadedUrl => !uploadedUrl)) {
|
|
55
|
+
throw new Error('UPLOAD_FAILED');
|
|
56
|
+
}
|
|
57
|
+
images.forEach((image, index) => {
|
|
58
|
+
image.setAttribute('src', uploadedUrls[index]);
|
|
59
|
+
});
|
|
60
|
+
const hasEmbeddedImage = Array.from(container.querySelectorAll('img')).some(image => DATA_IMAGE_PREFIX.test(image.getAttribute('src') || ''));
|
|
61
|
+
if (hasEmbeddedImage) {
|
|
62
|
+
throw new Error('UPLOAD_FAILED');
|
|
63
|
+
}
|
|
64
|
+
return container.innerHTML;
|
|
65
|
+
};
|