From 12ef25054fefdadc5018647f786df7159e4265f6 Mon Sep 17 00:00:00 2001 From: "Yassine R." Date: Tue, 17 Dec 2024 18:04:42 +0100 Subject: [PATCH] fix(frontend): fix sort of ids --- packages/common/src/search/core/search.ts | 18 ++---- .../manage-usagers-page.component.ts | 9 +-- .../services/usagersSorter.service.spec.ts | 59 +++++++++++++++---- .../services/usagersSorter.service.ts | 13 ++-- .../usager-filter/usagersFilter.service.ts | 42 +++++++------ .../admin-structures-list.component.html | 13 +++- 6 files changed, 100 insertions(+), 54 deletions(-) diff --git a/packages/common/src/search/core/search.ts b/packages/common/src/search/core/search.ts index 6fec728bfd..b5da417899 100644 --- a/packages/common/src/search/core/search.ts +++ b/packages/common/src/search/core/search.ts @@ -93,6 +93,7 @@ function match( score: 0, }; } + if (withScore) { return words.reduce( ({ match, score }, word) => { @@ -103,7 +104,7 @@ function match( }); return { match: match && matchWordResult.match, - score: score + matchWordResult.score, // si un mot a matché, on calcul quand même un score, ça pourrait permettre de retourner des résultats même si aucun match + score: score + matchWordResult.score, }; }, { match: true, score: 0 } as MatchWithScoreResults @@ -119,17 +120,10 @@ function match( }); const matchAllWords = firstNonMatchingWord === undefined; - if (matchAllWords) { - return { - match: true, - score: 1, - }; - } else { - return { - match: false, - score: 0, - }; - } + return { + match: matchAllWords, + score: matchAllWords ? 1 : 0, + }; } } diff --git a/packages/frontend/src/app/modules/manage-usagers/components/manage-usagers-page/manage-usagers-page.component.ts b/packages/frontend/src/app/modules/manage-usagers/components/manage-usagers-page/manage-usagers-page.component.ts index 653646ed48..20f1652575 100644 --- a/packages/frontend/src/app/modules/manage-usagers/components/manage-usagers-page/manage-usagers-page.component.ts +++ b/packages/frontend/src/app/modules/manage-usagers/components/manage-usagers-page/manage-usagers-page.component.ts @@ -381,13 +381,7 @@ export class ManageUsagersPageComponent } private validateDateSearchInput(text: string): Date | null { - const dateRegex = /\b(0[1-9]|[12]\d|3[01])\/(0[1-9]|1[0-2])\/([12]\d{3})\b/; - const match = text.match(dateRegex); - - if (!match) { - return null; - } - const parsedDate = parse(match[0], "dd/MM/yyyy", new Date()); + const parsedDate = parse(text.trim(), "dd/MM/yyyy", new Date()); return isValid(parsedDate) ? parsedDate : null; } @@ -476,6 +470,7 @@ export class ManageUsagersPageComponent } else { this.filters$.next(this.filters); } + this.setFilters(); } private getNextSortValue( diff --git a/packages/frontend/src/app/modules/manage-usagers/components/usager-filter/services/usagersSorter.service.spec.ts b/packages/frontend/src/app/modules/manage-usagers/components/usager-filter/services/usagersSorter.service.spec.ts index 7e346578ab..36749b4b8c 100644 --- a/packages/frontend/src/app/modules/manage-usagers/components/usager-filter/services/usagersSorter.service.spec.ts +++ b/packages/frontend/src/app/modules/manage-usagers/components/usager-filter/services/usagersSorter.service.spec.ts @@ -55,7 +55,20 @@ const usagersMock = [ procurations: [], }, }, + { + ref: 4, + prenom: "Toto", + nom: "Mariec", + surnom: "Clacla", + email: "", + customRef: "3A", + ayantsDroits: [], + options: { + procurations: [], + }, + }, ].map((usager) => new UsagerFormModel(usager as UsagerLight)); + const usagers = [ { ref: 1, @@ -80,7 +93,7 @@ const usagers = [ }, { ref: 2, - customRef: "50", + customRef: "", prenom: "Marie", nom: "Smith", surnom: "Maria", @@ -167,11 +180,14 @@ describe("usagersSorter - test from legacy code", () => { expect(results.length).toEqual(usagers.length); expect(results.map((x) => x.customRef)).toEqual([ "01", + "", "8", - "50", "AB5", "Ab6", ]); + + // CustomRef: "AB5" < "Ab6" < "01" < "8" < "" + expect(results.map((x) => x.ref)).toEqual([1, 2, 3, 5, 4]); }); it("usagersSorter customRef desc", () => { @@ -183,10 +199,13 @@ describe("usagersSorter - test from legacy code", () => { expect(results.map((x) => x.customRef)).toEqual([ "Ab6", "AB5", - "50", "8", + "", "01", ]); + + // CustomRef: "AB5" > "Ab6" > "01" > "8" > "" + expect(results.map((x) => x.ref)).toEqual([4, 5, 3, 2, 1]); }); }); @@ -200,7 +219,12 @@ describe("usagersSorter", () => { sortValue: "asc", }); - expect(result.map((u) => u.nom)).toEqual(["Meunier", "Smith", "Smith"]); + expect(result.map((u) => u.nom)).toEqual([ + "Mariec", + "Meunier", + "Smith", + "Smith", + ]); }); it("devrait trier par nom en ordre descendant", () => { @@ -209,7 +233,12 @@ describe("usagersSorter", () => { sortValue: "desc", }); - expect(result.map((u) => u.nom)).toEqual(["Smith", "Smith", "Meunier"]); + expect(result.map((u) => u.nom)).toEqual([ + "Smith", + "Smith", + "Meunier", + "Mariec", + ]); }); it("devrait utiliser le prénom comme second critère de tri", () => { @@ -225,22 +254,28 @@ describe("usagersSorter", () => { }); describe("sortBy avec tri par ID (customRef)", () => { - it("devrait trier les 'ref' numériques avant les non-numériques en asc", () => { - const result = usagersSorter.sortBy(baseUsagers, { + it("devrait trier les 'ref' numériques avant les non-numériques en asc / Desc", () => { + const tests = [ + { ref: 1, customRef: "001", nom: "X", prenom: "CC" }, + { ref: 2, customRef: null, nom: "X", prenom: "CC" }, + { ref: 3, customRef: "3A", nom: "X", prenom: "CC" }, + { ref: 4, customRef: "3", nom: "X", prenom: "CC" }, + { ref: 0, customRef: "", nom: "X", prenom: "CC" }, + ] as UsagerLight[]; + + const asc = usagersSorter.sortBy(tests, { sortKey: "ID", sortValue: "asc", }); - expect(result.map((u) => u.ref)).toEqual([1, 2, 3]); - }); + expect(asc.map((u) => u.ref)).toEqual([0, 1, 2, 3, 4]); - it("devrait trier les 'ref' numériques après les non-numériques en desc", () => { - const result = usagersSorter.sortBy(baseUsagers, { + const desc = usagersSorter.sortBy(tests, { sortKey: "ID", sortValue: "desc", }); - expect(result.map((u) => u.ref)).toEqual([3, 2, 1]); + expect(desc.map((u) => u.ref)).toEqual([4, 3, 2, 1, 0]); }); // Test avec un jeu de données plus complexe diff --git a/packages/frontend/src/app/modules/manage-usagers/components/usager-filter/services/usagersSorter.service.ts b/packages/frontend/src/app/modules/manage-usagers/components/usager-filter/services/usagersSorter.service.ts index b57aea56d3..ad0ef1fdf8 100644 --- a/packages/frontend/src/app/modules/manage-usagers/components/usager-filter/services/usagersSorter.service.ts +++ b/packages/frontend/src/app/modules/manage-usagers/components/usager-filter/services/usagersSorter.service.ts @@ -49,14 +49,17 @@ export function sortUsagersByCustomRef( ): UsagerLight[] { return sortMultiple(usagers, asc, (usager) => { const customRef = usager.customRef?.trim() || String(usager.ref); - const isNumeric = /^\d+$/.test(customRef); - return [ - isNumeric ? 0 : 1, - isNumeric ? customRef.replace(/^0+/, "").length : 0, + const parts = customRef.split(/(\d+)/).filter(Boolean); - customRef.toLowerCase(), + const sortValues = parts.map((part) => { + const isNum = /^\d+$/.test(part); + return isNum ? parseInt(part, 10) : String(part).toLowerCase().trim(); + }); + return [ + !/^\d/.test(customRef) ? 1 : 0, + ...sortValues, usager.nom.toLowerCase(), usager.prenom.toLowerCase(), ]; diff --git a/packages/frontend/src/app/modules/manage-usagers/components/usager-filter/usagersFilter.service.ts b/packages/frontend/src/app/modules/manage-usagers/components/usager-filter/usagersFilter.service.ts index c2db2529ca..4e4e0dd07c 100644 --- a/packages/frontend/src/app/modules/manage-usagers/components/usager-filter/usagersFilter.service.ts +++ b/packages/frontend/src/app/modules/manage-usagers/components/usager-filter/usagersFilter.service.ts @@ -8,6 +8,7 @@ import { usagerStatutChecker, } from "./services"; import { UsagersFilterCriteria } from "./UsagersFilterCriteria"; +import { isValid, parse } from "date-fns"; export const usagersFilter = { filter, @@ -34,15 +35,28 @@ function filterByCriteria( return filterByEntretien(usagers, criteria.entretien, now); } - const words = criteria.searchString ? buildWords(criteria.searchString) : []; - const needsTextSearch = words.length > 0; - // Si pas de filtres ni de recherche textuelle après le traitement entretien - if (!needsTextSearch && !hasAnyCriteria(criteria)) { + const activeFilters = buildActiveFilters(criteria); + if (!criteria.searchString && !activeFilters.length) { return usagers; } - const activeFilters = buildActiveFilters(criteria); + let words = []; + + if (criteria.searchString) { + if (criteria.searchStringField === "DATE_NAISSANCE") { + const parsedDate = parse( + criteria.searchString.trim(), + "dd/MM/yyyy", + new Date() + ); + if (isValid(parsedDate)) { + words.push(criteria.searchString); + } + } else { + words = buildWords(criteria.searchString); + } + } return usagers.filter((usager) => { if ( @@ -52,12 +66,16 @@ function filterByCriteria( return false; } - // Si pas de recherche textuelle, on a notre réponse - if (!needsTextSearch) { + if (words.length === 0) { return true; } + const attributes = getAttributes(usager, criteria); + if (criteria.searchStringField === "DATE_NAISSANCE") { + return attributes.includes(criteria.searchString); + } + return search.match(usager, { index: 0, getAttributes: () => attributes, @@ -103,16 +121,6 @@ function buildActiveFilters(criteria: UsagersFilterCriteria) { return activeFilters; } -function hasAnyCriteria(criteria: UsagersFilterCriteria): boolean { - return !!( - criteria.statut || - criteria.interactionType || - criteria.echeance || - criteria.lastInteractionDate || - criteria.entretien - ); -} - function filterByEntretien( usagers: UsagerLight[], entretien: string, diff --git a/packages/portail-admins/src/app/modules/admin-structures/components/admin-structures-list/admin-structures-list.component.html b/packages/portail-admins/src/app/modules/admin-structures/components/admin-structures-list/admin-structures-list.component.html index 9b02a847f4..3df8d9cb99 100644 --- a/packages/portail-admins/src/app/modules/admin-structures/components/admin-structures-list/admin-structures-list.component.html +++ b/packages/portail-admins/src/app/modules/admin-structures/components/admin-structures-list/admin-structures-list.component.html @@ -1,6 +1,17 @@ -
+
+
+

+ Structures + ({{ filteredStructures.length + }}/{{ totalStructures }}) +

+