Skip to content

Commit

Permalink
feat(bhFindPatient): onRegisterApi callback
Browse files Browse the repository at this point in the history
This commit introduces the onRegisterApi callback to the bhFindPatient
directive.  Any controller that needs access to the bhFindPatient's api
methods can request it via the `onRegisterApi` function.  For
demonstration, the Patient Invoice module does exactly this.

It also adds the initial unit test structure for karma testing the
component controller.  These unit tests will be rounded out in
subsequent commits.
  • Loading branch information
Jonathan Niles committed Jul 18, 2016
1 parent f630ed5 commit 0c9ffeb
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 79 deletions.
2 changes: 1 addition & 1 deletion client/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@
"PASSWORD" : "Password",
"PATIENT" : "Patient",
"PATIENT_DETAILS" : "Patient Details",
"PATIENT_ID" : "ID Patient",
"PATIENT_ID" : "Patient ID",
"PATIENT_NAME" : "Patient Name",
"PAYMENT" : "Payment",
"PAYMENT_METHOD" : "Payment Method",
Expand Down
62 changes: 30 additions & 32 deletions client/src/js/components/bhFindPatient.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ angular.module('bhima.components')
templateUrl : 'partials/templates/bhFindPatient.tmpl.html',
bindings: {
onSearchComplete: '&', // bind callback to call when data is available
onRegisterApi: '&', // expose force refresh API
required: '<', // bind the required (for ng-required)
suppressReset: '@', // bind a string
api: '=?' // expose force refresh API
}
});

