Commit cc1ad23c4e9244fa43d2217c245f6a4d4e39e8f8

Authored by Igor Kulikov
1 parent acb94868

Improve Entity View UI

... ... @@ -15,7 +15,7 @@
15 15 limitations under the License.
16 16
17 17 -->
18   -<md-dialog aria-label="{{ 'entity-view.add' | translate }}" tb-help="'entityViews'" help-container-id="help-container">
  18 +<md-dialog aria-label="{{ 'entity-view.add' | translate }}" style="width: 800px;" tb-help="'entityViews'" help-container-id="help-container">
19 19 <form name="theForm" ng-submit="vm.add()">
20 20 <md-toolbar>
21 21 <div class="md-toolbar-tools">
... ...
... ... @@ -60,7 +60,7 @@
60 60 entity-type="types.entityType.entityView">
61 61 </tb-entity-subtype-autocomplete>
62 62 <section layout="column">
63   - <label translate class="tb-title no-padding">entity-view.related-entity</label>
  63 + <label translate class="tb-title no-padding">entity-view.target-entity</label>
64 64 <tb-entity-select flex ng-disabled="!isEdit"
65 65 the-form="theForm"
66 66 tb-required="true"
... ... @@ -68,110 +68,145 @@
68 68 ng-model="entityView.entityId">
69 69 </tb-entity-select>
70 70 </section>
  71 + <md-expansion-panel-group class="tb-entity-view-panel-group" ng-class="{'disabled': $root.loading || !isEdit}"
  72 + auto-expand="true"
  73 + multiple="true"
  74 + md-component-id="attributesPanelGroup">
  75 + <md-expansion-panel md-component-id="{{attributesPanelId}}">
  76 + <md-expansion-panel-collapsed>
  77 + <div class="tb-panel-title">{{ 'entity-view.attributes-propagation' | translate }}</div>
  78 + <span flex></span>
  79 + <md-expansion-panel-icon></md-expansion-panel-icon>
  80 + </md-expansion-panel-collapsed>
  81 + <md-expansion-panel-expanded>
  82 + <md-expansion-panel-header ng-click="$mdExpansionPanel(attributesPanelId).collapse()">
  83 + <div class="tb-panel-title">{{ 'entity-view.attributes-propagation' | translate }}</div>
  84 + <span flex></span>
  85 + <md-expansion-panel-icon></md-expansion-panel-icon>
  86 + </md-expansion-panel-header>
  87 + <md-expansion-panel-content>
  88 + <div translate class="tb-hint">entity-view.attributes-propagation-hint</div>
  89 + <label translate class="tb-title no-padding">entity-view.client-attributes</label>
  90 + <md-chips style="padding-bottom: 15px;"
  91 + ng-required="false"
  92 + readonly="!isEdit"
  93 + ng-model="entityView.keys.attributes.cs"
  94 + placeholder="{{'entity-view.client-attributes-placeholder' | translate}}"
  95 + md-separator-keys="separatorKeys">
  96 + <md-autocomplete
  97 + md-no-cache="true"
  98 + id="ca_datakey"
  99 + md-selected-item="selectedAttributeDataKey"
  100 + md-search-text="attributeDataKeySearchText"
  101 + md-items="item in dataKeysSearch(attributeDataKeySearchText, types.dataKeyType.attribute)"
  102 + md-item-text="item.name"
  103 + md-min-length="0"
  104 + placeholder="{{'entity-view.client-attributes-placeholder' | translate }}"
  105 + md-menu-class="tb-attribute-datakey-autocomplete">
  106 + <span md-highlight-text="attributeDataKeySearchText" md-highlight-flags="^i">{{item}}</span>
  107 + </md-autocomplete>
  108 + </md-chips>
  109 + <label translate class="tb-title no-padding">entity-view.shared-attributes</label>
  110 + <md-chips style="padding-bottom: 15px;"
  111 + ng-required="false"
  112 + readonly="!isEdit"
  113 + ng-model="entityView.keys.attributes.sh"
  114 + placeholder="{{'entity-view.shared-attributes-placeholder' | translate}}"
  115 + md-separator-keys="separatorKeys">
  116 + <md-autocomplete
  117 + md-no-cache="true"
  118 + id="sh_datakey"
  119 + md-selected-item="selectedAttributeDataKey"
  120 + md-search-text="attributeDataKeySearchText"
  121 + md-items="item in dataKeysSearch(attributeDataKeySearchText, types.dataKeyType.attribute)"
  122 + md-item-text="item.name"
  123 + md-min-length="0"
  124 + placeholder="{{'entity-view.server-attributes-placeholder' | translate }}"
  125 + md-menu-class="tb-attribute-datakey-autocomplete">
  126 + <span md-highlight-text="attributeDataKeySearchText" md-highlight-flags="^i">{{item}}</span>
  127 + </md-autocomplete>
  128 + </md-chips>
  129 + <label translate class="tb-title no-padding">entity-view.server-attributes</label>
  130 + <md-chips style="padding-bottom: 15px;"
  131 + ng-required="false"
  132 + readonly="!isEdit"
  133 + ng-model="entityView.keys.attributes.ss"
  134 + placeholder="{{'entity-view.server-attributes-placeholder' | translate}}"
  135 + md-separator-keys="separatorKeys">
  136 + <md-autocomplete
  137 + md-no-cache="true"
  138 + id="ss_datakey"
  139 + md-selected-item="selectedAttributeDataKey"
  140 + md-search-text="attributeDataKeySearchText"
  141 + md-items="item in dataKeysSearch(attributeDataKeySearchText, types.dataKeyType.attribute)"
  142 + md-item-text="item.name"
  143 + md-min-length="0"
  144 + placeholder="{{'entity-view.server-attributes-placeholder' | translate }}"
  145 + md-menu-class="tb-attribute-datakey-autocomplete">
  146 + <span md-highlight-text="attributeDataKeySearchText" md-highlight-flags="^i">{{item}}</span>
  147 + </md-autocomplete>
  148 + </md-chips>
  149 + </md-expansion-panel-content>
  150 + </md-expansion-panel-expanded>
  151 + </md-expansion-panel>
  152 + <md-expansion-panel md-component-id="{{timeseriesPanelId}}">
  153 + <md-expansion-panel-collapsed>
  154 + <div class="tb-panel-title">{{ 'entity-view.timeseries-data' | translate }}</div>
  155 + <span flex></span>
  156 + <md-expansion-panel-icon></md-expansion-panel-icon>
  157 + </md-expansion-panel-collapsed>
  158 + <md-expansion-panel-expanded>
  159 + <md-expansion-panel-header ng-click="$mdExpansionPanel(timeseriesPanelId).collapse()">
  160 + <div class="tb-panel-title">{{ 'entity-view.timeseries-data' | translate }}</div>
  161 + <span flex></span>
  162 + <md-expansion-panel-icon></md-expansion-panel-icon>
  163 + </md-expansion-panel-header>
  164 + <md-expansion-panel-content>
  165 + <div translate class="tb-hint">entity-view.timeseries-data-hint</div>
  166 + <label translate class="tb-title no-padding">entity-view.timeseries</label>
  167 + <md-chips ng-required="false"
  168 + readonly="!isEdit"
  169 + ng-model="entityView.keys.timeseries"
  170 + placeholder="{{'entity-view.timeseries-placeholder' | translate}}"
  171 + md-separator-keys="separatorKeys">
  172 + <md-autocomplete
  173 + md-no-cache="true"
  174 + id="timeseries_datakey"
  175 + md-selected-item="selectedTimeseriesDataKey"
  176 + md-search-text="timeseriesDataKeySearchText"
  177 + md-items="item in dataKeysSearch(timeseriesDataKeySearchText, types.dataKeyType.timeseries)"
  178 + md-item-text="item.name"
  179 + md-min-length="0"
  180 + placeholder="{{'entity-view.timeseries-placeholder' | translate }}"
  181 + md-menu-class="tb-timeseries-datakey-autocomplete">
  182 + <span md-highlight-text="timeseriesDataKeySearchText" md-highlight-flags="^i">{{item}}</span>
  183 + </md-autocomplete>
  184 + </md-chips>
  185 + </md-expansion-panel-content>
  186 + </md-expansion-panel-expanded>
  187 + </md-expansion-panel>
  188 + </md-expansion-panel-group>
  189 + <section layout="row" layout-align="start start">
  190 + <mdp-date-picker ng-model="startTimeMs"
  191 + mdp-max-date="maxStartTimeMs"
  192 + mdp-placeholder="{{ 'entity-view.start-date' | translate }}"></mdp-date-picker>
  193 + <mdp-time-picker ng-model="startTimeMs"
  194 + mdp-max-date="maxStartTimeMs"
  195 + mdp-placeholder="{{ 'entity-view.start-ts' | translate }}"
  196 + mdp-auto-switch="true"></mdp-time-picker>
  197 + </section>
  198 + <section layout="row" layout-align="start start">
  199 + <mdp-date-picker ng-model="endTimeMs"
  200 + mdp-min-date="minEndTimeMs"
  201 + mdp-placeholder="{{ 'entity-view.end-date' | translate }}"></mdp-date-picker>
  202 + <mdp-time-picker ng-model="endTimeMs"
  203 + mdp-min-date="minEndTimeMs"
  204 + mdp-placeholder="{{ 'entity-view.end-ts' | translate }}"
  205 + mdp-auto-switch="true"></mdp-time-picker>
  206 + </section>
