Skip to content
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

Patient document preview #452

Merged
merged 2 commits into from
May 30, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions client/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@
"BANK" : "Bank",
"BANK_ACCOUNT" : "Bank Account",
"BILLING_SERVICES" : "Billing Services Applied",
"BY" : "By",
"BY_ID" : "By Id",
"BY_NAME" : "By Name",
"CANCELED" : "Canceled",
Expand Down Expand Up @@ -407,6 +408,12 @@
"SERVICE" : "Service",
"SET_DATE" : "Change Date",
"SEX" : "Sex",
"SIZE_BYTES" : "Bytes",
"SIZE_KB" : "Kb",
"SIZE_MB" : "Mb",
"SIZE_GB" : "Gb",
"SIZE_TB" : "Tb",
"SIZE_PB" : "Pb",
"SPOUSE" : "Spouse's Name",
"SPOUSE_EMPLOYER" : "Spouse's Employer",
"SPOUSE_PROFESSION" : "Spouse's Occupation",
Expand Down Expand Up @@ -444,6 +451,7 @@
"ENTER_CREDITOR" : "Enter Creditor",
"ENTER_DEBTOR" : "Enter Debtor",
"ENTER_DESCRIPTION" : "Enter description",
"ENTER_DOCUMENT_NAME": "Enter Document Name",
"ENTER_EMAIL" : "Enter email",
"ENTER_MAX_CREDIT" : "Enter max credit",
"ENTER_NAME" : "Enter Name",
Expand Down Expand Up @@ -542,10 +550,14 @@
"TITLE" : "Authentication"
},
"PATIENT_DOCUMENT" : {
"ADD" : "Add",
"ADD" : "Add documents",
"DISPLAY_LIST" : "Display as list",
"DISPLAY_THUMBNAIL" : "Display as thumbnail",
"DOCUMENT_TITLE" : "Document Title",
"DOCUMENT_LIST" : "Documents List",
"DOCUMENTS" : "Patient's Documents",
"DOWNLOAD" : "Download",
"NO_DOCUMENT" : "No Document Found",
"OVERVIEW" : "Overview",
"POSTED_BY" : "Posted by",
"SEARCH" : "Search documents",
Expand Down Expand Up @@ -582,6 +594,11 @@
"PAGE_TITLE" : "Patient Invoice",
"SUCCESS" : "Patient invoice successfully recorded."
},
"PATIENT_RECORDS": {
"TITLE" : "Patients",
"UPLOAD_PICTURE" : "Upload Patient Photo",
"NOT_FOUND" : "Unable to find patient with that ID. Please check with your system administrator."
},
"PATIENT_REG": {
"FIND_PATIENT" : "Find a Patient",
"PAGE_TITLE" : "Patient Registration",
Expand All @@ -591,11 +608,6 @@
"VIEW_PATIENT_RECORDS" : "View Patient Records",
"SUCCEESS" : "Patient record successfully written"
},
"PATIENT_RECORDS": {
"TITLE" : "Patients",
"UPLOAD_PICTURE" : "Upload Patient Photo",
"NOT_FOUND" : "Unable to find patient with that ID. Please check with your system administrator."
},
"PATIENT_REGISTRY" : {
"DAY" : "day",
"DAYS" : "days",
Expand Down
22 changes: 20 additions & 2 deletions client/src/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@
"BANK" : "Banque",
"BANK_ACCOUNT" : "Compte Bancaire",
"BILLING_SERVICES" : "Les services de facturation appliquée",
"BY" : "Par",
"BY_ID" : "Par id",
"BY_NAME" : "Par nom",
"CANCELED" : "Annulee",
Expand Down Expand Up @@ -404,6 +405,12 @@
"SERVICE" : "Service",
"SET_DATE" : "Changer la Date",
"SEX" : "Sexe",
"SIZE_BYTES" : "Octets",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

"SIZE_KB" : "Ko",
"SIZE_MB" : "Mo",
"SIZE_GB" : "Go",
"SIZE_TB" : "To",
"SIZE_PB" : "Po",
"SPOUSE" : "Nom de l'époux(se)",
"SPOUSE_EMPLOYER" : "Employeur(époux(se))",
"SPOUSE_PROFESSION" : "Profession (époux(se))",
Expand Down Expand Up @@ -441,6 +448,7 @@
"ENTER_CREDITOR" : "Entrer un crediteur",
"ENTER_DEBTOR" : "Entrer un debiteur",
"ENTER_DESCRIPTION" : "Entrer une description",
"ENTER_DOCUMENT_NAME": "Entrer le nom du document",
"ENTER_EMAIL" : "Entrer l'adresse e-mail",
"ENTER_MAX_CREDIT" : "Entrer le crédit maximale",
"ENTER_NAME" : "Entrer le nom",
Expand Down Expand Up @@ -539,10 +547,14 @@
"TITLE" : "Authentification"
},
"PATIENT_DOCUMENT" : {
"ADD" : "Ajouter",
"ADD" : "Ajouter documents",
"DISPLAY_LIST" : "Affichage en list",
"DISPLAY_THUMBNAIL" : "Affichage en miniature",
"DOCUMENT_TITLE" : "Titre du document",
"DOCUMENT_LIST" : "Liste des documents",
"DOCUMENTS" : "Documents du patient",
"DOWNLOAD" : "Telecharger",
"NO_DOCUMENT" : "Aucun document trouvé",
"OVERVIEW" : "Aperçu",
"POSTED_BY" : "Posté par",
"SEARCH" : "Chercher documents",
Expand All @@ -556,7 +568,8 @@
"PAGE_TITLE" : "Modifier Patient",
"RECORD_SAME" : "Aucun changement n'a été apporté sur le formulaire. Mettez à jour les détails de patients et appuyez sur soumettre.",
"REGISTERED" : "Patient Enregistré",
"WARN" : "Aucun groupes de patients n'a été trouvée. Les groupes de patients doivent être enregistrés dans le système avant l'affectation des patients"
"WARN" : "Aucun groupes de patients n'a été trouvée. Les groupes de patients doivent être enregistrés dans le système avant l'affectation des patients",
"EDIT_DETAILS" : "Modifier les details"
},
"PATIENT_GROUP": {
"ADD_PATIENT_GROUP" : "Nouveau Groupe de Patients",
Expand All @@ -577,6 +590,11 @@
"INVALID_ITEMS" : "Cette facture contient des articles invalides",
"PAGE_TITLE" : "Facture des patients"
},
"PATIENT_RECORDS": {
"TITLE" : "Patients",
"UPLOAD_PICTURE" : "Telecharger Photo Patient",
"NOT_FOUND" : "Impossible de trouver le patient ayant ce ID. Veuillez contacter votre administrateur systeme"
},
"PATIENT_REG": {
"FIND_PATIENT" : "Trouver Patient",
"PAGE_TITLE" : "Enregistrement des Patients",
Expand Down
12 changes: 1 addition & 11 deletions client/src/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -528,21 +528,11 @@ function bhimaConfig($stateProvider, $urlRouterProvider, $urlMatcherFactoryProvi
})

