@visns-studio/visns-components 5.10.2 → 5.10.4
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 +42 -1
- package/package.json +3 -3
- package/src/components/crm/DataGrid.jsx +707 -2686
- package/src/components/crm/Field.jsx +0 -2
- package/src/components/crm/cells/CellWithTooltip.jsx +138 -0
- package/src/components/crm/columns/ColumnRenderers.jsx +1358 -0
- package/src/components/crm/controls/AudioPlayer.jsx +19 -0
- package/src/components/crm/controls/AutoRefreshControls.jsx +37 -0
- package/src/components/crm/controls/DataGridSearch.jsx +238 -0
- package/src/components/crm/modals/GalleryModal.jsx +405 -0
- package/src/components/crm/styles/DataGrid.module.scss +296 -0
- package/src/components/crm/styles/global-datagrid.css +21 -0
- package/src/index.js +11 -0
|
@@ -0,0 +1,1358 @@
|
|
|
1
|
+
import numeral from 'numeral';
|
|
2
|
+
import moment from 'moment';
|
|
3
|
+
import parse from 'html-react-parser';
|
|
4
|
+
import { CloudDownload, Alarm } from 'akar-icons';
|
|
5
|
+
import { toast } from 'react-toastify';
|
|
6
|
+
import CellWithTooltip from '../cells/CellWithTooltip';
|
|
7
|
+
|
|
8
|
+
// Boolean Column Renderer
|
|
9
|
+
export const renderBooleanColumn = ({ column, commonProps, filterEditor, filterEditorProps }) => {
|
|
10
|
+
return {
|
|
11
|
+
...commonProps,
|
|
12
|
+
filterEditor: filterEditor,
|
|
13
|
+
filterEditorProps: filterEditorProps,
|
|
14
|
+
name: `${column.type}.${column.id}`,
|
|
15
|
+
sortable: false,
|
|
16
|
+
render: ({ data }) => {
|
|
17
|
+
const value = data[column.id] ? 'Yes' : 'No';
|
|
18
|
+
return (
|
|
19
|
+
<CellWithTooltip
|
|
20
|
+
value={data[column.id]}
|
|
21
|
+
columnType="boolean"
|
|
22
|
+
>
|
|
23
|
+
<span>{value}</span>
|
|
24
|
+
</CellWithTooltip>
|
|
25
|
+
);
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// Currency Column Renderer
|
|
31
|
+
export const renderCurrencyColumn = ({ column, commonProps }) => {
|
|
32
|
+
return {
|
|
33
|
+
...commonProps,
|
|
34
|
+
name: column.id,
|
|
35
|
+
render: ({ data }) => {
|
|
36
|
+
if (data) {
|
|
37
|
+
const formattedValue = numeral(data[column.id]).format('$0,0.00');
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<CellWithTooltip
|
|
41
|
+
value={data[column.id]}
|
|
42
|
+
columnType="currency"
|
|
43
|
+
>
|
|
44
|
+
<span>{formattedValue}</span>
|
|
45
|
+
</CellWithTooltip>
|
|
46
|
+
);
|
|
47
|
+
} else {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// Date Column Renderer
|
|
55
|
+
export const renderDateColumn = ({ column, commonProps, filterEditor, filterEditorProps }) => {
|
|
56
|
+
return {
|
|
57
|
+
...commonProps,
|
|
58
|
+
name: column.id,
|
|
59
|
+
filterEditor: filterEditor,
|
|
60
|
+
filterEditorProps: filterEditorProps,
|
|
61
|
+
defaultWidth: 120, // Set default width for date columns
|
|
62
|
+
minWidth: 120, // Set minimum width for date columns
|
|
63
|
+
render: ({ data }) => {
|
|
64
|
+
if (
|
|
65
|
+
data &&
|
|
66
|
+
data[column.id] &&
|
|
67
|
+
moment(data[column.id]).isValid() &&
|
|
68
|
+
moment(data[column.id]).format('YYYY-MM-DD') !== '1970-01-01'
|
|
69
|
+
) {
|
|
70
|
+
const value = moment(data[column.id]).format(
|
|
71
|
+
column.format || 'DD-MM-YYYY'
|
|
72
|
+
);
|
|
73
|
+
let columnStyle = {};
|
|
74
|
+
|
|
75
|
+
if (
|
|
76
|
+
column.active &&
|
|
77
|
+
column.active.id &&
|
|
78
|
+
column.active.value === 'expired'
|
|
79
|
+
) {
|
|
80
|
+
if (
|
|
81
|
+
data[column.active.id] &&
|
|
82
|
+
moment(data[column.active.id]).isBefore(moment())
|
|
83
|
+
) {
|
|
84
|
+
columnStyle = {
|
|
85
|
+
color: column.active.colour,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<CellWithTooltip
|
|
92
|
+
value={data[column.id]}
|
|
93
|
+
columnType="date"
|
|
94
|
+
>
|
|
95
|
+
<span style={columnStyle}>
|
|
96
|
+
{value}
|
|
97
|
+
</span>
|
|
98
|
+
</CellWithTooltip>
|
|
99
|
+
);
|
|
100
|
+
} else {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// DateTime Column Renderer
|
|
108
|
+
export const renderDateTimeColumn = ({ column, commonProps, filterEditor, filterEditorProps }) => {
|
|
109
|
+
return {
|
|
110
|
+
...commonProps,
|
|
111
|
+
name: column.id,
|
|
112
|
+
filterEditor: filterEditor,
|
|
113
|
+
filterEditorProps: filterEditorProps,
|
|
114
|
+
defaultWidth: 160, // Set default width for datetime columns
|
|
115
|
+
minWidth: 160, // Set minimum width for datetime columns
|
|
116
|
+
render: ({ data }) => {
|
|
117
|
+
if (
|
|
118
|
+
data &&
|
|
119
|
+
data[column.id] &&
|
|
120
|
+
moment(data[column.id]).isValid() &&
|
|
121
|
+
moment(data[column.id]).format('YYYY-MM-DD') !== '1970-01-01'
|
|
122
|
+
) {
|
|
123
|
+
const formattedValue = moment(data[column.id]).format(
|
|
124
|
+
column.format ? column.format : 'DD-MM-YYYY hh:mm A'
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
return <span>{formattedValue}</span>;
|
|
128
|
+
} else {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
// Array Count Column Renderer
|
|
136
|
+
export const renderArrayCountColumn = ({ column, commonProps }) => {
|
|
137
|
+
return {
|
|
138
|
+
...commonProps,
|
|
139
|
+
name: `${column.type}.${column.id}`,
|
|
140
|
+
sortable: false,
|
|
141
|
+
render: ({ data }) => {
|
|
142
|
+
if (data && data[column.id]) {
|
|
143
|
+
return data[column.id].length;
|
|
144
|
+
} else {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// Colour Column Renderer
|
|
152
|
+
export const renderColourColumn = ({ column, commonProps }) => {
|
|
153
|
+
return {
|
|
154
|
+
...commonProps,
|
|
155
|
+
name: `${column.type}.${column.id}`,
|
|
156
|
+
sortable: false,
|
|
157
|
+
render: ({ data }) => {
|
|
158
|
+
if (data && data[column.id]) {
|
|
159
|
+
return (
|
|
160
|
+
<div
|
|
161
|
+
style={{
|
|
162
|
+
width: '25px',
|
|
163
|
+
height: '25px',
|
|
164
|
+
borderRadius: '10px',
|
|
165
|
+
overflow: 'hidden',
|
|
166
|
+
}}
|
|
167
|
+
>
|
|
168
|
+
<div
|
|
169
|
+
style={{
|
|
170
|
+
background:
|
|
171
|
+
data[column.id] + ' none repeat scroll 0% 0%',
|
|
172
|
+
height: '100%',
|
|
173
|
+
width: '100%',
|
|
174
|
+
cursor: 'pointer',
|
|
175
|
+
position: 'relative',
|
|
176
|
+
outline: 'currentcolor none medium',
|
|
177
|
+
}}
|
|
178
|
+
></div>
|
|
179
|
+
</div>
|
|
180
|
+
);
|
|
181
|
+
} else {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
// Dropdown Column Renderer
|
|
189
|
+
export const renderDropdownColumn = ({
|
|
190
|
+
column,
|
|
191
|
+
commonProps,
|
|
192
|
+
filterEditor,
|
|
193
|
+
filterEditorProps,
|
|
194
|
+
dropdownData,
|
|
195
|
+
handleDropdownUpdate
|
|
196
|
+
}) => {
|
|
197
|
+
const columnId = Array.isArray(column.id)
|
|
198
|
+
? column.id.join('-')
|
|
199
|
+
: column.id;
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
...commonProps,
|
|
203
|
+
name: columnId,
|
|
204
|
+
filterEditor: filterEditor,
|
|
205
|
+
filterEditorProps: filterEditorProps,
|
|
206
|
+
render: ({ data }) => {
|
|
207
|
+
return (
|
|
208
|
+
<select
|
|
209
|
+
name={column.id}
|
|
210
|
+
value={data[column.id]?.id || ''}
|
|
211
|
+
style={{ padding: '7px' }}
|
|
212
|
+
onChange={(e) => {
|
|
213
|
+
e.preventDefault();
|
|
214
|
+
|
|
215
|
+
if (
|
|
216
|
+
column.update?.key &&
|
|
217
|
+
column.update?.url &&
|
|
218
|
+
column.update?.method
|
|
219
|
+
) {
|
|
220
|
+
handleDropdownUpdate(
|
|
221
|
+
column.update.key,
|
|
222
|
+
`${column.update.url}/${data.id}`,
|
|
223
|
+
column.update.method,
|
|
224
|
+
e.target.value
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
}}
|
|
228
|
+
>
|
|
229
|
+
<option value="">
|
|
230
|
+
Select{' '}
|
|
231
|
+
{/^[aeioAEIO]/.test(column.label) ? 'an' : 'a'}{' '}
|
|
232
|
+
{column.label}
|
|
233
|
+
</option>
|
|
234
|
+
{dropdownData[column.id] &&
|
|
235
|
+
dropdownData[column.id].length > 0
|
|
236
|
+
? dropdownData[column.id].map((option, index) => (
|
|
237
|
+
<option value={option.id} key={index}>
|
|
238
|
+
{option.label}
|
|
239
|
+
</option>
|
|
240
|
+
))
|
|
241
|
+
: null}
|
|
242
|
+
</select>
|
|
243
|
+
);
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
// Image Column Renderer
|
|
249
|
+
export const renderImageColumn = ({ column, commonProps }) => {
|
|
250
|
+
return {
|
|
251
|
+
...commonProps,
|
|
252
|
+
name: column.id,
|
|
253
|
+
render: ({ data }) => {
|
|
254
|
+
if (data && data[column.id]) {
|
|
255
|
+
const fileUrl = data[column.id][0]?.file_url || data[column.id]?.file_url;
|
|
256
|
+
|
|
257
|
+
if (fileUrl) {
|
|
258
|
+
return (
|
|
259
|
+
<span>
|
|
260
|
+
{parse(`<img width="150" src="${fileUrl}" />`)}
|
|
261
|
+
</span>
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return null;
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
// File Column Renderer
|
|
272
|
+
export const renderFileColumn = ({ column, commonProps, handleDownload, styles }) => {
|
|
273
|
+
return {
|
|
274
|
+
...commonProps,
|
|
275
|
+
name: column.id,
|
|
276
|
+
sortable: false,
|
|
277
|
+
render: ({ data }) => {
|
|
278
|
+
if (data && data[column.id]) {
|
|
279
|
+
// Check if the data is an array of files
|
|
280
|
+
if (Array.isArray(data[column.id])) {
|
|
281
|
+
// Return a span for each file in the array with added margin
|
|
282
|
+
return data[column.id].map((file, index) => (
|
|
283
|
+
<span
|
|
284
|
+
key={index}
|
|
285
|
+
onClick={(e) => {
|
|
286
|
+
e.stopPropagation();
|
|
287
|
+
e.preventDefault();
|
|
288
|
+
handleDownload(file);
|
|
289
|
+
}}
|
|
290
|
+
style={{
|
|
291
|
+
marginRight: '10px',
|
|
292
|
+
display: 'inline-block',
|
|
293
|
+
}}
|
|
294
|
+
>
|
|
295
|
+
<CloudDownload
|
|
296
|
+
data-tooltip-id="system-tooltip"
|
|
297
|
+
data-tooltip-content={`Download File ${file.file_name}`}
|
|
298
|
+
strokeWidth={2}
|
|
299
|
+
size={14}
|
|
300
|
+
className={styles.tdaction}
|
|
301
|
+
/>
|
|
302
|
+
</span>
|
|
303
|
+
));
|
|
304
|
+
} else {
|
|
305
|
+
// Return a single span for a single file with added margin
|
|
306
|
+
return (
|
|
307
|
+
<span
|
|
308
|
+
onClick={(e) => {
|
|
309
|
+
e.stopPropagation();
|
|
310
|
+
e.preventDefault();
|
|
311
|
+
handleDownload(data[column.id]);
|
|
312
|
+
}}
|
|
313
|
+
style={{
|
|
314
|
+
marginRight: '10px',
|
|
315
|
+
display: 'inline-block',
|
|
316
|
+
}}
|
|
317
|
+
>
|
|
318
|
+
<CloudDownload
|
|
319
|
+
data-tooltip-id="system-tooltip"
|
|
320
|
+
data-tooltip-content={`Download File ${data[column.id].file_name}`}
|
|
321
|
+
strokeWidth={2}
|
|
322
|
+
size={14}
|
|
323
|
+
className={styles.tdaction}
|
|
324
|
+
/>
|
|
325
|
+
</span>
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
} else {
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
};
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
// Icons Column Renderer
|
|
336
|
+
export const renderIconsColumn = ({ column, commonProps }) => {
|
|
337
|
+
return {
|
|
338
|
+
...commonProps,
|
|
339
|
+
name: column.id,
|
|
340
|
+
sortable: false,
|
|
341
|
+
render: ({ data }) => {
|
|
342
|
+
const icons = [];
|
|
343
|
+
|
|
344
|
+
if (column.icons && column.icons.length > 0) {
|
|
345
|
+
column.icons.forEach((icon, index) => {
|
|
346
|
+
icons.push(
|
|
347
|
+
<img
|
|
348
|
+
key={index}
|
|
349
|
+
src={icon.url}
|
|
350
|
+
alt={icon.name}
|
|
351
|
+
data-tooltip-id="system-tooltip"
|
|
352
|
+
data-tooltip-content={icon.name}
|
|
353
|
+
/>
|
|
354
|
+
);
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if (data) {
|
|
359
|
+
return <span>{icons}</span>;
|
|
360
|
+
} else {
|
|
361
|
+
return null;
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
};
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
// JSON Column Renderer
|
|
368
|
+
export const renderJsonColumn = ({ column, commonProps }) => {
|
|
369
|
+
return {
|
|
370
|
+
...commonProps,
|
|
371
|
+
name: `${column.id}.${column.jsonData}`,
|
|
372
|
+
render: ({ data }) => {
|
|
373
|
+
if (
|
|
374
|
+
data &&
|
|
375
|
+
data[column.id] &&
|
|
376
|
+
data[column.id][column.jsonData]
|
|
377
|
+
) {
|
|
378
|
+
const jsonValue = data[column.id][column.jsonData];
|
|
379
|
+
|
|
380
|
+
return (
|
|
381
|
+
<CellWithTooltip
|
|
382
|
+
value={jsonValue}
|
|
383
|
+
columnType="json"
|
|
384
|
+
>
|
|
385
|
+
<span>{jsonValue}</span>
|
|
386
|
+
</CellWithTooltip>
|
|
387
|
+
);
|
|
388
|
+
} else {
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
},
|
|
392
|
+
};
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
// Number Column Renderer
|
|
396
|
+
export const renderNumberColumn = ({ column, commonProps }) => {
|
|
397
|
+
return {
|
|
398
|
+
...commonProps,
|
|
399
|
+
name: column.id,
|
|
400
|
+
type: 'number',
|
|
401
|
+
};
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
// Option Column Renderer
|
|
405
|
+
export const renderOptionColumn = ({ column, commonProps, filterEditor, filterEditorProps }) => {
|
|
406
|
+
return {
|
|
407
|
+
...commonProps,
|
|
408
|
+
name: column.id,
|
|
409
|
+
filterEditor: filterEditor,
|
|
410
|
+
filterEditorProps: filterEditorProps,
|
|
411
|
+
render: ({ data }) => {
|
|
412
|
+
let newData;
|
|
413
|
+
|
|
414
|
+
if (
|
|
415
|
+
data &&
|
|
416
|
+
column.options &&
|
|
417
|
+
column.options[data[column.id]]
|
|
418
|
+
) {
|
|
419
|
+
if (
|
|
420
|
+
column.key &&
|
|
421
|
+
data[column.key] > 0 &&
|
|
422
|
+
column.options[data[column.id]].includes('#')
|
|
423
|
+
) {
|
|
424
|
+
newData = column.options[data[column.id]].replace(
|
|
425
|
+
/#/g,
|
|
426
|
+
data[column.key]
|
|
427
|
+
);
|
|
428
|
+
} else {
|
|
429
|
+
newData = column.options[data[column.id]];
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
return (
|
|
433
|
+
<CellWithTooltip
|
|
434
|
+
value={newData}
|
|
435
|
+
columnType="option"
|
|
436
|
+
>
|
|
437
|
+
<span>{newData}</span>
|
|
438
|
+
</CellWithTooltip>
|
|
439
|
+
);
|
|
440
|
+
} else {
|
|
441
|
+
return null;
|
|
442
|
+
}
|
|
443
|
+
},
|
|
444
|
+
};
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
// Placeholder Column Renderer
|
|
448
|
+
export const renderPlaceholderColumn = ({ column, commonProps }) => {
|
|
449
|
+
return {
|
|
450
|
+
...commonProps,
|
|
451
|
+
name: column.id,
|
|
452
|
+
sortable: false,
|
|
453
|
+
render: ({ data }) => {
|
|
454
|
+
if (data) {
|
|
455
|
+
return (
|
|
456
|
+
<CellWithTooltip
|
|
457
|
+
value={column.placeholder}
|
|
458
|
+
columnType="placeholder"
|
|
459
|
+
>
|
|
460
|
+
<span>{column.placeholder}</span>
|
|
461
|
+
</CellWithTooltip>
|
|
462
|
+
);
|
|
463
|
+
} else {
|
|
464
|
+
return null;
|
|
465
|
+
}
|
|
466
|
+
},
|
|
467
|
+
};
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
// Age Column Renderer
|
|
471
|
+
export const renderAgeColumn = ({ column, commonProps, filterEditor }) => {
|
|
472
|
+
return {
|
|
473
|
+
...commonProps,
|
|
474
|
+
type: 'number',
|
|
475
|
+
filterEditor: filterEditor,
|
|
476
|
+
name: `${column.type}.${column.id}`,
|
|
477
|
+
render: ({ data }) => {
|
|
478
|
+
const value = column.id.reduce((acc, id) => {
|
|
479
|
+
if (acc === '') {
|
|
480
|
+
return data[id];
|
|
481
|
+
} else {
|
|
482
|
+
return acc ? acc[id] : '';
|
|
483
|
+
}
|
|
484
|
+
}, '');
|
|
485
|
+
|
|
486
|
+
if (value !== '' && value !== null) {
|
|
487
|
+
const date = moment(value);
|
|
488
|
+
|
|
489
|
+
return (
|
|
490
|
+
<span>
|
|
491
|
+
{moment().diff(
|
|
492
|
+
date,
|
|
493
|
+
column.duration ? column.duration : 'years'
|
|
494
|
+
)}
|
|
495
|
+
</span>
|
|
496
|
+
);
|
|
497
|
+
} else {
|
|
498
|
+
return null;
|
|
499
|
+
}
|
|
500
|
+
},
|
|
501
|
+
};
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
// Coding Column Renderer
|
|
505
|
+
export const renderCodingColumn = ({ column, commonProps, handleCoding }) => {
|
|
506
|
+
return {
|
|
507
|
+
...commonProps,
|
|
508
|
+
name: `${column.type}.${column.id}`,
|
|
509
|
+
sortable: false,
|
|
510
|
+
render: ({ data }) => {
|
|
511
|
+
if (data) {
|
|
512
|
+
return handleCoding(column, data);
|
|
513
|
+
} else {
|
|
514
|
+
return null;
|
|
515
|
+
}
|
|
516
|
+
},
|
|
517
|
+
};
|
|
518
|
+
};
|
|
519
|
+
|
|
520
|
+
// Relation Column Renderer
|
|
521
|
+
export const renderRelationColumn = ({ column, commonProps, filterEditor, filterEditorProps, relationName }) => {
|
|
522
|
+
return {
|
|
523
|
+
...commonProps,
|
|
524
|
+
name: relationName,
|
|
525
|
+
sortable: false,
|
|
526
|
+
filterEditor: filterEditor,
|
|
527
|
+
filterEditorProps: filterEditorProps,
|
|
528
|
+
render: ({ data }) => {
|
|
529
|
+
let value = column.id.reduce((acc, id) => {
|
|
530
|
+
if (acc === '') {
|
|
531
|
+
if (data[id]) {
|
|
532
|
+
return data[id];
|
|
533
|
+
} else {
|
|
534
|
+
return '';
|
|
535
|
+
}
|
|
536
|
+
} else {
|
|
537
|
+
if (acc && acc[id]) {
|
|
538
|
+
return acc[id];
|
|
539
|
+
} else {
|
|
540
|
+
return '';
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}, '');
|
|
544
|
+
|
|
545
|
+
if (value) {
|
|
546
|
+
if (Array.isArray(value)) {
|
|
547
|
+
if (value[0]) {
|
|
548
|
+
value = value[0];
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
if (Array.isArray(column.nameFrom)) {
|
|
553
|
+
value = column.nameFrom
|
|
554
|
+
.map((nf) => value?.[nf] ?? '')
|
|
555
|
+
.join(' ');
|
|
556
|
+
} else {
|
|
557
|
+
if (
|
|
558
|
+
value &&
|
|
559
|
+
value.hasOwnProperty(column.nameFrom)
|
|
560
|
+
) {
|
|
561
|
+
value = value[column.nameFrom];
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
if (
|
|
566
|
+
column.placeholder &&
|
|
567
|
+
column.placeholder !== ''
|
|
568
|
+
) {
|
|
569
|
+
return (
|
|
570
|
+
<span>
|
|
571
|
+
{column.placeholder}
|
|
572
|
+
</span>
|
|
573
|
+
);
|
|
574
|
+
} else {
|
|
575
|
+
if (column.hasOwnProperty('format')) {
|
|
576
|
+
if (column.format) {
|
|
577
|
+
value = moment(value).format('DD-MM-YYYY');
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
if (
|
|
582
|
+
typeof value === 'string' ||
|
|
583
|
+
typeof value === 'number'
|
|
584
|
+
) {
|
|
585
|
+
return (
|
|
586
|
+
<CellWithTooltip
|
|
587
|
+
value={value}
|
|
588
|
+
columnType="relation"
|
|
589
|
+
>
|
|
590
|
+
<span>{value}</span>
|
|
591
|
+
</CellWithTooltip>
|
|
592
|
+
);
|
|
593
|
+
} else {
|
|
594
|
+
return null;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
} else {
|
|
598
|
+
return null;
|
|
599
|
+
}
|
|
600
|
+
},
|
|
601
|
+
};
|
|
602
|
+
};
|
|
603
|
+
|
|
604
|
+
// RelationArray Column Renderer
|
|
605
|
+
export const renderRelationArrayColumn = ({ column, commonProps, filterEditor, filterEditorProps, relationName }) => {
|
|
606
|
+
return {
|
|
607
|
+
...commonProps,
|
|
608
|
+
name: relationName,
|
|
609
|
+
sortable: false,
|
|
610
|
+
filterEditor: filterEditor,
|
|
611
|
+
filterEditorProps: filterEditorProps,
|
|
612
|
+
render: ({ data }) => {
|
|
613
|
+
const relationValue = column.id.reduce(
|
|
614
|
+
(acc, id) =>
|
|
615
|
+
acc === ''
|
|
616
|
+
? data[id]
|
|
617
|
+
: acc && acc[id]
|
|
618
|
+
? acc[id]
|
|
619
|
+
: '',
|
|
620
|
+
''
|
|
621
|
+
);
|
|
622
|
+
|
|
623
|
+
if (
|
|
624
|
+
relationValue &&
|
|
625
|
+
Array.isArray(relationValue) &&
|
|
626
|
+
relationValue.length > 0
|
|
627
|
+
) {
|
|
628
|
+
const nameProperties =
|
|
629
|
+
Array.isArray(column.nameFrom)
|
|
630
|
+
? column.nameFrom
|
|
631
|
+
: [column.nameFrom];
|
|
632
|
+
|
|
633
|
+
const values = relationValue
|
|
634
|
+
.map((rv) => {
|
|
635
|
+
if (
|
|
636
|
+
column.childId &&
|
|
637
|
+
Array.isArray(column.childId)
|
|
638
|
+
) {
|
|
639
|
+
let childValue = rv;
|
|
640
|
+
|
|
641
|
+
column.childId.forEach((a) => {
|
|
642
|
+
if (childValue[a]) {
|
|
643
|
+
childValue = childValue[a];
|
|
644
|
+
}
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
if (childValue) {
|
|
648
|
+
const propertyValues =
|
|
649
|
+
nameProperties
|
|
650
|
+
.map((prop) => childValue[prop])
|
|
651
|
+
.filter(
|
|
652
|
+
(value) =>
|
|
653
|
+
value !== undefined &&
|
|
654
|
+
value !== null
|
|
655
|
+
);
|
|
656
|
+
return propertyValues.join(' ');
|
|
657
|
+
}
|
|
658
|
+
} else {
|
|
659
|
+
const propertyValues =
|
|
660
|
+
nameProperties
|
|
661
|
+
.map((prop) => rv[prop])
|
|
662
|
+
.filter(
|
|
663
|
+
(value) =>
|
|
664
|
+
value !== undefined &&
|
|
665
|
+
value !== null
|
|
666
|
+
);
|
|
667
|
+
return propertyValues.join(' ');
|
|
668
|
+
}
|
|
669
|
+
})
|
|
670
|
+
.filter((value) => value !== '');
|
|
671
|
+
|
|
672
|
+
let result = '';
|
|
673
|
+
|
|
674
|
+
if (
|
|
675
|
+
column.relation?.id &&
|
|
676
|
+
column.relation?.key
|
|
677
|
+
) {
|
|
678
|
+
const relationValue =
|
|
679
|
+
column.relation.key.reduce(
|
|
680
|
+
(acc, id) =>
|
|
681
|
+
acc === ''
|
|
682
|
+
? data[id]
|
|
683
|
+
: acc && acc[id]
|
|
684
|
+
? acc[id]
|
|
685
|
+
: '',
|
|
686
|
+
''
|
|
687
|
+
);
|
|
688
|
+
|
|
689
|
+
result = `${relationValue[column.relation.id]}<br />`;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
if (
|
|
693
|
+
column.where &&
|
|
694
|
+
column.where.id &&
|
|
695
|
+
column.where.value
|
|
696
|
+
) {
|
|
697
|
+
if (
|
|
698
|
+
data[column.where.id] ===
|
|
699
|
+
column.where.value
|
|
700
|
+
) {
|
|
701
|
+
result += values.join('<br />');
|
|
702
|
+
}
|
|
703
|
+
} else {
|
|
704
|
+
result += values.join('<br />');
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
return (
|
|
708
|
+
<CellWithTooltip
|
|
709
|
+
value={result}
|
|
710
|
+
columnType="relationArray"
|
|
711
|
+
>
|
|
712
|
+
<span>{parse(result)}</span>
|
|
713
|
+
</CellWithTooltip>
|
|
714
|
+
);
|
|
715
|
+
} else {
|
|
716
|
+
let result = '';
|
|
717
|
+
|
|
718
|
+
if (
|
|
719
|
+
column.relation?.id &&
|
|
720
|
+
column.relation?.key
|
|
721
|
+
) {
|
|
722
|
+
const relationValue =
|
|
723
|
+
column.relation.key.reduce(
|
|
724
|
+
(acc, id) =>
|
|
725
|
+
acc === ''
|
|
726
|
+
? data[id]
|
|
727
|
+
: acc && acc[id]
|
|
728
|
+
? acc[id]
|
|
729
|
+
: '',
|
|
730
|
+
''
|
|
731
|
+
);
|
|
732
|
+
|
|
733
|
+
result =
|
|
734
|
+
relationValue &&
|
|
735
|
+
relationValue[column.relation.id]
|
|
736
|
+
? relationValue[column.relation.id]
|
|
737
|
+
: '';
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
return (
|
|
741
|
+
<CellWithTooltip
|
|
742
|
+
value={result}
|
|
743
|
+
columnType="relationArray"
|
|
744
|
+
>
|
|
745
|
+
<span>{parse(result)}</span>
|
|
746
|
+
</CellWithTooltip>
|
|
747
|
+
);
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
return null;
|
|
751
|
+
},
|
|
752
|
+
};
|
|
753
|
+
};
|
|
754
|
+
|
|
755
|
+
// RichText Column Renderer
|
|
756
|
+
export const renderRichTextColumn = ({ column, commonProps }) => {
|
|
757
|
+
return {
|
|
758
|
+
...commonProps,
|
|
759
|
+
name: column.id,
|
|
760
|
+
render: ({ data }) => {
|
|
761
|
+
if (data && data[column.id]) {
|
|
762
|
+
return (
|
|
763
|
+
<CellWithTooltip
|
|
764
|
+
value={data[column.id]}
|
|
765
|
+
columnType="richtext"
|
|
766
|
+
>
|
|
767
|
+
<span>
|
|
768
|
+
{parse(data[column.id])}
|
|
769
|
+
</span>
|
|
770
|
+
</CellWithTooltip>
|
|
771
|
+
);
|
|
772
|
+
} else {
|
|
773
|
+
return null;
|
|
774
|
+
}
|
|
775
|
+
},
|
|
776
|
+
};
|
|
777
|
+
};
|
|
778
|
+
|
|
779
|
+
// Stage Column Renderer
|
|
780
|
+
export const renderStageColumn = ({ column, commonProps }) => {
|
|
781
|
+
return {
|
|
782
|
+
...commonProps,
|
|
783
|
+
name: column.id,
|
|
784
|
+
sortable: false,
|
|
785
|
+
render: ({ data }) => {
|
|
786
|
+
let stage = '';
|
|
787
|
+
|
|
788
|
+
column.keyIds.forEach((a, b) => {
|
|
789
|
+
if (data[a] === 1) {
|
|
790
|
+
stage = column.valueIds[b];
|
|
791
|
+
}
|
|
792
|
+
});
|
|
793
|
+
|
|
794
|
+
return (
|
|
795
|
+
<CellWithTooltip
|
|
796
|
+
value={stage}
|
|
797
|
+
columnType="stage"
|
|
798
|
+
>
|
|
799
|
+
<span>{stage}</span>
|
|
800
|
+
</CellWithTooltip>
|
|
801
|
+
);
|
|
802
|
+
},
|
|
803
|
+
};
|
|
804
|
+
};
|
|
805
|
+
|
|
806
|
+
// Time Column Renderer
|
|
807
|
+
export const renderTimeColumn = ({ column, commonProps }) => {
|
|
808
|
+
return {
|
|
809
|
+
...commonProps,
|
|
810
|
+
name: column.id,
|
|
811
|
+
render: ({ data }) => {
|
|
812
|
+
if (
|
|
813
|
+
data &&
|
|
814
|
+
data[column.id] &&
|
|
815
|
+
moment(data[column.id]).isValid() &&
|
|
816
|
+
moment(data[column.id]).format('YYYY-MM-DD') !== '1970-01-01'
|
|
817
|
+
) {
|
|
818
|
+
const formattedTime = moment(data[column.id]).format(
|
|
819
|
+
column.format ? column.format : 'hh:mm A'
|
|
820
|
+
);
|
|
821
|
+
|
|
822
|
+
return (
|
|
823
|
+
<CellWithTooltip
|
|
824
|
+
value={data[column.id]}
|
|
825
|
+
columnType="time"
|
|
826
|
+
>
|
|
827
|
+
<span>{formattedTime}</span>
|
|
828
|
+
</CellWithTooltip>
|
|
829
|
+
);
|
|
830
|
+
} else {
|
|
831
|
+
return null;
|
|
832
|
+
}
|
|
833
|
+
},
|
|
834
|
+
};
|
|
835
|
+
};
|
|
836
|
+
|
|
837
|
+
// Timer Column Renderer
|
|
838
|
+
export const renderTimerColumn = ({ column, commonProps, handleTimer, form, columns, styles }) => {
|
|
839
|
+
return {
|
|
840
|
+
...commonProps,
|
|
841
|
+
name: column.id,
|
|
842
|
+
render: ({ data }) => {
|
|
843
|
+
if (
|
|
844
|
+
data &&
|
|
845
|
+
data[column.id] &&
|
|
846
|
+
moment(data[column.id]).isValid() &&
|
|
847
|
+
moment(data[column.id]).format('YYYY-MM-DD') !== '1970-01-01'
|
|
848
|
+
) {
|
|
849
|
+
const formattedData = moment(data[column.id]).format(
|
|
850
|
+
column.format ? column.format : 'DD-MM-YYYY hh:mm A'
|
|
851
|
+
);
|
|
852
|
+
|
|
853
|
+
return (
|
|
854
|
+
<CellWithTooltip
|
|
855
|
+
value={data[column.id]}
|
|
856
|
+
columnType="timer"
|
|
857
|
+
>
|
|
858
|
+
<span>{formattedData}</span>
|
|
859
|
+
</CellWithTooltip>
|
|
860
|
+
);
|
|
861
|
+
} else {
|
|
862
|
+
let shouldRenderButton = false;
|
|
863
|
+
|
|
864
|
+
if (
|
|
865
|
+
!column.hasOwnProperty('require') ||
|
|
866
|
+
column.require.length === 0
|
|
867
|
+
) {
|
|
868
|
+
shouldRenderButton = true;
|
|
869
|
+
} else {
|
|
870
|
+
for (const req of column.require) {
|
|
871
|
+
if (req.hasOwnProperty('id')) {
|
|
872
|
+
const hasValue = req.hasOwnProperty('value');
|
|
873
|
+
if (
|
|
874
|
+
(hasValue && data[req.id] === req.value) ||
|
|
875
|
+
(!hasValue && data[req.id])
|
|
876
|
+
) {
|
|
877
|
+
shouldRenderButton = true;
|
|
878
|
+
} else {
|
|
879
|
+
shouldRenderButton = false;
|
|
880
|
+
break;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
if (shouldRenderButton) {
|
|
887
|
+
return (
|
|
888
|
+
<button
|
|
889
|
+
className={styles.clockButton}
|
|
890
|
+
onClick={(e) => {
|
|
891
|
+
e.stopPropagation();
|
|
892
|
+
e.preventDefault();
|
|
893
|
+
|
|
894
|
+
// Check if every required field in column.validate exists and is truthy in data
|
|
895
|
+
if (
|
|
896
|
+
column.validate &&
|
|
897
|
+
column.validate.length > 0
|
|
898
|
+
) {
|
|
899
|
+
const missingFields = column.validate.filter(
|
|
900
|
+
(v) => !data[v]
|
|
901
|
+
);
|
|
902
|
+
|
|
903
|
+
if (missingFields.length === 0) {
|
|
904
|
+
handleTimer(
|
|
905
|
+
data[form.primaryKey],
|
|
906
|
+
column.id,
|
|
907
|
+
data
|
|
908
|
+
);
|
|
909
|
+
} else {
|
|
910
|
+
// Format field names to be more readable
|
|
911
|
+
const formattedFields = missingFields.map(
|
|
912
|
+
(field) => {
|
|
913
|
+
// Try to find the column with this field ID to get its label
|
|
914
|
+
const fieldColumn = columns.find(
|
|
915
|
+
(col) => col.id === field
|
|
916
|
+
);
|
|
917
|
+
// Use the label if found, otherwise use the field ID
|
|
918
|
+
return fieldColumn?.label || field;
|
|
919
|
+
}
|
|
920
|
+
);
|
|
921
|
+
|
|
922
|
+
const fieldList = formattedFields.join(', ');
|
|
923
|
+
toast.error(
|
|
924
|
+
`Please complete the following required field${
|
|
925
|
+
missingFields.length > 1 ? 's' : ''
|
|
926
|
+
} before starting the timer: ${fieldList}`
|
|
927
|
+
);
|
|
928
|
+
}
|
|
929
|
+
} else {
|
|
930
|
+
handleTimer(
|
|
931
|
+
data[form.primaryKey],
|
|
932
|
+
column.id,
|
|
933
|
+
data
|
|
934
|
+
);
|
|
935
|
+
}
|
|
936
|
+
}}
|
|
937
|
+
>
|
|
938
|
+
<Alarm
|
|
939
|
+
data-tooltip-id="system-tooltip"
|
|
940
|
+
data-tooltip-content={`${column.label} Timer`}
|
|
941
|
+
strokeWidth={2}
|
|
942
|
+
size={14}
|
|
943
|
+
style={{
|
|
944
|
+
color: 'white',
|
|
945
|
+
}}
|
|
946
|
+
/>
|
|
947
|
+
</button>
|
|
948
|
+
);
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
// Return a placeholder div to maintain consistent row height
|
|
952
|
+
return (
|
|
953
|
+
<div
|
|
954
|
+
style={{
|
|
955
|
+
width: '28px',
|
|
956
|
+
height: '28px',
|
|
957
|
+
display: 'flex',
|
|
958
|
+
alignItems: 'center',
|
|
959
|
+
justifyContent: 'center',
|
|
960
|
+
margin: '0 auto',
|
|
961
|
+
}}
|
|
962
|
+
>
|
|
963
|
+
{/* Empty placeholder to maintain layout */}
|
|
964
|
+
</div>
|
|
965
|
+
);
|
|
966
|
+
}
|
|
967
|
+
},
|
|
968
|
+
};
|
|
969
|
+
};
|
|
970
|
+
|
|
971
|
+
// URL Column Renderer
|
|
972
|
+
export const renderUrlColumn = ({ column, commonProps }) => {
|
|
973
|
+
return {
|
|
974
|
+
...commonProps,
|
|
975
|
+
name: column.id,
|
|
976
|
+
render: ({ data }) => {
|
|
977
|
+
if (data && data[column.id]) {
|
|
978
|
+
return (
|
|
979
|
+
<CellWithTooltip
|
|
980
|
+
value={data[column.id]}
|
|
981
|
+
columnType="url"
|
|
982
|
+
>
|
|
983
|
+
<span>
|
|
984
|
+
<a
|
|
985
|
+
href={data[column.id]}
|
|
986
|
+
target="_blank"
|
|
987
|
+
>
|
|
988
|
+
Link
|
|
989
|
+
</a>
|
|
990
|
+
</span>
|
|
991
|
+
</CellWithTooltip>
|
|
992
|
+
);
|
|
993
|
+
} else {
|
|
994
|
+
return null;
|
|
995
|
+
}
|
|
996
|
+
},
|
|
997
|
+
};
|
|
998
|
+
};
|
|
999
|
+
|
|
1000
|
+
// Input Text Column Renderer
|
|
1001
|
+
export const renderInputTextColumn = ({
|
|
1002
|
+
column,
|
|
1003
|
+
commonProps,
|
|
1004
|
+
localInputValuesRef,
|
|
1005
|
+
setLocalInputValues,
|
|
1006
|
+
handleInputUpdate
|
|
1007
|
+
}) => {
|
|
1008
|
+
return {
|
|
1009
|
+
...commonProps,
|
|
1010
|
+
name: column.id,
|
|
1011
|
+
render: ({ data }) => {
|
|
1012
|
+
const inputKey = `${data.id}-${column.id}`;
|
|
1013
|
+
|
|
1014
|
+
// Use the ref value first, then fall back to data value
|
|
1015
|
+
const currentValue =
|
|
1016
|
+
localInputValuesRef.current[inputKey] !== undefined
|
|
1017
|
+
? localInputValuesRef.current[inputKey]
|
|
1018
|
+
: data[column.id] || '';
|
|
1019
|
+
|
|
1020
|
+
return (
|
|
1021
|
+
<input
|
|
1022
|
+
type="text"
|
|
1023
|
+
name={column.id}
|
|
1024
|
+
value={currentValue}
|
|
1025
|
+
style={{
|
|
1026
|
+
padding: '7px',
|
|
1027
|
+
width: '100%',
|
|
1028
|
+
}}
|
|
1029
|
+
onChange={(e) => {
|
|
1030
|
+
const newValue = e.target.value;
|
|
1031
|
+
|
|
1032
|
+
// Update both state and ref
|
|
1033
|
+
localInputValuesRef.current = {
|
|
1034
|
+
...localInputValuesRef.current,
|
|
1035
|
+
[inputKey]: newValue,
|
|
1036
|
+
};
|
|
1037
|
+
|
|
1038
|
+
setLocalInputValues((prev) => ({
|
|
1039
|
+
...prev,
|
|
1040
|
+
[inputKey]: newValue,
|
|
1041
|
+
}));
|
|
1042
|
+
|
|
1043
|
+
if (
|
|
1044
|
+
column.update?.key &&
|
|
1045
|
+
column.update?.url &&
|
|
1046
|
+
column.update?.method
|
|
1047
|
+
) {
|
|
1048
|
+
handleInputUpdate(
|
|
1049
|
+
column.update.key,
|
|
1050
|
+
`${column.update.url}/${data.id}`,
|
|
1051
|
+
column.update.method,
|
|
1052
|
+
newValue,
|
|
1053
|
+
inputKey
|
|
1054
|
+
);
|
|
1055
|
+
}
|
|
1056
|
+
}}
|
|
1057
|
+
onBlur={() => {
|
|
1058
|
+
if (
|
|
1059
|
+
column.update?.key &&
|
|
1060
|
+
column.update?.url &&
|
|
1061
|
+
column.update?.method
|
|
1062
|
+
) {
|
|
1063
|
+
handleInputUpdate.flush();
|
|
1064
|
+
}
|
|
1065
|
+
}}
|
|
1066
|
+
/>
|
|
1067
|
+
);
|
|
1068
|
+
},
|
|
1069
|
+
};
|
|
1070
|
+
};
|
|
1071
|
+
|
|
1072
|
+
// Address Column Renderer
|
|
1073
|
+
export const renderAddressColumn = ({ column, commonProps, filterEditor, filterEditorProps }) => {
|
|
1074
|
+
return {
|
|
1075
|
+
...commonProps,
|
|
1076
|
+
name: `${column.type}.${column.id}`,
|
|
1077
|
+
filterEditor: filterEditor,
|
|
1078
|
+
filterEditorProps: filterEditorProps,
|
|
1079
|
+
render: ({ data }) => {
|
|
1080
|
+
const addressFields = [
|
|
1081
|
+
'address1',
|
|
1082
|
+
'address2',
|
|
1083
|
+
'suburb',
|
|
1084
|
+
'postcode',
|
|
1085
|
+
];
|
|
1086
|
+
|
|
1087
|
+
const addressValue = addressFields
|
|
1088
|
+
.filter((field) => data[field])
|
|
1089
|
+
.map((field) => data[field])
|
|
1090
|
+
.join(' ');
|
|
1091
|
+
|
|
1092
|
+
const stateValue =
|
|
1093
|
+
data.state?.name ||
|
|
1094
|
+
data.state ||
|
|
1095
|
+
'';
|
|
1096
|
+
|
|
1097
|
+
const value = `${addressValue} ${stateValue}`;
|
|
1098
|
+
|
|
1099
|
+
return (
|
|
1100
|
+
<CellWithTooltip
|
|
1101
|
+
value={value}
|
|
1102
|
+
columnType="address"
|
|
1103
|
+
>
|
|
1104
|
+
<span>{value}</span>
|
|
1105
|
+
</CellWithTooltip>
|
|
1106
|
+
);
|
|
1107
|
+
},
|
|
1108
|
+
};
|
|
1109
|
+
};
|
|
1110
|
+
|
|
1111
|
+
// Created By Column Renderer
|
|
1112
|
+
export const renderCreatedByColumn = ({ column, commonProps }) => {
|
|
1113
|
+
return {
|
|
1114
|
+
...commonProps,
|
|
1115
|
+
name: `${column.type}.${column.id}`,
|
|
1116
|
+
sortable: false,
|
|
1117
|
+
render: ({ data }) => {
|
|
1118
|
+
if (
|
|
1119
|
+
data.audits[0] &&
|
|
1120
|
+
data.audits[0].user &&
|
|
1121
|
+
data.audits[0].user.name
|
|
1122
|
+
) {
|
|
1123
|
+
const value = data.audits[0].user.name;
|
|
1124
|
+
|
|
1125
|
+
return <span>{value}</span>;
|
|
1126
|
+
} else {
|
|
1127
|
+
return null;
|
|
1128
|
+
}
|
|
1129
|
+
},
|
|
1130
|
+
};
|
|
1131
|
+
};
|
|
1132
|
+
|
|
1133
|
+
// Date Range Column Renderer
|
|
1134
|
+
export const renderDateRangeColumn = ({ column, commonProps, filterEditor, filterEditorProps }) => {
|
|
1135
|
+
return {
|
|
1136
|
+
...commonProps,
|
|
1137
|
+
name: `${column.id[0]}.${column.id[1]}.`,
|
|
1138
|
+
filterEditor: filterEditor,
|
|
1139
|
+
filterEditorProps: filterEditorProps,
|
|
1140
|
+
defaultWidth: 200, // Set default width for daterange columns
|
|
1141
|
+
minWidth: 200, // Set minimum width for daterange columns
|
|
1142
|
+
render: ({ data }) => {
|
|
1143
|
+
let value = '';
|
|
1144
|
+
|
|
1145
|
+
if (
|
|
1146
|
+
data &&
|
|
1147
|
+
data[column.id[0]] &&
|
|
1148
|
+
moment(data[column.id[0]]).isValid() &&
|
|
1149
|
+
moment(data[column.id[0]]).format('YYYY-MM-DD') !== '1970-01-01'
|
|
1150
|
+
) {
|
|
1151
|
+
value = moment(data[column.id[0]]).format(
|
|
1152
|
+
column.format || 'DD-MM-YYYY'
|
|
1153
|
+
);
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
if (
|
|
1157
|
+
data &&
|
|
1158
|
+
data[column.id[1]] &&
|
|
1159
|
+
moment(data[column.id[1]]).isValid() &&
|
|
1160
|
+
moment(data[column.id[1]]).format('YYYY-MM-DD') !== '1970-01-01'
|
|
1161
|
+
) {
|
|
1162
|
+
value += ` - ${moment(data[column.id[1]]).format(
|
|
1163
|
+
column.format || 'DD-MM-YYYY'
|
|
1164
|
+
)}`;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
return <span>{value}</span>;
|
|
1168
|
+
},
|
|
1169
|
+
};
|
|
1170
|
+
};
|
|
1171
|
+
|
|
1172
|
+
// Stage Counter Column Renderer
|
|
1173
|
+
export const renderStageCounterColumn = ({ column, commonProps, navigate }) => {
|
|
1174
|
+
return {
|
|
1175
|
+
...commonProps,
|
|
1176
|
+
name: column.id,
|
|
1177
|
+
sortable: false,
|
|
1178
|
+
render: ({ data }) => {
|
|
1179
|
+
if (
|
|
1180
|
+
data &&
|
|
1181
|
+
column.stageConfig &&
|
|
1182
|
+
column.stageConfig.key
|
|
1183
|
+
) {
|
|
1184
|
+
// Check if the data has the specified key and it's an array
|
|
1185
|
+
const stageData = data[column.stageConfig.key];
|
|
1186
|
+
|
|
1187
|
+
if (
|
|
1188
|
+
stageData &&
|
|
1189
|
+
Array.isArray(stageData)
|
|
1190
|
+
) {
|
|
1191
|
+
const stageCount = stageData.length;
|
|
1192
|
+
|
|
1193
|
+
// Create a clickable element if link is provided
|
|
1194
|
+
const handleClick = (e) => {
|
|
1195
|
+
e.stopPropagation();
|
|
1196
|
+
e.preventDefault();
|
|
1197
|
+
|
|
1198
|
+
if (
|
|
1199
|
+
column.link &&
|
|
1200
|
+
column.link.url &&
|
|
1201
|
+
column.link.key &&
|
|
1202
|
+
navigate
|
|
1203
|
+
) {
|
|
1204
|
+
navigate(
|
|
1205
|
+
`${column.link.url}${data[column.link.key]}`
|
|
1206
|
+
);
|
|
1207
|
+
}
|
|
1208
|
+
};
|
|
1209
|
+
|
|
1210
|
+
// Create an array of squares based on the stage data
|
|
1211
|
+
const squares = [];
|
|
1212
|
+
for (let i = 0; i < stageCount; i++) {
|
|
1213
|
+
// Get the stage item
|
|
1214
|
+
const stageItem = stageData[i];
|
|
1215
|
+
|
|
1216
|
+
// Get the label value from the stage item using stageLabelKey if provided
|
|
1217
|
+
let labelValue = '';
|
|
1218
|
+
if (
|
|
1219
|
+
column.stageConfig.stageLabelKey &&
|
|
1220
|
+
stageItem &&
|
|
1221
|
+
stageItem[column.stageConfig.stageLabelKey] !== undefined
|
|
1222
|
+
) {
|
|
1223
|
+
// Get the value from the stage item
|
|
1224
|
+
const rawValue = stageItem[column.stageConfig.stageLabelKey];
|
|
1225
|
+
|
|
1226
|
+
// If it's an object with a name property, use that
|
|
1227
|
+
if (
|
|
1228
|
+
rawValue &&
|
|
1229
|
+
typeof rawValue === 'object' &&
|
|
1230
|
+
rawValue.name
|
|
1231
|
+
) {
|
|
1232
|
+
labelValue = rawValue.name.charAt(0);
|
|
1233
|
+
}
|
|
1234
|
+
// If it's a string, use the first character
|
|
1235
|
+
else if (
|
|
1236
|
+
typeof rawValue === 'string' &&
|
|
1237
|
+
rawValue.length > 0
|
|
1238
|
+
) {
|
|
1239
|
+
labelValue = rawValue.charAt(0);
|
|
1240
|
+
}
|
|
1241
|
+
// Otherwise use the raw value if it can be converted to string
|
|
1242
|
+
else if (
|
|
1243
|
+
rawValue !== null &&
|
|
1244
|
+
rawValue !== undefined
|
|
1245
|
+
) {
|
|
1246
|
+
labelValue = String(rawValue).charAt(0);
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
// Create tooltip content from the full value if available
|
|
1251
|
+
let tooltipContent = `Stage ${i + 1}`;
|
|
1252
|
+
if (
|
|
1253
|
+
column.stageConfig.stageLabelKey &&
|
|
1254
|
+
stageItem &&
|
|
1255
|
+
stageItem[column.stageConfig.stageLabelKey]
|
|
1256
|
+
) {
|
|
1257
|
+
const rawValue = stageItem[column.stageConfig.stageLabelKey];
|
|
1258
|
+
if (
|
|
1259
|
+
rawValue &&
|
|
1260
|
+
typeof rawValue === 'object' &&
|
|
1261
|
+
rawValue.name
|
|
1262
|
+
) {
|
|
1263
|
+
tooltipContent = `${rawValue.name} (Stage ${i + 1})`;
|
|
1264
|
+
} else if (
|
|
1265
|
+
rawValue !== null &&
|
|
1266
|
+
rawValue !== undefined
|
|
1267
|
+
) {
|
|
1268
|
+
tooltipContent = `Stage ${i + 1})`;
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
// Determine the background color based on stageColour configuration
|
|
1273
|
+
let backgroundColor = 'var(--primary-color, #4a90e2)';
|
|
1274
|
+
|
|
1275
|
+
if (
|
|
1276
|
+
column.stageConfig.stageColour &&
|
|
1277
|
+
column.stageConfig.stageColour.key &&
|
|
1278
|
+
column.stageConfig.stageColour.options &&
|
|
1279
|
+
stageItem
|
|
1280
|
+
) {
|
|
1281
|
+
const colourKey = column.stageConfig.stageColour.key;
|
|
1282
|
+
const colourOptions = column.stageConfig.stageColour.options;
|
|
1283
|
+
|
|
1284
|
+
// Get the value for the color key
|
|
1285
|
+
if (stageItem[colourKey] !== undefined) {
|
|
1286
|
+
const keyValue = stageItem[colourKey];
|
|
1287
|
+
|
|
1288
|
+
// Find matching option
|
|
1289
|
+
const matchingOption = colourOptions.find((option) => {
|
|
1290
|
+
// Handle both direct value and object with id
|
|
1291
|
+
if (
|
|
1292
|
+
typeof keyValue === 'object' &&
|
|
1293
|
+
keyValue !== null
|
|
1294
|
+
) {
|
|
1295
|
+
// Use loose equality (==) to handle type coercion between string and number
|
|
1296
|
+
return keyValue.id == option.id;
|
|
1297
|
+
}
|
|
1298
|
+
// Use loose equality (==) to handle type coercion between string and number
|
|
1299
|
+
return keyValue == option.id;
|
|
1300
|
+
});
|
|
1301
|
+
|
|
1302
|
+
// Use the color from the matching option if found
|
|
1303
|
+
if (
|
|
1304
|
+
matchingOption &&
|
|
1305
|
+
matchingOption.colour
|
|
1306
|
+
) {
|
|
1307
|
+
backgroundColor = matchingOption.colour;
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
squares.push(
|
|
1313
|
+
<div
|
|
1314
|
+
key={i}
|
|
1315
|
+
style={{
|
|
1316
|
+
width: '20px',
|
|
1317
|
+
height: '20px',
|
|
1318
|
+
backgroundColor: backgroundColor,
|
|
1319
|
+
borderRadius: '3px',
|
|
1320
|
+
margin: '0 2px',
|
|
1321
|
+
display: 'flex',
|
|
1322
|
+
justifyContent: 'center',
|
|
1323
|
+
alignItems: 'center',
|
|
1324
|
+
color: 'white',
|
|
1325
|
+
fontSize: '11px',
|
|
1326
|
+
fontWeight: 'bold',
|
|
1327
|
+
}}
|
|
1328
|
+
data-tooltip-id="system-tooltip"
|
|
1329
|
+
data-tooltip-content={tooltipContent}
|
|
1330
|
+
>
|
|
1331
|
+
{labelValue}
|
|
1332
|
+
</div>
|
|
1333
|
+
);
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
return (
|
|
1337
|
+
<div
|
|
1338
|
+
onClick={handleClick}
|
|
1339
|
+
style={{
|
|
1340
|
+
display: 'flex',
|
|
1341
|
+
flexWrap: 'wrap',
|
|
1342
|
+
justifyContent: 'center',
|
|
1343
|
+
alignItems: 'center',
|
|
1344
|
+
cursor: column.link ? 'pointer' : 'default',
|
|
1345
|
+
gap: '4px',
|
|
1346
|
+
padding: '2px 0',
|
|
1347
|
+
maxWidth: '100%',
|
|
1348
|
+
}}
|
|
1349
|
+
>
|
|
1350
|
+
{squares}
|
|
1351
|
+
</div>
|
|
1352
|
+
);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
return null;
|
|
1356
|
+
},
|
|
1357
|
+
};
|
|
1358
|
+
};
|