71 207 <md-input-container class="md-block">
72 208 <label translate>entity-view.description</label>
73 209 <textarea ng-model="entityView.additionalInfo.description" rows="2"></textarea>
74 210 </md-input-container>
75   - <section layout="column">
76   - <label translate class="tb-title no-padding">entity-view.client-attributes</label>
77   - <md-chips style="padding-bottom: 15px;"
78   - ng-required="false"
79   - readonly="!isEdit"
80   - ng-model="entityView.keys.attributes.cs"
81   - placeholder="{{'entity-view.client-attributes-placeholder' | translate}}"
82   - md-separator-keys="separatorKeys">
83   - <md-autocomplete
84   - md-no-cache="true"
85   - id="ca_datakey"
86   - md-selected-item="selectedAttributeDataKey"
87   - md-search-text="attributeDataKeySearchText"
88   - md-items="item in dataKeysSearch(attributeDataKeySearchText, types.dataKeyType.attribute)"
89   - md-item-text="item.name"
90   - md-min-length="0"
91   - placeholder="{{'entity-view.client-attributes-placeholder' | translate }}"
92   - md-menu-class="tb-attribute-datakey-autocomplete">
93   - <span md-highlight-text="attributeDataKeySearchText" md-highlight-flags="^i">{{item}}</span>
94   - </md-autocomplete>
95   - </md-chips>
96   - <label translate class="tb-title no-padding">entity-view.shared-attributes</label>
97   - <md-chips style="padding-bottom: 15px;"
98   - ng-required="false"
99   - readonly="!isEdit"
100   - ng-model="entityView.keys.attributes.sh"
101   - placeholder="{{'entity-view.shared-attributes-placeholder' | translate}}"
102   - md-separator-keys="separatorKeys">
103   - <md-autocomplete
104   - md-no-cache="true"
105   - id="sh_datakey"
106   - md-selected-item="selectedAttributeDataKey"
107   - md-search-text="attributeDataKeySearchText"
108   - md-items="item in dataKeysSearch(attributeDataKeySearchText, types.dataKeyType.attribute)"
109   - md-item-text="item.name"
110   - md-min-length="0"
111   - placeholder="{{'entity-view.server-attributes-placeholder' | translate }}"
112   - md-menu-class="tb-attribute-datakey-autocomplete">
113   - <span md-highlight-text="attributeDataKeySearchText" md-highlight-flags="^i">{{item}}</span>
114   - </md-autocomplete>
115   - </md-chips>
116   - <label translate class="tb-title no-padding">entity-view.server-attributes</label>
117   - <md-chips style="padding-bottom: 15px;"
118   - ng-required="false"
119   - readonly="!isEdit"
120   - ng-model="entityView.keys.attributes.ss"
121   - placeholder="{{'entity-view.server-attributes-placeholder' | translate}}"
122   - md-separator-keys="separatorKeys">
123   - <md-autocomplete
124   - md-no-cache="true"
125   - id="ss_datakey"
126   - md-selected-item="selectedAttributeDataKey"
127   - md-search-text="attributeDataKeySearchText"
128   - md-items="item in dataKeysSearch(attributeDataKeySearchText, types.dataKeyType.attribute)"
129   - md-item-text="item.name"
130   - md-min-length="0"
131   - placeholder="{{'entity-view.server-attributes-placeholder' | translate }}"
132   - md-menu-class="tb-attribute-datakey-autocomplete">
133   - <span md-highlight-text="attributeDataKeySearchText" md-highlight-flags="^i">{{item}}</span>
134   - </md-autocomplete>
135   - </md-chips>
136   - <label translate class="tb-title no-padding">entity-view.timeseries</label>
137   - <md-chips ng-required="false"
138   - readonly="!isEdit"
139   - ng-model="entityView.keys.timeseries"
140   - placeholder="{{'entity-view.timeseries-placeholder' | translate}}"
141   - md-separator-keys="separatorKeys">
142   - <md-autocomplete
143   - md-no-cache="true"
144   - id="timeseries_datakey"
145   - md-selected-item="selectedTimeseriesDataKey"
146   - md-search-text="timeseriesDataKeySearchText"
147   - md-items="item in dataKeysSearch(timeseriesDataKeySearchText, types.dataKeyType.timeseries)"
148   - md-item-text="item.name"
149   - md-min-length="0"
150   - placeholder="{{'entity-view.timeseries-placeholder' | translate }}"
151   - md-menu-class="tb-timeseries-datakey-autocomplete">
152   - <span md-highlight-text="timeseriesDataKeySearchText" md-highlight-flags="^i">{{item}}</span>
153   - </md-autocomplete>
154   - </md-chips>
155   - </section>
156   - <section layout="column">
157   - <section layout="row" layout-align="start start">
158   - <mdp-date-picker ng-model="startTimeMs"
159   - mdp-max-date="maxStartTimeMs"
160   - mdp-placeholder="{{ 'entity-view.start-ts' | translate }}"></mdp-date-picker>
161   - <mdp-time-picker ng-model="startTimeMs"
162   - mdp-max-date="maxStartTimeMs"
163   - mdp-placeholder="{{ 'entity-view.start-ts' | translate }}"
164   - mdp-auto-switch="true"></mdp-time-picker>
165   - </section>
166   - <section layout="row" layout-align="start start">
167   - <mdp-date-picker ng-model="endTimeMs"
168   - mdp-min-date="minEndTimeMs"
169   - mdp-placeholder="{{ 'entity-view.end-ts' | translate }}"></mdp-date-picker>
170   - <mdp-time-picker ng-model="endTimeMs"
171   - mdp-min-date="minEndTimeMs"
172   - mdp-placeholder="{{ 'entity-view.end-ts' | translate }}"
173   - mdp-auto-switch="true"></mdp-time-picker>
174   - </section>
175   - </section>
176 211 </fieldset>
177 212 </md-content>
... ...
... ... @@ -13,6 +13,9 @@
13 13 * See the License for the specific language governing permissions and
14 14 * limitations under the License.
15 15 */
  16 +
  17 +import './entity-view.scss';
  18 +
