mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
#1145 Anlage von Kunden (Gast, Filiale und Online)
This commit is contained in:
40
angular.json
40
angular.json
@@ -1456,6 +1456,46 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@ui/modal": {
|
||||
"projectType": "library",
|
||||
"root": "apps/ui/modal",
|
||||
"sourceRoot": "apps/ui/modal/src",
|
||||
"prefix": "ui",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:ng-packagr",
|
||||
"options": {
|
||||
"tsConfig": "apps/ui/modal/tsconfig.lib.json",
|
||||
"project": "apps/ui/modal/ng-package.json"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"tsConfig": "apps/ui/modal/tsconfig.lib.prod.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "apps/ui/modal/src/test.ts",
|
||||
"tsConfig": "apps/ui/modal/tsconfig.spec.json",
|
||||
"karmaConfig": "apps/ui/modal/karma.conf.js"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"apps/ui/modal/tsconfig.lib.json",
|
||||
"apps/ui/modal/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "sales"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { StringDictionary } from '@cmf/core';
|
||||
import { AutocompleteDTO, CustomerDTO, CustomerInfoDTO, CustomerService, InputDTO } from '@swagger/crm';
|
||||
import { AddressDTO, AutocompleteDTO, CustomerDTO, CustomerInfoDTO, CustomerService, InputDTO } from '@swagger/crm';
|
||||
import { PagedResult, Result } from 'apps/domain/defs/src/public-api';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@@ -39,4 +39,32 @@ export class CrmCustomerService {
|
||||
patchCustomer(customerId: number, customer: CustomerDTO): Observable<Result<CustomerDTO>> {
|
||||
return this.customerService.CustomerPatchCustomer({ customerId, customer });
|
||||
}
|
||||
|
||||
createB2BCustomer(customer: CustomerDTO) {
|
||||
// this.customerService.CustomerCreateCustomer({ ...customer, })
|
||||
}
|
||||
|
||||
createOnlineCustomer(customer: CustomerDTO) {
|
||||
return this.customerService.CustomerCreateOnlineCustomer({ ...customer, customerType: 8, hasOnlineAccount: true });
|
||||
}
|
||||
|
||||
createGuestCustomer(customer: CustomerDTO) {
|
||||
return this.customerService.CustomerCreateOnlineCustomer({ ...customer, customerType: 8, isGuestAccount: true });
|
||||
}
|
||||
|
||||
createBranchCustomer(customer: CustomerDTO) {
|
||||
return this.customerService.CustomerCreateCustomer({ ...customer, customerType: 8 });
|
||||
}
|
||||
|
||||
validateAddress(address: AddressDTO) {
|
||||
return this.customerService.CustomerValidateAddress(address);
|
||||
}
|
||||
|
||||
getCountries() {
|
||||
return this.customerService.CustomerGetCountries({});
|
||||
}
|
||||
|
||||
emailExists(email: string) {
|
||||
return this.customerService.CustomerEmailExists(email);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
<form *ngIf="control" [formGroup]="control">
|
||||
<ng-container formGroupName="organisation">
|
||||
<ui-form-control label="Firmenname" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="name" tabindex="1" />
|
||||
</ui-form-control>
|
||||
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Abteilung" [clearable]="false">
|
||||
<input uiInput type="text" formControlName="department" tabindex="2" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="USt-ID" [clearable]="false">
|
||||
<input uiInput type="text" formControlName="vatId" tabindex="3" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Anrede" [clearable]="false">
|
||||
<ui-select formControlName="gender" tabindex="4">
|
||||
<ui-select-option [value]="2" label="Herr"></ui-select-option>
|
||||
<ui-select-option [value]="4" label="Frau"></ui-select-option>
|
||||
</ui-select>
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Titel">
|
||||
<ui-select formControlName="title" tabindex="5">
|
||||
<ui-select-option value="Dr." label="Dr."></ui-select-option>
|
||||
<ui-select-option value="Prof." label="Prof."></ui-select-option>
|
||||
<ui-select-option value="Prof. Dr." label="Prof. Dr."></ui-select-option>
|
||||
</ui-select>
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Nachname" [clearable]="false">
|
||||
<input uiInput type="text" formControlName="lastName" tabindex="6" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Vorname" [clearable]="false">
|
||||
<input uiInput type="text" formControlName="firstName" tabindex="7" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<ng-container formGroupName="address">
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Straße" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="street" tabindex="8" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Hausnummer" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="streetNumber" tabindex="9" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<div class="control-row">
|
||||
<ui-form-control label="PLZ" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="zipCode" tabindex="10" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Ort" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="city" tabindex="11" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<ui-form-control label="Adresszusatz" [clearable]="false">
|
||||
<input uiInput type="text" formControlName="info" tabindex="12" />
|
||||
</ui-form-control>
|
||||
|
||||
<ui-form-control label="Land" [clearable]="false">
|
||||
<ui-select formControlName="country" tabindex="13">
|
||||
<ui-select-option value="DEU" label="Deutschland"></ui-select-option>
|
||||
</ui-select>
|
||||
</ui-form-control>
|
||||
</ng-container>
|
||||
|
||||
<ng-container formGroupName="communicationDetails">
|
||||
<ui-form-control label="E-Mail" [clearable]="false">
|
||||
<input uiInput type="mail" formControlName="email" tabindex="14" />
|
||||
</ui-form-control>
|
||||
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Festnetznummer">
|
||||
<input uiInput type="tel" formControlName="phone" tabindex="15" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Mobilnummer" [clearable]="false">
|
||||
<input uiInput type="tel" formControlName="mobile" tabindex="16" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
</ng-container>
|
||||
</form>
|
||||
@@ -1,7 +0,0 @@
|
||||
.control-row {
|
||||
@apply flex flex-row gap-8;
|
||||
|
||||
ui-form-control {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
import { Component, ChangeDetectionStrategy, Input } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { CustomerDTO } from '@swagger/crm';
|
||||
|
||||
@Component({
|
||||
selector: 'page-create-b2b',
|
||||
templateUrl: 'create-b2b-form.component.html',
|
||||
styleUrls: ['create-b2b-form.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class CreateB2BComponent {
|
||||
@Input()
|
||||
customer: CustomerDTO;
|
||||
|
||||
control: FormGroup;
|
||||
|
||||
constructor(private fb: FormBuilder) {
|
||||
this.initForm();
|
||||
}
|
||||
|
||||
initForm() {
|
||||
const { fb } = this;
|
||||
|
||||
this.control = fb.group({
|
||||
organisation: fb.group({
|
||||
name: fb.control('', [Validators.required]),
|
||||
department: fb.control(''),
|
||||
vatId: fb.control(''),
|
||||
}),
|
||||
gender: fb.control(0),
|
||||
title: fb.control(''),
|
||||
firstName: fb.control(''),
|
||||
lastName: fb.control(''),
|
||||
address: fb.group({
|
||||
street: fb.control('', [Validators.required]),
|
||||
streetNumber: fb.control('', [Validators.required]),
|
||||
zipCode: fb.control('', [Validators.required]),
|
||||
city: fb.control('', [Validators.required]),
|
||||
info: fb.control(''),
|
||||
country: fb.control('DEU', [Validators.required]),
|
||||
}),
|
||||
communicationDetails: fb.group({
|
||||
email: fb.control(''),
|
||||
phone: fb.control(''),
|
||||
mobile: fb.control(''),
|
||||
}),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
<div class="card">
|
||||
<h1>Kundendaten erfassen</h1>
|
||||
<p>
|
||||
Für eine B2B Bestellung benötigen Sie<br />
|
||||
einen Firmenaccount. Wir legen diesen<br />
|
||||
gerne direkt für Sie an.
|
||||
</p>
|
||||
<page-customer-type-selector [(ngModel)]="type" (ngModelChange)="setType($event)"></page-customer-type-selector>
|
||||
<div class="router-outlet-wrapper">
|
||||
<form *ngIf="control" [formGroup]="control" (ngSubmit)="submit()">
|
||||
<ng-container formGroupName="organisation">
|
||||
<ui-form-control label="Firmenname" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="name" tabindex="1" />
|
||||
</ui-form-control>
|
||||
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Abteilung" [clearable]="false">
|
||||
<input uiInput type="text" formControlName="department" tabindex="2" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="USt-ID" [clearable]="false">
|
||||
<input uiInput type="text" formControlName="vatId" tabindex="3" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Anrede" [clearable]="false">
|
||||
<ui-select formControlName="gender" tabindex="4">
|
||||
<ui-select-option [value]="2" label="Herr"></ui-select-option>
|
||||
<ui-select-option [value]="4" label="Frau"></ui-select-option>
|
||||
</ui-select>
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Titel">
|
||||
<ui-select formControlName="title" tabindex="5">
|
||||
<ui-select-option value="Dr." label="Dr."></ui-select-option>
|
||||
<ui-select-option value="Prof." label="Prof."></ui-select-option>
|
||||
<ui-select-option value="Prof. Dr." label="Prof. Dr."></ui-select-option>
|
||||
</ui-select>
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Vorname" [clearable]="false">
|
||||
<input uiInput type="text" formControlName="firstName" tabindex="6" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Nachname" [clearable]="false">
|
||||
<input uiInput type="text" formControlName="lastName" tabindex="7" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<ng-container formGroupName="address">
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Straße" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="street" tabindex="8" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Hausnummer" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="streetNumber" tabindex="9" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<div class="control-row">
|
||||
<ui-form-control label="PLZ" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="zipCode" tabindex="10" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Ort" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="city" tabindex="11" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<ui-form-control label="Adresszusatz" [clearable]="false">
|
||||
<input uiInput type="text" formControlName="info" tabindex="12" />
|
||||
</ui-form-control>
|
||||
|
||||
<ui-form-control label="Land" [clearable]="false" requiredMark="*">
|
||||
<ui-select formControlName="country" tabindex="13">
|
||||
<ui-select-option
|
||||
*ngFor="let country of countries$ | async"
|
||||
[label]="country.name"
|
||||
[value]="country.isO3166_A_3"
|
||||
></ui-select-option>
|
||||
</ui-select>
|
||||
</ui-form-control>
|
||||
</ng-container>
|
||||
|
||||
<ng-container formGroupName="communicationDetails">
|
||||
<ui-form-control label="E-Mail" [clearable]="false">
|
||||
<input uiInput type="mail" formControlName="email" tabindex="14" />
|
||||
</ui-form-control>
|
||||
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Festnetznummer">
|
||||
<input uiInput type="tel" formControlName="phone" tabindex="15" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Mobilnummer" [clearable]="false">
|
||||
<input uiInput type="tel" formControlName="mobile" tabindex="16" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<div class="center">
|
||||
<button class="create-customer-submit" type="submit" [disabled]="control.invalid">Speichern</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,68 @@
|
||||
import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { CrmCustomerService } from '@domain/crm';
|
||||
import { UiModalService } from '@ui/modal';
|
||||
import { CustomerCreateComponentBase } from './customer-create.component';
|
||||
|
||||
@Component({
|
||||
selector: 'page-customer-create-b2b',
|
||||
templateUrl: 'customer-create-b2b.component.html',
|
||||
styleUrls: ['customer-create.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class CustomerCreateB2BComponent extends CustomerCreateComponentBase implements OnInit {
|
||||
constructor(
|
||||
public activatedRoute: ActivatedRoute,
|
||||
public router: Router,
|
||||
private fb: FormBuilder,
|
||||
public modal: UiModalService,
|
||||
public customerService: CrmCustomerService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.init();
|
||||
}
|
||||
|
||||
createControl(): FormGroup {
|
||||
const fb = this.fb;
|
||||
|
||||
return fb.group({
|
||||
organisation: fb.group({
|
||||
name: fb.control('', [Validators.required]),
|
||||
department: fb.control(''),
|
||||
vatId: fb.control(''),
|
||||
}),
|
||||
gender: fb.control(0),
|
||||
title: fb.control(''),
|
||||
firstName: fb.control(''),
|
||||
lastName: fb.control(''),
|
||||
address: fb.group({
|
||||
street: fb.control('', [Validators.required]),
|
||||
streetNumber: fb.control('', [Validators.required]),
|
||||
zipCode: fb.control('', [Validators.required]),
|
||||
city: fb.control('', [Validators.required]),
|
||||
info: fb.control(''),
|
||||
country: fb.control('DEU', [Validators.required]),
|
||||
}),
|
||||
communicationDetails: fb.group({
|
||||
email: fb.control(''),
|
||||
phone: fb.control(''),
|
||||
mobile: fb.control(''),
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
async submit(): Promise<void> {
|
||||
if (this.control.invalid) {
|
||||
return;
|
||||
}
|
||||
|
||||
let address = await this.validateAddress(this.control.value.address);
|
||||
if (address) {
|
||||
this.control.patchValue({ address });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<div class="card">
|
||||
<h1>Kundendaten erfassen</h1>
|
||||
<p>
|
||||
TEXT FÜR FILIALKUNDE(MINIMALKUNDE)
|
||||
</p>
|
||||
<page-customer-type-selector [(ngModel)]="type" (ngModelChange)="setType($event)"></page-customer-type-selector>
|
||||
|
||||
<div class="router-outlet-wrapper">
|
||||
<form *ngIf="control" [formGroup]="control" (ngSubmit)="submit()">
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Anrede">
|
||||
<ui-select formControlName="gender" tabindex="1">
|
||||
<ui-select-option [value]="2" label="Herr"></ui-select-option>
|
||||
<ui-select-option [value]="4" label="Frau"></ui-select-option>
|
||||
</ui-select>
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Titel">
|
||||
<ui-select formControlName="title" tabindex="2">
|
||||
<ui-select-option value="Dr." label="Dr."></ui-select-option>
|
||||
<ui-select-option value="Prof." label="Prof."></ui-select-option>
|
||||
<ui-select-option value="Prof. Dr." label="Prof. Dr."></ui-select-option>
|
||||
</ui-select>
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Vorname" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="firstName" tabindex="3" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Nachname" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="lastName" tabindex="4" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<ng-container formGroupName="communicationDetails">
|
||||
<ui-form-control label="E-Mail" [clearable]="false">
|
||||
<input uiInput type="mail" formControlName="email" tabindex="5" />
|
||||
</ui-form-control>
|
||||
</ng-container>
|
||||
|
||||
<ng-container formGroupName="organisation">
|
||||
<ui-form-control label="Firmenname">
|
||||
<input uiInput type="text" formControlName="name" tabindex="6" />
|
||||
</ui-form-control>
|
||||
</ng-container>
|
||||
|
||||
<ng-container formGroupName="address">
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Straße">
|
||||
<input uiInput type="text" formControlName="street" tabindex="7" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Hausnummer">
|
||||
<input uiInput type="text" formControlName="streetNumber" tabindex="8" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<div class="control-row">
|
||||
<ui-form-control label="PLZ">
|
||||
<input uiInput type="text" formControlName="zipCode" tabindex="9" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Ort">
|
||||
<input uiInput type="text" formControlName="city" tabindex="10" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<ui-form-control label="Land" [clearable]="false">
|
||||
<ui-select formControlName="country" tabindex="11">
|
||||
<ui-select-option
|
||||
*ngFor="let country of countries$ | async"
|
||||
[label]="country.name"
|
||||
[value]="country.isO3166_A_3"
|
||||
></ui-select-option>
|
||||
</ui-select>
|
||||
</ui-form-control>
|
||||
</ng-container>
|
||||
|
||||
<ng-container formGroupName="communicationDetails">
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Festnetznummer">
|
||||
<input uiInput type="tel" formControlName="phone" tabindex="12" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Mobilnummer" [clearable]="false">
|
||||
<input uiInput type="tel" formControlName="mobile" tabindex="13" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ui-form-control label="Geburtsdatum (TT.MM.JJJJ)">
|
||||
<input uiInput type="text" formControlName="dateOfBirth" tabindex="14" />
|
||||
</ui-form-control>
|
||||
|
||||
<div class="center">
|
||||
<button class="create-customer-submit" type="submit" [disabled]="control.invalid">Speichern</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,80 @@
|
||||
import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { CrmCustomerService } from '@domain/crm';
|
||||
import { CustomerDTO } from '@swagger/crm';
|
||||
import { UiModalService } from '@ui/modal';
|
||||
import { CustomerCreateGuestComponent } from './customer-create-guest.component';
|
||||
import { CustomerCreateComponentBase } from './customer-create.component';
|
||||
|
||||
@Component({
|
||||
selector: 'page-customer-create-branch',
|
||||
templateUrl: 'customer-create-branch.component.html',
|
||||
styleUrls: ['customer-create.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class CustomerCreateBranchComponent extends CustomerCreateComponentBase implements OnInit {
|
||||
constructor(
|
||||
public activatedRoute: ActivatedRoute,
|
||||
public router: Router,
|
||||
private fb: FormBuilder,
|
||||
public modal: UiModalService,
|
||||
public customerService: CrmCustomerService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
createControl(): FormGroup {
|
||||
const fb = this.fb;
|
||||
|
||||
return fb.group({
|
||||
organisation: fb.group({
|
||||
name: fb.control(''),
|
||||
}),
|
||||
gender: fb.control(0),
|
||||
title: fb.control(''),
|
||||
firstName: fb.control('', [Validators.required]),
|
||||
lastName: fb.control('', [Validators.required]),
|
||||
dateOfBirth: fb.control('', [CustomerCreateGuestComponent.dateOfBirthValidator]),
|
||||
address: fb.group({
|
||||
street: fb.control(''),
|
||||
streetNumber: fb.control(''),
|
||||
zipCode: fb.control(''),
|
||||
city: fb.control(''),
|
||||
country: fb.control('DEU'),
|
||||
}),
|
||||
communicationDetails: fb.group({
|
||||
email: fb.control(''),
|
||||
phone: fb.control(''),
|
||||
mobile: fb.control(''),
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
async submit(): Promise<void> {
|
||||
if (this.control.invalid) {
|
||||
return;
|
||||
}
|
||||
|
||||
let address = await this.validateAddress(this.control.value.address);
|
||||
if (address) {
|
||||
this.control.patchValue({ address });
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await this.customerService.createBranchCustomer(this.control.value).toPromise();
|
||||
|
||||
if (response.error) {
|
||||
throw new Error(response.message);
|
||||
} else {
|
||||
this.router.navigate(['/customer', response.result.id]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<div class="card">
|
||||
<h1>Kundendaten erfassen</h1>
|
||||
<p>
|
||||
Wenn Sie möchten legen wir Ihnen <br />
|
||||
gerne ein Onlinekonto an. Dort können <br />
|
||||
Sie Ihre Bestellungen einsehen.
|
||||
</p>
|
||||
<page-customer-type-selector [(ngModel)]="type" (ngModelChange)="setType($event)"></page-customer-type-selector>
|
||||
<div class="router-outlet-wrapper">
|
||||
<form *ngIf="control" [formGroup]="control" (ngSubmit)="submit()">
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Anrede" requiredMark="*">
|
||||
<ui-select formControlName="gender" tabindex="1">
|
||||
<ui-select-option [value]="2" label="Herr"></ui-select-option>
|
||||
<ui-select-option [value]="4" label="Frau"></ui-select-option>
|
||||
</ui-select>
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Titel">
|
||||
<ui-select formControlName="title" tabindex="2">
|
||||
<ui-select-option value="Dr." label="Dr."></ui-select-option>
|
||||
<ui-select-option value="Prof." label="Prof."></ui-select-option>
|
||||
<ui-select-option value="Prof. Dr." label="Prof. Dr."></ui-select-option>
|
||||
</ui-select>
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Vorname" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="firstName" tabindex="3" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Nachname" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="lastName" tabindex="4" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<p class="bold">
|
||||
Wir werden Ihnen Werbung zu ähnlichen Produkten oder Dienstleistungen aus unserem Sortiment per E-Mail zusenden. Sie können der
|
||||
Verwendung Ihrer Daten jederzeit z.B. mittels der in den E-Mails enthaltenen Abmeldelinks widersprechen, ohne dass hierfür andere
|
||||
als die Übermittlungskosten nach den Basistarifen entstehen.
|
||||
</p>
|
||||
|
||||
<ng-container formGroupName="communicationDetails">
|
||||
<ui-form-control label="E-Mail" requiredMark="*">
|
||||
<input uiInput type="mail" formControlName="email" tabindex="5" />
|
||||
</ui-form-control>
|
||||
</ng-container>
|
||||
|
||||
<ng-container formGroupName="organisation">
|
||||
<ui-form-control label="Firmenname">
|
||||
<input uiInput type="text" formControlName="name" tabindex="6" />
|
||||
</ui-form-control>
|
||||
</ng-container>
|
||||
|
||||
<ng-container formGroupName="address">
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Straße" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="street" tabindex="7" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Hausnummer" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="streetNumber" tabindex="8" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<div class="control-row">
|
||||
<ui-form-control label="PLZ" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="zipCode" tabindex="9" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Ort" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="city" tabindex="10" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<ui-form-control label="Land" requiredMark="*">
|
||||
<ui-select formControlName="country" tabindex="11">
|
||||
<ui-select-option
|
||||
*ngFor="let country of countries$ | async"
|
||||
[label]="country.name"
|
||||
[value]="country.isO3166_A_3"
|
||||
></ui-select-option>
|
||||
</ui-select>
|
||||
</ui-form-control>
|
||||
</ng-container>
|
||||
|
||||
<ng-container formGroupName="communicationDetails">
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Festnetznummer">
|
||||
<input uiInput type="tel" formControlName="phone" tabindex="12" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Mobilnummer" [clearable]="false">
|
||||
<input uiInput type="tel" formControlName="mobile" tabindex="13" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ui-form-control label="Geburtsdatum (TT.MM.JJJJ)">
|
||||
<input type="text" formControlName="dateOfBirth" pagesDateOfBirth tabindex="14" />
|
||||
</ui-form-control>
|
||||
|
||||
<div class="center">
|
||||
<button class="create-customer-submit" type="submit" [disabled]="control.invalid">Speichern</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,78 @@
|
||||
import { Component, ChangeDetectionStrategy, OnInit, ChangeDetectorRef } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { CrmCustomerService } from '@domain/crm';
|
||||
import { UiModalService } from '@ui/modal';
|
||||
import { CustomerCreateComponentBase } from './customer-create.component';
|
||||
|
||||
@Component({
|
||||
selector: 'page-customer-create-guest',
|
||||
templateUrl: 'customer-create-guest.component.html',
|
||||
styleUrls: ['customer-create.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class CustomerCreateGuestComponent extends CustomerCreateComponentBase implements OnInit {
|
||||
constructor(
|
||||
public activatedRoute: ActivatedRoute,
|
||||
public router: Router,
|
||||
private fb: FormBuilder,
|
||||
public modal: UiModalService,
|
||||
public customerService: CrmCustomerService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.init();
|
||||
}
|
||||
|
||||
createControl(): FormGroup {
|
||||
const { fb } = this;
|
||||
|
||||
return fb.group({
|
||||
organisation: fb.group({
|
||||
name: fb.control(''),
|
||||
}),
|
||||
gender: fb.control(0, [Validators.required]),
|
||||
title: fb.control(''),
|
||||
firstName: fb.control('', [Validators.required]),
|
||||
lastName: fb.control('', [Validators.required]),
|
||||
dateOfBirth: fb.control('', [CustomerCreateGuestComponent.dateOfBirthValidator]),
|
||||
address: fb.group({
|
||||
street: fb.control('', [Validators.required]),
|
||||
streetNumber: fb.control('', [Validators.required]),
|
||||
zipCode: fb.control('', [Validators.required]),
|
||||
city: fb.control('', [Validators.required]),
|
||||
country: fb.control('DEU', [Validators.required]),
|
||||
}),
|
||||
communicationDetails: fb.group({
|
||||
email: fb.control('', [Validators.required, Validators.email]),
|
||||
phone: fb.control(''),
|
||||
mobile: fb.control(''),
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
async submit(): Promise<void> {
|
||||
if (this.control.invalid) {
|
||||
return;
|
||||
}
|
||||
|
||||
let address = await this.validateAddress(this.control.value.address);
|
||||
if (address) {
|
||||
this.control.patchValue({ address });
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await this.customerService.createGuestCustomer(this.control.value).toPromise();
|
||||
|
||||
if (response.error) {
|
||||
throw new Error(response.message);
|
||||
} else {
|
||||
this.router.navigate(['/customer', response.result.id]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<div class="card">
|
||||
<h1>Kundendaten erfassen</h1>
|
||||
<p>
|
||||
Wenn Sie möchten legen wir Ihnen <br />
|
||||
gerne ein Onlinekonto an. Dort können <br />
|
||||
Sie Ihre Bestellungen einsehen.
|
||||
</p>
|
||||
<page-customer-type-selector [(ngModel)]="type" (ngModelChange)="setType($event)"></page-customer-type-selector>
|
||||
|
||||
<div class="router-outlet-wrapper">
|
||||
<form *ngIf="control" [formGroup]="control">
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Anrede" requiredMark="*">
|
||||
<ui-select formControlName="gender" tabindex="1">
|
||||
<ui-select-option [value]="2" label="Herr"></ui-select-option>
|
||||
<ui-select-option [value]="4" label="Frau"></ui-select-option>
|
||||
</ui-select>
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Titel">
|
||||
<ui-select formControlName="title" tabindex="2">
|
||||
<ui-select-option value="Dr." label="Dr."></ui-select-option>
|
||||
<ui-select-option value="Prof." label="Prof."></ui-select-option>
|
||||
<ui-select-option value="Prof. Dr." label="Prof. Dr."></ui-select-option>
|
||||
</ui-select>
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Vorname" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="firstName" tabindex="3" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Nachname" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="lastName" tabindex="4" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<ng-container formGroupName="communicationDetails">
|
||||
<ui-form-control label="E-Mail" requiredMark="*">
|
||||
<input uiInput type="mail" formControlName="email" tabindex="5" />
|
||||
</ui-form-control>
|
||||
</ng-container>
|
||||
|
||||
<ng-container formGroupName="organisation">
|
||||
<ui-form-control label="Firmenname">
|
||||
<input uiInput type="text" formControlName="name" tabindex="6" />
|
||||
</ui-form-control>
|
||||
</ng-container>
|
||||
|
||||
<ng-container formGroupName="address">
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Straße" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="street" tabindex="7" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Hausnummer" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="streetNumber" tabindex="8" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<div class="control-row">
|
||||
<ui-form-control label="PLZ" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="zipCode" tabindex="9" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Ort" requiredMark="*">
|
||||
<input uiInput type="text" formControlName="city" tabindex="10" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
|
||||
<ui-form-control label="Land" [clearable]="false" requiredMark="*">
|
||||
<ui-select formControlName="country" tabindex="11">
|
||||
<ui-select-option
|
||||
*ngFor="let country of countries$ | async"
|
||||
[label]="country.name"
|
||||
[value]="country.isO3166_A_3"
|
||||
></ui-select-option>
|
||||
</ui-select>
|
||||
</ui-form-control>
|
||||
</ng-container>
|
||||
|
||||
<p class="bold">Das Anlegen geht für Sie noch schneller, wenn wir Ihnen das initiale Passwort per SMS auf Ihr Mobilgerät schicken.</p>
|
||||
|
||||
<ng-container formGroupName="communicationDetails">
|
||||
<div class="control-row">
|
||||
<ui-form-control label="Festnetznummer">
|
||||
<input uiInput type="tel" formControlName="phone" tabindex="12" />
|
||||
</ui-form-control>
|
||||
<ui-form-control label="Mobilnummer" [clearable]="false">
|
||||
<input uiInput type="tel" formControlName="mobile" tabindex="13" />
|
||||
</ui-form-control>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ui-form-control label="Geburtsdatum (TT.MM.JJJJ)">
|
||||
<input pagesDateOfBirth type="text" formControlName="dateOfBirth" tabindex="14" />
|
||||
</ui-form-control>
|
||||
|
||||
<div class="center">
|
||||
<button class="create-customer-submit" type="submit" [disabled]="control.invalid">Speichern</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,77 @@
|
||||
import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { CrmCustomerService } from '@domain/crm';
|
||||
import { UiModalService } from '@ui/modal';
|
||||
import { CustomerCreateComponentBase } from './customer-create.component';
|
||||
|
||||
@Component({
|
||||
selector: 'customer-create-online',
|
||||
templateUrl: 'customer-create-online.component.html',
|
||||
styleUrls: ['customer-create.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class CustomerCreateOnlineComponent extends CustomerCreateComponentBase implements OnInit {
|
||||
constructor(
|
||||
public activatedRoute: ActivatedRoute,
|
||||
public router: Router,
|
||||
private fb: FormBuilder,
|
||||
public modal: UiModalService,
|
||||
public customerService: CrmCustomerService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.init();
|
||||
}
|
||||
|
||||
createControl(): FormGroup {
|
||||
const { fb } = this;
|
||||
|
||||
return fb.group({
|
||||
organisation: fb.group({
|
||||
name: fb.control(''),
|
||||
}),
|
||||
gender: fb.control(0, [Validators.required]),
|
||||
title: fb.control(''),
|
||||
firstName: fb.control('', [Validators.required]),
|
||||
lastName: fb.control('', [Validators.required]),
|
||||
dateOfBirth: fb.control('', [CustomerCreateComponentBase.dateOfBirthValidator]),
|
||||
address: fb.group({
|
||||
street: fb.control('', [Validators.required]),
|
||||
streetNumber: fb.control('', [Validators.required]),
|
||||
zipCode: fb.control('', [Validators.required]),
|
||||
city: fb.control('', [Validators.required]),
|
||||
country: fb.control('DEU', [Validators.required]),
|
||||
}),
|
||||
communicationDetails: fb.group({
|
||||
email: fb.control('', [Validators.required, Validators.email], [this.emailExistsValidator]),
|
||||
phone: fb.control(''),
|
||||
mobile: fb.control(''),
|
||||
}),
|
||||
});
|
||||
}
|
||||
async submit(): Promise<void> {
|
||||
if (this.control.invalid) {
|
||||
return;
|
||||
}
|
||||
|
||||
let address = await this.validateAddress(this.control.value.address);
|
||||
if (address) {
|
||||
this.control.patchValue({ address });
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await this.customerService.createOnlineCustomer(this.control.value).toPromise();
|
||||
|
||||
if (response.error) {
|
||||
throw new Error(response.message);
|
||||
} else {
|
||||
this.router.navigate(['/customer', response.result.id]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
<div class="card">
|
||||
<h1>Kundendaten erfassen</h1>
|
||||
<p>
|
||||
Für eine B2B Bestellung benötigen Sie <br />
|
||||
einen Firmenaccount. Wir legen diesen <br />
|
||||
gerne direkt für Sie an.
|
||||
</p>
|
||||
|
||||
<page-customer-type-selector [(ngModel)]="type" (ngModelChange)="setType($event)"></page-customer-type-selector>
|
||||
|
||||
<div class="router-outlet-wrapper">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
</div>
|
||||
@@ -30,4 +30,32 @@ page-customer-type-selector {
|
||||
.router-outlet-wrapper {
|
||||
max-width: 650px;
|
||||
@apply mx-auto;
|
||||
|
||||
p {
|
||||
@apply text-regular mt-8;
|
||||
}
|
||||
}
|
||||
|
||||
.control-row {
|
||||
@apply flex flex-row gap-8;
|
||||
|
||||
ui-form-control {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
@apply text-center;
|
||||
}
|
||||
|
||||
.create-customer-submit {
|
||||
@apply border-none outline-none bg-brand text-white font-bold text-cta-l px-px-25 py-px-15 rounded-full my-8;
|
||||
|
||||
&:disabled {
|
||||
@apply bg-inactive-branch;
|
||||
}
|
||||
}
|
||||
|
||||
.bold {
|
||||
@apply font-semibold;
|
||||
}
|
||||
|
||||
@@ -1,26 +1,83 @@
|
||||
import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core';
|
||||
import { AsyncValidatorFn, FormGroup, ValidationErrors, ValidatorFn } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { CrmCustomerService } from '@domain/crm';
|
||||
import { AddressDTO, CountryDTO } from '@swagger/crm';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { UiModalService } from '@ui/modal';
|
||||
import { AddressSelectionModalComponent } from '../modals/address-selection-modal.component';
|
||||
|
||||
export abstract class CustomerCreateComponentBase {
|
||||
static dateOfBirthValidator: ValidatorFn = (control): ValidationErrors | null => {
|
||||
if (control.value) {
|
||||
const match = /^(\d{4})(-(\d{2})){2}T((\d{2})(:|.)){3}(\d{3})Z$/g.test(control.value);
|
||||
if (!match) {
|
||||
return { dateOfBirth: 'Geburtsdatum ist ungültig' };
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
emailExistsValidator: AsyncValidatorFn = async (control): Promise<ValidationErrors | null> => {
|
||||
if (control.value) {
|
||||
if ((await this.customerService.emailExists(control.value).toPromise())?.result) {
|
||||
return { exists: 'E-Mail existiert bereits' };
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
@Component({
|
||||
selector: 'page-customer-create',
|
||||
templateUrl: 'customer-create.component.html',
|
||||
styleUrls: ['customer-create.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class CustomerCreateComponent implements OnInit {
|
||||
type: string;
|
||||
control: FormGroup;
|
||||
|
||||
constructor(private activatedRoute: ActivatedRoute, private router: Router) {}
|
||||
countries$: Observable<CountryDTO[]>;
|
||||
|
||||
ngOnInit() {
|
||||
this.type = this.activatedRoute.snapshot.queryParams.type || 'guest';
|
||||
abstract activatedRoute: ActivatedRoute;
|
||||
abstract router: Router;
|
||||
abstract modal: UiModalService;
|
||||
abstract customerService: CrmCustomerService;
|
||||
|
||||
init() {
|
||||
this.type = this.activatedRoute.snapshot?.routeConfig?.path;
|
||||
this.control = this.createControl();
|
||||
|
||||
this.countries$ = this.customerService.getCountries().pipe(map((response) => response.result));
|
||||
}
|
||||
|
||||
setType(type: string) {
|
||||
this.router.navigate(['./', type], {
|
||||
this.router.navigate(['../', type], {
|
||||
relativeTo: this.activatedRoute,
|
||||
});
|
||||
}
|
||||
|
||||
abstract createControl(): FormGroup;
|
||||
|
||||
abstract submit(): Promise<void>;
|
||||
|
||||
async validateAddress(address: AddressDTO): Promise<AddressDTO> {
|
||||
if (address.street && address.streetNumber && address.zipCode && address.city && address.country) {
|
||||
try {
|
||||
let addresses = await this.customerService
|
||||
.validateAddress(address)
|
||||
.pipe(
|
||||
map((response) =>
|
||||
response.result.map((ad) => ({
|
||||
...address,
|
||||
...ad,
|
||||
}))
|
||||
)
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
if (addresses?.length > 0) {
|
||||
const modalResult = await this.modal.open({ content: AddressSelectionModalComponent, data: addresses }).afterClosed$.toPromise();
|
||||
if (modalResult?.data) {
|
||||
return modalResult.data;
|
||||
}
|
||||
}
|
||||
} catch (error) {}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,38 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { CustomerCreateComponent } from './customer-create.component';
|
||||
import { CustomerTypeSelectorComponent } from './customer-type-selector/customer-type-selector.component';
|
||||
import { UiFormControlModule } from '@ui/form-control';
|
||||
import { UiInputModule } from '@ui/input';
|
||||
import { CreateB2BComponent } from './create-b2b-form/create-b2b-form.component';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { UiSelectModule } from '@ui/select';
|
||||
import { CustomerCreateBranchComponent } from './customer-create-branch.component';
|
||||
import { CustomerCreateGuestComponent } from './customer-create-guest.component';
|
||||
import { CustomerCreateOnlineComponent } from './customer-create-online.component';
|
||||
import { CustomerCreateB2BComponent } from './customer-create-b2b.component';
|
||||
import { DateOfBirthValueAccessorDirective } from './value-accessors/json-date.value-accessor';
|
||||
import { AddressSelectionModalModule } from '../modals/address-selection-modal.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, UiFormControlModule, UiInputModule, FormsModule, ReactiveFormsModule, RouterModule, UiSelectModule],
|
||||
exports: [CustomerCreateComponent, CreateB2BComponent],
|
||||
declarations: [CustomerCreateComponent, CustomerTypeSelectorComponent, CreateB2BComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
UiFormControlModule,
|
||||
UiInputModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
RouterModule,
|
||||
UiSelectModule,
|
||||
AddressSelectionModalModule,
|
||||
],
|
||||
exports: [CustomerCreateBranchComponent, CustomerCreateGuestComponent, CustomerCreateOnlineComponent, CustomerCreateB2BComponent],
|
||||
declarations: [
|
||||
CustomerCreateBranchComponent,
|
||||
CustomerTypeSelectorComponent,
|
||||
CustomerCreateGuestComponent,
|
||||
CustomerCreateOnlineComponent,
|
||||
CustomerCreateB2BComponent,
|
||||
DateOfBirthValueAccessorDirective,
|
||||
],
|
||||
})
|
||||
export class CustomerCreateModule {}
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
import { Directive, ElementRef, forwardRef, HostBinding, HostListener, Input, Renderer2 } from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { UiFormControlDirective } from '@ui/form-control';
|
||||
|
||||
@Directive({
|
||||
selector: 'input[pagesDateOfBirth]',
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: forwardRef(() => DateOfBirthValueAccessorDirective),
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
provide: UiFormControlDirective,
|
||||
useExisting: DateOfBirthValueAccessorDirective,
|
||||
},
|
||||
],
|
||||
})
|
||||
export class DateOfBirthValueAccessorDirective extends UiFormControlDirective<any> implements ControlValueAccessor {
|
||||
@Input()
|
||||
@HostBinding('attr.type')
|
||||
type: string;
|
||||
|
||||
get valueEmpty(): boolean {
|
||||
return !!this.value;
|
||||
}
|
||||
|
||||
readonly today = new Date();
|
||||
|
||||
value: string;
|
||||
|
||||
private onChange = (_: any) => {};
|
||||
private onTouched = () => {};
|
||||
|
||||
constructor(private elementRef: ElementRef, private renderer: Renderer2) {
|
||||
super();
|
||||
}
|
||||
|
||||
writeValue(obj: string | Date): void {
|
||||
this.setValue(obj, false);
|
||||
this.renderInputValue();
|
||||
}
|
||||
|
||||
registerOnChange(fn: any): void {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: any): void {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
|
||||
@HostListener('keyup', ['$event.target.value'])
|
||||
setValue(value: string | Date, emitEvent = true) {
|
||||
if (value instanceof Date) {
|
||||
this.value = this.format(value);
|
||||
} else {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
if (emitEvent) {
|
||||
const dateStruct = this.getDateStruct(this.value);
|
||||
|
||||
if (dateStruct) {
|
||||
this.onChange(this.parseDateStruct(dateStruct).toJSON());
|
||||
} else {
|
||||
this.onChange(this.value);
|
||||
}
|
||||
}
|
||||
|
||||
this.onTouched();
|
||||
}
|
||||
|
||||
getDateStruct(stringDate: string): { date: number; month: number; year: number } | undefined {
|
||||
if (!!stringDate) {
|
||||
const parts = stringDate.trim().split('.');
|
||||
if (parts.length === 3) {
|
||||
const date = +parts[0];
|
||||
const month = +parts[1];
|
||||
const year = +parts[2];
|
||||
|
||||
if (date >= 1 && date <= 31 && month >= 1 && month <= 12 && year >= 1900 && year <= this.today.getFullYear()) {
|
||||
return { date, month, year };
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
parseDateStruct({ year, month, date }: { date: number; month: number; year: number }) {
|
||||
return new Date(year, month - 1, date);
|
||||
}
|
||||
|
||||
format(date: Date): string {
|
||||
if (date) {
|
||||
return `${date.getDate()}.${date.getMonth() + 1},${date.getFullYear()}`;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
renderInputValue() {
|
||||
this.renderer.setAttribute(this.elementRef.nativeElement, 'value', this.value);
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
this.setValue(undefined);
|
||||
this.renderInputValue();
|
||||
}
|
||||
|
||||
focus(): void {
|
||||
setTimeout(() => {
|
||||
this.elementRef?.nativeElement?.click()?.focus();
|
||||
}, 0);
|
||||
}
|
||||
|
||||
@HostListener('focus')
|
||||
onFocus() {
|
||||
this.focused.emit(true);
|
||||
}
|
||||
|
||||
@HostListener('blur')
|
||||
onBlur() {
|
||||
this.onTouched();
|
||||
this.focused.emit(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<div class="wrapper">
|
||||
<div class="actions">
|
||||
<button class="close-btn" (click)="ref.close()">
|
||||
<ui-icon icon="close" size="21px"></ui-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h2>Bitte überprüfen Sie die eingegebenen Adressdaten</h2>
|
||||
<p>Vorschläge:</p>
|
||||
|
||||
<ul class="content">
|
||||
<li *ngFor="let item of ref?.data">
|
||||
<span>{{ item.street }} {{ item.streetNumber }}, {{ item.zipCode }} {{ item.city }}</span>
|
||||
<button (click)="ref.close(item)">Übernehmen</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="center">
|
||||
<button class="select-btn" (click)="ref.close()">Eingegebene Adresse übernehmen</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,44 @@
|
||||
:host {
|
||||
@apply bg-white;
|
||||
}
|
||||
|
||||
.actions {
|
||||
@apply flex flex-row justify-end;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
@apply bg-transparent border-none text-ucla-blue;
|
||||
}
|
||||
|
||||
h2,
|
||||
p {
|
||||
@apply text-center text-regular;
|
||||
}
|
||||
|
||||
h2 {
|
||||
@apply font-bold text-card-sub;
|
||||
}
|
||||
|
||||
ul {
|
||||
@apply list-none text-regular -mx-4 p-0 mt-px-35;
|
||||
|
||||
li {
|
||||
@apply flex flex-row items-center justify-between border-glitter border-t-4 border-b-0 border-solid border-r-0 border-l-0 py-px-15 px-px-25;
|
||||
|
||||
&:last-child {
|
||||
@apply border-b-4;
|
||||
}
|
||||
|
||||
button {
|
||||
@apply border-none outline-none bg-transparent text-brand text-cta-l text-right font-bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
@apply text-center;
|
||||
}
|
||||
|
||||
.select-btn {
|
||||
@apply border-none outline-none bg-brand text-white font-bold text-cta-l px-px-25 py-px-15 rounded-full my-8;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { AddressDTO } from '@swagger/crm';
|
||||
import { UiModalRef } from 'apps/ui/modal/src/lib/defs';
|
||||
|
||||
@Component({
|
||||
selector: 'page-address-selection-modal',
|
||||
templateUrl: 'address-selection-modal.component.html',
|
||||
styleUrls: ['address-selection-modal.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AddressSelectionModalComponent {
|
||||
constructor(public ref: UiModalRef<AddressDTO[]>) {}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { AddressSelectionModalComponent } from './address-selection-modal.component';
|
||||
import { UiIconModule } from '@ui/icon';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, UiIconModule],
|
||||
exports: [AddressSelectionModalComponent],
|
||||
declarations: [AddressSelectionModalComponent],
|
||||
})
|
||||
export class AddressSelectionModalModule {}
|
||||
@@ -1,7 +1,9 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { CreateB2BComponent } from './customer-create/create-b2b-form/create-b2b-form.component';
|
||||
import { CustomerCreateComponent } from './customer-create/customer-create.component';
|
||||
import { CustomerCreateB2BComponent } from './customer-create/customer-create-b2b.component';
|
||||
import { CustomerCreateBranchComponent } from './customer-create/customer-create-branch.component';
|
||||
import { CustomerCreateGuestComponent } from './customer-create/customer-create-guest.component';
|
||||
import { CustomerCreateOnlineComponent } from './customer-create/customer-create-online.component';
|
||||
import { CustomerDetailsComponent } from './customer-details/customer-details.component';
|
||||
import { CustomerSearchComponent } from './customer-search/customer-search.component';
|
||||
import { CustomerSearchMainComponent } from './customer-search/search-main/search-main.component';
|
||||
@@ -24,11 +26,12 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
component: CustomerCreateComponent,
|
||||
children: [
|
||||
{ path: 'guest', component: CreateB2BComponent },
|
||||
{ path: 'online', component: CreateB2BComponent },
|
||||
{ path: 'b2b', component: CreateB2BComponent },
|
||||
{ path: 'branch', component: CustomerCreateBranchComponent },
|
||||
{ path: 'online', component: CustomerCreateOnlineComponent },
|
||||
{ path: 'b2b', component: CustomerCreateB2BComponent },
|
||||
{ path: 'guest', component: CustomerCreateGuestComponent },
|
||||
{ path: '', pathMatch: 'full', redirectTo: 'branch' },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
<shell-breadcrumb [key]="application.activatedProcessId$ | async"></shell-breadcrumb>
|
||||
|
||||
<router-outlet></router-outlet>
|
||||
<div class="content-container">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
|
||||
@@ -2,3 +2,8 @@ shell-breadcrumb {
|
||||
margin-top: -5px;
|
||||
@apply mb-px-10 pb-px-10;
|
||||
}
|
||||
|
||||
.content-container {
|
||||
max-height: calc(100vh - 267px);
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ import { OverlaysModule } from './core/overlay/overlays.module';
|
||||
import { DateAdapter, NativeDateAdapter } from '@isa-ui/core/date';
|
||||
import { CoreBreadcrumbModule } from '@core/breadcrumb';
|
||||
import { CoreApplicationModule } from '@core/application';
|
||||
import { UiModalModule } from '@ui/modal';
|
||||
registerLocaleData(localeDe, localeDeExtra);
|
||||
registerLocaleData(localeDe, 'de', localeDeExtra);
|
||||
|
||||
@@ -123,6 +124,11 @@ export function remissionModuleOptionsFactory(config: AppConfiguration): Remissi
|
||||
*/
|
||||
CoreBreadcrumbModule.forRoot(),
|
||||
CoreApplicationModule.forRoot(),
|
||||
|
||||
/**
|
||||
* @ui Modules
|
||||
*/
|
||||
UiModalModule.forRoot(),
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
|
||||
@@ -6,10 +6,21 @@ export { LesepunkteRequest } from './models/lesepunkte-request';
|
||||
export { ListResponseArgsOfItemDTO } from './models/list-response-args-of-item-dto';
|
||||
export { ResponseArgsOfIEnumerableOfItemDTO } from './models/response-args-of-ienumerable-of-item-dto';
|
||||
export { ItemDTO } from './models/item-dto';
|
||||
export { ItemType } from './models/item-type';
|
||||
export { ProductDTO } from './models/product-dto';
|
||||
export { SizeOfString } from './models/size-of-string';
|
||||
export { WeightOfAvoirdupois } from './models/weight-of-avoirdupois';
|
||||
export { Avoirdupois } from './models/avoirdupois';
|
||||
export { SpecDTO } from './models/spec-dto';
|
||||
export { TextDTO } from './models/text-dto';
|
||||
export { ImageDTO } from './models/image-dto';
|
||||
export { AvailabilityDTO } from './models/availability-dto';
|
||||
export { ShopDTO } from './models/shop-dto';
|
||||
export { PriceDTO } from './models/price-dto';
|
||||
export { PriceValueDTO } from './models/price-value-dto';
|
||||
export { VATValueDTO } from './models/vatvalue-dto';
|
||||
export { VATType } from './models/vattype';
|
||||
export { AvailabilityType } from './models/availability-type';
|
||||
export { StockInfoDTO } from './models/stock-info-dto';
|
||||
export { ShelfInfoDTO } from './models/shelf-info-dto';
|
||||
export { KeyValueDTOOfStringAndString } from './models/key-value-dtoof-string-and-string';
|
||||
@@ -17,6 +28,7 @@ export { ReviewDTO } from './models/review-dto';
|
||||
export { EntityDTO } from './models/entity-dto';
|
||||
export { EntityStatus } from './models/entity-status';
|
||||
export { QueryTokenDTO } from './models/query-token-dto';
|
||||
export { CatalogType } from './models/catalog-type';
|
||||
export { OrderByDTO } from './models/order-by-dto';
|
||||
export { ListResponseArgsOfAutocompleteDTO } from './models/list-response-args-of-autocomplete-dto';
|
||||
export { ResponseArgsOfIEnumerableOfAutocompleteDTO } from './models/response-args-of-ienumerable-of-autocomplete-dto';
|
||||
@@ -27,6 +39,9 @@ export { ResponseArgsOfUISettingsDTO } from './models/response-args-of-uisetting
|
||||
export { UISettingsDTO } from './models/uisettings-dto';
|
||||
export { InputGroupDTO } from './models/input-group-dto';
|
||||
export { InputDTO } from './models/input-dto';
|
||||
export { InputType } from './models/input-type';
|
||||
export { InputOptionsDTO } from './models/input-options-dto';
|
||||
export { OptionDTO } from './models/option-dto';
|
||||
export { TranslationDTO } from './models/translation-dto';
|
||||
export { ResponseArgsOfIEnumerableOfQueryTokenDTO } from './models/response-args-of-ienumerable-of-query-token-dto';
|
||||
export { ResponseArgsOfIEnumerableOfStockInfoDTO } from './models/response-args-of-ienumerable-of-stock-info-dto';
|
||||
|
||||
@@ -5,16 +5,16 @@
|
||||
*/
|
||||
export interface AvailabilityDTO {
|
||||
|
||||
/**
|
||||
* Stock Status Code / Beschreibung
|
||||
*/
|
||||
sscText?: string;
|
||||
|
||||
/**
|
||||
* Produkt / Artikel PK
|
||||
*/
|
||||
itemId?: number;
|
||||
|
||||
/**
|
||||
* Shop
|
||||
*/
|
||||
shop?: any;
|
||||
|
||||
/**
|
||||
* Preis (VK)
|
||||
*/
|
||||
@@ -31,9 +31,9 @@ export interface AvailabilityDTO {
|
||||
ssc?: string;
|
||||
|
||||
/**
|
||||
* Shop
|
||||
* Stock Status Code / Beschreibung
|
||||
*/
|
||||
shop?: any;
|
||||
sscText?: string;
|
||||
|
||||
/**
|
||||
* Verfügbare Menge
|
||||
|
||||
2
apps/swagger/cat/src/lib/models/availability-type.ts
Normal file
2
apps/swagger/cat/src/lib/models/availability-type.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
/* tslint:disable */
|
||||
export type AvailabilityType = 0 | 1 | 2 | 32 | 256 | 1024 | 2048 | 4096 | 8192 | 16384;
|
||||
2
apps/swagger/cat/src/lib/models/avoirdupois.ts
Normal file
2
apps/swagger/cat/src/lib/models/avoirdupois.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
/* tslint:disable */
|
||||
export type Avoirdupois = 0 | 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096;
|
||||
6
apps/swagger/cat/src/lib/models/catalog-type.ts
Normal file
6
apps/swagger/cat/src/lib/models/catalog-type.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/* tslint:disable */
|
||||
|
||||
/**
|
||||
* Katalogbereich
|
||||
*/
|
||||
export type CatalogType = 0 | 1 | 2 | 4;
|
||||
18
apps/swagger/cat/src/lib/models/input-options-dto.ts
Normal file
18
apps/swagger/cat/src/lib/models/input-options-dto.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/* tslint:disable */
|
||||
import { OptionDTO } from './option-dto';
|
||||
|
||||
/**
|
||||
* Auswahl
|
||||
*/
|
||||
export interface InputOptionsDTO {
|
||||
|
||||
/**
|
||||
* Maximale Anzahl auswählbarer Elemente (null => alle, 1 = single select)
|
||||
*/
|
||||
max?: number;
|
||||
|
||||
/**
|
||||
* Werte
|
||||
*/
|
||||
values?: Array<OptionDTO>;
|
||||
}
|
||||
6
apps/swagger/cat/src/lib/models/input-type.ts
Normal file
6
apps/swagger/cat/src/lib/models/input-type.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/* tslint:disable */
|
||||
|
||||
/**
|
||||
* Art des Eingabewerts
|
||||
*/
|
||||
export type InputType = 0 | 1 | 2 | 4 | 8 | 16 | 32 | 64 | 96;
|
||||
@@ -10,16 +10,16 @@ import { KeyValueDTOOfStringAndString } from './key-value-dtoof-string-and-strin
|
||||
import { ReviewDTO } from './review-dto';
|
||||
export interface ItemDTO extends EntityDTO {
|
||||
|
||||
/**
|
||||
* Verfügbarkeit laut Katalog
|
||||
*/
|
||||
catalogAvailability?: any;
|
||||
|
||||
/**
|
||||
* Rang
|
||||
*/
|
||||
scoring?: number;
|
||||
|
||||
/**
|
||||
* Weitere Artikel-IDs
|
||||
*/
|
||||
ids?: {[key: string]: number};
|
||||
|
||||
/**
|
||||
* Artikel / Produkttyp
|
||||
*/
|
||||
@@ -56,9 +56,9 @@ export interface ItemDTO extends EntityDTO {
|
||||
images?: Array<ImageDTO>;
|
||||
|
||||
/**
|
||||
* Weitere Artikel-IDs
|
||||
* Verfügbarkeit laut Katalog
|
||||
*/
|
||||
ids?: {[key: string]: number};
|
||||
catalogAvailability?: any;
|
||||
|
||||
/**
|
||||
* Verfügbarkeit zur Bestellung in die Filiale
|
||||
|
||||
2
apps/swagger/cat/src/lib/models/item-type.ts
Normal file
2
apps/swagger/cat/src/lib/models/item-type.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
/* tslint:disable */
|
||||
export type ItemType = 0 | 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 | 8192 | 16384 | 32768;
|
||||
@@ -1,8 +1,11 @@
|
||||
/* tslint:disable */
|
||||
export interface KeyValueDTOOfStringAndString {
|
||||
enabled?: boolean;
|
||||
label?: string;
|
||||
key?: string;
|
||||
value?: string;
|
||||
selected?: boolean;
|
||||
description?: string;
|
||||
sort?: number;
|
||||
command?: string;
|
||||
}
|
||||
|
||||
27
apps/swagger/cat/src/lib/models/option-dto.ts
Normal file
27
apps/swagger/cat/src/lib/models/option-dto.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
/* tslint:disable */
|
||||
|
||||
/**
|
||||
* Auswahlelement
|
||||
*/
|
||||
export interface OptionDTO {
|
||||
|
||||
/**
|
||||
* Key / ID
|
||||
*/
|
||||
key?: string;
|
||||
|
||||
/**
|
||||
* Label
|
||||
*/
|
||||
label?: string;
|
||||
|
||||
/**
|
||||
* Wert
|
||||
*/
|
||||
value?: string;
|
||||
|
||||
/**
|
||||
* Unter-Optionen
|
||||
*/
|
||||
values?: Array<OptionDTO>;
|
||||
}
|
||||
7
apps/swagger/cat/src/lib/models/price-dto.ts
Normal file
7
apps/swagger/cat/src/lib/models/price-dto.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
/* tslint:disable */
|
||||
import { PriceValueDTO } from './price-value-dto';
|
||||
import { VATValueDTO } from './vatvalue-dto';
|
||||
export interface PriceDTO {
|
||||
value?: PriceValueDTO;
|
||||
vat?: VATValueDTO;
|
||||
}
|
||||
6
apps/swagger/cat/src/lib/models/price-value-dto.ts
Normal file
6
apps/swagger/cat/src/lib/models/price-value-dto.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/* tslint:disable */
|
||||
export interface PriceValueDTO {
|
||||
value?: number;
|
||||
currency?: string;
|
||||
currencySymbol?: string;
|
||||
}
|
||||
22
apps/swagger/cat/src/lib/models/product-dto.ts
Normal file
22
apps/swagger/cat/src/lib/models/product-dto.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
/* tslint:disable */
|
||||
import { SizeOfString } from './size-of-string';
|
||||
import { WeightOfAvoirdupois } from './weight-of-avoirdupois';
|
||||
export interface ProductDTO {
|
||||
name?: string;
|
||||
additionalName?: string;
|
||||
ean?: string;
|
||||
supplierProductNumber?: string;
|
||||
catalogProductNumber?: string;
|
||||
contributors?: string;
|
||||
manufacturer?: string;
|
||||
publicationDate?: string;
|
||||
productGroup?: string;
|
||||
edition?: string;
|
||||
volume?: string;
|
||||
serial?: string;
|
||||
format?: string;
|
||||
formatDetail?: string;
|
||||
locale?: string;
|
||||
size?: SizeOfString;
|
||||
weight?: WeightOfAvoirdupois;
|
||||
}
|
||||
@@ -6,16 +6,16 @@ import { OrderByDTO } from './order-by-dto';
|
||||
*/
|
||||
export interface QueryTokenDTO {
|
||||
|
||||
/**
|
||||
* Katalogbereich
|
||||
*/
|
||||
catalogType?: any;
|
||||
|
||||
/**
|
||||
* Lager PK
|
||||
*/
|
||||
stockId?: number;
|
||||
|
||||
/**
|
||||
* Bezeichner
|
||||
*/
|
||||
friendlyName?: string;
|
||||
|
||||
/**
|
||||
* Eingabewerte z.B. ("qs", "heller süden")
|
||||
*/
|
||||
@@ -32,9 +32,9 @@ export interface QueryTokenDTO {
|
||||
fuzzy?: number;
|
||||
|
||||
/**
|
||||
* Bezeichner
|
||||
* Katalogbereich
|
||||
*/
|
||||
friendlyName?: string;
|
||||
catalogType?: any;
|
||||
|
||||
/**
|
||||
* Filter
|
||||
|
||||
7
apps/swagger/cat/src/lib/models/shop-dto.ts
Normal file
7
apps/swagger/cat/src/lib/models/shop-dto.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
/* tslint:disable */
|
||||
|
||||
/**
|
||||
* Shop
|
||||
*/
|
||||
export interface ShopDTO {
|
||||
}
|
||||
7
apps/swagger/cat/src/lib/models/size-of-string.ts
Normal file
7
apps/swagger/cat/src/lib/models/size-of-string.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
/* tslint:disable */
|
||||
export interface SizeOfString {
|
||||
height: number;
|
||||
width: number;
|
||||
length: number;
|
||||
unit?: string;
|
||||
}
|
||||
2
apps/swagger/cat/src/lib/models/vattype.ts
Normal file
2
apps/swagger/cat/src/lib/models/vattype.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
/* tslint:disable */
|
||||
export type VATType = 0 | 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128;
|
||||
8
apps/swagger/cat/src/lib/models/vatvalue-dto.ts
Normal file
8
apps/swagger/cat/src/lib/models/vatvalue-dto.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/* tslint:disable */
|
||||
import { VATType } from './vattype';
|
||||
export interface VATValueDTO {
|
||||
label?: string;
|
||||
inPercent?: number;
|
||||
vatType?: VATType;
|
||||
value?: number;
|
||||
}
|
||||
6
apps/swagger/cat/src/lib/models/weight-of-avoirdupois.ts
Normal file
6
apps/swagger/cat/src/lib/models/weight-of-avoirdupois.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/* tslint:disable */
|
||||
import { Avoirdupois } from './avoirdupois';
|
||||
export interface WeightOfAvoirdupois {
|
||||
value: number;
|
||||
unit: Avoirdupois;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<div class="input-wrapper" [class.empty]="!ngControl.value" [class.focused]="uiControl.focused | async">
|
||||
<ng-content select="input[uiInput], ui-select"></ng-content>
|
||||
<label *ngIf="label" (click)="uiControl.focus()">{{ label }}{{ requiredMark }}</label>
|
||||
<ng-content select="input, ui-select"></ng-content>
|
||||
<label *ngIf="label" [for]="uiControl.id">{{ label }}{{ requiredMark }}</label>
|
||||
</div>
|
||||
<span class="hint" *ngIf="ngControl.touched && ngControl.errors">
|
||||
{{ ngControl.errors | uiFormControlFirstError: label }}
|
||||
|
||||
@@ -16,10 +16,7 @@ button.clear {
|
||||
@apply font-bold flex-grow;
|
||||
}
|
||||
|
||||
input[type='text'],
|
||||
input[type='password'],
|
||||
input[type='tel'],
|
||||
input[type='mail'] {
|
||||
input:not([type='radio']):not([type='checkbox']) {
|
||||
@apply outline-none border-none font-bold text-regular;
|
||||
|
||||
&:disabled {
|
||||
@@ -68,10 +65,7 @@ button.clear {
|
||||
|
||||
:host[variant='default'] {
|
||||
::ng-deep {
|
||||
input[type='text'],
|
||||
input[type='password'],
|
||||
input[type='tel'],
|
||||
input[type='mail'],
|
||||
input:not([type='radio']):not([type='checkbox']),
|
||||
ui-select {
|
||||
@apply border-t-0 border-l-0 border-r-0 border-solid pt-px-20 pb-px-10;
|
||||
border-bottom-width: 2px;
|
||||
@@ -114,3 +108,13 @@ button.clear {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:host[variant='default'] {
|
||||
&[type='radio'],
|
||||
&[type='checkbox'] {
|
||||
label,
|
||||
input {
|
||||
@apply cursor-pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
import { Directive, EventEmitter } from '@angular/core';
|
||||
import { Directive, EventEmitter, HostBinding, Input } from '@angular/core';
|
||||
|
||||
@Directive()
|
||||
export abstract class UiFormControlDirective<T> {
|
||||
@Input()
|
||||
@HostBinding('attr.name')
|
||||
name: string = (Date.now() + Math.random()).toString(32);
|
||||
|
||||
@Input()
|
||||
@HostBinding('attr.id')
|
||||
id: string = (Date.now() + Math.random()).toString(32);
|
||||
|
||||
focused = new EventEmitter<boolean>();
|
||||
|
||||
abstract type: string;
|
||||
|
||||
@@ -5,13 +5,16 @@ import { ValidationErrors } from '@angular/forms';
|
||||
})
|
||||
export class UiFormControlFirstErrorPipe implements PipeTransform {
|
||||
transform(errors: ValidationErrors, label: string): string {
|
||||
console.log(errors);
|
||||
if (errors) {
|
||||
const error = Object.keys(errors)[0];
|
||||
|
||||
switch (error) {
|
||||
case 'required':
|
||||
return `${label} wird benötigt`;
|
||||
case 'email':
|
||||
return `${label} ist ungültig`;
|
||||
default:
|
||||
return errors[error];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Directive, ElementRef, forwardRef, HostBinding, HostListener, Input, Renderer2, Self } from '@angular/core';
|
||||
import { ControlValueAccessor, NgControl, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { ChangeDetectorRef, Directive, ElementRef, forwardRef, HostBinding, HostListener, Input, Renderer2, Self } from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { UiFormControlDirective } from '@ui/form-control';
|
||||
|
||||
@Directive({
|
||||
@@ -66,7 +66,7 @@ export class UiInputDirective extends UiFormControlDirective<any> implements Con
|
||||
|
||||
focus(): void {
|
||||
setTimeout(() => {
|
||||
this.elementRef?.nativeElement?.click().focus();
|
||||
this.elementRef?.nativeElement?.click()?.focus();
|
||||
}, 0);
|
||||
}
|
||||
|
||||
@@ -74,8 +74,7 @@ export class UiInputDirective extends UiFormControlDirective<any> implements Con
|
||||
setValue(value: any, emitEvent = true) {
|
||||
if (this.value !== value) {
|
||||
this.currentValue = value;
|
||||
this.renderer.setAttribute(this.elementRef.nativeElement, 'value', this.value);
|
||||
|
||||
this.renderer.setProperty(this.elementRef.nativeElement, 'value', value);
|
||||
if (emitEvent) {
|
||||
this.onChange(value);
|
||||
this.onTouched();
|
||||
|
||||
25
apps/ui/modal/README.md
Normal file
25
apps/ui/modal/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Modal
|
||||
|
||||
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.1.2.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name --project modal` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project modal`.
|
||||
|
||||
> Note: Don't forget to add `--project modal` or else it will be added to the default project in your `angular.json` file.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build modal` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||
|
||||
## Publishing
|
||||
|
||||
After building your library with `ng build modal`, go to the dist folder `cd dist/modal` and run `npm publish`.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test modal` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
||||
32
apps/ui/modal/karma.conf.js
Normal file
32
apps/ui/modal/karma.conf.js
Normal file
@@ -0,0 +1,32 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma'),
|
||||
],
|
||||
client: {
|
||||
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: require('path').join(__dirname, '../../../coverage/ui/modal'),
|
||||
reports: ['html', 'lcovonly', 'text-summary'],
|
||||
fixWebpackSourcePaths: true,
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true,
|
||||
});
|
||||
};
|
||||
7
apps/ui/modal/ng-package.json
Normal file
7
apps/ui/modal/ng-package.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
|
||||
"dest": "../../../dist/ui/modal",
|
||||
"lib": {
|
||||
"entryFile": "src/public-api.ts"
|
||||
}
|
||||
}
|
||||
11
apps/ui/modal/package.json
Normal file
11
apps/ui/modal/package.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "@ui/modal",
|
||||
"version": "0.0.1",
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^10.1.2",
|
||||
"@angular/core": "^10.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
}
|
||||
}
|
||||
5
apps/ui/modal/src/lib/defs/index.ts
Normal file
5
apps/ui/modal/src/lib/defs/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
// start:ng42.barrel
|
||||
export * from './modal-config';
|
||||
export * from './modal-ref';
|
||||
export * from './modal-result';
|
||||
// end:ng42.barrel
|
||||
5
apps/ui/modal/src/lib/defs/modal-config.ts
Normal file
5
apps/ui/modal/src/lib/defs/modal-config.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { OverlayConfig } from '@angular/cdk/overlay';
|
||||
|
||||
export class UiModalConfig extends OverlayConfig {
|
||||
backdropClose?: boolean;
|
||||
}
|
||||
24
apps/ui/modal/src/lib/defs/modal-ref.ts
Normal file
24
apps/ui/modal/src/lib/defs/modal-ref.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { OverlayRef } from '@angular/cdk/overlay';
|
||||
import { TemplateRef, Type } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { UiModalResult } from './modal-result';
|
||||
|
||||
export class UiModalRef<TR = any, TD = any> {
|
||||
afterClosed$ = new Subject<UiModalResult<TR>>();
|
||||
|
||||
constructor(public overlay: OverlayRef, public content: TemplateRef<any> | Type<any>, public data: TD) {}
|
||||
|
||||
_close({ type, data }: { type: 'backdropClick' | 'close'; data: TR }): void {
|
||||
this.overlay.dispose();
|
||||
this.afterClosed$.next({
|
||||
type,
|
||||
data,
|
||||
});
|
||||
|
||||
this.afterClosed$.complete();
|
||||
}
|
||||
|
||||
close(data?: TR): void {
|
||||
this._close({ type: 'close', data });
|
||||
}
|
||||
}
|
||||
4
apps/ui/modal/src/lib/defs/modal-result.ts
Normal file
4
apps/ui/modal/src/lib/defs/modal-result.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export interface UiModalResult<T> {
|
||||
type: 'backdropClick' | 'close';
|
||||
data: T;
|
||||
}
|
||||
5
apps/ui/modal/src/lib/index.ts
Normal file
5
apps/ui/modal/src/lib/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
// start:ng42.barrel
|
||||
export * from './modal.component';
|
||||
export * from './modal.module';
|
||||
export * from './modal.service';
|
||||
// end:ng42.barrel
|
||||
8
apps/ui/modal/src/lib/modal.component.html
Normal file
8
apps/ui/modal/src/lib/modal.component.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<ng-container [ngSwitch]="contentType">
|
||||
<ng-container *ngSwitchCase="'template'">
|
||||
<ng-container *ngTemplateOutlet="content; context: context"></ng-container>
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchCase="'component'">
|
||||
<ng-container *ngComponentOutlet="content"></ng-container>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
3
apps/ui/modal/src/lib/modal.component.scss
Normal file
3
apps/ui/modal/src/lib/modal.component.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
@apply flex flex-col box-border bg-white p-4 w-full rounded-card;
|
||||
}
|
||||
35
apps/ui/modal/src/lib/modal.component.ts
Normal file
35
apps/ui/modal/src/lib/modal.component.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { Component, ChangeDetectionStrategy, OnInit, TemplateRef, Type } from '@angular/core';
|
||||
import { UiModalRef } from './defs/modal-ref';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-modal',
|
||||
templateUrl: 'modal.component.html',
|
||||
styleUrls: ['modal.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class UiModalComponent implements OnInit {
|
||||
contentType: 'template' | 'string' | 'component';
|
||||
content: string | TemplateRef<any> | Type<any>;
|
||||
context;
|
||||
|
||||
constructor(public ref: UiModalRef) {}
|
||||
|
||||
close(): void {
|
||||
this.ref.close(null);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.content = this.ref.content;
|
||||
|
||||
if (typeof this.content === 'string') {
|
||||
this.contentType = 'string';
|
||||
} else if (this.content instanceof TemplateRef) {
|
||||
this.contentType = 'template';
|
||||
this.context = {
|
||||
close: this.ref.close.bind(this.ref),
|
||||
};
|
||||
} else {
|
||||
this.contentType = 'component';
|
||||
}
|
||||
}
|
||||
}
|
||||
19
apps/ui/modal/src/lib/modal.module.ts
Normal file
19
apps/ui/modal/src/lib/modal.module.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { OverlayModule } from '@angular/cdk/overlay';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ModuleWithProviders, NgModule } from '@angular/core';
|
||||
import { UiModalComponent } from './modal.component';
|
||||
import { UiModalService } from './modal.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, OverlayModule],
|
||||
declarations: [UiModalComponent],
|
||||
exports: [UiModalComponent],
|
||||
})
|
||||
export class UiModalModule {
|
||||
static forRoot(): ModuleWithProviders<UiModalModule> {
|
||||
return {
|
||||
ngModule: UiModalModule,
|
||||
providers: [UiModalService],
|
||||
};
|
||||
}
|
||||
}
|
||||
49
apps/ui/modal/src/lib/modal.service.ts
Normal file
49
apps/ui/modal/src/lib/modal.service.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { GlobalPositionStrategy, Overlay } from '@angular/cdk/overlay';
|
||||
import { ComponentPortal } from '@angular/cdk/portal';
|
||||
import { Injectable, Injector, TemplateRef, Type } from '@angular/core';
|
||||
import { UiModalConfig } from './defs/modal-config';
|
||||
import { UiModalRef } from './defs/modal-ref';
|
||||
import { UiModalComponent } from './modal.component';
|
||||
|
||||
@Injectable()
|
||||
export class UiModalService {
|
||||
constructor(private overlay: Overlay, private injector: Injector) {}
|
||||
|
||||
open<R = any, T = any>({
|
||||
content,
|
||||
data,
|
||||
config,
|
||||
}: {
|
||||
content: TemplateRef<any> | Type<any>;
|
||||
data?: T;
|
||||
config?: UiModalConfig;
|
||||
}): UiModalRef<R> {
|
||||
const configs = new UiModalConfig({
|
||||
positionStrategy: new GlobalPositionStrategy().centerHorizontally().centerVertically(),
|
||||
hasBackdrop: true,
|
||||
backdropClose: true,
|
||||
width: '917px',
|
||||
...config,
|
||||
});
|
||||
|
||||
const overlay = this.overlay.create(configs);
|
||||
|
||||
const modalRef = new UiModalRef<R, T>(overlay, content, data);
|
||||
|
||||
const injector = this.createInjector(modalRef);
|
||||
overlay.attach(new ComponentPortal(UiModalComponent, null, injector));
|
||||
|
||||
if (configs.backdropClose) {
|
||||
overlay.backdropClick().subscribe(() => modalRef._close({ type: 'backdropClick', data: null }));
|
||||
}
|
||||
|
||||
return modalRef;
|
||||
}
|
||||
|
||||
createInjector(ref: UiModalRef): Injector {
|
||||
return Injector.create({
|
||||
providers: [{ provide: UiModalRef, useValue: ref }],
|
||||
parent: this.injector,
|
||||
});
|
||||
}
|
||||
}
|
||||
5
apps/ui/modal/src/public-api.ts
Normal file
5
apps/ui/modal/src/public-api.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
/*
|
||||
* Public API Surface of modal
|
||||
*/
|
||||
|
||||
export * from './lib';
|
||||
24
apps/ui/modal/src/test.ts
Normal file
24
apps/ui/modal/src/test.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js/dist/zone';
|
||||
import 'zone.js/dist/zone-testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: {
|
||||
context(
|
||||
path: string,
|
||||
deep?: boolean,
|
||||
filter?: RegExp
|
||||
): {
|
||||
keys(): string[];
|
||||
<T>(id: string): T;
|
||||
};
|
||||
};
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
25
apps/ui/modal/tsconfig.lib.json
Normal file
25
apps/ui/modal/tsconfig.lib.json
Normal file
@@ -0,0 +1,25 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"inlineSources": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"skipTemplateCodegen": true,
|
||||
"strictMetadataEmit": true,
|
||||
"enableResourceInlining": true
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
10
apps/ui/modal/tsconfig.lib.prod.json
Normal file
10
apps/ui/modal/tsconfig.lib.prod.json
Normal file
@@ -0,0 +1,10 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "./tsconfig.lib.json",
|
||||
"compilerOptions": {
|
||||
"declarationMap": false
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableIvy": false
|
||||
}
|
||||
}
|
||||
17
apps/ui/modal/tsconfig.spec.json
Normal file
17
apps/ui/modal/tsconfig.spec.json
Normal file
@@ -0,0 +1,17 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
17
apps/ui/modal/tslint.json
Normal file
17
apps/ui/modal/tslint.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "../../../tslint.json",
|
||||
"rules": {
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"ui",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"ui",
|
||||
"kebab-case"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
<button #selectButton (click)="select()" tabIndex="-1">
|
||||
<button type="button" #selectButton (click)="select()" tabIndex="-1">
|
||||
{{ label }}
|
||||
</button>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<div class="ui-input-wrapper">
|
||||
<div class="ui-select-value">{{ label }}</div>
|
||||
<button class="ui-select-toggle" (click)="toggle()" [disabled]="disabled">
|
||||
<button type="button" class="ui-select-toggle" (click)="toggle()" [disabled]="disabled">
|
||||
<ui-icon icon="arrow_head"></ui-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
}
|
||||
|
||||
:host.toggled .ui-select-dropdown-wrapper .ui-select-options {
|
||||
max-height: 20rem;
|
||||
max-height: 15rem;
|
||||
}
|
||||
|
||||
.ui-select-dropdown-wrapper .ui-select-options {
|
||||
|
||||
@@ -71,6 +71,7 @@ export class UiSelectComponent extends UiFormControlDirective<any> implements Co
|
||||
this.registerOptionsSelect();
|
||||
this.options.changes.subscribe((_) => {
|
||||
this.registerOptionsSelect();
|
||||
this.cdr.markForCheck();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -97,6 +98,9 @@ export class UiSelectComponent extends UiFormControlDirective<any> implements Co
|
||||
|
||||
setDisabledState?(isDisabled: boolean): void {
|
||||
this.disabled = isDisabled;
|
||||
if (this.disabled) {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
setValue(value: any, emitEvent: boolean = true) {
|
||||
@@ -109,6 +113,7 @@ export class UiSelectComponent extends UiFormControlDirective<any> implements Co
|
||||
}
|
||||
|
||||
this.onTouched();
|
||||
this.cdr.markForCheck();
|
||||
}
|
||||
|
||||
toggle() {
|
||||
@@ -128,21 +133,27 @@ export class UiSelectComponent extends UiFormControlDirective<any> implements Co
|
||||
}
|
||||
|
||||
close() {
|
||||
this.toggled = false;
|
||||
this.onTouched();
|
||||
this.cdr.markForCheck();
|
||||
if (this.toggled) {
|
||||
this.toggled = false;
|
||||
this.onTouched();
|
||||
this.cdr.markForCheck();
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('keyup', ['$event'])
|
||||
@HostListener('keydown', ['$event'])
|
||||
keyup(event: KeyboardEvent) {
|
||||
let optionIndex = this.options.toArray().findIndex((o) => o.focused);
|
||||
|
||||
if (event.key === 'ArrowUp') {
|
||||
event.preventDefault();
|
||||
|
||||
optionIndex--;
|
||||
if (optionIndex < 0) {
|
||||
return;
|
||||
}
|
||||
} else if (event.key === 'ArrowDown') {
|
||||
event.preventDefault();
|
||||
|
||||
optionIndex++;
|
||||
if (this.options.length - 1 < optionIndex) {
|
||||
return;
|
||||
|
||||
@@ -42,6 +42,8 @@ module.exports = {
|
||||
'px-15': '15px',
|
||||
'px-20': '20px',
|
||||
'px-25': '25px',
|
||||
'px-30': '30px',
|
||||
'px-35': '35px',
|
||||
'px-40': '40px',
|
||||
'px-50': '50px',
|
||||
'px-100': '100px',
|
||||
|
||||
@@ -145,6 +145,9 @@
|
||||
],
|
||||
"@ui/form-control": [
|
||||
"apps/ui/form-control/src/public-api.ts"
|
||||
],
|
||||
"@ui/modal": [
|
||||
"apps/ui/modal/src/public-api.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user