Pridani linku na planovac do menu, drobny bugfixing
This commit is contained in:
@@ -0,0 +1,57 @@
|
|||||||
|
<script setup>
|
||||||
|
import {computed} from "vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
lowerLimit: {
|
||||||
|
type: [String, Number],
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
lowerLimitUnit: {
|
||||||
|
type: String,
|
||||||
|
required: false // GND nema jednotky
|
||||||
|
},
|
||||||
|
upperLimit: {
|
||||||
|
type: [String, Number],
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
upperLimitUnit: {
|
||||||
|
type: String,
|
||||||
|
required: false // GND nema jednotky
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const getLimitFormatted = (limit, unit) => {
|
||||||
|
return `${limit} ${unit}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const upper = computed(() => getLimitFormatted(props.upperLimit, props.upperLimitUnit));
|
||||||
|
const lower = computed(() => getLimitFormatted(props.lowerLimit, props.lowerLimitUnit));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="altitude-limit">
|
||||||
|
<span class="upper">
|
||||||
|
{{ upper}}
|
||||||
|
</span>
|
||||||
|
<span class="lower">
|
||||||
|
{{ lower }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.altitude-limit {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
|
.upper, .lower {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upper {
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -2,9 +2,9 @@
|
|||||||
import {computed, ref, watch} from "vue";
|
import {computed, ref, watch} from "vue";
|
||||||
import {Marker, CustomMarker, Polyline} from "vue3-google-map";
|
import {Marker, CustomMarker, Polyline} from "vue3-google-map";
|
||||||
import MapWrapper from "components/map/MapWrapper.vue";
|
import MapWrapper from "components/map/MapWrapper.vue";
|
||||||
import AirspaceInfoWindow from "components/map/AirspaceInfoWindow.vue";
|
|
||||||
import {useFlightPlanObjects, useFlightPlanUtils} from "src/composables/flightPlan";
|
import {useFlightPlanObjects, useFlightPlanUtils} from "src/composables/flightPlan";
|
||||||
import {useGeocode} from "src/composables/geocoding";
|
import {useGeocode} from "src/composables/geocoding";
|
||||||
|
import AltitudeLimit from "components/AltitudeLimit.vue";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
flightPlan: {
|
flightPlan: {
|
||||||
@@ -35,24 +35,14 @@ const {center} = useGeocode();
|
|||||||
const {markerObject, googleMapsMarkerObject, infoWindowObject, editableNameTypes} = useFlightPlanObjects();
|
const {markerObject, googleMapsMarkerObject, infoWindowObject, editableNameTypes} = useFlightPlanObjects();
|
||||||
const {getMarkersFrom} = useFlightPlanUtils();
|
const {getMarkersFrom} = useFlightPlanUtils();
|
||||||
|
|
||||||
const infoWindow = ref(infoWindowObject({}));
|
const mapWrap = ref(null);
|
||||||
|
|
||||||
const handleMapClick = ({clickCoordinates, airspaces, airport, reportingPoint}) => {
|
|
||||||
infoWindow.value = infoWindowObject({
|
|
||||||
active: true,
|
|
||||||
position: clickCoordinates,
|
|
||||||
airspaces,
|
|
||||||
airport,
|
|
||||||
reportingPoint,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleMarkerClick = (marker) => {
|
const handleMarkerClick = (marker) => {
|
||||||
infoWindow.value = infoWindowObject({active: true, marker})
|
mapWrap.value.openInfoWindow({marker});
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePoiClick = (poi) => {
|
const handlePoiClick = (poi) => {
|
||||||
infoWindow.value = infoWindowObject({active: true, poi})
|
mapWrap.value.openInfoWindow({poi});
|
||||||
}
|
}
|
||||||
|
|
||||||
const markers = ref([]);
|
const markers = ref([]);
|
||||||
@@ -69,7 +59,7 @@ const addMarker = async (point) => {
|
|||||||
const insertAt = Math.min(markers.value.length, props.insertPosition);
|
const insertAt = Math.min(markers.value.length, props.insertPosition);
|
||||||
|
|
||||||
markers.value.splice(insertAt, 0, markerObject({...point}));
|
markers.value.splice(insertAt, 0, markerObject({...point}));
|
||||||
infoWindow.value = infoWindowObject({active: false});
|
// infoWindow.value = infoWindowObject({active: false});
|
||||||
|
|
||||||
emits("markers-changed", markers.value);
|
emits("markers-changed", markers.value);
|
||||||
emits("change-insert-position", insertAt + 1);
|
emits("change-insert-position", insertAt + 1);
|
||||||
@@ -88,6 +78,7 @@ const handleMarkerMove = async (idx, event) => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MapWrapper
|
<MapWrapper
|
||||||
|
ref="mapWrap"
|
||||||
style="width: 100%; height: 100%; min-height: 500px"
|
style="width: 100%; height: 100%; min-height: 500px"
|
||||||
:center="center"
|
:center="center"
|
||||||
:zoom="8"
|
:zoom="8"
|
||||||
@@ -95,15 +86,9 @@ const handleMarkerMove = async (idx, event) => {
|
|||||||
:airports="airports"
|
:airports="airports"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
:fullscreen-control="false"
|
:fullscreen-control="false"
|
||||||
@map-click="handleMapClick"
|
|
||||||
>
|
|
||||||
<AirspaceInfoWindow
|
|
||||||
v-if="infoWindow.active"
|
|
||||||
:info-window="infoWindow"
|
|
||||||
@close="infoWindow.active=false"
|
|
||||||
@add-to-route="addMarker"
|
@add-to-route="addMarker"
|
||||||
/>
|
|
||||||
|
|
||||||
|
>
|
||||||
<template v-for="poi in pointsOfInterest" :key="poi.name">
|
<template v-for="poi in pointsOfInterest" :key="poi.name">
|
||||||
<CustomMarker
|
<CustomMarker
|
||||||
v-if="poi.gpsLatitude && poi.gpsLongitude"
|
v-if="poi.gpsLatitude && poi.gpsLongitude"
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ const props = defineProps({
|
|||||||
v-ripple
|
v-ripple
|
||||||
v-for="flightPlan of items" :key="flightPlan">
|
v-for="flightPlan of items" :key="flightPlan">
|
||||||
<q-item-section avatar>
|
<q-item-section avatar>
|
||||||
<q-avatar icon="person" color="primary" text-color="white"/>
|
<q-avatar icon="flight" color="primary" text-color="white"/>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
<q-item-label>
|
<q-item-label>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ const props = defineProps({
|
|||||||
});
|
});
|
||||||
const emits = defineEmits(["update:gpsLatitude", "update:gpsLongitude", "notFound"]);
|
const emits = defineEmits(["update:gpsLatitude", "update:gpsLongitude", "notFound"]);
|
||||||
|
|
||||||
const {emitModels, setCoordinatesFromGeocode, center, zoom} = useGeocode(emits);
|
const {emitModels, setCoordinatesFromGeocode, searchGeocode, center, zoom} = useGeocode(emits);
|
||||||
const markerDropped = (position) => {
|
const markerDropped = (position) => {
|
||||||
emitModels(position.latLng.lat(), position.latLng.lng());
|
emitModels(position.latLng.lat(), position.latLng.lng());
|
||||||
}
|
}
|
||||||
@@ -30,6 +30,9 @@ onMounted(() => {
|
|||||||
center.value.lng = props.gpsLongitude;
|
center.value.lng = props.gpsLongitude;
|
||||||
center.value.lat = props.gpsLatitude
|
center.value.lat = props.gpsLatitude
|
||||||
} else if (props.label) {
|
} else if (props.label) {
|
||||||
|
searchGeocode(props.label).then(result => {
|
||||||
|
|
||||||
|
});
|
||||||
setCoordinatesFromGeocode(props.label);
|
setCoordinatesFromGeocode(props.label);
|
||||||
} else {
|
} else {
|
||||||
console.error("Set either label or gps coordinates.");
|
console.error("Set either label or gps coordinates.");
|
||||||
|
|||||||
@@ -2,16 +2,28 @@
|
|||||||
import {InfoWindow} from "vue3-google-map";
|
import {InfoWindow} from "vue3-google-map";
|
||||||
import {useFlightPlanUtils} from "src/composables/flightPlan";
|
import {useFlightPlanUtils} from "src/composables/flightPlan";
|
||||||
import {useGeocode} from "src/composables/geocoding";
|
import {useGeocode} from "src/composables/geocoding";
|
||||||
import {onMounted, ref, watch} from "vue";
|
import {ref, watch} from "vue";
|
||||||
|
import {useAirspaceColors} from "src/composables/airspaces";
|
||||||
|
import AltitudeLimit from "components/AltitudeLimit.vue";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
infoWindow: {
|
infoWindow: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
highlightedAirspaces: {
|
||||||
|
type: Array,
|
||||||
|
required: false,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
showActions: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const emits = defineEmits(["add-to-route", "close"])
|
const emits = defineEmits(["add-to-route", "highlight-airspace", "close"])
|
||||||
|
|
||||||
const {getIcon} = useFlightPlanUtils();
|
const {getIcon} = useFlightPlanUtils();
|
||||||
const {searchPlaceName} = useGeocode()
|
const {searchPlaceName} = useGeocode()
|
||||||
@@ -41,6 +53,11 @@ const addPoint = async () => {
|
|||||||
}
|
}
|
||||||
emits("add-to-route", point)
|
emits("add-to-route", point)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const {getColorByType} = useAirspaceColors();
|
||||||
|
const highlightAirspace = (airspace) => {
|
||||||
|
emits('highlight-airspace', airspace.name)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
@@ -61,16 +78,45 @@ const addPoint = async () => {
|
|||||||
<div v-if="infoWindow.poi">
|
<div v-if="infoWindow.poi">
|
||||||
<q-img :src="infoWindow.poi.titlePhoto.thumbnailUrl" v-if="infoWindow.poi.titlePhoto"/>
|
<q-img :src="infoWindow.poi.titlePhoto.thumbnailUrl" v-if="infoWindow.poi.titlePhoto"/>
|
||||||
{{ infoWindow.poi.name }}
|
{{ infoWindow.poi.name }}
|
||||||
|
|
||||||
{{ infoWindow.poi }}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-if="infoWindow.airspaces?.length">
|
<template v-if="infoWindow.airspaces?.length">
|
||||||
<span class="text-h6">Prostory</span>
|
<span class="text-h6">Prostory</span>
|
||||||
<div v-for="airspace in infoWindow.airspaces" :key="airspace">
|
<q-list>
|
||||||
|
<q-item-label v-for="airspace in infoWindow.airspaces" :key="airspace.name">
|
||||||
|
<q-avatar size="16px" class="q-mx-sm" :style="`border: solid 1px; background: ${getColorByType(airspace.type)}`"/>
|
||||||
|
|
||||||
|
<strong>
|
||||||
{{ airspace.name }}
|
{{ airspace.name }}
|
||||||
</div>
|
</strong>
|
||||||
|
|
||||||
|
<AltitudeLimit
|
||||||
|
class="q-mx-md"
|
||||||
|
:upper-limit="airspace.upperLimit"
|
||||||
|
:upper-limit-unit="airspace.upperAltUnit"
|
||||||
|
:lower-limit="airspace.lowerLimit"
|
||||||
|
:lower-limit-unit="airspace.lowerAltUnit"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<q-btn
|
||||||
|
v-if="airspace.type !== 'FIR'"
|
||||||
|
color="white"
|
||||||
|
:text-color="props.highlightedAirspaces.includes(airspace.name) ? 'primary' : 'grey-6'"
|
||||||
|
size="x-small"
|
||||||
|
round
|
||||||
|
text
|
||||||
|
icon="mdi-eye"
|
||||||
|
@click="highlightAirspace(airspace)"
|
||||||
|
/>
|
||||||
|
</q-item-label>
|
||||||
|
</q-list>
|
||||||
</template>
|
</template>
|
||||||
<q-btn class="q-mt-lg" color="secondary" @click="addPoint()">Přidat bod do trasy</q-btn>
|
<q-btn
|
||||||
|
v-if="showActions"
|
||||||
|
class="q-mt-lg"
|
||||||
|
color="secondary"
|
||||||
|
@click="addPoint()">
|
||||||
|
Přidat bod do trasy
|
||||||
|
</q-btn>
|
||||||
</InfoWindow>
|
</InfoWindow>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
import {Circle, GoogleMap, CustomControl, CustomMarker, Polygon} from "vue3-google-map";
|
import {Circle, GoogleMap, CustomControl, CustomMarker, Polygon} from "vue3-google-map";
|
||||||
import {computed, ref, watch} from "vue";
|
import {computed, ref, watch} from "vue";
|
||||||
import {useBasicVectorOperations, useVectorUtilities} from "src/graphql/fragments/vectorUtilities";
|
import {useBasicVectorOperations, useVectorUtilities} from "src/graphql/fragments/vectorUtilities";
|
||||||
|
import {useAirspaceColors} from "src/composables/airspaces";
|
||||||
|
import AirspaceInfoWindow from "components/map/AirspaceInfoWindow.vue";
|
||||||
|
import {useFlightPlanObjects} from "src/composables/flightPlan";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
bounds: {
|
bounds: {
|
||||||
@@ -18,6 +21,16 @@ const props = defineProps({
|
|||||||
required: false,
|
required: false,
|
||||||
default: () => []
|
default: () => []
|
||||||
},
|
},
|
||||||
|
showInfoWindow: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
allowAddMarker: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
showLayerControls: {
|
showLayerControls: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
@@ -25,7 +38,7 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const emits = defineEmits(["map-click"]);
|
const emits = defineEmits(["map-click", "add-to-route"]);
|
||||||
|
|
||||||
const key = process.env.GOOGLE_MAPS_API_KEY;
|
const key = process.env.GOOGLE_MAPS_API_KEY;
|
||||||
|
|
||||||
@@ -68,18 +81,7 @@ const displayAirspaceLayers = ref({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const airspaces = computed(() => {
|
const airspaces = computed(() => {
|
||||||
const colorsMap = {
|
const colorsMap = useAirspaceColors().colors;
|
||||||
TMA: "#800080",
|
|
||||||
CTR: "#366e36",
|
|
||||||
PROHIBIT: "#FF0000",
|
|
||||||
RMZ: "#FFdd00",
|
|
||||||
RESTRICT: "#ff6a00",
|
|
||||||
DANGER: "#FFA500",
|
|
||||||
TRAGA: "#008000",
|
|
||||||
ATZ: "#4e7cfc",
|
|
||||||
FIR: '#ffffff',
|
|
||||||
PARA: "#000000"
|
|
||||||
}
|
|
||||||
|
|
||||||
return props.airspacesData
|
return props.airspacesData
|
||||||
.filter(airspace => !!colorsMap[airspace.type])
|
.filter(airspace => !!colorsMap[airspace.type])
|
||||||
@@ -103,9 +105,6 @@ const airspaces = computed(() => {
|
|||||||
|
|
||||||
if (airspace.mapBounds.length > 0) {
|
if (airspace.mapBounds.length > 0) {
|
||||||
data['path'] = airspace.mapBounds;
|
data['path'] = airspace.mapBounds;
|
||||||
} else {
|
|
||||||
data['center'] = airspace.mapCenter;
|
|
||||||
data['radius'] = airspace.radius
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return data
|
return data
|
||||||
@@ -121,41 +120,61 @@ const airportsOnMap = computed(() => {
|
|||||||
const {isPointInPolygon, vectorDistanceToKm} = useVectorUtilities();
|
const {isPointInPolygon, vectorDistanceToKm} = useVectorUtilities();
|
||||||
const {vectorDistance} = useBasicVectorOperations();
|
const {vectorDistance} = useBasicVectorOperations();
|
||||||
|
|
||||||
const highlightedAirspaces = ref([]);
|
|
||||||
|
|
||||||
const getAirspacesAtCoordinates = (clickCoordinates) => {
|
const getAirspacesAtCoordinates = (clickCoordinates) => {
|
||||||
const airspacesUnderClick = []
|
const airspacesUnderClick = []
|
||||||
for (const airspace of props.airspacesData) {
|
for (const airspace of props.airspacesData) {
|
||||||
if (airspace.mapBounds && isPointInPolygon(clickCoordinates, airspace.mapBounds)) {
|
if (airspace.mapBounds && isPointInPolygon(clickCoordinates, airspace.mapBounds)) {
|
||||||
airspacesUnderClick.push(airspace);
|
airspacesUnderClick.push(airspace);
|
||||||
} else if (airspace.mapCenter && airspace.radius) {
|
|
||||||
const radDistance = vectorDistance(clickCoordinates, airspace.mapCenter);
|
|
||||||
const distanceKm = vectorDistanceToKm(radDistance)
|
|
||||||
|
|
||||||
if (distanceKm * 1000 <= airspace.radius) {
|
|
||||||
airspacesUnderClick.push(airspace)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return airspacesUnderClick;
|
return airspacesUnderClick;
|
||||||
}
|
}
|
||||||
const handleMapClick = (e) => {
|
|
||||||
const clickCoordinates = {lat: e.latLng.lat(), lng: e.latLng.lng()}
|
|
||||||
|
|
||||||
const airspacesUnderClick = getAirspacesAtCoordinates(clickCoordinates);
|
const {infoWindowObject} = useFlightPlanObjects();
|
||||||
|
const infoWindow = ref(infoWindowObject({}));
|
||||||
|
|
||||||
|
const openInfoWindow = (data) => {
|
||||||
|
infoWindow.value = infoWindowObject({active: true, ...data});
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
openInfoWindow
|
||||||
|
});
|
||||||
|
|
||||||
|
const emitMapClick = (data) => {
|
||||||
|
openInfoWindow(data);
|
||||||
|
emits("map-click", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
const highlightedAirspaces = ref([]);
|
||||||
|
|
||||||
|
const handleMapClick = (e) => {
|
||||||
|
const position = {lat: e.latLng.lat(), lng: e.latLng.lng()};
|
||||||
|
|
||||||
|
const airspacesUnderClick = getAirspacesAtCoordinates(position);
|
||||||
highlightedAirspaces.value = airspacesUnderClick.map(a => a.name);
|
highlightedAirspaces.value = airspacesUnderClick.map(a => a.name);
|
||||||
|
|
||||||
emits("map-click", {airspaces: airspacesUnderClick, clickCoordinates});
|
emitMapClick({position, airspaces: airspacesUnderClick});
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleReportingPointClick = (airport, reportingPoint) => {
|
const handleReportingPointClick = (airport, reportingPoint) => {
|
||||||
const position = {lat: reportingPoint.gpsLatitude, lng: reportingPoint.gpsLongitude};
|
const position = {lat: reportingPoint.gpsLatitude, lng: reportingPoint.gpsLongitude};
|
||||||
emits("map-click", {clickCoordinates: position, airport, reportingPoint})
|
|
||||||
|
const airspacesUnderClick = getAirspacesAtCoordinates(position);
|
||||||
|
highlightedAirspaces.value = [];
|
||||||
|
|
||||||
|
|
||||||
|
emitMapClick({position, airport, reportingPoint, airspaces: airspacesUnderClick})
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleAirportClick = (airport) => {
|
const handleAirportClick = (airport) => {
|
||||||
const position = {lat: airport.gpsLatitude, lng: airport.gpsLongitude};
|
const position = {lat: airport.gpsLatitude, lng: airport.gpsLongitude};
|
||||||
emits("map-click", {clickCoordinates: position, airport})
|
|
||||||
|
const airspacesUnderClick = getAirspacesAtCoordinates(position);
|
||||||
|
highlightedAirspaces.value = [];
|
||||||
|
|
||||||
|
|
||||||
|
emitMapClick({position, airport, airspaces: airspacesUnderClick})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -169,6 +188,15 @@ const handleAirportClick = (airport) => {
|
|||||||
:max-zoom="13"
|
:max-zoom="13"
|
||||||
ref="mapRef"
|
ref="mapRef"
|
||||||
>
|
>
|
||||||
|
<AirspaceInfoWindow
|
||||||
|
v-if="infoWindow.active"
|
||||||
|
:info-window="infoWindow"
|
||||||
|
:highlighted-airspaces="highlightedAirspaces"
|
||||||
|
@close="infoWindow.active=false"
|
||||||
|
@add-to-route="emits('add-to-route', $event)"
|
||||||
|
@highlight-airspace="highlightedAirspaces = [$event]"
|
||||||
|
/>
|
||||||
|
|
||||||
<template v-for="airspace in airspaces" :key="airspace.name">
|
<template v-for="airspace in airspaces" :key="airspace.name">
|
||||||
<Polygon :options="airspace" @click="handleMapClick"/>
|
<Polygon :options="airspace" @click="handleMapClick"/>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
<q-item-label>{{ title }}</q-item-label>
|
<q-item-label>{{ title }}</q-item-label>
|
||||||
<q-item-label caption>{{ caption }}</q-item-label>
|
<q-item-label caption v-if="caption">{{ caption }}</q-item-label>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
</template>
|
</template>
|
||||||
@@ -28,20 +28,15 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
|
||||||
caption: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
|
|
||||||
to: {
|
to: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
caption: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
icon: {
|
icon: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -51,7 +46,7 @@ const isButtonActive = computed(() => {
|
|||||||
const btnResolvedPath = $router.resolve(props.to).path;
|
const btnResolvedPath = $router.resolve(props.to).path;
|
||||||
|
|
||||||
if (props.to.name === 'myFlights') {
|
if (props.to.name === 'myFlights') {
|
||||||
return $route.name.toLowerCase().includes("flight");
|
return ["myFlights", "addFlight", "flightDetail", "flightEdit"].includes($route.name);
|
||||||
} else {
|
} else {
|
||||||
return $route.fullPath === btnResolvedPath || $route.fullPath.startsWith(btnResolvedPath);
|
return $route.fullPath === btnResolvedPath || $route.fullPath.startsWith(btnResolvedPath);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,14 @@ const linksList = [
|
|||||||
{
|
{
|
||||||
title: 'Moje lety',
|
title: 'Moje lety',
|
||||||
icon: "flight_takeoff",
|
icon: "flight_takeoff",
|
||||||
to: {name: "myFlights"}
|
to: {name: "myFlights"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'Moje plány',
|
||||||
|
icon: "pin_drop",
|
||||||
|
to: {name: "flightPlans"}
|
||||||
|
},
|
||||||
|
|
||||||
{separator: true},
|
{separator: true},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
export const useAirspaceColors = () => {
|
||||||
|
const colors = {
|
||||||
|
TMA: "#800080",
|
||||||
|
CTR: "#366e36",
|
||||||
|
PROHIBIT: "#FF0000",
|
||||||
|
RMZ: "#FFdd00",
|
||||||
|
RESTRICT: "#ff6a00",
|
||||||
|
DANGER: "#FFA500",
|
||||||
|
TRAGA: "#008000",
|
||||||
|
ATZ: "#4e7cfc",
|
||||||
|
FIR: '#ffffff',
|
||||||
|
PARA: "#000000"
|
||||||
|
}
|
||||||
|
|
||||||
|
const getColorByType = (airspaceType) => {
|
||||||
|
return colors[airspaceType] || '#ff00ff';
|
||||||
|
}
|
||||||
|
|
||||||
|
return {colors, getColorByType}
|
||||||
|
}
|
||||||
@@ -6,6 +6,10 @@ export const AIRSPACE_LIST = gql`
|
|||||||
airspaces {
|
airspaces {
|
||||||
name
|
name
|
||||||
type
|
type
|
||||||
|
lowerLimit
|
||||||
|
lowerAltUnit
|
||||||
|
upperLimit
|
||||||
|
upperAltUnit
|
||||||
|
|
||||||
mapBounds {
|
mapBounds {
|
||||||
lat
|
lat
|
||||||
|
|||||||
@@ -147,9 +147,9 @@ const fullscreen = ref(false);
|
|||||||
|
|
||||||
<q-checkbox v-model="formData.isDefaultName" label="Použít automatické jméno"/>
|
<q-checkbox v-model="formData.isDefaultName" label="Použít automatické jméno"/>
|
||||||
|
|
||||||
<q-checkbox v-model="formData.isPublic" label="Zveřejnit"/>
|
<!-- <q-checkbox v-model="formData.isPublic" label="Zveřejnit"/>-->
|
||||||
<q-checkbox v-model="formData.isEditableByCopilot" label="Kopilot může upravovat"/>
|
<!-- <q-checkbox v-model="formData.isEditableByCopilot" label="Kopilot může upravovat"/>-->
|
||||||
<DatetimePicker v-model="formData.plannedTakeoffDatetime" label="Datum a čas vzletu" v-bind="commonProps"/>
|
<DatetimePicker v-model="formData.plannedTakeoffDatetime" label="Plánovaný datum a čas vzletu" v-bind="commonProps"/>
|
||||||
<ComboboxInput v-model="formData.aircraft" :options="aircrafts" label="Letadlo" v-bind="commonProps"/>
|
<ComboboxInput v-model="formData.aircraft" :options="aircrafts" label="Letadlo" v-bind="commonProps"/>
|
||||||
|
|
||||||
<q-input v-model.number="formData.plannedSpeed" type="number" step="5" label="Plánovaná rychlost" v-bind="commonProps">
|
<q-input v-model.number="formData.plannedSpeed" type="number" step="5" label="Plánovaná rychlost" v-bind="commonProps">
|
||||||
|
|||||||
@@ -43,11 +43,12 @@ const routes = [
|
|||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{path: '', name: "myFlights", component: () => import('pages/profile/flight/FlightsPage.vue')},
|
{path: '', name: "myFlights", component: () => import('pages/profile/flight/FlightsPage.vue')},
|
||||||
{path: 'nastaveni', name: "profile", component: () => import('pages/profile/ProfilePage.vue')},
|
|
||||||
{path: 'lety/novy', name: "addFlight", component: () => import('pages/profile/flight/NewFlightPage.vue')},
|
{path: 'lety/novy', name: "addFlight", component: () => import('pages/profile/flight/NewFlightPage.vue')},
|
||||||
{path: 'lety/:id', name: "flightDetail", component: () => import('pages/profile/flight/FlightDetailPage.vue')},
|
{path: 'lety/:id', name: "flightDetail", component: () => import('pages/profile/flight/FlightDetailPage.vue')},
|
||||||
{path: 'lety/:id/edit/:step?', name: "flightEdit", component: () => import('pages/profile/flight/EditFlightPage.vue')},
|
{path: 'lety/:id/edit/:step?', name: "flightEdit", component: () => import('pages/profile/flight/EditFlightPage.vue')},
|
||||||
|
|
||||||
|
{path: 'nastaveni', name: "profile", component: () => import('pages/profile/ProfilePage.vue')},
|
||||||
|
|
||||||
{path: 'plany', name: "flightPlans", component: () => import('pages/profile/flightPlanner/FlightPlansPage.vue')},
|
{path: 'plany', name: "flightPlans", component: () => import('pages/profile/flightPlanner/FlightPlansPage.vue')},
|
||||||
{path: 'plany/novy', name: "newFlightPlan", component: () => import('pages/profile/flightPlanner/NewFlightPlanPage.vue')},
|
{path: 'plany/novy', name: "newFlightPlan", component: () => import('pages/profile/flightPlanner/NewFlightPlanPage.vue')},
|
||||||
{path: 'plany/:id', name: "editFlightPlan", component: () => import('pages/profile/flightPlanner/FlightPlanEditPage.vue')},
|
{path: 'plany/:id', name: "editFlightPlan", component: () => import('pages/profile/flightPlanner/FlightPlanEditPage.vue')},
|
||||||
@@ -56,10 +57,12 @@ const routes = [
|
|||||||
{path: 'poi/novy', name: "addPOI", component: () => import('pages/profile/poi/NewPointOfInterestPage.vue')},
|
{path: 'poi/novy', name: "addPOI", component: () => import('pages/profile/poi/NewPointOfInterestPage.vue')},
|
||||||
{path: 'poi/:id', name: "poiDetail", component: () => import('pages/profile/poi/PointOfInterestDetailPage.vue')},
|
{path: 'poi/:id', name: "poiDetail", component: () => import('pages/profile/poi/PointOfInterestDetailPage.vue')},
|
||||||
{path: 'poi/:id/edit/:step?', name: "poiEdit", component: () => import('pages/profile/poi/EditPointOfInterestPage.vue')},
|
{path: 'poi/:id/edit/:step?', name: "poiEdit", component: () => import('pages/profile/poi/EditPointOfInterestPage.vue')},
|
||||||
|
|
||||||
{path: 'kopiloti', name: "copilots", component: () => import('pages/profile/copilot/CopilotsPage.vue')},
|
{path: 'kopiloti', name: "copilots", component: () => import('pages/profile/copilot/CopilotsPage.vue')},
|
||||||
{path: 'kopiloti/novy', name: "addCopilot", component: () => import('pages/profile/copilot/NewCopilotPage.vue')},
|
{path: 'kopiloti/novy', name: "addCopilot", component: () => import('pages/profile/copilot/NewCopilotPage.vue')},
|
||||||
{path: 'kopiloti/:id', name: "copilotDetail", component: () => import('pages/profile/copilot/CopilotDetailPage.vue')},
|
{path: 'kopiloti/:id', name: "copilotDetail", component: () => import('pages/profile/copilot/CopilotDetailPage.vue')},
|
||||||
{path: 'kopiloti/:id/edit/:step?', name: "copilotEdit", component: () => import('pages/profile/copilot/EditCopilotPage.vue')},
|
{path: 'kopiloti/:id/edit/:step?', name: "copilotEdit", component: () => import('pages/profile/copilot/EditCopilotPage.vue')},
|
||||||
|
|
||||||
{path: 'letadla', name: "aircrafts", component: () => import('pages/profile/aircraft/AircraftsPage.vue')},
|
{path: 'letadla', name: "aircrafts", component: () => import('pages/profile/aircraft/AircraftsPage.vue')},
|
||||||
{path: 'letadla/nove', name: "addAircraft", component: () => import('pages/profile/aircraft/NewAircraftsPage.vue')},
|
{path: 'letadla/nove', name: "addAircraft", component: () => import('pages/profile/aircraft/NewAircraftsPage.vue')},
|
||||||
{path: 'letadla/:id', name: "aircraftDetail", component: () => import('pages/profile/aircraft/AircraftDetailPage.vue')},
|
{path: 'letadla/:id', name: "aircraftDetail", component: () => import('pages/profile/aircraft/AircraftDetailPage.vue')},
|
||||||
|
|||||||
Reference in New Issue
Block a user