@antscorp/antsomi-ui 1.3.5-beta.274 → 1.3.5-beta.276

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.
@@ -93,4 +93,5 @@ OriginInput.defaultProps = {
93
93
  export const Input = OriginInput;
94
94
  Input.TextArea = StyledInput.TextArea;
95
95
  Input.DefaultInput = AntdInput;
96
+ Input.Password = AntdInput.Password;
96
97
  export const { TextArea } = StyledInput;
@@ -8,6 +8,7 @@ export interface AccountListingProps {
8
8
  portalId?: number;
9
9
  languageCode?: string;
10
10
  appCode?: string;
11
+ menuCode?: string;
11
12
  };
12
13
  showAllAccount?: boolean;
13
14
  currentAccount?: string | 'all';
@@ -8,7 +8,7 @@ import { searchStringQuery } from '@antscorp/antsomi-ui/es/utils';
8
8
  import { useGetAccountList, useGetPermissionAccountList, useGetRecentAccount } from '../../..';
9
9
  export const AccountListing = props => {
10
10
  const { className, apiConfig, showAllAccount = true, currentAccount = '', onChange } = props;
11
- const { domain, token, userId, appCode, portalId } = apiConfig;
11
+ const { domain, token, userId, appCode, menuCode, portalId } = apiConfig;
12
12
  // States
13
13
  const [searchValue, setSearchValue] = useState('');
14
14
  // Queries
@@ -27,7 +27,7 @@ export const AccountListing = props => {
27
27
  domain,
28
28
  appCode: appCode || '',
29
29
  fullParent: true,
30
- menuCode: appCode || '',
30
+ menuCode: menuCode || appCode || '',
31
31
  },
32
32
  options: {
33
33
  enabled: portalId === PORTALS_IDS.SANDBOX_76753,
@@ -29,6 +29,7 @@ export interface HeaderV2Props {
29
29
  portalId?: number;
30
30
  token?: string;
31
31
  appCode?: string;
32
+ menuCode?: string;
32
33
  permissionDomain?: string;
33
34
  iamDomain?: string;
34
35
  };
@@ -20,15 +20,16 @@ import { AccountSharing, Help, Notification, } from '../../organism';
20
20
  import { APP_CODES, APP_PERMISSION_DOMAIN, CDP_API, IAM_API, ISSUE_API, PERMISSION_API, PLATFORM_API, PORTALS_IDS, SOCKET_API, } from '@antscorp/antsomi-ui/es/constants';
21
21
  import { useContextSelector } from 'use-context-selector';
22
22
  import { AppConfigContext } from '../../..';
23
+ const { DATAFLOWS, APP_ANTALYSER } = APP_CODES;
23
24
  export const HeaderV2 = memo(props => {
24
25
  var _a, _b;
25
- const { auth, env: envContext, languageCode = 'en', appCode, urlLogout: urlLogoutProvider = '', } = useContextSelector(AppConfigContext, state => state);
26
+ const { auth, env: envContext, languageCode = 'en', appCode: contextAppCode, urlLogout: urlLogoutProvider = '', menuCode: contextMenuCode, } = useContextSelector(AppConfigContext, state => state);
26
27
  const { search } = useLocation();
27
28
  const history = useHistory();
28
29
  /** Prefer to use Header in AppConfigContext */
29
30
  const { className, style, pageTitle = '', accountSelection = {}, helpConfig, notificationConfig = {}, accountSharingConfig, useURLParam, config, } = props;
30
31
  /** General config for children component */
31
- const { env = envContext, language = languageCode, userId = isNaN(Number(auth === null || auth === void 0 ? void 0 : auth.userId)) ? 0 : Number(auth === null || auth === void 0 ? void 0 : auth.userId), portalId = auth === null || auth === void 0 ? void 0 : auth.portalId, token = auth === null || auth === void 0 ? void 0 : auth.token, permissionDomain = PERMISSION_API, iamDomain = IAM_API, } = config || {};
32
+ const { env = envContext, language = languageCode, userId = isNaN(Number(auth === null || auth === void 0 ? void 0 : auth.userId)) ? 0 : Number(auth === null || auth === void 0 ? void 0 : auth.userId), portalId = auth === null || auth === void 0 ? void 0 : auth.portalId, token = auth === null || auth === void 0 ? void 0 : auth.token, permissionDomain = PERMISSION_API, iamDomain = IAM_API, appCode = contextAppCode, menuCode = contextMenuCode, } = config || {};
32
33
  const { currentAccount, inputStyle = 'select', onSelectAccount } = accountSelection, accountSelectionProps = __rest(accountSelection, ["currentAccount", "inputStyle", "onSelectAccount"]);
33
34
  const urlParams = useMemo(() => new URLSearchParams(search), [search]);
34
35
  const oidParam = (_a = urlParams.get('oid')) !== null && _a !== void 0 ? _a : '';
@@ -40,7 +41,8 @@ export const HeaderV2 = memo(props => {
40
41
  if (portalId !== PORTALS_IDS.SANDBOX_76753)
41
42
  return CDP_API[env || 'development'];
42
43
  switch (appCode) {
43
- case APP_CODES.DATAFLOWS:
44
+ case DATAFLOWS:
45
+ case APP_ANTALYSER:
44
46
  return (_a = APP_PERMISSION_DOMAIN[appCode || '']) === null || _a === void 0 ? void 0 : _a[env || ''];
45
47
  default:
46
48
  return CDP_API[env || 'development'];
@@ -58,6 +60,7 @@ export const HeaderV2 = memo(props => {
58
60
  portalId,
59
61
  token,
60
62
  appCode,
63
+ menuCode,
61
64
  };
62
65
  const helpConfigProps = Object.assign(Object.assign({}, configs), { portalId: portalId.toString(), userId: userId.toString(), token, domain: CDP_API[env], domainTicket: ISSUE_API[env], domainPlatform: PLATFORM_API, config: Object.assign(Object.assign({}, configs.config), { user_language: language }) });
63
66
  const notificationConfigProps = {
@@ -1,12 +1,3 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
1
  /* eslint-disable default-case */
11
2
  import React, { useCallback, useEffect, useImperativeHandle, useReducer, useRef, useState, } from 'react';
12
3
  import Icon from '@antscorp/icons';
@@ -19,7 +10,7 @@ import { v4 as uuidV4 } from 'uuid';
19
10
  import { Button, Popover } from '../../atoms';
20
11
  import ModalShortcut from './components/ModalShortcut';
21
12
  import { useDropFile, useKeyEventCanvas } from '@antscorp/antsomi-ui/es/hooks';
22
- import { DEFAULT_TRANSFORM, DrawAction, PAINT_OPTIONS, ShapeObject } from './constants';
13
+ import { DEFAULT_TRANSFORM, DrawAction, IMAGE_COORDINATE, PAINT_OPTIONS, ShapeObject, } from './constants';
23
14
  import { initialReducer, reducer } from './reducer';
24
15
  import { downloadURI, getTransformData } from './utils';
25
16
  import { StageWrapperStyled } from './styled';
@@ -50,30 +41,14 @@ export const ImageEditor = React.forwardRef((props, ref) => {
50
41
  const { current: { arrows, circles, imageCoordinate, rectangles, scribbles, image }, } = state;
51
42
  useEffect(() => {
52
43
  // NOTE: reset initial reducer when change image (in ImageSlider)
53
- dispatch({ type: 'RESET', payload: defaultValue ? defaultValue : initialReducer.current });
44
+ dispatch({ type: 'RESET', payload: defaultValue || initialReducer.current });
54
45
  }, [defaultValue]);
55
46
  // const [imageFromUrl] = useImage(imageUrl);
56
- // console.log(imageUrl, '🚀 ~ ImageEditor ~ imageFromUrl:', imageUrl);
47
+ // // console.log(imageUrl, '🚀 ~ ImageEditor ~ imageFromUrl:', imageUrl);
57
48
  const stageRef = useRef(null);
58
49
  const transformerRef = useRef(null);
59
50
  const selectionRectangleRef = useRef(null);
60
51
  const isPaintRef = useRef(false);
61
- // NOTE: format canvas action (as methods) to ref with forwardRef and useImperativeHandle
62
- useImperativeHandle(ref, () => {
63
- return {
64
- getBase64(options) {
65
- var _a, _b;
66
- (_a = transformerRef === null || transformerRef === void 0 ? void 0 : transformerRef.current) === null || _a === void 0 ? void 0 : _a.nodes([]);
67
- return (_b = stageRef === null || stageRef === void 0 ? void 0 : stageRef.current) === null || _b === void 0 ? void 0 : _b.toDataURL(options);
68
- },
69
- replaceImageWithUrl(imageUrl) {
70
- changeImage(imageUrl);
71
- },
72
- getCurrentState() {
73
- return state.current;
74
- },
75
- };
76
- }, [state]);
77
52
  const changeImage = useCallback((imageUrl) => {
78
53
  const image = new Image();
79
54
  image.src = imageUrl;
@@ -90,15 +65,30 @@ export const ImageEditor = React.forwardRef((props, ref) => {
90
65
  type: 'SET_NEW_STATE',
91
66
  payload: {
92
67
  image,
93
- imageCoordinate: Object.assign(Object.assign({}, imageCoordinate), { id: uuidV4(), x: (width - image.width) / 2, y: (height - image.height) / 2, width: image.width, height: image.height }),
68
+ imageCoordinate: Object.assign(Object.assign({}, IMAGE_COORDINATE), { id: uuidV4(), x: (width - image.width) / 2, y: (height - image.height) / 2, width: image.width, height: image.height }),
94
69
  saveHistory: true,
95
70
  },
96
71
  });
97
72
  });
98
- }, [height, width, imageCoordinate]);
73
+ }, [height, width]);
74
+ // NOTE: format canvas action (as methods) to ref with forwardRef and useImperativeHandle
75
+ useImperativeHandle(ref, () => ({
76
+ getBase64(options) {
77
+ var _a, _b;
78
+ (_a = transformerRef === null || transformerRef === void 0 ? void 0 : transformerRef.current) === null || _a === void 0 ? void 0 : _a.nodes([]);
79
+ return (_b = stageRef === null || stageRef === void 0 ? void 0 : stageRef.current) === null || _b === void 0 ? void 0 : _b.toDataURL(options);
80
+ },
81
+ replaceImageWithUrl(imageUrl) {
82
+ changeImage(imageUrl);
83
+ },
84
+ getCurrentState() {
85
+ return state.current;
86
+ },
87
+ }), [state, changeImage]);
99
88
  useEffect(() => {
100
- imageUrl && changeImage(imageUrl);
101
- }, [imageUrl]);
89
+ if (imageUrl)
90
+ changeImage(imageUrl);
91
+ }, [imageUrl, changeImage]);
102
92
  const onImportImageSelect = useCallback((e) => {
103
93
  var _a;
104
94
  if ((_a = e.target.files) === null || _a === void 0 ? void 0 : _a[0]) {
@@ -287,7 +277,7 @@ export const ImageEditor = React.forwardRef((props, ref) => {
287
277
  const selected = shapes.filter(shape => Konva.default.Util.haveIntersection(box, shape.getClientRect()));
288
278
  (_c = transformerRef === null || transformerRef === void 0 ? void 0 : transformerRef.current) === null || _c === void 0 ? void 0 : _c.nodes(selected);
289
279
  }
290
- }, [drawAction, selectionPosition.visible]);
280
+ }, [drawAction, selectionPosition.visible, showSelection]);
291
281
  const currentShapeRef = useRef();
292
282
  const onStageMouseDown = useCallback(() => {
293
283
  if (drawAction !== DrawAction.Crop)
@@ -416,19 +406,20 @@ export const ImageEditor = React.forwardRef((props, ref) => {
416
406
  setSelectionPosition(prev => (Object.assign(Object.assign({}, prev), { visible: false })));
417
407
  }
418
408
  }, [selectionPosition]);
419
- const onApplyCropClick = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
409
+ const onApplyCropClick = useCallback(() => {
420
410
  var _a;
421
411
  if (!cropZone)
422
412
  return;
423
- const dataUri = yield ((_a = stageRef === null || stageRef === void 0 ? void 0 : stageRef.current) === null || _a === void 0 ? void 0 : _a.toDataURL({
413
+ const dataUri = (_a = stageRef === null || stageRef === void 0 ? void 0 : stageRef.current) === null || _a === void 0 ? void 0 : _a.toDataURL({
424
414
  x: (cropZone === null || cropZone === void 0 ? void 0 : cropZone.x) + 2,
425
415
  y: (cropZone === null || cropZone === void 0 ? void 0 : cropZone.y) + 2,
426
416
  width: (cropZone === null || cropZone === void 0 ? void 0 : cropZone.width) - 4,
427
417
  height: (cropZone === null || cropZone === void 0 ? void 0 : cropZone.height) - 4,
428
- }));
418
+ });
429
419
  onClear();
430
- dataUri && changeImage(dataUri);
431
- }), [cropZone, changeImage, onClear]);
420
+ if (dataUri)
421
+ changeImage(dataUri);
422
+ }, [cropZone, changeImage, onClear]);
432
423
  const onShapeClick = useCallback((e, id, shape) => {
433
424
  var _a;
434
425
  if (drawAction !== DrawAction.Select)
@@ -540,9 +531,12 @@ export const ImageEditor = React.forwardRef((props, ref) => {
540
531
  const resultV = getAllSnapLines('vertical');
541
532
  const resultH = getAllSnapLines('horizontal');
542
533
  const closestSnapLines = [];
543
- const getSnapLine = ({ snapLine, offset, snap }, orientation) => {
544
- return { snapLine, offset, orientation, snap };
545
- };
534
+ const getSnapLine = ({ snapLine, offset, snap }, orientation) => ({
535
+ snapLine,
536
+ offset,
537
+ orientation,
538
+ snap,
539
+ });
546
540
  // find closest vertical and horizontal snappping lines
547
541
  const [minV] = resultV.sort((a, b) => a.diff - b.diff);
548
542
  const [minH] = resultH.sort((a, b) => a.diff - b.diff);
@@ -552,7 +546,7 @@ export const ImageEditor = React.forwardRef((props, ref) => {
552
546
  closestSnapLines.push(getSnapLine(minH, 'H'));
553
547
  return closestSnapLines;
554
548
  };
555
- const drawLines = (lines = []) => {
549
+ const drawLines = useCallback((lines = []) => {
556
550
  if (lines.length > 0) {
557
551
  const lineStyle = {
558
552
  stroke: 'rgb(255, 81, 12)',
@@ -576,7 +570,7 @@ export const ImageEditor = React.forwardRef((props, ref) => {
576
570
  setHLines(hLines);
577
571
  setVLines(vLines);
578
572
  }
579
- };
573
+ }, []);
580
574
  const onTransformerMove = useCallback((target) => {
581
575
  // const target = transformerRef.current;
582
576
  if (!target)
@@ -621,7 +615,7 @@ export const ImageEditor = React.forwardRef((props, ref) => {
621
615
  };
622
616
  target.setAbsolutePosition(newPos);
623
617
  // selectedNode.setAbsolutePosition(newPos);
624
- }, []);
618
+ }, [getShapeSnappingEdges, getSnapLines, drawLines]);
625
619
  return (React.createElement("div", { style: Object.assign({ width: `${width}px` }, (style || {})) },
626
620
  React.createElement(Flex, { justify: "space-between", align: "center", style: { marginBottom: '6px', display: hideAction ? 'none' : 'flex' } },
627
621
  React.createElement(Flex, { gap: 4 },
@@ -673,7 +667,7 @@ export const ImageEditor = React.forwardRef((props, ref) => {
673
667
  dispatch({
674
668
  type: 'SET_IMAGE_COORDINATE',
675
669
  payload: {
676
- imageCoordinate: Object.assign(Object.assign({}, imageCoordinate), { x: attrs.x, y: attrs.y }),
670
+ imageCoordinate: { x: attrs.x, y: attrs.y },
677
671
  saveHistory: true,
678
672
  },
679
673
  });
@@ -681,7 +675,7 @@ export const ImageEditor = React.forwardRef((props, ref) => {
681
675
  dispatch({
682
676
  type: 'SET_IMAGE_COORDINATE',
683
677
  payload: {
684
- imageCoordinate: Object.assign(Object.assign(Object.assign({}, imageCoordinate), { width: e.target.width(), height: e.target.height() }), getTransformData(e)),
678
+ imageCoordinate: Object.assign({ width: e.target.width(), height: e.target.height() }, getTransformData(e)),
685
679
  saveHistory: true,
686
680
  },
687
681
  });
@@ -52,12 +52,14 @@ type ReducerAction = {
52
52
  } | {
53
53
  type: 'SET_IMAGE_COORDINATE';
54
54
  payload: {
55
- imageCoordinate: ImageCoordinate;
55
+ imageCoordinate: Partial<ImageCoordinate>;
56
56
  saveHistory?: boolean;
57
57
  };
58
58
  } | {
59
59
  type: 'SET_NEW_STATE';
60
- payload: Partial<CanvasState> & {
60
+ payload: Omit<Partial<CanvasState>, 'imageCoordinate'> & {
61
+ imageCoordinate?: Partial<ImageCoordinate>;
62
+ } & {
61
63
  saveHistory?: boolean;
62
64
  };
63
65
  } | {
@@ -23,14 +23,16 @@ export const reducer = (state, action) => {
23
23
  case 'SET_IMAGE_COORDINATE':
24
24
  case 'SET_NEW_STATE': {
25
25
  const newHistoryStep = state.historyStep + 1;
26
- const newState = Object.assign(Object.assign({}, state.current), payload);
26
+ const newImageCoordinate = Object.assign(Object.assign({}, state.current.imageCoordinate), (type === 'SET_NEW_STATE' || type === 'SET_IMAGE_COORDINATE'
27
+ ? payload.imageCoordinate || {}
28
+ : {}));
29
+ const newState = Object.assign(Object.assign(Object.assign({}, state.current), payload), { imageCoordinate: newImageCoordinate });
27
30
  return Object.assign(Object.assign({}, state), { history: payload.saveHistory
28
31
  ? state.history.slice(0, newHistoryStep).concat([newState])
29
32
  : state.history, historyStep: payload.saveHistory ? newHistoryStep : state.historyStep, current: newState });
30
33
  }
31
34
  case 'SAVE_HISTORY': {
32
35
  return Object.assign(Object.assign({}, state), { historyStep: state.historyStep + 1, history: state.history.slice(0, state.historyStep + 1).concat([state.current]) });
33
- break;
34
36
  }
35
37
  case 'UNDO': {
36
38
  if (state.historyStep === 0) {
@@ -77,7 +77,7 @@ export interface TemplateSaveAsProps {
77
77
  value?: TemplateValueOptions;
78
78
  onChange?: (value: Partial<TemplateValueOptions>, errors?: any[]) => void;
79
79
  onSaveThumbnail?: (data: {
80
- thumbnails: (string | undefined)[];
80
+ thumbnails: ImageSliderProps['thumbnails'];
81
81
  thumbnailChange: number;
82
82
  }) => void;
83
83
  onEvent?: (value: Partial<TemplateValueOptions>) => void;
@@ -1,6 +1,10 @@
1
1
  import React from 'react';
2
+ type SliderThumbnail = {
3
+ url: string;
4
+ showSkeleton?: boolean;
5
+ };
2
6
  export interface ImageSliderProps {
3
- thumbnails: (string | undefined)[];
7
+ thumbnails: (string | SliderThumbnail | undefined)[];
4
8
  isLoading?: boolean;
5
9
  className?: string;
6
10
  skeleton?: boolean;
@@ -19,8 +23,9 @@ export interface ImageSliderProps {
19
23
  defaultThumbnail?: number;
20
24
  onSelectDefault?: (imgIndex: number) => void;
21
25
  onSaveThumbnail?: (data: {
22
- thumbnails: (string | undefined)[];
26
+ thumbnails: ImageSliderProps['thumbnails'];
23
27
  thumbnailChange: number;
24
28
  }) => void;
25
29
  }
26
30
  export declare const ImageSlider: React.FC<ImageSliderProps>;
31
+ export {};
@@ -1,5 +1,5 @@
1
1
  // Libraries
2
- import React, { useState, useRef, useMemo, useCallback, useEffect } from 'react';
2
+ import React, { useState, useRef, useMemo, useCallback } from 'react';
3
3
  import Icon from '@antscorp/icons';
4
4
  // Components
5
5
  import { Button, Flex, ImageResize, message, Spin, Typography, ImageResizeTuiEditor, } from '@antscorp/antsomi-ui/es/components';
@@ -7,7 +7,7 @@ import { Button, Flex, ImageResize, message, Spin, Typography, ImageResizeTuiEdi
7
7
  import { ImageSliderStyled } from './styled';
8
8
  import { SmallImage } from './SmallImage';
9
9
  import { BigImage } from './BigImage';
10
- import { useDropFile } from '@antscorp/antsomi-ui/es/hooks';
10
+ import { useDeepCompareEffect, useDeepCompareMemo, useDropFile, } from '@antscorp/antsomi-ui/es/hooks';
11
11
  import { checkShowSkeletonBaseUrl, getUrlNoCache } from '@antscorp/antsomi-ui/es/utils';
12
12
  import { isNil } from 'lodash';
13
13
  // Image size limit to 10MB
@@ -28,7 +28,7 @@ export const ImageSlider = props => {
28
28
  const [uploadThumbnail, setUploadThumbnail] = useState();
29
29
  const [latestCanvas, setLatestCanvas] = useState();
30
30
  // Effects
31
- useEffect(() => {
31
+ useDeepCompareEffect(() => {
32
32
  setDefaultThumbnailInternal(defaultThumbnail || 0);
33
33
  }, [defaultThumbnail]);
34
34
  const handleScroll = useCallback((scrollIndex) => {
@@ -49,14 +49,14 @@ export const ImageSlider = props => {
49
49
  handleScroll(newValue);
50
50
  return newValue;
51
51
  });
52
- }, [thumbnails, handleScroll]);
52
+ }, [handleScroll, thumbnailsQuantity]);
53
53
  const handlePrevThumbnail = useCallback(() => {
54
54
  setSelectedThumbnail(prev => {
55
55
  const newValue = prev === 0 ? thumbnailsQuantity - 1 : prev - 1;
56
56
  handleScroll(newValue);
57
57
  return newValue;
58
58
  });
59
- }, [thumbnails, handleScroll]);
59
+ }, [handleScroll, thumbnailsQuantity]);
60
60
  const handleSelectThumbnail = useCallback((index) => {
61
61
  handleScroll(index);
62
62
  setSelectedThumbnail(index);
@@ -68,19 +68,26 @@ export const ImageSlider = props => {
68
68
  onSelectDefault(index);
69
69
  }
70
70
  }, [onSelectDefault]);
71
- const handleSaveThumbnail = () => {
72
- var _a;
73
- const newThumbnail = [...thumbnails];
71
+ const handleSaveThumbnail = useCallback(() => {
72
+ var _a, _b;
73
+ const newThumbnails = [...thumbnails];
74
74
  // NOTE: https://konvajs.org/docs/data_and_serialization/High-Quality-Export.html
75
- newThumbnail[selectedThumbnail] = (_a = imageResizeRef.current) === null || _a === void 0 ? void 0 : _a.getBase64({ pixelRatio: 2.5 });
76
- onSaveThumbnail === null || onSaveThumbnail === void 0 ? void 0 : onSaveThumbnail({ thumbnails: newThumbnail, thumbnailChange: selectedThumbnail });
75
+ const base64Url = ((_a = imageResizeRef.current) === null || _a === void 0 ? void 0 : _a.getBase64({ pixelRatio: 2.5 })) || '';
76
+ if (typeof newThumbnails[selectedThumbnail] === 'object' &&
77
+ ((_b = newThumbnails[selectedThumbnail]) === null || _b === void 0 ? void 0 : _b.url)) {
78
+ newThumbnails[selectedThumbnail].url = base64Url;
79
+ }
80
+ else {
81
+ newThumbnails[selectedThumbnail] = base64Url;
82
+ }
83
+ onSaveThumbnail === null || onSaveThumbnail === void 0 ? void 0 : onSaveThumbnail({ thumbnails: newThumbnails, thumbnailChange: selectedThumbnail });
77
84
  setLatestCanvas(prev => {
78
85
  var _a;
79
86
  return (Object.assign(Object.assign({}, prev), { [selectedThumbnail]: (_a = imageResizeRef.current) === null || _a === void 0 ? void 0 : _a.getCurrentState() }));
80
87
  });
81
88
  setEditingThumbnail(undefined);
82
89
  handleSelectThumbnail(selectedThumbnail);
83
- };
90
+ }, [handleSelectThumbnail, onSaveThumbnail, selectedThumbnail, thumbnails]);
84
91
  const fileRef = useRef(null);
85
92
  const onImportImageClick = useCallback(() => {
86
93
  var _a;
@@ -90,7 +97,13 @@ export const ImageSlider = props => {
90
97
  var _a, _b, _c;
91
98
  if ((_a = e.target.files) === null || _a === void 0 ? void 0 : _a[0]) {
92
99
  if (((_b = e.target.files) === null || _b === void 0 ? void 0 : _b[0].size) > SIZE_LIMIT) {
93
- return message.error('File size too big');
100
+ // return message.error('File size too big');
101
+ message.error({
102
+ content: 'File size too big',
103
+ style: { fontSize: '11px', fontFamily: 'Roboto' },
104
+ });
105
+ e.target.files = null;
106
+ return;
94
107
  }
95
108
  (_c = imageResizeRef.current) === null || _c === void 0 ? void 0 : _c.replaceImageWithUrl(URL.createObjectURL(e.target.files[0]));
96
109
  setUploadThumbnail(undefined);
@@ -102,25 +115,39 @@ export const ImageSlider = props => {
102
115
  if (!((_a = e === null || e === void 0 ? void 0 : e.dataTransfer) === null || _a === void 0 ? void 0 : _a.files[0]))
103
116
  return;
104
117
  if (((_b = e === null || e === void 0 ? void 0 : e.dataTransfer) === null || _b === void 0 ? void 0 : _b.files[0].size) > SIZE_LIMIT) {
105
- return message.error('File size too big');
118
+ message.error({
119
+ content: 'File size too big',
120
+ style: { fontSize: '11px', fontFamily: 'Roboto' },
121
+ });
122
+ return;
106
123
  }
107
124
  (_c = imageResizeRef.current) === null || _c === void 0 ? void 0 : _c.replaceImageWithUrl(URL.createObjectURL((_d = e === null || e === void 0 ? void 0 : e.dataTransfer) === null || _d === void 0 ? void 0 : _d.files[0]));
108
125
  setUploadThumbnail(undefined);
109
126
  });
110
- const currentTime = useMemo(() => new Date(), []);
127
+ const currentTime = useDeepCompareMemo(() => new Date(), []);
111
128
  const timeGenerated = Math.floor(currentTime.getTime() / 1000 - (currentTime.getTime() % 3)) * 1000;
112
- const currentEditing = useMemo(() => editingThumbnail !== null && editingThumbnail !== void 0 ? editingThumbnail : uploadThumbnail, [editingThumbnail, uploadThumbnail]);
129
+ const currentEditing = useDeepCompareMemo(() => editingThumbnail !== null && editingThumbnail !== void 0 ? editingThumbnail : uploadThumbnail, [editingThumbnail, uploadThumbnail]);
130
+ const currentThumbnailUrl = useDeepCompareMemo(() => {
131
+ const currentThumbnail = thumbnails[currentEditing];
132
+ return typeof currentThumbnail === 'string' ? currentThumbnail : (currentThumbnail === null || currentThumbnail === void 0 ? void 0 : currentThumbnail.url) || '';
133
+ }, [currentEditing, thumbnails]);
134
+ const showSkeletonMemo = useDeepCompareMemo(() => {
135
+ const currentThumbnail = thumbnails[currentEditing];
136
+ const showSkeleton = typeof currentThumbnail === 'object' && !isNil(currentThumbnail === null || currentThumbnail === void 0 ? void 0 : currentThumbnail.showSkeleton)
137
+ ? currentThumbnail === null || currentThumbnail === void 0 ? void 0 : currentThumbnail.showSkeleton
138
+ : skeleton !== undefined
139
+ ? skeleton
140
+ : checkShowSkeletonBaseUrl(getUrlNoCache(currentThumbnailUrl, timeGenerated));
141
+ return showSkeleton;
142
+ }, [currentEditing, currentThumbnailUrl, skeleton, thumbnails, timeGenerated]);
113
143
  const ImageResizeComponent = useFabric ? ImageResizeTuiEditor : ImageResize;
114
- const showSkeletonMemo = skeleton !== undefined
115
- ? skeleton
116
- : checkShowSkeletonBaseUrl(getUrlNoCache(thumbnails[currentEditing], timeGenerated));
117
- return (React.createElement(ImageSliderStyled, { className: className || '', "$skeleton": skeleton, "$imageWidth": imageWidth, "$smallImageWidth": smallImageWidth, "$imageHeight": imageHeight, vertical: true, gap: 10 },
144
+ return (React.createElement(ImageSliderStyled, { className: className || '', "$skeleton": showSkeletonMemo, "$imageWidth": imageWidth, "$smallImageWidth": smallImageWidth, "$imageHeight": imageHeight, vertical: true, gap: 10 },
118
145
  React.createElement(Flex, { vertical: true, style: { zIndex: 25, display: !isNil(currentEditing) ? 'flex' : 'none' }, className: `edit-thumbnail-container ${!isNil(currentEditing) ? 'is-editing' : ''}` },
119
146
  React.createElement(ImageResizeComponent, { style: { visibility: typeof uploadThumbnail === 'number' ? 'hidden' : 'visible' }, className: "image-resize-wrapper", width: imageWidth, height: imageHeight, ref: imageResizeRef, hideAction: true, imageUrl:
120
147
  // latestCanvas && isEditPrevious
121
148
  (latestCanvas === null || latestCanvas === void 0 ? void 0 : latestCanvas[currentEditing])
122
149
  ? undefined
123
- : getUrlNoCache(thumbnails[currentEditing], timeGenerated),
150
+ : getUrlNoCache(currentThumbnailUrl, timeGenerated),
124
151
  // imageUrl={getUrlNoCache(
125
152
  // thumbnails[editingThumbnail ?? (uploadThumbnail as number)],
126
153
  // timeGenerated,
@@ -132,20 +159,32 @@ export const ImageSlider = props => {
132
159
  React.createElement(Typography.Text, { style: { fontSize: 16, marginBottom: '10px' } }, "Drag & Drop file here"),
133
160
  React.createElement("input", { type: "file", ref: fileRef, onChange: onImportImageSelect, style: { display: 'none' }, accept: "image/*" }),
134
161
  React.createElement(Button, { onClick: onImportImageClick }, "Browse Image"),
135
- React.createElement(Typography.Text, { style: { marginTop: '5px' } }, "File type: .jpg, .png. File size: under 10MB")))),
162
+ React.createElement(Typography.Text, { style: { marginTop: '5px', fontSize: '11px' } }, "File type: .jpg, .png. File size: under 10MB")))),
136
163
  React.createElement(Flex, { justify: "center", align: "center", gap: 8, className: "image-resize-action" },
137
164
  React.createElement(Button, { onClick: handleSaveThumbnail, type: "primary", disabled: uploadThumbnail !== undefined }, "Save"),
138
165
  React.createElement(Button, { onClick: () => {
139
166
  setEditingThumbnail(undefined);
140
167
  setUploadThumbnail(undefined);
141
168
  } }, "Cancel"))),
142
- React.createElement(Flex, { className: "thumbnail-preview-container", ref: thumbnailSelectedRef, style: { display: !isNil(currentEditing) ? 'none' : 'flex' } }, isLoading ? (React.createElement(Spin, { spinning: true })) : (thumbnails.map((url, index) => (React.createElement(BigImage, { key: `image-big_${url}_${index * 2}`, url: url, index: index, showSkeleton: skeleton, isDefaultThumbnail: defaultThumbnailInternal === index, isHideDefaultButton: hideDefaultButton || hideThumbnailsList || thumbnailsQuantity <= 1, imageFit: thumbnailFit, onClickDefaultButton: handleClickDefault, onClickEdit: () => setEditingThumbnail(selectedThumbnail),
143
- // onClickEdit={index => setEditingThumbnail(index)}
144
- onClickUpload: () => {
145
- setEditingThumbnail(selectedThumbnail);
146
- setUploadThumbnail(selectedThumbnail);
147
- } }))))),
148
- hideThumbnailsList || thumbnailsQuantity <= 1 ? null : (React.createElement(Flex, { gap: 10, className: "thumbnail-slider-container", ref: sliderContainerRef, style: { justifyContent: thumbnailsQuantity < slidesPerView ? 'center' : 'flex-start' } }, isLoading ? (React.createElement(Spin, { spinning: true })) : (thumbnails.map((url, index) => (React.createElement(SmallImage, { imageFit: thumbnailFit, key: `${url}_${index * 2}`, showSkeleton: skeleton, isSelected: index === selectedThumbnail, url: url, index: index, onClick: handleSelectThumbnail })))))),
169
+ React.createElement(Flex, { className: "thumbnail-preview-container", ref: thumbnailSelectedRef, style: { display: !isNil(currentEditing) ? 'none' : 'flex' } }, isLoading ? (React.createElement(Spin, { spinning: true })) : (thumbnails.map((thumbnail, index) => {
170
+ const url = typeof thumbnail === 'string' ? thumbnail : (thumbnail === null || thumbnail === void 0 ? void 0 : thumbnail.url) || '';
171
+ const showSkeleton = typeof thumbnail === 'object' && !isNil(thumbnail === null || thumbnail === void 0 ? void 0 : thumbnail.showSkeleton)
172
+ ? thumbnail === null || thumbnail === void 0 ? void 0 : thumbnail.showSkeleton
173
+ : skeleton;
174
+ return (React.createElement(BigImage, { key: `image-big_${url}_${index * 2}`, url: url, index: index, showSkeleton: showSkeleton, isDefaultThumbnail: defaultThumbnailInternal === index, isHideDefaultButton: hideDefaultButton || hideThumbnailsList || thumbnailsQuantity <= 1, imageFit: thumbnailFit, onClickDefaultButton: handleClickDefault, onClickEdit: () => setEditingThumbnail(selectedThumbnail),
175
+ // onClickEdit={index => setEditingThumbnail(index)}
176
+ onClickUpload: () => {
177
+ setEditingThumbnail(selectedThumbnail);
178
+ setUploadThumbnail(selectedThumbnail);
179
+ } }));
180
+ }))),
181
+ hideThumbnailsList || thumbnailsQuantity <= 1 ? null : (React.createElement(Flex, { gap: 10, className: "thumbnail-slider-container", ref: sliderContainerRef, style: { justifyContent: thumbnailsQuantity < slidesPerView ? 'center' : 'flex-start' } }, isLoading ? (React.createElement(Spin, { spinning: true })) : (thumbnails.map((thumbnail, index) => {
182
+ const url = typeof thumbnail === 'string' ? thumbnail : (thumbnail === null || thumbnail === void 0 ? void 0 : thumbnail.url) || '';
183
+ const showSkeleton = typeof thumbnail === 'object' && !isNil(thumbnail === null || thumbnail === void 0 ? void 0 : thumbnail.showSkeleton)
184
+ ? thumbnail === null || thumbnail === void 0 ? void 0 : thumbnail.showSkeleton
185
+ : skeleton;
186
+ return (React.createElement(SmallImage, { imageFit: thumbnailFit, key: `${url}_${index * 2}`, showSkeleton: showSkeleton, isSelected: index === selectedThumbnail, url: url, index: index, onClick: handleSelectThumbnail }));
187
+ })))),
149
188
  previewNavigation && !isLoading ? (React.createElement(React.Fragment, null,
150
189
  React.createElement(ButtonSlider, { direction: "left", type: "preview", onClick: handlePrevThumbnail }),
151
190
  React.createElement(ButtonSlider, { direction: "right", type: "preview", onClick: handleNextThumbnail }))) : null,
@@ -46,7 +46,7 @@ export * from './SelectMulti';
46
46
  export * from './SelectEventAttribute';
47
47
  export * from './DatePickerV2';
48
48
  export { ModalSelect } from './ModalSelect';
49
- export { EmptyData, EmptyDataProps } from './EmptyData';
49
+ export * from './EmptyData';
50
50
  export * from './PreviewModal';
51
51
  export * from './Drawer';
52
52
  export * from './DrawerDetail';
@@ -46,7 +46,7 @@ export * from './SelectMulti';
46
46
  export * from './SelectEventAttribute';
47
47
  export * from './DatePickerV2';
48
48
  export { ModalSelect } from './ModalSelect';
49
- export { EmptyData } from './EmptyData';
49
+ export * from './EmptyData';
50
50
  export * from './PreviewModal';
51
51
  export * from './Drawer';
52
52
  export * from './DrawerDetail';
@@ -30,7 +30,7 @@ import '@antscorp/processing-notification/dist/index.css';
30
30
  import { useLayoutStore } from './stores';
31
31
  // Utils
32
32
  import { checkingRoleScope } from './utils';
33
- const { DATAFLOWS } = APP_CODES;
33
+ const { DATAFLOWS, APP_ANTALYSER } = APP_CODES;
34
34
  export const Layout = memo(props => {
35
35
  const { leftMenuProps, headerProps = {}, workspaceProps, processingNotificationProps, children, onActiveMenuChange, } = props;
36
36
  const _a = leftMenuProps || {}, { className = '' } = _a, restOfLeftMenuProps = __rest(_a, ["className"]);
@@ -52,6 +52,7 @@ export const Layout = memo(props => {
52
52
  return PERMISSION_API;
53
53
  switch (appCode) {
54
54
  case DATAFLOWS:
55
+ case APP_ANTALYSER:
55
56
  return ((_a = APP_PERMISSION_DOMAIN[appCode]) === null || _a === void 0 ? void 0 : _a[env || 'development']) || PERMISSION_API;
56
57
  default:
57
58
  return PERMISSION_API;
@@ -67,6 +68,7 @@ export const Layout = memo(props => {
67
68
  return IAM_API;
68
69
  switch (appCode) {
69
70
  case DATAFLOWS:
71
+ case APP_ANTALYSER:
70
72
  return ((_a = APP_IAM_DOMAIN[appCode]) === null || _a === void 0 ? void 0 : _a[env || 'development']) || IAM_API;
71
73
  default:
72
74
  return IAM_API;
@@ -1,7 +1,7 @@
1
1
  // Constants
2
2
  import { ENV } from '../config';
3
3
  import { APP_CODES } from './variables';
4
- const { DATAFLOWS } = APP_CODES;
4
+ const { DATAFLOWS, APP_ANTALYSER } = APP_CODES;
5
5
  export const TINYMCE_API_KEY = 'scyw71pj8619analvxs56ppc2w2fj2kpy5vnmflhhc300y35';
6
6
  export const CDP_API = {
7
7
  [ENV.DEV]: 'https://sandbox-app.cdp.asia',
@@ -23,6 +23,11 @@ export const APP_PERMISSION_DOMAIN = {
23
23
  [ENV.SANDBOX]: 'https://sandbox-permission.ants.vn',
24
24
  [ENV.PROD]: 'https://permission.antsomi.com',
25
25
  },
26
+ [APP_ANTALYSER]: {
27
+ [ENV.DEV]: 'https://sandbox-permission.ants.vn',
28
+ [ENV.SANDBOX]: 'https://sandbox-permission.ants.vn',
29
+ [ENV.PROD]: 'https://permission.antsomi.com',
30
+ },
26
31
  };
27
32
  export const APP_IAM_DOMAIN = {
28
33
  [DATAFLOWS]: {
@@ -30,4 +35,9 @@ export const APP_IAM_DOMAIN = {
30
35
  [ENV.SANDBOX]: 'https://sandbox-aacm.ants.vn',
31
36
  [ENV.PROD]: 'https://iam.ants.tech',
32
37
  },
38
+ [APP_ANTALYSER]: {
39
+ [ENV.DEV]: 'https://sandbox-aacm.ants.vn',
40
+ [ENV.SANDBOX]: 'https://sandbox-aacm.ants.vn',
41
+ [ENV.PROD]: 'https://iam.ants.tech',
42
+ },
33
43
  };
@@ -19,6 +19,7 @@ export declare const GET_LIST_TYPE: {
19
19
  };
20
20
  export declare const APP_CODES: {
21
21
  DATAFLOWS: string;
22
+ APP_ANTALYSER: string;
22
23
  };
23
24
  export declare const PORTALS_IDS: {
24
25
  SANDBOX: number;
@@ -20,6 +20,7 @@ export const GET_LIST_TYPE = {
20
20
  /* APP_CODES */
21
21
  export const APP_CODES = {
22
22
  DATAFLOWS: 'DATAFLOWS',
23
+ APP_ANTALYSER: 'APP_ANTALYSER',
23
24
  };
24
25
  export const PORTALS_IDS = {
25
26
  SANDBOX: 33167,
@@ -5,6 +5,7 @@ export interface AppConfigProps {
5
5
  env?: envType;
6
6
  auth?: Omit<PayloadInfo, 'url'>;
7
7
  appCode?: string;
8
+ menuCode?: string;
8
9
  languageCode?: string;
9
10
  urlLogout?: string;
10
11
  setAppConfig: React.Dispatch<React.SetStateAction<AppConfigProviderProps>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antscorp/antsomi-ui",
3
- "version": "1.3.5-beta.274",
3
+ "version": "1.3.5-beta.276",
4
4
  "description": "An enterprise-class UI design language and React UI library.",
5
5
  "sideEffects": [
6
6
  "dist/*",