diff --git a/src/courseware/course/Course.jsx b/src/courseware/course/Course.jsx
index 1c751e8d..75af0273 100644
--- a/src/courseware/course/Course.jsx
+++ b/src/courseware/course/Course.jsx
@@ -14,7 +14,7 @@ import Sequence from './sequence';
import CourseBreadcrumbs from './CourseBreadcrumbs';
import { Header, CourseTabsNavigation } from '../../course-header';
import CourseSock from './course-sock';
-import Calculator from './calculator';
+import ContentTools from './tools/ContentTools';
import messages from './messages';
import { useModel } from '../../model-store';
@@ -54,7 +54,7 @@ function Course({
if (courseStatus === 'loaded') {
const {
- org, number, title, isStaff, tabs, verifiedMode, showCalculator,
+ org, number, title, isStaff, tabs, verifiedMode,
} = course;
return (
<>
@@ -96,7 +96,7 @@ function Course({
previousSequenceHandler={previousSequenceHandler}
/>
{verifiedMode && }
- {showCalculator && }
+
>
);
diff --git a/src/courseware/course/tools/ContentTools.jsx b/src/courseware/course/tools/ContentTools.jsx
new file mode 100644
index 00000000..0485b424
--- /dev/null
+++ b/src/courseware/course/tools/ContentTools.jsx
@@ -0,0 +1,33 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import Calculator from './calculator';
+import NotesVisibility from './notes/NotesVisibility';
+import './tools.scss';
+
+export default function ContentTools({
+ course,
+}) {
+ return (
+
+
+ {course.showCalculator && (
+
+ )}
+ {course.notes.enabled && (
+
+ )}
+
+
+ );
+}
+
+
+ContentTools.propTypes = {
+ course: PropTypes.shape({
+ notes: PropTypes.shape({
+ enabled: PropTypes.bool,
+ }),
+ showCalculator: PropTypes.bool,
+ }).isRequired,
+};
diff --git a/src/courseware/course/tools/calculator/calculator.scss b/src/courseware/course/tools/calculator/calculator.scss
new file mode 100644
index 00000000..2c5d11d0
--- /dev/null
+++ b/src/courseware/course/tools/calculator/calculator.scss
@@ -0,0 +1,7 @@
+.calculator {
+ width: 100%;
+ .calculator-content {
+ background-color: #f1f1f1;
+ box-shadow: 0 -1px 0 0 #ddd;
+ }
+}
diff --git a/src/courseware/course/calculator/index.jsx b/src/courseware/course/tools/calculator/index.jsx
similarity index 99%
rename from src/courseware/course/calculator/index.jsx
rename to src/courseware/course/tools/calculator/index.jsx
index d1739137..8d852973 100644
--- a/src/courseware/course/calculator/index.jsx
+++ b/src/courseware/course/tools/calculator/index.jsx
@@ -41,8 +41,8 @@ class Calculator extends Component {
render() {
return (
-
-
+
+
diff --git a/src/courseware/course/calculator/messages.js b/src/courseware/course/tools/calculator/messages.js
similarity index 100%
rename from src/courseware/course/calculator/messages.js
rename to src/courseware/course/tools/calculator/messages.js
diff --git a/src/courseware/course/tools/data/api.js b/src/courseware/course/tools/data/api.js
new file mode 100644
index 00000000..5084a7a2
--- /dev/null
+++ b/src/courseware/course/tools/data/api.js
@@ -0,0 +1,6 @@
+import { getConfig } from '@edx/frontend-platform';
+
+export default function toggleNotes() {
+ const iframe = document.getElementById('unit-iframe');
+ iframe.contentWindow.postMessage('tools.toggleNotes', getConfig().LMS_BASE_URL);
+}
diff --git a/src/courseware/course/tools/notes/NotesVisibility.jsx b/src/courseware/course/tools/notes/NotesVisibility.jsx
new file mode 100644
index 00000000..309d7535
--- /dev/null
+++ b/src/courseware/course/tools/notes/NotesVisibility.jsx
@@ -0,0 +1,66 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+import { getConfig } from '@edx/frontend-platform';
+import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
+import {
+ injectIntl, intlShape,
+} from '@edx/frontend-platform/i18n';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faPencilAlt } from '@fortawesome/free-solid-svg-icons';
+import toggleNotes from '../data/api';
+import messages from './messages';
+
+
+class NotesVisibility extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ visible: props.course.notes.visible,
+ };
+ this.visibilityUrl = `${getConfig().LMS_BASE_URL}/courses/${props.course.id}/edxnotes/visibility/`;
+ }
+
+ handleClick = () => {
+ const data = { visibility: this.state.visible };
+ getAuthenticatedHttpClient().put(
+ this.visibilityUrl,
+ data,
+ ).then(() => {
+ this.setState((state) => ({ visible: !state.visible }));
+ toggleNotes();
+ });
+ }
+
+ render() {
+ const message = this.state.visible ? 'notes.button.hide' : 'notes.button.show';
+ return (
+
+
+
+ {this.props.intl.formatMessage(messages[message])}
+
+
+ );
+ }
+}
+
+NotesVisibility.propTypes = {
+ intl: intlShape.isRequired,
+ course: PropTypes.shape({
+ id: PropTypes.string,
+ notes: PropTypes.shape({
+ enabled: PropTypes.bool,
+ visible: PropTypes.bool,
+ }),
+ }).isRequired,
+};
+
+export default injectIntl(NotesVisibility);
diff --git a/src/courseware/course/tools/notes/messages.js b/src/courseware/course/tools/notes/messages.js
new file mode 100644
index 00000000..253fb0f7
--- /dev/null
+++ b/src/courseware/course/tools/notes/messages.js
@@ -0,0 +1,16 @@
+import { defineMessages } from '@edx/frontend-platform/i18n';
+
+const messages = defineMessages({
+ 'notes.button.show': {
+ id: 'notes.button.show',
+ defaultMessage: 'Show Notes',
+ description: 'Message for toggling notes visibility',
+ },
+ 'notes.button.hide': {
+ id: 'notes.button.hide',
+ defaultMessage: 'Hide Notes',
+ description: 'Message for toggling notes visibility',
+ },
+});
+
+export default messages;
diff --git a/src/courseware/course/calculator/calculator.scss b/src/courseware/course/tools/tools.scss
similarity index 77%
rename from src/courseware/course/calculator/calculator.scss
rename to src/courseware/course/tools/tools.scss
index 6a64a20d..ad2337c9 100644
--- a/src/courseware/course/calculator/calculator.scss
+++ b/src/courseware/course/tools/tools.scss
@@ -1,10 +1,10 @@
-.calculator {
+.content-tools {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 100;
- .calculator-trigger {
+ .trigger {
cursor: pointer;
display: inline-block;
position: relative;
@@ -20,8 +20,4 @@
border-radius: .5rem;
}
}
- .calculator-content {
- background-color: #f1f1f1;
- box-shadow: 0 -1px 0 0 #ddd;
- }
}
diff --git a/src/data/api.js b/src/data/api.js
index 95596161..a1f38cbd 100644
--- a/src/data/api.js
+++ b/src/data/api.js
@@ -20,6 +20,7 @@ function normalizeMetadata(metadata) {
verifiedMode: camelCaseObject(metadata.verified_mode),
tabs: camelCaseObject(metadata.tabs),
showCalculator: metadata.show_calculator,
+ notes: camelCaseObject(metadata.notes),
};
}