Added dynamic filtering
This commit is contained in:
parent
ec3fc7f5ca
commit
a219f0f067
|
|
@ -113,6 +113,7 @@ export default class extends Controller {
|
||||||
const first = (s) => (typeof s === "string" && s.length ? s.trim()[0].toUpperCase() : "");
|
const first = (s) => (typeof s === "string" && s.length ? s.trim()[0].toUpperCase() : "");
|
||||||
const initials = `${first(data.name)}${first(data.prenom)}`;
|
const initials = `${first(data.name)}${first(data.prenom)}`;
|
||||||
|
|
||||||
|
// wrapper is for centering and circle clipping
|
||||||
const wrapper = document.createElement("div");
|
const wrapper = document.createElement("div");
|
||||||
wrapper.className = "avatar-wrapper";
|
wrapper.className = "avatar-wrapper";
|
||||||
// same size for both cases
|
// same size for both cases
|
||||||
|
|
@ -282,7 +283,7 @@ export default class extends Controller {
|
||||||
}];
|
}];
|
||||||
const tabulator = new Tabulator("#tabulator-userList", {
|
const tabulator = new Tabulator("#tabulator-userList", {
|
||||||
langs: TABULATOR_FR_LANG,
|
langs: TABULATOR_FR_LANG,
|
||||||
locale: "fr", //'en' for English, 'fr' for French (en is default, no need to include it)
|
locale: "fr",
|
||||||
ajaxURL: "/user/data",
|
ajaxURL: "/user/data",
|
||||||
ajaxConfig: "GET",
|
ajaxConfig: "GET",
|
||||||
pagination: true,
|
pagination: true,
|
||||||
|
|
@ -295,9 +296,26 @@ export default class extends Controller {
|
||||||
|
|
||||||
ajaxSorting: true,
|
ajaxSorting: true,
|
||||||
ajaxFiltering: true,
|
ajaxFiltering: true,
|
||||||
rowHeight: 60,
|
filterMode: "remote",
|
||||||
layout: "fitColumns", // activate French
|
|
||||||
|
|
||||||
|
// Add this to send filter data
|
||||||
|
ajaxURLGenerator: function(url, config, params) {
|
||||||
|
let queryParams = new URLSearchParams();
|
||||||
|
queryParams.append('page', params.page || 1);
|
||||||
|
queryParams.append('size', params.size || 10);
|
||||||
|
|
||||||
|
// Add filters
|
||||||
|
if (params.filter) {
|
||||||
|
params.filter.forEach(filter => {
|
||||||
|
queryParams.append(`filter[${filter.field}]`, filter.value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${url}?${queryParams.toString()}`;
|
||||||
|
},
|
||||||
|
|
||||||
|
rowHeight: 60,
|
||||||
|
layout: "fitColumns",
|
||||||
columns
|
columns
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -393,11 +393,29 @@ class UserController extends AbstractController
|
||||||
$page = max(1, (int)$request->query->get('page', 1));
|
$page = max(1, (int)$request->query->get('page', 1));
|
||||||
$size = max(1, (int)$request->query->get('size', 10));
|
$size = max(1, (int)$request->query->get('size', 10));
|
||||||
|
|
||||||
|
// Get filter parameters
|
||||||
|
$filters = $request->query->all('filter', []);
|
||||||
|
|
||||||
$repo = $this->userRepository;
|
$repo = $this->userRepository;
|
||||||
|
|
||||||
// Base query: keep your constraints intact (isDeleted=false, isActive=true)
|
// Base query
|
||||||
$qb = $repo->createQueryBuilder('u')
|
$qb = $repo->createQueryBuilder('u')
|
||||||
->where('u.isDeleted = :del')->setParameter('del', false);
|
->where('u.isDeleted = :del')->setParameter('del', false);
|
||||||
|
|
||||||
|
// Apply filters
|
||||||
|
if (!empty($filters['name'])) {
|
||||||
|
$qb->andWhere('u.surname LIKE :name')
|
||||||
|
->setParameter('name', '%' . $filters['name'] . '%');
|
||||||
|
}
|
||||||
|
if (!empty($filters['prenom'])) {
|
||||||
|
$qb->andWhere('u.name LIKE :prenom')
|
||||||
|
->setParameter('prenom', '%' . $filters['prenom'] . '%');
|
||||||
|
}
|
||||||
|
if (!empty($filters['email'])) {
|
||||||
|
$qb->andWhere('u.email LIKE :email')
|
||||||
|
->setParameter('email', '%' . $filters['email'] . '%');
|
||||||
|
}
|
||||||
|
|
||||||
$countQb = clone $qb;
|
$countQb = clone $qb;
|
||||||
$total = (int)$countQb->select('COUNT(u.id)')->getQuery()->getSingleScalarResult();
|
$total = (int)$countQb->select('COUNT(u.id)')->getQuery()->getSingleScalarResult();
|
||||||
|
|
||||||
|
|
@ -405,7 +423,7 @@ class UserController extends AbstractController
|
||||||
$offset = ($page - 1) * $size;
|
$offset = ($page - 1) * $size;
|
||||||
$rows = $qb->setFirstResult($offset)->setMaxResults($size)->getQuery()->getResult();
|
$rows = $qb->setFirstResult($offset)->setMaxResults($size)->getQuery()->getResult();
|
||||||
|
|
||||||
// Map to array (keep isConnected)
|
// Map to array
|
||||||
$data = array_map(function (User $user) {
|
$data = array_map(function (User $user) {
|
||||||
return [
|
return [
|
||||||
'id' => $user->getId(),
|
'id' => $user->getId(),
|
||||||
|
|
@ -419,15 +437,13 @@ class UserController extends AbstractController
|
||||||
];
|
];
|
||||||
}, $rows);
|
}, $rows);
|
||||||
|
|
||||||
// Match organizations response shape
|
|
||||||
$lastPage = (int)ceil($total / $size);
|
$lastPage = (int)ceil($total / $size);
|
||||||
|
|
||||||
return $this->json([
|
return $this->json([
|
||||||
'data' => $data,
|
'data' => $data,
|
||||||
'last_page' => $lastPage,
|
'last_page' => $lastPage,
|
||||||
'total' => $total, // optional but handy
|
'total' => $total,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route(path: '/indexTest', name: 'indexTest', methods: ['GET'])]
|
#[Route(path: '/indexTest', name: 'indexTest', methods: ['GET'])]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue