@antscorp/antsomi-ui 1.3.6-beta.4 → 1.3.6-beta.41

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 (122) hide show
  1. package/es/components/atoms/Input/Input.d.ts +11 -17
  2. package/es/components/atoms/Input/Input.js +7 -11
  3. package/es/components/atoms/SelectAssociatedTag/constants.d.ts +1 -1
  4. package/es/components/atoms/SelectAssociatedTag/constants.js +4 -4
  5. package/es/components/atoms/Switch/Switch.js +2 -1
  6. package/es/components/icons/LazyIcon/LazyIcon.d.ts +3 -0
  7. package/es/components/icons/LazyIcon/LazyIcon.js +3 -0
  8. package/es/components/icons/TaskAltIcon.d.ts +3 -0
  9. package/es/components/icons/TaskAltIcon.js +7 -0
  10. package/es/components/icons/UnsubscribeIcon.d.ts +3 -0
  11. package/es/components/icons/UnsubscribeIcon.js +7 -0
  12. package/es/components/icons/UnsubscribersIcon.d.ts +3 -0
  13. package/es/components/icons/UnsubscribersIcon.js +7 -0
  14. package/es/components/icons/index.d.ts +3 -0
  15. package/es/components/icons/index.js +3 -0
  16. package/es/components/molecules/CodeStructure/CodeStructure.d.ts +23 -2
  17. package/es/components/molecules/CodeStructure/CodeStructure.js +136 -26
  18. package/es/components/molecules/CodeStructure/constants.js +2 -2
  19. package/es/components/molecules/CodeStructure/styled.d.ts +3 -0
  20. package/es/components/molecules/CodeStructure/styled.js +6 -0
  21. package/es/components/molecules/CodeStructure/type.d.ts +2 -2
  22. package/es/components/molecules/CodeStructure/type.js +2 -2
  23. package/es/components/molecules/CodeStructure/utils.d.ts +12 -2
  24. package/es/components/molecules/CodeStructure/utils.js +5 -3
  25. package/es/components/molecules/DrawerDetail/DrawerDetail.js +10 -5
  26. package/es/components/molecules/DrawerDetail/types.d.ts +1 -0
  27. package/es/components/molecules/Dropdown/style.scss +6 -4
  28. package/es/components/molecules/EditingListV2/EditingList.js +5 -2
  29. package/es/components/molecules/EditingListV2/components/List/List.js +16 -6
  30. package/es/components/molecules/EditingListV2/components/Loadable.d.ts +0 -6
  31. package/es/components/molecules/EditingListV2/components/Loadable.js +0 -1
  32. package/es/components/molecules/EditingListV2/components/Popover/Popover.js +6 -12
  33. package/es/components/molecules/EditingListV2/components/index.d.ts +0 -3
  34. package/es/components/molecules/EditingListV2/components/index.js +0 -3
  35. package/es/components/molecules/EditingListV2/types.d.ts +2 -0
  36. package/es/components/molecules/InputSelectAttribute/index.js +5 -2
  37. package/es/components/molecules/InputSelectAttribute/styled.js +7 -2
  38. package/es/components/molecules/SearchPopover/SearchPopover.d.ts +0 -1
  39. package/es/components/molecules/SearchPopover/SearchPopover.js +1 -2
  40. package/es/components/molecules/SearchPopover/components/PopoverAddField/PopoverAddField.js +2 -2
  41. package/es/components/molecules/SearchPopover/components/PopoverSelect/PopoverSelect.js +2 -2
  42. package/es/components/molecules/SearchPopover/types.d.ts +1 -0
  43. package/es/components/molecules/TagifyInput/TagifyInput.js +27 -10
  44. package/es/components/molecules/TagifyInput/constants.d.ts +2 -1
  45. package/es/components/molecules/TagifyInput/constants.js +2 -1
  46. package/es/components/molecules/TagifyInput/utils.js +5 -2
  47. package/es/components/molecules/TagifyInput/utils.style.js +3 -2
  48. package/es/components/molecules/UploadImage/index.d.ts +102 -3
  49. package/es/components/molecules/UploadImage/index.js +48 -110
  50. package/es/components/molecules/UploadImage/styled.d.ts +2 -1
  51. package/es/components/molecules/VirtualizedMenu/types.d.ts +1 -0
  52. package/es/components/organism/TicketEditorV2/Content.d.ts +27 -0
  53. package/es/components/organism/TicketEditorV2/Content.js +296 -0
  54. package/es/components/organism/TicketEditorV2/Service.d.ts +49 -0
  55. package/es/components/organism/TicketEditorV2/Service.js +58 -0
  56. package/es/components/organism/TicketEditorV2/TicketEditorV2.d.ts +20 -0
  57. package/es/components/organism/TicketEditorV2/TicketEditorV2.js +124 -0
  58. package/es/components/organism/TicketEditorV2/components/DropdownComponent.d.ts +9 -0
  59. package/es/components/organism/TicketEditorV2/components/DropdownComponent.js +45 -0
  60. package/es/components/organism/TicketEditorV2/components/Message.d.ts +2 -0
  61. package/es/components/organism/TicketEditorV2/components/Message.js +31 -0
  62. package/es/components/organism/TicketEditorV2/components/MessageComponent.d.ts +10 -0
  63. package/es/components/organism/TicketEditorV2/components/MessageComponent.js +64 -0
  64. package/es/components/organism/TicketEditorV2/components/icons/AddTicketIcon.d.ts +2 -0
  65. package/es/components/organism/TicketEditorV2/components/icons/AddTicketIcon.js +5 -0
  66. package/es/components/organism/TicketEditorV2/components/icons/TicketIcon.d.ts +2 -0
  67. package/es/components/organism/TicketEditorV2/components/icons/TicketIcon.js +5 -0
  68. package/es/components/organism/TicketEditorV2/constant.d.ts +17 -0
  69. package/es/components/organism/TicketEditorV2/constant.js +17 -0
  70. package/es/components/organism/TicketEditorV2/constants/index.d.ts +1 -0
  71. package/es/components/organism/TicketEditorV2/constants/index.js +1 -0
  72. package/es/components/organism/TicketEditorV2/constants/queryKeys.d.ts +5 -0
  73. package/es/components/organism/TicketEditorV2/constants/queryKeys.js +5 -0
  74. package/es/components/organism/TicketEditorV2/index.d.ts +1 -0
  75. package/es/components/organism/TicketEditorV2/index.js +1 -0
  76. package/es/components/organism/TicketEditorV2/queries/index.d.ts +3 -0
  77. package/es/components/organism/TicketEditorV2/queries/index.js +3 -0
  78. package/es/components/organism/TicketEditorV2/queries/useGetDetailTicket.d.ts +12 -0
  79. package/es/components/organism/TicketEditorV2/queries/useGetDetailTicket.js +14 -0
  80. package/es/components/organism/TicketEditorV2/queries/useGetListComments.d.ts +13 -0
  81. package/es/components/organism/TicketEditorV2/queries/useGetListComments.js +18 -0
  82. package/es/components/organism/TicketEditorV2/queries/useGetListUser.d.ts +11 -0
  83. package/es/components/organism/TicketEditorV2/queries/useGetListUser.js +14 -0
  84. package/es/components/organism/TicketEditorV2/styled.d.ts +54 -0
  85. package/es/components/organism/TicketEditorV2/styled.js +871 -0
  86. package/es/components/organism/TicketEditorV2/util.d.ts +46 -0
  87. package/es/components/organism/TicketEditorV2/util.js +408 -0
  88. package/es/components/organism/index.d.ts +1 -0
  89. package/es/components/organism/index.js +1 -0
  90. package/es/constants/queries.d.ts +1 -0
  91. package/es/constants/queries.js +1 -0
  92. package/es/locales/en/translation.json +2 -1
  93. package/es/locales/i18n.d.ts +2 -0
  94. package/es/locales/vi/translation.json +2 -1
  95. package/es/queries/ThirdParty/index.d.ts +1 -0
  96. package/es/queries/ThirdParty/index.js +1 -0
  97. package/es/queries/ThirdParty/useStoreSavedMedia.d.ts +1 -0
  98. package/es/queries/ThirdParty/useStoreSavedMedia.js +12 -0
  99. package/es/queries/index.d.ts +0 -1
  100. package/es/queries/index.js +0 -1
  101. package/es/services/MediaTemplateDesign/UploadFile/index.d.ts +1 -1
  102. package/es/services/MediaTemplateDesign/UploadFile/index.js +2 -2
  103. package/package.json +2 -2
  104. package/es/components/molecules/EditingListV2/components/Action/Action.d.ts +0 -6
  105. package/es/components/molecules/EditingListV2/components/Action/Action.js +0 -10
  106. package/es/components/molecules/EditingListV2/components/Action/index.d.ts +0 -1
  107. package/es/components/molecules/EditingListV2/components/Action/index.js +0 -1
  108. package/es/components/molecules/EditingListV2/components/Search/Search.d.ts +0 -4
  109. package/es/components/molecules/EditingListV2/components/Search/Search.js +0 -8
  110. package/es/components/molecules/EditingListV2/components/Search/index.d.ts +0 -1
  111. package/es/components/molecules/EditingListV2/components/Search/index.js +0 -1
  112. package/es/components/molecules/EditingListV2/components/Title/Title.d.ts +0 -9
  113. package/es/components/molecules/EditingListV2/components/Title/Title.js +0 -16
  114. package/es/components/molecules/EditingListV2/components/Title/index.d.ts +0 -1
  115. package/es/components/molecules/EditingListV2/components/Title/index.js +0 -1
  116. package/es/components/molecules/EditingListV2/styled.d.ts +0 -5
  117. package/es/components/molecules/EditingListV2/styled.js +0 -38
  118. package/es/components/molecules/SearchPopover/styles.scss +0 -7
  119. package/es/queries/Media/index.d.ts +0 -1
  120. package/es/queries/Media/index.js +0 -1
  121. package/es/queries/Media/useGetListingSavedMedia.d.ts +0 -12
  122. package/es/queries/Media/useGetListingSavedMedia.js +0 -15
