1.0.0 • Published 12 months ago

arhi-join-web v1.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
12 months ago

Build status code style: prettier style: styled-components types: types types: types EMA for prospect-api

arhi-join-web

Front end app for the quoting and join funnels for arhi and white labeled customers.

arhi-join-web is a react app using gatsby, redux with thunk middleware, and typescript. Based off the sales-gatsby-starter.

Links

Kaos

Production

Yet to be released

Logs

Developer Guide

Setup

Note that you will need to be connected to both the GlobalProtect VPN, be authenticated with RQP and have the RQP proxy active in order for the session to be properly established.

RQP auth

rqp auth -s kaos -z secure -r poweruser

Dev commands

npm i (known to work with nodejs version: 14.16.1)

# To run locally
# Will source environment variables available at .env.development and run gatsby develop command
npm run develop

# Build step (production) will require an environment variable supplied to specify tealium related variables
# In Buildkite we specify this in the build step, to achieve this locally, create a .env.production file
# or supply an environment variable in the command line
npm run build

# When making changes to sourceNodes it is good to clean Gatsby cache before each run
gatsby clean && npm run develop

# Production build using local variables at .env.development
# Same as above comment re environment variable
# use .env.production locally to specify this, or specify it in the command line
npm run build-local

# Build production build and serve
npm run build-serve

# Unit tests
npm run test:watch

# Reproduces test snapshots
npm run test:unit -- -u

# Watch all tests and re-run on change
npm run test:watch

Root of the project lists all pages at http://localhost:8000/. Some pages will not be accessible without a session in a certain state. Start a join with Welcome page.

Debugging

Option 1

  • Launch chrome using chrome.exe --remote-debugging-port=9222 --user-data-dir=remote-debug-profile
  • Attach VSCode debugger using Attach to Chrome

Option 2

  • Launch VSCode debugger using Launch to Chrome

This will work but you won't have all your personalised chrome extensions like React Developer tools, Redux tools, Modheader etc

Directory structure

.buildkite        # build scripts for buildkite
.cache            # Gatsby generated cache.
.env              # kaos and production environment files for each brand
@types            # types for third-party packages

data/
  brands/<brand>  # Brand specific content and pages configuration
  common/         # Common content to be shared across all brands

docs              # additional docs

node_modules/     # all the `npm install`ed node modules live here and this dir is ignored by Git

public/           # all the generated files

src/              # all the source files
  components/     # common components
  hooks/          # common hooks
  metrics/        # Tealium tracking related functions, types, etc.
  redux/          # Everything state related. We are using thunk middleware in this project
  services/       # utilities, types, etc.
  templates/      # templates for pages of the project
  types/          # common types

Environment variables config

Variables prefixed with GATSBY_ are also available on client side at runtime. They then can be accessed via process.env.GATSBY_VARIABLE_NAME. See this for more details.

Newly added variables need to be added to each environment file based on branch in .env/, e.g.:

.env/               # all brand related .env files for kaos and production
  [brand_name].kaos
  [brand_name].prod
.env.development    # variables for npm run develop

Chat launcher local development

