Delete timeseries UI implementation (#8932)
This commit is contained in:
parent
4b7cc4571d
commit
2f1290e7e1
@ -50,10 +50,11 @@ export class AttributeService {
|
||||
}
|
||||
|
||||
public deleteEntityTimeseries(entityId: EntityId, timeseries: Array<AttributeData>, deleteAllDataForKeys = false,
|
||||
startTs?: number, endTs?: number, config?: RequestConfig): Observable<any> {
|
||||
startTs?: number, endTs?: number, rewriteLatestIfDeleted = false, deleteLatest = false,
|
||||
config?: RequestConfig): Observable<any> {
|
||||
const keys = timeseries.map(attribute => encodeURIComponent(attribute.key)).join(',');
|
||||
let url = `/api/plugins/telemetry/${entityId.entityType}/${entityId.id}/timeseries/delete` +
|
||||
`?keys=${keys}&deleteAllDataForKeys=${deleteAllDataForKeys}`;
|
||||
`?keys=${keys}&deleteAllDataForKeys=${deleteAllDataForKeys}&rewriteLatestIfDeleted=${rewriteLatestIfDeleted}&deleteLatest=${deleteLatest}`;
|
||||
if (isDefinedAndNotNull(startTs)) {
|
||||
url += `&startTs=${startTs}`;
|
||||
}
|
||||
@ -63,6 +64,12 @@ export class AttributeService {
|
||||
return this.http.delete(url, defaultHttpOptionsFromConfig(config));
|
||||
}
|
||||
|
||||
public deleteEntityLatestTimeseries(entityId: EntityId, timeseries: Array<AttributeData>, config?: RequestConfig): Observable<any> {
|
||||
const keys = timeseries.map(attribute => encodeURIComponent(attribute.key)).join(',');
|
||||
let url = `/api/plugins/telemetry/${entityId.entityType}/${entityId.id}/timeseries/latest/delete?keys=${keys}`;
|
||||
return this.http.delete(url, defaultHttpOptionsFromConfig(config));
|
||||
}
|
||||
|
||||
public saveEntityAttributes(entityId: EntityId, attributeScope: AttributeScope, attributes: Array<AttributeData>,
|
||||
config?: RequestConfig): Observable<any> {
|
||||
const attributesData: {[key: string]: any} = {};
|
||||
@ -103,7 +110,8 @@ export class AttributeService {
|
||||
});
|
||||
let deleteEntityTimeseriesObservable: Observable<any>;
|
||||
if (deleteTimeseries.length) {
|
||||
deleteEntityTimeseriesObservable = this.deleteEntityTimeseries(entityId, deleteTimeseries, true, null, null, config);
|
||||
deleteEntityTimeseriesObservable = this.deleteEntityTimeseries(entityId, deleteTimeseries, true,
|
||||
null, null, false, false, config);
|
||||
} else {
|
||||
deleteEntityTimeseriesObservable = of(null);
|
||||
}
|
||||
|
||||
@ -93,6 +93,14 @@
|
||||
(click)="deleteAttributes($event)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
<button [fxShow]="attributeScope === latestTelemetryTypes.LATEST_TELEMETRY && dataSource.selection.selected.length > 1"
|
||||
class="button-widget-action"
|
||||
mat-icon-button [disabled]="isLoading$ | async"
|
||||
matTooltip="{{ 'action.delete' | translate }}"
|
||||
matTooltipPosition="above"
|
||||
(click)="deleteTimeseries($event)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
<button mat-raised-button color="accent"
|
||||
class="button-widget-action"
|
||||
[disabled]="isLoading$ | async"
|
||||
@ -198,6 +206,10 @@
|
||||
<span [fxShow]="!isClientSideTelemetryTypeMap.get(attributeScope)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</span>
|
||||
<button mat-icon-button [fxShow]="attributeScope === latestTelemetryTypes.LATEST_TELEMETRY"
|
||||
(click)="deleteTimeseries($event, attribute)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
@ -38,7 +38,7 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { DialogService } from '@core/services/dialog.service';
|
||||
import { Direction, SortOrder } from '@shared/models/page/sort-order';
|
||||
import { fromEvent, merge } from 'rxjs';
|
||||
import { fromEvent, merge, Observable } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged, tap } from 'rxjs/operators';
|
||||
import { EntityId } from '@shared/models/id/entity-id';
|
||||
import {
|
||||
@ -48,7 +48,7 @@ import {
|
||||
isClientSideTelemetryType,
|
||||
LatestTelemetry,
|
||||
TelemetryType,
|
||||
telemetryTypeTranslations,
|
||||
telemetryTypeTranslations, TimeseriesDeleteStrategy,
|
||||
toTelemetryType
|
||||
} from '@shared/models/telemetry/telemetry.models';
|
||||
import { AttributeDatasource } from '@home/models/datasource/attribute-datasource';
|
||||
@ -82,10 +82,14 @@ import {
|
||||
AddWidgetToDashboardDialogComponent,
|
||||
AddWidgetToDashboardDialogData
|
||||
} from '@home/components/attribute/add-widget-to-dashboard-dialog.component';
|
||||
import { deepClone } from '@core/utils';
|
||||
import { deepClone, isUndefinedOrNull } from '@core/utils';
|
||||
import { Filters } from '@shared/models/query/query.models';
|
||||
import { hidePageSizePixelValue } from '@shared/models/constants';
|
||||
import { ResizeObserver } from '@juggle/resize-observer';
|
||||
import {
|
||||
DELETE_TIMESERIES_PANEL_DATA,
|
||||
DeleteTimeseriesPanelComponent, DeleteTimeseriesPanelData
|
||||
} from '@home/components/attribute/delete-timeseries-panel.component';
|
||||
|
||||
|
||||
@Component({
|
||||
@ -378,6 +382,79 @@ export class AttributeTableComponent extends PageComponent implements AfterViewI
|
||||
});
|
||||
}
|
||||
|
||||
deleteTimeseries($event: Event, attribute?: AttributeData) {
|
||||
if ($event) {
|
||||
$event.stopPropagation();
|
||||
}
|
||||
const isMultipleDeletion = isUndefinedOrNull(attribute);
|
||||
const target = $event.target || $event.srcElement || $event.currentTarget;
|
||||
const config = new OverlayConfig();
|
||||
config.backdropClass = 'cdk-overlay-transparent-backdrop';
|
||||
config.hasBackdrop = true;
|
||||
const connectedPosition: ConnectedPosition = {
|
||||
originX: 'start',
|
||||
originY: 'top',
|
||||
overlayX: 'end',
|
||||
overlayY: 'top'
|
||||
};
|
||||
config.positionStrategy = this.overlay.position().flexibleConnectedTo(target as HTMLElement)
|
||||
.withPositions([connectedPosition]);
|
||||
config.maxWidth = '488px';
|
||||
config.width = '100%';
|
||||
const overlayRef = this.overlay.create(config);
|
||||
overlayRef.backdropClick().subscribe(() => {
|
||||
overlayRef.dispose();
|
||||
});
|
||||
|
||||
const providers: StaticProvider[] = [
|
||||
{
|
||||
provide: DELETE_TIMESERIES_PANEL_DATA,
|
||||
useValue: {
|
||||
isMultipleDeletion: isMultipleDeletion
|
||||
} as DeleteTimeseriesPanelData
|
||||
},
|
||||
{
|
||||
provide: OverlayRef,
|
||||
useValue: overlayRef
|
||||
}
|
||||
];
|
||||
const injector = Injector.create({parent: this.viewContainerRef.injector, providers});
|
||||
const componentRef = overlayRef.attach(new ComponentPortal(DeleteTimeseriesPanelComponent,
|
||||
this.viewContainerRef, injector));
|
||||
componentRef.onDestroy(() => {
|
||||
if (componentRef.instance.result !== null) {
|
||||
const strategy = componentRef.instance.result;
|
||||
const timeseries = isMultipleDeletion ? this.dataSource.selection.selected : [attribute];
|
||||
let deleteAllDataForKeys = false;
|
||||
let rewriteLatestIfDeleted = false;
|
||||
let startTs = null;
|
||||
let endTs = null;
|
||||
let deleteLatest = false;
|
||||
let task: Observable<any>;
|
||||
if (strategy === TimeseriesDeleteStrategy.DELETE_ALL_DATA_INCLUDING_KEY) {
|
||||
deleteAllDataForKeys = true;
|
||||
deleteLatest = true;
|
||||
}
|
||||
if (strategy === TimeseriesDeleteStrategy.DELETE_OLD_DATA_EXCEPT_LATEST_VALUE) {
|
||||
deleteAllDataForKeys = true;
|
||||
}
|
||||
if (strategy === TimeseriesDeleteStrategy.DELETE_LATEST_VALUE) {
|
||||
task = this.attributeService.deleteEntityLatestTimeseries(this.entityIdValue, timeseries);
|
||||
}
|
||||
if (strategy === TimeseriesDeleteStrategy.DELETE_DATA_FOR_TIME_PERIOD) {
|
||||
startTs = componentRef.instance.startDateTime.getTime();
|
||||
endTs = componentRef.instance.endDateTime.getTime();
|
||||
rewriteLatestIfDeleted = componentRef.instance.rewriteLatestIfDeleted;
|
||||
}
|
||||
if (!task) {
|
||||
task = this.attributeService.deleteEntityTimeseries(this.entityIdValue, timeseries, deleteAllDataForKeys,
|
||||
startTs, endTs, rewriteLatestIfDeleted, deleteLatest);
|
||||
}
|
||||
task.subscribe(() => this.reloadAttributes());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
deleteAttributes($event: Event) {
|
||||
if ($event) {
|
||||
$event.stopPropagation();
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
<!--
|
||||
|
||||
Copyright © 2016-2023 The Thingsboard Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
-->
|
||||
|
||||
<div class="mat-elevation-z1" style="max-width: 488px">
|
||||
<mat-toolbar>
|
||||
<h2>{{ "attribute.delete-timeseries.delete-strategy" | translate }}</h2>
|
||||
<span fxFlex></span>
|
||||
<button mat-icon-button
|
||||
(click)="cancel()"
|
||||
type="button">
|
||||
<mat-icon class="material-icons">close</mat-icon>
|
||||
</button>
|
||||
</mat-toolbar>
|
||||
<div style="padding: 16px; min-height: 188px">
|
||||
<mat-form-field fxFlex class="mat-block">
|
||||
<mat-label translate>attribute.delete-timeseries.strategy</mat-label>
|
||||
<mat-select [(ngModel)]="strategy">
|
||||
<mat-option *ngFor="let strategy of strategiesTranslationsMap.keys()" [value]="strategy">
|
||||
{{ strategiesTranslationsMap.get(strategy) | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div *ngIf="isPeriodStrategy()">
|
||||
<div fxLayout="row" fxLayoutGap="22px" fxLayout.xs="column" fxLayoutGap.xs="8px">
|
||||
<mat-form-field class="mat-block">
|
||||
<mat-label translate>attribute.delete-timeseries.start-time</mat-label>
|
||||
<mat-datetimepicker-toggle [for]="startDateTimePicker" matPrefix></mat-datetimepicker-toggle>
|
||||
<mat-datetimepicker #startDateTimePicker type="datetime" openOnFocus="true"></mat-datetimepicker>
|
||||
<input required matInput [(ngModel)]="startDateTime" [matDatetimepicker]="startDateTimePicker"
|
||||
(ngModelChange)="onStartDateTimeChange($event)">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="mat-block">
|
||||
<mat-label translate>attribute.delete-timeseries.ends-on</mat-label>
|
||||
<mat-datetimepicker-toggle [for]="endDatePicker" matPrefix></mat-datetimepicker-toggle>
|
||||
<mat-datetimepicker #endDatePicker type="datetime" openOnFocus="true"></mat-datetimepicker>
|
||||
<input required matInput [(ngModel)]="endDateTime" [matDatetimepicker]="endDatePicker"
|
||||
(ngModelChange)="onEndDateTimeChange($event)">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<mat-slide-toggle [(ngModel)]="rewriteLatestIfDeleted">
|
||||
{{ "attribute.delete-timeseries.rewrite-latest-value-if-deleted" | translate }}
|
||||
</mat-slide-toggle>
|
||||
</div>
|
||||
</div>
|
||||
<div fxLayout="row" class="tb-panel-actions">
|
||||
<span fxFlex></span>
|
||||
<button mat-button color="primary"
|
||||
type="button"
|
||||
(click)="cancel()" cdkFocusInitial>
|
||||
{{ 'action.cancel' | translate }}
|
||||
</button>
|
||||
<button mat-button mat-raised-button color="primary"
|
||||
type="submit"
|
||||
(click)="delete()">
|
||||
{{ 'action.apply' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright © 2016-2023 The Thingsboard Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
:host {
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.3), 0px 2px 6px 2px rgba(0, 0, 0, 0.15);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
:host ::ng-deep{
|
||||
div .mat-toolbar {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,100 @@
|
||||
///
|
||||
/// Copyright © 2016-2023 The Thingsboard Authors
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import { Component, Inject, InjectionToken, OnInit } from '@angular/core';
|
||||
import { OverlayRef } from '@angular/cdk/overlay';
|
||||
import {
|
||||
TimeseriesDeleteStrategy,
|
||||
timeseriesDeleteStrategyTranslations
|
||||
} from '@shared/models/telemetry/telemetry.models';
|
||||
import { MINUTE } from '@shared/models/time/time.models';
|
||||
|
||||
export const DELETE_TIMESERIES_PANEL_DATA = new InjectionToken<any>('DeleteTimeseriesPanelData');
|
||||
|
||||
export interface DeleteTimeseriesPanelData {
|
||||
isMultipleDeletion: boolean;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'tb-delete-timeseries-panel',
|
||||
templateUrl: './delete-timeseries-panel.component.html',
|
||||
styleUrls: ['./delete-timeseries-panel.component.scss']
|
||||
})
|
||||
export class DeleteTimeseriesPanelComponent implements OnInit {
|
||||
|
||||
strategy: string = TimeseriesDeleteStrategy.DELETE_ALL_DATA_INCLUDING_KEY;
|
||||
|
||||
result: string = null;
|
||||
|
||||
startDateTime: Date;
|
||||
|
||||
endDateTime: Date;
|
||||
|
||||
rewriteLatestIfDeleted: boolean = false;
|
||||
|
||||
strategiesTranslationsMap = timeseriesDeleteStrategyTranslations;
|
||||
|
||||
multipleDeletionStrategies = [
|
||||
TimeseriesDeleteStrategy.DELETE_ALL_DATA_INCLUDING_KEY,
|
||||
TimeseriesDeleteStrategy.DELETE_OLD_DATA_EXCEPT_LATEST_VALUE
|
||||
];
|
||||
|
||||
constructor(@Inject(DELETE_TIMESERIES_PANEL_DATA) public data: DeleteTimeseriesPanelData,
|
||||
public overlayRef: OverlayRef) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
let today = new Date();
|
||||
this.startDateTime = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate());
|
||||
this.endDateTime = today;
|
||||
if (this.data.isMultipleDeletion) {
|
||||
this.strategiesTranslationsMap = new Map(Array.from(this.strategiesTranslationsMap.entries())
|
||||
.filter(([strategy]) => {
|
||||
return this.multipleDeletionStrategies.includes(strategy);
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
delete(): void {
|
||||
this.result = this.strategy;
|
||||
this.overlayRef.dispose();
|
||||
}
|
||||
|
||||
cancel(): void {
|
||||
this.overlayRef.dispose();
|
||||
}
|
||||
|
||||
isPeriodStrategy(): boolean {
|
||||
return this.strategy === TimeseriesDeleteStrategy.DELETE_DATA_FOR_TIME_PERIOD;
|
||||
}
|
||||
|
||||
onStartDateTimeChange(newStartDateTime: Date) {
|
||||
const endDateTimeTs = this.endDateTime.getTime();
|
||||
if (newStartDateTime.getTime() >= endDateTimeTs) {
|
||||
this.startDateTime = new Date(endDateTimeTs - MINUTE);
|
||||
} else {
|
||||
this.startDateTime = newStartDateTime;
|
||||
}
|
||||
}
|
||||
|
||||
onEndDateTimeChange(newEndDateTime: Date) {
|
||||
const startDateTimeTs = this.startDateTime.getTime();
|
||||
if (newEndDateTime.getTime() <= startDateTimeTs) {
|
||||
this.endDateTime = new Date(startDateTimeTs + MINUTE);
|
||||
} else {
|
||||
this.endDateTime = newEndDateTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -177,6 +177,7 @@ import {
|
||||
} from '@home/components/widget/action/manage-widget-actions-dialog.component';
|
||||
import { WidgetConfigComponentsModule } from '@home/components/widget/config/widget-config-components.module';
|
||||
import { BasicWidgetConfigModule } from '@home/components/widget/config/basic/basic-widget-config.module';
|
||||
import { DeleteTimeseriesPanelComponent } from '@home/components/attribute/delete-timeseries-panel.component';
|
||||
|
||||
@NgModule({
|
||||
declarations:
|
||||
@ -205,6 +206,7 @@ import { BasicWidgetConfigModule } from '@home/components/widget/config/basic/ba
|
||||
AttributeTableComponent,
|
||||
AddAttributeDialogComponent,
|
||||
EditAttributeValuePanelComponent,
|
||||
DeleteTimeseriesPanelComponent,
|
||||
AliasesEntitySelectPanelComponent,
|
||||
AliasesEntitySelectComponent,
|
||||
AliasesEntityAutocompleteComponent,
|
||||
|
||||
@ -61,6 +61,13 @@ export enum TelemetryFeature {
|
||||
TIMESERIES = 'TIMESERIES'
|
||||
}
|
||||
|
||||
export enum TimeseriesDeleteStrategy {
|
||||
DELETE_ALL_DATA_INCLUDING_KEY = 'DELETE_ALL_DATA_INCLUDING_KEY',
|
||||
DELETE_OLD_DATA_EXCEPT_LATEST_VALUE = 'DELETE_OLD_DATA_EXCEPT_LATEST_VALUE',
|
||||
DELETE_LATEST_VALUE = 'DELETE_LATEST_VALUE',
|
||||
DELETE_DATA_FOR_TIME_PERIOD = 'DELETE_DATA_FOR_TIME_PERIOD'
|
||||
}
|
||||
|
||||
export type TelemetryType = LatestTelemetry | AttributeScope;
|
||||
|
||||
export const toTelemetryType = (val: string): TelemetryType => {
|
||||
@ -73,7 +80,7 @@ export const toTelemetryType = (val: string): TelemetryType => {
|
||||
|
||||
export const telemetryTypeTranslations = new Map<TelemetryType, string>(
|
||||
[
|
||||
[LatestTelemetry.LATEST_TELEMETRY, 'attribute.scope-latest-telemetry'],
|
||||
[LatestTelemetry.LATEST_TELEMETRY, 'attribute.scope-telemetry'],
|
||||
[AttributeScope.CLIENT_SCOPE, 'attribute.scope-client'],
|
||||
[AttributeScope.SERVER_SCOPE, 'attribute.scope-server'],
|
||||
[AttributeScope.SHARED_SCOPE, 'attribute.scope-shared']
|
||||
@ -89,6 +96,15 @@ export const isClientSideTelemetryType = new Map<TelemetryType, boolean>(
|
||||
]
|
||||
);
|
||||
|
||||
export const timeseriesDeleteStrategyTranslations = new Map<TimeseriesDeleteStrategy, string>(
|
||||
[
|
||||
[TimeseriesDeleteStrategy.DELETE_ALL_DATA_INCLUDING_KEY, 'attribute.delete-timeseries.all-data-including-key'],
|
||||
[TimeseriesDeleteStrategy.DELETE_OLD_DATA_EXCEPT_LATEST_VALUE, 'attribute.delete-timeseries.old-data-except-latest'],
|
||||
[TimeseriesDeleteStrategy.DELETE_LATEST_VALUE, 'attribute.delete-timeseries.latest-value'],
|
||||
[TimeseriesDeleteStrategy.DELETE_DATA_FOR_TIME_PERIOD, 'attribute.delete-timeseries.data-for-time-period']
|
||||
]
|
||||
)
|
||||
|
||||
export interface AttributeData {
|
||||
lastUpdateTs?: number;
|
||||
key: string;
|
||||
|
||||
@ -632,7 +632,7 @@
|
||||
"attributes": "Atributs",
|
||||
"latest-telemetry": "Última telemetria",
|
||||
"attributes-scope": "Abast dels atributs del dispositiu",
|
||||
"scope-latest-telemetry": "Última telemetria",
|
||||
"scope-telemetry": "Telemetria",
|
||||
"scope-client": "Atributs del Client",
|
||||
"scope-server": "Atributs del Servidor",
|
||||
"scope-shared": "Atributs Compartits",
|
||||
|
||||
@ -445,7 +445,7 @@
|
||||
"attributes": "Atributy",
|
||||
"latest-telemetry": "Poslední telemetrie",
|
||||
"attributes-scope": "Rozsah atributů entity",
|
||||
"scope-latest-telemetry": "Poslední telemetrie",
|
||||
"scope-telemetry": "Telemetrie",
|
||||
"scope-client": "Atributy klienta",
|
||||
"scope-server": "Atributy serveru",
|
||||
"scope-shared": "Sdílené atributy",
|
||||
|
||||
@ -453,7 +453,7 @@
|
||||
"attributes": "Attributter",
|
||||
"latest-telemetry": "Seneste telemetri",
|
||||
"attributes-scope": "Omfang af entitetsattributter",
|
||||
"scope-latest-telemetry": "Seneste telemetri",
|
||||
"scope-telemetry": "Telemetri",
|
||||
"scope-client": "Klientattributter",
|
||||
"scope-server": "Serverattributter",
|
||||
"scope-shared": "Delte attributter",
|
||||
|
||||
@ -324,7 +324,7 @@
|
||||
"attributes": "Eigenschaften",
|
||||
"latest-telemetry": "Neueste Telemetrie",
|
||||
"attributes-scope": "Entitätseigenschaftsbereich",
|
||||
"scope-latest-telemetry": "Neueste Telemetrie",
|
||||
"scope-telemetry": "Telemetrie",
|
||||
"scope-client": "Client Eigenschaften",
|
||||
"scope-server": "Server Eigenschaften",
|
||||
"scope-shared": "Gemeinsame Eigenschaften",
|
||||
|
||||
@ -291,7 +291,7 @@
|
||||
"attributes": "Χαρακτηριστικά",
|
||||
"latest-telemetry": "Τελευταία τηλεμετρία",
|
||||
"attributes-scope": "Πεδίο εφαρμογής Χαρακτηριστικών Οντότητας",
|
||||
"scope-latest-telemetry": "Τελευταία τηλεμετρία",
|
||||
"scope-telemetry": "Τηλεμετρία",
|
||||
"scope-client": "Χαρακτηριστικά Client",
|
||||
"scope-server": "Χαρακτηριστικά Server",
|
||||
"scope-shared": "Κοινόχρηστα Χαρακτηριστικά",
|
||||
|
||||
@ -691,7 +691,7 @@
|
||||
"attributes": "Attributes",
|
||||
"latest-telemetry": "Latest telemetry",
|
||||
"attributes-scope": "Entity attributes scope",
|
||||
"scope-latest-telemetry": "Latest telemetry",
|
||||
"scope-telemetry": "Telemetry",
|
||||
"scope-client": "Client attributes",
|
||||
"scope-server": "Server attributes",
|
||||
"scope-shared": "Shared attributes",
|
||||
@ -717,7 +717,18 @@
|
||||
"no-attributes-text": "No attributes found",
|
||||
"no-telemetry-text": "No telemetry found",
|
||||
"copy-key": "Copy key",
|
||||
"copy-value": "Copy value"
|
||||
"copy-value": "Copy value",
|
||||
"delete-timeseries": {
|
||||
"start-time": "Start time",
|
||||
"ends-on": "Ends on",
|
||||
"strategy": "Strategy",
|
||||
"delete-strategy": "Delete strategy",
|
||||
"all-data-including-key": "Delete all data including key",
|
||||
"old-data-except-latest": "Delete old data except latest value",
|
||||
"latest-value": "Delete latest value",
|
||||
"data-for-time-period": "Delete data for time period",
|
||||
"rewrite-latest-value-if-deleted": "Rewrite latest value if deleted"
|
||||
}
|
||||
},
|
||||
"api-usage": {
|
||||
"api-features": "API features",
|
||||
|
||||
@ -667,7 +667,7 @@
|
||||
"attributes": "Atributos",
|
||||
"latest-telemetry": "Última telemetría",
|
||||
"attributes-scope": "Alcance de los atributos del dispositivo",
|
||||
"scope-latest-telemetry": "Última telemetría",
|
||||
"scope-telemetry": "Telemetría",
|
||||
"scope-client": "Atributos de Cliente",
|
||||
"scope-server": "Atributos de Servidor",
|
||||
"scope-shared": "Atributos Compartidos",
|
||||
|
||||
@ -254,7 +254,7 @@
|
||||
"attributes": "ويژگي ها",
|
||||
"latest-telemetry": "آخرين سنجش",
|
||||
"attributes-scope": "حوزه ويژگي هاي موجودي",
|
||||
"scope-latest-telemetry": "آخرين سنجش",
|
||||
"scope-telemetry": "تله متری",
|
||||
"scope-client": "ويژگي هاي مشتري",
|
||||
"scope-server": "ويژگي هاي سِروِر",
|
||||
"scope-shared": "ويژگي هاي مشترک",
|
||||
|
||||
@ -459,7 +459,7 @@
|
||||
"next-widget": "Widget suivant",
|
||||
"prev-widget": "Widget précédent",
|
||||
"scope-client": "Attributs du client",
|
||||
"scope-latest-telemetry": "Dernière télémétrie",
|
||||
"scope-telemetry": "Télémétrie",
|
||||
"scope-server": "Attributs du serveur",
|
||||
"scope-shared": "Attributs partagés",
|
||||
"selected-attributes": "{count, plural, =1 {1 attribut} other {# attributs} } sélectionnés",
|
||||
|
||||
@ -276,7 +276,7 @@
|
||||
"attributes": "Attributi",
|
||||
"latest-telemetry": "Ultima telemetria",
|
||||
"attributes-scope": "Visibilità attributi entità",
|
||||
"scope-latest-telemetry": "Ultima telemetria",
|
||||
"scope-telemetry": "Telemetria",
|
||||
"scope-client": "Attributi client",
|
||||
"scope-server": "Attributi server",
|
||||
"scope-shared": "Attributi condivisi",
|
||||
|
||||
@ -244,7 +244,7 @@
|
||||
"attributes": "属性",
|
||||
"latest-telemetry": "最新テレメトリ",
|
||||
"attributes-scope": "エンティティ属性のスコープ",
|
||||
"scope-latest-telemetry": "最新テレメトリ",
|
||||
"scope-telemetry": "テレメトリー",
|
||||
"scope-client": "クライアントの属性",
|
||||
"scope-server": "サーバーの属性",
|
||||
"scope-shared": "共有属性",
|
||||
|
||||
@ -290,7 +290,7 @@
|
||||
"attributes": "ატრიბუტები",
|
||||
"latest-telemetry": "უახლესი ტელემეტრია",
|
||||
"attributes-scope": "ობიექტის ატრიბუტების ფარგლები",
|
||||
"scope-latest-telemetry": "უახლესი ტელემეტრია",
|
||||
"scope-telemetry": "ტელემეტრია",
|
||||
"scope-client": "კლიენტის ატრიბუტები",
|
||||
"scope-server": "სერვერის ატრიბუტები",
|
||||
"scope-shared": "ატრიბუტების გაზიარება",
|
||||
|
||||
@ -408,7 +408,7 @@
|
||||
"attributes": "속성",
|
||||
"latest-telemetry": "최근 데이터",
|
||||
"attributes-scope": "장치 속성 범위",
|
||||
"scope-latest-telemetry": "최근 데이터",
|
||||
"scope-telemetry": "원격 측정",
|
||||
"scope-client": "클라이언트 속성",
|
||||
"scope-server": "서버 속성",
|
||||
"scope-shared": "공유 속성",
|
||||
|
||||
@ -256,7 +256,7 @@
|
||||
"attributes": "Attribūti",
|
||||
"latest-telemetry": "Jaunākā telemetrija",
|
||||
"attributes-scope": "Vienības atribūtu darbības joma",
|
||||
"scope-latest-telemetry": "Jaunākā telemetrija",
|
||||
"scope-telemetry": "Telemetrija",
|
||||
"scope-client": "Klientu atribūti",
|
||||
"scope-server": "Servera atribūti",
|
||||
"scope-shared": "Dalītie atribūti",
|
||||
|
||||
@ -309,7 +309,7 @@
|
||||
"attributes": "Atributos",
|
||||
"latest-telemetry": "Última telemetria",
|
||||
"attributes-scope": "Escopo de atributos de entidade",
|
||||
"scope-latest-telemetry": "Última telemetria",
|
||||
"scope-telemetry": "Telemetria",
|
||||
"scope-client": "Atributos do cliente",
|
||||
"scope-server": "Atributos do servidor",
|
||||
"scope-shared": "Atributos compartilhados",
|
||||
|
||||
@ -285,7 +285,7 @@
|
||||
"attributes": "Atribute",
|
||||
"latest-telemetry": "Ultimele Date Telemetrice",
|
||||
"attributes-scope": "Scop Atribute Entitate",
|
||||
"scope-latest-telemetry": "Ultimele Date Telemetrice",
|
||||
"scope-telemetry": "Telemetrie",
|
||||
"scope-client": "Atribute Client",
|
||||
"scope-server": "Atribute Server",
|
||||
"scope-shared": "Atribute Partajate",
|
||||
|
||||
@ -408,7 +408,7 @@
|
||||
"attributes": "Lastnosti",
|
||||
"latest-telemetry": "Najnovejša telemetrija",
|
||||
"attributes-scope": "Obseg atributov entitete",
|
||||
"scope-latest-telemetry": "Najnovejša telemetrija",
|
||||
"scope-telemetry": "Telemetrija",
|
||||
"scope-client": "Atributi odjemalca",
|
||||
"scope-server": "Atributi strežnika",
|
||||
"scope-shared": "Skupni atributi",
|
||||
|
||||
@ -445,7 +445,7 @@
|
||||
"attributes": "Öznitelikler",
|
||||
"latest-telemetry": "Son telemetri",
|
||||
"attributes-scope": "Varlık öznitelik kapsamı",
|
||||
"scope-latest-telemetry": "Son telemetri",
|
||||
"scope-telemetry": "telemetri",
|
||||
"scope-client": "İstemci öznitelikler",
|
||||
"scope-server": "Sunucu öznitelikler",
|
||||
"scope-shared": "Paylaşılan öznitelikler",
|
||||
|
||||
@ -342,7 +342,7 @@
|
||||
"attributes": "Атрибути",
|
||||
"latest-telemetry": "Остання телеметрія",
|
||||
"attributes-scope": "Область видимості атрибутів",
|
||||
"scope-latest-telemetry": "Остання телеметрія",
|
||||
"scope-telemetry": "Телеметрія",
|
||||
"scope-client": "Клієнтські атрибути",
|
||||
"scope-server": "Серверні атрибути",
|
||||
"scope-shared": "Спільні атрибути",
|
||||
|
||||
@ -590,7 +590,7 @@
|
||||
"attributes": "属性",
|
||||
"latest-telemetry": "最新遥测数据",
|
||||
"attributes-scope": "设备属性范围",
|
||||
"scope-latest-telemetry": "最新遥测数据",
|
||||
"scope-telemetry": "遥测",
|
||||
"scope-client": "客户端属性",
|
||||
"scope-server": "服务端属性",
|
||||
"scope-shared": "共享属性",
|
||||
|
||||
@ -519,7 +519,7 @@
|
||||
"attributes": "屬性",
|
||||
"latest-telemetry": "最新遙測",
|
||||
"attributes-scope": "設備屬性範圍",
|
||||
"scope-latest-telemetry": "最新遙測",
|
||||
"scope-telemetry": "遙測",
|
||||
"scope-client": "客戶端屬性",
|
||||
"scope-server": "服務端屬性",
|
||||
"scope-shared": "共享屬性",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user