Skip to content

Commit

Permalink
Merge pull request #8205 from artoscinote/ma_SCI_9221
Browse files Browse the repository at this point in the history
Disable action toolbar buttons for 1 second after action, to prevent multiple submits [SCI-9221]
  • Loading branch information
artoscinote authored Feb 4, 2025
2 parents 02c180c + ba997d2 commit e005eef
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 6 deletions.
11 changes: 9 additions & 2 deletions app/javascript/vue/components/action_toolbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<div v-if="!loading && actions.length === 0" class="sn-action-toolbar__message">
{{ i18n.t('action_toolbar.no_actions') }}
</div>
<div v-for="action in actions" :key="action.name" class="sn-action-toolbar__action shrink-0">
<div v-for="action in actions" :key="action.name" class="sn-action-toolbar__action shrink-0" :class="{ 'disable-click': disabledActions[action.name] }">
<div v-if="action.type === 'group' && Array.isArray(action.actions) && action.actions.length > 1" class="export-actions-dropdown sci-dropdown dropup">
<button class="btn btn-primary dropdown-toggle single-object-action rounded" type="button" id="exportDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true" data-e2e="e2e-DD-actionToolbar-export">
<i class="sn-icon sn-icon-export"></i>
Expand Down Expand Up @@ -96,7 +96,8 @@ export default {
bottomOffset: 0,
leftOffset: 0,
buttonOverflow: false,
submitting: false
submitting: false,
disabledActions: {}
};
},
created() {
Expand Down Expand Up @@ -169,6 +170,12 @@ export default {
this.actionsLoadedCallback = func;
},
doAction(action, event) {
this.disabledActions[action.name] = true;
setTimeout(() => {
delete this.disabledActions[action.name];
}, 1000); // enable action after one second, to prevent multi-clicks
switch (action.type) {
case 'legacy':
// do nothing, this is handled by legacy code based on the button class
Expand Down
13 changes: 9 additions & 4 deletions app/javascript/vue/shared/datatable/action_toolbar.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<template>
<div class="p-4 w-full rounded bg-sn-light-grey min-h-[68px]" :class="{ 'disable-click': submitting }" data-e2e="e2e-CO-actionToolbar">
<div class="p-4 w-full rounded bg-sn-light-grey min-h-[68px]" data-e2e="e2e-CO-actionToolbar">
<div class="flex gap-4 items-center h-full">
<div v-if="loading && !actions.length" class="sn-action-toolbar__action">
<a class="rounded flex items-center py-1.5 px-2.5 bg-transparent text-transparent no-underline"></a>
</div>
<div v-if="!loading && actions.length === 0" class="text-sn-grey-grey">
{{ i18n.t('action_toolbar.no_actions') }}
</div>
<div v-for="action in actions" :key="action.name" class="sn-action-toolbar__action shrink-0">
<div v-for="action in actions" :key="action.name" class="sn-action-toolbar__action shrink-0" :class="{ 'disable-click': disabledActions[action.name] }">
<a :class="`rounded flex gap-2 items-center py-1.5 px-1.5 xl:px-2.5 hover:text-sn-white hover:bg-sn-blue
bg-sn-white color-sn-blue hover:no-underline focus:no-underline ${action.button_class}`"
:href="(['link', 'remote-modal']).includes(action.type) ? action.path : '#'"
Expand Down Expand Up @@ -42,7 +42,7 @@ export default {
reloadCallback: null,
loaded: false,
loading: true,
submitting: false
disabledActions: {}
};
},
watch: {
Expand Down Expand Up @@ -70,10 +70,15 @@ export default {
});
},
doAction(action, event) {
this.disabledActions[action.name] = true;
setTimeout(() => {
delete this.disabledActions[action.name];
}, 1000); // enable action after one second, to prevent multi-clicks
switch (action.type) {
case 'emit':
event.preventDefault();
this.submitting = true;
this.$emit('toolbar:action', action);
break;
case 'modal':
Expand Down

0 comments on commit e005eef

Please sign in to comment.