Files
lmnp-organizer/frontend/src/app/components/condition-report-page/condition-report-details-section.ts
T
nessar 878da155bd chore: add husky pre-commit hook and lint-staged configuration
- Created a pre-commit hook in .husky to run lint-staged.
- Added .lintstagedrc.mjs to format frontend files with Prettier and apply Spotless to backend Java files.
- Introduced .prettierignore to exclude specific directories from formatting.
2026-08-17 14:18:16 +02:00

134 lines
3.6 KiB
TypeScript

import { Component, input, output } from '@angular/core';
import { ConditionState, PropertyConditionReport } from '../../services/condition-report.service';
const states: readonly ConditionState[] = [
'NEUF',
'BON_ETAT',
'ETAT_USAGE',
'DEGRADE',
'ABSENT',
'NON_APPLICABLE',
];
@Component({
selector: 'app-condition-report-details-section',
templateUrl: './condition-report-details-section.html',
styleUrl: './condition-report-page.css',
})
export class ConditionReportDetailsSection {
readonly report = input.required<PropertyConditionReport>();
readonly reportChanged = output<PropertyConditionReport>();
readonly states = states;
setOccurredOn(event: Event): void {
this.update((report) => ({ ...report, occurredOn: this.value(event) }));
}
setTimeZone(event: Event): void {
this.update((report) => ({ ...report, timeZone: this.value(event) }));
}
updateParticipant(
index: number,
field: 'attendance' | 'representativeName',
event: Event,
): void {
this.update((report) => ({
...report,
participants: report.participants.map((participant, item) =>
item === index ? { ...participant, [field]: this.value(event) } : participant,
),
}));
}
addZone(): void {
const id = crypto.randomUUID();
this.update((report) => ({
...report,
zones: [
...report.zones,
{
id,
privateAreaId: this.privateAreas()[0]?.id ?? '',
label: '',
equipment: 'NONE',
},
],
observations: [
...report.observations,
{ subjectId: id, state: 'BON_ETAT', observation: '' },
],
}));
}
updateZone(id: string, field: 'privateAreaId' | 'label' | 'equipment', event: Event): void {
this.update((report) => ({
...report,
zones: report.zones.map((zone) =>
zone.id === id ? { ...zone, [field]: this.value(event) } : zone,
),
}));
}
removeZone(id: string): void {
this.update((report) => ({
...report,
zones: report.zones.filter((zone) => zone.id !== id),
observations: report.observations.filter((observation) => observation.subjectId !== id),
zonePhotoAbsences: report.zonePhotoAbsences.filter((absence) => absence.zoneId !== id),
}));
}
canRemoveZone(id: string): boolean {
return (
!id.startsWith('inventory:') &&
![':floor', ':walls', ':ceiling'].some((suffix) => id.endsWith(suffix))
);
}
updateObservation(id: string, field: 'state' | 'observation', event: Event): void {
this.update((report) => ({
...report,
observations: report.observations.map((observation) =>
observation.subjectId === id
? { ...observation, [field]: this.value(event) }
: observation,
),
}));
}
needsObservation(state: ConditionState): boolean {
return ['DEGRADE', 'ABSENT', 'NON_APPLICABLE'].includes(state);
}
privateAreas(): { id: string; label: string }[] {
const areas = new Map<string, string>();
for (const zone of this.report().zones) {
if (!zone.privateAreaId || areas.has(zone.privateAreaId)) continue;
const separator = zone.label.indexOf(' — ');
areas.set(
zone.privateAreaId,
separator < 0 ? zone.privateAreaId : zone.label.slice(0, separator),
);
}
return [...areas].map(([id, label]) => ({ id, label }));
}
observationLabel(subjectId: string): string {
return this.report().zones.find((zone) => zone.id === subjectId)?.label || 'Zone';
}
private update(change: (report: PropertyConditionReport) => PropertyConditionReport): void {
this.reportChanged.emit(change(this.report()));
}
private value(event: Event): string {
const target = event.target;
return target instanceof HTMLInputElement ||
target instanceof HTMLSelectElement ||
target instanceof HTMLTextAreaElement
? target.value
: '';
}
}