refactor(datatable): Standardize Livewire datatable component paths and fix select query

This commit is contained in:
Yoga Pangestu 2025-12-11 19:12:28 +07:00
parent a855fae353
commit 784e50c00d
37 changed files with 56 additions and 169 deletions

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Datatable\Studio\Catalog;
namespace App\Livewire\Datatable\Catalog;
use App\Models\Bottle;
use App\Models\PriceRequest;

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Datatable\Studio\Catalog;
namespace App\Livewire\Datatable\Catalog;
use App\Models\Brand;
use App\Traits\Datatable\WithConfiguration;

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Datatable\Studio\Catalog;
namespace App\Livewire\Datatable\Catalog;
use App\Models\Category;
use App\Traits\Datatable\WithConfiguration;

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Datatable\Studio\Catalog;
namespace App\Livewire\Datatable\Catalog;
use App\Models\Perfume;
use App\Models\PriceRequest;
@ -146,10 +146,7 @@ public function builder(): Builder
'perfumes.name',
'concentration',
'cost_price',
'sale_price',
'base_notes',
'middle_notes',
'top_notes'
'sale_price'
)
->with([
'categories',

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Datatable\Studio\Catalog;
namespace App\Livewire\Datatable\Catalog;
use App\Models\PriceRequest;
use App\Models\Product;

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Datatable\Studio\Feature;
namespace App\Livewire\Datatable\Feature;
use App\Models\ChooseUs;
use App\Traits\Datatable\WithConfiguration;

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Datatable\Studio\Feature;
namespace App\Livewire\Datatable\Feature;
use App\Models\PerfumeFeature;
use App\Traits\Datatable\WithConfiguration;

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Datatable\Studio\Finance;
namespace App\Livewire\Datatable\Finance;
use App\Models\Expense;
use App\Traits\Datatable\WithAppendColumn;
@ -64,7 +64,7 @@ public function columns(): array
public function builder(): Builder
{
return Expense::select('expenses.*')
return Expense::select('expenses.id', 'expenses.user_id', 'expenses.outlet_id', 'expenses.description', 'expenses.amount', 'expenses.created_at')
->whereIn('outlet_id', auth()->user()->outlets->pluck('id')->toArray())
->with(['outlet', 'user', 'user.employee']);
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Datatable\Studio\Finance;
namespace App\Livewire\Datatable\Finance;
use App\Enums\SalaryAdjustmentType;
use App\Models\Payroll;
@ -92,7 +92,18 @@ public function columns(): array
public function builder(): Builder
{
return Payroll::select('payrolls.*')
return Payroll::select(
'payrolls.id',
'payrolls.user_id',
'period_month',
'base_salary',
'bonus',
'deduction',
'total_salary',
'is_paid',
'paid_at',
'payrolls.created_at'
)
->where('period_month', '!=', now()->format('Y-m'))
->with(['user', 'user.employee']);
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Datatable\Studio\Information;
namespace App\Livewire\Datatable\Information;
use App\Models\Broadcast;
use App\Traits\Datatable\WithAppendColumn;

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Datatable\Studio\Information;
namespace App\Livewire\Datatable\Information;
use App\Models\Faq;
use App\Traits\Datatable\WithConfiguration;

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Datatable\Studio\Information;
namespace App\Livewire\Datatable\Information;
use App\Enums\PriceRequestStatus;
use App\Models\PriceRequest;

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Datatable\Studio\Loyalty;
namespace App\Livewire\Datatable\Loyalty;
use App\Models\Customer;
use App\Traits\Datatable\WithAppendColumn;

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Datatable\Studio\Loyalty;
namespace App\Livewire\Datatable\Loyalty;
use App\Models\Voucher;
use App\Traits\Datatable\WithAppendColumn;
@ -135,6 +135,6 @@ public function columns(): array
public function builder(): Builder
{
return Voucher::select('id', 'name', 'code', 'min_purchase', 'discount_amount', 'max_discount', 'quota', 'available_count', 'limit_per_user', 'start_date', 'end_date', 'type', 'created_at')->with('outlets');
return Voucher::select('id', 'name', 'code', 'tags', 'min_purchase', 'discount_amount', 'max_discount', 'quota', 'available_count', 'limit_per_user', 'start_date', 'end_date', 'type', 'created_at')->with('outlets');
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Datatable\Studio\Manage;
namespace App\Livewire\Datatable\Manage;
use App\Models\Article;
use App\Traits\Datatable\WithAppendColumn;
@ -61,6 +61,6 @@ public function columns(): array
public function builder(): Builder
{
return Article::select('articles.id', 'title', 'articles.status')->with(['author', 'author.employee']);
return Article::select('articles.id', 'author_id', 'title', 'articles.status', 'published_at')->with(['author', 'author.employee']);
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Datatable\Studio\Manage;
namespace App\Livewire\Datatable\Manage;
use App\Models\Order;
use App\Traits\Datatable\WithAppendColumn;

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Datatable\Studio\Manage;
namespace App\Livewire\Datatable\Manage;
use App\Models\Purchase;
use App\Traits\Datatable\WithAppendColumn;
@ -78,6 +78,6 @@ public function columns(): array
public function builder(): Builder
{
return Purchase::select('purchases.id', 'invoice_number', 'purchase_date', 'total')->with('outlet');
return Purchase::select('purchases.id', 'outlet_id', 'invoice_number', 'purchase_date', 'total')->with('outlet');
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Datatable\Studio\Manage;
namespace App\Livewire\Datatable\Manage;
use App\Models\StockOpname;
use App\Traits\Datatable\WithAppendColumn;
@ -49,7 +49,7 @@ public function columns(): array
public function builder(): Builder
{
return StockOpname::select('stock_opname.id', 'period_month')
return StockOpname::select('stock_opname.id', 'outlet_id', 'period_month')
->where('period_month', '!=', now()->format('Y-m'))
->with('outlet');
}

View File

@ -22,7 +22,7 @@ class="text-sm">
</flux:callout.text>
</flux:callout>
<livewire:datatable.studio.catalog.bottles-table />
<livewire:datatable.catalog.bottles-table />
</div>
@include('components.modals.confirmation', [

View File

@ -15,7 +15,7 @@
</div>
<div class="mt-6">
<livewire:datatable.studio.catalog.brands-table />
<livewire:datatable.catalog.brands-table />
</div>
@include('components.modals.confirmation', [

View File

@ -15,7 +15,7 @@
</div>
<div class="mt-6">
<livewire:datatable.studio.catalog.categories-table />
<livewire:datatable.catalog.categories-table />
</div>
@include('components.modals.confirmation', [

View File

@ -22,7 +22,7 @@ class="text-sm">
</flux:callout.text>
</flux:callout>
<livewire:datatable.studio.catalog.perfumes-table />
<livewire:datatable.catalog.perfumes-table />
</div>
@include('components.modals.confirmation', [

View File

@ -22,7 +22,7 @@ class="text-sm">
</flux:callout.text>
</flux:callout>
<livewire:datatable.studio.catalog.products-table />
<livewire:datatable.catalog.products-table />
</div>
@include('components.modals.confirmation', [

View File

@ -16,7 +16,7 @@
</div>
<div class="mt-6">
<livewire:datatable.studio.feature.choose-us-table />
<livewire:datatable.feature.choose-us-table />
</div>
@include('components.modals.confirmation', [
@ -27,7 +27,7 @@
'buttonColor' => 'danger',
'buttonText' => 'Ya, Hapus',
])
<flux:modal name="form-modal" class="w-[95%] max-w-sm md:max-w-xl mx-auto" @close="closeModal('form-modal')">
<div class="p-4 space-y-6">
<flux:heading size="lg">{{ $modalTitle }}</flux:heading>

View File

@ -16,7 +16,7 @@
</div>
<div class="mt-6">
<livewire:datatable.studio.feature.perfume-features-table />
<livewire:datatable.feature.perfume-features-table />
</div>
@include('components.modals.confirmation', [
@ -27,7 +27,7 @@
'buttonColor' => 'danger',
'buttonText' => 'Ya, Hapus',
])
<flux:modal name="form-modal" class="w-[95%] max-w-sm md:max-w-xl mx-auto" @close="closeModal('form-modal')">
<div class="p-4 space-y-6">
<flux:heading size="lg">{{ $modalTitle }}</flux:heading>

View File

@ -16,7 +16,7 @@
</div>
<div class="mt-6">
<livewire:datatable.studio.finance.expenses-table />
<livewire:datatable.finance.expenses-table />
</div>
@include('components.modals.confirmation', [

View File

@ -84,7 +84,7 @@ class="font-bold {{ $item->type->value == \App\Enums\SalaryAdjustmentType::DEDUC
@endforeach
</div>
<livewire:datatable.studio.finance.payrolls-table />
<livewire:datatable.finance.payrolls-table />
</div>
@include('components.modals.confirmation', [

View File

@ -15,7 +15,7 @@
</div>
<div class="mt-6">
<livewire:datatable.studio.information.broadcasts-table />
<livewire:datatable.information.broadcasts-table />
</div>
@include('components.modals.confirmation', [

View File

@ -15,7 +15,7 @@
</div>
<div class="mt-6">
<livewire:datatable.studio.information.faqs-table />
<livewire:datatable.information.faqs-table />
</div>
@include('components.modals.confirmation', [

View File

@ -6,7 +6,7 @@
</div>
<div class="mt-6">
<livewire:datatable.studio.information.price-requests-table />
<livewire:datatable.information.price-requests-table />
</div>
@include('components.modals.confirmation', [

View File

@ -26,7 +26,7 @@
</div>
@endif
<livewire:datatable.studio.loyalty.customers-table />
<livewire:datatable.loyalty.customers-table />
</div>
@include('components.modals.confirmation', [

View File

@ -25,7 +25,7 @@ class="text-sm">
</div>
@endif
<livewire:datatable.studio.loyalty.vouchers-table />
<livewire:datatable.loyalty.vouchers-table />
</div>
@include('components.modals.confirmation', [

View File

@ -14,7 +14,7 @@ class="text-sm">
</div>
<div class="mt-6">
<livewire:datatable.studio.manage.articles-table />
<livewire:datatable.manage.articles-table />
</div>
@include('components.modals.confirmation', [

View File

@ -17,7 +17,7 @@ class="text-sm">
</div>
<div class="mt-6">
<livewire:datatable.studio.manage.orders-table />
<livewire:datatable.manage.orders-table />
</div>
@include('components.modals.confirmation', [

View File

@ -21,7 +21,7 @@ class="text-sm">
</flux:callout.text>
</flux:callout>
<livewire:datatable.studio.manage.purchases-table />
<livewire:datatable.manage.purchases-table />
</div>
@include('components.modals.confirmation', [

View File

@ -99,7 +99,7 @@
@endforeach
</div>
<livewire:datatable.studio.manage.stock-opname-table />
<livewire:datatable.manage.stock-opname-table />
</div>
@include('components.modals.confirmation', [

View File

@ -1,121 +0,0 @@
<?php
use App\Livewire\Datatable\Studio\Finance\ExpensesTable;
use App\Models\Employee;
use App\Models\Expense;
use App\Models\Outlet;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
uses(RefreshDatabase::class);
beforeEach(function () {
// Setup Permissions if needed, though view might not need them strictly for data loading,
// but actions column does check permissions
$this->user = User::factory()->has(Employee::factory(), 'employee')->create();
$this->outlet = Outlet::factory()->create();
$this->user->outlets()->attach($this->outlet);
// Give permissions to view actions
// actions column checks: update expense, delete expense, or own data
// So for own data, no perm needed.
});
it('renders successfully', function () {
$this->actingAs($this->user);
Livewire::test(ExpensesTable::class)
->assertStatus(200);
});
it('shows expenses from user outlets', function () {
$this->actingAs($this->user);
Expense::factory()->create([
'user_id' => $this->user->id,
'outlet_id' => $this->outlet->id,
'description' => 'My Expense',
'amount' => 50000,
]);
Livewire::test(ExpensesTable::class)
->assertSee('My Expense')
->assertSee('50.000'); // Assuming currency formatting adds dot for thousands (ID)
});
it('does not show expenses from other outlets', function () {
$this->actingAs($this->user);
$otherOutlet = Outlet::factory()->create();
$otherUser = User::factory()->has(Employee::factory(), 'employee')->create();
$otherUser->outlets()->attach($otherOutlet);
Expense::factory()->create([
'user_id' => $otherUser->id,
'outlet_id' => $otherOutlet->id,
'description' => 'Other Expense',
'amount' => 100000,
]);
Livewire::test(ExpensesTable::class)
->assertDontSee('Other Expense');
});
it('can search by description', function () {
$this->actingAs($this->user);
Expense::factory()->create([
'user_id' => $this->user->id,
'outlet_id' => $this->outlet->id,
'description' => 'UniqueTerm',
'amount' => 12345,
]);
Expense::factory()->create([
'user_id' => $this->user->id,
'outlet_id' => $this->outlet->id,
'description' => 'AnotherItem',
'amount' => 67890,
]);
Livewire::test(ExpensesTable::class)
->set('search', 'UniqueTerm') // Standard search property
->assertSee('UniqueTerm')
->assertDontSee('AnotherItem');
});
it('can search by amount', function () {
$this->actingAs($this->user);
Expense::factory()->create([
'user_id' => $this->user->id,
'outlet_id' => $this->outlet->id,
'description' => 'Exp1',
'amount' => 8888,
]);
Expense::factory()->create([
'user_id' => $this->user->id,
'outlet_id' => $this->outlet->id,
'description' => 'Exp2',
'amount' => 9999,
]);
Livewire::test(ExpensesTable::class)
->set('search', '8888')
->assertSee('Exp1')
->assertDontSee('Exp2');
});
it('renders columns correctly', function () {
$this->actingAs($this->user);
Livewire::test(ExpensesTable::class)
->assertSee('Pegawai')
->assertSee('Keterangan')
->assertSee('Jumlah')
->assertSee('Outlet')
->assertSee('Tanggal')
->assertSee('Aksi');
});