aboutsummaryrefslogtreecommitdiff
path: root/viewer/src
diff options
context:
space:
mode:
Diffstat (limited to 'viewer/src')
-rw-r--r--viewer/src/@types/tag.d.ts40
-rw-r--r--viewer/src/components/LdProposition.vue9
-rw-r--r--viewer/src/components/LdTagInput.vue11
-rw-r--r--viewer/src/services/indexfactory.ts29
-rw-r--r--viewer/src/services/indexsearch.ts13
-rw-r--r--viewer/src/store/galleryStore.ts13
-rw-r--r--viewer/src/views/PanelLeft.vue3
7 files changed, 62 insertions, 56 deletions
diff --git a/viewer/src/@types/tag.d.ts b/viewer/src/@types/tag.d.ts
index bb908d3..9ed2c04 100644
--- a/viewer/src/@types/tag.d.ts
+++ b/viewer/src/@types/tag.d.ts
@@ -17,25 +17,25 @@
17-- along with this program. If not, see <https://www.gnu.org/licenses/>. 17-- along with this program. If not, see <https://www.gnu.org/licenses/>.
18*/ 18*/
19 19
20declare namespace Tag { 20import { Item, RawTag } from "./gallery";
21 interface Node {
22 tag: RawTag;
23 tagfiltered: RawTag;
24 rootPart: boolean;
25 childPart: boolean;
26 items: Item[];
27 children: Index;
28 }
29 interface Search extends Node {
30 parent?: Node;
31 operation: string; // Enum Operation
32 display: string;
33 }
34 type SearchByOperation = Record<string, Tag.Search[]>;
35 type Index = Record<string, Node>;
36 21
37 interface Category { 22export interface TagNode {
38 tag: string; 23 tag: RawTag;
39 index: Index; 24 tagfiltered: RawTag;
40 } 25 rootPart: boolean;
26 childPart: boolean;
27 items: Item[];
28 children: TagIndex;
29}
30export interface TagSearch extends TagNode {
31 parent?: TagNode;
32 operation: string; // Enum Operation
33 display: string;
34}
35export type TagSearchByOperation = Record<string, TagSearch[]>;
36export type TagIndex = Record<string, TagNode>;
37
38export interface TagCategory {
39 tag: string;
40 index: TagIndex;
41} 41}
diff --git a/viewer/src/components/LdProposition.vue b/viewer/src/components/LdProposition.vue
index 2396d1f..088e249 100644
--- a/viewer/src/components/LdProposition.vue
+++ b/viewer/src/components/LdProposition.vue
@@ -56,15 +56,16 @@
56<script lang="ts"> 56<script lang="ts">
57import { Item, RawTag } from "@/@types/gallery"; 57import { Item, RawTag } from "@/@types/gallery";
58import { Operation } from "@/@types/Operation"; 58import { Operation } from "@/@types/Operation";
59import { TagIndex, TagNode, TagSearch } from "@/@types/tag";
59import { Component, Prop, PropSync, Vue, Watch } from "vue-property-decorator"; 60import { Component, Prop, PropSync, Vue, Watch } from "vue-property-decorator";
60 61
61@Component 62@Component
62export default class LdProposition extends Vue { 63export default class LdProposition extends Vue {
63 @Prop() readonly category?: Tag.Node; 64 @Prop() readonly category?: TagNode;
64 @Prop({ type: Boolean, required: true }) readonly showCategory!: boolean; 65 @Prop({ type: Boolean, required: true }) readonly showCategory!: boolean;
65 @Prop({ type: Array, required: true }) readonly currentTags!: string[]; 66 @Prop({ type: Array, required: true }) readonly currentTags!: string[];
66 @Prop({ required: true }) readonly tagsIndex!: Tag.Index; 67 @Prop({ required: true }) readonly tagsIndex!: TagIndex;
67 @PropSync("searchFilters", { type: Array, required: true }) model!: Tag.Search[]; 68 @PropSync("searchFilters", { type: Array, required: true }) model!: TagSearch[];
68 69
69 readonly INITIAL_TAG_DISPLAY_LIMIT = this.getInitialTagDisplayLimit(); 70 readonly INITIAL_TAG_DISPLAY_LIMIT = this.getInitialTagDisplayLimit();
70 71
@@ -119,7 +120,7 @@ export default class LdProposition extends Vue {
119 return this.category?.tag ?? this.$t("panelLeft.propositions.other"); 120 return this.category?.tag ?? this.$t("panelLeft.propositions.other");
120 } 121 }
121 122
122 extractDistinctItems(currentTags: Tag.Search[]): Item[] { 123 extractDistinctItems(currentTags: TagSearch[]): Item[] {
123 return [...new Set(currentTags.flatMap(tag => tag.items))]; 124 return [...new Set(currentTags.flatMap(tag => tag.items))];
124 } 125 }
125 126
diff --git a/viewer/src/components/LdTagInput.vue b/viewer/src/components/LdTagInput.vue
index ef585f0..855813a 100644
--- a/viewer/src/components/LdTagInput.vue
+++ b/viewer/src/components/LdTagInput.vue
@@ -40,22 +40,23 @@
40</template> 40</template>
41 41
42<script lang="ts"> 42<script lang="ts">
43import { TagIndex, TagSearch } from "@/@types/tag";
43import IndexFactory from "@/services/indexfactory"; 44import IndexFactory from "@/services/indexfactory";
44import { Component, Emit, Prop, PropSync, Vue } from "vue-property-decorator"; 45import { Component, Emit, Prop, PropSync, Vue } from "vue-property-decorator";
45 46
46@Component 47@Component
47export default class LdTagInput extends Vue { 48export default class LdTagInput extends Vue {
48 @Prop({ required: true }) readonly tagsIndex!: Tag.Index; 49 @Prop({ required: true }) readonly tagsIndex!: TagIndex;
49 @PropSync("searchFilters", { type: Array, required: true }) model!: Tag.Search[]; 50 @PropSync("searchFilters", { type: Array, required: true }) model!: TagSearch[];
50 51
51 currentFilter: string = ""; 52 currentFilter: string = "";
52 filteredTags: Tag.Search[] = []; 53 filteredTags: TagSearch[] = [];
53 54
54 displayOption(option: Tag.Search): string { 55 displayOption(option: TagSearch): string {
55 return `${option.display} (${option.items.length})`; 56 return `${option.display} (${option.items.length})`;
56 } 57 }
57 58
58 filterAlreadyPresent(newSearch: Tag.Search) { 59 filterAlreadyPresent(newSearch: TagSearch) {
59 return !this.model.find( 60 return !this.model.find(
60 currentSearch => 61 currentSearch =>
61 currentSearch.tag === newSearch.tag && (!currentSearch.parent || currentSearch.parent === newSearch.parent) 62 currentSearch.tag === newSearch.tag && (!currentSearch.parent || currentSearch.parent === newSearch.parent)
diff --git a/viewer/src/services/indexfactory.ts b/viewer/src/services/indexfactory.ts
index 0c5fdc5..691a765 100644
--- a/viewer/src/services/indexfactory.ts
+++ b/viewer/src/services/indexfactory.ts
@@ -20,17 +20,18 @@
20import { Item, RawTag } from "@/@types/gallery"; 20import { Item, RawTag } from "@/@types/gallery";
21import { ItemType } from "@/@types/ItemType"; 21import { ItemType } from "@/@types/ItemType";
22import { Operation } from "@/@types/Operation"; 22import { Operation } from "@/@types/Operation";
23import { TagCategory, TagIndex, TagNode, TagSearch } from "@/@types/tag";
23import Navigation from "@/services/navigation"; 24import Navigation from "@/services/navigation";
24 25
25export default class IndexFactory { 26export default class IndexFactory {
26 public static generateTags(root: Item | null): Tag.Index { 27 public static generateTags(root: Item | null): TagIndex {
27 const tagsIndex: Tag.Index = {}; 28 const tagsIndex: TagIndex = {};
28 if (root) IndexFactory.pushTagsForItem(tagsIndex, root); 29 if (root) IndexFactory.pushTagsForItem(tagsIndex, root);
29 return tagsIndex; 30 return tagsIndex;
30 } 31 }
31 32
32 // Pushes all tags for a root item (and its children) to the index 33 // Pushes all tags for a root item (and its children) to the index
33 private static pushTagsForItem(tagsIndex: Tag.Index, item: Item): void { 34 private static pushTagsForItem(tagsIndex: TagIndex, item: Item): void {
34 if (item.properties.type === ItemType.DIRECTORY) { 35 if (item.properties.type === ItemType.DIRECTORY) {
35 item.properties.items.forEach(item => this.pushTagsForItem(tagsIndex, item)); 36 item.properties.items.forEach(item => this.pushTagsForItem(tagsIndex, item));
36 return; // Directories are not indexed 37 return; // Directories are not indexed
@@ -50,7 +51,7 @@ export default class IndexFactory {
50 } 51 }
51 } 52 }
52 53
53 private static pushPartToIndex(index: Tag.Node, part: string, item: Item, rootPart: boolean): Tag.Node { 54 private static pushPartToIndex(index: TagNode, part: string, item: Item, rootPart: boolean): TagNode {
54 if (!index) 55 if (!index)
55 index = { 56 index = {
56 tag: part, 57 tag: part,
@@ -69,8 +70,8 @@ export default class IndexFactory {
69 70
70 // --- 71 // ---
71 72
72 public static searchTags(tagsIndex: Tag.Index, filter: string, strict: boolean): Tag.Search[] { 73 public static searchTags(tagsIndex: TagIndex, filter: string, strict: boolean): TagSearch[] {
73 let search: Tag.Search[] = []; 74 let search: TagSearch[] = [];
74 if (tagsIndex && filter) { 75 if (tagsIndex && filter) {
75 const operation = IndexFactory.extractOperation(filter); 76 const operation = IndexFactory.extractOperation(filter);
76 if (operation !== Operation.INTERSECTION) filter = filter.slice(1); 77 if (operation !== Operation.INTERSECTION) filter = filter.slice(1);
@@ -96,12 +97,12 @@ export default class IndexFactory {
96 } 97 }
97 98
98 private static searchTagsFromFilterWithCategory( 99 private static searchTagsFromFilterWithCategory(
99 tagsIndex: Tag.Index, 100 tagsIndex: TagIndex,
100 operation: Operation, 101 operation: Operation,
101 category: string, 102 category: string,
102 disambiguation: string, 103 disambiguation: string,
103 strict: boolean 104 strict: boolean
104 ): Tag.Search[] { 105 ): TagSearch[] {
105 category = Navigation.normalize(category); 106 category = Navigation.normalize(category);
106 disambiguation = Navigation.normalize(disambiguation); 107 disambiguation = Navigation.normalize(disambiguation);
107 return Object.values(tagsIndex) 108 return Object.values(tagsIndex)
@@ -114,28 +115,28 @@ export default class IndexFactory {
114 } 115 }
115 116
116 private static searchTagsFromFilter( 117 private static searchTagsFromFilter(
117 tagsIndex: Tag.Index, 118 tagsIndex: TagIndex,
118 operation: Operation, 119 operation: Operation,
119 filter: string, 120 filter: string,
120 strict: boolean 121 strict: boolean
121 ): Tag.Search[] { 122 ): TagSearch[] {
122 filter = Navigation.normalize(filter); 123 filter = Navigation.normalize(filter);
123 return Object.values(tagsIndex) 124 return Object.values(tagsIndex)
124 .filter(node => IndexFactory.matches(node, filter, strict)) 125 .filter(node => IndexFactory.matches(node, filter, strict))
125 .map(node => ({ ...node, operation, display: `${operation}${node.tag}` })); 126 .map(node => ({ ...node, operation, display: `${operation}${node.tag}` }));
126 } 127 }
127 128
128 private static matches(node: Tag.Node, filter: string, strict: boolean): boolean {