Files
monorepo/LCU.WebApps.Operations.IncentiveManager/README.md
T
2026-03-23 11:21:52 -05:00

18 KiB
Raw Blame History

Incentive Manager

React/Redux client using IncentiveAPI to manage incentives and display progress for associates, branches and regions.

Getting Started

If you haven't set up your local environment for react development yet clone this repo and run the setup script to install the required tools here

Once that has finished you can run the SetupLocalSSL script in the root directory of the project, follow the prompts to install a local SSL cert for your project. Once that is complete you can run the "start-https" npm script and begin adding your feature

Style Concerns

ESLint and Prettier are the managers for code style. You may need to add an extension to your code editor for both Eslint and Prettier. There is a git commit hook setup to auto-apply Prettier rules after each commit. All edited files will be cleaned up.

On top of these linters we do have a few preferences that you should keep in mind:

  • React - Functional Components Only, API Calls in Services
  • Testing - Enzyme/Jest
  • Forms - Conform to outlined standards
  • Releases - Handle in Azure DevOps
  • Commits - Commitizen style
  • ADA Compliance

React

Functional Components Only In React 16.8 hooks were added to functional components giving them the same functionality as class components. These new functional components are much easier to read and do not require the 'Connection' declaration that class components did.

Learn more about react hooks here

Learn more about using Typescript with react hooks here

API Calls In Services To better keep our react projects DRY we move API calls to services instead of using them in actions or react hooks. This allows us to easily update all API calls throughout the entire application safely should an API change.

You can find services in src/shared/services

Testing

Enzyme and Jest are the testing libraries.

Forms

While forms have various roles and requirements, there are a set of standards that we can agree to when approaching form creation. Please keep these standards in mind as a guide and not a hard rule - although variations should likely be discussed with the team.

  • Disable submit for invalid forms, ensure 'enter' doesn't bypass this.
  • Mark required fields with a red *
  • Prefer 'immediate' form feedback
  • Do not store form state in redux
  • Use React-Strap components when possible: https://reactstrap.github.io/components/form
  • Use the React-Strap form validation UX:
  • Technical Recommendations:
    • Fields should have basic validation 'locally' in their component
    • Form-Wide validation should be handled in a parent component
    • When possible, store validation functions separately in the shared folder for re-use
  • Present success or failure in a banner above or below the form
  • Server feedback should be presented in a way that the appUser can either correct the form or provide a useful bug report

Connected Vs. Components Vs. Layout - Where does this component go?

React Components in this project are broken into 3 folders under the src directory Connected, Components, and Layout.

On first glance there is practically no difference between the react components saved in each. The distinction comes from its role within the application and its relationship to the redux store.

Connected - The Redux Folder A Container is a concept recommended by the Redux team to isolate app state from the display logic. In this project the folder is renamed Connected as a 'container' is a lose term and can be applied to unconnected react components as well.

Connected components are the 'pages' that contain non-connected components that depend upon data from the Redux Store. More specifically, Connected components are top level components that hold Redux functionality (such as Selectors and Dispatchers) and distribute it to child display components.

Anything that uses a Selector hook or several Dispatch hooks should be saved in the Containers folder and should not display any of its own data.

Components - The React Folder The Components folder is where the bulk of the React Components should be saved. The Components folder should contain the lowest level and most specific components. They are unconcerned with where their props come from and are in charge of collecting or displaying a piece of state.

None of these components should use a Selector (arguments can be made for allowing Dispatch, this project tends to avoid it), instead, the data will flow into these components from the app state via a Connected component's Selector. The final stop for all data is always a Component.

Glue components, or components that group together multiple children components, help transform data as well as manage state between several display components. While their function is similar to that of a Connected Component, glue components belong in the Component folder, as they are not dependent on the Redux store. Keep in mind glue components are not explicitly named as such.

The entire Components folder can be exported as a Library and used in any React application regardless of the presence of a Redux store.

