@visns-studio/visns-components 2.5.13 → 2.5.14
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,10 @@ const DataGrid = forwardRef(
|
|
|
555
571
|
};
|
|
556
572
|
|
|
557
573
|
/** Table Hooks */
|
|
574
|
+
useEffect(() => {
|
|
575
|
+
setRowsSelected(selected);
|
|
576
|
+
}, [selected]);
|
|
577
|
+
|
|
558
578
|
useEffect(() => {
|
|
559
579
|
const delayedSetDSearch = debounce(() => {
|
|
560
580
|
setDSearch(search);
|
|
@@ -813,6 +833,19 @@ const DataGrid = forwardRef(
|
|
|
813
833
|
}
|
|
814
834
|
},
|
|
815
835
|
};
|
|
836
|
+
case 'boolean':
|
|
837
|
+
return {
|
|
838
|
+
...commonProps,
|
|
839
|
+
name: `${column.type}.${column.id}`,
|
|
840
|
+
sortable: false,
|
|
841
|
+
render: ({ data }) => {
|
|
842
|
+
if (data[column.id]) {
|
|
843
|
+
return 'Yes';
|
|
844
|
+
} else {
|
|
845
|
+
return 'No';
|
|
846
|
+
}
|
|
847
|
+
},
|
|
848
|
+
};
|
|
816
849
|
case 'coding':
|
|
817
850
|
return {
|
|
818
851
|
...commonProps,
|
|
@@ -1220,29 +1253,39 @@ const DataGrid = forwardRef(
|
|
|
1220
1253
|
null
|
|
1221
1254
|
);
|
|
1222
1255
|
|
|
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
|
-
|
|
1256
|
+
if (column.filter && column.filter.type) {
|
|
1257
|
+
switch (column.filter.type) {
|
|
1258
|
+
case 'select':
|
|
1259
|
+
filterEditor = SelectFilter;
|
|
1260
|
+
filterEditorProps = {
|
|
1261
|
+
multiple:
|
|
1262
|
+
column.filter.operator === 'inlist'
|
|
1263
|
+
? true
|
|
1264
|
+
: false,
|
|
1265
|
+
wrapMultiple:
|
|
1266
|
+
column.filter.operator === 'inlist'
|
|
1267
|
+
? false
|
|
1268
|
+
: true,
|
|
1269
|
+
placeholder: column.filter.placeholder
|
|
1270
|
+
? column.filter.placeholder
|
|
1271
|
+
: 'All Options',
|
|
1272
|
+
dataSource: selectedDataSource,
|
|
1273
|
+
};
|
|
1274
|
+
break;
|
|
1275
|
+
case 'date':
|
|
1276
|
+
filterEditor = DateFilter;
|
|
1277
|
+
filterEditorProps = (props, { index }) => {
|
|
1278
|
+
return {
|
|
1279
|
+
dateFormat: 'DD-MM-YYYY',
|
|
1280
|
+
placeholder: 'All Dates',
|
|
1281
|
+
};
|
|
1282
|
+
};
|
|
1283
|
+
break;
|
|
1284
|
+
default:
|
|
1285
|
+
filterEditor = null;
|
|
1286
|
+
filterEditorProps = null;
|
|
1287
|
+
break;
|
|
1288
|
+
}
|
|
1246
1289
|
}
|
|
1247
1290
|
|
|
1248
1291
|
return {
|
|
@@ -1292,6 +1335,15 @@ const DataGrid = forwardRef(
|
|
|
1292
1335
|
<span>{column.placeholder}</span>
|
|
1293
1336
|
);
|
|
1294
1337
|
} else {
|
|
1338
|
+
if (column.hasOwnProperty('format')) {
|
|
1339
|
+
if (column.format) {
|
|
1340
|
+
value =
|
|
1341
|
+
moment(value).format(
|
|
1342
|
+
'DD-MM-YYYY'
|
|
1343
|
+
);
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1295
1347
|
return <span>{value}</span>;
|
|
1296
1348
|
}
|
|
1297
1349
|
} else {
|
|
@@ -1635,7 +1687,10 @@ const DataGrid = forwardRef(
|
|
|
1635
1687
|
header: 'Action',
|
|
1636
1688
|
defaultWidth: 100,
|
|
1637
1689
|
textAlign: 'center',
|
|
1638
|
-
textVerticalAlign:
|
|
1690
|
+
textVerticalAlign:
|
|
1691
|
+
style && style.text_vertical_align
|
|
1692
|
+
? style.text_vertical_align
|
|
1693
|
+
: 'center',
|
|
1639
1694
|
render: ({ data }) => {
|
|
1640
1695
|
return (
|
|
1641
1696
|
<div className="tdactions">
|
|
@@ -1823,32 +1878,33 @@ const DataGrid = forwardRef(
|
|
|
1823
1878
|
<>
|
|
1824
1879
|
{renderSearch()}
|
|
1825
1880
|
{renderCreateButton()}
|
|
1826
|
-
{limit && limit > 0
|
|
1881
|
+
{limit && limit > 0 ? (
|
|
1827
1882
|
<>
|
|
1828
1883
|
<ReactDataGrid
|
|
1884
|
+
{...tableSetting}
|
|
1829
1885
|
columns={gridColumns}
|
|
1830
1886
|
dataSource={data}
|
|
1831
1887
|
filterValue={filterValue}
|
|
1832
1888
|
limit={limit}
|
|
1833
1889
|
enableColumnAutosize={false}
|
|
1834
1890
|
enableColumnFilterContextMenu={false}
|
|
1835
|
-
enableSelection={
|
|
1891
|
+
enableSelection={true}
|
|
1836
1892
|
headerProps={headerProps}
|
|
1837
|
-
idProperty=
|
|
1838
|
-
/\//g,
|
|
1839
|
-
'-'
|
|
1840
|
-
)}`}
|
|
1893
|
+
idProperty="id"
|
|
1841
1894
|
minRowHeight={40}
|
|
1895
|
+
multiSelect={true}
|
|
1842
1896
|
onFilterValueChange={(filterValue) => {
|
|
1843
1897
|
handleFilterChange(filterValue);
|
|
1844
1898
|
}}
|
|
1845
1899
|
onLimitChange={setLimit}
|
|
1900
|
+
onSelectionChange={handleSelectionChnage}
|
|
1846
1901
|
onSortInfoChange={handleSort}
|
|
1847
1902
|
onRenderRow={onRenderRow}
|
|
1848
1903
|
pagination
|
|
1849
1904
|
renderColumnContextMenu={renderColumnContextMenu}
|
|
1850
1905
|
rowClassName="vs-datagrid--row"
|
|
1851
1906
|
rowHeight={null}
|
|
1907
|
+
selected={selected}
|
|
1852
1908
|
showZebraRows={true}
|
|
1853
1909
|
sortInfo={
|
|
1854
1910
|
ajaxSetting.sortBy && ajaxSetting.sort
|
|
@@ -1864,7 +1920,7 @@ const DataGrid = forwardRef(
|
|
|
1864
1920
|
style={gridStyle}
|
|
1865
1921
|
/>
|
|
1866
1922
|
</>
|
|
1867
|
-
)}
|
|
1923
|
+
) : null}
|
|
1868
1924
|
{audioSource && <audio src={audioSource} ref={audioRef} />}
|
|
1869
1925
|
<Popup
|
|
1870
1926
|
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