Use filter systems for most part lists.

This commit is contained in:
Jan Böhmer 2022-09-08 23:49:57 +02:00
parent b52c61bfa3
commit 0fc0136914
3 changed files with 106 additions and 138 deletions

View file

@ -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,
'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, 'entity' => $category,
'repo' => $this->entityManager->getRepository(Category::class), 'repo' => $this->entityManager->getRepository(Category::class),
'filterForm' => $filterForm->createView(), ]
]); );
} }
/** /**
@ -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', [
'datatable' => $table,
'entity' => $footprint, 'entity' => $footprint,
'repo' => $this->entityManager->getRepository(Footprint::class), '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', [
'datatable' => $table,
'entity' => $manufacturer, 'entity' => $manufacturer,
'repo' => $this->entityManager->getRepository(Manufacturer::class), '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', [
'datatable' => $table,
'entity' => $storelocation, 'entity' => $storelocation,
'repo' => $this->entityManager->getRepository(Storelocation::class), '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', [
'datatable' => $table,
'entity' => $supplier, 'entity' => $supplier,
'repo' => $this->entityManager->getRepository(Supplier::class), '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) {
$this->disableFormFieldAfterCreation($filterForm->get('tags')->get('value'));
}, [
'tag' => $tag, 'tag' => $tag,
'datatable' => $table, ]
]); );
} }
/** /**
@ -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()]);
} }
} }

View file

@ -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

View file

@ -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 %}