Files
lmnp-organizer/frontend/src/app/services/workspace.service.ts
T

251 lines
8.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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();
});
}
}