<template lang="pug">
div.filter_results(
v-b-tooltip.hover.viewport,
:title="$t('common.results_toolbar.filter_button_tooltip')"
)
v-select(
ref="select"
:searcheable="true"
:clearable="true"
:value="value"
@input="v=>$emit('input',v)"
class="filter_results"
:append-to-body="true" :calculate-position="withPopper"
:options="options"
)
template( v-slot:search="{ attributes, events }")
b-button.mini-btn.d-flex.justify.align-items-center.p-0(variant="outline-primary"
data-name="filter_button"
)
em.fas.fa-filter.m-0(
data-name="filter_button"
maxlength="1"
class=""
v-bind="attributes"
v-on="events" )
</template>
<script>
import { createPopper } from '@popperjs/core'
import $ from 'jquery'
import i18n from '@/i18n'
export const filterResultsSelectOptions = {
none: {
label: i18n.t('location_module.search_filters.none'),
value: 'NONE',
},
}
/**
* Used by Location module
* @todo Refactor migrate vue-select to vue-multiselect and remove vue-select dependency
*/
export default {
props: {
size: {
type: Number,
default: 16,
},
color: {
type: String,
default: '--color-black',
},
value: {
type: Object,
default: () => ({}),
},
circuitFilters: {
type: Boolean,
default: true,
},
missionFilters: {
type: Boolean,
default: true,
},
chronoFilters: {
type: Boolean,
default: false,
},
},
computed: {
style() {
return `font-size:${this.size}px; color: var(${this.color})`
},
options() {
return [
filterResultsSelectOptions.none,
{
label: this.$t('location_module.search_filters.contact_on__move'),
value: 'CONTACT_ON__MOVE',
},
{
label: this.$t('location_module.search_filters.contact_on__stop'),
value: 'CONTACT_ON__STOP',
},
{
label: this.$t('location_module.search_filters.contact_on__slow'),
value: 'CONTACT_ON__SLOW',
},
{
label: this.$t('location_module.search_filters.contact_off'),
value: 'CONTACT_OFF',
},
...(this.circuitFilters
? [
{
label: this.$t('location_module.search_filters.active_circuit'),
value: 'ACTIVE_CIRCUIT',
},
]
: []),
...(this.missionFilters
? [
{
label: this.$t('location_module.search_filters.active_mission'),
value: 'ACTIVE_MISSION',
},
]
: []),
...(this.chronoFilters
? [
{
label: this.$t('location_module.search_filters.chrono_driving'),
value: 'CHRONO_DRIVING',
},
{
label: this.$t(
'location_module.search_filters.chrono_available'
),
value: 'CHRONO_AVAILABLE',
},
{
label: this.$t('location_module.search_filters.chrono_resting'),
value: 'CHRONO_RESTING',
},
{
label: this.$t('location_module.search_filters.chrono_working'),
value: 'CHRONO_WORKING',
},
]
: []),
]
},
},
watch: {
value() {
let index = this.options.findIndex((o) => o.value == this.value.value)
this.$refs.select.typeAheadPointer = index
},
},
mounted() {
this.bindCloseOptionsOnBlur()
},
destroyed() {
$(window).off('click', this.onClick)
$(window).on('keyup', this.onKeyUp)
},
methods: {
/**
* Will close the options list if the user clicks outside the options or press Escape
*/
bindCloseOptionsOnBlur() {
const shouldClose = (e) => this.$refs.select && this.$refs.select.open
this.onClick = (e) => {
if (shouldClose(e) && e.target.dataset.name !== 'filter_button') {
this.$refs.select.closeSearchOptions(e)
}
}
this.onKeyUp = (e) => {
if (shouldClose(e) && e.key === 'Escape') {
this.$refs.select.closeSearchOptions(e)
}
}
$(window).on('click', this.onClick)
$(window).on('keyup', this.onKeyUp)
},
withPopper(dropdownList, component, { width }) {
/**
* We need to explicitly define the dropdown width since
* it is usually inherited from the parent with CSS.
*/
dropdownList.style.width = 'fit-content'
/**
* Here we position the dropdownList relative to the $refs.toggle Element.
*
* The 'offset' modifier aligns the dropdown so that the $refs.toggle and
* the dropdownList overlap by 1 pixel.
*
* The 'toggleClass' modifier adds a 'drop-up' class to the Vue Select
* wrapper so that we can set some styles for when the dropdown is placed
* above.
*/
const popper = createPopper(component.$refs.toggle, dropdownList, {
placement: 'right-end',
modifiers: [
{
name: 'offset',
options: {
offset: [0, -1],
},
},
{
name: 'toggleClass',
enabled: true,
phase: 'write',
fn({ state }) {
component.$el.classList.toggle('drop-down', true)
},
},
],
})
},
},
}
</script>
<style lang="scss">
.filter_results {
padding: 3px;
}
.filter_results em {
color: var(--color-black);
margin-top: 10px;
}
.filter_results .vs__selected {
font-size: 10px;
display: none;
}
.filter_results .vs__dropdown-toggle {
border: 0px;
width: fit-content;
cursor: pointer;
}
.filter_results .vs__actions {
display: none;
}
.filter_results .vs--single.vs--open .vs__selected {
display: none;
}
.filter_results button {
position: relative;
bottom: -4px;
}
</style>
Source