Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BO - Liste signalement] [Front] Gestion des filtres #2572

Merged
merged 13 commits into from
May 30, 2024
168 changes: 168 additions & 0 deletions assets/vue/components/common/AppAutoComplete.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
<template>
<div class="app-autocomplete" @click="closeAutocomplete">
<input
:id="id"
:name="id"
class="fr-input"
type="text"
v-model="searchText"
@input="updateSearch"
:placeholder="placeholder"
autocomplete="off"
@keydown.down.prevent="handleDownSuggestion"
@keydown.up.prevent="handleUpSuggestion"
@keydown.enter.prevent="handleEnterSuggestion"
/>
<ul v-if="suggestionFilteredList.length > 0"
class="fr-grid-row fr-background-alt--blue-france fr-text-label--blue-france fr-autocomplete-list" >
<li
class="fr-col-12 fr-p-3v fr-text-label--blue-france fr-autocomplete-suggestion"
v-for="(suggestion, index) in suggestionFilteredList"
:key="index"
@click="selectSuggestion(index)"
:class="{ 'fr-autocomplete-suggestion-highlighted': index === selectedSuggestionIndex }"
>
{{ suggestion }}
</li>
</ul>
<ul v-else-if="searchText.length > 0"
class="fr-grid-row fr-background--white fr-text-label--red-marianne fr-autocomplete-list">
<li class="fr-col-12 fr-p-3v fr-autocomplete-suggestion--disabled fr-text--xs">Aucun résultat trouvé</li>
</ul>
</div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
name: 'AppAutoComplete',
emits: ['update:modelValue'],
props: {
id: { type: String, default: '' },
modelValue: { type: Array, default: () => [] },
suggestions: {
type: Array,
required: true
},
multiple: {
type: Boolean,
default: false
},
placeholder: {
type: String,
default: ''
},
reset: {
type: Boolean,
default: false
}
},
watch: {
reset () {
this.resetData()
},
modelValue (newValue: any) {
if (newValue !== this.selectedSuggestions) {
this.selectedSuggestions = []
} else {
this.selectedSuggestions = newValue
}
}
},
data () {
return {
searchText: '',
selectedSuggestions: [] as string[],
suggestionFilteredList: [] as string[],
selectedSuggestion: '',
selectedSuggestionIndex: -1
}
},
created () {
document.addEventListener('click', this.closeAutocomplete)
},
methods: {
selectSuggestion (index: number) {
this.selectedSuggestionIndex = index
if (this.multiple) {
this.selectedSuggestions.push(this.suggestionFilteredList[index])
this.searchText = ''
} else {
this.searchText = this.suggestionFilteredList[index]
}
this.suggestionFilteredList = []
this.$emit('update:modelValue', this.multiple ? this.selectedSuggestions : this.searchText)
},
updateSearch () {
if (this.searchText.length < 1) {
this.suggestionFilteredList = []
} else if (this.searchText.length > 1) {
const searchTextNormalized = this.searchText
.toLowerCase()
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '')
.replace(/[\s-]/g, '')

this.suggestionFilteredList = (this.suggestions as string[])
.filter((item: string) => {
const itemNormalized = item
.toLowerCase()
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '')
.replace(/[\s-]/g, '')

return !this.selectedSuggestions.includes(item) && itemNormalized.includes(searchTextNormalized)
})
}
},
handleDownSuggestion () {
if (this.selectedSuggestionIndex < this.suggestionFilteredList.length - 1) {
this.selectedSuggestionIndex++
}
},
handleUpSuggestion () {
if (this.selectedSuggestionIndex > 0) {
this.selectedSuggestionIndex--
}
},
handleEnterSuggestion () {
if (this.selectedSuggestionIndex !== -1) {
this.selectSuggestion(this.selectedSuggestionIndex)
this.selectedSuggestionIndex = -1
}
},
closeAutocomplete (event: any) {
const target = event.target as HTMLElement
if (target && !event.target.closest('.fr-autocomplete-list')) {
this.suggestionFilteredList = []
this.selectedSuggestionIndex = -1
this.searchText = ''
}
},
resetData () {
this.searchText = ''
this.selectedSuggestions = []
this.suggestionFilteredList = []
this.selectedSuggestion = ''
this.selectedSuggestionIndex = -1
}
}
})
</script>

