@visns-studio/visns-components 4.8.11 → 4.8.13
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/package.json +1 -1
- package/src/components/crm/DataGrid.jsx +3 -1
- package/src/components/crm/Field.jsx +75 -22
- package/src/components/crm/Form.jsx +29 -5
- package/src/components/crm/generic/GenericDetail.jsx +2 -0
- package/src/components/crm/generic/GenericIndex.jsx +40 -0
- package/src/components/crm/generic/GenericSort.jsx +2 -2
- package/src/components/crm/styles/Field.module.scss +20 -0
package/package.json
CHANGED
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
76
76
|
},
|
|
77
77
|
"name": "@visns-studio/visns-components",
|
|
78
|
-
"version": "4.8.
|
|
78
|
+
"version": "4.8.13",
|
|
79
79
|
"description": "Various packages to assist in the development of our Custom Applications.",
|
|
80
80
|
"main": "src/index.js",
|
|
81
81
|
"files": [
|
|
@@ -457,11 +457,12 @@ const DataGrid = forwardRef(
|
|
|
457
457
|
form.hasOwnProperty('json') &&
|
|
458
458
|
form.json === true
|
|
459
459
|
) {
|
|
460
|
-
deleteForm.url = `${form.url}/
|
|
460
|
+
deleteForm.url = `${form.url}/json/delete`;
|
|
461
461
|
deleteForm.method = 'POST';
|
|
462
462
|
deleteForm.payload = {
|
|
463
463
|
id: d[form.primaryKey],
|
|
464
464
|
dataId: getDataId(),
|
|
465
|
+
key: form.jsonKey || '',
|
|
465
466
|
};
|
|
466
467
|
} else {
|
|
467
468
|
deleteForm.url = `${form.url}/${
|
|
@@ -2686,6 +2687,7 @@ const DataGrid = forwardRef(
|
|
|
2686
2687
|
paramValue={paramValue}
|
|
2687
2688
|
style={style}
|
|
2688
2689
|
updateForm={setFormData}
|
|
2690
|
+
userProfile={userProfile}
|
|
2689
2691
|
/>
|
|
2690
2692
|
</Popup>
|
|
2691
2693
|
<Popup
|
|
@@ -39,6 +39,7 @@ function Field({
|
|
|
39
39
|
mapbox,
|
|
40
40
|
onChange,
|
|
41
41
|
onChangeCheckbox,
|
|
42
|
+
onChangeCheckboxManual,
|
|
42
43
|
onChangeColour,
|
|
43
44
|
onChangeDate,
|
|
44
45
|
onChangeNumberFormat,
|
|
@@ -386,32 +387,84 @@ function Field({
|
|
|
386
387
|
/>
|
|
387
388
|
);
|
|
388
389
|
case 'checkbox':
|
|
389
|
-
return
|
|
390
|
+
return (
|
|
390
391
|
<div
|
|
391
|
-
className=
|
|
392
|
+
className={styles.fi__optionscontainer}
|
|
392
393
|
style={{ paddingTop: '10px' }}
|
|
393
394
|
>
|
|
394
|
-
{settings.
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
395
|
+
{settings.hasOwnProperty('mode')
|
|
396
|
+
? settings.mode === 'useValue' &&
|
|
397
|
+
settings.options.length > 0
|
|
398
|
+
? // Use Object.entries to loop through inputValue as it's an object
|
|
399
|
+
settings.options.map((value, index) => {
|
|
400
|
+
return (
|
|
401
|
+
<div
|
|
402
|
+
key={`${settings.id}-checkbox-option-${index}`}
|
|
403
|
+
className={
|
|
404
|
+
styles.fi__checkboxcontainer
|
|
405
|
+
}
|
|
406
|
+
>
|
|
407
|
+
<input
|
|
408
|
+
name={settings.id}
|
|
409
|
+
data-name={settings.id}
|
|
410
|
+
type="checkbox"
|
|
411
|
+
className={
|
|
412
|
+
styles.fi__customcheckbox
|
|
413
|
+
}
|
|
414
|
+
value={value.label}
|
|
415
|
+
checked={
|
|
416
|
+
inputValue
|
|
417
|
+
? inputValue[value.id]
|
|
418
|
+
: false
|
|
419
|
+
}
|
|
420
|
+
onChange={(e) => {
|
|
421
|
+
onChangeCheckboxManual(
|
|
422
|
+
value.id,
|
|
423
|
+
settings.id,
|
|
424
|
+
e.target.checked
|
|
425
|
+
);
|
|
426
|
+
}}
|
|
427
|
+
/>
|
|
428
|
+
<label
|
|
429
|
+
className={
|
|
430
|
+
styles.fi__checkboxlabel
|
|
431
|
+
}
|
|
432
|
+
>
|
|
433
|
+
{value.label}
|
|
434
|
+
</label>
|
|
435
|
+
</div>
|
|
436
|
+
);
|
|
437
|
+
})
|
|
438
|
+
: null
|
|
439
|
+
: // When settings.mode is not 'useValue', loop through settings.options
|
|
440
|
+
settings.options?.length > 0 &&
|
|
441
|
+
settings.options.map((option, index) => (
|
|
442
|
+
<div
|
|
443
|
+
key={`${settings.id}-checkbox-option-${index}`}
|
|
444
|
+
className="fi__checkboxcontainer"
|
|
445
|
+
>
|
|
446
|
+
<input
|
|
447
|
+
name={settings.id}
|
|
448
|
+
data-name={settings.id}
|
|
449
|
+
type="checkbox"
|
|
450
|
+
className={styles.fi__customcheckbox}
|
|
451
|
+
value={option.label}
|
|
452
|
+
checked={
|
|
453
|
+
inputValue
|
|
454
|
+
? inputValue[index]
|
|
455
|
+
: false
|
|
456
|
+
}
|
|
457
|
+
onChange={onChangeCheckbox}
|
|
458
|
+
/>
|
|
459
|
+
<label
|
|
460
|
+
className={styles.fi__checkboxlabel}
|
|
461
|
+
>
|
|
462
|
+
{option.label}
|
|
463
|
+
</label>
|
|
464
|
+
</div>
|
|
465
|
+
))}
|
|
413
466
|
</div>
|
|
414
|
-
)
|
|
467
|
+
);
|
|
415
468
|
case 'colour':
|
|
416
469
|
return (
|
|
417
470
|
<div className="cpicker">
|
|
@@ -162,6 +162,16 @@ function Form({
|
|
|
162
162
|
}));
|
|
163
163
|
};
|
|
164
164
|
|
|
165
|
+
const handleChangeCheckboxManual = (id, name, value) => {
|
|
166
|
+
setFormData((prevFormData) => ({
|
|
167
|
+
...prevFormData,
|
|
168
|
+
[name]: {
|
|
169
|
+
...prevFormData[name],
|
|
170
|
+
[id]: value, // Update the value for the key that matches 'id'
|
|
171
|
+
},
|
|
172
|
+
}));
|
|
173
|
+
};
|
|
174
|
+
|
|
165
175
|
const handleChangeColour = (event, color, id) => {
|
|
166
176
|
if (color && event && id) {
|
|
167
177
|
setFormData((prevState) => ({
|
|
@@ -422,6 +432,10 @@ function Form({
|
|
|
422
432
|
const renderInputValue = (i, f) => {
|
|
423
433
|
let value = '';
|
|
424
434
|
|
|
435
|
+
if (i.id === 'event_detail.type_of_event') {
|
|
436
|
+
console.info(i, f);
|
|
437
|
+
}
|
|
438
|
+
|
|
425
439
|
if (i.hasOwnProperty('parent') && i.parent) {
|
|
426
440
|
if (f[i.parent]) {
|
|
427
441
|
value = i.hasOwnProperty('key')
|
|
@@ -605,7 +619,7 @@ function Form({
|
|
|
605
619
|
switch (formType) {
|
|
606
620
|
case 'create':
|
|
607
621
|
if (formSettings.json) {
|
|
608
|
-
url += '/
|
|
622
|
+
url += '/json/store';
|
|
609
623
|
}
|
|
610
624
|
break;
|
|
611
625
|
case 'update':
|
|
@@ -613,8 +627,8 @@ function Form({
|
|
|
613
627
|
if (formSettings.json) {
|
|
614
628
|
url +=
|
|
615
629
|
formType === 'update'
|
|
616
|
-
? '/
|
|
617
|
-
: `/
|
|
630
|
+
? '/json/update'
|
|
631
|
+
: `/json/delete/${
|
|
618
632
|
formData[
|
|
619
633
|
formSettings.primaryKey
|
|
620
634
|
]
|
|
@@ -812,9 +826,13 @@ function Form({
|
|
|
812
826
|
) {
|
|
813
827
|
let dataId = getDataId();
|
|
814
828
|
|
|
815
|
-
urlSuffix = '/
|
|
829
|
+
urlSuffix = '/json/get';
|
|
816
830
|
method = 'POST';
|
|
817
|
-
payload = {
|
|
831
|
+
payload = {
|
|
832
|
+
id: columnId,
|
|
833
|
+
dataId,
|
|
834
|
+
key: formSettings.jsonKey || '',
|
|
835
|
+
};
|
|
818
836
|
} else {
|
|
819
837
|
urlSuffix = `/${columnId}`;
|
|
820
838
|
method = 'GET';
|
|
@@ -1176,6 +1194,9 @@ function Form({
|
|
|
1176
1194
|
mapbox={mapbox}
|
|
1177
1195
|
onChange={handleChange}
|
|
1178
1196
|
onChangeCheckbox={handleChangeCheckbox}
|
|
1197
|
+
onChangeCheckboxManual={
|
|
1198
|
+
handleChangeCheckboxManual
|
|
1199
|
+
}
|
|
1179
1200
|
onChangeDate={handleChangeDate}
|
|
1180
1201
|
onChangeNumberFormat={
|
|
1181
1202
|
handleChangeNumberFormat
|
|
@@ -1323,6 +1344,9 @@ function Form({
|
|
|
1323
1344
|
onChangeCheckbox={
|
|
1324
1345
|
handleChangeCheckbox
|
|
1325
1346
|
}
|
|
1347
|
+
onChangeCheckboxManual={
|
|
1348
|
+
handleChangeCheckboxManual
|
|
1349
|
+
}
|
|
1326
1350
|
onChangeColour={handleChangeColour}
|
|
1327
1351
|
onChangeDate={handleChangeDate}
|
|
1328
1352
|
onChangeNumberFormat={
|
|
@@ -1156,6 +1156,7 @@ function GenericDetail({
|
|
|
1156
1156
|
userProfile?.settings
|
|
1157
1157
|
?.style || {}
|
|
1158
1158
|
}
|
|
1159
|
+
userProfile={userProfile}
|
|
1159
1160
|
/>
|
|
1160
1161
|
</div>
|
|
1161
1162
|
</div>
|
|
@@ -1494,6 +1495,7 @@ function GenericDetail({
|
|
|
1494
1495
|
formType={formType}
|
|
1495
1496
|
style={userProfile?.settings?.style || {}}
|
|
1496
1497
|
updateForm={setFormData}
|
|
1498
|
+
userProfile={userProfile}
|
|
1497
1499
|
/>
|
|
1498
1500
|
</Popup>
|
|
1499
1501
|
</>
|
|
@@ -32,6 +32,7 @@ function useConfig(setting, tabs, filters, setRowsSelected, tableSetting) {
|
|
|
32
32
|
|
|
33
33
|
useEffect(() => {
|
|
34
34
|
setConfig({
|
|
35
|
+
export: setting.export || {},
|
|
35
36
|
ajaxSetting: setting.ajaxSetting,
|
|
36
37
|
form: setting.form,
|
|
37
38
|
columns: setting.columns,
|
|
@@ -216,6 +217,37 @@ function GenericIndex({
|
|
|
216
217
|
}
|
|
217
218
|
}, [rowsSelected, setting?.functions?.checkboxUpdate]);
|
|
218
219
|
|
|
220
|
+
const handleExport = async (e) => {
|
|
221
|
+
try {
|
|
222
|
+
if (e) {
|
|
223
|
+
e.preventDefault();
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
console.info(config, setting);
|
|
227
|
+
|
|
228
|
+
const res = await Download(
|
|
229
|
+
config.export.url,
|
|
230
|
+
config.export.method,
|
|
231
|
+
{}
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
if (res.data.error) {
|
|
235
|
+
toast.error(res.data.error);
|
|
236
|
+
} else {
|
|
237
|
+
// Assuming the response contains a Blob or similar data
|
|
238
|
+
if (res.data && res.data instanceof Blob) {
|
|
239
|
+
const fileName = `${config.export.filename}`;
|
|
240
|
+
saveAs(res.data, fileName);
|
|
241
|
+
} else {
|
|
242
|
+
// Handle the case where the response is not a Blob
|
|
243
|
+
toast.error('Invalid file format received.');
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
} catch (err) {
|
|
247
|
+
console.error(err);
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
|
|
219
251
|
const renderTable = useCallback(() => {
|
|
220
252
|
const isConfigValid = (config) => {
|
|
221
253
|
return (
|
|
@@ -387,6 +419,14 @@ function GenericIndex({
|
|
|
387
419
|
</button>
|
|
388
420
|
</div>
|
|
389
421
|
)}
|
|
422
|
+
|
|
423
|
+
{setting.export?.label && (
|
|
424
|
+
<div className={styles.polActions}>
|
|
425
|
+
<button className={styles.btn} onClick={handleExport}>
|
|
426
|
+
{setting.export.label}
|
|
427
|
+
</button>
|
|
428
|
+
</div>
|
|
429
|
+
)}
|
|
390
430
|
</>
|
|
391
431
|
);
|
|
392
432
|
}
|
|
@@ -83,7 +83,7 @@ const GenericSort = ({ category = false, layout = 'full' }) => {
|
|
|
83
83
|
let payload = {};
|
|
84
84
|
|
|
85
85
|
if (form?.json) {
|
|
86
|
-
fetchUrl = fetchUrl + '/
|
|
86
|
+
fetchUrl = fetchUrl + '/json/sortList';
|
|
87
87
|
payload.id = paramValue;
|
|
88
88
|
} else {
|
|
89
89
|
fetchUrl = fetchUrl + '/sort_list';
|
|
@@ -104,7 +104,7 @@ const GenericSort = ({ category = false, layout = 'full' }) => {
|
|
|
104
104
|
};
|
|
105
105
|
|
|
106
106
|
if (form?.json) {
|
|
107
|
-
fetchUrl = fetchUrl + '/
|
|
107
|
+
fetchUrl = fetchUrl + '/json/sortUpdate';
|
|
108
108
|
payload.id = paramValue;
|
|
109
109
|
} else {
|
|
110
110
|
fetchUrl = fetchUrl + '/sort_update';
|
|
@@ -81,6 +81,26 @@
|
|
|
81
81
|
top: -5px;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
.fi__optionscontainer {
|
|
85
|
+
display: flex;
|
|
86
|
+
flex-wrap: wrap; // Allows options to wrap if they exceed the container's width
|
|
87
|
+
gap: 10px; // Adds space between checkboxes
|
|
88
|
+
margin-top: 8px; // Adjust as needed to create space between the label and checkboxes
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.fi__checkboxcontainer {
|
|
92
|
+
display: flex;
|
|
93
|
+
align-items: center;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.fi__customcheckbox {
|
|
97
|
+
margin-right: 5px; // Space between checkbox and its label
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.fi__checkboxlabel {
|
|
101
|
+
user-select: none; // Improves UX by preventing text selection
|
|
102
|
+
}
|
|
103
|
+
|
|
84
104
|
input:not(:placeholder-shown) + .fi__span,
|
|
85
105
|
textarea:not(:placeholder-shown) + .fi__span,
|
|
86
106
|
select:not(:placeholder-shown) + .fi__span {
|