19 changed files with 1538 additions and 330 deletions
@ -0,0 +1,25 @@ |
|||||
|
{ |
||||
|
"widgetsBundle": { |
||||
|
"alias": "date", |
||||
|
"title": "Date", |
||||
|
"image": null |
||||
|
}, |
||||
|
"widgetTypes": [ |
||||
|
{ |
||||
|
"alias": "date_range_navigator", |
||||
|
"name": "Date-range-navigator", |
||||
|
"descriptor": { |
||||
|
"type": "static", |
||||
|
"sizeX": 5, |
||||
|
"sizeY": 5.5, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<date-range-navigator-widget class=\"date-range-navigator-widget\" ctx=\"ctx\"></date-range-navigator-widget>", |
||||
|
"templateCss": "", |
||||
|
"controllerScript": "self.onInit = function() {\n scope = self.ctx.$scope;\n scope.ctx = self.ctx;\n}", |
||||
|
"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}", |
||||
|
"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\":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\":{}}" |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
||||
File diff suppressed because it is too large
@ -0,0 +1,303 @@ |
|||||
|
/* |
||||
|
* ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL |
||||
|
* |
||||
|
* Copyright © 2016-2019 ThingsBoard, Inc. All Rights Reserved. |
||||
|
* |
||||
|
* NOTICE: All information contained herein is, and remains |
||||
|
* the property of ThingsBoard, Inc. and its suppliers, |
||||
|
* if any. The intellectual and technical concepts contained |
||||
|
* herein are proprietary to ThingsBoard, Inc. |
||||
|
* and its suppliers and may be covered by U.S. and Foreign Patents, |
||||
|
* patents in process, and are protected by trade secret or copyright law. |
||||
|
* |
||||
|
* Dissemination of this information or reproduction of this material is strictly forbidden |
||||
|
* unless prior written permission is obtained from COMPANY. |
||||
|
* |
||||
|
* Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, |
||||
|
* managers or contractors who have executed Confidentiality and Non-disclosure agreements |
||||
|
* explicitly covering such access. |
||||
|
* |
||||
|
* The copyright notice above does not evidence any actual or intended publication |
||||
|
* or disclosure of this source code, which includes |
||||
|
* information that is confidential and/or proprietary, and is a trade secret, of COMPANY. |
||||
|
* ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, |
||||
|
* OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT |
||||
|
* THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, |
||||
|
* AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. |
||||
|
* THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION |
||||
|
* DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, |
||||
|
* OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. |
||||
|
*/ |
||||
|
|
||||
|
/* eslint-disable import/no-unresolved, import/default */ |
||||
|
import widgetTpl from './date-range-navigator.tpl.html'; |
||||
|
import './date-range-navigator.scss'; |
||||
|
/* eslint-enable import/no-unresolved, import/default */ |
||||
|
|
||||
|
export default angular.module('thingsboard.widgets.dateRangeNavigator', []) |
||||
|
.directive('dateRangeNavigatorWidget', DateRangeNavigatorWidget) |
||||
|
.name; |
||||
|
|
||||
|
/*@ngInject*/ |
||||
|
function DateRangeNavigatorWidget() { |
||||
|
return { |
||||
|
restrict: "E", |
||||
|
scope: true, |
||||
|
bindToController: { |
||||
|
tableId: '=', |
||||
|
ctx: '=' |
||||
|
}, |
||||
|
controller: DateRangeNavigatorWidgetController, |
||||
|
controllerAs: 'vm', |
||||
|
templateUrl: widgetTpl |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
/*@ngInject*/ |
||||
|
function DateRangeNavigatorWidgetController($scope, $window, $filter) { |
||||
|
|
||||
|
let vm = this, |
||||
|
hour = 3600000, |
||||
|
day = 86400000, |
||||
|
week = 604800000, |
||||
|
month = 2629743000, |
||||
|
words = [ |
||||
|
"Mon", |
||||
|
"Tue", |
||||
|
"Wed", |
||||
|
"Thu", |
||||
|
"Fri", |
||||
|
"Sat", |
||||
|
"Sun", |
||||
|
"January", |
||||
|
"February", |
||||
|
"March", |
||||
|
"April", |
||||
|
"May", |
||||
|
"June", |
||||
|
"July", |
||||
|
"August", |
||||
|
"September", |
||||
|
"October", |
||||
|
"November", |
||||
|
"December", |
||||
|
"Ok", |
||||
|
'Custom Date Range', |
||||
|
'Date Range Template', |
||||
|
'Today', |
||||
|
'Yesterday', |
||||
|
'This Week', |
||||
|
'Last Week', |
||||
|
'Month', |
||||
|
'This Month', |
||||
|
'Last Month', |
||||
|
'Year', |
||||
|
'This Year', |
||||
|
'Last Year' |
||||
|
], |
||||
|
firstUpdate = true; |
||||
|
|
||||
|
$scope.datesMap = { |
||||
|
hour: { |
||||
|
ts: hour, |
||||
|
label: "Hour" |
||||
|
}, |
||||
|
day: { |
||||
|
ts: day, |
||||
|
label: "Day" |
||||
|
}, |
||||
|
week: { |
||||
|
ts: week, |
||||
|
label: "Week" |
||||
|
}, |
||||
|
twoWeeks: { |
||||
|
ts: week * 2, |
||||
|
label: "2 weeks" |
||||
|
}, |
||||
|
month: { |
||||
|
ts: month, |
||||
|
label: "Month" |
||||
|
}, |
||||
|
threeMonths: { |
||||
|
ts: month * 3, |
||||
|
label: "3 months" |
||||
|
}, |
||||
|
sixMonths: { |
||||
|
ts: month * 6, |
||||
|
label: "6 months" |
||||
|
} |
||||
|
}; |
||||
|
$scope.advancedModel = {}; |
||||
|
$scope.endRestrictionDate = Date.now(); |
||||
|
$scope.localizationMap = getLocalizationMap(); |
||||
|
|
||||
|
$scope.changeInterval = changeInterval; |
||||
|
$scope.goForth = goForth; |
||||
|
$scope.goBack = goBack; |
||||
|
$scope.triggerChange = triggerChange; |
||||
|
|
||||
|
$scope.$watch('vm.ctx', function () { |
||||
|
if (vm.ctx && vm.ctx.dashboard.dashboardTimewindow) { |
||||
|
$scope.settings = vm.ctx.widgetConfig.settings; |
||||
|
let selection; |
||||
|
if ($scope.settings.useSessionStorage) { |
||||
|
selection = readFromStorage('date-range'); |
||||
|
} |
||||
|
if (selection) { |
||||
|
$scope.advancedModel = { |
||||
|
selectedTemplateName: selection.name, |
||||
|
dateStart: selection.start, |
||||
|
dateEnd: selection.end |
||||
|
}; |
||||
|
} else { |
||||
|
let end = new Date(); |
||||
|
end.setHours(23,59,59,999); |
||||
|
|
||||
|
let formattedDate = getFormattedDate( |
||||
|
(end.getTime() + 1) - $scope.datesMap[$scope.settings.initialInterval || "week"].ts, |
||||
|
end.getTime() |
||||
|
); |
||||
|
$scope.advancedModel = formattedDate; |
||||
|
} |
||||
|
$scope.selectedStepSize = $scope.datesMap[$scope.settings.stepSize || "day"].ts; |
||||
|
|
||||
|
widgetContextTimewindowSync(); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
$scope.$on('dashboardTimewindowChanged', function () { |
||||
|
$scope.dashboardTimewindowChanged = true; |
||||
|
widgetContextTimewindowSync(); |
||||
|
}); |
||||
|
|
||||
|
function getLocalizationMap() { |
||||
|
let result = {}; |
||||
|
|
||||
|
words.forEach(function (key) { |
||||
|
result[key] = $filter('translate')('widgets.date-range-navigator.localizationMap.' + key); |
||||
|
}); |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
function triggerChange() { |
||||
|
updateTimewindow($scope.advancedModel.dateStart.getTime(), $scope.advancedModel.dateEnd.getTime() + day - 1); |
||||
|
} |
||||
|
|
||||
|
function widgetContextTimewindowSync() { |
||||
|
if (vm.ctx && vm.ctx.dashboardTimewindow && $scope.dashboardTimewindowChanged && |
||||
|
vm.ctx.dashboard.dashboardTimewindow.history && |
||||
|
vm.ctx.dashboard.dashboardTimewindow.history.fixedTimewindow) { |
||||
|
|
||||
|
|
||||
|
if (!firstUpdate) { |
||||
|
updateAdvancedModel(); |
||||
|
} |
||||
|
updateDateInterval(); |
||||
|
if ($scope.settings.useSessionStorage) { |
||||
|
updateStorageDate(); |
||||
|
} |
||||
|
if (firstUpdate) { |
||||
|
updateTimewindow($scope.advancedModel.dateStart.getTime(), $scope.advancedModel.dateEnd.getTime()); |
||||
|
firstUpdate = false; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function getFormattedDate(startTime, endTime) { |
||||
|
var template; |
||||
|
|
||||
|
let startDate = new Date(startTime); |
||||
|
let endDate = new Date(endTime); |
||||
|
|
||||
|
if (getDateDiff(startDate, endDate) === 0) { |
||||
|
template = $filter('date')(startDate, 'dd MMM yyyy'); |
||||
|
} else { |
||||
|
template = $filter('date')( |
||||
|
startDate, |
||||
|
'dd' + (startDate.getMonth() !== endDate.getMonth() || startDate.getFullYear() !== endDate.getFullYear() ? ' MMM' : '') + (startDate.getFullYear() !== endDate.getFullYear() ? ' yyyy' : '') |
||||
|
) |
||||
|
+ ' - ' + |
||||
|
$filter('date')( |
||||
|
endDate, |
||||
|
'dd MMM yyyy' |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
return { |
||||
|
selectedTemplateName: template, |
||||
|
dateStart: startDate, |
||||
|
dateEnd: endDate |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
function readFromStorage(itemKey) { |
||||
|
if ($window.sessionStorage.getItem(itemKey)) { |
||||
|
let selection = angular.fromJson($window.sessionStorage.getItem(itemKey)); |
||||
|
selection.start = new Date(parseInt(selection.start)); |
||||
|
selection.end = new Date(parseInt(selection.end)); |
||||
|
return selection; |
||||
|
} |
||||
|
|
||||
|
return undefined; |
||||
|
} |
||||
|
|
||||
|
function goForth() { |
||||
|
updateTimewindow(vm.ctx.dashboard.dashboardTimewindow.history.fixedTimewindow.startTimeMs + $scope.selectedStepSize, vm.ctx.dashboard.dashboardTimewindow.history.fixedTimewindow.endTimeMs + $scope.selectedStepSize); |
||||
|
} |
||||
|
|
||||
|
function goBack() { |
||||
|
updateTimewindow(vm.ctx.dashboard.dashboardTimewindow.history.fixedTimewindow.startTimeMs - $scope.selectedStepSize, vm.ctx.dashboard.dashboardTimewindow.history.fixedTimewindow.endTimeMs - $scope.selectedStepSize); |
||||
|
} |
||||
|
|
||||
|
function changeInterval() { |
||||
|
updateTimewindow(vm.ctx.dashboard.dashboardTimewindow.history.fixedTimewindow.endTimeMs - $scope.selectedDateInterval / 2, vm.ctx.dashboard.dashboardTimewindow.history.fixedTimewindow.endTimeMs + $scope.selectedDateInterval / 2); |
||||
|
} |
||||
|
|
||||
|
function getDateDiff(date1, date2) { |
||||
|
if (!date1 || !date2) return; |
||||
|
var _d1 = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate()), |
||||
|
_d2 = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate()); |
||||
|
return _d2 - _d1; |
||||
|
} |
||||
|
|
||||
|
function updateTimewindow(startTime, endTime) { |
||||
|
vm.ctx.dashboard.dashboardTimewindowApi.onUpdateTimewindow(startTime, endTime, 10); |
||||
|
} |
||||
|
|
||||
|
function updateDateInterval() { |
||||
|
let interval = $scope.advancedModel.dateEnd.getTime() - $scope.advancedModel.dateStart.getTime(); |
||||
|
|
||||
|
for (let i in $scope.datesMap) { |
||||
|
if ($scope.datesMap.hasOwnProperty(i)) { |
||||
|
if ($scope.datesMap[i].ts === interval || $scope.datesMap[i].ts === interval + 1 || $scope.datesMap[i].ts === interval - 1) { |
||||
|
$scope.selectedDateInterval = $scope.datesMap[i].ts; |
||||
|
$scope.customInterval = false; |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
$scope.selectedDateInterval = interval; |
||||
|
$scope.customInterval = {ts: interval, label: "Custom interval"}; |
||||
|
} |
||||
|
|
||||
|
function updateAdvancedModel() { |
||||
|
$scope.advancedModel = getFormattedDate(vm.ctx.dashboard.dashboardTimewindow.history.fixedTimewindow.startTimeMs, vm.ctx.dashboard.dashboardTimewindow.history.fixedTimewindow.endTimeMs); |
||||
|
} |
||||
|
|
||||
|
function updateStorageDate() { |
||||
|
saveIntoStorage('date-range', { |
||||
|
start: $scope.advancedModel.dateStart.getTime(), |
||||
|
end: $scope.advancedModel.dateEnd.getTime(), |
||||
|
name: $scope.advancedModel.selectedTemplateName |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function saveIntoStorage(keyName, selection) { |
||||
|
if (selection) { |
||||
|
$window.sessionStorage.setItem(keyName, angular.toJson(selection)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,124 @@ |
|||||
|
/** |
||||
|
* ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL |
||||
|
* |
||||
|
* Copyright © 2016-2019 ThingsBoard, Inc. All Rights Reserved. |
||||
|
* |
||||
|
* NOTICE: All information contained herein is, and remains |
||||
|
* the property of ThingsBoard, Inc. and its suppliers, |
||||
|
* if any. The intellectual and technical concepts contained |
||||
|
* herein are proprietary to ThingsBoard, Inc. |
||||
|
* and its suppliers and may be covered by U.S. and Foreign Patents, |
||||
|
* patents in process, and are protected by trade secret or copyright law. |
||||
|
* |
||||
|
* Dissemination of this information or reproduction of this material is strictly forbidden |
||||
|
* unless prior written permission is obtained from COMPANY. |
||||
|
* |
||||
|
* Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, |
||||
|
* managers or contractors who have executed Confidentiality and Non-disclosure agreements |
||||
|
* explicitly covering such access. |
||||
|
* |
||||
|
* The copyright notice above does not evidence any actual or intended publication |
||||
|
* or disclosure of this source code, which includes |
||||
|
* information that is confidential and/or proprietary, and is a trade secret, of COMPANY. |
||||
|
* ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, |
||||
|
* OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT |
||||
|
* THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, |
||||
|
* AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. |
||||
|
* THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION |
||||
|
* DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, |
||||
|
* OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. |
||||
|
*/ |
||||
|
|
||||
|
.date-range-navigator-widget { |
||||
|
display: flex; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
.date-range-navigator { |
||||
|
display: flex; |
||||
|
flex-wrap: wrap; |
||||
|
align-items: center; |
||||
|
justify-content: space-evenly; |
||||
|
width: 100%; |
||||
|
margin: auto; |
||||
|
|
||||
|
.drn__element { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
align-items: center; |
||||
|
max-width: 100%; |
||||
|
height: 60px; |
||||
|
margin: 4px 0; |
||||
|
} |
||||
|
|
||||
|
.navigation { |
||||
|
md-input-container { |
||||
|
margin: 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.picker { |
||||
|
.picker__wrapper { |
||||
|
position: relative; |
||||
|
max-width: 100%; |
||||
|
padding: 2px; |
||||
|
|
||||
|
> label { |
||||
|
position: absolute; |
||||
|
right: -3px; |
||||
|
bottom: 100%; |
||||
|
left: 0; |
||||
|
padding-left: 3px; |
||||
|
color: #787878; |
||||
|
transform: scale(.75); |
||||
|
transform-origin: left bottom; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.md-select-value { |
||||
|
min-width: 225px; |
||||
|
border-color: #e1e1e1; |
||||
|
|
||||
|
.md-select-icon { |
||||
|
color: #757575; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&.short-mode { |
||||
|
display: block; |
||||
|
width: 90%; |
||||
|
|
||||
|
.drn__element { |
||||
|
width: 100%; |
||||
|
|
||||
|
md-input-container { |
||||
|
flex: 1; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.picker { |
||||
|
.picker__wrapper { |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.md-select-value { |
||||
|
min-width: initial; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&.labels-hidden { |
||||
|
.drn__element { |
||||
|
margin: 0; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&.long-mode { |
||||
|
&.labels-hidden { |
||||
|
.drn__element { |
||||
|
height: 36px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,87 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
ThingsBoard, Inc. ("COMPANY") CONFIDENTIAL |
||||
|
|
||||
|
Copyright © 2016-2019 ThingsBoard, Inc. All Rights Reserved. |
||||
|
|
||||
|
NOTICE: All information contained herein is, and remains |
||||
|
the property of ThingsBoard, Inc. and its suppliers, |
||||
|
if any. The intellectual and technical concepts contained |
||||
|
herein are proprietary to ThingsBoard, Inc. |
||||
|
and its suppliers and may be covered by U.S. and Foreign Patents, |
||||
|
patents in process, and are protected by trade secret or copyright law. |
||||
|
|
||||
|
Dissemination of this information or reproduction of this material is strictly forbidden |
||||
|
unless prior written permission is obtained from COMPANY. |
||||
|
|
||||
|
Access to the source code contained herein is hereby forbidden to anyone except current COMPANY employees, |
||||
|
managers or contractors who have executed Confidentiality and Non-disclosure agreements |
||||
|
explicitly covering such access. |
||||
|
|
||||
|
The copyright notice above does not evidence any actual or intended publication |
||||
|
or disclosure of this source code, which includes |
||||
|
information that is confidential and/or proprietary, and is a trade secret, of COMPANY. |
||||
|
ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, |
||||
|
OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT |
||||
|
THE EXPRESS WRITTEN CONSENT OF COMPANY IS STRICTLY PROHIBITED, |
||||
|
AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. |
||||
|
THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION |
||||
|
DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, |
||||
|
OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. |
||||
|
|
||||
|
--> |
||||
|
<div class="date-range-navigator" |
||||
|
ng-class="{'short-mode':vm.ctx.width < 400, 'labels-hidden': settings.hideLabels, 'long-mode': vm.ctx.width >= 400}" |
||||
|
> |
||||
|
<div class="drn__element picker" ng-hide="settings.hidePicker" ng-if="vm.ctx"> |
||||
|
<div class="picker__wrapper"> |
||||
|
<label ng-hide="settings.hideLabels" ng-bind="'widgets.date-range-navigator.localizationMap.Date picker' | translate"></label> |
||||
|
<md-date-range ng-model="advancedModel" |
||||
|
md-on-select="triggerChange()" |
||||
|
localization-map="localizationMap" |
||||
|
one-panel="settings.onePanel" |
||||
|
auto-confirm="settings.autoConfirm" |
||||
|
show-template="settings.showTemplate" |
||||
|
first-day-of-week="settings.firstDayOfWeek" |
||||
|
></md-date-range> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="drn__element navigation" ng-hide="settings.hideInterval"> |
||||
|
<md-input-container class="md-block" |
||||
|
flex-gt-sm |
||||
|
> |
||||
|
<label ng-hide="settings.hideLabels" ng-bind="'widgets.date-range-navigator.localizationMap.Interval' | translate"></label> |
||||
|
<md-select ng-model="selectedDateInterval" |
||||
|
ng-change="changeInterval()" |
||||
|
aria-label="Pick date interval" |
||||
|
> |
||||
|
<md-option ng-if="customInterval" ng-value="customInterval.ts">{{'widgets.date-range-navigator.localizationMap.' + customInterval.label | translate}}</md-option> |
||||
|
<md-option ng-repeat="(dateKey, dateValue) in datesMap" ng-value="dateValue.ts"> |
||||
|
{{'widgets.date-range-navigator.localizationMap.' + dateValue.label | translate}} |
||||
|
</md-option> |
||||
|
</md-select> |
||||
|
</md-input-container> |
||||
|
</div> |
||||
|
|
||||
|
<div class="drn__element step" ng-hide="settings.hideStepSize"> |
||||
|
<md-button ng-click="goBack()" class="md-icon-button"> |
||||
|
<md-icon>keyboard_arrow_left</md-icon> |
||||
|
</md-button> |
||||
|
<md-input-container class="md-block" |
||||
|
flex-gt-sm |
||||
|
> |
||||
|
<label ng-hide="settings.hideLabels" ng-bind="'widgets.date-range-navigator.localizationMap.Step size' | translate"></label> |
||||
|
<md-select ng-model="selectedStepSize" |
||||
|
aria-label="Pick date interval" |
||||
|
> |
||||
|
<md-option ng-repeat="(dateKey, dateValue) in datesMap" ng-value="dateValue.ts"> |
||||
|
{{'widgets.date-range-navigator.localizationMap.'+dateValue.label | translate}} |
||||
|
</md-option> |
||||
|
</md-select> |
||||
|
</md-input-container> |
||||
|
<md-button ng-click="goForth()" class="md-icon-button"> |
||||
|
<md-icon>keyboard_arrow_right</md-icon> |
||||
|
</md-button> |
||||
|
</div> |
||||
|
</div> |
||||
Loading…
Reference in new issue