Skip to content

Commit

Permalink
EPCT-6 Wizard Component (#695)
Browse files Browse the repository at this point in the history
* Poc Wizard complete

* Form is now passed to the step to ease field validation messages

* Patient Registration now uses poc-wizard

* Form is now an optional attribute for the poc-wizard-step

* Isolating pocConfirmDialog scope
  • Loading branch information
edrisse authored and ynurmahomed committed Jul 19, 2018
1 parent 60e0813 commit 0878d76
Show file tree
Hide file tree
Showing 46 changed files with 875 additions and 1,307 deletions.
2 changes: 1 addition & 1 deletion app/common/patient/components/patientSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
}

function linkPatientNew() {
$state.go('newpatient.identifier');
$state.go('newpatient');
}

function onPatientSelect(patient) {
Expand Down
88 changes: 45 additions & 43 deletions app/common/patient/components/wizard/patientWizard.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,59 +4,61 @@
</div>
</div>

<div class="row bg-info-border content-border border-rouded">
<div id="status-buttons" class="text-center">
<a ui-sref-active="active" ng-click="vm.changeStep('identifier');">
<span class="label label-primary">1</span> {{'PATIENT_INFO_IDENTIFIERS' | translate}}
</a>
<a ui-sref-active="active" ng-click="vm.changeStep('name');">
<span class="label label-primary">2</span>
{{'PATIENT_INFO_NAME' | translate}}
</a>
<a ui-sref-active="active" ng-click="vm.changeStep('gender');">
<span class="label label-primary">3</span> {{'PATIENT_INFO_GENDER' | translate}}
</a>
<a ui-sref-active="active" ng-click="vm.changeStep('age');">
<span class="label label-primary">4</span> {{'PATIENT_INFO_AGE' | translate}}
</a>
<a ui-sref-active="active" ng-click="vm.changeStep('address');">
<span class="label label-primary">5</span> {{'PATIENT_INFO_ADDRESS' | translate}}
</a>
<a ui-sref-active="active" ng-click="vm.changeStep('other');">
<span class="label label-primary">6</span> {{'PATIENT_INFO_OTHERS' | translate}}
</a>
<a ui-sref-active="active" ng-click="vm.changeStep('testing');">
<span class="label label-primary">7</span> {{'PATIENT_INFO_HIV_TEST' | translate}}
</a>
</div>
</div>
<poc-wizard on-show-message="vm.setShowMessage(showMessage)" on-save="vm.save()">

<ui-view></ui-view>
<form name="vm.formIdentifiers" class="form-horizontal" novalidate>
<poc-wizard-step form="vm.formIdentifiers" title="{{'PATIENT_INFO_IDENTIFIERS' | translate}}">
<patient-identifiers-step patient="vm.patient" form="vm.formIdentifiers" show-messages="vm.showMessages" />
</poc-wizard-step>
</form>

<div class="row bg-info-border content-border border-rouded-bottom">
<form name="vm.formNames" class="form-horizontal" novalidate>
<poc-wizard-step form="vm.formNames" title="{{'PATIENT_INFO_NAME' | translate}}">
<patient-names-step patient="vm.patient" form="vm.formNames" show-messages="vm.showMessages" />
</poc-wizard-step>
</form>

<div class="pull-right">
<form name="vm.formGender" class="form-horizontal" novalidate>
<poc-wizard-step form="vm.formGender" title="{{'PATIENT_INFO_GENDER' | translate}}">
<patient-gender-step patient="vm.patient" form="vm.formGender" show-messages="vm.showMessages" />
</poc-wizard-step>
</form>

<button id="previous-step" type="button" class="btn btn-default btn-lg" ng-click="vm.stepBackwards();" ng-if="!vm.atFirstStep();">
<span class="glyphicon glyphicon glyphicon-step-backward"></span>
<span class="button-label">{{'PREVIOUS_STEP' | translate}}</span>
</button>
<form name="vm.formAge" class="form-horizontal" novalidate>
<poc-wizard-step form="vm.formAge" title="{{'PATIENT_INFO_AGE' | translate}}">
<patient-age-step patient="vm.patient" form="vm.formAge" show-messages="vm.showMessages" />
</poc-wizard-step>
</form>

<button id="next-step" type="button" class="btn btn-default btn-lg" ng-click="vm.stepForward();" ng-if="!vm.atLastStep();">
<span class="glyphicon glyphicon glyphicon-step-forward"></span>
<span class="button-label">{{'NEXT_STEP' | translate}}</span>
</button>
<form name="vm.formAddress" class="form-horizontal" novalidate>
<poc-wizard-step form="vm.formAddress" title="{{'PATIENT_INFO_ADDRESS' | translate}}">
<patient-address-step patient="vm.patient" form="vm.formAddress" show-messages="vm.showMessages" />
</poc-wizard-step>
</form>

<button id="confirm" type="button" class="btn btn-primary btn-lg" ng-click="vm.save();" ng-if="vm.atLastStep();">
<span class="glyphicon glyphicon-floppy-disk"></span>
<span class="button-label">{{'SAVE' | translate}}</span>
</button>
<form name="vm.formOther" class="form-horizontal" novalidate>
<poc-wizard-step form="vm.formOther" title="{{'PATIENT_INFO_OTHERS' | translate}}">
<patient-other-step patient="vm.patient" form="vm.formOther" show-messages="vm.showMessages" />
</poc-wizard-step>
</form>

</div>
<form name="vm.formHiv" class="form-horizontal" novalidate>
<poc-wizard-step form="vm.formHiv" title="{{'PATIENT_INFO_HIV_TEST' | translate}}">
<patient-hiv-test-step patient="vm.patient" form="vm.formHiv" show-messages="vm.showMessages" />
</poc-wizard-step>
</form>

<poc-wizard-step title="{{'CONFIRMATION' | translate}}">
<patient-confirm-step patient="vm.patient" />
</poc-wizard-step>

</poc-wizard>

<div class="row bg-info-border content-border border-rouded-bottom">

<button type="button" class="btn btn-warning btn-lg" ng-click="vm.linkCancel();">
<span class="glyphicon glyphicon-minus-sign"></span>
<span class="button-label">{{'CANCEL' | translate}}</span>
</button>

</div>
</div>
73 changes: 5 additions & 68 deletions app/common/patient/components/wizard/patientWizard.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,8 @@
});

