aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZero~Informatique2019-12-22 11:26:53 +0100
committerZero~Informatique2019-12-22 11:26:53 +0100
commit06c4d9299bb684805051355555fa89f0d440d194 (patch)
tree42bb1ac1fdcd44ba1edeef65fa94239fcf53fc77
parentdc251fffc2998f1cf4f8e9631928c4b92ac0d90e (diff)
downloadldgallery-06c4d9299bb684805051355555fa89f0d440d194.tar.gz
viewer: Implemented tag category and disambiguation filtering
-rw-r--r--viewer/src/@types/tag/index.d.ts4
-rw-r--r--viewer/src/components/LdTagInput.vue52
-rw-r--r--viewer/src/plugins/fontawesome.ts4
3 files changed, 48 insertions, 12 deletions
diff --git a/viewer/src/@types/tag/index.d.ts b/viewer/src/@types/tag/index.d.ts
index 6a027d4..30bbebb 100644
--- a/viewer/src/@types/tag/index.d.ts
+++ b/viewer/src/@types/tag/index.d.ts
@@ -4,5 +4,9 @@ declare namespace Tag {
4 items: Gallery.Item[]; 4 items: Gallery.Item[];
5 children: Index; 5 children: Index;
6 } 6 }
7 interface NodeWithParent extends Node {
8 parent: Node;
9 }
10 type Search = Node | NodeWithParent;
7 type Index = { [index: string]: Node }; 11 type Index = { [index: string]: Node };
8} \ No newline at end of file 12} \ No newline at end of file
diff --git a/viewer/src/components/LdTagInput.vue b/viewer/src/components/LdTagInput.vue
index 4edc1ce..4121cd7 100644
--- a/viewer/src/components/LdTagInput.vue
+++ b/viewer/src/components/LdTagInput.vue
@@ -3,14 +3,16 @@
3 v-model="$uiStore.currentTags" 3 v-model="$uiStore.currentTags"
4 :placeholder="$t('tagInput.placeholder')" 4 :placeholder="$t('tagInput.placeholder')"
5 autocomplete 5 autocomplete
6 ellipsis
7 attached
6 :data="filteredTags" 8 :data="filteredTags"
7 field="tag" 9 field="tag"
8 type="is-black" 10 type="is-black"
9 size="is-large" 11 icon="tag"
10 class="panelTagInput" 12 class="panelTagInput"
11 @typing="getFilteredTags" 13 @typing="searchTags"
12 > 14 >
13 <template slot-scope="props">{{props.option.tag}} ({{props.option.items.length}})</template> 15 <template slot-scope="props">{{displayOption(props.option)}}</template>
14 <template slot="empty">{{$t('tagInput.nomatch')}}</template> 16 <template slot="empty">{{$t('tagInput.nomatch')}}</template>
15 </b-taginput> 17 </b-taginput>
16</template> 18</template>
@@ -20,15 +22,45 @@ import { Component, Vue } from "vue-property-decorator";
20 22
21@Component 23@Component
22export default class LdTagInput extends Vue { 24export default class LdTagInput extends Vue {
23 filteredTags: Tag.Node[] = []; 25 filteredTags: Tag.Search[] = [];
24 26
25 getFilteredTags(filter: string) { 27 displayOption(option: Tag.Search): string {
28 return `${option.tag} (${option.items.length})`;
29 }
30
31 searchTags(filter: string) {
26 const tags = this.$galleryStore.tags; 32 const tags = this.$galleryStore.tags;
27 if (tags && filter) 33 let search: Tag.Search[] = [];
28 this.filteredTags = Object.values(tags) 34 if (tags && filter) {
29 .filter(node => node.tag.includes(filter)) 35 if (filter.includes(":")) {
30 .sort((a, b) => b.items.length - a.items.length); 36 const filterParts = filter.split(":");
31 else this.filteredTags = []; 37 search = this.searchTagsFromFilterWithCategory(tags, filterParts[0], filterParts[1]);
38 } else {
39 search = this.searchTagsFromFilter(tags, filter);
40 }
41 }
42 this.filteredTags = this.cleanupAndSort(search);
43 }
44
45 searchTagsFromFilterWithCategory(tags: Tag.Index, category: string, disambiguation: string): Tag.NodeWithParent[] {
46 return Object.values(tags)
47 .filter(node => node.tag.includes(category))
48 .flatMap(node =>
49 Object.values(node.children)
50 .filter(child => child.tag.includes(disambiguation))
51 .map(child => ({ ...child, parent: node, tag: `${node.tag}:${child.tag}` }))
52 );
53 }
54
55 searchTagsFromFilter(tags: Tag.Index, filter: string): Tag.Node[] {
56 return Object.values(tags).filter(node => node.tag.includes(filter));
57 }
58
59 cleanupAndSort(search: Tag.Search[]): Tag.Search[] {
60 const currentTags = this.$uiStore.currentTags;
61 return search
62 .filter(node => !currentTags.find(currentTag => currentTag.tag === node.tag))
63 .sort((a, b) => b.items.length - a.items.length);
32 } 64 }
33} 65}
34</script> 66</script>
diff --git a/viewer/src/plugins/fontawesome.ts b/viewer/src/plugins/fontawesome.ts
index 3af77b6..e129c57 100644
--- a/viewer/src/plugins/fontawesome.ts
+++ b/viewer/src/plugins/fontawesome.ts
@@ -1,9 +1,9 @@
1import Vue from "vue"; 1import Vue from "vue";
2 2
3import { library } from "@fortawesome/fontawesome-svg-core"; 3import { library } from "@fortawesome/fontawesome-svg-core";
4import { faExpandArrowsAlt, faFolder, faSearch } from "@fortawesome/free-solid-svg-icons"; 4import { faExpandArrowsAlt, faFolder, faSearch, faTag } from "@fortawesome/free-solid-svg-icons";
5import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; 5import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
6 6
7library.add(faExpandArrowsAlt, faFolder, faSearch); 7library.add(faExpandArrowsAlt, faFolder, faSearch, faTag);
8 8
9Vue.component("fa-icon", FontAwesomeIcon); 9Vue.component("fa-icon", FontAwesomeIcon);