Skip to content

Commit 74d069f

Browse files
committed
Add tags input field to action bar
1 parent 858c7a6 commit 74d069f

File tree

4 files changed

+55
-27
lines changed

4 files changed

+55
-27
lines changed

assets/controllers/elements/datatables/parts_controller.js

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import * as bootbox from "bootbox";
2727
*/
2828
export default class extends DatatablesController {
2929

30-
static targets = ['dt', 'selectPanel', 'selectIDs', 'selectCount', 'selectTargetPicker'];
30+
static targets = ['dt', 'selectPanel', 'selectIDs', 'selectCount', 'selectTargetPicker', 'selectTargetPickerTags'];
3131

3232
_confirmed = false;
3333

@@ -58,6 +58,7 @@ export default class extends DatatablesController {
5858
).join(",");
5959

6060
this.selectIDsTarget.value = selected_ids_string;
61+
//updateTargetPicker(e, items); // to enable automatic update of tags that belong to the currently selected parts
6162
}
6263

6364
updateOptions(select_element, json)
@@ -67,7 +68,19 @@ export default class extends DatatablesController {
6768
//$(select_element).selectpicker('destroy');
6869

6970
//Retrieve the select controller instance
70-
const select_controller = this.application.getControllerForElementAndIdentifier(select_element, 'elements--structural-entity-select');
71+
var select_controller;
72+
if (false && select_element.classList.contains('tagsinput'))
73+
{
74+
select_controller = this.application.getControllerForElementAndIdentifier(select_element, 'elements--tagsinput');
75+
const selectPanel = this.selectPanelTarget;
76+
selectPanel.querySelector('.tagsinput').classList.remove('d-none');
77+
}
78+
else
79+
{
80+
select_controller = this.application.getControllerForElementAndIdentifier(select_element, 'elements--structural-entity-select');
81+
select_element.nextElementSibling.classList.remove('d-none');
82+
}
83+
7184
/** @var {TomSelect} tom_select */
7285
const tom_select = select_controller.getTomSelect();
7386

@@ -81,20 +94,24 @@ export default class extends DatatablesController {
8194
tom_select.setValue(json[0].value);
8295
}
8396

84-
select_element.nextElementSibling.classList.remove('d-none');
8597

8698
//$(select_element).selectpicker('show');
87-
99+
88100
}
89101

90-
updateTargetPicker(event) {
102+
updateTargetPicker(event, items) {
91103
const element = event.target;
92104

93105
//Extract the url from the selected option
94106
const selected_option = element.options[element.options.selectedIndex];
95107
const url = selected_option.dataset.url;
96108

97-
const select_target = this.selectTargetPickerTarget;
109+
var select_target;
110+
if (url && url.endsWith('tag')){
111+
select_target = this.selectTargetPickerTagsTarget;
112+
}
113+
else
114+
select_target = this.selectTargetPickerTarget;
98115

99116
if (url) {
100117
fetch(url)
@@ -104,8 +121,9 @@ export default class extends DatatablesController {
104121
});
105122
});
106123
} else {
107-
//Hide the select element (the tomselect button is the sibling of the select element)
124+
//Hide the select elements (the tomselect button is the sibling of the select element)
108125
select_target.nextElementSibling.classList.add('d-none');
126+
this.selectPanelTarget.querySelector('.tagsinput').classList.add('d-none');
109127
}
110128

111129
//If the selected option has a data-turbo attribute, set it to the form

