From dbd2cb0e6ef6375d15a8ca399edaa7384bad0778 Mon Sep 17 00:00:00 2001 From: LRLJoe Date: Fri, 31 Jan 2025 08:14:07 +0000 Subject: [PATCH 01/23] Partial Merges --- resources/js/laravel-livewire-tables.js | 124 ++++++++++++++++++ resources/js/laravel-livewire-tables.min.js | 2 +- .../filters/livewire-array-filter.blade.php | 4 + .../components/tools/filter-pills.blade.php | 64 +++++---- .../filter-pills/external-item.blade.php | 27 ++++ .../Filters/LivewireArrayExternalFilter.php | 33 +++++ .../HandlesCoreMethodsForExternalFilter.php | 13 ++ ...HandlesCorePropertiesForExternalFilter.php | 48 +++++++ .../HandlesTableEventsForExternalFilter.php | 25 ++++ .../HandlesUpdateStatusForExternalFilter.php | 12 ++ .../Configuration/FilterConfiguration.php | 10 -- .../HandlesLivewireComponentFilters.php | 44 +++++++ src/Traits/Filters/HandlesPillsData.php | 35 +++++ src/Traits/Filters/HasFilterCore.php | 45 +++++++ src/Traits/Filters/HasFilterPills.php | 6 +- src/Traits/Filters/Helpers/FilterHelpers.php | 11 ++ .../Filters/Helpers/FilterPillsHelpers.php | 37 +++++- .../FilterPillsStylingConfiguration.php | 37 +++++- .../Filters/Styling/HasFilterPillsStyling.php | 3 + .../Helpers/FilterPillsStylingHelpers.php | 6 + .../FilterPillsStylingConfiguration.php | 27 ---- .../Helpers/FilterPillsStylingHelpers.php | 26 ---- .../Filters/Traits/FilterConfiguration.php | 33 +---- src/Views/Filters/Traits/FilterHelpers.php | 65 +-------- src/Views/Filters/Traits/HasFilterLabel.php | 35 +++++ src/Views/Filters/Traits/HasFilterPills.php | 83 ++++++++++++ src/Views/Filters/Traits/IsFilter.php | 17 +-- 27 files changed, 663 insertions(+), 209 deletions(-) create mode 100644 resources/views/components/external/filters/livewire-array-filter.blade.php create mode 100644 resources/views/components/tools/filter-pills/external-item.blade.php create mode 100644 src/External/Filters/LivewireArrayExternalFilter.php create mode 100644 src/External/Filters/Traits/HandlesCoreMethodsForExternalFilter.php create mode 100644 src/External/Filters/Traits/HandlesCorePropertiesForExternalFilter.php create mode 100644 src/External/Filters/Traits/HandlesTableEventsForExternalFilter.php create mode 100644 src/External/Filters/Traits/HandlesUpdateStatusForExternalFilter.php create mode 100644 src/Traits/Filters/HandlesLivewireComponentFilters.php create mode 100644 src/Traits/Filters/HandlesPillsData.php create mode 100644 src/Traits/Filters/HasFilterCore.php delete mode 100644 src/Traits/Styling/Configuration/FilterPillsStylingConfiguration.php delete mode 100644 src/Traits/Styling/Helpers/FilterPillsStylingHelpers.php create mode 100644 src/Views/Filters/Traits/HasFilterLabel.php create mode 100644 src/Views/Filters/Traits/HasFilterPills.php diff --git a/resources/js/laravel-livewire-tables.js b/resources/js/laravel-livewire-tables.js index 58964b9d5..beb475cc0 100644 --- a/resources/js/laravel-livewire-tables.js +++ b/resources/js/laravel-livewire-tables.js @@ -19,6 +19,9 @@ document.addEventListener('alpine:init', () => { selectAllStatus: wire.entangle('selectAll'), delaySelectAll: wire.entangle('delaySelectAll'), hideBulkActionsWhenEmpty: wire.entangle('hideBulkActionsWhenEmpty'), + externalFilterPillsVals: wire.entangle('externalFilterPillsValues').live, + showFilterPillLabel: [], + filterPillsSeparator: ', ', dragging: false, reorderEnabled: false, sourceID: '', @@ -36,6 +39,36 @@ document.addEventListener('alpine:init', () => { currentlyReorderingStatus: wire.entangle('currentlyReorderingStatus'), hideReorderColumnUnlessReorderingStatus: wire.entangle('hideReorderColumnUnlessReorderingStatus'), reorderDisplayColumn: wire.entangle('reorderDisplayColumn'), + syncExternalFilterPillsValues(filterKey,filterValues) { + this.externalFilterPillsVals[filterKey] = filterValues; + this.showFilterPillLabel[filterKey] = this.getFilterPillsLength(filterKey); + }, + getFilterPillsLength(filterKey) + { + return Object.keys(this.externalFilterPillsVals[filterKey]).length ?? 0; + }, + setFilterPillsLength(externalFilterPillsValues) + { + let filterValueLength = 0; + if (typeof(externalFilterPillsValues) !== 'undefined') + { + filterValueLength = Object.keys(externalFilterPillsValues).length ?? 0; + } + else + { + filterValueLength = 0; + } + return filterValueLength; + }, + showFilterPillsLabel(filterKey) + { + let pillsLength = this.getFilterPillsLength(filterKey); + return (this.getFilterPillsLength(filterKey) > 0); + }, + showFilterPillsSeparator(filterKey,index) + { + return ((index+1) < (this.getFilterPillsLength(filterKey))); + }, dragStart(event) { this.$nextTick(() => { this.setupEvenOddClasses() }); this.sourceID = event.target.id; @@ -659,4 +692,95 @@ document.addEventListener('alpine:init', () => { } })); + Alpine.data('filterPillsArrayExternal', (tableNameVal, filterKeyVal) => ({ + tableName: tableNameVal, + filterKey: filterKeyVal, + filterPillValues: null, + separator: ', ', + filterPillValuesLength: 0, + hasLoaded: false, + updatedPillsValues(event) + { + this.hasLoaded = false; + let eventTableName = event.detail.tableName ?? ''; + let eventFilterValues = event.detail.filterValues; + let eventFilterValueLength = 0; + if((eventTableName ?? '') != '' && eventTableName === this.tableName) + { + this.filterPillValues = eventFilterValues; + eventFilterValueLength = this.setLength(eventFilterValues); + + this.filterPillValuesLength = eventFilterValueLength; + } + this.hasLoaded = true; + }, + refreshFilterPill(event) + { + + }, + refreshFilterPillNew(event) + { + let eventFilterValues = event.detail.filterValues; + + this.filterPillValues = eventFilterValues; + this.filterPillValuesLength = (typeof(eventFilterValues) !== 'undefined') ? Object.keys(eventFilterValues).length : 0; + + }, + setupFilterPill(separator, filterPillValues) + { + this.hasLoaded = false; + + this.separator = separator; + this.filterPillValues = filterPillValues; + this.filterPillValuesLength = (typeof(this.filterPillValues) !== 'undefined') ? Object.keys(this.filterPillValues).length : 0; + this.$nextTick(() => { + this.filterPillValuesLength = (typeof(this.filterPillValues) !== 'undefined') ? Object.keys(this.filterPillValues).length : 0 + this.hasLoaded = true; + + }); + + }, + setSeparator(value) + { + this.separator = value; + }, + getLength() + { + return Object.keys(this.filterPillValues).length ?? 0; + }, + setLength(eventFilterValues) + { + let filterValueLength = 0; + if (typeof(eventFilterValues) !== 'undefined') + { + filterValueLength = Object.keys(eventFilterValues).length ?? 0; + } + else + { + filterValueLength = 0; + } + return filterValueLength; + }, + showSeparator(index) + { + return ((index+1) < (this.getLength())); + }, + init() + { + window.addEventListener('filter-pills-updated', (event) => { + this.updatedPillsValues(event) + }); + + window.addEventListener('update-filter-pill-values', (event) => { + this.refreshFilterPill(event) + }); + window.addEventListener('refresh-filter-pill', (event) => { + this.refreshFilterPillNew(event); + }); + + + } + })); + + }); \ No newline at end of file diff --git a/resources/js/laravel-livewire-tables.min.js b/resources/js/laravel-livewire-tables.min.js index 4f13539e9..20e265477 100644 --- a/resources/js/laravel-livewire-tables.min.js +++ b/resources/js/laravel-livewire-tables.min.js @@ -1 +1 @@ -document.addEventListener("alpine:init",()=>{Alpine.data("laravellivewiretable",e=>({tableId:"",showBulkActionsAlpine:!1,primaryKeyName:"",shouldBeDisplayed:e.entangle("shouldBeDisplayed"),tableName:e.entangle("tableName"),dataTableFingerprint:e.entangle("dataTableFingerprint"),listeners:[],childElementOpen:!1,filtersOpen:e.entangle("filterSlideDownDefaultVisible"),paginationCurrentCount:e.entangle("paginationCurrentCount"),paginationTotalItemCount:e.entangle("paginationTotalItemCount"),paginationCurrentItems:e.entangle("paginationCurrentItems"),selectedItems:e.entangle("selected"),selectAllStatus:e.entangle("selectAll"),delaySelectAll:e.entangle("delaySelectAll"),hideBulkActionsWhenEmpty:e.entangle("hideBulkActionsWhenEmpty"),dragging:!1,reorderEnabled:!1,sourceID:"",targetID:"",evenRowClasses:"",oddRowClasses:"",currentlyHighlightedElement:"",evenRowClassArray:{},oddRowClassArray:{},evenNotInOdd:{},oddNotInEven:{},orderedRows:[],defaultReorderColumn:e.get("defaultReorderColumn"),reorderStatus:e.entangle("reorderStatus"),currentlyReorderingStatus:e.entangle("currentlyReorderingStatus"),hideReorderColumnUnlessReorderingStatus:e.entangle("hideReorderColumnUnlessReorderingStatus"),reorderDisplayColumn:e.entangle("reorderDisplayColumn"),dragStart(e){this.$nextTick(()=>{this.setupEvenOddClasses()}),this.sourceID=e.target.id,e.dataTransfer.effectAllowed="move",e.dataTransfer.setData("text/plain",e.target.id),e.target.classList.add("laravel-livewire-tables-dragging")},dragOverEvent(e){"object"==typeof this.currentlyHighlightedElement&&this.currentlyHighlightedElement.classList.remove("laravel-livewire-tables-highlight-bottom","laravel-livewire-tables-highlight-top");let t=e.target.closest("tr");this.currentlyHighlightedElement=t,e.offsetYt.getBoundingClientRect().height/2?l.insertBefore(i,t.nextSibling):l.insertBefore(i,t),a{this.setupEvenOddClasses()})},cancelReorder(){this.hideReorderColumnUnlessReorderingStatus&&(this.reorderDisplayColumn=!1),e.disableReordering()},updateOrderedItems(){let t=document.getElementById(this.tableId),l=[];for(let i=1,s;s=t.rows[i];i++)l.push({[this.primaryKeyName]:s.getAttribute("rowpk"),[this.defaultReorderColumn]:i});e.storeReorder(l)},setupEvenOddClasses(){if(void 0===this.evenNotInOdd.length||0==this.evenNotInOdd.length||void 0===this.oddNotInEven.length||0==this.oddNotInEven.length){let e=document.getElementById(this.tableId).getElementsByTagName("tbody")[0],t=[],l=[];void 0!==e.rows[0]&&void 0!==e.rows[1]&&(t=Array.from(e.rows[0].classList),l=Array.from(e.rows[1].classList),this.evenNotInOdd=t.filter(e=>!l.includes(e)),this.oddNotInEven=l.filter(e=>!t.includes(e)),t=[],l=[])}},toggleSelectAll(){this.showBulkActionsAlpine&&(this.paginationTotalItemCount===this.selectedItems.length?(this.clearSelected(),this.selectAllStatus=!1):this.delaySelectAll?this.setAllItemsSelected():this.setAllSelected())},setAllItemsSelected(){this.showBulkActionsAlpine&&(this.selectAllStatus=!0,this.selectAllOnPage())},setAllSelected(){this.showBulkActionsAlpine&&(this.delaySelectAll?(this.selectAllStatus=!0,this.selectAllOnPage()):e.setAllSelected())},clearSelected(){this.showBulkActionsAlpine&&(this.selectAllStatus=!1,e.clearSelected())},selectAllOnPage(){if(!this.showBulkActionsAlpine)return;let e=this.selectedItems,t=this.paginationCurrentItems.values();for(let l of t)e.push(l.toString());this.selectedItems=[...new Set(e)]},setTableId(e){this.tableId=e},setAlpineBulkActions(e){this.showBulkActionsAlpine=e},setPrimaryKeyName(e){this.primaryKeyName=e},showTable(e){let t=e.detail.tableName??"",l=e.detail.tableFingerpint??"";((t??"")!=""&&t===this.tableName||""!=l&&eventTableFingerpint===this.dataTableFingerprint)&&(this.shouldBeDisplayed=!0)},hideTable(e){let t=e.detail.tableName??"",l=e.detail.tableFingerpint??"";(""!=t&&t===this.tableName||""!=l&&eventTableFingerpint===this.dataTableFingerprint)&&(this.shouldBeDisplayed=!1)},destroy(){this.listeners.forEach(e=>{e()})}})),Alpine.data("booleanFilter",(e,t,l,i)=>({switchOn:!1,value:e.entangle("filterComponents."+t).live,init(){this.switchOn=!1,void 0!==this.value&&(this.switchOn=Boolean(Number(this.value))),this.listeners.push(Livewire.on("filter-was-set",e=>{e.tableName==l&&e.filterKey==t&&(this.switchOn=e.value??i)}))}})),Alpine.data("newBooleanFilter",(e,t,l)=>({switchOn:!1,value:!1,toggleStatus(){let t=!Boolean(Number(this.$wire.get("filterComponents."+e)??this.value));return this.switchOn=this.value=t,Number(t)},toggleStatusWithUpdate(){let t=this.toggleStatus();this.$wire.set("filterComponents."+e,t)},toggleStatusWithReset(){this.toggleStatus(),this.$wire.call("resetFilter",e)},setSwitchOn(e){let t=Number(e??0);this.switchOn=Boolean(t)},init(){this.$nextTick(()=>{this.value=this.$wire.get("filterComponents."+e)??l,this.setSwitchOn(this.value??0)}),this.listeners.push(Livewire.on("filter-was-set",i=>{i.tableName==t&&i.filterKey==e&&(this.switchOn=i.value??l)}))}})),Alpine.data("numberRangeFilter",(e,t,l,i,s)=>({allFilters:e.entangle("filterComponents",!1),originalMin:0,originalMax:100,filterMin:0,filterMax:100,currentMin:0,currentMax:100,hasUpdate:!1,wireValues:e.entangle("filterComponents."+t,!1),defaultMin:i.minRange,defaultMax:i.maxRange,restrictUpdates:!1,initialiseStyles(){let e=document.getElementById(l);e.style.setProperty("--value-a",this.wireValues.min??this.filterMin),e.style.setProperty("--text-value-a",JSON.stringify(this.wireValues.min??this.filterMin)),e.style.setProperty("--value-b",this.wireValues.max??this.filterMax),e.style.setProperty("--text-value-b",JSON.stringify(this.wireValues.max??this.filterMax))},updateStyles(e,t){let i=document.getElementById(l);i.style.setProperty("--value-a",e),i.style.setProperty("--text-value-a",JSON.stringify(e)),i.style.setProperty("--value-b",t),i.style.setProperty("--text-value-b",JSON.stringify(t))},setupWire(){void 0!==this.wireValues?(this.filterMin=this.originalMin=void 0!==this.wireValues.min?this.wireValues.min:this.defaultMin,this.filterMax=this.originalMax=void 0!==this.wireValues.max?this.wireValues.max:this.defaultMax):(this.filterMin=this.originalMin=this.defaultMin,this.filterMax=this.originalMax=this.defaultMax),this.updateStyles(this.filterMin,this.filterMax)},allowUpdates(){this.updateWire()},updateWire(){let e=parseInt(this.filterMin),t=parseInt(this.filterMax);(e!=this.originalMin||t!=this.originalMax)&&(tthis.setupWire())}})),Alpine.data("flatpickrFilter",(e,t,l,i,s)=>({wireValues:e.entangle("filterComponents."+t),flatpickrInstance:flatpickr(i,{mode:"range",altFormat:l.altFormat??"F j, Y",altInput:l.altInput??!1,allowInput:l.allowInput??!1,allowInvalidPreload:l.allowInvalidPreload??!0,ariaDateFormat:l.ariaDateFormat??"F j, Y",clickOpens:!0,dateFormat:l.dateFormat??"Y-m-d",defaultDate:l.defaultDate??null,defaultHour:l.defaultHour??12,defaultMinute:l.defaultMinute??0,enableTime:l.enableTime??!1,enableSeconds:l.enableSeconds??!1,hourIncrement:l.hourIncrement??1,locale:l.locale??"en",minDate:l.earliestDate??null,maxDate:l.latestDate??null,minuteIncrement:l.minuteIncrement??5,shorthandCurrentMonth:l.shorthandCurrentMonth??!1,time_24hr:l.time_24hr??!1,weekNumbers:l.weekNumbers??!1,onOpen:function(){window.childElementOpen=!0},onChange:function(l,i,s){if(l.length>1){var a=i.split(" "),n={};window.childElementOpen=!1,window.filterPopoverOpen=!1,n={minDate:a[0],maxDate:void 0===a[2]?a[0]:a[2]},e.set("filterComponents."+t,n)}}}),changedValue:function(l){l.length<5&&(this.flatpickrInstance.setDate([]),e.set("filterComponents."+t,{}))},setupWire(){if(void 0!==this.wireValues){if(void 0!==this.wireValues.minDate&&void 0!==this.wireValues.maxDate){let e=[this.wireValues.minDate,this.wireValues.maxDate];this.flatpickrInstance.setDate(e)}else this.flatpickrInstance.setDate([])}else this.flatpickrInstance.setDate([])},init(){this.setupWire(),this.$watch("wireValues",e=>this.setupWire())}})),Alpine.data("tableWrapper",(e,t)=>({shouldBeDisplayed:e.entangle("shouldBeDisplayed"),listeners:[],childElementOpen:!1,filtersOpen:e.entangle("filterSlideDownDefaultVisible"),paginationCurrentCount:e.entangle("paginationCurrentCount"),paginationTotalItemCount:e.entangle("paginationTotalItemCount"),paginationCurrentItems:e.entangle("paginationCurrentItems"),selectedItems:e.entangle("selected"),selectAllStatus:e.entangle("selectAll"),delaySelectAll:e.entangle("delaySelectAll"),hideBulkActionsWhenEmpty:e.entangle("hideBulkActionsWhenEmpty"),toggleSelectAll(){t&&(this.paginationTotalItemCount===this.selectedItems.length?(this.clearSelected(),this.selectAllStatus=!1):this.delaySelectAll?this.setAllItemsSelected():this.setAllSelected())},setAllItemsSelected(){t&&(this.selectAllStatus=!0,this.selectAllOnPage())},setAllSelected(){t&&(this.delaySelectAll?(this.selectAllStatus=!0,this.selectAllOnPage()):e.setAllSelected())},clearSelected(){t&&(this.selectAllStatus=!1,e.clearSelected())},selectAllOnPage(){if(!t)return;let e=this.selectedItems,l=this.paginationCurrentItems.values();for(let i of l)e.push(i.toString());this.selectedItems=[...new Set(e)]},destroy(){this.listeners.forEach(e=>{e()})}})),Alpine.data("reorderFunction",(e,t,l)=>({dragging:!1,reorderEnabled:!1,sourceID:"",targetID:"",evenRowClasses:"",oddRowClasses:"",currentlyHighlightedElement:"",evenRowClassArray:{},oddRowClassArray:{},evenNotInOdd:{},oddNotInEven:{},orderedRows:[],defaultReorderColumn:e.get("defaultReorderColumn"),reorderStatus:e.get("reorderStatus"),currentlyReorderingStatus:e.entangle("currentlyReorderingStatus"),hideReorderColumnUnlessReorderingStatus:e.entangle("hideReorderColumnUnlessReorderingStatus"),reorderDisplayColumn:e.entangle("reorderDisplayColumn"),dragStart(e){this.$nextTick(()=>{this.setupEvenOddClasses()}),this.sourceID=e.target.id,e.dataTransfer.effectAllowed="move",e.dataTransfer.setData("text/plain",e.target.id),e.target.classList.add("laravel-livewire-tables-dragging")},dragOverEvent(e){"object"==typeof this.currentlyHighlightedElement&&this.currentlyHighlightedElement.classList.remove("laravel-livewire-tables-highlight-bottom","laravel-livewire-tables-highlight-top");let t=e.target.closest("tr");this.currentlyHighlightedElement=t,e.offsetYl.getBoundingClientRect().height/2?i.insertBefore(s,l.nextSibling):i.insertBefore(s,l),n{this.setupEvenOddClasses()}),this.currentlyReorderingStatus?e.disableReordering():(this.setupEvenOddClasses(),this.hideReorderColumnUnlessReorderingStatus&&(this.reorderDisplayColumn=!0),e.enableReordering())},cancelReorder(){this.hideReorderColumnUnlessReorderingStatus&&(this.reorderDisplayColumn=!1),e.disableReordering()},updateOrderedItems(){let i=document.getElementById(t),s=[];for(let a=1,n;n=i.rows[a];a++)s.push({[l]:n.getAttribute("rowpk"),[this.defaultReorderColumn]:a});e.storeReorder(s)},setupEvenOddClasses(){if(void 0===this.evenNotInOdd.length||0==this.evenNotInOdd.length||void 0===this.oddNotInEven.length||0==this.oddNotInEven.length){let e=document.getElementById(t).getElementsByTagName("tbody")[0],l=[],i=[];void 0!==e.rows[0]&&void 0!==e.rows[1]&&(l=Array.from(e.rows[0].classList),i=Array.from(e.rows[1].classList),this.evenNotInOdd=l.filter(e=>!i.includes(e)),this.oddNotInEven=i.filter(e=>!l.includes(e)),l=[],i=[])}},init(){}}))}); \ No newline at end of file +document.addEventListener("alpine:init",()=>{Alpine.data("laravellivewiretable",e=>({tableId:"",showBulkActionsAlpine:!1,primaryKeyName:"",shouldBeDisplayed:e.entangle("shouldBeDisplayed"),tableName:e.entangle("tableName"),dataTableFingerprint:e.entangle("dataTableFingerprint"),listeners:[],childElementOpen:!1,filtersOpen:e.entangle("filterSlideDownDefaultVisible"),paginationCurrentCount:e.entangle("paginationCurrentCount"),paginationTotalItemCount:e.entangle("paginationTotalItemCount"),paginationCurrentItems:e.entangle("paginationCurrentItems"),selectedItems:e.entangle("selected"),selectAllStatus:e.entangle("selectAll"),delaySelectAll:e.entangle("delaySelectAll"),hideBulkActionsWhenEmpty:e.entangle("hideBulkActionsWhenEmpty"),externalFilterPillsVals:e.entangle("externalFilterPillsValues").live,showFilterPillLabel:[],filterPillsSeparator:", ",dragging:!1,reorderEnabled:!1,sourceID:"",targetID:"",evenRowClasses:"",oddRowClasses:"",currentlyHighlightedElement:"",evenRowClassArray:{},oddRowClassArray:{},evenNotInOdd:{},oddNotInEven:{},orderedRows:[],defaultReorderColumn:e.get("defaultReorderColumn"),reorderStatus:e.entangle("reorderStatus"),currentlyReorderingStatus:e.entangle("currentlyReorderingStatus"),hideReorderColumnUnlessReorderingStatus:e.entangle("hideReorderColumnUnlessReorderingStatus"),reorderDisplayColumn:e.entangle("reorderDisplayColumn"),syncExternalFilterPillsValues(e,t){this.externalFilterPillsVals[e]=t,this.showFilterPillLabel[e]=this.getFilterPillsLength(e)},getFilterPillsLength(e){return Object.keys(this.externalFilterPillsVals[e]).length??0},setFilterPillsLength(e){let t=0;return void 0!==e?Object.keys(e).length??0:0},showFilterPillsLabel(e){return this.getFilterPillsLength(e),this.getFilterPillsLength(e)>0},showFilterPillsSeparator(e,t){return t+1{this.setupEvenOddClasses()}),this.sourceID=e.target.id,e.dataTransfer.effectAllowed="move",e.dataTransfer.setData("text/plain",e.target.id),e.target.classList.add("laravel-livewire-tables-dragging")},dragOverEvent(e){"object"==typeof this.currentlyHighlightedElement&&this.currentlyHighlightedElement.classList.remove("laravel-livewire-tables-highlight-bottom","laravel-livewire-tables-highlight-top");let t=e.target.closest("tr");this.currentlyHighlightedElement=t,e.offsetYt.getBoundingClientRect().height/2?l.insertBefore(i,t.nextSibling):l.insertBefore(i,t),a{this.setupEvenOddClasses()})},cancelReorder(){this.hideReorderColumnUnlessReorderingStatus&&(this.reorderDisplayColumn=!1),e.disableReordering()},updateOrderedItems(){let t=document.getElementById(this.tableId),l=[];for(let i=1,s;s=t.rows[i];i++)l.push({[this.primaryKeyName]:s.getAttribute("rowpk"),[this.defaultReorderColumn]:i});e.storeReorder(l)},setupEvenOddClasses(){if(void 0===this.evenNotInOdd.length||0==this.evenNotInOdd.length||void 0===this.oddNotInEven.length||0==this.oddNotInEven.length){let e=document.getElementById(this.tableId).getElementsByTagName("tbody")[0],t=[],l=[];void 0!==e.rows[0]&&void 0!==e.rows[1]&&(t=Array.from(e.rows[0].classList),l=Array.from(e.rows[1].classList),this.evenNotInOdd=t.filter(e=>!l.includes(e)),this.oddNotInEven=l.filter(e=>!t.includes(e)),t=[],l=[])}},toggleSelectAll(){this.showBulkActionsAlpine&&(this.paginationTotalItemCount===this.selectedItems.length?(this.clearSelected(),this.selectAllStatus=!1):this.delaySelectAll?this.setAllItemsSelected():this.setAllSelected())},setAllItemsSelected(){this.showBulkActionsAlpine&&(this.selectAllStatus=!0,this.selectAllOnPage())},setAllSelected(){this.showBulkActionsAlpine&&(this.delaySelectAll?(this.selectAllStatus=!0,this.selectAllOnPage()):e.setAllSelected())},clearSelected(){this.showBulkActionsAlpine&&(this.selectAllStatus=!1,e.clearSelected())},selectAllOnPage(){if(!this.showBulkActionsAlpine)return;let e=this.selectedItems,t=this.paginationCurrentItems.values();for(let l of t)e.push(l.toString());this.selectedItems=[...new Set(e)]},setTableId(e){this.tableId=e},setAlpineBulkActions(e){this.showBulkActionsAlpine=e},setPrimaryKeyName(e){this.primaryKeyName=e},showTable(e){let t=e.detail.tableName??"",l=e.detail.tableFingerpint??"";((t??"")!=""&&t===this.tableName||""!=l&&eventTableFingerpint===this.dataTableFingerprint)&&(this.shouldBeDisplayed=!0)},hideTable(e){let t=e.detail.tableName??"",l=e.detail.tableFingerpint??"";(""!=t&&t===this.tableName||""!=l&&eventTableFingerpint===this.dataTableFingerprint)&&(this.shouldBeDisplayed=!1)},destroy(){this.listeners.forEach(e=>{e()})}})),Alpine.data("booleanFilter",(e,t,l,i)=>({switchOn:!1,value:e.entangle("filterComponents."+t).live,init(){this.switchOn=!1,void 0!==this.value&&(this.switchOn=Boolean(Number(this.value))),this.listeners.push(Livewire.on("filter-was-set",e=>{e.tableName==l&&e.filterKey==t&&(this.switchOn=e.value??i)}))}})),Alpine.data("newBooleanFilter",(e,t,l)=>({switchOn:!1,value:!1,toggleStatus(){let t=!Boolean(Number(this.$wire.get("filterComponents."+e)??this.value));return this.switchOn=this.value=t,Number(t)},toggleStatusWithUpdate(){let t=this.toggleStatus();this.$wire.set("filterComponents."+e,t)},toggleStatusWithReset(){this.toggleStatus(),this.$wire.call("resetFilter",e)},setSwitchOn(e){let t=Number(e??0);this.switchOn=Boolean(t)},init(){this.$nextTick(()=>{this.value=this.$wire.get("filterComponents."+e)??l,this.setSwitchOn(this.value??0)}),this.listeners.push(Livewire.on("filter-was-set",i=>{i.tableName==t&&i.filterKey==e&&(this.switchOn=i.value??l)}))}})),Alpine.data("numberRangeFilter",(e,t,l,i,s)=>({allFilters:e.entangle("filterComponents",!1),originalMin:0,originalMax:100,filterMin:0,filterMax:100,currentMin:0,currentMax:100,hasUpdate:!1,wireValues:e.entangle("filterComponents."+t,!1),defaultMin:i.minRange,defaultMax:i.maxRange,restrictUpdates:!1,initialiseStyles(){let e=document.getElementById(l);e.style.setProperty("--value-a",this.wireValues.min??this.filterMin),e.style.setProperty("--text-value-a",JSON.stringify(this.wireValues.min??this.filterMin)),e.style.setProperty("--value-b",this.wireValues.max??this.filterMax),e.style.setProperty("--text-value-b",JSON.stringify(this.wireValues.max??this.filterMax))},updateStyles(e,t){let i=document.getElementById(l);i.style.setProperty("--value-a",e),i.style.setProperty("--text-value-a",JSON.stringify(e)),i.style.setProperty("--value-b",t),i.style.setProperty("--text-value-b",JSON.stringify(t))},setupWire(){void 0!==this.wireValues?(this.filterMin=this.originalMin=void 0!==this.wireValues.min?this.wireValues.min:this.defaultMin,this.filterMax=this.originalMax=void 0!==this.wireValues.max?this.wireValues.max:this.defaultMax):(this.filterMin=this.originalMin=this.defaultMin,this.filterMax=this.originalMax=this.defaultMax),this.updateStyles(this.filterMin,this.filterMax)},allowUpdates(){this.updateWire()},updateWire(){let e=parseInt(this.filterMin),t=parseInt(this.filterMax);(e!=this.originalMin||t!=this.originalMax)&&(tthis.setupWire())}})),Alpine.data("flatpickrFilter",(e,t,l,i,s)=>({wireValues:e.entangle("filterComponents."+t),flatpickrInstance:flatpickr(i,{mode:"range",altFormat:l.altFormat??"F j, Y",altInput:l.altInput??!1,allowInput:l.allowInput??!1,allowInvalidPreload:l.allowInvalidPreload??!0,ariaDateFormat:l.ariaDateFormat??"F j, Y",clickOpens:!0,dateFormat:l.dateFormat??"Y-m-d",defaultDate:l.defaultDate??null,defaultHour:l.defaultHour??12,defaultMinute:l.defaultMinute??0,enableTime:l.enableTime??!1,enableSeconds:l.enableSeconds??!1,hourIncrement:l.hourIncrement??1,locale:l.locale??"en",minDate:l.earliestDate??null,maxDate:l.latestDate??null,minuteIncrement:l.minuteIncrement??5,shorthandCurrentMonth:l.shorthandCurrentMonth??!1,time_24hr:l.time_24hr??!1,weekNumbers:l.weekNumbers??!1,onOpen:function(){window.childElementOpen=!0},onChange:function(l,i,s){if(l.length>1){var a=i.split(" "),r={};window.childElementOpen=!1,window.filterPopoverOpen=!1,r={minDate:a[0],maxDate:void 0===a[2]?a[0]:a[2]},e.set("filterComponents."+t,r)}}}),changedValue:function(l){l.length<5&&(this.flatpickrInstance.setDate([]),e.set("filterComponents."+t,{}))},setupWire(){if(void 0!==this.wireValues){if(void 0!==this.wireValues.minDate&&void 0!==this.wireValues.maxDate){let e=[this.wireValues.minDate,this.wireValues.maxDate];this.flatpickrInstance.setDate(e)}else this.flatpickrInstance.setDate([])}else this.flatpickrInstance.setDate([])},init(){this.setupWire(),this.$watch("wireValues",e=>this.setupWire())}})),Alpine.data("tableWrapper",(e,t)=>({shouldBeDisplayed:e.entangle("shouldBeDisplayed"),listeners:[],childElementOpen:!1,filtersOpen:e.entangle("filterSlideDownDefaultVisible"),paginationCurrentCount:e.entangle("paginationCurrentCount"),paginationTotalItemCount:e.entangle("paginationTotalItemCount"),paginationCurrentItems:e.entangle("paginationCurrentItems"),selectedItems:e.entangle("selected"),selectAllStatus:e.entangle("selectAll"),delaySelectAll:e.entangle("delaySelectAll"),hideBulkActionsWhenEmpty:e.entangle("hideBulkActionsWhenEmpty"),toggleSelectAll(){t&&(this.paginationTotalItemCount===this.selectedItems.length?(this.clearSelected(),this.selectAllStatus=!1):this.delaySelectAll?this.setAllItemsSelected():this.setAllSelected())},setAllItemsSelected(){t&&(this.selectAllStatus=!0,this.selectAllOnPage())},setAllSelected(){t&&(this.delaySelectAll?(this.selectAllStatus=!0,this.selectAllOnPage()):e.setAllSelected())},clearSelected(){t&&(this.selectAllStatus=!1,e.clearSelected())},selectAllOnPage(){if(!t)return;let e=this.selectedItems,l=this.paginationCurrentItems.values();for(let i of l)e.push(i.toString());this.selectedItems=[...new Set(e)]},destroy(){this.listeners.forEach(e=>{e()})}})),Alpine.data("reorderFunction",(e,t,l)=>({dragging:!1,reorderEnabled:!1,sourceID:"",targetID:"",evenRowClasses:"",oddRowClasses:"",currentlyHighlightedElement:"",evenRowClassArray:{},oddRowClassArray:{},evenNotInOdd:{},oddNotInEven:{},orderedRows:[],defaultReorderColumn:e.get("defaultReorderColumn"),reorderStatus:e.get("reorderStatus"),currentlyReorderingStatus:e.entangle("currentlyReorderingStatus"),hideReorderColumnUnlessReorderingStatus:e.entangle("hideReorderColumnUnlessReorderingStatus"),reorderDisplayColumn:e.entangle("reorderDisplayColumn"),dragStart(e){this.$nextTick(()=>{this.setupEvenOddClasses()}),this.sourceID=e.target.id,e.dataTransfer.effectAllowed="move",e.dataTransfer.setData("text/plain",e.target.id),e.target.classList.add("laravel-livewire-tables-dragging")},dragOverEvent(e){"object"==typeof this.currentlyHighlightedElement&&this.currentlyHighlightedElement.classList.remove("laravel-livewire-tables-highlight-bottom","laravel-livewire-tables-highlight-top");let t=e.target.closest("tr");this.currentlyHighlightedElement=t,e.offsetYl.getBoundingClientRect().height/2?i.insertBefore(s,l.nextSibling):i.insertBefore(s,l),r{this.setupEvenOddClasses()}),this.currentlyReorderingStatus?e.disableReordering():(this.setupEvenOddClasses(),this.hideReorderColumnUnlessReorderingStatus&&(this.reorderDisplayColumn=!0),e.enableReordering())},cancelReorder(){this.hideReorderColumnUnlessReorderingStatus&&(this.reorderDisplayColumn=!1),e.disableReordering()},updateOrderedItems(){let i=document.getElementById(t),s=[];for(let a=1,r;r=i.rows[a];a++)s.push({[l]:r.getAttribute("rowpk"),[this.defaultReorderColumn]:a});e.storeReorder(s)},setupEvenOddClasses(){if(void 0===this.evenNotInOdd.length||0==this.evenNotInOdd.length||void 0===this.oddNotInEven.length||0==this.oddNotInEven.length){let e=document.getElementById(t).getElementsByTagName("tbody")[0],l=[],i=[];void 0!==e.rows[0]&&void 0!==e.rows[1]&&(l=Array.from(e.rows[0].classList),i=Array.from(e.rows[1].classList),this.evenNotInOdd=l.filter(e=>!i.includes(e)),this.oddNotInEven=i.filter(e=>!l.includes(e)),l=[],i=[])}},init(){}})),Alpine.data("filterPillsArrayExternal",(e,t)=>({tableName:e,filterKey:t,filterPillValues:null,separator:", ",filterPillValuesLength:0,hasLoaded:!1,updatedPillsValues(e){this.hasLoaded=!1;let t=e.detail.tableName??"",l=e.detail.filterValues,i=0;(t??"")!=""&&t===this.tableName&&(this.filterPillValues=l,i=this.setLength(l),this.filterPillValuesLength=i),this.hasLoaded=!0},refreshFilterPill(e){},refreshFilterPillNew(e){let t=e.detail.filterValues;this.filterPillValues=t,this.filterPillValuesLength=void 0!==t?Object.keys(t).length:0},setupFilterPill(e,t){this.hasLoaded=!1,this.separator=e,this.filterPillValues=t,this.filterPillValuesLength=void 0!==this.filterPillValues?Object.keys(this.filterPillValues).length:0,this.$nextTick(()=>{this.filterPillValuesLength=void 0!==this.filterPillValues?Object.keys(this.filterPillValues).length:0,this.hasLoaded=!0})},setSeparator(e){this.separator=e},getLength(){return Object.keys(this.filterPillValues).length??0},setLength(e){let t=0;return void 0!==e?Object.keys(e).length??0:0},showSeparator(e){return e+1{this.updatedPillsValues(e)}),window.addEventListener("update-filter-pill-values",e=>{this.refreshFilterPill(e)}),window.addEventListener("refresh-filter-pill",e=>{this.refreshFilterPillNew(e)})}}))}); \ No newline at end of file diff --git a/resources/views/components/external/filters/livewire-array-filter.blade.php b/resources/views/components/external/filters/livewire-array-filter.blade.php new file mode 100644 index 000000000..6a5bd30d0 --- /dev/null +++ b/resources/views/components/external/filters/livewire-array-filter.blade.php @@ -0,0 +1,4 @@ +
+ {{ $slot }} +
\ No newline at end of file diff --git a/resources/views/components/tools/filter-pills.blade.php b/resources/views/components/tools/filter-pills.blade.php index 613c5b906..ff2b1915f 100644 --- a/resources/views/components/tools/filter-pills.blade.php +++ b/resources/views/components/tools/filter-pills.blade.php @@ -1,30 +1,40 @@ @aware([ 'tableName','isTailwind','isBootstrap','isBootstrap4','isBootstrap5']) -
-
$isTailwind, - 'mb-3' => $isBootstrap, - ]) x-cloak x-show="!currentlyReorderingStatus"> - $isTailwind, - '' => $isBootstrap, - ])> - {{ __($this->getLocalisationPath.'Applied Filters') }}: - +
merge([ - @tableloop($this->getAppliedFiltersWithValues() as $filterSelectName => $value) - @php($filter = $this->getFilterByKey($filterSelectName)) - @continue(is_null($filter) || $filter->isHiddenFromPills()) - @php( $filterPillValue = $filter->getFilterPillValue($value)) - @continue((is_array($filterPillValue) && empty($filterPillValue))) - @php( $filterPillTitle = $filter->getFilterPillTitle()) - @php( $separator = method_exists($filter, 'getPillsSeparator') ? $filter->getPillsSeparator() : ', ') - @if ($filter->hasCustomPillBlade()) - @include($filter->getCustomPillBlade(), ['filter' => $filter]) - @else - - @endif - @endtableloop - -
-
+ 'wire:loading.class' => $this->displayFilterPillsWhileLoading ? '' : 'invisible', + 'x-cloak', +]) +->class([ + 'mb-4 px-4 md:p-0' => $isTailwind, + 'mb-3' => $isBootstrap, +]) + +}}> + $isTailwind, + '' => $isBootstrap, + ])> + {{ __($this->getLocalisationPath.'Applied Filters') }}: + + @tableloop($this->getPillDataForFilter() as $filterKey => $data) + @php + $filterPillValue = $data['filterPillValue']; + $filterPillTitle = $data['filterPillTitle']; + $filterSelectName = $data['filterSelectName']; + $isAnExternalLivewireFilter = $data['isAnExternalLivewireFilter']; + $separator = $data['separator']; + + @endphp + @if ($data['filter']->hasCustomPillBlade()) + @include($data['filter']->getCustomPillBlade(), ['filter' => $data['filter']]) + @elseif($isAnExternalLivewireFilter) + + + @else + + @endif + @endtableloop + + +
\ No newline at end of file diff --git a/resources/views/components/tools/filter-pills/external-item.blade.php b/resources/views/components/tools/filter-pills/external-item.blade.php new file mode 100644 index 000000000..4615c0f44 --- /dev/null +++ b/resources/views/components/tools/filter-pills/external-item.blade.php @@ -0,0 +1,27 @@ +@aware(['tableName','isTailwind','isBootstrap','isBootstrap4','isBootstrap5']) +@props(['filterKey', 'filterPillTitle', 'filterPillValue' => [], 'filterSelectName', 'separator' => ', ']) + +merge($this->getFilterPillsItemAttributes) + ->class([ + 'inline-flex space-x-1 items-center px-2.5 py-0.5 rounded-full text-xs font-medium leading-4 capitalize' => $isTailwind && $this->getFilterPillsItemAttributes['default-styling'], + 'bg-indigo-100 text-indigo-800 dark:bg-indigo-200 dark:text-indigo-900' => $isTailwind && $this->getFilterPillsItemAttributes['default-colors'], + 'badge badge-pill badge-info d-inline-flex align-items-center' => $isBootstrap4 && $this->getFilterPillsItemAttributes['default-styling'], + 'badge rounded-pill bg-info d-inline-flex align-items-center' => $isBootstrap5 && $this->getFilterPillsItemAttributes['default-styling'], + ]) + ->except(['default-styling', 'default-colors']) + }}> + {{ $filterPillTitle }}: + + + + + diff --git a/src/External/Filters/LivewireArrayExternalFilter.php b/src/External/Filters/LivewireArrayExternalFilter.php new file mode 100644 index 000000000..5f08f1cdd --- /dev/null +++ b/src/External/Filters/LivewireArrayExternalFilter.php @@ -0,0 +1,33 @@ +skipUpdate) { + if (! $this->needsUpdating) { + $this->needsUpdating = true; + } + } + } +} \ No newline at end of file diff --git a/src/External/Filters/Traits/HandlesCoreMethodsForExternalFilter.php b/src/External/Filters/Traits/HandlesCoreMethodsForExternalFilter.php new file mode 100644 index 000000000..1ba5222a7 --- /dev/null +++ b/src/External/Filters/Traits/HandlesCoreMethodsForExternalFilter.php @@ -0,0 +1,13 @@ +setupFilter(); + } + + protected function setupFilter(): void {} +} diff --git a/src/External/Filters/Traits/HandlesCorePropertiesForExternalFilter.php b/src/External/Filters/Traits/HandlesCorePropertiesForExternalFilter.php new file mode 100644 index 000000000..ef0363fd5 --- /dev/null +++ b/src/External/Filters/Traits/HandlesCorePropertiesForExternalFilter.php @@ -0,0 +1,48 @@ +filterKey = $filterKey; + + return $this; + } + + public function getFilterKey(): string + { + return $this->filterKey; + } + + protected function setTableName(string $tableName): self + { + $this->tableName = $tableName; + + return $this; + } + + public function getTableName(): string + { + return $this->tableName; + } + + protected function setTableComponent(string $tableComponent): self + { + $this->tableComponent = $tableComponent; + + return $this; + } + + public function getTableComponent(): string + { + return $this->tableComponent; + } +} diff --git a/src/External/Filters/Traits/HandlesTableEventsForExternalFilter.php b/src/External/Filters/Traits/HandlesTableEventsForExternalFilter.php new file mode 100644 index 000000000..5afbdcbdb --- /dev/null +++ b/src/External/Filters/Traits/HandlesTableEventsForExternalFilter.php @@ -0,0 +1,25 @@ +tableName && $filterKey == $this->filterKey && $this->optionsSelected != $value) { + $this->optionsSelected = $value; + } + } + + #[Renderless] + public function renderingHandlesTableEventsForExternalFilter() + { + if ($this->needsUpdating) { + $this->needsUpdating = false; + $this->dispatch('livewireArrayFilterUpdateValuesNew', tableName: $this->tableName, filterKey: $this->filterKey, values: $this->optionsSelected)->to($this->tableComponent); + } + } +} diff --git a/src/External/Filters/Traits/HandlesUpdateStatusForExternalFilter.php b/src/External/Filters/Traits/HandlesUpdateStatusForExternalFilter.php new file mode 100644 index 000000000..8fa78f7ff --- /dev/null +++ b/src/External/Filters/Traits/HandlesUpdateStatusForExternalFilter.php @@ -0,0 +1,12 @@ +tableName == $tableName) { - $filter = $this->getFilterByKey($filterKey); - $filter->options($values); - } - - } - public function selectAllFilterOptions(string $filterKey): void { $filter = $this->getFilterByKey($filterKey); diff --git a/src/Traits/Filters/HandlesLivewireComponentFilters.php b/src/Traits/Filters/HandlesLivewireComponentFilters.php new file mode 100644 index 000000000..057b323b9 --- /dev/null +++ b/src/Traits/Filters/HandlesLivewireComponentFilters.php @@ -0,0 +1,44 @@ +hasExternalFilters; + } + + #[On('livewireArrayFilterUpdateValues')] + public function updateLivewireArrayFilterValues(string $filterKey, string $tableName, array $values): void + { + if ($this->getTableName() == $tableName) { + $filter = $this->getFilterByKey($filterKey); + $filter->options($values); + } + } + + #[On('livewireArrayFilterUpdateValuesNew')] + public function updateLivewireArrayFilterValuesNew(string $filterKey, string $tableName, array $values): void + { + $setup = ['original' => null, 'new' => null]; + + if ($this->getTableName() == $tableName) { + + $setup['original'] = $this->getFilters(); + $filterArray = $this->filterCollection->toArray(); + foreach ($filterArray as $index => $filter) { + if ($filter->getKey() == $filterKey) { + $options = collect($values)->pluck('value', 'id')->toArray(); + $filter->options($options); + $filterArray[$index] = $filter; + } + } + $this->filterCollection = collect($filterArray); + } + } +} diff --git a/src/Traits/Filters/HandlesPillsData.php b/src/Traits/Filters/HandlesPillsData.php new file mode 100644 index 000000000..abe0a6d02 --- /dev/null +++ b/src/Traits/Filters/HandlesPillsData.php @@ -0,0 +1,35 @@ +getAppliedFiltersWithValuesForPills() as $filterSelectName => $value) { + if (! is_null($filterSelectName)) { + if (! is_null($filter = $this->getFilterByKey($filterSelectName))) { + if ($filter->isEmpty($value)) { + continue; + } + $filterPillValue = $filter->getFilterPillValue($value); + $filterPillTitle = $filter->getFilterPillTitle(); + + $filters[$filter->getKey()] = [ + 'filter' => $filter, + 'isAnExternalLivewireFilter' => (method_exists($filter, 'isAnExternalLivewireFilter') && $filter->isAnExternalLivewireFilter()), + 'filterSelectName' => $filterSelectName, + 'filterPillTitle' => $filterPillTitle, + 'filterPillValue' => $filterPillValue, + 'separator' => method_exists($filter, 'getPillsSeparator') ? $filter->getPillsSeparator() : ', ', + ]; + } + } + + } + + return $filters; + } +} diff --git a/src/Traits/Filters/HasFilterCore.php b/src/Traits/Filters/HasFilterCore.php new file mode 100644 index 000000000..6b667f6b1 --- /dev/null +++ b/src/Traits/Filters/HasFilterCore.php @@ -0,0 +1,45 @@ +restoreFilterValues(); + + foreach ($this->getFilters() as $filter) { + if (method_exists($filter, 'isAnExternalLivewireFilter')) { + $this->tableHasExternalFilters = true; + } + if (! isset($this->appliedFilters[$filter->getKey()])) { + if ($filter->hasFilterDefaultValue()) { + $this->setFilter($filter->getKey(), $filter->getFilterDefaultValue()); + } else { + $this->resetFilter($filter); + } + } else { + $this->setFilter($filter->getKey(), $this->appliedFilters[$filter->getKey()]); + } + } + } + + public function bootedHasFilterCore(): void + { + $this->setBuilder($this->builder()); + + foreach ($this->filterComponents as $filterKey => $value) { + $this->appliedFilters[$filterKey] = $value; + } + } +} diff --git a/src/Traits/Filters/HasFilterPills.php b/src/Traits/Filters/HasFilterPills.php index ad94d9ba3..dbb9f6a17 100644 --- a/src/Traits/Filters/HasFilterPills.php +++ b/src/Traits/Filters/HasFilterPills.php @@ -15,4 +15,8 @@ trait HasFilterPills #[Locked] public bool $filterPillsStatus = true; -} + + public array $externalFilterPillsValues = []; + + public array $externalFilterPillsLength = []; +} \ No newline at end of file diff --git a/src/Traits/Filters/Helpers/FilterHelpers.php b/src/Traits/Filters/Helpers/FilterHelpers.php index 0c538653e..215ecb47f 100644 --- a/src/Traits/Filters/Helpers/FilterHelpers.php +++ b/src/Traits/Filters/Helpers/FilterHelpers.php @@ -111,4 +111,15 @@ public function getAppliedFiltersWithValuesCount(): int { return count($this->getAppliedFiltersWithValues()); } + + public function getAppliedFiltersCollection(): Collection + { + $validFilterKeys = $this->getFilters() + ->map(fn (Filter $filter) => $filter->getKey()) + ->toArray(); + + return collect($this->filterComponents ?? []) + ->filter(fn ($value, $key) => in_array($key, $validFilterKeys, true)); + } + } diff --git a/src/Traits/Filters/Helpers/FilterPillsHelpers.php b/src/Traits/Filters/Helpers/FilterPillsHelpers.php index f12cad696..83320ab6e 100644 --- a/src/Traits/Filters/Helpers/FilterPillsHelpers.php +++ b/src/Traits/Filters/Helpers/FilterPillsHelpers.php @@ -10,7 +10,7 @@ trait FilterPillsHelpers #[Computed] public function showFilterPillsSection(): bool { - return $this->filtersAreEnabled() && $this->filterPillsAreEnabled() && $this->hasAppliedVisibleFiltersForPills(); + return $this->filtersAreEnabled() && $this->filterPillsAreEnabled() && ($this->getAppliedFiltersWithValuesForPillsCount() > 0); } public function getFilterPillsStatus(): bool @@ -35,4 +35,37 @@ public function hasAppliedVisibleFiltersForPills(): bool ->reject(fn (Filter $filter) => $filter->isHiddenFromPills()) ->count() > 0; } -} + + /** + * @return array + */ + public function getAppliedFiltersWithValuesForPills(): array + { + return $this->appliedFilters = array_filter($this->getAppliedFilters(), function ($item, $key) { + $filter = $this->getFilterByKey($key); + if ($filter->isHiddenFromPills() || is_null($item)) { + return false; + } + $validatedValue = $filter->validate($item); + + if (is_null($validatedValue) || $filter->isEmpty($validatedValue) || $validatedValue == 'null') { + return false; + } else { + if (is_array($validatedValue)) { + if (array_key_exists(0, $validatedValue) && (is_null($validatedValue[0]) || $validatedValue[0] == 'null')) { + return false; + + } + } + } + + return is_array($validatedValue) ? count($validatedValue) : $validatedValue !== null; + }, ARRAY_FILTER_USE_BOTH); + } + + public function getAppliedFiltersWithValuesForPillsCount(): int + { + return count($this->getAppliedFiltersWithValuesForPills()); + + } +} \ No newline at end of file diff --git a/src/Traits/Filters/Styling/Configuration/FilterPillsStylingConfiguration.php b/src/Traits/Filters/Styling/Configuration/FilterPillsStylingConfiguration.php index 107428920..9d7b6b150 100644 --- a/src/Traits/Filters/Styling/Configuration/FilterPillsStylingConfiguration.php +++ b/src/Traits/Filters/Styling/Configuration/FilterPillsStylingConfiguration.php @@ -4,18 +4,41 @@ trait FilterPillsStylingConfiguration { - protected function setFilterPillsItemAttributes(array $attributes = []): self + protected function setShowFilterPillsWhileLoading(bool $status): self { - return $this->mergeCustomAttributes(propertyName: 'filterPillsItemAttributes', customAttributes: $attributes); + $this->showFilterPillsWhileLoading = $status; + + return $this; + } + + protected function showFilterPillsWhileLoadingEnabled(): self + { + return $this->setShowFilterPillsWhileLoading(true); } - protected function setFilterPillsResetFilterButtonAttributes(array $attributes = []): self + protected function showFilterPillsWhileLoadingDisabled(): self { - return $this->mergeCustomAttributes(propertyName: 'filterPillsResetFilterButtonAttributes', customAttributes: $attributes); + return $this->setShowFilterPillsWhileLoading(false); } - protected function setFilterPillsResetAllButtonAttributes(array $attributes = []): self + public function setFilterPillsItemAttributes(array $attributes = []): self { - return $this->mergeCustomAttributes(propertyName: 'filterPillsResetAllButtonAttributes', customAttributes: $attributes); + $this->filterPillsItemAttributes = [...$this->filterPillsItemAttributes, ...$attributes]; + + return $this; + } + + public function setFilterPillsResetFilterButtonAttributes(array $attributes = []): self + { + $this->filterPillsResetFilterButtonAttributes = [...$this->filterPillsResetFilterButtonAttributes, ...$attributes]; + + return $this; + } + + public function setFilterPillsResetAllButtonAttributes(array $attributes = []): self + { + $this->filterPillsResetAllButtonAttributes = [...$this->filterPillsResetAllButtonAttributes, ...$attributes]; + + return $this; } -} +} \ No newline at end of file diff --git a/src/Traits/Filters/Styling/HasFilterPillsStyling.php b/src/Traits/Filters/Styling/HasFilterPillsStyling.php index 78c0b829a..691ab5495 100644 --- a/src/Traits/Filters/Styling/HasFilterPillsStyling.php +++ b/src/Traits/Filters/Styling/HasFilterPillsStyling.php @@ -15,4 +15,7 @@ trait HasFilterPillsStyling protected array $filterPillsResetFilterButtonAttributes = ['class' => '', 'default-colors' => true, 'default-styling' => true]; protected array $filterPillsResetAllButtonAttributes = ['class' => '', 'default-colors' => true, 'default-styling' => true]; + + protected bool $showFilterPillsWhileLoading = true; + } diff --git a/src/Traits/Filters/Styling/Helpers/FilterPillsStylingHelpers.php b/src/Traits/Filters/Styling/Helpers/FilterPillsStylingHelpers.php index c3bd0d9d5..cfa10c377 100644 --- a/src/Traits/Filters/Styling/Helpers/FilterPillsStylingHelpers.php +++ b/src/Traits/Filters/Styling/Helpers/FilterPillsStylingHelpers.php @@ -6,6 +6,12 @@ trait FilterPillsStylingHelpers { + #[Computed] + public function displayFilterPillsWhileLoading(): bool + { + return $this->showFilterPillsWhileLoading; + } + #[Computed] public function getFilterPillsItemAttributes(): array { diff --git a/src/Traits/Styling/Configuration/FilterPillsStylingConfiguration.php b/src/Traits/Styling/Configuration/FilterPillsStylingConfiguration.php deleted file mode 100644 index 049b82d1d..000000000 --- a/src/Traits/Styling/Configuration/FilterPillsStylingConfiguration.php +++ /dev/null @@ -1,27 +0,0 @@ -filterPillsItemAttributes = [...$this->filterPillsItemAttributes, ...$attributes]; - - return $this; - } - - public function setFilterPillsResetFilterButtonAttributes(array $attributes = []): self - { - $this->filterPillsResetFilterButtonAttributes = [...$this->filterPillsResetFilterButtonAttributes, ...$attributes]; - - return $this; - } - - public function setFilterPillsResetAllButtonAttributes(array $attributes = []): self - { - $this->filterPillsResetAllButtonAttributes = [...$this->filterPillsResetAllButtonAttributes, ...$attributes]; - - return $this; - } -} diff --git a/src/Traits/Styling/Helpers/FilterPillsStylingHelpers.php b/src/Traits/Styling/Helpers/FilterPillsStylingHelpers.php deleted file mode 100644 index 2de5e1f6a..000000000 --- a/src/Traits/Styling/Helpers/FilterPillsStylingHelpers.php +++ /dev/null @@ -1,26 +0,0 @@ -filterPillsItemAttributes; - } - - #[Computed] - public function getFilterPillsResetFilterButtonAttributes(): array - { - return $this->filterPillsResetFilterButtonAttributes; - } - - #[Computed] - public function getFilterPillsResetAllButtonAttributes(): array - { - return $this->filterPillsResetAllButtonAttributes; - } -} diff --git a/src/Views/Filters/Traits/FilterConfiguration.php b/src/Views/Filters/Traits/FilterConfiguration.php index 2bf3f11b5..1c54907c6 100644 --- a/src/Views/Filters/Traits/FilterConfiguration.php +++ b/src/Views/Filters/Traits/FilterConfiguration.php @@ -4,23 +4,6 @@ trait FilterConfiguration { - public function setFilterPillTitle(string $title): self - { - $this->filterPillTitle = $title; - - return $this; - } - - /** - * @param array $values - */ - public function setFilterPillValues(array $values): self - { - $this->filterPillValues = $values; - - return $this; - } - public function notResetByClearButton(): self { $this->resetByClearButton = false; @@ -28,20 +11,6 @@ public function notResetByClearButton(): self return $this; } - public function setCustomFilterLabel(string $filterCustomLabel): self - { - $this->filterCustomLabel = $filterCustomLabel; - - return $this; - } - - public function setFilterPillBlade(string $blade): self - { - $this->filterCustomPillBlade = $blade; - - return $this; - } - /** * Sets a Default Value via the Filter Component * @@ -69,4 +38,4 @@ public function setGenericDisplayData(array $genericDisplayData = []): self return $this; } -} +} \ No newline at end of file diff --git a/src/Views/Filters/Traits/FilterHelpers.php b/src/Views/Filters/Traits/FilterHelpers.php index 10af4f5d2..2b433eb14 100644 --- a/src/Views/Filters/Traits/FilterHelpers.php +++ b/src/Views/Filters/Traits/FilterHelpers.php @@ -57,74 +57,11 @@ public function getFilterCallback(): callable return $this->filterCallback; } - public function getCustomFilterPillTitle(): ?string - { - return $this->filterPillTitle; - } - - public function getFilterPillTitle(): string - { - return $this->getCustomFilterPillTitle() ?? $this->getName(); - } - - /** - * @param mixed $value - */ - public function getFilterPillValue($value): array|string|bool|null - { - return $value; - } - - /** - * @return array - */ - public function getCustomFilterPillValues(): array - { - return $this->filterPillValues; - } - - public function getCustomFilterPillValue(string $value): ?string - { - return $this->getCustomFilterPillValues()[$value] ?? null; - } - public function isResetByClearButton(): bool { return $this->resetByClearButton === true; } - /** - * Returns whether the filter has a custom label blade - */ - public function hasCustomFilterLabel(): bool - { - return ! is_null($this->filterCustomLabel); - } - - /** - * Returns the path to the custom filter label blade - */ - public function getCustomFilterLabel(): string - { - return $this->filterCustomLabel ?? ''; - } - - /** - * Determine if filter has a Custom Pill Blade - */ - public function hasCustomPillBlade(): bool - { - return $this->filterCustomPillBlade != null; - } - - /** - * Get the path to the Custom Pill Blade - */ - public function getCustomPillBlade(): ?string - { - return $this->filterCustomPillBlade; - } - /** * Determines if the Filter has a Default Value via the Component */ @@ -154,4 +91,4 @@ public function render(): string|\Illuminate\Contracts\Foundation\Application|\I ->with($this->getFilterDisplayData()) ->with(['filterInputAttributes' => $this->getInputAttributesBag()]); } -} +} \ No newline at end of file diff --git a/src/Views/Filters/Traits/HasFilterLabel.php b/src/Views/Filters/Traits/HasFilterLabel.php new file mode 100644 index 000000000..b95bca9ed --- /dev/null +++ b/src/Views/Filters/Traits/HasFilterLabel.php @@ -0,0 +1,35 @@ +filterCustomLabel = $filterCustomLabel; + + return $this; + } + + /** + * Returns whether the filter has a custom label blade + */ + public function hasCustomFilterLabel(): bool + { + return ! is_null($this->filterCustomLabel); + } + + /** + * Returns the path to the custom filter label blade + */ + public function getCustomFilterLabel(): string + { + return $this->filterCustomLabel ?? ''; + } +} \ No newline at end of file diff --git a/src/Views/Filters/Traits/HasFilterPills.php b/src/Views/Filters/Traits/HasFilterPills.php new file mode 100644 index 000000000..0d9eaeece --- /dev/null +++ b/src/Views/Filters/Traits/HasFilterPills.php @@ -0,0 +1,83 @@ +filterPillTitle = $title; + + return $this; + } + + /** + * @param array $values + */ + public function setFilterPillValues(array $values): self + { + $this->filterPillValues = $values; + + return $this; + } + + public function setFilterPillBlade(string $blade): self + { + $this->filterCustomPillBlade = $blade; + + return $this; + } + + public function getCustomFilterPillTitle(): ?string + { + return $this->filterPillTitle; + } + + public function getFilterPillTitle(): string + { + return $this->getCustomFilterPillTitle() ?? $this->getName(); + } + + /** + * @param mixed $value + */ + public function getFilterPillValue($value): array|string|bool|null + { + return $value; + } + + /** + * @return array + */ + public function getCustomFilterPillValues(): array + { + return $this->filterPillValues; + } + + public function getCustomFilterPillValue(string $value): ?string + { + return $this->getCustomFilterPillValues()[$value] ?? null; + } + + /** + * Determine if filter has a Custom Pill Blade + */ + public function hasCustomPillBlade(): bool + { + return $this->filterCustomPillBlade != null; + } + + /** + * Get the path to the Custom Pill Blade + */ + public function getCustomPillBlade(): ?string + { + return $this->filterCustomPillBlade; + } +} \ No newline at end of file diff --git a/src/Views/Filters/Traits/IsFilter.php b/src/Views/Filters/Traits/IsFilter.php index 61cd61a4d..eff47120f 100644 --- a/src/Views/Filters/Traits/IsFilter.php +++ b/src/Views/Filters/Traits/IsFilter.php @@ -3,12 +3,14 @@ namespace Rappasoft\LaravelLivewireTables\Views\Filters\Traits; use Rappasoft\LaravelLivewireTables\Traits\Core\HasLocalisations; -use Rappasoft\LaravelLivewireTables\Views\Filters\Traits\Styling\{HandlesFilterInputAttributes, HandlesFilterLabelAttributes}; +use Rappasoft\LaravelLivewireTables\Views\Filters\Traits\Styling\{HandlesFilterInputAttributes}; use Rappasoft\LaravelLivewireTables\Views\Traits\Core\{HasConfig, HasLabelAttributes, HasView}; trait IsFilter { use HasLocalisations, + HasFilterPills, + HasFilterLabel, FilterConfiguration, FilterHelpers, HasConfig, @@ -16,8 +18,7 @@ trait IsFilter HasLabelAttributes, HasVisibility, HasView, - HandlesFilterInputAttributes, - HandlesFilterLabelAttributes; + HandlesFilterInputAttributes; protected string $name; @@ -27,15 +28,7 @@ trait IsFilter protected mixed $filterCallback = null; - protected ?string $filterPillTitle = null; - - protected array $filterPillValues = []; - - protected ?string $filterCustomLabel = null; - - protected ?string $filterCustomPillBlade = null; - protected mixed $filterDefaultValue = null; public array $genericDisplayData = []; -} +} \ No newline at end of file From f40727c271862387f68e15250effe2530f6bdd15 Mon Sep 17 00:00:00 2001 From: lrljoe <104938042+lrljoe@users.noreply.github.com> Date: Fri, 31 Jan 2025 08:14:35 +0000 Subject: [PATCH 02/23] Fix styling --- src/External/Filters/LivewireArrayExternalFilter.php | 2 +- src/Traits/Filters/HasFilterPills.php | 2 +- src/Traits/Filters/Helpers/FilterHelpers.php | 1 - src/Traits/Filters/Helpers/FilterPillsHelpers.php | 2 +- .../Styling/Configuration/FilterPillsStylingConfiguration.php | 2 +- src/Traits/Filters/Styling/HasFilterPillsStyling.php | 1 - src/Views/Filters/Traits/FilterConfiguration.php | 2 +- src/Views/Filters/Traits/FilterHelpers.php | 2 +- src/Views/Filters/Traits/HasFilterLabel.php | 2 +- src/Views/Filters/Traits/HasFilterPills.php | 2 +- src/Views/Filters/Traits/IsFilter.php | 2 +- 11 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/External/Filters/LivewireArrayExternalFilter.php b/src/External/Filters/LivewireArrayExternalFilter.php index 5f08f1cdd..dd3c93d50 100644 --- a/src/External/Filters/LivewireArrayExternalFilter.php +++ b/src/External/Filters/LivewireArrayExternalFilter.php @@ -30,4 +30,4 @@ public function updatedOptionsSelected($value) } } } -} \ No newline at end of file +} diff --git a/src/Traits/Filters/HasFilterPills.php b/src/Traits/Filters/HasFilterPills.php index dbb9f6a17..428015b2c 100644 --- a/src/Traits/Filters/HasFilterPills.php +++ b/src/Traits/Filters/HasFilterPills.php @@ -19,4 +19,4 @@ trait HasFilterPills public array $externalFilterPillsValues = []; public array $externalFilterPillsLength = []; -} \ No newline at end of file +} diff --git a/src/Traits/Filters/Helpers/FilterHelpers.php b/src/Traits/Filters/Helpers/FilterHelpers.php index 215ecb47f..b6843a7ba 100644 --- a/src/Traits/Filters/Helpers/FilterHelpers.php +++ b/src/Traits/Filters/Helpers/FilterHelpers.php @@ -121,5 +121,4 @@ public function getAppliedFiltersCollection(): Collection return collect($this->filterComponents ?? []) ->filter(fn ($value, $key) => in_array($key, $validFilterKeys, true)); } - } diff --git a/src/Traits/Filters/Helpers/FilterPillsHelpers.php b/src/Traits/Filters/Helpers/FilterPillsHelpers.php index 83320ab6e..53071683e 100644 --- a/src/Traits/Filters/Helpers/FilterPillsHelpers.php +++ b/src/Traits/Filters/Helpers/FilterPillsHelpers.php @@ -68,4 +68,4 @@ public function getAppliedFiltersWithValuesForPillsCount(): int return count($this->getAppliedFiltersWithValuesForPills()); } -} \ No newline at end of file +} diff --git a/src/Traits/Filters/Styling/Configuration/FilterPillsStylingConfiguration.php b/src/Traits/Filters/Styling/Configuration/FilterPillsStylingConfiguration.php index 9d7b6b150..358705c75 100644 --- a/src/Traits/Filters/Styling/Configuration/FilterPillsStylingConfiguration.php +++ b/src/Traits/Filters/Styling/Configuration/FilterPillsStylingConfiguration.php @@ -41,4 +41,4 @@ public function setFilterPillsResetAllButtonAttributes(array $attributes = []): return $this; } -} \ No newline at end of file +} diff --git a/src/Traits/Filters/Styling/HasFilterPillsStyling.php b/src/Traits/Filters/Styling/HasFilterPillsStyling.php index 691ab5495..8012d14d7 100644 --- a/src/Traits/Filters/Styling/HasFilterPillsStyling.php +++ b/src/Traits/Filters/Styling/HasFilterPillsStyling.php @@ -17,5 +17,4 @@ trait HasFilterPillsStyling protected array $filterPillsResetAllButtonAttributes = ['class' => '', 'default-colors' => true, 'default-styling' => true]; protected bool $showFilterPillsWhileLoading = true; - } diff --git a/src/Views/Filters/Traits/FilterConfiguration.php b/src/Views/Filters/Traits/FilterConfiguration.php index 1c54907c6..54311d2f8 100644 --- a/src/Views/Filters/Traits/FilterConfiguration.php +++ b/src/Views/Filters/Traits/FilterConfiguration.php @@ -38,4 +38,4 @@ public function setGenericDisplayData(array $genericDisplayData = []): self return $this; } -} \ No newline at end of file +} diff --git a/src/Views/Filters/Traits/FilterHelpers.php b/src/Views/Filters/Traits/FilterHelpers.php index 2b433eb14..4e3495c21 100644 --- a/src/Views/Filters/Traits/FilterHelpers.php +++ b/src/Views/Filters/Traits/FilterHelpers.php @@ -91,4 +91,4 @@ public function render(): string|\Illuminate\Contracts\Foundation\Application|\I ->with($this->getFilterDisplayData()) ->with(['filterInputAttributes' => $this->getInputAttributesBag()]); } -} \ No newline at end of file +} diff --git a/src/Views/Filters/Traits/HasFilterLabel.php b/src/Views/Filters/Traits/HasFilterLabel.php index b95bca9ed..ad672e798 100644 --- a/src/Views/Filters/Traits/HasFilterLabel.php +++ b/src/Views/Filters/Traits/HasFilterLabel.php @@ -32,4 +32,4 @@ public function getCustomFilterLabel(): string { return $this->filterCustomLabel ?? ''; } -} \ No newline at end of file +} diff --git a/src/Views/Filters/Traits/HasFilterPills.php b/src/Views/Filters/Traits/HasFilterPills.php index 0d9eaeece..3087853a6 100644 --- a/src/Views/Filters/Traits/HasFilterPills.php +++ b/src/Views/Filters/Traits/HasFilterPills.php @@ -80,4 +80,4 @@ public function getCustomPillBlade(): ?string { return $this->filterCustomPillBlade; } -} \ No newline at end of file +} diff --git a/src/Views/Filters/Traits/IsFilter.php b/src/Views/Filters/Traits/IsFilter.php index eff47120f..f4612053f 100644 --- a/src/Views/Filters/Traits/IsFilter.php +++ b/src/Views/Filters/Traits/IsFilter.php @@ -31,4 +31,4 @@ trait IsFilter protected mixed $filterDefaultValue = null; public array $genericDisplayData = []; -} \ No newline at end of file +} From 601ea9707e2747f9170f79ed1864952ccd6f6002 Mon Sep 17 00:00:00 2001 From: LRLJoe Date: Fri, 31 Jan 2025 08:23:07 +0000 Subject: [PATCH 03/23] Minor adjustments --- src/Traits/Filters/HandlesPillsData.php | 18 ++++++++++++------ src/Traits/WithFilters.php | 6 ++++-- .../Traits/IsLivewireComponentFilter.php | 6 ++++++ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/Traits/Filters/HandlesPillsData.php b/src/Traits/Filters/HandlesPillsData.php index abe0a6d02..2a7eccff1 100644 --- a/src/Traits/Filters/HandlesPillsData.php +++ b/src/Traits/Filters/HandlesPillsData.php @@ -8,15 +8,20 @@ public function getPillDataForFilter(): array { $filters = []; - foreach ($this->getAppliedFiltersWithValuesForPills() as $filterSelectName => $value) { - if (! is_null($filterSelectName)) { - if (! is_null($filter = $this->getFilterByKey($filterSelectName))) { - if ($filter->isEmpty($value)) { + foreach ($this->getAppliedFiltersWithValuesForPills() as $filterSelectName => $value) + { + if (!is_null($filterSelectName)) + { + if(!is_null($filter = $this->getFilterByKey($filterSelectName))) + { + if($filter->isEmpty($value)) + { continue; } $filterPillValue = $filter->getFilterPillValue($value); $filterPillTitle = $filter->getFilterPillTitle(); + $filters[$filter->getKey()] = [ 'filter' => $filter, 'isAnExternalLivewireFilter' => (method_exists($filter, 'isAnExternalLivewireFilter') && $filter->isAnExternalLivewireFilter()), @@ -27,9 +32,10 @@ public function getPillDataForFilter(): array ]; } } - + } return $filters; } -} + +} \ No newline at end of file diff --git a/src/Traits/WithFilters.php b/src/Traits/WithFilters.php index 08f66a8a8..7a509d695 100644 --- a/src/Traits/WithFilters.php +++ b/src/Traits/WithFilters.php @@ -4,17 +4,19 @@ use Illuminate\Support\Collection; use Livewire\Attributes\Locked; -use Rappasoft\LaravelLivewireTables\Traits\Filters\{HasFilterGenericData, HasFilterMenu, HasFilterPills, HasFilterQueryString, HasFiltersCore, HasFiltersStatus, HasFiltersVisibility}; +use Rappasoft\LaravelLivewireTables\Traits\Filters\{HandlesLivewireComponentFilters, HasFilterGenericData, HandlesPillsData, HasFilterMenu, HasFilterPills, HasFilterQueryString, HasFiltersCore, HasFiltersStatus, HasFiltersVisibility}; trait WithFilters { use HasFiltersStatus, HasFilterGenericData, HasFilterMenu, + HandlesPillsData, HasFilterPills, HasFilterQueryString, HasFiltersVisibility, - HasFiltersCore; + HasFiltersCore, + HandlesLivewireComponentFilters; // Set in JS public array $filterComponents = []; diff --git a/src/Views/Filters/Traits/IsLivewireComponentFilter.php b/src/Views/Filters/Traits/IsLivewireComponentFilter.php index 9d05a0b95..c6360ad18 100644 --- a/src/Views/Filters/Traits/IsLivewireComponentFilter.php +++ b/src/Views/Filters/Traits/IsLivewireComponentFilter.php @@ -8,6 +8,12 @@ trait IsLivewireComponentFilter { public string $livewireComponent = ''; + + public function isAnExternalLivewireFilter(): bool + { + return true; + } + public function setLivewireComponent(string $livewireComponent): self { From d777eec6da2d466aabf6dc294693d69a15ca24fe Mon Sep 17 00:00:00 2001 From: lrljoe <104938042+lrljoe@users.noreply.github.com> Date: Fri, 31 Jan 2025 08:23:33 +0000 Subject: [PATCH 04/23] Fix styling --- src/Traits/Filters/HandlesPillsData.php | 18 ++++++------------ src/Traits/WithFilters.php | 2 +- .../Traits/IsLivewireComponentFilter.php | 1 - 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/Traits/Filters/HandlesPillsData.php b/src/Traits/Filters/HandlesPillsData.php index 2a7eccff1..abe0a6d02 100644 --- a/src/Traits/Filters/HandlesPillsData.php +++ b/src/Traits/Filters/HandlesPillsData.php @@ -8,20 +8,15 @@ public function getPillDataForFilter(): array { $filters = []; - foreach ($this->getAppliedFiltersWithValuesForPills() as $filterSelectName => $value) - { - if (!is_null($filterSelectName)) - { - if(!is_null($filter = $this->getFilterByKey($filterSelectName))) - { - if($filter->isEmpty($value)) - { + foreach ($this->getAppliedFiltersWithValuesForPills() as $filterSelectName => $value) { + if (! is_null($filterSelectName)) { + if (! is_null($filter = $this->getFilterByKey($filterSelectName))) { + if ($filter->isEmpty($value)) { continue; } $filterPillValue = $filter->getFilterPillValue($value); $filterPillTitle = $filter->getFilterPillTitle(); - $filters[$filter->getKey()] = [ 'filter' => $filter, 'isAnExternalLivewireFilter' => (method_exists($filter, 'isAnExternalLivewireFilter') && $filter->isAnExternalLivewireFilter()), @@ -32,10 +27,9 @@ public function getPillDataForFilter(): array ]; } } - + } return $filters; } - -} \ No newline at end of file +} diff --git a/src/Traits/WithFilters.php b/src/Traits/WithFilters.php index 7a509d695..ea8108784 100644 --- a/src/Traits/WithFilters.php +++ b/src/Traits/WithFilters.php @@ -4,7 +4,7 @@ use Illuminate\Support\Collection; use Livewire\Attributes\Locked; -use Rappasoft\LaravelLivewireTables\Traits\Filters\{HandlesLivewireComponentFilters, HasFilterGenericData, HandlesPillsData, HasFilterMenu, HasFilterPills, HasFilterQueryString, HasFiltersCore, HasFiltersStatus, HasFiltersVisibility}; +use Rappasoft\LaravelLivewireTables\Traits\Filters\{HandlesLivewireComponentFilters, HandlesPillsData, HasFilterGenericData, HasFilterMenu, HasFilterPills, HasFilterQueryString, HasFiltersCore, HasFiltersStatus, HasFiltersVisibility}; trait WithFilters { diff --git a/src/Views/Filters/Traits/IsLivewireComponentFilter.php b/src/Views/Filters/Traits/IsLivewireComponentFilter.php index c6360ad18..32dfd3919 100644 --- a/src/Views/Filters/Traits/IsLivewireComponentFilter.php +++ b/src/Views/Filters/Traits/IsLivewireComponentFilter.php @@ -8,7 +8,6 @@ trait IsLivewireComponentFilter { public string $livewireComponent = ''; - public function isAnExternalLivewireFilter(): bool { return true; From 2708eeb5b879610fbd15983c38fa0c285144a830 Mon Sep 17 00:00:00 2001 From: LRLJoe Date: Fri, 31 Jan 2025 08:39:10 +0000 Subject: [PATCH 05/23] Minor tweaks for return type --- src/External/Filters/LivewireArrayExternalFilter.php | 2 +- .../Filters/Traits/HandlesTableEventsForExternalFilter.php | 2 +- src/Views/Filters/Traits/IsExternalArrayFilter.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/External/Filters/LivewireArrayExternalFilter.php b/src/External/Filters/LivewireArrayExternalFilter.php index dd3c93d50..e070d8eb6 100644 --- a/src/External/Filters/LivewireArrayExternalFilter.php +++ b/src/External/Filters/LivewireArrayExternalFilter.php @@ -22,7 +22,7 @@ abstract class LivewireArrayExternalFilter extends Component public array $optionsSelected = []; #[Renderless] - public function updatedOptionsSelected($value) + public function updatedOptionsSelected(mixed $value): void { if (! $this->skipUpdate) { if (! $this->needsUpdating) { diff --git a/src/External/Filters/Traits/HandlesTableEventsForExternalFilter.php b/src/External/Filters/Traits/HandlesTableEventsForExternalFilter.php index 5afbdcbdb..8231523f9 100644 --- a/src/External/Filters/Traits/HandlesTableEventsForExternalFilter.php +++ b/src/External/Filters/Traits/HandlesTableEventsForExternalFilter.php @@ -15,7 +15,7 @@ public function setFilterValues(string $tableName, string $filterKey, string|arr } #[Renderless] - public function renderingHandlesTableEventsForExternalFilter() + public function renderingHandlesTableEventsForExternalFilter(\Illuminate\View\View $view, array $data = []): void { if ($this->needsUpdating) { $this->needsUpdating = false; diff --git a/src/Views/Filters/Traits/IsExternalArrayFilter.php b/src/Views/Filters/Traits/IsExternalArrayFilter.php index 1c09a2b62..412ac5552 100644 --- a/src/Views/Filters/Traits/IsExternalArrayFilter.php +++ b/src/Views/Filters/Traits/IsExternalArrayFilter.php @@ -59,7 +59,7 @@ protected function sendUpdateDispatch(array $returnValues): void } #[Renderless] - public function renderingIsExternalArrayFilter(): void + public function renderingIsExternalArrayFilter(\Illuminate\View\View $view, array $data = []): void { $returnValues = []; From 599cc33c7446369197cb2f2fa3e28f65311d6797 Mon Sep 17 00:00:00 2001 From: LRLJoe Date: Fri, 31 Jan 2025 09:15:11 +0000 Subject: [PATCH 06/23] Minor dochint fixes --- src/Traits/Filters/HandlesPillsData.php | 31 +++++++++++-------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/Traits/Filters/HandlesPillsData.php b/src/Traits/Filters/HandlesPillsData.php index abe0a6d02..b940e40be 100644 --- a/src/Traits/Filters/HandlesPillsData.php +++ b/src/Traits/Filters/HandlesPillsData.php @@ -9,25 +9,22 @@ public function getPillDataForFilter(): array $filters = []; foreach ($this->getAppliedFiltersWithValuesForPills() as $filterSelectName => $value) { - if (! is_null($filterSelectName)) { - if (! is_null($filter = $this->getFilterByKey($filterSelectName))) { - if ($filter->isEmpty($value)) { - continue; - } - $filterPillValue = $filter->getFilterPillValue($value); - $filterPillTitle = $filter->getFilterPillTitle(); - - $filters[$filter->getKey()] = [ - 'filter' => $filter, - 'isAnExternalLivewireFilter' => (method_exists($filter, 'isAnExternalLivewireFilter') && $filter->isAnExternalLivewireFilter()), - 'filterSelectName' => $filterSelectName, - 'filterPillTitle' => $filterPillTitle, - 'filterPillValue' => $filterPillValue, - 'separator' => method_exists($filter, 'getPillsSeparator') ? $filter->getPillsSeparator() : ', ', - ]; + if (! is_null($filter = $this->getFilterByKey($filterSelectName))) { + if ($filter->isEmpty($value)) { + continue; } - } + $filterPillValue = $filter->getFilterPillValue($value); + $filterPillTitle = $filter->getFilterPillTitle(); + $filters[$filter->getKey()] = [ + 'filter' => $filter, + 'isAnExternalLivewireFilter' => (method_exists($filter, 'isAnExternalLivewireFilter') && $filter->isAnExternalLivewireFilter()), + 'filterSelectName' => $filterSelectName, + 'filterPillTitle' => $filterPillTitle, + 'filterPillValue' => $filterPillValue, + 'separator' => method_exists($filter, 'getPillsSeparator') ? $filter->getPillsSeparator() : ', ', + ]; + } } return $filters; From f0931c35a3b7083d73bbd2317a74303d112e3338 Mon Sep 17 00:00:00 2001 From: LRLJoe Date: Sun, 2 Feb 2025 08:10:42 +0000 Subject: [PATCH 07/23] Migration to support Livewire Filter Array filter pills, docs updates, and reverting away from computed properties for the theme determination --- docs/column-types/array_column.md | 4 +- docs/column-types/avg_column.md | 2 +- docs/column-types/count_column.md | 2 +- .../column-types/livewire_component_column.md | 2 +- .../filters-livewire-component-array.md | 51 ++++ docs/filters/available-component-methods.md | 130 +------- docs/filters/available-filter-methods.md | 279 ++++++++---------- docs/filters/filter-pills.md | 268 +++++++++++++++++ docs/start/recommended.md | 2 +- resources/js/laravel-livewire-tables.js | 114 ++++++- resources/js/laravel-livewire-tables.min.js | 2 +- .../components/includes/actions.blade.php | 12 +- .../components/includes/loading.blade.php | 14 +- .../views/components/pagination.blade.php | 76 ++--- .../table/td/bulk-actions.blade.php | 11 +- .../components/table/td/reorder.blade.php | 10 +- resources/views/components/table/th.blade.php | 23 +- .../table/th/bulk-actions.blade.php | 11 +- .../table/th/collapsed-columns.blade.php | 17 +- .../views/components/table/th/plain.blade.php | 7 +- .../components/table/th/sort-icons.blade.php | 7 +- .../table/tr/bulk-actions.blade.php | 44 +-- resources/views/components/tools.blade.php | 7 +- .../components/tools/filter-label.blade.php | 12 +- .../components/tools/filter-pills.blade.php | 25 +- .../filter-pills/buttons/reset-all.blade.php | 22 +- .../buttons/reset-filter.blade.php | 21 +- .../filter-pills/external-item.blade.php | 34 +-- .../tools/filter-pills/item.blade.php | 29 +- .../tools/filter-pills/wrapper.blade.php | 20 ++ .../components/tools/sorting-pills.blade.php | 32 +- .../views/components/tools/toolbar.blade.php | 41 ++- .../toolbar/items/bulk-actions.blade.php | 38 +-- .../toolbar/items/column-select.blade.php | 12 +- .../toolbar/items/filter-button.blade.php | 26 +- .../filter-popover/clear-button.blade.php | 9 +- .../toolbar/items/filter-slidedown.blade.php | 28 +- .../items/pagination-dropdown.blade.php | 16 +- .../toolbar/items/reorder-buttons.blade.php | 20 +- resources/views/datatable.blade.php | 83 +++--- resources/views/includes/offline.blade.php | 10 +- .../Filters/FilterPillData.php | 100 +++++++ .../Core/Search/HandlesSearchStatus.php | 6 + src/Traits/Filters/HandlesPillsData.php | 21 +- src/Traits/Filters/HasFilterPills.php | 4 +- .../Helpers/FilterVisibilityHelpers.php | 7 + src/Traits/Helpers/ActionsHelpers.php | 14 + src/Traits/Helpers/ColumnSelectHelpers.php | 1 + src/Traits/Helpers/PaginationHelpers.php | 6 + src/Traits/Helpers/ReorderingHelpers.php | 7 + .../Styling/Helpers/ToolsStylingHelpers.php | 3 +- .../Filters/LivewireComponentArrayFilter.php | 9 +- src/Views/Filters/Traits/HasFilterPills.php | 4 + .../Styling/HandlesFilterPillsAttributes.php | 38 +++ .../FilterPillDataTest.php | 144 +++++++++ 55 files changed, 1254 insertions(+), 683 deletions(-) create mode 100644 docs/filter-types/filters-livewire-component-array.md create mode 100644 docs/filters/filter-pills.md create mode 100644 resources/views/components/tools/filter-pills/wrapper.blade.php create mode 100644 src/DataTransferObjects/Filters/FilterPillData.php create mode 100644 src/Views/Filters/Traits/Styling/HandlesFilterPillsAttributes.php create mode 100644 tests/Unit/DataTransferObjects/FilterPillDataTest.php diff --git a/docs/column-types/array_column.md b/docs/column-types/array_column.md index 7802e78aa..3d612248d 100644 --- a/docs/column-types/array_column.md +++ b/docs/column-types/array_column.md @@ -5,7 +5,7 @@ weight: 2 Array columns provide an easy way to work with and display an array of data from a field. -``` +```php ArrayColumn::make('notes', 'name') ->data(fn($value, $row) => ($row->notes)) ->outputFormat(fn($index, $value) => "".$value->name."") @@ -16,7 +16,7 @@ ArrayColumn::make('notes', 'name') ### Empty Value You may define the default/empty value using the "emptyValue" method -``` +```php ArrayColumn::make('notes', 'name') ->emptyValue('Unknown'), ``` diff --git a/docs/column-types/avg_column.md b/docs/column-types/avg_column.md index d5e4b32fb..f0f7680ac 100644 --- a/docs/column-types/avg_column.md +++ b/docs/column-types/avg_column.md @@ -5,7 +5,7 @@ weight: 3 Avg columns provide an easy way to display the "Average" of a field on a relation. -``` +```php AvgColumn::make('Average Related User Age') ->setDataSource('users','age') ->sortable(), diff --git a/docs/column-types/count_column.md b/docs/column-types/count_column.md index 4b1fe6c3a..beb7d3437 100644 --- a/docs/column-types/count_column.md +++ b/docs/column-types/count_column.md @@ -5,7 +5,7 @@ weight: 8 Count columns provide an easy way to display the "Count" of a relation. -``` +```php CountColumn::make('Related Users') ->setDataSource('users') ->sortable(), diff --git a/docs/column-types/livewire_component_column.md b/docs/column-types/livewire_component_column.md index ebeb72724..f48859641 100644 --- a/docs/column-types/livewire_component_column.md +++ b/docs/column-types/livewire_component_column.md @@ -8,7 +8,7 @@ Livewire Component Columns allow for the use of a Livewire Component as a Column This is **not recommended** as due to the nature of Livewire, it becomes inefficient at scale. ## component -``` +```php LivewireComponentColumn::make('Action') ->component('PathToLivewireComponent'), diff --git a/docs/filter-types/filters-livewire-component-array.md b/docs/filter-types/filters-livewire-component-array.md new file mode 100644 index 000000000..86b2491dc --- /dev/null +++ b/docs/filter-types/filters-livewire-component-array.md @@ -0,0 +1,51 @@ +--- +title: Livewire Custom Array Filter (Beta) +weight: 13 +--- + +**IN BETA** +This feature is currently in beta, and use in production is not recommended. + +### Usage +This allows you to use a child/nested Livewire Component in place of the existing Filters, giving you more control over the look/feel/behaviour of a filter. This version supports use of returning an array of values for use in filtering. + +To use a LivewireComponentArrayFilter, you must include it in your namespace: +```php +use Rappasoft\LaravelLivewireTables\Views\Filters\LivewireComponentArrayFilter; +``` + +When creating a filter: +- Specify a unique name +- Set the path to a valid Livewire Component +- Define a filter() callback to define how the returned value will be used. + +```php + public function filters(): array + { + return [ + LivewireComponentArrayFilter::make('My External Filter') + ->setLivewireComponent('my-test-external-filter') + ->filter(function (Builder $builder, array $values) { + $builder->whereIn('foreign_id', $values); + }), + ]; + } +``` + +### setPillsSeparator +As this is an array, you can define the separator to use between pills values, by default this is set to ", " + +```php + public function filters(): array + { + return [ + LivewireComponentArrayFilter::make('My External Filter') + ->setLivewireComponent('my-test-external-filter') + ->setPillsSeparator(' OR ') + ->filter(function (Builder $builder, array $values) { + $builder->whereIn('foreign_id', $values); + }), + ]; + } +``` + diff --git a/docs/filters/available-component-methods.md b/docs/filters/available-component-methods.md index bf3c51c43..ffa02f29c 100644 --- a/docs/filters/available-component-methods.md +++ b/docs/filters/available-component-methods.md @@ -85,135 +85,9 @@ public function configure(): void --- -## setFilterPillsStatus +## Pills -**Enabled by default**, show/hide the filter pills. - -```php -public function configure(): void -{ - $this->setFilterPillsStatus(true); - $this->setFilterPillsStatus(false); -} -``` - -## setFilterPillsEnabled - -Show the filter pills for the component. - -```php -public function configure(): void -{ - // Shorthand for $this->setFilterPillsStatus(true) - $this->setFilterPillsEnabled(); -} -``` - -## setFilterPillsDisabled - -Hide the filter pills for the component. - -```php -public function configure(): void -{ - // Shorthand for $this->setFilterPillsStatus(false) - $this->setFilterPillsDisabled(); -} -``` - -## setFilterPillsItemAttributes -Allows for customisation of the appearance of the "Filter Pills Item" - -Note that this utilises a refreshed approach for attributes, and allows for appending to, or replacing the styles and colors independently, via the below methods. - -#### default-colors -Setting to false will disable the default colors for the Filter Pills Item, the default colors are: - -Bootstrap: None - -Tailwind: `bg-indigo-100 text-indigo-800 dark:bg-indigo-200 dark:text-indigo-900` - -#### default-styling -Setting to false will disable the default styling for the Filter Pills Item, the default styling is: - -Bootstrap 4: `badge badge-pill badge-info d-inline-flex align-items-center` - -Bootstrap 5: `badge rounded-pill bg-info d-inline-flex align-items-center` - -Tailwind: `inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium leading-4 capitalize` - -```php -public function configure(): void -{ - $this->setFilterPillsItemAttributes([ - 'class' => 'bg-rose-300 text-rose-800 dark:bg-indigo-200 dark:text-indigo-900', // Add these classes to the filter pills item - 'default-colors' => false, // Do not output the default colors - 'default-styling' => true // Output the default styling - ]); -} -``` - -## setFilterPillsResetFilterButtonAttributes -Allows for customisation of the appearance of the "Filter Pills Reset Filter Button" - -Note that this utilises a refreshed approach for attributes, and allows for appending to, or replacing the styles and colors independently, via the below methods. - -#### default-colors -Setting to false will disable the default colors for the Filter Pills Reset Filter Button, the default colors are: - -Bootstrap: None - -Tailwind: `text-indigo-400 hover:bg-indigo-200 hover:text-indigo-500 focus:bg-indigo-500 focus:text-white` - -#### default-styling -Setting to false will disable the default styling for the Filter Pills Reset Filter Button, the default styling is: - -Bootstrap: `text-white ml-2` - -Tailwind: `flex-shrink-0 ml-0.5 h-4 w-4 rounded-full inline-flex items-center justify-center focus:outline-none` - -```php -public function configure(): void -{ - $this->setFilterPillsResetFilterButtonAttributes([ - 'class' => 'text-rose-400 hover:bg-rose-200 hover:text-rose-500 focus:bg-rose-500', // Add these classes to the filter pills reset filter button - 'default-colors' => false, // Do not output the default colors - 'default-styling' => true // Output the default styling - ]); -} -``` - -## setFilterPillsResetAllButtonAttributes -Allows for customisation of the appearance of the "Filter Pills Reset All Button" - -Note that this utilises a refreshed approach for attributes, and allows for appending to, or replacing the styles and colors independently, via the below methods. - -#### default-colors -Setting to false will disable the default colors for the Filter Pills Reset All Button, the default colors are: - -Bootstrap: None - -Tailwind: `bg-gray-100 text-gray-800 dark:bg-gray-200 dark:text-gray-900` - -#### default-styling -Setting to false will disable the default styling for the Filter Pills Reset All Button, the default styling is: - -Bootstrap 4: `badge badge-pill badge-light` - -Bootstrap 5: `badge rounded-pill bg-light text-dark text-decoration-none` - -Tailwind: `inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium` - -```php -public function configure(): void -{ - $this->setFilterPillsResetAllButtonAttributes([ - 'class' => 'bg-rose-100 text-rose-800 dark:bg-gray-200 dark:text-gray-900', // Add these classes to the filter pills reset all button - 'default-colors' => false, // Do not output the default colors - 'default-styling' => true // Output the default styling - ]); -} -``` +See the [Filter Pills](./filter-pills) documentation for help with configuring the pills --- diff --git a/docs/filters/available-filter-methods.md b/docs/filters/available-filter-methods.md index 9597372d4..249273109 100644 --- a/docs/filters/available-filter-methods.md +++ b/docs/filters/available-filter-methods.md @@ -5,36 +5,10 @@ weight: 6 The following methods are available on the filter object. These are "filter-specific" methods. ----- +Ensure you check out: +- [Available Component Methods](./available-component-methods) documentation for Table Wide configuration +- [Filter Pills](./filter-pills) documentation for help with configuring the pills for a filter -## setFilterPillTitle - -By default, the filter pill title is the filter name, but you can make it whatever you want: - -```php -SelectFilter::make('Active') - ->setFilterPillTitle('User Status') -``` - -## setFilterPillValues - -If you have numeric, or generated keys as your filter option values, they probably don't look too nice in the filter pill. You can set the values to be displayed in the filter pill: - -```php -SelectFilter::make('Active') - ->setFilterPillTitle('User Status') - ->setFilterPillValues([ - '1' => 'Active', - '0' => 'Inactive', - ]) - ->options([ - '' => 'All', - '1' => 'Yes', - '0' => 'No', - ]) -``` - -Now instead of `Active: Yes` it will say `User Status: Active` ## hiddenFromMenus @@ -80,8 +54,96 @@ By default the `clear` button will reset all filters to their defaults. You can SelectFilter::make('Active') ->notResetByClearButton() ``` - -## setFilterSlidedownRow + +## setCustomView +Use a fully custom view for a filter. This will utilise solely your view when rendering this filter. Note that the following methods will no longer apply to a filter using this: +- setCustomFilterLabel +- setFilterLabelAttributes + +```php +TextFilter::make('Name') + ->setCustomView('text-custom-view'), +``` + +## Config + +If the filter takes any config options, you can set them with the `config` method: + +```php + DateFilter::make('Date') + ->config([ + 'min' => '2020-01-01', + 'max' => '2021-12-31', + ]) +``` + +## Customising Wireable Behaviour + +For the following Filters, you may customise how the input is wire:model into the Table Component: + +- DateFilter (Defaults to Live) +- DateTimeFilter (Defaults to Live) +- MultiSelectDropdownFilter (Defaults to live.debounce.250ms) +- MultiSelectFilter (Defaults to live.debounce.250ms) +- NumberFilter (Defaults to Blur) +- SelectFilter (Defaults to Live) +- TextFilter (Defaults to Blur) + +You may override this using the following methods, on any of the above Filter types: + +### setWireBlur() +Forces the filter to use a wire:model.blur approach +```php + TextFilter::make('Name') + ->config([ + 'placeholder' => 'Search Name', + 'maxlength' => '25', + ]) + ->setWireBlur() +``` + +### setWireDefer() +Forces the filter to use a wire:model approach +```php + TextFilter::make('Name') + ->config([ + 'placeholder' => 'Search Name', + 'maxlength' => '25', + ]) + ->setWireDefer() +``` + +### setWireLive() +Forces the fitler to use a wire:model.live approach +```php + TextFilter::make('Name') + ->config([ + 'placeholder' => 'Search Name', + 'maxlength' => '25', + ]) + ->setWireLive() +``` + +### setWireDebounce(int $debounceDelay) +Allows you to pass a string to use a wire:model.live.debounce.Xms approach +```php + TextFilter::make('Name') + ->config([ + 'placeholder' => 'Search Name', + 'maxlength' => '25', + ]) + ->setWireDebounce(50) +``` + +--- + +## Styling + +These methods allow you to over-ride default styling for individual Filters + +--- + +### setFilterSlidedownRow This method applies only when using the Slide Down approach to filter display. By default the filters will be displayed in the order that they are listed in the filters() method. This method allows you to specify the row that the filter will be listed. When multiple filters are placed on the same row, and a mobile device is used, then the first filter listed will "win" that row. @@ -92,7 +154,7 @@ SelectFilter::make('Active') ->setFilterSlidedownRow(1) ``` -## setFilterSlidedownColspan +### setFilterSlidedownColspan This method applies only when using the Slide Down approach to filter display. By default each filter will take up one column, with the number of columns determined by the size of the screen, this ranges from 1 on a mobile device, to a maximum of 5 on a large display. This method allows you to specify the number of columns that the filter should span. It will span the number of columns specified, up to the number of columns available (depending on screen size). @@ -107,37 +169,9 @@ DateFilter::make('Date') ->setFilterSlidedownColspan('2') ``` -## setFilterPillBlade - -Set a blade file for use in displaying the filter values in the pills area. You can use this in conjunction with setFilterPillValues() to prettify your applied filter values display. You will receive two properties ($filter) containing the filter instance, and ($value) containing the filter value. - -```php -SelectFilter::make('Active') - ->setFilterPillBlade('path.to.blade') -``` - -Example blade: -```php -@aware(['component']) -@props(['filter']) - - - {{ $filter->getFilterPillTitle() }} - ({{ $filter->getFilterPillValue($value) }}) - - - -``` +--- -## setCustomFilterLabel +### setCustomFilterLabel Set a custom blade file for the filter's label. This will be used in both the Pop-Over and SlideDown filter displays, you should therefore ensure that you cater for the different filter layouts. @@ -158,27 +192,27 @@ You will receive several properties to your blade, explained here: Example label blade: ```php -@props(['filter', 'filterLayout' => 'popover', 'tableName' => 'table', 'isTailwind' => false, 'isBootstrap' => false, 'isBootstrap4' => false, 'isBootstrap5' => false, 'customLabelAttributes' => []]) - - -