aboutsummaryrefslogtreecommitdiff
path: root/viewer/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'viewer/src/components')
-rw-r--r--viewer/src/components/LdProposition.vue52
-rw-r--r--viewer/src/components/LdTagInput.vue9
2 files changed, 43 insertions, 18 deletions
diff --git a/viewer/src/components/LdProposition.vue b/viewer/src/components/LdProposition.vue
index 3357777..c69a7c3 100644
--- a/viewer/src/components/LdProposition.vue
+++ b/viewer/src/components/LdProposition.vue
@@ -19,8 +19,9 @@
19--> 19-->
20 20
21<template> 21<template>
22 <div> 22 <div class="proposition">
23 <div v-for="proposed in proposedTags" :key="proposed.rawTag" class="proposition"> 23 <h2 v-if="showCategory && proposedTags.length" class="subtitle category">{{title}}</h2>
24 <div v-for="proposed in proposedTags" :key="proposed.rawTag">
24 <a 25 <a
25 class="operation-btns link" 26 class="operation-btns link"
26 :title="$t('tag-propositions.substraction')" 27 :title="$t('tag-propositions.substraction')"
@@ -54,6 +55,8 @@ import { Operation } from "@/@types/Operation";
54 55
55@Component 56@Component
56export default class LdProposition extends Vue { 57export default class LdProposition extends Vue {
58 @Prop() readonly category?: Tag.Node;
59 @Prop({ type: Boolean, required: true }) readonly showCategory!: boolean;
57 @Prop({ type: Array, required: true }) readonly currentTags!: string[]; 60 @Prop({ type: Array, required: true }) readonly currentTags!: string[];
58 @Prop({ required: true }) readonly tagsIndex!: Tag.Index; 61 @Prop({ required: true }) readonly tagsIndex!: Tag.Index;
59 @PropSync("searchFilters", { type: Array, required: true }) model!: Tag.Search[]; 62 @PropSync("searchFilters", { type: Array, required: true }) model!: Tag.Search[];
@@ -69,13 +72,14 @@ export default class LdProposition extends Vue {
69 this.extractDistinctItems(this.model) 72 this.extractDistinctItems(this.model)
70 .flatMap(item => item.tags) 73 .flatMap(item => item.tags)
71 .map(this.rightmost) 74 .map(this.rightmost)
72 .filter(rawTag => !this.model.find(search => search.tag === rawTag)) 75 .filter(rawTag => this.tagsIndex[rawTag] && !this.model.find(search => search.tag === rawTag))
73 .forEach(rawTag => (propositions[rawTag] = (propositions[rawTag] ?? 0) + 1)); 76 .forEach(rawTag => (propositions[rawTag] = (propositions[rawTag] ?? 0) + 1));
74 } else { 77 } else {
75 // Tags count from the current directory 78 // Tags count from the current directory
76 this.currentTags 79 this.currentTags
77 .flatMap(tag => tag.split(":")) 80 .flatMap(tag => tag.split(":"))
78 .map(tag => this.tagsIndex[tag]) 81 .map(tag => this.tagsIndex[tag])
82 .filter(Boolean)
79 .forEach(tagindex => (propositions[tagindex.tag] = tagindex.items.length)); 83 .forEach(tagindex => (propositions[tagindex.tag] = tagindex.items.length));
80 } 84 }
81 85
@@ -84,6 +88,10 @@ export default class LdProposition extends Vue {
84 .map(entry => ({ rawTag: entry[0], count: entry[1] })); 88 .map(entry => ({ rawTag: entry[0], count: entry[1] }));
85 } 89 }
86 90
91 get title() {
92 return this.category?.tag ?? this.$t("panelLeft.propositions.other");
93 }
94
87 extractDistinctItems(currentTags: Tag.Search[]): Gallery.Item[] { 95 extractDistinctItems(currentTags: Tag.Search[]): Gallery.Item[] {
88 return [...new Set(currentTags.flatMap(tag => tag.items))]; 96 return [...new Set(currentTags.flatMap(tag => tag.items))];
89 } 97 }
@@ -95,8 +103,8 @@ export default class LdProposition extends Vue {
95 103
96 add(operation: Operation, rawTag: Gallery.RawTag) { 104 add(operation: Operation, rawTag: Gallery.RawTag) {
97 const node = this.tagsIndex[rawTag]; 105 const node = this.tagsIndex[rawTag];
98 const search: Tag.Search = { ...node, operation, display: `${operation}${node.tag}` }; 106 const display = this.category ? `${operation}${this.category.tag}:${node.tag}` : `${operation}${node.tag}`;
99 this.model.push(search); 107 this.model.push({ ...node, parent: this.category, operation, display });
100 } 108 }
101} 109}
102</script> 110</script>
@@ -105,19 +113,29 @@ export default class LdProposition extends Vue {
105@import "@/assets/scss/theme.scss"; 113@import "@/assets/scss/theme.scss";
106 114
107.proposition { 115.proposition {
108 display: flex; 116 .subtitle {
109 align-items: center; 117 background-color: $proposed-category-bgcolor;
110 padding-right: 7px; 118 width: 100%;
111 .operation-tag { 119 padding: 0 0 6px 0;
112 text-overflow: ellipsis; 120 margin: 0;
113 white-space: nowrap; 121 text-align: center;
114 overflow: hidden; 122 font-variant: small-caps;
115 flex-grow: 1;
116 cursor: pointer;
117 } 123 }
118 .operation-btns { 124 > div {
119 padding: 2px 7px; 125 display: flex;
120 cursor: pointer; 126 align-items: center;
127 padding-right: 7px;
128 .operation-tag {
129 text-overflow: ellipsis;
130 white-space: nowrap;
131 overflow: hidden;
132 flex-grow: 1;
133 cursor: pointer;
134 }
135 .operation-btns {
136 padding: 2px 7px;
137 cursor: pointer;
138 }
121 } 139 }
122} 140}
123</style> 141</style>
diff --git a/viewer/src/components/LdTagInput.vue b/viewer/src/components/LdTagInput.vue
index b1b9e3e..6b6e749 100644
--- a/viewer/src/components/LdTagInput.vue
+++ b/viewer/src/components/LdTagInput.vue
@@ -57,10 +57,17 @@ export default class LdTagInput extends Vue {
57 return `${option.display} (${option.items.length})`; 57 return `${option.display} (${option.items.length})`;
58 } 58 }
59 59
60 filterAlreadyPresent(newSearch: Tag.Search) {
61 return !this.model.find(
62 currentSearch =>
63 currentSearch.tag === newSearch.tag && (!currentSearch.parent || currentSearch.parent === newSearch.parent)
64 );
65 }
66
60 searchTags(filter: string) { 67 searchTags(filter: string) {
61 this.currentFilter = filter; 68 this.currentFilter = filter;
62 this.filteredTags = IndexFactory.searchTags(this.tagsIndex, filter, false) 69 this.filteredTags = IndexFactory.searchTags(this.tagsIndex, filter, false)
63 .filter(newSearch => !this.model.find(currentSearch => currentSearch.tag === newSearch.tag)) 70 .filter(this.filterAlreadyPresent)
64 .sort((a, b) => b.items.length - a.items.length); 71 .sort((a, b) => b.items.length - a.items.length);
65 } 72 }
66 73