Skip to content

Commit

Permalink
Add "done" page to interview
Browse files Browse the repository at this point in the history
  • Loading branch information
jochenklar committed Aug 25, 2024
1 parent dcc0242 commit 58764e3
Show file tree
Hide file tree
Showing 17 changed files with 137 additions and 64 deletions.
1 change: 1 addition & 0 deletions rdmo/core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@
'projects/project_interview_add_field_help.html',
'projects/project_interview_add_set_help.html',
'projects/project_interview_buttons_help.html',
'projects/project_interview_done.html',
'projects/project_interview_multiple_values_warning.html',
'projects/project_interview_navigation_help.html',
'projects/project_interview_overview_help.html',
Expand Down
34 changes: 21 additions & 13 deletions rdmo/projects/assets/js/interview/actions/interviewActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,29 @@ import {
import { updateConfig } from 'rdmo/core/assets/js/actions/configActions'

export function fetchPage(pageId) {
return (dispatch) => {
const promise = isNil(pageId) ? PageApi.fetchContinue(projectId)
: PageApi.fetchPage(projectId, pageId)
return promise.then((page) => {
updateLocation(page.id)
initPage(page)
dispatch(fetchNavigation(page))
dispatch(fetchValues(page))
dispatch(fetchPageSuccess(page))
})
if (pageId === 'done') {
return (dispatch) => {
updateLocation('done')
dispatch(fetchNavigation(null))
dispatch(fetchPageSuccess(null, true))
}
} else {
return (dispatch) => {
const promise = isNil(pageId) ? PageApi.fetchContinue(projectId)
: PageApi.fetchPage(projectId, pageId)
return promise.then((page) => {
updateLocation(page.id)
initPage(page)
dispatch(fetchNavigation(page))
dispatch(fetchValues(page))
dispatch(fetchPageSuccess(page, false))
})
}
}
}

export function fetchPageSuccess(page) {
return {type: FETCH_PAGE_SUCCESS, page}
export function fetchPageSuccess(page, done) {
return {type: FETCH_PAGE_SUCCESS, page, done}
}

export function fetchPageError(errors) {
Expand All @@ -58,7 +66,7 @@ export function fetchPageError(errors) {

export function fetchNavigation(page) {
return (dispatch) => {
return ProjectApi.fetchNavigation(projectId, page.section.id)
return ProjectApi.fetchNavigation(projectId, page && page.section.id)
.then((navigation) => dispatch(fetchNavigationSuccess(navigation)))
.catch((errors) => dispatch(fetchNavigationError(errors)))

Expand Down
8 changes: 7 additions & 1 deletion rdmo/projects/assets/js/interview/api/ProjectApi.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { isNil } from 'lodash'

import BaseApi from 'rdmo/core/assets/js/api/BaseApi'

class ProjectsApi extends BaseApi {
Expand All @@ -7,7 +9,11 @@ class ProjectsApi extends BaseApi {
}

static fetchNavigation(projectId, page_id) {
return this.get(`/api/v1/projects/projects/${projectId}/navigation/${page_id}`)
if (isNil(page_id)) {
return this.get(`/api/v1/projects/projects/${projectId}/navigation/`)
} else {
return this.get(`/api/v1/projects/projects/${projectId}/navigation/${page_id}`)
}
}

static fetchProgress(projectId) {
Expand Down
16 changes: 10 additions & 6 deletions rdmo/projects/assets/js/interview/components/main/Breadcrump.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,22 @@ const Breadcrump = ({ overview, page, fetchPage }) => {
{overview.title}
</a>
</li>
<li>
<a href={`${baseUrl}/projects/${overview.id}/interview/${page.section.first}/`} onClick={handleClick}>
{page.section.title}
</a>
</li>
{
page && (
<li>
<a href={`${baseUrl}/projects/${overview.id}/interview/${page.section.first}/`} onClick={handleClick}>
{page.section.title}
</a>
</li>
)
}
</ul>
)
}

Breadcrump.propTypes = {
overview: PropTypes.object.isRequired,
page: PropTypes.object.isRequired,
page: PropTypes.object,
fetchPage: PropTypes.func.isRequired
}

Expand Down
33 changes: 33 additions & 0 deletions rdmo/projects/assets/js/interview/components/main/Done.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react'
import PropTypes from 'prop-types'

import baseUrl from 'rdmo/core/assets/js/utils/baseUrl'

import Template from 'rdmo/core/assets/js/components/Template'

const Done = ({ templates, overview }) => {

const projectUrl = `${baseUrl}/projects/${overview.id}/`
const answersUrl = `${baseUrl}/projects/${overview.id}/answers/`

return (
<>
<Template template={templates.project_interview_done} />

<p>
<a href={answersUrl}>{gettext('View answers')}</a>
</p>

<p>
<a href={projectUrl}>{gettext('Back to project overview')}</a>
</p>
</>
)
}

Done.propTypes = {
templates: PropTypes.object.isRequired,
overview: PropTypes.object.isRequired
}

export default Done
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import PageButtons from './PageButtons'
import PageHead from './PageHead'
import PageHelp from './PageHelp'

const Page = ({ config, templates, project, page, sets, values, fetchPage,
const Page = ({ config, templates, overview, page, sets, values, fetchPage,
createValue, updateValue, deleteValue,
activateSet, createSet, updateSet, deleteSet }) => {

Expand Down Expand Up @@ -50,7 +50,7 @@ const Page = ({ config, templates, project, page, sets, values, fetchPage,
questionset={element}
sets={sets}
values={values.filter((value) => element.attributes.includes(value.attribute))}
disabled={project.overview.read_only}
disabled={overview.read_only}
focus={elementIndex == 0}
parentSet={currentSet}
createSet={createSet}
Expand All @@ -72,7 +72,7 @@ const Page = ({ config, templates, project, page, sets, values, fetchPage,
value.set_prefix == currentSetPrefix &&
value.set_index == currentSetIndex
))}
disabled={project.overview.read_only}
disabled={overview.read_only}
focus={elementIndex == 0}
currentSet={currentSet}
createValue={createValue}
Expand All @@ -94,7 +94,7 @@ const Page = ({ config, templates, project, page, sets, values, fetchPage,
Page.propTypes = {
config: PropTypes.object.isRequired,
templates: PropTypes.object.isRequired,
project: PropTypes.object.isRequired,
overview: PropTypes.object.isRequired,
page: PropTypes.object.isRequired,
sets: PropTypes.array.isRequired,
values: PropTypes.array.isRequired,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const PageButtons = ({ page, fetchPage }) => {
{gettext('Proceed')}
</button>
) : (
<button type="button" onClick={() => {}}
<button type="button" onClick={() => fetchPage('done')}
className="btn btn-primary">
{gettext('Complete questionnaire')}
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ const Navigation = ({ currentPage, navigation, help, fetchPage }) => {
const label = interpolate(gettext('(%s of %s)'), [page.count, page.total])

return (
<li key={pageIndex} className={classNames({'active': page.id == currentPage.id})}>
<li key={pageIndex} className={classNames({'active': currentPage ? page.id == currentPage.id : false})}>
{
page.show ? (
<a href={`/projects/12/interview/${currentPage.id}/`} onClick={event => handleClick(event, page.id)}>
<a href={`/projects/12/interview/${page.id}/`} onClick={event => handleClick(event, page.id)}>
<span>{page.title}</span>
{
page.count > 0 && page.count == page.total && (
Expand Down Expand Up @@ -71,7 +71,7 @@ const Navigation = ({ currentPage, navigation, help, fetchPage }) => {
}

Navigation.propTypes = {
currentPage: PropTypes.object.isRequired,
currentPage: PropTypes.object,
navigation: PropTypes.array.isRequired,
help: PropTypes.string.isRequired,
fetchPage: PropTypes.func.isRequired
Expand Down
42 changes: 26 additions & 16 deletions rdmo/projects/assets/js/interview/containers/Main.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { connect } from 'react-redux'
import { isReady } from '../utils/interview'

import Breadcrump from '../components/main/Breadcrump'
import Done from '../components/main/Done'
import Page from '../components/main/page/Page'

import * as configActions from 'rdmo/core/assets/js/actions/configActions'
Expand All @@ -22,22 +23,31 @@ const Main = ({ config, settings, templates, user, project, interview, configAct
page={interview.page}
fetchPage={interviewActions.fetchPage}
/>
<Page
config={config}
templates={templates}
project={project}
page={interview.page}
sets={interview.sets}
values={interview.values}
fetchPage={interviewActions.fetchPage}
createValue={interviewActions.createValue}
updateValue={interviewActions.updateValue}
deleteValue={interviewActions.deleteValue}
activateSet={interviewActions.activateSet}
createSet={interviewActions.createSet}
updateSet={interviewActions.updateSet}
deleteSet={interviewActions.deleteSet}
/>
{
interview.done && (
<Done templates={templates} overview={project.overview} />
)
}
{
interview.page && (
<Page
config={config}
templates={templates}
overview={project.overview}
page={interview.page}
sets={interview.sets}
values={interview.values}
fetchPage={interviewActions.fetchPage}
createValue={interviewActions.createValue}
updateValue={interviewActions.updateValue}
deleteValue={interviewActions.deleteValue}
activateSet={interviewActions.activateSet}
createSet={interviewActions.createSet}
updateSet={interviewActions.updateSet}
deleteSet={interviewActions.deleteSet}
/>
)
}
</div>
)
}
Expand Down
4 changes: 2 additions & 2 deletions rdmo/projects/assets/js/interview/containers/Sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ const Sidebar = ({ config, settings, templates, user, project, interview, config
progress={project.progress}
help={templates.project_interview_progress_help} />
<Buttons
prev={interview.page.prev_page}
next={interview.page.next_page}
prev={interview.page && interview.page.prev_page}
next={interview.page && interview.page.next_page}
help={templates.project_interview_buttons_help}
fetchPage={interviewActions.fetchPage} />
<Navigation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
} from '../actions/actionTypes'

const initialState = {
done: null,
page: null,
navigation: null,
values: null,
Expand All @@ -27,7 +28,7 @@ const initialState = {
export default function interviewReducer(state = initialState, action) {
switch(action.type) {
case FETCH_PAGE_SUCCESS:
return { ...state, page: action.page, attributes: action.attributes }
return { ...state, page: action.page, done: action.done }
case FETCH_NAVIGATION_SUCCESS:
return { ...state, navigation: action.navigation }
case FETCH_VALUES_SUCCESS:
Expand Down
5 changes: 4 additions & 1 deletion rdmo/projects/assets/js/interview/utils/interview.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { isNil } from 'lodash'

const isReady = (interview) => {
return !(isNil(interview.page) || isNil(interview.navigation) || isNil(interview.values))
return (
(interview.done && !isNil(interview.navigation)) ||
(interview.page && !isNil(interview.navigation) && !isNil(interview.values))
)
}

export { isReady }
5 changes: 5 additions & 0 deletions rdmo/projects/assets/js/interview/utils/location.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ const parseLocation = () => {
return m1.groups
}

const m2 = pathname.match(/\/interview\/(?<pageId>(done))[/]*$/)
if (m2) {
return m2.groups
}

return {}
}

Expand Down
2 changes: 1 addition & 1 deletion rdmo/projects/progress.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def compute_navigation(section, project, snapshot=None):
'count': 0,
'total': 0
}
if catalog_section.id == section.id:
if section is not None and catalog_section.id == section.id:
navigation_section['pages'] = []

for page in catalog_section.elements:
Expand Down
10 changes: 10 additions & 0 deletions rdmo/projects/templates/projects/project_interview_done.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{% load i18n %}
{% load core_tags %}

<h2>
{% trans 'Done!' %}
</h2>

<p>
{% trans 'Thank you for filling out the questionnaire.' %}
</p>
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
{% load i18n %}

{% if settings.PROJECT_QUESTIONS_AUTOSAVE %}
<p class="help-block">
{% trans 'Using the navigation will save your input.' %}
</p>
{% else %}
<p class="help-block">
{% trans 'Please note that using the navigation will discard any unsaved input.' %}
</p>
{% endif %}

<p class="help-block">
{% blocktrans trimmed %}
Grey entries will be conditionally skipped based on your input.
Expand Down
12 changes: 7 additions & 5 deletions rdmo/projects/viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,17 @@ def overview(self, request, pk=None):
serializer = ProjectOverviewSerializer(project, context={'request': request})
return Response(serializer.data)

@action(detail=True, url_path=r'navigation/(?P<section_id>\d+)',
@action(detail=True, url_path=r'navigation(/(?P<section_id>\d+))?',
permission_classes=(HasModelPermission | HasProjectPermission, ))
def navigation(self, request, pk=None, section_id=None):
project = self.get_object()

try:
section = project.catalog.sections.get(pk=section_id)
except ObjectDoesNotExist as e:
raise NotFound() from e
section = None
if section_id is not None:
try:
section = project.catalog.sections.get(pk=section_id)
except ObjectDoesNotExist as e:
raise NotFound() from e

project.catalog.prefetch_elements()

Expand Down

0 comments on commit 58764e3

Please sign in to comment.