@visns-studio/visns-components 2.5.13 → 2.5.15
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.
|
@@ -42,6 +42,7 @@ import 'react-confirm-alert/src/react-confirm-alert.css';
|
|
|
42
42
|
|
|
43
43
|
import CustomFetch from './Fetch';
|
|
44
44
|
import Form from './Form';
|
|
45
|
+
import _ from 'lodash';
|
|
45
46
|
|
|
46
47
|
const loadData = async (
|
|
47
48
|
{ skip, limit, sortInfo, currentData, filterValue, groupBy },
|
|
@@ -104,10 +105,12 @@ const DataGrid = forwardRef(
|
|
|
104
105
|
form,
|
|
105
106
|
gridHeight,
|
|
106
107
|
settings,
|
|
107
|
-
setFilterData,
|
|
108
108
|
setConfig,
|
|
109
|
+
setFilterData,
|
|
109
110
|
setTotal,
|
|
111
|
+
setRowsSelected,
|
|
110
112
|
style,
|
|
113
|
+
tableSetting,
|
|
111
114
|
},
|
|
112
115
|
ref
|
|
113
116
|
) => {
|
|
@@ -171,6 +174,7 @@ const DataGrid = forwardRef(
|
|
|
171
174
|
const [gridColumns, setGridColumns] = useState([]);
|
|
172
175
|
const [limit, setLimit] = useState(0);
|
|
173
176
|
const [search, setSearch] = useState('');
|
|
177
|
+
const [selected, setSelected] = useState({});
|
|
174
178
|
|
|
175
179
|
/** Table Functions */
|
|
176
180
|
useImperativeHandle(ref, () => ({
|
|
@@ -179,6 +183,11 @@ const DataGrid = forwardRef(
|
|
|
179
183
|
},
|
|
180
184
|
}));
|
|
181
185
|
|
|
186
|
+
const handleSelectionChnage = useCallback(({ selected }) => {
|
|
187
|
+
console.info(selected, data);
|
|
188
|
+
setSelected(selected);
|
|
189
|
+
}, []);
|
|
190
|
+
|
|
182
191
|
const handleFilterChange = useCallback((d) => {
|
|
183
192
|
setFilterValue(d);
|
|
184
193
|
}, []);
|
|
@@ -425,7 +434,9 @@ const DataGrid = forwardRef(
|
|
|
425
434
|
<div className="filterAction--alt">
|
|
426
435
|
<button
|
|
427
436
|
className="btn"
|
|
428
|
-
onClick={() => {
|
|
437
|
+
onClick={(e) => {
|
|
438
|
+
e.preventDefault();
|
|
439
|
+
|
|
429
440
|
if (form.create) {
|
|
430
441
|
if (form.create.url) {
|
|
431
442
|
navigate(form.create.url);
|
|
@@ -450,28 +461,33 @@ const DataGrid = forwardRef(
|
|
|
450
461
|
};
|
|
451
462
|
|
|
452
463
|
const renderSearch = () => {
|
|
453
|
-
const
|
|
454
|
-
|
|
455
|
-
);
|
|
464
|
+
const isSearchEnabled = !(form.searchDisable === true);
|
|
465
|
+
const isCreateDisabled = form.createDisable === true;
|
|
456
466
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
<div className="
|
|
460
|
-
<
|
|
467
|
+
if (isSearchEnabled) {
|
|
468
|
+
return (
|
|
469
|
+
<div className="filterInput--alt">
|
|
470
|
+
<div className="icon-search">
|
|
471
|
+
<Search strokeWidth={2} size={18} />
|
|
472
|
+
</div>
|
|
473
|
+
<input
|
|
474
|
+
type="text"
|
|
475
|
+
placeholder="Search"
|
|
476
|
+
value={search}
|
|
477
|
+
onChange={handleChangeSearch}
|
|
478
|
+
/>
|
|
461
479
|
</div>
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
></div>
|
|
474
|
-
);
|
|
480
|
+
);
|
|
481
|
+
} else if (!isCreateDisabled) {
|
|
482
|
+
return (
|
|
483
|
+
<div
|
|
484
|
+
className="filterInput--alt"
|
|
485
|
+
style={{ height: '37px' }}
|
|
486
|
+
></div>
|
|
487
|
+
);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
return null; // Return null if neither search is enabled nor create is disabled
|
|
475
491
|
};
|
|
476
492
|
|
|
477
493
|
const handleCoding = (c, data) => {
|
|
@@ -555,6 +571,12 @@ const DataGrid = forwardRef(
|
|
|
555
571
|
};
|
|
556
572
|
|
|
557
573
|
/** Table Hooks */
|
|
574
|
+
useEffect(() => {
|
|
575
|
+
if ( setRowsSelected) {
|
|
576
|
+
setRowsSelected(selected);
|
|
577
|
+
}
|
|
578
|
+
}, [selected]);
|
|
579
|
+
|
|
558
580
|
useEffect(() => {
|
|
559
581
|
const delayedSetDSearch = debounce(() => {
|
|
560
582
|
setDSearch(search);
|
|
@@ -813,6 +835,19 @@ const DataGrid = forwardRef(
|
|
|
813
835
|
}
|
|
814
836
|
},
|
|
815
837
|
};
|
|
838
|
+
case 'boolean':
|
|
839
|
+
return {
|
|
840
|
+
...commonProps,
|
|
841
|
+
name: `${column.type}.${column.id}`,
|
|
842
|
+
sortable: false,
|
|
843
|
+
render: ({ data }) => {
|
|
844
|
+
if (data[column.id]) {
|
|
845
|
+
return 'Yes';
|
|
846
|
+
} else {
|
|
847
|
+
return 'No';
|
|
848
|
+
}
|
|
849
|
+
},
|
|
850
|
+
};
|
|
816
851
|
case 'coding':
|
|
817
852
|
return {
|
|
818
853
|
...commonProps,
|
|
@@ -1220,29 +1255,39 @@ const DataGrid = forwardRef(
|
|
|
1220
1255
|
null
|
|
1221
1256
|
);
|
|
1222
1257
|
|
|
1223
|
-
if (
|
|
1224
|
-
column.filter
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1258
|
+
if (column.filter && column.filter.type) {
|
|
1259
|
+
switch (column.filter.type) {
|
|
1260
|
+
case 'select':
|
|
1261
|
+
filterEditor = SelectFilter;
|
|
1262
|
+
filterEditorProps = {
|
|
1263
|
+
multiple:
|
|
1264
|
+
column.filter.operator === 'inlist'
|
|
1265
|
+
? true
|
|
1266
|
+
: false,
|
|
1267
|
+
wrapMultiple:
|
|
1268
|
+
column.filter.operator === 'inlist'
|
|
1269
|
+
? false
|
|
1270
|
+
: true,
|
|
1271
|
+
placeholder: column.filter.placeholder
|
|
1272
|
+
? column.filter.placeholder
|
|
1273
|
+
: 'All Options',
|
|
1274
|
+
dataSource: selectedDataSource,
|
|
1275
|
+
};
|
|
1276
|
+
break;
|
|
1277
|
+
case 'date':
|
|
1278
|
+
filterEditor = DateFilter;
|
|
1279
|
+
filterEditorProps = (props, { index }) => {
|
|
1280
|
+
return {
|
|
1281
|
+
dateFormat: 'DD-MM-YYYY',
|
|
1282
|
+
placeholder: 'All Dates',
|
|
1283
|
+
};
|
|
1284
|
+
};
|
|
1285
|
+
break;
|
|
1286
|
+
default:
|
|
1287
|
+
filterEditor = null;
|
|
1288
|
+
filterEditorProps = null;
|
|
1289
|
+
break;
|
|
1290
|
+
}
|
|
1246
1291
|
}
|
|
1247
1292
|
|
|
1248
1293
|
return {
|
|
@@ -1292,6 +1337,15 @@ const DataGrid = forwardRef(
|
|
|
1292
1337
|
<span>{column.placeholder}</span>
|
|
1293
1338
|
);
|
|
1294
1339
|
} else {
|
|
1340
|
+
if (column.hasOwnProperty('format')) {
|
|
1341
|
+
if (column.format) {
|
|
1342
|
+
value =
|
|
1343
|
+
moment(value).format(
|
|
1344
|
+
'DD-MM-YYYY'
|
|
1345
|
+
);
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1295
1349
|
return <span>{value}</span>;
|
|
1296
1350
|
}
|
|
1297
1351
|
} else {
|
|
@@ -1635,7 +1689,10 @@ const DataGrid = forwardRef(
|
|
|
1635
1689
|
header: 'Action',
|
|
1636
1690
|
defaultWidth: 100,
|
|
1637
1691
|
textAlign: 'center',
|
|
1638
|
-
textVerticalAlign:
|
|
1692
|
+
textVerticalAlign:
|
|
1693
|
+
style && style.text_vertical_align
|
|
1694
|
+
? style.text_vertical_align
|
|
1695
|
+
: 'center',
|
|
1639
1696
|
render: ({ data }) => {
|
|
1640
1697
|
return (
|
|
1641
1698
|
<div className="tdactions">
|
|
@@ -1823,32 +1880,33 @@ const DataGrid = forwardRef(
|
|
|
1823
1880
|
<>
|
|
1824
1881
|
{renderSearch()}
|
|
1825
1882
|
{renderCreateButton()}
|
|
1826
|
-
{limit && limit > 0
|
|
1883
|
+
{limit && limit > 0 ? (
|
|
1827
1884
|
<>
|
|
1828
1885
|
<ReactDataGrid
|
|
1886
|
+
{...tableSetting}
|
|
1829
1887
|
columns={gridColumns}
|
|
1830
1888
|
dataSource={data}
|
|
1831
1889
|
filterValue={filterValue}
|
|
1832
1890
|
limit={limit}
|
|
1833
1891
|
enableColumnAutosize={false}
|
|
1834
1892
|
enableColumnFilterContextMenu={false}
|
|
1835
|
-
enableSelection={
|
|
1893
|
+
enableSelection={true}
|
|
1836
1894
|
headerProps={headerProps}
|
|
1837
|
-
idProperty=
|
|
1838
|
-
/\//g,
|
|
1839
|
-
'-'
|
|
1840
|
-
)}`}
|
|
1895
|
+
idProperty="id"
|
|
1841
1896
|
minRowHeight={40}
|
|
1897
|
+
multiSelect={true}
|
|
1842
1898
|
onFilterValueChange={(filterValue) => {
|
|
1843
1899
|
handleFilterChange(filterValue);
|
|
1844
1900
|
}}
|
|
1845
1901
|
onLimitChange={setLimit}
|
|
1902
|
+
onSelectionChange={handleSelectionChnage}
|
|
1846
1903
|
onSortInfoChange={handleSort}
|
|
1847
1904
|
onRenderRow={onRenderRow}
|
|
1848
1905
|
pagination
|
|
1849
1906
|
renderColumnContextMenu={renderColumnContextMenu}
|
|
1850
1907
|
rowClassName="vs-datagrid--row"
|
|
1851
1908
|
rowHeight={null}
|
|
1909
|
+
selected={selected}
|
|
1852
1910
|
showZebraRows={true}
|
|
1853
1911
|
sortInfo={
|
|
1854
1912
|
ajaxSetting.sortBy && ajaxSetting.sort
|
|
@@ -1864,7 +1922,7 @@ const DataGrid = forwardRef(
|
|
|
1864
1922
|
style={gridStyle}
|
|
1865
1923
|
/>
|
|
1866
1924
|
</>
|
|
1867
|
-
)}
|
|
1925
|
+
) : null}
|
|
1868
1926
|
{audioSource && <audio src={audioSource} ref={audioRef} />}
|
|
1869
1927
|
<Popup
|
|
1870
1928
|
open={modalShow}
|
package/components/crm/Field.jsx
CHANGED
|
@@ -216,6 +216,8 @@ function Field({
|
|
|
216
216
|
'colour',
|
|
217
217
|
'plaindate',
|
|
218
218
|
'plaindatetime',
|
|
219
|
+
'plainrelation',
|
|
220
|
+
'plainrelationarray',
|
|
219
221
|
'plaintext',
|
|
220
222
|
].includes(settings.type)
|
|
221
223
|
) {
|
|
@@ -227,6 +229,42 @@ function Field({
|
|
|
227
229
|
}
|
|
228
230
|
};
|
|
229
231
|
|
|
232
|
+
const renderRelationText = (value) => {
|
|
233
|
+
let text = '';
|
|
234
|
+
|
|
235
|
+
const processKeys = (obj) => {
|
|
236
|
+
let tmpValue = obj;
|
|
237
|
+
settings.keys.forEach((key) => {
|
|
238
|
+
tmpValue = tmpValue[key];
|
|
239
|
+
});
|
|
240
|
+
return tmpValue;
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
if (Array.isArray(value) && value[0] && settings.keys) {
|
|
244
|
+
text = processKeys(value[0]);
|
|
245
|
+
} else if (typeof value === 'object' && value !== null) {
|
|
246
|
+
text = processKeys(value);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return text;
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
const renderRelationArrayText = (value) => {
|
|
253
|
+
let text = '';
|
|
254
|
+
|
|
255
|
+
if (value && settings.nameFrom) {
|
|
256
|
+
value.forEach((a, b) => {
|
|
257
|
+
if (b > 0) {
|
|
258
|
+
text += ', ';
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
text += a[settings.nameFrom];
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return text;
|
|
266
|
+
};
|
|
267
|
+
|
|
230
268
|
const renderInput = () => {
|
|
231
269
|
switch (settings.type) {
|
|
232
270
|
case 'text':
|
|
@@ -248,25 +286,78 @@ function Field({
|
|
|
248
286
|
);
|
|
249
287
|
case 'plaindate':
|
|
250
288
|
return (
|
|
251
|
-
<
|
|
289
|
+
<div
|
|
290
|
+
className="fi__div"
|
|
291
|
+
style={
|
|
292
|
+
settings.height
|
|
293
|
+
? {
|
|
294
|
+
height: settings.height,
|
|
295
|
+
}
|
|
296
|
+
: {}
|
|
297
|
+
}
|
|
298
|
+
>
|
|
252
299
|
{inputValue && inputValue !== 'null'
|
|
253
300
|
? moment(inputValue).format('DD-MM-YYYY')
|
|
254
301
|
: ''}
|
|
255
|
-
</
|
|
302
|
+
</div>
|
|
256
303
|
);
|
|
257
304
|
case 'plaindatetime':
|
|
258
305
|
return (
|
|
259
|
-
<
|
|
306
|
+
<div
|
|
307
|
+
className="fi__div"
|
|
308
|
+
style={
|
|
309
|
+
settings.height ? { height: settings.height } : {}
|
|
310
|
+
}
|
|
311
|
+
>
|
|
260
312
|
{inputValue && inputValue !== 'null'
|
|
261
313
|
? moment(inputValue).format('DD-MM-YYYY hh:mm A')
|
|
262
314
|
: ''}
|
|
263
|
-
</
|
|
315
|
+
</div>
|
|
264
316
|
);
|
|
265
317
|
case 'plaintext':
|
|
266
318
|
return (
|
|
267
|
-
<
|
|
319
|
+
<div
|
|
320
|
+
className="fi__div"
|
|
321
|
+
style={
|
|
322
|
+
settings.height
|
|
323
|
+
? {
|
|
324
|
+
height: settings.height,
|
|
325
|
+
}
|
|
326
|
+
: {}
|
|
327
|
+
}
|
|
328
|
+
>
|
|
268
329
|
{inputValue && inputValue !== 'null' ? inputValue : ''}
|
|
269
|
-
</
|
|
330
|
+
</div>
|
|
331
|
+
);
|
|
332
|
+
case 'plainrelation':
|
|
333
|
+
return (
|
|
334
|
+
<div
|
|
335
|
+
className="fi__div"
|
|
336
|
+
style={
|
|
337
|
+
settings.height
|
|
338
|
+
? {
|
|
339
|
+
height: settings.height,
|
|
340
|
+
}
|
|
341
|
+
: {}
|
|
342
|
+
}
|
|
343
|
+
>
|
|
344
|
+
{renderRelationText(inputValue)}
|
|
345
|
+
</div>
|
|
346
|
+
);
|
|
347
|
+
case 'plainrelationarray':
|
|
348
|
+
return (
|
|
349
|
+
<div
|
|
350
|
+
className="fi__div"
|
|
351
|
+
style={
|
|
352
|
+
settings.height
|
|
353
|
+
? {
|
|
354
|
+
height: settings.height,
|
|
355
|
+
}
|
|
356
|
+
: {}
|
|
357
|
+
}
|
|
358
|
+
>
|
|
359
|
+
{renderRelationArrayText(inputValue)}
|
|
360
|
+
</div>
|
|
270
361
|
);
|
|
271
362
|
case 'phone':
|
|
272
363
|
case 'mobile':
|
|
@@ -532,6 +623,8 @@ function Field({
|
|
|
532
623
|
'colour',
|
|
533
624
|
'plaindate',
|
|
534
625
|
'plaindatetime',
|
|
626
|
+
'plainrelation',
|
|
627
|
+
'plainrelationarray',
|
|
535
628
|
'plaintext',
|
|
536
629
|
].includes(settings.type)
|
|
537
630
|
) {
|
package/components/crm/Form.jsx
CHANGED
|
@@ -8,18 +8,19 @@ import { CircleX } from 'akar-icons';
|
|
|
8
8
|
|
|
9
9
|
import CustomFetch from './Fetch';
|
|
10
10
|
import Field from './Field';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
11
|
+
import Table from './DataGrid';
|
|
12
|
+
|
|
13
|
+
function Form({
|
|
14
|
+
closeModal,
|
|
15
|
+
columnId,
|
|
16
|
+
formType,
|
|
17
|
+
formSettings,
|
|
18
|
+
fetchTable,
|
|
19
|
+
style,
|
|
20
|
+
type,
|
|
21
|
+
updateForm,
|
|
22
|
+
userProfile,
|
|
23
|
+
}) {
|
|
23
24
|
const [inputClass, setInputClass] = useState({});
|
|
24
25
|
const [formData, setFormData] = useState({});
|
|
25
26
|
const [fetchTrigger, setFetchTrigger] = useState(false);
|
|
@@ -157,8 +158,6 @@ function Form(props) {
|
|
|
157
158
|
}));
|
|
158
159
|
};
|
|
159
160
|
|
|
160
|
-
console.info(inputValue, action, id);
|
|
161
|
-
|
|
162
161
|
switch (action.action) {
|
|
163
162
|
case 'select-option':
|
|
164
163
|
updateFormData({ [id]: inputValue });
|
|
@@ -221,66 +220,73 @@ function Form(props) {
|
|
|
221
220
|
|
|
222
221
|
const id = e.target.dataset.jsonkey || e.target.dataset.name;
|
|
223
222
|
|
|
224
|
-
|
|
223
|
+
if (formData.hasOwnProperty(id)) {
|
|
225
224
|
setFormData((prevState) => ({
|
|
226
225
|
...prevState,
|
|
227
|
-
|
|
226
|
+
[id]: e.target.checked,
|
|
228
227
|
}));
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
228
|
+
} else {
|
|
229
|
+
const updateFormData = (dataToUpdate) => {
|
|
230
|
+
setFormData((prevState) => ({
|
|
231
|
+
...prevState,
|
|
232
|
+
...dataToUpdate,
|
|
233
|
+
}));
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const updatePostalData = (checked) => {
|
|
237
|
+
const postalData = checked
|
|
238
|
+
? {
|
|
239
|
+
postal_address1: formData.address1,
|
|
240
|
+
postal_address2: formData.address2,
|
|
241
|
+
postal_suburb: formData.suburb,
|
|
242
|
+
postal_postcode: formData.postcode,
|
|
243
|
+
postal_state: formData.state,
|
|
244
|
+
postal_country: formData.country,
|
|
245
|
+
}
|
|
246
|
+
: {
|
|
247
|
+
postal_address1: '',
|
|
248
|
+
postal_address2: '',
|
|
249
|
+
postal_suburb: '',
|
|
250
|
+
postal_postcode: '',
|
|
251
|
+
postal_state: '',
|
|
252
|
+
postal_country: '',
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
updateFormData(postalData);
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
if (id === 'same_address') {
|
|
259
|
+
updatePostalData(e.target.checked);
|
|
260
|
+
}
|
|
256
261
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
262
|
+
if (e.target.dataset.show) {
|
|
263
|
+
const _show = e.target.dataset.show
|
|
264
|
+
? JSON.parse(e.target.dataset.show)
|
|
265
|
+
: [];
|
|
261
266
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
);
|
|
267
|
-
if (
|
|
268
|
-
showObject &&
|
|
269
|
-
showObject.value &&
|
|
270
|
-
showObject.value.length > 0
|
|
271
|
-
) {
|
|
272
|
-
field.hide = !showObject.value.includes(
|
|
273
|
-
e.target.checked
|
|
267
|
+
if (_show.length > 0) {
|
|
268
|
+
const updatedFields = formSettings.fields.map((field) => {
|
|
269
|
+
const showObject = _show.find(
|
|
270
|
+
(showItem) => showItem.id === field.id
|
|
274
271
|
);
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
272
|
+
if (
|
|
273
|
+
showObject &&
|
|
274
|
+
showObject.value &&
|
|
275
|
+
showObject.value.length > 0
|
|
276
|
+
) {
|
|
277
|
+
field.hide = !showObject.value.includes(
|
|
278
|
+
e.target.checked
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
return field;
|
|
282
|
+
});
|
|
278
283
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
+
if (updateForm) {
|
|
285
|
+
updateForm((prevState) => ({
|
|
286
|
+
...prevState,
|
|
287
|
+
fields: updatedFields,
|
|
288
|
+
}));
|
|
289
|
+
}
|
|
284
290
|
}
|
|
285
291
|
}
|
|
286
292
|
}
|
|
@@ -699,7 +705,8 @@ function Form(props) {
|
|
|
699
705
|
}
|
|
700
706
|
} else if (
|
|
701
707
|
field &&
|
|
702
|
-
field.hasOwnProperty('relation')
|
|
708
|
+
field.hasOwnProperty('relation') &&
|
|
709
|
+
!field.multi
|
|
703
710
|
) {
|
|
704
711
|
const relationTypes = [
|
|
705
712
|
'multi-dropdown',
|
|
@@ -830,35 +837,71 @@ function Form(props) {
|
|
|
830
837
|
) {
|
|
831
838
|
return null;
|
|
832
839
|
}
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
840
|
+
|
|
841
|
+
switch (item.type) {
|
|
842
|
+
case 'table':
|
|
843
|
+
return (
|
|
844
|
+
<div
|
|
845
|
+
className="grid__full"
|
|
846
|
+
key={
|
|
847
|
+
index +
|
|
848
|
+
'-fields-' +
|
|
849
|
+
(item.hasOwnProperty('key')
|
|
850
|
+
? item.id + '-' + item.key
|
|
851
|
+
: item.id)
|
|
852
|
+
}
|
|
853
|
+
>
|
|
854
|
+
<Table
|
|
855
|
+
ajaxSetting={item.ajaxSetting}
|
|
856
|
+
form={item.form}
|
|
857
|
+
columns={item.columns}
|
|
858
|
+
settings={item.settings}
|
|
859
|
+
style={
|
|
860
|
+
userProfile?.settings?.style ||
|
|
861
|
+
{}
|
|
862
|
+
}
|
|
863
|
+
/>
|
|
864
|
+
</div>
|
|
865
|
+
);
|
|
866
|
+
default:
|
|
867
|
+
return (
|
|
868
|
+
<Field
|
|
869
|
+
settings={item}
|
|
870
|
+
key={
|
|
871
|
+
index +
|
|
872
|
+
'-fields-' +
|
|
873
|
+
(item.hasOwnProperty('key')
|
|
874
|
+
? item.id + '-' + item.key
|
|
875
|
+
: item.id)
|
|
876
|
+
}
|
|
877
|
+
inputValue={
|
|
878
|
+
item.hasOwnProperty('key')
|
|
879
|
+
? formData[item.key]
|
|
880
|
+
: formData[item.id]
|
|
881
|
+
}
|
|
882
|
+
inputClass={inputClass}
|
|
883
|
+
onChange={handleChange}
|
|
884
|
+
onChangeDate={handleChangeDate}
|
|
885
|
+
onChangeSelect={handleChangeSelect}
|
|
886
|
+
onChangeRicheditor={
|
|
887
|
+
handleChangeRicheditor
|
|
888
|
+
}
|
|
889
|
+
onChangeToggle={handleChangeToggle}
|
|
890
|
+
onChangeNumberFormat={
|
|
891
|
+
handleChangeNumberFormat
|
|
892
|
+
}
|
|
893
|
+
autocompleteCallback={
|
|
894
|
+
autocompleteSelect
|
|
895
|
+
}
|
|
896
|
+
childDropdownCallback={
|
|
897
|
+
childDropdownCallback
|
|
898
|
+
}
|
|
899
|
+
uploadProgress={uploadProgress}
|
|
900
|
+
setFormData={setFormData}
|
|
901
|
+
style={style}
|
|
902
|
+
/>
|
|
903
|
+
);
|
|
904
|
+
}
|
|
862
905
|
})}
|
|
863
906
|
<div className="formItem fwItem">
|
|
864
907
|
<motion.div
|
|
@@ -14,6 +14,7 @@ import CustomFetch from '../Fetch';
|
|
|
14
14
|
import Form from '../Form';
|
|
15
15
|
import Table from '../DataGrid';
|
|
16
16
|
import TableFilter from '../TableFilter';
|
|
17
|
+
import { toast } from 'react-toastify';
|
|
17
18
|
|
|
18
19
|
function GenericDetail({ setting, urlParam, userProfile }) {
|
|
19
20
|
const routeParams = useParams();
|
|
@@ -32,6 +33,39 @@ function GenericDetail({ setting, urlParam, userProfile }) {
|
|
|
32
33
|
const [windowHeight, setWindowHeight] = useState(window.innerHeight);
|
|
33
34
|
|
|
34
35
|
/** General Functions */
|
|
36
|
+
const handleStageUpdate = async (stage) => {
|
|
37
|
+
const activeTab = subnav.find((s) => s.show === true);
|
|
38
|
+
|
|
39
|
+
if (activeTab) {
|
|
40
|
+
const activeTabConfig = tabs.find((t) => t.id === activeTab.id);
|
|
41
|
+
|
|
42
|
+
if (
|
|
43
|
+
activeTabConfig.stages.url &&
|
|
44
|
+
activeTabConfig.stages.url !== '' &&
|
|
45
|
+
activeTabConfig.stages.key &&
|
|
46
|
+
activeTabConfig.stages.key !== '' &&
|
|
47
|
+
activeTabConfig.stages.urlParam &&
|
|
48
|
+
activeTabConfig.stages.urlParam !== ''
|
|
49
|
+
) {
|
|
50
|
+
const url = `${activeTabConfig.stages.url}/${routeParams[urlParam]}`;
|
|
51
|
+
|
|
52
|
+
const res = await CustomFetch(url, 'POST', {
|
|
53
|
+
[activeTabConfig.stages.key]: stage.id,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
if (res.data.error === '') {
|
|
57
|
+
toast.success(
|
|
58
|
+
`Job stage has been updated to ${stage.label}`
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
handleReload();
|
|
62
|
+
} else {
|
|
63
|
+
toast.error(res.data.error);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
35
69
|
const handleReload = () => {
|
|
36
70
|
const min = 0;
|
|
37
71
|
const max = 999999999;
|
|
@@ -296,56 +330,118 @@ function GenericDetail({ setting, urlParam, userProfile }) {
|
|
|
296
330
|
</div>
|
|
297
331
|
);
|
|
298
332
|
case 'form':
|
|
333
|
+
const updateValueFromParam = (item, value) => {
|
|
334
|
+
if (item && item.urlParam) {
|
|
335
|
+
item.value = value;
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
const updateFieldValues = (
|
|
340
|
+
formConfig,
|
|
341
|
+
routeParams
|
|
342
|
+
) => {
|
|
343
|
+
formConfig.stages.data.forEach((stage) => {
|
|
344
|
+
const stageFormFields =
|
|
345
|
+
stage.form?.fields || [];
|
|
346
|
+
const stageAjaxWhereFields = [];
|
|
347
|
+
|
|
348
|
+
stageFormFields.forEach((field) => {
|
|
349
|
+
if (field.type === 'table') {
|
|
350
|
+
if (
|
|
351
|
+
field.ajaxSetting &&
|
|
352
|
+
field.ajaxSetting.where
|
|
353
|
+
) {
|
|
354
|
+
stageAjaxWhereFields.push(
|
|
355
|
+
...field.ajaxSetting.where
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
const tableFormFields =
|
|
360
|
+
field.form?.fields || [];
|
|
361
|
+
tableFormFields.forEach(
|
|
362
|
+
(formField) => {
|
|
363
|
+
updateValueFromParam(
|
|
364
|
+
formField,
|
|
365
|
+
routeParams[
|
|
366
|
+
formField.urlParam
|
|
367
|
+
]
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
stageAjaxWhereFields.forEach((where) => {
|
|
375
|
+
updateValueFromParam(
|
|
376
|
+
where,
|
|
377
|
+
routeParams[where.urlParam]
|
|
378
|
+
);
|
|
379
|
+
});
|
|
380
|
+
});
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
const formConfig = activeTabConfig;
|
|
384
|
+
updateFieldValues(formConfig, routeParams);
|
|
385
|
+
|
|
299
386
|
return (
|
|
300
387
|
<>
|
|
301
|
-
{
|
|
302
|
-
0 && (
|
|
388
|
+
{formConfig.stages?.data?.length > 0 && (
|
|
303
389
|
<div className="grid">
|
|
304
390
|
<div className="grid__row">
|
|
305
391
|
<div className="grid__full">
|
|
306
|
-
{
|
|
392
|
+
{formConfig.stages.data.map(
|
|
307
393
|
(stage) =>
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
394
|
+
data[
|
|
395
|
+
formConfig
|
|
396
|
+
.stages.key
|
|
397
|
+
] === stage.id && (
|
|
398
|
+
<React.Fragment
|
|
311
399
|
key={`stage-form-${stage.id}`}
|
|
312
400
|
>
|
|
313
|
-
{stage.form
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
401
|
+
{stage.form && (
|
|
402
|
+
<div className="gridtxt">
|
|
403
|
+
{stage
|
|
404
|
+
.form
|
|
405
|
+
.update
|
|
406
|
+
.title && (
|
|
407
|
+
<div className="gridtxt__header">
|
|
408
|
+
<span>
|
|
409
|
+
{
|
|
410
|
+
stage
|
|
411
|
+
.form
|
|
412
|
+
.update
|
|
413
|
+
.title
|
|
414
|
+
}
|
|
415
|
+
</span>
|
|
416
|
+
</div>
|
|
417
|
+
)}
|
|
418
|
+
<Form
|
|
419
|
+
columnId={
|
|
420
|
+
routeParams[
|
|
421
|
+
urlParam
|
|
422
|
+
]
|
|
423
|
+
}
|
|
424
|
+
formSettings={
|
|
425
|
+
stage.form
|
|
426
|
+
}
|
|
427
|
+
formType="update"
|
|
428
|
+
style={
|
|
429
|
+
userProfile
|
|
430
|
+
?.settings
|
|
431
|
+
?.style ||
|
|
432
|
+
{}
|
|
323
433
|
}
|
|
324
|
-
|
|
434
|
+
type="inline"
|
|
435
|
+
updateForm={
|
|
436
|
+
setFormData
|
|
437
|
+
}
|
|
438
|
+
userProfile={
|
|
439
|
+
userProfile
|
|
440
|
+
}
|
|
441
|
+
/>
|
|
325
442
|
</div>
|
|
326
443
|
)}
|
|
327
|
-
|
|
328
|
-
columnId={
|
|
329
|
-
routeParams[
|
|
330
|
-
urlParam
|
|
331
|
-
]
|
|
332
|
-
}
|
|
333
|
-
formSettings={
|
|
334
|
-
stage.form
|
|
335
|
-
}
|
|
336
|
-
formType="update"
|
|
337
|
-
style={
|
|
338
|
-
userProfile
|
|
339
|
-
?.settings
|
|
340
|
-
?.style ||
|
|
341
|
-
{}
|
|
342
|
-
}
|
|
343
|
-
updateForm={
|
|
344
|
-
setFormData
|
|
345
|
-
}
|
|
346
|
-
type="inline"
|
|
347
|
-
/>
|
|
348
|
-
</div>
|
|
444
|
+
</React.Fragment>
|
|
349
445
|
)
|
|
350
446
|
)}
|
|
351
447
|
</div>
|
|
@@ -353,18 +449,14 @@ function GenericDetail({ setting, urlParam, userProfile }) {
|
|
|
353
449
|
</div>
|
|
354
450
|
)}
|
|
355
451
|
|
|
356
|
-
{
|
|
452
|
+
{formConfig.form && (
|
|
357
453
|
<div className="gridtxt">
|
|
358
454
|
<div className="gridtxt__header">
|
|
359
|
-
<span>
|
|
360
|
-
{activeTabConfig.title}
|
|
361
|
-
</span>
|
|
455
|
+
<span>{formConfig.title}</span>
|
|
362
456
|
</div>
|
|
363
457
|
<Form
|
|
364
458
|
columnId={routeParams[urlParam]}
|
|
365
|
-
formSettings={
|
|
366
|
-
activeTabConfig.form
|
|
367
|
-
}
|
|
459
|
+
formSettings={formConfig.form}
|
|
368
460
|
formType="update"
|
|
369
461
|
style={
|
|
370
462
|
userProfile?.settings
|
|
@@ -713,6 +805,11 @@ function GenericDetail({ setting, urlParam, userProfile }) {
|
|
|
713
805
|
? 'opp-complete'
|
|
714
806
|
: ''
|
|
715
807
|
}
|
|
808
|
+
onClick={(e) => {
|
|
809
|
+
e.preventDefault();
|
|
810
|
+
|
|
811
|
+
handleStageUpdate(stage);
|
|
812
|
+
}}
|
|
716
813
|
>
|
|
717
814
|
<a>
|
|
718
815
|
{stage.label}
|
|
@@ -1,25 +1,55 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
2
|
import { Outlet } from 'react-router-dom';
|
|
3
|
+
import { toast } from 'react-toastify';
|
|
3
4
|
import Table from '../DataGrid';
|
|
4
5
|
import TableFilter from '../TableFilter';
|
|
5
6
|
|
|
6
7
|
function GenericIndex({ layout = 'full', setting, userProfile }) {
|
|
7
|
-
const {
|
|
8
|
-
|
|
8
|
+
const {
|
|
9
|
+
ajaxSetting,
|
|
10
|
+
columns,
|
|
11
|
+
filters,
|
|
12
|
+
form,
|
|
13
|
+
functions,
|
|
14
|
+
page,
|
|
15
|
+
settings,
|
|
16
|
+
tableSetting,
|
|
17
|
+
tabs,
|
|
18
|
+
} = setting;
|
|
9
19
|
|
|
10
20
|
const [config, setConfig] = useState({});
|
|
21
|
+
const [rowsSelected, setRowsSelected] = useState({});
|
|
11
22
|
const [subnav, setSubnav] = useState(filters || []);
|
|
12
23
|
const [total, setTotal] = useState(0);
|
|
13
24
|
const [windowHeight, setWindowHeight] = useState(window.innerHeight);
|
|
14
25
|
const pageTitle = page?.title;
|
|
15
26
|
|
|
27
|
+
const isObjectEmpty = (obj) => {
|
|
28
|
+
return Object.keys(obj).length === 0;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const handleCheckboxUpdate = (e) => {
|
|
32
|
+
e.preventDefault();
|
|
33
|
+
const message = functions.checkboxUpdate.message;
|
|
34
|
+
|
|
35
|
+
console.info(isObjectEmpty(rowsSelected), rowsSelected);
|
|
36
|
+
|
|
37
|
+
if (isObjectEmpty(rowsSelected)) {
|
|
38
|
+
toast.warning(message.warning);
|
|
39
|
+
} else {
|
|
40
|
+
console.info(rowsSelected);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
16
44
|
useEffect(() => {
|
|
17
45
|
if (!tabs || tabs.length === 0) {
|
|
18
46
|
setConfig(() => ({
|
|
19
47
|
ajaxSetting,
|
|
20
48
|
form,
|
|
21
49
|
columns,
|
|
50
|
+
setRowsSelected,
|
|
22
51
|
settings,
|
|
52
|
+
tableSetting,
|
|
23
53
|
}));
|
|
24
54
|
}
|
|
25
55
|
|
|
@@ -38,7 +68,9 @@ function GenericIndex({ layout = 'full', setting, userProfile }) {
|
|
|
38
68
|
ajaxSetting: activeTabConfig.ajaxSetting,
|
|
39
69
|
form: activeTabConfig.form,
|
|
40
70
|
columns: activeTabConfig.columns,
|
|
71
|
+
setRowsSelected,
|
|
41
72
|
settings: activeTabConfig.settings,
|
|
73
|
+
tableSetting,
|
|
42
74
|
}));
|
|
43
75
|
}
|
|
44
76
|
}
|
|
@@ -74,16 +106,40 @@ function GenericIndex({ layout = 'full', setting, userProfile }) {
|
|
|
74
106
|
</div>
|
|
75
107
|
|
|
76
108
|
{config.ajaxSetting &&
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
109
|
+
config.form &&
|
|
110
|
+
config.columns &&
|
|
111
|
+
config.settings ? (
|
|
112
|
+
<>
|
|
113
|
+
<div className="grid">
|
|
114
|
+
{subnav && subnav.length > 0 ? (
|
|
115
|
+
<div className="grid__subrow">
|
|
116
|
+
{layout === 'full' ? (
|
|
117
|
+
<>
|
|
118
|
+
<div className={`grid__subnav`}>
|
|
119
|
+
<TableFilter
|
|
120
|
+
filters={subnav}
|
|
121
|
+
setFilters={setSubnav}
|
|
122
|
+
setSettings={setConfig}
|
|
123
|
+
type={layout}
|
|
124
|
+
/>
|
|
125
|
+
</div>
|
|
126
|
+
<div className={`grid__subcontent`}>
|
|
127
|
+
<Table
|
|
128
|
+
{...config}
|
|
129
|
+
gridHeight={windowHeight * 0.65}
|
|
130
|
+
setConfig={setConfig}
|
|
131
|
+
setTotal={setTotal}
|
|
132
|
+
style={
|
|
133
|
+
userProfile?.settings
|
|
134
|
+
?.style || {}
|
|
135
|
+
}
|
|
136
|
+
/>
|
|
137
|
+
</div>
|
|
138
|
+
</>
|
|
139
|
+
) : (
|
|
140
|
+
<div className="grid__full">
|
|
141
|
+
<div className="tabcontent">
|
|
142
|
+
<div className={`tabcontent__menu`}>
|
|
87
143
|
<TableFilter
|
|
88
144
|
filters={subnav}
|
|
89
145
|
setFilters={setSubnav}
|
|
@@ -91,7 +147,7 @@ function GenericIndex({ layout = 'full', setting, userProfile }) {
|
|
|
91
147
|
type={layout}
|
|
92
148
|
/>
|
|
93
149
|
</div>
|
|
94
|
-
<div className={`
|
|
150
|
+
<div className={`tabcontent__main`}>
|
|
95
151
|
<Table
|
|
96
152
|
{...config}
|
|
97
153
|
gridHeight={
|
|
@@ -105,58 +161,35 @@ function GenericIndex({ layout = 'full', setting, userProfile }) {
|
|
|
105
161
|
}
|
|
106
162
|
/>
|
|
107
163
|
</div>
|
|
108
|
-
</>
|
|
109
|
-
) : (
|
|
110
|
-
<div className="grid__full">
|
|
111
|
-
<div className="tabcontent">
|
|
112
|
-
<div
|
|
113
|
-
className={`tabcontent__menu`}
|
|
114
|
-
>
|
|
115
|
-
<TableFilter
|
|
116
|
-
filters={subnav}
|
|
117
|
-
setFilters={setSubnav}
|
|
118
|
-
setSettings={setConfig}
|
|
119
|
-
type={layout}
|
|
120
|
-
/>
|
|
121
|
-
</div>
|
|
122
|
-
<div
|
|
123
|
-
className={`tabcontent__main`}
|
|
124
|
-
>
|
|
125
|
-
<Table
|
|
126
|
-
{...config}
|
|
127
|
-
gridHeight={
|
|
128
|
-
windowHeight * 0.65
|
|
129
|
-
}
|
|
130
|
-
setConfig={setConfig}
|
|
131
|
-
setTotal={setTotal}
|
|
132
|
-
style={
|
|
133
|
-
userProfile
|
|
134
|
-
?.settings
|
|
135
|
-
?.style || {}
|
|
136
|
-
}
|
|
137
|
-
/>
|
|
138
|
-
</div>
|
|
139
|
-
</div>
|
|
140
164
|
</div>
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
165
|
+
</div>
|
|
166
|
+
)}
|
|
167
|
+
</div>
|
|
168
|
+
) : (
|
|
169
|
+
<div className="grid__full">
|
|
170
|
+
<Table
|
|
171
|
+
{...config}
|
|
172
|
+
gridHeight={windowHeight * 0.65}
|
|
173
|
+
setConfig={setConfig}
|
|
174
|
+
setTotal={setTotal}
|
|
175
|
+
style={userProfile?.settings?.style || {}}
|
|
176
|
+
/>
|
|
177
|
+
</div>
|
|
178
|
+
)}
|
|
179
|
+
</div>
|
|
180
|
+
<Outlet />
|
|
181
|
+
</>
|
|
182
|
+
) : null}
|
|
183
|
+
|
|
184
|
+
{functions && functions.checkboxUpdate ? (
|
|
185
|
+
<div className="polActions">
|
|
186
|
+
<button className="btn" onClick={handleCheckboxUpdate}>
|
|
187
|
+
{functions.checkboxUpdate.label
|
|
188
|
+
? functions.checkboxUpdate.label
|
|
189
|
+
: 'Update'}
|
|
190
|
+
</button>
|
|
191
|
+
</div>
|
|
192
|
+
) : null}
|
|
160
193
|
</>
|
|
161
194
|
);
|
|
162
195
|
}
|
package/package.json
CHANGED