Layout - The DOM folder The Layout folder defines the 'Global' styling and structure of the application. This includes any Navigation, Footers, Menus and the like. These components are purely structural and agnostic to any data that the app intends to process or display.

These components should almost always be Higher Order Components or Wrapper Components. These are components that augment or wrap their children (in this case the child is typically the content of the application).

If a layout item needs to be connected to the Redux store, create a connected component that will be wrapped by the parent Layout component. For example

//PageContainer.tsx
import {Navbar, AnimatedLogo, PageContainer}  from "src/Layout" // Control Page Layout
import {AppMenu, MenuItem} from "menu-library"
import {ConnectedNavbarItem} from "src/Connected/ConnectedNavbarItem" //Navbar item with redux state
...
return (
	<Navbar>
		<AnimatedLogo>
		<ConnectedNavbarItem/>
		<AppMenu>
			<MenuItem src="/Home"> Home </AppItem>
		</AppMenu>
	<Navbar>
	<PageContainer>
		{...props.children}
	</PageContainer>
)

Application state does not belong inside of the Layout Folder. This folder represents the "canvas" that the rest of the application will be painted onto.

In some applications, the layout folder can be found under the Components directory. This is acceptable, however going forward it will be separated. The intention is to guarantee app state does not find its way to the layout folder.

I found X in a folder and it doesn't belong there This is more likely a mistake than an exception. Consider fixing this in a separate PR. Double check that there isn't a comment justifying its acceptability.

I think I found an Exception Exceptions are rare but may happen. When they do, open a discussion with the team and well document the exception in both the readme and comments in the compone

Releases

