Commit 4ef3311c1486d9f6b83acfb61e71abd5bc32ea88

Authored by okolesnik
2 parents edcad249 d3e041db

Merge branch 'date-range-navigator'

# Conflicts:
#	ui/src/app/api/widget.service.js
  1 +{
  2 + "widgetsBundle": {
  3 + "alias": "date",
  4 + "title": "Date",
  5 + "image": null
  6 + },
  7 + "widgetTypes": [
  8 + {
  9 + "alias": "date_range_navigator",
  10 + "name": "Date-range-navigator",
  11 + "descriptor": {
  12 + "type": "static",
  13 + "sizeX": 5,
  14 + "sizeY": 5.5,
  15 + "resources": [],
  16 + "templateHtml": "<date-range-navigator-widget class=\"date-range-navigator-widget\" ctx=\"ctx\"></date-range-navigator-widget>",
  17 + "templateCss": "",
  18 + "controllerScript": "self.onInit = function() {\n scope = self.ctx.$scope;\n scope.ctx = self.ctx;\n}",
  19 + "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"hidePicker\": {\n \"title\": \"Hide date range picker\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"onePanel\": {\n \"title\": \"Date range picker one panel\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"autoConfirm\": {\n \"title\": \"Date range picker auto confirm\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"showTemplate\": {\n \"title\": \"Date range picker show template\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"firstDayOfWeek\": {\n \"title\": \"First day of the week\",\n \"type\": \"number\",\n \"default\": 1\n },\n \"hideInterval\": {\n \"title\": \"Hide interval\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"initialInterval\": {\n\t\t\t\t\"title\": \"Initial interval\",\n\t\t\t\t\"type\": \"string\",\n\t\t\t\t\"default\": \"week\"\n\t\t\t},\n \"hideStepSize\": {\n \"title\": \"Hide step size\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"stepSize\": {\n\t\t\t\t\"title\": \"Initial step size\",\n\t\t\t\t\"type\": \"string\",\n\t\t\t\t\"default\": \"day\"\n\t\t\t},\n \"hideLabels\": {\n \"title\": \"Hide labels\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"useSessionStorage\": {\n \"title\": \"Use session storage\",\n \"type\": \"boolean\",\n \"default\": true\n }\n }\n },\n \"form\": [\n \"hidePicker\",\n\t\t\"onePanel\",\n\t\t\"autoConfirm\",\n\t\t\"showTemplate\",\n\t\t\"firstDayOfWeek\",\n \"hideInterval\",\n {\n\t\t\t\"key\": \"initialInterval\",\n\t\t\t\"type\": \"rc-select\",\n\t\t\t\"multiple\": false,\n\t\t\t\"items\": [\n\t\t\t\t{\n\t\t\t\t\t\"value\": \"hour\",\n\t\t\t\t\t\"label\": \"Hour\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"value\": \"day\",\n\t\t\t\t\t\"label\": \"Day\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"value\": \"week\",\n\t\t\t\t\t\"label\": \"Week\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"value\": \"twoWeeks\",\n\t\t\t\t\t\"label\": \"2 weeks\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"value\": \"month\",\n\t\t\t\t\t\"label\": \"Month\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"value\": \"threeMonths\",\n\t\t\t\t\t\"label\": \"3 months\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"value\": \"sixMonths\",\n\t\t\t\t\t\"label\": \"6 months\"\n\t\t\t\t}\n\t\t\t]\n\t\t},\n \"hideStepSize\",\n {\n\t\t\t\"key\": \"stepSize\",\n\t\t\t\"type\": \"rc-select\",\n\t\t\t\"multiple\": false,\n\t\t\t\"items\": [\n\t\t\t\t{\n\t\t\t\t\t\"value\": \"hour\",\n\t\t\t\t\t\"label\": \"Hour\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"value\": \"day\",\n\t\t\t\t\t\"label\": \"Day\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"value\": \"week\",\n\t\t\t\t\t\"label\": \"Week\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"value\": \"twoWeeks\",\n\t\t\t\t\t\"label\": \"2 weeks\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"value\": \"month\",\n\t\t\t\t\t\"label\": \"Month\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"value\": \"threeMonths\",\n\t\t\t\t\t\"label\": \"3 months\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"value\": \"sixMonths\",\n\t\t\t\t\t\"label\": \"6 months\"\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t\"hideLabels\",\n\t\t\"useSessionStorage\"\n ]\n}",
  20 + "dataKeySettingsSchema": "{}\n",
  21 + "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\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"defaultInterval\":\"week\",\"stepSize\":\"day\"},\"title\":\"Date-range-navigator\",\"dropShadow\":true,\"enableFullscreen\":true,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{}}"
  22 + }
  23 + }
  24 + ]
  25 +}
