From c3c0d1526ca9de234e2434cae56776974e0cf053 Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Wed, 25 Jan 2023 12:54:09 +0100 Subject: [PATCH 01/22] Add MetaPosition Helpers --- shared/src/data/dummy-objects/patient.ts | 2 +- shared/src/models/utils/index.ts | 13 ++-- .../utils/{ => position}/map-coordinates.ts | 2 +- .../utils/{ => position}/map-position.ts | 12 ++- .../utils/position/meta-position-helpers.ts | 76 +++++++++++++++++++ .../utils/{ => position}/meta-position.ts | 0 .../position/simulated-region-position.ts | 35 +++++++++ .../utils/position/transfer-position.ts | 37 +++++++++ .../models/utils/position/vehicle-position.ts | 35 +++++++++ .../utils/position/with-meta-position.ts | 5 ++ .../models/utils/simulated-region-position.ts | 19 ----- shared/src/models/utils/transfer-position.ts | 23 ------ shared/src/models/utils/vehicle-position.ts | 21 ----- .../src/utils/validators/is-metaposition.ts | 2 +- 14 files changed, 208 insertions(+), 74 deletions(-) rename shared/src/models/utils/{ => position}/map-coordinates.ts (89%) rename shared/src/models/utils/{ => position}/map-position.ts (57%) create mode 100644 shared/src/models/utils/position/meta-position-helpers.ts rename shared/src/models/utils/{ => position}/meta-position.ts (100%) create mode 100644 shared/src/models/utils/position/simulated-region-position.ts create mode 100644 shared/src/models/utils/position/transfer-position.ts create mode 100644 shared/src/models/utils/position/vehicle-position.ts create mode 100644 shared/src/models/utils/position/with-meta-position.ts delete mode 100644 shared/src/models/utils/simulated-region-position.ts delete mode 100644 shared/src/models/utils/transfer-position.ts delete mode 100644 shared/src/models/utils/vehicle-position.ts diff --git a/shared/src/data/dummy-objects/patient.ts b/shared/src/data/dummy-objects/patient.ts index 7fd5fc3c6..7516a0b44 100644 --- a/shared/src/data/dummy-objects/patient.ts +++ b/shared/src/data/dummy-objects/patient.ts @@ -1,5 +1,5 @@ import { FunctionParameters, Patient, PatientHealthState } from '../../models'; -import { MapCoordinates } from '../../models/utils/map-coordinates'; +import { MapCoordinates } from '../../models/utils/position/map-coordinates'; import { MapPosition } from '../../models/utils/map-position'; import { PatientStatusCode } from '../../models/utils/patient-status-code'; import { defaultPatientCategories } from '../default-state/patient-templates'; diff --git a/shared/src/models/utils/index.ts b/shared/src/models/utils/index.ts index 3f5f846fd..756a4270d 100644 --- a/shared/src/models/utils/index.ts +++ b/shared/src/models/utils/index.ts @@ -1,10 +1,11 @@ export { Position } from './position'; -export { MetaPosition } from './meta-position'; -export { MapPosition } from './map-position'; -export { VehiclePosition } from './vehicle-position'; -export { TransferPosition } from './transfer-position'; -export { SimulatedRegionPosition } from './simulated-region-position'; -export { MapCoordinates } from './map-coordinates'; +export { MetaPosition } from './/position/meta-position'; +export { MapPosition } from './position/map-position'; +export { VehiclePosition } from './position/vehicle-position'; +export { TransferPosition } from './position/transfer-position'; +export { SimulatedRegionPosition } from './position/simulated-region-position'; +export { MapCoordinates } from './position/map-coordinates'; +export * from './position/meta-position-helpers'; export * from './patient-status'; export { Size } from './size'; export { Role } from './role'; diff --git a/shared/src/models/utils/map-coordinates.ts b/shared/src/models/utils/position/map-coordinates.ts similarity index 89% rename from shared/src/models/utils/map-coordinates.ts rename to shared/src/models/utils/position/map-coordinates.ts index cab5696bd..75963fef0 100644 --- a/shared/src/models/utils/map-coordinates.ts +++ b/shared/src/models/utils/position/map-coordinates.ts @@ -1,5 +1,5 @@ import { IsNumber } from 'class-validator'; -import { getCreate } from './get-create'; +import { getCreate } from '../get-create'; export class MapCoordinates { @IsNumber() diff --git a/shared/src/models/utils/map-position.ts b/shared/src/models/utils/position/map-position.ts similarity index 57% rename from shared/src/models/utils/map-position.ts rename to shared/src/models/utils/position/map-position.ts index 726e0525f..aca939f1f 100644 --- a/shared/src/models/utils/map-position.ts +++ b/shared/src/models/utils/position/map-position.ts @@ -1,13 +1,21 @@ import { Type } from 'class-transformer'; import { ValidateNested } from 'class-validator'; -import { IsValue } from '../../utils/validators'; -import { getCreate } from './get-create'; +import { IsValue } from '../../../utils/validators'; +import { getCreate } from '../get-create'; import { MapCoordinates } from './map-coordinates'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { isOnMap, isNotOnMap, coordinatesOf } from './meta-position-helpers'; export class MapPosition { + /** + * @deprecated Use {@link isOnMap } or {@link isNotOnMap} instead + */ @IsValue('coordinates') public readonly type = 'coordinates'; + /** + * @deprecated Use {@link coordinatesOf} instead + */ @Type(() => MapCoordinates) @ValidateNested() public readonly position: MapCoordinates; diff --git a/shared/src/models/utils/position/meta-position-helpers.ts b/shared/src/models/utils/position/meta-position-helpers.ts new file mode 100644 index 000000000..123e7afc4 --- /dev/null +++ b/shared/src/models/utils/position/meta-position-helpers.ts @@ -0,0 +1,76 @@ +import type { UUID } from '../../../utils'; +import type { Transfer } from '../transfer'; +import type { MapCoordinates } from './map-coordinates'; +import type { MapPosition } from './map-position'; +import type { SimulatedRegionPosition } from './simulated-region-position'; +import type { TransferPosition } from './transfer-position'; +import type { VehiclePosition } from './vehicle-position'; +import type { WithMetaPosition } from './with-meta-position'; + +export function isOnMap(withMetaPosition: WithMetaPosition): boolean { + return withMetaPosition.metaPosition.type === 'coordinates'; +} +export function isInVehicle(withMetaPosition: WithMetaPosition): boolean { + return withMetaPosition.metaPosition.type === 'vehicle'; +} +export function isInTransfer(withMetaPosition: WithMetaPosition): boolean { + return withMetaPosition.metaPosition.type === 'transfer'; +} +export function isInSimulatedRegion( + withMetaPosition: WithMetaPosition +): boolean { + return withMetaPosition.metaPosition.type === 'simulatedRegion'; +} +export function isNotOnMap(withMetaPosition: WithMetaPosition): boolean { + return !isOnMap(withMetaPosition); +} +export function isNotInVehicle(withMetaPosition: WithMetaPosition): boolean { + return !isInVehicle(withMetaPosition); +} +export function isNotInTransfer(withMetaPosition: WithMetaPosition): boolean { + return !isInVehicle(withMetaPosition); +} +export function isNotInSimulatedRegion( + withMetaPosition: WithMetaPosition +): boolean { + return !isInSimulatedRegion(withMetaPosition); +} + +export function coordinatesOf( + withMetaPosition: WithMetaPosition +): MapCoordinates { + if (isOnMap(withMetaPosition)) { + return (withMetaPosition.metaPosition as MapPosition).position; + } + throw new TypeError( + `Expected metaPosition of object to be on Map. Was of type ${withMetaPosition.metaPosition.type}.` + ); +} + +export function vehicleItsIn(withMetaPosition: WithMetaPosition): UUID { + if (isInVehicle(withMetaPosition)) { + return (withMetaPosition.metaPosition as VehiclePosition).vehicleId; + } + throw new TypeError( + `Expected metaPosition of object to be in vehicle. Was of type ${withMetaPosition.metaPosition.type}.` + ); +} + +export function transferItsIn(withMetaPosition: WithMetaPosition): Transfer { + if (isInTransfer(withMetaPosition)) { + return (withMetaPosition.metaPosition as TransferPosition).transfer; + } + throw new TypeError( + `Expected metaPosition of object to be in transfer. Was of type ${withMetaPosition.metaPosition.type}.` + ); +} + +export function simulatedRegionItsIn(withMetaPosition: WithMetaPosition): UUID { + if (isInSimulatedRegion(withMetaPosition)) { + return (withMetaPosition.metaPosition as SimulatedRegionPosition) + .simulatedRegionId; + } + throw new TypeError( + `Expected metaPosition of object to be in simulatedRegion. Was of type ${withMetaPosition.metaPosition.type}.` + ); +} diff --git a/shared/src/models/utils/meta-position.ts b/shared/src/models/utils/position/meta-position.ts similarity index 100% rename from shared/src/models/utils/meta-position.ts rename to shared/src/models/utils/position/meta-position.ts diff --git a/shared/src/models/utils/position/simulated-region-position.ts b/shared/src/models/utils/position/simulated-region-position.ts new file mode 100644 index 000000000..bd880f28e --- /dev/null +++ b/shared/src/models/utils/position/simulated-region-position.ts @@ -0,0 +1,35 @@ +import { IsUUID } from 'class-validator'; +import { UUID } from '../../../utils'; +import { IsValue } from '../../../utils/validators'; +import { getCreate } from '../get-create'; +import { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + isInSimulatedRegion, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + isNotInSimulatedRegion, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + simulatedRegionItsIn, +} from './meta-position-helpers'; + +export class SimulatedRegionPosition { + /** + * @deprecated Use {@link isInSimulatedRegion } or {@link isNotInSimulatedRegion} instead + */ + @IsValue('simulatedRegion') + public readonly type = 'simulatedRegion'; + + /** + * @deprecated Use {@link simulatedRegionItsIn } instead + */ + @IsUUID() + public readonly simulatedRegionId: UUID; + + /** + * @deprecated Use {@link create} instead + */ + constructor(simulatedRegionId: UUID) { + this.simulatedRegionId = simulatedRegionId; + } + + static readonly create = getCreate(this); +} diff --git a/shared/src/models/utils/position/transfer-position.ts b/shared/src/models/utils/position/transfer-position.ts new file mode 100644 index 000000000..a6babc1d5 --- /dev/null +++ b/shared/src/models/utils/position/transfer-position.ts @@ -0,0 +1,37 @@ +import { Type } from 'class-transformer'; +import { ValidateNested } from 'class-validator'; +import { IsValue } from '../../../utils/validators'; +import { getCreate } from '../get-create'; +import { Transfer } from '../transfer'; +import { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + isInTransfer, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + isNotInTransfer, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + transferItsIn, +} from './meta-position-helpers'; + +export class TransferPosition { + /** + * @deprecated Use {@link isInTransfer } or {@link isNotInTransfer} instead + */ + @IsValue('transfer') + public readonly type = 'transfer'; + + /** + * @deprecated Use {@link transferItsIn } instead + */ + @Type(() => Transfer) + @ValidateNested() + public readonly transfer: Transfer; + + /** + * @deprecated Use {@link create} instead + */ + constructor(transfer: Transfer) { + this.transfer = transfer; + } + + static readonly create = getCreate(this); +} diff --git a/shared/src/models/utils/position/vehicle-position.ts b/shared/src/models/utils/position/vehicle-position.ts new file mode 100644 index 000000000..9b5711461 --- /dev/null +++ b/shared/src/models/utils/position/vehicle-position.ts @@ -0,0 +1,35 @@ +import { IsUUID } from 'class-validator'; +import { UUID } from '../../../utils'; +import { IsValue } from '../../../utils/validators'; +import { getCreate } from '../get-create'; +import { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + isInVehicle, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + isNotInVehicle, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + vehicleItsIn, +} from './meta-position-helpers'; + +export class VehiclePosition { + /** + * @deprecated Use {@link isInVehicle } or {@link isNotInVehicle} instead + */ + @IsValue('vehicle') + public readonly type = 'vehicle'; + + /** + * @deprecated Use {@link vehicleItsIn } instead + */ + @IsUUID() + public readonly vehicleId: UUID; + + /** + * @deprecated Use {@link create} instead + */ + constructor(vehicleId: UUID) { + this.vehicleId = vehicleId; + } + + static readonly create = getCreate(this); +} diff --git a/shared/src/models/utils/position/with-meta-position.ts b/shared/src/models/utils/position/with-meta-position.ts new file mode 100644 index 000000000..790aa0df7 --- /dev/null +++ b/shared/src/models/utils/position/with-meta-position.ts @@ -0,0 +1,5 @@ +import type { MetaPosition } from './meta-position'; + +export interface WithMetaPosition { + metaPosition: MetaPosition; +} diff --git a/shared/src/models/utils/simulated-region-position.ts b/shared/src/models/utils/simulated-region-position.ts deleted file mode 100644 index d797cdc66..000000000 --- a/shared/src/models/utils/simulated-region-position.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { UUID } from '../../utils'; -import { IsValue } from '../../utils/validators'; -import { getCreate } from './get-create'; - -export class SimulatedRegionPosition { - @IsValue('simulatedRegion') - public readonly type = 'simulatedRegion'; - - public readonly simulatedRegionId: UUID; - - /** - * @deprecated Use {@link create} instead - */ - constructor(simulatedRegionId: UUID) { - this.simulatedRegionId = simulatedRegionId; - } - - static readonly create = getCreate(this); -} diff --git a/shared/src/models/utils/transfer-position.ts b/shared/src/models/utils/transfer-position.ts deleted file mode 100644 index 26e9b1a43..000000000 --- a/shared/src/models/utils/transfer-position.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Type } from 'class-transformer'; -import { ValidateNested } from 'class-validator'; -import { IsValue } from '../../utils/validators'; -import { getCreate } from './get-create'; -import { Transfer } from './transfer'; - -export class TransferPosition { - @IsValue('transfer') - public readonly type = 'transfer'; - - @Type(() => Transfer) - @ValidateNested() - public readonly transfer: Transfer; - - /** - * @deprecated Use {@link create} instead - */ - constructor(transfer: Transfer) { - this.transfer = transfer; - } - - static readonly create = getCreate(this); -} diff --git a/shared/src/models/utils/vehicle-position.ts b/shared/src/models/utils/vehicle-position.ts deleted file mode 100644 index 80970ae93..000000000 --- a/shared/src/models/utils/vehicle-position.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { IsUUID } from 'class-validator'; -import { UUID } from '../../utils'; -import { IsValue } from '../../utils/validators'; -import { getCreate } from './get-create'; - -export class VehiclePosition { - @IsValue('vehicle') - public readonly type = 'vehicle'; - - @IsUUID() - public readonly vehicleId: UUID; - - /** - * @deprecated Use {@link create} instead - */ - constructor(vehicleId: UUID) { - this.vehicleId = vehicleId; - } - - static readonly create = getCreate(this); -} diff --git a/shared/src/utils/validators/is-metaposition.ts b/shared/src/utils/validators/is-metaposition.ts index e9999b011..d49ce6af4 100644 --- a/shared/src/utils/validators/is-metaposition.ts +++ b/shared/src/utils/validators/is-metaposition.ts @@ -2,7 +2,7 @@ import { Type } from 'class-transformer'; import { MapPosition } from '../../models/utils/map-position'; import type { MetaPosition } from '../../models/utils/meta-position'; import { SimulatedRegionPosition } from '../../models/utils/simulated-region-position'; -import { TransferPosition } from '../../models/utils/transfer-position'; +import { TransferPosition } from '../../models/utils/position/transfer-position'; import { VehiclePosition } from '../../models/utils/vehicle-position'; import { IsLiteralUnion } from './is-literal-union'; From 0ab923d4326b85c8c9a134c1c2085e8facf5329a Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Wed, 25 Jan 2023 17:59:50 +0100 Subject: [PATCH 02/22] Remove position property --- backend/src/exercise/patient-ticking.ts | 3 +- .../shared/core/drag-element.service.ts | 5 +- .../core/statistics/statistics.service.ts | 23 ++++++-- .../element-feature-manager.ts | 36 +++++++----- .../material-feature-manager.ts | 5 +- .../patient-feature-manager.ts | 5 +- .../personnel-feature-manager.ts | 5 +- .../simulated-region-feature-manager.ts | 2 +- .../vehicle-feature-manager.ts | 5 +- .../viewport-feature-manager.ts | 2 +- .../exercise-map/utility/ol-map-manager.ts | 17 +++--- .../shared/utility/types/with-position.ts | 5 -- .../selectors/exercise.selectors.ts | 7 ++- .../application/selectors/shared.selectors.ts | 36 +++++------- shared/src/data/dummy-objects/patient.ts | 2 +- shared/src/models/map-image.ts | 12 ++-- shared/src/models/material.ts | 16 +----- shared/src/models/patient-template.ts | 2 +- shared/src/models/patient.ts | 13 +---- shared/src/models/personnel.ts | 14 +---- shared/src/models/simulated-region.ts | 31 ++++++---- shared/src/models/transfer-point.ts | 14 ++--- shared/src/models/utils/index.ts | 3 +- .../utils/position/with-meta-position.ts | 2 +- shared/src/models/vehicle.ts | 13 +---- shared/src/models/viewport.ts | 29 ++++++---- .../create-vehicle-parameters.ts | 5 +- .../src/store/action-reducers/map-images.ts | 6 +- .../store/action-reducers/simulated-region.ts | 10 +++- .../store/action-reducers/transfer-point.ts | 10 ++-- shared/src/store/action-reducers/transfer.ts | 21 +++---- .../utils/calculate-treatments.ts | 13 +++-- .../action-reducers/utils/spatial-elements.ts | 22 +++----- shared/src/store/action-reducers/vehicle.ts | 56 +++++++++---------- shared/src/store/action-reducers/viewport.ts | 10 +++- .../src/utils/validators/is-metaposition.ts | 8 +-- 36 files changed, 224 insertions(+), 244 deletions(-) delete mode 100644 frontend/src/app/pages/exercises/exercise/shared/utility/types/with-position.ts diff --git a/backend/src/exercise/patient-ticking.ts b/backend/src/exercise/patient-ticking.ts index 1f6039936..38f130b0d 100644 --- a/backend/src/exercise/patient-ticking.ts +++ b/backend/src/exercise/patient-ticking.ts @@ -5,6 +5,7 @@ import type { PersonnelType, } from 'digital-fuesim-manv-shared'; import { + isOnMap, getElement, healthPointsDefaults, isAlive, @@ -29,7 +30,7 @@ export function patientTick( return ( Object.values(state.patients) // Only look at patients that are alive and have a position, i.e. are not in a vehicle - .filter((patient) => isAlive(patient.health) && patient.position) + .filter((patient) => isAlive(patient.health) && isOnMap(patient)) .map((patient) => { // update the time a patient is being treated, to check for pretriage later const treatmentTime = Patient.isTreatedByPersonnel(patient) diff --git a/frontend/src/app/pages/exercises/exercise/shared/core/drag-element.service.ts b/frontend/src/app/pages/exercises/exercise/shared/core/drag-element.service.ts index 143f58bed..2da6f3c52 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/core/drag-element.service.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/core/drag-element.service.ts @@ -175,10 +175,7 @@ export class DragElementService { this.exerciseService.proposeAction( { type: '[Patient] Add patient', - patient: { - ...patient, - position, - }, + patient, }, true ); diff --git a/frontend/src/app/pages/exercises/exercise/shared/core/statistics/statistics.service.ts b/frontend/src/app/pages/exercises/exercise/shared/core/statistics/statistics.service.ts index 530c82ddb..1d58d25b5 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/core/statistics/statistics.service.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/core/statistics/statistics.service.ts @@ -7,6 +7,8 @@ import type { Vehicle, } from 'digital-fuesim-manv-shared'; import { + coordinatesOf, + isOnMap, loopTroughTime, Personnel, uuid, @@ -108,18 +110,27 @@ export class StatisticsService { ), Object.values(draftState.patients).filter( (patient) => - patient.position && - Viewport.isInViewport(viewport, patient.position) + isOnMap(patient) && + Viewport.isInViewport( + viewport, + coordinatesOf(patient) + ) ), Object.values(draftState.vehicles).filter( (vehicle) => - vehicle.position && - Viewport.isInViewport(viewport, vehicle.position) + isOnMap(vehicle) && + Viewport.isInViewport( + viewport, + coordinatesOf(vehicle) + ) ), Object.values(draftState.personnel).filter( (personnel) => - personnel.position && - Viewport.isInViewport(viewport, personnel.position) + isOnMap(personnel) && + Viewport.isInViewport( + viewport, + coordinatesOf(personnel) + ) ) ), ]) diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/element-feature-manager.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/element-feature-manager.ts index 93c081916..4164ec5ae 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/element-feature-manager.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/element-feature-manager.ts @@ -1,9 +1,12 @@ import type { ExerciseState, + MetaPosition, + WithMetaPosition, Position, Size, UUID, } from 'digital-fuesim-manv-shared'; +import { coordinatesOf } from 'digital-fuesim-manv-shared'; import { isArray } from 'lodash-es'; import type { MapBrowserEvent } from 'ol'; import { Feature } from 'ol'; @@ -15,7 +18,6 @@ import type VectorLayer from 'ol/layer/Vector'; import type OlMap from 'ol/Map'; import type VectorSource from 'ol/source/Vector'; import { Subject } from 'rxjs'; -import type { WithPosition } from '../../utility/types/with-position'; import type { FeatureManager } from '../utility/feature-manager'; import type { Coordinates } from '../utility/movement-animator'; import { MovementAnimator } from '../utility/movement-animator'; @@ -25,7 +27,7 @@ import { ElementManager } from './element-manager'; export interface PositionableElement { readonly id: UUID; - readonly position: Position; + readonly metaPosition: MetaPosition; } export interface ResizableElement extends PositionableElement { @@ -44,8 +46,10 @@ export function isCoordinateArray( return isArray(coordinates[0]); } -export const createPoint = (element: WithPosition): Feature => - new Feature(new Point([element.position.x, element.position.y])); +export const createPoint = (element: WithMetaPosition): Feature => + new Feature( + new Point([coordinatesOf(element).x, coordinatesOf(element).y]) + ); export const createLineString = ( element: ResizableElement @@ -54,14 +58,20 @@ export const createLineString = ( export function getCoordinateArray(element: ResizableElement) { return [ - [element.position.x, element.position.y], - [element.position.x + element.size.width, element.position.y], + [coordinatesOf(element).x, coordinatesOf(element).y], + [ + coordinatesOf(element).x + element.size.width, + coordinatesOf(element).y, + ], + [ + coordinatesOf(element).x + element.size.width, + coordinatesOf(element).y - element.size.height, + ], [ - element.position.x + element.size.width, - element.position.y - element.size.height, + coordinatesOf(element).x, + coordinatesOf(element).y - element.size.height, ], - [element.position.x, element.position.y - element.size.height], - [element.position.x, element.position.y], + [coordinatesOf(element).x, coordinatesOf(element).y], ]; } @@ -134,7 +144,7 @@ export abstract class ElementFeatureManager< changedProperties: ReadonlySet, elementFeature: ElementFeature ): void { - if (changedProperties.has('position')) { + if (changedProperties.has('metaPosition')) { const newFeature = this.getFeatureFromElement(newElement); if (!newFeature) { throw new TypeError('newFeature undefined'); @@ -144,8 +154,8 @@ export abstract class ElementFeatureManager< (isLineString(newFeature) ? (newFeature.getGeometry()! as LineString).getCoordinates() : [ - newElement.position.x, - newElement.position.y, + coordinatesOf(newElement).x, + coordinatesOf(newElement).y, ]) as Coordinates ); } diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/material-feature-manager.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/material-feature-manager.ts index b6da79e5a..defcf06a6 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/material-feature-manager.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/material-feature-manager.ts @@ -6,16 +6,13 @@ import type VectorLayer from 'ol/layer/Vector'; import type OlMap from 'ol/Map'; import type VectorSource from 'ol/source/Vector'; import type { ExerciseService } from 'src/app/core/exercise.service'; -import type { WithPosition } from '../../utility/types/with-position'; import { MaterialPopupComponent } from '../shared/material-popup/material-popup.component'; import { ImagePopupHelper } from '../utility/popup-helper'; import { ImageStyleHelper } from '../utility/style-helper/image-style-helper'; import { NameStyleHelper } from '../utility/style-helper/name-style-helper'; import { createPoint, ElementFeatureManager } from './element-feature-manager'; -export class MaterialFeatureManager extends ElementFeatureManager< - WithPosition -> { +export class MaterialFeatureManager extends ElementFeatureManager { readonly type = 'materials'; private readonly imageStyleHelper = new ImageStyleHelper( (feature) => this.getElementFromFeature(feature)!.value.image diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/patient-feature-manager.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/patient-feature-manager.ts index e2ff69fee..c8dfe1eda 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/patient-feature-manager.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/patient-feature-manager.ts @@ -11,16 +11,13 @@ import type { ExerciseService } from 'src/app/core/exercise.service'; import type { AppState } from 'src/app/state/app.state'; import { selectConfiguration } from 'src/app/state/application/selectors/exercise.selectors'; import { selectStateSnapshot } from 'src/app/state/get-state-snapshot'; -import type { WithPosition } from '../../utility/types/with-position'; import { PatientPopupComponent } from '../shared/patient-popup/patient-popup.component'; import { ImagePopupHelper } from '../utility/popup-helper'; import { CircleStyleHelper } from '../utility/style-helper/circle-style-helper'; import { ImageStyleHelper } from '../utility/style-helper/image-style-helper'; import { createPoint, ElementFeatureManager } from './element-feature-manager'; -export class PatientFeatureManager extends ElementFeatureManager< - WithPosition -> { +export class PatientFeatureManager extends ElementFeatureManager { readonly type = 'patients'; private readonly popupHelper = new ImagePopupHelper(this.olMap, this.layer); diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/personnel-feature-manager.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/personnel-feature-manager.ts index 3d42f47ee..e34f773fd 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/personnel-feature-manager.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/personnel-feature-manager.ts @@ -6,16 +6,13 @@ import type VectorLayer from 'ol/layer/Vector'; import type OlMap from 'ol/Map'; import type VectorSource from 'ol/source/Vector'; import type { ExerciseService } from 'src/app/core/exercise.service'; -import type { WithPosition } from '../../utility/types/with-position'; import { PersonnelPopupComponent } from '../shared/personnel-popup/personnel-popup.component'; import { ImagePopupHelper } from '../utility/popup-helper'; import { ImageStyleHelper } from '../utility/style-helper/image-style-helper'; import { NameStyleHelper } from '../utility/style-helper/name-style-helper'; import { createPoint, ElementFeatureManager } from './element-feature-manager'; -export class PersonnelFeatureManager extends ElementFeatureManager< - WithPosition -> { +export class PersonnelFeatureManager extends ElementFeatureManager { readonly type = 'personnel'; private readonly imageStyleHelper = new ImageStyleHelper( (feature) => this.getElementFromFeature(feature)!.value.image diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/simulated-region-feature-manager.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/simulated-region-feature-manager.ts index acfa70e1d..a69529aa9 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/simulated-region-feature-manager.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/simulated-region-feature-manager.ts @@ -92,7 +92,7 @@ export class SimulatedRegionFeatureManager elementFeature: Feature ): void { if ( - changedProperties.has('position') || + changedProperties.has('metaPosition') || changedProperties.has('size') ) { const newFeature = this.getFeatureFromElement(newElement); diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/vehicle-feature-manager.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/vehicle-feature-manager.ts index 0a6e489f2..279aca132 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/vehicle-feature-manager.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/vehicle-feature-manager.ts @@ -7,16 +7,13 @@ import type VectorLayer from 'ol/layer/Vector'; import type OlMap from 'ol/Map'; import type VectorSource from 'ol/source/Vector'; import type { ExerciseService } from 'src/app/core/exercise.service'; -import type { WithPosition } from '../../utility/types/with-position'; import { VehiclePopupComponent } from '../shared/vehicle-popup/vehicle-popup.component'; import { ImagePopupHelper } from '../utility/popup-helper'; import { ImageStyleHelper } from '../utility/style-helper/image-style-helper'; import { NameStyleHelper } from '../utility/style-helper/name-style-helper'; import { createPoint, ElementFeatureManager } from './element-feature-manager'; -export class VehicleFeatureManager extends ElementFeatureManager< - WithPosition -> { +export class VehicleFeatureManager extends ElementFeatureManager { readonly type = 'vehicles'; private readonly imageStyleHelper = new ImageStyleHelper( diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/viewport-feature-manager.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/viewport-feature-manager.ts index 5fa0b86d0..68ee0ea97 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/viewport-feature-manager.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/viewport-feature-manager.ts @@ -103,7 +103,7 @@ export class ViewportFeatureManager elementFeature: Feature ): void { if ( - changedProperties.has('position') || + changedProperties.has('metaPosition') || changedProperties.has('size') ) { const newFeature = this.getFeatureFromElement(newElement); diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/ol-map-manager.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/ol-map-manager.ts index 4a7b944fc..474330b93 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/ol-map-manager.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/ol-map-manager.ts @@ -5,6 +5,7 @@ import type { MergeIntersection, UUID, } from 'digital-fuesim-manv-shared'; +import { coordinatesOf } from 'digital-fuesim-manv-shared'; import type { Feature } from 'ol'; import { Overlay, View } from 'ol'; import type Geometry from 'ol/geom/Geometry'; @@ -355,10 +356,10 @@ export class OlMapManager { const center = view.getCenter()!; const previousZoom = view.getZoom()!; const targetExtent = [ - viewport.position.x, - viewport.position.y - viewport.size.height, - viewport.position.x + viewport.size.width, - viewport.position.y, + coordinatesOf(viewport).x, + coordinatesOf(viewport).y - viewport.size.height, + coordinatesOf(viewport).x + viewport.size.width, + coordinatesOf(viewport).y, ]; view.fit(targetExtent); const matchingZoom = view.getZoom()!; @@ -527,20 +528,20 @@ export class OlMapManager { return; } const minX = Math.min( - ...viewports.map((viewport) => viewport.position.x) + ...viewports.map((viewport) => coordinatesOf(viewport).x) ); const minY = Math.min( ...viewports.map( - (viewport) => viewport.position.y - viewport.size.height + (viewport) => coordinatesOf(viewport).y - viewport.size.height ) ); const maxX = Math.max( ...viewports.map( - (viewport) => viewport.position.x + viewport.size.width + (viewport) => coordinatesOf(viewport).x + viewport.size.width ) ); const maxY = Math.max( - ...viewports.map((viewport) => viewport.position.y) + ...viewports.map((viewport) => coordinatesOf(viewport).y) ); const padding = 25; view.fit([minX, minY, maxX, maxY], { diff --git a/frontend/src/app/pages/exercises/exercise/shared/utility/types/with-position.ts b/frontend/src/app/pages/exercises/exercise/shared/utility/types/with-position.ts deleted file mode 100644 index 64c7c42dd..000000000 --- a/frontend/src/app/pages/exercises/exercise/shared/utility/types/with-position.ts +++ /dev/null @@ -1,5 +0,0 @@ -import type { Position } from 'digital-fuesim-manv-shared'; - -export type WithPosition = T & { - position: Position; -}; diff --git a/frontend/src/app/state/application/selectors/exercise.selectors.ts b/frontend/src/app/state/application/selectors/exercise.selectors.ts index 0fb94a5a2..b089de84b 100644 --- a/frontend/src/app/state/application/selectors/exercise.selectors.ts +++ b/frontend/src/app/state/application/selectors/exercise.selectors.ts @@ -6,6 +6,7 @@ import type { UUID, Vehicle, } from 'digital-fuesim-manv-shared'; +import { coordinatesOf } from 'digital-fuesim-manv-shared'; import type { TransferLine } from 'src/app/shared/types/transfer-line'; import type { AppState } from '../../app.state'; @@ -119,8 +120,10 @@ export const selectTransferLines = createSelector( Object.entries(transferPoint.reachableTransferPoints).map( ([connectedId, { duration }]) => ({ id: `${transferPoint.id}:${connectedId}` as const, - startPosition: transferPoint.position, - endPosition: transferPoints[connectedId]!.position, + startPosition: coordinatesOf(transferPoint), + endPosition: coordinatesOf( + transferPoints[connectedId]! + ), duration, }) ) diff --git a/frontend/src/app/state/application/selectors/shared.selectors.ts b/frontend/src/app/state/application/selectors/shared.selectors.ts index 706764625..5b4b625b4 100644 --- a/frontend/src/app/state/application/selectors/shared.selectors.ts +++ b/frontend/src/app/state/application/selectors/shared.selectors.ts @@ -4,15 +4,14 @@ import type { Material, Patient, Personnel, - Position, SimulatedRegion, TransferPoint, UUID, Vehicle, + WithMetaPosition, } from 'digital-fuesim-manv-shared'; -import { Viewport } from 'digital-fuesim-manv-shared'; +import { coordinatesOf, isOnMap, Viewport } from 'digital-fuesim-manv-shared'; import { pickBy } from 'lodash-es'; -import type { WithPosition } from 'src/app/pages/exercises/exercise/shared/utility/types/with-position'; import type { CateringLine } from 'src/app/shared/types/catering-line'; import type { AppState } from '../../app.state'; import { @@ -63,20 +62,16 @@ export const selectRestrictedViewport = createSelector( * @returns a selector that returns a UUIDMap of all elements that have a position and are in the viewport restriction */ function selectVisibleElementsFactory< - Element extends { readonly position?: Position }, + Element extends WithMetaPosition, Elements extends { readonly [key: UUID]: Element } = { readonly [key: UUID]: Element; - }, - ElementsWithPosition extends { - [Id in keyof Elements]: WithPosition; - } = { [Id in keyof Elements]: WithPosition } + } >( selectElements: (state: AppState) => Elements, - isInViewport: ( - element: WithPosition, - viewport: Viewport - ) => boolean = (element, viewport) => - Viewport.isInViewport(viewport, element.position) + isInViewport: (element: Element, viewport: Viewport) => boolean = ( + element, + viewport + ) => Viewport.isInViewport(viewport, coordinatesOf(element)) ) { return createSelector( selectRestrictedViewport, @@ -86,14 +81,11 @@ function selectVisibleElementsFactory< elements, (element) => // Is placed on the map - element.position && + isOnMap(element) && // No viewport restriction (!restrictedViewport || - isInViewport( - element as WithPosition, - restrictedViewport - )) - ) as ElementsWithPosition + isInViewport(element, restrictedViewport)) + ) ); } @@ -129,7 +121,7 @@ export const selectVisibleCateringLines = createSelector( (viewport, materials, personnel, patients) => // Mostly, there are fewer untreated patients than materials and personnel that are not treating Object.values(patients) - .filter((patient) => patient.position !== undefined) + .filter((patient) => isOnMap(patient)) .flatMap((patient) => [ ...Object.keys(patient.assignedPersonnelIds).map( @@ -140,9 +132,9 @@ export const selectVisibleCateringLines = createSelector( ), ].map((caterer) => ({ id: `${caterer.id}:${patient.id}` as const, - patientPosition: patient.position!, + patientPosition: coordinatesOf(patient), // If the catering element is treating a patient, it must have a position - catererPosition: caterer.position!, + catererPosition: coordinatesOf(caterer), })) ) // To improve performance, all Lines where both ends are not in the viewport diff --git a/shared/src/data/dummy-objects/patient.ts b/shared/src/data/dummy-objects/patient.ts index 7516a0b44..dfeb9b58b 100644 --- a/shared/src/data/dummy-objects/patient.ts +++ b/shared/src/data/dummy-objects/patient.ts @@ -1,6 +1,6 @@ import { FunctionParameters, Patient, PatientHealthState } from '../../models'; import { MapCoordinates } from '../../models/utils/position/map-coordinates'; -import { MapPosition } from '../../models/utils/map-position'; +import { MapPosition } from '../../models/utils/position/map-position'; import { PatientStatusCode } from '../../models/utils/patient-status-code'; import { defaultPatientCategories } from '../default-state/patient-templates'; diff --git a/shared/src/models/map-image.ts b/shared/src/models/map-image.ts index 6dc0c3e46..c62e39390 100644 --- a/shared/src/models/map-image.ts +++ b/shared/src/models/map-image.ts @@ -1,15 +1,17 @@ import { Type } from 'class-transformer'; import { IsBoolean, IsInt, IsUUID, ValidateNested } from 'class-validator'; import { uuid, UUID, uuidValidationOptions } from '../utils'; -import { Position, getCreate, ImageProperties } from './utils'; +import { IsMetaPosition } from '../utils/validators/is-metaposition'; +import type { MapCoordinates } from './utils'; +import { MapPosition, getCreate, ImageProperties, MetaPosition } from './utils'; export class MapImage { @IsUUID(4, uuidValidationOptions) public readonly id: UUID = uuid(); @ValidateNested() - @Type(() => Position) - public readonly position: Position; + @IsMetaPosition() + public readonly metaPosition: MetaPosition; @ValidateNested() @Type(() => ImageProperties) @@ -34,12 +36,12 @@ export class MapImage { * @deprecated Use {@link create} instead */ constructor( - topLeft: Position, + topLeft: MapCoordinates, image: ImageProperties, isLocked: boolean, zIndex: number ) { - this.position = topLeft; + this.metaPosition = MapPosition.create(topLeft); this.image = image; this.isLocked = isLocked; this.zIndex = zIndex; diff --git a/shared/src/models/material.ts b/shared/src/models/material.ts index 10dc9e2fa..1ab19b7d8 100644 --- a/shared/src/models/material.ts +++ b/shared/src/models/material.ts @@ -6,15 +6,15 @@ import { IsNumber, Min, Max, - IsOptional, } from 'class-validator'; import { maxTreatmentRange } from '../state-helpers/max-treatment-range'; import { uuidValidationOptions, UUID, uuid, UUIDSet } from '../utils'; import { IsUUIDSet } from '../utils/validators'; import { IsMetaPosition } from '../utils/validators/is-metaposition'; import type { MaterialTemplate } from './material-template'; -import { CanCaterFor, Position, ImageProperties, getCreate } from './utils'; -import { MetaPosition } from './utils/meta-position'; +import type { Position } from './utils'; +import { CanCaterFor, ImageProperties, getCreate } from './utils'; +import { MetaPosition } from './utils/position/meta-position'; export class Material { @IsUUID(4, uuidValidationOptions) @@ -57,15 +57,6 @@ export class Material { @ValidateNested() public readonly metaPosition: MetaPosition; - /** - * @deprecated use {@link metaPosition} - * if undefined, is in vehicle with {@link this.vehicleId} - */ - @ValidateNested() - @Type(() => Position) - @IsOptional() - public readonly position?: Position; - @ValidateNested() @Type(() => ImageProperties) public readonly image: ImageProperties; @@ -87,7 +78,6 @@ export class Material { this.vehicleId = vehicleId; this.vehicleName = vehicleName; this.assignedPatientIds = assignedPatientIds; - this.position = position; this.image = image; this.canCaterFor = canCaterFor; this.treatmentRange = treatmentRange; diff --git a/shared/src/models/patient-template.ts b/shared/src/models/patient-template.ts index ef8841390..1cadb121e 100644 --- a/shared/src/models/patient-template.ts +++ b/shared/src/models/patient-template.ts @@ -16,7 +16,7 @@ import { Patient } from './patient'; import type { FunctionParameters } from './patient-health-state'; import { PretriageInformation } from './utils/pretriage-information'; import { PatientHealthState } from './patient-health-state'; -import type { MetaPosition } from './utils/meta-position'; +import type { MetaPosition } from './utils/position/meta-position'; export class PatientTemplate { @IsUUID(4, uuidValidationOptions) diff --git a/shared/src/models/patient.ts b/shared/src/models/patient.ts index 29fdf2a7d..7e086f8cd 100644 --- a/shared/src/models/patient.ts +++ b/shared/src/models/patient.ts @@ -21,12 +21,11 @@ import { PatientStatus, patientStatusAllowedValues, ImageProperties, - Position, healthPointsDefaults, HealthPoints, getCreate, } from './utils'; -import { MetaPosition } from './utils/meta-position'; +import { MetaPosition } from './utils/position/meta-position'; import { PersonalInformation } from './utils/personal-information'; import { PretriageInformation } from './utils/pretriage-information'; @@ -70,16 +69,6 @@ export class Patient { /** * @deprecated use {@link metaPosition} - * Exclusive-or to {@link vehicleId} - */ - @ValidateNested() - @Type(() => Position) - @IsOptional() - public readonly position?: Position; - - /** - * @deprecated use {@link metaPosition} - * Exclusive-or to {@link position} */ @IsUUID(4, uuidValidationOptions) @IsOptional() diff --git a/shared/src/models/personnel.ts b/shared/src/models/personnel.ts index 9ed6b4f79..3e39a0c35 100644 --- a/shared/src/models/personnel.ts +++ b/shared/src/models/personnel.ts @@ -13,15 +13,15 @@ import { uuidValidationOptions, UUID, uuid, UUIDSet } from '../utils'; import { IsLiteralUnion, IsUUIDSet } from '../utils/validators'; import { IsMetaPosition } from '../utils/validators/is-metaposition'; import type { PersonnelTemplate } from './personnel-template'; +import type { Position } from './utils'; import { PersonnelType, CanCaterFor, ImageProperties, - Position, Transfer, getCreate, } from './utils'; -import { MetaPosition } from './utils/meta-position'; +import { MetaPosition } from './utils/position/meta-position'; import { personnelTypeAllowedValues } from './utils/personnel-type'; export class Personnel { @@ -72,15 +72,6 @@ export class Personnel { @ValidateNested() public readonly metaPosition: MetaPosition; - /** - * @deprecated use {@link metaPosition} - * If undefined, the personnel is either in the vehicle with {@link this.vehicleId} or in transfer. - */ - @ValidateNested() - @Type(() => Position) - @IsOptional() - public readonly position?: Position; - /** * * @deprecated use {@link metaPosition} * If undefined, the personnel is either in the vehicle with {@link this.vehicleId} or has a {@link position}. @@ -109,7 +100,6 @@ export class Personnel { this.vehicleName = vehicleName; this.personnelType = personnelType; this.assignedPatientIds = assignedPatientIds; - this.position = position; this.image = image; this.canCaterFor = canCaterFor; this.treatmentRange = treatmentRange; diff --git a/shared/src/models/simulated-region.ts b/shared/src/models/simulated-region.ts index 6e3db79a4..e59addff5 100644 --- a/shared/src/models/simulated-region.ts +++ b/shared/src/models/simulated-region.ts @@ -1,8 +1,17 @@ import { Type } from 'class-transformer'; import { IsString, IsUUID, ValidateNested } from 'class-validator'; import { UUID, uuid, uuidValidationOptions } from '../utils'; -import { getCreate, Position, Size } from './utils'; -import type { ImageProperties } from './utils'; +import { IsMetaPosition } from '../utils/validators/is-metaposition'; +import { + getCreate, + isInSimulatedRegion, + MapPosition, + MetaPosition, + simulatedRegionItsIn, + Size, +} from './utils'; +import type { ImageProperties, MapCoordinates } from './utils'; +import type { WithMetaPosition } from './utils/position/with-meta-position'; export class SimulatedRegion { @IsUUID(4, uuidValidationOptions) @@ -12,8 +21,8 @@ export class SimulatedRegion { * top-left position */ @ValidateNested() - @Type(() => Position) - public readonly position: Position; + @IsMetaPosition() + public readonly metaPosition: MetaPosition; @ValidateNested() @Type(() => Size) @@ -26,8 +35,8 @@ export class SimulatedRegion { * @param position top-left position * @deprecated Use {@link create} instead */ - constructor(position: Position, size: Size, name: string) { - this.position = position; + constructor(position: MapCoordinates, size: Size, name: string) { + this.metaPosition = MapPosition.create(position); this.size = size; this.name = name; } @@ -42,11 +51,11 @@ export class SimulatedRegion { static isInSimulatedRegion( region: SimulatedRegion, - position: Position + withMetaPosition: WithMetaPosition ): boolean { - // This class was copied from viewport.ts - // We will have to implement this logic differently - // later, for now, this is a stub method - return false; + return ( + isInSimulatedRegion(withMetaPosition) && + simulatedRegionItsIn(withMetaPosition) === region.id + ); } } diff --git a/shared/src/models/transfer-point.ts b/shared/src/models/transfer-point.ts index b825b36be..a683b9899 100644 --- a/shared/src/models/transfer-point.ts +++ b/shared/src/models/transfer-point.ts @@ -1,17 +1,17 @@ -import { Type } from 'class-transformer'; import { IsString, IsUUID, ValidateNested } from 'class-validator'; import { UUID, uuid, UUIDSet, uuidValidationOptions } from '../utils'; import { IsReachableTransferPoints, IsUUIDSet } from '../utils/validators'; -import type { ImageProperties } from './utils'; -import { getCreate, Position } from './utils'; +import { IsMetaPosition } from '../utils/validators/is-metaposition'; +import type { ImageProperties, MapCoordinates } from './utils'; +import { MapPosition, MetaPosition, getCreate } from './utils'; export class TransferPoint { @IsUUID(4, uuidValidationOptions) public readonly id: UUID = uuid(); @ValidateNested() - @Type(() => Position) - public readonly position: Position; + @IsMetaPosition() + public readonly metaPosition: MetaPosition; @IsReachableTransferPoints() public readonly reachableTransferPoints: ReachableTransferPoints; @@ -29,13 +29,13 @@ export class TransferPoint { * @deprecated Use {@link create} instead */ constructor( - position: Position, + position: MapCoordinates, reachableTransferPoints: ReachableTransferPoints, reachableHospitals: UUIDSet, internalName: string, externalName: string ) { - this.position = position; + this.metaPosition = MapPosition.create(position); this.reachableTransferPoints = reachableTransferPoints; this.reachableHospitals = reachableHospitals; this.internalName = internalName; diff --git a/shared/src/models/utils/index.ts b/shared/src/models/utils/index.ts index 756a4270d..27db93c17 100644 --- a/shared/src/models/utils/index.ts +++ b/shared/src/models/utils/index.ts @@ -1,5 +1,6 @@ export { Position } from './position'; -export { MetaPosition } from './/position/meta-position'; +export { MetaPosition } from './position/meta-position'; +export { WithMetaPosition } from './position/with-meta-position'; export { MapPosition } from './position/map-position'; export { VehiclePosition } from './position/vehicle-position'; export { TransferPosition } from './position/transfer-position'; diff --git a/shared/src/models/utils/position/with-meta-position.ts b/shared/src/models/utils/position/with-meta-position.ts index 790aa0df7..e296e7843 100644 --- a/shared/src/models/utils/position/with-meta-position.ts +++ b/shared/src/models/utils/position/with-meta-position.ts @@ -1,5 +1,5 @@ import type { MetaPosition } from './meta-position'; export interface WithMetaPosition { - metaPosition: MetaPosition; + readonly metaPosition: MetaPosition; } diff --git a/shared/src/models/vehicle.ts b/shared/src/models/vehicle.ts index 8c18b39da..5cb65b849 100644 --- a/shared/src/models/vehicle.ts +++ b/shared/src/models/vehicle.ts @@ -9,9 +9,9 @@ import { import { uuid, uuidValidationOptions, UUID, UUIDSet } from '../utils'; import { IsUUIDSet } from '../utils/validators'; import { IsMetaPosition } from '../utils/validators/is-metaposition'; -import { getCreate, Position, Transfer } from './utils'; +import { getCreate, Transfer } from './utils'; import { ImageProperties } from './utils/image-properties'; -import { MetaPosition } from './utils/meta-position'; +import { MetaPosition } from './utils/position/meta-position'; export class Vehicle { @IsUUID(4, uuidValidationOptions) @@ -33,15 +33,6 @@ export class Vehicle { @ValidateNested() public readonly metaPosition: MetaPosition; - /** - * @deprecated use {@link metaPosition} - * Exclusive-or to {@link transfer} - */ - @ValidateNested() - @Type(() => Position) - @IsOptional() - public readonly position?: Position; - @ValidateNested() @Type(() => ImageProperties) public readonly image: ImageProperties; diff --git a/shared/src/models/viewport.ts b/shared/src/models/viewport.ts index fc31482b7..bc2cdc03e 100644 --- a/shared/src/models/viewport.ts +++ b/shared/src/models/viewport.ts @@ -1,8 +1,15 @@ import { Type } from 'class-transformer'; import { IsString, IsUUID, ValidateNested } from 'class-validator'; import { UUID, uuid, uuidValidationOptions } from '../utils'; -import { getCreate, Position, Size } from './utils'; -import type { ImageProperties } from './utils'; +import { IsMetaPosition } from '../utils/validators/is-metaposition'; +import { + coordinatesOf, + getCreate, + MapPosition, + MetaPosition, + Size, +} from './utils'; +import type { ImageProperties, MapCoordinates } from './utils'; export class Viewport { @IsUUID(4, uuidValidationOptions) @@ -12,8 +19,8 @@ export class Viewport { * top-left position */ @ValidateNested() - @Type(() => Position) - public readonly position: Position; + @IsMetaPosition() + public readonly metaPosition: MetaPosition; @ValidateNested() @Type(() => Size) @@ -26,8 +33,8 @@ export class Viewport { * @param position top-left position * @deprecated Use {@link create} instead */ - constructor(position: Position, size: Size, name: string) { - this.position = position; + constructor(position: MapCoordinates, size: Size, name: string) { + this.metaPosition = MapPosition.create(position); this.size = size; this.name = name; } @@ -40,12 +47,12 @@ export class Viewport { aspectRatio: 1600 / 900, }; - static isInViewport(viewport: Viewport, position: Position): boolean { + static isInViewport(viewport: Viewport, position: MapCoordinates): boolean { return ( - viewport.position.x <= position.x && - position.x <= viewport.position.x + viewport.size.width && - viewport.position.y - viewport.size.height <= position.y && - position.y <= viewport.position.y + coordinatesOf(viewport).x <= position.x && + position.x <= coordinatesOf(viewport).x + viewport.size.width && + coordinatesOf(viewport).y - viewport.size.height <= position.y && + position.y <= coordinatesOf(viewport).y ); } } diff --git a/shared/src/state-helpers/create-vehicle-parameters.ts b/shared/src/state-helpers/create-vehicle-parameters.ts index e6f0021a3..b738132ed 100644 --- a/shared/src/state-helpers/create-vehicle-parameters.ts +++ b/shared/src/state-helpers/create-vehicle-parameters.ts @@ -3,9 +3,9 @@ import { Material, Personnel } from '../models'; import type { MaterialTemplate } from '../models/material-template'; import type { PersonnelTemplate } from '../models/personnel-template'; import type { PersonnelType, Position } from '../models/utils'; -import { MapPosition } from '../models/utils/map-position'; +import { MapPosition } from '../models/utils/position/map-position'; import type { MaterialType } from '../models/utils/material-type'; -import { VehiclePosition } from '../models/utils/vehicle-position'; +import { VehiclePosition } from '../models/utils/position/vehicle-position'; import { uuid } from '../utils'; import { arrayToUUIDSet } from '../utils/array-to-uuid-set'; @@ -55,7 +55,6 @@ export function createVehicleParameters( image: vehicleTemplate.image, patientIds: {}, personnelIds: arrayToUUIDSet(personnel.map((p) => p.id)), - position: vehiclePosition, metaPosition: MapPosition.create(vehiclePosition), }; return { diff --git a/shared/src/store/action-reducers/map-images.ts b/shared/src/store/action-reducers/map-images.ts index 26bce6329..c09999054 100644 --- a/shared/src/store/action-reducers/map-images.ts +++ b/shared/src/store/action-reducers/map-images.ts @@ -9,7 +9,7 @@ import { ValidateNested, } from 'class-validator'; import { MapImage } from '../../models'; -import { Position } from '../../models/utils'; +import { MapPosition, Position } from '../../models/utils'; import type { ExerciseState } from '../../state'; import type { Mutable } from '../../utils'; import { @@ -134,7 +134,9 @@ export namespace MapImagesActionReducers { action: MoveMapImageAction, reducer: (draftState, { mapImageId, targetPosition }) => { const mapImage = getElement(draftState, 'mapImages', mapImageId); - mapImage.position = cloneDeepMutable(targetPosition); + mapImage.metaPosition = cloneDeepMutable( + MapPosition.create(targetPosition) + ); return draftState; }, rights: 'trainer', diff --git a/shared/src/store/action-reducers/simulated-region.ts b/shared/src/store/action-reducers/simulated-region.ts index 390e0456e..6029e91b4 100644 --- a/shared/src/store/action-reducers/simulated-region.ts +++ b/shared/src/store/action-reducers/simulated-region.ts @@ -1,7 +1,7 @@ import { Type } from 'class-transformer'; import { IsString, IsUUID, ValidateNested } from 'class-validator'; import { SimulatedRegion } from '../../models'; -import { Position, Size } from '../../models/utils'; +import { MapPosition, Position, Size } from '../../models/utils'; import { cloneDeepMutable, UUID, uuidValidationOptions } from '../../utils'; import { IsValue } from '../../utils/validators'; import type { Action, ActionReducer } from '../action-reducer'; @@ -87,7 +87,9 @@ export namespace SimulatedRegionActionReducers { 'simulatedRegions', simulatedRegionId ); - simulatedRegion.position = cloneDeepMutable(targetPosition); + simulatedRegion.metaPosition = cloneDeepMutable( + MapPosition.create(targetPosition) + ); return draftState; }, rights: 'trainer', @@ -105,7 +107,9 @@ export namespace SimulatedRegionActionReducers { 'simulatedRegions', simulatedRegionId ); - simulatedRegion.position = cloneDeepMutable(targetPosition); + simulatedRegion.metaPosition = cloneDeepMutable( + MapPosition.create(targetPosition) + ); simulatedRegion.size = cloneDeepMutable(newSize); return draftState; }, diff --git a/shared/src/store/action-reducers/transfer-point.ts b/shared/src/store/action-reducers/transfer-point.ts index dd55cbae0..e41675c07 100644 --- a/shared/src/store/action-reducers/transfer-point.ts +++ b/shared/src/store/action-reducers/transfer-point.ts @@ -7,7 +7,7 @@ import { ValidateNested, } from 'class-validator'; import { TransferPoint } from '../../models'; -import { Position } from '../../models/utils'; +import { coordinatesOf, MapPosition, Position } from '../../models/utils'; import { cloneDeepMutable, UUID, uuidValidationOptions } from '../../utils'; import { IsValue } from '../../utils/validators'; import type { Action, ActionReducer } from '../action-reducer'; @@ -127,7 +127,9 @@ export namespace TransferPointActionReducers { 'transferPoints', transferPointId ); - transferPoint.position = cloneDeepMutable(targetPosition); + transferPoint.metaPosition = cloneDeepMutable( + MapPosition.create(targetPosition) + ); return draftState; }, rights: 'trainer', @@ -184,8 +186,8 @@ export namespace TransferPointActionReducers { const _duration = duration ?? estimateDuration( - transferPoint1.position, - transferPoint2.position + coordinatesOf(transferPoint1), + coordinatesOf(transferPoint2) ); transferPoint1.reachableTransferPoints[transferPointId2] = { duration: _duration, diff --git a/shared/src/store/action-reducers/transfer.ts b/shared/src/store/action-reducers/transfer.ts index 9dc2eee4d..4d2abb0af 100644 --- a/shared/src/store/action-reducers/transfer.ts +++ b/shared/src/store/action-reducers/transfer.ts @@ -2,7 +2,12 @@ import { Type } from 'class-transformer'; import { IsInt, IsOptional, IsUUID, ValidateNested } from 'class-validator'; import { TransferPoint } from '../../models'; import type { Position } from '../../models/utils'; -import { StartPoint, startPointTypeOptions } from '../../models/utils'; +import { + coordinatesOf, + MapPosition, + StartPoint, + startPointTypeOptions, +} from '../../models/utils'; import type { ExerciseState } from '../../state'; import { imageSizeToPosition } from '../../state-helpers'; import type { Mutable } from '../../utils'; @@ -42,20 +47,18 @@ export function letElementArrive( element.transfer.targetTransferPointId ); const newPosition: Mutable = { - x: targetTransferPoint.position.x, + x: coordinatesOf(targetTransferPoint).x, y: - targetTransferPoint.position.y + + coordinatesOf(targetTransferPoint).y + // Position it in the upper half of the transferPoint imageSizeToPosition(TransferPoint.image.height / 3), }; if (elementType === 'personnel') { updateElementPosition(draftState, 'personnel', element.id, newPosition); } else { - element.position = newPosition; - element.metaPosition = { - type: 'coordinates', - position: newPosition, - }; + element.metaPosition = cloneDeepMutable( + MapPosition.create(newPosition) + ); } delete element.transfer; } @@ -168,8 +171,6 @@ export namespace TransferActionReducers { // Remove the position of the element if (elementType === 'personnel') { removeElementPosition(draftState, 'personnel', element.id); - } else { - element.position = undefined; } // Set the element to transfer element.transfer = { diff --git a/shared/src/store/action-reducers/utils/calculate-treatments.ts b/shared/src/store/action-reducers/utils/calculate-treatments.ts index fbc9fd9d7..924f6720f 100644 --- a/shared/src/store/action-reducers/utils/calculate-treatments.ts +++ b/shared/src/store/action-reducers/utils/calculate-treatments.ts @@ -2,6 +2,7 @@ import { groupBy } from 'lodash-es'; import type { Material, Personnel } from '../../../models'; import { Patient } from '../../../models'; import type { PatientStatus, Position } from '../../../models/utils'; +import { coordinatesOf, isNotOnMap } from '../../../models/utils'; import { SpatialTree } from '../../../models/utils/spatial-tree'; import type { ExerciseState } from '../../../state'; import { maxTreatmentRange } from '../../../state-helpers/max-treatment-range'; @@ -188,7 +189,7 @@ export function updateTreatments( // Currently, the treatment pattern algorithm is stable. This means that completely done from scratch, // the result would semantically be the same. This could be changed later. - if (element.position === undefined) { + if (isNotOnMap(element)) { // The element is no longer in a position (get it?!) to be treated or treat a patient removeTreatmentsOfElement(state, element); return; @@ -215,13 +216,13 @@ export function updateTreatments( updateCateringAroundPatient( state, - element.position, + coordinatesOf(element), 'personnel', alreadyUpdatedElementIds ); updateCateringAroundPatient( state, - element.position, + coordinatesOf(element), 'materials', alreadyUpdatedElementIds ); @@ -244,7 +245,7 @@ function updateCatering( cateringElement.canCaterFor.yellow === 0 && cateringElement.canCaterFor.green === 0) || // The element is no longer in a position to treat a patient - cateringElement.position === undefined + isNotOnMap(cateringElement) ) { return; } @@ -262,7 +263,7 @@ function updateCatering( if (cateringElement.overrideTreatmentRange > 0) { const patientIdsInOverrideRange = SpatialTree.findAllElementsInCircle( state.spatialTrees.patients, - cateringElement.position, + coordinatesOf(cateringElement), cateringElement.overrideTreatmentRange ); // In the overrideTreatmentRange (the override circle) only the distance to the patient is important - his/her injuries are ignored @@ -291,7 +292,7 @@ function updateCatering( const patientsInTreatmentRange: Mutable[] = SpatialTree.findAllElementsInCircle( state.spatialTrees.patients, - cateringElement.position, + coordinatesOf(cateringElement), cateringElement.treatmentRange ) // Filter out every patient in the overrideTreatmentRange diff --git a/shared/src/store/action-reducers/utils/spatial-elements.ts b/shared/src/store/action-reducers/utils/spatial-elements.ts index 6a88929cf..aede143ec 100644 --- a/shared/src/store/action-reducers/utils/spatial-elements.ts +++ b/shared/src/store/action-reducers/utils/spatial-elements.ts @@ -1,4 +1,5 @@ -import type { Position } from '../../../models/utils'; +import { isOnMap, Position } from '../../../models/utils'; +import { MapPosition, isNotOnMap, coordinatesOf } from '../../../models/utils'; import { SpatialTree } from '../../../models/utils/spatial-tree'; import type { ExerciseState } from '../../../state'; import type { Mutable, UUID } from '../../../utils'; @@ -23,13 +24,13 @@ export function addElementPosition( elementId: UUID ) { const element = getElement(state, elementType, elementId); - if (element.position === undefined) { + if (isNotOnMap(element)) { return; } SpatialTree.addElement( state.spatialTrees[elementType], element.id, - element.position + coordinatesOf(element) ); updateTreatments(state, element); } @@ -44,8 +45,8 @@ export function updateElementPosition( targetPosition: Position ) { const element = getElement(state, elementType, elementId); - const startPosition = element.position; - if (startPosition !== undefined) { + if (isOnMap(element)) { + const startPosition = cloneDeepMutable(coordinatesOf(element)); SpatialTree.moveElement( state.spatialTrees[elementType], element.id, @@ -59,11 +60,7 @@ export function updateElementPosition( targetPosition ); } - element.position = cloneDeepMutable(targetPosition); - element.metaPosition = { - type: 'coordinates', - position: cloneDeepMutable(targetPosition), - }; + element.metaPosition = cloneDeepMutable(MapPosition.create(targetPosition)); updateTreatments(state, element); } @@ -77,14 +74,13 @@ export function removeElementPosition( elementId: UUID ) { const element = getElement(state, elementType, elementId); - if (element.position === undefined) { + if (isNotOnMap(element)) { return; } SpatialTree.removeElement( state.spatialTrees[elementType], element.id, - element.position + cloneDeepMutable(coordinatesOf(element)) ); - element.position = undefined; updateTreatments(state, element); } diff --git a/shared/src/store/action-reducers/vehicle.ts b/shared/src/store/action-reducers/vehicle.ts index c0704b6b3..dfdc66afa 100644 --- a/shared/src/store/action-reducers/vehicle.ts +++ b/shared/src/store/action-reducers/vehicle.ts @@ -1,7 +1,7 @@ import { Type } from 'class-transformer'; import { IsArray, IsString, IsUUID, ValidateNested } from 'class-validator'; import { Material, Personnel, Vehicle } from '../../models'; -import { Position } from '../../models/utils'; +import { MapPosition, Position, VehiclePosition } from '../../models/utils'; import type { ExerciseState } from '../../state'; import { imageSizeToPosition } from '../../state-helpers'; import type { Mutable } from '../../utils'; @@ -174,11 +174,9 @@ export namespace VehicleActionReducers { action: MoveVehicleAction, reducer: (draftState, { vehicleId, targetPosition }) => { const vehicle = getElement(draftState, 'vehicles', vehicleId); - vehicle.position = cloneDeepMutable(targetPosition); - vehicle.metaPosition = { - type: 'coordinates', - position: cloneDeepMutable(targetPosition), - }; + vehicle.metaPosition = cloneDeepMutable( + MapPosition.create(targetPosition) + ); return draftState; }, rights: 'participant', @@ -305,11 +303,11 @@ export namespace VehicleActionReducers { `Material with id ${material.id} is not assignable to the vehicle with id ${vehicle.id}` ); } - material.metaPosition = { - type: 'vehicle', - vehicleId, - }; removeElementPosition(draftState, 'materials', material.id); + material.metaPosition = cloneDeepMutable( + VehiclePosition.create(vehicleId) + ); + break; } case 'personnel': { @@ -328,15 +326,15 @@ export namespace VehicleActionReducers { `Personnel with id ${personnel.id} is not assignable to the vehicle with id ${vehicle.id}` ); } - personnel.metaPosition = { - type: 'vehicle', - vehicleId, - }; removeElementPosition( draftState, 'personnel', personnel.id ); + personnel.metaPosition = cloneDeepMutable( + VehiclePosition.create(vehicleId) + ); + break; } case 'patients': { @@ -354,27 +352,24 @@ export namespace VehicleActionReducers { ); } vehicle.patientIds[elementToBeLoadedId] = true; - - patient.metaPosition = { - type: 'vehicle', - vehicleId, - }; removeElementPosition(draftState, 'patients', patient.id); + patient.metaPosition = cloneDeepMutable( + VehiclePosition.create(vehicleId) + ); // Load in all materials Object.keys(vehicle.materialIds).forEach((materialId) => { - getElement( + removeElementPosition( draftState, 'materials', materialId - ).metaPosition = { - type: 'vehicle', - vehicleId, - }; - removeElementPosition( + ); + getElement( draftState, 'materials', materialId + ).metaPosition = cloneDeepMutable( + VehiclePosition.create(vehicleId) ); }); @@ -387,18 +382,17 @@ export namespace VehicleActionReducers { .transfer === undefined ) .forEach((personnelId) => { - getElement( + removeElementPosition( draftState, 'personnel', personnelId - ).metaPosition = { - type: 'vehicle', - vehicleId, - }; - removeElementPosition( + ); + getElement( draftState, 'personnel', personnelId + ).metaPosition = cloneDeepMutable( + VehiclePosition.create(vehicleId) ); }); } diff --git a/shared/src/store/action-reducers/viewport.ts b/shared/src/store/action-reducers/viewport.ts index 13c3b1919..927d28e55 100644 --- a/shared/src/store/action-reducers/viewport.ts +++ b/shared/src/store/action-reducers/viewport.ts @@ -1,7 +1,7 @@ import { Type } from 'class-transformer'; import { IsString, IsUUID, ValidateNested } from 'class-validator'; import { Viewport } from '../../models'; -import { Position, Size } from '../../models/utils'; +import { MapPosition, Position, Size } from '../../models/utils'; import { cloneDeepMutable, UUID, uuidValidationOptions } from '../../utils'; import { IsValue } from '../../utils/validators'; import type { Action, ActionReducer } from '../action-reducer'; @@ -80,7 +80,9 @@ export namespace ViewportActionReducers { action: MoveViewportAction, reducer: (draftState, { viewportId, targetPosition }) => { const viewport = getElement(draftState, 'viewports', viewportId); - viewport.position = cloneDeepMutable(targetPosition); + viewport.metaPosition = cloneDeepMutable( + MapPosition.create(targetPosition) + ); return draftState; }, rights: 'trainer', @@ -90,7 +92,9 @@ export namespace ViewportActionReducers { action: ResizeViewportAction, reducer: (draftState, { viewportId, targetPosition, newSize }) => { const viewport = getElement(draftState, 'viewports', viewportId); - viewport.position = cloneDeepMutable(targetPosition); + viewport.metaPosition = cloneDeepMutable( + MapPosition.create(targetPosition) + ); viewport.size = cloneDeepMutable(newSize); return draftState; }, diff --git a/shared/src/utils/validators/is-metaposition.ts b/shared/src/utils/validators/is-metaposition.ts index d49ce6af4..09585bdf3 100644 --- a/shared/src/utils/validators/is-metaposition.ts +++ b/shared/src/utils/validators/is-metaposition.ts @@ -1,9 +1,9 @@ import { Type } from 'class-transformer'; -import { MapPosition } from '../../models/utils/map-position'; -import type { MetaPosition } from '../../models/utils/meta-position'; -import { SimulatedRegionPosition } from '../../models/utils/simulated-region-position'; +import { MapPosition } from '../../models/utils/position/map-position'; +import type { MetaPosition } from '../../models/utils/position/meta-position'; +import { SimulatedRegionPosition } from '../../models/utils/position/simulated-region-position'; import { TransferPosition } from '../../models/utils/position/transfer-position'; -import { VehiclePosition } from '../../models/utils/vehicle-position'; +import { VehiclePosition } from '../../models/utils/position/vehicle-position'; import { IsLiteralUnion } from './is-literal-union'; class MetaPositionBase { From 7f46247c173fde3038f4988697fb53cf85cf04dd Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Thu, 26 Jan 2023 09:59:24 +0100 Subject: [PATCH 03/22] Fix Lint --- .../src/store/action-reducers/utils/spatial-elements.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/shared/src/store/action-reducers/utils/spatial-elements.ts b/shared/src/store/action-reducers/utils/spatial-elements.ts index aede143ec..0eceb0cf2 100644 --- a/shared/src/store/action-reducers/utils/spatial-elements.ts +++ b/shared/src/store/action-reducers/utils/spatial-elements.ts @@ -1,5 +1,10 @@ -import { isOnMap, Position } from '../../../models/utils'; -import { MapPosition, isNotOnMap, coordinatesOf } from '../../../models/utils'; +import type { Position } from '../../../models/utils'; +import { + isOnMap, + MapPosition, + isNotOnMap, + coordinatesOf, +} from '../../../models/utils'; import { SpatialTree } from '../../../models/utils/spatial-tree'; import type { ExerciseState } from '../../../state'; import type { Mutable, UUID } from '../../../utils'; From 337d9232447b209983f2f1c3204dd477efc2346a Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Thu, 26 Jan 2023 13:42:59 +0100 Subject: [PATCH 04/22] Unify access onto metaPosition --- shared/src/models/patient.ts | 7 - shared/src/models/personnel.ts | 4 - .../position/meta-position-helpers-mutable.ts | 100 +++++++++++ .../utils/position/meta-position-helpers.ts | 74 +++++++++ .../src/store/action-reducers/map-images.ts | 8 +- shared/src/store/action-reducers/material.ts | 12 +- shared/src/store/action-reducers/patient.ts | 29 ++-- shared/src/store/action-reducers/personnel.ts | 12 +- .../store/action-reducers/simulated-region.ts | 21 ++- .../store/action-reducers/transfer-point.ts | 11 +- shared/src/store/action-reducers/transfer.ts | 39 ++--- .../utils/calculate-treatments.spec.ts | 24 +-- .../action-reducers/utils/spatial-elements.ts | 12 +- shared/src/store/action-reducers/vehicle.ts | 157 +++++++++--------- shared/src/store/action-reducers/viewport.ts | 19 ++- 15 files changed, 353 insertions(+), 176 deletions(-) create mode 100644 shared/src/models/utils/position/meta-position-helpers-mutable.ts diff --git a/shared/src/models/patient.ts b/shared/src/models/patient.ts index 3e58f1310..1380e4b9b 100644 --- a/shared/src/models/patient.ts +++ b/shared/src/models/patient.ts @@ -67,9 +67,6 @@ export class Patient { @ValidateNested() public readonly metaPosition: MetaPosition; - /** - * @deprecated use {@link metaPosition} - */ @IsUUID(4, uuidValidationOptions) @IsOptional() public readonly vehicleId?: UUID; @@ -188,10 +185,6 @@ export class Patient { return patient.treatmentTime >= this.pretriageTimeThreshold; } - static isInVehicle(patient: Patient): boolean { - return patient.metaPosition.type === 'vehicle'; - } - static isTreatedByPersonnel(patient: Patient) { return !isEmpty(patient.assignedPersonnelIds); } diff --git a/shared/src/models/personnel.ts b/shared/src/models/personnel.ts index 3e39a0c35..4460511d0 100644 --- a/shared/src/models/personnel.ts +++ b/shared/src/models/personnel.ts @@ -128,8 +128,4 @@ export class Personnel { undefined ); } - - static isInVehicle(personnel: Personnel): boolean { - return personnel.metaPosition.type === 'vehicle'; - } } diff --git a/shared/src/models/utils/position/meta-position-helpers-mutable.ts b/shared/src/models/utils/position/meta-position-helpers-mutable.ts new file mode 100644 index 000000000..c93010bdd --- /dev/null +++ b/shared/src/models/utils/position/meta-position-helpers-mutable.ts @@ -0,0 +1,100 @@ +import type { ExerciseState } from '../../../state'; +import { getElement } from '../../../store/action-reducers/utils'; +import { updateTreatments } from '../../../store/action-reducers/utils/calculate-treatments'; +import type { SpatialElementType } from '../../../store/action-reducers/utils/spatial-elements'; +import { + removeElementPosition, + updateElementPosition, +} from '../../../store/action-reducers/utils/spatial-elements'; +import type { Mutable, UUID } from '../../../utils'; +import { cloneDeepMutable } from '../../../utils'; +import type { MetaPosition } from './meta-position'; +import { + coordinatesOfMetaPosition, + isMetaPositionNotOnMap, + isMetaPositionOnMap, + isNotOnMap, + isOnMap, +} from './meta-position-helpers'; + +type MutableMetaPosition = Mutable; + +interface WithMutableMetaPosition { + metaPosition: MutableMetaPosition; +} +interface WithMutableMetaPositionAndId extends WithMutableMetaPosition { + id: UUID; +} +type ElementType = + | 'alarmGroups' + | 'clients' + | 'hospitals' + | 'mapImages' + | 'materials' + | 'patients' + | 'personnel' + | 'simulatedRegions' + | 'transferPoints' + | 'vehicles' + | 'viewports'; + +export function changePositionWithId( + of: UUID, + to: MetaPosition, + type: ElementType, + inState: Mutable +) { + changePosition( + getElement(inState, type, of) as any, + to, + type === 'personnel' || type === 'materials' || type === 'patients' + ? type + : false, + inState + ); +} + +export function changePosition( + of: WithMutableMetaPosition, + to: MetaPosition, + type: SpatialElementType | false, + inState: Mutable +) { + if (type) { + updateSpatialElementTree( + of as WithMutableMetaPositionAndId, + to, + type, + inState + ); + of.metaPosition = cloneDeepMutable(to); + updateTreatments(inState, of as any); + return; + } + of.metaPosition = cloneDeepMutable(to); +} + +function updateSpatialElementTree( + element: WithMutableMetaPositionAndId, + to: MetaPosition, + type: SpatialElementType, + state: Mutable +) { + if (isOnMap(element) && isMetaPositionOnMap(to)) { + updateElementPosition( + state, + type, + element.id, + coordinatesOfMetaPosition(to) + ); + } else if (isOnMap(element) && isMetaPositionNotOnMap(to)) { + removeElementPosition(state, type, element.id); + } else if (isNotOnMap(element) && isMetaPositionOnMap(to)) { + updateElementPosition( + state, + type, + element.id, + coordinatesOfMetaPosition(to) + ); + } +} diff --git a/shared/src/models/utils/position/meta-position-helpers.ts b/shared/src/models/utils/position/meta-position-helpers.ts index 123e7afc4..59513222e 100644 --- a/shared/src/models/utils/position/meta-position-helpers.ts +++ b/shared/src/models/utils/position/meta-position-helpers.ts @@ -2,6 +2,7 @@ import type { UUID } from '../../../utils'; import type { Transfer } from '../transfer'; import type { MapCoordinates } from './map-coordinates'; import type { MapPosition } from './map-position'; +import type { MetaPosition } from './meta-position'; import type { SimulatedRegionPosition } from './simulated-region-position'; import type { TransferPosition } from './transfer-position'; import type { VehiclePosition } from './vehicle-position'; @@ -74,3 +75,76 @@ export function simulatedRegionItsIn(withMetaPosition: WithMetaPosition): UUID { `Expected metaPosition of object to be in simulatedRegion. Was of type ${withMetaPosition.metaPosition.type}.` ); } + +export function isMetaPositionOnMap(metaPosition: MetaPosition): boolean { + return metaPosition.type === 'coordinates'; +} +export function isMetaPositionInVehicle(metaPosition: MetaPosition): boolean { + return metaPosition.type === 'vehicle'; +} +export function isMetaPositionInTransfer(metaPosition: MetaPosition): boolean { + return metaPosition.type === 'transfer'; +} +export function isMetaPositionInSimulatedRegion( + metaPosition: MetaPosition +): boolean { + return metaPosition.type === 'simulatedRegion'; +} +export function isMetaPositionNotOnMap(metaPosition: MetaPosition): boolean { + return !isMetaPositionOnMap(metaPosition); +} +export function isMetaPositionNotInVehicle( + metaPosition: MetaPosition +): boolean { + return !isMetaPositionInVehicle(metaPosition); +} +export function isMetaPositionNotInTransfer( + metaPosition: MetaPosition +): boolean { + return !isMetaPositionInTransfer(metaPosition); +} +export function isMetaPositionNotInSimulatedRegion( + metaPosition: MetaPosition +): boolean { + return !isMetaPositionInSimulatedRegion(metaPosition); +} + +export function coordinatesOfMetaPosition( + metaPosition: MetaPosition +): MapCoordinates { + if (isMetaPositionOnMap(metaPosition)) { + return (metaPosition as MapPosition).position; + } + throw new TypeError( + `Expected metaPosition of object to be on Map. Was of type ${metaPosition.type}.` + ); +} + +export function vehicleMetaPositionIn(metaPosition: MetaPosition): UUID { + if (isMetaPositionInVehicle(metaPosition)) { + return (metaPosition as VehiclePosition).vehicleId; + } + throw new TypeError( + `Expected metaPosition of object to be in vehicle. Was of type ${metaPosition.type}.` + ); +} + +export function transferMetaPositionIn(metaPosition: MetaPosition): Transfer { + if (isMetaPositionInTransfer(metaPosition)) { + return (metaPosition as TransferPosition).transfer; + } + throw new TypeError( + `Expected metaPosition of object to be in transfer. Was of type ${metaPosition.type}.` + ); +} + +export function simulatedRegionMetaPositionIn( + metaPosition: MetaPosition +): UUID { + if (isMetaPositionInSimulatedRegion(metaPosition)) { + return (metaPosition as SimulatedRegionPosition).simulatedRegionId; + } + throw new TypeError( + `Expected metaPosition of object to be in simulatedRegion. Was of type ${metaPosition.type}.` + ); +} diff --git a/shared/src/store/action-reducers/map-images.ts b/shared/src/store/action-reducers/map-images.ts index c09999054..fb710b402 100644 --- a/shared/src/store/action-reducers/map-images.ts +++ b/shared/src/store/action-reducers/map-images.ts @@ -10,6 +10,7 @@ import { } from 'class-validator'; import { MapImage } from '../../models'; import { MapPosition, Position } from '../../models/utils'; +import { changePosition } from '../../models/utils/position/meta-position-helpers-mutable'; import type { ExerciseState } from '../../state'; import type { Mutable } from '../../utils'; import { @@ -134,8 +135,11 @@ export namespace MapImagesActionReducers { action: MoveMapImageAction, reducer: (draftState, { mapImageId, targetPosition }) => { const mapImage = getElement(draftState, 'mapImages', mapImageId); - mapImage.metaPosition = cloneDeepMutable( - MapPosition.create(targetPosition) + changePosition( + mapImage, + MapPosition.create(targetPosition), + false, + draftState ); return draftState; }, diff --git a/shared/src/store/action-reducers/material.ts b/shared/src/store/action-reducers/material.ts index a38b201ab..947de8cd4 100644 --- a/shared/src/store/action-reducers/material.ts +++ b/shared/src/store/action-reducers/material.ts @@ -1,10 +1,10 @@ import { Type } from 'class-transformer'; import { IsUUID, ValidateNested } from 'class-validator'; -import { Position } from '../../models/utils'; +import { MapPosition, Position } from '../../models/utils'; +import { changePositionWithId } from '../../models/utils/position/meta-position-helpers-mutable'; import { UUID, uuidValidationOptions } from '../../utils'; import { IsValue } from '../../utils/validators'; import type { Action, ActionReducer } from '../action-reducer'; -import { updateElementPosition } from './utils/spatial-elements'; export class MoveMaterialAction implements Action { @IsValue('[Material] Move material' as const) @@ -22,11 +22,11 @@ export namespace MaterialActionReducers { export const moveMaterial: ActionReducer = { action: MoveMaterialAction, reducer: (draftState, { materialId, targetPosition }) => { - updateElementPosition( - draftState, - 'materials', + changePositionWithId( materialId, - targetPosition + MapPosition.create(targetPosition), + 'materials', + draftState ); return draftState; }, diff --git a/shared/src/store/action-reducers/patient.ts b/shared/src/store/action-reducers/patient.ts index d25fca861..b92768b18 100644 --- a/shared/src/store/action-reducers/patient.ts +++ b/shared/src/store/action-reducers/patient.ts @@ -2,10 +2,16 @@ import { Type } from 'class-transformer'; import { IsString, IsUUID, MaxLength, ValidateNested } from 'class-validator'; import { Patient } from '../../models'; import { + isOnMap, + MapPosition, PatientStatus, patientStatusAllowedValues, Position, } from '../../models/utils'; +import { + changePosition, + changePositionWithId, +} from '../../models/utils/position/meta-position-helpers-mutable'; import type { ExerciseState } from '../../state'; import type { Mutable } from '../../utils'; import { @@ -19,11 +25,7 @@ import type { Action, ActionReducer } from '../action-reducer'; import { ReducerError } from '../reducer-error'; import { updateTreatments } from './utils/calculate-treatments'; import { getElement } from './utils/get-element'; -import { - addElementPosition, - removeElementPosition, - updateElementPosition, -} from './utils/spatial-elements'; +import { removeElementPosition } from './utils/spatial-elements'; export function deletePatient( draftState: Mutable, @@ -120,7 +122,12 @@ export namespace PatientActionReducers { } const mutablePatient = cloneDeepMutable(patient); draftState.patients[mutablePatient.id] = mutablePatient; - addElementPosition(draftState, 'patients', mutablePatient.id); + changePosition( + mutablePatient, + patient.metaPosition, + 'patients', + draftState + ); return draftState; }, rights: 'trainer', @@ -129,11 +136,11 @@ export namespace PatientActionReducers { export const movePatient: ActionReducer = { action: MovePatientAction, reducer: (draftState, { patientId, targetPosition }) => { - updateElementPosition( - draftState, - 'patients', + changePositionWithId( patientId, - targetPosition + MapPosition.create(targetPosition), + 'patients', + draftState ); return draftState; }, @@ -155,7 +162,7 @@ export namespace PatientActionReducers { const patient = getElement(draftState, 'patients', patientId); patient.pretriageStatus = patientStatus; - if (patient.metaPosition.type === 'coordinates') { + if (isOnMap(patient)) { updateTreatments(draftState, patient); } diff --git a/shared/src/store/action-reducers/personnel.ts b/shared/src/store/action-reducers/personnel.ts index 843c122ed..dcdbc97be 100644 --- a/shared/src/store/action-reducers/personnel.ts +++ b/shared/src/store/action-reducers/personnel.ts @@ -1,10 +1,10 @@ import { Type } from 'class-transformer'; import { IsUUID, ValidateNested } from 'class-validator'; -import { Position } from '../../models/utils'; +import { MapPosition, Position } from '../../models/utils'; +import { changePositionWithId } from '../../models/utils/position/meta-position-helpers-mutable'; import { UUID, uuidValidationOptions } from '../../utils'; import { IsValue } from '../../utils/validators'; import type { Action, ActionReducer } from '../action-reducer'; -import { updateElementPosition } from './utils/spatial-elements'; export class MovePersonnelAction implements Action { @IsValue('[Personnel] Move personnel' as const) @@ -22,11 +22,11 @@ export namespace PersonnelActionReducers { export const movePersonnel: ActionReducer = { action: MovePersonnelAction, reducer: (draftState, { personnelId, targetPosition }) => { - updateElementPosition( - draftState, - 'personnel', + changePositionWithId( personnelId, - targetPosition + MapPosition.create(targetPosition), + 'personnel', + draftState ); return draftState; }, diff --git a/shared/src/store/action-reducers/simulated-region.ts b/shared/src/store/action-reducers/simulated-region.ts index 6029e91b4..942555c1c 100644 --- a/shared/src/store/action-reducers/simulated-region.ts +++ b/shared/src/store/action-reducers/simulated-region.ts @@ -2,6 +2,10 @@ import { Type } from 'class-transformer'; import { IsString, IsUUID, ValidateNested } from 'class-validator'; import { SimulatedRegion } from '../../models'; import { MapPosition, Position, Size } from '../../models/utils'; +import { + changePosition, + changePositionWithId, +} from '../../models/utils/position/meta-position-helpers-mutable'; import { cloneDeepMutable, UUID, uuidValidationOptions } from '../../utils'; import { IsValue } from '../../utils/validators'; import type { Action, ActionReducer } from '../action-reducer'; @@ -82,13 +86,11 @@ export namespace SimulatedRegionActionReducers { { action: MoveSimulatedRegionAction, reducer: (draftState, { simulatedRegionId, targetPosition }) => { - const simulatedRegion = getElement( - draftState, + changePositionWithId( + simulatedRegionId, + MapPosition.create(targetPosition), 'simulatedRegions', - simulatedRegionId - ); - simulatedRegion.metaPosition = cloneDeepMutable( - MapPosition.create(targetPosition) + draftState ); return draftState; }, @@ -107,8 +109,11 @@ export namespace SimulatedRegionActionReducers { 'simulatedRegions', simulatedRegionId ); - simulatedRegion.metaPosition = cloneDeepMutable( - MapPosition.create(targetPosition) + changePosition( + simulatedRegion, + MapPosition.create(targetPosition), + false, + draftState ); simulatedRegion.size = cloneDeepMutable(newSize); return draftState; diff --git a/shared/src/store/action-reducers/transfer-point.ts b/shared/src/store/action-reducers/transfer-point.ts index e41675c07..f348b7ec1 100644 --- a/shared/src/store/action-reducers/transfer-point.ts +++ b/shared/src/store/action-reducers/transfer-point.ts @@ -8,6 +8,7 @@ import { } from 'class-validator'; import { TransferPoint } from '../../models'; import { coordinatesOf, MapPosition, Position } from '../../models/utils'; +import { changePositionWithId } from '../../models/utils/position/meta-position-helpers-mutable'; import { cloneDeepMutable, UUID, uuidValidationOptions } from '../../utils'; import { IsValue } from '../../utils/validators'; import type { Action, ActionReducer } from '../action-reducer'; @@ -122,13 +123,11 @@ export namespace TransferPointActionReducers { export const moveTransferPoint: ActionReducer = { action: MoveTransferPointAction, reducer: (draftState, { transferPointId, targetPosition }) => { - const transferPoint = getElement( - draftState, + changePositionWithId( + transferPointId, + MapPosition.create(targetPosition), 'transferPoints', - transferPointId - ); - transferPoint.metaPosition = cloneDeepMutable( - MapPosition.create(targetPosition) + draftState ); return draftState; }, diff --git a/shared/src/store/action-reducers/transfer.ts b/shared/src/store/action-reducers/transfer.ts index 4d2abb0af..d2569993f 100644 --- a/shared/src/store/action-reducers/transfer.ts +++ b/shared/src/store/action-reducers/transfer.ts @@ -3,11 +3,13 @@ import { IsInt, IsOptional, IsUUID, ValidateNested } from 'class-validator'; import { TransferPoint } from '../../models'; import type { Position } from '../../models/utils'; import { + TransferPosition, coordinatesOf, MapPosition, StartPoint, startPointTypeOptions, } from '../../models/utils'; +import { changePosition } from '../../models/utils/position/meta-position-helpers-mutable'; import type { ExerciseState } from '../../state'; import { imageSizeToPosition } from '../../state-helpers'; import type { Mutable } from '../../utils'; @@ -17,10 +19,6 @@ import { IsLiteralUnion, IsValue } from '../../utils/validators'; import type { Action, ActionReducer } from '../action-reducer'; import { ReducerError } from '../reducer-error'; import { getElement } from './utils'; -import { - removeElementPosition, - updateElementPosition, -} from './utils/spatial-elements'; type TransferableElementType = 'personnel' | 'vehicles'; const transferableElementTypeAllowedValues: AllowedValues = @@ -53,13 +51,12 @@ export function letElementArrive( // Position it in the upper half of the transferPoint imageSizeToPosition(TransferPoint.image.height / 3), }; - if (elementType === 'personnel') { - updateElementPosition(draftState, 'personnel', element.id, newPosition); - } else { - element.metaPosition = cloneDeepMutable( - MapPosition.create(newPosition) - ); - } + changePosition( + element, + MapPosition.create(newPosition), + elementType === 'personnel' ? elementType : false, + draftState + ); delete element.transfer; } @@ -168,10 +165,6 @@ export namespace TransferActionReducers { duration = startPoint.duration; } - // Remove the position of the element - if (elementType === 'personnel') { - removeElementPosition(draftState, 'personnel', element.id); - } // Set the element to transfer element.transfer = { startPoint: cloneDeepMutable(startPoint), @@ -179,16 +172,12 @@ export namespace TransferActionReducers { endTimeStamp: draftState.currentTime + duration, isPaused: false, }; - - element.metaPosition = { - type: 'transfer', - transfer: { - startPoint: cloneDeepMutable(startPoint), - targetTransferPointId, - endTimeStamp: draftState.currentTime + duration, - isPaused: false, - }, - }; + changePosition( + element, + TransferPosition.create(element.transfer), + elementType === 'personnel' ? elementType : false, + draftState + ); return draftState; }, diff --git a/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts b/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts index e811becfc..777a2d1d0 100644 --- a/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts +++ b/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts @@ -5,10 +5,15 @@ import { defaultPersonnelTemplates } from '../../../data/default-state/personnel import type { Patient } from '../../../models'; import { Material, Personnel } from '../../../models'; import type { MetaPosition, PatientStatus } from '../../../models/utils'; -import { CanCaterFor, Position } from '../../../models/utils'; -import { MapPosition } from '../../../models/utils/map-position'; +import { + coordinatesOf, + isMetaPositionOnMap, + CanCaterFor, + Position, +} from '../../../models/utils'; +import { MapPosition } from '../../../models/utils/position/map-position'; import { SpatialTree } from '../../../models/utils/spatial-tree'; -import { VehiclePosition } from '../../../models/utils/vehicle-position'; +import { VehiclePosition } from '../../../models/utils/position/vehicle-position'; import { ExerciseState } from '../../../state'; import type { Mutable, UUID } from '../../../utils'; import { cloneDeepMutable, uuid } from '../../../utils'; @@ -77,7 +82,6 @@ function addPatient( patient.pretriageStatus = pretriageStatus; patient.realStatus = realStatus; if (position) { - patient.position = cloneDeepMutable(position); patient.metaPosition = { type: 'coordinates', position: cloneDeepMutable(position), @@ -85,7 +89,7 @@ function addPatient( SpatialTree.addElement( state.spatialTrees.patients, patient.id, - patient.position + position ); } state.patients[patient.id] = patient; @@ -110,12 +114,11 @@ function addPersonnel( green: 0, logicalOperator: 'and', }; - if (metaPosition.type === 'coordinates') { - personnel.position = cloneDeepMutable(metaPosition.position); + if (isMetaPositionOnMap(metaPosition)) { SpatialTree.addElement( state.spatialTrees.personnel, personnel.id, - personnel.position + coordinatesOf(personnel) ); } state.personnel[personnel.id] = personnel; @@ -140,12 +143,11 @@ function addMaterial( green: 0, logicalOperator: 'and', }; - if (metaPosition.type === 'coordinates') { - material.position = cloneDeepMutable(metaPosition.position); + if (isMetaPositionOnMap(metaPosition)) { SpatialTree.addElement( state.spatialTrees.materials, material.id, - material.position + coordinatesOf(material) ); } state.materials[material.id] = material; diff --git a/shared/src/store/action-reducers/utils/spatial-elements.ts b/shared/src/store/action-reducers/utils/spatial-elements.ts index 0eceb0cf2..efd1a6599 100644 --- a/shared/src/store/action-reducers/utils/spatial-elements.ts +++ b/shared/src/store/action-reducers/utils/spatial-elements.ts @@ -1,15 +1,9 @@ import type { Position } from '../../../models/utils'; -import { - isOnMap, - MapPosition, - isNotOnMap, - coordinatesOf, -} from '../../../models/utils'; +import { isOnMap, isNotOnMap, coordinatesOf } from '../../../models/utils'; import { SpatialTree } from '../../../models/utils/spatial-tree'; import type { ExerciseState } from '../../../state'; import type { Mutable, UUID } from '../../../utils'; import { cloneDeepMutable } from '../../../utils'; -import { updateTreatments } from './calculate-treatments'; import { getElement } from './get-element'; /** @@ -37,7 +31,6 @@ export function addElementPosition( element.id, coordinatesOf(element) ); - updateTreatments(state, element); } /** @@ -65,8 +58,6 @@ export function updateElementPosition( targetPosition ); } - element.metaPosition = cloneDeepMutable(MapPosition.create(targetPosition)); - updateTreatments(state, element); } /** @@ -87,5 +78,4 @@ export function removeElementPosition( element.id, cloneDeepMutable(coordinatesOf(element)) ); - updateTreatments(state, element); } diff --git a/shared/src/store/action-reducers/vehicle.ts b/shared/src/store/action-reducers/vehicle.ts index dfdc66afa..3de10b551 100644 --- a/shared/src/store/action-reducers/vehicle.ts +++ b/shared/src/store/action-reducers/vehicle.ts @@ -1,7 +1,19 @@ import { Type } from 'class-transformer'; import { IsArray, IsString, IsUUID, ValidateNested } from 'class-validator'; import { Material, Personnel, Vehicle } from '../../models'; -import { MapPosition, Position, VehiclePosition } from '../../models/utils'; +import { + coordinatesOf, + isInVehicle, + isNotOnMap, + MapCoordinates, + MapPosition, + Position, + VehiclePosition, +} from '../../models/utils'; +import { + changePosition, + changePositionWithId, +} from '../../models/utils/position/meta-position-helpers-mutable'; import type { ExerciseState } from '../../state'; import { imageSizeToPosition } from '../../state-helpers'; import type { Mutable } from '../../utils'; @@ -16,11 +28,7 @@ import type { Action, ActionReducer } from '../action-reducer'; import { ReducerError } from '../reducer-error'; import { deletePatient } from './patient'; import { getElement } from './utils/get-element'; -import { - addElementPosition, - removeElementPosition, - updateElementPosition, -} from './utils/spatial-elements'; +import { removeElementPosition } from './utils/spatial-elements'; export function deleteVehicle( draftState: Mutable, @@ -150,20 +158,22 @@ export namespace VehicleActionReducers { } draftState.vehicles[vehicle.id] = cloneDeepMutable(vehicle); for (const material of cloneDeepMutable(materials)) { - material.metaPosition = { - type: 'vehicle', - vehicleId: vehicle.id, - }; + changePosition( + material, + VehiclePosition.create(vehicle.id), + 'materials', + draftState + ); draftState.materials[material.id] = material; - addElementPosition(draftState, 'materials', material.id); } for (const person of cloneDeepMutable(personnel)) { - person.metaPosition = { - type: 'vehicle', - vehicleId: vehicle.id, - }; + changePosition( + person, + VehiclePosition.create(vehicle.id), + 'personnel', + draftState + ); draftState.personnel[person.id] = person; - addElementPosition(draftState, 'personnel', person.id); } return draftState; }, @@ -173,9 +183,11 @@ export namespace VehicleActionReducers { export const moveVehicle: ActionReducer = { action: MoveVehicleAction, reducer: (draftState, { vehicleId, targetPosition }) => { - const vehicle = getElement(draftState, 'vehicles', vehicleId); - vehicle.metaPosition = cloneDeepMutable( - MapPosition.create(targetPosition) + changePositionWithId( + vehicleId, + MapPosition.create(targetPosition), + 'vehicles', + draftState ); return draftState; }, @@ -211,13 +223,12 @@ export namespace VehicleActionReducers { action: UnloadVehicleAction, reducer: (draftState, { vehicleId }) => { const vehicle = getElement(draftState, 'vehicles', vehicleId); - const unloadMetaPosition = vehicle.metaPosition; - if (unloadMetaPosition.type !== 'coordinates') { + if (isNotOnMap(vehicle)) { throw new ReducerError( `Vehicle with id ${vehicleId} is currently not on the map` ); } - const unloadPosition = unloadMetaPosition.position; + const unloadPosition = coordinatesOf(vehicle); const materialIds = Object.keys(vehicle.materialIds); const personnelIds = Object.keys(vehicle.personnelIds); const patientIds = Object.keys(vehicle.patientIds); @@ -237,10 +248,14 @@ export namespace VehicleActionReducers { for (const patientId of patientIds) { x += space; - updateElementPosition(draftState, 'patients', patientId, { - x, - y: unloadPosition.y, - }); + changePositionWithId( + patientId, + MapPosition.create( + MapCoordinates.create(x, unloadPosition.y) + ), + 'patients', + draftState + ); delete vehicle.patientIds[patientId]; } @@ -251,15 +266,14 @@ export namespace VehicleActionReducers { 'personnel', personnelId ); - if (Personnel.isInVehicle(personnel)) { - updateElementPosition( - draftState, - 'personnel', + if (isInVehicle(personnel)) { + changePositionWithId( personnelId, - { - x, - y: unloadPosition.y, - } + MapPosition.create( + MapCoordinates.create(x, unloadPosition.y) + ), + 'personnel', + draftState ); } } @@ -271,11 +285,15 @@ export namespace VehicleActionReducers { 'materials', materialId ); - if (Material.isInVehicle(material)) { - updateElementPosition(draftState, 'materials', materialId, { - x, - y: unloadPosition.y, - }); + if (isInVehicle(material)) { + changePosition( + material, + MapPosition.create( + MapCoordinates.create(x, unloadPosition.y) + ), + 'materials', + draftState + ); } } @@ -303,11 +321,12 @@ export namespace VehicleActionReducers { `Material with id ${material.id} is not assignable to the vehicle with id ${vehicle.id}` ); } - removeElementPosition(draftState, 'materials', material.id); - material.metaPosition = cloneDeepMutable( - VehiclePosition.create(vehicleId) + changePosition( + material, + VehiclePosition.create(vehicleId), + 'materials', + draftState ); - break; } case 'personnel': { @@ -326,15 +345,12 @@ export namespace VehicleActionReducers { `Personnel with id ${personnel.id} is not assignable to the vehicle with id ${vehicle.id}` ); } - removeElementPosition( - draftState, + changePosition( + personnel, + VehiclePosition.create(vehicleId), 'personnel', - personnel.id - ); - personnel.metaPosition = cloneDeepMutable( - VehiclePosition.create(vehicleId) + draftState ); - break; } case 'patients': { @@ -352,24 +368,19 @@ export namespace VehicleActionReducers { ); } vehicle.patientIds[elementToBeLoadedId] = true; - removeElementPosition(draftState, 'patients', patient.id); - patient.metaPosition = cloneDeepMutable( - VehiclePosition.create(vehicleId) + changePosition( + patient, + VehiclePosition.create(vehicleId), + 'patients', + draftState ); - // Load in all materials Object.keys(vehicle.materialIds).forEach((materialId) => { - removeElementPosition( - draftState, - 'materials', - materialId - ); - getElement( - draftState, + changePosition( + getElement(draftState, 'materials', materialId), + VehiclePosition.create(vehicleId), 'materials', - materialId - ).metaPosition = cloneDeepMutable( - VehiclePosition.create(vehicleId) + draftState ); }); @@ -382,17 +393,15 @@ export namespace VehicleActionReducers { .transfer === undefined ) .forEach((personnelId) => { - removeElementPosition( - draftState, - 'personnel', - personnelId - ); - getElement( - draftState, + changePosition( + getElement( + draftState, + 'personnel', + personnelId + ), + VehiclePosition.create(vehicleId), 'personnel', - personnelId - ).metaPosition = cloneDeepMutable( - VehiclePosition.create(vehicleId) + draftState ); }); } diff --git a/shared/src/store/action-reducers/viewport.ts b/shared/src/store/action-reducers/viewport.ts index 927d28e55..e0d7debf6 100644 --- a/shared/src/store/action-reducers/viewport.ts +++ b/shared/src/store/action-reducers/viewport.ts @@ -2,6 +2,10 @@ import { Type } from 'class-transformer'; import { IsString, IsUUID, ValidateNested } from 'class-validator'; import { Viewport } from '../../models'; import { MapPosition, Position, Size } from '../../models/utils'; +import { + changePosition, + changePositionWithId, +} from '../../models/utils/position/meta-position-helpers-mutable'; import { cloneDeepMutable, UUID, uuidValidationOptions } from '../../utils'; import { IsValue } from '../../utils/validators'; import type { Action, ActionReducer } from '../action-reducer'; @@ -79,9 +83,11 @@ export namespace ViewportActionReducers { export const moveViewport: ActionReducer = { action: MoveViewportAction, reducer: (draftState, { viewportId, targetPosition }) => { - const viewport = getElement(draftState, 'viewports', viewportId); - viewport.metaPosition = cloneDeepMutable( - MapPosition.create(targetPosition) + changePositionWithId( + viewportId, + MapPosition.create(targetPosition), + 'viewports', + draftState ); return draftState; }, @@ -92,8 +98,11 @@ export namespace ViewportActionReducers { action: ResizeViewportAction, reducer: (draftState, { viewportId, targetPosition, newSize }) => { const viewport = getElement(draftState, 'viewports', viewportId); - viewport.metaPosition = cloneDeepMutable( - MapPosition.create(targetPosition) + changePosition( + viewport, + MapPosition.create(targetPosition), + false, + draftState ); viewport.size = cloneDeepMutable(newSize); return draftState; From b51afac5b57b5776bc0d7f3e3f3efde085188532 Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Thu, 26 Jan 2023 13:56:37 +0100 Subject: [PATCH 05/22] Fix Frontend --- .../core/statistics/statistics.service.ts | 17 ++++++------- .../vehicle-popup/vehicle-popup.component.ts | 10 ++++---- .../src/store/reduce-exercise-state.spec.ts | 3 ++- .../store/validate-exercise-action.spec.ts | 24 ++++++++++++------- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/frontend/src/app/pages/exercises/exercise/shared/core/statistics/statistics.service.ts b/frontend/src/app/pages/exercises/exercise/shared/core/statistics/statistics.service.ts index 1d58d25b5..ebbfdb9bf 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/core/statistics/statistics.service.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/core/statistics/statistics.service.ts @@ -1,19 +1,20 @@ import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; -import type { - Client, - ExerciseState, - Patient, - Vehicle, -} from 'digital-fuesim-manv-shared'; import { + isNotInVehicle, coordinatesOf, isOnMap, loopTroughTime, - Personnel, uuid, Viewport, } from 'digital-fuesim-manv-shared'; +import type { + Personnel, + Client, + ExerciseState, + Patient, + Vehicle, +} from 'digital-fuesim-manv-shared'; import { countBy } from 'lodash-es'; import { ReplaySubject } from 'rxjs'; import { ApiService } from 'src/app/core/api.service'; @@ -159,7 +160,7 @@ export class StatisticsService { personnel: countBy( personnel.filter( (_personnel) => - !Personnel.isInVehicle(_personnel) && + isNotInVehicle(_personnel) && _personnel.transfer === undefined ), (_personnel) => _personnel.personnelType diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/shared/vehicle-popup/vehicle-popup.component.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/shared/vehicle-popup/vehicle-popup.component.ts index fc13ff075..915c822bf 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/shared/vehicle-popup/vehicle-popup.component.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/shared/vehicle-popup/vehicle-popup.component.ts @@ -2,7 +2,7 @@ import type { OnInit } from '@angular/core'; import { Component, EventEmitter, Output } from '@angular/core'; import { Store } from '@ngrx/store'; import type { UUID, Vehicle } from 'digital-fuesim-manv-shared'; -import { Material, Patient, Personnel } from 'digital-fuesim-manv-shared'; +import { isInVehicle, Material } from 'digital-fuesim-manv-shared'; import type { Observable } from 'rxjs'; import { combineLatest, map, switchMap } from 'rxjs'; import { ExerciseService } from 'src/app/core/exercise.service'; @@ -52,16 +52,14 @@ export class VehiclePopupComponent implements PopupComponent, OnInit { ).map((personnelId) => this.store .select(createSelectPersonnel(personnelId)) - .pipe( - map((personnel) => Personnel.isInVehicle(personnel)) - ) + .pipe(map((personnel) => isInVehicle(personnel))) ); const patientsAreInVehicle$ = Object.keys( _vehicle.patientIds ).map((patientId) => this.store .select(createSelectPatient(patientId)) - .pipe(map((patient) => Patient.isInVehicle(patient))) + .pipe(map((patient) => isInVehicle(patient))) ); return combineLatest([ ...materialsAreInVehicle$, @@ -70,7 +68,7 @@ export class VehiclePopupComponent implements PopupComponent, OnInit { ]); }), map((areInVehicle) => - areInVehicle.every((isInVehicle) => !isInVehicle) + areInVehicle.every((isInAVehicle) => !isInAVehicle) ) ); } diff --git a/shared/src/store/reduce-exercise-state.spec.ts b/shared/src/store/reduce-exercise-state.spec.ts index 49afadc2d..08726d289 100644 --- a/shared/src/store/reduce-exercise-state.spec.ts +++ b/shared/src/store/reduce-exercise-state.spec.ts @@ -1,5 +1,6 @@ import type { Viewport } from '../models'; import type { ExerciseStatus } from '../models/utils'; +import { MapCoordinates, MapPosition } from '../models/utils'; import { ExerciseState } from '../state'; import type { UUID } from '../utils'; import { uuid } from '../utils'; @@ -14,7 +15,7 @@ describe('exerciseReducer', () => { id: uuid(), name: 'Test', size: { width: 100, height: 100 }, - position: { x: 0, y: 0 }, + metaPosition: MapPosition.create(MapCoordinates.create(0, 0)), } as const; } diff --git a/shared/src/store/validate-exercise-action.spec.ts b/shared/src/store/validate-exercise-action.spec.ts index 9bc74a97d..63ccb39af 100644 --- a/shared/src/store/validate-exercise-action.spec.ts +++ b/shared/src/store/validate-exercise-action.spec.ts @@ -76,10 +76,13 @@ describe('validateExerciseAction', () => { height: 1, width: 1, }, - position: { - // this is of type string instead of number - x: '0' as unknown as number, - y: 0, + metaPosition: { + type: 'coordinates', + position: { + // this is of type string instead of number + x: '0' as unknown as number, + y: 0, + }, }, }, }) @@ -117,11 +120,14 @@ describe('validateExerciseAction', () => { height: 1, width: 1, }, - position: { - x: 0, - y: 0, - z: 0, - } as unknown as Position, + metaPosition: { + type: 'coordinates', + position: { + x: 0, + y: 0, + z: 0, + } as unknown as Position, + }, }, }) ).not.toEqual([]); From d4d84993840c9e6157752ad3e3c0574b8dc7bebf Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Thu, 26 Jan 2023 15:05:40 +0100 Subject: [PATCH 06/22] Remove Position Class --- .../send-alarm-group-interface.component.ts | 4 ++-- .../element-feature-manager.ts | 6 ++++-- .../simulated-region-feature-manager.ts | 4 ++-- .../viewport-feature-manager.ts | 4 ++-- .../utility/translate-interaction.ts | 12 +++++------ .../src/app/shared/types/catering-line.ts | 6 +++--- .../src/app/shared/types/transfer-line.ts | 6 +++--- shared/src/models/material.ts | 4 ++-- shared/src/models/personnel.ts | 4 ++-- shared/src/models/utils/index.ts | 1 - shared/src/models/utils/position.ts | 20 ------------------- shared/src/models/utils/spatial-tree.ts | 16 +++++++-------- .../create-vehicle-parameters.ts | 4 ++-- .../src/store/action-reducers/map-images.ts | 6 +++--- shared/src/store/action-reducers/material.ts | 6 +++--- shared/src/store/action-reducers/patient.ts | 6 +++--- shared/src/store/action-reducers/personnel.ts | 6 +++--- .../store/action-reducers/simulated-region.ts | 10 +++++----- .../store/action-reducers/transfer-point.ts | 11 ++++++---- shared/src/store/action-reducers/transfer.ts | 4 ++-- .../utils/calculate-distance.ts | 4 ++-- .../utils/calculate-treatments.ts | 4 ++-- .../action-reducers/utils/spatial-elements.ts | 4 ++-- shared/src/store/action-reducers/vehicle.ts | 5 ++--- shared/src/store/action-reducers/viewport.ts | 10 +++++----- 25 files changed, 75 insertions(+), 92 deletions(-) delete mode 100644 shared/src/models/utils/position.ts diff --git a/frontend/src/app/pages/exercises/exercise/shared/emergency-operations-center/send-alarm-group-interface/send-alarm-group-interface.component.ts b/frontend/src/app/pages/exercises/exercise/shared/emergency-operations-center/send-alarm-group-interface/send-alarm-group-interface.component.ts index 15b9189ab..d73e00b5e 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/emergency-operations-center/send-alarm-group-interface/send-alarm-group-interface.component.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/emergency-operations-center/send-alarm-group-interface/send-alarm-group-interface.component.ts @@ -3,7 +3,7 @@ import { Component } from '@angular/core'; import { Store } from '@ngrx/store'; import type { AlarmGroup, UUID } from 'digital-fuesim-manv-shared'; import { - Position, + MapCoordinates, AlarmGroupStartPoint, createVehicleParameters, TransferPoint, @@ -100,7 +100,7 @@ export class SendAlarmGroupInterfaceComponent implements OnDestroy { // Here one should use a MetaPosition with the Transfer. // But this is part of later Refactoring. // Also it is irrelevant, because the correctMetaPosition is set immediately after this is called. - Position.create(0, 0) + MapCoordinates.create(0, 0) ); return [ diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/element-feature-manager.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/element-feature-manager.ts index 4164ec5ae..166c3112c 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/element-feature-manager.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/element-feature-manager.ts @@ -2,7 +2,7 @@ import type { ExerciseState, MetaPosition, WithMetaPosition, - Position, + MapCoordinates, Size, UUID, } from 'digital-fuesim-manv-shared'; @@ -103,7 +103,9 @@ export abstract class ElementFeatureManager< protected readonly olMap: OlMap, public readonly layer: VectorLayer>, private readonly proposeMovementAction: ( - newPosition: FeatureType extends Point ? Position : Position[], + newPosition: FeatureType extends Point + ? MapCoordinates + : MapCoordinates[], element: Element ) => void, private readonly createElement: (element: Element) => ElementFeature diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/simulated-region-feature-manager.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/simulated-region-feature-manager.ts index a69529aa9..aa827e43b 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/simulated-region-feature-manager.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/simulated-region-feature-manager.ts @@ -1,6 +1,6 @@ import type { Store } from '@ngrx/store'; import type { UUID, SimulatedRegion } from 'digital-fuesim-manv-shared'; -import { Position, Size } from 'digital-fuesim-manv-shared'; +import { MapCoordinates, Size } from 'digital-fuesim-manv-shared'; import type { Feature, MapBrowserEvent } from 'ol'; import type LineString from 'ol/geom/LineString'; import type VectorLayer from 'ol/layer/Vector'; @@ -69,7 +69,7 @@ export class SimulatedRegionFeatureManager { type: '[SimulatedRegion] Resize simulated region', simulatedRegionId: element.id, - targetPosition: Position.create( + targetPosition: MapCoordinates.create( topLeftCoordinate[0]!, topLeftCoordinate[1]! ), diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/viewport-feature-manager.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/viewport-feature-manager.ts index 68ee0ea97..ebd8a5e21 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/viewport-feature-manager.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/viewport-feature-manager.ts @@ -1,6 +1,6 @@ import type { Store } from '@ngrx/store'; import type { UUID } from 'digital-fuesim-manv-shared'; -import { Position, Size, Viewport } from 'digital-fuesim-manv-shared'; +import { MapCoordinates, Size, Viewport } from 'digital-fuesim-manv-shared'; import type { Feature, MapBrowserEvent } from 'ol'; import type { Coordinate } from 'ol/coordinate'; import type LineString from 'ol/geom/LineString'; @@ -80,7 +80,7 @@ export class ViewportFeatureManager { type: '[Viewport] Resize viewport', viewportId: element.id, - targetPosition: Position.create( + targetPosition: MapCoordinates.create( topLeftCoordinate[0]!, topLeftCoordinate[1]! ), diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/translate-interaction.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/translate-interaction.ts index b78f05b38..8ae01f517 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/translate-interaction.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/translate-interaction.ts @@ -1,4 +1,4 @@ -import { Position } from 'digital-fuesim-manv-shared'; +import { MapCoordinates } from 'digital-fuesim-manv-shared'; import { isEqual } from 'lodash-es'; import type { Feature, MapBrowserEvent } from 'ol'; import type { LineString, Point } from 'ol/geom'; @@ -50,7 +50,7 @@ export class TranslateInteraction extends Translate { public static onTranslateEnd( feature: Feature, callback: ( - newCoordinates: T extends Point ? Position : Position[] + newCoordinates: T extends Point ? MapCoordinates : MapCoordinates[] ) => void ) { feature.addEventListener('translateend', (event) => { @@ -59,16 +59,16 @@ export class TranslateInteraction extends Translate { if (isCoordinateArray(coordinates)) { callback( coordinates.map((coordinate) => - Position.create(coordinate[0]!, coordinate[1]!) - ) as T extends Point ? never : Position[] + MapCoordinates.create(coordinate[0]!, coordinate[1]!) + ) as T extends Point ? never : MapCoordinates[] ); return; } callback( - Position.create( + MapCoordinates.create( coordinates[0]!, coordinates[1]! - ) as T extends Point ? Position : never + ) as T extends Point ? MapCoordinates : never ); }); } diff --git a/frontend/src/app/shared/types/catering-line.ts b/frontend/src/app/shared/types/catering-line.ts index 673762727..8326a5261 100644 --- a/frontend/src/app/shared/types/catering-line.ts +++ b/frontend/src/app/shared/types/catering-line.ts @@ -1,8 +1,8 @@ -import type { UUID, Position } from 'digital-fuesim-manv-shared'; +import type { UUID, MapCoordinates } from 'digital-fuesim-manv-shared'; export interface CateringLine { readonly id: `${UUID}:${UUID}`; - readonly catererPosition: Position; - readonly patientPosition: Position; + readonly catererPosition: MapCoordinates; + readonly patientPosition: MapCoordinates; } diff --git a/frontend/src/app/shared/types/transfer-line.ts b/frontend/src/app/shared/types/transfer-line.ts index 3c615d376..2769f4d7e 100644 --- a/frontend/src/app/shared/types/transfer-line.ts +++ b/frontend/src/app/shared/types/transfer-line.ts @@ -1,9 +1,9 @@ -import type { Position, UUID } from 'digital-fuesim-manv-shared'; +import type { MapCoordinates, UUID } from 'digital-fuesim-manv-shared'; export interface TransferLine { readonly id: `${UUID}:${UUID}`; - readonly startPosition: Position; - readonly endPosition: Position; + readonly startPosition: MapCoordinates; + readonly endPosition: MapCoordinates; readonly duration: number; } diff --git a/shared/src/models/material.ts b/shared/src/models/material.ts index 1ab19b7d8..533e54ba3 100644 --- a/shared/src/models/material.ts +++ b/shared/src/models/material.ts @@ -12,7 +12,7 @@ import { uuidValidationOptions, UUID, uuid, UUIDSet } from '../utils'; import { IsUUIDSet } from '../utils/validators'; import { IsMetaPosition } from '../utils/validators/is-metaposition'; import type { MaterialTemplate } from './material-template'; -import type { Position } from './utils'; +import type { MapCoordinates } from './utils'; import { CanCaterFor, ImageProperties, getCreate } from './utils'; import { MetaPosition } from './utils/position/meta-position'; @@ -73,7 +73,7 @@ export class Material { treatmentRange: number, overrideTreatmentRange: number, metaPosition: MetaPosition, - position?: Position + position?: MapCoordinates ) { this.vehicleId = vehicleId; this.vehicleName = vehicleName; diff --git a/shared/src/models/personnel.ts b/shared/src/models/personnel.ts index 4460511d0..e74e9729b 100644 --- a/shared/src/models/personnel.ts +++ b/shared/src/models/personnel.ts @@ -13,7 +13,7 @@ import { uuidValidationOptions, UUID, uuid, UUIDSet } from '../utils'; import { IsLiteralUnion, IsUUIDSet } from '../utils/validators'; import { IsMetaPosition } from '../utils/validators/is-metaposition'; import type { PersonnelTemplate } from './personnel-template'; -import type { Position } from './utils'; +import type { MapCoordinates } from './utils'; import { PersonnelType, CanCaterFor, @@ -94,7 +94,7 @@ export class Personnel { treatmentRange: number, overrideTreatmentRange: number, metaPosition: MetaPosition, - position?: Position + position?: MapCoordinates ) { this.vehicleId = vehicleId; this.vehicleName = vehicleName; diff --git a/shared/src/models/utils/index.ts b/shared/src/models/utils/index.ts index 27db93c17..81642ea06 100644 --- a/shared/src/models/utils/index.ts +++ b/shared/src/models/utils/index.ts @@ -1,4 +1,3 @@ -export { Position } from './position'; export { MetaPosition } from './position/meta-position'; export { WithMetaPosition } from './position/with-meta-position'; export { MapPosition } from './position/map-position'; diff --git a/shared/src/models/utils/position.ts b/shared/src/models/utils/position.ts deleted file mode 100644 index f61d5a5f9..000000000 --- a/shared/src/models/utils/position.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { IsNumber } from 'class-validator'; -import { getCreate } from './get-create'; - -export class Position { - @IsNumber() - public readonly x: number; - - @IsNumber() - public readonly y: number; - - /** - * @deprecated Use {@link create} instead - */ - constructor(x: number, y: number) { - this.x = x; - this.y = y; - } - - static readonly create = getCreate(this); -} diff --git a/shared/src/models/utils/spatial-tree.ts b/shared/src/models/utils/spatial-tree.ts index b617941aa..4be569944 100644 --- a/shared/src/models/utils/spatial-tree.ts +++ b/shared/src/models/utils/spatial-tree.ts @@ -9,7 +9,7 @@ import RBush from 'rbush'; import knn from 'rbush-knn'; import type { Mutable, UUID } from '../../utils'; import { ImmutableJsonObject } from '../../utils'; -import type { Position, Size } from '.'; +import type { MapCoordinates, Size } from '.'; import { getCreate } from '.'; /** @@ -64,7 +64,7 @@ export class SpatialTree { public static addElement( spatialTree: Mutable, elementId: UUID, - position: Position + position: MapCoordinates ) { const pointRBush = this.getPointRBush(spatialTree); pointRBush.insert({ @@ -77,7 +77,7 @@ export class SpatialTree { public static removeElement( spatialTree: Mutable, elementId: UUID, - position: Mutable | Position + position: MapCoordinates | Mutable ) { const pointRBush = this.getPointRBush(spatialTree); pointRBush.remove( @@ -93,8 +93,8 @@ export class SpatialTree { public static moveElement( spatialTree: Mutable, elementId: UUID, - startPosition: Mutable | Position, - targetPosition: Position + startPosition: MapCoordinates | Mutable, + targetPosition: MapCoordinates ) { // TODO: use the move function from RBush, when available: https://github.com/mourner/rbush/issues/28 this.removeElement(spatialTree, elementId, startPosition); @@ -109,7 +109,7 @@ export class SpatialTree { */ public static findAllElementsInCircle( spatialTree: Mutable, - circlePosition: Position, + circlePosition: MapCoordinates, radius: number ): UUID[] { // knn does not work great with `0`|`undefined` as it interprets either as `infinity` @@ -136,7 +136,7 @@ export class SpatialTree { */ public static findAllElementsInRectangle( spatialTree: Mutable, - topLeftPosition: Position, + topLeftPosition: MapCoordinates, size: Size ) { return this.getPointRBush(spatialTree).search({ @@ -154,7 +154,7 @@ export class SpatialTree { * @param id of the element */ interface PointRBushElement { - position: Position; + position: MapCoordinates; id: UUID; } diff --git a/shared/src/state-helpers/create-vehicle-parameters.ts b/shared/src/state-helpers/create-vehicle-parameters.ts index b738132ed..240d283a8 100644 --- a/shared/src/state-helpers/create-vehicle-parameters.ts +++ b/shared/src/state-helpers/create-vehicle-parameters.ts @@ -2,7 +2,7 @@ import type { Vehicle, VehicleTemplate } from '../models'; import { Material, Personnel } from '../models'; import type { MaterialTemplate } from '../models/material-template'; import type { PersonnelTemplate } from '../models/personnel-template'; -import type { PersonnelType, Position } from '../models/utils'; +import type { PersonnelType, MapCoordinates } from '../models/utils'; import { MapPosition } from '../models/utils/position/map-position'; import type { MaterialType } from '../models/utils/material-type'; import { VehiclePosition } from '../models/utils/position/vehicle-position'; @@ -22,7 +22,7 @@ export function createVehicleParameters( personnelTemplates: { [Key in PersonnelType]: PersonnelTemplate; }, - vehiclePosition: Position + vehiclePosition: MapCoordinates ): { materials: Material[]; personnel: Personnel[]; diff --git a/shared/src/store/action-reducers/map-images.ts b/shared/src/store/action-reducers/map-images.ts index fb710b402..86061c56c 100644 --- a/shared/src/store/action-reducers/map-images.ts +++ b/shared/src/store/action-reducers/map-images.ts @@ -9,7 +9,7 @@ import { ValidateNested, } from 'class-validator'; import { MapImage } from '../../models'; -import { MapPosition, Position } from '../../models/utils'; +import { MapPosition, MapCoordinates } from '../../models/utils'; import { changePosition } from '../../models/utils/position/meta-position-helpers-mutable'; import type { ExerciseState } from '../../state'; import type { Mutable } from '../../utils'; @@ -40,8 +40,8 @@ export class MoveMapImageAction implements Action { public readonly mapImageId!: UUID; @ValidateNested() - @Type(() => Position) - public readonly targetPosition!: Position; + @Type(() => MapCoordinates) + public readonly targetPosition!: MapCoordinates; } export class ScaleMapImageAction implements Action { diff --git a/shared/src/store/action-reducers/material.ts b/shared/src/store/action-reducers/material.ts index 947de8cd4..c17741a06 100644 --- a/shared/src/store/action-reducers/material.ts +++ b/shared/src/store/action-reducers/material.ts @@ -1,6 +1,6 @@ import { Type } from 'class-transformer'; import { IsUUID, ValidateNested } from 'class-validator'; -import { MapPosition, Position } from '../../models/utils'; +import { MapPosition, MapCoordinates } from '../../models/utils'; import { changePositionWithId } from '../../models/utils/position/meta-position-helpers-mutable'; import { UUID, uuidValidationOptions } from '../../utils'; import { IsValue } from '../../utils/validators'; @@ -14,8 +14,8 @@ export class MoveMaterialAction implements Action { public readonly materialId!: UUID; @ValidateNested() - @Type(() => Position) - public readonly targetPosition!: Position; + @Type(() => MapCoordinates) + public readonly targetPosition!: MapCoordinates; } export namespace MaterialActionReducers { diff --git a/shared/src/store/action-reducers/patient.ts b/shared/src/store/action-reducers/patient.ts index b92768b18..bc5e7a319 100644 --- a/shared/src/store/action-reducers/patient.ts +++ b/shared/src/store/action-reducers/patient.ts @@ -6,7 +6,7 @@ import { MapPosition, PatientStatus, patientStatusAllowedValues, - Position, + MapCoordinates, } from '../../models/utils'; import { changePosition, @@ -51,8 +51,8 @@ export class MovePatientAction implements Action { public readonly patientId!: UUID; @ValidateNested() - @Type(() => Position) - public readonly targetPosition!: Position; + @Type(() => MapCoordinates) + public readonly targetPosition!: MapCoordinates; } export class RemovePatientAction implements Action { diff --git a/shared/src/store/action-reducers/personnel.ts b/shared/src/store/action-reducers/personnel.ts index dcdbc97be..3c0ee8152 100644 --- a/shared/src/store/action-reducers/personnel.ts +++ b/shared/src/store/action-reducers/personnel.ts @@ -1,6 +1,6 @@ import { Type } from 'class-transformer'; import { IsUUID, ValidateNested } from 'class-validator'; -import { MapPosition, Position } from '../../models/utils'; +import { MapPosition, MapCoordinates } from '../../models/utils'; import { changePositionWithId } from '../../models/utils/position/meta-position-helpers-mutable'; import { UUID, uuidValidationOptions } from '../../utils'; import { IsValue } from '../../utils/validators'; @@ -14,8 +14,8 @@ export class MovePersonnelAction implements Action { public readonly personnelId!: UUID; @ValidateNested() - @Type(() => Position) - public readonly targetPosition!: Position; + @Type(() => MapCoordinates) + public readonly targetPosition!: MapCoordinates; } export namespace PersonnelActionReducers { diff --git a/shared/src/store/action-reducers/simulated-region.ts b/shared/src/store/action-reducers/simulated-region.ts index 942555c1c..2ba972d29 100644 --- a/shared/src/store/action-reducers/simulated-region.ts +++ b/shared/src/store/action-reducers/simulated-region.ts @@ -1,7 +1,7 @@ import { Type } from 'class-transformer'; import { IsString, IsUUID, ValidateNested } from 'class-validator'; import { SimulatedRegion } from '../../models'; -import { MapPosition, Position, Size } from '../../models/utils'; +import { MapCoordinates, MapPosition, Size } from '../../models/utils'; import { changePosition, changePositionWithId, @@ -32,8 +32,8 @@ export class MoveSimulatedRegionAction implements Action { @IsUUID(4, uuidValidationOptions) public readonly simulatedRegionId!: UUID; @ValidateNested() - @Type(() => Position) - public readonly targetPosition!: Position; + @Type(() => MapCoordinates) + public readonly targetPosition!: MapCoordinates; } export class ResizeSimulatedRegionAction implements Action { @@ -42,8 +42,8 @@ export class ResizeSimulatedRegionAction implements Action { @IsUUID(4, uuidValidationOptions) public readonly simulatedRegionId!: UUID; @ValidateNested() - @Type(() => Position) - public readonly targetPosition!: Position; + @Type(() => MapCoordinates) + public readonly targetPosition!: MapCoordinates; @ValidateNested() @Type(() => Size) public readonly newSize!: Size; diff --git a/shared/src/store/action-reducers/transfer-point.ts b/shared/src/store/action-reducers/transfer-point.ts index f348b7ec1..1a3c45c43 100644 --- a/shared/src/store/action-reducers/transfer-point.ts +++ b/shared/src/store/action-reducers/transfer-point.ts @@ -7,7 +7,7 @@ import { ValidateNested, } from 'class-validator'; import { TransferPoint } from '../../models'; -import { coordinatesOf, MapPosition, Position } from '../../models/utils'; +import { coordinatesOf, MapCoordinates, MapPosition } from '../../models/utils'; import { changePositionWithId } from '../../models/utils/position/meta-position-helpers-mutable'; import { cloneDeepMutable, UUID, uuidValidationOptions } from '../../utils'; import { IsValue } from '../../utils/validators'; @@ -35,8 +35,8 @@ export class MoveTransferPointAction implements Action { public readonly transferPointId!: UUID; @ValidateNested() - @Type(() => Position) - public readonly targetPosition!: Position; + @Type(() => MapCoordinates) + public readonly targetPosition!: MapCoordinates; } export class RenameTransferPointAction implements Action { @@ -323,7 +323,10 @@ export namespace TransferPointActionReducers { * @returns an estimated duration in ms to drive between the the two given positions * The resulting value is a multiple of 0.1 minutes. */ -function estimateDuration(startPosition: Position, targetPosition: Position) { +function estimateDuration( + startPosition: MapCoordinates, + targetPosition: MapCoordinates +) { // TODO: tweak these values more // How long in ms it takes to start + stop moving const overheadSummand = 10 * 1000; diff --git a/shared/src/store/action-reducers/transfer.ts b/shared/src/store/action-reducers/transfer.ts index d2569993f..f7885ad9f 100644 --- a/shared/src/store/action-reducers/transfer.ts +++ b/shared/src/store/action-reducers/transfer.ts @@ -1,7 +1,7 @@ import { Type } from 'class-transformer'; import { IsInt, IsOptional, IsUUID, ValidateNested } from 'class-validator'; import { TransferPoint } from '../../models'; -import type { Position } from '../../models/utils'; +import type { MapCoordinates } from '../../models/utils'; import { TransferPosition, coordinatesOf, @@ -44,7 +44,7 @@ export function letElementArrive( 'transferPoints', element.transfer.targetTransferPointId ); - const newPosition: Mutable = { + const newPosition: Mutable = { x: coordinatesOf(targetTransferPoint).x, y: coordinatesOf(targetTransferPoint).y + diff --git a/shared/src/store/action-reducers/utils/calculate-distance.ts b/shared/src/store/action-reducers/utils/calculate-distance.ts index 66fd06b9b..986f53d8a 100644 --- a/shared/src/store/action-reducers/utils/calculate-distance.ts +++ b/shared/src/store/action-reducers/utils/calculate-distance.ts @@ -1,8 +1,8 @@ -import type { Position } from '../../../models/utils'; +import type { MapCoordinates } from '../../../models/utils'; /** * @returns the distance between the two positions in meters. */ -export function calculateDistance(a: Position, b: Position) { +export function calculateDistance(a: MapCoordinates, b: MapCoordinates) { return Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2); } diff --git a/shared/src/store/action-reducers/utils/calculate-treatments.ts b/shared/src/store/action-reducers/utils/calculate-treatments.ts index 924f6720f..092224605 100644 --- a/shared/src/store/action-reducers/utils/calculate-treatments.ts +++ b/shared/src/store/action-reducers/utils/calculate-treatments.ts @@ -1,7 +1,7 @@ import { groupBy } from 'lodash-es'; import type { Material, Personnel } from '../../../models'; import { Patient } from '../../../models'; -import type { PatientStatus, Position } from '../../../models/utils'; +import type { MapCoordinates, PatientStatus } from '../../../models/utils'; import { coordinatesOf, isNotOnMap } from '../../../models/utils'; import { SpatialTree } from '../../../models/utils/spatial-tree'; import type { ExerciseState } from '../../../state'; @@ -119,7 +119,7 @@ function isMaterial( */ function updateCateringAroundPatient( state: Mutable, - position: Position, + position: MapCoordinates, elementType: 'materials' | 'personnel', elementIdsToBeSkipped: Set ) { diff --git a/shared/src/store/action-reducers/utils/spatial-elements.ts b/shared/src/store/action-reducers/utils/spatial-elements.ts index efd1a6599..2ae03a0bc 100644 --- a/shared/src/store/action-reducers/utils/spatial-elements.ts +++ b/shared/src/store/action-reducers/utils/spatial-elements.ts @@ -1,4 +1,4 @@ -import type { Position } from '../../../models/utils'; +import type { MapCoordinates } from '../../../models/utils'; import { isOnMap, isNotOnMap, coordinatesOf } from '../../../models/utils'; import { SpatialTree } from '../../../models/utils/spatial-tree'; import type { ExerciseState } from '../../../state'; @@ -40,7 +40,7 @@ export function updateElementPosition( state: Mutable, elementType: SpatialElementType, elementId: UUID, - targetPosition: Position + targetPosition: MapCoordinates ) { const element = getElement(state, elementType, elementId); if (isOnMap(element)) { diff --git a/shared/src/store/action-reducers/vehicle.ts b/shared/src/store/action-reducers/vehicle.ts index 3de10b551..891739ccb 100644 --- a/shared/src/store/action-reducers/vehicle.ts +++ b/shared/src/store/action-reducers/vehicle.ts @@ -7,7 +7,6 @@ import { isNotOnMap, MapCoordinates, MapPosition, - Position, VehiclePosition, } from '../../models/utils'; import { @@ -87,8 +86,8 @@ export class MoveVehicleAction implements Action { public readonly vehicleId!: UUID; @ValidateNested() - @Type(() => Position) - public readonly targetPosition!: Position; + @Type(() => MapCoordinates) + public readonly targetPosition!: MapCoordinates; } export class RemoveVehicleAction implements Action { diff --git a/shared/src/store/action-reducers/viewport.ts b/shared/src/store/action-reducers/viewport.ts index e0d7debf6..5b436814b 100644 --- a/shared/src/store/action-reducers/viewport.ts +++ b/shared/src/store/action-reducers/viewport.ts @@ -1,7 +1,7 @@ import { Type } from 'class-transformer'; import { IsString, IsUUID, ValidateNested } from 'class-validator'; import { Viewport } from '../../models'; -import { MapPosition, Position, Size } from '../../models/utils'; +import { MapCoordinates, MapPosition, Size } from '../../models/utils'; import { changePosition, changePositionWithId, @@ -32,8 +32,8 @@ export class MoveViewportAction implements Action { @IsUUID(4, uuidValidationOptions) public readonly viewportId!: UUID; @ValidateNested() - @Type(() => Position) - public readonly targetPosition!: Position; + @Type(() => MapCoordinates) + public readonly targetPosition!: MapCoordinates; } export class ResizeViewportAction implements Action { @@ -42,8 +42,8 @@ export class ResizeViewportAction implements Action { @IsUUID(4, uuidValidationOptions) public readonly viewportId!: UUID; @ValidateNested() - @Type(() => Position) - public readonly targetPosition!: Position; + @Type(() => MapCoordinates) + public readonly targetPosition!: MapCoordinates; @ValidateNested() @Type(() => Size) public readonly newSize!: Size; From 9ff7ce5657e17ed9d3f7e57c8fa0ce9fb577e191 Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Thu, 26 Jan 2023 15:17:26 +0100 Subject: [PATCH 07/22] Remove Position from Tests --- shared/src/models/utils/get-create.ts | 2 +- shared/src/models/utils/spatial-tree.ts | 2 +- .../utils/calculate-treatments.spec.ts | 48 +++++++++++++------ .../store/validate-exercise-action.spec.ts | 4 +- 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/shared/src/models/utils/get-create.ts b/shared/src/models/utils/get-create.ts index 5cccc3042..4dab6f921 100644 --- a/shared/src/models/utils/get-create.ts +++ b/shared/src/models/utils/get-create.ts @@ -9,7 +9,7 @@ import type { Constructor } from '../../utils'; * * @example * ```typescript - * export class Position { + * export class Coordinates { * @IsNumber() * public a: number; * /** diff --git a/shared/src/models/utils/spatial-tree.ts b/shared/src/models/utils/spatial-tree.ts index 4be569944..33ea781dc 100644 --- a/shared/src/models/utils/spatial-tree.ts +++ b/shared/src/models/utils/spatial-tree.ts @@ -159,7 +159,7 @@ interface PointRBushElement { } /** - * An RBush that works with our {@link Position} format (elements being points) + * An RBush that works with our {@link MapCoordinates} format (elements being points) * @see https://github.com/mourner/rbush#data-format */ class PointRBush extends RBush { diff --git a/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts b/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts index 777a2d1d0..4dd5d8787 100644 --- a/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts +++ b/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts @@ -9,7 +9,7 @@ import { coordinatesOf, isMetaPositionOnMap, CanCaterFor, - Position, + MapCoordinates, } from '../../../models/utils'; import { MapPosition } from '../../../models/utils/position/map-position'; import { SpatialTree } from '../../../models/utils/spatial-tree'; @@ -76,7 +76,7 @@ function addPatient( state: Mutable, pretriageStatus: PatientStatus, realStatus: PatientStatus, - position?: Position + position?: MapCoordinates ): Mutable { const patient = cloneDeepMutable(generateDummyPatient()); patient.pretriageStatus = pretriageStatus; @@ -224,7 +224,12 @@ describe('calculate treatment', () => { (state) => { (['green', 'yellow', 'red'] as PatientStatus[]).forEach( (color) => { - addPatient(state, color, color, Position.create(0, 0)); + addPatient( + state, + color, + color, + MapCoordinates.create(0, 0) + ); } ); } @@ -235,7 +240,12 @@ describe('calculate treatment', () => { it('does nothing when there are only dead patients', () => { const { beforeState, newState } = setupStateAndApplyTreatments( (state) => { - addPatient(state, 'black', 'black', Position.create(0, 0)); + addPatient( + state, + 'black', + 'black', + MapCoordinates.create(0, 0) + ); } ); expect(newState).toStrictEqual(beforeState); @@ -244,7 +254,12 @@ describe('calculate treatment', () => { it('does nothing when all personnel is in a vehicle', () => { const { beforeState, newState } = setupStateAndApplyTreatments( (state) => { - addPatient(state, 'green', 'green', Position.create(0, 0)); + addPatient( + state, + 'green', + 'green', + MapCoordinates.create(0, 0) + ); addPersonnel(state, VehiclePosition.create('')); } ); @@ -254,7 +269,12 @@ describe('calculate treatment', () => { it('does nothing when all material is in a vehicle', () => { const { beforeState, newState } = setupStateAndApplyTreatments( (state) => { - addPatient(state, 'green', 'green', Position.create(0, 0)); + addPatient( + state, + 'green', + 'green', + MapCoordinates.create(0, 0) + ); addMaterial(state, VehiclePosition.create('')); } ); @@ -273,13 +293,13 @@ describe('calculate treatment', () => { state, 'green', 'green', - Position.create(0, 0) + MapCoordinates.create(0, 0) ).id; ids.redPatient = addPatient( state, 'red', 'red', - Position.create(2, 2) + MapCoordinates.create(2, 2) ).id; ids.material = addMaterial( state, @@ -308,13 +328,13 @@ describe('calculate treatment', () => { state, 'green', 'green', - Position.create(-3, -3) + MapCoordinates.create(-3, -3) ).id; ids.redPatient = addPatient( state, 'red', 'red', - Position.create(3, 3) + MapCoordinates.create(3, 3) ).id; ids.material = addMaterial( state, @@ -344,13 +364,13 @@ describe('calculate treatment', () => { state, 'green', 'green', - Position.create(-10, -10) + MapCoordinates.create(-10, -10) ).id; ids.redPatient = addPatient( state, 'red', 'red', - Position.create(20, 20) + MapCoordinates.create(20, 20) ).id; ids.material = addMaterial( state, @@ -373,13 +393,13 @@ describe('calculate treatment', () => { state, 'green', 'green', - Position.create(-1, -1) + MapCoordinates.create(-1, -1) ).id; ids.redPatient = addPatient( state, 'red', 'red', - Position.create(2, 2) + MapCoordinates.create(2, 2) ).id; const material = addMaterial( state, diff --git a/shared/src/store/validate-exercise-action.spec.ts b/shared/src/store/validate-exercise-action.spec.ts index 63ccb39af..ab82fea27 100644 --- a/shared/src/store/validate-exercise-action.spec.ts +++ b/shared/src/store/validate-exercise-action.spec.ts @@ -1,5 +1,5 @@ -import type { Position } from '../models/utils'; import { Viewport } from '../models'; +import type { MapCoordinates } from '../models/utils'; import type { ExerciseAction } from './action-reducers'; import { validateExerciseAction } from '.'; @@ -126,7 +126,7 @@ describe('validateExerciseAction', () => { x: 0, y: 0, z: 0, - } as unknown as Position, + } as unknown as MapCoordinates, }, }, }) From 161330cfd4e18886276f360a2275cfbef7783f1a Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Thu, 26 Jan 2023 15:37:05 +0100 Subject: [PATCH 08/22] Rename MetaPosition to Position --- .../send-alarm-group-interface.component.ts | 7 +- .../element-feature-manager.ts | 8 +- .../vehicle-popup/vehicle-popup.component.ts | 4 +- .../application/selectors/shared.selectors.ts | 4 +- shared/src/models/map-image.ts | 8 +- shared/src/models/material.ts | 21 +-- shared/src/models/patient-template.ts | 4 +- shared/src/models/patient.ts | 10 +- shared/src/models/personnel.ts | 12 +- shared/src/models/simulated-region.ts | 16 +- shared/src/models/transfer-point.ts | 8 +- shared/src/models/utils/index.ts | 6 +- .../src/models/utils/position/map-position.ts | 2 +- .../utils/position/meta-position-helpers.ts | 150 ------------------ ...mutable.ts => position-helpers-mutable.ts} | 40 ++--- .../models/utils/position/position-helpers.ts | 134 ++++++++++++++++ .../{meta-position.ts => position.ts} | 2 +- .../position/simulated-region-position.ts | 2 +- .../utils/position/transfer-position.ts | 2 +- .../models/utils/position/vehicle-position.ts | 2 +- .../utils/position/with-meta-position.ts | 6 +- shared/src/models/vehicle.ts | 10 +- shared/src/models/viewport.ts | 14 +- .../state-migrations/16-add-meta-position.ts | 2 +- .../state-migrations/migration-functions.ts | 4 +- .../src/store/action-reducers/map-images.ts | 2 +- shared/src/store/action-reducers/material.ts | 2 +- shared/src/store/action-reducers/patient.ts | 2 +- shared/src/store/action-reducers/personnel.ts | 2 +- .../store/action-reducers/simulated-region.ts | 2 +- .../store/action-reducers/transfer-point.ts | 2 +- shared/src/store/action-reducers/transfer.ts | 2 +- .../utils/calculate-treatments.spec.ts | 18 +-- shared/src/store/action-reducers/vehicle.ts | 2 +- shared/src/store/action-reducers/viewport.ts | 2 +- .../{is-metaposition.ts => is-position.ts} | 14 +- 36 files changed, 248 insertions(+), 280 deletions(-) delete mode 100644 shared/src/models/utils/position/meta-position-helpers.ts rename shared/src/models/utils/position/{meta-position-helpers-mutable.ts => position-helpers-mutable.ts} (69%) create mode 100644 shared/src/models/utils/position/position-helpers.ts rename shared/src/models/utils/position/{meta-position.ts => position.ts} (92%) rename shared/src/utils/validators/{is-metaposition.ts => is-position.ts} (77%) diff --git a/frontend/src/app/pages/exercises/exercise/shared/emergency-operations-center/send-alarm-group-interface/send-alarm-group-interface.component.ts b/frontend/src/app/pages/exercises/exercise/shared/emergency-operations-center/send-alarm-group-interface/send-alarm-group-interface.component.ts index d73e00b5e..fadf08cdf 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/emergency-operations-center/send-alarm-group-interface/send-alarm-group-interface.component.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/emergency-operations-center/send-alarm-group-interface/send-alarm-group-interface.component.ts @@ -97,9 +97,12 @@ export class SendAlarmGroupInterfaceComponent implements OnDestroy { this.store ), // TODO: This position is not correct but needs to be provided. - // Here one should use a MetaPosition with the Transfer. + // Here one should use a Position with the Transfer. // But this is part of later Refactoring. - // Also it is irrelevant, because the correctMetaPosition is set immediately after this is called. + // We need the Transfer to be created before the Vehicle is created, + // else we need to provide a Position that is immediately overwritten by the Add to Transfer Action. + // This is done here + // Good Thing is, it is irrelevant, because the correctPosition is set immediately after this is called. MapCoordinates.create(0, 0) ); diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/element-feature-manager.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/element-feature-manager.ts index 166c3112c..fd8289538 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/element-feature-manager.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/element-feature-manager.ts @@ -1,7 +1,7 @@ import type { ExerciseState, - MetaPosition, - WithMetaPosition, + Position, + WithPosition, MapCoordinates, Size, UUID, @@ -27,7 +27,7 @@ import { ElementManager } from './element-manager'; export interface PositionableElement { readonly id: UUID; - readonly metaPosition: MetaPosition; + readonly metaPosition: Position; } export interface ResizableElement extends PositionableElement { @@ -46,7 +46,7 @@ export function isCoordinateArray( return isArray(coordinates[0]); } -export const createPoint = (element: WithMetaPosition): Feature => +export const createPoint = (element: WithPosition): Feature => new Feature( new Point([coordinatesOf(element).x, coordinatesOf(element).y]) ); diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/shared/vehicle-popup/vehicle-popup.component.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/shared/vehicle-popup/vehicle-popup.component.ts index 915c822bf..fb887ace0 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/shared/vehicle-popup/vehicle-popup.component.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/shared/vehicle-popup/vehicle-popup.component.ts @@ -2,7 +2,7 @@ import type { OnInit } from '@angular/core'; import { Component, EventEmitter, Output } from '@angular/core'; import { Store } from '@ngrx/store'; import type { UUID, Vehicle } from 'digital-fuesim-manv-shared'; -import { isInVehicle, Material } from 'digital-fuesim-manv-shared'; +import { isInVehicle } from 'digital-fuesim-manv-shared'; import type { Observable } from 'rxjs'; import { combineLatest, map, switchMap } from 'rxjs'; import { ExerciseService } from 'src/app/core/exercise.service'; @@ -45,7 +45,7 @@ export class VehiclePopupComponent implements PopupComponent, OnInit { ).map((materialId) => this.store .select(createSelectMaterial(materialId)) - .pipe(map((material) => Material.isInVehicle(material))) + .pipe(map((material) => isInVehicle(material))) ); const personnelAreInVehicle$ = Object.keys( _vehicle.personnelIds diff --git a/frontend/src/app/state/application/selectors/shared.selectors.ts b/frontend/src/app/state/application/selectors/shared.selectors.ts index 5b4b625b4..9f31c8dde 100644 --- a/frontend/src/app/state/application/selectors/shared.selectors.ts +++ b/frontend/src/app/state/application/selectors/shared.selectors.ts @@ -8,7 +8,7 @@ import type { TransferPoint, UUID, Vehicle, - WithMetaPosition, + WithPosition, } from 'digital-fuesim-manv-shared'; import { coordinatesOf, isOnMap, Viewport } from 'digital-fuesim-manv-shared'; import { pickBy } from 'lodash-es'; @@ -62,7 +62,7 @@ export const selectRestrictedViewport = createSelector( * @returns a selector that returns a UUIDMap of all elements that have a position and are in the viewport restriction */ function selectVisibleElementsFactory< - Element extends WithMetaPosition, + Element extends WithPosition, Elements extends { readonly [key: UUID]: Element } = { readonly [key: UUID]: Element; } diff --git a/shared/src/models/map-image.ts b/shared/src/models/map-image.ts index c62e39390..3a1cb248c 100644 --- a/shared/src/models/map-image.ts +++ b/shared/src/models/map-image.ts @@ -1,17 +1,17 @@ import { Type } from 'class-transformer'; import { IsBoolean, IsInt, IsUUID, ValidateNested } from 'class-validator'; import { uuid, UUID, uuidValidationOptions } from '../utils'; -import { IsMetaPosition } from '../utils/validators/is-metaposition'; +import { IsPosition } from '../utils/validators/is-position'; import type { MapCoordinates } from './utils'; -import { MapPosition, getCreate, ImageProperties, MetaPosition } from './utils'; +import { MapPosition, getCreate, ImageProperties, Position } from './utils'; export class MapImage { @IsUUID(4, uuidValidationOptions) public readonly id: UUID = uuid(); @ValidateNested() - @IsMetaPosition() - public readonly metaPosition: MetaPosition; + @IsPosition() + public readonly metaPosition: Position; @ValidateNested() @Type(() => ImageProperties) diff --git a/shared/src/models/material.ts b/shared/src/models/material.ts index 533e54ba3..3bba4286c 100644 --- a/shared/src/models/material.ts +++ b/shared/src/models/material.ts @@ -10,11 +10,10 @@ import { import { maxTreatmentRange } from '../state-helpers/max-treatment-range'; import { uuidValidationOptions, UUID, uuid, UUIDSet } from '../utils'; import { IsUUIDSet } from '../utils/validators'; -import { IsMetaPosition } from '../utils/validators/is-metaposition'; +import { IsPosition } from '../utils/validators/is-position'; import type { MaterialTemplate } from './material-template'; -import type { MapCoordinates } from './utils'; import { CanCaterFor, ImageProperties, getCreate } from './utils'; -import { MetaPosition } from './utils/position/meta-position'; +import { Position } from './utils/position/position'; export class Material { @IsUUID(4, uuidValidationOptions) @@ -53,9 +52,9 @@ export class Material { @Max(maxTreatmentRange) public readonly treatmentRange: number; - @IsMetaPosition() + @IsPosition() @ValidateNested() - public readonly metaPosition: MetaPosition; + public readonly metaPosition: Position; @ValidateNested() @Type(() => ImageProperties) @@ -72,8 +71,7 @@ export class Material { canCaterFor: CanCaterFor, treatmentRange: number, overrideTreatmentRange: number, - metaPosition: MetaPosition, - position?: MapCoordinates + metaPosition: Position ) { this.vehicleId = vehicleId; this.vehicleName = vehicleName; @@ -91,7 +89,7 @@ export class Material { materialTemplate: MaterialTemplate, vehicleId: UUID, vehicleName: string, - metaPosition: MetaPosition + metaPosition: Position ): Material { return this.create( vehicleId, @@ -101,12 +99,7 @@ export class Material { materialTemplate.canCaterFor, materialTemplate.treatmentRange, materialTemplate.overrideTreatmentRange, - metaPosition, - undefined + metaPosition ); } - - static isInVehicle(material: Material): boolean { - return material.metaPosition.type === 'vehicle'; - } } diff --git a/shared/src/models/patient-template.ts b/shared/src/models/patient-template.ts index 1cadb121e..5b2af3203 100644 --- a/shared/src/models/patient-template.ts +++ b/shared/src/models/patient-template.ts @@ -16,7 +16,7 @@ import { Patient } from './patient'; import type { FunctionParameters } from './patient-health-state'; import { PretriageInformation } from './utils/pretriage-information'; import { PatientHealthState } from './patient-health-state'; -import type { MetaPosition } from './utils/position/meta-position'; +import type { Position } from './utils/position/position'; export class PatientTemplate { @IsUUID(4, uuidValidationOptions) @@ -69,7 +69,7 @@ export class PatientTemplate { public static generatePatient( template: PatientTemplate, patientStatusCode: PatientStatusCode, - metaPosition: MetaPosition + metaPosition: Position ): Patient { // Randomize function parameters const healthStates = Object.fromEntries( diff --git a/shared/src/models/patient.ts b/shared/src/models/patient.ts index 1380e4b9b..fbc091abc 100644 --- a/shared/src/models/patient.ts +++ b/shared/src/models/patient.ts @@ -13,7 +13,7 @@ import { import { isEmpty } from 'lodash-es'; import { uuidValidationOptions, UUID, uuid, UUIDSet } from '../utils'; import { IsLiteralUnion, IsIdMap, IsUUIDSet } from '../utils/validators'; -import { IsMetaPosition } from '../utils/validators/is-metaposition'; +import { IsPosition } from '../utils/validators/is-position'; import { PatientHealthState } from './patient-health-state'; import { BiometricInformation, @@ -25,7 +25,7 @@ import { HealthPoints, getCreate, } from './utils'; -import { MetaPosition } from './utils/position/meta-position'; +import { Position } from './utils/position/position'; import { PersonalInformation } from './utils/personal-information'; import { PretriageInformation } from './utils/pretriage-information'; @@ -63,9 +63,9 @@ export class Patient { @Type(() => ImageProperties) public readonly image: ImageProperties; - @IsMetaPosition() + @IsPosition() @ValidateNested() - public readonly metaPosition: MetaPosition; + public readonly metaPosition: Position; @IsUUID(4, uuidValidationOptions) @IsOptional() @@ -150,7 +150,7 @@ export class Patient { image: ImageProperties, health: HealthPoints, remarks: string, - metaPosition: MetaPosition + metaPosition: Position ) { this.personalInformation = personalInformation; this.biometricInformation = biometricInformation; diff --git a/shared/src/models/personnel.ts b/shared/src/models/personnel.ts index e74e9729b..8398d6e17 100644 --- a/shared/src/models/personnel.ts +++ b/shared/src/models/personnel.ts @@ -11,7 +11,7 @@ import { import { maxTreatmentRange } from '../state-helpers/max-treatment-range'; import { uuidValidationOptions, UUID, uuid, UUIDSet } from '../utils'; import { IsLiteralUnion, IsUUIDSet } from '../utils/validators'; -import { IsMetaPosition } from '../utils/validators/is-metaposition'; +import { IsPosition } from '../utils/validators/is-position'; import type { PersonnelTemplate } from './personnel-template'; import type { MapCoordinates } from './utils'; import { @@ -21,7 +21,7 @@ import { Transfer, getCreate, } from './utils'; -import { MetaPosition } from './utils/position/meta-position'; +import { Position } from './utils/position/position'; import { personnelTypeAllowedValues } from './utils/personnel-type'; export class Personnel { @@ -68,9 +68,9 @@ export class Personnel { @Type(() => ImageProperties) public readonly image: ImageProperties; - @IsMetaPosition() + @IsPosition() @ValidateNested() - public readonly metaPosition: MetaPosition; + public readonly metaPosition: Position; /** * * @deprecated use {@link metaPosition} @@ -93,7 +93,7 @@ export class Personnel { canCaterFor: CanCaterFor, treatmentRange: number, overrideTreatmentRange: number, - metaPosition: MetaPosition, + metaPosition: Position, position?: MapCoordinates ) { this.vehicleId = vehicleId; @@ -113,7 +113,7 @@ export class Personnel { personnelTemplate: PersonnelTemplate, vehicleId: UUID, vehicleName: string, - metaPosition: MetaPosition + metaPosition: Position ): Personnel { return this.create( vehicleId, diff --git a/shared/src/models/simulated-region.ts b/shared/src/models/simulated-region.ts index e59addff5..93d3c21a8 100644 --- a/shared/src/models/simulated-region.ts +++ b/shared/src/models/simulated-region.ts @@ -1,17 +1,17 @@ import { Type } from 'class-transformer'; import { IsString, IsUUID, ValidateNested } from 'class-validator'; import { UUID, uuid, uuidValidationOptions } from '../utils'; -import { IsMetaPosition } from '../utils/validators/is-metaposition'; +import { IsPosition } from '../utils/validators/is-position'; import { getCreate, isInSimulatedRegion, MapPosition, - MetaPosition, + Position, simulatedRegionItsIn, Size, } from './utils'; import type { ImageProperties, MapCoordinates } from './utils'; -import type { WithMetaPosition } from './utils/position/with-meta-position'; +import type { WithPosition } from './utils/position/with-meta-position'; export class SimulatedRegion { @IsUUID(4, uuidValidationOptions) @@ -21,8 +21,8 @@ export class SimulatedRegion { * top-left position */ @ValidateNested() - @IsMetaPosition() - public readonly metaPosition: MetaPosition; + @IsPosition() + public readonly metaPosition: Position; @ValidateNested() @Type(() => Size) @@ -51,11 +51,11 @@ export class SimulatedRegion { static isInSimulatedRegion( region: SimulatedRegion, - withMetaPosition: WithMetaPosition + withPosition: WithPosition ): boolean { return ( - isInSimulatedRegion(withMetaPosition) && - simulatedRegionItsIn(withMetaPosition) === region.id + isInSimulatedRegion(withPosition) && + simulatedRegionItsIn(withPosition) === region.id ); } } diff --git a/shared/src/models/transfer-point.ts b/shared/src/models/transfer-point.ts index a683b9899..fa1a5db80 100644 --- a/shared/src/models/transfer-point.ts +++ b/shared/src/models/transfer-point.ts @@ -1,17 +1,17 @@ import { IsString, IsUUID, ValidateNested } from 'class-validator'; import { UUID, uuid, UUIDSet, uuidValidationOptions } from '../utils'; import { IsReachableTransferPoints, IsUUIDSet } from '../utils/validators'; -import { IsMetaPosition } from '../utils/validators/is-metaposition'; +import { IsPosition } from '../utils/validators/is-position'; import type { ImageProperties, MapCoordinates } from './utils'; -import { MapPosition, MetaPosition, getCreate } from './utils'; +import { MapPosition, Position, getCreate } from './utils'; export class TransferPoint { @IsUUID(4, uuidValidationOptions) public readonly id: UUID = uuid(); @ValidateNested() - @IsMetaPosition() - public readonly metaPosition: MetaPosition; + @IsPosition() + public readonly metaPosition: Position; @IsReachableTransferPoints() public readonly reachableTransferPoints: ReachableTransferPoints; diff --git a/shared/src/models/utils/index.ts b/shared/src/models/utils/index.ts index 81642ea06..afdb7b3cd 100644 --- a/shared/src/models/utils/index.ts +++ b/shared/src/models/utils/index.ts @@ -1,11 +1,11 @@ -export { MetaPosition } from './position/meta-position'; -export { WithMetaPosition } from './position/with-meta-position'; +export { Position } from './position/position'; +export { WithPosition } from './position/with-meta-position'; export { MapPosition } from './position/map-position'; export { VehiclePosition } from './position/vehicle-position'; export { TransferPosition } from './position/transfer-position'; export { SimulatedRegionPosition } from './position/simulated-region-position'; export { MapCoordinates } from './position/map-coordinates'; -export * from './position/meta-position-helpers'; +export * from './position/position-helpers'; export * from './patient-status'; export { Size } from './size'; export { Role } from './role'; diff --git a/shared/src/models/utils/position/map-position.ts b/shared/src/models/utils/position/map-position.ts index aca939f1f..07a4cc82b 100644 --- a/shared/src/models/utils/position/map-position.ts +++ b/shared/src/models/utils/position/map-position.ts @@ -4,7 +4,7 @@ import { IsValue } from '../../../utils/validators'; import { getCreate } from '../get-create'; import { MapCoordinates } from './map-coordinates'; // eslint-disable-next-line @typescript-eslint/no-unused-vars -import { isOnMap, isNotOnMap, coordinatesOf } from './meta-position-helpers'; +import { isOnMap, isNotOnMap, coordinatesOf } from './position-helpers'; export class MapPosition { /** diff --git a/shared/src/models/utils/position/meta-position-helpers.ts b/shared/src/models/utils/position/meta-position-helpers.ts deleted file mode 100644 index 59513222e..000000000 --- a/shared/src/models/utils/position/meta-position-helpers.ts +++ /dev/null @@ -1,150 +0,0 @@ -import type { UUID } from '../../../utils'; -import type { Transfer } from '../transfer'; -import type { MapCoordinates } from './map-coordinates'; -import type { MapPosition } from './map-position'; -import type { MetaPosition } from './meta-position'; -import type { SimulatedRegionPosition } from './simulated-region-position'; -import type { TransferPosition } from './transfer-position'; -import type { VehiclePosition } from './vehicle-position'; -import type { WithMetaPosition } from './with-meta-position'; - -export function isOnMap(withMetaPosition: WithMetaPosition): boolean { - return withMetaPosition.metaPosition.type === 'coordinates'; -} -export function isInVehicle(withMetaPosition: WithMetaPosition): boolean { - return withMetaPosition.metaPosition.type === 'vehicle'; -} -export function isInTransfer(withMetaPosition: WithMetaPosition): boolean { - return withMetaPosition.metaPosition.type === 'transfer'; -} -export function isInSimulatedRegion( - withMetaPosition: WithMetaPosition -): boolean { - return withMetaPosition.metaPosition.type === 'simulatedRegion'; -} -export function isNotOnMap(withMetaPosition: WithMetaPosition): boolean { - return !isOnMap(withMetaPosition); -} -export function isNotInVehicle(withMetaPosition: WithMetaPosition): boolean { - return !isInVehicle(withMetaPosition); -} -export function isNotInTransfer(withMetaPosition: WithMetaPosition): boolean { - return !isInVehicle(withMetaPosition); -} -export function isNotInSimulatedRegion( - withMetaPosition: WithMetaPosition -): boolean { - return !isInSimulatedRegion(withMetaPosition); -} - -export function coordinatesOf( - withMetaPosition: WithMetaPosition -): MapCoordinates { - if (isOnMap(withMetaPosition)) { - return (withMetaPosition.metaPosition as MapPosition).position; - } - throw new TypeError( - `Expected metaPosition of object to be on Map. Was of type ${withMetaPosition.metaPosition.type}.` - ); -} - -export function vehicleItsIn(withMetaPosition: WithMetaPosition): UUID { - if (isInVehicle(withMetaPosition)) { - return (withMetaPosition.metaPosition as VehiclePosition).vehicleId; - } - throw new TypeError( - `Expected metaPosition of object to be in vehicle. Was of type ${withMetaPosition.metaPosition.type}.` - ); -} - -export function transferItsIn(withMetaPosition: WithMetaPosition): Transfer { - if (isInTransfer(withMetaPosition)) { - return (withMetaPosition.metaPosition as TransferPosition).transfer; - } - throw new TypeError( - `Expected metaPosition of object to be in transfer. Was of type ${withMetaPosition.metaPosition.type}.` - ); -} - -export function simulatedRegionItsIn(withMetaPosition: WithMetaPosition): UUID { - if (isInSimulatedRegion(withMetaPosition)) { - return (withMetaPosition.metaPosition as SimulatedRegionPosition) - .simulatedRegionId; - } - throw new TypeError( - `Expected metaPosition of object to be in simulatedRegion. Was of type ${withMetaPosition.metaPosition.type}.` - ); -} - -export function isMetaPositionOnMap(metaPosition: MetaPosition): boolean { - return metaPosition.type === 'coordinates'; -} -export function isMetaPositionInVehicle(metaPosition: MetaPosition): boolean { - return metaPosition.type === 'vehicle'; -} -export function isMetaPositionInTransfer(metaPosition: MetaPosition): boolean { - return metaPosition.type === 'transfer'; -} -export function isMetaPositionInSimulatedRegion( - metaPosition: MetaPosition -): boolean { - return metaPosition.type === 'simulatedRegion'; -} -export function isMetaPositionNotOnMap(metaPosition: MetaPosition): boolean { - return !isMetaPositionOnMap(metaPosition); -} -export function isMetaPositionNotInVehicle( - metaPosition: MetaPosition -): boolean { - return !isMetaPositionInVehicle(metaPosition); -} -export function isMetaPositionNotInTransfer( - metaPosition: MetaPosition -): boolean { - return !isMetaPositionInTransfer(metaPosition); -} -export function isMetaPositionNotInSimulatedRegion( - metaPosition: MetaPosition -): boolean { - return !isMetaPositionInSimulatedRegion(metaPosition); -} - -export function coordinatesOfMetaPosition( - metaPosition: MetaPosition -): MapCoordinates { - if (isMetaPositionOnMap(metaPosition)) { - return (metaPosition as MapPosition).position; - } - throw new TypeError( - `Expected metaPosition of object to be on Map. Was of type ${metaPosition.type}.` - ); -} - -export function vehicleMetaPositionIn(metaPosition: MetaPosition): UUID { - if (isMetaPositionInVehicle(metaPosition)) { - return (metaPosition as VehiclePosition).vehicleId; - } - throw new TypeError( - `Expected metaPosition of object to be in vehicle. Was of type ${metaPosition.type}.` - ); -} - -export function transferMetaPositionIn(metaPosition: MetaPosition): Transfer { - if (isMetaPositionInTransfer(metaPosition)) { - return (metaPosition as TransferPosition).transfer; - } - throw new TypeError( - `Expected metaPosition of object to be in transfer. Was of type ${metaPosition.type}.` - ); -} - -export function simulatedRegionMetaPositionIn( - metaPosition: MetaPosition -): UUID { - if (isMetaPositionInSimulatedRegion(metaPosition)) { - return (metaPosition as SimulatedRegionPosition).simulatedRegionId; - } - throw new TypeError( - `Expected metaPosition of object to be in simulatedRegion. Was of type ${metaPosition.type}.` - ); -} diff --git a/shared/src/models/utils/position/meta-position-helpers-mutable.ts b/shared/src/models/utils/position/position-helpers-mutable.ts similarity index 69% rename from shared/src/models/utils/position/meta-position-helpers-mutable.ts rename to shared/src/models/utils/position/position-helpers-mutable.ts index c93010bdd..619eb6bc0 100644 --- a/shared/src/models/utils/position/meta-position-helpers-mutable.ts +++ b/shared/src/models/utils/position/position-helpers-mutable.ts @@ -8,21 +8,21 @@ import { } from '../../../store/action-reducers/utils/spatial-elements'; import type { Mutable, UUID } from '../../../utils'; import { cloneDeepMutable } from '../../../utils'; -import type { MetaPosition } from './meta-position'; +import type { Position } from './position'; import { - coordinatesOfMetaPosition, - isMetaPositionNotOnMap, - isMetaPositionOnMap, + coordinatesOfPosition, + isPositionNotOnMap, + isPositionOnMap, isNotOnMap, isOnMap, -} from './meta-position-helpers'; +} from './position-helpers'; -type MutableMetaPosition = Mutable; +type MutablePosition = Mutable; -interface WithMutableMetaPosition { - metaPosition: MutableMetaPosition; +interface WithMutablePosition { + metaPosition: MutablePosition; } -interface WithMutableMetaPositionAndId extends WithMutableMetaPosition { +interface WithMutablePositionAndId extends WithMutablePosition { id: UUID; } type ElementType = @@ -40,7 +40,7 @@ type ElementType = export function changePositionWithId( of: UUID, - to: MetaPosition, + to: Position, type: ElementType, inState: Mutable ) { @@ -55,14 +55,14 @@ export function changePositionWithId( } export function changePosition( - of: WithMutableMetaPosition, - to: MetaPosition, + of: WithMutablePosition, + to: Position, type: SpatialElementType | false, inState: Mutable ) { if (type) { updateSpatialElementTree( - of as WithMutableMetaPositionAndId, + of as WithMutablePositionAndId, to, type, inState @@ -75,26 +75,26 @@ export function changePosition( } function updateSpatialElementTree( - element: WithMutableMetaPositionAndId, - to: MetaPosition, + element: WithMutablePositionAndId, + to: Position, type: SpatialElementType, state: Mutable ) { - if (isOnMap(element) && isMetaPositionOnMap(to)) { + if (isOnMap(element) && isPositionOnMap(to)) { updateElementPosition( state, type, element.id, - coordinatesOfMetaPosition(to) + coordinatesOfPosition(to) ); - } else if (isOnMap(element) && isMetaPositionNotOnMap(to)) { + } else if (isOnMap(element) && isPositionNotOnMap(to)) { removeElementPosition(state, type, element.id); - } else if (isNotOnMap(element) && isMetaPositionOnMap(to)) { + } else if (isNotOnMap(element) && isPositionOnMap(to)) { updateElementPosition( state, type, element.id, - coordinatesOfMetaPosition(to) + coordinatesOfPosition(to) ); } } diff --git a/shared/src/models/utils/position/position-helpers.ts b/shared/src/models/utils/position/position-helpers.ts new file mode 100644 index 000000000..f8d0ada3b --- /dev/null +++ b/shared/src/models/utils/position/position-helpers.ts @@ -0,0 +1,134 @@ +import type { UUID } from '../../../utils'; +import type { Transfer } from '../transfer'; +import type { MapCoordinates } from './map-coordinates'; +import type { MapPosition } from './map-position'; +import type { Position } from './position'; +import type { SimulatedRegionPosition } from './simulated-region-position'; +import type { TransferPosition } from './transfer-position'; +import type { VehiclePosition } from './vehicle-position'; +import type { WithPosition } from './with-meta-position'; + +export function isOnMap(withPosition: WithPosition): boolean { + return withPosition.metaPosition.type === 'coordinates'; +} +export function isInVehicle(withPosition: WithPosition): boolean { + return withPosition.metaPosition.type === 'vehicle'; +} +export function isInTransfer(withPosition: WithPosition): boolean { + return withPosition.metaPosition.type === 'transfer'; +} +export function isInSimulatedRegion(withPosition: WithPosition): boolean { + return withPosition.metaPosition.type === 'simulatedRegion'; +} +export function isNotOnMap(withPosition: WithPosition): boolean { + return !isOnMap(withPosition); +} +export function isNotInVehicle(withPosition: WithPosition): boolean { + return !isInVehicle(withPosition); +} +export function isNotInTransfer(withPosition: WithPosition): boolean { + return !isInVehicle(withPosition); +} +export function isNotInSimulatedRegion(withPosition: WithPosition): boolean { + return !isInSimulatedRegion(withPosition); +} + +export function coordinatesOf(withPosition: WithPosition): MapCoordinates { + if (isOnMap(withPosition)) { + return (withPosition.metaPosition as MapPosition).position; + } + throw new TypeError( + `Expected metaPosition of object to be on Map. Was of type ${withPosition.metaPosition.type}.` + ); +} + +export function vehicleItsIn(withPosition: WithPosition): UUID { + if (isInVehicle(withPosition)) { + return (withPosition.metaPosition as VehiclePosition).vehicleId; + } + throw new TypeError( + `Expected metaPosition of object to be in vehicle. Was of type ${withPosition.metaPosition.type}.` + ); +} + +export function transferItsIn(withPosition: WithPosition): Transfer { + if (isInTransfer(withPosition)) { + return (withPosition.metaPosition as TransferPosition).transfer; + } + throw new TypeError( + `Expected metaPosition of object to be in transfer. Was of type ${withPosition.metaPosition.type}.` + ); +} + +export function simulatedRegionItsIn(withPosition: WithPosition): UUID { + if (isInSimulatedRegion(withPosition)) { + return (withPosition.metaPosition as SimulatedRegionPosition) + .simulatedRegionId; + } + throw new TypeError( + `Expected metaPosition of object to be in simulatedRegion. Was of type ${withPosition.metaPosition.type}.` + ); +} + +export function isPositionOnMap(metaPosition: Position): boolean { + return metaPosition.type === 'coordinates'; +} +export function isPositionInVehicle(metaPosition: Position): boolean { + return metaPosition.type === 'vehicle'; +} +export function isPositionInTransfer(metaPosition: Position): boolean { + return metaPosition.type === 'transfer'; +} +export function isPositionInSimulatedRegion(metaPosition: Position): boolean { + return metaPosition.type === 'simulatedRegion'; +} +export function isPositionNotOnMap(metaPosition: Position): boolean { + return !isPositionOnMap(metaPosition); +} +export function isPositionNotInVehicle(metaPosition: Position): boolean { + return !isPositionInVehicle(metaPosition); +} +export function isPositionNotInTransfer(metaPosition: Position): boolean { + return !isPositionInTransfer(metaPosition); +} +export function isPositionNotInSimulatedRegion( + metaPosition: Position +): boolean { + return !isPositionInSimulatedRegion(metaPosition); +} + +export function coordinatesOfPosition(metaPosition: Position): MapCoordinates { + if (isPositionOnMap(metaPosition)) { + return (metaPosition as MapPosition).position; + } + throw new TypeError( + `Expected metaPosition of object to be on Map. Was of type ${metaPosition.type}.` + ); +} + +export function vehiclePositionIn(metaPosition: Position): UUID { + if (isPositionInVehicle(metaPosition)) { + return (metaPosition as VehiclePosition).vehicleId; + } + throw new TypeError( + `Expected metaPosition of object to be in vehicle. Was of type ${metaPosition.type}.` + ); +} + +export function transferPositionIn(metaPosition: Position): Transfer { + if (isPositionInTransfer(metaPosition)) { + return (metaPosition as TransferPosition).transfer; + } + throw new TypeError( + `Expected metaPosition of object to be in transfer. Was of type ${metaPosition.type}.` + ); +} + +export function simulatedRegionPositionIn(metaPosition: Position): UUID { + if (isPositionInSimulatedRegion(metaPosition)) { + return (metaPosition as SimulatedRegionPosition).simulatedRegionId; + } + throw new TypeError( + `Expected metaPosition of object to be in simulatedRegion. Was of type ${metaPosition.type}.` + ); +} diff --git a/shared/src/models/utils/position/meta-position.ts b/shared/src/models/utils/position/position.ts similarity index 92% rename from shared/src/models/utils/position/meta-position.ts rename to shared/src/models/utils/position/position.ts index 888ee823b..055c0f545 100644 --- a/shared/src/models/utils/position/meta-position.ts +++ b/shared/src/models/utils/position/position.ts @@ -3,7 +3,7 @@ import type { SimulatedRegionPosition } from './simulated-region-position'; import type { TransferPosition } from './transfer-position'; import type { VehiclePosition } from './vehicle-position'; -export type MetaPosition = +export type Position = | MapPosition | SimulatedRegionPosition | TransferPosition diff --git a/shared/src/models/utils/position/simulated-region-position.ts b/shared/src/models/utils/position/simulated-region-position.ts index bd880f28e..26af7dfff 100644 --- a/shared/src/models/utils/position/simulated-region-position.ts +++ b/shared/src/models/utils/position/simulated-region-position.ts @@ -9,7 +9,7 @@ import { isNotInSimulatedRegion, // eslint-disable-next-line @typescript-eslint/no-unused-vars simulatedRegionItsIn, -} from './meta-position-helpers'; +} from './position-helpers'; export class SimulatedRegionPosition { /** diff --git a/shared/src/models/utils/position/transfer-position.ts b/shared/src/models/utils/position/transfer-position.ts index a6babc1d5..6f80018a7 100644 --- a/shared/src/models/utils/position/transfer-position.ts +++ b/shared/src/models/utils/position/transfer-position.ts @@ -10,7 +10,7 @@ import { isNotInTransfer, // eslint-disable-next-line @typescript-eslint/no-unused-vars transferItsIn, -} from './meta-position-helpers'; +} from './position-helpers'; export class TransferPosition { /** diff --git a/shared/src/models/utils/position/vehicle-position.ts b/shared/src/models/utils/position/vehicle-position.ts index 9b5711461..1bb236dc9 100644 --- a/shared/src/models/utils/position/vehicle-position.ts +++ b/shared/src/models/utils/position/vehicle-position.ts @@ -9,7 +9,7 @@ import { isNotInVehicle, // eslint-disable-next-line @typescript-eslint/no-unused-vars vehicleItsIn, -} from './meta-position-helpers'; +} from './position-helpers'; export class VehiclePosition { /** diff --git a/shared/src/models/utils/position/with-meta-position.ts b/shared/src/models/utils/position/with-meta-position.ts index e296e7843..e4af0cbc7 100644 --- a/shared/src/models/utils/position/with-meta-position.ts +++ b/shared/src/models/utils/position/with-meta-position.ts @@ -1,5 +1,5 @@ -import type { MetaPosition } from './meta-position'; +import type { Position } from './position'; -export interface WithMetaPosition { - readonly metaPosition: MetaPosition; +export interface WithPosition { + readonly metaPosition: Position; } diff --git a/shared/src/models/vehicle.ts b/shared/src/models/vehicle.ts index 5cb65b849..72ebaa9c3 100644 --- a/shared/src/models/vehicle.ts +++ b/shared/src/models/vehicle.ts @@ -8,10 +8,10 @@ import { } from 'class-validator'; import { uuid, uuidValidationOptions, UUID, UUIDSet } from '../utils'; import { IsUUIDSet } from '../utils/validators'; -import { IsMetaPosition } from '../utils/validators/is-metaposition'; +import { IsPosition } from '../utils/validators/is-position'; import { getCreate, Transfer } from './utils'; import { ImageProperties } from './utils/image-properties'; -import { MetaPosition } from './utils/position/meta-position'; +import { Position } from './utils/position/position'; export class Vehicle { @IsUUID(4, uuidValidationOptions) @@ -29,9 +29,9 @@ export class Vehicle { @IsNumber() public readonly patientCapacity: number; - @IsMetaPosition() + @IsPosition() @ValidateNested() - public readonly metaPosition: MetaPosition; + public readonly metaPosition: Position; @ValidateNested() @Type(() => ImageProperties) @@ -61,7 +61,7 @@ export class Vehicle { materialIds: UUIDSet, patientCapacity: number, image: ImageProperties, - metaPosition: MetaPosition + metaPosition: Position ) { this.vehicleType = vehicleType; this.name = name; diff --git a/shared/src/models/viewport.ts b/shared/src/models/viewport.ts index bc2cdc03e..dc1bf46c6 100644 --- a/shared/src/models/viewport.ts +++ b/shared/src/models/viewport.ts @@ -1,14 +1,8 @@ import { Type } from 'class-transformer'; import { IsString, IsUUID, ValidateNested } from 'class-validator'; import { UUID, uuid, uuidValidationOptions } from '../utils'; -import { IsMetaPosition } from '../utils/validators/is-metaposition'; -import { - coordinatesOf, - getCreate, - MapPosition, - MetaPosition, - Size, -} from './utils'; +import { IsPosition } from '../utils/validators/is-position'; +import { coordinatesOf, getCreate, MapPosition, Position, Size } from './utils'; import type { ImageProperties, MapCoordinates } from './utils'; export class Viewport { @@ -19,8 +13,8 @@ export class Viewport { * top-left position */ @ValidateNested() - @IsMetaPosition() - public readonly metaPosition: MetaPosition; + @IsPosition() + public readonly metaPosition: Position; @ValidateNested() @Type(() => Size) diff --git a/shared/src/state-migrations/16-add-meta-position.ts b/shared/src/state-migrations/16-add-meta-position.ts index bca88a103..e3bb0f865 100644 --- a/shared/src/state-migrations/16-add-meta-position.ts +++ b/shared/src/state-migrations/16-add-meta-position.ts @@ -1,7 +1,7 @@ import type { UUID } from '../utils'; import type { Migration } from './migration-functions'; -export const addMetaPosition16: Migration = { +export const addPosition16: Migration = { actions: (_initialState, actions) => { actions.forEach((action) => { if ( diff --git a/shared/src/state-migrations/migration-functions.ts b/shared/src/state-migrations/migration-functions.ts index 8bbed2f7b..a2a269b09 100644 --- a/shared/src/state-migrations/migration-functions.ts +++ b/shared/src/state-migrations/migration-functions.ts @@ -4,7 +4,7 @@ import { renameIncorrectPatientImages12 } from './12-rename-incorrect-patient-im import { addMapImageZIndex13 } from './13-add-map-image-zindex'; import { addPersonnelAndMaterialToState14 } from './14-add-personnel-and-material-templates-to-state'; import { addSimulatedRegions15 } from './15-add-simulated-regions'; -import { addMetaPosition16 } from './16-add-meta-position'; +import { addPosition16 } from './16-add-meta-position'; import { updateEocLog3 } from './3-update-eoc-log'; import { removeSetParticipantIdAction4 } from './4-remove-set-participant-id-action'; import { removeStatistics5 } from './5-remove-statistics'; @@ -54,5 +54,5 @@ export const migrations: { 13: addMapImageZIndex13, 14: addPersonnelAndMaterialToState14, 15: addSimulatedRegions15, - 16: addMetaPosition16, + 16: addPosition16, }; diff --git a/shared/src/store/action-reducers/map-images.ts b/shared/src/store/action-reducers/map-images.ts index 86061c56c..1ab8d77bd 100644 --- a/shared/src/store/action-reducers/map-images.ts +++ b/shared/src/store/action-reducers/map-images.ts @@ -10,7 +10,7 @@ import { } from 'class-validator'; import { MapImage } from '../../models'; import { MapPosition, MapCoordinates } from '../../models/utils'; -import { changePosition } from '../../models/utils/position/meta-position-helpers-mutable'; +import { changePosition } from '../../models/utils/position/position-helpers-mutable'; import type { ExerciseState } from '../../state'; import type { Mutable } from '../../utils'; import { diff --git a/shared/src/store/action-reducers/material.ts b/shared/src/store/action-reducers/material.ts index c17741a06..abb333f5c 100644 --- a/shared/src/store/action-reducers/material.ts +++ b/shared/src/store/action-reducers/material.ts @@ -1,7 +1,7 @@ import { Type } from 'class-transformer'; import { IsUUID, ValidateNested } from 'class-validator'; import { MapPosition, MapCoordinates } from '../../models/utils'; -import { changePositionWithId } from '../../models/utils/position/meta-position-helpers-mutable'; +import { changePositionWithId } from '../../models/utils/position/position-helpers-mutable'; import { UUID, uuidValidationOptions } from '../../utils'; import { IsValue } from '../../utils/validators'; import type { Action, ActionReducer } from '../action-reducer'; diff --git a/shared/src/store/action-reducers/patient.ts b/shared/src/store/action-reducers/patient.ts index bc5e7a319..28e806181 100644 --- a/shared/src/store/action-reducers/patient.ts +++ b/shared/src/store/action-reducers/patient.ts @@ -11,7 +11,7 @@ import { import { changePosition, changePositionWithId, -} from '../../models/utils/position/meta-position-helpers-mutable'; +} from '../../models/utils/position/position-helpers-mutable'; import type { ExerciseState } from '../../state'; import type { Mutable } from '../../utils'; import { diff --git a/shared/src/store/action-reducers/personnel.ts b/shared/src/store/action-reducers/personnel.ts index 3c0ee8152..0078da337 100644 --- a/shared/src/store/action-reducers/personnel.ts +++ b/shared/src/store/action-reducers/personnel.ts @@ -1,7 +1,7 @@ import { Type } from 'class-transformer'; import { IsUUID, ValidateNested } from 'class-validator'; import { MapPosition, MapCoordinates } from '../../models/utils'; -import { changePositionWithId } from '../../models/utils/position/meta-position-helpers-mutable'; +import { changePositionWithId } from '../../models/utils/position/position-helpers-mutable'; import { UUID, uuidValidationOptions } from '../../utils'; import { IsValue } from '../../utils/validators'; import type { Action, ActionReducer } from '../action-reducer'; diff --git a/shared/src/store/action-reducers/simulated-region.ts b/shared/src/store/action-reducers/simulated-region.ts index 2ba972d29..47da1ae69 100644 --- a/shared/src/store/action-reducers/simulated-region.ts +++ b/shared/src/store/action-reducers/simulated-region.ts @@ -5,7 +5,7 @@ import { MapCoordinates, MapPosition, Size } from '../../models/utils'; import { changePosition, changePositionWithId, -} from '../../models/utils/position/meta-position-helpers-mutable'; +} from '../../models/utils/position/position-helpers-mutable'; import { cloneDeepMutable, UUID, uuidValidationOptions } from '../../utils'; import { IsValue } from '../../utils/validators'; import type { Action, ActionReducer } from '../action-reducer'; diff --git a/shared/src/store/action-reducers/transfer-point.ts b/shared/src/store/action-reducers/transfer-point.ts index 1a3c45c43..c4760e0a0 100644 --- a/shared/src/store/action-reducers/transfer-point.ts +++ b/shared/src/store/action-reducers/transfer-point.ts @@ -8,7 +8,7 @@ import { } from 'class-validator'; import { TransferPoint } from '../../models'; import { coordinatesOf, MapCoordinates, MapPosition } from '../../models/utils'; -import { changePositionWithId } from '../../models/utils/position/meta-position-helpers-mutable'; +import { changePositionWithId } from '../../models/utils/position/position-helpers-mutable'; import { cloneDeepMutable, UUID, uuidValidationOptions } from '../../utils'; import { IsValue } from '../../utils/validators'; import type { Action, ActionReducer } from '../action-reducer'; diff --git a/shared/src/store/action-reducers/transfer.ts b/shared/src/store/action-reducers/transfer.ts index f7885ad9f..fee345168 100644 --- a/shared/src/store/action-reducers/transfer.ts +++ b/shared/src/store/action-reducers/transfer.ts @@ -9,7 +9,7 @@ import { StartPoint, startPointTypeOptions, } from '../../models/utils'; -import { changePosition } from '../../models/utils/position/meta-position-helpers-mutable'; +import { changePosition } from '../../models/utils/position/position-helpers-mutable'; import type { ExerciseState } from '../../state'; import { imageSizeToPosition } from '../../state-helpers'; import type { Mutable } from '../../utils'; diff --git a/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts b/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts index 4dd5d8787..5d72152b5 100644 --- a/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts +++ b/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts @@ -4,10 +4,10 @@ import { defaultMaterialTemplates } from '../../../data/default-state/material-t import { defaultPersonnelTemplates } from '../../../data/default-state/personnel-templates'; import type { Patient } from '../../../models'; import { Material, Personnel } from '../../../models'; -import type { MetaPosition, PatientStatus } from '../../../models/utils'; +import type { Position, PatientStatus } from '../../../models/utils'; import { coordinatesOf, - isMetaPositionOnMap, + isPositionOnMap, CanCaterFor, MapCoordinates, } from '../../../models/utils'; @@ -96,10 +96,7 @@ function addPatient( return patient; } -function addPersonnel( - state: Mutable, - metaPosition: MetaPosition -) { +function addPersonnel(state: Mutable, metaPosition: Position) { const personnel = cloneDeepMutable( Personnel.generatePersonnel( defaultPersonnelTemplates.notSan, @@ -114,7 +111,7 @@ function addPersonnel( green: 0, logicalOperator: 'and', }; - if (isMetaPositionOnMap(metaPosition)) { + if (isPositionOnMap(metaPosition)) { SpatialTree.addElement( state.spatialTrees.personnel, personnel.id, @@ -125,10 +122,7 @@ function addPersonnel( return personnel; } -function addMaterial( - state: Mutable, - metaPosition: MetaPosition -) { +function addMaterial(state: Mutable, metaPosition: Position) { const material = cloneDeepMutable( Material.generateMaterial( defaultMaterialTemplates.standard, @@ -143,7 +137,7 @@ function addMaterial( green: 0, logicalOperator: 'and', }; - if (isMetaPositionOnMap(metaPosition)) { + if (isPositionOnMap(metaPosition)) { SpatialTree.addElement( state.spatialTrees.materials, material.id, diff --git a/shared/src/store/action-reducers/vehicle.ts b/shared/src/store/action-reducers/vehicle.ts index 891739ccb..7a7dec1e6 100644 --- a/shared/src/store/action-reducers/vehicle.ts +++ b/shared/src/store/action-reducers/vehicle.ts @@ -12,7 +12,7 @@ import { import { changePosition, changePositionWithId, -} from '../../models/utils/position/meta-position-helpers-mutable'; +} from '../../models/utils/position/position-helpers-mutable'; import type { ExerciseState } from '../../state'; import { imageSizeToPosition } from '../../state-helpers'; import type { Mutable } from '../../utils'; diff --git a/shared/src/store/action-reducers/viewport.ts b/shared/src/store/action-reducers/viewport.ts index 5b436814b..bde167fd0 100644 --- a/shared/src/store/action-reducers/viewport.ts +++ b/shared/src/store/action-reducers/viewport.ts @@ -5,7 +5,7 @@ import { MapCoordinates, MapPosition, Size } from '../../models/utils'; import { changePosition, changePositionWithId, -} from '../../models/utils/position/meta-position-helpers-mutable'; +} from '../../models/utils/position/position-helpers-mutable'; import { cloneDeepMutable, UUID, uuidValidationOptions } from '../../utils'; import { IsValue } from '../../utils/validators'; import type { Action, ActionReducer } from '../action-reducer'; diff --git a/shared/src/utils/validators/is-metaposition.ts b/shared/src/utils/validators/is-position.ts similarity index 77% rename from shared/src/utils/validators/is-metaposition.ts rename to shared/src/utils/validators/is-position.ts index 09585bdf3..cf72d7f66 100644 --- a/shared/src/utils/validators/is-metaposition.ts +++ b/shared/src/utils/validators/is-position.ts @@ -1,28 +1,28 @@ import { Type } from 'class-transformer'; import { MapPosition } from '../../models/utils/position/map-position'; -import type { MetaPosition } from '../../models/utils/position/meta-position'; +import type { Position } from '../../models/utils/position/position'; import { SimulatedRegionPosition } from '../../models/utils/position/simulated-region-position'; import { TransferPosition } from '../../models/utils/position/transfer-position'; import { VehiclePosition } from '../../models/utils/position/vehicle-position'; import { IsLiteralUnion } from './is-literal-union'; -class MetaPositionBase { - @IsLiteralUnion({ +class PositionBase { + @IsLiteralUnion({ coordinates: true, simulatedRegion: true, transfer: true, vehicle: true, }) - public type: MetaPosition['type']; + public type: Position['type']; - constructor(type: MetaPosition['type']) { + constructor(type: Position['type']) { this.type = type; } } // eslint-disable-next-line @typescript-eslint/naming-convention -export const IsMetaPosition = () => - Type(() => MetaPositionBase, { +export const IsPosition = () => + Type(() => PositionBase, { keepDiscriminatorProperty: true, discriminator: { property: 'type', From ce42c40b832de1d891ff6cc1fa0ddff422bafe64 Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Thu, 26 Jan 2023 17:23:40 +0100 Subject: [PATCH 09/22] Add Migration (not for Add vehicle Action) --- .../position/position-helpers-mutable.ts | 2 + .../state-migrations/16-add-meta-position.ts | 2 +- .../17-replace-position-with-meta-position.ts | 348 ++++++++++++++++++ .../state-migrations/migration-functions.ts | 6 +- shared/src/state.ts | 2 +- 5 files changed, 356 insertions(+), 4 deletions(-) create mode 100644 shared/src/state-migrations/17-replace-position-with-meta-position.ts diff --git a/shared/src/models/utils/position/position-helpers-mutable.ts b/shared/src/models/utils/position/position-helpers-mutable.ts index 619eb6bc0..ffc50a3c0 100644 --- a/shared/src/models/utils/position/position-helpers-mutable.ts +++ b/shared/src/models/utils/position/position-helpers-mutable.ts @@ -80,6 +80,8 @@ function updateSpatialElementTree( type: SpatialElementType, state: Mutable ) { + console.log(type); + if (isOnMap(element) && isPositionOnMap(to)) { updateElementPosition( state, diff --git a/shared/src/state-migrations/16-add-meta-position.ts b/shared/src/state-migrations/16-add-meta-position.ts index e3bb0f865..bca88a103 100644 --- a/shared/src/state-migrations/16-add-meta-position.ts +++ b/shared/src/state-migrations/16-add-meta-position.ts @@ -1,7 +1,7 @@ import type { UUID } from '../utils'; import type { Migration } from './migration-functions'; -export const addPosition16: Migration = { +export const addMetaPosition16: Migration = { actions: (_initialState, actions) => { actions.forEach((action) => { if ( diff --git a/shared/src/state-migrations/17-replace-position-with-meta-position.ts b/shared/src/state-migrations/17-replace-position-with-meta-position.ts new file mode 100644 index 000000000..0b664f065 --- /dev/null +++ b/shared/src/state-migrations/17-replace-position-with-meta-position.ts @@ -0,0 +1,348 @@ +import type { UUID } from '../utils'; +import type { Migration } from './migration-functions'; + +export const replacePositionWithMetaPosition17: Migration = { + actions: (_initialState, actions) => { + console.log('Start Action Migration'); + actions.forEach((action) => { + if ( + (action as { type: string } | null)?.type === + '[Patient] Add patient' + ) { + const typedAction = action as { + patient: { + metaPosition?: + | any + | { type: 'coordinates'; position: any } + | { type: any }; + position: any; + }; + }; + if (typedAction.patient.metaPosition?.type === 'coordinates') { + typedAction.patient.metaPosition.coordinates = + typedAction.patient.metaPosition.position; + delete typedAction.patient.metaPosition.position; + } + typedAction.patient.position = typedAction.patient.metaPosition; + delete typedAction.patient.metaPosition; + } + if ( + (action as { type: string } | null)?.type === + '[Vehicle] Add vehicle' + ) { + const typedAction = action as { + vehicle: { + metaPosition?: + | any + | { type: 'coordinates'; position: any } + | { type: any }; + position: any; + }; + }; + if (typedAction.vehicle.metaPosition?.type === 'coordinates') { + typedAction.vehicle.metaPosition.coordinates = + typedAction.vehicle.metaPosition.position; + delete typedAction.vehicle.metaPosition.position; + } + typedAction.vehicle.position = typedAction.vehicle.metaPosition; + delete typedAction.vehicle.metaPosition; + } + if ( + (action as { type: string } | null)?.type === + '[Viewport] Add viewport' + ) { + const typedAction = action as { + viewport: { + position: + | { + type: 'coordinates'; + coordinates: { x: number; y: number }; + } + | { x: number; y: number }; + }; + }; + typedAction.viewport.position = { + type: 'coordinates', + coordinates: { + x: ( + typedAction.viewport.position as { + x: number; + y: number; + } + ).x, + y: ( + typedAction.viewport.position as { + x: number; + y: number; + } + ).y, + }, + }; + } + if ( + (action as { type: string } | null)?.type === + '[SimulatedRegion] Add simulated region' + ) { + const typedAction = action as { + simulatedRegion: { + position: + | { + type: 'coordinates'; + coordinates: { x: number; y: number }; + } + | { x: number; y: number }; + }; + }; + typedAction.simulatedRegion.position = { + type: 'coordinates', + coordinates: { + x: ( + typedAction.simulatedRegion.position as { + x: number; + y: number; + } + ).x, + y: ( + typedAction.simulatedRegion.position as { + x: number; + y: number; + } + ).y, + }, + }; + } + if ( + (action as { type: string } | null)?.type === + '[MapImage] Add MapImage' + ) { + const typedAction = action as { + mapImage: { + position: + | { + type: 'coordinates'; + coordinates: { x: number; y: number }; + } + | { x: number; y: number }; + }; + }; + typedAction.mapImage.position = { + type: 'coordinates', + coordinates: { + x: ( + typedAction.mapImage.position as { + x: number; + y: number; + } + ).x, + y: ( + typedAction.mapImage.position as { + x: number; + y: number; + } + ).y, + }, + }; + } + if ( + (action as { type: string } | null)?.type === + '[TransferPoint] Add TransferPoint' + ) { + const typedAction = action as { + transferPoint: { + position: + | { + type: 'coordinates'; + coordinates: { x: number; y: number }; + } + | { x: number; y: number }; + }; + }; + typedAction.transferPoint.position = { + type: 'coordinates', + coordinates: { + x: ( + typedAction.transferPoint.position as { + x: number; + y: number; + } + ).x, + y: ( + typedAction.transferPoint.position as { + x: number; + y: number; + } + ).y, + }, + }; + } + }); + console.log('End Action Migration'); + }, + state: (state) => { + console.log('Start State Migration'); + const typedState = state as { + patients: { + [patientId: UUID]: { + metaPosition?: + | any + | { type: 'coordinates'; position: any } + | { type: any }; + position: any; + }; + }; + materials: { + [materialId: UUID]: { + metaPosition?: + | any + | { type: 'coordinates'; position: any } + | { type: any }; + position: any; + }; + }; + vehicles: { + [vehicleId: UUID]: { + metaPosition?: + | any + | { type: 'coordinates'; position: any } + | { type: any }; + position: any; + }; + }; + personnel: { + [personnelId: UUID]: { + metaPosition?: + | any + | { type: 'coordinates'; position: any } + | { type: any }; + position: any; + }; + }; + viewports: { + [viewportId: UUID]: { + position: + | { + type: 'coordinates'; + coordinates: { x: number; y: number }; + } + | { x: number; y: number }; + }; + }; + simulatedRegions: { + [simulatedRegionId: UUID]: { + position: + | { + type: 'coordinates'; + coordinates: { x: number; y: number }; + } + | { x: number; y: number }; + }; + }; + mapImages: { + [simulatedRegionId: UUID]: { + position: + | { + type: 'coordinates'; + coordinates: { x: number; y: number }; + } + | { x: number; y: number }; + }; + }; + transferPoints: { + [simulatedRegionId: UUID]: { + position: + | { + type: 'coordinates'; + coordinates: { x: number; y: number }; + } + | { x: number; y: number }; + }; + }; + }; + + Object.values(typedState.patients).forEach((patient) => { + if (patient.metaPosition?.type === 'coordinates') { + patient.metaPosition.coordinates = + patient.metaPosition.position; + delete patient.metaPosition.position; + } + patient.position = patient.metaPosition; + delete patient.metaPosition; + }); + + Object.values(typedState.materials).forEach((material) => { + if (material.metaPosition.type === undefined) { + console.log('ALARMMMMM'); + } + if (material.metaPosition?.type === 'coordinates') { + material.metaPosition.coordinates = + material.metaPosition.position; + delete material.metaPosition.position; + } + material.position = material.metaPosition; + delete material.metaPosition; + }); + + Object.values(typedState.vehicles).forEach((vehicle) => { + if (vehicle.metaPosition?.type === 'coordinates') { + vehicle.metaPosition.coordinates = + vehicle.metaPosition.position; + delete vehicle.metaPosition.position; + } + vehicle.position = vehicle.metaPosition; + delete vehicle.metaPosition; + }); + + Object.values(typedState.personnel).forEach((personnel) => { + if (personnel.metaPosition?.type === 'coordinates') { + personnel.metaPosition.coordinates = + personnel.metaPosition.position; + delete personnel.metaPosition.position; + } + personnel.position = personnel.metaPosition; + delete personnel.metaPosition; + }); + Object.values(typedState.viewports).forEach((viewport) => { + viewport.position = { + type: 'coordinates', + coordinates: { + x: (viewport.position as { x: number; y: number }).x, + y: (viewport.position as { x: number; y: number }).y, + }, + }; + }); + Object.values(typedState.simulatedRegions).forEach( + (simulatedRegion) => { + simulatedRegion.position = { + type: 'coordinates', + coordinates: { + x: ( + simulatedRegion.position as { x: number; y: number } + ).x, + y: ( + simulatedRegion.position as { x: number; y: number } + ).y, + }, + }; + } + ); + Object.values(typedState.mapImages).forEach((mapImage) => { + mapImage.position = { + type: 'coordinates', + coordinates: { + x: (mapImage.position as { x: number; y: number }).x, + y: (mapImage.position as { x: number; y: number }).y, + }, + }; + }); + Object.values(typedState.transferPoints).forEach((transferPoint) => { + transferPoint.position = { + type: 'coordinates', + coordinates: { + x: (transferPoint.position as { x: number; y: number }).x, + y: (transferPoint.position as { x: number; y: number }).y, + }, + }; + }); + console.log('End State Migration'); + }, +}; diff --git a/shared/src/state-migrations/migration-functions.ts b/shared/src/state-migrations/migration-functions.ts index a2a269b09..d810082ce 100644 --- a/shared/src/state-migrations/migration-functions.ts +++ b/shared/src/state-migrations/migration-functions.ts @@ -4,7 +4,8 @@ import { renameIncorrectPatientImages12 } from './12-rename-incorrect-patient-im import { addMapImageZIndex13 } from './13-add-map-image-zindex'; import { addPersonnelAndMaterialToState14 } from './14-add-personnel-and-material-templates-to-state'; import { addSimulatedRegions15 } from './15-add-simulated-regions'; -import { addPosition16 } from './16-add-meta-position'; +import { addMetaPosition16 } from './16-add-meta-position'; +import { replacePositionWithMetaPosition17 } from './17-replace-position-with-meta-position'; import { updateEocLog3 } from './3-update-eoc-log'; import { removeSetParticipantIdAction4 } from './4-remove-set-participant-id-action'; import { removeStatistics5 } from './5-remove-statistics'; @@ -54,5 +55,6 @@ export const migrations: { 13: addMapImageZIndex13, 14: addPersonnelAndMaterialToState14, 15: addSimulatedRegions15, - 16: addPosition16, + 16: addMetaPosition16, + 17: replacePositionWithMetaPosition17, }; diff --git a/shared/src/state.ts b/shared/src/state.ts index 0f05987f2..8c018ebc3 100644 --- a/shared/src/state.ts +++ b/shared/src/state.ts @@ -148,5 +148,5 @@ export class ExerciseState { * * This number MUST be increased every time a change to any object (that is part of the state or the state itself) is made in a way that there may be states valid before that are no longer valid. */ - static readonly currentStateVersion = 16; + static readonly currentStateVersion = 17; } From d32b1d73f368d96b11587cd4fa8dcbdee81bcbd8 Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Mon, 30 Jan 2023 17:54:28 +0100 Subject: [PATCH 10/22] complete the renaming --- .../moveable-feature-manager.ts | 2 +- .../simulated-region-feature-manager.ts | 2 +- .../viewport-feature-manager.ts | 2 +- .../exercise-map/utility/geometry-helper.ts | 2 +- shared/src/models/map-image.ts | 4 +- shared/src/models/material.ts | 10 +-- shared/src/models/patient-template.ts | 4 +- shared/src/models/patient.ts | 6 +- shared/src/models/personnel.ts | 12 +-- shared/src/models/simulated-region.ts | 4 +- shared/src/models/transfer-point.ts | 4 +- .../position/position-helpers-mutable.ts | 6 +- .../models/utils/position/position-helpers.ts | 90 +++++++++---------- .../utils/position/with-meta-position.ts | 2 +- shared/src/models/vehicle.ts | 8 +- shared/src/models/viewport.ts | 4 +- .../create-vehicle-parameters.ts | 2 +- shared/src/store/action-reducers/patient.ts | 2 +- .../utils/calculate-treatments.spec.ts | 14 +-- .../src/store/reduce-exercise-state.spec.ts | 2 +- .../store/validate-exercise-action.spec.ts | 4 +- 21 files changed, 92 insertions(+), 94 deletions(-) diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/moveable-feature-manager.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/moveable-feature-manager.ts index 4a1f70ee6..94034d561 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/moveable-feature-manager.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/moveable-feature-manager.ts @@ -86,7 +86,7 @@ export abstract class MoveableFeatureManager< changedProperties: ReadonlySet, elementFeature: Feature ): void { - if (changedProperties.has('metaPosition')) { + if (changedProperties.has('position')) { this.movementAnimator.animateFeatureMovement( elementFeature, this.geometryHelper.getElementCoordinates(newElement) diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/simulated-region-feature-manager.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/simulated-region-feature-manager.ts index 3fa7dc410..0b62be0bb 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/simulated-region-feature-manager.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/simulated-region-feature-manager.ts @@ -92,7 +92,7 @@ export class SimulatedRegionFeatureManager elementFeature: Feature ): void { if ( - changedProperties.has('metaPosition') || + changedProperties.has('position') || changedProperties.has('size') ) { this.movementAnimator.animateFeatureMovement( diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/viewport-feature-manager.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/viewport-feature-manager.ts index e2bcc6386..2f1bb0c28 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/viewport-feature-manager.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/feature-managers/viewport-feature-manager.ts @@ -100,7 +100,7 @@ export class ViewportFeatureManager elementFeature: Feature ): void { if ( - changedProperties.has('metaPosition') || + changedProperties.has('position') || changedProperties.has('size') ) { this.movementAnimator.animateFeatureMovement( diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/geometry-helper.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/geometry-helper.ts index d0330fa05..c73200b8a 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/geometry-helper.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/geometry-helper.ts @@ -10,7 +10,7 @@ import type { Geometry } from 'ol/geom'; export interface PositionableElement { readonly id: UUID; - readonly metaPosition: Position; + readonly position: Position; } export type ResizableElement = PositionableElement & { diff --git a/shared/src/models/map-image.ts b/shared/src/models/map-image.ts index ef00fbaf1..62da92697 100644 --- a/shared/src/models/map-image.ts +++ b/shared/src/models/map-image.ts @@ -15,7 +15,7 @@ export class MapImage { @ValidateNested() @IsPosition() - public readonly metaPosition: Position; + public readonly position: Position; @ValidateNested() @Type(() => ImageProperties) @@ -45,7 +45,7 @@ export class MapImage { isLocked: boolean, zIndex: number ) { - this.metaPosition = MapPosition.create(topLeft); + this.position = MapPosition.create(topLeft); this.image = image; this.isLocked = isLocked; this.zIndex = zIndex; diff --git a/shared/src/models/material.ts b/shared/src/models/material.ts index a3bfde6e7..5b746bc14 100644 --- a/shared/src/models/material.ts +++ b/shared/src/models/material.ts @@ -57,7 +57,7 @@ export class Material { @IsPosition() @ValidateNested() - public readonly metaPosition: Position; + public readonly position: Position; @ValidateNested() @Type(() => ImageProperties) @@ -74,7 +74,7 @@ export class Material { canCaterFor: CanCaterFor, treatmentRange: number, overrideTreatmentRange: number, - metaPosition: Position + position: Position ) { this.vehicleId = vehicleId; this.vehicleName = vehicleName; @@ -83,7 +83,7 @@ export class Material { this.canCaterFor = canCaterFor; this.treatmentRange = treatmentRange; this.overrideTreatmentRange = overrideTreatmentRange; - this.metaPosition = metaPosition; + this.position = position; } static readonly create = getCreate(this); @@ -92,7 +92,7 @@ export class Material { materialTemplate: MaterialTemplate, vehicleId: UUID, vehicleName: string, - metaPosition: Position + position: Position ): Material { return this.create( vehicleId, @@ -102,7 +102,7 @@ export class Material { materialTemplate.canCaterFor, materialTemplate.treatmentRange, materialTemplate.overrideTreatmentRange, - metaPosition + position ); } } diff --git a/shared/src/models/patient-template.ts b/shared/src/models/patient-template.ts index eb61b4610..0c3140dbd 100644 --- a/shared/src/models/patient-template.ts +++ b/shared/src/models/patient-template.ts @@ -72,7 +72,7 @@ export class PatientTemplate { public static generatePatient( template: PatientTemplate, patientStatusCode: PatientStatusCode, - metaPosition: Position + position: Position ): Patient { // Randomize function parameters const healthStates = Object.fromEntries( @@ -113,7 +113,7 @@ export class PatientTemplate { template.image, template.health, '', - metaPosition + position ); } } diff --git a/shared/src/models/patient.ts b/shared/src/models/patient.ts index cb3ea0eef..e41f22f05 100644 --- a/shared/src/models/patient.ts +++ b/shared/src/models/patient.ts @@ -73,7 +73,7 @@ export class Patient { @IsPosition() @ValidateNested() - public readonly metaPosition: Position; + public readonly position: Position; @IsUUID(4, uuidValidationOptions) @IsOptional() @@ -158,7 +158,7 @@ export class Patient { image: ImageProperties, health: HealthPoints, remarks: string, - metaPosition: Position + position: Position ) { this.personalInformation = personalInformation; this.biometricInformation = biometricInformation; @@ -171,7 +171,7 @@ export class Patient { this.image = image; this.health = health; this.remarks = remarks; - this.metaPosition = metaPosition; + this.position = position; } static readonly create = getCreate(this); diff --git a/shared/src/models/personnel.ts b/shared/src/models/personnel.ts index 79998963b..0cad40ee9 100644 --- a/shared/src/models/personnel.ts +++ b/shared/src/models/personnel.ts @@ -73,10 +73,10 @@ export class Personnel { @IsPosition() @ValidateNested() - public readonly metaPosition: Position; + public readonly position: Position; /** - * * @deprecated use {@link metaPosition} + * * @deprecated use {@link position} * If undefined, the personnel is either in the vehicle with {@link this.vehicleId} or has a {@link position}. */ @ValidateNested() @@ -96,7 +96,7 @@ export class Personnel { canCaterFor: CanCaterFor, treatmentRange: number, overrideTreatmentRange: number, - metaPosition: Position, + position: Position, position?: MapCoordinates ) { this.vehicleId = vehicleId; @@ -107,7 +107,7 @@ export class Personnel { this.canCaterFor = canCaterFor; this.treatmentRange = treatmentRange; this.overrideTreatmentRange = overrideTreatmentRange; - this.metaPosition = metaPosition; + this.position = position; } static readonly create = getCreate(this); @@ -116,7 +116,7 @@ export class Personnel { personnelTemplate: PersonnelTemplate, vehicleId: UUID, vehicleName: string, - metaPosition: Position + position: Position ): Personnel { return this.create( vehicleId, @@ -127,7 +127,7 @@ export class Personnel { personnelTemplate.canCaterFor, personnelTemplate.treatmentRange, personnelTemplate.overrideTreatmentRange, - metaPosition, + position, undefined ); } diff --git a/shared/src/models/simulated-region.ts b/shared/src/models/simulated-region.ts index ec42a2bdc..e65e371c4 100644 --- a/shared/src/models/simulated-region.ts +++ b/shared/src/models/simulated-region.ts @@ -26,7 +26,7 @@ export class SimulatedRegion { */ @ValidateNested() @IsPosition() - public readonly metaPosition: Position; + public readonly position: Position; @ValidateNested() @Type(() => Size) @@ -40,7 +40,7 @@ export class SimulatedRegion { * @deprecated Use {@link create} instead */ constructor(position: MapCoordinates, size: Size, name: string) { - this.metaPosition = MapPosition.create(position); + this.position = MapPosition.create(position); this.size = size; this.name = name; } diff --git a/shared/src/models/transfer-point.ts b/shared/src/models/transfer-point.ts index 6a9f4bbe8..72885fd26 100644 --- a/shared/src/models/transfer-point.ts +++ b/shared/src/models/transfer-point.ts @@ -18,7 +18,7 @@ export class TransferPoint { @ValidateNested() @IsPosition() - public readonly metaPosition: Position; + public readonly position: Position; @IsReachableTransferPoints() public readonly reachableTransferPoints: ReachableTransferPoints; @@ -42,7 +42,7 @@ export class TransferPoint { internalName: string, externalName: string ) { - this.metaPosition = MapPosition.create(position); + this.position = MapPosition.create(position); this.reachableTransferPoints = reachableTransferPoints; this.reachableHospitals = reachableHospitals; this.internalName = internalName; diff --git a/shared/src/models/utils/position/position-helpers-mutable.ts b/shared/src/models/utils/position/position-helpers-mutable.ts index 42b27d7a1..aad920ea6 100644 --- a/shared/src/models/utils/position/position-helpers-mutable.ts +++ b/shared/src/models/utils/position/position-helpers-mutable.ts @@ -20,7 +20,7 @@ import { type MutablePosition = Mutable; interface WithMutablePosition { - metaPosition: MutablePosition; + position: MutablePosition; } interface WithMutablePositionAndId extends WithMutablePosition { id: UUID; @@ -67,11 +67,11 @@ export function changePosition( type, inState ); - of.metaPosition = cloneDeepMutable(to); + of.position = cloneDeepMutable(to); updateTreatments(inState, of as any); return; } - of.metaPosition = cloneDeepMutable(to); + of.position = cloneDeepMutable(to); } function updateSpatialElementTree( diff --git a/shared/src/models/utils/position/position-helpers.ts b/shared/src/models/utils/position/position-helpers.ts index f8d0ada3b..66e9ad261 100644 --- a/shared/src/models/utils/position/position-helpers.ts +++ b/shared/src/models/utils/position/position-helpers.ts @@ -9,16 +9,16 @@ import type { VehiclePosition } from './vehicle-position'; import type { WithPosition } from './with-meta-position'; export function isOnMap(withPosition: WithPosition): boolean { - return withPosition.metaPosition.type === 'coordinates'; + return withPosition.position.type === 'coordinates'; } export function isInVehicle(withPosition: WithPosition): boolean { - return withPosition.metaPosition.type === 'vehicle'; + return withPosition.position.type === 'vehicle'; } export function isInTransfer(withPosition: WithPosition): boolean { - return withPosition.metaPosition.type === 'transfer'; + return withPosition.position.type === 'transfer'; } export function isInSimulatedRegion(withPosition: WithPosition): boolean { - return withPosition.metaPosition.type === 'simulatedRegion'; + return withPosition.position.type === 'simulatedRegion'; } export function isNotOnMap(withPosition: WithPosition): boolean { return !isOnMap(withPosition); @@ -35,100 +35,98 @@ export function isNotInSimulatedRegion(withPosition: WithPosition): boolean { export function coordinatesOf(withPosition: WithPosition): MapCoordinates { if (isOnMap(withPosition)) { - return (withPosition.metaPosition as MapPosition).position; + return (withPosition.position as MapPosition).position; } throw new TypeError( - `Expected metaPosition of object to be on Map. Was of type ${withPosition.metaPosition.type}.` + `Expected position of object to be on Map. Was of type ${withPosition.position.type}.` ); } export function vehicleItsIn(withPosition: WithPosition): UUID { if (isInVehicle(withPosition)) { - return (withPosition.metaPosition as VehiclePosition).vehicleId; + return (withPosition.position as VehiclePosition).vehicleId; } throw new TypeError( - `Expected metaPosition of object to be in vehicle. Was of type ${withPosition.metaPosition.type}.` + `Expected position of object to be in vehicle. Was of type ${withPosition.position.type}.` ); } export function transferItsIn(withPosition: WithPosition): Transfer { if (isInTransfer(withPosition)) { - return (withPosition.metaPosition as TransferPosition).transfer; + return (withPosition.position as TransferPosition).transfer; } throw new TypeError( - `Expected metaPosition of object to be in transfer. Was of type ${withPosition.metaPosition.type}.` + `Expected position of object to be in transfer. Was of type ${withPosition.position.type}.` ); } export function simulatedRegionItsIn(withPosition: WithPosition): UUID { if (isInSimulatedRegion(withPosition)) { - return (withPosition.metaPosition as SimulatedRegionPosition) + return (withPosition.position as SimulatedRegionPosition) .simulatedRegionId; } throw new TypeError( - `Expected metaPosition of object to be in simulatedRegion. Was of type ${withPosition.metaPosition.type}.` + `Expected position of object to be in simulatedRegion. Was of type ${withPosition.position.type}.` ); } -export function isPositionOnMap(metaPosition: Position): boolean { - return metaPosition.type === 'coordinates'; +export function isPositionOnMap(position: Position): boolean { + return position.type === 'coordinates'; } -export function isPositionInVehicle(metaPosition: Position): boolean { - return metaPosition.type === 'vehicle'; +export function isPositionInVehicle(position: Position): boolean { + return position.type === 'vehicle'; } -export function isPositionInTransfer(metaPosition: Position): boolean { - return metaPosition.type === 'transfer'; +export function isPositionInTransfer(position: Position): boolean { + return position.type === 'transfer'; } -export function isPositionInSimulatedRegion(metaPosition: Position): boolean { - return metaPosition.type === 'simulatedRegion'; +export function isPositionInSimulatedRegion(position: Position): boolean { + return position.type === 'simulatedRegion'; } -export function isPositionNotOnMap(metaPosition: Position): boolean { - return !isPositionOnMap(metaPosition); +export function isPositionNotOnMap(position: Position): boolean { + return !isPositionOnMap(position); } -export function isPositionNotInVehicle(metaPosition: Position): boolean { - return !isPositionInVehicle(metaPosition); +export function isPositionNotInVehicle(position: Position): boolean { + return !isPositionInVehicle(position); } -export function isPositionNotInTransfer(metaPosition: Position): boolean { - return !isPositionInTransfer(metaPosition); +export function isPositionNotInTransfer(position: Position): boolean { + return !isPositionInTransfer(position); } -export function isPositionNotInSimulatedRegion( - metaPosition: Position -): boolean { - return !isPositionInSimulatedRegion(metaPosition); +export function isPositionNotInSimulatedRegion(position: Position): boolean { + return !isPositionInSimulatedRegion(position); } -export function coordinatesOfPosition(metaPosition: Position): MapCoordinates { - if (isPositionOnMap(metaPosition)) { - return (metaPosition as MapPosition).position; +export function coordinatesOfPosition(position: Position): MapCoordinates { + if (isPositionOnMap(position)) { + return (position as MapPosition).position; } throw new TypeError( - `Expected metaPosition of object to be on Map. Was of type ${metaPosition.type}.` + `Expected position of object to be on Map. Was of type ${position.type}.` ); } -export function vehiclePositionIn(metaPosition: Position): UUID { - if (isPositionInVehicle(metaPosition)) { - return (metaPosition as VehiclePosition).vehicleId; +export function vehiclePositionIn(position: Position): UUID { + if (isPositionInVehicle(position)) { + return (position as VehiclePosition).vehicleId; } throw new TypeError( - `Expected metaPosition of object to be in vehicle. Was of type ${metaPosition.type}.` + `Expected position of object to be in vehicle. Was of type ${position.type}.` ); } -export function transferPositionIn(metaPosition: Position): Transfer { - if (isPositionInTransfer(metaPosition)) { - return (metaPosition as TransferPosition).transfer; +export function transferPositionIn(position: Position): Transfer { + if (isPositionInTransfer(position)) { + return (position as TransferPosition).transfer; } throw new TypeError( - `Expected metaPosition of object to be in transfer. Was of type ${metaPosition.type}.` + `Expected position of object to be in transfer. Was of type ${position.type}.` ); } -export function simulatedRegionPositionIn(metaPosition: Position): UUID { - if (isPositionInSimulatedRegion(metaPosition)) { - return (metaPosition as SimulatedRegionPosition).simulatedRegionId; +export function simulatedRegionPositionIn(position: Position): UUID { + if (isPositionInSimulatedRegion(position)) { + return (position as SimulatedRegionPosition).simulatedRegionId; } throw new TypeError( - `Expected metaPosition of object to be in simulatedRegion. Was of type ${metaPosition.type}.` + `Expected position of object to be in simulatedRegion. Was of type ${position.type}.` ); } diff --git a/shared/src/models/utils/position/with-meta-position.ts b/shared/src/models/utils/position/with-meta-position.ts index e4af0cbc7..9fca34434 100644 --- a/shared/src/models/utils/position/with-meta-position.ts +++ b/shared/src/models/utils/position/with-meta-position.ts @@ -1,5 +1,5 @@ import type { Position } from './position'; export interface WithPosition { - readonly metaPosition: Position; + readonly position: Position; } diff --git a/shared/src/models/vehicle.ts b/shared/src/models/vehicle.ts index 12ff66264..094a0b0a5 100644 --- a/shared/src/models/vehicle.ts +++ b/shared/src/models/vehicle.ts @@ -34,14 +34,14 @@ export class Vehicle { @IsPosition() @ValidateNested() - public readonly metaPosition: Position; + public readonly position: Position; @ValidateNested() @Type(() => ImageProperties) public readonly image: ImageProperties; /** - * @deprecated use {@link metaPosition} + * @deprecated use {@link position} * Exclusive-or to {@link position} */ @ValidateNested() @@ -64,14 +64,14 @@ export class Vehicle { materialIds: UUIDSet, patientCapacity: number, image: ImageProperties, - metaPosition: Position + position: Position ) { this.vehicleType = vehicleType; this.name = name; this.materialIds = materialIds; this.patientCapacity = patientCapacity; this.image = image; - this.metaPosition = metaPosition; + this.position = position; } static readonly create = getCreate(this); diff --git a/shared/src/models/viewport.ts b/shared/src/models/viewport.ts index 2eb8369bd..2266f0d3c 100644 --- a/shared/src/models/viewport.ts +++ b/shared/src/models/viewport.ts @@ -18,7 +18,7 @@ export class Viewport { */ @ValidateNested() @IsPosition() - public readonly metaPosition: Position; + public readonly position: Position; @ValidateNested() @Type(() => Size) @@ -32,7 +32,7 @@ export class Viewport { * @deprecated Use {@link create} instead */ constructor(position: MapCoordinates, size: Size, name: string) { - this.metaPosition = MapPosition.create(position); + this.position = MapPosition.create(position); this.size = size; this.name = name; } diff --git a/shared/src/state-helpers/create-vehicle-parameters.ts b/shared/src/state-helpers/create-vehicle-parameters.ts index ec1b09ef6..661973a9a 100644 --- a/shared/src/state-helpers/create-vehicle-parameters.ts +++ b/shared/src/state-helpers/create-vehicle-parameters.ts @@ -56,7 +56,7 @@ export function createVehicleParameters( image: vehicleTemplate.image, patientIds: {}, personnelIds: arrayToUUIDSet(personnel.map((p) => p.id)), - metaPosition: MapPosition.create(vehiclePosition), + position: MapPosition.create(vehiclePosition), }; return { materials, diff --git a/shared/src/store/action-reducers/patient.ts b/shared/src/store/action-reducers/patient.ts index 80712ae9f..b85970817 100644 --- a/shared/src/store/action-reducers/patient.ts +++ b/shared/src/store/action-reducers/patient.ts @@ -124,7 +124,7 @@ export namespace PatientActionReducers { draftState.patients[mutablePatient.id] = mutablePatient; changePosition( mutablePatient, - patient.metaPosition, + patient.position, 'patient', draftState ); diff --git a/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts b/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts index a6b5b3cfc..d7f50e76f 100644 --- a/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts +++ b/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts @@ -82,7 +82,7 @@ function addPatient( patient.pretriageStatus = pretriageStatus; patient.realStatus = realStatus; if (position) { - patient.metaPosition = { + patient.position = { type: 'coordinates', position: cloneDeepMutable(position), }; @@ -96,13 +96,13 @@ function addPatient( return patient; } -function addPersonnel(state: Mutable, metaPosition: Position) { +function addPersonnel(state: Mutable, position: Position) { const personnel = cloneDeepMutable( Personnel.generatePersonnel( defaultPersonnelTemplates.notSan, uuid(), 'RTW 3/83/1', - metaPosition + position ) ); personnel.canCaterFor = { @@ -111,7 +111,7 @@ function addPersonnel(state: Mutable, metaPosition: Position) { green: 0, logicalOperator: 'and', }; - if (isPositionOnMap(metaPosition)) { + if (isPositionOnMap(position)) { SpatialTree.addElement( state.spatialTrees.personnel, personnel.id, @@ -122,13 +122,13 @@ function addPersonnel(state: Mutable, metaPosition: Position) { return personnel; } -function addMaterial(state: Mutable, metaPosition: Position) { +function addMaterial(state: Mutable, position: Position) { const material = cloneDeepMutable( Material.generateMaterial( defaultMaterialTemplates.standard, uuid(), 'RTW 3/83/1', - metaPosition + position ) ); material.canCaterFor = { @@ -137,7 +137,7 @@ function addMaterial(state: Mutable, metaPosition: Position) { green: 0, logicalOperator: 'and', }; - if (isPositionOnMap(metaPosition)) { + if (isPositionOnMap(position)) { SpatialTree.addElement( state.spatialTrees.materials, material.id, diff --git a/shared/src/store/reduce-exercise-state.spec.ts b/shared/src/store/reduce-exercise-state.spec.ts index ec0e744f8..317638bcc 100644 --- a/shared/src/store/reduce-exercise-state.spec.ts +++ b/shared/src/store/reduce-exercise-state.spec.ts @@ -16,7 +16,7 @@ describe('exerciseReducer', () => { type: 'viewport', name: 'Test', size: { width: 100, height: 100 }, - metaPosition: MapPosition.create(MapCoordinates.create(0, 0)), + position: MapPosition.create(MapCoordinates.create(0, 0)), } as const; } diff --git a/shared/src/store/validate-exercise-action.spec.ts b/shared/src/store/validate-exercise-action.spec.ts index 7be84aeab..81dbf84e7 100644 --- a/shared/src/store/validate-exercise-action.spec.ts +++ b/shared/src/store/validate-exercise-action.spec.ts @@ -77,7 +77,7 @@ describe('validateExerciseAction', () => { height: 1, width: 1, }, - metaPosition: { + position: { type: 'coordinates', position: { // this is of type string instead of number @@ -122,7 +122,7 @@ describe('validateExerciseAction', () => { height: 1, width: 1, }, - metaPosition: { + position: { type: 'coordinates', position: { x: 0, From 2877c0827625083d8350c1f29044b37767389f87 Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Mon, 30 Jan 2023 18:03:17 +0100 Subject: [PATCH 11/22] Fix Tests --- shared/src/models/personnel.ts | 7 ++----- shared/src/models/vehicle.ts | 4 ---- ...sition.ts => 18-replace-position-with-meta-position.ts} | 0 shared/src/state-migrations/migration-functions.ts | 2 +- shared/src/state.ts | 2 +- 5 files changed, 4 insertions(+), 11 deletions(-) rename shared/src/state-migrations/{17-replace-position-with-meta-position.ts => 18-replace-position-with-meta-position.ts} (100%) diff --git a/shared/src/models/personnel.ts b/shared/src/models/personnel.ts index 0cad40ee9..eef6a561a 100644 --- a/shared/src/models/personnel.ts +++ b/shared/src/models/personnel.ts @@ -13,7 +13,6 @@ import { uuidValidationOptions, UUID, uuid, UUIDSet } from '../utils'; import { IsLiteralUnion, IsUUIDSet, IsValue } from '../utils/validators'; import { IsPosition } from '../utils/validators/is-position'; import type { PersonnelTemplate } from './personnel-template'; -import type { MapCoordinates } from './utils'; import { PersonnelType, CanCaterFor, @@ -96,8 +95,7 @@ export class Personnel { canCaterFor: CanCaterFor, treatmentRange: number, overrideTreatmentRange: number, - position: Position, - position?: MapCoordinates + position: Position ) { this.vehicleId = vehicleId; this.vehicleName = vehicleName; @@ -127,8 +125,7 @@ export class Personnel { personnelTemplate.canCaterFor, personnelTemplate.treatmentRange, personnelTemplate.overrideTreatmentRange, - position, - undefined + position ); } } diff --git a/shared/src/models/vehicle.ts b/shared/src/models/vehicle.ts index 094a0b0a5..e00465950 100644 --- a/shared/src/models/vehicle.ts +++ b/shared/src/models/vehicle.ts @@ -40,10 +40,6 @@ export class Vehicle { @Type(() => ImageProperties) public readonly image: ImageProperties; - /** - * @deprecated use {@link position} - * Exclusive-or to {@link position} - */ @ValidateNested() @Type(() => Transfer) @IsOptional() diff --git a/shared/src/state-migrations/17-replace-position-with-meta-position.ts b/shared/src/state-migrations/18-replace-position-with-meta-position.ts similarity index 100% rename from shared/src/state-migrations/17-replace-position-with-meta-position.ts rename to shared/src/state-migrations/18-replace-position-with-meta-position.ts diff --git a/shared/src/state-migrations/migration-functions.ts b/shared/src/state-migrations/migration-functions.ts index eb633ded2..780cdf86d 100644 --- a/shared/src/state-migrations/migration-functions.ts +++ b/shared/src/state-migrations/migration-functions.ts @@ -5,8 +5,8 @@ import { addMapImageZIndex13 } from './13-add-map-image-zindex'; import { addPersonnelAndMaterialToState14 } from './14-add-personnel-and-material-templates-to-state'; import { addSimulatedRegions15 } from './15-add-simulated-regions'; import { addMetaPosition16 } from './16-add-meta-position'; -import { replacePositionWithMetaPosition18 } from './17-replace-position-with-meta-position'; import { addTypeProperty17 } from './17-add-type-property'; +import { replacePositionWithMetaPosition18 } from './18-replace-position-with-meta-position'; import { updateEocLog3 } from './3-update-eoc-log'; import { removeSetParticipantIdAction4 } from './4-remove-set-participant-id-action'; import { removeStatistics5 } from './5-remove-statistics'; diff --git a/shared/src/state.ts b/shared/src/state.ts index de96e2b71..646d02c7b 100644 --- a/shared/src/state.ts +++ b/shared/src/state.ts @@ -148,5 +148,5 @@ export class ExerciseState { * * This number MUST be increased every time a change to any object (that is part of the state or the state itself) is made in a way that there may be states valid before that are no longer valid. */ - static readonly currentStateVersion = 17; + static readonly currentStateVersion = 18; } From 6dc9ade6f14f167e36b42227fe66a2ca7938fabe Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Mon, 30 Jan 2023 19:11:55 +0100 Subject: [PATCH 12/22] Remove Transfer Property --- .../core/statistics/statistics.service.ts | 3 +- .../selectors/exercise.selectors.ts | 10 ++-- shared/src/models/patient.ts | 5 -- shared/src/models/personnel.ts | 11 ---- shared/src/models/vehicle.ts | 15 +----- .../18-replace-position-with-meta-position.ts | 8 +++ shared/src/store/action-reducers/exercise.ts | 24 +++++++-- .../store/action-reducers/transfer-point.ts | 18 +++++-- shared/src/store/action-reducers/transfer.ts | 52 ++++++++++++------- shared/src/store/action-reducers/vehicle.ts | 13 +++-- 10 files changed, 93 insertions(+), 66 deletions(-) diff --git a/frontend/src/app/pages/exercises/exercise/shared/core/statistics/statistics.service.ts b/frontend/src/app/pages/exercises/exercise/shared/core/statistics/statistics.service.ts index ebbfdb9bf..63ae552f0 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/core/statistics/statistics.service.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/core/statistics/statistics.service.ts @@ -7,6 +7,7 @@ import { loopTroughTime, uuid, Viewport, + isNotInTransfer, } from 'digital-fuesim-manv-shared'; import type { Personnel, @@ -161,7 +162,7 @@ export class StatisticsService { personnel.filter( (_personnel) => isNotInVehicle(_personnel) && - _personnel.transfer === undefined + isNotInTransfer(_personnel) ), (_personnel) => _personnel.personnelType ), diff --git a/frontend/src/app/state/application/selectors/exercise.selectors.ts b/frontend/src/app/state/application/selectors/exercise.selectors.ts index b089de84b..2feac5162 100644 --- a/frontend/src/app/state/application/selectors/exercise.selectors.ts +++ b/frontend/src/app/state/application/selectors/exercise.selectors.ts @@ -6,7 +6,7 @@ import type { UUID, Vehicle, } from 'digital-fuesim-manv-shared'; -import { coordinatesOf } from 'digital-fuesim-manv-shared'; +import { isInTransfer, coordinatesOf } from 'digital-fuesim-manv-shared'; import type { TransferLine } from 'src/app/shared/types/transfer-line'; import type { AppState } from '../../app.state'; @@ -162,15 +162,15 @@ export function createSelectReachableHospitals(transferPointId: UUID) { export const selectVehiclesInTransfer = createSelector( selectVehicles, (vehicles) => - Object.values(vehicles).filter( - (vehicle) => vehicle.transfer !== undefined + Object.values(vehicles).filter((vehicle) => + isInTransfer(vehicle) ) as (Vehicle & { transfer: Transfer })[] ); export const selectPersonnelInTransfer = createSelector( selectPersonnel, (personnel) => - Object.values(personnel).filter( - (_personnel) => _personnel.transfer !== undefined + Object.values(personnel).filter((_personnel) => + isInTransfer(_personnel) ) as (Personnel & { transfer: Transfer })[] ); diff --git a/shared/src/models/patient.ts b/shared/src/models/patient.ts index e41f22f05..3e1ec395a 100644 --- a/shared/src/models/patient.ts +++ b/shared/src/models/patient.ts @@ -2,7 +2,6 @@ import { Type } from 'class-transformer'; import { IsUUID, ValidateNested, - IsOptional, IsNumber, Max, Min, @@ -75,10 +74,6 @@ export class Patient { @ValidateNested() public readonly position: Position; - @IsUUID(4, uuidValidationOptions) - @IsOptional() - public readonly vehicleId?: UUID; - /** * The time the patient already is in the current state */ diff --git a/shared/src/models/personnel.ts b/shared/src/models/personnel.ts index eef6a561a..9452e2cb2 100644 --- a/shared/src/models/personnel.ts +++ b/shared/src/models/personnel.ts @@ -6,7 +6,6 @@ import { IsNumber, Min, Max, - IsOptional, } from 'class-validator'; import { maxTreatmentRange } from '../state-helpers/max-treatment-range'; import { uuidValidationOptions, UUID, uuid, UUIDSet } from '../utils'; @@ -17,7 +16,6 @@ import { PersonnelType, CanCaterFor, ImageProperties, - Transfer, getCreate, } from './utils'; import { Position } from './utils/position/position'; @@ -74,15 +72,6 @@ export class Personnel { @ValidateNested() public readonly position: Position; - /** - * * @deprecated use {@link position} - * If undefined, the personnel is either in the vehicle with {@link this.vehicleId} or has a {@link position}. - */ - @ValidateNested() - @Type(() => Transfer) - @IsOptional() - public readonly transfer?: Transfer; - /** * @deprecated Use {@link create} instead */ diff --git a/shared/src/models/vehicle.ts b/shared/src/models/vehicle.ts index e00465950..dfb2a5053 100644 --- a/shared/src/models/vehicle.ts +++ b/shared/src/models/vehicle.ts @@ -1,15 +1,9 @@ import { Type } from 'class-transformer'; -import { - IsNumber, - IsOptional, - IsString, - IsUUID, - ValidateNested, -} from 'class-validator'; +import { IsNumber, IsString, IsUUID, ValidateNested } from 'class-validator'; import { uuid, uuidValidationOptions, UUID, UUIDSet } from '../utils'; import { IsUUIDSet, IsValue } from '../utils/validators'; import { IsPosition } from '../utils/validators/is-position'; -import { getCreate, Transfer } from './utils'; +import { getCreate } from './utils'; import { ImageProperties } from './utils/image-properties'; import { Position } from './utils/position/position'; @@ -40,11 +34,6 @@ export class Vehicle { @Type(() => ImageProperties) public readonly image: ImageProperties; - @ValidateNested() - @Type(() => Transfer) - @IsOptional() - public readonly transfer?: Transfer; - @IsUUIDSet() public readonly personnelIds: UUIDSet = {}; diff --git a/shared/src/state-migrations/18-replace-position-with-meta-position.ts b/shared/src/state-migrations/18-replace-position-with-meta-position.ts index cabdb428c..06359de7c 100644 --- a/shared/src/state-migrations/18-replace-position-with-meta-position.ts +++ b/shared/src/state-migrations/18-replace-position-with-meta-position.ts @@ -183,6 +183,8 @@ export const replacePositionWithMetaPosition18: Migration = { const typedState = state as { patients: { [patientId: UUID]: { + vehicleId?: any; + transfer?: any; metaPosition?: | any | { type: 'coordinates'; position: any } @@ -201,6 +203,7 @@ export const replacePositionWithMetaPosition18: Migration = { }; vehicles: { [vehicleId: UUID]: { + transfer?: any; metaPosition?: | any | { type: 'coordinates'; position: any } @@ -210,6 +213,7 @@ export const replacePositionWithMetaPosition18: Migration = { }; personnel: { [personnelId: UUID]: { + transfer?: any; metaPosition?: | any | { type: 'coordinates'; position: any } @@ -260,6 +264,8 @@ export const replacePositionWithMetaPosition18: Migration = { }; Object.values(typedState.patients).forEach((patient) => { + delete patient.transfer; + delete patient.vehicleId; if (patient.metaPosition?.type === 'coordinates') { patient.metaPosition.coordinates = patient.metaPosition.position; @@ -283,6 +289,7 @@ export const replacePositionWithMetaPosition18: Migration = { }); Object.values(typedState.vehicles).forEach((vehicle) => { + delete vehicle.transfer; if (vehicle.metaPosition?.type === 'coordinates') { vehicle.metaPosition.coordinates = vehicle.metaPosition.position; @@ -293,6 +300,7 @@ export const replacePositionWithMetaPosition18: Migration = { }); Object.values(typedState.personnel).forEach((personnel) => { + delete personnel.transfer; if (personnel.metaPosition?.type === 'coordinates') { personnel.metaPosition.coordinates = personnel.metaPosition.position; diff --git a/shared/src/store/action-reducers/exercise.ts b/shared/src/store/action-reducers/exercise.ts index 1fd29a514..3e6327afc 100644 --- a/shared/src/store/action-reducers/exercise.ts +++ b/shared/src/store/action-reducers/exercise.ts @@ -8,9 +8,16 @@ import { } from 'class-validator'; import type { Personnel, Vehicle } from '../../models'; import { Patient } from '../../models'; -import { getStatus } from '../../models/utils'; +import { + getStatus, + isNotInTransfer, + transferItsIn, + TransferPosition, +} from '../../models/utils'; +import { changePosition } from '../../models/utils/position/position-helpers-mutable'; import type { ExerciseState } from '../../state'; import type { Mutable } from '../../utils'; +import { cloneDeepMutable } from '../../utils'; import type { ElementTypePluralMap } from '../../utils/element-type-plural-map'; import { elementTypePluralMap } from '../../utils/element-type-plural-map'; import { IsValue } from '../../utils/validators'; @@ -145,15 +152,22 @@ function refreshTransfer( ): void { const elements = draftState[elementTypePluralMap[type]]; Object.values(elements).forEach((element: Mutable) => { - if (!element.transfer) { + if (isNotInTransfer(element)) { return; } - if (element.transfer.isPaused) { - element.transfer.endTimeStamp += tickInterval; + if (transferItsIn(element).isPaused) { + const newTransfer = cloneDeepMutable(transferItsIn(element)); + newTransfer.endTimeStamp += tickInterval; + changePosition( + element, + TransferPosition.create(newTransfer), + false, + draftState + ); return; } // Not transferred yet - if (element.transfer.endTimeStamp > draftState.currentTime) { + if (transferItsIn(element).endTimeStamp > draftState.currentTime) { return; } letElementArrive(draftState, type, element.id); diff --git a/shared/src/store/action-reducers/transfer-point.ts b/shared/src/store/action-reducers/transfer-point.ts index de51668e5..2145a0a68 100644 --- a/shared/src/store/action-reducers/transfer-point.ts +++ b/shared/src/store/action-reducers/transfer-point.ts @@ -7,7 +7,13 @@ import { ValidateNested, } from 'class-validator'; import { TransferPoint } from '../../models'; -import { coordinatesOf, MapCoordinates, MapPosition } from '../../models/utils'; +import { + coordinatesOf, + isInTransfer, + MapCoordinates, + MapPosition, + transferItsIn, +} from '../../models/utils'; import { changePositionWithId } from '../../models/utils/position/position-helpers-mutable'; import { cloneDeepMutable, UUID, uuidValidationOptions } from '../../utils'; import { IsValue } from '../../utils/validators'; @@ -241,8 +247,9 @@ export namespace TransferPointActionReducers { vehicleId ); if ( - vehicle.transfer?.targetTransferPointId === - transferPointId + isInTransfer(vehicle) && + transferItsIn(vehicle).targetTransferPointId === + transferPointId ) { letElementArrive(draftState, vehicle.type, vehicleId); } @@ -254,8 +261,9 @@ export namespace TransferPointActionReducers { personnelId ); if ( - personnel.transfer?.targetTransferPointId === - transferPointId + isInTransfer(personnel) && + transferItsIn(personnel).targetTransferPointId === + transferPointId ) { letElementArrive( draftState, diff --git a/shared/src/store/action-reducers/transfer.ts b/shared/src/store/action-reducers/transfer.ts index 5ee99ee0b..e357340ef 100644 --- a/shared/src/store/action-reducers/transfer.ts +++ b/shared/src/store/action-reducers/transfer.ts @@ -3,6 +3,9 @@ import { IsInt, IsOptional, IsUUID, ValidateNested } from 'class-validator'; import { TransferPoint } from '../../models'; import type { MapCoordinates } from '../../models/utils'; import { + isInTransfer, + isNotInTransfer, + transferItsIn, TransferPosition, coordinatesOf, MapPosition, @@ -36,13 +39,13 @@ export function letElementArrive( ) { const element = getElement(draftState, elementType, elementId); // check that element is in transfer, this should be always the case where this function is used - if (!element.transfer) { + if (isInTransfer(element)) { throw getNotInTransferError(element.id); } const targetTransferPoint = getElement( draftState, 'transferPoint', - element.transfer.targetTransferPointId + transferItsIn(element).targetTransferPointId ); const newPosition: Mutable = { x: coordinatesOf(targetTransferPoint).x, @@ -57,7 +60,6 @@ export function letElementArrive( elementType === 'personnel' ? elementType : false, draftState ); - delete element.transfer; } export class AddToTransferAction implements Action { @@ -137,7 +139,7 @@ export namespace TransferActionReducers { // check if transferPoint exists getElement(draftState, 'transferPoint', targetTransferPointId); const element = getElement(draftState, elementType, elementId); - if (element.transfer) { + if (isInTransfer(element)) { throw new ReducerError( `Element with id ${element.id} is already in transfer` ); @@ -166,15 +168,14 @@ export namespace TransferActionReducers { } // Set the element to transfer - element.transfer = { - startPoint: cloneDeepMutable(startPoint), - targetTransferPointId, - endTimeStamp: draftState.currentTime + duration, - isPaused: false, - }; changePosition( element, - TransferPosition.create(element.transfer), + TransferPosition.create({ + startPoint: cloneDeepMutable(startPoint), + targetTransferPointId, + endTimeStamp: draftState.currentTime + duration, + isPaused: false, + }), elementType === 'personnel' ? elementType : false, draftState ); @@ -191,21 +192,29 @@ export namespace TransferActionReducers { { elementType, elementId, targetTransferPointId, timeToAdd } ) => { const element = getElement(draftState, elementType, elementId); - if (!element.transfer) { + if (isNotInTransfer(element)) { throw getNotInTransferError(element.id); } + const newTransfer = cloneDeepMutable(transferItsIn(element)); if (targetTransferPointId) { // check if transferPoint exists + getElement(draftState, 'transferPoint', targetTransferPointId); - element.transfer.targetTransferPointId = targetTransferPointId; + newTransfer.targetTransferPointId = targetTransferPointId; } if (timeToAdd) { // The endTimeStamp shouldn't be less then the current time - element.transfer.endTimeStamp = Math.max( + newTransfer.endTimeStamp = Math.max( draftState.currentTime, - element.transfer.endTimeStamp + timeToAdd + newTransfer.endTimeStamp + timeToAdd ); } + changePosition( + element, + TransferPosition.create(newTransfer), + false, + draftState + ); return draftState; }, rights: 'trainer', @@ -220,7 +229,7 @@ export namespace TransferActionReducers { // check if transferPoint exists getElement(draftState, 'transferPoint', targetTransferPointId); const element = getElement(draftState, elementType, elementId); - if (!element.transfer) { + if (isNotInTransfer(element)) { throw getNotInTransferError(element.id); } letElementArrive(draftState, elementType, elementId); @@ -234,10 +243,17 @@ export namespace TransferActionReducers { action: TogglePauseTransferAction, reducer: (draftState, { elementType, elementId }) => { const element = getElement(draftState, elementType, elementId); - if (!element.transfer) { + if (isNotInTransfer(element)) { throw getNotInTransferError(element.id); } - element.transfer.isPaused = !element.transfer.isPaused; + const newTransfer = cloneDeepMutable(transferItsIn(element)); + newTransfer.isPaused = !newTransfer.isPaused; + changePosition( + element, + TransferPosition.create(newTransfer), + false, + draftState + ); return draftState; }, rights: 'trainer', diff --git a/shared/src/store/action-reducers/vehicle.ts b/shared/src/store/action-reducers/vehicle.ts index 3c051253e..ca5306149 100644 --- a/shared/src/store/action-reducers/vehicle.ts +++ b/shared/src/store/action-reducers/vehicle.ts @@ -3,7 +3,9 @@ import { IsArray, IsString, IsUUID, ValidateNested } from 'class-validator'; import { Material, Personnel, Vehicle } from '../../models'; import { coordinatesOf, + isInTransfer, isInVehicle, + isNotInTransfer, isNotOnMap, MapCoordinates, MapPosition, @@ -330,7 +332,7 @@ export namespace VehicleActionReducers { 'personnel', elementToBeLoadedId ); - if (personnel.transfer !== undefined) { + if (isInTransfer(personnel)) { throw new ReducerError( `Personnel with id ${elementToBeLoadedId} is currently in transfer` ); @@ -384,8 +386,13 @@ export namespace VehicleActionReducers { .filter( // Skip personnel currently in transfer (personnelId) => - getElement(draftState, 'personnel', personnelId) - .transfer === undefined + isNotInTransfer( + getElement( + draftState, + 'personnel', + personnelId + ) + ) ) .forEach((personnelId) => { changePosition( From cf8ac25b4b60e193cb565161c7f566934b8aeb79 Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Mon, 30 Jan 2023 20:14:17 +0100 Subject: [PATCH 13/22] Add Migration for Add Vehicle Action --- .../src/models/utils/position/map-position.ts | 4 +- .../position/position-helpers-mutable.ts | 2 - .../models/utils/position/position-helpers.ts | 6 +- .../state-migrations/16-add-meta-position.ts | 57 +++++++++++++++++++ .../18-replace-position-with-meta-position.ts | 44 +++++++++++--- shared/src/store/action-reducers/transfer.ts | 1 + .../utils/calculate-treatments.spec.ts | 1 - 7 files changed, 100 insertions(+), 15 deletions(-) diff --git a/shared/src/models/utils/position/map-position.ts b/shared/src/models/utils/position/map-position.ts index 07a4cc82b..5751316da 100644 --- a/shared/src/models/utils/position/map-position.ts +++ b/shared/src/models/utils/position/map-position.ts @@ -18,13 +18,13 @@ export class MapPosition { */ @Type(() => MapCoordinates) @ValidateNested() - public readonly position: MapCoordinates; + public readonly coordinates: MapCoordinates; /** * @deprecated Use {@link create} instead */ constructor(position: MapCoordinates) { - this.position = position; + this.coordinates = position; } static readonly create = getCreate(this); diff --git a/shared/src/models/utils/position/position-helpers-mutable.ts b/shared/src/models/utils/position/position-helpers-mutable.ts index aad920ea6..9df1c5c85 100644 --- a/shared/src/models/utils/position/position-helpers-mutable.ts +++ b/shared/src/models/utils/position/position-helpers-mutable.ts @@ -80,8 +80,6 @@ function updateSpatialElementTree( type: SpatialElementType, state: Mutable ) { - console.log(type); - if (isOnMap(element) && isPositionOnMap(to)) { updateElementPosition( state, diff --git a/shared/src/models/utils/position/position-helpers.ts b/shared/src/models/utils/position/position-helpers.ts index 66e9ad261..054aaa256 100644 --- a/shared/src/models/utils/position/position-helpers.ts +++ b/shared/src/models/utils/position/position-helpers.ts @@ -27,7 +27,7 @@ export function isNotInVehicle(withPosition: WithPosition): boolean { return !isInVehicle(withPosition); } export function isNotInTransfer(withPosition: WithPosition): boolean { - return !isInVehicle(withPosition); + return !isInTransfer(withPosition); } export function isNotInSimulatedRegion(withPosition: WithPosition): boolean { return !isInSimulatedRegion(withPosition); @@ -35,7 +35,7 @@ export function isNotInSimulatedRegion(withPosition: WithPosition): boolean { export function coordinatesOf(withPosition: WithPosition): MapCoordinates { if (isOnMap(withPosition)) { - return (withPosition.position as MapPosition).position; + return (withPosition.position as MapPosition).coordinates; } throw new TypeError( `Expected position of object to be on Map. Was of type ${withPosition.position.type}.` @@ -97,7 +97,7 @@ export function isPositionNotInSimulatedRegion(position: Position): boolean { export function coordinatesOfPosition(position: Position): MapCoordinates { if (isPositionOnMap(position)) { - return (position as MapPosition).position; + return (position as MapPosition).coordinates; } throw new TypeError( `Expected position of object to be on Map. Was of type ${position.type}.` diff --git a/shared/src/state-migrations/16-add-meta-position.ts b/shared/src/state-migrations/16-add-meta-position.ts index bca88a103..344228c2d 100644 --- a/shared/src/state-migrations/16-add-meta-position.ts +++ b/shared/src/state-migrations/16-add-meta-position.ts @@ -40,6 +40,17 @@ export const addMetaPosition16: Migration = { transfer?: any; metaPosition?: any; }; + materials: { + position?: { x: number; y: number }; + vehicleId?: UUID; + metaPosition?: any; + }[]; + personnel: { + position?: { x: number; y: number }; + transfer?: any; + vehicleId?: UUID; + metaPosition?: any; + }[]; }; if (typedAction.vehicle.position) { typedAction.vehicle.metaPosition = { @@ -54,6 +65,52 @@ export const addMetaPosition16: Migration = { type: 'transfer', transfer: typedAction.vehicle.transfer, }; + } else { + typedAction.vehicle.metaPosition = { + type: 'coordinates', + position: { + x: 0, + y: 0, + }, + }; + } + for (const personnel of typedAction.personnel) { + if (personnel.position) { + personnel.metaPosition = { + type: 'coordinates', + position: { + x: personnel.position.x, + y: personnel.position.y, + }, + }; + } else if (personnel.transfer) { + personnel.metaPosition = { + type: 'transfer', + transfer: personnel.transfer, + }; + } else if (personnel.vehicleId) { + personnel.metaPosition = { + type: 'vehicle', + vehicleId: personnel.vehicleId, + }; + } + } + + for (const material of typedAction.materials) { + if (material.position) { + material.metaPosition = { + type: 'coordinates', + position: { + x: material.position.x, + y: material.position.y, + }, + }; + } else if (material.vehicleId) { + material.metaPosition = { + type: 'vehicle', + vehicleId: material.vehicleId, + }; + } } } }); diff --git a/shared/src/state-migrations/18-replace-position-with-meta-position.ts b/shared/src/state-migrations/18-replace-position-with-meta-position.ts index 06359de7c..df30f0ea4 100644 --- a/shared/src/state-migrations/18-replace-position-with-meta-position.ts +++ b/shared/src/state-migrations/18-replace-position-with-meta-position.ts @@ -3,7 +3,6 @@ import type { Migration } from './migration-functions'; export const replacePositionWithMetaPosition18: Migration = { actions: (_initialState, actions) => { - console.log('Start Action Migration'); actions.forEach((action) => { if ( (action as { type: string } | null)?.type === @@ -38,7 +37,43 @@ export const replacePositionWithMetaPosition18: Migration = { | { type: any }; position: any; }; + materials: { + metaPosition?: + | any + | { type: 'coordinates'; position: any } + | { type: any }; + position: any; + }[]; + personnel: { + transfer?: any; + metaPosition?: + | any + | { type: 'coordinates'; position: any } + | { type: any }; + position: any; + }[]; }; + for (const material of typedAction.materials) { + if (material.metaPosition?.type === 'coordinates') { + material.metaPosition.coordinates = + material.metaPosition.position; + delete material.metaPosition.position; + } + material.position = material.metaPosition; + delete material.metaPosition; + } + + for (const personnel of typedAction.personnel) { + delete personnel.transfer; + if (personnel.metaPosition?.type === 'coordinates') { + personnel.metaPosition.coordinates = + personnel.metaPosition.position; + delete personnel.metaPosition.position; + } + personnel.position = personnel.metaPosition; + delete personnel.metaPosition; + } + if (typedAction.vehicle.metaPosition?.type === 'coordinates') { typedAction.vehicle.metaPosition.coordinates = typedAction.vehicle.metaPosition.position; @@ -176,10 +211,8 @@ export const replacePositionWithMetaPosition18: Migration = { }; } }); - console.log('End Action Migration'); }, state: (state) => { - console.log('Start State Migration'); const typedState = state as { patients: { [patientId: UUID]: { @@ -276,9 +309,6 @@ export const replacePositionWithMetaPosition18: Migration = { }); Object.values(typedState.materials).forEach((material) => { - if (material.metaPosition.type === undefined) { - console.log('ALARMMMMM'); - } if (material.metaPosition?.type === 'coordinates') { material.metaPosition.coordinates = material.metaPosition.position; @@ -290,6 +320,7 @@ export const replacePositionWithMetaPosition18: Migration = { Object.values(typedState.vehicles).forEach((vehicle) => { delete vehicle.transfer; + if (vehicle.metaPosition?.type === 'coordinates') { vehicle.metaPosition.coordinates = vehicle.metaPosition.position; @@ -351,6 +382,5 @@ export const replacePositionWithMetaPosition18: Migration = { }, }; }); - console.log('End State Migration'); }, }; diff --git a/shared/src/store/action-reducers/transfer.ts b/shared/src/store/action-reducers/transfer.ts index e357340ef..3465398d8 100644 --- a/shared/src/store/action-reducers/transfer.ts +++ b/shared/src/store/action-reducers/transfer.ts @@ -139,6 +139,7 @@ export namespace TransferActionReducers { // check if transferPoint exists getElement(draftState, 'transferPoint', targetTransferPointId); const element = getElement(draftState, elementType, elementId); + if (isInTransfer(element)) { throw new ReducerError( `Element with id ${element.id} is already in transfer` diff --git a/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts b/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts index d7f50e76f..25fffb9a8 100644 --- a/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts +++ b/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts @@ -336,7 +336,6 @@ describe('calculate treatment', () => { ).id; } ); - console.log(ids); assertCatering(beforeState, newState, [ { catererId: ids.material, From e587c7e20aa2421fc5824f1d623294d57e9bb491 Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Mon, 30 Jan 2023 20:19:47 +0100 Subject: [PATCH 14/22] Fix Small Bug --- shared/src/store/action-reducers/transfer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/src/store/action-reducers/transfer.ts b/shared/src/store/action-reducers/transfer.ts index 3465398d8..95afb34c8 100644 --- a/shared/src/store/action-reducers/transfer.ts +++ b/shared/src/store/action-reducers/transfer.ts @@ -39,7 +39,7 @@ export function letElementArrive( ) { const element = getElement(draftState, elementType, elementId); // check that element is in transfer, this should be always the case where this function is used - if (isInTransfer(element)) { + if (isNotInTransfer(element)) { throw getNotInTransferError(element.id); } const targetTransferPoint = getElement( From 277f74c6314b34f6a2463facbf1002a2e6589aec Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Mon, 30 Jan 2023 20:47:35 +0100 Subject: [PATCH 15/22] Use type properties instead of passed strings --- .../position/position-helpers-mutable.ts | 23 ++++++++----------- shared/src/store/action-reducers/exercise.ts | 1 - .../src/store/action-reducers/map-images.ts | 1 - shared/src/store/action-reducers/patient.ts | 7 +----- .../store/action-reducers/simulated-region.ts | 1 - shared/src/store/action-reducers/transfer.ts | 10 +------- shared/src/store/action-reducers/vehicle.ts | 8 ------- shared/src/store/action-reducers/viewport.ts | 1 - 8 files changed, 12 insertions(+), 40 deletions(-) diff --git a/shared/src/models/utils/position/position-helpers-mutable.ts b/shared/src/models/utils/position/position-helpers-mutable.ts index 9df1c5c85..862fa8f22 100644 --- a/shared/src/models/utils/position/position-helpers-mutable.ts +++ b/shared/src/models/utils/position/position-helpers-mutable.ts @@ -21,11 +21,12 @@ type MutablePosition = Mutable; interface WithMutablePosition { position: MutablePosition; + type: MovableType; } interface WithMutablePositionAndId extends WithMutablePosition { id: UUID; } -type ElementType = +type MovableType = | 'alarmGroup' | 'client' | 'hospital' @@ -41,30 +42,26 @@ type ElementType = export function changePositionWithId( of: UUID, to: Position, - type: ElementType, + type: MovableType, inState: Mutable ) { - changePosition( - getElement(inState, type, of) as any, - to, - type === 'personnel' || type === 'material' || type === 'patient' - ? type - : false, - inState - ); + changePosition(getElement(inState, type, of) as any, to, inState); } export function changePosition( of: WithMutablePosition, to: Position, - type: SpatialElementType | false, inState: Mutable ) { - if (type) { + if ( + of.type === 'patient' || + of.type === 'personnel' || + of.type === 'material' + ) { updateSpatialElementTree( of as WithMutablePositionAndId, to, - type, + of.type, inState ); of.position = cloneDeepMutable(to); diff --git a/shared/src/store/action-reducers/exercise.ts b/shared/src/store/action-reducers/exercise.ts index 3e6327afc..1fe506674 100644 --- a/shared/src/store/action-reducers/exercise.ts +++ b/shared/src/store/action-reducers/exercise.ts @@ -161,7 +161,6 @@ function refreshTransfer( changePosition( element, TransferPosition.create(newTransfer), - false, draftState ); return; diff --git a/shared/src/store/action-reducers/map-images.ts b/shared/src/store/action-reducers/map-images.ts index b16e85ec2..d564fbaad 100644 --- a/shared/src/store/action-reducers/map-images.ts +++ b/shared/src/store/action-reducers/map-images.ts @@ -138,7 +138,6 @@ export namespace MapImagesActionReducers { changePosition( mapImage, MapPosition.create(targetPosition), - false, draftState ); return draftState; diff --git a/shared/src/store/action-reducers/patient.ts b/shared/src/store/action-reducers/patient.ts index b85970817..e8df777d5 100644 --- a/shared/src/store/action-reducers/patient.ts +++ b/shared/src/store/action-reducers/patient.ts @@ -122,12 +122,7 @@ export namespace PatientActionReducers { } const mutablePatient = cloneDeepMutable(patient); draftState.patients[mutablePatient.id] = mutablePatient; - changePosition( - mutablePatient, - patient.position, - 'patient', - draftState - ); + changePosition(mutablePatient, patient.position, draftState); return draftState; }, rights: 'trainer', diff --git a/shared/src/store/action-reducers/simulated-region.ts b/shared/src/store/action-reducers/simulated-region.ts index 764c1b870..b36f437f6 100644 --- a/shared/src/store/action-reducers/simulated-region.ts +++ b/shared/src/store/action-reducers/simulated-region.ts @@ -112,7 +112,6 @@ export namespace SimulatedRegionActionReducers { changePosition( simulatedRegion, MapPosition.create(targetPosition), - false, draftState ); simulatedRegion.size = cloneDeepMutable(newSize); diff --git a/shared/src/store/action-reducers/transfer.ts b/shared/src/store/action-reducers/transfer.ts index 95afb34c8..abfabc7a9 100644 --- a/shared/src/store/action-reducers/transfer.ts +++ b/shared/src/store/action-reducers/transfer.ts @@ -54,12 +54,7 @@ export function letElementArrive( // Position it in the upper half of the transferPoint imageSizeToPosition(TransferPoint.image.height / 3), }; - changePosition( - element, - MapPosition.create(newPosition), - elementType === 'personnel' ? elementType : false, - draftState - ); + changePosition(element, MapPosition.create(newPosition), draftState); } export class AddToTransferAction implements Action { @@ -177,7 +172,6 @@ export namespace TransferActionReducers { endTimeStamp: draftState.currentTime + duration, isPaused: false, }), - elementType === 'personnel' ? elementType : false, draftState ); @@ -213,7 +207,6 @@ export namespace TransferActionReducers { changePosition( element, TransferPosition.create(newTransfer), - false, draftState ); return draftState; @@ -252,7 +245,6 @@ export namespace TransferActionReducers { changePosition( element, TransferPosition.create(newTransfer), - false, draftState ); return draftState; diff --git a/shared/src/store/action-reducers/vehicle.ts b/shared/src/store/action-reducers/vehicle.ts index ca5306149..870b6caa9 100644 --- a/shared/src/store/action-reducers/vehicle.ts +++ b/shared/src/store/action-reducers/vehicle.ts @@ -162,7 +162,6 @@ export namespace VehicleActionReducers { changePosition( material, VehiclePosition.create(vehicle.id), - 'material', draftState ); draftState.materials[material.id] = material; @@ -171,7 +170,6 @@ export namespace VehicleActionReducers { changePosition( person, VehiclePosition.create(vehicle.id), - 'personnel', draftState ); draftState.personnel[person.id] = person; @@ -288,7 +286,6 @@ export namespace VehicleActionReducers { MapPosition.create( MapCoordinates.create(x, unloadPosition.y) ), - 'material', draftState ); } @@ -321,7 +318,6 @@ export namespace VehicleActionReducers { changePosition( material, VehiclePosition.create(vehicleId), - 'material', draftState ); break; @@ -345,7 +341,6 @@ export namespace VehicleActionReducers { changePosition( personnel, VehiclePosition.create(vehicleId), - 'personnel', draftState ); break; @@ -368,7 +363,6 @@ export namespace VehicleActionReducers { changePosition( patient, VehiclePosition.create(vehicleId), - 'patient', draftState ); // Load in all materials @@ -376,7 +370,6 @@ export namespace VehicleActionReducers { changePosition( getElement(draftState, 'material', materialId), VehiclePosition.create(vehicleId), - 'material', draftState ); }); @@ -402,7 +395,6 @@ export namespace VehicleActionReducers { personnelId ), VehiclePosition.create(vehicleId), - 'personnel', draftState ); }); diff --git a/shared/src/store/action-reducers/viewport.ts b/shared/src/store/action-reducers/viewport.ts index 4facbb1a7..3719ab8a1 100644 --- a/shared/src/store/action-reducers/viewport.ts +++ b/shared/src/store/action-reducers/viewport.ts @@ -101,7 +101,6 @@ export namespace ViewportActionReducers { changePosition( viewport, MapPosition.create(targetPosition), - false, draftState ); viewport.size = cloneDeepMutable(newSize); From 64f2e0c4ae1d72dd9c682effecdeac25e0f1639e Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Mon, 30 Jan 2023 20:55:46 +0100 Subject: [PATCH 16/22] Add comments --- shared/src/models/map-image.ts | 3 +++ shared/src/models/material.ts | 3 +++ shared/src/models/patient.ts | 3 +++ shared/src/models/personnel.ts | 3 +++ shared/src/models/simulated-region.ts | 4 +++- shared/src/models/transfer-point.ts | 3 +++ shared/src/models/utils/index.ts | 2 +- shared/src/models/utils/position/position-helpers.ts | 2 +- .../position/{with-meta-position.ts => with-position.ts} | 0 shared/src/models/vehicle.ts | 3 +++ shared/src/models/viewport.ts | 2 ++ 11 files changed, 25 insertions(+), 3 deletions(-) rename shared/src/models/utils/position/{with-meta-position.ts => with-position.ts} (100%) diff --git a/shared/src/models/map-image.ts b/shared/src/models/map-image.ts index 62da92697..9d8f158a5 100644 --- a/shared/src/models/map-image.ts +++ b/shared/src/models/map-image.ts @@ -13,6 +13,9 @@ export class MapImage { @IsValue('mapImage' as const) public readonly type = 'mapImage'; + /** + * @deprecated Do not access directly, use helper methods from models/utils/position/position-helpers(-mutable) instead. + */ @ValidateNested() @IsPosition() public readonly position: Position; diff --git a/shared/src/models/material.ts b/shared/src/models/material.ts index 5b746bc14..0df36780c 100644 --- a/shared/src/models/material.ts +++ b/shared/src/models/material.ts @@ -55,6 +55,9 @@ export class Material { @Max(maxTreatmentRange) public readonly treatmentRange: number; + /** + * @deprecated Do not access directly, use helper methods from models/utils/position/position-helpers(-mutable) instead. + */ @IsPosition() @ValidateNested() public readonly position: Position; diff --git a/shared/src/models/patient.ts b/shared/src/models/patient.ts index 3e1ec395a..a8f015149 100644 --- a/shared/src/models/patient.ts +++ b/shared/src/models/patient.ts @@ -70,6 +70,9 @@ export class Patient { @Type(() => ImageProperties) public readonly image: ImageProperties; + /** + * @deprecated Do not access directly, use helper methods from models/utils/position/position-helpers(-mutable) instead. + */ @IsPosition() @ValidateNested() public readonly position: Position; diff --git a/shared/src/models/personnel.ts b/shared/src/models/personnel.ts index 9452e2cb2..7e5d55bd7 100644 --- a/shared/src/models/personnel.ts +++ b/shared/src/models/personnel.ts @@ -68,6 +68,9 @@ export class Personnel { @Type(() => ImageProperties) public readonly image: ImageProperties; + /** + * @deprecated Do not access directly, use helper methods from models/utils/position/position-helpers(-mutable) instead. + */ @IsPosition() @ValidateNested() public readonly position: Position; diff --git a/shared/src/models/simulated-region.ts b/shared/src/models/simulated-region.ts index e65e371c4..41ccdc14d 100644 --- a/shared/src/models/simulated-region.ts +++ b/shared/src/models/simulated-region.ts @@ -12,7 +12,7 @@ import { Size, } from './utils'; import type { ImageProperties, MapCoordinates } from './utils'; -import type { WithPosition } from './utils/position/with-meta-position'; +import type { WithPosition } from './utils/position/with-position'; export class SimulatedRegion { @IsUUID(4, uuidValidationOptions) @@ -23,6 +23,8 @@ export class SimulatedRegion { /** * top-left position + * + * @deprecated Do not access directly, use helper methods from models/utils/position/position-helpers(-mutable) instead. */ @ValidateNested() @IsPosition() diff --git a/shared/src/models/transfer-point.ts b/shared/src/models/transfer-point.ts index 72885fd26..3691a5cac 100644 --- a/shared/src/models/transfer-point.ts +++ b/shared/src/models/transfer-point.ts @@ -16,6 +16,9 @@ export class TransferPoint { @IsValue('transferPoint' as const) public readonly type = 'transferPoint'; + /** + * @deprecated Do not access directly, use helper methods from models/utils/position/position-helpers(-mutable) instead. + */ @ValidateNested() @IsPosition() public readonly position: Position; diff --git a/shared/src/models/utils/index.ts b/shared/src/models/utils/index.ts index afdb7b3cd..7199bde54 100644 --- a/shared/src/models/utils/index.ts +++ b/shared/src/models/utils/index.ts @@ -1,5 +1,5 @@ export { Position } from './position/position'; -export { WithPosition } from './position/with-meta-position'; +export { WithPosition } from './position/with-position'; export { MapPosition } from './position/map-position'; export { VehiclePosition } from './position/vehicle-position'; export { TransferPosition } from './position/transfer-position'; diff --git a/shared/src/models/utils/position/position-helpers.ts b/shared/src/models/utils/position/position-helpers.ts index 054aaa256..c64db08e5 100644 --- a/shared/src/models/utils/position/position-helpers.ts +++ b/shared/src/models/utils/position/position-helpers.ts @@ -6,7 +6,7 @@ import type { Position } from './position'; import type { SimulatedRegionPosition } from './simulated-region-position'; import type { TransferPosition } from './transfer-position'; import type { VehiclePosition } from './vehicle-position'; -import type { WithPosition } from './with-meta-position'; +import type { WithPosition } from './with-position'; export function isOnMap(withPosition: WithPosition): boolean { return withPosition.position.type === 'coordinates'; diff --git a/shared/src/models/utils/position/with-meta-position.ts b/shared/src/models/utils/position/with-position.ts similarity index 100% rename from shared/src/models/utils/position/with-meta-position.ts rename to shared/src/models/utils/position/with-position.ts diff --git a/shared/src/models/vehicle.ts b/shared/src/models/vehicle.ts index dfb2a5053..cdc6fba41 100644 --- a/shared/src/models/vehicle.ts +++ b/shared/src/models/vehicle.ts @@ -26,6 +26,9 @@ export class Vehicle { @IsNumber() public readonly patientCapacity: number; + /** + * @deprecated Do not access directly, use helper methods from models/utils/position/position-helpers(-mutable) instead. + */ @IsPosition() @ValidateNested() public readonly position: Position; diff --git a/shared/src/models/viewport.ts b/shared/src/models/viewport.ts index 2266f0d3c..47c481d77 100644 --- a/shared/src/models/viewport.ts +++ b/shared/src/models/viewport.ts @@ -15,6 +15,8 @@ export class Viewport { /** * top-left position + * + * @deprecated Do not access directly, use helper methods from models/utils/position/position-helpers(-mutable) instead. */ @ValidateNested() @IsPosition() From 2dfaf0bd44b4d52ade846fa321c0589f5ebe7693 Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Mon, 30 Jan 2023 21:04:08 +0100 Subject: [PATCH 17/22] Fix Test --- shared/src/store/validate-exercise-action.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/src/store/validate-exercise-action.spec.ts b/shared/src/store/validate-exercise-action.spec.ts index 81dbf84e7..f5486b287 100644 --- a/shared/src/store/validate-exercise-action.spec.ts +++ b/shared/src/store/validate-exercise-action.spec.ts @@ -79,7 +79,7 @@ describe('validateExerciseAction', () => { }, position: { type: 'coordinates', - position: { + coordinates: { // this is of type string instead of number x: '0' as unknown as number, y: 0, @@ -124,7 +124,7 @@ describe('validateExerciseAction', () => { }, position: { type: 'coordinates', - position: { + coordinates: { x: 0, y: 0, z: 0, From 86210e126c83cd7806b1843b2f9a4df12c38d165 Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Mon, 30 Jan 2023 21:04:44 +0100 Subject: [PATCH 18/22] Fix Test --- .../store/action-reducers/utils/calculate-treatments.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts b/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts index 25fffb9a8..2e9b1182f 100644 --- a/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts +++ b/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts @@ -84,7 +84,7 @@ function addPatient( if (position) { patient.position = { type: 'coordinates', - position: cloneDeepMutable(position), + coordinates: cloneDeepMutable(position), }; SpatialTree.addElement( state.spatialTrees.patients, From ffee6e1a332f78b1ea5a32964db7eebf1c62a772 Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Mon, 30 Jan 2023 21:50:03 +0100 Subject: [PATCH 19/22] Fix Transfer Overview --- .../transfer-overview-table.component.html | 13 +++++++------ .../transfer-overview-table.component.ts | 3 +++ .../application/selectors/exercise.selectors.ts | 5 ++--- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/frontend/src/app/pages/exercises/exercise/shared/transfer-overview/transfer-overview-table/transfer-overview-table.component.html b/frontend/src/app/pages/exercises/exercise/shared/transfer-overview/transfer-overview-table/transfer-overview-table.component.html index 4d592c856..bd76dd228 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/transfer-overview/transfer-overview-table/transfer-overview-table.component.html +++ b/frontend/src/app/pages/exercises/exercise/shared/transfer-overview/transfer-overview-table/transfer-overview-table.component.html @@ -1,3 +1,4 @@ + @@ -37,21 +38,21 @@ @@ -71,21 +72,21 @@ diff --git a/frontend/src/app/pages/exercises/exercise/shared/transfer-overview/transfer-overview-table/transfer-overview-table.component.ts b/frontend/src/app/pages/exercises/exercise/shared/transfer-overview/transfer-overview-table/transfer-overview-table.component.ts index 35fdd6a1a..b24199a36 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/transfer-overview/transfer-overview-table/transfer-overview-table.component.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/transfer-overview/transfer-overview-table/transfer-overview-table.component.ts @@ -1,5 +1,6 @@ import { Component } from '@angular/core'; import { Store } from '@ngrx/store'; +import { transferItsIn } from 'digital-fuesim-manv-shared'; import type { AppState } from 'src/app/state/app.state'; import { selectExerciseStatus, @@ -20,6 +21,8 @@ export class TransferOverviewTableComponent { selectPersonnelInTransfer ); + public transferItsIn = transferItsIn; + public readonly exerciseStatus$ = this.store.select(selectExerciseStatus); constructor(private readonly store: Store) {} diff --git a/frontend/src/app/state/application/selectors/exercise.selectors.ts b/frontend/src/app/state/application/selectors/exercise.selectors.ts index 2feac5162..8a8aca370 100644 --- a/frontend/src/app/state/application/selectors/exercise.selectors.ts +++ b/frontend/src/app/state/application/selectors/exercise.selectors.ts @@ -2,7 +2,6 @@ import { createSelector } from '@ngrx/store'; import type { ExerciseState, Personnel, - Transfer, UUID, Vehicle, } from 'digital-fuesim-manv-shared'; @@ -164,7 +163,7 @@ export const selectVehiclesInTransfer = createSelector( (vehicles) => Object.values(vehicles).filter((vehicle) => isInTransfer(vehicle) - ) as (Vehicle & { transfer: Transfer })[] + ) as Vehicle[] ); export const selectPersonnelInTransfer = createSelector( @@ -172,5 +171,5 @@ export const selectPersonnelInTransfer = createSelector( (personnel) => Object.values(personnel).filter((_personnel) => isInTransfer(_personnel) - ) as (Personnel & { transfer: Transfer })[] + ) as Personnel[] ); From 9a9019bb4d3eabb50bfd80c32220364e14aa3ec7 Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Tue, 31 Jan 2023 15:34:17 +0100 Subject: [PATCH 20/22] Refactor Helper Methods to avoid duplicate Code --- .../models/utils/position/position-helpers.ts | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/shared/src/models/utils/position/position-helpers.ts b/shared/src/models/utils/position/position-helpers.ts index c64db08e5..77631a0cb 100644 --- a/shared/src/models/utils/position/position-helpers.ts +++ b/shared/src/models/utils/position/position-helpers.ts @@ -9,16 +9,16 @@ import type { VehiclePosition } from './vehicle-position'; import type { WithPosition } from './with-position'; export function isOnMap(withPosition: WithPosition): boolean { - return withPosition.position.type === 'coordinates'; + return isPositionOnMap(withPosition.position); } export function isInVehicle(withPosition: WithPosition): boolean { - return withPosition.position.type === 'vehicle'; + return isPositionInVehicle(withPosition.position); } export function isInTransfer(withPosition: WithPosition): boolean { - return withPosition.position.type === 'transfer'; + return isPositionInTransfer(withPosition.position); } export function isInSimulatedRegion(withPosition: WithPosition): boolean { - return withPosition.position.type === 'simulatedRegion'; + return isPositionInSimulatedRegion(withPosition.position); } export function isNotOnMap(withPosition: WithPosition): boolean { return !isOnMap(withPosition); @@ -35,7 +35,7 @@ export function isNotInSimulatedRegion(withPosition: WithPosition): boolean { export function coordinatesOf(withPosition: WithPosition): MapCoordinates { if (isOnMap(withPosition)) { - return (withPosition.position as MapPosition).coordinates; + return coordinatesOfPosition(withPosition.position); } throw new TypeError( `Expected position of object to be on Map. Was of type ${withPosition.position.type}.` @@ -44,7 +44,7 @@ export function coordinatesOf(withPosition: WithPosition): MapCoordinates { export function vehicleItsIn(withPosition: WithPosition): UUID { if (isInVehicle(withPosition)) { - return (withPosition.position as VehiclePosition).vehicleId; + return vehiclePositionIsIn(withPosition.position); } throw new TypeError( `Expected position of object to be in vehicle. Was of type ${withPosition.position.type}.` @@ -53,7 +53,7 @@ export function vehicleItsIn(withPosition: WithPosition): UUID { export function transferItsIn(withPosition: WithPosition): Transfer { if (isInTransfer(withPosition)) { - return (withPosition.position as TransferPosition).transfer; + return transferPositionIsIn(withPosition.position); } throw new TypeError( `Expected position of object to be in transfer. Was of type ${withPosition.position.type}.` @@ -62,8 +62,7 @@ export function transferItsIn(withPosition: WithPosition): Transfer { export function simulatedRegionItsIn(withPosition: WithPosition): UUID { if (isInSimulatedRegion(withPosition)) { - return (withPosition.position as SimulatedRegionPosition) - .simulatedRegionId; + return simulatedRegionPositionIsIn(withPosition.position); } throw new TypeError( `Expected position of object to be in simulatedRegion. Was of type ${withPosition.position.type}.` @@ -100,33 +99,33 @@ export function coordinatesOfPosition(position: Position): MapCoordinates { return (position as MapPosition).coordinates; } throw new TypeError( - `Expected position of object to be on Map. Was of type ${position.type}.` + `Expected position to be on Map. Was of type ${position.type}.` ); } -export function vehiclePositionIn(position: Position): UUID { +export function vehiclePositionIsIn(position: Position): UUID { if (isPositionInVehicle(position)) { return (position as VehiclePosition).vehicleId; } throw new TypeError( - `Expected position of object to be in vehicle. Was of type ${position.type}.` + `Expected position to be in vehicle. Was of type ${position.type}.` ); } -export function transferPositionIn(position: Position): Transfer { +export function transferPositionIsIn(position: Position): Transfer { if (isPositionInTransfer(position)) { return (position as TransferPosition).transfer; } throw new TypeError( - `Expected position of object to be in transfer. Was of type ${position.type}.` + `Expected position to be in transfer. Was of type ${position.type}.` ); } -export function simulatedRegionPositionIn(position: Position): UUID { +export function simulatedRegionPositionIsIn(position: Position): UUID { if (isPositionInSimulatedRegion(position)) { return (position as SimulatedRegionPosition).simulatedRegionId; } throw new TypeError( - `Expected position of object to be in simulatedRegion. Was of type ${position.type}.` + `Expected position to be in simulatedRegion. Was of type ${position.type}.` ); } From 991c6dc399a9c48629154e9941ecfc8a00b274ed Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Tue, 31 Jan 2023 17:11:44 +0100 Subject: [PATCH 21/22] Change Names of Helper Functions --- .../core/statistics/statistics.service.ts | 8 +++---- .../exercise-map/utility/ol-map-manager.ts | 20 +++++++++-------- .../utility/point-geometry-helper.ts | 9 +++++--- .../utility/polygon-geometry-helper.ts | 21 ++++++++++-------- .../transfer-overview-table.component.html | 12 +++++----- .../transfer-overview-table.component.ts | 4 ++-- .../selectors/exercise.selectors.ts | 6 ++--- .../application/selectors/shared.selectors.ts | 12 ++++++---- shared/src/models/simulated-region.ts | 4 ++-- .../src/models/utils/position/map-position.ts | 4 ++-- .../models/utils/position/position-helpers.ts | 22 ++++++++++--------- .../position/simulated-region-position.ts | 4 ++-- .../utils/position/transfer-position.ts | 4 ++-- .../models/utils/position/vehicle-position.ts | 4 ++-- shared/src/models/viewport.ts | 18 ++++++++++----- shared/src/store/action-reducers/exercise.ts | 8 +++---- .../store/action-reducers/transfer-point.ts | 12 +++++----- shared/src/store/action-reducers/transfer.ts | 16 ++++++++------ .../utils/calculate-treatments.spec.ts | 6 ++--- .../utils/calculate-treatments.ts | 10 ++++----- .../action-reducers/utils/spatial-elements.ts | 12 ++++++---- shared/src/store/action-reducers/vehicle.ts | 4 ++-- 22 files changed, 124 insertions(+), 96 deletions(-) diff --git a/frontend/src/app/pages/exercises/exercise/shared/core/statistics/statistics.service.ts b/frontend/src/app/pages/exercises/exercise/shared/core/statistics/statistics.service.ts index 63ae552f0..dc54695d2 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/core/statistics/statistics.service.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/core/statistics/statistics.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; import { isNotInVehicle, - coordinatesOf, + currentCoordinatesOf, isOnMap, loopTroughTime, uuid, @@ -115,7 +115,7 @@ export class StatisticsService { isOnMap(patient) && Viewport.isInViewport( viewport, - coordinatesOf(patient) + currentCoordinatesOf(patient) ) ), Object.values(draftState.vehicles).filter( @@ -123,7 +123,7 @@ export class StatisticsService { isOnMap(vehicle) && Viewport.isInViewport( viewport, - coordinatesOf(vehicle) + currentCoordinatesOf(vehicle) ) ), Object.values(draftState.personnel).filter( @@ -131,7 +131,7 @@ export class StatisticsService { isOnMap(personnel) && Viewport.isInViewport( viewport, - coordinatesOf(personnel) + currentCoordinatesOf(personnel) ) ) ), diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/ol-map-manager.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/ol-map-manager.ts index 797b92beb..f9ae5384a 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/ol-map-manager.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/ol-map-manager.ts @@ -5,7 +5,7 @@ import type { MergeIntersection, UUID, } from 'digital-fuesim-manv-shared'; -import { coordinatesOf } from 'digital-fuesim-manv-shared'; +import { currentCoordinatesOf } from 'digital-fuesim-manv-shared'; import type { Feature } from 'ol'; import { Overlay, View } from 'ol'; import type { Polygon } from 'ol/geom'; @@ -357,10 +357,10 @@ export class OlMapManager { const center = view.getCenter()!; const previousZoom = view.getZoom()!; const targetExtent = [ - coordinatesOf(viewport).x, - coordinatesOf(viewport).y - viewport.size.height, - coordinatesOf(viewport).x + viewport.size.width, - coordinatesOf(viewport).y, + currentCoordinatesOf(viewport).x, + currentCoordinatesOf(viewport).y - viewport.size.height, + currentCoordinatesOf(viewport).x + viewport.size.width, + currentCoordinatesOf(viewport).y, ]; view.fit(targetExtent); const matchingZoom = view.getZoom()!; @@ -529,20 +529,22 @@ export class OlMapManager { return; } const minX = Math.min( - ...viewports.map((viewport) => coordinatesOf(viewport).x) + ...viewports.map((viewport) => currentCoordinatesOf(viewport).x) ); const minY = Math.min( ...viewports.map( - (viewport) => coordinatesOf(viewport).y - viewport.size.height + (viewport) => + currentCoordinatesOf(viewport).y - viewport.size.height ) ); const maxX = Math.max( ...viewports.map( - (viewport) => coordinatesOf(viewport).x + viewport.size.width + (viewport) => + currentCoordinatesOf(viewport).x + viewport.size.width ) ); const maxY = Math.max( - ...viewports.map((viewport) => coordinatesOf(viewport).y) + ...viewports.map((viewport) => currentCoordinatesOf(viewport).y) ); const padding = 25; view.fit([minX, minY, maxX, maxY], { diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/point-geometry-helper.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/point-geometry-helper.ts index a1239b985..a9c65dee8 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/point-geometry-helper.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/point-geometry-helper.ts @@ -1,5 +1,8 @@ import type { WithPosition } from 'digital-fuesim-manv-shared'; -import { MapCoordinates, coordinatesOf } from 'digital-fuesim-manv-shared'; +import { + MapCoordinates, + currentCoordinatesOf, +} from 'digital-fuesim-manv-shared'; import { Feature } from 'ol'; import { Point } from 'ol/geom'; import type { @@ -15,8 +18,8 @@ export class PointGeometryHelper implements GeometryHelper { new Feature(new Point(this.getElementCoordinates(element))); getElementCoordinates = (element: WithPosition): Coordinates => [ - coordinatesOf(element).x, - coordinatesOf(element).y, + currentCoordinatesOf(element).x, + currentCoordinatesOf(element).y, ]; getFeatureCoordinates = (feature: Feature): Coordinates => diff --git a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/polygon-geometry-helper.ts b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/polygon-geometry-helper.ts index 2550ee9a1..29fc313d5 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/polygon-geometry-helper.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/exercise-map/utility/polygon-geometry-helper.ts @@ -1,4 +1,7 @@ -import { coordinatesOf, MapCoordinates } from 'digital-fuesim-manv-shared'; +import { + currentCoordinatesOf, + MapCoordinates, +} from 'digital-fuesim-manv-shared'; import { Feature } from 'ol'; import { Polygon } from 'ol/geom'; import type { @@ -20,20 +23,20 @@ export class PolygonGeometryHelper element: ResizableElement ): Coordinates => [ [ - [coordinatesOf(element).x, coordinatesOf(element).y], + [currentCoordinatesOf(element).x, currentCoordinatesOf(element).y], [ - coordinatesOf(element).x + element.size.width, - coordinatesOf(element).y, + currentCoordinatesOf(element).x + element.size.width, + currentCoordinatesOf(element).y, ], [ - coordinatesOf(element).x + element.size.width, - coordinatesOf(element).y - element.size.height, + currentCoordinatesOf(element).x + element.size.width, + currentCoordinatesOf(element).y - element.size.height, ], [ - coordinatesOf(element).x, - coordinatesOf(element).y - element.size.height, + currentCoordinatesOf(element).x, + currentCoordinatesOf(element).y - element.size.height, ], - [coordinatesOf(element).x, coordinatesOf(element).y], + [currentCoordinatesOf(element).x, currentCoordinatesOf(element).y], ], ]; diff --git a/frontend/src/app/pages/exercises/exercise/shared/transfer-overview/transfer-overview-table/transfer-overview-table.component.html b/frontend/src/app/pages/exercises/exercise/shared/transfer-overview/transfer-overview-table/transfer-overview-table.component.html index bd76dd228..0138c6716 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/transfer-overview/transfer-overview-table/transfer-overview-table.component.html +++ b/frontend/src/app/pages/exercises/exercise/shared/transfer-overview/transfer-overview-table/transfer-overview-table.component.html @@ -38,21 +38,21 @@ @@ -72,21 +72,21 @@ diff --git a/frontend/src/app/pages/exercises/exercise/shared/transfer-overview/transfer-overview-table/transfer-overview-table.component.ts b/frontend/src/app/pages/exercises/exercise/shared/transfer-overview/transfer-overview-table/transfer-overview-table.component.ts index b24199a36..da2e76397 100644 --- a/frontend/src/app/pages/exercises/exercise/shared/transfer-overview/transfer-overview-table/transfer-overview-table.component.ts +++ b/frontend/src/app/pages/exercises/exercise/shared/transfer-overview/transfer-overview-table/transfer-overview-table.component.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core'; import { Store } from '@ngrx/store'; -import { transferItsIn } from 'digital-fuesim-manv-shared'; +import { currentTransferOf } from 'digital-fuesim-manv-shared'; import type { AppState } from 'src/app/state/app.state'; import { selectExerciseStatus, @@ -21,7 +21,7 @@ export class TransferOverviewTableComponent { selectPersonnelInTransfer ); - public transferItsIn = transferItsIn; + public currentTransferOf = currentTransferOf; public readonly exerciseStatus$ = this.store.select(selectExerciseStatus); diff --git a/frontend/src/app/state/application/selectors/exercise.selectors.ts b/frontend/src/app/state/application/selectors/exercise.selectors.ts index 8a8aca370..42e6ab4a8 100644 --- a/frontend/src/app/state/application/selectors/exercise.selectors.ts +++ b/frontend/src/app/state/application/selectors/exercise.selectors.ts @@ -5,7 +5,7 @@ import type { UUID, Vehicle, } from 'digital-fuesim-manv-shared'; -import { isInTransfer, coordinatesOf } from 'digital-fuesim-manv-shared'; +import { isInTransfer, currentCoordinatesOf } from 'digital-fuesim-manv-shared'; import type { TransferLine } from 'src/app/shared/types/transfer-line'; import type { AppState } from '../../app.state'; @@ -119,8 +119,8 @@ export const selectTransferLines = createSelector( Object.entries(transferPoint.reachableTransferPoints).map( ([connectedId, { duration }]) => ({ id: `${transferPoint.id}:${connectedId}` as const, - startPosition: coordinatesOf(transferPoint), - endPosition: coordinatesOf( + startPosition: currentCoordinatesOf(transferPoint), + endPosition: currentCoordinatesOf( transferPoints[connectedId]! ), duration, diff --git a/frontend/src/app/state/application/selectors/shared.selectors.ts b/frontend/src/app/state/application/selectors/shared.selectors.ts index 9f31c8dde..fbd0c8421 100644 --- a/frontend/src/app/state/application/selectors/shared.selectors.ts +++ b/frontend/src/app/state/application/selectors/shared.selectors.ts @@ -10,7 +10,11 @@ import type { Vehicle, WithPosition, } from 'digital-fuesim-manv-shared'; -import { coordinatesOf, isOnMap, Viewport } from 'digital-fuesim-manv-shared'; +import { + currentCoordinatesOf, + isOnMap, + Viewport, +} from 'digital-fuesim-manv-shared'; import { pickBy } from 'lodash-es'; import type { CateringLine } from 'src/app/shared/types/catering-line'; import type { AppState } from '../../app.state'; @@ -71,7 +75,7 @@ function selectVisibleElementsFactory< isInViewport: (element: Element, viewport: Viewport) => boolean = ( element, viewport - ) => Viewport.isInViewport(viewport, coordinatesOf(element)) + ) => Viewport.isInViewport(viewport, currentCoordinatesOf(element)) ) { return createSelector( selectRestrictedViewport, @@ -132,9 +136,9 @@ export const selectVisibleCateringLines = createSelector( ), ].map((caterer) => ({ id: `${caterer.id}:${patient.id}` as const, - patientPosition: coordinatesOf(patient), + patientPosition: currentCoordinatesOf(patient), // If the catering element is treating a patient, it must have a position - catererPosition: coordinatesOf(caterer), + catererPosition: currentCoordinatesOf(caterer), })) ) // To improve performance, all Lines where both ends are not in the viewport diff --git a/shared/src/models/simulated-region.ts b/shared/src/models/simulated-region.ts index 41ccdc14d..1e170c7f5 100644 --- a/shared/src/models/simulated-region.ts +++ b/shared/src/models/simulated-region.ts @@ -8,7 +8,7 @@ import { isInSimulatedRegion, MapPosition, Position, - simulatedRegionItsIn, + currentSimulatedRegionIdOf, Size, } from './utils'; import type { ImageProperties, MapCoordinates } from './utils'; @@ -61,7 +61,7 @@ export class SimulatedRegion { ): boolean { return ( isInSimulatedRegion(withPosition) && - simulatedRegionItsIn(withPosition) === region.id + currentSimulatedRegionIdOf(withPosition) === region.id ); } } diff --git a/shared/src/models/utils/position/map-position.ts b/shared/src/models/utils/position/map-position.ts index 5751316da..cff3a2616 100644 --- a/shared/src/models/utils/position/map-position.ts +++ b/shared/src/models/utils/position/map-position.ts @@ -4,7 +4,7 @@ import { IsValue } from '../../../utils/validators'; import { getCreate } from '../get-create'; import { MapCoordinates } from './map-coordinates'; // eslint-disable-next-line @typescript-eslint/no-unused-vars -import { isOnMap, isNotOnMap, coordinatesOf } from './position-helpers'; +import { isOnMap, isNotOnMap, currentCoordinatesOf } from './position-helpers'; export class MapPosition { /** @@ -14,7 +14,7 @@ export class MapPosition { public readonly type = 'coordinates'; /** - * @deprecated Use {@link coordinatesOf} instead + * @deprecated Use {@link currentCoordinatesOf} instead */ @Type(() => MapCoordinates) @ValidateNested() diff --git a/shared/src/models/utils/position/position-helpers.ts b/shared/src/models/utils/position/position-helpers.ts index 77631a0cb..a87984a24 100644 --- a/shared/src/models/utils/position/position-helpers.ts +++ b/shared/src/models/utils/position/position-helpers.ts @@ -33,7 +33,9 @@ export function isNotInSimulatedRegion(withPosition: WithPosition): boolean { return !isInSimulatedRegion(withPosition); } -export function coordinatesOf(withPosition: WithPosition): MapCoordinates { +export function currentCoordinatesOf( + withPosition: WithPosition +): MapCoordinates { if (isOnMap(withPosition)) { return coordinatesOfPosition(withPosition.position); } @@ -42,27 +44,27 @@ export function coordinatesOf(withPosition: WithPosition): MapCoordinates { ); } -export function vehicleItsIn(withPosition: WithPosition): UUID { +export function currentVehicleIdOf(withPosition: WithPosition): UUID { if (isInVehicle(withPosition)) { - return vehiclePositionIsIn(withPosition.position); + return vehicleIdOfPosition(withPosition.position); } throw new TypeError( `Expected position of object to be in vehicle. Was of type ${withPosition.position.type}.` ); } -export function transferItsIn(withPosition: WithPosition): Transfer { +export function currentTransferOf(withPosition: WithPosition): Transfer { if (isInTransfer(withPosition)) { - return transferPositionIsIn(withPosition.position); + return transferOfPosition(withPosition.position); } throw new TypeError( `Expected position of object to be in transfer. Was of type ${withPosition.position.type}.` ); } -export function simulatedRegionItsIn(withPosition: WithPosition): UUID { +export function currentSimulatedRegionIdOf(withPosition: WithPosition): UUID { if (isInSimulatedRegion(withPosition)) { - return simulatedRegionPositionIsIn(withPosition.position); + return simulatedRegionIdOfPosition(withPosition.position); } throw new TypeError( `Expected position of object to be in simulatedRegion. Was of type ${withPosition.position.type}.` @@ -103,7 +105,7 @@ export function coordinatesOfPosition(position: Position): MapCoordinates { ); } -export function vehiclePositionIsIn(position: Position): UUID { +export function vehicleIdOfPosition(position: Position): UUID { if (isPositionInVehicle(position)) { return (position as VehiclePosition).vehicleId; } @@ -112,7 +114,7 @@ export function vehiclePositionIsIn(position: Position): UUID { ); } -export function transferPositionIsIn(position: Position): Transfer { +export function transferOfPosition(position: Position): Transfer { if (isPositionInTransfer(position)) { return (position as TransferPosition).transfer; } @@ -121,7 +123,7 @@ export function transferPositionIsIn(position: Position): Transfer { ); } -export function simulatedRegionPositionIsIn(position: Position): UUID { +export function simulatedRegionIdOfPosition(position: Position): UUID { if (isPositionInSimulatedRegion(position)) { return (position as SimulatedRegionPosition).simulatedRegionId; } diff --git a/shared/src/models/utils/position/simulated-region-position.ts b/shared/src/models/utils/position/simulated-region-position.ts index 26af7dfff..bf5e34309 100644 --- a/shared/src/models/utils/position/simulated-region-position.ts +++ b/shared/src/models/utils/position/simulated-region-position.ts @@ -8,7 +8,7 @@ import { // eslint-disable-next-line @typescript-eslint/no-unused-vars isNotInSimulatedRegion, // eslint-disable-next-line @typescript-eslint/no-unused-vars - simulatedRegionItsIn, + currentSimulatedRegionIdOf, } from './position-helpers'; export class SimulatedRegionPosition { @@ -19,7 +19,7 @@ export class SimulatedRegionPosition { public readonly type = 'simulatedRegion'; /** - * @deprecated Use {@link simulatedRegionItsIn } instead + * @deprecated Use {@link currentSimulatedRegionIdOf } instead */ @IsUUID() public readonly simulatedRegionId: UUID; diff --git a/shared/src/models/utils/position/transfer-position.ts b/shared/src/models/utils/position/transfer-position.ts index 6f80018a7..92f782be9 100644 --- a/shared/src/models/utils/position/transfer-position.ts +++ b/shared/src/models/utils/position/transfer-position.ts @@ -9,7 +9,7 @@ import { // eslint-disable-next-line @typescript-eslint/no-unused-vars isNotInTransfer, // eslint-disable-next-line @typescript-eslint/no-unused-vars - transferItsIn, + currentTransferOf, } from './position-helpers'; export class TransferPosition { @@ -20,7 +20,7 @@ export class TransferPosition { public readonly type = 'transfer'; /** - * @deprecated Use {@link transferItsIn } instead + * @deprecated Use {@link currentTransferOf } instead */ @Type(() => Transfer) @ValidateNested() diff --git a/shared/src/models/utils/position/vehicle-position.ts b/shared/src/models/utils/position/vehicle-position.ts index 1bb236dc9..cd12d25fd 100644 --- a/shared/src/models/utils/position/vehicle-position.ts +++ b/shared/src/models/utils/position/vehicle-position.ts @@ -8,7 +8,7 @@ import { // eslint-disable-next-line @typescript-eslint/no-unused-vars isNotInVehicle, // eslint-disable-next-line @typescript-eslint/no-unused-vars - vehicleItsIn, + currentVehicleIdOf, } from './position-helpers'; export class VehiclePosition { @@ -19,7 +19,7 @@ export class VehiclePosition { public readonly type = 'vehicle'; /** - * @deprecated Use {@link vehicleItsIn } instead + * @deprecated Use {@link currentVehicleIdOf } instead */ @IsUUID() public readonly vehicleId: UUID; diff --git a/shared/src/models/viewport.ts b/shared/src/models/viewport.ts index 47c481d77..081635bc4 100644 --- a/shared/src/models/viewport.ts +++ b/shared/src/models/viewport.ts @@ -3,7 +3,13 @@ import { IsString, IsUUID, ValidateNested } from 'class-validator'; import { UUID, uuid, uuidValidationOptions } from '../utils'; import { IsPosition } from '../utils/validators/is-position'; import { IsValue } from '../utils/validators'; -import { coordinatesOf, getCreate, MapPosition, Position, Size } from './utils'; +import { + currentCoordinatesOf, + getCreate, + MapPosition, + Position, + Size, +} from './utils'; import type { ImageProperties, MapCoordinates } from './utils'; export class Viewport { @@ -49,10 +55,12 @@ export class Viewport { static isInViewport(viewport: Viewport, position: MapCoordinates): boolean { return ( - coordinatesOf(viewport).x <= position.x && - position.x <= coordinatesOf(viewport).x + viewport.size.width && - coordinatesOf(viewport).y - viewport.size.height <= position.y && - position.y <= coordinatesOf(viewport).y + currentCoordinatesOf(viewport).x <= position.x && + position.x <= + currentCoordinatesOf(viewport).x + viewport.size.width && + currentCoordinatesOf(viewport).y - viewport.size.height <= + position.y && + position.y <= currentCoordinatesOf(viewport).y ); } } diff --git a/shared/src/store/action-reducers/exercise.ts b/shared/src/store/action-reducers/exercise.ts index 1fe506674..c20d48425 100644 --- a/shared/src/store/action-reducers/exercise.ts +++ b/shared/src/store/action-reducers/exercise.ts @@ -11,7 +11,7 @@ import { Patient } from '../../models'; import { getStatus, isNotInTransfer, - transferItsIn, + currentTransferOf, TransferPosition, } from '../../models/utils'; import { changePosition } from '../../models/utils/position/position-helpers-mutable'; @@ -155,8 +155,8 @@ function refreshTransfer( if (isNotInTransfer(element)) { return; } - if (transferItsIn(element).isPaused) { - const newTransfer = cloneDeepMutable(transferItsIn(element)); + if (currentTransferOf(element).isPaused) { + const newTransfer = cloneDeepMutable(currentTransferOf(element)); newTransfer.endTimeStamp += tickInterval; changePosition( element, @@ -166,7 +166,7 @@ function refreshTransfer( return; } // Not transferred yet - if (transferItsIn(element).endTimeStamp > draftState.currentTime) { + if (currentTransferOf(element).endTimeStamp > draftState.currentTime) { return; } letElementArrive(draftState, type, element.id); diff --git a/shared/src/store/action-reducers/transfer-point.ts b/shared/src/store/action-reducers/transfer-point.ts index 2145a0a68..2e2abf06d 100644 --- a/shared/src/store/action-reducers/transfer-point.ts +++ b/shared/src/store/action-reducers/transfer-point.ts @@ -8,11 +8,11 @@ import { } from 'class-validator'; import { TransferPoint } from '../../models'; import { - coordinatesOf, + currentCoordinatesOf, isInTransfer, MapCoordinates, MapPosition, - transferItsIn, + currentTransferOf, } from '../../models/utils'; import { changePositionWithId } from '../../models/utils/position/position-helpers-mutable'; import { cloneDeepMutable, UUID, uuidValidationOptions } from '../../utils'; @@ -191,8 +191,8 @@ export namespace TransferPointActionReducers { const _duration = duration ?? estimateDuration( - coordinatesOf(transferPoint1), - coordinatesOf(transferPoint2) + currentCoordinatesOf(transferPoint1), + currentCoordinatesOf(transferPoint2) ); transferPoint1.reachableTransferPoints[transferPointId2] = { duration: _duration, @@ -248,7 +248,7 @@ export namespace TransferPointActionReducers { ); if ( isInTransfer(vehicle) && - transferItsIn(vehicle).targetTransferPointId === + currentTransferOf(vehicle).targetTransferPointId === transferPointId ) { letElementArrive(draftState, vehicle.type, vehicleId); @@ -262,7 +262,7 @@ export namespace TransferPointActionReducers { ); if ( isInTransfer(personnel) && - transferItsIn(personnel).targetTransferPointId === + currentTransferOf(personnel).targetTransferPointId === transferPointId ) { letElementArrive( diff --git a/shared/src/store/action-reducers/transfer.ts b/shared/src/store/action-reducers/transfer.ts index abfabc7a9..d21a3304f 100644 --- a/shared/src/store/action-reducers/transfer.ts +++ b/shared/src/store/action-reducers/transfer.ts @@ -5,9 +5,9 @@ import type { MapCoordinates } from '../../models/utils'; import { isInTransfer, isNotInTransfer, - transferItsIn, + currentTransferOf, TransferPosition, - coordinatesOf, + currentCoordinatesOf, MapPosition, StartPoint, startPointTypeOptions, @@ -45,12 +45,12 @@ export function letElementArrive( const targetTransferPoint = getElement( draftState, 'transferPoint', - transferItsIn(element).targetTransferPointId + currentTransferOf(element).targetTransferPointId ); const newPosition: Mutable = { - x: coordinatesOf(targetTransferPoint).x, + x: currentCoordinatesOf(targetTransferPoint).x, y: - coordinatesOf(targetTransferPoint).y + + currentCoordinatesOf(targetTransferPoint).y + // Position it in the upper half of the transferPoint imageSizeToPosition(TransferPoint.image.height / 3), }; @@ -190,7 +190,7 @@ export namespace TransferActionReducers { if (isNotInTransfer(element)) { throw getNotInTransferError(element.id); } - const newTransfer = cloneDeepMutable(transferItsIn(element)); + const newTransfer = cloneDeepMutable(currentTransferOf(element)); if (targetTransferPointId) { // check if transferPoint exists @@ -240,7 +240,9 @@ export namespace TransferActionReducers { if (isNotInTransfer(element)) { throw getNotInTransferError(element.id); } - const newTransfer = cloneDeepMutable(transferItsIn(element)); + const newTransfer = cloneDeepMutable( + currentTransferOf(element) + ); newTransfer.isPaused = !newTransfer.isPaused; changePosition( element, diff --git a/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts b/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts index 2e9b1182f..d48852cd7 100644 --- a/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts +++ b/shared/src/store/action-reducers/utils/calculate-treatments.spec.ts @@ -6,7 +6,7 @@ import type { Patient } from '../../../models'; import { Material, Personnel } from '../../../models'; import type { Position, PatientStatus } from '../../../models/utils'; import { - coordinatesOf, + currentCoordinatesOf, isPositionOnMap, CanCaterFor, MapCoordinates, @@ -115,7 +115,7 @@ function addPersonnel(state: Mutable, position: Position) { SpatialTree.addElement( state.spatialTrees.personnel, personnel.id, - coordinatesOf(personnel) + currentCoordinatesOf(personnel) ); } state.personnel[personnel.id] = personnel; @@ -141,7 +141,7 @@ function addMaterial(state: Mutable, position: Position) { SpatialTree.addElement( state.spatialTrees.materials, material.id, - coordinatesOf(material) + currentCoordinatesOf(material) ); } state.materials[material.id] = material; diff --git a/shared/src/store/action-reducers/utils/calculate-treatments.ts b/shared/src/store/action-reducers/utils/calculate-treatments.ts index fd8d0ba94..514c07cd1 100644 --- a/shared/src/store/action-reducers/utils/calculate-treatments.ts +++ b/shared/src/store/action-reducers/utils/calculate-treatments.ts @@ -2,7 +2,7 @@ import { groupBy } from 'lodash-es'; import type { Material, Personnel } from '../../../models'; import { Patient } from '../../../models'; import type { MapCoordinates, PatientStatus } from '../../../models/utils'; -import { coordinatesOf, isNotOnMap } from '../../../models/utils'; +import { currentCoordinatesOf, isNotOnMap } from '../../../models/utils'; import { SpatialTree } from '../../../models/utils/spatial-tree'; import type { ExerciseState } from '../../../state'; import { maxTreatmentRange } from '../../../state-helpers/max-treatment-range'; @@ -197,13 +197,13 @@ export function updateTreatments( updateCateringAroundPatient( state, - coordinatesOf(element), + currentCoordinatesOf(element), 'personnel', alreadyUpdatedElementIds ); updateCateringAroundPatient( state, - coordinatesOf(element), + currentCoordinatesOf(element), 'material', alreadyUpdatedElementIds ); @@ -244,7 +244,7 @@ function updateCatering( if (cateringElement.overrideTreatmentRange > 0) { const patientIdsInOverrideRange = SpatialTree.findAllElementsInCircle( state.spatialTrees.patients, - coordinatesOf(cateringElement), + currentCoordinatesOf(cateringElement), cateringElement.overrideTreatmentRange ); // In the overrideTreatmentRange (the override circle) only the distance to the patient is important - his/her injuries are ignored @@ -273,7 +273,7 @@ function updateCatering( const patientsInTreatmentRange: Mutable[] = SpatialTree.findAllElementsInCircle( state.spatialTrees.patients, - coordinatesOf(cateringElement), + currentCoordinatesOf(cateringElement), cateringElement.treatmentRange ) // Filter out every patient in the overrideTreatmentRange diff --git a/shared/src/store/action-reducers/utils/spatial-elements.ts b/shared/src/store/action-reducers/utils/spatial-elements.ts index 49e8aef75..04f03bec4 100644 --- a/shared/src/store/action-reducers/utils/spatial-elements.ts +++ b/shared/src/store/action-reducers/utils/spatial-elements.ts @@ -1,5 +1,9 @@ import type { MapCoordinates } from '../../../models/utils'; -import { isOnMap, isNotOnMap, coordinatesOf } from '../../../models/utils'; +import { + isOnMap, + isNotOnMap, + currentCoordinatesOf, +} from '../../../models/utils'; import { SpatialTree } from '../../../models/utils/spatial-tree'; import type { ExerciseState } from '../../../state'; import type { Mutable, UUID } from '../../../utils'; @@ -33,7 +37,7 @@ export function addElementPosition( SpatialTree.addElement( state.spatialTrees[elementTypePluralMap[elementType]], element.id, - coordinatesOf(element) + currentCoordinatesOf(element) ); } @@ -48,7 +52,7 @@ export function updateElementPosition( ) { const element = getElement(state, elementType, elementId); if (isOnMap(element)) { - const startPosition = cloneDeepMutable(coordinatesOf(element)); + const startPosition = cloneDeepMutable(currentCoordinatesOf(element)); SpatialTree.moveElement( state.spatialTrees[elementTypePluralMap[elementType]], element.id, @@ -80,6 +84,6 @@ export function removeElementPosition( SpatialTree.removeElement( state.spatialTrees[elementTypePluralMap[elementType]], element.id, - cloneDeepMutable(coordinatesOf(element)) + cloneDeepMutable(currentCoordinatesOf(element)) ); } diff --git a/shared/src/store/action-reducers/vehicle.ts b/shared/src/store/action-reducers/vehicle.ts index 870b6caa9..6716c9326 100644 --- a/shared/src/store/action-reducers/vehicle.ts +++ b/shared/src/store/action-reducers/vehicle.ts @@ -2,7 +2,7 @@ import { Type } from 'class-transformer'; import { IsArray, IsString, IsUUID, ValidateNested } from 'class-validator'; import { Material, Personnel, Vehicle } from '../../models'; import { - coordinatesOf, + currentCoordinatesOf, isInTransfer, isInVehicle, isNotInTransfer, @@ -227,7 +227,7 @@ export namespace VehicleActionReducers { `Vehicle with id ${vehicleId} is currently not on the map` ); } - const unloadPosition = coordinatesOf(vehicle); + const unloadPosition = currentCoordinatesOf(vehicle); const materialIds = Object.keys(vehicle.materialIds); const personnelIds = Object.keys(vehicle.personnelIds); const patientIds = Object.keys(vehicle.patientIds); From 86eb1cbfe3d287cf1ce0c668858270f5703f6544 Mon Sep 17 00:00:00 2001 From: Benildur <82985280+benn02@users.noreply.github.com> Date: Tue, 31 Jan 2023 17:19:34 +0100 Subject: [PATCH 22/22] Added Comments to unused vars --- shared/src/models/utils/position/map-position.ts | 1 + shared/src/models/utils/position/simulated-region-position.ts | 3 +++ shared/src/models/utils/position/transfer-position.ts | 3 +++ shared/src/models/utils/position/vehicle-position.ts | 3 +++ 4 files changed, 10 insertions(+) diff --git a/shared/src/models/utils/position/map-position.ts b/shared/src/models/utils/position/map-position.ts index cff3a2616..9dd5a121f 100644 --- a/shared/src/models/utils/position/map-position.ts +++ b/shared/src/models/utils/position/map-position.ts @@ -3,6 +3,7 @@ import { ValidateNested } from 'class-validator'; import { IsValue } from '../../../utils/validators'; import { getCreate } from '../get-create'; import { MapCoordinates } from './map-coordinates'; +// import needed to display @link Links in Comments // eslint-disable-next-line @typescript-eslint/no-unused-vars import { isOnMap, isNotOnMap, currentCoordinatesOf } from './position-helpers'; diff --git a/shared/src/models/utils/position/simulated-region-position.ts b/shared/src/models/utils/position/simulated-region-position.ts index bf5e34309..fc1dc9fc6 100644 --- a/shared/src/models/utils/position/simulated-region-position.ts +++ b/shared/src/models/utils/position/simulated-region-position.ts @@ -3,10 +3,13 @@ import { UUID } from '../../../utils'; import { IsValue } from '../../../utils/validators'; import { getCreate } from '../get-create'; import { + // import needed to display @link Links in Comments // eslint-disable-next-line @typescript-eslint/no-unused-vars isInSimulatedRegion, + // import needed to display @link Links in Comments // eslint-disable-next-line @typescript-eslint/no-unused-vars isNotInSimulatedRegion, + // import needed to display @link Links in Comments // eslint-disable-next-line @typescript-eslint/no-unused-vars currentSimulatedRegionIdOf, } from './position-helpers'; diff --git a/shared/src/models/utils/position/transfer-position.ts b/shared/src/models/utils/position/transfer-position.ts index 92f782be9..f2f8b9672 100644 --- a/shared/src/models/utils/position/transfer-position.ts +++ b/shared/src/models/utils/position/transfer-position.ts @@ -4,10 +4,13 @@ import { IsValue } from '../../../utils/validators'; import { getCreate } from '../get-create'; import { Transfer } from '../transfer'; import { + // import needed to display @link Links in Comments // eslint-disable-next-line @typescript-eslint/no-unused-vars isInTransfer, + // import needed to display @link Links in Comments // eslint-disable-next-line @typescript-eslint/no-unused-vars isNotInTransfer, + // import needed to display @link Links in Comments // eslint-disable-next-line @typescript-eslint/no-unused-vars currentTransferOf, } from './position-helpers'; diff --git a/shared/src/models/utils/position/vehicle-position.ts b/shared/src/models/utils/position/vehicle-position.ts index cd12d25fd..4f91a3e0b 100644 --- a/shared/src/models/utils/position/vehicle-position.ts +++ b/shared/src/models/utils/position/vehicle-position.ts @@ -3,10 +3,13 @@ import { UUID } from '../../../utils'; import { IsValue } from '../../../utils/validators'; import { getCreate } from '../get-create'; import { + // import needed to display @link Links in Comments // eslint-disable-next-line @typescript-eslint/no-unused-vars isInVehicle, + // import needed to display @link Links in Comments // eslint-disable-next-line @typescript-eslint/no-unused-vars isNotInVehicle, + // import needed to display @link Links in Comments // eslint-disable-next-line @typescript-eslint/no-unused-vars currentVehicleIdOf, } from './position-helpers';