@antscorp/antsomi-ui 1.3.5-beta.472 → 1.3.5-beta.474

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 (39) hide show
  1. package/es/components/icons/EventIcon.js +1 -1
  2. package/es/components/molecules/DatePicker/DatePicker.js +6 -0
  3. package/es/components/molecules/MatchAnySelect/MatchesAnySelect.js +14 -11
  4. package/es/components/molecules/MatchAnySelect/styled.js +14 -1
  5. package/es/components/molecules/MatchAnySelect/types.d.ts +5 -3
  6. package/es/components/organism/DataTable/components/Filter/AddFilterButton.js +11 -2
  7. package/es/components/organism/DataTable/components/Filter/FilterCondition/index.d.ts +3 -1
  8. package/es/components/organism/DataTable/components/Filter/FilterCondition/index.js +11 -4
  9. package/es/components/organism/DataTable/components/Filter/FilterConditionList.js +12 -10
  10. package/es/components/organism/DataTable/components/Filter/FilterItem.js +36 -6
  11. package/es/components/organism/DataTable/components/Toolbar/RowSelectedControl.js +1 -1
  12. package/es/components/organism/DataTable/components/Toolbar/styled.js +1 -0
  13. package/es/components/organism/DataTable/constants/theme.js +2 -0
  14. package/es/components/organism/DataTable/hooks/useAddFilterButton.d.ts +5 -0
  15. package/es/components/organism/DataTable/hooks/useAddFilterButton.js +4 -2
  16. package/es/components/organism/DataTable/hooks/useDataTableListing/types.d.ts +15 -3
  17. package/es/components/organism/DataTable/hooks/useDataTableListing/useDataTableListing.d.ts +1 -0
  18. package/es/components/organism/DataTable/hooks/useDataTableListing/useDataTableListing.js +59 -13
  19. package/es/components/organism/DataTable/types/filter.d.ts +7 -0
  20. package/es/components/organism/DataTable/utils/filter.d.ts +4 -2
  21. package/es/components/organism/DataTable/utils/filter.js +46 -10
  22. package/es/constants/condition.d.ts +15 -0
  23. package/es/constants/condition.js +15 -0
  24. package/es/constants/datetime.d.ts +4 -0
  25. package/es/constants/datetime.js +4 -0
  26. package/es/constants/queries.d.ts +1 -0
  27. package/es/constants/queries.js +1 -0
  28. package/es/constants/theme.js +1 -0
  29. package/es/locales/en/translation.json +2 -1
  30. package/es/locales/i18n.d.ts +2 -0
  31. package/es/locales/translations.d.ts +1 -0
  32. package/es/locales/vi/translation.json +2 -1
  33. package/es/queries/DataTable/index.d.ts +6 -1
  34. package/es/queries/DataTable/index.js +5 -1
  35. package/es/services/DataTable/index.d.ts +7 -0
  36. package/es/services/DataTable/index.js +16 -4
  37. package/es/tests/DataTableTest.js +45 -12
  38. package/es/types/actionsButton.d.ts +1 -1
  39. package/package.json +1 -1
@@ -14,5 +14,5 @@ export const EventIcon = (_a) => {
14
14
  var props = __rest(_a, []);
15
15
  return (React.createElement("svg", Object.assign({ xmlns: "http://www.w3.org/2000/svg", height: "24px", viewBox: "0 0 24 24", width: "24px", fill: "currentColor" }, props),
16
16
  React.createElement("path", { d: "M0 0h24v24H0V0z", fill: "none" }),
17
- React.createElement("path", { d: "M19 4h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H5V10h14v10zm0-12H5V6h14v2zm-7 5h5v5h-5z" })));
17
+ React.createElement("path", { d: "M16 13h-3c-.55 0-1 .45-1 1v3c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-3c0-.55-.45-1-1-1zm0-10v1H8V3c0-.55-.45-1-1-1s-1 .45-1 1v1H5c-1.11 0-1.99.9-1.99 2L3 20c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-1V3c0-.55-.45-1-1-1s-1 .45-1 1zm2 17H6c-.55 0-1-.45-1-1V9h14v10c0 .55-.45 1-1 1z" })));
18
18
  };
@@ -1,8 +1,14 @@
1
1
  // Libraries
2
+ import React from 'react';
2
3
  import { DatePicker as AntdDatePicker } from 'antd';
3
4
  // Components
4
5
  import { AdvancedPicker } from './components/AdvancedPicker';
5
6
  import { AdvancedRangePicker } from './components/AdvancedRangePicker';
7
+ import { EventIcon } from '../../icons';
8
+ import { globalToken } from '@antscorp/antsomi-ui/es/constants';
6
9
  export const DatePicker = AntdDatePicker;
10
+ DatePicker.defaultProps = {
11
+ suffixIcon: React.createElement(EventIcon, { width: 20, height: 20, color: globalToken === null || globalToken === void 0 ? void 0 : globalToken.bw8 }),
12
+ };
7
13
  DatePicker.AdvancedPicker = AdvancedPicker;