16 19 /* eslint-disable import/no-unresolved, import/default */
17 20
18 21 import entityViewFieldsetTemplate from './entity-view-fieldset.tpl.html';
... ... @@ -20,12 +23,16 @@ import entityViewFieldsetTemplate from './entity-view-fieldset.tpl.html';
20 23 /* eslint-enable import/no-unresolved, import/default */
21 24
22 25 /*@ngInject*/
23   -export default function EntityViewDirective($q, $compile, $templateCache, $filter, toast, $translate, $mdConstant,
  26 +export default function EntityViewDirective($q, $compile, $templateCache, $filter, toast, $translate, $mdConstant, $mdExpansionPanel,
24 27 types, clipboardService, entityViewService, customerService, entityService) {
25 28 var linker = function (scope, element) {
26 29 var template = $templateCache.get(entityViewFieldsetTemplate);
27 30 element.html(template);
28 31
  32 + scope.attributesPanelId = (Math.random()*1000).toFixed(0);
  33 + scope.timeseriesPanelId = (Math.random()*1000).toFixed(0);
  34 + scope.$mdExpansionPanel = $mdExpansionPanel;
  35 +
29 36 scope.types = types;
30 37 scope.isAssignedToCustomer = false;
31 38 scope.isPublic = false;
... ...
  1 +/**
  2 + * Copyright © 2016-2018 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 +
  17 +@import "../../scss/constants";
  18 +
  19 +.tb-entity-view-panel-group {
  20 + .tb-panel-title {
  21 + min-width: 90px;
  22 + user-select: none;
  23 +
  24 + @media (min-width: $layout-breakpoint-sm) {
  25 + min-width: 180px;
  26 + }
  27 + }
  28 +
  29 + .tb-panel-prompt {
  30 + overflow: hidden;
  31 + font-size: 14px;
  32 + color: rgba(0, 0, 0, .87);
  33 + text-overflow: ellipsis;
  34 + white-space: nowrap;
  35 + }
  36 +
  37 + &.disabled {
  38 + .tb-panel-title,
  39 + .tb-panel-prompt {
  40 + color: rgba(0, 0, 0, .38);
  41 + }
  42 + }
  43 +
  44 + md-icon.md-expansion-panel-icon {
  45 + margin-right: 0;
  46 + }
  47 +}
... ...
... ... @@ -838,7 +838,9 @@
838 838 "unable-entity-view-device-alias-text": "Device alias '{{entityViewAlias}}' can't be deleted as it used by the following widget(s):<br/>{{widgetsList}}",
839 839 "select-entity-view": "Select entity view",
840 840 "make-public": "Make entity view public",
  841 + "start-date": "Start date",
841 842 "start-ts": "Start time",
  843 + "end-date": "End date",
842 844 "end-ts": "End time",
843 845 "date-limits": "Date limits",
844 846 "client-attributes": "Client attributes",
... ... @@ -849,7 +851,11 @@
849 851 "shared-attributes-placeholder": "Shared attributes",
850 852 "server-attributes-placeholder": "Server attributes",
851 853 "timeseries-placeholder": "Timeseries",
852   - "related-entity": "Related entity"
  854 + "target-entity": "Target entity",
  855 + "attributes-propagation": "Attributes propagation",
  856 + "attributes-propagation-hint": "Entity View will automatically copy specified attributes from Target Entity each time you save or update this entity view. For performance reasons target entity attributes are not propagated to entity view on each attribute change. You can enable automatic propagation by configuring \"copy to view\" rule node in your rule chain and linking \"Post attributes\" and \"Attributes Updated\" messages to the new rule node.",
  857 + "timeseries-data": "Timeseries data",
  858 + "timeseries-data-hint": "Configure timeseries data keys of the target entity that will be accessible to the entity view. This timeseries data is read-only."
853 859 },
854 860 "event": {
855 861 "event-type": "Event type",
... ...