Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/course-tabs/CourseTabsNavigation.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,14 @@ const CourseTabsNavigation = ({
className={classNames('nav-item flex-shrink-0 nav-link', { active: slug === activeTabSlug })}
href={url}
>
{title}
{(() => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a part of the RGA plugin i18n system.
See used RGA revision and fix there.

switch (slug) {
case 'instructor_analytics':
return intl.formatMessage({ id: 'learn.tabs.instructorAnalytics', defaultMessage: 'Instructor analytics' });
default:
return title;
}
})()}
</a>
))}
</Tabs>
Expand Down
13 changes: 10 additions & 3 deletions src/instructor-toolbar/InstructorToolbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { getConfig } from '@edx/frontend-platform';

import { FormattedMessage } from '@edx/frontend-platform/i18n';
import { ALERT_TYPES, AlertList } from '../generic/user-messages';
import Alert from '../generic/user-messages/Alert';
import MasqueradeWidget from './masquerade-widget';
Expand Down Expand Up @@ -75,17 +76,23 @@ const InstructorToolbar = (props) => {
{(urlStudio || urlInsights) && (
<>
<hr className="border-light" />
<span className="mr-2 mt-1 col-form-label">View course in:</span>
<span className="mr-2 mt-1 col-form-label">
<FormattedMessage id="instructorToolbar.viewCourseIn.label" defaultMessage="View course in:" />
</span>
</>
)}
{urlStudio && (
<span className="mx-1 my-1">
<a className="btn btn-inverse-outline-primary" href={urlStudio}>Studio</a>
<a className="btn btn-inverse-outline-primary" href={urlStudio}>
<FormattedMessage id="instructorToolbar.studio.link" defaultMessage="Studio" />
</a>
</span>
)}
{urlInsights && (
<span className="mx-1 my-1">
<a className="btn btn-inverse-outline-primary" href={urlInsights}>Insights</a>
<a className="btn btn-inverse-outline-primary" href={urlInsights}>
<FormattedMessage id="instructorToolbar.insights.link" defaultMessage="Insights" />
</a>
</span>
)}
</div>
Expand Down
51 changes: 32 additions & 19 deletions src/instructor-toolbar/masquerade-widget/MasqueradeWidget.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class MasqueradeWidget extends Component {
this.courseId = props.courseId;
this.state = {
autoFocus: false,
masquerade: 'Staff',
masquerade: this.props.intl.formatMessage(messages.staffLabel),
options: [],
shouldShowUserNameInput: false,
masqueradeUsername: null,
Expand All @@ -36,7 +36,7 @@ class MasqueradeWidget extends Component {
// This was explicitly denied by the backend;
// assume it's disabled/unavailable.
// eslint-disable-next-line no-console
this.onError('Unable to get masquerade options');
this.onError(this.props.intl.formatMessage(messages.optionsError));
}
}).catch((response) => {
// There's not much we can do to recover;
Expand Down Expand Up @@ -71,7 +71,7 @@ class MasqueradeWidget extends Component {
toggle(show) {
this.setState(prevState => ({
autoFocus: true,
masquerade: 'Specific Student...',
masquerade: this.props.intl.formatMessage(messages.specificStudentLabel),
shouldShowUserNameInput: show === undefined ? !prevState.shouldShowUserNameInput : show,
}));
}
Expand All @@ -80,30 +80,42 @@ class MasqueradeWidget extends Component {
const data = postData || {};
const active = data.active || {};
const available = data.available || [];
const options = available.map((group) => (
<MasqueradeWidgetOption
groupId={group.groupId}
groupName={group.name}
key={group.name}
role={group.role}
selected={active}
userName={group.userName}
userPartitionId={group.userPartitionId}
userNameInputToggle={(...args) => this.toggle(...args)}
onSubmit={(payload) => this.onSubmit(payload)}
/>
));
const options = available.map((group) => {
let localizedGroupName = group.name;
if (group.userName !== undefined) {
localizedGroupName = this.props.intl.formatMessage(messages.specificStudentLabel);
} else if (group.role === 'staff') {
localizedGroupName = this.props.intl.formatMessage(messages.staffLabel);
} else if (group.role === 'student' && !group.groupId) {
localizedGroupName = this.props.intl.formatMessage(messages.learnerLabel);
} else if (group.name === 'My certificate') {
localizedGroupName = this.props.intl.formatMessage(messages.myCertificateLabel);
}
return (
<MasqueradeWidgetOption
groupId={group.groupId}
groupName={localizedGroupName}
key={`${group.role || ''}-${group.name}`}
role={group.role}
selected={active}
userName={group.userName}
userPartitionId={group.userPartitionId}
userNameInputToggle={(...args) => this.toggle(...args)}
onSubmit={(payload) => this.onSubmit(payload)}
/>
);
});
if (active.userName) {
this.setState({
autoFocus: false,
masquerade: 'Specific Student...',
masquerade: this.props.intl.formatMessage(messages.specificStudentLabel),
masqueradeUsername: active.userName,
shouldShowUserNameInput: true,
});
} else if (active.groupName) {
this.setState({ masquerade: active.groupName });
} else if (active.role === 'student') {
this.setState({ masquerade: 'Learner' });
this.setState({ masquerade: this.props.intl.formatMessage(messages.learnerLabel) });
}
return options;
}
Expand All @@ -117,10 +129,11 @@ class MasqueradeWidget extends Component {
masqueradeUsername,
} = this.state;
const specificLearnerInputText = this.props.intl.formatMessage(messages.placeholder);
const viewThisCourseAsText = this.props.intl.formatMessage(messages.viewThisCourseAsLabel);
return (
<div className="flex-grow-1">
<div className="row">
<span className="col-auto col-form-label pl-3">View this course as:</span>
<span className="col-auto col-form-label pl-3">{viewThisCourseAsText}</span>
<Dropdown className="flex-shrink-1 mx-1">
<Dropdown.Toggle id="masquerade-widget-toggle" variant="inverse-outline-primary">
{masquerade}
Expand Down
30 changes: 30 additions & 0 deletions src/instructor-toolbar/masquerade-widget/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,36 @@ const messages = defineMessages({
defaultMessage: 'Masquerade as this user',
description: 'Label for the masquerade user input',
},
viewThisCourseAsLabel: {
id: 'masquerade-widget.viewThisCourseAs.label',
defaultMessage: 'View this course as:',
description: 'Label for masquerade dropdown in the instructor toolbar',
},
staffLabel: {
id: 'masquerade-widget.role.staff',
defaultMessage: 'Staff',
description: 'Masquerade dropdown selected label for Staff role',
},
learnerLabel: {
id: 'masquerade-widget.role.learner',
defaultMessage: 'Learner',
description: 'Masquerade dropdown selected label for Learner role',
},
specificStudentLabel: {
id: 'masquerade-widget.role.specificStudent',
defaultMessage: 'Specific Student...',
description: 'Masquerade dropdown selected label when viewing specific student',
},
myCertificateLabel: {
id: 'masquerade-widget.role.myCertificate',
defaultMessage: 'My certificate',
description: 'Masquerade dropdown label for the certificate view option',
},
optionsError: {
id: 'masquerade-widget.options.error',
defaultMessage: 'Unable to get masquerade options',
description: 'Error shown when fetching masquerade options fails',
},
});

export default messages;
Loading