@antscorp/antsomi-ui 1.3.5-beta.589 → 1.3.5-beta.590

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.
@@ -1,6 +1,6 @@
1
1
  /// <reference types="hoist-non-react-statics" />
2
2
  import React, { ReactNode } from 'react';
3
- import { InputProps as AntdInputProps, Input as AntdInput } from 'antd';
3
+ import { InputProps as AntdInputProps, Input as AntdInput, InputRef } from 'antd';
4
4
  export interface InputProps extends AntdInputProps {
5
5
  noborder?: 'true' | 'false' | boolean;
6
6
  debounce?: number;
@@ -16,20 +16,20 @@ export interface InputProps extends AntdInputProps {
16
16
  disableUndo?: boolean;
17
17
  withWrapper?: boolean;
18
18
  }
19
- export declare const Input: string & import("styled-components").StyledComponentBase<React.ForwardRefExoticComponent<AntdInputProps & React.RefAttributes<import("antd").InputRef>> & {
19
+ export declare const Input: string & import("styled-components").StyledComponentBase<React.ForwardRefExoticComponent<AntdInputProps & React.RefAttributes<InputRef>> & {
20
20
  Group: React.FC<import("antd/es/input").GroupProps>;
21
- Search: React.ForwardRefExoticComponent<import("antd/es/input").SearchProps & React.RefAttributes<import("antd").InputRef>>;
21
+ Search: React.ForwardRefExoticComponent<import("antd/es/input").SearchProps & React.RefAttributes<InputRef>>;
22
22
  TextArea: React.ForwardRefExoticComponent<import("antd/es/input").TextAreaProps & React.RefAttributes<import("antd/es/input/TextArea").TextAreaRef>>;
23
- Password: React.ForwardRefExoticComponent<import("antd/es/input").PasswordProps & React.RefAttributes<import("antd").InputRef>>;
24
- }, any, InputProps, never> & import("hoist-non-react-statics").NonReactStatics<React.ForwardRefExoticComponent<AntdInputProps & React.RefAttributes<import("antd").InputRef>> & {
23
+ Password: React.ForwardRefExoticComponent<import("antd/es/input").PasswordProps & React.RefAttributes<InputRef>>;
24
+ }, any, InputProps, never> & import("hoist-non-react-statics").NonReactStatics<React.ForwardRefExoticComponent<AntdInputProps & React.RefAttributes<InputRef>> & {
25
25
  Group: React.FC<import("antd/es/input").GroupProps>;
26
- Search: React.ForwardRefExoticComponent<import("antd/es/input").SearchProps & React.RefAttributes<import("antd").InputRef>>;
26
+ Search: React.ForwardRefExoticComponent<import("antd/es/input").SearchProps & React.RefAttributes<InputRef>>;
27
27
  TextArea: React.ForwardRefExoticComponent<import("antd/es/input").TextAreaProps & React.RefAttributes<import("antd/es/input/TextArea").TextAreaRef>>;
28
- Password: React.ForwardRefExoticComponent<import("antd/es/input").PasswordProps & React.RefAttributes<import("antd").InputRef>>;
28
+ Password: React.ForwardRefExoticComponent<import("antd/es/input").PasswordProps & React.RefAttributes<InputRef>>;
29
29
  }, {}> & {
30
30
  DefaultInput: typeof AntdInput;
31
31
  CustomSearch: typeof SearchInput;
32
32
  };
33
- declare const SearchInput: React.FC<InputProps>;
33
+ declare const SearchInput: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<InputRef>>;
34
34
  export declare const TextArea: React.ForwardRefExoticComponent<import("antd/es/input").TextAreaProps & React.RefAttributes<import("antd/es/input/TextArea").TextAreaRef>>;
35
35
  export {};
@@ -23,7 +23,7 @@ import { getPreventKeyboardAction } from '@antscorp/antsomi-ui/es/utils/web';
23
23
  import { StyledInput } from './styled';
24
24
  import { globalToken } from '@antscorp/antsomi-ui/es/constants';
25
25
  const PATH = '@antscorp/antsomi-ui/es/components/atoms/Input/Input.tsx';
26
- const OriginInput = props => {
26
+ const OriginInput = React.forwardRef((props, ref) => {
27
27
  // Props
28
28
  const { withWrapper, debounce, errorArchive, required, labelColor, isReverseMask, isHideErrMessage, focused, label, onAfterChange, onChange, errorMsg } = props, restProps = __rest(props, ["withWrapper", "debounce", "errorArchive", "required", "labelColor", "isReverseMask", "isHideErrMessage", "focused", "label", "onAfterChange", "onChange", "errorMsg"]);
29
29
  // State
@@ -79,7 +79,7 @@ const OriginInput = props => {
79
79
  }
80
80
  const content = (React.createElement(React.Fragment, null,
81
81
  label && renderRequiredLabel(label),
82
- React.createElement(StyledInput, Object.assign({}, restProps, { value: value, onBlur: e => {
82
+ React.createElement(StyledInput, Object.assign({}, restProps, { ref: ref, value: value, onBlur: e => {
83
83
  if (!isFocused) {
84
84
  setFocused(true);
85
85
  }
@@ -89,14 +89,14 @@ const OriginInput = props => {
89
89
  if (!withWrapper)
90
90
  return content;
91
91
  return React.createElement("div", { className: "input__wrapper" }, content);
92
- };
92
+ });
93
93
  OriginInput.defaultProps = {
94
94
  debounce: 400,
95
95
  isHideErrMessage: false,
96
96
  withWrapper: true,
97
97
  };
98
98
  export const Input = OriginInput;
99
- const SearchInput = props => (React.createElement(OriginInput, Object.assign({ bordered: false, autoFocus: true, suffix: React.createElement(Icon, { type: "icon-ants-search-2", size: 24, color: globalToken === null || globalToken === void 0 ? void 0 : globalToken.bw8 }) }, props, { className: `${props.className} antsomi-search-input` })));
99
+ const SearchInput = React.forwardRef((props, ref) => (React.createElement(OriginInput, Object.assign({ bordered: false, autoFocus: true, suffix: React.createElement(Icon, { type: "icon-ants-search-2", size: 24, color: globalToken === null || globalToken === void 0 ? void 0 : globalToken.bw8 }) }, props, { ref: ref, className: `${props.className} antsomi-search-input` }))));
100
100
  Input.CustomSearch = SearchInput;
101
101
  Input.TextArea = StyledInput.TextArea;
102
102
  Input.DefaultInput = AntdInput;
@@ -30,193 +30,6 @@ import { Button, Flex, Typography, Spin, Tooltip, Icon } from '../../atoms';
30
30
  import { THUMBNAIL_CARD_ACTION_OPTIONS, THUMBNAIL_CARD_DEFAULT_HEIGHT, THUMBNAIL_CARD_DEFAULT_WIDTH, } from './constants';
31
31
  import { getUrlNoCache, checkShowSkeletonBaseUrl } from '@antscorp/antsomi-ui/es/utils';
32
32
  import { translations } from '@antscorp/antsomi-ui/es/locales/translations';
33
- // export const ThumbnailCard: React.FC<ThumbnailCardProps> = memo(props => {
34
- // const [modal, contextHolder] = Modal.useModal();
35
- // const {
36
- // id,
37
- // name,
38
- // width = THUMBNAIL_CARD_DEFAULT_WIDTH,
39
- // height = THUMBNAIL_CARD_DEFAULT_HEIGHT,
40
- // thumbnail,
41
- // thumbnailFit,
42
- // removable = true,
43
- // actionAvailable = true,
44
- // showSkeleton,
45
- // loading = false,
46
- // removeModalProps,
47
- // editBtnProps,
48
- // previewBtnProps,
49
- // thumbnailCacheValue,
50
- // actionButtons,
51
- // onClickWrapper,
52
- // ...restOfProps
53
- // } = props;
54
- // const { onOk, ...restOfRemoveTemplateModalProps } = removeModalProps || {};
55
- // const {
56
- // text: editText = 'Use template',
57
- // onClick: onClickEdit,
58
- // ...restOfEditBtnProps
59
- // } = editBtnProps || {};
60
- // const {
61
- // text: previewText = 'Preview',
62
- // onClick: onClickPreview,
63
- // ...restOfPreviewBtnProps
64
- // } = previewBtnProps || {};
65
- // // Memo
66
- // const showSkeletonMemo =
67
- // // NOTES: Hot fix for showSkeleton base url if showSkeleton is not defined
68
- // typeof showSkeleton === 'undefined'
69
- // ? checkShowSkeletonBaseUrl(thumbnail)
70
- // : typeof showSkeleton === 'function'
71
- // ? showSkeleton(props)
72
- // : showSkeleton;
73
- // // Handlers
74
- // const handleRemoveThumbnail: React.MouseEventHandler<HTMLElement> = e => {
75
- // e.stopPropagation();
76
- // modal.confirm({
77
- // title: 'Remove template',
78
- // centered: true,
79
- // icon: <Icon type="icon-ants-info" style={{ fontSize: 16, lineHeight: '25px' }} />,
80
- // content: (
81
- // <div>
82
- // <p>Are you sure you want to remove the template?</p>
83
- // <p>This action can not be undone.</p>
84
- // </div>
85
- // ),
86
- // okText: 'Remove',
87
- // cancelText: 'Cancel',
88
- // closable: true,
89
- // ...restOfRemoveTemplateModalProps,
90
- // onOk: async () => {
91
- // if (onOk) onOk(id);
92
- // },
93
- // });
94
- // };
95
- // const handleWrapperClick: React.MouseEventHandler<HTMLElement> = e => {
96
- // e.stopPropagation();
97
- // onClickWrapper?.(id);
98
- // };
99
- // // Handlers
100
- // const renderActionButtons = () => {
101
- // if (!actionButtons) return null;
102
- // return Object.keys(actionButtons)
103
- // .map(key => {
104
- // const option = THUMBNAIL_CARD_ACTION_OPTIONS[key];
105
- // const actionSettings = actionButtons[key as TActionButtonKey];
106
- // if (actionSettings) {
107
- // const { buttonProps, key, customRender } = actionSettings;
108
- // const icon = actionSettings.icon || option.icon || '';
109
- // const label = actionSettings.label || option.label || '';
110
- // const ButtonComponent = (
111
- // <Tooltip title={label}>
112
- // <Button
113
- // key={key || option.key}
114
- // type="primary"
115
- // icon={
116
- // <Icon type={icon || option.icon} style={{ fontSize: 24, color: '#FFFFFF' }} />
117
- // }
118
- // {...buttonProps}
119
- // />
120
- // </Tooltip>
121
- // );
122
- // /**
123
- // * Handle custom render for action button
124
- // * If customRender is a function, return the function callback the ButtonComponent
125
- // * If not, return ButtonComponent
126
- // */
127
- // return typeof customRender === 'function'
128
- // ? customRender(ButtonComponent)
129
- // : ButtonComponent;
130
- // }
131
- // return null;
132
- // })
133
- // .filter(Boolean);
134
- // };
135
- // return (
136
- // <Flex gap={10} vertical {...restOfProps} style={{ width, ...restOfProps.style }}>
137
- // <ThumbnailCardWrapper
138
- // $showSkeleton={showSkeletonMemo}
139
- // style={{ height, cursor: actionAvailable ? 'default' : 'pointer' }}
140
- // onClick={handleWrapperClick}
141
- // >
142
- // <div className="screen">
143
- // {thumbnail && (
144
- // <img
145
- // src={getUrlNoCache(thumbnail, thumbnailCacheValue)}
146
- // alt=""
147
- // style={{ objectFit: thumbnailFit }}
148
- // onError={e => {
149
- // e.currentTarget.style.display = 'none';
150
- // }}
151
- // />
152
- // )}
153
- // </div>
154
- // {actionAvailable && !loading && (
155
- // <>
156
- // <Flex className="center-action" align="center" gap={10} vertical>
157
- // <Button
158
- // type="primary"
159
- // className="animate__animated animate__fadeIn"
160
- // {...restOfEditBtnProps}
161
- // onClick={e => {
162
- // e.stopPropagation();
163
- // onClickEdit?.(id);
164
- // }}
165
- // >
166
- // <Typography.Text
167
- // ellipsis={{ tooltip: editText }}
168
- // style={{ maxWidth: '100%', color: 'inherit' }}
169
- // >
170
- // {editText}
171
- // </Typography.Text>
172
- // </Button>
173
- // <Button
174
- // className="animate__animated animate__fadeIn"
175
- // onClick={e => {
176
- // e.stopPropagation();
177
- // onClickPreview?.(id);
178
- // }}
179
- // {...restOfPreviewBtnProps}
180
- // >
181
- // <Typography.Text
182
- // ellipsis={{ tooltip: previewText }}
183
- // style={{ maxWidth: '100%', color: 'inherit' }}
184
- // >
185
- // {previewText}
186
- // </Typography.Text>
187
- // </Button>
188
- // </Flex>
189
- // <div className="top-right-corner-action animate__animated animate__fadeIn">
190
- // {renderActionButtons()}
191
- // {removable && (
192
- // <Tooltip title={i18nInstance.t(translations.remove).toString()}>
193
- // <Button
194
- // type="primary"
195
- // icon={
196
- // <Icon
197
- // type="icon-ants-trash-outline"
198
- // style={{ fontSize: 24, color: '#FFFFFF' }}
199
- // />
200
- // }
201
- // onClick={handleRemoveThumbnail}
202
- // />
203
- // </Tooltip>
204
- // )}
205
- // </div>
206
- // <div className="backdrop" />
207
- // <div>{contextHolder}</div>
208
- // </>
209
- // )}
210
- // {loading && <Spin className="thumbnail__loading" spinning />}
211
- // </ThumbnailCardWrapper>
212
- // {!!name && (
213
- // <Typography.Text ellipsis={{ tooltip: name }} style={{ maxWidth: '100%' }}>
214
- // {name}
215
- // </Typography.Text>
216
- // )}
217
- // </Flex>
218
- // );
219
- // });
220
33
  export const ThumbnailCard = (props) => {
221
34
  const [modal, contextHolder] = Modal.useModal();
222
35
  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"]);
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  // Libraries
11
- import React, { memo, useEffect, useState } from 'react';
11
+ import React, { memo, useEffect, useRef, useState } from 'react';
12
12
  import { isEmpty } from 'lodash';
13
13
  import i18nInstance from '@antscorp/antsomi-ui/es/locales/i18n';
14
14
  // Components
@@ -44,6 +44,8 @@ export const SavedFilterAndMetrics = memo(props => {
44
44
  const [state, setState] = useState(initialState);
45
45
  // Variables
46
46
  const { searchValue } = state;
47
+ // Refs
48
+ const searchInputRef = useRef();
47
49
  // Memos
48
50
  const savedFilterList = useDeepCompareMemo(() => (list === null || list === void 0 ? void 0 : list.filter(({ name }) => searchStringQuery(name, searchValue))) || [], [list, searchValue]);
49
51
  const { matchedParents, results: filterMetricList } = useDeepCompareMemo(() => recursiveSearchItems({
@@ -55,6 +57,11 @@ export const SavedFilterAndMetrics = memo(props => {
55
57
  // Effects
56
58
  useEffect(() => {
57
59
  setState(initialState);
60
+ // Handle auto focus input search when component is mount
61
+ setTimeout(() => {
62
+ var _a;
63
+ (_a = searchInputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
64
+ }, 200);
58
65
  }, []);
59
66
  // Handlers
60
67
  const renderSavedFilter = () => {
@@ -109,7 +116,7 @@ export const SavedFilterAndMetrics = memo(props => {
109
116
  }), [filterMetricList, onSelectFilterMetric]);
110
117
  const renderFilterMetrics = () => (React.createElement(Menu, { key: matchedParents.map(item => `${item.id}`).join(','), mode: "inline", inlineIndent: 10, defaultOpenKeys: matchedParents.map(item => `${item.id}`), items: filterMetricItems }));
111
118
  return (React.createElement(FilterSelectFieldsContent, null,
112
- React.createElement(Input, { bordered: false, value: searchValue, className: "search-input", autoFocus: true, onAfterChange: value => setState(prev => (Object.assign(Object.assign({}, prev), { searchValue: value }))), suffix: React.createElement(Icon, { type: "icon-ants-search-2", size: 24 }) }),
119
+ React.createElement(Input.CustomSearch, { ref: searchInputRef, value: searchValue, className: "search-input", autoFocus: true, onAfterChange: value => setState(prev => (Object.assign(Object.assign({}, prev), { searchValue: value }))) }),
113
120
  React.createElement(Divider, { style: { borderColor: globalToken === null || globalToken === void 0 ? void 0 : globalToken.bw3, margin: '8px 0 2px 0' } }),
114
121
  isEmpty(savedFilterList) && isEmpty(filterMetricList) ? (React.createElement(EmptyData, { showIcon: false, title: "No data" })) : (React.createElement(Scrollbars, { autoHeight: true, autoHeightMax: 300, autoHide: true },
115
122
  renderSavedFilter(),
@@ -9,7 +9,7 @@ var __rest = (this && this.__rest) || function (s, e) {
9
9
  }
10
10
  return t;
11
11
  };
12
- import React, { useState } from 'react';
12
+ import React, { useRef, useState } from 'react';
13
13
  import styled from 'styled-components';
14
14
  import clsx from 'clsx';
15
15
  // Components
@@ -57,6 +57,8 @@ export const SearchPopover = props => {
57
57
  searchValue: '',
58
58
  isOpenPopover: false,
59
59
  });
60
+ // Refs
61
+ const searchInputRef = useRef();
60
62
  // Variables
61
63
  const { searchValue, isOpenPopover } = state;
62
64
  // Memo
@@ -114,7 +116,7 @@ export const SearchPopover = props => {
114
116
  React.createElement(Scrollbars, { autoHeight: true, autoHeightMax: 200 }, filteredSearchList)));
115
117
  };
116
118
  const content = (React.createElement(StyledContent, null,
117
- React.createElement(Input.CustomSearch, { value: searchValue, placeholder: t(translations.global.search).toString(), onAfterChange: searchValue => {
119
+ React.createElement(Input.CustomSearch, { ref: searchInputRef, autoFocus: true, value: searchValue, placeholder: t(translations.global.search).toString(), onAfterChange: searchValue => {
118
120
  setState(prev => (Object.assign(Object.assign({}, prev), { searchValue })));
119
121
  onSearch(searchValue);
120
122
  }, onPressEnter: e => {
@@ -126,6 +128,13 @@ export const SearchPopover = props => {
126
128
  return (React.createElement(Popover, Object.assign({ open: isOpenPopover, content: content, overlayInnerStyle: { width: 300, padding: 0 }, trigger: ['click'], arrow: false, placement: "bottomRight" }, restProps, { onOpenChange: open => {
127
129
  // Reset search value to empty when close popover
128
130
  setState(prev => (Object.assign(Object.assign(Object.assign({}, prev), { isOpenPopover: open }), (!open && { searchValue: '' }))));
131
+ // Auto focus search input when popover is open
132
+ if (open) {
133
+ setTimeout(() => {
134
+ var _a;
135
+ (_a = searchInputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
136
+ }, 200);
137
+ }
129
138
  // Clear search when close popover
130
139
  if (!open) {
131
140
  onSearch('');
@@ -7,7 +7,7 @@ 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, TThumbnailButton } from '@antscorp/antsomi-ui/es/components/molecules';
10
+ import { MatchesAnyItem, TRemoveModalProps, TThumbnailButton } from '@antscorp/antsomi-ui/es/components/molecules';
11
11
  import { TTemplateItem } from '@antscorp/antsomi-ui/es/components/template';
12
12
  export type TApiGlobal = AxiosRequestConfig<any> & {
13
13
  enabled?: boolean;
@@ -66,7 +66,10 @@ type TGridViewProps<TTableType> = {
66
66
  name?: (record: TTableType) => ReactNode | ReactNode;
67
67
  thumbnail?: (record: TTableType) => string | string;
68
68
  itemProps?: {
69
+ removable?: boolean;
69
70
  showButton?: boolean;
71
+ onRemove?: (record: TTableType) => void;
72
+ removeModalProps?: TRemoveModalProps;
70
73
  buttonProps?: Omit<TThumbnailButton, 'onClick'> & {
71
74
  onClick: (record: TTableType) => void;
72
75
  };
@@ -744,7 +744,13 @@ export function useDataTableListing(props) {
744
744
  loading: isTableListingLoading || isTableListingRefetching,
745
745
  },
746
746
  templateItemProps: {
747
- removable: false,
747
+ removable: gridViewItemProps === null || gridViewItemProps === void 0 ? void 0 : gridViewItemProps.removable,
748
+ removeModalProps: Object.assign(Object.assign({}, gridViewItemProps === null || gridViewItemProps === void 0 ? void 0 : gridViewItemProps.removeModalProps), { onOk: (id) => __awaiter(this, void 0, void 0, function* () {
749
+ 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);
750
+ if ((gridViewItemProps === null || gridViewItemProps === void 0 ? void 0 : gridViewItemProps.onRemove) && record) {
751
+ gridViewItemProps === null || gridViewItemProps === void 0 ? void 0 : gridViewItemProps.onRemove(record);
752
+ }
753
+ }) }),
748
754
  previewBtnProps: {
749
755
  show: false,
750
756
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antscorp/antsomi-ui",
3
- "version": "1.3.5-beta.589",
3
+ "version": "1.3.5-beta.590",
4
4
  "description": "An enterprise-class UI design language and React UI library.",
5
5
  "sideEffects": [
6
6
  "dist/*",