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

Add type property to elements in the state #616

Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
31c1691
WIP
lukasrad02 Jan 19, 2023
b5a13c8
Pick specific selectors from TypeSelectorMap
lukasrad02 Jan 24, 2023
eff1ca7
Fix linter
lukasrad02 Jan 24, 2023
4e67f17
Remove type property from feature
lukasrad02 Jan 24, 2023
fb7e43c
Merge branch 'dev' into refactoring/530-there-is-no-easy-way-to-diffe…
lukasrad02 Jan 25, 2023
e577366
Fix bug after merge
lukasrad02 Jan 25, 2023
9a519a4
Rename selector map to plural map and add validation
lukasrad02 Jan 25, 2023
8783aac
Simplify featureKeys
lukasrad02 Jan 25, 2023
7cf48be
Merge branch 'dev' into refactoring/530-there-is-no-easy-way-to-diffe…
lukasrad02 Jan 25, 2023
35519dc
Fix tests by adding type property to demo objects
lukasrad02 Jan 25, 2023
7375f10
WIP: Add migration
lukasrad02 Jan 25, 2023
41e0654
Update shared/src/utils/type-state-selector-map.ts
lukasrad02 Jan 26, 2023
06b3e37
Rename file to reflect variable name change
lukasrad02 Jan 26, 2023
cc7ad9a
Replace type literals by element property
lukasrad02 Jan 26, 2023
e759288
Run prettier
lukasrad02 Jan 26, 2023
366268c
Finish migration
lukasrad02 Jan 26, 2023
70ce305
Merge branch 'dev' into refactoring/530-there-is-no-easy-way-to-diffe…
lukasrad02 Jan 26, 2023
84b8ed7
Fix migration to set correct type on EocLogEntry
lukasrad02 Jan 26, 2023
fc368d9
Make imports consistent
lukasrad02 Jan 26, 2023
38e92ca
Reuse literal union from transfer in exercise
lukasrad02 Jan 26, 2023
0815a62
Merge branch 'dev' into refactoring/530-there-is-no-easy-way-to-diffe…
lukasrad02 Jan 26, 2023
bab16ea
Fix linter
lukasrad02 Jan 26, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export class CreateImageTemplateModalComponent {
type: '[MapImageTemplate] Add mapImageTemplate',
mapImageTemplate: {
id: uuid(),
type: 'mapImageTemplate',
image: {
url,
height,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export class SendAlarmGroupInterfaceComponent implements OnDestroy {
}),
this.exerciseService.proposeAction({
type: '[Transfer] Add to transfer',
elementType: 'vehicles',
elementType: 'vehicle',
elementId: vehicleParameters.vehicle.id,
startPoint: AlarmGroupStartPoint.create(
alarmGroup.name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export class CateringLinesFeatureManager
>
implements FeatureManager<Feature<LineString>>
{
readonly type = 'cateringLines';
readonly unsupportedChangeProperties = new Set(['id'] as const);

private readonly lineStyleHelper = new LineStyleHelper(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import type {
ExerciseState,
Position,
Size,
UUID,
} from 'digital-fuesim-manv-shared';
import type { Position, Size, UUID } from 'digital-fuesim-manv-shared';
import { isArray } from 'lodash-es';
import type { MapBrowserEvent } from 'ol';
import { Feature } from 'ol';
Expand Down Expand Up @@ -83,7 +78,6 @@ export abstract class ElementFeatureManager<
>
implements FeatureManager<ElementFeature>
{
abstract override readonly type: keyof ExerciseState;
public readonly togglePopup$ = new Subject<OpenPopupOptions<any>>();
protected readonly movementAnimator = new MovementAnimator<FeatureType>(
this.olMap,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,11 @@ export abstract class ElementManager<
UnsupportedChangeProperties
> = Exclude<ReadonlySet<keyof Element>, UnsupportedChangeProperties>
> {
/**
* When an element gets (dragged &) dropped, this identifies the type of the dropped element.
* @example `patients`
*/
abstract readonly type: string;

/**
* This should be called if a new element is added.
*/
public onElementCreated(element: Element) {
const feature = this.createFeature(element);
feature.set(featureKeys.type, this.type);
feature.set(featureKeys.value, element);
}

Expand Down Expand Up @@ -117,10 +110,7 @@ export abstract class ElementManager<
): ElementFeature | undefined;

public getElementFromFeature(feature: Feature<any>) {
return {
type: feature.get(featureKeys.type),
value: feature.get(featureKeys.value),
};
return feature.get(featureKeys.value);
}

private areAllPropertiesSupported(
Expand All @@ -140,6 +130,4 @@ export abstract class ElementManager<
*/
const featureKeys = {
value: 'elementValue',
// TODO: In the future the type should be saved in the element itself
type: 'elementType',
};
Dassderdie marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ import { ImageStyleHelper } from '../utility/style-helper/image-style-helper';
import { createPoint, ElementFeatureManager } from './element-feature-manager';

export class MapImageFeatureManager extends ElementFeatureManager<MapImage> {
readonly type = 'mapImages';
private readonly imageStyleHelper = new ImageStyleHelper(
(feature) => this.getElementFromFeature(feature)!.value.image
(feature) => (this.getElementFromFeature(feature) as MapImage).image
);
private readonly popupHelper = new ImagePopupHelper(this.olMap, this.layer);

Expand Down Expand Up @@ -45,7 +44,8 @@ export class MapImageFeatureManager extends ElementFeatureManager<MapImage> {
resolution
);
style.setZIndex(
this.getElementFromFeature(feature as Feature)!.value.zIndex
(this.getElementFromFeature(feature as Feature) as MapImage)
.zIndex
);
return style;
});
Expand All @@ -68,7 +68,7 @@ export class MapImageFeatureManager extends ElementFeatureManager<MapImage> {
}

override isFeatureTranslatable(feature: Feature<Point>): boolean {
const mapImage = this.getElementFromFeature(feature).value as MapImage;
const mapImage = this.getElementFromFeature(feature) as MapImage;
return (
selectStateSnapshot(selectCurrentRole, this.store) === 'trainer' &&
!mapImage.isLocked
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@ import { createPoint, ElementFeatureManager } from './element-feature-manager';
export class MaterialFeatureManager extends ElementFeatureManager<
WithPosition<Material>
> {
readonly type = 'materials';
private readonly imageStyleHelper = new ImageStyleHelper(
(feature) => this.getElementFromFeature(feature)!.value.image
(feature) => (this.getElementFromFeature(feature) as Material).image
);
private readonly nameStyleHelper = new NameStyleHelper(
(feature) => {
const material = this.getElementFromFeature(feature)!.value;
const material = this.getElementFromFeature(feature) as Material;
return {
name: material.vehicleName,
offsetY: material.image.height / 2 / normalZoom,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@ import { createPoint, ElementFeatureManager } from './element-feature-manager';
export class PatientFeatureManager extends ElementFeatureManager<
WithPosition<Patient>
> {
readonly type = 'patients';
private readonly popupHelper = new ImagePopupHelper(this.olMap, this.layer);

private readonly imageStyleHelper = new ImageStyleHelper((feature) => {
const patient = this.getElementFromFeature(feature)!.value;
const patient = this.getElementFromFeature(feature) as Patient;
return {
...patient.image,
rotation: patient.pretriageInformation.isWalkable
Expand All @@ -36,7 +35,7 @@ export class PatientFeatureManager extends ElementFeatureManager<

private readonly circleStyleHelper = new CircleStyleHelper(
(feature) => {
const patient = this.getElementFromFeature(feature)!.value;
const patient = this.getElementFromFeature(feature) as Patient;
const configuration = selectStateSnapshot(
selectConfiguration,
this.store
Expand All @@ -59,8 +58,8 @@ export class PatientFeatureManager extends ElementFeatureManager<
},
0.025,
(feature) =>
this.getElementFromFeature(feature)!.value.pretriageInformation
.isWalkable
(this.getElementFromFeature(feature) as Patient)
.pretriageInformation.isWalkable
? [0, 0.25]
: [-0.25, 0]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@ import { createPoint, ElementFeatureManager } from './element-feature-manager';
export class PersonnelFeatureManager extends ElementFeatureManager<
WithPosition<Personnel>
> {
readonly type = 'personnel';
private readonly imageStyleHelper = new ImageStyleHelper(
(feature) => this.getElementFromFeature(feature)!.value.image
(feature) => (this.getElementFromFeature(feature) as Personnel).image
);
private readonly nameStyleHelper = new NameStyleHelper(
(feature) => {
const personnel = this.getElementFromFeature(feature)!.value;
const personnel = this.getElementFromFeature(feature) as Personnel;
return {
name: personnel.vehicleName,
offsetY: personnel.image.height / 2 / normalZoom,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ export class SimulatedRegionFeatureManager
extends ElementFeatureManager<SimulatedRegion, LineString>
implements FeatureManager<Feature<LineString>>
{
readonly type = 'simulatedRegions';

override unsupportedChangeProperties = new Set(['id'] as const);

constructor(
Expand Down Expand Up @@ -63,8 +61,9 @@ export class SimulatedRegionFeatureManager
ResizeRectangleInteraction.onResize(
feature,
({ topLeftCoordinate, scale }) => {
const currentElement = this.getElementFromFeature(feature)!
.value as SimulatedRegion;
const currentElement = this.getElementFromFeature(
feature
) as SimulatedRegion;
this.exerciseService.proposeAction(
{
type: '[SimulatedRegion] Resize simulated region',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export class TransferLinesFeatureManager
>
implements FeatureManager<Feature<LineString>>
{
readonly type = 'transferLines';
readonly unsupportedChangeProperties = new Set(['id'] as const);

constructor(public readonly layer: VectorLayer<VectorSource<LineString>>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import { NameStyleHelper } from '../utility/style-helper/name-style-helper';
import { createPoint, ElementFeatureManager } from './element-feature-manager';

export class TransferPointFeatureManager extends ElementFeatureManager<TransferPoint> {
readonly type = 'transferPoints';
private readonly popupHelper = new ImagePopupHelper(this.olMap, this.layer);

constructor(
Expand Down Expand Up @@ -61,7 +60,8 @@ export class TransferPointFeatureManager extends ElementFeatureManager<TransferP
);
private readonly nameStyleHelper = new NameStyleHelper(
(feature: Feature) => ({
name: this.getElementFromFeature(feature)!.value.internalName,
name: (this.getElementFromFeature(feature) as TransferPoint)
.internalName,
offsetY: 0,
}),
0.2,
Expand All @@ -75,14 +75,15 @@ export class TransferPointFeatureManager extends ElementFeatureManager<TransferP
) {
// TODO: droppedElement isn't necessarily a transfer point -> fix getElementFromFeature typings
const droppedElement = this.getElementFromFeature(droppedFeature);
const droppedOnTransferPoint: TransferPoint =
this.getElementFromFeature(droppedOnFeature)!.value!;
const droppedOnTransferPoint = this.getElementFromFeature(
droppedOnFeature
) as TransferPoint;
if (!droppedElement || !droppedOnTransferPoint) {
console.error('Could not find element for the features');
return false;
}
if (
droppedElement.type !== 'vehicles' &&
droppedElement.type !== 'vehicle' &&
droppedElement.type !== 'personnel'
) {
return false;
Expand All @@ -106,7 +107,7 @@ export class TransferPointFeatureManager extends ElementFeatureManager<TransferP
{
type: '[Hospital] Transport patient to hospital',
hospitalId: targetId,
vehicleId: droppedElement.value.id,
vehicleId: droppedElement.id,
},
true
);
Expand All @@ -116,7 +117,7 @@ export class TransferPointFeatureManager extends ElementFeatureManager<TransferP
{
type: '[Transfer] Add to transfer',
elementType: droppedElement.type,
elementId: droppedElement.value.id,
elementId: droppedElement.id,
startPoint: TransferStartPoint.create(
droppedOnTransferPoint.id
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,12 @@ import { createPoint, ElementFeatureManager } from './element-feature-manager';
export class VehicleFeatureManager extends ElementFeatureManager<
WithPosition<Vehicle>
> {
readonly type = 'vehicles';

private readonly imageStyleHelper = new ImageStyleHelper(
(feature) => this.getElementFromFeature(feature)!.value.image
(feature) => (this.getElementFromFeature(feature) as Vehicle).image
);
private readonly nameStyleHelper = new NameStyleHelper(
(feature) => {
const vehicle = this.getElementFromFeature(feature)!.value;
const vehicle = this.getElementFromFeature(feature) as Vehicle;
return {
name: vehicle.name,
offsetY: vehicle.image.height / 2 / normalZoom,
Expand Down Expand Up @@ -66,29 +64,26 @@ export class VehicleFeatureManager extends ElementFeatureManager<
const droppedElement = this.getElementFromFeature(droppedFeature);
const droppedOnVehicle = this.getElementFromFeature(
droppedOnFeature
) as {
type: 'vehicles';
value: Vehicle;
};
) as Vehicle;
if (!droppedElement || !droppedOnVehicle) {
console.error('Could not find element for the features');
return false;
}
if (
(droppedElement.type === 'personnel' &&
droppedOnVehicle.value.personnelIds[droppedElement.value.id]) ||
(droppedElement.type === 'materials' &&
droppedOnVehicle.value.materialIds[droppedElement.value.id]) ||
(droppedElement.type === 'patients' &&
Object.keys(droppedOnVehicle.value.patientIds).length <
droppedOnVehicle.value.patientCapacity)
droppedOnVehicle.personnelIds[droppedElement.id]) ||
(droppedElement.type === 'material' &&
droppedOnVehicle.materialIds[droppedElement.id]) ||
(droppedElement.type === 'patient' &&
Object.keys(droppedOnVehicle.patientIds).length <
droppedOnVehicle.patientCapacity)
) {
// TODO: user feedback (e.g. toast)
this.exerciseService.proposeAction(
{
type: '[Vehicle] Load vehicle',
vehicleId: droppedOnVehicle.value.id,
elementToBeLoadedId: droppedElement.value.id,
vehicleId: droppedOnVehicle.id,
elementToBeLoadedId: droppedElement.id,
elementToBeLoadedType: droppedElement.type,
},
true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ export class ViewportFeatureManager
extends ElementFeatureManager<Viewport, LineString>
implements FeatureManager<Feature<LineString>>
{
readonly type = 'viewports';

override unsupportedChangeProperties = new Set(['id'] as const);

constructor(
Expand Down Expand Up @@ -74,8 +72,9 @@ export class ViewportFeatureManager
ResizeRectangleInteraction.onResize(
feature,
({ topLeftCoordinate, scale }) => {
const currentElement = this.getElementFromFeature(feature)!
.value as Viewport;
const currentElement = this.getElementFromFeature(
feature
) as Viewport;
this.exerciseService.proposeAction(
{
type: '[Viewport] Resize viewport',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@
</td>
<td class="align-middle">
<app-transfer-target-input
[elementType]="'vehicles'"
[elementType]="'vehicle'"
[elementId]="vehicle.id"
[transfer]="vehicle.transfer"
></app-transfer-target-input>
</td>
<td class="align-middle">
<app-transfer-time-input
[elementType]="'vehicles'"
[elementType]="'vehicle'"
[elementId]="vehicle.id"
[transfer]="vehicle.transfer"
></app-transfer-time-input>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { selectTransferPoints } from 'src/app/state/application/selectors/exerci
styleUrls: ['./transfer-target-input.component.scss'],
})
export class TransferTargetInputComponent {
@Input() elementType!: 'personnel' | 'vehicles';
@Input() elementType!: 'personnel' | 'vehicle';
@Input() elementId!: UUID;
@Input() transfer!: Transfer;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { selectCurrentTime } from 'src/app/state/application/selectors/exercise.
styleUrls: ['./transfer-time-input.component.scss'],
})
export class TransferTimeInputComponent {
@Input() elementType!: 'personnel' | 'vehicles';
@Input() elementType!: 'personnel' | 'vehicle';

@Input() elementId!: UUID;

Expand Down
4 changes: 4 additions & 0 deletions shared/src/models/alarm-group.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { IsString, IsUUID } from 'class-validator';
import { UUID, uuid, uuidValidationOptions } from '../utils';
import { IsValue } from '../utils/validators';
import { IsIdMap } from '../utils/validators/is-id-map';
import { getCreate } from './utils';
import { AlarmGroupVehicle } from './utils/alarm-group-vehicle';
Expand All @@ -8,6 +9,9 @@ export class AlarmGroup {
@IsUUID(4, uuidValidationOptions)
public readonly id: UUID = uuid();

@IsValue('alarmGroup' as const)
public readonly type = 'alarmGroup';

@IsString()
public readonly name: string;

Expand Down
Loading