@navette-js/tables 1.0.0-beta.3 → 1.0.0-beta.5
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/lib/index.d.ts +761 -85
- package/lib/index.js +1377 -236
- package/lib/query-builder.d.ts +92 -2
- package/lib/query-builder.js +164 -23
- package/package.json +6 -6
- package/views/filters.ejs +44 -0
- package/views/index.ejs +129 -106
package/views/index.ejs
CHANGED
|
@@ -15,23 +15,67 @@
|
|
|
15
15
|
|
|
16
16
|
return null
|
|
17
17
|
` %>
|
|
18
|
+
<% const rowActionsCell = (row) => { %>
|
|
19
|
+
<td class="fi-ta-cell">
|
|
20
|
+
<div class="<%- cls(['fi-ta-actions', actionsAlignment ? 'fi-align-' + actionsAlignment : '']) %>">
|
|
21
|
+
<%- row.actionsHtml ?? '' %>
|
|
22
|
+
<% for (const action of row.actions) { %>
|
|
23
|
+
<a href="<%= action.url %>" wire:navigate wire:key="<%= id %>.actions.<%= action.key %>" class="<%- cls(['fi-ac-link-action', 'fi-link', 'fi-size-sm', ...linkClasses]) %>">
|
|
24
|
+
<%- icon(action.icon, { size: 'sm' }) %>
|
|
25
|
+
<span class="fi-link-label">
|
|
26
|
+
<%= action.label %>
|
|
27
|
+
</span>
|
|
28
|
+
</a>
|
|
29
|
+
<% } %>
|
|
30
|
+
</div>
|
|
31
|
+
</td>
|
|
32
|
+
<% }; %>
|
|
33
|
+
<%
|
|
34
|
+
// Filters trigger button (funnel icon and active filter count) and filters panel, shared by every filters layout.
|
|
35
|
+
const filtersTriggerDefault = () => `<button title="${e(t('filament-tables::table.actions.filter.label'))}" aria-label="${e(t('filament-tables::table.actions.filter.label'))}" type="button" wire:loading.attr="aria-disabled" wire:loading.class="fi-disabled" class="fi-force-enabled fi-ac-icon-btn-action fi-icon-btn fi-size-md">${icon('m-funnel')}<div class="fi-icon-btn-badge-ctn"><span class="${cls([...badgeClasses, 'fi-badge', 'fi-size-xs'])}">${activeFiltersCount}</span></div></button>`;
|
|
36
|
+
const filtersTrigger = () => filterActions.trigger.customized
|
|
37
|
+
? filterActionHtml(filterActions.trigger, 'type="button" wire:loading.attr="aria-disabled" wire:loading.class="fi-disabled"', `<span class="${cls([...badgeClasses, 'fi-badge', 'fi-size-xs'])}">${activeFiltersCount}</span>`)
|
|
38
|
+
: filtersTriggerDefault();
|
|
39
|
+
const filterButton = (action, colorClasses, label, extra = '') => `<button type="button" wire:loading.attr="aria-disabled" wire:loading.class="fi-disabled" class="${cls(['fi-ac-btn-action', 'fi-btn', 'fi-size-md', ...colorClasses])}" data-table-filter-action="${action}" wire:click="${action === 'apply' ? 'applyTableFilters' : 'resetTableFiltersForm'}"${extra}>${e(label)}</button>`;
|
|
40
|
+
// Modal layout: "Apply" (deferred filters) closes the modal; "Reset" stays in the footer.
|
|
41
|
+
const filtersModalFooter = (modalId) => [
|
|
42
|
+
...(filtersDeferred && !filterActions.apply.hidden ? [filterButton('apply', primaryButtonClasses, filterActions.apply.label, ` x-on:click="${e("$dispatch('close-modal', { id: " + js(modalId) + ' })')}"`)] : []),
|
|
43
|
+
...(filterActions.reset.hidden ? [] : [filterButton('reset', grayButtonClasses, filterActions.reset.label)]),
|
|
44
|
+
];
|
|
45
|
+
const filtersPanel = (classes, extra = {}, closeModal = null) => view('filament-tables::filters', { attributes: attrs(extra).class(['fi-ta-filters', ...classes]).toHtml(), form: filtersForm, deferred: filtersDeferred, resetPosition: filtersResetPosition, closeModal, dangerLinkClasses, primaryButtonClasses, grayButtonClasses, filterActions, filterActionHtml });
|
|
46
|
+
%>
|
|
18
47
|
<div x-data="filamentTable({
|
|
19
48
|
areGroupsCollapsedByDefault: <%- grouping.collapsedByDefault ? 'true' : 'false' %>,
|
|
20
49
|
canTrackDeselectedRecords: true,
|
|
21
50
|
currentSelectionLivewireProperty: null,
|
|
22
|
-
maxSelectableRecords: null
|
|
51
|
+
maxSelectableRecords: <%- maxSelectableRecords ?? 'null' %>,
|
|
23
52
|
reorderMessage: <%- js(t('filament-tables::table.reordering.moved')) %>,
|
|
24
|
-
selectsCurrentPageOnly: false
|
|
53
|
+
selectsCurrentPageOnly: <%- selectsCurrentPageOnly ? 'true' : 'false' %>,
|
|
25
54
|
})" class="fi-ta">
|
|
26
55
|
<input type="hidden" value="<%- allCount %>" x-ref="allSelectableRecordsCount" />
|
|
27
56
|
|
|
28
57
|
<% if (reorder) { %><span wire:ignore x-ref="tableReorderStatus" role="status" aria-live="polite" aria-atomic="true" class="fi-sr-only"></span><% } %>
|
|
29
58
|
|
|
30
59
|
<div class="fi-ta-ctn<%- contentLayout ? ' fi-ta-ctn-with-content-layout' : '' %> fi-ta-ctn-with-footer fi-ta-ctn-with-header">
|
|
60
|
+
<% if (filtersForm !== null && filtersLayout.startsWith('before-content')) { %>
|
|
61
|
+
<div wire:ignore.self x-ref="filtersContentContainer" x-transition:enter-start="fi-opacity-0" x-transition:leave-end="fi-opacity-0" x-bind:class="{ 'fi-open': areFiltersOpen }" class="<%- cls(['fi-ta-filters-before-content-ctn', { 'lg:fi-open': !filtersLayout.endsWith('-collapsible') }, 'fi-width-' + (filtersFormWidth ?? 'xs')]) %>">
|
|
62
|
+
<%- filtersPanel(['fi-ta-filters-before-content']) %>
|
|
63
|
+
</div>
|
|
64
|
+
<% } %>
|
|
31
65
|
<div class="fi-ta-main">
|
|
32
66
|
<%# The toolbar is always visible only when it has content (search, filters, columns); otherwise only while records are selected. %>
|
|
33
|
-
<%
|
|
34
|
-
|
|
67
|
+
<%
|
|
68
|
+
const hasFilters = filtersForm !== null;
|
|
69
|
+
const filtersDialog = hasFilters && (filtersLayout === 'dropdown' || filtersLayout === 'modal');
|
|
70
|
+
const filtersAbove = hasFilters && (filtersLayout === 'above-content' || filtersLayout === 'above-content-collapsible');
|
|
71
|
+
const filtersBelow = hasFilters && filtersLayout === 'below-content';
|
|
72
|
+
const filtersBefore = hasFilters && filtersLayout.startsWith('before-content');
|
|
73
|
+
const filtersAfter = hasFilters && filtersLayout.startsWith('after-content');
|
|
74
|
+
const filtersCollapsible = hasFilters && filtersLayout.endsWith('-collapsible');
|
|
75
|
+
const filtersTriggerInToolbar = filtersDialog || filtersBefore || filtersAfter;
|
|
76
|
+
const filtersModalId = id + '-table-filters';
|
|
77
|
+
%>
|
|
78
|
+
<% const toolbarVisible = reorder !== null || groups.length > 0 || isSearchable || filtersTriggerInToolbar || hasColumnManager || toolbarActions.length > 0; %>
|
|
35
79
|
<div x-show="<%- heading !== null || headerActions.length || toolbarVisible ? 'true' : 'false' %> || false || (getSelectedRecordsCount() && <%- bulkActions.length ? 1 : 0 %>)" wire:key="<%= id %>.table.header.visible" class="fi-ta-header-ctn">
|
|
36
80
|
<%- hook('tables::header.before') %>
|
|
37
81
|
<% if (heading !== null || headerActions.length) { %>
|
|
@@ -52,44 +96,15 @@
|
|
|
52
96
|
<% } %>
|
|
53
97
|
<%- hook('tables::header.after') %>
|
|
54
98
|
<% if (filtersAbove) { %>
|
|
55
|
-
<%#
|
|
56
|
-
<div x-bind:class="{ 'fi-open': areFiltersOpen }" class="fi-ta-filters-above-content-ctn">
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
<h2 class="fi-ta-filters-heading">
|
|
60
|
-
<%= t('filament-tables::table.filters.heading') %>
|
|
61
|
-
</h2>
|
|
62
|
-
|
|
63
|
-
<div>
|
|
64
|
-
<button type="button" wire:loading.attr="aria-disabled" wire:loading.class="fi-disabled" class="<%- cls(['fi-ac-link-action', 'fi-link', 'fi-size-md', ...dangerLinkClasses]) %>" data-table-filter-action="reset" wire:click="resetTableFiltersForm">
|
|
65
|
-
<%- loadingIndicator(attrs({ 'wire:loading.delay.default': '', 'wire:target': 'resetTableFiltersForm' })) %>
|
|
66
|
-
<span class="fi-link-label">
|
|
67
|
-
<%= t('filament-tables::table.filters.actions.reset.label') %>
|
|
68
|
-
</span>
|
|
69
|
-
</button>
|
|
70
|
-
</div>
|
|
71
|
-
</div>
|
|
72
|
-
|
|
73
|
-
<%- filtersForm %>
|
|
74
|
-
|
|
75
|
-
<div class="fi-ta-filters-actions-ctn">
|
|
76
|
-
<button type="button" wire:loading.attr="aria-disabled" wire:loading.class="fi-disabled" class="<%- cls(['fi-ac-btn-action', 'fi-btn', 'fi-size-md', ...primaryButtonClasses]) %>" data-table-filter-action="apply" wire:click="applyTableFilters">
|
|
77
|
-
<%- loadingIndicator(attrs({ 'wire:loading.delay.default': '', 'wire:target': 'applyTableFilters' })) %>
|
|
78
|
-
<%= t('filament-tables::table.filters.actions.apply.label') %>
|
|
79
|
-
</button>
|
|
80
|
-
</div>
|
|
81
|
-
</div>
|
|
99
|
+
<%# Filters above the content, optionally collapsible. %>
|
|
100
|
+
<div<% if (filtersCollapsible) { %> x-bind:class="{ 'fi-open': areFiltersOpen }"<% } %> class="fi-ta-filters-above-content-ctn">
|
|
101
|
+
<%- filtersPanel([], filtersCollapsible ? { 'x-cloak': 'x-cloak', 'x-show': 'areFiltersOpen' } : { 'x-cloak': 'x-cloak' }) %>
|
|
102
|
+
<% if (filtersCollapsible) { %>
|
|
82
103
|
|
|
83
104
|
<span x-on:click="areFiltersOpen = ! areFiltersOpen" class="fi-ta-filters-trigger-action-ctn">
|
|
84
|
-
|
|
85
|
-
<%- icon('m-funnel') %>
|
|
86
|
-
<div class="fi-icon-btn-badge-ctn">
|
|
87
|
-
<span class="<%- cls([...badgeClasses, 'fi-badge', 'fi-size-xs']) %>">
|
|
88
|
-
<%- activeFiltersCount %>
|
|
89
|
-
</span>
|
|
90
|
-
</div>
|
|
91
|
-
</button>
|
|
105
|
+
<%- filtersTrigger() %>
|
|
92
106
|
</span>
|
|
107
|
+
<% } %>
|
|
93
108
|
</div>
|
|
94
109
|
<% } %>
|
|
95
110
|
<%- hook('tables::toolbar.before') %>
|
|
@@ -105,6 +120,7 @@
|
|
|
105
120
|
</button>
|
|
106
121
|
<% } %>
|
|
107
122
|
<%- hook('tables::toolbar.reorder-trigger.after') %>
|
|
123
|
+
<%- toolbarActions.join('') %>
|
|
108
124
|
<% if (bulkActions.length) { %>
|
|
109
125
|
<div x-data="filamentDropdown" x-cloak="x-cloak" x-show="getSelectedRecordsCount()" class="fi-dropdown">
|
|
110
126
|
<div x-on:mousedown="if ($event.button === 0) toggle($event)" class="fi-dropdown-trigger">
|
|
@@ -230,55 +246,33 @@
|
|
|
230
246
|
</div><% } %>
|
|
231
247
|
<%- hook('tables::toolbar.search.after') %>
|
|
232
248
|
|
|
233
|
-
<% if (
|
|
249
|
+
<% if (filtersDialog && filtersLayout === 'modal') { %>
|
|
250
|
+
<div class="fi-ta-filters-modal-trigger" x-on:click="$dispatch('open-modal', { id: <%= js(filtersModalId) %> })">
|
|
251
|
+
<%- filtersTrigger() %>
|
|
252
|
+
</div>
|
|
253
|
+
<%- modal({ id: filtersModalId, heading: t('filament-tables::table.filters.heading'), width: filtersFormWidth ?? 'md', livewireId: id, footerActions: filtersModalFooter(filtersModalId) }, filtersForm) %>
|
|
254
|
+
<% } else if (filtersDialog) { %>
|
|
234
255
|
<div x-data="filamentDropdown({ isMenu: false })" class="fi-dropdown fi-ta-filters-dropdown" wire:key="<%= id %>.table.filters">
|
|
235
256
|
<div x-on:mousedown="if ($event.button === 0) toggle($event)" class="fi-dropdown-trigger">
|
|
236
|
-
|
|
237
|
-
<%- icon('m-funnel') %>
|
|
238
|
-
<div class="fi-icon-btn-badge-ctn">
|
|
239
|
-
<span class="<%- cls([...badgeClasses, 'fi-badge', 'fi-size-xs']) %>">
|
|
240
|
-
<%- activeFiltersCount %>
|
|
241
|
-
</span>
|
|
242
|
-
</div>
|
|
243
|
-
</button>
|
|
257
|
+
<%- filtersTrigger() %>
|
|
244
258
|
</div>
|
|
245
259
|
|
|
246
|
-
<div x-cloak x-float.placement.bottom-end.shift.offset="{ offset: 8, }" x-ref="panel" x-transition:enter-start="fi-opacity-0" x-transition:leave-end="fi-opacity-0" wire:ignore.self wire:key="<%= id %>.table.filters.panel" class="fi-dropdown-panel fi-width
|
|
247
|
-
|
|
248
|
-
<div class="fi-ta-filters-header">
|
|
249
|
-
<h2 class="fi-ta-filters-heading">
|
|
250
|
-
<%= t('filament-tables::table.filters.heading') %>
|
|
251
|
-
</h2>
|
|
252
|
-
|
|
253
|
-
<div>
|
|
254
|
-
<button type="button" wire:loading.attr="aria-disabled" wire:loading.class="fi-disabled" class="<%- cls(['fi-ac-link-action', 'fi-link', 'fi-size-md', ...dangerLinkClasses]) %>" data-table-filter-action="reset" wire:click="resetTableFiltersForm">
|
|
255
|
-
<%- loadingIndicator(attrs({ 'wire:loading.delay.default': '', 'wire:target': 'resetTableFiltersForm' })) %>
|
|
256
|
-
<span class="fi-link-label">
|
|
257
|
-
<%= t('filament-tables::table.filters.actions.reset.label') %>
|
|
258
|
-
</span>
|
|
259
|
-
</button>
|
|
260
|
-
</div>
|
|
261
|
-
</div>
|
|
262
|
-
|
|
263
|
-
<%- filtersForm %>
|
|
264
|
-
|
|
265
|
-
<div class="fi-ta-filters-actions-ctn">
|
|
266
|
-
<button type="button" wire:loading.attr="aria-disabled" wire:loading.class="fi-disabled" class="<%- cls(['fi-ac-btn-action', 'fi-btn', 'fi-size-md', ...primaryButtonClasses]) %>" data-table-filter-action="apply" wire:click="applyTableFilters">
|
|
267
|
-
<%- loadingIndicator(attrs({ 'wire:loading.delay.default': '', 'wire:target': 'applyTableFilters' })) %>
|
|
268
|
-
<%= t('filament-tables::table.filters.actions.apply.label') %>
|
|
269
|
-
</button>
|
|
270
|
-
</div>
|
|
271
|
-
</div>
|
|
260
|
+
<div x-cloak x-float.placement.bottom-end.shift.offset="{ offset: 8, }" x-ref="panel" x-transition:enter-start="fi-opacity-0" x-transition:leave-end="fi-opacity-0" wire:ignore.self wire:key="<%= id %>.table.filters.panel" class="fi-dropdown-panel fi-width-<%= filtersFormWidth ?? 'xs' %>" style="<%= filtersFormMaxHeight ? 'max-height: ' + filtersFormMaxHeight : '' %>">
|
|
261
|
+
<%- filtersPanel([], { 'x-data': 'filamentTableFilters', 'x-on:click': 'handleActionClick($event)', tabindex: '-1' }) %>
|
|
272
262
|
</div>
|
|
273
263
|
</div>
|
|
264
|
+
<% } else if (filtersBefore || filtersAfter) { %>
|
|
265
|
+
<span x-ref="filtersTriggerActionContainer" x-on:click="toggleFiltersDropdown" class="<%- cls(['fi-ta-filters-trigger-action-ctn', { 'lg:fi-hidden': !filtersCollapsible }]) %>">
|
|
266
|
+
<%- filtersTrigger() %>
|
|
267
|
+
</span>
|
|
274
268
|
<% } %>
|
|
275
269
|
|
|
276
270
|
<%# These two hook slots only exist when there is a filters trigger or a column manager. %>
|
|
277
|
-
<% if (
|
|
271
|
+
<% if (filtersTriggerInToolbar || hasColumnManager) { %><%- hook('tables::toolbar.toggle-column-trigger.before') %><% } %>
|
|
278
272
|
<% if (hasColumnManager) { %>
|
|
279
273
|
<%- view('filament-tables::column-manager', { id, dangerLinkClasses, primaryButtonClasses }) %>
|
|
280
274
|
<% } %>
|
|
281
|
-
<% if (
|
|
275
|
+
<% if (filtersTriggerInToolbar || hasColumnManager) { %><%- hook('tables::toolbar.toggle-column-trigger.after') %><% } %>
|
|
282
276
|
</div><% } %>
|
|
283
277
|
<%- hook('tables::toolbar.end') %>
|
|
284
278
|
</div>
|
|
@@ -336,13 +330,14 @@
|
|
|
336
330
|
<div class="fi-ta-filter-indicators-badges-ctn" role="list">
|
|
337
331
|
<% for (const indicator of filterIndicators) { %>
|
|
338
332
|
<% const removal = 'removeTableFilter(' + js(indicator.filter) + ', ' + js(indicator.field) + ')'; %>
|
|
339
|
-
<span class="<%- cls([...indicatorBadgeClasses, 'fi-badge', 'fi-size-md']) %>" role="listitem">
|
|
333
|
+
<span class="<%- cls([...(indicator.color ? indicatorColorClasses(indicator.color) : indicatorBadgeClasses), 'fi-badge', 'fi-size-md']) %>" role="listitem">
|
|
340
334
|
<span class="fi-badge-label-ctn">
|
|
341
335
|
<span class="fi-badge-label">
|
|
342
336
|
<%= indicator.label %>
|
|
343
337
|
</span>
|
|
344
338
|
</span>
|
|
345
339
|
|
|
340
|
+
<% if (indicator.removable) { %>
|
|
346
341
|
<button data-prevent-disabled-clicks type="button" class="fi-badge-delete-btn" wire:loading.attr="aria-disabled" wire:loading.class="fi-disabled" wire:target="removeTableFilter" wire:click="<%= removal %>">
|
|
347
342
|
<span aria-hidden="true" wire:loading.remove.delay.default="" wire:target="<%= removal %>" class="fi-badge-delete-btn-icon"></span>
|
|
348
343
|
<%- loadingIndicator(attrs({ 'wire:loading.delay.default': '', 'wire:target': removal }), 'xs') %>
|
|
@@ -350,11 +345,13 @@
|
|
|
350
345
|
<%= t('filament-tables::table.filters.actions.remove.label') %>
|
|
351
346
|
</span>
|
|
352
347
|
</button>
|
|
348
|
+
<% } %>
|
|
353
349
|
</span>
|
|
354
350
|
<% } %>
|
|
355
351
|
</div>
|
|
356
352
|
</div>
|
|
357
353
|
|
|
354
|
+
<% if (filterIndicators.some((indicator) => indicator.removable)) { %>
|
|
358
355
|
<button x-tooltip="{
|
|
359
356
|
content: <%= js(t('filament-tables::table.filters.actions.remove_all.tooltip')) %>,
|
|
360
357
|
theme: $store.theme,
|
|
@@ -363,6 +360,7 @@
|
|
|
363
360
|
<%- icon('m-x-mark', { attributes: attrs({ 'wire:loading.remove.delay.default': '1', 'wire:target': 'removeTableFilters' }) }) %>
|
|
364
361
|
<%- loadingIndicator(attrs({ 'wire:loading.delay.default': '', 'wire:target': 'removeTableFilters' })) %>
|
|
365
362
|
</button>
|
|
363
|
+
<% } %>
|
|
366
364
|
</div>
|
|
367
365
|
<% } %>
|
|
368
366
|
|
|
@@ -463,13 +461,14 @@
|
|
|
463
461
|
<% } %>
|
|
464
462
|
</div>
|
|
465
463
|
<% } %>
|
|
466
|
-
<div aria-label="<%= heading ?? table.getPluralModelLabel() %>" role="list" class
|
|
464
|
+
<div aria-label="<%= heading ?? table.getPluralModelLabel() %>" role="list" <%- (contentGrid ? attrs().grid(contentGrid) : attrs()).class(['fi-ta-content', { 'fi-ta-content-grid': contentGrid !== null, 'fi-ta-content-grouped': grouping.active }]).toHtml() %>>
|
|
467
465
|
<% for (const row of rows) { %>
|
|
468
|
-
<div role="listitem" wire:key="<%= id %>.table.records.<%= row.key %>" class="<%- cls(['fi-ta-record', { 'fi-clickable': row.url || row.mountExpression, 'fi-ta-record-with-content-prefix': selectable }, row.classes]) %>" x-bind:class="{
|
|
466
|
+
<div<% if (row.collapsibleHtml !== null) { %> x-data="{ isCollapsed: <%- row.collapsed ? 'true' : 'false' %> }" x-init="$dispatch('collapsible-table-row-initialized')" x-on:collapse-all-table-rows.window="isCollapsed = true" x-on:expand-all-table-rows.window="isCollapsed = false"<% } %> role="listitem" wire:key="<%= id %>.table.records.<%= row.key %>" class="<%- cls(['fi-ta-record', { 'fi-clickable': row.url || row.mountExpression, 'fi-ta-record-with-content-prefix': selectable, 'fi-ta-record-with-content-suffix': row.collapsibleHtml !== null }, row.classes]) %>" x-bind:class="{<% if (row.collapsibleHtml !== null) { %>
|
|
467
|
+
'fi-ta-record-collapsed': isCollapsed,<% } %>
|
|
469
468
|
'fi-selected': <%- selectable ? 'true' : 'false' %> && isRecordSelected(<%= js(row.key) %>),
|
|
470
469
|
}">
|
|
471
|
-
<% if (selectable) { %>
|
|
472
|
-
<input aria-label="<%= t('filament-tables::table.fields.bulk_select_record.label', { key: row.key }) %>" type="checkbox" value="<%= row.key %>" x-on:click="toggleSelectedRecord(<%= js(row.key) %>)" x-bind:checked="isRecordSelected(<%= js(row.key) %>) ? 'checked' : null" data-group="<%= row.groupKey ?? '' %>" wire:loading.attr="disabled" wire:target="<%- targets %>" class="fi-ta-record-checkbox fi-checkbox-input" />
|
|
470
|
+
<% if (selectable && row.selectable) { %>
|
|
471
|
+
<input aria-label="<%= t('filament-tables::table.fields.bulk_select_record.label', { key: row.key }) %>" type="checkbox"<% if (maxSelectableRecords && maxSelectableRecords !== 1) { %> x-bind:disabled="! areRecordsToggleable([<%= js(row.key) %>])"<% } %> value="<%= row.key %>" x-on:click="toggleSelectedRecord(<%= js(row.key) %>)" x-bind:checked="isRecordSelected(<%= js(row.key) %>) ? 'checked' : null" data-group="<%= row.groupKey ?? '' %>" wire:loading.attr="disabled" wire:target="<%- targets %>" class="fi-ta-record-checkbox fi-checkbox-input" />
|
|
473
472
|
<% } %>
|
|
474
473
|
<div class="fi-ta-record-content-ctn">
|
|
475
474
|
<div>
|
|
@@ -480,13 +479,19 @@
|
|
|
480
479
|
<% } else { %>
|
|
481
480
|
<div class="fi-ta-record-content"><%- row.contentHtml %></div>
|
|
482
481
|
<% } %>
|
|
482
|
+
<% if (row.collapsibleHtml !== null) { %>
|
|
483
|
+
<div x-collapse x-show="! isCollapsed" class="fi-ta-record-content fi-collapsible"><%- row.collapsibleHtml %></div>
|
|
484
|
+
<% } %>
|
|
483
485
|
</div>
|
|
484
486
|
<% if (hasRowActions) { %>
|
|
485
|
-
<div class="fi-ta-actions fi-wrapped sm:fi-not-wrapped fi-align-start md:fi-align-end">
|
|
487
|
+
<div class="<%- cls(['fi-ta-actions fi-wrapped sm:fi-not-wrapped', contentGrid ? 'fi-align-' + (actionsAlignment ?? 'start') : 'fi-align-start md:fi-align-end', { 'fi-ta-actions-before-columns-position': actionsPosition === 'before-columns' }]) %>">
|
|
486
488
|
<%- row.actionsHtml ?? '' %>
|
|
487
489
|
</div>
|
|
488
490
|
<% } %>
|
|
489
491
|
</div>
|
|
492
|
+
<% if (row.collapsibleHtml !== null) { %>
|
|
493
|
+
<button aria-label="<%= t('filament-tables::table.actions.toggle_record_content.label', { key: row.key }) %>" x-bind:aria-expanded="! isCollapsed" type="button" x-on:click="isCollapsed = ! isCollapsed" class="fi-ta-record-collapse-btn fi-icon-btn"><%- icon('m-chevron-down') %></button>
|
|
494
|
+
<% } %>
|
|
490
495
|
</div>
|
|
491
496
|
<% } %>
|
|
492
497
|
</div>
|
|
@@ -593,18 +598,20 @@
|
|
|
593
598
|
|
|
594
599
|
<tr>
|
|
595
600
|
<% if (rows.length && reorder?.active) { %><th></th><% } %>
|
|
601
|
+
<% if (rows.length && !reorder?.active && hasRowActions && actionsPosition === 'before-cells') { %><th aria-label="<%= tc('filament-tables::table.columns.actions.label', 2) %>" scope="col" class="fi-ta-actions-header-cell fi-ta-empty-header-cell"></th><% } %>
|
|
596
602
|
<% if (rows.length && !reorder?.active && selectable) { %>
|
|
597
603
|
<th scope="col" class="fi-ta-cell fi-ta-selection-cell">
|
|
598
604
|
<input aria-label="<%= t('filament-tables::table.fields.bulk_select_page.label') %>" type="checkbox" x-bind:checked="<%= selectPageBinding %>" x-on:click="toggleSelectRecordsOnPage" wire:key="<%= id %>.table.bulk-select-page.checkbox.<%- randomKey() %>" wire:loading.attr="disabled" wire:target="<%- targets %>" class="fi-ta-page-checkbox fi-checkbox-input" />
|
|
599
605
|
</th>
|
|
600
606
|
<% } %>
|
|
607
|
+
<% if (rows.length && !reorder?.active && hasRowActions && actionsPosition === 'before-columns') { %><th aria-label="<%= tc('filament-tables::table.columns.actions.label', 2) %>" scope="col" class="fi-ta-actions-header-cell fi-ta-empty-header-cell"></th><% } %>
|
|
601
608
|
|
|
602
609
|
<%# A `tables::header.cell` hook that renders something replaces the column's header cell. %>
|
|
603
610
|
<% const hasHeaderCellHook = hasHook('tables::header.cell'); %>
|
|
604
611
|
<% for (const [columnIndex, column] of columns.entries()) { %>
|
|
605
612
|
<% const headerCellView = hasHeaderCellHook ? hook('tables::header.cell', { column: visibleColumns[columnIndex], isReordering }) : ''; %>
|
|
606
613
|
<% if (headerCellView.trim() !== '') { %><%- headerCellView %><% continue; } %>
|
|
607
|
-
<th<% if (column.sortable) { %> aria-sort="<%- column.sort %>"<% } %> scope="col" class="<%- cls(['fi-ta-header-cell', 'fi-ta-header-cell-' + column.cssName, { 'fi-grouped': column.grouped }, column.alignment && column.alignment !== 'start' ? 'fi-align-' + column.alignment : null]) %>"
|
|
614
|
+
<th<% if (column.sortable) { %> aria-sort="<%- column.sort %>"<% } %> scope="col" class="<%- cls(['fi-ta-header-cell', 'fi-ta-header-cell-' + column.cssName, { 'fi-growable': column.growable, 'fi-grouped': column.grouped, 'fi-wrapped': column.wrapHeader }, column.alignment && column.alignment !== 'start' ? 'fi-align-' + column.alignment : null, ...column.responsive]) %>"<% if (column.width) { %> style="width: <%= column.width %>"<% } %>>
|
|
608
615
|
<% if (column.sortable) { %>
|
|
609
616
|
<button type="button" data-prevent-disabled-clicks wire:click="sortTable(<%= js(column.name) %>)" wire:loading.attr="aria-disabled" wire:loading.class="fi-disabled" wire:target="<%- targets %>" class="fi-ta-header-cell-sort-btn">
|
|
610
617
|
<%= column.label %>
|
|
@@ -617,7 +624,7 @@
|
|
|
617
624
|
</th>
|
|
618
625
|
<% } %>
|
|
619
626
|
|
|
620
|
-
<% if (rows.length && !reorder?.active && hasRowActions) { %><th aria-label="<%= tc('filament-tables::table.columns.actions.label', 2) %>" scope="col" class="fi-ta-actions-header-cell fi-ta-empty-header-cell"></th><% } %>
|
|
627
|
+
<% if (rows.length && !reorder?.active && hasRowActions && !actionsPosition.startsWith('before')) { %><th aria-label="<%= tc('filament-tables::table.columns.actions.label', 2) %>" scope="col" class="fi-ta-actions-header-cell fi-ta-empty-header-cell"></th><% } %>
|
|
621
628
|
</tr>
|
|
622
629
|
</thead>
|
|
623
630
|
|
|
@@ -626,7 +633,7 @@
|
|
|
626
633
|
<tr class="fi-ta-row fi-ta-row-not-reorderable fi-ta-individual-search-row">
|
|
627
634
|
<% if (rows.length) { %><td></td><% } %>
|
|
628
635
|
<% for (const column of columns) { %>
|
|
629
|
-
<td class="<%- cls(['fi-ta-cell', column.individuallySearchable ? 'fi-ta-individual-search-cell fi-ta-individual-search-cell-' + column.cssName : null]) %>">
|
|
636
|
+
<td class="<%- cls(['fi-ta-cell', column.individuallySearchable ? 'fi-ta-individual-search-cell fi-ta-individual-search-cell-' + column.cssName : null, ...column.responsive]) %>">
|
|
630
637
|
<% if (column.individuallySearchable) { %>
|
|
631
638
|
<div x-id="['input']" class="fi-ta-search-field">
|
|
632
639
|
<label x-bind:for="$id('input')" class="fi-ta-cell-label">
|
|
@@ -706,15 +713,23 @@
|
|
|
706
713
|
<% } %>
|
|
707
714
|
</div>
|
|
708
715
|
</td>
|
|
709
|
-
<% } else if (
|
|
716
|
+
<% } else { %><% if (hasRowActions && actionsPosition === 'before-cells') { %><% rowActionsCell(row) %><% } %><% } %>
|
|
717
|
+
<% if (!reorder?.active && selectable) { %>
|
|
710
718
|
<td class="fi-ta-cell fi-ta-selection-cell">
|
|
711
|
-
|
|
719
|
+
<% if (row.selectable) { %><input aria-label="<%= t('filament-tables::table.fields.bulk_select_record.label', { key: row.key }) %>" type="checkbox"<% if (maxSelectableRecords && maxSelectableRecords !== 1) { %> x-bind:disabled="! areRecordsToggleable([<%= js(row.key) %>])"<% } %> value="<%= row.key %>" x-on:click="toggleSelectedRecord(<%= js(row.key) %>)" x-bind:checked="isRecordSelected(<%= js(row.key) %>) ? 'checked' : null" data-group="<%= row.groupKey ?? '' %>" wire:loading.attr="disabled" wire:target="<%- targets %>" class="fi-ta-record-checkbox fi-checkbox-input" /><% } %>
|
|
712
720
|
</td>
|
|
713
721
|
<% } %><%# end selection cell %>
|
|
722
|
+
<% if (!reorder?.active && hasRowActions && actionsPosition === 'before-columns') { %><% rowActionsCell(row) %><% } %>
|
|
714
723
|
|
|
715
724
|
<% for (const cell of row.cells) { %>
|
|
716
|
-
<td wire:key="<%= id %>.table.record.<%= row.key %>.column.<%= cell.name %>" class="<%- cls(['fi-ta-cell', 'fi-ta-cell-' + cell.cssName, cell.alignment && cell.alignment !== 'start' ? 'fi-align-' + cell.alignment : null]) %>">
|
|
717
|
-
<% if (cell.url) { %>
|
|
725
|
+
<td wire:key="<%= id %>.table.record.<%= row.key %>.column.<%= cell.name %>" class="<%- cls(['fi-ta-cell', 'fi-ta-cell-' + cell.cssName, cell.alignment && cell.alignment !== 'start' ? 'fi-align-' + cell.alignment : null, ...cell.responsive]) %>">
|
|
726
|
+
<% if (cell.mountExpression && !cell.url) { %>
|
|
727
|
+
<% if (table.isStackedOnMobile()) { %><div class="fi-ta-cell-label"><%= cell.label %></div><div class="fi-ta-cell-content"><% } %>
|
|
728
|
+
<button type="button" wire:click.prevent.stop="<%= cell.mountExpression %>" wire:loading.attr="disabled" wire:target="<%= cell.mountExpression %>" class="fi-ta-col">
|
|
729
|
+
<%- cell.html %>
|
|
730
|
+
</button>
|
|
731
|
+
<% if (table.isStackedOnMobile()) { %></div><% } %>
|
|
732
|
+
<% } else if (cell.url) { %>
|
|
718
733
|
<% if (table.isStackedOnMobile()) { %><div class="fi-ta-cell-label"><%= cell.label %></div><div class="fi-ta-cell-content"><% } %>
|
|
719
734
|
<a href="<%= cell.url %>" x-on:click="if (! ($event.altKey || $event.ctrlKey || $event.metaKey || $event.shiftKey)) { $event.preventDefault(); Alpine.navigate($el.getAttribute('href')) }" class="fi-ta-col fi-ta-col-has-column-url">
|
|
720
735
|
<%- cell.html %>
|
|
@@ -741,21 +756,7 @@
|
|
|
741
756
|
</td>
|
|
742
757
|
<% } %>
|
|
743
758
|
|
|
744
|
-
<% if (!reorder?.active && hasRowActions) { %>
|
|
745
|
-
<td class="fi-ta-cell">
|
|
746
|
-
<div class="fi-ta-actions ">
|
|
747
|
-
<%- row.actionsHtml ?? '' %>
|
|
748
|
-
<% for (const action of row.actions) { %>
|
|
749
|
-
<a href="<%= action.url %>" wire:navigate wire:key="<%= id %>.actions.<%= action.key %>" class="<%- cls(['fi-ac-link-action', 'fi-link', 'fi-size-sm', ...linkClasses]) %>">
|
|
750
|
-
<%- icon(action.icon, { size: 'sm' }) %>
|
|
751
|
-
<span class="fi-link-label">
|
|
752
|
-
<%= action.label %>
|
|
753
|
-
</span>
|
|
754
|
-
</a>
|
|
755
|
-
<% } %>
|
|
756
|
-
</div>
|
|
757
|
-
</td>
|
|
758
|
-
<% } %><%# end actions cell %>
|
|
759
|
+
<% if (!reorder?.active && hasRowActions && !actionsPosition.startsWith('before')) { %><% rowActionsCell(row) %><% } %><%# end actions cell %>
|
|
759
760
|
</tr>
|
|
760
761
|
<% } %>
|
|
761
762
|
<%# Summaries (already rendered and escaped rows): the last group's, then the table's. %>
|
|
@@ -771,20 +772,42 @@
|
|
|
771
772
|
<% if (rows.length) { %>
|
|
772
773
|
<%- pagination %>
|
|
773
774
|
<% } else { %>
|
|
775
|
+
<% if (emptyState.custom !== null) { %>
|
|
776
|
+
<%- emptyState.custom %>
|
|
777
|
+
<% } else { %>
|
|
774
778
|
<div class="fi-ta-empty-state" role="status">
|
|
775
779
|
<div class="fi-ta-empty-state-content">
|
|
776
780
|
<div class="fi-ta-empty-state-icon-bg">
|
|
777
|
-
<%- icon(
|
|
781
|
+
<%- icon(emptyState.icon, { size: 'lg', attributes: attrs({ 'wire:loading.remove.delay.default': '', 'wire:target': targets }) }) %>
|
|
778
782
|
<%- loadingIndicator(attrs({ 'wire:loading.delay.default': '', 'wire:target': targets }), 'lg') %>
|
|
779
783
|
</div>
|
|
780
784
|
|
|
781
785
|
<h2 class="fi-ta-empty-state-heading">
|
|
782
|
-
<%=
|
|
786
|
+
<%= emptyState.heading %>
|
|
783
787
|
</h2>
|
|
788
|
+
<% if (emptyState.description) { %>
|
|
789
|
+
<p class="fi-ta-empty-state-description">
|
|
790
|
+
<%= emptyState.description %>
|
|
791
|
+
</p>
|
|
792
|
+
<% } %>
|
|
793
|
+
<% if (emptyState.actions.length) { %>
|
|
794
|
+
<div class="fi-ta-actions fi-align-center fi-wrapped">
|
|
795
|
+
<%- emptyState.actions.join('') %>
|
|
796
|
+
</div>
|
|
797
|
+
<% } %>
|
|
784
798
|
</div>
|
|
785
799
|
</div>
|
|
800
|
+
<% } %>
|
|
786
801
|
<% } %>
|
|
802
|
+
<% if (filtersForm !== null && filtersLayout === 'below-content') { %>
|
|
803
|
+
<%- filtersPanel(['fi-ta-filters-below-content']) %>
|
|
804
|
+
<% } %>
|
|
805
|
+
</div>
|
|
806
|
+
<% if (filtersForm !== null && filtersLayout.startsWith('after-content')) { %>
|
|
807
|
+
<div wire:ignore.self x-ref="filtersContentContainer" x-transition:enter-start="fi-opacity-0" x-transition:leave-end="fi-opacity-0" x-bind:class="{ 'fi-open': areFiltersOpen }" class="<%- cls(['fi-ta-filters-after-content-ctn', { 'lg:fi-open': !filtersLayout.endsWith('-collapsible') }, 'fi-width-' + (filtersFormWidth ?? 'xs')]) %>">
|
|
808
|
+
<%- filtersPanel(['fi-ta-filters-after-content']) %>
|
|
787
809
|
</div>
|
|
810
|
+
<% } %>
|
|
788
811
|
</div>
|
|
789
812
|
<%- afterContainer %>
|
|
790
813
|
</div>
|