From 98b017831c5c7d6e75d5ebabcb22fd30fa050a97 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Wed, 22 May 2024 00:22:05 -0300 Subject: [PATCH] final --- code/_onclick/hud/ai.dm | 2 +- code/_onclick/hud/robot.dm | 2 +- code/datums/alarm.dm | 6 +- code/datums/station_alert.dm | 103 +++++++++++++++ code/game/machinery/computer/station_alert.dm | 34 ++--- code/modules/mob/living/silicon/ai/ai.dm | 54 ++------ .../modules/mob/living/silicon/robot/robot.dm | 39 ++---- .../mob/living/silicon/robot/robot_defines.dm | 4 +- code/modules/mob/living/silicon/silicon.dm | 2 +- .../simple_animal/friendly/drone/_drone.dm | 4 +- .../file_system/programs/alarm.dm | 24 ++-- tgstation.dme | 1 + .../interfaces/NtosStationAlertConsole.js | 4 +- .../tgui/interfaces/StationAlertConsole.js | 118 ++++++++++-------- 14 files changed, 217 insertions(+), 180 deletions(-) create mode 100644 code/datums/station_alert.dm diff --git a/code/_onclick/hud/ai.dm b/code/_onclick/hud/ai.dm index 5f8b10fd31..f2ef2e73a2 100644 --- a/code/_onclick/hud/ai.dm +++ b/code/_onclick/hud/ai.dm @@ -74,7 +74,7 @@ if(..()) return var/mob/living/silicon/ai/AI = usr - AI.ai_alerts() + AI.alert_control.ui_interact(AI) /atom/movable/screen/ai/announcement name = "Make Vox Announcement" diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index f905c31aa1..35fd31cbdb 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -361,7 +361,7 @@ if(.) return var/mob/living/silicon/robot/borgo = usr - borgo.robot_alerts() + borgo.alert_control.ui_interact(borgo) /atom/movable/screen/robot/thrusters name = "ion thrusters" diff --git a/code/datums/alarm.dm b/code/datums/alarm.dm index 64870fd203..7fc2245949 100644 --- a/code/datums/alarm.dm +++ b/code/datums/alarm.dm @@ -114,8 +114,8 @@ src.allowed_z_levels = allowed_z_levels src.allowed_areas = allowed_areas for(var/alarm_type in alarms_to_listen_for) - RegisterSignal(SSdcs, COMSIG_ALARM_FIRE(alarm_type), .proc/add_alarm) - RegisterSignal(SSdcs, COMSIG_ALARM_CLEAR(alarm_type), .proc/clear_alarm) + RegisterSignal(SSdcs, COMSIG_ALARM_FIRE(alarm_type), PROC_REF(add_alarm)) + RegisterSignal(SSdcs, COMSIG_ALARM_CLEAR(alarm_type), PROC_REF(clear_alarm)) return ..() @@ -147,7 +147,7 @@ var/list/cameras = source_area.cameras if(optional_camera) cameras = list(optional_camera) // This will cause harddels, so we need to clear manually - RegisterSignal(optional_camera, COMSIG_PARENT_QDELETING, .proc/clear_camera_ref, override = TRUE) //It's just fine to override, cause we clear all refs in the proc + RegisterSignal(optional_camera, COMSIG_PARENT_QDELETING, PROC_REF(clear_camera_ref), override = TRUE) //It's just fine to override, cause we clear all refs in the proc //This does mean that only the first alarm of that camera type in the area will send a ping, but jesus what else can ya do alarms_of_our_type[source_area.name] = list(source_area, cameras, list(handler)) diff --git a/code/datums/station_alert.dm b/code/datums/station_alert.dm new file mode 100644 index 0000000000..edec9f5cb5 --- /dev/null +++ b/code/datums/station_alert.dm @@ -0,0 +1,103 @@ +/datum/station_alert + /// Holder of the datum + var/holder + /// List of all alarm types we are listening to + var/list/alarm_types + /// Listens for alarms, provides the alarms list for our UI + var/datum/alarm_listener/listener + /// Title of our UI + var/title + /// If UI will also show and allow jumping to cameras connected to each alert area + var/camera_view + +/datum/station_alert/ui_host(mob/user) + return holder + +/datum/station_alert/New(holder, list/alarm_types, list/listener_z_level, list/listener_areas, title = "Station Alerts", camera_view = FALSE) + src.holder = holder + src.alarm_types = alarm_types + src.title = title + src.camera_view = camera_view + listener = new(alarm_types, listener_z_level, listener_areas) + +/datum/station_alert/Destroy() + QDEL_NULL(listener) + return ..() + +/datum/station_alert/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "StationAlertConsole", title) + ui.open() + +/datum/station_alert/ui_data(mob/user) + var/list/data = list() + data["cameraView"] = camera_view + data["alarms"] = list() + var/list/nominal_types = alarm_types.Copy() + var/list/alarms = listener.alarms + for(var/alarm_type in alarms) + var/list/alarm_category = list( + "name" = alarm_type, + "alerts" = list(), + ) + var/list/alerts = alarms[alarm_type] + for(var/alert in alerts) + var/list/alert_details = alerts[alert] + alarm_category["alerts"] += list(list( + "name" = get_area_name(alert_details[1], TRUE), + "cameras" = camera_view ? length(alert_details[2]) : null, + "sources" = camera_view ? length(alert_details[3]) : null, + "ref" = camera_view ? REF(alert) : null, + )) + data["alarms"] += list(alarm_category) + nominal_types -= alarm_type + if(length(nominal_types)) + for(var/nominal_type in nominal_types) + var/list/nominal_category = list( + "name" = nominal_type, + "alerts" = list(), + ) + data["alarms"] += list(nominal_category) + return data + +/datum/station_alert/ui_act(action, params) + . = ..() + if(.) + return + + switch(action) + if("select_camera") + var/mob/living/silicon/ai/ai = usr + if(!istype(ai)) + return + + var/list/alarms = listener.alarms + var/list/alerts = list() + for(var/alarm_type in alarms) + alerts += alarms[alarm_type] + + var/list/our_alert = locate(params["alert"]) in alerts + if(!length(our_alert)) + return + var/chosen_alert = alerts[our_alert] + var/list/cameras = chosen_alert[2] + if(!length(cameras)) + return + var/list/named_cameras = list() + for(var/obj/machinery/camera/camera in cameras) + named_cameras[camera.c_tag] = camera + + var/chosen_camera + if(length(named_cameras) == 1) + chosen_camera = named_cameras[1] + else + chosen_camera = tgui_input_list(ai, "Choose a camera to jump to", "Camera Selection", named_cameras) + if(!chosen_camera) + return + var/obj/machinery/camera/selected_camera = named_cameras[chosen_camera] + if(!selected_camera.can_use()) + to_chat(ai, span_warning("Camera is unavailable!")) + return + ai.switchCamera(selected_camera) + return TRUE diff --git a/code/game/machinery/computer/station_alert.dm b/code/game/machinery/computer/station_alert.dm index 8810c79932..ccac91d39a 100644 --- a/code/game/machinery/computer/station_alert.dm +++ b/code/game/machinery/computer/station_alert.dm @@ -4,42 +4,26 @@ icon_screen = "alert:0" icon_keyboard = "atmos_key" circuit = /obj/item/circuitboard/computer/stationalert - ///Listens for alarms, provides the alarms list for our ui - var/datum/alarm_listener/listener - light_color = LIGHT_COLOR_CYAN + /// Station alert datum for showing alerts UI + var/datum/station_alert/alert_control /obj/machinery/computer/station_alert/Initialize(mapload) - listener = new(list(ALARM_ATMOS, ALARM_FIRE, ALARM_POWER), list(z)) + alert_control = new(src, list(ALARM_ATMOS, ALARM_FIRE, ALARM_POWER), list(z), title = name) return ..() /obj/machinery/computer/station_alert/Destroy() - QDEL_NULL(listener) + QDEL_NULL(alert_control) return ..() -/obj/machinery/computer/station_alert/ui_interact(mob/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "StationAlertConsole", name) - ui.open() - -/obj/machinery/computer/station_alert/ui_data(mob/user) - var/list/data = list() - - data["alarms"] = list() - var/list/alarms = listener.alarms - for(var/alarm_type in alarms) - data["alarms"][alarm_type] = list() - for(var/area_name in alarms[alarm_type]) - data["alarms"][alarm_type] += area_name - - return data +/obj/machinery/computer/station_alert/ui_interact(mob/user) + alert_control.ui_interact(user) /obj/machinery/computer/station_alert/on_machine_stat_update(stat) if(stat & BROKEN) - listener.prevent_alarm_changes() + alert_control.listener.prevent_alarm_changes() else - listener.allow_alarm_changes() + alert_control.listener.allow_alarm_changes() /obj/machinery/computer/station_alert/update_overlays() . = ..() @@ -49,7 +33,7 @@ . |= "[icon_keyboard]_off" return . |= icon_keyboard - if(length(listener.alarms)) + if(length(alert_control.listener.alarms)) overlay_state = "alert:2" else overlay_state = "alert:0" diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 534a557b82..65288498ba 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -37,7 +37,6 @@ var/aiRestorePowerRoutine = 0 var/requires_power = POWER_REQ_ALL var/can_be_carded = TRUE - var/viewalerts = 0 var/icon/holo_icon //Female is assigned when AI is created. var/obj/controlled_equipment //A piece of equipment, to determine whether to relaymove or use the AI eye. var/radio_enabled = TRUE //Determins if a carded AI can speak with its built in radio or not. @@ -100,8 +99,8 @@ var/emote_display = "Neutral" //text string of the current emote we set for the status displays, to prevent logins resetting it. var/datum/robot_control/robot_control - ///Alarm listener datum, handes caring about alarm events and such - var/datum/alarm_listener/listener + /// Station alert datum for showing alerts UI + var/datum/station_alert/alert_control ///remember AI's last location var/atom/lastloc interaction_range = INFINITY @@ -183,9 +182,9 @@ builtInCamera = new (src) builtInCamera.network = list("ss13") - listener = new(list(ALARM_ATMOS, ALARM_FIRE, ALARM_POWER, ALARM_CAMERA, ALARM_BURGLAR, ALARM_MOTION), list(z)) - RegisterSignal(listener, COMSIG_ALARM_TRIGGERED, .proc/alarm_triggered) - RegisterSignal(listener, COMSIG_ALARM_CLEARED, .proc/alarm_cleared) + alert_control = new(src, list(ALARM_ATMOS, ALARM_FIRE, ALARM_POWER, ALARM_CAMERA, ALARM_BURGLAR, ALARM_MOTION), list(z), camera_view = TRUE) + RegisterSignal(alert_control.listener, COMSIG_ALARM_TRIGGERED, PROC_REF(alarm_triggered)) + RegisterSignal(alert_control.listener, COMSIG_ALARM_CLEARED, PROC_REF(alarm_cleared)) /mob/living/silicon/ai/Destroy() GLOB.ai_list -= src @@ -204,7 +203,7 @@ QDEL_NULL(malf_picker) QDEL_NULL(doomsday_device) QDEL_NULL(robot_control) - QDEL_NULL(listener) + QDEL_NULL(alert_control) QDEL_NULL(aiMulti) QDEL_NULL(aiPDA) malfhack = null @@ -278,39 +277,6 @@ Module: [connected_robot.designation] | Loc: [get_area_name(connected_robot, TRUE)] | Status: [robot_status]" . += "AI shell beacons detected: [LAZYLEN(GLOB.available_ai_shells)]" //Count of total AI shells -/mob/living/silicon/ai/proc/ai_alerts() - var/dat = "Current Station Alerts\n" - dat += "Close

