import type { ValidationState } from '../../common/static-wrappers/interfaces/validation-interface'; import { Component, Prop, toNative } from 'vue-facing-decorator'; import PowerduckState from '../../app/powerduck-state'; import TsxComponent from '../../app/vuetsx'; import BoundingBox from '../../data/bounding-box'; import FlexContainer from '../form/flex-container'; import FlexFormItem from '../form/form-item-flex'; import FormItemWrapper from '../form/form-item-wrapper'; import OpenStreetMap from '../open-street-map/open-street-map'; import NumericInput, { NumericInputMode } from './numeric-input'; interface GpsBoundingBoxInputArgs { bBoxModel: BoundingBox; mandatory?: boolean; disabled?: boolean; /** * QA_AT-8: optional callback fired after every operator edit to a bbox * field. Lets the consumer (e.g. Resort modal) flip a * `hasOperatorEditedBbox` flag so subsequent country / GPS changes stop * auto-recomputing the bbox. Backward-compatible: existing call sites that * omit it see no behaviour change. */ changed?: (field: keyof BoundingBox, value: number) => void; } @Component class GpsBoundingBoxInputComponent extends TsxComponent implements GpsBoundingBoxInputArgs { @Prop() bBoxModel: BoundingBox; @Prop() mandatory?: boolean; @Prop() disabled?: boolean; @Prop() changed?: (field: keyof BoundingBox, value: number) => void; onChange(field: keyof BoundingBox, value: number) { // QA_AT-11: align with `GpsInput` and round to 6 decimals (~11 cm) via // the shared `BoundingBox.roundCoord` (same rule as the server's // GpsHelper.roundCoord). QA_AT-24: NumericInput string-truncates while // typing (via maxDecimals={6} in renderInput); this round remains as a // defence-in-depth net for non-input paths — paste, programmatic bbox // prefills from country / GPS centroid recompute, etc. this.bBoxModel[field] = BoundingBox.roundCoord(value); if (this.changed) { this.changed(field, this.bBoxModel[field]); } } renderInput( h: any, label: string, value: number, onChanged?: (value: number) => void, showClearValueButton?: boolean, validationState?: ValidationState, ) { return ( { if (onChanged != null) { onChanged(e); } }} /> ); } render(h) { if (!this.bBoxModel) { return null; } // QA_AT-8: column order is latitudes (Y) on the left, longitudes (X) on // the right, matching `gps-input.tsx` lat-left / long-right semantics. return (
{this.renderInput( h, PowerduckState.getResourceValue('gpsBoundingBoxY1'), this.bBoxModel.y1, e => this.onChange('y1', e), )} {this.renderInput( h, PowerduckState.getResourceValue('gpsBoundingBoxY2'), this.bBoxModel.y2, e => this.onChange('y2', e), )} {this.renderInput( h, PowerduckState.getResourceValue('gpsBoundingBoxX1'), this.bBoxModel.x1, e => this.onChange('x1', e), )} {this.renderInput( h, PowerduckState.getResourceValue('gpsBoundingBoxX2'), this.bBoxModel.x2, e => this.onChange('x2', e), )}
); } } const GpsBoundingBoxInput = toNative(GpsBoundingBoxInputComponent); export default GpsBoundingBoxInput;