Browse Source

UI: Refactoring delete telemetry

pull/8928/head
Vladyslav_Prykhodko 3 years ago
parent
commit
a85f9fbabc
  1. 12
      ui-ngx/src/app/core/http/attribute.service.ts
  2. 2
      ui-ngx/src/app/modules/home/components/attribute/attribute-table.component.html
  3. 65
      ui-ngx/src/app/modules/home/components/attribute/attribute-table.component.ts
  4. 72
      ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.html
  5. 28
      ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.scss
  6. 25
      ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.ts

12
ui-ngx/src/app/core/http/attribute.service.ts

@ -53,8 +53,16 @@ export class AttributeService {
startTs?: number, endTs?: number, rewriteLatestIfDeleted = false, deleteLatest = true, startTs?: number, endTs?: number, rewriteLatestIfDeleted = false, deleteLatest = true,
config?: RequestConfig): Observable<any> { config?: RequestConfig): Observable<any> {
const keys = timeseries.map(attribute => encodeURIComponent(attribute.key)).join(','); const keys = timeseries.map(attribute => encodeURIComponent(attribute.key)).join(',');
let url = `/api/plugins/telemetry/${entityId.entityType}/${entityId.id}/timeseries/delete` + let url = `/api/plugins/telemetry/${entityId.entityType}/${entityId.id}/timeseries/delete?keys=${keys}`;
`?keys=${keys}&deleteAllDataForKeys=${deleteAllDataForKeys}&rewriteLatestIfDeleted=${rewriteLatestIfDeleted}&deleteLatest=${deleteLatest}`; if (isDefinedAndNotNull(deleteAllDataForKeys)) {
url += `&deleteAllDataForKeys=${deleteAllDataForKeys}`;
}
if (isDefinedAndNotNull(rewriteLatestIfDeleted)) {
url += `&rewriteLatestIfDeleted=${rewriteLatestIfDeleted}`;
}
if (isDefinedAndNotNull(deleteLatest)) {
url += `&deleteLatest=${deleteLatest}`;
}
if (isDefinedAndNotNull(startTs)) { if (isDefinedAndNotNull(startTs)) {
url += `&startTs=${startTs}`; url += `&startTs=${startTs}`;
} }

2
ui-ngx/src/app/modules/home/components/attribute/attribute-table.component.html

@ -198,7 +198,7 @@
<span [fxShow]="!isClientSideTelemetryTypeMap.get(attributeScope)"> <span [fxShow]="!isClientSideTelemetryTypeMap.get(attributeScope)">
<mat-icon>edit</mat-icon> <mat-icon>edit</mat-icon>
</span> </span>
<button mat-icon-button [fxShow]="attributeScope === latestTelemetryTypes.LATEST_TELEMETRY" <button mat-icon-button *ngIf="attributeScope === latestTelemetryTypes.LATEST_TELEMETRY"
(click)="deleteTimeseries($event, attribute)"> (click)="deleteTimeseries($event, attribute)">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
</button> </button>

65
ui-ngx/src/app/modules/home/components/attribute/attribute-table.component.ts

@ -38,7 +38,7 @@ import { TranslateService } from '@ngx-translate/core';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { DialogService } from '@core/services/dialog.service'; import { DialogService } from '@core/services/dialog.service';
import { Direction, SortOrder } from '@shared/models/page/sort-order'; import { Direction, SortOrder } from '@shared/models/page/sort-order';
import { fromEvent, merge, Observable } from 'rxjs'; import { fromEvent, merge } from 'rxjs';
import { debounceTime, distinctUntilChanged, tap } from 'rxjs/operators'; import { debounceTime, distinctUntilChanged, tap } from 'rxjs/operators';
import { EntityId } from '@shared/models/id/entity-id'; import { EntityId } from '@shared/models/id/entity-id';
import { import {
@ -48,7 +48,8 @@ import {
isClientSideTelemetryType, isClientSideTelemetryType,
LatestTelemetry, LatestTelemetry,
TelemetryType, TelemetryType,
telemetryTypeTranslations, TimeseriesDeleteStrategy, telemetryTypeTranslations,
TimeseriesDeleteStrategy,
toTelemetryType toTelemetryType
} from '@shared/models/telemetry/telemetry.models'; } from '@shared/models/telemetry/telemetry.models';
import { AttributeDatasource } from '@home/models/datasource/attribute-datasource'; import { AttributeDatasource } from '@home/models/datasource/attribute-datasource';
@ -88,7 +89,8 @@ import { hidePageSizePixelValue } from '@shared/models/constants';
import { ResizeObserver } from '@juggle/resize-observer'; import { ResizeObserver } from '@juggle/resize-observer';
import { import {
DELETE_TIMESERIES_PANEL_DATA, DELETE_TIMESERIES_PANEL_DATA,
DeleteTimeseriesPanelComponent, DeleteTimeseriesPanelData DeleteTimeseriesPanelComponent,
DeleteTimeseriesPanelData
} from '@home/components/attribute/delete-timeseries-panel.component'; } from '@home/components/attribute/delete-timeseries-panel.component';
@ -383,15 +385,19 @@ export class AttributeTableComponent extends PageComponent implements AfterViewI
}); });
} }
deleteTimeseries($event: Event, attribute?: AttributeData) { deleteTimeseries($event: Event, telemetry?: AttributeData) {
if ($event) { if ($event) {
$event.stopPropagation(); $event.stopPropagation();
} }
const isMultipleDeletion = isUndefinedOrNull(attribute) && this.dataSource.selection.selected.length > 1; const isMultipleDeletion = isUndefinedOrNull(telemetry) && this.dataSource.selection.selected.length > 1;
const target = $event.target || $event.srcElement || $event.currentTarget; const target = $event.target || $event.srcElement || $event.currentTarget;
const config = new OverlayConfig(); const config = new OverlayConfig({
config.backdropClass = 'cdk-overlay-transparent-backdrop'; panelClass: 'tb-filter-panel',
config.hasBackdrop = true; backdropClass: 'cdk-overlay-transparent-backdrop',
hasBackdrop: true,
maxWidth: 488,
width: '100%'
});
const connectedPosition: ConnectedPosition = { const connectedPosition: ConnectedPosition = {
originX: 'start', originX: 'start',
originY: 'top', originY: 'top',
@ -400,8 +406,6 @@ export class AttributeTableComponent extends PageComponent implements AfterViewI
}; };
config.positionStrategy = this.overlay.position().flexibleConnectedTo(target as HTMLElement) config.positionStrategy = this.overlay.position().flexibleConnectedTo(target as HTMLElement)
.withPositions([connectedPosition]); .withPositions([connectedPosition]);
config.maxWidth = '488px';
config.width = '100%';
const overlayRef = this.overlay.create(config); const overlayRef = this.overlay.create(config);
overlayRef.backdropClick().subscribe(() => { overlayRef.backdropClick().subscribe(() => {
overlayRef.dispose(); overlayRef.dispose();
@ -411,7 +415,7 @@ export class AttributeTableComponent extends PageComponent implements AfterViewI
{ {
provide: DELETE_TIMESERIES_PANEL_DATA, provide: DELETE_TIMESERIES_PANEL_DATA,
useValue: { useValue: {
isMultipleDeletion: isMultipleDeletion isMultipleDeletion
} as DeleteTimeseriesPanelData } as DeleteTimeseriesPanelData
}, },
{ {
@ -425,31 +429,34 @@ export class AttributeTableComponent extends PageComponent implements AfterViewI
componentRef.onDestroy(() => { componentRef.onDestroy(() => {
if (componentRef.instance.result !== null) { if (componentRef.instance.result !== null) {
const result = componentRef.instance.result; const result = componentRef.instance.result;
const deleteTimeseries = attribute ? [attribute]: this.dataSource.selection.selected; const deleteTimeseries = telemetry ? [telemetry]: this.dataSource.selection.selected;
let deleteAllDataForKeys = false; let deleteAllDataForKeys = false;
let rewriteLatestIfDeleted = false; let rewriteLatestIfDeleted = false;
let startTs = null; let startTs = null;
let endTs = null; let endTs = null;
let deleteLatest = true; let deleteLatest = true;
if (result.strategy === TimeseriesDeleteStrategy.DELETE_ALL_DATA) { switch (result.strategy) {
deleteAllDataForKeys = true; case TimeseriesDeleteStrategy.DELETE_ALL_DATA:
} deleteAllDataForKeys = true;
if (result.strategy === TimeseriesDeleteStrategy.DELETE_ALL_DATA_EXCEPT_LATEST_VALUE) { break;
deleteAllDataForKeys = true; case TimeseriesDeleteStrategy.DELETE_ALL_DATA_EXCEPT_LATEST_VALUE:
deleteLatest = false; deleteAllDataForKeys = true;
} deleteLatest = false;
if (result.strategy === TimeseriesDeleteStrategy.DELETE_LATEST_VALUE) { break;
rewriteLatestIfDeleted = result.rewriteLatest; case TimeseriesDeleteStrategy.DELETE_LATEST_VALUE:
startTs = deleteTimeseries[0].lastUpdateTs; rewriteLatestIfDeleted = result.rewriteLatest;
endTs = startTs + 1; startTs = deleteTimeseries[0].lastUpdateTs;
} endTs = startTs + 1;
if (result.strategy === TimeseriesDeleteStrategy.DELETE_ALL_DATA_FOR_TIME_PERIOD) { break;
startTs = result.startDateTime.getTime(); case TimeseriesDeleteStrategy.DELETE_ALL_DATA_FOR_TIME_PERIOD:
endTs = result.endDateTime.getTime(); startTs = result.startDateTime.getTime();
rewriteLatestIfDeleted = result.rewriteLatest; endTs = result.endDateTime.getTime();
rewriteLatestIfDeleted = result.rewriteLatest;
break;
} }
this.attributeService.deleteEntityTimeseries(this.entityIdValue, deleteTimeseries, deleteAllDataForKeys, this.attributeService.deleteEntityTimeseries(this.entityIdValue, deleteTimeseries, deleteAllDataForKeys,
startTs, endTs, rewriteLatestIfDeleted, deleteLatest).subscribe(() => this.reloadAttributes()); startTs, endTs, rewriteLatestIfDeleted, deleteLatest)
.subscribe(() => this.reloadAttributes());
} }
}); });
} }

72
ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.html

@ -16,47 +16,41 @@
--> -->
<form [formGroup]="deleteTimeseriesFormGroup" style="max-width: 488px"> <mat-toolbar>
<mat-toolbar> <h2>{{ "attribute.delete-timeseries.delete-strategy" | translate }}</h2>
<h2>{{ "attribute.delete-timeseries.delete-strategy" | translate }}</h2> <span fxFlex></span>
<span fxFlex></span> <button mat-icon-button
<button mat-icon-button type="button"
type="button" (click)="cancel()">
(click)="cancel()"> <mat-icon class="material-icons">close</mat-icon>
<mat-icon class="material-icons">close</mat-icon> </button>
</button> </mat-toolbar>
</mat-toolbar> <form [formGroup]="deleteTimeseriesFormGroup" class="mat-content mat-padding tb-form-settings">
<div style="padding: 16px; min-height: 188px"> <mat-form-field class="mat-block" subscriptSizing="dynamic">
<mat-form-field fxFlex class="mat-block"> <mat-label translate>attribute.delete-timeseries.strategy</mat-label>
<mat-label translate>attribute.delete-timeseries.strategy</mat-label> <mat-select formControlName="strategy">
<mat-select formControlName="strategy"> <mat-option *ngFor="let strategy of strategiesTranslationsMap.keys()" [value]="strategy">
<mat-option *ngFor="let strategy of strategiesTranslationsMap.keys()" [value]="strategy"> {{ strategiesTranslationsMap.get(strategy) | translate }}
{{ strategiesTranslationsMap.get(strategy) | translate }} </mat-option>
</mat-option> </mat-select>
</mat-select> </mat-form-field>
<div *ngIf="isPeriodStrategy()" class="tb-select-interval">
<mat-form-field class="mat-block" subscriptSizing="dynamic">
<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 formControlName="startDateTime" [matDatetimepicker]="startDateTimePicker">
</mat-form-field>
<mat-form-field class="mat-block" subscriptSizing="dynamic">
<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 formControlName="endDateTime" [matDatetimepicker]="endDatePicker">
</mat-form-field> </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 formControlName="startDateTime" [matDatetimepicker]="startDateTimePicker">
</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 formControlName="endDateTime" [matDatetimepicker]="endDatePicker">
</mat-form-field>
</div>
</div>
<div *ngIf="isPeriodStrategy() || isDeleteLatestStrategy()">
<mat-slide-toggle formControlName="rewriteLatest">
{{ "attribute.delete-timeseries.rewrite-latest-value" | translate }}
</mat-slide-toggle>
</div>
</div> </div>
<mat-slide-toggle class="tb-slide-toggle" formControlName="rewriteLatest" *ngIf="isPeriodStrategy() || isDeleteLatestStrategy()">
{{ "attribute.delete-timeseries.rewrite-latest-value" | translate }}
</mat-slide-toggle>
</form> </form>
<div fxLayout="row" class="tb-panel-actions"> <div fxLayout="row" class="tb-panel-actions">
<span fxFlex></span> <span fxFlex></span>

28
ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.scss

@ -13,16 +13,32 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
@import '../../../../../scss/constants';
:host { :host {
width: 100%; 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{ .mat-toolbar {
form .mat-toolbar {
background: none; background: none;
} }
.tb-form-settings {
flex-direction: column;
gap: 16px;
padding-top: 0;
}
.tb-select-interval {
display: flex;
flex-direction: row;
gap: 16px;
@media #{$mat-xs} {
flex-direction: column;
gap: 0;
}
}
.tb-slide-toggle {
margin-bottom: 8px;
}
} }

25
ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.ts

@ -51,34 +51,33 @@ export class DeleteTimeseriesPanelComponent implements OnInit, OnDestroy {
strategiesTranslationsMap = timeseriesDeleteStrategyTranslations; strategiesTranslationsMap = timeseriesDeleteStrategyTranslations;
multipleDeletionStrategies = [ private multipleDeletionStrategies = new Set<TimeseriesDeleteStrategy>([
TimeseriesDeleteStrategy.DELETE_ALL_DATA, TimeseriesDeleteStrategy.DELETE_ALL_DATA,
TimeseriesDeleteStrategy.DELETE_ALL_DATA_EXCEPT_LATEST_VALUE TimeseriesDeleteStrategy.DELETE_ALL_DATA_EXCEPT_LATEST_VALUE
]; ]);
private destroy$ = new Subject<void>(); private destroy$ = new Subject<void>();
constructor(@Inject(DELETE_TIMESERIES_PANEL_DATA) public data: DeleteTimeseriesPanelData, constructor(@Inject(DELETE_TIMESERIES_PANEL_DATA) private data: DeleteTimeseriesPanelData,
public overlayRef: OverlayRef, private overlayRef: OverlayRef,
public fb: FormBuilder) { } private fb: FormBuilder) { }
ngOnInit(): void { ngOnInit(): void {
const today = new Date(); const today = new Date();
if (this.data.isMultipleDeletion) { if (this.data.isMultipleDeletion) {
this.strategiesTranslationsMap = new Map(Array.from(this.strategiesTranslationsMap.entries()) this.strategiesTranslationsMap = new Map(Array.from(this.strategiesTranslationsMap)
.filter(([strategy]) => { .filter(([strategy]) => this.multipleDeletionStrategies.has(strategy)))
return this.multipleDeletionStrategies.includes(strategy);
}))
} }
this.deleteTimeseriesFormGroup = this.fb.group({ this.deleteTimeseriesFormGroup = this.fb.group({
strategy: [TimeseriesDeleteStrategy.DELETE_ALL_DATA], strategy: [TimeseriesDeleteStrategy.DELETE_ALL_DATA],
startDateTime: [ startDateTime: [
{ value: new Date(today.getFullYear(), today.getMonth() - 1, today.getDate()), disabled: true }, { value: new Date(today.getFullYear(), today.getMonth() - 1, today.getDate()), disabled: true },
[Validators.required] Validators.required
], ],
endDateTime: [{ value: today, disabled: true }, [Validators.required]], endDateTime: [{ value: today, disabled: true }, Validators.required],
rewriteLatest: [true] rewriteLatest: [true]
}) })
this.deleteTimeseriesFormGroup.get('strategy').valueChanges.pipe( this.deleteTimeseriesFormGroup.get('strategy').valueChanges.pipe(
takeUntil(this.destroy$) takeUntil(this.destroy$)
).subscribe(value => { ).subscribe(value => {
@ -124,7 +123,7 @@ export class DeleteTimeseriesPanelComponent implements OnInit, OnDestroy {
return this.deleteTimeseriesFormGroup.get('strategy').value === TimeseriesDeleteStrategy.DELETE_LATEST_VALUE; return this.deleteTimeseriesFormGroup.get('strategy').value === TimeseriesDeleteStrategy.DELETE_LATEST_VALUE;
} }
onStartDateTimeChange(newStartDateTime: Date) { private onStartDateTimeChange(newStartDateTime: Date) {
if (newStartDateTime) { if (newStartDateTime) {
const endDateTimeTs = this.deleteTimeseriesFormGroup.get('endDateTime').value.getTime(); const endDateTimeTs = this.deleteTimeseriesFormGroup.get('endDateTime').value.getTime();
if (newStartDateTime.getTime() >= endDateTimeTs) { if (newStartDateTime.getTime() >= endDateTimeTs) {
@ -137,7 +136,7 @@ export class DeleteTimeseriesPanelComponent implements OnInit, OnDestroy {
} }
} }
onEndDateTimeChange(newEndDateTime: Date) { private onEndDateTimeChange(newEndDateTime: Date) {
if (newEndDateTime) { if (newEndDateTime) {
const startDateTimeTs = this.deleteTimeseriesFormGroup.get('startDateTime').value.getTime(); const startDateTimeTs = this.deleteTimeseriesFormGroup.get('startDateTime').value.getTime();
if (newEndDateTime.getTime() <= startDateTimeTs) { if (newEndDateTime.getTime() <= startDateTimeTs) {

Loading…
Cancel
Save