mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-22 18:03:37 +02:00
Use filter systems for most part lists.
This commit is contained in:
parent
b52c61bfa3
commit
0fc0136914
3 changed files with 106 additions and 138 deletions
|
@ -65,11 +65,13 @@ class PartListsController extends AbstractController
|
||||||
{
|
{
|
||||||
private $entityManager;
|
private $entityManager;
|
||||||
private $nodesListBuilder;
|
private $nodesListBuilder;
|
||||||
|
private $dataTableFactory;
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $entityManager, NodesListBuilder $nodesListBuilder)
|
public function __construct(EntityManagerInterface $entityManager, NodesListBuilder $nodesListBuilder, DataTableFactory $dataTableFactory)
|
||||||
{
|
{
|
||||||
$this->entityManager = $entityManager;
|
$this->entityManager = $entityManager;
|
||||||
$this->nodesListBuilder = $nodesListBuilder;
|
$this->nodesListBuilder = $nodesListBuilder;
|
||||||
|
$this->dataTableFactory = $dataTableFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,35 +125,60 @@ class PartListsController extends AbstractController
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/category/{id}/parts", name="part_list_category")
|
* Common implementation for the part list pages.
|
||||||
*
|
* @param string $template The template that should be rendered
|
||||||
* @return JsonResponse|Response
|
* @param array $additonal_template_vars Any additional template variables that should be passed to the template
|
||||||
|
* @param callable $filter_changer A function that is called with the filter object as parameter. This function can be used to customize the filter
|
||||||
|
* @param callable $form_changer A function that is called with the form object as parameter. This function can be used to customize the form
|
||||||
|
* @return Response
|
||||||
*/
|
*/
|
||||||
public function showCategory(Category $category, Request $request, DataTableFactory $dataTable)
|
protected function showListWithFilter(Request $request, string $template, ?callable $filter_changer = null, ?callable $form_changer = null, array $additonal_template_vars = []): Response
|
||||||
{
|
{
|
||||||
$formRequest = clone $request;
|
$formRequest = clone $request;
|
||||||
$formRequest->setMethod('GET');
|
$formRequest->setMethod('GET');
|
||||||
$filter = new PartFilter($this->nodesListBuilder);
|
$filter = new PartFilter($this->nodesListBuilder);
|
||||||
|
if($filter_changer !== null){
|
||||||
|
$filter_changer($filter);
|
||||||
|
}
|
||||||
|
|
||||||
//Set the category as default filter and disable to change that constraint value
|
|
||||||
$filter->getCategory()->setOperator('INCLUDING_CHILDREN')->setValue($category);
|
|
||||||
$filterForm = $this->createForm(PartFilterType::class, $filter, ['method' => 'GET']);
|
$filterForm = $this->createForm(PartFilterType::class, $filter, ['method' => 'GET']);
|
||||||
$this->disableFormFieldAfterCreation($filterForm->get('category')->get('value'));
|
if($form_changer !== null) {
|
||||||
|
$form_changer($filterForm);
|
||||||
|
}
|
||||||
|
|
||||||
$filterForm->handleRequest($formRequest);
|
$filterForm->handleRequest($formRequest);
|
||||||
|
|
||||||
$table = $dataTable->createFromType(PartsDataTable::class, ['filter' => $filter])
|
$table = $this->dataTableFactory->createFromType(PartsDataTable::class, ['filter' => $filter])
|
||||||
->handleRequest($request);
|
->handleRequest($request);
|
||||||
|
|
||||||
if ($table->isCallback()) {
|
if ($table->isCallback()) {
|
||||||
return $table->getResponse();
|
return $table->getResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('Parts/lists/category_list.html.twig', [
|
return $this->render($template, array_merge([
|
||||||
'datatable' => $table,
|
'datatable' => $table,
|
||||||
'entity' => $category,
|
|
||||||
'repo' => $this->entityManager->getRepository(Category::class),
|
|
||||||
'filterForm' => $filterForm->createView(),
|
'filterForm' => $filterForm->createView(),
|
||||||
]);
|
], $additonal_template_vars));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Route("/category/{id}/parts", name="part_list_category")
|
||||||
|
*
|
||||||
|
* @return JsonResponse|Response
|
||||||
|
*/
|
||||||
|
public function showCategory(Category $category, Request $request)
|
||||||
|
{
|
||||||
|
return $this->showListWithFilter($request,
|
||||||
|
'Parts/lists/category_list.html.twig',
|
||||||
|
function (PartFilter $filter) use ($category) {
|
||||||
|
$filter->getCategory()->setOperator('INCLUDING_CHILDREN')->setValue($category);
|
||||||
|
}, function (FormInterface $filterForm) {
|
||||||
|
$this->disableFormFieldAfterCreation($filterForm->get('category')->get('value'));
|
||||||
|
}, [
|
||||||
|
'entity' => $category,
|
||||||
|
'repo' => $this->entityManager->getRepository(Category::class),
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -159,20 +186,19 @@ class PartListsController extends AbstractController
|
||||||
*
|
*
|
||||||
* @return JsonResponse|Response
|
* @return JsonResponse|Response
|
||||||
*/
|
*/
|
||||||
public function showFootprint(Footprint $footprint, Request $request, DataTableFactory $dataTable)
|
public function showFootprint(Footprint $footprint, Request $request)
|
||||||
{
|
{
|
||||||
$table = $dataTable->createFromType(PartsDataTable::class, ['footprint' => $footprint])
|
return $this->showListWithFilter($request,
|
||||||
->handleRequest($request);
|
'Parts/lists/footprint_list.html.twig',
|
||||||
|
function (PartFilter $filter) use ($footprint) {
|
||||||
if ($table->isCallback()) {
|
$filter->getFootprint()->setOperator('INCLUDING_CHILDREN')->setValue($footprint);
|
||||||
return $table->getResponse();
|
}, function (FormInterface $filterForm) {
|
||||||
}
|
$this->disableFormFieldAfterCreation($filterForm->get('footprint')->get('value'));
|
||||||
|
}, [
|
||||||
return $this->render('Parts/lists/footprint_list.html.twig', [
|
'entity' => $footprint,
|
||||||
'datatable' => $table,
|
'repo' => $this->entityManager->getRepository(Footprint::class),
|
||||||
'entity' => $footprint,
|
]
|
||||||
'repo' => $this->entityManager->getRepository(Footprint::class),
|
);
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -180,20 +206,19 @@ class PartListsController extends AbstractController
|
||||||
*
|
*
|
||||||
* @return JsonResponse|Response
|
* @return JsonResponse|Response
|
||||||
*/
|
*/
|
||||||
public function showManufacturer(Manufacturer $manufacturer, Request $request, DataTableFactory $dataTable)
|
public function showManufacturer(Manufacturer $manufacturer, Request $request)
|
||||||
{
|
{
|
||||||
$table = $dataTable->createFromType(PartsDataTable::class, ['manufacturer' => $manufacturer])
|
return $this->showListWithFilter($request,
|
||||||
->handleRequest($request);
|
'Parts/lists/manufacturer_list.html.twig',
|
||||||
|
function (PartFilter $filter) use ($manufacturer) {
|
||||||
if ($table->isCallback()) {
|
$filter->getManufacturer()->setOperator('INCLUDING_CHILDREN')->setValue($manufacturer);
|
||||||
return $table->getResponse();
|
}, function (FormInterface $filterForm) {
|
||||||
}
|
$this->disableFormFieldAfterCreation($filterForm->get('manufacturer')->get('value'));
|
||||||
|
}, [
|
||||||
return $this->render('Parts/lists/manufacturer_list.html.twig', [
|
'entity' => $manufacturer,
|
||||||
'datatable' => $table,
|
'repo' => $this->entityManager->getRepository(Manufacturer::class),
|
||||||
'entity' => $manufacturer,
|
]
|
||||||
'repo' => $this->entityManager->getRepository(Manufacturer::class),
|
);
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -201,20 +226,19 @@ class PartListsController extends AbstractController
|
||||||
*
|
*
|
||||||
* @return JsonResponse|Response
|
* @return JsonResponse|Response
|
||||||
*/
|
*/
|
||||||
public function showStorelocation(Storelocation $storelocation, Request $request, DataTableFactory $dataTable)
|
public function showStorelocation(Storelocation $storelocation, Request $request)
|
||||||
{
|
{
|
||||||
$table = $dataTable->createFromType(PartsDataTable::class, ['storelocation' => $storelocation])
|
return $this->showListWithFilter($request,
|
||||||
->handleRequest($request);
|
'Parts/lists/store_location_list.html.twig',
|
||||||
|
function (PartFilter $filter) use ($storelocation) {
|
||||||
if ($table->isCallback()) {
|
$filter->getStorelocation()->setOperator('INCLUDING_CHILDREN')->setValue($storelocation);
|
||||||
return $table->getResponse();
|
}, function (FormInterface $filterForm) {
|
||||||
}
|
$this->disableFormFieldAfterCreation($filterForm->get('storelocation')->get('value'));
|
||||||
|
}, [
|
||||||
return $this->render('Parts/lists/store_location_list.html.twig', [
|
'entity' => $storelocation,
|
||||||
'datatable' => $table,
|
'repo' => $this->entityManager->getRepository(Storelocation::class),
|
||||||
'entity' => $storelocation,
|
]
|
||||||
'repo' => $this->entityManager->getRepository(Storelocation::class),
|
);
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -222,20 +246,19 @@ class PartListsController extends AbstractController
|
||||||
*
|
*
|
||||||
* @return JsonResponse|Response
|
* @return JsonResponse|Response
|
||||||
*/
|
*/
|
||||||
public function showSupplier(Supplier $supplier, Request $request, DataTableFactory $dataTable)
|
public function showSupplier(Supplier $supplier, Request $request)
|
||||||
{
|
{
|
||||||
$table = $dataTable->createFromType(PartsDataTable::class, ['supplier' => $supplier])
|
return $this->showListWithFilter($request,
|
||||||
->handleRequest($request);
|
'Parts/lists/supplier_list.html.twig',
|
||||||
|
function (PartFilter $filter) use ($supplier) {
|
||||||
if ($table->isCallback()) {
|
$filter->getSupplier()->setOperator('INCLUDING_CHILDREN')->setValue($supplier);
|
||||||
return $table->getResponse();
|
}, function (FormInterface $filterForm) {
|
||||||
}
|
$this->disableFormFieldAfterCreation($filterForm->get('supplier')->get('value'));
|
||||||
|
}, [
|
||||||
return $this->render('Parts/lists/supplier_list.html.twig', [
|
'entity' => $supplier,
|
||||||
'datatable' => $table,
|
'repo' => $this->entityManager->getRepository(Supplier::class),
|
||||||
'entity' => $supplier,
|
]
|
||||||
'repo' => $this->entityManager->getRepository(Supplier::class),
|
);
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -246,17 +269,17 @@ class PartListsController extends AbstractController
|
||||||
public function showTag(string $tag, Request $request, DataTableFactory $dataTable)
|
public function showTag(string $tag, Request $request, DataTableFactory $dataTable)
|
||||||
{
|
{
|
||||||
$tag = trim($tag);
|
$tag = trim($tag);
|
||||||
$table = $dataTable->createFromType(PartsDataTable::class, ['tag' => $tag])
|
|
||||||
->handleRequest($request);
|
|
||||||
|
|
||||||
if ($table->isCallback()) {
|
return $this->showListWithFilter($request,
|
||||||
return $table->getResponse();
|
'Parts/lists/tags_list.html.twig',
|
||||||
}
|
function (PartFilter $filter) use ($tag) {
|
||||||
|
$filter->getTags()->setOperator('ANY')->setValue($tag);
|
||||||
return $this->render('Parts/lists/tags_list.html.twig', [
|
}, function (FormInterface $filterForm) {
|
||||||
'tag' => $tag,
|
$this->disableFormFieldAfterCreation($filterForm->get('tags')->get('value'));
|
||||||
'datatable' => $table,
|
}, [
|
||||||
]);
|
'tag' => $tag,
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -304,22 +327,6 @@ class PartListsController extends AbstractController
|
||||||
*/
|
*/
|
||||||
public function showAll(Request $request, DataTableFactory $dataTable)
|
public function showAll(Request $request, DataTableFactory $dataTable)
|
||||||
{
|
{
|
||||||
|
return $this->showListWithFilter($request,'Parts/lists/all_list.html.twig');
|
||||||
$formRequest = clone $request;
|
|
||||||
$formRequest->setMethod('GET');
|
|
||||||
$filter = new PartFilter($this->nodesListBuilder);
|
|
||||||
$filterForm = $this->createForm(PartFilterType::class, $filter, ['method' => 'GET']);
|
|
||||||
$filterForm->handleRequest($formRequest);
|
|
||||||
|
|
||||||
$table = $dataTable->createFromType(PartsDataTable::class, [
|
|
||||||
'filter' => $filter,
|
|
||||||
])
|
|
||||||
->handleRequest($request);
|
|
||||||
|
|
||||||
if ($table->isCallback()) {
|
|
||||||
return $table->getResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render('Parts/lists/all_list.html.twig', ['datatable' => $table, 'filterForm' => $filterForm->createView()]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -370,57 +370,12 @@ final class PartsDataTable implements DataTableTypeInterface
|
||||||
|
|
||||||
private function buildCriteria(QueryBuilder $builder, array $options): void
|
private function buildCriteria(QueryBuilder $builder, array $options): void
|
||||||
{
|
{
|
||||||
|
//We do the most stuff here in the filter class
|
||||||
if (isset($options['filter']) && $options['filter'] instanceof PartFilter) {
|
if (isset($options['filter']) && $options['filter'] instanceof PartFilter) {
|
||||||
$filter = $options['filter'];
|
$filter = $options['filter'];
|
||||||
|
|
||||||
$filter->apply($builder);
|
$filter->apply($builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($options['category'])) {
|
|
||||||
$category = $options['category'];
|
|
||||||
$list = $this->treeBuilder->typeToNodesList(Category::class, $category);
|
|
||||||
$list[] = $category;
|
|
||||||
|
|
||||||
$builder->andWhere('part.category IN (:cid)')->setParameter('cid', $list);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($options['footprint'])) {
|
|
||||||
$category = $options['footprint'];
|
|
||||||
$list = $this->treeBuilder->typeToNodesList(Footprint::class, $category);
|
|
||||||
$list[] = $category;
|
|
||||||
|
|
||||||
$builder->andWhere('part.footprint IN (:cid)')->setParameter('cid', $list);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($options['manufacturer'])) {
|
|
||||||
$category = $options['manufacturer'];
|
|
||||||
$list = $this->treeBuilder->typeToNodesList(Manufacturer::class, $category);
|
|
||||||
$list[] = $category;
|
|
||||||
|
|
||||||
$builder->andWhere('part.manufacturer IN (:cid)')->setParameter('cid', $list);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($options['storelocation'])) {
|
|
||||||
$location = $options['storelocation'];
|
|
||||||
$list = $this->treeBuilder->typeToNodesList(Storelocation::class, $location);
|
|
||||||
$list[] = $location;
|
|
||||||
|
|
||||||
$builder->andWhere('partLots.storage_location IN (:cid)')->setParameter('cid', $list);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($options['supplier'])) {
|
|
||||||
$supplier = $options['supplier'];
|
|
||||||
$list = $this->treeBuilder->typeToNodesList(Supplier::class, $supplier);
|
|
||||||
$list[] = $supplier;
|
|
||||||
|
|
||||||
$builder->andWhere('orderdetails.supplier IN (:cid)')->setParameter('cid', $list);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($options['tag'])) {
|
|
||||||
$builder->andWhere('part.tags LIKE :tag')->setParameter('tag', $options['tag']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($options['search'])) {
|
if (!empty($options['search'])) {
|
||||||
if (!$options['search_options']['regex']) {
|
if (!$options['search_options']['regex']) {
|
||||||
//Dont show results, if no things are selected
|
//Dont show results, if no things are selected
|
||||||
|
|
|
@ -6,6 +6,12 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="accordion mb-3">
|
||||||
|
{% include "Parts/lists/_filter.html.twig" %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% include "Parts/lists/_action_bar.html.twig" with {'url_options': {}} %}
|
||||||
|
|
||||||
{% include "Parts/lists/_parts_list.html.twig" %}
|
{% include "Parts/lists/_parts_list.html.twig" %}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue