44 changed files with 1445 additions and 318 deletions
File diff suppressed because one or more lines are too long
@ -0,0 +1,217 @@ |
|||||
|
/* |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
/* eslint-disable import/no-unresolved, import/default */ |
||||
|
|
||||
|
import deviceFilterTemplate from './device-filter.tpl.html'; |
||||
|
|
||||
|
/* eslint-enable import/no-unresolved, import/default */ |
||||
|
|
||||
|
import './device-filter.scss'; |
||||
|
|
||||
|
export default angular.module('thingsboard.directives.deviceFilter', []) |
||||
|
.directive('tbDeviceFilter', DeviceFilter) |
||||
|
.name; |
||||
|
|
||||
|
/*@ngInject*/ |
||||
|
function DeviceFilter($compile, $templateCache, $q, deviceService) { |
||||
|
|
||||
|
var linker = function (scope, element, attrs, ngModelCtrl) { |
||||
|
|
||||
|
var template = $templateCache.get(deviceFilterTemplate); |
||||
|
element.html(template); |
||||
|
|
||||
|
scope.ngModelCtrl = ngModelCtrl; |
||||
|
|
||||
|
scope.fetchDevices = function(searchText, limit) { |
||||
|
var pageLink = {limit: limit, textSearch: searchText}; |
||||
|
|
||||
|
var deferred = $q.defer(); |
||||
|
|
||||
|
deviceService.getTenantDevices(pageLink).then(function success(result) { |
||||
|
deferred.resolve(result.data); |
||||
|
}, function fail() { |
||||
|
deferred.reject(); |
||||
|
}); |
||||
|
|
||||
|
return deferred.promise; |
||||
|
} |
||||
|
|
||||
|
scope.updateValidity = function() { |
||||
|
if (ngModelCtrl.$viewValue) { |
||||
|
var value = ngModelCtrl.$viewValue; |
||||
|
var valid; |
||||
|
if (value.useFilter) { |
||||
|
ngModelCtrl.$setValidity('deviceList', true); |
||||
|
if (angular.isDefined(value.deviceNameFilter) && value.deviceNameFilter.length > 0) { |
||||
|
ngModelCtrl.$setValidity('deviceNameFilter', true); |
||||
|
valid = angular.isDefined(scope.model.matchingFilterDevice) && scope.model.matchingFilterDevice != null; |
||||
|
ngModelCtrl.$setValidity('deviceNameFilterDeviceMatch', valid); |
||||
|
} else { |
||||
|
ngModelCtrl.$setValidity('deviceNameFilter', false); |
||||
|
} |
||||
|
} else { |
||||
|
ngModelCtrl.$setValidity('deviceNameFilter', true); |
||||
|
ngModelCtrl.$setValidity('deviceNameFilterDeviceMatch', true); |
||||
|
valid = angular.isDefined(value.deviceList) && value.deviceList.length > 0; |
||||
|
ngModelCtrl.$setValidity('deviceList', valid); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
ngModelCtrl.$render = function () { |
||||
|
destroyWatchers(); |
||||
|
scope.model = { |
||||
|
useFilter: false, |
||||
|
deviceList: [], |
||||
|
deviceNameFilter: '' |
||||
|
} |
||||
|
if (ngModelCtrl.$viewValue) { |
||||
|
var value = ngModelCtrl.$viewValue; |
||||
|
var model = scope.model; |
||||
|
model.useFilter = value.useFilter === true ? true: false; |
||||
|
model.deviceList = []; |
||||
|
model.deviceNameFilter = value.deviceNameFilter || ''; |
||||
|
processDeviceNameFilter(model.deviceNameFilter).then( |
||||
|
function(device) { |
||||
|
scope.model.matchingFilterDevice = device; |
||||
|
if (value.deviceList && value.deviceList.length > 0) { |
||||
|
deviceService.getDevices(value.deviceList).then(function (devices) { |
||||
|
model.deviceList = devices; |
||||
|
updateMatchingDevice(); |
||||
|
initWatchers(); |
||||
|
}); |
||||
|
} else { |
||||
|
updateMatchingDevice(); |
||||
|
initWatchers(); |
||||
|
} |
||||
|
} |
||||
|
) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function updateMatchingDevice() { |
||||
|
if (scope.model.useFilter) { |
||||
|
scope.model.matchingDevice = scope.model.matchingFilterDevice; |
||||
|
} else { |
||||
|
if (scope.model.deviceList && scope.model.deviceList.length > 0) { |
||||
|
scope.model.matchingDevice = scope.model.deviceList[0]; |
||||
|
} else { |
||||
|
scope.model.matchingDevice = null; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function processDeviceNameFilter(deviceNameFilter) { |
||||
|
var deferred = $q.defer(); |
||||
|
if (angular.isDefined(deviceNameFilter) && deviceNameFilter.length > 0) { |
||||
|
scope.fetchDevices(deviceNameFilter, 1).then(function (devices) { |
||||
|
if (devices && devices.length > 0) { |
||||
|
deferred.resolve(devices[0]); |
||||
|
} else { |
||||
|
deferred.resolve(null); |
||||
|
} |
||||
|
}); |
||||
|
} else { |
||||
|
deferred.resolve(null); |
||||
|
} |
||||
|
return deferred.promise; |
||||
|
} |
||||
|
|
||||
|
function destroyWatchers() { |
||||
|
if (scope.deviceListDeregistration) { |
||||
|
scope.deviceListDeregistration(); |
||||
|
scope.deviceListDeregistration = null; |
||||
|
} |
||||
|
if (scope.useFilterDeregistration) { |
||||
|
scope.useFilterDeregistration(); |
||||
|
scope.useFilterDeregistration = null; |
||||
|
} |
||||
|
if (scope.deviceNameFilterDeregistration) { |
||||
|
scope.deviceNameFilterDeregistration(); |
||||
|
scope.deviceNameFilterDeregistration = null; |
||||
|
} |
||||
|
if (scope.matchingDeviceDeregistration) { |
||||
|
scope.matchingDeviceDeregistration(); |
||||
|
scope.matchingDeviceDeregistration = null; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function initWatchers() { |
||||
|
scope.deviceListDeregistration = scope.$watch('model.deviceList', function () { |
||||
|
if (ngModelCtrl.$viewValue) { |
||||
|
var value = ngModelCtrl.$viewValue; |
||||
|
value.deviceList = []; |
||||
|
if (scope.model.deviceList && scope.model.deviceList.length > 0) { |
||||
|
for (var i in scope.model.deviceList) { |
||||
|
value.deviceList.push(scope.model.deviceList[i].id.id); |
||||
|
} |
||||
|
} |
||||
|
updateMatchingDevice(); |
||||
|
ngModelCtrl.$setViewValue(value); |
||||
|
scope.updateValidity(); |
||||
|
} |
||||
|
}, true); |
||||
|
scope.useFilterDeregistration = scope.$watch('model.useFilter', function () { |
||||
|
if (ngModelCtrl.$viewValue) { |
||||
|
var value = ngModelCtrl.$viewValue; |
||||
|
value.useFilter = scope.model.useFilter; |
||||
|
updateMatchingDevice(); |
||||
|
ngModelCtrl.$setViewValue(value); |
||||
|
scope.updateValidity(); |
||||
|
} |
||||
|
}); |
||||
|
scope.deviceNameFilterDeregistration = scope.$watch('model.deviceNameFilter', function (newNameFilter, prevNameFilter) { |
||||
|
if (ngModelCtrl.$viewValue) { |
||||
|
if (!angular.equals(newNameFilter, prevNameFilter)) { |
||||
|
var value = ngModelCtrl.$viewValue; |
||||
|
value.deviceNameFilter = scope.model.deviceNameFilter; |
||||
|
processDeviceNameFilter(value.deviceNameFilter).then( |
||||
|
function(device) { |
||||
|
scope.model.matchingFilterDevice = device; |
||||
|
updateMatchingDevice(); |
||||
|
ngModelCtrl.$setViewValue(value); |
||||
|
scope.updateValidity(); |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
scope.matchingDeviceDeregistration = scope.$watch('model.matchingDevice', function (newMatchingDevice, prevMatchingDevice) { |
||||
|
if (!angular.equals(newMatchingDevice, prevMatchingDevice)) { |
||||
|
if (scope.onMatchingDeviceChange) { |
||||
|
scope.onMatchingDeviceChange({device: newMatchingDevice}); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
$compile(element.contents())(scope); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
return { |
||||
|
restrict: "E", |
||||
|
require: "^ngModel", |
||||
|
link: linker, |
||||
|
scope: { |
||||
|
isEdit: '=', |
||||
|
onMatchingDeviceChange: '&' |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,45 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
.tb-device-filter { |
||||
|
#device_list_chips { |
||||
|
.md-chips { |
||||
|
padding-bottom: 1px; |
||||
|
} |
||||
|
} |
||||
|
.device-name-filter-input { |
||||
|
margin-top: 10px; |
||||
|
margin-bottom: 0px; |
||||
|
.md-errors-spacer { |
||||
|
min-height: 0px; |
||||
|
} |
||||
|
} |
||||
|
.tb-filter-switch { |
||||
|
padding-left: 10px; |
||||
|
.filter-switch { |
||||
|
margin: 0; |
||||
|
} |
||||
|
.filter-label { |
||||
|
margin: 5px 0; |
||||
|
} |
||||
|
} |
||||
|
.tb-error-messages { |
||||
|
margin-top: -11px; |
||||
|
height: 35px; |
||||
|
.tb-error-message { |
||||
|
padding-left: 1px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,67 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
Copyright © 2016-2017 The Thingsboard Authors |
||||
|
|
||||
|
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
you may not use this file except in compliance with the License. |
||||
|
You may obtain a copy of the License at |
||||
|
|
||||
|
http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
|
||||
|
Unless required by applicable law or agreed to in writing, software |
||||
|
distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
See the License for the specific language governing permissions and |
||||
|
limitations under the License. |
||||
|
|
||||
|
--> |
||||
|
<section layout='column' class="tb-device-filter"> |
||||
|
<section layout='row'> |
||||
|
<section layout="column" flex ng-show="!model.useFilter"> |
||||
|
<md-chips flex |
||||
|
id="device_list_chips" |
||||
|
ng-required="!useFilter" |
||||
|
ng-model="model.deviceList" md-autocomplete-snap |
||||
|
md-require-match="true"> |
||||
|
<md-autocomplete |
||||
|
md-no-cache="true" |
||||
|
id="device" |
||||
|
md-selected-item="selectedDevice" |
||||
|
md-search-text="deviceSearchText" |
||||
|
md-items="item in fetchDevices(deviceSearchText, 10)" |
||||
|
md-item-text="item.name" |
||||
|
md-min-length="0" |
||||
|
placeholder="{{ 'device.device-list' | translate }}"> |
||||
|
<md-item-template> |
||||
|
<span md-highlight-text="deviceSearchText" md-highlight-flags="^i">{{item.name}}</span> |
||||
|
</md-item-template> |
||||
|
<md-not-found> |
||||
|
<span translate translate-values='{ device: deviceSearchText }'>device.no-devices-matching</span> |
||||
|
</md-not-found> |
||||
|
</md-autocomplete> |
||||
|
<md-chip-template> |
||||
|
<span> |
||||
|
<strong>{{$chip.name}}</strong> |
||||
|
</span> |
||||
|
</md-chip-template> |
||||
|
</md-chips> |
||||
|
</section> |
||||
|
<section layout="row" flex ng-show="model.useFilter"> |
||||
|
<md-input-container flex class="device-name-filter-input"> |
||||
|
<label translate>device.name-starts-with</label> |
||||
|
<input ng-model="model.deviceNameFilter" aria-label="{{ 'device.name-starts-with' | translate }}"> |
||||
|
</md-input-container> |
||||
|
</section> |
||||
|
<section class="tb-filter-switch" layout="column" layout-align="center center"> |
||||
|
<label class="tb-small filter-label" translate>device.use-device-name-filter</label> |
||||
|
<md-switch class="filter-switch" ng-model="model.useFilter" aria-label="use-filter-switcher"> |
||||
|
</md-switch> |
||||
|
</section> |
||||
|
</section> |
||||
|
<div class="tb-error-messages" ng-messages="ngModelCtrl.$error" role="alert"> |
||||
|
<div translate ng-message="deviceList" class="tb-error-message">device.device-list-empty</div> |
||||
|
<div translate ng-message="deviceNameFilter" class="tb-error-message">device.device-name-filter-required</div> |
||||
|
<div translate translate-values='{ device: model.deviceNameFilter }' ng-message="deviceNameFilterDeviceMatch" |
||||
|
class="tb-error-message">device.device-name-filter-no-device-matched</div> |
||||
|
</div> |
||||
|
</section> |
||||
@ -0,0 +1,32 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
Copyright © 2016-2017 The Thingsboard Authors |
||||
|
|
||||
|
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
you may not use this file except in compliance with the License. |
||||
|
You may obtain a copy of the License at |
||||
|
|
||||
|
http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
|
||||
|
Unless required by applicable law or agreed to in writing, software |
||||
|
distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
See the License for the specific language governing permissions and |
||||
|
limitations under the License. |
||||
|
|
||||
|
--> |
||||
|
|
||||
|
<section class="tb-aliases-device-select" layout='row' layout-align="start center" ng-style="{minHeight: '32px', padding: '0 6px'}"> |
||||
|
<md-button class="md-icon-button" aria-label="{{ 'dashboard.select-devices' | translate }}" ng-click="openEditMode($event)"> |
||||
|
<md-tooltip md-direction="{{tooltipDirection}}"> |
||||
|
{{ 'dashboard.select-devices' | translate }} |
||||
|
</md-tooltip> |
||||
|
<md-icon aria-label="{{ 'dashboard.select-devices' | translate }}" class="material-icons">devices_other</md-icon> |
||||
|
</md-button> |
||||
|
<span ng-click="openEditMode($event)"> |
||||
|
<md-tooltip md-direction="{{tooltipDirection}}"> |
||||
|
{{ 'dashboard.select-devices' | translate }} |
||||
|
</md-tooltip> |
||||
|
{{displayValue}} |
||||
|
</span> |
||||
|
</section> |
||||
@ -0,0 +1,31 @@ |
|||||
|
/* |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
/*@ngInject*/ |
||||
|
export default function AliasesDeviceSelectPanelController(mdPanelRef, $scope, types, deviceAliases, deviceAliasesInfo, onDeviceAliasesUpdate) { |
||||
|
|
||||
|
var vm = this; |
||||
|
vm._mdPanelRef = mdPanelRef; |
||||
|
vm.deviceAliases = deviceAliases; |
||||
|
vm.deviceAliasesInfo = deviceAliasesInfo; |
||||
|
vm.onDeviceAliasesUpdate = onDeviceAliasesUpdate; |
||||
|
|
||||
|
$scope.$watch('vm.deviceAliases', function () { |
||||
|
if (onDeviceAliasesUpdate) { |
||||
|
onDeviceAliasesUpdate(vm.deviceAliases); |
||||
|
} |
||||
|
}, true); |
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
Copyright © 2016-2017 The Thingsboard Authors |
||||
|
|
||||
|
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
you may not use this file except in compliance with the License. |
||||
|
You may obtain a copy of the License at |
||||
|
|
||||
|
http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
|
||||
|
Unless required by applicable law or agreed to in writing, software |
||||
|
distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
See the License for the specific language governing permissions and |
||||
|
limitations under the License. |
||||
|
|
||||
|
--> |
||||
|
<md-content flex layout="column"> |
||||
|
<section flex layout="column"> |
||||
|
<md-content flex class="md-padding" layout="column"> |
||||
|
<div flex layout="row" ng-repeat="(aliasId, deviceAlias) in vm.deviceAliases"> |
||||
|
<md-input-container flex> |
||||
|
<label>{{deviceAlias.alias}}</label> |
||||
|
<md-select ng-model="vm.deviceAliases[aliasId].deviceId"> |
||||
|
<md-option ng-repeat="deviceInfo in vm.deviceAliasesInfo[aliasId]" ng-value="deviceInfo.id"> |
||||
|
{{deviceInfo.name}} |
||||
|
</md-option> |
||||
|
</md-select> |
||||
|
</md-input-container> |
||||
|
</div> |
||||
|
</md-content> |
||||
|
</section> |
||||
|
</md-content> |
||||
@ -0,0 +1,153 @@ |
|||||
|
/* |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
import './aliases-device-select.scss'; |
||||
|
|
||||
|
import $ from 'jquery'; |
||||
|
|
||||
|
/* eslint-disable import/no-unresolved, import/default */ |
||||
|
|
||||
|
import aliasesDeviceSelectButtonTemplate from './aliases-device-select-button.tpl.html'; |
||||
|
import aliasesDeviceSelectPanelTemplate from './aliases-device-select-panel.tpl.html'; |
||||
|
|
||||
|
/* eslint-enable import/no-unresolved, import/default */ |
||||
|
|
||||
|
/* eslint-disable angular/angularelement */ |
||||
|
/*@ngInject*/ |
||||
|
export default function AliasesDeviceSelectDirective($compile, $templateCache, types, $mdPanel, $document, $translate) { |
||||
|
|
||||
|
var linker = function (scope, element, attrs, ngModelCtrl) { |
||||
|
|
||||
|
/* tbAliasesDeviceSelect (ng-model) |
||||
|
* { |
||||
|
* "aliasId": { |
||||
|
* alias: alias, |
||||
|
* deviceId: deviceId |
||||
|
* } |
||||
|
* } |
||||
|
*/ |
||||
|
|
||||
|
var template = $templateCache.get(aliasesDeviceSelectButtonTemplate); |
||||
|
|
||||
|
scope.tooltipDirection = angular.isDefined(attrs.tooltipDirection) ? attrs.tooltipDirection : 'top'; |
||||
|
|
||||
|
element.html(template); |
||||
|
|
||||
|
scope.openEditMode = function (event) { |
||||
|
if (scope.disabled) { |
||||
|
return; |
||||
|
} |
||||
|
var position; |
||||
|
var panelHeight = 250; |
||||
|
var panelWidth = 300; |
||||
|
var offset = element[0].getBoundingClientRect(); |
||||
|
var bottomY = offset.bottom - $(window).scrollTop(); //eslint-disable-line
|
||||
|
var leftX = offset.left - $(window).scrollLeft(); //eslint-disable-line
|
||||
|
var yPosition; |
||||
|
var xPosition; |
||||
|
if (bottomY + panelHeight > $( window ).height()) { //eslint-disable-line
|
||||
|
yPosition = $mdPanel.yPosition.ABOVE; |
||||
|
} else { |
||||
|
yPosition = $mdPanel.yPosition.BELOW; |
||||
|
} |
||||
|
if (leftX + panelWidth > $( window ).width()) { //eslint-disable-line
|
||||
|
xPosition = $mdPanel.xPosition.ALIGN_END; |
||||
|
} else { |
||||
|
xPosition = $mdPanel.xPosition.ALIGN_START; |
||||
|
} |
||||
|
position = $mdPanel.newPanelPosition() |
||||
|
.relativeTo(element) |
||||
|
.addPanelPosition(xPosition, yPosition); |
||||
|
var config = { |
||||
|
attachTo: angular.element($document[0].body), |
||||
|
controller: 'AliasesDeviceSelectPanelController', |
||||
|
controllerAs: 'vm', |
||||
|
templateUrl: aliasesDeviceSelectPanelTemplate, |
||||
|
panelClass: 'tb-aliases-device-select-panel', |
||||
|
position: position, |
||||
|
fullscreen: false, |
||||
|
locals: { |
||||
|
'deviceAliases': angular.copy(scope.model), |
||||
|
'deviceAliasesInfo': scope.deviceAliasesInfo, |
||||
|
'onDeviceAliasesUpdate': function (deviceAliases) { |
||||
|
scope.model = deviceAliases; |
||||
|
scope.updateView(); |
||||
|
} |
||||
|
}, |
||||
|
openFrom: event, |
||||
|
clickOutsideToClose: true, |
||||
|
escapeToClose: true, |
||||
|
focusOnOpen: false |
||||
|
}; |
||||
|
$mdPanel.open(config); |
||||
|
} |
||||
|
|
||||
|
scope.updateView = function () { |
||||
|
var value = angular.copy(scope.model); |
||||
|
ngModelCtrl.$setViewValue(value); |
||||
|
updateDisplayValue(); |
||||
|
} |
||||
|
|
||||
|
ngModelCtrl.$render = function () { |
||||
|
if (ngModelCtrl.$viewValue) { |
||||
|
var value = ngModelCtrl.$viewValue; |
||||
|
scope.model = angular.copy(value); |
||||
|
updateDisplayValue(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function updateDisplayValue() { |
||||
|
var displayValue; |
||||
|
var singleValue = true; |
||||
|
var currentAliasId; |
||||
|
for (var aliasId in scope.model) { |
||||
|
if (!currentAliasId) { |
||||
|
currentAliasId = aliasId; |
||||
|
} else { |
||||
|
singleValue = false; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
if (singleValue) { |
||||
|
var deviceId = scope.model[currentAliasId].deviceId; |
||||
|
var devicesInfo = scope.deviceAliasesInfo[currentAliasId]; |
||||
|
for (var i=0;i<devicesInfo.length;i++) { |
||||
|
if (devicesInfo[i].id === deviceId) { |
||||
|
displayValue = devicesInfo[i].name; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
displayValue = $translate.instant('device.devices'); |
||||
|
} |
||||
|
scope.displayValue = displayValue; |
||||
|
} |
||||
|
|
||||
|
$compile(element.contents())(scope); |
||||
|
} |
||||
|
|
||||
|
return { |
||||
|
restrict: "E", |
||||
|
require: "^ngModel", |
||||
|
scope: { |
||||
|
deviceAliasesInfo:'=' |
||||
|
}, |
||||
|
link: linker |
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/* eslint-enable angular/angularelement */ |
||||
@ -0,0 +1,43 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
.md-panel { |
||||
|
&.tb-aliases-device-select-panel { |
||||
|
position: absolute; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.tb-aliases-device-select-panel { |
||||
|
max-height: 250px; |
||||
|
min-width: 300px; |
||||
|
background: white; |
||||
|
border-radius: 4px; |
||||
|
box-shadow: 0 7px 8px -4px rgba(0, 0, 0, 0.2), |
||||
|
0 13px 19px 2px rgba(0, 0, 0, 0.14), |
||||
|
0 5px 24px 4px rgba(0, 0, 0, 0.12); |
||||
|
overflow-x: hidden; |
||||
|
overflow-y: auto; |
||||
|
md-content { |
||||
|
background-color: #fff; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.tb-aliases-device-select { |
||||
|
span { |
||||
|
pointer-events: all; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue