From 81b211c76846a77845e579d4af3296950db45848 Mon Sep 17 00:00:00 2001 From: Jay George Date: Wed, 7 Jan 2026 11:43:43 +0000 Subject: [PATCH 1/4] Check for actions to be ready before showing the floating toolbar. This prevents custom actions like "Generate Social Images" from "popping in" to the floating toolbar prematurely --- resources/js/components/actions/BulkActions.vue | 10 +++++++++- resources/js/components/ui/Listing/BulkActions.vue | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/resources/js/components/actions/BulkActions.vue b/resources/js/components/actions/BulkActions.vue index 5382b1eb4a0..1661506a37d 100644 --- a/resources/js/components/actions/BulkActions.vue +++ b/resources/js/components/actions/BulkActions.vue @@ -16,6 +16,7 @@ const emit = defineEmits(['started', 'completed']); const { prepareActions, runServerAction } = useActions(); let actions = ref([]); +let actionsReady = ref(false); const confirmableActions = useTemplateRef('confirmableActions'); @@ -46,9 +47,12 @@ watch(props.selections, getActions, { deep: true }); function getActions() { if (!hasSelections.value) { actions.value = []; + actionsReady.value = false; return; } + actionsReady.value = false; + let params = { selections: toRaw(props.selections), }; @@ -59,7 +63,10 @@ function getActions() { axios .post(props.url + '/list', params) - .then(response => actions.value = response.data); + .then(response => { + actions.value = response.data; + actionsReady.value = true; + }); } let errors = ref({}); @@ -91,5 +98,6 @@ function runAction(action, values, onSuccess, onError) { diff --git a/resources/js/components/ui/Listing/BulkActions.vue b/resources/js/components/ui/Listing/BulkActions.vue index 63ef6e7f578..f2b92c9e430 100644 --- a/resources/js/components/ui/Listing/BulkActions.vue +++ b/resources/js/components/ui/Listing/BulkActions.vue @@ -40,10 +40,10 @@ function actionFailed(response) { :context="actionContext" @started="actionStarted" @completed="actionCompleted" - v-slot="{ actions }" + v-slot="{ actions, actionsReady }" > Date: Sat, 24 Jan 2026 10:34:03 +0000 Subject: [PATCH 2/4] Remove bulk actions delay, this will not be needed after #13450 --- resources/js/components/ui/Listing/BulkActions.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/js/components/ui/Listing/BulkActions.vue b/resources/js/components/ui/Listing/BulkActions.vue index d172a7a1863..35ae33c869e 100644 --- a/resources/js/components/ui/Listing/BulkActions.vue +++ b/resources/js/components/ui/Listing/BulkActions.vue @@ -49,7 +49,7 @@ function actionFailed(response) { class="sticky inset-x-0 bottom-1 sm:bottom-6 z-100 flex w-full max-w-[95vw] mx-auto justify-center " :initial="{ y: 100, opacity: 0 }" :animate="{ y: 0, opacity: 1 }" - :transition="{ duration: 0.2, delay: 0.075, ease: 'easeInOut' }" + :transition="{ duration: 0.2, ease: 'easeInOut' }" >
From 2c3091ccc40950b753721bfd85e5ec5d15e40a75 Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Sun, 25 Jan 2026 10:48:32 -0500 Subject: [PATCH 3/4] rather than completely waiting, show a loading spinner --- resources/js/components/actions/BulkActions.vue | 9 ++++----- resources/js/components/ui/Listing/BulkActions.vue | 7 ++++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/resources/js/components/actions/BulkActions.vue b/resources/js/components/actions/BulkActions.vue index 1661506a37d..9a9252afb5c 100644 --- a/resources/js/components/actions/BulkActions.vue +++ b/resources/js/components/actions/BulkActions.vue @@ -16,7 +16,7 @@ const emit = defineEmits(['started', 'completed']); const { prepareActions, runServerAction } = useActions(); let actions = ref([]); -let actionsReady = ref(false); +let loading = ref(false); const confirmableActions = useTemplateRef('confirmableActions'); @@ -47,11 +47,10 @@ watch(props.selections, getActions, { deep: true }); function getActions() { if (!hasSelections.value) { actions.value = []; - actionsReady.value = false; return; } - actionsReady.value = false; + loading.value = true; let params = { selections: toRaw(props.selections), @@ -65,7 +64,7 @@ function getActions() { .post(props.url + '/list', params) .then(response => { actions.value = response.data; - actionsReady.value = true; + loading.value = false; }); } @@ -98,6 +97,6 @@ function runAction(action, values, onSuccess, onError) { diff --git a/resources/js/components/ui/Listing/BulkActions.vue b/resources/js/components/ui/Listing/BulkActions.vue index 35ae33c869e..4dde65c8b60 100644 --- a/resources/js/components/ui/Listing/BulkActions.vue +++ b/resources/js/components/ui/Listing/BulkActions.vue @@ -2,7 +2,7 @@ import { Motion } from 'motion-v'; import { injectListingContext } from '../Listing/Listing.vue'; import { computed, ref, watch } from 'vue'; -import { Button, ButtonGroup } from '@ui'; +import { Button, ButtonGroup, Icon } from '@ui'; import BulkActions from '@/components/actions/BulkActions.vue'; const { actionUrl, actionContext, selections, refresh, clearSelections } = injectListingContext(); @@ -40,10 +40,10 @@ function actionFailed(response) { :context="actionContext" @started="actionStarted" @completed="actionCompleted" - v-slot="{ actions, actionsReady }" + v-slot="{ actions, loading }" >