Einbau Validation finished

This commit is contained in:
2024-08-03 12:16:04 +02:00
parent f58448679d
commit 4c1b1fbc87
19 changed files with 421 additions and 338 deletions

View File

@@ -15,7 +15,7 @@
[type]="kind"
[id]="name"
[ngModel]="value"
(input)="onInputChange($event)"
(ngModelChange)="onInputChange($event)"
(blur)="onTouched()"
[attr.name]="name"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"

View File

@@ -1,5 +1,5 @@
import { CommonModule } from '@angular/common';
import { Component, EventEmitter, forwardRef, Input, Output } from '@angular/core';
import { Component, forwardRef, Input } from '@angular/core';
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
import { BaseInputComponent } from '../base-input/base-input.component';
import { TooltipComponent } from '../tooltip/tooltip.component';
@@ -19,7 +19,6 @@ import { ValidationMessagesService } from '../validation-messages.service';
],
})
export class ValidatedInputComponent extends BaseInputComponent {
@Output() valueChange = new EventEmitter<any>();
@Input() kind: 'text' | 'number' | 'email' | 'tel' = 'text';
constructor(validationMessagesService: ValidationMessagesService) {
super(validationMessagesService);

View File

@@ -1,6 +1,6 @@
<div>
<label for="type" class="block text-sm font-bold text-gray-700 mb-1 relative w-fit"
>Property Category @if(validationMessage){
>{{ label }} @if(validationMessage){
<div
attr.data-tooltip-target="tooltip-{{ name }}"
class="absolute inline-flex items-center justify-center w-6 h-6 text-xs font-bold text-white bg-red-500 border-2 border-white rounded-full -top-2 dark:border-gray-900 hover:cursor-pointer"

View File

@@ -10,7 +10,6 @@
</div>
<app-tooltip id="tooltip-{{ name }}" [text]="validationMessage"></app-tooltip>
}
<span class="text-red-500 ml-1">{{ validationMessage }}</span>
</label>
<textarea [id]="name" [ngModel]="value" (ngModelChange)="onInputChange($event)" [attr.name]="name" class="w-full p-2 border border-gray-300 rounded-md" rows="3"></textarea>
</div>

View File

@@ -7,8 +7,10 @@ import { lastValueFrom } from 'rxjs';
import { BusinessListing, User } from '../../../../../../bizmatch-server/src/models/db.model';
import { BusinessListingCriteria, KeycloakUser, MailInfo } from '../../../../../../bizmatch-server/src/models/main.model';
import { environment } from '../../../../environments/environment';
import { MessageService } from '../../../components/message/message.service';
import { ValidatedInputComponent } from '../../../components/validated-input/validated-input.component';
import { ValidatedTextareaComponent } from '../../../components/validated-textarea/validated-textarea.component';
import { ValidationMessagesService } from '../../../components/validation-messages.service';
import { HistoryService } from '../../../services/history.service';
import { ListingsService } from '../../../services/listings.service';
import { MailService } from '../../../services/mail.service';
@@ -65,6 +67,8 @@ export class DetailsBusinessListingComponent {
private sanitizer: DomSanitizer,
public historyService: HistoryService,
public keycloakService: KeycloakService,
private validationMessagesService: ValidationMessagesService,
private messageService: MessageService,
) {
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
@@ -86,15 +90,28 @@ export class DetailsBusinessListingComponent {
this.listingUser = await this.userService.getByMail(this.listing.email);
this.description = this.sanitizer.bypassSecurityTrustHtml(this.listing.description);
}
ngOnDestroy() {
this.validationMessagesService.clearMessages(); // Löschen Sie alle bestehenden Validierungsnachrichten
}
isAdmin() {
return this.keycloakService.getUserRoles(true).includes('ADMIN');
}
async mail() {
this.mailinfo.email = this.listingUser.email;
this.mailinfo.listing = this.listing;
await this.mailService.mail(this.mailinfo);
// this.messageService.add({ severity: 'info', summary: 'Confirmed', detail: 'Your message has been sent to the creator of the listing', life: 3000 });
try {
this.mailinfo.email = this.listingUser.email;
this.mailinfo.listing = this.listing;
await this.mailService.mail(this.mailinfo);
this.messageService.addMessage({ severity: 'success', text: 'Your message has been sent to the creator of the listing', duration: 3000 });
} catch (error) {
this.messageService.addMessage({
severity: 'danger',
text: 'An error occurred while sending the request',
duration: 5000,
});
if (error.error && Array.isArray(error.error?.message)) {
this.validationMessagesService.updateMessages(error.error.message);
}
}
}
get listingDetails() {
let typeOfRealEstate = '';

View File

@@ -7,8 +7,10 @@ import { lastValueFrom } from 'rxjs';
import { CommercialPropertyListing, User } from '../../../../../../bizmatch-server/src/models/db.model';
import { CommercialPropertyListingCriteria, ErrorResponse, KeycloakUser, MailInfo } from '../../../../../../bizmatch-server/src/models/main.model';
import { environment } from '../../../../environments/environment';
import { MessageService } from '../../../components/message/message.service';
import { ValidatedInputComponent } from '../../../components/validated-input/validated-input.component';
import { ValidatedTextareaComponent } from '../../../components/validated-textarea/validated-textarea.component';
import { ValidationMessagesService } from '../../../components/validation-messages.service';
import { HistoryService } from '../../../services/history.service';
import { ImageService } from '../../../services/image.service';
import { ListingsService } from '../../../services/listings.service';
@@ -71,6 +73,8 @@ export class DetailsCommercialPropertyListingComponent {
public keycloakService: KeycloakService,
private imageService: ImageService,
private ngZone: NgZone,
private validationMessagesService: ValidationMessagesService,
private messageService: MessageService,
) {
this.mailinfo = { sender: {}, email: '', url: environment.mailinfoUrl };
@@ -100,6 +104,9 @@ export class DetailsCommercialPropertyListingComponent {
];
//this.initFlowbite();
}
ngOnDestroy() {
this.validationMessagesService.clearMessages(); // Löschen Sie alle bestehenden Validierungsnachrichten
}
private initFlowbite() {
this.ngZone.runOutsideAngular(() => {
import('flowbite')
@@ -113,14 +120,20 @@ export class DetailsCommercialPropertyListingComponent {
return this.keycloakService.getUserRoles(true).includes('ADMIN');
}
async mail() {
this.mailinfo.email = this.listingUser.email;
this.mailinfo.listing = this.listing;
const result = await this.mailService.mail(this.mailinfo);
if (result) {
this.errorResponse = result as ErrorResponse;
} else {
this.errorResponse = null;
// this.messageService.add({ severity: 'info', summary: 'Confirmed', detail: 'Your message has been sent to the creator of the listing', life: 3000 });
try {
this.mailinfo.email = this.listingUser.email;
this.mailinfo.listing = this.listing;
await this.mailService.mail(this.mailinfo);
this.messageService.addMessage({ severity: 'success', text: 'Your message has been sent to the creator of the listing', duration: 3000 });
} catch (error) {
this.messageService.addMessage({
severity: 'danger',
text: 'An error occurred while sending the request',
duration: 5000,
});
if (error.error && Array.isArray(error.error?.message)) {
this.validationMessagesService.updateMessages(error.error.message);
}
}
}
containsError(fieldname: string) {

View File

@@ -81,9 +81,7 @@ export class BusinessListingsComponent {
this.criteria.page = page;
this.search();
}
imageErrorHandler(listing: ListingType) {
// listing.hideImage = true; // Bild ausblenden, wenn es nicht geladen werden kann
}
imageErrorHandler(listing: ListingType) {}
reset() {
this.criteria.title = null;
}

View File

@@ -119,6 +119,9 @@ export class AccountComponent {
label: this.titleCasePipe.transform(type),
}));
}
ngOnDestroy() {
this.validationMessagesService.clearMessages(); // Löschen Sie alle bestehenden Validierungsnachrichten
}
printInvoice(invoice: Invoice) {}
async updateProfile(user: User) {

View File

@@ -5,7 +5,16 @@
<form #listingForm="ngForm" class="space-y-4">
<div class="mb-4">
<label for="listingsCategory" class="block text-sm font-bold text-gray-700 mb-1">Listing category</label>
<ng-select [readonly]="mode === 'edit'" [items]="selectOptions?.listingCategories" bindLabel="name" bindValue="value" [(ngModel)]="listing.listingsCategory" name="listingsCategory"> </ng-select>
<ng-select
[readonly]="mode === 'edit'"
[items]="selectOptions?.listingCategories"
bindLabel="name"
bindValue="value"
[(ngModel)]="listing.listingsCategory"
(ngModelChange)="changeListingCategory($event)"
name="listingsCategory"
>
</ng-select>
</div>
<!-- <div class="mb-4">

View File

@@ -22,6 +22,7 @@ import { ValidatedNgSelectComponent } from '../../../components/validated-ng-sel
import { ValidatedPriceComponent } from '../../../components/validated-price/validated-price.component';
import { ValidatedQuillComponent } from '../../../components/validated-quill/validated-quill.component';
import { ValidatedTextareaComponent } from '../../../components/validated-textarea/validated-textarea.component';
import { ValidationMessagesService } from '../../../components/validation-messages.service';
import { ArrayToStringPipe } from '../../../pipes/array-to-string.pipe';
import { GeoService } from '../../../services/geo.service';
import { ImageService } from '../../../services/image.service';
@@ -80,6 +81,7 @@ export class EditBusinessListingComponent {
private messageService: MessageService,
private route: ActivatedRoute,
private keycloakService: KeycloakService,
private validationMessagesService: ValidationMessagesService,
) {
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
@@ -111,11 +113,25 @@ export class EditBusinessListingComponent {
}
}
}
ngOnDestroy() {
this.validationMessagesService.clearMessages(); // Löschen Sie alle bestehenden Validierungsnachrichten
}
async save() {
this.listing = await this.listingsService.save(this.listing, this.listing.listingsCategory);
this.router.navigate(['editBusinessListing', this.listing.id]);
this.messageService.addMessage({ severity: 'success', text: 'Listing changes have been persisted', duration: 3000 });
try {
this.listing = await this.listingsService.save(this.listing, this.listing.listingsCategory);
this.router.navigate(['editBusinessListing', this.listing.id]);
this.messageService.addMessage({ severity: 'success', text: 'Listing changes have been persisted', duration: 3000 });
this.validationMessagesService.clearMessages(); // Löschen Sie alle bestehenden Validierungsnachrichten
} catch (error) {
this.messageService.addMessage({
severity: 'danger',
text: 'An error occurred while saving the profile',
duration: 5000,
});
if (error.error && Array.isArray(error.error?.message)) {
this.validationMessagesService.updateMessages(error.error.message);
}
}
}
suggestions: string[] | undefined;

View File

@@ -5,7 +5,16 @@
<form #listingForm="ngForm" class="space-y-4">
<div>
<label for="listingsCategory" class="block text-sm font-bold text-gray-700 mb-1">Listing category</label>
<ng-select [readonly]="mode === 'edit'" [items]="selectOptions?.listingCategories" bindLabel="name" bindValue="value" [(ngModel)]="listing.listingsCategory" name="listingsCategory"> </ng-select>
<ng-select
[readonly]="mode === 'edit'"
[items]="selectOptions?.listingCategories"
bindLabel="name"
bindValue="value"
(ngModelChange)="changeListingCategory($event)"
[(ngModel)]="listing.listingsCategory"
name="listingsCategory"
>
</ng-select>
</div>
<!-- <div class="mb-4">
@@ -26,7 +35,9 @@
<label for="type" class="block text-sm font-bold text-gray-700 mb-1">Property Category</label>
<ng-select [items]="typesOfCommercialProperty" bindLabel="name" bindValue="value" [(ngModel)]="listing.type" name="type"> </ng-select>
</div> -->
<app-validated-ng-select label="Property Category" name="type" [(ngModel)]="listing.type" [items]="typesOfCommercialProperty"></app-validated-ng-select>
<div>
<app-validated-ng-select label="Property Category" name="type" [(ngModel)]="listing.type" [items]="typesOfCommercialProperty"></app-validated-ng-select>
</div>
<!-- <div class="flex mb-4 space-x-4">
<div class="w-1/2">

View File

@@ -25,6 +25,7 @@ import { ValidatedInputComponent } from '../../../components/validated-input/val
import { ValidatedNgSelectComponent } from '../../../components/validated-ng-select/validated-ng-select.component';
import { ValidatedPriceComponent } from '../../../components/validated-price/validated-price.component';
import { ValidatedQuillComponent } from '../../../components/validated-quill/validated-quill.component';
import { ValidationMessagesService } from '../../../components/validation-messages.service';
import { ArrayToStringPipe } from '../../../pipes/array-to-string.pipe';
import { GeoService } from '../../../services/geo.service';
import { ImageService } from '../../../services/image.service';
@@ -119,6 +120,7 @@ export class EditCommercialPropertyListingComponent {
private confirmationService: ConfirmationService,
private messageService: MessageService,
private viewportRuler: ViewportRuler,
private validationMessagesService: ValidationMessagesService,
) {
// Abonniere Router-Events, um den aktiven Link zu ermitteln
this.router.events.subscribe(event => {
@@ -151,11 +153,25 @@ export class EditCommercialPropertyListingComponent {
}
}
}
ngOnDestroy() {
this.validationMessagesService.clearMessages(); // Löschen Sie alle bestehenden Validierungsnachrichten
}
async save() {
this.listing = (await this.listingsService.save(this.listing, this.listing.listingsCategory)) as CommercialPropertyListing;
this.router.navigate(['editCommercialPropertyListing', this.listing.id]);
this.messageService.addMessage({ severity: 'success', text: 'Listing changes have been persisted', duration: 3000 });
try {
this.listing = (await this.listingsService.save(this.listing, this.listing.listingsCategory)) as CommercialPropertyListing;
this.router.navigate(['editCommercialPropertyListing', this.listing.id]);
this.messageService.addMessage({ severity: 'success', text: 'Listing changes have been persisted', duration: 3000 });
this.validationMessagesService.clearMessages(); // Löschen Sie alle bestehenden Validierungsnachrichten
} catch (error) {
this.messageService.addMessage({
severity: 'danger',
text: 'An error occurred while saving the profile',
duration: 5000,
});
if (error.error && Array.isArray(error.error?.message)) {
this.validationMessagesService.updateMessages(error.error.message);
}
}
}
async search(event: AutoCompleteCompleteEvent) {
@@ -214,47 +230,4 @@ export class EditCommercialPropertyListingComponent {
imageOrderChanged(imageOrder: string[]) {
this.listing.imageOrder = imageOrder;
}
// select(event: any) {
// const imageUrl = URL.createObjectURL(event.files[0]);
// getImageDimensions(imageUrl).then(dimensions => {
// const dialogWidth = getDialogWidth(dimensions);
// this.dialogRef = this.dialogService.open(ImageCropperComponent, {
// data: {
// imageUrl: imageUrl,
// fileUpload: this.fileUpload,
// ratioVariable: false,
// },
// header: 'Edit Image',
// width: dialogWidth,
// modal: true,
// closeOnEscape: true,
// keepInViewport: true,
// closable: false,
// breakpoints: {
// '960px': '75vw',
// '640px': '90vw',
// },
// });
// this.dialogRef.onClose.subscribe(cropper => {
// if (cropper) {
// this.loadingService.startLoading('uploadImage');
// cropper.getCroppedCanvas().toBlob(async blob => {
// this.imageService.uploadImage(blob, 'uploadPropertyPicture', this.listing.imagePath, this.listing.serialId).subscribe(
// async event => {
// if (event.type === HttpEventType.Response) {
// this.ts = new Date().getTime();
// console.log('Upload abgeschlossen', event.body);
// this.loadingService.stopLoading('uploadImage');
// this.listing = await lastValueFrom(this.listingsService.getListingById(this.id, 'commercialProperty'));
// }
// },
// error => console.error('Fehler beim Upload:', error),
// );
// }, 'image/jpg');
// cropper.destroy();
// }
// });
// });
// }
}

View File

@@ -4,8 +4,10 @@ import { KeycloakService } from 'keycloak-angular';
import { User } from '../../../../../../bizmatch-server/src/models/db.model';
import { ErrorResponse, KeycloakUser, MailInfo } from '../../../../../../bizmatch-server/src/models/main.model';
import { environment } from '../../../../environments/environment';
import { MessageService } from '../../../components/message/message.service';
import { ValidatedInputComponent } from '../../../components/validated-input/validated-input.component';
import { ValidatedTextareaComponent } from '../../../components/validated-textarea/validated-textarea.component';
import { ValidationMessagesService } from '../../../components/validation-messages.service';
import { MailService } from '../../../services/mail.service';
import { UserService } from '../../../services/user.service';
import { SharedModule } from '../../../shared/shared/shared.module';
@@ -23,7 +25,13 @@ export class EmailUsComponent {
keycloakUser: KeycloakUser;
user: User;
errorResponse: ErrorResponse;
constructor(private mailService: MailService, private userService: UserService, public keycloakService: KeycloakService) {
constructor(
private mailService: MailService,
private userService: UserService,
public keycloakService: KeycloakService,
private validationMessagesService: ValidationMessagesService,
private messageService: MessageService,
) {
this.mailinfo = { sender: {}, email: '', url: environment.mailinfoUrl };
}
async ngOnInit() {
@@ -34,14 +42,23 @@ export class EmailUsComponent {
this.mailinfo.sender = { name: `${this.user.firstname} ${this.user.lastname}`, email: this.user.email, phoneNumber: this.user.phoneNumber, state: this.user.companyLocation };
}
}
ngOnDestroy() {
this.validationMessagesService.clearMessages(); // Löschen Sie alle bestehenden Validierungsnachrichten
}
async mail() {
this.mailinfo.email = 'support@bizmatch.net';
const result = await this.mailService.mail(this.mailinfo);
if (result) {
this.errorResponse = result as ErrorResponse;
} else {
this.errorResponse = null;
// this.messageService.add({ severity: 'info', summary: 'Confirmed', detail: 'Your request has been forwarded to the support team of bizmatch.', life: 3000 });
try {
this.mailinfo.email = 'support@bizmatch.net';
await this.mailService.mail(this.mailinfo);
this.messageService.addMessage({ severity: 'success', text: 'Your request has been forwarded to the support team of bizmatch.', duration: 3000 });
} catch (error) {
this.messageService.addMessage({
severity: 'danger',
text: 'An error occurred',
duration: 5000,
});
if (error.error && Array.isArray(error.error?.message)) {
this.validationMessagesService.updateMessages(error.error.message);
}
}
}
containsError(fieldname: string) {