traxxx/assets/components/alerts/search.vue

127 lines
2.0 KiB
Vue

<template>
<div>
<input
ref="input"
v-model="query"
:placeholder="label || `Search ${content}`"
class="input"
@input="search"
>
<ul
v-if="results.length > 0"
class="nolist"
>
<li
v-for="actor in results"
:key="`actor-${actor.id}`"
class="result"
@click="selectResult(actor)"
><img
v-if="actor.avatar"
:src="getPath(actor.avatar)"
class="avatar"
>{{ actor.name }}</li>
</ul>
</div>
</template>
<script>
async function search() {
if (this.content === 'actors') {
this.results = await this.$store.dispatch('searchActors', {
query: this.query,
minLength: 1,
limit: 10,
});
}
if (this.content === 'entities') {
this.results = await this.$store.dispatch('searchEntities', {
query: this.query,
limit: 10,
});
}
if (this.content === 'tags') {
this.results = await this.$store.dispatch('searchTags', {
query: this.query,
minLength: 1,
limit: 10,
});
}
if (this.content === 'stashes') {
this.results = this.$store.state.auth.user.stashes.filter(stash => new RegExp(this.query).test(stash.name));
}
}
function selectResult(item) {
this.query = null;
this.results = [];
this.$emit('select', item);
}
async function mounted() {
this.$refs.input.focus();
if (this.defaults.length > 0 && this.content === 'tags') {
this.results = await this.$store.dispatch('fetchTags', {
slugs: this.defaults,
});
}
if (this.content === 'stashes') {
this.results = this.$store.state.auth.user.stashes;
}
}
export default {
props: {
content: {
type: String,
default: null,
},
defaults: {
type: Array,
default: () => [],
},
label: {
type: String,
default: null,
},
},
data() {
return {
query: null,
results: [],
};
},
emits: ['select'],
mounted,
methods: {
search,
selectResult,
},
};
</script>
<style lang="scss" scoped>
.result {
display: flex;
align-items: center;
padding: .5rem;
&:hover {
color: var(--primary);
cursor: pointer;
}
}
.avatar {
height: 2rem;
margin: 0 .5rem 0 0;
}
</style>