feat: add product ID filter to product index page and update pagination logic

This commit is contained in:
Yoga Pangestu 2026-07-19 17:38:46 +07:00
parent 9539ff7042
commit 03ea092d39
3 changed files with 23 additions and 4 deletions

View File

@ -34,16 +34,19 @@ public function index(Request $request): Response
$status = $request->string('status')->toString(); $status = $request->string('status')->toString();
$categoryId = $request->string('category_id')->toString(); $categoryId = $request->string('category_id')->toString();
$stockStatus = $request->string('stock_status')->toString(); $stockStatus = $request->string('stock_status')->toString();
$productId = $request->string('product_id')->toString();
return Inertia::render('admin/master/products/Index', [ return Inertia::render('admin/master/products/Index', [
'products' => $this->productService->paginateForIndex($tableQuery, $status, $categoryId, $stockStatus), 'products' => $this->productService->paginateForIndex($tableQuery, $status, $categoryId, $stockStatus, $productId),
'categories' => $this->categoryService->getSelectOptions(), 'categories' => $this->categoryService->getSelectOptions(),
'filters' => $this->dataTableFilters($tableQuery, [ 'filters' => $this->dataTableFilters($tableQuery, [
'status' => $status, 'status' => $status,
'category_id' => $categoryId, 'category_id' => $categoryId,
'stock_status' => $stockStatus, 'stock_status' => $stockStatus,
'search_id' => $tableQuery['search_id'], 'search_id' => $tableQuery['search_id'],
'product_id' => $productId,
]), ]),
'productsList' => Product::query()->orderBy('name')->get(['id', 'name'])->map(fn ($p) => ['value' => (string) $p->id, 'label' => $p->name])->all(),
]); ]);
} }

View File

@ -31,7 +31,7 @@ public function __construct(
private readonly PushNotificationService $pushNotificationService, private readonly PushNotificationService $pushNotificationService,
) {} ) {}
public function paginateForIndex(array $tableQuery, string $status, string $categoryId = '', string $stockStatus = ''): LengthAwarePaginator public function paginateForIndex(array $tableQuery, string $status, string $categoryId = '', string $stockStatus = '', string $productId = ''): LengthAwarePaginator
{ {
$query = Product::query() $query = Product::query()
->with([ ->with([
@ -49,8 +49,12 @@ public function paginateForIndex(array $tableQuery, string $status, string $cate
}) })
->when(($tableQuery['search_id'] ?? '') === '' && $tableQuery['search'] !== '', function (Builder $query) use ($tableQuery): void { ->when(($tableQuery['search_id'] ?? '') === '' && $tableQuery['search'] !== '', function (Builder $query) use ($tableQuery): void {
$search = $tableQuery['search']; $search = $tableQuery['search'];
$query->whereHas('variants', fn (Builder $query) => $query->where('name', 'like', "%{$search}%")); $query->where(function (Builder $q) use ($search): void {
$q->where('products.name', 'like', "%{$search}%")
->orWhereHas('variants', fn (Builder $q) => $q->where('name', 'like', "%{$search}%"));
});
}) })
->when($productId !== '', fn (Builder $query) => $query->where('products.id', $productId))
->when($status !== '', fn (Builder $query) => $query->where('status', $status)) ->when($status !== '', fn (Builder $query) => $query->where('status', $status))
->when($categoryId !== '', function (Builder $query) use ($categoryId): void { ->when($categoryId !== '', function (Builder $query) use ($categoryId): void {
$query->whereHas('categories', fn (Builder $query) => $query->where('categories.id', $categoryId)); $query->whereHas('categories', fn (Builder $query) => $query->where('categories.id', $categoryId));

View File

@ -26,7 +26,9 @@ const props = defineProps<{
status?: string; status?: string;
category_id?: string; category_id?: string;
stock_status?: string; stock_status?: string;
product_id?: string;
}; };
productsList?: { value: string; label: string }[];
}>(); }>();
const { can } = useCan(); const { can } = useCan();
@ -36,12 +38,21 @@ const { query, setSearch, setFilter, resetFilters, syncFromServer } =
useDataTableQuery({ useDataTableQuery({
url: index.url(), url: index.url(),
initial: { ...props.filters }, initial: { ...props.filters },
filterKeys: ['status', 'category_id', 'stock_status'], filterKeys: ['status', 'category_id', 'stock_status', 'product_id'],
}); });
useDataTableQuerySync(() => props.filters, syncFromServer); useDataTableQuerySync(() => props.filters, syncFromServer);
const filterDefs = computed<DataTableFilterDef[]>(() => [ const filterDefs = computed<DataTableFilterDef[]>(() => [
{
key: 'product_id',
label: 'Nama Produk',
type: 'select',
options: props.productsList?.map((p) => ({
value: p.value,
label: p.label,
})) ?? [],
},
{ {
key: 'category_id', key: 'category_id',
label: 'Kategori', label: 'Kategori',
@ -73,6 +84,7 @@ const filterDefs = computed<DataTableFilterDef[]>(() => [
]); ]);
const filterValues = computed(() => ({ const filterValues = computed(() => ({
product_id: query.value.product_id ?? '',
category_id: query.value.category_id ?? '', category_id: query.value.category_id ?? '',
status: query.value.status ?? '', status: query.value.status ?? '',
stock_status: query.value.stock_status ?? '', stock_status: query.value.stock_status ?? '',