Releases are handled by anyone on the team with access to Azure DevOps. Generally when a pull request is accepted to develop, that will be automatically built and deployed to QA. The QA application is here: [https://qa-optin.azurewebsites.net/#/associate]. The same is true for the front end / Client.

To get to UAT, develop must be merged into the master branch. This will automatically cause the main branch to be built and the resulting release to be pushed to UAT.

When creating releases, it's important not to forget to make a release and update the change notes as needed. There is information on creating a release below.

Setup Commitizen and Produce changelogs and release notes

Commitizen is a command line tool that helps format commit messages with a series of prompts that are used to generate a commit message. We use this tool to standardize our commits for tracking a changelog and producing release notes.

  • npm install commitizen -g
  • npm install commitizen --save-dev // Already done for you, skip.
  • npm install cz-conventional-changelog --save-dev // Already done for you, skip.
  • npm install husky --save-dev // Already done for you, skip.
  • npm install --save-dev validate-commit-msg // Already done for you, skip.
  • npm install -g conventional-changelog-cli

Instead of committing with git commit commit with git cz This will force your messages into the format ():

Definition Description
feat A new feature
fix A bug fix
docs Documentation only changes
style Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
refactor A code change that neither fixes a bug nor adds a feature
perf A code change that improves performance
test Adding missing or correcting existing tests
chore Changes to the build process or auxiliary tools and libraries such as documentation generation

Here is how semantic-release will map these to release types and how it maps to semantic verioning:

Commit message Release type
fix(pencil): stop graphite breaking
when too much pressure applied
Patch Release (PATCH)
feat(pencil): add 'graphiteWidth' option Feature Release (MINOR)
BREAKING CHANGE: The graphiteWidth option
has been removed. The default graphite
width of 10mm is always used for performance reasons.
Breaking Release (MAJOR)

Produce or update the changelog

You shouldn't need to do this, it should be generated for you when you create a release (below)

  • Create changelog from scratch: conventional-changelog -p angular -i CHANGELOG.md -s -r 0
  • Update the changelog: conventional-changelog -p angular -i CHANGELOG.md -s

Produce a set of release notes and bump version

  • Use: npm run release
  • You should check the ChangeLog.MD after this and make any corrections.

Resources:

ADA Compliance

This application is targeting level AA ADA Compliance, here is the checklist you should keep in mind when developing:

  • Every image, video file, audio file, plug-in, etc. has an alt tag
  • Complex graphics are accompanied by detailed text descriptions
  • The alt descriptions describe the purpose of the objects
  • If an image is also used as a link, the alt tag describes the graphics and the link destination
  • Decorative graphics with no other function have empty alt descriptions (alt=””)
  • Data tables have the column and row headers appropriately identified (using the tag)
  • Make sure the page does not contain repeatedly flashing images
  • Check to make sure the page does not contain a strobe effect
  • All scripts and plug-ins and the content within them are accessible to assistive technologies, or else an alternative means of accessing equivalent content is provided
  • When form controls are text input fields use the LABEL element
  • When text is not available use the title attribute
  • Include any special instructions within field labels
  • Make sure that form fields are in a logical tab order
  • Include a ‘Skip Navigation’ button to help those using text readers
  • SVG icons should not focusable by tabbing in IE (utilize focusable="false" on all icon tags)

Coding tools for ADA Compliance

Learning React, Redux, Typescript, etc

Docs:

React, Redux And Typescript have great quick-start guides that walk through their features step by step with examples:

Bootstrap:

Unified Opt in uses Bootstrap 4

Search the Docs here: https://getbootstrap.com/docs/4.0/getting-started/introduction/

If you see className with "fa fa-noun" we are expecting bootstrap to render that text as an icon. Search all the possible bootstrap fontawesome icons here: https://fontawesome.com/v4.7.0/icons/

Useful Resources:

1. https://medium.com/@tkssharma/understanding-redux-react-in-easiest-way-part-1-81f3209fc0e5 2. https://blog.usejournal.com/using-react-with-redux-and-typescript-c7ec48c211f6 3. https://hackernoon.com/redux-step-by-step-a-simple-and-robust-workflow-for-real-life-apps-1fdf7df46092 4. https://medium.com/naukri-engineering/email-sending-architecture-using-messaging-queue-314a18f8595c 5. https://reactjs.org/docs/higher-order-components.html#convention-maximizing-composability 6. https://blog.logrocket.com/react-redux-connect-when-and-how-to-use-it-f2a1edab2013/ 7. https://stackoverflow.com/questions/54154673/react-typescript-redux-connect-function-not-working 8. https://redux.js.org/recipes/structuring-reducers/basic-reducer-structure

Redux in TypeScript Quick Guide

  1. Know what a Higher Order Component is.
  2. The types: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-redux/index.d.ts#L59
  3. Connect is a higher order component used to wrap your component giving it access to state from the store and dispatch actions.

Build

Run npm run build to build the project with default settings, which for create-react-app is production. The development server will do a debug build.

Run (Development server)

Run npm start for a dev server. Navigate to https://localhost:3000/. The app will automatically reload if you change any of the source files. Note that this will run with a proxy in place so that you can contact the web services.

Deploy (QA, UAT, Prod)

Deployments to QA, UAT, and Prod are automatically handled by Azure Dev-Ops. See the additional resources section below; as there is a document outlining the software development process, as well as the cloud setup Azure.

Running unit tests

Run npm run test to run the unit tests interactively, they will re-run whenever you make changes. To simulate the CI server and run them once, npm run test-ci or set the CI environment variable before running npm run test

Suggestion for IDE

  • Visual Studio Code
  • Webstorm

Other Tools:

FAQ

Q. What the heck is a 'thunk'? A. https://daveceddia.com/what-is-a-thunk/

Q. I'm running the unit test and I see output like this: HeadlessChrome 68.0.3440 (Windows 10.0.0) XYZComponent should use the service to add address controls to the form group FAILED [object ErrorEvent] thrown A. Re-run the tests using npm run test-debug, which will show the full stack trace but not provide code coverage.

Q. What do I need to know about Security? A. The major security concerns are outlined in the architecture documents in the share (see resources above). The main security mechanism is for Landmark employees, and uses the React-ADAL library to authenticate against Azure AD.

Q. Where was this project started from? A. This project was bootstrapped with Create React App.