@controleonline/ui-default 1.0.263

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.
Files changed (56) hide show
  1. package/.github/agents/developer.agent.md +30 -0
  2. package/.github/agents/devops.agent.md +30 -0
  3. package/.github/agents/qa.agent.md +30 -0
  4. package/.github/agents/security.agent.md +30 -0
  5. package/.scrutinizer.yml +20 -0
  6. package/AGENTS.md +47 -0
  7. package/FUNDING.yml +1 -0
  8. package/package.json +21 -0
  9. package/src/react/components/errors/DefaultErrors.js +360 -0
  10. package/src/react/components/files/DefaultFile.js +46 -0
  11. package/src/react/components/filters/CompactFilterSelector.js +262 -0
  12. package/src/react/components/filters/CompactFilterSelector.styles.js +124 -0
  13. package/src/react/components/filters/DateShortcutFilter.js +264 -0
  14. package/src/react/components/filters/DateShortcutFilter.styles.js +82 -0
  15. package/src/react/components/filters/DefaultColumnFilter.js +97 -0
  16. package/src/react/components/filters/DefaultColumnFilter.styles.js +21 -0
  17. package/src/react/components/filters/DefaultExternalFilters.js +441 -0
  18. package/src/react/components/filters/DefaultExternalFilters.styles.js +177 -0
  19. package/src/react/components/filters/DefaultSearch.js +103 -0
  20. package/src/react/components/filters/DefaultSearch.styles.js +70 -0
  21. package/src/react/components/filters/dateFilterSelection.js +29 -0
  22. package/src/react/components/form/DefaultForm.js +198 -0
  23. package/src/react/components/form/DefaultForm.styles.js +70 -0
  24. package/src/react/components/help/DefaultTooltip.js +87 -0
  25. package/src/react/components/help/DefaultTooltip.styles.js +61 -0
  26. package/src/react/components/inputs/DefaultInput.js +160 -0
  27. package/src/react/components/inputs/DefaultInput.styles.js +93 -0
  28. package/src/react/components/inputs/DefaultSelect.js +192 -0
  29. package/src/react/components/inputs/DefaultSelect.styles.js +65 -0
  30. package/src/react/components/inputs/defaultInputUtils.js +230 -0
  31. package/src/react/components/map/DefaultGoogleMap.styles.js +9 -0
  32. package/src/react/components/map/DefaultGoogleMap.web.js +698 -0
  33. package/src/react/components/map/DefaultMap.native.js +71 -0
  34. package/src/react/components/map/DefaultMap.shared.js +762 -0
  35. package/src/react/components/map/DefaultMap.styles.js +16 -0
  36. package/src/react/components/map/DefaultMap.web.js +66 -0
  37. package/src/react/components/map/DefaultNativeMap.native.js +615 -0
  38. package/src/react/components/map/DefaultNativeMap.shared.js +532 -0
  39. package/src/react/components/map/DefaultNativeMap.styles.js +122 -0
  40. package/src/react/components/table/DefaultTable.js +1897 -0
  41. package/src/react/components/table/DefaultTable.styles.js +610 -0
  42. package/src/react/index.js +10 -0
  43. package/src/react/utils/tableVisibleColumnsPreferences.js +264 -0
  44. package/src/store/default/actions.js +444 -0
  45. package/src/store/default/getters.js +28 -0
  46. package/src/store/default/mutation_types.js +26 -0
  47. package/src/store/default/mutations.js +138 -0
  48. package/src/tests/react/components/DateShortcutFilter.test.js +96 -0
  49. package/src/tests/react/components/errors/DefaultErrors.test.js +162 -0
  50. package/src/tests/react/components/files/DefaultFile.test.js +80 -0
  51. package/src/tests/react/components/map/DefaultMap.shared.test.js +162 -0
  52. package/src/tests/react/filters/dateFilterSelection.test.js +46 -0
  53. package/src/tests/react/inputs/defaultInputUtils.test.js +45 -0
  54. package/src/tests/react/store/defaultActions.test.js +112 -0
  55. package/src/tests/react/utils/tableVisibleColumnsPreferences.test.js +223 -0
  56. package/src/utils/filters.js +56 -0
