refactor: delete unused condition report mode
This commit is contained in:
1 parent
83db663047
commit
aa66fda1ca
4 files changed
+7
-301
No files matched your search
-156
@@ -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>
|
||||
}
|
||||
+6
-40
@@ -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();
|
||||
|
||||
+1
-104
@@ -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)"
|
||||
|
||||
Reference in new issue
Block a user