Skip to content

Commit

Permalink
Merge pull request #162 from ministryofjustice/719-tasklist
Browse files Browse the repository at this point in the history
(719) Add basic task list
  • Loading branch information
yndajas committed Aug 31, 2023
2 parents 1486e55 + a2988a4 commit 2550d7a
Show file tree
Hide file tree
Showing 13 changed files with 215 additions and 10 deletions.
1 change: 1 addition & 0 deletions assets/scss/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ $govuk-page-width: $moj-page-width;
@import './components/header-bar';
@import './components/navigation';
@import './components/person-banner';
@import './components/task-list';
@import './local';
3 changes: 3 additions & 0 deletions assets/scss/components/_task-list.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.moj-task-list__items {
padding-left: 0;
}
5 changes: 3 additions & 2 deletions integration_tests/e2e/refer.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ context('Refer', () => {
const confirmPersonPage = Page.verifyOnPage(ConfirmPersonPage, { course, courseOffering, person })
confirmPersonPage.confirmPerson()

Page.verifyOnPage(TaskListPage, { course, courseOffering, organisation })
Page.verifyOnPage(TaskListPage, { course, courseOffering, organisation, referral })
})

it('Shows the in-progress referral task list', () => {
Expand Down Expand Up @@ -169,11 +169,12 @@ context('Refer', () => {
const path = referPaths.show({ referralId: referral.id })
cy.visit(path)

const taskListPage = Page.verifyOnPage(TaskListPage, { course, courseOffering, organisation })
const taskListPage = Page.verifyOnPage(TaskListPage, { course, courseOffering, organisation, referral })
taskListPage.shouldHavePersonDetails(person)
taskListPage.shouldContainNavigation(path)
taskListPage.shouldContainBackLink('#')
taskListPage.shouldContainOrganisationAndCourseHeading(taskListPage)
taskListPage.shouldContainAudienceTags(taskListPage.course.audienceTags)
taskListPage.shouldContainTaskList()
})
})
2 changes: 1 addition & 1 deletion integration_tests/pages/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export default abstract class Page {
}): void {
const { course, organisation } = pageWithOrganisationAndCoursePresenter

cy.get('h2:nth-of-type(1)').then(organisationAndCourseHeading => {
cy.get('.govuk-grid-column-two-thirds > h2:first-child').then(organisationAndCourseHeading => {
const expectedText = `${organisation.name} | ${course.nameAndAlternateName}`
const { actual, expected } = Helpers.parseHtml(organisationAndCourseHeading, expectedText)
expect(actual).to.equal(expected)
Expand Down
40 changes: 36 additions & 4 deletions integration_tests/pages/refer/taskList.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CourseUtils } from '../../../server/utils'
import { CourseUtils, ReferralUtils } from '../../../server/utils'
import Page from '../page'
import type { Course, CourseOffering, Organisation } from '@accredited-programmes/models'
import type { Course, CourseOffering, Organisation, Referral } from '@accredited-programmes/models'
import type { CoursePresenter } from '@accredited-programmes/ui'

export default class TaskListPage extends Page {
Expand All @@ -10,12 +10,44 @@ export default class TaskListPage extends Page {

organisation: Organisation

constructor(args: { course: Course; courseOffering: CourseOffering; organisation: Organisation }) {
referral: Referral

constructor(args: {
course: Course
courseOffering: CourseOffering
organisation: Organisation
referral: Referral
}) {
super('Make a referral')

const { course, courseOffering, organisation } = args
const { course, courseOffering, organisation, referral } = args
this.course = CourseUtils.presentCourse(course)
this.courseOffering = courseOffering
this.organisation = organisation
this.referral = referral
}

shouldContainTaskList() {
const taskListSections = ReferralUtils.taskListSections(this.referral)

taskListSections.forEach((section, sectionIndex) => {
cy.get(`.moj-task-list > li:nth-child(${sectionIndex + 1})`).within(() => {
cy.get('.moj-task-list__section').should('have.text', section.heading)

section.items.forEach((item, itemIndex) => {
cy.get(`.moj-task-list__item:nth-child(${itemIndex + 1})`).within(listItemElement => {
cy.get('.moj-task-list__task-name').then(taskNameElement => {
cy.wrap(taskNameElement).should('have.text', item.text)

if (item.url) {
cy.wrap(taskNameElement).should('have.attr', 'href', item.url)
}
})

this.shouldContainTags([item.statusTag], listItemElement)
})
})
})
})
}
}
22 changes: 22 additions & 0 deletions server/@types/ui/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,25 @@ type OrganisationWithOfferingEmailsPresenter = Organisation & {
summaryListRows: Array<GovukFrontendSummaryListRowWithValue>
}

type ReferralTaskListStatusText = 'completed' | 'not started' | 'cannot start yet'

// these are `GovukFrontendTag`s with spefic values
type ReferralTaskListStatusTag =
| { classes: 'govuk-tag moj-task-list__task-completed'; text: 'completed' }
| { classes: 'govuk-tag govuk-tag--grey moj-task-list__task-completed'; text: 'not started' }
| { classes: 'govuk-tag govuk-tag--grey moj-task-list__task-completed'; text: 'cannot start yet' }

type ReferralTaskListItem = {
statusTag: ReferralTaskListStatusTag
text: string
url?: string
}

type ReferralTaskListSection = {
heading: string
items: Array<ReferralTaskListItem>
}

export type {
CoursePresenter,
GovukFrontendSummaryListRowWithValue,
Expand All @@ -35,5 +54,8 @@ export type {
OrganisationWithOfferingEmailsPresenter,
OrganisationWithOfferingEmailsSummaryListRows,
OrganisationWithOfferingId,
ReferralTaskListSection,
ReferralTaskListStatusTag,
ReferralTaskListStatusText,
TagColour,
}
6 changes: 5 additions & 1 deletion server/controllers/refer/referralsController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
personFactory,
referralFactory,
} from '../../testutils/factories'
import { CourseUtils, TypeUtils } from '../../utils'
import { CourseUtils, ReferralUtils, TypeUtils } from '../../utils'
import type { CoursePresenter } from '@accredited-programmes/ui'

jest.mock('../../utils/courseUtils')
Expand Down Expand Up @@ -127,6 +127,9 @@ describe('ReferralsController', () => {
const person = personFactory.build()
personService.getPerson.mockResolvedValue(person)

const referral = referralFactory.build({ offeringId: courseOffering.id, prisonNumber: person.prisonNumber })
referralService.getReferral.mockResolvedValue(referral)

const requestHandler = referralsController.show()
await requestHandler(request, response, next)

Expand All @@ -138,6 +141,7 @@ describe('ReferralsController', () => {
organisation,
pageHeading: 'Make a referral',
person,
taskListSections: ReferralUtils.taskListSections(referral),
})
})
})
Expand Down
3 changes: 2 additions & 1 deletion server/controllers/refer/referralsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import createError from 'http-errors'

import { referPaths } from '../../paths'
import type { CourseService, OrganisationService, PersonService, ReferralService } from '../../services'
import { CourseUtils, TypeUtils } from '../../utils'
import { CourseUtils, ReferralUtils, TypeUtils } from '../../utils'
import type { CreatedReferralResponse } from '@accredited-programmes/models'

export default class ReferralsController {
Expand Down Expand Up @@ -69,6 +69,7 @@ export default class ReferralsController {
organisation,
pageHeading: 'Make a referral',
person,
taskListSections: ReferralUtils.taskListSections(referral),
})
}
}
Expand Down
13 changes: 12 additions & 1 deletion server/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,19 @@ import DateUtils from './dateUtils'
import nunjucksSetup from './nunjucksSetup'
import OrganisationUtils from './organisationUtils'
import PersonUtils from './personUtils'
import ReferralUtils from './referralUtils'
import RouteUtils from './routeUtils'
import StringUtils from './stringUtils'
import TypeUtils from './typeUtils'

export { CourseUtils, DateUtils, OrganisationUtils, PersonUtils, RouteUtils, StringUtils, TypeUtils, nunjucksSetup }
export {
CourseUtils,
DateUtils,
OrganisationUtils,
PersonUtils,
ReferralUtils,
RouteUtils,
StringUtils,
TypeUtils,
nunjucksSetup,
}
55 changes: 55 additions & 0 deletions server/utils/referralUtils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import ReferralUtils from './referralUtils'
import { referralFactory } from '../testutils/factories'

describe('ReferralUtils', () => {
describe('taskListSections', () => {
it('returns task list sections for a given referral', () => {
const referral = referralFactory.build()

expect(ReferralUtils.taskListSections(referral)).toEqual([
{
heading: 'Personal details',
items: [
{
statusTag: { classes: 'govuk-tag moj-task-list__task-completed', text: 'completed' },
text: 'Confirm personal details',
},
],
},
{
heading: 'Referral information',
items: [
{
statusTag: { classes: 'govuk-tag govuk-tag--grey moj-task-list__task-completed', text: 'not started' },
text: 'Add Accredited Programme history',
url: '#',
},
{
statusTag: { classes: 'govuk-tag govuk-tag--grey moj-task-list__task-completed', text: 'not started' },
text: 'Confirm the OASys information',
url: '#',
},
{
statusTag: { classes: 'govuk-tag govuk-tag--grey moj-task-list__task-completed', text: 'not started' },
text: 'Add reason for referral and any additional information',
url: '#',
},
],
},
{
heading: 'Check answers and submit',
items: [
{
statusTag: {
classes: 'govuk-tag govuk-tag--grey moj-task-list__task-completed',
text: 'cannot start yet',
},
text: 'Check answers and submit',
url: '#',
},
],
},
])
})
})
})
49 changes: 49 additions & 0 deletions server/utils/referralUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import type { Referral } from '@accredited-programmes/models'
import type {
ReferralTaskListSection,
ReferralTaskListStatusTag,
ReferralTaskListStatusText,
} from '@accredited-programmes/ui'

export default class ReferralUtils {
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
static taskListSections(referral: Referral): Array<ReferralTaskListSection> {
return [
{
heading: 'Personal details',
items: [{ statusTag: ReferralUtils.taskListStatus('completed'), text: 'Confirm personal details' }],
},
{
heading: 'Referral information',
items: [
{
statusTag: ReferralUtils.taskListStatus('not started'),
text: 'Add Accredited Programme history',
url: '#',
},
{ statusTag: ReferralUtils.taskListStatus('not started'), text: 'Confirm the OASys information', url: '#' },
{
statusTag: ReferralUtils.taskListStatus('not started'),
text: 'Add reason for referral and any additional information',
url: '#',
},
],
},
{
heading: 'Check answers and submit',
items: [
{ statusTag: ReferralUtils.taskListStatus('cannot start yet'), text: 'Check answers and submit', url: '#' },
],
},
]
}

private static taskListStatus(text: ReferralTaskListStatusText): ReferralTaskListStatusTag {
const classes =
text === 'completed'
? 'govuk-tag moj-task-list__task-completed'
: 'govuk-tag govuk-tag--grey moj-task-list__task-completed'

return { classes, text } as ReferralTaskListStatusTag
}
}
19 changes: 19 additions & 0 deletions server/views/referrals/_taskListSection.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{% from "govuk/components/tag/macro.njk" import govukTag %}

{% macro taskListSection(section) %}
<li>
<h2 class="moj-task-list__section">{{ section.heading }}</h2>
<ul class="moj-task-list__items">
{% for item in section.items %}
<li class="moj-task-list__item">
{% if item.url %}
<a class="moj-task-list__task-name" href="{{ item.url }}">{{ item.text }}</a>
{% else %}
<span class="moj-task-list__task-name">{{ item.text }}</span>
{% endif %}
{{ govukTag(item.statusTag) }}
</li>
{% endfor %}
</ul>
</li>
{% endmacro %}
7 changes: 7 additions & 0 deletions server/views/referrals/show.njk
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{% from "govuk/components/back-link/macro.njk" import govukBackLink %}

{% from "./_taskListSection.njk" import taskListSection %}
{% from "../partials/audienceTags.njk" import audienceTags %}

{% extends "../partials/layout.njk" %}
Expand All @@ -23,6 +24,12 @@
{% include "../partials/organisationAndCourse.njk" %}

{{ audienceTags(course.audienceTags) }}

<ol class="moj-task-list">
{% for section in taskListSections %}
{{ taskListSection(section) }}
{% endfor %}
</ol>
</div>
</div>
{% endblock content %}

0 comments on commit 2550d7a

Please sign in to comment.