Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MIA-102 Add homepage - first iteration #19

Merged
merged 1 commit into from
Jan 9, 2025
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ COMPONENT_API_TIMEOUT_DEADLINE=5000
COMMON_COMPONENTS_ENABLED=true
DPS_HOME_PAGE_URL=https://digital-dev.prison.service.justice.gov.uk
PRISONER_PROFILE_URL=https://prisoner-dev.digital.prison.service.justice.gov.uk
LEGACY_KEY_WORKERS_UI_URL=https://dev.manage-key-workers.service.justice.gov.uk

# Credentials for allowing user access
AUTH_CODE_CLIENT_ID=hmpps-typescript-template
Expand Down
11 changes: 11 additions & 0 deletions assets/js/card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
function Card(container) {
this.container = container

if (this.container.querySelector('a') !== null) {
this.container.addEventListener('click', () => {
this.container.querySelector('a').click()
})
}
}

export default Card
7 changes: 7 additions & 0 deletions assets/js/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import * as govukFrontend from 'govuk-frontend'
import * as mojFrontend from '@ministryofjustice/frontend'
import Card from './card'
import { nodeListForEach } from './utils'

govukFrontend.initAll()
mojFrontend.initAll()

var $cards = document.querySelectorAll('.card--clickable')
nodeListForEach($cards, function ($card) {
new Card($card)
})
10 changes: 10 additions & 0 deletions assets/js/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function nodeListForEach(nodes, callback) {
if (window.NodeList.prototype.forEach) {
return nodes.forEach(callback)
}
for (var i = 0; i < nodes.length; i++) {
callback.call(window, nodes[i], i, nodes)
}
}

export { nodeListForEach }
3 changes: 2 additions & 1 deletion assets/scss/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ $govuk-page-width: $moj-page-width;
@import 'node_modules/@ministryofjustice/hmpps-connect-dps-components/dist/assets/footer';
@import 'node_modules/@ministryofjustice/hmpps-connect-dps-components/dist/assets/header-bar';

@import './components/card';
@import './components/header-bar';
@import './local';
@import './local';
98 changes: 98 additions & 0 deletions assets/scss/components/_card.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/* ==========================================================================
COMPONENTS / #CARD
========================================================================== */

$card-border-width: 1px;
$card-border-bottom-width: govuk-spacing(1);
$card-border-hover-color: $govuk-border-colour;
$card-border-color: lighten($card-border-hover-color, 15%);

.card {
margin-bottom: govuk-spacing(7);
background: $govuk-body-background-colour;
border: $card-border-width solid $card-border-color;
position: relative;
width: 100%;
padding: govuk-spacing(5);

&__heading {
margin-top: 0;
margin-bottom: govuk-spacing(3);
}

&__description {
margin-bottom: 0;
}

/* Clickable card
========================================================================== */
&--clickable {
border-bottom-width: $card-border-bottom-width;

&:hover,
&:active {
cursor: pointer;

.card__heading a,
.card__link {
color: $govuk-link-hover-colour;
text-decoration: none;

&:focus {
@include govuk-focused-text;
}
}
}

&:hover {
border-color: $card-border-hover-color;
}

&:active {
border-color: $card-border-hover-color;
bottom: -$card-border-width;
}
}
}

/* Card group
========================================================================== */

/**
* A card group allows you to have a row of cards.
* Flexbox is used to make each card in a row the same height.
*/

.card-group {
display: flex;
flex-wrap: wrap;
margin-bottom: govuk-spacing(3);
padding: 0;

@include govuk-media-query($until: desktop) {
margin-bottom: govuk-spacing(6);
}

&__item {
display: flex;
list-style-type: none;
margin-bottom: 0;

@include govuk-media-query($until: desktop) {
flex: 0 0 100%;
}
.card {
margin-bottom: govuk-spacing(5);
}

@include govuk-media-query($until: desktop) {
.card {
margin-bottom: govuk-spacing(3);
}

&:last-child .card {
margin-bottom: 0;
}
}
}
}
19 changes: 19 additions & 0 deletions assets/scss/local.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
.govuk-main-wrapper {
min-height: 600px;
}

.homepage-content-container {
width: 300%;
margin-left: -100%;
padding: 30px 0;
background: #f0f4f5;
height: auto;
display: flex;
justify-content: center;
}

.homepage-content {
max-width: 100vw;
}

