Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ jobs:
uses: actions/upload-artifact@v7
with:
name: web-coverage-report
path: ./web/finalCoverage
path: ./web/apps/wps-web/finalCoverage

upload-code-coverage:
name: Coverage with CodeCov
Expand Down
26 changes: 18 additions & 8 deletions Dockerfile.web
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,30 @@
ARG NODE_OPTIONS="--v8-pool-size=4"

# PHASE 1 - build frontend.
FROM docker.io/library/node:20-alpine AS static
FROM docker.io/library/node:24-alpine AS static
# Switch to root user for package installs
USER 0
WORKDIR /app

COPY web/package.json .
COPY web/yarn.lock .
COPY web/.yarnrc.yml .
COPY web/package.json web/yarn.lock web/.yarnrc.yml web/turbo.json ./

# Copy package manifests before source for better layer caching
COPY web/packages/tsconfig/package.json packages/tsconfig/
COPY web/packages/types/package.json packages/types/
COPY web/packages/utils/package.json packages/utils/
COPY web/packages/api/package.json packages/api/
COPY web/packages/ui/package.json packages/ui/
COPY web/apps/wps-web/package.json apps/wps-web/

# do install first so it will be cached
RUN corepack enable \
&& yarn set version berry \
&& CYPRESS_INSTALL_BINARY=0 yarn install --immutable
COPY web .
RUN yarn run build:prod

# Copy all source
COPY web/packages/ packages/
COPY web/apps/wps-web/ apps/wps-web/

RUN yarn turbo build

# PHASE 2 - prepare hosting.
FROM docker.io/library/nginx:stable-alpine
Expand All @@ -28,7 +38,7 @@ FROM docker.io/library/nginx:stable-alpine
COPY ./openshift/nginx.conf /etc/nginx/nginx.conf

# Copy the static content:
COPY --from=static /app/build .
COPY --from=static /app/apps/wps-web/build .

