@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,46 @@
1
+ const {
2
+ resolveNextDateFilterValue,
3
+ } = require('../../../react/components/filters/dateFilterSelection');
4
+
5
+ const { describe, expect, it } = global;
6
+
7
+ describe('dateFilterSelection', () => {
8
+ it('clears the filter when all is selected', () => {
9
+ expect(
10
+ resolveNextDateFilterValue(
11
+ {
12
+ shortcut: 'custom',
13
+ customRange: { from: '2026-06-01', to: '2026-06-28' },
14
+ },
15
+ 'all',
16
+ ),
17
+ ).toBeNull();
18
+ });
19
+
20
+ it('preserves the custom range when the custom option is confirmed', () => {
21
+ const currentValue = {
22
+ shortcut: 'custom',
23
+ customRange: { from: '2026-06-01', to: '2026-06-28' },
24
+ };
25
+
26
+ expect(
27
+ resolveNextDateFilterValue(currentValue, 'custom'),
28
+ ).toEqual(currentValue);
29
+ });
30
+
31
+ it('keeps the current custom range when switching to a shortcut', () => {
32
+ expect(
33
+ resolveNextDateFilterValue(
34
+ {
35
+ shortcut: 'custom',
36
+ customRange: { from: '2026-06-10', to: '2026-06-12' },
37
+ },
38
+ '30d',
39
+ ),
40
+ ).toEqual({
41
+ shortcut: '30d',
42
+ customRange: { from: '2026-06-10', to: '2026-06-12' },
43
+ });
44
+ });
45
+ });
46
+
@@ -0,0 +1,45 @@
1
+ const {describe, expect, it, jest} = require('@jest/globals');
2
+
3
+ jest.mock('@store', () => ({
4
+ getAllStores: () => ({}),
5
+ }));
6
+
7
+ jest.mock('@controleonline/ui-common/src/utils/formatter.js', () => ({}));
8
+
9
+ jest.mock('@controleonline/ui-common/src/react/utils/storeColumns', () => ({
10
+ formatStoreColumnValue: ({value}) => value,
11
+ }));
12
+
13
+ const {mapOptions} = require('../../../react/components/inputs/defaultInputUtils');
14
+
15
+ describe('defaultInputUtils', () => {
16
+ it('deduplicates list options by normalized key', () => {
17
+ const column = {
18
+ formatList(item) {
19
+ return {
20
+ value: item.id,
21
+ label: item.wallet,
22
+ };
23
+ },
24
+ };
25
+
26
+ const options = mapOptions(column, [
27
+ {id: 4584, wallet: 'Cielo'},
28
+ {id: 4584, wallet: 'Cielo'},
29
+ {id: 4579, wallet: 'Cielo'},
30
+ ]);
31
+
32
+ expect(options).toEqual([
33
+ {
34
+ key: '4584',
35
+ label: 'Cielo',
36
+ raw: {id: 4584, wallet: 'Cielo'},
37
+ },
38
+ {
39
+ key: '4579',
40
+ label: 'Cielo',
41
+ raw: {id: 4579, wallet: 'Cielo'},
42
+ },
43
+ ]);
44
+ });
45
+ });
@@ -0,0 +1,112 @@
1
+ /* global describe, expect, it */
2
+
3
+ global.localStorage = {
4
+ getItem: jest.fn(() => null),
5
+ setItem: jest.fn(),
6
+ removeItem: jest.fn(),
7
+ }
8
+
9
+ jest.mock('@controleonline/ui-common/src/api', () => ({
10
+ api: {
11
+ fetch: jest.fn(),
12
+ },
13
+ }))
14
+
15
+ const {api} = require('@controleonline/ui-common/src/api')
16
+ const types = require('../../../store/default/mutation_types')
17
+ const {
18
+ STORE_ACTION_META_KEY,
19
+ splitStoreActionPayload,
20
+ buildStoreErrorCommitOptions,
21
+ get,
22
+ } = require('../../../store/default/actions')
23
+
24
+ describe('default store action controls', () => {
25
+ beforeEach(() => {
26
+ api.fetch.mockReset()
27
+ })
28
+
29
+ it('separates local store metadata from the request payload', () => {
30
+ const input = {
31
+ id: '15',
32
+ phone: 925578229,
33
+ [STORE_ACTION_META_KEY]: {
34
+ skipSystemError: true,
35
+ dedupeKey: 'phone-save',
36
+ },
37
+ }
38
+
39
+ const result = splitStoreActionPayload(input)
40
+
41
+ expect(result).toEqual({
42
+ payload: {
43
+ id: '15',
44
+ phone: 925578229,
45
+ },
46
+ storeMeta: {
47
+ skipSystemError: true,
48
+ dedupeKey: 'phone-save',
49
+ },
50
+ })
51
+ expect(input[STORE_ACTION_META_KEY]).toEqual({
52
+ skipSystemError: true,
53
+ dedupeKey: 'phone-save',
54
+ })
55
+ })
56
+
57
+ it('builds commit options only from supported metadata', () => {
58
+ expect(
59
+ buildStoreErrorCommitOptions({
60
+ skipSystemError: true,
61
+ dedupeKey: 'contact-save',
62
+ providerKey: 'modal',
63
+ position: 'top',
64
+ ignored: true,
65
+ }),
66
+ ).toEqual({
67
+ skipSystemError: true,
68
+ dedupeKey: 'contact-save',
69
+ providerKey: 'modal',
70
+ position: 'top',
71
+ })
72
+ })
73
+
74
+ it('keeps the current item mounted while reloading when preserveItem is requested', async () => {
75
+ api.fetch.mockResolvedValue({
76
+ '@id': '/orders/15',
77
+ id: 15,
78
+ name: 'Pedido atualizado',
79
+ })
80
+
81
+ const commit = jest.fn()
82
+ const getters = {
83
+ resourceEndpoint: 'orders',
84
+ item: {
85
+ '@id': '/orders/15',
86
+ id: 15,
87
+ name: 'Pedido antigo',
88
+ },
89
+ }
90
+
91
+ await get(
92
+ {commit, getters},
93
+ {
94
+ id: '15',
95
+ [STORE_ACTION_META_KEY]: {
96
+ preserveItem: true,
97
+ },
98
+ },
99
+ )
100
+
101
+ expect(api.fetch).toHaveBeenCalledWith('orders/15', {})
102
+ expect(commit).toHaveBeenCalledWith(types.SET_ISLOADING, true)
103
+ expect(commit).toHaveBeenCalledWith(types.SET_ERROR, null)
104
+ expect(commit).not.toHaveBeenCalledWith(types.SET_ITEM, {})
105
+ expect(commit).toHaveBeenCalledWith(types.SET_ITEM, {
106
+ '@id': '/orders/15',
107
+ id: 15,
108
+ name: 'Pedido atualizado',
109
+ })
110
+ expect(commit).toHaveBeenCalledWith(types.SET_ISLOADING, false)
111
+ })
112
+ })
@@ -0,0 +1,223 @@
1
+ const {
2
+ DEFAULT_TABLE_PREFERENCES_STORAGE_KEY,
3
+ TABLE_SORT_DIRECTION_PREFERENCES_KEY,
4
+ TABLE_SORT_FIELD_PREFERENCES_KEY,
5
+ TABLE_SORT_PREFERENCES_KEY,
6
+ TABLE_VISIBLE_COLUMNS_PREFERENCES_KEY,
7
+ TABLE_VIEW_MODE_PREFERENCES_KEY,
8
+ buildDefaultVisibleColumns,
9
+ persistTableSortPreference,
10
+ persistTableViewModePreference,
11
+ persistVisibleColumnsPreference,
12
+ resolveStoredTableSortPreference,
13
+ resolveStoredTableViewModePreference,
14
+ resolveStoredVisibleColumnsPreference,
15
+ sanitizeVisibleColumnsPreference,
16
+ } = require('../../../react/utils/tableVisibleColumnsPreferences');
17
+
18
+ const { beforeEach, describe, expect, it } = global;
19
+
20
+ const createLocalStorageMock = () => {
21
+ let storage = {};
22
+
23
+ return {
24
+ clear: () => {
25
+ storage = {};
26
+ },
27
+ getItem: key => (key in storage ? storage[key] : null),
28
+ removeItem: key => {
29
+ delete storage[key];
30
+ },
31
+ setItem: (key, value) => {
32
+ storage[key] = String(value);
33
+ },
34
+ };
35
+ };
36
+
37
+ describe('tableVisibleColumnsPreferences', () => {
38
+ const columns = [
39
+ { name: 'id' },
40
+ { name: 'status' },
41
+ { name: 'price', visible: false },
42
+ ];
43
+
44
+ beforeEach(() => {
45
+ global.localStorage = createLocalStorageMock();
46
+ });
47
+
48
+ it('builds the default visibility map from store columns', () => {
49
+ expect(buildDefaultVisibleColumns(columns)).toEqual({
50
+ id: true,
51
+ status: true,
52
+ price: false,
53
+ });
54
+ });
55
+
56
+ it('sanitizes stored preferences against the current columns', () => {
57
+ expect(
58
+ sanitizeVisibleColumnsPreference({
59
+ columns,
60
+ visibleColumns: {
61
+ id: false,
62
+ unknown: true,
63
+ },
64
+ }),
65
+ ).toEqual({
66
+ id: false,
67
+ status: true,
68
+ price: false,
69
+ });
70
+ });
71
+
72
+ it('reads and writes visible columns preferences under the per-page bucket', () => {
73
+ global.localStorage.setItem(
74
+ DEFAULT_TABLE_PREFERENCES_STORAGE_KEY,
75
+ JSON.stringify({
76
+ theme: 'light',
77
+ [TABLE_VISIBLE_COLUMNS_PREFERENCES_KEY]: {
78
+ 'financialEntries:receivables': {
79
+ id: false,
80
+ },
81
+ },
82
+ }),
83
+ );
84
+
85
+ expect(
86
+ resolveStoredVisibleColumnsPreference('financialEntries:receivables'),
87
+ ).toEqual({
88
+ id: false,
89
+ });
90
+
91
+ persistVisibleColumnsPreference('financialEntries:payables', {
92
+ id: true,
93
+ status: false,
94
+ });
95
+
96
+ expect(
97
+ JSON.parse(
98
+ global.localStorage.getItem(DEFAULT_TABLE_PREFERENCES_STORAGE_KEY),
99
+ ),
100
+ ).toEqual({
101
+ theme: 'light',
102
+ [TABLE_VISIBLE_COLUMNS_PREFERENCES_KEY]: {
103
+ 'financialEntries:receivables': {
104
+ id: false,
105
+ },
106
+ 'financialEntries:payables': {
107
+ id: true,
108
+ status: false,
109
+ },
110
+ },
111
+ });
112
+ });
113
+
114
+ it('reads and writes the preferred table view mode by page', () => {
115
+ global.localStorage.setItem(
116
+ DEFAULT_TABLE_PREFERENCES_STORAGE_KEY,
117
+ JSON.stringify({
118
+ [TABLE_VIEW_MODE_PREFERENCES_KEY]: {
119
+ 'financialEntries:payables': 'cards',
120
+ },
121
+ }),
122
+ );
123
+
124
+ expect(
125
+ resolveStoredTableViewModePreference(
126
+ 'financialEntries:payables',
127
+ 'table',
128
+ ),
129
+ ).toBe('cards');
130
+
131
+ expect(
132
+ resolveStoredTableViewModePreference(
133
+ 'financialEntries:receivables',
134
+ 'table',
135
+ ),
136
+ ).toBe('table');
137
+
138
+ persistTableViewModePreference('financialEntries:receivables', 'table');
139
+
140
+ expect(
141
+ JSON.parse(
142
+ global.localStorage.getItem(DEFAULT_TABLE_PREFERENCES_STORAGE_KEY),
143
+ ),
144
+ ).toEqual({
145
+ [TABLE_VIEW_MODE_PREFERENCES_KEY]: {
146
+ 'financialEntries:payables': 'cards',
147
+ 'financialEntries:receivables': 'table',
148
+ },
149
+ });
150
+ });
151
+
152
+ it('reads and writes the preferred sort by page', () => {
153
+ global.localStorage.setItem(
154
+ DEFAULT_TABLE_PREFERENCES_STORAGE_KEY,
155
+ JSON.stringify({
156
+ [TABLE_SORT_FIELD_PREFERENCES_KEY]: {
157
+ 'financialEntries:payables': 'price',
158
+ },
159
+ [TABLE_SORT_DIRECTION_PREFERENCES_KEY]: {
160
+ 'financialEntries:payables': 'asc',
161
+ },
162
+ }),
163
+ );
164
+
165
+ expect(
166
+ resolveStoredTableSortPreference('financialEntries:payables'),
167
+ ).toEqual({
168
+ direction: 'asc',
169
+ field: 'price',
170
+ });
171
+
172
+ expect(
173
+ resolveStoredTableSortPreference('financialEntries:receivables'),
174
+ ).toBeNull();
175
+
176
+ persistTableSortPreference('financialEntries:receivables', {
177
+ direction: 'desc',
178
+ field: 'dueDate',
179
+ });
180
+
181
+ expect(
182
+ JSON.parse(
183
+ global.localStorage.getItem(DEFAULT_TABLE_PREFERENCES_STORAGE_KEY),
184
+ ),
185
+ ).toEqual({
186
+ [TABLE_SORT_FIELD_PREFERENCES_KEY]: {
187
+ 'financialEntries:payables': 'price',
188
+ 'financialEntries:receivables': 'dueDate',
189
+ },
190
+ [TABLE_SORT_DIRECTION_PREFERENCES_KEY]: {
191
+ 'financialEntries:payables': 'asc',
192
+ 'financialEntries:receivables': 'desc',
193
+ },
194
+ [TABLE_SORT_PREFERENCES_KEY]: {
195
+ 'financialEntries:receivables': {
196
+ direction: 'desc',
197
+ field: 'dueDate',
198
+ },
199
+ },
200
+ });
201
+ });
202
+
203
+ it('keeps reading the legacy combined sort format when needed', () => {
204
+ global.localStorage.setItem(
205
+ DEFAULT_TABLE_PREFERENCES_STORAGE_KEY,
206
+ JSON.stringify({
207
+ [TABLE_SORT_PREFERENCES_KEY]: {
208
+ 'financialEntries:ownTransfers': {
209
+ direction: 'asc',
210
+ field: 'createdAt',
211
+ },
212
+ },
213
+ }),
214
+ );
215
+
216
+ expect(
217
+ resolveStoredTableSortPreference('financialEntries:ownTransfers'),
218
+ ).toEqual({
219
+ direction: 'asc',
220
+ field: 'createdAt',
221
+ });
222
+ });
223
+ });
@@ -0,0 +1,56 @@
1
+ export default class Filters {
2
+ constructor(route, store) {
3
+ this.route = route;
4
+ this.store = store;
5
+ }
6
+
7
+ getFilters() {
8
+ if (!this.getRoute() || !this.store) return {};
9
+ const storedUser = this.getAllFilters();
10
+ return storedUser && storedUser[this.getRoute()]
11
+ ? storedUser[this.getRoute()][this.store] || {}
12
+ : {};
13
+ }
14
+
15
+ setFilters(data) {
16
+ if (!this.getRoute() || !this.store) return;
17
+ const storedUser = this.getAllFilters();
18
+ if (!storedUser[this.getRoute()]) {
19
+ storedUser[this.getRoute()] = {};
20
+ }
21
+ storedUser[this.getRoute()][this.store] = data;
22
+ localStorage.setItem('DefaultFilters', JSON.stringify(storedUser));
23
+ }
24
+
25
+ getVisibleColumns() {
26
+ if (!this.getRoute() || !this.store) return {};
27
+ const storedUser = this.getAllVisibleColumns();
28
+ return storedUser && storedUser[this.getRoute()]
29
+ ? storedUser[this.getRoute()][this.store] || {}
30
+ : {};
31
+ }
32
+
33
+ setVisibleColumns(visibleColumns) {
34
+ if (!this.getRoute() || !this.store) return;
35
+ const storedUser = this.getAllVisibleColumns();
36
+ if (!storedUser[this.getRoute()]) {
37
+ storedUser[this.getRoute()] = {};
38
+ }
39
+ storedUser[this.getRoute()][this.store] = visibleColumns;
40
+ localStorage.setItem('DefaultVisibleColumns', JSON.stringify(storedUser));
41
+ }
42
+
43
+ getAllFilters() {
44
+ const data = localStorage.getItem('DefaultFilters');
45
+ return data ? JSON.parse(data) : {};
46
+ }
47
+
48
+ getRoute() {
49
+ return this.route;
50
+ }
51
+
52
+ getAllVisibleColumns() {
53
+ const data = localStorage.getItem('DefaultVisibleColumns');
54
+ return data ? JSON.parse(data) : {};
55
+ }
56
+ }