@@ -17,6 +17,9 @@ import { STATEFUL_BUTTON_STATES } from '@src/constants';
1717import getPageHeadTitle from '@src/generic/utils' ;
1818import { useScrollToHashElement } from '@src/hooks' ;
1919import { useCourseAuthoringContext } from '@src/CourseAuthoringContext' ;
20+ import { useUserPermissionsWithAuthzCourse } from '@src/authz/hooks' ;
21+ import { getScheduleAndDetailsPermissions } from '@src/authz/permissionHelpers' ;
22+ import PermissionDeniedAlert from '@src/generic/PermissionDeniedAlert' ;
2023
2124import {
2225 fetchCourseSettingsQuery ,
@@ -49,12 +52,19 @@ const ScheduleAndDetails = () => {
4952 const courseDetails = useSelector ( getCourseDetails ) ;
5053 const loadingDetailsStatus = useSelector ( getLoadingDetailsStatus ) ;
5154 const loadingSettingsStatus = useSelector ( getLoadingSettingsStatus ) ;
52- const isLoading = loadingDetailsStatus === RequestStatus . IN_PROGRESS
53- || loadingSettingsStatus === RequestStatus . IN_PROGRESS ;
5455
5556 const { courseId, courseDetails : course } = useCourseAuthoringContext ( ) ;
5657 document . title = getPageHeadTitle ( course ?. name || '' , intl . formatMessage ( messages . headingTitle ) ) ;
5758
59+ const {
60+ isLoading : isLoadingUserPermissions ,
61+ permissions : userPermissions ,
62+ } = useUserPermissionsWithAuthzCourse ( courseId , getScheduleAndDetailsPermissions ( courseId ) ) ;
63+
64+ const isLoading = loadingDetailsStatus === RequestStatus . IN_PROGRESS
65+ || loadingSettingsStatus === RequestStatus . IN_PROGRESS
66+ || isLoadingUserPermissions ;
67+
5868 const {
5969 platformName,
6070 isCreditCourse,
@@ -144,6 +154,10 @@ const ScheduleAndDetails = () => {
144154 const { overview : initialOverview } = courseDetails || { } ;
145155 const { aboutSidebarHtml : initialAboutSidebarHtml } = courseDetails || { } ;
146156
157+ if ( ! isLoadingUserPermissions && ! userPermissions . canViewScheduleAndDetails ) {
158+ return < PermissionDeniedAlert /> ;
159+ }
160+
147161 if ( isLoading ) {
148162 // eslint-disable-next-line react/jsx-no-useless-fragment
149163 return < > </ > ;
@@ -157,6 +171,9 @@ const ScheduleAndDetails = () => {
157171 ) ;
158172 }
159173
174+ const isScheduleEditable = ! isLoadingUserPermissions && userPermissions . canEditSchedule ;
175+ const isDetailsEditable = ! isLoadingUserPermissions && userPermissions . canEditDetails ;
176+
160177 const showCreditSection = creditEligibilityEnabled && isCreditCourse ;
161178 const showRequirementsSection = aboutPageEditable || isPrerequisiteCoursesEnabled || isEntranceExamsEnabled ;
162179 const hasErrors = ! ! Object . keys ( errorFields ) . length ;
@@ -255,6 +272,7 @@ const ScheduleAndDetails = () => {
255272 < PacingSection
256273 selfPaced = { selfPaced }
257274 startDate = { startDate }
275+ isEditable = { isDetailsEditable }
258276 onChange = { handleValuesChange }
259277 />
260278 < ScheduleSection
@@ -269,12 +287,14 @@ const ScheduleAndDetails = () => {
269287 certificateAvailableDate = { certificateAvailableDate }
270288 certificatesDisplayBehavior = { certificatesDisplayBehavior }
271289 canShowCertificateAvailableDateField = { canShowCertificateAvailableDateField }
290+ isEditable = { isScheduleEditable }
272291 onChange = { handleValuesChange }
273292 />
274293 { aboutPageEditable && (
275294 < DetailsSection
276295 language = { language }
277296 languageOptions = { languageOptions }
297+ isEditable = { isDetailsEditable }
278298 onChange = { handleValuesChange }
279299 />
280300 ) }
@@ -295,16 +315,19 @@ const ScheduleAndDetails = () => {
295315 shortDescriptionEditable = { shortDescriptionEditable }
296316 enableExtendedCourseDetails = { enableExtendedCourseDetails }
297317 videoThumbnailImageAssetPath = { videoThumbnailImageAssetPath }
318+ isEditable = { isDetailsEditable }
298319 onChange = { handleValuesChange }
299320 />
300321 { enableExtendedCourseDetails && (
301322 < >
302323 < LearningOutcomesSection
303324 learningInfo = { learningInfo }
325+ isEditable = { isDetailsEditable }
304326 onChange = { handleValuesChange }
305327 />
306328 < InstructorsSection
307329 instructors = { instructorInfo ?. instructors }
330+ isEditable = { isDetailsEditable }
308331 onChange = { handleValuesChange }
309332 />
310333 </ >
@@ -322,12 +345,14 @@ const ScheduleAndDetails = () => {
322345 isPrerequisiteCoursesEnabled = {
323346 isPrerequisiteCoursesEnabled
324347 }
348+ isEditable = { isDetailsEditable }
325349 onChange = { handleValuesChange }
326350 />
327351 ) }
328352 { licensingEnabled && (
329353 < LicenseSection
330354 license = { license }
355+ isEditable = { isDetailsEditable }
331356 onChange = { handleValuesChange }
332357 />
333358 ) }
@@ -375,7 +400,7 @@ const ScheduleAndDetails = () => {
375400 < StatefulButton
376401 key = "save-button"
377402 onClick = { handleUpdateValues }
378- disabled = { hasErrors }
403+ disabled = { hasErrors || ( ! isScheduleEditable && ! isDetailsEditable ) }
379404 state = {
380405 isQueryPending
381406 ? STATEFUL_BUTTON_STATES . pending
0 commit comments