aboutsummaryrefslogtreecommitdiff
path: root/viewer/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'viewer/src/components')
-rw-r--r--viewer/src/components/LdTagInput.vue48
-rw-r--r--viewer/src/components/index.ts2
2 files changed, 41 insertions, 9 deletions
diff --git a/viewer/src/components/LdTagInput.vue b/viewer/src/components/LdTagInput.vue
index 4121cd7..daca62d 100644
--- a/viewer/src/components/LdTagInput.vue
+++ b/viewer/src/components/LdTagInput.vue
@@ -6,11 +6,14 @@
6 ellipsis 6 ellipsis
7 attached 7 attached
8 :data="filteredTags" 8 :data="filteredTags"
9 field="tag" 9 field="display"
10 type="is-black" 10 type="is-black"
11 icon="tag" 11 icon="tag"
12 size="is-medium"
12 class="panelTagInput" 13 class="panelTagInput"
13 @typing="searchTags" 14 @typing="searchTags"
15 @add="onAdd"
16 @remove="onRemove"
14 > 17 >
15 <template slot-scope="props">{{displayOption(props.option)}}</template> 18 <template slot-scope="props">{{displayOption(props.option)}}</template>
16 <template slot="empty">{{$t('tagInput.nomatch')}}</template> 19 <template slot="empty">{{$t('tagInput.nomatch')}}</template>
@@ -19,41 +22,70 @@
19 22
20<script lang="ts"> 23<script lang="ts">
21import { Component, Vue } from "vue-property-decorator"; 24import { Component, Vue } from "vue-property-decorator";
25import { Operation } from "@/@types/tag/Operation";
22 26
23@Component 27@Component
24export default class LdTagInput extends Vue { 28export default class LdTagInput extends Vue {
25 filteredTags: Tag.Search[] = []; 29 filteredTags: Tag.Search[] = [];
26 30
31 onAdd(e: any) {
32 this.$uiStore.mode = "search";
33 }
34
35 onRemove() {
36 if (this.$uiStore.currentTags.length === 0) this.$uiStore.mode = "navigation";
37 }
38
27 displayOption(option: Tag.Search): string { 39 displayOption(option: Tag.Search): string {
28 return `${option.tag} (${option.items.length})`; 40 return `${option.display} (${option.items.length})`;
41 }
42
43 extractOperation(filter: string) {
44 const first = filter.slice(0, 1);
45 switch (first) {
46 case Operation.ADDITION:
47 case Operation.SUBSTRACTION:
48 return first;
49 default:
50 return Operation.INTERSECTION;
51 }
29 } 52 }
30 53
31 searchTags(filter: string) { 54 searchTags(filter: string) {
32 const tags = this.$galleryStore.tags; 55 const tags = this.$galleryStore.tags;
33 let search: Tag.Search[] = []; 56 let search: Tag.Search[] = [];
34 if (tags && filter) { 57 if (tags && filter) {
58 const operation = this.extractOperation(filter);
59 if (operation !== Operation.INTERSECTION) filter = filter.slice(1);
35 if (filter.includes(":")) { 60 if (filter.includes(":")) {
36 const filterParts = filter.split(":"); 61 const filterParts = filter.split(":");
37 search = this.searchTagsFromFilterWithCategory(tags, filterParts[0], filterParts[1]); 62 search = this.searchTagsFromFilterWithCategory(tags, operation, filterParts[0], filterParts[1]);
38 } else { 63 } else {
39 search = this.searchTagsFromFilter(tags, filter); 64 search = this.searchTagsFromFilter(tags, operation, filter);
40 } 65 }
41 } 66 }
42 this.filteredTags = this.cleanupAndSort(search); 67 this.filteredTags = this.cleanupAndSort(search);
43 } 68 }
44 69
45 searchTagsFromFilterWithCategory(tags: Tag.Index, category: string, disambiguation: string): Tag.NodeWithParent[] { 70 searchTagsFromFilterWithCategory(
71 tags: Tag.Index,
72 operation: Operation,
73 category: string,
74 disambiguation: string
75 ): Tag.Search[] {
46 return Object.values(tags) 76 return Object.values(tags)
47 .filter(node => node.tag.includes(category)) 77 .filter(node => node.tag.includes(category))
48 .flatMap(node => 78 .flatMap(node =>
49 Object.values(node.children) 79 Object.values(node.children)
50 .filter(child => child.tag.includes(disambiguation)) 80 .filter(child => child.tag.includes(disambiguation))
51 .map(child => ({ ...child, parent: node, tag: `${node.tag}:${child.tag}` })) 81 .map(child => ({ ...child, parent: node, operation, display: `${operation}${node.tag}:${child.tag}` }))
52 ); 82 );
53 } 83 }
54 84
55 searchTagsFromFilter(tags: Tag.Index, filter: string): Tag.Node[] { 85 searchTagsFromFilter(tags: Tag.Index, operation: Operation, filter: string): Tag.Search[] {
56 return Object.values(tags).filter(node => node.tag.includes(filter)); 86 return Object.values(tags)
87 .filter(node => node.tag.includes(filter))
88 .map(node => ({ ...node, operation, display: `${operation}${node.tag}` }));
57 } 89 }
58 90
59 cleanupAndSort(search: Tag.Search[]): Tag.Search[] { 91 cleanupAndSort(search: Tag.Search[]): Tag.Search[] {
diff --git a/viewer/src/components/index.ts b/viewer/src/components/index.ts
index 1406b34..4586f62 100644
--- a/viewer/src/components/index.ts
+++ b/viewer/src/components/index.ts
@@ -17,6 +17,6 @@ requireComponent.keys().forEach(fileName => {
17 // Look for the component options on `.default`, which will 17 // Look for the component options on `.default`, which will
18 // exist if the component was exported with `export default`, 18 // exist if the component was exported with `export default`,
19 // otherwise fall back to module's root. 19 // otherwise fall back to module's root.
20 componentConfig.default || componentConfig 20 componentConfig.default ?? componentConfig
21 ) 21 )
22}) \ No newline at end of file 22}) \ No newline at end of file