251 lines
8.4 KiB
TypeScript
251 lines
8.4 KiB
TypeScript
import { Injectable, inject } from '@angular/core';
|
||
import { MatDialog } from '@angular/material/dialog';
|
||
import {
|
||
ConfirmationDialog,
|
||
ConfirmationDialogData,
|
||
} from '../components/confirmation-dialog/confirmation-dialog';
|
||
import { Apartment, ApartmentService } from './apartment.service';
|
||
import { FileDownloadService } from './file-download.service';
|
||
import { Lease, LeaseService } from './lease.service';
|
||
import { Tenant, TenantAttachment, TenantService } from './tenant.service';
|
||
import { TenantAttachmentTransferService } from './tenant-attachment-transfer.service';
|
||
import { WorkspaceResource } from './workspace-resource';
|
||
|
||
const newResourceKey = 'new';
|
||
|
||
@Injectable({ providedIn: 'root' })
|
||
export class WorkspaceService {
|
||
private readonly dialog = inject(MatDialog);
|
||
private readonly apartmentService = inject(ApartmentService);
|
||
private readonly tenantService = inject(TenantService);
|
||
private readonly leaseService = inject(LeaseService);
|
||
private readonly downloads = inject(FileDownloadService);
|
||
private readonly attachmentTransfers = inject(TenantAttachmentTransferService);
|
||
|
||
private readonly apartmentResource = new WorkspaceResource(
|
||
() => this.apartmentService.getApartments(),
|
||
{
|
||
load: 'Impossible de charger les appartements.',
|
||
save: 'Impossible d’enregistrer cet appartement.',
|
||
delete: 'Impossible de supprimer cet appartement.',
|
||
},
|
||
);
|
||
private readonly tenantResource = new WorkspaceResource(() => this.tenantService.getTenants(), {
|
||
load: 'Impossible de charger les locataires.',
|
||
save: 'Impossible d’enregistrer ce locataire.',
|
||
delete: 'Impossible de supprimer ce locataire.',
|
||
});
|
||
private readonly leaseResource = new WorkspaceResource(() => this.leaseService.getLeases(), {
|
||
load: 'Impossible de charger les baux.',
|
||
save: 'Impossible d’enregistrer ce bail.',
|
||
delete: 'Impossible de supprimer ce bail.',
|
||
});
|
||
|
||
readonly apartments = this.apartmentResource.items;
|
||
readonly apartmentLoadState = this.apartmentResource.loadState;
|
||
readonly deletingApartmentIds = this.apartmentResource.deletingIds;
|
||
readonly apartmentDeleteErrors = this.apartmentResource.deleteErrors;
|
||
readonly tenants = this.tenantResource.items;
|
||
readonly tenantLoadState = this.tenantResource.loadState;
|
||
readonly deletingTenantIds = this.tenantResource.deletingIds;
|
||
readonly tenantDeleteErrors = this.tenantResource.deleteErrors;
|
||
readonly leases = this.leaseResource.items;
|
||
readonly leaseLoadState = this.leaseResource.loadState;
|
||
readonly deletingLeaseIds = this.leaseResource.deletingIds;
|
||
readonly leaseDeleteErrors = this.leaseResource.deleteErrors;
|
||
|
||
readonly tenantAttachmentErrors = this.attachmentTransfers.errors;
|
||
readonly uploadingTenantIds = this.attachmentTransfers.uploadingTenantIds;
|
||
readonly tenantUploadProgress = this.attachmentTransfers.uploadProgress;
|
||
readonly deletingAttachmentIds = this.attachmentTransfers.deletingIds;
|
||
readonly attachmentDeleteErrors = this.attachmentTransfers.deleteErrors;
|
||
readonly downloadingAttachmentIds = this.attachmentTransfers.downloadingIds;
|
||
readonly attachmentDownloadErrors = this.attachmentTransfers.downloadErrors;
|
||
|
||
loadApartments(): void {
|
||
this.apartmentResource.load();
|
||
}
|
||
|
||
saveApartment(apartment: Apartment, id?: string, onSuccess?: () => void): void {
|
||
this.apartmentResource.save(
|
||
this.resourceKey(id),
|
||
id
|
||
? this.apartmentService.updateApartment(id, apartment)
|
||
: this.apartmentService.createApartment(apartment),
|
||
onSuccess,
|
||
);
|
||
}
|
||
|
||
apartmentSaving(id?: string): boolean {
|
||
return this.apartmentResource.savingKeys().has(this.resourceKey(id));
|
||
}
|
||
|
||
apartmentSaveError(id?: string): string {
|
||
return this.apartmentResource.saveErrors()[this.resourceKey(id)] ?? '';
|
||
}
|
||
|
||
clearApartmentSaveError(id?: string): void {
|
||
this.apartmentResource.clearSaveError(this.resourceKey(id));
|
||
}
|
||
|
||
deleteApartment(id: string): void {
|
||
this.requestConfirmation(
|
||
{
|
||
title: 'Supprimer cet appartement ?',
|
||
message: 'Êtes-vous sûr de vouloir supprimer cet appartement ?',
|
||
confirmLabel: 'Supprimer',
|
||
},
|
||
() => this.apartmentResource.delete(id, this.apartmentService.deleteApartment(id)),
|
||
);
|
||
}
|
||
|
||
loadTenants(): void {
|
||
this.tenantResource.load();
|
||
}
|
||
|
||
saveTenant(tenant: Tenant, id?: string, onSuccess?: () => void): void {
|
||
this.tenantResource.save(
|
||
this.resourceKey(id),
|
||
id ? this.tenantService.updateTenant(id, tenant) : this.tenantService.createTenant(tenant),
|
||
onSuccess,
|
||
);
|
||
}
|
||
|
||
tenantSaving(id?: string): boolean {
|
||
return this.tenantResource.savingKeys().has(this.resourceKey(id));
|
||
}
|
||
|
||
tenantSaveError(id?: string): string {
|
||
return this.tenantResource.saveErrors()[this.resourceKey(id)] ?? '';
|
||
}
|
||
|
||
clearTenantSaveError(id?: string): void {
|
||
this.tenantResource.clearSaveError(this.resourceKey(id));
|
||
}
|
||
|
||
deleteTenant(id: string): void {
|
||
this.requestConfirmation(
|
||
{
|
||
title: 'Supprimer ce locataire ?',
|
||
message: 'Êtes-vous sûr de vouloir supprimer ce locataire ?',
|
||
confirmLabel: 'Supprimer',
|
||
},
|
||
() => this.tenantResource.delete(id, this.tenantService.deleteTenant(id)),
|
||
);
|
||
}
|
||
|
||
uploadTenantAttachment(tenantId: string, file: File): void {
|
||
this.attachmentTransfers.upload(tenantId, file, (attachment) => {
|
||
this.tenantResource.update(tenantId, (tenant) => ({
|
||
...tenant,
|
||
attachments: [
|
||
...(tenant.attachments ?? []).filter((item) => item.id !== attachment.id),
|
||
attachment,
|
||
],
|
||
}));
|
||
this.tenantResource.load();
|
||
});
|
||
}
|
||
|
||
downloadTenantAttachment(tenantId: string, attachment: { id: string; fileName: string }): void {
|
||
this.attachmentTransfers.download(tenantId, attachment);
|
||
}
|
||
|
||
attachmentDownloading(attachmentId: string): boolean {
|
||
return this.attachmentTransfers.downloading(attachmentId);
|
||
}
|
||
|
||
attachmentDownloadError(attachmentId: string): string {
|
||
return this.attachmentTransfers.downloadError(attachmentId);
|
||
}
|
||
|
||
deleteTenantAttachment(tenantId: string, attachment: TenantAttachment): void {
|
||
this.requestConfirmation(
|
||
{
|
||
title: 'Retirer cette pièce jointe ?',
|
||
message: `Êtes-vous sûr de vouloir retirer « ${attachment.fileName} » ?`,
|
||
confirmLabel: 'Retirer',
|
||
},
|
||
() =>
|
||
this.attachmentTransfers.delete(tenantId, attachment.id, () => {
|
||
this.tenantResource.update(tenantId, (tenant) => ({
|
||
...tenant,
|
||
attachments: (tenant.attachments ?? []).filter((item) => item.id !== attachment.id),
|
||
}));
|
||
this.tenantResource.load();
|
||
}),
|
||
);
|
||
}
|
||
|
||
loadLeases(): void {
|
||
this.leaseResource.load();
|
||
}
|
||
|
||
saveLease(lease: Lease, onSuccess?: () => void): void {
|
||
this.leaseResource.save(newResourceKey, this.leaseService.createLease(lease), onSuccess);
|
||
}
|
||
|
||
leaseSaving(): boolean {
|
||
return this.leaseResource.savingKeys().has(newResourceKey);
|
||
}
|
||
|
||
leaseSaveError(): string {
|
||
return this.leaseResource.saveErrors()[newResourceKey] ?? '';
|
||
}
|
||
|
||
clearLeaseSaveError(): void {
|
||
this.leaseResource.clearSaveError(newResourceKey);
|
||
}
|
||
|
||
deleteLease(id: string): void {
|
||
this.requestConfirmation(
|
||
{
|
||
title: 'Supprimer ce bail ?',
|
||
message: 'Êtes-vous sûr de vouloir supprimer ce bail ?',
|
||
confirmLabel: 'Supprimer',
|
||
},
|
||
() => this.leaseResource.delete(id, this.leaseService.deleteLease(id)),
|
||
);
|
||
}
|
||
|
||
downloadLeasePdf(lease: Lease): void {
|
||
if (!lease.id) return;
|
||
this.downloads.download(
|
||
this.leaseDownloadKey(lease.id),
|
||
this.leaseService.downloadPdf(lease.id),
|
||
`bail-${lease.id}.pdf`,
|
||
'Impossible de télécharger ce bail.',
|
||
);
|
||
}
|
||
|
||
leaseDownloading(leaseId: string): boolean {
|
||
return this.downloads.isPending(this.leaseDownloadKey(leaseId));
|
||
}
|
||
|
||
leaseDownloadError(leaseId: string): string {
|
||
return this.downloads.error(this.leaseDownloadKey(leaseId));
|
||
}
|
||
|
||
private resourceKey(id?: string): string {
|
||
return id ?? newResourceKey;
|
||
}
|
||
|
||
private leaseDownloadKey(leaseId: string): string {
|
||
return `lease:${leaseId}`;
|
||
}
|
||
|
||
private requestConfirmation(data: ConfirmationDialogData, onConfirmed: () => void): void {
|
||
this.dialog
|
||
.open(ConfirmationDialog, {
|
||
data,
|
||
role: 'alertdialog',
|
||
width: 'min(420px, calc(100vw - 32px))',
|
||
maxWidth: 'calc(100vw - 32px)',
|
||
})
|
||
.afterClosed()
|
||
.subscribe((confirmed) => {
|
||
if (confirmed) onConfirmed();
|
||
});
|
||
}
|
||
}
|