Commit 814a685d761e289f4a0e3203e50088d6e87bb92b

Authored by Vladyslav_Prykhodko
1 parent 23121c5b

UI: Added conditionally show widget table cell button action

@@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
18 "resources": [], 18 "resources": [],
19 "templateHtml": "<tb-alarms-table-widget \n [ctx]=\"ctx\">\n</tb-alarms-table-widget>", 19 "templateHtml": "<tb-alarms-table-widget \n [ctx]=\"ctx\">\n</tb-alarms-table-widget>",
20 "templateCss": "", 20 "templateCss": "",
21 - "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.alarmsTableWidget.onDataUpdated();\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n }\n };\n}\n\nself.onDestroy = function() {\n}\n", 21 + "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.alarmsTableWidget.onDataUpdated();\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true,\n hasShowCondition: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n }\n };\n}\n\nself.onDestroy = function() {\n}\n",
22 "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"AlarmTableSettings\",\n \"properties\": {\n \"alarmsTitle\": {\n \"title\": \"Alarms table title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"enableSelection\": {\n \"title\": \"Enable alarms selection\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableSearch\": {\n \"title\": \"Enable alarms search\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableSelectColumnDisplay\": {\n \"title\": \"Enable select columns to display\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableFilter\": {\n \"title\": \"Enable alarm filter\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableStickyHeader\": {\n \"title\": \"Always display header\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableStickyAction\": {\n \"title\": \"Always display actions column\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"displayDetails\": {\n \"title\": \"Display alarm details\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"allowAcknowledgment\": {\n \"title\": \"Allow alarms acknowledgment\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"allowClear\": {\n \"title\": \"Allow alarms clear\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"displayPagination\": {\n \"title\": \"Display pagination\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"defaultPageSize\": {\n \"title\": \"Default page size\",\n \"type\": \"number\",\n \"default\": 10\n },\n \"defaultSortOrder\": {\n \"title\": \"Default sort order\",\n \"type\": \"string\",\n \"default\": \"-createdTime\"\n },\n \"useRowStyleFunction\": {\n \"title\": \"Use row style function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"rowStyleFunction\": {\n \"title\": \"Row style function: f(alarm, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"alarmsTitle\",\n \"enableSelection\",\n \"enableSearch\",\n \"enableSelectColumnDisplay\",\n \"enableFilter\",\n \"enableStickyHeader\",\n \"enableStickyAction\",\n \"displayDetails\",\n \"allowAcknowledgment\",\n \"allowClear\",\n \"displayPagination\",\n \"defaultPageSize\",\n \"defaultSortOrder\",\n \"useRowStyleFunction\",\n {\n \"key\": \"rowStyleFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useRowStyleFunction === true\"\n }\n ]\n}", 22 "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"AlarmTableSettings\",\n \"properties\": {\n \"alarmsTitle\": {\n \"title\": \"Alarms table title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"enableSelection\": {\n \"title\": \"Enable alarms selection\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableSearch\": {\n \"title\": \"Enable alarms search\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableSelectColumnDisplay\": {\n \"title\": \"Enable select columns to display\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableFilter\": {\n \"title\": \"Enable alarm filter\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableStickyHeader\": {\n \"title\": \"Always display header\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableStickyAction\": {\n \"title\": \"Always display actions column\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"displayDetails\": {\n \"title\": \"Display alarm details\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"allowAcknowledgment\": {\n \"title\": \"Allow alarms acknowledgment\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"allowClear\": {\n \"title\": \"Allow alarms clear\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"displayPagination\": {\n \"title\": \"Display pagination\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"defaultPageSize\": {\n \"title\": \"Default page size\",\n \"type\": \"number\",\n \"default\": 10\n },\n \"defaultSortOrder\": {\n \"title\": \"Default sort order\",\n \"type\": \"string\",\n \"default\": \"-createdTime\"\n },\n \"useRowStyleFunction\": {\n \"title\": \"Use row style function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"rowStyleFunction\": {\n \"title\": \"Row style function: f(alarm, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"alarmsTitle\",\n \"enableSelection\",\n \"enableSearch\",\n \"enableSelectColumnDisplay\",\n \"enableFilter\",\n \"enableStickyHeader\",\n \"enableStickyAction\",\n \"displayDetails\",\n \"allowAcknowledgment\",\n \"allowClear\",\n \"displayPagination\",\n \"defaultPageSize\",\n \"defaultSortOrder\",\n \"useRowStyleFunction\",\n {\n \"key\": \"rowStyleFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useRowStyleFunction === true\"\n }\n ]\n}",
23 "dataKeySettingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"DataKeySettings\",\n \"properties\": {\n \"columnWidth\": {\n \"title\": \"Column width (px or %)\",\n \"type\": \"string\",\n \"default\": \"0px\"\n },\n \"useCellStyleFunction\": {\n \"title\": \"Use cell style function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellStyleFunction\": {\n \"title\": \"Cell style function: f(value, alarm, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"useCellContentFunction\": {\n \"title\": \"Use cell content function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellContentFunction\": {\n \"title\": \"Cell content function: f(value, alarm, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"defaultColumnVisibility\": {\n \"title\": \"Default column visibility\",\n \"type\": \"string\",\n \"default\": \"visible\"\n },\n \"columnSelectionToDisplay\": {\n \"title\": \"Column selection in 'Columns to Display'\",\n \"type\": \"string\",\n \"default\": \"enabled\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"columnWidth\",\n \"useCellStyleFunction\",\n {\n \"key\": \"cellStyleFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useCellStyleFunction === true\"\n },\n \"useCellContentFunction\",\n {\n \"key\": \"cellContentFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useCellContentFunction === true\"\n },\n {\n \"key\": \"defaultColumnVisibility\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"visible\",\n \"label\": \"Visible\"\n },\n {\n \"value\": \"hidden\",\n \"label\": \"Hidden\"\n } \n ]\n },\n {\n \"key\": \"columnSelectionToDisplay\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"enabled\",\n \"label\": \"Enabled\"\n },\n {\n \"value\": \"disabled\",\n \"label\": \"Disabled\"\n } \n ]\n }\n ]\n}", 23 "dataKeySettingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"DataKeySettings\",\n \"properties\": {\n \"columnWidth\": {\n \"title\": \"Column width (px or %)\",\n \"type\": \"string\",\n \"default\": \"0px\"\n },\n \"useCellStyleFunction\": {\n \"title\": \"Use cell style function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellStyleFunction\": {\n \"title\": \"Cell style function: f(value, alarm, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"useCellContentFunction\": {\n \"title\": \"Use cell content function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellContentFunction\": {\n \"title\": \"Cell content function: f(value, alarm, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"defaultColumnVisibility\": {\n \"title\": \"Default column visibility\",\n \"type\": \"string\",\n \"default\": \"visible\"\n },\n \"columnSelectionToDisplay\": {\n \"title\": \"Column selection in 'Columns to Display'\",\n \"type\": \"string\",\n \"default\": \"enabled\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"columnWidth\",\n \"useCellStyleFunction\",\n {\n \"key\": \"cellStyleFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useCellStyleFunction === true\"\n },\n \"useCellContentFunction\",\n {\n \"key\": \"cellContentFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useCellContentFunction === true\"\n },\n {\n \"key\": \"defaultColumnVisibility\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"visible\",\n \"label\": \"Visible\"\n },\n {\n \"value\": \"hidden\",\n \"label\": \"Hidden\"\n } \n ]\n },\n {\n \"key\": \"columnSelectionToDisplay\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"enabled\",\n \"label\": \"Enabled\"\n },\n {\n \"value\": \"disabled\",\n \"label\": \"Disabled\"\n } \n ]\n }\n ]\n}",
24 "defaultConfig": "{\"timewindow\":{\"realtime\":{\"interval\":1000,\"timewindowMs\":86400000},\"aggregation\":{\"type\":\"NONE\",\"limit\":200}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"4px\",\"settings\":{\"enableSelection\":true,\"enableSearch\":true,\"displayDetails\":true,\"allowAcknowledgment\":true,\"allowClear\":true,\"displayPagination\":true,\"defaultPageSize\":10,\"defaultSortOrder\":\"-createdTime\",\"enableSelectColumnDisplay\":true,\"enableStickyAction\":false,\"enableFilter\":true},\"title\":\"Alarms table\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":false,\"showLegend\":false,\"alarmSource\":{\"type\":\"function\",\"dataKeys\":[{\"name\":\"createdTime\",\"type\":\"alarm\",\"label\":\"Created time\",\"color\":\"#2196f3\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.021092237451093787},{\"name\":\"originator\",\"type\":\"alarm\",\"label\":\"Originator\",\"color\":\"#4caf50\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.2780007688856758},{\"name\":\"type\",\"type\":\"alarm\",\"label\":\"Type\",\"color\":\"#f44336\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.7323586880398418},{\"name\":\"severity\",\"type\":\"alarm\",\"label\":\"Severity\",\"color\":\"#ffc107\",\"settings\":{\"useCellStyleFunction\":false,\"useCellContentFunction\":false},\"_hash\":0.09927019860088193},{\"name\":\"status\",\"type\":\"alarm\",\"label\":\"Status\",\"color\":\"#607d8b\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.6588418951443418}],\"entityAliasId\":null,\"name\":\"alarms\"},\"alarmSearchStatus\":\"ANY\",\"alarmsPollingInterval\":5,\"showTitleIcon\":false,\"titleIcon\":\"more_horiz\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"widgetStyle\":{},\"displayTimewindow\":true,\"actions\":{},\"alarmStatusList\":[],\"alarmSeverityList\":[],\"alarmTypeList\":[],\"searchPropagatedAlarms\":false}" 24 "defaultConfig": "{\"timewindow\":{\"realtime\":{\"interval\":1000,\"timewindowMs\":86400000},\"aggregation\":{\"type\":\"NONE\",\"limit\":200}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"4px\",\"settings\":{\"enableSelection\":true,\"enableSearch\":true,\"displayDetails\":true,\"allowAcknowledgment\":true,\"allowClear\":true,\"displayPagination\":true,\"defaultPageSize\":10,\"defaultSortOrder\":\"-createdTime\",\"enableSelectColumnDisplay\":true,\"enableStickyAction\":false,\"enableFilter\":true},\"title\":\"Alarms table\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":false,\"showLegend\":false,\"alarmSource\":{\"type\":\"function\",\"dataKeys\":[{\"name\":\"createdTime\",\"type\":\"alarm\",\"label\":\"Created time\",\"color\":\"#2196f3\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.021092237451093787},{\"name\":\"originator\",\"type\":\"alarm\",\"label\":\"Originator\",\"color\":\"#4caf50\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.2780007688856758},{\"name\":\"type\",\"type\":\"alarm\",\"label\":\"Type\",\"color\":\"#f44336\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.7323586880398418},{\"name\":\"severity\",\"type\":\"alarm\",\"label\":\"Severity\",\"color\":\"#ffc107\",\"settings\":{\"useCellStyleFunction\":false,\"useCellContentFunction\":false},\"_hash\":0.09927019860088193},{\"name\":\"status\",\"type\":\"alarm\",\"label\":\"Status\",\"color\":\"#607d8b\",\"settings\":{\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.6588418951443418}],\"entityAliasId\":null,\"name\":\"alarms\"},\"alarmSearchStatus\":\"ANY\",\"alarmsPollingInterval\":5,\"showTitleIcon\":false,\"titleIcon\":\"more_horiz\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"widgetStyle\":{},\"displayTimewindow\":true,\"actions\":{},\"alarmStatusList\":[],\"alarmSeverityList\":[],\"alarmTypeList\":[],\"searchPropagatedAlarms\":false}"
@@ -54,7 +54,7 @@ @@ -54,7 +54,7 @@
54 "resources": [], 54 "resources": [],
55 "templateHtml": "<tb-timeseries-table-widget \n [ctx]=\"ctx\">\n</tb-timeseries-table-widget>", 55 "templateHtml": "<tb-timeseries-table-widget \n [ctx]=\"ctx\">\n</tb-timeseries-table-widget>",
56 "templateCss": "", 56 "templateCss": "",
57 - "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.timeseriesTableWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n ignoreDataUpdateOnIntervalTick: true\n };\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n }\n };\n}\n\nself.onDestroy = function() {\n}", 57 + "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.timeseriesTableWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n ignoreDataUpdateOnIntervalTick: true\n };\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true,\n hasShowCondition: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n }\n };\n}\n\nself.onDestroy = function() {\n}",
58 "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"TimeseriesTableSettings\",\n \"properties\": {\n \"enableSearch\": {\n \"title\": \"Enable search\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableStickyHeader\": {\n \"title\": \"Always display header\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableStickyAction\": {\n \"title\": \"Always display actions column\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"showTimestamp\": {\n \"title\": \"Display timestamp column\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"showMilliseconds\": {\n \"title\": \"Display timestamp milliseconds\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"displayPagination\": {\n \"title\": \"Display pagination\",\n \"type\": \"boolean\",\n \"default\": true\n }, \n \"useEntityLabel\": {\n \"title\": \"Use entity label in tab name\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"defaultPageSize\": {\n \"title\": \"Default page size\",\n \"type\": \"number\",\n \"default\": 10\n },\n \"hideEmptyLines\": {\n \"title\": \"Hide empty lines\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"disableStickyHeader\": {\n \"title\": \"Disable sticky header\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"useRowStyleFunction\": {\n \"title\": \"Use row style function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"rowStyleFunction\": {\n \"title\": \"Row style function: f(rowData, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"enableSearch\",\n \"enableStickyHeader\",\n \"enableStickyAction\",\n \"showTimestamp\",\n \"showMilliseconds\",\n \"displayPagination\",\n \"useEntityLabel\",\n \"defaultPageSize\",\n \"identifyDeviceSelector\",\n \"hideEmptyLines\",\n \"useRowStyleFunction\",\n {\n \"key\": \"rowStyleFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useRowStyleFunction === true\"\n }\n ]\n}", 58 "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"TimeseriesTableSettings\",\n \"properties\": {\n \"enableSearch\": {\n \"title\": \"Enable search\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableStickyHeader\": {\n \"title\": \"Always display header\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableStickyAction\": {\n \"title\": \"Always display actions column\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"showTimestamp\": {\n \"title\": \"Display timestamp column\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"showMilliseconds\": {\n \"title\": \"Display timestamp milliseconds\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"displayPagination\": {\n \"title\": \"Display pagination\",\n \"type\": \"boolean\",\n \"default\": true\n }, \n \"useEntityLabel\": {\n \"title\": \"Use entity label in tab name\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"defaultPageSize\": {\n \"title\": \"Default page size\",\n \"type\": \"number\",\n \"default\": 10\n },\n \"hideEmptyLines\": {\n \"title\": \"Hide empty lines\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"disableStickyHeader\": {\n \"title\": \"Disable sticky header\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"useRowStyleFunction\": {\n \"title\": \"Use row style function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"rowStyleFunction\": {\n \"title\": \"Row style function: f(rowData, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"enableSearch\",\n \"enableStickyHeader\",\n \"enableStickyAction\",\n \"showTimestamp\",\n \"showMilliseconds\",\n \"displayPagination\",\n \"useEntityLabel\",\n \"defaultPageSize\",\n \"identifyDeviceSelector\",\n \"hideEmptyLines\",\n \"useRowStyleFunction\",\n {\n \"key\": \"rowStyleFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useRowStyleFunction === true\"\n }\n ]\n}",
59 "dataKeySettingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"DataKeySettings\",\n \"properties\": {\n \"useCellStyleFunction\": {\n \"title\": \"Use cell style function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellStyleFunction\": {\n \"title\": \"Cell style function: f(value, rowData, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"useCellContentFunction\": {\n \"title\": \"Use cell content function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellContentFunction\": {\n \"title\": \"Cell content function: f(value, rowData, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"useCellStyleFunction\",\n {\n \"key\": \"cellStyleFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useCellStyleFunction === true\"\n },\n \"useCellContentFunction\",\n {\n \"key\": \"cellContentFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useCellContentFunction === true\"\n }\n ]\n}", 59 "dataKeySettingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"DataKeySettings\",\n \"properties\": {\n \"useCellStyleFunction\": {\n \"title\": \"Use cell style function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellStyleFunction\": {\n \"title\": \"Cell style function: f(value, rowData, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"useCellContentFunction\": {\n \"title\": \"Use cell content function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellContentFunction\": {\n \"title\": \"Cell content function: f(value, rowData, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"useCellStyleFunction\",\n {\n \"key\": \"cellStyleFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useCellStyleFunction === true\"\n },\n \"useCellContentFunction\",\n {\n \"key\": \"cellContentFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useCellContentFunction === true\"\n }\n ]\n}",
60 "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temperature °C\",\"color\":\"#2196f3\",\"settings\":{\"useCellStyleFunction\":true,\"cellStyleFunction\":\"if (value) {\\n var percent = (value + 60)/120 * 100;\\n var color = tinycolor.mix('blue', 'red', amount = percent);\\n color.setAlpha(.5);\\n return {\\n paddingLeft: '20px',\\n color: '#ffffff',\\n background: color.toRgbString(),\\n fontSize: '18px'\\n };\\n} else {\\n return {};\\n}\"},\"_hash\":0.8587686344902596,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nvar multiplier = Math.pow(10, 1 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Humidity, %\",\"color\":\"#ffc107\",\"settings\":{\"useCellStyleFunction\":true,\"cellStyleFunction\":\"if (value) {\\n var percent = value;\\n var backgroundColor = tinycolor('blue');\\n backgroundColor.setAlpha(value/100);\\n var color = 'blue';\\n if (value > 50) {\\n color = 'white';\\n }\\n \\n return {\\n paddingLeft: '20px',\\n color: color,\\n background: backgroundColor.toRgbString(),\\n fontSize: '18px'\\n };\\n} else {\\n return {};\\n}\",\"useCellContentFunction\":false},\"_hash\":0.12775350966079668,\"funcBody\":\"var value = prevValue + Math.random() * 20 - 10;\\nvar multiplier = Math.pow(10, 1 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < 5) {\\n\\tvalue = 5;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"interval\":1000,\"timewindowMs\":60000},\"aggregation\":{\"type\":\"NONE\",\"limit\":200}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"showTimestamp\":true,\"displayPagination\":true,\"defaultPageSize\":10},\"title\":\"Timeseries table\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":false,\"showLegend\":false,\"widgetStyle\":{},\"actions\":{},\"showTitleIcon\":false,\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\"}" 60 "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temperature °C\",\"color\":\"#2196f3\",\"settings\":{\"useCellStyleFunction\":true,\"cellStyleFunction\":\"if (value) {\\n var percent = (value + 60)/120 * 100;\\n var color = tinycolor.mix('blue', 'red', amount = percent);\\n color.setAlpha(.5);\\n return {\\n paddingLeft: '20px',\\n color: '#ffffff',\\n background: color.toRgbString(),\\n fontSize: '18px'\\n };\\n} else {\\n return {};\\n}\"},\"_hash\":0.8587686344902596,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nvar multiplier = Math.pow(10, 1 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Humidity, %\",\"color\":\"#ffc107\",\"settings\":{\"useCellStyleFunction\":true,\"cellStyleFunction\":\"if (value) {\\n var percent = value;\\n var backgroundColor = tinycolor('blue');\\n backgroundColor.setAlpha(value/100);\\n var color = 'blue';\\n if (value > 50) {\\n color = 'white';\\n }\\n \\n return {\\n paddingLeft: '20px',\\n color: color,\\n background: backgroundColor.toRgbString(),\\n fontSize: '18px'\\n };\\n} else {\\n return {};\\n}\",\"useCellContentFunction\":false},\"_hash\":0.12775350966079668,\"funcBody\":\"var value = prevValue + Math.random() * 20 - 10;\\nvar multiplier = Math.pow(10, 1 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < 5) {\\n\\tvalue = 5;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"interval\":1000,\"timewindowMs\":60000},\"aggregation\":{\"type\":\"NONE\",\"limit\":200}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"showTimestamp\":true,\"displayPagination\":true,\"defaultPageSize\":10},\"title\":\"Timeseries table\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":false,\"showLegend\":false,\"widgetStyle\":{},\"actions\":{},\"showTitleIcon\":false,\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\"}"
@@ -126,7 +126,7 @@ @@ -126,7 +126,7 @@
126 "resources": [], 126 "resources": [],
127 "templateHtml": "<tb-entities-table-widget \n [ctx]=\"ctx\">\n</tb-entities-table-widget>", 127 "templateHtml": "<tb-entities-table-widget \n [ctx]=\"ctx\">\n</tb-entities-table-widget>",
128 "templateCss": "", 128 "templateCss": "",
129 - "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.entitiesTableWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n hasDataPageLink: true,\n warnOnPageDataOverflow: false,\n dataKeysOptional: true\n };\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n },\n 'rowDoubleClick': {\n name: 'widget-action.row-double-click',\n multiple: false\n }\n };\n}\n\nself.onDestroy = function() {\n}\n", 129 + "controllerScript": "self.onInit = function() {\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.entitiesTableWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n hasDataPageLink: true,\n warnOnPageDataOverflow: false,\n dataKeysOptional: true\n };\n}\n\nself.actionSources = function() {\n return {\n 'actionCellButton': {\n name: 'widget-action.action-cell-button',\n multiple: true,\n hasShowCondition: true\n },\n 'rowClick': {\n name: 'widget-action.row-click',\n multiple: false\n },\n 'rowDoubleClick': {\n name: 'widget-action.row-double-click',\n multiple: false\n }\n };\n}\n\nself.onDestroy = function() {\n}\n",
130 "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"EntitiesTableSettings\",\n \"properties\": {\n \"entitiesTitle\": {\n \"title\": \"Entities table title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"enableSearch\": {\n \"title\": \"Enable entities search\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableSelectColumnDisplay\": {\n \"title\": \"Enable select columns to display\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableStickyHeader\": {\n \"title\": \"Always display header\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableStickyAction\": {\n \"title\": \"Always display actions column\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"displayEntityName\": {\n \"title\": \"Display entity name column\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"entityNameColumnTitle\": {\n \"title\": \"Entity name column title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"displayEntityLabel\": {\n \"title\": \"Display entity label column\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"entityLabelColumnTitle\": {\n \"title\": \"Entity label column title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"displayEntityType\": {\n \"title\": \"Display entity type column\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"displayPagination\": {\n \"title\": \"Display pagination\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"defaultPageSize\": {\n \"title\": \"Default page size\",\n \"type\": \"number\",\n \"default\": 10\n },\n \"defaultSortOrder\": {\n \"title\": \"Default sort order\",\n \"type\": \"string\",\n \"default\": \"entityName\"\n },\n \"useRowStyleFunction\": {\n \"title\": \"Use row style function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"rowStyleFunction\": {\n \"title\": \"Row style function: f(entity, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"entitiesTitle\",\n \"enableSearch\",\n \"enableSelectColumnDisplay\",\n \"enableStickyHeader\",\n \"enableStickyAction\",\n \"displayEntityName\",\n \"entityNameColumnTitle\",\n \"displayEntityLabel\",\n \"entityLabelColumnTitle\",\n \"displayEntityType\",\n \"displayPagination\",\n \"defaultPageSize\",\n \"defaultSortOrder\",\n \"useRowStyleFunction\",\n {\n \"key\": \"rowStyleFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useRowStyleFunction === true\"\n }\n ]\n}", 130 "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"EntitiesTableSettings\",\n \"properties\": {\n \"entitiesTitle\": {\n \"title\": \"Entities table title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"enableSearch\": {\n \"title\": \"Enable entities search\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableSelectColumnDisplay\": {\n \"title\": \"Enable select columns to display\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableStickyHeader\": {\n \"title\": \"Always display header\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"enableStickyAction\": {\n \"title\": \"Always display actions column\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"displayEntityName\": {\n \"title\": \"Display entity name column\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"entityNameColumnTitle\": {\n \"title\": \"Entity name column title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"displayEntityLabel\": {\n \"title\": \"Display entity label column\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"entityLabelColumnTitle\": {\n \"title\": \"Entity label column title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"displayEntityType\": {\n \"title\": \"Display entity type column\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"displayPagination\": {\n \"title\": \"Display pagination\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"defaultPageSize\": {\n \"title\": \"Default page size\",\n \"type\": \"number\",\n \"default\": 10\n },\n \"defaultSortOrder\": {\n \"title\": \"Default sort order\",\n \"type\": \"string\",\n \"default\": \"entityName\"\n },\n \"useRowStyleFunction\": {\n \"title\": \"Use row style function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"rowStyleFunction\": {\n \"title\": \"Row style function: f(entity, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"entitiesTitle\",\n \"enableSearch\",\n \"enableSelectColumnDisplay\",\n \"enableStickyHeader\",\n \"enableStickyAction\",\n \"displayEntityName\",\n \"entityNameColumnTitle\",\n \"displayEntityLabel\",\n \"entityLabelColumnTitle\",\n \"displayEntityType\",\n \"displayPagination\",\n \"defaultPageSize\",\n \"defaultSortOrder\",\n \"useRowStyleFunction\",\n {\n \"key\": \"rowStyleFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useRowStyleFunction === true\"\n }\n ]\n}",
131 "dataKeySettingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"DataKeySettings\",\n \"properties\": {\n \"columnWidth\": {\n \"title\": \"Column width (px or %)\",\n \"type\": \"string\",\n \"default\": \"0px\"\n },\n \"useCellStyleFunction\": {\n \"title\": \"Use cell style function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellStyleFunction\": {\n \"title\": \"Cell style function: f(value, entity, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"useCellContentFunction\": {\n \"title\": \"Use cell content function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellContentFunction\": {\n \"title\": \"Cell content function: f(value, entity, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"defaultColumnVisibility\": {\n \"title\": \"Default column visibility\",\n \"type\": \"string\",\n \"default\": \"visible\"\n },\n \"columnSelectionToDisplay\": {\n \"title\": \"Column selection in 'Columns to Display'\",\n \"type\": \"string\",\n \"default\": \"enabled\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"columnWidth\",\n \"useCellStyleFunction\",\n {\n \"key\": \"cellStyleFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useCellStyleFunction === true\"\n },\n \"useCellContentFunction\",\n {\n \"key\": \"cellContentFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useCellContentFunction === true\"\n },\n {\n \"key\": \"defaultColumnVisibility\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"visible\",\n \"label\": \"Visible\"\n },\n {\n \"value\": \"hidden\",\n \"label\": \"Hidden\"\n } \n ]\n },\n {\n \"key\": \"columnSelectionToDisplay\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"enabled\",\n \"label\": \"Enabled\"\n },\n {\n \"value\": \"disabled\",\n \"label\": \"Disabled\"\n } \n ]\n }\n ]\n}", 131 "dataKeySettingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"DataKeySettings\",\n \"properties\": {\n \"columnWidth\": {\n \"title\": \"Column width (px or %)\",\n \"type\": \"string\",\n \"default\": \"0px\"\n },\n \"useCellStyleFunction\": {\n \"title\": \"Use cell style function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellStyleFunction\": {\n \"title\": \"Cell style function: f(value, entity, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"useCellContentFunction\": {\n \"title\": \"Use cell content function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellContentFunction\": {\n \"title\": \"Cell content function: f(value, entity, ctx)\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"defaultColumnVisibility\": {\n \"title\": \"Default column visibility\",\n \"type\": \"string\",\n \"default\": \"visible\"\n },\n \"columnSelectionToDisplay\": {\n \"title\": \"Column selection in 'Columns to Display'\",\n \"type\": \"string\",\n \"default\": \"enabled\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"columnWidth\",\n \"useCellStyleFunction\",\n {\n \"key\": \"cellStyleFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useCellStyleFunction === true\"\n },\n \"useCellContentFunction\",\n {\n \"key\": \"cellContentFunction\",\n \"type\": \"javascript\",\n \"condition\": \"model.useCellContentFunction === true\"\n },\n {\n \"key\": \"defaultColumnVisibility\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"visible\",\n \"label\": \"Visible\"\n },\n {\n \"value\": \"hidden\",\n \"label\": \"Hidden\"\n } \n ]\n },\n {\n \"key\": \"columnSelectionToDisplay\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"enabled\",\n \"label\": \"Enabled\"\n },\n {\n \"value\": \"disabled\",\n \"label\": \"Disabled\"\n } \n ]\n }\n ]\n}",
132 "defaultConfig": "{\"timewindow\":{\"realtime\":{\"interval\":1000,\"timewindowMs\":86400000},\"aggregation\":{\"type\":\"NONE\",\"limit\":200}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"4px\",\"settings\":{\"enableSelection\":true,\"enableSearch\":true,\"displayDetails\":true,\"displayPagination\":true,\"defaultPageSize\":10,\"defaultSortOrder\":\"entityName\",\"displayEntityName\":true,\"displayEntityType\":true},\"title\":\"Entities table\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":false,\"showLegend\":false,\"datasources\":[{\"type\":\"function\",\"name\":\"Simulated\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Sin\",\"color\":\"#2196f3\",\"settings\":{\"columnWidth\":\"0px\",\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.472295003170325,\"funcBody\":\"return Math.round(1000*Math.sin(time/5000));\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Cos\",\"color\":\"#4caf50\",\"settings\":{\"columnWidth\":\"0px\",\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.8926244886945558,\"funcBody\":\"return Math.round(1000*Math.cos(time/5000));\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#f44336\",\"settings\":{\"columnWidth\":\"0px\",\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.6401141393938932,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}]}" 132 "defaultConfig": "{\"timewindow\":{\"realtime\":{\"interval\":1000,\"timewindowMs\":86400000},\"aggregation\":{\"type\":\"NONE\",\"limit\":200}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"4px\",\"settings\":{\"enableSelection\":true,\"enableSearch\":true,\"displayDetails\":true,\"displayPagination\":true,\"defaultPageSize\":10,\"defaultSortOrder\":\"entityName\",\"displayEntityName\":true,\"displayEntityType\":true},\"title\":\"Entities table\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":false,\"showLegend\":false,\"datasources\":[{\"type\":\"function\",\"name\":\"Simulated\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Sin\",\"color\":\"#2196f3\",\"settings\":{\"columnWidth\":\"0px\",\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.472295003170325,\"funcBody\":\"return Math.round(1000*Math.sin(time/5000));\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Cos\",\"color\":\"#4caf50\",\"settings\":{\"columnWidth\":\"0px\",\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.8926244886945558,\"funcBody\":\"return Math.round(1000*Math.cos(time/5000));\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#f44336\",\"settings\":{\"columnWidth\":\"0px\",\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.6401141393938932,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}]}"
@@ -40,7 +40,6 @@ import { @@ -40,7 +40,6 @@ import {
40 import { UtilsService } from '@core/services/utils.service'; 40 import { UtilsService } from '@core/services/utils.service';
41 import { 41 import {
42 WidgetActionSource, 42 WidgetActionSource,
43 - widgetActionSources,  
44 WidgetActionType, 43 WidgetActionType,
45 widgetActionTypeTranslationMap 44 widgetActionTypeTranslationMap
46 } from '@shared/models/widget.models'; 45 } from '@shared/models/widget.models';
@@ -150,13 +149,13 @@ export class WidgetActionDialogComponent extends DialogComponent<WidgetActionDia @@ -150,13 +149,13 @@ export class WidgetActionDialogComponent extends DialogComponent<WidgetActionDia
150 } 149 }
151 150
152 displayShowWidgetActionForm(): boolean { 151 displayShowWidgetActionForm(): boolean {
153 - return this.widgetActionFormGroup.get('actionSourceId').value === widgetActionSources.headerButton.value; 152 + return !!this.data.actionsData.actionSources[this.widgetActionFormGroup.get('actionSourceId').value]?.hasShowCondition;
154 } 153 }
155 154
156 private updateShowWidgetActionForm() { 155 private updateShowWidgetActionForm() {
157 const actionSourceId = this.widgetActionFormGroup.get('actionSourceId').value; 156 const actionSourceId = this.widgetActionFormGroup.get('actionSourceId').value;
158 const useShowWidgetActionFunction = this.widgetActionFormGroup.get('useShowWidgetActionFunction').value; 157 const useShowWidgetActionFunction = this.widgetActionFormGroup.get('useShowWidgetActionFunction').value;
159 - if (actionSourceId === widgetActionSources.headerButton.value && useShowWidgetActionFunction) { 158 + if (!!this.data.actionsData.actionSources[actionSourceId]?.hasShowCondition && useShowWidgetActionFunction) {
160 this.widgetActionFormGroup.get('showWidgetActionFunction').setValidators([Validators.required]); 159 this.widgetActionFormGroup.get('showWidgetActionFunction').setValidators([Validators.required]);
161 } else { 160 } else {
162 this.widgetActionFormGroup.get('showWidgetActionFunction').clearValidators(); 161 this.widgetActionFormGroup.get('showWidgetActionFunction').clearValidators();
@@ -87,35 +87,40 @@ @@ -87,35 +87,40 @@
87 </mat-cell> 87 </mat-cell>
88 </ng-container> 88 </ng-container>
89 <ng-container matColumnDef="actions" [stickyEnd]="enableStickyAction"> 89 <ng-container matColumnDef="actions" [stickyEnd]="enableStickyAction">
90 - <mat-header-cell *matHeaderCellDef [ngStyle.gt-md]="{ minWidth: (actionCellDescriptors.length * 40) + 'px',  
91 - maxWidth: (actionCellDescriptors.length * 40) + 'px',  
92 - width: (actionCellDescriptors.length * 40) + 'px' }"> 90 + <mat-header-cell *matHeaderCellDef [ngStyle.gt-md]="{ minWidth: (countCellButtonAction * 40) + 'px',
  91 + maxWidth: (countCellButtonAction * 40) + 'px',
  92 + width: (countCellButtonAction * 40) + 'px' }">
93 </mat-header-cell> 93 </mat-header-cell>
94 - <mat-cell *matCellDef="let alarm" [ngStyle.gt-md]="{ minWidth: (actionCellDescriptors.length * 40) + 'px',  
95 - maxWidth: (actionCellDescriptors.length * 40) + 'px',  
96 - width: (actionCellDescriptors.length * 40) + 'px' }"> 94 + <mat-cell *matCellDef="let alarm" [ngStyle.gt-md]="{ minWidth: (countCellButtonAction * 40) + 'px',
  95 + maxWidth: (countCellButtonAction * 40) + 'px',
  96 + width: (countCellButtonAction * 40) + 'px' }">
97 <div fxHide fxShow.gt-md fxFlex fxLayout="row" fxLayoutAlign="end"> 97 <div fxHide fxShow.gt-md fxFlex fxLayout="row" fxLayoutAlign="end">
98 - <button mat-button mat-icon-button [disabled]="(isLoading$ | async) || !actionEnabled(alarm, actionDescriptor)"  
99 - *ngFor="let actionDescriptor of actionCellDescriptors; trackBy: trackByActionCellDescriptionId"  
100 - matTooltip="{{ actionDescriptor.displayName }}"  
101 - matTooltipPosition="above"  
102 - (click)="onActionButtonClick($event, alarm, actionDescriptor)">  
103 - <mat-icon>{{actionDescriptor.icon}}</mat-icon>  
104 - </button> 98 + <ng-container *ngFor="let actionDescriptor of alarm.actionCellButtons; trackBy: trackByActionCellDescriptionId">
  99 + <span *ngIf="!actionDescriptor.icon" style="width: 40px;"></span>
  100 + <button mat-button mat-icon-button [disabled]="(isLoading$ | async) || !actionEnabled(alarm, actionDescriptor)"
  101 + *ngIf="actionDescriptor.icon"
  102 + matTooltip="{{ actionDescriptor.displayName }}"
  103 + matTooltipPosition="above"
  104 + (click)="onActionButtonClick($event, alarm, actionDescriptor)">
  105 + <mat-icon>{{actionDescriptor.icon}}</mat-icon>
  106 + </button>
  107 + </ng-container>
105 </div> 108 </div>
106 - <div fxHide fxShow.lt-lg *ngIf="actionCellDescriptors.length"> 109 + <div fxHide fxShow.lt-lg *ngIf="alarm.hasActions">
107 <button mat-button mat-icon-button 110 <button mat-button mat-icon-button
108 (click)="$event.stopPropagation(); ctx.detectChanges();" 111 (click)="$event.stopPropagation(); ctx.detectChanges();"
109 [matMenuTriggerFor]="cellActionsMenu"> 112 [matMenuTriggerFor]="cellActionsMenu">
110 <mat-icon class="material-icons">more_vert</mat-icon> 113 <mat-icon class="material-icons">more_vert</mat-icon>
111 </button> 114 </button>
112 <mat-menu #cellActionsMenu="matMenu" xPosition="before"> 115 <mat-menu #cellActionsMenu="matMenu" xPosition="before">
113 - <button mat-menu-item *ngFor="let actionDescriptor of actionCellDescriptors; trackBy: trackByActionCellDescriptionId"  
114 - [disabled]="(isLoading$ | async) || !actionEnabled(alarm, actionDescriptor)"  
115 - (click)="onActionButtonClick($event, alarm, actionDescriptor)">  
116 - <mat-icon>{{actionDescriptor.icon}}</mat-icon>  
117 - <span>{{ actionDescriptor.displayName }}</span>  
118 - </button> 116 + <ng-container *ngFor="let actionDescriptor of alarm.actionCellButtons; trackBy: trackByActionCellDescriptionId">
  117 + <button mat-menu-item *ngIf="actionDescriptor.icon"
  118 + [disabled]="(isLoading$ | async) || !actionEnabled(alarm, actionDescriptor)"
  119 + (click)="onActionButtonClick($event, alarm, actionDescriptor)">
  120 + <mat-icon>{{actionDescriptor.icon}}</mat-icon>
  121 + <span>{{ actionDescriptor.displayName }}</span>
  122 + </button>
  123 + </ng-container>
119 </mat-menu> 124 </mat-menu>
120 </div> 125 </div>
121 </mat-cell> 126 </mat-cell>
@@ -58,6 +58,7 @@ import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; @@ -58,6 +58,7 @@ import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
58 import { 58 import {
59 CellContentInfo, 59 CellContentInfo,
60 CellStyleInfo, 60 CellStyleInfo,
  61 + checkHasActions,
61 constructTableCssString, 62 constructTableCssString,
62 DisplayColumn, 63 DisplayColumn,
63 EntityColumn, 64 EntityColumn,
@@ -72,7 +73,10 @@ import { @@ -72,7 +73,10 @@ import {
72 getColumnSelectionAvailability, 73 getColumnSelectionAvailability,
73 getColumnWidth, 74 getColumnWidth,
74 getRowStyleInfo, 75 getRowStyleInfo,
  76 + getTableCellButtonActions,
  77 + prepareTableCellButtonActions,
75 RowStyleInfo, 78 RowStyleInfo,
  79 + TableCellButtonActionDescriptor,
76 TableWidgetDataKeySettings, 80 TableWidgetDataKeySettings,
77 TableWidgetSettings, 81 TableWidgetSettings,
78 widthStyle 82 widthStyle
@@ -130,7 +134,7 @@ interface AlarmsTableWidgetSettings extends TableWidgetSettings { @@ -130,7 +134,7 @@ interface AlarmsTableWidgetSettings extends TableWidgetSettings {
130 allowClear: boolean; 134 allowClear: boolean;
131 } 135 }
132 136
133 -interface AlarmWidgetActionDescriptor extends WidgetActionDescriptor { 137 +interface AlarmWidgetActionDescriptor extends TableCellButtonActionDescriptor {
134 details?: boolean; 138 details?: boolean;
135 acknowledge?: boolean; 139 acknowledge?: boolean;
136 clear?: boolean; 140 clear?: boolean;
@@ -160,8 +164,8 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, @@ -160,8 +164,8 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
160 public textSearchMode = false; 164 public textSearchMode = false;
161 public columns: Array<EntityColumn> = []; 165 public columns: Array<EntityColumn> = [];
162 public displayedColumns: string[] = []; 166 public displayedColumns: string[] = [];
163 - public actionCellDescriptors: AlarmWidgetActionDescriptor[] = [];  
164 public alarmsDatasource: AlarmsDatasource; 167 public alarmsDatasource: AlarmsDatasource;
  168 + public countCellButtonAction: number;
165 169
166 private cellContentCache: Array<any> = []; 170 private cellContentCache: Array<any> = [];
167 private cellStyleCache: Array<any> = []; 171 private cellStyleCache: Array<any> = [];
@@ -288,38 +292,6 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, @@ -288,38 +292,6 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
288 this.allowAcknowledgment = isDefined(this.settings.allowAcknowledgment) ? this.settings.allowAcknowledgment : true; 292 this.allowAcknowledgment = isDefined(this.settings.allowAcknowledgment) ? this.settings.allowAcknowledgment : true;
289 this.allowClear = isDefined(this.settings.allowClear) ? this.settings.allowClear : true; 293 this.allowClear = isDefined(this.settings.allowClear) ? this.settings.allowClear : true;
290 294
291 - if (this.displayDetails) {  
292 - this.actionCellDescriptors.push(  
293 - {  
294 - displayName: this.translate.instant('alarm.details'),  
295 - icon: 'more_horiz',  
296 - details: true  
297 - } as AlarmWidgetActionDescriptor  
298 - );  
299 - }  
300 -  
301 - if (this.allowAcknowledgment) {  
302 - this.actionCellDescriptors.push(  
303 - {  
304 - displayName: this.translate.instant('alarm.acknowledge'),  
305 - icon: 'done',  
306 - acknowledge: true  
307 - } as AlarmWidgetActionDescriptor  
308 - );  
309 - }  
310 -  
311 - if (this.allowClear) {  
312 - this.actionCellDescriptors.push(  
313 - {  
314 - displayName: this.translate.instant('alarm.clear'),  
315 - icon: 'clear',  
316 - clear: true  
317 - } as AlarmWidgetActionDescriptor  
318 - );  
319 - }  
320 -  
321 - this.actionCellDescriptors = this.actionCellDescriptors.concat(this.ctx.actionsApi.getActionDescriptors('actionCellButton'));  
322 -  
323 if (this.settings.alarmsTitle && this.settings.alarmsTitle.length) { 295 if (this.settings.alarmsTitle && this.settings.alarmsTitle.length) {
324 this.alarmsTitlePattern = this.utils.customTranslation(this.settings.alarmsTitle, this.settings.alarmsTitle); 296 this.alarmsTitlePattern = this.utils.customTranslation(this.settings.alarmsTitle, this.settings.alarmsTitle);
325 } else { 297 } else {
@@ -436,11 +408,44 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, @@ -436,11 +408,44 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
436 } 408 }
437 this.sortOrderProperty = sortColumn ? sortColumn.def : null; 409 this.sortOrderProperty = sortColumn ? sortColumn.def : null;
438 410
439 - if (this.actionCellDescriptors.length) { 411 + const actionCellDescriptors: AlarmWidgetActionDescriptor[] = [];
  412 + if (this.displayDetails) {
  413 + actionCellDescriptors.push(
  414 + {
  415 + displayName: this.translate.instant('alarm.details'),
  416 + icon: 'more_horiz',
  417 + details: true
  418 + } as AlarmWidgetActionDescriptor
  419 + );
  420 + }
  421 +
  422 + if (this.allowAcknowledgment) {
  423 + actionCellDescriptors.push(
  424 + {
  425 + displayName: this.translate.instant('alarm.acknowledge'),
  426 + icon: 'done',
  427 + acknowledge: true
  428 + } as AlarmWidgetActionDescriptor
  429 + );
  430 + }
  431 +
  432 + if (this.allowClear) {
  433 + actionCellDescriptors.push(
  434 + {
  435 + displayName: this.translate.instant('alarm.clear'),
  436 + icon: 'clear',
  437 + clear: true
  438 + } as AlarmWidgetActionDescriptor
  439 + );
  440 + }
  441 +
  442 + this.countCellButtonAction = actionCellDescriptors.length + this.ctx.actionsApi.getActionDescriptors('actionCellButton').length;
  443 +
  444 + if (this.countCellButtonAction) {
440 this.displayedColumns.push('actions'); 445 this.displayedColumns.push('actions');
441 } 446 }
442 447
443 - this.alarmsDatasource = new AlarmsDatasource(this.subscription, latestDataKeys, this.ngZone); 448 + this.alarmsDatasource = new AlarmsDatasource(this.subscription, latestDataKeys, this.ngZone, this.ctx, actionCellDescriptors);
444 if (this.enableSelection) { 449 if (this.enableSelection) {
445 this.alarmsDatasource.selectionModeChanged$.subscribe((selectionMode) => { 450 this.alarmsDatasource.selectionModeChanged$.subscribe((selectionMode) => {
446 const hideTitlePanel = selectionMode || this.textSearchMode; 451 const hideTitlePanel = selectionMode || this.textSearchMode;
@@ -495,7 +500,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, @@ -495,7 +500,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
495 if (this.enableSelection) { 500 if (this.enableSelection) {
496 this.displayedColumns.unshift('select'); 501 this.displayedColumns.unshift('select');
497 } 502 }
498 - if (this.actionCellDescriptors.length) { 503 + if (this.countCellButtonAction) {
499 this.displayedColumns.push('actions'); 504 this.displayedColumns.push('actions');
500 } 505 }
501 this.clearCache(); 506 this.clearCache();
@@ -986,9 +991,16 @@ class AlarmsDatasource implements DataSource<AlarmDataInfo> { @@ -986,9 +991,16 @@ class AlarmsDatasource implements DataSource<AlarmDataInfo> {
986 private appliedPageLink: AlarmDataPageLink; 991 private appliedPageLink: AlarmDataPageLink;
987 private appliedSortOrderLabel: string; 992 private appliedSortOrderLabel: string;
988 993
  994 + private cellButtonActions: TableCellButtonActionDescriptor[];
  995 + private readonly usedShowCellActionFunction: boolean;
  996 +
989 constructor(private subscription: IWidgetSubscription, 997 constructor(private subscription: IWidgetSubscription,
990 private dataKeys: Array<DataKey>, 998 private dataKeys: Array<DataKey>,
991 - private ngZone: NgZone) { 999 + private ngZone: NgZone,
  1000 + private widgetContext: WidgetContext,
  1001 + actionCellDescriptors: AlarmWidgetActionDescriptor[]) {
  1002 + this.cellButtonActions = actionCellDescriptors.concat(getTableCellButtonActions(widgetContext));
  1003 + this.usedShowCellActionFunction = this.cellButtonActions.some(action => action.useShowActionCellButtonFunction);
992 } 1004 }
993 1005
994 connect(collectionViewer: CollectionViewer): Observable<AlarmDataInfo[] | ReadonlyArray<AlarmDataInfo>> { 1006 connect(collectionViewer: CollectionViewer): Observable<AlarmDataInfo[] | ReadonlyArray<AlarmDataInfo>> {
@@ -1069,6 +1081,15 @@ class AlarmsDatasource implements DataSource<AlarmDataInfo> { @@ -1069,6 +1081,15 @@ class AlarmsDatasource implements DataSource<AlarmDataInfo> {
1069 } 1081 }
1070 alarm[dataKey.label] = value; 1082 alarm[dataKey.label] = value;
1071 }); 1083 });
  1084 + if (this.cellButtonActions.length) {
  1085 + if (this.usedShowCellActionFunction) {
  1086 + alarm.actionCellButtons = prepareTableCellButtonActions(this.widgetContext, this.cellButtonActions, alarm);
  1087 + alarm.hasActions = checkHasActions(alarm.actionCellButtons);
  1088 + } else {
  1089 + alarm.actionCellButtons = this.cellButtonActions;
  1090 + alarm.hasActions = true;
  1091 + }
  1092 + }
1072 return alarm; 1093 return alarm;
1073 } 1094 }
1074 1095
@@ -48,35 +48,40 @@ @@ -48,35 +48,40 @@
48 </mat-cell> 48 </mat-cell>
49 </ng-container> 49 </ng-container>
50 <ng-container matColumnDef="actions" [stickyEnd]="enableStickyAction"> 50 <ng-container matColumnDef="actions" [stickyEnd]="enableStickyAction">
51 - <mat-header-cell *matHeaderCellDef [ngStyle.gt-md]="{ minWidth: (actionCellDescriptors.length * 40) + 'px',  
52 - maxWidth: (actionCellDescriptors.length * 40) + 'px',  
53 - width: (actionCellDescriptors.length * 40) + 'px' }"> 51 + <mat-header-cell *matHeaderCellDef [ngStyle.gt-md]="{ minWidth: (countCellButtonAction * 40) + 'px',
  52 + maxWidth: (countCellButtonAction * 40) + 'px',
  53 + width: (countCellButtonAction * 40) + 'px' }">
54 </mat-header-cell> 54 </mat-header-cell>
55 - <mat-cell *matCellDef="let entity" [ngStyle.gt-md]="{ minWidth: (actionCellDescriptors.length * 40) + 'px',  
56 - maxWidth: (actionCellDescriptors.length * 40) + 'px',  
57 - width: (actionCellDescriptors.length * 40) + 'px' }"> 55 + <mat-cell *matCellDef="let entity" [ngStyle.gt-md]="{ minWidth: (countCellButtonAction * 40) + 'px',
  56 + maxWidth: (countCellButtonAction * 40) + 'px',
  57 + width: (countCellButtonAction * 40) + 'px' }">
58 <div fxHide fxShow.gt-md fxFlex fxLayout="row" fxLayoutAlign="end"> 58 <div fxHide fxShow.gt-md fxFlex fxLayout="row" fxLayoutAlign="end">
59 - <button mat-button mat-icon-button [disabled]="isLoading$ | async"  
60 - *ngFor="let actionDescriptor of actionCellDescriptors; trackBy: trackByActionCellDescriptionId"  
61 - matTooltip="{{ actionDescriptor.displayName }}"  
62 - matTooltipPosition="above"  
63 - (click)="onActionButtonClick($event, entity, actionDescriptor)">  
64 - <mat-icon>{{actionDescriptor.icon}}</mat-icon>  
65 - </button> 59 + <ng-container *ngFor="let actionDescriptor of entity.actionCellButtons; trackBy: trackByActionCellDescriptionId">
  60 + <span *ngIf="!actionDescriptor.icon" style="width: 40px;"></span>
  61 + <button mat-button mat-icon-button [disabled]="isLoading$ | async"
  62 + *ngIf="actionDescriptor.icon"
  63 + matTooltip="{{ actionDescriptor.displayName }}"
  64 + matTooltipPosition="above"
  65 + (click)="onActionButtonClick($event, entity, actionDescriptor)">
  66 + <mat-icon>{{actionDescriptor.icon}}</mat-icon>
  67 + </button>
  68 + </ng-container>
66 </div> 69 </div>
67 - <div fxHide fxShow.lt-lg *ngIf="actionCellDescriptors.length"> 70 + <div fxHide fxShow.lt-lg *ngIf="entity.hasActions">
68 <button mat-button mat-icon-button 71 <button mat-button mat-icon-button
69 (click)="$event.stopPropagation(); ctx.detectChanges();" 72 (click)="$event.stopPropagation(); ctx.detectChanges();"
70 [matMenuTriggerFor]="cellActionsMenu"> 73 [matMenuTriggerFor]="cellActionsMenu">
71 <mat-icon class="material-icons">more_vert</mat-icon> 74 <mat-icon class="material-icons">more_vert</mat-icon>
72 </button> 75 </button>
73 <mat-menu #cellActionsMenu="matMenu" xPosition="before"> 76 <mat-menu #cellActionsMenu="matMenu" xPosition="before">
74 - <button mat-menu-item *ngFor="let actionDescriptor of actionCellDescriptors; trackBy: trackByActionCellDescriptionId"  
75 - [disabled]="isLoading$ | async"  
76 - (click)="onActionButtonClick($event, entity, actionDescriptor)">  
77 - <mat-icon>{{actionDescriptor.icon}}</mat-icon>  
78 - <span>{{ actionDescriptor.displayName }}</span>  
79 - </button> 77 + <ng-container *ngFor="let actionDescriptor of entity.actionCellButtons; trackBy: trackByActionCellDescriptionId">
  78 + <button mat-menu-item *ngIf="actionDescriptor.icon"
  79 + [disabled]="isLoading$ | async"
  80 + (click)="onActionButtonClick($event, entity, actionDescriptor)">
  81 + <mat-icon>{{actionDescriptor.icon}}</mat-icon>
  82 + <span>{{ actionDescriptor.displayName }}</span>
  83 + </button>
  84 + </ng-container>
80 </mat-menu> 85 </mat-menu>
81 </div> 86 </div>
82 </mat-cell> 87 </mat-cell>
@@ -63,6 +63,7 @@ import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; @@ -63,6 +63,7 @@ import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
63 import { 63 import {
64 CellContentInfo, 64 CellContentInfo,
65 CellStyleInfo, 65 CellStyleInfo,
  66 + checkHasActions,
66 constructTableCssString, 67 constructTableCssString,
67 DisplayColumn, 68 DisplayColumn,
68 EntityColumn, 69 EntityColumn,
@@ -78,7 +79,10 @@ import { @@ -78,7 +79,10 @@ import {
78 getColumnWidth, 79 getColumnWidth,
79 getEntityValue, 80 getEntityValue,
80 getRowStyleInfo, 81 getRowStyleInfo,
  82 + getTableCellButtonActions,
  83 + prepareTableCellButtonActions,
81 RowStyleInfo, 84 RowStyleInfo,
  85 + TableCellButtonActionDescriptor,
82 TableWidgetDataKeySettings, 86 TableWidgetDataKeySettings,
83 TableWidgetSettings, 87 TableWidgetSettings,
84 widthStyle 88 widthStyle
@@ -136,8 +140,8 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni @@ -136,8 +140,8 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni
136 public textSearchMode = false; 140 public textSearchMode = false;
137 public columns: Array<EntityColumn> = []; 141 public columns: Array<EntityColumn> = [];
138 public displayedColumns: string[] = []; 142 public displayedColumns: string[] = [];
139 - public actionCellDescriptors: WidgetActionDescriptor[];  
140 public entityDatasource: EntityDatasource; 143 public entityDatasource: EntityDatasource;
  144 + public countCellButtonAction: number;
141 145
142 private cellContentCache: Array<any> = []; 146 private cellContentCache: Array<any> = [];
143 private cellStyleCache: Array<any> = []; 147 private cellStyleCache: Array<any> = [];
@@ -245,7 +249,7 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni @@ -245,7 +249,7 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni
245 private initializeConfig() { 249 private initializeConfig() {
246 this.ctx.widgetActions = [this.searchAction, this.columnDisplayAction]; 250 this.ctx.widgetActions = [this.searchAction, this.columnDisplayAction];
247 251
248 - this.actionCellDescriptors = this.ctx.actionsApi.getActionDescriptors('actionCellButton'); 252 + this.countCellButtonAction = this.ctx.actionsApi.getActionDescriptors('actionCellButton').length;
249 253
250 if (this.settings.entitiesTitle && this.settings.entitiesTitle.length) { 254 if (this.settings.entitiesTitle && this.settings.entitiesTitle.length) {
251 this.entitiesTitlePattern = this.utils.customTranslation(this.settings.entitiesTitle, this.settings.entitiesTitle); 255 this.entitiesTitlePattern = this.utils.customTranslation(this.settings.entitiesTitle, this.settings.entitiesTitle);
@@ -426,10 +430,10 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni @@ -426,10 +430,10 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni
426 } 430 }
427 this.sortOrderProperty = sortColumn ? sortColumn.def : null; 431 this.sortOrderProperty = sortColumn ? sortColumn.def : null;
428 432
429 - if (this.actionCellDescriptors.length) { 433 + if (this.countCellButtonAction) {
430 this.displayedColumns.push('actions'); 434 this.displayedColumns.push('actions');
431 } 435 }
432 - this.entityDatasource = new EntityDatasource(this.translate, dataKeys, this.subscription, this.ngZone); 436 + this.entityDatasource = new EntityDatasource(this.translate, dataKeys, this.subscription, this.ngZone, this.ctx);
433 } 437 }
434 438
435 private editColumnsToDisplay($event: Event) { 439 private editColumnsToDisplay($event: Event) {
@@ -470,7 +474,7 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni @@ -470,7 +474,7 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni
470 columns, 474 columns,
471 columnsUpdated: (newColumns) => { 475 columnsUpdated: (newColumns) => {
472 this.displayedColumns = newColumns.filter(column => column.display).map(column => column.def); 476 this.displayedColumns = newColumns.filter(column => column.display).map(column => column.def);
473 - if (this.actionCellDescriptors.length) { 477 + if (this.countCellButtonAction) {
474 this.displayedColumns.push('actions'); 478 this.displayedColumns.push('actions');
475 } 479 }
476 this.clearCache(); 480 this.clearCache();
@@ -713,12 +717,18 @@ class EntityDatasource implements DataSource<EntityData> { @@ -713,12 +717,18 @@ class EntityDatasource implements DataSource<EntityData> {
713 private appliedPageLink: EntityDataPageLink; 717 private appliedPageLink: EntityDataPageLink;
714 private appliedSortOrderLabel: string; 718 private appliedSortOrderLabel: string;
715 719
  720 + private cellButtonActions: TableCellButtonActionDescriptor[];
  721 + private readonly usedShowCellActionFunction: boolean;
  722 +
716 constructor( 723 constructor(
717 private translate: TranslateService, 724 private translate: TranslateService,
718 private dataKeys: Array<DataKey>, 725 private dataKeys: Array<DataKey>,
719 private subscription: IWidgetSubscription, 726 private subscription: IWidgetSubscription,
720 - private ngZone: NgZone 727 + private ngZone: NgZone,
  728 + private widgetContext: WidgetContext
721 ) { 729 ) {
  730 + this.cellButtonActions = getTableCellButtonActions(widgetContext);
  731 + this.usedShowCellActionFunction = this.cellButtonActions.some(action => action.useShowActionCellButtonFunction);
722 } 732 }
723 733
724 connect(collectionViewer: CollectionViewer): Observable<EntityData[] | ReadonlyArray<EntityData>> { 734 connect(collectionViewer: CollectionViewer): Observable<EntityData[] | ReadonlyArray<EntityData>> {
@@ -792,6 +802,15 @@ class EntityDatasource implements DataSource<EntityData> { @@ -792,6 +802,15 @@ class EntityDatasource implements DataSource<EntityData> {
792 entity[dataKey.label] = ''; 802 entity[dataKey.label] = '';
793 } 803 }
794 }); 804 });
  805 + if (this.cellButtonActions.length) {
  806 + if (this.usedShowCellActionFunction) {
  807 + entity.actionCellButtons = prepareTableCellButtonActions(this.widgetContext, this.cellButtonActions, entity);
  808 + entity.hasActions = checkHasActions(entity.actionCellButtons);
  809 + } else {
  810 + entity.actionCellButtons = this.cellButtonActions;
  811 + entity.hasActions = true;
  812 + }
  813 + }
795 return entity; 814 return entity;
796 } 815 }
797 816
@@ -318,7 +318,7 @@ export const parseWithTranslation = { @@ -318,7 +318,7 @@ export const parseWithTranslation = {
318 } 318 }
319 }; 319 };
320 320
321 -export function parseData(input: DatasourceData[]): FormattedData[] { 321 +export function parseData(input: DatasourceData[], dataIndex?: number): FormattedData[] {
322 return _(input).groupBy(el => el?.datasource.entityName + el?.datasource.entityType) 322 return _(input).groupBy(el => el?.datasource.entityName + el?.datasource.entityType)
323 .values().value().map((entityArray, i) => { 323 .values().value().map((entityArray, i) => {
324 const obj: FormattedData = { 324 const obj: FormattedData = {
@@ -330,12 +330,12 @@ export function parseData(input: DatasourceData[]): FormattedData[] { @@ -330,12 +330,12 @@ export function parseData(input: DatasourceData[]): FormattedData[] {
330 deviceType: null 330 deviceType: null
331 }; 331 };
332 entityArray.filter(el => el.data.length).forEach(el => { 332 entityArray.filter(el => el.data.length).forEach(el => {
333 - const indexDate = el.data.length - 1;  
334 - if (!obj.hasOwnProperty(el.dataKey.label) || el.data[indexDate][1] !== '') {  
335 - obj[el.dataKey.label] = el.data[indexDate][1];  
336 - obj[el.dataKey.label + '|ts'] = el.data[indexDate][0]; 333 + dataIndex = isDefined(dataIndex) ? dataIndex : el.data.length - 1;
  334 + if (!obj.hasOwnProperty(el.dataKey.label) || el.data[dataIndex][1] !== '') {
  335 + obj[el.dataKey.label] = el.data[dataIndex][1];
  336 + obj[el.dataKey.label + '|ts'] = el.data[dataIndex][0];
337 if (el.dataKey.label === 'type') { 337 if (el.dataKey.label === 'type') {
338 - obj.deviceType = el.data[indexDate][1]; 338 + obj.deviceType = el.data[dataIndex][1];
339 } 339 }
340 } 340 }
341 }); 341 });
@@ -15,12 +15,14 @@ @@ -15,12 +15,14 @@
15 /// 15 ///
16 16
17 import { EntityId } from '@shared/models/id/entity-id'; 17 import { EntityId } from '@shared/models/id/entity-id';
18 -import { DataKey, WidgetConfig } from '@shared/models/widget.models';  
19 -import { getDescendantProp, isDefined } from '@core/utils'; 18 +import { DataKey, WidgetActionDescriptor, WidgetConfig } from '@shared/models/widget.models';
  19 +import { getDescendantProp, isDefined, isNotEmptyStr } from '@core/utils';
20 import { AlarmDataInfo, alarmFields } from '@shared/models/alarm.models'; 20 import { AlarmDataInfo, alarmFields } from '@shared/models/alarm.models';
21 import * as tinycolor_ from 'tinycolor2'; 21 import * as tinycolor_ from 'tinycolor2';
22 import { Direction, EntityDataSortOrder, EntityKey } from '@shared/models/query/query.models'; 22 import { Direction, EntityDataSortOrder, EntityKey } from '@shared/models/query/query.models';
23 import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; 23 import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
  24 +import { WidgetContext } from '@home/models/widget-component.models';
  25 +import { FormattedData } from '@home/components/widget/lib/maps/map-models';
24 26
25 const tinycolor = tinycolor_; 27 const tinycolor = tinycolor_;
26 28
@@ -48,11 +50,20 @@ export interface TableWidgetDataKeySettings { @@ -48,11 +50,20 @@ export interface TableWidgetDataKeySettings {
48 columnSelectionToDisplay?: ColumnSelectionOptions; 50 columnSelectionToDisplay?: ColumnSelectionOptions;
49 } 51 }
50 52
  53 +export type ShowCellButtonActionFunction = (ctx: WidgetContext, data: EntityData | AlarmDataInfo | FormattedData) => boolean;
  54 +
  55 +export interface TableCellButtonActionDescriptor extends WidgetActionDescriptor {
  56 + useShowActionCellButtonFunction: boolean;
  57 + showActionCellButtonFunction: ShowCellButtonActionFunction;
  58 +}
  59 +
51 export interface EntityData { 60 export interface EntityData {
52 id: EntityId; 61 id: EntityId;
53 entityName: string; 62 entityName: string;
54 entityLabel?: string; 63 entityLabel?: string;
55 entityType?: string; 64 entityType?: string;
  65 + actionCellButtons?: TableCellButtonActionDescriptor[];
  66 + hasActions?: boolean;
56 [key: string]: any; 67 [key: string]: any;
57 } 68 }
58 69
@@ -296,6 +307,45 @@ export function getColumnSelectionAvailability(keySettings: TableWidgetDataKeySe @@ -296,6 +307,45 @@ export function getColumnSelectionAvailability(keySettings: TableWidgetDataKeySe
296 return !(isDefined(keySettings.columnSelectionToDisplay) && keySettings.columnSelectionToDisplay === 'disabled'); 307 return !(isDefined(keySettings.columnSelectionToDisplay) && keySettings.columnSelectionToDisplay === 'disabled');
297 } 308 }
298 309
  310 +export function getTableCellButtonActions(widgetContext: WidgetContext): TableCellButtonActionDescriptor[] {
  311 + return widgetContext.actionsApi.getActionDescriptors('actionCellButton').map(descriptor => {
  312 + let useShowActionCellButtonFunction = descriptor.useShowWidgetActionFunction || false;
  313 + let showActionCellButtonFunction: ShowCellButtonActionFunction = null;
  314 + if (useShowActionCellButtonFunction && isNotEmptyStr(descriptor.showWidgetActionFunction)) {
  315 + try {
  316 + showActionCellButtonFunction =
  317 + new Function('widgetContext', 'data', descriptor.showWidgetActionFunction) as ShowCellButtonActionFunction;
  318 + } catch (e) {
  319 + useShowActionCellButtonFunction = false;
  320 + }
  321 + }
  322 + return {...descriptor, showActionCellButtonFunction, useShowActionCellButtonFunction};
  323 + });
  324 +}
  325 +
  326 +export function checkHasActions(cellButtonActions: TableCellButtonActionDescriptor[]): boolean {
  327 + return cellButtonActions.some(action => action.icon);
  328 +}
  329 +
  330 +export function prepareTableCellButtonActions(widgetContext: WidgetContext, cellButtonActions: TableCellButtonActionDescriptor[],
  331 + data: EntityData | AlarmDataInfo | FormattedData): TableCellButtonActionDescriptor[] {
  332 + return cellButtonActions.map(action =>
  333 + filterTableCellButtonAction(widgetContext, action, data) ? action : { id: action.id } as TableCellButtonActionDescriptor);
  334 +}
  335 +
  336 +function filterTableCellButtonAction(widgetContext: WidgetContext,
  337 + action: TableCellButtonActionDescriptor, data: EntityData | AlarmDataInfo | FormattedData): boolean {
  338 + if (action.useShowActionCellButtonFunction) {
  339 + try {
  340 + return action.showActionCellButtonFunction(widgetContext, data);
  341 + } catch (e) {
  342 + console.warn('Failed to execute showActionCellButtonFunction', e);
  343 + return false;
  344 + }
  345 + } else {
  346 + return true;
  347 + }
  348 +}
299 349
300 export function constructTableCssString(widgetConfig: WidgetConfig): string { 350 export function constructTableCssString(widgetConfig: WidgetConfig): string {
301 const origColor = widgetConfig.color || 'rgba(0, 0, 0, 0.87)'; 351 const origColor = widgetConfig.color || 'rgba(0, 0, 0, 0.87)';
@@ -59,35 +59,40 @@ @@ -59,35 +59,40 @@
59 </mat-cell> 59 </mat-cell>
60 </ng-container> 60 </ng-container>
61 <ng-container matColumnDef="actions" [stickyEnd]="enableStickyAction"> 61 <ng-container matColumnDef="actions" [stickyEnd]="enableStickyAction">
62 - <mat-header-cell *matHeaderCellDef [ngStyle.gt-md]="{ minWidth: (actionCellDescriptors.length * 40) + 'px',  
63 - maxWidth: (actionCellDescriptors.length * 40) + 'px',  
64 - width: (actionCellDescriptors.length * 40) + 'px' }"> 62 + <mat-header-cell *matHeaderCellDef [ngStyle.gt-md]="{ minWidth: (countCellButtonAction * 40) + 'px',
  63 + maxWidth: (countCellButtonAction * 40) + 'px',
  64 + width: (countCellButtonAction * 40) + 'px' }">
65 </mat-header-cell> 65 </mat-header-cell>
66 - <mat-cell *matCellDef="let row" [ngStyle.gt-md]="{ minWidth: (actionCellDescriptors.length * 40) + 'px',  
67 - maxWidth: (actionCellDescriptors.length * 40) + 'px',  
68 - width: (actionCellDescriptors.length * 40) + 'px' }"> 66 + <mat-cell *matCellDef="let row" [ngStyle.gt-md]="{ minWidth: (countCellButtonAction * 40) + 'px',
  67 + maxWidth: (countCellButtonAction * 40) + 'px',
  68 + width: (countCellButtonAction * 40) + 'px' }">
69 <div fxHide fxShow.gt-md fxFlex fxLayout="row" fxLayoutAlign="end"> 69 <div fxHide fxShow.gt-md fxFlex fxLayout="row" fxLayoutAlign="end">
70 - <button mat-button mat-icon-button [disabled]="isLoading$ | async"  
71 - *ngFor="let actionDescriptor of actionCellDescriptors; trackBy: trackByActionCellDescriptionId"  
72 - matTooltip="{{ actionDescriptor.displayName }}"  
73 - matTooltipPosition="above"  
74 - (click)="onActionButtonClick($event, row, actionDescriptor)">  
75 - <mat-icon>{{actionDescriptor.icon}}</mat-icon>  
76 - </button> 70 + <ng-container *ngFor="let actionDescriptor of row.actionCellButtons; trackBy: trackByActionCellDescriptionId">
  71 + <span *ngIf="!actionDescriptor.icon" style="width: 40px;"></span>
  72 + <button *ngIf="actionDescriptor.icon"
  73 + mat-button mat-icon-button [disabled]="isLoading$ | async"
  74 + matTooltip="{{ actionDescriptor.displayName }}"
  75 + matTooltipPosition="above"
  76 + (click)="onActionButtonClick($event, row, actionDescriptor)">
  77 + <mat-icon>{{actionDescriptor.icon}}</mat-icon>
  78 + </button>
  79 + </ng-container>
77 </div> 80 </div>
78 - <div fxHide fxShow.lt-lg *ngIf="actionCellDescriptors.length"> 81 + <div fxHide fxShow.lt-lg *ngIf="row.hasActions">
79 <button mat-button mat-icon-button 82 <button mat-button mat-icon-button
80 (click)="$event.stopPropagation(); ctx.detectChanges();" 83 (click)="$event.stopPropagation(); ctx.detectChanges();"
81 [matMenuTriggerFor]="cellActionsMenu"> 84 [matMenuTriggerFor]="cellActionsMenu">
82 <mat-icon class="material-icons">more_vert</mat-icon> 85 <mat-icon class="material-icons">more_vert</mat-icon>
83 </button> 86 </button>
84 <mat-menu #cellActionsMenu="matMenu" xPosition="before"> 87 <mat-menu #cellActionsMenu="matMenu" xPosition="before">
85 - <button mat-menu-item *ngFor="let actionDescriptor of actionCellDescriptors; trackBy: trackByActionCellDescriptionId"  
86 - [disabled]="isLoading$ | async"  
87 - (click)="onActionButtonClick($event, row, actionDescriptor)">  
88 - <mat-icon>{{actionDescriptor.icon}}</mat-icon>  
89 - <span>{{ actionDescriptor.displayName }}</span>  
90 - </button> 88 + <ng-container *ngFor="let actionDescriptor of row.actionCellButtons; trackBy: trackByActionCellDescriptionId">
  89 + <button mat-menu-item *ngIf="actionDescriptor.icon"
  90 + [disabled]="isLoading$ | async"
  91 + (click)="onActionButtonClick($event, row, actionDescriptor)">
  92 + <mat-icon>{{actionDescriptor.icon}}</mat-icon>
  93 + <span>{{ actionDescriptor.displayName }}</span>
  94 + </button>
  95 + </ng-container>
91 </mat-menu> 96 </mat-menu>
92 </div> 97 </div>
93 </mat-cell> 98 </mat-cell>
@@ -53,17 +53,22 @@ import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; @@ -53,17 +53,22 @@ import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
53 import { 53 import {
54 CellContentInfo, 54 CellContentInfo,
55 CellStyleInfo, 55 CellStyleInfo,
  56 + checkHasActions,
56 constructTableCssString, 57 constructTableCssString,
57 getCellContentInfo, 58 getCellContentInfo,
58 getCellStyleInfo, 59 getCellStyleInfo,
59 getRowStyleInfo, 60 getRowStyleInfo,
  61 + getTableCellButtonActions,
  62 + prepareTableCellButtonActions,
60 RowStyleInfo, 63 RowStyleInfo,
  64 + TableCellButtonActionDescriptor,
61 TableWidgetDataKeySettings, 65 TableWidgetDataKeySettings,
62 TableWidgetSettings 66 TableWidgetSettings
63 } from '@home/components/widget/lib/table-widget.models'; 67 } from '@home/components/widget/lib/table-widget.models';
64 import { Overlay } from '@angular/cdk/overlay'; 68 import { Overlay } from '@angular/cdk/overlay';
65 import { SubscriptionEntityInfo } from '@core/api/widget-api.models'; 69 import { SubscriptionEntityInfo } from '@core/api/widget-api.models';
66 import { DatePipe } from '@angular/common'; 70 import { DatePipe } from '@angular/common';
  71 +import { parseData } from '@home/components/widget/lib/maps/common-maps-utils';
67 72
68 export interface TimeseriesTableWidgetSettings extends TableWidgetSettings { 73 export interface TimeseriesTableWidgetSettings extends TableWidgetSettings {
69 showTimestamp: boolean; 74 showTimestamp: boolean;
@@ -72,6 +77,8 @@ export interface TimeseriesTableWidgetSettings extends TableWidgetSettings { @@ -72,6 +77,8 @@ export interface TimeseriesTableWidgetSettings extends TableWidgetSettings {
72 } 77 }
73 78
74 interface TimeseriesRow { 79 interface TimeseriesRow {
  80 + actionCellButtons?: TableCellButtonActionDescriptor[];
  81 + hasActions?: boolean;
75 [col: number]: any; 82 [col: number]: any;
76 formattedTs: string; 83 formattedTs: string;
77 } 84 }
@@ -116,9 +123,9 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI @@ -116,9 +123,9 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
116 public pageSizeOptions; 123 public pageSizeOptions;
117 public textSearchMode = false; 124 public textSearchMode = false;
118 public textSearch: string = null; 125 public textSearch: string = null;
119 - public actionCellDescriptors: WidgetActionDescriptor[];  
120 public sources: TimeseriesTableSource[]; 126 public sources: TimeseriesTableSource[];
121 public sourceIndex: number; 127 public sourceIndex: number;
  128 + public countCellButtonAction: number;
122 129
123 private cellContentCache: Array<any> = []; 130 private cellContentCache: Array<any> = [];
124 private cellStyleCache: Array<any> = []; 131 private cellStyleCache: Array<any> = [];
@@ -204,7 +211,7 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI @@ -204,7 +211,7 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
204 private initialize() { 211 private initialize() {
205 this.ctx.widgetActions = [this.searchAction ]; 212 this.ctx.widgetActions = [this.searchAction ];
206 213
207 - this.actionCellDescriptors = this.ctx.actionsApi.getActionDescriptors('actionCellButton'); 214 + this.countCellButtonAction = this.ctx.actionsApi.getActionDescriptors('actionCellButton').length;
208 215
209 this.searchAction.show = isDefined(this.settings.enableSearch) ? this.settings.enableSearch : true; 216 this.searchAction.show = isDefined(this.settings.enableSearch) ? this.settings.enableSearch : true;
210 this.displayPagination = isDefined(this.settings.displayPagination) ? this.settings.displayPagination : true; 217 this.displayPagination = isDefined(this.settings.displayPagination) ? this.settings.displayPagination : true;
@@ -288,10 +295,10 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI @@ -288,10 +295,10 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
288 cellContentInfo.decimals = dataKey.decimals; 295 cellContentInfo.decimals = dataKey.decimals;
289 source.contentsInfo.push(cellContentInfo); 296 source.contentsInfo.push(cellContentInfo);
290 } 297 }
291 - if (this.actionCellDescriptors.length) { 298 + if (this.countCellButtonAction) {
292 source.displayedColumns.push('actions'); 299 source.displayedColumns.push('actions');
293 } 300 }
294 - const tsDatasource = new TimeseriesDatasource(source, this.hideEmptyLines, this.dateFormatFilter, this.datePipe); 301 + const tsDatasource = new TimeseriesDatasource(source, this.hideEmptyLines, this.dateFormatFilter, this.datePipe, this.ctx);
295 tsDatasource.dataUpdated(this.data); 302 tsDatasource.dataUpdated(this.data);
296 this.sources.push(source); 303 this.sources.push(source);
297 } 304 }
@@ -570,12 +577,18 @@ class TimeseriesDatasource implements DataSource<TimeseriesRow> { @@ -570,12 +577,18 @@ class TimeseriesDatasource implements DataSource<TimeseriesRow> {
570 private allRowsSubject = new BehaviorSubject<TimeseriesRow[]>([]); 577 private allRowsSubject = new BehaviorSubject<TimeseriesRow[]>([]);
571 private allRows$: Observable<Array<TimeseriesRow>> = this.allRowsSubject.asObservable(); 578 private allRows$: Observable<Array<TimeseriesRow>> = this.allRowsSubject.asObservable();
572 579
  580 + private cellButtonActions: TableCellButtonActionDescriptor[];
  581 + private readonly usedShowCellActionFunction: boolean;
  582 +
573 constructor( 583 constructor(
574 private source: TimeseriesTableSource, 584 private source: TimeseriesTableSource,
575 private hideEmptyLines: boolean, 585 private hideEmptyLines: boolean,
576 private dateFormatFilter: string, 586 private dateFormatFilter: string,
577 - private datePipe: DatePipe 587 + private datePipe: DatePipe,
  588 + private widgetContext: WidgetContext
578 ) { 589 ) {
  590 + this.cellButtonActions = getTableCellButtonActions(widgetContext);
  591 + this.usedShowCellActionFunction = this.cellButtonActions.some(action => action.useShowActionCellButtonFunction);
579 this.source.timeseriesDatasource = this; 592 this.source.timeseriesDatasource = this;
580 } 593 }
581 594
@@ -617,13 +630,23 @@ class TimeseriesDatasource implements DataSource<TimeseriesRow> { @@ -617,13 +630,23 @@ class TimeseriesDatasource implements DataSource<TimeseriesRow> {
617 const rowsMap: {[timestamp: number]: TimeseriesRow} = {}; 630 const rowsMap: {[timestamp: number]: TimeseriesRow} = {};
618 for (let d = 0; d < data.length; d++) { 631 for (let d = 0; d < data.length; d++) {
619 const columnData = data[d].data; 632 const columnData = data[d].data;
620 - columnData.forEach((cellData) => { 633 + columnData.forEach((cellData, index) => {
621 const timestamp = cellData[0]; 634 const timestamp = cellData[0];
622 let row = rowsMap[timestamp]; 635 let row = rowsMap[timestamp];
623 if (!row) { 636 if (!row) {
624 row = { 637 row = {
625 formattedTs: this.datePipe.transform(timestamp, this.dateFormatFilter) 638 formattedTs: this.datePipe.transform(timestamp, this.dateFormatFilter)
626 }; 639 };
  640 + if (this.cellButtonActions.length) {
  641 + if (this.usedShowCellActionFunction) {
  642 + const parsedData = parseData(data, index);
  643 + row.actionCellButtons = prepareTableCellButtonActions(this.widgetContext, this.cellButtonActions, parsedData[0]);
  644 + row.hasActions = checkHasActions(row.actionCellButtons);
  645 + } else {
  646 + row.hasActions = true;
  647 + row.actionCellButtons = this.cellButtonActions;
  648 + }
  649 + }
627 row[0] = timestamp; 650 row[0] = timestamp;
628 for (let c = 0; c < data.length; c++) { 651 for (let c = 0; c < data.length; c++) {
629 row[c + 1] = undefined; 652 row[c + 1] = undefined;
@@ -22,6 +22,7 @@ import { TimePageLink } from '@shared/models/page/page-link'; @@ -22,6 +22,7 @@ import { TimePageLink } from '@shared/models/page/page-link';
22 import { NULL_UUID } from '@shared/models/id/has-uuid'; 22 import { NULL_UUID } from '@shared/models/id/has-uuid';
23 import { EntityType } from '@shared/models/entity-type.models'; 23 import { EntityType } from '@shared/models/entity-type.models';
24 import { CustomerId } from '@shared/models/id/customer-id'; 24 import { CustomerId } from '@shared/models/id/customer-id';
  25 +import { TableCellButtonActionDescriptor } from '@home/components/widget/lib/table-widget.models';
25 26
26 export enum AlarmSeverity { 27 export enum AlarmSeverity {
27 CRITICAL = 'CRITICAL', 28 CRITICAL = 'CRITICAL',
@@ -105,6 +106,8 @@ export interface AlarmInfo extends Alarm { @@ -105,6 +106,8 @@ export interface AlarmInfo extends Alarm {
105 } 106 }
106 107
107 export interface AlarmDataInfo extends AlarmInfo { 108 export interface AlarmDataInfo extends AlarmInfo {
  109 + actionCellButtons?: TableCellButtonActionDescriptor[];
  110 + hasActions?: boolean;
108 [key: string]: any; 111 [key: string]: any;
109 } 112 }
110 113
@@ -121,6 +121,7 @@ export interface WidgetActionSource { @@ -121,6 +121,7 @@ export interface WidgetActionSource {
121 name: string; 121 name: string;
122 value: string; 122 value: string;
123 multiple: boolean; 123 multiple: boolean;
  124 + hasShowCondition?: boolean;
124 } 125 }
125 126
126 export const widgetActionSources: {[acionSourceId: string]: WidgetActionSource} = { 127 export const widgetActionSources: {[acionSourceId: string]: WidgetActionSource} = {
@@ -129,6 +130,7 @@ export const widgetActionSources: {[acionSourceId: string]: WidgetActionSource} @@ -129,6 +130,7 @@ export const widgetActionSources: {[acionSourceId: string]: WidgetActionSource}
129 name: 'widget-action.header-button', 130 name: 'widget-action.header-button',
130 value: 'headerButton', 131 value: 'headerButton',
131 multiple: true, 132 multiple: true,
  133 + hasShowCondition: true
132 } 134 }
133 }; 135 };
134 136