Skip to content

Commit

Permalink
Merge pull request #5027 from davidwatkins73/waltz-5025-survey-env-co…
Browse files Browse the repository at this point in the history
…nditionals

Waltz 5025 survey env conditionals
  • Loading branch information
davidwatkins73 authored Aug 5, 2020
2 parents 71b4a43 + 3db0908 commit efe1bce
Show file tree
Hide file tree
Showing 17 changed files with 411 additions and 315 deletions.
8 changes: 8 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@
<spark.version>2.9.1</spark.version>
<spring.version>5.2.2.RELEASE</spring.version>
<super-csv.version>2.4.0</super-csv.version>
<commons-jexl3.version>3.1</commons-jexl3.version>

<timestamp>${maven.build.timestamp}</timestamp>
</properties>

Expand Down Expand Up @@ -212,6 +214,12 @@
<artifactId>javax.annotation-api</artifactId>
<version>${annotation-api.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-jexl3</artifactId>
<version>${commons-jexl3.version}</version>
</dependency>


<!-- db -->
<dependency>
Expand Down
25 changes: 6 additions & 19 deletions waltz-jobs/pom.xml
Original file line number Diff line number Diff line change
@@ -1,25 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Waltz - Enterprise Architecture
~ Copyright (C) 2016, 2017, 2018, 2019 Waltz open source project
~ See README.md for more information
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific
~
-->

<!--
~ Waltz - Enterprise Architecture
~ Copyright (C) 2016, 2017, 2018, 2019 Waltz open source project
~ Copyright (C) 2016, 2017, 2018, 2019, 2020 Waltz open source project
~ See README.md for more information
~
~ Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -89,6 +71,11 @@
<artifactId>jackson-dataformat-yaml</artifactId>
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-jexl3</artifactId>
</dependency>

</dependencies>

<build>
Expand Down
30 changes: 15 additions & 15 deletions waltz-ng/client/survey/survey-instance-response-edit.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,46 +18,45 @@

<div>
<waltz-page-header icon="wpforms"
name="{{ ctrl.surveyRun.name }}"
name="{{ ctrl.surveyDetails.run.name }}"
small="edit response">
<breadcrumbs>
<ol class="waltz-breadcrumbs">
<li>
<a ui-sref="main">Home</a>
</li>
<li>
<waltz-entity-link entity-ref="ctrl.surveyInstance.surveyEntity">
<waltz-entity-link entity-ref="ctrl.surveyDetails.instance.surveyEntity"
tooltip-placement="bottom">
</waltz-entity-link>
</li>
<li>
<a ui-sref="main.survey.instance.user">Surveys</a>
</li>
<li>
<span ng-bind="ctrl.surveyRun.name">
</span>
<span ng-bind="ctrl.surveyDetails.run.name">
</span>
</li>
</ol>
</breadcrumbs>
</waltz-page-header>

<div class="waltz-page-summary waltz-page-summary-attach">
<waltz-survey-instance-summary instance-id="ctrl.surveyInstance.id">
<waltz-survey-instance-summary instance-id="ctrl.surveyDetails.instance.id">
</waltz-survey-instance-summary>
</div>

<br>

<br>


<waltz-section name="Responses"
icon="pencil-square"
ng-if="ctrl.isUserInstanceRecipient && ctrl.instanceCanBeEdited">
ng-if="ctrl.surveyDetails.permissions.participant && ctrl.instanceCanBeEdited">
<form name="surveyResponseForm"
class="form-horizontal waltz-survey-form"
role="form"
novalidate>
<div ng-repeat="groupedQuestion in ctrl.surveyQuestionInfos track by groupedQuestion.sectionName"
<div ng-repeat="groupedQuestion in ctrl.groupedQuestions track by groupedQuestion.sectionName"
class="waltz-survey-question-section">

<h4 ng-bind="groupedQuestion.sectionName"
Expand Down Expand Up @@ -91,9 +90,10 @@
type="number"
ng-attr-id="{{ qi.question.id }}"
placeholder="Please enter a number"
ng-model-options="{ allowInvalid: true, debounce: 200 }"
ng-model="ctrl.surveyResponses[qi.question.id].numberResponse"
ng-required="qi.question.isMandatory"
ng-blur="ctrl.saveResponse(qi.question.id)"
ng-change="ctrl.saveResponse(qi.question.id)"
class="form-control"/>
<!-- boolean -->
<div ng-switch-when="BOOLEAN">
Expand Down Expand Up @@ -160,7 +160,7 @@
ng-attr-id="{{ qi.question.id }}"
ng-model="ctrl.surveyResponses[qi.question.id].stringResponse"
ng-required="qi.question.isMandatory"
ng-blur="ctrl.saveResponse(qi.question.id)"
ng-change="ctrl.saveResponse(qi.question.id)"
ng-options="entry.value as entry.value for entry in qi.dropdownEntries | orderBy:'position'"
class="form-control">
</select>
Expand Down Expand Up @@ -245,23 +245,23 @@
</waltz-section>

<div class="alert alert-warning"
ng-if="ctrl.surveyInstance.status === 'EXPIRED'">
ng-if="ctrl.surveyDetails.instance.status === 'EXPIRED'">
<h4>Survey Expired</h4>
<p>This survey response has been expired without being submitted.</p>
</div>

<div class="alert alert-warning"
ng-if="ctrl.surveyInstance.status === 'COMPLETED' || ctrl.surveyInstance.status === 'APPROVED'">
ng-if="ctrl.surveyDetails.instance.status === 'COMPLETED' || ctrl.surveyDetails.instance.status === 'APPROVED'">
<h4>Survey Completed</h4>
<p>
This survey response has been completed and is no longer can be edited. Please follow this
<a ui-sref="main.survey.instance.response.view ({ id: ctrl.surveyInstance.id })">link</a>
<a ui-sref="main.survey.instance.response.view ({ id: ctrl.surveyDetails.instance.id })">link</a>
to view the responses.
</p>
</div>

<div class="alert alert-warning"
ng-if="!ctrl.isUserInstanceRecipient">
ng-if="!ctrl.surveyDetails.permissions.participant">
<h4>Permission Denied</h4>
<p>You don't have permission to respond to this survey.</p>
</div>
Expand Down
88 changes: 43 additions & 45 deletions waltz-ng/client/survey/survey-instance-response-edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/

import {formats, initialiseData} from "../common/index";
import {groupQuestions, indexResponses, mkSurveyExpressionEvaluator, refreshQuestions} from "./survey-utils";
import * as SurveyUtils from "./survey-utils";
import _ from "lodash";
import {CORE_API} from "../common/services/core-api-utils";
import moment from "moment";
Expand All @@ -27,10 +27,8 @@ import template from "./survey-instance-response-edit.html";

const initialState = {
changeLogSection: dynamicSections.changeLogSection,
isUserInstanceRecipient: false,
instanceCanBeEdited: false,
surveyInstance: {},
surveyQuestionInfos: [],
groupedQuestions: [],
surveyResponses: {},
user: {}
};
Expand All @@ -40,8 +38,11 @@ Please ensure you have saved any comments you may have entered (by clicking 'Sav
Are you sure you want to submit your responses?`;



const statusesWhichSupportEditing = ["NOT_STARTED", "IN_PROGRESS", "REJECTED"];
const statusesWhichSupportEditing = [
"NOT_STARTED",
"IN_PROGRESS",
"REJECTED"
];


function controller($location,
Expand All @@ -62,51 +63,32 @@ function controller($location,
kind: "SURVEY_INSTANCE"
};

function loadAll() {
const recipientsPromise = serviceBroker
.loadViewData(CORE_API.SurveyInstanceStore.findRecipients, [id])
.then(r => r.data);

const instancePromise = serviceBroker
.loadViewData(CORE_API.SurveyInstanceStore.getById, [id])
.then(r => {
vm.surveyInstance = r.data;
vm.instanceCanBeEdited = _.includes(statusesWhichSupportEditing, vm.surveyInstance.status);
});

const runPromise = instancePromise
.then(() => serviceBroker
.loadViewData(CORE_API.SurveyRunStore.getById, [vm.surveyInstance.surveyRunId]))
.then(r => vm.surveyRun = r.data);

const questionPromise = serviceBroker
.loadViewData(CORE_API.SurveyQuestionStore.findForInstance, [id])
.then(r => vm.allQuestions = r.data);

function boot() {
const responsePromise = serviceBroker
.loadViewData(CORE_API.SurveyInstanceStore.findResponses, [id])
.then(r => vm.surveyResponses = indexResponses(r.data));
.then(r => vm.surveyResponses = SurveyUtils.indexResponses(r.data));

$q.all([questionPromise, responsePromise])
.then(() => vm.surveyQuestionInfos = refreshQuestions(vm.allQuestions, vm.surveyResponses));
SurveyUtils
.loadSurveyInfo($q, serviceBroker, userService, id, true)
.then(details => {
vm.surveyDetails = details;
vm.instanceCanBeEdited = _.includes(statusesWhichSupportEditing, details.instance.status);
});

$q.all([userService.whoami(), recipientsPromise])
.then(([user = {}, recipients = []]) => {
vm.user = user;
const [currentRecipients = [], otherRecipients = []] = _.partition(
recipients,
r => _.toLower(r.person.email) === _.toLower(user.userName));
reloadQuestions();
}

vm.isUserInstanceRecipient = currentRecipients.length > 0;
vm.otherRecipients = otherRecipients.map(r => r.person);
function reloadQuestions() {
const questionPromise = serviceBroker
.loadViewData(CORE_API.SurveyQuestionStore.findForInstance, [id], { force: true })
.then(r => {
vm.groupedQuestions = SurveyUtils.groupQuestions(r.data);
});
}

loadAll();

vm.saveResponse = (questionId) => {
const questionResponse = vm.surveyResponses[questionId];
vm.surveyQuestionInfos = refreshQuestions(vm.allQuestions, vm.surveyResponses);

const saveParams = Object.assign(
{questionId},
Expand All @@ -117,9 +99,12 @@ function controller($location,
: null
});

serviceBroker.execute(
CORE_API.SurveyInstanceStore.saveResponse,
[vm.surveyInstance.id, saveParams]);
serviceBroker
.execute(
CORE_API.SurveyInstanceStore.saveResponse,
[vm.surveyDetails.instance.id, saveParams])
.then(() => reloadQuestions());

};

vm.saveEntityResponse = (entity, questionId) => {
Expand All @@ -146,12 +131,18 @@ function controller($location,
const questionResponse = _.get(vm.surveyResponses, [question.id], {});
questionResponse.comment = valObj.newVal;

const saveParams = [
vm.surveyDetails.instance.id,
Object.assign({"questionId": question.id}, questionResponse)
];

return serviceBroker
.execute(
CORE_API.SurveyInstanceStore.saveResponse,
[vm.surveyInstance.id, Object.assign({"questionId": question.id}, questionResponse)]);
saveParams);
};


/**
* This is a bit of fakery as the questions are saved each time a response is updated.
* Therefore this method merely moves the user back to their instance list.
Expand All @@ -163,13 +154,16 @@ function controller($location,
}, 200); // allow blur events to fire
};


const doSubmit = () => {
serviceBroker
.execute(
CORE_API.SurveyInstanceStore.updateStatus,
[vm.surveyInstance.id, {newStatus: "COMPLETED"}])
[vm.surveyDetails.instance.id, {newStatus: "COMPLETED"}])
.then(() => {
notification.success("Survey response submitted successfully");
// we force a reload of the notification store to update any listeners that the number
// of open surveys may have changed (i.e. the counter in the profile menu)
serviceBroker.loadAppData(
CORE_API.NotificationStore.findAll,
[],
Expand All @@ -186,6 +180,10 @@ function controller($location,
}, 200); // allow blur events to fire, because 'confirm' blocks events
};


// --- BOOT
boot();

}

controller.$inject = [
Expand Down
2 changes: 1 addition & 1 deletion waltz-ng/client/survey/survey-instance-response-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function controller($q,
$q.all([questionPromise, responsePromise])
.then(([allQuestions, surveyResponses]) => {
vm.answersById = SurveyUtils.indexResponses(surveyResponses);
vm.groupedQuestions = SurveyUtils.refreshQuestions(allQuestions, vm.answersById);
vm.groupedQuestions = SurveyUtils.groupQuestions(allQuestions);
});

}
Expand Down
10 changes: 6 additions & 4 deletions waltz-ng/client/survey/survey-template-edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@ const qInclusionPredicateHelp = `
The inclusion predicate allows for questions to be conditionally included in a survey depending on the values of other fields.
See the documentation for a complete list of functions and their arguments. Below is a selection of the main functions/operators:
* Logical operators: \`< <= > >= == != && || ! \`
* \`isChecked(extId, defaultValue)\`: \`true\` if the question with the given ext id is checked, \`false\` if not checked,
* \`< <= > >= == != && || ! \`: logical operators
* \`isChecked(extId, <defaultValue>)\`: \`true\` if the question with the given ext id is checked, \`false\` if not checked,
or \`defaultValue\` if the answer is currently undefined.
* \`numberValue(extId, defaultValue)\`: numeric value of the response for the given ext id (or \`defaultValue\`)
* \`ditto(extId)\`: evaluates same conditions from a different question. Good for repetition, enhancements.
* \`numberValue(extId, <defaultValue>)\`: numeric value of the response for the given ext id (or \`defaultValue\`)
* \`ditto(extId)\`: evaluates same conditions from a different question. Useful for repetition of complex predicates.
* \`val(extId, <defaultValue>)\`: returns the current value
* \`isRetiring()\`: (application only) true if app has planned retirement date but no actual retirement date
`;


Expand Down
7 changes: 3 additions & 4 deletions waltz-ng/client/survey/survey-template-list.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ <h4>
<col width="30%">
<col width="10%">
<col width="10%">
<col width="20%">
<col width="30%">
<col width="15%">
<col width="35%">
</colgroup>
<thead>
<tr>
Expand Down Expand Up @@ -84,8 +84,7 @@ <h4>
<span ng-bind="ctrl.owners[template.ownerId].displayName"></span>
</td>
<td>
<waltz-markdown class='small'
text="template.description | limitTo:100">
<waltz-markdown text="template.description | limitTo:100">
</waltz-markdown>
<span ng-if="template.description.length > 100">...</span>
</td>
Expand Down
Loading

0 comments on commit efe1bce

Please sign in to comment.