128 lines
4.4 KiB
Vue
128 lines
4.4 KiB
Vue
<script>
|
|
import {useFlightPlansStore} from "stores/FlightPlans";
|
|
|
|
export default {
|
|
preFetch({store, currentRoute}) {
|
|
return useFlightPlansStore(store).fetchPublicDetail({
|
|
id: currentRoute.params.id,
|
|
username: currentRoute.params.username
|
|
})
|
|
}
|
|
}
|
|
</script>
|
|
<script setup>
|
|
import {storeToRefs} from "pinia";
|
|
import {useAppStore} from "stores/App";
|
|
import {publicProfileBreadcrumbs} from "src/composables/breadcrumbs";
|
|
import FlightPlanMap from "components/flightPlans/FlightPlanMap.vue";
|
|
import {computed, onMounted, ref} from "vue";
|
|
import {useAirspacesStore} from "stores/Airspaces";
|
|
import {usePointsOfInterestStore} from "stores/PointsOfInterest";
|
|
import {useAirportsStore} from "stores/Airports";
|
|
import {formatDatetime, minutesToHumanReadable} from "src/composables/datetimeUtils";
|
|
import {useFlightPlanCalculations, useFlightPlanUtils} from "src/composables/flightPlan";
|
|
import FlightPlanRouteTable from "components/flightPlans/FlightPlanRouteTable.vue";
|
|
import {useMeta} from "quasar";
|
|
import {metaData} from "src/composables/meta";
|
|
|
|
const props = defineProps({
|
|
pilot: {
|
|
type: Object,
|
|
required: true
|
|
}
|
|
});
|
|
|
|
const {flightPlan} = storeToRefs(useFlightPlansStore());
|
|
|
|
useAppStore().setPageTitle(flightPlan.value.name);
|
|
useMeta(() => metaData({
|
|
title: `Plán: ${flightPlan.value.name}`,
|
|
keywords: [flightPlan.value.name, "plán", "trasa", "navigace", "štítek", "mapa", flightPlan.value.aircraft?.callSign],
|
|
description: flightPlan.value.description,
|
|
}));
|
|
useAppStore().setBreadcrumbs([
|
|
...publicProfileBreadcrumbs(props.pilot),
|
|
{label: `Plán: ${flightPlan.value.name}`},
|
|
]);
|
|
|
|
|
|
onMounted(() => {
|
|
useAirspacesStore().fetch();
|
|
usePointsOfInterestStore().fetchPublic({limit: 10000});
|
|
useAirportsStore().fetch();
|
|
});
|
|
|
|
const {pointsOfInterest} = storeToRefs(usePointsOfInterestStore());
|
|
const {airspaces: airspacesData, areAirspacesLoading: isQueryRunning} = storeToRefs(useAirspacesStore())
|
|
const {airports} = storeToRefs(useAirportsStore());
|
|
|
|
const {getMarkersFrom} = useFlightPlanUtils();
|
|
|
|
const usedPointsOfInterest = computed(() => {
|
|
const poisInTrackIds = getMarkersFrom(flightPlan.value).filter(m => !!m.pointOfInterestId).map(poi => poi.pointOfInterestId);
|
|
return pointsOfInterest.value.filter(poi => poisInTrackIds.includes(poi.id))
|
|
});
|
|
|
|
const openedTab = ref("map");
|
|
|
|
const {getTotalDistance, getTotalDuration} = useFlightPlanCalculations();
|
|
|
|
const showInfoCard = computed(() => flightPlan.value.aircraft || flightPlan.value.plannedTakeoffDatetime || flight.value.description);
|
|
</script>
|
|
|
|
<template>
|
|
<q-tabs v-model="openedTab">
|
|
<q-tab name="map">Mapa</q-tab>
|
|
<q-tab name="trackTable">Trasa</q-tab>
|
|
<q-tab name="info" v-if="showInfoCard">Informace</q-tab>
|
|
</q-tabs>
|
|
|
|
<q-tab-panels v-model="openedTab" class="q-mb-lg">
|
|
<q-tab-panel name="map">
|
|
<FlightPlanMap
|
|
:airspace-data="airspacesData"
|
|
:airports="airports"
|
|
:points-of-interest="usedPointsOfInterest"
|
|
:flight-plan="flightPlan"
|
|
/>
|
|
<div class="row">
|
|
<div class="col">
|
|
<q-chip size="lg">
|
|
<q-icon class="q-mx-md" name="mdi-map-marker-distance"/>
|
|
{{ getTotalDistance(flightPlan) }} km
|
|
</q-chip>
|
|
|
|
</div>
|
|
<div class="col text-right">
|
|
<q-chip size="lg">
|
|
<q-icon name="mdi-clock-outline"/>
|
|
{{ minutesToHumanReadable(getTotalDuration(flightPlan, flightPlan.plannedSpeed)) }}
|
|
</q-chip>
|
|
</div>
|
|
</div>
|
|
|
|
</q-tab-panel>
|
|
<q-tab-panel name="trackTable">
|
|
<FlightPlanRouteTable :planned-speed="flightPlan.plannedSpeed" :flight-plan="flightPlan"/>
|
|
</q-tab-panel>
|
|
<q-tab-panel name="info" v-if="showInfoCard">
|
|
<div v-if="flightPlan.plannedTakeoffDatetime">
|
|
Plánovaný vzlet: {{ formatDatetime(flightPlan.plannedTakeoffDatetime) }}
|
|
<br>
|
|
</div>
|
|
<div v-if="flightPlan.aircraft">
|
|
<q-avatar v-if="flightPlan.aircraft.titlePhoto" class="q-ma-md">
|
|
<img :src="flightPlan.aircraft.titlePhoto.thumbnailUrl" alt=""/>
|
|
</q-avatar>
|
|
<router-link v-if="flightPlan.aircraft.isPublic" :to="{name: 'publicAircraftDetail', params: {callSign: flightPlan.aircraft.callSign}}">
|
|
{{ flightPlan.aircraft.callSign }}
|
|
</router-link>
|
|
<template v-else>
|
|
{{ flightPlan.aircraft.callSign }}
|
|
</template>
|
|
</div>
|
|
<div v-html="flightPlan.description"/>
|
|
</q-tab-panel>
|
|
</q-tab-panels>
|
|
</template>
|