From 43d312f0cb08f931a958eb9c2393344657a656e5 Mon Sep 17 00:00:00 2001 From: Bluefox Date: Thu, 23 Jan 2025 13:40:27 +0000 Subject: [PATCH] Added types (#497) * Added types * More types --- .../src-vis/public/widgets/basic/js/table.js | 606 ++++++++++++------ .../iobroker.vis-2/src-vis/src/Editor.tsx | 21 +- .../Vis/Widgets/Basic/BasicImageGeneric.tsx | 4 +- .../Vis/Widgets/Basic/BasicViewInWidget8.tsx | 4 +- .../src/Vis/Widgets/JQui/JQuiSlider.tsx | 5 +- .../src-vis/src/Vis/Widgets/Swipe/Swipe.tsx | 4 +- .../src/Vis/Widgets/Tabs/TabsSliderTabs.tsx | 4 +- .../src-vis/src/Vis/visEngine.tsx | 189 +++--- .../src-vis/src/Vis/visRxWidget.tsx | 8 +- .../src-vis/src/Vis/visView.tsx | 16 +- packages/types-vis-2/index.d.ts | 373 +++++------ 11 files changed, 699 insertions(+), 535 deletions(-) diff --git a/packages/iobroker.vis-2/src-vis/public/widgets/basic/js/table.js b/packages/iobroker.vis-2/src-vis/public/widgets/basic/js/table.js index 3e175e144..dece838de 100644 --- a/packages/iobroker.vis-2/src-vis/public/widgets/basic/js/table.js +++ b/packages/iobroker.vis-2/src-vis/public/widgets/basic/js/table.js @@ -1,4 +1,4 @@ -"use strict"; +'use strict'; // Following classes should be used if variable table_class="tclass" // // @@ -41,47 +41,55 @@ if (vis.editMode) { // Add words for basic widgets - $.extend(true, systemDictionary, { - "table_oid": {"en": "Table Object ID", "de": "Table Object ID", "ru": "ID таблицы"}, - "static_value": {"en": "Static JSON(If no ID)", "de": "Static JSON(If no ID)", "ru": "Значение, если нет ID таблицы"}, - "event_oid": {"en": "Event ID", "de": "Ereigniss ID", "ru": "ID события"}, - "selected_oid": {"en": "Selected ID", "de": "Ausgewählt ID", "ru": "ID для отмеченного"}, - "hide_header": {"en": "Hide header", "de": "Kein Header", "ru": "Скрыть заголовок"}, - "show_scroll": {"en": "Show scroll", "de": "Zeige Scrollbar", "ru": "Показать прокрутку"}, - "detailed_wid": {"en": "Detailed widget", "de": "Detailed widget", "ru": "Виджет детализации"}, - "colCount": {"en": "Column count", "de": "Kolumnanzahl", "ru": "Кол-во колонок"}, - "group_header": {"en": "Headers", "de": "Headers", "ru": "Заголовок"}, - "colName": {"en": "Name", "de": "Name", "ru": "Имя"}, - "colWidth": {"en": "Width", "de": "Width", "ru": "Ширина"}, - "colAttr": {"en": "Attribute in JSON", "de": "Attribut in JSON", "ru": "Атрибут в JSON"}, - "ack_oid": {"en": "Acknowledge ID", "de": "Bestätigung ID", "ru": "ID для подтверждения"}, - "new_on_top": {"en": "New event on top", "de": "Neus Ereignis am Anfang", "ru": "Новые события сначала"} + $.extend(true, window.systemDictionary, { + table_oid: { en: 'Table Object ID', de: 'Table Object ID', ru: 'ID таблицы' }, + static_value: { en: 'Static JSON(If no ID)', de: 'Static JSON(If no ID)', ru: 'Значение, если нет ID таблицы' }, + event_oid: { en: 'Event ID', de: 'Ereigniss ID', ru: 'ID события' }, + selected_oid: { en: 'Selected ID', de: 'Ausgewählt ID', ru: 'ID для отмеченного' }, + hide_header: { en: 'Hide header', de: 'Kein Header', ru: 'Скрыть заголовок' }, + show_scroll: { en: 'Show scroll', de: 'Zeige Scrollbar', ru: 'Показать прокрутку' }, + detailed_wid: { en: 'Detailed widget', de: 'Detailed widget', ru: 'Виджет детализации' }, + colCount: { en: 'Column count', de: 'Kolumnanzahl', ru: 'Кол-во колонок' }, + group_header: { en: 'Headers', de: 'Headers', ru: 'Заголовок' }, + colName: { en: 'Name', de: 'Name', ru: 'Имя' }, + colWidth: { en: 'Width', de: 'Width', ru: 'Ширина' }, + colAttr: { en: 'Attribute in JSON', de: 'Attribut in JSON', ru: 'Атрибут в JSON' }, + ack_oid: { en: 'Acknowledge ID', de: 'Bestätigung ID', ru: 'ID для подтверждения' }, + new_on_top: { en: 'New event on top', de: 'Neus Ereignis am Anfang', ru: 'Новые события сначала' }, }); } vis.binds.table = { - getBrowserScrollSize: function (){ + getBrowserScrollSize: function () { var css = { - "border": "none", - "height": "200px", - "margin": "0", - "padding": "0", - "width": "200px" + border: 'none', + height: '200px', + margin: '0', + padding: '0', + width: '200px', }; - var inner = $("
").css($.extend({}, css)); - var outer = $("
").css($.extend({ - "left": "-1000px", - "overflow": "scroll", - "position": "absolute", - "top": "-1000px" - }, css)).append(inner).appendTo("body") + var inner = $('
').css($.extend({}, css)); + var outer = $('
') + .css( + $.extend( + { + left: '-1000px', + overflow: 'scroll', + position: 'absolute', + top: '-1000px', + }, + css, + ), + ) + .append(inner) + .appendTo('body') .scrollLeft(1000) .scrollTop(1000); var scrollSize = { - height: (outer.offset().top - inner.offset().top) || 0, - width: (outer.offset().left - inner.offset().left) || 0 + height: outer.offset().top - inner.offset().top || 0, + width: outer.offset().left - inner.offset().left || 0, }; outer.remove(); @@ -89,7 +97,7 @@ vis.binds.table = { }, // Show detailed information - onRowClick: function () { + onRowClick: function () { var $this = $(this); var data = $this.data('options'); @@ -99,7 +107,10 @@ vis.binds.table = { $this.addClass(data.tClass + '-tr-selected'); if (data.selected_oid) { - vis.setValue(data.selected_oid, typeof data.content === 'string' ? data.content : JSON.stringify(data.content)); + vis.setValue( + data.selected_oid, + typeof data.content === 'string' ? data.content : JSON.stringify(data.content), + ); } // Get container for detailed information @@ -117,11 +128,32 @@ vis.binds.table = { for (var odata in data.content[obj]) { if (typeof data.content[obj][odata] === 'function') continue; var val = data.content[obj][odata].toString(); - if (odata.length > 1 && odata[0] === '_' && obj !== '_class' && obj.substring(0, 4) !== '_btn' && obj !== '_id') { + if ( + odata.length > 1 && + odata[0] === '_' && + obj !== '_class' && + obj.substring(0, 4) !== '_btn' && + obj !== '_id' + ) { continue; } - text += '
' + - ''; + text += + '' + + ''; if (val && val.length > 6 && val.substring(val.length - 6) === ' ') { text += ''; } @@ -130,8 +162,23 @@ vis.binds.table = { } else { var val = data.content[obj].toString(); - text += '' + - ''; + text += + '' + + ''; if (val && val.length > 6 && val.substring(val.length - 6) === ' ') { text += ''; @@ -143,7 +190,13 @@ vis.binds.table = { // Try to find special attributes starting with '_' for (var obj in data.content) { if (!data.content.hasOwnProperty(obj) || typeof data.content[obj] === 'function') continue; - if (obj.length > 0 && obj[0] === '_' && obj !== '_class' && obj.substring(0, 4) !== '_btn' && obj !== '_id') { + if ( + obj.length > 0 && + obj[0] === '_' && + obj !== '_class' && + obj.substring(0, 4) !== '_btn' && + obj !== '_id' + ) { text += '
' + odata + '' + val + '
' + + odata + + '' + + val + + '
 
' + obj.substring(1) + '' + val + '
' + + obj.substring(1) + + '' + + val + + '
 
'; // Show that object var r = 0; @@ -152,21 +205,58 @@ vis.binds.table = { for (var odata in data.content[obj]) { if (typeof data.content[obj][odata] === 'function') continue; var val = data.content[obj][odata].toString(); - if (odata.length > 1 && odata[0] === '_' && obj !== '_class' && obj.substring(0, 4) !== '_btn' && obj !== '_id') { + if ( + odata.length > 1 && + odata[0] === '_' && + obj !== '_class' && + obj.substring(0, 4) !== '_btn' && + obj !== '_id' + ) { continue; } - text += '' + - ''; + text += + '' + + ''; if (val && val.length > 6 && val.substring(val.length - 6) === ' ') { - text += ''; + text += + ''; } r++; } } else { var val = data.content[obj].toString(); - text += '' + - ''; + text += + '' + + ''; if (val && val.length > 6 && val.substring(val.length - 6) === ' ') { text += ''; @@ -178,7 +268,6 @@ vis.binds.table = { } } - // If no special _data object found => show standard elements if (!text) { text = '
' + odata + '' + val + '
' + + odata + + '' + + val + + '
 
 
' + obj.substring(1) + '' + val + '
' + + obj.substring(1) + + '' + + val + + '
 
'; @@ -186,14 +275,35 @@ vis.binds.table = { var row = 0; for (var data_obj in data.content) { // Show that object - if (!data.content.hasOwnProperty(data_obj) || - (data_obj.length > 1 && data_obj[0] === '_' && data_obj !== '_class' && data_obj.substring(0, 4) !== '_btn' && data_obj !== '_id')) { + if ( + !data.content.hasOwnProperty(data_obj) || + (data_obj.length > 1 && + data_obj[0] === '_' && + data_obj !== '_class' && + data_obj.substring(0, 4) !== '_btn' && + data_obj !== '_id') + ) { continue; } var val = data.content[data_obj].toString(); - text += '' + - ''; + text += + '' + + ''; if (val.length > 6 && val.substring(val.length - 6) === ' ') { text += ''; @@ -237,17 +347,16 @@ vis.binds.table = { } }, - createRow: function (rowData, wid, options, rowNumber, noTR, index, serverID) { - var tClass = options['class'] || 'tclass'; + createRow: function (rowData, wid, options, rowNumber, noTR, index, serverID) { + var tClass = options['class'] || 'tclass'; var _classes = rowData['_class'] ? rowData['_class'].split(' ') : null; var text; // Create row if (!noTR) { - text = ''; - if (attr.match(/^_btn/)){ + text += + ''; + text += + ''; } k++; } @@ -302,7 +436,7 @@ vis.binds.table = { return text; }, - showTable: function (view, wid, options) { + showTable: function (view, wid, options) { var $div = $('#' + wid); if (!$div.length) { setTimeout(function () { @@ -314,7 +448,7 @@ vis.binds.table = { var tClass = options['class'] || 'tclass'; // read actual table as json string - var tableJson = options.table_oid ? vis.states.attr(options.table_oid + '.val') : (options.static_value || ''); + var tableJson = options.table_oid ? vis.states.attr(options.table_oid + '.val') : options.static_value || ''; var table = []; if (typeof app !== 'undefined' && app.replaceFilePathJson) { tableJson = app.replaceFilePathJson(tableJson); @@ -322,9 +456,8 @@ vis.binds.table = { if (tableJson && typeof tableJson === 'string') { try { table = JSON.parse(tableJson); - } - catch (e) { - console.log ("showTable: Cannot parse json table"); + } catch (e) { + console.log('showTable: Cannot parse json table'); table = []; } } else { @@ -338,7 +471,14 @@ vis.binds.table = { // Start creation of table var header = '
' + data_obj + '' + data.content[data_obj]+'
' + + data_obj + + '' + + data.content[data_obj] + + '
 
'; + if (attr.match(/^_btn/)) { if (typeof rowData[attr] === 'string') { - btnText = rowData[attr]; + btnText = rowData[attr]; } else { - btnText = rowData[attr].caption; + btnText = rowData[attr].caption; btnClass = rowData[attr]._class; } if (btnText) { - text += ''; + text += + ''; } } else { text += rowData[attr]; @@ -292,7 +417,16 @@ vis.binds.table = { } if (!options.colCount || k <= options.colCount) { - text += '' + rowData[attr] + '' + + rowData[attr] + + '
'; - var text = '
'; + var text = + '
'; var headerDone = false; var j = 0; var selectedId = null; @@ -356,9 +496,11 @@ vis.binds.table = { header += ''; var k = 1; for (var obj in table[ii]) { - if (!table[ii].hasOwnProperty(obj) || + if ( + !table[ii].hasOwnProperty(obj) || obj.match(/^jQuery/) || - typeof table[ii][obj] === 'function') { + typeof table[ii][obj] === 'function' + ) { continue; } @@ -366,19 +508,42 @@ vis.binds.table = { if (attr && attr[0] === '_') { if (attr.match(/^_btn/) || options['colAttr' + k]) { - header += ''; + header += + ''; k++; } continue; } if (!options.colCount || k <= options.colCount) { - header += ''; + header += + ''; } k++; } - if (options.show_scroll !== 'false' && options.show_scroll !== false && options.show_scroll !== undefined){ + if ( + options.show_scroll !== 'false' && + options.show_scroll !== false && + options.show_scroll !== undefined + ) { // Get the scroll width once - if (!vis.binds.table.scrollSize) vis.binds.table.scrollSize = vis.binds.table.getBrowserScrollSize(); + if (!vis.binds.table.scrollSize) + vis.binds.table.scrollSize = vis.binds.table.getBrowserScrollSize(); header += ''; } @@ -386,7 +551,7 @@ vis.binds.table = { headerDone = true; } - if (_classes &&_classes.indexOf('selected') !== -1) selectedId = ii; + if (_classes && _classes.indexOf('selected') !== -1) selectedId = ii; text += vis.binds.table.createRow(table[ii], wid, options, j, false, ii, table[ii]._id); j++; @@ -401,164 +566,192 @@ vis.binds.table = { $elem.append((options.hide_header ? '' : header) + text); var data = { options: options, - wid: wid, - view: view + wid: wid, + view: view, }; - $elem.find('.vis-table-ack-button').unbind('click touchstart').bind('click touchstart', function (e) { - // Protect against two events - if (vis.detectBounce(this)) return; + $elem + .find('.vis-table-ack-button') + .unbind('click touchstart') + .bind('click touchstart', function (e) { + // Protect against two events + if (vis.detectBounce(this)) return; - vis.binds.table.onAckButton.call(this, e); - }); + vis.binds.table.onAckButton.call(this, e); + }); // Set additional data for every row for (var i = 0, len = table.length; i < len; i++) { if (!table[i]) continue; - $elem.find('.vis-table-ack-button[data-index="' + i + '"]') - .data('options', { - ack_id: table[i]._ack_id || JSON.stringify(table[i]), - ack_oid: options.ack_oid - }); + $elem.find('.vis-table-ack-button[data-index="' + i + '"]').data('options', { + ack_id: table[i]._ack_id || JSON.stringify(table[i]), + ack_oid: options.ack_oid, + }); } // If detailed information desired if (options.detailed_wid) { // Bind on click event for every row - $elem.find('.vis-table-row').unbind('click touchstart').bind('click touchstart', function (e) { - // Protect against two events - if (vis.detectBounce(this)) return; - - vis.binds.table.onRowClick.call(this, e); - }); + $elem + .find('.vis-table-row') + .unbind('click touchstart') + .bind('click touchstart', function (e) { + // Protect against two events + if (vis.detectBounce(this)) return; + + vis.binds.table.onRowClick.call(this, e); + }); // Set additional data for every row for (i = 0, len = table.length; i < len; i++) { if (!table[i]) continue; - $elem.find('.vis-table-row[data-index="' + i + '"]') - .data('options', { - content: table[i], + $elem.find('.vis-table-row[data-index="' + i + '"]').data('options', { + content: table[i], detailed_wid: options.detailed_wid, - tClass: tClass, - wid: wid, + tClass: tClass, + wid: wid, selected_oid: options.selected_oid, }); } if (selectedId) { - setTimeout (function () { + setTimeout(function () { $elem.find('.vis-table-row[data-index="' + selectedId + '"]').trigger('click'); }, 200); } } else if (options.selected_oid) { - $elem.find('.vis-table-row').unbind('click touchstart').bind('click touchstart', function (e) { - // Protect against two events - if (vis.detectBounce(this)) return; - - vis.binds.table.onRowClick.call(this, e); - // Set additional data for every row - for (i = 0, len = table.length; i < len; i++) { - if (!table[i]) continue; - $elem.find('.vis-table-row[data-index="' + i + '"]') - .data('options', { - content: table[i], - wid: wid, + $elem + .find('.vis-table-row') + .unbind('click touchstart') + .bind('click touchstart', function (e) { + // Protect against two events + if (vis.detectBounce(this)) return; + + vis.binds.table.onRowClick.call(this, e); + // Set additional data for every row + for (i = 0, len = table.length; i < len; i++) { + if (!table[i]) continue; + $elem.find('.vis-table-row[data-index="' + i + '"]').data('options', { + content: table[i], + wid: wid, selected_oid: options.selected_oid, }); - } - }); + } + }); } // Remember index to calculate even or odd - data.rowNum = options.new_on_top ? 0 : ((j - 1) >= 0 ? j - 1 : 0); + data.rowNum = options.new_on_top ? 0 : j - 1 >= 0 ? j - 1 : 0; - function cbNewTable (e, newVal, oldVal) { + function cbNewTable(e, newVal, oldVal) { $elem.trigger('newTable', newVal); } - function cbNewEvent (e, newVal, oldVal) { + function cbNewEvent(e, newVal, oldVal) { $elem.trigger('newEvent', newVal); } if (!$('#' + wid).data('inited')) { $('#' + wid).data('inited', true); // New event coming - $elem.on('newEvent', function (e, newVal) { - if (e.handled) return; - e.handled = true; - var newEvent; - var data = $(this).data('options'); - // Convert event to json - if (newVal) { - if (typeof newVal === 'string') { - try { - newEvent = JSON.parse(newVal); - } - catch (e) - { - console.log('elem.triggered: Cannot parse json new event ' + newVal); - return; + $elem + .on('newEvent', function (e, newVal) { + if (e.handled) return; + e.handled = true; + var newEvent; + var data = $(this).data('options'); + // Convert event to json + if (newVal) { + if (typeof newVal === 'string') { + try { + newEvent = JSON.parse(newVal); + } catch (e) { + console.log('elem.triggered: Cannot parse json new event ' + newVal); + return; + } + } else { + newEvent = newVal; } } else { - newEvent = newVal; + return; } - } - else { - return; - } - // Try to find, if this event yet exists - var $row = (newEvent._id !== undefined) ? $(this).find('tr[data-index="' + newEvent._id + '"]') : []; + // Try to find, if this event yet exists + var $row = newEvent._id !== undefined ? $(this).find('tr[data-index="' + newEvent._id + '"]') : []; - // get next row number for new line - if (!$row.length) data.rowNum++; + // get next row number for new line + if (!$row.length) data.rowNum++; - var text = vis.binds.table.createRow(newEvent, data.wid, data.options, data.rowNum, ($row.length > 0), (newEvent._id === undefined) ? data.rowNum : newEvent._id); + var text = vis.binds.table.createRow( + newEvent, + data.wid, + data.options, + data.rowNum, + $row.length > 0, + newEvent._id === undefined ? data.rowNum : newEvent._id, + ); - if ($row.length) { - $row.html(text).addClass(newEvent._class || ''); - } else { - // If add to the top of table - if (data.options.new_on_top) { - $('#' + this.id).find('.vis-table-body').prepend(text); + if ($row.length) { + $row.html(text).addClass(newEvent._class || ''); } else { - // Add to the bottom of table - $('#' + this.id).find('.vis-table-body').append(text); + // If add to the top of table + if (data.options.new_on_top) { + $('#' + this.id) + .find('.vis-table-body') + .prepend(text); + } else { + // Add to the bottom of table + $('#' + this.id) + .find('.vis-table-body') + .append(text); + } } - } - var $el; - // If detailed widget desired - if (data.options.detailed_wid) { - $el = $('#' + this.id).find('.vis-table-row[data-index="' + ((newEvent._id === undefined) ? data.rowNum : newEvent._id) + '"]') + var $el; + // If detailed widget desired + if (data.options.detailed_wid) { + $el = $('#' + this.id) + .find( + '.vis-table-row[data-index="' + + (newEvent._id === undefined ? data.rowNum : newEvent._id) + + '"]', + ) + .data('options', { + content: newEvent, + detailed_wid: options.detailed_wid, + tClass: tClass, + wid: wid, + }) + .unbind('click touchstart') + .bind('click touchstart', function (e) { + // Protect against two events + if (vis.detectBounce(this)) return; + + vis.binds.table.onRowClick.call(this, e); + }); + $el = $(this).find('.tr_' + (newEvent._id === undefined ? data.rowNum : newEvent._id)); + } + + $('#' + this.id) + .find('.ack_button_' + (newEvent._id === undefined ? data.rowNum : newEvent._id)) .data('options', { - content: newEvent, - detailed_wid: options.detailed_wid, - tClass: tClass, - wid: wid - }).unbind('click touchstart').bind('click touchstart', function (e) { + data: newEvent, + parent: this, + ack_id: newEvent._ack_id || JSON.stringify(newEvent), + }) + .unbind('click touchstart') + .bind('click touchstart', function (e) { // Protect against two events if (vis.detectBounce(this)) return; - vis.binds.table.onRowClick.call(this, e); + vis.binds.table.onAckButton.call(this, e); }); - $el = $(this).find('.tr_' + ((newEvent._id === undefined) ? data.rowNum : newEvent._id)); - } - - $('#' + this.id).find('.ack_button_' + ((newEvent._id === undefined) ? data.rowNum : newEvent._id)) - .data('options', {data: newEvent, parent: this, ack_id: newEvent._ack_id || JSON.stringify(newEvent)}) - .unbind('click touchstart').bind('click touchstart', function (e) { - // Protect against two events - if (vis.detectBounce(this)) return; - - vis.binds.table.onAckButton.call(this, e); - }); - }) - .on('newTable', function (e, newVal) { - if (e.handled) return; - e.handled = true; - var data = $(this).data('options'); - // Update whole table - _setTimeout(vis.binds.table.showTable, 50, data.view, data.wid, data.options); - }); + }) + .on('newTable', function (e, newVal) { + if (e.handled) return; + e.handled = true; + var data = $(this).data('options'); + // Update whole table + _setTimeout(vis.binds.table.showTable, 50, data.view, data.wid, data.options); + }); } $('#' + wid).data('options', data); @@ -575,16 +768,34 @@ vis.binds.table = { } }, - showDialog: function (view, wid, options) { + showDialog: function (view, wid, options) { var trigger_value = vis.states.attr(options.trigger_id + '.val'); // Register callback in dashUI if (options.trigger_id) vis.binds.table.registerIds(wid, options.trigger_id); // Create widget container $('#' + wid).remove(); - $('#visview_' + view).append('
' + - '
' + (options['colName' + k] || '') + '' + + (options['colName' + k] || '') + + '' + (options['colName' + k] || attr) + '' + + (options['colName' + k] || attr) + + '
' + (options.image ? '': '') + '' + options.text + '
' + - ''); + $('#visview_' + view).append( + '
' + + '
' + + (options.image ? '' : '') + + '' + + options.text + + '
' + + '
', + ); var elem = document.getElementById(wid); @@ -593,7 +804,7 @@ vis.binds.table = { if (options.buttons[t]) { buttons[options.buttons[t]] = { text: options.buttons[t], - data: {data: options.buttons[t], trigger_id: options.trigger_id}, + data: { data: options.buttons[t], trigger_id: options.trigger_id }, click: function (evt, ui) { if (1 || !vis.editMode) { if (vis.binds.dialog_trigger_id) { @@ -601,26 +812,25 @@ vis.binds.table = { } } $(this).dialog('close'); - } - } + }, + }; } } elem._options = options; // Disable autofocus in edit mode if (vis.editMode) { - $.ui.dialog.prototype._focusTabbable = function () { - }; + $.ui.dialog.prototype._focusTabbable = function () {}; } $(elem).dialog({ resizable: false, - height: options.height || 200, - width: options.width || 400, - autoOpen: false, - modal: (options.modal === true || options.modal === 'true'), + height: options.height || 200, + width: options.width || 400, + autoOpen: false, + modal: options.modal === true || options.modal === 'true', draggable: false, - buttons: buttons + buttons: buttons, }); if ((vis.editMode && options.show) || trigger_value === 'open') { @@ -633,6 +843,6 @@ vis.binds.table = { $(this).dialog('open'); vis.binds.dialog_trigger_id = this._options.trigger_id; } - } - } + }; + }, }; diff --git a/packages/iobroker.vis-2/src-vis/src/Editor.tsx b/packages/iobroker.vis-2/src-vis/src/Editor.tsx index c96e83156..af7cbdf31 100644 --- a/packages/iobroker.vis-2/src-vis/src/Editor.tsx +++ b/packages/iobroker.vis-2/src-vis/src/Editor.tsx @@ -1190,17 +1190,17 @@ class Editor extends Runtime { return; } this.setState({ selectedGroup: groupId }); - this.setSelectedWidgets([]); + void this.setSelectedWidgets([]); }; undo = async (): Promise => { - this.setSelectedWidgets([]); + void this.setSelectedWidgets([]); await this.changeProject(this.state.history[this.state.historyCursor - 1], true); await this.setStateAsync({ historyCursor: this.state.historyCursor - 1 }); }; redo = async (): Promise => { - this.setSelectedWidgets([]); + void this.setSelectedWidgets([]); await this.changeProject(this.state.history[this.state.historyCursor + 1], true); await this.setStateAsync({ historyCursor: this.state.historyCursor + 1 }); }; @@ -1669,13 +1669,15 @@ class Editor extends Runtime { const project = deepClone(store.getState().visProject); const widget = project[this.state.selectedView].widgets[id]; if (widget?.marketplace) { - const marketplace = deepClone( + const marketplace: MarketplaceWidgetRevision | null = deepClone( store .getState() .visProject.___settings.marketplace.find(item => item.widget_id === widget.marketplace.widget_id), ); await this.deleteWidgetsAction(); - await this.addMarketplaceWidget(marketplace.id, null, null, id, widget.data, widget.style); + if (marketplace) { + await this.addMarketplaceWidget(marketplace.id, null, null, id, widget.data, widget.style); + } } }; @@ -2152,13 +2154,12 @@ class Editor extends Runtime { name: view, widgets: [], }; - Object.keys(store.getState().visProject[view].widgets).forEach((widget: AnyWidgetId) => { + const pWidgets = store.getState().visProject[view].widgets; + Object.keys(pWidgets).forEach((widget: AnyWidgetId) => { if ( this.state.updateWidgetsDialog && - store.getState().visProject[view].widgets[widget].marketplace?.widget_id === - this.state.updateWidgetsDialog.widget_id && - store.getState().visProject[view].widgets[widget].marketplace?.version !== - this.state.updateWidgetsDialog.version + pWidgets[widget].marketplace?.widget_id === this.state.updateWidgetsDialog.widget_id && + pWidgets[widget].marketplace?.version !== this.state.updateWidgetsDialog.version ) { viewWidgets.widgets.push(widget); } diff --git a/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/Basic/BasicImageGeneric.tsx b/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/Basic/BasicImageGeneric.tsx index ea5dbb45b..180e9f5ac 100644 --- a/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/Basic/BasicImageGeneric.tsx +++ b/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/Basic/BasicImageGeneric.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { Icon } from '@iobroker/adapter-react-v5'; -import type { RxRenderWidgetProps, VisBaseWidgetProps } from '@iobroker/types-vis-2'; +import type { RxRenderWidgetProps, VisBaseWidgetProps, WidgetData } from '@iobroker/types-vis-2'; import VisRxWidget from '@/Vis/visRxWidget'; -export interface RxDataBasicImageGeneric { +export interface RxDataBasicImageGeneric extends WidgetData { stretch: boolean; refreshInterval: number; refreshOnWakeUp: boolean; diff --git a/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/Basic/BasicViewInWidget8.tsx b/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/Basic/BasicViewInWidget8.tsx index 515a7b4e7..6f5ca3cd8 100644 --- a/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/Basic/BasicViewInWidget8.tsx +++ b/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/Basic/BasicViewInWidget8.tsx @@ -17,10 +17,10 @@ import React, { type CSSProperties } from 'react'; import { I18n } from '@iobroker/adapter-react-v5'; -import type { RxRenderWidgetProps, RxWidgetInfo, RxWidgetInfoGroup } from '@iobroker/types-vis-2'; +import type { RxRenderWidgetProps, RxWidgetInfo, RxWidgetInfoGroup, WidgetData } from '@iobroker/types-vis-2'; import VisRxWidget from '../../visRxWidget'; -interface RxData { +interface RxData extends WidgetData { oid: string; count: number; [key: `contains_view_${number}`]: string; diff --git a/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/JQui/JQuiSlider.tsx b/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/JQui/JQuiSlider.tsx index a78cc441f..2449f3b93 100644 --- a/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/JQui/JQuiSlider.tsx +++ b/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/JQui/JQuiSlider.tsx @@ -19,16 +19,17 @@ import { FormControl, FormLabel, Slider, Stack, LinearProgress } from '@mui/mate import { Icon, type LegacyConnection } from '@iobroker/adapter-react-v5'; -import VisRxWidget, { type VisRxData, type VisRxWidgetState } from '../../visRxWidget'; +import VisRxWidget, { type VisRxWidgetState } from '../../visRxWidget'; import type { RxRenderWidgetProps, RxWidgetInfo, RxWidgetInfoAttributesField, VisBaseWidgetProps, + WidgetData, Writeable, } from '@iobroker/types-vis-2'; -interface RxData extends VisRxData { +interface RxData extends WidgetData { type: 'single' | 'range'; oid: string; click_id: string; diff --git a/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/Swipe/Swipe.tsx b/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/Swipe/Swipe.tsx index 6f4d78d85..f702ea2be 100644 --- a/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/Swipe/Swipe.tsx +++ b/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/Swipe/Swipe.tsx @@ -16,11 +16,11 @@ import React from 'react'; import { I18n } from '@iobroker/adapter-react-v5'; -import type { RxRenderWidgetProps, RxWidgetInfo } from '@iobroker/types-vis-2'; +import type { RxRenderWidgetProps, RxWidgetInfo, WidgetData } from '@iobroker/types-vis-2'; import VisRxWidget from '../../visRxWidget'; import InstallSwipe from './InstallSwipe'; -interface RxData { +interface RxData extends WidgetData { left_nav_view: string; right_nav_view: string; hideIndication: boolean; diff --git a/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/Tabs/TabsSliderTabs.tsx b/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/Tabs/TabsSliderTabs.tsx index c466ff715..7a9b4a993 100644 --- a/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/Tabs/TabsSliderTabs.tsx +++ b/packages/iobroker.vis-2/src-vis/src/Vis/Widgets/Tabs/TabsSliderTabs.tsx @@ -18,10 +18,10 @@ import React from 'react'; import { Tab, Tabs } from '@mui/material'; import { Icon } from '@iobroker/adapter-react-v5'; -import type { RxRenderWidgetProps, RxWidgetInfo } from '@iobroker/types-vis-2'; +import type { RxRenderWidgetProps, RxWidgetInfo, WidgetData } from '@iobroker/types-vis-2'; import VisRxWidget, { type VisRxWidgetState } from '../../visRxWidget'; -interface RxData { +interface RxData extends WidgetData { show_tabs: number; vertical: boolean; variant: '' | 'centered' | 'fullWidth'; diff --git a/packages/iobroker.vis-2/src-vis/src/Vis/visEngine.tsx b/packages/iobroker.vis-2/src-vis/src/Vis/visEngine.tsx index eaafbeeae..ee87ed314 100644 --- a/packages/iobroker.vis-2/src-vis/src/Vis/visEngine.tsx +++ b/packages/iobroker.vis-2/src-vis/src/Vis/visEngine.tsx @@ -55,6 +55,11 @@ import type { VisFormatUtils as VisFormatUtilsType, VisCanWidgetStateValues, CanObservable, + LegacyVisConnection, + VisBinding, + Widget, + WidgetData, + VisRxWidgetStateValues, } from '@iobroker/types-vis-2'; import type Editor from '@/Editor'; import { deepClone } from '@/Utils/utils'; @@ -252,8 +257,8 @@ class VisEngine extends React.Component { statesDebounce: Record< string, { - state: any; - timeout: number; + state: ioBroker.StateValue | null; + timeout: ReturnType | number; } >; @@ -289,7 +294,7 @@ class VisEngine extends React.Component { viewsActiveFilter: Record; // eslint-disable-next-line react/no-unused-class-component-methods - defaultMode: any; + defaultMode: number; can: any; @@ -406,15 +411,15 @@ class VisEngine extends React.Component { this.vis.language = systemConfig.common.language || 'en'; this.systemConfig = systemConfig; - this.props.socket.subscribeState( + void this.props.socket.subscribeState( this.ID_CONTROL_INSTANCE, this.onStateChange as ioBroker.StateChangeHandler, ); - this.props.socket.subscribeState( + void this.props.socket.subscribeState( this.ID_CONTROL_DATA, this.onStateChange as ioBroker.StateChangeHandler, ); - this.props.socket.subscribeState( + void this.props.socket.subscribeState( this.ID_CONTROL_COMMAND, this.onStateChange as ioBroker.StateChangeHandler, ); @@ -636,7 +641,13 @@ class VisEngine extends React.Component { activeWidgets: [], navChangeCallbacks: [], editMode: !!this.props.editMode, - binds: {}, + binds: { + basic: null, + table: null, + jqplot: null, + jqueryui: null, + swipe: null, + }, views: store.getState().visProject, activeView: this.props.selectedView, language: this.props.lang, @@ -809,7 +820,9 @@ class VisEngine extends React.Component { } }, registerOnChange: (callback: any, arg: string, wid: AnyWidgetId) => { - !wid && console.warn('No widget ID for registerOnChange callback! Please fix'); + if (!wid) { + console.warn('No widget ID for registerOnChange callback! Please fix'); + } if ( !this.onChangeCallbacks.find( @@ -841,7 +854,7 @@ class VisEngine extends React.Component { window.localStorage.setItem('visInstance', instance); return this.instance; }, - findByRoles: (stateId, roles) => { + findByRoles: (stateId: string, roles: string[]): Record => { if (typeof roles !== 'object') { roles = [roles]; } else { @@ -892,7 +905,7 @@ class VisEngine extends React.Component { } return result; }, - findByName: (stateId, objName) => { + findByName: (stateId: string, objName: string): string | false => { // try to detect other values // Go through all channels of this device @@ -919,7 +932,7 @@ class VisEngine extends React.Component { }, hideShowAttr: widAttr => console.warn('hideShowAttr is deprecated: ', widAttr), bindingsCache: {}, - extractBinding: (format, doNotIgnoreEditMode) => { + extractBinding: (format: string, doNotIgnoreEditMode: boolean): VisBinding[] | null => { if ((!doNotIgnoreEditMode && !!this.props.editMode) || !format) { return null; } @@ -928,17 +941,23 @@ class VisEngine extends React.Component { return JSON.parse(JSON.stringify(this.vis.bindingsCache[format])); } - const result = extractBinding(format); + const result: VisBinding[] | null = extractBinding(format); // cache bindings if (result) { - this.vis.bindingsCache = this.vis.bindingsCache || {}; this.vis.bindingsCache[format] = JSON.parse(JSON.stringify(result)); } return result; }, - formatBinding: (format, view, wid, widget, widgetData, values) => + formatBinding: ( + format: string, + view: string, + wid: AnyWidgetId, + widget: Widget, + widgetData: WidgetData, + values: VisRxWidgetStateValues, + ): string => this.formatUtils.formatBinding({ format, view, @@ -948,7 +967,7 @@ class VisEngine extends React.Component { values, moment, }), - getViewOfWidget: id => { + getViewOfWidget: (id: AnyWidgetId): string => { const views = store.getState().visProject; // find a view of this widget for (const v in views) { @@ -961,18 +980,23 @@ class VisEngine extends React.Component { } return null; }, - confirmMessage: (message, title, icon, width, callback) => - this.props.onConfirmDialog(message, title, icon, width, callback), + confirmMessage: ( + message: string, + title: string, + icon: string, + width: number, + callback: () => boolean, + ): void => this.props.onConfirmDialog(message, title, icon, width, callback), config: {}, // storage of dialog positions and size (Deprecated) showCode: (code, title, mode) => this.props.onShowCode(code, title, mode), - findCommonAttributes: (/* view, widgets */) => { + findCommonAttributes: (/* view, widgets */): void => { // }, - bindWidgetClick: () => { + bindWidgetClick: (): void => { // used in vis.1 // do nothing, as it is not required in react }, - preloadImages: srcs => { + preloadImages: (srcs: string[]): void => { // preload images this.preloadImagesCacheImgs = this.preloadImagesCacheImgs || []; this.preloadImagesCacheSrcs = this.preloadImagesCacheSrcs || []; @@ -989,9 +1013,9 @@ class VisEngine extends React.Component { } }, updateStates: data => { - data && + if (data) { Object.keys(data).forEach(id => { - let state = data[id]; + let state: ioBroker.State = data[id]; if (id.startsWith('local_')) { // if it is a local variable, we have to initiate this @@ -1004,14 +1028,17 @@ class VisEngine extends React.Component { user: this.props.currentUser ? this.props.currentUser._id : 'system.user.admin', q: 0, }; + this.onStateChange(id, state); + return; } if (!state) { return; } - this.setValue(id, state); + this.setValue(id, state.val); }); + } }, getHistory: (id, options, cb) => { options = options || {}; @@ -1198,7 +1225,7 @@ class VisEngine extends React.Component { } // allows sending command to view - onCommand = (view: string, command: ViewCommand, data: ViewCommandOptions): void => { + onCommand = (view: string, command: ViewCommand, data?: ViewCommandOptions): void => { if (this.refViews[view]?.onCommand) { this.refViews[view].onCommand(command, data); } @@ -1297,42 +1324,7 @@ class VisEngine extends React.Component { ); } - createConnection(): { - namespace: string; - logError: (errorText: string) => void; - getIsConnected: () => boolean; - getGroups: ( - groupName: string | ((result: any) => void) | boolean, - useCache: boolean | ((result: any) => void), - cb: (result: any) => void, - ) => void; - getConfig: ( - useCache: boolean, - cb?: (error: string | null, systemConfig?: ioBroker.SystemConfigCommon) => void, - ) => void; - getObjects: (useCache?: boolean) => Promise>; - getLoggedUser: (cb: (isSecure: boolean, user: string) => void) => void; - subscribe: (IDs: string[], cb: () => void) => void; - unsubscribe: (IDs: string[], cb: () => void) => void; - authenticate: (user: string, password: string, salt: string) => void; - getStates: (IDs: string, cb: (arg1: any, arg2?: any) => void) => void; - setState: (id: string, val: any, cb: (arg1?: any) => void) => void; - sendTo: (instance: string, command: string, data: any, cb?: (result: Record) => void) => void; - setReloadTimeout: () => void; - setReconnectInterval: (interval: number) => void; - getUser: () => string; - sendCommand: (instance: string, command: string, data: any, ack: boolean) => Promise; - readFile: (filename: string, cb: (arg1: any, arg2?: any, arg3?: any, arg4?: any) => void) => Promise; - getHistory: ( - id: string, - options: ioBroker.GetHistoryOptions & { timeout: number }, - cb: (arg1: any, arg2?: any) => void, - ) => void; - getHttp: (url: string, callback: (data: any) => void) => boolean; - _socket: { - emit: (cmd: string, data: any, cb: (arg1: any, arg2?: any) => void) => void; - }; - } { + createConnection(): LegacyVisConnection { // props.socket return { namespace: this.props.adapterId, @@ -1420,7 +1412,7 @@ class VisEngine extends React.Component { // find out the default file mode if (objects[instance]?.native?.defaultFileMode) { // eslint-disable-next-line react/no-unused-class-component-methods - this.defaultMode = objects[instance].native.defaultFileMode; + this.defaultMode = objects[instance].native.defaultFileMode as number; } return objects; @@ -1449,19 +1441,24 @@ class VisEngine extends React.Component { }; } }, - getStates: (IDs: string, cb: (arg1: any, arg2?: any) => void): void => { - if (!IDs || !IDs.length) { - cb && cb(null, {}); + getStates: ( + ids: string, + cb: (error: Error | null, states?: Record) => void, + ): void => { + if (!ids || !ids.length) { + if (cb) { + cb(null, {}); + } return; } this.props.socket - .getForeignStates(IDs) + .getForeignStates(ids) .then(data => cb(null, data)) .catch(error => cb(error || 'Authentication required')); }, - setState: (id: string, val: any, cb: (arg1?: any) => void): void => { + setState: (id: string, val: ioBroker.StateValue, cb: (error?: Error | null) => void): void => { if (!id) { - cb && cb('No id'); + cb && cb(new Error('No id')); return; } this.props.socket @@ -1487,7 +1484,7 @@ class VisEngine extends React.Component { // }, getUser: (): string => this.userName, - sendCommand: (instance: string, command: string, data: any, ack: boolean): Promise => + sendCommand: (instance: string, command: string, data: any, ack?: boolean): Promise => this.props.socket .setState(this.ID_CONTROL_INSTANCE, { val: instance || 'notdefined', ack: true }) .then(() => this.props.socket.setState(this.ID_CONTROL_DATA, { val: data, ack: true })) @@ -1500,7 +1497,7 @@ class VisEngine extends React.Component { .catch(e => console.error(`Cannot set state: ${e}`)), readFile: ( filename: string, - cb: (arg1: any, arg2?: any, arg3?: any, arg4?: any) => void, + cb: (error: Error | null, data?: string | Buffer, filename?: string, mimeType?: string) => void, ): Promise => { let adapter = this.conn.namespace; if (filename[0] === '/') { @@ -1519,17 +1516,17 @@ class VisEngine extends React.Component { getHistory: ( id: string, options: ioBroker.GetHistoryOptions & { timeout: number }, - cb: (arg1: any, arg2?: any) => void, + cb: (error: Error | null, result?: ioBroker.GetHistoryResult) => void, ): void => { options = options || ({} as ioBroker.GetHistoryOptions & { timeout: number }); options.timeout = options.timeout || 2000; let timeout = setTimeout(() => { timeout = null; - cb('timeout'); + cb(new Error('timeout')); }, options.timeout); - this.props.socket + void this.props.socket .getHistory(id, options) .then(result => { if (timeout) { @@ -1549,7 +1546,7 @@ class VisEngine extends React.Component { getHttp: (url: string, callback: (data: any) => void): boolean => this.props.socket.getRawSocket().emit('httpGet', url, (data: any): void => callback && callback(data)), _socket: { - emit: (cmd: string, data: any, cb: (arg1: any, arg2?: any) => void): void => { + emit: (cmd: string, data: any, cb: (error: Error | null, arg2?: any) => void): void => { let promise; if (cmd === 'getObject') { promise = this.props.socket.getObject(data); @@ -1730,7 +1727,7 @@ class VisEngine extends React.Component { */ } - _setValue(id: string, val: any): void { + _setValue(id: string, val: ioBroker.StateValue): void { const oldVal = this.canStates.attr(`${id}.val`); // Send ack=false with new value to all widgets @@ -1758,9 +1755,9 @@ class VisEngine extends React.Component { }); } - setValue = (id: string, val: any): void => { + setValue = (id: string, val: ioBroker.StateValue): void => { if (!id) { - console.log(`ID is null for val=${val}`); + console.log(`ID is null for val=${JSON.stringify(val)}`); return; } @@ -2095,18 +2092,7 @@ class VisEngine extends React.Component { return false; } - onStateChange = ( - id: string, - state: Partial< - ioBroker.State & { - val: { - instance: string; - command: string; - data: any; - }; - } - >, - ): void => { + onStateChange = (id: string, state: ioBroker.SettableState | null | undefined): void => { if (!id || state === null || typeof state !== 'object') { return; } @@ -2121,6 +2107,7 @@ class VisEngine extends React.Component { return; } + let command: { instance: string; command: string; data: any } | undefined; // if command is a JSON string if ( state.val && @@ -2130,15 +2117,15 @@ class VisEngine extends React.Component { ) { // try to parse it try { - state.val = JSON.parse(state.val); + command = JSON.parse(state.val); } catch { console.warn(`Command seems to be an object, but cannot parse it: ${state.val}`); } } // if command is an object {instance: 'iii', command: 'cmd', data: 'ddd'} - if (state.val?.instance) { - if (this.onUserCommand(state.val.instance, state.val.command, state.val.data)) { + if (command?.instance) { + if (this.onUserCommand(command.instance, command.command, command.data)) { // clear state this.props.socket .setState(id, { val: '', ack: true }) @@ -2209,19 +2196,15 @@ class VisEngine extends React.Component { } // process visibility - this.linkContext.visibility[id]?.forEach(item => { - this.updateWidget(item.view, item.widget, 'visibility', item); - }); + this.linkContext.visibility[id]?.forEach(item => this.updateWidget(item.view, item.widget, 'visibility', item)); // process signals - this.linkContext.signals[id]?.forEach(item => { - this.updateWidget(item.view, item.widget, 'signal', item, id); - }); + this.linkContext.signals[id]?.forEach(item => this.updateWidget(item.view, item.widget, 'signal', item, id)); // Process last update - this.linkContext.lastChanges[id]?.forEach(item => { - this.updateWidget(item.view, item.widget, 'lastChange', item, id); - }); + this.linkContext.lastChanges[id]?.forEach(item => + this.updateWidget(item.view, item.widget, 'lastChange', item, id), + ); // Bindings on every element this.linkContext.bindings[id]?.forEach(item => this.updateWidget(item.view, item.widget, 'binding', item, id)); @@ -2251,7 +2234,7 @@ class VisEngine extends React.Component { console.log(`[${new Date().toISOString()}] +SUBSCRIBE: ${id}`); this.createCanState(id); if (!id.startsWith('local_')) { - this.props.socket.subscribeState(id, this.onStateChange as ioBroker.StateChangeHandler); + void this.props.socket.subscribeState(id, this.onStateChange as ioBroker.StateChangeHandler); } } }); @@ -2454,7 +2437,9 @@ ${this.scripts} ); // inform the legacy widgets - window.jQuery && (window.jQuery as any)(window).trigger('viewChanged', this.props.activeView); + if (window.jQuery) { + (window as any).jQuery(window).trigger('viewChanged', this.props.activeView); + } } this.visContext = { diff --git a/packages/iobroker.vis-2/src-vis/src/Vis/visRxWidget.tsx b/packages/iobroker.vis-2/src-vis/src/Vis/visRxWidget.tsx index 3bcd10056..eb3352451 100644 --- a/packages/iobroker.vis-2/src-vis/src/Vis/visRxWidget.tsx +++ b/packages/iobroker.vis-2/src-vis/src/Vis/visRxWidget.tsx @@ -119,7 +119,13 @@ class VisRxWidget< private mouseDownOnView?: | null - | ((e: MouseEvent, wid: AnyWidgetId, isRelative: boolean, isResize: boolean, isDoubleClick: boolean) => void); + | (( + e: React.MouseEvent, + wid: AnyWidgetId, + isRelative: boolean, + isResize?: boolean, + isDoubleClick?: boolean, + ) => void); private bindingsTimer?: ReturnType; diff --git a/packages/iobroker.vis-2/src-vis/src/Vis/visView.tsx b/packages/iobroker.vis-2/src-vis/src/Vis/visView.tsx index f0e49d5ab..71c7b65c7 100644 --- a/packages/iobroker.vis-2/src-vis/src/Vis/visView.tsx +++ b/packages/iobroker.vis-2/src-vis/src/Vis/visView.tsx @@ -81,7 +81,13 @@ interface CreateWidgetOptions { isRelative: boolean; mouseDownOnView: | null - | ((e: MouseEvent, wid: AnyWidgetId, isRelative: boolean, isResize: boolean, isDoubleClick: boolean) => void); + | (( + e: React.MouseEvent, + wid: AnyWidgetId, + isRelative: boolean, + isResize?: boolean, + isDoubleClick?: boolean, + ) => void); moveAllowed: boolean; ignoreMouseEvents?: boolean | undefined; onIgnoreMouseEvents?: (ignore: boolean) => void; @@ -581,7 +587,13 @@ class VisView extends React.Component { // Called from Widget mouseDownOnView = this.props.context.runtime ? null - : (e: MouseEvent, wid: AnyWidgetId, _isRelative: boolean, isResize: boolean, isDoubleClick: boolean) => { + : ( + e: React.MouseEvent, + wid: AnyWidgetId, + _isRelative: boolean, + isResize?: boolean, + isDoubleClick?: boolean, + ) => { if (this.ignoreMouseEvents) { return; } diff --git a/packages/types-vis-2/index.d.ts b/packages/types-vis-2/index.d.ts index 7717842d3..6442d113d 100644 --- a/packages/types-vis-2/index.d.ts +++ b/packages/types-vis-2/index.d.ts @@ -50,7 +50,9 @@ export type WidgetReference = { x?: number, y?: number, save?: boolean, - calculateRelativeWidgetPosition?: null | ((...props: any[]) => void), + calculateRelativeWidgetPosition?: + | null + | ((id: AnyWidgetId, left: string, top: string, shadowDiv: HTMLDivElement, order: AnyWidgetId[]) => void), ) => void; onResize?: undefined | (() => void); onTempSelect?: (selected?: boolean) => void; @@ -87,8 +89,25 @@ export interface VisBaseWidgetProps { /** Function to register the widget */ askView: (command: AskViewCommand, props?: WidgetReference) => any; onIgnoreMouseEvents: (bool: boolean) => void; - onWidgetsChanged: (...props: any[]) => void; - mouseDownOnView: (...props: any[]) => void; + onWidgetsChanged: ( + changesOfWidgets: + | { + wid: AnyWidgetId; + view: string; + style: WidgetStyle; + data: WidgetData; + }[] + | null, + view: string, + viewSettings?: ViewSettings, + ) => void; + mouseDownOnView: ( + e: React.MouseEvent, + wid: AnyWidgetId, + isRelative: boolean, + isResize?: boolean, + isDoubleClick?: boolean, + ) => void; refParent: React.RefObject; // eslint-disable-next-line react/no-unused-prop-types customSettings: Record; @@ -175,29 +194,20 @@ export type RxWidgetInfoAttributesFieldText = { /** Field label (i18n) */ readonly label?: string; /** JS Function for conditional visibility */ - readonly hidden?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly hidden?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Tooltip (i18n) */ readonly tooltip?: string; /** JS Function for conditional disability */ - readonly disabled?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly disabled?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** JS Function for error */ - readonly error?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly error?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Do not show binding symbol fot this field */ readonly noBinding?: boolean; /** Callback called if the field value changed */ readonly onChange?: ( field: RxWidgetInfoAttributesField, - data: Record, - changeData: (newData: Record) => void, + data: WidgetData, + changeData: (newData: WidgetData) => void, socket: LegacyConnection, index?: number, ) => Promise; @@ -209,10 +219,7 @@ export type RxWidgetInfoAttributesFieldDelimiter = { /** It is not required here */ readonly name: string; /** JS Function for conditional visibility */ - readonly hidden?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly hidden?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); }; export type RxWidgetInfoAttributesFieldHelp = { @@ -230,10 +237,7 @@ export type RxWidgetInfoAttributesFieldHelp = { /** Field label (i18n) */ readonly label?: string; /** JS Function for conditional visibility */ - readonly hidden?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly hidden?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); }; export type RxWidgetInfoAttributesFieldHTML = { @@ -249,29 +253,20 @@ export type RxWidgetInfoAttributesFieldHTML = { /** Field label (i18n) */ readonly label?: string; /** JS Function for conditional visibility */ - readonly hidden?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly hidden?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Tooltip (i18n) */ readonly tooltip?: string; /** JS Function for conditional disability */ - readonly disabled?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly disabled?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** JS Function for error */ - readonly error?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly error?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Do not show binding symbol fot this field */ readonly noBinding?: boolean; /** Callback called if the field value changed */ readonly onChange?: ( field: RxWidgetInfoAttributesField, - data: Record, - changeData: (newData: Record) => void, + data: WidgetData, + changeData: (newData: WidgetData) => void, socket: LegacyConnection, index?: number, ) => Promise; @@ -286,7 +281,8 @@ export type RxWidgetInfoAttributesFieldID = { readonly noInit?: boolean; /** Do not subscribe on changes of the object */ readonly noSubscribe?: boolean; - /** Filter of objects (not JSON string, it is an object), like: + /** + * Filter of objects (not JSON string, it is an object), like: - `{common: {custom: true}}` - show only objects with some custom settings - `{common: {custom: 'sql.0'}}` - show only objects with sql.0 custom settings (only of the specific instance) - `{common: {custom: '_dataSources'}}` - show only objects of adapters `influxdb' or 'sql' or 'history' @@ -313,29 +309,20 @@ export type RxWidgetInfoAttributesFieldID = { /** Field label (i18n) */ readonly label?: string; /** JS Function for conditional visibility */ - readonly hidden?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly hidden?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Tooltip (i18n) */ readonly tooltip?: string; /** JS Function for conditional disability */ - readonly disabled?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly disabled?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** JS Function for error */ - readonly error?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly error?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Do not show binding symbol fot this field */ readonly noBinding?: boolean; /** Callback called if the field value changed */ readonly onChange?: ( field: RxWidgetInfoAttributesField, - data: Record, - changeData: (newData: Record) => void, + data: WidgetData, + changeData: (newData: WidgetData) => void, socket: LegacyConnection, index?: number, ) => Promise; @@ -358,29 +345,20 @@ export type RxWidgetInfoAttributesFieldInstance = { /** Field label (i18n) */ readonly label?: string; /** JS Function for conditional visibility */ - readonly hidden?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly hidden?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Tooltip (i18n) */ readonly tooltip?: string; /** JS Function for conditional disability */ - readonly disabled?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly disabled?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** JS Function for error */ - readonly error?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly error?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Do not show binding symbol fot this field */ readonly noBinding?: boolean; /** Callback called if the field value changed */ readonly onChange?: ( field: RxWidgetInfoAttributesField, - data: Record, - changeData: (newData: Record) => void, + data: WidgetData, + changeData: (newData: WidgetData) => void, socket: LegacyConnection, index?: number, ) => Promise; @@ -401,29 +379,20 @@ export type RxWidgetInfoAttributesFieldSelect = { /** Field label (i18n) */ readonly label?: string; /** JS Function for conditional visibility */ - readonly hidden?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly hidden?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Tooltip (i18n) */ readonly tooltip?: string; /** JS Function for conditional disability */ - readonly disabled?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly disabled?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** JS Function for error */ - readonly error?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly error?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Do not show binding symbol fot this field */ readonly noBinding?: boolean; /** Callback called if the field value changed */ readonly onChange?: ( field: RxWidgetInfoAttributesField, - data: Record, - changeData: (newData: Record) => void, + data: WidgetData, + changeData: (newData: WidgetData) => void, socket: LegacyConnection, index?: number, ) => Promise; @@ -442,29 +411,20 @@ export type RxWidgetInfoAttributesFieldCheckbox = { /** Field label (i18n) */ readonly label?: string; /** JS Function for conditional visibility */ - readonly hidden?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly hidden?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Tooltip (i18n) */ readonly tooltip?: string; /** JS Function for conditional disability */ - readonly disabled?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly disabled?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** JS Function for error */ - readonly error?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly error?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Do not show binding symbol fot this field */ readonly noBinding?: boolean; /** Callback called if the field value changed */ readonly onChange?: ( field: RxWidgetInfoAttributesField, - data: Record, - changeData: (newData: Record) => void, + data: WidgetData, + changeData: (newData: WidgetData) => void, socket: LegacyConnection, index?: number, ) => Promise; @@ -487,29 +447,20 @@ export type RxWidgetInfoAttributesFieldNumber = { /** Field label (i18n) */ readonly label?: string; /** JS Function for conditional visibility */ - readonly hidden?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly hidden?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Tooltip (i18n) */ readonly tooltip?: string; /** JS Function for conditional disability */ - readonly disabled?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly disabled?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** JS Function for error */ - readonly error?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly error?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Do not show binding symbol fot this field */ readonly noBinding?: boolean; /** Callback called if the field value changed */ readonly onChange?: ( field: RxWidgetInfoAttributesField, - data: Record, - changeData: (newData: Record) => void, + data: WidgetData, + changeData: (newData: WidgetData) => void, socket: LegacyConnection, index?: number, ) => Promise; @@ -536,29 +487,20 @@ export type RxWidgetInfoAttributesFieldSlider = { /** Field label (i18n) */ readonly label?: string; /** JS Function for conditional visibility */ - readonly hidden?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly hidden?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Tooltip (i18n) */ readonly tooltip?: string; /** JS Function for conditional disability */ - readonly disabled?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly disabled?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** JS Function for error */ - readonly error?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly error?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Do not show binding symbol fot this field */ readonly noBinding?: boolean; /** Callback called if the field value changed */ readonly onChange?: ( field: RxWidgetInfoAttributesField, - data: Record, - changeData: (newData: Record) => void, + data: WidgetData, + changeData: (newData: WidgetData) => void, socket: LegacyConnection, index?: number, ) => Promise; @@ -587,29 +529,20 @@ export type RxWidgetInfoAttributesFieldWidget = { /** Field label (i18n) */ readonly label?: string; /** JS Function for conditional visibility */ - readonly hidden?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly hidden?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Tooltip (i18n) */ readonly tooltip?: string; /** JS Function for conditional disability */ - readonly disabled?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly disabled?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** JS Function for error */ - readonly error?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly error?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Do not show binding symbol fot this field */ readonly noBinding?: boolean; /** Callback called if the field value changed */ readonly onChange?: ( field: RxWidgetInfoAttributesField, - data: Record, - changeData: (newData: Record) => void, + data: WidgetData, + changeData: (newData: WidgetData) => void, socket: LegacyConnection, index?: number, ) => Promise; @@ -628,29 +561,20 @@ export type RxWidgetInfoAttributesFieldSelectViews = { /** Field label (i18n) */ readonly label?: string; /** JS Function for conditional visibility */ - readonly hidden?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly hidden?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Tooltip (i18n) */ readonly tooltip?: string; /** JS Function for conditional disability */ - readonly disabled?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly disabled?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** JS Function for error */ - readonly error?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly error?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Do not show binding symbol fot this field */ readonly noBinding?: boolean; /** Callback called if the field value changed */ readonly onChange?: ( field: RxWidgetInfoAttributesField, - data: Record, - changeData: (newData: Record) => void, + data: WidgetData, + changeData: (newData: WidgetData) => void, socket: LegacyConnection, index?: number, ) => Promise; @@ -674,29 +598,20 @@ export type RxWidgetInfoAttributesFieldCustom = { /** Field label (i18n) */ readonly label?: string; /** JS Function for conditional visibility */ - readonly hidden?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly hidden?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Tooltip (i18n) */ readonly tooltip?: string; /** JS Function for conditional disability */ - readonly disabled?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly disabled?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** JS Function for error */ - readonly error?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly error?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Do not show binding symbol fot this field */ readonly noBinding?: boolean; /** Callback called if the field value changed */ readonly onChange?: ( field: RxWidgetInfoAttributesField, - data: Record, - changeData: (newData: Record) => void, + data: WidgetData, + changeData: (newData: WidgetData) => void, socket: LegacyConnection, index?: number, ) => Promise; @@ -728,29 +643,20 @@ export type RxWidgetInfoAttributesFieldSimple = { /** Field label (i18n) */ readonly label?: string; /** JS Function for conditional visibility */ - readonly hidden?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly hidden?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Tooltip (i18n) */ readonly tooltip?: string; /** JS Function for conditional disability */ - readonly disabled?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly disabled?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** JS Function for error */ - readonly error?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly error?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Do not show binding symbol fot this field */ readonly noBinding?: boolean; /** Callback called if the field value changed */ readonly onChange?: ( field: RxWidgetInfoAttributesField, - data: Record, - changeData: (newData: Record) => void, + data: WidgetData, + changeData: (newData: WidgetData) => void, socket: LegacyConnection, index?: number, ) => Promise; @@ -765,29 +671,20 @@ export type RxWidgetInfoAttributesFieldDefault = { /** Field label (i18n) */ readonly label?: string; /** JS Function for conditional visibility */ - readonly hidden?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly hidden?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Tooltip (i18n) */ readonly tooltip?: string; /** JS Function for conditional disability */ - readonly disabled?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly disabled?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** JS Function for error */ - readonly error?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly error?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); /** Do not show binding symbol fot this field */ readonly noBinding?: boolean; /** Callback called if the field value changed */ readonly onChange?: ( field: RxWidgetInfoAttributesField, - data: Record, - changeData: (newData: Record) => void, + data: WidgetData, + changeData: (newData: WidgetData) => void, socket: LegacyConnection, index?: number, ) => Promise; @@ -1006,7 +903,7 @@ export interface SingleWidget { /** Permissions for each user for the widget */ permissions?: UserPermissions; /** This widget was taken from a marketplace */ - marketplace?: any; + marketplace?: MarketplaceWidgetRevision; /** Indicator that this widget is used in another widget (e.g., in panel) */ usedInWidget?: boolean; /** CSS for this widget */ @@ -1195,17 +1092,64 @@ export interface VisCanWidgetStateValues extends VisRxWidgetStateValues { removeAttr: (id: string) => void; } +export interface LegacyVisConnection { + namespace: string; + logError: (errorText: string) => void; + getIsConnected: () => boolean; + getGroups: ( + groupName: string | ((result: any) => void) | boolean, + useCache: boolean | ((result: any) => void), + cb: (result: any) => void, + ) => void; + getConfig: ( + useCache: boolean, + cb?: (error: string | null, systemConfig?: ioBroker.SystemConfigCommon) => void, + ) => void; + getObjects: (useCache?: boolean) => Promise>; + getLoggedUser: (cb: (isSecure: boolean, user: string) => void) => void; + subscribe: (ids: string[], cb: () => void) => void; + unsubscribe: (ids: string[], cb: () => void) => void; + authenticate: (user: string, password: string, salt: string) => void; + getStates: (ids: string, cb: (error: Error | null, states?: Record) => void) => void; + setState: (id: string, val: ioBroker.StateValue, cb: (error?: Error | null) => void) => void; + sendTo: (instance: string, command: string, data: any, cb?: (result: Record) => void) => void; + setReloadTimeout: () => void; + setReconnectInterval: (interval: number) => void; + getUser: () => string; + sendCommand: (instance: string, command: string, data: any, ack?: boolean) => Promise; + readFile: ( + filename: string, + cb: (error: Error | null, data?: string | Buffer, filename?: string, mimeType?: string) => void, + ) => Promise; + getHistory: ( + id: string, + options: ioBroker.GetHistoryOptions & { timeout: number }, + cb: (error: Error | null, result?: ioBroker.GetHistoryResult) => void, + ) => void; + getHttp: (url: string, callback: (data: any) => void) => boolean; + _socket: { + emit: (cmd: string, data: any, cb: (arg1: any, arg2?: any) => void) => void; + }; +} + export interface VisLegacy { instance: string; - navChangeCallbacks: (() => void)[]; + navChangeCallbacks: ((view: string) => void)[]; findNearestResolution: (width?: number, height?: number) => string; version: number; states: VisCanWidgetStateValues; - objects: Record; + objects: Record; isTouch: boolean; activeWidgets: string[]; editMode: boolean; - binds: any; + binds: { + basic: any; + table: any; + jqplot: any; + jqueryui: any; + swipe: any; + [visWidgetSet: string]: any; + }; views: Project; activeView: string; language: string; @@ -1217,7 +1161,7 @@ export interface VisLegacy { viewsActiveFilter: Record; onChangeCallbacks: ArgumentChanged[]; subscribing: Subscribing; - conn: any; + conn: LegacyVisConnection; lastChangedView: string | null; // used in vis-2 to save last sent view name over vis-2.0.command updateContainers: () => void; renderView: (viewDiv: string, view: string, hidden: boolean, cb: (viewDiv: string, view: string) => void) => void; @@ -1253,14 +1197,22 @@ export interface VisLegacy { ) => void; showWidgetHelper: (viewDiv: string, view: string, wid: string, isShow: boolean) => void; addFont: (fontName: string) => void; - registerOnChange: (callback: any, arg: string, wid: AnyWidgetId) => void; - unregisterOnChange: (callback: any, arg: string, wid: AnyWidgetId) => void; + registerOnChange: ( + callback: (itemArg: any, wid: string, val: ioBroker.StateValue, ack: boolean, ts: number) => void, + itemArg: any, + wid: AnyWidgetId, + ) => void; + unregisterOnChange: ( + callback: (itemArg: any, wid: string, val: ioBroker.StateValue, ack: boolean, ts: number) => void, + arg: itemArg, + wid: AnyWidgetId, + ) => void; generateInstance: () => string; - findByRoles: (stateId: string, roles: string[]) => any; - findByName: (stateId: string, objName: string) => any; + findByRoles: (stateId: string, roles: string[]) => Record; + findByName: (stateId: string, objName: string) => string | false; hideShowAttr: (widAttr: string) => void; - bindingsCache: Record; - extractBinding: (format: string, doNotIgnoreEditMode?: boolean) => any; + bindingsCache: Record; + extractBinding: (format: string, doNotIgnoreEditMode?: boolean) => VisBinding[] | null; formatBinding: ( format: string, view: string, @@ -1667,8 +1619,8 @@ export interface VisContext { | { wid: AnyWidgetId; view: string; - style?: Record; - data?: Record; + style?: WidgetStyle; + data?: WidgetData; }[] | null, view?: string, @@ -1741,7 +1693,7 @@ export interface CustomPaletteProperties { themeType: 'dark' | 'light'; helpers: { deviceIcons: Record; - detectDevices: (socket: LegacyConnection) => Promise; + detectDevices: (socket: LegacyConnection) => Promise; getObjectIcon: (obj: ioBroker.Object, id?: string, imagePrefix?: string) => string; allObjects: (socket: LegacyConnection) => Promise>; getNewWidgetId: (project: Project, offset?: number) => SingleWidgetId; @@ -1759,10 +1711,7 @@ interface RxWidgetInfoGroup { readonly label?: string; readonly indexFrom?: number; readonly indexTo?: string; - readonly hidden?: - | string - | ((data: Record) => boolean) - | ((data: Record, index: number) => boolean); + readonly hidden?: string | ((data: WidgetData) => boolean) | ((data: WidgetData, index: number) => boolean); } interface RxWidgetInfo {