From ad4c333006e7e171f9199209787b2c05317d5bd7 Mon Sep 17 00:00:00 2001 From: Joseph Amlung Date: Fri, 24 Jul 2026 11:50:56 -0400 Subject: [PATCH] OpenConceptLab/ocl_issues#2644 | fix Remove Resources by Reference dialog feedback and radio grouping Fixes two bugs in the "Remove Resources by Reference" dialog reported by MSF: 1. onExecute hardcoded deleteReferences(referenceIds, false), so choosing only "Remove reference(s)" (the recommended action for the common single-reference case) suppressed all success/error feedback and never closed the dialog or reloaded, even though the DELETE request succeeded server-side. Replaced with a combined completion handler that always surfaces success/error/queued-task status regardless of which action(s) ran, and also fixes excludeReferences silently claiming success on a 202 (queued Celery task) response instead of surfacing it like ReferenceForm.jsx already does for Add References. 2. Each resource row's RadioGroup used the literal name="reference-action", shared across every row rendered in the same dialog. Native HTML radio grouping is scoped by name across the whole page, not per React component instance, so selecting more than one resource collapsed all rows into a single mutually-exclusive group -- only one radio in the entire dialog could end up checked, regardless of each row's own recommendation. Scoped the name per row via resource.uuid. --- .../CollectionHomeChildrenList.jsx | 53 +++++++++++-------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/components/collections/CollectionHomeChildrenList.jsx b/src/components/collections/CollectionHomeChildrenList.jsx index 7b5d8042..61d27800 100644 --- a/src/components/collections/CollectionHomeChildrenList.jsx +++ b/src/components/collections/CollectionHomeChildrenList.jsx @@ -1,7 +1,7 @@ import React from 'react'; import alertifyjs from 'alertifyjs'; import { - includes, compact, isEmpty, get, merge, forEach, flatten, uniq, map, max, keys, filter + includes, compact, isEmpty, get, merge, forEach, flatten, uniq, map, max, keys, filter, some } from 'lodash'; import { Dialog, DialogContent, DialogTitle, Divider, CircularProgress, @@ -67,34 +67,43 @@ class CollectionHomeChildrenList extends React.Component { const conceptURLs = getURLs('Concept') const mappingURLs = getURLs('Mapping') - this.deleteReferences(referenceIds, false) + const requests = [] + if(!isEmpty(referenceIds)) + requests.push(this.deleteReferences(referenceIds, false)) if(!isEmpty(conceptURLs) || !isEmpty(mappingURLs)) - this.excludeReferences({concepts: conceptURLs, mappings: mappingURLs, exclude: true}) + requests.push(this.excludeReferences({concepts: conceptURLs, mappings: mappingURLs, exclude: true})) + + Promise.all(requests).then(this.onExecuteComplete) } - excludeReferences = data => { - APIService - .new() - .overrideURL(this.props.versionedObjectURL) - .appendToUrl('references/').put({data: data}).then(() => { - this.setState( - {describeDelete: false}, - () => alertifyjs.success(`Successfully executed`, 1, () => window.location.reload()) - ) - }) + onExecuteComplete = responses => { + const statuses = map(responses, response => get(response, 'status')) + this.setState({describeDelete: false}, () => { + if(some(statuses, status => !includes([200, 202, 204], status))) + alertifyjs.error('Failed!') + else if(includes(statuses, 202)) + alertifyjs.success('The request is in the queue and will be processed soon.', 10, () => window.location.reload()) + else + alertifyjs.success(`Successfully executed`, 1, () => window.location.reload()) + }) } + excludeReferences = data => APIService + .new() + .overrideURL(this.props.versionedObjectURL) + .appendToUrl('references/').put({data: data}) + deleteReferences = (referenceIds, alert = true) => { - if(!isEmpty(referenceIds)) { - APIService.new().overrideURL(this.props.versionedObjectURL).appendToUrl('references/').delete({ids: referenceIds}).then(response => { - if(alert) { - if(get(response, 'status') === 204) - alertifyjs.success(`Successfully delete references`, 1, () => window.location.reload()) - else if(alert) - alertifyjs.error('Failed!') - } + const request = APIService.new().overrideURL(this.props.versionedObjectURL).appendToUrl('references/').delete({ids: referenceIds}) + if(alert) { + request.then(response => { + if(get(response, 'status') === 204) + alertifyjs.success(`Successfully delete references`, 1, () => window.location.reload()) + else + alertifyjs.error('Failed!') }) } + return request } onReferencesDelete = items => { @@ -256,7 +265,7 @@ class CollectionHomeChildrenList extends React.Component { this.onActionChange(event, resource, value)} defaultValue={recommendedOption} >