Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/963 report behavior has new collectible info about transported patients #978

Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project does **not** adhere to [Semantic Versioning](https://semver.org
- Selected material, personnel and vehicles are now highlighted on the map.
- When material or personnel is selected, the corresponding vehicle is highlighted as well.
- When a vehicle is selected, the corresponding material and personnel are highlighted as well.
- The reports behavior can generate reports on the counts of transferred patients per triage category.

### Changed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const map: { [Key in ExerciseRadiogram['type']]: string } = {
treatmentStatusRadiogram: 'Behandlungsstatus',
vehicleCountRadiogram: 'Anzahl an Fahrzeugen',
resourceRequestRadiogram: 'Anfrage nach Fahrzeugen',
transferCountsRadiogram: 'Anzahl abtransportierter Patienten',
};

@Pipe({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<h5>Transportstatus</h5>

<ng-container *appLet="radiogram$ | async as radiogram">
<p *ngIf="radiogram.scope === 'singleRegion'">Für diese Patientenablage.</p>
<p *ngIf="radiogram.scope === 'transportManagement'">
Für alle von dieser Transportorganisation verwalteten Patientenablagen.
</p>

<table class="table table-sm w-100">
<thead>
<tr>
<th>SK</th>
<th>Abtransportiert</th>
<th>Verbleibend</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let category of alwaysShowCategories">
<td>
<app-patient-status-badge [status]="category" />
</td>
<td>
{{ radiogram.transferredPatientsCounts[category] }}
</td>
<td>
{{ radiogram.remainingPatientsCounts[category] }}
</td>
</tr>
<ng-container
*ngFor="let category of showIfTransferredOrRemainingCategories"
>
<tr
*ngIf="
radiogram.transferredPatientsCounts[category] > 0 ||
radiogram.remainingPatientsCounts[category] > 0
"
>
<td>
<app-patient-status-badge [status]="category" />
</td>
<td>
{{ radiogram.transferredPatientsCounts[category] }}
</td>
<td>
{{ radiogram.remainingPatientsCounts[category] }}
</td>
</tr>
</ng-container>
<ng-container *ngFor="let category of showIfTransferredCategories">
<tr *ngIf="radiogram.transferredPatientsCounts[category] > 0">
<td>
<app-patient-status-badge [status]="category" />
</td>
<td>
{{ radiogram.transferredPatientsCounts[category] }}
</td>
<td>
{{ radiogram.remainingPatientsCounts[category] }}
</td>
</tr>
</ng-container>
</tbody>
</table>
</ng-container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { OnInit } from '@angular/core';
import { Component, Input } from '@angular/core';
import { Store } from '@ngrx/store';
import type { TransferCountsRadiogram } from 'digital-fuesim-manv-shared';
import { UUID } from 'digital-fuesim-manv-shared';
import type { Observable } from 'rxjs';
import type { AppState } from 'src/app/state/app.state';
import { createSelectRadiogram } from 'src/app/state/application/selectors/exercise.selectors';

@Component({
selector: 'app-radiogram-card-content-transfer-counts',
templateUrl: './radiogram-card-content-transfer-counts.component.html',
styleUrls: ['./radiogram-card-content-transfer-counts.component.scss'],
})
export class RadiogramCardContentTransferCountsComponent implements OnInit {
/**
* Categories that should always be listed in the table.
*/
readonly alwaysShowCategories = ['red', 'yellow', 'green'] as const;

/**
* Categories that should be listed in the table if patients of these categories have been transferred and/or are remaining.
*/
readonly showIfTransferredOrRemainingCategories = [
'blue',
'white',
] as const;

/**
* Categories that should only be listed in the table if patients of these categories have been transferred.
* (Black patients should usually never be transferred, so its okay to not show their remaining number.)
*/
readonly showIfTransferredCategories = ['black'] as const;

@Input() radiogramId!: UUID;

radiogram$!: Observable<TransferCountsRadiogram>;

constructor(private readonly store: Store<AppState>) {}

ngOnInit(): void {
this.radiogram$ = this.store.select(
createSelectRadiogram<TransferCountsRadiogram>(this.radiogramId)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,42 @@
<app-radiogram-card-content-vehicle-count
*ngSwitchCase="'vehicleCountRadiogram'"
[radiogramId]="radiogram.id"
></app-radiogram-card-content-vehicle-count>
/>
<app-radiogram-card-content-patient-count
*ngSwitchCase="'patientCountRadiogram'"
[radiogramId]="radiogram.id"
>
</app-radiogram-card-content-patient-count>
/>
<app-radiogram-card-content-treatment-status
*ngSwitchCase="'treatmentStatusRadiogram'"
[radiogramId]="radiogram.id"
></app-radiogram-card-content-treatment-status>
/>
<app-radiogram-card-content-personnel-count
*ngSwitchCase="'personnelCountRadiogram'"
[radiogramId]="radiogram.id"
></app-radiogram-card-content-personnel-count>
/>
<app-radiogram-card-content-material-count
*ngSwitchCase="'materialCountRadiogram'"
[radiogramId]="radiogram.id"
></app-radiogram-card-content-material-count>
/>
<app-radigoram-card-content-missing-transfer-connection
*ngSwitchCase="'missingTransferConnectionRadiogram'"
[radiogramId]="radiogram.id"
></app-radigoram-card-content-missing-transfer-connection>
/>
<app-radigoram-card-content-resource-request
*ngSwitchCase="'resourceRequestRadiogram'"
[radiogramId]="radiogram.id"
></app-radigoram-card-content-resource-request>
/>
<app-radiogram-card-content-transfer-counts
*ngSwitchCase="'transferCountsRadiogram'"
[radiogramId]="radiogram.id"
/>
<app-radiogram-card-content-fallback
*ngSwitchDefault
[radiogramType]="radiogram.type"
></app-radiogram-card-content-fallback>
/>
</ng-container>
<ng-template #informationUnavailable>
<app-radiogram-card-content-information-unavailable
[radiogramType]="radiogram.type"
></app-radiogram-card-content-information-unavailable>
/>
</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import { SimulatedRegionOverviewVehiclesTabComponent } from './tabs/vehicles-tab
import { SimulatedRegionOverviewPatientsTableComponent } from './patients-table/simulated-region-overview-patients-table.component';
import { StartTransferService } from './start-transfer.service';
import { SimulatedRegionOverviewBehaviorTransferVehiclesComponent } from './tabs/behavior-tab/behaviors/transfer-vehicles/simulated-region-overview-behavior-transfer-vehicles.component';
import { RadiogramCardContentTransferCountsComponent } from './radiogram-list/radiogram-card/radiogram-card-content-transfer-counts/radiogram-card-content-transfer-counts.component';

@NgModule({
declarations: [
Expand Down Expand Up @@ -90,6 +91,7 @@ import { SimulatedRegionOverviewBehaviorTransferVehiclesComponent } from './tabs
SimulatedRegionOverviewVehiclesTabComponent,
SimulatedRegionOverviewPatientsTableComponent,
SimulatedRegionOverviewBehaviorTransferVehiclesComponent,
RadiogramCardContentTransferCountsComponent,
],
imports: [
FormsModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export class SimulatedRegionOverviewBehaviorReportComponent implements OnInit {
personnelCount: 'Anzahl an Rettungskräften',
materialCount: 'Anzahl an Material',
treatmentStatus: 'Behandlungsstatus',
transferCounts: 'Anzahl der ins Krankenhaus transportierten Patienten',
};

createReportCollapsed = true;
Expand Down
3 changes: 3 additions & 0 deletions shared/src/models/radiogram/exercise-radiogram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import { Radiogram } from './radiogram';
import { TreatmentStatusRadiogram } from './treatment-status-radiogram';
import { VehicleCountRadiogram } from './vehicle-count-radiogram';
import { ResourceRequestRadiogram } from './resource-request-radiogram';
import { TransferCountsRadiogram } from './transfer-counts-radiogram';

export const radiograms = {
MaterialCountRadiogram,
MissingTransferConnectionRadiogram,
PatientCountRadiogram,
PersonnelCountRadiogram,
ResourceRequestRadiogram,
TransferCountsRadiogram,
TreatmentStatusRadiogram,
VehicleCountRadiogram,
};
Expand All @@ -33,6 +35,7 @@ export const radiogramDictionary: ExerciseRadiogramDictionary = {
patientCountRadiogram: PatientCountRadiogram,
personnelCountRadiogram: PersonnelCountRadiogram,
resourceRequestRadiogram: ResourceRequestRadiogram,
transferCountsRadiogram: TransferCountsRadiogram,
treatmentStatusRadiogram: TreatmentStatusRadiogram,
vehicleCountRadiogram: VehicleCountRadiogram,
};
Expand Down
2 changes: 2 additions & 0 deletions shared/src/models/radiogram/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ export * from './treatment-status-radiogram';
export * from './vehicle-count-radiogram';
export * from './resource-request-radiogram';
export * from './status';
export * from './transfer-counts-radiogram';
export * from './utils';
77 changes: 77 additions & 0 deletions shared/src/models/radiogram/transfer-counts-radiogram.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { IsBoolean, IsUUID, ValidateNested } from 'class-validator';
import { UUID, uuidValidationOptions } from '../../utils';
import { IsLiteralUnion, IsValue } from '../../utils/validators';
import { IsRadiogramStatus } from '../../utils/validators/is-radiogram-status';
import type { PatientStatus } from '../utils';
import { getCreate } from '../utils';
import { ResourceDescription } from '../utils/resource-description';
import { IsResourceDescription } from '../../utils/validators/is-resource-description';
import type { Radiogram } from './radiogram';
import { ExerciseRadiogramStatus } from './status/exercise-radiogram-status';
import { Scope, scopeAllowedValues } from './utils/scope';

export class TransferCountsRadiogram implements Radiogram {
@IsUUID(4, uuidValidationOptions)
readonly id: UUID;

@IsValue('transferCountsRadiogram')
readonly type = 'transferCountsRadiogram';

@IsUUID(4, uuidValidationOptions)
readonly simulatedRegionId: UUID;

/**
* @deprecated use the helpers from {@link radiogram-helpers.ts}
* or {@link radiogram-helpers-mutable.ts} instead
*/
@IsRadiogramStatus()
@ValidateNested()
readonly status: ExerciseRadiogramStatus;

@IsBoolean()
readonly informationAvailable: boolean = false;

@IsResourceDescription()
readonly transferredPatientsCounts: ResourceDescription<PatientStatus> = {
red: 0,
yellow: 0,
green: 0,
blue: 0,
black: 0,
white: 0,
};

@IsResourceDescription()
readonly remainingPatientsCounts: ResourceDescription<PatientStatus> = {
red: 0,
yellow: 0,
green: 0,
blue: 0,
black: 0,
white: 0,
};

/**
* Defines the scope of the counts reported with this radiogram.
* * `singleRegion`: The patient counts refer only to the simulated region that sent the radiogram
* * `transportManagement`: The patient counts refer to all simulated regions
* that are managed by the transport management behavior of the simulated region that sent the radiogram
*/
@IsLiteralUnion(scopeAllowedValues)
readonly scope: Scope = 'singleRegion';

/**
* @deprecated Use {@link create} instead
*/
constructor(
id: UUID,
simulatedRegionId: UUID,
status: ExerciseRadiogramStatus
) {
this.id = id;
this.simulatedRegionId = simulatedRegionId;
this.status = status;
}

static readonly create = getCreate(this);
}
1 change: 1 addition & 0 deletions shared/src/models/radiogram/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './scope';
6 changes: 6 additions & 0 deletions shared/src/models/radiogram/utils/scope.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export type Scope = 'singleRegion' | 'transportManagement';

export const scopeAllowedValues = {
singleRegion: true,
transportManagement: true,
} as const;
4 changes: 4 additions & 0 deletions shared/src/simulation/behaviors/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { TransferCountsRadiogram } from '../../models/radiogram';
import type { ExerciseRadiogram } from '../../models/radiogram/exercise-radiogram';
import { MaterialCountRadiogram } from '../../models/radiogram/material-count-radiogram';
import { PatientCountRadiogram } from '../../models/radiogram/patient-count-radiogram';
Expand All @@ -14,6 +15,7 @@ export const reportableInformationAllowedValues: AllowedValues<ReportableInforma
patientCount: true,
personnelCount: true,
vehicleCount: true,
transferCounts: true,
treatmentStatus: true,
materialCount: true,
};
Expand All @@ -26,6 +28,7 @@ export type ReportableInformation =
| 'materialCount'
| 'patientCount'
| 'personnelCount'
| 'transferCounts'
| 'treatmentStatus'
| 'vehicleCount';

Expand All @@ -39,6 +42,7 @@ export const createRadiogramMap: {
patientCount: PatientCountRadiogram.create,
personnelCount: PersonnelCountRadiogram.create,
vehicleCount: VehicleCountRadiogram.create,
transferCounts: TransferCountsRadiogram.create,
treatmentStatus: TreatmentStatusRadiogram.create,
materialCount: MaterialCountRadiogram.create,
};