Entity Admin widgets. Introduce updateAliases method of alias controller.
This commit is contained in:
parent
1d960b96bc
commit
1157df05e9
File diff suppressed because one or more lines are too long
@ -95,6 +95,7 @@ public abstract class AbstractAssetEntity<T extends Asset> extends BaseSqlEntity
|
|||||||
this.customerId = assetEntity.getCustomerId();
|
this.customerId = assetEntity.getCustomerId();
|
||||||
this.type = assetEntity.getType();
|
this.type = assetEntity.getType();
|
||||||
this.name = assetEntity.getName();
|
this.name = assetEntity.getName();
|
||||||
|
this.label = assetEntity.getLabel();
|
||||||
this.searchText = assetEntity.getSearchText();
|
this.searchText = assetEntity.getSearchText();
|
||||||
this.additionalInfo = assetEntity.getAdditionalInfo();
|
this.additionalInfo = assetEntity.getAdditionalInfo();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,7 +26,7 @@ import { map } from 'rxjs/operators';
|
|||||||
|
|
||||||
export class AliasController implements IAliasController {
|
export class AliasController implements IAliasController {
|
||||||
|
|
||||||
private entityAliasesChangedSubject = new Subject<Array<string>>();
|
entityAliasesChangedSubject = new Subject<Array<string>>();
|
||||||
entityAliasesChanged: Observable<Array<string>> = this.entityAliasesChangedSubject.asObservable();
|
entityAliasesChanged: Observable<Array<string>> = this.entityAliasesChangedSubject.asObservable();
|
||||||
|
|
||||||
private entityAliasResolvedSubject = new Subject<string>();
|
private entityAliasResolvedSubject = new Subject<string>();
|
||||||
@ -69,6 +69,23 @@ export class AliasController implements IAliasController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateAliases(aliasIds?: Array<string>) {
|
||||||
|
if (!aliasIds) {
|
||||||
|
aliasIds = [];
|
||||||
|
for (const aliasId of Object.keys(this.resolvedAliases)) {
|
||||||
|
aliasIds.push(aliasId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const tasks: Observable<AliasInfo>[] = [];
|
||||||
|
for (const aliasId of aliasIds) {
|
||||||
|
this.setAliasUnresolved(aliasId);
|
||||||
|
tasks.push(this.getAliasInfo(aliasId));
|
||||||
|
}
|
||||||
|
forkJoin(tasks).subscribe(() => {
|
||||||
|
this.entityAliasesChangedSubject.next(aliasIds);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
dashboardStateChanged() {
|
dashboardStateChanged() {
|
||||||
const changedAliasIds: Array<string> = [];
|
const changedAliasIds: Array<string> = [];
|
||||||
for (const aliasId of Object.keys(this.resolvedAliasesToStateEntities)) {
|
for (const aliasId of Object.keys(this.resolvedAliasesToStateEntities)) {
|
||||||
@ -85,7 +102,7 @@ export class AliasController implements IAliasController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private setAliasUnresolved(aliasId: string) {
|
setAliasUnresolved(aliasId: string) {
|
||||||
delete this.resolvedAliases[aliasId];
|
delete this.resolvedAliases[aliasId];
|
||||||
delete this.resolvedAliasesObservable[aliasId];
|
delete this.resolvedAliasesObservable[aliasId];
|
||||||
delete this.resolvedAliasesToStateEntities[aliasId];
|
delete this.resolvedAliasesToStateEntities[aliasId];
|
||||||
@ -225,7 +242,7 @@ export class AliasController implements IAliasController {
|
|||||||
resolveAlarmSource(alarmSource: Datasource): Observable<Datasource> {
|
resolveAlarmSource(alarmSource: Datasource): Observable<Datasource> {
|
||||||
return this.resolveDatasource(alarmSource, true).pipe(
|
return this.resolveDatasource(alarmSource, true).pipe(
|
||||||
map((datasources) => {
|
map((datasources) => {
|
||||||
const datasource = datasources[0];
|
const datasource = datasources && datasources.length ? datasources[0] : deepClone(alarmSource);
|
||||||
if (datasource.type === DatasourceType.function) {
|
if (datasource.type === DatasourceType.function) {
|
||||||
let name: string;
|
let name: string;
|
||||||
if (datasource.name && datasource.name.length) {
|
if (datasource.name && datasource.name.length) {
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
/// limitations under the License.
|
/// limitations under the License.
|
||||||
///
|
///
|
||||||
|
|
||||||
import { Observable } from 'rxjs';
|
import { Observable, Subject } from 'rxjs';
|
||||||
import { EntityId } from '@app/shared/models/id/entity-id';
|
import { EntityId } from '@app/shared/models/id/entity-id';
|
||||||
import {
|
import {
|
||||||
DataSet,
|
DataSet,
|
||||||
@ -99,6 +99,7 @@ export interface IAliasController {
|
|||||||
getEntityAliases(): EntityAliases;
|
getEntityAliases(): EntityAliases;
|
||||||
updateCurrentAliasEntity(aliasId: string, currentEntity: EntityInfo);
|
updateCurrentAliasEntity(aliasId: string, currentEntity: EntityInfo);
|
||||||
updateEntityAliases(entityAliases: EntityAliases);
|
updateEntityAliases(entityAliases: EntityAliases);
|
||||||
|
updateAliases(aliasIds?: Array<string>);
|
||||||
dashboardStateChanged();
|
dashboardStateChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,6 +219,7 @@ export interface SubscriptionEntityInfo {
|
|||||||
|
|
||||||
export interface IWidgetSubscription {
|
export interface IWidgetSubscription {
|
||||||
|
|
||||||
|
options: WidgetSubscriptionOptions;
|
||||||
id: string;
|
id: string;
|
||||||
init$: Observable<IWidgetSubscription>;
|
init$: Observable<IWidgetSubscription>;
|
||||||
ctx: WidgetSubscriptionContext;
|
ctx: WidgetSubscriptionContext;
|
||||||
|
|||||||
@ -127,7 +127,7 @@ export class WidgetSubscription implements IWidgetSubscription {
|
|||||||
targetDeviceName: string;
|
targetDeviceName: string;
|
||||||
executingSubjects: Array<Subject<any>>;
|
executingSubjects: Array<Subject<any>>;
|
||||||
|
|
||||||
constructor(subscriptionContext: WidgetSubscriptionContext, options: WidgetSubscriptionOptions) {
|
constructor(subscriptionContext: WidgetSubscriptionContext, public options: WidgetSubscriptionOptions) {
|
||||||
const subscriptionSubject = new ReplaySubject<IWidgetSubscription>();
|
const subscriptionSubject = new ReplaySubject<IWidgetSubscription>();
|
||||||
this.init$ = subscriptionSubject.asObservable();
|
this.init$ = subscriptionSubject.asObservable();
|
||||||
this.ctx = subscriptionContext;
|
this.ctx = subscriptionContext;
|
||||||
@ -878,8 +878,8 @@ export class WidgetSubscription implements IWidgetSubscription {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private checkAlarmSource(aliasIds: Array<string>): boolean {
|
private checkAlarmSource(aliasIds: Array<string>): boolean {
|
||||||
if (this.alarmSource && this.alarmSource.entityAliasId) {
|
if (this.options.alarmSource && this.options.alarmSource.entityAliasId) {
|
||||||
return aliasIds.indexOf(this.alarmSource.entityAliasId) > -1;
|
return aliasIds.indexOf(this.options.alarmSource.entityAliasId) > -1;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -887,14 +887,17 @@ export class WidgetSubscription implements IWidgetSubscription {
|
|||||||
|
|
||||||
private checkSubscriptions(aliasIds: Array<string>): boolean {
|
private checkSubscriptions(aliasIds: Array<string>): boolean {
|
||||||
let subscriptionsChanged = false;
|
let subscriptionsChanged = false;
|
||||||
for (const listener of this.datasourceListeners) {
|
const datasources = this.options.datasources;
|
||||||
if (listener.datasource.entityAliasId) {
|
if (datasources) {
|
||||||
if (aliasIds.indexOf(listener.datasource.entityAliasId) > -1) {
|
for (const datasource of datasources) {
|
||||||
|
if (datasource.entityAliasId) {
|
||||||
|
if (aliasIds.indexOf(datasource.entityAliasId) > -1) {
|
||||||
subscriptionsChanged = true;
|
subscriptionsChanged = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return subscriptionsChanged;
|
return subscriptionsChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import { forkJoin, Observable, of } from 'rxjs';
|
|||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { EntityId } from '@shared/models/id/entity-id';
|
import { EntityId } from '@shared/models/id/entity-id';
|
||||||
import { AttributeData, AttributeScope } from '@shared/models/telemetry/telemetry.models';
|
import { AttributeData, AttributeScope } from '@shared/models/telemetry/telemetry.models';
|
||||||
|
import { isDefinedAndNotNull } from '@core/utils';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -31,10 +32,12 @@ export class AttributeService {
|
|||||||
) { }
|
) { }
|
||||||
|
|
||||||
public getEntityAttributes(entityId: EntityId, attributeScope: AttributeScope,
|
public getEntityAttributes(entityId: EntityId, attributeScope: AttributeScope,
|
||||||
config?: RequestConfig): Observable<Array<AttributeData>> {
|
keys?: Array<string>, config?: RequestConfig): Observable<Array<AttributeData>> {
|
||||||
return this.http.get<Array<AttributeData>>(`/api/plugins/telemetry/${entityId.entityType}/${entityId.id}/values/attributes/` +
|
let url = `/api/plugins/telemetry/${entityId.entityType}/${entityId.id}/values/attributes/${attributeScope}`;
|
||||||
`${attributeScope}`,
|
if (keys && keys.length) {
|
||||||
defaultHttpOptionsFromConfig(config));
|
url += `?keys=${keys.join(',')}`;
|
||||||
|
}
|
||||||
|
return this.http.get<Array<AttributeData>>(url, defaultHttpOptionsFromConfig(config));
|
||||||
}
|
}
|
||||||
|
|
||||||
public deleteEntityAttributes(entityId: EntityId, attributeScope: AttributeScope, attributes: Array<AttributeData>,
|
public deleteEntityAttributes(entityId: EntityId, attributeScope: AttributeScope, attributes: Array<AttributeData>,
|
||||||
@ -58,7 +61,7 @@ export class AttributeService {
|
|||||||
const attributesData: {[key: string]: any} = {};
|
const attributesData: {[key: string]: any} = {};
|
||||||
const deleteAttributes: AttributeData[] = [];
|
const deleteAttributes: AttributeData[] = [];
|
||||||
attributes.forEach((attribute) => {
|
attributes.forEach((attribute) => {
|
||||||
if (attribute.value !== null) {
|
if (isDefinedAndNotNull(attribute.value)) {
|
||||||
attributesData[attribute.key] = attribute.value;
|
attributesData[attribute.key] = attribute.value;
|
||||||
} else {
|
} else {
|
||||||
deleteAttributes.push(attribute);
|
deleteAttributes.push(attribute);
|
||||||
@ -85,7 +88,7 @@ export class AttributeService {
|
|||||||
const timeseriesData: {[key: string]: any} = {};
|
const timeseriesData: {[key: string]: any} = {};
|
||||||
const deleteTimeseries: AttributeData[] = [];
|
const deleteTimeseries: AttributeData[] = [];
|
||||||
timeseries.forEach((attribute) => {
|
timeseries.forEach((attribute) => {
|
||||||
if (attribute.value !== null) {
|
if (isDefinedAndNotNull(attribute.value)) {
|
||||||
timeseriesData[attribute.key] = attribute.value;
|
timeseriesData[attribute.key] = attribute.value;
|
||||||
} else {
|
} else {
|
||||||
deleteTimeseries.push(attribute);
|
deleteTimeseries.push(attribute);
|
||||||
|
|||||||
@ -109,15 +109,20 @@ export class CustomActionPrettyResourcesTabsComponent extends PageComponent impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
private validate(): boolean {
|
private validate(): boolean {
|
||||||
|
if (this.action.customResources) {
|
||||||
for (const resource of this.action.customResources) {
|
for (const resource of this.action.customResources) {
|
||||||
if (!resource.url) {
|
if (!resource.url) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public addResource() {
|
public addResource() {
|
||||||
|
if (!this.action.customResources) {
|
||||||
|
this.action.customResources = [];
|
||||||
|
}
|
||||||
this.action.customResources.push({url: ''});
|
this.action.customResources.push({url: ''});
|
||||||
this.notifyActionUpdated();
|
this.notifyActionUpdated();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,7 +28,7 @@ import { PageLink } from '@shared/models/page/page-link';
|
|||||||
import { catchError, map, publishReplay, refCount, share, take, tap } from 'rxjs/operators';
|
import { catchError, map, publishReplay, refCount, share, take, tap } from 'rxjs/operators';
|
||||||
import { entityTypeTranslations } from '@shared/models/entity-type.models';
|
import { entityTypeTranslations } from '@shared/models/entity-type.models';
|
||||||
import { UtilsService } from '@core/services/utils.service';
|
import { UtilsService } from '@core/services/utils.service';
|
||||||
import { deepClone, isUndefined } from '@core/utils';
|
import { deepClone, isDefined, isUndefined } from '@core/utils';
|
||||||
|
|
||||||
import customSampleJs from '!raw-loader!./custom-sample-js.raw';
|
import customSampleJs from '!raw-loader!./custom-sample-js.raw';
|
||||||
import customSampleCss from '!raw-loader!./custom-sample-css.raw';
|
import customSampleCss from '!raw-loader!./custom-sample-css.raw';
|
||||||
@ -72,7 +72,7 @@ export function toCustomAction(action: WidgetActionDescriptorInfo): CustomAction
|
|||||||
customFunction: action.customFunction
|
customFunction: action.customFunction
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
result.customResources = action ? deepClone(action.customResources) : [];
|
result.customResources = action && isDefined(action.customResources) ? deepClone(action.customResources) : [];
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -102,8 +102,4 @@ export class DynamicWidgetComponent extends PageComponent implements IDynamicWid
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
widgetForceReInit() {
|
|
||||||
this.ctx.widgetForceReInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -304,7 +304,7 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni
|
|||||||
|
|
||||||
const dataKeys: Array<DataKey> = [];
|
const dataKeys: Array<DataKey> = [];
|
||||||
|
|
||||||
const datasource = this.subscription.datasources[0];
|
const datasource = this.subscription.options.datasources ? this.subscription.options.datasources[0] : null;
|
||||||
|
|
||||||
if (datasource) {
|
if (datasource) {
|
||||||
datasource.dataKeys.forEach((entityDataKey) => {
|
datasource.dataKeys.forEach((entityDataKey) => {
|
||||||
|
|||||||
@ -263,7 +263,6 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI
|
|||||||
this.widgetContext.servicesMap = ServicesMap;
|
this.widgetContext.servicesMap = ServicesMap;
|
||||||
this.widgetContext.isEdit = this.isEdit;
|
this.widgetContext.isEdit = this.isEdit;
|
||||||
this.widgetContext.isMobile = this.isMobile;
|
this.widgetContext.isMobile = this.isMobile;
|
||||||
this.widgetContext.widgetForceReInit = this.reInit.bind(this);
|
|
||||||
|
|
||||||
this.widgetContext.subscriptionApi = {
|
this.widgetContext.subscriptionApi = {
|
||||||
createSubscription: this.createSubscription.bind(this),
|
createSubscription: this.createSubscription.bind(this),
|
||||||
@ -1096,7 +1095,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI
|
|||||||
this.cssParser.createStyleElement(actionNamespace, customCss, 'nonamespace');
|
this.cssParser.createStyleElement(actionNamespace, customCss, 'nonamespace');
|
||||||
}
|
}
|
||||||
const resourceTasks: Observable<string>[] = [];
|
const resourceTasks: Observable<string>[] = [];
|
||||||
if (customResources.length > 0) {
|
if (isDefined(customResources) && customResources.length > 0) {
|
||||||
customResources.forEach((resource) => {
|
customResources.forEach((resource) => {
|
||||||
resourceTasks.push(
|
resourceTasks.push(
|
||||||
this.resources.loadResource(resource.url).pipe(
|
this.resources.loadResource(resource.url).pipe(
|
||||||
|
|||||||
@ -14,7 +14,6 @@
|
|||||||
/// limitations under the License.
|
/// limitations under the License.
|
||||||
///
|
///
|
||||||
|
|
||||||
import { ExceptionData } from '@shared/models/error.models';
|
|
||||||
import { IDashboardComponent } from '@home/models/dashboard-component.models';
|
import { IDashboardComponent } from '@home/models/dashboard-component.models';
|
||||||
import {
|
import {
|
||||||
DataSet,
|
DataSet,
|
||||||
@ -51,7 +50,7 @@ import { AssetService } from '@app/core/http/asset.service';
|
|||||||
import { DialogService } from '@core/services/dialog.service';
|
import { DialogService } from '@core/services/dialog.service';
|
||||||
import { CustomDialogService } from '@home/components/widget/dialog/custom-dialog.service';
|
import { CustomDialogService } from '@home/components/widget/dialog/custom-dialog.service';
|
||||||
import { isDefined, formatValue } from '@core/utils';
|
import { isDefined, formatValue } from '@core/utils';
|
||||||
import { Observable, of, ReplaySubject } from 'rxjs';
|
import { forkJoin, Observable, of, ReplaySubject } from 'rxjs';
|
||||||
import { WidgetSubscription } from '@core/api/widget-subscription';
|
import { WidgetSubscription } from '@core/api/widget-subscription';
|
||||||
|
|
||||||
export interface IWidgetAction {
|
export interface IWidgetAction {
|
||||||
@ -161,8 +160,6 @@ export class WidgetContext {
|
|||||||
isEdit: boolean;
|
isEdit: boolean;
|
||||||
isMobile: boolean;
|
isMobile: boolean;
|
||||||
|
|
||||||
widgetForceReInit?: () => void;
|
|
||||||
|
|
||||||
widgetNamespace?: string;
|
widgetNamespace?: string;
|
||||||
subscriptionApi?: WidgetSubscriptionApi;
|
subscriptionApi?: WidgetSubscriptionApi;
|
||||||
|
|
||||||
@ -187,6 +184,11 @@ export class WidgetContext {
|
|||||||
|
|
||||||
ngZone?: NgZone;
|
ngZone?: NgZone;
|
||||||
|
|
||||||
|
rxjs = {
|
||||||
|
forkJoin,
|
||||||
|
of
|
||||||
|
};
|
||||||
|
|
||||||
detectChanges(updateWidgetParams: boolean = false) {
|
detectChanges(updateWidgetParams: boolean = false) {
|
||||||
if (!this.destroyed) {
|
if (!this.destroyed) {
|
||||||
if (updateWidgetParams) {
|
if (updateWidgetParams) {
|
||||||
@ -208,11 +210,14 @@ export class WidgetContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateAliases(aliasIds?: Array<string>) {
|
||||||
|
this.aliasController.updateAliases(aliasIds);
|
||||||
|
}
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.destroyed = false;
|
this.destroyed = false;
|
||||||
this.hideTitlePanel = false;
|
this.hideTitlePanel = false;
|
||||||
this.widgetTitle = undefined;
|
this.widgetTitle = undefined;
|
||||||
this.customHeaderActions = undefined;
|
|
||||||
this.widgetActions = undefined;
|
this.widgetActions = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -226,7 +231,6 @@ export interface IDynamicWidgetComponent {
|
|||||||
rpcErrorText: string;
|
rpcErrorText: string;
|
||||||
rpcRejection: HttpErrorResponse;
|
rpcRejection: HttpErrorResponse;
|
||||||
raf: RafService;
|
raf: RafService;
|
||||||
widgetForceReInit(): void;
|
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user