.state('patientDocuments', {
url : '/patients/documents',
url : '/patients/:patient_uuid/documents',
controller : 'PatientDocumentsController as PatientDocCtrl',
templateUrl : 'partials/patients/documents/documents.html'
})

.state('patientDocuments.view', {
params : { patient_uuid: null },
views : {
'document@patientDocuments' : {
controller : 'DocumentViewController as DocViewCtrl',
templateUrl : 'partials/patients/documents/views/documentView.html'
}
}
})

/* Patient Invoicing */
.state('patientInvoice', {
url : '/invoices/patient',
Expand Down
117 changes: 117 additions & 0 deletions client/src/js/components/bhFindDocument.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
angular.module('bhima.components')
.component('bhFindDocument', {
controller : FindDocumentComponent,
controllerAs : '$ctrl',
templateUrl : 'partials/templates/bhFindDocument.tmpl.html',
bindings: {
enablePatientDetails : '<', // bind boolean (true|false) : Enable patient details option
enableOptionBar : '<', // bind boolean (true|false) : Enable option for add, display list or display thumbnail in a bar
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can most of these options be bound as attributes @ to avoid too many $watch() statements? Or must they be dynamic?

enableSearch : '<', // bind boolean (true|false) : Enable search bar option
display : '@', // bind (list|thumbnail) : Display either in list or thumbnail mode
patientUuid : '<' // Required patient uuid
}
});

FindDocumentComponent.$inject = [
'PatientService', 'ModalService', 'DocumentService',
'NotifyService', 'UserService', '$translate'
];

/**
* Find Document Component
* This component is responsible for displaying documents for specific patient given
*/
function FindDocumentComponent(Patient, Modal, Document, Notify, User, $translate) {
var vm = this;

/** global variables */
vm.session = {
patientUuid : this.patientUuid,
enablePatientDetails : Boolean(this.enablePatientDetails),
enableOptionBar : Boolean(this.enableOptionBar),
enableSearch : Boolean(this.enableSearch),
display : this.display,
showAction : false
};

/** expose to the view */
vm.switchDisplay = switchDisplay;
vm.toggleAction = toggleAction;
vm.addDocument = addDocument;
vm.deleteDocument = deleteDocument;
vm.mimeIcon = mimeIcon;

// startup the component
startup();

/** function switchDisplay */
function switchDisplay(mode) {
vm.session.display = mode;
}

/** toggle document actions */
function toggleAction(index) {
vm.selectedIndex = index;
vm.session.showAction = vm.session.showAction === true ? false : true;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An easier way to do this in the future would be this:

vm.session.showAction = !vm.session.showAction;

}

/** function add documents modal */
function addDocument() {
Modal.openUploadDocument({ patient_uuid: vm.session.patientUuid })
.then(startup);
}

/** delete document */
function deleteDocument(uuid) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a delete modal implemented in bootstrap by @lomamech. Here is the code. Could you use it instead? See #150 for the reasons why.

Modal.confirm($translate.instant('FORM.DIALOGS.CONFIRM_DELETE'))
.then(function (ans) {
if (!ans) { return; }

return Document.remove(vm.session.patientUuid, uuid)
.then(function () {
Notify.success('FORM.INFOS.DELETE_SUCCESS');
startup();
});

})
.catch(Notify.handleError);
}

/** getting patient document */
function startup() {
if (!vm.session.patientUuid) { return; }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why should happen if there is not a patientUuid? Will this case ever occur?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no data for unknow patient

No data will be displayed

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, this is fine for now. I wonder if, in the future, we should include an error message saying the patient cannot be found, and perhaps a link to the patient registry.


Patient.read(vm.session.patientUuid)
.then(function (patient) {
vm.session.patient = patient;
})
.catch(Notify.handleError);

Document.read(vm.session.patientUuid)
.then(function (documents) {
vm.session.patientDocuments = documents;
})
.catch(Notify.handleError);
}

/** format the image type */
function mimeIcon(mimetype) {
var result = {};

if (mimetype.indexOf('image') > -1) {
result = { icon : 'fa-file-image-o', label : 'Image' };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future, these labels could be translated.

} else if (mimetype.indexOf('pdf') > -1) {
result = { icon : 'fa-file-pdf-o', label : 'PDF' };
} else if (mimetype.indexOf('word') > -1) {
result = { icon : 'fa-file-word-o', label : 'MS WORD' };
} else if (mimetype.indexOf('sheet') > -1) {
result = { icon : 'fa-file-excel-o', label : 'MS EXCEL' };
} else if (mimetype.indexOf('presentation') > -1) {
result = { icon : 'fa-file-powerpoint-o', label : 'MS Power Point' };
} else {
result = { icon : 'fa-file-o', label : 'Fichier' };
};

return result;
}
}
23 changes: 23 additions & 0 deletions client/src/js/filters/bytes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
angular.module('bhima.filters')
.filter('bytes', BytesFilter);

BytesFilter.$inject = ['$translate'];

/**
* Bytes Filter
* Format bytes size to human readable format
*/
function BytesFilter($translate) {
return function(bytes, precision) {
if (isNaN(parseFloat(bytes)) || !isFinite(bytes)) { return '-'; }
if (typeof precision === 'undefined') { precision = 1; }
var units = ['SIZE_BYTES', 'SIZE_KB', 'SIZE_MB', 'SIZE_GB', 'SIZE_TB', 'SIZE_TB'],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool! Another optimization (not necessary for this PR), would be to move the keys and $translate call out of the return statement, since they never change.

Like:

function BytesFilter($translate) {
  var units = ['SIZE_BYTES', 'SIZE_KB', 'SIZE_MB', 'SIZE_GB', 'SIZE_TB', 'SIZE_TB'];
  units = units.map(function (u) { return 'FORM.LABELS.' + $translate.instant(u); });
  return function (bytes, precision) { 
   // code ....
  };
}

Just an idea. :)

number = Math.floor(Math.log(bytes) / Math.log(1024));

units = units.map(function (unit) {
return $translate.instant('FORM.LABELS.' + unit);
});

return (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision) + ' ' + units[number];
}
}
63 changes: 47 additions & 16 deletions client/src/partials/patients/documents/documents.css
Original file line number Diff line number Diff line change
@@ -1,32 +1,26 @@
.document {
border: 1px solid #efefef;
border: 1px solid #ddd;
padding: 5px;
margin-bottom: 15px;
cursor: pointer;
border-top: 5px solid #efefef;
}
.document:hover {
border-top: 5px solid blue;
background-color: #eaeafe;
background-color: #eee;
}

