diff --git a/core/ajax/mobile.ajax.php b/core/ajax/mobile.ajax.php index 893cfd2c..378aca98 100755 --- a/core/ajax/mobile.ajax.php +++ b/core/ajax/mobile.ajax.php @@ -59,6 +59,20 @@ } ajax::success($return); } + + if (init('action') == 'getNotificationsV2') { + $return = ''; + $iq = init('iq'); + $mobile = eqLogic::byLogicalId($iq, 'mobile'); + if (is_object($mobile)) { + $return = mobile::getNotificationsV2($iq); + } + ajax::success($return); + } + + if (init('action') == 'removeNotificationV2') { + ajax::success(mobile::removeNotificationV2(init('iq', ''), init('id', ''))); + } // APP V1 diff --git a/core/class/mobile.class.php b/core/class/mobile.class.php index 3c1d0e08..89dd8a4b 100755 --- a/core/class/mobile.class.php +++ b/core/class/mobile.class.php @@ -34,6 +34,16 @@ class mobile extends eqLogic /* * ***********************Methode static*************************** */ + /** + * Core callback to returns the directory of data not to be saved in the Jeedom backup + * + * @return array + */ + public static function backupExclude() + { + return ['data']; + } + public static function cronDaily() { foreach (eqLogic::byType('mobile') as $mobile) { @@ -1002,6 +1012,48 @@ public static function notification($arn, $os, $titre, $message, $type, $idNotif log::add('mobile', 'debug', '|└────────────────────'); } + /** + * Get all notifications from Iq + * Call by ajax getNotificationsV2 + * @return array + */ + public static function getNotificationsV2($Iq) + { + $return = __('Aucune notification.', __FILE__); + $filePath = dirname(__FILE__) . '/../data/notifications/' . $Iq . '.json'; + if (file_exists($filePath)) { + $notifs = json_decode(file_get_contents($filePath), true); + if (is_array($notifs) && count($notifs) > 0) $return = json_encode(array_reverse($notifs)); + } + return $return; + } + + /** + * remove notification from Id into filepath id + * Call by ajax removeNotificationV2 + */ + public static function removeNotificationV2($_iq, $_id) + { + $pathNotificationData = '/../data/notifications'; + $filePath = dirname(__FILE__) . $pathNotificationData . '/' . $_iq . '.json'; + if (file_exists($filePath)) { + $notificationsContent = file_get_contents($filePath); + $notifications = json_decode($notificationsContent, true); + if ($notifications === null) { + throw new Exception(__('Fichier de notification vide !.', __FILE__)); + } + if (isset($notifications[$_id])) { + unset($notifications[$_id]); + file_put_contents($filePath, json_encode($notifications)); + return count($notifications); + } else { + throw new Exception(__('Id notification introuvable :', __FILE__) . ' ' . $_id); + } + } else { + throw new Exception(__('Fichier de notifications non trouvé : ', __FILE__) . $filePath); + } + } + /** * Create and update cmd geoloc * Call By api : setConfigs @@ -1841,7 +1893,7 @@ public function execute($_options = array()) $askParams = json_decode($notif['data']['askParams'], true); $notifTime = strtotime($notif['data']['date']); $currentTime = time(); - $timeout = $askParams['timeout'] / 1000; + $timeout = (isset($askParams['timeout'])) ? $askParams['timeout'] / 1000 : 0; return $notif['data']['askVariable'] == 'rien' || ($currentTime - $notifTime) < $timeout; }); file_put_contents($filePath, json_encode($notifs)); @@ -1850,7 +1902,7 @@ public function execute($_options = array()) case 3: $notifs = json_decode(file_get_contents($filePath), true); $notifs = array_filter($notifs, function ($notif) { - return $notif['data']['choiceAsk'] == ''; + return !isset($notif['data']['choiceAsk']) || $notif['data']['choiceAsk'] == ''; }); file_put_contents($filePath, json_encode($notifs)); log::add('mobile', 'info', '| Suppression des asks répondus effectuée'); diff --git a/desktop/css/notification.css b/desktop/css/notification.css new file mode 100644 index 00000000..75786447 --- /dev/null +++ b/desktop/css/notification.css @@ -0,0 +1,129 @@ +.notification-box { + padding: 32px; +} + +.notification-step { + display: flex; + margin-bottom: 32px; + position: relative; +} + +.notification-step:last-child { + margin-bottom: 0px; +} + +.notification-line { + position: absolute; + left: 114px; + top: 40px; + bottom: -32px; + width: 2px; + background-color: var(--logo-primary-color); + z-index: 1; +} + +.notification-date { + display: flex; + height: 40px; + align-items: center; + margin-right: 16px; + width: 79px; + font-size: 12px; + padding: 5px; + text-align: center; + border-radius: var(--border-radius) var(--border-radius) var(--border-radius) var(--border-radius) !important; + background-color: var(--form-bg-color); + /* z-index: 1;*/ +} + +.notification-step:last-child .notification-line { + display: none; +} + +.notification-circle { + width: 40px; + height: 40px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin-right: 16px; + background-color: var(--form-bg-color); + border: 2px solid var(--txt-color); + z-index: 2; +} + +.ask-timeout .notification-circle { + color: var(--linkHoverLight-color) !important; + background-color: var(--al-info-color) !important; + border: none; +} + +.ask-success .notification-circle { + color: var(--linkHoverLight-color) !important; + background-color: var(--al-success-color) !important; + border: none; +} + +.ask-in-progress .notification-circle { + color: var(--linkHoverLight-color) !important; + background-color: var(--al-warning-color) !important; + border: none; +} + +.stepper-critical .notification-circle { + border: 1px solid red; +} + +.notification-content { + flex: 1; + padding: 10px; + border-radius: var(--border-radius) var(--border-radius) var(--border-radius) var(--border-radius); + background-color: var(--form-bg-color); +} + +.notification-img { + margin-top: 10px; +} + +.notification-img img { + max-width: 250px; +} + +.notification-title { + font-weight: 600; + margin-bottom: 4px; + font-size: 18px; +} + +.notification-status { + font-size: 13px; + display: inline-block; + padding: 2px 8px; + border-radius: 12px; + margin-top: 4px; +} + +.ask-success .notification-status { + color: var(--linkHoverLight-color) !important; + background-color: var(--al-success-color) !important; + border: none; +} + +.ask-timeout .notification-status { + color: var(--linkHoverLight-color) !important; + background-color: var(--al-info-color) !important; + border: none; +} + +.ask-in-progress .notification-status { + color: var(--linkHoverLight-color) !important; + background-color: var(--al-warning-color) !important; + border: none; +} + +.notification-button { + display: flex; + margin-bottom: 32px; + justify-content: end; +} \ No newline at end of file diff --git a/desktop/js/mobile.js b/desktop/js/mobile.js index 21e385eb..5861fb3f 100755 --- a/desktop/js/mobile.js +++ b/desktop/js/mobile.js @@ -54,6 +54,7 @@ document.querySelector("#bt_pluginmobile")?.addEventListener("click", function ( contentUrl: "index.php?v=d&plugin=mobile&modal=AppV1Plugin", }); }); + document.querySelector("#bt_piecemobile")?.addEventListener("click", function (event) { jeeDialog.dialog({ id: "objectsModal", @@ -61,6 +62,7 @@ document.querySelector("#bt_piecemobile")?.addEventListener("click", function (e contentUrl: "index.php?v=d&plugin=mobile&modal=AppV1Piece", }); }); + document.querySelector("#bt_scenariomobile")?.addEventListener("click", function (event) { jeeDialog.dialog({ id: "scenariosModal", @@ -68,6 +70,7 @@ document.querySelector("#bt_scenariomobile")?.addEventListener("click", function contentUrl: "index.php?v=d&plugin=mobile&modal=AppV1Scenario", }); }); + document.querySelector("#bt_regenConfig")?.addEventListener("click", function (event) { domUtils.ajax({ type: "POST", @@ -89,6 +92,48 @@ document.querySelector("#bt_regenConfig")?.addEventListener("click", function (e }); }); +// NotificationsV2 +document.querySelector(".notification-box")?.addEventListener("click", function (event) { + var _target = null + if (_target = event.target.closest('.bt_removeNotification')) { + let notification = _target.closest('.notification-step') + let id = notification.getAttribute('data-id'); + let iq = notification.getAttribute('data-iq'); + domUtils.ajax({ + type: "POST", + url: "plugins/mobile/core/ajax/mobile.ajax.php", + data: { + action: "removeNotificationV2", + id: id, + iq: iq + }, + dataType: "json", + error: function (request, status, error) { + domUtils.handleAjaxError(request, status, error) + }, + success: function (data) { + if (data.state != "ok") { + jeedomUtils.showAlert({ message: data.result, level: "danger" }) + return + } + notification.remove() + if (data.result == '0' && is_object(el = document.querySelector(".notification-box"))) { + el.innerHTML = '
{{Aucune notifications}}
' + } + jeedomUtils.showAlert({ message: "{{Notification supprimées.}}", level: "success"}); + }, + }); + return + } + + if (_target = event.target.closest('.bt_refreshNotifications')) { + let iq = _target.getAttribute('data-iq') + printNotification(iq) + jeedomUtils.showAlert({ message: "{{Terminé.}}", level: "success"}); + return + } +}); + // Copie pour monitoring var toCopy = document.getElementById("to-copy-monitoring"); var arnComplet = document.getElementById("arnComplet"); @@ -107,14 +152,15 @@ document.getElementById("copy-monitoring")?.addEventListener("click", function ( function printEqLogic(_eqLogic) { let appVersion = _eqLogic.configuration.appVersion; - console.log(appVersion) if (appVersion == 2) { document.querySelectorAll(".paramV1").unseen() document.querySelectorAll(".paramV2").seen() + printNotification(_eqLogic.logicalId) } else { document.querySelectorAll(".paramV2").unseen() document.querySelectorAll(".paramV1").seen() - + let el = document.querySelector(".notification-box"); + el.innerHTML = '
Compatible AppV2 uniquement.
' } // AppV1 @@ -243,7 +289,6 @@ function printEqLogic(_eqLogic) { } function addCmdToTable(_cmd) { - console.log('addCmdToTable') if (document.getElementById('table_cmd') == null) return if (!isset(_cmd)) { var _cmd = { configuration: {} } @@ -307,6 +352,96 @@ function addCmdToTable(_cmd) { }) } +function printNotification(_iq) { + domUtils.ajax({ + type: "POST", + url: "plugins/mobile/core/ajax/mobile.ajax.php", + data: { + action: "getNotificationsV2", + iq: _iq, + }, + dataType: "json", + global: false, + error: function (request, status, error) { + domUtils.handleAjaxError(request, status, error) + }, + success: function (data) { + if (data.state != "ok") { + jeedomUtils.showAlert({ message: data.result, level: "danger" }) + return + } + + let el = document.querySelector(".notification-box"); + + try { + var objectData = JSON.parse(data.result); + } catch { + el.innerHTML = '
' + data.result + '
' + return + } + + if (typeof objectData == "object") { + let notification = '' + notification += '
Rafraichir
' + moment.locale(jeeFrontEnd.language.substring(0, 2)) + for (var i in objectData) { + // ASK + let askStatus = '' + let askChoice = '' + if (isset(objectData[i].data.choiceAsk)) { + askStatus = 'ask-success' + askChoice = objectData[i].data.choiceAsk + } else if (objectData[i].data.askVariable != 'rien') { + let notifTime = moment(objectData[i].data.date, "YYYY-MM-DD hh:mm:ss").unix() + let currentTime = moment().unix() + try { + let askParams = (isset(objectData[i].data.askParams)) ? JSON.parse(objectData[i].data.askParams) : '' + if (isset(askParams.timeout)) { + let timeout = askParams.timeout / 1000 + if ((currentTime - notifTime) > timeout) { + askStatus = 'ask-timeout' + askChoice = '{{Timeout}}' + } else { + askStatus += 'ask-in-progress' + askChoice = '{{En cours...}}' + } + } + } catch { } + } + + notification += '
' + notification += '
' + objectData[i].data.date + '
' + if (objectData[i].data.askVariable != 'rien') { + notification += '
ASK
' + } else if (objectData[i].data.critical == 'true') { + notification += '
N
' + } else if (objectData[i].data.silent == 'true') { + notification += '
NS
' + } else { + notification += '
N
' + } + notification += '
' + notification += '
' + //notification += ' {{Supprimer}}' + notification += '' + notification += '
' + objectData[i].data.title + '
' + notification += '
' + objectData[i].data.body + '
' + if (isset(objectData[i].data.image)) { + notification += '
' + } + if (askChoice != '') notification += '
' + askChoice + '
' + notification += '
' + notification += '
' + //console.log(objectData[i]) + } + el.innerHTML = notification + jeedomUtils.initTooltips(el) + } + }, + }); + +} + // WIZARD var _contentContainer = document.getElementById('wizard_container'); @@ -500,4 +635,4 @@ function allowNavigation(_direction = 'both', _allowed = true) { function exitWizard() { window.location.href = 'index.php?v=d&m=mobile&p=mobile'; -} \ No newline at end of file +} diff --git a/desktop/php/mobile.php b/desktop/php/mobile.php index ead82a54..cf288f8f 100755 --- a/desktop/php/mobile.php +++ b/desktop/php/mobile.php @@ -178,6 +178,7 @@
  • {{Commandes}}
  • +
  • {{Notifications}}
  • @@ -362,8 +363,14 @@
    +
    +
    +
    Compatible AppV2 uniquement.
    +
    +
    + - \ No newline at end of file +