playbook_ui 14.19.0.pre.alpha.PLAY21377811 → 14.19.0.pre.alpha.borderfixadvancedtable7815
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.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +4 -3
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.html.erb +16 -8
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +9 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_actions_rails.html.erb +137 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_actions_rails.md +3 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_header_rails.html.erb +40 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_header_rails.md +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_advanced_table/index.js +355 -52
- data/app/pb_kits/playbook/pb_advanced_table/table_action_bar.html.erb +23 -0
- data/app/pb_kits/playbook/pb_advanced_table/table_action_bar.rb +19 -0
- data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +4 -0
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +1 -1
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +19 -77
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default.html.erb +10 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +1 -11
- data/app/pb_kits/playbook/pb_dropdown/docs/index.js +0 -5
- data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +2 -16
- data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.html.erb +13 -34
- data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.rb +1 -3
- data/app/pb_kits/playbook/pb_dropdown/hooks/useHandleOnKeydown.tsx +6 -0
- data/app/pb_kits/playbook/pb_dropdown/index.js +41 -334
- data/app/pb_kits/playbook/pb_dropdown/keyboard_accessibility.js +12 -39
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownOption.tsx +12 -16
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +12 -78
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with.html.erb +0 -1
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +0 -1
- data/dist/chunks/_typeahead-B9-s4j4U.js +22 -0
- data/dist/chunks/_weekday_stacked-CvzpmXD5.js +45 -0
- data/dist/chunks/{lib-BB_ZEriO.js → lib-B20MXZcW.js} +2 -2
- data/dist/chunks/{pb_form_validation-C0la9CZR.js → pb_form_validation-WWvUXPKD.js} +1 -1
- data/dist/chunks/vendor.js +1 -1
- data/dist/playbook-doc.js +1 -1
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +12 -23
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default_rails.html.erb +0 -31
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default_rails.md +0 -5
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select.jsx +0 -56
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select.md +0 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display.jsx +0 -58
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display.md +0 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display_rails.html.erb +0 -20
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display_rails.md +0 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_rails.html.erb +0 -19
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_rails.md +0 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_autocomplete.html.erb +0 -20
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_autocomplete.jsx +0 -57
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_autocomplete.md +0 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_custom_options.html.erb +0 -50
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_custom_options.jsx +0 -105
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_default.html.erb +0 -22
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_default.jsx +0 -67
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/MultiSelectTriggerDisplay.tsx +0 -58
- data/dist/chunks/_typeahead-CLGxsWj4.js +0 -22
- data/dist/chunks/_weekday_stacked-BrJMDrKs.js +0 -45
@@ -9,9 +9,128 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
9
9
|
return ADVANCED_TABLE_SELECTOR;
|
10
10
|
}
|
11
11
|
|
12
|
+
// Track selections per table
|
13
|
+
static tableData = new Map();
|
14
|
+
|
15
|
+
// Get or initialize data for a specific table
|
16
|
+
static getTableData(tableId) {
|
17
|
+
if (!PbAdvancedTable.tableData.has(tableId)) {
|
18
|
+
PbAdvancedTable.tableData.set(tableId, {
|
19
|
+
selectedRows: new Set(),
|
20
|
+
expandedRows: new Set(),
|
21
|
+
initialized: false
|
22
|
+
});
|
23
|
+
}
|
24
|
+
return PbAdvancedTable.tableData.get(tableId);
|
25
|
+
}
|
26
|
+
|
27
|
+
// Get the table container from any element within the table
|
28
|
+
getTableContainer() {
|
29
|
+
return this.element.closest(".pb_advanced_table");
|
30
|
+
}
|
31
|
+
|
32
|
+
// Get table ID, create one if needed
|
33
|
+
getTableId() {
|
34
|
+
const tableContainer = this.getTableContainer();
|
35
|
+
if (!tableContainer) return null;
|
36
|
+
|
37
|
+
// Generate ID if none exists
|
38
|
+
if (!tableContainer.id) {
|
39
|
+
tableContainer.id = `table-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
|
40
|
+
}
|
41
|
+
|
42
|
+
return tableContainer.id;
|
43
|
+
}
|
44
|
+
|
45
|
+
// Update the data attribute with selected rows
|
12
46
|
updateTableSelectedRowsAttribute() {
|
13
|
-
const
|
14
|
-
|
47
|
+
const tableContainer = this.getTableContainer();
|
48
|
+
const tableId = this.getTableId();
|
49
|
+
if (!tableId) return;
|
50
|
+
|
51
|
+
const tableData = PbAdvancedTable.getTableData(tableId);
|
52
|
+
const selectedRowsArray = Array.from(tableData.selectedRows);
|
53
|
+
|
54
|
+
// Update data attribute
|
55
|
+
tableContainer.dataset.selectedRows = JSON.stringify(selectedRowsArray);
|
56
|
+
|
57
|
+
// Update action bar visibility
|
58
|
+
this.updateActionBarVisibility(tableContainer, tableData.selectedRows);
|
59
|
+
}
|
60
|
+
|
61
|
+
// Update action bar visibility based on selection state
|
62
|
+
updateActionBarVisibility(tableContainer, selectedRows) {
|
63
|
+
if (!tableContainer) return;
|
64
|
+
|
65
|
+
const actionBar = tableContainer.querySelector(".row-selection-actions-card");
|
66
|
+
if (!actionBar) return;
|
67
|
+
|
68
|
+
const selectedCount = selectedRows.size;
|
69
|
+
|
70
|
+
// Update count display
|
71
|
+
const countElement = actionBar.querySelector(".selected-count");
|
72
|
+
if (countElement) {
|
73
|
+
countElement.textContent = `${selectedCount} Selected`;
|
74
|
+
}
|
75
|
+
|
76
|
+
// Show/hide based on selection
|
77
|
+
if (selectedCount > 0) {
|
78
|
+
this.showActionBar(actionBar);
|
79
|
+
} else {
|
80
|
+
this.hideActionBar(actionBar);
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
// Show action bar with animation
|
85
|
+
showActionBar(actionBar) {
|
86
|
+
if (!actionBar) return;
|
87
|
+
|
88
|
+
// Force display block
|
89
|
+
actionBar.style.display = "block";
|
90
|
+
|
91
|
+
// Get the height before animation
|
92
|
+
const height = actionBar.scrollHeight + "px";
|
93
|
+
|
94
|
+
// Force all style changes directly
|
95
|
+
actionBar.style.height = height;
|
96
|
+
actionBar.classList.add("is-visible");
|
97
|
+
actionBar.classList.add("show-action-card");
|
98
|
+
actionBar.classList.replace("p_none", "p_xs");
|
99
|
+
// This is for keeping the border around the card when showing the action bar
|
100
|
+
actionBar.classList.replace("pb_card_kit_deselected_border_none", "pb_card_kit_deselected");
|
101
|
+
actionBar.style.overflow = "hidden";
|
102
|
+
|
103
|
+
// Complete animation after delay
|
104
|
+
window.setTimeout(() => {
|
105
|
+
if (actionBar.classList.contains("is-visible")) {
|
106
|
+
actionBar.style.height = "";
|
107
|
+
actionBar.style.overflow = "visible";
|
108
|
+
}
|
109
|
+
}, 300);
|
110
|
+
}
|
111
|
+
|
112
|
+
// Hide action bar with animation
|
113
|
+
hideActionBar(actionBar) {
|
114
|
+
if (!actionBar) return;
|
115
|
+
|
116
|
+
// Set exact height before animation
|
117
|
+
actionBar.style.height = actionBar.scrollHeight + "px";
|
118
|
+
actionBar.offsetHeight; // Trigger reflow
|
119
|
+
|
120
|
+
// Animate to height 0
|
121
|
+
window.setTimeout(() => {
|
122
|
+
actionBar.style.height = "0";
|
123
|
+
actionBar.style.overflow = "hidden";
|
124
|
+
}, 10);
|
125
|
+
|
126
|
+
// Remove visibility classes after animation
|
127
|
+
window.setTimeout(() => {
|
128
|
+
actionBar.classList.remove("is-visible");
|
129
|
+
actionBar.classList.remove("show-action-card");
|
130
|
+
actionBar.classList.replace("p_xs", "p_none");
|
131
|
+
// This is for removing the border when hiding the action bar
|
132
|
+
actionBar.classList.replace( "pb_card_kit_deselected", "pb_card_kit_deselected_border_none");
|
133
|
+
}, 300);
|
15
134
|
}
|
16
135
|
|
17
136
|
// Check if the row is expanded or collapsed
|
@@ -22,6 +141,7 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
22
141
|
return closeIcon?.style.display === "none" || !closeIcon;
|
23
142
|
}
|
24
143
|
|
144
|
+
// Update parent checkboxes based on child selections
|
25
145
|
updateParentCheckboxes(checkbox) {
|
26
146
|
const rowEl = checkbox.closest("tr");
|
27
147
|
if (!rowEl) return;
|
@@ -29,6 +149,11 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
29
149
|
const table = rowEl.closest("table");
|
30
150
|
if (!table) return;
|
31
151
|
|
152
|
+
const tableId = this.getTableId();
|
153
|
+
if (!tableId) return;
|
154
|
+
|
155
|
+
const tableData = PbAdvancedTable.getTableData(tableId);
|
156
|
+
|
32
157
|
const contentTrail = rowEl.dataset.advancedTableContent;
|
33
158
|
if (!contentTrail) return;
|
34
159
|
|
@@ -71,15 +196,15 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
71
196
|
|
72
197
|
const parentCheckboxId = parentCheckbox.id;
|
73
198
|
if (allChildrenChecked) {
|
74
|
-
|
199
|
+
tableData.selectedRows.add(parentCheckboxId);
|
75
200
|
parentRow.classList.add("bg-row-selection");
|
76
201
|
parentRow.classList.remove("bg-white", "bg-silver");
|
77
202
|
} else {
|
78
|
-
|
203
|
+
tableData.selectedRows.delete(parentCheckboxId);
|
79
204
|
}
|
80
205
|
if (!allChildrenChecked) {
|
81
206
|
parentRow.classList.remove("bg-row-selection");
|
82
|
-
|
207
|
+
|
83
208
|
if (this.isRowExpanded(parentRow)) {
|
84
209
|
parentRow.classList.remove("bg-silver");
|
85
210
|
parentRow.classList.add("bg-white");
|
@@ -91,18 +216,24 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
91
216
|
});
|
92
217
|
}
|
93
218
|
|
219
|
+
// Handle row checkbox click
|
94
220
|
handleCheckboxClick(event) {
|
95
221
|
const checkbox = event.currentTarget;
|
96
222
|
const rowId = checkbox.id;
|
97
223
|
const isChecked = checkbox.checked;
|
98
224
|
const rowEl = checkbox.closest("tr");
|
99
225
|
|
226
|
+
const tableId = this.getTableId();
|
227
|
+
if (!tableId) return;
|
228
|
+
|
229
|
+
const tableData = PbAdvancedTable.getTableData(tableId);
|
230
|
+
|
100
231
|
if (isChecked) {
|
101
|
-
|
232
|
+
tableData.selectedRows.add(rowId);
|
102
233
|
rowEl.classList.add("bg-row-selection");
|
103
234
|
rowEl.classList.remove("bg-white", "bg-silver");
|
104
235
|
} else {
|
105
|
-
|
236
|
+
tableData.selectedRows.delete(rowId);
|
106
237
|
}
|
107
238
|
// Update background color on row
|
108
239
|
if (!isChecked) {
|
@@ -116,6 +247,7 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
116
247
|
rowEl.classList.add("bg-silver");
|
117
248
|
}
|
118
249
|
}
|
250
|
+
|
119
251
|
if (rowEl) {
|
120
252
|
const table = rowEl.closest("table");
|
121
253
|
const rowContent = rowEl.dataset.advancedTableContent;
|
@@ -137,11 +269,11 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
137
269
|
const childRowId = childCheckbox.id;
|
138
270
|
const childRowEl = childCheckbox.closest("tr");
|
139
271
|
if (isChecked) {
|
140
|
-
|
272
|
+
tableData.selectedRows.add(childRowId);
|
141
273
|
childRowEl?.classList.add("bg-row-selection");
|
142
274
|
childRowEl?.classList.remove("bg-white", "bg-silver");
|
143
275
|
} else {
|
144
|
-
|
276
|
+
tableData.selectedRows.delete(childRowId);
|
145
277
|
}
|
146
278
|
if (!isChecked) {
|
147
279
|
childRowEl?.classList.remove("bg-row-selection");
|
@@ -183,43 +315,124 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
183
315
|
return table.querySelectorAll(`[data-row-parent="${this.element.id}"]`);
|
184
316
|
}
|
185
317
|
|
186
|
-
static expandedRows = new Set();
|
187
|
-
static selectedRows = new Set();
|
188
318
|
static isCollapsing = false;
|
189
319
|
|
190
320
|
connect() {
|
321
|
+
// Get table container and generate ID if needed
|
322
|
+
const tableContainer = this.getTableContainer();
|
323
|
+
if (!tableContainer) return;
|
324
|
+
|
325
|
+
const tableId = this.getTableId();
|
326
|
+
if (!tableId) return;
|
327
|
+
|
328
|
+
// Get or initialize table data
|
329
|
+
const tableData = PbAdvancedTable.getTableData(tableId);
|
330
|
+
|
331
|
+
// Handle toggle click
|
191
332
|
this.element.addEventListener("click", () => {
|
192
333
|
if (!PbAdvancedTable.isCollapsing) {
|
193
334
|
const isExpanded =
|
194
335
|
this.element.querySelector(UP_ARROW_SELECTOR).style.display ===
|
195
336
|
"inline-block";
|
196
337
|
if (!isExpanded) {
|
197
|
-
|
338
|
+
tableData.expandedRows.add(this.element.id);
|
198
339
|
} else {
|
199
|
-
|
340
|
+
tableData.expandedRows.delete(this.element.id);
|
200
341
|
}
|
201
|
-
this.toggleElement(this.target);
|
342
|
+
this.toggleElement(this.target, tableData.expandedRows);
|
202
343
|
}
|
203
344
|
});
|
204
|
-
|
345
|
+
|
205
346
|
this.hideCloseIcon();
|
206
|
-
|
347
|
+
|
207
348
|
const table = this.element.closest("table");
|
208
|
-
|
209
|
-
|
210
|
-
if
|
211
|
-
|
212
|
-
|
213
|
-
//
|
349
|
+
if (!table) return;
|
350
|
+
|
351
|
+
// Skip if this table is already initialized
|
352
|
+
if (tableData.initialized) return;
|
353
|
+
|
354
|
+
// Initialize the action bar
|
355
|
+
const actionBar = tableContainer.querySelector(".row-selection-actions-card");
|
356
|
+
if (actionBar) {
|
357
|
+
// Direct style application
|
358
|
+
Object.assign(actionBar.style, {
|
359
|
+
height: '0px',
|
360
|
+
overflow: 'hidden',
|
361
|
+
display: 'block',
|
362
|
+
opacity: '0'
|
363
|
+
});
|
364
|
+
|
365
|
+
// Remove visibility classes
|
366
|
+
actionBar.classList.remove("p_xs", "is-visible", "show-action-card");
|
367
|
+
actionBar.classList.add("p_none");
|
368
|
+
|
369
|
+
// Add CSS rules
|
370
|
+
const styleId = `action-bar-styles-${tableId}`;
|
371
|
+
let styleTag = document.getElementById(styleId);
|
372
|
+
if (!styleTag) {
|
373
|
+
styleTag = document.createElement('style');
|
374
|
+
styleTag.id = styleId;
|
375
|
+
document.head.appendChild(styleTag);
|
376
|
+
}
|
377
|
+
|
378
|
+
styleTag.textContent = `
|
379
|
+
#${tableId} .row-selection-actions-card.is-visible.show-action-card {
|
380
|
+
height: auto !important;
|
381
|
+
overflow: visible !important;
|
382
|
+
display: block !important;
|
383
|
+
opacity: 1 !important;
|
384
|
+
transition: height 0.3s ease, opacity 0.3s ease !important;
|
385
|
+
}
|
386
|
+
`;
|
387
|
+
|
388
|
+
// Direct DOM event listeners for checkboxes
|
389
|
+
const checkboxes = table.querySelectorAll('input[type="checkbox"]');
|
390
|
+
checkboxes.forEach(checkbox => {
|
391
|
+
checkbox.addEventListener('change', function() {
|
392
|
+
// Count selected checkboxes
|
393
|
+
const selectedCount = Array.from(checkboxes).filter(cb => cb.checked).length;
|
394
|
+
|
395
|
+
if (selectedCount > 0) {
|
396
|
+
// Show action bar directly
|
397
|
+
actionBar.style.height = 'auto';
|
398
|
+
actionBar.style.overflow = 'visible';
|
399
|
+
actionBar.style.opacity = '1';
|
400
|
+
actionBar.classList.remove("p_none");
|
401
|
+
actionBar.classList.add("p_xs", "is-visible", "show-action-card");
|
402
|
+
|
403
|
+
// Update the count
|
404
|
+
const countElement = actionBar.querySelector(".selected-count");
|
405
|
+
if (countElement) {
|
406
|
+
countElement.textContent = `${selectedCount} Selected`;
|
407
|
+
}
|
408
|
+
} else {
|
409
|
+
// Hide action bar directly
|
410
|
+
actionBar.style.height = '0px';
|
411
|
+
actionBar.style.overflow = 'hidden';
|
412
|
+
actionBar.style.opacity = '0';
|
413
|
+
actionBar.classList.remove("p_xs", "is-visible", "show-action-card");
|
414
|
+
actionBar.classList.add("p_none");
|
415
|
+
}
|
416
|
+
});
|
417
|
+
});
|
418
|
+
}
|
419
|
+
|
420
|
+
// Bind checkbox change handlers
|
214
421
|
const checkboxLabels = table.querySelectorAll("label[data-row-id]");
|
215
422
|
checkboxLabels.forEach((label) => {
|
216
423
|
const checkbox = label.querySelector("input[type='checkbox']");
|
217
424
|
if (!checkbox) return;
|
218
|
-
|
425
|
+
|
426
|
+
// Remove any existing event listeners
|
427
|
+
const newCheckbox = checkbox.cloneNode(true);
|
428
|
+
checkbox.parentNode.replaceChild(newCheckbox, checkbox);
|
429
|
+
|
430
|
+
// Add our event listener
|
431
|
+
newCheckbox.addEventListener("change", (event) => {
|
219
432
|
this.handleCheckboxClick(event);
|
220
433
|
});
|
221
434
|
});
|
222
|
-
|
435
|
+
|
223
436
|
// Bind nested row expansion logic
|
224
437
|
const nestedButtons = table.querySelectorAll("[data-advanced-table]");
|
225
438
|
nestedButtons.forEach((button) => {
|
@@ -227,54 +440,61 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
227
440
|
const isExpanded =
|
228
441
|
button.querySelector(UP_ARROW_SELECTOR).style.display === "inline-block";
|
229
442
|
if (isExpanded) {
|
230
|
-
|
443
|
+
tableData.expandedRows.add(button.id);
|
231
444
|
} else {
|
232
|
-
|
445
|
+
tableData.expandedRows.delete(button.id);
|
233
446
|
}
|
234
447
|
});
|
235
448
|
});
|
236
|
-
|
237
|
-
// Bind select-all logic
|
449
|
+
|
450
|
+
// Bind select-all logic
|
238
451
|
const selectAllCheckbox = table.querySelector("#select-all-rows");
|
239
452
|
if (selectAllCheckbox) {
|
240
|
-
|
241
|
-
|
453
|
+
// Remove any existing event listeners
|
454
|
+
const newSelectAllCheckbox = selectAllCheckbox.cloneNode(true);
|
455
|
+
selectAllCheckbox.parentNode.replaceChild(newSelectAllCheckbox, selectAllCheckbox);
|
456
|
+
|
457
|
+
// Add our event listener
|
458
|
+
newSelectAllCheckbox.addEventListener("change", () => {
|
459
|
+
const checkboxInput = newSelectAllCheckbox.querySelector('input[type="checkbox"]');
|
242
460
|
const checkAll = checkboxInput.checked;
|
243
|
-
|
461
|
+
|
244
462
|
const checkboxes = Array.from(
|
245
463
|
table.querySelectorAll("label[data-row-id] input[type='checkbox']")
|
246
464
|
);
|
247
|
-
|
465
|
+
|
248
466
|
checkboxes.forEach((cb) => {
|
249
467
|
cb.checked = checkAll;
|
250
468
|
const rowId = cb.id;
|
251
469
|
const rowEl = cb.closest("tr");
|
252
470
|
|
253
471
|
if (checkAll) {
|
254
|
-
|
472
|
+
tableData.selectedRows.add(rowId);
|
255
473
|
rowEl?.classList.add("bg-row-selection");
|
256
474
|
rowEl?.classList.remove("bg-white", "bg-silver");
|
257
475
|
} else {
|
258
|
-
|
476
|
+
tableData.selectedRows.delete(rowId);
|
259
477
|
rowEl?.classList.remove("bg-row-selection");
|
260
478
|
rowEl?.classList.add("bg-white");
|
261
479
|
}
|
262
480
|
});
|
263
|
-
|
481
|
+
|
264
482
|
checkboxes.forEach((cb) => this.updateParentCheckboxes(cb));
|
265
|
-
|
483
|
+
|
266
484
|
this.updateTableSelectedRowsAttribute();
|
267
485
|
});
|
268
486
|
}
|
487
|
+
|
488
|
+
// Mark table as initialized
|
489
|
+
tableData.initialized = true;
|
269
490
|
}
|
270
|
-
|
271
491
|
|
272
492
|
hideCloseIcon() {
|
273
493
|
const closeIcon = this.element.querySelector(UP_ARROW_SELECTOR);
|
274
494
|
closeIcon.style.display = "none";
|
275
495
|
}
|
276
496
|
|
277
|
-
showElement(elements) {
|
497
|
+
showElement(elements, expandedRows) {
|
278
498
|
elements.forEach((elem) => {
|
279
499
|
elem.style.display = "table-row";
|
280
500
|
elem.classList.add("is-visible");
|
@@ -297,7 +517,7 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
297
517
|
(id) => `${childRow.id}_${id}`
|
298
518
|
);
|
299
519
|
const allAncestorsExpanded = prefixedAncestorIds.every((id) =>
|
300
|
-
|
520
|
+
expandedRows.has(id)
|
301
521
|
);
|
302
522
|
|
303
523
|
const checkIfParentIsExpanded = () => {
|
@@ -306,7 +526,7 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
306
526
|
const isParentVisible =
|
307
527
|
childRow.previousElementSibling.classList.contains("is-visible");
|
308
528
|
if (parentRowId) {
|
309
|
-
const isInSet =
|
529
|
+
const isInSet = expandedRows.has(parentRowId);
|
310
530
|
if (isInSet && isParentVisible) {
|
311
531
|
return true;
|
312
532
|
}
|
@@ -326,14 +546,14 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
326
546
|
});
|
327
547
|
}
|
328
548
|
|
329
|
-
hideElement(elements) {
|
549
|
+
hideElement(elements, expandedRows) {
|
330
550
|
elements.forEach((elem) => {
|
331
551
|
elem.style.display = "none";
|
332
552
|
elem.classList.remove("is-visible");
|
333
553
|
|
334
554
|
// Remove the row ID from expandedRows when this row is hidden
|
335
|
-
if (
|
336
|
-
|
555
|
+
if (expandedRows.has(elem.id)) {
|
556
|
+
expandedRows.delete(elem.id);
|
337
557
|
}
|
338
558
|
|
339
559
|
const childrenArray = elem.dataset.advancedTableContent.split("-");
|
@@ -354,12 +574,12 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
354
574
|
});
|
355
575
|
}
|
356
576
|
|
357
|
-
toggleElement(elements) {
|
577
|
+
toggleElement(elements, expandedRows) {
|
358
578
|
if (!elements.length) return;
|
359
579
|
|
360
580
|
const isVisible = elements[0].classList.contains("is-visible");
|
361
581
|
|
362
|
-
isVisible ? this.hideElement(elements) : this.showElement(elements);
|
582
|
+
isVisible ? this.hideElement(elements, expandedRows) : this.showElement(elements, expandedRows);
|
363
583
|
isVisible ? this.displayDownArrow() : this.displayUpArrow();
|
364
584
|
|
365
585
|
const row = this.element.closest("tr");
|
@@ -382,6 +602,12 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
382
602
|
}
|
383
603
|
|
384
604
|
static handleToggleAllHeaders(element) {
|
605
|
+
// Get table ID
|
606
|
+
const tableContainer = element.closest(".pb_advanced_table");
|
607
|
+
if (!tableContainer || !tableContainer.id) return;
|
608
|
+
|
609
|
+
const tableData = PbAdvancedTable.getTableData(tableContainer.id);
|
610
|
+
|
385
611
|
const table = element.closest(".pb_table");
|
386
612
|
const firstLevelButtons = table.querySelectorAll(
|
387
613
|
".pb_advanced_table_body > .pb_table_tr[data-row-depth='0'] [data-advanced-table]"
|
@@ -395,17 +621,17 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
395
621
|
if (allExpanded) {
|
396
622
|
firstLevelButtons.forEach((button) => {
|
397
623
|
button.click();
|
398
|
-
|
624
|
+
tableData.expandedRows.delete(button.id);
|
399
625
|
});
|
400
626
|
} else {
|
401
627
|
firstLevelButtons.forEach((button) => {
|
402
|
-
if (!
|
628
|
+
if (!tableData.expandedRows.has(button.id)) {
|
403
629
|
button.click();
|
404
|
-
|
630
|
+
tableData.expandedRows.add(button.id);
|
405
631
|
}
|
406
632
|
});
|
407
633
|
|
408
|
-
|
634
|
+
tableData.expandedRows.forEach((rowId) => {
|
409
635
|
const nestedButton = table.querySelector(
|
410
636
|
`[data-advanced-table][id="${rowId}"]`
|
411
637
|
);
|
@@ -417,6 +643,12 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
417
643
|
}
|
418
644
|
|
419
645
|
static handleToggleAllSubRows(element, rowDepth) {
|
646
|
+
// Get table ID
|
647
|
+
const tableContainer = element.closest(".pb_advanced_table");
|
648
|
+
if (!tableContainer || !tableContainer.id) return;
|
649
|
+
|
650
|
+
const tableData = PbAdvancedTable.getTableData(tableContainer.id);
|
651
|
+
|
420
652
|
const table = element.closest(".pb_table");
|
421
653
|
const parentRow = element.closest("tr");
|
422
654
|
if (!parentRow) {
|
@@ -436,19 +668,90 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
436
668
|
if (allExpanded) {
|
437
669
|
subRowButtons.forEach((button) => {
|
438
670
|
button.click();
|
439
|
-
|
671
|
+
tableData.expandedRows.delete(button.id);
|
440
672
|
});
|
441
673
|
} else {
|
442
674
|
subRowButtons.forEach((button) => {
|
443
|
-
if (!
|
675
|
+
if (!tableData.expandedRows.has(button.id)) {
|
444
676
|
button.click();
|
445
|
-
|
677
|
+
tableData.expandedRows.add(button.id);
|
446
678
|
}
|
447
679
|
});
|
448
680
|
}
|
449
681
|
}
|
450
682
|
}
|
451
683
|
|
684
|
+
// Initialize on page load
|
685
|
+
document.addEventListener('DOMContentLoaded', () => {
|
686
|
+
const advancedTables = document.querySelectorAll('.pb_advanced_table');
|
687
|
+
|
688
|
+
// Initialize each table and its action bar
|
689
|
+
advancedTables.forEach(table => {
|
690
|
+
// Generate ID if needed
|
691
|
+
if (!table.id) {
|
692
|
+
table.id = `table-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
|
693
|
+
}
|
694
|
+
|
695
|
+
// Initialize table data
|
696
|
+
PbAdvancedTable.getTableData(table.id);
|
697
|
+
|
698
|
+
// Initialize action bar
|
699
|
+
const actionBar = table.querySelector('.row-selection-actions-card');
|
700
|
+
if (actionBar) {
|
701
|
+
// Direct styling override
|
702
|
+
Object.assign(actionBar.style, {
|
703
|
+
height: '0px',
|
704
|
+
overflow: 'hidden',
|
705
|
+
display: 'block',
|
706
|
+
opacity: '0'
|
707
|
+
});
|
708
|
+
|
709
|
+
// Remove any visibility classes
|
710
|
+
actionBar.classList.remove("p_xs", "is-visible", "show-action-card");
|
711
|
+
actionBar.classList.add("p_none");
|
712
|
+
|
713
|
+
// Direct DOM manipulation for checkboxes - exclude select-all checkbox
|
714
|
+
const checkboxes = table.querySelectorAll('input[type="checkbox"]');
|
715
|
+
checkboxes.forEach(checkbox => {
|
716
|
+
checkbox.addEventListener('change', function() {
|
717
|
+
// Get all checked checkboxes
|
718
|
+
const allCheckedCheckboxes = Array.from(checkboxes).filter(cb => cb.checked);
|
719
|
+
|
720
|
+
// Filter out the select-all checkbox
|
721
|
+
const selectedRowCheckboxes = allCheckedCheckboxes.filter(cb => {
|
722
|
+
return cb.id !== 'select-all-rows' && !cb.closest('#select-all-rows');
|
723
|
+
});
|
724
|
+
|
725
|
+
// Get the selected count (excluding select-all)
|
726
|
+
const selectedCount = selectedRowCheckboxes.length;
|
727
|
+
|
728
|
+
if (selectedCount > 0) {
|
729
|
+
// Show action bar directly
|
730
|
+
actionBar.style.height = 'auto';
|
731
|
+
actionBar.style.overflow = 'visible';
|
732
|
+
actionBar.style.opacity = '1';
|
733
|
+
actionBar.classList.remove("p_none");
|
734
|
+
actionBar.classList.add("p_xs", "is-visible", "show-action-card");
|
735
|
+
|
736
|
+
// Update the count
|
737
|
+
const countElement = actionBar.querySelector(".selected-count");
|
738
|
+
if (countElement) {
|
739
|
+
countElement.textContent = `${selectedCount} Selected`;
|
740
|
+
}
|
741
|
+
} else {
|
742
|
+
// Hide action bar directly
|
743
|
+
actionBar.style.height = '0px';
|
744
|
+
actionBar.style.overflow = 'hidden';
|
745
|
+
actionBar.style.opacity = '0';
|
746
|
+
actionBar.classList.add("p_none");
|
747
|
+
actionBar.classList.remove("p_xs", "is-visible", "show-action-card");
|
748
|
+
}
|
749
|
+
});
|
750
|
+
});
|
751
|
+
}
|
752
|
+
});
|
753
|
+
});
|
754
|
+
|
452
755
|
window.expandAllRows = (element) => {
|
453
756
|
PbAdvancedTable.handleToggleAllHeaders(element);
|
454
757
|
};
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<%= pb_rails("card", props: {
|
2
|
+
border_none: object.is_visible,
|
3
|
+
classname: object.classname,
|
4
|
+
padding: object.is_visible ? "xs" : "none",
|
5
|
+
data: {
|
6
|
+
action_bar: true
|
7
|
+
}
|
8
|
+
}) do %>
|
9
|
+
<%= pb_rails("flex", props: { align_items: "center", justify: "between" }) do %>
|
10
|
+
<%= pb_rails("caption", props: { color: "light", padding_left: "xs", size: "xs" }) do %>
|
11
|
+
<span class="selected-count"><%= object.selected_count %> Selected</span>
|
12
|
+
<% end %>
|
13
|
+
<%= pb_rails("flex/flex_item") do %>
|
14
|
+
<%= pb_rails("flex") do %>
|
15
|
+
<% if object.actions.present? %>
|
16
|
+
<% object.actions.each do |action| %>
|
17
|
+
<%= action %>
|
18
|
+
<% end %>
|
19
|
+
<% end %>
|
20
|
+
<% end %>
|
21
|
+
<% end %>
|
22
|
+
<% end %>
|
23
|
+
<% end %>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Playbook
|
4
|
+
module PbAdvancedTable
|
5
|
+
class TableActionBar < Playbook::KitBase
|
6
|
+
prop :actions, type: Playbook::Props::Array,
|
7
|
+
default: []
|
8
|
+
prop :is_visible, type: Playbook::Props::Boolean,
|
9
|
+
default: false
|
10
|
+
prop :selected_count, type: Playbook::Props::Number,
|
11
|
+
default: 0
|
12
|
+
|
13
|
+
def classname
|
14
|
+
# Just use row-selection-actions-card as the base class
|
15
|
+
generate_classname("row-selection-actions-card", separator: " ")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -15,6 +15,8 @@ module Playbook
|
|
15
15
|
default: "scroll"
|
16
16
|
prop :selectable_rows, type: Playbook::Props::Boolean,
|
17
17
|
default: false
|
18
|
+
prop :show_actions_bar, type: Playbook::Props::Boolean,
|
19
|
+
default: true
|
18
20
|
|
19
21
|
def classname
|
20
22
|
additional_classes = []
|
@@ -27,6 +29,7 @@ module Playbook
|
|
27
29
|
def th_classname(is_first_column: false)
|
28
30
|
additional_classes = []
|
29
31
|
additional_classes << "pinned-left" if is_first_column && responsive == "scroll" && !selectable_rows
|
32
|
+
additional_classes << "header-cells-with-actions" if selectable_rows && show_actions_bar
|
30
33
|
|
31
34
|
generate_classname("table-header-cells", *additional_classes, separator: " ")
|
32
35
|
end
|
@@ -46,6 +49,7 @@ module Playbook
|
|
46
49
|
if selectable_rows
|
47
50
|
additional_classes = []
|
48
51
|
additional_classes << "table-header-cells-custom"
|
52
|
+
additional_classes << "header-cells-with-actions" if show_actions_bar
|
49
53
|
additional_classes << "checkbox-cell-header"
|
50
54
|
additional_classes << "pinned-left" if responsive == "scroll"
|
51
55
|
pb_rails("table/table_header", props: {
|