From 27ade91013d72aca2b5e4672557c1d3e4cbf935f Mon Sep 17 00:00:00 2001 From: Bob Meredith Date: Mon, 6 Jan 2025 16:15:30 +0000 Subject: [PATCH] APS-1702 Suitability search filter changes --- e2e/steps/assess.ts | 4 +- integration_tests/pages/match/searchPage.ts | 6 -- integration_tests/tests/match/match.cy.ts | 6 +- server/@types/ui/index.d.ts | 8 +-- .../matchingInformation.test.ts | 20 +++--- .../matchingInformation.ts | 6 +- .../utils/matchingInformationUtils.test.ts | 61 ++----------------- .../utils/matchingInformationUtils.ts | 14 +---- .../testutils/factories/placementRequest.ts | 2 - .../factories/spaceSearchParameters.ts | 1 - .../utils/assessments/acceptanceData.test.ts | 13 +--- server/utils/match/index.test.ts | 6 +- server/utils/match/index.ts | 18 +++--- server/utils/placementCriteriaUtils.ts | 32 +++++++--- server/utils/placementRequests/utils.test.ts | 1 - server/utils/placementRequests/utils.ts | 2 - server/utils/utils.ts | 6 +- server/views/match/search.njk | 47 ++++++-------- 18 files changed, 87 insertions(+), 166 deletions(-) diff --git a/e2e/steps/assess.ts b/e2e/steps/assess.ts index 4548192dbd..1c67f0ce1f 100644 --- a/e2e/steps/assess.ts +++ b/e2e/steps/assess.ts @@ -144,7 +144,7 @@ export const addMatchingInformation = async (page: Page) => { await matchingInformationPage.checkRadio('Standard AP') - const relevantRisksAndOffences = ['Accepts hate crime offenders', 'Accepts non sexual child offenders'] + const relevantRisksAndOffences = ['Accepts hate crime offenders', 'Accepts non sexual child offenders', 'Is catered'] const irrelevantRisksAndOffences = [ 'Accepts sex offenders', 'Is suitable for vulnerable', @@ -153,7 +153,7 @@ export const addMatchingInformation = async (page: Page) => { 'Is arson suitable', ] - const essentialCharacteristics = ['Is catered', 'Has en suite'] + const essentialCharacteristics = ['Has en suite'] const desirableCharacteristics: Array = [] const irrelevantCharacteristics = ['Is step free designated', 'Is wheelchair designated', 'Is single'] diff --git a/integration_tests/pages/match/searchPage.ts b/integration_tests/pages/match/searchPage.ts index b3e237978c..5d29fa98ca 100644 --- a/integration_tests/pages/match/searchPage.ts +++ b/integration_tests/pages/match/searchPage.ts @@ -59,15 +59,11 @@ export default class SearchPage extends Page { } changeSearchParameters(newSearchParameters: SpaceSearchParametersUi): void { - this.clearDateInputs('startDate') - this.completeDateInputs('startDate', newSearchParameters.startDate) - this.getTextInputByIdAndClear('targetPostcodeDistrict') this.getTextInputByIdAndEnterDetails('targetPostcodeDistrict', newSearchParameters.targetPostcodeDistrict) cy.get('[type="checkbox"]').uncheck() this.checkRadioByNameAndValue('requirements[apType]', newSearchParameters.requirements.apType) - this.checkRadioByNameAndValue('requirements[gender]', newSearchParameters.requirements.gender) newSearchParameters.requirements.spaceCharacteristics.forEach(requirement => { cy.get(`input[name="requirements[spaceCharacteristics][]"][value="${requirement}"]`).check() @@ -75,11 +71,9 @@ export default class SearchPage extends Page { } shouldShowSearchParametersInInputs(newSearchParameters: SpaceSearchParametersUi): void { - this.dateInputsShouldContainDate('startDate', newSearchParameters.startDate) this.verifyTextInputContentsById('targetPostcodeDistrict', newSearchParameters.targetPostcodeDistrict) cy.get(`input[name="requirements[apType]"][value="${newSearchParameters.requirements.apType}"]`) - cy.get(`input[name="requirements[gender]"][value="${newSearchParameters.requirements.gender}"]`) newSearchParameters.requirements.spaceCharacteristics.forEach(requirement => { cy.get(`input[name="requirements[spaceCharacteristics][]"][value="${requirement}"]`).should('be.checked') diff --git a/integration_tests/tests/match/match.cy.ts b/integration_tests/tests/match/match.cy.ts index 9ba6281176..c78e952979 100644 --- a/integration_tests/tests/match/match.cy.ts +++ b/integration_tests/tests/match/match.cy.ts @@ -90,7 +90,6 @@ context('Placement Requests', () => { targetPostcodeDistrict: placementRequest.location, requirements: { apTypes: [placementRequest.type], - genders: [placementRequest.gender], spaceCharacteristics: filteredPlacementCriteria, }, }) @@ -99,7 +98,7 @@ context('Placement Requests', () => { expect(secondSearchRequestBody).to.contain({ applicationId: placementRequest.applicationId, durationInDays: placementRequest.duration, - startDate: newSearchParameters.startDate, + startDate: placementRequest.expectedArrival, targetPostcodeDistrict: newSearchParameters.targetPostcodeDistrict, }) @@ -107,7 +106,6 @@ context('Placement Requests', () => { expect(secondSearchRequestBody.requirements.spaceCharacteristics).to.contain.members( newSearchParameters.requirements.spaceCharacteristics, ) - expect(secondSearchRequestBody.requirements.genders).to.contain.members([newSearchParameters.requirements.gender]) }) }) @@ -296,7 +294,7 @@ context('Placement Requests', () => { // And there is a placement request waiting for me to match const person = personFactory.build() - const essentialCharacteristics: Array = ['acceptsHateCrimeOffenders'] + const essentialCharacteristics: Array = ['isArsonDesignated'] const desirableCharacteristics: Array = ['isCatered', 'hasEnSuite'] const placementRequest = placementRequestDetailFactory.build({ person, diff --git a/server/@types/ui/index.d.ts b/server/@types/ui/index.d.ts index 2fba252d2e..681cf47478 100644 --- a/server/@types/ui/index.d.ts +++ b/server/@types/ui/index.d.ts @@ -13,7 +13,6 @@ import { Cas1PremisesBasicSummary, Document, FlagsEnvelope, - Gender, Mappa, OASysSection, PersonAcctAlert, @@ -111,7 +110,7 @@ export type TableCell = export type TableRow = Array -export interface RadioItem { +export type RadioItem = { text: string value: string checked?: boolean @@ -131,9 +130,9 @@ export type CheckBoxItem = } behaviour?: 'exclusive' } - | CheckBoxDivider + | Divider -export type CheckBoxDivider = { divider: string } +export type Divider = { divider: string } export interface SelectOption { text: string @@ -385,7 +384,6 @@ export interface SpaceSearchParametersUi { durationInDays: string requirements: { apType: ApType - gender: Gender spaceCharacteristics: Array } } diff --git a/server/form-pages/assess/matchingInformation/matchingInformationTask/matchingInformation.test.ts b/server/form-pages/assess/matchingInformation/matchingInformationTask/matchingInformation.test.ts index 431e1bf25e..1db9755c98 100644 --- a/server/form-pages/assess/matchingInformation/matchingInformationTask/matchingInformation.test.ts +++ b/server/form-pages/assess/matchingInformation/matchingInformationTask/matchingInformation.test.ts @@ -45,7 +45,7 @@ const defaultMatchingInformationValuesReturnValue: Partial { const page = new MatchingInformation({}, assessment) expect(page.errors()).toEqual({ - isStepFreeDesignated: 'You must specify a preference for step-free access', - hasEnSuite: 'You must specify a preference for en-suite bathroom', + isStepFreeDesignated: 'You must specify a preference for step-free', + hasEnSuite: 'You must specify a preference for en-suite', lengthOfStayAgreed: 'You must state if you agree with the length of the stay', }) }) @@ -115,18 +115,18 @@ describe('MatchingInformation', () => { expect(page.response()).toEqual({ 'What type of AP is required?': 'Enhanced Security AP (ESAP)', - 'Designated arson room': 'Essential', - 'Room suitable for a person with sexual offences': 'Not relevant', - 'Wheelchair accessible': 'Essential', + 'Suitable for sexual offences': 'Not relevant', + Wheelchair: 'Essential', 'Single room': 'Desirable', - 'Step-free access': 'Desirable', - 'Catering required': 'Not relevant', - 'En-suite bathroom': 'Not relevant', + 'Step-free': 'Desirable', + Catered: 'Not relevant', + 'En-suite': 'Not relevant', 'Vulnerable to exploitation': 'Relevant', - 'Sexual offences against an adult': 'Relevant', + 'Sexual offences against adults': 'Relevant', 'Sexual offences against children': 'Relevant', 'Non sexual offences against children': 'Relevant', 'Hate based offences': 'Relevant', + 'Arson room': 'Essential', 'Arson offences': 'Relevant', 'Do you agree with the suggested length of stay?': 'Yes', 'Information for Central Referral Unit (CRU) manager': 'Some info', diff --git a/server/form-pages/assess/matchingInformation/matchingInformationTask/matchingInformation.ts b/server/form-pages/assess/matchingInformation/matchingInformationTask/matchingInformation.ts index a86f4a731c..1d88ed7421 100644 --- a/server/form-pages/assess/matchingInformation/matchingInformationTask/matchingInformation.ts +++ b/server/form-pages/assess/matchingInformation/matchingInformationTask/matchingInformation.ts @@ -160,9 +160,9 @@ export default class MatchingInformation implements TasklistPage { this.placementRequirementCriteria.forEach(placementRequirementCriterion => { if (!this.body[placementRequirementCriterion]) { - errors[placementRequirementCriterion] = `You must specify a preference for ${lowerCase( - placementCriteriaLabels[placementRequirementCriterion], - )}` + errors[placementRequirementCriterion] = `You must specify a preference for ${placementCriteriaLabels[ + placementRequirementCriterion + ].toLowerCase()}` } }) diff --git a/server/form-pages/utils/matchingInformationUtils.test.ts b/server/form-pages/utils/matchingInformationUtils.test.ts index bd86db1f9e..2703428602 100644 --- a/server/form-pages/utils/matchingInformationUtils.test.ts +++ b/server/form-pages/utils/matchingInformationUtils.test.ts @@ -36,9 +36,9 @@ describe('matchingInformationUtils', () => { describe('defaultMatchingInformationValues', () => { const bodyWithUndefinedValues: MatchingInformationBody = { acceptsChildSexOffenders: undefined, - acceptsHateCrimeOffenders: undefined, acceptsNonSexualChildOffenders: undefined, acceptsSexOffenders: undefined, + acceptsHateCrimeOffenders: undefined, apType: undefined, cruInformation: undefined, hasEnSuite: undefined, @@ -109,13 +109,12 @@ describe('matchingInformationUtils', () => { expect(defaultMatchingInformationValues(body, application)).toEqual({ acceptsChildSexOffenders: 'relevant', - acceptsHateCrimeOffenders: 'relevant', acceptsNonSexualChildOffenders: 'relevant', + acceptsHateCrimeOffenders: 'relevant', acceptsSexOffenders: 'relevant', apType: 'isPIPE', isArsonDesignated: 'essential', - isArsonSuitable: 'relevant', - isCatered: 'essential', + isCatered: 'relevant', isSingle: 'essential', isSuitableForVulnerable: 'relevant', isSuitedForSexOffenders: 'essential', @@ -128,13 +127,11 @@ describe('matchingInformationUtils', () => { it('uses current values where they exist', () => { const currentValues: Partial = { acceptsChildSexOffenders: 'relevant', - acceptsHateCrimeOffenders: 'relevant', acceptsNonSexualChildOffenders: 'relevant', acceptsSexOffenders: 'relevant', apType: 'isPIPE', isArsonDesignated: 'desirable', - isArsonSuitable: 'relevant', - isCatered: 'desirable', + isCatered: 'relevant', isSingle: 'desirable', isSuitableForVulnerable: 'relevant', isSuitedForSexOffenders: 'desirable', @@ -180,30 +177,6 @@ describe('matchingInformationUtils', () => { }) }) - describe('acceptsHateCrimeOffenders', () => { - truthyCurrentPreviousValues.forEach(value => { - it(`is set to 'relevant' when \`hateCrime\` === ['${value.join("', '")}']`, () => { - when(retrieveOptionalQuestionResponseFromFormArtifact) - .calledWith(application, DateOfOffence, 'hateCrime') - .mockReturnValue(value) - - expect(defaultMatchingInformationValues(bodyWithUndefinedValues, application)).toEqual( - expect.objectContaining({ acceptsHateCrimeOffenders: 'relevant' }), - ) - }) - }) - - it("is set to 'notRelevant' when `hateCrime` === undefined", () => { - when(retrieveOptionalQuestionResponseFromFormArtifact) - .calledWith(application, DateOfOffence, 'hateCrime') - .mockReturnValue(undefined) - - expect(defaultMatchingInformationValues(bodyWithUndefinedValues, application)).toEqual( - expect.objectContaining({ acceptsHateCrimeOffenders: 'notRelevant' }), - ) - }) - }) - describe('acceptsNonSexualChildOffenders', () => { truthyCurrentPreviousValues.forEach(value => { it(`is set to 'relevant' when \`nonSexualOffencesAgainstChildren\` === ['${value.join("', '")}']`, () => { @@ -299,30 +272,6 @@ describe('matchingInformationUtils', () => { }) }) - describe('isArsonSuitable', () => { - truthyCurrentPreviousValues.forEach(value => { - it(`is set to 'relevant' when \`arsonOffence\` === ['${value.join("', '")}']`, () => { - when(retrieveOptionalQuestionResponseFromFormArtifact) - .calledWith(application, DateOfOffence, 'arsonOffence') - .mockReturnValue(value) - - expect(defaultMatchingInformationValues(bodyWithUndefinedValues, application)).toEqual( - expect.objectContaining({ isArsonSuitable: 'relevant' }), - ) - }) - }) - - it("is set to 'notRelevant' when `arsonOffence` === undefined", () => { - when(retrieveOptionalQuestionResponseFromFormArtifact) - .calledWith(application, DateOfOffence, 'arsonOffence') - .mockReturnValue(undefined) - - expect(defaultMatchingInformationValues(bodyWithUndefinedValues, application)).toEqual( - expect.objectContaining({ isArsonSuitable: 'notRelevant' }), - ) - }) - }) - describe('isCatered', () => { it("is set to 'essential' when `catering` (self-catering) === 'no'", () => { when(retrieveQuestionResponseFromFormArtifact) @@ -330,7 +279,7 @@ describe('matchingInformationUtils', () => { .mockReturnValue('no') expect(defaultMatchingInformationValues(bodyWithUndefinedValues, application)).toEqual( - expect.objectContaining({ isCatered: 'essential' }), + expect.objectContaining({ isCatered: 'relevant' }), ) }) diff --git a/server/form-pages/utils/matchingInformationUtils.ts b/server/form-pages/utils/matchingInformationUtils.ts index 0d9e529868..601e84cfa2 100644 --- a/server/form-pages/utils/matchingInformationUtils.ts +++ b/server/form-pages/utils/matchingInformationUtils.ts @@ -148,6 +148,7 @@ const defaultMatchingInformationValues = ( 'relevant', 'notRelevant', ), + apType: apType(body, application), isArsonDesignated: getValue( body, @@ -158,22 +159,13 @@ const defaultMatchingInformationValues = ( 'essential', 'notRelevant', ), - isArsonSuitable: getValue( - body, - 'isArsonSuitable', - application, - [{ name: 'arsonOffence', page: DateOfOffence, optional: true }], - ['current', 'previous'], - 'relevant', - 'notRelevant', - ), - isCatered: getValue( + isCatered: getValue( body, 'isCatered', application, [{ name: 'catering', page: Catering }], ['no'], - 'essential', + 'relevant', 'notRelevant', ), isSingle: getValue( diff --git a/server/testutils/factories/placementRequest.ts b/server/testutils/factories/placementRequest.ts index 35cfa1b516..9afd6632f7 100644 --- a/server/testutils/factories/placementRequest.ts +++ b/server/testutils/factories/placementRequest.ts @@ -54,12 +54,10 @@ export const placementCriteria: Array = [ 'acceptsSexOffenders', 'acceptsChildSexOffenders', 'acceptsNonSexualChildOffenders', - 'acceptsHateCrimeOffenders', 'isWheelchairDesignated', 'isSingle', 'isStepFreeDesignated', 'isCatered', 'hasEnSuite', 'isSuitedForSexOffenders', - 'isArsonSuitable', ] as const diff --git a/server/testutils/factories/spaceSearchParameters.ts b/server/testutils/factories/spaceSearchParameters.ts index 695a3b87e3..0f2a2f4b28 100644 --- a/server/testutils/factories/spaceSearchParameters.ts +++ b/server/testutils/factories/spaceSearchParameters.ts @@ -36,7 +36,6 @@ export const spaceSearchParametersUiFactory = Factory.define { apType: 'isESAP', isWheelchairDesignated: 'essential', isStepFreeDesignated: 'essential', - isCatered: 'essential', acceptsSexOffenders: 'relevant', acceptsChildSexOffenders: 'relevant', acceptsNonSexualChildOffenders: 'relevant', - isArsonSuitable: 'relevant', - acceptsHateCrimeOffenders: 'relevant', isSuitableForVulnerable: 'relevant', }) @@ -153,12 +150,9 @@ describe('acceptanceData', () => { 'isESAP', 'isWheelchairDesignated', 'isStepFreeDesignated', - 'isCatered', 'acceptsSexOffenders', 'acceptsChildSexOffenders', 'acceptsNonSexualChildOffenders', - 'isArsonSuitable', - 'acceptsHateCrimeOffenders', 'isSuitableForVulnerable', 'isSuitedForSexOffenders', ].sort(), @@ -170,14 +164,11 @@ describe('acceptanceData', () => { apType: 'normal', isWheelchairDesignated: 'desirable', isStepFreeDesignated: 'desirable', - isCatered: 'desirable', }) const result = criteriaFromMatchingInformation(matchingInformation) - expect(result.desirableCriteria.sort()).toEqual( - ['isStepFreeDesignated', 'isWheelchairDesignated', 'isCatered'].sort(), - ) + expect(result.desirableCriteria.sort()).toEqual(['isStepFreeDesignated', 'isWheelchairDesignated'].sort()) expect(result.essentialCriteria).toEqual([]) }) @@ -190,8 +181,6 @@ describe('acceptanceData', () => { acceptsSexOffenders: 'notRelevant', acceptsChildSexOffenders: 'notRelevant', acceptsNonSexualChildOffenders: 'notRelevant', - isArsonSuitable: 'notRelevant', - acceptsHateCrimeOffenders: 'notRelevant', isSuitableForVulnerable: 'notRelevant', }) diff --git a/server/utils/match/index.test.ts b/server/utils/match/index.test.ts index ae25f9ca2d..000bfdd402 100644 --- a/server/utils/match/index.test.ts +++ b/server/utils/match/index.test.ts @@ -86,7 +86,6 @@ describe('matchUtils', () => { durationInDays: Number(uiParams.durationInDays), requirements: { apTypes: [uiParams.requirements.apType], - genders: [uiParams.requirements.gender], spaceCharacteristics: uiParams.requirements.spaceCharacteristics, }, applicationId: uiParams.applicationId, @@ -210,11 +209,11 @@ describe('matchUtils', () => { describe('groupedCheckboxes', () => { it('returns checkboxes grouped by category', () => { expect(groupedCheckboxes()).toEqual({ - 'Risks and offences': { + 'AP requirements': { inputName: 'spaceCharacteristics', items: groupedCriteria.offenceAndRisk.items, }, - 'Access needs and additional features': { + 'Room requirements': { inputName: 'spaceCharacteristics', items: groupedCriteria.accessNeeds.items, }, @@ -567,6 +566,7 @@ describe('matchUtils', () => { text: 'Standard AP', value: 'normal', }, + { divider: 'or' }, { checked: false, conditional: undefined, diff --git a/server/utils/match/index.ts b/server/utils/match/index.ts index dcb6ce22ce..a5f8e2adc1 100644 --- a/server/utils/match/index.ts +++ b/server/utils/match/index.ts @@ -11,9 +11,10 @@ import type { Cas1SpaceSearchParameters as SpaceSearchParameters, Cas1SpaceSearchResult as SpaceSearchResult, } from '@approved-premises/api' -import type { +import { KeyDetailsArgs, ObjectWithDateParts, + RadioItem, SpaceSearchParametersUi, SummaryListItem, } from '@approved-premises/ui' @@ -21,9 +22,9 @@ import { DateFormats, daysToWeeksAndDays } from '../dateUtils' import { createQueryString, sentenceCase } from '../utils' import matchPaths from '../../paths/match' import { - offenceAndRiskCriteriaLabels, placementCriteriaLabels, placementRequirementCriteriaLabels, + spaceSearchCriteriaApLevelLabels, } from '../placementCriteriaUtils' import { apTypeLabels } from '../apTypeLabels' import { convertKeyValuePairToRadioItems } from '../formUtils' @@ -56,7 +57,6 @@ export const mapUiParamsForApi = (query: SpaceSearchParametersUi): SpaceSearchPa targetPostcodeDistrict: query.targetPostcodeDistrict, requirements: { apTypes: [query.requirements.apType], - genders: [query.requirements.gender], spaceCharacteristics: query.requirements.spaceCharacteristics, }, durationInDays: Number(query.durationInDays), @@ -387,12 +387,12 @@ export const startDateObjFromParams = (params: { startDate: string } | ObjectWit export const groupedCriteria = { offenceAndRisk: { - title: 'Risks and offences', - items: offenceAndRiskCriteriaLabels, + title: 'AP requirements', + items: spaceSearchCriteriaApLevelLabels, inputName: 'spaceCharacteristics', }, accessNeeds: { - title: 'Access needs and additional features', + title: 'Room requirements', items: placementRequirementCriteriaLabels, inputName: 'spaceCharacteristics', }, @@ -422,7 +422,11 @@ export const checkBoxesForCriteria = (criteria: Record, selected } export const apTypeLabelsForRadioInput = (selectedValue: ApType) => { - return convertKeyValuePairToRadioItems(apTypeLabels, selectedValue) + const apTypeRadios = convertKeyValuePairToRadioItems(apTypeLabels, selectedValue) as Array< + RadioItem | { divider: 'or' } + > + apTypeRadios.splice(1, 0, { divider: 'or' }) + return apTypeRadios } export const lengthOfStayRow = (lengthInDays: number) => ({ diff --git a/server/utils/placementCriteriaUtils.ts b/server/utils/placementCriteriaUtils.ts index 5ec28f1136..b1230bb6d6 100644 --- a/server/utils/placementCriteriaUtils.ts +++ b/server/utils/placementCriteriaUtils.ts @@ -20,18 +20,18 @@ export const applyApTypeToAssessApType: Record, Specia export const specialistApTypeCriteria = apTypes.map(type => applyApTypeToAssessApType[type]) export const offenceAndRiskCriteria = [ - 'isSuitableForVulnerable', 'acceptsSexOffenders', 'acceptsChildSexOffenders', 'acceptsNonSexualChildOffenders', 'acceptsHateCrimeOffenders', 'isArsonSuitable', + 'isSuitableForVulnerable', + 'isCatered', ] as const export const prepopulatablePlacementRequirementCriteria = [ 'isWheelchairDesignated', 'isArsonDesignated', 'isSingle', - 'isCatered', 'isSuitedForSexOffenders', ] as const export const nonPrepopulatablePlacementRequirementCriteria = ['isStepFreeDesignated', 'hasEnSuite'] as const @@ -51,22 +51,22 @@ export const placementCriteriaLabels: Record = { isMHAPElliottHouse: 'Specialist Mental Health AP (Elliott House - Midlands)', isMHAPStJosephs: 'Specialist Mental Health AP (St Josephs - Greater Manchester)', isSemiSpecialistMentalHealth: 'Semi-specialist mental health', - isSuitableForVulnerable: 'Vulnerable to exploitation', - acceptsSexOffenders: 'Sexual offences against an adult', + acceptsSexOffenders: 'Sexual offences against adults', acceptsChildSexOffenders: 'Sexual offences against children', acceptsNonSexualChildOffenders: 'Non sexual offences against children', + isSuitableForVulnerable: 'Vulnerable to exploitation', acceptsHateCrimeOffenders: 'Hate based offences', - isWheelchairDesignated: 'Wheelchair accessible', + isWheelchairDesignated: 'Wheelchair', + isStepFreeDesignated: 'Step-free', + hasEnSuite: 'En-suite', isSingle: 'Single room', - isStepFreeDesignated: 'Step-free access', - isCatered: 'Catering required', - hasEnSuite: 'En-suite bathroom', - isSuitedForSexOffenders: 'Room suitable for a person with sexual offences', + isCatered: 'Catered', + isArsonDesignated: 'Arson room', + isSuitedForSexOffenders: 'Suitable for sexual offences', isArsonSuitable: 'Arson offences', hasBrailleSignage: 'Braille signage', hasTactileFlooring: 'Tactile flooring', hasHearingLoop: 'Hearing loop', - isArsonDesignated: 'Designated arson room', } export const specialistApTypeCriteriaLabels = filterByType( @@ -85,3 +85,15 @@ export const placementRequirementCriteriaLabels = filterByType = [ + 'acceptsSexOffenders', + 'acceptsChildSexOffenders', + 'acceptsNonSexualChildOffenders', + 'isSuitableForVulnerable', + 'isCatered', +] + +export const spaceSearchCriteriaApLevelLabels = filterByType(apLevelSearchCriteria, { + ...placementCriteriaLabels, + isSuitableForVulnerable: 'Vulnerable to exploitation (removes ESAP APs)', +}) diff --git a/server/utils/placementRequests/utils.test.ts b/server/utils/placementRequests/utils.test.ts index 8b0b55aa79..a976a24f30 100644 --- a/server/utils/placementRequests/utils.test.ts +++ b/server/utils/placementRequests/utils.test.ts @@ -34,7 +34,6 @@ describe('utils', () => { ...placementRequest.essentialCriteria, ]), apType: placementRequest.type, - gender: placementRequest.gender, }, }) }) diff --git a/server/utils/placementRequests/utils.ts b/server/utils/placementRequests/utils.ts index 9a6f916288..408f13d315 100644 --- a/server/utils/placementRequests/utils.ts +++ b/server/utils/placementRequests/utils.ts @@ -18,7 +18,6 @@ export const mapPlacementRequestToSpaceSearchParams = ({ essentialCriteria, desirableCriteria, type, - gender, }: PlacementRequest): SpaceSearchParametersUi => { return { applicationId, @@ -28,7 +27,6 @@ export const mapPlacementRequestToSpaceSearchParams = ({ requirements: { spaceCharacteristics: filterOutAPTypes([...desirableCriteria, ...essentialCriteria]), apType: type, - gender, }, } } diff --git a/server/utils/utils.ts b/server/utils/utils.ts index 3b2afec349..c7ee33595b 100644 --- a/server/utils/utils.ts +++ b/server/utils/utils.ts @@ -64,8 +64,10 @@ export const pascalCase = (string: string) => camelCase(string).replace(/\w/, s */ export const sentenceCase = (string: string) => Case.sentence(string) -export const lowerCase = (string: string) => Case.lower(string) - +export const lowerCase = (string: string) => { + const result = Case.lower(string) + return result +} /** * Removes any items in an array of summary list items that are blank or undefined * @param items an array of summary list items diff --git a/server/views/match/search.njk b/server/views/match/search.njk index 0725eb7481..4dc60749b2 100644 --- a/server/views/match/search.njk +++ b/server/views/match/search.njk @@ -21,6 +21,11 @@ }) }} {% endblock %} +{% set locationTitle %} + Preferred location +
For example, M5
+{% endset %} + {% block content %}
@@ -54,31 +59,29 @@
- {{ govukDateInput({ - id: "startDate", - namePrefix: "startDate", - fieldset: { - legend: { - text: "Available from", - classes: "govuk-fieldset__legend--s" - } + {% call govukFieldset({ + legend: { + html: locationTitle }, - items: dateFieldValues('startDate', errors), - errorMessage: errors.startDate - }) }} + hint: { + text: "For example, M5" + } + }) %} {{ govukInput({ id: "targetPostcodeDistrict", name: "targetPostcodeDistrict", value: targetPostcodeDistrict, label: { - text: "Preferred location", - classes: "govuk-fieldset__legend--s" - + text: "Postcode" }, classes: "govuk-input--width-3" }) }} + {% endcall %} + +
+ {{ govukRadios({ name: "requirements[apType]", classes: "govuk-radios--small", @@ -106,21 +109,7 @@ items: MatchUtils.checkBoxesForCriteria(details.items, context['requirements'][details.inputName]) }) }} {% endfor %} - - {{ govukRadios({ - name: "requirements[gender]", - classes: "govuk-radios--small", - value: requirements.gender, - fieldset: { - legend: { - text: 'Gender', - classes: 'govuk-fieldset__legend--s', - isPageHeading: false - } - }, - items: [{value: 'male', text: 'Male' }, {value: 'female', text: 'Female' }] - }) }} - +
{{ govukButton({ text: "Update",