Pridani linku na planovac do menu, drobny bugfixing

This commit is contained in:
Michal Kváček
2024-05-06 09:40:25 +02:00
parent be8966b5c1
commit 670e80d998
12 changed files with 245 additions and 98 deletions
+57
View File
@@ -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>
+7 -22
View File
@@ -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>
+4 -1
View File
@@ -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.");
+53 -7
View File
@@ -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>
+59 -31
View File
@@ -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>
+5 -10
View File
@@ -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},
{ {
+20
View File
@@ -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}
}
+4
View File
@@ -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">
+4 -1
View File
@@ -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')},