99 IconButton ,
1010 useToggle ,
1111} from '@openedx/paragon' ;
12- import { useEffect , useCallback } from 'react' ;
12+ import React , { useEffect , useCallback } from 'react' ;
1313import { Link } from 'react-router-dom' ;
1414import { MoreVert } from '@openedx/paragon/icons' ;
1515
@@ -28,7 +28,8 @@ import { LibraryUnitBlocks } from '../units/LibraryUnitBlocks';
2828import messages from './messages' ;
2929import componentMessages from '../components/messages' ;
3030import ContainerDeleter from '../components/ContainerDeleter' ;
31- import { useContainer } from '../data/apiHooks' ;
31+ import { useContainer , usePublishContainer } from '../data/apiHooks' ;
32+ import { ToastContext } from '../../generic/toast-context' ;
3233
3334type ContainerMenuProps = {
3435 containerId : string ,
@@ -71,8 +72,9 @@ const UnitMenu = ({ containerId, displayName }: ContainerMenuProps) => {
7172const UnitInfo = ( ) => {
7273 const intl = useIntl ( ) ;
7374
74- const { libraryId } = useLibraryContext ( ) ;
75+ const { libraryId, readOnly } = useLibraryContext ( ) ;
7576 const { componentPickerMode } = useComponentPickerContext ( ) ;
77+ const { showToast } = React . useContext ( ToastContext ) ;
7678 const {
7779 defaultTab,
7880 hiddenTabs,
@@ -90,6 +92,7 @@ const UnitInfo = () => {
9092
9193 const unitId = sidebarComponentInfo ?. id ;
9294 const { data : container } = useContainer ( unitId ) ;
95+ const publishContainer = usePublishContainer ( unitId ! ) ;
9396
9497 const showOpenUnitButton = ! insideUnit && ! componentPickerMode ;
9598
@@ -105,6 +108,15 @@ const UnitInfo = () => {
105108 ) ;
106109 } , [ hiddenTabs , defaultTab . unit , unitId ] ) ;
107110
111+ const handlePublish = React . useCallback ( async ( ) => {
112+ try {
113+ await publishContainer . mutateAsync ( ) ;
114+ showToast ( intl . formatMessage ( messages . publishContainerSuccess ) ) ;
115+ } catch ( error ) {
116+ showToast ( intl . formatMessage ( messages . publishContainerFailed ) ) ;
117+ }
118+ } , [ publishContainer ] ) ;
119+
108120 useEffect ( ( ) => {
109121 // Show Organize tab if JumpToAddCollections action is set in sidebarComponentInfo
110122 if ( jumpToCollections ) {
@@ -118,8 +130,8 @@ const UnitInfo = () => {
118130
119131 return (
120132 < Stack >
121- { showOpenUnitButton && (
122- < div className = "d-flex flex-wrap" >
133+ < div className = "d-flex flex-wrap" >
134+ { showOpenUnitButton && (
123135 < Button
124136 variant = "outline-primary"
125137 className = "m-1 text-nowrap flex-grow-1"
@@ -128,12 +140,24 @@ const UnitInfo = () => {
128140 >
129141 { intl . formatMessage ( messages . openUnitButton ) }
130142 </ Button >
143+ ) }
144+ { ! componentPickerMode && ! readOnly && (
145+ < Button
146+ variant = "outline-primary"
147+ className = "m-1 text-nowrap flex-grow-1"
148+ disabled = { ! container . hasUnpublishedChanges || publishContainer . isLoading }
149+ onClick = { handlePublish }
150+ >
151+ { intl . formatMessage ( messages . publishContainerButton ) }
152+ </ Button >
153+ ) }
154+ { showOpenUnitButton && ( // Check: should we still show this on the unit page?
131155 < UnitMenu
132156 containerId = { unitId }
133157 displayName = { container . displayName }
134158 />
135- </ div >
136- ) }
159+ ) }
160+ </ div >
137161 < Tabs
138162 variant = "tabs"
139163 className = "my-3 d-flex justify-content-around"
0 commit comments