umbrella-library
v2.1.1
Published
This library provides reusable components for use inside the SRS **Umbrella UI,** a complex customer-facing frontend appllication that employs module federation and microfrontends.
Downloads
55
Keywords
Readme
Umbrella Library
This library provides reusable components for use inside the SRS Umbrella UI, a complex customer-facing frontend appllication that employs module federation and microfrontends.
This library was originally generated with Angular CLI version 12.2.0.
[TOC]
Installation
To install and run this application locally, you need to have NodeJS installed at a version of 10.0
or greater.
To complete installation and run the app locally, please follow these instructions.
Directory Structure
/lib
- This is where the exportable library files and features are.
/lib/public-modules
- Place all components and services that will be made publicly available from this library here/lib/public-api.ts
- List all exported components and services here.
Major Features
Data Table
This custom exported component can handle -- and should be used -- for most of the many data tables used in the Umbrella UI.
Below is a list of the @input
parameters the component can handle for customization and configuration:
- label: string - A unique name and ID for the data-table
- columns: dataTable[] - An array of columns, each of type shared/types/data-table-column.type, specifying the columns of data to display
- records: any[] - The data that is to be displayed.
- totalRecordsCount: number - The number of records returned and sent to the data table.
- customCellTemplateRef: TemplateRef Described below.
- customNoDataTemplateRef: TemplateRef A template that can be used to customize what user sees when there is no data returned.
- showDownloadButton: boolean - Show/Hide download csv button
- downloadFileName: string - Downloaded csv file name
- readonly: boolean - Whether or not the table and data options should enable user interaction
- pageSize: number - The number of records to be displayed per page by default prior to user interaction.
- searchable: boolean - Whether or not the table should offer a search bar
- selectable: boolean - Whether or not the table should offer an ID column of checkboxes, enabling multi-select of the rows of the table
- selectedRecordSet: Set - The set of records currently selected.
- selectRecord: function - An EventEmitter and callback used when user selects a record. Should be used with
selectable
- fetchRecords: function - The EventEmitter function used to fetch the records from the service in the MFE
Cell Display with Format
As for display, all data is displayed as standard Ant
table data unless a format
field is present when the column is defined, or a customCellTemplateRef is used. If a format
field is defined, these are the options:
- date - The data will be displayed in the table as a date.
- twoFields - Two fields will be concatenated as strings. Useful for a full name field, for instance.
- boolean - A boolean data field will be displayed with one of two defined strings, depending on whether the data is
true
orfalse
. - label - Data can be displayed as colored labels. Pass into the
format
objectformat.type = 'label'
and aformat.labels
object with key(s) that are the value(s) you want to display labels for, and the value(s) are mini-objects containinglabelText
andlabelColor
for each value. The colors currently available aregreen
,red
andgray
. - lookupTable - A data table can be used to display text depending on the data for each row. This data table can be loaded asynchronously in the
makeLookupTables()
component function. - image - An image can be displayed, as defined in the
format.src
field.
Cell Display with CellTemplateRef
To further define custom cells displays not possible with the format
option above, a custom TemplateRef can be passed by name from the parent in the MFE
- record Required <ng-template> attribute: et-record=record
- column Optional <ng-template> attribute: et-column=column. Useful in case of multiple custom olumns with 'templateRef' format type.
Example:
<ng-template #templateRefName
let-column="column"
let-record="record">
<ng-container *ngIf="column.field === myColumnFieldName'">
{{record.fleet.name}}
</ng-container>
</ng-template>
Header
This custom component displays the header for the MFE, including the name of MFE and any buttons on the top left.
The @input
parameters for this component:
- title string - The title of the entire application.
- subTitle: string - A secondary title string.
- tags: HeaderTag[] - An array of tags for the header using
HeaderTag
type - primaryButton: ActionButton - The primary button on the upper right.
- secondaryButtons: ActionButton[] - An array of
ActionButton
that will appear to the left of the primary button. - ellipsisDropdownItems: MenuDropdownItem[] - Dropdown options.
- breadcrumbItems: HeaderBreadcrumb[] - Navigation breadcrumb links.
- navRoutes: HeaderNavRoute[].
Footer
- primaryButton: ActionButton - An optional primary button in the footer.
- secondaryButtons: ActionButton[] - An array of
ActionButton
that will appear to the left of the primary button.
Error Interceptor
The Umbrella Error Interceptor handles automatic logout for expired tokens. It should be added to all MFEs.
To add it to a MFE, simply import it in whatever module imports the HttpClientModule
(probably the MFE's Shared or App module).
- Add
HTTP_INTERCEPTORS
to your import from Angular'shttp
library - Add
UmbrellaErrorInterceptor
to your Umbrella Library import - In the Module configuration, use a
providers
property and add the Umbrella Error Interceptor
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import {
UmbrellaHeaderModule,
UmbrellaFooterModule,
UmbrellaDataTableModule,
UmbrellaErrorInterceptor
} from 'umbrella-library';
@NgModule({
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: UmbrellaErrorInterceptor,
multi: true,
}
],
imports: [
...
Note: If your MFE has its own Error Interceptor, you can simply add it as another stanza inside the providers
array. Ensure both Interceptors stanzas have the multi:true
property.
Extending the Application
Contributing
To add new features or new components to this library:
- Create a new directory in the
public-modules
directory to host your new feature. - Create your components or services there with Code Scaffolding and
ng generate
commands, as specified below. - Name your exported class the way you would like it be imported into our Umbrella microfrontends.
- Write your code to customize your component.
- Add a stanza in the
/public-api.ts
file to ensure the library will export your new feature. - Use the directions below and publish a new version to npm:
- Publish a minor version if the changes are not going to break or require changes in any other components.
- Publish as a new major version if there are breaking changes.
Whether you're adding new features or simply fixing bugs in this shared library, always:
- Write unit tests for your components.
- Use Prettier and utilize formatting and linting to add code that is compliant with the standards listed below.
- Follow the Git branching strategy below to create your branches.
- Write your Pull Request as specified below.
- Update this README if and when necessary!
- That's it! 🎉
Code Scaffolding
Run ng generate component component-name --project umbrella-library
to generate a new component. You can also use ng generate directive|pipe|service|class|guard|interface|enum|module --project umbrella-library
.
-> Note: Don't forget to add --project umbrella-library
or else it will be added to the default project in your angular.json
file.
Code Formatting
This application requires well-formatted code. It is recommended you set up automated code formatting. The easiest way to do this is to simply configure your IDE to format files on every save as follows:
Automated Formatting
Configure your IDE to run the format:all
command upon save. With VSCode, this can be done by installing a plugin such as RunOnSave. If you do install RunOnSave, simply add this configuration to your VSCode's settings.json
:
"emeraldwalk.runonsave": {
"commands": [
{
"match": ".*",
"cmd": "npm run format:all"
}
]
}
Manual Formatting
If you don't choose to set up auto-formatting, you can also manually format your code with :
- Prettier (TS, CSS). We use Prettier to format all files except for HTML (see below). Manually call npm run format:prettier
to format all TS, CSS, and config files inside the src
directory. This command is an alias for npx prettier --write src
, which you can also use if you prefer not to use the alias, and you can replace the src
with a single file or directory, and the relevant file(s) will be formatted automatically according to our current prettier standards. You can replace the --write
with --check
to simply check formatting without making changes. There's also
- JSBeautify (HTML). We use JSBeautify to format HTML files. You can use npm run format:html
to format all HTML files in the repository. You can also use npm run format:html-file [FILE]
to format a single file.
Run All Formatting. Use npm run format:all
and all TS, CSS, and HTML files inside the src
directory will be formatted automatically for you. This is command you should automate or run prior to creating your Pull Requests.
Other Commands
In addition, the following npm script commands are available when working on this application:
- Code Formatting (HTML). Use npm run format -- '[FILE]'
on an HTML template file named FILE, and the file will be formatted automatically according to our current linting standards. You can also run npm run format: all
to reformat all html files of the application at once.
- Code Linting (TS). Use npm run lint --files '[FILE]'
on a TS script file named FILE to see lint errors for that file (but make no changes to it). Append --fix
to this command to fix some of the issues automatically for you.
Git Branching Model
We use git to manage all of our development flow. Please create branches and pull requests properly. Read our Git Branching Model to accomplish this. (That document is specific to the Driver Portal, but the model is the same for this application).
Code Comments
Explanations
Generally code should be clear and not complex so that inline documentation and explanation is not necessary. However, whenever the code is complex or uses a solution or algorithm that will not be readily apparent to another engineer who might review or extend the code, always add comments explaining the solution or algorithm used. /* */
comment notation should be used for these explanatory comments.
Unused code
Code that is currently unneeded should generally be removed from the repository. There is no need to keep unused code as the git history will keep it. However, during initial buildout of features or when the API integration is unstable or not yet used, there will be times to temporarily commment out code. //
comment notation should be used. This way code comments is immediately differentiated from unneeded code.
TODOs
Tasks that should be completed soon and that are not captured in JIRA tickets can be noted with JSDoc's /* @TODO */
notation. This way a quick search on the @TODO will bring up all the tasks flagged in the code. Also if we utilize JSDoc in the future, the @TODO notation will be helpful.
Pull Requests
An optimal PR for our git history explains all of the changes that it makes to the repository with a title and description that is easy to read and to understand, and (if necessary) to revert.
PR Title
The title of the PR should be a very brief imperative-voice description of what the PR does, prefixed by the JIRA story abbreviation it addresses. (If there is no JIRA ticket, use the component that the pull request affects or "[MAINT]" if the PR addresses repository maintenance):
{{ [JIRA-XXX] }} - {{ Brief summary of what PR does }}
eg:
[FS-326] - Fix settings menu
If a pull request is not to be considered for merging (yet), please prefix the PR title with [WIP] or [DO NOT MERGE] to indicate the code isn't intended to be merged.
PR Body
While this isn't required, the body of the pull request ideally helps the next engineer review the code by following the Problem/Solution/Result pattern. Each section should contain a description or list of items. The Solution section should describe what each change does, together with any justifications, reasoning, or concerns. Include a link to the JIRA ticket when possible in the Problem section.
eg:
PROBLEM
- Description (eg: Can’t view the menu)
- [JIRA ticket link]
SOLUTION
- What you did, what files were edited, why
- (eg: Fixed menu visibility)
RESULT
- User experience change
- (eg: Menu now appears on click)
- Any changes engineers will experience
- If changes to UI are substantial or important, include screenshot of the app showing changes to the UI.
Publishing the Library
When you have finished making your changes, publish a version to npm. We use the Angular CLI and the npm package managerto build and publish the library as an npm package.
Make all of your changes inside the /projects/umbrella-library/src
directory.
Then, to build and publish to npm, step back out to the projects
directory and build and publish:
ng build umbrella-library
cd ../dist/umbrella-library
npm version [bump to new version]
npm publish
Note: You may need to use the public access flag when publishing: npm publish --access=public
From Angular documentation: You should always build libraries for distribution using the production configuration. This ensures that generated output uses the appropriate optimizations and the correct package format for npm.
Monitoring
Information on site monitoring coming soon:
- Health Check
- NodePing
- New Relic
Further help
To get more help on the Angular CLI use ng help
or review the Angular CLI README.