@@ -0,0 +1,230 @@
1
+ import { getAllStores } from '@store';
2
+ import Formatter from '@controleonline/ui-common/src/utils/formatter.js';
3
+ import { formatStoreColumnValue } from '@controleonline/ui-common/src/react/utils/storeColumns';
4
+
5
+ export const normalizeText = value => String(value ?? '').trim();
6
+ const formatHumanLabel = value =>
7
+ normalizeText(value)
8
+ .replace(/([a-z])([A-Z])/g, '$1 $2')
9
+ .replace(/[_-]+/g, ' ')
10
+ .replace(/^\w/, letter => letter.toUpperCase());
11
+ const DEFAULT_TRANSLATABLE_FIELDS = new Set([
12
+ 'active',
13
+ 'app',
14
+ 'channel',
15
+ 'displaytype',
16
+ 'featured',
17
+ 'frequency',
18
+ 'invoicetype',
19
+ 'installments',
20
+ 'ordertype',
21
+ 'peopletype',
22
+ 'pricecalculation',
23
+ 'productcondition',
24
+ 'realstatus',
25
+ 'status',
26
+ ]);
27
+
28
+ export const getColumnKey = column => column?.key || column?.name || '';
29
+
30
+ const normalizeColumnKey = value =>
31
+ normalizeText(value)
32
+ .replace(/[^a-zA-Z0-9]/g, '')
33
+ .toLowerCase();
34
+
35
+ const shouldTranslateOptionLabel = (column, storeName, rawLabel) => {
36
+ if (column?.translate === false || !normalizeText(rawLabel) || !normalizeText(storeName)) {
37
+ return false;
38
+ }
39
+
40
+ if (column?.translate === true || Array.isArray(column?.list)) {
41
+ return true;
42
+ }
43
+
44
+ return [column?.key, column?.name, column?.label]
45
+ .map(normalizeColumnKey)
46
+ .filter(Boolean)
47
+ .some(candidate => DEFAULT_TRANSLATABLE_FIELDS.has(candidate));
48
+ };
49
+
50
+ export const normalizeId = value => {
51
+ if (!value) return '';
52
+ if (typeof value === 'number') return String(value);
53
+ if (typeof value === 'string') {
54
+ const match = value.match(/\d+/g);
55
+ return match ? match[match.length - 1] : value;
56
+ }
57
+ return normalizeId(value?.id || value?.['@id'] || '');
58
+ };
59
+
60
+ export const isEditableColumn = column =>
61
+ column?.editable !== false &&
62
+ !column?.isIdentity &&
63
+ column?.inputType !== 'increase' &&
64
+ column?.inputType !== 'image' &&
65
+ !String(getColumnKey(column)).includes('.');
66
+
67
+ export const normalizeOptionKey = option => {
68
+ if (!option) return '';
69
+ if (typeof option !== 'object') return normalizeId(option) || normalizeText(option);
70
+ return normalizeText(
71
+ option.value ??
72
+ option.id ??
73
+ normalizeId(option['@id']) ??
74
+ option.key ??
75
+ '',
76
+ );
77
+ };
78
+
79
+ export const resolveOptionLabel = (column, option, storeName = '') => {
80
+ if (!option) return '';
81
+
82
+ const translateOptionLabel = rawLabel => {
83
+ const normalizedLabel = normalizeText(rawLabel);
84
+ if (!shouldTranslateOptionLabel(column, storeName, normalizedLabel)) {
85
+ return normalizedLabel;
86
+ }
87
+
88
+ const translated = global.t?.t(storeName, 'label', normalizedLabel) || normalizedLabel;
89
+ return normalizeText(translated) === formatHumanLabel(normalizedLabel)
90
+ ? normalizedLabel
91
+ : translated;
92
+ };
93
+
94
+ if (typeof column?.formatList === 'function') {
95
+ const formatted = column.formatList(option, null, column);
96
+ if (formatted && typeof formatted === 'object') {
97
+ return translateOptionLabel(formatted.label ?? formatted.value);
98
+ }
99
+ if (formatted) return translateOptionLabel(formatted);
100
+ }
101
+
102
+ const rawLabel = normalizeText(
103
+ option.label ??
104
+ option[column?.searchParam] ??
105
+ option[column?.name] ??
106
+ option.name ??
107
+ option.status ??
108
+ option.wallet ??
109
+ option.paymentType ??
110
+ option.alias ??
111
+ option.id,
112
+ );
113
+
114
+ return translateOptionLabel(rawLabel);
115
+ };
116
+
117
+ export const resolveStoreNameFromList = list => normalizeText(list).split('/')[0] || '';
118
+
119
+ const filterItemsByListRequestParams = (items = [], column = null) => {
120
+ const requestParams =
121
+ column?.listRequestParams &&
122
+ typeof column.listRequestParams === 'object' &&
123
+ !Array.isArray(column.listRequestParams)
124
+ ? column.listRequestParams
125
+ : null;
126
+
127
+ if (!requestParams || Object.keys(requestParams).length === 0) {
128
+ return Array.isArray(items) ? items : [];
129
+ }
130
+
131
+ return (Array.isArray(items) ? items : []).filter(item =>
132
+ Object.entries(requestParams).every(([key, expectedValue]) => {
133
+ if (expectedValue === undefined || expectedValue === null || expectedValue === '') {
134
+ return true;
135
+ }
136
+
137
+ return normalizeText(item?.[key]) === normalizeText(expectedValue);
138
+ }),
139
+ );
140
+ };
141
+
142
+ export const mapOptions = (column, items = [], storeName = '') => {
143
+ const seenKeys = new Set();
144
+ const options = [];
145
+
146
+ (Array.isArray(items) ? items : []).forEach(item => {
147
+ const formatted =
148
+ typeof column?.formatList === 'function'
149
+ ? column.formatList(item, null, column)
150
+ : item;
151
+ const key = normalizeOptionKey(formatted) || normalizeOptionKey(item);
152
+ const dedupeKey = key || normalizeText(resolveOptionLabel(column, item, storeName)).toLowerCase();
153
+
154
+ if (dedupeKey && seenKeys.has(dedupeKey)) return;
155
+ if (dedupeKey) seenKeys.add(dedupeKey);
156
+
157
+ options.push({
158
+ key,
159
+ label: resolveOptionLabel(column, item, storeName) || '-',
160
+ raw: item,
161
+ });
162
+ });
163
+
164
+ return options;
165
+ };
166
+
167
+ export const buildOptionsFromColumn = (column, getOptionsForColumn = null, storeName = '') => {
168
+ const explicitOptions = getOptionsForColumn?.(column);
169
+ if (Array.isArray(explicitOptions) && explicitOptions.length > 0) {
170
+ return mapOptions(column, explicitOptions, storeName);
171
+ }
172
+
173
+ const listStoreName = resolveStoreNameFromList(column?.list);
174
+ if (!listStoreName) return [];
175
+
176
+ const listStore = getAllStores()?.[listStoreName];
177
+ return mapOptions(
178
+ column,
179
+ filterItemsByListRequestParams(listStore?.getters?.items || [], column),
180
+ storeName,
181
+ );
182
+ };
183
+
184
+ export const resolveCellText = ({ column, columns = [], row, storeName, value }) => {
185
+ const fieldName = getColumnKey(column);
186
+ const rawValue = value ?? row?.[fieldName];
187
+ const formattedValue = formatStoreColumnValue({
188
+ columns: columns.length ? columns : [column],
189
+ fieldName,
190
+ row,
191
+ storeName,
192
+ value: rawValue,
193
+ });
194
+
195
+ return normalizeText(formattedValue) || '-';
196
+ };
197
+
198
+ export const resolveEditValue = (column, row, value) => {
199
+ const rawValue = value ?? row?.[getColumnKey(column)];
200
+ if (column?.list) {
201
+ return normalizeOptionKey(
202
+ typeof column?.formatList === 'function'
203
+ ? column.formatList(rawValue, row, column)
204
+ : rawValue,
205
+ );
206
+ }
207
+
208
+ if (typeof column?.editFormat === 'function') {
209
+ return normalizeText(column.editFormat(rawValue, column, row, true));
210
+ }
211
+
212
+ if ((column?.inputType === 'date' || column?.inputType === 'date-range') && rawValue) {
213
+ return normalizeText(Formatter.formatDateYmdTodmY(rawValue));
214
+ }
215
+
216
+ return normalizeText(rawValue);
217
+ };
218
+
219
+ export const formatSaveValue = (column, value, row) => {
220
+ if (typeof column?.saveFormat === 'function') {
221
+ return column.saveFormat(value, column, row);
222
+ }
223
+
224
+ if (value && typeof value === 'object') {
225
+ if (value.value) return Number.isNaN(Number(value.value)) ? value.value : Number(value.value);
226
+ if (value['@id']) return value['@id'];
227
+ }
228
+
229
+ return Number.isNaN(Number(value)) || value === '' ? value : Number(value);
230
+ };
@@ -0,0 +1,9 @@
1
+ import {StyleSheet} from 'react-native';
2
+
3
+ export default StyleSheet.create({
4
+ mapViewport: {
5
+ width: '100%',
6
+ height: '100%',
7
+ backgroundColor: '#E5EEF5',
8
+ },
9
+ });