Skip to content

Commit

Permalink
Adds autocomplete to search in pages "results" and "element"
Browse files Browse the repository at this point in the history
  • Loading branch information
alemangui committed Dec 19, 2024
1 parent 95815a6 commit 55659a0
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 17 deletions.
12 changes: 6 additions & 6 deletions frontend/src/components/ElementAutocomplete.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,15 @@ import { getTypeIcon, getTypeInFrench } from "@/utils/mappings"
import { useFetch, useDebounceFn } from "@vueuse/core"
import useToaster from "@/composables/use-toaster"
const modelValue = defineModel({
type: String,
default: "",
})
const container = ref(undefined)
const optionsList = ref(undefined)
const autocompleteResults = ref([])
const searchTerm = ref("")
const searchTerm = ref(modelValue.value)
const debounceDelay = 350
const props = defineProps({
Expand All @@ -82,11 +87,6 @@ const props = defineProps({
},
})
defineModel({
type: String,
default: "",
})
const emit = defineEmits(["selected", "search"])
const hasFocus = ref(false)
const displayOptions = computed(() => hasFocus.value && !!autocompleteResults.value.length)
Expand Down
25 changes: 19 additions & 6 deletions frontend/src/views/ElementPage/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
<div class="bg-blue-france-925 py-8">
<!-- Search -->
<div class="fr-container">
<DsfrSearchBar
placeholder="Rechercher par ingrédient, plante, substance..."
<ElementAutocomplete
v-model="searchTerm"
hint="Tapez au moins trois caractères pour démarrer la recherche"
@selected="goToSelectedOption"
@search="search"
:chooseFirstAsDefault="false"
/>
</div>
</div>
Expand Down Expand Up @@ -101,7 +103,7 @@

<script setup>
import { ref, computed, watch } from "vue"
import { getTypeIcon, getTypeInFrench, unSlugifyType, getApiType } from "@/utils/mappings"
import { getTypeIcon, getTypeInFrench, unSlugifyType, slugifyType, getApiType } from "@/utils/mappings"
import { useRoute, useRouter } from "vue-router"
import { useFetch } from "@vueuse/core"
import { handleError } from "@/utils/error-handling"
Expand All @@ -110,16 +112,23 @@ import ElementTag from "./ElementTag.vue"
import ElementStatusBadge from "@/components/ElementStatusBadge.vue"
import ElementText from "./ElementText.vue"
import ElementTextSection from "./ElementTextSection.vue"
import ElementAutocomplete from "@/components/ElementAutocomplete"
import ReportIssueBlock from "./ReportIssueBlock.vue"
const route = useRoute()
const router = useRouter()
const notFound = ref(false)
const searchTerm = ref(null)
const search = () => {
if (searchTerm.value.length < 3) window.alert("Veuillez saisir au moins trois caractères")
else router.push({ name: "ElementSearchResultsPage", query: { q: searchTerm.value } })
const search = (newTerm) => {
if (newTerm.length < 3) window.alert("Veuillez saisir au moins trois caractères")
else router.push({ name: "ElementSearchResultsPage", query: { q: newTerm } })
}
const goToSelectedOption = (option) => {
const slugguedType = slugifyType(option.objectType)
const urlComponent = `${option?.id}--${slugguedType}--${option?.name}`
return router.push({ name: "ElementPage", params: { urlComponent } })
}
// Afin d'améliorer le SEO, l'urlComponent prend la forme id--type--name
Expand Down Expand Up @@ -204,4 +213,8 @@ watch(route, getElementFromApi)
.fr-table :deep(table) {
@apply !table;
}
.fr-container :deep(input),
.fr-container :deep(button) {
@apply !mt-0;
}
</style>
27 changes: 22 additions & 5 deletions frontend/src/views/ElementSearchResultsPage/index.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<template>
<div class="bg-blue-france-925 py-8">
<div class="fr-container">
<DsfrSearchBar
placeholder="Rechercher par ingrédient, plante, substance..."
<ElementAutocomplete
v-model="searchTerm"
hint="Tapez au moins trois caractères pour démarrer la recherche"
@selected="goToSelectedOption"
@search="search"
:chooseFirstAsDefault="false"
/>
</div>
</div>
Expand Down Expand Up @@ -51,7 +53,9 @@ import { useFetch } from "@vueuse/core"
import { headers } from "@/utils/data-fetching"
import ResultCard from "./ResultCard"
import ProgressSpinner from "@/components/ProgressSpinner"
import ElementAutocomplete from "@/components/ElementAutocomplete"
import { handleError } from "@/utils/error-handling"
import { slugifyType } from "@/utils/mappings"
import { getPagesForPagination } from "@/utils/components"
const router = useRouter()
Expand All @@ -64,9 +68,9 @@ Cette base est en amélioration continue, l'équipe du BEPIAS et Compl'Alim font
Cependant et même si nous avons vocation à l'exhaustivité, il s’agit d’un outil administratif qui n'a pas force de loi.`
// Search
const search = () => {
if (searchTerm.value.length < 3) window.alert("Veuillez saisir au moins trois caractères")
else router.push({ query: { q: searchTerm.value } })
const search = (newTerm) => {
if (newTerm.length < 3) window.alert("Veuillez saisir au moins trois caractères")
else router.push({ query: { q: newTerm } })
}
// Pagination
Expand All @@ -92,6 +96,12 @@ const fetchSearchResults = async () => {
await handleError(response)
}
const goToSelectedOption = (option) => {
const slugguedType = slugifyType(option.objectType)
const urlComponent = `${option?.id}--${slugguedType}--${option?.name}`
return router.push({ name: "ElementPage", params: { urlComponent } })
}
// Initial search
fetchSearchResults() // No need for Suspense
Expand All @@ -109,3 +119,10 @@ watch(page, () => {
routerFunction({ query: { ...route.query, ...{ page: page.value } } })
})
</script>
<style scoped>
.fr-container :deep(input),
.fr-container :deep(button) {
@apply !mt-0;
}
</style>

0 comments on commit 55659a0

Please sign in to comment.