@@ -531,6 +531,8 @@ export const ChangeRequestPageInner: FC<ChangeRequestPageInnerType> = ({
531531 return `${ matchingUser . first_name } ${ matchingUser . last_name } `
532532 } )
533533 const approved = ! ! approval && ! ! approval . approved_at
534+ // Locks the CR UI once any reviewer has approved.
535+ const hasApprovals = changeRequest . approvals . some ( ( v ) => ! ! v . approved_at )
534536 const isYourChangeRequest = changeRequest . user === AccountStore . getUser ( ) . id
535537
536538 const user =
@@ -548,7 +550,7 @@ export const ChangeRequestPageInner: FC<ChangeRequestPageInnerType> = ({
548550 < Button theme = 'secondary' onClick = { deleteChangeRequest } >
549551 Delete
550552 </ Button >
551- { editChangeRequest && (
553+ { editChangeRequest && ! hasApprovals && (
552554 < Button onClick = { editChangeRequest } className = 'ml-2' >
553555 Edit
554556 </ Button >
@@ -562,6 +564,14 @@ export const ChangeRequestPageInner: FC<ChangeRequestPageInnerType> = ({
562564 by { user ? `${ user . first_name } ${ user . last_name } ` : 'Unknown user' }
563565 </ PageTitle >
564566 < p className = 'mt-2' > { changeRequest . description } </ p >
567+ { hasApprovals && isYours && ! changeRequest . committed_at && (
568+ < div className = 'col-md-6 mb-4' >
569+ < InfoMessage >
570+ This change request has been approved and can no longer be edited.
571+ Delete it and create a new change request to make further changes.
572+ </ InfoMessage >
573+ </ div >
574+ ) }
565575 { isScheduled && (
566576 < div className = 'col-md-6 mb-4' >
567577 < InfoMessage icon = 'calendar' title = 'Scheduled Change' >
@@ -584,15 +594,21 @@ export const ChangeRequestPageInner: FC<ChangeRequestPageInnerType> = ({
584594 < >
585595 { ! Utils . getFlagsmithHasFeature ( 'disable_users_as_reviewers' ) && (
586596 < div className = 'mb-4' >
587- < SettingsButton onClick = { ( ) => setShowUsers ( true ) } >
588- Assigned users
589- </ SettingsButton >
597+ { hasApprovals ? (
598+ < div className = 'font-weight-medium mb-2' > Assigned users</ div >
599+ ) : (
600+ < SettingsButton onClick = { ( ) => setShowUsers ( true ) } >
601+ Assigned users
602+ </ SettingsButton >
603+ ) }
590604 < Row className = 'mt-2' >
591605 { ownerUsers . length !== 0 &&
592606 ownerUsers . map ( ( u ) => (
593607 < Row
594608 key = { u . id }
595- onClick = { ( ) => removeOwner ( u . id ) }
609+ onClick = {
610+ hasApprovals ? undefined : ( ) => removeOwner ( u . id )
611+ }
596612 className = 'chip'
597613 style = { {
598614 marginBottom : 4 ,
@@ -602,53 +618,67 @@ export const ChangeRequestPageInner: FC<ChangeRequestPageInnerType> = ({
602618 < span className = 'font-weight-bold' >
603619 { u . first_name } { u . last_name }
604620 </ span >
605- < span className = 'chip-icon ion' >
606- < IonIcon icon = { close } />
607- </ span >
621+ { ! hasApprovals && (
622+ < span className = 'chip-icon ion' >
623+ < IonIcon icon = { close } />
624+ </ span >
625+ ) }
608626 </ Row >
609627 ) ) }
610628 </ Row >
611- < UserSelect
612- users = { orgUsers }
613- value = { ownerUsers && ownerUsers . map ( ( v ) => v . id ) }
614- onAdd = { addOwner }
615- onRemove = { removeOwner }
616- isOpen = { showUsers }
617- onToggle = { ( ) => setShowUsers ( ! showUsers ) }
618- />
629+ { ! hasApprovals && (
630+ < UserSelect
631+ users = { orgUsers }
632+ value = { ownerUsers && ownerUsers . map ( ( v ) => v . id ) }
633+ onAdd = { addOwner }
634+ onRemove = { removeOwner }
635+ isOpen = { showUsers }
636+ onToggle = { ( ) => setShowUsers ( ! showUsers ) }
637+ />
638+ ) }
619639 </ div >
620640 ) }
621641 < div className = 'mb-4' >
622- < SettingsButton onClick = { ( ) => setShowGroups ( true ) } >
623- Assigned groups
624- </ SettingsButton >
642+ { hasApprovals ? (
643+ < div className = 'font-weight-medium mb-2' > Assigned groups</ div >
644+ ) : (
645+ < SettingsButton onClick = { ( ) => setShowGroups ( true ) } >
646+ Assigned groups
647+ </ SettingsButton >
648+ ) }
625649 < Row className = 'mt-2' >
626650 { ! ! ownerGroups ?. length &&
627651 ownerGroups . map ( ( g ) => (
628652 < Row
629653 key = { g . id }
630- onClick = { ( ) => removeOwner ( g . id , false ) }
654+ onClick = {
655+ hasApprovals ? undefined : ( ) => removeOwner ( g . id , false )
656+ }
631657 className = 'chip'
632658 style = { {
633659 marginBottom : 4 ,
634660 marginTop : 4 ,
635661 } }
636662 >
637663 < span className = 'font-weight-bold' > { g . name } </ span >
638- < span className = 'chip-icon ion' >
639- < IonIcon icon = { close } />
640- </ span >
664+ { ! hasApprovals && (
665+ < span className = 'chip-icon ion' >
666+ < IonIcon icon = { close } />
667+ </ span >
668+ ) }
641669 </ Row >
642670 ) ) }
643671 </ Row >
644- < MyGroupsSelect
645- orgId = { AccountStore . getOrganisation ( ) . id }
646- value = { ownerGroups && ownerGroups . map ( ( v ) => v . id ) }
647- onAdd = { addOwner }
648- onRemove = { removeOwner }
649- isOpen = { showGroups }
650- onToggle = { ( ) => setShowGroups ( ! showGroups ) }
651- />
672+ { ! hasApprovals && (
673+ < MyGroupsSelect
674+ orgId = { AccountStore . getOrganisation ( ) . id }
675+ value = { ownerGroups && ownerGroups . map ( ( v ) => v . id ) }
676+ onAdd = { addOwner }
677+ onRemove = { removeOwner }
678+ isOpen = { showGroups }
679+ onToggle = { ( ) => setShowGroups ( ! showGroups ) }
680+ />
681+ ) }
652682 </ div >
653683 </ >
654684 }
0 commit comments