Showing
17 changed files
with
192 additions
and
37 deletions
... | ... | @@ -83,6 +83,11 @@ VALUES ( now ( ), minTimeuuid ( 0 ), 'cards', 'timeseries_table', |
83 | 83 | 'Timeseries table' ); |
84 | 84 | |
85 | 85 | INSERT INTO "thingsboard"."widget_type" ( "id", "tenant_id", "bundle_alias", "alias", "descriptor", "name" ) |
86 | +VALUES ( now ( ), minTimeuuid ( 0 ), 'cards', 'html_card', | |
87 | +'{"type":"static","sizeX":7.5,"sizeY":3,"resources":[],"templateHtml":"","templateCss":"","controllerScript":"fns.init = function(containerElement, settings, datasources,\n data) {\n\n var container = $(containerElement);\n \n var cssParser = new cssjs();\n cssParser.testMode = false;\n var namespace = ''html-card-'' + hashCode(settings.cardCss);\n cssParser.cssPreviewNamespace = namespace;\n cssParser.createStyleElement(namespace, settings.cardCss);\n container.addClass(namespace);\n container.html(settings.cardHtml);\n \n function hashCode(str) {\n var hash = 0;\n var i, char;\n if (str.length === 0) return hash;\n for (i = 0; i < str.length; i++) {\n char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return hash;\n }\n\n}\n\n\nfns.redraw = function(containerElement, width, height, data, timeWindow, sizeChanged) {\n\n};","settingsSchema":"{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"required\": [\"cardHtml\"],\n \"properties\": {\n \"cardCss\": {\n \"title\": \"CSS\",\n \"type\": \"string\",\n \"default\": \".card {\\n font-weight: bold; \\n}\"\n },\n \"cardHtml\": {\n \"title\": \"HTML\",\n \"type\": \"string\",\n \"default\": \"<div class=''card''>HTML code here</div>\"\n }\n }\n },\n \"form\": [\n {\n \"key\": \"cardCss\",\n \"type\": \"css\"\n }, \n {\n \"key\": \"cardHtml\",\n \"type\": \"html\"\n } \n ]\n}","dataKeySettingsSchema":"{}\n","defaultConfig":"{\"datasources\":[{\"type\":\"static\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"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;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"cardHtml\":\"<div class=''card''>HTML code here</div>\",\"cardCss\":\".card {\\n font-weight: bold;\\n font-size: 32px;\\n color: #999;\\n width: 100%;\\n height: 100%;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n}\"},\"title\":\"HTML Card\",\"dropShadow\":true}"}', | |
88 | +'HTML Card' ); | |
89 | + | |
90 | +INSERT INTO "thingsboard"."widget_type" ( "id", "tenant_id", "bundle_alias", "alias", "descriptor", "name" ) | |
86 | 91 | VALUES ( now ( ), minTimeuuid ( 0 ), 'analogue_gauges', 'speed_gauge_canvas_gauges', |
87 | 92 | '{"type":"latest","sizeX":7,"sizeY":5,"resources":[],"templateHtml":"<canvas id=\"radialGauge\"></canvas>\n","templateCss":"","controllerScript":"var gauge;\n\nfns.init = function(containerElement, settings, datasources,\n data) {\n gauge = new TbAnalogueRadialGauge(containerElement, settings, data, ''radialGauge''); \n\n}\n\n\nfns.redraw = function(containerElement, width, height, data, timeWindow, sizeChanged) {\n gauge.redraw(width, height, data, sizeChanged);\n};\n\nfns.destroy = function() {\n}\n","settingsSchema":"{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"minValue\": {\n \"title\": \"Minimum value\",\n \"type\": \"number\",\n \"default\": 0\n },\n \"maxValue\": {\n \"title\": \"Maximum value\",\n \"type\": \"number\",\n \"default\": 100\n },\n \"unitTitle\": {\n \"title\": \"Unit title\",\n \"type\": \"string\",\n \"default\": null\n },\n \"showUnitTitle\": {\n \"title\": \"Show unit title\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"units\": {\n \"title\": \"Units\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"majorTicksCount\": {\n \"title\": \"Major ticks count\",\n \"type\": \"number\",\n \"default\": null\n },\n \"minorTicks\": {\n \"title\": \"Minor ticks count\",\n \"type\": \"number\",\n \"default\": 2\n },\n \"valueBox\": {\n \"title\": \"Show value box\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"valueInt\": {\n \"title\": \"Digits count for integer part of value\",\n \"type\": \"number\",\n \"default\": 3\n },\n \"valueDec\": {\n \"title\": \"Digits count for decimal part of value\",\n \"type\": \"number\",\n \"default\": 2\n },\n \"defaultColor\": {\n \"title\": \"Default color\",\n \"type\": \"string\",\n \"default\": null\n },\n \"colorPlate\": {\n \"title\": \"Plate color\",\n \"type\": \"string\",\n \"default\": \"#fff\"\n },\n \"colorMajorTicks\": {\n \"title\": \"Major ticks color\",\n \"type\": \"string\",\n \"default\": \"#444\"\n },\n \"colorMinorTicks\": {\n \"title\": \"Minor ticks color\",\n \"type\": \"string\",\n \"default\": \"#666\"\n },\n \"colorNeedle\": {\n \"title\": \"Needle color\",\n \"type\": \"string\",\n \"default\": null\n },\n \"colorNeedleEnd\": {\n \"title\": \"Needle color - end gradient\",\n \"type\": \"string\",\n \"default\": null\n },\n \"colorNeedleShadowUp\": {\n \"title\": \"Upper half of the needle shadow color\",\n \"type\": \"string\",\n \"default\": \"rgba(2,255,255,0.2)\"\n },\n \"colorNeedleShadowDown\": {\n \"title\": \"Drop shadow needle color.\",\n \"type\": \"string\",\n \"default\": \"rgba(188,143,143,0.45)\"\n },\n \"colorValueBoxRect\": {\n \"title\": \"Value box rectangle stroke color\",\n \"type\": \"string\",\n \"default\": \"#888\"\n },\n \"colorValueBoxRectEnd\": {\n \"title\": \"Value box rectangle stroke color - end gradient\",\n \"type\": \"string\",\n \"default\": \"#666\"\n },\n \"colorValueBoxBackground\": {\n \"title\": \"Value box background color\",\n \"type\": \"string\",\n \"default\": \"#babab2\"\n },\n \"colorValueBoxShadow\": {\n \"title\": \"Value box shadow color\",\n \"type\": \"string\",\n \"default\": \"rgba(0,0,0,1)\"\n },\n \"highlights\": {\n \"title\": \"Highlights\",\n \"type\": \"array\",\n \"items\": {\n \"title\": \"Highlight\",\n \"type\": \"object\",\n \"properties\": {\n \"from\": {\n \"title\": \"From\",\n \"type\": \"number\"\n },\n \"to\": {\n \"title\": \"To\",\n \"type\": \"number\"\n },\n \"color\": {\n \"title\": \"Color\",\n \"type\": \"string\"\n }\n }\n }\n },\n \"highlightsWidth\": {\n \"title\": \"Highlights width\",\n \"type\": \"number\",\n \"default\": 15\n },\n \"showBorder\": {\n \"title\": \"Show border\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"numbersFont\": {\n \"title\": \"Tick numbers font\",\n \"type\": \"object\",\n \"properties\": {\n \"family\": {\n \"title\": \"Font family\",\n \"type\": \"string\",\n \"default\": \"RobotoDraft\"\n },\n \"size\": {\n \"title\": \"Size\",\n \"type\": \"number\",\n \"default\": 18\n },\n \"style\": {\n \"title\": \"Style\",\n \"type\": \"string\",\n \"default\": \"normal\"\n },\n \"weight\": {\n \"title\": \"Weight\",\n \"type\": \"string\",\n \"default\": \"500\"\n },\n \"color\": {\n \"title\": \"color\",\n \"type\": \"string\",\n \"default\": null\n }\n }\n },\n \"titleFont\": {\n \"title\": \"Title text font\",\n \"type\": \"object\",\n \"properties\": {\n \"family\": {\n \"title\": \"Font family\",\n \"type\": \"string\",\n \"default\": \"RobotoDraft\"\n },\n \"size\": {\n \"title\": \"Size\",\n \"type\": \"number\",\n \"default\": 24\n },\n \"style\": {\n \"title\": \"Style\",\n \"type\": \"string\",\n \"default\": \"normal\"\n },\n \"weight\": {\n \"title\": \"Weight\",\n \"type\": \"string\",\n \"default\": \"500\"\n },\n \"color\": {\n \"title\": \"color\",\n \"type\": \"string\",\n \"default\": \"#888\"\n }\n }\n },\n \"unitsFont\": {\n \"title\": \"Units text font\",\n \"type\": \"object\",\n \"properties\": {\n \"family\": {\n \"title\": \"Font family\",\n \"type\": \"string\",\n \"default\": \"RobotoDraft\"\n },\n \"size\": {\n \"title\": \"Size\",\n \"type\": \"number\",\n \"default\": 22\n },\n \"style\": {\n \"title\": \"Style\",\n \"type\": \"string\",\n \"default\": \"normal\"\n },\n \"weight\": {\n \"title\": \"Weight\",\n \"type\": \"string\",\n \"default\": \"500\"\n },\n \"color\": {\n \"title\": \"color\",\n \"type\": \"string\",\n \"default\": \"#888\"\n }\n }\n },\n \"valueFont\": {\n \"title\": \"Value text font\",\n \"type\": \"object\",\n \"properties\": {\n \"family\": {\n \"title\": \"Font family\",\n \"type\": \"string\",\n \"default\": \"RobotoDraft\"\n },\n \"size\": {\n \"title\": \"Size\",\n \"type\": \"number\",\n \"default\": 40\n },\n \"style\": {\n \"title\": \"Style\",\n \"type\": \"string\",\n \"default\": \"normal\"\n },\n \"weight\": {\n \"title\": \"Weight\",\n \"type\": \"string\",\n \"default\": \"500\"\n },\n \"color\": {\n \"title\": \"color\",\n \"type\": \"string\",\n \"default\": \"#444\"\n },\n \"shadowColor\": {\n \"title\": \"Shadow color\",\n \"type\": \"string\",\n \"default\": \"rgba(0,0,0,0.3)\"\n }\n }\n },\n \"animation\": {\n \"title\": \"Enable animation\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"animationDuration\": {\n \"title\": \"Animation duration\",\n \"type\": \"number\",\n \"default\": 500\n },\n \"animationRule\": {\n \"title\": \"Animation rule\",\n \"type\": \"string\",\n \"default\": \"cycle\"\n },\n \"startAngle\": {\n \"title\": \"Start ticks angle\",\n \"type\": \"number\",\n \"default\": 45\n },\n \"ticksAngle\": {\n \"title\": \"Ticks angle\",\n \"type\": \"number\",\n \"default\": 270\n },\n \"needleCircleSize\": {\n \"title\": \"Needle circle size\",\n \"type\": \"number\",\n \"default\": 10\n }\n },\n \"required\": []\n },\n \"form\": [\n \"startAngle\",\n \"ticksAngle\",\n \"needleCircleSize\",\n \"minValue\",\n \"maxValue\",\n \"unitTitle\",\n \"showUnitTitle\",\n \"units\",\n \"majorTicksCount\",\n \"minorTicks\",\n \"valueBox\",\n \"valueInt\",\n \"valueDec\",\n {\n \"key\": \"defaultColor\",\n \"type\": \"color\"\n },\n {\n \"key\": \"colorPlate\",\n \"type\": \"color\"\n },\n {\n \"key\": \"colorMajorTicks\",\n \"type\": \"color\"\n },\n {\n \"key\": \"colorMinorTicks\",\n \"type\": \"color\"\n },\n {\n \"key\": \"colorNeedle\",\n \"type\": \"color\"\n },\n {\n \"key\": \"colorNeedleEnd\",\n \"type\": \"color\"\n },\n {\n \"key\": \"colorNeedleShadowUp\",\n \"type\": \"color\"\n },\n {\n \"key\": \"colorNeedleShadowDown\",\n \"type\": \"color\"\n },\n {\n \"key\": \"colorValueBoxRect\",\n \"type\": \"color\"\n },\n {\n \"key\": \"colorValueBoxRectEnd\",\n \"type\": \"color\"\n },\n {\n \"key\": \"colorValueBoxBackground\",\n \"type\": \"color\"\n },\n {\n \"key\": \"colorValueBoxShadow\",\n \"type\": \"color\"\n },\n {\n \"key\": \"highlights\",\n \"items\": [\n \"highlights[].from\",\n \"highlights[].to\",\n {\n \"key\": \"highlights[].color\",\n \"type\": \"color\"\n }\n ]\n },\n \"highlightsWidth\",\n \"showBorder\",\n {\n \"key\": \"numbersFont\",\n \"items\": [\n \"numbersFont.family\",\n \"numbersFont.size\",\n {\n \"key\": \"numbersFont.style\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"normal\",\n \"label\": \"Normal\"\n },\n {\n \"value\": \"italic\",\n \"label\": \"Italic\"\n },\n {\n \"value\": \"oblique\",\n \"label\": \"Oblique\"\n }\n ]\n },\n {\n \"key\": \"numbersFont.weight\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"normal\",\n \"label\": \"Normal\"\n },\n {\n \"value\": \"bold\",\n \"label\": \"Bold\"\n },\n {\n \"value\": \"bolder\",\n \"label\": \"Bolder\"\n },\n {\n \"value\": \"lighter\",\n \"label\": \"Lighter\"\n },\n {\n \"value\": \"100\",\n \"label\": \"100\"\n },\n {\n \"value\": \"200\",\n \"label\": \"200\"\n },\n {\n \"value\": \"300\",\n \"label\": \"300\"\n },\n {\n \"value\": \"400\",\n \"label\": \"400\"\n },\n {\n \"value\": \"500\",\n \"label\": \"500\"\n },\n {\n \"value\": \"600\",\n \"label\": \"600\"\n },\n {\n \"value\": \"700\",\n \"label\": \"800\"\n },\n {\n \"value\": \"800\",\n \"label\": \"800\"\n },\n {\n \"value\": \"900\",\n \"label\": \"900\"\n }\n ]\n },\n {\n \"key\": \"numbersFont.color\",\n \"type\": \"color\"\n }\n ]\n },\n {\n \"key\": \"titleFont\",\n \"items\": [\n \"titleFont.family\",\n \"titleFont.size\",\n {\n \"key\": \"titleFont.style\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"normal\",\n \"label\": \"Normal\"\n },\n {\n \"value\": \"italic\",\n \"label\": \"Italic\"\n },\n {\n \"value\": \"oblique\",\n \"label\": \"Oblique\"\n }\n ]\n },\n {\n \"key\": \"titleFont.weight\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"normal\",\n \"label\": \"Normal\"\n },\n {\n \"value\": \"bold\",\n \"label\": \"Bold\"\n },\n {\n \"value\": \"bolder\",\n \"label\": \"Bolder\"\n },\n {\n \"value\": \"lighter\",\n \"label\": \"Lighter\"\n },\n {\n \"value\": \"100\",\n \"label\": \"100\"\n },\n {\n \"value\": \"200\",\n \"label\": \"200\"\n },\n {\n \"value\": \"300\",\n \"label\": \"300\"\n },\n {\n \"value\": \"400\",\n \"label\": \"400\"\n },\n {\n \"value\": \"500\",\n \"label\": \"500\"\n },\n {\n \"value\": \"600\",\n \"label\": \"600\"\n },\n {\n \"value\": \"700\",\n \"label\": \"800\"\n },\n {\n \"value\": \"800\",\n \"label\": \"800\"\n },\n {\n \"value\": \"900\",\n \"label\": \"900\"\n }\n ]\n },\n {\n \"key\": \"titleFont.color\",\n \"type\": \"color\"\n }\n ]\n },\n {\n \"key\": \"unitsFont\",\n \"items\": [\n \"unitsFont.family\",\n \"unitsFont.size\",\n {\n \"key\": \"unitsFont.style\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"normal\",\n \"label\": \"Normal\"\n },\n {\n \"value\": \"italic\",\n \"label\": \"Italic\"\n },\n {\n \"value\": \"oblique\",\n \"label\": \"Oblique\"\n }\n ]\n },\n {\n \"key\": \"unitsFont.weight\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"normal\",\n \"label\": \"Normal\"\n },\n {\n \"value\": \"bold\",\n \"label\": \"Bold\"\n },\n {\n \"value\": \"bolder\",\n \"label\": \"Bolder\"\n },\n {\n \"value\": \"lighter\",\n \"label\": \"Lighter\"\n },\n {\n \"value\": \"100\",\n \"label\": \"100\"\n },\n {\n \"value\": \"200\",\n \"label\": \"200\"\n },\n {\n \"value\": \"300\",\n \"label\": \"300\"\n },\n {\n \"value\": \"400\",\n \"label\": \"400\"\n },\n {\n \"value\": \"500\",\n \"label\": \"500\"\n },\n {\n \"value\": \"600\",\n \"label\": \"600\"\n },\n {\n \"value\": \"700\",\n \"label\": \"800\"\n },\n {\n \"value\": \"800\",\n \"label\": \"800\"\n },\n {\n \"value\": \"900\",\n \"label\": \"900\"\n }\n ]\n },\n {\n \"key\": \"unitsFont.color\",\n \"type\": \"color\"\n }\n ]\n },\n {\n \"key\": \"valueFont\",\n \"items\": [\n \"valueFont.family\",\n \"valueFont.size\",\n {\n \"key\": \"valueFont.style\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"normal\",\n \"label\": \"Normal\"\n },\n {\n \"value\": \"italic\",\n \"label\": \"Italic\"\n },\n {\n \"value\": \"oblique\",\n \"label\": \"Oblique\"\n }\n ]\n },\n {\n \"key\": \"valueFont.weight\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"normal\",\n \"label\": \"Normal\"\n },\n {\n \"value\": \"bold\",\n \"label\": \"Bold\"\n },\n {\n \"value\": \"bolder\",\n \"label\": \"Bolder\"\n },\n {\n \"value\": \"lighter\",\n \"label\": \"Lighter\"\n },\n {\n \"value\": \"100\",\n \"label\": \"100\"\n },\n {\n \"value\": \"200\",\n \"label\": \"200\"\n },\n {\n \"value\": \"300\",\n \"label\": \"300\"\n },\n {\n \"value\": \"400\",\n \"label\": \"400\"\n },\n {\n \"value\": \"500\",\n \"label\": \"500\"\n },\n {\n \"value\": \"600\",\n \"label\": \"600\"\n },\n {\n \"value\": \"700\",\n \"label\": \"800\"\n },\n {\n \"value\": \"800\",\n \"label\": \"800\"\n },\n {\n \"value\": \"900\",\n \"label\": \"900\"\n }\n ]\n },\n {\n \"key\": \"valueFont.color\",\n \"type\": \"color\"\n },\n {\n \"key\": \"valueFont.shadowColor\",\n \"type\": \"color\"\n }\n ]\n }, \n \"animation\",\n \"animationDuration\",\n {\n \"key\": \"animationRule\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"linear\",\n \"label\": \"Linear\"\n },\n {\n \"value\": \"quad\",\n \"label\": \"Quad\"\n },\n {\n \"value\": \"quint\",\n \"label\": \"Quint\"\n },\n {\n \"value\": \"cycle\",\n \"label\": \"Cycle\"\n },\n {\n \"value\": \"bounce\",\n \"label\": \"Bounce\"\n },\n {\n \"value\": \"elastic\",\n \"label\": \"Elastic\"\n },\n {\n \"value\": \"dequad\",\n \"label\": \"Dequad\"\n },\n {\n \"value\": \"dequint\",\n \"label\": \"Dequint\"\n },\n {\n \"value\": \"decycle\",\n \"label\": \"Decycle\"\n },\n {\n \"value\": \"debounce\",\n \"label\": \"Debounce\"\n },\n {\n \"value\": \"delastic\",\n \"label\": \"Delastic\"\n }\n ]\n }\n ]\n}","dataKeySettingsSchema":"{}\n","defaultConfig":"{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Speed\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.7282710489093589,\"funcBody\":\"var value = prevValue + Math.random() * 50 - 25;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 220) {\\n\\tvalue = 220;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"maxValue\":180,\"startAngle\":45,\"ticksAngle\":270,\"showBorder\":false,\"defaultColor\":\"#e65100\",\"needleCircleSize\":7,\"highlights\":[{\"from\":80,\"to\":120,\"color\":\"#fdd835\"},{\"color\":\"#e57373\",\"from\":120,\"to\":180}],\"showUnitTitle\":false,\"colorPlate\":\"#fff\",\"colorMajorTicks\":\"#444\",\"colorMinorTicks\":\"#666\",\"minorTicks\":2,\"valueInt\":3,\"minValue\":0,\"valueDec\":0,\"highlightsWidth\":15,\"valueBox\":true,\"animation\":true,\"animationDuration\":1500,\"animationRule\":\"linear\",\"colorNeedleShadowUp\":\"rgba(2, 255, 255, 0)\",\"colorNeedleShadowDown\":\"rgba(188, 143, 143, 0.78)\",\"units\":\"MPH\",\"majorTicksCount\":9,\"numbersFont\":{\"family\":\"RobotoDraft\",\"size\":22,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#616161\"},\"titleFont\":{\"family\":\"RobotoDraft\",\"size\":24,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#888\"},\"unitsFont\":{\"family\":\"RobotoDraft\",\"size\":28,\"style\":\"normal\",\"weight\":\"500\",\"color\":\"#616161\"},\"valueFont\":{\"size\":32,\"style\":\"normal\",\"weight\":\"normal\",\"shadowColor\":\"rgba(0, 0, 0, 0.49)\",\"color\":\"#444\",\"family\":\"Segment7Standard\"},\"colorValueBoxRect\":\"#888\",\"colorValueBoxRectEnd\":\"#666\",\"colorValueBoxBackground\":\"#babab2\",\"colorValueBoxShadow\":\"rgba(0,0,0,1)\"},\"title\":\"Speed gauge - Canvas Gauges\"}"}', |
88 | 93 | 'Speed gauge - Canvas Gauges' ); | ... | ... |
... | ... | @@ -46,6 +46,7 @@ function WidgetService($rootScope, $http, $q, $filter, $ocLazyLoad, $window, typ |
46 | 46 | $window.TbAnalogueRadialGauge = TbAnalogueRadialGauge; |
47 | 47 | $window.TbDigitalGauge = TbDigitalGauge; |
48 | 48 | $window.TbMapWidget = TbMapWidget; |
49 | + $window.cssjs = cssjs; | |
49 | 50 | |
50 | 51 | var cssParser = new cssjs(); |
51 | 52 | cssParser.testMode = false; | ... | ... |
... | ... | @@ -141,6 +141,14 @@ export default angular.module('thingsboard.types', []) |
141 | 141 | bundleAlias: "gpio_widgets", |
142 | 142 | alias: "basic_gpio_control" |
143 | 143 | } |
144 | + }, | |
145 | + static: { | |
146 | + value: "static", | |
147 | + name: "widget.static", | |
148 | + template: { | |
149 | + bundleAlias: "cards", | |
150 | + alias: "html_card" | |
151 | + } | |
144 | 152 | } |
145 | 153 | }, |
146 | 154 | systemBundleAlias: { | ... | ... |
... | ... | @@ -139,6 +139,7 @@ function DashboardController($scope, $rootScope, $element, $timeout, $log, toast |
139 | 139 | vm.widgetBackgroundColor = widgetBackgroundColor; |
140 | 140 | vm.widgetPadding = widgetPadding; |
141 | 141 | vm.showWidgetTitle = showWidgetTitle; |
142 | + vm.dropWidgetShadow = dropWidgetShadow; | |
142 | 143 | vm.hasTimewindow = hasTimewindow; |
143 | 144 | vm.editWidget = editWidget; |
144 | 145 | vm.exportWidget = exportWidget; |
... | ... | @@ -521,6 +522,14 @@ function DashboardController($scope, $rootScope, $element, $timeout, $log, toast |
521 | 522 | } |
522 | 523 | } |
523 | 524 | |
525 | + function dropWidgetShadow(widget) { | |
526 | + if (angular.isDefined(widget.config.dropShadow)) { | |
527 | + return widget.config.dropShadow; | |
528 | + } else { | |
529 | + return true; | |
530 | + } | |
531 | + } | |
532 | + | |
524 | 533 | function hasTimewindow(widget) { |
525 | 534 | return widget.type === types.widgetType.timeseries.value; |
526 | 535 | } | ... | ... |
... | ... | @@ -28,8 +28,10 @@ |
28 | 28 | <li gridster-item="widget" ng-repeat="widget in vm.widgets"> |
29 | 29 | <md-menu md-position-mode="target target" tb-mousepoint-menu> |
30 | 30 | <div tb-expand-fullscreen |
31 | - expand-button-id="expand-button" on-fullscreen-changed="vm.onWidgetFullscreenChanged(expanded, widget)" layout="column" class="tb-widget md-whiteframe-4dp" | |
32 | - ng-class="{'tb-highlighted': vm.isHighlighted(widget), 'tb-not-highlighted': vm.isNotHighlighted(widget)}" | |
31 | + expand-button-id="expand-button" on-fullscreen-changed="vm.onWidgetFullscreenChanged(expanded, widget)" layout="column" class="tb-widget" | |
32 | + ng-class="{'tb-highlighted': vm.isHighlighted(widget), | |
33 | + 'tb-not-highlighted': vm.isNotHighlighted(widget), | |
34 | + 'md-whiteframe-4dp': vm.dropWidgetShadow(widget)}" | |
33 | 35 | tb-mousedown="vm.widgetMouseDown($event, widget)" |
34 | 36 | tb-mousemove="vm.widgetMouseMove($event, widget)" |
35 | 37 | tb-mouseup="vm.widgetMouseUp($event, widget)" | ... | ... |
1 | +/* | |
2 | + * Copyright © 2016-2017 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | +import React from 'react'; | |
17 | +import ThingsboardAceEditor from './json-form-ace-editor.jsx'; | |
18 | +import 'brace/mode/css'; | |
19 | +import beautify from 'js-beautify'; | |
20 | + | |
21 | +const css_beautify = beautify.css; | |
22 | + | |
23 | +class ThingsboardCss extends React.Component { | |
24 | + | |
25 | + constructor(props) { | |
26 | + super(props); | |
27 | + this.onTidyCss = this.onTidyCss.bind(this); | |
28 | + } | |
29 | + | |
30 | + onTidyCss(css) { | |
31 | + return css_beautify(css, {indent_size: 4}); | |
32 | + } | |
33 | + | |
34 | + render() { | |
35 | + return ( | |
36 | + <ThingsboardAceEditor {...this.props} mode='css' onTidy={this.onTidyCss} {...this.state}></ThingsboardAceEditor> | |
37 | + ); | |
38 | + } | |
39 | +} | |
40 | + | |
41 | +export default ThingsboardCss; | ... | ... |
1 | +/* | |
2 | + * Copyright © 2016-2017 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | +import React from 'react'; | |
17 | +import ThingsboardAceEditor from './json-form-ace-editor.jsx'; | |
18 | +import 'brace/mode/html'; | |
19 | +import beautify from 'js-beautify'; | |
20 | + | |
21 | +const html_beautify = beautify.html; | |
22 | + | |
23 | +class ThingsboardHtml extends React.Component { | |
24 | + | |
25 | + constructor(props) { | |
26 | + super(props); | |
27 | + this.onTidyHtml = this.onTidyHtml.bind(this); | |
28 | + } | |
29 | + | |
30 | + onTidyHtml(html) { | |
31 | + return html_beautify(html, {indent_size: 4}); | |
32 | + } | |
33 | + | |
34 | + render() { | |
35 | + return ( | |
36 | + <ThingsboardAceEditor {...this.props} mode='html' onTidy={this.onTidyHtml} {...this.state}></ThingsboardAceEditor> | |
37 | + ); | |
38 | + } | |
39 | +} | |
40 | + | |
41 | +export default ThingsboardHtml; | ... | ... |
... | ... | @@ -19,6 +19,8 @@ import { utils } from 'react-schema-form'; |
19 | 19 | import ThingsboardArray from './json-form-array.jsx'; |
20 | 20 | import ThingsboardJavaScript from './json-form-javascript.jsx'; |
21 | 21 | import ThingsboardJson from './json-form-json.jsx'; |
22 | +import ThingsboardHtml from './json-form-html.jsx'; | |
23 | +import ThingsboardCss from './json-form-css.jsx'; | |
22 | 24 | import ThingsboardColor from './json-form-color.jsx' |
23 | 25 | import ThingsboardRcSelect from './json-form-rc-select.jsx'; |
24 | 26 | import ThingsboardNumber from './json-form-number.jsx'; |
... | ... | @@ -52,6 +54,8 @@ class ThingsboardSchemaForm extends React.Component { |
52 | 54 | 'array': ThingsboardArray, |
53 | 55 | 'javascript': ThingsboardJavaScript, |
54 | 56 | 'json': ThingsboardJson, |
57 | + 'html': ThingsboardHtml, | |
58 | + 'css': ThingsboardCss, | |
55 | 59 | 'color': ThingsboardColor, |
56 | 60 | 'rc-select': ThingsboardRcSelect, |
57 | 61 | 'fieldset': ThingsboardFieldSet | ... | ... |
... | ... | @@ -74,11 +74,12 @@ function WidgetConfig($compile, $templateCache, $rootScope, types, utils) { |
74 | 74 | scope.selectedTab = 0; |
75 | 75 | scope.title = ngModelCtrl.$viewValue.title; |
76 | 76 | scope.showTitle = ngModelCtrl.$viewValue.showTitle; |
77 | + scope.dropShadow = angular.isDefined(ngModelCtrl.$viewValue.dropShadow) ? ngModelCtrl.$viewValue.dropShadow : true; | |
77 | 78 | scope.backgroundColor = ngModelCtrl.$viewValue.backgroundColor; |
78 | 79 | scope.color = ngModelCtrl.$viewValue.color; |
79 | 80 | scope.padding = ngModelCtrl.$viewValue.padding; |
80 | 81 | scope.timewindow = ngModelCtrl.$viewValue.timewindow; |
81 | - if (scope.widgetType !== types.widgetType.rpc.value) { | |
82 | + if (scope.widgetType !== types.widgetType.rpc.value && scope.widgetType !== types.widgetType.static.value) { | |
82 | 83 | if (scope.datasources) { |
83 | 84 | scope.datasources.splice(0, scope.datasources.length); |
84 | 85 | } else { |
... | ... | @@ -89,7 +90,7 @@ function WidgetConfig($compile, $templateCache, $rootScope, types, utils) { |
89 | 90 | scope.datasources.push({value: ngModelCtrl.$viewValue.datasources[i]}); |
90 | 91 | } |
91 | 92 | } |
92 | - } else { | |
93 | + } else if (scope.widgetType === types.widgetType.rpc.value) { | |
93 | 94 | if (ngModelCtrl.$viewValue.targetDeviceAliasIds && ngModelCtrl.$viewValue.targetDeviceAliasIds.length > 0) { |
94 | 95 | var aliasId = ngModelCtrl.$viewValue.targetDeviceAliasIds[0]; |
95 | 96 | if (scope.deviceAliases[aliasId]) { |
... | ... | @@ -140,18 +141,19 @@ function WidgetConfig($compile, $templateCache, $rootScope, types, utils) { |
140 | 141 | if (scope.widgetType === types.widgetType.rpc.value) { |
141 | 142 | valid = value && value.targetDeviceAliasIds && value.targetDeviceAliasIds.length > 0; |
142 | 143 | ngModelCtrl.$setValidity('targetDeviceAliasIds', valid); |
143 | - } else { | |
144 | + } else if (scope.widgetType !== types.widgetType.static.value) { | |
144 | 145 | valid = value && value.datasources && value.datasources.length > 0; |
145 | 146 | ngModelCtrl.$setValidity('datasources', valid); |
146 | 147 | } |
147 | 148 | } |
148 | 149 | }; |
149 | 150 | |
150 | - scope.$watch('title + showTitle + backgroundColor + color + padding + intervalSec', function () { | |
151 | + scope.$watch('title + showTitle + dropShadow + backgroundColor + color + padding + intervalSec', function () { | |
151 | 152 | if (ngModelCtrl.$viewValue) { |
152 | 153 | var value = ngModelCtrl.$viewValue; |
153 | 154 | value.title = scope.title; |
154 | 155 | value.showTitle = scope.showTitle; |
156 | + value.dropShadow = scope.dropShadow; | |
155 | 157 | value.backgroundColor = scope.backgroundColor; |
156 | 158 | value.color = scope.color; |
157 | 159 | value.padding = scope.padding; |
... | ... | @@ -177,7 +179,8 @@ function WidgetConfig($compile, $templateCache, $rootScope, types, utils) { |
177 | 179 | }, true); |
178 | 180 | |
179 | 181 | scope.$watch('datasources', function () { |
180 | - if (ngModelCtrl.$viewValue && scope.widgetType !== types.widgetType.rpc.value) { | |
182 | + if (ngModelCtrl.$viewValue && scope.widgetType !== types.widgetType.rpc.value | |
183 | + && scope.widgetType !== types.widgetType.static.value) { | |
181 | 184 | var value = ngModelCtrl.$viewValue; |
182 | 185 | if (value.datasources) { |
183 | 186 | value.datasources.splice(0, value.datasources.length); |
... | ... | @@ -235,7 +238,8 @@ function WidgetConfig($compile, $templateCache, $rootScope, types, utils) { |
235 | 238 | }; |
236 | 239 | |
237 | 240 | scope.updateDatasourcesAccordionState = function () { |
238 | - if (scope.widgetType !== types.widgetType.rpc.value) { | |
241 | + if (scope.widgetType !== types.widgetType.rpc.value && | |
242 | + scope.widgetType !== types.widgetType.static.value) { | |
239 | 243 | if (scope.datasourcesAccordion) { |
240 | 244 | scope.updateDatasourcesAccordionStatePending = false; |
241 | 245 | var expand = scope.datasources && scope.datasources.length < 4; | ... | ... |
... | ... | @@ -31,6 +31,11 @@ |
31 | 31 | ng-model="showTitle">{{ 'widget-config.display-title' | translate }} |
32 | 32 | </md-checkbox> |
33 | 33 | </div> |
34 | + <div layout="row" layout-padding> | |
35 | + <md-checkbox flex aria-label="{{ 'widget-config.drop-shadow' | translate }}" | |
36 | + ng-model="dropShadow">{{ 'widget-config.drop-shadow' | translate }} | |
37 | + </md-checkbox> | |
38 | + </div> | |
34 | 39 | <div flex |
35 | 40 | md-color-picker |
36 | 41 | ng-model="backgroundColor" |
... | ... | @@ -64,7 +69,7 @@ |
64 | 69 | <tb-timewindow as-button="true" flex ng-model="timewindow"></tb-timewindow> |
65 | 70 | </div> |
66 | 71 | <v-accordion id="datasources-accordion" control="datasourcesAccordion" class="vAccordion--default" |
67 | - ng-show="widgetType !== types.widgetType.rpc.value"> | |
72 | + ng-show="widgetType !== types.widgetType.rpc.value && widgetType !== types.widgetType.static.value"> | |
68 | 73 | <v-pane id="datasources-pane" expanded="forceExpandDatasources"> |
69 | 74 | <v-pane-header> |
70 | 75 | {{ 'widget-config.datasources' | translate }} | ... | ... |
... | ... | @@ -66,6 +66,10 @@ export default function AddWidgetController($scope, widgetService, deviceService |
66 | 66 | link = 'widgetsConfigRpc'; |
67 | 67 | break; |
68 | 68 | } |
69 | + case types.widgetType.static.value: { | |
70 | + link = 'widgetsConfigStatic'; | |
71 | + break; | |
72 | + } | |
69 | 73 | } |
70 | 74 | } |
71 | 75 | return link; | ... | ... |
... | ... | @@ -41,6 +41,7 @@ export default function DashboardController(types, widgetService, userService, |
41 | 41 | vm.latestWidgetTypes = []; |
42 | 42 | vm.timeseriesWidgetTypes = []; |
43 | 43 | vm.rpcWidgetTypes = []; |
44 | + vm.staticWidgetTypes = []; | |
44 | 45 | vm.widgetEditMode = $state.$current.data.widgetEditMode; |
45 | 46 | vm.widgets = []; |
46 | 47 | |
... | ... | @@ -82,6 +83,7 @@ export default function DashboardController(types, widgetService, userService, |
82 | 83 | vm.latestWidgetTypes = []; |
83 | 84 | vm.timeseriesWidgetTypes = []; |
84 | 85 | vm.rpcWidgetTypes = []; |
86 | + vm.staticWidgetTypes = []; | |
85 | 87 | if (vm.widgetsBundle) { |
86 | 88 | var bundleAlias = vm.widgetsBundle.alias; |
87 | 89 | var isSystem = vm.widgetsBundle.tenantId.id === types.id.nullUid; |
... | ... | @@ -127,6 +129,8 @@ export default function DashboardController(types, widgetService, userService, |
127 | 129 | vm.latestWidgetTypes.push(widget); |
128 | 130 | } else if (widgetTypeInfo.type === types.widgetType.rpc.value) { |
129 | 131 | vm.rpcWidgetTypes.push(widget); |
132 | + } else if (widgetTypeInfo.type === types.widgetType.static.value) { | |
133 | + vm.staticWidgetTypes.push(widget); | |
130 | 134 | } |
131 | 135 | top += sizeY; |
132 | 136 | loadNextOrComplete(i); |
... | ... | @@ -442,6 +446,10 @@ export default function DashboardController(types, widgetService, userService, |
442 | 446 | link = 'widgetsConfigRpc'; |
443 | 447 | break; |
444 | 448 | } |
449 | + case types.widgetType.static.value: { | |
450 | + link = 'widgetsConfigStatic'; | |
451 | + break; | |
452 | + } | |
445 | 453 | } |
446 | 454 | } |
447 | 455 | return link; |
... | ... | @@ -490,6 +498,7 @@ export default function DashboardController(types, widgetService, userService, |
490 | 498 | vm.timeseriesWidgetTypes = []; |
491 | 499 | vm.latestWidgetTypes = []; |
492 | 500 | vm.rpcWidgetTypes = []; |
501 | + vm.staticWidgetTypes = []; | |
493 | 502 | } |
494 | 503 | |
495 | 504 | function addWidgetFromType(event, widget) { | ... | ... |
... | ... | @@ -136,7 +136,7 @@ |
136 | 136 | </header-pane> |
137 | 137 | <div> |
138 | 138 | <md-tabs ng-if="vm.timeseriesWidgetTypes.length > 0 || vm.latestWidgetTypes.length > 0 || |
139 | - vm.rpcWidgetTypes.length > 0" | |
139 | + vm.rpcWidgetTypes.length > 0 || vm.staticWidgetTypes.length > 0" | |
140 | 140 | flex |
141 | 141 | class="tb-absolute-fill" md-border-bottom> |
142 | 142 | <md-tab ng-if="vm.timeseriesWidgetTypes.length > 0" style="height: 100%;" label="{{ 'widget.timeseries' | translate }}"> |
... | ... | @@ -169,9 +169,19 @@ |
169 | 169 | on-widget-clicked="vm.addWidgetFromType(event, widget)"> |
170 | 170 | </tb-dashboard> |
171 | 171 | </md-tab> |
172 | + <md-tab ng-if="vm.staticWidgetTypes.length > 0" style="height: 100%;" label="{{ 'widget.static' | translate }}"> | |
173 | + <tb-dashboard | |
174 | + widgets="vm.staticWidgetTypes" | |
175 | + is-edit="false" | |
176 | + is-mobile="true" | |
177 | + is-edit-action-enabled="false" | |
178 | + is-remove-action-enabled="false" | |
179 | + on-widget-clicked="vm.addWidgetFromType(event, widget)"> | |
180 | + </tb-dashboard> | |
181 | + </md-tab> | |
172 | 182 | </md-tabs> |
173 | 183 | <span translate ng-if="vm.timeseriesWidgetTypes.length === 0 && vm.latestWidgetTypes.length === 0 && |
174 | - vm.rpcWidgetTypes.length === 0 && vm.widgetsBundle" | |
184 | + vm.rpcWidgetTypes.length === 0 && vm.staticWidgetTypes.length === 0 && vm.widgetsBundle" | |
175 | 185 | layout-align="center center" |
176 | 186 | style="text-transform: uppercase; display: flex;" |
177 | 187 | class="md-headline tb-absolute-fill">widgets-bundle.empty</span> | ... | ... |
... | ... | @@ -305,31 +305,33 @@ export default function AttributeTableDirective($compile, $templateCache, $rootS |
305 | 305 | for (var i = 0; i < widgetTypes.length; i++) { |
306 | 306 | var widgetType = widgetTypes[i]; |
307 | 307 | var widgetInfo = widgetService.toWidgetInfo(widgetType); |
308 | - var sizeX = widgetInfo.sizeX*2; | |
309 | - var sizeY = widgetInfo.sizeY*2; | |
310 | - var col = Math.floor(Math.max(0, (20 - sizeX)/2)); | |
311 | - var widget = { | |
312 | - isSystemType: isSystem, | |
313 | - bundleAlias: bundleAlias, | |
314 | - typeAlias: widgetInfo.alias, | |
315 | - type: widgetInfo.type, | |
316 | - title: widgetInfo.widgetName, | |
317 | - sizeX: sizeX, | |
318 | - sizeY: sizeY, | |
319 | - row: 0, | |
320 | - col: col, | |
321 | - config: angular.fromJson(widgetInfo.defaultConfig) | |
322 | - }; | |
323 | - | |
324 | - widget.config.title = widgetInfo.widgetName; | |
325 | - widget.config.datasources = [datasource]; | |
326 | - var length; | |
327 | - if (scope.attributeScope === types.latestTelemetry && widgetInfo.type !== types.widgetType.rpc.value) { | |
328 | - length = scope.widgetsListCache.push([widget]); | |
329 | - scope.widgetsList.push(length === 1 ? [widget] : []); | |
330 | - } else if (widgetInfo.type === types.widgetType.latest.value) { | |
331 | - length = scope.widgetsListCache.push([widget]); | |
332 | - scope.widgetsList.push(length === 1 ? [widget] : []); | |
308 | + if (widgetInfo.type !== types.widgetType.static.value) { | |
309 | + var sizeX = widgetInfo.sizeX * 2; | |
310 | + var sizeY = widgetInfo.sizeY * 2; | |
311 | + var col = Math.floor(Math.max(0, (20 - sizeX) / 2)); | |
312 | + var widget = { | |
313 | + isSystemType: isSystem, | |
314 | + bundleAlias: bundleAlias, | |
315 | + typeAlias: widgetInfo.alias, | |
316 | + type: widgetInfo.type, | |
317 | + title: widgetInfo.widgetName, | |
318 | + sizeX: sizeX, | |
319 | + sizeY: sizeY, | |
320 | + row: 0, | |
321 | + col: col, | |
322 | + config: angular.fromJson(widgetInfo.defaultConfig) | |
323 | + }; | |
324 | + | |
325 | + widget.config.title = widgetInfo.widgetName; | |
326 | + widget.config.datasources = [datasource]; | |
327 | + var length; | |
328 | + if (scope.attributeScope === types.latestTelemetry && widgetInfo.type !== types.widgetType.rpc.value) { | |
329 | + length = scope.widgetsListCache.push([widget]); | |
330 | + scope.widgetsList.push(length === 1 ? [widget] : []); | |
331 | + } else if (widgetInfo.type === types.widgetType.latest.value) { | |
332 | + length = scope.widgetsListCache.push([widget]); | |
333 | + scope.widgetsList.push(length === 1 ? [widget] : []); | |
334 | + } | |
333 | 335 | } |
334 | 336 | } |
335 | 337 | scope.widgetsLoaded = true; | ... | ... |
... | ... | @@ -45,7 +45,7 @@ var pluginActionsClazzHelpLinkMap = { |
45 | 45 | 'org.thingsboard.server.extensions.rest.action.RestApiCallPluginAction': 'pluginActionRestApiCall' |
46 | 46 | }; |
47 | 47 | |
48 | -var helpBaseUrl = "http://thingsboard.io"; | |
48 | +var helpBaseUrl = "https://thingsboard.io"; | |
49 | 49 | |
50 | 50 | export default angular.module('thingsboard.help', []) |
51 | 51 | .constant('helpLinks', |
... | ... | @@ -86,6 +86,7 @@ export default angular.module('thingsboard.help', []) |
86 | 86 | widgetsConfigTimeseries: helpBaseUrl + "/docs/user-guide/ui/dashboards#timeseries", |
87 | 87 | widgetsConfigLatest: helpBaseUrl + "/docs/user-guide/ui/dashboards#latest", |
88 | 88 | widgetsConfigRpc: helpBaseUrl + "/docs/user-guide/ui/dashboards#rpc", |
89 | + widgetsConfigStatic: helpBaseUrl + "/docs/user-guide/ui/dashboards#static", | |
89 | 90 | }, |
90 | 91 | getPluginLink: function(plugin) { |
91 | 92 | var link = 'plugins'; | ... | ... |
... | ... | @@ -53,6 +53,13 @@ |
53 | 53 | </md-icon> |
54 | 54 | <span translate>{{vm.types.widgetType.rpc.name}}</span> |
55 | 55 | </md-button> |
56 | + <md-button class="tb-card-button md-raised md-primary" layout="column" | |
57 | + ng-click="vm.typeSelected(vm.types.widgetType.static.value)"> | |
58 | + <md-icon class="material-icons tb-md-96" | |
59 | + aria-label="{{ vm.types.widgetType.static.name | translate }}">font_download | |
60 | + </md-icon> | |
61 | + <span translate>{{vm.types.widgetType.static.name}}</span> | |
62 | + </md-button> | |
56 | 63 | </div> |
57 | 64 | </fieldset> |
58 | 65 | </div> | ... | ... |
... | ... | @@ -603,6 +603,7 @@ |
603 | 603 | "timeseries": "Time series", |
604 | 604 | "latest-values": "Latest values", |
605 | 605 | "rpc": "Control widget", |
606 | + "static": "Static widget", | |
606 | 607 | "select-widget-type": "Select widget type", |
607 | 608 | "missing-widget-title-error": "Widget title must be specified!", |
608 | 609 | "widget-saved": "Widget saved", |
... | ... | @@ -663,6 +664,7 @@ |
663 | 664 | "title": "Title", |
664 | 665 | "general-settings": "General settings", |
665 | 666 | "display-title": "Display title", |
667 | + "drop-shadow": "Drop shadow", | |
666 | 668 | "background-color": "Background color", |
667 | 669 | "text-color": "Text color", |
668 | 670 | "padding": "Padding", | ... | ... |