@antscorp/antsomi-ui 1.3.5-beta.989 → 1.3.5-beta.991

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.
@@ -8,8 +8,8 @@ import SelectTag from './SelectTag';
8
8
  import { defaultProps } from './constants';
9
9
  export const SelectAssociatedTag = (props) => {
10
10
  // Props
11
- const { tagConfigs, style, selected, disabled, options, children, onSelect } = props;
11
+ const { tagConfigs, style, status, selected, disabled, options, children, onSelect } = props;
12
12
  const { tag, value } = selected || {};
13
- return (_jsxs(StyledSpace, { className: "select-associated-tag", 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 }))] }));
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
14
  };
15
15
  SelectAssociatedTag.defaultProps = defaultProps;
@@ -13,6 +13,20 @@ export const StyledSpace = styled(Space.Compact) `
13
13
 
14
14
  border-bottom: 1px solid ${globalToken?.blue1};
15
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
+
16
30
  > div:last-child {
17
31
  width: 100%;
18
32
  }
@@ -6,6 +6,7 @@ export type TagItem = {
6
6
  background: CSSProperties['background'];
7
7
  color: CSSProperties['color'];
8
8
  };
9
+ export type Status = 'error' | 'warning' | 'success';
9
10
  export interface TagConfigProps {
10
11
  selectedTag: TagItem['value'];
11
12
  title?: string;
@@ -47,6 +48,11 @@ export interface SelectAssociatedTagProps {
47
48
  * @type {boolean}
48
49
  */
49
50
  disabled?: boolean;
51
+ /**
52
+ * The status of the SelectAssociatedTag, if any.
53
+ * @type {'error' | 'warning' | 'success' }
54
+ */
55
+ status?: Status;
50
56
  /**
51
57
  * A list of selectable options.
52
58
  * @type {SelectOption[]}
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  import type { PayloadInfo } from '@antscorp/antsomi-ui/es/types';
3
2
  export type TDisplayFormat = 'number' | 'percentage' | 'currency' | 'datetime';
4
3
  type DisplayFormatProps = {
@@ -11,6 +11,7 @@ import { RefillUnitType } from './type';
11
11
  // Constants
12
12
  import { CAPITALIZATION_OPTIONS, CHARACTER_ORDER_OPTIONS, CHARACTER_TYPE_OPTIONS, REFILL_UNIT_OPTIONS, SEPARATOR_OPTIONS, } from './constants';
13
13
  import { CodeStructureWrapper } from './styled';
14
+ import { useDebouncedCallbackV2 } from '@antscorp/antsomi-ui/es/hooks';
14
15
  const { Title } = Typography;
15
16
  export const CodeStructure = ({ initialData, onChange }) => {
16
17
  const [form] = Form.useForm();
@@ -33,12 +34,10 @@ export const CodeStructure = ({ initialData, onChange }) => {
33
34
  draft.maxCodes = value;
34
35
  });
35
36
  };
36
- /** *********** ✨ Codeium Command ⭐ ************ */
37
37
  /**
38
38
  * Update the code sample with prefix and suffix
39
39
  * @param {string} value The new value of code sample with prefix and suffix
40
40
  */
41
- /** **** 99b15217-c7a7-4093-8b8f-ea4b4271af48 ****** */
42
41
  const setCodeWithPrefixAndSuffix = (value) => {
43
42
  setState(draft => {
44
43
  draft.codeWithPrefixAndSuffix = value;
@@ -60,36 +59,39 @@ export const CodeStructure = ({ initialData, onChange }) => {
60
59
  draft.refillUnit = value;
61
60
  });
62
61
  }, [setState, setRefillThreshold]);
62
+ const debouncedOnChange = useDebouncedCallbackV2(onChange, 350);
63
63
  const updateFormValues = (data) => {
64
64
  const allValues = form.getFieldsValue();
65
+ const numLetters = form.getFieldValue('alphabetLetters');
66
+ const numDigits = form.getFieldValue('digitalNumbers');
67
+ const type = form.getFieldValue('characterType');
65
68
  form.setFieldsValue(allValues);
66
- const dataOnChange = {
67
- ...allValues,
68
- ...(allValues.refillInterval === 'auto' ? { refillThreshold, refillUnit } : {}),
69
- };
70
- onChange(dataOnChange);
69
+ let totalPredicted = maxCodes;
70
+ const isRelevantChangeMaxCode = Object.keys(data).some(key => key === 'alphabetLetters' || key === 'digitalNumbers' || key === 'characterType');
71
71
  const isRelevantChangeCodeKey = Object.keys(data).some(key => key !== 'quantity' &&
72
72
  key !== 'suffix' &&
73
73
  key !== 'prefix' &&
74
74
  key !== 'refillInterval' &&
75
75
  key !== 'separator');
76
76
  const isChangePrefix = Object.keys(data).some(key => key === 'suffix' || key === 'prefix' || key === 'separator');
77
+ if (isRelevantChangeMaxCode) {
78
+ const total = calculateTotalCodes(numLetters, numDigits, type);
79
+ totalPredicted = total;
80
+ setMaxCodes(total);
81
+ }
77
82
  if (isRelevantChangeCodeKey) {
78
83
  setCodeSample(generateRandomCodeWithConfig(form.getFieldsValue()));
79
84
  }
80
85
  if (isChangePrefix) {
81
86
  setCodeWithPrefixAndSuffix(generateCodeWithPrefixAndSuffix(codeSample, form.getFieldValue('prefix'), form.getFieldValue('suffix'), form.getFieldValue('separator')));
82
87
  }
88
+ const dataOnChange = {
89
+ ...allValues,
90
+ totalPredicted,
91
+ ...(allValues.refillInterval === 'auto' ? { refillThreshold, refillUnit } : {}),
92
+ };
93
+ debouncedOnChange(dataOnChange);
83
94
  };
84
- const computeTotalCodes = useCallback(() => {
85
- const numLetters = form.getFieldValue('alphabetLetters');
86
- const numDigits = form.getFieldValue('digitalNumbers');
87
- const type = form.getFieldValue('characterType');
88
- if (numLetters && numDigits && type) {
89
- const total = calculateTotalCodes(numLetters, numDigits, type);
90
- setMaxCodes(total);
91
- }
92
- }, [form]);
93
95
  // Effects
94
96
  useEffect(() => {
95
97
  setRefillThreshold(initialData.refillThreshold || 0);
@@ -97,13 +99,6 @@ export const CodeStructure = ({ initialData, onChange }) => {
97
99
  useEffect(() => {
98
100
  setRefillUnit(initialData.refillUnit || RefillUnitType.CODES);
99
101
  }, [initialData.refillUnit, setRefillUnit]);
100
- useEffect(() => {
101
- computeTotalCodes();
102
- }, [
103
- form.getFieldValue('alphabetLetters'),
104
- form.getFieldValue('digitalNumbers'),
105
- form.getFieldValue('characterType'),
106
- ]);
107
102
  useEffect(() => {
108
103
  setCodeSample(generateRandomCodeWithConfig(form.getFieldsValue()));
109
104
  setMaxCodes(calculateTotalCodes(form.getFieldValue('alphabetLetters'), form.getFieldValue('digitalNumbers'), form.getFieldValue('characterType')));
@@ -111,7 +106,11 @@ export const CodeStructure = ({ initialData, onChange }) => {
111
106
  useEffect(() => {
112
107
  form.setFieldsValue(initialData);
113
108
  }, [initialData, form]);
114
- return (_jsx(CodeStructureWrapper, { children: _jsxs(Form, { form: form, layout: "horizontal", labelCol: { span: 8 }, colon: false, wrapperCol: { span: 16 }, labelAlign: "left", initialValues: initialData, onValuesChange: updateFormValues, children: [_jsx(Title, { level: 5, children: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE, 'Code Structure') }), _jsx(Form.Item, { label: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_PREFIX, 'Prefix'), name: "prefix", children: _jsx(Input, { placeholder: "" }) }), _jsxs(Row, { children: [_jsx(Col, { span: 8, offset: 0, children: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_INFIX, 'Infix') }), _jsx(Col, { span: 16, offset: 0, children: _jsxs(Flex, { vertical: true, gap: 10, children: [_jsx(Row, { children: _jsx(Col, { offset: 0, children: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_CHAC_TYPE, 'Character Type') }) }), _jsx(Form.Item, { name: "characterType", children: _jsx(Radio.Group, { options: CHARACTER_TYPE_OPTIONS }) })] }) })] }), _jsx(Row, { children: _jsx(Col, { offset: 8, children: _jsxs(Flex, { gap: 10, align: "center", children: [_jsx(Form.Item, { name: "digitalNumbers", children: _jsx(InputNumber, { min: 1, max: 50, style: { width: '40px' } }) }), _jsx("div", { style: { marginBottom: '15px' }, children: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_CHAC_TYPE_DIG_NO, 'digital numbers') })] }) }) }), _jsx(Row, { children: _jsx(Col, { offset: 8, children: _jsxs(Flex, { gap: 10, align: "center", children: [_jsx(Form.Item, { name: "alphabetLetters", children: _jsx(InputNumber, { min: 1, max: 50, style: { width: '40px' } }) }), _jsx("div", { style: { marginBottom: '15px' }, children: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_CHAC_TYPE_LET_NO, 'alphabet letters') })] }) }) }), _jsxs(Flex, { vertical: true, gap: 10, children: [_jsx(Row, { children: _jsx(Col, { offset: 8, children: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_CAP, 'Letters Capitalization') }) }), _jsx(Form.Item, { label: _jsx("span", { children: "\u00A0" }), name: "capitalization", children: _jsx(Radio.Group, { options: CAPITALIZATION_OPTIONS }) })] }), _jsxs(Flex, { vertical: true, gap: 10, children: [_jsx(Row, { children: _jsx(Col, { offset: 8, children: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_CHAC_ORDER, 'Character Order') }) }), _jsx(Form.Item, { label: _jsx("span", { children: "\u00A0" }), name: "characterOrder", children: _jsx(Radio.Group, { options: CHARACTER_ORDER_OPTIONS }) })] }), _jsx(Form.Item, { label: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_SUFFIX, 'Suffix'), name: "suffix", children: _jsx(Input, { placeholder: "" }) }), _jsx(Form.Item, { label: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_SEPARATOR, 'Separator'), name: "separator", children: _jsx(Select, { options: SEPARATOR_OPTIONS, style: { width: '50%' } }) }), _jsxs(Row, { children: [_jsx(Col, { span: 8, children: _jsxs(Flex, { justify: "start", align: "center", gap: 5, children: [translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_QUANTITY, 'Quantity'), ' ', _jsx("span", { style: { color: 'red' }, children: "*" })] }) }), _jsx(Col, { children: _jsxs(Flex, { gap: 10, align: "center", children: [_jsx(Form.Item, { name: "quantity", children: _jsx(InputNumber, { min: 1, max: 10000 }) }), _jsx("div", { style: { marginBottom: '15px' }, children: "code(s) per time" })] }) })] }), _jsxs(Form.Item, { label: translate(translations._ACT_PREVIEW, 'Preview'), children: ["Maximum of ", _jsx("b", { children: maxCodes.toLocaleString() }), " codes (sample", ' ', generateCodeWithPrefixAndSuffix(codeSample, form.getFieldValue('prefix'), form.getFieldValue('suffix'), form.getFieldValue('separator')), ") to be generated"] }), _jsx(Title, { level: 5, children: "Code Refill" }), _jsx(Form.Item, { label: "Refill Interval", name: "refillInterval", children: _jsxs(Radio.Group, { style: { display: 'flex', flexDirection: 'column', gap: '10px' }, onChange: e => {
109
+ return (_jsx(CodeStructureWrapper, { children: _jsxs(Form, { form: form, layout: "horizontal", labelCol: { span: 6 }, colon: false, wrapperCol: { span: 24 }, labelAlign: "left", initialValues: initialData, onValuesChange: updateFormValues, children: [_jsx(Title, { level: 5, children: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE, 'Code Structure') }), _jsx(Form.Item, { label: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_PREFIX, 'Prefix'), name: "prefix", children: _jsx(Input, { placeholder: "", style: {
110
+ maxWidth: 465,
111
+ } }) }), _jsxs(Row, { children: [_jsx(Col, { span: 6, offset: 0, children: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_INFIX, 'Infix') }), _jsx(Col, { span: 16, offset: 0, children: _jsxs(Flex, { vertical: true, gap: 10, children: [_jsx(Row, { children: _jsx(Col, { offset: 0, children: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_CHAC_TYPE, 'Character Type') }) }), _jsx(Form.Item, { name: "characterType", children: _jsx(Radio.Group, { options: CHARACTER_TYPE_OPTIONS }) })] }) })] }), _jsx(Row, { children: _jsx(Col, { offset: 6, children: _jsxs(Flex, { gap: 10, align: "center", children: [_jsx(Form.Item, { name: "digitalNumbers", children: _jsx(InputNumber, { min: 1, max: 50, style: { width: '40px' } }) }), _jsx("div", { style: { marginBottom: '15px' }, children: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_CHAC_TYPE_DIG_NO, 'digital numbers') })] }) }) }), _jsx(Row, { children: _jsx(Col, { offset: 6, children: _jsxs(Flex, { gap: 10, align: "center", children: [_jsx(Form.Item, { name: "alphabetLetters", children: _jsx(InputNumber, { min: 1, max: 50, style: { width: '40px' } }) }), _jsx("div", { style: { marginBottom: '15px' }, children: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_CHAC_TYPE_LET_NO, 'alphabet letters') })] }) }) }), _jsxs(Flex, { vertical: true, gap: 10, children: [_jsx(Row, { children: _jsx(Col, { offset: 6, children: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_CAP, 'Letters Capitalization') }) }), _jsx(Form.Item, { label: _jsx("span", { children: "\u00A0" }), name: "capitalization", children: _jsx(Radio.Group, { options: CAPITALIZATION_OPTIONS }) })] }), _jsxs(Flex, { vertical: true, gap: 10, children: [_jsx(Row, { children: _jsx(Col, { offset: 6, children: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_CHAC_ORDER, 'Character Order') }) }), _jsx(Form.Item, { label: _jsx("span", { children: "\u00A0" }), name: "characterOrder", children: _jsx(Radio.Group, { options: CHARACTER_ORDER_OPTIONS }) })] }), _jsx(Form.Item, { label: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_SUFFIX, 'Suffix'), name: "suffix", children: _jsx(Input, { placeholder: "", style: {
112
+ maxWidth: 465,
113
+ } }) }), _jsx(Form.Item, { label: translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_SEPARATOR, 'Separator'), name: "separator", children: _jsx(Select, { options: SEPARATOR_OPTIONS, style: { width: '180px' } }) }), _jsxs(Row, { children: [_jsx(Col, { span: 6, children: _jsxs(Flex, { justify: "start", align: "center", gap: 5, children: [translate(translations._POOL_RULE_SETTING_CODE_STRUCTURE_QUANTITY, 'Quantity'), ' ', _jsx("span", { style: { color: 'red' }, children: "*" })] }) }), _jsx(Col, { children: _jsxs(Flex, { gap: 10, align: "center", children: [_jsx(Form.Item, { name: "quantity", children: _jsx(InputNumber, { min: 1, max: 10000 }) }), _jsx("div", { style: { marginBottom: '15px' }, children: "code(s) per time" })] }) })] }), _jsxs(Form.Item, { label: translate(translations._ACT_PREVIEW, 'Preview'), children: ["Maximum of ", _jsx("b", { children: maxCodes.toLocaleString() }), " codes (sample", ' ', generateCodeWithPrefixAndSuffix(codeSample, form.getFieldValue('prefix'), form.getFieldValue('suffix'), form.getFieldValue('separator')), ") to be generated"] }), _jsx(Title, { level: 5, children: "Code Refill" }), _jsx(Form.Item, { label: "Refill Interval", name: "refillInterval", children: _jsxs(Radio.Group, { style: { display: 'flex', flexDirection: 'column', gap: '10px' }, onChange: e => {
115
114
  e.preventDefault();
116
115
  }, children: [_jsx(Radio, { value: "manual", children: "Manual refill only" }), _jsx(Radio, { value: "auto", children: _jsxs(Flex, { gap: 10, align: "center", children: [_jsx(Typography.Text, { style: { whiteSpace: 'nowrap' }, children: "Add codes when less than" }), _jsx(InputNumber, { min: refillUnit === RefillUnitType.CODES ? 0 : 1, max: refillUnit === RefillUnitType.PERCENT ? 100 : undefined, style: { width: '63px' }, value: refillThreshold, onChange: value => setRefillThreshold(value || 1) }), _jsx(Select, { onClick: e => e.preventDefault(), value: refillUnit, onChange: setRefillUnit, options: REFILL_UNIT_OPTIONS, style: { width: '63px' } }), "remaining"] }) })] }) })] }) }));
117
116
  };
@@ -3,5 +3,4 @@
3
3
  * Asynchronously loads the component for TemplateListing
4
4
  *
5
5
  */
6
- /// <reference types="react" />
7
6
  export declare const TemplateListing: (props: import("./types").TemplateListingProps<{}>) => JSX.Element;
@@ -25,3 +25,4 @@ export * from './useWindowSize';
25
25
  export * from './useCustomRouter';
26
26
  export * from './useUpdateEffect';
27
27
  export * from './useOutsideClick';
28
+ export * from './useDebouncedCallbackV2';
package/es/hooks/index.js CHANGED
@@ -44,3 +44,4 @@ export * from './useWindowSize';
44
44
  export * from './useCustomRouter';
45
45
  export * from './useUpdateEffect';
46
46
  export * from './useOutsideClick';
47
+ export * from './useDebouncedCallbackV2';
@@ -0,0 +1,3 @@
1
+ type UnaryVoidFunction<T> = (arg: T) => void;
2
+ export declare const useDebouncedCallbackV2: <T>(func: UnaryVoidFunction<T>, wait: number) => (arg: T) => void;
3
+ export {};
@@ -0,0 +1,9 @@
1
+ import { useCallback, useRef } from 'react';
2
+ export const useDebouncedCallbackV2 = (func, wait) => {
3
+ const timeout = useRef();
4
+ const debouncedFunc = (arg) => {
5
+ clearTimeout(timeout.current);
6
+ timeout.current = setTimeout(() => func(arg), wait);
7
+ };
8
+ return useCallback(debouncedFunc, [func, wait]);
9
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antscorp/antsomi-ui",
3
- "version": "1.3.5-beta.989",
3
+ "version": "1.3.5-beta.991",
4
4
  "description": "An enterprise-class UI design language and React UI library.",
5
5
  "sideEffects": [
6
6
  "dist/*",