@antscorp/antsomi-ui 1.7.6 → 1.7.7

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 (43) hide show
  1. package/es/components/icons/DataIcon.js +3 -13
  2. package/es/components/icons/ExpandLessIcon.d.ts +3 -0
  3. package/es/components/icons/ExpandLessIcon.js +8 -0
  4. package/es/components/icons/GridViewIcon.d.ts +3 -0
  5. package/es/components/icons/GridViewIcon.js +10 -0
  6. package/es/components/icons/SearchIcon.d.ts +3 -0
  7. package/es/components/icons/SearchIcon.js +9 -0
  8. package/es/components/icons/ViewColumnIcon.d.ts +3 -0
  9. package/es/components/icons/ViewColumnIcon.js +10 -0
  10. package/es/components/icons/hooks/useIcon.d.ts +2 -2
  11. package/es/components/icons/hooks/useIcon.js +1 -1
  12. package/es/components/icons/index.d.ts +5 -1
  13. package/es/components/icons/index.js +5 -1
  14. package/es/components/molecules/MatchAnySelect/MatchesAnySelect.js +1 -1
  15. package/es/components/molecules/ThumbnailCard/ThumbnailCard.js +6 -6
  16. package/es/components/molecules/ThumbnailCard/types.d.ts +1 -0
  17. package/es/components/organism/DataTable/DataTable.js +25 -4
  18. package/es/components/organism/DataTable/components/GridView/index.d.ts +5 -0
  19. package/es/components/organism/DataTable/components/GridView/index.js +13 -0
  20. package/es/components/organism/DataTable/components/Table/ResizableCell.js +4 -4
  21. package/es/components/organism/DataTable/components/Table/index.js +1 -1
  22. package/es/components/organism/DataTable/components/Table/styled.js +20 -0
  23. package/es/components/organism/DataTable/components/Toolbar/ToolbarActionButtons.js +21 -8
  24. package/es/components/organism/DataTable/components/index.d.ts +1 -0
  25. package/es/components/organism/DataTable/components/index.js +1 -0
  26. package/es/components/organism/DataTable/constants/theme.js +1 -1
  27. package/es/components/organism/DataTable/constants/toolbar.d.ts +4 -0
  28. package/es/components/organism/DataTable/constants/toolbar.js +15 -3
  29. package/es/components/organism/DataTable/hooks/useDataTableListing/types.d.ts +18 -1
  30. package/es/components/organism/DataTable/hooks/useDataTableListing/useDataTableListing.d.ts +5 -1
  31. package/es/components/organism/DataTable/hooks/useDataTableListing/useDataTableListing.js +77 -17
  32. package/es/components/organism/DataTable/styled/index.d.ts +1 -0
  33. package/es/components/organism/DataTable/styled/index.js +23 -2
  34. package/es/components/organism/DataTable/types/index.d.ts +2 -0
  35. package/es/components/organism/DataTable/types/toolbar.d.ts +11 -2
  36. package/es/components/organism/LeftMenu/constants/variables.js +1 -0
  37. package/es/components/template/Layout/Layout.js +6 -5
  38. package/es/components/template/TemplateListing/index.js +2 -3
  39. package/es/constants/theme.js +18 -0
  40. package/es/tests/DataTableTest.js +4 -0
  41. package/es/types/actionsButton.d.ts +2 -2
  42. package/package.json +1 -1
  43. package/CHANGELOG.md +0 -91
@@ -1,18 +1,8 @@
1
- var __rest = (this && this.__rest) || function (s, e) {
2
- var t = {};
3
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
- t[p] = s[p];
5
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
- t[p[i]] = s[p[i]];
9
- }
10
- return t;
11
- };
12
1
  // Libraries
13
2
  import React, { forwardRef } from 'react';