src/Controller/PartListsController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public function tableAction(Request $request, PartsTableActionHandler $actionHan
7878
$errors = [];
7979

8080
$parts = $actionHandler->idStringToArray($ids);
81-
$redirectResponse = $actionHandler->handleAction($action, $parts, $target ? $target : null, $redirect, $errors);
81+
$redirectResponse = $actionHandler->handleAction($action, $parts, $target !== '' ? $target : null, $redirect, $errors);
8282

8383
//Save changes
8484
$this->entityManager->flush();

src/Controller/SelectAPIController.php

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
use App\Entity\Parts\StorageLocation;
3333
use App\Entity\ProjectSystem\Project;
3434
use App\Form\Type\Helper\StructuralEntityChoiceHelper;
35+
use App\Services\Tools\TagFinder;
3536
use App\Services\Trees\NodesListBuilder;
36-
use App\ApiPlatform\Filter\TagFilter;
3737
use Doctrine\ORM\EntityManagerInterface;
3838
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
3939
use Symfony\Component\HttpFoundation\Response;
@@ -50,20 +50,6 @@ public function __construct(private readonly NodesListBuilder $nodesListBuilder,
5050
{
5151
}
5252

53-
#[Route(path: '/tag', name: 'select_tag')]
54-
public function tag(): Response
55-
{
56-
$tags = [
57-
'text' => 'test',
58-
'value' => 'test',
59-
];
60-
$this->addEmptyNode($tags);
61-
// pseudocode:
62-
// for each part in selection
63-
// use TagFilter to find tags
64-
// dedupe
65-
return $this->json($tags);
66-
6753
#[Route(path: '/category', name: 'select_category')]
6854
public function category(): Response
6955
{
@@ -150,6 +136,27 @@ public function labelProfilesLot(EntityManagerInterface $entityManager): Respons
150136

151137
return $this->json($nodes);
152138
}
139+
140+
#[Route(path: '/tag', name: 'select_tag')]
141+
public function getResponseForTags(EntityManagerInterface $entityManager): Response
142+
{
143+
$tf = new TagFinder($entityManager, ['min_keyword_length' => 2, 'query_limit' => 250]);
144+
$list = $tf->listTags('__'); // return every tag with at least two characters!
145+
146+
$entries = [];
147+
148+
foreach($list as $d)
149+
{
150+
151+
//if ($entries[$d] === null)
152+
$entries[$d['tags']] = $d['tags'];
153+
}
154+
155+
return $this->json(array_map(static fn($key, $value) => [
156+
'text' => $value,
157+
'value' => $key,
158+
], array_keys($entries), $entries));
159+
}
153160

154161
protected function getResponseForClass(string $class, bool $include_empty = false): Response
155162
{

templates/components/datatables.macro.html.twig

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,6 @@
4141

4242
<select class="form-select" name="action" data-controller="elements--select" {{ stimulus_action('elements/datatables/parts', 'updateTargetPicker', 'change') }}
4343
title="{% trans %}part_list.action.action.title{% endtrans %}" required>
44-
<optgroup label="{% trans %}part_list.action.action.group.tags{% endtrans %}">
45-
<option {% if not is_granted('@parts.edit') %}disabled{% endif %} value="add_tag" data-url="{{ path('select_tag') }}">{% trans %}part_list.action.action.add_tag{% endtrans %}</option>
46-
<option {% if not is_granted('@parts.edit') %}disabled{% endif %} value="remove_tag" data-url="{{ path('select_tag') }}">{% trans %}part_list.action.action.remove_tag{% endtrans %}</option>
47-
</optgroup>
4844
<optgroup label="{% trans %}part_list.action.action.group.favorite{% endtrans %}">
4945
<option {% if not is_granted('@parts.change_favorite') %}disabled{% endif %} value="favorite">{% trans %}part_list.action.action.favorite{% endtrans %}</option>
5046
<option {% if not is_granted('@parts.change_favorite') %}disabled{% endif %} value="unfavorite">{% trans %}part_list.action.action.unfavorite{% endtrans %}</option>
@@ -53,6 +49,10 @@
5349
<option {% if not is_granted('@parts.edit') %}disabled{% endif %} value="set_needs_review">{% trans %}part_list.action.action.set_needs_review{% endtrans %}</option>
5450
<option {% if not is_granted('@parts.edit') %}disabled{% endif %} value="unset_needs_review">{% trans %}part_list.action.action.unset_needs_review{% endtrans %}</option>
5551
</optgroup>
52+
<optgroup label="{% trans %}part_list.action.action.group.tags{% endtrans %}">
53+
<option {% if not is_granted('@parts.edit') %}disabled{% endif %} value="add_tag" data-url="{{ path('select_tag') }}">{% trans %}part_list.action.action.add_tag{% endtrans %}</option>
54+
<option {% if not is_granted('@parts.edit') %}disabled{% endif %} value="remove_tag" data-url="{{ path('select_tag') }}">{% trans %}part_list.action.action.remove_tag{% endtrans %}</option>
55+
</optgroup>
5656
<optgroup label="{% trans %}part_list.action.action.group.change_field{% endtrans %}">
5757
<option {% if not is_granted('@parts.edit') %}disabled{% endif %} value="change_category" data-url="{{ path('select_category') }}">{% trans %}part_list.action.action.change_category{% endtrans %}</option>
5858
<option {% if not is_granted('@parts.edit') %}disabled{% endif %} value="change_footprint" data-url="{{ path('select_footprint') }}">{% trans %}part_list.action.action.change_footprint{% endtrans %}</option>
@@ -82,6 +82,9 @@
8282
<select class="form-select d-none" data-controller="elements--structural-entity-select" name="target" {{ stimulus_target('elements/datatables/parts', 'selectTargetPicker') }}>
8383
{# This is left empty, as this will be filled by Javascript #}
8484
</select>
85+
<input class="tagsinput d-none" data-controller="elements--tagsinput" name="target" {{ stimulus_target('elements/datatables/parts', 'selectTargetPickerTags') }}>
86+
{# This is left empty, as this will be filled by Javascript #}
87+
</input>
8588

8689
<button type="submit" class="btn btn-primary">{% trans %}part_list.action.submit{% endtrans %}</button>
8790
</div>

0 commit comments

Comments
 (0)