/* @ngInject */
function PatientWizardController($stateParams, $state, patientService, notifier, TabManager, translateFilter) {

var tabManager;

var currentStep;
function PatientWizardController($stateParams, $state, patientService,
notifier, translateFilter) {

var updating = false;

Expand All @@ -29,14 +26,9 @@
vm.openMRSPatient = {};

vm.$onInit = $onInit;
vm.changeStep = changeStep;
vm.linkCancel = linkCancel;
vm.save = save;
vm.stepForward = stepForward;
vm.stepBackwards = stepBackwards;
vm.setCurrentStep = setCurrentStep;
vm.atLastStep = atLastStep;
vm.atFirstStep = atFirstStep;
vm.setShowMessage = setShowMessage;

function $onInit() {

Expand All @@ -55,28 +47,6 @@
$state.go($stateParams.returnState);
});
}

tabManager = new TabManager();
tabManager.addStepDefinition('identifier');
tabManager.addStepDefinition('name');
tabManager.addStepDefinition('gender');
tabManager.addStepDefinition('age');
tabManager.addStepDefinition('address');
tabManager.addStepDefinition('other');
tabManager.addStepDefinition('testing');
tabManager.addStepDefinition('confirm');
}

// TODO handle navigating directly to a step that is not the first.
function setCurrentStep(s) {
if (!s.getName) {
throw new Error(`Step '${s.constructor.name}' should implement getName()`);
}
currentStep = s;
}

function getStepStateName(name) {
return `${vm.srefPrefix}.${name}`;
}

function linkCancel() {
Expand Down Expand Up @@ -121,41 +91,8 @@
}
}

function changeStep(toStepName) {
var currentStepName = currentStep.getName();

var stepingForward = tabManager.isStepingForward(currentStepName, toStepName);
var jumpingMoreThanOneTab = tabManager.isJumpingMoreThanOneTab(currentStepName, toStepName);

if (!stepingForward || (stepingForward && !jumpingMoreThanOneTab && currentStep.form.$valid)) {
vm.showMessages = false;
$state.go(getStepStateName(tabManager.goToStep(toStepName)));
} else if (stepingForward && jumpingMoreThanOneTab) {
notifier.warning("", translateFilter('FOLLOW_SEQUENCE_OF_TABS'));
} else {
vm.showMessages = true;
}
}

function stepForward() {
if (currentStep.form.$valid) {
vm.showMessages = false;
$state.go(getStepStateName(tabManager.stepForward()));
} else {
vm.showMessages = true;
}
}

function stepBackwards() {
$state.go(getStepStateName(tabManager.stepBackwards()));
}

function atLastStep() {
return currentStep && tabManager.isLastStep(currentStep.getName());
}

function atFirstStep() {
return currentStep && tabManager.isFirstStep(currentStep.getName());
function setShowMessage(showMessage) {
vm.showMessages = showMessage;
}

}
Expand Down
48 changes: 15 additions & 33 deletions app/common/patient/components/wizard/steps/patientAddressStep.html
Original file line number Diff line number Diff line change
@@ -1,41 +1,23 @@
<form name="vm.form" class="form-horizontal">
<div class="panel-body">

