From 6c4f1ad6249203013176086d977852b68b7ccf0c Mon Sep 17 00:00:00 2001 From: Fabian Breitling <83815772+msfb3@users.noreply.github.com> Date: Thu, 30 Jan 2025 11:09:59 +0100 Subject: [PATCH 1/5] feat(ZMS-3503): added logic to end emergency with checkbox --- zmsadmin/js/block/emergency/index.js | 2 + zmsadmin/js/block/scope/emergencyend.js | 163 ++++++++++++++++++ zmsadmin/js/index.js | 6 + zmsadmin/templates/block/scope/form.twig | 8 +- zmsentities/src/Zmsentities/Schema/Entity.php | 4 +- 5 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 zmsadmin/js/block/scope/emergencyend.js diff --git a/zmsadmin/js/block/emergency/index.js b/zmsadmin/js/block/emergency/index.js index 1751ac346..4e6cb719f 100644 --- a/zmsadmin/js/block/emergency/index.js +++ b/zmsadmin/js/block/emergency/index.js @@ -9,10 +9,12 @@ class View extends BaseView { constructor (element, options) { super(element) + console.log("Options received:", options); this.includeUrl = options.includeurl this.returnTarget = options.returnTarget this.workstationName = ""+options.workstationname this.scope = options.scope + console.log("Scope received:", this.scope); this.data = Object.assign({}, deepGet(this, ['scope', 'status', 'emergency'])) this.minimized = false this.refreshTimer = null diff --git a/zmsadmin/js/block/scope/emergencyend.js b/zmsadmin/js/block/scope/emergencyend.js new file mode 100644 index 000000000..9f685b659 --- /dev/null +++ b/zmsadmin/js/block/scope/emergencyend.js @@ -0,0 +1,163 @@ +import BaseView from '../../lib/baseview' +import $ from 'jquery' +import { deepGet, tryJson, noOp } from '../../lib/utils' +// import { playSound } from '../../lib/audio' + +const DEFAULT_REFRESH_INTERVAL = 15 + +class View extends BaseView { + + constructor (element, options) { + super(element) + console.log("Emergency Options received:", options); + this.includeUrl = options.includeurl + this.returnTarget = options.returnTarget + this.workstationName = ""+options.workstationname + this.scope = options.scope + console.log("Emergency Scope received:", this.scope); + this.data = Object.assign({}, deepGet(this, ['scope', 'status', 'emergency'])) + this.minimized = false + this.refreshTimer = null + this.refreshId = 0 + + this.bindPublicMethods( 'endEmergency') + this.$.find('.emergency__button-end').on('click', this.endEmergency) + this.$.on('keydown', function exitKeyEventListener (ev){ + var key = ev.key; + switch(key) { + case 'Escape': // ESC + console.log('ESC'); + this.minimize; // ToDo: Don't work yet + break; + } + }) + + + // ) + //console.log('Component: Emergency', this) + } + + invalidateRefreshId() { + this.refreshId = this.refreshId + 1 + } + + + loadData () { + const url = `${this.includeUrl}/workstation/status/` + + return new Promise((resolve, reject) => { + $.ajax(url, { + method: 'GET' + }).done(data => { + const emergencyData = deepGet(tryJson(data), ['workstation', 'scope', 'status', 'emergency']) + resolve(emergencyData) + }).fail(err => { + console.log('XHR error', url, err) + reject(err) + }) + }) + } + + + + sendEmergencyCancel() { + this.invalidateRefreshId() + const url = `${this.includeUrl}/scope/${this.scope.id}/emergency/` + + return new Promise((resolve, reject) => { + $.ajax(url, { + method: 'GET' + }).done(() => { + resolve() + }).fail(err => { + console.log('XHR error', url, err) + reject(err) + }) + }) + } + + update (newData) { + this.data = Object.assign({}, this.data, newData) + this.render() + } + + + render () { + const data = this.data + + const activated = parseInt(data.activated, 10) + const acceptedByWorkstation = parseInt(data.acceptedByWorkstation, 10) + const source = data.calledByWorkstation === this.workstationName ? 'self' : 'other' + + let state = 'clear' + if (activated > 0) { + state = 'triggered' + + if (acceptedByWorkstation > -1) { + state = 'help-coming' + } + } + + if (this.minimized) { + this.$.attr('data-minimized', true) + } else { + this.$.removeAttr('data-minimized') + } + // Barrierefreiheit + if (state == 'clear') { + this.$.find('.emergency__overlay').attr('hidden', 'hidden') + } else { + this.$.find('.emergency__overlay').removeAttr('hidden') + } + + this.$.attr('data-source', source) + this.$.attr('data-state', state) + this.$.find('.emergency__source').text((data.calledByWorkstation === '0') ? 'Tresen' : `Platz ${data.calledByWorkstation}`) + this.$.find('.emergency__help-from').text((data.acceptedByWorkstation === '0' ? 'Tresen' : `Platz ${data.acceptedByWorkstation}`)) + } + + endEmergency() { + this.update({activated: "0", calledByWorkstation: "-1", acceptedByWorkstation: "-1"}) + this.sendEmergencyCancel() + console.log('end emergency'); + this.removeFocusTrap(this.$.find('.emergency__overlay-layout')); + } + + removeFocusTrap(elem) { + var tabbable = elem.find('select, input, textarea, button, a, *[role="button"]'); + tabbable.unbind('keydown'); + } + + addFocusTrap(elem) { + // Get all focusable elements inside our trap container + var tabbable = elem.find('select, input, textarea, button, a, *[role="button"]'); + // Focus the first element + if (tabbable.length ) { + tabbable.filter(':visible').first().focus(); + //console.log(tabbable.filter(':visible').first()); + } + tabbable.bind('keydown', function (e) { + if (e.keyCode === 9) { // TAB pressed + // we need to update the visible last and first focusable elements everytime tab is pressed, + // because elements can change their visibility + var firstVisible = tabbable.filter(':visible').first(); + var lastVisible = tabbable.filter(':visible').last(); + if (firstVisible && lastVisible) { + if (e.shiftKey && ( $(firstVisible)[0] === $(this)[0] ) ) { + // TAB + SHIFT pressed on first visible element + e.preventDefault(); + lastVisible.focus(); + } + else if (!e.shiftKey && ( $(lastVisible)[0] === $(this)[0] ) ) { + // TAB pressed pressed on last visible element + e.preventDefault(); + firstVisible.focus(); + } + } + } + }); + } + +} + +export default View; diff --git a/zmsadmin/js/index.js b/zmsadmin/js/index.js index 6b1ec817f..92e2c2dec 100644 --- a/zmsadmin/js/index.js +++ b/zmsadmin/js/index.js @@ -26,6 +26,7 @@ import PickupKeyboardHandheldView from "./page/pickup/keyboard-handheld" import StatisticView from './page/statistic' import LoginScopeSelectView from './block/scope/loginselectform' +import EmergencyEnd from './block/scope/emergencyend' //import AvailabilityDayPage from './page/availabilityDay' import WeekCalendarPage from './page/weekCalendar' import printScopeAppointmentsByDay from './page/scopeAppointmentsByDay/print' @@ -108,6 +109,10 @@ $('[data-scope-select-form]').each(function () { new LoginScopeSelectView(this, getDataAttributes(this)); }) +$('.emergency-end').each(function () { + new EmergencyEnd(this, getDataAttributes(this)); +}) + $('.pickup-view').each(function () { new PickupView(this, getDataAttributes(this)); }) @@ -139,6 +144,7 @@ DialogHandler.hideMessages(); // Say hello console.log("Welcome to the ZMS admin interface..."); +console.log("Hello") // hook up react components diff --git a/zmsadmin/templates/block/scope/form.twig b/zmsadmin/templates/block/scope/form.twig index 568b5dcf8..d527fef83 100644 --- a/zmsadmin/templates/block/scope/form.twig +++ b/zmsadmin/templates/block/scope/form.twig @@ -627,7 +627,12 @@