.document h4 {
margin: 2px;
}

.document .document-actions {
.document-actions {
text-align: center;
width: 100%;
margin: auto;
margin-top: 5px;
}

.document .crop {
width: 100%;
height: 150px;
overflow: hidden;
}

.document .crop img.document-thumbnail {
display: block;
width: 100%;
Expand All @@ -38,18 +32,55 @@
-webkit-transition: margin-top 1s;
transition: margin-top 1s;
}

.document:hover .crop img.document-thumbnail {
-webkit-filter: grayscale(0%);
filter: grayscale(0%);
margin-top: -50px;
-webkit-filter: grayscale(0%);
filter: grayscale(0%);
margin-top: -25px;
}
.document .crop .document-icon {
text-align: center;
font-size: 10rem;
color: #337ab7;
}
.patient-document .pd-patient {
padding: 7px;
margin-bottom: 5px;
border: 1px solid green;
color: green;
background-color: #e4f9ec;
}
.patient-document .pd-search {
margin-bottom: 5px;
}

/* patient document heading */
.patient-document .pd-documents .heading {
display: flex;
justify-content: space-between;
background-color: #337ab7;
color: #fff;
padding: 5px;
margin-bottom: 5px;
}
.patient-document .pd-documents .heading > .left {
margin: 5px 10px;
}

/* patient list thumbanil */
.patient-document .display-thumbnail {
display: flex;
align-items: flex-start;
align-content: flex-start;
justify-content: flex-start;
flex-wrap: wrap;
}
.patient-document .display-thumbnail > .document {
width: 50%;
}

/* document upload thumbnail */
.document-upload-thumbnail {
display: block;
width: 100%;
margin: auto;
margin-bottom: 10px;
-webkit-filter: grayscale(75%);
filter: grayscale(75%);
}
Loading