Skip to content

Commit f1e6fec

Browse files
fix: add view in console button (#180)
1 parent 9757d9e commit f1e6fec

5 files changed

Lines changed: 33 additions & 3 deletions

File tree

src/courseInfo/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export interface CourseInfoResponse {
2828
},
2929
gradebookUrl: string,
3030
studioGradingUrl?: string,
31+
adminConsoleUrl: string | null,
3132
}
3233

3334
interface EnrollmentCounts extends Record<string, number> {

src/courseTeam/CourseTeamPage.test.tsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,18 @@ jest.mock('react-router-dom', () => ({
88
useParams: jest.fn(() => ({ courseId: 'course-v1:test-course' })),
99
}));
1010

11-
jest.mock('./data/apiHook', () => ({
11+
jest.mock('@src/courseTeam/data/apiHook', () => ({
1212
useAddTeamMember: () => ({ mutate: jest.fn() }),
1313
}));
1414

15+
jest.mock('@src/data/apiHook', () => ({
16+
useCourseInfo: jest.fn(() => ({
17+
data: {
18+
adminConsoleUrl: 'http://example.com/admin-console',
19+
},
20+
})),
21+
}));
22+
1523
// Mock the child components but allow passing through props
1624
jest.mock('./components/MembersContent', () => {
1725
return function MembersContent({ onEdit }: { onEdit?: (user: any) => void }) {
@@ -171,4 +179,11 @@ describe('CourseTeamPage', () => {
171179
// Modal should be visible
172180
expect(screen.getByText('Edit Team Member Modal for testuser')).toBeInTheDocument();
173181
});
182+
183+
it('renders view studio roles button with correct URL', () => {
184+
renderWithAlertAndIntl(<CourseTeamPage />);
185+
const viewRolesButton = screen.getByRole('link', { name: /view studio roles/i });
186+
expect(viewRolesButton).toBeInTheDocument();
187+
expect(viewRolesButton).toHaveAttribute('href', 'http://example.com/admin-console');
188+
});
174189
});

src/courseTeam/CourseTeamPage.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
11
import { useState } from 'react';
22
import { useIntl } from '@openedx/frontend-base';
33
import { Button, Tab, Tabs, useToggle } from '@openedx/paragon';
4-
import { Plus } from '@openedx/paragon/icons';
4+
import { Plus, TrendingUp } from '@openedx/paragon/icons';
55
import AddTeamMemberModal from '@src/courseTeam/components/AddTeamMemberModal';
66
import EditTeamMemberModal from '@src/courseTeam/components/EditTeamMemberModal';
77
import MembersContent from '@src/courseTeam/components/MembersContent';
88
import RolesContent from '@src/courseTeam/components/RolesContent';
99
import messages from '@src/courseTeam/messages';
1010
import { AlertOutlet } from '@src/providers/AlertProvider';
1111
import { CourseTeamMember } from '@src/courseTeam/types';
12+
import { useParams } from 'react-router-dom';
13+
import { useCourseInfo } from '@src/data/apiHook';
1214

1315
const CourseTeamPage = () => {
1416
const intl = useIntl();
17+
const { courseId = '' } = useParams();
1518
const [isOpenAddModal, openAddModal, closeAddModal] = useToggle(false);
1619
const [isOpenEditModal, openEditModal, closeEditModal] = useToggle(false);
1720
const [selectedUser, setSelectedUser] = useState<CourseTeamMember | null>(null);
21+
const { data } = useCourseInfo(courseId);
22+
const { adminConsoleUrl = '' } = data || {};
1823

1924
const handleEdit = (user: CourseTeamMember) => {
2025
setSelectedUser(user);
@@ -25,7 +30,10 @@ const CourseTeamPage = () => {
2530
<>
2631
<div className="d-flex justify-content-between align-items-center mb-3">
2732
<h3 className="text-primary-700 mb-0">{intl.formatMessage(messages.courseTeamTitle)}</h3>
28-
<Button iconBefore={Plus} variant="primary" onClick={openAddModal}>{intl.formatMessage(messages.addTeamMember)}</Button>
33+
<div>
34+
{adminConsoleUrl && <Button iconBefore={TrendingUp} variant="outline-primary" className="mr-3" as="a" href={adminConsoleUrl}>{intl.formatMessage(messages.viewStudioRoles)}</Button>}
35+
<Button iconBefore={Plus} variant="primary" onClick={openAddModal}>{intl.formatMessage(messages.addTeamMember)}</Button>
36+
</div>
2937
</div>
3038
<AlertOutlet />
3139
<Tabs>

src/courseTeam/messages.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,11 @@ const messages = defineMessages({
240240
id: 'instruct.courseTeam.addRoleError',
241241
defaultMessage: 'Failed to add role to {username}.',
242242
description: 'Error message displayed when adding a role to a team member fails',
243+
},
244+
viewStudioRoles: {
245+
id: 'instruct.courseTeam.viewStudioRoles',
246+
defaultMessage: 'View Studio Roles',
247+
description: 'Button label for viewing course team roles in Studio',
243248
}
244249
});
245250

src/data/apiHook.test.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const mockCourseData = {
3535
dataResearcher: false,
3636
},
3737
gradebookUrl: 'http://example.com/gradebook',
38+
adminConsoleUrl: 'http://example.com/admin-console',
3839
};
3940

4041
const createWrapper = () => {

0 commit comments

Comments
 (0)