major refactoring

This commit is contained in:
mpetrov 2024-11-07 16:26:38 +02:00
parent bc5d15553e
commit 0a00b39398
10 changed files with 74 additions and 65 deletions

View File

@ -28,6 +28,7 @@ export interface SysParamsState {
userSettings: UserSettings;
maxResourceSize: number;
maxRuleNodeDebugDurationMinutes: number;
ruleChainDebugPerTenantLimitsConfiguration?: string;
}
export interface SysParams extends SysParamsState {

View File

@ -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 {

View File

@ -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>

View File

@ -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();

View File

@ -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>

View File

@ -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;

View File

@ -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>

View File

@ -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 {

View File

@ -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 });
}
}

View File

@ -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",