Add loading indicator and disable buttons during actions

Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
Julius Härtl 2018-05-30 10:40:50 +02:00
parent 5ac8af27dc
commit 52895cb41e
No known key found for this signature in database
GPG key ID: 4C614C6ED2CDE6DF
3 changed files with 61 additions and 25 deletions

View file

@ -63,11 +63,12 @@
</div>
<div class="actions">
<div class="warning hidden"></div>
<input v-if="app.update" class="update" type="button" :value="t('settings', 'Update to %s', app.update)" v-on:click="update(app.id)" />
<input v-if="app.canUnInstall" class="uninstall" type="button" :value="t('settings', 'Remove')" v-on:click="remove(app.id)" />
<input v-if="app.active" class="enable" type="button" :value="t('settings','Disable')" v-on:click="disable(app.id)" />
<input v-if="!app.active" class="enable" type="button" :value="enableButtonText" v-on:click="enable(app.id)" v-tooltip.auto="enableButtonTooltip" :disabled="!app.canInstall" />
<div class="warning" v-if="app.error">{{ app.error }}</div>
<div class="icon icon-loading-small" v-if="loading(app.id)"></div>
<input v-if="app.update" class="update" type="button" :value="t('settings', 'Update to %s', app.update)" v-on:click="update(app.id)" :disabled="installing || loading(app.id)" />
<input v-if="app.canUnInstall" class="uninstall" type="button" :value="t('settings', 'Remove')" v-on:click="remove(app.id)" :disabled="installing || loading(app.id)" />
<input v-if="app.active" class="enable" type="button" :value="t('settings','Disable')" v-on:click="disable(app.id)" :disabled="installing || loading(app.id)" />
<input v-if="!app.active" class="enable" type="button" :value="enableButtonText" v-on:click="enable(app.id)" v-tooltip.auto="enableButtonTooltip" :disabled="!app.canInstall || installing || loading(app.id)" />
</div>
</div>
</template>
@ -101,7 +102,6 @@
return {
isSelected: false,
groupCheckedAppsData: false,
loading: false,
scrolled: false,
filterId: '',
};
@ -114,6 +114,15 @@
this.filterId = 'invertIconApps' + Math.floor((Math.random() * 100 )) + new Date().getSeconds() + new Date().getMilliseconds();
},
computed: {
loading() {
let self = this;
return function(id) {
return self.$store.getters.loading(id);
}
},
installing() {
return this.$store.getters.loading('install');
},
filterUrl() {
return `url(#${this.filterId})`;
},

View file

@ -82,7 +82,7 @@
.catch((error) => { OC.Notification.show(error)});
},
install(appId) {
this.$store.dispatch('installApp', { appId: appId })
this.$store.dispatch('enableApp', { appId: appId })
.then((response) => { OC.Settings.Apps.rebuildNavigation(); })
.catch((error) => { OC.Notification.show(error)});
},

View file

@ -66,6 +66,16 @@ const mutations = {
state.allApps = apps;
},
setError(state, {appId, error}) {
let app = state.apps.find(app => app.id === appId);
app.error = error;
},
clearError(state, {appId, error}) {
let app = state.apps.find(app => app.id === appId);
app.error = null;
},
enableApp(state, {appId, groups}) {
let app = state.apps.find(app => app.id === appId);
app.active = true;
@ -98,12 +108,22 @@ const mutations = {
state.updateCount = 0;
},
startLoading(state, id) {
Vue.set(state.loading, id, true);
console.log(state.loading);
if (Array.isArray(id)) {
id.forEach((_id) => {
Vue.set(state.loading, _id, true);
})
} else {
Vue.set(state.loading, id, true);
}
},
stopLoading(state, id) {
Vue.set(state.loading, id, false);
console.log(state.loading);
if (Array.isArray(id)) {
id.forEach((_id) => {
Vue.set(state.loading, _id, false);
})
} else {
Vue.set(state.loading, id, false);
}
},
};
@ -145,14 +165,22 @@ const actions = {
apps = [appId];
}
return api.requireAdmin().then((response) => {
return api.post(OC.generateUrl(`settings/apps/enable`), {appIds: apps, groups: groups})
context.commit('startLoading', apps);
context.commit('startLoading', 'install');
return api.post(OC.generateUrl(`settings/apps/enable`), {appIds: apps, groups: groups})
.then((response) => {
context.commit('stopLoading', apps);
context.commit('stopLoading', 'install');
apps.forEach(_appId => {
context.commit('enableApp', {appId: _appId, groups: groups});
});
return true;
})
.catch((error) => context.commit('APPS_API_FAILURE', { appId, error }))
.catch((error) => {
context.commit('stopLoading', apps);
context.commit('stopLoading', 'install');
context.commit('APPS_API_FAILURE', { appId, error })
})
}).catch((error) => context.commit('API_FAILURE', { appId, error }));
},
disableApp(context, { appId }) {
@ -163,35 +191,34 @@ const actions = {
apps = [appId];
}
return api.requireAdmin().then((response) => {
context.commit('startLoading', apps);
return api.post(OC.generateUrl(`settings/apps/disable`), {appIds: apps})
.then((response) => {
context.commit('stopLoading', apps);
apps.forEach(_appId => {
context.commit('disableApp', _appId);
});
return true;
})
.catch((error) => context.commit('APPS_API_FAILURE', { appId, error }))
}).catch((error) => context.commit('API_FAILURE', { appId, error }));
},
// TODO: use enable app
installApp(context, { appId }) {
return api.requireAdmin().then((response) => {
return api.get(OC.generateUrl(`settings/apps/enable/${appId}`))
.then((response) => {
context.commit('enableApp', appId);
return true;
.catch((error) => {
context.commit('stopLoading', apps);
context.commit('APPS_API_FAILURE', { appId, error })
})
.catch((error) => context.commit('APPS_API_FAILURE', { appId, error }))
}).catch((error) => context.commit('API_FAILURE', { appId, error }));
},
uninstallApp(context, { appId }) {
return api.requireAdmin().then((response) => {
context.commit('startLoading', appId);
return api.get(OC.generateUrl(`settings/apps/uninstall/${appId}`))
.then((response) => {
context.commit('stopLoading', appId);
context.commit('uninstallApp', appId);
return true;
})
.catch((error) => context.commit('APPS_API_FAILURE', { appId, error }))
.catch((error) => {
context.commit('stopLoading', appId);
context.commit('APPS_API_FAILURE', { appId, error })
})
}).catch((error) => context.commit('API_FAILURE', { appId, error }));
},