@controleonline/ui-default 1.0.263 → 1.0.265

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 (61) hide show
  1. package/AGENTS.md +47 -45
  2. package/package.json +20 -20
  3. package/src/react/components/errors/DefaultErrors.js +307 -325
  4. package/src/react/components/files/DefaultFile.js +46 -46
  5. package/src/react/components/filters/CompactFilterSelector.js +78 -24
  6. package/src/react/components/filters/CompactFilterSelector.styles.js +17 -5
  7. package/src/react/components/filters/DefaultColumnFilter.js +191 -57
  8. package/src/react/components/filters/DefaultExternalFilters.js +245 -182
  9. package/src/react/components/filters/DefaultSearch.js +131 -92
  10. package/src/react/components/filters/DefaultSearch.styles.js +65 -70
  11. package/src/react/components/form/DefaultForm.js +172 -151
  12. package/src/react/components/form/DefaultForm.styles.js +71 -66
  13. package/src/react/components/help/DefaultTooltip.js +87 -87
  14. package/src/react/components/help/DefaultTooltip.styles.js +61 -61
  15. package/src/react/components/inputs/DefaultDateInput.js +150 -0
  16. package/src/react/components/inputs/DefaultInput.js +162 -127
  17. package/src/react/components/inputs/DefaultInput.styles.js +6 -0
  18. package/src/react/components/inputs/DefaultSelect.js +320 -152
  19. package/src/react/components/inputs/defaultInputUtils.js +40 -19
  20. package/src/react/components/map/DefaultGoogleMap.styles.js +115 -9
  21. package/src/react/components/map/DefaultGoogleMap.web.js +560 -446
  22. package/src/react/components/map/DefaultMap.native.js +73 -71
  23. package/src/react/components/map/DefaultMap.styles.js +16 -16
  24. package/src/react/components/map/DefaultMap.web.js +68 -66
  25. package/src/react/components/map/DefaultNativeMap.native.js +307 -183
  26. package/src/react/components/map/DefaultNativeMap.shared.js +439 -340
  27. package/src/react/components/map/DefaultNativeMap.styles.js +156 -122
  28. package/src/react/components/table/DefaultColumnMenu.js +108 -0
  29. package/src/react/components/table/DefaultDebug.js +233 -0
  30. package/src/react/components/table/DefaultFiltersModal.js +142 -0
  31. package/src/react/components/table/DefaultModalButton.js +18 -0
  32. package/src/react/components/table/DefaultSearchModal.js +49 -0
  33. package/src/react/components/table/DefaultTable.js +345 -1846
  34. package/src/react/components/table/DefaultTable.styles.js +247 -136
  35. package/src/react/components/table/DefaultTable.utils.js +502 -0
  36. package/src/react/components/table/DefaultTableBody.js +26 -0
  37. package/src/react/components/table/DefaultTableCards.js +171 -0
  38. package/src/react/components/table/DefaultTableControls.js +208 -0
  39. package/src/react/components/table/DefaultTableEmptyState.js +22 -0
  40. package/src/react/components/table/DefaultTableFooter.js +172 -0
  41. package/src/react/components/table/DefaultTableInput.js +145 -0
  42. package/src/react/components/table/DefaultTableRows.js +340 -0
  43. package/src/react/components/table/DefaultTableSearch.js +100 -0
  44. package/src/react/components/table/DefaultTableToolbar.js +98 -0
  45. package/src/react/components/table/DefaultToolbarAction.js +56 -0
  46. package/src/react/components/table/useDefaultTablePagination.js +370 -0
  47. package/src/react/components/table/useDefaultTableSorting.js +126 -0
  48. package/src/react/components/table/useDefaultTableTheme.js +58 -0
  49. package/src/react/index.js +10 -10
  50. package/src/react/utils/tableVisibleColumnsPreferences.js +239 -211
  51. package/src/store/default/actions.js +51 -13
  52. package/src/store/default/getters.js +10 -8
  53. package/src/store/default/mutation_types.js +4 -2
  54. package/src/store/default/mutations.js +10 -1
  55. package/src/tests/react/components/errors/DefaultErrors.test.js +162 -162
  56. package/src/tests/react/components/files/DefaultFile.test.js +80 -80
  57. package/src/tests/react/components/form/DefaultForm.test.js +81 -0
  58. package/src/tests/react/components/inputs/DefaultSelect.test.js +185 -0
  59. package/src/tests/react/components/table/DefaultTable.test.js +1183 -0
  60. package/src/tests/react/store/defaultActions.test.js +59 -0
  61. package/src/tests/react/utils/tableVisibleColumnsPreferences.test.js +247 -168
@@ -1,162 +1,162 @@
1
- const React = require('react');
2
- const renderer = require('react-test-renderer');
3
- const {jest} = require('@jest/globals');
4
-
5
- const {afterEach, beforeEach, describe, expect, it} = global;
6
-
7
- global.IS_REACT_ACT_ENVIRONMENT = true;
8
-
9
- let mockStores = {};
10
- let consoleErrorSpy = null;
11
-
12
- jest.mock('@store', () => ({
13
- useStore: jest.fn(name => {
14
- if (name === 'theme') {
15
- return {
16
- getters: {
17
- colors: {
18
- inputErrorBackground: '#FEF2F2',
19
- inputErrorBorder: '#DC2626',
20
- inputErrorText: '#B91C1C',
21
- modalBackground: '#FFFFFF',
22
- modalBorder: '#DC2626',
23
- modalCloseIcon: '#B91C1C',
24
- modalOverlay: 'rgba(15, 23, 42, 0.55)',
25
- modalText: '#334155',
26
- primary: '#0EA5E9',
27
- textDanger: '#DC2626',
28
- },
29
- },
30
- };
31
- }
32
-
33
- return mockStores[name] || {actions: {}, getters: {}};
34
- }),
35
- useStores: jest.fn(selector =>
36
- (typeof selector === 'function' ? selector(mockStores) : mockStores),
37
- ),
38
- }));
39
-
40
- jest.mock('react-native', () => {
41
- const React = require('react');
42
- const createComponent = name => props =>
43
- React.createElement(name, props, props.children);
44
-
45
- return {
46
- Modal: props => React.createElement('modal', props, props.children),
47
- Pressable: props => React.createElement('pressable', props, props.children),
48
- StyleSheet: {
49
- create: styles => styles,
50
- },
51
- Text: createComponent('text'),
52
- TouchableOpacity: createComponent('touchable-opacity'),
53
- View: createComponent('view'),
54
- };
55
- });
56
-
57
- const DefaultErrors =
58
- require('../../../../react/components/errors/DefaultErrors').default;
59
-
60
- const getTextNodes = tree =>
61
- tree.root
62
- .findAllByType('text')
63
- .map(node => (Array.isArray(node.children) ? node.children.join('') : ''))
64
- .filter(Boolean);
65
-
66
- describe('DefaultErrors', () => {
67
- beforeEach(() => {
68
- jest.useFakeTimers();
69
- consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
70
- mockStores = {
71
- orders: {
72
- actions: {
73
- setError: jest.fn(),
74
- },
75
- getters: {
76
- error: 'Falha ao salvar.',
77
- },
78
- },
79
- };
80
- });
81
-
82
- afterEach(() => {
83
- if (consoleErrorSpy) {
84
- consoleErrorSpy.mockRestore();
85
- consoleErrorSpy = null;
86
- }
87
-
88
- jest.clearAllTimers();
89
- jest.useRealTimers();
90
- });
91
-
92
- it('renders the store error in a popup and clears the store when closed', () => {
93
- let tree;
94
-
95
- renderer.act(() => {
96
- tree = renderer.create(
97
- React.createElement(DefaultErrors, {
98
- store: 'orders',
99
- title: 'Nao foi possivel concluir',
100
- }),
101
- );
102
- });
103
-
104
- expect(tree.root.findByType('modal').props.visible).toBe(true);
105
- expect(getTextNodes(tree)).toEqual(
106
- expect.arrayContaining([
107
- 'Nao foi possivel concluir',
108
- 'Falha ao salvar.',
109
- '×',
110
- ]),
111
- );
112
-
113
- const closeButton = tree.root.findByProps({testID: 'default-errors-close'});
114
-
115
- renderer.act(() => {
116
- closeButton.props.onPress();
117
- });
118
-
119
- expect(mockStores.orders.actions.setError).toHaveBeenCalledWith('');
120
- expect(tree.toJSON()).toBeNull();
121
- });
122
-
123
- it('renders an explicit popup even without a store binding', () => {
124
- let tree;
125
-
126
- renderer.act(() => {
127
- tree = renderer.create(
128
- React.createElement(DefaultErrors, {
129
- title: 'Pedido nao informado.',
130
- }),
131
- );
132
- });
133
-
134
- expect(tree.root.findByType('modal').props.visible).toBe(true);
135
- expect(getTextNodes(tree)).toEqual(
136
- expect.arrayContaining([
137
- 'Pedido nao informado.',
138
- '×',
139
- ]),
140
- );
141
- });
142
-
143
- it('auto closes after five seconds and clears the store error', () => {
144
- let tree;
145
-
146
- renderer.act(() => {
147
- tree = renderer.create(
148
- React.createElement(DefaultErrors, {
149
- store: 'orders',
150
- title: 'Nao foi possivel concluir',
151
- }),
152
- );
153
- });
154
-
155
- renderer.act(() => {
156
- jest.advanceTimersByTime(5000);
157
- });
158
-
159
- expect(mockStores.orders.actions.setError).toHaveBeenCalledWith('');
160
- expect(tree.toJSON()).toBeNull();
161
- });
162
- });
1
+ const React = require('react');
2
+ const renderer = require('react-test-renderer');
3
+ const {jest} = require('@jest/globals');
4
+
5
+ const {afterEach, beforeEach, describe, expect, it} = global;
6
+
7
+ global.IS_REACT_ACT_ENVIRONMENT = true;
8
+
9
+ let mockStores = {};
10
+ let consoleErrorSpy = null;
11
+
12
+ jest.mock('@store', () => ({
13
+ useStore: jest.fn(name => {
14
+ if (name === 'theme') {
15
+ return {
16
+ getters: {
17
+ colors: {
18
+ inputErrorBackground: '#FEF2F2',
19
+ inputErrorBorder: '#DC2626',
20
+ inputErrorText: '#B91C1C',
21
+ modalBackground: '#FFFFFF',
22
+ modalBorder: '#DC2626',
23
+ modalCloseIcon: '#B91C1C',
24
+ modalOverlay: 'rgba(15, 23, 42, 0.55)',
25
+ modalText: '#334155',
26
+ primary: '#0EA5E9',
27
+ textDanger: '#DC2626',
28
+ },
29
+ },
30
+ };
31
+ }
32
+
33
+ return mockStores[name] || {actions: {}, getters: {}};
34
+ }),
35
+ useStores: jest.fn(selector =>
36
+ (typeof selector === 'function' ? selector(mockStores) : mockStores),
37
+ ),
38
+ }));
39
+
40
+ jest.mock('react-native', () => {
41
+ const React = require('react');
42
+ const createComponent = name => props =>
43
+ React.createElement(name, props, props.children);
44
+
45
+ return {
46
+ Modal: props => React.createElement('modal', props, props.children),
47
+ Pressable: props => React.createElement('pressable', props, props.children),
48
+ StyleSheet: {
49
+ create: styles => styles,
50
+ },
51
+ Text: createComponent('text'),
52
+ TouchableOpacity: createComponent('touchable-opacity'),
53
+ View: createComponent('view'),
54
+ };
55
+ });
56
+
57
+ const DefaultErrors =
58
+ require('../../../../react/components/errors/DefaultErrors').default;
59
+
60
+ const getTextNodes = tree =>
61
+ tree.root
62
+ .findAllByType('text')
63
+ .map(node => (Array.isArray(node.children) ? node.children.join('') : ''))
64
+ .filter(Boolean);
65
+
66
+ describe('DefaultErrors', () => {
67
+ beforeEach(() => {
68
+ jest.useFakeTimers();
69
+ consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
70
+ mockStores = {
71
+ orders: {
72
+ actions: {
73
+ setError: jest.fn(),
74
+ },
75
+ getters: {
76
+ error: 'Falha ao salvar.',
77
+ },
78
+ },
79
+ };
80
+ });
81
+
82
+ afterEach(() => {
83
+ if (consoleErrorSpy) {
84
+ consoleErrorSpy.mockRestore();
85
+ consoleErrorSpy = null;
86
+ }
87
+
88
+ jest.clearAllTimers();
89
+ jest.useRealTimers();
90
+ });
91
+
92
+ it('renders the store error in a popup and clears the store when closed', () => {
93
+ let tree;
94
+
95
+ renderer.act(() => {
96
+ tree = renderer.create(
97
+ React.createElement(DefaultErrors, {
98
+ store: 'orders',
99
+ title: 'Nao foi possivel concluir',
100
+ }),
101
+ );
102
+ });
103
+
104
+ expect(tree.root.findByType('modal').props.visible).toBe(true);
105
+ expect(getTextNodes(tree)).toEqual(
106
+ expect.arrayContaining([
107
+ 'Nao foi possivel concluir',
108
+ 'Falha ao salvar.',
109
+ '×',
110
+ ]),
111
+ );
112
+
113
+ const closeButton = tree.root.findByProps({testID: 'default-errors-close'});
114
+
115
+ renderer.act(() => {
116
+ closeButton.props.onPress();
117
+ });
118
+
119
+ expect(mockStores.orders.actions.setError).toHaveBeenCalledWith('');
120
+ expect(tree.toJSON()).toBeNull();
121
+ });
122
+
123
+ it('renders an explicit popup even without a store binding', () => {
124
+ let tree;
125
+
126
+ renderer.act(() => {
127
+ tree = renderer.create(
128
+ React.createElement(DefaultErrors, {
129
+ title: 'Pedido nao informado.',
130
+ }),
131
+ );
132
+ });
133
+
134
+ expect(tree.root.findByType('modal').props.visible).toBe(true);
135
+ expect(getTextNodes(tree)).toEqual(
136
+ expect.arrayContaining([
137
+ 'Pedido nao informado.',
138
+ '×',
139
+ ]),
140
+ );
141
+ });
142
+
143
+ it('auto closes after five seconds and clears the store error', () => {
144
+ let tree;
145
+
146
+ renderer.act(() => {
147
+ tree = renderer.create(
148
+ React.createElement(DefaultErrors, {
149
+ store: 'orders',
150
+ title: 'Nao foi possivel concluir',
151
+ }),
152
+ );
153
+ });
154
+
155
+ renderer.act(() => {
156
+ jest.advanceTimersByTime(5000);
157
+ });
158
+
159
+ expect(mockStores.orders.actions.setError).toHaveBeenCalledWith('');
160
+ expect(tree.toJSON()).toBeNull();
161
+ });
162
+ });
@@ -1,80 +1,80 @@
1
- const React = require('react');
2
- const renderer = require('react-test-renderer');
3
- const {jest} = require('@jest/globals');
4
-
5
- const {afterEach, beforeEach, describe, expect, it} = global;
6
-
7
- global.IS_REACT_ACT_ENVIRONMENT = true;
8
-
9
- jest.mock('@env', () => ({
10
- env: {
11
- API_ENTRYPOINT: 'https://api.controleonline.com',
12
- DOMAIN: 'manager.controleonline.com',
13
- },
14
- }));
15
-
16
- jest.mock('@store', () => ({
17
- useStore: jest.fn(() => ({
18
- getters: {},
19
- })),
20
- }));
21
-
22
- jest.mock('react-native', () => ({
23
- Image: props => React.createElement('image', props, props.children),
24
- }));
25
-
26
- const DefaultFile =
27
- require('../../../../react/components/files/DefaultFile').default;
28
-
29
- describe('DefaultFile', () => {
30
- beforeEach(() => {
31
- jest.clearAllMocks();
32
- });
33
-
34
- afterEach(() => {
35
- jest.clearAllTimers();
36
- });
37
-
38
- it('renders backend download files with app-domain query and headers', () => {
39
- let tree;
40
-
41
- renderer.act(() => {
42
- tree = renderer.create(
43
- React.createElement(DefaultFile, {
44
- file: {
45
- id: 3,
46
- url: '/files/3/download',
47
- },
48
- company: {
49
- domain: 'maincompany.controleonline.com',
50
- },
51
- headers: {
52
- Authorization: 'Bearer token',
53
- },
54
- resizeMode: 'contain',
55
- }),
56
- );
57
- });
58
-
59
- const image = tree.root.findByType('image');
60
-
61
- expect(image.props.source).toEqual({
62
- uri: 'https://api.controleonline.com/files/3/download?app-domain=maincompany.controleonline.com',
63
- headers: {
64
- Authorization: 'Bearer token',
65
- 'app-domain': 'maincompany.controleonline.com',
66
- },
67
- });
68
- expect(image.props.resizeMode).toBe('contain');
69
- });
70
-
71
- it('returns null when there is no file source', () => {
72
- let tree;
73
-
74
- renderer.act(() => {
75
- tree = renderer.create(React.createElement(DefaultFile, null));
76
- });
77
-
78
- expect(tree.toJSON()).toBeNull();
79
- });
80
- });
1
+ const React = require('react');
2
+ const renderer = require('react-test-renderer');
3
+ const {jest} = require('@jest/globals');
4
+
5
+ const {afterEach, beforeEach, describe, expect, it} = global;
6
+
7
+ global.IS_REACT_ACT_ENVIRONMENT = true;
8
+
9
+ jest.mock('@env', () => ({
10
+ env: {
11
+ API_ENTRYPOINT: 'https://api.controleonline.com',
12
+ DOMAIN: 'manager.controleonline.com',
13
+ },
14
+ }));
15
+
16
+ jest.mock('@store', () => ({
17
+ useStore: jest.fn(() => ({
18
+ getters: {},
19
+ })),
20
+ }));
21
+
22
+ jest.mock('react-native', () => ({
23
+ Image: props => React.createElement('image', props, props.children),
24
+ }));
25
+
26
+ const DefaultFile =
27
+ require('../../../../react/components/files/DefaultFile').default;
28
+
29
+ describe('DefaultFile', () => {
30
+ beforeEach(() => {
31
+ jest.clearAllMocks();
32
+ });
33
+
34
+ afterEach(() => {
35
+ jest.clearAllTimers();
36
+ });
37
+
38
+ it('renders backend download files with app-domain query and headers', () => {
39
+ let tree;
40
+
41
+ renderer.act(() => {
42
+ tree = renderer.create(
43
+ React.createElement(DefaultFile, {
44
+ file: {
45
+ id: 3,
46
+ url: '/files/3/download',
47
+ },
48
+ company: {
49
+ domain: 'maincompany.controleonline.com',
50
+ },
51
+ headers: {
52
+ Authorization: 'Bearer token',
53
+ },
54
+ resizeMode: 'contain',
55
+ }),
56
+ );
57
+ });
58
+
59
+ const image = tree.root.findByType('image');
60
+
61
+ expect(image.props.source).toEqual({
62
+ uri: 'https://api.controleonline.com/files/3/download?app-domain=maincompany.controleonline.com',
63
+ headers: {
64
+ Authorization: 'Bearer token',
65
+ 'app-domain': 'maincompany.controleonline.com',
66
+ },
67
+ });
68
+ expect(image.props.resizeMode).toBe('contain');
69
+ });
70
+
71
+ it('returns null when there is no file source', () => {
72
+ let tree;
73
+
74
+ renderer.act(() => {
75
+ tree = renderer.create(React.createElement(DefaultFile, null));
76
+ });
77
+
78
+ expect(tree.toJSON()).toBeNull();
79
+ });
80
+ });
@@ -0,0 +1,81 @@
1
+ const React = require('react');
2
+ const renderer = require('react-test-renderer');
3
+ const {jest} = require('@jest/globals');
4
+
5
+ const {beforeEach, describe, expect, it} = global;
6
+
7
+ global.IS_REACT_ACT_ENVIRONMENT = true;
8
+
9
+ let mockStores = {};
10
+ let capturedInputs = [];
11
+
12
+ jest.mock('@store', () => ({
13
+ useStore: jest.fn(name => mockStores[name] || {actions: {}, getters: {}}),
14
+ }));
15
+
16
+ jest.mock('react-native', () => {
17
+ const React = require('react');
18
+ const createComponent = name => props =>
19
+ React.createElement(name, props, props.children);
20
+
21
+ return {
22
+ ScrollView: createComponent('ScrollView'),
23
+ StyleSheet: {create: value => value},
24
+ Text: createComponent('Text'),
25
+ TouchableOpacity: createComponent('TouchableOpacity'),
26
+ View: createComponent('View'),
27
+ };
28
+ });
29
+
30
+ jest.mock('../../../../react/components/inputs/DefaultInput', () => props => {
31
+ const React = require('react');
32
+ capturedInputs.push(props);
33
+ return React.createElement('DefaultInput', props);
34
+ });
35
+
36
+ const DefaultForm = require('../../../../react/components/form/DefaultForm').default;
37
+
38
+ describe('DefaultForm', () => {
39
+ beforeEach(() => {
40
+ capturedInputs = [];
41
+ mockStores = {
42
+ theme: {
43
+ getters: {
44
+ colors: {},
45
+ },
46
+ },
47
+ };
48
+ });
49
+
50
+ it('keeps create-mode draft text while typing when no row is provided', async () => {
51
+ const columns = [
52
+ {
53
+ name: 'name',
54
+ label: 'reason',
55
+ editable: true,
56
+ },
57
+ ];
58
+
59
+ await renderer.act(async () => {
60
+ renderer.create(
61
+ React.createElement(DefaultForm, {
62
+ actions: {
63
+ save: jest.fn(),
64
+ },
65
+ columns,
66
+ mode: 'create',
67
+ storeName: 'order_cancellation_reasons',
68
+ }),
69
+ );
70
+ });
71
+
72
+ const inputBeforeTyping = capturedInputs[capturedInputs.length - 1];
73
+
74
+ await renderer.act(async () => {
75
+ inputBeforeTyping.onChangeValue('Cliente desistiu');
76
+ });
77
+
78
+ const inputAfterTyping = capturedInputs[capturedInputs.length - 1];
79
+ expect(inputAfterTyping.value).toBe('Cliente desistiu');
80
+ });
81
+ });