@antscorp/antsomi-ui 2.0.57 → 2.0.59

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 (52) hide show
  1. package/es/components/icons/LazyIcon/LazyIcon.d.ts +3 -0
  2. package/es/components/icons/LazyIcon/LazyIcon.js +3 -0
  3. package/es/components/icons/TaskAltIcon.js +1 -1
  4. package/es/components/icons/UnsubscribeIcon.d.ts +3 -0
  5. package/es/components/icons/UnsubscribeIcon.js +7 -0
  6. package/es/components/icons/UnsubscribersIcon.d.ts +3 -0
  7. package/es/components/icons/UnsubscribersIcon.js +7 -0
  8. package/es/components/icons/index.d.ts +3 -0
  9. package/es/components/icons/index.js +3 -0
  10. package/es/components/molecules/EditingListV2/EditingList.d.ts +2 -0
  11. package/es/components/molecules/EditingListV2/EditingList.js +18 -0
  12. package/es/components/molecules/EditingListV2/components/List/List.d.ts +9 -0
  13. package/es/components/molecules/EditingListV2/components/List/List.js +48 -0
  14. package/es/components/molecules/EditingListV2/components/List/index.d.ts +1 -0
  15. package/es/components/molecules/EditingListV2/components/List/index.js +1 -0
  16. package/es/components/molecules/EditingListV2/components/Loadable.d.ts +8 -0
  17. package/es/components/molecules/EditingListV2/components/Loadable.js +2 -0
  18. package/es/components/molecules/EditingListV2/components/Popover/Popover.d.ts +11 -0
  19. package/es/components/molecules/EditingListV2/components/Popover/Popover.js +11 -0
  20. package/es/components/molecules/EditingListV2/components/Popover/index.d.ts +1 -0
  21. package/es/components/molecules/EditingListV2/components/Popover/index.js +1 -0
  22. package/es/components/molecules/EditingListV2/components/index.d.ts +3 -0
  23. package/es/components/molecules/EditingListV2/components/index.js +3 -0
  24. package/es/components/molecules/EditingListV2/index.d.ts +2 -0
  25. package/es/components/molecules/EditingListV2/index.js +1 -0
  26. package/es/components/molecules/EditingListV2/types.d.ts +20 -0
  27. package/es/components/molecules/EditingListV2/types.js +1 -0
  28. package/es/components/molecules/EditingListV2/utils.d.ts +27 -0
  29. package/es/components/molecules/EditingListV2/utils.js +28 -0
  30. package/es/components/molecules/SearchPopover/components/PopoverAddField/PopoverAddField.js +2 -2
  31. package/es/components/molecules/SearchPopover/components/PopoverSelect/PopoverSelect.js +4 -4
  32. package/es/components/molecules/SearchPopover/components/PopoverSelect/styled.js +1 -0
  33. package/es/components/molecules/SearchPopover/types.d.ts +1 -0
  34. package/es/components/molecules/UploadImage/index.d.ts +102 -2
  35. package/es/components/molecules/UploadImage/index.js +48 -73
  36. package/es/components/molecules/UploadImage/styled.d.ts +2 -1
  37. package/es/components/molecules/VirtualizedMenu/types.d.ts +1 -0
  38. package/es/components/molecules/index.d.ts +1 -0
  39. package/es/components/molecules/index.js +1 -0
  40. package/es/constants/queries.d.ts +1 -0
  41. package/es/constants/queries.js +1 -0
  42. package/es/constants/theme.js +3 -0
  43. package/es/locales/en/translation.json +2 -1
  44. package/es/locales/i18n.d.ts +2 -0
  45. package/es/locales/vi/translation.json +2 -1
  46. package/es/queries/ThirdParty/index.d.ts +1 -0
  47. package/es/queries/ThirdParty/index.js +1 -0
  48. package/es/queries/ThirdParty/useStoreSavedMedia.d.ts +1 -0
  49. package/es/queries/ThirdParty/useStoreSavedMedia.js +12 -0
  50. package/es/services/MediaTemplateDesign/UploadFile/index.d.ts +1 -1
  51. package/es/services/MediaTemplateDesign/UploadFile/index.js +2 -2
  52. package/package.json +1 -1
