@antscorp/antsomi-ui 1.3.5-beta.782 → 1.3.5-beta.784

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.
@@ -7,6 +7,7 @@ import { useDeepCompareMemo } from '@antscorp/antsomi-ui/es/hooks/useDeepCompare
7
7
  import { useDebounce } from '@antscorp/antsomi-ui/es/hooks/useDebounce';
8
8
  import { useUpdateEffect } from '@antscorp/antsomi-ui/es/hooks/useUpdateEffect';
9
9
  import { useDeepCompareEffect } from '@antscorp/antsomi-ui/es/hooks/useDeepCompareEffect';
10
+ import { useSettingsTagify } from './hooks';
10
11
  // Components
11
12
  import Tagify from '@yaireo/tagify';
12
13
  // Css
@@ -14,15 +15,16 @@ import '@yaireo/tagify/dist/tagify.css';
14
15
  // Styled
15
16
  import { TagTextArea, TagifyWrapper, WrapperPlaceHolder } from './styled';
16
17
  // Utils
17
- import { parseTagStringToTagify, convertInputStringToOriginal, emojiManufacturer, getEmojiTag, } from './utils';
18
+ import { parseTagStringToTagify, convertInputStringToOriginal, emojiManufacturer, getEmojiTag, isPersonalizeTagType, } from './utils';
19
+ import { acceptablePatternChecking, getCachedRegex, getPersonalizeTagInfo, patternHandlers, } from './patternHandlers';
18
20
  // Constants
