Skip to content

Commit

Permalink
WIP: Add UI for VehicleTemplate editing
Browse files Browse the repository at this point in the history
  • Loading branch information
ClFeSc committed Dec 26, 2022
1 parent 70d09e5 commit da0bf69
Show file tree
Hide file tree
Showing 17 changed files with 584 additions and 1 deletion.
6 changes: 6 additions & 0 deletions frontend/src/app/pages/exercises/exercise/exercise.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ import { ExerciseComponent } from './exercise/exercise.component';
import { AlarmGroupOverviewModule } from './shared/alarm-group-overview/alarm-group-overview.module';
import { ClientOverviewModule } from './shared/client-overview/client-overview.module';
import { CreateImageTemplateModalComponent } from './shared/editor-panel/create-image-template-modal/create-image-template-modal.component';
import { CreateVehicleTemplateModalComponent } from './shared/editor-panel/create-vehicle-template-modal/create-vehicle-template-modal.component';
import { EditImageTemplateModalComponent } from './shared/editor-panel/edit-image-template-modal/edit-image-template-modal.component';
import { EditVehicleTemplateModalComponent } from './shared/editor-panel/edit-vehicle-template-modal/edit-vehicle-template-modal.component';
import { ImageTemplateFormComponent } from './shared/editor-panel/image-template-form/image-template-form.component';
import { VehicleTemplateFormComponent } from './shared/editor-panel/vehicle-template-form/vehicle-template-form.component';
import { EmergencyOperationsCenterModule } from './shared/emergency-operations-center/emergency-operations-center.module';
import { ExerciseMapModule } from './shared/exercise-map/exercise-map.module';
import { ExerciseSettingsModalComponent } from './shared/exercise-settings/exercise-settings-modal/exercise-settings-modal.component';
Expand All @@ -30,8 +33,11 @@ import { TransferOverviewModule } from './shared/transfer-overview/transfer-over
ExerciseSettingsModalComponent,
TimeTravelComponent,
CreateImageTemplateModalComponent,
CreateVehicleTemplateModalComponent,
EditImageTemplateModalComponent,
EditVehicleTemplateModalComponent,
ImageTemplateFormComponent,
VehicleTemplateFormComponent,
],
imports: [
CommonModule,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<div class="modal-header">
<h4 class="modal-title">Fahrzeugvorlage hinzufügen</h4>
<button type="button" class="btn-close" (click)="close()"></button>
</div>
<div class="modal-body">
<app-vehicle-template-form
[initialValues]="{
url: editableVehicleTemplateValues.url,
height: editableVehicleTemplateValues.height,
name: editableVehicleTemplateValues.name,
type: editableVehicleTemplateValues.type,
patientCapacity: editableVehicleTemplateValues.patientCapacity
}"
(submitVehicleTemplate)="createImageTemplate($event)"
[btnText]="'Fahrzeugvorlage hinzufügen'"
></app-vehicle-template-form>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Component } from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { uuid } from 'digital-fuesim-manv-shared';
import { ExerciseService } from 'src/app/core/exercise.service';
import type {
ChangedVehicleTemplateValues,
EditableVehicleTemplateValues,
} from '../vehicle-template-form/vehicle-template-form.component';