\ No newline at end of file
... ...
... ... @@ -5239,12 +5239,14 @@
5239 5239 "balanced-match": {
5240 5240 "version": "1.0.0",
5241 5241 "bundled": true,
5242   - "dev": true
  5242 + "dev": true,
  5243 + "optional": true
5243 5244 },
5244 5245 "brace-expansion": {
5245 5246 "version": "1.1.11",
5246 5247 "bundled": true,
5247 5248 "dev": true,
  5249 + "optional": true,
5248 5250 "requires": {
5249 5251 "balanced-match": "^1.0.0",
5250 5252 "concat-map": "0.0.1"
... ... @@ -5259,17 +5261,20 @@
5259 5261 "code-point-at": {
5260 5262 "version": "1.1.0",
5261 5263 "bundled": true,
5262   - "dev": true
  5264 + "dev": true,
  5265 + "optional": true
5263 5266 },
5264 5267 "concat-map": {
5265 5268 "version": "0.0.1",
5266 5269 "bundled": true,
5267   - "dev": true
  5270 + "dev": true,
  5271 + "optional": true
5268 5272 },
5269 5273 "console-control-strings": {
5270 5274 "version": "1.1.0",
5271 5275 "bundled": true,
5272   - "dev": true
  5276 + "dev": true,
  5277 + "optional": true
5273 5278 },
5274 5279 "core-util-is": {
5275 5280 "version": "1.0.2",
... ... @@ -5386,7 +5391,8 @@
5386 5391 "inherits": {
5387 5392 "version": "2.0.3",
5388 5393 "bundled": true,
5389   - "dev": true
  5394 + "dev": true,
  5395 + "optional": true
5390 5396 },
5391 5397 "ini": {
5392 5398 "version": "1.3.5",
... ... @@ -5398,6 +5404,7 @@
5398 5404 "version": "1.0.0",
5399 5405 "bundled": true,
5400 5406 "dev": true,
  5407 + "optional": true,
5401 5408 "requires": {
5402 5409 "number-is-nan": "^1.0.0"
5403 5410 }
... ... @@ -5412,6 +5419,7 @@
5412 5419 "version": "3.0.4",
5413 5420 "bundled": true,
5414 5421 "dev": true,
  5422 + "optional": true,
5415 5423 "requires": {
5416 5424 "brace-expansion": "^1.1.7"
5417 5425 }
... ... @@ -5419,12 +5427,14 @@
5419 5427 "minimist": {
5420 5428 "version": "0.0.8",
5421 5429 "bundled": true,
5422   - "dev": true
  5430 + "dev": true,
  5431 + "optional": true
5423 5432 },
5424 5433 "minipass": {
5425 5434 "version": "2.2.4",
5426 5435 "bundled": true,
5427 5436 "dev": true,
  5437 + "optional": true,
5428 5438 "requires": {
5429 5439 "safe-buffer": "^5.1.1",
5430 5440 "yallist": "^3.0.0"
... ... @@ -5443,6 +5453,7 @@
5443 5453 "version": "0.5.1",
5444 5454 "bundled": true,
5445 5455 "dev": true,
  5456 + "optional": true,
5446 5457 "requires": {
5447 5458 "minimist": "0.0.8"
5448 5459 }
... ... @@ -5523,7 +5534,8 @@
5523 5534 "number-is-nan": {
5524 5535 "version": "1.0.1",
5525 5536 "bundled": true,
5526   - "dev": true
  5537 + "dev": true,
  5538 + "optional": true
5527 5539 },
5528 5540 "object-assign": {
5529 5541 "version": "4.1.1",
... ... @@ -5535,6 +5547,7 @@
5535 5547 "version": "1.4.0",
5536 5548 "bundled": true,
5537 5549 "dev": true,
  5550 + "optional": true,
5538 5551 "requires": {
5539 5552 "wrappy": "1"
5540 5553 }
... ... @@ -5656,6 +5669,7 @@
5656 5669 "version": "1.0.2",
5657 5670 "bundled": true,
5658 5671 "dev": true,
  5672 + "optional": true,
5659 5673 "requires": {
5660 5674 "code-point-at": "^1.0.0",
5661 5675 "is-fullwidth-code-point": "^1.0.0",
... ... @@ -8344,6 +8358,18 @@
8344 8358 "tinycolor2": "*"
8345 8359 }
8346 8360 },
  8361 + "md-date-range-picker": {
  8362 + "version": "0.8.4",
  8363 + "resolved": "https://registry.npmjs.org/md-date-range-picker/-/md-date-range-picker-0.8.4.tgz",
  8364 + "integrity": "sha512-TgLyozMJypi92yvXaljLcermTFhd1+0rlaVwV+Duo0EplbKfDJfFF3WohWhB7VmPwJNP//o44sUlecY+r/ZvXA==",
  8365 + "requires": {
  8366 + "angular": "^1.5.8",
  8367 + "angular-animate": "^1.5.8",
  8368 + "angular-aria": "^1.5.8",
  8369 + "angular-material": "^1.1.0",
  8370 + "angular-messages": "^1.5.8"
  8371 + }
  8372 + },
8347 8373 "mdPickers": {
8348 8374 "version": "git://github.com/alenaksu/mdPickers.git#72592ae51c81a7260701055ea21870efa57fa7c8",
8349 8375 "from": "git://github.com/alenaksu/mdPickers.git#0.7.5"
... ...
... ... @@ -67,6 +67,7 @@
67 67 "material-ui": "^0.16.1",
68 68 "material-ui-number-input": "^5.0.16",
69 69 "md-color-picker": "0.2.6",
  70 + "md-date-range-picker": "^0.8.4",
70 71 "mdPickers": "git://github.com/alenaksu/mdPickers.git#0.7.5",
71 72 "moment": "^2.15.0",
72 73 "ngFlowchart": "git://github.com/thingsboard/ngFlowchart.git#master",
... ...
... ... @@ -256,13 +256,13 @@ function TimeService($translate, $http, $q, types) {
256 256 return timewindow;
257 257 }
258 258
259   - function toHistoryTimewindow(timewindow, startTimeMs, endTimeMs) {
260   -
261   - var interval = 0;
  259 + function toHistoryTimewindow(timewindow, startTimeMs, endTimeMs, interval) {
262 260 if (timewindow.history) {
263   - interval = timewindow.history.interval;
  261 + interval = angular.isDefined(interval) ? interval : timewindow.history.interval;
264 262 } else if (timewindow.realtime) {
265 263 interval = timewindow.realtime.interval;
  264 + } else {
  265 + interval = 0;
266 266 }
267 267
268 268 var aggType;
... ...
... ... @@ -23,6 +23,7 @@ import thingsboardAlarmsTableWidget from '../widget/lib/alarms-table-widget';
23 23 import thingsboardEntitiesTableWidget from '../widget/lib/entities-table-widget';
24 24 import thingsboardEntitiesHierarchyWidget from '../widget/lib/entities-hierarchy-widget';
25 25 import thingsboardExtensionsTableWidget from '../widget/lib/extensions-table-widget';
  26 +import thingsboardDateRangeNavigatorWidget from '../widget/lib/date-range-navigator/date-range-navigator';
26 27
27 28 import thingsboardRpcWidgets from '../widget/lib/rpc';
28 29
... ... @@ -35,6 +36,7 @@ import TbMapWidget from '../widget/lib/map-widget';
35 36 import TbMapWidgetV2 from '../widget/lib/map-widget2';
36 37 import TripAnimationWidget from '../widget/lib/tripAnimation/trip-animation-widget';
37 38
  39 +
38 40 import 'jquery.terminal/js/jquery.terminal.min.js';
39 41 import 'jquery.terminal/css/jquery.terminal.min.css';
40 42
... ... @@ -44,8 +46,10 @@ import cssjs from '../../vendor/css.js/css';
44 46 import thingsboardTypes from '../common/types.constant';
45 47 import thingsboardUtils from '../common/utils.service';
46 48
47   -export default angular.module('thingsboard.api.widget', ['oc.lazyLoad', thingsboardLedLight, thingsboardTimeseriesTableWidget,
48   - thingsboardAlarmsTableWidget, thingsboardEntitiesTableWidget, thingsboardEntitiesHierarchyWidget, thingsboardExtensionsTableWidget, thingsboardRpcWidgets, thingsboardTypes, thingsboardUtils, TripAnimationWidget])
  49 +export default angular.module('thingsboard.api.widget', ['oc.lazyLoad', thingsboardLedLight,
  50 + thingsboardTimeseriesTableWidget, thingsboardAlarmsTableWidget, thingsboardEntitiesTableWidget,
  51 + thingsboardEntitiesHierarchyWidget, thingsboardExtensionsTableWidget, thingsboardDateRangeNavigatorWidget,
  52 + thingsboardRpcWidgets, thingsboardTypes, thingsboardUtils, TripAnimationWidget])
49 53 .factory('widgetService', WidgetService)
50 54 .name;
51 55
... ...
... ... @@ -29,6 +29,7 @@ import 'angular-translate-storage-cookie';
29 29 import 'angular-translate-handler-log';
30 30 import 'angular-translate-interpolation-messageformat';
31 31 import 'md-color-picker';
  32 +import 'md-date-range-picker';
32 33 import mdPickers from 'mdPickers';
33 34 import ngSanitize from 'angular-sanitize';
34 35 import FBAngular from 'angular-fullscreen';
... ... @@ -66,6 +67,7 @@ import 'angular-hotkeys/build/hotkeys.min.css';
66 67 import 'angular-carousel/dist/angular-carousel.min.css';
67 68 import 'angular-material-expansion-panel/dist/md-expansion-panel.min.css';
68 69 import 'ngFlowchart/dist/flowchart.css';
  70 +import 'md-date-range-picker/src/md-date-range-picker.css';
69 71 import '../scss/main.scss';
70 72
71 73 import thingsboardThirdpartyFix from './common/thirdparty-fix';
... ... @@ -107,6 +109,7 @@ angular.module('thingsboard', [
107 109 angularSocialshare,
108 110 'pascalprecht.translate',
109 111 'mdColorPicker',
  112 + 'ngMaterialDateRangePicker',
110 113 mdPickers,
111 114 ngSanitize,
112 115 FBAngular.name,
... ...
... ... @@ -219,14 +219,14 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
219 219 }
220 220 }, 0);
221 221 },
222   - onUpdateTimewindow: function(startTimeMs, endTimeMs) {
  222 + onUpdateTimewindow: function(startTimeMs, endTimeMs, interval) {
223 223 if (!vm.originalDashboardTimewindow) {
224 224 vm.originalDashboardTimewindow = angular.copy(vm.dashboardTimewindow);
225 225 }
226 226 $timeout(function() {
227   - vm.dashboardTimewindow = timeService.toHistoryTimewindow(vm.dashboardTimewindow, startTimeMs, endTimeMs);
  227 + vm.dashboardTimewindow = timeService.toHistoryTimewindow(vm.dashboardTimewindow, startTimeMs, endTimeMs, interval);
228 228 }, 0);
229   - }
  229 + },
230 230 };
231 231
232 232 addResizeListener(gridsterParent[0], onGridsterParentResize); // eslint-disable-line no-undef
... ...
... ... @@ -76,9 +76,9 @@ export default function WidgetController($scope, $state, $timeout, $window, $ele
76 76 defaultSubscription: null,
77 77 dashboardTimewindow: dashboardTimewindow,
78 78 timewindowFunctions: {
79   - onUpdateTimewindow: function(startTimeMs, endTimeMs) {
  79 + onUpdateTimewindow: function(startTimeMs, endTimeMs, interval) {
80 80 if (widgetContext.defaultSubscription) {
81   - widgetContext.defaultSubscription.onUpdateTimewindow(startTimeMs, endTimeMs);
  81 + widgetContext.defaultSubscription.onUpdateTimewindow(startTimeMs, endTimeMs, interval);
82 82 }
83 83 },
84 84 onResetTimewindow: function() {
... ...
... ... @@ -1549,6 +1549,65 @@
1549 1549 "widget-type-file": "Widget-Typdatei",
1550 1550 "invalid-widget-type-file-error": "Widget-Typ kann nicht importiert werden: Ungültige Datenstruktur des Widget-Typs."
1551 1551 },
  1552 + "widgets": {
  1553 + "date-range-navigator": {
  1554 + "localizationMap": {
  1555 + "Sun": "So.",
  1556 + "Mon": "Mo.",
  1557 + "Tue": "Di.",
  1558 + "Wed": "Mi.",
  1559 + "Thu": "Do.",
  1560 + "Fri": "Fr.",
  1561 + "Sat": "Sa.",
  1562 + "Jan": "Jan.",
  1563 + "Feb": "Feb.",
  1564 + "Mar": "März",
  1565 + "Apr": "Apr.",
  1566 + "May": "Mai",
  1567 + "Jun": "Juni",
  1568 + "Jul": "Juli",
  1569 + "Aug": "Aug.",
  1570 + "Sep": "Sep.",
  1571 + "Oct": "Okt.",
  1572 + "Nov": "Nov.",
  1573 + "Dec": "Dez.",
  1574 + "January": "Januar",
  1575 + "February": "Februar",
  1576 + "March": "März",
  1577 + "April": "April",
  1578 + "June": "Juni",
  1579 + "July": "Juli",
  1580 + "August": "August",
  1581 + "September": "September",
  1582 + "October": "Oktober",
  1583 + "November": "November",
  1584 + "December": "Dezember",
  1585 + "Custom Date Range": "Benutzerdefinierter Datumsbereich",
  1586 + "Date Range Template": "Datumsbereichsvorlage",
  1587 + "Today": "Heute",
  1588 + "Yesterday": "Gestern",
  1589 + "This Week": "Diese Woche",
  1590 + "Last Week": "Letzte Woche",
  1591 + "This Month": "Diesen Monat",
  1592 + "Last Month": "Im vergangenen Monat",
  1593 + "Year": "Jahr",
  1594 + "This Year": "Dieses Jahr",
  1595 + "Last Year": "Vergangenes Jahr",
  1596 + "Date picker": "Datumsauswahl",
  1597 + "Hour": "Stunde",
  1598 + "Day": "Tag",
  1599 + "Week": "Woche",
  1600 + "2 weeks": "2 Wochen",
  1601 + "Month": "Monat",
  1602 + "3 months": "3 Monate",
  1603 + "6 months": "6 Monate",
  1604 + "Custom interval": "Benutzerdefiniertes Intervall",
  1605 + "Interval": "Intervall",
  1606 + "Step size": "Schrittlänge",
  1607 + "Ok": "Ok"
  1608 + }
  1609 + }
  1610 + },
1552 1611 "icon": {
1553 1612 "icon": "Symbol",
1554 1613 "select-icon": "Symbol auswählen",
... ...
... ... @@ -1555,6 +1555,65 @@
1555 1555 "widget-type-file": "Widget type file",
1556 1556 "invalid-widget-type-file-error": "Unable to import widget type: Invalid widget type data structure."
1557 1557 },
  1558 + "widgets": {
  1559 + "date-range-navigator": {
  1560 + "localizationMap": {
  1561 + "Sun": "Sun",
  1562 + "Mon": "Mon",
  1563 + "Tue": "Tue",
  1564 + "Wed": "Wed",
  1565 + "Thu": "Thu",
  1566 + "Fri": "Fri",
  1567 + "Sat": "Sat",
  1568 + "Jan": "Jan",
  1569 + "Feb": "Feb",
  1570 + "Mar": "Mar",
  1571 + "Apr": "Apr",
  1572 + "May": "May",
  1573 + "Jun": "Jun",
  1574 + "Jul": "Jul",
  1575 + "Aug": "Aug",
  1576 + "Sep": "Sep",
  1577 + "Oct": "Oct",
  1578 + "Nov": "Nov",
  1579 + "Dec": "Dec",
  1580 + "January": "January",
  1581 + "February": "February",
  1582 + "March": "March",
  1583 + "April": "April",
  1584 + "June": "June",
  1585 + "July": "July",
  1586 + "August": "August",
  1587 + "September": "September",
  1588 + "October": "October",
  1589 + "November": "November",
  1590 + "December": "December",
  1591 + "Custom Date Range": "Custom Date Range",
  1592 + "Date Range Template": "Date Range Template",
  1593 + "Today": "Today",
  1594 + "Yesterday": "Yesterday",
  1595 + "This Week": "This Week",
  1596 + "Last Week": "Last Week",
  1597 + "This Month": "This Month",
  1598 + "Last Month": "Last Month",
  1599 + "Year": "Year",
  1600 + "This Year": "This Year",
  1601 + "Last Year": "Last Year",
  1602 + "Date picker": "Date picker",
  1603 + "Hour": "Hour",
  1604 + "Day": "Day",
  1605 + "Week": "Week",
  1606 + "2 weeks": "2 Weeks",
  1607 + "Month": "Month",
  1608 + "3 months": "3 Months",
  1609 + "6 months": "6 Months",
  1610 + "Custom interval": "Custom interval",
  1611 + "Interval": "Interval",
  1612 + "Step size": "Step size",
  1613 + "Ok": "Ok"
  1614 + }
  1615 + }
  1616 + },
1558 1617 "icon": {
1559 1618 "icon": "Icon",
1560 1619 "select-icon": "Select icon",
... ...
... ... @@ -1549,6 +1549,65 @@
1549 1549 "widget-type-file": "Archivo de tipo de widget",
1550 1550 "invalid-widget-type-file-error": "No se puede importar tipo de widget: Estructura de datos del tipo de widget es inválida."
1551 1551 },
  1552 + "widgets": {
  1553 + "date-range-navigator": {
  1554 + "localizationMap": {
  1555 + "Sun": "Dom.",
  1556 + "Mon": "Lun.",
  1557 + "Tue": "Mar.",
  1558 + "Wed": "Mié",
  1559 + "Thu": "Jue.",
  1560 + "Fri": "Vie.",
  1561 + "Sat": "Sáb.",
  1562 + "Jan": "Ene.",
  1563 + "Feb": "Feb.",
  1564 + "Mar": "Mar.",
  1565 + "Apr": "Abr.",
  1566 + "May": "May.",
  1567 + "Jun": "Jun.",
  1568 + "Jul": "Jul.",
  1569 + "Aug": "Ago.",
  1570 + "Sep": "Sept.",
  1571 + "Oct": "Oct.",
  1572 + "Nov": "Nov.",
  1573 + "Dec": "Dic.",
  1574 + "January": "Enero",
  1575 + "February": "Febrero",
  1576 + "March": "Marzo",
  1577 + "April": "Abril",
  1578 + "June": "Junio",
  1579 + "July": "Julio",
  1580 + "August": "Agosto",
  1581 + "September": "Septiembre",
  1582 + "October": "Octubre",
  1583 + "November": "Noviembre",
  1584 + "December": "Diciembre",
  1585 + "Custom Date Range": "Intervalo de fechas personalizado",
  1586 + "Date Range Template": "Plantilla de rango de fechas",
  1587 + "Today": "Hoy",
  1588 + "Yesterday": "Ayer",
  1589 + "This Week": "Esta semana",
  1590 + "Last Week": "La semana pasada",
  1591 + "This Month": "Este mes",
  1592 + "Last Month": "El mes pasado",
  1593 + "Year": "Año",
  1594 + "This Year": "Este año",
  1595 + "Last Year": "Último",
  1596 + "Date picker": "Date picker",
  1597 + "Hour": "Hora",
  1598 + "Day": "Día",
  1599 + "Week": "Semana",
  1600 + "2 weeks": "2 Semanas",
  1601 + "Month": "Mes",
  1602 + "3 months": "3 Meses",
  1603 + "6 months": "6 Meses",
  1604 + "Custom interval": "Intervalo personalizado",
  1605 + "Interval": "Intervalo",
  1606 + "Step size": "Numero de pie",
  1607 + "Ok": "De acuerdo"
  1608 + }
  1609 + }
  1610 + },
1552 1611 "icon": {
1553 1612 "icon": "Icono",
1554 1613 "select-icon": "Seleccionar icono",
... ...
... ... @@ -1549,6 +1549,65 @@
1549 1549 "widget-type-file": "پرونده نوع ويجت",
1550 1550 "invalid-widget-type-file-error": ".وارد کردن نوع ويجت ممکن نيست: ساختار داده نوع ويجت نامعتبر است"
1551 1551 },
  1552 + "widgets": {
  1553 + "date-range-navigator": {
  1554 + "localizationMap": {
  1555 + "Sun": "یکشنبه",
  1556 + "Mon": "دوشنبه",
  1557 + "Tue": "سه‌شنبه",
  1558 + "Wed": "چهارشنبه",
  1559 + "Thu": "پنجشنبه",
  1560 + "Fri": "جمعه",
  1561 + "Sat": "شنبه",
  1562 + "Jan": "ژانویهٔ",
  1563 + "Feb": "فوریهٔ",
  1564 + "Mar": "مارس",
  1565 + "Apr": "آوریل",
  1566 + "May": "مهٔ",
  1567 + "Jun": "ژوئن",
  1568 + "Jul": "ژوئیهٔ",
  1569 + "Aug": "اوت",
  1570 + "Sep": "سپتامبر",
  1571 + "Oct": "اکتبر",
  1572 + "Nov": "نوامبر",
  1573 + "Dec": "دسامبر",
  1574 + "January": "January",
  1575 + "February": "February",
  1576 + "March": "March",
  1577 + "April": "April",
  1578 + "June": "June",
  1579 + "July": "July",
  1580 + "August": "August",
  1581 + "September": "September",
  1582 + "October": "October",
  1583 + "November": "November",
  1584 + "December": "December",
  1585 + "Custom Date Range": "Custom Date Range",
  1586 + "Date Range Template": "Date Range Template",
  1587 + "Today": "Today",
  1588 + "Yesterday": "Yesterday",
  1589 + "This Week": "This Week",
  1590 + "Last Week": "Last Week",
  1591 + "This Month": "This Month",
  1592 + "Last Month": "Last Month",
  1593 + "Year": "Year",
  1594 + "This Year": "This Year",
  1595 + "Last Year": "Last Year",
  1596 + "Date picker": "Date picker",
  1597 + "Hour": "Hour",
  1598 + "Day": "Day",
  1599 + "Week": "Week",
  1600 + "2 weeks": "2 weeks",
  1601 + "Month": "Month",
  1602 + "3 months": "3 months",
  1603 + "6 months": "6 months",
  1604 + "Custom interval": "Custom interval",
  1605 + "Interval": "Interval",
  1606 + "Step size": "Step size",
  1607 + "Ok": "Ok"
  1608 + }
  1609 + }
  1610 + },
1552 1611 "icon": {
1553 1612 "icon": "آيکون",
1554 1613 "select-icon": "انتخاب آيکون",
... ...
... ... @@ -1437,6 +1437,65 @@
1437 1437 "invalid-widget-type-file-error": "Impossible d'importer le type de widget: structure de données de type widget invalide.",
1438 1438 "widget-type-file": "Fichier de type Widget"
1439 1439 },
  1440 + "widgets": {
  1441 + "date-range-navigator": {
  1442 + "localizationMap": {
  1443 + "Sun": "Dim.",
  1444 + "Mon": "Lun.",
  1445 + "Tue": "Mar.",
  1446 + "Wed": "Mer.",
  1447 + "Thu": "Jeu.",
  1448 + "Fri": "Ven.",
  1449 + "Sat": "Sam.",
  1450 + "Jan": "Janv.",
  1451 + "Feb": "Févr.",
  1452 + "Mar": "Mars",
  1453 + "Apr": "Avr.",
  1454 + "May": "Mai",
  1455 + "Jun": "Juin",
  1456 + "Jul": "Juil.",
  1457 + "Aug": "Août",
  1458 + "Sep": "Sept.",
  1459 + "Oct": "Oct.",
  1460 + "Nov": "Nov.",
  1461 + "Dec": "Déc.",
  1462 + "January": "Janvier",
  1463 + "February": "Février",
  1464 + "March": "Mars",
  1465 + "April": "Avril",
  1466 + "June": "Juin",
  1467 + "July": "Juillet",
  1468 + "August": "Août",
  1469 + "September": "Septembre",
  1470 + "October": "Octobre",
  1471 + "November": "Novembre",
  1472 + "December": "Décembre",
  1473 + "Custom Date Range": "Plage de dates personnalisée",
  1474 + "Date Range Template": "Modèle de plage de dates",
  1475 + "Today": "Aujourd'hui",
  1476 + "Yesterday": "Hier",
  1477 + "This Week": "Cette semaine",
  1478 + "Last Week": "La semaine dernière",
  1479 + "This Month": "Ce mois-ci",
  1480 + "Last Month": "Le mois dernier",
  1481 + "Year": "Année",
  1482 + "This Year": "Cette année",
  1483 + "Last Year": "L'année dernière",
  1484 + "Date picker": "Sélecteur de date",
  1485 + "Hour": "Heure",
  1486 + "Day": "Journée",
  1487 + "Week": "La semaine",
  1488 + "2 weeks": "2 Semaines",
  1489 + "Month": "Mois",
  1490 + "3 months": "3 Mois",
  1491 + "6 months": "6 Mois",
  1492 + "Custom interval": "Intervalle personnalisé",
  1493 + "Interval": "Intervalle",
  1494 + "Step size": "Taille de pas",
  1495 + "Ok": "Ok"
  1496 + }
  1497 + }
  1498 + },
1440 1499 "widgets-bundle": {
1441 1500 "add": "Ajouter un groupe de widgets",
1442 1501 "add-widgets-bundle-text": "Ajouter un nouveau groupe de widgets",
... ...
... ... @@ -1554,6 +1554,65 @@
1554 1554 "widget-type-file": "File tipo di widget",
1555 1555 "invalid-widget-type-file-error": "Impossibile importare un tipo di widget: struttura dati del widget non valida."
1556 1556 },
  1557 + "widgets": {
  1558 + "date-range-navigator": {
  1559 + "localizationMap": {
  1560 + "Sun": "Dom",
  1561 + "Mon": "Lun",
  1562 + "Tue": "Mar",
  1563 + "Wed": "Mer",
  1564 + "Thu": "Gio",
  1565 + "Fri": "Ven",
  1566 + "Sat": "Sab",
  1567 + "Jan": "Gen",
  1568 + "Feb": "Feb",
  1569 + "Mar": "Mar",
  1570 + "Apr": "Apr",
  1571 + "May": "Mag",
  1572 + "Jun": "Giu",
  1573 + "Jul": "Lug",
  1574 + "Aug": "Ago",
  1575 + "Sep": "Set",
  1576 + "Oct": "Ott",
  1577 + "Nov": "Nov",
  1578 + "Dec": "Dic",
  1579 + "January": "Gennaio",
  1580 + "February": "Febbraio",
  1581 + "March": "Marzo",
  1582 + "April": "Aprile",
  1583 + "June": "Giugno",
  1584 + "July": "Luglio",
  1585 + "August": "Agosto",
  1586 + "September": "Settembre",
  1587 + "October": "Ottobre",
  1588 + "November": "Novembre",
  1589 + "December": "Dicembre",
  1590 + "Custom Date Range": "Intervallo di date personalizzato",
  1591 + "Date Range Template": "Modello di intervallo di date",
  1592 + "Today": "Oggi",
  1593 + "Yesterday": "Ieri",
  1594 + "This Week": "Questa settimana",
  1595 + "Last Week": "La settimana scorsa",
  1596 + "This Month": "Questo mese",
  1597 + "Last Month": "Lo scorso mese",
  1598 + "Year": "Anno",
  1599 + "This Year": "Quest'anno",
  1600 + "Last Year": "L'anno scorso",
  1601 + "Date picker": "Date picker",
  1602 + "Hour": "Ora",
  1603 + "Day": "Giorno",
  1604 + "Week": "Settimana",
  1605 + "2 weeks": "2 Settimane",
  1606 + "Month": "Mese",
  1607 + "3 months": "3 Mesi",
  1608 + "6 months": "6 Mesi",
  1609 + "Custom interval": "Intervallo personalizzato",
  1610 + "Interval": "Intervallo",
  1611 + "Step size": "Dimensione del passo",
  1612 + "Ok": "Ok"
  1613 + }
  1614 + }
  1615 + },
1557 1616 "icon": {
1558 1617 "icon": "Icona",
1559 1618 "select-icon": "Seleziona icona",
... ...
... ... @@ -1432,6 +1432,65 @@
1432 1432 "widget-type-file": "ウィジェットタイプファイル",
1433 1433 "invalid-widget-type-file-error": "ウィジェットタイプをインポートできません:ウィジェットタイプのデータ構造が無効です。"
1434 1434 },
  1435 + "widgets": {
  1436 + "date-range-navigator": {
  1437 + "localizationMap": {
  1438 + "Sun": "日",
  1439 + "Mon": "月",
  1440 + "Tue": "火",
  1441 + "Wed": "水",
  1442 + "Thu": "木",
  1443 + "Fri": "金",
  1444 + "Sat": "土",
  1445 + "Jan": "1月",
  1446 + "Feb": "2月",
  1447 + "Mar": "3月",
  1448 + "Apr": "4月",
  1449 + "May": "5月",
  1450 + "Jun": "6月",
  1451 + "Jul": "7月",
  1452 + "Aug": "8月",
  1453 + "Sep": "9月",
  1454 + "Oct": "10月",
  1455 + "Nov": "11月",
  1456 + "Dec": "12月",
  1457 + "January": "1月",
  1458 + "February": "2月",
  1459 + "March": "行進",
  1460 + "April": "4月",
  1461 + "June": "六月",
  1462 + "July": "7月",
  1463 + "August": "8月",
  1464 + "September": "9月",
  1465 + "October": "10月",
  1466 + "November": "11月",
  1467 + "December": "12月",
  1468 + "Custom Date Range": "カスタム期間",
  1469 + "Date Range Template": "日付範囲テンプレート",
  1470 + "Today": "今日",
  1471 + "Yesterday": "昨日",
  1472 + "This Week": "今週",
  1473 + "Last Week": "先週",
  1474 + "This Month": "今月",
  1475 + "Last Month": "先月",
  1476 + "Year": "年",
  1477 + "This Year": "今年",
  1478 + "Last Year": "昨年",
  1479 + "Date picker": "日付ピッカー",
  1480 + "Hour": "時",
  1481 + "Day": "日",
  1482 + "Week": "週間",
  1483 + "2 weeks": "2週間",
  1484 + "Month": "月",
  1485 + "3 months": "3ヶ月",
  1486 + "6 months": "6ヵ月",
  1487 + "Custom interval": "カスタム間隔",
  1488 + "Interval": "間隔",
  1489 + "Step size": "刻み幅",
  1490 + "Ok": "Ok"
  1491 + }
  1492 + }
  1493 + },
1435 1494 "icon": {
1436 1495 "icon": "アイコン",
1437 1496 "select-icon": "選択アイコン",
... ...
... ... @@ -1308,6 +1308,65 @@
1308 1308 "widget-type-file": "위젯 타입 파일",
1309 1309 "invalid-widget-type-file-error": "위젯 타입을 가져오기 할 수 없습니다.: 잘못된 위젯 타입 데이터 구조입니다."
1310 1310 },
  1311 + "widgets": {
  1312 + "date-range-navigator": {
  1313 + "localizationMap": {
  1314 + "Sun": "일",
  1315 + "Mon": "월",
  1316 + "Tue": "화",
  1317 + "Wed": "수",
  1318 + "Thu": "목",
  1319 + "Fri": "금",
  1320 + "Sat": "토",
  1321 + "Jan": "1월",
  1322 + "Feb": "2월",
  1323 + "Mar": "3월",
  1324 + "Apr": "4월",
  1325 + "May": "5월",
  1326 + "Jun": "6월",
  1327 + "Jul": "7월",
  1328 + "Aug": "8월",
  1329 + "Sep": "9월",
  1330 + "Oct": "10월",
  1331 + "Nov": "11월",
  1332 + "Dec": "12월",
  1333 + "January": "일월",
  1334 + "February": "이월",
  1335 + "March": "행진",
  1336 + "April": "4 월",
  1337 + "June": "유월",
  1338 + "July": "칠월",
  1339 + "August": "팔월",
  1340 + "September": "구월",
  1341 + "October": "십월",
  1342 + "November": "십일월",
  1343 + "December": "12 월",
  1344 + "Custom Date Range": "맞춤 기간",
  1345 + "Date Range Template": "기간 템플릿",
  1346 + "Today": "오늘",
  1347 + "Yesterday": "어제",
  1348 + "This Week": "이번 주",
  1349 + "Last Week": "지난주",
  1350 + "This Month": "이번 달",
  1351 + "Last Month": "지난 달",
  1352 + "Year": "년",
  1353 + "This Year": "올해",
  1354 + "Last Year": "작년",
  1355 + "Date picker": "날짜 선택기",
  1356 + "Hour": "시간",
  1357 + "Day": "일",
  1358 + "Week": "주",
  1359 + "2 weeks": "이주",
  1360 + "Month": "달",
  1361 + "3 months": "3 개월",
  1362 + "6 months": "6 개월",
  1363 + "Custom interval": "사용자 지정 간격",
  1364 + "Interval": "간격",
  1365 + "Step size": "단계 크기",
  1366 + "Ok": "Ok"
  1367 + }
  1368 + }
  1369 + },
1311 1370 "icon": {
1312 1371 "icon": "Icon",
1313 1372 "select-icon": "Select icon",
... ...
... ... @@ -1548,6 +1548,65 @@
1548 1548 "widget-type-file": "Файл типа виджета",
1549 1549 "invalid-widget-type-file-error": "Не удалось импортировать виджет: неизвестная схема данных типа виджета."
1550 1550 },
  1551 + "widgets": {
  1552 + "date-range-navigator": {
  1553 + "localizationMap": {
  1554 + "Sun": "Вс",
  1555 + "Mon": "Пн",
  1556 + "Tue": "Вт",
  1557 + "Wed": "Ср",
  1558 + "Thu": "Чт",
  1559 + "Fri": "Пт",
  1560 + "Sat": "Сб",
  1561 + "Jan": "Янв.",
  1562 + "Feb": "Февр.",
  1563 + "Mar": "Март",
  1564 + "Apr": "Апр.",
  1565 + "May": "Май",
  1566 + "Jun": "Июнь",
  1567 + "Jul": "Июль",
  1568 + "Aug": "Авг.",
  1569 + "Sep": "Сент.",
  1570 + "Oct": "Окт.",
  1571 + "Nov": "Нояб.",
  1572 + "Dec": "Дек.",
  1573 + "January": "Январь",
  1574 + "February": "Февраль",
  1575 + "March": "Март",
  1576 + "April": "Апрель",
  1577 + "June": "Июнь",
  1578 + "July": "Июль",
  1579 + "August": "Август",
  1580 + "September": "Сентябрь",
  1581 + "October": "Октября",
  1582 + "November": "Ноябрь",
  1583 + "December": "Декабрь",
  1584 + "Custom Date Range": "Пользовательский диапазон дат",
  1585 + "Date Range Template": "Шаблон диапазона дат",
  1586 + "Today": "Сегодня",
  1587 + "Yesterday": "Вчера",
  1588 + "This Week": "На этой неделе",
  1589 + "Last Week": "Прошлая неделя",
  1590 + "This Month": "Этот месяц",
  1591 + "Last Month": "Прошлый месяц",
  1592 + "Year": "Год",
  1593 + "This Year": "В этом году",
  1594 + "Last Year": "Прошлый год",
  1595 + "Date picker": "Выбор даты",
  1596 + "Hour": "Час",
  1597 + "Day": "День",
  1598 + "Week": "Неделю",
  1599 + "2 weeks": "2 Недели",
  1600 + "Month": "Месяц",
  1601 + "3 months": "3 Месяца",
  1602 + "6 months": "6 Месяцев",
  1603 + "Custom interval": "Пользовательский интервал",
  1604 + "Interval": "Интервал",
  1605 + "Step size": "Размер шага",
  1606 + "Ok": "Ok"
  1607 + }
  1608 + }
  1609 + },
1551 1610 "icon": {
1552 1611 "icon": "Иконка",
1553 1612 "select-icon": "Выбрать иконку",
... ...
... ... @@ -1514,6 +1514,65 @@
1514 1514 "widget-type-file": "Gösterge türü dosyası",
1515 1515 "invalid-widget-type-file-error": "Gösterge türü içe aktarılamadı: Geçersiz gösterge türü veri yapısı."
1516 1516 },
  1517 + "widgets": {
  1518 + "date-range-navigator": {
  1519 + "localizationMap": {
  1520 + "Sun": "Paz",
  1521 + "Mon": "Pzt",
  1522 + "Tue": "Sal",
  1523 + "Wed": "Çar",
  1524 + "Thu": "Per",
  1525 + "Fri": "Cum",
  1526 + "Sat": "Cmt",
  1527 + "Jan": "Oca",
  1528 + "Feb": "Şub",
  1529 + "Mar": "Mar",
  1530 + "Apr": "Nis",
  1531 + "May": "May",
  1532 + "Jun": "Haz",
  1533 + "Jul": "Tem",
  1534 + "Aug": "Ağu",
  1535 + "Sep": "Eyl",
  1536 + "Oct": "Eki",
  1537 + "Nov": "Kas",
  1538 + "Dec": "Ara",
  1539 + "January": "Ocak",
  1540 + "February": "Şubat",
  1541 + "March": "Mart",
  1542 + "April": "Nisan",
  1543 + "June": "Haziran",
  1544 + "July": "Temmuz",
  1545 + "August": "Ağustos",
  1546 + "September": "Eylül",
  1547 + "October": "Ekim",
  1548 + "November": "Kasım",
  1549 + "December": "Aralık",
  1550 + "Custom Date Range": "Özel Tarih Aralığı",
  1551 + "Date Range Template": "Tarih Aralığı Şablonu",
  1552 + "Today": "Bugün",
  1553 + "Yesterday": "Dün",
  1554 + "This Week": "Bu hafta",
  1555 + "Last Week": "Geçen hafta",
  1556 + "This Month": "Bu ay",
  1557 + "Last Month": "Geçen ay",
  1558 + "Year": "Yıl",
  1559 + "This Year": "Bu yıl",
  1560 + "Last Year": "Geçen yıl",
  1561 + "Date picker": "Tarih seçici",
  1562 + "Hour": "Saat",
  1563 + "Day": "Gün",
  1564 + "Week": "Hafta",
  1565 + "2 weeks": "2 Hafta",
  1566 + "Month": "Ay",
  1567 + "3 months": "3 Ay",
  1568 + "6 months": "6 Ay",
  1569 + "Custom interval": "Özel aralık",
  1570 + "Interval": "Aralık",
  1571 + "Step size": "Adım boyutu",
  1572 + "Ok": "Ok"
  1573 + }
  1574 + }
  1575 + },
1517 1576 "icon": {
1518 1577 "icon": "İkon",
1519 1578 "select-icon": "İkon seç",
... ...
... ... @@ -1418,6 +1418,65 @@
1418 1418 "widget-type-file": "部件类型文件",
1419 1419 "invalid-widget-type-file-error": "无法导入部件类型:无效的部件类型数据结构。"
1420 1420 },
  1421 + "widgets": {
  1422 + "date-range-navigator": {
  1423 + "localizationMap": {
  1424 + "Sun": "周日",
  1425 + "Mon": "周一",
  1426 + "Tue": "周二",
  1427 + "Wed": "周三",
  1428 + "Thu": "周四",
  1429 + "Fri": "周五",
  1430 + "Sat": "周六",
  1431 + "Jan": "1月",
  1432 + "Feb": "2月",
  1433 + "Mar": "3月",
  1434 + "Apr": "4月",
  1435 + "May": "5月",
  1436 + "Jun": "6月",
  1437 + "Jul": "7月",
  1438 + "Aug": "8月",
  1439 + "Sep": "9月",
  1440 + "Oct": "10月",
  1441 + "Nov": "11月",
  1442 + "Dec": "12月",
  1443 + "January": "一月",
  1444 + "February": "二月",
  1445 + "March": "游行",
  1446 + "April": "四月",
  1447 + "June": "六月",
  1448 + "July": "七月",
  1449 + "August": "八月",
  1450 + "September": "九月",
  1451 + "October": "十月",
  1452 + "November": "十一月",
  1453 + "December": "十二月",
  1454 + "Custom Date Range": "自定义日期范围",
  1455 + "Date Range Template": "日期范围模板",
  1456 + "Today": "今天",
  1457 + "Yesterday": "昨天",
  1458 + "This Week": "本星期",
  1459 + "Last Week": "上个星期",
  1460 + "This Month": "这个月",
  1461 + "Last Month": "上个月",
  1462 + "Year": "年",
  1463 + "This Year": "今年",
  1464 + "Last Year": "去年",
  1465 + "Date picker": "日期选择器",
  1466 + "Hour": "小时",
  1467 + "Day": "天",
  1468 + "Week": "周",
  1469 + "2 weeks": "2周",
  1470 + "Month": "月",
  1471 + "3 months": "3个月",
  1472 + "6 months": "6个月",
  1473 + "Custom interval": "自定义间隔",
  1474 + "Interval": "间隔",
  1475 + "Step size": "一步的大小",
  1476 + "Ok": "Ok"
  1477 + }
  1478 + }
  1479 + },
1421 1480 "icon": {
1422 1481 "icon": "图标",
1423 1482 "select-icon": "选择图标",
... ...
  1 +/*
  2 + * Copyright © 2016-2019 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 +/* eslint-disable import/no-unresolved, import/default */
  17 +import widgetTpl from './date-range-navigator.tpl.html';
  18 +import './date-range-navigator.scss';
  19 +/* eslint-enable import/no-unresolved, import/default */
  20 +
  21 +export default angular.module('thingsboard.widgets.dateRangeNavigator', [])
  22 + .directive('dateRangeNavigatorWidget', DateRangeNavigatorWidget)
  23 + .name;
  24 +
  25 +/*@ngInject*/
  26 +function DateRangeNavigatorWidget() {
  27 + return {
  28 + restrict: "E",
  29 + scope: true,
  30 + bindToController: {
  31 + tableId: '=',
  32 + ctx: '='
  33 + },
  34 + controller: DateRangeNavigatorWidgetController,
  35 + controllerAs: 'vm',
  36 + templateUrl: widgetTpl
  37 + };
  38 +}
  39 +
  40 +/*@ngInject*/
  41 +function DateRangeNavigatorWidgetController($scope, $window, $filter) {
  42 +
  43 + let vm = this,
  44 + hour = 3600000,
  45 + day = 86400000,
  46 + week = 604800000,
  47 + month = 2629743000,
  48 + words = [
  49 + "Mon",
  50 + "Tue",
  51 + "Wed",
  52 + "Thu",
  53 + "Fri",
  54 + "Sat",
  55 + "Sun",
  56 + "January",
  57 + "February",
  58 + "March",
  59 + "April",
  60 + "May",
  61 + "June",
  62 + "July",
  63 + "August",
  64 + "September",
  65 + "October",
  66 + "November",
  67 + "December",
  68 + "Ok",
  69 + 'Custom Date Range',
  70 + 'Date Range Template',
  71 + 'Today',
  72 + 'Yesterday',
  73 + 'This Week',
  74 + 'Last Week',
  75 + 'Month',
  76 + 'This Month',
  77 + 'Last Month',
  78 + 'Year',
  79 + 'This Year',
  80 + 'Last Year'
  81 + ],
  82 + firstUpdate = true;
  83 +
  84 + $scope.datesMap = {
  85 + hour: {
  86 + ts: hour,
  87 + label: "Hour"
  88 + },
  89 + day: {
  90 + ts: day,
  91 + label: "Day"
  92 + },
  93 + week: {
  94 + ts: week,
  95 + label: "Week"
  96 + },
  97 + twoWeeks: {
  98 + ts: week * 2,
  99 + label: "2 weeks"
  100 + },
  101 + month: {
  102 + ts: month,
  103 + label: "Month"
  104 + },
  105 + threeMonths: {
  106 + ts: month * 3,
  107 + label: "3 months"
  108 + },
  109 + sixMonths: {
  110 + ts: month * 6,
  111 + label: "6 months"
  112 + }
  113 + };
  114 + $scope.advancedModel = {};
  115 + $scope.endRestrictionDate = Date.now();
  116 + $scope.localizationMap = getLocalizationMap();
  117 +
  118 + $scope.changeInterval = changeInterval;
  119 + $scope.goForth = goForth;
  120 + $scope.goBack = goBack;
  121 + $scope.triggerChange = triggerChange;
  122 +
  123 + $scope.$watch('vm.ctx', function () {
  124 + if (vm.ctx && vm.ctx.dashboard.dashboardTimewindow) {
  125 + $scope.settings = vm.ctx.widgetConfig.settings;
  126 + let selection;
  127 + if ($scope.settings.useSessionStorage) {
  128 + selection = readFromStorage('date-range');
  129 + }
  130 + if (selection) {
  131 + $scope.advancedModel = {
  132 + selectedTemplateName: selection.name,
  133 + dateStart: selection.start,
  134 + dateEnd: selection.end
  135 + };
  136 + } else {
  137 + let end = new Date();
  138 + end.setHours(23, 59, 59, 999);
  139 +
  140 + let formattedDate = getFormattedDate(
  141 + (end.getTime() + 1) - $scope.datesMap[$scope.settings.initialInterval || "week"].ts,
  142 + end.getTime()
  143 + );
  144 + $scope.advancedModel = formattedDate;
  145 + }
  146 + $scope.selectedStepSize = $scope.datesMap[$scope.settings.stepSize || "day"].ts;
  147 +
  148 + widgetContextTimewindowSync();
  149 + }
  150 + });
  151 +
  152 + $scope.$on('dashboardTimewindowChanged', function () {
  153 + $scope.dashboardTimewindowChanged = true;
  154 + widgetContextTimewindowSync();
  155 + });
  156 +
  157 + function getLocalizationMap() {
  158 + let result = {};
  159 +
  160 + words.forEach(function (key) {
  161 + result[key] = $filter('translate')('widgets.date-range-navigator.localizationMap.' + key);
  162 + });
  163 +
  164 + return result;
  165 + }
  166 +
  167 + function triggerChange() {
  168 + updateTimewindow($scope.advancedModel.dateStart.getTime(), $scope.advancedModel.dateEnd.getTime() + day - 1);
  169 + }
  170 +
  171 + function widgetContextTimewindowSync() {
  172 + if (vm.ctx && vm.ctx.dashboardTimewindow && $scope.dashboardTimewindowChanged &&
  173 + vm.ctx.dashboard.dashboardTimewindow.history &&
  174 + vm.ctx.dashboard.dashboardTimewindow.history.fixedTimewindow) {
  175 +
  176 +
  177 + if (!firstUpdate) {
  178 + updateAdvancedModel();
  179 + }
  180 + updateDateInterval();
  181 + if ($scope.settings.useSessionStorage) {
  182 + updateStorageDate();
  183 + }
  184 + if (firstUpdate) {
  185 + updateTimewindow($scope.advancedModel.dateStart.getTime(), $scope.advancedModel.dateEnd.getTime());
  186 + firstUpdate = false;
  187 + }
  188 + }
  189 + }
  190 +
  191 + function getFormattedDate(startTime, endTime) {
  192 + var template;
  193 +
  194 + let startDate = new Date(startTime);
  195 + let endDate = new Date(endTime);
  196 +
  197 + if (getDateDiff(startDate, endDate) === 0) {
  198 + template = $filter('date')(startDate, 'dd MMM yyyy');
  199 + } else {
  200 + template = $filter('date')(
  201 + startDate,
  202 + 'dd' + (startDate.getMonth() !== endDate.getMonth() || startDate.getFullYear() !== endDate.getFullYear() ? ' MMM' : '') + (startDate.getFullYear() !== endDate.getFullYear() ? ' yyyy' : '')
  203 + )
  204 + + ' - ' +
  205 + $filter('date')(
  206 + endDate,
  207 + 'dd MMM yyyy'
  208 + );
  209 + }
  210 +
  211 + return {
  212 + selectedTemplateName: template,
  213 + dateStart: startDate,
  214 + dateEnd: endDate
  215 + };
  216 + }
  217 +
  218 + function readFromStorage(itemKey) {
  219 + if ($window.sessionStorage.getItem(itemKey)) {
  220 + let selection = angular.fromJson($window.sessionStorage.getItem(itemKey));
  221 + selection.start = new Date(parseInt(selection.start));
  222 + selection.end = new Date(parseInt(selection.end));
  223 + return selection;
  224 + }
  225 +
  226 + return undefined;
  227 + }
  228 +
  229 + function goForth() {
  230 + let startTime = vm.ctx.dashboard.dashboardTimewindow.history ?
  231 + vm.ctx.dashboard.dashboardTimewindow.history.fixedTimewindow.startTimeMs :
  232 + $scope.advancedModel.dateStart.getTime();
  233 + let endTime = vm.ctx.dashboard.dashboardTimewindow.history ?
  234 + vm.ctx.dashboard.dashboardTimewindow.history.fixedTimewindow.endTimeMs :
  235 + $scope.advancedModel.dateEnd.getTime();
  236 + updateTimewindow(startTime + $scope.selectedStepSize, endTime + $scope.selectedStepSize);
  237 + }
  238 +
  239 + function goBack() {
  240 + let startTime = vm.ctx.dashboard.dashboardTimewindow.history ?
  241 + vm.ctx.dashboard.dashboardTimewindow.history.fixedTimewindow.startTimeMs :
  242 + $scope.advancedModel.dateStart.getTime();
  243 + let endTime = vm.ctx.dashboard.dashboardTimewindow.history ?
  244 + vm.ctx.dashboard.dashboardTimewindow.history.fixedTimewindow.endTimeMs :
  245 + $scope.advancedModel.dateEnd.getTime();
  246 + updateTimewindow(startTime - $scope.selectedStepSize, endTime - $scope.selectedStepSize);
  247 + }
  248 +
  249 + function changeInterval() {
  250 + let endTime = vm.ctx.dashboard.dashboardTimewindow.history ?
  251 + vm.ctx.dashboard.dashboardTimewindow.history.fixedTimewindow.endTimeMs :
  252 + $scope.advancedModel.dateEnd.getTime();
  253 + updateTimewindow(endTime - $scope.selectedDateInterval / 2, endTime + $scope.selectedDateInterval / 2);
  254 + }
  255 +
  256 + function getDateDiff(date1, date2) {
  257 + if (!date1 || !date2) return;
  258 + var _d1 = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate()),
  259 + _d2 = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate());
  260 + return _d2 - _d1;
  261 + }
  262 +
  263 + function updateTimewindow(startTime, endTime) {
  264 + vm.ctx.dashboard.dashboardTimewindowApi.onUpdateTimewindow(startTime, endTime, 10);
  265 + }
  266 +
  267 + function updateDateInterval() {
  268 + let interval = $scope.advancedModel.dateEnd.getTime() - $scope.advancedModel.dateStart.getTime();
  269 +
  270 + for (let i in $scope.datesMap) {
  271 + if ($scope.datesMap.hasOwnProperty(i)) {
  272 + if ($scope.datesMap[i].ts === interval || $scope.datesMap[i].ts === interval + 1 || $scope.datesMap[i].ts === interval - 1) {
  273 + $scope.selectedDateInterval = $scope.datesMap[i].ts;
  274 + $scope.customInterval = false;
  275 + return;
  276 + }
  277 + }
  278 + }
  279 +
  280 + $scope.selectedDateInterval = interval;
  281 + $scope.customInterval = {ts: interval, label: "Custom interval"};
  282 + }
  283 +
  284 + function updateAdvancedModel() {
  285 + $scope.advancedModel = getFormattedDate(vm.ctx.dashboard.dashboardTimewindow.history.fixedTimewindow.startTimeMs, vm.ctx.dashboard.dashboardTimewindow.history.fixedTimewindow.endTimeMs);
  286 + }
  287 +
  288 + function updateStorageDate() {
  289 + saveIntoStorage('date-range', {
  290 + start: $scope.advancedModel.dateStart.getTime(),
  291 + end: $scope.advancedModel.dateEnd.getTime(),
  292 + name: $scope.advancedModel.selectedTemplateName
  293 + });
  294 + }
  295 +
  296 + function saveIntoStorage(keyName, selection) {
  297 + if (selection) {
  298 + $window.sessionStorage.setItem(keyName, angular.toJson(selection));
  299 + }
  300 + }
  301 +}
\ No newline at end of file
... ...
  1 +/**
  2 + * Copyright © 2016-2019 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 +.date-range-navigator-widget {
  17 + display: flex;
  18 + height: 100%;
  19 +}
  20 +
  21 +.date-range-navigator {
  22 + display: flex;
  23 + flex-wrap: wrap;
  24 + align-items: center;
  25 + justify-content: space-evenly;
  26 + width: 100%;
  27 + margin: auto;
  28 +
  29 + .drn__element {
  30 + display: flex;
  31 + flex-direction: row;
  32 + align-items: center;
  33 + max-width: 100%;
  34 + height: 60px;
  35 + margin: 4px 0;
  36 + }
  37 +
  38 + .navigation {
  39 + md-input-container {
  40 + margin: 0;
  41 + }
  42 + }
  43 +
  44 + .picker {
  45 + .picker__wrapper {
  46 + position: relative;
  47 + max-width: 100%;
  48 + padding: 2px;
  49 +
  50 + > label {
  51 + position: absolute;
  52 + right: -3px;
  53 + bottom: 100%;
  54 + left: 0;
  55 + padding-left: 3px;
  56 + color: #787878;
  57 + transform: scale(.75);
  58 + transform-origin: left bottom;
  59 + }
  60 + }
  61 +
  62 + .md-select-value {
  63 + min-width: 225px;
  64 + border-color: #e1e1e1;
  65 +
  66 + .md-select-icon {
  67 + color: #757575;
  68 + }
  69 + }
  70 + }
  71 +
  72 + &.short-mode {
  73 + display: block;
  74 + width: 90%;
  75 +
  76 + .drn__element {
  77 + width: 100%;
  78 +
  79 + md-input-container {
  80 + flex: 1;
  81 + }
  82 + }
  83 +
  84 + .picker {
  85 + .picker__wrapper {
  86 + width: 100%;
  87 + }
  88 +
  89 + .md-select-value {
  90 + min-width: initial;
  91 + }
  92 + }
  93 +
  94 + &.labels-hidden {
  95 + .drn__element {
  96 + margin: 0;
  97 + }
  98 + }
  99 + }
  100 +
  101 + &.long-mode {
  102 + &.labels-hidden {
  103 + .drn__element {
  104 + height: 36px;
  105 + }
  106 + }
  107 + }
  108 +}
... ...
  1 +<!--
  2 +
  3 + Copyright © 2016-2019 The Thingsboard Authors
  4 +
  5 + Licensed under the Apache License, Version 2.0 (the "License");
  6 + you may not use this file except in compliance with the License.
  7 + You may obtain a copy of the License at
  8 +
  9 + http://www.apache.org/licenses/LICENSE-2.0
  10 +
  11 + Unless required by applicable law or agreed to in writing, software
  12 + distributed under the License is distributed on an "AS IS" BASIS,
  13 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 + See the License for the specific language governing permissions and
  15 + limitations under the License.
  16 +
  17 +-->
  18 +<div class="date-range-navigator"
  19 + ng-class="{'short-mode':vm.ctx.width < 400, 'labels-hidden': settings.hideLabels, 'long-mode': vm.ctx.width >= 400}"
  20 +>
  21 + <div class="drn__element picker" ng-hide="settings.hidePicker" ng-if="vm.ctx">
  22 + <div class="picker__wrapper">
  23 + <label ng-hide="settings.hideLabels" ng-bind="'widgets.date-range-navigator.localizationMap.Date picker' | translate"></label>
  24 + <md-date-range ng-model="advancedModel"
  25 + md-on-select="triggerChange()"
  26 + localization-map="localizationMap"
  27 + one-panel="settings.onePanel"
  28 + auto-confirm="settings.autoConfirm"
  29 + show-template="settings.showTemplate"
  30 + first-day-of-week="settings.firstDayOfWeek"
  31 + ></md-date-range>
  32 + </div>
  33 + </div>
  34 +
  35 + <div class="drn__element navigation" ng-hide="settings.hideInterval">
  36 + <md-input-container class="md-block"
  37 + flex-gt-sm
  38 + >
  39 + <label ng-hide="settings.hideLabels" ng-bind="'widgets.date-range-navigator.localizationMap.Interval' | translate"></label>
  40 + <md-select ng-model="selectedDateInterval"
  41 + ng-change="changeInterval()"
  42 + aria-label="Pick date interval"
  43 + >
  44 + <md-option ng-if="customInterval" ng-value="customInterval.ts">{{'widgets.date-range-navigator.localizationMap.' + customInterval.label | translate}}</md-option>
  45 + <md-option ng-repeat="(dateKey, dateValue) in datesMap" ng-value="dateValue.ts">
  46 + {{'widgets.date-range-navigator.localizationMap.' + dateValue.label | translate}}
  47 + </md-option>
  48 + </md-select>
  49 + </md-input-container>
  50 + </div>
  51 +
  52 + <div class="drn__element step" ng-hide="settings.hideStepSize">
  53 + <md-button ng-click="goBack()" class="md-icon-button">
  54 + <md-icon>keyboard_arrow_left</md-icon>
  55 + </md-button>
  56 + <md-input-container class="md-block"
  57 + flex-gt-sm
  58 + >
  59 + <label ng-hide="settings.hideLabels" ng-bind="'widgets.date-range-navigator.localizationMap.Step size' | translate"></label>
  60 + <md-select ng-model="selectedStepSize"
  61 + aria-label="Pick date interval"
  62 + >
  63 + <md-option ng-repeat="(dateKey, dateValue) in datesMap" ng-value="dateValue.ts">
  64 + {{'widgets.date-range-navigator.localizationMap.'+dateValue.label | translate}}
  65 + </md-option>
  66 + </md-select>
  67 + </md-input-container>
  68 + <md-button ng-click="goForth()" class="md-icon-button">
  69 + <md-icon>keyboard_arrow_right</md-icon>
  70 + </md-button>
  71 + </div>
  72 +</div>
... ...