19
- import { EMOJI, defaultCssVariables, tagifyDefaultProps } from './constants';
21
+ import { EMOJI, PERSONALIZE_PTN, SHORT_LINK, defaultCssVariables, tagifyDefaultProps, } from './constants';
20
22
  const TagifyInput = forwardRef((props, ref) => {
21
23
  // Props
22
- const { value, readonly, maxLength, placeholder, acceptableTagPattern, mapAttributes, maxTags, name, children, cssTagifyVariables, onTagClick, onChange, } = props;
24
+ const { initialValue, readonly, disabled, maxLength, placeholder, acceptableTagPattern, mapAttributes, maxPersonalizeTags, name, children, cssTagifyVariables, onTagClick, onChange, } = props;
23
25
  console.count('------------ re-render ------------');
24
26
  // States
25
- const [inputTyping, , setInputTyping] = useDebounce(value, 450);
27
+ const [inputTypeDebounce, , setInputTyping] = useDebounce(initialValue, 450);
26
28
  // Refs
27
29
  const inputRef = useRef(null);
28
30
  const tagifyRef = useRef(null);
@@ -30,20 +32,22 @@ const TagifyInput = forwardRef((props, ref) => {
30
32
  const placeHolderRef = useRef(null);
31
33
  // Memoizations
32
34
  const cssVariablesMemoized = useMemo(() => _.assign({}, defaultCssVariables, cssTagifyVariables || {}), [cssTagifyVariables]);
33
- const parsedValue = useDeepCompareMemo(() => parseTagStringToTagify(value, acceptableTagPattern, mapAttributes), [value, acceptableTagPattern, mapAttributes]);
35
+ const parsedDefaultValue = useDeepCompareMemo(() => parseTagStringToTagify(initialValue, acceptableTagPattern), [initialValue, acceptableTagPattern]);
34
36
  // Expose some methods
35
37
  useImperativeHandle(ref, () => ({
36
38
  onAddNewTag: (newTag) => {
37
39
  if (newTag && tagifyRef.current) {
38
- const { settings } = tagifyRef.current;
39
- const { readonly } = settings;
40
+ const { settings, value: currentTags } = tagifyRef.current;
41
+ const { readonly, maxTags } = settings;
42
+ const currentPersonalizeTags = currentTags.filter(tag => ![EMOJI, SHORT_LINK].includes(tag.type));
43
+ const currentPersonalizeTagsLength = currentPersonalizeTags.length;
40
44
  // Check readonly
41
45
  if (readonly)
42
46
  return;
43
47
  // For case add new common emoji
44
48
  if (typeof newTag === 'string') {
45
49
  tagifyRef.current.injectAtCaret(newTag);
46
- // Need to reselect to keep the caret position
50
+ // Need to re-select to keep the caret position
47
51
  const selection = window.getSelection();
48
52
  if (selection?.rangeCount) {
49
53
  const range = selection.getRangeAt(0);
@@ -52,21 +56,26 @@ const TagifyInput = forwardRef((props, ref) => {
52
56
  }
53
57
  }
54
58
  else {
59
+ // In case add new common tag
55
60
  const { type } = newTag;
56
- // Add new tag
61
+ /*
62
+ * Validate the max limit before add new tag
63
+ * For emoji and short link, it will be passed
64
+ */
65
+ if (![EMOJI, SHORT_LINK].includes(type) &&
66
+ currentPersonalizeTagsLength >= maxTags)
67
+ return;
68
+ // Create new tag
57
69
  const newTagEle = tagifyRef.current.createTagElem(newTag);
70
+ // Add new tag
58
71
  tagifyRef.current.injectAtCaret(newTagEle);
59
72
  // Change data out before place the caret to keep valid caret positioning
60
73
  const inputValue = tagifyRef.current.getInputValue();
61
74
  const convertedValue = convertInputStringToOriginal(inputValue);
62
75
  onChange(convertedValue);
63
- if (type === EMOJI) {
64
- const elm = tagifyRef.current.insertAfterTag(newTagEle, '\u00A0'); // <- adds space after the tag
65
- tagifyRef.current.placeCaretAfterNode(elm);
66
- }
67
- else {
68
- tagifyRef.current.placeCaretAfterNode(newTagEle);
69
- }
76
+ // NOTE: place to refactor if not need to add space after the tag
77
+ const spaceEle = tagifyRef.current.insertAfterTag(newTagEle, '\u00A0'); // <- adds space after the tag
78
+ tagifyRef.current.placeCaretAfterNode(spaceEle);
70
79
  }
71
80
  }
72
81
  },
@@ -136,17 +145,19 @@ const TagifyInput = forwardRef((props, ref) => {
136
145
  templates: {
137
146
  tag: customizeTag,
138
147
  },
139
- maxTags,
140
- readonly,
141
148
  mode: 'mix',
142
- placeholder,
149
+ placeholder: 'Enter your text...',
143
150
  mixMode: {
144
151
  insertAfterTag: '', // Not insert anything after tag
145
152
  },
146
153
  tagTextProp: 'label', // Use `tagify.label` to display the tags
147
154
  enforceWhitelist: false, // Ensure that tags not in the whitelist can be added
148
155
  duplicates: true, // Allow duplicate tags
149
- editTags: false, // Allow tag editing
156
+ editTags: false, // Not allow tag editing
157
+ dropdown: {
158
+ enabled: false, // Do not display the dropdown
159
+ },
160
+ pattern: /^$a/, // -> using this regex never match any character to "prevent" add new tag when press enter
150
161
  hooks: {
151
162
  beforeKeyDown: (event, data) => {
152
163
  /*
@@ -174,7 +185,7 @@ const TagifyInput = forwardRef((props, ref) => {
174
185
  },
175
186
  });
176
187
  }
177
- }, [placeholder, readonly, maxTags, maxLength, customizeTag]);
188
+ }, [maxLength, customizeTag]);
178
189
  // Initialization tagify
179
190
  useLayoutEffect(() => {
180
191
  initializeTagify();
@@ -184,14 +195,53 @@ const TagifyInput = forwardRef((props, ref) => {
184
195
  }
185
196
  };
186
197
  }, [initializeTagify]);
187
- // Force refresh tags the tagify after the map attributes changes to show valid tags
198
+ // Settings some tagify attributes
199
+ useSettingsTagify(tagifyRef.current, {
200
+ disabled,
201
+ readonly,
202
+ maxPersonalizeTags,
203
+ placeholder,
204
+ });
205
+ /*
206
+ * Need to sync label of the tags if any map attribute is changed to make correct label
207
+ * */
188
208
  useDeepCompareEffect(() => {
189
209
  if (!_.isEmpty(mapAttributes) && tagifyRef.current) {
190
- const inputValue = tagifyRef.current?.getInputValue();
191
- console.count('----------- refresh tagify -----------');
192
- tagifyRef.current?.loadOriginalValues(inputValue);
210
+ const tagElements = tagifyRef.current.getTagElms();
211
+ const { pattern, name: cachePatternName, acceptablePattern: acceptableType, } = patternHandlers[PERSONALIZE_PTN];
212
+ tagElements.forEach(tagElement => {
213
+ const { __tagifyTagData: tagData } = tagElement;
214
+ if (tagData) {
215
+ const { type, value } = tagData;
216
+ const isPersonalTag = isPersonalizeTagType(type);
217
+ if (isPersonalTag && value) {
218
+ const isAccepted = acceptablePatternChecking(acceptableType, acceptableTagPattern);
219
+ // No need to continue if pattern is not accepted
220
+ if (!isAccepted)
221
+ return;
222
+ // Use the cached regex instead of creating a new one each time
223
+ const regex = getCachedRegex(pattern, 'g', cachePatternName);
224
+ let match;
225
+ // Iterate over matches of the current pattern
226
+ // eslint-disable-next-line no-cond-assign
227
+ while ((match = regex.exec(value)) !== null) {
228
+ const [, personalizeContent] = match;
229
+ const [tagCode] = personalizeContent.split('||');
230
+ const { label: tagLabel } = getPersonalizeTagInfo(tagCode, mapAttributes);
231
+ const tagTextNode = tagifyRef.current?.getTagTextNode(tagElement);
232
+ if (tagTextNode) {
233
+ /*
234
+ * Just only update to the correct text of the tag
235
+ * NOTE: Do not actually affect raw data
236
+ */
237
+ tagTextNode.textContent = tagLabel;
238
+ }
239
+ }
240
+ }
241
+ }
242
+ });
193
243
  }
194
- }, [mapAttributes]);
244
+ }, [mapAttributes, acceptableTagPattern]);
195
245
  // Listen to Tagify events
196
246
  useEffect(() => {
197
247
  const { current: tagifyInstance } = tagifyRef || {};
@@ -210,9 +260,9 @@ const TagifyInput = forwardRef((props, ref) => {
210
260
  };
211
261
  }, [onTagItemClick, onTagifyTyping, onTagifyRemoved]);
212
262
  useUpdateEffect(() => {
213
- const convertedValue = convertInputStringToOriginal(inputTyping);
263
+ const convertedValue = convertInputStringToOriginal(inputTypeDebounce);
214
264
  onChange(convertedValue);
215
- }, [inputTyping]);
265
+ }, [inputTypeDebounce]);
216
266
  useEffect(() => {
217
267
  if (!tagifyRef.current?.DOM.scope)
218
268
  return;
@@ -241,7 +291,7 @@ const TagifyInput = forwardRef((props, ref) => {
241
291
  }
242
292
  };
243
293
  }, []);
244
- return (_jsxs(TagifyWrapper, { ref: tagifyWrapperRef, "$cssTagifyVariables": cssVariablesMemoized, className: "tagify-container", id: "tagify-container", "data-test": "tagify-wrapper", children: [_jsx(TagTextArea, { id: "tagify-textarea", ref: inputRef, name: name, defaultValue: parsedValue, "data-test": "tagify-input" }), _jsx(WrapperPlaceHolder, { ref: placeHolderRef, "$isShow": !!children, children: children })] }));
294
+ return (_jsxs(TagifyWrapper, { ref: tagifyWrapperRef, "$cssTagifyVariables": cssVariablesMemoized, className: "tagify-container", id: "tagify-container", "data-test": "tagify-wrapper", children: [_jsx(TagTextArea, { id: "tagify-textarea", ref: inputRef, name: name, defaultValue: parsedDefaultValue, "data-test": "tagify-input" }), _jsx(WrapperPlaceHolder, { ref: placeHolderRef, "$isShow": !!children, children: children })] }));
245
295
  });
246
296
  TagifyInput.defaultProps = tagifyDefaultProps;
247
297
  export default memo(TagifyInput);
@@ -36,9 +36,10 @@ export const DEFAULT_ACCEPT_TAGS = [
36
36
  LINE_EMOJI_PTN,
37
37
  ];
38
38
  export const tagifyDefaultProps = {
39
- value: '',
39
+ initialValue: '',
40
40
  name: 'tagifyInput',
41
41
  readonly: false,
42
+ disabled: false,
42
43
  placeholder: undefined,
43
44
  acceptableTagPattern: DEFAULT_ACCEPT_TAGS,
44
45
  onChange: () => { },
@@ -1,6 +1,6 @@
1
- export const errorWrapper = (handler) => (match, mapAttributes) => {
1
+ export const errorWrapper = (handler) => match => {
2
2
  try {
3
- return handler(match, mapAttributes);
3
+ return handler(match);
4
4
  }
5
5
  catch (error) {
6
6
  // eslint-disable-next-line no-console
@@ -0,0 +1 @@
1
+ export * from './useSettingsTagify';
@@ -0,0 +1 @@
1
+ export * from './useSettingsTagify';
@@ -0,0 +1,7 @@
1
+ /// <reference types="yaireo__tagify" />
2
+ import Tagify from '@yaireo/tagify';
3
+ import type { TagDataCustomize, TagifyInputProps } from '../types';
4
+ type TagifyInstanceProps = Tagify<TagDataCustomize> | null;
5
+ type SettingsTagifyProps = Pick<TagifyInputProps, 'readonly' | 'disabled' | 'placeholder' | 'maxPersonalizeTags'>;
6
+ export declare const useSettingsTagify: (tagifyInstance: TagifyInstanceProps, settings: SettingsTagifyProps) => void;
7
+ export {};
@@ -0,0 +1,30 @@
1
+ /* eslint-disable react-hooks/exhaustive-deps */
2
+ // Libraries
3
+ import { useLayoutEffect } from 'react';
4
+ export const useSettingsTagify = (tagifyInstance, settings) => {
5
+ const { readonly, disabled, placeholder, maxPersonalizeTags } = settings;
6
+ // Set read only
7
+ useLayoutEffect(() => {
8
+ if (tagifyInstance && typeof readonly !== 'undefined') {
9
+ tagifyInstance.setReadonly(readonly);
10
+ }
11
+ }, [readonly]);
12
+ // Set disabled
13
+ useLayoutEffect(() => {
14
+ if (tagifyInstance && typeof disabled !== 'undefined') {
15
+ tagifyInstance.setDisabled(disabled);
16
+ }
17
+ }, [disabled]);
18
+ // Set placeholder
19
+ useLayoutEffect(() => {
20
+ if (tagifyInstance && typeof placeholder !== 'undefined') {
21
+ tagifyInstance.setPlaceholder(placeholder);
22
+ }
23
+ }, [placeholder]);
24
+ // Set max personalize tags
25
+ useLayoutEffect(() => {
26
+ if (tagifyInstance && typeof maxPersonalizeTags !== 'undefined') {
27
+ tagifyInstance.settings.maxTags = maxPersonalizeTags;
28
+ }
29
+ }, [maxPersonalizeTags]);
30
+ };
@@ -1,4 +1,4 @@
1
- import type { AcceptablePattern, PatterTagName, PatternHandlerWrapper } from './types';
1
+ import type { AcceptablePattern, MapAttributesProps, PatterTagName, PatternHandlerWrapper } from './types';
2
2
  /**
3
3
  * Retrieves a cached regular expression or compiles and caches it if not found.
4
4
  * @param pattern The regex pattern string.
@@ -10,4 +10,8 @@ export declare function getCachedRegex(pattern: string, flags?: string, cacheKey
10
10
  export declare const tagRegexStringPattern = "\\[\\[({.*?})\\]\\]";
11
11
  export declare function acceptablePatternChecking(pattern: AcceptablePattern, acceptablePattern: Array<AcceptablePattern>): boolean;
12
12
  export declare function validateURL(txt: string): boolean;
13
+ export declare const getPersonalizeTagInfo: (originalTag: string, mapAttributes?: MapAttributesProps) => {
14
+ label: string;
15
+ type: string;
16
+ };
13
17
  export declare const patternHandlers: Record<PatterTagName, PatternHandlerWrapper>;
@@ -38,7 +38,7 @@ export function validateURL(txt) {
38
38
  const regexUrl = getCachedRegex('^(https?:\\/\\/)?(([A-Za-z]{3,9}:)?(\\/\\/)?(?:[-;:&=+$,\\w]+@)?[A-Za-z0-9.-]+|(?:www\\.|[-;:&=+$,\\w]+@)[A-Za-z0-9.-]+)((\\/[+~%\\/\\.\\w-_]*)*(?:\\?[-+=&;%@\\.\\w_]*)?(#(?:[.!\\/\\\\\\w-]*)?)?)$', '', 'checkingURL');
39
39
  return regexUrl.test(txt);
40
40
  }
41
- const getPersonalizeTagInfo = (originalTag, mapAttributes) => {
41
+ export const getPersonalizeTagInfo = (originalTag, mapAttributes) => {
42
42
  try {
43
43
  const [type, attributeName] = originalTag.split('.');
44
44
  if (!mapAttributes || !mapAttributes[type]) {
@@ -87,7 +87,7 @@ const handleShortlinkIndividualPattern = match => {
87
87
  const tag = createTagPattern({
88
88
  label,
89
89
  type: SHORT_LINK,
90
- shortLinkType: SHORT_LINK_TYPE.INDIVIDUAL,
90
+ shortlinkType: SHORT_LINK_TYPE.INDIVIDUAL,
91
91
  value: fullMatch,
92
92
  });
93
93
  return { isValid, tag };
@@ -114,7 +114,7 @@ const handleShortlinkGeneralPattern = match => {
114
114
  const tag = createTagPattern({
115
115
  label,
116
116
  type: SHORT_LINK,
117
- shortLinkType: SHORT_LINK_TYPE.GENERAL,
117
+ shortlinkType: SHORT_LINK_TYPE.GENERAL,
118
118
  value: fullMatch,
119
119
  });
120
120
  return { isValid, tag };
@@ -140,17 +140,17 @@ const handleLinePattern = match => {
140
140
  /*
141
141
  * Function to handle generic of personalize #{...} pattern
142
142
  */
143
- const handlePersonalizeTagPattern = (match, mapAttributes) => {
143
+ const handlePersonalizeTagPattern = match => {
144
144
  const [personalizeTag, personalizeContent] = match;
145
145
  const [tagCode] = personalizeContent.split('||');
146
- const { label: tagLabel, type: tagType } = getPersonalizeTagInfo(tagCode, mapAttributes);
147
- if (!tagCode || !tagType) {
146
+ const [type, attributeName] = tagCode.split('.');
147
+ if (!tagCode || !type) {
148
148
  console.error('Invalid personalize pattern detected: ', tagCode);
149
149
  return { isValid: false, tag: '[[Invalid Personalize]]' };
150
150
  }
151
151
  const tag = createTagPattern({
152
- type: tagType,
153
- label: tagLabel,
152
+ type: type,
153
+ label: attributeName || type,
154
154
  value: personalizeTag,
155
155
  });
156
156
  return { isValid: true, tag };
@@ -9,10 +9,10 @@ export type MapAttributesProps = Record<string, Record<string, any>>;
9
9
  */
10
10
  export interface TagifyInputProps {
11
11
  /**
12
- * Represents the initial or current value of the Tagify input.
13
- * Typically used to populate the tags when the component is first rendered.
12
+ * Initial value for the Tagify input field.
13
+ * Only used when the component is first rendered.
14
14
  */
15
- value: string;
15
+ initialValue: string;
16
16
  /**
17
17
  * Optional mapping configuration for custom attributes associated with tags.
18
18
  * Defines how tag attributes are mapped and processed internally.
@@ -30,12 +30,13 @@ export interface TagifyInputProps {
30
30
  classNames?: ClassNameSettings;
31
31
  placeholder?: TagifySettings['placeholder'];
32
32
  readonly?: TagifySettings['readonly'];
33
+ disabled?: boolean;
33
34
  maxLength?: number;
34
35
  /**
35
36
  * Specifies the maximum number of tags that can be added to the input.
36
37
  * Helps enforce constraints by limiting the number of tags a user can input.
37
38
  */
38
- maxTags?: TagifySettings['maxTags'];
39
+ maxPersonalizeTags?: TagifySettings['maxTags'];
39
40
  /**
40
41
  * Defines acceptable patterns or validation rules for tags.
41
42
  * Ensures only tags matching specified patterns can be added, enforcing content rules.
@@ -84,7 +85,7 @@ interface TagDataEmoji extends Omit<TagDataText, 'type'> {
84
85
  interface TagDataShortLink extends Omit<TagDataText, 'type'> {
85
86
  value: string;
86
87
  type: Extract<TagType, 'shortlink'>;
87
- shortLinkType: ShortLinkType;
88
+ shortlinkType: ShortLinkType;
88
89
  }
89
90
  export type TagDataCustomize = TagDataEmoji | TagDataText | TagDataShortLink;
90
91
  export interface EmojiTag {
@@ -92,7 +93,7 @@ export interface EmojiTag {
92
93
  emoji: string;
93
94
  code: string;
94
95
  }
95
- export type PatternHandler = (match: RegExpExecArray, mapAttributes?: MapAttributesProps) => {
96
+ export type PatternHandler = (match: RegExpExecArray) => {
96
97
  isValid: boolean;
97
98
  tag: string;
98
99
  };
@@ -1,11 +1,11 @@
1
- import { AcceptablePattern, EmojiCollection, EmojiTag, MapAttributesProps } from './types';
1
+ import { AcceptablePattern, EmojiCollection, EmojiTag, TagType } from './types';
2
2
  /**
3
3
  * Parses the input string and replaces matching patterns with processed tags.
4
4
  * This function iterates over predefined regex patterns and replaces each match
5
5
  * with a corresponding replacement string generated by pattern handlers.
6
6
  *
7
7
  * @param {string} input - The input string containing tags and patterns to be replaced.
8
- * @param {MapAttributesProps} [mapAttributes] - Optional object containing additional attributes or configuration
8
+ * @param {Array<AcceptablePattern>} acceptableTagPattern - An array of acceptable tag patterns
9
9
  * passed to the pattern handler for tag processing.
10
10
  * @returns {string} The modified string with all pattern matches replaced by their corresponding tags.
11
11
  *
@@ -18,10 +18,11 @@ import { AcceptablePattern, EmojiCollection, EmojiTag, MapAttributesProps } from
18
18
  * Example:
19
19
  * ```javascript
20
20
  * const input = "Here is some text with a #{shortlink(https://example.com)} pattern.";
21
- * const result = parseTagStringToTagify(input);
21
+ * const acceptableTagPattern = ['shortlink'];
22
+ * const result = parseTagStringToTagify(input, acceptableTagPattern);
22
23
  * ```
23
24
  */
24
- export declare const parseTagStringToTagify: (input: string, acceptableTagPattern: Array<AcceptablePattern>, mapAttributes?: MapAttributesProps) => string;
25
+ export declare const parseTagStringToTagify: (input: string, acceptableTagPattern: Array<AcceptablePattern>) => string;
25
26
  /**
26
27
  * Converts an input string containing JSON-like tags to a formatted string.
27
28
  * @param input The input string with JSON-like tags.
@@ -43,3 +44,4 @@ export declare const getImageSourceViberEmoji: (fileName?: string) => any;
43
44
  export declare const emojiManufacturer: (text: string, collectionType: EmojiCollection) => string[];
44
45
  export declare const getEmojiTag: ({ src, emoji, code }: EmojiTag) => string;
45
46
  export declare const getStyledTags: () => string;
47
+ export declare const isPersonalizeTagType: (type: TagType) => boolean;
@@ -1,7 +1,7 @@
1
1
  // Libraries
2
2
  import stringReplaceToArray from 'string-replace-to-array';
3
3
  // Constants
4
- import { EMOJI, EMOJI_COLLECTIONS, PREFIX_PATTERN_LINE_MESSAGE, TAG_COLOR, TAG_TYPE, } from './constants';
4
+ import { CUSTOMER, CUSTOM_FN, EMOJI, EMOJI_COLLECTIONS, EVENT, OBJECT_WIDGET, PREFIX_PATTERN_LINE_MESSAGE, PROMOTION_CODE, TAG_COLOR, TAG_TYPE, VISITOR, } from './constants';
5
5
  import { iconsViber } from './iconsViber';
6
6
  // Utils
7
7
  import { acceptablePatternChecking, getCachedRegex, patternHandlers, tagRegexStringPattern, } from './patternHandlers';
@@ -11,7 +11,7 @@ import { acceptablePatternChecking, getCachedRegex, patternHandlers, tagRegexStr
11
11
  * with a corresponding replacement string generated by pattern handlers.
12
12
  *
13
13
  * @param {string} input - The input string containing tags and patterns to be replaced.
14
- * @param {MapAttributesProps} [mapAttributes] - Optional object containing additional attributes or configuration
14
+ * @param {Array<AcceptablePattern>} acceptableTagPattern - An array of acceptable tag patterns
15
15
  * passed to the pattern handler for tag processing.
16
16
  * @returns {string} The modified string with all pattern matches replaced by their corresponding tags.
17
17
  *
@@ -24,10 +24,11 @@ import { acceptablePatternChecking, getCachedRegex, patternHandlers, tagRegexStr
24
24
  * Example:
25
25
  * ```javascript
26
26
  * const input = "Here is some text with a #{shortlink(https://example.com)} pattern.";
27
- * const result = parseTagStringToTagify(input);
27
+ * const acceptableTagPattern = ['shortlink'];
28
+ * const result = parseTagStringToTagify(input, acceptableTagPattern);
28
29
  * ```
29
30
  */
30
- export const parseTagStringToTagify = (input, acceptableTagPattern, mapAttributes) => {
31
+ export const parseTagStringToTagify = (input, acceptableTagPattern) => {
31
32
  const resultParts = [];
32
33
  let lastIndex = 0;
33
34
  // Array to store all matches from all patterns with their positions
@@ -45,7 +46,7 @@ export const parseTagStringToTagify = (input, acceptableTagPattern, mapAttribute
45
46
  // Iterate over matches of the current pattern
46
47
  // eslint-disable-next-line no-cond-assign
47
48
  while ((match = regex.exec(input)) !== null) {
48
- const { isValid, tag } = handler(match, mapAttributes);
49
+ const { isValid, tag } = handler(match);
49
50
  if (isValid) {
50
51
  matches.push({ startIndex: match.index, endIndex: regex.lastIndex, replacement: tag });
51
52
  }
@@ -325,3 +326,4 @@ export const getStyledTags = () => {
325
326
  });
326
327
  return styledTags.join('');
327
328
  };
329
+ export const isPersonalizeTagType = (type) => [CUSTOMER, VISITOR, EVENT, PROMOTION_CODE, OBJECT_WIDGET, CUSTOM_FN].includes(type);
@@ -5,10 +5,9 @@ import { StyledNoData, StyldTitle, StyledRoot, TimelineBottom } from './styled';
5
5
  import { Flex, Spin } from '../../atoms';
6
6
  import { ItemEvent, TimeLineTitle, ItemGroupEvent } from './components';
7
7
  import { useInView } from 'react-intersection-observer';
8
- import { translate, translations } from '@antscorp/antsomi-ui/es/locales';
8
+ import { translate, translations } from '@antscorp/antsomi-locales';
9
9
  import { isEmpty } from 'lodash';
10
10
  import { differenceInMonths, formatDateTZ, startOfMonth, subMonths, } from '@antscorp/antsomi-ui/es/utils/date';
11
- import { getTranslateMessage } from '@antscorp/antsomi-ui/es/locales/i18n';
12
11
  import { EmptyData } from '../../molecules';
13
12
  export const ActivityTimeline = (props) => {
14
13
  const { timelines = [], isLoading = false, title = translate(translations._BLOCK_TIMELINE_CUS), timezone = Intl.DateTimeFormat().resolvedOptions().timeZone, objectName = '_THIS_PERSON_UPPERCASE', onFetchMore, eventTracking: eventTrackingProp = [], header, className, } = props;
@@ -92,7 +91,7 @@ export const ActivityTimeline = (props) => {
92
91
  return (_jsxs(_Fragment, { children: [header, _jsx(Flex, { style: { height: 240 }, align: "center", justify: "center", children: _jsx(Spin, { indicatorSize: 24 }) })] }));
93
92
  }
94
93
  if (!timelines.length) {
95
- return (_jsxs(_Fragment, { children: [header, _jsx(StyledNoData, { style: { height: 240 }, align: "center", justify: "center", children: _jsx(EmptyData, { showIcon: false, description: getTranslateMessage(translations.noData).toString() }) })] }));
94
+ return (_jsxs(_Fragment, { children: [header, _jsx(StyledNoData, { align: "center", justify: "center", children: _jsx(EmptyData, { showIcon: false, title: translate(translations._PROFILES_NO_DATA), description: translate(translations._PROFILES_MESSAGE_NO_DATA_TIMELINE).toString() }) })] }));
96
95
  }
97
96
  return (_jsxs(_Fragment, { children: [header, showMainContent(timelines, objectName), showBottomComponent()] }));
98
97
  };
@@ -14,10 +14,13 @@ export const ImgPanel = styled.div `
14
14
  height: 6.25rem;
15
15
  position: relative;
16
16
  border: 1px solid rgb(230, 230, 230);
17
+ border-radius: 10px;
18
+
17
19
  @media screen and (max-width: 767px) {
18
20
  width: 80px;
19
21
  height: 80px;
20
22
  }
23
+
21
24
  &:before {
22
25
  content: '';
23
26
  position: absolute;
@@ -42,9 +45,11 @@ export const ImgPanel = styled.div `
42
45
  }
43
46
  }
44
47
  }
48
+
45
49
  a {
46
50
  width: 100%;
47
51
  height: 100%;
52
+
48
53
  & > span {
49
54
  display: block;
50
55
  width: 100%;
@@ -80,15 +85,5 @@ export const LinkExtendTitle = styled(Typography.Link) `
80
85
  `;
81
86
  export const PlainCard = styled.div `
82
87
  font-size: 0.875rem;
83
-
84
- /* font-size: 0.75rem; */
85
-
86
88
  line-height: 1.25;
87
- /* &:last-of-type {
88
- /* margin-top: 2.375rem;
89
- margin-top: 3rem;
90
- @media screen and (max-width: 767px) {
91
- margin-top: 12px;
92
- }
93
- } */
94
89
  `;
@@ -1,11 +1,17 @@
1
1
  import { Flex } from 'antd';
2
2
  import styled from 'styled-components';
3
- export const StyledRoot = styled.div ``;
3
+ export const StyledRoot = styled.div `
4
+ display: flex;
5
+ flex-direction: column;
6
+ height: 100%;
7
+ `;
4
8
  export const StyldTitle = styled.div `
5
9
  font-size: 16px;
6
10
  font-weight: bold;
7
11
  `;
8
- export const StyledNoData = styled(Flex) ``;
12
+ export const StyledNoData = styled(Flex) `
13
+ height: 100%;
14
+ `;
9
15
  export const WrapperContainerRedeem = styled.div `
10
16
  display: flex;
11
17
  justify-content: space-between;
@@ -1060,6 +1060,7 @@
1060
1060
  "_TITL_DISPLAY_TIME_AS": "Display time as",
1061
1061
  "_TITL_DISPLAY_FUNCTION_OUTPUT": "Display function output",
1062
1062
  "_TITL_DOMAIN": "Domain",
1063
+ "_TITL_COOKIE_DOMAIN": "Cookie Domain",
1063
1064
  "_TITL_DOWNLOAD_DATA_EXAMPLE": "Download data example",
1064
1065
  "_TITL_DRAG_FILE_HERE": "Drag file here",
1065
1066
  "_TITL_DRAG_IMAGE_HERE": "Drag image here",
@@ -2121,7 +2122,7 @@
2121
2122
  "_PREDICT_MODEL_DESCRIBE_PLACEHOLDER": "Describe your RFM model",
2122
2123
  "_PREDICT_MODEL_BO_DISABLE": "Data-updated of this Business Object has been disabled",
2123
2124
  "_PREDICT_MODEL_CREATE_NEW_RFM": "Create new RFM",
2124
- "_DES_DELIVERY_INTERVAL": "Delivery Interval Setting",
2125
+ "_DES_DELIVERY_INTERVAL": "Delivery Interval",
2125
2126
  "_DES_BY_NUMBER_RECORD": "By number of record",
2126
2127
  "_DES_BY_DAY": "By day(s)",
2127
2128
  "_DES_BY_HOUR": "By hour(s)",
@@ -2612,12 +2613,12 @@
2612
2613
  "_PROFILES_WIDGET_1": "Customer information",
2613
2614
  "_PROFILES_WIDGET_2": "Item recommendation",
2614
2615
  "_PROFILES_WIDGET_3": "User activity",
2615
- "_PROFILES_WIDGET_4": "Visitor Information",
2616
+ "_PROFILES_WIDGET_4": "Visitor information",
2616
2617
  "_PROFILES_WIDGET_5": "Extended visualizations",
2617
2618
  "_PROFILES_SETTINGS_TAB": "Data",
2618
2619
  "_PROFILES_SETTINGS_1": "Avatar",
2619
2620
  "_PROFILES_SETTINGS_2": "Full name",
2620
- "_PROFILES_BTN_ADD_SOCIAL_GR": "Add Social Group",
2621
+ "_PROFILES_BTN_ADD_SOCIAL_GR": "Add social group",
2621
2622
  "_PROFILES_AUDIENCE_INFO_1": "Customer since",
2622
2623
  "_PROFILES_AUDIENCE_INFO_2": "Last activity",
2623
2624
  "_PROFILES_BTN_ADD_ATT": "Add attribute",
@@ -2628,5 +2629,18 @@
2628
2629
  "_PROFILES_BTN_SET_DEFAULT": "Set as default",
2629
2630
  "_PROFILES_DEFAULT_TEMP_TOOLTIP": "Default template",
2630
2631
  "_PROFILES_MESSAGE_NO_TEMP": "You don't have any templates to visualize profiles",
2631
- "_PROFILES_USER_GUIDE_2": "Click the button to create a template"
2632
+ "_PROFILES_USER_GUIDE_2": "Click the button to create a template",
2633
+ "_PROFILES_MESSAGE_NO_DATA_TIMELINE": "Modify the visualization to configure displayed events",
2634
+ "_PROFILES_MESSAGE_NO_DATA_INFOR": "Modify the visualization to configure displayed attributes",
2635
+ "_PROFILES_MESSAGE_NO_DATA_GROUP": "Please add attributes you want to display",
2636
+ "_PROFILES_ADD_EVENT": "Add event",
2637
+ "_COOKIE_DM_DEFINITION": "What is it?",
2638
+ "_COOKIE_DM_INSTRUCTION": "Instruction",
2639
+ "_COOKIE_DM_DEFINITION_1": "The cookie domain allows you to specify a domain where tracking cookies will be set, ensuring seamless data collection across subdomains. This helps maintain a consistent User ID, enabling accurate cross-subdomain tracking and preventing fragmented customer profiles. ",
2640
+ "_COOKIE_DM_DEFINITION_2": "By ensuring unified data collection, it enhances personalization, improves analytics, and provides a clearer view of customer behavior across your entire web ecosystem.",
2641
+ "_COOKIE_DM_INSTRUCTION_1_SUM": "Identify the Primary Domain: ",
2642
+ "_COOKIE_DM_INSTRUCTION_1_DES_1": "This is the base domain for all subdomains you want to track. ",
2643
+ "_COOKIE_DM_INSTRUCTION_1_DES_2": "Example: {{x}}",
2644
+ "_COOKIE_DM_INSTRUCTION_2_SUM": "Configure the Cookie Domain:",
2645
+ "_COOKIE_DM_INSTRUCTION_2_DES_1": "Input {{x}} to track data across all subdomains (eg: shop.antsomi.com or blog.antsomi.com)"
2632
2646
  }