From 26f6546f9d43e81fdf1836f764bc61e625ac3b6c Mon Sep 17 00:00:00 2001 From: pfleu <pierre.fleutot@audemarspiguet.com> Date: Fri, 26 Jan 2024 10:43:02 +0100 Subject: [PATCH] =?UTF-8?q?Page=20Lexique=20:=20on=20peut=20filtrer=20tout?= =?UTF-8?q?es=20les=20entr=C3=A9es=20poss=C3=A9dant=20un=20label=20en=20cl?= =?UTF-8?q?iquant=20sur=20le=20label=20d'uen=20entr=C3=A9e.=20L'ajout=20de?= =?UTF-8?q?=20label=20=C3=A0=20une=20entr=C3=A9e=20se=20fait=20via=20un=20?= =?UTF-8?q?nouveau=20bouton.=20Les=20filtres=20par=20label=20sont=20list?= =?UTF-8?q?=C3=A9s=20en=20t=C3=AAte=20de=20colonne=20et=20supprimables.=20?= =?UTF-8?q?Si=20plusieurs=20filtres=20label,=20la=20condition=20est=20"OU"?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/assets/css/app.css | 6 +++ public/assets/js/app.js | 15 +++--- src/Controller/LexiconController.php | 4 ++ src/Repository/EntryRepository.php | 6 +++ templates/lexicon/show.html.twig | 68 ++++++++++++++++++++------ translations/messages+intl-icu.en.yaml | 1 + translations/messages+intl-icu.fr.yaml | 3 +- 7 files changed, 81 insertions(+), 22 deletions(-) diff --git a/public/assets/css/app.css b/public/assets/css/app.css index c85ae9e..3c13ac0 100755 --- a/public/assets/css/app.css +++ b/public/assets/css/app.css @@ -623,4 +623,10 @@ audio::-webkit-media-controls-mute-button { padding-left: 40px; padding-right: 40px; box-shadow: 2px 2px 6px 0px rgba(0,0,0,0.63); +} + +.disabled-ajax-reload { + /*background-color: lightgrey;*/ + pointer-events: none; + opacity: 0.7; } \ No newline at end of file diff --git a/public/assets/js/app.js b/public/assets/js/app.js index c4ed772..0a0d412 100755 --- a/public/assets/js/app.js +++ b/public/assets/js/app.js @@ -15,6 +15,13 @@ $(function() { }); }); + + // Initialize Tooltips Bootstrap 5 + var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')) + var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) { + return new bootstrap.Tooltip(tooltipTriggerEl) + }) + // NAV : Notifications var down = false; $('#bell').click(function(e){ @@ -45,7 +52,6 @@ $(function() { initializeFormToggles(); initializeConfirmDialog(); // Confirmation des suppressions dans une modal Boostrap initializeAllCollections(); - initializePopover(); initializeFormAutomaticReload(); // initializeFieldsSelect2(); // initializeSubmitRedirect(); @@ -225,11 +231,6 @@ function initializeConfirmDialog() { } } -function initializePopover() { - $('[data-toggle="popover"]').popover({'html':true}); - $('[data-toggle="tooltip"]').tooltip({html: true}); -} - // // Initialise datepicker et datetimepicker // function initializeDatepicker() { @@ -499,7 +500,7 @@ function initializeAjaxReload() { $('body').on('click', '.ajax-reload', function (e) { // Si on a cliqué sur un lien qui demande confirmation, on ne fait rien, l'action aura lieu lors du click sur le bouton de confirmation - if ($(e.currentTarget).attr('data-confirm')) {console.log('canceled reload'); + if ($(e.currentTarget).attr('data-confirm')) { return; } diff --git a/src/Controller/LexiconController.php b/src/Controller/LexiconController.php index 5ffc276..87583f3 100644 --- a/src/Controller/LexiconController.php +++ b/src/Controller/LexiconController.php @@ -53,6 +53,9 @@ class LexiconController extends AppBaseController $filter = $form->getData(); $filter['lexicon'] = $lexicon; + $labelFilterIds = $request->get('labelFilterIds'); + $filter['labels'] = $labelFilterIds; + $labelsFiltered = $labelFilterIds ? $this->getLabels($labelFilterIds) : []; // Entrées triées par createdAt // On ajoute l'ordre d'ajout de l'entrée (on se base sur createdAt) comme index @@ -107,6 +110,7 @@ class LexiconController extends AppBaseController return $this->render('lexicon/show.html.twig', [ 'entries' => $entriesIndexedById, 'lexicon' => $lexicon, + 'labelsFiltered' => $labelsFiltered, 'form' => $form->createView(), 'sortingColumn' => $sortingColumn, 'sortingOrder' => $sortingOrder, diff --git a/src/Repository/EntryRepository.php b/src/Repository/EntryRepository.php index a0de5b0..66eae1e 100644 --- a/src/Repository/EntryRepository.php +++ b/src/Repository/EntryRepository.php @@ -150,6 +150,12 @@ class EntryRepository extends ServiceEntityRepository ->setParameter('lexicon', $filter['lexicon']); } + if (!empty($filter['labels'])) { + $qb ->leftJoin('h.labels', 'l') + ->andWhere('l.id IN (:labels)') + ->setParameter('labels', $filter['labels']); + } + // if (!empty($filter['headword'])) { // $qb ->andWhere('e.headword = :headword') // ->setParameter('headword', $filter['headword']); diff --git a/templates/lexicon/show.html.twig b/templates/lexicon/show.html.twig index 8063eaa..f9ab819 100644 --- a/templates/lexicon/show.html.twig +++ b/templates/lexicon/show.html.twig @@ -32,6 +32,8 @@ </div> {% endif %} + + {########################## SEARCHBAR ############################} <div class="row mt-4"> <div class="col-lg-4 col-md-6 mb-1"> @@ -59,10 +61,16 @@ </a> </div> {% endif %} + + {% if is_granted('LEXICON_EDIT', lexicon) %} + <a href="#" data-url="{{ path('app_lexicon_add_words_list', {id: lexicon.id}) }}" class="modal-form btn btn-dark ms-5"> {{ "Ajouter une liste de mot"|trans }}</a> + {% endif %} </div> </div> + + {########################## LISTE ENTRÉES ############################} <div class="row mt-4"> <div class="col"> @@ -70,6 +78,8 @@ <form name="entries_selection" id="entriesSelection" action="{{ path('app_lexicon_process_selected_entries', {id: lexicon.id}) }}" method="post" novalidate="novalidate" autocomplete="off"> <table class="table table-bordered rounded-3 overflow-hidden"> + + {###### TABLE HEADER ######} <thead> <tr> <th colspan="2" class="text-center"> @@ -79,7 +89,7 @@ <a title="{{ "Ajouter un mot au lexique"|trans }}" href="#" data-url="{{ path('app_lexicon_add_headword', {id: lexicon.id}) }}" class="ms-2 modal-form"><i class="fa fa-plus-circle text-success"></i></a> {% endif %} </div> - {% if searchString %} + {% if searchString %} {# FILTRE HEADWORD supprimable #} <span class="badge bg-danger"> {{ "Filtre: " }}{{ searchString }} <a href="{{ path('app_lexicon_show', {id: lexicon.id}) }}" class="hover-grey"><i title="{{ "Supprimer le filtre"|trans }}" class="fa fa-times-circle"></i></a> @@ -87,7 +97,19 @@ {% endif %} </th> {# <th colspan="3" class="text-center">{{ "Labels"|trans }}</th>#} - <th colspan="2" class="text-center">{{ "Labels"|trans }}</th> + <th colspan="2" class="text-center"> + {{ "Labels"|trans }} + {% if labelsFiltered %} {# FILTRES par LABEL supprimables #} + <div> + {% for label in labelsFiltered %} + <span class="badge bg-danger"> + {{ "Filtre: " }}{{ label }} + <a href="{{ path('app_lexicon_show', { id: lexicon.id, labelFilterIds: app.request.query.get('labelFilterIds')|filter((v, k) => v != label.id) } ) }}" class="hover-grey"><i title="{{ "Supprimer le filtre"|trans }}" class="fa fa-times-circle"></i></a> + </span> + {% endfor %} + </div> + {% endif %} + </th> <th></th> {% if not lexicon.user %} <th></th> @@ -96,6 +118,7 @@ <tr> <th class="text-nowrap"> <span>{{ macros.sorting_column_with_filter("Ordre"|trans, 'createdAt', _context, {id: lexicon.id}) }}</span> + {# On ajoute le param shuffle dans la query et on supprime les params sortingOrder et sortingColumn #} <a href="{{ path('app_lexicon_show', {id: lexicon.id}|merge({shuffle: 'SHUFFLE'})|merge(app.request.query.all|filter((value, key) => (key != 'sortingColumn' and key != 'sortingOrder')))) }}"> <i class="ms-3 fa fa-random"></i> </a> @@ -116,6 +139,8 @@ {% endif %} </tr> </thead> + + {###### TABLE BODY ######} <tbody> {% for entry in entries %} {# @var entry \App\Entity\Entry #} @@ -139,16 +164,38 @@ </div> {# {% endif %}#} </td> + + {############ LABELS ############} {# <td>{% for label in entry.headword.morphologicalLabels %}<span class="badge bg-primary">{{ label }}</span> {% endfor %}</td>#} - <td class="col-md-2 {{ is_granted('LEXICON_EDIT', lexicon) ? 'modal-form' }}" data-url="{{ path('app_label_choose', {lexiconId: lexicon.id, entryId: entry.id, category: constant("App\\Entity\\Label::LABEL_CATEGORY_GENERAL")}) }}"> - {% for label in label_manager.entryVisibleLabels(entry, app.user, constant("App\\Entity\\Label::LABEL_CATEGORY_GENERAL")) %}<span class="blink-target">{% include "label/_labelBadge.html.twig" %}</span>{% endfor %} + <td class="col-md-2"> + <div class="d-flex justify-content-between"> + <span> + {% for label in label_manager.entryVisibleLabels(entry, app.user, constant("App\\Entity\\Label::LABEL_CATEGORY_GENERAL")) %} + <a href="{{ path('app_lexicon_show', {id: lexicon.id, labelFilterIds: [label.id]|merge(app.request.query.get('labelFilterIds') ?: {}) }) }}" data-bs-placement="left" data-bs-toggle="tooltip" title="{{ 'Afficher uniquement les mots possédant ce label'|trans }}">{% include "label/_labelBadge.html.twig" %}</a> + {% endfor %} + </span> + {% if is_granted('LEXICON_EDIT', lexicon) %} + <a class="modal-form links-container" data-url="{{ path('app_label_choose', {lexiconId: lexicon.id, entryId: entry.id, category: constant("App\\Entity\\Label::LABEL_CATEGORY_GENERAL")}) }}"><i class="fa fa-pencil-square text-grey"></i></a> + {% endif %} + </div> + </td> + <td class="col-md-2"> + <div class="d-flex justify-content-between"> + <span> + {% for label in label_manager.entryVisibleLabels(entry, app.user, constant("App\\Entity\\Label::LABEL_CATEGORY_MILESTONE")) %} + <a href="{{ path('app_lexicon_show', {id: lexicon.id, labelFilterIds: [label.id]|merge(app.request.query.get('labelFilterIds') ?: {}) }) }}" data-bs-placement="left" data-bs-toggle="tooltip" title="{{ 'Afficher uniquement les mots possédant ce label'|trans }}">{% include "label/_labelBadge.html.twig" %}</a> + {% endfor %} + </span> + {% if is_granted('LEXICON_EDIT', lexicon) %} + <a class="modal-form links-container" data-url="{{ path('app_label_choose', {lexiconId: lexicon.id, entryId: entry.id, category: constant("App\\Entity\\Label::LABEL_CATEGORY_MILESTONE")}) }}"><i class="fa fa-pencil-square text-grey"></i></a> + {% endif %} + </div> </td> {# <td class="col-md-2 {{ is_granted('LEXICON_EDIT', lexicon) ? 'modal-form' }}" data-url="{{ path('app_label_choose', {lexiconId: lexicon.id, entryId: entry.id, category: constant("App\\Entity\\Label::LABEL_CATEGORY_INSTITUTIONAL")}) }}">#} {# {% for label in label_manager.entryVisibleLabels(entry, app.user, constant("App\\Entity\\Label::LABEL_CATEGORY_INSTITUTIONAL")) %}<span class="blink-target">{% include "label/_labelBadge.html.twig" %}</span>{% endfor %}#} {# </td>#} - <td class="col-md-2 {{ is_granted('LEXICON_EDIT', lexicon) ? 'modal-form' }}" data-url="{{ path('app_label_choose', {lexiconId: lexicon.id, entryId: entry.id, category: constant("App\\Entity\\Label::LABEL_CATEGORY_MILESTONE")}) }}"> - {% for label in label_manager.entryVisibleLabels(entry, app.user, constant("App\\Entity\\Label::LABEL_CATEGORY_MILESTONE")) %}<span class="blink-target">{% include "label/_labelBadge.html.twig" %}</span>{% endfor %} - </td> + + {############ DEFINITIONS ############} <td> {% for pos, definitions in entry.formattedDefinitions %} <a class="text-decoration-none text-toggle" data-bs-toggle="collapse" href="#def-{{ entry.id }}-{{ loop.index }}" role="button" aria-expanded="false" aria-controls="collapseExample"> @@ -177,13 +224,6 @@ </form> - <div class="row"> - <div class="col-md-12"> - {% if is_granted('LEXICON_EDIT', lexicon) %} - <a href="#" data-url="{{ path('app_lexicon_add_words_list', {id: lexicon.id}) }}" class="modal-form btn btn-dark btn-xs"> {{ "Ajouter une liste de mot"|trans }}</a> - {% endif %} - </div> - </div> </div> diff --git a/translations/messages+intl-icu.en.yaml b/translations/messages+intl-icu.en.yaml index a0e0cd6..1caa84c 100644 --- a/translations/messages+intl-icu.en.yaml +++ b/translations/messages+intl-icu.en.yaml @@ -338,3 +338,4 @@ copy_entry: label: 'Target lexicon' copy_entry.merge.submit: 'Submit' copy_entry.merge.label: 'Merging preference' +"Afficher uniquement les mots possédant ce label": "Display only words with this label" \ No newline at end of file diff --git a/translations/messages+intl-icu.fr.yaml b/translations/messages+intl-icu.fr.yaml index dbb992e..3f93239 100644 --- a/translations/messages+intl-icu.fr.yaml +++ b/translations/messages+intl-icu.fr.yaml @@ -352,4 +352,5 @@ copy_entry.merge.submit: 'Enregistrer' copy_entry.merge.label: 'Préférence de fusion' copy_entry: lexicon: - label: 'Lexique cible' \ No newline at end of file + label: 'Lexique cible' +"Afficher uniquement les mots possédant ce label": "Afficher uniquement les mots possédant ce label" \ No newline at end of file -- GitLab