@visns-studio/visns-components 5.8.19 → 5.9.0
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/README.md +149 -0
- package/package.json +1 -1
- package/src/components/crm/DataGrid.jsx +485 -131
- package/src/components/crm/Field.jsx +2 -2
- package/src/components/crm/MultiSelect.jsx +33 -13
- package/src/components/crm/generic/GenericDetail.jsx +32 -2
- package/src/components/crm/styles/DataGrid.module.scss +38 -6
- package/src/components/crm/styles/MultiSelect.module.scss +31 -9
- package/src/components/crm/styles/TableFilter.module.scss +32 -1
- package/src/components/crm/styles/global-datagrid.css +175 -1
- package/src/components/styles/global.css +29 -0
- package/src/examples/ImprovedCheckboxDataGrid.jsx +269 -0
- package/src/examples/MultiSelectStylingTest.jsx +76 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import DataGrid from '../components/crm/DataGrid';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Example demonstrating the improved checkbox column functionality in DataGrid
|
|
6
|
+
*
|
|
7
|
+
* Key improvements:
|
|
8
|
+
* 1. Larger touch targets for mobile devices
|
|
9
|
+
* 2. Fixed unintended "uncheck all" behavior when clicking empty space
|
|
10
|
+
* 3. Better visual feedback for clickable areas
|
|
11
|
+
* 4. Maintained existing selection functionality
|
|
12
|
+
*/
|
|
13
|
+
const ImprovedCheckboxDataGrid = () => {
|
|
14
|
+
const [rowsSelected, setRowsSelected] = useState({});
|
|
15
|
+
const [tableData, setTableData] = useState([]);
|
|
16
|
+
const [total, setTotal] = useState(0);
|
|
17
|
+
|
|
18
|
+
// Example configuration with checkbox functionality enabled
|
|
19
|
+
const exampleConfig = {
|
|
20
|
+
ajaxSetting: {
|
|
21
|
+
url: '/api/example/data',
|
|
22
|
+
take: 25,
|
|
23
|
+
sortBy: 'id',
|
|
24
|
+
sort: 'desc',
|
|
25
|
+
where: [],
|
|
26
|
+
},
|
|
27
|
+
columns: [
|
|
28
|
+
{
|
|
29
|
+
id: 'id',
|
|
30
|
+
label: 'ID',
|
|
31
|
+
type: 'text',
|
|
32
|
+
minWidth: 80,
|
|
33
|
+
maxWidth: 80,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: 'name',
|
|
37
|
+
label: 'Name',
|
|
38
|
+
type: 'text',
|
|
39
|
+
flex: 1,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: 'email',
|
|
43
|
+
label: 'Email',
|
|
44
|
+
type: 'text',
|
|
45
|
+
flex: 1,
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
id: 'status',
|
|
49
|
+
label: 'Status',
|
|
50
|
+
type: 'text',
|
|
51
|
+
minWidth: 100,
|
|
52
|
+
maxWidth: 100,
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
settings: [
|
|
56
|
+
{
|
|
57
|
+
id: 'edit',
|
|
58
|
+
label: 'Edit',
|
|
59
|
+
icon: 'edit',
|
|
60
|
+
url: '/edit/{id}',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: 'delete',
|
|
64
|
+
label: 'Delete',
|
|
65
|
+
icon: 'delete',
|
|
66
|
+
url: '/delete/{id}',
|
|
67
|
+
method: 'DELETE',
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
// Enable checkbox column functionality
|
|
71
|
+
tableSetting: {
|
|
72
|
+
checkboxColumn: true,
|
|
73
|
+
enableSelection: true,
|
|
74
|
+
},
|
|
75
|
+
functions: {
|
|
76
|
+
checkboxUpdate: {
|
|
77
|
+
url: '/api/bulk-update',
|
|
78
|
+
method: 'POST',
|
|
79
|
+
data: {},
|
|
80
|
+
message: {
|
|
81
|
+
warning: 'Please select at least one item to update.',
|
|
82
|
+
success: 'Items updated successfully!',
|
|
83
|
+
error: 'Failed to update items.',
|
|
84
|
+
},
|
|
85
|
+
label: 'Update Selected',
|
|
86
|
+
},
|
|
87
|
+
checkboxDelete: {
|
|
88
|
+
url: '/api/bulk-delete',
|
|
89
|
+
method: 'DELETE',
|
|
90
|
+
data: {},
|
|
91
|
+
message: {
|
|
92
|
+
warning: 'Please select at least one item to delete.',
|
|
93
|
+
success: 'Items deleted successfully!',
|
|
94
|
+
error: 'Failed to delete items.',
|
|
95
|
+
},
|
|
96
|
+
label: 'Delete Selected',
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const handleBulkUpdate = () => {
|
|
102
|
+
const selectedCount = Object.keys(rowsSelected).length;
|
|
103
|
+
console.log(
|
|
104
|
+
`Bulk update triggered for ${selectedCount} items:`,
|
|
105
|
+
rowsSelected
|
|
106
|
+
);
|
|
107
|
+
// In a real implementation, this would call the API
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const handleBulkDelete = () => {
|
|
111
|
+
const selectedCount = Object.keys(rowsSelected).length;
|
|
112
|
+
console.log(
|
|
113
|
+
`Bulk delete triggered for ${selectedCount} items:`,
|
|
114
|
+
rowsSelected
|
|
115
|
+
);
|
|
116
|
+
// In a real implementation, this would call the API
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
return (
|
|
120
|
+
<div style={{ padding: '20px' }}>
|
|
121
|
+
<h2>Improved Checkbox DataGrid Example</h2>
|
|
122
|
+
|
|
123
|
+
<div style={{ marginBottom: '20px' }}>
|
|
124
|
+
<h3>Key Improvements:</h3>
|
|
125
|
+
<ul>
|
|
126
|
+
<li>
|
|
127
|
+
<strong>Fixed checkbox cell clicks:</strong> Clicking
|
|
128
|
+
anywhere in a checkbox cell (including empty space) now
|
|
129
|
+
properly toggles ONLY that row
|
|
130
|
+
</li>
|
|
131
|
+
<li>
|
|
132
|
+
<strong>Eliminated "clear all" bug:</strong> No more
|
|
133
|
+
accidental clearing of all selections when clicking
|
|
134
|
+
checkbox cell areas
|
|
135
|
+
</li>
|
|
136
|
+
<li>
|
|
137
|
+
<strong>Consistent toggle behavior:</strong> Both
|
|
138
|
+
checkbox input clicks and cell area clicks now behave
|
|
139
|
+
identically
|
|
140
|
+
</li>
|
|
141
|
+
<li>
|
|
142
|
+
<strong>Multiple selection support:</strong> Can
|
|
143
|
+
properly select/deselect individual rows when multiple
|
|
144
|
+
rows are already selected
|
|
145
|
+
</li>
|
|
146
|
+
<li>
|
|
147
|
+
<strong>Header-only bulk actions:</strong>{' '}
|
|
148
|
+
Select/unselect all only works from header checkbox
|
|
149
|
+
</li>
|
|
150
|
+
<li>
|
|
151
|
+
<strong>Touch-friendly targets:</strong> Larger
|
|
152
|
+
clickable areas for mobile devices
|
|
153
|
+
</li>
|
|
154
|
+
</ul>
|
|
155
|
+
</div>
|
|
156
|
+
|
|
157
|
+
<div style={{ marginBottom: '20px' }}>
|
|
158
|
+
<p>
|
|
159
|
+
<strong>Selected items:</strong>{' '}
|
|
160
|
+
{Object.keys(rowsSelected).length}
|
|
161
|
+
</p>
|
|
162
|
+
{Object.keys(rowsSelected).length > 0 && (
|
|
163
|
+
<div style={{ display: 'flex', gap: '10px' }}>
|
|
164
|
+
<button
|
|
165
|
+
onClick={handleBulkUpdate}
|
|
166
|
+
style={{
|
|
167
|
+
padding: '8px 16px',
|
|
168
|
+
backgroundColor: '#3b82f6',
|
|
169
|
+
color: 'white',
|
|
170
|
+
border: 'none',
|
|
171
|
+
borderRadius: '4px',
|
|
172
|
+
cursor: 'pointer',
|
|
173
|
+
}}
|
|
174
|
+
>
|
|
175
|
+
Update Selected ({Object.keys(rowsSelected).length})
|
|
176
|
+
</button>
|
|
177
|
+
<button
|
|
178
|
+
onClick={handleBulkDelete}
|
|
179
|
+
style={{
|
|
180
|
+
padding: '8px 16px',
|
|
181
|
+
backgroundColor: '#ef4444',
|
|
182
|
+
color: 'white',
|
|
183
|
+
border: 'none',
|
|
184
|
+
borderRadius: '4px',
|
|
185
|
+
cursor: 'pointer',
|
|
186
|
+
}}
|
|
187
|
+
>
|
|
188
|
+
Delete Selected ({Object.keys(rowsSelected).length})
|
|
189
|
+
</button>
|
|
190
|
+
</div>
|
|
191
|
+
)}
|
|
192
|
+
</div>
|
|
193
|
+
|
|
194
|
+
<div
|
|
195
|
+
style={{
|
|
196
|
+
border: '1px solid #d1d5db',
|
|
197
|
+
borderRadius: '8px',
|
|
198
|
+
overflow: 'hidden',
|
|
199
|
+
}}
|
|
200
|
+
>
|
|
201
|
+
<DataGrid
|
|
202
|
+
{...exampleConfig}
|
|
203
|
+
setRowsSelected={setRowsSelected}
|
|
204
|
+
setTableData={setTableData}
|
|
205
|
+
setTotal={setTotal}
|
|
206
|
+
gridHeight={400}
|
|
207
|
+
/>
|
|
208
|
+
</div>
|
|
209
|
+
|
|
210
|
+
<div
|
|
211
|
+
style={{
|
|
212
|
+
marginTop: '20px',
|
|
213
|
+
fontSize: '14px',
|
|
214
|
+
color: '#6b7280',
|
|
215
|
+
}}
|
|
216
|
+
>
|
|
217
|
+
<h4>Testing Instructions:</h4>
|
|
218
|
+
<ol>
|
|
219
|
+
<li>
|
|
220
|
+
<strong>Test checkbox input clicks:</strong> Click
|
|
221
|
+
directly on checkbox inputs - should toggle individual
|
|
222
|
+
rows
|
|
223
|
+
</li>
|
|
224
|
+
<li>
|
|
225
|
+
<strong>Test cell area clicks:</strong> Click on empty
|
|
226
|
+
space within checkbox cells - should behave identically
|
|
227
|
+
to checkbox clicks
|
|
228
|
+
</li>
|
|
229
|
+
<li>
|
|
230
|
+
<strong>Test multiple selections:</strong> Select 2-3
|
|
231
|
+
rows, then try to deselect individual rows - should work
|
|
232
|
+
properly
|
|
233
|
+
</li>
|
|
234
|
+
<li>
|
|
235
|
+
<strong>Test header checkbox:</strong> Click header
|
|
236
|
+
checkbox to select/unselect ALL rows
|
|
237
|
+
</li>
|
|
238
|
+
<li>
|
|
239
|
+
<strong>Test mixed interactions:</strong> Mix checkbox
|
|
240
|
+
input clicks and cell area clicks - should behave
|
|
241
|
+
consistently
|
|
242
|
+
</li>
|
|
243
|
+
<li>
|
|
244
|
+
<strong>Touch devices:</strong> Verify larger touch
|
|
245
|
+
targets work properly on mobile devices
|
|
246
|
+
</li>
|
|
247
|
+
</ol>
|
|
248
|
+
|
|
249
|
+
<h4>Expected Behavior:</h4>
|
|
250
|
+
<ul>
|
|
251
|
+
<li>
|
|
252
|
+
✅ Clicking any part of a checkbox cell toggles that
|
|
253
|
+
specific row
|
|
254
|
+
</li>
|
|
255
|
+
<li>
|
|
256
|
+
✅ Header checkbox controls select/unselect all
|
|
257
|
+
functionality
|
|
258
|
+
</li>
|
|
259
|
+
<li>✅ No more unexpected "uncheck all" behavior</li>
|
|
260
|
+
<li>
|
|
261
|
+
✅ Consistent behavior across desktop and mobile devices
|
|
262
|
+
</li>
|
|
263
|
+
</ul>
|
|
264
|
+
</div>
|
|
265
|
+
</div>
|
|
266
|
+
);
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
export default ImprovedCheckboxDataGrid;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import MultiSelect from '../components/crm/MultiSelect';
|
|
3
|
+
|
|
4
|
+
function MultiSelectStylingTest() {
|
|
5
|
+
const [selectedValues, setSelectedValues] = useState([]);
|
|
6
|
+
|
|
7
|
+
const options = [
|
|
8
|
+
{ id: 1, label: 'Customer Service Representative' },
|
|
9
|
+
{ id: 2, label: 'Dashboard Administrator' },
|
|
10
|
+
{ id: 3, label: 'Project Manager' },
|
|
11
|
+
{ id: 4, label: 'Technical Support Specialist' },
|
|
12
|
+
{ id: 5, label: 'Sales Representative' },
|
|
13
|
+
{ id: 6, label: 'Quality Assurance Analyst' },
|
|
14
|
+
{ id: 7, label: 'Business Development Manager' },
|
|
15
|
+
{ id: 8, label: 'Software Engineer' }
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
const handleChange = (values) => {
|
|
19
|
+
setSelectedValues(values);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<div style={{ padding: '20px', maxWidth: '600px', margin: '0 auto' }}>
|
|
24
|
+
<h1>MultiSelect Styling Test</h1>
|
|
25
|
+
<p>This test verifies that the delete/cross icons appear inline with the selected item text, not on a new line.</p>
|
|
26
|
+
|
|
27
|
+
<div style={{ marginBottom: '20px' }}>
|
|
28
|
+
<h3>Test Case: Multi-Select with Long Labels</h3>
|
|
29
|
+
<p>Select multiple items to test the inline styling of delete icons:</p>
|
|
30
|
+
|
|
31
|
+
<MultiSelect
|
|
32
|
+
settings={{
|
|
33
|
+
id: 'stylingTest',
|
|
34
|
+
multi: true
|
|
35
|
+
}}
|
|
36
|
+
multi={true}
|
|
37
|
+
options={options}
|
|
38
|
+
inputValue={selectedValues}
|
|
39
|
+
onChange={handleChange}
|
|
40
|
+
placeholder="Select multiple roles..."
|
|
41
|
+
/>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div style={{ marginTop: '20px', padding: '15px', backgroundColor: '#f5f5f5', borderRadius: '8px' }}>
|
|
45
|
+
<h3>Expected Behavior:</h3>
|
|
46
|
+
<ul>
|
|
47
|
+
<li>✅ Delete icons should appear on the same line as the text</li>
|
|
48
|
+
<li>✅ Selected items should have a consistent height</li>
|
|
49
|
+
<li>✅ Delete icons should be clickable and remove the item</li>
|
|
50
|
+
<li>✅ Hover effect should work on delete icons</li>
|
|
51
|
+
<li>✅ Multiple selections should wrap properly without excessive height</li>
|
|
52
|
+
</ul>
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<div style={{ marginTop: '20px' }}>
|
|
56
|
+
<h3>Selected Values:</h3>
|
|
57
|
+
<pre style={{ backgroundColor: '#fff', padding: '10px', borderRadius: '4px', border: '1px solid #ddd' }}>
|
|
58
|
+
{JSON.stringify(selectedValues, null, 2)}
|
|
59
|
+
</pre>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<div style={{ marginTop: '20px', fontSize: '14px', color: '#666' }}>
|
|
63
|
+
<p><strong>Testing Instructions:</strong></p>
|
|
64
|
+
<ol>
|
|
65
|
+
<li>Select 2-3 items from the dropdown</li>
|
|
66
|
+
<li>Verify that delete icons (×) appear next to each selected item on the same line</li>
|
|
67
|
+
<li>Hover over delete icons to see the red background effect</li>
|
|
68
|
+
<li>Click delete icons to remove items</li>
|
|
69
|
+
<li>Check that the component height doesn't grow unnecessarily</li>
|
|
70
|
+
</ol>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export default MultiSelectStylingTest;
|