To augment the robust feature set of MCF, a web interface is provided. This is a minimalistic UI to allow users basic functionality (e.g. Admin Console) and to perform CRUD operations on organizations, projects, and associated model data.
The UI is compromised mainly of React components, EJS templates, and sass/scss (CSS). Many of the React components leverage JSX, a XML-like extension to JavaScript.
The MCF takes a hybrid approach between a server side rendered multipage application and a single page application. This hybrid design was chosen because it allows for the design of separate and distinct pages, while still supporting the more modern single page application design. The pages which are served to a user can either take the form of a server side rendered EJS file, or they can utilize React in order to mount a single page application to the html file served to users with the MCF. As a result of this design decision, multiple single page applications were created specifically for projects, organizations, the home page, the profile page, and the admin console. Each have an EJS file and corresponding React entry point.
MCF has been designed to transpile JSX files into plain JavaScript which are
hosted as static assets. The build.js file found in the /scripts
directory
utilizes a bundler known as 'Webpack' with the 'Babel' extension to take care
of both transpiling and minifying React files. Babel is the compiler for the
JSX files, while Webpack is the module bundler that brings all of the files into
one place for the code to be read correctly.
React will use webpack to transpile and bundle code using node mbee build
,
or it can also be run exclusively using node mbee build --react
.
Routes define the accessible URL endpoints in the UI. Generally, routes are only used in parent (or container) components or pages. Due to the implementation and use of React with EJS templates, there is an important distinction to be made between routes defined with Express Router and those referenced and used with React Router.
Express is solely responsible for backend routes i.e. how the application's
endpoints respond to client requests (e.g. refreshing a web page). Routes
defined in the app/routes.js
file are required to specify the respective
action to take when that endpoint is accessed. From a UI perspective, this
calls a function defined within the app/controllers/ui-controller.js
which
ultimately calls Express' res.render
to select the corresponding EJS
template from app/views
and inject it into a master app/views/layout.ejs
template. The EJS file that is specified by the render()
call
utilizes the layout which automatically configures the banner, navbar,
and page layout. Additionally, the layout injects dependencies for jQuery,
Popper, Bootstrap, Font Awesome, and imports the main MCF style sheet.
This ensures that all pages designed for the MCF will appear uniform and
will be properly configured. The selected EJS file will be injected where
the <%- body %>
tag is in layout.ejs
.
The React Router is leveraged throughout the application to navigate to various
components without reloading and requesting entire pages of the application.
Typically, these routes are defined in the Sidebar
component within the
following components located in the app/ui/components
directory:
admin-console-views/admin-console-home.jsx
org-views/org-home.jsx
profile-views/profile-home.jsx
project-views/project-home.jsx
Route paths specified within this component pattern match to render the appropriate component. As mentioned earlier, this is only requesting information the component(s) require via AJAX calls as opposed to requesting an entire page from the web server.
At a high-level, the UI component structure is intended to be organized by pages or views that users can navigate to. The top level directory structure of the UI is described in the sections below.
The /apps
directory contains the "single page application" entry points for
the following: Admin Console, Home, Nav, Org, Profile, and Project. These
files are fairly minimal, only importing the main/home page component into the file
to mount it onto the html element.
The /general
directory consists of reusable components. These
components are not specific to one app and are intended to be "data agnostic",
by focusing more on the presentation and formatting aspects of the UI.
Consists of all components that makeup the home-view
sans list items
associated with Organizations and Projects.
The org-views
directory consists of the main organization pages. These components
define the general layout and routes for organizations.
The project-views
directory contains all the main project pages and components.
These items define the layout, routes, and structure for project related components.
These views encompass the following project specific components:
- Elements
- Branches/Tags
- Artifacts
- Search
The profile-views
directory contains components associated with managing
and interacting with User profiles such as: updating profile information,
passwords, and permissions.
The admin-console-views
directory encompasses components responsible for rendering
privileged user views along with associated layouts and routes.
The shared-views
directory consists mainly of components that are shared amongst
the organization, project, branch, artifacts pages. Unlike many of the components
in /general
, these components are more tightly coupled with the data on their
respective view (e.g. Org-List is solely responsible for rendering Organization data,
whereas a component residing in /general
are consider more data agnostic.