1+ import { getConfig } from '@edx/frontend-platform' ;
12import { useIntl } from '@edx/frontend-platform/i18n' ;
2- import { useToggle } from '@openedx/paragon' ;
3+ import {
4+ Tab ,
5+ Tabs ,
6+ useToggle ,
7+ } from '@openedx/paragon' ;
38import { SchoolOutline , Tag } from '@openedx/paragon/icons' ;
49
10+ import { useUserPermissions } from '@src/authz/data/apiHooks' ;
11+ import { COURSE_PERMISSIONS } from '@src/authz/constants' ;
512import { ContentTagsDrawerSheet , ContentTagsSnippet } from '@src/content-tags-drawer' ;
13+ import { useCourseSettings , useWaffleFlags } from '@src/data/apiHooks' ;
614import { ComponentCountSnippet } from '@src/generic/block-type-utils' ;
15+ import { HelpSidebarLink , otherLinkURLParams , messages as helpSidebarMessages } from '@src/generic/help-sidebar' ;
16+ import { SidebarContent , SidebarSection , SidebarTitle } from '@src/generic/sidebar' ;
717import { useGetBlockTypes } from '@src/search-manager' ;
818import { useCourseAuthoringContext } from '@src/CourseAuthoringContext' ;
919
10- import { SidebarContent , SidebarSection , SidebarTitle } from '@src/generic/sidebar' ;
11-
1220import { useCourseDetails } from '@src/course-outline/data/apiHooks' ;
1321import messages from '../messages' ;
1422
15- export const CourseInfoSidebar = ( ) => {
23+ const DetailsTab = ( ) => {
1624 const intl = useIntl ( ) ;
17- const { courseId } = useCourseAuthoringContext ( ) ;
18- const { data : courseDetails } = useCourseDetails ( courseId ) ;
1925
26+ const { courseId } = useCourseAuthoringContext ( ) ;
2027 const { data : componentData } = useGetBlockTypes (
2128 [ `context_key = "${ courseId } "` ] ,
2229 ) ;
23-
2430 const [ isManageTagsDrawerOpen , openManageTagsDrawer , closeManageTagsDrawer ] = useToggle ( false ) ;
2531
2632 return (
27- < div >
28- < SidebarTitle
29- title = { courseDetails ?. title || '' }
30- icon = { SchoolOutline }
31- />
33+ < >
3234 < SidebarContent >
3335 < SidebarSection
3436 title = { intl . formatMessage ( messages . sidebarSectionSummary ) }
@@ -54,6 +56,122 @@ export const CourseInfoSidebar = () => {
5456 onClose = { closeManageTagsDrawer }
5557 showSheet = { isManageTagsDrawerOpen }
5658 />
57- </ div >
59+ </ >
60+ ) ;
61+ } ;
62+
63+ const SettingsTab = ( ) => {
64+ const intl = useIntl ( ) ;
65+ const { courseId } = useCourseAuthoringContext ( ) ;
66+ const { data : courseSettingsData } = useCourseSettings ( courseId ) ;
67+
68+ const {
69+ grading,
70+ courseTeam,
71+ advancedSettings,
72+ scheduleAndDetails,
73+ groupConfigurations,
74+ } = otherLinkURLParams ;
75+ const waffleFlags = useWaffleFlags ( courseId ) ;
76+
77+ const proctoredExamSettingsUrl = courseSettingsData ?. mfeProctoredExamSettingsUrl ;
78+
79+ /*
80+ AuthZ for Course Authoring
81+ If authz.enable_course_authoring flag is enabled, validate permissions using AuthZ API.
82+ */
83+ const isAuthzEnabled = waffleFlags . enableAuthzCourseAuthoring ;
84+ const { isLoading : isLoadingUserPermissions , data : userPermissions } = useUserPermissions ( {
85+ canManageAdvancedSettings : {
86+ action : COURSE_PERMISSIONS . MANAGE_ADVANCED_SETTINGS ,
87+ scope : courseId ,
88+ } ,
89+ } , isAuthzEnabled ) ;
90+
91+ // If it's still loading, don't show the Advanced Settings link, otherwise, use the permission to decide
92+ const authzCanManageAdvancedSettings = isLoadingUserPermissions
93+ ? false
94+ : ! ! userPermissions ?. canManageAdvancedSettings ;
95+
96+ // When authz is enabled, use permission, otherwise it's always allowed (legacy behavior)
97+ const canManageAdvancedSettings = isAuthzEnabled ? authzCanManageAdvancedSettings : true ;
98+
99+ return (
100+ < SidebarSection
101+ title = { intl . formatMessage ( messages . settingsTabText ) }
102+ >
103+ < HelpSidebarLink
104+ as = "span"
105+ pathToPage = { `/course/${ courseId } /${ scheduleAndDetails } ` }
106+ title = { intl . formatMessage (
107+ helpSidebarMessages . sidebarLinkToScheduleAndDetails ,
108+ ) }
109+ isNewPage
110+ />
111+ < HelpSidebarLink
112+ as = "span"
113+ pathToPage = { `/course/${ courseId } /${ grading } ` }
114+ title = { intl . formatMessage ( helpSidebarMessages . sidebarLinkToGrading ) }
115+ isNewPage
116+ />
117+ < HelpSidebarLink
118+ as = "span"
119+ pathToPage = { `/course/${ courseId } /${ courseTeam } ` }
120+ title = { intl . formatMessage ( helpSidebarMessages . sidebarLinkToCourseTeam ) }
121+ isNewPage
122+ />
123+ < HelpSidebarLink
124+ as = "span"
125+ pathToPage = { `/course/${ courseId } /${ groupConfigurations } ` }
126+ title = { intl . formatMessage ( helpSidebarMessages . sidebarLinkToGroupConfigurations ) }
127+ isNewPage
128+ />
129+ { canManageAdvancedSettings && (
130+ < HelpSidebarLink
131+ as = "span"
132+ pathToPage = { `/course/${ courseId } /${ advancedSettings } ` }
133+ title = { intl . formatMessage ( helpSidebarMessages . sidebarLinkToAdvancedSettings ) }
134+ isNewPage
135+ />
136+ ) }
137+ { proctoredExamSettingsUrl && (
138+ < HelpSidebarLink
139+ as = "span"
140+ pathToPage = { proctoredExamSettingsUrl }
141+ title = { intl . formatMessage (
142+ helpSidebarMessages . sidebarLinkToProctoredExamSettings ,
143+ ) }
144+ isNewPage
145+ />
146+ ) }
147+ </ SidebarSection >
148+ ) ;
149+ } ;
150+
151+ export const CourseInfoSidebar = ( ) => {
152+ const intl = useIntl ( ) ;
153+ const { courseId } = useCourseAuthoringContext ( ) ;
154+ const { data : courseDetails } = useCourseDetails ( courseId ) ;
155+
156+ return (
157+ < >
158+ < SidebarTitle
159+ title = { courseDetails ?. title || '' }
160+ icon = { SchoolOutline }
161+ />
162+ < Tabs
163+ variant = "tabs"
164+ className = "my-2 mx-n3.5"
165+ id = "course-info-tabs"
166+ mountOnEnter
167+ >
168+ < Tab eventKey = "info" title = { intl . formatMessage ( messages . infoTabText ) } >
169+ < DetailsTab />
170+ </ Tab >
171+ < Tab eventKey = "settings" title = { intl . formatMessage ( messages . settingsTabText ) } >
172+ < SettingsTab />
173+ </ Tab >
174+ </ Tabs >
175+ </ >
58176 ) ;
59177} ;
0 commit comments