8
14
  DatePicker.AdvancedRangePicker = AdvancedRangePicker;
@@ -41,7 +41,7 @@ const { t } = i18nInstance;
41
41
  const { Text } = Typography;
42
42
  export const MatchesAny = props => {
43
43
  // Props
44
- const { objectName, isLoading = false, showExtendValue = true, items, onApply = () => { }, onCancel = () => { } } = props, restOfProps = __rest(props, ["objectName", "isLoading", "showExtendValue", "items", "onApply", "onCancel"]);
44
+ const { objectName, loading = false, showExtendValue = true, items, onApply = () => { }, onCancel = () => { } } = props, restOfProps = __rest(props, ["objectName", "loading", "showExtendValue", "items", "onApply", "onCancel"]);
45
45
  // State
46
46
  const [state, setState] = useState(matchesAnyInitialState);
47
47
  // Variables
@@ -104,9 +104,11 @@ export const MatchesAny = props => {
104
104
  setState(prev => (Object.assign(Object.assign({}, prev), { selectedItems: [] })));
105
105
  };
106
106
  const renderItemNodeTitle = ({ item, onSelectItem, onRemoveItem, }) => {
107
- const { isExtendValue, title } = item; // Destructure properties from item
107
+ const { isExtendValue, title, subTitle } = item; // Destructure properties from item
108
108
  return (React.createElement(React.Fragment, null,
109
- React.createElement(Text, { ellipsis: { tooltip: true } }, title),
109
+ React.createElement("div", { className: "title-content" },
110
+ React.createElement(Text, { ellipsis: { tooltip: true } }, title),
111
+ subTitle && (React.createElement(Text, { className: "sub-title", ellipsis: { tooltip: true }, style: { color: globalToken === null || globalToken === void 0 ? void 0 : globalToken.bw8 } }, subTitle))),
110
112
  React.createElement(Flex, { align: "center", gap: 5 },
111
113
  isExtendValue && (React.createElement(Icon, { type: "icon-ants-empty-flag", size: 20, color: globalToken === null || globalToken === void 0 ? void 0 : globalToken.colorPrimary })),
112
114
  React.createElement(ActionButton, { className: "select-button", align: "center", justify: "center", onClick: () => {
@@ -191,18 +193,18 @@ export const MatchesAny = props => {
191
193
  React.createElement(Flex, { align: "center", justify: "space-between" },
192
194
  React.createElement(Text, { strong: true }, `${objectName} (${flatTree(items, 'children').filter(item => !item.children).length})`),
193
195
  React.createElement(TextButton, { disabled: isDisableSelectAll, onClick: onSelectAll }, t(translations.global.selectAll).toString())),
194
- React.createElement(Spin, { spinning: isLoading },
196
+ React.createElement(Spin, { spinning: loading },
195
197
  React.createElement(Scrollbars, { style: { height: '100%' } }, (treeData === null || treeData === void 0 ? void 0 : treeData.length) ? (React.createElement(StyledTree, { key: searchValue, defaultExpandedKeys: matchedParents.map(item => item.key), selectable: false, treeData: treeData, switcherIcon: props => (React.createElement(Icon, { type: "icon-ants-caret-down", style: {
196
198
  transform: props.expanded ? 'rotate(0)' : 'rotate(-90deg)',
197
199
  transition: 'transform 0.3s ease',
198
- }, color: globalToken === null || globalToken === void 0 ? void 0 : globalToken.bw8 })) })) : (React.createElement(EmptyData, { showIcon: false, title: t(translations.noData).toString() })))))));
200
+ }, color: globalToken === null || globalToken === void 0 ? void 0 : globalToken.bw8 })) })) : (React.createElement(EmptyData, { showIcon: false, description: t(translations.global.noResultsMatchesKeyWord).toString() })))))));
199
201
  };
