UNPKG

@modernpoacher/zashiki-govuk-frontend

Version:
452 lines (377 loc) 10.5 kB
import debug from 'debug' import toZashiki from 'shinkansen-transmission/transmission/to-zashiki' import fromDocumentToHash from 'shinkansen-transmission/transmission/from-document-to-hash' import getResourceUrl from './common/get-resource-url.mjs' import { hasEnum, getEnum, hasOneOf, getOneOf, hasAnyOf, getAnyOf, getField, hasField, hasTitle, getTitle, hasValue, getValue, hasText, getText, hasHtml, getHtml, hasElementsTitle } from './common/index.mjs' const log = debug('zashiki/transformer/to-check-answers') log('`zashiki` is awake') export const toSummaryValue = ({ elements } = {}) => { const { title: value = getValue(elements) } = elements return value } export const transformFieldValue = (field = {}) => ( hasValue(field) ? { text: getValue(field) } : {} ) export const transformSummaryKey = ({ elements } = {}) => ( hasTitle(elements) ? { text: getTitle(elements) } : {} ) export const getVisuallyHiddenText = ({ elements: { title: visuallyHiddenText = '' } = {} } = {}) => visuallyHiddenText.toLowerCase() export function getEnumSelectedItemsValue (items = [], selectedItems = []) { log('getEnumSelectedItemsValue') return ( selectedItems.reduce((accumulator, selectedItem) => ( (selectedItem in items) ? accumulator.concat(`<p class="govuk-body">${items[selectedItem]}</p>`) : accumulator ), '') // || 'Not answered' ) } export function getEnumSelectedItemValue (items = [], [selectedItem] = []) { log('getEnumSelectedItemValue') return ( selectedItem in items ? String(items[selectedItem]) : '' // 'Not answered' ) } export function getAnyOfSelectedItemsValue (items = [], selectedItems = []) { log('getAnyOfSelectedItemsValue') return ( selectedItems.reduce((accumulator, selectedItem) => ( (selectedItem in items) ? accumulator.concat(`<p class="govuk-body">${toSummaryValue(items[selectedItem])}</p>`) : accumulator ), '') // || 'Not answered' ) } export function getAnyOfSelectedItemValue (items = [], [selectedItem] = []) { log('getAnyOfSelectedItemValue') return (selectedItem in items) ? toSummaryValue(items[selectedItem]) // || 'Not answered' : '' // 'Not answered' } export function getOneOfSelectedItemsValue (items = [], selectedItems = []) { log('getOneOfSelectedItemsValue') return ( selectedItems.reduce((accumulator, selectedItem) => ( (selectedItem in items) ? accumulator.concat(`<p class="govuk-body">${toSummaryValue(items[selectedItem])}</p>`) : accumulator ), '') // || 'Not answered' ) } export function getOneOfSelectedItemValue (items = [], [selectedItem] = []) { log('getOneOfSelectedItemValue') return (selectedItem in items) ? toSummaryValue(items[selectedItem]) // || 'Not answered' : '' // 'Not answered' } export function getGroup (index, array) { const group = [] let n = index + 1 let sibling = array[n] if (sibling) { while (!hasElementsTitle(sibling)) { group.push(sibling) n = n + 1 sibling = array[n] if (!sibling) break } } return group } export function transformEnumValue ({ items, selectedItems } = {}) { log('transformEnumValue') if (selectedItems.length < 1) { return {} } else { if (selectedItems.length > 1) { return { html: getEnumSelectedItemsValue(items, selectedItems) } } } return { text: getEnumSelectedItemValue(items, selectedItems) } } export function transformAnyOfValue ({ items, selectedItems } = {}) { log('transformAnyOfValue') if (selectedItems.length < 1) { return {} } else { if (selectedItems.length > 1) { return { html: getAnyOfSelectedItemsValue(items, selectedItems) } } } return { text: getAnyOfSelectedItemValue(items, selectedItems) } } export function transformOneOfValue ({ items, selectedItems } = {}) { log('transformOneOfValue') if (selectedItems.length < 1) { return {} } else { if (selectedItems.length > 1) { return { html: getOneOfSelectedItemsValue(items, selectedItems) } } } return { text: getOneOfSelectedItemValue(items, selectedItems) } } export function transformSummaryValue ({ elements }) { log('transformSummaryValue') if (hasEnum(elements)) { const field = getEnum(elements) return transformEnumValue(field) } else { if (hasAnyOf(elements)) { const field = getAnyOf(elements) return transformAnyOfValue(field) } else { if (hasOneOf(elements)) { const field = getOneOf(elements) return transformOneOfValue(field) } else { if (hasField(elements)) { const field = getField(elements) return transformFieldValue(field) } } } } return {} } export function transformString (zashiki, resource) { log('transformString') return { key: transformSummaryKey(zashiki), value: transformSummaryValue(zashiki), actions: { items: [ { href: getResourceUrl(resource), text: 'Change', visuallyHiddenText: getVisuallyHiddenText(zashiki) } ] } } } export function transformNumber (zashiki, resource) { log('transformNumber') return { key: transformSummaryKey(zashiki), value: transformSummaryValue(zashiki), actions: { items: [ { href: getResourceUrl(resource), text: 'Change', visuallyHiddenText: getVisuallyHiddenText(zashiki) } ] } } } export function transformObject ({ elements: { fields = [] } = {} } = {}, resource = {}, array = [], group = []) { log('transformObject') return fields.reduce((accumulator, field, i, a) => { if (hasElementsTitle(field)) { /* * `field` has a title. Put any title-less siblings into `group` */ group = getGroup(i, a) if (group.length) { /* * Transform `field` and siblings */ return accumulator.concat(transformObjectGroup([field, ...group], resource)) } } return ( group.includes(field) ? accumulator : accumulator.concat(transform(field, resource, array, group)) ) }, array) } export function transformArray ({ elements: { fields = [] } = {} } = {}, resource = {}, array = [], group = []) { log('transformArray') return fields.reduce((accumulator, field, i, a) => { if (hasElementsTitle(field)) { /* * `field` has a title. Put any title-less siblings into `group` */ group = getGroup(i, a) if (group.length) { /* * Transform `field` and siblings */ return accumulator.concat(transformArrayGroup([field, ...group], resource)) } } return ( group.includes(field) ? accumulator : accumulator.concat(transform(field, resource, array, group)) ) }, array) } export function transformBoolean (zashiki, resource) { log('transformBoolean') return { key: transformSummaryKey(zashiki), value: transformSummaryValue(zashiki), actions: { items: [ { href: getResourceUrl(resource), text: 'Change', visuallyHiddenText: getVisuallyHiddenText(zashiki) } ] } } } export function transformNull (zashiki, resource) { log('transformNull') return { key: transformSummaryKey(zashiki), value: transformSummaryValue(zashiki), actions: { items: [ { href: getResourceUrl(resource), text: 'Change', visuallyHiddenText: getVisuallyHiddenText(zashiki) } ] } } } export function transformObjectGroupSummaryValue (group = []) { log('transformObjectGroupSummaryValue') return { html: group.reduce((accumulator, field) => { const value = transformSummaryValue(field) if (hasText(value)) { return accumulator.concat(getText(value)) } else { if (hasHtml(value)) { return accumulator.concat(getHtml(value)) } } return accumulator }, []).join('<br>') } } export function transformArrayGroupSummaryValue (group = []) { log('transformArrayGroupSummaryValue') return { html: group.reduce((accumulator, field) => { const value = transformSummaryValue(field) if (hasText(value)) { return accumulator.concat(`<p class="govuk-body">${getText(value)}</p>`) } else { if (hasHtml(value)) { return accumulator.concat(`<p class="govuk-body">${getHtml(value)}</p>`) } } return accumulator }, []).join('\n') } } export function transformObjectGroup (group = [], resource = {}) { log('transformObjectGroup') const [ field ] = group return { key: transformSummaryKey(field), value: transformObjectGroupSummaryValue(group), actions: { items: [ { href: getResourceUrl(resource), text: 'Change', visuallyHiddenText: getVisuallyHiddenText(field) } ] } } } export function transformArrayGroup (group = [], resource = {}) { log('transformArrayGroup') const [ field ] = group return { key: transformSummaryKey(field), value: transformArrayGroupSummaryValue(group), actions: { items: [ { href: getResourceUrl(resource), text: 'Change', visuallyHiddenText: getVisuallyHiddenText(field) } ] } } } export function transform (zashiki = {}, resource = {}, array = [], group = []) { log('transform') const { meta: { type } = {} } = zashiki switch (type) { case 'string': return transformString(zashiki, resource) case 'number': return transformNumber(zashiki, resource) case 'object': return transformObject(zashiki, resource, array, group) case 'array': return transformArray(zashiki, resource, array, group) case 'boolean': return transformBoolean(zashiki, resource) case 'null': return transformNull(zashiki, resource) default: throw new Error('Zashiki incompatible with transformer') } } export default (definition, response, resource) => transform(toZashiki(definition, (response !== undefined) ? fromDocumentToHash(response, definition) : {}), resource)