@@ -343,6 +343,7 @@ export declare const LazyIcon: {
343
343
  TabGroupIcon: import("react").LazyExoticComponent<import("react").ForwardRefExoticComponent<import("../types").IconProps & import("react").RefAttributes<SVGSVGElement>>>;
344
344
  TableIcon: import("react").LazyExoticComponent<import("react").ForwardRefExoticComponent<import("../types").IconProps & import("react").RefAttributes<SVGSVGElement>>>;
345
345
  TableVer2Icon: import("react").LazyExoticComponent<import("react").ForwardRefExoticComponent<import("../types").IconProps & import("react").RefAttributes<SVGSVGElement>>>;
346
+ TaskAltIcon: import("react").LazyExoticComponent<import("react").ForwardRefExoticComponent<import("../types").IconProps & import("react").RefAttributes<SVGSVGElement>>>;
346
347
  TextIcon: import("react").LazyExoticComponent<import("react").ForwardRefExoticComponent<import("../types").IconProps & import("react").RefAttributes<SVGSVGElement>>>;
347
348
  ThirdPartyPluginV130Icon: import("react").LazyExoticComponent<import("react").ForwardRefExoticComponent<import("../types").IconProps & import("react").RefAttributes<SVGSVGElement>>>;
348
349
  ThirdPartyPluginV230Icon: import("react").LazyExoticComponent<import("react").ForwardRefExoticComponent<import("../types").IconProps & import("react").RefAttributes<SVGSVGElement>>>;
@@ -357,6 +358,8 @@ export declare const LazyIcon: {
357
358
  UnblockIcon: import("react").LazyExoticComponent<import("react").ForwardRefExoticComponent<import("../types").IconProps & import("react").RefAttributes<SVGSVGElement>>>;
358
359
  UndoIcon: import("react").LazyExoticComponent<import("react").ForwardRefExoticComponent<import("../types").IconProps & import("react").RefAttributes<SVGSVGElement>>>;
359
360
  Unknown30Icon: import("react").LazyExoticComponent<import("react").ForwardRefExoticComponent<import("../types").IconProps & import("react").RefAttributes<SVGSVGElement>>>;
361
+ UnsubscribersIcon: import("react").LazyExoticComponent<import("react").ForwardRefExoticComponent<import("../types").IconProps & import("react").RefAttributes<SVGSVGElement>>>;
362
+ UnsubscribeIcon: import("react").LazyExoticComponent<import("react").ForwardRefExoticComponent<import("../types").IconProps & import("react").RefAttributes<SVGSVGElement>>>;
360
363
  UploadIcon: import("react").LazyExoticComponent<import("react").ForwardRefExoticComponent<import("../types").IconProps & import("react").RefAttributes<SVGSVGElement>>>;
361
364
  UploadMenuIcon: import("react").LazyExoticComponent<import("react").ForwardRefExoticComponent<import("../types").IconProps & import("react").RefAttributes<SVGSVGElement>>>;
362
365
  UserActivityIcon: import("react").LazyExoticComponent<import("react").ForwardRefExoticComponent<import("../types").IconProps & import("react").RefAttributes<SVGSVGElement>>>;
@@ -349,6 +349,7 @@ export const LazyIcon = {
349
349
  TabGroupIcon: lazy(() => import('../TabGroupIcon').then(m => ({ default: m.TabGroupIcon }))),
350
350
  TableIcon: lazy(() => import('../TableIcon').then(m => ({ default: m.TableIcon }))),
351
351
  TableVer2Icon: lazy(() => import('../TableVer2Icon').then(m => ({ default: m.TableVer2Icon }))),
352
+ TaskAltIcon: lazy(() => import('../TaskAltIcon').then(m => ({ default: m.TaskAltIcon }))),
352
353
  TextIcon: lazy(() => import('../TextIcon').then(m => ({ default: m.TextIcon }))),
353
354
  ThirdPartyPluginV130Icon: lazy(() => import('../ThirdPartyPluginV130Icon').then(m => ({ default: m.ThirdPartyPluginV130Icon }))),
354
355
  ThirdPartyPluginV230Icon: lazy(() => import('../ThirdPartyPluginV230Icon').then(m => ({ default: m.ThirdPartyPluginV230Icon }))),
@@ -363,6 +364,8 @@ export const LazyIcon = {
363
364
  UnblockIcon: lazy(() => import('../UnblockIcon').then(m => ({ default: m.UnblockIcon }))),
364
365
  UndoIcon: lazy(() => import('../UndoIcon').then(m => ({ default: m.UndoIcon }))),
365
366
  Unknown30Icon: lazy(() => import('../Unknown30Icon').then(m => ({ default: m.Unknown30Icon }))),
367
+ UnsubscribersIcon: lazy(() => import('../UnsubscribersIcon').then(m => ({ default: m.UnsubscribersIcon }))),
368
+ UnsubscribeIcon: lazy(() => import('../UnsubscribeIcon').then(m => ({ default: m.UnsubscribeIcon }))),
366
369
  UploadIcon: lazy(() => import('../UploadIcon').then(m => ({ default: m.UploadIcon }))),
367
370
  UploadMenuIcon: lazy(() => import('../UploadMenuIcon').then(m => ({ default: m.UploadMenuIcon }))),
368
371
  UserActivityIcon: lazy(() => import('../UserActivityIcon').then(m => ({ default: m.UserActivityIcon }))),
@@ -3,5 +3,5 @@ import { forwardRef } from 'react';
3
3
  import { useIcon } from './hooks/useIcon';
4
4
  export const TaskAltIcon = forwardRef((props, ref) => {
5
5
  const { width, height } = useIcon(props);
6
- return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 -960 960 960", fill: "#fff", ...props, ref: ref, width: width, height: height, children: _jsx("path", { d: "M480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q65 0 123 19t107 53l-58 59q-38-24-81-37.5T480-800q-133 0-226.5 93.5T160-480q0 133 93.5 226.5T480-160q133 0 226.5-93.5T800-480q0-18-2-36t-6-35l65-65q11 32 17 66t6 70q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm-56-216L254-466l56-56 114 114 400-401 56 56-456 457Z" }) }));
6
+ return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 -960 960 960", fill: "currentColor", ...props, ref: ref, width: width, height: height, children: _jsx("path", { d: "M480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q65 0 123 19t107 53l-58 59q-38-24-81-37.5T480-800q-133 0-226.5 93.5T160-480q0 133 93.5 226.5T480-160q133 0 226.5-93.5T800-480q0-18-2-36t-6-35l65-65q11 32 17 66t6 70q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm-56-216L254-466l56-56 114 114 400-401 56 56-456 457Z" }) }));
7
7
  });
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { IconProps } from './types';
3
+ export declare const UnsubscribeIcon: React.ForwardRefExoticComponent<IconProps & React.RefAttributes<SVGSVGElement>>;
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from 'react';
3
+ import { useIcon } from './hooks/useIcon';
4
+ export const UnsubscribeIcon = forwardRef((props, ref) => {
5
+ const { width, height } = useIcon(props);
6
+ return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 -960 960 960", fill: "currentColor", ...props, ref: ref, width: width, height: height, children: _jsx("path", { d: "M480-440 160-640v400h320q0 21 3 40.5t9 39.5H160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h640q33 0 56.5 23.5T880-720v228q-18-9-38.5-15t-41.5-9v-124L480-440Zm0-80 320-200H160l320 200ZM760-40q-83 0-141.5-58.5T560-240q0-83 58.5-141.5T760-440q83 0 141.5 58.5T960-240q0 83-58.5 141.5T760-40ZM640-220h240v-40H640v40Zm-480-20v-480 480Z" }) }));
7
+ });
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { IconProps } from './types';
3
+ export declare const UnsubscribersIcon: React.ForwardRefExoticComponent<IconProps & React.RefAttributes<SVGSVGElement>>;
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from 'react';
3
+ import { useIcon } from './hooks/useIcon';
4
+ export const UnsubscribersIcon = forwardRef((props, ref) => {
5
+ const { width, height } = useIcon(props);
6
+ return (_jsx("svg", { viewBox: "0 0 30 30", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props, ref: ref, width: width, height: height, children: _jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M16.2695 20.3125C16.2695 21.3145 16.4839 22.2665 16.8693 23.125H2.5V21.8945L5.01953 19.375V13.1641C5.01953 11.2109 5.50781 9.51172 6.48438 8.06641C7.5 6.62109 8.88672 5.68359 10.6445 5.25391V4.375C10.6445 3.86719 10.8203 3.4375 11.1719 3.08594C11.5234 2.69531 11.9727 2.5 12.5195 2.5C13.0664 2.5 13.5156 2.69531 13.8672 3.08594C14.2188 3.4375 14.3945 3.86719 14.3945 4.375V5.25391C16.1523 5.68359 17.5195 6.62109 18.4961 8.06641C19.5117 9.51172 20.0195 11.2109 20.0195 13.1641V14.1871C17.7935 15.3251 16.2695 17.6408 16.2695 20.3125ZM12.5195 26.875C11.8164 26.875 11.2109 26.6406 10.7031 26.1719C10.2344 25.7031 10 25.1172 10 24.4141H15.0391C15.0391 25.0781 14.7852 25.6641 14.2773 26.1719C13.7695 26.6406 13.1836 26.875 12.5195 26.875ZM28.7695 20.3125C28.7695 23.4191 26.2511 25.9375 23.1445 25.9375C20.0379 25.9375 17.5195 23.4191 17.5195 20.3125C17.5195 17.2059 20.0379 14.6875 23.1445 14.6875C26.2511 14.6875 28.7695 17.2059 28.7695 20.3125ZM26.2695 19.6875V20.9375H20.0195V19.6875H26.2695Z", fill: "currentColor" }) }));
7
+ });
@@ -339,6 +339,7 @@ export { SystemRunningIcon } from './SystemRunningIcon';
339
339
  export { TabGroupIcon } from './TabGroupIcon';
340
340
  export { TableIcon } from './TableIcon';
341
341
  export { TableVer2Icon } from './TableVer2Icon';
342
+ export { TaskAltIcon } from './TaskAltIcon';
342
343
  export { TextIcon } from './TextIcon';
343
344
  export { ThirdPartyPluginV130Icon } from './ThirdPartyPluginV130Icon';
344
345
  export { ThirdPartyPluginV230Icon } from './ThirdPartyPluginV230Icon';
@@ -353,6 +354,8 @@ export { TipsIdeaLight30Icon } from './TipsIdeaLight30Icon';
353
354
  export { UnblockIcon } from './UnblockIcon';
354
355
  export { UndoIcon } from './UndoIcon';
355
356
  export { Unknown30Icon } from './Unknown30Icon';
357
+ export { UnsubscribersIcon } from './UnsubscribersIcon';
358
+ export { UnsubscribeIcon } from './UnsubscribeIcon';
356
359
  export { UploadIcon } from './UploadIcon';
357
360
  export { UploadMenuIcon } from './UploadMenuIcon';
358
361
  export { UserActivityIcon } from './UserActivityIcon';
@@ -339,6 +339,7 @@ export { SystemRunningIcon } from './SystemRunningIcon';
339
339
  export { TabGroupIcon } from './TabGroupIcon';
340
340
  export { TableIcon } from './TableIcon';
341
341
  export { TableVer2Icon } from './TableVer2Icon';
342
+ export { TaskAltIcon } from './TaskAltIcon';
342
343
  export { TextIcon } from './TextIcon';
343
344
  export { ThirdPartyPluginV130Icon } from './ThirdPartyPluginV130Icon';
344
345
  export { ThirdPartyPluginV230Icon } from './ThirdPartyPluginV230Icon';
@@ -353,6 +354,8 @@ export { TipsIdeaLight30Icon } from './TipsIdeaLight30Icon';
353
354
  export { UnblockIcon } from './UnblockIcon';
354
355
  export { UndoIcon } from './UndoIcon';
355
356
  export { Unknown30Icon } from './Unknown30Icon';
357
+ export { UnsubscribersIcon } from './UnsubscribersIcon';
358
+ export { UnsubscribeIcon } from './UnsubscribeIcon';
356
359
  export { UploadIcon } from './UploadIcon';
357
360
  export { UploadMenuIcon } from './UploadMenuIcon';
358
361
  export { UserActivityIcon } from './UserActivityIcon';
@@ -0,0 +1,2 @@
1
+ import { EditingListProps } from './types';
2
+ export declare const EditingListV2: (props: EditingListProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Libraries
3
+ import { useMemo } from 'react';
4
+ // Components
5
+ import { Suspense } from '../../atoms';
6
+ import { ListItem, LazyComponent } from './components';
7
+ const { Popover } = LazyComponent;
8
+ export const EditingListV2 = (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]);
11
+ const selectedOptions = useMemo(() => options.filter(opt => selected.includes(opt.key)), [selected, options]);
12
+ // const isSelectAll = selectedOptions.length === options.length;
13
+ const handleRemove = (removedKey) => {
14
+ const selectedKeys = selectedOptions.filter(opt => opt.key !== removedKey).map(opt => opt.key);
15
+ onChange?.(selectedKeys);
16
+ };
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 }) }))] }));
18
+ };
@@ -0,0 +1,9 @@
1
+ import { Option } from '../../types';
2
+ type ListProps = {
3
+ isLoading: boolean;
4
+ selectOptions: Option[];
5
+ removable?: boolean;
6
+ onClickRemove?: (key: string) => void;
7
+ };
8
+ export declare const ListItem: (props: ListProps) => import("react/jsx-runtime").JSX.Element | undefined;
9
+ export {};
@@ -0,0 +1,48 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Libraries
3
+ import { useState } from 'react';
4
+ import { isEmpty } from 'lodash';
5
+ // Components
6
+ import { Spin, Typography, Tooltip } from '../../../../atoms';
7
+ import { List } from 'antd';
8
+ import { CloseIcon, WarningIcon } from '@antscorp/antsomi-ui/es/components/icons';
9
+ // Utils
10
+ import { CLS } from '../../utils';
11
+ // Constants
12
+ import { globalToken } from '@antscorp/antsomi-ui/es/constants';
13
+ export const ListItem = (props) => {
14
+ const { isLoading, selectOptions, onClickRemove, removable } = props;
15
+ const [hover, setHover] = useState('');
16
+ const renderLabel = (label) => {
17
+ if (typeof label === 'string') {
18
+ return _jsx(Typography.Text, { ellipsis: { tooltip: true }, children: label });
19
+ }
20
+ return label;
21
+ };
22
+ const items = selectOptions.map(opt => ({
23
+ className: CLS.ListItem.default,
24
+ key: opt.key,
25
+ errorMessage: opt.errorMessage,
26
+ label: renderLabel(opt.label),
27
+ }));
28
+ if (isLoading) {
29
+ return _jsx(Spin, { indicatorSize: 24 });
30
+ }
31
+ if (isEmpty(selectOptions)) {
32
+ return;
33
+ }
34
+ return (_jsx(List, { dataSource: items, renderItem: item => (_jsxs(List.Item, { style: {
35
+ display: 'flex',
36
+ alignItems: 'center',
37
+ border: `1px solid ${item.errorMessage ? '#EF3340' : '#B8CFE6'}`,
38
+ borderRadius: '4px',
39
+ padding: '10px',
40
+ marginBottom: '10px',
41
+ minHeight: '40px',
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 }))] })] })) }));
48
+ };
@@ -0,0 +1 @@
1
+ export { ListItem } from './List';
@@ -0,0 +1 @@
1
+ export { ListItem } from './List';
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+ export declare const Popover: import("react").LazyExoticComponent<(props: {
3
+ placement?: "leftTop" | "leftBottom" | "rightTop" | "rightBottom" | "left" | "right" | "bottom" | "top" | "bottomLeft" | "bottomRight" | "topLeft" | "topRight" | undefined;
4
+ options: import("../types").Option[];
5
+ selected: string[];
6
+ addButtonLabel: import("react").ReactNode;
7
+ onChange?: ((selected: string[]) => void) | undefined;
8
+ }) => import("react/jsx-runtime").JSX.Element>;
@@ -0,0 +1,2 @@
1
+ import { lazy } from 'react';
2
+ export const Popover = lazy(() => import('./Popover').then(module => ({ default: module.Popover })));
@@ -0,0 +1,11 @@
1
+ /// <reference types="react" />
2
+ import { Option } from '../../types';
3
+ type PopoverProps = {
4
+ placement?: 'left' | 'right' | 'top' | 'bottom' | 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'leftTop' | 'leftBottom' | 'rightTop' | 'rightBottom';
5
+ options: Option[];
6
+ selected: string[];
7
+ addButtonLabel: React.ReactNode;
8
+ onChange?: (selected: string[]) => void;
9
+ };
10
+ export declare const Popover: (props: PopoverProps) => import("react/jsx-runtime").JSX.Element;
11
+ export {};
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /* eslint-disable react/jsx-boolean-value */
3
+ // Components
4
+ import { Button } from '@antscorp/antsomi-ui/es/components/atoms';
5
+ import { PopoverAddField } from '../../../SearchPopover';
6
+ // Icons
7
+ import { AddIcon } from '../../../../icons';
8
+ export const Popover = (props) => {
9
+ const { options, selected, addButtonLabel, onChange, placement } = props;
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", style: { gap: 2 }, children: [_jsx(AddIcon, { size: 14 }), addButtonLabel] }) }));
11
+ };
@@ -0,0 +1 @@
1
+ export { Popover } from './Popover';
@@ -0,0 +1 @@
1
+ export { Popover } from './Popover';
@@ -0,0 +1,3 @@
1
+ export { ListItem } from './List';
2
+ export { Popover } from './Popover';
3
+ export * as LazyComponent from './Loadable';
@@ -0,0 +1,3 @@
1
+ export { ListItem } from './List';
2
+ export { Popover } from './Popover';
3
+ export * as LazyComponent from './Loadable';
@@ -0,0 +1,2 @@
1
+ export { EditingListV2 } from './EditingList';
2
+ export type { EditingListProps } from './types';
@@ -0,0 +1 @@
1
+ export { EditingListV2 } from './EditingList';
@@ -0,0 +1,20 @@
1
+ /// <reference types="react" />
2
+ export type Option = {
3
+ key: string;
4
+ label: React.ReactNode;
5
+ errorMessage?: string;
6
+ search?: string;
7
+ };
8
+ export type EditingListProps = {
9
+ popupPlacement?: 'left' | 'right' | 'top' | 'bottom' | 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'leftTop' | 'leftBottom' | 'rightTop' | 'rightBottom';
10
+ addButtonLabel?: string;
11
+ options?: Option[];
12
+ selected?: string[];
13
+ showNum?: boolean;
14
+ className?: string;
15
+ isLoading?: boolean;
16
+ emptyDescription?: string;
17
+ removable?: boolean;
18
+ isAllowEmpty?: boolean;
19
+ onChange?: (selected: string[]) => void;
20
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ export declare const componentCls: (className: string) => string;
2
+ export declare const CLS: {
3
+ readonly Root: {
4
+ readonly default: string;
5
+ };
6
+ readonly Title: {
7
+ readonly default: string;
8
+ };
9
+ readonly Search: {
10
+ readonly default: string;
11
+ };
12
+ readonly RemoveButton: {
13
+ readonly default: string;
14
+ };
15
+ readonly AddButton: {
16
+ readonly default: string;
17
+ };
18
+ readonly ListWapper: {
19
+ readonly default: string;
20
+ };
21
+ readonly List: {
22
+ readonly default: string;
23
+ };
24
+ readonly ListItem: {
25
+ readonly default: string;
26
+ };
27
+ };
@@ -0,0 +1,28 @@
1
+ import { antsomiClsx } from '@antscorp/antsomi-ui/es/utils';
2
+ export const componentCls = antsomiClsx('editing-list');
3
+ export const CLS = {
4
+ Root: {
5
+ default: componentCls('root'),
6
+ },
7
+ Title: {
8
+ default: componentCls('title'),
9
+ },
10
+ Search: {
11
+ default: componentCls('search'),
12
+ },
13
+ RemoveButton: {
14
+ default: componentCls('remove-btn'),
15
+ },
16
+ AddButton: {
17
+ default: componentCls('add-btn'),
18
+ },
19
+ ListWapper: {
20
+ default: componentCls('selected-list-wrapper'),
21
+ },
22
+ List: {
23
+ default: componentCls('selected-list'),
24
+ },
25
+ ListItem: {
26
+ default: componentCls('selected-list-item'),
27
+ },
28
+ };
@@ -6,7 +6,7 @@ import { PopoverSelect } from '../PopoverSelect';
6
6
  import { Flex, Typography } from 'antd';
7
7
  import { IconField } from '@antscorp/antsomi-ui/es/components/atoms/IconField';
8
8
  export const PopoverAddField = (props) => {
9
- const { fields, onSearchPredicate, className, children, ...rest } = props;
9
+ const { fields, onSearchPredicate, className, children, isAllowEmpty, ...rest } = props;
10
10
  const originalFieldByKey = useMemo(() => new Map(fields.map(field => [field.key, field])), [fields]);
11
11
  const handleOnSearchPredicate = useCallback((option) => {
12
12
  const originalField = originalFieldByKey.get(option.key);
@@ -26,5 +26,5 @@ export const PopoverAddField = (props) => {
26
26
  selected: params.selected.includes(field.key),
27
27
  })] })),