200
202
  const renderSelectedList = () => (React.createElement("div", { className: "matches-any__section" },
201
203
  React.createElement(Flex, { className: "matches-any__header", justify: "space-between" },
202
204
  React.createElement(Text, { strong: true }, `${t(translations.global.selected)} (${(selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.length) || 0})`),
203
205
  React.createElement(TextButton, { disabled: isDisableRemoveAll, onClick: onRemoveAll }, t(translations.global.removeAll).toString())),
204
206
  React.createElement("div", { className: "matches-any__body" },
205
- React.createElement(Spin, { spinning: isLoading },
207
+ React.createElement(Spin, { spinning: loading },
206
208
  React.createElement(Scrollbars, { style: { height: '100%' } }, !(selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.length) ? (React.createElement(EmptyData, { icon: "icon-ants-database", description: t(translations.global.selectItemsFromList).toString() })) : (React.createElement(StyledTree, { selectable: false, treeData: selectedTreeData, switcherIcon: props => (React.createElement(Icon, { type: "icon-ants-caret-down", style: {
207
209
  transform: props.expanded ? 'rotate(0)' : 'rotate(-90deg)',
208
210
  transition: 'transform 0.3s ease',
@@ -236,12 +238,11 @@ export const MatchesAny = props => {
236
238
  };
237
239
  export const MatchesAnySelect = props => {
238
240
  var _a, _b, _c;
239
- const { placeholder = 'Select an item', dropdownStyle, objectName, selectedItems, items, isLoading, onChange = () => { } } = props, restProps = __rest(props, ["placeholder", "dropdownStyle", "objectName", "selectedItems", "items", "isLoading", "onChange"]);
241
+ const { placeholder = 'Select an item', dropdownStyle, objectName, selectedItems, items, loading, popupClassName, onChange = () => { } } = props, restProps = __rest(props, ["placeholder", "dropdownStyle", "objectName", "selectedItems", "items", "loading", "popupClassName", "onChange"]);
240
242
  // State
241
243
  const [state, setState] = useState(initialState);
242
244
  // Variables
243
245
  const { isOpenPopover } = state;
244
- // Memo
245
246
  const value = Array.isArray(selectedItems) && (selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.length)
246
247
  ? `${(_a = selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.map(item => item.title)) === null || _a === void 0 ? void 0 : _a[0]}${((_b = selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.slice(1)) === null || _b === void 0 ? void 0 : _b.length) ? `, and +${(_c = selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.slice(1)) === null || _c === void 0 ? void 0 : _c.length} more` : ''}` || []
247
248
  : undefined;
@@ -250,7 +251,9 @@ export const MatchesAnySelect = props => {
250
251
  onChange(selectedItems);
251
252
  setState(prev => (Object.assign(Object.assign({}, prev), { isOpenPopover: false })));
252
253
  };
253
- return (React.createElement(Popover, { open: isOpenPopover, arrow: false, placement: "bottomLeft", content: React.createElement(MatchesAny, { items: items, selectedItems: selectedItems, isLoading: isLoading, objectName: objectName, style: { margin: '-8px 0px' }, onApply: onApplyMatchesAny, onCancel: () => setState(prev => (Object.assign(Object.assign({}, prev), { isOpenPopover: false }))) }), overlayStyle: { width: 700 }, trigger: ['click'], destroyTooltipOnHide: true, onOpenChange: () => setState(prev => (Object.assign(Object.assign({}, prev), { isOpenPopover: !isOpenPopover }))) },
254
- React.createElement(Tooltip, { mouseEnterDelay: 0.5, title: `${selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.map(item => item.title).join(', ')}` },
255
- React.createElement(Select, Object.assign({ title: "", value: value, placeholder: placeholder, popupMatchSelectWidth: 700, dropdownStyle: Object.assign(Object.assign({}, dropdownStyle), { display: 'none', padding: 0 }) }, restProps)))));
254
+ return (React.createElement(Popover, { open: isOpenPopover, arrow: false, placement: "bottomLeft", content: React.createElement(MatchesAny, { className: popupClassName, items: items, selectedItems: selectedItems, loading: loading, objectName: objectName, onApply: onApplyMatchesAny, onCancel: () => setState(prev => (Object.assign(Object.assign({}, prev), { isOpenPopover: false }))) }), overlayStyle: { width: 700 }, overlayInnerStyle: {
255
+ padding: 0,
256
+ }, trigger: ['click'], destroyTooltipOnHide: true, onOpenChange: () => setState(prev => (Object.assign(Object.assign({}, prev), { isOpenPopover: !isOpenPopover }))) },
257
+ React.createElement(Tooltip, { mouseEnterDelay: 0.5, title: `${selectedItems ? selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.map(item => item.title).join(', ') : ''}` },
258
+ React.createElement(Select, Object.assign({ title: "", value: value, placeholder: placeholder, popupMatchSelectWidth: 700, dropdownStyle: Object.assign(Object.assign({}, dropdownStyle), { display: 'none', padding: 0 }), loading: loading }, restProps)))));
256
259
  };
@@ -90,6 +90,19 @@ export const MatchesAnyWrapper = styled(Flex) `
90
90
  align-items: center;
91
91
  justify-content: space-between;
92
92
  gap: 10px;
93
+
94
+ .title-content {
95
+ padding: 5px 0px;
96
+ display: flex;
97
+ flex-direction: column;
98
+ width: 100%;
99
+ height: 100%;
100
+ overflow: auto;
101
+
102
+ .sub-title {
103
+ font-size: 11px;
104
+ }
105
+ }
93
106
  }
94
107
  }
95
108
 
@@ -113,7 +126,7 @@ export const MatchesAnyWrapper = styled(Flex) `
113
126
 
114
127
  &.antsomi-tree-treenode-disabled {
115
128
  .antsomi-typography {
116
- color: ${globalToken === null || globalToken === void 0 ? void 0 : globalToken.bw6};
129
+ color: ${globalToken === null || globalToken === void 0 ? void 0 : globalToken.bw6} !important;
117
130
  }
118
131
 
119
132
  .select-button {
@@ -2,14 +2,16 @@ import { TreeDataNode } from 'antd';
2
2
  import type { SelectProps } from '@antscorp/antsomi-ui/es/components/molecules';
3
3
  import type { FlexProps } from '@antscorp/antsomi-ui/es/components/atoms';
4
4
  export type MatchesAnyItem = TreeDataNode & {
5
+ /** Addition title of the item. */
6
+ subTitle?: string;
7
+ /** Indicates whether the item is extended */
5
8
  isExtendValue?: boolean;
9
+ /** An array of children items. */
6
10
  children?: MatchesAnyItem[];
7
11
  };
8
12
  export interface MatchesAnySelectProps extends SelectProps {
9
13
  /** The name of object to be displayed in Popover */
10
14
  objectName?: string;
11
- /** Indicates whether the component is loading */
12
- isLoading?: boolean;
13
15
  /** Indicates whether show the extend value button */
14
16
  showExtendValue?: boolean;
15
17
  /** An array of items. */
@@ -23,7 +25,7 @@ export interface MatchesAnyProps extends Omit<FlexProps, 'children'> {
23
25
  /** The name of the object, corresponding to the `objectName` property in `MatchesAnySelectProps`. */
24
26
  objectName?: MatchesAnySelectProps['objectName'];
25
27
  /** Indicates whether the component is in a loading state, corresponding to the `isLoading` property in `MatchesAnySelectProps`. */
26
- isLoading?: MatchesAnySelectProps['isLoading'];
28
+ loading?: MatchesAnySelectProps['loading'];
27
29
  /** Determines whether to show the extended value, corresponding to the `showExtendValue` property in `MatchesAnySelectProps`. */
28
30
  showExtendValue?: MatchesAnySelectProps['showExtendValue'];
29
31
  /** An array of items. */
@@ -13,8 +13,8 @@ import { translations } from '@antscorp/antsomi-ui/es/locales/translations';
13
13
  import { EXCEPTION_OFF_FILTER_CLASS } from '../../constants/filter';
14
14
  export const AddFilterButton = memo(() => {
15
15
  const { t } = i18nInstance;
16
- const { openPopover, selectedFilterMetric, onSelectFilterMetric, onApplyFilterMetricCondition, onClickAddFilter, setState: setAddFilterConditionState, } = useAddFilterCondition();
17
- return (React.createElement(Popover, { open: openPopover, content: React.createElement("div", { className: EXCEPTION_OFF_FILTER_CLASS }, selectedFilterMetric ? (React.createElement(FilterCondition, { filterMetric: selectedFilterMetric, onCancel: () => onSelectFilterMetric(undefined), onApply: ({ operator, value }) => {
16
+ const { openPopover, selectedFilterMetric, matchesAny, onSelectFilterMetric, onApplyFilterMetricCondition, onClickAddFilter, onChangeFilterCondition, setState: setAddFilterConditionState, } = useAddFilterCondition();
17
+ return (React.createElement(Popover, { open: openPopover, content: React.createElement("div", { className: EXCEPTION_OFF_FILTER_CLASS }, selectedFilterMetric ? (React.createElement(FilterCondition, { filterMetric: selectedFilterMetric, matchesAny: matchesAny, onCancel: () => onSelectFilterMetric(undefined), onApply: ({ operator, value }) => {
18
18
  onApplyFilterMetricCondition({
19
19
  filterMetric: selectedFilterMetric,
20
20
  operator,
@@ -22,6 +22,15 @@ export const AddFilterButton = memo(() => {
22
22
  });
23
23
  onSelectFilterMetric(undefined);
24
24
  setAddFilterConditionState(prev => (Object.assign(Object.assign({}, prev), { openPopover: false })));
25
+ }, onChange: condition => {
26
+ const { id, dataType } = selectedFilterMetric;
27
+ const { operator, value } = condition || {};
28
+ onChangeFilterCondition({
29
+ column: id,
30
+ operator,
31
+ value,
32
+ dataType,
33
+ });
25
34
  } })) : (React.createElement(SavedFilterAndMetrics, { onSelectFilterMetric: onSelectFilterMetric, onSelectSavedFilter: () => {
26
35
  setAddFilterConditionState(prev => (Object.assign(Object.assign({}, prev), { openPopover: false })));
27
36
  } }))), trigger: ['click'], overlayInnerStyle: { width: 300, padding: 0 }, arrow: false, placement: "bottomLeft", destroyTooltipOnHide: true, onOpenChange: open => {
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { FilterItem, FilterMetricItem } from '../../../types';
2
+ import { FilterItem, FilterMetricItem, FilterProps } from '../../../types';
3
3
  type TFormType = {
4
4
  operator: string;
5
5
  value: any;
@@ -7,8 +7,10 @@ type TFormType = {
7
7
  interface FilterConditionProps {
8
8
  filterMetric: FilterMetricItem;
9
9
  filterCondition?: FilterItem;
10
+ matchesAny?: FilterProps['matchesAny'];
10
11
  onCancel?: () => void;
11
12
  onApply?: (values: TFormType) => void;
13
+ onChange?: (values: TFormType) => void;
12
14
  }
13
15
  export declare const FilterCondition: React.FC<FilterConditionProps>;
14
16
  export {};
@@ -10,12 +10,12 @@ import { EXCEPTION_OFF_FILTER_CLASS } from '../../../constants/filter';
10
10
  const { BETWEEN, EXISTS, NOT_EXISTS } = OPERATORS_OPTION;
11
11
  export const FilterCondition = props => {
12
12
  // Props
13
- const { filterMetric, filterCondition, onCancel, onApply } = props;
13
+ const { filterMetric, filterCondition, matchesAny, onChange, onCancel, onApply } = props;
14
14
  // Hooks
15
15
  const [form] = Form.useForm();
16
16
  // Form
17
- const operator = Form.useWatch('operator', form);
18
- const value = Form.useWatch('value', form);
17
+ const formValues = Form.useWatch([], form);
18
+ const { operator, value } = formValues || {};
19
19
  // Variables
20
20
  const { name, dataType, operators } = filterMetric;
21
21
  // Memos
@@ -53,6 +53,12 @@ export const FilterCondition = props => {
53
53
  operator: ((_a = operatorList[0]) === null || _a === void 0 ? void 0 : _a.value) || '',
54
54
  });
55
55
  }, [form, operatorList]);
56
+ /** Handle callback change values */
57
+ useEffect(() => {
58
+ if (formValues) {
59
+ onChange === null || onChange === void 0 ? void 0 : onChange(formValues);
60
+ }
61
+ }, [formValues, onChange]);
56
62
  /* Update filter condition values */
57
63
  useEffect(() => {
58
64
  if (filterCondition) {
@@ -82,12 +88,13 @@ export const FilterCondition = props => {
82
88
  React.createElement(Form.Item, { name: "operator", noStyle: true },
83
89
  React.createElement(Select, { value: operator, options: operatorList, onChange: () => form.setFieldsValue({
84
90
  value: '',
85
- }), getPopupContainer: node => node.parentElement, dropdownRender: menu => (React.createElement("div", { className: EXCEPTION_OFF_FILTER_CLASS, onClick: e => e.stopPropagation() }, menu)) })),
91
+ }), dropdownRender: menu => (React.createElement("div", { className: EXCEPTION_OFF_FILTER_CLASS, onClick: e => e.stopPropagation() }, menu)) })),
86
92
  React.createElement(Form.Item, { name: "value", noStyle: true }),
87
93
  renderValueField({
88
94
  filterMetric,
89
95
  operator,
90
96
  value,
97
+ matchesAny,
91
98
  onChangeValue: value => {
92
99
  form.setFieldsValue({
93
100
  value,
@@ -6,7 +6,7 @@ import { Button, Flex, Icon, Popover } from '@antscorp/antsomi-ui/es/components/
6
6
  import { FilterCondition } from './FilterCondition';
7
7
  // Constants
8
8
  import { EXCEPTION_OFF_FILTER_CLASS, FILTER_SHOW_MAX } from '../../constants/filter';
9
- import { OPERATORS_OPTION, globalToken } from '@antscorp/antsomi-ui/es/constants';
9
+ import { globalToken } from '@antscorp/antsomi-ui/es/constants';
10
10
  // Contexts
11
11
  import { useDataTableContext } from '../../contexts/DataTableContext';
12
12
  // Hooks
@@ -22,7 +22,7 @@ import { translations } from '@antscorp/antsomi-ui/es/locales/translations';
22
22
  const { t } = i18nInstance;
23
23
  export const FilterConditionList = memo(() => {
24
24
  // Store
25
- const { filterMetrics, filters, isFilterActive, onChangeFilters = () => { }, } = useDataTableContext(store => store.filter);
25
+ const { filterMetrics, filters, isFilterActive, matchesAny, onChangeFilters = () => { }, onChangeFilterCondition = () => { }, } = useDataTableContext(store => store.filter);
26
26
  const setFilter = useDataTableContext(store => store.setFilter);
27
27
  // State
28
28
  /* Reserve for handle popover open per filter condition */
@@ -60,36 +60,38 @@ export const FilterConditionList = memo(() => {
60
60
  onChangeFilters(cloneFilters || []);
61
61
  };
62
62
  const renderFilterItem = () => serializeFilters === null || serializeFilters === void 0 ? void 0 : serializeFilters.map((filter, index) => {
63
- var _a;
64
63
  const { column, operator, value, isOpenPopover } = filter;
65
64
  const metric = flattenFilterMetrics === null || flattenFilterMetrics === void 0 ? void 0 : flattenFilterMetrics.find(filterMetric => filterMetric.id === column);
66
- const operatorLabel = ((_a = Object.values(OPERATORS_OPTION).find(({ value }) => value === operator)) === null || _a === void 0 ? void 0 : _a.label) || '';
67
65
  // Hide too many filter when filter is active
68
66
  if (!metric || (!isFilterActive && index + 1 > FILTER_SHOW_MAX))
69
67
  return null;
70
68
  return (React.createElement(Popover, { key: `${column}-${operator}-${value}-${index}`, open: isOpenPopover, content: React.createElement("div", { className: EXCEPTION_OFF_FILTER_CLASS },
71
- React.createElement(FilterCondition, { filterMetric: metric, filterCondition: filter, onApply: ({ operator, value }) => {
69
+ React.createElement(FilterCondition, { matchesAny: matchesAny, filterMetric: metric, filterCondition: filter, onApply: ({ operator, value }) => {
72
70
  onApplyFilterMetricCondition({
73
71
  operator,
74
72
  value,
75
73
  existMetricIdx: index,
76
74
  });
77
75
  handleTogglePopover(index, false);
76
+ }, onChange: condition => {
77
+ onChangeFilterCondition({
78
+ column: metric.id,
79
+ operator: condition.operator,
80
+ value: condition.value,
81
+ dataType: metric.dataType,
82
+ });
78
83
  }, onCancel: () => handleTogglePopover(index, false) })), trigger: ['click'], overlayInnerStyle: { width: 300, padding: 0 }, arrow: false, placement: "bottomLeft", onOpenChange: open => handleTogglePopover(index, open) },
79
84
  React.createElement(FilterItem, { gap: 5, onClick: () => setFilter({
80
85
  isFilterActive: true,
81
- }), name: (metric === null || metric === void 0 ? void 0 : metric.name) || column.toString() || '', operator: operatorLabel, value: value, onClickRemove: () => onClickRemoveFilter(index) })));
86
+ }), name: (metric === null || metric === void 0 ? void 0 : metric.name) || column.toString() || '', operator: operator, value: value, onClickRemove: () => onClickRemoveFilter(index) })));
82
87
  });
83
88
  const renderViewAll = () => {
84
89
  var _a;
85
90
  if (isFilterActive || (serializeFilters === null || serializeFilters === void 0 ? void 0 : serializeFilters.length) <= FILTER_SHOW_MAX)
86
91
  return null;
87
92
  return (React.createElement(Popover, { open: isOpenViewAllPopover, content: React.createElement(Flex, { vertical: true, gap: 5 }, (_a = serializeFilters === null || serializeFilters === void 0 ? void 0 : serializeFilters.slice(3)) === null || _a === void 0 ? void 0 : _a.map((filter, index) => {
88
- var _a;
89
93
  const { column, operator, value } = filter;
90
94
  const metric = flattenFilterMetrics === null || flattenFilterMetrics === void 0 ? void 0 : flattenFilterMetrics.find(filterMetric => filterMetric.id === column);
91
- const operatorLabel = ((_a = Object.values(OPERATORS_OPTION).find(({ value }) => value === operator)) === null || _a === void 0 ? void 0 : _a.label) ||
92
- '';
93
95
  if (!metric)
94
96
  return null;
95
97
  return (React.createElement(FilterItem, { key: `${column}-${operator}-${value}-${index}`, gap: 5, onClick: () => {
@@ -100,7 +102,7 @@ export const FilterConditionList = memo(() => {
100
102
  handleTogglePopover(FILTER_SHOW_MAX + index, true);
101
103
  // Close popover view all
102
104
  setState(prev => (Object.assign(Object.assign({}, prev), { isOpenViewAllPopover: false })));
103
- }, name: (metric === null || metric === void 0 ? void 0 : metric.name) || column.toString() || '', operator: operatorLabel, value: value, onClickRemove: () => onClickRemoveFilter(index) }));
105
+ }, name: (metric === null || metric === void 0 ? void 0 : metric.name) || column.toString() || '', operator: operator, value: value, onClickRemove: () => onClickRemoveFilter(index) }));
104
106
  })), trigger: ['click'], overlayInnerStyle: { width: 300, padding: 15 }, arrow: false, onOpenChange: open => setState(prev => (Object.assign(Object.assign({}, prev), { isOpenViewAllPopover: open }))) },
105
107
  React.createElement(Button, { type: "text", style: Object.assign({}, (isOpenViewAllPopover && { backgroundColor: globalToken === null || globalToken === void 0 ? void 0 : globalToken.blue1_1 })) },
106
108
  t(translations.viewAll).toString(),
@@ -10,22 +10,52 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  return t;
11
11
  };
12
12
  // Libraries
13
- import React from 'react';
13
+ import React, { useMemo } from 'react';
14
+ import dayjs from 'dayjs';
14
15
  // Components
15
16
  import { Icon, Typography } from '@antscorp/antsomi-ui/es/components/atoms';
16
17
  // Styled
17
18
  import { StyledFilterItem } from './styled';
19
+ // Constants
20
+ import { DATE_TIME_FORMAT, OPERATORS_CODE, OPERATORS_OPTION, } from '@antscorp/antsomi-ui/es/constants';
21
+ const { MATCHES_ANY, MATCHES, NOT_MATCHES, IS } = OPERATORS_CODE;
18
22
  const { Text } = Typography;
19
23
  export const FilterItem = props => {
20
24
  const { name, operator, value, onClickRemove } = props, restProps = __rest(props, ["name", "operator", "value", "onClickRemove"]);
21
- const tooltipContent = `${name} ${operator} ${value}`;
25
+ // Memo
26
+ const serializeValue = useMemo(() => {
27
+ // Check type of value is valid date
28
+ if (dayjs(value).isValid()) {
29
+ return dayjs(value).format(DATE_TIME_FORMAT.FILTER_CONDITION);
30
+ }
31
+ // Check value is an array and operator is MATCHES_ANY
32
+ if (Array.isArray(value) && operator === MATCHES_ANY) {
33
+ return value.map(item => item.title).join(', ');
34
+ }
35
+ return value;
36
+ }, [operator, value]);
37
+ const serializeOperator = useMemo(() => {
38
+ var _a;
39
+ const operatorLabel = ((_a = Object.values(OPERATORS_OPTION).find(({ value }) => value === operator)) === null || _a === void 0 ? void 0 : _a.label) || '';
40
+ switch (operator) {
41
+ case MATCHES_ANY:
42
+ case NOT_MATCHES:
43
+ case MATCHES:
44
+ case IS:
45
+ return null;
46
+ default:
47
+ return operatorLabel;
48
+ }
49
+ }, [operator]);
50
+ const tooltipContent = `${name} ${operator} ${serializeValue}`;
22
51
  return (React.createElement(StyledFilterItem, Object.assign({ gap: 5 }, restProps),
23
52
  React.createElement(Text, { ellipsis: { tooltip: tooltipContent } },
24
- React.createElement(Text, { strong: true }, name),
25
- " \u00A0",
26
- React.createElement(Text, null, operator),
53
+ React.createElement(Text, null, name),
27
54
  " \u00A0",
28
- React.createElement(Text, { strong: true, className: "filter-item__value" }, value)),
55
+ serializeOperator && React.createElement(Text, null,
56
+ serializeOperator,
57
+ " \u00A0"),
58
+ React.createElement(Text, { strong: true, className: "filter-item__value" }, serializeValue)),
29
59
  React.createElement("div", { className: "filter-item__close-btn", onClick: e => {
30
60
  e.stopPropagation();
31
61
  if (onClickRemove) {
@@ -19,7 +19,7 @@ export const RowSelectedControl = memo(() => {
19
19
  }
20
20
  return (dropdownProps === null || dropdownProps === void 0 ? void 0 : dropdownProps.menu) ? (React.createElement(Dropdown, Object.assign({ key: key, trigger: ['click'], arrow: false, placement: "bottomLeft", overlayStyle: { minWidth: 200 } }, dropdownProps), buttonComponent)) : (buttonComponent);
21
21
  };
22
- return (React.createElement(RowSelectedControlWrapper, { align: "center" },
22
+ return (React.createElement(RowSelectedControlWrapper, { className: "selected-control", align: "center" },
23
23
  React.createElement(Flex, { className: "selected-count-label", align: "center" },
24
24
  (selectedRowKeys === null || selectedRowKeys === void 0 ? void 0 : selectedRowKeys.length) || 0,
25
25
  " selected"),
@@ -38,6 +38,7 @@ export const FilterSection = styled(Flex) `
38
38
  cursor: pointer;
39
39
  `;
40
40
  export const RowSelectedControlWrapper = styled(Flex) `
41
+ flex-shrink: 0;
41
42
  height: ${toolbarHeight}px;
42
43
  background-color: ${globalToken === null || globalToken === void 0 ? void 0 : globalToken.colorPrimary};
43
44
  color: ${globalToken === null || globalToken === void 0 ? void 0 : globalToken.bw0};
@@ -20,6 +20,8 @@ export const DATA_TABLE_THEME = {
20
20
  rowHoverBg: '#DEEFFE',
21
21
  borderRadius: 0,
22
22
  headerBorderRadius: 0,
23
+ rowSelectedBg: '#DEEFFE',
24
+ rowSelectedHoverBg: '#F2F9FF',
23
25
  },
24
26
  Menu: {
25
27
  itemBorderRadius: 0,
@@ -12,10 +12,15 @@ type OnApplyFilterMetricConditionValue = {
12
12
  };
13
13
  export declare const useAddFilterCondition: () => {
14
14
  filters: import("../types").FilterItem[] | undefined;
15
+ matchesAny: {
16
+ list?: import("../../..").MatchesAnyItem[] | undefined;
17
+ isLoading?: boolean | undefined;
18
+ } | undefined;
15
19
  setState: import("react").Dispatch<import("react").SetStateAction<TState>>;
16
20
  onSelectFilterMetric: (filterMetric?: FilterMetricItem) => void;
17
21
  onApplyFilterMetricCondition: (values: OnApplyFilterMetricConditionValue) => void;
18
22
  onClickAddFilter: () => void;
23
+ onChangeFilterCondition: (filterItem: import("../types").FilterItem) => void;
19
24
  openPopover?: boolean | undefined;
20
25
  selectedFilterMetric?: FilterMetricItem | undefined;
21
26
  };
@@ -10,7 +10,7 @@ export const useAddFilterCondition = () => {
10
10
  selectedFilterMetric: undefined,
11
11
  });
12
12
  // Store
13
- const { filters, onChangeFilters = () => { } } = useDataTableContext(store => store.filter);
13
+ const { filters, matchesAny, onChangeFilters = () => { }, onChangeFilterCondition = () => { }, } = useDataTableContext(store => store.filter);
14
14
  const setFilter = useDataTableContext(store => store.setFilter);
15
15
  // Handlers
16
16
  const onSelectFilterMetric = useCallback((filterMetric) => {
@@ -48,9 +48,11 @@ export const useAddFilterCondition = () => {
48
48
  return Object.assign(Object.assign({}, state), {
49
49
  // Filter
50
50
  filters,
51
+ matchesAny,
51
52
  // Handlers
52
53
  setState,
53
54
  onSelectFilterMetric,
54
55
  onApplyFilterMetricCondition,
55
- onClickAddFilter });
56
+ onClickAddFilter,
57
+ onChangeFilterCondition });
56
58
  };
@@ -7,9 +7,14 @@ 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
11
  export type TApiGlobal = AxiosRequestConfig<any> & {
11
12
  enabled?: boolean;
12
13
  };
14
+ type TMatchesAnyParams = (filterItem?: FilterItem) => any | any;
15
+ type TMatchesAnyProps = {
16
+ formatData: (response: any) => MatchesAnyItem[];
17
+ };
13
18
  export type TConfig<TTableType = any> = {
14
19
  env?: TEnv;
15
20
  auth?: TServiceAuth;
@@ -19,8 +24,12 @@ export type TConfig<TTableType = any> = {
19
24
  filter?: TApiGlobal;
20
25
  search?: TApiGlobal;
21
26
  matchesAny?: {
22
- general: TApiGlobal;
23
- } & Partial<Record<keyof TTableType, TApiGlobal>>;
27
+ general: Omit<TApiGlobal, 'params'> & {
28
+ params?: TMatchesAnyParams;
29
+ };
30
+ } & Partial<Record<keyof TTableType, Omit<TApiGlobal, 'params'> & {
31
+ params?: TMatchesAnyParams;
32
+ }>>;
24
33
  };
25
34
  object?: {
26
35
  type: number;
@@ -48,7 +57,7 @@ type TSearchProps<TSearchType> = Partial<Pick<TSearchActionButton, 'addFilterInf
48
57
  };
49
58
  export interface UseDataTableListingProps<TTableType = any, TSearchType = any> {
50
59
  name?: string;
51
- config: TConfig;
60
+ config: TConfig<TTableType>;
52
61
  queryOptions?: {
53
62
  getTableListing?: TGetTableListing['options'];
54
63
  getColumnMetricList?: TGetColumnMetrics['options'];
@@ -68,6 +77,9 @@ export interface UseDataTableListingProps<TTableType = any, TSearchType = any> {
68
77
  filter?: {
69
78
  externalFilters?: FilterItem[];
70
79
  includeDataType?: boolean;
80
+ matchesAny?: {
81
+ general: TMatchesAnyProps;
82
+ } & Partial<Record<keyof TTableType, TMatchesAnyProps>>;
71
83
  };
72
84
  }
73
85
  export interface DataTableLocalStorage<TTableType = any> {
@@ -47,6 +47,7 @@ type TState<TTableType = any> = {
47
47
  };
48
48
  searchValue?: string;
49
49
  sorter?: SorterResult<TTableType>;
50
+ selectedFilterItem?: FilterItem;
50
51
  };
51
52
  export declare function useDataTableListing<TTableType = Record<string, any>, TSearchType = any>(props: UseDataTableListingProps<TTableType, TSearchType>): TUseDataTableListing<TTableType>;
52
53
  export {};