-
Notifications
You must be signed in to change notification settings - Fork 1
Getting Started
See also the backend Getting Started page.
This application was bootstrapped with Create React App; the documentation has some useful basic information.
The following libraries are used heavily:
- React
- Redux
- React Redux
- Redux Thunk
- React Router (but mostly only in one file)
It will be helpful to install the React DevTools and the Redux DevTools.
Many other libraries are used as well (it's JavaScript, what do you expect?), but typically, either they're not critical to understanding how the application works or it's very obvious what they do. In particular:
- Axios is a promise-based JavaScript HTTP client
- immutability-helper provides some syntax sugar for creating a mutated copy of an object
- React Bootstrap provides React components for Bootstrap (NB: we use the old version with Bootstrap 3)
Be aware that most dependencies are months or years out of date, so documentation for the most recent versions may not be useful.
The entrypoint for the application is src/index.js
. This file:
- sets up the Redux store, and installs the Redux Thunk and Connected React Router middlewares
- contains the root component,
App
, which:- installs Axios interceptors to catch unhandled errors and cache/deduplicate in-flight network requests
- fetches some basic data (e.g. the ID of the currently logged-in user) that the rest of the application uses
- uses React Router to display other components depending on the path the user has navigated to (with an ugly special case to display a nicer error if a student tries to access the portal before they have been invited to the first rotation)
- renders the
App
(and theProvider
from React Redux) into the element with IDroot
(located inpublic/index.html
)
The rest of the frontend is roughly split up into six sections:
-
public/
contains files that will be included verbatim in the build -
src/actions/
contains Redux/Redux Thunk action creators that talk to the backend API -
src/components/
contains React components that aren't stand-alone pages -
src/interceptors/
contains two Axios interceptors:-
src/interceptors/cache.js
caches in-flight network requests – since each component is (by and large) responsible for fetching its own data, many network requests can sometimes be made simultaneously to the same API endpoint; this interceptor ensures that if two requests are made simultaneously, only one network request will actually go over the wire (this may be a premature optimisation!) -
src/interceptors/errors.js
shows a pop-up message whenever a network request fails, and redirects to the login page if the failure was authentication-related (though if the request included a header called_axios
, this interceptor ignores it and does not show a popup)
-
-
src/pages/
contains larger React components which will be rendered by React Router insrc/index.js
-
src/reducers/
contains the Redux reducer that updates the global state based on actions emitted by the functions insrc/actions/
plus a few other files:
-
src/config.js
extracts data from environment variables into JavaScript variables (NB: these are substituted automatically at build-time) -
src/constants.js
defines things like the names of roles, the programmes a project can relate to, what grades a report can have, etc. (NB: these are mostly duplicated in the backend, and should be kept in sync if at all possible – see #25) -
src/header.js
should really be insrc/components/
, but isn't -
src/index.css
is nominally the CSS forsrc/index.js
, but is actually just a bunch of miscellaneous styles
Some conventions/paradigms are common to many JavaScript projects:
- Redux action creators should either return a Redux action (i.e. an object with a
type
property) or an async action – in this project, all async actions are thunks that take adispatch
and (potentially) agetState
argument and then dispatch other action creators. - All async actions should return a promise which the caller can call
.then()
and/or.catch()
on. - Actions (not async actions!) typically come in pairs of "request" and "receive", which should always be dispatched in equal quantity (though NB: the "request" actions in this project have a number associated with them so that one "request" can be emitted for many entities, but the "receive" actions should always be emitted once for each entity received).
Others are specific to this project:
- Action creators which return an action (as opposed to ones which return a thunk) have names which start with
request
orreceive
(or in one caseremove
), and are only called by other (async) actions. - If an HTTP request includes an
_axios
header, then the interceptor that displays an error message on failure is disabled for that request. - "Rotations" are usually referred to as "groups", for historical reasons. In newer code they are referred to as "rotations".
- The visibility of a rotation (i.e. the
student_viewable
attribute, or theview_projects_predeadline
role) refers to the projects within that rotation, not the rotation itself – the serialised rotation (series, part, deadlines, ...) is always visible to all users.