{ "custom": { "auth": { "almAck": false, "almShelve": false, "config": false, "control": false }, "filters": { "alm": [], "prov": [], "tag": [] } }, "params": {}, "propConfig": { "custom.auth": { "binding": { "config": { "path": "session.props.auth.user.roles" }, "transforms": [ { "code": "\treturn utils.roles.validate(value)", "type": "script" } ], "type": "property" }, "persistent": true }, "custom.filters": { "persistent": true } }, "props": {}, "root": { "children": [ { "children": [ { "children": [ { "meta": { "name": "Label" }, "position": { "basis": "75px", "shrink": 0 }, "props": { "style": { "backgroundColor": "var(--neutral-30)" }, "text": "IO GW:", "textStyle": { "fontSize": "0.6em", "textAlign": "center", "textTransform": "uppercase" } }, "type": "ia.display.label" }, { "meta": { "name": "FlexRepeater" }, "position": { "grow": 1, "shrink": 0 }, "props": { "alignItems": "flex-start", "elementPosition": { "basis": "auto", "grow": 0, "shrink": 0 }, "instances": [ { "color": "var(--callToAction)", "filterString": "prov:Ignition_Common_IO_Gtwy", "instancePosition": {}, "instanceStyle": { "classes": "" }, "label": "Ignition_Common_IO_Gtwy", "source": "prov" }, { "color": "var(--callToAction)", "filterString": "prov:Ignition_SATB1_IO1_default", "instancePosition": {}, "instanceStyle": { "classes": "" }, "label": "Ignition_SATB1_IO1_default", "source": "prov" } ], "path": "Library/Templates/Framework/Pill Button", "style": { "gap": "5px", "padding": "8px 5px" }, "useDefaultViewHeight": false, "useDefaultViewWidth": false, "wrap": "wrap" }, "type": "ia.display.flex-repeater" }, { "children": [ { "events": { "component": { "onActionPerformed": { "config": { "script": "\tsource \u003d self.parent.parent.meta.name\n\tsystem.perspective.sendMessage(\u0027clearFilters\u0027, {\n\t\t\u0027source\u0027: source\n\t})\n\tself.parent.parent.parent.parent.getChild(\"AlarmStatusTable\").custom.filters[source] \u003d []" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Button" }, "props": { "primary": false, "text": "Remove All", "textStyle": { "fontSize": "0.75em", "textAlign": "center" } }, "type": "ia.input.button" } ], "meta": { "name": "FlexContainer" }, "position": { "basis": "78px", "shrink": 0 }, "props": { "alignItems": "center", "justify": "center", "style": { "backgroundColor": "var(--neutral-30)", "border-left": "1px solid var(--border)" } }, "type": "ia.container.flex" } ], "meta": { "name": "prov" }, "position": { "display": false, "grow": 1 }, "props": { "style": { "borderBottom": "1px solid var(--border)", "borderTop": "1px solid var(--border)" } }, "type": "ia.container.flex" }, { "children": [ { "meta": { "name": "Label" }, "position": { "basis": "75px", "shrink": 0 }, "props": { "style": { "backgroundColor": "var(--neutral-30)" }, "text": "Quick Search:", "textStyle": { "fontSize": "0.6em", "textAlign": "center", "textTransform": "uppercase" } }, "type": "ia.display.label" }, { "meta": { "name": "FlexRepeater" }, "position": { "grow": 1 }, "propConfig": { "props.instances": { "persistent": true }, "props.instances[14].label": { "binding": { "config": { "expression": "\u0027\u0027" }, "type": "expr" } } }, "props": { "elementPosition": { "basis": "auto", "grow": 0, "shrink": 0 }, "instances": [ { "color": "var(--action-primary)", "filterString": "", "instancePosition": {}, "instanceStyle": { "classes": "" }, "label": "DH101", "mode": "", "selected": false, "source": "tag" }, { "color": "var(--action-primary)", "filterString": "", "instancePosition": {}, "instanceStyle": { "classes": "" }, "label": "DH102", "mode": "", "selected": false, "source": "tag" }, { "color": "var(--action-primary)", "filterString": "", "instancePosition": {}, "instanceStyle": { "classes": "" }, "label": "DH201", "mode": "", "selected": false, "source": "tag" }, { "color": "var(--action-primary)", "filterString": "", "instancePosition": {}, "instanceStyle": { "classes": "" }, "label": "DH202", "mode": "", "selected": false, "source": "tag" }, { "color": "var(--action-primary)", "filterString": "", "instancePosition": {}, "instanceStyle": { "classes": "" }, "label": "DH203", "mode": "", "selected": false, "source": "tag" }, { "color": "var(--action-primary)", "filterString": "", "instancePosition": {}, "instanceStyle": { "classes": "" }, "label": "CHWS", "mode": "", "selected": false, "source": "tag" }, { "color": "var(--action-primary)", "filterString": "", "instancePosition": {}, "instanceStyle": { "classes": "" }, "label": "Electrical", "mode": "", "selected": false, "source": "tag" }, { "color": "var(--neutral-50)", "filterString": "", "instancePosition": {}, "instanceStyle": { "classes": "" }, "label": "", "mode": "Custom", "selected": false, "source": "tag" } ], "path": "Library/Framework/Pill Button", "style": { "gap": "5px", "padding": "8px 5px" }, "useDefaultViewHeight": false, "useDefaultViewWidth": false, "wrap": "wrap" }, "type": "ia.display.flex-repeater" }, { "children": [ { "events": { "component": { "onActionPerformed": { "config": { "script": "\tsource \u003d self.parent.parent.meta.name\n\tself.view.custom.filters[source] \u003d []\n\tflexRepeater \u003d self.parent.parent.getChild(\"FlexRepeater\")\n\ttoDelete \u003d []\n\tfor i, instance in enumerate(flexRepeater.props.instances):\n\t\tinstance[\u0027selected\u0027] \u003d False\n\t\tif instance[\u0027mode\u0027] \u003d\u003d \u0027Custom\u0027:\n\t\t\tinstance[\u0027label\u0027] \u003d \u0027\u0027\n\t\t\tif i \u003c len(flexRepeater.props.instances) - 1:\n\t\t\t\ttoDelete.append(i)\n\tfor index in reversed(toDelete):\n\t\tflexRepeater.props.instances.pop(index)" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Button" }, "props": { "primary": false, "text": "Remove All", "textStyle": { "fontSize": "0.75em", "textAlign": "center" } }, "type": "ia.input.button" } ], "meta": { "name": "FlexContainer" }, "position": { "basis": "78px", "shrink": 0 }, "props": { "alignItems": "center", "justify": "center", "style": { "backgroundColor": "var(--neutral-30)", "border-left": "1px solid var(--border)" } }, "type": "ia.container.flex" } ], "meta": { "name": "tag" }, "position": { "grow": 1 }, "type": "ia.container.flex" } ], "meta": { "name": "FlexContainer" }, "position": { "shrink": 0 }, "props": { "direction": "column", "style": { "border": "1px solid var(--border)" } }, "type": "ia.container.flex" }, { "meta": { "name": "RadioGroup" }, "propConfig": { "props.value": { "binding": { "config": { "expression": "0" }, "type": "expr" } } }, "props": { "align": "start", "radioStyle": { "padding": "0px 10px" }, "radios": [ { "enabled": true, "selected": true, "style": { "classes": "" }, "text": "Match on ANY", "value": 0 }, { "selected": false, "text": "Match on ALL", "value": 1 } ], "style": { "borderLeft": "1px solid var(--border)", "borderRight": "1px solid var(--border)", "fontSize": "0.8em", "padding": "4px 5px" } }, "type": "ia.input.radio-group" }, { "meta": { "contextMenu": { "enabled": true, "items": [ { "children": [], "icon": { "color": "", "path": "", "style": {} }, "link": { "target": "self", "url": "" }, "message": { "payload": {}, "scope": "page", "type": "" }, "method": { "name": "navigate", "params": {} }, "style": { "classes": "" }, "text": "Goto", "type": "method" } ] }, "name": "AlarmStatusTable" }, "position": { "grow": 1 }, "propConfig": { "props.enableAcknowledge": { "binding": { "config": { "path": "view.custom.auth.almAck" }, "enabled": false, "type": "property" } }, "props.enableShelve": { "binding": { "config": { "path": "view.custom.auth.almShelve" }, "enabled": false, "type": "property" } }, "props.enableUnshelve": { "binding": { "config": { "path": "view.custom.auth.almShelve" }, "enabled": false, "type": "property" } } }, "props": { "columns": { "active": { "activeTime": { "width": 70 }, "displayPath": { "order": 3, "width": 250 }, "label": { "enabled": true, "order": 2 }, "name": { "enabled": false }, "priority": { "order": 4, "width": 40 }, "source": { "order": 6 }, "state": { "order": 5, "width": 75 } } }, "enableAcknowledge": false, "enableShelve": false, "enableUnshelve": false, "filters": { "active": { "conditions": { "label": "" }, "priorities": { "critical": false, "high": false, "low": false, "medium": false }, "results": { "data": [ { "ackNotes": "", "ackPipeline": "", "ackTime": "", "ackUser": "", "activePipeline": "", "activeTime": "2026-05-08 19:55:09.517+0000", "clearPipeline": "", "clearTime": "", "deadband": "0.0", "displayPath": "DOAS Building Pressure High", "eventId": "bf3b5b18-4008-470d-ad7d-29439dec05f5", "eventTime": "2026-05-08 19:55:09.517+0000", "eventValue": "100.0", "isAcked": "false", "isActive": "true", "isClear": "false", "label": "DOAS1", "name": "High", "notes": "", "priority": "Critical", "source": "prov:default:/tag:simulator/DOAS/DOAS1/Building Pressure:/alm:High", "state": "Active, Unacknowledged" } ], "enabled": true }, "states": { "clearUnacked": false } }, "shelved": { "results": { "enabled": true } } }, "pager": { "initialOption": 50 }, "rowStyles": { "activeAcked": { "priorities": { "critical": { "backgroundColor": "#e2202888" }, "high": { "backgroundColor": "#de7c3388" }, "low": { "backgroundColor": "#7266b788" }, "medium": { "backgroundColor": "#f4b83488" } } }, "activeUnacked": { "priorities": { "critical": { "backgroundColor": "var(--alarm-critical)" }, "high": { "backgroundColor": "var(--alarm-high)" }, "low": { "backgroundColor": "var(--alarm-low)" }, "medium": { "backgroundColor": "var(--alarm-medium)" } } } }, "shelvingTimes": [ 2592000, 43200, 1800, 3600, 7200, 14400 ], "toolbar": { "enableConfiguration": false, "enableFilter": false, "enableFilterResults": false, "enablePreFilters": false, "toggleableFilter": false } }, "scripts": { "customMethods": [ { "name": "convertToDict", "params": [ "input_str" ], "script": " # Split by \u0027:/\u0027, keeping \u0027:\u0027 within key-value pairs\n parts \u003d input_str.split(\u0027:/\u0027)\n result_dict \u003d {}\n \n # Loop through the parts and create key-value pairs\n for part in parts:\n key, value \u003d part.split(\u0027:\u0027, 1)\n result_dict[key] \u003d value\n \n return result_dict" }, { "name": "navigate", "params": [], "script": "\tsystem.perspective.print(\"Context Click\")\n\tif len(self.props.selection.active.data) \u003d\u003d 1:\n\t\t#prov:Ignition_SATB1_IO1_default:/tag:Datahall 1/Development/UT HS1/Alarms/Vacuum Fault Interrupter_VF-1 Tripped:/alm:Alarm\n\t\t#prov:Ignition_Common_IO_Gtwy:/tag:Electrical/SES 1B/SEL 3/Over Current:/alm:Over Current\n\t\tsrcPath \u003d self.props.selection.active.data[0].source \n\t\tparams \u003d utils.nav.openL4AlarmPopup(srcPath)\n\t\t\n\t\tsystem.perspective.print(\"Params: %s\"%(params))\n\t\tutils.nav.openEQPopup(params[\"objectName\"], params[\"tagPath\"], modal\u003dTrue, resizable\u003dTrue, draggable\u003dTrue)" } ], "extensionFunctions": [ { "enabled": false, "name": "filterAlarm", "script": "\tresult \u003d True\n\tsource \u003d self.convertToDict(alarmEvent.get(\u0027source\u0027).toString())\n\tprov \u003d source[\u0027prov\u0027]\n\ttag \u003d alarmEvent.get(\u0027displayPath\u0027).toString() #source[\u0027tag\u0027]\n\talm \u003d source[\u0027alm\u0027]\n\t\n\tfilters \u003d self.view.custom.filters\n\tmatchRule \u003d self.getSibling(\"RadioGroup\").props.value\n\t\n\tif len(filters[\u0027prov\u0027]) \u003e 0:\n\t\tif prov not in filters[\u0027prov\u0027]:\n\t\t\tresult \u003d False\n\t\t\t\n\tif len(filters[\u0027tag\u0027]) \u003e 0:\n\t if matchRule \u003d\u003d 0: # match on ANY\n\t result \u003d False \n\t for t in filters[\u0027tag\u0027]:\n\t if t.upper() in tag.upper():\n\t result \u003d True\n\t break # If any tag matches, we can break out of the loop\n\t elif matchRule \u003d\u003d 1: # match on ALL\n\t for t in filters[\u0027tag\u0027]:\n\t if t.upper() not in tag.upper():\n\t result \u003d False\n\t break # If any tag doesn\u0027t match, stop and return False\n\t\n\treturn result\n\n#\tresult \u003d True\n#\tsource \u003d self.convertToDict(alarmEvent.get(\u0027source\u0027).toString())\n#\tprov \u003d source[\u0027prov\u0027]\n#\ttag \u003d source[\u0027tag\u0027]\n#\talm \u003d source[\u0027alm\u0027]\n#\t\n#\tfilters \u003d self.view.custom.filters\n#\tmatchRule \u003d self.getSibling(\"RadioGroup\").props.value\n#\t\n#\tif len(filters[\u0027prov\u0027]) \u003e 0:\n#\t\tif prov not in filters[\u0027prov\u0027]:\n#\t\t\tresult \u003d False\n#\t\t\t\n#\tif len(filters[\u0027tag\u0027]) \u003e 0:\n#\t if matchRule \u003d\u003d 0: # match on ANY\n#\t result \u003d False \n#\t for t in filters[\u0027tag\u0027]:\n#\t if t.upper() in tag.upper():\n#\t result \u003d True\n#\t break # If any tag matches, we can break out of the loop\n#\t elif matchRule \u003d\u003d 1: # match on ALL\n#\t for t in filters[\u0027tag\u0027]:\n#\t if t.upper() not in tag.upper():\n#\t result \u003d False\n#\t break # If any tag doesn\u0027t match, stop and return False\n#\t\n#\treturn result" } ], "messageHandlers": [] }, "type": "ia.display.alarmstatustable" } ], "meta": { "name": "root" }, "props": { "direction": "column" }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "addFilter", "pageScope": true, "script": "\tsource \u003d payload[\u0027source\u0027]\n\tlabel \u003d payload[\u0027label\u0027]\n\tindex \u003d payload[\u0027index\u0027]\n\t\n\tflexRepeater \u003d self.getChild(\"FlexContainer\").getChild(source).getChild(\"FlexRepeater\")\n\t\n\tif label in self.view.custom.filters[source]:\n\t\tpass\n\telse:\n\t\tself.view.custom.filters[source].append(label)\n\t\tflexRepeater.props.instances[index].selected \u003d True", "sessionScope": false, "viewScope": false }, { "messageType": "customFilter", "pageScope": true, "script": "\tsource \u003d payload[\u0027source\u0027]\n\tlabel \u003d payload[\u0027label\u0027]\n\tindex \u003d payload[\u0027index\u0027]\n\t\n\tflexRepeater \u003d self.getChild(\"FlexContainer\").getChild(\u0027tag\u0027).getChild(\"FlexRepeater\")\n\t\n\tif label in self.view.custom.filters[source]:\n\t\tpass\n\telse:\n\t\tself.view.custom.filters[source].append(label)\n\t\tflexRepeater.props.instances[index][\u0027selected\u0027] \u003d True\n\t\tflexRepeater.props.instances[index][\u0027label\u0027] \u003d label\n\t\tflexRepeater.props.instances.append({\n\t\t\t\"color\": \"var(--neutral-50)\",\n\t\t\t\"filterString\": \"\",\n\t\t\t\"instancePosition\": {},\n\t\t\t\"instanceStyle\": {\n\t\t\t\"classes\": \"\"\n\t\t\t},\n\t\t\t\"mode\": \"Custom\",\n\t\t\t\"selected\": False,\n\t\t\t\"source\": \"tag\",\n\t\t\t\"label\": \"\"\n\t\t\t})", "sessionScope": false, "viewScope": false }, { "messageType": "removeFilter", "pageScope": true, "script": "\tsource \u003d payload[\u0027source\u0027]\n\tlabel \u003d payload[\u0027label\u0027]\n\tindex \u003d payload[\u0027index\u0027]\n\t\n\tflexRepeater \u003d self.getChild(\"FlexContainer\").getChild(source).getChild(\"FlexRepeater\")\n\t\n\tif label in self.view.custom.filters[source]:\n\t\ti \u003d self.view.custom.filters[source].index(label)\n\t\tself.view.custom.filters[source].pop(i)\n\t\tflexRepeater.props.instances[index].selected \u003d False\n\t\tif flexRepeater.props.instances[index].mode \u003d\u003d \u0027Custom\u0027:\n\t\t\tflexRepeater.props.instances[index].label \u003d \u0027\u0027\n\t\t\tif index \u003c len(flexRepeater.props.instances) - 1:\n\t\t\t\tflexRepeater.props.instances.pop(index)\n\telse:\n\t\tpass", "sessionScope": false, "viewScope": false } ] }, "type": "ia.container.flex" } }