From 46bc45e9391b30fb8f414e9b1becbfaa68c7a766 Mon Sep 17 00:00:00 2001 From: Finomosec <1665799+Finomosec@users.noreply.github.com> Date: Mon, 1 Jun 2026 16:42:13 +0200 Subject: [PATCH] fix: parallelize batch rate API requests and guard selectedIds - Use Promise.all instead of sequential for...of loop - Add defensive check for empty/undefined selectedIds - Merge rating and clear-rating logic into single loop Co-Authored-By: Claude Opus 4.6 (1M context) --- ui/src/common/BatchRateButton.jsx | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/ui/src/common/BatchRateButton.jsx b/ui/src/common/BatchRateButton.jsx index 37a0eceab..a94af92c4 100644 --- a/ui/src/common/BatchRateButton.jsx +++ b/ui/src/common/BatchRateButton.jsx @@ -95,24 +95,25 @@ export const BatchRateButton = ({ const handleApply = async () => { setOpen(false) + if (!selectedIds || selectedIds.length === 0) { + unselectAll(resource) + return + } try { - for (const id of selectedIds) { + const requests = [] + selectedIds.forEach((id) => { if (rating > 0) { - await subsonic.setRating(id, rating) + requests.push(subsonic.setRating(id, rating)) + } else if (rating === -1) { + requests.push(subsonic.setRating(id, 0)) } if (starred === true) { - await subsonic.star(id) + requests.push(subsonic.star(id)) } else if (starred === false) { - await subsonic.unstar(id) + requests.push(subsonic.unstar(id)) } - } - // Clear rating if "delete" was chosen (rating === -1) - if (rating === -1) { - for (const id of selectedIds) { - await subsonic.setRating(id, 0) - } - } - // Force React-Admin to re-fetch the records, then refresh the view + }) + await Promise.all(requests) await dataProvider.getMany(resource, { ids: selectedIds }) notify('message.batchRateSuccess', { type: 'info' }) refresh()