fix(admin): keep a parallel addon toggle when a photo provider toggle fails on the phone

The phone rolled a failed photo provider toggle back by restoring the whole addon list it saw at the click, which also undid any switch flipped while the request was in flight. Photo providers now go through the same toggle as every other addon, with a per row rollback, as on desktop.
This commit is contained in:
Maurice
2026-10-09 10:33:34 +02:00
parent 163b4c54e0
commit 2a242f29fb
2 changed files with 31 additions and 19 deletions
@@ -111,7 +111,8 @@ export default function MAdminAddonManager({ bagTrackingEnabled, onToggleBagTrac
const handleToggle = async (addon: Addon) => {
const newEnabled = !addon.enabled
// Optimistic update
// Optimistic flip, per-row rollback on failure. Rolling the whole addons snapshot
// back instead would undo a toggle the user hit in parallel.
setAddons(prev => prev.map(a => a.id === addon.id ? { ...a, enabled: newEnabled } : a))
try {
await adminApi.updateAddon(addon.id, { enabled: newEnabled })
@@ -139,22 +140,6 @@ export default function MAdminAddonManager({ bagTrackingEnabled, onToggleBagTrac
return addon.type === 'trip' && (addon.icon === 'Image' || haystack.includes('photo') || haystack.includes('memories'))
}
const handleTogglePhotoProvider = async (providerAddon: Addon) => {
const enableProvider = !providerAddon.enabled
const prev = addons
setAddons(current => current.map(a => a.id === providerAddon.id ? { ...a, enabled: enableProvider } : a))
try {
await adminApi.updateAddon(providerAddon.id, { enabled: enableProvider })
refreshGlobalAddons()
toast.success(t('admin.addons.toast.updated'))
} catch {
setAddons(prev)
toast.error(t('admin.addons.toast.error'))
}
}
const photoProviderAddons = addons.filter(isPhotoProviderAddon)
const documentProviderAddons = addons.filter(a => a.type === 'document_provider')
const tripAddons = addons.filter(a => a.type === 'trip' && !isPhotosAddon(a))
@@ -165,7 +150,7 @@ export default function MAdminAddonManager({ bagTrackingEnabled, onToggleBagTrac
label: provider.name,
description: provider.description,
enabled: provider.enabled,
toggle: () => handleTogglePhotoProvider(provider),
toggle: () => handleToggle(provider),
}))
// No credential form under these, unlike the photo providers: a document
// connection belongs to a trip and is entered there. The admin only decides