refactoring
This commit is contained in:
parent
2933071a0f
commit
0a8e526d08
@ -19,12 +19,12 @@
|
||||
class="tb-rounded-btn flex-1 w-36"
|
||||
color="primary"
|
||||
#matButton
|
||||
[class.active]="(isDebugAllActive() || debugFailures) && !disabled"
|
||||
[class.active]="((isDebugAllActive$ | async) || debugFailures) && !disabled"
|
||||
[disabled]="disabled"
|
||||
(click)="openDebugStrategyPanel($event, matButton)">
|
||||
<mat-icon [color]="disabled ? 'inherit' : 'primary'">bug_report</mat-icon>
|
||||
<span *ngIf="!debugFailures && !isDebugAllActive()" translate>common.disabled</span>
|
||||
<span *ngIf="isDebugAllActive() && debugFailures" translate>debug-config.all</span>
|
||||
<span *ngIf="isDebugAllActive() && !debugFailures">{{ debugAllUntil | debugDurationLeft }}</span>
|
||||
<span *ngIf="!isDebugAllActive() && debugFailures" translate>debug-config.failures</span>
|
||||
<span *ngIf="!debugFailures && !(isDebugAllActive$ | async)" translate>common.disabled</span>
|
||||
<span *ngIf="(isDebugAllActive$ | async) && debugFailures" translate>debug-config.all</span>
|
||||
<span *ngIf="(isDebugAllActive$ | async) && !debugFailures">{{ debugAllUntil | durationLeft }}</span>
|
||||
<span *ngIf="!(isDebugAllActive$ | async) && debugFailures" translate>debug-config.failures</span>
|
||||
</button>
|
||||
@ -21,22 +21,20 @@ import {
|
||||
ViewContainerRef,
|
||||
DestroyRef,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
EventEmitter,
|
||||
Output
|
||||
} from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { SharedModule } from '@shared/shared.module';
|
||||
import { DebugDurationLeftPipe } from '@home/pages/rulechain/debug-duration-left.pipe';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from '@core/core.state';
|
||||
import { DurationLeftPipe } from '@shared/pipe/duration-left.pipe';
|
||||
import { TbPopoverService } from '@shared/components/popover.service';
|
||||
import { MatButton } from '@angular/material/button';
|
||||
import { DebugConfigPanelComponent } from '@home/pages/rulechain/debug-config-panel.component';
|
||||
import { DebugConfigPanelComponent } from './debug-config-panel.component';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { interval } from 'rxjs';
|
||||
import { timer } from 'rxjs';
|
||||
import { SECOND } from '@shared/models/time/time.models';
|
||||
import { RuleNodeDebugConfig } from '@shared/models/rule-node.models';
|
||||
import { HasDebugConfig } from '@shared/models/entity.models';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-debug-config-button',
|
||||
@ -45,7 +43,7 @@ import { RuleNodeDebugConfig } from '@shared/models/rule-node.models';
|
||||
imports: [
|
||||
CommonModule,
|
||||
SharedModule,
|
||||
DebugDurationLeftPipe,
|
||||
DurationLeftPipe,
|
||||
],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
@ -55,20 +53,18 @@ export class DebugConfigButtonComponent {
|
||||
@Input() debugAll = false;
|
||||
@Input() debugAllUntil = 0;
|
||||
@Input() disabled = false;
|
||||
@Input() maxRuleNodeDebugDurationMinutes: number;
|
||||
@Input() ruleChainDebugPerTenantLimitsConfiguration: string;
|
||||
|
||||
@Output() onDebugConfigChanged = new EventEmitter<RuleNodeDebugConfig>()
|
||||
@Output() onDebugConfigChanged = new EventEmitter<HasDebugConfig>();
|
||||
|
||||
constructor(protected store: Store<AppState>,
|
||||
private popoverService: TbPopoverService,
|
||||
isDebugAllActive$ = timer(0, SECOND).pipe(map(() => this.debugAllUntil > new Date().getTime()));
|
||||
|
||||
constructor(private popoverService: TbPopoverService,
|
||||
private renderer: Renderer2,
|
||||
private viewContainerRef: ViewContainerRef,
|
||||
private destroyRef: DestroyRef,
|
||||
private cdr: ChangeDetectorRef
|
||||
) {
|
||||
interval(SECOND)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe(() => this.cdr.markForCheck());
|
||||
}
|
||||
) {}
|
||||
|
||||
openDebugStrategyPanel($event: Event, matButton: MatButton): void {
|
||||
if ($event) {
|
||||
@ -84,19 +80,16 @@ export class DebugConfigButtonComponent {
|
||||
debugFailures: this.debugFailures,
|
||||
debugAll: this.debugAll,
|
||||
debugAllUntil: this.debugAllUntil,
|
||||
maxRuleNodeDebugDurationMinutes: this.maxRuleNodeDebugDurationMinutes,
|
||||
ruleChainDebugPerTenantLimitsConfiguration: this.ruleChainDebugPerTenantLimitsConfiguration
|
||||
},
|
||||
{},
|
||||
{}, {}, true);
|
||||
debugStrategyPopover.tbComponentRef.instance.popover = debugStrategyPopover;
|
||||
debugStrategyPopover.tbComponentRef.instance.onConfigApplied.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((config: RuleNodeDebugConfig) => {
|
||||
debugStrategyPopover.tbComponentRef.instance.onConfigApplied.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((config: HasDebugConfig) => {
|
||||
this.onDebugConfigChanged.emit(config);
|
||||
this.cdr.markForCheck();
|
||||
debugStrategyPopover.hide();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
isDebugAllActive(): boolean {
|
||||
return this.debugAllUntil > new Date().getTime();
|
||||
}
|
||||
}
|
||||
@ -27,23 +27,18 @@
|
||||
</div>
|
||||
<div class="flex flex-col gap-3">
|
||||
<mat-slide-toggle class="mat-slide" [formControl]="onFailuresControl">
|
||||
<mat-label tb-hint-tooltip-icon="{{ 'debug-config.hint.on-failure' | translate }}">
|
||||
<div tb-hint-tooltip-icon="{{ 'debug-config.hint.on-failure' | translate }}">
|
||||
{{ 'debug-config.on-failure' | translate }}
|
||||
</mat-label>
|
||||
</div>
|
||||
</mat-slide-toggle>
|
||||
<div class="flex justify-between align-center">
|
||||
<mat-slide-toggle class="mat-slide" [formControl]="debugAllControl">
|
||||
<mat-label tb-hint-tooltip-icon="{{ 'debug-config.hint.all-messages' | translate }}">
|
||||
{{ 'debug-config.all-messages' | translate }} {{ '( ' }}
|
||||
<span *ngIf="isDebugAllOn() else debugAllOffLabel">{{ debugAllUntil | debugDurationLeft }}</span>
|
||||
<ng-template #debugAllOffLabel>
|
||||
{{ maxRuleNodeDebugDurationMinutes + ' ' }} {{ ('debug-config.min' | translate) }}
|
||||
</ng-template>
|
||||
{{ ' )' }}
|
||||
</mat-label>
|
||||
<div tb-hint-tooltip-icon="{{ 'debug-config.hint.all-messages' | translate }}">
|
||||
{{ 'debug-config.all-messages' | translate: { time: (isDebugAllActive$ | async) ? (debugAllUntil | durationLeft) : ('debug-config.min' | translate: { number: maxRuleNodeDebugDurationMinutes }) } }}
|
||||
</div>
|
||||
</mat-slide-toggle>
|
||||
<button mat-icon-button *ngIf="isDebugAllOn()"
|
||||
class="tb-mat-20 p-0 mr-2"
|
||||
<button mat-icon-button *ngIf="(isDebugAllActive$ | async)"
|
||||
class="tb-mat-20"
|
||||
matTooltip="{{ 'action.reset' | translate }}"
|
||||
matTooltipPosition="above"
|
||||
color="primary"
|
||||
@ -18,24 +18,21 @@ import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
DestroyRef,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnInit
|
||||
} from '@angular/core';
|
||||
import { PageComponent } from '@shared/components/page.component';
|
||||
import { TbPopoverComponent } from '@shared/components/popover.component';
|
||||
import { FormControl, UntypedFormBuilder } from '@angular/forms';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from '@core/core.state';
|
||||
import { UntypedFormBuilder } from '@angular/forms';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { SharedModule } from '@shared/shared.module';
|
||||
import { getCurrentAuthState } from '@core/auth/auth.selectors';
|
||||
import { RuleNodeDebugConfig } from '@shared/models/rule-node.models';
|
||||
import { MINUTE, SECOND } from '@shared/models/time/time.models';
|
||||
import { DebugDurationLeftPipe } from '@home/pages/rulechain/debug-duration-left.pipe';
|
||||
import { interval } from 'rxjs';
|
||||
import { DurationLeftPipe } from '@shared/pipe/duration-left.pipe';
|
||||
import { timer } from 'rxjs';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { HasDebugConfig } from '@shared/models/entity.models';
|
||||
import { distinctUntilChanged, map, tap } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-debug-config-panel',
|
||||
@ -44,7 +41,7 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
imports: [
|
||||
SharedModule,
|
||||
CommonModule,
|
||||
DebugDurationLeftPipe
|
||||
DurationLeftPipe
|
||||
],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
@ -54,31 +51,35 @@ export class DebugConfigPanelComponent extends PageComponent implements OnInit {
|
||||
@Input() debugFailures = false;
|
||||
@Input() debugAll = false;
|
||||
@Input() debugAllUntil = 0;
|
||||
@Input() maxRuleNodeDebugDurationMinutes: number;
|
||||
@Input() ruleChainDebugPerTenantLimitsConfiguration: string;
|
||||
|
||||
onFailuresControl: FormControl<boolean>;
|
||||
debugAllControl: FormControl<boolean>;
|
||||
onFailuresControl = this.fb.control(false);
|
||||
debugAllControl = this.fb.control(false);
|
||||
|
||||
onConfigApplied = new EventEmitter<RuleNodeDebugConfig>()
|
||||
maxMessagesCount: string;
|
||||
maxTimeFrameSec: string;
|
||||
|
||||
readonly maxRuleNodeDebugDurationMinutes = getCurrentAuthState(this.store).maxRuleNodeDebugDurationMinutes;
|
||||
readonly ruleChainDebugPerTenantLimitsConfiguration = getCurrentAuthState(this.store).ruleChainDebugPerTenantLimitsConfiguration;
|
||||
readonly maxMessagesCount = this.ruleChainDebugPerTenantLimitsConfiguration?.split(':')[0];
|
||||
readonly maxTimeFrameSec = this.ruleChainDebugPerTenantLimitsConfiguration?.split(':')[1];
|
||||
isDebugAllActive$ = timer(0, SECOND).pipe(
|
||||
map(() => {
|
||||
this.cd.markForCheck();
|
||||
return this.debugAllUntil > new Date().getTime()
|
||||
}),
|
||||
distinctUntilChanged(),
|
||||
tap(isDebugOn => this.debugAllControl.patchValue(isDebugOn, { emitEvent: false }))
|
||||
);
|
||||
|
||||
constructor(private fb: UntypedFormBuilder,
|
||||
private destroyRef: DestroyRef,
|
||||
private cdr: ChangeDetectorRef,
|
||||
protected store: Store<AppState>) {
|
||||
super(store);
|
||||
onConfigApplied = new EventEmitter<HasDebugConfig>();
|
||||
|
||||
this.onFailuresControl = this.fb.control(false);
|
||||
this.debugAllControl = this.fb.control(false);
|
||||
constructor(private fb: UntypedFormBuilder, private cd: ChangeDetectorRef) {
|
||||
super();
|
||||
|
||||
this.observeDebugAllChange();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.debugAllControl.patchValue(this.isDebugAllOn(), { emitEvent: false });
|
||||
this.maxMessagesCount = this.ruleChainDebugPerTenantLimitsConfiguration?.split(':')[0];
|
||||
this.maxTimeFrameSec = this.ruleChainDebugPerTenantLimitsConfiguration?.split(':')[1];
|
||||
this.onFailuresControl.patchValue(this.debugFailures);
|
||||
}
|
||||
|
||||
@ -99,22 +100,10 @@ export class DebugConfigPanelComponent extends PageComponent implements OnInit {
|
||||
this.debugAllUntil = new Date().getTime() + this.maxRuleNodeDebugDurationMinutes * MINUTE;
|
||||
}
|
||||
|
||||
isDebugAllOn(): boolean {
|
||||
return this.debugAllUntil > new Date().getTime();
|
||||
}
|
||||
|
||||
private observeDebugAllChange(): void {
|
||||
interval(SECOND)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe(() => {
|
||||
this.debugAllControl.patchValue(this.isDebugAllOn(), { emitEvent: false });
|
||||
this.cdr.markForCheck();
|
||||
});
|
||||
|
||||
this.debugAllControl.valueChanges.pipe(takeUntilDestroyed()).subscribe(value => {
|
||||
this.debugAllUntil = value? new Date().getTime() + this.maxRuleNodeDebugDurationMinutes * MINUTE : 0;
|
||||
this.debugAll = value;
|
||||
this.cdr.markForCheck();
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -40,6 +40,8 @@
|
||||
[debugAll]="ruleNode.debugAll"
|
||||
[debugFailures]="ruleNode.debugFailures"
|
||||
[debugAllUntil]="ruleNode.debugAllUntil"
|
||||
[maxRuleNodeDebugDurationMinutes]="maxRuleNodeDebugDurationMinutes"
|
||||
[ruleChainDebugPerTenantLimitsConfiguration]="ruleChainDebugPerTenantLimitsConfiguration"
|
||||
(onDebugConfigChanged)="onDebugConfigChanged($event)"
|
||||
/>
|
||||
<button mat-stroked-button
|
||||
|
||||
@ -29,7 +29,7 @@ import { PageComponent } from '@shared/components/page.component';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from '@core/core.state';
|
||||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { FcRuleNode, RuleNodeDebugConfig, RuleNodeType } from '@shared/models/rule-node.models';
|
||||
import { FcRuleNode, RuleNodeType } from '@shared/models/rule-node.models';
|
||||
import { EntityType } from '@shared/models/entity-type.models';
|
||||
import { Subject } from 'rxjs';
|
||||
import { RuleNodeConfigComponent } from './rule-node-config.component';
|
||||
@ -39,6 +39,8 @@ import { ComponentClusteringMode } from '@shared/models/component-descriptor.mod
|
||||
import { coerceBoolean } from '@shared/decorators/coercion';
|
||||
import { ServiceType } from '@shared/models/queue.models';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { getCurrentAuthState } from '@core/auth/auth.selectors';
|
||||
import { HasDebugConfig } from '@shared/models/entity.models';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-rule-node',
|
||||
@ -79,6 +81,9 @@ export class RuleNodeDetailsComponent extends PageComponent implements OnInit, O
|
||||
|
||||
ruleNodeFormGroup: UntypedFormGroup;
|
||||
|
||||
readonly maxRuleNodeDebugDurationMinutes = getCurrentAuthState(this.store).maxRuleNodeDebugDurationMinutes;
|
||||
readonly ruleChainDebugPerTenantLimitsConfiguration = getCurrentAuthState(this.store).ruleChainDebugPerTenantLimitsConfiguration;
|
||||
|
||||
private destroy$ = new Subject<void>();
|
||||
|
||||
constructor(protected store: Store<AppState>,
|
||||
@ -205,7 +210,7 @@ export class RuleNodeDetailsComponent extends PageComponent implements OnInit, O
|
||||
return this.ruleNode.component.clusteringMode === ComponentClusteringMode.USER_PREFERENCE;
|
||||
}
|
||||
|
||||
onDebugConfigChanged(config: RuleNodeDebugConfig): void {
|
||||
onDebugConfigChanged(config: HasDebugConfig): void {
|
||||
this.ruleNodeFormGroup.get('debugAllUntil').setValue(config.debugAllUntil);
|
||||
this.ruleNodeFormGroup.get('debugAll').setValue(config.debugAll);
|
||||
this.ruleNodeFormGroup.get('debugFailures').setValue(config.debugFailures);
|
||||
|
||||
@ -32,8 +32,8 @@ import { RuleNodeDetailsComponent } from './rule-node-details.component';
|
||||
import { RuleNodeLinkComponent } from './rule-node-link.component';
|
||||
import { LinkLabelsComponent } from '@home/pages/rulechain/link-labels.component';
|
||||
import { RuleNodeConfigComponent } from './rule-node-config.component';
|
||||
import { DebugDurationLeftPipe } from '@home/pages/rulechain/debug-duration-left.pipe';
|
||||
import { DebugConfigButtonComponent } from '@home/pages/rulechain/debug-config-button.component';
|
||||
import { DurationLeftPipe } from '@shared/pipe/duration-left.pipe';
|
||||
import { DebugConfigButtonComponent } from '@home/components/debug-config/debug-config-button.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@ -62,7 +62,7 @@ import { DebugConfigButtonComponent } from '@home/pages/rulechain/debug-config-b
|
||||
SharedModule,
|
||||
HomeComponentsModule,
|
||||
RuleChainRoutingModule,
|
||||
DebugDurationLeftPipe,
|
||||
DurationLeftPipe,
|
||||
DebugConfigButtonComponent
|
||||
]
|
||||
})
|
||||
|
||||
@ -191,3 +191,9 @@ export interface HasTenantId {
|
||||
export interface HasVersion {
|
||||
version?: number;
|
||||
}
|
||||
|
||||
export interface HasDebugConfig {
|
||||
debugAll: boolean;
|
||||
debugFailures: boolean;
|
||||
debugAllUntil: number;
|
||||
}
|
||||
|
||||
@ -27,19 +27,16 @@ import { AppState } from '@core/core.state';
|
||||
import { AbstractControl, UntypedFormGroup } from '@angular/forms';
|
||||
import { RuleChainType } from '@shared/models/rule-chain.models';
|
||||
import { DebugRuleNodeEventBody } from '@shared/models/event.models';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { HasDebugConfig } from '@shared/models/entity.models';
|
||||
|
||||
export interface RuleNodeConfiguration {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface RuleNode extends BaseData<RuleNodeId> {
|
||||
export interface RuleNode extends BaseData<RuleNodeId>, HasDebugConfig {
|
||||
ruleChainId?: RuleChainId;
|
||||
type: string;
|
||||
name: string;
|
||||
debugAll: boolean;
|
||||
debugFailures: boolean;
|
||||
debugAllUntil: number;
|
||||
singletonMode: boolean;
|
||||
queueName?: string;
|
||||
configurationVersion?: number;
|
||||
@ -347,21 +344,12 @@ export interface FcRuleNode extends FcRuleNodeType {
|
||||
ruleNodeId?: RuleNodeId;
|
||||
additionalInfo?: any;
|
||||
configuration?: RuleNodeConfiguration;
|
||||
debugAll?: boolean;
|
||||
debugFailures?: boolean;
|
||||
debugAllUntil?: number;
|
||||
error?: string;
|
||||
highlighted?: boolean;
|
||||
componentClazz?: string;
|
||||
ruleChainType?: RuleChainType;
|
||||
}
|
||||
|
||||
export interface RuleNodeDebugConfig {
|
||||
debugAll: boolean;
|
||||
debugFailures: boolean;
|
||||
debugAllUntil: number;
|
||||
}
|
||||
|
||||
export interface FcRuleEdge extends FcEdge {
|
||||
labels?: string[];
|
||||
}
|
||||
|
||||
@ -15,22 +15,21 @@
|
||||
///
|
||||
|
||||
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';
|
||||
import { MillisecondsToTimeStringPipe } from './milliseconds-to-time-string.pipe';
|
||||
|
||||
@Pipe({
|
||||
name: 'debugDurationLeft',
|
||||
name: 'durationLeft',
|
||||
pure: false,
|
||||
standalone: true,
|
||||
})
|
||||
export class DebugDurationLeftPipe implements PipeTransform {
|
||||
export class DurationLeftPipe implements PipeTransform {
|
||||
|
||||
constructor(private translate: TranslateService, private millisecondsToTimeString: MillisecondsToTimeStringPipe) {
|
||||
}
|
||||
|
||||
transform(debugAllUntil: number): string {
|
||||
const time = this.millisecondsToTimeString.transform((debugAllUntil - new Date().getTime()), true, true);
|
||||
return `${time} ` + this.translate.instant('common.left');
|
||||
transform(untilTimestamp: number, shortFormat = true, onlyFirstDigit = true): string {
|
||||
const time = this.millisecondsToTimeString.transform((untilTimestamp - new Date().getTime()), shortFormat, onlyFirstDigit) ?? 0;
|
||||
return this.translate.instant('common.time-left', { time });
|
||||
}
|
||||
}
|
||||
@ -58,7 +58,9 @@ export class MillisecondsToTimeStringPipe implements PipeTransform {
|
||||
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;
|
||||
if (onlyFirstDigit) {
|
||||
return timeString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -25,3 +25,4 @@ export * from './file-size.pipe';
|
||||
export * from './selectable-columns.pipe';
|
||||
export * from './image.pipe';
|
||||
export * from './key-value-not-empty.pipe';
|
||||
export * from './duration-left.pipe';
|
||||
|
||||
@ -996,10 +996,10 @@
|
||||
"type-sms-sent": "SMS sent"
|
||||
},
|
||||
"debug-config": {
|
||||
"min": "min",
|
||||
"min": "{{number}} min",
|
||||
"label": "Debug configuration",
|
||||
"on-failure": "Failures only (24/7)",
|
||||
"all-messages": "All messages",
|
||||
"all-messages": "All messages ({{time}})",
|
||||
"failures": "Failures",
|
||||
"all": "All",
|
||||
"hint": {
|
||||
@ -1045,7 +1045,7 @@
|
||||
"open-details-page": "Open details page",
|
||||
"not-found": "Not found",
|
||||
"documentation": "Documentation",
|
||||
"left": "left"
|
||||
"time-left": "{{time}} left"
|
||||
},
|
||||
"content-type": {
|
||||
"json": "Json",
|
||||
|
||||
@ -1278,7 +1278,7 @@ pre.tb-highlight {
|
||||
}
|
||||
|
||||
&.active:not(:disabled) {
|
||||
border-color: $primary !important;
|
||||
--mdc-outlined-button-outline-color: $primary;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user