fix: Improve Filament component behavior, update dependencies, and adjust styling.

This commit is contained in:
Yoga Pangestu 2026-01-05 09:29:57 +07:00
parent f97531e355
commit 3760eeb00d
21 changed files with 573 additions and 2066 deletions

View File

@ -4,10 +4,10 @@
use App\Enums\DecisionAdmin; use App\Enums\DecisionAdmin;
use App\Enums\VerificationStatus; use App\Enums\VerificationStatus;
use App\Filament\Resources\Manage\Journalists\Pages\ManageJournalists;
use App\Filament\Resources\Manage\Partners\Pages\ViewPartner;
use App\Models\VerificationRequest; use App\Models\VerificationRequest;
use App\Models\VerificationReview; use App\Models\VerificationReview;
use App\Filament\Resources\Manage\Partners\Pages\ViewPartner;
use App\Filament\Resources\Manage\Journalists\Pages\ManageJournalists;
use BackedEnum; use BackedEnum;
use Filament\Actions\Action; use Filament\Actions\Action;
use Filament\Actions\Concerns\InteractsWithActions; use Filament\Actions\Concerns\InteractsWithActions;

View File

@ -4,13 +4,11 @@
use App\Enums\DecisionAdmin; use App\Enums\DecisionAdmin;
use App\Enums\VerificationStatus; use App\Enums\VerificationStatus;
use App\Filament\Resources\Manage\Journalists\Pages\ManageJournalists;
use App\Models\Company; use App\Models\Company;
use App\Models\Journalist; use App\Models\Journalist;
use App\Models\PartnerMedia; use App\Models\PartnerMedia;
use App\Models\VerificationRequest; use App\Models\VerificationRequest;
use App\Filament\Pages\CustomCompany;
use App\Filament\Pages\CustomMedia;
use App\Filament\Resources\Manage\Journalists\Pages\ManageJournalists;
use BackedEnum; use BackedEnum;
use BezhanSalleh\FilamentShield\Traits\HasPageShield; use BezhanSalleh\FilamentShield\Traits\HasPageShield;
use Filament\Actions\Action; use Filament\Actions\Action;
@ -323,14 +321,14 @@ public function journalistProgress(): array
public function submitCompanyAction(): Action public function submitCompanyAction(): Action
{ {
return Action::make('submitCompany') return Action::make('submitCompany')
->label(fn() => $this->needsRevision($this->companyVerification) ? 'Kirim Ulang' : 'Ajukan Verifikasi') ->label(fn () => $this->needsRevision($this->companyVerification) ? 'Kirim Ulang' : 'Ajukan Verifikasi')
->icon('heroicon-o-paper-airplane') ->icon('heroicon-o-paper-airplane')
->color('primary') ->color('primary')
->requiresConfirmation() ->requiresConfirmation()
->modalHeading('Ajukan Verifikasi Perusahaan') ->modalHeading('Ajukan Verifikasi Perusahaan')
->modalDescription('Apakah Anda yakin ingin mengajukan data perusahaan untuk diverifikasi? Pastikan semua data sudah benar.') ->modalDescription('Apakah Anda yakin ingin mengajukan data perusahaan untuk diverifikasi? Pastikan semua data sudah benar.')
->modalSubmitActionLabel('Ya, Ajukan') ->modalSubmitActionLabel('Ya, Ajukan')
->visible(fn() => $this->canSubmit($this->company, $this->companyVerification)) ->visible(fn () => $this->canSubmit($this->company, $this->companyVerification))
->action(function () { ->action(function () {
$this->submitVerification('company', $this->company, $this->companyVerification); $this->submitVerification('company', $this->company, $this->companyVerification);
}); });
@ -342,14 +340,14 @@ public function submitCompanyAction(): Action
public function submitMediaAction(): Action public function submitMediaAction(): Action
{ {
return Action::make('submitMedia') return Action::make('submitMedia')
->label(fn() => $this->needsRevision($this->mediaVerification) ? 'Kirim Ulang' : 'Ajukan Verifikasi') ->label(fn () => $this->needsRevision($this->mediaVerification) ? 'Kirim Ulang' : 'Ajukan Verifikasi')
->icon('heroicon-o-paper-airplane') ->icon('heroicon-o-paper-airplane')
->color('primary') ->color('primary')
->requiresConfirmation() ->requiresConfirmation()
->modalHeading('Ajukan Verifikasi Media') ->modalHeading('Ajukan Verifikasi Media')
->modalDescription('Apakah Anda yakin ingin mengajukan data media untuk diverifikasi? Pastikan semua data sudah benar.') ->modalDescription('Apakah Anda yakin ingin mengajukan data media untuk diverifikasi? Pastikan semua data sudah benar.')
->modalSubmitActionLabel('Ya, Ajukan') ->modalSubmitActionLabel('Ya, Ajukan')
->visible(fn() => $this->canSubmit($this->partnerMedia, $this->mediaVerification)) ->visible(fn () => $this->canSubmit($this->partnerMedia, $this->mediaVerification))
->action(function () { ->action(function () {
$this->submitVerification('media', $this->partnerMedia, $this->mediaVerification); $this->submitVerification('media', $this->partnerMedia, $this->mediaVerification);
}); });
@ -361,14 +359,14 @@ public function submitMediaAction(): Action
public function submitJournalistAction(): Action public function submitJournalistAction(): Action
{ {
return Action::make('submitJournalist') return Action::make('submitJournalist')
->label(fn() => $this->needsRevision($this->journalistVerification) ? 'Kirim Ulang' : 'Ajukan Verifikasi') ->label(fn () => $this->needsRevision($this->journalistVerification) ? 'Kirim Ulang' : 'Ajukan Verifikasi')
->icon('heroicon-o-paper-airplane') ->icon('heroicon-o-paper-airplane')
->color('primary') ->color('primary')
->requiresConfirmation() ->requiresConfirmation()
->modalHeading('Ajukan Verifikasi Jurnalis') ->modalHeading('Ajukan Verifikasi Jurnalis')
->modalDescription('Apakah Anda yakin ingin mengajukan data jurnalis untuk diverifikasi? Pastikan semua data sudah benar.') ->modalDescription('Apakah Anda yakin ingin mengajukan data jurnalis untuk diverifikasi? Pastikan semua data sudah benar.')
->modalSubmitActionLabel('Ya, Ajukan') ->modalSubmitActionLabel('Ya, Ajukan')
->visible(fn() => $this->canSubmit($this->journalist, $this->journalistVerification)) ->visible(fn () => $this->canSubmit($this->journalist, $this->journalistVerification))
->action(function () { ->action(function () {
$this->submitVerification('journalist', $this->journalist, $this->journalistVerification); $this->submitVerification('journalist', $this->journalist, $this->journalistVerification);
}); });

View File

@ -3,8 +3,8 @@
namespace App\Filament\Resources\Manage\Journalists; namespace App\Filament\Resources\Manage\Journalists;
use App\Filament\Columns\TimestampColumns; use App\Filament\Columns\TimestampColumns;
use App\Filament\Resources\Manage\Journalists\Pages\ManageJournalists;
use App\Filament\Pages\CustomMedia; use App\Filament\Pages\CustomMedia;
use App\Filament\Resources\Manage\Journalists\Pages\ManageJournalists;
use App\Models\Journalist; use App\Models\Journalist;
use Asmit\FilamentUpload\Forms\Components\AdvancedFileUpload; use Asmit\FilamentUpload\Forms\Components\AdvancedFileUpload;
use BackedEnum; use BackedEnum;
@ -106,7 +106,7 @@ public static function form(Schema $schema): Schema
->schema( ->schema(
collect($documents) collect($documents)
->map( ->map(
fn($doc) => Section::make($doc['title']) fn ($doc) => Section::make($doc['title'])
->schema([ ->schema([
TextInput::make($doc['text_name']) TextInput::make($doc['text_name'])
->hiddenLabel() ->hiddenLabel()

View File

@ -34,7 +34,7 @@ protected function mutateFormDataBeforeCreate(array $data): array
$newNumber = str_pad($lastNumber + 1, 6, '0', STR_PAD_LEFT); $newNumber = str_pad($lastNumber + 1, 6, '0', STR_PAD_LEFT);
$data['code'] = 'ADN' . $newNumber; $data['code'] = 'ADN'.$newNumber;
return $data; return $data;
} }

View File

@ -6,8 +6,8 @@
return Application::configure(basePath: dirname(__DIR__)) return Application::configure(basePath: dirname(__DIR__))
->withRouting( ->withRouting(
web: __DIR__ . '/../routes/web.php', web: __DIR__.'/../routes/web.php',
commands: __DIR__ . '/../routes/console.php', commands: __DIR__.'/../routes/console.php',
health: '/up', health: '/up',
) )
->withMiddleware(function (Middleware $middleware): void { ->withMiddleware(function (Middleware $middleware): void {

View File

@ -17,6 +17,7 @@
"joaopaulolndev/filament-pdf-viewer": "^2.0", "joaopaulolndev/filament-pdf-viewer": "^2.0",
"laravel/framework": "^12.0", "laravel/framework": "^12.0",
"laravel/tinker": "^2.10.1", "laravel/tinker": "^2.10.1",
"livewire/livewire": "^3.7",
"spatie/laravel-sluggable": "^3.7", "spatie/laravel-sluggable": "^3.7",
"spatie/laravel-tags": "^4.10", "spatie/laravel-tags": "^4.10",
"swisnl/filament-backgrounds": "^2.0" "swisnl/filament-backgrounds": "^2.0"
@ -95,4 +96,4 @@
}, },
"minimum-stability": "stable", "minimum-stability": "stable",
"prefer-stable": true "prefer-stable": true
} }

868
composer.lock generated

File diff suppressed because it is too large Load Diff

1556
package-lock.json generated

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
function c({livewireId:s}){return{areAllCheckboxesChecked:!1,checkboxListOptions:[],search:"",visibleCheckboxListOptions:[],init(){this.checkboxListOptions=Array.from(this.$root.querySelectorAll(".fi-fo-checkbox-list-option")),this.updateVisibleCheckboxListOptions(),this.$nextTick(()=>{this.checkIfAllCheckboxesAreChecked()}),Livewire.hook("commit",({component:e,commit:t,succeed:i,fail:o,respond:h})=>{i(({snapshot:r,effect:l})=>{this.$nextTick(()=>{e.id===s&&(this.checkboxListOptions=Array.from(this.$root.querySelectorAll(".fi-fo-checkbox-list-option")),this.updateVisibleCheckboxListOptions(),this.checkIfAllCheckboxesAreChecked())})})}),this.$watch("search",()=>{this.updateVisibleCheckboxListOptions(),this.checkIfAllCheckboxesAreChecked()})},checkIfAllCheckboxesAreChecked(){this.areAllCheckboxesChecked=this.visibleCheckboxListOptions.length===this.visibleCheckboxListOptions.filter(e=>e.querySelector("input[type=checkbox]:checked, input[type=checkbox]:disabled")).length},toggleAllCheckboxes(){this.checkIfAllCheckboxesAreChecked();let e=!this.areAllCheckboxesChecked;this.visibleCheckboxListOptions.forEach(t=>{let i=t.querySelector("input[type=checkbox]");i.disabled||(i.checked=e,i.dispatchEvent(new Event("change")))}),this.areAllCheckboxesChecked=e},updateVisibleCheckboxListOptions(){this.visibleCheckboxListOptions=this.checkboxListOptions.filter(e=>["",null,void 0].includes(this.search)||e.querySelector(".fi-fo-checkbox-list-option-label")?.innerText.toLowerCase().includes(this.search.toLowerCase())?!0:e.querySelector(".fi-fo-checkbox-list-option-description")?.innerText.toLowerCase().includes(this.search.toLowerCase()))}}}export{c as default}; function c({livewireId:s}){return{areAllCheckboxesChecked:!1,checkboxListOptions:[],search:"",visibleCheckboxListOptions:[],init(){this.checkboxListOptions=Array.from(this.$root.querySelectorAll(".fi-fo-checkbox-list-option")),this.updateVisibleCheckboxListOptions(),this.$nextTick(()=>{this.checkIfAllCheckboxesAreChecked()}),Livewire.hook("commit",({component:e,commit:t,succeed:i,fail:o,respond:h})=>{i(({snapshot:r,effect:l})=>{this.$nextTick(()=>{e.id===s&&(this.checkboxListOptions=Array.from(this.$root.querySelectorAll(".fi-fo-checkbox-list-option")),this.updateVisibleCheckboxListOptions(),this.checkIfAllCheckboxesAreChecked())})})}),this.$watch("search",()=>{this.updateVisibleCheckboxListOptions(),this.checkIfAllCheckboxesAreChecked()})},checkIfAllCheckboxesAreChecked(){this.areAllCheckboxesChecked=this.visibleCheckboxListOptions.length===this.visibleCheckboxListOptions.filter(e=>e.querySelector("input[type=checkbox]:checked, input[type=checkbox]:disabled")).length},toggleAllCheckboxes(){this.checkIfAllCheckboxesAreChecked();let e=!this.areAllCheckboxesChecked;this.visibleCheckboxListOptions.forEach(t=>{let i=t.querySelector("input[type=checkbox]");i.disabled||i.checked!==e&&(i.checked=e,i.dispatchEvent(new Event("change")))}),this.areAllCheckboxesChecked=e},updateVisibleCheckboxListOptions(){this.visibleCheckboxListOptions=this.checkboxListOptions.filter(e=>["",null,void 0].includes(this.search)||e.querySelector(".fi-fo-checkbox-list-option-label")?.innerText.toLowerCase().includes(this.search.toLowerCase())?!0:e.querySelector(".fi-fo-checkbox-list-option-description")?.innerText.toLowerCase().includes(this.search.toLowerCase()))}}}export{c as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
function r({initialHeight:t,shouldAutosize:i,state:s}){return{state:s,wrapperEl:null,init(){this.wrapperEl=this.$el.parentNode,this.setInitialHeight(),i?this.$watch("state",()=>{this.resize()}):this.setUpResizeObserver()},setInitialHeight(){this.$el.scrollHeight<=0||(this.wrapperEl.style.height=t+"rem")},resize(){if(this.setInitialHeight(),this.$el.scrollHeight<=0)return;let e=this.$el.scrollHeight+"px";this.wrapperEl.style.height!==e&&(this.wrapperEl.style.height=e)},setUpResizeObserver(){new ResizeObserver(()=>{this.wrapperEl.style.height=this.$el.style.height}).observe(this.$el)}}}export{r as default}; function r({initialHeight:i,shouldAutosize:s,state:h}){return{state:h,wrapperEl:null,init(){this.wrapperEl=this.$el.parentNode,this.setInitialHeight(),s?this.$watch("state",()=>{this.resize()}):this.setUpResizeObserver()},setInitialHeight(){this.$el.scrollHeight<=0||(this.wrapperEl.style.height=i+"rem")},resize(){if(this.$el.scrollHeight<=0)return;let e=this.$el.style.height;this.$el.style.height="0px";let t=this.$el.scrollHeight+"px";this.$el.style.height=e,this.wrapperEl.style.height!==t&&(this.wrapperEl.style.height=t)},setUpResizeObserver(){new ResizeObserver(()=>{this.wrapperEl.style.height=this.$el.style.height}).observe(this.$el)}}}export{r as default};

View File

@ -1 +1 @@
function u({activeTab:a,isTabPersistedInQueryString:e,livewireId:h,tab:o,tabQueryStringKey:s}){return{tab:o,init(){let t=this.getTabs(),i=new URLSearchParams(window.location.search);e&&i.has(s)&&t.includes(i.get(s))&&(this.tab=i.get(s)),this.$watch("tab",()=>this.updateQueryString()),(!this.tab||!t.includes(this.tab))&&(this.tab=t[a-1]),Livewire.hook("commit",({component:r,commit:f,succeed:c,fail:l,respond:b})=>{c(({snapshot:d,effect:m})=>{this.$nextTick(()=>{if(r.id!==h)return;let n=this.getTabs();n.includes(this.tab)||(this.tab=n[a-1]??this.tab)})})})},getTabs(){return this.$refs.tabsData?JSON.parse(this.$refs.tabsData.value):[]},updateQueryString(){if(!e)return;let t=new URL(window.location.href);t.searchParams.set(s,this.tab),history.replaceState(null,document.title,t.toString())}}}export{u as default}; function I({activeTab:w,isScrollable:f,isTabPersistedInQueryString:m,livewireId:g,tab:T,tabQueryStringKey:c}){return{boundResizeHandler:null,isScrollable:f,resizeDebounceTimer:null,tab:T,withinDropdownIndex:null,withinDropdownMounted:!1,init(){let t=this.getTabs(),e=new URLSearchParams(window.location.search);m&&e.has(c)&&t.includes(e.get(c))&&(this.tab=e.get(c)),this.$watch("tab",()=>this.updateQueryString()),(!this.tab||!t.includes(this.tab))&&(this.tab=t[w-1]),Livewire.hook("commit",({component:n,commit:d,succeed:r,fail:h,respond:u})=>{r(({snapshot:p,effect:i})=>{this.$nextTick(()=>{if(n.id!==g)return;let s=this.getTabs();s.includes(this.tab)||(this.tab=s[w-1]??this.tab)})})}),f||(this.boundResizeHandler=this.debouncedUpdateTabsWithinDropdown.bind(this),window.addEventListener("resize",this.boundResizeHandler),this.updateTabsWithinDropdown())},calculateAvailableWidth(t){let e=window.getComputedStyle(t);return Math.floor(t.clientWidth)-Math.ceil(parseFloat(e.paddingLeft))*2},calculateContainerGap(t){let e=window.getComputedStyle(t);return Math.ceil(parseFloat(e.columnGap))},calculateDropdownIconWidth(t){let e=t.querySelector(".fi-icon");return Math.ceil(e.clientWidth)},calculateTabItemGap(t){let e=window.getComputedStyle(t);return Math.ceil(parseFloat(e.columnGap)||8)},calculateTabItemPadding(t){let e=window.getComputedStyle(t);return Math.ceil(parseFloat(e.paddingLeft))+Math.ceil(parseFloat(e.paddingRight))},findOverflowIndex(t,e,n,d,r,h){let u=t.map(i=>Math.ceil(i.clientWidth)),p=t.map(i=>{let s=i.querySelector(".fi-tabs-item-label"),a=i.querySelector(".fi-badge"),o=Math.ceil(s.clientWidth),l=a?Math.ceil(a.clientWidth):0;return{label:o,badge:l,total:o+(l>0?d+l:0)}});for(let i=0;i<t.length;i++){let s=u.slice(0,i+1).reduce((b,y)=>b+y,0),a=i*n,o=p.slice(i+1),l=o.length>0,W=l?Math.max(...o.map(b=>b.total)):0,D=l?r+W+d+h+n:0;if(s+a+D>e)return i}return-1},get isDropdownButtonVisible(){return this.withinDropdownMounted?this.withinDropdownIndex===null?!1:this.getTabs().findIndex(e=>e===this.tab)<this.withinDropdownIndex:!0},getTabs(){return this.$refs.tabsData?JSON.parse(this.$refs.tabsData.value):[]},updateQueryString(){if(!m)return;let t=new URL(window.location.href);t.searchParams.set(c,this.tab),history.replaceState(null,document.title,t.toString())},debouncedUpdateTabsWithinDropdown(){clearTimeout(this.resizeDebounceTimer),this.resizeDebounceTimer=setTimeout(()=>this.updateTabsWithinDropdown(),150)},async updateTabsWithinDropdown(){this.withinDropdownIndex=null,this.withinDropdownMounted=!1,await this.$nextTick();let t=this.$el.querySelector(".fi-tabs"),e=t.querySelector(".fi-tabs-item:last-child"),n=Array.from(t.children).slice(0,-1),d=n.map(a=>a.style.display);n.forEach(a=>a.style.display=""),t.offsetHeight;let r=this.calculateAvailableWidth(t),h=this.calculateContainerGap(t),u=this.calculateDropdownIconWidth(e),p=this.calculateTabItemGap(n[0]),i=this.calculateTabItemPadding(n[0]),s=this.findOverflowIndex(n,r,h,p,i,u);n.forEach((a,o)=>a.style.display=d[o]),s!==-1&&(this.withinDropdownIndex=s),this.withinDropdownMounted=!0},destroy(){this.boundResizeHandler&&window.removeEventListener("resize",this.boundResizeHandler),clearTimeout(this.resizeDebounceTimer)}}}export{I as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long