From 9ed953d1b257cf68e3de703f68b52a3c1b7673d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Tue, 6 Sep 2022 00:25:02 +0200 Subject: [PATCH] Implemented the basics for a parametric search --- .../elements/collection_type_controller.js | 22 ++-- .../Filters/CompoundFilterTrait.php | 10 ++ .../Constraints/Part/ParameterConstraint.php | 116 ++++++++++++++++++ src/DataTables/Filters/PartFilter.php | 16 +++ .../Constraints/ParameterConstraintType.php | 37 ++++++ src/Form/Filters/PartFilterType.php | 10 ++ templates/Form/FilterTypesLayout.html.twig | 17 +++ templates/Parts/lists/_filter.html.twig | 32 +++++ 8 files changed, 253 insertions(+), 7 deletions(-) create mode 100644 src/DataTables/Filters/Constraints/Part/ParameterConstraint.php create mode 100644 src/Form/Filters/Constraints/ParameterConstraintType.php diff --git a/assets/controllers/elements/collection_type_controller.js b/assets/controllers/elements/collection_type_controller.js index 4c804534..607984a2 100644 --- a/assets/controllers/elements/collection_type_controller.js +++ b/assets/controllers/elements/collection_type_controller.js @@ -103,12 +103,20 @@ export default class extends Controller { } deleteElement(event) { - bootbox.confirm(this.deleteMessageValue, (result) => { - if(result) { - const target = event.target; - //Remove the row element from the table - target.closest("tr").remove(); - } - }); + const del = () => { + const target = event.target; + //Remove the row element from the table + target.closest("tr").remove(); + } + + if(this.deleteMessageValue) { + bootbox.confirm(this.deleteMessageValue, (result) => { + if (result) { + del(); + } + }); + } else { + del(); + } } } \ No newline at end of file diff --git a/src/DataTables/Filters/CompoundFilterTrait.php b/src/DataTables/Filters/CompoundFilterTrait.php index 70536512..d39257fa 100644 --- a/src/DataTables/Filters/CompoundFilterTrait.php +++ b/src/DataTables/Filters/CompoundFilterTrait.php @@ -2,6 +2,7 @@ namespace App\DataTables\Filters; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\QueryBuilder; trait CompoundFilterTrait @@ -23,6 +24,15 @@ trait CompoundFilterTrait if($value instanceof FilterInterface) { $filters[$property->getName()] = $value; } + + //Add filters in collections + if ($value instanceof Collection) { + foreach ($value as $key => $filter) { + if($filter instanceof FilterInterface) { + $filters[$property->getName() . '.' . (string) $key] = $filter; + } + } + } } return $filters; } diff --git a/src/DataTables/Filters/Constraints/Part/ParameterConstraint.php b/src/DataTables/Filters/Constraints/Part/ParameterConstraint.php new file mode 100644 index 00000000..318cc3d4 --- /dev/null +++ b/src/DataTables/Filters/Constraints/Part/ParameterConstraint.php @@ -0,0 +1,116 @@ +getEntityManager()); + + //The alias has to be uniq for each subquery, so generate a random one + $alias = uniqid('param_', false); + + $subqb->select('COUNT(' . $alias . ')') + ->from(PartParameter::class, $alias) + ->where($alias . '.element = part'); + + if (!empty($this->name)) { + $paramName = $this->generateParameterIdentifier('params.name'); + $subqb->andWhere($alias . '.name = :' . $paramName); + $queryBuilder->setParameter($paramName, $this->name); + } + + if (!empty($this->symbol)) { + $paramName = $this->generateParameterIdentifier('params.symbol'); + $subqb->andWhere($alias . '.symbol = :' . $paramName); + $queryBuilder->setParameter($paramName, $this->symbol); + } + + if (!empty($this->unit)) { + $paramName = $this->generateParameterIdentifier('params.unit'); + $subqb->andWhere($alias . '.unit = :' . $paramName); + $queryBuilder->setParameter($paramName, $this->unit); + } + + $queryBuilder->andWhere('(' . $subqb->getDQL() . ') > 0'); + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @param string $name + * @return ParameterConstraint + */ + public function setName(string $name): ParameterConstraint + { + $this->name = $name; + return $this; + } + + /** + * @return string + */ + public function getSymbol(): string + { + return $this->symbol; + } + + /** + * @param string $symbol + * @return ParameterConstraint + */ + public function setSymbol(string $symbol): ParameterConstraint + { + $this->symbol = $symbol; + return $this; + } + + /** + * @return string + */ + public function getUnit(): string + { + return $this->unit; + } + + /** + * @param string $unit + * @return ParameterConstraint + */ + public function setUnit(string $unit): ParameterConstraint + { + $this->unit = $unit; + return $this; + } +} \ No newline at end of file diff --git a/src/DataTables/Filters/PartFilter.php b/src/DataTables/Filters/PartFilter.php index df5c976b..1e6a33a3 100644 --- a/src/DataTables/Filters/PartFilter.php +++ b/src/DataTables/Filters/PartFilter.php @@ -8,6 +8,7 @@ use App\DataTables\Filters\Constraints\DateTimeConstraint; use App\DataTables\Filters\Constraints\EntityConstraint; use App\DataTables\Filters\Constraints\IntConstraint; use App\DataTables\Filters\Constraints\NumberConstraint; +use App\DataTables\Filters\Constraints\Part\ParameterConstraint; use App\DataTables\Filters\Constraints\Part\TagsConstraint; use App\DataTables\Filters\Constraints\TextConstraint; use App\Entity\Attachments\AttachmentType; @@ -18,6 +19,7 @@ use App\Entity\Parts\MeasurementUnit; use App\Entity\Parts\Storelocation; use App\Entity\Parts\Supplier; use App\Services\Trees\NodesListBuilder; +use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\QueryBuilder; class PartFilter implements FilterInterface @@ -112,6 +114,9 @@ class PartFilter implements FilterInterface /** @var TextConstraint */ protected $attachmentName; + /** @var ArrayCollection */ + protected $parameters; + public function __construct(NodesListBuilder $nodesListBuilder) { $this->name = new TextConstraint('part.name'); @@ -153,6 +158,8 @@ class PartFilter implements FilterInterface $this->attachmentName = new TextConstraint('attachments.name'); $this->orderdetailsCount = new IntConstraint('COUNT(orderdetails)'); + + $this->parameters = new ArrayCollection(); } public function apply(QueryBuilder $queryBuilder): void @@ -372,5 +379,14 @@ class PartFilter implements FilterInterface return $this->amountSum; } + /** + * @return ArrayCollection + */ + public function getParameters(): ArrayCollection + { + return $this->parameters; + } + + } diff --git a/src/Form/Filters/Constraints/ParameterConstraintType.php b/src/Form/Filters/Constraints/ParameterConstraintType.php new file mode 100644 index 00000000..39a2ca9e --- /dev/null +++ b/src/Form/Filters/Constraints/ParameterConstraintType.php @@ -0,0 +1,37 @@ +setDefaults([ + 'compound' => true, + 'data_class' => ParameterConstraint::class, + ]); + } + + public function buildForm(FormBuilderInterface $builder, array $options): void + { + $builder->add('name', TextType::class, [ + 'required' => false, + ]); + + $builder->add('unit', SearchType::class, [ + 'required' => false, + ]); + + $builder->add('symbol', SearchType::class, [ + 'required' => false + ]); + } +} \ No newline at end of file diff --git a/src/Form/Filters/PartFilterType.php b/src/Form/Filters/PartFilterType.php index b3d491ab..0583715e 100644 --- a/src/Form/Filters/PartFilterType.php +++ b/src/Form/Filters/PartFilterType.php @@ -13,11 +13,13 @@ use App\Form\Filters\Constraints\BooleanConstraintType; use App\Form\Filters\Constraints\ChoiceConstraintType; use App\Form\Filters\Constraints\DateTimeConstraintType; use App\Form\Filters\Constraints\NumberConstraintType; +use App\Form\Filters\Constraints\ParameterConstraintType; use App\Form\Filters\Constraints\StructuralEntityConstraintType; use App\Form\Filters\Constraints\TagsConstraintType; use App\Form\Filters\Constraints\TextConstraintType; use Svg\Tag\Text; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\CollectionType; use Symfony\Component\Form\Extension\Core\Type\DateTimeType; use Symfony\Component\Form\Extension\Core\Type\DateType; use Symfony\Component\Form\Extension\Core\Type\ResetType; @@ -209,6 +211,14 @@ class PartFilterType extends AbstractType 'label' => 'part.filter.attachmentName', ]); + $builder->add('parameters', CollectionType::class, [ + 'label' => 'parameter.label', + 'entry_type' => ParameterConstraintType::class, + 'allow_delete' => true, + 'allow_add' => true, + 'reindex_enable' => false, + ]); + $builder->add('submit', SubmitType::class, [ 'label' => 'filter.submit', ]); diff --git a/templates/Form/FilterTypesLayout.html.twig b/templates/Form/FilterTypesLayout.html.twig index 0b2dfa17..a84ca51e 100644 --- a/templates/Form/FilterTypesLayout.html.twig +++ b/templates/Form/FilterTypesLayout.html.twig @@ -38,4 +38,21 @@ {% block choice_constraint_widget %} {{ block('text_constraint_widget') }} +{% endblock %} + +{% block parameter_constraint_widget %} + {% import 'components/collection_type.macro.html.twig' as collection %} + + {{ form_widget(form.name, {"attr": {"data-pages--parameters-autocomplete-target": "name"}}) }} + {{ form_widget(form.symbol, {"attr": {"data-pages--parameters-autocomplete-target": "symbol", "data-pages--latex-preview-target": "input"}}) }} + + {{ form_widget(form.unit, {"attr": {"data-pages--parameters-autocomplete-target": "unit", "data-pages--latex-preview-target": "input"}}) }} + + + + {{ form_errors(form) }} + + {% endblock %} \ No newline at end of file diff --git a/templates/Parts/lists/_filter.html.twig b/templates/Parts/lists/_filter.html.twig index aa2eb474..9e48cd05 100644 --- a/templates/Parts/lists/_filter.html.twig +++ b/templates/Parts/lists/_filter.html.twig @@ -20,6 +20,9 @@ + {{ form_start(filterForm, {"attr": {"data-controller": "helpers--form-cleanup", "data-action": "helpers--form-cleanup#submit"}}) }} @@ -72,6 +75,35 @@ {{ form_row(filterForm.orderdetailsCount) }} +
+ {% import 'components/collection_type.macro.html.twig' as collection %} + +
+ + + + + + + + + + + + + {% for param in filterForm.parameters %} + {{ form_widget(param) }} + {% endfor %} + +
{% trans %}specifications.property{% endtrans %}{% trans %}specifications.symbol{% endtrans %}{% trans %}specifications.value{% endtrans %}{% trans %}specifications.unit{% endtrans %}{% trans %}specifications.text{% endtrans %}
+ + +
+
+