diff options
author | Zero~Informatique | 2020-02-27 23:26:00 +0100 |
---|---|---|
committer | Zero~Informatique | 2020-02-27 23:26:31 +0100 |
commit | f2ff937fe4a5782741886ef4920fd0e284775463 (patch) | |
tree | 8a51b6ceb74bd359ac282a7ff3d6a75f0a105de7 | |
parent | f09e9d9fa29284bd9ae872efe5ba1d526e349011 (diff) | |
download | ldgallery-f2ff937fe4a5782741886ef4920fd0e284775463.tar.gz |
viewer: tag index bugfix
Search from the URL requires a strict match instead of a loose match
Category search was case sensitive
Category + disambiguation was matching like an intersection of both tags instead of being hard-coupled
Removed the logs for the release (coming soon)
-rw-r--r-- | viewer/src/components/LdCommand.vue | 2 | ||||
-rw-r--r-- | viewer/src/components/LdTagInput.vue | 2 | ||||
-rw-r--r-- | viewer/src/services/indexfactory.ts | 36 | ||||
-rw-r--r-- | viewer/src/views/GalleryNavigation.vue | 1 | ||||
-rw-r--r-- | viewer/src/views/PanelLeft.vue | 2 |
5 files changed, 27 insertions, 16 deletions
diff --git a/viewer/src/components/LdCommand.vue b/viewer/src/components/LdCommand.vue index 398107e..9afd121 100644 --- a/viewer/src/components/LdCommand.vue +++ b/viewer/src/components/LdCommand.vue | |||
@@ -55,7 +55,7 @@ export default class LdCommand extends Vue { | |||
55 | } | 55 | } |
56 | 56 | ||
57 | isEntryPoint(): boolean { | 57 | isEntryPoint(): boolean { |
58 | return history.state.ldgallery === "ENTRYPOINT"; // Set by MainLayout.vue | 58 | return history.state?.ldgallery === "ENTRYPOINT"; // Set by MainLayout.vue |
59 | } | 59 | } |
60 | 60 | ||
61 | parent(): RawLocation { | 61 | parent(): RawLocation { |
diff --git a/viewer/src/components/LdTagInput.vue b/viewer/src/components/LdTagInput.vue index b2a2c58..bdb07bc 100644 --- a/viewer/src/components/LdTagInput.vue +++ b/viewer/src/components/LdTagInput.vue | |||
@@ -55,7 +55,7 @@ export default class LdTagInput extends Vue { | |||
55 | } | 55 | } |
56 | 56 | ||
57 | searchTags(filter: string) { | 57 | searchTags(filter: string) { |
58 | this.filteredTags = IndexFactory.searchTags(this.tagsIndex, filter) | 58 | this.filteredTags = IndexFactory.searchTags(this.tagsIndex, filter, false) |
59 | .filter(newSearch => !this.model.find(currentSearch => currentSearch.tag === newSearch.tag)) | 59 | .filter(newSearch => !this.model.find(currentSearch => currentSearch.tag === newSearch.tag)) |
60 | .sort((a, b) => b.items.length - a.items.length); | 60 | .sort((a, b) => b.items.length - a.items.length); |
61 | } | 61 | } |
diff --git a/viewer/src/services/indexfactory.ts b/viewer/src/services/indexfactory.ts index 6fed6cc..45abcd5 100644 --- a/viewer/src/services/indexfactory.ts +++ b/viewer/src/services/indexfactory.ts | |||
@@ -30,7 +30,6 @@ export default class IndexFactory { | |||
30 | 30 | ||
31 | // Pushes all tags for a root item (and its children) to the index | 31 | // Pushes all tags for a root item (and its children) to the index |
32 | private static pushTagsForItem(tagsIndex: Tag.Index, item: Gallery.Item): void { | 32 | private static pushTagsForItem(tagsIndex: Tag.Index, item: Gallery.Item): void { |
33 | console.log("IndexingTagsFor: ", item.path); | ||
34 | if (item.properties.type === "directory") { | 33 | if (item.properties.type === "directory") { |
35 | item.properties.items.forEach(item => this.pushTagsForItem(tagsIndex, item)); | 34 | item.properties.items.forEach(item => this.pushTagsForItem(tagsIndex, item)); |
36 | return; // Directories are not indexed | 35 | return; // Directories are not indexed |
@@ -39,27 +38,35 @@ export default class IndexFactory { | |||
39 | const parts = tag.split(':'); | 38 | const parts = tag.split(':'); |
40 | let lastPart: string | null = null; | 39 | let lastPart: string | null = null; |
41 | for (const part of parts) { | 40 | for (const part of parts) { |
42 | if (!tagsIndex[part]) tagsIndex[part] = { tag: part, tagfiltered: Navigation.normalize(part), items: [], children: {} }; | 41 | tagsIndex[part] = IndexFactory.pushPartToIndex(tagsIndex[part], part, item); |
43 | if (!tagsIndex[part].items.includes(item)) tagsIndex[part].items.push(item); | 42 | if (lastPart) { |
44 | if (lastPart) tagsIndex[lastPart].children[part] = tagsIndex[part]; | 43 | const children = tagsIndex[lastPart].children; |
44 | children[part] = IndexFactory.pushPartToIndex(children[part], part, item); | ||
45 | } | ||
45 | lastPart = part; | 46 | lastPart = part; |
46 | } | 47 | } |
47 | } | 48 | } |
48 | } | 49 | } |
49 | 50 | ||
51 | private static pushPartToIndex(index: Tag.Node, part: string, item: Gallery.Item): Tag.Node { | ||
52 | if (!index) index = { tag: part, tagfiltered: Navigation.normalize(part), items: [], children: {} }; | ||
53 | if (!index.items.includes(item)) index.items.push(item); | ||
54 | return index; | ||
55 | } | ||
56 | |||
50 | // --- | 57 | // --- |
51 | 58 | ||
52 | 59 | ||
53 | public static searchTags(tagsIndex: Tag.Index, filter: string): Tag.Search[] { | 60 | public static searchTags(tagsIndex: Tag.Index, filter: string, strict: boolean): Tag.Search[] { |
54 | let search: Tag.Search[] = []; | 61 | let search: Tag.Search[] = []; |
55 | if (tagsIndex && filter) { | 62 | if (tagsIndex && filter) { |
56 | const operation = IndexFactory.extractOperation(filter); | 63 | const operation = IndexFactory.extractOperation(filter); |
57 | if (operation !== Operation.INTERSECTION) filter = filter.slice(1); | 64 | if (operation !== Operation.INTERSECTION) filter = filter.slice(1); |
58 | if (filter.includes(":")) { | 65 | if (filter.includes(":")) { |
59 | const filterParts = filter.split(":"); | 66 | const filterParts = filter.split(":"); |
60 | search = this.searchTagsFromFilterWithCategory(tagsIndex, operation, filterParts[0], filterParts[1]); | 67 | search = this.searchTagsFromFilterWithCategory(tagsIndex, operation, filterParts[0], filterParts[1], strict); |
61 | } else { | 68 | } else { |
62 | search = this.searchTagsFromFilter(tagsIndex, operation, filter); | 69 | search = this.searchTagsFromFilter(tagsIndex, operation, filter, strict); |
63 | } | 70 | } |
64 | } | 71 | } |
65 | return search; | 72 | return search; |
@@ -80,22 +87,27 @@ export default class IndexFactory { | |||
80 | tagsIndex: Tag.Index, | 87 | tagsIndex: Tag.Index, |
81 | operation: Operation, | 88 | operation: Operation, |
82 | category: string, | 89 | category: string, |
83 | disambiguation: string | 90 | disambiguation: string, |
91 | strict: boolean | ||
84 | ): Tag.Search[] { | 92 | ): Tag.Search[] { |
93 | category = Navigation.normalize(category); | ||
85 | disambiguation = Navigation.normalize(disambiguation); | 94 | disambiguation = Navigation.normalize(disambiguation); |
86 | return Object.values(tagsIndex) | 95 | return Object.values(tagsIndex) |
87 | .filter(node => node.tag.includes(category)) | 96 | .filter(node => strict || node.tagfiltered.includes(category)) |
97 | .filter(node => !strict || node.tagfiltered === category) | ||
88 | .flatMap(node => | 98 | .flatMap(node => |
89 | Object.values(node.children) | 99 | Object.values(node.children) |
90 | .filter(child => child.tagfiltered.includes(disambiguation)) | 100 | .filter(child => strict || child.tagfiltered.includes(disambiguation)) |
101 | .filter(child => !strict || child.tagfiltered === disambiguation) | ||
91 | .map(child => ({ ...child, parent: node, operation, display: `${operation}${node.tag}:${child.tag}` })) | 102 | .map(child => ({ ...child, parent: node, operation, display: `${operation}${node.tag}:${child.tag}` })) |
92 | ); | 103 | ); |
93 | } | 104 | } |
94 | 105 | ||
95 | private static searchTagsFromFilter(tagsIndex: Tag.Index, operation: Operation, filter: string): Tag.Search[] { | 106 | private static searchTagsFromFilter(tagsIndex: Tag.Index, operation: Operation, filter: string, strict: boolean): Tag.Search[] { |
96 | filter = Navigation.normalize(filter); | 107 | filter = Navigation.normalize(filter); |
97 | return Object.values(tagsIndex) | 108 | return Object.values(tagsIndex) |
98 | .filter(node => node.tagfiltered.includes(filter)) | 109 | .filter(node => strict || node.tagfiltered.includes(filter)) |
110 | .filter(node => !strict || node.tagfiltered === filter) | ||
99 | .map(node => ({ ...node, operation, display: `${operation}${node.tag}` })); | 111 | .map(node => ({ ...node, operation, display: `${operation}${node.tag}` })); |
100 | } | 112 | } |
101 | } | 113 | } |
diff --git a/viewer/src/views/GalleryNavigation.vue b/viewer/src/views/GalleryNavigation.vue index fafb2ed..7c6d11b 100644 --- a/viewer/src/views/GalleryNavigation.vue +++ b/viewer/src/views/GalleryNavigation.vue | |||
@@ -49,7 +49,6 @@ export default class GalleryNavigation extends Vue { | |||
49 | 49 | ||
50 | @Watch("path") | 50 | @Watch("path") |
51 | pathChanged() { | 51 | pathChanged() { |
52 | console.log("Path: ", this.path); | ||
53 | this.$galleryStore.setCurrentPath(this.path); | 52 | this.$galleryStore.setCurrentPath(this.path); |
54 | } | 53 | } |
55 | 54 | ||
diff --git a/viewer/src/views/PanelLeft.vue b/viewer/src/views/PanelLeft.vue index 54b9c63..5b3196a 100644 --- a/viewer/src/views/PanelLeft.vue +++ b/viewer/src/views/PanelLeft.vue | |||
@@ -72,7 +72,7 @@ export default class PanelLeft extends Vue { | |||
72 | const query = Object.keys(route.query); | 72 | const query = Object.keys(route.query); |
73 | if (query.length > 0) { | 73 | if (query.length > 0) { |
74 | const tagsIndex = this.$galleryStore.tagsIndex; | 74 | const tagsIndex = this.$galleryStore.tagsIndex; |
75 | this.searchFilters = Object.keys(route.query).flatMap(filter => IndexFactory.searchTags(tagsIndex, filter)); | 75 | this.searchFilters = Object.keys(route.query).flatMap(filter => IndexFactory.searchTags(tagsIndex, filter, true)); |
76 | this.$galleryStore.setCurrentSearch([...this.searchFilters]); | 76 | this.$galleryStore.setCurrentSearch([...this.searchFilters]); |
77 | } | 77 | } |
78 | } | 78 | } |