Merge branch 'develop/3.0' of github.com:thingsboard/thingsboard into develop/3.0
This commit is contained in:
commit
620b66b700
@ -44,6 +44,8 @@ import org.thingsboard.server.common.data.page.TimePageLink;
|
|||||||
import org.thingsboard.server.service.security.permission.Operation;
|
import org.thingsboard.server.service.security.permission.Operation;
|
||||||
import org.thingsboard.server.service.security.permission.Resource;
|
import org.thingsboard.server.service.security.permission.Resource;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api")
|
@RequestMapping("/api")
|
||||||
public class AlarmController extends BaseController {
|
public class AlarmController extends BaseController {
|
||||||
@ -155,6 +157,7 @@ public class AlarmController extends BaseController {
|
|||||||
@RequestParam(required = false) String sortOrder,
|
@RequestParam(required = false) String sortOrder,
|
||||||
@RequestParam(required = false) Long startTime,
|
@RequestParam(required = false) Long startTime,
|
||||||
@RequestParam(required = false) Long endTime,
|
@RequestParam(required = false) Long endTime,
|
||||||
|
@RequestParam(required = false) String offset,
|
||||||
@RequestParam(required = false) Boolean fetchOriginator
|
@RequestParam(required = false) Boolean fetchOriginator
|
||||||
) throws ThingsboardException {
|
) throws ThingsboardException {
|
||||||
checkParameter("EntityId", strEntityId);
|
checkParameter("EntityId", strEntityId);
|
||||||
@ -168,8 +171,12 @@ public class AlarmController extends BaseController {
|
|||||||
}
|
}
|
||||||
checkEntityId(entityId, Operation.READ);
|
checkEntityId(entityId, Operation.READ);
|
||||||
TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
|
TimePageLink pageLink = createTimePageLink(pageSize, page, textSearch, sortProperty, sortOrder, startTime, endTime);
|
||||||
|
UUID idOffsetUuid = null;
|
||||||
|
if (StringUtils.isNotEmpty(offset)) {
|
||||||
|
idOffsetUuid = toUUID(offset);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return checkNotNull(alarmService.findAlarms(getCurrentUser().getTenantId(), new AlarmQuery(entityId, pageLink, alarmSearchStatus, alarmStatus, fetchOriginator)).get());
|
return checkNotNull(alarmService.findAlarms(getCurrentUser().getTenantId(), new AlarmQuery(entityId, pageLink, alarmSearchStatus, alarmStatus, fetchOriginator, idOffsetUuid)).get());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw handleException(e);
|
throw handleException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,8 @@ import org.thingsboard.server.common.data.id.EntityId;
|
|||||||
import org.thingsboard.server.common.data.id.TenantId;
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
import org.thingsboard.server.common.data.page.TimePageLink;
|
import org.thingsboard.server.common.data.page.TimePageLink;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by ashvayka on 11.05.17.
|
* Created by ashvayka on 11.05.17.
|
||||||
*/
|
*/
|
||||||
@ -35,5 +37,6 @@ public class AlarmQuery {
|
|||||||
private AlarmSearchStatus searchStatus;
|
private AlarmSearchStatus searchStatus;
|
||||||
private AlarmStatus status;
|
private AlarmStatus status;
|
||||||
private Boolean fetchOriginator;
|
private Boolean fetchOriginator;
|
||||||
|
private UUID idOffset;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -300,7 +300,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
|
|||||||
AlarmSeverity highestSeverity = null;
|
AlarmSeverity highestSeverity = null;
|
||||||
AlarmQuery query;
|
AlarmQuery query;
|
||||||
while (hasNext && AlarmSeverity.CRITICAL != highestSeverity) {
|
while (hasNext && AlarmSeverity.CRITICAL != highestSeverity) {
|
||||||
query = new AlarmQuery(entityId, nextPageLink, alarmSearchStatus, alarmStatus, false);
|
query = new AlarmQuery(entityId, nextPageLink, alarmSearchStatus, alarmStatus, false, null);
|
||||||
PageData<AlarmInfo> alarms = alarmDao.findAlarms(tenantId, query);
|
PageData<AlarmInfo> alarms = alarmDao.findAlarms(tenantId, query);
|
||||||
if (alarms.hasNext()) {
|
if (alarms.hasNext()) {
|
||||||
nextPageLink = nextPageLink.nextPageLink();
|
nextPageLink = nextPageLink.nextPageLink();
|
||||||
|
|||||||
@ -33,7 +33,7 @@ import java.util.List;
|
|||||||
@SqlDao
|
@SqlDao
|
||||||
public interface AlarmRepository extends CrudRepository<AlarmEntity, String> {
|
public interface AlarmRepository extends CrudRepository<AlarmEntity, String> {
|
||||||
|
|
||||||
@Query("SELECT a FROM AlarmEntity a WHERE a.originatorId = :originatorId AND a.type = :alarmType ORDER BY startTs DESC")
|
@Query("SELECT a FROM AlarmEntity a WHERE a.originatorId = :originatorId AND a.type = :alarmType ORDER BY a.startTs DESC")
|
||||||
List<AlarmEntity> findLatestByOriginatorAndType(@Param("originatorId") String originatorId,
|
List<AlarmEntity> findLatestByOriginatorAndType(@Param("originatorId") String originatorId,
|
||||||
@Param("alarmType") String alarmType,
|
@Param("alarmType") String alarmType,
|
||||||
Pageable pageable);
|
Pageable pageable);
|
||||||
@ -48,6 +48,7 @@ public interface AlarmRepository extends CrudRepository<AlarmEntity, String> {
|
|||||||
"AND re.fromType = :affectedEntityType " +
|
"AND re.fromType = :affectedEntityType " +
|
||||||
"AND (:startId IS NULL OR a.id >= :startId) " +
|
"AND (:startId IS NULL OR a.id >= :startId) " +
|
||||||
"AND (:endId IS NULL OR a.id <= :endId) " +
|
"AND (:endId IS NULL OR a.id <= :endId) " +
|
||||||
|
"AND (:idOffset IS NULL OR a.id < :idOffset) " +
|
||||||
"AND (LOWER(a.type) LIKE LOWER(CONCAT(:searchText, '%'))" +
|
"AND (LOWER(a.type) LIKE LOWER(CONCAT(:searchText, '%'))" +
|
||||||
"OR LOWER(a.severity) LIKE LOWER(CONCAT(:searchText, '%'))" +
|
"OR LOWER(a.severity) LIKE LOWER(CONCAT(:searchText, '%'))" +
|
||||||
"OR LOWER(a.status) LIKE LOWER(CONCAT(:searchText, '%')))")
|
"OR LOWER(a.status) LIKE LOWER(CONCAT(:searchText, '%')))")
|
||||||
@ -57,6 +58,7 @@ public interface AlarmRepository extends CrudRepository<AlarmEntity, String> {
|
|||||||
@Param("relationType") String relationType,
|
@Param("relationType") String relationType,
|
||||||
@Param("startId") String startId,
|
@Param("startId") String startId,
|
||||||
@Param("endId") String endId,
|
@Param("endId") String endId,
|
||||||
|
@Param("idOffset") String idOffset,
|
||||||
@Param("searchText") String searchText,
|
@Param("searchText") String searchText,
|
||||||
Pageable pageable);
|
Pageable pageable);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -117,6 +117,7 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A
|
|||||||
relationType,
|
relationType,
|
||||||
startTimeToId(query.getPageLink().getStartTime()),
|
startTimeToId(query.getPageLink().getStartTime()),
|
||||||
endTimeToId(query.getPageLink().getEndTime()),
|
endTimeToId(query.getPageLink().getEndTime()),
|
||||||
|
query.getIdOffset() != null ? UUIDConverter.fromTimeUUID(query.getIdOffset()) : null,
|
||||||
Objects.toString(query.getPageLink().getTextSearch(), ""),
|
Objects.toString(query.getPageLink().getTextSearch(), ""),
|
||||||
DaoUtil.toPageable(query.getPageLink())
|
DaoUtil.toPageable(query.getPageLink())
|
||||||
)
|
)
|
||||||
|
|||||||
@ -190,6 +190,8 @@ export interface WidgetSubscriptionOptions {
|
|||||||
alarmSource?: Datasource;
|
alarmSource?: Datasource;
|
||||||
alarmSearchStatus?: AlarmSearchStatus;
|
alarmSearchStatus?: AlarmSearchStatus;
|
||||||
alarmsPollingInterval?: number;
|
alarmsPollingInterval?: number;
|
||||||
|
alarmsMaxCountLoad?: number;
|
||||||
|
alarmsFetchSize?: number;
|
||||||
datasources?: Array<Datasource>;
|
datasources?: Array<Datasource>;
|
||||||
targetDeviceAliasIds?: Array<string>;
|
targetDeviceAliasIds?: Array<string>;
|
||||||
targetDeviceIds?: Array<string>;
|
targetDeviceIds?: Array<string>;
|
||||||
|
|||||||
@ -93,6 +93,8 @@ export class WidgetSubscription implements IWidgetSubscription {
|
|||||||
}
|
}
|
||||||
|
|
||||||
alarmsPollingInterval: number;
|
alarmsPollingInterval: number;
|
||||||
|
alarmsMaxCountLoad: number;
|
||||||
|
alarmsFetchSize: number;
|
||||||
alarmSourceListener: AlarmSourceListener;
|
alarmSourceListener: AlarmSourceListener;
|
||||||
|
|
||||||
loadingData: boolean;
|
loadingData: boolean;
|
||||||
@ -153,6 +155,10 @@ export class WidgetSubscription implements IWidgetSubscription {
|
|||||||
options.alarmSearchStatus : AlarmSearchStatus.ANY;
|
options.alarmSearchStatus : AlarmSearchStatus.ANY;
|
||||||
this.alarmsPollingInterval = isDefined(options.alarmsPollingInterval) ?
|
this.alarmsPollingInterval = isDefined(options.alarmsPollingInterval) ?
|
||||||
options.alarmsPollingInterval : 5000;
|
options.alarmsPollingInterval : 5000;
|
||||||
|
this.alarmsMaxCountLoad = isDefined(options.alarmsMaxCountLoad) ?
|
||||||
|
options.alarmsMaxCountLoad : 0;
|
||||||
|
this.alarmsFetchSize = isDefined(options.alarmsFetchSize) ?
|
||||||
|
options.alarmsFetchSize : 100;
|
||||||
this.alarmSourceListener = null;
|
this.alarmSourceListener = null;
|
||||||
this.alarms = [];
|
this.alarms = [];
|
||||||
this.originalTimewindow = null;
|
this.originalTimewindow = null;
|
||||||
@ -712,6 +718,8 @@ export class WidgetSubscription implements IWidgetSubscription {
|
|||||||
alarmSource: this.alarmSource,
|
alarmSource: this.alarmSource,
|
||||||
alarmSearchStatus: this.alarmSearchStatus,
|
alarmSearchStatus: this.alarmSearchStatus,
|
||||||
alarmsPollingInterval: this.alarmsPollingInterval,
|
alarmsPollingInterval: this.alarmsPollingInterval,
|
||||||
|
alarmsMaxCountLoad: this.alarmsMaxCountLoad,
|
||||||
|
alarmsFetchSize: this.alarmsFetchSize,
|
||||||
alarmsUpdated: alarms => this.alarmsUpdated(alarms)
|
alarmsUpdated: alarms => this.alarmsUpdated(alarms)
|
||||||
};
|
};
|
||||||
this.alarms = null;
|
this.alarms = null;
|
||||||
|
|||||||
@ -38,12 +38,15 @@ import { Direction, SortOrder } from '@shared/models/page/sort-order';
|
|||||||
import { concatMap, expand, map, toArray } from 'rxjs/operators';
|
import { concatMap, expand, map, toArray } from 'rxjs/operators';
|
||||||
import { EMPTY } from 'rxjs';
|
import { EMPTY } from 'rxjs';
|
||||||
import Timeout = NodeJS.Timeout;
|
import Timeout = NodeJS.Timeout;
|
||||||
|
import { isDefined } from '@core/utils';
|
||||||
|
|
||||||
interface AlarmSourceListenerQuery {
|
interface AlarmSourceListenerQuery {
|
||||||
entityType: EntityType;
|
entityType: EntityType;
|
||||||
entityId: string;
|
entityId: string;
|
||||||
alarmSearchStatus: AlarmSearchStatus;
|
alarmSearchStatus: AlarmSearchStatus;
|
||||||
alarmStatus: AlarmStatus;
|
alarmStatus: AlarmStatus;
|
||||||
|
alarmsMaxCountLoad: number;
|
||||||
|
alarmsFetchSize: number;
|
||||||
fetchOriginator?: boolean;
|
fetchOriginator?: boolean;
|
||||||
limit?: number;
|
limit?: number;
|
||||||
interval?: number;
|
interval?: number;
|
||||||
@ -58,6 +61,8 @@ export interface AlarmSourceListener {
|
|||||||
alarmSource: Datasource;
|
alarmSource: Datasource;
|
||||||
alarmsPollingInterval: number;
|
alarmsPollingInterval: number;
|
||||||
alarmSearchStatus: AlarmSearchStatus;
|
alarmSearchStatus: AlarmSearchStatus;
|
||||||
|
alarmsMaxCountLoad: number;
|
||||||
|
alarmsFetchSize: number;
|
||||||
alarmsUpdated: (alarms: Array<AlarmInfo>) => void;
|
alarmsUpdated: (alarms: Array<AlarmInfo>) => void;
|
||||||
lastUpdateTs?: number;
|
lastUpdateTs?: number;
|
||||||
alarmsQuery?: AlarmSourceListenerQuery;
|
alarmsQuery?: AlarmSourceListenerQuery;
|
||||||
@ -132,7 +137,9 @@ export class AlarmService {
|
|||||||
entityType: alarmSource.entityType,
|
entityType: alarmSource.entityType,
|
||||||
entityId: alarmSource.entityId,
|
entityId: alarmSource.entityId,
|
||||||
alarmSearchStatus: alarmSourceListener.alarmSearchStatus,
|
alarmSearchStatus: alarmSourceListener.alarmSearchStatus,
|
||||||
alarmStatus: null
|
alarmStatus: null,
|
||||||
|
alarmsMaxCountLoad: alarmSourceListener.alarmsMaxCountLoad,
|
||||||
|
alarmsFetchSize: alarmSourceListener.alarmsFetchSize
|
||||||
};
|
};
|
||||||
const originatorKeys = alarmSource.dataKeys.filter(dataKey => dataKey.name.toLocaleLowerCase().includes('originator'));
|
const originatorKeys = alarmSource.dataKeys.filter(dataKey => dataKey.name.toLocaleLowerCase().includes('originator'));
|
||||||
if (originatorKeys.length) {
|
if (originatorKeys.length) {
|
||||||
@ -186,32 +193,49 @@ export class AlarmService {
|
|||||||
null,
|
null,
|
||||||
sortOrder);
|
sortOrder);
|
||||||
} else if (alarmsQuery.interval) {
|
} else if (alarmsQuery.interval) {
|
||||||
pageLink = new TimePageLink(100, 0,
|
pageLink = new TimePageLink(alarmsQuery.alarmsFetchSize || 100, 0,
|
||||||
null,
|
null,
|
||||||
sortOrder, time - alarmsQuery.interval);
|
sortOrder, time - alarmsQuery.interval);
|
||||||
} else if (alarmsQuery.startTime) {
|
} else if (alarmsQuery.startTime) {
|
||||||
pageLink = new TimePageLink(100, 0,
|
pageLink = new TimePageLink(alarmsQuery.alarmsFetchSize || 100, 0,
|
||||||
null,
|
null,
|
||||||
sortOrder, Math.round(alarmsQuery.startTime));
|
sortOrder, Math.round(alarmsQuery.startTime));
|
||||||
if (alarmsQuery.endTime) {
|
if (alarmsQuery.endTime) {
|
||||||
pageLink.endTime = Math.round(alarmsQuery.endTime);
|
pageLink.endTime = Math.round(alarmsQuery.endTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.fetchAlarms(alarmsQuery, pageLink);
|
let leftToLoad;
|
||||||
|
if (isDefined(alarmsQuery.alarmsMaxCountLoad) && alarmsQuery.alarmsMaxCountLoad !== 0) {
|
||||||
|
leftToLoad = alarmsQuery.alarmsMaxCountLoad;
|
||||||
|
if (leftToLoad < pageLink.pageSize) {
|
||||||
|
pageLink.pageSize = leftToLoad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.fetchAlarms(alarmsQuery, pageLink, leftToLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
private fetchAlarms(query: AlarmSourceListenerQuery,
|
private fetchAlarms(query: AlarmSourceListenerQuery,
|
||||||
pageLink: TimePageLink): Observable<Array<AlarmInfo>> {
|
pageLink: TimePageLink, leftToLoad?: number): Observable<Array<AlarmInfo>> {
|
||||||
const alarmQuery = new AlarmQuery(
|
const alarmQuery = new AlarmQuery(
|
||||||
{id: query.entityId, entityType: query.entityType},
|
{id: query.entityId, entityType: query.entityType},
|
||||||
pageLink,
|
pageLink,
|
||||||
query.alarmSearchStatus,
|
query.alarmSearchStatus,
|
||||||
query.alarmStatus,
|
query.alarmStatus,
|
||||||
query.fetchOriginator);
|
query.fetchOriginator,
|
||||||
|
null);
|
||||||
return this.getAlarms(alarmQuery, {ignoreLoading: true}).pipe(
|
return this.getAlarms(alarmQuery, {ignoreLoading: true}).pipe(
|
||||||
expand((data) => {
|
expand((data) => {
|
||||||
if (data.hasNext && !query.limit) {
|
let continueLoad = data.hasNext && !query.limit;
|
||||||
alarmQuery.pageLink.page += 1;
|
if (continueLoad && isDefined(leftToLoad)) {
|
||||||
|
leftToLoad -= data.data.length;
|
||||||
|
if (leftToLoad === 0) {
|
||||||
|
continueLoad = false;
|
||||||
|
} else if (leftToLoad < alarmQuery.pageLink.pageSize) {
|
||||||
|
alarmQuery.pageLink.pageSize = leftToLoad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (continueLoad) {
|
||||||
|
alarmQuery.offset = data.data[data.data.length-1].id.id;
|
||||||
return this.getAlarms(alarmQuery, {ignoreLoading: true});
|
return this.getAlarms(alarmQuery, {ignoreLoading: true});
|
||||||
} else {
|
} else {
|
||||||
return EMPTY;
|
return EMPTY;
|
||||||
|
|||||||
@ -110,7 +110,7 @@ export class AlarmTableConfig extends EntityTableConfig<AlarmInfo, TimePageLink>
|
|||||||
}
|
}
|
||||||
|
|
||||||
fetchAlarms(pageLink: TimePageLink): Observable<PageData<AlarmInfo>> {
|
fetchAlarms(pageLink: TimePageLink): Observable<PageData<AlarmInfo>> {
|
||||||
const query = new AlarmQuery(this.entityId, pageLink, this.searchStatus, null, true);
|
const query = new AlarmQuery(this.entityId, pageLink, this.searchStatus, null, true, null);
|
||||||
return this.alarmService.getAlarms(query);
|
return this.alarmService.getAlarms(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -36,29 +36,60 @@
|
|||||||
fxFlex formControlName="timewindow"></tb-timewindow>
|
fxFlex formControlName="timewindow"></tb-timewindow>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="widgetType === widgetTypes.alarm" fxLayout="column" fxLayoutGap="8px" fxLayoutAlign="center"
|
<div *ngIf="widgetType === widgetTypes.alarm" fxLayout="column" fxLayoutAlign="center">
|
||||||
fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="start center">
|
<div fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="start center" fxLayoutGap="8px">
|
||||||
<mat-form-field fxFlex class="mat-block">
|
<mat-form-field fxFlex class="mat-block">
|
||||||
<mat-label translate>alarm.alarm-status</mat-label>
|
<mat-label translate>alarm.alarm-status</mat-label>
|
||||||
<mat-select matInput formControlName="alarmSearchStatus">
|
<mat-select matInput formControlName="alarmSearchStatus">
|
||||||
<mat-option *ngFor="let searchStatus of alarmSearchStatuses" [value]="searchStatus">
|
<mat-option *ngFor="let searchStatus of alarmSearchStatuses" [value]="searchStatus">
|
||||||
{{ ('alarm.search-status.' + searchStatus) | translate }}
|
{{ ('alarm.search-status.' + searchStatus) | translate }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field fxFlex class="mat-block">
|
<mat-form-field fxFlex class="mat-block">
|
||||||
<mat-label translate>alarm.polling-interval</mat-label>
|
<mat-label translate>alarm.polling-interval</mat-label>
|
||||||
<input matInput required
|
<input matInput required
|
||||||
formControlName="alarmsPollingInterval"
|
formControlName="alarmsPollingInterval"
|
||||||
type="number"
|
type="number"
|
||||||
step="1"/>
|
step="1"/>
|
||||||
<mat-error *ngIf="dataSettings.get('alarmsPollingInterval').hasError('required')">
|
<mat-error *ngIf="dataSettings.get('alarmsPollingInterval').hasError('required')">
|
||||||
{{ 'alarm.polling-interval-required' | translate }}
|
{{ 'alarm.polling-interval-required' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
<mat-error *ngIf="dataSettings.get('alarmsPollingInterval').hasError('min')">
|
<mat-error *ngIf="dataSettings.get('alarmsPollingInterval').hasError('min')">
|
||||||
{{ 'alarm.min-polling-interval-message' | translate }}
|
{{ 'alarm.min-polling-interval-message' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="start center" fxLayoutGap="8px">
|
||||||
|
<mat-form-field fxFlex class="mat-block">
|
||||||
|
<mat-label translate>alarm.max-count-load</mat-label>
|
||||||
|
<input matInput required
|
||||||
|
formControlName="alarmsMaxCountLoad"
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
step="1">
|
||||||
|
<mat-error *ngIf="dataSettings.get('alarmsMaxCountLoad').hasError('required')">
|
||||||
|
{{ 'alarm.max-count-load-required' | translate }}
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="dataSettings.get('alarmsMaxCountLoad').hasError('min')">
|
||||||
|
{{ 'alarm.max-count-load-error-min' | translate }}
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field fxFlex class="mat-block">
|
||||||
|
<mat-label translate>alarm.fetch-size</mat-label>
|
||||||
|
<input matInput required
|
||||||
|
formControlName="alarmsFetchSize"
|
||||||
|
type="number"
|
||||||
|
min="10"
|
||||||
|
step="1">
|
||||||
|
<mat-error *ngIf="dataSettings.get('alarmsFetchSize').hasError('required')">
|
||||||
|
{{ 'alarm.fetch-size-required' | translate }}
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="dataSettings.get('alarmsFetchSize').hasError('min')">
|
||||||
|
{{ 'alarm.fetch-size-error-min' | translate }}
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<mat-expansion-panel class="tb-datasources" *ngIf="widgetType !== widgetTypes.rpc &&
|
<mat-expansion-panel class="tb-datasources" *ngIf="widgetType !== widgetTypes.rpc &&
|
||||||
widgetType !== widgetTypes.alarm &&
|
widgetType !== widgetTypes.alarm &&
|
||||||
|
|||||||
@ -287,6 +287,10 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont
|
|||||||
this.dataSettings.addControl('alarmSearchStatus', this.fb.control(null));
|
this.dataSettings.addControl('alarmSearchStatus', this.fb.control(null));
|
||||||
this.dataSettings.addControl('alarmsPollingInterval', this.fb.control(null,
|
this.dataSettings.addControl('alarmsPollingInterval', this.fb.control(null,
|
||||||
[Validators.required, Validators.min(1)]));
|
[Validators.required, Validators.min(1)]));
|
||||||
|
this.dataSettings.addControl('alarmsMaxCountLoad', this.fb.control(null,
|
||||||
|
[Validators.required, Validators.min(0)]));
|
||||||
|
this.dataSettings.addControl('alarmsFetchSize', this.fb.control(null,
|
||||||
|
[Validators.required, Validators.min(10)]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.modelValue.isDataEnabled) {
|
if (this.modelValue.isDataEnabled) {
|
||||||
@ -439,6 +443,14 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont
|
|||||||
{ alarmsPollingInterval: isDefined(config.alarmsPollingInterval) ?
|
{ alarmsPollingInterval: isDefined(config.alarmsPollingInterval) ?
|
||||||
config.alarmsPollingInterval : 5}, {emitEvent: false}
|
config.alarmsPollingInterval : 5}, {emitEvent: false}
|
||||||
);
|
);
|
||||||
|
this.dataSettings.patchValue(
|
||||||
|
{ alarmsMaxCountLoad: isDefined(config.alarmsMaxCountLoad) ?
|
||||||
|
config.alarmsMaxCountLoad : 0}, {emitEvent: false}
|
||||||
|
);
|
||||||
|
this.dataSettings.patchValue(
|
||||||
|
{ alarmsFetchSize: isDefined(config.alarmsFetchSize) ?
|
||||||
|
config.alarmsFetchSize : 100}, {emitEvent: false}
|
||||||
|
);
|
||||||
this.alarmSourceSettings.patchValue(
|
this.alarmSourceSettings.patchValue(
|
||||||
config.alarmSource, {emitEvent: false}
|
config.alarmSource, {emitEvent: false}
|
||||||
);
|
);
|
||||||
|
|||||||
@ -828,6 +828,10 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI
|
|||||||
this.widget.config.alarmSearchStatus : AlarmSearchStatus.ANY;
|
this.widget.config.alarmSearchStatus : AlarmSearchStatus.ANY;
|
||||||
options.alarmsPollingInterval = isDefined(this.widget.config.alarmsPollingInterval) ?
|
options.alarmsPollingInterval = isDefined(this.widget.config.alarmsPollingInterval) ?
|
||||||
this.widget.config.alarmsPollingInterval * 1000 : 5000;
|
this.widget.config.alarmsPollingInterval * 1000 : 5000;
|
||||||
|
options.alarmsMaxCountLoad = isDefined(this.widget.config.alarmsMaxCountLoad) ?
|
||||||
|
this.widget.config.alarmsMaxCountLoad : 0;
|
||||||
|
options.alarmsFetchSize = isDefined(this.widget.config.alarmsFetchSize) ?
|
||||||
|
this.widget.config.alarmsFetchSize : 100;
|
||||||
} else {
|
} else {
|
||||||
options.datasources = deepClone(this.widget.config.datasources);
|
options.datasources = deepClone(this.widget.config.datasources);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,16 +14,14 @@
|
|||||||
/// limitations under the License.
|
/// limitations under the License.
|
||||||
///
|
///
|
||||||
|
|
||||||
import {BaseData} from '@shared/models/base-data';
|
import { BaseData } from '@shared/models/base-data';
|
||||||
import {AssetId} from '@shared/models/id/asset-id';
|
import { TenantId } from '@shared/models/id/tenant-id';
|
||||||
import {TenantId} from '@shared/models/id/tenant-id';
|
import { AlarmId } from '@shared/models/id/alarm-id';
|
||||||
import {CustomerId} from '@shared/models/id/customer-id';
|
import { EntityId } from '@shared/models/id/entity-id';
|
||||||
import {AlarmId} from '@shared/models/id/alarm-id';
|
|
||||||
import {EntityId} from '@shared/models/id/entity-id';
|
|
||||||
import { ActionStatus } from '@shared/models/audit-log.models';
|
|
||||||
import { TimePageLink } from '@shared/models/page/page-link';
|
import { TimePageLink } from '@shared/models/page/page-link';
|
||||||
import { NULL_UUID } from '@shared/models/id/has-uuid';
|
import { NULL_UUID } from '@shared/models/id/has-uuid';
|
||||||
import { EntityType } from '@shared/models/entity-type.models';
|
import { EntityType } from '@shared/models/entity-type.models';
|
||||||
|
import { isString } from '@core/utils';
|
||||||
|
|
||||||
export enum AlarmSeverity {
|
export enum AlarmSeverity {
|
||||||
CRITICAL = 'CRITICAL',
|
CRITICAL = 'CRITICAL',
|
||||||
@ -199,15 +197,17 @@ export class AlarmQuery {
|
|||||||
searchStatus: AlarmSearchStatus;
|
searchStatus: AlarmSearchStatus;
|
||||||
status: AlarmStatus;
|
status: AlarmStatus;
|
||||||
fetchOriginator: boolean;
|
fetchOriginator: boolean;
|
||||||
|
offset: string;
|
||||||
|
|
||||||
constructor(entityId: EntityId, pageLink: TimePageLink,
|
constructor(entityId: EntityId, pageLink: TimePageLink,
|
||||||
searchStatus: AlarmSearchStatus, status: AlarmStatus,
|
searchStatus: AlarmSearchStatus, status: AlarmStatus,
|
||||||
fetchOriginator: boolean) {
|
fetchOriginator: boolean, offset: string) {
|
||||||
this.affectedEntityId = entityId;
|
this.affectedEntityId = entityId;
|
||||||
this.pageLink = pageLink;
|
this.pageLink = pageLink;
|
||||||
this.searchStatus = searchStatus;
|
this.searchStatus = searchStatus;
|
||||||
this.status = status;
|
this.status = status;
|
||||||
this.fetchOriginator = fetchOriginator;
|
this.fetchOriginator = fetchOriginator;
|
||||||
|
this.offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public toQuery(): string {
|
public toQuery(): string {
|
||||||
@ -221,6 +221,9 @@ export class AlarmQuery {
|
|||||||
if (typeof this.fetchOriginator !== 'undefined' && this.fetchOriginator !== null) {
|
if (typeof this.fetchOriginator !== 'undefined' && this.fetchOriginator !== null) {
|
||||||
query += `&fetchOriginator=${this.fetchOriginator}`;
|
query += `&fetchOriginator=${this.fetchOriginator}`;
|
||||||
}
|
}
|
||||||
|
if (isString(this.offset) && this.offset.length) {
|
||||||
|
query += `&offset=${this.offset}`;
|
||||||
|
}
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -360,6 +360,8 @@ export interface WidgetConfig {
|
|||||||
alarmSource?: Datasource;
|
alarmSource?: Datasource;
|
||||||
alarmSearchStatus?: AlarmSearchStatus;
|
alarmSearchStatus?: AlarmSearchStatus;
|
||||||
alarmsPollingInterval?: number;
|
alarmsPollingInterval?: number;
|
||||||
|
alarmsMaxCountLoad?: number;
|
||||||
|
alarmsFetchSize?: number;
|
||||||
datasources?: Array<Datasource>;
|
datasources?: Array<Datasource>;
|
||||||
targetDeviceAliasIds?: Array<string>;
|
targetDeviceAliasIds?: Array<string>;
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user