@@ -18,8 +18,10 @@ export const generateRandomCodeWithConfig = ({ characterType, digitalNumbers, al
18
18
  else if (capitalization === CapitalizationType.LOWERCASE) {
19
19
  letterPart = letterPart.toLowerCase();
20
20
  }
21
- else if (capitalization === CapitalizationType.TITLE_CASE && letterPart.length > 0) {
22
- letterPart = letterPart.charAt(0).toUpperCase() + letterPart.slice(1).toLowerCase();
21
+ else if (capitalization === CapitalizationType.RANDOM) {
22
+ letterPart = Array.from(letterPart)
23
+ .map(char => (Math.random() < 0.5 ? char.toUpperCase() : char.toLowerCase()))
24
+ .join('');
23
25
  }
24
26
  // Order characters
25
27
  let finalCode = '';
@@ -46,7 +48,7 @@ export const generateCodeWithPrefixAndSuffix = (code, prefix, suffix, separator)
46
48
  finalCode = `${finalCode}${separator !== SeparatorType.NONE ? (separator === SeparatorType.HYPHEN ? '-' : separator === SeparatorType.DOT ? '.' : '_') : ''}${suffix}`;
47
49
  return finalCode;
48
50
  };
49
- export const calculateTotalCodes = (numberOfLetters, numberOfDigits, characterType) => {
51
+ export const calculateTotalCodes = ({ numberOfLetters, numberOfDigits, characterType, }) => {
50
52
  let totalCodes = 0;
51
53
  switch (characterType) {
52
54
  case CharacterType.LETTERS:
@@ -16,7 +16,7 @@ import { safeParseJson } from '@antscorp/antsomi-ui/es/utils';
16
16
  import { POST_MESSAGE_TYPES } from '@antscorp/antsomi-ui/es/constants';
17
17
  export const DrawerDetail = props => {
18
18
  // Props
19
- const { width, fullScreen: fullScreenProp = false, children, menuProps, closeIconProps, maxWidth, minWidth, defaultSize = 'max', headerProps, name, destroyOnClose = true, mask = false, classNames, onToggleCollapse, closable = false, ...restProps } = props;
19
+ const { width, fullScreen: fullScreenProp = false, children, menuProps, closeIconProps, maxWidth, minWidth, defaultSize = 'max', headerProps, name, destroyOnClose = true, mask = false, classNames, collapsed: propCollapsed, onToggleCollapse, closable = false, ...restProps } = props;
20
20
  const { show: showMenu = true, showExpandButton = true, showClose = true, items, selectedKeys, footer, onClick = () => { }, } = menuProps || {};
21
21
  const { children: headerChildren, ...restOfHeaderProps } = headerProps || {};
22
22
  const { onClose = () => { } } = props;
@@ -99,17 +99,22 @@ export const DrawerDetail = props => {
99
99
  }
100
100
  }
101
101
  }, [collapseDrawer, fullScreen, matchesSmallScreen, maxWidth, minWidth, width]);
102
- const handleToggleDrawerSize = () => {
102
+ const handleToggleDrawerSize = useCallback((updatedCollapsed) => {
103
103
  const localStorageValues = safeParseJson(localStorage.getItem(DRAWER_DETAIL_LOCAL_STORAGE_KEY), {});
104
- toggleCollapseDrawer(!collapseDrawer);
105
- onToggleCollapse?.(!collapseDrawer);
104
+ toggleCollapseDrawer(updatedCollapsed ?? !collapseDrawer);
105
+ onToggleCollapse?.(updatedCollapsed ?? !collapseDrawer);
106
106
  /**
107
107
  * Set local storage last collapsed
108
108
  */
109
109
  if (name) {
110
110
  localStorage.setItem(DRAWER_DETAIL_LOCAL_STORAGE_KEY, JSON.stringify({ ...localStorageValues, [name || '']: !collapseDrawer }));
111
111
  }
112
- };
112
+ }, [collapseDrawer, name, onToggleCollapse, toggleCollapseDrawer]);
113
+ useEffect(() => {
114
+ if (propCollapsed !== undefined) {
115
+ handleToggleDrawerSize(propCollapsed);
116
+ }
117
+ }, [propCollapsed, handleToggleDrawerSize]);
113
118
  return (_jsxs(StyledDrawer, { push: false, closable: closable, width: drawerWidth, motion: {
114
119
  visible: false,
115
120
  motionAppear: false,
@@ -14,6 +14,7 @@ export interface DrawerDetailProps extends Omit<DrawerProps, 'closeIcon' | 'titl
14
14
  classNames?: DrawerProps['classNames'] & {
15
15
  btnToogleSize?: string;
16
16
  };
17
+ collapsed?: boolean;
17
18
  onToggleCollapse?: (collapsed: boolean) => void;
18
19
  }
19
20
  export interface DrawerDetailCloseIconProps extends React.HtmlHTMLAttributes<HTMLDivElement> {
@@ -1,9 +1,11 @@
1
1
  .antsomi-input-dropdown-overlay {
2
- .antsomi-dropdown-menu {
3
- overflow: hidden;
2
+ &.antsomi-dropdown {
3
+ .antsomi-dropdown-menu {
4
+ overflow: hidden;
4
5
 
5
- :hover {
6
- overflow: auto;
6
+ &:hover {
7
+ overflow: auto;
8
+ }
7
9
  }
8
10
  }
9
11
  }
@@ -1,15 +1,18 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Libraries
2
3
  import { useMemo } from 'react';
4
+ // Components
3
5
  import { Suspense } from '../../atoms';
4
6
  import { ListItem, LazyComponent } from './components';
5
7
  const { Popover } = LazyComponent;
6
8
  export const EditingListV2 = (props) => {
7
- const { isLoading = false, addButtonLabel = 'Add', options = [], selected = [], removable = true, popupPlacement = 'right', className, onChange, } = props;
9
+ const { isLoading = false, addButtonLabel = 'Add', options = [], selected = [], removable = true, popupPlacement = 'leftBottom', className, onChange, } = props;
10
+ const popoverOptions = useMemo(() => options.filter(opt => !opt.errorMessage), [options]);
8
11
  const selectedOptions = useMemo(() => options.filter(opt => selected.includes(opt.key)), [selected, options]);
9
12
  // const isSelectAll = selectedOptions.length === options.length;
10
13
  const handleRemove = (removedKey) => {
11
14
  const selectedKeys = selectedOptions.filter(opt => opt.key !== removedKey).map(opt => opt.key);
12
15
  onChange?.(selectedKeys);
13
16
  };
14
- return (_jsxs("div", { className: className, children: [_jsx(ListItem, { isLoading: isLoading, selectOptions: selectedOptions, removable: removable, onClickRemove: handleRemove }), !isLoading && (_jsx(Suspense, { children: _jsx(Popover, { placement: popupPlacement, options: options, selected: selected, addButtonLabel: addButtonLabel, onChange: onChange }) }))] }));
17
+ return (_jsxs("div", { className: className, children: [_jsx(ListItem, { isLoading: isLoading, selectOptions: selectedOptions, removable: removable, onClickRemove: handleRemove }), !isLoading && (_jsx(Suspense, { children: _jsx(Popover, { placement: popupPlacement, options: popoverOptions, selected: selected, addButtonLabel: addButtonLabel, onChange: onChange }) }))] }));
15
18
  };
@@ -1,11 +1,15 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Spin, Typography } from '../../../../atoms';
2
+ // Libraries
3
+ import { useState } from 'react';
3
4
  import { isEmpty } from 'lodash';
4
- import { CLS } from '../../utils';
5
+ // Components
6
+ import { Spin, Typography, Tooltip } from '../../../../atoms';
5
7
  import { List } from 'antd';
6
- import { CloseIcon } from '@antscorp/antsomi-ui/es/components/icons';
8
+ import { CloseIcon, WarningIcon } from '@antscorp/antsomi-ui/es/components/icons';
9
+ // Utils
10
+ import { CLS } from '../../utils';
11
+ // Constants
7
12
  import { globalToken } from '@antscorp/antsomi-ui/es/constants';
8
- import { useState } from 'react';
9
13
  export const ListItem = (props) => {
10
14
  const { isLoading, selectOptions, onClickRemove, removable } = props;
11
15
  const [hover, setHover] = useState('');
@@ -18,6 +22,7 @@ export const ListItem = (props) => {
18
22
  const items = selectOptions.map(opt => ({
19
23
  className: CLS.ListItem.default,
20
24
  key: opt.key,
25
+ errorMessage: opt.errorMessage,
21
26
  label: renderLabel(opt.label),
22
27
  }));
23
28
  if (isLoading) {
@@ -29,10 +34,15 @@ export const ListItem = (props) => {
29
34
  return (_jsx(List, { dataSource: items, renderItem: item => (_jsxs(List.Item, { style: {
30
35
  display: 'flex',
31
36
  alignItems: 'center',
32
- border: '1px solid #B8CFE6',
37
+ border: `1px solid ${item.errorMessage ? '#EF3340' : '#B8CFE6'}`,
33
38
  borderRadius: '4px',
34
39
  padding: '10px',
35
40
  marginBottom: '10px',
36
41
  minHeight: '40px',
37
- }, onMouseEnter: () => setHover(item.key), onMouseLeave: () => setHover(''), children: [item.label, ' ', hover === item.key && removable && (_jsx(CloseIcon, { size: 18, color: globalToken?.bw8, style: { flexShrink: 0 }, onClick: onClickRemove ? () => onClickRemove(item.key) : undefined }))] })) }));
42
+ }, onMouseEnter: () => setHover(item.key), onMouseLeave: () => setHover(''), children: [item.label, _jsxs("div", { style: {
43
+ flexShrink: 0,
44
+ display: 'flex',
45
+ alignItems: 'center',
46
+ gap: '5px',
47
+ }, children: [item.errorMessage && (_jsx(Tooltip, { title: item.errorMessage, children: _jsx(WarningIcon, { size: 18 }) })), hover === item.key && removable && (_jsx(CloseIcon, { size: 18, color: globalToken?.bw8, style: { cursor: 'pointer' }, onClick: onClickRemove ? () => onClickRemove(item.key) : undefined }))] })] })) }));
38
48
  };
@@ -1,10 +1,4 @@
1
1
  /// <reference types="react" />
2
- export declare const Title: import("react").LazyExoticComponent<(props: {
3
- title: import("react").ReactNode;
4
- showNum: boolean;
5
- selectedAmount?: number | undefined;
6
- optionAmount?: number | undefined;
7
- }) => import("react/jsx-runtime").JSX.Element>;
8
2
  export declare const Popover: import("react").LazyExoticComponent<(props: {
9
3
  placement?: "leftTop" | "leftBottom" | "rightTop" | "rightBottom" | "left" | "right" | "bottom" | "top" | "bottomLeft" | "topLeft" | "topRight" | "bottomRight" | undefined;
10
4
  options: import("../types").Option[];
@@ -1,3 +1,2 @@
1
1
  import { lazy } from 'react';
2
- export const Title = lazy(() => import('./Title').then(module => ({ default: module.Title })));
3
2
  export const Popover = lazy(() => import('./Popover').then(module => ({ default: module.Popover })));
@@ -1,17 +1,11 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /* eslint-disable react/jsx-boolean-value */
3
+ // Components
2
4
  import { Button } from '@antscorp/antsomi-ui/es/components/atoms';
3
- import { AddIcon } from '../../../../icons';
4
5
  import { PopoverAddField } from '../../../SearchPopover';
6
+ // Icons
7
+ import { AddIcon } from '../../../../icons';
5
8
  export const Popover = (props) => {
6
9
  const { options, selected, addButtonLabel, onChange, placement } = props;
7
- return (_jsx(_Fragment, { children: _jsx(PopoverAddField, { style: { margin: 0 }, fields: options, placement: placement, selected: selected,
8
- // onApply={value =>
9
- // updateUnsubscribeSetting([
10
- // {
11
- // fieldPath: 'settings.unsubscribePreferences.preferenceListIds',
12
- // data: value as unknown as string,
13
- // },
14
- // ])
15
- // }
16
- onApply: onChange, children: _jsxs(Button, { type: "text", children: [_jsx(AddIcon, { size: 14 }), addButtonLabel] }) }) }));
10
+ return (_jsx(PopoverAddField, { style: { margin: 0, position: 'absolute', width: '300px' }, fields: options, placement: placement, selected: selected, onApply: onChange, isAllowEmpty: true, children: _jsxs(Button, { type: "text", children: [_jsx(AddIcon, { size: 14 }), addButtonLabel] }) }));
17
11
  };
@@ -1,6 +1,3 @@
1
1
  export { ListItem } from './List';
2
- export { Action } from './Action';
3
- export { Search } from './Search';
4
2
  export { Popover } from './Popover';
5
- export { Title } from './Title';
6
3
  export * as LazyComponent from './Loadable';
@@ -1,6 +1,3 @@
1
1
  export { ListItem } from './List';
2
- export { Action } from './Action';
3
- export { Search } from './Search';
4
2
  export { Popover } from './Popover';
5
- export { Title } from './Title';
6
3
  export * as LazyComponent from './Loadable';
@@ -2,6 +2,7 @@
2
2
  export type Option = {
3
3
  key: string;
4
4
  label: React.ReactNode;
5
+ errorMessage?: string;
5
6
  search?: string;
6
7
  };
7
8
  export type EditingListProps = {
@@ -14,5 +15,6 @@ export type EditingListProps = {
14
15
  isLoading?: boolean;
15
16
  emptyDescription?: string;
16
17
  removable?: boolean;
18
+ isAllowEmpty?: boolean;
17
19
  onChange?: (selected: string[]) => void;
18
20
  };
@@ -14,6 +14,7 @@ import { EmptyData } from '../EmptyData';
14
14
  import { Dashboard30Icon, ErrorIcon } from '../../icons';
15
15
  // Constants
16
16
  import { THEME } from '@antscorp/antsomi-ui/es/constants';
17
+ import { TAG_TYPE } from '../TagifyInput';
17
18
  const InputSelectAttribute = (props) => {
18
19
  const { value, errorMsg, label, isErrorTag, sourceOptions = [], mapCodeOptions = {}, onChange, } = props;
19
20
  const [form] = Form.useForm();
@@ -27,7 +28,7 @@ const InputSelectAttribute = (props) => {
27
28
  return [];
28
29
  }, [sourceValue, mapCodeOptions]);
29
30
  const initCodeTitleField = useMemo(() => {
30
- if (sourceValue === 'allocated_code') {
31
+ if (sourceValue === TAG_TYPE.PROMOTION_CODE) {
31
32
  return 'Allocated Code';
32
33
  }
33
34
  return upperFirst(translate(translations._ITEM_NAME_ATTRIBUTE, 'attribute'));
@@ -98,7 +99,9 @@ const InputSelectAttribute = (props) => {
98
99
  height: 32,
99
100
  padding: '4px 12px 4px 4px',
100
101
  borderBottom: `1px solid ${errorMsg ? THEME.token?.colorError : THEME.token?.blue1}`,
101
- }, children: [_jsx("div", { style: { width: '100%', cursor: 'pointer' }, onClick: onOpenModal, children: isObjValue && (_jsx(Tag, { isError: isErrorTag, children: isErrorTag ? (_jsxs(Flex, { gap: 5, align: "center", children: ["Unknown", _jsx(Tooltip, { title: "The used dynamic content is removed", children: _jsx(ErrorIcon, { size: 16 }) })] })) : (get(mapCodeBySource, [value?.code, 'label'], value?.code)) })) }), _jsx(Icon, { type: "icon-ants-remove", style: { fontSize: 10, color: '#222', cursor: 'pointer' }, onClick: onDeselect })] }));
102
+ }, children: [_jsx("div", { style: { width: '100%', cursor: 'pointer' }, onClick: onOpenModal, children: isObjValue && (_jsx(Tag, { isError: isErrorTag, children: isErrorTag ? (_jsxs(Flex, { gap: 5, align: "center", children: ["Unknown", _jsx(Tooltip, { title: "The used dynamic content is removed", children: _jsx(ErrorIcon, { size: 16 }) })] })) : (_jsx(Typography.Text, { ellipsis: {
103
+ tooltip: get(mapCodeBySource, [value?.code, 'label'], value?.code),
104
+ }, style: { maxWidth: 150 }, children: get(mapCodeBySource, [value?.code, 'label'], value?.code) })) })) }), _jsx(Icon, { type: "icon-ants-remove", style: { fontSize: 10, color: '#222', cursor: 'pointer' }, onClick: onDeselect })] }));
102
105
  }
103
106
  else {
104
107
  element = (_jsx(StyledSelect, { mode: "multiple", options: [{ value: '', label: 'Or select a field' }], notFoundContent: null, onSelect: onOpenModal, style: { width: '100%', borderTop: 'none', borderLeft: 'none', borderRight: 'none' }, onDeselect: onDeselect, autoClearSearchValue: false, searchValue: typeof value === 'string' ? value : '', onSearch: onChangeInput, status: errorMsg ? 'error' : undefined, placeholder: typeof value === 'string' ? value : translate(translations.inputYourValue.title), "$isPlaceholder": !value, "$isError": !!errorMsg, dropdownStyle: {
@@ -5,8 +5,13 @@ import { SelectV2 as Select } from '@antscorp/antsomi-ui/es/components/molecules
5
5
  // Constants
6
6
  import { THEME } from '@antscorp/antsomi-ui/es/constants';
7
7
  export const StyledSelect = styled(Select) `
8
- .antsomi-select-selection-search {
9
- width: fit-content !important;
8
+ .antsomi-select-selection-overflow .antsomi-select-selection-overflow-item {
9
+ flex: 1;
10
+
11
+ .antsomi-select-selection-search {
12
+ width: fit-content !important;
13
+ flex: 1;
14
+ }
10
15
  }
11
16
 
12
17
  ${({ $isError }) => $isError
@@ -1,3 +1,2 @@
1
- import './styles.scss';
2
1
  import { SearchPopoverProps } from './types';
3
2
  export declare const SearchPopover: (props: SearchPopoverProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,6 +1,5 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Popover } from 'antd';
3
- import './styles.scss';
4
3
  import clsx from 'clsx';
5
4
  import { StyledInput } from './styled';
6
5
  import { translate, translations } from '@antscorp/antsomi-ui/es/locales';
@@ -8,5 +7,5 @@ import { SearchIcon } from '../../icons';
8
7
  export const SearchPopover = (props) => {
9
8
  const { inputSearchProps = {}, ...popoverProps } = props;
10
9
  const { overlayClassName, arrow = false, children, content, trigger = ['click'], ...restPopoverProps } = popoverProps;
11
- return (_jsx(Popover, { trigger: trigger, arrow: arrow, destroyTooltipOnHide: true, ...restPopoverProps, overlayClassName: clsx('search-popover-overlay', overlayClassName), overlay: true, content: _jsxs(_Fragment, { children: [_jsx(StyledInput, { placeholder: inputSearchProps?.placeholder || `${translate(translations.global.search)}`, bordered: false, ...inputSearchProps, addonAfter: _jsx(SearchIcon, {}), withWrapper: false }), content] }), children: children }));
10
+ return (_jsx(Popover, { trigger: trigger, arrow: arrow, destroyTooltipOnHide: true, ...restPopoverProps, overlayClassName: clsx('no-padding-content', overlayClassName), overlay: true, content: _jsxs(_Fragment, { children: [_jsx(StyledInput, { placeholder: inputSearchProps?.placeholder || `${translate(translations.global.search)}`, bordered: false, ...inputSearchProps, addonAfter: _jsx(SearchIcon, {}), withWrapper: false }), content] }), children: children }));
12
11
  };
@@ -7,7 +7,7 @@ import { PopoverSelect } from '../PopoverSelect';
7
7
  import { Flex, Typography } from 'antd';
8
8
  import { IconField } from '@antscorp/antsomi-ui/es/components/atoms/IconField';
9
9
  export const PopoverAddField = (props) => {
10
- const { fields, onSearchPredicate, className, children, ...rest } = props;
10
+ const { fields, onSearchPredicate, className, children, isAllowEmpty, ...rest } = props;
11
11
  const originalFieldByKey = useMemo(() => new Map(fields.map(field => [field.key, field])), [fields]);
12
12
  const handleOnSearchPredicate = useCallback((option) => {
13
13
  const originalField = originalFieldByKey.get(option.key);
@@ -27,5 +27,5 @@ export const PopoverAddField = (props) => {
27
27
  selected: params.selected.includes(field.key),
28
28
  })] })),
29
29
  })), [fields]);
30
- return (_jsx(PopoverSelect, { ...rest, options: options, onSearchPredicate: handleOnSearchPredicate, className: clsx(className, 'ants-popover-add-fields'), children: children || (_jsxs(Button, { type: "text", children: [_jsx(Icon, { type: "icon-ants-plus-slim", size: 14 }), "Add fields"] })) }));
30
+ return (_jsx(PopoverSelect, { ...rest, options: options, onSearchPredicate: handleOnSearchPredicate, className: clsx(className, 'ants-popover-add-fields'), isAllowEmpty: isAllowEmpty || false, children: children || (_jsxs(Button, { type: "text", children: [_jsx(Icon, { type: "icon-ants-plus-slim", size: 14 }), "Add fields"] })) }));
31
31
  };
@@ -14,7 +14,7 @@ import { VirtualizedMenu } from '../../../VirtualizedMenu';
14
14
  import { ITEM_SIZE, ITEM_SPACING } from '../../../VirtualizedMenu/config';
15
15
  const { t } = i18nInstance;
16
16
  export const PopoverSelect = (props) => {
17
- const { open: openProp, selected, options: optionsProp = [], inputSearchProps = {}, children, showAllLabel = 'Show all', showSelectedLabel = 'Show selected', selectAllLabel = 'Select all', deselectAllLabel = 'Unselect all', menuProps = {}, onCancel, onApply, onSearchPredicate, ...rest } = props;
17
+ const { open: openProp, selected, options: optionsProp = [], inputSearchProps = {}, children, showAllLabel = 'Show all', showSelectedLabel = 'Show selected', selectAllLabel = 'Select all', deselectAllLabel = 'Unselect all', menuProps = {}, isAllowEmpty = false, onCancel, onApply, onSearchPredicate, ...rest } = props;
18
18
  const itemSize = menuProps.itemSize || ITEM_SIZE;
19
19
  const itemSpacing = menuProps.itemSpacing || ITEM_SPACING;
20
20
  const { value: searchValue, searchConfig, ...restInputSearchProps } = inputSearchProps;
@@ -26,7 +26,7 @@ export const PopoverSelect = (props) => {
26
26
  const [selectedKeys, setSelectedKeys] = useState(new Set());
27
27
  const [search, setSearch] = useState('');
28
28
  const [showSelected, setShowSelected] = useState(false);
29
- const applyDisabled = selectedKeys.size === 0;
29
+ const applyDisabled = selectedKeys.size === 0 && !isAllowEmpty;
30
30
  const options = useMemo(() => typeof optionsProp === 'function'
31
31
  ? optionsProp({ selected: [...selectedKeys] })
32
32
  : optionsProp, [optionsProp, selectedKeys]);
@@ -9,6 +9,7 @@ export type SearchPopoverProps = PropsWithChildren<{
9
9
  inputSearchProps?: InputProps & {
10
10
  searchConfig?: SearchConfig;
11
11
  };
12
+ isAllowEmpty?: boolean;
12
13
  } & PopoverProps>;
13
14
  export type Option = {
14
15
  key: string;
@@ -21,10 +21,10 @@ import { acceptablePatternChecking, detectURLRegex, getCachedRegex, getCustomTag
21
21
  // Constants
22
22
  import { DETECT_LINK, EMOJI, PERSONALIZE_PTN, SHORT_LINK, SHORT_LINK_PTN, SHORT_LINK_V2, TAG_TYPE, defaultCssVariables, tagifyDefaultProps, TAG_CUSTOM_ATTRIBUTES, } from './constants';
23
23
  const { CUSTOM_TAG } = TAG_TYPE;
24
- const { READONLY_TAG, INVALID_TAG, MESSAGE_TAG, FORCE_SHOW_TOOLTIP, ERROR_TAG, WARNING_TAG } = TAG_CUSTOM_ATTRIBUTES;
24
+ const { PREPARING_ST, INVALID_TAG, MESSAGE_TAG, FORCE_SHOW_TOOLTIP, ERROR_TAG, WARNING_TAG } = TAG_CUSTOM_ATTRIBUTES;
25
25
  const TagifyInput = forwardRef((props, ref) => {
26
26
  // Props
27
- const { initialValue, escapeHTML, status, readonly, readonlyTag, realtime, disabled, maxLength, maxHeight, minWidth, placeholder, minWidthPlaceholder, isSingleLineText, acceptableTagPattern, tagProperties = {}, mapAttributes = {}, mapErrorAttributes = {}, maxPersonalizeTags, name, children, cssTagifyVariables, onTagClick, onTagRemove, onChange, } = props;
27
+ const { initialValue, escapeHTML, status, readonly, readonlyTag, realtime, disabled, maxLength, maxHeight, minWidth, placeholder, minWidthPlaceholder, isSingleLineText, acceptableTagPattern, tagProperties, mapAttributes = {}, mapErrorAttributes = {}, maxPersonalizeTags, name, children, cssTagifyVariables, onTagClick, onTagRemove, onChange, } = props;
28
28
  // States
29
29
  const [isLineBreak, setIsLineBreak] = useState(hasLineBreak(initialValue));
30
30
  const [tooltipRefresher, setTooltipRefresher] = useState(1);
@@ -35,6 +35,7 @@ const TagifyInput = forwardRef((props, ref) => {
35
35
  const tagifyWrapperRef = useRef(null);
36
36
  const placeholderRef = useRef(null);
37
37
  const lastRange = useRef(null);
38
+ const tagLength = tagifyRef?.current?.getTagElms().length;
38
39
  // Memoizations
39
40
  const cssVariablesMemoized = useMemo(() => _.assign({}, defaultCssVariables, cssTagifyVariables || {}), [cssTagifyVariables]);
40
41
  // Only run in the first render
@@ -500,7 +501,11 @@ const TagifyInput = forwardRef((props, ref) => {
500
501
  case EMOJI: {
501
502
  closeIcon = '';
502
503
  const emojiPath = emojiManufacturer(value, collection);
503
- visibleTagContent = getEmojiTag({ src: emojiPath, emoji: label, code: value });
504
+ visibleTagContent = getEmojiTag({
505
+ src: emojiPath,
506
+ emoji: label,
507
+ code: value,
508
+ });
504
509
  break;
505
510
  }
506
511
  case DETECT_LINK: {
@@ -789,27 +794,28 @@ const TagifyInput = forwardRef((props, ref) => {
789
794
  }, [disabled, placeholder, readonly]);
790
795
  // Set readonly for each tag
791
796
  useEffect(() => {
792
- if (tagifyRef.current && typeof readonlyTag !== 'undefined') {
797
+ if (tagifyRef.current && tagLength && typeof readonlyTag !== 'undefined') {
793
798
  const tagElementList = tagifyRef.current.getTagElms();
794
799
  tagElementList.forEach((tagElement) => {
795
800
  const tagType = _.get(tagElement, '__tagifyTagData.type', '');
796
801
  const isPersonalizeTag = isPersonalizeTagType(tagType);
802
+ const isCustomTag = isCustomTagType(tagType);
797
803
  // Only support readonly for personalize tag
798
- if (!isPersonalizeTag)
804
+ if (!isPersonalizeTag && !isCustomTag)
799
805
  return;
800
806
  // Caution: Don't use readonly attribute -> readonly attribute Tagify library managed
801
807
  if (readonlyTag) {
802
- tagElement.setAttribute(READONLY_TAG, readonlyTag.toString());
808
+ tagElement.setAttribute(PREPARING_ST, readonlyTag.toString());
803
809
  }
804
810
  else {
805
811
  // Only remove readonly-tag attribute if the invalid attribute is not existing
806
812
  if (!tagElement.hasAttribute(INVALID_TAG)) {
807
- tagElement.removeAttribute(READONLY_TAG);
813
+ tagElement.removeAttribute(PREPARING_ST);
808
814
  }
809
815
  }
810
816
  });
811
817
  }
812
- }, [readonlyTag]);
818
+ }, [readonlyTag, tagLength]);
813
819
  // Set max personalize tags
814
820
  useLayoutEffect(() => {
815
821
  if (tagifyRef.current && typeof maxPersonalizeTags !== 'undefined') {
@@ -823,10 +829,10 @@ const TagifyInput = forwardRef((props, ref) => {
823
829
  makeValidLabelTags(mapAttributes, mapErrorAttributes);
824
830
  }, [mapAttributes, mapErrorAttributes, makeValidLabelTags]);
825
831
  useLayoutEffect(() => {
826
- if (tagProperties) {
832
+ if (tagProperties && tagLength) {
827
833
  executeTagProperties(tagProperties);
828
834
  }
829
- }, [tagProperties, executeTagProperties]);
835
+ }, [tagProperties, tagLength, executeTagProperties]);
830
836
  // Listen to Tagify events
831
837
  useEffect(() => {
832
838
  const { current: tagifyInstance } = tagifyRef || {};
@@ -874,18 +880,24 @@ const TagifyInput = forwardRef((props, ref) => {
874
880
  }
875
881
  // Convert the string to tagify pattern
876
882
  const content = parseTagStringToTagify(textValue, acceptableTagPattern);
883
+ setIsLineBreak(hasLineBreak(textValue));
877
884
  tagifyRef.current.loadOriginalValues(content);
878
885
  // Need to sync label of the tags if any map attribute is changed to make correct label
879
886
  makeValidLabelTags(mapAttributes, mapErrorAttributes);
887
+ if (tagProperties) {
888
+ executeTagProperties(tagProperties);
889
+ }
880
890
  }
881
891
  }
882
892
  }, [
883
893
  initialValue,
884
894
  mapAttributes,
895
+ tagProperties,
885
896
  mapErrorAttributes,
886
897
  escapeHTML,
887
898
  acceptableTagPattern,
888
899
  makeValidLabelTags,
900
+ executeTagProperties,
889
901
  ]);
890
902
  useEffect(() => {
891
903
  if (tagifyRef.current && initialValue === '') {
@@ -945,6 +957,11 @@ const TagifyInput = forwardRef((props, ref) => {
945
957
  }, []);
946
958
  useDeepCompareEffect(() => {
947
959
  const showTooltip = (tagElement) => {
960
+ const isTagReadonly = tagifyRef.current?.settings.readonly;
961
+ const tagType = tagElement.getAttribute('type');
962
+ // If tag is readonly and tag type is hint for link, do not show the tooltip
963
+ if (isTagReadonly && tagType === DETECT_LINK)
964
+ return;
948
965
  const tagRect = tagElement.getBoundingClientRect();
949
966
  const errorTag = tagElement.getAttribute(ERROR_TAG);
950
967
  const warningTag = tagElement.getAttribute(WARNING_TAG);
@@ -16,6 +16,7 @@ export declare const TAG_STATUS: {
16
16
  readonly DO_NOT_VIEW: "do-not-view";
17
17
  };
18
18
  export declare const TAG_CUSTOM_ATTRIBUTES: {
19
+ readonly PREPARING_ST: "preparing-setting";
19
20
  readonly READONLY_TAG: "readonly-tag";
20
21
  readonly INVALID_TAG: "invalid-tag";
21
22
  readonly REMOVED_TAG: "removed-tag";
@@ -28,7 +29,7 @@ export declare const TAG_CUSTOM_ATTRIBUTES: {
28
29
  readonly BG_COLOR_PERSONALIZE_TYPE: "bg-color-personalize-type";
29
30
  readonly BG_COLOR_PERSONALIZE_TYPE_V2: "bgColorPersonalizeType";
30
31
  };
31
- export declare const READONLY_TAG: "readonly-tag", INVALID_TAG: "invalid-tag", REMOVED_TAG: "removed-tag", NO_VIEW_TAG: "no-view-tag", MESSAGE_TAG: "message-tag", FORCE_SHOW_TOOLTIP: "force-show-tooltip", ERROR_TAG: "error-tag", WARNING_TAG: "warning-tag", PRIORITY_COLOR_TYPE: "priority-color-type", BG_COLOR_PERSONALIZE_TYPE: "bg-color-personalize-type", BG_COLOR_PERSONALIZE_TYPE_V2: "bgColorPersonalizeType";
32
+ export declare const PREPARING_ST: "preparing-setting", READONLY_TAG: "readonly-tag", INVALID_TAG: "invalid-tag", REMOVED_TAG: "removed-tag", NO_VIEW_TAG: "no-view-tag", MESSAGE_TAG: "message-tag", FORCE_SHOW_TOOLTIP: "force-show-tooltip", ERROR_TAG: "error-tag", WARNING_TAG: "warning-tag", PRIORITY_COLOR_TYPE: "priority-color-type", BG_COLOR_PERSONALIZE_TYPE: "bg-color-personalize-type", BG_COLOR_PERSONALIZE_TYPE_V2: "bgColorPersonalizeType";
32
33
  export declare const defaultCssVariables: {
33
34
  '--input-color': string | undefined;
34
35
  '--input-font-size': string;
@@ -17,6 +17,7 @@ export const TAG_STATUS = {
17
17
  DO_NOT_VIEW: 'do-not-view',
18
18
  };
19
19
  export const TAG_CUSTOM_ATTRIBUTES = {
20
+ PREPARING_ST: 'preparing-setting',
20
21
  READONLY_TAG: 'readonly-tag',
21
22
  INVALID_TAG: 'invalid-tag',
22
23
  REMOVED_TAG: 'removed-tag',
@@ -29,7 +30,7 @@ export const TAG_CUSTOM_ATTRIBUTES = {
29
30
  BG_COLOR_PERSONALIZE_TYPE: 'bg-color-personalize-type',
30
31
  BG_COLOR_PERSONALIZE_TYPE_V2: 'bgColorPersonalizeType',
31
32
  };
32
- export const { READONLY_TAG, INVALID_TAG, REMOVED_TAG, NO_VIEW_TAG, MESSAGE_TAG, FORCE_SHOW_TOOLTIP, ERROR_TAG, WARNING_TAG, PRIORITY_COLOR_TYPE, BG_COLOR_PERSONALIZE_TYPE, BG_COLOR_PERSONALIZE_TYPE_V2, } = TAG_CUSTOM_ATTRIBUTES;
33
+ export const { PREPARING_ST, READONLY_TAG, INVALID_TAG, REMOVED_TAG, NO_VIEW_TAG, MESSAGE_TAG, FORCE_SHOW_TOOLTIP, ERROR_TAG, WARNING_TAG, PRIORITY_COLOR_TYPE, BG_COLOR_PERSONALIZE_TYPE, BG_COLOR_PERSONALIZE_TYPE_V2, } = TAG_CUSTOM_ATTRIBUTES;
33
34
  export const defaultCssVariables = {
34
35
  '--input-color': globalToken?.colorText,
35
36
  '--input-font-size': `${globalToken?.fontSize}px`,
@@ -6,7 +6,7 @@ import { iconsViber } from './iconsViber';
6
6
  // Utils
7
7
  import { acceptablePatternChecking, detectURLRegex, getCachedRegex, patternHandlers, tagRegexStringPattern, } from './patternHandlers';
8
8
  const { CUSTOMER, VISITOR, EVENT, JOURNEY, CAMPAIGN, VARIANT, PROMOTION_CODE, CUSTOM_FN, OBJECT_WIDGET, CONTENT_SOURCE_GROUP, ALLOCATED_CODE, CUSTOM_TAG, } = TAG_TYPE;
9
- const { READONLY_TAG, INVALID_TAG, MESSAGE_TAG, ERROR_TAG, WARNING_TAG, PRIORITY_COLOR_TYPE, BG_COLOR_PERSONALIZE_TYPE, BG_COLOR_PERSONALIZE_TYPE_V2, } = TAG_CUSTOM_ATTRIBUTES;
9
+ const { PREPARING_ST, READONLY_TAG, INVALID_TAG, MESSAGE_TAG, ERROR_TAG, WARNING_TAG, PRIORITY_COLOR_TYPE, BG_COLOR_PERSONALIZE_TYPE, BG_COLOR_PERSONALIZE_TYPE_V2, } = TAG_CUSTOM_ATTRIBUTES;
10
10
  const { REMOVED, ARCHIVED, INACTIVE, INVALID, EXPIRED, WARNING, DO_NOT_VIEW, ERROR } = TAG_STATUS;
11
11
  /*
12
12
  * Custom error type for JSON parse errors
@@ -616,9 +616,12 @@ export function isTagClickable(tagify, tag, tagData) {
616
616
  return false;
617
617
  }
618
618
  const isValidType = isValidTagType(type);
619
+ const preparingSetting = tag.getAttribute(PREPARING_ST);
619
620
  const readonlyTag = tag.getAttribute(READONLY_TAG);
621
+ const isTagReadonly = readonlyTag && readonlyTag === 'true';
622
+ const isPreparingSetting = preparingSetting && preparingSetting === 'true';
620
623
  const { readonly } = tagify.settings;
621
- return !(readonly || (readonlyTag && readonlyTag === 'true') || !isValidType);
624
+ return !(readonly || isTagReadonly || isPreparingSetting || !isValidType);
622
625
  }
623
626
  /**
624
627
  * Finds text nodes within an HTML element that contain URLs.
@@ -3,7 +3,7 @@ import { css } from 'styled-components';
3
3
  import { isString } from 'lodash';
4
4
  // Constants
5
5
  import { globalToken } from '@antscorp/antsomi-ui/es/constants';
6
- import { DETECT_LINK, EMOJI, ERROR_TAG, MIN_H_WRAPPER, READONLY_TAG, SHORT_LINK, SHORT_LINK_TYPE, SHORT_LINK_V2, TAG_COLOR, TAG_H, TAG_TYPE, WARNING_TAG, TAG_TYPE_LIST, } from './constants';
6
+ import { DETECT_LINK, EMOJI, ERROR_TAG, MIN_H_WRAPPER, READONLY_TAG, SHORT_LINK, SHORT_LINK_TYPE, SHORT_LINK_V2, TAG_COLOR, TAG_H, TAG_TYPE, WARNING_TAG, TAG_TYPE_LIST, PREPARING_ST, } from './constants';
7
7
  export const getTagifyStyled = ({ $maxHeight, $tagifyFullWidth }) => css `
8
8
  ${$maxHeight &&
9
9
  css `
@@ -170,7 +170,8 @@ export const getTagifyTagStyled = (_wrapperProps) => css `
170
170
  height: fit-content;
171
171
  }
172
172
 
173
- &[${READONLY_TAG}='true'] {
173
+ &[${READONLY_TAG}='true'],
174
+ &[${PREPARING_ST}='true'] {
174
175
  cursor: not-allowed;
175
176
  }
176
177