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