@omniumretail/component-library 1.0.60 → 1.0.62
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/dist/bundle.js +8 -19
- package/dist/main.css +14 -0
- package/dist/types/components/InputCountryCode/index.d.ts +3 -1
- package/dist/types/components/ModalWithTable/index.d.ts +1 -0
- package/dist/types/components/Tag/index.d.ts +4 -2
- package/dist/types/components/Upload/index.d.ts +1 -0
- package/package.json +1 -1
- package/src/components/InputCountryCode/index.tsx +37 -27
- package/src/components/InputCountryCode/inputCountryCode.stories.tsx +26 -4
- package/src/components/ModalWithTable/ModalWithTable.stories.tsx +1 -1
- package/src/components/ModalWithTable/index.tsx +17 -4
- package/src/components/Tag/Tag.stories.tsx +4 -1
- package/src/components/Tag/index.tsx +86 -11
- package/src/components/Tag/styles.module.scss +17 -0
- package/src/components/Upload/Upload.stories.tsx +1 -1
- package/src/components/Upload/index.tsx +21 -22
- package/src/locales/en.json +2 -1
- package/src/locales/es.json +2 -1
- package/src/locales/pt.json +2 -1
package/dist/main.css
CHANGED
|
@@ -280,6 +280,20 @@
|
|
|
280
280
|
.Hfh5KLg4Y_g44Ajhx9aV .anticon-close:hover {
|
|
281
281
|
color: var(--color-black);
|
|
282
282
|
}
|
|
283
|
+
.yhGDUJJiYhqjPCJgNdjI .Gj9zvBh4toFNL6uoWOIk {
|
|
284
|
+
display: flex;
|
|
285
|
+
gap: 12px;
|
|
286
|
+
}
|
|
287
|
+
.yhGDUJJiYhqjPCJgNdjI .BvTiplJPlDM4ob_yobaL {
|
|
288
|
+
display: flex;
|
|
289
|
+
flex-direction: row;
|
|
290
|
+
gap: 12px;
|
|
291
|
+
font-family: "SilkaBold";
|
|
292
|
+
text-decoration: underline;
|
|
293
|
+
}
|
|
294
|
+
.yhGDUJJiYhqjPCJgNdjI .BvTiplJPlDM4ob_yobaL div {
|
|
295
|
+
cursor: pointer;
|
|
296
|
+
}
|
|
283
297
|
/*!*******************************************************************************************************************************************************************!*\
|
|
284
298
|
!*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/sass-loader/dist/cjs.js!./src/components/DatePicker/styles.module.scss ***!
|
|
285
299
|
\*******************************************************************************************************************************************************************/
|
|
@@ -4,5 +4,7 @@ export interface FormInputCountryCodeProps extends Omit<FormItemProps, "name"> {
|
|
|
4
4
|
selectProps?: SelectProps;
|
|
5
5
|
inputProps?: InputProps;
|
|
6
6
|
inputWithSelectBoxValue?: string;
|
|
7
|
+
value?: string;
|
|
8
|
+
onChange?: (value: any) => void;
|
|
7
9
|
}
|
|
8
|
-
export declare const InputCountryCode: ({ inputProps, selectProps, name, inputWithSelectBoxValue, ...itemProps }: FormInputCountryCodeProps) => JSX.Element;
|
|
10
|
+
export declare const InputCountryCode: ({ inputProps, selectProps, name, inputWithSelectBoxValue, value, onChange, ...itemProps }: FormInputCountryCodeProps) => JSX.Element;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { TagProps } from 'antd';
|
|
2
2
|
export interface customTagProps extends TagProps {
|
|
3
|
-
customTags?:
|
|
4
|
-
tagsInfo?:
|
|
3
|
+
customTags?: string[];
|
|
4
|
+
tagsInfo?: (tags: string[]) => void;
|
|
5
|
+
advancedTagsInfo?: (tags: string[]) => void;
|
|
6
|
+
advancedTags?: string[];
|
|
5
7
|
}
|
|
6
8
|
export declare const TagField: (props: customTagProps) => JSX.Element;
|
|
@@ -2,6 +2,7 @@ import type { UploadFile, UploadProps } from 'antd/es/upload/interface';
|
|
|
2
2
|
interface UploadPropsExtended extends UploadProps {
|
|
3
3
|
onImageChange?: (file: UploadFile | null) => void;
|
|
4
4
|
initialFileList?: UploadFile[];
|
|
5
|
+
initialImageUrl?: string;
|
|
5
6
|
}
|
|
6
7
|
export declare const Upload: (props: UploadPropsExtended) => JSX.Element;
|
|
7
8
|
export {};
|
package/package.json
CHANGED
|
@@ -9,57 +9,67 @@ export interface FormInputCountryCodeProps extends Omit<FormItemProps, "name"> {
|
|
|
9
9
|
selectProps?: SelectProps;
|
|
10
10
|
inputProps?: InputProps;
|
|
11
11
|
inputWithSelectBoxValue?: string;
|
|
12
|
+
value?: string;
|
|
13
|
+
onChange?: (value: any) => void;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
interface CountryCodeProps {
|
|
15
|
-
value?: string;
|
|
16
|
-
onChange?: (value:
|
|
17
|
+
value?: string | { Number: string; CountryISO2: string };
|
|
18
|
+
onChange?: (value: any) => void;
|
|
17
19
|
selectProps?: SelectProps;
|
|
18
20
|
inputProps?: InputProps;
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
const CountryCode = ({ value, onChange, selectProps, inputProps }: CountryCodeProps) => {
|
|
22
|
-
const[inputDefaultValue, setInputDefaultValue] = useState<any>(inputProps?.defaultValue);
|
|
24
|
+
const [inputDefaultValue, setInputDefaultValue] = useState<any>(inputProps?.defaultValue);
|
|
25
|
+
const [countryCode, setCountryCode] = useState(selectProps?.defaultValue);
|
|
23
26
|
|
|
24
|
-
useEffect(()=> {
|
|
27
|
+
useEffect(() => {
|
|
25
28
|
setInputDefaultValue(inputProps?.defaultValue);
|
|
26
|
-
}, [])
|
|
29
|
+
}, []);
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const phoneNumber = value?.replace(validCountryCode as string || "", "") || "";
|
|
33
|
-
const changeLocalValue = useCallback((value: string | number, element: string) => {
|
|
34
|
-
if(element !== 'countryCode') {
|
|
35
|
-
setInputDefaultValue(value);
|
|
36
|
-
onChange?.(`${validCountryCode}${value}` || "");
|
|
37
|
-
return;
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (value && typeof value === 'object') {
|
|
33
|
+
setInputDefaultValue(value.Number);
|
|
34
|
+
setCountryCode(value.CountryISO2);
|
|
38
35
|
}
|
|
36
|
+
}, [value]);
|
|
39
37
|
|
|
40
|
-
|
|
38
|
+
const changeLocalValue = useCallback(
|
|
39
|
+
(value: string | number, element: string) => {
|
|
40
|
+
if (element !== 'countryCode') {
|
|
41
|
+
setInputDefaultValue(value);
|
|
42
|
+
onChange?.({ Number: value, CountryISO2: countryCode }); // Update this line
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
41
45
|
|
|
42
|
-
|
|
43
|
-
|
|
46
|
+
setCountryCode(value);
|
|
47
|
+
onChange?.({ Number: inputDefaultValue, CountryISO2: value }); // Update this line
|
|
48
|
+
},
|
|
49
|
+
[onChange, countryCode, inputDefaultValue],
|
|
50
|
+
);
|
|
44
51
|
|
|
45
52
|
return (
|
|
46
53
|
<Input.Group compact className={styles.inputGroup}>
|
|
47
54
|
<Select
|
|
48
55
|
{...selectProps}
|
|
49
|
-
value={
|
|
56
|
+
value={countryCode || selectProps?.defaultValue}
|
|
50
57
|
onChange={(value) => changeLocalValue(value, 'countryCode')}
|
|
51
|
-
>
|
|
52
|
-
|
|
53
|
-
|
|
58
|
+
></Select>
|
|
59
|
+
<InputField
|
|
60
|
+
{...inputProps}
|
|
61
|
+
value={inputDefaultValue}
|
|
62
|
+
onChange={(event) => changeLocalValue(event.target.value, 'phoneNumber')}
|
|
63
|
+
/>
|
|
54
64
|
</Input.Group>
|
|
55
|
-
)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export const InputCountryCode = ({ inputProps, selectProps, name, inputWithSelectBoxValue, ...itemProps}: FormInputCountryCodeProps) => {
|
|
65
|
+
);
|
|
66
|
+
};
|
|
59
67
|
|
|
68
|
+
export const InputCountryCode = ({ inputProps, selectProps, name, inputWithSelectBoxValue, value, onChange, ...itemProps }: FormInputCountryCodeProps) => {
|
|
60
69
|
return (
|
|
61
70
|
<Form.Item name={name} {...itemProps}>
|
|
62
|
-
<CountryCode inputProps={inputProps} selectProps={selectProps} />
|
|
71
|
+
<CountryCode inputProps={inputProps} selectProps={selectProps} value={value} onChange={onChange} />
|
|
63
72
|
</Form.Item>
|
|
64
73
|
)
|
|
65
74
|
}
|
|
75
|
+
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Form
|
|
1
|
+
import { Form, Button } from 'antd';
|
|
2
2
|
import { Meta, Story } from "@storybook/react";
|
|
3
3
|
import { InputCountryCode, FormInputCountryCodeProps } from '.';
|
|
4
4
|
|
|
@@ -7,9 +7,31 @@ export default {
|
|
|
7
7
|
component: InputCountryCode,
|
|
8
8
|
} as Meta;
|
|
9
9
|
|
|
10
|
-
const Template: Story<FormInputCountryCodeProps> = (args) =>
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
const Template: Story<FormInputCountryCodeProps> = (args) => {
|
|
11
|
+
return (
|
|
12
|
+
<Form>
|
|
13
|
+
<InputCountryCode {...args}></InputCountryCode>
|
|
14
|
+
|
|
15
|
+
<Form.Item name={["testitem"]}>
|
|
16
|
+
<InputCountryCode
|
|
17
|
+
selectProps={{
|
|
18
|
+
options: [
|
|
19
|
+
{
|
|
20
|
+
label: 'PT',
|
|
21
|
+
value: '+351',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
label: 'KZ',
|
|
25
|
+
value: '94',
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
defaultValue: 'KZ',
|
|
29
|
+
}} inputProps={{ defaultValue: '919767347' }} />
|
|
30
|
+
</Form.Item>
|
|
31
|
+
|
|
32
|
+
</Form>
|
|
33
|
+
)
|
|
34
|
+
};
|
|
13
35
|
|
|
14
36
|
export const Primary = Template.bind({});
|
|
15
37
|
Primary.args = {
|
|
@@ -84,7 +84,7 @@ const Template: Story<ModalWithTableProps> = (args) => {
|
|
|
84
84
|
return (
|
|
85
85
|
<>
|
|
86
86
|
<button onClick={() => onClickMe()}> Button </button>
|
|
87
|
-
<ModalWithTable {...args} modalData={setModalData} isLoading={isFetching} tableData={data} isOpen={isModalOpen}></ModalWithTable>
|
|
87
|
+
<ModalWithTable {...args} modalData={setModalData} isLoading={isFetching} tableData={data} isOpen={isModalOpen} advancedTagsList={['Country', 'County']}></ModalWithTable>
|
|
88
88
|
</>
|
|
89
89
|
);
|
|
90
90
|
}
|
|
@@ -16,6 +16,8 @@ export interface ModalWithTableProps {
|
|
|
16
16
|
isLoading?: boolean;
|
|
17
17
|
confirmLoading?: boolean;
|
|
18
18
|
initialRowSelectedInfo?: any;
|
|
19
|
+
// Tags List for advanced search
|
|
20
|
+
advancedTagsList?: string[];
|
|
19
21
|
}
|
|
20
22
|
function objectsAreEqual(obj1: any, obj2: any) {
|
|
21
23
|
const keys1 = Object.keys(obj1);
|
|
@@ -46,7 +48,8 @@ export const ModalWithTable = (props: ModalWithTableProps) => {
|
|
|
46
48
|
tableData,
|
|
47
49
|
modalData,
|
|
48
50
|
isLoading,
|
|
49
|
-
initialRowSelectedInfo
|
|
51
|
+
initialRowSelectedInfo,
|
|
52
|
+
advancedTagsList
|
|
50
53
|
} = props;
|
|
51
54
|
|
|
52
55
|
const prevIsOpenRef = useRef<boolean>();
|
|
@@ -60,6 +63,7 @@ export const ModalWithTable = (props: ModalWithTableProps) => {
|
|
|
60
63
|
pageInfo: {},
|
|
61
64
|
rowSelectionInfo: [],
|
|
62
65
|
tagsInfo: [],
|
|
66
|
+
advancedTagsInfo: [],
|
|
63
67
|
selectedData: [],
|
|
64
68
|
});
|
|
65
69
|
const pageBase = { currentPage: 1 };
|
|
@@ -68,6 +72,7 @@ export const ModalWithTable = (props: ModalWithTableProps) => {
|
|
|
68
72
|
const [pageInfo, setPageInfo] = useState<any>(pageBase);
|
|
69
73
|
const [rowSelectionInfo, setRowSelectionInfo] = useState<any>(undefined);
|
|
70
74
|
const [tagsInfo, setTagsInfo] = useState<any>([]);
|
|
75
|
+
const [advancedTagsInfo, setAdvancedTagsInfo] = useState<any>([]);
|
|
71
76
|
const [selectedData, setSelectedData] = useState<any>([]);
|
|
72
77
|
|
|
73
78
|
useEffect(() => {
|
|
@@ -78,6 +83,7 @@ export const ModalWithTable = (props: ModalWithTableProps) => {
|
|
|
78
83
|
pageInfo: pageInfo,
|
|
79
84
|
rowSelectionInfo: rowSelectionInfo,
|
|
80
85
|
tagsInfo: tagsInfo,
|
|
86
|
+
advancedTagsInfo: advancedTagsInfo,
|
|
81
87
|
selectedData: selectedData,
|
|
82
88
|
});
|
|
83
89
|
}
|
|
@@ -92,12 +98,12 @@ export const ModalWithTable = (props: ModalWithTableProps) => {
|
|
|
92
98
|
setPageInfo(initialValues.pageInfo);
|
|
93
99
|
setRowSelectionInfo(initialValues.rowSelectionInfo);
|
|
94
100
|
setTagsInfo(initialValues.tagsInfo);
|
|
101
|
+
setAdvancedTagsInfo(initialValues.advancedTagsInfo)
|
|
95
102
|
setSelectedData(initialValues.selectedData);
|
|
96
103
|
};
|
|
97
104
|
|
|
98
105
|
const saveChanges = () => {
|
|
99
106
|
setOpen(false);
|
|
100
|
-
|
|
101
107
|
if (tableData?.rowSelection?.type === 'radio') {
|
|
102
108
|
setSelectedData([selectedData[selectedData.length - 1]]);
|
|
103
109
|
}
|
|
@@ -112,12 +118,13 @@ export const ModalWithTable = (props: ModalWithTableProps) => {
|
|
|
112
118
|
pageInfo: pageInfo,
|
|
113
119
|
rowSelectionInfo: rowSelectionInfo,
|
|
114
120
|
tagsInfo: tagsInfo,
|
|
121
|
+
advancedTagsInfo: advancedTagsInfo,
|
|
115
122
|
open: open,
|
|
116
123
|
selectedData: selectedData,
|
|
117
124
|
};
|
|
118
125
|
|
|
119
126
|
modalData(modalDataObj);
|
|
120
|
-
}, [tagsInfo, open, rowSelectionInfo, selectedData]);
|
|
127
|
+
}, [tagsInfo, advancedTagsInfo, open, rowSelectionInfo, selectedData]);
|
|
121
128
|
|
|
122
129
|
useEffect(() => {
|
|
123
130
|
const selectedRowKeys = rowSelectionInfo || tableData.rowSelection.selectedRowKeys;
|
|
@@ -172,6 +179,12 @@ export const ModalWithTable = (props: ModalWithTableProps) => {
|
|
|
172
179
|
}
|
|
173
180
|
}, [tagsInfo]);
|
|
174
181
|
|
|
182
|
+
useEffect(() => {
|
|
183
|
+
if (advancedTagsInfo.length > 0) {
|
|
184
|
+
setConfirmLoading(true);
|
|
185
|
+
}
|
|
186
|
+
}, [advancedTagsInfo]);
|
|
187
|
+
|
|
175
188
|
useEffect(() => {
|
|
176
189
|
setConfirmLoading(isLoading!);
|
|
177
190
|
}, [isLoading]);
|
|
@@ -203,7 +216,7 @@ export const ModalWithTable = (props: ModalWithTableProps) => {
|
|
|
203
216
|
className={modalClasses}
|
|
204
217
|
>
|
|
205
218
|
<div className={styles.tagsWrapper}>
|
|
206
|
-
<TagField tagsInfo={setTagsInfo} />
|
|
219
|
+
<TagField tagsInfo={setTagsInfo} advancedTagsInfo={setAdvancedTagsInfo} advancedTags={advancedTagsList} />
|
|
207
220
|
</div>
|
|
208
221
|
|
|
209
222
|
<div className={styles.tableWrapper}>
|
|
@@ -10,8 +10,11 @@ export default {
|
|
|
10
10
|
|
|
11
11
|
const Template: Story<TagProps> = (args) => {
|
|
12
12
|
const [tagsInfo, setTagsInfo] = useState<any>({});
|
|
13
|
+
const [advancedTagsInfo, setAdvancedTagsInfo] = useState<any>({});
|
|
14
|
+
|
|
15
|
+
console.log('page: basic', tagsInfo,'advanced', advancedTagsInfo);
|
|
13
16
|
|
|
14
|
-
return <TagField {...args} tagsInfo={setTagsInfo}></TagField>;
|
|
17
|
+
return <TagField {...args} tagsInfo={setTagsInfo} advancedTagsInfo={setAdvancedTagsInfo}></TagField>;
|
|
15
18
|
}
|
|
16
19
|
|
|
17
20
|
export const Primary = Template.bind({});
|
|
@@ -8,17 +8,21 @@ import classNames from 'classnames';
|
|
|
8
8
|
import { t } from 'i18next';
|
|
9
9
|
|
|
10
10
|
export interface customTagProps extends TagProps {
|
|
11
|
-
customTags?:
|
|
12
|
-
tagsInfo?:
|
|
11
|
+
customTags?: string[],
|
|
12
|
+
tagsInfo?: (tags: string[]) => void,
|
|
13
|
+
advancedTagsInfo?: (tags: string[]) => void,
|
|
14
|
+
advancedTags?: string[],
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
export const TagField = (props: customTagProps) => {
|
|
16
|
-
const { customTags = [] } = props;
|
|
18
|
+
const { customTags = [], advancedTags } = props;
|
|
17
19
|
|
|
18
|
-
const [tags, setTags] = useState<string[]>(customTags);
|
|
20
|
+
const [tags, setTags] = useState<string[]>(customTags.filter(tag => !tag.includes('=')));
|
|
19
21
|
const [inputVisible, setInputVisible] = useState<boolean>(false);
|
|
20
22
|
const [inputValue, setInputValue] = useState('');
|
|
21
23
|
const inputRef = useRef<InputRef>(null);
|
|
24
|
+
const [advancedTagList, setAdvancedTagList] = useState<string[]>([]);
|
|
25
|
+
const [allTags, setAllTags] = useState<string[]>([]);
|
|
22
26
|
|
|
23
27
|
useEffect(() => {
|
|
24
28
|
if (inputVisible) {
|
|
@@ -27,8 +31,16 @@ export const TagField = (props: customTagProps) => {
|
|
|
27
31
|
}, [inputVisible]);
|
|
28
32
|
|
|
29
33
|
const handleClose = (removedTag: string) => {
|
|
34
|
+
const newAllTags = allTags.filter((tag) => tag !== removedTag);
|
|
35
|
+
setAllTags(newAllTags);
|
|
36
|
+
|
|
30
37
|
const newTags = tags.filter((tag) => tag !== removedTag);
|
|
31
38
|
setTags(newTags);
|
|
39
|
+
|
|
40
|
+
if (advancedTags && advancedTagList.includes(removedTag)) {
|
|
41
|
+
const newAdvancedTags = advancedTagList.filter((tag) => tag !== removedTag);
|
|
42
|
+
setAdvancedTagList(newAdvancedTags);
|
|
43
|
+
}
|
|
32
44
|
};
|
|
33
45
|
|
|
34
46
|
const showInput = () => {
|
|
@@ -40,16 +52,57 @@ export const TagField = (props: customTagProps) => {
|
|
|
40
52
|
};
|
|
41
53
|
|
|
42
54
|
const handleInputConfirm = () => {
|
|
43
|
-
|
|
44
|
-
|
|
55
|
+
let isAdvancedTag = false;
|
|
56
|
+
if (inputValue && allTags.indexOf(inputValue) === -1) {
|
|
57
|
+
setAllTags([...allTags, inputValue]); // Add to allTags
|
|
58
|
+
if (advancedTags && advancedTags.includes(inputValue.split('=')[0]) && !advancedTags.includes(inputValue)) {
|
|
59
|
+
setAdvancedTagList([...advancedTagList, inputValue]);
|
|
60
|
+
isAdvancedTag = true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Only add the inputValue to the tags array if it's not an advanced tag
|
|
64
|
+
if (!isAdvancedTag) {
|
|
65
|
+
setTags([...tags, inputValue]);
|
|
66
|
+
}
|
|
45
67
|
}
|
|
68
|
+
|
|
46
69
|
setInputVisible(false);
|
|
47
70
|
setInputValue('');
|
|
71
|
+
|
|
72
|
+
const basicTags = tags.filter((tag) => !advancedTagList.includes(tag));
|
|
73
|
+
props.tagsInfo?.(basicTags);
|
|
74
|
+
props.advancedTagsInfo?.(advancedTagList);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
|
78
|
+
const cursorPosition: any = e.currentTarget.selectionStart;
|
|
79
|
+
const advancedFilterMatch = advancedTags && advancedTags.find((filter: any) => inputValue.startsWith(`${filter}=`));
|
|
80
|
+
if (advancedFilterMatch) {
|
|
81
|
+
const filterLength = advancedFilterMatch.length;
|
|
82
|
+
if (cursorPosition <= filterLength && ![8, 46].includes(e.keyCode)) {
|
|
83
|
+
e.preventDefault();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Prevent the input of '=' manually
|
|
88
|
+
if (e.key === "=") {
|
|
89
|
+
e.preventDefault();
|
|
90
|
+
}
|
|
48
91
|
};
|
|
49
92
|
|
|
93
|
+
const doSomething = (e: any) => {
|
|
94
|
+
const tag = e.target.innerText;
|
|
95
|
+
if (!advancedTagList.map(tag => tag.split('=')[0]).includes(tag)) {
|
|
96
|
+
setInputValue(`${tag}=`);
|
|
97
|
+
setInputVisible(true);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
|
|
50
102
|
useEffect(() => {
|
|
51
|
-
props?.
|
|
52
|
-
|
|
103
|
+
props.tagsInfo?.(tags);
|
|
104
|
+
props.advancedTagsInfo?.(advancedTagList);
|
|
105
|
+
}, [tags, advancedTagList]);
|
|
53
106
|
|
|
54
107
|
const forMap = (tag: string) => {
|
|
55
108
|
const tagElem = (
|
|
@@ -69,8 +122,18 @@ export const TagField = (props: customTagProps) => {
|
|
|
69
122
|
</span>
|
|
70
123
|
);
|
|
71
124
|
};
|
|
72
|
-
|
|
73
|
-
const
|
|
125
|
+
|
|
126
|
+
const advancedTagsMap = (tag: string) => {
|
|
127
|
+
const disabled = advancedTagList.map(tag => tag.split('=')[0]).includes(tag);
|
|
128
|
+
return (
|
|
129
|
+
<div onClick={!disabled ? doSomething : undefined} key={tag} style={{ color: disabled ? 'gray' : undefined }}>
|
|
130
|
+
{tag}
|
|
131
|
+
</div>
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const tagChild = allTags.map(forMap);
|
|
136
|
+
const advancedTagsChild = advancedTags && advancedTags.map(advancedTagsMap);
|
|
74
137
|
|
|
75
138
|
return (
|
|
76
139
|
<div className={styles.tagfield}>
|
|
@@ -81,15 +144,27 @@ export const TagField = (props: customTagProps) => {
|
|
|
81
144
|
size="small"
|
|
82
145
|
value={inputValue}
|
|
83
146
|
onChange={handleInputChange}
|
|
147
|
+
onKeyDown={handleKeyDown}
|
|
84
148
|
onPressEnter={handleInputConfirm}
|
|
85
149
|
className={styles['tagfield__input']}
|
|
86
150
|
/>
|
|
87
151
|
)}
|
|
88
152
|
{!inputVisible && (
|
|
89
153
|
<Tag onClick={showInput} className={classNames(styles['tagfield__creator'], 'site-tag-plus')}>
|
|
90
|
-
<SearchOutlined /> {
|
|
154
|
+
<SearchOutlined /> {t('components.tag.search')}
|
|
91
155
|
</Tag>
|
|
92
156
|
)}
|
|
157
|
+
{
|
|
158
|
+
advancedTags &&
|
|
159
|
+
<div style={{ marginTop: 16, marginBottom: 16 }} className={styles.advancedTagsWrapper}>
|
|
160
|
+
<div className={styles.label}>
|
|
161
|
+
{t('components.tag.advancedFields')}:
|
|
162
|
+
</div>
|
|
163
|
+
<div className={styles.advancedTags}>
|
|
164
|
+
{advancedTagsChild}
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
}
|
|
93
168
|
<div style={{ marginTop: 16 }}>
|
|
94
169
|
<TweenOneGroup
|
|
95
170
|
enter={{
|
|
@@ -40,4 +40,21 @@
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
+
|
|
44
|
+
.advancedTagsWrapper {
|
|
45
|
+
display: flex;
|
|
46
|
+
gap: 12px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.advancedTags {
|
|
50
|
+
display: flex;
|
|
51
|
+
flex-direction: row;
|
|
52
|
+
gap: 12px;
|
|
53
|
+
font-family: "SilkaBold";
|
|
54
|
+
text-decoration: underline;
|
|
55
|
+
|
|
56
|
+
div {
|
|
57
|
+
cursor: pointer;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
43
60
|
}
|
|
@@ -1,46 +1,46 @@
|
|
|
1
1
|
import { Upload as UploadAntd } from 'antd';
|
|
2
2
|
import ImgCrop from 'antd-img-crop';
|
|
3
3
|
import type { RcFile, UploadFile, UploadProps } from 'antd/es/upload/interface';
|
|
4
|
-
import
|
|
5
|
-
import imageCompression from 'browser-image-compression';
|
|
4
|
+
import { useEffect, useState } from 'react';
|
|
6
5
|
|
|
7
6
|
interface UploadPropsExtended extends UploadProps {
|
|
8
7
|
onImageChange?: (file: UploadFile | null) => void;
|
|
9
8
|
initialFileList?: UploadFile[];
|
|
9
|
+
initialImageUrl?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function generateRandomString() {
|
|
13
|
+
return Math.random().toString(36).substring(2, 14);
|
|
10
14
|
}
|
|
11
15
|
|
|
12
16
|
export const Upload = (props: UploadPropsExtended) => {
|
|
13
17
|
const {
|
|
14
18
|
onImageChange,
|
|
15
|
-
initialFileList
|
|
19
|
+
initialFileList,
|
|
20
|
+
initialImageUrl
|
|
16
21
|
} = props;
|
|
17
22
|
const [fileList, setFileList] = useState<UploadFile[]>(initialFileList || []);
|
|
18
23
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
} catch (error) {
|
|
30
|
-
console.error('Image compression failed:', error);
|
|
31
|
-
return file;
|
|
24
|
+
// when component mounts or initialImageUrl changes, update fileList
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (initialImageUrl) {
|
|
27
|
+
const newFile: UploadFile = {
|
|
28
|
+
uid: generateRandomString(), // use any unique string
|
|
29
|
+
name: initialImageUrl, // use the URL as the name
|
|
30
|
+
status: 'done',
|
|
31
|
+
url: initialImageUrl, // this is used for preview
|
|
32
|
+
};
|
|
33
|
+
setFileList((prevFileList) => [...prevFileList, newFile]);
|
|
32
34
|
}
|
|
33
|
-
};
|
|
35
|
+
}, [initialImageUrl]);
|
|
34
36
|
|
|
35
37
|
const beforeUpload: UploadProps['beforeUpload'] = async (file: RcFile) => {
|
|
36
|
-
const compressedFile = await compressImage(file);
|
|
37
|
-
|
|
38
38
|
const newFile: UploadFile = {
|
|
39
39
|
uid: file.uid,
|
|
40
40
|
name: file.name,
|
|
41
41
|
type: file.type,
|
|
42
|
-
size:
|
|
43
|
-
originFileObj:
|
|
42
|
+
size: file.size,
|
|
43
|
+
originFileObj: file,
|
|
44
44
|
status: 'done',
|
|
45
45
|
};
|
|
46
46
|
|
|
@@ -78,7 +78,6 @@ export const Upload = (props: UploadPropsExtended) => {
|
|
|
78
78
|
return (
|
|
79
79
|
<ImgCrop rotationSlider>
|
|
80
80
|
<UploadAntd
|
|
81
|
-
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
|
|
82
81
|
listType="picture-card"
|
|
83
82
|
fileList={fileList}
|
|
84
83
|
beforeUpload={beforeUpload}
|
package/src/locales/en.json
CHANGED
package/src/locales/es.json
CHANGED