- Complete GGZ Ecademy Nuxt.js user portal - Learning products browser and management - Member management interface - User authentication and roles - Multi-language support (NL/EN) - Vuex store for state management - Component-based architecture
This commit is contained in:
303
components/UniversalFilterSelector/UniversalFilterSelector.vue
Normal file
303
components/UniversalFilterSelector/UniversalFilterSelector.vue
Normal file
@@ -0,0 +1,303 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-select
|
||||
v-model="vModelSelected"
|
||||
:items="filterItems"
|
||||
item-text="title"
|
||||
item-value="id"
|
||||
:outlined="editMode"
|
||||
:solo="!editMode"
|
||||
:disabled="!editMode"
|
||||
:flat="!editMode"
|
||||
append-icon="icon-dropdown"
|
||||
v-if="isSelect"
|
||||
>
|
||||
<template slot="item" slot-scope="data">
|
||||
<v-icon
|
||||
x-small
|
||||
class="mr-2"
|
||||
v-if="data.item.color"
|
||||
:color="data.item.color"
|
||||
>mdi-circle</v-icon
|
||||
>
|
||||
<span>
|
||||
{{ data.item.title }}
|
||||
</span>
|
||||
</template>
|
||||
</v-select>
|
||||
|
||||
<v-list
|
||||
v-if="isCheckbox"
|
||||
:outlined="editMode"
|
||||
:solo="!editMode"
|
||||
:disabled="!editMode"
|
||||
:flat="!editMode"
|
||||
>
|
||||
<v-list-item-group v-model="vModelSelected" multiple>
|
||||
<template v-for="(item, i) in filterItems">
|
||||
<v-list-item
|
||||
:key="`item-${i}`"
|
||||
:value="item.id"
|
||||
active-class="secondary"
|
||||
two-line
|
||||
>
|
||||
<template v-slot:default="{ active, toggle }">
|
||||
<v-list-item-content>
|
||||
<v-list-item-title v-text="item.title"></v-list-item-title>
|
||||
<v-list-item-subtitle
|
||||
v-if="item.subtitle"
|
||||
v-text="item.subtitle"
|
||||
></v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
|
||||
<v-list-item-action>
|
||||
<v-checkbox :input-value="active" :true-value="item.id" />
|
||||
</v-list-item-action>
|
||||
</template>
|
||||
</v-list-item>
|
||||
</template>
|
||||
</v-list-item-group>
|
||||
</v-list>
|
||||
|
||||
<v-select
|
||||
chips
|
||||
multiple
|
||||
v-model="vModelSelected"
|
||||
:items="filterItems"
|
||||
item-text="title"
|
||||
item-value="id"
|
||||
:outlined="editMode"
|
||||
:solo="!editMode"
|
||||
:disabled="!editMode"
|
||||
:flat="!editMode"
|
||||
append-icon="icon-dropdown"
|
||||
v-if="isMixed"
|
||||
/>
|
||||
|
||||
<v-list v-if="isMenu">
|
||||
<v-list-item-group v-model="filtersSelected" multiple id="searchbar">
|
||||
<v-text-field
|
||||
filled
|
||||
dense
|
||||
rounded
|
||||
v-model="search"
|
||||
append-icon="icon-search"
|
||||
hide-details
|
||||
:placeholder="$t('general.search')"
|
||||
single-line
|
||||
full-width
|
||||
flat
|
||||
outlined
|
||||
v-if="hasManyItems"
|
||||
class="mb-4"
|
||||
/>
|
||||
|
||||
<template v-for="(item, i) in filterItemsFiltered">
|
||||
<v-divider v-if="!item" :key="`divider-${i}`"></v-divider>
|
||||
|
||||
<v-list-item v-else :key="`item-${i}`" :value="item.id">
|
||||
<template v-slot:default="{ active, toggle }">
|
||||
<v-list-item-content>
|
||||
<v-list-item-title v-text="item.title"></v-list-item-title>
|
||||
</v-list-item-content>
|
||||
|
||||
<v-list-item-action>
|
||||
<v-checkbox :input-value="active" :true-value="item.id" />
|
||||
</v-list-item-action>
|
||||
</template>
|
||||
</v-list-item>
|
||||
</template>
|
||||
</v-list-item-group>
|
||||
</v-list>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import searchBar from '~/components/UI/SearchBar/SearchBar'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
searchBar,
|
||||
},
|
||||
props: {
|
||||
filterTitle: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
filterType: {
|
||||
type: String,
|
||||
default: 'select',
|
||||
},
|
||||
editMode: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
target: {
|
||||
type: String,
|
||||
default: 'filters',
|
||||
validator: function (value) {
|
||||
// The value must match one of these strings
|
||||
return ['filters', 'versions', 'accreditations'].indexOf(value) !== -1
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
search: '',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isSelect() {
|
||||
return this.filterType === 'select'
|
||||
},
|
||||
isCheckbox() {
|
||||
return this.filterType === 'checkbox'
|
||||
},
|
||||
isMixed() {
|
||||
return this.filterType === 'mixed'
|
||||
},
|
||||
isMenu() {
|
||||
return this.filterType === 'menu'
|
||||
},
|
||||
hasItems() {
|
||||
return this.filterItems.length > 0
|
||||
},
|
||||
hasManyItems() {
|
||||
return this.filterItems.length >= 5
|
||||
},
|
||||
// Both Checkbox and Mixed have multiple filters
|
||||
multiple() {
|
||||
return this.isCheckbox || this.isMixed
|
||||
},
|
||||
filterId() {
|
||||
return this.$store.getters.getFilterByTitle(this.filterTitle).id
|
||||
},
|
||||
filterItems() {
|
||||
if (this.filterTitle) {
|
||||
return this.$store.getters.getFilterByTitle(this.filterTitle).items
|
||||
}
|
||||
return []
|
||||
},
|
||||
|
||||
filterItemsFiltered() {
|
||||
if (this.search) {
|
||||
return this.$store.getters
|
||||
.getFilterByTitle(this.filterTitle)
|
||||
.items.filter((filter) => {
|
||||
return filter.title
|
||||
.toLowerCase()
|
||||
.includes(this.search.toLowerCase())
|
||||
})
|
||||
}
|
||||
return this.filterItems
|
||||
},
|
||||
|
||||
filtersSelected: {
|
||||
get() {
|
||||
return this.$store.state.learning.filtersSelected
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit('learning/SELECT_FILTERS', value)
|
||||
},
|
||||
},
|
||||
|
||||
vModelSelected: {
|
||||
// Gets Object / Array of Objects from filters
|
||||
get() {
|
||||
if (!this.$store.getters.localProduct.filtersGrouped) {
|
||||
return []
|
||||
}
|
||||
if (
|
||||
this.target === 'filters' &&
|
||||
typeof this.$store.getters.localProduct.filtersGrouped[
|
||||
this.filterId
|
||||
] === 'undefined'
|
||||
) {
|
||||
return []
|
||||
}
|
||||
|
||||
let filterItemsIdsSelectedRaw
|
||||
|
||||
if (this.target === 'filters') {
|
||||
// Gets ids from the local learning product array associated to the filterId
|
||||
filterItemsIdsSelectedRaw =
|
||||
this.$store.getters.localProduct.filtersGrouped[this.filterId] || []
|
||||
}
|
||||
|
||||
if (this.target === 'versions') {
|
||||
filterItemsIdsSelectedRaw =
|
||||
this.$store.state.learning.versionsFiltersSelected[this.filterId] ||
|
||||
[]
|
||||
}
|
||||
|
||||
if (this.target === 'accreditations') {
|
||||
filterItemsIdsSelectedRaw =
|
||||
this.$store.state.learning.accreditationsFiltersSelected[
|
||||
this.filterId
|
||||
] || []
|
||||
}
|
||||
|
||||
// if multiple filter, checkbox type, return array of filter items ids only
|
||||
if (this.multiple) {
|
||||
this.selected = filterItemsIdsSelectedRaw
|
||||
return filterItemsIdsSelectedRaw
|
||||
}
|
||||
|
||||
// Single Select Input
|
||||
return this.filterItems.find(
|
||||
(filterItem) => filterItem.id == filterItemsIdsSelectedRaw[0]
|
||||
)
|
||||
},
|
||||
|
||||
set(value) {
|
||||
this.setFilterItems(value)
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
setFilterItems(value) {
|
||||
this.$store.commit('learning/UPDATE_FILTERS', {
|
||||
filterId: this.filterId,
|
||||
target: this.target || 'filters',
|
||||
value,
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.v-input >>> .v-icon {
|
||||
color: var(--v-txt-base) !important;
|
||||
}
|
||||
.v-input >>> .mdi-checkbox-blank-outline::before {
|
||||
font-family: 'mijnggz';
|
||||
content: '\e921' !important;
|
||||
}
|
||||
.v-input >>> .mdi-checkbox-marked::before {
|
||||
font-family: 'mijnggz';
|
||||
content: '\e923' !important;
|
||||
}
|
||||
#searchbar.mx-4 {
|
||||
margin: 30px -24px !important;
|
||||
margin-top: 10px !important;
|
||||
}
|
||||
.v-input >>> .v-expansion-panel-header {
|
||||
color: var(--v-txt-base) !important;
|
||||
}
|
||||
/* .v-input >>> .v-input__slot label {
|
||||
font-weight: 600;
|
||||
color: var(--v-txt-base) !important;
|
||||
} */
|
||||
|
||||
/* .v-input >>> .v-messages__message {
|
||||
padding-left: 33px;
|
||||
font-size: 16px;
|
||||
color: var(--v-tertiary-base) !important;
|
||||
}
|
||||
.v-input >>> .v-input__control:hover label,
|
||||
.v-input >>> .v-input__control:hover .v-messages__message {
|
||||
color: var(--v-secAccent-base) !important;
|
||||
} */
|
||||
</style>
|
||||
Reference in New Issue
Block a user