1+ import { useCallback , useMemo , useState } from 'react' ;
2+
13import {
4+ Alert ,
25 Breadcrumb , Button , Card , Icon , Stack ,
36} from '@openedx/paragon' ;
47import { ArrowBack } from '@openedx/paragon/icons' ;
5- import { useCallback , useMemo , useState } from 'react' ;
8+ import { FormattedMessage , useIntl } from '@edx/frontend-platform/i18n' ;
9+
610import { ContainerType } from '@src/generic/key-utils' ;
711import ErrorAlert from '@src/generic/alert-error' ;
812import { LoadingSpinner } from '@src/generic/Loading' ;
913import { useContainer , useContainerChildren } from '@src/library-authoring/data/apiHooks' ;
10- import { useIntl } from '@edx/frontend-platform/i18n' ;
14+ import { BoldText } from '@src/utils' ;
15+
1116import ChildrenPreview from './ChildrenPreview' ;
1217import ContainerRow from './ContainerRow' ;
1318import { useCourseContainerChildren } from './data/apiHooks' ;
@@ -18,12 +23,17 @@ import messages from './messages';
1823interface ContainerInfoProps {
1924 upstreamBlockId : string ;
2025 downstreamBlockId : string ;
26+ isReadyToSyncIndividually ?: boolean ;
2127}
2228
2329interface Props extends ContainerInfoProps {
2430 parent : ContainerInfoProps [ ] ;
2531 onRowClick : ( row : WithState < ContainerChild > ) => void ;
2632 onBackBtnClick : ( ) => void ;
33+ // This two props are used to show an alert for the changes to text components with local overrides.
34+ // They may be removed in the future.
35+ localUpdateAlertCount : number ;
36+ localUpdateAlertBlockName : string ;
2737}
2838
2939/**
@@ -35,9 +45,11 @@ const CompareContainersWidgetInner = ({
3545 parent,
3646 onRowClick,
3747 onBackBtnClick,
48+ localUpdateAlertCount,
49+ localUpdateAlertBlockName,
3850} : Props ) => {
3951 const intl = useIntl ( ) ;
40- const { data, isError, error } = useCourseContainerChildren ( downstreamBlockId ) ;
52+ const { data, isError, error } = useCourseContainerChildren ( downstreamBlockId , parent . length === 0 ) ;
4153 const {
4254 data : libData ,
4355 isError : isLibError ,
@@ -127,7 +139,19 @@ const CompareContainersWidgetInner = ({
127139 }
128140
129141 return (
130- < div className = "row" >
142+ < div className = "row justify-content-center" >
143+ { localUpdateAlertCount > 0 && (
144+ < Alert variant = "info" >
145+ < FormattedMessage
146+ { ...messages . localChangeInTextAlert }
147+ values = { {
148+ blockName : localUpdateAlertBlockName ,
149+ count : localUpdateAlertCount ,
150+ b : BoldText ,
151+ } }
152+ />
153+ </ Alert >
154+ ) }
131155 < div className = "col col-6 p-1" >
132156 < Card className = "p-4" >
133157 < ChildrenPreview title = { getTitleComponent ( data ?. displayName ) } side = "Before" >
@@ -151,7 +175,11 @@ const CompareContainersWidgetInner = ({
151175 * and allows the user to select the container to view. This is a wrapper component that maintains current
152176 * source state. Actual implementation of the diff view is done by CompareContainersWidgetInner.
153177 */
154- export const CompareContainersWidget = ( { upstreamBlockId, downstreamBlockId } : ContainerInfoProps ) => {
178+ export const CompareContainersWidget = ( {
179+ upstreamBlockId,
180+ downstreamBlockId,
181+ isReadyToSyncIndividually = false ,
182+ } : ContainerInfoProps ) => {
155183 const [ currentContainerState , setCurrentContainerState ] = useState < ContainerInfoProps & {
156184 parent : ContainerInfoProps [ ] ;
157185 } > ( {
@@ -160,6 +188,23 @@ export const CompareContainersWidget = ({ upstreamBlockId, downstreamBlockId }:
160188 parent : [ ] ,
161189 } ) ;
162190
191+ const { data } = useCourseContainerChildren ( downstreamBlockId , true ) ;
192+ let localUpdateAlertBlockName = '' ;
193+ let localUpdateAlertCount = 0 ;
194+
195+ // Show this alert if the only change is text components with local overrides.
196+ // We decided not to put this in `CompareContainersWidgetInner` because if you enter a child,
197+ // the alert would disappear. By keeping this call in CompareContainersWidget,
198+ // the alert remains in the modal regardless of whether you navigate within the children.
199+ if ( ! isReadyToSyncIndividually && data ?. upstreamReadyToSyncChildrenInfo
200+ && data . upstreamReadyToSyncChildrenInfo . every ( value => value . isModified && value . blockType === 'html' )
201+ ) {
202+ localUpdateAlertCount = data . upstreamReadyToSyncChildrenInfo . length ;
203+ if ( localUpdateAlertCount === 1 ) {
204+ localUpdateAlertBlockName = data . upstreamReadyToSyncChildrenInfo [ 0 ] . name ;
205+ }
206+ }
207+
163208 const onRowClick = ( row : WithState < ContainerChild > ) => {
164209 if ( ! isRowClickable ( row . state , row . blockType as ContainerType ) ) {
165210 return ;
@@ -197,6 +242,8 @@ export const CompareContainersWidget = ({ upstreamBlockId, downstreamBlockId }:
197242 parent = { currentContainerState . parent }
198243 onRowClick = { onRowClick }
199244 onBackBtnClick = { onBackBtnClick }
245+ localUpdateAlertCount = { localUpdateAlertCount }
246+ localUpdateAlertBlockName = { localUpdateAlertBlockName }
200247 />
201248 ) ;
202249} ;
0 commit comments