aboutsummaryrefslogtreecommitdiff
path: root/viewer/src/components/LdProposition.vue
diff options
context:
space:
mode:
authorZero~Informatique2019-12-28 04:52:30 +0100
committerZero~Informatique2019-12-28 04:53:01 +0100
commita681accaa7617892bb7c53248aa9030a4eb47f50 (patch)
tree0d04aee1ef36ffaae1b0fac0a61ef7dad8d38e7c /viewer/src/components/LdProposition.vue
parentdeaed8a6737edc6e28c08e9c6734dde6e37a4016 (diff)
downloadldgallery-a681accaa7617892bb7c53248aa9030a4eb47f50.tar.gz
viewer: Tag propositions. Disabled directory indexation.
Note: The propositions are not based on the current search results, but on the searched tags, which doesn't seem to be the correct way. We'll probably have to move the search results to a store for global visibility.
Diffstat (limited to 'viewer/src/components/LdProposition.vue')
-rw-r--r--viewer/src/components/LdProposition.vue75
1 files changed, 75 insertions, 0 deletions
diff --git a/viewer/src/components/LdProposition.vue b/viewer/src/components/LdProposition.vue
new file mode 100644
index 0000000..b23c14a
--- /dev/null
+++ b/viewer/src/components/LdProposition.vue
@@ -0,0 +1,75 @@
1<template>
2 <div>
3 <div v-for="proposed in proposedTags" :key="proposed.rawTag" class="proposition">
4 <fa-icon icon="minus" @click="add(Operation.SUBSTRACTION, proposed.rawTag)" />
5 <span
6 @click="add(Operation.INTERSECTION, proposed.rawTag)"
7 >{{proposed.rawTag}}&nbsp;x{{proposed.count}}</span>
8 <fa-icon icon="plus" @click="add(Operation.ADDITION, proposed.rawTag)" />
9 </div>
10 </div>
11</template>
12
13<script lang="ts">
14import { Component, Vue } from "vue-property-decorator";
15import { Operation } from "@/@types/tag/Operation";
16import Gallery from '../views/Gallery.vue';
17
18@Component
19export default class LdTagInput extends Vue {
20 get Operation() {
21 return Operation;
22 }
23
24 get proposedTags() {
25 const currentTags = this.$uiStore.currentTags;
26 let propositions: { [index: string]: number } = {};
27 if (currentTags.length > 0) {
28 // Tags count from current search
29 this.extractDistinctItems(currentTags)
30 .flatMap(item => item.tags)
31 .map(this.rightmost)
32 .filter(rawTag => !currentTags.find(currentTag => currentTag.tag === rawTag))
33 .forEach(rawTag => (propositions[rawTag] = (propositions[rawTag] ?? 0) + 1));
34 } else {
35 // Tags count from the whole gallery
36 Object.entries(this.$galleryStore.tags)
37 .forEach(entry => (propositions[entry[0]] = entry[1].items.length));
38 }
39
40 return Object.entries(propositions)
41 .sort((a,b) => b[1] - a[1])
42 .map(entry => ({rawTag: entry[0], count: entry[1]}));
43 }
44
45 extractDistinctItems(currentTags: Tag.Search[]): Gallery.Item[] {
46 return [...new Set(currentTags.flatMap(tag => tag.items))];
47 }
48
49 rightmost(tag: Gallery.RawTag): Gallery.RawTag {
50 const dot = tag.lastIndexOf(".");
51 return dot <= 0 ? tag : tag.substr(dot + 1);
52 }
53
54 add(operation: Operation, rawTag: Gallery.RawTag) {
55 const node = this.$galleryStore.tags[rawTag];
56 const search: Tag.Search = { ...node, operation, display: `${operation}${node.tag}` };
57 this.$uiStore.currentTags.push(search);
58 this.$uiStore.mode = "search";
59 }
60}
61</script>
62
63<style lang="scss">
64.proposition {
65 display: flex;
66 justify-content: space-between;
67 align-items: center;
68 margin: 10px;
69 color: lightcyan;
70 cursor: pointer;
71}
72.proposition span {
73 padding: 0 10px;
74}
75</style>