<style>
.app-autocomplete {
position: relative;
width: 100%;
ul {
position: absolute;
width: 100%;
z-index: 1;
}
}
.fr-autocomplete-suggestion--disabled:hover {
background-color: unset;
cursor: default;
}
</style>
39 changes: 39 additions & 0 deletions assets/vue/components/common/AppNumber.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<template>
<div class="histo-number-input">
<input
class="fr-input"
:id="id"
:name="id"
:value="modelValue"
@input="onInputEvent"
:placeholder="placeholder"
min="0"
type="number"
/>
</div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
name: 'AppNumber',
props: {
id: { type: String, default: '' },
modelValue: String,
onInput: { type: Function },
placeholder: String
},
emits: ['update:modelValue'],
methods: {
onInputEvent (e: any) {
if (e.target.value > 0) {
this.$emit('update:modelValue', e.target.value)
if (this.onInput !== undefined) {
this.onInput(e.target.value)
}
}
}
}
})
</script>
48 changes: 48 additions & 0 deletions assets/vue/components/common/AppSearch.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<template>
<div class="histo-search fr-input-wrap fr-icon-search-line">
<input
class="fr-input"
:id="id"
:name="id"
:value="modelValue"
@input="onInputEvent"
@search="onSearchEvent"
:placeholder="placeholder"
type="search"
/>
</div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
name: 'AppSearch',
props: {
id: { type: String, default: '' },
modelValue: { type: String, default: '' },
onInput: { type: Function },
placeholder: { type: String, default: '' },
minLengthSearch: { type: Number, default: 0 }
},
emits: ['update:modelValue'],
methods: {
onInputEvent (e: any) {
if (e.target.value.length >= this.minLengthSearch) {
this.$emit('update:modelValue', e.target.value)
if (this.onInput !== undefined) {
this.onInput(e.target.value)
}
}
},
onSearchEvent (e: any) {
if (e.target.value === '') {
this.$emit('update:modelValue', null)
if (this.onInput !== undefined) {
this.onInput(null)
}
}
}
}
})
</script>
5 changes: 5 additions & 0 deletions assets/vue/components/common/HistoMultiSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ export default defineComponent({
handleClickItem (event:any) {
const clickedElement:any = event.target
const clickedOptionId:string = clickedElement.dataset.optionid

if (!clickedOptionId) {
return
}

this.modelValue.push(clickedOptionId)
this.$emit('update:modelValue', this.modelValue)
if (this.onChange !== undefined) {
Expand Down
4 changes: 3 additions & 1 deletion assets/vue/components/common/HistoSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
:value="modelValue"
@change="onSelectedEvent"
>
<option v-if="placeholder" value="" selected disabled hidden>{{ placeholder }}</option>
<option v-for="item in displayedItems" :value="item.Id" :key="item.Id">{{ item.Text }}</option>
</select>
</span>
Expand All @@ -26,7 +27,8 @@ export default defineComponent({
optionItems: {
type: Array as () => Array<HistoInterfaceSelectOption>,
default: () => []
}
},
placeholder: { type: String, default: '' }
},
data: function () {
return {
Expand Down
11 changes: 9 additions & 2 deletions assets/vue/components/common/external/HistoDatePicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
format="dd/MM/yyyy"
selectText="Appliquer"
cancelText="Annuler"
:placeholder=placeholder
:ref="id"
/>
</div>
Expand All @@ -25,7 +26,13 @@ export default defineComponent({
expose: ['updateDate'],
props: {
id: { type: String, default: null },
modelValue: { type: Array }
modelValue: { type: Array },
placeholder: { type: String, default: null }
},
watch: {
modelValue (newValue: any) {
this.dates = newValue
}
},
data () {
return {
Expand All @@ -38,7 +45,7 @@ export default defineComponent({
this.dates = newDates
},
handleDate: function (modelData: any) {
if (modelData[1] === null) {
if (modelData !== null && modelData[1] === null) {
modelData[1] = new Date()
}
if (this.dates !== undefined && this.dates !== null) {
Expand Down
Loading
Loading