@visns-studio/visns-components 5.12.12 → 5.12.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
88
88
|
},
|
|
89
89
|
"name": "@visns-studio/visns-components",
|
|
90
|
-
"version": "5.12.
|
|
90
|
+
"version": "5.12.13",
|
|
91
91
|
"description": "Various packages to assist in the development of our Custom Applications.",
|
|
92
92
|
"main": "src/index.js",
|
|
93
93
|
"files": [
|
|
@@ -10,6 +10,64 @@ import CustomFetch from '../Fetch';
|
|
|
10
10
|
import MultiSelect from '../MultiSelect';
|
|
11
11
|
import styles from '../styles/GenericEditableTable.module.scss';
|
|
12
12
|
|
|
13
|
+
// Simple Tooltip Component
|
|
14
|
+
const Tooltip = ({ children, text, position = 'top' }) => {
|
|
15
|
+
const [isVisible, setIsVisible] = useState(false);
|
|
16
|
+
const [coords, setCoords] = useState({ x: 0, y: 0 });
|
|
17
|
+
const elementRef = useRef(null);
|
|
18
|
+
|
|
19
|
+
const handleMouseEnter = () => {
|
|
20
|
+
if (!elementRef.current) return;
|
|
21
|
+
const rect = elementRef.current.getBoundingClientRect();
|
|
22
|
+
const scrollLeft =
|
|
23
|
+
window.pageXOffset || document.documentElement.scrollLeft;
|
|
24
|
+
const scrollTop =
|
|
25
|
+
window.pageYOffset || document.documentElement.scrollTop;
|
|
26
|
+
|
|
27
|
+
let x = rect.left + scrollLeft + rect.width / 2;
|
|
28
|
+
let y = rect.top + scrollTop;
|
|
29
|
+
|
|
30
|
+
if (position === 'bottom') {
|
|
31
|
+
y = rect.bottom + scrollTop + 5;
|
|
32
|
+
} else if (position === 'top') {
|
|
33
|
+
y = y - 5;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
setCoords({ x, y });
|
|
37
|
+
setIsVisible(true);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const handleMouseLeave = () => {
|
|
41
|
+
setIsVisible(false);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<span
|
|
46
|
+
ref={elementRef}
|
|
47
|
+
onMouseEnter={handleMouseEnter}
|
|
48
|
+
onMouseLeave={handleMouseLeave}
|
|
49
|
+
className={styles.tooltipContainer}
|
|
50
|
+
>
|
|
51
|
+
{children}
|
|
52
|
+
{isVisible &&
|
|
53
|
+
ReactDOM.createPortal(
|
|
54
|
+
<div
|
|
55
|
+
className={`${styles.tooltip} ${
|
|
56
|
+
styles[`tooltip-${position}`]
|
|
57
|
+
}`}
|
|
58
|
+
style={{
|
|
59
|
+
left: coords.x,
|
|
60
|
+
top: coords.y,
|
|
61
|
+
}}
|
|
62
|
+
>
|
|
63
|
+
{text}
|
|
64
|
+
</div>,
|
|
65
|
+
document.body
|
|
66
|
+
)}
|
|
67
|
+
</span>
|
|
68
|
+
);
|
|
69
|
+
};
|
|
70
|
+
|
|
13
71
|
// Updated ColourPicker with an expanded pastel palette
|
|
14
72
|
const ColourPicker = ({ value, columnId, keyCounter, onChange }) => {
|
|
15
73
|
const [colorPickerShow, setColorPickerShow] = useState(false);
|
|
@@ -59,35 +117,42 @@ const ColourPicker = ({ value, columnId, keyCounter, onChange }) => {
|
|
|
59
117
|
<div className={styles.cpicker__btn}>
|
|
60
118
|
<button
|
|
61
119
|
ref={buttonRef}
|
|
62
|
-
style={
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
120
|
+
style={
|
|
121
|
+
value
|
|
122
|
+
? {
|
|
123
|
+
background: value,
|
|
124
|
+
border: '1px solid rgba(0,0,0,0.2)',
|
|
125
|
+
borderRadius: '3px',
|
|
126
|
+
width: '20px',
|
|
127
|
+
height: '20px',
|
|
128
|
+
padding: '0',
|
|
129
|
+
cursor: 'pointer',
|
|
130
|
+
display: 'flex',
|
|
131
|
+
alignItems: 'center',
|
|
132
|
+
justifyContent: 'center',
|
|
133
|
+
}
|
|
134
|
+
: {
|
|
135
|
+
background: 'transparent',
|
|
136
|
+
border: '1px solid rgba(0,0,0,0.2)',
|
|
137
|
+
borderRadius: '3px',
|
|
138
|
+
width: '20px',
|
|
139
|
+
height: '20px',
|
|
140
|
+
padding: '0',
|
|
141
|
+
cursor: 'pointer',
|
|
142
|
+
display: 'flex',
|
|
143
|
+
alignItems: 'center',
|
|
144
|
+
justifyContent: 'center',
|
|
145
|
+
}
|
|
146
|
+
}
|
|
85
147
|
onClick={(e) => {
|
|
86
148
|
e.preventDefault();
|
|
87
149
|
setColorPickerShow(!colorPickerShow);
|
|
88
150
|
}}
|
|
89
151
|
>
|
|
90
|
-
<Droplets
|
|
152
|
+
<Droplets
|
|
153
|
+
size={18}
|
|
154
|
+
style={{ color: value ? 'white' : 'black' }}
|
|
155
|
+
/>
|
|
91
156
|
</button>
|
|
92
157
|
|
|
93
158
|
{colorPickerShow &&
|
|
@@ -146,7 +211,7 @@ const GenericEditableTable = ({
|
|
|
146
211
|
const isInitialLoad = useRef(true);
|
|
147
212
|
const { columns, rows, form, title } = schedulingConfig;
|
|
148
213
|
const hasCategory = rows && rows.categoryKey; // Only group if defined
|
|
149
|
-
const hasColourColumn = columns.some(col => col.id === 'colours');
|
|
214
|
+
const hasColourColumn = columns.some((col) => col.id === 'colours');
|
|
150
215
|
|
|
151
216
|
// dataSets: each item => { created_at: string, data: array of rows }
|
|
152
217
|
const [dataSets, setDataSets] = useState([]);
|
|
@@ -158,6 +223,9 @@ const GenericEditableTable = ({
|
|
|
158
223
|
const [newEntries, setNewEntries] = useState({});
|
|
159
224
|
const [newEntry, setNewEntry] = useState({});
|
|
160
225
|
|
|
226
|
+
// Row selection state for copy functionality
|
|
227
|
+
const [selectedRows, setSelectedRows] = useState(new Set());
|
|
228
|
+
|
|
161
229
|
// On mount or when 'data' changes, read from data[schedulingConfig.rows.key] and handle both new & old formats
|
|
162
230
|
useEffect(() => {
|
|
163
231
|
const raw = data && data[schedulingConfig.rows.key];
|
|
@@ -220,6 +288,8 @@ const GenericEditableTable = ({
|
|
|
220
288
|
} else {
|
|
221
289
|
setLocalData([]);
|
|
222
290
|
}
|
|
291
|
+
// Clear selected rows when dataset changes
|
|
292
|
+
setSelectedRows(new Set());
|
|
223
293
|
}, [dataSets, activeDatasetIndex]);
|
|
224
294
|
|
|
225
295
|
// Helper to sort by sort_order
|
|
@@ -504,11 +574,50 @@ const GenericEditableTable = ({
|
|
|
504
574
|
return hasCategory ? groupCategoriesByType(localData) : [];
|
|
505
575
|
}, [localData, hasCategory]);
|
|
506
576
|
|
|
507
|
-
// 5)
|
|
577
|
+
// 5) Row selection handlers
|
|
578
|
+
const handleRowSelection = (rowId, isChecked) => {
|
|
579
|
+
setSelectedRows((prev) => {
|
|
580
|
+
const newSelected = new Set(prev);
|
|
581
|
+
if (isChecked) {
|
|
582
|
+
newSelected.add(rowId);
|
|
583
|
+
} else {
|
|
584
|
+
newSelected.delete(rowId);
|
|
585
|
+
}
|
|
586
|
+
return newSelected;
|
|
587
|
+
});
|
|
588
|
+
};
|
|
589
|
+
|
|
590
|
+
const handleSelectAll = (isChecked, dataToSelect = null) => {
|
|
591
|
+
if (isChecked) {
|
|
592
|
+
const rowIds = dataToSelect
|
|
593
|
+
? dataToSelect.map((entry) => entry.id)
|
|
594
|
+
: localData.map((entry) => entry.id);
|
|
595
|
+
setSelectedRows(new Set(rowIds));
|
|
596
|
+
} else {
|
|
597
|
+
setSelectedRows(new Set());
|
|
598
|
+
}
|
|
599
|
+
};
|
|
600
|
+
|
|
601
|
+
const isAllSelected = (dataToCheck = null) => {
|
|
602
|
+
const dataSet = dataToCheck || localData;
|
|
603
|
+
return (
|
|
604
|
+
dataSet.length > 0 &&
|
|
605
|
+
dataSet.every((entry) => selectedRows.has(entry.id))
|
|
606
|
+
);
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
// 6) Enhanced column copy with row selection
|
|
508
610
|
const handleColumnCopy = (column, group = null) => {
|
|
509
|
-
let
|
|
510
|
-
|
|
511
|
-
|
|
611
|
+
let dataToProcess = group ? group.entries : localData;
|
|
612
|
+
|
|
613
|
+
// Filter by selected rows if any are selected
|
|
614
|
+
if (selectedRows.size > 0) {
|
|
615
|
+
dataToProcess = dataToProcess.filter((entry) =>
|
|
616
|
+
selectedRows.has(entry.id)
|
|
617
|
+
);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
let values = dataToProcess.map((entry) => entry[column.id]);
|
|
512
621
|
|
|
513
622
|
const textToCopy = values
|
|
514
623
|
.filter((val) => val !== undefined && val !== null)
|
|
@@ -516,19 +625,23 @@ const GenericEditableTable = ({
|
|
|
516
625
|
|
|
517
626
|
navigator.clipboard
|
|
518
627
|
.writeText(textToCopy)
|
|
519
|
-
.then(() =>
|
|
628
|
+
.then(() => {
|
|
629
|
+
const selectionInfo =
|
|
630
|
+
selectedRows.size > 0
|
|
631
|
+
? ` (${selectedRows.size} selected rows)`
|
|
632
|
+
: ' (all rows)';
|
|
520
633
|
toast.success(
|
|
521
634
|
`Copied ${values.length} value${
|
|
522
635
|
values.length !== 1 ? 's' : ''
|
|
523
636
|
} from "${column.label}"${
|
|
524
637
|
group ? ` (Group: ${group.category})` : ''
|
|
525
|
-
}`
|
|
526
|
-
)
|
|
527
|
-
)
|
|
638
|
+
}${selectionInfo}`
|
|
639
|
+
);
|
|
640
|
+
})
|
|
528
641
|
.catch(() => toast.error('Failed to copy to clipboard'));
|
|
529
642
|
};
|
|
530
643
|
|
|
531
|
-
//
|
|
644
|
+
// 7) Sorting: grouped
|
|
532
645
|
const handleSortChangeGrouped = (groupId, entryId, direction) => {
|
|
533
646
|
if (!hasCategory) return;
|
|
534
647
|
setLocalData((prev) => {
|
|
@@ -580,7 +693,7 @@ const GenericEditableTable = ({
|
|
|
580
693
|
});
|
|
581
694
|
};
|
|
582
695
|
|
|
583
|
-
//
|
|
696
|
+
// 8) Sorting: ungrouped
|
|
584
697
|
const handleSortChangeUngrouped = (entryId, direction) => {
|
|
585
698
|
setLocalData((prev) => {
|
|
586
699
|
const sortedData = sortBySortOrder(prev);
|
|
@@ -611,7 +724,7 @@ const GenericEditableTable = ({
|
|
|
611
724
|
});
|
|
612
725
|
};
|
|
613
726
|
|
|
614
|
-
//
|
|
727
|
+
// 9) Deletion
|
|
615
728
|
const handleDeleteRow = (entry) => {
|
|
616
729
|
confirmDialog({
|
|
617
730
|
title: 'Confirm to Delete',
|
|
@@ -784,7 +897,7 @@ const GenericEditableTable = ({
|
|
|
784
897
|
// Render new row field
|
|
785
898
|
const renderNewRowField = (newRowData, column, groupId = null) => {
|
|
786
899
|
const value = newRowData ? newRowData[column.id] : '';
|
|
787
|
-
|
|
900
|
+
|
|
788
901
|
// Special handling for colours column regardless of type
|
|
789
902
|
if (column.id === 'colours') {
|
|
790
903
|
return (
|
|
@@ -800,7 +913,7 @@ const GenericEditableTable = ({
|
|
|
800
913
|
/>
|
|
801
914
|
);
|
|
802
915
|
}
|
|
803
|
-
|
|
916
|
+
|
|
804
917
|
switch (column.type) {
|
|
805
918
|
case 'colour':
|
|
806
919
|
// For other colour columns, picker is rendered in the action column
|
|
@@ -921,6 +1034,7 @@ const GenericEditableTable = ({
|
|
|
921
1034
|
const newRowData = hasCategory ? newEntries[groupId] || {} : newEntry;
|
|
922
1035
|
return (
|
|
923
1036
|
<tr className={styles.newRow}>
|
|
1037
|
+
<td className={styles.checkboxColumn}></td>
|
|
924
1038
|
{columns.map((column) => (
|
|
925
1039
|
<td
|
|
926
1040
|
key={column.id}
|
|
@@ -946,6 +1060,51 @@ const GenericEditableTable = ({
|
|
|
946
1060
|
);
|
|
947
1061
|
};
|
|
948
1062
|
|
|
1063
|
+
// Checkbox column header
|
|
1064
|
+
const renderSelectAllCheckbox = (group = null) => (
|
|
1065
|
+
<th
|
|
1066
|
+
key="select-all"
|
|
1067
|
+
className={styles.checkboxColumn}
|
|
1068
|
+
onClick={() => {
|
|
1069
|
+
const currentlyAllSelected = isAllSelected(group?.entries);
|
|
1070
|
+
handleSelectAll(!currentlyAllSelected, group?.entries);
|
|
1071
|
+
}}
|
|
1072
|
+
style={{ cursor: 'pointer' }}
|
|
1073
|
+
title={
|
|
1074
|
+
group ? `Select all in ${group.category}` : 'Select all rows'
|
|
1075
|
+
}
|
|
1076
|
+
>
|
|
1077
|
+
<input
|
|
1078
|
+
type="checkbox"
|
|
1079
|
+
checked={isAllSelected(group?.entries)}
|
|
1080
|
+
onChange={() => {}} // Empty handler since we handle click on the cell
|
|
1081
|
+
style={{ cursor: 'pointer', pointerEvents: 'none' }}
|
|
1082
|
+
tabIndex={-1}
|
|
1083
|
+
/>
|
|
1084
|
+
</th>
|
|
1085
|
+
);
|
|
1086
|
+
|
|
1087
|
+
// Row checkbox cell
|
|
1088
|
+
const renderRowCheckbox = (entry) => (
|
|
1089
|
+
<td
|
|
1090
|
+
key={`checkbox-${entry.id}`}
|
|
1091
|
+
className={styles.checkboxColumn}
|
|
1092
|
+
onClick={() => {
|
|
1093
|
+
const isCurrentlySelected = selectedRows.has(entry.id);
|
|
1094
|
+
handleRowSelection(entry.id, !isCurrentlySelected);
|
|
1095
|
+
}}
|
|
1096
|
+
style={{ cursor: 'pointer' }}
|
|
1097
|
+
>
|
|
1098
|
+
<input
|
|
1099
|
+
type="checkbox"
|
|
1100
|
+
checked={selectedRows.has(entry.id)}
|
|
1101
|
+
onChange={() => {}} // Empty handler since we handle click on the cell
|
|
1102
|
+
style={{ cursor: 'pointer', pointerEvents: 'none' }}
|
|
1103
|
+
tabIndex={-1}
|
|
1104
|
+
/>
|
|
1105
|
+
</td>
|
|
1106
|
+
);
|
|
1107
|
+
|
|
949
1108
|
// Header cell with optional copy icon
|
|
950
1109
|
const renderHeaderCell = (column, group = null) => (
|
|
951
1110
|
<th
|
|
@@ -968,7 +1127,7 @@ const GenericEditableTable = ({
|
|
|
968
1127
|
}}
|
|
969
1128
|
style={{ cursor: 'pointer' }}
|
|
970
1129
|
>
|
|
971
|
-
<Copy size={
|
|
1130
|
+
<Copy size={20} />
|
|
972
1131
|
</span>
|
|
973
1132
|
)}
|
|
974
1133
|
</div>
|
|
@@ -1027,11 +1186,12 @@ const GenericEditableTable = ({
|
|
|
1027
1186
|
{groupedCategories.map((group) => (
|
|
1028
1187
|
<React.Fragment key={group.id}>
|
|
1029
1188
|
<tr className={styles.categoryRow}>
|
|
1030
|
-
<td colSpan={columns.length +
|
|
1189
|
+
<td colSpan={columns.length + 2}>
|
|
1031
1190
|
{group.category}
|
|
1032
1191
|
</td>
|
|
1033
1192
|
</tr>
|
|
1034
1193
|
<tr>
|
|
1194
|
+
{renderSelectAllCheckbox(group)}
|
|
1035
1195
|
{columns.map((column) =>
|
|
1036
1196
|
renderHeaderCell(column, group)
|
|
1037
1197
|
)}
|
|
@@ -1046,6 +1206,7 @@ const GenericEditableTable = ({
|
|
|
1046
1206
|
getRowBackground(entry),
|
|
1047
1207
|
}}
|
|
1048
1208
|
>
|
|
1209
|
+
{renderRowCheckbox(entry)}
|
|
1049
1210
|
{columns.map((column) => (
|
|
1050
1211
|
<td
|
|
1051
1212
|
key={column.id}
|
|
@@ -1070,55 +1231,70 @@ const GenericEditableTable = ({
|
|
|
1070
1231
|
>
|
|
1071
1232
|
{!hasColourColumn && (
|
|
1072
1233
|
<ColourPicker
|
|
1073
|
-
value={
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1234
|
+
value={
|
|
1235
|
+
entry.row_colour ||
|
|
1236
|
+
''
|
|
1237
|
+
}
|
|
1238
|
+
columnId={
|
|
1239
|
+
'row_colour'
|
|
1240
|
+
}
|
|
1241
|
+
keyCounter={
|
|
1242
|
+
entry.keyCounter
|
|
1243
|
+
}
|
|
1244
|
+
onChange={
|
|
1245
|
+
handleFieldChange
|
|
1246
|
+
}
|
|
1077
1247
|
/>
|
|
1078
1248
|
)}
|
|
1079
1249
|
{idx > 0 && (
|
|
1080
|
-
<
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1250
|
+
<Tooltip text="Move up">
|
|
1251
|
+
<ArrowUp
|
|
1252
|
+
size={16}
|
|
1253
|
+
onClick={() =>
|
|
1254
|
+
handleSortChangeGrouped(
|
|
1255
|
+
group.id,
|
|
1256
|
+
entry.id,
|
|
1257
|
+
'up'
|
|
1258
|
+
)
|
|
1259
|
+
}
|
|
1260
|
+
style={{
|
|
1261
|
+
cursor: 'pointer',
|
|
1262
|
+
}}
|
|
1263
|
+
/>
|
|
1264
|
+
</Tooltip>
|
|
1093
1265
|
)}
|
|
1094
1266
|
{idx <
|
|
1095
1267
|
group.entries.length -
|
|
1096
1268
|
1 && (
|
|
1097
|
-
<
|
|
1269
|
+
<Tooltip text="Move down">
|
|
1270
|
+
<ArrowDown
|
|
1271
|
+
size={16}
|
|
1272
|
+
onClick={() =>
|
|
1273
|
+
handleSortChangeGrouped(
|
|
1274
|
+
group.id,
|
|
1275
|
+
entry.id,
|
|
1276
|
+
'down'
|
|
1277
|
+
)
|
|
1278
|
+
}
|
|
1279
|
+
style={{
|
|
1280
|
+
cursor: 'pointer',
|
|
1281
|
+
}}
|
|
1282
|
+
/>
|
|
1283
|
+
</Tooltip>
|
|
1284
|
+
)}
|
|
1285
|
+
<Tooltip text="Delete row">
|
|
1286
|
+
<Trash2
|
|
1098
1287
|
size={16}
|
|
1099
1288
|
onClick={() =>
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
entry.id,
|
|
1103
|
-
'down'
|
|
1289
|
+
handleDeleteRow(
|
|
1290
|
+
entry
|
|
1104
1291
|
)
|
|
1105
1292
|
}
|
|
1106
1293
|
style={{
|
|
1107
1294
|
cursor: 'pointer',
|
|
1108
1295
|
}}
|
|
1109
1296
|
/>
|
|
1110
|
-
|
|
1111
|
-
<Trash2
|
|
1112
|
-
size={16}
|
|
1113
|
-
onClick={() =>
|
|
1114
|
-
handleDeleteRow(
|
|
1115
|
-
entry
|
|
1116
|
-
)
|
|
1117
|
-
}
|
|
1118
|
-
style={{
|
|
1119
|
-
cursor: 'pointer',
|
|
1120
|
-
}}
|
|
1121
|
-
/>
|
|
1297
|
+
</Tooltip>
|
|
1122
1298
|
</div>
|
|
1123
1299
|
</td>
|
|
1124
1300
|
</tr>
|
|
@@ -1130,6 +1306,7 @@ const GenericEditableTable = ({
|
|
|
1130
1306
|
(col) => col.type === 'total'
|
|
1131
1307
|
) !== -1 && (
|
|
1132
1308
|
<tr className={styles.subtotalRow}>
|
|
1309
|
+
<td></td>
|
|
1133
1310
|
{columns.map((col, index) => {
|
|
1134
1311
|
const totalColIndex =
|
|
1135
1312
|
columns.findIndex(
|
|
@@ -1192,126 +1369,153 @@ const GenericEditableTable = ({
|
|
|
1192
1369
|
<table className={styles.schedulingTable}>
|
|
1193
1370
|
<thead>
|
|
1194
1371
|
<tr>
|
|
1372
|
+
{renderSelectAllCheckbox()}
|
|
1195
1373
|
{columns.map((column) => renderHeaderCell(column))}
|
|
1196
1374
|
<th style={{ width: '5%' }}></th>
|
|
1197
1375
|
</tr>
|
|
1198
1376
|
</thead>
|
|
1199
1377
|
<tbody>
|
|
1200
|
-
{localData.length > 0 &&
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1378
|
+
{localData.length > 0 &&
|
|
1379
|
+
sortBySortOrder(localData).map((entry, idx) => (
|
|
1380
|
+
<tr
|
|
1381
|
+
key={entry.id}
|
|
1382
|
+
style={{
|
|
1383
|
+
background: getRowBackground(entry),
|
|
1384
|
+
}}
|
|
1385
|
+
>
|
|
1386
|
+
{renderRowCheckbox(entry)}
|
|
1387
|
+
{columns.map((column) => (
|
|
1388
|
+
<td
|
|
1389
|
+
key={column.id}
|
|
1390
|
+
style={{
|
|
1391
|
+
width: column.width || 'auto',
|
|
1392
|
+
textAlign:
|
|
1393
|
+
column.type === 'currency'
|
|
1394
|
+
? 'right'
|
|
1395
|
+
: 'left',
|
|
1396
|
+
}}
|
|
1397
|
+
>
|
|
1398
|
+
{renderScheduledTableField(
|
|
1399
|
+
entry,
|
|
1400
|
+
column,
|
|
1401
|
+
idx
|
|
1402
|
+
)}
|
|
1403
|
+
</td>
|
|
1404
|
+
))}
|
|
1405
|
+
<td>
|
|
1406
|
+
<div className={styles.tdactions}>
|
|
1407
|
+
{!hasColourColumn && (
|
|
1408
|
+
<ColourPicker
|
|
1409
|
+
value={
|
|
1410
|
+
entry.row_colour || ''
|
|
1411
|
+
}
|
|
1412
|
+
columnId={'row_colour'}
|
|
1413
|
+
keyCounter={idx}
|
|
1414
|
+
onChange={handleFieldChange}
|
|
1415
|
+
/>
|
|
1416
|
+
)}
|
|
1417
|
+
{idx > 0 && (
|
|
1418
|
+
<Tooltip text="Move up">
|
|
1419
|
+
<ArrowUp
|
|
1420
|
+
size={16}
|
|
1421
|
+
onClick={() =>
|
|
1422
|
+
handleSortChangeUngrouped(
|
|
1423
|
+
entry.id,
|
|
1424
|
+
'up'
|
|
1425
|
+
)
|
|
1426
|
+
}
|
|
1427
|
+
style={{
|
|
1428
|
+
cursor: 'pointer',
|
|
1429
|
+
}}
|
|
1430
|
+
/>
|
|
1431
|
+
</Tooltip>
|
|
1432
|
+
)}
|
|
1433
|
+
{idx <
|
|
1434
|
+
sortBySortOrder(localData)
|
|
1435
|
+
.length -
|
|
1436
|
+
1 && (
|
|
1437
|
+
<Tooltip text="Move down">
|
|
1438
|
+
<ArrowDown
|
|
1439
|
+
size={16}
|
|
1440
|
+
onClick={() =>
|
|
1441
|
+
handleSortChangeUngrouped(
|
|
1442
|
+
entry.id,
|
|
1443
|
+
'down'
|
|
1444
|
+
)
|
|
1445
|
+
}
|
|
1446
|
+
style={{
|
|
1447
|
+
cursor: 'pointer',
|
|
1448
|
+
}}
|
|
1449
|
+
/>
|
|
1450
|
+
</Tooltip>
|
|
1451
|
+
)}
|
|
1452
|
+
<Tooltip text="Delete row">
|
|
1453
|
+
<Trash2
|
|
1454
|
+
size={16}
|
|
1455
|
+
onClick={() =>
|
|
1456
|
+
handleDeleteRow(entry)
|
|
1457
|
+
}
|
|
1458
|
+
style={{
|
|
1459
|
+
cursor: 'pointer',
|
|
1460
|
+
}}
|
|
1461
|
+
/>
|
|
1462
|
+
</Tooltip>
|
|
1463
|
+
</div>
|
|
1221
1464
|
</td>
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
<div className={styles.tdactions}>
|
|
1225
|
-
{!hasColourColumn && (
|
|
1226
|
-
<ColourPicker
|
|
1227
|
-
value={entry.row_colour || ''}
|
|
1228
|
-
columnId={'row_colour'}
|
|
1229
|
-
keyCounter={idx}
|
|
1230
|
-
onChange={handleFieldChange}
|
|
1231
|
-
/>
|
|
1232
|
-
)}
|
|
1233
|
-
{idx > 0 && (
|
|
1234
|
-
<ArrowUp
|
|
1235
|
-
size={16}
|
|
1236
|
-
onClick={() =>
|
|
1237
|
-
handleSortChangeUngrouped(
|
|
1238
|
-
entry.id,
|
|
1239
|
-
'up'
|
|
1240
|
-
)
|
|
1241
|
-
}
|
|
1242
|
-
style={{ cursor: 'pointer' }}
|
|
1243
|
-
/>
|
|
1244
|
-
)}
|
|
1245
|
-
{idx <
|
|
1246
|
-
sortBySortOrder(localData).length -
|
|
1247
|
-
1 && (
|
|
1248
|
-
<ArrowDown
|
|
1249
|
-
size={16}
|
|
1250
|
-
onClick={() =>
|
|
1251
|
-
handleSortChangeUngrouped(
|
|
1252
|
-
entry.id,
|
|
1253
|
-
'down'
|
|
1254
|
-
)
|
|
1255
|
-
}
|
|
1256
|
-
style={{ cursor: 'pointer' }}
|
|
1257
|
-
/>
|
|
1258
|
-
)}
|
|
1259
|
-
<Trash2
|
|
1260
|
-
size={16}
|
|
1261
|
-
onClick={() =>
|
|
1262
|
-
handleDeleteRow(entry)
|
|
1263
|
-
}
|
|
1264
|
-
style={{ cursor: 'pointer' }}
|
|
1265
|
-
/>
|
|
1266
|
-
</div>
|
|
1267
|
-
</td>
|
|
1268
|
-
</tr>
|
|
1269
|
-
))}
|
|
1465
|
+
</tr>
|
|
1466
|
+
))}
|
|
1270
1467
|
|
|
1271
1468
|
{renderNewRowForm()}
|
|
1272
1469
|
|
|
1273
|
-
{localData.length > 0 &&
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
{
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
index === totalColIndex - 1 &&
|
|
1282
|
-
index > 0
|
|
1283
|
-
) {
|
|
1284
|
-
return <td key={col.id}>Subtotal</td>;
|
|
1285
|
-
}
|
|
1286
|
-
if (index === totalColIndex) {
|
|
1287
|
-
const overallTotal = sortBySortOrder(
|
|
1288
|
-
localData
|
|
1289
|
-
).reduce(
|
|
1290
|
-
(sum, entry) =>
|
|
1291
|
-
sum +
|
|
1292
|
-
calculateTotal(
|
|
1293
|
-
entry,
|
|
1294
|
-
columns[totalColIndex].keys
|
|
1295
|
-
),
|
|
1296
|
-
0
|
|
1297
|
-
);
|
|
1298
|
-
return (
|
|
1299
|
-
<td key={col.id}>
|
|
1300
|
-
{overallTotal.toLocaleString(
|
|
1301
|
-
'en-AU',
|
|
1302
|
-
{
|
|
1303
|
-
style: 'currency',
|
|
1304
|
-
currency: 'AUD',
|
|
1305
|
-
}
|
|
1306
|
-
)}
|
|
1307
|
-
</td>
|
|
1470
|
+
{localData.length > 0 &&
|
|
1471
|
+
columns.findIndex((col) => col.type === 'total') !==
|
|
1472
|
+
-1 && (
|
|
1473
|
+
<tr className={styles.subtotalRow}>
|
|
1474
|
+
<td></td>
|
|
1475
|
+
{columns.map((col, index) => {
|
|
1476
|
+
const totalColIndex = columns.findIndex(
|
|
1477
|
+
(c) => c.type === 'total'
|
|
1308
1478
|
);
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1479
|
+
if (
|
|
1480
|
+
index === totalColIndex - 1 &&
|
|
1481
|
+
index > 0
|
|
1482
|
+
) {
|
|
1483
|
+
return (
|
|
1484
|
+
<td key={col.id}>Subtotal</td>
|
|
1485
|
+
);
|
|
1486
|
+
}
|
|
1487
|
+
if (index === totalColIndex) {
|
|
1488
|
+
const overallTotal =
|
|
1489
|
+
sortBySortOrder(
|
|
1490
|
+
localData
|
|
1491
|
+
).reduce(
|
|
1492
|
+
(sum, entry) =>
|
|
1493
|
+
sum +
|
|
1494
|
+
calculateTotal(
|
|
1495
|
+
entry,
|
|
1496
|
+
columns[
|
|
1497
|
+
totalColIndex
|
|
1498
|
+
].keys
|
|
1499
|
+
),
|
|
1500
|
+
0
|
|
1501
|
+
);
|
|
1502
|
+
return (
|
|
1503
|
+
<td key={col.id}>
|
|
1504
|
+
{overallTotal.toLocaleString(
|
|
1505
|
+
'en-AU',
|
|
1506
|
+
{
|
|
1507
|
+
style: 'currency',
|
|
1508
|
+
currency: 'AUD',
|
|
1509
|
+
}
|
|
1510
|
+
)}
|
|
1511
|
+
</td>
|
|
1512
|
+
);
|
|
1513
|
+
}
|
|
1514
|
+
return <td key={col.id} />;
|
|
1515
|
+
})}
|
|
1516
|
+
<td></td>
|
|
1517
|
+
</tr>
|
|
1518
|
+
)}
|
|
1315
1519
|
</tbody>
|
|
1316
1520
|
</table>
|
|
1317
1521
|
)}
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
|
|
6
6
|
th,
|
|
7
7
|
td {
|
|
8
|
-
padding: 0.
|
|
8
|
+
padding: 0.4rem 0.5rem; // Increased padding for better readability
|
|
9
9
|
text-align: left;
|
|
10
10
|
border: 1px solid rgba(var(--primary-rgb), 0.1);
|
|
11
|
-
line-height: 1; //
|
|
11
|
+
line-height: 1.3; // Increased line height for better readability
|
|
12
12
|
vertical-align: middle; // Ensure vertical alignment
|
|
13
|
-
height:
|
|
13
|
+
height: 40px; // Increased row height
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
// Additional high-specificity selectors to override any global styles
|
|
@@ -18,14 +18,14 @@
|
|
|
18
18
|
td select,
|
|
19
19
|
th input,
|
|
20
20
|
th select {
|
|
21
|
-
padding: 0.
|
|
21
|
+
padding: 0.3rem 0.5rem !important;
|
|
22
22
|
margin: 0 !important;
|
|
23
|
-
font-size: 0.
|
|
24
|
-
height:
|
|
25
|
-
line-height: 1 !important;
|
|
23
|
+
font-size: 0.9rem !important;
|
|
24
|
+
height: 32px !important;
|
|
25
|
+
line-height: 1.2 !important;
|
|
26
26
|
border: 1px solid rgba(var(--primary-rgb), 0.1) !important;
|
|
27
27
|
box-sizing: border-box !important;
|
|
28
|
-
border-radius:
|
|
28
|
+
border-radius: 4px !important;
|
|
29
29
|
width: 100% !important;
|
|
30
30
|
appearance: none !important;
|
|
31
31
|
background: white !important;
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
th select {
|
|
36
36
|
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><path d="M6 9L1 4h10z" fill="%23666"/></svg>') !important;
|
|
37
37
|
background-repeat: no-repeat !important;
|
|
38
|
-
background-position: right 0.
|
|
39
|
-
background-size:
|
|
40
|
-
padding: 0.
|
|
38
|
+
background-position: right 0.5rem center !important;
|
|
39
|
+
background-size: 10px !important;
|
|
40
|
+
padding: 0.3rem 1.5rem 0.3rem 0.5rem !important;
|
|
41
41
|
cursor: pointer !important;
|
|
42
42
|
|
|
43
43
|
&::-ms-expand {
|
|
@@ -46,13 +46,13 @@
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
th {
|
|
49
|
-
padding: 0.
|
|
50
|
-
font-size:
|
|
49
|
+
padding: 0.5rem 0.5rem; // Increased header padding
|
|
50
|
+
font-size: 1rem; // Larger font size for headers
|
|
51
51
|
font-weight: bold;
|
|
52
52
|
background-color: var(--primary-color);
|
|
53
53
|
color: white;
|
|
54
54
|
text-align: center;
|
|
55
|
-
height:
|
|
55
|
+
height: 45px; // Increased header height
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
td {
|
|
@@ -64,17 +64,17 @@
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
/*
|
|
67
|
+
/* Updated styling for native input and select elements */
|
|
68
68
|
input,
|
|
69
69
|
select {
|
|
70
|
-
padding: 0.
|
|
70
|
+
padding: 0.3rem 0.5rem !important; // Increased padding for better usability
|
|
71
71
|
margin: 0 !important;
|
|
72
|
-
font-size: 0.
|
|
73
|
-
height:
|
|
74
|
-
line-height: 1 !important;
|
|
72
|
+
font-size: 0.9rem !important; // Larger font size for readability
|
|
73
|
+
height: 32px !important; // Increased height
|
|
74
|
+
line-height: 1.2 !important;
|
|
75
75
|
border: 1px solid rgba(var(--primary-rgb), 0.1) !important;
|
|
76
76
|
box-sizing: border-box !important;
|
|
77
|
-
border-radius:
|
|
77
|
+
border-radius: 4px !important; // Larger border radius
|
|
78
78
|
width: 100% !important;
|
|
79
79
|
appearance: none !important; // Remove default dropdown arrow for consistency
|
|
80
80
|
background: white !important;
|
|
@@ -84,9 +84,9 @@
|
|
|
84
84
|
&:not([type]) {
|
|
85
85
|
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><path d="M6 9L1 4h10z" fill="%23666"/></svg>') !important;
|
|
86
86
|
background-repeat: no-repeat !important;
|
|
87
|
-
background-position: right 0.
|
|
88
|
-
background-size:
|
|
89
|
-
padding-right:
|
|
87
|
+
background-position: right 0.5rem center !important;
|
|
88
|
+
background-size: 10px !important;
|
|
89
|
+
padding-right: 1.5rem !important;
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
|
|
@@ -96,9 +96,9 @@
|
|
|
96
96
|
background: white !important;
|
|
97
97
|
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><path d="M6 9L1 4h10z" fill="%23666"/></svg>') !important;
|
|
98
98
|
background-repeat: no-repeat !important;
|
|
99
|
-
background-position: right 0.
|
|
100
|
-
background-size:
|
|
101
|
-
padding: 0.
|
|
99
|
+
background-position: right 0.5rem center !important;
|
|
100
|
+
background-size: 10px !important;
|
|
101
|
+
padding: 0.3rem 1.5rem 0.3rem 0.5rem !important; // Increased padding values
|
|
102
102
|
cursor: pointer !important;
|
|
103
103
|
|
|
104
104
|
// Remove default arrow on different browsers
|
|
@@ -233,19 +233,19 @@
|
|
|
233
233
|
width: max-content;
|
|
234
234
|
display: inline-block;
|
|
235
235
|
position: relative;
|
|
236
|
-
padding: 0.
|
|
236
|
+
padding: 0.4rem 0.8rem; /* Increased padding */
|
|
237
237
|
cursor: pointer;
|
|
238
|
-
font-size: 0.
|
|
238
|
+
font-size: 0.9rem; /* Larger font size */
|
|
239
239
|
color: var(--tertiary-color);
|
|
240
240
|
text-decoration: none;
|
|
241
241
|
overflow: hidden;
|
|
242
242
|
background: var(--primary-color);
|
|
243
243
|
border: 1px solid rgba(var(--primary-color--rgb), 1.1);
|
|
244
|
-
border-radius:
|
|
244
|
+
border-radius: 4px; /* Larger border radius */
|
|
245
245
|
outline: none;
|
|
246
246
|
transition: all 0.2s cubic-bezier(0.85, 0, 0.15, 1) 0s;
|
|
247
|
-
height:
|
|
248
|
-
line-height: 1;
|
|
247
|
+
height: 34px; /* Match input height */
|
|
248
|
+
line-height: 1.2;
|
|
249
249
|
display: flex;
|
|
250
250
|
align-items: center;
|
|
251
251
|
justify-content: center;
|
|
@@ -263,19 +263,19 @@
|
|
|
263
263
|
flex-wrap: nowrap;
|
|
264
264
|
justify-content: flex-start;
|
|
265
265
|
align-items: center;
|
|
266
|
-
gap: 0.
|
|
266
|
+
gap: 0.3rem; // Increased gap
|
|
267
267
|
background: transparent !important; /* Ensure no background color interference */
|
|
268
268
|
|
|
269
269
|
span {
|
|
270
270
|
display: flex;
|
|
271
271
|
align-items: center;
|
|
272
272
|
position: relative;
|
|
273
|
-
width:
|
|
274
|
-
height:
|
|
273
|
+
width: 16px; // Smaller icons for sort and trash
|
|
274
|
+
height: 16px;
|
|
275
275
|
|
|
276
276
|
svg {
|
|
277
|
-
width:
|
|
278
|
-
height:
|
|
277
|
+
width: 16px;
|
|
278
|
+
height: 16px;
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
281
|
}
|
|
@@ -293,8 +293,8 @@
|
|
|
293
293
|
margin: 0;
|
|
294
294
|
outline: none;
|
|
295
295
|
transition: all 0.2s ease;
|
|
296
|
-
width:
|
|
297
|
-
height:
|
|
296
|
+
width: 24px; // Larger color picker button
|
|
297
|
+
height: 24px;
|
|
298
298
|
|
|
299
299
|
&:hover {
|
|
300
300
|
opacity: 0.8;
|
|
@@ -302,8 +302,8 @@
|
|
|
302
302
|
}
|
|
303
303
|
|
|
304
304
|
svg {
|
|
305
|
-
width:
|
|
306
|
-
height:
|
|
305
|
+
width: 18px; // Larger icon
|
|
306
|
+
height: 18px;
|
|
307
307
|
}
|
|
308
308
|
}
|
|
309
309
|
}
|
|
@@ -665,19 +665,19 @@
|
|
|
665
665
|
border-top: 1px dashed rgba(var(--primary-rgb), 0.3);
|
|
666
666
|
border-bottom: 1px dashed rgba(var(--primary-rgb), 0.3);
|
|
667
667
|
|
|
668
|
-
/*
|
|
668
|
+
/* Updated styling for new row inputs and selects */
|
|
669
669
|
input,
|
|
670
670
|
select {
|
|
671
|
-
height:
|
|
672
|
-
padding: 0.
|
|
673
|
-
font-size: 0.
|
|
671
|
+
height: 32px !important; // Increased height
|
|
672
|
+
padding: 0.3rem 0.5rem !important; // Increased padding
|
|
673
|
+
font-size: 0.9rem !important;
|
|
674
674
|
appearance: none !important;
|
|
675
675
|
background: white !important;
|
|
676
676
|
margin: 0 !important;
|
|
677
|
-
line-height: 1 !important;
|
|
677
|
+
line-height: 1.2 !important;
|
|
678
678
|
border: 1px solid rgba(var(--primary-rgb), 0.1) !important;
|
|
679
679
|
box-sizing: border-box !important;
|
|
680
|
-
border-radius:
|
|
680
|
+
border-radius: 4px !important;
|
|
681
681
|
width: 100% !important;
|
|
682
682
|
|
|
683
683
|
// Ensure selects have dropdown arrow
|
|
@@ -685,9 +685,9 @@
|
|
|
685
685
|
&:not([type]) {
|
|
686
686
|
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><path d="M6 9L1 4h10z" fill="%23666"/></svg>') !important;
|
|
687
687
|
background-repeat: no-repeat !important;
|
|
688
|
-
background-position: right 0.
|
|
689
|
-
background-size:
|
|
690
|
-
padding-right:
|
|
688
|
+
background-position: right 0.5rem center !important;
|
|
689
|
+
background-size: 10px !important;
|
|
690
|
+
padding-right: 1.5rem !important;
|
|
691
691
|
}
|
|
692
692
|
}
|
|
693
693
|
|
|
@@ -696,9 +696,9 @@
|
|
|
696
696
|
background: white !important;
|
|
697
697
|
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><path d="M6 9L1 4h10z" fill="%23666"/></svg>') !important;
|
|
698
698
|
background-repeat: no-repeat !important;
|
|
699
|
-
background-position: right 0.
|
|
700
|
-
background-size:
|
|
701
|
-
padding: 0.
|
|
699
|
+
background-position: right 0.5rem center !important;
|
|
700
|
+
background-size: 10px !important;
|
|
701
|
+
padding: 0.3rem 1.5rem 0.3rem 0.5rem !important; // Updated padding
|
|
702
702
|
cursor: pointer !important;
|
|
703
703
|
|
|
704
704
|
&::-ms-expand {
|
|
@@ -707,6 +707,108 @@
|
|
|
707
707
|
}
|
|
708
708
|
}
|
|
709
709
|
|
|
710
|
+
/* Tooltip styles */
|
|
711
|
+
.tooltipContainer {
|
|
712
|
+
position: relative;
|
|
713
|
+
display: inline-flex;
|
|
714
|
+
align-items: center;
|
|
715
|
+
justify-content: center;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
.tooltip {
|
|
719
|
+
position: absolute;
|
|
720
|
+
background: rgba(0, 0, 0, 0.9);
|
|
721
|
+
color: white;
|
|
722
|
+
padding: 6px 10px;
|
|
723
|
+
border-radius: 4px;
|
|
724
|
+
font-size: 0.75rem;
|
|
725
|
+
font-weight: 500;
|
|
726
|
+
white-space: nowrap;
|
|
727
|
+
z-index: 10000;
|
|
728
|
+
pointer-events: none;
|
|
729
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
|
730
|
+
transform: translateX(-50%);
|
|
731
|
+
|
|
732
|
+
&::before {
|
|
733
|
+
content: '';
|
|
734
|
+
position: absolute;
|
|
735
|
+
left: 50%;
|
|
736
|
+
border: 5px solid transparent;
|
|
737
|
+
transform: translateX(-50%);
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
&.tooltip-top {
|
|
741
|
+
transform: translateX(-50%) translateY(-100%);
|
|
742
|
+
margin-top: -5px;
|
|
743
|
+
|
|
744
|
+
&::before {
|
|
745
|
+
top: 100%;
|
|
746
|
+
border-top-color: rgba(0, 0, 0, 0.9);
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
&.tooltip-bottom {
|
|
751
|
+
transform: translateX(-50%) translateY(0%);
|
|
752
|
+
margin-top: 5px;
|
|
753
|
+
|
|
754
|
+
&::before {
|
|
755
|
+
bottom: 100%;
|
|
756
|
+
border-bottom-color: rgba(0, 0, 0, 0.9);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
/* Checkbox styling */
|
|
762
|
+
.schedulingTable input[type="checkbox"] {
|
|
763
|
+
cursor: pointer;
|
|
764
|
+
width: 14px !important;
|
|
765
|
+
height: 14px !important;
|
|
766
|
+
min-width: 14px !important;
|
|
767
|
+
min-height: 14px !important;
|
|
768
|
+
max-width: 14px !important;
|
|
769
|
+
max-height: 14px !important;
|
|
770
|
+
margin: 0 !important;
|
|
771
|
+
padding: 0 !important;
|
|
772
|
+
accent-color: var(--primary-color);
|
|
773
|
+
vertical-align: middle;
|
|
774
|
+
flex-shrink: 0;
|
|
775
|
+
display: inline-block;
|
|
776
|
+
|
|
777
|
+
&:hover {
|
|
778
|
+
transform: scale(1.05);
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
/* Checkbox column specific styling */
|
|
783
|
+
.checkboxColumn {
|
|
784
|
+
width: 30px !important;
|
|
785
|
+
max-width: 30px !important;
|
|
786
|
+
min-width: 30px !important;
|
|
787
|
+
padding: 0.2rem !important;
|
|
788
|
+
text-align: center !important;
|
|
789
|
+
vertical-align: middle !important;
|
|
790
|
+
cursor: pointer !important;
|
|
791
|
+
user-select: none !important;
|
|
792
|
+
transition: background-color 0.2s ease !important;
|
|
793
|
+
|
|
794
|
+
/* Ensure checkbox container doesn't stretch */
|
|
795
|
+
display: table-cell !important;
|
|
796
|
+
|
|
797
|
+
&:hover {
|
|
798
|
+
background-color: rgba(var(--primary-rgb), 0.08) !important;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
&:active {
|
|
802
|
+
background-color: rgba(var(--primary-rgb), 0.12) !important;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
input[type="checkbox"] {
|
|
806
|
+
display: inline-block !important;
|
|
807
|
+
vertical-align: middle !important;
|
|
808
|
+
pointer-events: none !important; /* Prevent direct checkbox interaction */
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
|
|
710
812
|
.datasetSelector {
|
|
711
813
|
display: flex;
|
|
712
814
|
align-items: center;
|