major refactoring
This commit is contained in:
parent
bc5d15553e
commit
0a00b39398
@ -28,6 +28,7 @@ export interface SysParamsState {
|
||||
userSettings: UserSettings;
|
||||
maxResourceSize: number;
|
||||
maxRuleNodeDebugDurationMinutes: number;
|
||||
ruleChainDebugPerTenantLimitsConfiguration?: string;
|
||||
}
|
||||
|
||||
export interface SysParams extends SysParamsState {
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { MINUTE } from '@shared/models/time/time.models';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { MillisecondsToTimeStringPipe } from '@shared/pipe/milliseconds-to-time-string.pipe';
|
||||
|
||||
@Pipe({
|
||||
name: 'debugDurationLeft',
|
||||
@ -23,9 +25,12 @@ import { MINUTE } from '@shared/models/time/time.models';
|
||||
standalone: true,
|
||||
})
|
||||
export class DebugDurationLeftPipe implements PipeTransform {
|
||||
|
||||
constructor(private translate: TranslateService, private millisecondsToTimeString: MillisecondsToTimeStringPipe) {
|
||||
}
|
||||
transform(lastUpdateTs: number, maxRuleNodeDebugDurationMinutes: number): string {
|
||||
const minutes = Math.max(0, Math.floor(this.getDebugTime(lastUpdateTs, maxRuleNodeDebugDurationMinutes) / MINUTE));
|
||||
return `${minutes} min left`;
|
||||
const time = this.millisecondsToTimeString.transform(this.getDebugTime(lastUpdateTs, maxRuleNodeDebugDurationMinutes), true, true);
|
||||
return `${time} ` + this.translate.instant('common.left');
|
||||
}
|
||||
|
||||
getDebugTime(lastUpdateTs: number, maxRuleNodeDebugDurationMinutes: number): number {
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
-->
|
||||
<button mat-stroked-button
|
||||
class="tb-rounded-btn flex-1 mr-2 w-[140px]"
|
||||
class="tb-rounded-btn flex-1 w-36"
|
||||
color="primary"
|
||||
#matButton
|
||||
[class.active]="debugStrategyFormControl.value !== DebugStrategy.DISABLED && !disabled"
|
||||
@ -24,8 +24,8 @@
|
||||
(click)="openDebugStrategyPanel($event, matButton)">
|
||||
<mat-icon [color]="disabled ? 'inherit' : 'primary'">bug_report</mat-icon>
|
||||
<ng-container [ngSwitch]="debugStrategyFormControl.value">
|
||||
<span *ngSwitchCase="DebugStrategy.DISABLED" translate>disabled</span>
|
||||
<span *ngSwitchCase="DebugStrategy.ALL_WITH_FAILURES" translate>debug-strategy.all</span>
|
||||
<span *ngSwitchCase="DebugStrategy.DISABLED" translate>common.disabled</span>
|
||||
<span *ngSwitchCase="DebugStrategy.ALL_THEN_ONLY_FAILURE_EVENTS" translate>debug-strategy.all</span>
|
||||
<span *ngSwitchCase="DebugStrategy.ALL_EVENTS">{{ lastUpdateTs | debugDurationLeft : maxRuleNodeDebugDurationMinutes }}</span>
|
||||
<span *ngSwitchCase="DebugStrategy.ONLY_FAILURE_EVENTS" translate>debug-strategy.failures</span>
|
||||
</ng-container>
|
||||
|
||||
@ -59,10 +59,10 @@ import { MINUTE } from '@shared/models/time/time.models';
|
||||
})
|
||||
export class DebugStrategyButtonComponent implements ControlValueAccessor {
|
||||
|
||||
@Input() disabled = false;
|
||||
@Input() lastUpdateTs: number;
|
||||
|
||||
debugStrategyFormControl: FormControl<DebugStrategy>;
|
||||
disabled = false;
|
||||
|
||||
private onChange: (debugStrategy: DebugStrategy) => void;
|
||||
|
||||
@ -113,6 +113,10 @@ export class DebugStrategyButtonComponent implements ControlValueAccessor {
|
||||
|
||||
registerOnTouched(_: () => {}): void {}
|
||||
|
||||
setDisabledState(isDisabled: boolean): void {
|
||||
this.disabled = isDisabled;
|
||||
}
|
||||
|
||||
writeValue(value: DebugStrategy): void {
|
||||
this.debugStrategyFormControl.patchValue(value, { emitEvent: false });
|
||||
this.cdr.markForCheck();
|
||||
|
||||
@ -15,18 +15,23 @@
|
||||
limitations under the License.
|
||||
|
||||
-->
|
||||
<div [formGroup]="debugStrategyFormGroup">
|
||||
<div class="tb-form-panel-title p-2" translate>debug-strategy.label</div>
|
||||
<div class="p-1 hint-container">
|
||||
<div class="tb-form-hint tb-primary-fill tb-flex center" tbTruncateWithTooltip>{{ 'debug-strategy.hint.main' | translate }}</div>
|
||||
<div [formGroup]="debugStrategyFormGroup" class="flex flex-col gap-2 p-2 max-w-sm">
|
||||
<div class="tb-form-panel-title" translate>debug-strategy.label</div>
|
||||
<div class="hint-container">
|
||||
<div class="tb-form-hint tb-primary-fill tb-flex center">
|
||||
<span *ngIf="ruleChainDebugPerTenantLimitsConfiguration else noLimitHint">
|
||||
{{ 'debug-strategy.hint.main-limited' | translate: { msg: maxMessagesCount, sec: maxTimeFrameSec } }}
|
||||
</span>
|
||||
<ng-template #noLimitHint>{{ 'debug-strategy.hint.main' | translate }}</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col p-2">
|
||||
<mat-slide-toggle class="mat-slide p-1" formControlName="onFailure">
|
||||
<div class="flex flex-col gap-2">
|
||||
<mat-slide-toggle class="mat-slide" formControlName="onFailure">
|
||||
<mat-label tb-hint-tooltip-icon="{{ 'debug-strategy.hint.on-failure' | translate }}">
|
||||
{{ 'debug-strategy.on-failure' | translate }}
|
||||
</mat-label>
|
||||
</mat-slide-toggle>
|
||||
<mat-slide-toggle class="mat-slide p-1" formControlName="allMessages">
|
||||
<mat-slide-toggle class="mat-slide" formControlName="allMessages">
|
||||
<mat-label tb-hint-tooltip-icon="{{ 'debug-strategy.hint.all-messages' | translate }}">
|
||||
{{ 'debug-strategy.all-messages' | translate }} {{ ' (' + maxRuleNodeDebugDurationMinutes + ' ' }} {{ ('debug-strategy.min' | translate) + ')'}}
|
||||
</mat-label>
|
||||
|
||||
@ -44,6 +44,9 @@ export class DebugStrategyPanelComponent extends PageComponent implements OnInit
|
||||
onStrategyApplied = new EventEmitter<DebugStrategy>()
|
||||
|
||||
readonly maxRuleNodeDebugDurationMinutes = getCurrentAuthState(this.store).maxRuleNodeDebugDurationMinutes;
|
||||
readonly ruleChainDebugPerTenantLimitsConfiguration = getCurrentAuthState(this.store).ruleChainDebugPerTenantLimitsConfiguration;
|
||||
readonly maxMessagesCount = this.ruleChainDebugPerTenantLimitsConfiguration?.split(':')[0];
|
||||
readonly maxTimeFrameSec = this.ruleChainDebugPerTenantLimitsConfiguration?.split(':')[1];
|
||||
|
||||
constructor(private fb: UntypedFormBuilder,
|
||||
protected store: Store<AppState>) {
|
||||
@ -67,7 +70,7 @@ export class DebugStrategyPanelComponent extends PageComponent implements OnInit
|
||||
const allMessages = this.debugStrategyFormGroup.get('allMessages').value;
|
||||
const onFailure = this.debugStrategyFormGroup.get('onFailure').value;
|
||||
if (allMessages && onFailure) {
|
||||
this.onStrategyApplied.emit(DebugStrategy.ALL_WITH_FAILURES);
|
||||
this.onStrategyApplied.emit(DebugStrategy.ALL_THEN_ONLY_FAILURE_EVENTS);
|
||||
} else if (allMessages) {
|
||||
this.onStrategyApplied.emit(DebugStrategy.ALL_EVENTS);
|
||||
} else if (onFailure) {
|
||||
@ -79,7 +82,7 @@ export class DebugStrategyPanelComponent extends PageComponent implements OnInit
|
||||
|
||||
private updatePanelStrategy(): void {
|
||||
switch (this.debugStrategy) {
|
||||
case DebugStrategy.ALL_WITH_FAILURES:
|
||||
case DebugStrategy.ALL_THEN_ONLY_FAILURE_EVENTS:
|
||||
this.debugStrategyFormGroup.get('allMessages').patchValue(true, { emitEvent: false });
|
||||
this.debugStrategyFormGroup.get('onFailure').patchValue(true, { emitEvent: false });
|
||||
break;
|
||||
|
||||
@ -34,8 +34,8 @@
|
||||
{{ 'rulenode.name-max-length' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<section class="flex flex-row max-w-[280px] mb-[22px]">
|
||||
<tb-debug-strategy-button formControlName="debugStrategy" [disabled]="disabled" [lastUpdateTs]="ruleNode.lastUpdateTs"/>
|
||||
<section class="flex flex-row max-w-xs mb-5">
|
||||
<tb-debug-strategy-button class="mr-2" formControlName="debugStrategy" [lastUpdateTs]="ruleNode.lastUpdateTs"/>
|
||||
<button mat-stroked-button
|
||||
class="tb-rounded-btn flex-1"
|
||||
color="primary"
|
||||
@ -43,9 +43,9 @@
|
||||
[disabled]="disabled"
|
||||
[class.active]="ruleNodeFormGroup.get('singletonMode').value"
|
||||
(click)="onSingleModeChange($event)">
|
||||
<mat-icon [class.opacity-0]="!ruleNodeFormGroup.get('singletonMode').value">checkmark</mat-icon>
|
||||
<mat-icon [class.invisible]="!ruleNodeFormGroup.get('singletonMode').value">checkmark</mat-icon>
|
||||
<span translate>rulenode.singleton</span>
|
||||
<input [class.hidden]="true" formControlName="singletonMode">
|
||||
<input class="hidden" formControlName="singletonMode">
|
||||
</button>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
@ -358,7 +358,7 @@ export enum DebugStrategy {
|
||||
DISABLED = 'DISABLED',
|
||||
ALL_EVENTS = 'ALL_EVENTS',
|
||||
ONLY_FAILURE_EVENTS = 'ONLY_FAILURE_EVENTS',
|
||||
ALL_WITH_FAILURES = 'ALL_WITH_FAILURES',
|
||||
ALL_THEN_ONLY_FAILURE_EVENTS = 'ALL_THEN_ONLY_FAILURE_EVENTS',
|
||||
}
|
||||
|
||||
export interface FcRuleEdge extends FcEdge {
|
||||
|
||||
@ -24,53 +24,42 @@ export class MillisecondsToTimeStringPipe implements PipeTransform {
|
||||
|
||||
constructor(private translate: TranslateService) {
|
||||
}
|
||||
transform(millseconds: number, shortFormat = false, onlyFirstDigit = false): string {
|
||||
const { days, hours, minutes, seconds } = this.extractTimeUnits(millseconds);
|
||||
return this.formatTimeString(days, hours, minutes, seconds, shortFormat, onlyFirstDigit);
|
||||
}
|
||||
|
||||
transform(millseconds: number, shortFormat = false): string {
|
||||
let seconds = Math.floor(millseconds / 1000);
|
||||
private extractTimeUnits(milliseconds: number): { days: number; hours: number; minutes: number; seconds: number } {
|
||||
const seconds = Math.floor(milliseconds / 1000);
|
||||
const days = Math.floor(seconds / 86400);
|
||||
let hours = Math.floor((seconds % 86400) / 3600);
|
||||
let minutes = Math.floor(((seconds % 86400) % 3600) / 60);
|
||||
seconds = seconds % 60;
|
||||
const hours = Math.floor((seconds % 86400) / 3600);
|
||||
const minutes = Math.floor(((seconds % 86400) % 3600) / 60);
|
||||
return { days, hours, minutes, seconds: seconds % 60 };
|
||||
}
|
||||
|
||||
private formatTimeString(
|
||||
days: number,
|
||||
hours: number,
|
||||
minutes: number,
|
||||
seconds: number,
|
||||
shortFormat: boolean,
|
||||
onlyFirstDigit: boolean
|
||||
): string {
|
||||
const timeUnits = [
|
||||
{ value: days, key: 'days', shortKey: 'short.days' },
|
||||
{ value: hours, key: 'hours', shortKey: 'short.hours' },
|
||||
{ value: minutes, key: 'minutes', shortKey: 'short.minutes' },
|
||||
{ value: seconds, key: 'seconds', shortKey: 'short.seconds' }
|
||||
];
|
||||
|
||||
let timeString = '';
|
||||
if (shortFormat) {
|
||||
if (days > 0) {
|
||||
timeString += this.translate.instant('timewindow.short.days', {days});
|
||||
}
|
||||
if (hours > 0) {
|
||||
timeString += this.translate.instant('timewindow.short.hours', {hours});
|
||||
}
|
||||
if (minutes > 0) {
|
||||
timeString += this.translate.instant('timewindow.short.minutes', {minutes});
|
||||
}
|
||||
if (seconds > 0) {
|
||||
timeString += this.translate.instant('timewindow.short.seconds', {seconds});
|
||||
}
|
||||
if (!timeString.length) {
|
||||
timeString += this.translate.instant('timewindow.short.seconds', {seconds: 0});
|
||||
}
|
||||
} else {
|
||||
if (days > 0) {
|
||||
timeString += this.translate.instant('timewindow.days', {days});
|
||||
}
|
||||
if (hours > 0) {
|
||||
if (timeString.length === 0 && hours === 1) {
|
||||
hours = 0;
|
||||
}
|
||||
timeString += this.translate.instant('timewindow.hours', {hours});
|
||||
}
|
||||
if (minutes > 0) {
|
||||
if (timeString.length === 0 && minutes === 1) {
|
||||
minutes = 0;
|
||||
}
|
||||
timeString += this.translate.instant('timewindow.minutes', {minutes});
|
||||
}
|
||||
if (seconds > 0) {
|
||||
if (timeString.length === 0 && seconds === 1) {
|
||||
seconds = 0;
|
||||
}
|
||||
timeString += this.translate.instant('timewindow.seconds', {seconds});
|
||||
for (const { value, key, shortKey } of timeUnits) {
|
||||
if (value > 0) {
|
||||
timeString += this.translate.instant(shortFormat ? `timewindow.${shortKey}` : `timewindow.${key}`, { [key]: value });
|
||||
if (onlyFirstDigit) return timeString;
|
||||
}
|
||||
}
|
||||
return timeString;
|
||||
|
||||
return timeString.length > 0 ? timeString : this.translate.instant('timewindow.short.seconds', { seconds: 0 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1004,6 +1004,7 @@
|
||||
"all": "All",
|
||||
"hint": {
|
||||
"main": "All node debug messages rate limited with:",
|
||||
"main-limited": "All node debug messages will be rate-limited, with a maximum of {{msg}} messages allowed per {{sec}} seconds.",
|
||||
"on-failure": "Save all failure debug events without time limit.",
|
||||
"all-messages": "Save all debug events during time limit."
|
||||
}
|
||||
@ -1038,11 +1039,13 @@
|
||||
"enter-password": "Enter password",
|
||||
"enter-search": "Enter search",
|
||||
"created-time": "Created time",
|
||||
"disabled": "Disabled",
|
||||
"loading": "Loading...",
|
||||
"proceed": "Proceed",
|
||||
"open-details-page": "Open details page",
|
||||
"not-found": "Not found",
|
||||
"documentation": "Documentation"
|
||||
"documentation": "Documentation",
|
||||
"left": "left"
|
||||
},
|
||||
"content-type": {
|
||||
"json": "Json",
|
||||
@ -2084,7 +2087,6 @@
|
||||
"column": "Column",
|
||||
"row": "Row"
|
||||
},
|
||||
"disabled": "Disabled",
|
||||
"edge": {
|
||||
"edge": "Edge",
|
||||
"edge-instances": "Edge instances",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user