@irontec/ivoz-ui 1.7.14 → 1.7.17
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/components/List/Content/FastSearchField.js +36 -4
- package/components/List/Content/ListContentValue.js +1 -1
- package/components/List/Filter/ContentFilterDialog.js +1 -5
- package/components/List/Filter/ContentFilterSelector/ContentFilterRow.js +52 -15
- package/components/List/Filter/ContentFilterSelector/ContentFilterRow.styles.js +9 -0
- package/components/List/Filter/ContentFilterSelector/ContentFilterSelector.js +11 -3
- package/entities/DefaultEntityBehavior/ListDecorator.js +17 -2
- package/entities/DefaultEntityBehavior.d.ts +1 -1
- package/entities/DefaultEntityBehavior.js +1 -1
- package/entities/EntityInterface.d.ts +1 -0
- package/helpers/{fechAllPages.js → fetchAllPages.js} +6 -9
- package/helpers/index.d.ts +1 -1
- package/helpers/index.js +1 -1
- package/package.json +1 -1
- package/services/form/Field/DynamicAutocomplete/DynamicAutocomplete.js +18 -12
- package/services/form/Field/FileUploader/FileUploader.styles.d.ts +4 -1
- package/services/form/Field/FileUploader/FileUploader.styles.js +7 -3
- package/services/form/Field/FileUploader/Variant/ImageFileUploader.js +10 -2
- /package/helpers/{fechAllPages.d.ts → fetchAllPages.d.ts} +0 -0
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import SearchIcon from '@mui/icons-material/Search';
|
|
3
|
-
import { forwardRef, useEffect, useState } from 'react';
|
|
3
|
+
import { forwardRef, useEffect, useMemo, useState } from 'react';
|
|
4
4
|
import { StyledSearchTextField } from '../../../services/form/Field/TextField/TextField.styles';
|
|
5
5
|
import { useStoreActions, useStoreState } from 'store';
|
|
6
6
|
import { isPropertyFk } from '../../../services';
|
|
7
7
|
import { StyledAutocomplete } from '../../../services/form/Field/Autocomplete/Autocomplete.styles';
|
|
8
|
+
import { StyledDynamicAutocomplete } from '../../../services/form/Field/DynamicAutocomplete/DynamicAutocomplete.styles';
|
|
8
9
|
import useFirstColumn from './hook/useFirstColumn';
|
|
9
10
|
import useFirstColumnCriteria from './hook/useFirstColumnCriteria';
|
|
11
|
+
import StoreContainer from '../../../store/StoreContainer';
|
|
10
12
|
const FastSearchField = (props, ref) => {
|
|
11
13
|
const { className, path, entityService, ignoreColumn } = props;
|
|
12
14
|
const storeQueryStringCriteria = useStoreState((state) => state.route.queryStringCriteria);
|
|
@@ -25,6 +27,32 @@ const FastSearchField = (props, ref) => {
|
|
|
25
27
|
const isFk = isPropertyFk(firstColumnSpec);
|
|
26
28
|
const foreignEntities = useStoreState((state) => state.list.fkChoices);
|
|
27
29
|
const fkChoices = foreignEntities[firstColumnName] || [];
|
|
30
|
+
const [selectOptions, setSelectOptions] = useState(undefined);
|
|
31
|
+
const { useDynamicAutocomplete, entityName } = useMemo(() => {
|
|
32
|
+
var _a;
|
|
33
|
+
if (!isFk) {
|
|
34
|
+
return { useDynamicAutocomplete: false, entityName: '' };
|
|
35
|
+
}
|
|
36
|
+
const entities = StoreContainer.store.getState().entities.entities;
|
|
37
|
+
const entName = ((_a = firstColumnSpec.$ref) === null || _a === void 0 ? void 0 : _a.replace('#/definitions/', '')) || '';
|
|
38
|
+
const entity = entities === null || entities === void 0 ? void 0 : entities[entName];
|
|
39
|
+
return {
|
|
40
|
+
useDynamicAutocomplete: (entity === null || entity === void 0 ? void 0 : entity.dynamicSelectOptions) || false,
|
|
41
|
+
entityName: entName,
|
|
42
|
+
};
|
|
43
|
+
}, [isFk, firstColumnSpec]);
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (!useDynamicAutocomplete || !entityName) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const entities = StoreContainer.store.getState().entities.entities;
|
|
49
|
+
const entity = entities === null || entities === void 0 ? void 0 : entities[entityName];
|
|
50
|
+
if (entity === null || entity === void 0 ? void 0 : entity.selectOptions) {
|
|
51
|
+
entity.selectOptions().then((handler) => {
|
|
52
|
+
setSelectOptions(() => handler);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}, [useDynamicAutocomplete, entityName]);
|
|
28
56
|
const isDatetime = !isFk && firstColumnSpec.format === 'date-time';
|
|
29
57
|
const initialValue = (firstColumnCriteria === null || firstColumnCriteria === void 0 ? void 0 : firstColumnCriteria.value) || '';
|
|
30
58
|
const [value, setValue] = useState(isDatetime ? initialValue.replace(' ', 'T') : initialValue);
|
|
@@ -63,9 +91,8 @@ const FastSearchField = (props, ref) => {
|
|
|
63
91
|
const queryStringCriteriaWithoutPagination = queryStringCriteria.filter((criteria) => criteria.name !== '_page');
|
|
64
92
|
setQueryStringCriteria(queryStringCriteriaWithoutPagination);
|
|
65
93
|
};
|
|
66
|
-
const changeHandler = ({ target
|
|
67
|
-
|
|
68
|
-
setValue(value);
|
|
94
|
+
const changeHandler = ({ target }) => {
|
|
95
|
+
setValue(target.value);
|
|
69
96
|
};
|
|
70
97
|
useEffect(() => {
|
|
71
98
|
//reset value
|
|
@@ -81,6 +108,11 @@ const FastSearchField = (props, ref) => {
|
|
|
81
108
|
}, 2000);
|
|
82
109
|
return () => clearTimeout(timeOutId);
|
|
83
110
|
}, [value, firstColumnCriteria]);
|
|
111
|
+
if (isFk && useDynamicAutocomplete) {
|
|
112
|
+
return (_jsx(StyledDynamicAutocomplete, { name: 'fast_search', label: '', className: className, value: value, choices: {}, multiple: false, required: false, disabled: false, onChange: changeHandler, onBlur: () => {
|
|
113
|
+
/* noop */
|
|
114
|
+
}, selectOptions: selectOptions, error: false, errorMsg: '', hasChanged: false }));
|
|
115
|
+
}
|
|
84
116
|
if (isFk) {
|
|
85
117
|
return (_jsx(StyledAutocomplete, { className: className, name: 'fast_search', label: '', placeholder: 'Search', value: value, multiple: false, required: false, disabled: false, onChange: changeHandler, onBlur: () => {
|
|
86
118
|
/* noop */
|
|
@@ -58,7 +58,7 @@ const ListContentValue = (props) => {
|
|
|
58
58
|
response = _jsx(StyledCheckBoxOutlineBlankIcon, {});
|
|
59
59
|
}
|
|
60
60
|
else {
|
|
61
|
-
response = _jsx(ListDecorator, { field: columnName, row: row, property: column });
|
|
61
|
+
response = _jsx(ListDecorator, { field: columnName, row: row, property: column, entityPath: entityService.getEntity().path });
|
|
62
62
|
}
|
|
63
63
|
if (isDownloadable && isFileType) {
|
|
64
64
|
response = (_jsx(DownloadFile, { row: row, path: entityService.getEntity().path, fileType: columnName }));
|
|
@@ -16,10 +16,6 @@ export function ContentFilterDialog(props) {
|
|
|
16
16
|
});
|
|
17
17
|
const mobile = useMediaQuery(useTheme().breakpoints.down('md'));
|
|
18
18
|
const [loading, setLoading] = useState(true);
|
|
19
|
-
const [criteria, setCriteria] = useState(queryStringCriteria);
|
|
20
|
-
useEffect(() => {
|
|
21
|
-
setCriteria(queryStringCriteria);
|
|
22
|
-
}, [queryStringCriteria, setCriteria]);
|
|
23
19
|
const foreignKeyGetterLoader = entityService.getEntity().foreignKeyGetter;
|
|
24
20
|
useEffect(() => {
|
|
25
21
|
if (!loading) {
|
|
@@ -59,7 +55,7 @@ export function ContentFilterDialog(props) {
|
|
|
59
55
|
setQueryStringCriteria(sanitizeData);
|
|
60
56
|
};
|
|
61
57
|
const removeFilter = (index) => {
|
|
62
|
-
const newCriteria = [...
|
|
58
|
+
const newCriteria = [...queryStringCriteria];
|
|
63
59
|
newCriteria.splice(index, 1);
|
|
64
60
|
setQueryStringCriteria(newCriteria);
|
|
65
61
|
};
|
|
@@ -6,9 +6,11 @@ import { memo, useEffect, useMemo, useState } from 'react';
|
|
|
6
6
|
import { LightButton, TonalButton, } from '../../../../components/shared/Button/Button.styles';
|
|
7
7
|
import { isPropertyFk, isPropertyScalar, } from '../../../../services/api/ParsedApiSpecInterface';
|
|
8
8
|
import { StyledDropdown } from '../../../../services/form/Field/Dropdown/Dropdown.styles';
|
|
9
|
+
import { StyledDynamicAutocomplete } from '../../../../services/form/Field/DynamicAutocomplete/DynamicAutocomplete.styles';
|
|
9
10
|
import { StyledTextField } from '../../../../services/form/Field/TextField/TextField.styles';
|
|
10
11
|
import _ from '../../../../services/translations/translate';
|
|
11
12
|
import FilterIconFactory from '../icons/FilterIconFactory';
|
|
13
|
+
import StoreContainer from '../../../../store/StoreContainer';
|
|
12
14
|
const StyledDropdownMemo = memo(StyledDropdown, (prev, next) => {
|
|
13
15
|
return prev.value === next.value;
|
|
14
16
|
});
|
|
@@ -34,21 +36,52 @@ export default function ContentFilterRow(props) {
|
|
|
34
36
|
setName(row.name);
|
|
35
37
|
setType(row.type);
|
|
36
38
|
setValue(row.value);
|
|
37
|
-
}, [row]);
|
|
39
|
+
}, [row.name, row.type, row.value]);
|
|
38
40
|
const column = columns[name];
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
41
|
+
const [selectOptions, setSelectOptions] = useState(null);
|
|
42
|
+
const { useDynamicAutocomplete, entityName, enumValue } = useMemo(() => {
|
|
43
|
+
var _a;
|
|
44
|
+
let enumVal = null;
|
|
45
|
+
let useDynamic = false;
|
|
46
|
+
let entName = '';
|
|
47
|
+
if (isPropertyFk(column)) {
|
|
48
|
+
const entities = StoreContainer.store.getState().entities.entities;
|
|
49
|
+
entName = ((_a = column.$ref) === null || _a === void 0 ? void 0 : _a.replace('#/definitions/', '')) || '';
|
|
50
|
+
const entity = entities === null || entities === void 0 ? void 0 : entities[entName];
|
|
51
|
+
if (entity === null || entity === void 0 ? void 0 : entity.dynamicSelectOptions) {
|
|
52
|
+
useDynamic = true;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
enumVal = fkChoices[name] || {};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else if (column.enum) {
|
|
59
|
+
enumVal = column.enum;
|
|
60
|
+
}
|
|
61
|
+
else if (column.type === 'boolean') {
|
|
62
|
+
enumVal = {
|
|
63
|
+
true: _('True'),
|
|
64
|
+
false: _('False'),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
useDynamicAutocomplete: useDynamic,
|
|
69
|
+
entityName: entName,
|
|
70
|
+
enumValue: enumVal,
|
|
50
71
|
};
|
|
51
|
-
}
|
|
72
|
+
}, [column, name, fkChoices]);
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
if (!useDynamicAutocomplete || !entityName) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const entities = StoreContainer.store.getState().entities.entities;
|
|
78
|
+
const entity = entities === null || entities === void 0 ? void 0 : entities[entityName];
|
|
79
|
+
if (entity === null || entity === void 0 ? void 0 : entity.selectOptions) {
|
|
80
|
+
entity.selectOptions().then((handler) => {
|
|
81
|
+
setSelectOptions(() => handler);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}, [useDynamicAutocomplete, entityName]);
|
|
52
85
|
const columnFormat = isPropertyScalar(column) && column.format;
|
|
53
86
|
let textFieldInputType = 'text';
|
|
54
87
|
const inputProps = {};
|
|
@@ -81,13 +114,17 @@ export default function ContentFilterRow(props) {
|
|
|
81
114
|
setType(target.value);
|
|
82
115
|
}, onBlur: () => {
|
|
83
116
|
/* noop */
|
|
84
|
-
}, choices: filterChoices, error: false, errorMsg: '', hasChanged: false }), type !== 'exists' && !enumValue && (_jsx(StyledTextField, { name: 'value', value: value, type: textFieldInputType, error: false, errorMsg: '', inputProps: inputProps, InputProps: {}, hasChanged: false, onChange: ({ target }) => {
|
|
117
|
+
}, choices: filterChoices, error: false, errorMsg: '', hasChanged: false }), type !== 'exists' && !enumValue && !useDynamicAutocomplete && (_jsx(StyledTextField, { name: 'value', value: value, type: textFieldInputType, error: false, errorMsg: '', inputProps: inputProps, InputProps: {}, hasChanged: false, onChange: ({ target }) => {
|
|
85
118
|
let { value } = target;
|
|
86
119
|
if (textFieldInputType === 'datetime-local') {
|
|
87
120
|
value = value.replace('T', ' ');
|
|
88
121
|
}
|
|
89
122
|
setValue(value);
|
|
90
|
-
} })), type !== 'exists' &&
|
|
123
|
+
} })), type !== 'exists' && useDynamicAutocomplete && selectOptions && (_jsx(StyledDynamicAutocomplete, { name: 'value', label: '', value: value, choices: {}, multiple: false, required: false, disabled: false, onChange: ({ target }) => {
|
|
124
|
+
setValue(target.value);
|
|
125
|
+
}, onBlur: () => {
|
|
126
|
+
/* noop */
|
|
127
|
+
}, selectOptions: selectOptions, error: false, errorMsg: '', hasChanged: false })), type !== 'exists' && enumValue && !useDynamicAutocomplete && (_jsx(StyledDropdown, { name: 'value', label: '', value: value, required: false, disabled: false, onChange: ({ target }) => {
|
|
91
128
|
setValue(target.value);
|
|
92
129
|
}, onBlur: () => {
|
|
93
130
|
/* noop */
|
|
@@ -5,6 +5,10 @@ export const StyledContentFilterRow = styled(ContentFilterRow)(({ theme }) => {
|
|
|
5
5
|
display: 'flex',
|
|
6
6
|
alignItems: 'center',
|
|
7
7
|
gap: 'var(--spacing-md)',
|
|
8
|
+
'& > *:not(button)': {
|
|
9
|
+
flex: 1,
|
|
10
|
+
minWidth: 0,
|
|
11
|
+
},
|
|
8
12
|
[theme.breakpoints.down('md')]: {
|
|
9
13
|
flexDirection: 'column',
|
|
10
14
|
gap: 'var(--spacing-sm)',
|
|
@@ -16,5 +20,10 @@ export const StyledContentFilterRow = styled(ContentFilterRow)(({ theme }) => {
|
|
|
16
20
|
height: '40px',
|
|
17
21
|
aspectRatio: '1',
|
|
18
22
|
},
|
|
23
|
+
'& .dynamic-autocomplete': {
|
|
24
|
+
'& .MuiInputBase-root': {
|
|
25
|
+
maxHeight: '40px',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
19
28
|
};
|
|
20
29
|
});
|
|
@@ -20,7 +20,15 @@ export default function ContentFilterSelector(props) {
|
|
|
20
20
|
const propertyName = columnNames[idx];
|
|
21
21
|
filters[propertyName] = entityService.getPropertyFilters(propertyName, path);
|
|
22
22
|
}
|
|
23
|
-
const [criteria, setCriteria] = useState(
|
|
23
|
+
const [criteria, setCriteria] = useState(() => {
|
|
24
|
+
if (!queryStringCriteria.length)
|
|
25
|
+
return [];
|
|
26
|
+
return queryStringCriteria.map((row) => ({
|
|
27
|
+
name: row.name,
|
|
28
|
+
type: row.type,
|
|
29
|
+
value: decodeURIComponent(row.value),
|
|
30
|
+
}));
|
|
31
|
+
});
|
|
24
32
|
const fieldNames = {};
|
|
25
33
|
for (const fldName in filters) {
|
|
26
34
|
fieldNames[fldName] = columns[fldName].label;
|
|
@@ -45,7 +53,7 @@ export default function ContentFilterSelector(props) {
|
|
|
45
53
|
newCriteria[idx] = {
|
|
46
54
|
name,
|
|
47
55
|
type,
|
|
48
|
-
value
|
|
56
|
+
value,
|
|
49
57
|
};
|
|
50
58
|
setCriteria(newCriteria);
|
|
51
59
|
};
|
|
@@ -61,7 +69,7 @@ export default function ContentFilterSelector(props) {
|
|
|
61
69
|
const mobile = useMediaQuery(useTheme().breakpoints.down('md'));
|
|
62
70
|
return (_jsxs("form", Object.assign({ className: className }, { children: [_jsxs(Box, Object.assign({ className: 'filters' }, { children: [_jsx("div", { children: _('Select Fields') }), !mobile &&
|
|
63
71
|
criteria.map((row, idx) => {
|
|
64
|
-
return (_jsx(StyledContentFilterRow, { idx: idx, filters: filters, row: row, columns: columns, fkChoices: fkChoices, fieldNames: fieldNames, isLast: false, setRow: setRow, removeRow: removeRow }, idx));
|
|
72
|
+
return (_jsx(StyledContentFilterRow, { idx: idx, filters: filters, row: row, columns: columns, fkChoices: fkChoices, fieldNames: fieldNames, isLast: false, setRow: setRow, removeRow: removeRow }, `${row.name}-${row.type}-${idx}`));
|
|
65
73
|
}), _jsx(StyledContentFilterRow, { idx: criteria.length, filters: filters, row: {
|
|
66
74
|
name: Object.keys(filters)[0],
|
|
67
75
|
type: defaultFilter,
|
|
@@ -1,9 +1,20 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
1
10
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
11
|
import { isPropertyEmbeddable, isPropertyScalar, } from '../../services/api/ParsedApiSpecInterface';
|
|
3
12
|
import { CustomFunctionComponentContext } from '../../services/form/Field/CustomComponentWrapper';
|
|
4
13
|
import ListDecoratorMultilang from './ListDecoratorMultilang';
|
|
14
|
+
import { ImageFileUploader } from '../../services/form/Field/FileUploader/Variant/ImageFileUploader';
|
|
5
15
|
const ListDecorator = (props) => {
|
|
6
|
-
|
|
16
|
+
var _a;
|
|
17
|
+
const { field, row, property, ignoreCustomComponent, entityPath } = props;
|
|
7
18
|
const valuePath = field.split('.');
|
|
8
19
|
let value = valuePath.length > 1
|
|
9
20
|
? row[valuePath.shift()][valuePath.shift()]
|
|
@@ -19,7 +30,11 @@ const ListDecorator = (props) => {
|
|
|
19
30
|
return (_jsx(ListDecoratorMultilang, { field: field, row: row, property: property }));
|
|
20
31
|
}
|
|
21
32
|
if (property.type === 'file') {
|
|
22
|
-
|
|
33
|
+
const isImage = (_a = value === null || value === void 0 ? void 0 : value.mimeType) === null || _a === void 0 ? void 0 : _a.includes('image/');
|
|
34
|
+
if (isImage && entityPath) {
|
|
35
|
+
return (_jsx(ImageFileUploader, { _columnName: field, _context: CustomFunctionComponentContext.read, values: row, property: property, disabled: false, readOnly: true, downloadPath: `${entityPath}/${row.id}/${field}`, handleDownload: () => __awaiter(void 0, void 0, void 0, function* () { return Promise.resolve(); }), changeHandler: () => null, onBlur: () => null, choices: null, hasChanged: false }));
|
|
36
|
+
}
|
|
37
|
+
return value === null || value === void 0 ? void 0 : value.baseName;
|
|
23
38
|
}
|
|
24
39
|
if (isPropertyScalar(property) && property.enum) {
|
|
25
40
|
let idx = value;
|
|
@@ -47,7 +47,7 @@ declare const DefaultEntityBehavior: {
|
|
|
47
47
|
Form: () => Promise<EntityFormType>;
|
|
48
48
|
View: () => Promise<(props: import("./EntityInterface").ViewProps) => JSX.Element | null>;
|
|
49
49
|
fetchFks: (endpoint: string, properties: Array<EntityValues> | Array<string>, setter: FetchFksCallback, cancelToken?: CancelToken) => Promise<unknown>;
|
|
50
|
-
fetchAllFks: (props: import("../helpers/
|
|
50
|
+
fetchAllFks: (props: import("../helpers/fetchAllPages").fetchAllPagesProps) => Promise<unknown>;
|
|
51
51
|
defaultOrderBy: string;
|
|
52
52
|
defaultOrderDirection: OrderDirection;
|
|
53
53
|
};
|
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import * as React from 'react';
|
|
11
11
|
import { OrderDirection, } from './EntityInterface';
|
|
12
|
-
import { fetchAllPages } from '../helpers/
|
|
12
|
+
import { fetchAllPages } from '../helpers/fetchAllPages';
|
|
13
13
|
import { isEntityItem } from '../router';
|
|
14
14
|
import autoForeignKeyResolver from './DefaultEntityBehavior/AutoForeignKeyResolver';
|
|
15
15
|
import autoSelectOptions, { autoSelectOptionHandlers, } from './DefaultEntityBehavior/AutoSelectOptions';
|
|
@@ -14,6 +14,7 @@ export declare type ListDecoratorPropsType = {
|
|
|
14
14
|
row: any;
|
|
15
15
|
property: PropertySpec;
|
|
16
16
|
ignoreCustomComponent?: true;
|
|
17
|
+
entityPath?: string;
|
|
17
18
|
};
|
|
18
19
|
export declare type ListDecoratorType = React.FunctionComponent<ListDecoratorPropsType>;
|
|
19
20
|
export interface ChildDecoratorProps {
|
|
@@ -15,23 +15,20 @@ export const fetchAllPages = (props) => __awaiter(void 0, void 0, void 0, functi
|
|
|
15
15
|
let keepGoing = true;
|
|
16
16
|
let _page = parseInt(((_a = endpoint.match(/_page=([0-9]+)/)) === null || _a === void 0 ? void 0 : _a[1]) || '1', 10);
|
|
17
17
|
const response = [];
|
|
18
|
-
let loopCount = 0;
|
|
19
18
|
while (keepGoing) {
|
|
20
19
|
try {
|
|
21
|
-
if (loopCount > 5) {
|
|
22
|
-
console.error('Too much requests');
|
|
23
|
-
break;
|
|
24
|
-
}
|
|
25
|
-
loopCount++;
|
|
26
20
|
const result = yield getAction({
|
|
27
21
|
path: endpoint,
|
|
28
22
|
silenceErrors: false,
|
|
29
|
-
params: Object.assign(Object.assign({}, params), {
|
|
23
|
+
params: Object.assign(Object.assign({ _itemsPerPage: 200 }, params), { _page }),
|
|
30
24
|
successCallback: (data, headers) => __awaiter(void 0, void 0, void 0, function* () {
|
|
31
25
|
response.push(...data);
|
|
32
26
|
const totalItems = parseInt((headers === null || headers === void 0 ? void 0 : headers['x-total-items']) || `${response.length}`, 10);
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
const totalPages = parseInt((headers === null || headers === void 0 ? void 0 : headers['x-total-pages']) || '1', 10);
|
|
28
|
+
const isLastPage = _page >= totalPages;
|
|
29
|
+
const hasAllItems = response.length >= totalItems;
|
|
30
|
+
const isEmptyResponse = !data.length;
|
|
31
|
+
if (isLastPage || hasAllItems || isEmptyResponse) {
|
|
35
32
|
keepGoing = false;
|
|
36
33
|
}
|
|
37
34
|
_page++;
|
package/helpers/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './fetchAllPages';
|
|
2
2
|
export * from './fetchFilteredPage';
|
package/helpers/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './fetchAllPages';
|
|
2
2
|
export * from './fetchFilteredPage';
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@ const DynamicAutocomplete = (props) => {
|
|
|
9
9
|
var _a;
|
|
10
10
|
const { nullOption, name, label, required, multiple, disabled, onBlur, error, errorMsg, helperText, hasChanged, value, choices, selectOptions, onChange, } = props;
|
|
11
11
|
const { t } = useTranslation();
|
|
12
|
-
let className = props.className;
|
|
12
|
+
let className = props.className || '';
|
|
13
13
|
if (hasChanged) {
|
|
14
14
|
className += ' changed';
|
|
15
15
|
}
|
|
@@ -25,7 +25,11 @@ const DynamicAutocomplete = (props) => {
|
|
|
25
25
|
const [loading, setLoading] = useState(false);
|
|
26
26
|
const [currentOption, setCurrentOption] = useState(nullOptionObject);
|
|
27
27
|
const debounceTimeoutRef = useRef();
|
|
28
|
+
const loadedValuesRef = useRef(new Set());
|
|
28
29
|
useEffect(() => {
|
|
30
|
+
if (selectOptions && Object.keys(choices).length === 0) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
29
33
|
if (Array.isArray(choices)) {
|
|
30
34
|
setArrayChoices(choices);
|
|
31
35
|
return;
|
|
@@ -41,25 +45,27 @@ const DynamicAutocomplete = (props) => {
|
|
|
41
45
|
if (nullValue) {
|
|
42
46
|
return;
|
|
43
47
|
}
|
|
44
|
-
if (!
|
|
48
|
+
if (!selectOptions) {
|
|
45
49
|
return;
|
|
46
50
|
}
|
|
47
|
-
|
|
48
|
-
? choices.some((item) => item.id === value)
|
|
49
|
-
: choices && value in choices;
|
|
50
|
-
if (choicesIncludesValue) {
|
|
51
|
+
if (loadedValuesRef.current.has(value)) {
|
|
51
52
|
return;
|
|
52
53
|
}
|
|
53
|
-
|
|
54
|
+
loadedValuesRef.current.add(value);
|
|
55
|
+
selectOptions({
|
|
54
56
|
callback: (options) => {
|
|
55
57
|
const option = options[0];
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
if (option) {
|
|
59
|
+
setArrayChoices((prev) => {
|
|
60
|
+
const exists = prev.some((item) => item.id == option.id);
|
|
61
|
+
return exists ? prev : [...prev, option];
|
|
62
|
+
});
|
|
63
|
+
}
|
|
58
64
|
},
|
|
59
65
|
}, {
|
|
60
66
|
id: value,
|
|
61
67
|
});
|
|
62
|
-
}, []);
|
|
68
|
+
}, [value, selectOptions]);
|
|
63
69
|
const setOptions = useCallback((options) => {
|
|
64
70
|
const isCurrentOptionIncluded = options.some((option) => option.id == (currentOption === null || currentOption === void 0 ? void 0 : currentOption.id));
|
|
65
71
|
if (!isCurrentOptionIncluded &&
|
|
@@ -209,9 +215,9 @@ const DynamicAutocomplete = (props) => {
|
|
|
209
215
|
const disableClearable = arrayChoices.find((item) => item.id === '__null__')
|
|
210
216
|
? false
|
|
211
217
|
: true;
|
|
212
|
-
const safeValue = arrayChoices.find((item) => item.id
|
|
218
|
+
const safeValue = arrayChoices.find((item) => item.id == value)
|
|
213
219
|
? value
|
|
214
220
|
: null;
|
|
215
|
-
return (_jsx(MuiAutocomplete, { className: 'dynamic-autocomplete' + className, value: safeValue, multiple: multiple, disabled: disabled, disableClearable: disableClearable, onChange: onChangeWrapper, onBlur: onBlur, onInputChange: handleInputChange, options: arrayChoices !== null && arrayChoices !== void 0 ? arrayChoices : [], getOptionLabel: getOptionLabel, isOptionEqualToValue: isOptionEqualToValue, loading: loading, placeholder: props.placeholder, renderInput: renderInput, PaperComponent: CustomOption, renderOption: (props, option) => (_jsx(Box, Object.assign({ component: 'li', className: 'autocomplete-option', "data-value": option.id }, props, { children: option.label }))) }));
|
|
221
|
+
return (_jsx(MuiAutocomplete, { className: 'dynamic-autocomplete ' + className, value: safeValue, multiple: multiple, disabled: disabled, disableClearable: disableClearable, onChange: onChangeWrapper, onBlur: onBlur, onInputChange: handleInputChange, options: arrayChoices !== null && arrayChoices !== void 0 ? arrayChoices : [], getOptionLabel: getOptionLabel, isOptionEqualToValue: isOptionEqualToValue, loading: loading, placeholder: props.placeholder, renderInput: renderInput, PaperComponent: CustomOption, renderOption: (props, option) => (_jsx(Box, Object.assign({ component: 'li', className: 'autocomplete-option', "data-value": option.id }, props, { children: option.label }))) }));
|
|
216
222
|
};
|
|
217
223
|
export default DynamicAutocomplete;
|
|
@@ -12,6 +12,9 @@ interface StyledUploadButtonLabelProps {
|
|
|
12
12
|
export declare const StyledUploadButtonLabel: import("@emotion/styled").StyledComponent<StyledUploadButtonLabelProps & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
|
|
13
13
|
export declare const StyledFileNameContainer: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
14
14
|
export declare const StyledImageContainer: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
15
|
-
|
|
15
|
+
interface StyledImagePreviewProps {
|
|
16
|
+
$isReadMode?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare const StyledImagePreview: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme> & StyledImagePreviewProps, import("react").DetailedHTMLProps<import("react").ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, {}>;
|
|
16
19
|
export declare const StyledTextContainer: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
17
20
|
export {};
|
|
@@ -38,10 +38,14 @@ export const StyledImageContainer = styled('div')({
|
|
|
38
38
|
color: '#A3A4A8',
|
|
39
39
|
},
|
|
40
40
|
});
|
|
41
|
-
export const StyledImagePreview = styled('img')({
|
|
42
|
-
maxWidth: '
|
|
41
|
+
export const StyledImagePreview = styled('img')(({ $isReadMode }) => ({
|
|
42
|
+
maxWidth: $isReadMode ? '50px' : '200px',
|
|
43
|
+
maxHeight: $isReadMode ? '50px' : '200px',
|
|
44
|
+
width: 'auto',
|
|
43
45
|
height: 'auto',
|
|
44
|
-
|
|
46
|
+
objectFit: $isReadMode ? 'cover' : 'contain',
|
|
47
|
+
cursor: $isReadMode ? '' : 'pointer',
|
|
48
|
+
}));
|
|
45
49
|
export const StyledTextContainer = styled('div')({
|
|
46
50
|
color: '#B2B3B6',
|
|
47
51
|
fontSize: '14px',
|
|
@@ -16,14 +16,16 @@ import { useStoreActions } from '../../../../../store';
|
|
|
16
16
|
import { StyledImageFileUpladerTextDield } from '../../TextField/TextField.styles';
|
|
17
17
|
import { IconButton, InputAdornment } from '@mui/material';
|
|
18
18
|
import CancelIcon from '@mui/icons-material/Cancel';
|
|
19
|
+
import { CustomFunctionComponentContext } from '../../CustomComponentWrapper';
|
|
19
20
|
export const ImageFileUploader = (props) => {
|
|
20
21
|
var _a, _b;
|
|
21
|
-
const { _columnName, accept, values, disabled, handleDownload, changeHandler, onBlur, downloadPath, property, } = props;
|
|
22
|
+
const { _columnName, _context, accept, values, disabled, handleDownload, changeHandler, onBlur, downloadPath, property, } = props;
|
|
22
23
|
const fileValue = values[_columnName];
|
|
23
24
|
const id = `${_columnName}-file-upload`;
|
|
24
25
|
const fileName = (fileValue === null || fileValue === void 0 ? void 0 : fileValue.file) ? (_a = fileValue.file) === null || _a === void 0 ? void 0 : _a.name : fileValue === null || fileValue === void 0 ? void 0 : fileValue.baseName;
|
|
25
26
|
const fileSize = (fileValue === null || fileValue === void 0 ? void 0 : fileValue.file) ? (_b = fileValue.file) === null || _b === void 0 ? void 0 : _b.size : fileValue === null || fileValue === void 0 ? void 0 : fileValue.fileSize;
|
|
26
27
|
const fileSizeMb = Math.round(((fileSize || 0) / 1024 / 1024) * 10) / 10;
|
|
28
|
+
const isReadMode = _context === CustomFunctionComponentContext.read;
|
|
27
29
|
const apiDownload = useStoreActions((actions) => {
|
|
28
30
|
return actions.api.download;
|
|
29
31
|
});
|
|
@@ -49,6 +51,12 @@ export const ImageFileUploader = (props) => {
|
|
|
49
51
|
}),
|
|
50
52
|
});
|
|
51
53
|
}, [fileValue.file, fileValue.baseName]);
|
|
54
|
+
if (isReadMode) {
|
|
55
|
+
if (!fileName || !imageSrc) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
return (_jsx(StyledImageContainer, { children: _jsx(StyledImagePreview, { src: imageSrc, "$isReadMode": isReadMode }) }));
|
|
59
|
+
}
|
|
52
60
|
return (_jsxs(_Fragment, { children: [_jsxs(StyledFileUploaderContainer, { children: [_jsx("input", { style: { display: 'none' }, id: id, type: 'file', accept: accept, onChange: (event) => {
|
|
53
61
|
const files = event.target.files || [];
|
|
54
62
|
const value = Object.assign(Object.assign({}, fileValue), { file: files[0] });
|
|
@@ -60,7 +68,7 @@ export const ImageFileUploader = (props) => {
|
|
|
60
68
|
};
|
|
61
69
|
changeHandler(changeEvent);
|
|
62
70
|
onBlur(changeEvent);
|
|
63
|
-
} }), fileName && (_jsx(StyledImageContainer, Object.assign({ className: disabled ? 'disabled' : '' }, { children: imageSrc ? (_jsx(StyledImagePreview, { src: imageSrc, onClick: handleDownload })) : (values.id && _jsx(AccountCircleIcon, { onClick: handleDownload })) }))), _jsxs(StyledTextContainer, { children: [_jsx("span", { children: "JPG, JPEG, PNG format" }), _jsx("span", { children: "Maximum 500KB" }), !disabled && (_jsx(StyledUploadButtonLabel, Object.assign({ htmlFor: id }, { children: _('Upload image') }))), fileName && (_jsxs("span", { children: [fileName, " (", fileSizeMb, "MB)"] })), fileName && !property.required && (_jsx(StyledImageFileUpladerTextDield, { type: 'text', multiline: false, value: fileName, hasChanged: false, disabled: true, InputProps: {
|
|
71
|
+
} }), fileName && (_jsx(StyledImageContainer, Object.assign({ className: disabled ? 'disabled' : '' }, { children: imageSrc ? (_jsx(StyledImagePreview, { src: imageSrc, onClick: handleDownload, "$isReadMode": isReadMode })) : (values.id && _jsx(AccountCircleIcon, { onClick: handleDownload })) }))), _jsxs(StyledTextContainer, { children: [_jsx("span", { children: "JPG, JPEG, PNG format" }), _jsx("span", { children: "Maximum 500KB" }), !disabled && (_jsx(StyledUploadButtonLabel, Object.assign({ htmlFor: id }, { children: _('Upload image') }))), fileName && (_jsxs("span", { children: [fileName, " (", fileSizeMb, "MB)"] })), fileName && !property.required && (_jsx(StyledImageFileUpladerTextDield, { type: 'text', multiline: false, value: fileName, hasChanged: false, disabled: true, InputProps: {
|
|
64
72
|
endAdornment: (_jsx(InputAdornment, Object.assign({ position: 'end' }, { children: _jsx(IconButton, Object.assign({ "aria-label": 'delete image', onClick: () => {
|
|
65
73
|
setImageSrc(null);
|
|
66
74
|
const changeEvent = {
|
|
File without changes
|