diff --git a/ui-ngx/src/app/modules/home/components/debug-config/debug-config-button.component.html b/ui-ngx/src/app/modules/home/components/debug-config/debug-config-button.component.html deleted file mode 100644 index bdaf2de487..0000000000 --- a/ui-ngx/src/app/modules/home/components/debug-config/debug-config-button.component.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - diff --git a/ui-ngx/src/app/modules/home/components/debug-config/debug-config-button.component.scss b/ui-ngx/src/app/modules/home/components/debug-config/debug-config-button.component.scss deleted file mode 100644 index 06fcba27be..0000000000 --- a/ui-ngx/src/app/modules/home/components/debug-config/debug-config-button.component.scss +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright © 2016-2024 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 { - .mini-debug-btn { - color: rgba(0, 0, 0, 0.6); - } -} diff --git a/ui-ngx/src/app/modules/home/components/debug-settings/debug-settings-button.component.html b/ui-ngx/src/app/modules/home/components/debug-settings/debug-settings-button.component.html new file mode 100644 index 0000000000..cd43d56e96 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/debug-settings/debug-settings-button.component.html @@ -0,0 +1,39 @@ + + diff --git a/ui-ngx/src/app/modules/home/components/debug-config/debug-config-button.component.ts b/ui-ngx/src/app/modules/home/components/debug-settings/debug-settings-button.component.ts similarity index 55% rename from ui-ngx/src/app/modules/home/components/debug-config/debug-config-button.component.ts rename to ui-ngx/src/app/modules/home/components/debug-settings/debug-settings-button.component.ts index c1a93d8ed9..8f05d7dad0 100644 --- a/ui-ngx/src/app/modules/home/components/debug-config/debug-config-button.component.ts +++ b/ui-ngx/src/app/modules/home/components/debug-settings/debug-settings-button.component.ts @@ -21,82 +21,128 @@ import { ViewContainerRef, DestroyRef, ChangeDetectionStrategy, - EventEmitter, - Output + forwardRef } from '@angular/core'; import { CommonModule } from '@angular/common'; import { SharedModule } from '@shared/shared.module'; import { DurationLeftPipe } from '@shared/pipe/duration-left.pipe'; import { TbPopoverService } from '@shared/components/popover.service'; import { MatButton } from '@angular/material/button'; -import { DebugConfigPanelComponent } from './debug-config-panel.component'; +import { DebugSettingsPanelComponent } from './debug-settings-panel.component'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { shareReplay, timer } from 'rxjs'; import { SECOND } from '@shared/models/time/time.models'; -import { HasDebugConfig } from '@shared/models/entity.models'; +import { DebugSettings } from '@shared/models/entity.models'; import { map } from 'rxjs/operators'; import { getCurrentAuthState } from '@core/auth/auth.selectors'; import { AppState } from '@core/core.state'; import { Store } from '@ngrx/store'; +import { + ControlValueAccessor, + FormBuilder, + NG_VALUE_ACCESSOR, + UntypedFormGroup, +} from '@angular/forms'; @Component({ - selector: 'tb-debug-config-button', - templateUrl: './debug-config-button.component.html', - styleUrls: ['./debug-config-button.component.scss'], + selector: 'tb-debug-settings-button', + templateUrl: './debug-settings-button.component.html', standalone: true, imports: [ CommonModule, SharedModule, DurationLeftPipe, ], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => DebugSettingsButtonComponent), + multi: true + }, + ], changeDetection: ChangeDetectionStrategy.OnPush }) -export class DebugConfigButtonComponent { +export class DebugSettingsButtonComponent implements ControlValueAccessor { - @Input() debugFailures = false; - @Input() debugAll = false; - @Input() debugAllUntil = 0; - @Input() disabled = false; - @Input() minifyMode = false; @Input() debugLimitsConfiguration: string; - @Output() onDebugConfigChanged = new EventEmitter(); - - isDebugAllActive$ = timer(0, SECOND).pipe(map(() => this.debugAllUntil > new Date().getTime() || this.debugAll), shareReplay(1)); + debugSettingsFormGroup: UntypedFormGroup; + disabled = false; + isDebugAllActive$ = timer(0, SECOND).pipe(map(() => this.allEnabledUntil > new Date().getTime() || this.allEnabled), shareReplay(1)); readonly maxDebugModeDurationMinutes = getCurrentAuthState(this.store).maxDebugModeDurationMinutes; + private onChange: (settings: DebugSettings) => void; + constructor(private popoverService: TbPopoverService, private renderer: Renderer2, private store: Store, private viewContainerRef: ViewContainerRef, private destroyRef: DestroyRef, - ) {} + private fb: FormBuilder, + ) { + this.debugSettingsFormGroup = this.fb.group({ + failuresEnabled: [false], + allEnabled: [false], + allEnabledUntil: [] + }); + + this.debugSettingsFormGroup.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(value => { + this.onChange(value); + }) + } + + get failuresEnabled(): boolean { + return this.debugSettingsFormGroup.get('failuresEnabled').value; + } + + get allEnabled(): boolean { + return this.debugSettingsFormGroup.get('allEnabled').value; + } + + get allEnabledUntil(): number { + return this.debugSettingsFormGroup.get('allEnabledUntil').value; + } openDebugStrategyPanel($event: Event, matButton: MatButton): void { if ($event) { $event.stopPropagation(); } const trigger = matButton._elementRef.nativeElement; + const debugSettings = this.debugSettingsFormGroup.value; + if (this.popoverService.hasPopover(trigger)) { this.popoverService.hidePopover(trigger); } else { const debugStrategyPopover = this.popoverService.displayPopover(trigger, this.renderer, - this.viewContainerRef, DebugConfigPanelComponent, 'bottom', true, null, + this.viewContainerRef, DebugSettingsPanelComponent, 'bottom', true, null, { - debugFailures: this.debugFailures, - debugAll: this.debugAll, - debugAllUntil: this.debugAllUntil, + ...debugSettings, maxDebugModeDurationMinutes: this.maxDebugModeDurationMinutes, debugLimitsConfiguration: this.debugLimitsConfiguration }, {}, {}, {}, true); debugStrategyPopover.tbComponentRef.instance.popover = debugStrategyPopover; - debugStrategyPopover.tbComponentRef.instance.onConfigApplied.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((config: HasDebugConfig) => { - this.onDebugConfigChanged.emit(config); + debugStrategyPopover.tbComponentRef.instance.onConfigApplied.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((settings: DebugSettings) => { + this.debugSettingsFormGroup.patchValue(settings); debugStrategyPopover.hide(); }); } } + + registerOnChange(fn: (settings: DebugSettings) => void): void { + this.onChange = fn; + } + + registerOnTouched(_: () => void): void {} + + writeValue(settings: DebugSettings): void { + this.debugSettingsFormGroup.patchValue(settings, {emitEvent: false}); + } + + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + this.debugSettingsFormGroup[isDisabled ? 'disable' : 'enable']({emitEvent: false}); + } } diff --git a/ui-ngx/src/app/modules/home/components/debug-config/debug-config-panel.component.html b/ui-ngx/src/app/modules/home/components/debug-settings/debug-settings-panel.component.html similarity index 74% rename from ui-ngx/src/app/modules/home/components/debug-config/debug-config-panel.component.html rename to ui-ngx/src/app/modules/home/components/debug-settings/debug-settings-panel.component.html index 379ad579eb..7e4b1fb231 100644 --- a/ui-ngx/src/app/modules/home/components/debug-config/debug-config-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/debug-settings/debug-settings-panel.component.html @@ -19,10 +19,11 @@
debug-config.label
- + @if (debugLimitsConfiguration) { {{ 'debug-config.hint.main-limited' | translate: { msg: maxMessagesCount, sec: maxTimeFrameSec } }} - - {{ 'debug-config.hint.main' | translate }} + } @else { + {{ 'debug-config.hint.main' | translate }} + }
@@ -34,17 +35,19 @@
- {{ 'debug-config.all-messages' | translate: { time: (isDebugAllActive$ | async) && !debugAll ? (debugAllUntil | durationLeft) : ('debug-config.min' | translate: { number: maxDebugModeDurationMinutes }) } }} + {{ 'debug-config.all-messages' | translate: { time: (isDebugAllActive$ | async) && !allEnabled ? (allEnabledUntil | durationLeft) : ('debug-config.min' | translate: { number: maxDebugModeDurationMinutes }) } }}
- + @if ((isDebugAllActive$ | async) && !allEnabled) { + + }
diff --git a/ui-ngx/src/app/modules/home/components/debug-config/debug-config-panel.component.ts b/ui-ngx/src/app/modules/home/components/debug-settings/debug-settings-panel.component.ts similarity index 70% rename from ui-ngx/src/app/modules/home/components/debug-config/debug-config-panel.component.ts rename to ui-ngx/src/app/modules/home/components/debug-settings/debug-settings-panel.component.ts index 7ad88955ba..e9e7f084c3 100644 --- a/ui-ngx/src/app/modules/home/components/debug-config/debug-config-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/debug-settings/debug-settings-panel.component.ts @@ -31,12 +31,13 @@ import { MINUTE, SECOND } from '@shared/models/time/time.models'; import { DurationLeftPipe } from '@shared/pipe/duration-left.pipe'; import { shareReplay, timer } from 'rxjs'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { HasDebugConfig } from '@shared/models/entity.models'; +import { DebugSettings } from '@shared/models/entity.models'; import { distinctUntilChanged, map, tap } from 'rxjs/operators'; +import { coerceBoolean } from '@shared/decorators/coercion'; @Component({ - selector: 'tb-debug-config-panel', - templateUrl: './debug-config-panel.component.html', + selector: 'tb-debug-settings-panel', + templateUrl: './debug-settings-panel.component.html', standalone: true, imports: [ SharedModule, @@ -45,12 +46,12 @@ import { distinctUntilChanged, map, tap } from 'rxjs/operators'; ], changeDetection: ChangeDetectionStrategy.OnPush }) -export class DebugConfigPanelComponent extends PageComponent implements OnInit { +export class DebugSettingsPanelComponent extends PageComponent implements OnInit { - @Input() popover: TbPopoverComponent; - @Input() debugFailures = false; - @Input() debugAll = false; - @Input() debugAllUntil = 0; + @Input() popover: TbPopoverComponent; + @Input() @coerceBoolean() failuresEnabled = false; + @Input() @coerceBoolean() allEnabled = false; + @Input() allEnabledUntil = 0; @Input() maxDebugModeDurationMinutes: number; @Input() debugLimitsConfiguration: string; @@ -63,14 +64,14 @@ export class DebugConfigPanelComponent extends PageComponent implements OnInit { isDebugAllActive$ = timer(0, SECOND).pipe( map(() => { this.cd.markForCheck(); - return this.debugAllUntil > new Date().getTime() || this.debugAll; + return this.allEnabledUntil > new Date().getTime() || this.allEnabled; }), distinctUntilChanged(), tap(isDebugOn => this.debugAllControl.patchValue(isDebugOn, { emitEvent: false })), shareReplay(1), ); - onConfigApplied = new EventEmitter(); + onConfigApplied = new EventEmitter(); constructor(private fb: UntypedFormBuilder, private cd: ChangeDetectorRef) { super(); @@ -81,7 +82,7 @@ export class DebugConfigPanelComponent extends PageComponent implements OnInit { ngOnInit(): void { this.maxMessagesCount = this.debugLimitsConfiguration?.split(':')[0]; this.maxTimeFrameSec = this.debugLimitsConfiguration?.split(':')[1]; - this.onFailuresControl.patchValue(this.debugFailures); + this.onFailuresControl.patchValue(this.failuresEnabled); } onCancel(): void { @@ -90,22 +91,22 @@ export class DebugConfigPanelComponent extends PageComponent implements OnInit { onApply(): void { this.onConfigApplied.emit({ - debugAll: this.debugAll, - debugFailures: this.onFailuresControl.value, - debugAllUntil: this.debugAllUntil + allEnabled: this.allEnabled, + failuresEnabled: this.onFailuresControl.value, + allEnabledUntil: this.allEnabledUntil }); } onReset(): void { - this.debugAll = true; - this.debugAllUntil = new Date().getTime() + this.maxDebugModeDurationMinutes * MINUTE; + this.allEnabled = true; + this.allEnabledUntil = new Date().getTime() + this.maxDebugModeDurationMinutes * MINUTE; this.cd.markForCheck(); } private observeDebugAllChange(): void { this.debugAllControl.valueChanges.pipe(takeUntilDestroyed()).subscribe(value => { - this.debugAllUntil = value? new Date().getTime() + this.maxDebugModeDurationMinutes * MINUTE : 0; - this.debugAll = value; + this.allEnabledUntil = value? new Date().getTime() + this.maxDebugModeDurationMinutes * MINUTE : 0; + this.allEnabled = value; this.cd.markForCheck(); }); } diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html index dd095117d7..8566eeb47f 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html @@ -76,22 +76,6 @@
-
- - tenant-profile.maximum-debug-duration-min - - - {{ 'tenant-profile.maximum-debug-duration-min-range' | translate }} - - - {{ 'tenant-profile.maximum-debug-duration-min-required' | translate }} - - - -
-
@@ -370,6 +354,25 @@ +
+ + {{ 'tenant-profile.debug' | translate }} tenant-profile.unlimited + +
+ + tenant-profile.maximum-debug-duration-min + + + {{ 'tenant-profile.maximum-debug-duration-min-range' | translate }} + + + +
+
+
+
{{ 'tenant-profile.ota-files-in-bytes' | translate }} tenant-profile.unlimited diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts index c715a978b2..98c382b479 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts @@ -85,7 +85,7 @@ export class DefaultTenantProfileConfigurationComponent implements ControlValueA tenantNotificationRequestsRateLimit: [null, []], tenantNotificationRequestsPerRuleRateLimit: [null, []], maxTransportMessages: [null, [Validators.required, Validators.min(0)]], - maxDebugModeDurationMinutes: [null, [Validators.required, Validators.min(0)]], + maxDebugModeDurationMinutes: [null, [Validators.min(0)]], maxTransportDataPoints: [null, [Validators.required, Validators.min(0)]], maxREExecutions: [null, [Validators.required, Validators.min(0)]], maxJSExecutions: [null, [Validators.required, Validators.min(0)]], diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.html b/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.html index 5ae72a8880..a9ab128d09 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.html +++ b/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.html @@ -35,13 +35,10 @@
-