mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Es existiert bereits ein Onlinekonto
This commit is contained in:
@@ -4,7 +4,7 @@ import { AbstractControl, AsyncValidatorFn, FormControl, FormGroup } from '@angu
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { BreadcrumbService } from '@core/breadcrumb';
|
||||
import { CrmCustomerService } from '@domain/crm';
|
||||
import { AddressDTO, CustomerDTO, ShippingAddressDTO } from '@swagger/crm';
|
||||
import { AddressDTO, CustomerDTO, PayerDTO, ShippingAddressDTO } from '@swagger/crm';
|
||||
import { UiErrorModalComponent, UiModalService } from '@ui/modal';
|
||||
import { UiValidators } from '@ui/validators';
|
||||
import { isNull } from 'lodash';
|
||||
@@ -138,6 +138,7 @@ export abstract class AbstractCreateCustomer implements OnInit, OnDestroy {
|
||||
|
||||
patchFormData(key: keyof CustomerCreateFormData, value: any) {
|
||||
this._formData.next({ ...this.formData, [key]: value });
|
||||
this.cdr.markForCheck();
|
||||
}
|
||||
|
||||
emailExistsValidator: AsyncValidatorFn = (control) => {
|
||||
@@ -240,12 +241,35 @@ export abstract class AbstractCreateCustomer implements OnInit, OnDestroy {
|
||||
customer.dateOfBirth = data.birthDate;
|
||||
}
|
||||
|
||||
if (data.billingAddress?.deviatingAddress) {
|
||||
const billingAddress = this.mapToBillingAddress(data.billingAddress);
|
||||
|
||||
if (this.validateShippingAddress) {
|
||||
try {
|
||||
billingAddress.address = await this.validateAddressData(billingAddress.address);
|
||||
} catch (error) {
|
||||
this.form.enable();
|
||||
setTimeout(() => {
|
||||
this.addressFormBlock.setAddressValidationError(error.error.invalidProperties);
|
||||
}, 10);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
customer.payers = [
|
||||
{
|
||||
payer: billingAddress,
|
||||
isDefault: new Date().toJSON(),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
if (data.deviatingDeliveryAddress?.deviatingAddress) {
|
||||
const shippingAddress = this.mapToShippingAddress(data.deviatingDeliveryAddress);
|
||||
|
||||
if (this.validateShippingAddress) {
|
||||
try {
|
||||
debugger;
|
||||
shippingAddress.address = await this.validateAddressData(shippingAddress.address);
|
||||
} catch (error) {
|
||||
this.form.enable();
|
||||
@@ -284,6 +308,22 @@ export abstract class AbstractCreateCustomer implements OnInit, OnDestroy {
|
||||
};
|
||||
}
|
||||
|
||||
mapToBillingAddress({ name, address, email, organisation, phoneNumbers }: DeviatingAddressFormBlockData): PayerDTO {
|
||||
return {
|
||||
gender: name?.gender,
|
||||
title: name?.title,
|
||||
firstName: name?.firstName,
|
||||
lastName: name?.lastName,
|
||||
address,
|
||||
communicationDetails: {
|
||||
email: email ? email : null,
|
||||
mobile: phoneNumbers?.mobile ? phoneNumbers.mobile : null,
|
||||
phone: phoneNumbers?.phone ? phoneNumbers.phone : null,
|
||||
},
|
||||
organisation,
|
||||
};
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.onDestroy$.next();
|
||||
this.onDestroy$.complete();
|
||||
|
||||
@@ -173,7 +173,7 @@ export class CreateP4MCustomerComponent extends AbstractCreateCustomer implement
|
||||
}
|
||||
}
|
||||
|
||||
mapCustomerInfoDtoToCustomerDto(customerInfoDto: CustomerInfoDTO): CustomerDTO {
|
||||
static MapCustomerInfoDtoToCustomerDto(customerInfoDto: CustomerInfoDTO): CustomerDTO {
|
||||
return {
|
||||
address: customerInfoDto.address,
|
||||
agentComment: customerInfoDto.agentComment,
|
||||
@@ -210,7 +210,7 @@ export class CreateP4MCustomerComponent extends AbstractCreateCustomer implement
|
||||
if (customerDto) {
|
||||
customer = { ...customerDto, ...customer };
|
||||
} else if (customerInfoDto) {
|
||||
customer = { ...this.mapCustomerInfoDtoToCustomerDto(customerInfoDto), ...customer };
|
||||
customer = { ...CreateP4MCustomerComponent.MapCustomerInfoDtoToCustomerDto(customerInfoDto), ...customer };
|
||||
}
|
||||
|
||||
const p4mFeature = customer.features?.find((attr) => attr.key === 'p4mUser');
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<form *ngIf="formData$ | async; let data" (keydown.enter)="$event.preventDefault()">
|
||||
<h1 class="title flex flex-row items-center justify-center">Kundenkartendaten erfasen</h1>
|
||||
<p class="description">Bitte erfassen Sie die Kundenkarte</p>
|
||||
|
||||
<app-customer-type-selector [processId]="processId$ | async" [p4mUser]="true" customerType="webshop" [readonly]="true">
|
||||
</app-customer-type-selector>
|
||||
|
||||
<app-p4m-number-form-block
|
||||
#p4mBlock
|
||||
@@ -21,35 +25,55 @@
|
||||
>
|
||||
</app-newsletter-form-block>
|
||||
|
||||
<app-deviating-address-form-block
|
||||
#dbaBlock
|
||||
[defaults]="{ address: { country: 'DEU' } }"
|
||||
[tabIndexStart]="newsletterBlock.tabIndexEnd + 1"
|
||||
(onInit)="addFormBlock('billingAddress', $event)"
|
||||
[data]="data.billingAddress"
|
||||
(dataChanges)="patchFormData('billingAddress', $event)"
|
||||
[nameRequiredMarks]="nameRequiredMarks"
|
||||
[nameValidatorFns]="nameValidationFns"
|
||||
[addressRequiredMarks]="shippingAddressRequiredMarks"
|
||||
[addressValidatorFns]="shippingAddressValidators"
|
||||
>
|
||||
Abweichende Rechnugsaddresse anlegen
|
||||
</app-deviating-address-form-block>
|
||||
<app-name-form-block [data]="data.name" readonly> </app-name-form-block>
|
||||
|
||||
<app-deviating-address-form-block
|
||||
#ddaBlock
|
||||
[defaults]="{ address: { country: 'DEU' } }"
|
||||
[tabIndexStart]="dbaBlock.tabIndexEnd + 1"
|
||||
(onInit)="addFormBlock('deviatingDeliveryAddress', $event)"
|
||||
[data]="data.deviatingDeliveryAddress"
|
||||
(dataChanges)="patchFormData('deviatingDeliveryAddress', $event)"
|
||||
[nameRequiredMarks]="nameRequiredMarks"
|
||||
[nameValidatorFns]="nameValidationFns"
|
||||
[addressRequiredMarks]="shippingAddressRequiredMarks"
|
||||
[addressValidatorFns]="shippingAddressValidators"
|
||||
>
|
||||
Abweichende Lieferadresse anlegen
|
||||
</app-deviating-address-form-block>
|
||||
<app-email-form-block [data]="data.email" readonly> </app-email-form-block>
|
||||
|
||||
<app-organisation-form-block appearence="compact" [data]="data.organisation" readonly></app-organisation-form-block>
|
||||
|
||||
<app-address-form-block [data]="data.address" readonly> </app-address-form-block>
|
||||
|
||||
<div class="mt-8">
|
||||
<h4 class="-mb-6">Rechnugsadresse</h4>
|
||||
<ui-form-control class="-mb-5" [showHint]="false">
|
||||
<input type="text" [value]="(billingAddress | address:true) ?? 'Keine Adresse vorhanden'" [uiInput] [readonly]="true" />
|
||||
</ui-form-control>
|
||||
<app-deviating-address-form-block
|
||||
#dbaBlock
|
||||
[defaults]="{ address: { country: 'DEU' } }"
|
||||
[tabIndexStart]="newsletterBlock.tabIndexEnd + 1"
|
||||
(onInit)="addFormBlock('billingAddress', $event)"
|
||||
[data]="data.billingAddress"
|
||||
(dataChanges)="patchFormData('billingAddress', $event)"
|
||||
[nameRequiredMarks]="nameRequiredMarks"
|
||||
[nameValidatorFns]="nameValidationFns"
|
||||
[addressRequiredMarks]="addressRequiredMarks"
|
||||
[addressValidatorFns]="addressValidatorFns"
|
||||
>
|
||||
Abweichende Rechnugsaddresse anlegen
|
||||
</app-deviating-address-form-block>
|
||||
</div>
|
||||
|
||||
<div class="mt-8">
|
||||
<h4 class="-mb-6">Lieferadresse</h4>
|
||||
<ui-form-control class="-mb-5" [showHint]="false">
|
||||
<input type="text" [value]="(shippingAddress | address:true) ?? 'Keine Adresse vorhanden'" [uiInput] [readonly]="true" />
|
||||
</ui-form-control>
|
||||
<app-deviating-address-form-block
|
||||
#ddaBlock
|
||||
[defaults]="{ address: { country: 'DEU' } }"
|
||||
[tabIndexStart]="dbaBlock.tabIndexEnd + 1"
|
||||
(onInit)="addFormBlock('deviatingDeliveryAddress', $event)"
|
||||
[data]="data.deviatingDeliveryAddress"
|
||||
(dataChanges)="patchFormData('deviatingDeliveryAddress', $event)"
|
||||
[nameRequiredMarks]="nameRequiredMarks"
|
||||
[nameValidatorFns]="nameValidationFns"
|
||||
[addressRequiredMarks]="addressRequiredMarks"
|
||||
[addressValidatorFns]="addressValidatorFns"
|
||||
>
|
||||
Abweichende Lieferadresse anlegen
|
||||
</app-deviating-address-form-block>
|
||||
</div>
|
||||
|
||||
<app-birth-date-form-block
|
||||
#bdBlock
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { CustomerDTO } from '@swagger/crm';
|
||||
import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core';
|
||||
import { ValidatorFn, Validators } from '@angular/forms';
|
||||
import { Result } from '@domain/defs';
|
||||
import { CustomerDTO, CustomerInfoDTO, KeyValueDTOOfStringAndString, PayerDTO } from '@swagger/crm';
|
||||
import { NameFormBlockData } from '../../form-blocks/name/name-form-block-data';
|
||||
import { AbstractCreateCustomer } from '../abstract-create-customer';
|
||||
import { CreateP4MCustomerComponent } from '../create-p4m-customer';
|
||||
|
||||
@Component({
|
||||
selector: 'page-update-p4m-webshop-customer',
|
||||
@@ -8,12 +12,136 @@ import { AbstractCreateCustomer } from '../abstract-create-customer';
|
||||
styleUrls: ['../create-customer.scss', 'update-p4m-webshop-customer.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class UpdateP4MWebshopCustomerComponent extends AbstractCreateCustomer {
|
||||
export class UpdateP4MWebshopCustomerComponent extends AbstractCreateCustomer implements OnInit {
|
||||
validateAddress = true;
|
||||
|
||||
validateShippingAddress = true;
|
||||
|
||||
saveCustomer(customer: CustomerDTO): Promise<CustomerDTO> {
|
||||
throw new Error('Method not implemented.');
|
||||
agbValidatorFns = [Validators.requiredTrue];
|
||||
|
||||
birthDateValidatorFns = [Validators.required];
|
||||
|
||||
nameRequiredMarks = ['gender', 'firstName', 'lastName'];
|
||||
|
||||
nameValidationFns: Record<keyof NameFormBlockData, ValidatorFn[]> = {
|
||||
firstName: [Validators.required],
|
||||
lastName: [Validators.required],
|
||||
gender: [Validators.required],
|
||||
title: [],
|
||||
};
|
||||
|
||||
addressRequiredMarks = ['street', 'streetNumber', 'zipCode', 'city', 'country'];
|
||||
|
||||
addressValidatorFns: Record<string, ValidatorFn[]> = {
|
||||
street: [Validators.required],
|
||||
streetNumber: [Validators.required],
|
||||
zipCode: [Validators.required],
|
||||
city: [Validators.required],
|
||||
country: [Validators.required],
|
||||
};
|
||||
|
||||
get billingAddress(): PayerDTO | undefined {
|
||||
const payers = this.formData?._meta?.customerDto?.payers;
|
||||
|
||||
if (!payers || payers.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// the default payer is the payer with the latest isDefault(Date) value
|
||||
const defaultPayer = payers.reduce((prev, curr) => (new Date(prev.isDefault) > new Date(curr.isDefault) ? prev : curr));
|
||||
|
||||
return defaultPayer.payer.data;
|
||||
}
|
||||
|
||||
get shippingAddress() {
|
||||
const shippingAddresses = this.formData?._meta?.customerDto?.shippingAddresses;
|
||||
|
||||
if (!shippingAddresses || shippingAddresses.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// the default shipping address is the shipping address with the latest isDefault(Date) value
|
||||
const defaultShippingAddress = shippingAddresses.reduce((prev, curr) =>
|
||||
new Date(prev.data.isDefault) > new Date(curr.data.isDefault) ? prev : curr
|
||||
);
|
||||
|
||||
return defaultShippingAddress.data;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
super.ngOnInit();
|
||||
}
|
||||
|
||||
getInterests(): KeyValueDTOOfStringAndString[] {
|
||||
const interests: KeyValueDTOOfStringAndString[] = [];
|
||||
|
||||
for (const key in this.formData.interests) {
|
||||
if (this.formData.interests[key]) {
|
||||
interests.push({ key, group: 'KUBI_INTERESSEN' });
|
||||
}
|
||||
}
|
||||
|
||||
return interests;
|
||||
}
|
||||
|
||||
getNewsletter(): KeyValueDTOOfStringAndString | undefined {
|
||||
if (this.formData.newsletter) {
|
||||
return { key: 'kubi_newsletter', group: 'KUBI_NEWSLETTER' };
|
||||
}
|
||||
}
|
||||
|
||||
async saveCustomer(customer: CustomerDTO): Promise<CustomerDTO> {
|
||||
console.log('saveCustomer', customer);
|
||||
let res: Result<CustomerDTO>;
|
||||
|
||||
const { customerDto, customerInfoDto } = this.formData?._meta ?? {};
|
||||
|
||||
if (customerDto) {
|
||||
customer = { ...customerDto, shippingAddresses: [], payers: [], ...customer };
|
||||
|
||||
if (customerDto.shippingAddresses?.length) {
|
||||
customer.shippingAddresses.unshift(...customerDto.shippingAddresses);
|
||||
}
|
||||
if (customerDto.payers?.length) {
|
||||
customer.payers.unshift(...customerDto.payers);
|
||||
}
|
||||
} else if (customerInfoDto) {
|
||||
customer = { ...CreateP4MCustomerComponent.MapCustomerInfoDtoToCustomerDto(customerInfoDto), ...customer };
|
||||
}
|
||||
|
||||
const p4mFeature = customer.features?.find((attr) => attr.key === 'p4mUser');
|
||||
if (p4mFeature) {
|
||||
p4mFeature.value = this.formData.p4m;
|
||||
} else {
|
||||
customer.features.push({
|
||||
key: 'p4mUser',
|
||||
value: this.formData.p4m,
|
||||
});
|
||||
}
|
||||
|
||||
const interests = this.getInterests();
|
||||
|
||||
if (interests.length > 0) {
|
||||
customer.features?.push(...interests);
|
||||
// TODO: Klärung wie Interessen zukünftig gespeichert werden
|
||||
// await this._loyaltyCardService
|
||||
// .LoyaltyCardSaveInteressen({
|
||||
// customerId: res.result.id,
|
||||
// interessen: this.getInterests(),
|
||||
// })
|
||||
// .toPromise();
|
||||
}
|
||||
|
||||
const newsletter = this.getNewsletter();
|
||||
|
||||
if (newsletter) {
|
||||
customer.features.push(newsletter);
|
||||
} else {
|
||||
customer.features = customer.features.filter((feature) => feature.key !== 'kubi_newsletter' && feature.group !== 'KUBI_NEWSLETTER');
|
||||
}
|
||||
|
||||
res = await this.customerService.createOnlineCustomer(customer).toPromise();
|
||||
|
||||
return res.result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,15 @@ import {
|
||||
EmailFormBlockModule,
|
||||
PhoneNumbersFormBlockModule,
|
||||
} from '../../form-blocks';
|
||||
import { UiFormControlModule } from '@ui/form-control';
|
||||
import { UiInputModule } from '@ui/input';
|
||||
import { CustomerPipesModule } from '../../pipes';
|
||||
import { CustomerTypeSelectorModule } from '../../shared/customer-type-selector';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
CustomerTypeSelectorModule,
|
||||
AddressFormBlockModule,
|
||||
BirthDateFormBlockModule,
|
||||
InterestsFormBlockModule,
|
||||
@@ -31,6 +36,9 @@ import {
|
||||
AcceptAGBFormBlockModule,
|
||||
EmailFormBlockModule,
|
||||
PhoneNumbersFormBlockModule,
|
||||
UiFormControlModule,
|
||||
UiInputModule,
|
||||
CustomerPipesModule,
|
||||
],
|
||||
exports: [UpdateP4MWebshopCustomerComponent],
|
||||
declarations: [UpdateP4MWebshopCustomerComponent],
|
||||
|
||||
@@ -15,6 +15,7 @@ import { PhoneNumbersFormBlockComponent, PhoneNumbersFormBlockData } from '../ph
|
||||
templateUrl: 'deviating-address-form-block.component.html',
|
||||
styleUrls: ['deviating-address-form-block.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
exportAs: 'appDeviatingAddressFormBlock',
|
||||
})
|
||||
export class DeviatingAddressFormBlockComponent extends FormBlockGroup<DeviatingAddressFormBlockData> implements AfterViewInit {
|
||||
@Input()
|
||||
@@ -36,13 +37,7 @@ export class DeviatingAddressFormBlockComponent extends FormBlockGroup<Deviating
|
||||
private readonly _phoneNumbersFormBlock: AddressFormBlockComponent;
|
||||
|
||||
get tabIndexEnd() {
|
||||
let tabIndex = this.tabIndexStart;
|
||||
if (this.control.value.deviatingDeliveryAddress) {
|
||||
return (
|
||||
this._phoneNumbersFormBlock?.tabIndexEnd ?? this._emailFormBlock?.tabIndexEnd ?? this._addressFormBlock?.tabIndexEnd ?? tabIndex
|
||||
);
|
||||
}
|
||||
return tabIndex;
|
||||
return this.tabIndexStart + 10;
|
||||
}
|
||||
|
||||
@Input() defaults: Partial<DeviatingAddressFormBlockData>;
|
||||
|
||||
@@ -14,9 +14,6 @@ export class OrganisationFormBlockComponent extends FormBlockGroup<OrganisationF
|
||||
appearence: 'default' | 'compact' = 'default';
|
||||
|
||||
get tabIndexEnd() {
|
||||
if (this.appearence === 'compact') {
|
||||
return this.tabIndexStart;
|
||||
}
|
||||
return this.tabIndexStart + 2;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,11 +18,13 @@ export interface AddressData {
|
||||
export class AddressPipe implements PipeTransform {
|
||||
private result: string;
|
||||
private data: AddressData;
|
||||
private useComma = false;
|
||||
|
||||
constructor(private cdr: ChangeDetectorRef) {}
|
||||
|
||||
transform(data: AddressData): string {
|
||||
transform(data: AddressData, useComma?: boolean): string {
|
||||
this.data = data;
|
||||
this.useComma = useComma ?? this.useComma;
|
||||
this.getResult();
|
||||
|
||||
return this.result;
|
||||
@@ -33,13 +35,13 @@ export class AddressPipe implements PipeTransform {
|
||||
let parts = [
|
||||
this.data?.organisation?.name || '',
|
||||
this.data?.organisation?.department || '',
|
||||
[this.data?.lastName, this.data?.firstName].filter((f) => !!f).join(', '),
|
||||
[this.data?.lastName, this.data?.firstName].filter((f) => !!f).join(this.useComma ? ' ' : ', '),
|
||||
`${this.data?.address?.street || ''} ${this.data?.address?.streetNumber || ''}`,
|
||||
`${this.data?.address?.zipCode || ''} ${this.data?.address?.city || ''}`,
|
||||
]
|
||||
.filter((value) => value != '')
|
||||
.filter((value) => value.trim());
|
||||
result = parts.join(' | ');
|
||||
result = parts.join(this.useComma ? ', ' : ' | ');
|
||||
|
||||
if (result !== this.result) {
|
||||
this.result = result;
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
<ui-checkbox *ngIf="customerType !== 'b2b'" [ngModel]="p4mUser" (ngModelChange)="setValue({ p4mUser: !p4mUser })" [disabled]="p4mReadonly">
|
||||
<ui-checkbox
|
||||
*ngIf="customerType !== 'b2b'"
|
||||
[ngModel]="p4mUser"
|
||||
(ngModelChange)="setValue({ p4mUser: !p4mUser })"
|
||||
[disabled]="p4mReadonly || readonly"
|
||||
>
|
||||
Kundenkarte
|
||||
</ui-checkbox>
|
||||
<ng-container *ngFor="let option of filteredOptions$ | async">
|
||||
@@ -6,6 +11,7 @@
|
||||
*ngIf="option?.enabled !== false"
|
||||
[ngModel]="option.value === customerType"
|
||||
(ngModelChange)="setValue({ customerType: $event ? option.value : undefined })"
|
||||
[disabled]="readonly"
|
||||
>
|
||||
{{ option.label }}
|
||||
</ui-checkbox>
|
||||
|
||||
@@ -42,6 +42,9 @@ export class CustomerTypeSelectorComponent extends ComponentStore<CustomerTypeSe
|
||||
implements OnInit, OnDestroy, ControlValueAccessor {
|
||||
private _onDestroy$ = new Subject<void>();
|
||||
|
||||
@Input()
|
||||
readonly: boolean;
|
||||
|
||||
@Input()
|
||||
get value() {
|
||||
if (this.p4mUser) {
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
<div class="input-wrapper" [class.empty]="!ngControl?.value" [class.focused]="uiControl?.focused | async">
|
||||
<div class="input-wrapper" [class.empty]="!ngControl?.value" [class.focused]="!isReadonly && (uiControl?.focused | async)">
|
||||
<!-- suffix and prefix order changed due to flex-row-reverse -->
|
||||
<span class="suffix">{{ suffix }}</span>
|
||||
<ng-content select="input, ui-select, ui-datepicker, button, ui-searchbox, textarea"></ng-content>
|
||||
<span class="prefix">{{ prefix }}</span>
|
||||
<label *ngIf="label" [for]="uiControl?.id">{{ label }}{{ requiredMark }}</label>
|
||||
</div>
|
||||
<span class="hint" *ngIf="ngControl?.touched && ngControl?.errors">
|
||||
<span class="hint" *ngIf="showHint && ngControl?.touched && ngControl?.errors">
|
||||
{{ ngControl?.errors | uiFormControlFirstError: label }}
|
||||
</span>
|
||||
<span class="hint readonly-hint" *ngIf="showHint && isReadonly">Nicht Änderbar</span>
|
||||
<button
|
||||
*ngIf="clearable && ngControl?.value && !ngControl?.disabled && !(uiControl?.type === 'radio' || uiControl?.type === 'checkbox')"
|
||||
*ngIf="
|
||||
!isReadonly && clearable && ngControl?.value && !ngControl?.disabled && !(uiControl?.type === 'radio' || uiControl?.type === 'checkbox')
|
||||
"
|
||||
class="ui-form-control-clear clear"
|
||||
type="button"
|
||||
(click)="clear()"
|
||||
|
||||
@@ -8,6 +8,10 @@ button.clear {
|
||||
|
||||
.hint {
|
||||
@apply text-brand text-x-small font-bold;
|
||||
|
||||
&.readonly-hint {
|
||||
@apply text-inactive-branch font-normal;
|
||||
}
|
||||
}
|
||||
|
||||
.status {
|
||||
@@ -142,3 +146,10 @@ button.clear {
|
||||
@apply gap-0;
|
||||
}
|
||||
}
|
||||
|
||||
::ng-deep .ui-form-control--readonly {
|
||||
input,
|
||||
ui-select {
|
||||
@apply opacity-40;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,11 @@ export class UiFormControlComponent implements AfterContentInit, OnDestroy {
|
||||
return this.uiControl?.type;
|
||||
}
|
||||
|
||||
@HostBinding('class.ui-form-control--readonly')
|
||||
get isReadonly() {
|
||||
return this.uiControl?.readonly;
|
||||
}
|
||||
|
||||
@Input()
|
||||
label: string;
|
||||
|
||||
@@ -50,6 +55,9 @@ export class UiFormControlComponent implements AfterContentInit, OnDestroy {
|
||||
@Input()
|
||||
suffix: string;
|
||||
|
||||
@Input()
|
||||
showHint = true;
|
||||
|
||||
@Output()
|
||||
cleared = new EventEmitter();
|
||||
|
||||
@@ -68,8 +76,6 @@ export class UiFormControlComponent implements AfterContentInit, OnDestroy {
|
||||
this.cdr.markForCheck();
|
||||
})
|
||||
);
|
||||
} else {
|
||||
console.error('UiFormControlDirective is missing in Template');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';
|
||||
import { Directive, EventEmitter, HostBinding, Input } from '@angular/core';
|
||||
|
||||
@Directive()
|
||||
@@ -10,6 +11,17 @@ export abstract class UiFormControlDirective<T> {
|
||||
@HostBinding('attr.id')
|
||||
id: string = (Date.now() + Math.random()).toString(32);
|
||||
|
||||
private _readonly = false;
|
||||
|
||||
@Input()
|
||||
@HostBinding('readonly')
|
||||
get readonly(): boolean {
|
||||
return this._readonly;
|
||||
}
|
||||
set readonly(value: BooleanInput) {
|
||||
this._readonly = coerceBooleanProperty(value);
|
||||
}
|
||||
|
||||
focused = new EventEmitter<boolean>();
|
||||
|
||||
abstract type: string;
|
||||
|
||||
@@ -17,6 +17,11 @@ export class UiFormFieldComponent implements AfterContentInit {
|
||||
|
||||
@ContentChild(UiLabelComponent, { read: UiLabelComponent }) label: UiLabelComponent;
|
||||
|
||||
@HostBinding('class.ui-form-field--readonly')
|
||||
isReadonly() {
|
||||
return this.input?.readonly;
|
||||
}
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngAfterContentInit(): void {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { BooleanInput } from '@angular/cdk/coercion';
|
||||
import { Directive, ElementRef, HostBinding, Input, Optional, Self } from '@angular/core';
|
||||
import { FormControl, FormControlDirective } from '@angular/forms';
|
||||
|
||||
@@ -26,6 +27,10 @@ export class UiInputDirective {
|
||||
}
|
||||
}
|
||||
|
||||
@Input()
|
||||
@HostBinding('readonly')
|
||||
readonly: boolean;
|
||||
|
||||
constructor(
|
||||
@Optional() @Self() private readonly _controlDirective: FormControlDirective,
|
||||
private _elementRef: ElementRef<UiInputDirective>
|
||||
|
||||
@@ -32,16 +32,6 @@ import { UiSelectOptionComponent } from './ui-select-option.component';
|
||||
export class UiSelectComponent extends UiFormControlDirective<any> implements ControlValueAccessor, AfterContentInit {
|
||||
readonly type = 'ui-select';
|
||||
|
||||
private _readonly = false;
|
||||
|
||||
@Input()
|
||||
get readonly(): boolean {
|
||||
return this._readonly;
|
||||
}
|
||||
set readonly(value: BooleanInput) {
|
||||
this._readonly = coerceBooleanProperty(value);
|
||||
}
|
||||
|
||||
@Input()
|
||||
value: any;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user