Adds notes visibility toggle (#44)
* added notes * moved around components * Addressed feedback
This commit is contained in:
@@ -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 && <CourseSock verifiedMode={verifiedMode} />}
|
||||
{showCalculator && <Calculator />}
|
||||
<ContentTools course={course} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
33
src/courseware/course/tools/ContentTools.jsx
Normal file
33
src/courseware/course/tools/ContentTools.jsx
Normal file
@@ -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 (
|
||||
<div className="content-tools">
|
||||
<div className="d-flex justify-content-end m-0">
|
||||
{course.showCalculator && (
|
||||
<Calculator />
|
||||
)}
|
||||
{course.notes.enabled && (
|
||||
<NotesVisibility course={course} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
ContentTools.propTypes = {
|
||||
course: PropTypes.shape({
|
||||
notes: PropTypes.shape({
|
||||
enabled: PropTypes.bool,
|
||||
}),
|
||||
showCalculator: PropTypes.bool,
|
||||
}).isRequired,
|
||||
};
|
||||
7
src/courseware/course/tools/calculator/calculator.scss
Normal file
7
src/courseware/course/tools/calculator/calculator.scss
Normal file
@@ -0,0 +1,7 @@
|
||||
.calculator {
|
||||
width: 100%;
|
||||
.calculator-content {
|
||||
background-color: #f1f1f1;
|
||||
box-shadow: 0 -1px 0 0 #ddd;
|
||||
}
|
||||
}
|
||||
@@ -41,8 +41,8 @@ class Calculator extends Component {
|
||||
render() {
|
||||
return (
|
||||
<Collapsible.Advanced className="calculator">
|
||||
<div className="container-fluid text-right">
|
||||
<Collapsible.Trigger tag="a" className="calculator-trigger btn">
|
||||
<div className="text-right">
|
||||
<Collapsible.Trigger tag="a" className="trigger btn">
|
||||
<Collapsible.Visible whenOpen>
|
||||
<FontAwesomeIcon icon={faTimesCircle} aria-hidden="true" className="mr-2" />
|
||||
</Collapsible.Visible>
|
||||
6
src/courseware/course/tools/data/api.js
Normal file
6
src/courseware/course/tools/data/api.js
Normal file
@@ -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);
|
||||
}
|
||||
66
src/courseware/course/tools/notes/NotesVisibility.jsx
Normal file
66
src/courseware/course/tools/notes/NotesVisibility.jsx
Normal file
@@ -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 (
|
||||
<div className="trigger" style={{ width: '200px' }}>
|
||||
<div
|
||||
role="switch"
|
||||
className={`btn ${this.state.visible ? 'text-secondary' : 'text-success'}`}
|
||||
onClick={this.handleClick}
|
||||
onKeyDown={this.handleClick}
|
||||
tabIndex="-1"
|
||||
aria-checked={this.state.visible ? 'true' : 'false'}
|
||||
>
|
||||
<FontAwesomeIcon icon={faPencilAlt} aria-hidden="true" className="mr-2" />
|
||||
{this.props.intl.formatMessage(messages[message])}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
16
src/courseware/course/tools/notes/messages.js
Normal file
16
src/courseware/course/tools/notes/messages.js
Normal file
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ function normalizeMetadata(metadata) {
|
||||
verifiedMode: camelCaseObject(metadata.verified_mode),
|
||||
tabs: camelCaseObject(metadata.tabs),
|
||||
showCalculator: metadata.show_calculator,
|
||||
notes: camelCaseObject(metadata.notes),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user