diff --git a/ui/app/i18n/ot/locale_en.json b/ui/app/i18n/ot/locale_en.json
index 13cc969b00..5d84a73887 100644
--- a/ui/app/i18n/ot/locale_en.json
+++ b/ui/app/i18n/ot/locale_en.json
@@ -14,6 +14,7 @@
"DATE": "Date",
"DISCARD": "Discard",
"SAVE": "Save",
+ "UPDATE": "Update",
"ADD_SURGICAL_APPOINTMENT": "Add Surgery",
"EDIT_SURGICAL_APPOINTMENT": "Edit Surgery",
@@ -114,5 +115,16 @@
"ACTUAL_TIME_ADDED_TO_KEY":"Actual time added to ",
"OT_SURGICAL_BLOCK_ACROSS_MULTIPLE_DAYS_CONFIRMATION_MESSAGE": "Are you sure you want to create a surgical block across days?",
"MOVING_KEY": "Moving",
- "FROM_KEY": "from"
+ "FROM_KEY": "from",
+ "EMPTY_NOTES_ERROR": "Note cannot be empty",
+ "NOTE_TITLE": "Note",
+ "FROM": "From",
+ "TO": "To",
+ "FROM_DATE_BEFORE_TO_DATE_ERROR": "From date should be before To date",
+ "DATE_OUT_OF_RANGE_ERROR": "Please select date within the valid range",
+ "DELETE_NOTE_TITLE": "Delete Note",
+ "YES_KEY": "Yes",
+ "NO_KEY": "No",
+ "DELETE_NOTE_MESSAGE": "Are you sure you want to delete this note?",
+ "NOTES_PLACEHOLDER": "Enter a maximum of 150 characters"
}
diff --git a/ui/app/ot/constants.js b/ui/app/ot/constants.js
index 165d59570b..c8ca8aba25 100644
--- a/ui/app/ot/constants.js
+++ b/ui/app/ot/constants.js
@@ -17,7 +17,8 @@ Bahmni.OT.Constants = (function () {
defaultCalendarStartTime: '00:00',
weekDays: {"Monday": 1, "Tuesday": 2, "Wednesday": 3, "Thursday": 4, "Friday": 5, "Saturday": 6, "Sunday": 7 },
defaultWeekStartDayName: 'Sunday',
- providerSurgicalAttributeFormat: 'org.openmrs.Provider'
+ providerSurgicalAttributeFormat: 'org.openmrs.Provider',
+ notesUrl: RESTWS_V1 + '/notes'
};
})();
diff --git a/ui/app/ot/controller/otCalendarController.js b/ui/app/ot/controller/otCalendarController.js
index d4771d4b49..2b76170a4f 100644
--- a/ui/app/ot/controller/otCalendarController.js
+++ b/ui/app/ot/controller/otCalendarController.js
@@ -1,8 +1,8 @@
'use strict';
angular.module('bahmni.ot')
- .controller('otCalendarController', ['$scope', '$rootScope', '$q', '$interval', 'spinner', 'locationService', 'surgicalAppointmentService', '$timeout', 'appService', 'surgicalAppointmentHelper',
- function ($scope, $rootScope, $q, $interval, spinner, locationService, surgicalAppointmentService, $timeout, appService, surgicalAppointmentHelper) {
+ .controller('otCalendarController', ['$scope', '$rootScope', '$q', '$interval', '$state', 'spinner', 'locationService', 'surgicalAppointmentService', '$timeout', 'appService', 'surgicalAppointmentHelper',
+ function ($scope, $rootScope, $q, $interval, $state, spinner, locationService, surgicalAppointmentService, $timeout, appService, surgicalAppointmentHelper) {
var updateCurrentDayTimeline = function () {
$scope.currentTimeLineHeight = heightPerMin * Bahmni.Common.Util.DateUtil.diffInMinutes($scope.calendarStartDatetime, new Date());
};
@@ -10,8 +10,167 @@ angular.module('bahmni.ot')
$scope.blocksStartDatetime = $scope.weekOrDay === 'day' ? $scope.viewDate : moment($scope.weekStartDate).startOf('day');
$scope.blocksEndDatetime = $scope.weekOrDay === 'day' ? moment($scope.viewDate).endOf('day') : moment(Bahmni.Common.Util.DateUtil.getWeekEndDate($scope.weekStartDate)).endOf('day');
};
+ $scope.isModalVisible = false;
+ $scope.notesStartDate = false;
+ $scope.notesEndDate = false;
+ $scope.isEdit = false;
+ $scope.showDeletePopUp = false;
+ $scope.styleForBlock = function (index) {
+ if (index === 6) {
+ return { 'border-right': '.5px solid lightgrey'};
+ }
+ };
+ var setValidStartDate = function (viewDate) {
+ const currentDate = new Date(viewDate);
+ $scope.validStartDate = $scope.weekDates[0];
+ while (currentDate > new Date($scope.weekDates[0])) {
+ const prev = new Date(currentDate);
+ currentDate.setDate(currentDate.getDate() - 1);
+ if ($scope.notesForWeek[currentDate]) {
+ $scope.validStartDate = prev;
+ break;
+ }
+ }
+ };
+ var setValidEndDate = function (viewDate) {
+ const currentDate = new Date(viewDate);
+ $scope.validEndDate = $scope.weekDates[6];
+ while (currentDate < new Date($scope.weekDates[6])) {
+ const prev = new Date(currentDate);
+ currentDate.setDate(currentDate.getDate() + 1);
+ if ($scope.notesForWeek[currentDate]) {
+ $scope.validEndDate = prev;
+ break;
+ }
+ }
+ };
+
+ $scope.showNotesPopup = function (weekStartDate, addIndex) {
+ const currentDate = new Date(weekStartDate);
+ if (addIndex === undefined) {
+ addIndex = 0;
+ }
+ currentDate.setDate(currentDate.getDate() + addIndex);
+ $scope.notesStartDate = currentDate;
+ $scope.notesEndDate = currentDate;
+ $scope.isModalVisible = true;
+ $scope.isDayView = $state.weekOrDay === 'day';
+ if (!$scope.isDayView) {
+ setValidStartDate(currentDate);
+ setValidEndDate(currentDate);
+ }
+ };
+ $scope.showNotesPopupEdit = function (weekStartDate, addIndex) {
+ const note = $scope.getNotesForDay(weekStartDate, addIndex);
+ const currentDate = new Date(weekStartDate);
+ $scope.otNotesField = note;
+ currentDate.setDate(currentDate.getDate() + addIndex);
+ $scope.notesStartDate = currentDate;
+ $scope.notesEndDate = currentDate;
+ $scope.isModalVisible = true;
+ $scope.isEdit = true;
+ $scope.dateOutOfRangeError = false;
+ };
+ $scope.closeNotes = function () {
+ $scope.isModalVisible = false;
+ $scope.startDateBeforeEndDateError = false;
+ $scope.emptyNoteError = false;
+ $scope.dateOutOfRangeError = false;
+ $scope.notesStartDate = undefined;
+ $scope.notesEndDate = undefined;
+ $scope.otNotesField = '';
+ $scope.isEdit = false;
+ };
+ $scope.setNotesEndDate = function (date) {
+ $scope.dateOutOfRangeError = date === undefined;
+ $scope.startDateBeforeEndDateError = date < $scope.notesStartDate;
+ $scope.notesEndDate = date;
+ };
+
+ $scope.setNotesStartDate = function (date) {
+ $scope.dateOutOfRangeError = date === undefined;
+ $scope.startDateBeforeEndDateError = date > $scope.notesEndDate;
+ $scope.notesStartDate = date;
+ };
+
+ $scope.setNotes = function (notes) {
+ $scope.otNotesField = notes;
+ if (notes) {
+ $scope.emptyNoteError = false;
+ }
+ if (notes && notes.id) {
+ $scope.notesId = notes.id;
+ }
+ };
+ $scope.openDeletePopup = function (weekStartDate, index) {
+ if (weekStartDate) {
+ $scope.currentDate = new Date(weekStartDate);
+ $scope.currentDate.setDate($scope.currentDate.getDate() + index);
+ }
+ $scope.showDeletePopUp = true;
+ };
+ $scope.closeDeletePopup = function () {
+ $scope.showDeletePopUp = false;
+ };
+ $scope.deleteNotes = function () {
+ var noteId;
+ if ($scope.weekOrDay === "week") {
+ noteId = $scope.notesForWeek[$scope.currentDate].noteId;
+ }
+ surgicalAppointmentService.deleteNoteForADay(noteId || $scope.noteId);
+ $scope.showDeletePopUp = false;
+ $state.go("otScheduling", {viewDate: $scope.viewDate}, {reload: true});
+ };
+
+ $scope.saveNotes = function () {
+ if ($scope.startDateBeforeEndDateError || $scope.dateOutOfRangeError) {
+ return;
+ }
+ if (!$scope.otNotesField) {
+ $scope.emptyNoteError = true;
+ return;
+ }
+ if ($scope.isDayView) {
+ surgicalAppointmentService.saveNoteForADay($scope.viewDate, $scope.otNotesField);
+ } else {
+ surgicalAppointmentService.saveNoteForADay($scope.notesStartDate, $scope.otNotesField, $scope.notesEndDate);
+ }
+ $state.go("otScheduling", {viewDate: $scope.viewDate}, {reload: true});
+ };
+
+ $scope.updateNotes = function () {
+ if ($scope.startDateBeforeEndDateError || $scope.dateOutOfRangeError) {
+ return;
+ }
+ if (!$scope.otNotesField) {
+ $scope.emptyNoteError = true;
+ return;
+ }
+ var note;
+ if ($scope.weekOrDay === "week") {
+ note = $scope.notesForWeek[$scope.notesStartDate];
+ }
+ surgicalAppointmentService.updateNoteForADay(note ? note.noteId : $scope.noteId, $scope.otNotesField, $rootScope.currentProvider.uuid);
+ $state.go("otScheduling", {viewDate: $scope.viewDate}, {reload: true});
+ };
var heightPerMin = 120 / $scope.dayViewSplit;
+ var showToolTipForNotes = function () {
+ $('.notes-text').tooltip({
+ content: function () {
+ var vm = (this);
+ return $(vm).prop('title');
+ },
+ track: true
+ });
+ };
+ const getNotes = function () {
+ if ($scope.weekOrDay === 'day') {
+ return surgicalAppointmentService.getBulkNotes(new Date($scope.viewDate));
+ } else if ($scope.weekOrDay === 'week') {
+ return surgicalAppointmentService.getBulkNotes($scope.weekStartDate, getWeekDate(7));
+ }
+ };
var init = function () {
var dayStart = ($scope.dayViewStart || Bahmni.OT.Constants.defaultCalendarStartTime).split(':');
var dayEnd = ($scope.dayViewEnd || Bahmni.OT.Constants.defaultCalendarEndTime).split(':');
@@ -20,6 +179,9 @@ angular.module('bahmni.ot')
$scope.editDisabled = true;
$scope.cancelDisabled = true;
$scope.addActualTimeDisabled = true;
+ $scope.otNotes = "";
+ $scope.isModalVisible = false;
+ $scope.showDeletePopUp = false;
$scope.dayViewSplit = parseInt($scope.dayViewSplit) > 0 ? parseInt($scope.dayViewSplit) : 60;
$scope.calendarStartDatetime = Bahmni.Common.Util.DateUtil.addMinutes($scope.viewDate, (dayStart[0] * 60 + parseInt(dayStart[1])));
$scope.calendarEndDatetime = Bahmni.Common.Util.DateUtil.addMinutes($scope.viewDate, (dayEnd[0] * 60 + parseInt(dayEnd[1])));
@@ -28,7 +190,8 @@ angular.module('bahmni.ot')
$scope.rows = $scope.getRowsForCalendar();
return $q.all([locationService.getAllByTag('Operation Theater'),
surgicalAppointmentService.getSurgicalBlocksInDateRange($scope.blocksStartDatetime, $scope.blocksEndDatetime, false, true),
- surgicalAppointmentService.getSurgeons()]).then(function (response) {
+ surgicalAppointmentService.getSurgeons(),
+ getNotes()]).then(function (response) {
$scope.locations = response[0].data.results;
$scope.weekDates = $scope.getAllWeekDates();
var surgicalBlocksByLocation = _.map($scope.locations, function (location) {
@@ -36,6 +199,13 @@ angular.module('bahmni.ot')
return surgicalBlock.location.uuid === location.uuid;
});
});
+ if (response[3] && response[3].status === 200) {
+ $scope.noteForTheDay = response[3].data.length > 0 ? response[3].data[0].noteText : '';
+ $scope.noteId = response[3].data.length > 0 ? response[3].data[0].noteId : '';
+ } else {
+ $scope.noteForTheDay = '';
+ $scope.noteId = '';
+ }
var providerNames = appService.getAppDescriptor().getConfigValue("primarySurgeonsForOT");
$scope.surgeons = surgicalAppointmentHelper.filterProvidersByName(providerNames, response[2].data.results);
var surgicalBlocksBySurgeons = _.map($scope.surgeons, function (surgeon) {
@@ -48,7 +218,34 @@ angular.module('bahmni.ot')
return $scope.isSurgicalBlockActiveOnGivenDate(surgicalBlock, weekDate);
});
});
+
+ $scope.getNotesForWeek = function (weekStartDate, index) {
+ const date = new Date(weekStartDate);
+ if (index === undefined) {
+ const notesForAWeek = {};
+ response[3].data.map(function (note) {
+ notesForAWeek[new Date(note.noteDate)] = note;
+ });
+ return notesForAWeek;
+ }
+ return _.filter(response[3].data, function (note) {
+ const currentDate = new Date(date);
+ currentDate.setDate(date.getDate() + index);
+ return new Date(note.noteDate).getDate() === (currentDate).getDate();
+ });
+ };
+
+ if ($scope.weekOrDay === 'week') {
+ $scope.notesForWeek = $scope.getNotesForWeek();
+ }
+
+ $scope.getNotesForDay = function (weekStartDate, index) {
+ var notes = $scope.getNotesForWeek(weekStartDate, index);
+ return notes.length > 0 ? notes[0].noteText : '';
+ };
+
$scope.blockedOtsOfTheWeek = getBlockedOtsOfTheWeek();
+ showToolTipForNotes();
var setOTView = function (providerToggle) {
$scope.providerToggle = providerToggle;
@@ -66,8 +263,8 @@ angular.module('bahmni.ot')
};
$scope.isSurgicalBlockActiveOnGivenDate = function (surgicalBlock, weekDate) {
- return Bahmni.Common.Util.DateUtil.isSameDate(moment(surgicalBlock.startDatetime).startOf('day').toDate(), weekDate)
- || moment(surgicalBlock.endDatetime).toDate() > weekDate;
+ return Bahmni.Common.Util.DateUtil.isSameDate(moment(surgicalBlock.startDatetime).startOf('day').toDate(), weekDate) ||
+ moment(surgicalBlock.endDatetime).toDate() > weekDate;
};
$scope.intervals = function () {
diff --git a/ui/app/ot/directives/otNotes.js b/ui/app/ot/directives/otNotes.js
new file mode 100644
index 0000000000..1e73580744
--- /dev/null
+++ b/ui/app/ot/directives/otNotes.js
@@ -0,0 +1,10 @@
+'use strict';
+
+angular.module('bahmni.ot')
+ .directive('otNotes', [function () {
+ return {
+ restrict: 'E',
+ require: '^otCalendar',
+ templateUrl: "../ot/views/notesModal.html"
+ };
+ }]);
diff --git a/ui/app/ot/index.html b/ui/app/ot/index.html
index c63f6871e5..5f7477ddbf 100644
--- a/ui/app/ot/index.html
+++ b/ui/app/ot/index.html
@@ -247,6 +247,7 @@
+
diff --git a/ui/app/ot/services/surgicalAppointmentService.js b/ui/app/ot/services/surgicalAppointmentService.js
index fdd9e91918..85e9874c0d 100644
--- a/ui/app/ot/services/surgicalAppointmentService.js
+++ b/ui/app/ot/services/surgicalAppointmentService.js
@@ -66,4 +66,53 @@ angular.module('bahmni.ot')
withCredentials: true
});
};
+ this.getBulkNotes = function (startDate, endDate) {
+ return $http.get(Bahmni.OT.Constants.notesUrl, {
+ method: 'GET',
+ params: {
+ noteType: 'OT Module',
+ noteStartDate: startDate,
+ noteEndDate: endDate
+ },
+ withCredentials: true
+ });
+ };
+
+ var constructPayload = function (noteDate, note, noteEndDate) {
+ const payload = [];
+ const currentDate = new Date(noteDate);
+ // eslint-disable-next-line no-unmodified-loop-condition
+ while (currentDate <= noteEndDate) {
+ payload.push({
+ noteTypeName: "OT module",
+ noteDate: new Date(currentDate),
+ noteText: note
+ });
+ currentDate.setDate(currentDate.getDate() + 1);
+ }
+ return payload;
+ };
+
+ this.saveNoteForADay = function (noteDate, note, noteEndDate) {
+ const payload = noteEndDate != null ? constructPayload(noteDate, note, noteEndDate) : [{
+ noteTypeName: "OT module",
+ noteDate: noteDate,
+ noteText: note
+ }];
+ const headers = {"Accept": "application/json", "Content-Type": "application/json"};
+ return $http.post(Bahmni.OT.Constants.notesUrl, payload, headers);
+ };
+
+ this.updateNoteForADay = function (noteId, note, providerUuid) {
+ const payload = {
+ noteText: note,
+ providerUuid: providerUuid
+ };
+ const headers = {"Accept": "application/json", "Content-Type": "application/json"};
+ return $http.post(Bahmni.OT.Constants.notesUrl + "/" + noteId, payload, headers);
+ };
+ this.deleteNoteForADay = function (noteId) {
+ const headers = {"Accept": "application/json", "Content-Type": "application/json", withCredentials: true};
+ return $http.delete(Bahmni.OT.Constants.notesUrl + "/" + noteId, headers);
+ };
}]);
diff --git a/ui/app/ot/views/notesModal.html b/ui/app/ot/views/notesModal.html
new file mode 100644
index 0000000000..21f9ec5d2e
--- /dev/null
+++ b/ui/app/ot/views/notesModal.html
@@ -0,0 +1,45 @@
+
+
+
×
+
+
{{'NOTE_TITLE' | translate}}
+
+
+
{{'EMPTY_NOTES_ERROR' | translate }}
+
+
+
{{'FROM' | translate}}
+
+
+
+
{{'TO' | translate}}
+
+
+
+ {{'FROM_DATE_BEFORE_TO_DATE_ERROR' | translate}}
+
+
+ {{'DATE_OUT_OF_RANGE_ERROR' | translate}}
+
+
+
+
+
+
+
+
+
+
+
×
+
+
{{'DELETE_NOTE_TITLE' | translate}}
+
{{'DELETE_NOTE_MESSAGE' | translate}}
+
+
+
+
+
diff --git a/ui/app/ot/views/otCalendar.html b/ui/app/ot/views/otCalendar.html
index 4651a0f369..9e7e6fc418 100644
--- a/ui/app/ot/views/otCalendar.html
+++ b/ui/app/ot/views/otCalendar.html
@@ -1,13 +1,27 @@
-
-
- {{location.name}}
-
-
- {{surgeon.person.display}}
-
+
+
{{viewDate | bahmniDateTimeWithFormat: 'ddd'}}
+
{{viewDate | bahmniDateTimeWithFormat: 'DD'}}
+
+
+
+ {{noteForTheDay}}
+
+
+
+
+
+
+ {{location.name}}
+
+
+ {{surgeon.person.display}}
+
+
+
+
@@ -35,7 +49,7 @@
ng-if="shouldDisplayCurrentTimeLine()"
ng-style = "{top : currentTimeLineHeight + 'px'}">
-
+
diff --git a/ui/app/ot/views/otWeeklyCalendar.html b/ui/app/ot/views/otWeeklyCalendar.html
index 4506332dfc..43c0503771 100644
--- a/ui/app/ot/views/otWeeklyCalendar.html
+++ b/ui/app/ot/views/otWeeklyCalendar.html
@@ -1,8 +1,16 @@
-
- {{weekStartDate | addDays: index | bahmniDateTimeWithFormat: 'Do MMM, ddd'}}
-
+
+
{{weekStartDate | addDays: index | bahmniDateTimeWithFormat: 'ddd'}}
+
{{weekStartDate | addDays: index | bahmniDateTimeWithFormat: 'DD'}}
+
+
+
+ {{getNotesForDay(weekStartDate, index)}}
+
+
+
+
@@ -31,9 +39,8 @@
ng-if="shouldDisplayCurrentTimeLine()"
ng-style="{top : currentTimeLineHeight + 'px'}">
-
+
-
diff --git a/ui/app/styles/ot/_otCalendar.scss b/ui/app/styles/ot/_otCalendar.scss
index 7014f21f5e..5d31a6c031 100644
--- a/ui/app/styles/ot/_otCalendar.scss
+++ b/ui/app/styles/ot/_otCalendar.scss
@@ -15,26 +15,72 @@
.calendar-location {
padding-left: 80px;
overflow: hidden;
+ background: #fff;
+ width: 94%;
float: left;
- display: flex;
position: absolute;
z-index: 20;
- background: #fff;
- width: 94%;
.heading-cell {
width: 300px;
box-sizing: border-box;
text-align: center;
float: left;
- border-bottom: .5px solid lightgrey;
padding: 10px 0;
+ border-bottom: 1px solid #ddd;
font-family: OpenSansSemiBold;
}
}
+ .day-heading{
+ position: absolute;
+ top: 55px;
+ }
+ .error{
+ color: #da1e28;
+ padding-top: 5px;
+ height: 15px;
+ }
+ .heading-ot-date{
+ font-size: 24px;
+ }
+ .heading-ot{
+ padding-bottom: 10px;
+ }
+ .heading-ot-block{
+ display: inline-block;
+ position: absolute;
+ left: 24px;
+ }
+ .notesTab{
+ width: calc(100% - 10px);
+ height: 30px;
+ color: #161616;
+ &:hover{
+ background-color: #EDF5FF;
+ }
+ }
+ .notes-text{
+ background-color: #FCF4D6;
+ width: calc(100% - 10px);
+ color: #161616;
+ height: auto;
+ border: 1px solid #F1C21B;
+ border-left: 4px solid #F1C21B;
+ display: flex;
+ div{
+ display: inline-block;
+ width: calc(100% - 54px);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+ > * {
+ padding: 8px;
+ }
+ }
.calendar-time-container {
clear: left;
position: absolute;
- top: 36px;
+ top: 94px;
background: #fff;
z-index: 19;
@@ -57,7 +103,7 @@
left: 80px;
overflow: auto;
padding-bottom: 5px;
- top: 36px;
+ top: 95px;
width: calc(100% - 90px);
right: 0;
}
@@ -307,4 +353,10 @@
padding: 0.3%;
border-radius: 4px;
position: absolute;
+ z-index: 20;
+}
+hr{
+ border: 0;
+ border-bottom: 1px solid #ddd;
+ margin-top: 15px;
}
diff --git a/ui/app/styles/ot/_otWeeklyCalendar.scss b/ui/app/styles/ot/_otWeeklyCalendar.scss
index 4082a5d252..52a216d21e 100644
--- a/ui/app/styles/ot/_otWeeklyCalendar.scss
+++ b/ui/app/styles/ot/_otWeeklyCalendar.scss
@@ -6,8 +6,40 @@
text-align: center;
float: left;
border-bottom: .5px solid lightgrey;
- padding: 10px 0;
- font-family: OpenSansSemiBold;
+ padding: 5px 0;
+ .note{
+ border-left: .5px solid lightgrey;
+ width: 100%;
+ height: 33px;
+ &:hover{
+ background-color: #EDF5FF;
+ }
+ }
+ .heading-ot-date{
+ font-size: 24px;
+ }
+ .heading-ot{
+ padding-bottom: 10px;
+ }
+ .notes-text{
+ background-color: #FCF4D6;
+ height: auto;
+ border: 1px solid #F1C21B;
+ border-left: 3px solid #F1C21B;
+ color: #161616;
+ text-align: left;
+ display: flex;
+ div{
+ display: inline-block;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ width: 80%;
+ }
+ > * {
+ padding: 8px 0 8px 8px;
+ }
+ }
}
}
.table-block {
@@ -36,6 +68,103 @@
}
}
}
+ .identifier-ui {
+ position: fixed;
+ z-index: 1000;
+ padding-top: 100px;
+ width: 100%;
+ height: 100%;
+ left: 0;
+ top: 0;
+ overflow: auto;
+ background-color: rgba(0, 0, 0, 0.6);
+
+ .identifier-iframe {
+ background-color: #fefefe;
+ position: relative;
+ margin: auto;
+ border: 1px solid #888;
+ padding: 20px 0;
+ width: 30%;
+ top: 100px;
+ height: 320px;
+
+ @media screen and (max-width: 540px) {
+ width: 90%;
+ }
+
+ @media screen and (min-width: 541px) and (max-width: 1024px) {
+ width: 80%;
+ }
+ .calendar-day-input {
+ background: #fff;
+ border: 1px solid #95989a;
+ outline: none;
+ width: 205px;
+ font-size: 14px;
+ padding: 5px;
+ border-radius: 3px;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
+ transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
+ display: inline-block;
+ color: #000;
+ }
+ button{
+ height: 64px;
+ width: 50%;
+ color: white;
+ border: none;
+ border-radius: 0;
+ background-image: none;
+ position: absolute;
+ bottom: 0;
+ text-align: left;
+ }
+
+ h6{
+ color: black;
+ }
+
+ .save-button{
+ right: 0;
+ background-color: #007d79;
+ }
+ .delete-button{
+ right: 0;
+ background-color: #da1e28;
+ }
+
+ .cancel-button{
+ left: 0;
+ background-color: #39393F;
+ }
+ .notes-text-area{
+ width: 95%;
+ border: 0.5px solid;
+ resize: none;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
+ border-radius: 4px;
+ &:focus{
+ background-color: white;
+ }
+ }
+ }
+
+ .close {
+ color: #aaaaaa;
+ float: right;
+ font-size: 28px;
+ font-weight: bold;
+ margin-bottom: 10px;
+ }
+
+ .close:hover,
+ .close:focus {
+ color: #000;
+ text-decoration: none;
+ cursor: pointer;
+ }
+ }
}
.surgical-block {
margin: 0 1px;
diff --git a/ui/test/unit/ot/controller/otCalendarController.spec.js b/ui/test/unit/ot/controller/otCalendarController.spec.js
index 6ebe806d50..77bb4ff024 100644
--- a/ui/test/unit/ot/controller/otCalendarController.spec.js
+++ b/ui/test/unit/ot/controller/otCalendarController.spec.js
@@ -1,10 +1,11 @@
'use strict';
describe("otCalendarController", function () {
- var scope, controller, q, spinner, state;
+ var scope, controller, q, spinner;
+ var state = jasmine.createSpyObj('$state', ['go']);
var locationService = jasmine.createSpyObj('locationService', ['getAllByTag']);
spinner = jasmine.createSpyObj('spinner', ['forPromise', 'then', 'catch']);
- var surgicalAppointmentService = jasmine.createSpyObj('surgicalAppointmentService', ['getSurgicalBlocksInDateRange', 'getSurgeons']);
+ var surgicalAppointmentService = jasmine.createSpyObj('surgicalAppointmentService', ['getSurgicalBlocksInDateRange', 'getSurgeons', 'getBulkNotes', 'saveNoteForADay']);
var ngDialog = jasmine.createSpyObj('ngDialog', ['open']);
var appService = jasmine.createSpyObj('appService', ['getAppDescriptor']);
var appDescriptor = jasmine.createSpyObj('appDescriptor', ['getConfigValue']);
@@ -69,6 +70,17 @@ describe("otCalendarController", function () {
}
];
+ var notes = [
+ {
+ id: 1,
+ noteText: "note1",
+ noteType: "OT module",
+ noteDate: "2017-02-19T09:00:00.000+0530",
+ uuid: "note1-uuid",
+ location: "location1"
+ }
+ ];
+
locationService.getAllByTag.and.callFake(function () {
return {data: {results: [{uuid: "uuid1", name: "location1"}, {uuid: "uuid2", name: "location2"}]}};
});
@@ -88,10 +100,13 @@ describe("otCalendarController", function () {
scope.dayViewStart = '09:00';
scope.dayViewEnd = '16:30';
scope.dayViewSplit = '60';
+ scope.notesStartDate = false;
+ scope.notesEndDate = false;
scope.viewDate = moment('2017-02-19').toDate();
controller('otCalendarController', {
$scope: scope,
locationService: locationService,
+ $state: state,
$q: q,
spinner: spinner,
surgicalAppointmentService: surgicalAppointmentService,
@@ -110,6 +125,9 @@ describe("otCalendarController", function () {
surgicalAppointmentService.getSurgeons.and.callFake(function () {
return {data: {results: surgeons}};
});
+ surgicalAppointmentService.getBulkNotes.and.callFake(function () {
+ return {data: notes}
+ });
createController();
var intervals = scope.intervals();
@@ -123,6 +141,9 @@ describe("otCalendarController", function () {
surgicalAppointmentService.getSurgeons.and.callFake(function () {
return {data: {results: surgeons}};
});
+ surgicalAppointmentService.getBulkNotes.and.callFake(function () {
+ return {data: notes}
+ });
createController();
var rows = scope.getRowsForCalendar();
@@ -141,6 +162,9 @@ describe("otCalendarController", function () {
surgicalAppointmentService.getSurgeons.and.callFake(function () {
return {data: {results: surgeons}};
});
+ surgicalAppointmentService.getBulkNotes.and.callFake(function () {
+ return {data: notes}
+ });
createController();
expect(locationService.getAllByTag).toHaveBeenCalledWith('Operation Theater');
@@ -156,6 +180,9 @@ describe("otCalendarController", function () {
surgicalAppointmentService.getSurgeons.and.callFake(function () {
return {data: {results: surgeons}};
});
+ surgicalAppointmentService.getBulkNotes.and.callFake(function () {
+ return {data: notes}
+ });
scope.weekOrDay = 'day';
createController();
expect(surgicalAppointmentService.getSurgicalBlocksInDateRange).toHaveBeenCalledWith(scope.viewDate, moment(scope.viewDate).endOf('day'), false, true);
@@ -261,4 +288,140 @@ describe("otCalendarController", function () {
});
});
+ describe('notes', function () {
+ it('should set startDate and endDate to selectedDate when showNotesPopup is called', function () {
+ surgicalAppointmentService.getSurgicalBlocksInDateRange.and.callFake(function () {
+ return {data: {results: weekSurgicalBlocks}};
+ });
+ scope.weekOrDay = 'week';
+ scope.weekStartDate = moment('2020-04-06').toDate();
+ surgicalAppointmentService.getSurgeons.and.callFake(function () {
+ return {data: {results: surgeons}};
+ });
+ surgicalAppointmentService.getBulkNotes.and.callFake(function () {
+ return {data: notes}
+ });
+ createController();
+ const weekStartDate = moment('2023-07-02').toDate();
+ const expectedDate = moment('2023-07-05').toDate();
+ scope.showNotesPopup(weekStartDate, 3);
+ expect(scope.notesStartDate).toEqual(expectedDate);
+ expect(scope.notesEndDate).toEqual(expectedDate);
+ });
+ it('should set startDate and endDate to selectedDate when we try to edit existing note', function () {
+ surgicalAppointmentService.getSurgicalBlocksInDateRange.and.callFake(function () {
+ return {data: {results: weekSurgicalBlocks}};
+ });
+ scope.weekOrDay = 'week';
+ scope.weekStartDate = moment('2020-04-06').toDate();
+ surgicalAppointmentService.getSurgeons.and.callFake(function () {
+ return {data: {results: surgeons}};
+ });
+ surgicalAppointmentService.getBulkNotes.and.callFake(function () {
+ return {data: notes}
+ });
+ createController();
+ const weekStartDate = moment('2023-07-02').toDate();
+ const expectedDate = moment('2023-07-05').toDate();
+ scope.showNotesPopupEdit(weekStartDate, 3, 'note to show');
+ expect(scope.notesStartDate).toEqual(expectedDate);
+ expect(scope.notesEndDate).toEqual(expectedDate);
+ });
+ it('should clear startDate and endDate notes popup is closed', function () {
+ surgicalAppointmentService.getSurgicalBlocksInDateRange.and.callFake(function () {
+ return {data: {results: weekSurgicalBlocks}};
+ });
+ scope.weekOrDay = 'week';
+ scope.weekStartDate = moment('2020-04-06').toDate();
+ surgicalAppointmentService.getSurgeons.and.callFake(function () {
+ return {data: {results: surgeons}};
+ });
+ surgicalAppointmentService.getBulkNotes.and.callFake(function () {
+ return {data: notes}
+ });
+ createController();
+ const weekStartDate = moment('2023-07-02').toDate();
+ const expectedDate = moment('2023-07-05').toDate();
+ scope.showNotesPopupEdit(weekStartDate, 3, 'note to show');
+ expect(scope.notesStartDate).toEqual(expectedDate);
+ expect(scope.notesEndDate).toEqual(expectedDate);
+ scope.closeNotes();
+ expect(scope.notesStartDate).toEqual(undefined);
+ expect(scope.notesEndDate).toEqual(undefined);
+ expect(scope.otNotesField).toEqual('');
+ });
+ it('should set the notes popup fields and save', function () {
+ surgicalAppointmentService.getSurgicalBlocksInDateRange.and.callFake(function () {
+ return {data: {results: weekSurgicalBlocks}};
+ });
+ scope.weekOrDay = 'week';
+ scope.weekStartDate = moment('2020-04-06').toDate();
+ surgicalAppointmentService.getSurgeons.and.callFake(function () {
+ return {data: {results: surgeons}};
+ });
+ surgicalAppointmentService.getBulkNotes.and.callFake(function () {
+ return {data: notes}
+ });
+ createController();
+ const viewDate = moment('2023-07-05').toDate();
+ scope.setNotesStartDate(viewDate);
+ scope.setNotesEndDate(viewDate);
+ scope.setNotes('note to show');
+ scope.saveNotes();
+ expect(scope.notesStartDate).toEqual(viewDate);
+ expect(scope.notesEndDate).toEqual(viewDate);
+ expect(scope.otNotesField).toEqual('note to show');
+ });
+ it('should set error field for empty notes when we try to save empty notes', function () {
+ surgicalAppointmentService.getSurgicalBlocksInDateRange.and.callFake(function () {
+ return {data: {results: weekSurgicalBlocks}};
+ });
+ scope.weekOrDay = 'week';
+ scope.weekStartDate = moment('2020-04-06').toDate();
+ surgicalAppointmentService.getSurgeons.and.callFake(function () {
+ return {data: {results: surgeons}};
+ });
+ surgicalAppointmentService.getBulkNotes.and.callFake(function () {
+ return {data: notes}
+ });
+ createController();
+ scope.setNotes('');
+ scope.saveNotes();
+ expect(scope.emptyNoteError).toEqual(true);
+ });
+ it('should set error field when start Date is before endDate', function () {
+ surgicalAppointmentService.getSurgicalBlocksInDateRange.and.callFake(function () {
+ return {data: {results: weekSurgicalBlocks}};
+ });
+ scope.weekOrDay = 'week';
+ scope.weekStartDate = moment('2020-04-06').toDate();
+ surgicalAppointmentService.getSurgeons.and.callFake(function () {
+ return {data: {results: surgeons}};
+ });
+ surgicalAppointmentService.getBulkNotes.and.callFake(function () {
+ return {data: notes}
+ });
+ createController();
+ scope.setNotesStartDate(moment('2023-07-05').toDate());
+ scope.setNotesEndDate(moment('2023-07-02').toDate());
+ scope.saveNotes();
+ expect(scope.startDateBeforeEndDateError).toEqual(true);
+ });
+ it('should get styling of last block', function () {
+ surgicalAppointmentService.getSurgicalBlocksInDateRange.and.callFake(function () {
+ return {data: {results: weekSurgicalBlocks}};
+ });
+ scope.weekOrDay = 'week';
+ scope.weekStartDate = moment('2020-04-06').toDate();
+ surgicalAppointmentService.getSurgeons.and.callFake(function () {
+ return {data: {results: surgeons}};
+ });
+ surgicalAppointmentService.getBulkNotes.and.callFake(function () {
+ return {data: notes}
+ });
+ createController();
+ const style = scope.styleForBlock(6);
+ expect(style).toEqual({ 'border-right': '.5px solid lightgrey'});
+ });
+ });
});
diff --git a/ui/test/unit/ot/services/surgicalAppointmentService.spec.js b/ui/test/unit/ot/services/surgicalAppointmentService.spec.js
index 9bb511ae17..1c6d7163ee 100644
--- a/ui/test/unit/ot/services/surgicalAppointmentService.spec.js
+++ b/ui/test/unit/ot/services/surgicalAppointmentService.spec.js
@@ -97,7 +97,7 @@ describe('surgicalAppointmentService', function () {
expect(mockHttp.get).toHaveBeenCalled();
expect(mockHttp.get.calls.mostRecent().args[0]).toBe("/openmrs/ws/rest/v1/surgicalBlock");
- expect(mockHttp.get.calls.mostRecent().args[1].params).toEqual({ startDatetime : '2039-08-26T12:00:00.000+0000', endDatetime : '2039-08-26T15:00:00.000+0000',includeVoided: false, activeBlocks: true, v: "custom:(id,uuid," +
+ expect(mockHttp.get.calls.mostRecent().args[1].params).toEqual({ startDatetime : '2039-08-26T12:00:00.000+0000', endDatetime : '2039-08-26T15:00:00.000+0000', includeVoided: false, activeBlocks: true, v: "custom:(id,uuid," +
"provider:(uuid,person:(uuid,display),attributes:(attributeType:(display),value,voided))," +
"location:(uuid,name),startDatetime,endDatetime,surgicalAppointments:(id,uuid,patient:(uuid,display,person:(age))," +
"actualStartDatetime,actualEndDatetime,status,notes,sortWeight,bedNumber,bedLocation,surgicalAppointmentAttributes))"});