Miscellaneous updates to the boilerplate code. (#161)
Based on changes/things I noticed when putting together the frontend-app-account repository.
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -12,3 +12,5 @@ dist/
|
||||
|
||||
### Emacs ###
|
||||
*~
|
||||
/.vscode
|
||||
/temp
|
||||
|
||||
32
docs/decisions/0001-record-architecture-decisions.rst
Normal file
32
docs/decisions/0001-record-architecture-decisions.rst
Normal file
@@ -0,0 +1,32 @@
|
||||
1. Record Architecture Decisions
|
||||
--------------------------------
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
Accepted
|
||||
|
||||
Context
|
||||
-------
|
||||
|
||||
We would like to keep a historical record on the architectural
|
||||
decisions we make with this app as it evolves over time.
|
||||
|
||||
Decision
|
||||
--------
|
||||
|
||||
We will use Architecture Decision Records, as described by
|
||||
Michael Nygard in `Documenting Architecture Decisions`_
|
||||
|
||||
.. _Documenting Architecture Decisions: http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions
|
||||
|
||||
Consequences
|
||||
------------
|
||||
|
||||
See Michael Nygard's article, linked above.
|
||||
|
||||
References
|
||||
----------
|
||||
|
||||
* https://resources.sei.cmu.edu/asset_files/Presentation/2017_017_001_497746.pdf
|
||||
* https://github.com/npryce/adr-tools/tree/master/doc/adr
|
||||
77
package-lock.json
generated
77
package-lock.json
generated
@@ -2570,18 +2570,11 @@
|
||||
"integrity": "sha512-APBpZvdQrC1MJWMzk33V7FR2RhBRtnH2QPLqZzS+qia7PixwgWNlnX7UfHjhx+YWkM53GdsZKs40EBkSwADuMA=="
|
||||
},
|
||||
"@edx/edx-bootstrap": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@edx/edx-bootstrap/-/edx-bootstrap-2.0.0.tgz",
|
||||
"integrity": "sha512-2wuEqzLNQDxX46+rr6HHsFAEuXiAGHHCMEavjlgBDStX4mLIYJrey3vi6oOmN/qvlIFQEM17GDihrFPq46wPgQ==",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@edx/edx-bootstrap/-/edx-bootstrap-2.0.1.tgz",
|
||||
"integrity": "sha512-tq9ScRJBkUYw+0ypTshd+9+9Hnow00FkS6Rvh0RfK4xZ+rh8wNAUIVkG3TMclaW5qxvXSIE7Qo7YO7i7JrqV6A==",
|
||||
"requires": {
|
||||
"bootstrap": "^4.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"bootstrap": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.3.1.tgz",
|
||||
"integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@edx/frontend-analytics": {
|
||||
@@ -2639,9 +2632,9 @@
|
||||
"integrity": "sha512-1djcoIfT2rqqnGDTBPwuQOekgtKyk9lwriKAC2oFJeqvDhmMmqSnWUTEJde4/UiZbV7zhEMJ6GPnF9LH5bsadg=="
|
||||
},
|
||||
"@edx/paragon": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-4.1.2.tgz",
|
||||
"integrity": "sha512-0OQkclsrocwvokqIsXFZWSkcyzeF9FaT2zo9/Wb2DpbePOoy9axnnBvaU2GUCdOdGiJTM885OJT8ywCOvnUVBg==",
|
||||
"version": "4.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-4.1.4.tgz",
|
||||
"integrity": "sha512-IucQ5a8vp5Qg7A9xP8hvOb1ywTw7n4wSW9CkRDVTs7mJnbD0pPJeskkhF91GlJEtFi8tXLbjRJslNU+9qKgF4A==",
|
||||
"requires": {
|
||||
"airbnb-prop-types": "^2.12.0",
|
||||
"classnames": "^2.2.6",
|
||||
@@ -3983,9 +3976,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node-releases": {
|
||||
"version": "1.1.15",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.15.tgz",
|
||||
"integrity": "sha512-cKV097BQaZr8LTSRUa2+oc/aX5L8UkZtPQrMSTgiJEeaW7ymTDCoRaGCoaTqk0lqnalcoSHu4wjSl0Cmj2+bMw==",
|
||||
"version": "1.1.16",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.16.tgz",
|
||||
"integrity": "sha512-BOMWCW9CaT4sffMa5S9Mj4vYObvVShyo6JoM9WzzQOKVyNUn1+OVMUaQT3fo2tJKCMwHjqaDW/Pf3/JsYmPD2g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"semver": "^5.3.0"
|
||||
@@ -6396,6 +6389,11 @@
|
||||
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
||||
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
|
||||
},
|
||||
"bootstrap": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.3.1.tgz",
|
||||
"integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag=="
|
||||
},
|
||||
"boxen": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
|
||||
@@ -7878,9 +7876,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node-releases": {
|
||||
"version": "1.1.15",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.15.tgz",
|
||||
"integrity": "sha512-cKV097BQaZr8LTSRUa2+oc/aX5L8UkZtPQrMSTgiJEeaW7ymTDCoRaGCoaTqk0lqnalcoSHu4wjSl0Cmj2+bMw==",
|
||||
"version": "1.1.16",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.16.tgz",
|
||||
"integrity": "sha512-BOMWCW9CaT4sffMa5S9Mj4vYObvVShyo6JoM9WzzQOKVyNUn1+OVMUaQT3fo2tJKCMwHjqaDW/Pf3/JsYmPD2g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"semver": "^5.3.0"
|
||||
@@ -11382,7 +11380,8 @@
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
@@ -11403,12 +11402,14 @@
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@@ -11423,17 +11424,20 @@
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
@@ -11550,7 +11554,8 @@
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
@@ -11562,6 +11567,7 @@
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
@@ -11576,6 +11582,7 @@
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
@@ -11583,12 +11590,14 @@
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.3.5",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.0"
|
||||
@@ -11607,6 +11616,7 @@
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
@@ -11687,7 +11697,8 @@
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
@@ -11699,6 +11710,7 @@
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@@ -11784,7 +11796,8 @@
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
@@ -11820,6 +11833,7 @@
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
@@ -11839,6 +11853,7 @@
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
@@ -11882,12 +11897,14 @@
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.3",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -25,13 +25,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@cospired/i18n-iso-languages": "^2.0.2",
|
||||
"@edx/edx-bootstrap": "^2.0.0",
|
||||
"@edx/edx-bootstrap": "^2.0.1",
|
||||
"@edx/frontend-analytics": "^1.0.0",
|
||||
"@edx/frontend-auth": "^4.0.0",
|
||||
"@edx/frontend-component-footer": "^2.0.3",
|
||||
"@edx/frontend-component-site-header": "^2.1.4",
|
||||
"@edx/frontend-logging": "^1.0.2",
|
||||
"@edx/paragon": "^4.1.2",
|
||||
"@edx/paragon": "^4.1.3",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.14",
|
||||
"@fortawesome/free-brands-svg-icons": "^5.7.2",
|
||||
"@fortawesome/free-regular-svg-icons": "^5.7.1",
|
||||
|
||||
@@ -1,18 +1,37 @@
|
||||
import React from 'react';
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
function PageLoading() {
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
className="d-flex justify-content-center align-items-center flex-column"
|
||||
style={{
|
||||
height: '50vh',
|
||||
}}
|
||||
>
|
||||
<div className="spinner-border text-primary" role="status" />
|
||||
export default class PageLoading extends Component {
|
||||
renderSrMessage() {
|
||||
if (!this.props.srMessage) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<span className="sr-only">
|
||||
{this.props.srMessage}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
className="d-flex justify-content-center align-items-center flex-column"
|
||||
style={{
|
||||
height: '50vh',
|
||||
}}
|
||||
>
|
||||
<div className="spinner-border text-primary" role="status">
|
||||
{this.renderSrMessage()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default PageLoading;
|
||||
PageLoading.propTypes = {
|
||||
srMessage: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
@@ -28,7 +28,7 @@ function PageContent({
|
||||
intl,
|
||||
}) {
|
||||
if (!ready) {
|
||||
return <PageLoading />;
|
||||
return <PageLoading srMessage={intl.formatMessage(messages['app.loading.message'])} />;
|
||||
}
|
||||
|
||||
const mainMenu = [
|
||||
@@ -56,7 +56,7 @@ function PageContent({
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
href: `${process.env.BASE_URL}/u/${username}`,
|
||||
href: `${process.env.LMS_BASE_URL}/u/${username}`,
|
||||
content: intl.formatMessage(messages['siteheader.user.menu.profile']),
|
||||
},
|
||||
{
|
||||
|
||||
@@ -46,6 +46,11 @@ const messages = defineMessages({
|
||||
defaultMessage: 'Sign Up',
|
||||
description: 'Link to registration',
|
||||
},
|
||||
'app.loading.message': {
|
||||
id: 'app.loading.message',
|
||||
defaultMessage: 'Loading',
|
||||
description: 'Message shown when page content is loading.',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
|
||||
@@ -8,21 +8,37 @@
|
||||
"siteheader.user.menu.logout": "Logout",
|
||||
"siteheader.user.menu.login": "Login",
|
||||
"siteheader.user.menu.register": "Sign Up",
|
||||
"app.loading.message": "Loading",
|
||||
"profile.error.message.text": "An unexpected error occurred. Please click the button below to return to your profile and try again.",
|
||||
"profile.error.button.text": "Return to Your Profile",
|
||||
"profile.notfound.message": "The page you're looking for is unavailable or there's an error in the URL. Please check the URL and try again.",
|
||||
"profile.age.headline": "Your profile cannot be shared.",
|
||||
"profile.age.details": "To share your profile with other edX learners, you must confirm that you are over the age of 13.",
|
||||
"profile.age.set.date": "Set your date of birth",
|
||||
"profile.datejoined.member.since": "Member since {year}",
|
||||
"profile.bio.empty": "Add a short bio",
|
||||
"profile.bio.about.me": "About Me",
|
||||
"profile.certificate.organization.label": "From",
|
||||
"profile.certificate.completion.date.label": "Completed on {date}",
|
||||
"profile.no.certificates": "You don't have any certificates yet.",
|
||||
"profile.certificates.my.certificates": "My Certificates",
|
||||
"profile.certificates.view.certificate": "View Certificate",
|
||||
"profile.certificates.types.verified": "Verified Certificate",
|
||||
"profile.certificates.types.professional": "Professional Certificate",
|
||||
"profile.certificates.types.unknown": "Certificate",
|
||||
"profile.country.label": "Location",
|
||||
"profile.country.empty": "Add location",
|
||||
"profile.datejoined.member.since": "Member since {year}",
|
||||
"profile.education.empty": "Add education",
|
||||
"profile.education.education": "Education",
|
||||
"profile.education.levels.p": "Doctorate",
|
||||
"profile.education.levels.m": "Master's or professional degree",
|
||||
"profile.education.levels.b": "Bachelor's Degree",
|
||||
"profile.education.levels.a": "Associate's degree",
|
||||
"profile.education.levels.hs": "Secondary/high school",
|
||||
"profile.education.levels.jhs": "Junior secondary/junior high/middle school",
|
||||
"profile.education.levels.el": "Elementary/primary school",
|
||||
"profile.education.levels.none": "No formal education",
|
||||
"profile.education.levels.o": "Other education",
|
||||
"profile.editbutton.edit": "Edit",
|
||||
"profile.formcontrols.who.can.see": "Who can see this:",
|
||||
"profile.formcontrols.button.cancel": "Cancel",
|
||||
@@ -31,14 +47,17 @@
|
||||
"profile.formcontrols.button.saved": "Saved",
|
||||
"profile.visibility.who.just.me": "Just me",
|
||||
"profile.visibility.who.everyone": "Everyone on edX",
|
||||
"profile.name.full.name": "Full Name",
|
||||
"profile.name.details": "This is the name that appears in your account and on your certificates.",
|
||||
"profile.name.empty": "Add name",
|
||||
"profile.name.full.name": "Full Name",
|
||||
"profile.preferredlanguage.label": "Language",
|
||||
"profile.preferredlanguage.empty": "Add language",
|
||||
"profile.preferredlanguage.label": "Primary Language Spoken",
|
||||
"profile.profileavatar.upload-button": "Upload Photo",
|
||||
"profile.profileavatar.change-button": "Change",
|
||||
"profile.profileavatar.remove.button": "Remove",
|
||||
"profile.image.alt.attribute": "profile avatar",
|
||||
"profile.sociallinks.add": "Add {network}",
|
||||
"profile.sociallinks.social.links": "Social Links"
|
||||
"profile.sociallinks.social.links": "Social Links",
|
||||
"profile.viewMyRecords": "View My Records",
|
||||
"profile.loading": "Profile loading..."
|
||||
}
|
||||
@@ -151,7 +151,7 @@ export class ProfilePage extends React.Component {
|
||||
} = this.props;
|
||||
|
||||
if (isLoadingProfile) {
|
||||
return <PageLoading />;
|
||||
return <PageLoading srMessage={this.props.intl.formatMessage(messages['profile.loading'])} />;
|
||||
}
|
||||
|
||||
const commonFormProps = {
|
||||
|
||||
@@ -6,6 +6,11 @@ const messages = defineMessages({
|
||||
defaultMessage: 'View My Records',
|
||||
description: 'A link to go view my academic records',
|
||||
},
|
||||
'profile.loading': {
|
||||
id: 'profile.loading',
|
||||
defaultMessage: 'Profile loading...',
|
||||
description: 'Message displayed when the profile data is loading.',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
|
||||
@@ -19,7 +19,13 @@ exports[`<ProfilePage /> Renders correctly in various states app loading 1`] = `
|
||||
<div
|
||||
className="spinner-border text-primary"
|
||||
role="status"
|
||||
/>
|
||||
>
|
||||
<span
|
||||
className="sr-only"
|
||||
>
|
||||
Profile loading...
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -109,6 +109,7 @@ module.exports = Merge.smart(commonConfig, {
|
||||
BASE_URL: 'localhost:1995',
|
||||
LMS_BASE_URL: 'http://localhost:18000',
|
||||
CREDENTIALS_BASE_URL: 'http://localhost:18150',
|
||||
ECOMMERCE_BASE_URL: 'http://localhost:18130',
|
||||
LOGIN_URL: 'http://localhost:18000/login',
|
||||
LOGOUT_URL: 'http://localhost:18000/login',
|
||||
CSRF_TOKEN_API_PATH: '/csrf/api/v1/token',
|
||||
|
||||
@@ -134,6 +134,7 @@ module.exports = Merge.smart(commonConfig, {
|
||||
BASE_URL: null,
|
||||
LMS_BASE_URL: null,
|
||||
CREDENTIALS_BASE_URL: null,
|
||||
ECOMMERCE_BASE_URL: null,
|
||||
LOGIN_URL: null,
|
||||
LOGOUT_URL: null,
|
||||
CSRF_TOKEN_API_PATH: null,
|
||||
|
||||
Reference in New Issue
Block a user