@antscorp/antsomi-ui 2.0.62 → 2.0.64-staging.1
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.
- package/es/components/atoms/SelectAssociatedTag/SelectAssociatedTag.d.ts +5 -0
- package/es/components/atoms/SelectAssociatedTag/SelectAssociatedTag.js +15 -0
- package/es/components/atoms/SelectAssociatedTag/SelectTag.d.ts +4 -0
- package/es/components/atoms/SelectAssociatedTag/SelectTag.js +26 -0
- package/es/components/atoms/SelectAssociatedTag/constants.d.ts +11 -0
- package/es/components/atoms/SelectAssociatedTag/constants.js +42 -0
- package/es/components/atoms/SelectAssociatedTag/index.d.ts +3 -0
- package/es/components/atoms/SelectAssociatedTag/index.js +2 -0
- package/es/components/atoms/SelectAssociatedTag/styled.d.ts +7 -0
- package/es/components/atoms/SelectAssociatedTag/styled.js +60 -0
- package/es/components/atoms/SelectAssociatedTag/types.d.ts +76 -0
- package/es/components/atoms/SelectAssociatedTag/types.js +1 -0
- package/es/components/atoms/Switch/Switch.js +2 -1
- package/es/components/atoms/index.d.ts +1 -0
- package/es/components/atoms/index.js +1 -0
- package/es/components/molecules/Dropdown/style.scss +6 -4
- package/es/components/molecules/EditingList/EditingList.js +3 -3
- package/es/components/molecules/EditingList/components/Loadable.d.ts +1 -1
- package/es/components/molecules/EditingList/components/Popover/Popover.d.ts +2 -2
- package/es/components/molecules/EditingList/components/Popover/Popover.js +2 -2
- package/es/components/molecules/EditingList/types.d.ts +2 -0
- package/es/components/molecules/InputSelectAttribute/index.d.ts +25 -0
- package/es/components/molecules/InputSelectAttribute/index.js +115 -0
- package/es/components/molecules/InputSelectAttribute/styled.d.ts +14 -0
- package/es/components/molecules/InputSelectAttribute/styled.js +33 -0
- package/es/components/molecules/SearchPopover/components/PopoverSelect/PopoverSelect.js +4 -4
- package/es/components/molecules/SearchPopover/types.d.ts +6 -1
- package/es/components/molecules/SearchPopover/utils.d.ts +2 -2
- package/es/components/molecules/SearchPopover/utils.js +4 -3
- package/es/components/molecules/SelectV2/styled.d.ts +3 -1
- package/es/components/molecules/SelectV2/styled.js +2 -2
- package/es/components/molecules/TagifyInput/TagifyInput.js +169 -77
- package/es/components/molecules/TagifyInput/constants.d.ts +24 -2
- package/es/components/molecules/TagifyInput/constants.js +25 -2
- package/es/components/molecules/TagifyInput/patternHandlers.d.ts +12 -6
- package/es/components/molecules/TagifyInput/patternHandlers.js +88 -43
- package/es/components/molecules/TagifyInput/types.d.ts +24 -3
- package/es/components/molecules/TagifyInput/utils.d.ts +7 -1
- package/es/components/molecules/TagifyInput/utils.js +72 -4
- package/es/components/molecules/TagifyInput/utils.style.js +82 -96
- package/es/components/molecules/index.d.ts +1 -0
- package/es/components/molecules/index.js +1 -0
- package/es/components/organism/TicketEditor/Content.d.ts +2 -1
- package/es/components/organism/TicketEditor/Content.js +10 -38
- package/es/components/organism/TicketEditor/Service.d.ts +5 -0
- package/es/components/organism/TicketEditor/Service.js +11 -0
- package/es/components/organism/TicketEditor/components/Editor/EditorToolbar.d.ts +22 -0
- package/es/components/organism/TicketEditor/components/Editor/EditorToolbar.js +73 -0
- package/es/components/organism/TicketEditor/components/Editor/index.d.ts +10 -0
- package/es/components/organism/TicketEditor/components/Editor/index.js +84 -0
- package/es/components/organism/TicketEditor/index.js +2 -2
- package/es/components/organism/TicketEditor/util.d.ts +1 -1
- package/es/components/organism/TicketEditor/util.js +3 -3
- package/es/components/template/Layout/Layout.js +6 -6
- package/es/locales/ja/google-sheet.json +9 -9
- package/package.json +18 -15
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Components
|
|
3
|
+
import { StyledSpace } from './styled';
|
|
4
|
+
import { Divider } from 'antd';
|
|
5
|
+
import { Select } from '../../molecules';
|
|
6
|
+
import SelectTag from './SelectTag';
|
|
7
|
+
// Constants
|
|
8
|
+
import { defaultProps } from './constants';
|
|
9
|
+
export const SelectAssociatedTag = (props) => {
|
|
10
|
+
// Props
|
|
11
|
+
const { tagConfigs, style, status, selected, disabled, options, children, onSelect } = props;
|
|
12
|
+
const { tag, value } = selected || {};
|
|
13
|
+
return (_jsxs(StyledSpace, { className: `select-associated-tag ${status}`, style: style, children: [_jsx(SelectTag, { ...tagConfigs, selectedTag: tag }), _jsx(Divider, { type: "vertical", style: { margin: '0px 1px 0px 6px' }, className: "antsomi-divider-between-select" }), children ?? (_jsx(Select, { style: { width: '100%', height: '100%' }, value: value, disabled: disabled, options: options, onChange: onSelect }))] }));
|
|
14
|
+
};
|
|
15
|
+
SelectAssociatedTag.defaultProps = defaultProps;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// Libraries
|
|
3
|
+
import { memo, useMemo, useState } from 'react';
|
|
4
|
+
import { keyBy } from 'lodash';
|
|
5
|
+
// Components
|
|
6
|
+
import { Flex, Typography } from 'antd';
|
|
7
|
+
import { Popover } from '../Popover';
|
|
8
|
+
import { SelectedTag } from './styled';
|
|
9
|
+
const SelectTag = (props) => {
|
|
10
|
+
// Props
|
|
11
|
+
const { selectedTag, disabled, title, options, onSelect } = props;
|
|
12
|
+
// State
|
|
13
|
+
const [open, setOpen] = useState(false);
|
|
14
|
+
// Memoized
|
|
15
|
+
const mapOptsMemo = useMemo(() => keyBy(options, 'value'), [options]);
|
|
16
|
+
const selectedItem = useMemo(() => mapOptsMemo?.[selectedTag] || {}, [selectedTag, mapOptsMemo]);
|
|
17
|
+
const handleOpenChange = () => {
|
|
18
|
+
setOpen(!open);
|
|
19
|
+
};
|
|
20
|
+
const handleClick = (item) => {
|
|
21
|
+
setOpen(false);
|
|
22
|
+
onSelect(item);
|
|
23
|
+
};
|
|
24
|
+
return (_jsx(Popover, { open: open && !disabled, title: _jsx(Typography.Text, { style: { fontWeight: '400', maxWidth: 130 }, ellipsis: { tooltip: title }, children: title }), content: _jsx(Flex, { wrap: "wrap", gap: 6, style: { padding: '10px 0px' }, children: options?.map(item => (_jsx(SelectedTag, { "$color": item.color, "$background": item.background, ellipsis: { tooltip: item.label }, onClick: () => handleClick(item), children: item.label }, item.value))) }), placement: "bottomLeft", trigger: "click", overlayInnerStyle: { padding: 10, maxWidth: 150 }, onOpenChange: handleOpenChange, children: _jsx(SelectedTag, { "$color": selectedItem?.color, "$background": selectedItem?.background, ellipsis: { tooltip: selectedItem?.label }, children: selectedItem?.label }) }));
|
|
25
|
+
};
|
|
26
|
+
export default memo(SelectTag);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SelectAssociatedTagProps, TagItem } from './types';
|
|
2
|
+
export declare const DEFAULT_TAGS: {
|
|
3
|
+
readonly RAW: "RAW";
|
|
4
|
+
readonly md5: "md5";
|
|
5
|
+
readonly sha_256: "sha_256";
|
|
6
|
+
readonly MD5: "MD5";
|
|
7
|
+
readonly SHA_256: "SHA_256";
|
|
8
|
+
};
|
|
9
|
+
export declare const DEFAULT_TAGS_OPTS: Record<string, TagItem>;
|
|
10
|
+
export declare const DEFAULT_TAGS_LIST: TagItem[];
|
|
11
|
+
export declare const defaultProps: SelectAssociatedTagProps;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Constants
|
|
2
|
+
import { globalToken } from '@antscorp/antsomi-ui/es/constants';
|
|
3
|
+
// Locales
|
|
4
|
+
import { translations, translate } from '@antscorp/antsomi-locales';
|
|
5
|
+
export const DEFAULT_TAGS = {
|
|
6
|
+
RAW: 'RAW',
|
|
7
|
+
md5: 'md5',
|
|
8
|
+
sha_256: 'sha_256',
|
|
9
|
+
MD5: 'MD5',
|
|
10
|
+
SHA_256: 'SHA_256',
|
|
11
|
+
};
|
|
12
|
+
export const DEFAULT_TAGS_OPTS = {
|
|
13
|
+
RAW: { label: 'RAW', value: DEFAULT_TAGS.RAW, color: globalToken?.bw0, background: '#4CB4C9' },
|
|
14
|
+
md5: { label: 'md5', value: DEFAULT_TAGS.md5, color: globalToken?.bw0, background: '#3B8FDE' },
|
|
15
|
+
sha_256: {
|
|
16
|
+
label: 'sha-256',
|
|
17
|
+
value: DEFAULT_TAGS.sha_256,
|
|
18
|
+
color: globalToken?.bw0,
|
|
19
|
+
background: '#12B800',
|
|
20
|
+
},
|
|
21
|
+
MD5: { label: 'MD5', value: DEFAULT_TAGS.MD5, color: globalToken?.bw0, background: '#3B8FDE' },
|
|
22
|
+
SHA_265: {
|
|
23
|
+
label: 'SHA-256',
|
|
24
|
+
value: DEFAULT_TAGS.SHA_256,
|
|
25
|
+
color: globalToken?.bw0,
|
|
26
|
+
background: '#12B800',
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
export const DEFAULT_TAGS_LIST = Object.values(DEFAULT_TAGS_OPTS);
|
|
30
|
+
export const defaultProps = {
|
|
31
|
+
tagConfigs: {
|
|
32
|
+
options: DEFAULT_TAGS_LIST,
|
|
33
|
+
title: translate(translations._INFO_STORY_WAIT_FOR_HASH, 'Hash Method'),
|
|
34
|
+
onSelect: () => { },
|
|
35
|
+
},
|
|
36
|
+
selected: {
|
|
37
|
+
tag: DEFAULT_TAGS.RAW,
|
|
38
|
+
value: DEFAULT_TAGS.SHA_256,
|
|
39
|
+
},
|
|
40
|
+
options: DEFAULT_TAGS_LIST,
|
|
41
|
+
onSelect: () => { },
|
|
42
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { TagItem } from './types';
|
|
3
|
+
export declare const StyledSpace: import("styled-components").StyledComponent<import("react").FC<import("antd/es/space/Compact").SpaceCompactProps>, any, {}, never>;
|
|
4
|
+
export declare const SelectedTag: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("antd/es/typography/Text").TextProps & import("react").RefAttributes<HTMLSpanElement>>, any, {
|
|
5
|
+
$background: TagItem['background'];
|
|
6
|
+
$color: TagItem['color'];
|
|
7
|
+
}, never>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Libraries
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
// Components
|
|
4
|
+
import { Space } from '../Space';
|
|
5
|
+
import { Typography } from 'antd';
|
|
6
|
+
// Constants
|
|
7
|
+
import { globalToken } from '@antscorp/antsomi-ui/es/constants';
|
|
8
|
+
export const StyledSpace = styled(Space.Compact) `
|
|
9
|
+
width: 100%;
|
|
10
|
+
height: 30px;
|
|
11
|
+
padding-left: 5px;
|
|
12
|
+
align-items: center;
|
|
13
|
+
|
|
14
|
+
border-bottom: 1px solid ${globalToken?.blue1};
|
|
15
|
+
|
|
16
|
+
&.select-associated-tag {
|
|
17
|
+
&.warning {
|
|
18
|
+
border-bottom-color: ${globalToken?.colorWarning};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
&.error {
|
|
22
|
+
border-bottom-color: ${globalToken?.colorError};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
&.success {
|
|
26
|
+
border-bottom-color: ${globalToken?.colorSuccess};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
> div:last-child {
|
|
31
|
+
width: 100%;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.antsomi-divider.antsomi-divider-vertical {
|
|
35
|
+
height: 20px;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.antsomi-select-selector {
|
|
39
|
+
border: none !important;
|
|
40
|
+
}
|
|
41
|
+
`;
|
|
42
|
+
export const SelectedTag = styled(Typography.Text) `
|
|
43
|
+
border-radius: 3px;
|
|
44
|
+
height: 16px;
|
|
45
|
+
line-height: 16px;
|
|
46
|
+
padding-left: 3px;
|
|
47
|
+
padding-right: 3px;
|
|
48
|
+
flex-shrink: 0;
|
|
49
|
+
cursor: pointer;
|
|
50
|
+
|
|
51
|
+
background: ${props => props.$background};
|
|
52
|
+
|
|
53
|
+
&.antsomi-typography {
|
|
54
|
+
color: ${props => props.$color};
|
|
55
|
+
|
|
56
|
+
&.antsomi-typography-ellipsis {
|
|
57
|
+
max-width: 70px;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
`;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Dictionary } from 'lodash';
|
|
2
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
3
|
+
export type TagItem = {
|
|
4
|
+
label: string;
|
|
5
|
+
value: string;
|
|
6
|
+
background: CSSProperties['background'];
|
|
7
|
+
color: CSSProperties['color'];
|
|
8
|
+
};
|
|
9
|
+
export type Status = 'error' | 'warning' | 'success';
|
|
10
|
+
export interface TagConfigProps {
|
|
11
|
+
selectedTag: TagItem['value'];
|
|
12
|
+
title?: string;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
options: TagItem[];
|
|
15
|
+
onSelect: (newItem: TagItem) => void;
|
|
16
|
+
}
|
|
17
|
+
export type SelectOption = {
|
|
18
|
+
label: string;
|
|
19
|
+
value: string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Properties for the SelectAssociatedTag component.
|
|
23
|
+
*/
|
|
24
|
+
export interface SelectAssociatedTagProps {
|
|
25
|
+
/**
|
|
26
|
+
* Configuration properties for tag options, excluding the selected tag.
|
|
27
|
+
* @type {Omit<TagConfigProps, 'selectedTag'>}
|
|
28
|
+
*/
|
|
29
|
+
tagConfigs: Omit<TagConfigProps, 'selectedTag'>;
|
|
30
|
+
/**
|
|
31
|
+
* The currently selected tag and its associated value.
|
|
32
|
+
* @type {{ tag: string; value: string; }}
|
|
33
|
+
*/
|
|
34
|
+
selected: {
|
|
35
|
+
/**
|
|
36
|
+
* The identifier for the selected tag.
|
|
37
|
+
* @type {string}
|
|
38
|
+
*/
|
|
39
|
+
tag: string;
|
|
40
|
+
/**
|
|
41
|
+
* The value associated with the selected tag.
|
|
42
|
+
* @type {Dictionary<SelectOption>}
|
|
43
|
+
*/
|
|
44
|
+
value: Dictionary<SelectOption>;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Whether the SelectAssociatedTag is disabled.
|
|
48
|
+
* @type {boolean}
|
|
49
|
+
*/
|
|
50
|
+
disabled?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* The status of the SelectAssociatedTag, if any.
|
|
53
|
+
* @type {'error' | 'warning' | 'success' }
|
|
54
|
+
*/
|
|
55
|
+
status?: Status;
|
|
56
|
+
/**
|
|
57
|
+
* A list of selectable options.
|
|
58
|
+
* @type {SelectOption[]}
|
|
59
|
+
*/
|
|
60
|
+
options: SelectOption[];
|
|
61
|
+
/**
|
|
62
|
+
* The style object for the SelectAssociatedTag component.
|
|
63
|
+
* @type {CSSProperties}
|
|
64
|
+
*/
|
|
65
|
+
style?: CSSProperties;
|
|
66
|
+
/**
|
|
67
|
+
* The children to be rendered inside the SelectAssociatedTag component.
|
|
68
|
+
* @type {ReactNode}
|
|
69
|
+
*/
|
|
70
|
+
children?: ReactNode;
|
|
71
|
+
/**
|
|
72
|
+
* Callback function called when an option is selected.
|
|
73
|
+
* @type {(value: Dictionary<SelectOption>, option: SelectOption | SelectOption[]) => void}
|
|
74
|
+
*/
|
|
75
|
+
onSelect: (value: Dictionary<SelectOption>, option: SelectOption | SelectOption[]) => void;
|
|
76
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -3,6 +3,7 @@ import { THEME } from '@antscorp/antsomi-ui/es/constants';
|
|
|
3
3
|
import { StyledSwitch } from './styled';
|
|
4
4
|
const Switch = props => {
|
|
5
5
|
const { color = THEME.token?.colorPrimary || '#005eb8', style, ...rest } = props;
|
|
6
|
-
|
|
6
|
+
const validatedColor = CSS.supports('color', color) ? color : THEME.token?.colorPrimary;
|
|
7
|
+
return _jsx(StyledSwitch, { style: { ...style, '--switch-color': validatedColor }, ...rest });
|
|
7
8
|
};
|
|
8
9
|
export { Switch };
|
|
@@ -46,6 +46,7 @@ export * from './RateV2';
|
|
|
46
46
|
export * from './Popover';
|
|
47
47
|
export * from './Iframe';
|
|
48
48
|
export * from './Avatar';
|
|
49
|
+
export * from './SelectAssociatedTag';
|
|
49
50
|
export type { SliderProps } from './Slider';
|
|
50
51
|
export type { PaginationProps } from './Pagination';
|
|
51
52
|
export type { InputDynamicProps } from './InputDynamic';
|
|
@@ -9,15 +9,15 @@ import { Action, List, Search, LazyComponent } from './components';
|
|
|
9
9
|
import { CLS } from './utils';
|
|
10
10
|
const { Popover, Title } = LazyComponent;
|
|
11
11
|
export const EditingList = (props) => {
|
|
12
|
-
const { isLoading = false, addBtnLabel = 'Add', showNum = true, options = [], selected = [], title, removable = true, className, emptyDescription, onChange, } = props;
|
|
12
|
+
const { isLoading = false, addBtnLabel = 'Add', showNum = true, options = [], selected = [], title, removable = true, className, emptyDescription, popoverProps, onChange, } = props;
|
|
13
13
|
const [search, setSearch] = useState('');
|
|
14
14
|
const debounceSearch = useDebounce(search);
|
|
15
15
|
const selectedOptions = useMemo(() => options.filter(opt => selected.includes(opt.key)), [selected, options]);
|
|
16
|
-
const filterdOptions = useMemo(() => selectedOptions.filter(opt => defaultPopoverSelectSearch(opt, debounceSearch)), [selectedOptions, debounceSearch]);
|
|
16
|
+
const filterdOptions = useMemo(() => selectedOptions.filter(opt => defaultPopoverSelectSearch(opt, debounceSearch, popoverProps?.inputSearchProps?.searchConfig)), [selectedOptions, debounceSearch, popoverProps?.inputSearchProps?.searchConfig]);
|
|
17
17
|
const isSelectAll = selectedOptions.length === options.length;
|
|
18
18
|
const handleRemove = (removedKey) => {
|
|
19
19
|
const selectedKeys = selectedOptions.filter(opt => opt.key !== removedKey).map(opt => opt.key);
|
|
20
20
|
onChange?.(selectedKeys);
|
|
21
21
|
};
|
|
22
|
-
return (_jsxs(EditingListRoot, { className: clsx(CLS.Root.default, className), vertical: true, gap: 8, children: [title && (_jsx(Suspense, { children: _jsx(Title, { showNum: showNum, title: title, selectedAmount: selected.length, optionAmount: options.length }) })), _jsx(Search, { onChange: e => setSearch(e.target.value) }), _jsx(List, { isLoading: isLoading, filterdOptions: filterdOptions, emptyDescription: emptyDescription, renderAction: key => (_jsx(Action, { removable: removable, onClickRemove: () => handleRemove(key) })) }), !isSelectAll && !isLoading && (_jsx(Suspense, { children: _jsx(Popover, { options: options, selected: selected, addBtnLabel: addBtnLabel, onChange: onChange }) }))] }));
|
|
22
|
+
return (_jsxs(EditingListRoot, { className: clsx(CLS.Root.default, className), vertical: true, gap: 8, children: [title && (_jsx(Suspense, { children: _jsx(Title, { showNum: showNum, title: title, selectedAmount: selected.length, optionAmount: options.length }) })), _jsx(Search, { onChange: e => setSearch(e.target.value) }), _jsx(List, { isLoading: isLoading, filterdOptions: filterdOptions, emptyDescription: emptyDescription, renderAction: key => (_jsx(Action, { removable: removable, onClickRemove: () => handleRemove(key) })) }), !isSelectAll && !isLoading && (_jsx(Suspense, { children: _jsx(Popover, { options: options, selected: selected, addBtnLabel: addBtnLabel, onChange: onChange, ...popoverProps }) }))] }));
|
|
23
23
|
};
|
|
@@ -10,4 +10,4 @@ export declare const Popover: import("react").LazyExoticComponent<(props: {
|
|
|
10
10
|
selected: string[];
|
|
11
11
|
addBtnLabel: import("react").ReactNode;
|
|
12
12
|
onChange?: ((selected: string[]) => void) | undefined;
|
|
13
|
-
}) => import("react/jsx-runtime").JSX.Element>;
|
|
13
|
+
} & Pick<import("../../SearchPopover/types").PopoverSelectProps, "inputSearchProps">) => import("react/jsx-runtime").JSX.Element>;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import { Option } from '../../types';
|
|
2
|
+
import { EditingListProps, Option } from '../../types';
|
|
3
3
|
type PopoverProps = {
|
|
4
4
|
options: Option[];
|
|
5
5
|
selected: string[];
|
|
6
6
|
addBtnLabel: React.ReactNode;
|
|
7
7
|
onChange?: (selected: string[]) => void;
|
|
8
|
-
};
|
|
8
|
+
} & EditingListProps['popoverProps'];
|
|
9
9
|
export declare const Popover: (props: PopoverProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
10
|
export {};
|
|
@@ -4,6 +4,6 @@ import { PopoverSelect } from '../../../SearchPopover';
|
|
|
4
4
|
import { StyledAddBtn } from '../../styled';
|
|
5
5
|
import { CLS } from '../../utils';
|
|
6
6
|
export const Popover = (props) => {
|
|
7
|
-
const { options, selected, addBtnLabel, onChange } = props;
|
|
8
|
-
return (_jsx(PopoverSelect, { options: options, selected: selected, onApply: onChange, children: _jsxs(StyledAddBtn, { className: CLS.AddButton.default, role: "button", children: [_jsx(AddIcon, {}), addBtnLabel] }) }));
|
|
7
|
+
const { options, selected, addBtnLabel, onChange, ...popoverSearchProps } = props;
|
|
8
|
+
return (_jsx(PopoverSelect, { options: options, selected: selected, onApply: onChange, ...popoverSearchProps, children: _jsxs(StyledAddBtn, { className: CLS.AddButton.default, role: "button", children: [_jsx(AddIcon, {}), addBtnLabel] }) }));
|
|
9
9
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
+
import { PopoverSelectProps } from '../SearchPopover/types';
|
|
2
3
|
export type Option = {
|
|
3
4
|
key: string;
|
|
4
5
|
label: React.ReactNode;
|
|
@@ -14,5 +15,6 @@ export type EditingListProps = {
|
|
|
14
15
|
isLoading?: boolean;
|
|
15
16
|
emptyDescription?: string;
|
|
16
17
|
removable?: boolean;
|
|
18
|
+
popoverProps?: Pick<PopoverSelectProps, 'inputSearchProps'>;
|
|
17
19
|
onChange?: (selected: string[]) => void;
|
|
18
20
|
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export type ValueType = 'input' | 'select';
|
|
3
|
+
type Value = {
|
|
4
|
+
source: string;
|
|
5
|
+
code: any;
|
|
6
|
+
} | string;
|
|
7
|
+
type Option = {
|
|
8
|
+
[key: string]: any;
|
|
9
|
+
label: string;
|
|
10
|
+
value: string;
|
|
11
|
+
};
|
|
12
|
+
export interface InputSelectAttributeProps {
|
|
13
|
+
sourceOptions: Option[];
|
|
14
|
+
mapCodeOptions: Record<string, Option[]>;
|
|
15
|
+
label?: string;
|
|
16
|
+
isErrorTag?: boolean;
|
|
17
|
+
errorMsg?: string;
|
|
18
|
+
value: Value;
|
|
19
|
+
onChange: (newValueData: {
|
|
20
|
+
value: Value;
|
|
21
|
+
valueType: ValueType;
|
|
22
|
+
}) => void;
|
|
23
|
+
}
|
|
24
|
+
declare const _default: import("react").MemoExoticComponent<(props: InputSelectAttributeProps) => import("react/jsx-runtime").JSX.Element>;
|
|
25
|
+
export default _default;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
// Libraries
|
|
3
|
+
import { memo, useCallback, useMemo, useState } from 'react';
|
|
4
|
+
import { get, has, keyBy, upperFirst } from 'lodash';
|
|
5
|
+
import { Flex, Form, Select, Tooltip, Typography } from 'antd';
|
|
6
|
+
// Translations
|
|
7
|
+
import { translate, translations } from '@antscorp/antsomi-ui/es/locales';
|
|
8
|
+
// Components
|
|
9
|
+
import Icon from '@antscorp/icons';
|
|
10
|
+
import { ModalV2 } from '../ModalV2';
|
|
11
|
+
import { StyledTag as Tag } from '@antscorp/antsomi-ui/es/components/molecules/SelectV2/styled';
|
|
12
|
+
import { StyledSelect } from './styled';
|
|
13
|
+
import { EmptyData } from '../EmptyData';
|
|
14
|
+
import { Dashboard30Icon, ErrorIcon } from '../../icons';
|
|
15
|
+
// Constants
|
|
16
|
+
import { THEME } from '@antscorp/antsomi-ui/es/constants';
|
|
17
|
+
import { TAG_TYPE } from '../TagifyInput';
|
|
18
|
+
const InputSelectAttribute = (props) => {
|
|
19
|
+
const { value, errorMsg, label, isErrorTag, sourceOptions = [], mapCodeOptions = {}, onChange, } = props;
|
|
20
|
+
const [form] = Form.useForm();
|
|
21
|
+
const sourceValue = Form.useWatch('source', form);
|
|
22
|
+
// States
|
|
23
|
+
const [openModal, setOpenModal] = useState(false);
|
|
24
|
+
const codeOptions = useMemo(() => {
|
|
25
|
+
if (sourceValue) {
|
|
26
|
+
return get(mapCodeOptions, sourceValue, []);
|
|
27
|
+
}
|
|
28
|
+
return [];
|
|
29
|
+
}, [sourceValue, mapCodeOptions]);
|
|
30
|
+
const initCodeTitleField = useMemo(() => {
|
|
31
|
+
if (sourceValue === TAG_TYPE.PROMOTION_CODE) {
|
|
32
|
+
return 'Allocated Code';
|
|
33
|
+
}
|
|
34
|
+
return upperFirst(translate(translations._ITEM_NAME_ATTRIBUTE, 'attribute'));
|
|
35
|
+
}, [sourceValue]);
|
|
36
|
+
const mapCodeBySource = useMemo(() => {
|
|
37
|
+
if (typeof value === 'string')
|
|
38
|
+
return {};
|
|
39
|
+
return keyBy(get(mapCodeOptions, value?.source, []), 'value');
|
|
40
|
+
}, [mapCodeOptions, value]);
|
|
41
|
+
const getCodeDefaultBySource = useCallback((source) => get(mapCodeOptions, [source, '0', 'value'], ''), [mapCodeOptions]);
|
|
42
|
+
const onOpenModal = useCallback(() => {
|
|
43
|
+
if (value && typeof value !== 'string') {
|
|
44
|
+
const isExist = has(mapCodeBySource, [value?.code, 'label']);
|
|
45
|
+
form.setFieldsValue({ source: value?.source, code: isExist ? value?.code : undefined });
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
const source = sourceOptions[0]?.value || '';
|
|
49
|
+
const code = getCodeDefaultBySource(source);
|
|
50
|
+
form.setFieldsValue({ source, code });
|
|
51
|
+
}
|
|
52
|
+
setOpenModal(true);
|
|
53
|
+
}, [value, mapCodeBySource, form, sourceOptions, getCodeDefaultBySource]);
|
|
54
|
+
const onDeselect = useCallback(() => {
|
|
55
|
+
onChange({ value: '', valueType: 'input' });
|
|
56
|
+
}, [onChange]);
|
|
57
|
+
const onHideModal = useCallback(() => {
|
|
58
|
+
setOpenModal(false);
|
|
59
|
+
}, []);
|
|
60
|
+
const onAfterClose = useCallback(() => {
|
|
61
|
+
form.resetFields();
|
|
62
|
+
}, [form]);
|
|
63
|
+
const onOk = async () => {
|
|
64
|
+
try {
|
|
65
|
+
// Validate form fields before getting values
|
|
66
|
+
const values = await form.validateFields();
|
|
67
|
+
if (typeof values !== 'string') {
|
|
68
|
+
const newValue = {
|
|
69
|
+
source: values?.source,
|
|
70
|
+
code: values?.code,
|
|
71
|
+
};
|
|
72
|
+
onChange({ value: newValue, valueType: 'select' });
|
|
73
|
+
}
|
|
74
|
+
setOpenModal(false);
|
|
75
|
+
}
|
|
76
|
+
catch (errorInfo) {
|
|
77
|
+
// eslint-disable-next-line no-console
|
|
78
|
+
console.error('Validation Failed:', errorInfo);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const onChangeInput = useCallback((val) => {
|
|
82
|
+
onChange({ value: val, valueType: 'input' });
|
|
83
|
+
}, [onChange]);
|
|
84
|
+
const onValuesChange = useCallback((changedValues) => {
|
|
85
|
+
// If source changed -> set new code based on new source
|
|
86
|
+
if (changedValues?.source) {
|
|
87
|
+
const newCode = getCodeDefaultBySource(changedValues.source);
|
|
88
|
+
form.setFieldValue('code', newCode);
|
|
89
|
+
}
|
|
90
|
+
}, [form, getCodeDefaultBySource]);
|
|
91
|
+
const renderInput = () => {
|
|
92
|
+
let element = null;
|
|
93
|
+
const isObjValue = value && typeof value !== 'string';
|
|
94
|
+
if (openModal || isObjValue) {
|
|
95
|
+
element = (_jsxs("div", { style: {
|
|
96
|
+
display: 'flex',
|
|
97
|
+
alignItems: 'center',
|
|
98
|
+
justifyContent: 'space-between',
|
|
99
|
+
height: 32,
|
|
100
|
+
padding: '4px 12px 4px 4px',
|
|
101
|
+
borderBottom: `1px solid ${errorMsg ? THEME.token?.colorError : THEME.token?.blue1}`,
|
|
102
|
+
}, children: [_jsx("div", { style: { width: '100%', cursor: 'pointer' }, onClick: onOpenModal, children: isObjValue && (_jsx(Tag, { isError: isErrorTag, children: isErrorTag ? (_jsxs(Flex, { gap: 5, align: "center", children: ["Unknown", _jsx(Tooltip, { title: "The used dynamic content is removed", children: _jsx(ErrorIcon, { size: 16 }) })] })) : (_jsx(Typography.Text, { ellipsis: {
|
|
103
|
+
tooltip: get(mapCodeBySource, [value?.code, 'label'], value?.code),
|
|
104
|
+
}, style: { maxWidth: 150 }, children: get(mapCodeBySource, [value?.code, 'label'], value?.code) })) })) }), _jsx(Icon, { type: "icon-ants-remove", style: { fontSize: 10, color: '#222', cursor: 'pointer' }, onClick: onDeselect })] }));
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
element = (_jsx(StyledSelect, { mode: "multiple", options: [{ value: '', label: 'Or select a field' }], notFoundContent: null, onSelect: onOpenModal, style: { width: '100%', borderTop: 'none', borderLeft: 'none', borderRight: 'none' }, onDeselect: onDeselect, autoClearSearchValue: false, searchValue: typeof value === 'string' ? value : '', onSearch: onChangeInput, status: errorMsg ? 'error' : undefined, placeholder: typeof value === 'string' ? value : translate(translations.inputYourValue.title), "$isPlaceholder": !value, "$isError": !!errorMsg, dropdownStyle: {
|
|
108
|
+
...(openModal ? { display: 'none' } : {}),
|
|
109
|
+
} }));
|
|
110
|
+
}
|
|
111
|
+
return element;
|
|
112
|
+
};
|
|
113
|
+
return (_jsxs(_Fragment, { children: [renderInput(), errorMsg ? (_jsx(Typography.Text, { style: { marginLeft: 8, color: THEME.token?.red8, marginTop: 5 }, children: errorMsg })) : null, _jsx(ModalV2, { title: translate(translations._PREDICT_MODEL_SELECT_ATTRIBUTE, 'Select attribute'), okText: translate(translations._ACT_APPLY, 'Apply'), open: openModal, onOk: onOk, onCancel: onHideModal, afterClose: onAfterClose, destroyOnClose: true, centered: true, children: _jsxs(Form, { colon: false, form: form, onValuesChange: onValuesChange, children: [_jsx(Form.Item, { label: translate(translations._TITL_PERSONALIZATION_TYPE, 'Content Source'), name: "source", required: true, labelCol: { span: 6 }, labelAlign: "left", rules: [{ required: true, message: 'Please select field!' }], children: _jsx(Select, { suffixIcon: _jsx(Icon, { type: "icon-ants-expand-more", style: { fontSize: '20px', color: THEME.token?.colorIcon } }), options: sourceOptions, placeholder: "Please select an item" }) }), _jsx(Form.Item, { label: label || initCodeTitleField, required: true, labelCol: { span: 6 }, labelAlign: "left", name: "code", rules: [{ required: true, message: 'Please select field!' }], children: _jsx(Select, { suffixIcon: _jsx(Icon, { type: "icon-ants-expand-more", style: { fontSize: '20px', color: THEME.token?.colorIcon } }), notFoundContent: _jsx(EmptyData, { size: "small", icon: _jsx(Dashboard30Icon, {}), description: "No personalized content in this journey" }), placeholder: "Please select an item", options: codeOptions }) })] }) })] }));
|
|
114
|
+
};
|
|
115
|
+
export default memo(InputSelectAttribute);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const StyledSelect: import("styled-components").StyledComponent<{
|
|
2
|
+
(props: import("@antscorp/antsomi-ui/es/components/molecules").SelectV2Props): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
defaultProps: {
|
|
4
|
+
suffixIcon: import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
filterOption: (input: any, option: any) => boolean;
|
|
6
|
+
tagRender: (props: any) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
containerStyle: {};
|
|
8
|
+
labelStyle: {};
|
|
9
|
+
clearIcon: import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
};
|
|
11
|
+
}, any, {
|
|
12
|
+
$isPlaceholder?: any;
|
|
13
|
+
$isError?: boolean | undefined;
|
|
14
|
+
}, never>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Libraries
|
|
2
|
+
import styled, { css } from 'styled-components';
|
|
3
|
+
// Components
|
|
4
|
+
import { SelectV2 as Select } from '@antscorp/antsomi-ui/es/components/molecules';
|
|
5
|
+
// Constants
|
|
6
|
+
import { THEME } from '@antscorp/antsomi-ui/es/constants';
|
|
7
|
+
export const StyledSelect = styled(Select) `
|
|
8
|
+
.antsomi-select-selection-overflow .antsomi-select-selection-overflow-item {
|
|
9
|
+
flex: 1;
|
|
10
|
+
|
|
11
|
+
.antsomi-select-selection-search {
|
|
12
|
+
width: fit-content !important;
|
|
13
|
+
flex: 1;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
${({ $isError }) => $isError
|
|
18
|
+
? css `
|
|
19
|
+
.antsomi-select-selector {
|
|
20
|
+
box-shadow: none !important;
|
|
21
|
+
}
|
|
22
|
+
`
|
|
23
|
+
: css ``}
|
|
24
|
+
|
|
25
|
+
.antsomi-select-selection-placeholder {
|
|
26
|
+
${props => !props.$isPlaceholder
|
|
27
|
+
? css `
|
|
28
|
+
color: rgba(0, 0, 0, 0.85);
|
|
29
|
+
font-size: ${THEME.token?.fontSize}px;
|
|
30
|
+
`
|
|
31
|
+
: css ``}
|
|
32
|
+
}
|
|
33
|
+
`;
|
|
@@ -15,7 +15,7 @@ export const PopoverSelect = (props) => {
|
|
|
15
15
|
const { open: openProp, selected, options: optionsProp = [], inputSearchProps = {}, children, showAllLabel = 'Show all', showSelectedLabel = 'Show selected', selectAllLabel = 'Select all', deselectAllLabel = 'Unselect all', menuProps = {}, isAllowEmpty = false, onCancel, onApply, onSearchPredicate, ...rest } = props;
|
|
16
16
|
const itemSize = menuProps.itemSize || ITEM_SIZE;
|
|
17
17
|
const itemSpacing = menuProps.itemSpacing || ITEM_SPACING;
|
|
18
|
-
const { value: searchValue, ...restInputSearchProps } = inputSearchProps;
|
|
18
|
+
const { value: searchValue, searchConfig, ...restInputSearchProps } = inputSearchProps;
|
|
19
19
|
const refOnSearchPredicate = useRef(onSearchPredicate);
|
|
20
20
|
useEffect(() => {
|
|
21
21
|
refOnSearchPredicate.current = onSearchPredicate;
|
|
@@ -46,15 +46,15 @@ export const PopoverSelect = (props) => {
|
|
|
46
46
|
const filteredOptions = useMemo(() => {
|
|
47
47
|
let result = options.filter(field => {
|
|
48
48
|
if (!refOnSearchPredicate.current) {
|
|
49
|
-
return defaultSearch(field, search);
|
|
49
|
+
return defaultSearch(field, search, searchConfig);
|
|
50
50
|
}
|
|
51
|
-
return refOnSearchPredicate.current(field) || defaultSearch(field, search);
|
|
51
|
+
return refOnSearchPredicate.current(field) || defaultSearch(field, search, searchConfig);
|
|
52
52
|
});
|
|
53
53
|
if (showSelected) {
|
|
54
54
|
result = result.filter(field => selectedKeys.has(field.key));
|
|
55
55
|
}
|
|
56
56
|
return result;
|
|
57
|
-
}, [options, search, showSelected, selectedKeys]);
|
|
57
|
+
}, [options, search, showSelected, selectedKeys, searchConfig]);
|
|
58
58
|
const handleToggleField = (field, checked) => {
|
|
59
59
|
const newSelectedKeys = new Set(selectedKeys);
|
|
60
60
|
if (checked) {
|
|
@@ -2,8 +2,13 @@ import { PopoverProps } from 'antd';
|
|
|
2
2
|
import { InputProps } from '../../atoms/Input';
|
|
3
3
|
import React, { PropsWithChildren } from 'react';
|
|
4
4
|
import { MenuInlineProps } from '../VirtualizedMenu/types';
|
|
5
|
+
export type SearchConfig = {
|
|
6
|
+
searchWithKey?: boolean;
|
|
7
|
+
};
|
|
5
8
|
export type SearchPopoverProps = PropsWithChildren<{
|
|
6
|
-
inputSearchProps?: InputProps
|
|
9
|
+
inputSearchProps?: InputProps & {
|
|
10
|
+
searchConfig?: SearchConfig;
|
|
11
|
+
};
|
|
7
12
|
isAllowEmpty?: boolean;
|
|
8
13
|
} & PopoverProps>;
|
|
9
14
|
export type Option = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Option } from './types';
|
|
2
|
-
export declare const defaultSearch: (opt: Option, search: string) => boolean;
|
|
1
|
+
import { Option, SearchConfig } from './types';
|
|
2
|
+
export declare const defaultSearch: (opt: Option, search: string, config?: SearchConfig) => boolean;
|
|
3
3
|
export declare const calDefaultListHeightInPopover: (params: {
|
|
4
4
|
listLength: number;
|
|
5
5
|
itemSize: number;
|