Rozdeleni planovace do samostatnych routes

This commit is contained in:
Michal Kváček
2024-09-30 06:43:58 +02:00
parent 786c59cc4a
commit 86e8dbf8e7
12 changed files with 395 additions and 303 deletions
+1 -1
View File
@@ -37,7 +37,7 @@
"autoprefixer": "^10.4.16",
"eslint": "^8.55.0",
"eslint-config-prettier": "^8.10.0",
"eslint-plugin-vue": "^9.19.2",
"eslint-plugin-vue": "^9.28.0",
"postcss": "^8.4.14",
"prettier": "^2.8.8"
},
@@ -1,9 +1,9 @@
<script setup>
import DatetimePicker from "components/inputs/DatetimePicker.vue";
import {computed, reactive} from "vue";
import {reactive} from "vue";
import {commonProps} from "src/composables/inputs";
import FormWrapper from "components/FormWrapper.vue";
import {useFlightPlanCalculations, useFlightPlanUtils} from "src/composables/flightPlan";
import {useFlightPlanCalculations} from "src/composables/flightPlan";
const props = defineProps({
flightPlan: {
@@ -17,18 +17,13 @@ const {getTotalDuration} = useFlightPlanCalculations();
const formData = reactive({
gpxTrackFile: null,
takeoffDatetime: props.flightPlan.plannedTakeoffDatetime,
landingDatetime: new Date((new Date(props.flightPlan.plannedTakeoffDatetime)).getTime() + 60 * 1000 * getTotalDuration(props.flightPlan)),
landingDatetime: new Date(
(new Date(props.flightPlan.plannedTakeoffDatetime)).getTime() + 60 * 1000 * getTotalDuration(props.flightPlan)
),
copyTrack: true,
createPointsOfInterests: true,
flightPlan: props.flightPlan,
});
const {getMarkersFrom} = useFlightPlanUtils();
const hasGeocodeInTrack = computed(() => {
return !!getMarkersFrom(props.flightPlan).find(point => point.type === 'geocode');
});
</script>
<template>
@@ -1,12 +1,9 @@
<script setup>
import {computed} from "vue";
import {textEllipsis} from "src/composables/utils";
import {minutesToHumanReadable} from "src/composables/datetimeUtils";
import {useFlightPlanUtils} from "src/composables/flightPlan";
import {useQuasar} from "quasar";
import {useUnitsConvertors} from "src/composables/units";
import CloudCoverIcon from "components/weather/CloudCoverIcon.vue";
import {formatDatetime} from "src/composables/datetimeUtils";
const props = defineProps({
flightPlan: {
@@ -17,7 +14,6 @@ const props = defineProps({
const columns = [
{
label: 'Místo',
align: "left",
@@ -42,9 +38,17 @@ const columns = [
const {screen} = useQuasar();
const {getMarkersFrom} = useFlightPlanUtils();
const {kmhToKnots} = useUnitsConvertors();
const {kmhToKnots, ftToM} = useUnitsConvertors();
const getCloudsBase = (weatherInfo) => {
const tempDiff = weatherInfo.temperatureSurface - weatherInfo.dewpointSurface;
const cloudLevelInFt = tempDiff / 2.5 * 1000;
return Math.round(ftToM(cloudLevelInFt));
}
const markers = getMarkersFrom(props.flightPlan);
const markersWithWeather = markers.filter(marker => !!marker.weatherInfo);
</script>
<template>
@@ -54,13 +58,19 @@ const markers = getMarkersFrom(props.flightPlan);
flat bordered
hide-bottom
:title="flightPlan.name"
:rows="markers"
:rows="markersWithWeather"
:columns="columns"
:rows-per-page-options="[0]"
>
<template v-slot:body-cell-place="props">
<q-td :props="props">
{{ props.row.name }}
<strong>
{{ props.row.name }}
</strong>
<br>
<small>
{{ formatDatetime(props.row.weatherInfo.datetime) }}
</small>
</q-td>
</template>
@@ -68,14 +78,15 @@ const markers = getMarkersFrom(props.flightPlan);
<q-td :props="props">
{{ props.row.weatherInfo.temperatureSurface }}° C
<br>
Rosný bod {{ props.row.weatherInfo.dewpointSurface }}° C
<small>
Rosný bod {{ props.row.weatherInfo.dewpointSurface }}° C
</small>
</q-td>
</template>
<template v-slot:body-cell-wind="props">
<q-td :props="props">
<q-icon name="navigation" :style="`transform: rotate(${props.row.weatherInfo.windDirectionSurface}deg)`"/>
<br>
{{ props.row.weatherInfo.windDirectionSurface }}°
<br>
{{ kmhToKnots(props.row.weatherInfo.windSpeedSurface) }} kt
@@ -84,11 +95,16 @@ const markers = getMarkersFrom(props.flightPlan);
<template v-slot:body-cell-clouds="props">
<q-td :props="props">
<CloudCoverIcon :cloudcover="props.row.weatherInfo.cloudcoverTotal"/>
<CloudCoverIcon :cloudcover="props.row.weatherInfo.cloudcoverTotal"/>
<br>
celkové pokrytí oblačností {{ props.row.weatherInfo.cloudcoverTotal }} %
<br>
nízké mraky {{ props.row.weatherInfo.cloudcoverLow }} %
<template v-if="props.row.weatherInfo.cloudcoverLow > 5">
<br>
odhadovaná výška základen: {{ getCloudsBase(props.row.weatherInfo) }} m
</template>
</q-td>
</template>
+6 -1
View File
@@ -4,5 +4,10 @@ export const useUnitsConvertors = () => {
return Math.round(speedKmh * 0.53996);
}
return {kmhToKnots}
const ftToM = (distanceInFt) => {
return Math.round(distanceInFt * 0.3048 * 10) / 10;
}
return {kmhToKnots, ftToM}
}
@@ -9,276 +9,34 @@ export default {
</script>
<script setup>
import {computed, onMounted, ref} from "vue";
import {usePointsOfInterestStore} from "stores/PointsOfInterest";
import {computed} from "vue";
import {storeToRefs} from "pinia";
import {useAirspacesStore} from "stores/Airspaces";
import {useAirportsStore} from "stores/Airports";
import {useAppStore} from "stores/App";
import {useFlightPlanObjects, useFlightPlanUtils} from "src/composables/flightPlan";
import FlightPlanMap from "components/flightPlans/FlightPlanMap.vue";
import FlightPlanRoute from "components/flightPlans/FlightPlanRoute.vue";
import FlightPlanSideControls from "components/flightPlans/FlightPlanSideControls.vue";
import {useAircraftsStore} from "stores/Aircrafts";
import {errorObject, successObject} from "src/composables/dialog";
import {useQuasar} from "quasar";
import FlightPlanNavLogTable from "components/flightPlans/FlightPlanNavLogTable.vue";
import FlightPlanForm from "components/flightPlans/FlightPlanForm.vue";
import {useFlightsStore} from "stores/Flights";
import {useRouter} from "vue-router";
import FlightFromPlanForm from "components/flightPlans/FlightFromPlanForm.vue";
import BasicInfoBanner from "components/banners/BasicInfoBanner.vue";
import FlightPlanWeatherInfo from "components/flightPlans/FlightPlanWeatherInfo.vue";
const {flightPlan} = storeToRefs(useFlightPlansStore());
const flightPlanName = computed(() => flightPlan.value.name || "Nepojmenovaný plán");
useAppStore().setPageTitle(`${flightPlanName.value} - plánovnání`);
useAppStore().setBreadcrumbs([
{to: {name: "flightPlans"}, label: "Moje plány"},
{label: flightPlanName.value},
]);
onMounted(() => {
useAirspacesStore().fetch();
useAircraftsStore().fetch({});
usePointsOfInterestStore().fetch({limit: 10000});
useAirportsStore().fetch();
const displayedTabs = computed(() => {
const tabs = [
{label: "Trasa", route: "editFlightPlan", icon: "route"},
{label: "Informace", route: "editFlightPlanInfo", icon: "info"},
{label: "Počasí", route: "editFlightPlanWeather", icon: "mdi-weather-windy"}, // TODO: jen pokud se povedlo nejake pocasi stahnout
{label: "Navigační štítek", route: "editFlightPlanNavlog", icon: "navigation"},
];
if (flightPlan.value.aircraft) {
tabs.push({label: "Let", route: "flightPlanFlight", icon: "flight"})
}
return tabs;
});
const {pointsOfInterest} = storeToRefs(usePointsOfInterestStore());
const {airspaces: airspacesData, areAirspacesLoading: isQueryRunning} = storeToRefs(useAirspacesStore())
const {airports} = storeToRefs(useAirportsStore());
const {aircrafts: aircraftsData} = storeToRefs(useAircraftsStore());
const aircrafts = computed(() => aircraftsData.value.map(a => ({id: a.id, name: a.callSign})));
const {getMarkersFrom} = useFlightPlanUtils();
const {markerObject} = useFlightPlanObjects();
const openedTab = ref("route");
const flightPlannerDialogOpen = ref(false);
const flightPlanMarkers = ref(getMarkersFrom(flightPlan.value));
const handleMarkersChanges = (markers) => {
flightPlanMarkers.value = markers;
useFlightPlansStore().update(flightPlan.value.id, {
markers: markers.map(m => markerObject({
name: m.name,
type: m.type,
airportId: m.airportId,
pointOfInterestId: m.pointOfInterestId,
gpsLatitude: m.gpsLatitude,
gpsLongitude: m.gpsLongitude,
}))
});
};
const $q = useQuasar();
const handleFlightPlanInfoSave = (formData) => {
useFlightPlansStore().update(flightPlan.value.id, formData).then(() => {
$q.notify(successObject("Informace úspěšně uloženy"));
})
}
const insertAtPosition = ref(flightPlanMarkers.value.length);
const fullscreen = ref(false);
const takeoffAirport = computed(() => {
const markers = getMarkersFrom(flightPlan.value)
return markers[0].type === 'airport' ? markers[0] : null;
})
const landingAirport = computed(() => {
const markers = getMarkersFrom(flightPlan.value);
const lastMarker = markers[markers.length - 1];
return lastMarker.type === 'airport' ? lastMarker : null;
})
const $router = useRouter();
const createNewFlightFromPlan = (formData) => {
const markers = getMarkersFrom(formData.flightPlan);
const takeoff = markers.shift();
const landing = markers.pop();
if ((takeoff.type !== 'airport' || landing.type !== 'airport') && !formData.gpxTrackFile) {
$q.notify(errorObject("Zkontroluj letiště vzletu a přistání. Aktuálně zvolené hodnoty se jako letiště nezdají. Pro pokračování uprav buď plán, nebo zkus nahrát trasu v GPX."));
return;
}
const track = [];
if (formData.copyTrack) {
// TODO: po ulozeni mapPoint/geocode??? upravit i trasu v planu - predelat ten mapPoint na POI s IDckem
for (const i in markers) {
const marker = markers[i];
if (i === 0 || i === markers.length - 1 || marker.type === 'mapPoint') continue;
const obj = {
[marker.type === 'airport' ? 'airport' : 'pointOfInterest']: {
id: marker.airportId || marker.pointOfInterestId || null,
name: marker.name,
},
gpsLatitude: marker.gpsLatitude,
gpsLongitude: marker.gpsLongitude
};
track.push(obj);
}
}
useFlightsStore().create({
name: formData.flightPlan.name,
aircraft: {id: formData.flightPlan.aircraft.id, name: formData.flightPlan.aircraft.callSign},
flightPlanId: formData.flightPlan.id,
takeoffAirport: takeoff ? {id: takeoff.airportId, name: takeoff.name} : null,
landingAirport: landing ? {id: landing.airportId, name: landing.name} : null,
gpxTrackFile: formData.gpxTrackFile,
takeoffDatetime: formData.takeoffDatetime,
landingDatetime: formData.landingDatetime,
track
}).then(res => {
$q.notify(successObject("Let úspěšně vytvořen. Nyní můžeš nastavit detaily."))
$router.push({name: 'flightEdit', params: {id: res.id, step: 'photo'}});
});
}
</script>
<template>
<q-tabs v-model="openedTab">
<q-tab name="route">
<q-icon name="route"/>
Trasa
</q-tab>
<q-tab name="info">
<q-icon name="info"/>
Informace
</q-tab>
<q-tab name="weather">
<q-icon name="mdi-weather-windy"/>
Počasí
</q-tab>
<q-tab name="navLog">
<q-icon name="navigation"/>
Navigační štítek
</q-tab>
<q-tab name="flight" v-if="flightPlan.aircraft">
<q-icon name="flight"/>
Let
</q-tab>
<q-tabs>
<q-route-tab v-for="tab in displayedTabs" :key="tab.route" replace exact :to="{name: tab.route, params: {id: flightPlan.id}}">
<q-icon :name="tab.icon"/>
{{ tab.label }}
</q-route-tab>
</q-tabs>
<q-tab-panels v-model="openedTab">
<q-tab-panel name="route">
<div :class="{row: true, fullscreen}">
<div class="col map--wrapper" style="min-width: 1px">
<FlightPlanMap
class="map"
:insert-position="insertAtPosition"
:airspace-data="airspacesData"
:airports="airports"
:points-of-interest="pointsOfInterest"
:flight-plan="flightPlan"
@change-insert-position="insertAtPosition = $event"
@markers-changed="handleMarkersChanges"
/>
</div>
<div class="col-12 col-md-3 col-lg-2 markers-control">
<FlightPlanSideControls
:is-fullscreen="fullscreen"
:insert-position="insertAtPosition"
:flight-plan="flightPlan"
@change-insert-position="insertAtPosition = $event"
@open="flightPlannerDialogOpen=true"
@fullscreen-toggle="fullscreen = !fullscreen"
/>
</div>
</div>
</q-tab-panel>
<q-tab-panel name="info">
<div class="row">
<div class="col">
<FlightPlanForm
:aircrafts="aircrafts"
:flight-plan="flightPlan"
@save="handleFlightPlanInfoSave"
/>
</div>
</div>
</q-tab-panel>
<q-tab-panel name="navLog">
<FlightPlanNavLogTable
:flight-plan="flightPlan"
:planned-speed="flightPlan.plannedSpeed"
/>
</q-tab-panel>
<q-tab-panel name="weather">
<FlightPlanWeatherInfo :flight-plan="flightPlan" />
</q-tab-panel>
<q-tab-panel name="flight" v-if="flightPlan.aircraft">
<BasicInfoBanner v-if="!takeoffAirport || !landingAirport" color="error">
V plánu nemáš žádné letiště vzletu nebo přistání. Pro import letu musíš nahrát trasu.
</BasicInfoBanner>
<FlightFromPlanForm
:flight-plan="flightPlan"
@save="createNewFlightFromPlan"
/>
</q-tab-panel>
</q-tab-panels>
<q-dialog full-width v-model="flightPlannerDialogOpen">
<q-card>
<q-card-section class="row items-center q-pb-none">
<div class="text-h6">Přidat otočný bod</div>
<q-space/>
<q-btn icon="close" flat round dense v-close-popup/>
</q-card-section>
<q-card-section class="q-pt-none">
<FlightPlanRoute
:markers="flightPlanMarkers"
:points-of-interest="pointsOfInterest"
:airports="airports"
@markers-changed="handleMarkersChanges"
/>
</q-card-section>
<q-card-actions align="right" class="text-primary">
<q-btn flat label="Hotovo" v-close-popup/>
</q-card-actions>
</q-card>
</q-dialog>
<router-view :flight-plan-name="flightPlanName" :flight-plan="flightPlan"/>
</template>
<style lang="scss" scoped>
.fullscreen {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
z-index: 2001;
.map--wrapper {
height: 100%;
.map {
height: 100vh !important;
}
}
.markers-control {
background: white;
}
}
</style>
@@ -0,0 +1,90 @@
<script setup>
import BasicInfoBanner from "components/banners/BasicInfoBanner.vue";
import FlightFromPlanForm from "components/flightPlans/FlightFromPlanForm.vue";
import {computed} from "vue";
import {useRouter} from "vue-router";
import {errorObject, successObject} from "src/composables/dialog";
import {useFlightsStore} from "stores/Flights";
import {useFlightPlanUtils} from "src/composables/flightPlan";
import {useQuasar} from "quasar";
const props = defineProps({
flightPlan: {
type: Object,
required: true
}
});
const {getMarkersFrom} = useFlightPlanUtils();
const takeoffAirport = computed(() => {
const markers = getMarkersFrom(props.flightPlan)
return markers[0].type === 'airport' ? markers[0] : null;
})
const landingAirport = computed(() => {
const markers = getMarkersFrom(props.flightPlan);
const lastMarker = markers[markers.length - 1];
return lastMarker.type === 'airport' ? lastMarker : null;
})
const $q = useQuasar();
const $router = useRouter();
const createNewFlightFromPlan = (formData) => {
const markers = getMarkersFrom(formData.flightPlan);
const takeoff = markers.shift();
const landing = markers.pop();
if ((takeoff.type !== 'airport' || landing.type !== 'airport') && !formData.gpxTrackFile) {
$q.notify(errorObject("Zkontroluj letiště vzletu a přistání. Aktuálně zvolené hodnoty se jako letiště nezdají. Pro pokračování uprav buď plán, nebo zkus nahrát trasu v GPX."));
return;
}
const track = [];
if (formData.copyTrack) {
// TODO: po ulozeni mapPoint/geocode??? upravit i trasu v planu - predelat ten mapPoint na POI s IDckem
for (const i in markers) {
const marker = markers[i];
if (i === 0 || i === markers.length - 1 || marker.type === 'mapPoint') continue;
const obj = {
[marker.type === 'airport' ? 'airport' : 'pointOfInterest']: {
id: marker.airportId || marker.pointOfInterestId || null,
name: marker.name,
},
gpsLatitude: marker.gpsLatitude,
gpsLongitude: marker.gpsLongitude
};
track.push(obj);
}
}
useFlightsStore().create({
name: formData.flightPlan.name,
aircraft: {id: formData.flightPlan.aircraft.id, name: formData.flightPlan.aircraft.callSign},
flightPlanId: formData.flightPlan.id,
takeoffAirport: takeoff ? {id: takeoff.airportId, name: takeoff.name} : null,
landingAirport: landing ? {id: landing.airportId, name: landing.name} : null,
gpxTrackFile: formData.gpxTrackFile,
takeoffDatetime: formData.takeoffDatetime,
landingDatetime: formData.landingDatetime,
track
}).then(res => {
$q.notify(successObject("Let úspěšně vytvořen. Nyní můžeš nastavit detaily."))
$router.push({name: 'flightEdit', params: {id: res.id, step: 'copilot'}});
});
}
</script>
<template>
<BasicInfoBanner v-if="!takeoffAirport || !landingAirport" color="error">
V plánu nemáš žádné letiště vzletu nebo přistání. Pro import letu musíš nahrát trasu.
</BasicInfoBanner>
<FlightFromPlanForm
:flight-plan="flightPlan"
@save="createNewFlightFromPlan"
/>
</template>
@@ -0,0 +1,37 @@
<script setup>
import FlightPlanForm from "components/flightPlans/FlightPlanForm.vue";
import {useQuasar} from "quasar";
import {successObject} from "src/composables/dialog";
import {useFlightPlansStore} from "stores/FlightPlans";
import {storeToRefs} from "pinia";
import {useAircraftsStore} from "stores/Aircrafts";
import {onMounted} from "vue";
const props = defineProps({
flightPlan: {
type: Object,
required: true
}
});
onMounted(() => {
useAircraftsStore().fetch({});
});
const {aircrafts} = storeToRefs(useAircraftsStore());
const $q = useQuasar();
const handleFlightPlanInfoSave = (formData) => {
useFlightPlansStore().update(props.flightPlan.value.id, formData).then(() => {
$q.notify(successObject("Informace úspěšně uloženy"));
})
}
</script>
<template>
<FlightPlanForm
:aircrafts="aircrafts"
:flight-plan="flightPlan"
@save="handleFlightPlanInfoSave"
/>
</template>
@@ -0,0 +1,142 @@
<script setup>
import FlightPlanMap from "components/flightPlans/FlightPlanMap.vue";
import FlightPlanSideControls from "components/flightPlans/FlightPlanSideControls.vue";
import {computed, onMounted, ref} from "vue";
import {useAirspacesStore} from "stores/Airspaces";
import {useAircraftsStore} from "stores/Aircrafts";
import {usePointsOfInterestStore} from "stores/PointsOfInterest";
import {useAirportsStore} from "stores/Airports";
import {storeToRefs} from "pinia";
import {useFlightPlanObjects, useFlightPlanUtils} from "src/composables/flightPlan";
import {useFlightPlansStore} from "stores/FlightPlans";
import FlightPlanRoute from "components/flightPlans/FlightPlanRoute.vue";
import {useAppStore} from "stores/App";
onMounted(() => {
useAirspacesStore().fetch();
useAircraftsStore().fetch({});
usePointsOfInterestStore().fetch({limit: 10000});
useAirportsStore().fetch();
});
const props = defineProps({
flightPlan: {
type: Object,
required: true
},
flightPlanName: {
type: String,
required: true
}
});
useAppStore().setPageTitle(`${props.flightPlanName} - plánovnání`);
useAppStore().setBreadcrumbs([
{to: {name: "flightPlans"}, label: "Moje plány"},
{label: props.flightPlanName},
]);
const {pointsOfInterest} = storeToRefs(usePointsOfInterestStore());
const {airspaces: airspacesData, areAirspacesLoading: isQueryRunning} = storeToRefs(useAirspacesStore())
const {airports} = storeToRefs(useAirportsStore());
const {aircrafts: aircraftsData} = storeToRefs(useAircraftsStore());
const aircrafts = computed(() => aircraftsData.value.map(a => ({id: a.id, name: a.callSign})));
const {getMarkersFrom} = useFlightPlanUtils();
const {markerObject} = useFlightPlanObjects();
const flightPlanMarkers = ref(getMarkersFrom(props.flightPlan));
const handleMarkersChanges = (markers) => {
flightPlanMarkers.value = markers;
useFlightPlansStore().update(props.flightPlan.id, {
markers: markers.map(m => markerObject({
name: m.name,
type: m.type,
airportId: m.airportId,
pointOfInterestId: m.pointOfInterestId,
gpsLatitude: m.gpsLatitude,
gpsLongitude: m.gpsLongitude,
}))
});
};
const insertAtPosition = ref(flightPlanMarkers.value.length);
const fullscreen = ref(false);
const flightPlannerDialogOpen = ref(false);
</script>
<template>
<div :class="{row: true, fullscreen}">
<div class="col map--wrapper" style="min-width: 1px">
<FlightPlanMap
class="map"
:insert-position="insertAtPosition"
:airspace-data="airspacesData"
:airports="airports"
:points-of-interest="pointsOfInterest"
:flight-plan="flightPlan"
@change-insert-position="insertAtPosition = $event"
@markers-changed="handleMarkersChanges"
/>
</div>
<div class="col-12 col-md-3 col-lg-2 markers-control">
<FlightPlanSideControls
:is-fullscreen="fullscreen"
:insert-position="insertAtPosition"
:flight-plan="flightPlan"
@change-insert-position="insertAtPosition = $event"
@open="flightPlannerDialogOpen=true"
@fullscreen-toggle="fullscreen = !fullscreen"
/>
</div>
</div>
<q-dialog full-width v-model="flightPlannerDialogOpen">
<q-card>
<q-card-section class="row items-center q-pb-none">
<div class="text-h6">Přidat otočný bod</div>
<q-space/>
<q-btn icon="close" flat round dense v-close-popup/>
</q-card-section>
<q-card-section class="q-pt-none">
<FlightPlanRoute
:markers="flightPlanMarkers"
:points-of-interest="pointsOfInterest"
:airports="airports"
@markers-changed="handleMarkersChanges"
/>
</q-card-section>
<q-card-actions align="right" class="text-primary">
<q-btn flat label="Hotovo" v-close-popup/>
</q-card-actions>
</q-card>
</q-dialog>
</template>
<style lang="scss" scoped>
.fullscreen {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
z-index: 2001;
.map--wrapper {
height: 100%;
.map {
height: 100vh !important;
}
}
.markers-control {
background: white;
}
}
</style>
@@ -0,0 +1,18 @@
<script setup>
import FlightPlanNavLogTable from "components/flightPlans/FlightPlanNavLogTable.vue";
const props = defineProps({
flightPlan: {
type: Object,
required: true
}
});
</script>
<template>
<FlightPlanNavLogTable
:flight-plan="flightPlan"
:planned-speed="flightPlan.plannedSpeed"
/>
</template>
@@ -0,0 +1,15 @@
<script setup>
import FlightPlanWeatherInfo from "components/flightPlans/FlightPlanWeatherInfo.vue";
const props = defineProps({
flightPlan: {
type: Object,
required: true
}
});
</script>
<template>
<FlightPlanWeatherInfo :flight-plan="flightPlan"/>
</template>
+11 -1
View File
@@ -59,7 +59,17 @@ const routes = [
{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/:id', name: "editFlightPlan", component: () => import('pages/profile/flightPlanner/FlightPlanEditPage.vue')},
{
path: 'plany/:id',
component: () => import('pages/profile/flightPlanner/FlightPlanEditPage.vue'),
children: [
{path: '', name: "editFlightPlan", component: () => import('pages/profile/flightPlanner/FlightPlanMapPage.vue')},
{path: 'pocasi', name: "editFlightPlanWeather", component: () => import('pages/profile/flightPlanner/FlightPlanWeatherPage.vue')},
{path: 'info', name: "editFlightPlanInfo", component: () => import('pages/profile/flightPlanner/FlightPlanInfoPage.vue')},
{path: 'let', name: "flightPlanFlight", component: () => import('pages/profile/flightPlanner/FlightPlanFlightPage.vue')},
{path: 'stitek', name: "editFlightPlanNavlog", component: () => import('pages/profile/flightPlanner/FlightPlanNavlogPage.vue')},
]
},
{path: 'poi', name: "poi", component: () => import('pages/profile/poi/PointsOfInterestPage.vue')},
{path: 'poi/novy', name: "addPOI", component: () => import('pages/profile/poi/NewPointOfInterestPage.vue')},
+23 -17
View File
@@ -1632,17 +1632,18 @@ eslint-config-prettier@^8.10.0:
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz#3a06a662130807e2502fc3ff8b4143d8a0658e11"
integrity sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==
eslint-plugin-vue@^9.19.2:
version "9.19.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-9.19.2.tgz#7ab83a001a1ac8bccae013c5b9cb5d2c644fb376"
integrity sha512-CPDqTOG2K4Ni2o4J5wixkLVNwgctKXFu6oBpVJlpNq7f38lh9I80pRTouZSJ2MAebPJlINU/KTFSXyQfBUlymA==
eslint-plugin-vue@^9.28.0:
version "9.28.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-9.28.0.tgz#e4412f0c1024bafd15ffeaa6f76f4c99152e2765"
integrity sha512-ShrihdjIhOTxs+MfWun6oJWuk+g/LAhN+CiuOl/jjkG3l0F2AuK5NMTaWqyvBgkFtpYmyks6P4603mLmhNJW8g==
dependencies:
"@eslint-community/eslint-utils" "^4.4.0"
globals "^13.24.0"
natural-compare "^1.4.0"
nth-check "^2.1.1"
postcss-selector-parser "^6.0.13"
semver "^7.5.4"
vue-eslint-parser "^9.3.1"
postcss-selector-parser "^6.0.15"
semver "^7.6.3"
vue-eslint-parser "^9.4.3"
xml-name-validator "^4.0.0"
eslint-scope@^7.1.1, eslint-scope@^7.2.2:
@@ -1989,7 +1990,7 @@ glob@^7.1.3, glob@^7.1.4, glob@^7.2.3:
once "^1.3.0"
path-is-absolute "^1.0.0"
globals@^13.19.0:
globals@^13.19.0, globals@^13.24.0:
version "13.24.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171"
integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==
@@ -2755,10 +2756,10 @@ pinia@^2.0.33:
"@vue/devtools-api" "^6.5.0"
vue-demi ">=0.14.5"
postcss-selector-parser@^6.0.13:
version "6.0.13"
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b"
integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==
postcss-selector-parser@^6.0.15:
version "6.1.2"
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de"
integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==
dependencies:
cssesc "^3.0.0"
util-deprecate "^1.0.2"
@@ -3042,13 +3043,18 @@ semver@^7.3.5:
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.1.tgz#60bfe090bf907a25aa8119a72b9f90ef7ca281b2"
integrity sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==
semver@^7.3.6, semver@^7.5.4:
semver@^7.3.6:
version "7.5.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
dependencies:
lru-cache "^6.0.0"
semver@^7.6.3:
version "7.6.3"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143"
integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==
send@0.18.0:
version "0.18.0"
resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
@@ -3424,10 +3430,10 @@ vue-demi@^0.13.1:
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.13.11.tgz#7d90369bdae8974d87b1973564ad390182410d99"
integrity sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==
vue-eslint-parser@^9.3.1:
version "9.3.2"
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-9.3.2.tgz#6f9638e55703f1c77875a19026347548d93fd499"
integrity sha512-q7tWyCVaV9f8iQyIA5Mkj/S6AoJ9KBN8IeUSf3XEmBrOtxOZnfTg5s4KClbZBCK3GtnT/+RyCLZyDHuZwTuBjg==
vue-eslint-parser@^9.4.3:
version "9.4.3"
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz#9b04b22c71401f1e8bca9be7c3e3416a4bde76a8"
integrity sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==
dependencies:
debug "^4.3.4"
eslint-scope "^7.1.1"