diff --git a/assets/css/app.css b/assets/css/app.css index 1a5d7f5e..98d09eda 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -683,4 +683,8 @@ table.dataTable { .tab-content>form>.active { display: block; +} + +.dataTables_length { + display: inline-flex; } \ No newline at end of file diff --git a/assets/ts_src/ajax_ui.ts b/assets/ts_src/ajax_ui.ts index 4ac628d1..d1eabc18 100644 --- a/assets/ts_src/ajax_ui.ts +++ b/assets/ts_src/ajax_ui.ts @@ -511,7 +511,12 @@ class AjaxUI { var promise = $('#part_list').initDataTables(settings, { "fixedHeader": { header: $(window).width() >= 768, //Only enable fixedHeaders on devices with big screen. Fixes scrolling issues on smartphones. - headerOffset: $("#navbar").height()} + headerOffset: $("#navbar").height()}, + "buttons": [ { + "extend": 'colvis', + 'className': 'mr-2 btn-light', + "text": "" + }] }); //Register links. diff --git a/config/packages/datatables.yaml b/config/packages/datatables.yaml index a4b866f9..b78788f4 100644 --- a/config/packages/datatables.yaml +++ b/config/packages/datatables.yaml @@ -8,15 +8,16 @@ datatables: lengthMenu : [10, 25, 50, 100, 250, 500, 1000, 2500] pageLength: 50 #dom: "<'row' <'col-sm-12' tr>><'row' <'col-sm-6'l><'col-sm-6 text-right'pif>>" - dom: " <'row'<'col mb-2' l> <'col mb-2'<'pull-right' p>>> - <'card border-primary' - <'#part-card-header.card-header bg-primary text-white'> + dom: " <'row'<'col mb-2 input-group' B l> <'col mb-2' <'pull-right' p>>> + <'card' rt <'card-footer card-footer-table text-muted' i > > <'row'<'col mt-2' l> <'col mt-2'<'pull-right' p>>>" pagingType: 'simple_numbers' searching: true + stateSave: true + template_parameters: # Example classes to integrate nicely with Bootstrap 3.x diff --git a/src/Controller/PartListsController.php b/src/Controller/PartListsController.php index cb468517..45007ccb 100644 --- a/src/Controller/PartListsController.php +++ b/src/Controller/PartListsController.php @@ -54,7 +54,7 @@ class PartListsController extends AbstractController return $table->getResponse(); } - return $this->render('parts_list.html.twig', ['datatable' => $table]); + return $this->render('Parts/lists/category_list.html.twig', ['datatable' => $table]); } /** diff --git a/src/DataTables/PartsDataTable.php b/src/DataTables/PartsDataTable.php index 147be40e..0edd0aa2 100644 --- a/src/DataTables/PartsDataTable.php +++ b/src/DataTables/PartsDataTable.php @@ -35,9 +35,13 @@ use App\Services\EntityURLGenerator; use Doctrine\ORM\QueryBuilder; use Omines\DataTablesBundle\Adapter\Doctrine\ORM\SearchCriteriaProvider; use Omines\DataTablesBundle\Adapter\Doctrine\ORMAdapter; +use Omines\DataTablesBundle\Column\BoolColumn; +use Omines\DataTablesBundle\Column\DateTimeColumn; +use Omines\DataTablesBundle\Column\MapColumn; use Omines\DataTablesBundle\Column\TextColumn; use Omines\DataTablesBundle\DataTable; use Omines\DataTablesBundle\DataTableTypeInterface; +use Symfony\Contracts\Translation\TranslatorInterface; class PartsDataTable implements DataTableTypeInterface { @@ -45,10 +49,12 @@ class PartsDataTable implements DataTableTypeInterface * @var EntityURLGenerator */ protected $urlGenerator; + protected $translator; - public function __construct(EntityURLGenerator $urlGenerator) + public function __construct(EntityURLGenerator $urlGenerator, TranslatorInterface $translator) { $this->urlGenerator = $urlGenerator; + $this->translator = $translator; } protected function buildCriteria(QueryBuilder $builder, array $options) @@ -79,16 +85,84 @@ class PartsDataTable implements DataTableTypeInterface */ public function configure(DataTable $dataTable, array $options) { - $dataTable//->add("id", TextColumn::class) - ->add('name', TextColumn::class, ['label' => 'name.label', - 'render' => function ($value, Part $context) { - return $this->urlGenerator->infoHTML($context); - }, ]) - ->add('description', TextColumn::class, ['label' => 'description.label']) - ->add('category', TextColumn::class, ['field' => 'category.name', 'label' => 'category.label']) - ->add('amountSum', TextColumn::class, ['label' => 'instock.label_short']) - ->add('minamount', TextColumn::class, ['label' => 'mininstock.label_short']) + $dataTable + ->add('name', TextColumn::class, [ + 'label' => $this->translator->trans('part.table.name'), + 'render' => function ($value, Part $context) { + return $this->urlGenerator->infoHTML($context); + }, + ]) + ->add('id', TextColumn::class, [ + 'label' => $this->translator->trans('part.table.id'), + 'visible' => false + ]) + ->add('description', TextColumn::class, [ + 'label' => $this->translator->trans('part.table.description'), + ]) + ->add('category', TextColumn::class, [ + 'field' => 'category.name', + 'label' => $this->translator->trans('part.table.category') + ]) + //->add('footprint', TextColumn::class, ['field' => 'footprint.name']) + //->add('manufacturer', TextColumn::class, ['field' => 'manufacturer.name' ]) + //->add('amountSum', TextColumn::class, ['label' => 'instock.label_short']) + ->add('amount', TextColumn::class, [ + 'label' => $this->translator->trans('part.table.amount'), + 'propertyPath' => 'amountSum' + ]) + ->add('minamount', TextColumn::class, [ + 'label' => $this->translator->trans('part.table.minamount') + ]) //->add('storelocation', TextColumn::class, ['field' => 'storelocation.name', 'label' => 'storelocation.label']) + + ->add('addedDate', DateTimeColumn::class, [ + 'label' => $this->translator->trans('part.table.addedDate'), + 'visible' => false + ]) + ->add('lastModified', DateTimeColumn::class, [ + 'label' => $this->translator->trans('part.table.lastModified'), + 'visible' => false + ]) + ->add('needs_review', BoolColumn::class, [ + 'label' => $this->translator->trans('part.table.needsReview'), + 'trueValue' => $this->translator->trans('true'), + 'falseValue' => $this->translator->trans('false'), + 'nullValue' => '', + 'visible' => false + ]) + ->add('favorite', BoolColumn::class, [ + 'label' => $this->translator->trans('part.table.favorite'), + 'trueValue' => $this->translator->trans('true'), + 'falseValue' => $this->translator->trans('false'), + 'nullValue' => '', + 'visible' => false + ]) + ->add('manufacturing_status', MapColumn::class, [ + 'label' => $this->translator->trans('part.table.manufacturingStatus'), + 'visible' => false, + 'default' => $this->translator->trans('m_status.unknown'), + 'map' => [ + '' => $this->translator->trans('m_status.unknown'), + 'announced' => $this->translator->trans('m_status.announced'), + 'active' => $this->translator->trans('m_status.active'), + 'nrfnd' => $this->translator->trans('m_status.nrfnd'), + 'eol' => $this->translator->trans('m_status.eol'), + 'discontinued' => $this->translator->trans('m_status.discontinued') + ] + ]) + ->add('manufacturer_product_number', TextColumn::class, [ + 'label' => $this->translator->trans('part.table.mpn'), + 'visible' => false + ]) + ->add('mass', TextColumn::class, [ + 'label' => $this->translator->trans('part.table.mass'), + 'visible' => false + ]) + ->add('tags', TextColumn::class, [ + 'label' => $this->translator->trans('part.table.tags'), + 'visible' => false + ]) + ->addOrderBy('name') ->createAdapter(ORMAdapter::class, [ 'entity' => Part::class, diff --git a/templates/Parts/lists/category_list.html.twig b/templates/Parts/lists/category_list.html.twig new file mode 100644 index 00000000..54f26233 --- /dev/null +++ b/templates/Parts/lists/category_list.html.twig @@ -0,0 +1,20 @@ +{% extends "base.html.twig" %} + +{% block content %} + + + {# Set the title for the table here. It will be inserted into the table later.#} + + +
+
+
+
+

{% trans %}part_list.loading.caption{% endtrans %}

+
{% trans %}part_list.loading.message{% endtrans %}
+
+
+
+
+ +{% endblock %} diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf index 2f300684..64022b7b 100644 --- a/translations/messages.de.xlf +++ b/translations/messages.de.xlf @@ -1722,6 +1722,74 @@ Element 3 flash.info Info + + part.table.name + Name + + + part.table.id + ID + + + part.table.description + Beschreibung + + + part.table.category + Kategorie + + + part.table.amount + Menge + + + part.table.minamount + Min.Menge + + + part.table.addedDate + Hinzugefügt + + + part.table.lastModified + Zuletzt bearbeitet + + + part.table.needsReview + Review benötigt + + + true + wahr + + + false + falsch + + + part.table.favorite + Favorit + + + part.table.manufacturingStatus + Status + + + part.table.mpn + MPN + + + part.table.mass + Gewicht + + + part.table.tags + Tags + + + datatable.datatable.lengthMenu + _MENU_ + diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index de76a3ca..ffa03cce 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -1693,6 +1693,74 @@ Element 3 flash.info Info + + part.table.name + Name + + + part.table.id + Id + + + part.table.description + Description + + + part.table.category + Category + + + part.table.amount + Amount + + + part.table.minamount + Min. Amount + + + part.table.addedDate + Created at + + + part.table.lastModified + Last modified + + + part.table.needsReview + Needs review + + + true + true + + + false + false + + + part.table.favorite + Favorite + + + part.table.manufacturingStatus + Status + + + part.table.mpn + MPN + + + part.table.mass + Mass + + + part.table.tags + Tags + + + datatable.datatable.lengthMenu + _MENU_ + diff --git a/translations/validators.de.xlf b/translations/validators.de.xlf index c9e3e0c4..16fd94b2 100644 --- a/translations/validators.de.xlf +++ b/translations/validators.de.xlf @@ -397,33 +397,33 @@ src\Entity\Supplier.php:0 - validator.noneofitschild.self - Ein Element kann nicht sich selbst übergeordnet sein! - - - validator.noneofitschild.children - Ein Kindelement kann nicht das übergeordnete Element sein! - - - validator.isSelectable - Das Element muss auswählbar sein! - - - validator.part_lot.location_full.no_increasment - Der verwendete Lagerort wurde als voll markiert, daher kann der Bestand nicht erhöht werden. (Neuer Bestand maximal {{ old_amount }}) - - - validator.part_lot.location_full - Der Lagerort ist voll, daher können keine neue Teile hinzugefügt werden. - - - validator.part_lot.only_existing - Der Lagerort wurde als "nur bestehende Teile" markiert, daher können keine neuen Teile hinzugefügt werden. - - - validator.part_lot.single_part - Der Lagerort wurde als "Nur ein Bauteil" markiert, daher kann kein neues Bauteil hinzugefügt werden. - + validator.noneofitschild.self + Ein Element kann nicht sich selbst übergeordnet sein! + + + validator.noneofitschild.children + Ein Kindelement kann nicht das übergeordnete Element sein! + + + validator.isSelectable + Das Element muss auswählbar sein! + + + validator.part_lot.location_full.no_increasment + Der verwendete Lagerort wurde als voll markiert, daher kann der Bestand nicht erhöht werden. (Neuer Bestand maximal {{ old_amount }}) + + + validator.part_lot.location_full + Der Lagerort ist voll, daher können keine neue Teile hinzugefügt werden. + + + validator.part_lot.only_existing + Der Lagerort wurde als "nur bestehende Teile" markiert, daher können keine neuen Teile hinzugefügt werden. + + + validator.part_lot.single_part + Der Lagerort wurde als "Nur ein Bauteil" markiert, daher kann kein neues Bauteil hinzugefügt werden. + diff --git a/translations/validators.en.xlf b/translations/validators.en.xlf index 26386009..ba5e2370 100644 --- a/translations/validators.en.xlf +++ b/translations/validators.en.xlf @@ -396,34 +396,34 @@ src\Entity\StructuralDBElement.php:0 src\Entity\Supplier.php:0 - - validator.noneofitschild.self - A element can not be its own parent. - - - validator.noneofitschild.children - The parent can not be one of the children of itself. - - - validator.isSelectable - The element must be selectable. - - - validator.part_lot.location_full.no_increasment - The storage location was marked as full, so you can not increase the instock amount. (New amount max. {{ old_amount }}) - - - validator.part_lot.location_full - The storage location was marked as full, so you can not add a new part to it. - - - validator.part_lot.only_existing - The storage location was marked as "only existing", so you can not add new part to it. - - - validator.part_lot.single_part - The storage location was marked as "single part", so you can not add a new part to it. - + + validator.noneofitschild.self + A element can not be its own parent. + + + validator.noneofitschild.children + The parent can not be one of the children of itself. + + + validator.isSelectable + The element must be selectable. + + + validator.part_lot.location_full.no_increasment + The storage location was marked as full, so you can not increase the instock amount. (New amount max. {{ old_amount }}) + + + validator.part_lot.location_full + The storage location was marked as full, so you can not add a new part to it. + + + validator.part_lot.only_existing + The storage location was marked as "only existing", so you can not add new part to it. + + + validator.part_lot.single_part + The storage location was marked as "single part", so you can not add a new part to it. +