44 changed files with 1399 additions and 126 deletions
@ -0,0 +1,146 @@ |
|||
/* |
|||
* 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 entitySubtypeListTemplate from './entity-subtype-list.tpl.html'; |
|||
|
|||
/* eslint-enable import/no-unresolved, import/default */ |
|||
|
|||
import './entity-subtype-list.scss'; |
|||
|
|||
/*@ngInject*/ |
|||
export default function EntitySubtypeListDirective($compile, $templateCache, $q, $mdUtil, $translate, $filter, types, assetService, deviceService) { |
|||
|
|||
var linker = function (scope, element, attrs, ngModelCtrl) { |
|||
|
|||
var template = $templateCache.get(entitySubtypeListTemplate); |
|||
element.html(template); |
|||
|
|||
scope.ngModelCtrl = ngModelCtrl; |
|||
|
|||
|
|||
scope.entitySubtypesList = []; |
|||
scope.entitySubtypes = null; |
|||
|
|||
if (scope.entityType == types.entityType.asset) { |
|||
scope.placeholder = scope.tbRequired ? $translate.instant('asset.enter-asset-type') |
|||
: $translate.instant('asset.any-asset'); |
|||
scope.secondaryPlaceholder = '+' + $translate.instant('asset.asset-type'); |
|||
scope.noSubtypesMathingText = 'asset.no-asset-types-matching'; |
|||
scope.subtypeListEmptyText = 'asset.asset-type-list-empty'; |
|||
} else if (scope.entityType == types.entityType.device) { |
|||
scope.placeholder = scope.tbRequired ? $translate.instant('device.enter-device-type') |
|||
: $translate.instant('device.any-device'); |
|||
scope.secondaryPlaceholder = '+' + $translate.instant('device.device-type'); |
|||
scope.noSubtypesMathingText = 'device.no-device-types-matching'; |
|||
scope.subtypeListEmptyText = 'device.device-type-list-empty'; |
|||
} |
|||
|
|||
scope.$watch('tbRequired', function () { |
|||
scope.updateValidity(); |
|||
}); |
|||
|
|||
scope.fetchEntitySubtypes = function(searchText) { |
|||
var deferred = $q.defer(); |
|||
loadSubTypes().then( |
|||
function success(subTypes) { |
|||
var result = $filter('filter')(subTypes, {'$': searchText}); |
|||
if (result && result.length) { |
|||
deferred.resolve(result); |
|||
} else { |
|||
deferred.resolve([searchText]); |
|||
} |
|||
}, |
|||
function fail() { |
|||
deferred.reject(); |
|||
} |
|||
); |
|||
return deferred.promise; |
|||
} |
|||
|
|||
scope.updateValidity = function() { |
|||
var value = ngModelCtrl.$viewValue; |
|||
var valid = !scope.tbRequired || value && value.length > 0; |
|||
ngModelCtrl.$setValidity('entitySubtypesList', valid); |
|||
} |
|||
|
|||
ngModelCtrl.$render = function () { |
|||
scope.entitySubtypesList = ngModelCtrl.$viewValue; |
|||
if (!scope.entitySubtypesList) { |
|||
scope.entitySubtypesList = []; |
|||
} |
|||
} |
|||
|
|||
scope.$watch('entitySubtypesList', function () { |
|||
ngModelCtrl.$setViewValue(scope.entitySubtypesList); |
|||
scope.updateValidity(); |
|||
}, true); |
|||
|
|||
function loadSubTypes() { |
|||
var deferred = $q.defer(); |
|||
if (!scope.entitySubtypes) { |
|||
var entitySubtypesPromise; |
|||
if (scope.entityType == types.entityType.asset) { |
|||
entitySubtypesPromise = assetService.getAssetTypes(); |
|||
} else if (scope.entityType == types.entityType.device) { |
|||
entitySubtypesPromise = deviceService.getDeviceTypes(); |
|||
} |
|||
if (entitySubtypesPromise) { |
|||
entitySubtypesPromise.then( |
|||
function success(types) { |
|||
scope.entitySubtypes = []; |
|||
types.forEach(function (type) { |
|||
scope.entitySubtypes.push(type.type); |
|||
}); |
|||
deferred.resolve(scope.entitySubtypes); |
|||
}, |
|||
function fail() { |
|||
deferred.reject(); |
|||
} |
|||
); |
|||
} else { |
|||
deferred.reject(); |
|||
} |
|||
} else { |
|||
deferred.resolve(scope.entitySubtypes); |
|||
} |
|||
return deferred.promise; |
|||
} |
|||
|
|||
$compile(element.contents())(scope); |
|||
|
|||
$mdUtil.nextTick(function(){ |
|||
var inputElement = angular.element('input', element); |
|||
inputElement.on('blur', function() { |
|||
scope.inputTouched = true; |
|||
} ); |
|||
}); |
|||
|
|||
} |
|||
|
|||
return { |
|||
restrict: "E", |
|||
require: "^ngModel", |
|||
link: linker, |
|||
scope: { |
|||
disabled:'=ngDisabled', |
|||
tbRequired: '=?', |
|||
entityType: "=" |
|||
} |
|||
}; |
|||
|
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
/** |
|||
* 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-entity-subtype-list { |
|||
#entity_subtype_list_chips { |
|||
.md-chips { |
|||
padding-bottom: 1px; |
|||
} |
|||
} |
|||
.tb-error-messages { |
|||
margin-top: -11px; |
|||
height: 35px; |
|||
.tb-error-message { |
|||
padding-left: 1px; |
|||
} |
|||
} |
|||
}*/ |
|||
@ -0,0 +1,54 @@ |
|||
<!-- |
|||
|
|||
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 flex layout='column' class="tb-entity-subtype-list"> |
|||
<md-chips flex |
|||
readonly="disabled" |
|||
id="entity_subtype_list_chips" |
|||
ng-required="tbRequired" |
|||
ng-model="entitySubtypesList" |
|||
placeholder="{{placeholder}}" |
|||
secondary-placeholder="{{secondaryPlaceholder}}" |
|||
md-autocomplete-snap |
|||
md-require-match="false"> |
|||
<md-autocomplete |
|||
md-no-cache="true" |
|||
id="entitySubtype" |
|||
md-selected-item="selectedEntitySubtype" |
|||
md-search-text="entitySubtypeSearchText" |
|||
md-items="item in fetchEntitySubtypes(entitySubtypeSearchText)" |
|||
md-item-text="item" |
|||
md-min-length="0" |
|||
placeholder="{{ (!entitySubtypesList || !entitySubtypesList.length) ? placeholder : secondaryPlaceholder }}"> |
|||
<md-item-template> |
|||
<span md-highlight-text="entitySubtypeSearchText" md-highlight-flags="^i">{{item}}</span> |
|||
</md-item-template> |
|||
<md-not-found> |
|||
<span translate translate-values='{ entitySubtype: entitySubtypeSearchText }'>{{noSubtypesMathingText}}</span> |
|||
</md-not-found> |
|||
</md-autocomplete> |
|||
<md-chip-template> |
|||
<span> |
|||
<strong>{{$chip}}</strong> |
|||
</span> |
|||
</md-chip-template> |
|||
</md-chips> |
|||
<div class="tb-error-messages" ng-messages="ngModelCtrl.$error" ng-if="inputTouched && tbRequired" role="alert"> |
|||
<div translate ng-message="entitySubtypesList" class="tb-error-message">{{subtypeListEmptyText}}</div> |
|||
</div> |
|||
</section> |
|||
@ -0,0 +1,111 @@ |
|||
/* |
|||
* 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 entityTypeListTemplate from './entity-type-list.tpl.html'; |
|||
|
|||
/* eslint-enable import/no-unresolved, import/default */ |
|||
|
|||
import './entity-type-list.scss'; |
|||
|
|||
/*@ngInject*/ |
|||
export default function EntityTypeListDirective($compile, $templateCache, $q, $mdUtil, $translate, $filter, types, entityService) { |
|||
|
|||
var linker = function (scope, element, attrs, ngModelCtrl) { |
|||
|
|||
var template = $templateCache.get(entityTypeListTemplate); |
|||
element.html(template); |
|||
|
|||
scope.ngModelCtrl = ngModelCtrl; |
|||
|
|||
scope.placeholder = scope.tbRequired ? $translate.instant('entity.enter-entity-type') |
|||
: $translate.instant('entity.any-entity'); |
|||
scope.secondaryPlaceholder = '+' + $translate.instant('entity.entity-type'); |
|||
|
|||
var entityTypes = entityService.prepareAllowedEntityTypesList(scope.allowedEntityTypes); |
|||
scope.entityTypesList = []; |
|||
for (var type in entityTypes) { |
|||
var entityTypeInfo = {}; |
|||
entityTypeInfo.value = entityTypes[type]; |
|||
entityTypeInfo.name = $translate.instant(types.entityTypeTranslations[entityTypeInfo.value].type) + ''; |
|||
scope.entityTypesList.push(entityTypeInfo); |
|||
} |
|||
|
|||
scope.$watch('tbRequired', function () { |
|||
scope.updateValidity(); |
|||
}); |
|||
|
|||
scope.fetchEntityTypes = function(searchText) { |
|||
var deferred = $q.defer(); |
|||
var entityTypes = $filter('filter')(scope.entityTypesList, {name: searchText}); |
|||
deferred.resolve(entityTypes); |
|||
return deferred.promise; |
|||
} |
|||
|
|||
scope.updateValidity = function() { |
|||
var value = ngModelCtrl.$viewValue; |
|||
var valid = !scope.tbRequired || value && value.length > 0; |
|||
ngModelCtrl.$setValidity('entityTypeList', valid); |
|||
} |
|||
|
|||
ngModelCtrl.$render = function () { |
|||
scope.entityTypeList = []; |
|||
var value = ngModelCtrl.$viewValue; |
|||
if (value && value.length) { |
|||
value.forEach(function(type) { |
|||
var entityTypeInfo = {}; |
|||
entityTypeInfo.value = type; |
|||
entityTypeInfo.name = $translate.instant(types.entityTypeTranslations[entityTypeInfo.value].type) + ''; |
|||
scope.entityTypeList.push(entityTypeInfo); |
|||
}); |
|||
} |
|||
} |
|||
|
|||
scope.$watch('entityTypeList', function () { |
|||
var values = []; |
|||
if (scope.entityTypeList && scope.entityTypeList.length) { |
|||
scope.entityTypeList.forEach(function(entityType) { |
|||
values.push(entityType.value); |
|||
}); |
|||
} |
|||
ngModelCtrl.$setViewValue(values); |
|||
scope.updateValidity(); |
|||
}, true); |
|||
|
|||
$compile(element.contents())(scope); |
|||
|
|||
$mdUtil.nextTick(function(){ |
|||
var inputElement = angular.element('input', element); |
|||
inputElement.on('blur', function() { |
|||
scope.inputTouched = true; |
|||
} ); |
|||
}); |
|||
|
|||
} |
|||
|
|||
return { |
|||
restrict: "E", |
|||
require: "^ngModel", |
|||
link: linker, |
|||
scope: { |
|||
disabled:'=ngDisabled', |
|||
tbRequired: '=?', |
|||
allowedEntityTypes: '=?' |
|||
} |
|||
}; |
|||
|
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
/** |
|||
* 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-entity-type-list { |
|||
#entity_type_list_chips { |
|||
.md-chips { |
|||
padding-bottom: 1px; |
|||
} |
|||
} |
|||
.tb-error-messages { |
|||
margin-top: -11px; |
|||
height: 35px; |
|||
.tb-error-message { |
|||
padding-left: 1px; |
|||
} |
|||
} |
|||
}*/ |
|||
@ -0,0 +1,54 @@ |
|||
<!-- |
|||
|
|||
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 flex layout='column' class="tb-entity-type-list"> |
|||
<md-chips flex |
|||
readonly="disabled" |
|||
id="entity_type_list_chips" |
|||
ng-required="tbRequired" |
|||
ng-model="entityTypeList" |
|||
placeholder="{{placeholder}}" |
|||
secondary-placeholder="{{secondaryPlaceholder}}" |
|||
md-autocomplete-snap |
|||
md-require-match="true"> |
|||
<md-autocomplete |
|||
md-no-cache="true" |
|||
id="entityType" |
|||
md-selected-item="selectedEntityType" |
|||
md-search-text="entityTypeSearchText" |
|||
md-items="item in fetchEntityTypes(entityTypeSearchText)" |
|||
md-item-text="item.name" |
|||
md-min-length="0" |
|||
placeholder="{{ (!entityTypeList || !entityTypeList.length) ? placeholder : secondaryPlaceholder }}"> |
|||
<md-item-template> |
|||
<span md-highlight-text="entityTypeSearchText" md-highlight-flags="^i">{{item.name}}</span> |
|||
</md-item-template> |
|||
<md-not-found> |
|||
<span translate translate-values='{ entityType: entityTypeSearchText }'>entity.no-entity-types-matching</span> |
|||
</md-not-found> |
|||
</md-autocomplete> |
|||
<md-chip-template> |
|||
<span> |
|||
<strong>{{$chip.name}}</strong> |
|||
</span> |
|||
</md-chip-template> |
|||
</md-chips> |
|||
<div class="tb-error-messages" ng-messages="ngModelCtrl.$error" ng-if="inputTouched && tbRequired" role="alert"> |
|||
<div translate ng-message="entityTypeList" class="tb-error-message">entity.entity-type-list-empty</div> |
|||
</div> |
|||
</section> |
|||
@ -0,0 +1,85 @@ |
|||
/* |
|||
* 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 './relation-filters.scss'; |
|||
|
|||
/* eslint-disable import/no-unresolved, import/default */ |
|||
|
|||
import relationFiltersTemplate from './relation-filters.tpl.html'; |
|||
|
|||
/* eslint-enable import/no-unresolved, import/default */ |
|||
|
|||
/*@ngInject*/ |
|||
export default function RelationFilters($compile, $templateCache) { |
|||
|
|||
return { |
|||
restrict: "E", |
|||
require: "^ngModel", |
|||
scope: { |
|||
allowedEntityTypes: '=?' |
|||
}, |
|||
link: linker |
|||
}; |
|||
|
|||
function linker( scope, element, attrs, ngModelCtrl ) { |
|||
|
|||
var template = $templateCache.get(relationFiltersTemplate); |
|||
element.html(template); |
|||
|
|||
scope.relationFilters = []; |
|||
|
|||
scope.addFilter = addFilter; |
|||
scope.removeFilter = removeFilter; |
|||
|
|||
ngModelCtrl.$render = function () { |
|||
if (ngModelCtrl.$viewValue) { |
|||
var value = ngModelCtrl.$viewValue; |
|||
value.forEach(function (filter) { |
|||
scope.relationFilters.push(filter); |
|||
}); |
|||
} |
|||
scope.$watch('relationFilters', function (newVal, prevVal) { |
|||
if (!angular.equals(newVal, prevVal)) { |
|||
updateValue(); |
|||
} |
|||
}, true); |
|||
} |
|||
|
|||
function addFilter() { |
|||
var filter = { |
|||
relationType: null, |
|||
entityTypes: [] |
|||
}; |
|||
scope.relationFilters.push(filter); |
|||
} |
|||
|
|||
function removeFilter($event, filter) { |
|||
var index = scope.relationFilters.indexOf(filter); |
|||
if (index > -1) { |
|||
scope.relationFilters.splice(index, 1); |
|||
} |
|||
} |
|||
|
|||
function updateValue() { |
|||
var value = []; |
|||
scope.relationFilters.forEach(function (filter) { |
|||
value.push(filter); |
|||
}); |
|||
ngModelCtrl.$setViewValue(value); |
|||
} |
|||
$compile(element.contents())(scope); |
|||
} |
|||
} |
|||
@ -0,0 +1,77 @@ |
|||
/** |
|||
* 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-relation-filters { |
|||
.header { |
|||
padding-left: 5px; |
|||
padding-right: 5px; |
|||
padding-bottom: 5px; |
|||
.cell { |
|||
padding-left: 5px; |
|||
padding-right: 5px; |
|||
color: rgba(0,0,0,.54); |
|||
font-size: 12px; |
|||
font-weight: 700; |
|||
white-space: nowrap; |
|||
} |
|||
} |
|||
.body { |
|||
padding-left: 5px; |
|||
padding-right: 5px; |
|||
max-height: 300px; |
|||
overflow: auto; |
|||
padding-bottom: 20px; |
|||
.row { |
|||
padding-top: 5px; |
|||
} |
|||
.cell { |
|||
padding-left: 5px; |
|||
padding-right: 5px; |
|||
|
|||
md-select { |
|||
margin: 0 0 24px; |
|||
} |
|||
|
|||
md-input-container { |
|||
margin: 0; |
|||
} |
|||
|
|||
md-chips-wrap { |
|||
padding: 0px; |
|||
margin: 0 0 24px; |
|||
.md-chip-input-container { |
|||
margin: 0; |
|||
} |
|||
md-autocomplete { |
|||
height: 30px; |
|||
md-autocomplete-wrap { |
|||
height: 30px; |
|||
} |
|||
} |
|||
} |
|||
.md-chips .md-chip-input-container input { |
|||
padding: 2px 2px 2px; |
|||
height: 26px; |
|||
line-height: 26px; |
|||
} |
|||
|
|||
} |
|||
|
|||
.md-button { |
|||
margin: 0; |
|||
} |
|||
} |
|||
} |
|||
@ -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. |
|||
|
|||
--> |
|||
<div class="tb-relation-filters"> |
|||
<div class="header" ng-show="relationFilters.length"> |
|||
<div layout="row" layout-align="start center"> |
|||
<span class="cell" style="width: 200px; min-width: 200px;" translate>relation.type</span> |
|||
<span class="cell" flex translate>entity.entity-types</span> |
|||
<span class="cell" style="width: 40px; min-width: 40px;"> </span> |
|||
</div> |
|||
</div> |
|||
<div class="body" ng-show="relationFilters.length"> |
|||
<div class="row" ng-form name="relationFilterForm" flex layout="row" layout-align="start center" ng-repeat="filter in relationFilters track by $index"> |
|||
<div class="md-whiteframe-1dp" flex layout="row" layout-align="start center"> |
|||
<tb-relation-type-autocomplete class="cell" style="width: 200px; min-width: 200px;" |
|||
hide-label |
|||
the-form="relationFilterForm" |
|||
ng-model="filter.relationType" |
|||
tb-required="false"> |
|||
</tb-relation-type-autocomplete> |
|||
<tb-entity-type-list class="cell" flex |
|||
ng-model="filter.entityTypes" |
|||
allowed-entity-types="allowedEntityTypes" |
|||
tb-required="false"> |
|||
</tb-entity-type-list> |
|||
<md-button ng-disabled="loading" class="md-icon-button md-primary" style="width: 40px; min-width: 40px;" |
|||
ng-click="removeFilter($event, filter)" aria-label="{{ 'action.remove' | translate }}"> |
|||
<md-tooltip md-direction="top"> |
|||
{{ 'relation.remove-relation-filter' | translate }} |
|||
</md-tooltip> |
|||
<md-icon aria-label="{{ 'action.remove' | translate }}" class="material-icons"> |
|||
close |
|||
</md-icon> |
|||
</md-button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="any-filter" ng-show="!relationFilters.length"> |
|||
<span layout-align="center center" |
|||
class="tb-prompt" translate>relation.any-relation</span> |
|||
</div> |
|||
<div> |
|||
<md-button ng-disabled="loading" class="md-primary md-raised" ng-click="addFilter($event)" aria-label="{{ 'action.add' | translate }}"> |
|||
<md-tooltip md-direction="top"> |
|||
{{ 'relation.add-relation-filter' | translate }} |
|||
</md-tooltip> |
|||
<md-icon aria-label="{{ 'action.add' | translate }}" class="material-icons"> |
|||
add |
|||
</md-icon> |
|||
{{ 'action.add' | translate }} |
|||
</md-button> |
|||
</div> |
|||
</div> |
|||
Loading…
Reference in new issue