28
28
  })), [fields]);
29
- 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"] })) }));
29
+ 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"] })) }));
30
30
  };
@@ -12,7 +12,7 @@ import { VirtualizedMenu } from '../../../VirtualizedMenu';
12
12
  import { ITEM_SIZE, ITEM_SPACING } from '../../../VirtualizedMenu/config';
13
13
  const { t } = i18nInstance;
14
14
  export const PopoverSelect = (props) => {
15
- 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;
15
+ 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;
16
16
  const itemSize = menuProps.itemSize || ITEM_SIZE;
17
17
  const itemSpacing = menuProps.itemSpacing || ITEM_SPACING;
18
18
  const { value: searchValue, ...restInputSearchProps } = inputSearchProps;
@@ -24,7 +24,7 @@ export const PopoverSelect = (props) => {
24
24
  const [selectedKeys, setSelectedKeys] = useState(new Set());
25
25
  const [search, setSearch] = useState('');
26
26
  const [showSelected, setShowSelected] = useState(false);
27
- const applyDisabled = selectedKeys.size === 0;
27
+ const applyDisabled = selectedKeys.size === 0 && !isAllowEmpty;
28
28
  const options = useMemo(() => typeof optionsProp === 'function'
29
29
  ? optionsProp({ selected: [...selectedKeys] })
30
30
  : optionsProp, [optionsProp, selectedKeys]);
@@ -109,11 +109,11 @@ export const PopoverSelect = (props) => {
109
109
  key: opt.key,
110
110
  label: (_jsx(Checkbox, { onChange: e => handleToggleField(opt, e.target.checked), checked: selectedKeys.has(opt.key), children: renderCheckBoxLabel(opt) })),
111
111
  }));