Expand All @@ -26,9 +26,9 @@ FindPatientComponent.$inject = [
* which are presented to the user.
*
* SUPPORTED ATTRIBUTES:
* - on-search-complete : the callback function which get the returned patient
* - on-search-complete : a callback function called with the found patient
* - suppress-reset: a boolean value to
* - api: an object which will be bound to the current scope.
* - on-registry-api: a callback to be called with the component's api
*/
function FindPatientComponent(Patients, AppCache, Notify) {
var vm = this;
Expand All @@ -37,9 +37,9 @@ function FindPatientComponent(Patients, AppCache, Notify) {
var cache = AppCache('FindPatientComponent');

/* @const the max number of records to fetch from the server */
var LIMIT = 20;
var LIMIT = 10;

/** supported searches: by name or by id */
/* supported searches: by name or by id */
vm.options = {
findById : {
'label' : 'FORM.LABELS.PATIENT_ID',
Expand Down Expand Up @@ -81,7 +81,7 @@ function FindPatientComponent(Patients, AppCache, Notify) {

var options = {
reference : reference,
limit : LIMIT
limit : 1
};

// query the patient's search endpoint for the
Expand All @@ -94,15 +94,15 @@ function FindPatientComponent(Patients, AppCache, Notify) {
}

/**
* @method searchByName
*
* @param {string} text Patient name (first_name, middle_name or last_name)
*
* @description This function make a call to BHIMA API for getting patients
* according the name (first_name, middle_name or last_name).
*
* @return {Array} An array of patients
*/
* @method searchByName
*
* @param {string} text Patient name (first_name, middle_name or last_name)
*
* @description This function make a call to BHIMA API for getting patients
* according the name (first_name, middle_name or last_name).
*
* @return {Array} An array of patients
*/
function searchByName(text) {
vm.loadStatus = 'loading';

Expand Down Expand Up @@ -173,15 +173,15 @@ function FindPatientComponent(Patients, AppCache, Notify) {
}

/**
* @method formatPatient
*
* @param {object} patient The patient object
*
* @description This function is responsible for formatting the patient name
* to be more readable
*
* @returns {string} The formatted patient name
*/
* @method formatPatient
*
* @param {object} patient The patient object
*
* @description This function is responsible for formatting the patient name
* to be more readable
*
* @returns {string} The formatted patient name
*/
function formatPatient(p) {
return p ? p.first_name + ' ' + p.last_name + ' ' + p.middle_name : '';
}
Expand All @@ -205,6 +205,8 @@ function FindPatientComponent(Patients, AppCache, Notify) {
patient.name = formatPatient(patient);
patient.sex = patient.sex.toUpperCase();

console.log(patient);

// call the external function with patient
vm.onSearchComplete({ patient : patient });

Expand Down Expand Up @@ -250,12 +252,8 @@ function FindPatientComponent(Patients, AppCache, Notify) {
}
}

// Expose reset method - this allows the controller to reset the state without
// forcing a page refresh
// TODO Discuss - This could be done by binding and watching objects
// the functionality required is forcing a reset on the directive from the controller
// TODO Force search if required?
vm.api = {
reset : reload
};
// call the onRegisterApi() callback with the
vm.onRegisterApi({
api : { reset : reload }
});
}
3 changes: 0 additions & 3 deletions client/src/js/services/PatientService.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,6 @@ function PatientService($http, util, Session, $uibModal, Documents, Visits) {

var target = baseUrl.concat('search');

// ensure that the search returns detailed results
options.detailed = 1;

return $http.get(target, { params : options })
.then(util.unwrapHttpResponse);
}
Expand Down
16 changes: 7 additions & 9 deletions client/src/partials/patient_invoice/patientInvoice.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@
<div class="col-md-6">

<div class="form-group">
<label class="control-label">{{ "FORM.LABELS.RECIPIENT" | translate }}</label>
<bh-find-patient
type="inline"
suppress-reset="true"
on-search-complete="PatientInvoiceCtrl.setPatient(patient)"
api="PatientInvoiceCtrl.patientSearch">
on-register-api="PatientInvoiceCtrl.onPatientSearchApiCallback(api)">
</bh-find-patient>
</div>

Expand Down Expand Up @@ -70,11 +68,11 @@
@todo - since we know this is a financial date, we could set min and max for periods etc.
-->
<bh-date-editor
date-value="PatientInvoiceCtrl.Invoice.details.date"
validation-trigger="detailsForm.$submitted"
min-date="PatientInvoiceCtrl.minimumDate"
max-date="PatientInvoiceCtrl.timestamp">
</bh-date-editor>
date-value="PatientInvoiceCtrl.Invoice.details.date"
validation-trigger="detailsForm.$submitted"
min-date="PatientInvoiceCtrl.minimumDate"
max-date="PatientInvoiceCtrl.timestamp">
</bh-date-editor>

<div
class="form-group"
Expand All @@ -83,7 +81,7 @@
<textarea
ng-model="PatientInvoiceCtrl.Invoice.details.description"
name="notes"
placeholder="{{"FORM.PLACEHOLDERS.NOTES}}..."
placeholder="{{'FORM.PLACEHOLDERS.NOTES' | translate}}..."
class="form-control"
ng-maxlength="PatientInvoiceCtrl.maxLength"
rows="4"
Expand Down
11 changes: 9 additions & 2 deletions client/src/partials/patient_invoice/patientInvoice.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ function PatientInvoiceController(Patients, PatientInvoices, PatientInvoiceForm,
vm.maxLength = util.maxTextLength;
vm.minimumDate = util.minimumDate;
vm.itemIncrement = 1;
vm.onPatientSearchApiCallback = onPatientSearchApiCallback;

// read in services and bind to the view
Services.read()
Expand Down Expand Up @@ -138,6 +139,11 @@ function PatientInvoiceController(Patients, PatientInvoices, PatientInvoiceForm,
});
}

// register the patient search api
function onPatientSearchApiCallback(api) {
vm.patientSearchApi = api;
}

// reset everything in the controller - default values
function clear(detailsForm) {

Expand All @@ -157,8 +163,9 @@ function PatientInvoiceController(Patients, PatientInvoices, PatientInvoiceForm,
vm.Invoice.setService(vm.services[0]);
}

if (vm.patientSearch) {
vm.patientSearch.reset();
// reset the find patient component
if (vm.patientSearchApi) {
vm.patientSearchApi.reset();
}
}

Expand Down
62 changes: 30 additions & 32 deletions client/src/partials/templates/bhFindPatient.tmpl.html
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<div data-find-patient ng-form="FindPatientForm" bh-form-defaults novalidate>

<!-- inline Find Patient Directive UI -->
<div class="form-group has-feedback"
ng-class="{
'has-success': !$ctrl.showSearchView && $ctrl.loadStatus=='loaded',
'has-error': !$ctrl.showSearchView && $ctrl.loadStatus=='error'
}"
>
<label class="control-label">{{ "FORM.LABELS.PATIENT" | translate }}</label>

<!-- inline input zone -->
<!-- input zone -->
<div class="input-group" ng-if="$ctrl.showSearchView">

<div class="input-group-btn" uib-dropdown tabindex=-1>
Expand Down Expand Up @@ -61,14 +61,14 @@
ng-disabled="FindPatientForm.idInput.$invalid"
ng-click="$ctrl.submit()"
data-find-patient-submit>
<span>{{ "FORM.BUTTONS.SEARCH" | translate }}</span>
{{ "FORM.BUTTONS.SEARCH" | translate }}
</button>
</span>
</div>
<!-- /inline input zone -->

<!-- inline notification -->
<p class="help-block text-right">
<p class="help-block text-right" ng-show="$ctrl.showSearchView">
<span class="text-warning" ng-show="($ctrl.noPatients && $ctrl.nameInput)">
<i class="fa fa-info-circle"></i> {{ "FORM.INFOS.PATIENT_NOT_FOUND" | translate }}
</span>
Expand All @@ -78,40 +78,38 @@
</p>
<!-- /inline notification -->

<!-- notification zone for result -->
<div ng-if="!$ctrl.showSearchView">

<div class="input-group">
<!-- notification zone -->
<div class="input-group" ng-if="!$ctrl.showSearchView">

<span class="input-group-addon">
<span class="glyphicon glyphicon-user"></span>
</span>
<span class="input-group-addon">
<i class="fa fa-user"></i>
</span>

<input ng-if="$ctrl.loadStatus=='loaded'" readonly class="form-control" value="[{{ $ctrl.patient.reference }}] {{ $ctrl.patient.name }}">
<input ng-if="$ctrl.loadStatus=='error'" readonly class="form-control" value="{{ 'FORM.INFOS.PATIENT_NOT_FOUND' | translate }}">
<input ng-if="$ctrl.loadStatus=='loaded'" readonly class="form-control" value="[{{ $ctrl.patient.reference }}] {{ $ctrl.patient.name }}">
<input ng-if="$ctrl.loadStatus=='error'" readonly class="form-control" value="{{ 'FORM.INFOS.PATIENT_NOT_FOUND' | translate }}">

<div class="input-group-btn">
<a
ng-if="$ctrl.loadStatus=='loaded'"
class="btn btn-default"
uib-popover-template="'partials/templates/popover/patientinfo.tmpl.html'"
popover-title="Patient Record"
popover-placement="bottom"
popover-trigger="mouseenter"
popover-append-to-body="true">
<span class="glyphicon glyphicon-info-sign"></span>
</a>
<div class="input-group-btn">
<a
ng-if="$ctrl.loadStatus=='loaded'"
class="btn btn-default"
uib-popover-template="'partials/templates/popover/patientinfo.tmpl.html'"
popover-title="Patient Record"
popover-placement="bottom"
popover-trigger="mouseenter"
popover-append-to-body="true">
<span class="fa fa-info-circle"></span>
</a>

<!-- Only shown if the controller has not specified suppressReset -->
<a
ng-if="!$ctrl.suppressReset"
class="btn btn-default"
ng-click="$ctrl.reload()">
<span class="glyphicon glyphicon-refresh"></span>
</a>
</div>
<!-- Only shown if the controller has not specified suppressReset -->
<a
ng-if="!$ctrl.suppressReset"
class="btn btn-default"
ng-click="$ctrl.reload()">
<span class="fa fa-refresh"></span>
</a>
</div>
</div>
<!-- /notification zone -->
</div>
<!-- /notification zone -->
</div>
Loading

0 comments on commit 0c9ffeb

Please sign in to comment.