There are two useful environment variables you can set for local development convenience when it comes to testing and debugging the @nib/chatbot-launcher package (which is centralised in the <ChatLauncherProxy/> component. Note that this only affects behaviour in localhost.

You can optionally open the launched chat window in a new tab, instead of in a pop-up. This can be more convenient when using browser extension based devtools.

#.env.development
REACT_APP_CHAT_LAUNCHER_OPEN_IN_TAB=true

It is also possible to override the default URL (host protocol & origin, + /chat path) and point it to something else, for example if you're running the chatbot client locally:

#.env.development

# If you're running the `client` locally, in the `chatbot-client-monorepo`:
REACT_APP_LOCAL_CHAT_LAUNCHER_URL=http://localhost:8080
# Otherwise you can point to `cf-test` and access via RQP proxy and GlobalProtect:
REACT_APP_LOCAL_CHAT_LAUNCHER_URL=https://www.nib-cf-test.com/chat
# Or the prod chatbot (which anyone can access)
REACT_APP_LOCAL_CHAT_LAUNCHER_URL=https://www.nib.com.au/chat

Note that this overrides the URL protocol, origin, AND path. As such you shouldn't expect the prop suffix path to be added to this URL. If you want to test different path suffixes, then you'll need to include that in your env var value.

Note, however, that any calculated query parameters (e.g. load external config) ARE appended to the local override URL as well.

Brands

Brand variations are controlled via GATSBY_BRAND environment variables which defaults to nib.

To add a new brand, you will need to:

  • create a new folder under data/<brand> and follow the data structure used by the other existing brands in the data directory.
  • update @nib-components/theme to include new brand theme
  • add a new set of .env files
  • update build pipelines

By default Mesh components will use nib defaults in form-fields and validation. The components will be functional but may need to get updated content for a new whitelabel brand.

Check brand.config document page for more details about brand config file.

WithVariants

This is a pattern that is used when we need to use a different component based on the brand. The code for WithVariants component is in src/components/WithVariants.

Here is how ErrorLink component uses CallLink for apia brand and a different component for nib

const variants = {
  nib: NibLinkOrCall,
  apia: CallLink
};

export const ErrorLink = withVariants(variants, CallLink);

withVariants parameters:

  • variants is an object with props for each brand with variation
  • CallLink is a default component that will be used for any brand that is not specified in variants

Sourcing products from PCAT

PCAT API (https://product-catalogue-api-v2.kaos.internal.nibit.com.au) stores data about products (Hospitals or Extras) and it's inclusions (Procedures or Services).

We use Gatsby sourceNodes to source PCAT data at build time and store it with Gatsby GraphQL.

src
  services
    createSchemaCustomisation   # https://www.gatsbyjs.com/docs/schema-customization/
      index.ts                  # specifies types for GraphQL schema.
                                # Build step will fail if the generated schema does not match types.
    sourceNodes                 # https://www.gatsbyjs.com/docs/recipes/sourcing-data/
      index.ts                  # gets product ids from data/brands/${brand}/content.json and calls
                                # sourceHospitalProducts and sourceExtrasProducts
      pcatService.ts            # axios requests to pcat
      sourceHospitalProducts.ts # creates Procedure, ProductProcedure and HospitalProduct nodes with data required on frontend.
      sourceExtrasProducts.ts   # creates ProductService and ExtrasProduct nodes with data required on frontend.
  templates
    hospital.tsx                # contains GraphQL query with fragments for hospital
    extras.tsx                  # contains GraphQL query with fragments for extras
  components
    ProductCard
      index.tsx                 # uses the data received from GraphQL to show products with inclusions
fragments.ts                    # globally defined fragments used to query GraphQL

We get the data from PCAT at build time and create nodes in GraphQL. For example Hospital and Extras pages get data with GraphQL query:

export const HospitalPageQuery = graphql`
  query HospitalPageQuery {
    pageDetails(template: {eq: "hospital"}) {
      metadata {
        title
      }
    }
    ...ProductCardList_Hospital
  }
`;

ProductCardList_Hospital is a fragment defined in fragments.ts.

Use gatsby clean && npm run develop for when you are changing sourceNodes to see changes in GraphQL.

We want to fail the build when something goes wrong with sourcing data from PCAT. This will make sure production always has right data from PCAT. Do not handle PCAT exceptions in this project and let the build fail.

PCAT responses are not made for our needs so most of the logic in sourceHospitalProducts and sourceExtrasProducts creates nodes that suit our needs of the frontend. Use swagger or postman requests to understand what data is returned from PCAT - https://github.com/nib-group/product-catalogue-services

Copy/paste query from templates/hospital.tsx or templates/extras.tsx and relevant fragments into GraphiQL to see what is returned to the component with the query. It is useful to form the query in GraphiQL first and then update the components to consume the data.

Override Product EffectiveDate

GATSBY_PRODUCT_EFFECTIVE_DATE_OVERRIDE=YYYY-MM-DD

If set, all PCAT requests will have effectiveDate parameter overridden with this value. This results in the product sourceNodes exhibiting this overridden effectiveDate value in addition to client side Pricing API requests. This value may be set manually in the build/bundling step in pipeline.yaml for the respective brand and environment type.

Tealium

We use Tealium to track join progress on each page. Read more: https://confluence.nib.com.au/display/DWKARC/Tealium+for+Gatsby+Pages+-+Developer+Guide

Changing Product Data

The product data that is loaded into GraphQL is serialised as JSON in the following locations ./data/brands/<brand>/content.json. This may be edited to tweak the content or display of the products in the resulting UI. Properties of interest are:

  • "suggestedProducts" which controls which (if any) product card receives a highlight box signifying popularity.
  • "products" which describes the various products available via the PCAT productId. The array order is maintained in the resulting UI.

Configuring display of ExtrasProduct Inclusions

Custom Sorting of ExtrasProduct Inclusions

Sorted subsets of the ExtrasProduct Inclusions may be supplied via the brand's content.json. This allows corrections in the order to be made without defining the sorting of the entire ProductService or ServiceComponent list. This is activated client-side - See the ServiceComponent presentation for more information.

Multiple partial sorts may be provided. The second dimension array defines a singular partial sort with the first element indicating the starting point by which all following ProductService's will be ordered in the UI. In the below example, the result is that ProductService 101 will be re-ordered to proceed ProductService 100 and ProductService 350 will follow 320.

"customProductServiceSorting": {
  "extras": {
    "serviceComponent": [[100, 101], [320, 350]],
    "productService": []
  }
}

To mandate that a ProductService/ServiceComponent be the first inclusion in the list, use 0 as the starting point.

"customProductServiceSorting": {
  "extras": {
    "serviceComponent": [[0, 100]],
    "productService": [[0, 230]]
  }
}

To mandate that a ProductService/ServiceComponent be the last inclusion in the list, use -1 as the starting point.

"customProductServiceSorting": {
  "extras": {
    "serviceComponent": [[-1, 100]],
    "productService": [[-1, 230]]
  }
}

Hiding Service Components from ExtrasProduct Inclusions

Each brand exhibits a list to allow non-pertinent ServiceComponents to be hidden from the ExtrasProduct inclusions view. This is activated client-side - see the components/ProductCard/InclusionsList component and the ServiceComponent presentation for more information.

"filteredServiceComponents": {

  "extras": [100, 101]

}

Service Component Groups

Preliminary work to list Inclusions via their "Service Component Group" is also supported via a brand's content.json. NOTE: This is currently disabled and may only be requested via sortBy=groups query parameter on the /extras page. This is activated client-side - see the components/ProductCard/InclusionsList component and the ServiceComponent presentation for more information.

"serviceComponentGroups": [
  {
    "name": "Commonly Used Services",
    "serviceComponents": [7, 100, 101, 27, 9, 11]
  },
]

Lighthouse

Lighthouse CI is set up to run checks on branches in buildkite after the deployment. To run lighthouse locally install lhci: npm install -g @lhci/cli@0.9.x Then build and serve project locally - npm run build-local-serve And run checks npm run lh

It runs tests 3 times and reports with the median results. Currently there are three links setup to be tested:

The results are shown in buildkite under 'Running commands' in Lighthouse step. The detailed results are temporarily uploaded to 'https://storage.googleapis.com/'. The full link is in the buildkite logs.

The config is in .lighthouserc.js. We are using recommended lighthouse config without PWA.

NOTE: some rules are disabled to make lighthouse pass. Some of those rules are actually ok to turn off and for others we need to come back, fix and re-enable the rules.

Troubleshooting Documentation

Please see here for more information.