29 changed files with 977 additions and 26 deletions
@ -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. |
|||
*/ |
|||
|
|||
export default angular.module('thingsboard.directives.finishRender', []) |
|||
.directive('tbOnFinishRender', OnFinishRender) |
|||
.name; |
|||
|
|||
/*@ngInject*/ |
|||
function OnFinishRender($timeout) { |
|||
return { |
|||
restrict: 'A', |
|||
link: function (scope, element, attr) { |
|||
if (scope.$last === true) { |
|||
$timeout(function () { |
|||
scope.$emit(attr.tbOnFinishRender); |
|||
}); |
|||
} |
|||
} |
|||
}; |
|||
} |
|||
@ -0,0 +1,88 @@ |
|||
/* |
|||
* 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 MaterialIconsDialogController from './material-icons-dialog.controller'; |
|||
|
|||
/* eslint-disable import/no-unresolved, import/default */ |
|||
|
|||
import materialIconSelectTemplate from './material-icon-select.tpl.html'; |
|||
import materialIconsDialogTemplate from './material-icons-dialog.tpl.html'; |
|||
|
|||
/* eslint-enable import/no-unresolved, import/default */ |
|||
|
|||
|
|||
export default angular.module('thingsboard.directives.materialIconSelect', []) |
|||
.controller('MaterialIconsDialogController', MaterialIconsDialogController) |
|||
.directive('tbMaterialIconSelect', MaterialIconSelect) |
|||
.name; |
|||
|
|||
/*@ngInject*/ |
|||
function MaterialIconSelect($compile, $templateCache, $document, $mdDialog) { |
|||
|
|||
var linker = function (scope, element, attrs, ngModelCtrl) { |
|||
var template = $templateCache.get(materialIconSelectTemplate); |
|||
element.html(template); |
|||
|
|||
scope.tbRequired = angular.isDefined(scope.tbRequired) ? scope.tbRequired : false; |
|||
scope.icon = null; |
|||
|
|||
scope.updateView = function () { |
|||
ngModelCtrl.$setViewValue(scope.icon); |
|||
} |
|||
|
|||
ngModelCtrl.$render = function () { |
|||
if (ngModelCtrl.$viewValue) { |
|||
scope.icon = ngModelCtrl.$viewValue; |
|||
} |
|||
if (!scope.icon || !scope.icon.length) { |
|||
scope.icon = 'more_horiz'; |
|||
} |
|||
} |
|||
|
|||
scope.$watch('icon', function () { |
|||
scope.updateView(); |
|||
}); |
|||
|
|||
scope.openIconDialog = function($event) { |
|||
if ($event) { |
|||
$event.stopPropagation(); |
|||
} |
|||
$mdDialog.show({ |
|||
controller: 'MaterialIconsDialogController', |
|||
controllerAs: 'vm', |
|||
templateUrl: materialIconsDialogTemplate, |
|||
parent: angular.element($document[0].body), |
|||
locals: {icon: scope.icon}, |
|||
skipHide: true, |
|||
fullscreen: true, |
|||
targetEvent: $event |
|||
}).then(function (icon) { |
|||
scope.icon = icon; |
|||
}); |
|||
} |
|||
|
|||
$compile(element.contents())(scope); |
|||
} |
|||
|
|||
return { |
|||
restrict: "E", |
|||
require: "^ngModel", |
|||
link: linker, |
|||
scope: { |
|||
tbRequired: '=?', |
|||
} |
|||
}; |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
<!-- |
|||
|
|||
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 layout="row"> |
|||
<md-icon class="material-icons" ng-click="openIconDialog($event)">{{icon}}</md-icon> |
|||
<md-input-container flex> |
|||
<md-input-container class="md-block"> |
|||
<label translate>icon.icon</label> |
|||
<input ng-click="openIconDialog($event)" ng-model="icon"> |
|||
</md-input-container> |
|||
</md-input-container> |
|||
</div> |
|||
@ -0,0 +1,59 @@ |
|||
/* |
|||
* 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 './material-icons-dialog.scss'; |
|||
|
|||
/*@ngInject*/ |
|||
export default function MaterialIconsDialogController($scope, $mdDialog, $timeout, utils, icon) { |
|||
|
|||
var vm = this; |
|||
|
|||
vm.selectedIcon = icon; |
|||
|
|||
vm.showAll = false; |
|||
vm.loadingIcons = false; |
|||
|
|||
$scope.$watch('vm.showAll', function(showAll) { |
|||
if (showAll) { |
|||
vm.loadingIcons = true; |
|||
$timeout(function() { |
|||
utils.getMaterialIcons().then( |
|||
function success(icons) { |
|||
vm.icons = icons; |
|||
} |
|||
); |
|||
}); |
|||
} else { |
|||
vm.icons = utils.getCommonMaterialIcons(); |
|||
} |
|||
}); |
|||
|
|||
$scope.$on('iconsLoadFinished', function() { |
|||
vm.loadingIcons = false; |
|||
}); |
|||
|
|||
vm.cancel = cancel; |
|||
vm.selectIcon = selectIcon; |
|||
|
|||
function cancel() { |
|||
$mdDialog.cancel(); |
|||
} |
|||
|
|||
function selectIcon($event, icon) { |
|||
vm.selectedIcon = icon; |
|||
$mdDialog.hide(vm.selectedIcon); |
|||
} |
|||
} |
|||
@ -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. |
|||
*/ |
|||
|
|||
.tb-material-icons-dialog { |
|||
button.md-icon-button.tb-select-icon-button { |
|||
border: solid 1px orange; |
|||
border-radius: 0%; |
|||
padding: 16px; |
|||
height: 56px; |
|||
width: 56px; |
|||
margin: 10px; |
|||
} |
|||
.tb-icons-load { |
|||
top: 64px; |
|||
background: rgba(255,255,255,0.75); |
|||
z-index: 3; |
|||
} |
|||
} |
|||
@ -0,0 +1,62 @@ |
|||
<!-- |
|||
|
|||
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-dialog class="tb-material-icons-dialog" aria-label="{{'icon.material-icons' | translate }}" style="min-width: 600px;"> |
|||
<form> |
|||
<md-toolbar> |
|||
<div class="md-toolbar-tools"> |
|||
<h2>{{ 'icon.select-icon' | translate }}</h2> |
|||
<span flex></span> |
|||
<section layout="row" layout-align="start center"> |
|||
<md-switch ng-model="vm.showAll" |
|||
aria-label="{{ 'icon.show-all' | translate }}"> |
|||
</md-switch> |
|||
<label translate>icon.show-all</label> |
|||
</section> |
|||
<md-button class="md-icon-button" ng-click="vm.cancel()"> |
|||
<ng-md-icon icon="close" aria-label="{{ 'action.close' | translate }}"></ng-md-icon> |
|||
</md-button> |
|||
</div> |
|||
</md-toolbar> |
|||
<md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> |
|||
<span style="min-height: 5px;" flex="" ng-show="!loading"></span> |
|||
<div class="tb-absolute-fill tb-icons-load" ng-show="vm.loadingIcons" layout="column" layout-align="center center"> |
|||
<md-progress-circular md-mode="indeterminate" ng-disabled="!vm.loadingIcons" class="md-accent" md-diameter="40"></md-progress-circular> |
|||
</div> |
|||
<md-dialog-content> |
|||
<div class="md-dialog-content"> |
|||
<md-content class="md-padding" layout="column"> |
|||
<fieldset ng-disabled="loading"> |
|||
<md-button ng-class="{'md-primary md-raised': icon == vm.selectedIcon}" class="tb-select-icon-button md-icon-button" |
|||
ng-repeat="icon in vm.icons" ng-click="vm.selectIcon($event, icon)" tb-on-finish-render="iconsLoadFinished"> |
|||
<md-icon class="material-icons">{{icon}}</md-icon> |
|||
<md-tooltip md-direction="bottom"> |
|||
{{ icon }} |
|||
</md-tooltip> |
|||
</md-button> |
|||
</fieldset> |
|||
</md-content> |
|||
</div> |
|||
</md-dialog-content> |
|||
<md-dialog-actions layout="row"> |
|||
<span flex></span> |
|||
<md-button ng-disabled="loading" ng-click="vm.cancel()"> |
|||
{{ 'action.cancel' | translate }} |
|||
</md-button> |
|||
</md-dialog-actions> |
|||
</form> |
|||
</md-dialog> |
|||
@ -0,0 +1,255 @@ |
|||
/** |
|||
* Created by igor on 6/20/17. |
|||
*/ |
|||
/* |
|||
* 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 './manage-widget-actions.scss'; |
|||
|
|||
import thingsboardMaterialIconSelect from '../../material-icon-select.directive'; |
|||
|
|||
import WidgetActionDialogController from './widget-action-dialog.controller'; |
|||
|
|||
/* eslint-disable import/no-unresolved, import/default */ |
|||
|
|||
import manageWidgetActionsTemplate from './manage-widget-actions.tpl.html'; |
|||
import widgetActionDialogTemplate from './widget-action-dialog.tpl.html'; |
|||
|
|||
/* eslint-enable import/no-unresolved, import/default */ |
|||
|
|||
export default angular.module('thingsboard.directives.widgetActions', [thingsboardMaterialIconSelect]) |
|||
.controller('WidgetActionDialogController', WidgetActionDialogController) |
|||
.directive('tbManageWidgetActions', ManageWidgetActions) |
|||
.name; |
|||
|
|||
/*@ngInject*/ |
|||
function ManageWidgetActions() { |
|||
return { |
|||
restrict: "E", |
|||
scope: true, |
|||
bindToController: { |
|||
actionSources: '=', |
|||
widgetActions: '=' |
|||
}, |
|||
controller: ManageWidgetActionsController, |
|||
controllerAs: 'vm', |
|||
templateUrl: manageWidgetActionsTemplate |
|||
}; |
|||
} |
|||
|
|||
/* eslint-disable angular/angularelement */ |
|||
|
|||
|
|||
/*@ngInject*/ |
|||
function ManageWidgetActionsController($rootScope, $scope, $document, $mdDialog, $q, $filter, |
|||
$translate, $timeout, types) { |
|||
|
|||
let vm = this; |
|||
|
|||
vm.allActions = []; |
|||
|
|||
vm.actions = []; |
|||
vm.actionsCount = 0; |
|||
|
|||
vm.query = { |
|||
order: 'actionSourceName', |
|||
limit: 10, |
|||
page: 1, |
|||
search: null |
|||
}; |
|||
|
|||
vm.enterFilterMode = enterFilterMode; |
|||
vm.exitFilterMode = exitFilterMode; |
|||
vm.onReorder = onReorder; |
|||
vm.onPaginate = onPaginate; |
|||
vm.addAction = addAction; |
|||
vm.editAction = editAction; |
|||
vm.deleteAction = deleteAction; |
|||
|
|||
$timeout(function(){ |
|||
$scope.manageWidgetActionsForm.querySearchInput.$pristine = false; |
|||
}); |
|||
|
|||
$scope.$watch('vm.widgetActions', function() { |
|||
if (vm.widgetActions) { |
|||
reloadActions(); |
|||
} |
|||
}); |
|||
|
|||
$scope.$watch("vm.query.search", function(newVal, prevVal) { |
|||
if (!angular.equals(newVal, prevVal) && vm.query.search != null) { |
|||
updateActions(); |
|||
} |
|||
}); |
|||
|
|||
function enterFilterMode () { |
|||
vm.query.search = ''; |
|||
} |
|||
|
|||
function exitFilterMode () { |
|||
vm.query.search = null; |
|||
updateActions(); |
|||
} |
|||
|
|||
function onReorder () { |
|||
updateActions(); |
|||
} |
|||
|
|||
function onPaginate () { |
|||
updateActions(); |
|||
} |
|||
|
|||
function addAction($event) { |
|||
if ($event) { |
|||
$event.stopPropagation(); |
|||
} |
|||
openWidgetActionDialog($event, null, true); |
|||
} |
|||
|
|||
function editAction ($event, action) { |
|||
if ($event) { |
|||
$event.stopPropagation(); |
|||
} |
|||
openWidgetActionDialog($event, action, false); |
|||
} |
|||
|
|||
function deleteAction($event, action) { |
|||
if ($event) { |
|||
$event.stopPropagation(); |
|||
} |
|||
if (action) { |
|||
var title = $translate.instant('widget-config.delete-action-title'); |
|||
var content = $translate.instant('widget-config.delete-action-text', {actionName: action.name}); |
|||
var confirm = $mdDialog.confirm() |
|||
.targetEvent($event) |
|||
.title(title) |
|||
.htmlContent(content) |
|||
.ariaLabel(title) |
|||
.cancel($translate.instant('action.no')) |
|||
.ok($translate.instant('action.yes')); |
|||
|
|||
confirm._options.skipHide = true; |
|||
confirm._options.fullscreen = true; |
|||
|
|||
$mdDialog.show(confirm).then(function () { |
|||
var index = getActionIndex(action.id, vm.allActions); |
|||
if (index > -1) { |
|||
vm.allActions.splice(index, 1); |
|||
} |
|||
var targetActions = vm.widgetActions[action.actionSourceId]; |
|||
index = getActionIndex(action.id, targetActions); |
|||
if (index > -1) { |
|||
targetActions.splice(index, 1); |
|||
} |
|||
$scope.manageWidgetActionsForm.$setDirty(); |
|||
updateActions(); |
|||
}); |
|||
} |
|||
} |
|||
|
|||
function openWidgetActionDialog($event, action, isAdd) { |
|||
var prevActionId = null; |
|||
if (!isAdd) { |
|||
prevActionId = action.id; |
|||
} |
|||
$mdDialog.show({ |
|||
controller: 'WidgetActionDialogController', |
|||
controllerAs: 'vm', |
|||
templateUrl: widgetActionDialogTemplate, |
|||
parent: angular.element($document[0].body), |
|||
locals: {isAdd: isAdd, actionSources: vm.actionSources, action: angular.copy(action)}, |
|||
skipHide: true, |
|||
fullscreen: true, |
|||
targetEvent: $event |
|||
}).then(function (action) { |
|||
saveAction(action, prevActionId); |
|||
updateActions(); |
|||
}); |
|||
} |
|||
|
|||
function getActionIndex(id, actions) { |
|||
var result = $filter('filter')(actions, {id: id}, true); |
|||
if (result && result.length) { |
|||
return actions.indexOf(result[0]); |
|||
} |
|||
return -1; |
|||
} |
|||
|
|||
function saveAction(action, prevActionId) { |
|||
action.actionSourceName = vm.actionSources[action.actionSourceId].name; |
|||
action.typeName = $translate.instant(types.widgetActionTypes[action.type].name); |
|||
var actionSourceId = action.actionSourceId; |
|||
var widgetAction = angular.copy(action); |
|||
delete widgetAction.actionSourceId; |
|||
delete widgetAction.actionSourceName; |
|||
delete widgetAction.typeName; |
|||
var targetActions = vm.widgetActions[actionSourceId]; |
|||
if (!targetActions) { |
|||
targetActions = []; |
|||
vm.widgetActions[actionSourceId] = targetActions; |
|||
} |
|||
if (prevActionId) { |
|||
var index = getActionIndex(prevActionId, vm.allActions); |
|||
if (index > -1) { |
|||
vm.allActions[index] = action; |
|||
} |
|||
index = getActionIndex(prevActionId, targetActions); |
|||
if (index > -1) { |
|||
targetActions[index] = widgetAction; |
|||
} |
|||
} else { |
|||
vm.allActions.push(action); |
|||
targetActions.push(widgetAction); |
|||
} |
|||
$scope.manageWidgetActionsForm.$setDirty(); |
|||
} |
|||
|
|||
function reloadActions() { |
|||
vm.allActions = []; |
|||
vm.actions = []; |
|||
vm.actionsCount = 0; |
|||
|
|||
for (var actionSourceId in vm.widgetActions) { |
|||
var actionSource = vm.actionSources[actionSourceId]; |
|||
var actionSourceActions = vm.widgetActions[actionSourceId]; |
|||
for (var i=0;i<actionSourceActions.length;i++) { |
|||
var actionSourceAction = actionSourceActions[i]; |
|||
var action = { |
|||
id: actionSourceAction.id, |
|||
actionSourceId: actionSourceId, |
|||
actionSourceName: actionSource.name, |
|||
name: actionSourceAction.name, |
|||
icon: actionSourceAction.icon, |
|||
type: actionSourceAction.type, |
|||
typeName: $translate.instant(types.widgetActionTypes[actionSourceAction.type].name) |
|||
}; |
|||
vm.allActions.push(action); |
|||
} |
|||
} |
|||
|
|||
updateActions (); |
|||
} |
|||
|
|||
function updateActions () { |
|||
var result = $filter('orderBy')(vm.allActions, vm.query.order); |
|||
if (vm.query.search != null) { |
|||
result = $filter('filter')(result, {$: vm.query.search}); |
|||
} |
|||
vm.actionsCount = result.length; |
|||
var startIndex = vm.query.limit * (vm.query.page - 1); |
|||
vm.actions = result.slice(startIndex, startIndex + vm.query.limit); |
|||
} |
|||
} |
|||
@ -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. |
|||
*/ |
|||
.tb-manage-widget-actions { |
|||
table.md-table { |
|||
tbody { |
|||
tr { |
|||
td { |
|||
&.tb-action-cell { |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
white-space: nowrap; |
|||
min-width: 100px; |
|||
max-width: 100px; |
|||
width: 100px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,99 @@ |
|||
<!-- |
|||
|
|||
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 ng-form="manageWidgetActionsForm" class="tb-manage-widget-actions md-whiteframe-z1" layout="column"> |
|||
<md-toolbar class="md-table-toolbar md-default" ng-show="vm.query.search === null"> |
|||
<div class="md-toolbar-tools"> |
|||
<span translate>widget-config.actions</span> |
|||
<span flex></span> |
|||
<md-button class="md-icon-button" ng-click="vm.addAction($event)"> |
|||
<md-icon>add</md-icon> |
|||
<md-tooltip md-direction="top"> |
|||
{{ 'widget-config.add-action' | translate }} |
|||
</md-tooltip> |
|||
</md-button> |
|||
<md-button class="md-icon-button" ng-click="vm.enterFilterMode()"> |
|||
<md-icon>search</md-icon> |
|||
<md-tooltip md-direction="top"> |
|||
{{ 'action.search' | translate }} |
|||
</md-tooltip> |
|||
</md-button> |
|||
</div> |
|||
</md-toolbar> |
|||
<md-toolbar class="md-table-toolbar md-default" ng-show="vm.query.search != null"> |
|||
<div class="md-toolbar-tools"> |
|||
<md-button class="md-icon-button" aria-label="{{ 'action.search' | translate }}"> |
|||
<md-icon aria-label="{{ 'action.search' | translate }}" class="material-icons">search</md-icon> |
|||
<md-tooltip md-direction="top"> |
|||
{{ 'widget-config.search-actions' | translate }} |
|||
</md-tooltip> |
|||
</md-button> |
|||
<md-input-container flex> |
|||
<label> </label> |
|||
<input ng-model="vm.query.search" name="querySearchInput" placeholder="{{ 'widget-config.search-actions' | translate }}"/> |
|||
</md-input-container> |
|||
<md-button class="md-icon-button" aria-label="Close" ng-click="vm.exitFilterMode()"> |
|||
<md-icon aria-label="Close" class="material-icons">close</md-icon> |
|||
<md-tooltip md-direction="top"> |
|||
{{ 'action.close' | translate }} |
|||
</md-tooltip> |
|||
</md-button> |
|||
</div> |
|||
</md-toolbar> |
|||
<md-table-container> |
|||
<table md-table> |
|||
<thead md-head md-order="vm.query.order" md-on-reorder="vm.onReorder"> |
|||
<tr md-row> |
|||
<th md-column md-order-by="actionSourceName"><span translate>widget-config.action-source</span></th> |
|||
<th md-column md-order-by="name"><span translate>widget-config.action-name</span></th> |
|||
<th md-column md-order-by="icon"><span translate>widget-config.action-icon</span></th> |
|||
<th md-column md-order-by="typeName"><span translate>widget-config.action-type</span></th> |
|||
<th md-column><span> </span></th> |
|||
</tr> |
|||
</thead> |
|||
<tbody md-body> |
|||
<tr md-row ng-repeat="action in vm.actions"> |
|||
<td md-cell>{{action.actionSourceName}}</td> |
|||
<td md-cell>{{action.name}}</td> |
|||
<td md-cell> |
|||
<md-icon aria-label="{{ 'widget-config.action-icon' | translate }}" class="material-icons">{{action.icon}}</md-icon> |
|||
</td> |
|||
<td md-cell>{{action.typeName}}</td> |
|||
<td md-cell class="tb-action-cell"> |
|||
<md-button class="md-icon-button" aria-label="{{ 'action.edit' | translate }}" |
|||
ng-click="vm.editAction($event, action)"> |
|||
<md-icon aria-label="{{ 'action.edit' | translate }}" class="material-icons">edit</md-icon> |
|||
<md-tooltip md-direction="top"> |
|||
{{ 'widget-config.edit-action' | translate }} |
|||
</md-tooltip> |
|||
</md-button> |
|||
<md-button class="md-icon-button" aria-label="{{'action.delete' | translate}}" ng-click="vm.deleteAction($event, action)"> |
|||
<md-icon aria-label="Delete" class="material-icons">delete</md-icon> |
|||
<md-tooltip md-direction="top"> |
|||
{{ 'widget-config.delete-action' | translate }} |
|||
</md-tooltip> |
|||
</md-button> |
|||
</td> |
|||
</tr> |
|||
</tbody> |
|||
</table> |
|||
</md-table-container> |
|||
<md-table-pagination md-limit="vm.query.limit" md-limit-options="[10, 15, 20]" |
|||
md-page="vm.query.page" md-total="{{vm.actionsCount}}" |
|||
md-on-paginate="vm.onPaginate" md-page-select> |
|||
</md-table-pagination> |
|||
</div> |
|||
@ -0,0 +1,46 @@ |
|||
/* |
|||
* 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 WidgetActionDialogController($scope, $mdDialog, types, utils, isAdd, actionSources, action) { |
|||
|
|||
var vm = this; |
|||
|
|||
vm.types = types; |
|||
|
|||
vm.isAdd = isAdd; |
|||
vm.actionSources = actionSources; |
|||
|
|||
if (vm.isAdd) { |
|||
vm.action = { |
|||
id: utils.guid() |
|||
}; |
|||
} else { |
|||
vm.action = action; |
|||
} |
|||
|
|||
vm.cancel = cancel; |
|||
vm.save = save; |
|||
|
|||
function cancel() { |
|||
$mdDialog.cancel(); |
|||
} |
|||
|
|||
function save() { |
|||
$scope.theForm.$setPristine(); |
|||
$mdDialog.hide(vm.action); |
|||
} |
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
<!-- |
|||
|
|||
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-dialog class="tb-widget-action-dialog" aria-label="{{'widget-config.action' | translate }}" style="min-width: 600px;"> |
|||
<form name="theForm" ng-submit="vm.save()"> |
|||
<md-toolbar> |
|||
<div class="md-toolbar-tools"> |
|||
<h2>{{ (vm.isAdd ? 'widget-config.add-action' : 'widget-config.edit-action') | translate }}</h2> |
|||
<span flex></span> |
|||
<md-button class="md-icon-button" ng-click="vm.cancel()"> |
|||
<ng-md-icon icon="close" aria-label="{{ 'action.close' | translate }}"></ng-md-icon> |
|||
</md-button> |
|||
</div> |
|||
</md-toolbar> |
|||
<md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> |
|||
<span style="min-height: 5px;" flex="" ng-show="!loading"></span> |
|||
<md-dialog-content> |
|||
<div class="md-dialog-content"> |
|||
<md-content class="md-padding" layout="column"> |
|||
<fieldset ng-disabled="loading"> |
|||
<md-input-container class="md-block"> |
|||
<label translate>widget-config.action-source</label> |
|||
<md-select name="actionSource" required aria-label="{{ 'widget-config.action-source' | translate }}" ng-model="vm.action.actionSourceId"> |
|||
<md-option ng-repeat="(actionSourceId, actionSource) in vm.actionSources" ng-value="actionSourceId"> |
|||
{{actionSource.name}} |
|||
</md-option> |
|||
</md-select> |
|||
<div ng-messages="theForm.actionSource.$error"> |
|||
<div ng-message="required" translate>widget-config.action-source-required</div> |
|||
</div> |
|||
</md-input-container> |
|||
<md-input-container class="md-block"> |
|||
<label translate>widget-config.action-name</label> |
|||
<input name="name" required ng-model="vm.action.name"> |
|||
<div ng-messages="theForm.name.$error"> |
|||
<div ng-message="required" translate>widget-config.action-name-required</div> |
|||
</div> |
|||
</md-input-container> |
|||
<tb-material-icon-select ng-model="vm.action.icon"> |
|||
</tb-material-icon-select> |
|||
<md-input-container class="md-block"> |
|||
<label translate>widget-config.action-type</label> |
|||
<md-select name="actionType" required aria-label="{{ 'widget-config.action-type' | translate }}" ng-model="vm.action.type"> |
|||
<md-option ng-repeat="actionType in vm.types.widgetActionTypes" ng-value="actionType.value"> |
|||
{{ actionType.name | translate }} |
|||
</md-option> |
|||
</md-select> |
|||
<div ng-messages="theForm.actionType.$error"> |
|||
<div ng-message="required" translate>widget-config.action-type-required</div> |
|||
</div> |
|||
</md-input-container> |
|||
</fieldset> |
|||
</md-content> |
|||
</div> |
|||
</md-dialog-content> |
|||
<md-dialog-actions layout="row"> |
|||
<span flex></span> |
|||
<md-button ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" |
|||
class="md-raised md-primary"> |
|||
{{ (vm.isAdd ? 'action.add' : 'action.save') | translate }} |
|||
</md-button> |
|||
<md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;"> |
|||
{{ 'action.cancel' | translate }} |
|||
</md-button> |
|||
</md-dialog-actions> |
|||
</form> |
|||
</md-dialog> |
|||
Loading…
Reference in new issue