-
Notifications
You must be signed in to change notification settings - Fork 1
Implement the task list-supported template #453
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
base: rc-tasklist
Are you sure you want to change the base?
Changes from all commits
4ce20b8
b9d8cbe
646607a
51316e0
5e6daca
8e5f032
63da116
a9d8966
f3a6c7d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,13 +5,15 @@ | |
| const Ajv = require('ajv'); | ||
| const AjvErrors = require('ajv-errors'); | ||
| const VError = require('verror'); | ||
| const createQRouter = require('q-router'); | ||
| const router = require('q-router'); | ||
| const uuidv4 = require('uuid/v4'); | ||
| const ajvFormatsMobileUk = require('ajv-formats-mobile-uk'); | ||
| const templates = require('./templates'); | ||
| const questionnaireResource = require('./resources/questionnaire-resource'); | ||
| const createQuestionnaireHelper = require('./questionnaire/questionnaire'); | ||
| const isQuestionnaireCompatible = require('./utils/isQuestionnaireVersionCompatible'); | ||
| const createTaskListService = require('./task-list/task-list-service'); | ||
| const getProgress = require('./utils/getProgressArray'); | ||
|
|
||
| const defaults = {}; | ||
| defaults.createQuestionnaireDAL = require('./questionnaire-dal'); | ||
|
|
@@ -51,6 +53,13 @@ function createQuestionnaireService({ | |
| await db.updateExpiryForAuthenticatedOwner(questionnaireId, owner); | ||
| } | ||
|
|
||
| function supportsTaskList(questionnaireDefinition) { | ||
| if (questionnaireDefinition.routes.type === 'parallel') { | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| async function createQuestionnaire(templateName, ownerData, originData, externalData) { | ||
| if (!(templateName in templates)) { | ||
| throw new VError( | ||
|
|
@@ -99,7 +108,7 @@ function createQuestionnaireService({ | |
| } | ||
|
|
||
| return { | ||
| data: questionnaireResource({questionnaire}) | ||
| data: questionnaireResource({questionnaire}, supportsTaskList(questionnaire)) | ||
| }; | ||
| } | ||
|
|
||
|
|
@@ -184,7 +193,8 @@ function createQuestionnaireService({ | |
|
|
||
| async function getAnswers(questionnaireId) { | ||
| const questionnaire = await getQuestionnaire(questionnaireId); | ||
| const resourceCollection = questionnaire.progress.reduce((acc, sectionAnswersId) => { | ||
| const progress = getProgress(questionnaire); | ||
| const resourceCollection = progress.reduce((acc, sectionAnswersId) => { | ||
| // Does this section have answers | ||
| if (questionnaire.answers[sectionAnswersId]) { | ||
| acc.push(buildAnswerResource(sectionAnswersId, questionnaire)); | ||
|
|
@@ -206,7 +216,7 @@ function createQuestionnaireService({ | |
| const questionnaireDefinition = await getQuestionnaire(questionnaireId); | ||
|
|
||
| // 2 - is the section allowed to be posted to e.g. is it in their progress | ||
| const qRouter = createQRouter(questionnaireDefinition); | ||
| const qRouter = router(questionnaireDefinition); | ||
| const sectionDetails = getSection(sectionId, qRouter); | ||
|
|
||
| // 3 - Section is available. Validate the answers against it | ||
|
|
@@ -238,7 +248,6 @@ function createQuestionnaireService({ | |
| // 4 - If we're here all is good | ||
| // Pass the answers to the router which will update the context (questionnaire) with these answers. | ||
| let answeredQuestionnaire; | ||
|
|
||
| if (sectionDetails.id === 'owner') { | ||
| const currentSection = qRouter.current(); | ||
| currentSection.context.answers[sectionDetails.id] = coercedAnswers; | ||
|
|
@@ -341,9 +350,35 @@ function createQuestionnaireService({ | |
| }; | ||
| } | ||
|
|
||
| function getSectionRouteBySectionId(questionnaireDefinition, sectionId) { | ||
| const questionnaire = createQuestionnaireHelper({questionnaireDefinition}); | ||
| const taskListService = createTaskListService({questionnaireDefinition}); | ||
|
|
||
| const section = questionnaire.getSection(sectionId); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rather than using |
||
| if (taskListService.isTaskListSchema({sectionSchema: section.getSchema()})) { | ||
| return {}; | ||
| } | ||
|
|
||
| const {states} = questionnaireDefinition.routes; | ||
|
|
||
| if (supportsTaskList(questionnaireDefinition)) { | ||
| const tasks = states; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this necessary? |
||
| const taskIds = Object.keys(tasks); | ||
| for (let i = 0; i < taskIds.length; i += 1) { | ||
| if (sectionId in tasks[taskIds[i]].states) { | ||
| return tasks[taskIds[i]].states[sectionId]; | ||
| } | ||
| } | ||
| } else if (sectionId in states) { | ||
| return states[sectionId]; | ||
| } | ||
|
|
||
| throw new VError(`Section "${sectionId}" not found`); | ||
| } | ||
|
|
||
| async function buildMetaBlock(questionnaire, sectionId) { | ||
| // TODO: move this meta on to the appropriate section resource | ||
| const sectionType = questionnaire.routes.states[sectionId].type; | ||
| const sectionType = getSectionRouteBySectionId(questionnaire, sectionId).type; | ||
| const isFinalType = sectionType && sectionType === 'final'; | ||
| return { | ||
| summary: questionnaire.routes.summary, | ||
|
|
@@ -404,7 +439,8 @@ function createQuestionnaireService({ | |
| }; | ||
| } | ||
| // 2 - get router | ||
| const qRouter = createQRouter(questionnaire); | ||
| const qRouter = router(questionnaire); | ||
|
|
||
| // 3 - filter or paginate progress entries if required | ||
| // Currently this only supports queries that return a single progress entry | ||
| if (query) { | ||
|
|
@@ -451,6 +487,7 @@ function createQuestionnaireService({ | |
|
|
||
| // Is the progress entry available | ||
| if (section) { | ||
| const taskListService = createTaskListService(); | ||
| if (isQuestionnaireModified) { | ||
| // Store the updated questionnaire object | ||
| await db.updateQuestionnaireByOwner(questionnaireId, section.context); | ||
|
|
@@ -459,12 +496,20 @@ function createQuestionnaireService({ | |
| sectionId = section.id; | ||
|
|
||
| // Create the progress entry compound document | ||
| const previousProgressEntryLink = | ||
| section.id === section.context.routes.initial | ||
| ? questionnaire.routes.referrer | ||
| : `${process.env.DCS_URL}/api/questionnaires/${ | ||
| questionnaire.id | ||
| }/progress-entries?filter[sectionId]=${qRouter.previous(sectionId).id}`; | ||
| let previousProgressEntryLink; | ||
| if ( | ||
| section.id === section.context.routes.initial || | ||
| section.id === section.context.currentSectionId // task list | ||
| ) { | ||
| previousProgressEntryLink = questionnaire.routes.referrer; | ||
| // TODO: pass in the sectionSchema, not the sectionId. | ||
| } else if (taskListService.isTaskListSchema({sectionId: section.id})) { | ||
| previousProgressEntryLink = undefined; | ||
| } else { | ||
| previousProgressEntryLink = `${process.env.DCS_URL}/api/questionnaires/${ | ||
| questionnaire.id | ||
| }/progress-entries?filter[sectionId]=${qRouter.previous(sectionId).id}`; | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fine for now, but we should chuck a |
||
|
|
||
| compoundDocument.data = [buildProgressEntryResource(sectionId)]; | ||
| // Include related resources | ||
|
|
@@ -528,8 +573,9 @@ function createQuestionnaireService({ | |
|
|
||
| async function getAnswersBySectionId(questionnaireId, sectionId) { | ||
| const questionnaire = await getQuestionnaire(questionnaireId); | ||
| const progress = getProgress(questionnaire); | ||
|
|
||
| if (questionnaire.progress.includes(sectionId)) { | ||
| if (progress.includes(sectionId)) { | ||
| return { | ||
| data: buildAnswerResource(sectionId, questionnaire) | ||
| }; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not necessary, the module is still called q-router!