@controleonline/ui-default 1.0.269 → 1.0.272
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/.github/workflows/integration-source-gate.yml +68 -0
- package/.github/workflows/manager-worker.yml +19 -0
- package/AGENTS.md +46 -50
- package/docs/technical/Contrato-de-colunas.md +67 -0
- package/docs/technical/Default-Components.md +76 -0
- package/docs/technical/DefaultForm.md +80 -0
- package/docs/technical/DefaultInput-e-DefaultSelect.md +73 -0
- package/docs/technical/DefaultTable.md +203 -0
- package/docs/wiki.md +1 -0
- package/package.json +22 -21
- package/scripts/validate-wiki-pointer.cjs +13 -0
- package/src/react/components/address/DefaultAddress.js +435 -0
- package/src/react/components/address/DefaultAddress.styles.js +133 -0
- package/src/react/components/address/DefaultAddressMapPane.js +55 -0
- package/src/react/components/address/LatLonReadonlyFields.js +51 -0
- package/src/react/components/address/defaultAddressHelpers.js +163 -0
- package/src/react/components/address/defaultAddressStyles.js +136 -0
- package/src/react/components/address/defaultAddressUtils.js +129 -0
- package/src/react/components/extra-data/DefaultExtraData.js +152 -0
- package/src/react/components/extra-data/DefaultExtraData.styles.js +61 -0
- package/src/react/components/files/DefaultFile.js +231 -46
- package/src/react/components/files/DefaultFileColumn.js +123 -0
- package/src/react/components/files/DefaultFileColumn.styles.js +52 -0
- package/src/react/components/files/DefaultFileColumn.utils.js +104 -0
- package/src/react/components/filters/CompactFilterSelector.js +51 -35
- package/src/react/components/filters/DefaultColumnFilter.js +58 -41
- package/src/react/components/filters/DefaultExternalFilters.js +331 -265
- package/src/react/components/form/DefaultForm.js +99 -79
- package/src/react/components/help/DefaultTooltip.js +59 -33
- package/src/react/components/help/DefaultTooltip.styles.js +23 -3
- package/src/react/components/inputs/DefaultColorInput.js +153 -0
- package/src/react/components/inputs/DefaultFeatherIconPicker.js +146 -0
- package/src/react/components/inputs/DefaultFeatherIconPicker.styles.js +113 -0
- package/src/react/components/inputs/DefaultInput.js +69 -5
- package/src/react/components/inputs/DefaultInput.styles.js +26 -0
- package/src/react/components/inputs/DefaultSelect.js +134 -123
- package/src/react/components/inputs/defaultInputUtils.js +69 -43
- package/src/react/components/map/DefaultGoogleMap.styles.js +9 -2
- package/src/react/components/map/DefaultGoogleMap.web.js +49 -28
- package/src/react/components/map/DefaultMap.native.js +73 -73
- package/src/react/components/map/DefaultMap.shared.js +911 -762
- package/src/react/components/map/DefaultMap.web.js +124 -68
- package/src/react/components/table/DefaultColumnMenu.js +109 -108
- package/src/react/components/table/DefaultDebug.js +45 -38
- package/src/react/components/table/DefaultSearchModal.js +9 -1
- package/src/react/components/table/DefaultTable.grouping.js +98 -0
- package/src/react/components/table/DefaultTable.js +215 -109
- package/src/react/components/table/DefaultTable.styles.js +367 -314
- package/src/react/components/table/DefaultTableBody.js +13 -8
- package/src/react/components/table/DefaultTableCards.js +20 -1
- package/src/react/components/table/DefaultTableControls.js +180 -205
- package/src/react/components/table/DefaultTableImportModal.js +108 -0
- package/src/react/components/table/DefaultTableInput.js +1 -0
- package/src/react/components/table/DefaultTableRowActions.js +1 -1
- package/src/react/components/table/DefaultTableRows.js +224 -363
- package/src/react/components/table/DefaultTableSearch.js +28 -5
- package/src/react/components/table/DefaultTableToolbar.js +92 -3
- package/src/react/components/table/useDefaultTablePagination.js +56 -7
- package/src/react/components/table/useDefaultTableStoreSync.js +164 -0
- package/src/react/components/upload/DefaultUpload.js +436 -0
- package/src/react/components/upload/DefaultUpload.styles.js +153 -0
- package/src/react/components/upload/DefaultUploadAttachmentsList.js +138 -0
- package/src/react/components/upload/DefaultUploadManagerModal.js +247 -0
- package/src/react/components/upload/defaultUploadHelpers.js +108 -0
- package/src/react/components/upload/defaultUploadLibrary.js +248 -0
- package/src/react/components/upload/fileUpload.js +93 -0
- package/src/react/hooks/usePostalCodeLookup.js +145 -0
- package/src/react/index.js +6 -0
- package/src/react/services/addressFormUtils.js +196 -0
- package/src/react/services/addressGeo.js +227 -0
- package/src/react/utils/tableVisibleColumnsPreferences.js +29 -12
- package/src/tests/react/components/address/defaultAddressHelpers.test.js +104 -0
- package/src/tests/react/components/files/DefaultFile.test.js +6 -6
- package/src/tests/react/components/form/DefaultForm.test.js +123 -0
- package/src/tests/react/components/inputs/DefaultSelect.test.js +108 -79
- package/src/tests/react/components/table/DefaultTable.grouping.test.js +49 -0
- package/src/tests/react/components/table/DefaultTable.test.js +54 -2
- package/src/tests/react/components/table/DefaultTableControls.filters.test.mjs +21 -0
- package/src/tests/react/components/table/resolveRowBackgroundColor.test.mjs +45 -0
- package/src/tests/react/components/table/useDefaultTableStoreSync.test.js +161 -0
- package/src/tests/react/components/upload/DefaultUpload.test.js +353 -0
- package/src/tests/react/components/upload/defaultUploadLibrary.test.js +82 -0
- package/src/tests/react/components/upload/peopleMediaLibraryPreview.test.mjs +57 -0
- package/src/tests/react/hooks/usePostalCodeLookup.test.js +40 -0
- package/src/tests/react/services/SMOKE-637-cep-hydrate.md +45 -0
- package/src/tests/react/services/addressFormUtils.test.js +176 -0
- package/src/tests/react/services/addressGeoLookup.async.test.js +104 -0
- package/src/tests/react/services/addressGeoLookup.test.js +105 -0
- package/src/tests/react/services/smoke-637/form-cep-12941040.png +0 -0
- package/src/tests/react/services/smoke-637/index.html +132 -0
- package/src/tests/react/utils/tableVisibleColumnsPreferences.test.js +84 -48
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import {extractFileId, resolveDefaultFileUrl} from '@controleonline/ui-common/src/react/utils/fileUrl';
|
|
2
|
+
|
|
3
|
+
const FILE_INPUT_TYPES = new Set([
|
|
4
|
+
'document',
|
|
5
|
+
'documents',
|
|
6
|
+
'file',
|
|
7
|
+
'files',
|
|
8
|
+
'image',
|
|
9
|
+
'images',
|
|
10
|
+
'pdf',
|
|
11
|
+
]);
|
|
12
|
+
|
|
13
|
+
const IMAGE_EXTENSIONS = new Set(['avif', 'bmp', 'gif', 'ico', 'jpeg', 'jpg', 'png', 'svg', 'webp']);
|
|
14
|
+
const PDF_EXTENSIONS = new Set(['pdf']);
|
|
15
|
+
const DOCUMENT_EXTENSIONS = new Set(['doc', 'docx', 'odt', 'rtf', 'xls', 'xlsx', 'ods', 'ppt', 'pptx', 'odp']);
|
|
16
|
+
|
|
17
|
+
export const normalizeFileColumnText = value => String(value ?? '').trim();
|
|
18
|
+
|
|
19
|
+
export const normalizeFileColumnType = value =>
|
|
20
|
+
normalizeFileColumnText(value).replace(/[^a-z0-9]/gi, '').toLowerCase();
|
|
21
|
+
|
|
22
|
+
export const isFileInputColumn = column =>
|
|
23
|
+
FILE_INPUT_TYPES.has(normalizeFileColumnType(column?.inputType));
|
|
24
|
+
|
|
25
|
+
const asArray = value => {
|
|
26
|
+
if (Array.isArray(value)) return value;
|
|
27
|
+
if (value === undefined || value === null || value === '') return [];
|
|
28
|
+
if (typeof value === 'string' && value.includes(',')) {
|
|
29
|
+
return value
|
|
30
|
+
.split(',')
|
|
31
|
+
.map(item => item.trim())
|
|
32
|
+
.filter(Boolean);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return [value];
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const pickFilePayload = item =>
|
|
39
|
+
item && typeof item === 'object' && !Array.isArray(item) && item.file
|
|
40
|
+
? item.file
|
|
41
|
+
: item;
|
|
42
|
+
|
|
43
|
+
const resolveForcedFileType = column => {
|
|
44
|
+
const inputType = normalizeFileColumnType(column?.inputType);
|
|
45
|
+
if (inputType === 'image' || inputType === 'images') return 'image';
|
|
46
|
+
if (inputType === 'pdf') return 'application';
|
|
47
|
+
if (inputType === 'document' || inputType === 'documents') return 'document';
|
|
48
|
+
return normalizeFileColumnText(column?.fileType);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const resolveForcedExtension = column => {
|
|
52
|
+
const inputType = normalizeFileColumnType(column?.inputType);
|
|
53
|
+
if (inputType === 'pdf') return 'pdf';
|
|
54
|
+
return normalizeFileColumnText(column?.extension).toLowerCase();
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const resolveKind = ({fileType, extension}) => {
|
|
58
|
+
const normalizedType = normalizeFileColumnType(fileType);
|
|
59
|
+
const normalizedExtension = normalizeFileColumnText(extension).replace(/^\./, '').toLowerCase();
|
|
60
|
+
|
|
61
|
+
if (normalizedType === 'image' || IMAGE_EXTENSIONS.has(normalizedExtension)) return 'image';
|
|
62
|
+
if (PDF_EXTENSIONS.has(normalizedExtension)) return 'pdf';
|
|
63
|
+
if (DOCUMENT_EXTENSIONS.has(normalizedExtension) || normalizedType === 'document') return 'document';
|
|
64
|
+
if (normalizedType === 'text') return 'text';
|
|
65
|
+
if (normalizedType === 'audio') return 'audio';
|
|
66
|
+
if (normalizedType === 'video') return 'video';
|
|
67
|
+
return 'file';
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const normalizeDefaultFileColumnItems = ({
|
|
71
|
+
column = {},
|
|
72
|
+
company = null,
|
|
73
|
+
row = {},
|
|
74
|
+
value,
|
|
75
|
+
} = {}) =>
|
|
76
|
+
asArray(value ?? row?.[column?.key || column?.name]).map((item, index) => {
|
|
77
|
+
const payload = pickFilePayload(item);
|
|
78
|
+
const isObject = payload && typeof payload === 'object' && !Array.isArray(payload);
|
|
79
|
+
const id = extractFileId(payload);
|
|
80
|
+
const fileType = isObject
|
|
81
|
+
? normalizeFileColumnText(payload.fileType) || resolveForcedFileType(column)
|
|
82
|
+
: resolveForcedFileType(column);
|
|
83
|
+
const extension = isObject
|
|
84
|
+
? normalizeFileColumnText(payload.extension).toLowerCase() || resolveForcedExtension(column)
|
|
85
|
+
: resolveForcedExtension(column);
|
|
86
|
+
const url = isObject && typeof payload.url === 'string'
|
|
87
|
+
? payload.url
|
|
88
|
+
: resolveDefaultFileUrl(payload, {company});
|
|
89
|
+
const driveUrl = isObject && typeof payload.driveUrl === 'string'
|
|
90
|
+
? payload.driveUrl
|
|
91
|
+
: '';
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
extension,
|
|
95
|
+
fileName: isObject ? normalizeFileColumnText(payload.fileName) : '',
|
|
96
|
+
fileType,
|
|
97
|
+
id,
|
|
98
|
+
key: `${id || normalizeFileColumnText(payload) || index}`,
|
|
99
|
+
kind: resolveKind({fileType, extension}),
|
|
100
|
+
openUrl: driveUrl || url,
|
|
101
|
+
relationId: item && typeof item === 'object' && !Array.isArray(item) ? extractFileId(item) : null,
|
|
102
|
+
source: payload,
|
|
103
|
+
};
|
|
104
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useCallback, useMemo, useState } from 'react';
|
|
1
|
+
import React, { useCallback, useMemo, useState } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Image,
|
|
4
4
|
Modal,
|
|
@@ -7,10 +7,11 @@ import {
|
|
|
7
7
|
TextInput,
|
|
8
8
|
TouchableOpacity,
|
|
9
9
|
TouchableWithoutFeedback,
|
|
10
|
-
useWindowDimensions,
|
|
11
|
-
View,
|
|
12
|
-
} from 'react-native';
|
|
13
|
-
import
|
|
10
|
+
useWindowDimensions,
|
|
11
|
+
View,
|
|
12
|
+
} from 'react-native';
|
|
13
|
+
import { useStore } from '@store';
|
|
14
|
+
import Icon from 'react-native-vector-icons/Feather';
|
|
14
15
|
import {
|
|
15
16
|
formatStoreColumnLabel,
|
|
16
17
|
resolveStoreColumn,
|
|
@@ -19,16 +20,16 @@ import {
|
|
|
19
20
|
import { isValidFeatherIcon } from '../inputs/defaultInputUtils';
|
|
20
21
|
import createStyles from './CompactFilterSelector.styles';
|
|
21
22
|
|
|
22
|
-
const buildTheme = ({ accentColor, themeColors = {} }) => ({
|
|
23
|
-
accentColor: accentColor,
|
|
24
|
-
activeBackgroundColor:
|
|
25
|
-
themeColors.activeBackgroundColor || `${accentColor}14
|
|
26
|
-
activeIconBackgroundColor:
|
|
27
|
-
themeColors.activeIconBackgroundColor || `${accentColor}24
|
|
28
|
-
activeChevronColor:
|
|
29
|
-
themeColors.activeChevronColor ||
|
|
30
|
-
themeColors.activeIconColor ||
|
|
31
|
-
accentColor,
|
|
23
|
+
const buildTheme = ({ accentColor, themeColors = {} }) => ({
|
|
24
|
+
accentColor: accentColor,
|
|
25
|
+
activeBackgroundColor:
|
|
26
|
+
themeColors.activeBackgroundColor || (accentColor ? `${accentColor}14` : themeColors.backgroundColor),
|
|
27
|
+
activeIconBackgroundColor:
|
|
28
|
+
themeColors.activeIconBackgroundColor || (accentColor ? `${accentColor}24` : themeColors.iconBackgroundColor),
|
|
29
|
+
activeChevronColor:
|
|
30
|
+
themeColors.activeChevronColor ||
|
|
31
|
+
themeColors.activeIconColor ||
|
|
32
|
+
accentColor,
|
|
32
33
|
activeIconColor: themeColors.activeIconColor || accentColor,
|
|
33
34
|
activeTextColor: themeColors.activeTextColor || accentColor,
|
|
34
35
|
backgroundColor: themeColors.backgroundColor || '#F8FAFC',
|
|
@@ -44,10 +45,10 @@ const buildTheme = ({ accentColor, themeColors = {} }) => ({
|
|
|
44
45
|
modalTitleColor: themeColors.modalTitleColor || '#0F172A',
|
|
45
46
|
optionBackgroundColor: themeColors.optionBackgroundColor || '#F8FAFC',
|
|
46
47
|
optionBorderColor: themeColors.optionBorderColor || '#E2E8F0',
|
|
47
|
-
optionSelectedTextColor:
|
|
48
|
-
themeColors.optionSelectedTextColor || accentColor,
|
|
49
|
-
textColor: themeColors.textColor || '#0F172A',
|
|
50
|
-
});
|
|
48
|
+
optionSelectedTextColor:
|
|
49
|
+
themeColors.optionSelectedTextColor || accentColor,
|
|
50
|
+
textColor: themeColors.textColor || '#0F172A',
|
|
51
|
+
});
|
|
51
52
|
|
|
52
53
|
const noop = () => {};
|
|
53
54
|
|
|
@@ -82,12 +83,12 @@ const resolveStoreFieldLabel = ({ fallbackLabel = '', field = '', store = '' })
|
|
|
82
83
|
);
|
|
83
84
|
};
|
|
84
85
|
|
|
85
|
-
const CompactFilterSelector = ({
|
|
86
|
-
accentColor =
|
|
87
|
-
active = false,
|
|
88
|
-
children = null,
|
|
89
|
-
dense = false,
|
|
90
|
-
disabled = false,
|
|
86
|
+
const CompactFilterSelector = ({
|
|
87
|
+
accentColor = null,
|
|
88
|
+
active = false,
|
|
89
|
+
children = null,
|
|
90
|
+
dense = false,
|
|
91
|
+
disabled = false,
|
|
91
92
|
icon = 'sliders',
|
|
92
93
|
label = '',
|
|
93
94
|
labelCaption = '',
|
|
@@ -98,18 +99,33 @@ const CompactFilterSelector = ({
|
|
|
98
99
|
options = [],
|
|
99
100
|
searchable = false,
|
|
100
101
|
selectedKey = '',
|
|
101
|
-
field = '',
|
|
102
|
-
store = '',
|
|
103
|
-
themeColors = {},
|
|
104
|
-
title = '',
|
|
105
|
-
}) => {
|
|
102
|
+
field = '',
|
|
103
|
+
store = '',
|
|
104
|
+
themeColors = {},
|
|
105
|
+
title = '',
|
|
106
|
+
}) => {
|
|
107
|
+
const themeStore = useStore('theme');
|
|
106
108
|
const [visible, setVisible] = useState(false);
|
|
107
109
|
const [searchText, setSearchText] = useState('');
|
|
108
|
-
const { width: windowWidth } = useWindowDimensions();
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
const { width: windowWidth } = useWindowDimensions();
|
|
111
|
+
const themeStoreColors = themeStore?.getters?.colors || {};
|
|
112
|
+
const resolvedAccentColor =
|
|
113
|
+
accentColor ||
|
|
114
|
+
themeColors.primary ||
|
|
115
|
+
themeColors.accent ||
|
|
116
|
+
themeStoreColors.primary ||
|
|
117
|
+
themeStoreColors.accent ||
|
|
118
|
+
'';
|
|
119
|
+
const resolvedTheme = useMemo(
|
|
120
|
+
() => buildTheme({
|
|
121
|
+
accentColor: resolvedAccentColor,
|
|
122
|
+
themeColors: {
|
|
123
|
+
...themeStoreColors,
|
|
124
|
+
...themeColors,
|
|
125
|
+
},
|
|
126
|
+
}),
|
|
127
|
+
[resolvedAccentColor, themeColors, themeStoreColors],
|
|
128
|
+
);
|
|
113
129
|
const styles = useMemo(
|
|
114
130
|
() => createStyles(resolvedTheme, dense, windowWidth),
|
|
115
131
|
[dense, resolvedTheme, windowWidth],
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useCallback, useState } from 'react';
|
|
1
|
+
import React, { useCallback, useEffect, useState } from 'react';
|
|
2
2
|
import { TextInput, View } from 'react-native';
|
|
3
3
|
import { getAllStores, useStore } from '@store';
|
|
4
4
|
import {
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
import CompactFilterSelector from './CompactFilterSelector';
|
|
14
14
|
import DateShortcutFilter from './DateShortcutFilter';
|
|
15
15
|
import { resolveNextDateFilterValue } from './dateFilterSelection';
|
|
16
|
+
import useDefaultTableTheme from '@controleonline/ui-default/src/react/components/table/useDefaultTableTheme';
|
|
16
17
|
import {
|
|
17
18
|
normalizeCollectionItems,
|
|
18
19
|
resolveColumnListLoadParams,
|
|
@@ -25,9 +26,9 @@ import {
|
|
|
25
26
|
sanitizeTableFiltersPreference,
|
|
26
27
|
} from '../../utils/tableVisibleColumnsPreferences';
|
|
27
28
|
import styles from './DefaultColumnFilter.styles';
|
|
28
|
-
|
|
29
|
-
const DefaultColumnFilter = ({
|
|
30
|
-
accentColor =
|
|
29
|
+
|
|
30
|
+
const DefaultColumnFilter = ({
|
|
31
|
+
accentColor = null,
|
|
31
32
|
column,
|
|
32
33
|
filters = {},
|
|
33
34
|
onBeforeOpen = null,
|
|
@@ -35,15 +36,22 @@ const DefaultColumnFilter = ({
|
|
|
35
36
|
getOptionsForColumn = null,
|
|
36
37
|
onChange = null,
|
|
37
38
|
storeName = '',
|
|
38
|
-
style = null,
|
|
39
|
+
style = null,
|
|
39
40
|
}) => {
|
|
40
41
|
const store = useStore(storeName);
|
|
41
42
|
const peopleStore = useStore('people');
|
|
42
43
|
const configs = store?.getters?.configs || {};
|
|
44
|
+
const { resolvedAccentColor } = useDefaultTableTheme(accentColor);
|
|
43
45
|
const [loadedItems, setLoadedItems] = useState([]);
|
|
44
46
|
const [loadedKey, setLoadedKey] = useState('');
|
|
45
47
|
const fieldName = getColumnKey(column);
|
|
46
48
|
const currentCompanyId = peopleStore?.getters?.currentCompany?.id;
|
|
49
|
+
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
setLoadedItems([]);
|
|
52
|
+
setLoadedKey('');
|
|
53
|
+
}, [currentCompanyId]);
|
|
54
|
+
|
|
47
55
|
const requestChange = useCallback(
|
|
48
56
|
(nextFieldName, value) => {
|
|
49
57
|
if (typeof onChange === 'function') {
|
|
@@ -65,7 +73,10 @@ const DefaultColumnFilter = ({
|
|
|
65
73
|
const columns = Array.isArray(store?.getters?.columns) ? store.getters.columns : [];
|
|
66
74
|
const tablePreferenceScope =
|
|
67
75
|
configs.tablePreferenceScope ||
|
|
68
|
-
resolveDefaultTablePreferenceScope({
|
|
76
|
+
resolveDefaultTablePreferenceScope({
|
|
77
|
+
companyId: currentCompanyId,
|
|
78
|
+
storeName,
|
|
79
|
+
});
|
|
69
80
|
const persistedFilters = sanitizeTableFiltersPreference({
|
|
70
81
|
columns,
|
|
71
82
|
filters: nextFilters,
|
|
@@ -81,7 +92,7 @@ const DefaultColumnFilter = ({
|
|
|
81
92
|
|
|
82
93
|
configs.onFilterChange?.(nextFilters);
|
|
83
94
|
},
|
|
84
|
-
[configs, onChange, store, storeName],
|
|
95
|
+
[configs, currentCompanyId, onChange, store, storeName],
|
|
85
96
|
);
|
|
86
97
|
const resolveOptions = useCallback(
|
|
87
98
|
targetColumn => {
|
|
@@ -149,11 +160,11 @@ const DefaultColumnFilter = ({
|
|
|
149
160
|
loadedKey,
|
|
150
161
|
],
|
|
151
162
|
);
|
|
152
|
-
|
|
153
|
-
if (column?.filter === false || column?.filters === false) {
|
|
154
|
-
return <View style={style} />;
|
|
155
|
-
}
|
|
156
|
-
|
|
163
|
+
|
|
164
|
+
if (column?.filter === false || column?.filters === false) {
|
|
165
|
+
return <View style={style} />;
|
|
166
|
+
}
|
|
167
|
+
|
|
157
168
|
if (isDateLikeColumn(column)) {
|
|
158
169
|
const filterValue = filters?.[fieldName] || {};
|
|
159
170
|
return (
|
|
@@ -164,7 +175,7 @@ const DefaultColumnFilter = ({
|
|
|
164
175
|
field={fieldName}
|
|
165
176
|
labelCaption={global.t?.t(storeName, 'label', column?.label || fieldName)}
|
|
166
177
|
value={filterValue.shortcut || 'all'}
|
|
167
|
-
customRange={filterValue.customRange || { from: '', to: '' }}
|
|
178
|
+
customRange={filterValue.customRange || { from: '', to: '' }}
|
|
168
179
|
onChange={optionKey =>
|
|
169
180
|
requestChange(
|
|
170
181
|
fieldName,
|
|
@@ -175,25 +186,31 @@ const DefaultColumnFilter = ({
|
|
|
175
186
|
...(filterValue || {}),
|
|
176
187
|
shortcut: 'custom',
|
|
177
188
|
customRange: range,
|
|
178
|
-
})}
|
|
179
|
-
/>
|
|
180
|
-
</View>
|
|
181
|
-
);
|
|
182
|
-
}
|
|
183
|
-
|
|
189
|
+
})}
|
|
190
|
+
/>
|
|
191
|
+
</View>
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
184
195
|
if (column?.list) {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
196
|
+
/*
|
|
197
|
+
* @agents List options for filters must load only when the modal opens
|
|
198
|
+
* (onBeforeOpen). Falling back to the shared store items would show
|
|
199
|
+
* another company's payment types / wallets / categories.
|
|
200
|
+
*/
|
|
201
|
+
const explicitOptions = resolveOptions(column);
|
|
202
|
+
const rawOptions = Array.isArray(explicitOptions)
|
|
203
|
+
? mapOptions(column, explicitOptions, storeName)
|
|
204
|
+
: mapOptions(column, loadedItems, storeName);
|
|
188
205
|
const options = [
|
|
189
206
|
{ key: '', label: global.t?.t(storeName, 'label', 'select') },
|
|
190
207
|
...rawOptions,
|
|
191
208
|
];
|
|
192
|
-
const selectedKey = normalizeOptionKey(filters?.[fieldName]);
|
|
193
|
-
const selected = options.find(option => option.key === selectedKey);
|
|
194
|
-
|
|
195
|
-
return (
|
|
196
|
-
<View style={[style, styles.filterCell]}>
|
|
209
|
+
const selectedKey = normalizeOptionKey(filters?.[fieldName]);
|
|
210
|
+
const selected = options.find(option => option.key === selectedKey);
|
|
211
|
+
|
|
212
|
+
return (
|
|
213
|
+
<View style={[style, styles.filterCell]}>
|
|
197
214
|
<CompactFilterSelector
|
|
198
215
|
dense
|
|
199
216
|
store={storeName}
|
|
@@ -201,7 +218,7 @@ const DefaultColumnFilter = ({
|
|
|
201
218
|
icon="filter"
|
|
202
219
|
onBeforeOpen={onBeforeOpen || (() => loadListOptions())}
|
|
203
220
|
onSearchChange={onSearchChange || (value => loadListOptions(value))}
|
|
204
|
-
accentColor={
|
|
221
|
+
accentColor={resolvedAccentColor}
|
|
205
222
|
active={Boolean(selectedKey)}
|
|
206
223
|
label={selected?.label || options[0]?.label || ''}
|
|
207
224
|
options={options}
|
|
@@ -211,21 +228,21 @@ const DefaultColumnFilter = ({
|
|
|
211
228
|
requestChange(fieldName, optionKey);
|
|
212
229
|
return true;
|
|
213
230
|
}}
|
|
214
|
-
/>
|
|
215
|
-
</View>
|
|
216
|
-
);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
return (
|
|
220
|
-
<View style={[style, styles.filterCell]}>
|
|
221
|
-
<TextInput
|
|
231
|
+
/>
|
|
232
|
+
</View>
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return (
|
|
237
|
+
<View style={[style, styles.filterCell]}>
|
|
238
|
+
<TextInput
|
|
222
239
|
style={styles.filterInput}
|
|
223
240
|
value={normalizeText(filters?.[fieldName])}
|
|
224
241
|
placeholder={global.t?.t(storeName, 'input', column?.label || fieldName)}
|
|
225
242
|
onChangeText={value => requestChange(fieldName, value)}
|
|
226
243
|
/>
|
|
227
|
-
</View>
|
|
228
|
-
);
|
|
229
|
-
};
|
|
230
|
-
|
|
231
|
-
export default DefaultColumnFilter;
|
|
244
|
+
</View>
|
|
245
|
+
);
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
export default DefaultColumnFilter;
|