Merge pull request #13092 from ArtemDzhereleiko/AD/imp/toggle-select/error
Error icon with tooltip for toggle select for Map widget settings
This commit is contained in:
commit
a697d25ffa
@ -41,10 +41,10 @@
|
||||
</div>
|
||||
<tb-toggle-select [(ngModel)]="dataLayerMode"
|
||||
[ngModelOptions]="{ standalone: true }">
|
||||
<tb-toggle-option *ngIf="trip" value="trips">{{ 'widgets.maps.overlays.trips' | translate }}</tb-toggle-option>
|
||||
<tb-toggle-option value="markers">{{ 'widgets.maps.overlays.markers' | translate }}</tb-toggle-option>
|
||||
<tb-toggle-option value="polygons">{{ 'widgets.maps.overlays.polygons' | translate }}</tb-toggle-option>
|
||||
<tb-toggle-option value="circles">{{ 'widgets.maps.overlays.circles' | translate }}</tb-toggle-option>
|
||||
<tb-toggle-option *ngIf="trip" value="trips" [error]="mapSettingsFormGroup.get('trips').invalid ? ('common.required-fields' | translate) : null">{{ 'widgets.maps.overlays.trips' | translate }}</tb-toggle-option>
|
||||
<tb-toggle-option value="markers" [error]="mapSettingsFormGroup.get('markers').invalid ? ('common.required-fields' | translate) : null">{{ 'widgets.maps.overlays.markers' | translate }}</tb-toggle-option>
|
||||
<tb-toggle-option value="polygons" [error]="mapSettingsFormGroup.get('polygons').invalid ? ('common.required-fields' | translate) : null">{{ 'widgets.maps.overlays.polygons' | translate }}</tb-toggle-option>
|
||||
<tb-toggle-option value="circles" [error]="mapSettingsFormGroup.get('circles').invalid ? ('common.required-fields' | translate) : null">{{ 'widgets.maps.overlays.circles' | translate }}</tb-toggle-option>
|
||||
</tb-toggle-select>
|
||||
</div>
|
||||
<tb-map-data-layers *ngIf="trip"
|
||||
|
||||
@ -41,7 +41,16 @@
|
||||
[name]="name"
|
||||
[(ngModel)]="value"
|
||||
(ngModelChange)="valueChange.emit(value)">
|
||||
<mat-button-toggle *ngFor="let option of options; trackBy: trackByHeaderOption" [value]="option.value" [disabled]="disabled">{{ option.name }}</mat-button-toggle>
|
||||
<mat-button-toggle *ngFor="let option of options; trackBy: trackByHeaderOption" [value]="option.value" [disabled]="disabled" [class.tb-toggle-button-error]="(option.error$ | async) && value !== option.value">
|
||||
{{ option.name }}
|
||||
<mat-icon matTooltipPosition="above"
|
||||
matTooltipClass="tb-error-tooltip"
|
||||
[matTooltip]="(option.error$ | async)"
|
||||
*ngIf="(option.error$ | async) && value !== option.value"
|
||||
class="tb-error tb-error-icon">
|
||||
warning
|
||||
</mat-icon>
|
||||
</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
</div>
|
||||
<button mat-icon-button
|
||||
|
||||
@ -43,6 +43,12 @@
|
||||
.tb-toggle-header {
|
||||
transition: transform 500ms cubic-bezier(0.35, 0, 0.25, 1);
|
||||
}
|
||||
|
||||
.tb-error-icon {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
:host ::ng-deep {
|
||||
@ -79,6 +85,12 @@
|
||||
border-radius: 100px;
|
||||
}
|
||||
}
|
||||
.tb-toggle-button-error {
|
||||
.mat-button-toggle-button {
|
||||
border: 1px solid rgb(221, 44, 0);
|
||||
border-radius: 20px;
|
||||
}
|
||||
}
|
||||
.mat-button-toggle + .mat-button-toggle {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
@ -16,7 +16,8 @@
|
||||
|
||||
import {
|
||||
AfterContentChecked,
|
||||
AfterContentInit, AfterViewChecked,
|
||||
AfterContentInit,
|
||||
AfterViewChecked,
|
||||
AfterViewInit,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
@ -25,17 +26,20 @@ import {
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
HostBinding,
|
||||
Input, NgZone,
|
||||
Input,
|
||||
NgZone,
|
||||
OnChanges,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
Output,
|
||||
QueryList,
|
||||
SimpleChanges,
|
||||
ViewChild
|
||||
} from '@angular/core';
|
||||
import { PageComponent } from '@shared/components/page.component';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from '@core/core.state';
|
||||
import { BehaviorSubject, Subject, Subscription } from 'rxjs';
|
||||
import { BehaviorSubject, Observable, ReplaySubject, Subject, Subscription } from 'rxjs';
|
||||
import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';
|
||||
import { MediaBreakpoints } from '@shared/models/constants';
|
||||
import { coerceBoolean } from '@shared/decorators/coercion';
|
||||
@ -46,6 +50,7 @@ import { MatButtonToggle, MatButtonToggleGroup } from '@angular/material/button-
|
||||
export interface ToggleHeaderOption {
|
||||
name: string;
|
||||
value: any;
|
||||
error$?: Observable<string>;
|
||||
}
|
||||
|
||||
export type ToggleHeaderAppearance = 'fill' | 'fill-invert' | 'stroked';
|
||||
@ -59,10 +64,14 @@ export type ScrollDirection = 'after' | 'before';
|
||||
}
|
||||
)
|
||||
// eslint-disable-next-line @angular-eslint/directive-class-suffix
|
||||
export class ToggleOption {
|
||||
export class ToggleOption implements OnChanges, OnDestroy {
|
||||
|
||||
@Input() value: any;
|
||||
|
||||
@Input() error: string;
|
||||
|
||||
currentError = new ReplaySubject<string>(1);
|
||||
|
||||
get viewValue(): string {
|
||||
return (this._element?.nativeElement.textContent || '').trim();
|
||||
}
|
||||
@ -70,6 +79,18 @@ export class ToggleOption {
|
||||
constructor(
|
||||
private _element: ElementRef<HTMLElement>
|
||||
) {}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes?.error) {
|
||||
if (changes.error.currentValue !== changes.error.previousValue) {
|
||||
this.currentError.next(this.error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.currentError.complete();
|
||||
}
|
||||
}
|
||||
|
||||
@Directive()
|
||||
@ -102,8 +123,10 @@ export abstract class _ToggleBase extends PageComponent implements AfterContentI
|
||||
this.options.length = 0;
|
||||
this.toggleOptions.forEach(option => {
|
||||
this.options.push(
|
||||
{ name: option.viewValue,
|
||||
value: option.value
|
||||
{
|
||||
name: option.viewValue,
|
||||
value: option.value,
|
||||
error$: option.currentError.asObservable()
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
@ -1137,7 +1137,8 @@
|
||||
"key-required": "Key is required.",
|
||||
"key-pattern": "Key is invalid.",
|
||||
"key-max-length": "Key should be less than 256 characters."
|
||||
}
|
||||
},
|
||||
"required-fields": "Missing required fields"
|
||||
},
|
||||
"content-type": {
|
||||
"json": "Json",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user