112
- return (_jsx(SearchPopover, { destroyTooltipOnHide: true, ...rest, content: _jsxs(_Fragment, { children: [optionsProp.length > 0 && (_jsxs(StyledAction, { children: [_jsx(Button, { type: "link", size: "small", onClick: () => setShowSelected(current => !current), children: showSelected ? showAllLabel : showSelectedLabel }), selectedKeys.size === options.length ? (_jsx(Button, { type: "link", onClick: handleDeselectAll, children: deselectAllLabel })) : (_jsx(Button, { type: "link", onClick: handleSelectAll, children: selectAllLabel }))] })), filteredOptions.length ? (_jsx(StyledListFieldsWrapper, { "$minHeight": calDefaultListHeightInPopover({
112
+ return (_jsx(SearchPopover, { destroyTooltipOnHide: true, placement: "bottomLeft", ...rest, content: _jsxs(_Fragment, { children: [optionsProp.length > 0 && (_jsxs(StyledAction, { children: [_jsx(Button, { type: "link", size: "small", onClick: () => setShowSelected(current => !current), children: showSelected ? showAllLabel : showSelectedLabel }), selectedKeys.size === options.length ? (_jsx(Button, { type: "link", onClick: handleDeselectAll, children: deselectAllLabel })) : (_jsx(Button, { type: "link", onClick: handleSelectAll, children: selectAllLabel }))] })), filteredOptions.length ? (_jsx(StyledListFieldsWrapper, { "$minHeight": calDefaultListHeightInPopover({
113
113
  listLength: filteredOptions.length,
114
114
  itemSize,
115
115
  itemSpacing,
116
- }), children: _jsx(VirtualizedMenu, { ...menuProps, itemSize: itemSize, items: items }) })) : (_jsx(EmptyData, { showIcon: false, description: t(translations.noData).toString() })), _jsxs(StyledFooter, { children: [_jsx(Button, { onClick: handleCancel, children: "Cancel" }), _jsx(Button, { onClick: handleApply, disabled: applyDisabled, type: "primary", children: "Apply" })] })] }), trigger: ['click'], placement: "bottomLeft", open: open, inputSearchProps: {
116
+ }), children: _jsx(VirtualizedMenu, { ...menuProps, itemSize: itemSize, items: items }) })) : (_jsx(EmptyData, { showIcon: false, description: t(translations.noData).toString() })), _jsxs(StyledFooter, { children: [_jsx(Button, { onClick: handleCancel, children: "Cancel" }), _jsx(Button, { onClick: handleApply, disabled: applyDisabled, type: "primary", children: "Apply" })] })] }), trigger: ['click'], open: open, inputSearchProps: {
117
117
  ...restInputSearchProps,
118
118
  value: search,
119
119
  onAfterChange: handleOnSearch,
@@ -21,5 +21,6 @@ export const StyledAction = styled.div `
21
21
  `;
22
22
  export const StyledListFieldsWrapper = styled.div `
23
23
  min-height: ${props => props.$minHeight}px;
24
+ min-width: 300px;
24
25
  flex: 1;
25
26
  `;
@@ -4,6 +4,7 @@ import React, { PropsWithChildren } from 'react';
4
4
  import { MenuInlineProps } from '../VirtualizedMenu/types';
5
5
  export type SearchPopoverProps = PropsWithChildren<{
6
6
  inputSearchProps?: InputProps;
7
+ isAllowEmpty?: boolean;
7
8
  } & PopoverProps>;
8
9
  export type Option = {
9
10
  key: string;
@@ -1,33 +1,133 @@
1
1
  import React from 'react';
2
2
  import { UploadProps as AntdUploadProps } from 'antd/lib/upload';
3
3
  export type MediaMode = 'image' | 'video';
4
- interface UploadImageProps extends AntdUploadProps {
4
+ /**
5
+ * Props for the UploadImage component.
6
+ */
7
+ export interface UploadImageProps extends AntdUploadProps {
8
+ /**
9
+ * Heading text for the image upload modal.
10
+ * @default "Image Selection"
11
+ */
5
12
  labelHeadingModal?: string;
13
+ /**
14
+ * Label for the button used to select an image.
15
+ * @default "Select Image from computer"
16
+ */
6
17
  labelButtonSelect?: string;
18
+ /**
19
+ * Label for the modal confirming image deletion.
20
+ * @default "Delete Image"
21
+ */
7
22
  labelModalDelete?: string;
23
+ /**
24
+ * Placeholder text for the search input inside the modal.
25
+ * @default "Search image..."
26
+ */
8
27
  searchPlaceholder?: string;
28
+ /**
29
+ * Callback triggered when an image is removed.
30
+ */
9
31
  onRemoveImage?: Function;
32
+ /**
33
+ * Callback triggered when an image is selected or changed.
34
+ */
10
35
  onChangeImage?: Function;
36
+ /**
37
+ * The currently selected image object.
38
+ */
11
39
  selectedImage?: UploadMediaObject;
40
+ /**
41
+ * Controls the visibility of the image upload modal.
42
+ * @default false
43
+ */
12
44
  isOpen?: boolean;
45
+ /**
46
+ * Determines if the component should operate in input mode.
47
+ * @default true
48
+ */
13
49
  isInputMode?: boolean;
50
+ /**
51
+ * Name of the icon to be displayed.
52
+ * @default "image-3"
53
+ */
14
54
  iconName?: string;
55
+ /**
56
+ * Mode in which the media should be handled.
57
+ * @default "image"
58
+ */
15
59
  mode?: MediaMode;
16
- width?: any;
60
+ /**
61
+ * Width of the upload component.
62
+ * @default "100%"
63
+ */
64
+ width?: string | number;
65
+ /**
66
+ * List of validation errors related to the upload.
67
+ * @default []
68
+ */
17
69
  errors?: Array<any>;
70
+ /**
71
+ * Allowed file extensions for the upload.
72
+ * @default [".jpg", ".png", ".jfif", ".jpeg", ".gif", ".webp"]
73
+ */
18
74
  extensions?: string[];
75
+ /**
76
+ * Maximum file size allowed for upload (in MB).
77
+ * @default 10
78
+ */
19
79
  maxSize?: number;
80
+ /**
81
+ * Title text for the upload section.
82
+ */
20
83
  title?: string;
84
+ /**
85
+ * Whether to display the image URL after upload.
86
+ * @default true
87
+ */
21
88
  showImageURL?: boolean;
89
+ /**
90
+ * Placeholder text for the upload input field.
91
+ * @default "Enter image URL"
92
+ */
22
93
  placeholder?: string;
94
+ /**
95
+ * Domain-specific media folder or endpoint.
96
+ * @default "https://sandbox-media-template.antsomi.com/cdp"
97
+ */
23
98
  domainMedia: string;
99
+ /**
100
+ * Unique slug identifier for media categorization.
101
+ * @default "api/v1"
102
+ */
24
103
  slug: string;
104
+ /**
105
+ * Configuration parameters for API requests.
106
+ */
25
107
  paramConfigs?: {
108
+ /**
109
+ * Authentication token for media uploads.
110
+ * @default ""
111
+ */
26
112
  token?: string;
113
+ /**
114
+ * User identifier for media ownership.
115
+ * @default ""
116
+ */
27
117
  userId?: string;
118
+ /**
119
+ * Account identifier for media association.
120
+ * @default ""
121
+ */
28
122
  accountId: string;
29
123
  };
124
+ /**
125
+ * Whether the image upload is required.
126
+ */
30
127
  required?: boolean;
128
+ /**
129
+ * Indicates if the input is currently focused.
130
+ */
31
131
  focused?: boolean;
32
132
  }
33
133
  interface UploadMediaObject {
@@ -3,15 +3,19 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
3
3
  /* eslint-disable @typescript-eslint/no-use-before-define */
4
4
  /* eslint-disable react-hooks/exhaustive-deps */
5
5
  // Libraries
6
- import { useEffect, useState, useRef } from 'react';
6
+ import { useEffect, useState, useRef, useMemo } from 'react';
7
7
  import Upload from 'antd/lib/upload';
8
+ import { useQueryClient } from '@tanstack/react-query';
9
+ import { cloneDeep, flattenDeep } from 'lodash';
10
+ import { useInView } from 'react-intersection-observer';
8
11
  // Hooks
9
- import { useDeepCompareEffect } from '@antscorp/antsomi-ui/es/hooks';
12
+ import { useDebounce } from '@antscorp/antsomi-ui/es/hooks/useDebounce';
13
+ import { useStoreSavedMedia } from '@antscorp/antsomi-ui/es/queries';
10
14
  // Assets
11
15
  import PlaceholderImage from '@antscorp/antsomi-ui/es/assets/images/placeholder-image.png';
12
16
  import MediaIcon from './MediaIcon';
13
17
  // Service
14
- import { uploadFile, createSavedMedia, deleteSavedMedia, getListingSavedMedia, } from '@antscorp/antsomi-ui/es/services/MediaTemplateDesign/UploadFile';
18
+ import { uploadFile, createSavedMedia, deleteSavedMedia, } from '@antscorp/antsomi-ui/es/services/MediaTemplateDesign/UploadFile';
15
19
  // Atoms
16
20
  import { Button, Icon, Text, message, Spin, Input, Space, } from '@antscorp/antsomi-ui/es/components/atoms';
17
21
  // Molecules
@@ -19,10 +23,10 @@ import { Modal, InputSearch, Select } from '@antscorp/antsomi-ui/es/components/m
19
23
  // Styled
20
24
  import { Boxed, ErrorMessage, Image, Overlay, Paragraph, TextStyled, UploadImageWrapper, WrapperBtn, WrapperIcon, WrapperInputMode, WrapperListImages, } from './styled';
21
25
  // Utils
22
- import { handleError, safeParse } from '@antscorp/antsomi-ui/es/utils';
26
+ import { safeParse } from '@antscorp/antsomi-ui/es/utils';
23
27
  import { getMediaTypeByMode, getReplacementExtension } from './utils';
24
28
  // Constants
25
- import { THEME } from '@antscorp/antsomi-ui/es/constants';
29
+ import { QUERY_KEYS, THEME } from '@antscorp/antsomi-ui/es/constants';
26
30
  const flexStyleCenter = {
27
31
  display: 'flex',
28
32
  gap: '15px',
@@ -39,75 +43,45 @@ const SORT_OPTIONS = {
39
43
  label: 'Sort by Size',
40
44
  },
41
45
  };
42
- const PATH = '@antscorp/antsomi-ui/es/components/molecules/UploadImage/index.tsx';
43
46
  export const UploadImage = props => {
44
47
  const { labelHeadingModal, labelButtonSelect, labelModalDelete, searchPlaceholder, onRemoveImage, onChangeImage: onChangeMedia, isOpen, isInputMode, width, placeholder, extensions, maxSize, title, showImageURL: showMediaURL, selectedImage: selectedMediaProp, required, focused, domainMedia, slug, paramConfigs, errors, iconName, mode, } = props;
45
48
  const { Dragger } = Upload;
46
- const [storeSavedMedia, setStoreSavedMedia] = useState([]);
47
49
  const [selectedMedia, setSelectedMedia] = useState(selectedMediaProp || { url: '' });
48
50
  const [isModalOpen, setIsModalOpen] = useState(isOpen);
49
- const [listMedia, setListMedia] = useState(storeSavedMedia || []);
51
+ const [textSearchDebounce, textSearch, setTextSearch] = useDebounce('', 350);
50
52
  const [sortOption, setSortOption] = useState(SORT_OPTIONS.BY_UPLOAD_DATE.value);
51
53
  const [loading, setLoading] = useState(false);
52
54
  const [isOpenConfirmDelete, setOpenConfirmDelete] = useState(false);
53
- const [triggerRefresh, setTriggerRefresh] = useState(1);
54
55
  const uploadFilesRef = useRef([]);
55
56
  const uploadFilesTimeoutRef = useRef();
56
57
  const deleteMediaRef = useRef();
57
58
  const isError = safeParse(errors, []).length > 0;
58
- useDeepCompareEffect(() => {
59
- setListMedia(storeSavedMedia || []);
60
- setLoading(false);
61
- }, [storeSavedMedia]);
59
+ const queryClient = useQueryClient();
60
+ const paramsMemo = useMemo(() => ({
61
+ ...paramConfigs,
62
+ type: getMediaTypeByMode(mode),
63
+ }), [paramConfigs, mode]);
64
+ const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading: isLoadingStore, refetch, } = useStoreSavedMedia(domainMedia, slug, paramsMemo);
65
+ const flattenedMedia = useMemo(() => {
66
+ const flattened = cloneDeep(flattenDeep(data?.pages));
67
+ // Filter media based on search text
68
+ const filteredMedia = textSearchDebounce
69
+ ? flattened.filter(media => media.name?.toLowerCase().includes(textSearchDebounce.toLowerCase()))
70
+ : flattened;
71
+ // Sort media based on the selected sort option
72
+ if (sortOption === SORT_OPTIONS.BY_SIZE.value) {
73
+ return filteredMedia.sort((media1, media2) => media1.size - media2.size);
74
+ }
75
+ return filteredMedia.sort((media1, media2) => media1.createdAt && media2.createdAt
76
+ ? media1.createdAt.isAfter(media2.createdAt)
77
+ ? -1
78
+ : 1
79
+ : 0);
80
+ }, [data?.pages, sortOption, textSearchDebounce]);
62
81
  // When selectedMediaProp onChange
63
82
  useEffect(() => {
64
83
  setSelectedMedia(selectedMediaProp || { url: '' });
65
84
  }, [selectedMediaProp]);
66
- useEffect(() => {
67
- if (sortOption === SORT_OPTIONS.BY_SIZE.value) {
68
- setListMedia(listMedia ? [...listMedia].sort((media1, media2) => media1.size - media2.size) : []);
69
- }
70
- else {
71
- setListMedia(listMedia
72
- ? [...listMedia].sort((media1, media2) => media1.createdAt && media2.createdAt
73
- ? media1.createdAt.isAfter(media2.createdAt)
74
- ? -1
75
- : 1
76
- : 0)
77
- : []);
78
- }
79
- }, [sortOption]);
80
- const handleGetStoreSavedMedia = async (domain, slug, paramConfigs) => {
81
- try {
82
- setLoading(true);
83
- const type = getMediaTypeByMode(mode);
84
- const params = {
85
- ...paramConfigs,
86
- type,
87
- };
88
- const result = await getListingSavedMedia(domain, slug, params);
89
- if (result) {
90
- setStoreSavedMedia(result || []);
91
- }
92
- }
93
- catch (error) {
94
- handleError(error, {
95
- path: PATH,
96
- name: 'handleGetStoreSavedMedia',
97
- args: {
98
- error,
99
- },
100
- });
101
- // eslint-disable-next-line no-console
102
- console.log('error :>', error);
103
- }
104
- finally {
105
- setLoading(false);
106
- }
107
- };
108
- useEffect(() => {
109
- handleGetStoreSavedMedia(domainMedia, slug, paramConfigs);
110
- }, [triggerRefresh]);
111
85
  const showModal = (e) => {
112
86
  e.stopPropagation();
113
87
  setIsModalOpen(true);
@@ -125,6 +99,14 @@ export const UploadImage = props => {
125
99
  const onChangeSort = (option) => {
126
100
  setSortOption(option);
127
101
  };
102
+ const { ref } = useInView({
103
+ triggerOnce: false,
104
+ onChange: inView => {
105
+ if (inView && hasNextPage && !isFetchingNextPage) {
106
+ fetchNextPage();
107
+ }
108
+ },
109
+ });
128
110
  const renderListMedia = (listMediaRender) => listMediaRender.map((media, idx) => (_jsxs(WrapperListImages, { className: "ants-group", children: [_jsxs(Boxed, { children: [_jsx(Image, { src: mode === 'video' ? media.thumbnail : media.url, alt: "img", loading: "lazy" }), _jsxs(WrapperBtn, { className: "group-hover", children: [_jsx(Button, { onClick: () => handleSelectMedia(media), style: { backgroundColor: 'rgb(255,255,255)' }, children: "USE" }), _jsx(Button, { onClick: () => handleRemoveUploadedMedia(media), style: { backgroundColor: 'rgb(255,255,255)' }, children: _jsx(Icon, { type: "icon-ants-remove-trash", size: 15, style: { color: THEME.token?.colorPrimary } }) })] }), _jsx(Overlay, { className: "group-hover" })] }), _jsx(Paragraph, { style: {
129
111
  overflow: 'hidden',
130
112
  textOverflow: 'ellipsis',
@@ -134,16 +116,7 @@ export const UploadImage = props => {
134
116
  }, title: media.name, children: media.name }), _jsxs(Paragraph, { children: ["Uploaded: ", media.createdAt.format('DD/MM/YYYY'), " at ", media.createdAt.format('hh:mm:ss A')] }), _jsxs(Paragraph, { children: ["Size: ", media.sizeString] })] }, idx)));
135
117
  const onChangeSearchImage = (e) => {
136
118
  const { value } = e.target;
137
- if (value && value.trim()) {
138
- setListMedia(storeSavedMedia
139
- ? storeSavedMedia
140
- .filter(item => item.name.toLocaleLowerCase().includes(value.trim().toLocaleLowerCase()))
141
- .slice(0, 15)
142
- : []);
143
- }
144
- else {
145
- setListMedia(storeSavedMedia);
146
- }
119
+ setTextSearch(value.trim());
147
120
  };
148
121
  const handleRemoveMedia = () => {
149
122
  if (onRemoveImage) {
@@ -161,7 +134,9 @@ export const UploadImage = props => {
161
134
  if (res && res.data && res.data.code === 200 && res.data.data) {
162
135
  const { success_media = [] } = res.data.data;
163
136
  if (Array.isArray(success_media) && success_media.length) {
164
- setTriggerRefresh(triggerRefresh + 1);
137
+ queryClient.invalidateQueries([QUERY_KEYS.GET_LIST_SAVED_MEDIA, domainMedia, slug, paramsMemo], {
138
+ exact: false,
139
+ });
165
140
  }
166
141
  }
167
142
  setOpenConfirmDelete(false);
@@ -235,7 +210,7 @@ export const UploadImage = props => {
235
210
  })));
236
211
  await Promise.all(arrPromise);
237
212
  setLoading(false);
238
- setTriggerRefresh(triggerRefresh + 1);
213
+ refetch({ refetchPage: (_page, index) => index === 0 });
239
214
  }
240
215
  else {
241
216
  setLoading(false);
@@ -279,7 +254,7 @@ export const UploadImage = props => {
279
254
  justifyContent: 'space-between',
280
255
  alignItems: 'center',
281
256
  marginBottom: 20,
282
- }, children: [_jsx(InputSearch, { style: { width: 232 }, onChange: onChangeSearchImage, placeholder: searchPlaceholder }), _jsx(Select, { defaultValue: SORT_OPTIONS.BY_UPLOAD_DATE.value, value: sortOption, options: Object.values(SORT_OPTIONS), style: { width: 232 }, onChange: onChangeSort })] }), _jsx(Spin, { spinning: loading, children: _jsx(Dragger, { ...props, accept: extensions?.join(','),
257
+ }, children: [_jsx(InputSearch, { value: textSearch, style: { width: 232 }, onChange: onChangeSearchImage, placeholder: searchPlaceholder }), _jsx(Select, { defaultValue: SORT_OPTIONS.BY_UPLOAD_DATE.value, value: sortOption, options: Object.values(SORT_OPTIONS), style: { width: 232 }, onChange: onChangeSort })] }), _jsx(Spin, { spinning: loading || isFetchingNextPage || isLoadingStore, children: _jsx(Dragger, { ...props, accept: extensions?.join(','),
283
258
  // action={`${APP_CONFIG.API_URL}/file-upload/file?&_token=${userInfo?.token}&_user_id=${userInfo?.user_id}&_account_id=${userInfo?.account_id}`}
284
259
  // beforeUpload={handleBeforeUploadFile}
285
260
  // onChange={onChangeFileUpload}
@@ -289,13 +264,13 @@ export const UploadImage = props => {
289
264
  }, children: [_jsx(Icon, { type: `icon-ants-${iconName}`, size: 36, style: { color: THEME.token?.colorIcon } }), _jsxs("div", { style: { ...flexStyleCenter, justifyContent: 'flex-start' }, children: [_jsx(TextStyled, { className: "ant-upload-text", children: "Drag & Drop file here" }), _jsx("span", { children: "or" }), _jsx(Button, { style: { backgroundColor: '#ffffff' }, children: labelButtonSelect }), _jsx(Button, { onClick: handleRemoveMedia, style: {
290
265
  display: 'none !important',
291
266
  backgroundColor: '#ffffff',
292
- }, children: _jsx(Icon, { type: "icon-ants-remove-trash", size: 15, style: { color: THEME.token?.colorPrimary } }) })] })] }) }) }), _jsx("div", { style: {
267
+ }, children: _jsx(Icon, { type: "icon-ants-remove-trash", size: 15, style: { color: THEME.token?.colorPrimary } }) })] })] }) }) }), _jsxs("div", { style: {
293
268
  display: 'flex',
294
269
  flexWrap: 'wrap',
295
270
  gap: '35px',
296
271
  paddingTop: 20,
297
272
  width: '100%',
298
- }, children: renderListMedia(listMedia) })] })] }));
273
+ }, children: [renderListMedia(flattenedMedia), _jsx("div", { ref: ref })] })] })] }));
299
274
  };
