Proof of concept for filter component
parent
ea35cbcadf
commit
f0ba2f54d7
|
@ -2,26 +2,7 @@
|
|||
<div class="actor-browser browser flexrow">
|
||||
<section class="control-area flexcol">
|
||||
<div class="controls">
|
||||
<div class="filtercontainer">
|
||||
<!-- Name filter. -->
|
||||
<div class="filter">
|
||||
<input type="text" name="compendiumBrowser.name" v-model="name" :placeholder="game.i18n.localize('Name')" />
|
||||
</div>
|
||||
|
||||
<!-- Sort -->
|
||||
<div class="form-group">
|
||||
<label>{{ game.i18n.localize('Sort by:') }}</label>
|
||||
<div class="form-fields">
|
||||
<select class="sort" v-model="sortBy">
|
||||
<option v-for="(option, index) in sortOptions" :key="index" :value="option.value">{{ option.label }}</option>
|
||||
</select>
|
||||
<a class="direction" data-direction="asc" @click="changeDirection()">
|
||||
<i class="fa-solid fa-sort-numeric-up" v-if="direction === 'asc'"></i>
|
||||
<i class="fa-solid fa-sort-numeric-down-alt" v-if="direction !== 'asc'"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<FilterNameSort v-model="name" :filters="sorts"/>
|
||||
|
||||
<div class="filtercontainer">
|
||||
<h3>{{ game.i18n.localize('General') }}</h3>
|
||||
|
@ -182,6 +163,7 @@ import { onUpdated } from 'vue';
|
|||
// External components.
|
||||
import Slider from '@vueform/slider';
|
||||
import Multiselect from '@vueform/multiselect';
|
||||
import FilterNameSort from '@/components/dialogs/compendium-browser/filters/FilterNameSort.vue';
|
||||
// Helper methods.
|
||||
import {
|
||||
getPackIndex,
|
||||
|
@ -197,6 +179,7 @@ export default {
|
|||
components: {
|
||||
Slider,
|
||||
Multiselect,
|
||||
FilterNameSort,
|
||||
},
|
||||
setup() {
|
||||
return {
|
||||
|
@ -226,13 +209,15 @@ export default {
|
|||
totalRows: 0,
|
||||
},
|
||||
// Sorting.
|
||||
sortBy: 'name',
|
||||
direction: 'asc',
|
||||
sortOptions: [
|
||||
{ value: 'name', label: game.i18n.localize('Name') },
|
||||
{ value: 'cr', label: game.i18n.localize('Challenge Rating') },
|
||||
{ value: 'size', label: game.i18n.localize('Size') },
|
||||
],
|
||||
sorts: {
|
||||
sortBy: 'name',
|
||||
direction: 'asc',
|
||||
sortOptions: [
|
||||
{ value: 'name', label: game.i18n.localize('Name') },
|
||||
{ value: 'cr', label: game.i18n.localize('Challenge Rating') },
|
||||
{ value: 'size', label: game.i18n.localize('Size') },
|
||||
],
|
||||
},
|
||||
// Our list of pseudo documents returned from the compendium.
|
||||
packIndex: [],
|
||||
// Filters.
|
||||
|
@ -279,8 +264,8 @@ export default {
|
|||
* Click event to reset our filters.
|
||||
*/
|
||||
resetFilters() {
|
||||
this.sortBy = 'name';
|
||||
this.direction = 'asc';
|
||||
this.sorts.sortBy = 'name';
|
||||
this.sorts.direction = 'asc';
|
||||
this.name = '';
|
||||
this.crRange = [0, 30];
|
||||
this.legact = '';
|
||||
|
@ -292,10 +277,6 @@ export default {
|
|||
this.size = [];
|
||||
this.creatureType = [];
|
||||
},
|
||||
changeDirection() {
|
||||
if (this.direction === "asc") this.direction = "desc";
|
||||
else this.direction = "asc";
|
||||
},
|
||||
/**
|
||||
* Get multiselect options.
|
||||
*/
|
||||
|
@ -386,7 +367,7 @@ export default {
|
|||
// Sort.
|
||||
result = result.sort((a, b) => {
|
||||
// Add sorts here.
|
||||
switch (this.sortBy) {
|
||||
switch (this.sorts.sortBy) {
|
||||
case 'cr':
|
||||
return a.system.details.cr - b.system.details.cr;
|
||||
case 'size':
|
||||
|
@ -394,7 +375,7 @@ export default {
|
|||
}
|
||||
return a.name.localeCompare(b.name);
|
||||
});
|
||||
if (this.direction === "desc") {
|
||||
if (this.sorts.direction === "desc") {
|
||||
result = result.reverse();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
<template>
|
||||
<div class="filtercontainer">
|
||||
<!-- Name filter. -->
|
||||
<div class="filter">
|
||||
<input type="text" name="compendiumBrowser.name" v-model="value" :placeholder="game.i18n.localize('Name')" />
|
||||
</div>
|
||||
|
||||
<!-- Sort -->
|
||||
<div class="form-group">
|
||||
<label>{{ game.i18n.localize('Sort by:') }}</label>
|
||||
<div class="form-fields">
|
||||
<select class="sort" v-model="filters.sortBy">
|
||||
<option v-for="(option, index) in filters.sortOptions" :key="index" :value="option.value">{{ option.label }}</option>
|
||||
</select>
|
||||
<a class="direction" data-direction="asc" @click="changeDirection()">
|
||||
<i v-if="filters.direction === 'asc'" class="fa-solid fa-sort-numeric-up"></i>
|
||||
<i v-else class="fa-solid fa-sort-numeric-down-alt"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'FilterNameSort',
|
||||
// Use a modelValue prop and emit to allow v-model on this component.
|
||||
// The name input itself will use a computed property named value that
|
||||
// has both a getter and setter which are automatically triggered by
|
||||
// v-model.
|
||||
props: ['modelValue','filters'],
|
||||
emits: ['update:modelValue'],
|
||||
components: {},
|
||||
setup() {
|
||||
return {
|
||||
// Expose Foundry globals to the template.
|
||||
CONFIG,
|
||||
game
|
||||
}
|
||||
},
|
||||
data() {},
|
||||
methods: {
|
||||
// updateValue(event) {
|
||||
// this.valueMutable = event.target.value;
|
||||
// console.log(event.target.value);
|
||||
// this.$emit('update:value', event.target.value);
|
||||
// },
|
||||
changeDirection() {
|
||||
if (this.filters.direction === "asc") this.filters.direction = "desc";
|
||||
else this.filters.direction = "asc";
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
value: {
|
||||
// Retrieve the internal value.
|
||||
get() {
|
||||
return this.modelValue;
|
||||
},
|
||||
// In addition to setting the internal value,
|
||||
// emit the new value to the parent.
|
||||
set(value) {
|
||||
this.$emit('update:modelValue', value);
|
||||
}
|
||||
}
|
||||
},
|
||||
async created() {},
|
||||
async mounted() {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
Loading…
Reference in New Issue