not-found page, #85, client logging
This commit is contained in:
parent
1f8febc479
commit
a8bb163acf
|
|
@ -13,6 +13,9 @@ import { FileService } from './file/file.service.js';
|
|||
import { GeoModule } from './geo/geo.module.js';
|
||||
import { ImageModule } from './image/image.module.js';
|
||||
import { ListingsModule } from './listings/listings.module.js';
|
||||
import { LogController } from './log/log.controller.js';
|
||||
import { LogModule } from './log/log.module.js';
|
||||
|
||||
import { MailModule } from './mail/mail.module.js';
|
||||
import { RequestDurationMiddleware } from './request-duration/request-duration.middleware.js';
|
||||
import { SelectOptionsModule } from './select-options/select-options.module.js';
|
||||
|
|
@ -75,8 +78,9 @@ loadEnvFiles();
|
|||
ImageModule,
|
||||
PassportModule,
|
||||
AiModule,
|
||||
LogModule,
|
||||
],
|
||||
controllers: [AppController],
|
||||
controllers: [AppController, LogController],
|
||||
providers: [AppService, FileService],
|
||||
})
|
||||
export class AppModule {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
import { Body, Controller, Inject, Post, Request, UseGuards } from '@nestjs/common';
|
||||
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
|
||||
import { Logger } from 'winston';
|
||||
import { OptionalJwtAuthGuard } from '../jwt-auth/optional-jwt-auth.guard.js';
|
||||
import { LogMessage } from '../models/main.model.js';
|
||||
@Controller('log')
|
||||
export class LogController {
|
||||
constructor(@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger) {}
|
||||
|
||||
@UseGuards(OptionalJwtAuthGuard)
|
||||
@Post()
|
||||
log(@Request() req, @Body() message: LogMessage) {
|
||||
if (message.severity === 'info') {
|
||||
this.logger.info(message.text);
|
||||
} else {
|
||||
this.logger.error(message.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { LogController } from './log.controller.js';
|
||||
|
||||
@Module({
|
||||
controllers: [LogController],
|
||||
})
|
||||
export class LogModule {}
|
||||
|
|
@ -247,6 +247,14 @@ export interface CountyResult {
|
|||
state: string;
|
||||
state_code: string;
|
||||
}
|
||||
export interface LogMessage {
|
||||
severity: 'error' | 'info';
|
||||
text: string;
|
||||
}
|
||||
export interface ModalResult {
|
||||
accepted: boolean;
|
||||
criteria?: BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria;
|
||||
}
|
||||
export function isEmpty(value: any): boolean {
|
||||
// Check for undefined or null
|
||||
if (value === undefined || value === null) {
|
||||
|
|
|
|||
|
|
@ -54,6 +54,10 @@ export const routes: Routes = [
|
|||
canActivate: [ListingCategoryGuard],
|
||||
component: NotFoundComponent, // Dummy-Komponente, wird nie angezeigt, da der Guard weiterleitet
|
||||
},
|
||||
{
|
||||
path: 'notfound',
|
||||
component: NotFoundComponent,
|
||||
},
|
||||
// #########
|
||||
// User Details
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { CriteriaChangeService } from '../../services/criteria-change.service';
|
|||
import { SearchService } from '../../services/search.service';
|
||||
import { SharedService } from '../../services/shared.service';
|
||||
import { UserService } from '../../services/user.service';
|
||||
import { compareObjects, createEmptyBusinessListingCriteria, createEmptyCommercialPropertyListingCriteria, createEmptyUserListingCriteria, getCriteriaProxy, map2User } from '../../utils/utils';
|
||||
import { assignProperties, compareObjects, createEmptyBusinessListingCriteria, createEmptyCommercialPropertyListingCriteria, createEmptyUserListingCriteria, getCriteriaProxy, map2User } from '../../utils/utils';
|
||||
import { DropdownComponent } from '../dropdown/dropdown.component';
|
||||
import { ModalService } from '../search-modal/modal.service';
|
||||
@Component({
|
||||
|
|
@ -86,9 +86,11 @@ export class HeaderComponent {
|
|||
ngAfterViewInit() {}
|
||||
|
||||
async openModal() {
|
||||
const accepted = await this.modalService.showModal(this.criteria);
|
||||
if (accepted) {
|
||||
const modalResult = await this.modalService.showModal(this.criteria);
|
||||
if (modalResult.accepted) {
|
||||
this.searchService.search(this.criteria);
|
||||
} else {
|
||||
this.criteria = assignProperties(this.criteria, modalResult.criteria);
|
||||
}
|
||||
}
|
||||
navigateWithState(dest: string, state: any) {
|
||||
|
|
|
|||
|
|
@ -1 +1,35 @@
|
|||
<p>not-found works!</p>
|
||||
<!-- <section class="bg-white dark:bg-gray-900">
|
||||
<div class="py-8 px-4 mx-auto max-w-screen-xl lg:py-16 lg:px-6">
|
||||
<div class="mx-auto max-w-screen-sm text-center">
|
||||
<h1 class="mb-4 text-7xl tracking-tight font-extrabold lg:text-9xl text-primary-600 dark:text-primary-500">404</h1>
|
||||
<p class="mb-4 text-3xl tracking-tight font-bold text-gray-900 md:text-4xl dark:text-white">Something's missing.</p>
|
||||
<p class="mb-4 text-lg font-light text-gray-500 dark:text-gray-400">Sorry, we can't find that page.</p>
|
||||
<a
|
||||
routerLink="/home"
|
||||
class="inline-flex text-white bg-primary-600 hover:bg-primary-800 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:focus:ring-primary-900 my-4"
|
||||
>Back to Homepage</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</section> -->
|
||||
<section class="bg-white dark:bg-gray-900">
|
||||
<div class="py-8 px-4 mx-auto max-w-screen-xl lg:py-16 lg:px-6">
|
||||
<div class="mx-auto max-w-screen-sm text-center">
|
||||
<h1 class="mb-4 text-7xl tracking-tight font-extrabold lg:text-9xl text-blue-700 dark:text-blue-500">404</h1>
|
||||
<p class="mb-4 text-3xl tracking-tight font-bold text-gray-900 md:text-4xl dark:text-white">Something's missing.</p>
|
||||
<p class="mb-4 text-lg font-light text-gray-500 dark:text-gray-400">Sorry, we can't find that page</p>
|
||||
<!-- <a
|
||||
href="#"
|
||||
class="inline-flex text-white bg-primary-600 hover:bg-primary-800 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:focus:ring-primary-900 my-4"
|
||||
>Back to Homepage</a
|
||||
> -->
|
||||
<button
|
||||
type="button"
|
||||
[routerLink]="['/home']"
|
||||
class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800"
|
||||
>
|
||||
Back to Homepage
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
import { CommonModule } from '@angular/common';
|
||||
import { Component } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-not-found',
|
||||
standalone: true,
|
||||
template: '<h2>Page not found</h2>',
|
||||
imports: [CommonModule, RouterModule],
|
||||
templateUrl: './not-found.component.html',
|
||||
})
|
||||
export class NotFoundComponent {}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// 1. Shared Service (modal.service.ts)
|
||||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { BusinessListingCriteria, CommercialPropertyListingCriteria, UserListingCriteria } from '../../../../../bizmatch-server/src/models/main.model';
|
||||
import { BusinessListingCriteria, CommercialPropertyListingCriteria, ModalResult, UserListingCriteria } from '../../../../../bizmatch-server/src/models/main.model';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
|
|
@ -9,26 +9,26 @@ import { BusinessListingCriteria, CommercialPropertyListingCriteria, UserListing
|
|||
export class ModalService {
|
||||
private modalVisibleSubject = new BehaviorSubject<boolean>(false);
|
||||
private messageSubject = new BehaviorSubject<BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria>(null);
|
||||
private resolvePromise!: (value: boolean) => void;
|
||||
private resolvePromise!: (value: ModalResult) => void;
|
||||
|
||||
modalVisible$: Observable<boolean> = this.modalVisibleSubject.asObservable();
|
||||
message$: Observable<BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria> = this.messageSubject.asObservable();
|
||||
|
||||
showModal(message: BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria): Promise<boolean> {
|
||||
showModal(message: BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria): Promise<ModalResult> {
|
||||
this.messageSubject.next(message);
|
||||
this.modalVisibleSubject.next(true);
|
||||
return new Promise<boolean>(resolve => {
|
||||
return new Promise<ModalResult>(resolve => {
|
||||
this.resolvePromise = resolve;
|
||||
});
|
||||
}
|
||||
|
||||
accept(): void {
|
||||
this.modalVisibleSubject.next(false);
|
||||
this.resolvePromise(true);
|
||||
this.resolvePromise({ accepted: true });
|
||||
}
|
||||
|
||||
reject(): void {
|
||||
reject(backupCriteria: BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria): void {
|
||||
this.modalVisibleSubject.next(false);
|
||||
this.resolvePromise(false);
|
||||
this.resolvePromise({ accepted: false, criteria: backupCriteria });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
} @else {
|
||||
<h3 class="text-xl font-semibold text-gray-900">Professional Listing Search</h3>
|
||||
}
|
||||
<button (click)="modalService.reject()" type="button" class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ml-auto inline-flex justify-center items-center">
|
||||
<button (click)="close()" type="button" class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ml-auto inline-flex justify-center items-center">
|
||||
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
|
||||
</svg>
|
||||
|
|
@ -20,6 +20,11 @@
|
|||
<div class="flex space-x-4 mb-4">
|
||||
<button class="text-blue-600 font-medium border-b-2 border-blue-600 pb-2">Classic Search</button>
|
||||
<button class="text-gray-500">AI Search <span class="bg-gray-200 text-xs font-semibold px-2 py-1 rounded">BETA</span></button>
|
||||
<i data-tooltip-target="tooltip-light" class="fa-solid fa-trash-can flex self-center ml-2 hover:cursor-pointer text-blue-500" (click)="clearFilter()"></i>
|
||||
<div id="tooltip-light" role="tooltip" class="absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-gray-900 bg-white border border-gray-200 rounded-lg shadow-sm opacity-0 tooltip">
|
||||
Clear all Filter
|
||||
<div class="tooltip-arrow" data-popper-arrow></div>
|
||||
</div>
|
||||
</div>
|
||||
@if(criteria.criteriaType==='businessListings'){
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
|
|
@ -470,7 +475,7 @@
|
|||
</button>
|
||||
<button
|
||||
type="button"
|
||||
(click)="modalService.reject()"
|
||||
(click)="close()"
|
||||
class="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-blue-300 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10"
|
||||
>
|
||||
Cancel
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { ListingsService } from '../../services/listings.service';
|
|||
import { SelectOptionsService } from '../../services/select-options.service';
|
||||
import { UserService } from '../../services/user.service';
|
||||
import { SharedModule } from '../../shared/shared/shared.module';
|
||||
import { resetBusinessListingCriteria, resetCommercialPropertyListingCriteria, resetUserListingCriteria } from '../../utils/utils';
|
||||
import { ValidatedCityComponent } from '../validated-city/validated-city.component';
|
||||
import { ModalService } from './modal.service';
|
||||
@UntilDestroy()
|
||||
|
|
@ -29,7 +30,9 @@ export class SearchModalComponent {
|
|||
countyInput$ = new Subject<string>();
|
||||
private criteriaChangeSubscription: Subscription;
|
||||
public criteria: BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria;
|
||||
backupCriteria: BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria;
|
||||
numberOfResults$: Observable<number>;
|
||||
cancelDisable = false;
|
||||
constructor(
|
||||
public selectOptions: SelectOptionsService,
|
||||
public modalService: ModalService,
|
||||
|
|
@ -42,6 +45,7 @@ export class SearchModalComponent {
|
|||
this.setupCriteriaChangeListener();
|
||||
this.modalService.message$.pipe(untilDestroyed(this)).subscribe(msg => {
|
||||
this.criteria = msg;
|
||||
this.backupCriteria = JSON.parse(JSON.stringify(msg));
|
||||
this.setTotalNumberOfResults();
|
||||
});
|
||||
this.modalService.modalVisible$.pipe(untilDestroyed(this)).subscribe(val => {
|
||||
|
|
@ -54,7 +58,9 @@ export class SearchModalComponent {
|
|||
this.loadCounties();
|
||||
}
|
||||
|
||||
ngOnChanges() {}
|
||||
ngOnChanges() {
|
||||
console.log('sdf');
|
||||
}
|
||||
categoryClicked(checked: boolean, value: string) {
|
||||
if (checked) {
|
||||
this.criteria.types.push(value);
|
||||
|
|
@ -116,7 +122,10 @@ export class SearchModalComponent {
|
|||
}
|
||||
}
|
||||
private setupCriteriaChangeListener() {
|
||||
this.criteriaChangeSubscription = this.criteriaChangeService.criteriaChange$.pipe(debounceTime(400)).subscribe(() => this.setTotalNumberOfResults());
|
||||
this.criteriaChangeSubscription = this.criteriaChangeService.criteriaChange$.pipe(debounceTime(400)).subscribe(() => {
|
||||
this.setTotalNumberOfResults();
|
||||
this.cancelDisable = true;
|
||||
});
|
||||
}
|
||||
trackByFn(item: GeoResult) {
|
||||
return item.id;
|
||||
|
|
@ -148,4 +157,16 @@ export class SearchModalComponent {
|
|||
}
|
||||
}
|
||||
}
|
||||
clearFilter() {
|
||||
if (this.criteria.criteriaType === 'businessListings') {
|
||||
resetBusinessListingCriteria(this.criteria);
|
||||
} else if (this.criteria.criteriaType === 'commercialPropertyListings') {
|
||||
resetCommercialPropertyListingCriteria(this.criteria);
|
||||
} else {
|
||||
resetUserListingCriteria(this.criteria);
|
||||
}
|
||||
}
|
||||
close() {
|
||||
this.modalService.reject(this.backupCriteria);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import { ValidatedTextareaComponent } from '../../../components/validated-textar
|
|||
import { ValidationMessagesService } from '../../../components/validation-messages.service';
|
||||
import { HistoryService } from '../../../services/history.service';
|
||||
import { ListingsService } from '../../../services/listings.service';
|
||||
import { LogService } from '../../../services/log.service';
|
||||
import { MailService } from '../../../services/mail.service';
|
||||
import { SelectOptionsService } from '../../../services/select-options.service';
|
||||
import { UserService } from '../../../services/user.service';
|
||||
|
|
@ -67,6 +68,7 @@ export class DetailsBusinessListingComponent {
|
|||
public keycloakService: KeycloakService,
|
||||
private validationMessagesService: ValidationMessagesService,
|
||||
private messageService: MessageService,
|
||||
private logService: LogService,
|
||||
) {
|
||||
this.router.events.subscribe(event => {
|
||||
if (event instanceof NavigationEnd) {
|
||||
|
|
@ -88,7 +90,8 @@ export class DetailsBusinessListingComponent {
|
|||
this.listingUser = await this.userService.getByMail(this.listing.email);
|
||||
this.description = this.sanitizer.bypassSecurityTrustHtml(this.listing.description);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
this.logService.log({ severity: 'error', text: error.error.message });
|
||||
this.router.navigate(['notfound']);
|
||||
}
|
||||
}
|
||||
ngOnDestroy() {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import { ValidationMessagesService } from '../../../components/validation-messag
|
|||
import { HistoryService } from '../../../services/history.service';
|
||||
import { ImageService } from '../../../services/image.service';
|
||||
import { ListingsService } from '../../../services/listings.service';
|
||||
import { LogService } from '../../../services/log.service';
|
||||
import { MailService } from '../../../services/mail.service';
|
||||
import { SelectOptionsService } from '../../../services/select-options.service';
|
||||
import { UserService } from '../../../services/user.service';
|
||||
|
|
@ -75,6 +76,7 @@ export class DetailsCommercialPropertyListingComponent {
|
|||
private ngZone: NgZone,
|
||||
private validationMessagesService: ValidationMessagesService,
|
||||
private messageService: MessageService,
|
||||
private logService: LogService,
|
||||
) {
|
||||
this.mailinfo = { sender: {}, email: '', url: environment.mailinfoUrl };
|
||||
|
||||
|
|
@ -105,7 +107,8 @@ export class DetailsCommercialPropertyListingComponent {
|
|||
this.propertyDetails.push({ label: 'Draft', value: this.listing.draft ? 'Yes' : 'No' });
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
this.logService.log({ severity: 'error', text: error.error.message });
|
||||
this.router.navigate(['notfound']);
|
||||
}
|
||||
|
||||
//this.initFlowbite();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
import { LogMessage } from '../../../../bizmatch-server/src/models/main.model';
|
||||
import { environment } from '../../environments/environment';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class LogService {
|
||||
private apiBaseUrl = environment.apiBaseUrl;
|
||||
constructor(private http: HttpClient) {}
|
||||
|
||||
async log(message: LogMessage): Promise<void> {
|
||||
lastValueFrom(this.http.post(`${this.apiBaseUrl}/bizmatch/log`, message));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,93 +1,11 @@
|
|||
import { Router } from '@angular/router';
|
||||
import { ConsoleFormattedStream, INFO, createLogger as _createLogger, stdSerializers } from 'browser-bunyan';
|
||||
import { jwtDecode } from 'jwt-decode';
|
||||
import onChange from 'on-change';
|
||||
import { User } from '../../../../bizmatch-server/src/models/db.model';
|
||||
import { BusinessListingCriteria, CommercialPropertyListingCriteria, JwtToken, KeycloakUser, MailInfo, UserListingCriteria } from '../../../../bizmatch-server/src/models/main.model';
|
||||
import { environment } from '../../environments/environment';
|
||||
|
||||
// export function createDefaultUser(email: string, firstname: string, lastname: string): User {
|
||||
// return {
|
||||
// id: undefined,
|
||||
// email,
|
||||
// firstname,
|
||||
// lastname,
|
||||
// phoneNumber: '',
|
||||
// description: '',
|
||||
// companyName: '',
|
||||
// companyOverview: '',
|
||||
// companyWebsite: '',
|
||||
// companyLocation: '',
|
||||
// offeredServices: '',
|
||||
// areasServed: [],
|
||||
// hasProfile: false,
|
||||
// hasCompanyLogo: false,
|
||||
// licensedIn: [],
|
||||
// gender: undefined,
|
||||
// customerType: undefined,
|
||||
// customerSubType: undefined,
|
||||
// created: new Date(),
|
||||
// updated: new Date(),
|
||||
// };
|
||||
// }
|
||||
|
||||
// export function createDefaultCommercialPropertyListing(): CommercialPropertyListing {
|
||||
// return {
|
||||
// id: undefined,
|
||||
// serialId: undefined,
|
||||
// email: '',
|
||||
// type: null,
|
||||
// title: '',
|
||||
// description: '',
|
||||
// city: '',
|
||||
// state: '',
|
||||
// price: null,
|
||||
// favoritesForUser: [],
|
||||
// hideImage: false,
|
||||
// draft: false,
|
||||
// zipCode: null,
|
||||
// county: '',
|
||||
// imageOrder: [],
|
||||
// imagePath: '',
|
||||
// created: null,
|
||||
// updated: null,
|
||||
// visits: null,
|
||||
// lastVisit: null,
|
||||
// latitude: null,
|
||||
// longitude: null,
|
||||
// listingsCategory: 'commercialProperty',
|
||||
// };
|
||||
// }
|
||||
// export function createDefaultBusinessListing(): BusinessListing {
|
||||
// return {
|
||||
// id: undefined,
|
||||
// email: '',
|
||||
// type: null,
|
||||
// title: '',
|
||||
// description: '',
|
||||
// city: '',
|
||||
// state: '',
|
||||
// price: null,
|
||||
// favoritesForUser: [],
|
||||
// draft: false,
|
||||
// realEstateIncluded: false,
|
||||
// leasedLocation: false,
|
||||
// franchiseResale: false,
|
||||
// salesRevenue: null,
|
||||
// cashFlow: null,
|
||||
// supportAndTraining: '',
|
||||
// employees: null,
|
||||
// established: null,
|
||||
// internalListingNumber: null,
|
||||
// reasonForSale: '',
|
||||
// brokerLicencing: '',
|
||||
// internals: '',
|
||||
// created: null,
|
||||
// updated: null,
|
||||
// visits: null,
|
||||
// lastVisit: null,
|
||||
// latitude: null,
|
||||
// longitude: null,
|
||||
// listingsCategory: 'business',
|
||||
// };
|
||||
// }
|
||||
export function createEmptyBusinessListingCriteria(): BusinessListingCriteria {
|
||||
return {
|
||||
start: 0,
|
||||
|
|
@ -153,6 +71,66 @@ export function createEmptyUserListingCriteria(): UserListingCriteria {
|
|||
radius: null,
|
||||
};
|
||||
}
|
||||
export function resetBusinessListingCriteria(criteria: BusinessListingCriteria) {
|
||||
criteria.start = 0;
|
||||
criteria.length = 0;
|
||||
criteria.page = 0;
|
||||
criteria.state = null;
|
||||
criteria.city = null;
|
||||
criteria.types = [];
|
||||
criteria.prompt = '';
|
||||
criteria.criteriaType = 'businessListings';
|
||||
criteria.minPrice = null;
|
||||
criteria.maxPrice = null;
|
||||
criteria.minRevenue = null;
|
||||
criteria.maxRevenue = null;
|
||||
criteria.minCashFlow = null;
|
||||
criteria.maxCashFlow = null;
|
||||
criteria.minNumberEmployees = null;
|
||||
criteria.maxNumberEmployees = null;
|
||||
criteria.establishedSince = null;
|
||||
criteria.establishedUntil = null;
|
||||
criteria.realEstateChecked = false;
|
||||
criteria.leasedLocation = false;
|
||||
criteria.franchiseResale = false;
|
||||
criteria.title = '';
|
||||
criteria.brokerName = '';
|
||||
criteria.searchType = 'exact';
|
||||
criteria.radius = null;
|
||||
}
|
||||
|
||||
export function resetCommercialPropertyListingCriteria(criteria: CommercialPropertyListingCriteria) {
|
||||
criteria.start = 0;
|
||||
criteria.length = 0;
|
||||
criteria.page = 0;
|
||||
criteria.state = null;
|
||||
criteria.city = null;
|
||||
criteria.types = [];
|
||||
criteria.prompt = '';
|
||||
criteria.criteriaType = 'commercialPropertyListings';
|
||||
criteria.minPrice = null;
|
||||
criteria.maxPrice = null;
|
||||
criteria.title = '';
|
||||
criteria.searchType = 'exact';
|
||||
criteria.radius = null;
|
||||
}
|
||||
|
||||
export function resetUserListingCriteria(criteria: UserListingCriteria) {
|
||||
criteria.start = 0;
|
||||
criteria.length = 0;
|
||||
criteria.page = 0;
|
||||
criteria.city = null;
|
||||
criteria.types = [];
|
||||
criteria.prompt = '';
|
||||
criteria.criteriaType = 'brokerListings';
|
||||
criteria.brokerName = '';
|
||||
criteria.companyName = '';
|
||||
criteria.counties = [];
|
||||
criteria.state = '';
|
||||
criteria.searchType = 'exact';
|
||||
criteria.radius = null;
|
||||
}
|
||||
|
||||
export function createMailInfo(user: User): MailInfo {
|
||||
return {
|
||||
sender: { name: `${user.firstname} ${user.lastname}`, email: user.email, phoneNumber: user.phoneNumber, state: user.companyLocation?.state, comments: null },
|
||||
|
|
@ -178,9 +156,7 @@ export function formatPhoneNumber(phone: string): string {
|
|||
}
|
||||
return phone;
|
||||
}
|
||||
// export const getSessionStorageHandler = function (path, value, previous, applyData) {
|
||||
// sessionStorage.setItem(applyData, JSON.stringify(this));
|
||||
// };
|
||||
|
||||
export const getSessionStorageHandler = function (criteriaType, path, value, previous, applyData) {
|
||||
sessionStorage.setItem(`${criteriaType}_criteria`, JSON.stringify(this));
|
||||
console.log('Zusätzlicher Parameter:', criteriaType);
|
||||
|
|
@ -191,19 +167,6 @@ export const getSessionStorageHandlerWrapper = param => {
|
|||
};
|
||||
};
|
||||
|
||||
export function getCriteriaStateObject(criteriaType: 'businessListings' | 'commercialPropertyListings' | 'brokerListings') {
|
||||
let initialState;
|
||||
if (criteriaType === 'businessListings') {
|
||||
initialState = createEmptyBusinessListingCriteria();
|
||||
} else if (criteriaType === 'commercialPropertyListings') {
|
||||
initialState = createEmptyCommercialPropertyListingCriteria();
|
||||
} else {
|
||||
initialState = createEmptyUserListingCriteria();
|
||||
}
|
||||
const storedState = sessionStorage.getItem(`${criteriaType}`);
|
||||
return storedState ? JSON.parse(storedState) : initialState;
|
||||
}
|
||||
|
||||
export function routeListingWithState(router: Router, value: string, data: any) {
|
||||
if (value === 'business') {
|
||||
router.navigate(['createBusinessListing'], { state: { data } });
|
||||
|
|
@ -248,70 +211,6 @@ export function getDialogWidth(dimensions): string {
|
|||
return dialogWidth;
|
||||
}
|
||||
|
||||
import { initFlowbite } from 'flowbite';
|
||||
import onChange from 'on-change';
|
||||
import { Subject, concatMap, delay, of } from 'rxjs';
|
||||
import { User } from '../../../../bizmatch-server/src/models/db.model';
|
||||
import { environment } from '../../environments/environment';
|
||||
|
||||
const flowbiteQueue = new Subject<() => void>();
|
||||
|
||||
flowbiteQueue.pipe(concatMap(item => of(item).pipe(delay(100)))).subscribe(x => {
|
||||
x();
|
||||
});
|
||||
|
||||
export function Flowbite() {
|
||||
return function (target: any) {
|
||||
const originalOnInit = target.prototype.ngOnInit;
|
||||
target.prototype.ngOnInit = function () {
|
||||
if (originalOnInit) {
|
||||
originalOnInit.apply(this);
|
||||
}
|
||||
initFlowbiteFix();
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export function initFlowbiteFix() {
|
||||
flowbiteQueue.next(() => {
|
||||
const elements = Array.from(document.querySelectorAll('*'));
|
||||
const flowbiteElements: Element[] = [];
|
||||
const initializedElements = Array.from(document.querySelectorAll('[flowbite-initialized]'));
|
||||
|
||||
for (const element of elements) {
|
||||
const attributes = Array.from(element.attributes);
|
||||
|
||||
for (const attribute of attributes) {
|
||||
if (attribute.name.startsWith('data-') && !initializedElements.includes(element)) {
|
||||
flowbiteElements.push(element);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const element of flowbiteElements) {
|
||||
element.setAttribute('flowbite-initialized', '');
|
||||
}
|
||||
initFlowbite();
|
||||
|
||||
for (const element of flowbiteElements) {
|
||||
const attributes: { name: string; value: string }[] = Array.from(element.attributes);
|
||||
const dataAttributes = attributes.filter(attribute => attribute.name.startsWith('data-'));
|
||||
|
||||
for (const attribute of dataAttributes) {
|
||||
element.setAttribute(attribute.name.replace('data-', 'fb-'), attribute.value);
|
||||
element.removeAttribute(attribute.name);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
// export function arraysEqual(arr1: any[], arr2: any[]): boolean {
|
||||
// if (arr1.length !== arr2.length) return false;
|
||||
// for (let i = 0; i < arr1.length; i++) {
|
||||
// if (arr1[i] !== arr2[i]) return false;
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
export function compareObjects<T extends object>(obj1: T, obj2: T, ignoreProperties: (keyof T)[] = []): number {
|
||||
let differences = 0;
|
||||
const keys = Object.keys(obj1) as Array<keyof T>;
|
||||
|
|
@ -380,10 +279,29 @@ function arraysEqual(arr1: any[] | null | undefined, arr2: any[] | null | undefi
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export function assignProperties(target, source) {
|
||||
for (let key in source) {
|
||||
if (source.hasOwnProperty(key)) {
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
// -----------------------------
|
||||
// Criteria Proxy
|
||||
// -----------------------------
|
||||
export function getCriteriaStateObject(criteriaType: 'businessListings' | 'commercialPropertyListings' | 'brokerListings') {
|
||||
let initialState;
|
||||
if (criteriaType === 'businessListings') {
|
||||
initialState = createEmptyBusinessListingCriteria();
|
||||
} else if (criteriaType === 'commercialPropertyListings') {
|
||||
initialState = createEmptyCommercialPropertyListingCriteria();
|
||||
} else {
|
||||
initialState = createEmptyUserListingCriteria();
|
||||
}
|
||||
const storedState = sessionStorage.getItem(`${criteriaType}`);
|
||||
return storedState ? JSON.parse(storedState) : initialState;
|
||||
}
|
||||
export function getCriteriaProxy(path: string, component: any): BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria {
|
||||
if ('businessListings' === path) {
|
||||
return createEnhancedProxy(getCriteriaStateObject('businessListings'), component);
|
||||
|
|
|
|||
Loading…
Reference in New Issue