diff --git a/bizmatch-server/src/models/main.model.ts b/bizmatch-server/src/models/main.model.ts
index 47de0ab..abb9c89 100644
--- a/bizmatch-server/src/models/main.model.ts
+++ b/bizmatch-server/src/models/main.model.ts
@@ -69,11 +69,11 @@ export interface ListCriteria {
state: string;
city: GeoResult;
prompt: string;
- sortBy: SortByOptions;
searchType: 'exact' | 'radius';
// radius: '5' | '20' | '50' | '100' | '200' | '300' | '400' | '500';
radius: number;
criteriaType: 'businessListings' | 'commercialPropertyListings' | 'brokerListings';
+ sortBy?: SortByOptions;
}
export interface BusinessListingCriteria extends ListCriteria {
minPrice: number;
diff --git a/bizmatch/src/app/components/header/header.component.html b/bizmatch/src/app/components/header/header.component.html
index 1a3689d..2d59435 100644
--- a/bizmatch/src/app/components/header/header.component.html
+++ b/bizmatch/src/app/components/header/header.component.html
@@ -6,32 +6,23 @@
@if(isFilterUrl()){
-
-
+
@for(item of sortByOptions; track item){
- - {{ item.selectName ? item.selectName : item.name }}
+ - {{ item.selectName ? item.selectName : item.name }}
}
@@ -217,23 +208,14 @@
-
-
diff --git a/bizmatch/src/app/components/header/header.component.ts b/bizmatch/src/app/components/header/header.component.ts
index 3d888d5..285a795 100644
--- a/bizmatch/src/app/components/header/header.component.ts
+++ b/bizmatch/src/app/components/header/header.component.ts
@@ -17,7 +17,7 @@ import { SearchService } from '../../services/search.service';
import { SelectOptionsService } from '../../services/select-options.service';
import { SharedService } from '../../services/shared.service';
import { UserService } from '../../services/user.service';
-import { assignProperties, compareObjects, createEmptyBusinessListingCriteria, createEmptyCommercialPropertyListingCriteria, createEmptyUserListingCriteria, getCriteriaProxy, map2User } from '../../utils/utils';
+import { assignProperties, createEmptyUserListingCriteria, getCriteriaProxy, map2User } from '../../utils/utils';
import { DropdownComponent } from '../dropdown/dropdown.component';
import { ModalService } from '../search-modal/modal.service';
@UntilDestroy()
@@ -49,6 +49,7 @@ export class HeaderComponent {
sortByOptions: KeyValueAsSortBy[] = [];
numberOfBroker$: Observable
;
numberOfCommercial$: Observable;
+ sortBy: SortByOptions = null; // Neu: Separate Property
constructor(
private router: Router,
private userService: UserService,
@@ -76,7 +77,7 @@ export class HeaderComponent {
this.profileUrl = this.user.hasProfile ? `${this.env.imageBaseUrl}/pictures/profile/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}` : `/assets/images/placeholder.png`;
}
this.numberOfBroker$ = this.userService.getNumberOfBroker(createEmptyUserListingCriteria());
- this.numberOfCommercial$ = this.listingService.getNumberOfListings(createEmptyCommercialPropertyListingCriteria(), 'commercialProperty');
+ this.numberOfCommercial$ = this.listingService.getNumberOfListings('commercialProperty');
setTimeout(() => {
initFlowbite();
}, 10);
@@ -87,7 +88,7 @@ export class HeaderComponent {
this.checkCurrentRoute(this.router.url);
this.setupSortByOptions();
-
+ this.loadSortBy(); // Neu
this.routerSubscription = this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe((event: any) => {
this.checkCurrentRoute(event.urlAfterRedirects);
this.setupSortByOptions();
@@ -99,31 +100,56 @@ export class HeaderComponent {
this.user = u;
});
}
+ private loadSortBy() {
+ const storedSortBy = sessionStorage.getItem(this.getSortByKey());
+ this.sortBy = storedSortBy ? (storedSortBy as SortByOptions) : null;
+ }
+
+ private saveSortBy() {
+ sessionStorage.setItem(this.getSortByKey(), this.sortBy);
+ }
+ private getSortByKey(): string {
+ // Basierend auf Route (für Business/Commercial unterscheiden)
+ if (this.isBusinessListing()) return 'businessSortBy';
+ if (this.isCommercialPropertyListing()) return 'commercialSortBy';
+ if (this.isProfessionalListing()) return 'professionalsSortBy';
+ return 'defaultSortBy'; // Fallback
+ }
+ sortByFct(selectedSortBy: SortByOptions) {
+ this.sortBy = selectedSortBy;
+ this.saveSortBy(); // Speichere separat
+ this.sortDropdownVisible = false;
+ this.searchService.search(this.criteria.criteriaType); // Neu: Übergebe sortBy separat
+ }
private checkCurrentRoute(url: string): void {
this.baseRoute = url.split('/')[1]; // Nimmt den ersten Teil der Route nach dem ersten '/'
const specialRoutes = [, '', ''];
this.criteria = getCriteriaProxy(this.baseRoute, this);
- // this.searchService.search(this.criteria);
}
setupSortByOptions() {
this.sortByOptions = [];
+ let storedSortBy = null;
if (this.isProfessionalListing()) {
this.sortByOptions = [...this.sortByOptions, ...this.selectOptions.sortByOptions.filter(s => s.type === 'professional')];
+ storedSortBy = sessionStorage.getItem('professionalsSortBy');
}
if (this.isBusinessListing()) {
this.sortByOptions = [...this.sortByOptions, ...this.selectOptions.sortByOptions.filter(s => s.type === 'business' || s.type === 'listing')];
+ storedSortBy = sessionStorage.getItem('businessSortBy');
}
if (this.isCommercialPropertyListing()) {
this.sortByOptions = [...this.sortByOptions, ...this.selectOptions.sortByOptions.filter(s => s.type === 'commercial' || s.type === 'listing')];
+ storedSortBy = sessionStorage.getItem('commercialSortBy');
}
this.sortByOptions = [...this.sortByOptions, ...this.selectOptions.sortByOptions.filter(s => !s.type)];
+ this.sortBy = storedSortBy && storedSortBy !== 'null' ? (storedSortBy as SortByOptions) : null;
}
ngAfterViewInit() {}
async openModal() {
const modalResult = await this.modalService.showModal(this.criteria);
if (modalResult.accepted) {
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
} else {
this.criteria = assignProperties(this.criteria, modalResult.criteria);
}
@@ -147,9 +173,7 @@ export class HeaderComponent {
isProfessionalListing(): boolean {
return ['/brokerListings'].includes(this.router.url);
}
- // isSortingUrl(): boolean {
- // return ['/businessListings', '/commercialPropertyListings'].includes(this.router.url);
- // }
+
closeDropdown() {
const dropdownButton = document.getElementById('user-menu-button');
const dropdownMenu = this.user ? document.getElementById('user-login') : document.getElementById('user-unknown');
@@ -180,23 +204,7 @@ export class HeaderComponent {
this.destroy$.next();
this.destroy$.complete();
}
- getNumberOfFiltersSet() {
- if (this.criteria?.criteriaType === 'brokerListings') {
- return compareObjects(createEmptyUserListingCriteria(), this.criteria, ['start', 'length', 'page', 'searchType', 'radius', 'sortBy']);
- } else if (this.criteria?.criteriaType === 'businessListings') {
- return compareObjects(createEmptyBusinessListingCriteria(), this.criteria, ['start', 'length', 'page', 'searchType', 'radius', 'sortBy']);
- } else if (this.criteria?.criteriaType === 'commercialPropertyListings') {
- return compareObjects(createEmptyCommercialPropertyListingCriteria(), this.criteria, ['start', 'length', 'page', 'searchType', 'radius', 'sortBy']);
- } else {
- return 0;
- }
- }
- sortBy(sortBy: SortByOptions) {
- this.criteria.sortBy = sortBy;
- this.sortDropdownVisible = false;
- this.searchService.search(this.criteria);
- }
toggleSortDropdown() {
this.sortDropdownVisible = !this.sortDropdownVisible;
}
diff --git a/bizmatch/src/app/components/search-modal/search-modal-commercial.component.ts b/bizmatch/src/app/components/search-modal/search-modal-commercial.component.ts
index 9ccc2b9..2a5c1f3 100644
--- a/bizmatch/src/app/components/search-modal/search-modal-commercial.component.ts
+++ b/bizmatch/src/app/components/search-modal/search-modal-commercial.component.ts
@@ -95,11 +95,11 @@ export class SearchModalCommercialComponent {
this.criteria.title = null;
break;
}
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
}
clearFilter() {
resetCommercialPropertyListingCriteria(this.criteria);
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
}
// Handle category change
onCategoryChange(event: any[]) {
@@ -116,7 +116,7 @@ export class SearchModalCommercialComponent {
this.criteria.types.splice(index, 1);
}
}
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
}
private loadCounties() {
this.counties$ = concat(
@@ -135,7 +135,7 @@ export class SearchModalCommercialComponent {
);
}
onCriteriaChange() {
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
}
setCity(city) {
if (city) {
@@ -146,7 +146,7 @@ export class SearchModalCommercialComponent {
this.criteria.radius = null;
this.criteria.searchType = 'exact';
}
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
}
setState(state: string) {
if (state) {
@@ -155,11 +155,11 @@ export class SearchModalCommercialComponent {
this.criteria.state = null;
this.setCity(null);
}
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
}
setRadius(radius: number) {
this.criteria.radius = radius;
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
}
private setupCriteriaChangeListener() {
this.criteriaChangeSubscription = this.criteriaChangeService.criteriaChange$.pipe(debounceTime(400)).subscribe(() => {
@@ -181,14 +181,14 @@ export class SearchModalCommercialComponent {
}
closeAndSearch() {
this.modalService.accept();
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
this.close();
}
setTotalNumberOfResults() {
if (this.criteria) {
console.log(`Getting total number of results for ${this.criteria.criteriaType}`);
if (this.criteria.criteriaType === 'commercialPropertyListings') {
- this.numberOfResults$ = this.listingService.getNumberOfListings(this.criteria, 'commercialProperty');
+ this.numberOfResults$ = this.listingService.getNumberOfListings('commercialProperty');
} else {
this.numberOfResults$ = of();
}
@@ -202,7 +202,7 @@ export class SearchModalCommercialComponent {
debouncedSearch() {
clearTimeout(this.debounceTimeout);
this.debounceTimeout = setTimeout(() => {
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
}, 1000);
}
}
diff --git a/bizmatch/src/app/components/search-modal/search-modal.component.ts b/bizmatch/src/app/components/search-modal/search-modal.component.ts
index ac9496f..3ef04f5 100644
--- a/bizmatch/src/app/components/search-modal/search-modal.component.ts
+++ b/bizmatch/src/app/components/search-modal/search-modal.component.ts
@@ -140,12 +140,12 @@ export class SearchModalComponent {
this.criteria.title = null;
break;
}
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
}
// Handle category change
onCategoryChange(selectedCategories: string[]) {
this.criteria.types = selectedCategories;
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
}
// Handle property type change
@@ -159,7 +159,7 @@ export class SearchModalComponent {
this.criteria[value] = true;
}
this.selectedPropertyType = value;
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
}
// Update selected property type based on current criteria
@@ -181,7 +181,7 @@ export class SearchModalComponent {
this.criteria.types.splice(index, 1);
}
}
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
}
private loadCounties() {
this.counties$ = concat(
@@ -200,7 +200,7 @@ export class SearchModalComponent {
);
}
onCriteriaChange() {
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
}
setCity(city) {
if (city) {
@@ -211,7 +211,7 @@ export class SearchModalComponent {
this.criteria.radius = null;
this.criteria.searchType = 'exact';
}
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
}
setState(state: string) {
if (state) {
@@ -220,11 +220,11 @@ export class SearchModalComponent {
this.criteria.state = null;
this.setCity(null);
}
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
}
setRadius(radius: number) {
this.criteria.radius = radius;
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
}
private setupCriteriaChangeListener() {
this.criteriaChangeSubscription = this.criteriaChangeService.criteriaChange$.pipe(debounceTime(400)).subscribe(() => {
@@ -246,7 +246,7 @@ export class SearchModalComponent {
}
closeAndSearch() {
this.modalService.accept();
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
this.close();
}
isTypeOfBusinessClicked(v: KeyValueStyle) {
@@ -259,7 +259,7 @@ export class SearchModalComponent {
if (this.criteria) {
console.log(`Getting total number of results for ${this.criteria.criteriaType}`);
if (this.criteria.criteriaType === 'businessListings' || this.criteria.criteriaType === 'commercialPropertyListings') {
- this.numberOfResults$ = this.listingService.getNumberOfListings(this.criteria, this.criteria.criteriaType === 'businessListings' ? 'business' : 'commercialProperty');
+ this.numberOfResults$ = this.listingService.getNumberOfListings(this.criteria.criteriaType === 'businessListings' ? 'business' : 'commercialProperty');
} else if (this.criteria.criteriaType === 'brokerListings') {
//this.numberOfResults$ = this.userService.getNumberOfBroker(this.criteria);
} else {
@@ -270,7 +270,7 @@ export class SearchModalComponent {
clearFilter() {
resetBusinessListingCriteria(this.criteria);
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
}
close() {
this.modalService.reject(this.backupCriteria);
@@ -282,12 +282,12 @@ export class SearchModalComponent {
// Aktivieren Sie nur die aktuell ausgewählte Checkbox
this.criteria[checkbox] = value;
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
}
debouncedSearch() {
clearTimeout(this.debounceTimeout);
this.debounceTimeout = setTimeout(() => {
- this.searchService.search(this.criteria);
+ this.searchService.search(this.criteria.criteriaType);
}, 1000);
}
}
diff --git a/bizmatch/src/app/pages/home/home.component.ts b/bizmatch/src/app/pages/home/home.component.ts
index 15b92cd..dbd5da4 100644
--- a/bizmatch/src/app/pages/home/home.component.ts
+++ b/bizmatch/src/app/pages/home/home.component.ts
@@ -5,7 +5,7 @@ import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { NgSelectModule } from '@ng-select/ng-select';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { initFlowbite } from 'flowbite';
-import { catchError, concat, debounceTime, distinctUntilChanged, lastValueFrom, Observable, of, Subject, Subscription, switchMap, tap } from 'rxjs';
+import { catchError, concat, debounceTime, distinctUntilChanged, Observable, of, Subject, Subscription, switchMap, tap } from 'rxjs';
import { BusinessListingCriteria, CityAndStateResult, CommercialPropertyListingCriteria, GeoResult, KeycloakUser, UserListingCriteria } from '../../../../../bizmatch-server/src/models/main.model';
import { ModalService } from '../../components/search-modal/modal.service';
import { TooltipComponent } from '../../components/tooltip/tooltip.component';
@@ -18,7 +18,6 @@ import { SearchService } from '../../services/search.service';
import { SelectOptionsService } from '../../services/select-options.service';
import { UserService } from '../../services/user.service';
import {
- assignProperties,
compareObjects,
createEmptyBusinessListingCriteria,
createEmptyCommercialPropertyListingCriteria,
@@ -26,6 +25,7 @@ import {
createEnhancedProxy,
getCriteriaStateObject,
map2User,
+ removeSortByStorage,
} from '../../utils/utils';
@UntilDestroy()
@Component({
@@ -86,12 +86,13 @@ export class HomeComponent {
initFlowbite();
}, 0);
this.numberOfBroker$ = this.userService.getNumberOfBroker(createEmptyUserListingCriteria());
- this.numberOfCommercial$ = this.listingService.getNumberOfListings(createEmptyCommercialPropertyListingCriteria(), 'commercialProperty');
+ this.numberOfCommercial$ = this.listingService.getNumberOfListings('commercialProperty');
const token = await this.authService.getToken();
sessionStorage.removeItem('businessListings');
sessionStorage.removeItem('commercialPropertyListings');
sessionStorage.removeItem('brokerListings');
this.criteria = createEnhancedProxy(getCriteriaStateObject('businessListings'), this);
+ removeSortByStorage();
this.user = map2User(token);
this.loadCities();
this.setupCriteriaChangeListener();
@@ -201,7 +202,7 @@ export class HomeComponent {
if (this.criteria) {
console.log(`Getting total number of results for ${this.criteria.criteriaType}`);
if (this.criteria.criteriaType === 'businessListings' || this.criteria.criteriaType === 'commercialPropertyListings') {
- this.numberOfResults$ = this.listingService.getNumberOfListings(this.criteria, this.criteria.criteriaType === 'businessListings' ? 'business' : 'commercialProperty');
+ this.numberOfResults$ = this.listingService.getNumberOfListings(this.criteria.criteriaType === 'businessListings' ? 'business' : 'commercialProperty');
} else if (this.criteria.criteriaType === 'brokerListings') {
this.numberOfResults$ = this.userService.getNumberOfBroker(this.criteria);
} else {
@@ -273,41 +274,4 @@ export class HomeComponent {
}, this.pauseTime);
}
}
- async generateAiResponse() {
- this.loadingAi = true;
- this.aiSearchFailed = false;
- try {
- const result = await this.aiService.generateAiReponse(this.aiSearchText);
- let criteria: BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria | any;
- if (result.criteriaType === 'businessListings') {
- this.changeTab('business');
- criteria = result as BusinessListingCriteria;
- } else if (result.criteriaType === 'commercialPropertyListings') {
- this.changeTab('commercialProperty');
- criteria = result as CommercialPropertyListingCriteria;
- } else {
- this.changeTab('broker');
- criteria = result as UserListingCriteria;
- }
- const city = criteria.city as string;
- if (city && city.length > 0) {
- let results = await lastValueFrom(this.geoService.findCitiesStartingWith(city, criteria.state));
- if (results.length > 0) {
- criteria.city = results[0];
- } else {
- criteria.city = null;
- }
- }
- if (criteria.radius && criteria.radius.length > 0) {
- criteria.radius = parseInt(criteria.radius);
- }
- this.loadingAi = false;
- this.criteria = assignProperties(this.criteria, criteria);
- this.search();
- } catch (error) {
- console.log(error);
- this.aiSearchFailed = true;
- this.loadingAi = false;
- }
- }
}
diff --git a/bizmatch/src/app/pages/listings/broker-listings/broker-listings.component.ts b/bizmatch/src/app/pages/listings/broker-listings/broker-listings.component.ts
index 767ff98..fb58fd5 100644
--- a/bizmatch/src/app/pages/listings/broker-listings/broker-listings.component.ts
+++ b/bizmatch/src/app/pages/listings/broker-listings/broker-listings.component.ts
@@ -3,7 +3,7 @@ import { ChangeDetectorRef, Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
-import { BusinessListing, User } from '../../../../../../bizmatch-server/src/models/db.model';
+import { BusinessListing, SortByOptions, User } from '../../../../../../bizmatch-server/src/models/db.model';
import { LISTINGS_PER_PAGE, ListingType, UserListingCriteria, emailToDirName } from '../../../../../../bizmatch-server/src/models/main.model';
import { environment } from '../../../../environments/environment';
import { CustomerSubTypeComponent } from '../../../components/customer-sub-type/customer-sub-type.component';
@@ -45,6 +45,7 @@ export class BrokerListingsComponent {
emailToDirName = emailToDirName;
page = 1;
pageCount = 1;
+ sortBy: SortByOptions = null; // Neu: Separate Property
constructor(
public selectOptions: SelectOptionsService,
private listingsService: ListingsService,
@@ -60,13 +61,19 @@ export class BrokerListingsComponent {
) {
this.criteria = getCriteriaProxy('brokerListings', this) as UserListingCriteria;
this.init();
- this.searchService.currentCriteria.pipe(untilDestroyed(this)).subscribe(criteria => {
- if (criteria && criteria.criteriaType === 'brokerListings') {
+ this.loadSortBy();
+ this.searchService.currentCriteria.pipe(untilDestroyed(this)).subscribe(({ criteria, sortBy }) => {
+ if (criteria.criteriaType === 'brokerListings') {
this.criteria = criteria as UserListingCriteria;
+ this.sortBy = sortBy || this.sortBy || null;
this.search();
}
});
}
+ private loadSortBy() {
+ const storedSortBy = sessionStorage.getItem('professionalsSortBy');
+ this.sortBy = storedSortBy && storedSortBy !== 'null' ? (storedSortBy as SortByOptions) : null;
+ }
async ngOnInit() {}
async init() {
this.search();
@@ -101,14 +108,14 @@ export class BrokerListingsComponent {
this.criteriaChangeService.notifyCriteriaChange();
// Search with cleared filters
- this.searchService.search(this.criteria);
+ this.searchService.search('brokerListings');
}
async openFilterModal() {
// Open the search modal with current criteria
const modalResult = await this.modalService.showModal(this.criteria);
if (modalResult.accepted) {
- this.searchService.search(this.criteria);
+ this.searchService.search('brokerListings');
} else {
this.criteria = assignProperties(this.criteria, modalResult.criteria);
}
diff --git a/bizmatch/src/app/pages/listings/business-listings/business-listings.component.ts b/bizmatch/src/app/pages/listings/business-listings/business-listings.component.ts
index 0a740b9..6f1fed2 100644
--- a/bizmatch/src/app/pages/listings/business-listings/business-listings.component.ts
+++ b/bizmatch/src/app/pages/listings/business-listings/business-listings.component.ts
@@ -4,7 +4,7 @@ import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import dayjs from 'dayjs';
-import { BusinessListing } from '../../../../../../bizmatch-server/src/models/db.model';
+import { BusinessListing, SortByOptions } from '../../../../../../bizmatch-server/src/models/db.model';
import { BusinessListingCriteria, LISTINGS_PER_PAGE, ListingType, emailToDirName } from '../../../../../../bizmatch-server/src/models/main.model';
import { environment } from '../../../../environments/environment';
import { PaginatorComponent } from '../../../components/paginator/paginator.component';
@@ -43,6 +43,7 @@ export class BusinessListingsComponent {
page = 1;
pageCount = 1;
emailToDirName = emailToDirName;
+ sortBy: SortByOptions = null; // Neu: Separate Property
constructor(
public selectOptions: SelectOptionsService,
private listingsService: ListingsService,
@@ -58,13 +59,19 @@ export class BusinessListingsComponent {
this.criteria = getCriteriaProxy('businessListings', this) as BusinessListingCriteria;
this.modalService.sendCriteria(this.criteria);
this.init();
- this.searchService.currentCriteria.pipe(untilDestroyed(this)).subscribe(criteria => {
- if (criteria && criteria.criteriaType === 'businessListings') {
+ this.loadSortBy();
+ this.searchService.currentCriteria.pipe(untilDestroyed(this)).subscribe(({ criteria, sortBy }) => {
+ if (criteria.criteriaType === 'businessListings') {
this.criteria = criteria as BusinessListingCriteria;
+ this.sortBy = sortBy || this.sortBy || null;
this.search();
}
});
}
+ private loadSortBy() {
+ const storedSortBy = sessionStorage.getItem('businessSortBy');
+ this.sortBy = storedSortBy && storedSortBy !== 'null' ? (storedSortBy as SortByOptions) : null;
+ }
async ngOnInit() {
this.search();
}
@@ -73,7 +80,7 @@ export class BusinessListingsComponent {
}
async search() {
- const listingReponse = await this.listingsService.getListings(this.criteria, 'business');
+ const listingReponse = await this.listingsService.getListings('business');
this.listings = listingReponse.results;
this.totalRecords = listingReponse.totalCount;
this.pageCount = this.totalRecords % LISTINGS_PER_PAGE === 0 ? this.totalRecords / LISTINGS_PER_PAGE : Math.floor(this.totalRecords / LISTINGS_PER_PAGE) + 1;
@@ -106,7 +113,7 @@ export class BusinessListingsComponent {
this.criteriaChangeService.notifyCriteriaChange();
// Search with cleared filters
- this.searchService.search(this.criteria);
+ this.searchService.search('businessListings');
}
async openFilterModal() {
@@ -114,7 +121,7 @@ export class BusinessListingsComponent {
const modalResult = await this.modalService.showModal(this.criteria);
if (modalResult.accepted) {
this.criteria = assignProperties(this.criteria, modalResult.criteria); // Update criteria with modal result
- this.searchService.search(this.criteria); // Trigger search with updated criteria
+ this.searchService.search('businessListings'); // Trigger search with updated criteria
}
}
}
diff --git a/bizmatch/src/app/pages/listings/commercial-property-listings/commercial-property-listings.component.ts b/bizmatch/src/app/pages/listings/commercial-property-listings/commercial-property-listings.component.ts
index c974f5f..d7ddf8b 100644
--- a/bizmatch/src/app/pages/listings/commercial-property-listings/commercial-property-listings.component.ts
+++ b/bizmatch/src/app/pages/listings/commercial-property-listings/commercial-property-listings.component.ts
@@ -4,7 +4,7 @@ import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import dayjs from 'dayjs';
-import { CommercialPropertyListing } from '../../../../../../bizmatch-server/src/models/db.model';
+import { CommercialPropertyListing, SortByOptions } from '../../../../../../bizmatch-server/src/models/db.model';
import { CommercialPropertyListingCriteria, LISTINGS_PER_PAGE, ResponseCommercialPropertyListingArray } from '../../../../../../bizmatch-server/src/models/main.model';
import { environment } from '../../../../environments/environment';
import { PaginatorComponent } from '../../../components/paginator/paginator.component';
@@ -43,7 +43,7 @@ export class CommercialPropertyListingsComponent {
page = 1;
pageCount = 1;
ts = new Date().getTime();
-
+ sortBy: SortByOptions = null; // Neu: Separate Property
constructor(
public selectOptions: SelectOptionsService,
private listingsService: ListingsService,
@@ -58,23 +58,25 @@ export class CommercialPropertyListingsComponent {
) {
this.criteria = getCriteriaProxy('commercialPropertyListings', this) as CommercialPropertyListingCriteria;
this.modalService.sendCriteria(this.criteria);
- this.init();
- this.searchService.currentCriteria.pipe(untilDestroyed(this)).subscribe(criteria => {
- if (criteria && criteria.criteriaType === 'commercialPropertyListings') {
+ this.loadSortBy();
+ this.searchService.currentCriteria.pipe(untilDestroyed(this)).subscribe(({ criteria, sortBy }) => {
+ if (criteria.criteriaType === 'commercialPropertyListings') {
this.criteria = criteria as CommercialPropertyListingCriteria;
+ this.sortBy = sortBy || this.sortBy || null;
this.search();
}
});
}
-
- async ngOnInit() {}
-
- async init() {
+ private loadSortBy() {
+ const storedSortBy = sessionStorage.getItem('commercialSortBy');
+ this.sortBy = storedSortBy && storedSortBy !== 'null' ? (storedSortBy as SortByOptions) : null;
+ }
+ async ngOnInit() {
this.search();
}
async search() {
- const listingReponse = await this.listingsService.getListings(this.criteria, 'commercialProperty');
+ const listingReponse = await this.listingsService.getListings('commercialProperty');
this.listings = (listingReponse).results;
this.totalRecords = (listingReponse).totalCount;
this.pageCount = this.totalRecords % LISTINGS_PER_PAGE === 0 ? this.totalRecords / LISTINGS_PER_PAGE : Math.floor(this.totalRecords / LISTINGS_PER_PAGE) + 1;
@@ -114,14 +116,14 @@ export class CommercialPropertyListingsComponent {
this.criteriaChangeService.notifyCriteriaChange();
// Search with cleared filters
- this.searchService.search(this.criteria);
+ this.searchService.search('commercialPropertyListings');
}
async openFilterModal() {
const modalResult = await this.modalService.showModal(this.criteria);
if (modalResult.accepted) {
this.criteria = assignProperties(this.criteria, modalResult.criteria); // Update criteria with modal result
- this.searchService.search(this.criteria); // Trigger search with updated criteria
+ this.searchService.search('commercialPropertyListings'); // Trigger search with updated criteria
}
}
}
diff --git a/bizmatch/src/app/services/listings.service.ts b/bizmatch/src/app/services/listings.service.ts
index 5a973d5..06bcc02 100644
--- a/bizmatch/src/app/services/listings.service.ts
+++ b/bizmatch/src/app/services/listings.service.ts
@@ -2,8 +2,9 @@ import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, lastValueFrom } from 'rxjs';
import { BusinessListing, CommercialPropertyListing } from '../../../../bizmatch-server/src/models/db.model';
-import { BusinessListingCriteria, CommercialPropertyListingCriteria, ListingType, ResponseBusinessListingArray, ResponseCommercialPropertyListingArray } from '../../../../bizmatch-server/src/models/main.model';
+import { ListingType, ResponseBusinessListingArray, ResponseCommercialPropertyListingArray } from '../../../../bizmatch-server/src/models/main.model';
import { environment } from '../../environments/environment';
+import { getCriteriaByListingCategory, getSortByListingCategory } from '../utils/utils';
@Injectable({
providedIn: 'root',
@@ -12,20 +13,21 @@ export class ListingsService {
private apiBaseUrl = environment.apiBaseUrl;
constructor(private http: HttpClient) {}
- async getListings(
- criteria: BusinessListingCriteria | CommercialPropertyListingCriteria,
- listingsCategory: 'business' | 'professionals_brokers' | 'commercialProperty',
- ): Promise {
- const result = await lastValueFrom(this.http.post(`${this.apiBaseUrl}/bizmatch/listings/${listingsCategory}/find`, criteria));
+ async getListings(listingsCategory: 'business' | 'professionals_brokers' | 'commercialProperty'): Promise {
+ const criteria = getCriteriaByListingCategory(listingsCategory);
+ const sortBy = getSortByListingCategory(listingsCategory);
+ const body = { ...criteria, sortBy }; // Merge sortBy in Body
+ const result = await lastValueFrom(this.http.post(`${this.apiBaseUrl}/bizmatch/listings/${listingsCategory}/find`, body));
return result;
}
- getNumberOfListings(criteria: BusinessListingCriteria | CommercialPropertyListingCriteria, listingsCategory: 'business' | 'commercialProperty'): Observable {
- return this.http.post(`${this.apiBaseUrl}/bizmatch/listings/${listingsCategory}/findTotal`, criteria);
- }
- async getListingsByPrompt(criteria: BusinessListingCriteria | CommercialPropertyListingCriteria): Promise {
- const result = await lastValueFrom(this.http.post(`${this.apiBaseUrl}/bizmatch/listings/business/search`, criteria));
- return result;
+
+ getNumberOfListings(listingsCategory: 'business' | 'commercialProperty'): Observable {
+ const criteria = getCriteriaByListingCategory(listingsCategory);
+ const sortBy = getSortByListingCategory(listingsCategory);
+ const body = { ...criteria, sortBy }; // Merge, falls relevant (wenn Backend sortBy für Count braucht; sonst ignorieren)
+ return this.http.post(`${this.apiBaseUrl}/bizmatch/listings/${listingsCategory}/findTotal`, body);
}
+
getListingById(id: string, listingsCategory?: 'business' | 'commercialProperty'): Observable {
const result = this.http.get(`${this.apiBaseUrl}/bizmatch/listings/${listingsCategory}/${id}`);
return result;
diff --git a/bizmatch/src/app/services/search.service.ts b/bizmatch/src/app/services/search.service.ts
index 2183cbf..1d6e1e0 100644
--- a/bizmatch/src/app/services/search.service.ts
+++ b/bizmatch/src/app/services/search.service.ts
@@ -1,17 +1,30 @@
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
+import { SortByOptions } from '../../../../bizmatch-server/src/models/db.model';
import { BusinessListingCriteria, CommercialPropertyListingCriteria, UserListingCriteria } from '../../../../bizmatch-server/src/models/main.model';
+import { getCriteriaProxy } from '../utils/utils';
@Injectable({
providedIn: 'root',
})
export class SearchService {
- private criteriaSource = new Subject();
+ private criteriaSource = new Subject<{
+ criteria: BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria;
+ sortBy?: SortByOptions;
+ }>();
currentCriteria = this.criteriaSource.asObservable();
constructor() {}
- search(criteria: BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria): void {
- this.criteriaSource.next(criteria);
+ search(criteriaType: 'businessListings' | 'commercialPropertyListings' | 'brokerListings'): void {
+ const criteria = getCriteriaProxy(criteriaType, this);
+ const storedSortBy =
+ criteriaType === 'businessListings'
+ ? sessionStorage.getItem('businessSortBy')
+ : criteriaType === 'commercialPropertyListings'
+ ? sessionStorage.getItem('commercialSortBy')
+ : sessionStorage.getItem('professionalsSortBy');
+ const sortBy = storedSortBy && storedSortBy !== 'null' ? (storedSortBy as SortByOptions) : null;
+ this.criteriaSource.next({ criteria, sortBy });
}
}
diff --git a/bizmatch/src/app/utils/utils.ts b/bizmatch/src/app/utils/utils.ts
index 9f6daa0..9279fb3 100644
--- a/bizmatch/src/app/utils/utils.ts
+++ b/bizmatch/src/app/utils/utils.ts
@@ -2,7 +2,7 @@ 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 { SortByOptions, 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';
@@ -15,7 +15,6 @@ export function createEmptyBusinessListingCriteria(): BusinessListingCriteria {
city: null,
types: [],
prompt: '',
- sortBy: null,
criteriaType: 'businessListings',
minPrice: null,
maxPrice: null,
@@ -46,7 +45,6 @@ export function createEmptyCommercialPropertyListingCriteria(): CommercialProper
city: null,
types: [],
prompt: '',
- sortBy: null,
criteriaType: 'commercialPropertyListings',
minPrice: null,
maxPrice: null,
@@ -64,7 +62,6 @@ export function createEmptyUserListingCriteria(): UserListingCriteria {
city: null,
types: [],
prompt: '',
- sortBy: null,
criteriaType: 'brokerListings',
brokerName: '',
companyName: '',
@@ -82,7 +79,6 @@ export function resetBusinessListingCriteria(criteria: BusinessListingCriteria)
criteria.city = null;
criteria.types = [];
criteria.prompt = '';
- criteria.sortBy = null;
criteria.criteriaType = 'businessListings';
criteria.minPrice = null;
criteria.maxPrice = null;
@@ -110,7 +106,6 @@ export function resetCommercialPropertyListingCriteria(criteria: CommercialPrope
criteria.city = null;
criteria.types = [];
criteria.prompt = '';
- criteria.sortBy = null;
criteria.criteriaType = 'commercialPropertyListings';
criteria.minPrice = null;
criteria.maxPrice = null;
@@ -126,7 +121,6 @@ export function resetUserListingCriteria(criteria: UserListingCriteria) {
criteria.city = null;
criteria.types = [];
criteria.prompt = '';
- criteria.sortBy = null;
criteria.criteriaType = 'brokerListings';
criteria.brokerName = '';
criteria.companyName = '';
@@ -300,6 +294,11 @@ export function checkAndUpdate(changed: boolean, condition: boolean, assignment:
}
return changed || condition;
}
+export function removeSortByStorage() {
+ sessionStorage.removeItem('businessSortBy');
+ sessionStorage.removeItem('commercialSortBy');
+ sessionStorage.removeItem('professionalsSortBy');
+}
// -----------------------------
// Criteria Proxy
// -----------------------------
@@ -341,6 +340,19 @@ export function createEnhancedProxy(obj: BusinessListingCriteria | CommercialPro
}
});
}
-// export function isAdmin(email: string) {
-// return 'andreas.knuth@gmail.com' === email;
-// }
+export function getCriteriaByListingCategory(listingsCategory: 'business' | 'professionals_brokers' | 'commercialProperty') {
+ const storedState =
+ listingsCategory === 'business'
+ ? sessionStorage.getItem('businessListings')
+ : listingsCategory === 'commercialProperty'
+ ? sessionStorage.getItem('commercialPropertyListings')
+ : sessionStorage.getItem('brokerListings');
+ return JSON.parse(storedState);
+}
+
+export function getSortByListingCategory(listingsCategory: 'business' | 'professionals_brokers' | 'commercialProperty') {
+ const storedSortBy =
+ listingsCategory === 'business' ? sessionStorage.getItem('businessSortBy') : listingsCategory === 'commercialProperty' ? sessionStorage.getItem('commercialSortBy') : sessionStorage.getItem('professionalsSortBy');
+ const sortBy = storedSortBy && storedSortBy !== 'null' ? (storedSortBy as SortByOptions) : null;
+ return sortBy;
+}