.dropshadow {
border: 1px solid govuk-colour('dark-grey');
box-shadow: 0 5px govuk-colour('mid-grey');
}
8 changes: 6 additions & 2 deletions cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ export default defineConfig({
})
},
baseUrl: 'http://localhost:3007',
excludeSpecPattern: '**/!(*.cy).ts',
specPattern: 'integration_tests/e2e/**/*.cy.{js,jsx,ts,tsx}',
excludeSpecPattern: ['dist', '**/!(*.cy).ts'],
specPattern: '**/*.cy.{js,jsx,ts,tsx}',
supportFile: 'integration_tests/support/index.ts',
experimentalRunAllSpecs: true,
retries: {
runMode: 2,
},
},
})
14 changes: 11 additions & 3 deletions esbuild/esbuild.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ const buildConfig = {
from: path.join(cwd, 'server/views/**/*'),
to: path.join(cwd, 'dist/server/views'),
},
{
from: path.join(cwd, 'server/routes/journeys/**/*'),
to: path.join(cwd, 'dist/server/routes/journeys'),
},
{
from: path.join(cwd, 'server/routes/**/*'),
to: path.join(cwd, 'dist/server/routes'),
},
],
},

Expand Down Expand Up @@ -60,14 +68,14 @@ const main = () => {

if (args.includes('--dev-server')) {
let serverProcess = null
chokidar.watch(['dist']).on('all', () => {
chokidar.watch(['dist'], { ignored: ['**/*.cy.ts'] }).on('all', () => {
if (serverProcess) serverProcess.kill()
serverProcess = spawn('node', ['--env-file=.env', 'dist/server.js'], { stdio: 'inherit' })
})
}
if (args.includes('--dev-test-server')) {
let serverProcess = null
chokidar.watch(['dist']).on('all', () => {
chokidar.watch(['dist'], { ignored: ['**/*.cy.ts'] }).on('all', () => {
if (serverProcess) serverProcess.kill()
serverProcess = spawn('node', ['--env-file=feature.env', 'dist/server.js'], { stdio: 'inherit' })
})
Expand All @@ -82,7 +90,7 @@ const main = () => {

// App
chokidar
.watch(['server/**/*'], { ...chokidarOptions, ignored: ['**/*.test.ts'] })
.watch(['server/**/*'], { ...chokidarOptions, ignored: ['**/*.test.ts', '**/*.cy.ts'] })
.on('all', () => buildApp(buildConfig).catch(e => process.stderr.write(`${e}\n`)))
}
}
Expand Down
5 changes: 4 additions & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import hmppsConfig from '@ministryofjustice/eslint-config-hmpps'

export default [
...hmppsConfig(),
...hmppsConfig({
extraIgnorePaths: ['assets'],
}),
{
rules: {
'dot-notation': 'off',
'import/prefer-default-export': 0,
},
},
]
1 change: 1 addition & 0 deletions feature.env
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ KEYWORKER_API_URL=http://localhost:9091/keyworker-api
PRISON_API_URL=http://localhost:9091/prison-api
COMPONENT_API_URL=http://localhost:9091/components
COMMON_COMPONENTS_ENABLED=true
LEGACY_KEY_WORKERS_UI_URL=https://legacy.key-workers.url
1 change: 1 addition & 0 deletions helm_deploy/values-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ generic-service:
PRISONER_PROFILE_URL: "https://prisoner-dev.digital.prison.service.justice.gov.uk"
PRISON_API_URL: "https://prison-api-dev.prison.service.justice.gov.uk"
KEYWORKER_API_URL: "https://keyworker-api-dev.prison.service.justice.gov.uk"
LEGACY_KEY_WORKERS_UI_URL: "https://dev.manage-key-workers.service.justice.gov.uk"
ENVIRONMENT_NAME: DEV
AUDIT_ENABLED: "false"
SENTRY_ENVIRONMENT: DEV
Expand Down
1 change: 1 addition & 0 deletions helm_deploy/values-preprod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ generic-service:
PRISONER_PROFILE_URL: "https://prisoner-preprod.digital.prison.service.justice.gov.uk"
PRISON_API_URL: "https://prison-api-preprod.prison.service.justice.gov.uk"
KEYWORKER_API_URL: "https://keyworker-api-preprod.prison.service.justice.gov.uk"
LEGACY_KEY_WORKERS_UI_URL: "https://preprod.manage-key-workers.service.justice.gov.uk"
ENVIRONMENT_NAME: PRE-PRODUCTION
AUDIT_ENABLED: "false"
SENTRY_ENVIRONMENT: PRE-PRODUCTION
Expand Down
1 change: 1 addition & 0 deletions helm_deploy/values-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ generic-service:
PRISONER_PROFILE_URL: "https://prisoner.digital.prison.service.justice.gov.uk"
KEYWORKER_API_URL: "https://keyworker-api.prison.service.justice.gov.uk"
PRISON_API_URL: "https://prison-api.prison.service.justice.gov.uk"
LEGACY_KEY_WORKERS_UI_URL: "https://manage-key-workers.service.justice.gov.uk"
AUDIT_ENABLED: "false"
SENTRY_ENVIRONMENT: PRODUCTION

Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
import { v4 as uuidV4 } from 'uuid'

context('test errorHandler', () => {
const uuid = uuidV4()

beforeEach(() => {
cy.task('reset')
cy.task('stubSignIn')
cy.task('stubComponents')
})

it('should go to the custom error page when an API 500s', () => {
cy.task('stubGetPrisoner500')
cy.task('stubGetPrisonerImage')
// TODO: add test for API error handling
it.skip('should go to the custom error page when an API 500s', () => {
cy.task('stubAPI500Error')
cy.signIn()
cy.visit(`${uuid}/prisoners/A1111AA/referral/start`, { failOnStatusCode: false })
cy.visit(`/path-that-requires-API-call`, { failOnStatusCode: false })
cy.findByText(/sorry, there is a problem with the service/i).should('be.visible')
})

it('should say page not found when 404', () => {
cy.signIn()
cy.visit(`${uuid}/foobar`, { failOnStatusCode: false })
cy.visit(`/foobar`, { failOnStatusCode: false })
cy.findByRole('heading', { name: /Page not found/i }).should('be.visible')
})
})
4 changes: 1 addition & 3 deletions integration_tests/pages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ import Page, { PageElement } from './page'

export default class IndexPage extends Page {
constructor() {
super('This site is under construction...')
super('Key workers')
}

headerUserName = (): PageElement => cy.get('[data-qa=header-user-name]')

headerPhaseBanner = (): PageElement => cy.get('[data-qa=header-phase-banner]')
}
1 change: 1 addition & 0 deletions integration_tests/support/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
import './commands'
import '@testing-library/cypress/add-commands'
11 changes: 11 additions & 0 deletions integration_tests/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"target": "es5",
"noEmit": true,
"lib": ["es5", "dom", "es2015.promise"],
"types": ["cypress", "express", "express-session", "@testing-library/cypress"],
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["**/*.ts"]
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"start-feature:dev": "concurrently -k -p \"[{name}]\" -n \"ESBuild,Node\" -c \"yellow.bold,cyan.bold\" \"node esbuild/esbuild.config.js --build --watch \" \"node esbuild/esbuild.config.js --dev-test-server\"",
"lint": "eslint . --cache --max-warnings 0",
"lint-fix": "eslint . --cache --max-warnings 0 --fix",
"typecheck": "tsc",
"typecheck": "tsc && tsc -p integration_tests && tsc -p server/routes",
"test": "jest",
"test:ci": "jest --runInBand",
"security_audit": "npx audit-ci --config audit-ci.json",
Expand Down
1 change: 1 addition & 0 deletions server/@types/express/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export declare global {
csrfToken: ReturnType<CsrfTokenGenerator>
user: HmppsUser
digitalPrisonServicesUrl: string
legacyKeyWorkersUiUrl: string
breadcrumbs: Breadcrumbs
prisoner?: PrisonerSummary
buildNumber?: string
Expand Down
3 changes: 2 additions & 1 deletion server/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import routes from './routes'
import type { Services } from './services'
import checkPopulateUserCaseloads from './middleware/checkPopulateUserCaseloads'
import populateClientToken from './middleware/populateSystemClientToken'
import breadcrumbs from './middleware/breadcrumbs'

export default function createApp(services: Services): express.Application {
const app = express()
Expand Down Expand Up @@ -62,7 +63,7 @@ export default function createApp(services: Services): express.Application {
res.notFound = () => res.status(404).render('pages/not-found')
next()
})

app.use(breadcrumbs())
app.use(checkPopulateUserCaseloads(services.prisonApiService))
app.use(routes(services))

Expand Down
1 change: 1 addition & 0 deletions server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ export default {
serviceUrls: {
digitalPrison: get('DPS_HOME_PAGE_URL', 'http://localhost:3001', requiredInProduction),
prisonerProfile: get('PRISONER_PROFILE_URL', 'http://localhost:3001', requiredInProduction),
legacyKeyWorkersUI: get('LEGACY_KEY_WORKERS_UI_URL', 'http://localhost:3001', requiredInProduction),
},
sqs: {
audit: auditConfig(),
Expand Down
2 changes: 1 addition & 1 deletion server/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module.exports = {
'.*.cy.ts',
],
testMatch: ['<rootDir>/(server|job)/**/?(*.)(test).{ts,js,jsx,mjs}'],
testPathIgnorePatterns: ['<rootDir>/server/routes/journeys', '<rootDir>/server/routes/csip-records', 'node_modules'],
testPathIgnorePatterns: ['<rootDir>/server/routes/journeys', 'node_modules'],
testEnvironment: 'node',
rootDir: '../',
moduleFileExtensions: ['web.js', 'js', 'json', 'node', 'ts'],
Expand Down
Loading
Loading