playbook_ui 14.19.0.pre.alpha.PLAY1973formpillinternalsizing7728 → 14.19.0.pre.alpha.PLAY2033atactionbarrails7730
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.html.erb +19 -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 +56 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/index.js +336 -55
- 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_form_pill/_form_pill.scss +12 -19
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +4 -1
@@ -9,19 +9,131 @@ 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.style.overflow = "hidden";
|
99
|
+
|
100
|
+
// Complete animation after delay
|
101
|
+
window.setTimeout(() => {
|
102
|
+
if (actionBar.classList.contains("is-visible")) {
|
103
|
+
actionBar.style.height = "";
|
104
|
+
actionBar.style.overflow = "visible";
|
105
|
+
}
|
106
|
+
}, 300);
|
107
|
+
}
|
108
|
+
|
109
|
+
// Hide action bar with animation
|
110
|
+
hideActionBar(actionBar) {
|
111
|
+
if (!actionBar) return;
|
112
|
+
|
113
|
+
// Set exact height before animation
|
114
|
+
actionBar.style.height = actionBar.scrollHeight + "px";
|
115
|
+
actionBar.offsetHeight; // Trigger reflow
|
116
|
+
|
117
|
+
// Animate to height 0
|
118
|
+
window.setTimeout(() => {
|
119
|
+
actionBar.style.height = "0";
|
120
|
+
actionBar.style.overflow = "hidden";
|
121
|
+
}, 10);
|
122
|
+
|
123
|
+
// Remove visibility classes after animation
|
124
|
+
window.setTimeout(() => {
|
125
|
+
actionBar.classList.remove("is-visible");
|
126
|
+
actionBar.classList.remove("show-action-card");
|
127
|
+
}, 300);
|
15
128
|
}
|
16
129
|
|
17
|
-
// Check if
|
18
|
-
// This is used to determine the background color of the row
|
19
|
-
// when the checkbox is checked or unchecked
|
130
|
+
// Check if row is expanded
|
20
131
|
isRowExpanded(rowEl) {
|
21
132
|
const closeIcon = rowEl.querySelector(UP_ARROW_SELECTOR);
|
22
133
|
return closeIcon?.style.display === "none" || !closeIcon;
|
23
134
|
}
|
24
135
|
|
136
|
+
// Update parent checkboxes based on child selections
|
25
137
|
updateParentCheckboxes(checkbox) {
|
26
138
|
const rowEl = checkbox.closest("tr");
|
27
139
|
if (!rowEl) return;
|
@@ -29,6 +141,11 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
29
141
|
const table = rowEl.closest("table");
|
30
142
|
if (!table) return;
|
31
143
|
|
144
|
+
const tableId = this.getTableId();
|
145
|
+
if (!tableId) return;
|
146
|
+
|
147
|
+
const tableData = PbAdvancedTable.getTableData(tableId);
|
148
|
+
|
32
149
|
const contentTrail = rowEl.dataset.advancedTableContent;
|
33
150
|
if (!contentTrail) return;
|
34
151
|
|
@@ -71,15 +188,15 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
71
188
|
|
72
189
|
const parentCheckboxId = parentCheckbox.id;
|
73
190
|
if (allChildrenChecked) {
|
74
|
-
|
191
|
+
tableData.selectedRows.add(parentCheckboxId);
|
75
192
|
parentRow.classList.add("bg-row-selection");
|
76
193
|
parentRow.classList.remove("bg-white", "bg-silver");
|
77
194
|
} else {
|
78
|
-
|
195
|
+
tableData.selectedRows.delete(parentCheckboxId);
|
79
196
|
}
|
80
197
|
if (!allChildrenChecked) {
|
81
198
|
parentRow.classList.remove("bg-row-selection");
|
82
|
-
|
199
|
+
|
83
200
|
if (this.isRowExpanded(parentRow)) {
|
84
201
|
parentRow.classList.remove("bg-silver");
|
85
202
|
parentRow.classList.add("bg-white");
|
@@ -91,18 +208,24 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
91
208
|
});
|
92
209
|
}
|
93
210
|
|
211
|
+
// Handle row checkbox click
|
94
212
|
handleCheckboxClick(event) {
|
95
213
|
const checkbox = event.currentTarget;
|
96
214
|
const rowId = checkbox.id;
|
97
215
|
const isChecked = checkbox.checked;
|
98
216
|
const rowEl = checkbox.closest("tr");
|
99
217
|
|
218
|
+
const tableId = this.getTableId();
|
219
|
+
if (!tableId) return;
|
220
|
+
|
221
|
+
const tableData = PbAdvancedTable.getTableData(tableId);
|
222
|
+
|
100
223
|
if (isChecked) {
|
101
|
-
|
224
|
+
tableData.selectedRows.add(rowId);
|
102
225
|
rowEl.classList.add("bg-row-selection");
|
103
226
|
rowEl.classList.remove("bg-white", "bg-silver");
|
104
227
|
} else {
|
105
|
-
|
228
|
+
tableData.selectedRows.delete(rowId);
|
106
229
|
}
|
107
230
|
// Update background color on row
|
108
231
|
if (!isChecked) {
|
@@ -116,6 +239,7 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
116
239
|
rowEl.classList.add("bg-silver");
|
117
240
|
}
|
118
241
|
}
|
242
|
+
|
119
243
|
if (rowEl) {
|
120
244
|
const table = rowEl.closest("table");
|
121
245
|
const rowContent = rowEl.dataset.advancedTableContent;
|
@@ -137,11 +261,11 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
137
261
|
const childRowId = childCheckbox.id;
|
138
262
|
const childRowEl = childCheckbox.closest("tr");
|
139
263
|
if (isChecked) {
|
140
|
-
|
264
|
+
tableData.selectedRows.add(childRowId);
|
141
265
|
childRowEl?.classList.add("bg-row-selection");
|
142
266
|
childRowEl?.classList.remove("bg-white", "bg-silver");
|
143
267
|
} else {
|
144
|
-
|
268
|
+
tableData.selectedRows.delete(childRowId);
|
145
269
|
}
|
146
270
|
if (!isChecked) {
|
147
271
|
childRowEl?.classList.remove("bg-row-selection");
|
@@ -183,43 +307,121 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
183
307
|
return table.querySelectorAll(`[data-row-parent="${this.element.id}"]`);
|
184
308
|
}
|
185
309
|
|
186
|
-
static expandedRows = new Set();
|
187
|
-
static selectedRows = new Set();
|
188
310
|
static isCollapsing = false;
|
189
311
|
|
190
312
|
connect() {
|
313
|
+
// Get table container and generate ID if needed
|
314
|
+
const tableContainer = this.getTableContainer();
|
315
|
+
if (!tableContainer) return;
|
316
|
+
|
317
|
+
const tableId = this.getTableId();
|
318
|
+
if (!tableId) return;
|
319
|
+
|
320
|
+
// Get or initialize table data
|
321
|
+
const tableData = PbAdvancedTable.getTableData(tableId);
|
322
|
+
|
323
|
+
// Handle toggle click
|
191
324
|
this.element.addEventListener("click", () => {
|
192
325
|
if (!PbAdvancedTable.isCollapsing) {
|
193
326
|
const isExpanded =
|
194
327
|
this.element.querySelector(UP_ARROW_SELECTOR).style.display ===
|
195
328
|
"inline-block";
|
196
329
|
if (!isExpanded) {
|
197
|
-
|
330
|
+
tableData.expandedRows.add(this.element.id);
|
198
331
|
} else {
|
199
|
-
|
332
|
+
tableData.expandedRows.delete(this.element.id);
|
200
333
|
}
|
201
|
-
this.toggleElement(this.target);
|
334
|
+
this.toggleElement(this.target, tableData.expandedRows);
|
202
335
|
}
|
203
336
|
});
|
204
|
-
|
337
|
+
|
205
338
|
this.hideCloseIcon();
|
206
|
-
|
339
|
+
|
207
340
|
const table = this.element.closest("table");
|
208
|
-
|
209
|
-
|
210
|
-
if
|
211
|
-
|
212
|
-
|
213
|
-
//
|
341
|
+
if (!table) return;
|
342
|
+
|
343
|
+
// Skip if this table is already initialized
|
344
|
+
if (tableData.initialized) return;
|
345
|
+
|
346
|
+
// Initialize the action bar
|
347
|
+
const actionBar = tableContainer.querySelector(".row-selection-actions-card");
|
348
|
+
if (actionBar) {
|
349
|
+
// Direct style application
|
350
|
+
Object.assign(actionBar.style, {
|
351
|
+
height: '0px',
|
352
|
+
overflow: 'hidden',
|
353
|
+
display: 'block',
|
354
|
+
opacity: '0'
|
355
|
+
});
|
356
|
+
|
357
|
+
// Remove visibility classes
|
358
|
+
actionBar.classList.remove("is-visible", "show-action-card");
|
359
|
+
|
360
|
+
// Add CSS rules
|
361
|
+
const styleId = `action-bar-styles-${tableId}`;
|
362
|
+
let styleTag = document.getElementById(styleId);
|
363
|
+
if (!styleTag) {
|
364
|
+
styleTag = document.createElement('style');
|
365
|
+
styleTag.id = styleId;
|
366
|
+
document.head.appendChild(styleTag);
|
367
|
+
}
|
368
|
+
|
369
|
+
styleTag.textContent = `
|
370
|
+
#${tableId} .row-selection-actions-card.is-visible.show-action-card {
|
371
|
+
height: auto !important;
|
372
|
+
overflow: visible !important;
|
373
|
+
display: block !important;
|
374
|
+
opacity: 1 !important;
|
375
|
+
transition: height 0.3s ease, opacity 0.3s ease !important;
|
376
|
+
}
|
377
|
+
`;
|
378
|
+
|
379
|
+
// Direct DOM event listeners for checkboxes
|
380
|
+
const checkboxes = table.querySelectorAll('input[type="checkbox"]');
|
381
|
+
checkboxes.forEach(checkbox => {
|
382
|
+
checkbox.addEventListener('change', function() {
|
383
|
+
// Count selected checkboxes
|
384
|
+
const selectedCount = Array.from(checkboxes).filter(cb => cb.checked).length;
|
385
|
+
|
386
|
+
if (selectedCount > 0) {
|
387
|
+
// Show action bar directly
|
388
|
+
actionBar.style.height = 'auto';
|
389
|
+
actionBar.style.overflow = 'visible';
|
390
|
+
actionBar.style.opacity = '1';
|
391
|
+
actionBar.classList.add("is-visible", "show-action-card");
|
392
|
+
|
393
|
+
// Update the count
|
394
|
+
const countElement = actionBar.querySelector(".selected-count");
|
395
|
+
if (countElement) {
|
396
|
+
countElement.textContent = `${selectedCount} Selected`;
|
397
|
+
}
|
398
|
+
} else {
|
399
|
+
// Hide action bar directly
|
400
|
+
actionBar.style.height = '0px';
|
401
|
+
actionBar.style.overflow = 'hidden';
|
402
|
+
actionBar.style.opacity = '0';
|
403
|
+
actionBar.classList.remove("is-visible", "show-action-card");
|
404
|
+
}
|
405
|
+
});
|
406
|
+
});
|
407
|
+
}
|
408
|
+
|
409
|
+
// Bind checkbox change handlers
|
214
410
|
const checkboxLabels = table.querySelectorAll("label[data-row-id]");
|
215
411
|
checkboxLabels.forEach((label) => {
|
216
412
|
const checkbox = label.querySelector("input[type='checkbox']");
|
217
413
|
if (!checkbox) return;
|
218
|
-
|
414
|
+
|
415
|
+
// Remove any existing event listeners
|
416
|
+
const newCheckbox = checkbox.cloneNode(true);
|
417
|
+
checkbox.parentNode.replaceChild(newCheckbox, checkbox);
|
418
|
+
|
419
|
+
// Add our event listener
|
420
|
+
newCheckbox.addEventListener("change", (event) => {
|
219
421
|
this.handleCheckboxClick(event);
|
220
422
|
});
|
221
423
|
});
|
222
|
-
|
424
|
+
|
223
425
|
// Bind nested row expansion logic
|
224
426
|
const nestedButtons = table.querySelectorAll("[data-advanced-table]");
|
225
427
|
nestedButtons.forEach((button) => {
|
@@ -227,54 +429,61 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
227
429
|
const isExpanded =
|
228
430
|
button.querySelector(UP_ARROW_SELECTOR).style.display === "inline-block";
|
229
431
|
if (isExpanded) {
|
230
|
-
|
432
|
+
tableData.expandedRows.add(button.id);
|
231
433
|
} else {
|
232
|
-
|
434
|
+
tableData.expandedRows.delete(button.id);
|
233
435
|
}
|
234
436
|
});
|
235
437
|
});
|
236
|
-
|
237
|
-
// Bind select-all logic
|
438
|
+
|
439
|
+
// Bind select-all logic
|
238
440
|
const selectAllCheckbox = table.querySelector("#select-all-rows");
|
239
441
|
if (selectAllCheckbox) {
|
240
|
-
|
241
|
-
|
442
|
+
// Remove any existing event listeners
|
443
|
+
const newSelectAllCheckbox = selectAllCheckbox.cloneNode(true);
|
444
|
+
selectAllCheckbox.parentNode.replaceChild(newSelectAllCheckbox, selectAllCheckbox);
|
445
|
+
|
446
|
+
// Add our event listener
|
447
|
+
newSelectAllCheckbox.addEventListener("change", () => {
|
448
|
+
const checkboxInput = newSelectAllCheckbox.querySelector('input[type="checkbox"]');
|
242
449
|
const checkAll = checkboxInput.checked;
|
243
|
-
|
450
|
+
|
244
451
|
const checkboxes = Array.from(
|
245
452
|
table.querySelectorAll("label[data-row-id] input[type='checkbox']")
|
246
453
|
);
|
247
|
-
|
454
|
+
|
248
455
|
checkboxes.forEach((cb) => {
|
249
456
|
cb.checked = checkAll;
|
250
457
|
const rowId = cb.id;
|
251
458
|
const rowEl = cb.closest("tr");
|
252
459
|
|
253
460
|
if (checkAll) {
|
254
|
-
|
461
|
+
tableData.selectedRows.add(rowId);
|
255
462
|
rowEl?.classList.add("bg-row-selection");
|
256
463
|
rowEl?.classList.remove("bg-white", "bg-silver");
|
257
464
|
} else {
|
258
|
-
|
465
|
+
tableData.selectedRows.delete(rowId);
|
259
466
|
rowEl?.classList.remove("bg-row-selection");
|
260
467
|
rowEl?.classList.add("bg-white");
|
261
468
|
}
|
262
469
|
});
|
263
|
-
|
470
|
+
|
264
471
|
checkboxes.forEach((cb) => this.updateParentCheckboxes(cb));
|
265
|
-
|
472
|
+
|
266
473
|
this.updateTableSelectedRowsAttribute();
|
267
474
|
});
|
268
475
|
}
|
476
|
+
|
477
|
+
// Mark table as initialized
|
478
|
+
tableData.initialized = true;
|
269
479
|
}
|
270
|
-
|
271
480
|
|
272
481
|
hideCloseIcon() {
|
273
482
|
const closeIcon = this.element.querySelector(UP_ARROW_SELECTOR);
|
274
483
|
closeIcon.style.display = "none";
|
275
484
|
}
|
276
485
|
|
277
|
-
showElement(elements) {
|
486
|
+
showElement(elements, expandedRows) {
|
278
487
|
elements.forEach((elem) => {
|
279
488
|
elem.style.display = "table-row";
|
280
489
|
elem.classList.add("is-visible");
|
@@ -297,7 +506,7 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
297
506
|
(id) => `${childRow.id}_${id}`
|
298
507
|
);
|
299
508
|
const allAncestorsExpanded = prefixedAncestorIds.every((id) =>
|
300
|
-
|
509
|
+
expandedRows.has(id)
|
301
510
|
);
|
302
511
|
|
303
512
|
const checkIfParentIsExpanded = () => {
|
@@ -306,7 +515,7 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
306
515
|
const isParentVisible =
|
307
516
|
childRow.previousElementSibling.classList.contains("is-visible");
|
308
517
|
if (parentRowId) {
|
309
|
-
const isInSet =
|
518
|
+
const isInSet = expandedRows.has(parentRowId);
|
310
519
|
if (isInSet && isParentVisible) {
|
311
520
|
return true;
|
312
521
|
}
|
@@ -326,14 +535,14 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
326
535
|
});
|
327
536
|
}
|
328
537
|
|
329
|
-
hideElement(elements) {
|
538
|
+
hideElement(elements, expandedRows) {
|
330
539
|
elements.forEach((elem) => {
|
331
540
|
elem.style.display = "none";
|
332
541
|
elem.classList.remove("is-visible");
|
333
542
|
|
334
543
|
// Remove the row ID from expandedRows when this row is hidden
|
335
|
-
if (
|
336
|
-
|
544
|
+
if (expandedRows.has(elem.id)) {
|
545
|
+
expandedRows.delete(elem.id);
|
337
546
|
}
|
338
547
|
|
339
548
|
const childrenArray = elem.dataset.advancedTableContent.split("-");
|
@@ -354,12 +563,12 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
354
563
|
});
|
355
564
|
}
|
356
565
|
|
357
|
-
toggleElement(elements) {
|
566
|
+
toggleElement(elements, expandedRows) {
|
358
567
|
if (!elements.length) return;
|
359
568
|
|
360
569
|
const isVisible = elements[0].classList.contains("is-visible");
|
361
570
|
|
362
|
-
isVisible ? this.hideElement(elements) : this.showElement(elements);
|
571
|
+
isVisible ? this.hideElement(elements, expandedRows) : this.showElement(elements, expandedRows);
|
363
572
|
isVisible ? this.displayDownArrow() : this.displayUpArrow();
|
364
573
|
|
365
574
|
const row = this.element.closest("tr");
|
@@ -382,6 +591,12 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
382
591
|
}
|
383
592
|
|
384
593
|
static handleToggleAllHeaders(element) {
|
594
|
+
// Get table ID
|
595
|
+
const tableContainer = element.closest(".pb_advanced_table");
|
596
|
+
if (!tableContainer || !tableContainer.id) return;
|
597
|
+
|
598
|
+
const tableData = PbAdvancedTable.getTableData(tableContainer.id);
|
599
|
+
|
385
600
|
const table = element.closest(".pb_table");
|
386
601
|
const firstLevelButtons = table.querySelectorAll(
|
387
602
|
".pb_advanced_table_body > .pb_table_tr[data-row-depth='0'] [data-advanced-table]"
|
@@ -395,17 +610,17 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
395
610
|
if (allExpanded) {
|
396
611
|
firstLevelButtons.forEach((button) => {
|
397
612
|
button.click();
|
398
|
-
|
613
|
+
tableData.expandedRows.delete(button.id);
|
399
614
|
});
|
400
615
|
} else {
|
401
616
|
firstLevelButtons.forEach((button) => {
|
402
|
-
if (!
|
617
|
+
if (!tableData.expandedRows.has(button.id)) {
|
403
618
|
button.click();
|
404
|
-
|
619
|
+
tableData.expandedRows.add(button.id);
|
405
620
|
}
|
406
621
|
});
|
407
622
|
|
408
|
-
|
623
|
+
tableData.expandedRows.forEach((rowId) => {
|
409
624
|
const nestedButton = table.querySelector(
|
410
625
|
`[data-advanced-table][id="${rowId}"]`
|
411
626
|
);
|
@@ -417,6 +632,12 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
417
632
|
}
|
418
633
|
|
419
634
|
static handleToggleAllSubRows(element, rowDepth) {
|
635
|
+
// Get table ID
|
636
|
+
const tableContainer = element.closest(".pb_advanced_table");
|
637
|
+
if (!tableContainer || !tableContainer.id) return;
|
638
|
+
|
639
|
+
const tableData = PbAdvancedTable.getTableData(tableContainer.id);
|
640
|
+
|
420
641
|
const table = element.closest(".pb_table");
|
421
642
|
const parentRow = element.closest("tr");
|
422
643
|
if (!parentRow) {
|
@@ -436,19 +657,79 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
436
657
|
if (allExpanded) {
|
437
658
|
subRowButtons.forEach((button) => {
|
438
659
|
button.click();
|
439
|
-
|
660
|
+
tableData.expandedRows.delete(button.id);
|
440
661
|
});
|
441
662
|
} else {
|
442
663
|
subRowButtons.forEach((button) => {
|
443
|
-
if (!
|
664
|
+
if (!tableData.expandedRows.has(button.id)) {
|
444
665
|
button.click();
|
445
|
-
|
666
|
+
tableData.expandedRows.add(button.id);
|
446
667
|
}
|
447
668
|
});
|
448
669
|
}
|
449
670
|
}
|
450
671
|
}
|
451
672
|
|
673
|
+
// Initialize on page load
|
674
|
+
document.addEventListener('DOMContentLoaded', () => {
|
675
|
+
const advancedTables = document.querySelectorAll('.pb_advanced_table');
|
676
|
+
|
677
|
+
// Initialize each table and its action bar
|
678
|
+
advancedTables.forEach(table => {
|
679
|
+
// Generate ID if needed
|
680
|
+
if (!table.id) {
|
681
|
+
table.id = `table-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
|
682
|
+
}
|
683
|
+
|
684
|
+
// Initialize table data
|
685
|
+
PbAdvancedTable.getTableData(table.id);
|
686
|
+
|
687
|
+
// Initialize action bar
|
688
|
+
const actionBar = table.querySelector('.row-selection-actions-card');
|
689
|
+
if (actionBar) {
|
690
|
+
// Direct styling override
|
691
|
+
Object.assign(actionBar.style, {
|
692
|
+
height: '0px',
|
693
|
+
overflow: 'hidden',
|
694
|
+
display: 'block',
|
695
|
+
opacity: '0'
|
696
|
+
});
|
697
|
+
|
698
|
+
// Remove any visibility classes
|
699
|
+
actionBar.classList.remove("is-visible", "show-action-card");
|
700
|
+
|
701
|
+
// Direct DOM manipulation for checkboxes
|
702
|
+
const checkboxes = table.querySelectorAll('input[type="checkbox"]');
|
703
|
+
checkboxes.forEach(checkbox => {
|
704
|
+
checkbox.addEventListener('change', function() {
|
705
|
+
// Count selected checkboxes
|
706
|
+
const selectedCount = Array.from(checkboxes).filter(cb => cb.checked).length;
|
707
|
+
|
708
|
+
if (selectedCount > 0) {
|
709
|
+
// Show action bar directly
|
710
|
+
actionBar.style.height = 'auto';
|
711
|
+
actionBar.style.overflow = 'visible';
|
712
|
+
actionBar.style.opacity = '1';
|
713
|
+
actionBar.classList.add("is-visible", "show-action-card");
|
714
|
+
|
715
|
+
// Update the count
|
716
|
+
const countElement = actionBar.querySelector(".selected-count");
|
717
|
+
if (countElement) {
|
718
|
+
countElement.textContent = `${selectedCount} Selected`;
|
719
|
+
}
|
720
|
+
} else {
|
721
|
+
// Hide action bar directly
|
722
|
+
actionBar.style.height = '0px';
|
723
|
+
actionBar.style.overflow = 'hidden';
|
724
|
+
actionBar.style.opacity = '0';
|
725
|
+
actionBar.classList.remove("is-visible", "show-action-card");
|
726
|
+
}
|
727
|
+
});
|
728
|
+
});
|
729
|
+
}
|
730
|
+
});
|
731
|
+
});
|
732
|
+
|
452
733
|
window.expandAllRows = (element) => {
|
453
734
|
PbAdvancedTable.handleToggleAllHeaders(element);
|
454
735
|
};
|
@@ -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
|