@antscorp/antsomi-ui 2.0.75 → 2.0.76

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.
@@ -1,3 +1,4 @@
1
+ export declare const MIN_VISIBLE_COUNT = 40;
1
2
  export declare const COMMON_COLLECTION_KEYS: {
2
3
  readonly SMILEYS_BODY: "smileys_body";
3
4
  readonly ANIMALS_NATURE: "animals_nature";
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { EmojiAirportShuttleIcon, EmojiBallIcon, EmojiElectricBoltIcon, EmojiFlagIcon, EmojiLightBulbIcon, EmojiPetFootIcon, EmojiRamenDiningIcon, EmojiReactionIcon, } from '@antscorp/antsomi-ui/es/components/icons';
3
+ export const MIN_VISIBLE_COUNT = 40; // ROW: 4, COLUMN: 10 => 4 x 10
3
4
  export const COMMON_COLLECTION_KEYS = {
4
5
  SMILEYS_BODY: 'smileys_body',
5
6
  ANIMALS_NATURE: 'animals_nature',
@@ -12,13 +12,13 @@ import { EmojiSmileIcon, SearchIcon } from '@antscorp/antsomi-ui/es/components/i
12
12
  // Hooks
13
13
  import { useDebounce } from '@antscorp/antsomi-ui/es/hooks/useDebounceV2';
14
14
  // Constants
15
- import { COMMON_TAB_COLLECTION, SMILEYS_BODY } from './constants';
15
+ import { COMMON_TAB_COLLECTION, MIN_VISIBLE_COUNT, SMILEYS_BODY } from './constants';
16
16
  import { globalToken } from '@antscorp/antsomi-ui/es/constants';
17
17
  const { Text } = Typography;
18
18
  const emojiListParsed = JSON.parse(JSON.stringify(ICON_EMOJI_COMMON));
19
19
  const CommonCollection = ({ onEmojiClick }) => {
20
20
  // States
21
- const [visibleCount, setVisibleCount] = useState(40);
21
+ const [visibleCount, setVisibleCount] = useState(MIN_VISIBLE_COUNT);
22
22
  const [state, setState] = useImmer({
23
23
  collectionActive: SMILEYS_BODY,
24
24
  txtSearch: '',
@@ -54,7 +54,7 @@ const CommonCollection = ({ onEmojiClick }) => {
54
54
  setVisibleCount(prev => {
55
55
  const newCount = prev + 30;
56
56
  if (newCount >= collectionLength)
57
- return collectionLength;
57
+ return collectionLength > MIN_VISIBLE_COUNT ? collectionLength : MIN_VISIBLE_COUNT;
58
58
  return newCount;
59
59
  });
60
60
  }
@@ -1,3 +1,4 @@
1
+ export declare const MIN_VISIBLE_COUNT = 40;
1
2
  export declare const PRODUCT_ID_EMOJIS: readonly [{
2
3
  readonly id: "5ac2213e040ab15980c9b447";
3
4
  readonly total: 182;
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable consistent-return */
2
2
  // Utils
3
3
  import { getLinkLineURLImage } from '@antscorp/antsomi-ui/es/components/molecules/TagifyInput';
4
+ export const MIN_VISIBLE_COUNT = 40; // ROW: 4, COLUMN: 10 => 4 x 10
4
5
  export const PRODUCT_ID_EMOJIS = [
5
6
  {
6
7
  id: '5ac2213e040ab15980c9b447',
@@ -10,11 +10,11 @@ import { Button, Flex, Scrollbars } from '@antscorp/antsomi-ui/es/components/ato
10
10
  import { getLinkLineURLImage, PREFIX_PATTERN_LINE_MESSAGE, } from '@antscorp/antsomi-ui/es/components/molecules';
11
11
  import { EmojiSmileIcon } from '@antscorp/antsomi-ui/es/components/icons';
12
12
  // Constants
13
- import { LINE_MESSAGE_EMOJIS, TAB_LINE_MESSAGE_EMOJIS } from './constants';
13
+ import { LINE_MESSAGE_EMOJIS, MIN_VISIBLE_COUNT, TAB_LINE_MESSAGE_EMOJIS } from './constants';
14
14
  import { globalToken } from '@antscorp/antsomi-ui/es/constants';
15
15
  const LineCollection = ({ onEmojiClick }) => {
16
16
  // States
17
- const [visibleCount, setVisibleCount] = useState(40);
17
+ const [visibleCount, setVisibleCount] = useState(MIN_VISIBLE_COUNT);
18
18
  const [state, setState] = useImmer({
19
19
  collectionActive: TAB_LINE_MESSAGE_EMOJIS[0]?.key || '',
20
20
  });
@@ -32,7 +32,7 @@ const LineCollection = ({ onEmojiClick }) => {
32
32
  setVisibleCount(prev => {
33
33
  const newCount = prev + 30;
34
34
  if (newCount >= collectionLength)
35
- return collectionLength;
35
+ return collectionLength > MIN_VISIBLE_COUNT ? collectionLength : collectionLength;
36
36
  return newCount;
37
37
  });
38
38
  }
@@ -14,9 +14,10 @@ import { EmojiSmileIcon, SearchIcon } from '@antscorp/antsomi-ui/es/components/i
14
14
  // Constants
15
15
  import { globalToken } from '@antscorp/antsomi-ui/es/constants';
16
16
  const listEmoji = Object.values(iconsViber);
17
+ const MIN_VISIBLE_COUNT = 40; // ROW: 4, COLUMN: 10 => 4 x 10
17
18
  const ViberCollection = ({ onEmojiClick }) => {
18
19
  // States
19
- const [visibleCount, setVisibleCount] = useState(40);
20
+ const [visibleCount, setVisibleCount] = useState(MIN_VISIBLE_COUNT);
20
21
  const [state, setState] = useImmer({
21
22
  txtSearch: '',
22
23
  });
@@ -43,7 +44,7 @@ const ViberCollection = ({ onEmojiClick }) => {
43
44
  setVisibleCount(prev => {
44
45
  const newCount = prev + 30;
45
46
  if (newCount >= collectionLength)
46
- return collectionLength;
47
+ return collectionLength > MIN_VISIBLE_COUNT ? collectionLength : MIN_VISIBLE_COUNT;
47
48
  return newCount;
48
49
  });
49
50
  }
@@ -10,7 +10,7 @@ import { CDP_ROUTE } from '@antscorp/antsomi-ui/es/constants';
10
10
  const translateAt = translate(translations._INFO_LOCATION, 'at');
11
11
  const urlJourney = (data, config) => {
12
12
  const { story = {} } = data;
13
- const url = `${CDP_ROUTE[config.env || ENV.PROD]}/${config.auth?.portalId}/${config.auth?.userId}/marketing-hub/journeys/${story.channelId && story.channelId}/list?ui=detail-drawer&journeyId=${story.id && story.id}&channelId=${story.channelId && story.channelId}&tab=settings&design=preview`;
13
+ const url = `${CDP_ROUTE[config.env || ENV.PROD]}/gen2/${config.auth?.portalId}/${config.auth?.userId}/marketing-hub/journeys/${story.channelId && story.channelId}/list?ui=detail-drawer&journeyId=${story.id && story.id}&channelId=${story.channelId && story.channelId}&tab=settings&design=preview`;
14
14
  return url;
15
15
  };
16
16
  export const getValuesReplace = (objectReplace, data) => {
@@ -35,6 +35,7 @@ const Loading = ({ isLoading, height, width }) => isLoading && (_jsx(WrapperLoad
35
35
  const Help = props => {
36
36
  const { configs, triggerType, buttonProps, boundsDraggable, isShowResizeHover, children } = props;
37
37
  const { apiKey, domainPlatform, appCode, domain, portalId, token, userId, config, domainTicket, domainUpload, avatar, } = configs;
38
+ console.log('🚀 ~ domainUpload:', domainUpload);
38
39
  // const [isOpenDropdown, setIsOpenDropdown] = useState<boolean>(false);
39
40
  const [defaultPositionDrawActions, setDefaultPositionDrawActions] = useState(DEFAULT_POSITIONS.capture);
40
41
  const [defaultPositionRecordActions, setDefaultPositionRecordActions] = useState(DEFAULT_POSITIONS.record);
@@ -53,6 +54,7 @@ const Help = props => {
53
54
  message: '',
54
55
  files: [],
55
56
  referenceUrl: '',
57
+ fileZendesk: [],
56
58
  });
57
59
  const { listUsers, isFetchingUsers } = useGetListUser({
58
60
  domain,
@@ -191,12 +193,19 @@ const Help = props => {
191
193
  try {
192
194
  setIsMainLoading(true);
193
195
  const response = await uploadService({ files: [file] });
196
+ const fileZendesk = await uploadZendeskService(file);
194
197
  if (response.code === 200) {
195
198
  setValueInput(prevVal => ({
196
199
  ...prevVal,
197
200
  files: [...valueInput.files, response.data[0]],
198
201
  }));
199
202
  }
203
+ if (!isEmpty(fileZendesk)) {
204
+ setValueInput(prevVal => ({
205
+ ...prevVal,
206
+ fileZendesk: [...valueInput.fileZendesk, fileZendesk],
207
+ }));
208
+ }
200
209
  }
201
210
  catch (error) {
202
211
  // eslint-disable-next-line no-console
@@ -262,6 +271,28 @@ const Help = props => {
262
271
  newListFile = newListFile.filter(list => list?.token !== token);
263
272
  setValueInput(prevVal => ({ ...prevVal, files: newListFile }));
264
273
  };
274
+ const handleRemoveFileV2 = (url, fileName) => {
275
+ let newListFile = valueInput.files;
276
+ newListFile = newListFile.filter((list) => list?.url !== url);
277
+ const newFileZendesk = valueInput.fileZendesk.filter(file => file.file_name !== fileName);
278
+ setValueInput(prevVal => ({
279
+ ...prevVal,
280
+ files: newListFile,
281
+ fileZendesk: newFileZendesk,
282
+ }));
283
+ };
284
+ const uploadZendeskService = async (listFiles) => {
285
+ const formData = new FormData();
286
+ formData.append('file', listFiles);
287
+ const params = {
288
+ data: formData,
289
+ };
290
+ const responseZendesk = await Service.tickets.callApi.upload(params, domainTicket, token, config, userId, 'ticket');
291
+ if (responseZendesk.code === 200) {
292
+ return responseZendesk.data;
293
+ }
294
+ return [];
295
+ };
265
296
  const handleResetData = () => {
266
297
  setUrlImageDrawer('');
267
298
  setUrlVideoPreview('');
@@ -272,6 +303,7 @@ const Help = props => {
272
303
  message: '',
273
304
  title: '',
274
305
  files: [],
306
+ fileZendesk: [],
275
307
  }));
276
308
  setIsShowPopup(false);
277
309
  setErrFile({
@@ -558,6 +590,7 @@ const Help = props => {
558
590
  try {
559
591
  setIsMainLoading(true);
560
592
  let attachments = [];
593
+ let attachmentsZendesk = [];
561
594
  const uploadServices = TicketService.tickets.callApi.uploadImg({
562
595
  domain: domainUpload,
563
596
  token,
@@ -567,13 +600,20 @@ const Help = props => {
567
600
  if (params.attachments && !isEmpty(params.attachments)) {
568
601
  attachments = [...params.attachments];
569
602
  }
603
+ if (params.attachmentsZendesk && !isEmpty(params.attachmentsZendesk)) {
604
+ attachmentsZendesk = [...params.attachmentsZendesk];
605
+ }
570
606
  if (imageDrew.dataURL) {
571
607
  const imageFile = base64ToFile(imageDrew.dataURL, `${imageDrew.imageName}-${generateUniqueId()}.png`);
572
608
  if (imageFile) {
573
609
  const response = await uploadServices({ files: [imageFile], mode: 'file' });
610
+ const fileZendesk = await uploadZendeskService(imageFile);
574
611
  if (response.code === 200) {
575
612
  attachments.push(response.data[0]);
576
613
  }
614
+ if (!isEmpty(fileZendesk)) {
615
+ attachmentsZendesk.push(fileZendesk?.token);
616
+ }
577
617
  }
578
618
  }
579
619
  if (!isEmpty(dataRecorded)) {
@@ -582,14 +622,19 @@ const Help = props => {
582
622
  const videoFile = convertBlobToFile(blob, blobName);
583
623
  if (videoFile) {
584
624
  const response = await uploadServices({ files: [videoFile], mode: 'video' });
625
+ const fileZendesk = await uploadZendeskService(videoFile);
585
626
  if (response.code === 200) {
586
627
  attachments.push(response.data[0]);
587
628
  }
629
+ if (!isEmpty(fileZendesk)) {
630
+ attachmentsZendesk.push(fileZendesk?.token);
631
+ }
588
632
  }
589
633
  }
590
634
  const dataToAPI = {
591
635
  ...restParams,
592
636
  attachments,
637
+ attachmentsZendesk,
593
638
  networkId: Number(portalId),
594
639
  ticketType: type === REPORT_TYPES.ISSUE ? 'bug' : 'request',
595
640
  };
@@ -624,6 +669,7 @@ const Help = props => {
624
669
  if (!errFile.isError) {
625
670
  const params = formatParams({ ...valueInput, feature: appTargeting });
626
671
  const mapUserById = keyBy(listUsers, 'userId');
672
+ console.log('🚀 ~ handleSubmit ~ params:', params);
627
673
  const ownerEmail = mapUserById[params.ownerId || '']?.email;
628
674
  const referenceUrl = window.location.href;
629
675
  handleCreateTicket({
@@ -808,7 +854,7 @@ const Help = props => {
808
854
  color: THEME.token?.colorIcon,
809
855
  fontSize: '12px',
810
856
  cursor: 'pointer',
811
- }, onClick: () => handleRemoveFile(file?.token), children: "clear" })] }, file?.token))) })), _jsx(WrapperIconEditor, { borderTop: Boolean(valueInput.files?.length), children: _jsxs(WrapperInputFile, { children: [_jsx("label", { htmlFor: "fileImage", children: _jsx(Icon, { type: "icon-ants-hyperlink", style: {
857
+ }, onClick: () => handleRemoveFileV2(file?.url, file?.file_name), children: "clear" })] }, file?.token))) })), _jsx(WrapperIconEditor, { borderTop: Boolean(valueInput.files?.length), children: _jsxs(WrapperInputFile, { children: [_jsx("label", { htmlFor: "fileImage", children: _jsx(Icon, { type: "icon-ants-hyperlink", style: {
812
858
  color: THEME.token?.colorPrimary,
813
859
  fontSize: '24px',
814
860
  position: 'absolute',
@@ -24,6 +24,7 @@ export interface ValueFormProps {
24
24
  followers: any[];
25
25
  message: string;
26
26
  files: any[];
27
+ fileZendesk: any[];
27
28
  referenceUrl: string;
28
29
  }
29
30
  export interface AllAppOptionsProps {
@@ -10,6 +10,7 @@ export declare const formatParams: (data: any) => {
10
10
  category: string;
11
11
  message: string;
12
12
  attachments: never[];
13
+ attachmentsZendesk: never[];
13
14
  };
14
15
  export declare const postCustomEvent: (type: any, data: any) => void;
15
16
  export declare const expendDefault: (data: any) => string[];
@@ -3,6 +3,7 @@ export const formatAccountId = data => {
3
3
  return results;
4
4
  };
5
5
  export const formatParams = data => {
6
+ console.log('🚀 ~ data:', data);
6
7
  const params = {
7
8
  title: '',
8
9
  ownerId: undefined,
@@ -14,6 +15,7 @@ export const formatParams = data => {
14
15
  category: '',
15
16
  message: '',
16
17
  attachments: [],
18
+ attachmentsZendesk: [],
17
19
  };
18
20
  if (data?.ownerId) {
19
21
  params.ownerId = data?.ownerId;
@@ -45,6 +47,9 @@ export const formatParams = data => {
45
47
  if (data?.files?.length) {
46
48
  params.attachments = data?.files;
47
49
  }
50
+ if (data.fileZendesk?.length) {
51
+ params.attachmentsZendesk = data?.fileZendesk?.map(file => file?.token);
52
+ }
48
53
  return params;
49
54
  };
50
55
  export const postCustomEvent = (type, data) => {
@@ -22,6 +22,7 @@ const initValueInput = {
22
22
  followers: [],
23
23
  message: '',
24
24
  files: [],
25
+ fileZendesk: [],
25
26
  isChanged: false,
26
27
  referenceUrl: window.location.href,
27
28
  };
@@ -38,6 +39,7 @@ const Content = ({ portalId, token, action, ticketId, listUsers, domainTicket, d
38
39
  const [isLoadingUpload, setIsLoadingUpload] = useState(false);
39
40
  const [isLoadingFollower, setIsLoadingFollower] = useState(false);
40
41
  const [valueInput, setValueInput] = useState(initValueInput);
42
+ const [fileInputKey, setFileInputKey] = useState(0);
41
43
  const [errFile, setErrFile] = useState({
42
44
  isError: false,
43
45
  message: '',
@@ -262,6 +264,7 @@ const Content = ({ portalId, token, action, ticketId, listUsers, domainTicket, d
262
264
  ownerId: null,
263
265
  properties: {},
264
266
  message: '',
267
+ attachmentsZendesk: [],
265
268
  };
266
269
  if (valueInput?.followers?.length) {
267
270
  params.followers = formatAccountId(valueInput?.followers);
@@ -275,6 +278,7 @@ const Content = ({ portalId, token, action, ticketId, listUsers, domainTicket, d
275
278
  params.submitterEmail = listUsers?.find(user => user.userId === userId)?.email;
276
279
  params.ownerId = Number(valueInput?.ownerId[0]?.userId);
277
280
  params.message = valueInput?.message;
281
+ params.attachmentsZendesk = valueInput.fileZendesk.map(file => file.token);
278
282
  fetchUpdateComment(params);
279
283
  handleUpdateFollowers(valueInput?.followers?.map((fol) => fol.userId));
280
284
  };
@@ -285,8 +289,22 @@ const Content = ({ portalId, token, action, ticketId, listUsers, domainTicket, d
285
289
  token,
286
290
  userId,
287
291
  });
292
+ const uploadZendeskService = async (listFiles) => {
293
+ const formData = new FormData();
294
+ formData.append('file', listFiles);
295
+ const params = {
296
+ data: formData,
297
+ };
298
+ const responseZendesk = await Service.tickets.callApi.upload(params, domainTicket, token, config, userId, 'ticket');
299
+ if (responseZendesk.code === 200) {
300
+ updateValueInput({
301
+ fileZendesk: [...valueInput?.fileZendesk, responseZendesk?.data],
302
+ });
303
+ }
304
+ };
288
305
  try {
289
306
  const response = await uploadService({ files: [file] });
307
+ await uploadZendeskService(file);
290
308
  if (response.code === 200) {
291
309
  updateValueInput({
292
310
  files: [...valueInput?.files, response?.data[0]],
@@ -324,14 +342,21 @@ const Content = ({ portalId, token, action, ticketId, listUsers, domainTicket, d
324
342
  });
325
343
  handleUploadFile(e.target.files[0]);
326
344
  }
345
+ setFileInputKey(fileInputKey + 1);
327
346
  };
328
- const handleRemoveFile = url => {
347
+ const handleRemoveFile = (url, fileName) => {
329
348
  let newListFile = valueInput.files;
330
349
  newListFile = newListFile.filter((list) => list?.url !== url);
331
350
  updateValueInput({ files: newListFile });
332
351
  };
333
- const handleCloseSnackbar = () => {
334
- setIsOpenToast({ ...isOpenToast, isOpen: false });
352
+ const handleRemoveFileV2 = (url, fileName) => {
353
+ let newListFile = valueInput.files;
354
+ newListFile = newListFile.filter((list) => list?.url !== url);
355
+ const newFileZendesk = valueInput.fileZendesk.filter(file => file.file_name !== fileName);
356
+ updateValueInput({
357
+ files: newListFile,
358
+ fileZendesk: newFileZendesk,
359
+ });
335
360
  };
336
361
  return (_jsxs("div", { style: { height: '100%' }, children: [_jsxs(Helmet, { children: [_jsx("meta", { charSet: "utf-8" }), _jsx("title", { children: browserTitle })] }), _jsxs(Spin, { style: { height: '100vh' }, spinning: isLoading ||
337
362
  isLoadingDetails ||
@@ -352,7 +377,9 @@ const Content = ({ portalId, token, action, ticketId, listUsers, domainTicket, d
352
377
  domain: domainUpload,
353
378
  token,
354
379
  userId,
355
- }), onChange: handleEditorChange, placeholder: "Enter your comment...", height: 195 }), _jsxs("div", { children: [valueInput.files?.length > 0 && (_jsx(WrapperLinkItemFiles, { children: valueInput.files?.map((file) => (_jsxs("div", { className: "file-item", children: [_jsxs("div", { className: "file-name-group", children: [_jsx(Icon, { className: "file-icon", type: "icon-ants-attachment" }), _jsx(Tooltip, { title: file?.file_name, children: _jsx("span", { className: "file-name", children: file?.file_name }) })] }), _jsx(Icon, { onClick: () => handleRemoveFile(file?.url), className: "remove-btn", type: "icon-ants-remove-slim" })] }, file?.file_name))) })), _jsxs(WrapperIconEditor, { borderTop: !!valueInput.files?.length, children: [_jsxs(WrapperInputFile, { children: [_jsx("label", { htmlFor: "fileImage", className: "upload-wrapper-label", children: _jsx(Icon, { type: "icon-ants-attachment", className: "upload-icon" }) }), _jsx("input", { type: "file", style: { position: 'absolute', top: 0, right: 0, display: 'none' }, name: "fileImage", id: "fileImage", onChange: handleOnchangeFile })] }), isUpdate && (_jsx(Button, { type: "primary", disabled: !handleValidateContent(textValue) || isLoadingUpload, className: "reply-btn", style: {
380
+ }), onChange: handleEditorChange, placeholder: "Enter your comment...", height: 195 }), _jsxs("div", { children: [valueInput.files?.length > 0 && (_jsx(WrapperLinkItemFiles, { children: valueInput.files?.map((file) => (_jsxs("div", { className: "file-item", children: [_jsxs("div", { className: "file-name-group", children: [_jsx(Icon, { className: "file-icon", type: "icon-ants-attachment" }), _jsx(Tooltip, { title: file?.file_name, children: _jsx("span", { className: "file-name", children: file?.file_name }) })] }), _jsx(Icon, { onClick: () => {
381
+ handleRemoveFileV2(file?.url, file?.file_name);
382
+ }, className: "remove-btn", type: "icon-ants-remove-slim" })] }, file?.file_name))) })), _jsxs(WrapperIconEditor, { borderTop: !!valueInput.files?.length, children: [_jsxs(WrapperInputFile, { children: [_jsx("label", { htmlFor: `fileImage-${fileInputKey}`, className: "upload-wrapper-label", children: _jsx(Icon, { type: "icon-ants-attachment", className: "upload-icon" }) }), _jsx("input", { type: "file", style: { position: 'absolute', top: 0, right: 0, display: 'none' }, name: `fileImage-${fileInputKey}`, id: `fileImage-${fileInputKey}`, onChange: handleOnchangeFile }, fileInputKey)] }), isUpdate && (_jsx(Button, { type: "primary", disabled: !handleValidateContent(textValue) || isLoadingUpload, className: "reply-btn", style: {
356
383
  background: `${!handleValidateContent(textValue) || isLoadingUpload
357
384
  ? '#ccc'
358
385
  : '#1f5fac'}`,
@@ -38,6 +38,7 @@ export declare const formatParams: (data: any) => {
38
38
  category: string;
39
39
  message: string;
40
40
  attachments: never[];
41
+ attachmentsZendesk: never[];
41
42
  submitterEmail: string;
42
43
  };
43
44
  export declare const formatDatarender: (data: any, listSelect: any, listAccount: any) => any;
@@ -306,6 +306,7 @@ export const formatParams = data => {
306
306
  category: '',
307
307
  message: '',
308
308
  attachments: [],
309
+ attachmentsZendesk: [],
309
310
  submitterEmail: '',
310
311
  };
311
312
  if (data?.ownerId) {
@@ -338,6 +339,9 @@ export const formatParams = data => {
338
339
  if (data?.files?.length) {
339
340
  params.attachments = data?.files;
340
341
  }
342
+ if (data?.fileZendesk) {
343
+ params.attachmentsZendesk = data?.fileZendesk?.map(file => file?.token);
344
+ }
341
345
  if (data?.submitterEmail) {
342
346
  params.submitterEmail = data?.submitterEmail;
343
347
  }
@@ -21,6 +21,7 @@ const initValueInput = {
21
21
  followers: [],
22
22
  message: '',
23
23
  files: [],
24
+ fileZendesk: [],
24
25
  isChanged: false,
25
26
  referenceUrl: window.location.href,
26
27
  };
@@ -37,6 +38,7 @@ const Content = ({ apiKey, domain, portalId, token, action, ticketId, listUsers,
37
38
  const [isLoadingUpload, setIsLoadingUpload] = useState(false);
38
39
  const [isLoadingFollower, setIsLoadingFollower] = useState(false);
39
40
  const [valueInput, setValueInput] = useState(initValueInput);
41
+ const [fileInputKey, setFileInputKey] = useState(0);
40
42
  const [errFile, setErrFile] = useState({
41
43
  isError: false,
42
44
  message: '',
@@ -144,7 +146,6 @@ const Content = ({ apiKey, domain, portalId, token, action, ticketId, listUsers,
144
146
  });
145
147
  }
146
148
  }, [ticketDetails, listUsers, dataSelects]);
147
- console.log('🚀 ~ listUsers:', listUsers);
148
149
  useEffect(() => {
149
150
  setIsLoading(true);
150
151
  getCustomFields();
@@ -175,6 +176,7 @@ const Content = ({ apiKey, domain, portalId, token, action, ticketId, listUsers,
175
176
  attachments: [],
176
177
  },
177
178
  submitterEmail: '',
179
+ attachmentsZendesk: [],
178
180
  };
179
181
  if (valueInput?.followers?.length) {
180
182
  params.followers = valueInput?.followers;
@@ -187,6 +189,7 @@ const Content = ({ apiKey, domain, portalId, token, action, ticketId, listUsers,
187
189
  params.submitterEmail = email;
188
190
  params.ownerId = Number(valueInput?.ownerId[0]?.userId);
189
191
  params.message = valueInput?.message;
192
+ params.attachmentsZendesk = valueInput?.fileZendesk?.map(file => file?.token);
190
193
  fetchUpdateComment(params);
191
194
  handleUpdateFollowers(valueInput?.followers?.map((fol) => fol.userId));
192
195
  };
@@ -199,8 +202,22 @@ const Content = ({ apiKey, domain, portalId, token, action, ticketId, listUsers,
199
202
  const uploadService = Service.tickets.callApi.uploadFile({
200
203
  domain: domainUpload,
201
204
  });
205
+ const uploadZendeskService = async (listFiles) => {
206
+ const formData = new FormData();
207
+ formData.append('file', listFiles);
208
+ const params = {
209
+ data: formData,
210
+ };
211
+ const responseZendesk = await Service.tickets.callApi.upload(params, domainTicket, token, config, userId, 'ticket');
212
+ if (responseZendesk.code === 200) {
213
+ updateValueInput({
214
+ fileZendesk: [...valueInput?.fileZendesk, responseZendesk?.data],
215
+ });
216
+ }
217
+ };
202
218
  try {
203
219
  const response = await uploadService({ files: [file], mode: 'file' });
220
+ await uploadZendeskService(file);
204
221
  if (response.code === 200) {
205
222
  updateValueInput({
206
223
  files: [...valueInput?.files, response?.data[0]],
@@ -238,12 +255,22 @@ const Content = ({ apiKey, domain, portalId, token, action, ticketId, listUsers,
238
255
  });
239
256
  handleUploadFile(e.target.files[0]);
240
257
  }
258
+ setFileInputKey(fileInputKey + 1);
241
259
  };
242
260
  const handleRemoveFile = token => {
243
261
  let newListFile = valueInput.files;
244
262
  newListFile = newListFile.filter((list) => list?.token !== token);
245
263
  updateValueInput({ files: newListFile });
246
264
  };
265
+ const handleRemoveFileV2 = (url, fileName) => {
266
+ let newListFile = valueInput.files;
267
+ newListFile = newListFile.filter((list) => list?.url !== url);
268
+ const newFileZendesk = valueInput.fileZendesk.filter(file => file.file_name !== fileName);
269
+ updateValueInput({
270
+ files: newListFile,
271
+ fileZendesk: newFileZendesk,
272
+ });
273
+ };
247
274
  const ownerEmail = useMemo(() => {
248
275
  const keyById = keyBy(listUsers, 'userId');
249
276
  if (keyById[ticketDetails?.ownerId]) {
@@ -262,7 +289,7 @@ const Content = ({ apiKey, domain, portalId, token, action, ticketId, listUsers,
262
289
  // width="300px"
263
290
  onChange: handleOnchangeInput, name: "referenceUrl", value: valueInput.referenceUrl }))] })] }), _jsxs(WrapperRightContent, { children: [_jsxs(WrapperEditor, { children: [_jsxs("div", { children: [_jsx(QuillEditor, { value: textValue, uploadService: Service.tickets.callApi.uploadFile({
264
291
  domain: domainUpload,
265
- }), onChange: handleEditorChange, placeholder: "Enter your comment...", height: 195 }), _jsxs("div", { children: [valueInput.files?.length > 0 && (_jsx(WrapperLinkItemFiles, { children: valueInput.files?.map((file) => (_jsxs("div", { className: "file-item", children: [_jsxs("div", { className: "file-name-group", children: [_jsx(Icon, { className: "file-icon", type: "icon-ants-attachment" }), _jsx(Tooltip, { title: file?.file_name, children: _jsx("span", { className: "file-name", children: file?.file_name }) })] }), _jsx(Icon, { onClick: () => handleRemoveFile(file?.token), className: "remove-btn", type: "icon-ants-remove-slim" })] }, file?.token))) })), _jsxs(WrapperIconEditor, { borderTop: !!valueInput.files?.length, children: [_jsxs(WrapperInputFile, { children: [_jsx("label", { htmlFor: "fileImage", className: "upload-wrapper-label", children: _jsx(Icon, { type: "icon-ants-attachment", className: "upload-icon" }) }), _jsx("input", { type: "file", style: { position: 'absolute', top: 0, right: 0, display: 'none' }, name: "fileImage", id: "fileImage", onChange: handleOnchangeFile })] }), isUpdate && (_jsx(Button, { type: "primary", disabled: !handleValidateContent(textValue) || isLoadingUpload, className: "reply-btn", style: {
292
+ }), onChange: handleEditorChange, placeholder: "Enter your comment...", height: 195 }), _jsxs("div", { children: [valueInput.files?.length > 0 && (_jsx(WrapperLinkItemFiles, { children: valueInput.files?.map((file) => (_jsxs("div", { className: "file-item", children: [_jsxs("div", { className: "file-name-group", children: [_jsx(Icon, { className: "file-icon", type: "icon-ants-attachment" }), _jsx(Tooltip, { title: file?.file_name, children: _jsx("span", { className: "file-name", children: file?.file_name }) })] }), _jsx(Icon, { onClick: () => handleRemoveFileV2(file?.url, file?.file_name), className: "remove-btn", type: "icon-ants-remove-slim" })] }, file?.token))) })), _jsxs(WrapperIconEditor, { borderTop: !!valueInput.files?.length, children: [_jsxs(WrapperInputFile, { children: [_jsx("label", { htmlFor: `fileImage-${fileInputKey}`, className: "upload-wrapper-label", children: _jsx(Icon, { type: "icon-ants-attachment", className: "upload-icon" }) }), _jsx("input", { type: "file", style: { position: 'absolute', top: 0, right: 0, display: 'none' }, name: `fileImage-${fileInputKey}`, id: `fileImage-${fileInputKey}`, onChange: handleOnchangeFile }, fileInputKey)] }), isUpdate && (_jsx(Button, { type: "primary", disabled: !handleValidateContent(textValue) || isLoadingUpload, className: "reply-btn", style: {
266
293
  background: `${!handleValidateContent(textValue) || isLoadingUpload
267
294
  ? '#ccc'
268
295
  : '#1f5fac'}`,
@@ -35,7 +35,7 @@ const API = {
35
35
  // const data = getEntriesV2(res, 0);
36
36
  // dataBackup[params.objectName] = data;
37
37
  res.data),
38
- upload: (params, domain, token, config, userId, type) => callApiWithAuth(`api/upload/index`, 'post', params.data, domain, config, token, userId, true, type).then(res =>
38
+ upload: (params, domain, token, config, userId, type) => callApiWithAuth(`api/base/upload/index`, 'post', params.data, domain, config, token, userId, true, type).then(res =>
39
39
  // const data = getEntriesV2(res, 0);
40
40
  // dataBackup[params.objectName] = data;
41
41
  res.data),
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useMemo, useRef, useState } from 'react';
2
+ import { useEffect, useMemo, useRef, useState } from 'react';
3
3
  import { WrapperAvatar, WrapperContentAvatar, WrapperLinkItemFiles, WrapperModalHeaderImg, WrapperModalImg, } from '../styled';
4
4
  import { Icon, Image, Spin, Tooltip } from '@antscorp/antsomi-ui/es/components';
5
5
  import { convertDateToTimestamp, generateAvatar } from '../util';
@@ -13,6 +13,26 @@ const MessageComponent = ({ toUser, fromUser, followers, attachments, message, d
13
13
  isOpen: false,
14
14
  src: '',
15
15
  });
16
+ useEffect(() => {
17
+ if (refMesage.current) {
18
+ refMesage.current.querySelectorAll('img')?.forEach(img => {
19
+ img.style.cursor = 'pointer';
20
+ img.addEventListener('click', () => {
21
+ setModalImg({
22
+ ...modalImg,
23
+ isOpen: true,
24
+ src: img?.src,
25
+ });
26
+ });
27
+ });
28
+ refMesage.current.querySelectorAll('a')?.forEach(a => {
29
+ const isOpenNewTab = a.attributes?.rel?.value?.includes('noopener noreferrer');
30
+ if (isOpenNewTab) {
31
+ a.setAttribute('target', '_blank');
32
+ }
33
+ });
34
+ }
35
+ }, [refMesage.current]);
16
36
  const isImageUrl = url => IMAGE_EXTENDS.some(tail => url && url.toLowerCase().endsWith(tail));
17
37
  const [images, files] = useMemo(() => {
18
38
  const arrImgs = [];
@@ -24,6 +24,7 @@ export declare const ANTALYSER_API: {
24
24
  production: string;
25
25
  };
26
26
  export declare const CDP_ROUTE: {
27
+ development: string;
27
28
  sandbox: string;
28
29
  "sandbox-cdp": string;
29
30
  staging: string;
@@ -28,6 +28,7 @@ export const ANTALYSER_API = {
28
28
  [ENV.PROD]: 'https://sandbox-antalyser.ants.vn',
29
29
  };
30
30
  export const CDP_ROUTE = {
31
+ [ENV.DEV]: 'https://sandbox-cdp.antsomi.com',
31
32
  [ENV.SANDBOX]: 'https://sandbox-cdp.antsomi.com',
32
33
  [ENV.SANDBOX_CDP]: 'https://sandbox-cdp.antsomi.com',
33
34
  [ENV.STAGING]: 'https://staging-cdp.antsomi.com',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antscorp/antsomi-ui",
3
- "version": "2.0.75",
3
+ "version": "2.0.76",
4
4
  "description": "An enterprise-class UI design language and React UI library.",
5
5
  "sideEffects": [
6
6
  "dist/*",