<div class="panel panel-primary content-border-margin">
<div class="form-group form-group-lg" ng-repeat="addressLevel in vm.addressLevels">

<div class="panel-heading">
<h3 class="panel-title">{{'PATIENT_INFO_ADDRESS' | translate}}</h3>
</div>

<div class="panel-body">

<div class="form-group form-group-lg" ng-repeat="addressLevel in vm.addressLevels">
<label for="{{addressLevel.addressField}}" class="col-sm-2 control-label">{{addressLevel.name | translate}}
<span class="asterick" ng-show="addressLevel.required">*</span>
</label>

<label for="{{addressLevel.addressField}}" class="col-sm-2 control-label">{{addressLevel.name | translate}}
<span class="asterick" ng-show="addressLevel.required">*</span></label>
<div class="col-sm-10" ng-class="{'has-error': vm.form[addressLevel.addressField].$invalid && vm.showMessages}">

<div class="col-sm-10"
ng-class="{'has-error': vm.form[addressLevel.addressField].$invalid && vm.shouldShowMessages()}">

<div ng-messages for="vm.form[addressLevel.addressField].$error" ng-show="vm.shouldShowMessages()">
<div ng-messages-include="../common/application/views/error-messages.html"></div>
</div>

<input type="text" name="{{addressLevel.addressField}}" id="{{addressLevel.addressField}}"
class="form-control keyboard-in"
ng-required="{{addressLevel.required}}"
ng-model="vm.patient.address[addressLevel.addressField]"
uib-typeahead="entry.name for entry in vm.getAddressEntryList(addressLevel.addressField, $viewValue)"
typeahead-on-select="vm.addressFieldSelected(addressLevel.addressField, $item)"
ng-change="vm.clearFields(addressLevel.addressField)"
ng-pattern="/^([a-zA-Z0-9\s]|[\)\(\'\/\-\.])*$/"
autocomplete="off"
ng-maxlength="{{addressLevel.addressField === 'country' ? 50 : 255}}"
maxlength="{{addressLevel.addressField === 'country' ? 50 : 255}}">
</div>
</div>
<div ng-messages for="vm.form[addressLevel.addressField].$error" ng-show="vm.showMessages">
<div ng-messages-include="../common/application/views/error-messages.html"></div>
</div>

<input type="text" name="{{addressLevel.addressField}}" id="{{addressLevel.addressField}}" class="form-control keyboard-in"
ng-required="{{addressLevel.required}}" ng-model="vm.patient.address[addressLevel.addressField]" uib-typeahead="entry.name for entry in vm.getAddressEntryList(addressLevel.addressField, $viewValue)"
typeahead-on-select="vm.addressFieldSelected(addressLevel.addressField, $item)" ng-change="vm.clearFields(addressLevel.addressField)"
ng-pattern="/^([a-zA-Z0-9\s]|[\)\(\'\/\-\.])*$/" autocomplete="off" ng-maxlength="{{addressLevel.addressField === 'country' ? 50 : 255}}"
maxlength="{{addressLevel.addressField === 'country' ? 50 : 255}}">
</div>

</div>

</form>
</div>
23 changes: 4 additions & 19 deletions app/common/patient/components/wizard/steps/patientAddressStep.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@
.module('common.patient')
.component('patientAddressStep', {
bindings: {
patient: '<'
patient: '<',
form: '<',
showMessages: '<'
},
controller: PatientAddressStepController,
controllerAs: 'vm',
require: {
patientWizard: '^^',
},
templateUrl: '../common/patient/components/wizard/steps/patientAddressStep.html',
templateUrl: '../common/patient/components/wizard/steps/patientAddressStep.html'
});

/* @ngInject */
Expand All @@ -24,35 +23,21 @@

var vm = this;

var NAME = 'address';

vm.addressLevels = [];

vm.$onInit = $onInit;
vm.getName = getName;
vm.shouldShowMessages = shouldShowMessages;
vm.addressFieldSelected = addressFieldSelected;
vm.getAddressEntryList = getAddressEntryList;
vm.clearFields = clearFields;

function $onInit() {
vm.patientWizard.setCurrentStep(vm);

configurationService.getAddressLevels()
.then(addressLevels => {
vm.addressLevels = addressLevels.slice(0).reverse();
addressLevelsNamesInDescendingOrder = vm.addressLevels.map(addressLevel => addressLevel.addressField);
});
}

function getName() {
return NAME;
}

function shouldShowMessages() {
return vm.patientWizard.showMessages;
}

function addressFieldSelected(addressFieldName, $item) {
var parentFields = addressLevelsNamesInDescendingOrder.slice(addressLevelsNamesInDescendingOrder.indexOf(addressFieldName) + 1);
var parent = $item.parent;
Expand Down
Loading

0 comments on commit 0878d76

Please sign in to comment.