mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-01-13 05:39:33 +00:00
Add tags input field to action bar
This commit is contained in:
parent
858c7a6e0f
commit
74d069f4bd
4 changed files with 55 additions and 27 deletions
|
|
@ -27,7 +27,7 @@ import * as bootbox from "bootbox";
|
|||
*/
|
||||
export default class extends DatatablesController {
|
||||
|
||||
static targets = ['dt', 'selectPanel', 'selectIDs', 'selectCount', 'selectTargetPicker'];
|
||||
static targets = ['dt', 'selectPanel', 'selectIDs', 'selectCount', 'selectTargetPicker', 'selectTargetPickerTags'];
|
||||
|
||||
_confirmed = false;
|
||||
|
||||
|
|
@ -58,6 +58,7 @@ export default class extends DatatablesController {
|
|||
).join(",");
|
||||
|
||||
this.selectIDsTarget.value = selected_ids_string;
|
||||
//updateTargetPicker(e, items); // to enable automatic update of tags that belong to the currently selected parts
|
||||
}
|
||||
|
||||
updateOptions(select_element, json)
|
||||
|
|
@ -67,7 +68,19 @@ export default class extends DatatablesController {
|
|||
//$(select_element).selectpicker('destroy');
|
||||
|
||||
//Retrieve the select controller instance
|
||||
const select_controller = this.application.getControllerForElementAndIdentifier(select_element, 'elements--structural-entity-select');
|
||||
var select_controller;
|
||||
if (false && select_element.classList.contains('tagsinput'))
|
||||
{
|
||||
select_controller = this.application.getControllerForElementAndIdentifier(select_element, 'elements--tagsinput');
|
||||
const selectPanel = this.selectPanelTarget;
|
||||
selectPanel.querySelector('.tagsinput').classList.remove('d-none');
|
||||
}
|
||||
else
|
||||
{
|
||||
select_controller = this.application.getControllerForElementAndIdentifier(select_element, 'elements--structural-entity-select');
|
||||
select_element.nextElementSibling.classList.remove('d-none');
|
||||
}
|
||||
|
||||
/** @var {TomSelect} tom_select */
|
||||
const tom_select = select_controller.getTomSelect();
|
||||
|
||||
|
|
@ -81,20 +94,24 @@ export default class extends DatatablesController {
|
|||
tom_select.setValue(json[0].value);
|
||||
}
|
||||
|
||||
select_element.nextElementSibling.classList.remove('d-none');
|
||||
|
||||
//$(select_element).selectpicker('show');
|
||||
|
||||
|
||||
}
|
||||
|
||||
updateTargetPicker(event) {
|
||||
updateTargetPicker(event, items) {
|
||||
const element = event.target;
|
||||
|
||||
//Extract the url from the selected option
|
||||
const selected_option = element.options[element.options.selectedIndex];
|
||||
const url = selected_option.dataset.url;
|
||||
|
||||
const select_target = this.selectTargetPickerTarget;
|
||||
var select_target;
|
||||
if (url && url.endsWith('tag')){
|
||||
select_target = this.selectTargetPickerTagsTarget;
|
||||
}
|
||||
else
|
||||
select_target = this.selectTargetPickerTarget;
|
||||
|
||||
if (url) {
|
||||
fetch(url)
|
||||
|
|
@ -104,8 +121,9 @@ export default class extends DatatablesController {
|
|||
});
|
||||
});
|
||||
} else {
|
||||
//Hide the select element (the tomselect button is the sibling of the select element)
|
||||
//Hide the select elements (the tomselect button is the sibling of the select element)
|
||||
select_target.nextElementSibling.classList.add('d-none');
|
||||
this.selectPanelTarget.querySelector('.tagsinput').classList.add('d-none');
|
||||
}
|
||||
|
||||
//If the selected option has a data-turbo attribute, set it to the form
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ class PartListsController extends AbstractController
|
|||
$errors = [];
|
||||
|
||||
$parts = $actionHandler->idStringToArray($ids);
|
||||
$redirectResponse = $actionHandler->handleAction($action, $parts, $target ? $target : null, $redirect, $errors);
|
||||
$redirectResponse = $actionHandler->handleAction($action, $parts, $target !== '' ? $target : null, $redirect, $errors);
|
||||
|
||||
//Save changes
|
||||
$this->entityManager->flush();
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ use App\Entity\Parts\MeasurementUnit;
|
|||
use App\Entity\Parts\StorageLocation;
|
||||
use App\Entity\ProjectSystem\Project;
|
||||
use App\Form\Type\Helper\StructuralEntityChoiceHelper;
|
||||
use App\Services\Tools\TagFinder;
|
||||
use App\Services\Trees\NodesListBuilder;
|
||||
use App\ApiPlatform\Filter\TagFilter;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
|
@ -50,20 +50,6 @@ class SelectAPIController extends AbstractController
|
|||
{
|
||||
}
|
||||
|
||||
#[Route(path: '/tag', name: 'select_tag')]
|
||||
public function tag(): Response
|
||||
{
|
||||
$tags = [
|
||||
'text' => 'test',
|
||||
'value' => 'test',
|
||||
];
|
||||
$this->addEmptyNode($tags);
|
||||
// pseudocode:
|
||||
// for each part in selection
|
||||
// use TagFilter to find tags
|
||||
// dedupe
|
||||
return $this->json($tags);
|
||||
|
||||
#[Route(path: '/category', name: 'select_category')]
|
||||
public function category(): Response
|
||||
{
|
||||
|
|
@ -150,6 +136,27 @@ class SelectAPIController extends AbstractController
|
|||
|
||||
return $this->json($nodes);
|
||||
}
|
||||
|
||||
#[Route(path: '/tag', name: 'select_tag')]
|
||||
public function getResponseForTags(EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$tf = new TagFinder($entityManager, ['min_keyword_length' => 2, 'query_limit' => 250]);
|
||||
$list = $tf->listTags('__'); // return every tag with at least two characters!
|
||||
|
||||
$entries = [];
|
||||
|
||||
foreach($list as $d)
|
||||
{
|
||||
|
||||
//if ($entries[$d] === null)
|
||||
$entries[$d['tags']] = $d['tags'];
|
||||
}
|
||||
|
||||
return $this->json(array_map(static fn($key, $value) => [
|
||||
'text' => $value,
|
||||
'value' => $key,
|
||||
], array_keys($entries), $entries));
|
||||
}
|
||||
|
||||
protected function getResponseForClass(string $class, bool $include_empty = false): Response
|
||||
{
|
||||
|
|
|
|||
|
|
@ -41,10 +41,6 @@
|
|||
|
||||
<select class="form-select" name="action" data-controller="elements--select" {{ stimulus_action('elements/datatables/parts', 'updateTargetPicker', 'change') }}
|
||||
title="{% trans %}part_list.action.action.title{% endtrans %}" required>
|
||||
<optgroup label="{% trans %}part_list.action.action.group.tags{% endtrans %}">
|
||||
<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>
|
||||
<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>
|
||||
</optgroup>
|
||||
<optgroup label="{% trans %}part_list.action.action.group.favorite{% endtrans %}">
|
||||
<option {% if not is_granted('@parts.change_favorite') %}disabled{% endif %} value="favorite">{% trans %}part_list.action.action.favorite{% endtrans %}</option>
|
||||
<option {% if not is_granted('@parts.change_favorite') %}disabled{% endif %} value="unfavorite">{% trans %}part_list.action.action.unfavorite{% endtrans %}</option>
|
||||
|
|
@ -53,6 +49,10 @@
|
|||
<option {% if not is_granted('@parts.edit') %}disabled{% endif %} value="set_needs_review">{% trans %}part_list.action.action.set_needs_review{% endtrans %}</option>
|
||||
<option {% if not is_granted('@parts.edit') %}disabled{% endif %} value="unset_needs_review">{% trans %}part_list.action.action.unset_needs_review{% endtrans %}</option>
|
||||
</optgroup>
|
||||
<optgroup label="{% trans %}part_list.action.action.group.tags{% endtrans %}">
|
||||
<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>
|
||||
<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>
|
||||
</optgroup>
|
||||
<optgroup label="{% trans %}part_list.action.action.group.change_field{% endtrans %}">
|
||||
<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>
|
||||
<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 @@
|
|||
<select class="form-select d-none" data-controller="elements--structural-entity-select" name="target" {{ stimulus_target('elements/datatables/parts', 'selectTargetPicker') }}>
|
||||
{# This is left empty, as this will be filled by Javascript #}
|
||||
</select>
|
||||
<input class="tagsinput d-none" data-controller="elements--tagsinput" name="target" {{ stimulus_target('elements/datatables/parts', 'selectTargetPickerTags') }}>
|
||||
{# This is left empty, as this will be filled by Javascript #}
|
||||
</input>
|
||||
|
||||
<button type="submit" class="btn btn-primary">{% trans %}part_list.action.submit{% endtrans %}</button>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue