Commit 00a40e63ba0cbb974fc9dd4ea034d27da0bba83d

Authored by deaflynx
1 parent b1011f43

Deleted edges hierarchy widget

... ... @@ -22,7 +22,6 @@ import thingsboardTimeseriesTableWidget from '../widget/lib/timeseries-table-wid
22 22 import thingsboardAlarmsTableWidget from '../widget/lib/alarms-table-widget';
23 23 import thingsboardEntitiesTableWidget from '../widget/lib/entities-table-widget';
24 24 import thingsboardEntitiesHierarchyWidget from '../widget/lib/entities-hierarchy-widget';
25   -import thingsboardEdgesHierarchyWidget from '../widget/lib/edges-hierarchy-widget';
26 25 import thingsboardExtensionsTableWidget from '../widget/lib/extensions-table-widget';
27 26 import thingsboardDateRangeNavigatorWidget from '../widget/lib/date-range-navigator/date-range-navigator';
28 27 import thingsboardMultipleInputWidget from '../widget/lib/multiple-input-widget';
... ... @@ -53,7 +52,7 @@ import thingsboardUtils from '../common/utils.service';
53 52
54 53 export default angular.module('thingsboard.api.widget', ['oc.lazyLoad', thingsboardLedLight,
55 54 thingsboardTimeseriesTableWidget, thingsboardAlarmsTableWidget, thingsboardEntitiesTableWidget,
56   - thingsboardEntitiesHierarchyWidget, thingsboardEdgesHierarchyWidget, thingsboardExtensionsTableWidget, thingsboardDateRangeNavigatorWidget,
  55 + thingsboardEntitiesHierarchyWidget, thingsboardExtensionsTableWidget, thingsboardDateRangeNavigatorWidget,
57 56 thingsboardMultipleInputWidget, thingsboardWebCameraInputWidget, thingsboardRpcWidgets, thingsboardTypes,
58 57 thingsboardUtils, thingsboardJsonToString, TripAnimationWidget])
59 58 .factory('widgetService', WidgetService)
... ...
1   -/*
2   - * Copyright © 2016-2020 The Thingsboard Authors
3   - *
4   - * Licensed under the Apache License, Version 2.0 (the "License");
5   - * you may not use this file except in compliance with the License.
6   - * You may obtain a copy of the License at
7   - *
8   - * http://www.apache.org/licenses/LICENSE-2.0
9   - *
10   - * Unless required by applicable law or agreed to in writing, software
11   - * distributed under the License is distributed on an "AS IS" BASIS,
12   - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   - * See the License for the specific language governing permissions and
14   - * limitations under the License.
15   - */
16   -import './edges-hierarchy-widget.scss';
17   -
18   -/* eslint-disable import/no-unresolved, import/default */
19   -
20   -import edgesHierarchyWidgetTemplate from './edges-hierarchy-widget.tpl.html';
21   -
22   -/* eslint-enable import/no-unresolved, import/default */
23   -
24   -export default angular.module('thingsboard.widgets.edgesHierarchyWidget', [])
25   - .directive('tbEdgesHierarchyWidget', EdgesHierarchyWidget)
26   - .name;
27   -/* eslint-disable no-unused-vars */
28   -/*@ngInject*/
29   -function EdgesHierarchyWidget() {
30   - return {
31   - restrict: "E",
32   - scope: true,
33   - bindToController: {
34   - hierarchyId: '=',
35   - ctx: '='
36   - },
37   - controller: EdgesHierarchyWidgetController,
38   - controllerAs: 'vm',
39   - templateUrl: edgesHierarchyWidgetTemplate
40   - };
41   -}
42   -
43   -/*@ngInject*/
44   -function EdgesHierarchyWidgetController($element, $scope, $q, $timeout, toast, types, entityService, entityRelationService,
45   - assetService, deviceService, entityViewService, dashboardService, ruleChainService /*$filter, $mdMedia, $mdPanel, $document, $translate, $timeout, utils, types*/) {
46   - var vm = this;
47   -
48   - vm.showData = true;
49   -
50   - vm.nodeEditCallbacks = {};
51   -
52   - vm.nodeIdCounter = 0;
53   -
54   - vm.nodesMap = {};
55   - vm.pendingUpdateNodeTasks = {};
56   - vm.edgeGroupsNodesMap = {};
57   -
58   - vm.query = {
59   - search: null
60   - };
61   -
62   - vm.searchAction = {
63   - name: 'action.search',
64   - show: true,
65   - onAction: function() {
66   - vm.enterFilterMode();
67   - },
68   - icon: 'search'
69   - };
70   -
71   - vm.onNodesInserted = onNodesInserted;
72   - vm.onNodeSelected = onNodeSelected;
73   - vm.enterFilterMode = enterFilterMode;
74   - vm.exitFilterMode = exitFilterMode;
75   - vm.searchCallback = searchCallback;
76   -
77   - $scope.$watch('vm.ctx', function() {
78   - if (vm.ctx && vm.ctx.defaultSubscription) {
79   - vm.settings = vm.ctx.settings;
80   - vm.widgetConfig = vm.ctx.widgetConfig;
81   - vm.subscription = vm.ctx.defaultSubscription;
82   - vm.datasources = vm.subscription.datasources;
83   - initializeConfig();
84   - updateDatasources();
85   - }
86   - });
87   -
88   - $scope.$watch("vm.query.search", function(newVal, prevVal) {
89   - if (!angular.equals(newVal, prevVal) && vm.query.search != null) {
90   - updateSearchNodes();
91   - }
92   - });
93   -
94   - $scope.$on('edges-hierarchy-data-updated', function(event, hierarchyId) {
95   - if (vm.hierarchyId == hierarchyId) {
96   - if (vm.subscription) {
97   - updateNodeData(vm.subscription.data);
98   - }
99   - }
100   - });
101   -
102   - function initializeConfig() {
103   -
104   - vm.ctx.widgetActions = [ vm.searchAction ];
105   -
106   - var testNodeCtx = {
107   - entity: {
108   - id: {
109   - entityType: 'DEVICE',
110   - id: '123'
111   - },
112   - name: 'TEST DEV1'
113   - },
114   - data: {},
115   - level: 2
116   - };
117   - var parentNodeCtx = angular.copy(testNodeCtx);
118   - parentNodeCtx.level = 1;
119   - testNodeCtx.parentNodeCtx = parentNodeCtx;
120   -
121   - var nodeRelationQueryFunction = loadNodeCtxFunction(vm.settings.nodeRelationQueryFunction, 'nodeCtx', testNodeCtx);
122   - var nodeIconFunction = loadNodeCtxFunction(vm.settings.nodeIconFunction, 'nodeCtx', testNodeCtx);
123   - var nodeTextFunction = loadNodeCtxFunction(vm.settings.nodeTextFunction, 'nodeCtx', testNodeCtx);
124   - var nodeDisabledFunction = loadNodeCtxFunction(vm.settings.nodeDisabledFunction, 'nodeCtx', testNodeCtx);
125   - var nodeOpenedFunction = loadNodeCtxFunction(vm.settings.nodeOpenedFunction, 'nodeCtx', testNodeCtx);
126   - var nodeHasChildrenFunction = loadNodeCtxFunction(vm.settings.nodeHasChildrenFunction, 'nodeCtx', testNodeCtx);
127   -
128   - var testNodeCtx2 = angular.copy(testNodeCtx);
129   - testNodeCtx2.entity.name = 'TEST DEV2';
130   -
131   - var nodesSortFunction = loadNodeCtxFunction(vm.settings.nodesSortFunction, 'nodeCtx1,nodeCtx2', testNodeCtx, testNodeCtx2);
132   -
133   - vm.nodeRelationQueryFunction = nodeRelationQueryFunction || defaultNodeRelationQueryFunction;
134   - vm.nodeIconFunction = nodeIconFunction || defaultNodeIconFunction;
135   - vm.nodeTextFunction = nodeTextFunction || ((nodeCtx) => nodeCtx.entity.name);
136   - vm.nodeDisabledFunction = nodeDisabledFunction || (() => false);
137   - vm.nodeOpenedFunction = nodeOpenedFunction || defaultNodeOpenedFunction;
138   - vm.nodeHasChildrenFunction = nodeHasChildrenFunction || (() => true);
139   - vm.nodesSortFunction = nodesSortFunction || defaultSortFunction;
140   - }
141   -
142   - function loadNodeCtxFunction(functionBody, argNames, ...args) {
143   - var nodeCtxFunction = null;
144   - if (angular.isDefined(functionBody) && functionBody.length) {
145   - try {
146   - nodeCtxFunction = new Function(argNames, functionBody);
147   - var res = nodeCtxFunction.apply(null, args);
148   - if (angular.isUndefined(res)) {
149   - nodeCtxFunction = null;
150   - }
151   - } catch (e) {
152   - nodeCtxFunction = null;
153   - }
154   - }
155   - return nodeCtxFunction;
156   - }
157   -
158   - function enterFilterMode () {
159   - vm.query.search = '';
160   - vm.ctx.hideTitlePanel = true;
161   - $timeout(()=>{
162   - angular.element(vm.ctx.$container).find('.searchInput').focus();
163   - })
164   - }
165   -
166   - function exitFilterMode () {
167   - vm.query.search = null;
168   - updateSearchNodes();
169   - vm.ctx.hideTitlePanel = false;
170   - }
171   -
172   - function searchCallback (searchText, node) {
173   - var theNode = vm.nodesMap[node.id];
174   - if (theNode && theNode.data.searchText) {
175   - return theNode.data.searchText.includes(searchText.toLowerCase());
176   - }
177   - return false;
178   - }
179   -
180   - function updateDatasources() {
181   - vm.loadNodes = loadNodes;
182   - }
183   -
184   - function updateSearchNodes() {
185   - if (vm.query.search != null) {
186   - vm.nodeEditCallbacks.search(vm.query.search);
187   - } else {
188   - vm.nodeEditCallbacks.clearSearch();
189   - }
190   - }
191   -
192   - function onNodesInserted(nodes/*, parent*/) {
193   - if (nodes) {
194   - nodes.forEach((nodeId) => {
195   - var task = vm.pendingUpdateNodeTasks[nodeId];
196   - if (task) {
197   - task();
198   - delete vm.pendingUpdateNodeTasks[nodeId];
199   - }
200   - });
201   - }
202   - }
203   -
204   - function onNodeSelected(node, event) {
205   - var nodeId;
206   - if (!node) {
207   - nodeId = -1;
208   - } else {
209   - nodeId = node.id;
210   - }
211   - if (nodeId !== -1) {
212   - var selectedNode = vm.nodesMap[nodeId];
213   - if (selectedNode) {
214   - var descriptors = vm.ctx.actionsApi.getActionDescriptors('nodeSelected');
215   - if (descriptors.length) {
216   - var entity = selectedNode.data.nodeCtx.entity;
217   - vm.ctx.actionsApi.handleWidgetAction(event, descriptors[0], entity.id, entity.name, { nodeCtx: selectedNode.data.nodeCtx });
218   - }
219   - }
220   - }
221   - }
222   -
223   - function updateNodeData(subscriptionData) {
224   - var affectedNodes = [];
225   - if (subscriptionData) {
226   - for (var i=0;i<subscriptionData.length;i++) {
227   - var datasource = subscriptionData[i].datasource;
228   - if (datasource.nodeId) {
229   - var node = vm.nodesMap[datasource.nodeId];
230   - var key = subscriptionData[i].dataKey.label;
231   - var value = undefined;
232   - if (subscriptionData[i].data && subscriptionData[i].data.length) {
233   - value = subscriptionData[i].data[0][1];
234   - }
235   - if (node.data.nodeCtx.data[key] !== value) {
236   - if (affectedNodes.indexOf(datasource.nodeId) === -1) {
237   - affectedNodes.push(datasource.nodeId);
238   - }
239   - node.data.nodeCtx.data[key] = value;
240   - }
241   - }
242   - }
243   - }
244   - affectedNodes.forEach((nodeId) => {
245   - var node = vm.nodeEditCallbacks.getNode(nodeId);
246   - if (node) {
247   - updateNodeStyle(vm.nodesMap[nodeId]);
248   - } else {
249   - vm.pendingUpdateNodeTasks[nodeId] = () => {
250   - updateNodeStyle(vm.nodesMap[nodeId]);
251   - };
252   - }
253   - });
254   - }
255   -
256   - function updateNodeStyle(node) {
257   - var newText = prepareNodeText(node);
258   - if (!angular.equals(node.text, newText)) {
259   - node.text = newText;
260   - vm.nodeEditCallbacks.updateNode(node.id, node.text);
261   - }
262   - var newDisabled = vm.nodeDisabledFunction(node.data.nodeCtx);
263   - if (!angular.equals(node.state.disabled, newDisabled)) {
264   - node.state.disabled = newDisabled;
265   - if (node.state.disabled) {
266   - vm.nodeEditCallbacks.disableNode(node.id);
267   - } else {
268   - vm.nodeEditCallbacks.enableNode(node.id);
269   - }
270   - }
271   - var newHasChildren = vm.nodeHasChildrenFunction(node.data.nodeCtx);
272   - if (!angular.equals(node.children, newHasChildren)) {
273   - node.children = newHasChildren;
274   - vm.nodeEditCallbacks.setNodeHasChildren(node.id, node.children);
275   - }
276   - }
277   -
278   - function prepareNodeText(node) {
279   - var nodeIcon = prepareNodeIcon(node.data.nodeCtx);
280   - var nodeText = vm.nodeTextFunction(node.data.nodeCtx);
281   - node.data.searchText = nodeText ? nodeText.replace(/<[^>]+>/g, '').toLowerCase() : "";
282   - return nodeIcon + nodeText;
283   - }
284   -
285   - function loadNodes(node, cb) {
286   - if (node.id === '#') {
287   - var tasks = [];
288   - for (var i=0;i<vm.datasources.length;i++) {
289   - var datasource = vm.datasources[i];
290   - tasks.push(datasourceToNode(datasource));
291   - }
292   - $q.all(tasks).then((nodes) => {
293   - cb(prepareNodes(nodes));
294   - updateNodeData(vm.subscription.data);
295   - });
296   - } else {
297   - if (node.data && node.data.nodeCtx.entity && node.data.nodeCtx.entity.id && node.data.nodeCtx.entity.id.entityType !== 'function') {
298   - if (node.data.nodeCtx.entity.id.entityType === types.entityType.edge) {
299   - /* assetService.getEdgeAssets(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then(
300   - (entities) => {
301   - var tasks = [];
302   - for (var i=0;i<entities.data.length;i++) {
303   - var relation = entities.data[i];
304   - var targetId = node.data.nodeCtx.entity.id.entityType === types.entityType.edge ? relation.id : node.data.nodeCtx.entity.id;
305   - tasks.push(entityIdToNode(targetId.entityType, targetId.id, node.data.datasource, node.data.nodeCtx));
306   - }
307   - $q.all(tasks).then((nodes) => {
308   - cb(prepareNodes(nodes));
309   - });
310   - }
311   - );
312   - deviceService.getEdgeDevices(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then(
313   - (entities) => {
314   - var tasks = [];
315   - for (var i=0;i<entities.data.length;i++) {
316   - var relation = entities.data[i];
317   - var targetId = node.data.nodeCtx.entity.id.entityType === types.entityType.edge ? relation.id : node.data.nodeCtx.entity.id;
318   - tasks.push(entityIdToNode(targetId.entityType, targetId.id, node.data.datasource, node.data.nodeCtx));
319   - }
320   - $q.all(tasks).then((nodes) => {
321   - cb(prepareNodes(nodes));
322   - });
323   - }
324   - );
325   - entityViewService.getEdgeEntityViews(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then(
326   - (entities) => {
327   - var tasks = [];
328   - for (var i=0;i<entities.data.length;i++) {
329   - var relation = entities.data[i];
330   - var targetId = node.data.nodeCtx.entity.id.entityType === types.entityType.edge ? relation.id : node.data.nodeCtx.entity.id;
331   - tasks.push(entityIdToNode(targetId.entityType, targetId.id, node.data.datasource, node.data.nodeCtx));
332   - }
333   - $q.all(tasks).then((nodes) => {
334   - cb(prepareNodes(nodes));
335   - });
336   - }
337   - );
338   - dashboardService.getEdgeDashboards(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then(
339   - (entities) => {
340   - var tasks = [];
341   - for (var i=0;i<entities.data.length;i++) {
342   - var relation = entities.data[i];
343   - var targetId = node.data.nodeCtx.entity.id.entityType === types.entityType.edge ? relation.id : node.data.nodeCtx.entity.id;
344   - tasks.push(entityIdToNode(targetId.entityType, targetId.id, node.data.datasource, node.data.nodeCtx));
345   - }
346   - $q.all(tasks).then((nodes) => {
347   - cb(prepareNodes(nodes));
348   - });
349   - }
350   - )
351   - ruleChainService.getEdgeRuleChains(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then(
352   - (entities) => {
353   - var tasks = [];
354   - for (var i=0;i<entities.data.length;i++) {
355   - var relation = entities.data[i];
356   - var targetId = node.data.nodeCtx.entity.id.entityType === types.entityType.edge ? relation.id : node.data.nodeCtx.entity.id;
357   - tasks.push(entityIdToNode(targetId.entityType, targetId.id, node.data.datasource, node.data.nodeCtx));
358   - }
359   - $q.all(tasks).then((nodes) => {
360   - cb(prepareNodes(nodes));
361   - });
362   - }
363   - )
364   - */
365   -
366   - entityIdToNodeEdge("edgeGroup", "001", node.data.datasource, )
367   -
368   - } else {
369   - var relationQuery = prepareNodeRelationQuery(node.data.nodeCtx);
370   - entityRelationService.findByQuery(relationQuery, {ignoreErrors: true, ignoreLoading: true}).then(
371   - (entityRelations) => {
372   - var tasks = [];
373   - for (var i=0;i<entityRelations.length;i++) {
374   - var relation = entityRelations[i];
375   - var targetId = relationQuery.parameters.direction === types.entitySearchDirection.from ? relation.to : relation.from;
376   - tasks.push(entityIdToNode(targetId.entityType, targetId.id, node.data.datasource, node.data.nodeCtx));
377   - }
378   - $q.all(tasks).then((nodes) => {
379   - cb(prepareNodes(nodes));
380   - });
381   - },
382   - (error) => {
383   - var errorText = "Failed to get relations!";
384   - if (error && error.status === 400) {
385   - errorText = "Invalid relations query returned by 'Node relations query function'! Please check widget configuration!";
386   - }
387   - showError(errorText);
388   - }
389   - );
390   - }
391   - } else {
392   - cb([]);
393   - }
394   - }
395   - }
396   -
397   - function showError(errorText) {
398   - var toastParent = angular.element('.tb-edges-hierarchy', $element);
399   - toast.showError(errorText, toastParent, 'bottom left');
400   - }
401   -
402   - function prepareNodes(nodes) {
403   - nodes = nodes.filter((node) => node !== null);
404   - nodes.sort((node1, node2) => vm.nodesSortFunction(node1.data.nodeCtx, node2.data.nodeCtx));
405   - return nodes;
406   - }
407   -
408   - function datasourceToNode(datasource, parentNodeCtx) {
409   - var deferred = $q.defer();
410   - resolveEntity(datasource).then(
411   - (entity) => {
412   - if (entity != null) {
413   - var node = {
414   - id: ++vm.nodeIdCounter
415   - };
416   - vm.nodesMap[node.id] = node;
417   - datasource.nodeId = node.id;
418   - node.icon = false;
419   - var nodeCtx = {
420   - parentNodeCtx: parentNodeCtx,
421   - entity: entity,
422   - data: {}
423   - };
424   - nodeCtx.level = parentNodeCtx ? parentNodeCtx.level + 1 : 1;
425   - node.data = {
426   - datasource: datasource,
427   - nodeCtx: nodeCtx
428   - };
429   - node.state = {
430   - disabled: vm.nodeDisabledFunction(node.data.nodeCtx),
431   - opened: vm.nodeOpenedFunction(node.data.nodeCtx)
432   - };
433   - node.text = prepareNodeText(node);
434   - node.children = vm.nodeHasChildrenFunction(node.data.nodeCtx);
435   - deferred.resolve(node);
436   - } else {
437   - deferred.resolve(null);
438   - }
439   - }
440   - );
441   - return deferred.promise;
442   - }
443   -
444   - function datasourceToNodeEdge(datasource, parentNodeCtx) {
445   - var deferred = $q.defer();
446   - resolveEntity(datasource).then(
447   - (entity) => {
448   - if (entity != null) {
449   - var node = {
450   - id: ++vm.nodeIdCounter
451   - };
452   - vm.nodesMap[node.id] = node;
453   - datasource.nodeId = node.id;
454   - node.icon = false;
455   - var nodeCtx = {
456   - parentNodeCtx: parentNodeCtx,
457   - entity: entity,
458   - data: {}
459   - };
460   - nodeCtx.level = parentNodeCtx ? parentNodeCtx.level + 1 : 1;
461   - node.data = {
462   - datasource: datasource,
463   - nodeCtx: nodeCtx
464   - };
465   - node.state = {
466   - disabled: vm.nodeDisabledFunction(node.data.nodeCtx),
467   - opened: vm.nodeOpenedFunction(node.data.nodeCtx)
468   - };
469   - node.text = prepareNodeText(node);
470   - node.children = vm.nodeHasChildrenFunction(node.data.nodeCtx);
471   - deferred.resolve(node);
472   - } else {
473   - deferred.resolve(null);
474   - }
475   - }
476   - );
477   - return deferred.promise;
478   - }
479   -
480   -
481   - function entityIdToNodeEdge(entityType, entityId, parentDatasource, parentNodeCtx) {
482   - var deferred = $q.defer();
483   - var datasource = {
484   - dataKeys: parentDatasource.dataKeys,
485   - type: types.datasourceType.entity,
486   - entityType: entityType,
487   - entityId: entityId
488   - };
489   - datasourceToNodeEdge(datasource, parentNodeCtx).then(
490   - (node) => {
491   - if (node != null) {
492   - var subscriptionOptions = {
493   - type: types.widgetType.latest.value,
494   - datasources: [datasource],
495   - callbacks: {
496   - onDataUpdated: (subscription) => {
497   - updateNodeData(subscription.data);
498   - }
499   - }
500   - };
501   - vm.ctx.subscriptionApi.createSubscription(subscriptionOptions, true).then(
502   - (/*subscription*/) => {
503   - deferred.resolve(node);
504   - }
505   - );
506   - } else {
507   - deferred.resolve(node);
508   - }
509   - }
510   - );
511   - return deferred.promise;
512   - }
513   -
514   - function entityIdToNode(entityType, entityId, parentDatasource, parentNodeCtx) {
515   - var deferred = $q.defer();
516   - var datasource = {
517   - dataKeys: parentDatasource.dataKeys,
518   - type: types.datasourceType.entity,
519   - entityType: entityType,
520   - entityId: entityId
521   - };
522   - datasourceToNode(datasource, parentNodeCtx).then(
523   - (node) => {
524   - if (node != null) {
525   - var subscriptionOptions = {
526   - type: types.widgetType.latest.value,
527   - datasources: [datasource],
528   - callbacks: {
529   - onDataUpdated: (subscription) => {
530   - updateNodeData(subscription.data);
531   - }
532   - }
533   - };
534   - vm.ctx.subscriptionApi.createSubscription(subscriptionOptions, true).then(
535   - (/*subscription*/) => {
536   - deferred.resolve(node);
537   - }
538   - );
539   - } else {
540   - deferred.resolve(node);
541   - }
542   - }
543   - );
544   - return deferred.promise;
545   - }
546   -
547   - function resolveEntity(datasource) {
548   - var deferred = $q.defer();
549   - if (datasource.type === types.datasourceType.function) {
550   - var entity = {
551   - id: {
552   - entityType: "function"
553   - },
554   - name: datasource.name
555   - }
556   - deferred.resolve(entity);
557   - } else {
558   - entityService.getEntity(datasource.entityType, datasource.entityId, {ignoreLoading: true}).then(
559   - (entity) => {
560   - deferred.resolve(entity);
561   - },
562   - () => {
563   - deferred.resolve(null);
564   - }
565   - );
566   - }
567   - return deferred.promise;
568   - }
569   -
570   -
571   - function prepareNodeRelationQuery(nodeCtx) {
572   - var relationQuery = vm.nodeRelationQueryFunction(nodeCtx);
573   - if (relationQuery && relationQuery === 'default') {
574   - relationQuery = defaultNodeRelationQueryFunction(nodeCtx);
575   - }
576   - return relationQuery;
577   - }
578   -
579   - function defaultNodeRelationQueryFunction(nodeCtx) {
580   - var entity = nodeCtx.entity;
581   - var query = {
582   - parameters: {
583   - rootId: entity.id.id,
584   - rootType: entity.id.entityType,
585   - direction: types.entitySearchDirection.from,
586   - relationTypeGroup: "COMMON",
587   - maxLevel: 1
588   - },
589   - filters: [
590   - {
591   - relationType: "Contains",
592   - entityTypes: []
593   - }
594   - ]
595   - };
596   - return query;
597   - }
598   -
599   - function prepareNodeIcon(nodeCtx) {
600   - var iconInfo = vm.nodeIconFunction(nodeCtx);
601   - if (iconInfo && iconInfo === 'default') {
602   - iconInfo = defaultNodeIconFunction(nodeCtx);
603   - }
604   - if (iconInfo && (iconInfo.iconUrl || iconInfo.materialIcon)) {
605   - if (iconInfo.materialIcon) {
606   - return materialIconHtml(iconInfo.materialIcon);
607   - } else {
608   - return iconUrlHtml(iconInfo.iconUrl);
609   - }
610   - } else {
611   - return "";
612   - }
613   - }
614   -
615   - function materialIconHtml(materialIcon) {
616   - return '<md-icon aria-label="'+materialIcon+'" class="node-icon material-icons" role="img" aria-hidden="false">'+materialIcon+'</md-icon>';
617   - }
618   -
619   - function iconUrlHtml(iconUrl) {
620   - return '<div class="node-icon" style="background-image: url('+iconUrl+');">&nbsp;</div>';
621   - }
622   -
623   - function defaultNodeIconFunction(nodeCtx) {
624   - var materialIcon = 'insert_drive_file';
625   - var entity = nodeCtx.entity;
626   - if (entity && entity.id && entity.id.entityType) {
627   - switch (entity.id.entityType) {
628   - case 'function':
629   - materialIcon = 'functions';
630   - break;
631   - case types.entityType.device:
632   - materialIcon = 'devices_other';
633   - break;
634   - case types.entityType.asset:
635   - materialIcon = 'domain';
636   - break;
637   - case types.entityType.tenant:
638   - materialIcon = 'supervisor_account';
639   - break;
640   - case types.entityType.customer:
641   - materialIcon = 'supervisor_account';
642   - break;
643   - case types.entityType.user:
644   - materialIcon = 'account_circle';
645   - break;
646   - case types.entityType.dashboard:
647   - materialIcon = 'dashboards';
648   - break;
649   - case types.entityType.alarm:
650   - materialIcon = 'notifications_active';
651   - break;
652   - case types.entityType.entityView:
653   - materialIcon = 'view_quilt';
654   - break;
655   - case types.entityType.edge:
656   - materialIcon = 'router';
657   - break;
658   - case types.entityType.rulechain:
659   - materialIcon = 'settings_ethernet';
660   - break;
661   - }
662   - }
663   - return {
664   - materialIcon: materialIcon
665   - };
666   - }
667   -
668   - function defaultNodeOpenedFunction(nodeCtx) {
669   - return nodeCtx.level <= 4;
670   - }
671   -
672   - function defaultSortFunction(nodeCtx1, nodeCtx2) {
673   - var result = nodeCtx1.entity.id.entityType.localeCompare(nodeCtx2.entity.id.entityType);
674   - if (result === 0) {
675   - result = nodeCtx1.entity.name.localeCompare(nodeCtx2.entity.name);
676   - }
677   - return result;
678   - }
679   -}
1   -/**
2   - * Copyright © 2016-2020 The Thingsboard Authors
3   - *
4   - * Licensed under the Apache License, Version 2.0 (the "License");
5   - * you may not use this file except in compliance with the License.
6   - * You may obtain a copy of the License at
7   - *
8   - * http://www.apache.org/licenses/LICENSE-2.0
9   - *
10   - * Unless required by applicable law or agreed to in writing, software
11   - * distributed under the License is distributed on an "AS IS" BASIS,
12   - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   - * See the License for the specific language governing permissions and
14   - * limitations under the License.
15   - */
16   -.tb-has-timewindow {
17   - .tb-edges-hierarchy {
18   - md-toolbar {
19   - min-height: 60px;
20   - max-height: 60px;
21   - }
22   - }
23   -}
24   -
25   -.tb-edges-hierarchy {
26   - md-toolbar {
27   - min-height: 39px;
28   - max-height: 39px;
29   - }
30   -
31   - .tb-entities-nav-tree-panel {
32   - overflow-x: auto;
33   - overflow-y: auto;
34   -
35   - .tb-nav-tree-container {
36   - &.jstree-proton {
37   - .jstree-anchor {
38   - div.node-icon {
39   - display: inline-block;
40   - width: 22px;
41   - height: 22px;
42   - margin-right: 2px;
43   - margin-bottom: 2px;
44   - background-color: transparent;
45   - background-repeat: no-repeat;
46   - background-attachment: scroll;
47   - background-position: center center;
48   - background-size: 18px 18px;
49   - }
50   -
51   - md-icon.node-icon {
52   - width: 22px;
53   - min-width: 22px;
54   - height: 22px;
55   - min-height: 22px;
56   - margin-right: 2px;
57   - margin-bottom: 2px;
58   - color: inherit;
59   -
60   - &.material-icons { /* stylelint-disable-line selector-max-class */
61   - font-size: 18px;
62   - line-height: 22px;
63   - text-align: center;
64   - }
65   - }
66   -
67   - &.jstree-hovered:not(.jstree-clicked),
68   - &.jstree-disabled {
69   - div.node-icon { /* stylelint-disable-line selector-max-class */
70   - opacity: .5;
71   - }
72   - }
73   - }
74   - }
75   - }
76   - }
77   -}
78   -
79   -@media (max-width: 768px) {
80   - .tb-edges-hierarchy {
81   - .tb-entities-nav-tree-panel {
82   - .tb-nav-tree-container {
83   - &.jstree-proton-responsive {
84   - .jstree-anchor {
85   - div.node-icon {
86   - width: 40px;
87   - height: 40px;
88   - margin: 0;
89   - background-size: 24px 24px;
90   - }
91   -
92   - md-icon.node-icon {
93   - width: 40px;
94   - min-width: 40px;
95   - height: 40px;
96   - min-height: 40px;
97   - margin: 0;
98   -
99   - &.material-icons { /* stylelint-disable-line selector-max-class */
100   - font-size: 24px;
101   - line-height: 40px;
102   - }
103   - }
104   - }
105   - }
106   - }
107   - }
108   - }
109   -}
1   -<!--
2   -
3   - Copyright © 2016-2020 The Thingsboard Authors
4   -
5   - Licensed under the Apache License, Version 2.0 (the "License");
6   - you may not use this file except in compliance with the License.
7   - You may obtain a copy of the License at
8   -
9   - http://www.apache.org/licenses/LICENSE-2.0
10   -
11   - Unless required by applicable law or agreed to in writing, software
12   - distributed under the License is distributed on an "AS IS" BASIS,
13   - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   - See the License for the specific language governing permissions and
15   - limitations under the License.
16   -
17   --->
18   -<div class="tb-absolute-fill tb-edges-hierarchy" layout="column">
19   - <div ng-show="vm.showData" flex class="tb-absolute-fill" layout="column">
20   - <md-toolbar class="md-table-toolbar md-default" ng-show="vm.query.search != null">
21   - <div class="md-toolbar-tools">
22   - <md-button class="md-icon-button" aria-label="{{ 'action.search' | translate }}">
23   - <md-icon aria-label="{{ 'action.search' | translate }}" class="material-icons">search</md-icon>
24   - <md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}">
25   - {{'entity.search' | translate}}
26   - </md-tooltip>
27   - </md-button>
28   - <md-input-container flex>
29   - <label>&nbsp;</label>
30   - <input ng-model="vm.query.search" class="searchInput" placeholder="{{'entity.search' | translate}}"/>
31   - </md-input-container>
32   - <md-button class="md-icon-button" aria-label="Close" ng-click="vm.exitFilterMode()">
33   - <md-icon aria-label="Close" class="material-icons">close</md-icon>
34   - <md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}">
35   - {{ 'action.close' | translate }}
36   - </md-tooltip>
37   - </md-button>
38   - </div>
39   - </md-toolbar>
40   - <div flex class="tb-entities-nav-tree-panel">
41   - <tb-nav-tree
42   - load-nodes="vm.loadNodes"
43   - on-node-selected="vm.onNodeSelected(node, event)"
44   - on-nodes-inserted="vm.onNodesInserted(nodes, parent)"
45   - edit-callbacks="vm.nodeEditCallbacks"
46   - enable-search="true"
47   - search-callback="vm.searchCallback(searchText, node)"
48   - ></tb-nav-tree>
49   - </div>
50   - </div>
51   -</div>