Skip to content
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
9 changes: 9 additions & 0 deletions src/client/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,12 @@
display: none;
visibility: hidden;
}

.govuk-button--link {
@extend %govuk-link;
@include govuk-font($size: 19);
color: $govuk-link-colour;
border: none;
cursor: pointer;
background-color: transparent;
}
28 changes: 2 additions & 26 deletions src/server/plugins/engine/components/UkAddressField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
} from '~/src/server/plugins/engine/components/FormComponent.js'
import { TextField } from '~/src/server/plugins/engine/components/TextField.js'
import { type QuestionPageController } from '~/src/server/plugins/engine/pageControllers/QuestionPageController.js'
import { type FormQuery } from '~/src/server/plugins/engine/types/index.js'
import {
type ErrorMessageTemplateList,
type FormPayload,
Expand All @@ -17,7 +16,6 @@ import {
type FormSubmissionError,
type FormSubmissionState
} from '~/src/server/plugins/engine/types.js'
import { JOURNEY_BASE_URL } from '~/src/server/plugins/postcode-lookup/models/index.js'

export class UkAddressField extends FormComponent {
declare options: UkAddressFieldComponent['options']
Expand Down Expand Up @@ -160,11 +158,7 @@ export class UkAddressField extends FormComponent {
)
}

getViewModel(
payload: FormPayload,
errors?: FormSubmissionError[],
query?: FormQuery
) {
getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {
const { collection, name, options } = this

const viewModel = super.getViewModel(payload, errors)
Expand Down Expand Up @@ -210,30 +204,12 @@ export class UkAddressField extends FormComponent {
? this.getDisplayStringFromState(payload)
: undefined

let postcodeLookupBaseUrl
let postcodeLookupQuery

if (usePostcodeLookup) {
const searchParams = new URLSearchParams([['clear', 'true']])

if (query) {
Object.entries(query).forEach(([key, value]) => {
searchParams.append(key, value ?? '')
})
}

postcodeLookupBaseUrl = JOURNEY_BASE_URL
postcodeLookupQuery = searchParams.toString()
}

return {
...viewModel,
value,
fieldset,
components,
usePostcodeLookup,
postcodeLookupBaseUrl,
postcodeLookupQuery
usePostcodeLookup
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/server/plugins/engine/models/FormModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,9 @@ function validateFormPayload(
// Skip validation GET requests or other actions
if (
!request.payload ||
(action && ![FormAction.Validate, FormAction.SaveAndExit].includes(action))
(action &&
![FormAction.Validate, FormAction.SaveAndExit].includes(action) &&
!action.startsWith(FormAction.External))
) {
return context
}
Expand Down
3 changes: 1 addition & 2 deletions src/server/plugins/engine/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ export const plugin = {
await server.register({
plugin: postcodeLookupPlugin,
options: {
ordnanceSurveyApiKey,
enginePluginOptions: options
ordnanceSurveyApiKey
}
})
}
Expand Down
57 changes: 56 additions & 1 deletion src/server/plugins/engine/routes/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ComponentType } from '@defra/forms-model'
import Boom from '@hapi/boom'
import {
type ResponseObject,
Expand Down Expand Up @@ -25,8 +26,13 @@ import {
type FormContext,
type PluginOptions
} from '~/src/server/plugins/engine/types.js'
import { dispatch } from '~/src/server/plugins/postcode-lookup/routes/index.js'
import { type PostcodeLookupDispatchArgs } from '~/src/server/plugins/postcode-lookup/types.js'
import {
ExternalActions,
FormAction,
type FormRequest,
type FormRequestPayload,
type FormResponseToolkit
} from '~/src/server/routes/types.js'

Expand All @@ -38,7 +44,7 @@ export async function redirectOrMakeHandler(
context: FormContext
) => ResponseObject | Promise<ResponseObject>
) {
const { app, params } = request
const { app, params, payload } = request
const { model } = app

if (!model) {
Expand All @@ -64,6 +70,55 @@ export async function redirectOrMakeHandler(
})
}

// External journey redirect
const { action = '' } = page.getFormParams(request)
if (payload && action.startsWith(FormAction.External)) {
// Find the external action and arguments
// `external-{externalAction}--{argname1}:{argvalue1}--{argname2}:{argvalue2}`
// E.g. external-postcode-lookup--name:wDFtgf--step:manual
const externalActionsWithArgs = action
.slice(`${FormAction.External}-`.length)
.split('--')
const externalAction = externalActionsWithArgs[0] as ExternalActions
const externalActionArgs = externalActionsWithArgs
.slice(1)
.map((arg) => arg.split(':'))

switch (externalAction) {
case ExternalActions.PostcodeLookup: {
const args = Object.fromEntries(
externalActionArgs
) as PostcodeLookupDispatchArgs
const componentName = args.name
const component = model.componentDefMap.get(componentName)

if (!component) {
throw Boom.notFound(`No component found for ${componentName}`)
}

if (component.type !== ComponentType.UkAddressField) {
throw Boom.internal(
`Invalid component type, expected UkAddressFieldComponent got ${component.type}`
)
}

return dispatch(request as FormRequestPayload, h, {
payload,
formName: model.name,
componentName,
componentHint: component.hint,
componentTitle: component.title || page.title,
step: args.step,
sourceUrl: request.url.toString()
})
}
default:
throw Boom.internal(
`Invalid external action, expected one of '${Object.values(ExternalActions).join('|')}' got '${externalAction}'`
)
}
}

const flash = cacheService.getFlash(request)
const context = model.getFormContext(request, state, flash?.errors)
const relevantPath = page.getRelevantPath(request, context)
Expand Down
17 changes: 10 additions & 7 deletions src/server/plugins/engine/views/components/ukaddressfield.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,18 @@
}) if fieldset else addressFieldHtml }}

{% if usePostcodeLookup %}
{% set postcodeLookupBaseUrl = component.model.postcodeLookupBaseUrl %}
{% set postcodeLookupQuery = component.model.postcodeLookupQuery %}
{% set value = component.model.value %}
{% set postcodeLookupHref = postcodeLookupBaseUrl + "/" + slug + page.path + "/" + component.model.name + "?" + postcodeLookupQuery %}
{% set value = component.model.value %}

{% if value %}
{% set insetHtml %}
<strong>Selected address:</strong>
<br><br>
{{ value }}
<br><br>
<a href="{{ postcodeLookupHref }}" class="govuk-link govuk-link--no-visited-state">Use a different address</a>
<p class="govuk-body">
<button class="govuk-link govuk-button--link govuk-!-margin-right-1" name="action"
value="external-postcode-lookup--name:{{component.model.name}}">Use a different address</button>
</p>
{% endset %}

{{ govukInsetText({
Expand All @@ -54,10 +54,13 @@
<div class="govuk-button-group">
{{ govukButton({
text: "Find an address",
href: postcodeLookupHref,
attributes: {
name: "action",
value: "external-postcode-lookup--name:" + component.model.name
},
classes: "govuk-button--secondary govuk-!-margin-right-1"
}) }}
<p class="govuk-body">or <a href="{{ postcodeLookupHref }}&step=manual" class="govuk-link govuk-link--no-visited-state">enter address manually</a></p>
<p class="govuk-body">or <button class="govuk-link govuk-button--link govuk-!-margin-right-1" name="action" value="external-postcode-lookup--name:{{component.model.name}}--step:manual">enter address manually</button></p>
</div>
{% endif %}
{% endif %}
Expand Down
22 changes: 2 additions & 20 deletions src/server/plugins/postcode-lookup/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { makeLoadFormPreHandler } from '~/src/server/plugins/engine/routes/index.js'
import { getRoutes } from '~/src/server/plugins/postcode-lookup/routes/index.js'

export const VIEW_PATH = 'src/server/plugins/postcode-lookup/views'
Expand All @@ -11,25 +10,8 @@ export const postcodeLookupPlugin = {
dependencies: ['@hapi/vision'],
multiple: false,
register(server, options) {
const loadFormPreHandler = makeLoadFormPreHandler(
server,
options.enginePluginOptions
)

const getRouteOptions = {
pre: [
{
method: loadFormPreHandler
}
]
}

server.route(
/** @type {ServerRoute[]} */ (
// @ts-expect-error - Request typing
getRoutes(getRouteOptions, options)
)
)
// @ts-expect-error - Request typing
server.route(getRoutes(options))
}
}

Expand Down
Loading
Loading