diff --git a/bizmatch-server/src/file/file.service.ts b/bizmatch-server/src/file/file.service.ts index 496c341..ccc1659 100644 --- a/bizmatch-server/src/file/file.service.ts +++ b/bizmatch-server/src/file/file.service.ts @@ -128,22 +128,6 @@ export class FileService { let timeTaken = Date.now() - start; this.logger.info(`Quality: ${quality} - Time: ${timeTaken} milliseconds`); } - // getProfileImagesForUsers(userids: string) { - // const ids = userids.split(','); - // let result = {}; - // for (const id of ids) { - // result = { ...result, [id]: fs.existsSync(`./pictures/profile/${id}.avif`) }; - // } - // return result; - // } - // getCompanyLogosForUsers(userids: string) { - // const ids = userids.split(','); - // let result = {}; - // for (const id of ids) { - // result = { ...result, [id]: fs.existsSync(`./pictures/logo/${id}.avif`) }; - // } - // return result; - // } deleteImage(path: string) { fs.unlinkSync(path); } diff --git a/bizmatch-server/src/image/image.controller.ts b/bizmatch-server/src/image/image.controller.ts index 8eb26a3..0046769 100644 --- a/bizmatch-server/src/image/image.controller.ts +++ b/bizmatch-server/src/image/image.controller.ts @@ -1,4 +1,4 @@ -import { Controller, Delete, Get, Inject, Param, Post, UploadedFile, UseInterceptors } from '@nestjs/common'; +import { Controller, Delete, Inject, Param, Post, UploadedFile, UseInterceptors } from '@nestjs/common'; import { FileInterceptor } from '@nestjs/platform-express'; import { WINSTON_MODULE_PROVIDER } from 'nest-winston'; import { Logger } from 'winston'; @@ -6,9 +6,6 @@ import { FileService } from '../file/file.service.js'; import { ListingsService } from '../listings/listings.service.js'; import { SelectOptionsService } from '../select-options/select-options.service.js'; -import { commercials } from '../drizzle/schema.js'; -import { CommercialPropertyListing } from '../models/db.model.js'; - @Controller('image') export class ImageController { constructor( @@ -24,20 +21,7 @@ export class ImageController { @UseInterceptors(FileInterceptor('file')) async uploadPropertyPicture(@UploadedFile() file: Express.Multer.File, @Param('imagePath') imagePath: string, @Param('serial') serial: string) { const imagename = await this.fileService.storePropertyPicture(file, imagePath, serial); - await this.listingService.addImage(imagePath, imagename); - } - @Get(':email/:serial') - async getPropertyImagesById(@Param('email') adjustedEmail: string, @Param('serial') serial: string): Promise { - const result = await this.listingService.findByImagePath(adjustedEmail); - const listing = result as CommercialPropertyListing; - if (listing.imageOrder) { - return listing.imageOrder; - } else { - const imageOrder = await this.fileService.getPropertyImages(adjustedEmail, serial); - listing.imageOrder = imageOrder; - this.listingService.updateListing(listing.id, listing, commercials); - return imageOrder; - } + await this.listingService.addImage(imagePath, serial, imagename); } @Delete('propertyPicture/:imagePath/:serial/:imagename') async deletePropertyImagesById(@Param('imagePath') imagePath: string, @Param('serial') serial: string, @Param('imagename') imagename: string): Promise { diff --git a/bizmatch-server/src/listings/business-listings.controller.ts b/bizmatch-server/src/listings/business-listings.controller.ts index 0b087a0..7fada7b 100644 --- a/bizmatch-server/src/listings/business-listings.controller.ts +++ b/bizmatch-server/src/listings/business-listings.controller.ts @@ -34,7 +34,7 @@ export class BusinessListingsController { @Put() update(@Body() listing: any) { this.logger.info(`Save Listing`); - return this.listingsService.updateListing(listing.id, listing, businesses); + return this.listingsService.updateBusinessListing(listing.id, listing); } @Delete(':id') deleteById(@Param('id') id: string) { diff --git a/bizmatch-server/src/listings/commercial-property-listings.controller.ts b/bizmatch-server/src/listings/commercial-property-listings.controller.ts index 5641a8e..83757a2 100644 --- a/bizmatch-server/src/listings/commercial-property-listings.controller.ts +++ b/bizmatch-server/src/listings/commercial-property-listings.controller.ts @@ -38,16 +38,11 @@ export class CommercialPropertyListingsController { @Put() async update(@Body() listing: any) { this.logger.info(`Save Listing`); - return await this.listingsService.updateListing(listing.id, listing, commercials); + return await this.listingsService.updateCommercialPropertyListing(listing.id, listing); } @Delete(':id/:imagePath') deleteById(@Param('id') id: string, @Param('imagePath') imagePath: string) { this.listingsService.deleteListing(id, commercials); this.fileService.deleteDirectoryIfExists(imagePath); } - - @Put('imageOrder/:id') - async changeImageOrder(@Param('id') id: string, @Body() imageOrder: string[]) { - this.listingsService.updateImageOrder(id, imageOrder); - } } diff --git a/bizmatch-server/src/listings/listings.service.ts b/bizmatch-server/src/listings/listings.service.ts index 70c5acc..b08d98a 100644 --- a/bizmatch-server/src/listings/listings.service.ts +++ b/bizmatch-server/src/listings/listings.service.ts @@ -6,6 +6,7 @@ import { BusinessListing, CommercialPropertyListing } from 'src/models/db.model. import { Logger } from 'winston'; import * as schema from '../drizzle/schema.js'; import { PG_CONNECTION, businesses, commercials } from '../drizzle/schema.js'; +import { FileService } from '../file/file.service.js'; import { ListingCriteria } from '../models/main.model.js'; @Injectable() @@ -13,6 +14,7 @@ export class ListingsService { constructor( @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger, @Inject(PG_CONNECTION) private conn: NodePgDatabase, + private fileService: FileService, ) {} private getConditions(criteria: ListingCriteria, table: typeof businesses | typeof commercials): any[] { const conditions = []; @@ -68,11 +70,11 @@ export class ListingsService { .where(sql`${table.id} = ${id}`); return result[0] as BusinessListing | CommercialPropertyListing; } - async findByImagePath(imagePath: string): Promise { + async findByImagePath(imagePath: string, serial: string): Promise { const result = await this.conn .select() .from(commercials) - .where(sql`${commercials.imagePath} = ${imagePath}`); + .where(and(sql`${commercials.imagePath} = ${imagePath}`, sql`${commercials.serialId} = ${serial}`)); return result[0] as CommercialPropertyListing; } async findByUserId(userId: string, table: typeof businesses | typeof commercials): Promise { @@ -86,13 +88,24 @@ export class ListingsService { return createdListing as BusinessListing | CommercialPropertyListing; } - async updateListing(id: string, data: BusinessListing | CommercialPropertyListing, table: typeof businesses | typeof commercials): Promise { + async updateCommercialPropertyListing(id: string, data: CommercialPropertyListing): Promise { data.updated = new Date(); data.created = new Date(data.created); - const [updateListing] = await this.conn.update(table).set(data).where(eq(table.id, id)).returning(); + const imageOrder = await this.fileService.getPropertyImages(data.imagePath, String(data.serialId)); + let difference = imageOrder.filter(x => !data.imageOrder.includes(x)).concat(data.imageOrder.filter(x => !imageOrder.includes(x))); + if (difference.length > 0) { + this.logger.warn(`changes between image directory and imageOrder in listing ${data.serialId}: ${difference.join(',')}`); + data.imageOrder = imageOrder; + } + const [updateListing] = await this.conn.update(commercials).set(data).where(eq(commercials.id, id)).returning(); + return updateListing as BusinessListing | CommercialPropertyListing; + } + async updateBusinessListing(id: string, data: BusinessListing): Promise { + data.updated = new Date(); + data.created = new Date(data.created); + const [updateListing] = await this.conn.update(businesses).set(data).where(eq(businesses.id, id)).returning(); return updateListing as BusinessListing | CommercialPropertyListing; } - async deleteListing(id: string, table: typeof businesses | typeof commercials): Promise { await this.conn.delete(table).where(eq(table.id, id)); } @@ -106,23 +119,17 @@ export class ListingsService { // ############################################################## // Images for commercial Properties // ############################################################## - - async updateImageOrder(id: string, imageOrder: string[]) { - const listing = (await this.findById(id, commercials)) as unknown as CommercialPropertyListing; - listing.imageOrder = imageOrder; - await this.updateListing(listing.id, listing, commercials); - } async deleteImage(id: string, name: string) { const listing = (await this.findById(id, commercials)) as unknown as CommercialPropertyListing; const index = listing.imageOrder.findIndex(im => im === name); if (index > -1) { listing.imageOrder.splice(index, 1); - await this.updateListing(listing.id, listing, commercials); + await this.updateCommercialPropertyListing(listing.id, listing); } } - async addImage(imagePath: string, imagename: string) { - const listing = (await this.findByImagePath(imagePath)) as unknown as CommercialPropertyListing; + async addImage(imagePath: string, serial: string, imagename: string) { + const listing = (await this.findByImagePath(imagePath, serial)) as unknown as CommercialPropertyListing; listing.imageOrder.push(imagename); - await this.updateListing(listing.id, listing, commercials); + await this.updateCommercialPropertyListing(listing.id, listing); } } diff --git a/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.html b/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.html index 40c3baf..c4fcb8b 100644 --- a/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.html +++ b/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.html @@ -49,7 +49,7 @@
- + diff --git a/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.ts b/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.ts index e9ce3ca..050633a 100644 --- a/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.ts +++ b/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.ts @@ -27,7 +27,6 @@ import { getCriteriaStateObject, getSessionStorageHandler, map2User } from '../. styleUrl: './details-commercial-property-listing.component.scss', }) export class DetailsCommercialPropertyListingComponent { - // listings: Array; responsiveOptions = [ { breakpoint: '1199px', @@ -49,7 +48,6 @@ export class DetailsCommercialPropertyListingComponent { listing: CommercialPropertyListing; criteria: ListingCriteria; mailinfo: MailInfo; - propertyImages: string[] = []; environment = environment; user: KeycloakUser; listingUser: User; @@ -79,7 +77,6 @@ export class DetailsCommercialPropertyListingComponent { const token = await this.keycloakService.getToken(); this.user = map2User(token); this.listing = await lastValueFrom(this.listingsService.getListingById(this.id, 'commercialProperty')); - this.propertyImages = await this.imageService.getPropertyImages(this.listing.imagePath, this.listing.serialId); this.listingUser = await this.userService.getById(this.listing.userId); this.description = this.sanitizer.bypassSecurityTrustHtml(this.listing.description); } diff --git a/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.html b/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.html index 2795535..dd97b24 100644 --- a/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.html +++ b/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.html @@ -111,9 +111,9 @@
- @if (propertyImages?.length>0){ + @if (listing && listing.imageOrder?.length>0){
- @for (image of propertyImages; track image) { + @for (image of listing.imageOrder; track listing.imageOrder) {
diff --git a/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.ts b/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.ts index e04a26d..9f76dd5 100644 --- a/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.ts +++ b/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.ts @@ -63,7 +63,6 @@ export class EditCommercialPropertyListingComponent { user: User; maxFileSize = 3000000; environment = environment; - propertyImages: string[]; responsiveOptions = [ { breakpoint: '1199px', @@ -137,7 +136,6 @@ export class EditCommercialPropertyListingComponent { this.listing.description = this.data?.description; } } - this.propertyImages = await this.imageService.getPropertyImages(this.listing.imagePath, this.listing.serialId); } async save() { @@ -179,7 +177,6 @@ export class EditCommercialPropertyListingComponent { if (event.type === HttpEventType.Response) { console.log('Upload abgeschlossen', event.body); this.loadingService.stopLoading('uploadImage'); - this.propertyImages = await this.imageService.getPropertyImages(this.listing.imagePath, this.listing.serialId); this.listing = await lastValueFrom(this.listingsService.getListingById(this.id, 'commercialProperty')); } }, @@ -206,7 +203,6 @@ export class EditCommercialPropertyListingComponent { this.listing.imageOrder = this.listing.imageOrder.filter(item => item !== imageName); await Promise.all([this.imageService.deleteListingImage(this.listing.imagePath, this.listing.serialId, imageName), this.listingsService.save(this.listing, 'commercialProperty')]); this.messageService.add({ severity: 'info', summary: 'Confirmed', detail: 'Image deleted' }); - this.propertyImages = await this.imageService.getPropertyImages(this.listing.imagePath, this.listing.serialId); }, reject: () => { // this.messageService.add({ severity: 'error', summary: 'Rejected', detail: 'You have rejected' }); @@ -216,8 +212,7 @@ export class EditCommercialPropertyListingComponent { } onDrop(event: { previousIndex: number; currentIndex: number }) { - moveItemInArray(this.propertyImages, event.previousIndex, event.currentIndex); - this.listingsService.changeImageOrder(this.listing.id, this.propertyImages); + moveItemInArray(this.listing.imageOrder, event.previousIndex, event.currentIndex); } changeListingCategory(value: 'business' | 'commercialProperty') { routeListingWithState(this.router, value, this.listing); diff --git a/bizmatch/src/app/services/image.service.ts b/bizmatch/src/app/services/image.service.ts index 3bf3dff..bb1e116 100644 --- a/bizmatch/src/app/services/image.service.ts +++ b/bizmatch/src/app/services/image.service.ts @@ -37,7 +37,4 @@ export class ImageService { const adjustedEmail = emailToDirName(email); await lastValueFrom(this.http.delete<[]>(`${this.apiBaseUrl}/bizmatch/image/profile/${adjustedEmail}`)); } - async getPropertyImages(imagePath: string, serial: number): Promise { - return await lastValueFrom(this.http.get(`${this.apiBaseUrl}/bizmatch/image/${imagePath}/${serial}`)); - } } diff --git a/bizmatch/src/app/services/listings.service.ts b/bizmatch/src/app/services/listings.service.ts index c419814..49a6fcd 100644 --- a/bizmatch/src/app/services/listings.service.ts +++ b/bizmatch/src/app/services/listings.service.ts @@ -40,7 +40,4 @@ export class ListingsService { async deleteCommercialPropertyListing(id: string, imagePath: string) { await lastValueFrom(this.http.delete(`${this.apiBaseUrl}/bizmatch/listings/commercialProperty/${id}/${imagePath}`)); } - async changeImageOrder(id: string, propertyImages: string[]): Promise { - return await lastValueFrom(this.http.put(`${this.apiBaseUrl}/bizmatch/listings/commercialProperty/imageOrder/${id}`, propertyImages)); - } }