Commit 846f5ba86b5d3cc5ff83df8d7a7fd064589330a2
Merge remote-tracking branch 'deaflynx/develop/3.3-edge' into develop/3.3-edge
Showing
39 changed files
with
353 additions
and
78 deletions
... | ... | @@ -492,6 +492,7 @@ public class AssetController extends BaseController { |
492 | 492 | @PathVariable(EDGE_ID) String strEdgeId, |
493 | 493 | @RequestParam int pageSize, |
494 | 494 | @RequestParam int page, |
495 | + @RequestParam(required = false) String type, | |
495 | 496 | @RequestParam(required = false) String textSearch, |
496 | 497 | @RequestParam(required = false) String sortProperty, |
497 | 498 | @RequestParam(required = false) String sortOrder, |
... | ... | @@ -503,7 +504,11 @@ public class AssetController extends BaseController { |
503 | 504 | EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); |
504 | 505 | checkEdgeId(edgeId, Operation.READ); |
505 | 506 | TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime); |
506 | - return checkNotNull(assetService.findAssetsByTenantIdAndEdgeId(tenantId, edgeId, pageLink)); | |
507 | + if (type != null && type.trim().length() > 0) { | |
508 | + return checkNotNull(assetService.findAssetsByTenantIdAndEdgeIdAndType(tenantId, edgeId, type, pageLink)); | |
509 | + } else { | |
510 | + return checkNotNull(assetService.findAssetsByTenantIdAndEdgeId(tenantId, edgeId, pageLink)); | |
511 | + } | |
507 | 512 | } catch (Exception e) { |
508 | 513 | throw handleException(e); |
509 | 514 | } | ... | ... |
... | ... | @@ -677,6 +677,7 @@ public class EntityViewController extends BaseController { |
677 | 677 | @PathVariable(EDGE_ID) String strEdgeId, |
678 | 678 | @RequestParam int pageSize, |
679 | 679 | @RequestParam int page, |
680 | + @RequestParam(required = false) String type, | |
680 | 681 | @RequestParam(required = false) String textSearch, |
681 | 682 | @RequestParam(required = false) String sortProperty, |
682 | 683 | @RequestParam(required = false) String sortOrder, |
... | ... | @@ -688,7 +689,11 @@ public class EntityViewController extends BaseController { |
688 | 689 | EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); |
689 | 690 | checkEdgeId(edgeId, Operation.READ); |
690 | 691 | TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime); |
691 | - return checkNotNull(entityViewService.findEntityViewsByTenantIdAndEdgeId(tenantId, edgeId, pageLink)); | |
692 | + if (type != null && type.trim().length() > 0) { | |
693 | + return checkNotNull(entityViewService.findEntityViewsByTenantIdAndEdgeIdAndType(tenantId, edgeId, type, pageLink)); | |
694 | + } else { | |
695 | + return checkNotNull(entityViewService.findEntityViewsByTenantIdAndEdgeId(tenantId, edgeId, pageLink)); | |
696 | + } | |
692 | 697 | } catch (Exception e) { |
693 | 698 | throw handleException(e); |
694 | 699 | } | ... | ... |
... | ... | @@ -82,4 +82,6 @@ public interface AssetService { |
82 | 82 | Asset unassignAssetFromEdge(TenantId tenantId, AssetId assetId, EdgeId edgeId); |
83 | 83 | |
84 | 84 | PageData<Asset> findAssetsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink); |
85 | + | |
86 | + PageData<Asset> findAssetsByTenantIdAndEdgeIdAndType(TenantId tenantId, EdgeId edgeId, String type, TimePageLink pageLink); | |
85 | 87 | } | ... | ... |
... | ... | @@ -83,4 +83,6 @@ public interface EntityViewService { |
83 | 83 | EntityView unassignEntityViewFromEdge(TenantId tenantId, EntityViewId entityViewId, EdgeId edgeId); |
84 | 84 | |
85 | 85 | PageData<EntityView> findEntityViewsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink); |
86 | + | |
87 | + PageData<EntityView> findEntityViewsByTenantIdAndEdgeIdAndType(TenantId tenantId, EdgeId edgeId, String type, TimePageLink pageLink); | |
86 | 88 | } | ... | ... |
... | ... | @@ -177,4 +177,15 @@ public interface AssetDao extends Dao<Asset>, TenantEntityDao { |
177 | 177 | * @return the list of asset objects |
178 | 178 | */ |
179 | 179 | PageData<Asset> findAssetsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink); |
180 | + | |
181 | + /** | |
182 | + * Find assets by tenantId, edgeId, type and page link. | |
183 | + * | |
184 | + * @param tenantId the tenantId | |
185 | + * @param edgeId the edgeId | |
186 | + * @param type the type | |
187 | + * @param pageLink the page link | |
188 | + * @return the list of asset objects | |
189 | + */ | |
190 | + PageData<Asset> findAssetsByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, TimePageLink pageLink); | |
180 | 191 | } | ... | ... |
... | ... | @@ -372,6 +372,16 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ |
372 | 372 | return assetDao.findAssetsByTenantIdAndEdgeId(tenantId.getId(), edgeId.getId(), pageLink); |
373 | 373 | } |
374 | 374 | |
375 | + @Override | |
376 | + public PageData<Asset> findAssetsByTenantIdAndEdgeIdAndType(TenantId tenantId, EdgeId edgeId, String type, TimePageLink pageLink) { | |
377 | + log.trace("Executing findAssetsByTenantIdAndEdgeIdAndType, tenantId [{}], edgeId [{}], type [{}] pageLink [{}]", tenantId, edgeId, type, pageLink); | |
378 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | |
379 | + validateId(edgeId, INCORRECT_EDGE_ID + edgeId); | |
380 | + validateString(type, "Incorrect type " + type); | |
381 | + validatePageLink(pageLink); | |
382 | + return assetDao.findAssetsByTenantIdAndEdgeIdAndType(tenantId.getId(), edgeId.getId(), type, pageLink); | |
383 | + } | |
384 | + | |
375 | 385 | private DataValidator<Asset> assetValidator = |
376 | 386 | new DataValidator<Asset>() { |
377 | 387 | ... | ... |
... | ... | @@ -165,4 +165,18 @@ public interface EntityViewDao extends Dao<EntityView> { |
165 | 165 | UUID edgeId, |
166 | 166 | PageLink pageLink); |
167 | 167 | |
168 | + /** | |
169 | + * Find entity views by tenantId, edgeId, type and page link. | |
170 | + * | |
171 | + * @param tenantId the tenantId | |
172 | + * @param edgeId the edgeId | |
173 | + * @param type the type | |
174 | + * @param pageLink the page link | |
175 | + * @return the list of entity view objects | |
176 | + */ | |
177 | + PageData<EntityView> findEntityViewsByTenantIdAndEdgeIdAndType(UUID tenantId, | |
178 | + UUID edgeId, | |
179 | + String type, | |
180 | + PageLink pageLink); | |
181 | + | |
168 | 182 | } | ... | ... |
... | ... | @@ -390,6 +390,16 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti |
390 | 390 | return entityViewDao.findEntityViewsByTenantIdAndEdgeId(tenantId.getId(), edgeId.getId(), pageLink); |
391 | 391 | } |
392 | 392 | |
393 | + @Override | |
394 | + public PageData<EntityView> findEntityViewsByTenantIdAndEdgeIdAndType(TenantId tenantId, EdgeId edgeId, String type, TimePageLink pageLink) { | |
395 | + log.trace("Executing findEntityViewsByTenantIdAndEdgeIdAndType, tenantId [{}], edgeId [{}], type [{}], pageLink [{}]", tenantId, edgeId, type, pageLink); | |
396 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | |
397 | + validateId(edgeId, INCORRECT_EDGE_ID + edgeId); | |
398 | + validateString(type, "Incorrect type " + type); | |
399 | + validatePageLink(pageLink); | |
400 | + return entityViewDao.findEntityViewsByTenantIdAndEdgeIdAndType(tenantId.getId(), edgeId.getId(), type, pageLink); | |
401 | + } | |
402 | + | |
393 | 403 | private DataValidator<EntityView> entityViewValidator = |
394 | 404 | new DataValidator<EntityView>() { |
395 | 405 | ... | ... |
... | ... | @@ -132,5 +132,16 @@ public interface AssetRepository extends PagingAndSortingRepository<AssetEntity, |
132 | 132 | @Param("searchText") String searchText, |
133 | 133 | Pageable pageable); |
134 | 134 | |
135 | + @Query("SELECT a FROM AssetEntity a, RelationEntity re WHERE a.tenantId = :tenantId " + | |
136 | + "AND a.id = re.toId AND re.toType = 'ASSET' AND re.relationTypeGroup = 'EDGE' " + | |
137 | + "AND re.relationType = 'Contains' AND re.fromId = :edgeId AND re.fromType = 'EDGE' " + | |
138 | + "AND a.type = :type " + | |
139 | + "AND LOWER(a.searchText) LIKE LOWER(CONCAT(:searchText, '%'))") | |
140 | + Page<AssetEntity> findByTenantIdAndEdgeIdAndType(@Param("tenantId") UUID tenantId, | |
141 | + @Param("edgeId") UUID edgeId, | |
142 | + @Param("type") String type, | |
143 | + @Param("searchText") String searchText, | |
144 | + Pageable pageable); | |
145 | + | |
135 | 146 | Long countByTenantIdAndTypeIsNot(UUID tenantId, String type); |
136 | 147 | } | ... | ... |
... | ... | @@ -200,6 +200,18 @@ public class JpaAssetDao extends JpaAbstractSearchTextDao<AssetEntity, Asset> im |
200 | 200 | } |
201 | 201 | |
202 | 202 | @Override |
203 | + public PageData<Asset> findAssetsByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, TimePageLink pageLink) { | |
204 | + log.debug("Try to find assets by tenantId [{}], edgeId [{}], type [{}] and pageLink [{}]", tenantId, edgeId, type, pageLink); | |
205 | + return DaoUtil.toPageData(assetRepository | |
206 | + .findByTenantIdAndEdgeIdAndType( | |
207 | + tenantId, | |
208 | + edgeId, | |
209 | + type, | |
210 | + Objects.toString(pageLink.getTextSearch(), ""), | |
211 | + DaoUtil.toPageable(pageLink))); | |
212 | + } | |
213 | + | |
214 | + @Override | |
203 | 215 | public Long countByTenantId(TenantId tenantId) { |
204 | 216 | return assetRepository.countByTenantIdAndTypeIsNot(tenantId.getId(), TB_SERVICE_QUEUE); |
205 | 217 | } | ... | ... |
... | ... | @@ -20,7 +20,6 @@ import org.springframework.data.domain.Pageable; |
20 | 20 | import org.springframework.data.jpa.repository.Query; |
21 | 21 | import org.springframework.data.repository.PagingAndSortingRepository; |
22 | 22 | import org.springframework.data.repository.query.Param; |
23 | -import org.thingsboard.server.dao.model.sql.AssetEntity; | |
24 | 23 | import org.thingsboard.server.dao.model.sql.DeviceEntity; |
25 | 24 | import org.thingsboard.server.dao.model.sql.DeviceInfoEntity; |
26 | 25 | ... | ... |
... | ... | @@ -129,4 +129,15 @@ public interface EntityViewRepository extends PagingAndSortingRepository<EntityV |
129 | 129 | @Param("edgeId") UUID edgeId, |
130 | 130 | @Param("searchText") String searchText, |
131 | 131 | Pageable pageable); |
132 | + | |
133 | + @Query("SELECT ev FROM EntityViewEntity ev, RelationEntity re WHERE ev.tenantId = :tenantId " + | |
134 | + "AND ev.id = re.toId AND re.toType = 'ENTITY_VIEW' AND re.relationTypeGroup = 'EDGE' " + | |
135 | + "AND re.relationType = 'Contains' AND re.fromId = :edgeId AND re.fromType = 'EDGE' " + | |
136 | + "AND ev.type = :type " + | |
137 | + "AND LOWER(ev.searchText) LIKE LOWER(CONCAT(:searchText, '%'))") | |
138 | + Page<EntityViewEntity> findByTenantIdAndEdgeIdAndType(@Param("tenantId") UUID tenantId, | |
139 | + @Param("edgeId") UUID edgeId, | |
140 | + @Param("type") String type, | |
141 | + @Param("searchText") String searchText, | |
142 | + Pageable pageable); | |
132 | 143 | } | ... | ... |
... | ... | @@ -192,4 +192,16 @@ public class JpaEntityViewDao extends JpaAbstractSearchTextDao<EntityViewEntity, |
192 | 192 | Objects.toString(pageLink.getTextSearch(), ""), |
193 | 193 | DaoUtil.toPageable(pageLink))); |
194 | 194 | } |
195 | + | |
196 | + @Override | |
197 | + public PageData<EntityView> findEntityViewsByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, PageLink pageLink) { | |
198 | + log.debug("Try to find entity views by tenantId [{}], edgeId [{}], type [{}] and pageLink [{}]", tenantId, edgeId, type, pageLink); | |
199 | + return DaoUtil.toPageData(entityViewRepository | |
200 | + .findByTenantIdAndEdgeIdAndType( | |
201 | + tenantId, | |
202 | + edgeId, | |
203 | + type, | |
204 | + Objects.toString(pageLink.getTextSearch(), ""), | |
205 | + DaoUtil.toPageable(pageLink))); | |
206 | + } | |
195 | 207 | } | ... | ... |
... | ... | @@ -99,7 +99,7 @@ export class AssetService { |
99 | 99 | return this.http.delete(`/api/edge/${edgeId}/asset/${assetId}`, defaultHttpOptionsFromConfig(config)); |
100 | 100 | } |
101 | 101 | |
102 | - public getEdgeAssets(edgeId, pageLink: PageLink, type: string = '', | |
102 | + public getEdgeAssets(edgeId: string, pageLink: PageLink, type: string = '', | |
103 | 103 | config?: RequestConfig): Observable<PageData<AssetInfo>> { |
104 | 104 | return this.http.get<PageData<AssetInfo>>(`/api/edge/${edgeId}/assets${pageLink.toQuery()}&type=${type}`, |
105 | 105 | defaultHttpOptionsFromConfig(config)); | ... | ... |
... | ... | @@ -76,12 +76,6 @@ export class EdgeService { |
76 | 76 | defaultHttpOptionsFromConfig(config)); |
77 | 77 | } |
78 | 78 | |
79 | - public setRootRuleChain(edgeId: string, ruleChainId: string, | |
80 | - config?: RequestConfig): Observable<Edge> { | |
81 | - return this.http.post<Edge>(`/api/edge/${edgeId}/${ruleChainId}/root`, | |
82 | - defaultHttpOptionsFromConfig(config)); | |
83 | - } | |
84 | - | |
85 | 79 | public getTenantEdgeInfos(pageLink: PageLink, type: string = '', |
86 | 80 | config?: RequestConfig): Observable<PageData<EdgeInfo>> { |
87 | 81 | return this.http.get<PageData<EdgeInfo>>(`/api/tenant/edgeInfos${pageLink.toQuery()}&type=${type}`, | ... | ... |
... | ... | @@ -44,6 +44,7 @@ import { TranslateService } from '@ngx-translate/core'; |
44 | 44 | import { EntityType } from '@shared/models/entity-type.models'; |
45 | 45 | import { deepClone, snakeCase } from '@core/utils'; |
46 | 46 | import { DebugRuleNodeEventBody } from '@app/shared/models/event.models'; |
47 | +import { Edge } from "@shared/models/edge.models"; | |
47 | 48 | |
48 | 49 | @Injectable({ |
49 | 50 | providedIn: 'root' |
... | ... | @@ -323,4 +324,9 @@ export class RuleChainService { |
323 | 324 | return this.http.get<Array<RuleChain>>(`/api/ruleChain/defaultEdgeRuleChains`, defaultHttpOptionsFromConfig(config)); |
324 | 325 | } |
325 | 326 | |
327 | + public setEdgeRootRuleChain(edgeId: string, ruleChainId: string, config?: RequestConfig): Observable<Edge> { //TODO deaflynx EdgeInfo vs. Edge check usage | |
328 | + return this.http.post<Edge>(`/api/edge/${edgeId}/${ruleChainId}/root`, | |
329 | + defaultHttpOptionsFromConfig(config)); | |
330 | + } | |
331 | + | |
326 | 332 | } | ... | ... |
... | ... | @@ -101,6 +101,17 @@ export class EntityFilterViewComponent implements ControlValueAccessor { |
101 | 101 | {deviceType}); |
102 | 102 | } |
103 | 103 | break; |
104 | + case AliasFilterType.edgeType: | |
105 | + const edgeType = this.filter.edgeType; | |
106 | + prefix = this.filter.edgeNameFilter; | |
107 | + if (prefix && prefix.length) { | |
108 | + this.filterDisplayValue = this.translate.instant('alias.filter-type-edge-type-and-name-description', | |
109 | + {edgeType, prefix}); | |
110 | + } else { | |
111 | + this.filterDisplayValue = this.translate.instant('alias.filter-type-edge-type-description', | |
112 | + {edgeType}); | |
113 | + } | |
114 | + break; | |
104 | 115 | case AliasFilterType.entityViewType: |
105 | 116 | const entityView = this.filter.entityViewType; |
106 | 117 | prefix = this.filter.entityViewNameFilter; |
... | ... | @@ -166,6 +177,7 @@ export class EntityFilterViewComponent implements ControlValueAccessor { |
166 | 177 | break; |
167 | 178 | case AliasFilterType.assetSearchQuery: |
168 | 179 | case AliasFilterType.deviceSearchQuery: |
180 | + case AliasFilterType.edgeSearchQuery: | |
169 | 181 | case AliasFilterType.entityViewSearchQuery: |
170 | 182 | allEntitiesText = this.translate.instant('alias.all-entities'); |
171 | 183 | anyRelationText = this.translate.instant('alias.any-relation'); |
... | ... | @@ -207,6 +219,16 @@ export class EntityFilterViewComponent implements ControlValueAccessor { |
207 | 219 | this.filterDisplayValue = this.translate.instant('alias.filter-type-device-search-query-description', |
208 | 220 | translationValues |
209 | 221 | ); |
222 | + } else if (this.filter.type === AliasFilterType.edgeSearchQuery) { | |
223 | + const edgeTypesQuoted = []; | |
224 | + this.filter.edgeTypes.forEach((filterEdgeType) => { | |
225 | + edgeTypesQuoted.push(`'${filterEdgeType}'`); | |
226 | + }); | |
227 | + const edgeTypesText = edgeTypesQuoted.join(', '); | |
228 | + translationValues.edgeTypes = edgeTypesText; | |
229 | + this.filterDisplayValue = this.translate.instant('alias.filter-type-edge-search-query-description', | |
230 | + translationValues | |
231 | + ); | |
210 | 232 | } else if (this.filter.type === AliasFilterType.entityViewSearchQuery) { |
211 | 233 | const entityViewTypesQuoted = []; |
212 | 234 | this.filter.entityViewTypes.forEach((filterEntityViewType) => { | ... | ... |
... | ... | @@ -103,6 +103,16 @@ |
103 | 103 | <input matInput formControlName="entityViewNameFilter"> |
104 | 104 | </mat-form-field> |
105 | 105 | </ng-template> |
106 | + <ng-template [ngSwitchCase]="aliasFilterType.edgeType"> | |
107 | + <tb-entity-subtype-autocomplete required | |
108 | + formControlName="edgeType" | |
109 | + [entityType]="entityType.EDGE"> | |
110 | + </tb-entity-subtype-autocomplete> | |
111 | + <mat-form-field class="mat-block"> | |
112 | + <mat-label translate>edge.name-starts-with</mat-label> | |
113 | + <input matInput formControlName="edgeNameFilter"> | |
114 | + </mat-form-field> | |
115 | + </ng-template> | |
106 | 116 | <ng-template [ngSwitchCase]="aliasFilterType.relationsQuery"> |
107 | 117 | <section fxLayout="column" id="relationsQueryFilter"> |
108 | 118 | <label class="tb-small">{{ 'alias.root-entity' | translate }}</label> |
... | ... | @@ -169,6 +179,7 @@ |
169 | 179 | </ng-template> |
170 | 180 | <ng-template [ngSwitchCase]="entityFilterFormGroup.get('type').value === aliasFilterType.assetSearchQuery || |
171 | 181 | entityFilterFormGroup.get('type').value === aliasFilterType.deviceSearchQuery || |
182 | + entityFilterFormGroup.get('type').value === aliasFilterType.edgeSearchQuery || | |
172 | 183 | entityFilterFormGroup.get('type').value === aliasFilterType.entityViewSearchQuery ? |
173 | 184 | entityFilterFormGroup.get('type').value : ''"> |
174 | 185 | <label class="tb-small">{{ 'alias.root-entity' | translate }}</label> |
... | ... | @@ -248,6 +259,14 @@ |
248 | 259 | formControlName="deviceTypes"> |
249 | 260 | </tb-entity-subtype-list> |
250 | 261 | </ng-template> |
262 | + <ng-template [ngSwitchCase]="aliasFilterType.edgeSearchQuery"> | |
263 | + <div class="mat-caption tb-required" style="color: rgba(0,0,0,0.57);" translate>edge.edge-types</div> | |
264 | + <tb-entity-subtype-list | |
265 | + required | |
266 | + [entityType]="entityType.EDGE" | |
267 | + formControlName="edgeTypes"> | |
268 | + </tb-entity-subtype-list> | |
269 | + </ng-template> | |
251 | 270 | <ng-template [ngSwitchCase]="aliasFilterType.entityViewSearchQuery"> |
252 | 271 | <div class="mat-caption tb-required" style="color: rgba(0,0,0,0.57);" translate>entity-view.entity-view-types</div> |
253 | 272 | <tb-entity-subtype-list | ... | ... |
... | ... | @@ -141,6 +141,12 @@ export class EntityFilterComponent implements ControlValueAccessor, OnInit { |
141 | 141 | deviceNameFilter: [filter ? filter.deviceNameFilter : '', []], |
142 | 142 | }); |
143 | 143 | break; |
144 | + case AliasFilterType.edgeType: | |
145 | + this.filterFormGroup = this.fb.group({ | |
146 | + edgeType: [filter ? filter.edgeType : null, [Validators.required]], | |
147 | + edgeNameFilter: [filter ? filter.edgeNameFilter : '', []], | |
148 | + }); | |
149 | + break; | |
144 | 150 | case AliasFilterType.entityViewType: |
145 | 151 | this.filterFormGroup = this.fb.group({ |
146 | 152 | entityViewType: [filter ? filter.entityViewType : null, [Validators.required]], |
... | ... | @@ -153,6 +159,7 @@ export class EntityFilterComponent implements ControlValueAccessor, OnInit { |
153 | 159 | case AliasFilterType.relationsQuery: |
154 | 160 | case AliasFilterType.assetSearchQuery: |
155 | 161 | case AliasFilterType.deviceSearchQuery: |
162 | + case AliasFilterType.edgeSearchQuery: | |
156 | 163 | case AliasFilterType.entityViewSearchQuery: |
157 | 164 | this.filterFormGroup = this.fb.group({ |
158 | 165 | rootStateEntity: [filter ? filter.rootStateEntity : false, []], |
... | ... | @@ -179,6 +186,9 @@ export class EntityFilterComponent implements ControlValueAccessor, OnInit { |
179 | 186 | } else if (type === AliasFilterType.deviceSearchQuery) { |
180 | 187 | this.filterFormGroup.addControl('deviceTypes', |
181 | 188 | this.fb.control(filter ? filter.deviceTypes : [], [Validators.required])); |
189 | + } else if (type === AliasFilterType.edgeSearchQuery) { | |
190 | + this.filterFormGroup.addControl('edgeTypes', | |
191 | + this.fb.control(filter ? filter.edgeTypes : [], [Validators.required])); | |
182 | 192 | } else if (type === AliasFilterType.entityViewSearchQuery) { |
183 | 193 | this.filterFormGroup.addControl('entityViewTypes', |
184 | 194 | this.fb.control(filter ? filter.entityViewTypes : [], [Validators.required])); | ... | ... |
... | ... | @@ -190,9 +190,9 @@ export class EventTableConfig extends EntityTableConfig<Event, TimePageLink> { |
190 | 190 | this.columns.push( |
191 | 191 | new EntityTableColumn<Event>('type', 'event.type', '100%', |
192 | 192 | (entity) => entity.type, entity => ({}), false), |
193 | - new EntityTableColumn<Event>('action', 'event.action', '100%', | |
193 | + new EntityTableColumn<Event>('action', 'edge.event-action', '100%', | |
194 | 194 | (entity) => entity.action, entity => ({}), false), |
195 | - new EntityTableColumn<Event>('entityId', 'event.entityId', '100%', | |
195 | + new EntityTableColumn<Event>('entityId', 'edge.entity-id', '100%', | |
196 | 196 | (entity) => entity.id.id, entity => ({}), false), //TODO: replace this to entity.entityId because of conflict wiht entityId model |
197 | 197 | new EntityTableColumn<Event>('status', 'event.status', '100%', |
198 | 198 | (entity) => this.updateEdgeEventStatus(entity.createdTime), | ... | ... |
... | ... | @@ -36,6 +36,12 @@ |
36 | 36 | </button> |
37 | 37 | <button mat-raised-button color="primary" |
38 | 38 | [disabled]="(isLoading$ | async)" |
39 | + (click)="onEntityAction($event, 'unassignFromEdge')" | |
40 | + [fxShow]="!isEdit && assetScope === 'edge'"> | |
41 | + {{ 'edge.unassign-from-edge' | translate }} | |
42 | + </button> | |
43 | + <button mat-raised-button color="primary" | |
44 | + [disabled]="(isLoading$ | async)" | |
39 | 45 | (click)="onEntityAction($event, 'delete')" |
40 | 46 | [fxShow]="!hideDelete() && !isEdit"> |
41 | 47 | {{'asset.delete' | translate }} | ... | ... |
... | ... | @@ -466,6 +466,9 @@ export class AssetsTableConfigResolver implements Resolve<EntityTableConfig<Asse |
466 | 466 | case 'unassignFromCustomer': |
467 | 467 | this.unassignFromCustomer(action.event, action.entity); |
468 | 468 | return true; |
469 | + case 'unassignFromEdge': | |
470 | + this.unassignFromEdge(action.event, action.entity); | |
471 | + return true; | |
469 | 472 | } |
470 | 473 | return false; |
471 | 474 | } | ... | ... |
... | ... | @@ -55,6 +55,12 @@ |
55 | 55 | </button> |
56 | 56 | <button mat-raised-button color="primary" |
57 | 57 | [disabled]="(isLoading$ | async)" |
58 | + (click)="onEntityAction($event, 'unassignFromEdge')" | |
59 | + [fxShow]="!isEdit && dashboardScope === 'edge'"> | |
60 | + {{ 'edge.unassign-from-edge' | translate }} | |
61 | + </button> | |
62 | + <button mat-raised-button color="primary" | |
63 | + [disabled]="(isLoading$ | async)" | |
58 | 64 | (click)="onEntityAction($event, 'delete')" |
59 | 65 | [fxShow]="!hideDelete() && !isEdit"> |
60 | 66 | {{'dashboard.delete' | translate }} | ... | ... |
... | ... | @@ -250,6 +250,12 @@ export class DashboardsTableConfigResolver implements Resolve<EntityTableConfig< |
250 | 250 | if (dashboardScope === 'edge') { |
251 | 251 | actions.push( |
252 | 252 | { |
253 | + name: this.translate.instant('dashboard.export'), | |
254 | + icon: 'file_download', | |
255 | + isEnabled: () => true, | |
256 | + onAction: ($event, entity) => this.exportDashboard($event, entity) | |
257 | + }, | |
258 | + { | |
253 | 259 | name: this.translate.instant('edge.unassign-from-edge'), |
254 | 260 | icon: 'portable_wifi_off', |
255 | 261 | isEnabled: (entity) => true, |
... | ... | @@ -351,7 +357,10 @@ export class DashboardsTableConfigResolver implements Resolve<EntityTableConfig< |
351 | 357 | } |
352 | 358 | if (this.config.componentsData.dashboardScope === 'customer') { |
353 | 359 | this.router.navigateByUrl(`customers/${this.config.componentsData.customerId}/dashboards/${dashboard.id.id}`); |
354 | - } else { | |
360 | + } else if (this.config.componentsData.dashboardScope === 'edge') { | |
361 | + this.router.navigateByUrl(`edges/${this.config.componentsData.edgeId}/dashboards/${dashboard.id.id}`); | |
362 | + } | |
363 | + else { | |
355 | 364 | this.router.navigateByUrl(`dashboards/${dashboard.id.id}`); |
356 | 365 | } |
357 | 366 | } |
... | ... | @@ -543,6 +552,9 @@ export class DashboardsTableConfigResolver implements Resolve<EntityTableConfig< |
543 | 552 | case 'unassignFromCustomer': |
544 | 553 | this.unassignFromCustomer(action.event, action.entity, this.config.componentsData.customerId); |
545 | 554 | return true; |
555 | + case 'unassignFromEdge': | |
556 | + this.unassignFromEdge(action.event, action.entity); | |
557 | + return true; | |
546 | 558 | } |
547 | 559 | return false; |
548 | 560 | } |
... | ... | @@ -572,7 +584,7 @@ export class DashboardsTableConfigResolver implements Resolve<EntityTableConfig< |
572 | 584 | $event.stopPropagation(); |
573 | 585 | } |
574 | 586 | this.dialogService.confirm( |
575 | - this.translate.instant('dashboard.unassign-dashboard-from-edge-title', {dashboardName: dashboard.name}), | |
587 | + this.translate.instant('dashboard.unassign-dashboard-title', {dashboardTitle: dashboard.title}), | |
576 | 588 | this.translate.instant('dashboard.unassign-dashboard-from-edge-text'), |
577 | 589 | this.translate.instant('action.no'), |
578 | 590 | this.translate.instant('action.yes'), | ... | ... |
... | ... | @@ -40,6 +40,12 @@ |
40 | 40 | [fxShow]="!isEdit"> |
41 | 41 | {{ (deviceScope === 'customer_user' ? 'device.view-credentials' : 'device.manage-credentials') | translate }} |
42 | 42 | </button> |
43 | + <button mat-raised-button color="primary" | |
44 | + [disabled]="(isLoading$ | async)" | |
45 | + (click)="onEntityAction($event, 'unassignFromEdge')" | |
46 | + [fxShow]="!isEdit && deviceScope === 'edge'"> | |
47 | + {{ 'edge.unassign-from-edge' | translate }} | |
48 | + </button> | |
43 | 49 | <button mat-raised-button color="primary" fxFlex.xs |
44 | 50 | [disabled]="(isLoading$ | async)" |
45 | 51 | (click)="onEntityAction($event, 'delete')" | ... | ... |
... | ... | @@ -544,6 +544,9 @@ export class DevicesTableConfigResolver implements Resolve<EntityTableConfig<Dev |
544 | 544 | case 'unassignFromCustomer': |
545 | 545 | this.unassignFromCustomer(action.event, action.entity); |
546 | 546 | return true; |
547 | + case 'unassignFromEdge': | |
548 | + this.unassignFromEdge(action.event, action.entity); | |
549 | + return true; | |
547 | 550 | case 'manageCredentials': |
548 | 551 | this.manageCredentials(action.event, action.entity); |
549 | 552 | return true; | ... | ... |
... | ... | @@ -24,6 +24,9 @@ import { DevicesTableConfigResolver } from "@home/pages/device/devices-table-con |
24 | 24 | import { EntityViewsTableConfigResolver } from "@home/pages/entity-view/entity-views-table-config.resolver"; |
25 | 25 | import { DashboardsTableConfigResolver } from "@home/pages/dashboard/dashboards-table-config.resolver"; |
26 | 26 | import { RuleChainsTableConfigResolver } from "@home/pages/rulechain/rulechains-table-config.resolver"; |
27 | +import { DashboardPageComponent } from "@home/pages/dashboard/dashboard-page.component"; | |
28 | +import { dashboardBreadcumbLabelFunction, DashboardResolver } from "@home/pages/dashboard/dashboard-routing.module"; | |
29 | +import { BreadCrumbConfig } from "@shared/components/breadcrumb"; | |
27 | 30 | |
28 | 31 | const routes: Routes = [ |
29 | 32 | { |
... | ... | @@ -53,7 +56,7 @@ const routes: Routes = [ |
53 | 56 | auth: [Authority.TENANT_ADMIN], |
54 | 57 | ruleChainsType: 'edge', |
55 | 58 | breadcrumb: { |
56 | - label: 'edge.rulechains', | |
59 | + label: 'rulechain.edge-rulechains', | |
57 | 60 | icon: 'settings_ethernet' |
58 | 61 | }, |
59 | 62 | }, |
... | ... | @@ -108,19 +111,43 @@ const routes: Routes = [ |
108 | 111 | }, |
109 | 112 | { |
110 | 113 | path: ':edgeId/dashboards', |
111 | - component: EntitiesTableComponent, | |
112 | 114 | data: { |
113 | - auth: [Authority.TENANT_ADMIN, Authority.CUSTOMER_USER], | |
114 | - dashboardsType: 'edge', | |
115 | 115 | breadcrumb: { |
116 | 116 | label: 'edge.dashboards', |
117 | 117 | icon: 'dashboard' |
118 | 118 | } |
119 | 119 | }, |
120 | - resolve: { | |
121 | - entitiesTableConfig: DashboardsTableConfigResolver | |
122 | - } | |
123 | - }] | |
120 | + children: [ | |
121 | + { | |
122 | + path: '', | |
123 | + component: EntitiesTableComponent, | |
124 | + data: { | |
125 | + auth: [Authority.TENANT_ADMIN], | |
126 | + dashboardsType: 'edge' | |
127 | + }, | |
128 | + resolve: { | |
129 | + entitiesTableConfig: DashboardsTableConfigResolver | |
130 | + }, | |
131 | + }, | |
132 | + { | |
133 | + path: ':dashboardId', | |
134 | + component: DashboardPageComponent, | |
135 | + data: { | |
136 | + breadcrumb: { | |
137 | + labelFunction: dashboardBreadcumbLabelFunction, | |
138 | + icon: 'dashboard' | |
139 | + } as BreadCrumbConfig<DashboardPageComponent>, | |
140 | + auth: [Authority.TENANT_ADMIN, Authority.CUSTOMER_USER], | |
141 | + title: 'edge.dashboard', | |
142 | + widgetEditMode: false | |
143 | + }, | |
144 | + resolve: { | |
145 | + dashboard: DashboardResolver | |
146 | + } | |
147 | + } | |
148 | + ] | |
149 | + }, | |
150 | + ] | |
124 | 151 | }] |
125 | 152 | |
126 | 153 | @NgModule({ | ... | ... |
... | ... | @@ -103,7 +103,8 @@ export class EdgesTableConfigResolver implements Resolve<EntityTableConfig<EdgeI |
103 | 103 | resolve(route: ActivatedRouteSnapshot): Observable<EntityTableConfig<EdgeInfo>> { |
104 | 104 | const routeParams = route.params; |
105 | 105 | this.config.componentsData = { |
106 | - edgeScope: route.data.edgesType | |
106 | + edgeScope: route.data.edgesType, | |
107 | + edgeType: '' | |
107 | 108 | }; |
108 | 109 | this.customerId = routeParams.customerId; |
109 | 110 | return this.store.pipe(select(selectAuthUser), take(1)).pipe( |
... | ... | @@ -152,7 +153,7 @@ export class EdgesTableConfigResolver implements Resolve<EntityTableConfig<EdgeI |
152 | 153 | new EntityTableColumn<EdgeInfo>('customerIsPublic', 'edge.public', '60px', |
153 | 154 | entity => { |
154 | 155 | return checkBoxCell(entity.customerIsPublic); |
155 | - }, () => ({}), false), | |
156 | + }, () => ({}), false) | |
156 | 157 | ); |
157 | 158 | } |
158 | 159 | return columns; |
... | ... | @@ -161,7 +162,7 @@ export class EdgesTableConfigResolver implements Resolve<EntityTableConfig<EdgeI |
161 | 162 | configureEntityFunctions(edgeScope: string): void { |
162 | 163 | if (edgeScope === 'tenant') { |
163 | 164 | this.config.entitiesFetchFunction = pageLink => |
164 | - this.edgeService.getTenantEdgeInfos(pageLink); | |
165 | + this.edgeService.getTenantEdgeInfos(pageLink, this.config.componentsData.edgeType); | |
165 | 166 | this.config.deleteEntity = id => this.edgeService.deleteEdge(id.id); |
166 | 167 | } |
167 | 168 | if (edgeScope === 'customer') { |
... | ... | @@ -176,10 +177,10 @@ export class EdgesTableConfigResolver implements Resolve<EntityTableConfig<EdgeI |
176 | 177 | if (edgeScope === 'tenant') { |
177 | 178 | actions.push( |
178 | 179 | { |
179 | - name: this.translate.instant('edge.make-public'), | |
180 | - icon: 'share', | |
181 | - isEnabled: (entity) => (!entity.customerId || entity.customerId.id === NULL_UUID), | |
182 | - onAction: ($event, entity) => this.makePublic($event, entity) | |
180 | + name: this.translate.instant('edge.make-public'), | |
181 | + icon: 'share', | |
182 | + isEnabled: (entity) => (!entity.customerId || entity.customerId.id === NULL_UUID), | |
183 | + onAction: ($event, entity) => this.makePublic($event, entity) | |
183 | 184 | }, |
184 | 185 | { |
185 | 186 | name: this.translate.instant('edge.assign-to-customer'), | ... | ... |
... | ... | @@ -36,6 +36,12 @@ |
36 | 36 | </button> |
37 | 37 | <button mat-raised-button color="primary" |
38 | 38 | [disabled]="(isLoading$ | async)" |
39 | + (click)="onEntityAction($event, 'unassignFromEdge')" | |
40 | + [fxShow]="!isEdit && entityViewScope === 'edge'"> | |
41 | + {{ 'edge.unassign-from-edge' | translate }} | |
42 | + </button> | |
43 | + <button mat-raised-button color="primary" | |
44 | + [disabled]="(isLoading$ | async)" | |
39 | 45 | (click)="onEntityAction($event, 'delete')" |
40 | 46 | [fxShow]="!hideDelete() && !isEdit"> |
41 | 47 | {{'entity-view.delete' | translate }} | ... | ... |
... | ... | @@ -441,6 +441,9 @@ export class EntityViewsTableConfigResolver implements Resolve<EntityTableConfig |
441 | 441 | case 'unassignFromCustomer': |
442 | 442 | this.unassignFromCustomer(action.event, action.entity); |
443 | 443 | return true; |
444 | + case 'unassignFromEdge': | |
445 | + this.unassignFromEdge(action.event, action.entity); | |
446 | + return true; | |
444 | 447 | } |
445 | 448 | return false; |
446 | 449 | } | ... | ... |
... | ... | @@ -210,7 +210,7 @@ const routes: Routes = [ |
210 | 210 | component: EntitiesTableComponent, |
211 | 211 | data: { |
212 | 212 | auth: [Authority.TENANT_ADMIN], |
213 | - title: 'edge.rulechains', | |
213 | + title: 'rulechain.edge-rulechains', | |
214 | 214 | ruleChainsType: 'edges' |
215 | 215 | }, |
216 | 216 | resolve: { |
... | ... | @@ -227,7 +227,7 @@ const routes: Routes = [ |
227 | 227 | icon: 'settings_ethernet' |
228 | 228 | } as BreadCrumbConfig<RuleChainPageComponent>, |
229 | 229 | auth: [Authority.TENANT_ADMIN], |
230 | - title: 'edge.rulechain', | |
230 | + title: 'rulechain.edge-rulechain', | |
231 | 231 | import: false, |
232 | 232 | ruleChainType: ruleChainType.edge |
233 | 233 | }, |
... | ... | @@ -248,7 +248,7 @@ const routes: Routes = [ |
248 | 248 | icon: 'settings_ethernet' |
249 | 249 | } as BreadCrumbConfig<RuleChainPageComponent>, |
250 | 250 | auth: [Authority.TENANT_ADMIN], |
251 | - title: 'edge.rulechain', | |
251 | + title: 'rulechain.edge-rulechain', | |
252 | 252 | import: true, |
253 | 253 | ruleChainType: ruleChainType.edge |
254 | 254 | }, | ... | ... |
... | ... | @@ -31,7 +31,19 @@ |
31 | 31 | <button mat-raised-button color="primary" |
32 | 32 | [disabled]="(isLoading$ | async)" |
33 | 33 | (click)="onEntityAction($event, 'setRoot')" |
34 | - [fxShow]="!isEdit && !entity?.root"> | |
34 | + [fxShow]="!isEdit && !entity?.root && ruleChainScope === 'tenant'"> | |
35 | + {{'rulechain.set-root' | translate }} | |
36 | + </button> | |
37 | + <button mat-raised-button color="primary" | |
38 | + [disabled]="(isLoading$ | async)" | |
39 | + (click)="onEntityAction($event, 'setDefaultRoot')" | |
40 | + [fxShow]="!isEdit && !entity?.root && ruleChainScope === 'edges'"> | |
41 | + {{'rulechain.set-default-root-edge' | translate }} | |
42 | + </button> | |
43 | + <button mat-raised-button color="primary" | |
44 | + [disabled]="(isLoading$ | async)" | |
45 | + (click)="onEntityAction($event, 'setRoot')" | |
46 | + [fxShow]="!isEdit && !isRootRuleChain() && ruleChainScope === 'edge'"> | |
35 | 47 | {{'rulechain.set-root' | translate }} |
36 | 48 | </button> |
37 | 49 | <button mat-raised-button color="primary" | ... | ... |
... | ... | @@ -31,6 +31,8 @@ import { EntityTableConfig } from '@home/models/entity/entities-table-config.mod |
31 | 31 | }) |
32 | 32 | export class RuleChainComponent extends EntityComponent<RuleChain> { |
33 | 33 | |
34 | + ruleChainScope: 'tenant' | 'edges' | 'edge'; | |
35 | + | |
34 | 36 | constructor(protected store: Store<AppState>, |
35 | 37 | protected translate: TranslateService, |
36 | 38 | @Inject('entity') protected entityValue: RuleChain, |
... | ... | @@ -39,6 +41,11 @@ export class RuleChainComponent extends EntityComponent<RuleChain> { |
39 | 41 | super(store, fb, entityValue, entitiesTableConfigValue); |
40 | 42 | } |
41 | 43 | |
44 | + ngOnInit() { | |
45 | + this.ruleChainScope = this.entitiesTableConfig.componentsData.ruleChainScope; | |
46 | + super.ngOnInit(); | |
47 | + } | |
48 | + | |
42 | 49 | hideDelete() { |
43 | 50 | if (this.entitiesTableConfig) { |
44 | 51 | return !this.entitiesTableConfig.deleteEnabled(this.entity); |
... | ... | @@ -78,4 +85,12 @@ export class RuleChainComponent extends EntityComponent<RuleChain> { |
78 | 85 | horizontalPosition: 'right' |
79 | 86 | })); |
80 | 87 | } |
88 | + | |
89 | + isRootRuleChain() { | |
90 | + if (this.entitiesTableConfig && this.entityValue) { | |
91 | + return this.entitiesTableConfig.componentsData.rootRuleChainId == this.entityValue.id.id; | |
92 | + } else { | |
93 | + return false; | |
94 | + } | |
95 | + } | |
81 | 96 | } | ... | ... |
... | ... | @@ -20,7 +20,7 @@ import {ActivatedRouteSnapshot, Resolve, Route, Router} from '@angular/router'; |
20 | 20 | import { |
21 | 21 | CellActionDescriptor, |
22 | 22 | checkBoxCell, |
23 | - DateEntityTableColumn, | |
23 | + DateEntityTableColumn, EntityColumn, | |
24 | 24 | EntityTableColumn, |
25 | 25 | EntityTableConfig, |
26 | 26 | GroupActionDescriptor, HeaderActionDescriptor |
... | ... | @@ -37,7 +37,7 @@ import { RuleChainTabsComponent } from '@home/pages/rulechain/rulechain-tabs.com |
37 | 37 | import { ImportExportService } from '@home/components/import-export/import-export.service'; |
38 | 38 | import { ItemBufferService } from '@core/services/item-buffer.service'; |
39 | 39 | import { EdgeService } from "@core/http/edge.service"; |
40 | -import { map } from "rxjs/operators"; | |
40 | +import {map, mergeMap} from "rxjs/operators"; | |
41 | 41 | import { forkJoin, Observable } from "rxjs"; |
42 | 42 | import { |
43 | 43 | AddEntitiesToEdgeDialogComponent, |
... | ... | @@ -69,18 +69,6 @@ export class RuleChainsTableConfigResolver implements Resolve<EntityTableConfig< |
69 | 69 | this.config.entityTranslations = entityTypeTranslations.get(EntityType.RULE_CHAIN); |
70 | 70 | this.config.entityResources = entityTypeResources.get(EntityType.RULE_CHAIN); |
71 | 71 | |
72 | - this.config.columns.push( | |
73 | - new DateEntityTableColumn<RuleChain>('createdTime', 'common.created-time', this.datePipe, '150px'), | |
74 | - new EntityTableColumn<RuleChain>('name', 'rulechain.name', '100%'), | |
75 | - new EntityTableColumn<RuleChain>('root', 'rulechain.root', '60px', | |
76 | - entity => { | |
77 | - if (isDefined(this.config.componentsData.edgeId)) { | |
78 | - return checkBoxCell((this.config.componentsData.edge.rootRuleChainId.id == entity.id.id)); | |
79 | - } else { | |
80 | - return checkBoxCell(entity.root); | |
81 | - } | |
82 | - }) | |
83 | - ); | |
84 | 72 | this.config.deleteEntityTitle = ruleChain => this.translate.instant('rulechain.delete-rulechain-title', |
85 | 73 | { ruleChainName: ruleChain.name }); |
86 | 74 | this.config.deleteEntityContent = () => this.translate.instant('rulechain.delete-rulechain-text'); |
... | ... | @@ -98,25 +86,56 @@ export class RuleChainsTableConfigResolver implements Resolve<EntityTableConfig< |
98 | 86 | ruleChainScope: route.data.ruleChainsType, |
99 | 87 | edgeId: routeParams.edgeId |
100 | 88 | }; |
101 | - if (this.config.componentsData.edgeId) { | |
89 | + this.config.columns = this.configureEntityTableColumns(this.config.componentsData.ruleChainScope); | |
90 | + this.configureEntityFunctions(this.config.componentsData.ruleChainScope); | |
91 | + this.config.groupActionDescriptors = this.configureGroupActions(this.config.componentsData.ruleChainScope); | |
92 | + this.config.addActionDescriptors = this.configureAddActions(this.config.componentsData.ruleChainScope); | |
93 | + this.config.cellActionDescriptors = this.configureCellActions(this.config.componentsData.ruleChainScope); | |
94 | + if (this.config.componentsData.ruleChainScope === 'tenant' || this.config.componentsData.ruleChainScope === 'edges') { | |
95 | + this.config.entitySelectionEnabled = ruleChain => ruleChain && !ruleChain.root; | |
96 | + this.config.deleteEnabled = (ruleChain) => ruleChain && !ruleChain.root; | |
97 | + this.config.entitiesDeleteEnabled = true; | |
98 | + } | |
99 | + else if (this.config.componentsData.ruleChainScope === 'edge') { | |
102 | 100 | this.config.entitySelectionEnabled = ruleChain => this.config.componentsData.edge.rootRuleChainId.id != ruleChain.id.id; |
103 | - this.config.deleteEnabled = () => false; | |
104 | 101 | this.edgeService.getEdge(this.config.componentsData.edgeId).subscribe(edge => { |
105 | 102 | this.config.componentsData.edge = edge; |
106 | 103 | this.config.tableTitle = edge.name + ': ' + this.translate.instant('rulechain.edge-rulechains'); |
107 | 104 | }); |
105 | + this.config.entitiesDeleteEnabled = false; | |
108 | 106 | } |
109 | - else { | |
110 | - this.config.entitySelectionEnabled = ruleChain => ruleChain && !ruleChain.root; | |
111 | - this.config.deleteEnabled = (ruleChain) => ruleChain && !ruleChain.root; | |
112 | - } | |
113 | - this.configureEntityFunctions(this.config.componentsData.ruleChainScope); | |
114 | - this.config.groupActionDescriptors = this.configureGroupActions(this.config.componentsData.ruleChainScope); | |
115 | - this.config.addActionDescriptors = this.configureAddActions(this.config.componentsData.ruleChainScope); | |
116 | - this.config.cellActionDescriptors = this.configureCellActions(this.config.componentsData.ruleChainScope); | |
117 | 107 | return this.config; |
118 | 108 | } |
119 | 109 | |
110 | + configureEntityTableColumns(ruleChainScope: string): Array<EntityColumn<RuleChain>> { | |
111 | + const columns: Array<EntityColumn<RuleChain>> = []; | |
112 | + if (ruleChainScope === 'tenant' || ruleChainScope === 'edge') { | |
113 | + columns.push( | |
114 | + new DateEntityTableColumn<RuleChain>('createdTime', 'common.created-time', this.datePipe, '150px'), | |
115 | + new EntityTableColumn<RuleChain>('name', 'rulechain.name', '100%'), | |
116 | + new EntityTableColumn<RuleChain>('root', 'rulechain.root', '60px', | |
117 | + entity => { | |
118 | + if (ruleChainScope === 'edge') { | |
119 | + return checkBoxCell((this.config.componentsData.edge.rootRuleChainId.id == entity.id.id)); | |
120 | + } else { | |
121 | + return checkBoxCell(entity.root); | |
122 | + } | |
123 | + }) | |
124 | + ); | |
125 | + } | |
126 | + if (ruleChainScope === 'edges') { | |
127 | + columns.push( | |
128 | + new DateEntityTableColumn<RuleChain>('createdTime', 'common.created-time', this.datePipe, '150px'), | |
129 | + new EntityTableColumn<RuleChain>('name', 'rulechain.name', '100%'), | |
130 | + new EntityTableColumn<RuleChain>('root', 'rulechain.default-root', '60px', | |
131 | + entity => { | |
132 | + return checkBoxCell(entity.root); | |
133 | + }) | |
134 | + ); | |
135 | + } | |
136 | + return columns; | |
137 | + } | |
138 | + | |
120 | 139 | configureAddActions(ruleChainScope: string): Array<HeaderActionDescriptor> { |
121 | 140 | const actions: Array<HeaderActionDescriptor> = []; |
122 | 141 | if (ruleChainScope === 'tenant' || ruleChainScope === 'edges') { |
... | ... | @@ -293,8 +312,8 @@ export class RuleChainsTableConfigResolver implements Resolve<EntityTableConfig< |
293 | 312 | true |
294 | 313 | ).subscribe((res) => { |
295 | 314 | if (res) { |
296 | - if (this.config.componentsData.edgeId) { | |
297 | - this.edgeService.setRootRuleChain(this.config.componentsData.edgeId, ruleChain.id.id).subscribe( | |
315 | + if (this.config.componentsData.ruleChainScope === 'edge') { | |
316 | + this.ruleChainService.setEdgeRootRuleChain(this.config.componentsData.edgeId, ruleChain.id.id).subscribe( | |
298 | 317 | (edge) => { |
299 | 318 | this.config.componentsData.edge = edge; |
300 | 319 | this.config.table.updateData(); |
... | ... | @@ -323,6 +342,9 @@ export class RuleChainsTableConfigResolver implements Resolve<EntityTableConfig< |
323 | 342 | case 'setRoot': |
324 | 343 | this.setRootRuleChain(action.event, action.entity); |
325 | 344 | return true; |
345 | + case 'setDefaultRoot': | |
346 | + this.setDefaultRootEdgeRuleChain(action.event, action.entity); | |
347 | + return true; | |
326 | 348 | } |
327 | 349 | return false; |
328 | 350 | } |
... | ... | @@ -465,18 +487,18 @@ export class RuleChainsTableConfigResolver implements Resolve<EntityTableConfig< |
465 | 487 | } |
466 | 488 | |
467 | 489 | isNonRootRuleChain(ruleChain: RuleChain) { |
468 | - if (this.config.componentsData.edgeId) { | |
490 | + if (this.config.componentsData.ruleChainScope === 'edge') { | |
469 | 491 | return (isDefined(this.config.componentsData.edge.rootRuleChainId) && this.config.componentsData.edge.rootRuleChainId != null && this.config.componentsData.edge.rootRuleChainId.id != ruleChain.id.id); |
470 | 492 | } |
471 | 493 | return (isDefined(ruleChain)) && !ruleChain.root; |
472 | 494 | } |
473 | 495 | |
474 | 496 | isDefaultEdgeRuleChain(ruleChain) { |
475 | - return (isDefined(ruleChain)) && !ruleChain.root && ruleChain.isDefault; | |
497 | + return (isDefined(ruleChain)) && !ruleChain.root && this.config.componentsData.defaultEdgeRuleChainIds.includes(ruleChain.id.id); | |
476 | 498 | } |
477 | 499 | |
478 | 500 | isNonDefaultEdgeRuleChain(ruleChain) { |
479 | - return (isDefined(ruleChain)) && !ruleChain.root && !ruleChain.isDefault; | |
501 | + return (isDefined(ruleChain)) && !ruleChain.root && !this.config.componentsData.defaultEdgeRuleChainIds.includes(ruleChain.id.id); | |
480 | 502 | } |
481 | 503 | |
482 | 504 | fetchRuleChains(pageLink: PageLink) { |
... | ... | @@ -484,17 +506,10 @@ export class RuleChainsTableConfigResolver implements Resolve<EntityTableConfig< |
484 | 506 | } |
485 | 507 | |
486 | 508 | fetchEdgeRuleChains(pageLink: PageLink) { |
487 | - let defaultEdgeRuleChainIds: Array<string> = []; | |
509 | + this.config.componentsData.defaultEdgeRuleChainIds = []; | |
488 | 510 | this.ruleChainService.getDefaultEdgeRuleChains().subscribe(ruleChains => { |
489 | - ruleChains.map(ruleChain => defaultEdgeRuleChainIds.push(ruleChain.id.id)) | |
511 | + ruleChains.map(ruleChain => this.config.componentsData.defaultEdgeRuleChainIds.push(ruleChain.id.id)); | |
490 | 512 | }); |
491 | - return this.ruleChainService.getRuleChains(pageLink, ruleChainType.edge).pipe( | |
492 | - map(response => { | |
493 | - response.data.map(ruleChain => | |
494 | - ruleChain.isDefault = defaultEdgeRuleChainIds.some(id => ruleChain.id.id.includes(id)) | |
495 | - ); | |
496 | - return response; | |
497 | - }) | |
498 | - ); | |
513 | + return this.ruleChainService.getRuleChains(pageLink, ruleChainType.edge); | |
499 | 514 | } |
500 | 515 | } | ... | ... |
... | ... | @@ -143,9 +143,10 @@ export class EntitySubTypeListComponent implements ControlValueAccessor, OnInit, |
143 | 143 | break; |
144 | 144 | case EntityType.EDGE: |
145 | 145 | this.placeholder = this.required ? this.translate.instant('edge.enter-edge-type') |
146 | - : this.translate.instant('edge.edge-any-edge'); | |
146 | + : this.translate.instant('edge.any-edge'); | |
147 | 147 | this.secondaryPlaceholder = '+' + this.translate.instant('edge.edge-type'); |
148 | 148 | this.noSubtypesMathingText = 'edge.no-edge-types-matching'; |
149 | + this.subtypeListEmptyText = 'edge.edge-type-list-empty'; | |
149 | 150 | this.broadcastSubscription = this.broadcast.on('edgeSaved', () => { |
150 | 151 | this.entitySubtypes = null; |
151 | 152 | }); | ... | ... |
... | ... | @@ -1179,8 +1179,6 @@ |
1179 | 1179 | "unassign-from-edge": "Unassign from edge", |
1180 | 1180 | "dashboards": "Edge Dashboards", |
1181 | 1181 | "manage-edge-rulechains": "Manage edge rule chains", |
1182 | - "rulechains": "Edge Rule Chains", | |
1183 | - "rulechain": "Edge Rule Chain", | |
1184 | 1182 | "edge-key": "Edge key", |
1185 | 1183 | "copy-edge-key": "Copy Edge key", |
1186 | 1184 | "edge-key-copied-message": "Edge key has been copied to clipboard", |
... | ... | @@ -1204,6 +1202,9 @@ |
1204 | 1202 | "enter-edge-type": "Enter entity view type", |
1205 | 1203 | "any-edge": "Any edge", |
1206 | 1204 | "no-edge-types-matching": "No edge types matching '{{entitySubtype}}' were found.", |
1205 | + "edge-type-list-empty": "No device types selected.", | |
1206 | + "edge-types": "Edge types", | |
1207 | + "dashboard": "Edge dashboard", | |
1207 | 1208 | "unassign-edges-action-title": "Unassign { count, plural, 1 {1 edge} other {# edges} } from customer" |
1208 | 1209 | }, |
1209 | 1210 | "error": { |
... | ... | @@ -2035,6 +2036,7 @@ |
2035 | 2036 | "open-rulechain": "Open rule chain", |
2036 | 2037 | "assign-new-rulechain": "Assign new rulechain", |
2037 | 2038 | "edge-rulechains": "Edge Rule chains", |
2039 | + "edge-rulechain": "Edge Rule chain", | |
2038 | 2040 | "core-rulechains": "Core Rule chains", |
2039 | 2041 | "unassign-rulechain-from-edge-text": "After the confirmation the rulechain will be unassigned and won't be accessible by the edge.", |
2040 | 2042 | "unassign-rulechains-from-edge-title": "Unassign { count, plural, 1 {1 rulechain} other {# rulechains} } from edge", |
... | ... | @@ -2054,7 +2056,8 @@ |
2054 | 2056 | "unassign-rulechain-title": "Are you sure you want to unassign the rulechain '{{ruleChainName}}'?", |
2055 | 2057 | "unassign-rulechains-title": "Are you sure you want to unassign { count, plural, 1 {1 rulechain} other {# rulechains} }?", |
2056 | 2058 | "unassign-rulechains": "Unassign rulechains", |
2057 | - "default": "Default" | |
2059 | + "default": "Default", | |
2060 | + "default-root": "Default root" | |
2058 | 2061 | }, |
2059 | 2062 | "rulenode": { |
2060 | 2063 | "details": "Details", | ... | ... |
... | ... | @@ -194,7 +194,7 @@ export default function EdgeRoutes($stateProvider, types) { |
194 | 194 | }, |
195 | 195 | data: { |
196 | 196 | searchEnabled: true, |
197 | - pageTitle: 'edge.rulechains', | |
197 | + pageTitle: 'rulechain.edge-rulechains', | |
198 | 198 | ruleChainsType: 'edge' |
199 | 199 | }, |
200 | 200 | ncyBreadcrumb: { | ... | ... |