" - var/list/alarms = listener.alarms - for (var/alarm_type in alarms) - dat += "[alarm_type]
\n" - var/list/alerts = alarms[alarm_type] - if (length(alerts)) - for (var/alarm in alerts) - var/list/alm = alerts[alarm] - var/area/A = alm[1] - var/C = alm[2] - var/list/sources = alm[3] - dat += "" - if (C && istype(C, /list)) - var/dat2 = "" - for (var/obj/machinery/camera/I in C) - dat2 += "[(dat2=="") ? "" : " | "][I.c_tag]" - dat += "-- [A.name] ([(dat2!="") ? dat2 : "No Camera"])" - else if (C && istype(C, /obj/machinery/camera)) - var/obj/machinery/camera/Ctmp = C - dat += "-- [A.name] ([Ctmp.c_tag])" - else - dat += "-- [A.name] (No Camera)" - if (sources.len > 1) - dat += "- [sources.len] sources" - dat += "
\n" - else - dat += "-- All Systems Nominal
\n" - dat += "
\n" - viewalerts = 1 - src << browse(dat, "window=aialerts&can_close=0") - /mob/living/silicon/ai/proc/ai_call_shuttle() if(control_disabled) to_chat(usr, "Wireless control is disabled!") @@ -438,15 +404,13 @@ return ..() if (href_list["mach_close"]) - if (href_list["mach_close"] == "aialerts") - viewalerts = 0 var/t1 = "window=[href_list["mach_close"]]" unset_machine() src << browse(null, t1) if (href_list["switchcamera"]) switchCamera(locate(href_list["switchcamera"])) in GLOB.cameranet.cameras if (href_list["showalerts"]) - ai_alerts() + alert_control.ui_interact(src) #ifdef AI_VOX if(href_list["say_word"]) play_vox_word(href_list["say_word"], null, src) @@ -572,15 +536,11 @@ queueAlarm("--- [alarm_type] alarm detected in [home_name]! ([dat2])", alarm_type) else queueAlarm("--- [alarm_type] alarm detected in [home_name]! (No Camera)", alarm_type) - if (viewalerts) - ai_alerts() return TRUE /mob/living/silicon/ai/proc/alarm_cleared(datum/source, alarm_type, area/source_area) SIGNAL_HANDLER queueAlarm("--- [alarm_type] alarm in [source_area.name] has been cleared.", alarm_type, 0) - if(viewalerts) - ai_alerts() //Replaces /mob/living/silicon/ai/verb/change_network() in ai.dm & camera.dm //Adds in /mob/living/silicon/ai/proc/ai_network_change() instead diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 7b2e3103dc..8c39a46f06 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -89,11 +89,11 @@ diag_hud_set_borgcell() logevent("System brought online.") - listener = new(list(ALARM_ATMOS, ALARM_FIRE, ALARM_POWER, ALARM_CAMERA, ALARM_BURGLAR, ALARM_MOTION), list(z)) - RegisterSignal(listener, COMSIG_ALARM_TRIGGERED, .proc/alarm_triggered) - RegisterSignal(listener, COMSIG_ALARM_CLEARED, .proc/alarm_cleared) - listener.RegisterSignal(src, COMSIG_LIVING_PREDEATH, /datum/alarm_listener/proc/prevent_alarm_changes) - listener.RegisterSignal(src, COMSIG_LIVING_REVIVE, /datum/alarm_listener/proc/allow_alarm_changes) + alert_control = new(src, list(ALARM_ATMOS, ALARM_FIRE, ALARM_POWER, ALARM_CAMERA, ALARM_BURGLAR, ALARM_MOTION), list(z)) + RegisterSignal(alert_control.listener, COMSIG_ALARM_TRIGGERED, PROC_REF(alarm_triggered)) + RegisterSignal(alert_control.listener, COMSIG_ALARM_CLEARED, PROC_REF(alarm_cleared)) + alert_control.listener.RegisterSignal(src, COMSIG_LIVING_PREDEATH, /datum/alarm_listener/proc/prevent_alarm_changes) + alert_control.listener.RegisterSignal(src, COMSIG_LIVING_REVIVE, /datum/alarm_listener/proc/allow_alarm_changes) add_verb(src, /mob/living/proc/lay_down) //CITADEL EDIT gimmie rest verb kthx add_verb(src, /mob/living/silicon/robot/proc/rest_style) @@ -138,15 +138,15 @@ QDEL_NULL(inv2) QDEL_NULL(inv3) QDEL_NULL(spark_system) - QDEL_NULL(listener) + QDEL_NULL(alert_control) cell = null return ..() /mob/living/silicon/robot/Topic(href, href_list) . = ..() //Show alerts window if user clicked on "Show alerts" in chat - if (href_list["showalerts"]) - robot_alerts() + if(href_list["showalerts"]) + alert_control.ui_interact(src) /mob/living/silicon/robot/proc/pick_module() if(module.type != /obj/item/robot_module) @@ -206,28 +206,7 @@ if(usr.stat == DEAD) to_chat(src, "Alert: You are dead.") return //won't work if dead - robot_alerts() - -/mob/living/silicon/robot/proc/robot_alerts() - var/dat = "" - var/list/alarms = listener.alarms - for (var/alarm_type in alarms) - dat += "[alarm_type]
\n" - var/list/alerts = alarms[alarm_type] - if (length(alerts)) - for (var/alarm in alerts) - var/list/alm = alerts[alarm] - var/area/A = alm[1] - dat += "" - dat += "-- [A.name]" - dat += "
\n" - else - dat += "-- All Systems Nominal
\n" - dat += "
\n" - - var/datum/browser/alerts = new(usr, "robotalerts", "Current Station Alerts", 400, 410) - alerts.set_content(dat) - alerts.open() + alert_control.ui_interact(src) /mob/living/silicon/robot/proc/ionpulse() if(!ionpulse_on) diff --git a/code/modules/mob/living/silicon/robot/robot_defines.dm b/code/modules/mob/living/silicon/robot/robot_defines.dm index ccbce17b4f..43f02f8e30 100644 --- a/code/modules/mob/living/silicon/robot/robot_defines.dm +++ b/code/modules/mob/living/silicon/robot/robot_defines.dm @@ -24,8 +24,8 @@ /// the last health before updating - to check net change in health var/previous_health - ///Alarm listener datum, handes caring about alarm events and such - var/datum/alarm_listener/listener + /// Station alert datum for showing alerts UI + var/datum/station_alert/alert_control //Hud stuff diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 9740e5c430..bf325062aa 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -96,7 +96,7 @@ alarm_types_clear[type] += 1 if(in_cooldown) return - addtimer(CALLBACK(src, .proc/show_alarms), 3 SECONDS) + addtimer(CALLBACK(src, PROC_REF(show_alarms)), 3 SECONDS) /mob/living/silicon/proc/show_alarms() if(alarms_to_show.len < 5) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index b927178445..2b83f11e2d 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -104,8 +104,8 @@ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) listener = new(list(ALARM_ATMOS, ALARM_FIRE, ALARM_POWER), list(z)) - RegisterSignal(listener, COMSIG_ALARM_TRIGGERED, .proc/alarm_triggered) - RegisterSignal(listener, COMSIG_ALARM_CLEARED, .proc/alarm_cleared) + RegisterSignal(listener, COMSIG_ALARM_TRIGGERED, PROC_REF(alarm_triggered)) + RegisterSignal(listener, COMSIG_ALARM_CLEARED, PROC_REF(alarm_cleared)) listener.RegisterSignal(src, COMSIG_LIVING_PREDEATH, /datum/alarm_listener/proc/prevent_alarm_changes) listener.RegisterSignal(src, COMSIG_LIVING_REVIVE, /datum/alarm_listener/proc/allow_alarm_changes) diff --git a/code/modules/modular_computers/file_system/programs/alarm.dm b/code/modules/modular_computers/file_system/programs/alarm.dm index a0b54153ee..fd9fc0425f 100644 --- a/code/modules/modular_computers/file_system/programs/alarm.dm +++ b/code/modules/modular_computers/file_system/programs/alarm.dm @@ -8,20 +8,21 @@ size = 5 tgui_id = "NtosStationAlertConsole" program_icon = "bell" - var/has_alert = 0 - ///Listens for alarms, manages our listing of alarms - var/datum/alarm_listener/listener + /// If there is any station alert + var/has_alert = FALSE + /// Station alert datum for showing alerts UI + var/datum/station_alert/alert_control /datum/computer_file/program/alarm_monitor/New() //We want to send an alarm if we're in one of the mining home areas //Or if we're on station. Otherwise, die. var/list/allowed_areas = GLOB.the_station_areas + typesof(/area/mine) - listener = new(list(ALARM_ATMOS, ALARM_FIRE, ALARM_POWER), null, allowed_areas) - RegisterSignal(listener, list(COMSIG_ALARM_TRIGGERED, COMSIG_ALARM_CLEARED), .proc/update_alarm_display) + alert_control = new(computer, list(ALARM_ATMOS, ALARM_FIRE, ALARM_POWER), listener_areas = allowed_areas) + RegisterSignal(alert_control.listener, list(COMSIG_ALARM_TRIGGERED, COMSIG_ALARM_CLEARED), PROC_REF(update_alarm_display)) return ..() /datum/computer_file/program/alarm_monitor/Destroy() - QDEL_NULL(listener) + QDEL_NULL(alert_control) return ..() /datum/computer_file/program/alarm_monitor/process_tick() @@ -40,20 +41,13 @@ /datum/computer_file/program/alarm_monitor/ui_data(mob/user) var/list/data = get_header_data() - - data["alarms"] = list() - var/list/alarms = listener.alarms - for(var/alarm_type in alarms) - data["alarms"][alarm_type] = list() - for(var/area in alarms[alarm_type]) - data["alarms"][alarm_type] += area - + data += alert_control.ui_data(user) return data /datum/computer_file/program/alarm_monitor/proc/update_alarm_display() SIGNAL_HANDLER has_alert = FALSE - if(length(listener.alarms)) + if(length(alert_control.listener.alarms)) has_alert = TRUE /datum/computer_file/program/alarm_monitor/run_program(mob/user) diff --git a/tgstation.dme b/tgstation.dme index 2855b6e5e2..9e2969580c 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -505,6 +505,7 @@ #include "code\datums\shuttles.dm" #include "code\datums\soullink.dm" #include "code\datums\spawners_menu.dm" +#include "code\datums\station_alert.dm" #include "code\datums\tgs_event_handler.dm" #include "code\datums\verbs.dm" #include "code\datums\view.dm" diff --git a/tgui/packages/tgui/interfaces/NtosStationAlertConsole.js b/tgui/packages/tgui/interfaces/NtosStationAlertConsole.js index 67666f2cdf..e39a38dd73 100644 --- a/tgui/packages/tgui/interfaces/NtosStationAlertConsole.js +++ b/tgui/packages/tgui/interfaces/NtosStationAlertConsole.js @@ -4,8 +4,8 @@ import { StationAlertConsoleContent } from './StationAlertConsole'; export const NtosStationAlertConsole = () => { return ( + width={335} + height={587}> diff --git a/tgui/packages/tgui/interfaces/StationAlertConsole.js b/tgui/packages/tgui/interfaces/StationAlertConsole.js index 8773a1b655..2b8b30784d 100644 --- a/tgui/packages/tgui/interfaces/StationAlertConsole.js +++ b/tgui/packages/tgui/interfaces/StationAlertConsole.js @@ -1,12 +1,18 @@ +import { sortBy } from 'common/collections'; +import { flow } from 'common/fp'; import { useBackend } from '../backend'; -import { Section } from '../components'; +import { Button, Section, Stack } from '../components'; import { Window } from '../layouts'; -export const StationAlertConsole = () => { +export const StationAlertConsole = (props, context) => { + const { data } = useBackend(context); + const { + cameraView, + } = data; return ( + width={cameraView ? 390 : 345} + height={587}> @@ -15,55 +21,65 @@ export const StationAlertConsole = () => { }; export const StationAlertConsoleContent = (props, context) => { - const { data } = useBackend(context); - const categories = data.alarms || []; - const fire = categories['Fire'] || []; - const atmos = categories['Atmosphere'] || []; - const power = categories['Power'] || []; + const { act, data } = useBackend(context); + const { + cameraView, + } = data; + + const sortingKey = { + "Fire": 0, + "Atmosphere": 1, + "Power": 2, + "Burglar": 3, + "Motion": 4, + "Camera": 5, + }; + + const sortedAlarms = flow([ + sortBy((alarm) => sortingKey[alarm.name]), + ])(data.alarms || []); + return ( <> -
-
    - {fire.length === 0 && ( -
  • - Systems Nominal -
  • - )} - {fire.map(alert => ( -
  • - {alert} -
  • - ))} -
-
-
-
    - {atmos.length === 0 && ( -
  • - Systems Nominal -
  • - )} - {atmos.map(alert => ( -
  • - {alert} -
  • - ))} -
-
-
-
    - {power.length === 0 && ( -
  • - Systems Nominal -
  • - )} - {power.map(alert => ( -
  • - {alert} -
  • - ))} -
-
+ {sortedAlarms.map(category => ( +
+
    + {category.alerts?.length === 0 && ( +
  • + Systems Nominal +
  • + )} + {category.alerts.map(alert => ( + + +
  • + {alert.name} {!!cameraView && alert?.sources > 1 + ? " (" + alert.sources + " sources)" : ""} +
  • +
    + {!!cameraView && ( + +
+
+ ))} ); };