Loading src/components/CollectionsTree.vue +51 −84 Original line number Diff line number Diff line Loading @@ -10,15 +10,16 @@ <slot name="toolbar"/> </v-toolbar-title> </v-toolbar> <v-treeview dense :items="collectionsTree" :load-children="collectionClicked" :items="items" hoverable activatable item-text="title" class="jama-collection-tree rounded-0" @update:active="updateActive" class="jama-collection-tree" @update:active="activeItemChanged" return-object > <template v-slot:label="{ item }"> Loading @@ -34,109 +35,74 @@ </template> <script> import {mapGetters} from "vuex"; import {mapActions, mapGetters} from "vuex"; export default { name: "CollectionsTree", data() { return { items: [], selectedCollection : null, emulate: false highlightedNode: null, simulateClick: false, } }, mounted() { this.fetchCollections(); this.fetchCollectionTree(this.currentRootCollectionId); }, computed: { collectionsTree: { get() { return this.$store.state.collectionsTree }, }, ...mapGetters(["collections", "currentRootCollectionId", "currentCollection"]) }, watch: { currentCollection() { if(this.currentCollection.id == this.currentRootCollectionId) { document.querySelectorAll('.v-treeview-node--active') .forEach((elt) => elt.classList.remove('v-treeview-node--active'))//desactive current active } if (this.highlightedNode && this.highlightedNode.id !== this.currentCollection.id) { if(this.selectedCollection && this.selectedCollection.id !== this.currentCollection.id){ if (this.currentCollection.id == this.currentRootCollectionId) {//home clicked this.highlightedNode = null; document.querySelectorAll('.v-treeview-node--active') .forEach((elt) => elt.classList.remove('v-treeview-node--active'))//desactive current active } else {//collection was loaded but from external action (no click on treeview) this.simulateClick = true; try { const target = document.querySelector('#tree-item-' + this.currentCollection.id) .parentElement.parentElement; this.emulate = true; this.simulateClick = true; target.click(); } // eslint-disable-next-line no-empty catch(e){} catch (e) { } } } } }, // collections(){ // const target = document.querySelector('#tree-item-' + this.currentCollection.id) // .parentElement.parentElement; // target.click(); // } }, methods: { async collectionClicked(c) { this.selectedCollection = c; if(this.emulate) this.highlightedNode = c; if (this.simulateClick) return; await this.fetchCollections(this.selectedCollection); await this.fetchCollectionTree(c.id); this.$emit('tree-collection-selected', c.id); }, async fetchCollections(collection) { let children = []; return this.$jamaClient.collections( collection ? collection.id : this.currentRootCollectionId, false, 0, 2000, false, false).then(cols => { if (!this.$store.getters.showHiddenCollections) { cols = cols.filter(c => { return !c.title.startsWith('.') }); } cols.forEach((c) => { let col = { title: c.title, id: c.id, } if (c.children_count > 0) col.children = [] children.push(col); }) if(!collection) this.items =[...children] else collection.children.push(...children) }); }, updateActive(values){ if(values.length !== 1) return false; this.selectedCollection = values[0]; if(this.emulate){ this.emulate = false; return; } else { this.$emit('tree-collection-selected', this.selectedCollection.id); async activeItemChanged(values) { if (values.length === 1) { this.highlightedNode = values[0]; this.$emit('tree-collection-selected', values[0].id) } }, loadHome() { this.$emit('tree-collection-selected', this.currentRootCollectionId); } }, ...mapActions(["fetchCollectionTree", "fetchCollections"]) } } </script> Loading @@ -146,6 +112,7 @@ export default { .jama-collection-tree { max-height: calc(100vh - 64px); overflow-y: auto; .v-list-item { cursor: pointer; } Loading src/components/VueJama.vue +3 −2 Original line number Diff line number Diff line Loading @@ -591,12 +591,13 @@ export default { async addCollection(collectionName) { if (collectionName && this.collections.indexOf(collectionName) < 0) { await this.$store.dispatch('addCollection', let newCollection = await this.$store.dispatch('addCollection', { title: collectionName, parentId: this.currentCollection ? this.currentCollection.id : null, } ); EventBus.$emit('collection-added', newCollection); } }, Loading Loading @@ -645,7 +646,7 @@ export default { this.jamaAlert("Suppression impossible") } else { this.collections.splice(this.collections.indexOf(collection), 1); this.loadCollectionById(collection.parent) this.loadCollectionById(collection.parent); } }, Loading src/store/JamaStore.js +61 −12 Original line number Diff line number Diff line Loading @@ -20,6 +20,27 @@ function sortOptionsAsString(sortOptions) { } } /** * collectionsTree's item finder * @param id * @param items * @returns {*} */ function findItem(id, items = null) { return items.reduce((acc, item) => { if (acc) { return acc; } if (item.id === id) { return item; } if (item.children) { return findItem(id, item.children); } return acc; }, null); } export default new Vuex.Store({ state: { Loading @@ -28,6 +49,7 @@ export default new Vuex.Store({ projects: [], resources: [], collections: [], collectionsTree: [], projectProperties: [], allSelected: false, selectedCollections: [], Loading Loading @@ -58,6 +80,7 @@ export default new Vuex.Store({ projects: state => state.projects, resources: state => state.resources, collections: state => state.collections, collectionsTree: state => state.collectionsTree, selectedResources: state => state.selectedResources, selectedCollections: state => state.selectedCollections, allSelected: state => state.allSelected, Loading Loading @@ -103,6 +126,10 @@ export default new Vuex.Store({ state.collections = collections; }, setCollectionsTree: (state, tree) => { state.collectionsTree = tree }, setAllSelected: (state, bool) => { state.allSelected = bool; }, Loading Loading @@ -293,6 +320,25 @@ export default new Vuex.Store({ commit('setCurrentCollection', collection); }, async fetchCollectionTree(context, id) { let collections = await JamaRPClient.collections(id); collections.forEach((c) => { if (c.children_count > 0) c.children = [] }) let item = findItem(id, context.state.collectionsTree); if (!item) { context.commit('setCollectionsTree', collections); } else { if(collections.length > 0) item.children = collections; else { item.children = null; } context.commit('setCollectionsTree', [...context.state.collectionsTree]); } }, async fetchResources(context, {collectionId = null, includeMetas = false, limitFrom = 0, limitTo = 2000}) { let resources = await JamaRPClient.resources( collectionId, Loading Loading @@ -325,8 +371,10 @@ export default new Vuex.Store({ }, async deleteCollection(context, {collectionId, recursive}) { let rid = context.state.currentCollection.id === collectionId ? context.state.currentCollection.parent : context.state.currentCollection.id let res = await JamaRPClient.deleteCollection(collectionId, recursive); context.commit('deleteCollection', collectionId); await context.dispatch('fetchCollectionTree', rid); return res; }, Loading @@ -338,6 +386,7 @@ export default new Vuex.Store({ let newCollection = await JamaRPClient.addCollection(title, parentId); if (newCollection) { context.commit('addCollection', newCollection); await context.dispatch('fetchCollectionTree', parentId); } return newCollection }, Loading Loading
src/components/CollectionsTree.vue +51 −84 Original line number Diff line number Diff line Loading @@ -10,15 +10,16 @@ <slot name="toolbar"/> </v-toolbar-title> </v-toolbar> <v-treeview dense :items="collectionsTree" :load-children="collectionClicked" :items="items" hoverable activatable item-text="title" class="jama-collection-tree rounded-0" @update:active="updateActive" class="jama-collection-tree" @update:active="activeItemChanged" return-object > <template v-slot:label="{ item }"> Loading @@ -34,109 +35,74 @@ </template> <script> import {mapGetters} from "vuex"; import {mapActions, mapGetters} from "vuex"; export default { name: "CollectionsTree", data() { return { items: [], selectedCollection : null, emulate: false highlightedNode: null, simulateClick: false, } }, mounted() { this.fetchCollections(); this.fetchCollectionTree(this.currentRootCollectionId); }, computed: { collectionsTree: { get() { return this.$store.state.collectionsTree }, }, ...mapGetters(["collections", "currentRootCollectionId", "currentCollection"]) }, watch: { currentCollection() { if(this.currentCollection.id == this.currentRootCollectionId) { document.querySelectorAll('.v-treeview-node--active') .forEach((elt) => elt.classList.remove('v-treeview-node--active'))//desactive current active } if (this.highlightedNode && this.highlightedNode.id !== this.currentCollection.id) { if(this.selectedCollection && this.selectedCollection.id !== this.currentCollection.id){ if (this.currentCollection.id == this.currentRootCollectionId) {//home clicked this.highlightedNode = null; document.querySelectorAll('.v-treeview-node--active') .forEach((elt) => elt.classList.remove('v-treeview-node--active'))//desactive current active } else {//collection was loaded but from external action (no click on treeview) this.simulateClick = true; try { const target = document.querySelector('#tree-item-' + this.currentCollection.id) .parentElement.parentElement; this.emulate = true; this.simulateClick = true; target.click(); } // eslint-disable-next-line no-empty catch(e){} catch (e) { } } } } }, // collections(){ // const target = document.querySelector('#tree-item-' + this.currentCollection.id) // .parentElement.parentElement; // target.click(); // } }, methods: { async collectionClicked(c) { this.selectedCollection = c; if(this.emulate) this.highlightedNode = c; if (this.simulateClick) return; await this.fetchCollections(this.selectedCollection); await this.fetchCollectionTree(c.id); this.$emit('tree-collection-selected', c.id); }, async fetchCollections(collection) { let children = []; return this.$jamaClient.collections( collection ? collection.id : this.currentRootCollectionId, false, 0, 2000, false, false).then(cols => { if (!this.$store.getters.showHiddenCollections) { cols = cols.filter(c => { return !c.title.startsWith('.') }); } cols.forEach((c) => { let col = { title: c.title, id: c.id, } if (c.children_count > 0) col.children = [] children.push(col); }) if(!collection) this.items =[...children] else collection.children.push(...children) }); }, updateActive(values){ if(values.length !== 1) return false; this.selectedCollection = values[0]; if(this.emulate){ this.emulate = false; return; } else { this.$emit('tree-collection-selected', this.selectedCollection.id); async activeItemChanged(values) { if (values.length === 1) { this.highlightedNode = values[0]; this.$emit('tree-collection-selected', values[0].id) } }, loadHome() { this.$emit('tree-collection-selected', this.currentRootCollectionId); } }, ...mapActions(["fetchCollectionTree", "fetchCollections"]) } } </script> Loading @@ -146,6 +112,7 @@ export default { .jama-collection-tree { max-height: calc(100vh - 64px); overflow-y: auto; .v-list-item { cursor: pointer; } Loading
src/components/VueJama.vue +3 −2 Original line number Diff line number Diff line Loading @@ -591,12 +591,13 @@ export default { async addCollection(collectionName) { if (collectionName && this.collections.indexOf(collectionName) < 0) { await this.$store.dispatch('addCollection', let newCollection = await this.$store.dispatch('addCollection', { title: collectionName, parentId: this.currentCollection ? this.currentCollection.id : null, } ); EventBus.$emit('collection-added', newCollection); } }, Loading Loading @@ -645,7 +646,7 @@ export default { this.jamaAlert("Suppression impossible") } else { this.collections.splice(this.collections.indexOf(collection), 1); this.loadCollectionById(collection.parent) this.loadCollectionById(collection.parent); } }, Loading
src/store/JamaStore.js +61 −12 Original line number Diff line number Diff line Loading @@ -20,6 +20,27 @@ function sortOptionsAsString(sortOptions) { } } /** * collectionsTree's item finder * @param id * @param items * @returns {*} */ function findItem(id, items = null) { return items.reduce((acc, item) => { if (acc) { return acc; } if (item.id === id) { return item; } if (item.children) { return findItem(id, item.children); } return acc; }, null); } export default new Vuex.Store({ state: { Loading @@ -28,6 +49,7 @@ export default new Vuex.Store({ projects: [], resources: [], collections: [], collectionsTree: [], projectProperties: [], allSelected: false, selectedCollections: [], Loading Loading @@ -58,6 +80,7 @@ export default new Vuex.Store({ projects: state => state.projects, resources: state => state.resources, collections: state => state.collections, collectionsTree: state => state.collectionsTree, selectedResources: state => state.selectedResources, selectedCollections: state => state.selectedCollections, allSelected: state => state.allSelected, Loading Loading @@ -103,6 +126,10 @@ export default new Vuex.Store({ state.collections = collections; }, setCollectionsTree: (state, tree) => { state.collectionsTree = tree }, setAllSelected: (state, bool) => { state.allSelected = bool; }, Loading Loading @@ -293,6 +320,25 @@ export default new Vuex.Store({ commit('setCurrentCollection', collection); }, async fetchCollectionTree(context, id) { let collections = await JamaRPClient.collections(id); collections.forEach((c) => { if (c.children_count > 0) c.children = [] }) let item = findItem(id, context.state.collectionsTree); if (!item) { context.commit('setCollectionsTree', collections); } else { if(collections.length > 0) item.children = collections; else { item.children = null; } context.commit('setCollectionsTree', [...context.state.collectionsTree]); } }, async fetchResources(context, {collectionId = null, includeMetas = false, limitFrom = 0, limitTo = 2000}) { let resources = await JamaRPClient.resources( collectionId, Loading Loading @@ -325,8 +371,10 @@ export default new Vuex.Store({ }, async deleteCollection(context, {collectionId, recursive}) { let rid = context.state.currentCollection.id === collectionId ? context.state.currentCollection.parent : context.state.currentCollection.id let res = await JamaRPClient.deleteCollection(collectionId, recursive); context.commit('deleteCollection', collectionId); await context.dispatch('fetchCollectionTree', rid); return res; }, Loading @@ -338,6 +386,7 @@ export default new Vuex.Store({ let newCollection = await JamaRPClient.addCollection(title, parentId); if (newCollection) { context.commit('addCollection', newCollection); await context.dispatch('fetchCollectionTree', parentId); } return newCollection }, Loading