RUN mkdir -p /tmp/nginx/client_temp
RUN chmod -R 755 /tmp/nginx
Expand Down
7 changes: 6 additions & 1 deletion web/.dockerignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
**/.gitignore
**/node_modules
**/Dockerfile*
**/Dockerfile*
**/build
**/dist
**/.turbo
**/coverage
**/coverage-cypress
3 changes: 2 additions & 1 deletion web/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
.sentryclirc
.pnp.*
.yarn/*
.turbo/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
cypress/downloads
apps/wps-web/cypress/downloads
16 changes: 0 additions & 16 deletions web/Dockerfile

This file was deleted.

File renamed without changes.
File renamed without changes.
24 changes: 24 additions & 0 deletions web/apps/wps-web/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
FROM node:24-alpine AS builder
WORKDIR /app

# Copy workspace config first (better layer caching)
COPY package.json yarn.lock .yarnrc.yml turbo.json ./

# Copy package manifests before source (layer cache for yarn install)
COPY packages/tsconfig/package.json packages/tsconfig/
COPY packages/types/package.json packages/types/
COPY packages/utils/package.json packages/utils/
COPY packages/api/package.json packages/api/
COPY packages/ui/package.json packages/ui/
COPY apps/wps-web/package.json apps/wps-web/

RUN yarn install --immutable

# Copy all source
COPY packages/ packages/
COPY apps/wps-web/ apps/wps-web/

RUN yarn turbo build

FROM nginx:alpine
COPY --from=builder /app/apps/wps-web/build /usr/share/nginx/html
32 changes: 16 additions & 16 deletions web/README.md → web/apps/wps-web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,19 @@ Wildfire Predictive Services to support decision making in prevention, preparedn

#### [Node.js](https://nodejs.org/en/)

- You’ll need to have Node >= 20.x and yarn on your machine. You can use [nvm](https://github.com/nvm-sh/nvm#installation) (macOS/Linux) or [nvm-windows](https://github.com/coreybutler/nvm-windows#node-version-manager-nvm-for-windows) to switch Node versions between different projects.
- Note: We are using Node 19 as a base image on our pipeline.
- On ubuntu: `sudo apt install nodejs`
- You’ll need to have Node >= 24.x and yarn on your machine. You can use [nvm](https://github.com/nvm-sh/nvm#installation) (macOS/Linux) or [nvm-windows](https://github.com/coreybutler/nvm-windows#node-version-manager-nvm-for-windows) to switch Node versions between different projects.

#### [yarn](https://yarnpkg.com/)

- `npm install -g yarn`
- `corepack enable`

### Installing

In the project directory, run:
All commands should be run from the `web/` workspace root, not from this directory.

#### `yarn`
#### `yarn install`

Installs all dependencies in the node_modules folder.
Installs all dependencies for all packages in the monorepo.

#### Cypress on WSL2

Expand All @@ -33,35 +31,37 @@ It's possible to configure cypress to run with an X-server with WSL2 and Windows
The short version is:

- Launch VcXsrv (remember to check "Disable access control")
- `yarn run cypress`
- `yarn workspace @wps/wps-web run cy:open`

### Executing program

In the project directory, create `.env` file at root using `.env.example` as a sample, then you can run:
From the `web/` workspace root, create `.env` file in `apps/wps-web/` using `apps/wps-web/.env.example` as a sample, then you can run:

#### `yarn start`
All of the following commands use [Turbo](https://turbo.build/) to orchestrate tasks across the monorepo.

#### `yarn turbo dev`

Runs the app in the development mode.
The page will reload if you make edits. You will also see any lint errors in the console.

#### `yarn test`
#### `yarn turbo test`

Launches the jest test runner in the interactive watch mode.
Launches the vitest test runner across all packages.
Includes logic only unit tests and [react-testing-library](https://testing-library.com/docs/react-testing-library/intro/) component tests.

#### `yarn cypress`
#### `yarn workspace @wps/wps-web run cy:open`

Launches the cypress test runner in the interactive watch mode.
Includes end-to-end / integration tests for frontend common path interactions.

#### `yarn run build`
#### `yarn turbo build`

Builds the app for production to the `build` folder.
Builds the app for production to the `apps/wps-web/build` folder.
It correctly bundles React in production mode and optimizes the build for the best performance.

##### Running the application in docker:

1. Create `.env` file at root using `.env.example` as a sample
1. Create `.env` file in `apps/wps-web/` using `apps/wps-web/.env.example` as a sample
2. Run `docker compose build` and then `docker compose up`
3. Open [http://localhost:3000](http://localhost:3000) to view it in the browser.

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FIRE_BEHAVIOR_CALC_ROUTE } from '../../src/utils/constants'
import { FIRE_BEHAVIOR_CALC_ROUTE } from '../../../../packages/utils/src/constants'
import { FuelTypes } from '../../src/features/fbaCalculator/fuelTypes'

describe('FireCalc Page', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { HFI_CALC_ROUTE } from '../../src/utils/constants'
import { HFI_CALC_ROUTE } from '../../../../packages/utils/src/constants'

function interceptSelectStationTrue(
fire_centre: number,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MORE_CAST_2_ROUTE } from '../../src/utils/constants'
import { MORE_CAST_2_ROUTE } from '../../../../packages/utils/src/constants'

describe('More Cast 2 Page', () => {
beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NOT_AVAILABLE } from '../../src/utils/strings'
import { PERCENTILE_CALC_ROUTE } from '../../src/utils/constants'
import { stationCodeQueryKey } from '../../src/utils/url'
import { NOT_AVAILABLE } from '../../../../packages/utils/src/strings'
import { PERCENTILE_CALC_ROUTE } from '../../../../packages/utils/src/constants'
import { stationCodeQueryKey } from '../../../../packages/utils/src/url'

describe('Percentile Calculator Page', () => {
describe('Weather station dropdown', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"Zone","Weather Station","Elevation","FBP Fuel Type","Grass Cure","Status","Temp","RH","Wind Dir","Wind Speed (km/h)","Precip (mm)","FFMC","DMC","DC","ISI","BUI","FWI","HFI","Critical Hours (4000 kW/m)","Critical Hours (10000 kW/m)","ROS (m/min)","Fire Type","CFB (%)","Flame Length (m)","30 min fire size (ha)","60 min fire size (ha)"
"K5","PENTICTON RS (328)","427","O1A","80","ACTUAL","25.9","30","302","7.3","0","91.932","122.665","1002.44","8.156","187.86","33.709","1468.3296228910988","","","13.984091646581893","S","0.0","2.212336338874282","5.1009941188966925","28.273388410171016"
"Zone","Weather Station","Elevation","FBP Fuel Type","Grass Cure","Status","Temp","RH","Wind Dir","Wind Speed (km/h)","Precip (mm)","FFMC","DMC","DC","ISI","BUI","FWI","HFI","Critical Hours (4000 kW/m)","Critical Hours (10000 kW/m)","ROS (m/min)","Fire Type","CFB (%)","Flame Length (m)","30 min fire size (ha)","60 min fire size (ha)"
"K5","PENTICTON RS (328)","427","O1A","80","ACTUAL","25.9","30","302","7.3","0","91.932","122.665","1002.44","8.156","187.86","33.709","1468.3296228910988","","","13.984091646581893","S","0.0","2.212336338874282","5.1009941188966925","28.273388410171016"
"K2","AFTON (322)","780","C5","","ACTUAL","20.5","38","310","9.2","0","89.579","90.588","858.106","6.417","143.344","26.922","629.1355440376345","","","0.5728888963554044","S","0.0","1.4481431145178463","0.009328024522166307","0.0522691463588831"
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
127 changes: 127 additions & 0 deletions web/apps/wps-web/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
{
"name": "@wps/wps-web",
"version": "0.1.0",
"engines": {
"node": ">=20",
"npm": ">=10.7.0"
},
"type": "module",
"license": "Apache-2.0",
"licenses": [
{
"type": "Apache-2.0",
"url": "https://www.apache.org/licenses/LICENSE-2.0"
}
],
"dependencies": {
"@emotion/react": "^11.8.2",
"@emotion/styled": "^11.8.1",
"@mui/icons-material": "^5.5.1",
"@mui/material": "5.15.20",
"@mui/system": "^5.15.14",
"@mui/x-data-grid-pro": "^6.0.0",
"@mui/x-date-pickers": "^7.29.4",
"@psu/cffdrs_ts": "git+https://github.com/cffdrs/cffdrs_ts#b9afdabc89dd4bdf04ccf1e406a4a5d8d552ff51",
"@reduxjs/toolkit": "^2.2.7",
"@sentry/react": "^10.0.0",
"@sentry/vite-plugin": "^5.0.0",
"@types/esri-leaflet": "^3.0.0",
"@types/leaflet": "^1.7.0",
"@types/lodash": "^4.14.173",
"@types/luxon": "^3.0.2",
"@types/react": "18.3.3",
"@types/react-dom": "^18.3.0",
"@types/react-plotly.js": "^2.2.4",
"@types/react-router-dom": "^5.3.3",
"@types/webpack-env": "^1.15.1",
"@typescript-eslint/eslint-plugin": "^8.0.0",
"@typescript-eslint/parser": "^8.0.0",
"@vitest/coverage-v8": "^4.0.8",
"axios": "1.8.2",
"date-fns": "^4.0.0",
"eslint-config-prettier": "^10.0.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react": "^7.34.4",
"esri-leaflet": "3.0.12",
"filefy": "^0.1.11",
"jsdom": "^26.0.0",
"jwt-decode": "^4.0.0",
"keycloak-js": "^25.0.0",
"leaflet": "^1.7.1",
"lodash": "^4.17.21",
"luxon": "^3.0.2",
"match-sorter": "^8.0.0",
"nyc": "^17.0.0",
"ol": "10.0.0",
"ol-mapbox-style": "^13.1.1",
"ol-pmtiles": "^2.0.0",
"prettier": "^3.3.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-is": "^19.2.4",
"react-redux": "^9.1.2",
"react-router-dom": "^7.6.2",
"recharts": "^3.0.0",
"typescript": "^5.2.2",
"vitest": "^4.0.0",
"whatwg-fetch": "^3.6.20"
},
"scripts": {
"start": "vite",
"dev": "vite",
"start:cypress": "export $(cat .env.cypress | xargs) && yarn start",
"build": "tsc -b && vite build",
"build:prod": "tsc -b && vite build",
"test": "VITE_PMTILES_BUCKET=https://nrs.objectstore.gov.bc.ca/gpdqha/psu/pmtiles/ vitest",
"test:ci": "CI=true npm test",
"coverage": "npm test -- --coverage --watchAll=false",
"coverage:ci": "CI=true VITE_KEYCLOAK_CLIENT=wps-web VITE_PMTILES_BUCKET=https://nrs.objectstore.gov.bc.ca/gpdqha/psu/pmtiles/ vitest run --coverage",
"cy:open": "cypress open",
"cy:run": "cypress run --browser chrome --config watchForFileChanges=false",
"cypress:ci": "start-server-and-test start:cypress http://localhost:3030 'cy:run'",
"lint": "eslint",
"lint:fix": "eslint --fix",
"format": "prettier --write \"**/*.+(js|jsx|json|yml|yaml|css|md)\"",
"finalizeCoverage": "yarn node mergeCoverage.cjs",
"preview": "vite preview"
},
"devDependencies": {
"@babel/core": "^7.29.0",
"@babel/preset-env": "^7.29.0",
"@cypress/code-coverage": "^4.0.0",
"@eslint/compat": "^2.0.0",
"@testing-library/dom": "^10.1.0",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^16.0.0",
"@testing-library/user-event": "^14.5.2",
"@types/babel__core": "^7",
"@types/babel__preset-env": "^7",
"@types/jest": "^30.0.0",
"@types/react-is": "^19",
"@types/recharts": "^1.8.23",
"@vitejs/plugin-react": "^4.3.1",
"@wps/tsconfig": "workspace:*",
"babel-loader": "^10.1.1",
"cypress": "^15.10.0",
"eslint": "^9.7.0",
"eslint-plugin-react-hooks": "^7.0.0",
"eslint-plugin-react-refresh": "^0.4.7",
"globals": "^17.0.0",
"rollup": "^4.59.0",
"start-server-and-test": "^2.0.0",
"ts-sinon": "^2.0.2",
"vite": "^7.0.0",
"vite-plugin-istanbul": "^7.0.0",
"vite-plugin-svgr": "^4.2.0",
"webpack": "^5.105.4"
},
"nyc": {
"report-dir": "coverage-cypress",
"excludeAfterRemap": true,
"exclude": [
"src/serviceWorker.ts",
"src/app/store.ts"
]
},
"_comment": "packageManager is defined at workspace root"
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { useLocation, useNavigate } from 'react-router-dom'
import { rowShouldUpdate, isWindSpeedInvalid, isPrecipInvalid } from 'features/fbaCalculator/validation'
import TextDisplayCell from 'features/fbaCalculator/components/TextDisplayCell'
import FixedDecimalNumberCell from 'features/fbaCalculator/components/FixedDecimalNumberCell'
import HFICell from 'components/HFICell'
import HFICell from './HFICell'
import CrownFractionBurnedCell from 'features/fbaCalculator/components/CrownFractionBurnedCell'
import CriticalHoursCell from 'features/fbaCalculator/components/CriticalHoursCell'
import StatusCell from 'features/fbaCalculator/components/StatusCell'
Expand All @@ -41,7 +41,7 @@ import StickyCell from 'components/StickyCell'
import FBATableHead from 'features/fbaCalculator/components/FBATableHead'
import FireTable from 'components/FireTable'
import FBATableInstructions from 'features/fbaCalculator/components/FBATableInstructions'
import FilterColumnsModal from 'components/FilterColumnsModal'
import FilterColumnsModal from './FilterColumnsModal'
import WPSDatePicker from 'components/WPSDatePicker'
import { AppDispatch } from 'app/store'
import { DataTableCell } from 'features/hfiCalculator/components/StyledPlanningAreaComponents'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { TableCell } from '@mui/material'
import { styled } from '@mui/material/styles'
import React from 'react'
import FixedDecimalNumberCell from 'features/fbaCalculator/components/FixedDecimalNumberCell'
import FixedDecimalNumberCell from './FixedDecimalNumberCell'
import { isNull, isUndefined } from 'lodash'

const PREFIX = 'HFICell'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { TableContainer, Table, TableBody, TableRow } from '@mui/material'
import { render } from '@testing-library/react'
import HFICell from 'components/HFICell'
import HFICell from './HFICell'

describe('HFICell', () => {
it('should render without color when HFI is undefined', () => {
Expand Down
Loading
Loading