300
275
  UploadImage.defaultProps = {
301
276
  isOpen: false,
@@ -1,3 +1,4 @@
1
+ import { CSSProperties } from 'react';
1
2
  export declare const WrapperListImages: import("styled-components").StyledComponent<"div", any, {}, never>;
2
3
  export declare const TextStyled: import("styled-components").StyledComponent<"span", any, {}, never>;
3
4
  export declare const Boxed: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -6,7 +7,7 @@ export declare const WrapperBtn: import("styled-components").StyledComponent<"di
6
7
  export declare const Paragraph: import("styled-components").StyledComponent<"p", any, {}, never>;
7
8
  export declare const Overlay: import("styled-components").StyledComponent<"div", any, {}, never>;
8
9
  export declare const WrapperInputMode: import("styled-components").StyledComponent<"div", any, {
9
- width?: string | undefined;
10
+ width?: CSSProperties['width'];
10
11
  }, never>;
11
12
  export declare const WrapperIcon: import("styled-components").StyledComponent<"div", any, {}, never>;
12
13
  export declare const ErrorMessage: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -8,6 +8,7 @@ export type ItemType = {
8
8
  scrollingLabel?: string;
9
9
  label?: ReactNode;
10
10
  children?: ItemType[];
11
+ errorMessage?: string | undefined;
11
12
  disabled?: boolean;
12
13
  };
13
14
  export type SerializedItemType = ItemType & {
@@ -6,6 +6,7 @@ export { Select } from './Select';
6
6
  export { SelectV2 } from './SelectV2';
7
7
  export { DatePicker } from './DatePicker';
8
8
  export { ChatBox, ChatBoxInsight } from './ChatBox';
9
+ export { EditingListV2 } from './EditingListV2';
9
10
  export { PopupDraggable } from './PopupDraggable';
10
11
  export { CaptureScreen } from './CaptureScreen';
11
12
  export { SettingWrapper } from './SettingWrapper';
@@ -6,6 +6,7 @@ export { Select } from './Select';
6
6
  export { SelectV2 } from './SelectV2';
7
7
  export { DatePicker } from './DatePicker';
8
8
  export { ChatBox, ChatBoxInsight } from './ChatBox';
9
+ export { EditingListV2 } from './EditingListV2';
9
10
  export { PopupDraggable } from './PopupDraggable';
10
11
  export { CaptureScreen } from './CaptureScreen';
11
12
  export { SettingWrapper } from './SettingWrapper';
@@ -18,6 +18,7 @@ export declare const QUERY_KEYS: {
18
18
  GET_OBJECT_TEMPLATE_DETAIL: string;
19
19
  GET_SAVE_AS_GALLERY_PERMISSION_EMAILS: string;
20
20
  GET_LIST_FALLBACK_BO: string;
21
+ GET_LIST_SAVED_MEDIA: string;
21
22
  GET_DASHBOARD: string;
22
23
  GET_LIST_MENU: string;
23
24
  GET_LIST_MENU_PERMISSION: string;
@@ -27,6 +27,7 @@ export const QUERY_KEYS = {
27
27
  GET_SAVE_AS_GALLERY_PERMISSION_EMAILS: 'GET_SAVE_AS_GALLERY_PERMISSION_EMAILS',
28
28
  // THIRD PARTY
29
29
  GET_LIST_FALLBACK_BO: 'GET_LIST_FALLBACK_BO',
30
+ GET_LIST_SAVED_MEDIA: 'GET_LIST_SAVED_MEDIA',
30
31
  // Left menu
31
32
  GET_DASHBOARD: 'GET_DASHBOARD',
32
33
  GET_LIST_MENU: 'GET_LIST_MENU',
@@ -103,6 +103,9 @@ THEME.components = {
103
103
  colorTextDisabled: THEME.token?.bw0,
104
104
  textHoverBg: '#F2F9FF',
105
105
  marginXS: 0,
106
+ primaryShadow: 'none',
107
+ dangerShadow: 'none',
108
+ defaultShadow: 'none',
106
109
  /* Text type */
107
110
  colorBgTextHover: THEME.token?.blue,
108
111
  colorBgTextActive: THEME.token?.blue1_1,
@@ -661,7 +661,8 @@
661
661
  "_explore": "Explore",
662
662
  "_builtIn": "Built in",
663
663
  "_standard": "Standard",
664
- "_ipRestriction": "IP Restriction"
664
+ "_ipRestriction": "IP Restriction",
665
+ "_unsubscribers": "Unsubscribers"
665
666
  }
666
667
  },
667
668
  "layout": {
@@ -3408,6 +3408,7 @@ export declare const translationsJson: {
3408
3408
  _builtIn: string;
3409
3409
  _standard: string;
3410
3410
  _ipRestriction: string;
3411
+ _unsubscribers: string;
3411
3412
  };
3412
3413
  };
3413
3414
  layout: {
@@ -6390,6 +6391,7 @@ export declare const translationsJson: {
6390
6391
  _builtIn: string;
6391
6392
  _standard: string;
6392
6393
  _ipRestriction: string;
6394
+ _unsubscribers: string;
6393
6395
  };
6394
6396
  };
6395
6397
  layout: {
@@ -211,7 +211,8 @@
211
211
  "_explore": "",
212
212
  "_builtIn": "Mẫu",
213
213
  "_standard": "Tiêu chuẩn",
214
- "_ipRestriction": "Hạn chế IP"
214
+ "_ipRestriction": "Hạn chế IP",
215
+ "_unsubscribers": "Người hủy đăng ký"
215
216
  }
216
217
  },
217
218
  "layout": {
@@ -1,2 +1,3 @@
1
1
  export * from './useGetEventTrackingAttributes';
2
2
  export * from './useGetListFallbackBO';
3
+ export * from './useStoreSavedMedia';
@@ -1,2 +1,3 @@
1
1
  export * from './useGetEventTrackingAttributes';
2
2
  export * from './useGetListFallbackBO';
3
+ export * from './useStoreSavedMedia';
@@ -0,0 +1 @@
1
+ export declare const useStoreSavedMedia: (domain: string, slug: string, infos: any) => import("@tanstack/react-query").UseInfiniteQueryResult<import("../../models/SavedMedia").SavedMedia[], unknown>;
@@ -0,0 +1,12 @@
1
+ // Libraries
2
+ import { useInfiniteQuery } from '@tanstack/react-query';
3
+ // Services
4
+ import { getListingSavedMedia } from '../../services/MediaTemplateDesign/UploadFile';
5
+ // Constants
6
+ import { QUERY_KEYS } from '../../constants';
7
+ // Hook to fetch data with infinite scrolling
8
+ export const useStoreSavedMedia = (domain, slug, infos) => useInfiniteQuery({
9
+ queryKey: [QUERY_KEYS.GET_LIST_SAVED_MEDIA, domain, slug, infos],
10
+ queryFn: ({ pageParam }) => getListingSavedMedia(domain, slug, infos, pageParam),
11
+ getNextPageParam: (lastPage, pages) => (lastPage.length >= 10 ? pages.length + 1 : undefined),
12
+ });
@@ -1,6 +1,6 @@
1
1
  import { SavedMedia } from '@antscorp/antsomi-ui/es/models/SavedMedia';
2
2
  import { Upload } from '@antscorp/antsomi-ui/es/models/Upload';
3
- export declare const getListingSavedMedia: (domainUrl: string, slug: string, infos: any) => Promise<SavedMedia[]>;
3
+ export declare const getListingSavedMedia: (domainUrl: string, slug: string, infos: any, page?: number) => Promise<SavedMedia[]>;
4
4
  export declare const createSavedMedia: (domainUrl: string, slug: string, infos: any, data: any) => Promise<any>;
5
5
  export declare const deleteSavedMedia: (domainUrl: string, slug: string, infos: any, id: string | number) => Promise<any>;
6
6
  export declare const uploadFile: (domainUrl: string, slug: string, infos: any, files: any) => Promise<Upload[]>;
@@ -3,11 +3,11 @@
3
3
  import { SavedMedia } from '@antscorp/antsomi-ui/es/models/SavedMedia';
4
4
  import { Upload } from '@antscorp/antsomi-ui/es/models/Upload';
5
5
  import { services } from '@antscorp/antsomi-ui/es/services';
6
- export const getListingSavedMedia = async (domainUrl, slug, infos) => {
6
+ export const getListingSavedMedia = async (domainUrl, slug, infos, page = 1) => {
7
7
  try {
8
8
  const { type = '', ...restInfos } = infos || {};
9
9
  const { data } = await services.mediaTemplateDesign.getList({
10
- API_HOST: `${domainUrl}/${slug}/saved-media/index?type=${type}`,
10
+ API_HOST: `${domainUrl}/${slug}/saved-media/index?type=${type}&page=${page}&limit=10`,
11
11
  }, restInfos);
12
12
  let savedImages = data?.data || [];
13
13
  savedImages = savedImages.map((savedImage) => new SavedMedia(savedImage));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antscorp/antsomi-ui",
3
- "version": "2.0.57",
3
+ "version": "2.0.59",
4
4
  "description": "An enterprise-class UI design language and React UI library.",
5
5
  "sideEffects": [
6
6
  "dist/*",