From 00d89c7a16295c8aeebd944fc77b6fb977237a2d Mon Sep 17 00:00:00 2001 From: tcharlss <tcharlss@bravecassine.com> Date: Thu, 2 Jun 2022 23:13:06 +0200 Subject: [PATCH] feat: La balise `#TRI` permet d'alterner le sens du tri. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * La balise `#TRI` produit dorénavant toujours un lien, même si l'item est exposé. * Un clic sur un item exposé inverse le sens du tri * L'item utilisé pour le tri est indiqué visuellement au moyen d'un picto (uniquement dans le privé) Fix: #4877 --- CHANGELOG.md | 4 + ecrire/public/balises.php | 31 +++---- ecrire/public/criteres.php | 5 +- ecrire/public/fonctions.php | 88 +++++++++++++++++++ prive/themes/spip/images/tri-sens-asc-xx.svg | 1 + prive/themes/spip/images/tri-sens-desc-xx.svg | 1 + prive/themes/spip/lists.css.html | 24 +++++ 7 files changed, 135 insertions(+), 19 deletions(-) create mode 100644 prive/themes/spip/images/tri-sens-asc-xx.svg create mode 100644 prive/themes/spip/images/tri-sens-desc-xx.svg diff --git a/CHANGELOG.md b/CHANGELOG.md index 125a61abf7..1a7a8734e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,10 @@ - #5118 Fix les viewbox erronnées lors de la copie locale des SVG sans viewbox - #5194 Améliorer le comportement du bouton "Ajourd'hui" dans le dateur en surlignant le jour courant + ajout option data-todayhighlight sur les input.date + fix option data-clearbtn +### Added + +- #4877 La balise `#TRI` permet d'alterner le sens du critère `tri` + ### Removed - spip-team/securite#3724 #5150 Suppression de la fonction `initialiser_sel()` (qui ne servait que pour la gestion de htpasswd déportée en plugin). diff --git a/ecrire/public/balises.php b/ecrire/public/balises.php index d9c30869eb..0c0110ae2b 100644 --- a/ecrire/public/balises.php +++ b/ecrire/public/balises.php @@ -2688,34 +2688,31 @@ function balise_TRI_dist($p, $liste = 'true') { return $p; } - $_champ = interprete_argument_balise(1, $p); - // si pas de champ, renvoyer le critere de tri utilise - if (!$_champ) { - $p->code = $boucle->modificateur['tri_champ']; + // Différentes infos relatives au tri présentes dans les modificateurs + $_tri_nom = $boucle->modificateur['tri_nom'] ; // nom du paramètre définissant le tri + $_tri_champ = $boucle->modificateur['tri_champ']; // champ actuel utilisé le tri + $_tri_sens = $boucle->modificateur['tri_sens']; // sens de tri actuel + $_tri_liste_sens_defaut = $boucle->modificateur['tri_liste_sens_defaut']; // sens par défaut pour chaque champ + + $_champ_ou_sens = interprete_argument_balise(1, $p); + // si pas de champ, renvoyer le critère de tri actuel + if (!$_champ_ou_sens) { + $p->code = $_tri_champ; return $p; } // forcer la jointure si besoin, et si le champ est statique - if (preg_match(",^'([\w.]+)'$,i", $_champ, $m)) { + if (preg_match(",^'([\w.]+)'$,i", $_champ_ou_sens, $m)) { index_pile($b, $m[1], $p->boucles, '', null, true, false); } $_libelle = interprete_argument_balise(2, $p); - $_libelle = $_libelle ?: $_champ; + $_libelle = $_libelle ?: $_champ_ou_sens; - $_class = interprete_argument_balise(3, $p); - // si champ = ">" c'est un lien vers le tri croissant : de gauche a droite ==> 1 - // si champ = "<" c'est un lien vers le tri decroissant : (sens inverse) == -1 - $_issens = "in_array($_champ,array('>','<'))"; - $_sens = "(strpos('< >',$_champ)-1)"; + $_class = interprete_argument_balise(3, $p) ?? "''"; - $_variable = "((\$s=$_issens)?'sens':'tri')." . $boucle->modificateur['tri_nom']; - $_url = "parametre_url(self(),$_variable,\$s?$_sens:$_champ)"; - $_url = "parametre_url($_url,'var_memotri',strncmp(" . $boucle->modificateur['tri_nom'] . ",'session',7)==0?$_variable:'')"; - $_on = '$s?(' . $boucle->modificateur['tri_sens'] . "==$_sens" . '):(' . $boucle->modificateur['tri_champ'] . "==$_champ)"; + $p->code = "calculer_balise_tri($_champ_ou_sens, $_libelle, $_class, $_tri_nom, $_tri_champ, $_tri_sens, $_tri_liste_sens_defaut)"; - $p->code = "lien_ou_expose($_url,$_libelle,$_on" . ($_class ? ",$_class" : '') . ')'; - //$p->code = "''"; $p->interdire_scripts = false; return $p; diff --git a/ecrire/public/criteres.php b/ecrire/public/criteres.php index fa0418cb85..4947412782 100644 --- a/ecrire/public/criteres.php +++ b/ecrire/public/criteres.php @@ -1824,18 +1824,19 @@ function critere_tri_dist($idb, &$boucles, $crit) { // definition du champ par defaut $_champ_defaut = !isset($crit->param[0][0]) ? "''" : calculer_liste([$crit->param[0][0]], $idb, $boucles, $boucle->id_parent); - $_sens_defaut = !isset($crit->param[1][0]) ? '1' + $_liste_sens_defaut = !isset($crit->param[1][0]) ? '1' : calculer_liste([$crit->param[1][0]], $idb, $boucles, $boucle->id_parent); $_variable = !isset($crit->param[2][0]) ? "'$idb'" : calculer_liste([$crit->param[2][0]], $idb, $boucles, $boucle->id_parent); $_tri = "((\$t=(isset(\$Pile[0]['tri'.$_variable]))?\$Pile[0]['tri'.$_variable]:((strncmp($_variable,'session',7)==0 AND session_get('tri'.$_variable))?session_get('tri'.$_variable):$_champ_defaut))?tri_protege_champ(\$t):'')"; - $_sens_defaut = "(is_array(\$s=$_sens_defaut)?(isset(\$s[\$st=$_tri])?\$s[\$st]:reset(\$s)):\$s)"; + $_sens_defaut = "(is_array(\$s=$_liste_sens_defaut)?(isset(\$s[\$st=$_tri])?\$s[\$st]:reset(\$s)):\$s)"; $_sens = "((intval(\$t=(isset(\$Pile[0]['sens'.$_variable]))?\$Pile[0]['sens'.$_variable]:((strncmp($_variable,'session',7)==0 AND session_get('sens'.$_variable))?session_get('sens'.$_variable):$_sens_defaut))==-1 OR \$t=='inverse')?-1:1)"; $boucle->modificateur['tri_champ'] = $_tri; $boucle->modificateur['tri_sens'] = $_sens; + $boucle->modificateur['tri_liste_sens_defaut'] = $_liste_sens_defaut; $boucle->modificateur['tri_nom'] = $_variable; // faut il inserer un test sur l'existence de $tri parmi les champs de la table ? // evite des erreurs sql, mais peut empecher des tri sur jointure ... diff --git a/ecrire/public/fonctions.php b/ecrire/public/fonctions.php index 6ca2ea2eb8..d53f67333e 100644 --- a/ecrire/public/fonctions.php +++ b/ecrire/public/fonctions.php @@ -404,6 +404,94 @@ function calculer_rang_smart($titre, $objet_source, $id, $env) { return recuperer_numero($titre); } +/** + * Calcul de la balise #TRI + * + * @param string $champ_ou_sens + * - soit le nom de champ sur lequel effectuer le nouveau tri + * - soit `<` et `>` pour définir le sens du tri sur le champ actuel + * @param string $libelle + * Texte du lien + * @param string $classe + * Classe ajoutée au lien, telle que `ajax` + * @param string $tri_nom + * Nom du paramètre définissant le tri + * @param string $tri_champ + * Nom du champ actuel utilisé pour le tri + * @param string $tri_sens + * Sens de tri actuel, 1 ou -1 + * @param array|string|int $liste_tri_sens_defaut + * Soit la liste des sens de tri par défaut pour chaque champ + * Soit une valeur par défaut pour tous les champs (1, -1, inverse) + * @return string + * HTML avec un lien cliquable + */ +function calculer_balise_tri(string $champ_ou_sens, string $libelle, string $classe, string $tri_nom, string $tri_champ, string $tri_sens, $liste_tri_sens_defaut): string { + + $url = self('&'); + $tri_sens = (int) $tri_sens; + $alias_sens = [ + '<' => -1, + '>' => 1, + 'inverse' => -1, + ]; + + // Normaliser la liste des sens de tri par défaut + // On ajoute un jocker pour les champs non présents dans la liste + // avec la valeur du 1er item de la liste, idem critère {tri} + if (is_array($liste_tri_sens_defaut)) { + $liste_tri_sens_defaut['*'] = array_values($liste_tri_sens_defaut)[0]; + } else { + $liste_tri_sens_defaut = [ + '*' => (int) ($alias_sens[$liste_tri_sens_defaut] ?? $liste_tri_sens_defaut), + ]; + } + + // Le nouveau sens de tri : + // Soit c'est un sens fixe donné en paramètre (< ou >) + $is_sens_fixe = array_key_exists($champ_ou_sens, $alias_sens); + if ($is_sens_fixe) { + $tri_sens_nouveau = $alias_sens[$champ_ou_sens]; + // Soit c'est le champ utilisé actuellement pour le tri → on inverse le sens + } elseif ($champ_ou_sens === $tri_champ) { + $tri_sens_nouveau = $tri_sens * -1; + // Sinon c'est un nouveau champ, et on prend son tri par défaut + } else { + $tri_sens_nouveau = (int) ($liste_tri_sens_defaut[$champ_ou_sens] ?? $liste_tri_sens_defaut['*']); + } + + // URL : ajouter le champ sur lequel porte le tri + if (!$is_sens_fixe) { + $param_tri = "tri$tri_nom"; + $url = parametre_url($url, $param_tri, $champ_ou_sens); + } + + // URL : n'ajouter le sens de tri que si nécessaire, + // c.à .d différent du sens par défaut pour le champ + $param_sens = "sens$tri_nom"; + $tri_sens_defaut_champ = (int) ($liste_tri_sens_defaut[$champ_ou_sens] ?? $liste_tri_sens_defaut['*']); + if ($tri_sens_nouveau !== $tri_sens_defaut_champ) { + $url = parametre_url($url, $param_sens, $tri_sens_nouveau); + } else { + $url = parametre_url($url, $param_sens, ''); + } + + // Drapeau pour garder en session ? + $param_memo = (!$is_sens_fixe ? $param_tri : $param_sens); + $url = parametre_url($url, 'var_memotri', strncmp($tri_nom, 'session', 7) == 0 ? $param_memo : ''); + + // Classes : on indique le sens de tri et l'item exposé + $classe .= ' item-tri item-tri_' . ($tri_sens === 1 ? 'asc' : 'desc'); + if ($champ_ou_sens === $tri_champ) { + $classe .= ' item-tri_actif'; + } + + // Lien + $balise = lien_ou_expose($url, $libelle, false, $classe); + + return $balise; +} + /** * Proteger les champs passes dans l'url et utiliser dans {tri ...} diff --git a/prive/themes/spip/images/tri-sens-asc-xx.svg b/prive/themes/spip/images/tri-sens-asc-xx.svg new file mode 100644 index 0000000000..57ae3cb018 --- /dev/null +++ b/prive/themes/spip/images/tri-sens-asc-xx.svg @@ -0,0 +1 @@ +<svg role="img" xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" aria-labelledby="arrowUpIconTitle" stroke="#111" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none" color="#111"> <title id="arrowUpIconTitle">Arrow Up</title> <path d="M18 9l-6-6-6 6"/> <path d="M12 21V4"/> <path stroke-linecap="round" d="M12 3v1"/> </svg> \ No newline at end of file diff --git a/prive/themes/spip/images/tri-sens-desc-xx.svg b/prive/themes/spip/images/tri-sens-desc-xx.svg new file mode 100644 index 0000000000..19bb3a65d0 --- /dev/null +++ b/prive/themes/spip/images/tri-sens-desc-xx.svg @@ -0,0 +1 @@ +<svg role="img" xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" aria-labelledby="arrowDownIconTitle" stroke="#111" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none" color="#111"> <title id="arrowDownIconTitle">Arrow Down</title> <path d="M6 15l6 6 6-6"/> <path d="M12 3v17"/> <path stroke-linecap="round" d="M12 21v-1"/> </svg> \ No newline at end of file diff --git a/prive/themes/spip/lists.css.html b/prive/themes/spip/lists.css.html index 937f699146..a845cf25d9 100644 --- a/prive/themes/spip/lists.css.html +++ b/prive/themes/spip/lists.css.html @@ -716,6 +716,30 @@ text-align: var(--spip-left); } +/* Balise TRI : picto indiquant le sens de tri sur l'item exposé */ +.item-tri_actif { + display: inline-flex; + align-items: center; +} +.item-tri_actif:after { + content: ""; + display: inline-block; + width: 1em; + height: 1em; + margin-inline-start: 0.15em; + margin-inline-start: 0.15em; + background-color: currentColor !important; + mask-size: contain; + mask-position: center; + mask-repeat: no-repeat; +} +.item-tri_actif.item-tri_asc:after { + mask-image: url("#CHEMIN_IMAGE{tri-sens-asc-xx.svg}"); +} +.item-tri_actif.item-tri_desc:after { + mask-image: url("#CHEMIN_IMAGE{tri-sens-desc-xx.svg}"); +} + /** * ========= -- GitLab