diff --git a/src/lib/dialog/base-dialog.component.ts b/src/lib/dialog/base-dialog.component.ts index ceb8a2c..0b2ac11 100644 --- a/src/lib/dialog/base-dialog.component.ts +++ b/src/lib/dialog/base-dialog.component.ts @@ -25,9 +25,9 @@ export abstract class BaseDialogComponent implements AfterViewInit, OnDestroy { protected readonly _formBuilder = inject(UntypedFormBuilder); protected readonly _loadingService = inject(LoadingService); protected readonly _toaster = inject(Toaster); + protected readonly _subscriptions: Subscription = new Subscription(); readonly #confirmationDialogService = inject(ConfirmationDialogService); readonly #dialog = inject(MatDialog); - readonly #subscriptions: Subscription = new Subscription(); #hasErrors = false; protected constructor(protected readonly _dialogRef: MatDialogRef, private readonly _isInEditMode = false) {} @@ -45,20 +45,20 @@ export abstract class BaseDialogComponent implements AfterViewInit, OnDestroy { } ngAfterViewInit() { - this.#subscriptions.add(this._dialogRef.backdropClick().subscribe(() => this.close())); + this._subscriptions.add(this._dialogRef.backdropClick().subscribe(() => this.close())); const events = [fromEvent(window, 'keyup'), fromEvent(window, 'input'), this.form?.valueChanges]; const events$ = merge(...events).pipe( debounceTime(10), tap(() => (this.#hasErrors = !!document.getElementsByClassName('ng-invalid')[0])), ); - this.#subscriptions.add(events$.subscribe()); + this._subscriptions.add(events$.subscribe()); } abstract save(options?: SaveOptions): void; ngOnDestroy(): void { - this.#subscriptions.unsubscribe(); + this._subscriptions.unsubscribe(); } close() { diff --git a/src/lib/inputs/details-radio/details-radio-option.ts b/src/lib/inputs/details-radio/details-radio-option.ts index b372705..6b4a68b 100644 --- a/src/lib/inputs/details-radio/details-radio-option.ts +++ b/src/lib/inputs/details-radio/details-radio-option.ts @@ -1,6 +1,14 @@ +interface ExtraOption { + label: string; + checked: boolean; +} + export interface DetailsRadioOption { id?: string; label: string; description: string; + descriptionParams?: Record; + icon?: string; value: I; + extraOption?: ExtraOption; } diff --git a/src/lib/inputs/details-radio/details-radio.component.html b/src/lib/inputs/details-radio/details-radio.component.html index b1071ed..d166810 100644 --- a/src/lib/inputs/details-radio/details-radio.component.html +++ b/src/lib/inputs/details-radio/details-radio.component.html @@ -7,11 +7,35 @@ [ngClass]="{ 'mb-8': !displayInRow, 'mr-8': displayInRow }" class="option pointer" > -
- - +
+ + +
+ + + +
+ + {{ option.extraOption.label | translate }} + +
+
+ +
- {{ option.description | translate }} + +
+ + +
+ + {{ option.description | translate }} +
diff --git a/src/lib/inputs/details-radio/details-radio.component.scss b/src/lib/inputs/details-radio/details-radio.component.scss index 51db6f8..651bb93 100644 --- a/src/lib/inputs/details-radio/details-radio.component.scss +++ b/src/lib/inputs/details-radio/details-radio.component.scss @@ -10,6 +10,28 @@ label { &.active { background-color: rgba(var(--iqser-primary-rgb), 0.1); } + + .icon-option { + display: flex; + gap: 20px; + + .icon { + transform: scale(1.2); + margin-top: 5px; + } + + .text { + display: flex; + flex-direction: column; + } + + .checked { + margin-left: auto; + margin-top: 5px; + transform: scale(0.8); + color: var(--iqser-primary); + } + } } .row { diff --git a/src/lib/inputs/details-radio/details-radio.component.ts b/src/lib/inputs/details-radio/details-radio.component.ts index 1517794..1e80578 100644 --- a/src/lib/inputs/details-radio/details-radio.component.ts +++ b/src/lib/inputs/details-radio/details-radio.component.ts @@ -1,10 +1,12 @@ -import { Component, Input } from '@angular/core'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; import { DetailsRadioOption } from './details-radio-option'; -import { NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { FormsModule, NG_VALIDATORS, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; import { FormFieldComponent } from '../form-field/form-field-component.directive'; -import { NgClass, NgForOf } from '@angular/common'; +import { NgClass, NgForOf, NgIf } from '@angular/common'; import { RoundCheckboxComponent } from '../round-checkbox/round-checkbox.component'; import { TranslateModule } from '@ngx-translate/core'; +import { MatIconModule } from '@angular/material/icon'; +import { MatCheckboxModule } from '@angular/material/checkbox'; @Component({ selector: 'iqser-details-radio [options]', @@ -23,20 +25,42 @@ import { TranslateModule } from '@ngx-translate/core'; useExisting: DetailsRadioComponent, }, ], - imports: [NgForOf, NgClass, RoundCheckboxComponent, TranslateModule], + imports: [ + NgForOf, + NgClass, + RoundCheckboxComponent, + TranslateModule, + MatIconModule, + NgIf, + FormsModule, + MatCheckboxModule, + ReactiveFormsModule, + ], }) export class DetailsRadioComponent extends FormFieldComponent> { @Input() options: DetailsRadioOption[] = []; @Input() displayInRow = false; + @Output() readonly extraOptionChanged: EventEmitter> = new EventEmitter(); + toggleOption(option: DetailsRadioOption): void { - this.markAsTouched(); - const currentlyChecked = this.value?.value === option.value; - this._value = currentlyChecked ? undefined : option; - this.onChange(this._value); + if (option.value !== this._value?.value) { + this.markAsTouched(); + const currentlyChecked = this.value?.value === option.value; + this._value = currentlyChecked ? undefined : option; + this.onChange(this._value); + } } - groupId(option: DetailsRadioOption) { + groupId(option: DetailsRadioOption): string { return (option.id ?? option.label.replace('.', '-')) + '-checkbox-details-input'; } + + isSelected(option: DetailsRadioOption): boolean { + return option.value === this.value?.value; + } + + emitExtraOption(): void { + this.extraOptionChanged.emit(this.value); + } }