From e34be1261d9219e5b2b92ebe271f609f11d55f63 Mon Sep 17 00:00:00 2001 From: Zero~Informatique Date: Sun, 22 Dec 2019 03:50:40 +0100 Subject: vewer: Tags indexing and search input --- viewer/.eslintrc.js | 2 +- viewer/src/@types/tag/index.d.ts | 8 +++++++ viewer/src/components/LdTagInput.vue | 40 +++++++++++++++++++++++++++++++++++ viewer/src/locales/en.json | 4 +++- viewer/src/store/galleryStore.ts | 41 ++++++++++++++++++++++++++++++++---- viewer/src/store/uiStore.ts | 5 ++++- viewer/src/views/Gallery.vue | 6 +++--- viewer/src/views/MainLayout.vue | 7 ++++-- viewer/src/views/PanelLeft.vue | 20 ++++++++++++++++++ viewer/visualstudio.code-workspace | 1 + 10 files changed, 122 insertions(+), 12 deletions(-) create mode 100644 viewer/src/@types/tag/index.d.ts create mode 100644 viewer/src/components/LdTagInput.vue create mode 100644 viewer/src/views/PanelLeft.vue diff --git a/viewer/.eslintrc.js b/viewer/.eslintrc.js index 095216b..996c4f3 100644 --- a/viewer/.eslintrc.js +++ b/viewer/.eslintrc.js @@ -11,7 +11,7 @@ module.exports = { ], rules: { - "no-console": process.env.NODE_ENV === "production" ? "error" : "off", + "no-console": "off", "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off", 'vue/attribute-hyphenation': 'warn', 'vue/html-closing-bracket-spacing': 'warn', diff --git a/viewer/src/@types/tag/index.d.ts b/viewer/src/@types/tag/index.d.ts new file mode 100644 index 0000000..6a027d4 --- /dev/null +++ b/viewer/src/@types/tag/index.d.ts @@ -0,0 +1,8 @@ +declare namespace Tag { + interface Node { + tag: string; + items: Gallery.Item[]; + children: Index; + } + type Index = { [index: string]: Node }; +} \ No newline at end of file diff --git a/viewer/src/components/LdTagInput.vue b/viewer/src/components/LdTagInput.vue new file mode 100644 index 0000000..4edc1ce --- /dev/null +++ b/viewer/src/components/LdTagInput.vue @@ -0,0 +1,40 @@ + + + + + diff --git a/viewer/src/locales/en.json b/viewer/src/locales/en.json index d966983..f24ac1f 100644 --- a/viewer/src/locales/en.json +++ b/viewer/src/locales/en.json @@ -1,3 +1,5 @@ { - "message": "hello i18n !!" + "tagInput.placeholder": "Tags", + "panelLeft.title": "Filters", + "tagInput.nomatch": "No match" } \ No newline at end of file diff --git a/viewer/src/store/galleryStore.ts b/viewer/src/store/galleryStore.ts index 4751561..c875837 100644 --- a/viewer/src/store/galleryStore.ts +++ b/viewer/src/store/galleryStore.ts @@ -7,16 +7,49 @@ const VuexModule = createModule({ export default class GalleryStore extends VuexModule { - galleryItems: Gallery.Item | null = null; + galleryItemsRoot: Gallery.Item | null = null; + tags: Tag.Index = {}; - @mutation setGalleryItems(galleryItems: Gallery.Item) { - this.galleryItems = galleryItems; + // --- + + @mutation setGalleryItemsRoot(galleryItemsRoot: Gallery.Item) { + this.galleryItemsRoot = galleryItemsRoot; + } + + @mutation private setTags(tags: Tag.Index) { + this.tags = tags; } + // --- + @action async fetchGalleryItems(url: string) { fetch(url) .then(response => response.json()) - .then(this.setGalleryItems); + .then(this.setGalleryItemsRoot) + .then(this.indexTags); } + @action async indexTags() { + let index = {}; + if (this.galleryItemsRoot) + GalleryStore.pushTagsForItem(index, this.galleryItemsRoot); + console.log(index); + this.setTags(index); + } + + private static pushTagsForItem(index: Tag.Index, item: Gallery.Item) { + console.log("IndexingTagsFor: ", item.path); + for (const tag of item.tags) { + const parts = tag.split('.'); + let lastPart: string | null = null; + for (const part of parts) { + if (!index[part]) index[part] = { tag: part, items: [], children: {} }; + index[part].items.push(item); + if (lastPart) index[lastPart].children[part] = index[part]; + lastPart = part; + } + } + if (item.properties.type === "directory") + item.properties.items.forEach(item => this.pushTagsForItem(index, item)); + } } \ No newline at end of file diff --git a/viewer/src/store/uiStore.ts b/viewer/src/store/uiStore.ts index c4143a1..e04b507 100644 --- a/viewer/src/store/uiStore.ts +++ b/viewer/src/store/uiStore.ts @@ -2,12 +2,15 @@ import { createModule, mutation, action } from "vuex-class-component"; const VuexModule = createModule({ namespaced: "uiStore", - strict: true + strict: false }) export default class UIStore extends VuexModule { fullscreen: boolean = false; + currentTags: Tag.Node[] = []; + + // --- @mutation toggleFullscreen() { this.fullscreen = !this.fullscreen; diff --git a/viewer/src/views/Gallery.vue b/viewer/src/views/Gallery.vue index 954903a..2020280 100644 --- a/viewer/src/views/Gallery.vue +++ b/viewer/src/views/Gallery.vue @@ -13,7 +13,7 @@ import GalleryImage from "./GalleryImage.vue"; @Component({ components: { GalleryDirectory, GalleryImage }, }) -export default class Root extends Vue { +export default class Gallery extends Vue { @Prop(String) readonly pathMatch!: string; get isDirectory(): boolean { @@ -25,8 +25,8 @@ export default class Root extends Vue { } get currentItem(): Gallery.Item | null { - const galleryItems = this.$galleryStore.galleryItems; - if (galleryItems) return this.searchCurrentItem(galleryItems, this.pathMatch); + const galleryItemsRoot = this.$galleryStore.galleryItemsRoot; + if (galleryItemsRoot) return this.searchCurrentItem(galleryItemsRoot, this.pathMatch); return null; } diff --git a/viewer/src/views/MainLayout.vue b/viewer/src/views/MainLayout.vue index 9f3a17b..2afd4b9 100644 --- a/viewer/src/views/MainLayout.vue +++ b/viewer/src/views/MainLayout.vue @@ -1,7 +1,7 @@