From b866e8f1560ec3a847107d5bdbe742a35e110be0 Mon Sep 17 00:00:00 2001 From: Bram Wiepjes <bramw@protonmail.com> Date: Fri, 11 Oct 2019 11:43:24 +0200 Subject: [PATCH] moved the selected group to the group store instead of the application --- web-frontend/components/group/GroupForm.vue | 3 + .../components/group/GroupsContextItem.vue | 16 ++--- .../components/sidebar/ApplicationForm.vue | 3 + web-frontend/components/sidebar/Sidebar.vue | 4 +- .../components/sidebar/SidebarApplication.vue | 4 +- web-frontend/middleware/group.js | 6 +- web-frontend/pages/app/index.vue | 2 +- web-frontend/store/application.js | 53 +++++----------- web-frontend/store/auth.js | 2 +- web-frontend/store/group.js | 63 ++++++++++++++++--- web-frontend/utils/error.js | 4 +- 11 files changed, 94 insertions(+), 66 deletions(-) diff --git a/web-frontend/components/group/GroupForm.vue b/web-frontend/components/group/GroupForm.vue index ad46180e6..a5714eead 100644 --- a/web-frontend/components/group/GroupForm.vue +++ b/web-frontend/components/group/GroupForm.vue @@ -42,6 +42,9 @@ export default { values: { name: { required } } + }, + mounted() { + this.$refs.name.focus() } } </script> diff --git a/web-frontend/components/group/GroupsContextItem.vue b/web-frontend/components/group/GroupsContextItem.vue index 4036d7f09..a5dbde24b 100644 --- a/web-frontend/components/group/GroupsContextItem.vue +++ b/web-frontend/components/group/GroupsContextItem.vue @@ -2,7 +2,7 @@ <li class="select-item" :class="{ - active: selectedGroup.id == group.id, + active: group._.selected, 'select-item-loading': group._.loading }" > @@ -41,8 +41,6 @@ </template> <script> -import { mapState } from 'vuex' - export default { name: 'GroupsContextItem', props: { @@ -51,11 +49,6 @@ export default { required: true } }, - computed: { - ...mapState({ - selectedGroup: state => state.application.selectedGroup - }) - }, methods: { setLoading(group, value) { this.$store.dispatch('group/setItemLoading', { group, value: value }) @@ -69,7 +62,7 @@ export default { this.$store .dispatch('group/update', { - id: group.id, + group, values: { name: event.value } @@ -85,17 +78,16 @@ export default { selectGroup(group) { this.setLoading(group, true) - this.$store.dispatch('application/selectGroup', group).then(() => { + this.$store.dispatch('group/select', group).then(() => { this.setLoading(group, false) this.$emit('selected') }) }, deleteGroup(group) { this.$refs.context.hide() - this.$store.dispatch('application/unselectGroup') this.setLoading(group, true) - this.$store.dispatch('group/delete', group.id).then(() => { + this.$store.dispatch('group/delete', group).then(() => { this.setLoading(group, false) }) } diff --git a/web-frontend/components/sidebar/ApplicationForm.vue b/web-frontend/components/sidebar/ApplicationForm.vue index e49a9cc3c..aa7522cbb 100644 --- a/web-frontend/components/sidebar/ApplicationForm.vue +++ b/web-frontend/components/sidebar/ApplicationForm.vue @@ -38,6 +38,9 @@ export default { } } }, + mounted() { + this.$refs.name.focus() + }, validations: { values: { name: { required } diff --git a/web-frontend/components/sidebar/Sidebar.vue b/web-frontend/components/sidebar/Sidebar.vue index e3749ec5d..6f9c1185d 100644 --- a/web-frontend/components/sidebar/Sidebar.vue +++ b/web-frontend/components/sidebar/Sidebar.vue @@ -43,11 +43,11 @@ export default { computed: { ...mapState({ applications: state => state.application.items, - selectedGroup: state => state.application.selectedGroup + selectedGroup: state => state.group.selected }), ...mapGetters({ isLoading: 'application/isLoading', - hasSelectedGroup: 'application/hasSelectedGroup' + hasSelectedGroup: 'group/hasSelected' }) } } diff --git a/web-frontend/components/sidebar/SidebarApplication.vue b/web-frontend/components/sidebar/SidebarApplication.vue index a77da8ab9..5d33da4e7 100644 --- a/web-frontend/components/sidebar/SidebarApplication.vue +++ b/web-frontend/components/sidebar/SidebarApplication.vue @@ -70,7 +70,7 @@ export default { this.$store .dispatch('application/update', { - id: application.id, + application, values: { name: event.value } @@ -87,7 +87,7 @@ export default { this.$refs.context.hide() this.setLoading(application, true) - this.$store.dispatch('application/delete', application.id).then(() => { + this.$store.dispatch('application/delete', application).then(() => { this.setLoading(application, false) }) } diff --git a/web-frontend/middleware/group.js b/web-frontend/middleware/group.js index 8f45a39be..4b5ea661b 100644 --- a/web-frontend/middleware/group.js +++ b/web-frontend/middleware/group.js @@ -12,12 +12,12 @@ export default function({ store, req, app }) { // Get the selected group id const groupId = getGroupCookie(app.$cookies) - // If a group id cookie is set, the user is authenticated and a selectedGroup + // If a group id cookie is set, the user is authenticated and a selected group // is not already set then we will fetch the groups and select that group. if ( groupId && store.getters['auth/isAuthenticated'] && - !store.getters['application/hasSelectedGroup'] + !store.getters['group/hasSelected'] ) { return store .dispatch('group/fetchAll') @@ -27,7 +27,7 @@ export default function({ store, req, app }) { .then(() => { const group = store.getters['group/get'](groupId) if (group) { - return store.dispatch('application/selectGroup', group) + return store.dispatch('group/select', group) } }) } diff --git a/web-frontend/pages/app/index.vue b/web-frontend/pages/app/index.vue index 13ea3bd8d..035ffa406 100644 --- a/web-frontend/pages/app/index.vue +++ b/web-frontend/pages/app/index.vue @@ -22,7 +22,7 @@ export default { ...mapState({ user: state => state.auth.user, groups: state => state.group.items, - selectedGroup: state => state.application.selectedGroup, + selectedGroup: state => state.group.selected, applications: state => state.application.applications, groupApplications: state => state.application.items }) diff --git a/web-frontend/store/application.js b/web-frontend/store/application.js index 1866b8413..905dfa0e2 100644 --- a/web-frontend/store/application.js +++ b/web-frontend/store/application.js @@ -1,6 +1,5 @@ import { Application } from '@/core/applications' import ApplicationService from '@/services/application' -import { setGroupCookie } from '@/utils/group' import { notify404, notifyError } from '@/utils/error' function populateApplication(application, getters) { @@ -14,17 +13,13 @@ function populateApplication(application, getters) { export const state = () => ({ applications: {}, loading: false, - items: [], - selectedGroup: {} + items: [] }) export const mutations = { REGISTER(state, application) { state.applications[application.type] = application }, - SET_SELECTED_GROUP(state, group) { - state.selectedGroup = group - }, SET_ITEMS(state, applications) { state.items = applications }, @@ -66,18 +61,14 @@ export const actions = { commit('SET_ITEM_LOADING', { application, value }) }, /** - * Choose an existing group. It will fetch all the applications of that group, - * sets a cookie so the next time the page loads the group is still selected - * and populates each item. + * Fetches all the applications of a given group. The is mostly called when + * the user selects a different group. */ - selectGroup({ commit, getters, dispatch }, group) { + fetchAll({ commit, getters, dispatch }, group) { commit('SET_LOADING', true) return ApplicationService.fetchAll(group.id) .then(({ data }) => { - commit('SET_SELECTED_GROUP', group) - setGroupCookie(group.id, this.app.$cookies) - data.forEach((part, index, d) => { populateApplication(data[index], getters) }) @@ -89,8 +80,9 @@ export const actions = { notify404( dispatch, error, - 'Unable to select group', - "You're unable to select the group. This could be because you're not part of the group." + 'Unable to fetch applications', + "You're unable to fetch the application of this group. " + + "This could be because you're not part of the group." ) }) .then(() => { @@ -98,19 +90,17 @@ export const actions = { }) }, /** - * If a selected group is deleted or for example the user logs off the current - * group must be unselected which means that all the fetched items will be - * forgotten. + * Clears all the currently selected applications, this could be called when + * the group is deleted of when the user logs off. */ - unselectGroup({ commit }) { - commit('SET_SELECTED_GROUP', {}) + clearAll({ commit }) { commit('SET_ITEMS', []) }, /** * Creates a new application with the given type and values for the currently * selected group. */ - create({ commit, getters, dispatch }, { type, values }) { + create({ commit, getters, rootGetters, dispatch }, { type, values }) { if (values.hasOwnProperty('type')) { throw new Error( 'The key "type" is a reserved, but is already set on the ' + @@ -123,7 +113,7 @@ export const actions = { } values.type = type - return ApplicationService.create(getters.selectedGroupId, values) + return ApplicationService.create(rootGetters['group/selectedId'], values) .then(({ data }) => { populateApplication(data, getters) commit('ADD_ITEM', data) @@ -141,8 +131,8 @@ export const actions = { /** * Updates the values of an existing application. */ - update({ commit, dispatch }, { id, values }) { - return ApplicationService.update(id, values) + update({ commit, dispatch }, { application, values }) { + return ApplicationService.update(application.id, values) .then(({ data }) => { commit('UPDATE_ITEM', data) }) @@ -160,10 +150,10 @@ export const actions = { /** * Deletes an existing application. */ - delete({ commit, dispatch }, id) { - return ApplicationService.delete(id) + delete({ commit, dispatch }, application) { + return ApplicationService.delete(application.id) .then(() => { - commit('DELETE_ITEM', id) + commit('DELETE_ITEM', application.id) }) .catch(error => { notifyError( @@ -179,15 +169,6 @@ export const actions = { } export const getters = { - selectedGroupId(state) { - return state.selectedGroup.id - }, - hasSelectedGroup(state) { - return state.selectedGroup.hasOwnProperty('id') - }, - applications(state) { - return state.applications - }, isLoading(state) { return state.loading }, diff --git a/web-frontend/store/auth.js b/web-frontend/store/auth.js index 7801eadec..00bff617c 100644 --- a/web-frontend/store/auth.js +++ b/web-frontend/store/auth.js @@ -59,7 +59,7 @@ export const actions = { unsetGroupCookie(this.app.$cookies) commit('CLEAR_USER_DATA') dispatch('group/clearAll', {}, { root: true }) - dispatch('application/unselectGroup', {}, { root: true }) + dispatch('group/unselect', {}, { root: true }) }, /** * Refresh the existing token. If successful commit the new token and start a diff --git a/web-frontend/store/group.js b/web-frontend/store/group.js index 4d3235e92..4ee74ae17 100644 --- a/web-frontend/store/group.js +++ b/web-frontend/store/group.js @@ -1,15 +1,17 @@ import GroupService from '@/services/group' import { notify404 } from '@/utils/error' +import { setGroupCookie, unsetGroupCookie } from '@/utils/group' function populateGroup(group) { - group._ = { loading: false } + group._ = { loading: false, selected: false } return group } export const state = () => ({ loaded: false, loading: false, - items: [] + items: [], + selected: {} }) export const mutations = { @@ -27,6 +29,9 @@ export const mutations = { }) }, SET_ITEM_LOADING(state, { group, value }) { + if (!group.hasOwnProperty('_')) { + return + } group._.loading = value }, ADD_ITEM(state, item) { @@ -40,6 +45,19 @@ export const mutations = { DELETE_ITEM(state, id) { const index = state.items.findIndex(item => item.id === id) state.items.splice(index, 1) + }, + SET_SELECTED(state, group) { + Object.values(state.items).forEach(item => { + item._.selected = false + }) + group._.selected = true + state.selected = group + }, + UNSELECT(state) { + Object.values(state.items).forEach(item => { + item._.selected = false + }) + state.selected = {} } } @@ -95,8 +113,8 @@ export const actions = { /** * Updates the values of the group with the provided id. */ - update({ commit, dispatch }, { id, values }) { - return GroupService.update(id, values) + update({ commit, dispatch }, { group, values }) { + return GroupService.update(group.id, values) .then(({ data }) => { commit('UPDATE_ITEM', data) }) @@ -113,10 +131,15 @@ export const actions = { /** * Deletes an existing group with the provided id. */ - delete({ commit, dispatch }, id) { - return GroupService.delete(id) + delete({ commit, dispatch }, group) { + return GroupService.delete(group.id) .then(() => { - commit('DELETE_ITEM', id) + if (group._.selected) { + console.log('calling unselect') + dispatch('unselect', group) + } + + commit('DELETE_ITEM', group.id) }) .catch(error => { notify404( @@ -127,6 +150,22 @@ export const actions = { "you're not part of the group." ) }) + }, + /** + * Select a group and fetch all the applications related to that group. + */ + select({ commit, dispatch }, group) { + commit('SET_SELECTED', group) + setGroupCookie(group.id, this.app.$cookies) + return dispatch('application/fetchAll', group, { root: true }) + }, + /** + * Unselect a group if selected and clears all the fetched applications. + */ + unselect({ commit, dispatch, getters }, group) { + commit('UNSELECT', {}) + unsetGroupCookie(this.app.$cookies) + return dispatch('application/clearAll', group, { root: true }) } } @@ -139,5 +178,15 @@ export const getters = { }, get: state => id => { return state.items.find(item => item.id === id) + }, + hasSelected(state) { + return state.selected.hasOwnProperty('id') + }, + selectedId(state) { + if (!state.selected.hasOwnProperty('id')) { + throw new Error('There is no selected group.') + } + + return state.selected.id } } diff --git a/web-frontend/utils/error.js b/web-frontend/utils/error.js index 0ed9dcd44..5eebe08c6 100644 --- a/web-frontend/utils/error.js +++ b/web-frontend/utils/error.js @@ -18,8 +18,8 @@ export function notify404(dispatch, error, title, message) { * Adds a notification error if the response error is equal to the provided * error code. */ -export function notifyError(dispatch, error, error_code, title, message) { - if (error.responseError === error_code) { +export function notifyError(dispatch, error, errorCode, title, message) { + if (error.responseError === errorCode) { dispatch( 'notification/error', {