@c8y/ng1-modules 1017.0.134 → 1017.0.136
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/ui/properties/computedProperties.provider.js +1 -1
- package/core/ui/properties/computedPropertyConfigModal.html +40 -35
- package/core/ui/properties/lastMeasurementConfig.html +8 -7
- package/core/ui/properties/schemaPropertySelector.html +29 -22
- package/dataPointExplorer/views/widgetConfig.html +139 -81
- package/dataPointTable/views/widgetConfig.html +111 -54
- package/kpi/views/listConfig.html +60 -25
- package/package.json +1 -1
- package/scada/views/componentConfig.html +62 -32
- package/scada/views/mapping.html +112 -101
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";!function(){function t(c){t.$inject=["$injector","c8yModal"];var i,a=new WeakMap,f={},u={},p={};function s(t,e,r){var o=f[t],n=_.isArray(e)?e:e.$inject;void 0===n&&(n=c.annotate(e));var i=_.includes(n,"config");if(o)throw new Error('Computed property "'.concat(t,'" already registered'));if(i){if(p[t])throw new Error('Computed property factory "'.concat(t,'" already registered'));p[t]={config:r,property:e}}f[t]={config:r,property:e}}function e(o,t){var n=p[t];if(!n)throw new Error('Computed property factory "'.concat(t,'" is not registered'));return{create:function(t,e){if(u[t])throw new Error('Computed property "'.concat(t,'" already registered'));return u[t]={getter:o.invoke(n.property,void 0,{config:e}),config:n.config},!0},attach:function(t,e,r){d(t,e,{getter:o.invoke(n.property,void 0,{config:r})})}}}function r(r){_.forEach(f,function(e,t){u[t]||(u[t]={_lazy:!0,getter:function(){var t=this._getter;return t||(this._getter=r.invoke(e.property,void 0,{config:!1}),t=this._getter),t},config:e.config})})}function g(t,e){if(_.isArray(e))return function(e,t){var c=_.keys(p),a=_.union(_.keys(u),c);_(t).filter("computed").map(function(t){var e=_.last(t.id.split("!!")),r=(t.config||{})._id||String(Math.random()).substr(2),o=t.config||{},n=_.includes(a,e),i=e+(_.includes(c,e)?"_".concat(r):"");return(t.config=o)._id=r,n&&(t.keyPath=[i]),{key:e,keyPath:i,isFactory:_.includes(c,e),config:o,exists:n}}).filter("exists").forEach(function(t){t.isFactory?i(t.key).attach(e,t.keyPath,t.config):g(e,t.key)})}(t,e),t;var r=e;if(r){var o=u[r];if(!o)throw new Error('Computed property "'.concat(r,'" is not registered.'));d(t,r,o)}else!function(i){_.forEach(u,function(e,r){var t=function(t){return t&&d(i,r,e)},o=(e.config||{}).attachIf,n=(o=o||_.constant(!0))(i);_.isFunction(_.get(n,"then"))?n.then(t):t(n)})}(t);return t}function d(t,e,r){if(_.isObjectLike(t)){if(!_.has(t,e)){var o=r._lazy?r.getter():r.getter,n=o.detach||_.noop,i=a.get(t);i||(i=[],a.set(t,i)),i.push(function(t){n(t),delete t[e]}),Object.defineProperty(t,e,{enumerable:!1,configurable:!0,get:function(){return o(this)}})}}else console.warn("[Computed properties] Managed object is not an object")}function l(e){var r=this,t=a.get(e);_.forEach(t,function(t){try{t.call(r,e)}catch(t){console.error("Error detaching computed property",t)}}),a.delete(e)}function t(t,n){var o=_.partial(r,t);return{register:function(t,e,r){s(t,e,r),o()},attach:g,detach:l,factory:i=_.partial(e,t),init:o,edit:function(t){var e=_.last(t.id.split("!!")),r=p[e];if(!r)throw new Error("".concat(e," is not a factory computed property."));var o=_.get(r,"config.configTemplateUrl");return n({templateUrl:":::PLUGIN_PATH:::/ui/properties/computedPropertyConfigModal.html",controller:"ComputedPropertyConfigCtrl",size:"
|
|
1
|
+
"use strict";!function(){function t(c){t.$inject=["$injector","c8yModal"];var i,a=new WeakMap,f={},u={},p={};function s(t,e,r){var o=f[t],n=_.isArray(e)?e:e.$inject;void 0===n&&(n=c.annotate(e));var i=_.includes(n,"config");if(o)throw new Error('Computed property "'.concat(t,'" already registered'));if(i){if(p[t])throw new Error('Computed property factory "'.concat(t,'" already registered'));p[t]={config:r,property:e}}f[t]={config:r,property:e}}function e(o,t){var n=p[t];if(!n)throw new Error('Computed property factory "'.concat(t,'" is not registered'));return{create:function(t,e){if(u[t])throw new Error('Computed property "'.concat(t,'" already registered'));return u[t]={getter:o.invoke(n.property,void 0,{config:e}),config:n.config},!0},attach:function(t,e,r){d(t,e,{getter:o.invoke(n.property,void 0,{config:r})})}}}function r(r){_.forEach(f,function(e,t){u[t]||(u[t]={_lazy:!0,getter:function(){var t=this._getter;return t||(this._getter=r.invoke(e.property,void 0,{config:!1}),t=this._getter),t},config:e.config})})}function g(t,e){if(_.isArray(e))return function(e,t){var c=_.keys(p),a=_.union(_.keys(u),c);_(t).filter("computed").map(function(t){var e=_.last(t.id.split("!!")),r=(t.config||{})._id||String(Math.random()).substr(2),o=t.config||{},n=_.includes(a,e),i=e+(_.includes(c,e)?"_".concat(r):"");return(t.config=o)._id=r,n&&(t.keyPath=[i]),{key:e,keyPath:i,isFactory:_.includes(c,e),config:o,exists:n}}).filter("exists").forEach(function(t){t.isFactory?i(t.key).attach(e,t.keyPath,t.config):g(e,t.key)})}(t,e),t;var r=e;if(r){var o=u[r];if(!o)throw new Error('Computed property "'.concat(r,'" is not registered.'));d(t,r,o)}else!function(i){_.forEach(u,function(e,r){var t=function(t){return t&&d(i,r,e)},o=(e.config||{}).attachIf,n=(o=o||_.constant(!0))(i);_.isFunction(_.get(n,"then"))?n.then(t):t(n)})}(t);return t}function d(t,e,r){if(_.isObjectLike(t)){if(!_.has(t,e)){var o=r._lazy?r.getter():r.getter,n=o.detach||_.noop,i=a.get(t);i||(i=[],a.set(t,i)),i.push(function(t){n(t),delete t[e]}),Object.defineProperty(t,e,{enumerable:!1,configurable:!0,get:function(){return o(this)}})}}else console.warn("[Computed properties] Managed object is not an object")}function l(e){var r=this,t=a.get(e);_.forEach(t,function(t){try{t.call(r,e)}catch(t){console.error("Error detaching computed property",t)}}),a.delete(e)}function t(t,n){var o=_.partial(r,t);return{register:function(t,e,r){s(t,e,r),o()},attach:g,detach:l,factory:i=_.partial(e,t),init:o,edit:function(t){var e=_.last(t.id.split("!!")),r=p[e];if(!r)throw new Error("".concat(e," is not a factory computed property."));var o=_.get(r,"config.configTemplateUrl");return n({templateUrl:":::PLUGIN_PATH:::/ui/properties/computedPropertyConfigModal.html",controller:"ComputedPropertyConfigCtrl",size:"sm",resolve:{options:function(){return{configTemplateUrl:o,computedProperty:e,configSchema:_.isObjectLike(t.configSchema)&&t.configSchema,config:angular.copy(t.config)||{},prop:t}}}})},listFactories:function(){return _.map(p,function(t,e){return{id:e,config:_.clone(t.config)}})}}}return{register:s,$get:t}}function e(t){t.init()}e.$inject=["c8yComputedProperties"],t.$inject=["$injector"],angular.module("c8y.ui").provider("c8yComputedProperties",t).run(e)}();
|
|
@@ -1,38 +1,43 @@
|
|
|
1
|
-
<div class="modal
|
|
2
|
-
<
|
|
3
|
-
</div>
|
|
4
|
-
<div class="modal-body" id="modal-body">
|
|
5
|
-
<h4>
|
|
1
|
+
<div class="c8y-viewport-modal">
|
|
2
|
+
<div class="modal-header dialog-header">
|
|
6
3
|
<i c8y-icon="bolt"></i>
|
|
7
|
-
|
|
8
|
-
</
|
|
4
|
+
<div id="modal-title-property" class="h4" translate>Computed property configuration</div>
|
|
5
|
+
</div>
|
|
6
|
+
<div class="modal-inner-scroll">
|
|
7
|
+
<p class="text-center bg-level-0 text-medium text-16 p-t-16 p-b-16 sticky-top separator-bottom"
|
|
8
|
+
style="z-index: 110;">
|
|
9
|
+
{{ computedProperty}}
|
|
10
|
+
</p>
|
|
11
|
+
<div class="modal-body no-card-context p-t-16" id="modal-body-property">
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
</div>
|
|
20
|
-
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
13
|
+
<form name="configForm" novalidate>
|
|
14
|
+
<div ng-if="configTemplateUrl" ng-include="configTemplateUrl"></div>
|
|
15
|
+
<c8y-schema-form
|
|
16
|
+
ng-if="configSchema"
|
|
17
|
+
schema="configSchema"
|
|
18
|
+
form="['*']"
|
|
19
|
+
model="config"
|
|
20
|
+
></c8y-schema-form>
|
|
21
|
+
</form>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="modal-footer">
|
|
25
|
+
<button
|
|
26
|
+
class="btn btn-default"
|
|
27
|
+
type="button"
|
|
28
|
+
title="{{ 'Cancel' | translate }}"
|
|
29
|
+
ng-click="$dismiss()"
|
|
30
|
+
>
|
|
31
|
+
{{ 'Cancel' | translate }}
|
|
32
|
+
</button>
|
|
33
|
+
<button
|
|
34
|
+
class="btn btn-primary"
|
|
35
|
+
type="button"
|
|
36
|
+
title="{{ 'Save' | translate }}"
|
|
37
|
+
ng-click="$close(config)"
|
|
38
|
+
ng-disabled="configForm.$invalid"
|
|
39
|
+
>
|
|
40
|
+
{{ 'Save' | translate }}
|
|
41
|
+
</button>
|
|
42
|
+
</div>
|
|
38
43
|
</div>
|
|
@@ -22,13 +22,14 @@
|
|
|
22
22
|
|
|
23
23
|
<div class="form-group">
|
|
24
24
|
<label for="returnTypeField" translate>Return type</label>
|
|
25
|
-
<select
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
<div class="c8y-select-wrapper">
|
|
26
|
+
<select
|
|
27
|
+
id="returnTypeField"
|
|
28
|
+
class="form-control"
|
|
29
|
+
ng-model="config.resultType"
|
|
30
|
+
ng-options="resultType.value as (resultType.label | translate) for resultType in resultTypes.values()"
|
|
31
|
+
></select>
|
|
32
|
+
</div>
|
|
32
33
|
</div>
|
|
33
34
|
</ng-form>
|
|
34
35
|
</div>
|
|
@@ -6,18 +6,18 @@
|
|
|
6
6
|
<div class="form-group m-16">
|
|
7
7
|
<div class="input-group input-group-search">
|
|
8
8
|
<input
|
|
9
|
-
type="search"
|
|
10
9
|
class="form-control"
|
|
11
|
-
|
|
10
|
+
type="search"
|
|
12
11
|
ng-model="search"
|
|
12
|
+
placeholder="{{ 'Filter properties' | translate }}"
|
|
13
13
|
/>
|
|
14
14
|
<span class="input-group-addon">
|
|
15
15
|
<i c8y-icon="search" ng-show="search.length === 0 || !search"></i>
|
|
16
16
|
<i
|
|
17
17
|
c8y-icon="times"
|
|
18
18
|
class="text-muted"
|
|
19
|
-
ng-show="search.length > 0"
|
|
20
19
|
ng-click="search = ''"
|
|
20
|
+
ng-show="search.length > 0"
|
|
21
21
|
></i>
|
|
22
22
|
</span>
|
|
23
23
|
</div>
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
|
|
40
40
|
<div
|
|
41
41
|
class="modal-inner-scroll container-fluid"
|
|
42
|
-
id="modal-body"
|
|
43
42
|
style="max-height: calc(100vh - 340px)"
|
|
43
|
+
id="modal-body"
|
|
44
44
|
>
|
|
45
45
|
<div class="row">
|
|
46
46
|
<div
|
|
@@ -49,21 +49,24 @@
|
|
|
49
49
|
>
|
|
50
50
|
<div class="col-xs-2">
|
|
51
51
|
<span ng-switch="selectSingle">
|
|
52
|
-
<label ng-switch-when="true"
|
|
52
|
+
<label class="c8y-radio" ng-switch-when="true">
|
|
53
53
|
<input
|
|
54
|
-
name="property"
|
|
55
54
|
type="radio"
|
|
55
|
+
aria-label="{{ property.label }}"
|
|
56
|
+
id="radio-{{ property.keyPath.join('.') }}"
|
|
57
|
+
name="property"
|
|
56
58
|
ng-model="properties.selected"
|
|
57
59
|
ng-value="property"
|
|
58
60
|
/>
|
|
59
61
|
<span></span>
|
|
60
62
|
</label>
|
|
61
|
-
<label
|
|
63
|
+
<label class="c8y-checkbox" ng-switch-default>
|
|
62
64
|
<input
|
|
63
65
|
type="checkbox"
|
|
64
|
-
|
|
66
|
+
aria-label="{{ property.label }}"
|
|
67
|
+
id="checkbox-{{ property.keyPath.join('.') }}"
|
|
65
68
|
ng-change="onSelectProperty(property)"
|
|
66
|
-
|
|
69
|
+
ng-model="property.__active"
|
|
67
70
|
/>
|
|
68
71
|
<span></span>
|
|
69
72
|
</label>
|
|
@@ -71,21 +74,24 @@
|
|
|
71
74
|
</div>
|
|
72
75
|
<div
|
|
73
76
|
class="col-xs-5 text-truncate"
|
|
74
|
-
title="{{ property.label | translate }}"
|
|
75
77
|
ng-class="{ strong: isComplexProperty(property) }"
|
|
78
|
+
title="{{ property.label | translate }}"
|
|
76
79
|
>
|
|
77
80
|
<span>
|
|
78
81
|
<button
|
|
79
82
|
aria-label="{{ 'Complex property' | translate }}"
|
|
80
83
|
class="btn btn-dot"
|
|
81
84
|
type="button"
|
|
82
|
-
ng-if="isComplexProperty(property) && isAtLeastOneSubpropertyListed(property)"
|
|
83
85
|
uib-tooltip="{{
|
|
84
86
|
'Complex property. Subproperties are listed below.`tooltip`' | translate
|
|
85
87
|
}}"
|
|
86
|
-
tooltip-placement="auto"
|
|
87
|
-
tooltip-popup-delay="500"
|
|
88
88
|
tooltip-append-to-body="true"
|
|
89
|
+
tooltip-placement="right"
|
|
90
|
+
tooltip-popup-delay="500"
|
|
91
|
+
aria-label="{{
|
|
92
|
+
'Complex property. Subproperties are listed below.`tooltip`' | translate
|
|
93
|
+
}}"
|
|
94
|
+
ng-if="isComplexProperty(property) && isAtLeastOneSubpropertyListed(property)"
|
|
89
95
|
>
|
|
90
96
|
<i c8y-icon="tags" class="text-info"></i>
|
|
91
97
|
</button>
|
|
@@ -93,27 +99,29 @@
|
|
|
93
99
|
aria-label="{{ 'Complex property' | translate }}"
|
|
94
100
|
class="btn btn-dot"
|
|
95
101
|
type="button"
|
|
96
|
-
ng-if="isComplexProperty(property) && !isAtLeastOneSubpropertyListed(property)"
|
|
97
102
|
uib-tooltip="{{ 'Complex property.`tooltip`' | translate }}"
|
|
98
|
-
tooltip-placement="auto"
|
|
99
103
|
tooltip-append-to-body="true"
|
|
104
|
+
tooltip-placement="right"
|
|
105
|
+
aria-label="{{ 'Complex property.`tooltip`' | translate }}"
|
|
106
|
+
ng-if="isComplexProperty(property) && !isAtLeastOneSubpropertyListed(property)"
|
|
100
107
|
>
|
|
101
|
-
<i class="text-info"
|
|
108
|
+
<i c8y-icon="tag" class="text-info"></i>
|
|
102
109
|
</button>
|
|
103
110
|
<button
|
|
104
111
|
aria-label="{{ 'Computed property' | translate }}"
|
|
105
112
|
class="btn btn-dot"
|
|
106
113
|
type="button"
|
|
107
|
-
ng-show="property.computed"
|
|
108
114
|
uib-tooltip="{{ 'Computed property.`tooltip`' | translate }}"
|
|
115
|
+
tooltip-append-to-body="true"
|
|
109
116
|
tooltip-placement="right"
|
|
110
117
|
tooltip-popup-delay="500"
|
|
111
|
-
|
|
118
|
+
aria-label="{{ 'Computed property.`tooltip`' | translate }}"
|
|
119
|
+
ng-show="property.computed"
|
|
112
120
|
>
|
|
113
|
-
<i class="text-primary-light"
|
|
121
|
+
<i c8y-icon="bolt" class="text-primary-light"></i>
|
|
114
122
|
</button>
|
|
115
123
|
</span>
|
|
116
|
-
{{ property.label | translate
|
|
124
|
+
{{ property.label | translate }}
|
|
117
125
|
</div>
|
|
118
126
|
<div class="col-xs-5 text-truncate" title="{{ property.keyPath.join('.') }}">
|
|
119
127
|
{{ property.keyPath.join('.') }}
|
|
@@ -133,10 +141,9 @@
|
|
|
133
141
|
</button>
|
|
134
142
|
<button
|
|
135
143
|
title="{{ 'Select' | translate }}"
|
|
136
|
-
|
|
144
|
+
ng-click="close()"
|
|
137
145
|
ng-disabled="selectIsDisabled()"
|
|
138
146
|
class="btn btn-primary"
|
|
139
|
-
ng-click="close()"
|
|
140
147
|
>
|
|
141
148
|
{{ 'Select' | translate }}
|
|
142
149
|
</button>
|
|
@@ -1,85 +1,143 @@
|
|
|
1
|
-
<div
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
1
|
+
<div
|
|
2
|
+
ng-controller="DataPointWidgetConfigCtrl"
|
|
3
|
+
ng-init="disableLocalStorage = true"
|
|
4
|
+
class="row no-card-context d-flex"
|
|
5
|
+
style="height: calc(100vh - 422px);"
|
|
6
|
+
>
|
|
7
|
+
<div class="col-md-5 bg-level-1 a-s-stretch inner-scroll">
|
|
8
|
+
<div class="p-l-24 bg-inherit p-t-8">
|
|
9
|
+
<div class="form-group m-b-0 p-b-16 separator-bottom">
|
|
10
|
+
<label for="dateSelection">
|
|
11
|
+
{{ 'Date selection' | translate }}
|
|
12
|
+
<button
|
|
13
|
+
type="button"
|
|
14
|
+
class="btn-help btn-help--sm"
|
|
15
|
+
aria-label="{{ 'Help' | translate }}"
|
|
16
|
+
uib-popover-html="dateSelectionHelpPopoverText | translate"
|
|
17
|
+
popover-placement="right"
|
|
18
|
+
popover-trigger="'focus'"
|
|
19
|
+
popover-append-to-body="true"
|
|
20
|
+
></button>
|
|
21
|
+
</label>
|
|
22
|
+
<div class="c8y-select-wrapper">
|
|
23
|
+
<select
|
|
24
|
+
id="dateSelection"
|
|
25
|
+
class="form-control"
|
|
26
|
+
title="{{ 'Date selection' | translate }}"
|
|
27
|
+
aria-label="{{ 'Date selection' | translate }}"
|
|
28
|
+
ng-model="dateSelection"
|
|
29
|
+
>
|
|
30
|
+
<option
|
|
31
|
+
title="{{ 'Widget configuration' | translate }}"
|
|
32
|
+
value="{{ 'config' }}"
|
|
33
|
+
>
|
|
34
|
+
{{ 'Widget configuration' | translate }}
|
|
35
|
+
</option>
|
|
36
|
+
<option
|
|
37
|
+
title="{{ 'Widget and widget configuration' | translate }}"
|
|
38
|
+
value="{{ 'view_and_config' }}"
|
|
39
|
+
>
|
|
40
|
+
{{ 'Widget and widget configuration' | translate }}
|
|
41
|
+
</option>
|
|
42
|
+
<option
|
|
43
|
+
title="{{ 'Dashboard time range' | translate }}"
|
|
44
|
+
value="{{ 'dashboard_context' }}"
|
|
45
|
+
>
|
|
46
|
+
{{ 'Dashboard time range' | translate }}
|
|
47
|
+
</option>
|
|
48
|
+
</select>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<c8y-data-point-list
|
|
53
|
+
datapoints="data.datapoints"
|
|
54
|
+
allow-adding-data-points-from-context-mo-only="dashboard.deviceType && dashboard.deviceTypeValue"
|
|
55
|
+
dont-save="true"
|
|
56
|
+
no-target
|
|
57
|
+
no-yellow-range
|
|
58
|
+
no-red-range
|
|
59
|
+
class="bg-inherit separator-bottom"
|
|
60
|
+
></c8y-data-point-list>
|
|
61
|
+
<c8y-alarms-events-timelines-config
|
|
62
|
+
configs="data.alarmsEventsConfigs"
|
|
63
|
+
allow-alarms-events-from-context-mo-only="dashboard.deviceType && dashboard.deviceTypeValue"
|
|
64
|
+
class="d-block bg-inherit separator-top"
|
|
65
|
+
style="padding-top: 1px;"
|
|
66
|
+
></c8y-alarms-events-timelines-config>
|
|
37
67
|
</div>
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
<div class="col-md-7 sticky-top">
|
|
71
|
+
<div class="p-r-24 p-t-8">
|
|
72
|
+
<div
|
|
73
|
+
class="data-point-explorer d-flex d-col"
|
|
74
|
+
ng-controller="c8yDataPointExplorerCtrl"
|
|
75
|
+
>
|
|
76
|
+
<div class="m-b-4 m-t-4 d-flex j-c-end gap-8">
|
|
77
|
+
<c8y-realtime-button
|
|
78
|
+
ng-show="!data.widgetInstanceGlobalTimeContext"
|
|
79
|
+
class="top-right-control"
|
|
80
|
+
channel="{{ channel }}"
|
|
81
|
+
state="data.realtime"
|
|
82
|
+
on-data="onData($data)"
|
|
83
|
+
></c8y-realtime-button>
|
|
84
|
+
<c8y-realtime-button
|
|
85
|
+
ng-show="false"
|
|
86
|
+
channel="{{ alarmsChannel }}"
|
|
87
|
+
state="data.realtime"
|
|
88
|
+
on-data="onAlarm($data)"
|
|
89
|
+
on-data-update="onAlarm($data)"
|
|
90
|
+
></c8y-realtime-button>
|
|
91
|
+
<c8y-realtime-button
|
|
92
|
+
ng-show="false"
|
|
93
|
+
channel="{{ eventsChannel }}"
|
|
94
|
+
state="data.realtime"
|
|
95
|
+
on-data="onEvent($data)"
|
|
96
|
+
></c8y-realtime-button>
|
|
97
|
+
<c8y-aggregation
|
|
98
|
+
class="top-right-control"
|
|
99
|
+
date-from="data.dateFrom"
|
|
100
|
+
date-to="data.dateTo"
|
|
101
|
+
aggregation="data.aggregation"
|
|
102
|
+
realtime="data.realtime"
|
|
103
|
+
auto="true"
|
|
104
|
+
></c8y-aggregation>
|
|
105
|
+
<c8y-interval
|
|
106
|
+
ng-show="!data.widgetInstanceGlobalTimeContext"
|
|
107
|
+
class="top-right-control"
|
|
108
|
+
date-from="data.dateFrom"
|
|
109
|
+
date-to="data.dateTo"
|
|
110
|
+
interval="data.interval"
|
|
111
|
+
></c8y-interval>
|
|
112
|
+
</div>
|
|
113
|
+
<div
|
|
114
|
+
class="c8yGraphFill"
|
|
115
|
+
style="height: calc(100vh - 520px);"
|
|
116
|
+
>
|
|
117
|
+
<c8y-chart
|
|
118
|
+
datapoints="data.graphDataPoints"
|
|
119
|
+
date-from="data.dateFrom"
|
|
120
|
+
date-to="data.dateTo"
|
|
121
|
+
realtime="data.realtime"
|
|
122
|
+
aggregation="data.aggregation"
|
|
123
|
+
show-time="!data.widgetInstanceGlobalTimeContext"
|
|
124
|
+
on-data="(onData)"
|
|
125
|
+
on-update-dates="onUpdateDates($dateFrom, $dateTo)"
|
|
126
|
+
on-update-displayed-dates="onUpdateDisplayedDates($dateFrom, $dateTo)"
|
|
127
|
+
on-box-changed="onBoxChanged(box)"
|
|
128
|
+
></c8y-chart>
|
|
129
|
+
</div>
|
|
130
|
+
<c8y-alarms-events-timelines-chart
|
|
131
|
+
alarms-events-configs="data.graphAlarmsEventsConfigs"
|
|
132
|
+
date-from="data.displayedDateFrom"
|
|
133
|
+
date-to="data.displayedDateTo"
|
|
134
|
+
on-update-dates="onUpdateDates($dateFrom, $dateTo)"
|
|
135
|
+
realtime="data.realtime"
|
|
136
|
+
on-realtime-alarm-fn="onRealtimeAlarmFn(onRealtimeAlarm)"
|
|
137
|
+
on-realtime-event-fn="onRealtimeEventFn(onRealtimeEvent)"
|
|
138
|
+
chart-box="chartBox"
|
|
139
|
+
></c8y-alarms-events-timelines-chart>
|
|
140
|
+
</div>
|
|
51
141
|
</div>
|
|
52
|
-
<c8y-alarms-events-timelines-chart
|
|
53
|
-
alarms-events-configs="data.graphAlarmsEventsConfigs"
|
|
54
|
-
date-from="data.displayedDateFrom"
|
|
55
|
-
date-to="data.displayedDateTo"
|
|
56
|
-
on-update-dates="onUpdateDates($dateFrom, $dateTo)"
|
|
57
|
-
realtime="data.realtime"
|
|
58
|
-
on-realtime-alarm-fn="onRealtimeAlarmFn(onRealtimeAlarm)"
|
|
59
|
-
on-realtime-event-fn="onRealtimeEventFn(onRealtimeEvent)"
|
|
60
|
-
chart-box="chartBox"
|
|
61
|
-
></c8y-alarms-events-timelines-chart>
|
|
62
|
-
<c8y-data-point-list
|
|
63
|
-
datapoints="data.datapoints"
|
|
64
|
-
allow-adding-data-points-from-context-mo-only="dashboard.deviceType && dashboard.deviceTypeValue"
|
|
65
|
-
dont-save="true"
|
|
66
|
-
no-target
|
|
67
|
-
no-yellow-range
|
|
68
|
-
no-red-range
|
|
69
|
-
class="bg-level-0"
|
|
70
|
-
></c8y-data-point-list>
|
|
71
|
-
<c8y-alarms-events-timelines-config
|
|
72
|
-
configs="data.alarmsEventsConfigs"
|
|
73
|
-
allow-alarms-events-from-context-mo-only="dashboard.deviceType && dashboard.deviceTypeValue"
|
|
74
|
-
class="bg-level-0"
|
|
75
|
-
></c8y-alarms-events-timelines-config>
|
|
76
|
-
<label
|
|
77
|
-
title="{{ 'Show date selection' | translate }}"
|
|
78
|
-
class="checkbox-inline c8y-checkbox m-t-16"
|
|
79
|
-
>
|
|
80
|
-
<input type="checkbox" ng-model="data.displayDateSelection" />
|
|
81
|
-
<span></span>
|
|
82
|
-
<span>{{ 'Show date selection' | translate }}</span>
|
|
83
|
-
</label>
|
|
84
142
|
</div>
|
|
85
143
|
</div>
|
|
@@ -1,54 +1,111 @@
|
|
|
1
|
-
<div
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
1
|
+
<div
|
|
2
|
+
ng-controller="DataPointWidgetConfigCtrl"
|
|
3
|
+
ng-init="disableLocalStorage = true"
|
|
4
|
+
class="row no-card-context d-flex"
|
|
5
|
+
style="height: calc(100vh - 422px);"
|
|
6
|
+
>
|
|
7
|
+
<div class="col-md-5 bg-level-1 a-s-stretch inner-scroll">
|
|
8
|
+
<div class="p-l-24 bg-inherit p-t-8">
|
|
9
|
+
<div class="form-group m-b-0 p-b-16 separator-bottom">
|
|
10
|
+
<label for="dateSelection">
|
|
11
|
+
{{ 'Date selection' | translate }}
|
|
12
|
+
<button
|
|
13
|
+
type="button"
|
|
14
|
+
class="btn-help btn-help--sm"
|
|
15
|
+
aria-label="{{ 'Help' | translate }}"
|
|
16
|
+
uib-popover-html="dateSelectionHelpPopoverText | translate"
|
|
17
|
+
popover-placement="right"
|
|
18
|
+
popover-trigger="'focus'"
|
|
19
|
+
popover-append-to-body="true"
|
|
20
|
+
></button>
|
|
21
|
+
</label>
|
|
22
|
+
<div class="c8y-select-wrapper">
|
|
23
|
+
<select
|
|
24
|
+
id="dateSelection"
|
|
25
|
+
class="form-control"
|
|
26
|
+
title="{{ 'Date selection' | translate }}"
|
|
27
|
+
aria-label="{{ 'Date selection' | translate }}"
|
|
28
|
+
ng-model="dateSelection"
|
|
29
|
+
>
|
|
30
|
+
<option
|
|
31
|
+
title="{{ 'Widget configuration' | translate }}"
|
|
32
|
+
value="{{ 'config' }}"
|
|
33
|
+
>
|
|
34
|
+
{{ 'Widget configuration' | translate }}
|
|
35
|
+
</option>
|
|
36
|
+
<option
|
|
37
|
+
title="{{ 'Widget and widget configuration' | translate }}"
|
|
38
|
+
value="{{ 'view_and_config' }}"
|
|
39
|
+
>
|
|
40
|
+
{{ 'Widget and widget configuration' | translate }}
|
|
41
|
+
</option>
|
|
42
|
+
<option
|
|
43
|
+
title="{{ 'Dashboard time range' | translate }}"
|
|
44
|
+
value="{{ 'dashboard_context' }}"
|
|
45
|
+
>
|
|
46
|
+
{{ 'Dashboard time range' | translate }}
|
|
47
|
+
</option>
|
|
48
|
+
</select>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<c8y-data-point-list
|
|
53
|
+
datapoints="data.datapoints"
|
|
54
|
+
allow-adding-data-points-from-context-mo-only="dashboard.deviceType && dashboard.deviceTypeValue"
|
|
55
|
+
dont-save="true"
|
|
56
|
+
class="bg-inherit separator-bottom"
|
|
57
|
+
></c8y-data-point-list>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<div class="col-md-7 sticky-top">
|
|
62
|
+
<div class="p-r-24 p-t-8">
|
|
63
|
+
<div
|
|
64
|
+
class="data-point-explorer d-flex d-col"
|
|
65
|
+
ng-controller="c8yDataPointExplorerCtrl"
|
|
66
|
+
>
|
|
67
|
+
<div class="m-b-4 m-t-4 d-flex j-c-end gap-8">
|
|
68
|
+
<c8y-realtime-button
|
|
69
|
+
ng-show="!data.widgetInstanceGlobalTimeContext"
|
|
70
|
+
class="top-right-control"
|
|
71
|
+
channel="{{ channel }}"
|
|
72
|
+
state="data.realtime"
|
|
73
|
+
on-data="onData($data)"
|
|
74
|
+
></c8y-realtime-button>
|
|
75
|
+
<c8y-aggregation
|
|
76
|
+
class="top-right-control"
|
|
77
|
+
date-from="data.dateFrom"
|
|
78
|
+
date-to="data.dateTo"
|
|
79
|
+
aggregation="data.aggregation"
|
|
80
|
+
realtime="data.realtime"
|
|
81
|
+
auto="true"
|
|
82
|
+
></c8y-aggregation>
|
|
83
|
+
<c8y-interval
|
|
84
|
+
ng-show="!data.widgetInstanceGlobalTimeContext"
|
|
85
|
+
class="top-right-control"
|
|
86
|
+
date-from="data.dateFrom"
|
|
87
|
+
date-to="data.dateTo"
|
|
88
|
+
interval="data.interval"
|
|
89
|
+
></c8y-interval>
|
|
90
|
+
</div>
|
|
91
|
+
<div
|
|
92
|
+
class="c8yGraphFill"
|
|
93
|
+
style="height: calc(100vh - 520px);"
|
|
94
|
+
>
|
|
95
|
+
<c8y-chart
|
|
96
|
+
datapoints="data.graphDataPoints"
|
|
97
|
+
date-from="data.dateFrom"
|
|
98
|
+
date-to="data.dateTo"
|
|
99
|
+
realtime="data.realtime"
|
|
100
|
+
aggregation="data.aggregation"
|
|
101
|
+
show-time="!data.widgetInstanceGlobalTimeContext"
|
|
102
|
+
on-data="(onData)"
|
|
103
|
+
on-update-dates="onUpdateDates($dateFrom, $dateTo)"
|
|
104
|
+
on-update-displayed-dates="onUpdateDisplayedDates($dateFrom, $dateTo)"
|
|
105
|
+
on-box-changed="onBoxChanged(box)"
|
|
106
|
+
></c8y-chart>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
<div ng-controller="kpiConfigCtrl">
|
|
2
|
-
<div
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
<div
|
|
3
|
+
ng-controller="listConfigCtrl"
|
|
4
|
+
class="no-card-context row m-l-0 m-r-0"
|
|
5
|
+
style="height: calc(100vh - 422px)"
|
|
6
|
+
>
|
|
7
|
+
<div class="col-md-6 p-l-24 inner-scroll bg-level-1">
|
|
5
8
|
<c8y-data-point-list
|
|
6
9
|
ng-model="config"
|
|
7
10
|
datapoints="config.options.dataPoints"
|
|
@@ -10,28 +13,60 @@
|
|
|
10
13
|
allow-adding-data-points-from-context-mo-only="dashboard.deviceType && dashboard.deviceTypeValue"
|
|
11
14
|
></c8y-data-point-list>
|
|
12
15
|
</div>
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
16
|
+
<div class="col-md-6 p-r-24 inner-scroll">
|
|
17
|
+
<div class="card-header separator sticky-top bg-level-0">
|
|
18
|
+
<span class="card-title">{{ 'Column visibility' | translate }}</span>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="form-group p-t-8">
|
|
21
|
+
<label class="c8y-checkbox">
|
|
22
|
+
<input
|
|
23
|
+
type="checkbox"
|
|
24
|
+
ng-model="config.options.kpi"
|
|
25
|
+
/>
|
|
26
|
+
<span></span>
|
|
27
|
+
<span>{{ 'Label' | translate }}</span>
|
|
28
|
+
</label>
|
|
29
|
+
<label class="c8y-checkbox">
|
|
30
|
+
<input
|
|
31
|
+
type="checkbox"
|
|
32
|
+
ng-model="config.options.target"
|
|
33
|
+
/>
|
|
34
|
+
<span></span>
|
|
35
|
+
<span>{{ 'Target' | translate }}</span>
|
|
36
|
+
</label>
|
|
37
|
+
<label class="c8y-checkbox">
|
|
38
|
+
<input
|
|
39
|
+
type="checkbox"
|
|
40
|
+
ng-model="config.options.current"
|
|
41
|
+
/>
|
|
42
|
+
<span></span>
|
|
43
|
+
<span>{{ 'Current' | translate }}</span>
|
|
44
|
+
</label>
|
|
45
|
+
<label class="c8y-checkbox">
|
|
46
|
+
<input
|
|
47
|
+
type="checkbox"
|
|
48
|
+
ng-model="config.options.diff"
|
|
49
|
+
/>
|
|
50
|
+
<span></span>
|
|
51
|
+
<span>{{ 'Diff' | translate }}</span>
|
|
52
|
+
</label>
|
|
53
|
+
<label class="c8y-checkbox">
|
|
54
|
+
<input
|
|
55
|
+
type="checkbox"
|
|
56
|
+
ng-model="config.options.diffPercentage"
|
|
57
|
+
/>
|
|
58
|
+
<span></span>
|
|
59
|
+
<span>{{ 'Diff %' | translate }}</span>
|
|
60
|
+
</label>
|
|
61
|
+
<label class="c8y-checkbox">
|
|
62
|
+
<input
|
|
63
|
+
type="checkbox"
|
|
64
|
+
ng-model="config.options.asset"
|
|
65
|
+
/>
|
|
66
|
+
<span></span>
|
|
67
|
+
<span>{{ 'Asset' | translate }}</span>
|
|
68
|
+
</label>
|
|
69
|
+
</div>
|
|
35
70
|
</div>
|
|
36
71
|
</div>
|
|
37
72
|
</div>
|
package/package.json
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
<div
|
|
2
|
-
|
|
1
|
+
<div
|
|
2
|
+
ng-controller="ScadaWidgetConfigCtrl as ctrl"
|
|
3
|
+
class="p-t-8"
|
|
4
|
+
>
|
|
5
|
+
<div>
|
|
3
6
|
<label>
|
|
4
7
|
<span translate>SVG</span>
|
|
5
8
|
<button
|
|
@@ -14,7 +17,10 @@
|
|
|
14
17
|
></button>
|
|
15
18
|
</label>
|
|
16
19
|
|
|
17
|
-
<div
|
|
20
|
+
<div
|
|
21
|
+
class="alert alert-info text-left"
|
|
22
|
+
ng-show="svgTooltipVisible"
|
|
23
|
+
>
|
|
18
24
|
<p translate>
|
|
19
25
|
For placeholder to be recognized it needs to be used at least once in curly braces with no
|
|
20
26
|
other expression, for example,
|
|
@@ -59,32 +65,54 @@
|
|
|
59
65
|
</div>
|
|
60
66
|
|
|
61
67
|
<div class="form-group">
|
|
62
|
-
<label translate>Select code sanitization option</label>
|
|
63
|
-
<select
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
<label for="sanitization" translate>Select code sanitization option</label>
|
|
69
|
+
<div class="c8y-select-wrapper">
|
|
70
|
+
<select
|
|
71
|
+
class="form-control"
|
|
72
|
+
id="sanitization"
|
|
73
|
+
ng-model="config.sanitization"
|
|
74
|
+
ng-init="config.sanitization = config.sanitization || 'strict'"
|
|
75
|
+
>
|
|
76
|
+
<option
|
|
77
|
+
value="strict"
|
|
78
|
+
translate
|
|
79
|
+
>strict`code sanitization`</option>
|
|
80
|
+
<option
|
|
81
|
+
value="lax"
|
|
82
|
+
translate
|
|
83
|
+
>lax`code sanitization`</option>
|
|
84
|
+
<option
|
|
85
|
+
value="none"
|
|
86
|
+
translate
|
|
87
|
+
>none`code sanitization`</option>
|
|
88
|
+
</select>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
<div class="form-group">
|
|
92
|
+
<file-picker
|
|
93
|
+
files="ctrl.files"
|
|
94
|
+
multiple="false"
|
|
95
|
+
display-drop-zone="false"
|
|
96
|
+
on-file-selected="ctrl.onSelectFile(ctrl.files[0].file)"
|
|
97
|
+
></file-picker>
|
|
98
|
+
<input type="hidden" />
|
|
72
99
|
</div>
|
|
73
|
-
|
|
74
|
-
<file-picker
|
|
75
|
-
files="ctrl.files"
|
|
76
|
-
multiple="false"
|
|
77
|
-
display-drop-zone="false"
|
|
78
|
-
on-file-selected="ctrl.onSelectFile(ctrl.files[0].file)"
|
|
79
|
-
></file-picker>
|
|
80
|
-
<input type="hidden" />
|
|
81
|
-
<span id="helpBlock" class="help-block m-b-16" translate>SVG content will be sanitized.</span>
|
|
82
100
|
</div>
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
<
|
|
86
|
-
|
|
87
|
-
|
|
101
|
+
<div class="form-group p-t-16">
|
|
102
|
+
<label class="input-group">{{ 'Preview' | translate }}</label>
|
|
103
|
+
<span
|
|
104
|
+
id="helpBlock"
|
|
105
|
+
class="help-block m-b-8"
|
|
106
|
+
translate
|
|
107
|
+
>SVG content will be sanitized.</span>
|
|
108
|
+
<span
|
|
109
|
+
ng-show="ctrl.loading"
|
|
110
|
+
class="m-l-4"
|
|
111
|
+
>
|
|
112
|
+
<i
|
|
113
|
+
c8y-icon="spinner"
|
|
114
|
+
class="icon-spin"
|
|
115
|
+
></i>
|
|
88
116
|
</span>
|
|
89
117
|
<div ng-switch="!!(ctrl.device && forms.componentForm.mapping.$valid && config.mapping)">
|
|
90
118
|
<div
|
|
@@ -95,14 +123,16 @@
|
|
|
95
123
|
device="ctrl.device"
|
|
96
124
|
devices="ctrl.devices"
|
|
97
125
|
device-ids="config.deviceIds"
|
|
98
|
-
style="height: 200px"
|
|
99
126
|
></div>
|
|
100
|
-
<div
|
|
101
|
-
|
|
127
|
+
<div
|
|
128
|
+
ng-switch-default
|
|
129
|
+
class="alert alert-info"
|
|
130
|
+
translate
|
|
131
|
+
>
|
|
132
|
+
Select a device and fill all mappings to preview an SVG.
|
|
102
133
|
</div>
|
|
103
134
|
</div>
|
|
104
135
|
</div>
|
|
105
|
-
|
|
106
136
|
<div
|
|
107
137
|
c8y-scada-mapping
|
|
108
138
|
name="mapping"
|
|
@@ -111,6 +141,6 @@
|
|
|
111
141
|
devices="ctrl.devices"
|
|
112
142
|
device-ids="config.deviceIds"
|
|
113
143
|
on-device-ids-change="ctrl.onDeviceIdsChange()"
|
|
114
|
-
class="table-responsive"
|
|
115
144
|
></div>
|
|
145
|
+
|
|
116
146
|
</div>
|
package/scada/views/mapping.html
CHANGED
|
@@ -1,102 +1,113 @@
|
|
|
1
|
-
<
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
ng-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
1
|
+
<div class="svg-mappings">
|
|
2
|
+
<label>{{ 'Mappings' | translate }}</label>
|
|
3
|
+
<ul class="c8y-list__group c8y-list__group--strip">
|
|
4
|
+
<li class="c8y-list__item" ng-repeat="mapping in mappings | orderBy:'placeholder'">
|
|
5
|
+
<div class="c8y-list__item__block d-block">
|
|
6
|
+
<div class="c8y-list__item__body">
|
|
7
|
+
<div class="row">
|
|
8
|
+
<div class="col-md-4">
|
|
9
|
+
<label class="text-label-small d-block" translate>Placeholder</label>
|
|
10
|
+
<div class="text-medium">
|
|
11
|
+
<i
|
|
12
|
+
c8y-icon="exclamation-circle"
|
|
13
|
+
class="m-r-4 text-danger"
|
|
14
|
+
ng-show="hasError[mapping.placeholder]"
|
|
15
|
+
></i>
|
|
16
|
+
<span title="{{ mapping.placeholder }}">
|
|
17
|
+
{{ mapping.placeholder }}
|
|
18
|
+
</span>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="col-md-8">
|
|
22
|
+
<label class="text-label-small d-block" translate>Target</label>
|
|
23
|
+
<div class="form-group-sm form-group">
|
|
24
|
+
<span ng-show="!devices.length">---</span>
|
|
25
|
+
<span
|
|
26
|
+
class="text-truncate"
|
|
27
|
+
title="{{ devices[0].name }}"
|
|
28
|
+
ng-show="devices.length == 1"
|
|
29
|
+
>
|
|
30
|
+
{{ devices[0].name }}
|
|
31
|
+
</span>
|
|
32
|
+
<div class="c8y-select-wrapper" ng-show="devices.length > 1">
|
|
33
|
+
<select
|
|
34
|
+
class="form-control"
|
|
35
|
+
ng-change="onDeviceIdsChange()"
|
|
36
|
+
ng-model="deviceIds[mapping.placeholder]"
|
|
37
|
+
ng-options="device.id as device.name for device in devices"
|
|
38
|
+
required
|
|
39
|
+
></select>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="col-md-4" ng-switch="!!mapping.config.configSchema">
|
|
44
|
+
<label class="text-label-small d-block" translate>Mapped to</label>
|
|
45
|
+
<button
|
|
46
|
+
class="btn btn-sm btn-default text-truncate"
|
|
47
|
+
type="button"
|
|
48
|
+
title=" {{ humanizeValue(mapping) }}"
|
|
49
|
+
ng-click="editComputedProperty(mapping)"
|
|
50
|
+
ng-switch-when="true"
|
|
51
|
+
>
|
|
52
|
+
<i c8y-icon="bolt"></i>
|
|
53
|
+
<span>
|
|
54
|
+
{{ humanizeValue(mapping) }}
|
|
55
|
+
</span>
|
|
56
|
+
</button>
|
|
57
|
+
<div class="form-control-static">
|
|
58
|
+
<span class="text-truncate" title="{{ humanizeValue(mapping) }}" ng-switch-default>
|
|
59
|
+
{{ humanizeValue(mapping) }}
|
|
60
|
+
</span>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
<div class="col-md-4">
|
|
64
|
+
<label class="text-label-small d-block" translate>Current value</label>
|
|
65
|
+
<div class="form-control-static" title="{{ propertyValueFor(mapping) }}">
|
|
66
|
+
<span class="text-truncate text-monospace">
|
|
67
|
+
{{ propertyValueFor(mapping) }}
|
|
68
|
+
</span>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
<div class="col-md-4">
|
|
72
|
+
<label class="text-label-small d-block" translate>Actions</label>
|
|
73
|
+
<button
|
|
74
|
+
class="btn btn-default btn-sm"
|
|
75
|
+
type="button"
|
|
76
|
+
uib-tooltip="{{ 'Clear mapping' | translate }}"
|
|
77
|
+
tooltip-append-to-body="true"
|
|
78
|
+
tooltip-popup-delay="500"
|
|
79
|
+
aria-label="{{ 'Clear mapping' | translate }}"
|
|
80
|
+
ng-click="clearMapping(mapping)"
|
|
81
|
+
ng-disabled="!mapping.config"
|
|
82
|
+
>
|
|
83
|
+
<i c8y-icon="delete-document"></i>
|
|
84
|
+
</button>
|
|
85
|
+
<button
|
|
86
|
+
class="btn btn-default btn-sm"
|
|
87
|
+
type="button"
|
|
88
|
+
uib-tooltip="{{ 'Assign fieldbus property' | translate }}"
|
|
89
|
+
tooltip-append-to-body="true"
|
|
90
|
+
tooltip-popup-delay="500"
|
|
91
|
+
aria-label="{{ 'Assign fieldbus property' | translate }}"
|
|
92
|
+
ng-click="setFieldbusMapping(mapping)"
|
|
93
|
+
>
|
|
94
|
+
<i c8y-icon="tasks"></i>
|
|
95
|
+
</button>
|
|
96
|
+
<button
|
|
97
|
+
class="btn btn-default btn-sm"
|
|
98
|
+
type="button"
|
|
99
|
+
uib-tooltip="{{ 'Assign device property' | translate }}"
|
|
100
|
+
tooltip-append-to-body="true"
|
|
101
|
+
tooltip-popup-delay="500"
|
|
102
|
+
aria-label="{{ 'Assign device property' | translate }}"
|
|
103
|
+
ng-click="setMapping(mapping)"
|
|
104
|
+
>
|
|
105
|
+
<i c8y-icon="edit"></i>
|
|
106
|
+
</button>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
49
109
|
</div>
|
|
50
|
-
</
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
title="{{ humanizeValue(mapping) }}"
|
|
55
|
-
>
|
|
56
|
-
<a
|
|
57
|
-
ng-switch-when="true"
|
|
58
|
-
class="btn btn-xs btn-default"
|
|
59
|
-
href=""
|
|
60
|
-
ng-click="editComputedProperty(mapping)"
|
|
61
|
-
>
|
|
62
|
-
<i c8y-icon="bolt"></i>
|
|
63
|
-
{{ humanizeValue(mapping) }}
|
|
64
|
-
</a>
|
|
65
|
-
<span ng-switch-default>{{ humanizeValue(mapping) }}</span>
|
|
66
|
-
</td>
|
|
67
|
-
<td class="text-truncate">
|
|
68
|
-
<span title=" {{ propertyValueFor(mapping) }}">
|
|
69
|
-
{{ propertyValueFor(mapping) }}
|
|
70
|
-
</span>
|
|
71
|
-
</td>
|
|
72
|
-
<td>
|
|
73
|
-
<div class="d-flex flex-end">
|
|
74
|
-
<button
|
|
75
|
-
type="button"
|
|
76
|
-
class="btn btn-danger btn-xs showOnHover pull-right"
|
|
77
|
-
title="{{ 'Clear mapping' | translate }}"
|
|
78
|
-
ng-click="clearMapping(mapping)"
|
|
79
|
-
>
|
|
80
|
-
<i c8y-icon="scissors"></i>
|
|
81
|
-
</button>
|
|
82
|
-
<button
|
|
83
|
-
type="button"
|
|
84
|
-
class="btn btn-primary btn-xs showOnHover pull-right"
|
|
85
|
-
title="{{ 'Assign fieldbus property' | translate }}"
|
|
86
|
-
ng-click="setFieldbusMapping(mapping)"
|
|
87
|
-
>
|
|
88
|
-
<i c8y-icon="tasks"></i>
|
|
89
|
-
</button>
|
|
90
|
-
<button
|
|
91
|
-
type="button"
|
|
92
|
-
class="btn btn-primary btn-xs showOnHover pull-right"
|
|
93
|
-
title="{{ 'Assign device property' | translate }}"
|
|
94
|
-
ng-click="setMapping(mapping)"
|
|
95
|
-
>
|
|
96
|
-
<i c8y-icon="pencil"></i>
|
|
97
|
-
</button>
|
|
98
|
-
</div>
|
|
99
|
-
</td>
|
|
100
|
-
</tr>
|
|
101
|
-
</tbody>
|
|
102
|
-
</table>
|
|
110
|
+
</div>
|
|
111
|
+
</li>
|
|
112
|
+
</ul>
|
|
113
|
+
</div>
|