refactor: delete unused condition report mode

This commit is contained in:
nessar authored and Nessar committed 2026-08-17 14:18:18 +02:00
1 parent 83db663047
commit aa66fda1ca
4 files changed
+7 -301

No files matched your search

@@ -124,159 +124,3 @@
}
</section>
}
@if (!generalOnly()) {
<section>
<h2>Zones et sujets observés</h2>
@for (zone of report().zones; track zone.id; let index = $index) {
<fieldset>
<legend>{{ zone.label || 'Zone' }}</legend>
<mat-form-field appearance="outline">
<mat-label>Espace privatif</mat-label>
<mat-select
[attr.data-field-path]="'zones[' + index + '].privateAreaId'"
[attr.aria-invalid]="
fieldError('zones[' + index + '].privateAreaId') ? 'true' : null
"
[attr.aria-describedby]="
fieldError('zones[' + index + '].privateAreaId')
? errorId('zones[' + index + '].privateAreaId')
: null
"
[value]="zone.privateAreaId"
(selectionChange)="updateZone(zone.id, 'privateAreaId', $event.value)"
>
@for (area of privateAreas(); track area.id) {
<mat-option [value]="area.id">{{ area.label }}</mat-option>
}
</mat-select>
</mat-form-field>
@if (fieldError('zones[' + index + '].privateAreaId')) {
<p [id]="errorId('zones[' + index + '].privateAreaId')" class="field-error">
{{ fieldError('zones[' + index + '].privateAreaId') }}
</p>
}
<mat-form-field appearance="outline">
<mat-label>Libellé</mat-label>
<input
matInput
[attr.data-field-path]="'zones[' + index + '].label'"
[attr.aria-invalid]="
fieldError('zones[' + index + '].label') ? 'true' : null
"
[attr.aria-describedby]="
fieldError('zones[' + index + '].label')
? errorId('zones[' + index + '].label')
: null
"
required
[value]="zone.label"
(input)="updateZone(zone.id, 'label', $event)"
/>
</mat-form-field>
@if (fieldError('zones[' + index + '].label')) {
<p [id]="errorId('zones[' + index + '].label')" class="field-error">
{{ fieldError('zones[' + index + '].label') }}
</p>
}
<mat-form-field appearance="outline">
<mat-label>Équipement</mat-label>
<mat-select
[attr.data-field-path]="'zones[' + index + '].equipment'"
[attr.aria-invalid]="
fieldError('zones[' + index + '].equipment') ? 'true' : null
"
[attr.aria-describedby]="
fieldError('zones[' + index + '].equipment')
? errorId('zones[' + index + '].equipment')
: null
"
[value]="zone.equipment"
(selectionChange)="updateZone(zone.id, 'equipment', $event.value)"
>
<mat-option value="NONE">Aucun</mat-option>
<mat-option value="CLIMATISATION">Climatisation</mat-option>
<mat-option value="OTHER">Autre</mat-option>
</mat-select>
</mat-form-field>
@if (fieldError('zones[' + index + '].equipment')) {
<p [id]="errorId('zones[' + index + '].equipment')" class="field-error">
{{ fieldError('zones[' + index + '].equipment') }}
</p>
}
@if (canRemoveZone(zone.id)) {
<button mat-button color="warn" type="button" (click)="removeZone(zone.id)">
Supprimer cette zone
</button>
}
</fieldset>
}
<button mat-stroked-button type="button" (click)="addZone()">Ajouter une zone</button>
@for (
observation of report().observations;
track observation.subjectId;
let index = $index
) {
<fieldset>
<legend>{{ observationLabel(observation.subjectId) }}</legend>
<mat-form-field appearance="outline">
<mat-label>État</mat-label>
<mat-select
[attr.data-field-path]="'observations[' + index + '].state'"
[attr.aria-invalid]="
fieldError('observations[' + index + '].state') ? 'true' : null
"
[attr.aria-describedby]="
fieldError('observations[' + index + '].state')
? errorId('observations[' + index + '].state')
: null
"
[value]="observation.state"
(selectionChange)="
updateObservation(observation.subjectId, 'state', $event.value)
"
>
@for (state of states; track state) {
<mat-option [value]="state">{{ stateLabels[state] }}</mat-option>
}
</mat-select>
</mat-form-field>
@if (fieldError('observations[' + index + '].state')) {
<p [id]="errorId('observations[' + index + '].state')" class="field-error">
{{ fieldError('observations[' + index + '].state') }}
</p>
}
<mat-form-field appearance="outline">
<mat-label
>Observation{{
needsObservation(observation.state) ? ' (obligatoire)' : ''
}}</mat-label
>
<textarea
matInput
[attr.data-field-path]="'observations[' + index + '].observation'"
[attr.aria-invalid]="
fieldError('observations[' + index + '].observation') ? 'true' : null
"
[attr.aria-describedby]="
fieldError('observations[' + index + '].observation')
? errorId('observations[' + index + '].observation')
: null
"
[required]="needsObservation(observation.state)"
[value]="observation.observation"
(input)="updateObservation(observation.subjectId, 'observation', $event)"
></textarea>
</mat-form-field>
@if (fieldError('observations[' + index + '].observation')) {
<p
[id]="errorId('observations[' + index + '].observation')"
class="field-error"
>
{{ fieldError('observations[' + index + '].observation') }}
</p>
}
</fieldset>
}
</section>
}
@@ -4,10 +4,11 @@ import { ConditionReportDetailsSection } from './condition-report-details-sectio
import { workflowReport } from './condition-report-test-data';
describe('ConditionReportDetailsSection', () => {
it('updates general data, participants, addresses, zones and observations', () => {
it('updates date, participants, exit forwarding addresses and field paths', () => {
const fixture = TestBed.createComponent(ConditionReportDetailsSection);
fixture.componentRef.setInput('report', {
...structuredClone(workflowReport),
type: 'EXIT',
participants: [
{
partyId: 'tenant',
@@ -18,16 +19,6 @@ describe('ConditionReportDetailsSection', () => {
},
],
forwardingAddresses: [{ tenantPartyId: 'tenant', address: 'Old address' }],
zones: [
{
id: 'area:floor',
privateAreaId: 'area',
label: 'Cuisine — Sol',
equipment: 'NONE',
},
{ id: 'zone', privateAreaId: 'area', label: 'Fenêtre', equipment: 'OTHER' },
],
observations: [{ subjectId: 'zone', state: 'BON_ETAT', observation: '' }],
});
const changed = vi.fn();
const fieldChanged = vi.fn();
@@ -39,11 +30,6 @@ describe('ConditionReportDetailsSection', () => {
fixture.componentInstance.updateParticipant(0, 'representativeName', inputEvent('Proxy'));
fixture.componentInstance.updateForwardingAddress('tenant', inputEvent('New address'));
fixture.componentInstance.updateForwardingAddress('other', inputEvent('Other address'));
fixture.componentInstance.updateZone('zone', 'label', inputEvent('Porte'));
fixture.componentInstance.updateZone('zone', 'equipment', 'CLIMATISATION');
fixture.componentInstance.updateObservation('zone', 'state', 'DEGRADE');
fixture.componentInstance.updateObservation('zone', 'observation', inputEvent('Rayure'));
fixture.componentInstance.removeZone('zone');
const emitted = changed.mock.calls.map(([value]) => value);
expect(emitted[0]).toEqual(expect.objectContaining({ occurredOn: '2026-07-23' }));
@@ -60,35 +46,15 @@ describe('ConditionReportDetailsSection', () => {
tenantPartyId: 'other',
address: 'Other address',
});
expect(emitted[5].zones[1]).toEqual(expect.objectContaining({ label: 'Porte' }));
expect(emitted[6].zones[1]).toEqual(
expect.objectContaining({ equipment: 'CLIMATISATION' }),
);
expect(emitted[7].observations[0]).toEqual(expect.objectContaining({ state: 'DEGRADE' }));
expect(emitted[8].observations[0]).toEqual(
expect.objectContaining({ observation: 'Rayure' }),
);
expect(emitted[9]).toEqual(
expect.objectContaining({
zones: [expect.objectContaining({ id: 'area:floor' })],
observations: [],
}),
);
expect(fieldChanged).toHaveBeenCalledWith('occurredOn');
expect(fieldChanged).toHaveBeenCalledWith('participants[0].attendance');
expect(fieldChanged).toHaveBeenCalledWith('participants[0].representativeName');
expect(fieldChanged).toHaveBeenCalledWith('forwardingAddresses[0].address');
expect(fieldChanged).toHaveBeenCalledWith('forwardingAddresses[1].address');
expect(fixture.componentInstance.forwardingAddress('tenant')).toBe('Old address');
expect(fixture.componentInstance.forwardingAddress('missing')).toBe('');
expect(fixture.componentInstance.forwardingAddressIndex('tenant')).toBe(0);
expect(fixture.componentInstance.forwardingAddressIndex('missing')).toBe(1);
expect(fixture.componentInstance.canRemoveZone('zone')).toBe(true);
expect(fixture.componentInstance.canRemoveZone('area:floor')).toBe(false);
expect(fixture.componentInstance.canRemoveZone('missing')).toBe(false);
expect(fixture.componentInstance.privateAreas()).toEqual([
{ id: 'area', label: 'Cuisine' },
]);
expect(fixture.componentInstance.observationLabel('zone')).toBe('Fenêtre');
expect(fixture.componentInstance.observationLabel('missing')).toBe('Zone');
expect(fixture.componentInstance.needsObservation('DEGRADE')).toBe(true);
expect(fixture.componentInstance.needsObservation('BON_ETAT')).toBe(false);
expect(fixture.componentInstance.fieldError('missing')).toBe('');
expect(fixture.componentInstance.errorId('missing')).toBe('condition-report-error-missing');
fixture.detectChanges();
@@ -3,23 +3,12 @@ import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatSelectModule } from '@angular/material/select';
import { ConditionState, PropertyConditionReport } from '../../services/condition-report.service';
import { PropertyConditionReport } from '../../services/condition-report.service';
import {
ConditionReportFieldErrors,
conditionReportErrorId,
conditionReportFieldError,
} from './condition-report-draft-validator';
import { conditionReportStateLabels } from './condition-report-state-label';
import { isAdditionalConditionZone } from './condition-report-zone';
const states: readonly ConditionState[] = [
'NEUF',
'BON_ETAT',
'ETAT_USAGE',
'DEGRADE',
'ABSENT',
'NON_APPLICABLE',
];
@Component({
selector: 'app-condition-report-details-section',
@@ -29,12 +18,9 @@ const states: readonly ConditionState[] = [
})
export class ConditionReportDetailsSection {
readonly report = input.required<PropertyConditionReport>();
readonly generalOnly = input(false);
readonly errors = input<ConditionReportFieldErrors>({});
readonly reportChanged = output<PropertyConditionReport>();
readonly fieldChanged = output<string>();
readonly states = states;
readonly stateLabels = conditionReportStateLabels;
setOccurredOn(event: Event | string): void {
this.fieldChanged.emit('occurredOn');
@@ -89,87 +75,6 @@ export class ConditionReportDetailsSection {
return index < 0 ? this.report().forwardingAddresses.length : index;
}
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 | string,
): void {
this.fieldChanged.emit(`zones[${this.zoneIndex(id)}].${field}`);
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),
photoAbsences: report.photoAbsences.filter((absence) => absence.subjectId !== id),
}));
}
canRemoveZone(id: string): boolean {
const zone = this.report().zones.find((candidate) => candidate.id === id);
return zone ? isAdditionalConditionZone(zone) : false;
}
updateObservation(id: string, field: 'state' | 'observation', event: Event | string): void {
this.fieldChanged.emit(`observations[${this.observationIndex(id)}].${field}`);
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';
}
fieldError(path: string): string {
return conditionReportFieldError(this.errors(), path);
}
@@ -178,14 +83,6 @@ export class ConditionReportDetailsSection {
return conditionReportErrorId(path);
}
private zoneIndex(id: string): number {
return this.report().zones.findIndex((zone) => zone.id === id);
}
private observationIndex(id: string): number {
return this.report().observations.findIndex((observation) => observation.subjectId === id);
}
private update(change: (report: PropertyConditionReport) => PropertyConditionReport): void {
this.reportChanged.emit(change(this.report()));
}
@@ -46,7 +46,6 @@
</ng-template>
<app-condition-report-details-section
[report]="report()"
[generalOnly]="true"
[errors]="allFieldErrors()"
(reportChanged)="changeGeneral($event)"
(fieldChanged)="clearFieldError($event)"