From d011e58030546b9ba60d95e3ecb7cfef508b30fc Mon Sep 17 00:00:00 2001
From: Matthieu
Date: Fri, 24 Oct 2025 15:18:24 +0200
Subject: [PATCH] feat: ajouter le tri par nom sur les catalogues
---
app/components/model-types/ManagementView.vue | 4 +-
app/pages/component-catalog.vue | 128 ++++++++++++++----
app/pages/pieces-catalog.vue | 128 ++++++++++++++----
3 files changed, 204 insertions(+), 56 deletions(-)
diff --git a/app/components/model-types/ManagementView.vue b/app/components/model-types/ManagementView.vue
index 8a0d72e..b8b864f 100644
--- a/app/components/model-types/ManagementView.vue
+++ b/app/components/model-types/ManagementView.vue
@@ -68,8 +68,8 @@ const props = withDefaults(
const selectedCategory = ref(props.category);
const searchInput = ref("");
const searchTerm = ref("");
-const sort = ref<"name" | "createdAt">("createdAt");
-const dir = ref<"asc" | "desc">("desc");
+const sort = ref<"name" | "createdAt">("name");
+const dir = ref<"asc" | "desc">("asc");
const limit = ref(20);
const offset = ref(0);
diff --git a/app/pages/component-catalog.vue b/app/pages/component-catalog.vue
index 0535c9e..cc73db3 100644
--- a/app/pages/component-catalog.vue
+++ b/app/pages/component-catalog.vue
@@ -26,18 +26,52 @@
-
-
-
- {{ filteredComposants.length }} / {{ composantsTotal }} résultat{{ filteredComposants.length > 1 ? 's' : '' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ visibleComposants.length }} / {{ composantsTotal }} résultat{{ visibleComposants.length > 1 ? 's' : '' }}
@@ -49,7 +83,7 @@
Aucun composant n'a encore été créé.
-
+
Aucun composant ne correspond à votre recherche.
@@ -64,7 +98,7 @@
-
+
| {{ component.name || 'Composant sans nom' }} |
{{ component.typeComposant?.name || '—' }} |
{{ component.reference || '—' }} |
@@ -108,20 +142,60 @@ const composantsList = computed(() => composants.value || [])
const composantsTotal = computed(() => composantsList.value.length)
const searchTerm = ref('')
-const filteredComposants = computed(() => {
- const term = searchTerm.value.trim().toLowerCase()
- if (!term) {
- return composantsList.value
+const sortField = ref<'name' | 'createdAt'>('name')
+const sortDirection = ref<'asc' | 'desc'>('asc')
+
+const resolveComparableName = (component: Record) => {
+ const toComparable = (value?: string | null) =>
+ (value ?? '').toString().trim().toLowerCase()
+
+ return (
+ toComparable(component?.name) ||
+ toComparable(component?.reference) ||
+ toComparable(component?.id)
+ )
+}
+
+const resolveComparableDate = (component: Record) => {
+ const raw = component?.createdAt ?? component?.created_at ?? null
+ if (!raw) {
+ return 0
}
- return composantsList.value.filter((component) => {
- const name = (component?.name || '').toLowerCase()
- const reference = (component?.reference || '').toLowerCase()
- const category = (component?.typeComposant?.name || '').toLowerCase()
- return (
- name.includes(term) ||
- reference.includes(term) ||
- category.includes(term)
- )
+ const parsed = new Date(raw).getTime()
+ return Number.isNaN(parsed) ? 0 : parsed
+}
+
+const visibleComposants = computed(() => {
+ const term = searchTerm.value.trim().toLowerCase()
+ const source = composantsList.value || []
+
+ const filtered = term
+ ? source.filter((component) => {
+ const name = (component?.name || '').toLowerCase()
+ const reference = (component?.reference || '').toLowerCase()
+ const category = (component?.typeComposant?.name || '').toLowerCase()
+ return (
+ name.includes(term) ||
+ reference.includes(term) ||
+ category.includes(term)
+ )
+ })
+ : [...source]
+
+ const direction = sortDirection.value === 'asc' ? 1 : -1
+
+ return filtered.sort((a, b) => {
+ if (sortField.value === 'name') {
+ return (
+ resolveComparableName(a).localeCompare(
+ resolveComparableName(b),
+ 'fr',
+ { sensitivity: 'base' }
+ ) * direction
+ )
+ }
+
+ return (resolveComparableDate(a) - resolveComparableDate(b)) * direction
})
})
diff --git a/app/pages/pieces-catalog.vue b/app/pages/pieces-catalog.vue
index b0337f5..95265a1 100644
--- a/app/pages/pieces-catalog.vue
+++ b/app/pages/pieces-catalog.vue
@@ -25,18 +25,52 @@
-
-
-
- {{ filteredPieces.length }} / {{ piecesTotal }} résultat{{ filteredPieces.length > 1 ? 's' : '' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ visiblePieces.length }} / {{ piecesTotal }} résultat{{ visiblePieces.length > 1 ? 's' : '' }}
@@ -48,7 +82,7 @@
Aucune pièce n'a encore été créée.
-
+
Aucune pièce ne correspond à votre recherche.
@@ -63,7 +97,7 @@
-
+
| {{ piece.name || 'Pièce sans nom' }} |
{{ piece.typePiece?.name || '—' }} |
{{ piece.reference || '—' }} |
@@ -107,20 +141,60 @@ const piecesList = computed(() => pieces.value || [])
const piecesTotal = computed(() => piecesList.value.length)
const searchTerm = ref('')
-const filteredPieces = computed(() => {
- const term = searchTerm.value.trim().toLowerCase()
- if (!term) {
- return piecesList.value
+const sortField = ref<'name' | 'createdAt'>('name')
+const sortDirection = ref<'asc' | 'desc'>('asc')
+
+const resolveComparableName = (piece: Record) => {
+ const normalise = (value?: string | null) =>
+ (value ?? '').toString().trim().toLowerCase()
+
+ return (
+ normalise(piece?.name) ||
+ normalise(piece?.reference) ||
+ normalise(piece?.id)
+ )
+}
+
+const resolveComparableDate = (piece: Record) => {
+ const raw = piece?.createdAt ?? piece?.created_at ?? null
+ if (!raw) {
+ return 0
}
- return piecesList.value.filter((piece) => {
- const name = (piece?.name || '').toLowerCase()
- const reference = (piece?.reference || '').toLowerCase()
- const category = (piece?.typePiece?.name || '').toLowerCase()
- return (
- name.includes(term) ||
- reference.includes(term) ||
- category.includes(term)
- )
+ const timestamp = new Date(raw).getTime()
+ return Number.isNaN(timestamp) ? 0 : timestamp
+}
+
+const visiblePieces = computed(() => {
+ const term = searchTerm.value.trim().toLowerCase()
+ const source = piecesList.value || []
+
+ const filtered = term
+ ? source.filter((piece) => {
+ const name = (piece?.name || '').toLowerCase()
+ const reference = (piece?.reference || '').toLowerCase()
+ const category = (piece?.typePiece?.name || '').toLowerCase()
+ return (
+ name.includes(term) ||
+ reference.includes(term) ||
+ category.includes(term)
+ )
+ })
+ : [...source]
+
+ const direction = sortDirection.value === 'asc' ? 1 : -1
+
+ return filtered.sort((a, b) => {
+ if (sortField.value === 'name') {
+ return (
+ resolveComparableName(a).localeCompare(
+ resolveComparableName(b),
+ 'fr',
+ { sensitivity: 'base' }
+ ) * direction
+ )
+ }
+
+ return (resolveComparableDate(a) - resolveComparableDate(b)) * direction
})
})