UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

92 lines 14.6 kB
import { Component, Input, Output, ViewChild, EventEmitter, ElementRef } from '@angular/core'; import { AppLogsService } from './app-logs.service'; import { fromEvent, Subject, of, interval, NEVER } from 'rxjs'; import { filter, catchError, tap, debounce, switchMap, takeUntil, finalize, delay, repeat, merge, scan } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "./app-logs.service"; import * as i2 from "@angular/common"; import * as i3 from "@c8y/ngx-components"; export class AppLogsAutoRefreshComponent { set buttonsDisabled(areDisabled) { this.isAutoRefreshDisabled = areDisabled; if (areDisabled && this.isAutoRefreshOn) { this.isAutoRefreshOn = false; this.cancel$.next(false); } } constructor(appLogsService) { this.appLogsService = appLogsService; this.cancel$ = new Subject(); this.isAutoRefreshDisabled = false; this.logsToOutput = this.getEmptyLogsJson(); this.isAutoRefreshOn = true; this.onNewLogs = new EventEmitter(); this.isRealtimeEnabled = new EventEmitter(); this.toggleState = currentState => !currentState; } ngAfterViewInit() { const clicks$ = fromEvent(this.button.nativeElement, 'click').pipe(merge(this.cancel$), debounce(() => interval(300)), scan(this.toggleState, false), tap(isAutoRefreshOn => this.setButtonState(isAutoRefreshOn)), switchMap(isOn => (isOn ? this.watchForNewLogs() : NEVER))); this.subscription = clicks$.subscribe(); } ngOnDestroy() { if (this.subscription) { this.subscription.unsubscribe(); } } setButtonState(isAutoRefreshOn) { this.isAutoRefreshOn = isAutoRefreshOn; this.isRealtimeEnabled.emit(isAutoRefreshOn); } watchForNewLogs() { return this.startPolling().pipe(takeUntil(this.cancel$.pipe(filter(isAutoRefreshOn => isAutoRefreshOn === false))), finalize(() => { this.isAutoRefreshOn = false; })); } startPolling() { return of(1).pipe(switchMap(() => this.getNewLogs().pipe(catchError(() => of(this.getEmptyLogsJson())))), tap(logs => this.updateLogsToOutput(logs)), delay(10000), repeat()); } getNewLogs() { return this.appLogsService.getLogs$(this.getAppId(), this.getInstanceName()); } getAppId() { return this.mo.applicationId; } getInstanceName() { return this.selectedInstance.name; } updateLogsToOutput(newLogs) { const { dateFrom, dateTo } = newLogs; if (dateFrom && dateTo) { this.logsToOutput = { ...newLogs }; this.onNewLogs.emit(this.logsToOutput); } } getEmptyLogsJson() { return { dateFrom: null, dateTo: null, logs: '', truncated: false }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AppLogsAutoRefreshComponent, deps: [{ token: i1.AppLogsService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AppLogsAutoRefreshComponent, selector: "c8y-app-logs-auto-refresh", inputs: { selectedInstance: "selectedInstance", mo: "mo", buttonsDisabled: "buttonsDisabled" }, outputs: { onNewLogs: "onNewLogs", isRealtimeEnabled: "isRealtimeEnabled" }, viewQueries: [{ propertyName: "button", first: true, predicate: ["autoRefresh"], descendants: true, static: true }], ngImport: i0, template: "<button #autoRefresh\n type=\"button\"\n class=\"btn btn-link c8y-realtime\"\n [ngStyle]=\"{'width': 'auto'}\"\n title=\"{{'Toggle auto refresh' | translate}}\"\n [disabled]=\"isAutoRefreshDisabled\"\n>\n <span class=\"c8y-pulse\" [ngClass]=\"isAutoRefreshOn ? 'active' : 'inactive'\"></span>\n {{'Auto refresh' | translate}}\n</button>", dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AppLogsAutoRefreshComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-app-logs-auto-refresh', template: "<button #autoRefresh\n type=\"button\"\n class=\"btn btn-link c8y-realtime\"\n [ngStyle]=\"{'width': 'auto'}\"\n title=\"{{'Toggle auto refresh' | translate}}\"\n [disabled]=\"isAutoRefreshDisabled\"\n>\n <span class=\"c8y-pulse\" [ngClass]=\"isAutoRefreshOn ? 'active' : 'inactive'\"></span>\n {{'Auto refresh' | translate}}\n</button>" }] }], ctorParameters: () => [{ type: i1.AppLogsService }], propDecorators: { selectedInstance: [{ type: Input }], mo: [{ type: Input }], buttonsDisabled: [{ type: Input }], onNewLogs: [{ type: Output }], isRealtimeEnabled: [{ type: Output }], button: [{ type: ViewChild, args: ['autoRefresh', { static: true }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLWxvZ3MtYXV0by1yZWZyZXNoLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2FwcC1sb2dzL2FwcC1sb2dzLWF1dG8tcmVmcmVzaC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi9hcHAtbG9ncy9hcHAtbG9ncy1hdXRvLXJlZnJlc2guY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTlGLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNwRCxPQUFPLEVBQWMsU0FBUyxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDekYsT0FBTyxFQUNMLE1BQU0sRUFDTixVQUFVLEVBQ1YsR0FBRyxFQUNILFFBQVEsRUFDUixTQUFTLEVBQ1QsU0FBUyxFQUNULFFBQVEsRUFDUixLQUFLLEVBQ0wsTUFBTSxFQUNOLEtBQUssRUFDTCxJQUFJLEVBQ0wsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7QUFNeEIsTUFBTSxPQUFPLDJCQUEyQjtJQVF0QyxJQUFhLGVBQWUsQ0FBQyxXQUFvQjtRQUMvQyxJQUFJLENBQUMscUJBQXFCLEdBQUcsV0FBVyxDQUFDO1FBQ3pDLElBQUksV0FBVyxJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUN4QyxJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztZQUM3QixJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzQixDQUFDO0lBQ0gsQ0FBQztJQU9ELFlBQW9CLGNBQThCO1FBQTlCLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQXBCbEQsWUFBTyxHQUFxQixJQUFJLE9BQU8sRUFB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QUNoQyxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQztRQUNyQyxJQUFJLFFBQVEsSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsR0FBRyxPQUFPLEVBQUUsQ0FBQztZQUNuQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDekMsQ0FBQztJQUNILENBQUM7SUFFTyxnQkFBZ0I7UUFDdEIsT0FBTztZQUNMLFFBQVEsRUFBRSxJQUFJO1lBQ2QsTUFBTSxFQUFFLElBQUk7WUFDWixJQUFJLEVBQUUsRUFBRTtZQUNSLFNBQVMsRUFBRSxLQUFLO1NBQ2pCLENBQUM7SUFDSixDQUFDOytHQTFGVSwyQkFBMkI7bUdBQTNCLDJCQUEyQixtV0N0QnhDLHlWQVNTOzs0RkRhSSwyQkFBMkI7a0JBSnZDLFNBQVM7K0JBQ0UsMkJBQTJCO21GQVM1QixnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csRUFBRTtzQkFBVixLQUFLO2dCQUNPLGVBQWU7c0JBQTNCLEtBQUs7Z0JBT0ksU0FBUztzQkFBbEIsTUFBTTtnQkFDRyxpQkFBaUI7c0JBQTFCLE1BQU07Z0JBQ3FDLE1BQU07c0JBQWpELFNBQVM7dUJBQUMsYUFBYSxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE91dHB1dCwgVmlld0NoaWxkLCBFdmVudEVtaXR0ZXIsIEVsZW1lbnRSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IExvZ3NKU09OIH0gZnJvbSAnLi9sb2dzLm1vZGVsJztcbmltcG9ydCB7IEFwcExvZ3NTZXJ2aWNlIH0gZnJvbSAnLi9hcHAtbG9ncy5zZXJ2aWNlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIGZyb21FdmVudCwgU3ViamVjdCwgb2YsIGludGVydmFsLCBORVZFUiwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge1xuICBmaWx0ZXIsXG4gIGNhdGNoRXJyb3IsXG4gIHRhcCxcbiAgZGVib3VuY2UsXG4gIHN3aXRjaE1hcCxcbiAgdGFrZVVudGlsLFxuICBmaW5hbGl6ZSxcbiAgZGVsYXksXG4gIHJlcGVhdCxcbiAgbWVyZ2UsXG4gIHNjYW5cbn0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktYXBwLWxvZ3MtYXV0by1yZWZyZXNoJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2FwcC1sb2dzLWF1dG8tcmVmcmVzaC5jb21wb25lbnQuaHRtbCdcbn0pXG5leHBvcnQgY2xhc3MgQXBwTG9nc0F1dG9SZWZyZXNoQ29tcG9uZW50IHtcbiAgY2FuY2VsJDogU3ViamVjdDxib29sZWFuPiA9IG5ldyBTdWJqZWN0PGJvb2xlYW4+KCk7XG4gIGlzQXV0b1JlZnJlc2hEaXNhYmxlZCA9IGZhbHNlO1xuICBsb2dzVG9PdXRwdXQ6IExvZ3NKU09OID0gdGhpcy5nZXRFbXB0eUxvZ3NKc29uKCk7XG4gIGlzQXV0b1JlZnJlc2hPbiA9IHRydWU7XG5cbiAgQElucHV0KCkgc2VsZWN0ZWRJbnN0YW5jZTogYW55O1xuICBASW5wdXQoKSBtbzogYW55O1xuICBASW5wdXQoKSBzZXQgYnV0dG9uc0Rpc2FibGVkKGFyZURpc2FibGVkOiBib29sZWFuKSB7XG4gICAgdGhpcy5pc0F1dG9SZWZyZXNoRGlzYWJsZWQgPSBhcmVEaXNhYmxlZDtcbiAgICBpZiAoYXJlRGlzYWJsZWQgJiYgdGhpcy5pc0F1dG9SZWZyZXNoT24pIHtcbiAgICAgIHRoaXMuaXNBdXRvUmVmcmVzaE9uID0gZmFsc2U7XG4gICAgICB0aGlzLmNhbmNlbCQubmV4dChmYWxzZSk7XG4gICAgfVxuICB9XG4gIEBPdXRwdXQoKSBvbk5ld0xvZ3MgPSBuZXcgRXZlbnRFbWl0dGVyPExvZ3NKU09OPigpO1xuICBAT3V0cHV0KCkgaXNSZWFsdGltZUVuYWJsZWQgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG4gIEBWaWV3Q2hpbGQoJ2F1dG9SZWZyZXNoJywgeyBzdGF0aWM6IHRydWUgfSkgYnV0dG9uOiBFbGVtZW50UmVmO1xuXG4gIHByaXZhdGUgc3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBhcHBMb2dzU2VydmljZTogQXBwTG9nc1NlcnZpY2UpIHt9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIGNvbnN0IGNsaWNrcyQgPSBmcm9tRXZlbnQodGhpcy5idXR0b24ubmF0aXZlRWxlbWVudCwgJ2NsaWNrJykucGlwZShcbiAgICAgIG1lcmdlKHRoaXMuY2FuY2VsJCksXG4gICAgICBkZWJvdW5jZSgoKSA9PiBpbnRlcnZhbCgzMDApKSxcbiAgICAgIHNjYW4odGhpcy50b2dnbGVTdGF0ZSwgZmFsc2UpLFxuICAgICAgdGFwKGlzQXV0b1JlZnJlc2hPbiA9PiB0aGlzLnNldEJ1dHRvblN0YXRlKGlzQXV0b1JlZnJlc2hPbikpLFxuICAgICAgc3dpdGNoTWFwKGlzT24gPT4gKGlzT24gPyB0aGlzLndhdGNoRm9yTmV3TG9ncygpIDogTkVWRVIpKVxuICAgICk7XG4gICAgdGhpcy5zdWJzY3JpcHRpb24gPSBjbGlja3MkLnN1YnNjcmliZSgpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgaWYgKHRoaXMuc3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLnN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgfVxuICBwcml2YXRlIHRvZ2dsZVN0YXRlID0gY3VycmVudFN0YXRlID0+ICFjdXJyZW50U3RhdGU7XG5cbiAgcHJpdmF0ZSBzZXRCdXR0b25TdGF0ZShpc0F1dG9SZWZyZXNoT246IGJvb2xlYW4pIHtcbiAgICB0aGlzLmlzQXV0b1JlZnJlc2hPbiA9IGlzQXV0b1JlZnJlc2hPbjtcbiAgICB0aGlzLmlzUmVhbHRpbWVFbmFibGVkLmVtaXQoaXNBdXRvUmVmcmVzaE9uKTtcbiAgfVxuXG4gIHByaXZhdGUgd2F0Y2hGb3JOZXdMb2dzKCkge1xuICAgIHJldHVybiB0aGlzLnN0YXJ0UG9sbGluZygpLnBpcGUoXG4gICAgICB0YWtlVW50aWwodGhpcy5jYW5jZWwkLnBpcGUoZmlsdGVyKGlzQXV0b1JlZnJlc2hPbiA9PiBpc0F1dG9SZWZyZXNoT24gPT09IGZhbHNlKSkpLFxuICAgICAgZmluYWxpemUoKCkgPT4ge1xuICAgICAgICB0aGlzLmlzQXV0b1JlZnJlc2hPbiA9IGZhbHNlO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGFydFBvbGxpbmcoKSB7XG4gICAgcmV0dXJuIG9mKDEpLnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5nZXROZXdMb2dzKCkucGlwZShjYXRjaEVycm9yKCgpID0+IG9mKHRoaXMuZ2V0RW1wdHlMb2dzSnNvbigpKSkpKSxcbiAgICAgIHRhcChsb2dzID0+IHRoaXMudXBkYXRlTG9nc1RvT3V0cHV0KGxvZ3MpKSxcbiAgICAgIGRlbGF5KDEwMDAwKSxcbiAgICAgIHJlcGVhdCgpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0TmV3TG9ncygpOiBPYnNlcnZhYmxlPExvZ3NKU09OPiB7XG4gICAgcmV0dXJuIHRoaXMuYXBwTG9nc1NlcnZpY2UuZ2V0TG9ncyQodGhpcy5nZXRBcHBJZCgpLCB0aGlzLmdldEluc3RhbmNlTmFtZSgpKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0QXBwSWQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5tby5hcHBsaWNhdGlvbklkO1xuICB9XG4gIHByaXZhdGUgZ2V0SW5zdGFuY2VOYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRJbnN0YW5jZS5uYW1lO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVMb2dzVG9PdXRwdXQobmV3TG9ncykge1xuICAgIGNvbnN0IHsgZGF0ZUZyb20sIGRhdGVUbyB9ID0gbmV3TG9ncztcbiAgICBpZiAoZGF0ZUZyb20gJiYgZGF0ZVRvKSB7XG4gICAgICB0aGlzLmxvZ3NUb091dHB1dCA9IHsgLi4ubmV3TG9ncyB9O1xuICAgICAgdGhpcy5vbk5ld0xvZ3MuZW1pdCh0aGlzLmxvZ3NUb091dHB1dCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRFbXB0eUxvZ3NKc29uKCk6IExvZ3NKU09OIHtcbiAgICByZXR1cm4ge1xuICAgICAgZGF0ZUZyb206IG51bGwsXG4gICAgICBkYXRlVG86IG51bGwsXG4gICAgICBsb2dzOiAnJyxcbiAgICAgIHRydW5jYXRlZDogZmFsc2VcbiAgICB9O1xuICB9XG59XG4iLCI8YnV0dG9uICNhdXRvUmVmcmVzaFxuICB0eXBlPVwiYnV0dG9uXCJcbiAgY2xhc3M9XCJidG4gYnRuLWxpbmsgYzh5LXJlYWx0aW1lXCJcbiAgW25nU3R5bGVdPVwieyd3aWR0aCc6ICdhdXRvJ31cIlxuICB0aXRsZT1cInt7J1RvZ2dsZSBhdXRvIHJlZnJlc2gnIHwgdHJhbnNsYXRlfX1cIlxuICBbZGlzYWJsZWRdPVwiaXNBdXRvUmVmcmVzaERpc2FibGVkXCJcbj5cbiAgPHNwYW4gY2xhc3M9XCJjOHktcHVsc2VcIiBbbmdDbGFzc109XCJpc0F1dG9SZWZyZXNoT24gPyAnYWN0aXZlJyA6ICdpbmFjdGl2ZSdcIj48L3NwYW4+XG4gIHt7J0F1dG8gcmVmcmVzaCcgfCB0cmFuc2xhdGV9fVxuPC9idXR0b24+Il19