UNPKG

node-red-contrib-displayext-node

Version:

A node for software DisplayEXT

370 lines (340 loc) 14.8 kB
<script type="text/javascript"> // convert to i18 text function c_(x) { return RED._("node-red-dashboard/ui_template:ui_template."+x); } RED.nodes.registerType('ui_templateListDE',{ category: "Display Externe", color: '#B2EBE0', defaults: { group: {type: 'ui_groupDE', required:true}, name: {value: ''}, order: {value: 0}, width: {value: 0, validate: function(v) { var valid = true if (this.templateScope !== 'global') { var width = v||0; var currentGroup = $('#node-input-group').val()||this.group; var groupNode = RED.nodes.node(currentGroup); valid = !groupNode || +width <= +groupNode.width; $("#node-input-size").toggleClass("input-error",!valid); } return valid; }}, height: {value: 0}, format: {value: `<style> .action-buttons { display: flex; justify-content: space-between; align-items: center; padding: 15px; background: #3d3b3b; color: white; border-radius: 15px; margin-bottom: 20px } .action-btn { padding: 10px 20px; background: #747474; color: white; border: none; border-radius: 10px; cursor: pointer; display: flex; justify-content: space-between; align-items: center; width: 130px; } .action-btn:hover { background: #0056b3 } .device-list-container { display: flex; flex-direction: column; gap: 5px; width: auto; padding: 10px; font-family: Arial, sans-serif } .device-header, .device-item { display: grid ; grid-template-columns: 2.3fr 3fr 3fr 1.3fr 2.7fr 1.4fr 1fr; padding: 10px; border-radius: 10px; background: #2a2a2a; color: white; text-align: center; align-items: center; justify-items: start; } .device-header { font-weight: 100; background: #444; font-size: medium; } .device-item { border: 1px solid #555 } .device-voyant { width: 15px; height: 15px; border-radius: 50%; background: red; margin: auto; border: 2px solid #333; box-shadow: 0 0 5px rgba(0, 0, 0, 0.4); transition: background-color 0.3s ease, box-shadow 0.3s ease } .device-voyant.green { background-color: #00f90a; box-shadow: 0 0 10px #00f90a } .device-voyant.red { background-color: #f44336; box-shadow: 0 0 10px #f44336 } .device-voyant.yellow { background-color: #FFEB3B; box-shadow: 0 0 10px #FFEB3B } .device-voyant.off { background-color: #9e9e9e; box-shadow: none } .device-btn { padding: 5px 10px; background: #007bff; color: white; border: none; cursor: pointer; border-radius: 3px; text-align: center } .device-btn-blackout { padding: 5px 10px; background: red; color: white; border: none; cursor: pointer; border-radius: 3px; text-align: center; } .device-btn:hover { background: #0056b3; } .device-btn-blackout:hover { background: darkred; } .dropdown { padding: 5px; width: 80%; margin: auto } .device-list-container { overflow: auto; /* Cacher les barres de défilement */ -ms-overflow-style: none; /* Pour IE et Edge */ scrollbar-width: none; /* Pour Firefox */ } .device-list-container::-webkit-scrollbar { display: none; /* Pour Chrome, Safari et Edge */ } </style> <div class="action-buttons"> <button class="action-btn" ng-click="reloadPage()"><img style="width:20px" src="https://cine-production.github.io/ServiceTiers/BASEDONNEE/node-red/reload.svg">Reload</button><h2 style="color: #329fff !important;!i;!;background: #ffe4c400 !important;!i;!;font-weight: unset;">Devices</h2><button class="action-btn" ng-click="send({ payload: { action: 'modify', devices: msg.payload.data } })"><img style="width:20px" src="https://cine-production.github.io/ServiceTiers/BASEDONNEE/node-red/modif.svg">Modifier</button> </div> <div class="device-list-container"> <div class="device-header"> <span>Name</span><span>IP</span><span>Port</span><span>Status</span><span>Action</span><span>Play</span><span>blackout</span></div> <div ng-repeat="device in msg.payload.data" class="device-item"> <span>{{ device.name }}</span><span>{{ device.ip }}</span><span>{{ device.port }}</span> <div class="device-voyant" id="{{device.name}}-{{device.ip}}"></div> <select class="dropdown" ng-model="selectedMedia"> <option ng-repeat="media in msg.payload.dataMedia" value="{{ media.name }}"> {{ media.name }} </option> </select><button class="device-btn" ng-click="send({ payload: { action: 'play', devices: device.ip + ':' + device.port, media: selectedMedia } })">Play</button> </select><button class="device-btn-blackout" ng-click="send({ payload: { action: 'blackout', devices: device.ip + ':' + device.port } })">blackout</button> </div> </div> <script> (function(scope) { scope.reloadPage = function() { scope.send({ payload: 'reload' }); // Envoie le message au backend // Délai de 500 ms avant de recharger la page setTimeout(function() { location.reload(); }, 300); }; })(scope); `+`<`+`/script>`}, storeOutMessages: {value: false}, fwdInMessages: {value: false}, resendOnRefresh: {value: true}, templateScope: {value: 'local'}, className: {value: ''} }, inputs:1, outputs:1, icon: "icon.png", paletteLabel: 'List Computers', label: function() { return this.name || 'List Computers'; }, labelStyle: function() { return this.name?"node_label_italic":""; }, oneditprepare: function() { if (RED.editor.hasOwnProperty("editText") && typeof RED.editor.editText === "function") { $("#node-template-expand-editor").show(); } else { $("#node-template-expand-editor").hide(); } var that = this; $("#node-input-size").elementSizer({ width: "#node-input-width", height: "#node-input-height", group: "#node-input-group" }); if (typeof this.storeOutMessages === 'undefined') { this.storeOutMessages = true; $('#node-input-storeOutMessages').prop('checked', true); } if (typeof this.fwdInMessages === 'undefined') { this.fwdInMessages = true; $('#node-input-fwdInMessages').prop('checked', true); } if (typeof this.templateScope === 'undefined') { this.templateScope = 'local'; $('#node-input-templateScope').val(this.templateScope); } $('#node-input-templateScope').on('change', function() { if ($('#node-input-templateScope').val() === 'global') { $('#template-row-group, #template-row-size, #template-pass-store, #template-row-class').hide(); that._def.defaults.group.required = false; } else { $('#template-row-group, #template-row-size, #template-pass-store, #template-row-class').show(); that._def.defaults.group.required = true; } var rows = $("#dialog-form>div:not(.node-text-editor-row)"); var height = $("#dialog-form").height(); for (var i=0; i<rows.size(); i++) { height = height - $(rows[i]).outerHeight(true); } if ($('#node-input-templateScope').val() === "global") { height += 240; } var editorRow = $("#dialog-form>div.node-text-editor-row"); height -= (parseInt(editorRow.css("marginTop")) + parseInt(editorRow.css("marginBottom"))); $(".node-text-editor").css("height",height+"px"); if (this.editor) { this.editor.resize(); } }) this.editor = RED.editor.createEditor({ id: 'node-input-format-editor', mode: 'ace/mode/html', value: $("#node-input-format").val() }); RED.library.create({ url:"uitemplates", // where to get the data from type:"ui_template", // the type of object the library is for editor:this.editor, // the field name the main text body goes to mode:"ace/mode/html", fields:['name'] }); this.editor.focus(); RED.popover.tooltip($("#node-template-expand-editor"),c_("label.expand")); $("#node-template-expand-editor").on("click", function(e) { e.preventDefault(); var value = that.editor.getValue(); RED.editor.editText({ mode: 'html', value: value, width: "Infinity", cursor: that.editor.getCursorPosition(), complete: function(v,cursor) { that.editor.setValue(v, -1); that.editor.gotoLine(cursor.row+1,cursor.column,false); setTimeout(function() { that.editor.focus(); },300); } }) }) }, oneditsave: function() { var annot = this.editor.getSession().getAnnotations(); this.noerr = 0; $("#node-input-noerr").val(0); for (var k=0; k < annot.length; k++) { if (annot[k].type === "error") { $("#node-input-noerr").val(annot.length); this.noerr = annot.length; } } $("#node-input-format").val(this.editor.getValue()); this.editor.destroy(); delete this.editor; }, oneditcancel: function() { this.editor.destroy(); delete this.editor; }, oneditresize: function(size) { var rows = $("#dialog-form>div:not(.node-text-editor-row)"); var height = $("#dialog-form").height(); for (var i=0; i<rows.size(); i++) { height = height - $(rows[i]).outerHeight(true); } if ($('#node-input-templateScope').val() === "global") { height += 232; } var editorRow = $("#dialog-form>div.node-text-editor-row"); height -= (parseInt(editorRow.css("marginTop")) + parseInt(editorRow.css("marginBottom"))); $(".node-text-editor").css("height",height+"px"); this.editor.resize(); } }); </script> <script type="text/html" data-template-name="ui_templateListDE"> <!-- <div class="form-row"> <label for="node-input-format"><span data-i18n="ui_templateListDE.label.type"></span></label> <select style="width:76%" id="node-input-templateScope"> <option value="local" data-i18n="ui_templateListDE.label.local"></option> <option value="global" data-i18n="ui_templateListDE.label.global"></option> </select> </div> --> <div class="form-row" id="template-row-group"> <label for="node-input-group"><i class="fa fa-table"></i> <span data-i18n="ui_templateListDE.label.group"></span></label> <input type="text" id="node-input-group"> </div> <div class="form-row" id="template-row-size"> <label><i class="fa fa-object-group"></i> <span data-i18n="ui_templateListDE.label.size"></span></label> <input type="hidden" id="node-input-width"> <input type="hidden" id="node-input-height"> <button class="editor-button" id="node-input-size"></button> </div> <!-- <div class="form-row" id="template-row-class"> <label for="node-input-className"><i class="fa fa-code"></i> <span data-i18n="ui_templateListDE.label.className"></label> <input type="text" id="node-input-className" data-i18n="[placeholder]ui_templateListDE.label.classNamePlaceholder"/> </div> --> <div class="form-row"> <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label> <div style="display:inline-block; width:calc(100% - 105px)"> <input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name"> </div> </div> <div class="form-row" style="display:none;margin-bottom:0px; "> <label for="node-input-format"><i class="fa fa-copy"></i> <span data-i18n="ui_templateListDE.label.template"></span></label> <input type="hidden" id="node-input-format"> <button id="node-template-expand-editor" class="red-ui-button red-ui-button-small" style="float:right"><i class="fa fa-expand"></i></button> </div> <!-- <div class="form-row node-text-editor-row"> <div style="height:250px; min-height:100px" class="node-text-editor" id="node-input-format-editor" ></div> </div> --> <!-- <div id="template-pass-store"> <div class="form-row" style="margin-bottom:0px;"> <input type="checkbox" id="node-input-fwdInMessages" style="display:inline-block; margin-left:8px; width:auto; vertical-align:top;"> <label for="node-input-fwdInMessages" style="width:70%;"> <span data-i18n="ui_templateListDE.label.pass-through"></span></label> </div> <div class="form-row" style="margin-bottom:0px;"> <input type="checkbox" id="node-input-storeOutMessages" style="display:inline-block; margin-left:8px; width:auto; vertical-align:top;"> <label for="node-input-storeOutMessages" style="width:70%;"> <span data-i18n="ui_templateListDE.label.store-state"></span></label> </div> <div class="form-row" style="margin-bottom:0px;"> <input type="checkbox" id="node-input-resendOnRefresh" style="display:inline-block; margin-left:8px; width:auto; vertical-align:top;"> <label for="node-input-resendOnRefresh" style="width:70%;"> <span data-i18n="ui_templateListDE.label.resend"></span></label> </div> </div> --> </script>