diff --git a/app/src/App.vue b/app/src/App.vue index 232f31ae..b320c6d6 100644 --- a/app/src/App.vue +++ b/app/src/App.vue @@ -40,9 +40,9 @@ - + - + @@ -93,7 +93,13 @@ export default { }, computed: { - ...mapGetters(['connected', 'yunohost', 'transitions', 'waiting']) + ...mapGetters([ + 'connected', + 'yunohost', + 'routerKey', + 'transitions', + 'waiting' + ]) }, watch: { diff --git a/app/src/router/index.js b/app/src/router/index.js index 6cb71d75..86295d51 100644 --- a/app/src/router/index.js +++ b/app/src/router/index.js @@ -29,6 +29,7 @@ const router = new VueRouter({ }) router.beforeEach((to, from, next) => { + store.dispatch('UPDATE_ROUTER_KEY', { to, from }) if (store.getters.error) { store.dispatch('DISMISS_ERROR', true) } diff --git a/app/src/router/routes.js b/app/src/router/routes.js index 563b5f08..518594f5 100644 --- a/app/src/router/routes.js +++ b/app/src/router/routes.js @@ -167,6 +167,7 @@ const routes = [ component: () => import(/* webpackChunkName: "components/configPanel" */ '@/components/ConfigPanel'), props: true, meta: { + routerParams: ['name'], // Override router key params to avoid view recreation at tab change. args: { trad: 'config' }, breadcrumb: ['domain-list', 'domain-info', 'domain-config'] } @@ -267,6 +268,7 @@ const routes = [ component: () => import(/* webpackChunkName: "components/configPanel" */ '@/components/ConfigPanel'), props: true, meta: { + routerParams: ['id'], args: { trad: 'app_config_panel' }, breadcrumb: ['app-list', 'app-info', 'app-config-panel'] } diff --git a/app/src/store/info.js b/app/src/store/info.js index 67fa9027..41aade6f 100644 --- a/app/src/store/info.js +++ b/app/src/store/info.js @@ -2,7 +2,7 @@ import Vue from 'vue' import router from '@/router' import i18n from '@/i18n' import api from '@/api' -import { timeout, isObjectLiteral } from '@/helpers/commons' +import { timeout, isEmptyValue, isObjectLiteral } from '@/helpers/commons' export default { state: { @@ -15,7 +15,8 @@ export default { requests: [], // Array of `request` error: null, // null || request historyTimer: null, // null || setTimeout id - tempMessages: [] // array of messages + tempMessages: [], // Array of messages + routerKey: undefined // String if current route has params }, mutations: { @@ -87,6 +88,10 @@ export default { } else { state.error = null } + }, + + 'SET_ROUTER_KEY' (state, key) { + state.routerKey = key } }, @@ -264,6 +269,24 @@ export default { 'DISMISS_WARNING' ({ commit, state }, request) { commit('SET_WAITING', false) Vue.delete(request, 'showWarningMessage') + }, + + 'UPDATE_ROUTER_KEY' ({ commit }, { to, from }) { + if (isEmptyValue(to.params)) { + commit('SET_ROUTER_KEY', undefined) + return + } + // If the next route uses the same component as the previous one, Vue will not + // recreate an instance of that component, so hooks like `created()` will not be + // triggered and data will not be fetched. + // For routes with params, we create a unique key to force the recreation of a view. + // Params can be declared in route `meta` to stricly define which params should be + // taken into account. + const params = to.meta.routerParams + ? to.meta.routerParams.map(key => to.params[key]) + : Object.values(to.params) + + commit('SET_ROUTER_KEY', `${to.name}-${params.join('-')}`) } }, @@ -279,6 +302,7 @@ export default { currentRequest: state => { const request = state.requests.find(({ status }) => status === 'pending') return request || state.requests[state.requests.length - 1] - } + }, + routerKey: state => state.routerKey } }