Showing
16 changed files
with
255 additions
and
27 deletions
... | ... | @@ -57,6 +57,14 @@ export class AppComponent implements OnInit { |
57 | 57 | '0,10 0 0,1 2,12A10,10 0 0,1 12,2Z" /></svg>' |
58 | 58 | ) |
59 | 59 | ); |
60 | + this.matIconRegistry.addSvgIconLiteral( | |
61 | + 'alpha-e-circle-outline', | |
62 | + this.domSanitizer.bypassSecurityTrustHtml( | |
63 | + '<svg viewBox="0 0 24 24"><path d="M9,7H15V9H11V11H15V13H11V15H15V17H9V7M12,2A10,10 0 0,'+ | |
64 | + '1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 ' + | |
65 | + '0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4Z" /></svg>' | |
66 | + ) | |
67 | + ); | |
60 | 68 | |
61 | 69 | this.storageService.testLocalStorage(); |
62 | 70 | ... | ... |
... | ... | @@ -50,6 +50,8 @@ import { AlarmSourceListener } from '@core/http/alarm.service'; |
50 | 50 | import { DatasourceListener } from '@core/api/datasource.service'; |
51 | 51 | import * as deepEqual from 'deep-equal'; |
52 | 52 | import { EntityId } from '@app/shared/models/id/entity-id'; |
53 | +import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; | |
54 | +import { entityFields } from '@shared/models/entity.models'; | |
53 | 55 | |
54 | 56 | export class WidgetSubscription implements IWidgetSubscription { |
55 | 57 | |
... | ... | @@ -342,6 +344,12 @@ export class WidgetSubscription implements IWidgetSubscription { |
342 | 344 | dataKey, |
343 | 345 | data: [] |
344 | 346 | }; |
347 | + if (dataKey.type === DataKeyType.entityField && datasource.entity) { | |
348 | + const propName = entityFields[dataKey.name] ? entityFields[dataKey.name].value : dataKey.name; | |
349 | + if (datasource.entity[propName]) { | |
350 | + datasourceData.data.push([Date.now(), datasource.entity[propName]]); | |
351 | + } | |
352 | + } | |
345 | 353 | this.data.push(datasourceData); |
346 | 354 | this.hiddenData.push({data: []}); |
347 | 355 | if (this.displayLegend) { |
... | ... | @@ -682,8 +690,15 @@ export class WidgetSubscription implements IWidgetSubscription { |
682 | 690 | }, |
683 | 691 | datasourceIndex: index |
684 | 692 | }; |
693 | + | |
694 | + let entityFieldKey = false; | |
695 | + | |
685 | 696 | for (let a = 0; a < datasource.dataKeys.length; a++) { |
686 | - this.data[index + a].data = []; | |
697 | + if (datasource.dataKeys[a].type !== DataKeyType.entityField) { | |
698 | + this.data[index + a].data = []; | |
699 | + } else { | |
700 | + entityFieldKey = true; | |
701 | + } | |
687 | 702 | } |
688 | 703 | index += datasource.dataKeys.length; |
689 | 704 | this.datasourceListeners.push(listener); |
... | ... | @@ -691,7 +706,7 @@ export class WidgetSubscription implements IWidgetSubscription { |
691 | 706 | if (datasource.dataKeys.length) { |
692 | 707 | this.ctx.datasourceService.subscribeToDatasource(listener); |
693 | 708 | } |
694 | - if (datasource.unresolvedStateEntity || | |
709 | + if (datasource.unresolvedStateEntity || entityFieldKey || | |
695 | 710 | !datasource.dataKeys.length || |
696 | 711 | (datasource.type === DatasourceType.entity && !datasource.entityId) |
697 | 712 | ) { | ... | ... |
... | ... | @@ -45,11 +45,11 @@ export class AttributeService { |
45 | 45 | defaultHttpOptionsFromConfig(config)); |
46 | 46 | } |
47 | 47 | |
48 | - public deleteEntityTimeseries(entityId: EntityId, timeseries: Array<AttributeData>, | |
48 | + public deleteEntityTimeseries(entityId: EntityId, timeseries: Array<AttributeData>, deleteAllDataForKeys = false, | |
49 | 49 | config?: RequestConfig): Observable<any> { |
50 | 50 | const keys = timeseries.map(attribute => attribute.key).join(','); |
51 | 51 | return this.http.delete(`/api/plugins/telemetry/${entityId.entityType}/${entityId.id}/timeseries/delete` + |
52 | - `?keys=${keys}`, | |
52 | + `?keys=${keys}&deleteAllDataForKeys=${deleteAllDataForKeys}`, | |
53 | 53 | defaultHttpOptionsFromConfig(config)); |
54 | 54 | } |
55 | 55 | |
... | ... | @@ -93,7 +93,7 @@ export class AttributeService { |
93 | 93 | }); |
94 | 94 | let deleteEntityTimeseriesObservable: Observable<any>; |
95 | 95 | if (deleteTimeseries.length) { |
96 | - deleteEntityTimeseriesObservable = this.deleteEntityTimeseries(entityId, deleteTimeseries, config); | |
96 | + deleteEntityTimeseriesObservable = this.deleteEntityTimeseries(entityId, deleteTimeseries, true, config); | |
97 | 97 | } else { |
98 | 98 | deleteEntityTimeseriesObservable = of(null); |
99 | 99 | } | ... | ... |
... | ... | @@ -20,7 +20,13 @@ import { Observable, ReplaySubject } from 'rxjs'; |
20 | 20 | import { HttpClient } from '@angular/common/http'; |
21 | 21 | import { PageLink } from '@shared/models/page/page-link'; |
22 | 22 | import { PageData } from '@shared/models/page/page-data'; |
23 | -import { Device, DeviceCredentials, DeviceInfo, DeviceSearchQuery } from '@app/shared/models/device.models'; | |
23 | +import { | |
24 | + ClaimRequest, ClaimResult, | |
25 | + Device, | |
26 | + DeviceCredentials, | |
27 | + DeviceInfo, | |
28 | + DeviceSearchQuery | |
29 | +} from '@app/shared/models/device.models'; | |
24 | 30 | import { EntitySubtype } from '@app/shared/models/entity-type.models'; |
25 | 31 | import { AuthService } from '@core/auth/auth.service'; |
26 | 32 | |
... | ... | @@ -127,4 +133,13 @@ export class DeviceService { |
127 | 133 | return this.http.get<Device>(`/api/tenant/devices?deviceName=${deviceName}`, defaultHttpOptionsFromConfig(config)); |
128 | 134 | } |
129 | 135 | |
136 | + public claimDevice(deviceName: string, claimRequest: ClaimRequest, | |
137 | + config?: RequestConfig): Observable<ClaimResult> { | |
138 | + return this.http.post<ClaimResult>(`api/customer/device/${deviceName}/claim`, claimRequest, defaultHttpOptionsFromConfig(config)); | |
139 | + } | |
140 | + | |
141 | + public unclaimDevice(deviceName: string, config?: RequestConfig) { | |
142 | + return this.http.delete(`/api/customer/device/${deviceName}/claim`, defaultHttpOptionsFromConfig(config)); | |
143 | + } | |
144 | + | |
130 | 145 | } | ... | ... |
... | ... | @@ -44,7 +44,7 @@ import { AliasInfo, StateParams, SubscriptionInfo } from '@core/api/widget-api.m |
44 | 44 | import { Datasource, DatasourceType, KeyInfo } from '@app/shared/models/widget.models'; |
45 | 45 | import { UtilsService } from '@core/services/utils.service'; |
46 | 46 | import { AliasFilterType, EntityAlias, EntityAliasFilter, EntityAliasFilterResult } from '@shared/models/alias.models'; |
47 | -import { EntityInfo, ImportEntitiesResultInfo, ImportEntityData } from '@shared/models/entity.models'; | |
47 | +import { entityFields, EntityInfo, ImportEntitiesResultInfo, ImportEntityData } from '@shared/models/entity.models'; | |
48 | 48 | import { |
49 | 49 | EntityRelationInfo, |
50 | 50 | EntityRelationsQuery, |
... | ... | @@ -503,8 +503,50 @@ export class EntityService { |
503 | 503 | return entityTypes; |
504 | 504 | } |
505 | 505 | |
506 | + private getEntityFieldKeys (entityType: EntityType, searchText: string): Array<string> { | |
507 | + const entityFieldKeys: string[] = []; | |
508 | + const query = searchText.toLowerCase(); | |
509 | + switch(entityType) { | |
510 | + case EntityType.USER: | |
511 | + entityFieldKeys.push(entityFields.name.keyName); | |
512 | + entityFieldKeys.push(entityFields.email.keyName); | |
513 | + entityFieldKeys.push(entityFields.firstName.keyName); | |
514 | + entityFieldKeys.push(entityFields.lastName.keyName); | |
515 | + break; | |
516 | + case EntityType.TENANT: | |
517 | + case EntityType.CUSTOMER: | |
518 | + entityFieldKeys.push(entityFields.title.keyName); | |
519 | + entityFieldKeys.push(entityFields.email.keyName); | |
520 | + entityFieldKeys.push(entityFields.country.keyName); | |
521 | + entityFieldKeys.push(entityFields.state.keyName); | |
522 | + entityFieldKeys.push(entityFields.city.keyName); | |
523 | + entityFieldKeys.push(entityFields.address.keyName); | |
524 | + entityFieldKeys.push(entityFields.address2.keyName); | |
525 | + entityFieldKeys.push(entityFields.zip.keyName); | |
526 | + entityFieldKeys.push(entityFields.phone.keyName); | |
527 | + break; | |
528 | + case EntityType.ENTITY_VIEW: | |
529 | + entityFieldKeys.push(entityFields.name.keyName); | |
530 | + entityFieldKeys.push(entityFields.type.keyName); | |
531 | + break; | |
532 | + case EntityType.DEVICE: | |
533 | + case EntityType.ASSET: | |
534 | + entityFieldKeys.push(entityFields.name.keyName); | |
535 | + entityFieldKeys.push(entityFields.type.keyName); | |
536 | + entityFieldKeys.push(entityFields.label.keyName); | |
537 | + break; | |
538 | + case EntityType.DASHBOARD: | |
539 | + entityFieldKeys.push(entityFields.title.keyName); | |
540 | + break; | |
541 | + } | |
542 | + return query ? entityFieldKeys.filter((entityField) => entityField.toLowerCase().indexOf(query) === 0) : entityFieldKeys; | |
543 | + } | |
544 | + | |
506 | 545 | public getEntityKeys(entityId: EntityId, query: string, type: DataKeyType, |
507 | 546 | config?: RequestConfig): Observable<Array<string>> { |
547 | + if (type === DataKeyType.entityField) { | |
548 | + return of(this.getEntityFieldKeys(entityId.entityType as EntityType, query)); | |
549 | + } | |
508 | 550 | let url = `/api/plugins/telemetry/${entityId.entityType}/${entityId.id}/keys/`; |
509 | 551 | if (type === DataKeyType.timeseries) { |
510 | 552 | url += 'timeseries'; |
... | ... | @@ -588,7 +630,8 @@ export class EntityService { |
588 | 630 | if (filter.stateEntityParamName && filter.stateEntityParamName.length) { |
589 | 631 | result.entityParamName = filter.stateEntityParamName; |
590 | 632 | } |
591 | - const stateEntityId = this.getStateEntityId(filter, stateParams); | |
633 | + const stateEntityInfo = this.getStateEntityInfo(filter, stateParams); | |
634 | + const stateEntityId = stateEntityInfo.entityId; | |
592 | 635 | switch (filter.type) { |
593 | 636 | case AliasFilterType.singleEntity: |
594 | 637 | const aliasEntityId = this.resolveAliasEntityId(filter.singleEntity.entityType, filter.singleEntity.id); |
... | ... | @@ -697,7 +740,8 @@ export class EntityService { |
697 | 740 | parameters: { |
698 | 741 | rootId: relationQueryRootEntityId.id, |
699 | 742 | rootType: relationQueryRootEntityId.entityType as EntityType, |
700 | - direction: filter.direction | |
743 | + direction: filter.direction, | |
744 | + fetchLastLevelOnly: filter.fetchLastLevelOnly | |
701 | 745 | }, |
702 | 746 | filters: filter.filters |
703 | 747 | }; |
... | ... | @@ -741,10 +785,12 @@ export class EntityService { |
741 | 785 | parameters: { |
742 | 786 | rootId: searchQueryRootEntityId.id, |
743 | 787 | rootType: searchQueryRootEntityId.entityType as EntityType, |
744 | - direction: filter.direction | |
788 | + direction: filter.direction, | |
789 | + fetchLastLevelOnly: filter.fetchLastLevelOnly | |
745 | 790 | }, |
746 | 791 | relationType: filter.relationType |
747 | 792 | }; |
793 | + searchQuery.parameters.maxLevel = filter.maxLevel && filter.maxLevel > 0 ? filter.maxLevel : -1; | |
748 | 794 | let findByQueryObservable: Observable<Array<BaseData<EntityId>>>; |
749 | 795 | if (filter.type === AliasFilterType.assetSearchQuery) { |
750 | 796 | const assetSearchQuery = searchQuery as AssetSearchQuery; |
... | ... | @@ -988,8 +1034,8 @@ export class EntityService { |
988 | 1034 | ); |
989 | 1035 | } |
990 | 1036 | |
991 | - private getStateEntityId(filter: EntityAliasFilter, stateParams: StateParams): EntityId { | |
992 | - let entityId = null; | |
1037 | + private getStateEntityInfo(filter: EntityAliasFilter, stateParams: StateParams): {entityId: EntityId} { | |
1038 | + let entityId: EntityId = null; | |
993 | 1039 | if (stateParams) { |
994 | 1040 | if (filter.stateEntityParamName && filter.stateEntityParamName.length) { |
995 | 1041 | if (stateParams[filter.stateEntityParamName]) { |
... | ... | @@ -1005,7 +1051,7 @@ export class EntityService { |
1005 | 1051 | if (entityId) { |
1006 | 1052 | entityId = this.resolveAliasEntityId(entityId.entityType, entityId.id); |
1007 | 1053 | } |
1008 | - return entityId; | |
1054 | + return {entityId}; | |
1009 | 1055 | } |
1010 | 1056 | |
1011 | 1057 | private resolveAliasEntityId(entityType: EntityType | AliasEntityType, id: string): EntityId { | ... | ... |
... | ... | @@ -133,6 +133,14 @@ |
133 | 133 | </tb-entity-select> |
134 | 134 | </div> |
135 | 135 | </div> |
136 | + <div fxFlex fxLayout="row"> | |
137 | + <section class="tb-root-state-entity-switch" fxLayout="row" fxLayoutAlign="start center" style="padding-left: 0px;"> | |
138 | + <mat-slide-toggle class="root-state-entity-switch" | |
139 | + formControlName="fetchLastLevelOnly"> | |
140 | + </mat-slide-toggle> | |
141 | + <label class="tb-small root-state-entity-label" translate>alias.last-level-relation</label> | |
142 | + </section> | |
143 | + </div> | |
136 | 144 | <div fxFlex fxLayoutGap="8px" fxLayout="row"> |
137 | 145 | <mat-form-field class="mat-block" style="min-width: 100px;"> |
138 | 146 | <mat-label translate>relation.direction</mat-label> |
... | ... | @@ -191,6 +199,14 @@ |
191 | 199 | </tb-entity-select> |
192 | 200 | </div> |
193 | 201 | </div> |
202 | + <div fxFlex fxLayout="row"> | |
203 | + <section class="tb-root-state-entity-switch" fxLayout="row" fxLayoutAlign="start center" style="padding-left: 0px;"> | |
204 | + <mat-slide-toggle class="root-state-entity-switch" | |
205 | + formControlName="fetchLastLevelOnly"> | |
206 | + </mat-slide-toggle> | |
207 | + <label class="tb-small root-state-entity-label" translate>alias.last-level-relation</label> | |
208 | + </section> | |
209 | + </div> | |
194 | 210 | <div fxFlex fxLayoutGap="8px" fxLayout="row"> |
195 | 211 | <mat-form-field class="mat-block" style="min-width: 100px;"> |
196 | 212 | <mat-label translate>relation.direction</mat-label> | ... | ... |
... | ... | @@ -165,6 +165,7 @@ export class EntityFilterComponent implements ControlValueAccessor, OnInit { |
165 | 165 | rootEntity: [filter ? filter.rootEntity : null, (filter && filter.rootStateEntity) ? [] : [Validators.required]], |
166 | 166 | direction: [filter ? filter.direction : EntitySearchDirection.FROM, [Validators.required]], |
167 | 167 | maxLevel: [filter ? filter.maxLevel : 1, []], |
168 | + fetchLastLevelOnly: [filter ? filter.fetchLastLevelOnly : false, []] | |
168 | 169 | }); |
169 | 170 | this.filterFormGroup.get('rootStateEntity').valueChanges.subscribe((rootStateEntity: boolean) => { |
170 | 171 | this.filterFormGroup.get('rootEntity').setValidators(rootStateEntity ? [] : [Validators.required]); | ... | ... |
... | ... | @@ -38,6 +38,12 @@ |
38 | 38 | <mat-icon class="tb-mat-20" |
39 | 39 | svgIcon="alpha-a-circle-outline"></mat-icon> |
40 | 40 | </span> |
41 | + <span *ngIf="key.type === dataKeyTypes.entityField" | |
42 | + matTooltip="{{'datakey.entity-field' | translate }}" | |
43 | + matTooltipPosition="above"> | |
44 | + <mat-icon class="tb-mat-20" | |
45 | + svgIcon="alpha-e-circle-outline"></mat-icon> | |
46 | + </span> | |
41 | 47 | <span *ngIf="key.type === dataKeyTypes.timeseries" |
42 | 48 | matTooltip="{{'datakey.timeseries' | translate }}" |
43 | 49 | matTooltipPosition="above"> |
... | ... | @@ -87,6 +93,12 @@ |
87 | 93 | <mat-icon class="tb-mat-16" |
88 | 94 | svgIcon="alpha-a-circle-outline"></mat-icon> |
89 | 95 | </span> |
96 | + <span *ngIf="key.type === dataKeyTypes.entityField" | |
97 | + matTooltip="{{'datakey.entity-field' | translate }}" | |
98 | + matTooltipPosition="above"> | |
99 | + <mat-icon class="tb-mat-16" | |
100 | + svgIcon="alpha-e-circle-outline"></mat-icon> | |
101 | + </span> | |
90 | 102 | <span *ngIf="key.type === dataKeyTypes.timeseries" |
91 | 103 | matTooltip="{{'datakey.timeseries' | translate }}" |
92 | 104 | matTooltipPosition="above"> |
... | ... | @@ -114,15 +126,22 @@ |
114 | 126 | <span *ngIf="widgetType == widgetTypes.latest" |
115 | 127 | matTooltip="{{'datakey.attributes' | translate }}" |
116 | 128 | matTooltipPosition="above"> |
117 | - <mat-icon (click)="createKey(searchText, dataKeyTypes.attribute)" | |
129 | + <mat-icon (click)="createKey(searchText, dataKeyTypes.attribute)" | |
118 | 130 | class="tb-mat-16" |
119 | 131 | svgIcon="alpha-a-circle-outline"></mat-icon> |
120 | - </span> | |
132 | + </span> | |
133 | + <span *ngIf="widgetType == widgetTypes.latest" | |
134 | + matTooltip="{{'datakey.entity-field' | translate }}" | |
135 | + matTooltipPosition="above"> | |
136 | + <mat-icon (click)="createKey(searchText, dataKeyTypes.entityField)" | |
137 | + class="tb-mat-16" | |
138 | + svgIcon="alpha-e-circle-outline"></mat-icon> | |
139 | + </span> | |
121 | 140 | <span matTooltip="{{'datakey.timeseries' | translate }}" |
122 | 141 | matTooltipPosition="above"> |
123 | - <mat-icon (click)="createKey(searchText, dataKeyTypes.timeseries)" | |
142 | + <mat-icon (click)="createKey(searchText, dataKeyTypes.timeseries)" | |
124 | 143 | class="tb-mat-16">timeline</mat-icon> |
125 | - </span> | |
144 | + </span> | |
126 | 145 | </ng-template> |
127 | 146 | </ng-template> |
128 | 147 | </div> | ... | ... |
... | ... | @@ -420,6 +420,7 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, AfterVie |
420 | 420 | const dataKeyTypes = [DataKeyType.timeseries]; |
421 | 421 | if (this.widgetType === widgetType.latest) { |
422 | 422 | dataKeyTypes.push(DataKeyType.attribute); |
423 | + dataKeyTypes.push(DataKeyType.entityField); | |
423 | 424 | } |
424 | 425 | fetchObservable = this.callbacks.fetchEntityKeys(this.entityAliasId, this.searchText, dataKeyTypes); |
425 | 426 | } else { | ... | ... |
... | ... | @@ -14,7 +14,7 @@ |
14 | 14 | /// limitations under the License. |
15 | 15 | /// |
16 | 16 | |
17 | -import { ChangeDetectionStrategy, Component, forwardRef, Input, OnInit } from '@angular/core'; | |
17 | +import { Component, forwardRef, Input, OnInit } from '@angular/core'; | |
18 | 18 | import { PageComponent } from '@shared/components/page.component'; |
19 | 19 | import { Store } from '@ngrx/store'; |
20 | 20 | import { AppState } from '@core/core.state'; |
... | ... | @@ -22,12 +22,11 @@ import { |
22 | 22 | DataKey, |
23 | 23 | Datasource, |
24 | 24 | DatasourceType, |
25 | - datasourceTypeTranslationMap, defaultLegendConfig, | |
26 | - WidgetActionDescriptor, | |
25 | + datasourceTypeTranslationMap, | |
26 | + defaultLegendConfig, | |
27 | 27 | widgetType |
28 | 28 | } from '@shared/models/widget.models'; |
29 | 29 | import { |
30 | - AbstractControl, | |
31 | 30 | ControlValueAccessor, |
32 | 31 | FormArray, |
33 | 32 | FormBuilder, |
... | ... | @@ -58,7 +57,8 @@ import { MatDialog } from '@angular/material/dialog'; |
58 | 57 | import { EntityService } from '@core/http/entity.service'; |
59 | 58 | import { JsonFormComponentData } from '@shared/components/json-form/json-form-component.models'; |
60 | 59 | import { WidgetActionsData } from './action/manage-widget-actions.component.models'; |
61 | -import { Dashboard, DashboardState } from '@shared/models/dashboard.models'; | |
60 | +import { DashboardState } from '@shared/models/dashboard.models'; | |
61 | +import { entityFields } from '@shared/models/entity.models'; | |
62 | 62 | |
63 | 63 | const emptySettingsSchema = { |
64 | 64 | type: 'object', |
... | ... | @@ -621,10 +621,10 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont |
621 | 621 | return chip; |
622 | 622 | } else { |
623 | 623 | let label: string = chip; |
624 | - if (type === DataKeyType.alarm) { | |
625 | - const alarmField = alarmFields[label]; | |
626 | - if (alarmField) { | |
627 | - label = this.translate.instant(alarmField.name); | |
624 | + if (type === DataKeyType.alarm || type === DataKeyType.entityField) { | |
625 | + const keyField = type === DataKeyType.alarm ? alarmFields[label] : entityFields[chip];; | |
626 | + if (keyField) { | |
627 | + label = this.translate.instant(keyField.name); | |
628 | 628 | } |
629 | 629 | } |
630 | 630 | label = this.genNextLabel(label); | ... | ... |
... | ... | @@ -91,6 +91,7 @@ export interface RelationsQueryFilter { |
91 | 91 | direction?: EntitySearchDirection; |
92 | 92 | filters?: Array<EntityTypeFilter>; |
93 | 93 | maxLevel?: number; |
94 | + fetchLastLevelOnly?: boolean; | |
94 | 95 | } |
95 | 96 | |
96 | 97 | export interface EntitySearchQueryFilter { |
... | ... | @@ -100,6 +101,8 @@ export interface EntitySearchQueryFilter { |
100 | 101 | rootEntity?: EntityId; |
101 | 102 | relationType?: string; |
102 | 103 | direction?: EntitySearchDirection; |
104 | + maxLevel?: number; | |
105 | + fetchLastLevelOnly?: boolean; | |
103 | 106 | } |
104 | 107 | |
105 | 108 | export interface AssetSearchQueryFilter extends EntitySearchQueryFilter { | ... | ... |
... | ... | @@ -57,3 +57,18 @@ export interface DeviceCredentials extends BaseData<DeviceCredentialsId> { |
57 | 57 | export interface DeviceSearchQuery extends EntitySearchQuery { |
58 | 58 | deviceTypes: Array<string>; |
59 | 59 | } |
60 | + | |
61 | +export interface ClaimRequest { | |
62 | + secretKey: string; | |
63 | +} | |
64 | + | |
65 | +export enum ClaimResponse { | |
66 | + SUCCESS = 'SUCCESS', | |
67 | + FAILURE = 'FAILURE', | |
68 | + CLAIMED = 'CLAIMED' | |
69 | +} | |
70 | + | |
71 | +export interface ClaimResult { | |
72 | + device: Device, | |
73 | + response: ClaimResponse | |
74 | +} | ... | ... |
... | ... | @@ -53,3 +53,89 @@ export interface ImportEntitiesResultInfo { |
53 | 53 | entity: number; |
54 | 54 | }; |
55 | 55 | } |
56 | + | |
57 | +export interface EntityField { | |
58 | + keyName: string; | |
59 | + value: string; | |
60 | + name: string; | |
61 | + time?: boolean; | |
62 | +} | |
63 | + | |
64 | +export const entityFields: {[fieldName: string]: EntityField} = { | |
65 | + createdTime: { | |
66 | + keyName: 'createdTime', | |
67 | + name: 'entity-field.created-time', | |
68 | + value: 'createdTime', | |
69 | + time: true | |
70 | + }, | |
71 | + name: { | |
72 | + keyName: 'name', | |
73 | + name: 'entity-field.name', | |
74 | + value: 'name' | |
75 | + }, | |
76 | + type: { | |
77 | + keyName: 'type', | |
78 | + name: 'entity-field.type', | |
79 | + value: 'type' | |
80 | + }, | |
81 | + firstName: { | |
82 | + keyName: 'firstName', | |
83 | + name: 'entity-field.first-name', | |
84 | + value: 'firstName' | |
85 | + }, | |
86 | + lastName: { | |
87 | + keyName: 'lastName', | |
88 | + name: 'entity-field.last-name', | |
89 | + value: 'lastName' | |
90 | + }, | |
91 | + email: { | |
92 | + keyName: 'email', | |
93 | + name: 'entity-field.email', | |
94 | + value: 'email' | |
95 | + }, | |
96 | + title: { | |
97 | + keyName: 'title', | |
98 | + name: 'entity-field.title', | |
99 | + value: 'title' | |
100 | + }, | |
101 | + country: { | |
102 | + keyName: 'country', | |
103 | + name: 'entity-field.country', | |
104 | + value: 'country' | |
105 | + }, | |
106 | + state: { | |
107 | + keyName: 'state', | |
108 | + name: 'entity-field.state', | |
109 | + value: 'state' | |
110 | + }, | |
111 | + city: { | |
112 | + keyName: 'city', | |
113 | + name: 'entity-field.city', | |
114 | + value: 'city' | |
115 | + }, | |
116 | + address: { | |
117 | + keyName: 'address', | |
118 | + name: 'entity-field.address', | |
119 | + value: 'address' | |
120 | + }, | |
121 | + address2: { | |
122 | + keyName: 'address2', | |
123 | + name: 'entity-field.address2', | |
124 | + value: 'address2' | |
125 | + }, | |
126 | + zip: { | |
127 | + keyName: 'zip', | |
128 | + name: 'entity-field.zip', | |
129 | + value: 'zip' | |
130 | + }, | |
131 | + phone: { | |
132 | + keyName: 'phone', | |
133 | + name: 'entity-field.phone', | |
134 | + value: 'phone' | |
135 | + }, | |
136 | + label: { | |
137 | + keyName: 'label', | |
138 | + name: 'entity-field.label', | |
139 | + value: 'label' | |
140 | + } | |
141 | +}; | ... | ... |