arhi-join-web v1.0.0
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
- nib - https://www.nib-cf-test.com/health-insurance/join/welcome
- apia- https://healthquote-test.apia.com.au/join/welcome
- ing - https://healthquote-test.ing.com.au/join/welcome
- suncorp - https://healthquote-test.suncorp.com.au/join/welcome
- all brands - https://arhi-sales-white-label-router.kaos.nibit.com.au/join/welcome - with header arhi_brand : brand-name
Production
- nib - https://www.nib.com.au/health-insurance/join/welcome
- apia - https://healthquote.apia.com.au/join/welcome
- ing - https://healthquote.ing.com.au/join/welcome
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 variationCallLink
is a default component that will be used for any brand that is not specified invariants
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 PCATproductId
. 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:
- http://localhost:9000/welcome/
- http://localhost:9000/hospital?directQuote=true
- http://localhost:9000/extras?directQuote=true'
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.