@Component({
selector: 'app-create-vehicle-template-modal',
templateUrl: './create-vehicle-template-modal.component.html',
styleUrls: ['./create-vehicle-template-modal.component.scss'],
})
export class CreateVehicleTemplateModalComponent {
public readonly editableVehicleTemplateValues: EditableVehicleTemplateValues =
{
url: null,
height: 100,
name: null,
patientCapacity: 1,
type: null,
};

constructor(
public readonly activeModal: NgbActiveModal,
private readonly exerciseService: ExerciseService
) {}

public createImageTemplate({
url,
height,
name,
aspectRatio,
patientCapacity,
type,
}: ChangedVehicleTemplateValues) {
this.exerciseService
.proposeAction({
type: '[VehicleTemplate] Add vehicleTemplate',
vehicleTemplate: {
id: uuid(),
image: {
url,
height,
aspectRatio,
},
name,
materials: ['standard'],
patientCapacity,
personnel: ['rettSan'],
vehicleType: type,
},
})
.then((response) => {
if (response.success) {
this.close();
}
});
}

public close() {
this.activeModal.close();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { CreateVehicleTemplateModalComponent } from './create-vehicle-template-modal.component';

export async function openCreateVehicleTemplateModal(
ngbModalService: NgbModal
) {
ngbModalService.open(CreateVehicleTemplateModalComponent);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<div class="modal-header">
<h4 class="modal-title">Fahrzeugvorlage bearbeiten</h4>
<button type="button" class="btn-close" (click)="close()"></button>
</div>
<div *ngIf="vehicleTemplate" class="modal-body">
<app-vehicle-template-form
[initialValues]="{
name: vehicleTemplate.name,
type: vehicleTemplate.vehicleType,
url: vehicleTemplate.image.url,
height: vehicleTemplate.image.height,
patientCapacity: vehicleTemplate.patientCapacity
}"
(submitVehicleTemplate)="editVehicleTemplate($event)"
[btnText]="'Speichern'"
></app-vehicle-template-form>

<button class="btn btn-danger float-end" (click)="deleteVehicleTemplate()">
<i class="bi bi-trash-fill"></i>
Löschen
</button>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import type { OnInit } from '@angular/core';
import { Component } from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { Store } from '@ngrx/store';
import type {
UUID,
Mutable,
VehicleTemplate,
} from 'digital-fuesim-manv-shared';
import { cloneDeepMutable } from 'digital-fuesim-manv-shared';
import { ExerciseService } from 'src/app/core/exercise.service';
import type { AppState } from 'src/app/state/app.state';
import { createSelectVehicleTemplate } from 'src/app/state/application/selectors/exercise.selectors';
import { selectStateSnapshot } from 'src/app/state/get-state-snapshot';
import type { ChangedVehicleTemplateValues } from '../vehicle-template-form/vehicle-template-form.component';

@Component({
selector: 'app-edit-vehicle-template-modal',
templateUrl: './edit-vehicle-template-modal.component.html',
styleUrls: ['./edit-vehicle-template-modal.component.scss'],
})
export class EditVehicleTemplateModalComponent implements OnInit {
// This is set after the modal creation and therefore accessible in ngOnInit
public vehicleTemplateId!: UUID;

public vehicleTemplate?: Mutable<VehicleTemplate>;

constructor(
private readonly exerciseService: ExerciseService,
private readonly store: Store<AppState>,
public readonly activeModal: NgbActiveModal
) {}

ngOnInit(): void {
this.vehicleTemplate = cloneDeepMutable(
selectStateSnapshot(
createSelectVehicleTemplate(this.vehicleTemplateId),
this.store
)
);
}

public deleteVehicleTemplate(): void {
this.exerciseService
.proposeAction({
type: '[VehicleTemplate] Delete vehicleTemplates',
id: this.vehicleTemplateId,
})
.then((response) => {
if (response.success) {
this.close();
}
});
}

public editVehicleTemplate({
url,
height,
name,
aspectRatio,
patientCapacity,
type,
}: ChangedVehicleTemplateValues): void {
if (!this.vehicleTemplate) {
console.error("VehicleTemplate wasn't initialized yet");
return;
}
this.exerciseService
.proposeAction({
type: '[VehicleTemplate] Edit vehicleTemplate',
id: this.vehicleTemplateId,
name,
image: {
url,
height,
aspectRatio,
},
materials: this.vehicleTemplate.materials,
patientCapacity,
personnelTypes: this.vehicleTemplate.personnel,
vehicleType: type,
})
.then((response) => {
if (response.success) {
this.close();
}
});
}

public close(): void {
this.activeModal.close();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import type { UUID } from 'digital-fuesim-manv-shared';
import { EditVehicleTemplateModalComponent } from './edit-vehicle-template-modal.component';

export async function openEditVehicleTemplateModal(
ngbModalService: NgbModal,
vehicleTemplateId: UUID
) {
const modalRef = ngbModalService.open(EditVehicleTemplateModalComponent);
const componentInstance =
modalRef.componentInstance as EditVehicleTemplateModalComponent;
componentInstance.vehicleTemplateId = vehicleTemplateId;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<ng-container *ngIf="values">
<div class="form-group mb-3">
<label class="form-label">Standardname von neuen Fahrzeugen:</label>
<input
#nameInput="ngModel"
[(ngModel)]="values.name"
required
type="text"
class="form-control"
placeholder="Fahrzeugname"
/>
<app-display-validation
[ngModelInput]="nameInput"
></app-display-validation>
</div>
<div class="form-group mb-3">
<label class="form-label">Typ:</label>
<input
#typeInput="ngModel"
[(ngModel)]="values.type"
required
type="text"
class="form-control"
placeholder="Fahrzeugtyp"
/>
<app-display-validation
[ngModelInput]="typeInput"
></app-display-validation>
</div>
<div class="form-group mb-3">
<label class="form-label">Bildadresse:</label>
<input
#imageUrlInput="ngModel"
[(ngModel)]="values.url"
[appAutofocus]="true"
appImageExistsValidator
required
type="url"
class="form-control"
placeholder="https://example.com/image.png"
/>
<app-display-validation
[ngModelInput]="imageUrlInput"
></app-display-validation>
</div>
<div class="form-group mb-3">
<label class="form-label">Bildhöhe:</label>
<input
#heightInput="ngModel"
[(ngModel)]="values.height"
required
min="1"
step="1"
appIntegerValidator
type="number"
class="form-control"
placeholder="100"
/>
<app-display-validation
[ngModelInput]="heightInput"
></app-display-validation>
</div>
<div class="form-group mb-3">
<label class="form-label">Patientenkapazität:</label>
<input
#patientCapacityInput="ngModel"
[(ngModel)]="values.patientCapacity"
required
min="0"
step="1"
appIntegerValidator
type="number"
class="form-control"
placeholder="1"
/>
<app-display-validation
[ngModelInput]="patientCapacityInput"
></app-display-validation>
</div>

<!-- If the button is not disabled the imageTemplate is correct -->
<button
(click)="submit()"
[disabled]="
nameInput.invalid ||
typeInput.invalid ||
imageUrlInput.invalid ||
heightInput.invalid ||
patientCapacityInput.invalid
"
class="btn btn-primary"
>
{{ btnText }}
</button>
</ng-container>
Loading

0 comments on commit da0bf69

Please sign in to comment.