Pridani tabulky s necim jako navigacni stitek do planovace
This commit is contained in:
@@ -0,0 +1,51 @@
|
|||||||
|
<script setup>
|
||||||
|
import {commonProps} from "src/composables/inputs";
|
||||||
|
import DatetimePicker from "components/inputs/DatetimePicker.vue";
|
||||||
|
import ComboboxInput from "components/inputs/ComboboxInput.vue";
|
||||||
|
import FormWrapper from "components/FormWrapper.vue";
|
||||||
|
import {onMounted, reactive} from "vue";
|
||||||
|
import {setDefaultData} from "src/composables/form/formHandling";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
flightPlan: {
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
aircrafts: {
|
||||||
|
type: Array,
|
||||||
|
},
|
||||||
|
isRequestPending: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const formData = reactive({
|
||||||
|
name: props.flightPlan.name || null,
|
||||||
|
isDefaultName: props.flightPlan ? props.flightPlan.isDefaultName : true,
|
||||||
|
isEditableByCopilot: props.flightPlan.isEditableByCopilot || false,
|
||||||
|
isPublic: props.flightPlan.isPublic || false,
|
||||||
|
plannedTakeoffDatetime: props.flightPlan.plannedTakeoffDatetime || null,
|
||||||
|
aircraft: props.flightPlan && props.flightPlan.aircraft ? {
|
||||||
|
id: props.flightPlan.aircraft.id, name: props.flightPlan.aircraft.callSign
|
||||||
|
} : null,
|
||||||
|
plannedSpeed: props.flightPlan.plannedSpeed || 150,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<FormWrapper v-model="formData" :is-request-pending="isRequestPending">
|
||||||
|
<q-input v-model="formData.name" label="Jméno letu" v-if="!formData.isDefaultName" v-bind="commonProps"/>
|
||||||
|
<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.isEditableByCopilot" label="Kopilot může upravovat"/>-->
|
||||||
|
<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"/>
|
||||||
|
|
||||||
|
<q-input v-model.number="formData.plannedSpeed" type="number" step="5" label="Plánovaná rychlost" v-bind="commonProps">
|
||||||
|
<template #append>km/h</template>
|
||||||
|
</q-input>
|
||||||
|
</FormWrapper>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
<script setup>
|
||||||
|
import {computed} from "vue";
|
||||||
|
import {useFlightPlanCalculations} from "src/composables/flightPlan";
|
||||||
|
import {minutesToHumanReadable} from "src/composables/datetimeUtils";
|
||||||
|
import {useQuasar} from "quasar";
|
||||||
|
import {textEllipsis} from "src/composables/utils";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
flightPlan: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
plannedSpeed: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
// name: 'from',
|
||||||
|
label: 'Z',
|
||||||
|
align: "left",
|
||||||
|
field: 'from'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Do',
|
||||||
|
align: "left",
|
||||||
|
field: 'to'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
label: 'Kurz',
|
||||||
|
field: 'bearing',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
label: 'Vzdálenost',
|
||||||
|
field: 'distance',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
label: 'Čas',
|
||||||
|
field: 'duration',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const {getDuration, getTotalTime, getTotalDistance} = useFlightPlanCalculations();
|
||||||
|
|
||||||
|
const data = computed(() => props.flightPlan.track.map((item) => ({
|
||||||
|
from: textEllipsis(item.from.name, 30),
|
||||||
|
to: textEllipsis(item.to.name, 30),
|
||||||
|
distance: `${item.distance} km`,
|
||||||
|
bearing: `${item.bearing} °`,
|
||||||
|
duration: minutesToHumanReadable(getDuration(item.distance, props.plannedSpeed)),
|
||||||
|
})));
|
||||||
|
|
||||||
|
const {screen} = useQuasar();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<q-table
|
||||||
|
:grid="screen.xs"
|
||||||
|
:dense="screen.lt.md"
|
||||||
|
flat bordered
|
||||||
|
hide-bottom
|
||||||
|
:title="flightPlan.name"
|
||||||
|
:rows="data"
|
||||||
|
:columns="columns"
|
||||||
|
:rows-per-page-options="[0]"
|
||||||
|
>
|
||||||
|
<template #bottom-row="{cols}">
|
||||||
|
<tr class="summary">
|
||||||
|
<td v-for="col in cols" :key="col.field" :class="{'text-right': col.align === 'right'}">
|
||||||
|
<template v-if="col.field === 'duration'">
|
||||||
|
{{ minutesToHumanReadable(getTotalTime(flightPlan, plannedSpeed)) }}
|
||||||
|
</template>
|
||||||
|
<template v-else-if="col.field === 'distance'">
|
||||||
|
{{ getTotalDistance(flightPlan) }} km
|
||||||
|
</template>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
</q-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.summary {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,18 +1,13 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {computed, ref, watch} from "vue";
|
import {computed, ref, watch} from "vue";
|
||||||
import {minutesToHumanReadable} from "src/composables/datetimeUtils";
|
import {minutesToHumanReadable} from "src/composables/datetimeUtils";
|
||||||
import {useFlightPlanUtils} from "src/composables/flightPlan";
|
import {useFlightPlanCalculations, useFlightPlanUtils} from "src/composables/flightPlan";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
flightPlan: {
|
flightPlan: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
plannedSpeed: {
|
|
||||||
type: Number,
|
|
||||||
required: false,
|
|
||||||
default: 150
|
|
||||||
},
|
|
||||||
isFullscreen: {
|
isFullscreen: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
@@ -25,19 +20,8 @@ const props = defineProps({
|
|||||||
|
|
||||||
const emits = defineEmits(["open", "change-insert-position", "fullscren-toggle"])
|
const emits = defineEmits(["open", "change-insert-position", "fullscren-toggle"])
|
||||||
|
|
||||||
|
const {getDuration, getTotalDistance, getTotalTime} = useFlightPlanCalculations();
|
||||||
const getDuration = (distance, speed) => Math.round(distance / speed * 60)
|
const totalDistance = computed(() => getTotalDistance(props.flightPlan));
|
||||||
|
|
||||||
const totalDistance = computed(() => {
|
|
||||||
if (!props.flightPlan.track.length) return null;
|
|
||||||
|
|
||||||
return Math.round(props.flightPlan.track.map(t => t.distance).reduce((a, b) => a + b));
|
|
||||||
});
|
|
||||||
const totalTime = computed(() => {
|
|
||||||
if (!props.flightPlan.track.length) return null;
|
|
||||||
|
|
||||||
return props.flightPlan.track.map(t => getDuration(t.distance, props.plannedSpeed)).reduce((a, b) => a + b)
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,13 +57,15 @@ const totalTime = computed(() => {
|
|||||||
<q-item-label caption class="q-py-sm" v-if="segment.distance">
|
<q-item-label caption class="q-py-sm" v-if="segment.distance">
|
||||||
{{ segment.bearing }}°,
|
{{ segment.bearing }}°,
|
||||||
{{ segment.distance }} km,
|
{{ segment.distance }} km,
|
||||||
{{ minutesToHumanReadable(getDuration(segment.distance, props.plannedSpeed)) }}
|
{{ minutesToHumanReadable(getDuration(segment.distance, props.flightPlan.plannedSpeed)) }}
|
||||||
</q-item-label>
|
</q-item-label>
|
||||||
<q-item-label>
|
<q-item-label>
|
||||||
<q-btn
|
<q-btn
|
||||||
@click="emits('change-insert-position', i+1)"
|
@click="emits('change-insert-position', i+1)"
|
||||||
icon="add"
|
icon="add"
|
||||||
size="sm"
|
size="xs"
|
||||||
|
:round="insertPosition !== i+1"
|
||||||
|
outline
|
||||||
class="q-ml-lg q-mb-sm"
|
class="q-ml-lg q-mb-sm"
|
||||||
:color="insertPosition === i+1 ? 'primary' : 'grey'"
|
:color="insertPosition === i+1 ? 'primary' : 'grey'"
|
||||||
>
|
>
|
||||||
@@ -123,7 +109,7 @@ const totalTime = computed(() => {
|
|||||||
<q-item-section>
|
<q-item-section>
|
||||||
Celková vzdálenost: {{ totalDistance }} km
|
Celková vzdálenost: {{ totalDistance }} km
|
||||||
<br>
|
<br>
|
||||||
Plánovaná doba letu: {{ minutesToHumanReadable(totalTime) }}
|
Plánovaná doba letu: {{ minutesToHumanReadable(getTotalTime(props.flightPlan, props.flightPlan.plannedSpeed)) }}
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -23,6 +23,24 @@ export const useFlightPlanUtils = () => {
|
|||||||
return {getIcon, getMarkersFrom}
|
return {getIcon, getMarkersFrom}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const useFlightPlanCalculations = () => {
|
||||||
|
const getDuration = (distance, speed) => Math.round(distance / speed * 60)
|
||||||
|
|
||||||
|
const getTotalDistance = (flightPlan) => {
|
||||||
|
if (!flightPlan.track.length) return null;
|
||||||
|
|
||||||
|
return Math.round(flightPlan.track.map(t => t.distance).reduce((a, b) => a + b));
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTotalTime = (flightPlan, plannedSpeed) => {
|
||||||
|
if (!flightPlan.track.length) return null;
|
||||||
|
|
||||||
|
return flightPlan.track.map(t => getDuration(t.distance, plannedSpeed)).reduce((a, b) => a + b)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {getDuration, getTotalDistance, getTotalTime}
|
||||||
|
}
|
||||||
|
|
||||||
export const useFlightPlanObjects = () => {
|
export const useFlightPlanObjects = () => {
|
||||||
const editableNameTypes = ["geocode", "mapPoint"];
|
const editableNameTypes = ["geocode", "mapPoint"];
|
||||||
|
|
||||||
|
|||||||
@@ -8,3 +8,18 @@ export const pluralize = (count, singular, plural, pluralMore) => {
|
|||||||
else if (count < 5) return plural;
|
else if (count < 5) return plural;
|
||||||
else return pluralMore;
|
else return pluralMore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const textEllipsis = (text, maxLength) => {
|
||||||
|
if (text.length <= maxLength) {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
let words = text.split(' ');
|
||||||
|
|
||||||
|
const maxWords = 2;
|
||||||
|
if (words.length <= maxWords + 1) {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
return words[0] + ' ... ' + words[words.length - 1];
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,28 +14,23 @@ import {usePointsOfInterestStore} from "stores/PointsOfInterest";
|
|||||||
import {storeToRefs} from "pinia";
|
import {storeToRefs} from "pinia";
|
||||||
import {useAirspacesStore} from "stores/Airspaces";
|
import {useAirspacesStore} from "stores/Airspaces";
|
||||||
import {useAirportsStore} from "stores/Airports";
|
import {useAirportsStore} from "stores/Airports";
|
||||||
import {commonProps} from "src/composables/inputs";
|
|
||||||
import {useAppStore} from "stores/App";
|
import {useAppStore} from "stores/App";
|
||||||
import {useFlightPlanObjects, useFlightPlanUtils} from "src/composables/flightPlan";
|
import {useFlightPlanObjects, useFlightPlanUtils} from "src/composables/flightPlan";
|
||||||
import FlightPlanMap from "components/flightPlans/FlightPlanMap.vue";
|
import FlightPlanMap from "components/flightPlans/FlightPlanMap.vue";
|
||||||
import FlightPlanRoute from "components/flightPlans/FlightPlanRoute.vue";
|
import FlightPlanRoute from "components/flightPlans/FlightPlanRoute.vue";
|
||||||
import FlightPlanSideControls from "components/flightPlans/FlightPlanSideControls.vue";
|
import FlightPlanSideControls from "components/flightPlans/FlightPlanSideControls.vue";
|
||||||
import DatetimePicker from "components/inputs/DatetimePicker.vue";
|
|
||||||
import {useAircraftsStore} from "stores/Aircrafts";
|
import {useAircraftsStore} from "stores/Aircrafts";
|
||||||
import ComboboxInput from "components/inputs/ComboboxInput.vue";
|
|
||||||
import FormWrapper from "components/FormWrapper.vue";
|
|
||||||
import {successObject} from "src/composables/dialog";
|
import {successObject} from "src/composables/dialog";
|
||||||
import {useQuasar} from "quasar";
|
import {useQuasar} from "quasar";
|
||||||
import {useCopilotsStore} from "stores/Copilots";
|
import FlightPlanRouteTable from "components/flightPlans/FlightPlanRouteTable.vue";
|
||||||
|
import FlightPlanForm from "components/flightPlans/FlightPlanForm.vue";
|
||||||
|
|
||||||
const {flightPlan} = storeToRefs(useFlightPlansStore());
|
const {flightPlan} = storeToRefs(useFlightPlansStore());
|
||||||
|
|
||||||
const flightPlanName = computed(() => flightPlan.value.name || "Nepojmenovaný plán");
|
const flightPlanName = computed(() => flightPlan.value.name || "Nepojmenovaný plán");
|
||||||
useAppStore().setPageTitle(`${flightPlanName.value} - plánovnání`);
|
useAppStore().setPageTitle(`${flightPlanName.value} - plánovnání`);
|
||||||
useAppStore().setBreadcrumbs([
|
useAppStore().setBreadcrumbs([
|
||||||
{to: {name: "flightPlans"}, label: "Moje plány"},
|
{to: {name: "flightPlans"}, label: "Moje plány"},
|
||||||
{label: flightPlanName.value},
|
{label: flightPlanName.value},
|
||||||
{label: "Editace"}
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -51,20 +46,9 @@ const {airports} = storeToRefs(useAirportsStore());
|
|||||||
const {aircrafts: aircraftsData} = storeToRefs(useAircraftsStore());
|
const {aircrafts: aircraftsData} = storeToRefs(useAircraftsStore());
|
||||||
const aircrafts = computed(() => aircraftsData.value.map(a => ({id: a.id, name: a.callSign})));
|
const aircrafts = computed(() => aircraftsData.value.map(a => ({id: a.id, name: a.callSign})));
|
||||||
|
|
||||||
|
|
||||||
const {getMarkersFrom} = useFlightPlanUtils();
|
const {getMarkersFrom} = useFlightPlanUtils();
|
||||||
const {markerObject} = useFlightPlanObjects();
|
const {markerObject} = useFlightPlanObjects();
|
||||||
|
|
||||||
const formData = ref({
|
|
||||||
name: flightPlan.value?.name || null,
|
|
||||||
isDefaultName: flightPlan.value ? flightPlan.value.isDefaultName : true,
|
|
||||||
isEditableByCopilot: flightPlan.value?.isEditableByCopilot || false,
|
|
||||||
isPublic: flightPlan.value?.isPublic || false,
|
|
||||||
plannedTakeoffDatetime: flightPlan.value?.plannedTakeoffDatetime || null,
|
|
||||||
aircraft: flightPlan.value && flightPlan.value.aircraft ? {id: flightPlan.value.aircraft.id, name: flightPlan.value.aircraft.callSign} : null,
|
|
||||||
plannedSpeed: flightPlan.value?.plannedSpeed || 150,
|
|
||||||
})
|
|
||||||
|
|
||||||
const openedTab = ref("route");
|
const openedTab = ref("route");
|
||||||
const flightPlannerDialogOpen = ref(false);
|
const flightPlannerDialogOpen = ref(false);
|
||||||
const flightPlanMarkers = ref(getMarkersFrom(flightPlan.value));
|
const flightPlanMarkers = ref(getMarkersFrom(flightPlan.value));
|
||||||
@@ -73,7 +57,6 @@ const handleMarkersChanges = (markers) => {
|
|||||||
flightPlanMarkers.value = markers;
|
flightPlanMarkers.value = markers;
|
||||||
|
|
||||||
useFlightPlansStore().update(flightPlan.value.id, {
|
useFlightPlansStore().update(flightPlan.value.id, {
|
||||||
name: formData.value.name,
|
|
||||||
markers: markers.map(m => markerObject({
|
markers: markers.map(m => markerObject({
|
||||||
name: m.name,
|
name: m.name,
|
||||||
type: m.type,
|
type: m.type,
|
||||||
@@ -85,9 +68,9 @@ const handleMarkersChanges = (markers) => {
|
|||||||
|
|
||||||
|
|
||||||
const $q = useQuasar();
|
const $q = useQuasar();
|
||||||
const handleFlightPlanInfoSave = () => {
|
const handleFlightPlanInfoSave = (formData) => {
|
||||||
useFlightPlansStore().update(flightPlan.value.id, formData.value).then(() => {
|
useFlightPlansStore().update(flightPlan.value.id, formData).then(() => {
|
||||||
$q.notify(successObject("Ulozeno"));
|
$q.notify(successObject("Informace úspěšně uloženy"));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const insertAtPosition = ref(flightPlanMarkers.value.length);
|
const insertAtPosition = ref(flightPlanMarkers.value.length);
|
||||||
@@ -95,6 +78,7 @@ const fullscreen = ref(false);
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
{{ flightPlan.plannedSpeed }}
|
||||||
<q-tabs v-model="openedTab">
|
<q-tabs v-model="openedTab">
|
||||||
<q-tab name="route">
|
<q-tab name="route">
|
||||||
<q-icon name="route"/>
|
<q-icon name="route"/>
|
||||||
@@ -105,6 +89,12 @@ const fullscreen = ref(false);
|
|||||||
<q-icon name="info"/>
|
<q-icon name="info"/>
|
||||||
Informace
|
Informace
|
||||||
</q-tab>
|
</q-tab>
|
||||||
|
|
||||||
|
<q-tab name="navLog">
|
||||||
|
<q-icon name="navigation"/>
|
||||||
|
Navigační štítek
|
||||||
|
</q-tab>
|
||||||
|
|
||||||
</q-tabs>
|
</q-tabs>
|
||||||
<q-tab-panels v-model="openedTab">
|
<q-tab-panels v-model="openedTab">
|
||||||
<q-tab-panel name="route">
|
<q-tab-panel name="route">
|
||||||
@@ -136,25 +126,22 @@ const fullscreen = ref(false);
|
|||||||
<q-tab-panel name="info">
|
<q-tab-panel name="info">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<FormWrapper v-model="formData" @save="handleFlightPlanInfoSave">
|
<FlightPlanForm
|
||||||
<q-input v-model="formData.name" label="Jméno letu" v-if="!formData.isDefaultName" v-bind="commonProps"/>
|
:aircrafts="aircrafts"
|
||||||
|
:flight-plan="flightPlan"
|
||||||
<q-checkbox v-model="formData.isDefaultName" label="Použít automatické jméno"/>
|
@save="handleFlightPlanInfoSave"
|
||||||
|
/>
|
||||||
<!-- <q-checkbox v-model="formData.isPublic" label="Zveřejnit"/>-->
|
|
||||||
<!-- <q-checkbox v-model="formData.isEditableByCopilot" label="Kopilot může upravovat"/>-->
|
|
||||||
<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"/>
|
|
||||||
|
|
||||||
<q-input v-model.number="formData.plannedSpeed" type="number" step="5" label="Plánovaná rychlost" v-bind="commonProps">
|
|
||||||
<template #append>km/h</template>
|
|
||||||
</q-input>
|
|
||||||
</FormWrapper>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
</q-tab-panels>
|
|
||||||
|
|
||||||
|
<q-tab-panel name="navLog">
|
||||||
|
<FlightPlanRouteTable
|
||||||
|
:flight-plan="flightPlan"
|
||||||
|
:planned-speed="flightPlan.plannedSpeed"
|
||||||
|
/>
|
||||||
|
</q-tab-panel>
|
||||||
|
</q-tab-panels>
|
||||||
|
|
||||||
<q-dialog full-width v-model="flightPlannerDialogOpen">
|
<q-dialog full-width v-model="flightPlannerDialogOpen">
|
||||||
<q-card>
|
<q-card>
|
||||||
|
|||||||
@@ -11,15 +11,13 @@ import FlightPlansList from "components/flightPlans/FlightPlansList.vue";
|
|||||||
useAppStore().setPageTitle("Nový plán");
|
useAppStore().setPageTitle("Nový plán");
|
||||||
useAppStore().setBreadcrumbs([
|
useAppStore().setBreadcrumbs([
|
||||||
{to: {name: "myFlights"}, label: "Moje lety"},
|
{to: {name: "myFlights"}, label: "Moje lety"},
|
||||||
{to: {name: "flightPlans"}, label: "Plány"},
|
{label: "Plánované lety"},
|
||||||
{label: "Nový"}
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
useFlightPlansStore().fetch();
|
useFlightPlansStore().fetch();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const {flightPlans, isQueryRunning} = storeToRefs(useFlightPlansStore());
|
const {flightPlans, isQueryRunning} = storeToRefs(useFlightPlansStore());
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ useMeta(() => metaData({
|
|||||||
Pro obohacení informací používá Polétání.cz data z následujících zdrojů:
|
Pro obohacení informací používá Polétání.cz data z následujících zdrojů:
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Open Meteo API - pro stahování informací o počasí při vzletu a přistání</li>
|
<li>Open Meteo API - pro stahování informací o počasí při vzletu a přistání, pro stahování informací o elevaci terénu</li>
|
||||||
<li>Elevation API - pro stažení informací o výšce terénu. Tato informace se používá u fotografií a trasy letu</li>
|
<li>Elevation API - pro stažení informací o výšce terénu. Tato informace se používá u fotografií a trasy letu</li>
|
||||||
<li>VFR příručka - pro aktualizaci informací o letištích</li>
|
<li>OpenAIP - primární zdroj dat o vzdušném prostoru a letištích</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3>O autorovi</h3>
|
<h3>O autorovi</h3>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const sendMessage = () => {
|
|||||||
email_from: formData.value.email,
|
email_from: formData.value.email,
|
||||||
content: formData.value.content
|
content: formData.value.content
|
||||||
}).then((e) => {
|
}).then((e) => {
|
||||||
$q.notify(successObject("Zpráva byla jakoby odeslána"));
|
$q.notify(successObject("Zpráva byla odeslána"));
|
||||||
formData.value = {email: "", content: ""};
|
formData.value = {email: "", content: ""};
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
$q.notify(errorObject("Zprávu se nepodařilo odeslat. Zkus to znovu za chvíli."));
|
$q.notify(errorObject("Zprávu se nepodařilo odeslat. Zkus to znovu za chvíli."));
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ useAppStore().setBreadcrumbs([
|
|||||||
Sdílet zážitky s kamarády
|
Sdílet zážitky s kamarády
|
||||||
Upravovat fotky
|
Upravovat fotky
|
||||||
Zobrazovat je v kontextu polohy
|
Zobrazovat je v kontextu polohy
|
||||||
|
Planovat let
|
||||||
Debriefing letu: https://www.easa.europa.eu/community/topics/post-flight-debrief
|
Debriefing letu: https://www.easa.europa.eu/community/topics/post-flight-debrief
|
||||||
|
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
|
|||||||
Reference in New Issue
Block a user