aboutsummaryrefslogtreecommitdiff
path: root/viewer/src/components/LdTagInput.vue
diff options
context:
space:
mode:
Diffstat (limited to 'viewer/src/components/LdTagInput.vue')
-rw-r--r--viewer/src/components/LdTagInput.vue75
1 files changed, 9 insertions, 66 deletions
diff --git a/viewer/src/components/LdTagInput.vue b/viewer/src/components/LdTagInput.vue
index eff02e6..982abe4 100644
--- a/viewer/src/components/LdTagInput.vue
+++ b/viewer/src/components/LdTagInput.vue
@@ -19,7 +19,7 @@
19 19
20<template> 20<template>
21 <b-taginput 21 <b-taginput
22 v-model="$uiStore.currentTags" 22 v-model="model"
23 :placeholder="$t('tagInput.placeholder')" 23 :placeholder="$t('tagInput.placeholder')"
24 autocomplete 24 autocomplete
25 ellipsis 25 ellipsis
@@ -30,8 +30,6 @@
30 size="is-medium" 30 size="is-medium"
31 class="paneltag-input" 31 class="paneltag-input"
32 @typing="searchTags" 32 @typing="searchTags"
33 @add="onAdd"
34 @remove="onRemove"
35 > 33 >
36 <template slot-scope="props">{{displayOption(props.option)}}</template> 34 <template slot-scope="props">{{displayOption(props.option)}}</template>
37 <template slot="empty">{{$t('tagInput.nomatch')}}</template> 35 <template slot="empty">{{$t('tagInput.nomatch')}}</template>
@@ -39,80 +37,25 @@
39</template> 37</template>
40 38
41<script lang="ts"> 39<script lang="ts">
42import { Component, Vue } from "vue-property-decorator"; 40import { Component, Vue, Model, Prop } from "vue-property-decorator";
43import { Operation } from "@/@types/Operation"; 41import { Operation } from "@/@types/Operation";
44import Tools from "@/tools"; 42import Navigation from "@/services/navigation";
43import IndexFactory from "../services/indexfactory";
45 44
46@Component 45@Component
47export default class LdTagInput extends Vue { 46export default class LdTagInput extends Vue {
48 filteredTags: Tag.Search[] = []; 47 @Prop({ required: true }) readonly tagsIndex!: Tag.Index;
49 48 @Model() model!: Tag.Search[];
50 onAdd(e: any) {
51 this.$uiStore.mode = "search";
52 }
53 49
54 onRemove() { 50 filteredTags: Tag.Search[] = [];
55 if (this.$uiStore.currentTags.length === 0) this.$uiStore.mode = "navigation";
56 }
57 51
58 displayOption(option: Tag.Search): string { 52 displayOption(option: Tag.Search): string {
59 return `${option.display} (${option.items.length})`; 53 return `${option.display} (${option.items.length})`;
60 } 54 }
61 55
62 extractOperation(filter: string): Operation {
63 const first = filter.slice(0, 1);
64 switch (first) {
65 case Operation.ADDITION:
66 case Operation.SUBSTRACTION:
67 return first;
68 default:
69 return Operation.INTERSECTION;
70 }
71 }
72
73 searchTags(filter: string) { 56 searchTags(filter: string) {
74 const tags = this.$galleryStore.tags; 57 this.filteredTags = IndexFactory.searchTags(this.tagsIndex, filter)
75 let search: Tag.Search[] = []; 58 .filter(newSearch => !this.model.find(currentSearch => currentSearch.tag === newSearch.tag))
76 if (tags && filter) {
77 const operation = this.extractOperation(filter);
78 if (operation !== Operation.INTERSECTION) filter = filter.slice(1);
79 if (filter.includes(":")) {
80 const filterParts = filter.split(":");
81 search = this.searchTagsFromFilterWithCategory(tags, operation, filterParts[0], filterParts[1]);
82 } else {
83 search = this.searchTagsFromFilter(tags, operation, filter);
84 }
85 }
86 this.filteredTags = this.cleanupAndSort(search);
87 }
88
89 searchTagsFromFilterWithCategory(
90 tags: Tag.Index,
91 operation: Operation,
92 category: string,
93 disambiguation: string
94 ): Tag.Search[] {
95 disambiguation = Tools.normalize(disambiguation);
96 return Object.values(tags)
97 .filter(node => node.tag.includes(category))
98 .flatMap(node =>
99 Object.values(node.children)
100 .filter(child => child.tagfiltered.includes(disambiguation))
101 .map(child => ({ ...child, parent: node, operation, display: `${operation}${node.tag}:${child.tag}` }))
102 );
103 }
104
105 searchTagsFromFilter(tags: Tag.Index, operation: Operation, filter: string): Tag.Search[] {
106 filter = Tools.normalize(filter);
107 return Object.values(tags)
108 .filter(node => node.tagfiltered.includes(filter))
109 .map(node => ({ ...node, operation, display: `${operation}${node.tag}` }));
110 }
111
112 cleanupAndSort(search: Tag.Search[]): Tag.Search[] {
113 const currentTags = this.$uiStore.currentTags;
114 return search
115 .filter(node => !currentTags.find(currentTag => currentTag.tag === node.tag))
116 .sort((a, b) => b.items.length - a.items.length); 59 .sort((a, b) => b.items.length - a.items.length);
117 } 60 }
118} 61}