3
+ import { useIcon } from './hooks/useIcon';
14
4
  export const DataIcon = forwardRef((props, ref) => {
15
- const restProps = __rest(props, []);
16
- return (React.createElement("svg", Object.assign({ ref: ref, width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, restProps),
5
+ const { width, height } = useIcon(props);
6
+ return (React.createElement("svg", Object.assign({ viewBox: "0 0 24 24", fill: "currentColor", xmlns: "http://www.w3.org/2000/svg" }, props, { ref: ref, width: width, height: height }),
17
7
  React.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M19.002 6.5C19.002 7.88071 15.6499 9 11.515 9C7.38 9 4.02795 7.88071 4.02795 6.5C4.02795 5.11929 7.38 4 11.515 4C15.6499 4 19.002 5.11929 19.002 6.5ZM18.974 12.131C18.974 13.42 15.622 14.465 11.487 14.465C7.352 14.465 4 13.419 4 12.131V8.46204C4 9.75104 7.352 10.795 11.487 10.795C15.622 10.795 18.974 9.74904 18.974 8.46204V12.131ZM18.974 17.8423C18.974 19.1313 15.622 20.1763 11.487 20.1763C7.352 20.1763 4 19.1303 4 17.8423V14.1733C4 15.4623 7.352 16.5063 11.487 16.5063C15.622 16.5063 18.974 15.4603 18.974 14.1733V17.8423Z", fill: "currentColor" })));
18
8
  });
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { IconProps } from './type';
3
+ export declare const ExpandLessIcon: React.ForwardRefExoticComponent<IconProps & React.RefAttributes<SVGSVGElement>>;
@@ -0,0 +1,8 @@
1
+ import React, { forwardRef } from 'react';
2
+ import { useIcon } from './hooks/useIcon';
3
+ export const ExpandLessIcon = forwardRef((props, ref) => {
4
+ const { width, height } = useIcon(props);
5
+ return (React.createElement("svg", Object.assign({ viewBox: "0 0 24 24", fill: "currentColor", xmlns: "http://www.w3.org/2000/svg" }, props, { ref: ref, height: height, width: width }),
6
+ React.createElement("path", { d: "M0 0h24v24H0V0z", fill: "none" }),
7
+ React.createElement("path", { d: "M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14l-6-6z" })));
8
+ });
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { IconProps } from './type';
3
+ export declare const GridViewIcon: React.ForwardRefExoticComponent<IconProps & React.RefAttributes<SVGSVGElement>>;
@@ -0,0 +1,10 @@
1
+ // Libraries
2
+ import React, { forwardRef } from 'react';
3
+ import { useIcon } from './hooks/useIcon';
4
+ export const GridViewIcon = forwardRef((props, ref) => {
5
+ const { width, height } = useIcon(props);
6
+ return (React.createElement("svg", Object.assign({ xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor" }, props, { ref: ref, height: height, width: width }),
7
+ React.createElement("g", { fillRule: "evenodd" },
8
+ React.createElement("path", { d: "M0 0h24v24H0z", fill: "none" }),
9
+ React.createElement("path", { d: "M3 3v8h8V3H3zm6 6H5V5h4v4zm-6 4v8h8v-8H3zm6 6H5v-4h4v4zm4-16v8h8V3h-8zm6 6h-4V5h4v4zm-6 4v8h8v-8h-8zm6 6h-4v-4h4v4z" }))));
10
+ });
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { IconProps } from './type';
3
+ export declare const SearchIcon: React.ForwardRefExoticComponent<IconProps & React.RefAttributes<SVGSVGElement>>;
@@ -0,0 +1,9 @@
1
+ // Libraries
2
+ import React, { forwardRef } from 'react';
3
+ import { useIcon } from './hooks/useIcon';
4
+ export const SearchIcon = forwardRef((props, ref) => {
5
+ const { width, height } = useIcon(props);
6
+ return (React.createElement("svg", Object.assign({ xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24" }, props, { ref: ref, height: height, width: width, fill: "currentColor" }),
7
+ React.createElement("path", { d: "M0 0h24v24H0V0z", fill: "none" }),
8
+ React.createElement("path", { d: "M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" })));
9
+ });
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { IconProps } from './type';
3
+ export declare const ViewColumnIcon: React.ForwardRefExoticComponent<IconProps & React.RefAttributes<SVGSVGElement>>;
@@ -0,0 +1,10 @@
1
+ // Libraries
2
+ import React, { forwardRef } from 'react';
3
+ import { useIcon } from './hooks/useIcon';
4
+ export const ViewColumnIcon = forwardRef((props, ref) => {
5
+ const { width, height } = useIcon(props);
6
+ return (React.createElement("svg", Object.assign({ xmlns: "http://www.w3.org/2000/svg", enableBackground: "new 0 0 24 24" }, props, { viewBox: "0 0 24 24", ref: ref, height: height, width: width, fill: "currentColor" }),
7
+ React.createElement("rect", { fill: "none", height: "24", width: "24" }),
8
+ React.createElement("g", null,
9
+ React.createElement("path", { d: "M14.67,5v14H9.33V5H14.67z M15.67,19H21V5h-5.33V19z M8.33,19V5H3v14H8.33z" }))));
10
+ });
@@ -1,5 +1,5 @@
1
1
  import { IconProps } from '../type';
2
2
  export declare const useIcon: (props: IconProps) => {
3
- width: string | number | undefined;
4
- height: string | number | undefined;
3
+ width: string | number;
4
+ height: string | number;
5
5
  };
@@ -1,7 +1,7 @@
1
1
  import { useMemo } from 'react';
2
2
  export const useIcon = (props) => {
3
3
  const { size = 24 } = props;
4
- const [width, height] = useMemo(() => [size || (props === null || props === void 0 ? void 0 : props.width), size || (props === null || props === void 0 ? void 0 : props.height)], [size, props.width, props.height]);
4
+ const [width, height] = useMemo(() => [(props === null || props === void 0 ? void 0 : props.width) || size, (props === null || props === void 0 ? void 0 : props.height) || size], [size, props.width, props.height]);
5
5
  return {
6
6
  width,
7
7
  height,
@@ -54,5 +54,9 @@ export { Interactive } from './Interactive';
54
54
  export { Web } from './Web';
55
55
  export { LocalMallIcon } from './LocalMallIcon';
56
56
  export { LoadingIcon } from './LoadingIcon';
57
- export { TableIcon } from './TableIcon';
58
57
  export { DataIcon } from './DataIcon';
58
+ export { TableIcon } from './TableIcon';
59
+ export { ExpandLessIcon } from './ExpandLessIcon';
60
+ export { SearchIcon } from './SearchIcon';
61
+ export { ViewColumnIcon } from './ViewColumnIcon';
62
+ export { GridViewIcon } from './GridViewIcon';
@@ -54,5 +54,9 @@ export { Interactive } from './Interactive';
54
54
  export { Web } from './Web';
55
55
  export { LocalMallIcon } from './LocalMallIcon';
56
56
  export { LoadingIcon } from './LoadingIcon';
57
- export { TableIcon } from './TableIcon';
58
57
  export { DataIcon } from './DataIcon';
58
+ export { TableIcon } from './TableIcon';
59
+ export { ExpandLessIcon } from './ExpandLessIcon';
60
+ export { SearchIcon } from './SearchIcon';
61
+ export { ViewColumnIcon } from './ViewColumnIcon';
62
+ export { GridViewIcon } from './GridViewIcon';
@@ -229,7 +229,7 @@ export const MatchesAny = props => {
229
229
  React.createElement(Text, { strong: true }, `${t(translations.global.selected)} (${(selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.length) || 0})`),
230
230
  React.createElement(TextButton, { disabled: isDisableRemoveAll, onClick: onRemoveAll }, t(translations.global.removeAll).toString())),
231
231
  React.createElement("div", { className: "matches-any__body" },
232
- React.createElement(Scrollbars, { style: { height: '100%' } }, !(selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.length) ? (React.createElement(EmptyData, { icon: React.createElement(DataIcon, { color: globalToken === null || globalToken === void 0 ? void 0 : globalToken.bw5, width: 48, height: 48 }), description: t(translations.global.selectItemsFromList).toString() })) : (React.createElement(StyledTree, { selectable: false, treeData: selectedTreeData, switcherIcon: props => (React.createElement(Icon, { type: "icon-ants-caret-down", style: {
232
+ React.createElement(Scrollbars, { style: { height: '100%' } }, !(selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.length) ? (React.createElement(EmptyData, { icon: React.createElement(DataIcon, { color: globalToken === null || globalToken === void 0 ? void 0 : globalToken.bw5, size: 48 }), description: t(translations.global.selectItemsFromList).toString() })) : (React.createElement(StyledTree, { selectable: false, treeData: selectedTreeData, switcherIcon: props => (React.createElement(Icon, { type: "icon-ants-caret-down", style: {
233
233
  transform: props.expanded ? 'rotate(0)' : 'rotate(-90deg)',
234
234
  transition: 'transform 0.3s ease',
235
235
  }, color: globalToken === null || globalToken === void 0 ? void 0 : globalToken.bw8 })) }))))));
@@ -221,8 +221,8 @@ export const ThumbnailCard = (props) => {
221
221
  const [modal, contextHolder] = Modal.useModal();
222
222
  const { id, name, width = THUMBNAIL_CARD_DEFAULT_WIDTH, height = THUMBNAIL_CARD_DEFAULT_HEIGHT, thumbnail, thumbnailFit, removable = true, actionAvailable = true, showSkeleton, loading = false, removeModalProps, editBtnProps, previewBtnProps, thumbnailCacheValue, actionButtons, onClickWrapper } = props, restOfProps = __rest(props, ["id", "name", "width", "height", "thumbnail", "thumbnailFit", "removable", "actionAvailable", "showSkeleton", "loading", "removeModalProps", "editBtnProps", "previewBtnProps", "thumbnailCacheValue", "actionButtons", "onClickWrapper"]);
223
223
  const _a = removeModalProps || {}, { onOk } = _a, restOfRemoveTemplateModalProps = __rest(_a, ["onOk"]);
224
- const _b = editBtnProps || {}, { text: editText = 'Use template', onClick: onClickEdit } = _b, restOfEditBtnProps = __rest(_b, ["text", "onClick"]);
225
- const _c = previewBtnProps || {}, { text: previewText = 'Preview', onClick: onClickPreview } = _c, restOfPreviewBtnProps = __rest(_c, ["text", "onClick"]);
224
+ const _b = editBtnProps || {}, { text: editText = 'Use template', onClick: onClickEdit, show: showEditBtn = true } = _b, restOfEditBtnProps = __rest(_b, ["text", "onClick", "show"]);
225
+ const _c = previewBtnProps || {}, { text: previewText = 'Preview', onClick: onClickPreview, show: showPreviewBtn = true } = _c, restOfPreviewBtnProps = __rest(_c, ["text", "onClick", "show"]);
226
226
  // Memo
227
227
  const showSkeletonMemo =
228
228
  // NOTES: Hot fix for showSkeleton base url if showSkeleton is not defined
@@ -286,16 +286,16 @@ export const ThumbnailCard = (props) => {
286
286
  } }))),
287
287
  actionAvailable && !loading && (React.createElement(React.Fragment, null,
288
288
  React.createElement(Flex, { className: "center-action", align: "center", gap: 10, vertical: true },
289
- React.createElement(Button, Object.assign({ type: "primary", className: "animate__animated animate__fadeIn" }, restOfEditBtnProps, { onClick: e => {
289
+ showEditBtn && (React.createElement(Button, Object.assign({ type: "primary", className: "animate__animated animate__fadeIn" }, restOfEditBtnProps, { onClick: e => {
290
290
  e.stopPropagation();
291
291
  onClickEdit === null || onClickEdit === void 0 ? void 0 : onClickEdit(id);
292
292
  } }),
293
- React.createElement(Typography.Text, { ellipsis: { tooltip: editText }, style: { maxWidth: '100%', color: 'inherit' } }, editText)),
294
- React.createElement(Button, Object.assign({ className: "animate__animated animate__fadeIn", onClick: e => {
293
+ React.createElement(Typography.Text, { ellipsis: { tooltip: editText }, style: { maxWidth: '100%', color: 'inherit' } }, editText))),
294
+ showPreviewBtn && (React.createElement(Button, Object.assign({ className: "animate__animated animate__fadeIn", onClick: e => {
295
295
  e.stopPropagation();
296
296
  onClickPreview === null || onClickPreview === void 0 ? void 0 : onClickPreview(id);
297
297
  } }, restOfPreviewBtnProps),
298
- React.createElement(Typography.Text, { ellipsis: { tooltip: previewText }, style: { maxWidth: '100%', color: 'inherit' } }, previewText))),
298
+ React.createElement(Typography.Text, { ellipsis: { tooltip: previewText }, style: { maxWidth: '100%', color: 'inherit' } }, previewText)))),
299
299
  React.createElement("div", { className: "top-right-corner-action animate__animated animate__fadeIn" },
300
300
  renderActionButtons(),
301
301
  removable && (React.createElement(Tooltip, { title: i18nInstance.t(translations.remove).toString() },
@@ -6,6 +6,7 @@ export type TRemoveModalProps = Omit<ModalFuncProps, 'onOk'> & {
6
6
  onOk?: (id: TThumbnailCardId) => void;
7
7
  };
8
8
  export type TThumbnailButton = Omit<ButtonProps, 'onClick'> & {
9
+ show?: boolean;
9
10
  text?: string;
10
11
  onClick?: (id: TThumbnailCardId) => void;
11
12
  };
@@ -14,22 +14,43 @@ var __rest = (this && this.__rest) || function (s, e) {
14
14
  import React from 'react';
15
15
  // Hooks
16
16
  import { useDataTable } from './hooks';
17
+ import { useDeepCompareMemo } from '@antscorp/antsomi-ui/es/hooks';
17
18
  // Styled
18
- import { DataTableWrapper } from './styled';
19
+ import { DataTableContent, DataTableWrapper } from './styled';
20
+ // Constants
21
+ import { GRID_VIEW_KEYS } from './constants';
19
22
  // Components
20
- import { Table, Pagination, Toolbar } from './components';
23
+ import { Table, Pagination, Toolbar, GridView } from './components';
21
24
  // Providers
22
25
  import { DataTableProvider } from './providers/DataTableProvider';
23
26
  import { AntdTableConfigProvider } from './providers';
24
27
  // Store
25
28
  import { useDataTableStore } from './hooks/useDataTableStore';
29
+ const { GRID, TABLE } = GRID_VIEW_KEYS;
30
+ const RENDER_VIEW_COMPONENTS = {
31
+ [GRID]: React.createElement(GridView, null),
32
+ [TABLE]: React.createElement(Table, null),
33
+ };
26
34
  function DataTableComponent(props) {
35
+ const { contentRender } = props || {};
27
36
  // Hooks
28
37
  const { pagination, toolbar, setPagination } = useDataTable(props);
29
- const { show: showToolbar = true } = toolbar || {};
38
+ const { show: showToolbar = true, actionButtons } = toolbar || {};
39
+ const { GRID_VIEW } = actionButtons || {};
40
+ const renderModeView = useDeepCompareMemo(() => {
41
+ // Check if has content render then return this content
42
+ if (contentRender) {
43
+ return contentRender();
44
+ }
45
+ const modeView = (GRID_VIEW === null || GRID_VIEW === void 0 ? void 0 : GRID_VIEW.mode) || 'TABLE';
46
+ const renderContentWrapper = (key = 'TABLE', children) => (React.createElement(DataTableContent, { style: {
47
+ display: key === modeView ? 'flex' : 'none',
48
+ } }, children));
49
+ return Object.keys(RENDER_VIEW_COMPONENTS).map(key => (React.createElement(React.Fragment, { key: key }, renderContentWrapper(key, RENDER_VIEW_COMPONENTS[key]))));
50
+ }, [GRID_VIEW === null || GRID_VIEW === void 0 ? void 0 : GRID_VIEW.mode, contentRender]);
30
51
  return (React.createElement(DataTableWrapper, null,
31
52
  !!showToolbar && React.createElement(Toolbar, null),
32
- React.createElement(Table, null),
53
+ renderModeView,
33
54
  React.createElement(Pagination, Object.assign({ id: "data-table-pagination" }, pagination, { onChange: payload => {
34
55
  var _a;
35
56
  setPagination(payload);
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ interface GridViewProps {
3
+ }
4
+ export declare const GridView: React.FC<GridViewProps>;
5
+ export {};
@@ -0,0 +1,13 @@
1
+ // Libraries
2
+ import React, { memo } from 'react';
3
+ // Components
4
+ import { TemplateListing } from '@antscorp/antsomi-ui/es/components/template';
5
+ import { useDataTableContext } from '../../contexts/DataTableContext';
6
+ export const GridView = memo(() => {
7
+ const gridView = useDataTableContext(store => { var _a; return (_a = store.toolbar.actionButtons) === null || _a === void 0 ? void 0 : _a.GRID_VIEW; });
8
+ if (gridView) {
9
+ const { templateListingProps } = gridView;
10
+ return React.createElement(TemplateListing, Object.assign({}, templateListingProps));
11
+ }
12
+ return null;
13
+ });
@@ -34,10 +34,10 @@ export const ResizableCell = props => {
34
34
  return (React.createElement("th", Object.assign({}, restProps, { style: columnStyle, onClick: onClick }), CellHeaderContent));
35
35
  }
36
36
  const handleStyleResizable = (type) => {
37
- var _a, _b;
38
- (_b = (_a = tableRef === null || tableRef === void 0 ? void 0 : tableRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll('.antsomi-table-row')) === null || _b === void 0 ? void 0 : _b.forEach(rowEl => {
37
+ var _a;
38
+ (_a = tableRef === null || tableRef === void 0 ? void 0 : tableRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll('.antsomi-table-body > table > tbody.antsomi-table-tbody > .antsomi-table-row').forEach(rowEl => {
39
39
  var _a;
40
- const cell = (_a = rowEl.querySelectorAll(`.antsomi-table-cell:not(.antsomi-table-selection-column)`)) === null || _a === void 0 ? void 0 : _a[index !== null && index !== void 0 ? index : 0];
40
+ const cell = (_a = rowEl.querySelectorAll(`.antsomi-table-cell:not(.antsomi-table-selection-column):not(.antsomi-table-row-expand-icon-cell)`)) === null || _a === void 0 ? void 0 : _a[index !== null && index !== void 0 ? index : 0];
41
41
  if (cell) {
42
42
  if (type === 'add') {
43
43
  return cell.setAttribute('aria-resizable', 'true');
@@ -55,7 +55,7 @@ export const ResizableCell = props => {
55
55
  // Update the state with the new width
56
56
  setWidth(size.width);
57
57
  // Select all column elements within the table body colgroup
58
- const resizeColEls = (_a = tableRef === null || tableRef === void 0 ? void 0 : tableRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`.antsomi-table-body colgroup > col:not(.antsomi-table-selection-col)`);
58
+ const resizeColEls = (_a = tableRef === null || tableRef === void 0 ? void 0 : tableRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`.antsomi-table-body colgroup > col:not(.antsomi-table-selection-col):not(.antsomi-table-expand-icon-col)`);
59
59
  // Select the specific column element to resize
60
60
  const resizeColEl = resizeColEls === null || resizeColEls === void 0 ? void 0 : resizeColEls[index !== null && index !== void 0 ? index : 0];
61
61
  // If the column element exists, update its width style
@@ -65,7 +65,7 @@ export const Table = memo(() => {
65
65
  });
66
66
  }
67
67
  }, [tableProps.columns, columnWidths]);
68
- return (React.createElement(ConfigProvider, { theme: { token: { motion: false } }, renderEmpty: () => (React.createElement(EmptyData, { icon: React.createElement(DataIcon, { color: globalToken === null || globalToken === void 0 ? void 0 : globalToken.bw5, width: 48, height: 48 }), description: t(translations.noData).toString() })) },
68
+ return (React.createElement(ConfigProvider, { theme: { token: { motion: false } }, renderEmpty: () => (React.createElement(EmptyData, { icon: React.createElement(DataIcon, { color: globalToken === null || globalToken === void 0 ? void 0 : globalToken.bw5, size: 48 }), description: t(translations.noData).toString() })) },
69
69
  React.createElement(StyledTable, Object.assign({}, restOfTable, { ref: ref => {
70
70
  tableRef.current = ref === null || ref === void 0 ? void 0 : ref.nativeElement;
71
71
  }, scroll: Object.assign(Object.assign({}, scroll), { y: (scroll === null || scroll === void 0 ? void 0 : scroll.y) || '100%', x: (scroll === null || scroll === void 0 ? void 0 : scroll.x) || '100%' }), components: {
@@ -74,6 +74,26 @@ export const StyledTable = styled(Table) `
74
74
  overflow: hidden;
75
75
  }
76
76
  }
77
+
78
+ .antsomi-table-expanded-row-fixed {
79
+ padding: 15px;
80
+
81
+ &::after {
82
+ display: none;
83
+ }
84
+ }
85
+
86
+ .antsomi-table-container {
87
+ &::after {
88
+ box-shadow: none !important;
89
+ }
90
+ }
91
+
92
+ .antsomi-table-cell-fix-left {
93
+ &::after {
94
+ box-shadow: none !important;
95
+ }
96
+ }
77
97
  }
78
98
 
79
99
  thead.antsomi-table-thead {
@@ -27,6 +27,7 @@ import { Icon } from '@antscorp/antsomi-ui/es/components/atoms';
27
27
  // Utils
28
28
  import { renderActionButtons } from '@antscorp/antsomi-ui/es/utils';
29
29
  import { flatFilterMetrics } from '../../utils';
30
+ import { GridViewIcon, TableIcon } from '@antscorp/antsomi-ui/es/components/icons';
30
31
  export const ToolbarActionButtons = memo(() => {
31
32
  // Store
32
33
  const actionButtons = useDataTableContext(useShallow(store => store.toolbar.actionButtons));
@@ -54,13 +55,16 @@ export const ToolbarActionButtons = memo(() => {
54
55
  };
55
56
  // Renders
56
57
  const renderComponent = (action) => {
57
- const { key, label, buttonProps, icon, customRender } = action;
58
- const actionButton = (React.createElement(ActionButton, Object.assign({ key: key, type: "text" }, buttonProps),
59
- React.createElement(Icon, { type: icon, size: 18 }),
60
- `${label}`.toUpperCase()));
58
+ const { key, label: actionLabel, buttonProps, icon: actionIcon, customRender } = action;
59
+ const actionButton = (payload) => {
60
+ const { icon = actionIcon, label = actionLabel } = payload || {};
61
+ return (React.createElement(ActionButton, Object.assign({ key: key, type: "text" }, buttonProps),
62
+ React.createElement("div", { className: "action-icon" }, typeof icon === 'string' ? React.createElement(Icon, { type: icon }) : icon),
63
+ `${label}`.toUpperCase()));
64
+ };
61
65
  // If customRender is exist then return custom render instead of render internal component
62
66
  if (customRender)
63
- return actionButton;
67
+ return actionButton();
64
68
  switch (key) {
65
69
  case 'SEARCH': {
66
70
  const _a = action, { addFilterInfo, onClickSearchItem, isAddFilterFromSearchItem } = _a, restOfAction = __rest(_a, ["addFilterInfo", "onClickSearchItem", "isAddFilterFromSearchItem"]);
@@ -69,13 +73,22 @@ export const ToolbarActionButtons = memo(() => {
69
73
  onAddFilterFromSearch(searchItem.label, addFilterInfo);
70
74
  }
71
75
  onClickSearchItem === null || onClickSearchItem === void 0 ? void 0 : onClickSearchItem(searchItem, index);
72
- }, onAddFilter: value => onAddFilterFromSearch(value, addFilterInfo) }), actionButton));
76
+ }, onAddFilter: value => onAddFilterFromSearch(value, addFilterInfo) }), actionButton()));
73
77
  }
74
78
  case 'COLUMN': {
75
- return React.createElement(ModifyColumn, { key: key }, actionButton);
79
+ return React.createElement(ModifyColumn, { key: key }, actionButton());
80
+ }
81
+ case 'GRID_VIEW': {
82
+ const { mode, onChangeMode = () => { } } = action;
83
+ return (React.createElement("div", { key: key, onClick: () => {
84
+ onChangeMode(mode === 'TABLE' ? 'GRID' : 'TABLE');
85
+ } }, actionButton({
86
+ icon: mode === 'TABLE' ? React.createElement(GridViewIcon, null) : React.createElement(TableIcon, null),
87
+ label: mode === 'TABLE' ? 'Grid view' : 'Table',
88
+ })));
76
89
  }
77
90
  default:
78
- return actionButton;
91
+ return actionButton();
79
92
  }
80
93
  };
81
94
  return (React.createElement(ToolbarActionButtonWrapper, { align: "center", gap: 2 }, renderActionButtons({
@@ -3,3 +3,4 @@ export * from './ModifyColumn';
3
3
  export * from './Filter';
4
4
  export * from './Toolbar';
5
5
  export * from './Pagination';
6
+ export * from './GridView';
@@ -3,3 +3,4 @@ export * from './ModifyColumn';
3
3
  export * from './Filter';
4
4
  export * from './Toolbar';
5
5
  export * from './Pagination';
6
+ export * from './GridView';
@@ -17,7 +17,7 @@ export const DATA_TABLE_THEME = {
17
17
  cellPaddingBlock: 10,
18
18
  cellPaddingInline: 10,
19
19
  borderColor: '#E5E5E5',
20
- rowHoverBg: '#DEEFFE',
20
+ rowHoverBg: '#F2F9FF',
21
21
  borderRadius: 0,
22
22
  headerBorderRadius: 0,
23
23
  rowSelectedBg: '#DEEFFE',
@@ -12,3 +12,7 @@ export declare const TOOLBAR_ACTION_KEYS: {
12
12
  readonly MORE: "MORE";
13
13
  };
14
14
  export declare const TOOLBAR_ACTION_OPTIONS: TActionOptions;
15
+ export declare const GRID_VIEW_KEYS: {
16
+ readonly TABLE: "TABLE";
17
+ readonly GRID: "GRID";
18
+ };
@@ -1,4 +1,7 @@
1
+ import React from 'react';
1
2
  import i18nInstance from '@antscorp/antsomi-ui/es/locales/i18n';
3
+ // Icons
4
+ import { SearchIcon, TableIcon, ViewColumnIcon } from '@antscorp/antsomi-ui/es/components/icons';
2
5
  // Types
3
6
  import { translations } from '@antscorp/antsomi-ui/es/locales/translations';
4
7
  export const TOOLBAR_ACTION_KEYS = {
@@ -13,17 +16,17 @@ export const TOOLBAR_ACTION_KEYS = {
13
16
  GRID_VIEW: 'GRID_VIEW',
14
17
  MORE: 'MORE',
15
18
  };
16
- const { SEARCH, COLUMN, EXPLORE, EXPORT, CALENDAR, TABLE, COMPARE } = TOOLBAR_ACTION_KEYS;
19
+ const { SEARCH, COLUMN, EXPLORE, EXPORT, CALENDAR, TABLE, COMPARE, GRID_VIEW } = TOOLBAR_ACTION_KEYS;
17
20
  export const TOOLBAR_ACTION_OPTIONS = {
18
21
  [SEARCH]: {
19
22
  key: SEARCH,
20
23
  label: i18nInstance.t(translations.dataTableToolbar.toolbarActions.search).toString(),
21
- icon: 'icon-ants-search-2',
24
+ icon: React.createElement(SearchIcon, null),
22
25
  },
23
26
  [COLUMN]: {
24
27
  key: COLUMN,
25
28
  label: 'Column',
26
- icon: 'icon-ants-column-2',
29
+ icon: React.createElement(ViewColumnIcon, null),
27
30
  },
28
31
  [EXPLORE]: {
29
32
  key: EXPLORE,
@@ -50,4 +53,13 @@ export const TOOLBAR_ACTION_OPTIONS = {
50
53
  label: 'Compare',
51
54
  icon: 'file-download',
52
55
  },
56
+ [GRID_VIEW]: {
57
+ key: GRID_VIEW,
58
+ label: 'Grid View',
59
+ icon: React.createElement(TableIcon, null),
60
+ },
61
+ };
62
+ export const GRID_VIEW_KEYS = {
63
+ TABLE: 'TABLE',
64
+ GRID: 'GRID',
53
65
  };
@@ -7,7 +7,8 @@ import { PaginationProps } from '../../components';
7
7
  import { ColumnType } from 'antd/es/table';
8
8
  import { SorterResult } from 'antd/es/table/interface';
9
9
  import { TGetColumnMetrics, TGetFilterMetricList, TGetModifyColumnList, TGetSavedFilterList, TGetSearchListing, TGetTableListing } from '@antscorp/antsomi-ui/es/queries';
10
- import { MatchesAnyItem } from '@antscorp/antsomi-ui/es/components/molecules';
10
+ import { MatchesAnyItem, TThumbnailButton } from '@antscorp/antsomi-ui/es/components/molecules';
11
+ import { TTemplateItem } from '@antscorp/antsomi-ui/es/components/template';
11
12
  export type TApiGlobal = AxiosRequestConfig<any> & {
12
13
  enabled?: boolean;
13
14
  };
@@ -60,6 +61,17 @@ type TSearchProps<TSearchType> = Partial<Pick<TSearchActionButton, 'addFilterInf
60
61
  onClickSearchItem?: (record?: Partial<TSearchType>) => void;
61
62
  formatData?: (response: any) => Partial<TSearchType>[];
62
63
  };
64
+ type TGridViewProps<TTableType> = {
65
+ itemMapKeys: Record<keyof TTemplateItem, keyof TTableType>;
66
+ name?: (record: TTableType) => ReactNode | ReactNode;
67
+ thumbnail?: (record: TTableType) => string | string;
68
+ itemProps?: {
69
+ showButton?: boolean;
70
+ buttonProps?: Omit<TThumbnailButton, 'onClick'> & {
71
+ onClick: (record: TTableType) => void;
72
+ };
73
+ };
74
+ };
63
75
  export type TFormatFilterValue = Partial<Record<TOperatorKey, (value: any) => unknown>>;
64
76
  export interface UseDataTableListingProps<TTableType = any, TSearchType = any> {
65
77
  name?: string;
@@ -73,7 +85,11 @@ export interface UseDataTableListingProps<TTableType = any, TSearchType = any> {
73
85
  getSearchListing?: TGetSearchListing['options'];
74
86
  };
75
87
  table?: Omit<TableProps<TTableType>, 'columns'> & {
88
+ /** Main key for map ids */
76
89
  mainColumnKey: keyof TTableType;
90
+ /** Expand column key for show icon expand row */
91
+ expandColumnKey?: keyof TTableType;
92
+ /** columns?: Partial<Record<keyof TTableType, ColumnType<TTableType>>>; */
77
93
  columns?: {
78
94
  [K in keyof TTableType | 'toggle']?: TTableColumnType<TTableType, K>;
79
95
  };
@@ -94,6 +110,7 @@ export interface UseDataTableListingProps<TTableType = any, TSearchType = any> {
94
110
  */
95
111
  formatFilterValue?: TFormatFilterValue;
96
112
  };
113
+ gridView?: TGridViewProps<TTableType>;
97
114
  }
98
115
  export interface DataTableLocalStorage<TTableType = any> {
99
116
  filter?: {
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { useGetColumnMetrics, useGetFilterMetricList, useGetModifyColumnList, useGetSavedFilterList, useGetSearchListing, useGetTableListing } from '@antscorp/antsomi-ui/es/queries';
3
3
  import { UseDataTableListingProps } from './types';
4
- import { FilterItem, FilterProps, TColumnActionButton, TSearchActionButton, TableProps } from '../../types';
4
+ import { FilterItem, FilterProps, TColumnActionButton, TGridViewActionButton, TSearchActionButton, TableProps, TGridViewKeys } from '../../types';
5
5
  import { PaginationProps } from '../../components';
6
6
  import { SorterResult } from 'antd/es/table/interface';
7
7
  interface TUseDataTableListing<TTableType = any> {
@@ -10,6 +10,7 @@ interface TUseDataTableListing<TTableType = any> {
10
10
  pagination: PaginationProps;
11
11
  table: TableProps<TTableType>;
12
12
  search: TSearchActionButton;
13
+ gridView: TGridViewActionButton;
13
14
  /**
14
15
  * This selectedRowKeys is deprecated. Use selectedRow.keys instead.
15
16
  * @deprecated
@@ -48,6 +49,9 @@ type TState<TTableType = any> = {
48
49
  searchValue?: string;
49
50
  sorter?: SorterResult<TTableType>;
50
51
  selectedFilterItem?: FilterItem;
52
+ expandedRowKeys?: React.Key[];
53
+ /** Mode view of data table listing */
54
+ modeView?: TGridViewKeys;
51
55
  };
52
56
  export declare function useDataTableListing<TTableType = Record<string, any>, TSearchType = any>(props: UseDataTableListingProps<TTableType, TSearchType>): TUseDataTableListing<TTableType>;
53
57
  export {};
@@ -21,7 +21,7 @@ var __rest = (this && this.__rest) || function (s, e) {
21
21
  // Libraries
22
22
  import React, { useCallback, useMemo, useState } from 'react';
23
23
  import { Link } from 'react-router-dom';
24
- import { flatMap, isEmpty, pick } from 'lodash';
24
+ import { flatMap, isEmpty, pick, xor } from 'lodash';
25
25
  import { useQueryClient } from '@tanstack/react-query';
26
26
  // Types
27
27
  import { useAppConfigContext } from '@antscorp/antsomi-ui/es/providers';
@@ -38,6 +38,7 @@ import { useCreateModifyColumn, useDeleteModifyColumn, useDeleteSavedFilter, use
38
38
  import { flatTree, mapResponseSearchToGeneral, parseJSONFromLocalStorage, } from '@antscorp/antsomi-ui/es/utils';
39
39
  import { METRIC_MAP_NUMBER_TYPE } from '../../constants/filter';
40
40
  import { mapFiltersToApiFilters, mapFiltersToRules, mapRulesToFilters } from '../../utils';
41
+ import { ExpandLessIcon } from '@antscorp/antsomi-ui/es/components/icons';
41
42
  const { Text } = Typography;
42
43
  const { MATCHES, MATCHES_ANY, NOT_MATCHES } = OPERATORS_CODE;
43
44
  const initialState = {
@@ -60,11 +61,13 @@ const initialState = {
60
61
  searchValue: '',
61
62
  sorter: {},
62
63
  selectedFilterItem: undefined,
64
+ expandedRowKeys: [],
65
+ modeView: 'TABLE',
63
66
  };
64
67
  export function useDataTableListing(props) {
65
68
  var _a, _b, _c;
66
69
  // Props
67
- const { config, name = 'default', table: tableProps, search: searchProps, filter: filterProps, queryOptions, } = props || {};
70
+ const { config, name = 'default', table: tableProps, search: searchProps, filter: filterProps, gridView: gridViewProps, queryOptions, } = props || {};
68
71
  // Hooks
69
72
  const queryClient = useQueryClient();
70
73
  const { appConfig } = useAppConfigContext();
@@ -77,9 +80,10 @@ export function useDataTableListing(props) {
77
80
  const _e = apiFilter || {}, { url: filterUrl = `${COLUMN_DOMAIN[env || 'development']}/api/filter`, enabled: enabledApiFilter = true } = _e, restOfApiFilterRequest = __rest(_e, ["url", "enabled"]);
78
81
  const _f = apiListing || {}, { url: listingUrl = '', enabled: enabledApiListing = true } = _f, restOfApiListingRequest = __rest(_f, ["url", "enabled"]);
79
82
  const _g = apiSearch || {}, { url: searchUrl = '', enabled: enabledApiSearch = true } = _g, restOfApiSearchRequest = __rest(_g, ["url", "enabled"]);
80
- const { filters, selectedFilterId, pagination, selectedRowKeys, searchValue, table, sorter, selectedRow, selectedFilterItem, } = state;
83
+ const { filters, selectedFilterId, pagination, selectedRowKeys, searchValue, table, sorter, selectedRow, selectedFilterItem, expandedRowKeys, modeView, } = state;
81
84
  const { externalFilters, includeDataType = false, matchesAny, formatFilterValue, } = filterProps || {};
82
- const { sortDirectionKey = 'az', mainColumnKey } = tableProps || {};
85
+ const { sortDirectionKey = 'az', mainColumnKey, expandColumnKey, expandable } = tableProps || {};
86
+ const { itemProps: gridViewItemProps } = gridViewProps || {};
83
87
  const modifyColumnAuth = Object.assign(Object.assign({}, auth), { url: columnUrl });
84
88
  const filterAuth = Object.assign(Object.assign({}, auth), { url: filterUrl });
85
89
  const listingAuth = Object.assign(Object.assign({}, auth), { url: listingUrl });
@@ -285,6 +289,34 @@ export function useDataTableListing(props) {
285
289
  name: filterName,
286
290
  removable: true,
287
291
  }))) || []), [savedFiltersData]);
292
+ const renderColumnWithExpandIcon = useCallback((children, // The content of the column
293
+ headerCol, // The header configuration for the column
294
+ record) => {
295
+ const { name } = headerCol || {}; // Destructure the name from the headerCol, with a fallback to an empty object
296
+ if (expandColumnKey === name) {
297
+ // Check if the current column is the expand column
298
+ const expanded = expandedRowKeys === null || expandedRowKeys === void 0 ? void 0 : expandedRowKeys.includes(
299
+ // Check if the current row is expanded
300
+ (record === null || record === void 0 ? void 0 : record[mainColumnKey]) || '');
301
+ return (React.createElement(Flex, { align: "center", gap: 4 },
302
+ React.createElement(ExpandLessIcon, { size: 20, style: {
303
+ flexShrink: 0,
304
+ color: globalToken === null || globalToken === void 0 ? void 0 : globalToken.bw8,
305
+ transform: `rotate(${expanded ? 0 : 180}deg)`,
306
+ cursor: 'pointer',
307
+ transition: 'transform 0.3s ease',
308
+ }, onClick: () => {
309
+ if (expandable && expandable.onExpand) {
310
+ expandable.onExpand(!expanded, record);
311
+ }
312
+ setState(prev => (Object.assign(Object.assign({}, prev), { expandedRowKeys: xor(expandedRowKeys, [
313
+ record[mainColumnKey],
314
+ ]) })));
315
+ } }),
316
+ children));
317
+ }
318
+ return children;
319
+ }, [expandColumnKey, expandable, expandedRowKeys, mainColumnKey]);
288
320
  const tableColumns = useDeepCompareMemo(() => {
289
321
  let data = [];
290
322
  const { columns } = tableProps || {};
@@ -318,16 +350,16 @@ export function useDataTableListing(props) {
318
350
  }
319
351
  : {})) }, typeof value !== 'object' ? value || DEFAULT_CELL_EMPTY : DEFAULT_CELL_EMPTY));
320
352
  if ((_a = columns === null || columns === void 0 ? void 0 : columns[name]) === null || _a === void 0 ? void 0 : _a.render) {
321
- return columns[name].render(value, record, index, RenderComponent);
353
+ return renderColumnWithExpandIcon(columns[name].render(value, record, index, RenderComponent), headerCol, record);
322
354
  }
323
355
  if (link) {
324
- return (React.createElement(Link, { to: typeof link === 'function' ? link(record) : link }, RenderComponent));
356
+ return renderColumnWithExpandIcon(React.createElement(Link, { to: typeof link === 'function' ? link(record) : link }, RenderComponent), headerCol, record);
325
357
  }
326
- return RenderComponent;
358
+ return renderColumnWithExpandIcon(RenderComponent, headerCol, record);
327
359
  } });
328
360
  })) || []);
329
361
  return data;
330
- }, [tableHeader, tableProps, sorter]);
362
+ }, [tableProps, tableHeader, sorter === null || sorter === void 0 ? void 0 : sorter.columnKey, sorter === null || sorter === void 0 ? void 0 : sorter.order, renderColumnWithExpandIcon]);
331
363
  const tableData = useDeepCompareMemo(() => ((Array === null || Array === void 0 ? void 0 : Array.isArray(tableBody)) &&
332
364
  (tableBody === null || tableBody === void 0 ? void 0 : tableBody.map((row) => (Object.assign(Object.assign({}, row), { key: row === null || row === void 0 ? void 0 : row[tableProps === null || tableProps === void 0 ? void 0 : tableProps.mainColumnKey] }))))) ||
333
365
  [], [tableBody]);
@@ -345,6 +377,15 @@ export function useDataTableListing(props) {
345
377
  }
346
378
  return [];
347
379
  }, [matchesAny, infiniteMatchesAnyData, selectedFilterItem === null || selectedFilterItem === void 0 ? void 0 : selectedFilterItem.column]);
380
+ const gridViewList = useDeepCompareMemo(() => {
381
+ if (gridViewProps === null || gridViewProps === void 0 ? void 0 : gridViewProps.itemMapKeys) {
382
+ const { name, thumbnail } = gridViewProps || {};
383
+ return ((tableData === null || tableData === void 0 ? void 0 : tableData.map(record => Object.entries((gridViewProps === null || gridViewProps === void 0 ? void 0 : gridViewProps.itemMapKeys) || {}).reduce((acc, [key, value]) => (Object.assign(Object.assign(Object.assign(Object.assign({}, acc), { [key]: record[value] }), (thumbnail && {
384
+ thumbnail: typeof thumbnail === 'function' ? thumbnail(record) : thumbnail,
385
+ })), (name && { name: typeof name === 'function' ? name(record) : name }))), {}))) || []);
386
+ }
387
+ return [];
388
+ }, [gridViewProps, tableData]);
348
389
  // Effects
349
390
  /**
350
391
  * Update values from local storage to state
@@ -580,21 +621,40 @@ export function useDataTableListing(props) {
580
621
  /* Pagination */
581
622
  pagination: Object.assign(Object.assign({}, pagination), { total, onChange: onChangePagination }),
582
623
  /* Table */
583
- table: {
584
- loading: isTableListingLoading || isTableListingRefetching,
585
- columns: tableColumns,
586
- dataSource: tableData,
587
- columnWidths: table.columnWidths || {},
588
- rowSelection: {
624
+ table: Object.assign(Object.assign({}, tableProps), { loading: isTableListingLoading || isTableListingRefetching, columns: tableColumns, dataSource: tableData, columnWidths: table.columnWidths || {}, expandable: Object.assign({ showExpandColumn: false, expandedRowKeys: expandedRowKeys || [] }, tableProps === null || tableProps === void 0 ? void 0 : tableProps.expandable), rowSelection: {
589
625
  selectedRowKeys: selectedRow.keys || [],
590
626
  onChange: onChangeSelectedRow,
591
- },
592
- onChange: onChangeTable,
593
- onColumnResize(data) {
627
+ }, onChange: onChangeTable, onColumnResize(data) {
594
628
  const { index, width } = data;
595
629
  handleUpdateTable({
596
630
  columnWidths: Object.assign(Object.assign({}, table.columnWidths), { [index]: width }),
597
631
  });
632
+ } }),
633
+ /* Grid view */
634
+ gridView: {
635
+ mode: modeView,
636
+ onChangeMode(mode) {
637
+ setState(prev => (Object.assign(Object.assign({}, prev), { modeView: mode })));
638
+ },
639
+ templateListingProps: {
640
+ templatesProps: {
641
+ items: gridViewList,
642
+ loading: isTableListingLoading || isTableListingRefetching,
643
+ },
644
+ templateItemProps: {
645
+ removable: false,
646
+ previewBtnProps: {
647
+ show: false,
648
+ },
649
+ actionAvailable: gridViewItemProps === null || gridViewItemProps === void 0 ? void 0 : gridViewItemProps.showButton,
650
+ editBtnProps: Object.assign(Object.assign({}, gridViewItemProps === null || gridViewItemProps === void 0 ? void 0 : gridViewItemProps.buttonProps), { onClick(id) {
651
+ var _a, _b;
652
+ const record = tableData === null || tableData === void 0 ? void 0 : tableData.find(item => (item === null || item === void 0 ? void 0 : item[gridViewProps === null || gridViewProps === void 0 ? void 0 : gridViewProps.itemMapKeys.id]) === id);
653
+ if (record && ((_a = gridViewItemProps === null || gridViewItemProps === void 0 ? void 0 : gridViewItemProps.buttonProps) === null || _a === void 0 ? void 0 : _a.onClick)) {
654
+ (_b = gridViewItemProps === null || gridViewItemProps === void 0 ? void 0 : gridViewItemProps.buttonProps) === null || _b === void 0 ? void 0 : _b.onClick(record);
655
+ }
656
+ } }),
657
+ },
598
658
  },
599
659
  },
600
660
  /* Selected row */
@@ -7,4 +7,5 @@ export declare const ActionButton: import("styled-components").StyledComponent<i
7
7
  $hide?: boolean | undefined;
8
8
  }, never>;
9
9
  export declare const FilterMetricLabel: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("antd/es/flex/interface").FlexProps<import("antd/es/_util/type").AnyObject> & import("react").RefAttributes<HTMLElement>>, any, {}, never>;
10
+ export declare const DataTableContent: import("styled-components").StyledComponent<"div", any, {}, never>;
10
11
  export declare const FilterButton: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -34,15 +34,26 @@ export const ActionButton = styled(Button) `
34
34
  display: flex !important;
35
35
  flex-direction: column;
36
36
  align-items: center;
37
- justify-content: center;
38
- gap: 4px 0px !important;
39
37
  height: 43px !important;
40
38
  width: 50px !important;
39
+ gap: 4px !important;
40
+ padding: 3px 0px !important;
41
41
  font-size: 8px !important;
42
+ line-height: 1 !important;
42
43
  color: ${globalToken === null || globalToken === void 0 ? void 0 : globalToken.bw8} !important;
43
44
 
44
45
  ${props => props.$hide && `visibility: hidden !important;`}
45
46
 
47
+ .action-icon {
48
+ display: flex;
49
+ align-items: center;
50
+ justify-content: center;
51
+ flex-shrink: 0;
52
+ > i {
53
+ font-size: 24px !important;
54
+ }
55
+ }
56
+
46
57
  /* &:hover, */
47
58
  &:active {
48
59
  color: ${globalToken === null || globalToken === void 0 ? void 0 : globalToken.colorPrimary} !important;
@@ -60,6 +71,16 @@ export const FilterMetricLabel = styled(Flex) `
60
71
  color: ${globalToken === null || globalToken === void 0 ? void 0 : globalToken.bw8};
61
72
  }
62
73
  `;
74
+ export const DataTableContent = styled.div `
75
+ display: flex;
76
+ flex-direction: column;
77
+ overflow: auto;
78
+
79
+ .scrollbar-view {
80
+ height: 100%;
81
+ position: relative !important;
82
+ }
83
+ `;
63
84
  /* Filter */
64
85
  export const FilterButton = styled.div `
65
86
  width: 24px;
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  import { TableProps as AntdTableProps } from 'antd';
2
3
  import { StoreApi } from 'zustand';
3
4
  import { ToolbarProps } from './toolbar';
@@ -13,6 +14,7 @@ export interface TableProps<T> extends AntdTableProps<T> {
13
14
  export interface ModifyColumnProps {
14
15
  }
15
16
  export interface DataTableProps<TTableDataType = any> extends Partial<DataTableState<TTableDataType>> {
17
+ contentRender?: () => React.ReactNode;
16
18
  store?: StoreApi<DataTableStore<any>> | null;
17
19
  }
18
20
  export interface DataTableState<TTableDataType> {
@@ -1,13 +1,15 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { DropdownProps } from 'antd';
3
- import { TOOLBAR_ACTION_KEYS } from '../constants';
3
+ import { GRID_VIEW_KEYS, TOOLBAR_ACTION_KEYS } from '../constants';
4
4
  import { AddButtonProps } from '../components/AddButton';
5
5
  import { TActionButton, TConfirmResponse } from '@antscorp/antsomi-ui/es/types';
6
6
  import { TOperatorKey } from '@antscorp/antsomi-ui/es/types/condition';
7
7
  import { ModifyColumnMetric } from '../../ModifyColumnModal';
8
8
  import { SavedModifyColumnItem, TOnSaveModifyColumnArgs } from '../../ModifyColumnModal/types';
9
9
  import { TextProps } from 'antd/es/typography/Text';
10
+ import { TemplateListingProps } from '../../../template';
10
11
  export type TActionToolbarButtonKey<T extends string[] = []> = (typeof TOOLBAR_ACTION_KEYS)[keyof typeof TOOLBAR_ACTION_KEYS] | T[number];
12
+ export type TGridViewKeys = (typeof GRID_VIEW_KEYS)[keyof typeof GRID_VIEW_KEYS];
11
13
  export type TSearchItem = {
12
14
  id: string | number;
13
15
  label: string;
@@ -54,7 +56,14 @@ export type TColumnActionButton = TActionButton & {
54
56
  metrics?: ModifyColumnMetric[];
55
57
  onApply?: (args: TOnSaveModifyColumnArgs) => Promise<TConfirmResponse>;
56
58
  };
57
- export type TToolbarActionButton<TActionKey extends string[] = [], ActionKey extends TActionToolbarButtonKey<TActionKey> = TActionToolbarButtonKey<TActionKey>> = ActionKey extends 'SEARCH' ? TSearchActionButton : ActionKey extends 'COLUMN' ? TColumnActionButton : TActionButton;
59
+ export type TGridViewActionButton = TActionButton & {
60
+ /** The mode of the grid view. Ex: '' */
61
+ mode?: TGridViewKeys;
62
+ templateListingProps?: TemplateListingProps;
63
+ /** The callback function to change the mode of the grid view. */
64
+ onChangeMode?: (mode: TGridViewKeys) => void;
65
+ };
66
+ export type TToolbarActionButton<TActionKey extends string[] = [], ActionKey extends TActionToolbarButtonKey<TActionKey> = TActionToolbarButtonKey<TActionKey>> = ActionKey extends 'SEARCH' ? TSearchActionButton : ActionKey extends 'COLUMN' ? TColumnActionButton : ActionKey extends 'GRID_VIEW' ? TGridViewActionButton : TActionButton;
58
67
  export type TCollapse = {
59
68
  collapsed?: boolean;
60
69
  onCollapse?: (collapsed: boolean) => void;
@@ -34,6 +34,7 @@ export const HOME_MENU_ITEMS = {
34
34
  menu_item_name: 'Dashboard',
35
35
  menu_item_code: 'ownedDashboard',
36
36
  icon_name: 'icon-ants-dashboard',
37
+ // menu_item_path: `${HOME_ROUTE}/detail`,
37
38
  page_title: '_dashboard',
38
39
  },
39
40
  };
@@ -142,11 +142,12 @@ export const Layout = memo(props => {
142
142
  return (React.createElement(LayoutWrapper, { showLeftMenu: !!showLeftMenu },
143
143
  React.createElement(Helmet, null,
144
144
  React.createElement("meta", { charSet: "utf-8" }),
145
- React.createElement("title", null, (header === null || header === void 0 ? void 0 : header.browserTitle) || (header === null || header === void 0 ? void 0 : header.pageTitle)
146
- ? isString(header === null || header === void 0 ? void 0 : header.pageTitle)
147
- ? header === null || header === void 0 ? void 0 : header.pageTitle
148
- : ''
149
- : activePageTitle)),
145
+ React.createElement("title", null, (header === null || header === void 0 ? void 0 : header.browserTitle) ||
146
+ ((header === null || header === void 0 ? void 0 : header.pageTitle)
147
+ ? isString(header === null || header === void 0 ? void 0 : header.pageTitle)
148
+ ? header === null || header === void 0 ? void 0 : header.pageTitle
149
+ : ''
150
+ : activePageTitle))),
150
151
  React.createElement(HeaderV2, Object.assign({}, mergeHeaderProps, { showLogo: !showLeftMenu })),
151
152
  React.createElement(Flex, { className: "layout-body" },
152
153
  showLeftMenu && (React.createElement(LeftMenu, Object.assign({ className: `layout-body__menu ${leftMenuClassName}` }, mergeLeftMenuProps, { appConfig: leftMenuAppConfig, onActiveMenuCodeChange: onActiveMenuCodeChange }))),
@@ -32,6 +32,7 @@ export const TemplateListing = memo(props => {
32
32
  const { header, footer, items = [], gap = LISTING_GAP_DEFAULT, loading = false, wrapperClassName, wrapperStyle, onLoadMoreTemplates = () => { }, } = templatesProps || {};
33
33
  const _a = previewModalProps || {}, { onOk, onCancel } = _a, restOfPreviewModalProps = __rest(_a, ["onOk", "onCancel"]);
34
34
  const _b = templateItemProps || {}, { width = THUMBNAIL_CARD_DEFAULT_WIDTH, height = THUMBNAIL_CARD_DEFAULT_HEIGHT, previewBtnProps } = _b, restOfTemplateItemProps = __rest(_b, ["width", "height", "previewBtnProps"]);
35
+ console.log('🚀 ~ templateItemProps:', templateItemProps);
35
36
  const { onClick: onClickPreview } = previewBtnProps || {};
36
37
  const isHasData = items.length > 0;
37
38
  // Memo
@@ -80,9 +81,7 @@ export const TemplateListing = memo(props => {
80
81
  const loading = typeof (item === null || item === void 0 ? void 0 : item.name) === 'undefined';
81
82
  return (React.createElement("div", { key: id },
82
83
  index === items.length - 2 && React.createElement(LoadMoreBlock, { ref: loadMoreRef }),
83
- React.createElement(ThumbnailCard, Object.assign({ id: id || 0, name: name || 'Untitled', loading: loading, width: width * ratio, height: height * ratio, thumbnail: thumbnail, className: `${templateItemProps.className}`, thumbnailCacheValue: thumbnailCacheValue, previewBtnProps: {
84
- onClick: handleClickThumbnailPreview,
85
- } }, restOfTemplateItemProps))));
84
+ React.createElement(ThumbnailCard, Object.assign({ id: id || 0, name: name || 'Untitled', loading: loading, width: width * ratio, height: height * ratio, thumbnail: thumbnail, className: `${templateItemProps.className}`, thumbnailCacheValue: thumbnailCacheValue, previewBtnProps: Object.assign({ onClick: handleClickThumbnailPreview }, previewBtnProps) }, restOfTemplateItemProps))));
86
85
  }))),
87
86
  !loading && !blankTemplateProps.show && !isHasData && React.createElement(Empty, Object.assign({}, emptyProps)))),
88
87
  footer),
@@ -244,5 +244,23 @@ THEME.components = {
244
244
  Form: {
245
245
  itemMarginBottom: 15,
246
246
  },
247
+ Table: {
248
+ headerBg: '#F9F9F9',
249
+ headerSortActiveBg: '#F9F9F9',
250
+ headerSortHoverBg: '#F9F9F9',
251
+ headerFilterHoverBg: '#F9F9F9',
252
+ fixedHeaderSortActiveBg: '#F9F9F9',
253
+ bodySortBg: '#ffffff',
254
+ fontWeightStrong: 700,
255
+ cellPaddingBlock: 10,
256
+ cellPaddingInline: 10,
257
+ borderColor: '#E5E5E5',
258
+ rowHoverBg: '#F2F9FF',
259
+ borderRadius: 0,
260
+ headerBorderRadius: 0,
261
+ rowSelectedBg: '#DEEFFE',
262
+ rowSelectedHoverBg: '#F2F9FF',
263
+ rowExpandedBg: '#F9F9F9',
264
+ },
247
265
  };
248
266
  export const globalToken = theme.getDesignToken(THEME);
@@ -118,6 +118,10 @@ export const DataTableTest = () => {
118
118
  // },
119
119
  // },
120
120
  },
121
+ table: {
122
+ mainColumnKey: 'survey_id',
123
+ expandColumnKey: 'survey_name',
124
+ },
121
125
  });
122
126
  return (React.createElement(BrowserRouter, null,
123
127
  React.createElement(TableTestWrapper, null,
@@ -4,13 +4,13 @@ export type TActionButton = {
4
4
  buttonProps?: ButtonProps;
5
5
  key?: string;
6
6
  label?: React.ReactNode;
7
- icon?: string;
7
+ icon?: ReactNode;
8
8
  customRender?: (node: ReactNode) => ReactNode;
9
9
  };
10
10
  export type TActionOption = {
11
11
  key: string;
12
12
  label: string;
13
- icon?: string;
13
+ icon?: ReactNode;
14
14
  iconSize?: number;
15
15
  };
16
16
  export type TActionOptions = Record<string, TActionOption>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antscorp/antsomi-ui",
3
- "version": "1.7.6",
3
+ "version": "1.7.7",
4
4
  "description": "An enterprise-class UI design language and React UI library.",
5
5
  "sideEffects": [
6
6
  "dist/*",
package/CHANGELOG.md DELETED
@@ -1,91 +0,0 @@
1
- ### Changelog
2
-
3
- All notable changes to this project will be documented in this file. Dates are displayed in UTC.
4
-
5
- Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
-
7
- #### [v1.7.6](https://bitbucket.org/git-vn/at.packages.frontend/compare/v1.7.6..v2.0.22)
8
-
9
- - chore: update storybook version [`d13f194`](https://bitbucket.org/git-vn/at.packages.frontend/commits/d13f19462c2fe117934df7fe2e09fd0aa95a0167)
10
- - feat: update input width when in view [`f27b982`](https://bitbucket.org/git-vn/at.packages.frontend/commits/f27b982a4427c414a1b5d5538641516a3d35aa6e)
11
- - chore: update datatable components [`d38cf96`](https://bitbucket.org/git-vn/at.packages.frontend/commits/d38cf9687b2a6fd03396247d04c6ef37a6b030f1)
12
-
13
- ### [v2.0.22](https://bitbucket.org/git-vn/at.packages.frontend/compare/v2.0.22..v1.7.5)
14
-
15
- > 19 January 2023
16
-
17
- #### [v1.7.5](https://bitbucket.org/git-vn/at.packages.frontend/compare/v1.7.5..v1.7.4)
18
-
19
- > 11 July 2024
20
-
21
- - feat(compoents): add component AccountProfile [`e504187`](https://bitbucket.org/git-vn/at.packages.frontend/commits/e5041873fa3236acf35312801754240a7542b8dd)
22
- - chore(component): remove unuse common folder [`5123bac`](https://bitbucket.org/git-vn/at.packages.frontend/commits/5123bac8005db98661ca48c500aab56ac42b1feb)
23
- - chore: update formatFitlerValue for useTablisting hook [`2b173a0`](https://bitbucket.org/git-vn/at.packages.frontend/commits/2b173a02ab8fb24a8cd3b6d1c8403c111e831eb4)
24
-
25
- #### [v1.7.4](https://bitbucket.org/git-vn/at.packages.frontend/compare/v1.7.4..v1.3.5-beta.446)
26
-
27
- > 5 July 2024
28
-
29
- - chore: update storybook version [`d13f194`](https://bitbucket.org/git-vn/at.packages.frontend/commits/d13f19462c2fe117934df7fe2e09fd0aa95a0167)
30
- - feat(MatchesAnySelect): create and handle new MatchesAnySelect component [`a89c46e`](https://bitbucket.org/git-vn/at.packages.frontend/commits/a89c46e00e81d5a28ac37f42166dcab1c49212df)
31
- - chore: update filter matches any datatable [`4db6dc8`](https://bitbucket.org/git-vn/at.packages.frontend/commits/4db6dc81b62a9168ca9fe1a5e39e414e473e7285)
32
-
33
- #### [v1.3.5-beta.446](https://bitbucket.org/git-vn/at.packages.frontend/compare/v1.3.5-beta.446..v1.0.10)
34
-
35
- > 2 July 2024
36
-
37
- - chore(datatable): update useTableListing hook [`262def1`](https://bitbucket.org/git-vn/at.packages.frontend/commits/262def14c8a44ae73d1d9163696afc25e026ba45)
38
- - chore: update data table component [`7fce77d`](https://bitbucket.org/git-vn/at.packages.frontend/commits/7fce77db8191ff7633679ea9befe28718eb40a88)
39
- - chore(storybook): add addon-controls [`8ea93fc`](https://bitbucket.org/git-vn/at.packages.frontend/commits/8ea93fc4bb41c50f7a7025bc79d968d849e8d113)
40
-
41
- #### [v1.0.10](https://bitbucket.org/git-vn/at.packages.frontend/compare/v1.0.10..v1.0.9)
42
-
43
- > 20 June 2024
44
-
45
- #### [v1.0.9](https://bitbucket.org/git-vn/at.packages.frontend/compare/v1.0.9..v1.0.8)
46
-
47
- > 20 June 2024
48
-
49
- #### [v1.0.8](https://bitbucket.org/git-vn/at.packages.frontend/compare/v1.0.8..v1.0.3)
50
-
51
- > 20 June 2024
52
-
53
- - feat(SelectAccount): add component [`2f1dea0`](https://bitbucket.org/git-vn/at.packages.frontend/commits/2f1dea035af07a01a6be8da47b531d52d2977bbe)
54
- - fix: update style for calendar selection [`4347b91`](https://bitbucket.org/git-vn/at.packages.frontend/commits/4347b91f5bbe31caeb64478116c1822fe443f359)
55
- - feat(EditorTab): use modal async in onCloseTab [`76aece8`](https://bitbucket.org/git-vn/at.packages.frontend/commits/76aece8cc7a44385d63019058daa1f8477c8fbcb)
56
-
57
- #### [v1.0.3](https://bitbucket.org/git-vn/at.packages.frontend/compare/v1.0.3..v1.0.2)
58
-
59
- > 17 January 2023
60
-
61
- - update timeline package [`e198927`](https://bitbucket.org/git-vn/at.packages.frontend/commits/e198927d83931f9155e90ab9a1d9d3a5ac2989c4)
62
- - update-ticket-editor [`38dd7b0`](https://bitbucket.org/git-vn/at.packages.frontend/commits/38dd7b0a7b2b0b58a63e725419e9b057e053f44f)
63
- - update-upload-file-ticket-editor [`bb2f2ef`](https://bitbucket.org/git-vn/at.packages.frontend/commits/bb2f2ef1c46f4239ad716c897e53856a6368ea7d)
64
-
65
- #### v1.0.2
66
-
67
- > 4 January 2023
68
-
69
- - Sprint10/vinlt/feature/date advanced [`#24`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/24)
70
- - Sprint10/sangndd/feature/extend value matches any [`#23`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/23)
71
- - Sprint10/sangndd/feature/extend value matches any [`#22`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/22)
72
- - [Scatter chart] Max X-axis giá trị bị lặp [`#20`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/20)
73
- - Sprint8/vinlt/feature/show data label short [`#18`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/18)
74
- - Fix duplicate axis max value [`#17`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/17)
75
- - [Antalyser] Một số bug khi nhập axis giá trị thập phân [`#16`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/16)
76
- - Sprint6/vinlt/fixbug/chart [`#15`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/15)
77
- - - Axis allows input of decimal values [`#14`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/14)
78
- - Sprint4/sangndd/feature/icons [`#12`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/12)
79
- - Sprint4/sangndd/feature/icons [`#11`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/11)
80
- - Sprint4/thanghn/fixbug/pivot alias border [`#10`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/10)
81
- - fix scroll dimension and total column [`#9`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/9)
82
- - [ANTALYSER][Filter][Khi filter filed có type date và semantic là "Month day" thì không load được danh sách các ngày trong tháng] [`#7`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/7)
83
- - [ANTALYSER][Pivot chart][Tính năng Add border shadow chưa hoạt động] [`#8`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/8)
84
- - Fix bug [ANTALYSER][Scatter chart][Label ở cột X và Y chưa đổi theo alias name đã change ở metric] [`#6`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/6)
85
- - Fix bug [Pivot chart] Row color không hiển thị được khi chọn hiển thị data của metric là Bar [`#5`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/5)
86
- - Fix bug package antscorp/charts [`#1`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/1)
87
- - Fix bug package antscorp/chart [`#2`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/2)
88
- - table component [`#1`](https://bitbucket.org/git-vn/at.packages.frontend/pull-requests/1)
89
- - Update map indonesia [`fc94208`](https://bitbucket.org/git-vn/at.packages.frontend/commits/fc9420838b3f4087a5763017e9bf7e72ee8c5e31)
90
- - Update geomap [`43f3098`](https://bitbucket.org/git-vn/at.packages.frontend/commits/43f3098506f30a215dc2b30734590e5c55f8b490)
91
- - sync package master [`7476118`](https://bitbucket.org/git-vn/at.packages.frontend/commits/7476118de2fcfa1bd6b0a9e3c0f887b29fd149b6)