diff options
author | Notkea | 2020-01-10 22:31:47 +0100 |
---|---|---|
committer | GitHub | 2020-01-10 22:31:47 +0100 |
commit | 7042ffc06326fa8ffe70f5a59747709250166c16 (patch) | |
tree | dbfc7567bd106e03a47b499d2a07cecb6b8d6305 /viewer/src/components/LdProposition.vue | |
parent | c9264b0a0a7e1cb92ef7d9a391cee2c94376cff3 (diff) | |
parent | 27b51018525dbb7a6edb3073819d82245387ddd3 (diff) | |
download | ldgallery-7042ffc06326fa8ffe70f5a59747709250166c16.tar.gz |
Merge pull request #34 from pacien/develop
first working prototype
Diffstat (limited to 'viewer/src/components/LdProposition.vue')
-rw-r--r-- | viewer/src/components/LdProposition.vue | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/viewer/src/components/LdProposition.vue b/viewer/src/components/LdProposition.vue new file mode 100644 index 0000000..9a32e0a --- /dev/null +++ b/viewer/src/components/LdProposition.vue | |||
@@ -0,0 +1,93 @@ | |||
1 | <!-- ldgallery - A static generator which turns a collection of tagged | ||
2 | -- pictures into a searchable web gallery. | ||
3 | -- | ||
4 | -- Copyright (C) 2019-2020 Guillaume FOUET | ||
5 | -- | ||
6 | -- This program is free software: you can redistribute it and/or modify | ||
7 | -- it under the terms of the GNU Affero General Public License as | ||
8 | -- published by the Free Software Foundation, either version 3 of the | ||
9 | -- License, or (at your option) any later version. | ||
10 | -- | ||
11 | -- This program is distributed in the hope that it will be useful, | ||
12 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | -- GNU Affero General Public License for more details. | ||
15 | -- | ||
16 | -- You should have received a copy of the GNU Affero General Public License | ||
17 | -- along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
18 | --> | ||
19 | |||
20 | <template> | ||
21 | <div> | ||
22 | <div v-for="proposed in proposedTags" :key="proposed.rawTag" class="proposition"> | ||
23 | <fa-icon icon="minus" @click="add(Operation.SUBSTRACTION, proposed.rawTag)" /> | ||
24 | <span | ||
25 | @click="add(Operation.INTERSECTION, proposed.rawTag)" | ||
26 | >{{proposed.rawTag}} x{{proposed.count}}</span> | ||
27 | <fa-icon icon="plus" @click="add(Operation.ADDITION, proposed.rawTag)" /> | ||
28 | </div> | ||
29 | </div> | ||
30 | </template> | ||
31 | |||
32 | <script lang="ts"> | ||
33 | import { Component, Vue } from "vue-property-decorator"; | ||
34 | import { Operation } from "@/@types/tag/Operation"; | ||
35 | |||
36 | @Component | ||
37 | export default class LdTagInput extends Vue { | ||
38 | get Operation() { | ||
39 | return Operation; | ||
40 | } | ||
41 | |||
42 | get proposedTags() { | ||
43 | const currentTags = this.$uiStore.currentTags; | ||
44 | let propositions: { [index: string]: number } = {}; | ||
45 | if (currentTags.length > 0) { | ||
46 | // Tags count from current search | ||
47 | this.extractDistinctItems(currentTags) | ||
48 | .flatMap(item => item.tags) | ||
49 | .map(this.rightmost) | ||
50 | .filter(rawTag => !currentTags.find(currentTag => currentTag.tag === rawTag)) | ||
51 | .forEach(rawTag => (propositions[rawTag] = (propositions[rawTag] ?? 0) + 1)); | ||
52 | } else { | ||
53 | // Tags count from the whole gallery | ||
54 | Object.entries(this.$galleryStore.tags) | ||
55 | .forEach(entry => (propositions[entry[0]] = entry[1].items.length)); | ||
56 | } | ||
57 | |||
58 | return Object.entries(propositions) | ||
59 | .sort((a,b) => b[1] - a[1]) | ||
60 | .map(entry => ({rawTag: entry[0], count: entry[1]})); | ||
61 | } | ||
62 | |||
63 | extractDistinctItems(currentTags: Tag.Search[]): Gallery.Item[] { | ||
64 | return [...new Set(currentTags.flatMap(tag => tag.items))]; | ||
65 | } | ||
66 | |||
67 | rightmost(tag: Gallery.RawTag): Gallery.RawTag { | ||
68 | const dot = tag.lastIndexOf("."); | ||
69 | return dot <= 0 ? tag : tag.substr(dot + 1); | ||
70 | } | ||
71 | |||
72 | add(operation: Operation, rawTag: Gallery.RawTag) { | ||
73 | const node = this.$galleryStore.tags[rawTag]; | ||
74 | const search: Tag.Search = { ...node, operation, display: `${operation}${node.tag}` }; | ||
75 | this.$uiStore.currentTags.push(search); | ||
76 | this.$uiStore.mode = "search"; | ||
77 | } | ||
78 | } | ||
79 | </script> | ||
80 | |||
81 | <style lang="scss"> | ||
82 | .proposition { | ||
83 | display: flex; | ||
84 | justify-content: space-between; | ||
85 | align-items: center; | ||
86 | margin: 10px; | ||
87 | color: lightcyan; | ||
88 | cursor: pointer; | ||
89 | } | ||
90 | .proposition span { | ||
91 | padding: 0 10px; | ||
92 | } | ||
93 | </style> | ||