Verejna cast, hezci 404ka, refaktoring

This commit is contained in:
Michal Kváček
2023-08-09 22:46:44 +02:00
parent 25250ae00e
commit 3e33187ba5
31 changed files with 531 additions and 306 deletions
+69
View File
@@ -0,0 +1,69 @@
<script setup>
import {flight} from "src/composables/objects/flight";
import MapWithMarkers from "components/map/MapWithMarkers.vue";
import {computed} from "vue";
const props = defineProps({
flight: {
type: Object,
required: true
}
})
const trackWithGPS = computed(() => {
return flight.value.track.filter(poi => poi.pointOfInterest.gpsLatitude && poi.pointOfInterest.gpsLongitude)
});
const pointsOfInterests = computed(() => {
const path = [{
label: flight.value.takeoffAirport.name,
position:
{
lat: flight.value.takeoffAirport.gpsLatitude,
lng: flight.value.takeoffAirport.gpsLongitude
}
}];
for (const poi of trackWithGPS.value) {
path.push({
label: poi.pointOfInterest.name,
position: {lat: poi.pointOfInterest.gpsLatitude, lng: poi.pointOfInterest.gpsLongitude}
});
}
path.push({
label: flight.value.takeoffAirport.name,
position: {
lat: flight.value.landingAirport.gpsLatitude,
lng: flight.value.landingAirport.gpsLongitude
}
});
return path;
});
const mapPhotos = computed(() => {
return flight.value.photos.filter(photo => photo.gpsLatitude && photo.gpsLongitude)
});
const displayMap = computed(() => {
return (
!!flight.value.gpsTrackUrl ||
mapPhotos.value.length > 0 ||
trackWithGPS.value.length > 0 ||
flight.value.landingAirport.id !== flight.value.takeoffAirport.id
)
});
</script>
<template>
<MapWithMarkers
v-if="displayMap"
style="width: 100%; height: 500px;"
:gpx-track-url="flight.gpxTrackUrl"
:markers="pointsOfInterests"
:photos="mapPhotos"
/>
</template>
+4 -4
View File
@@ -18,7 +18,7 @@ const props = defineProps({
displayVisibilityInfo: {
type: Boolean,
required: false,
default: false
default: true
}
});
@@ -33,12 +33,12 @@ const props = defineProps({
:to="{name: routeDetail.name, params:{...routeDetail.params, id: flight.id}}"
>
<q-item-section avatar>
<q-avatar size="100px">
<div v-if="flight.coverPhoto" :style="`width: 100px; height: 100px; background-image: url('${flight.coverPhoto.thumbnailUrl}'); background-size: cover`"></div>
<q-avatar size="150px">
<div v-if="flight.coverPhoto" :style="`width: 150px; height: 150px; background-image: url('${flight.coverPhoto.thumbnailUrl}'); background-size: cover`"></div>
</q-avatar>
</q-item-section>
<q-item-section>
{{ flightName(flight) }}
<h5>{{ flightName(flight) }}</h5>
<div class="text-secondary">
<q-icon name="flight_takeoff"/>
{{ formatDatetime(flight.takeoffDatetime) }}
+52
View File
@@ -0,0 +1,52 @@
<script setup>
import PhotoDetail from "components/photos/PhotoDetail.vue";
import { ref, watch} from "vue";
const props = defineProps({
photos: {
type: Array,
required: true
},
coverPhotoUrl: {
type: String,
required: false
}
})
const displayedPhoto = ref(null);
const openPhotoDetail = ref(false);
const photoData = ref(null);
const openDetail = ({photo, idx, allPhotos}) => {
openPhotoDetail.value = true;
photoData.value = {photo, idx, allPhotos}
}
watch(() => props.photos, (newVal) => {
if (newVal.length === 0) return;
displayedPhoto.value = props.coverPhotoUrl || newVal[0].url;
}, {immediate: true});
</script>
<template>
<q-carousel
v-if="photos.length > 0"
animated
v-model="displayedPhoto"
arrows
swipeable
height="auto"
infinite
>
<q-carousel-slide style="padding: 0" v-for="(photo, idx) in photos" :key="photo.url" :name="photo.url">
<q-img :src="photo.url" @click="openDetail({photo, idx, allPhotos: photos})"/>
</q-carousel-slide>
</q-carousel>
<PhotoDetail
v-if="photoData"
v-model="openPhotoDetail"
:photo="photoData.photo"
:photos="photoData.allPhotos"
:opened-index="photoData.idx"
/>
</template>
+74 -55
View File
@@ -21,6 +21,7 @@ const props = defineProps({
}
}
)
const formData = reactive({
aircraft: null,
takeoffAirport: null,
@@ -28,89 +29,107 @@ const formData = reactive({
takeoffDatetime: null,
landingDatetime: null,
landings: 1,
isPublic: false,
name: "",
description: "",
})
const recalculateDuration = (data) => {
const diff = data.landingDatetime - data.takeoffDatetime;
data.durationTotal = diff / 1000 / 60;
}
watch(() => [formData.takeoffDatetime, formData.landingDatetime], () => recalculateDuration(formData))
});
const rules = {};
const isMounted = ref(false);
// tohle je blby ohack kvuli tomu, ze DatetimeInput se renderuje jeste pred mounted a do props nedostane hodnotu
// modelu. A neumi se s tim smirit...
onMounted(() => {
if (props.flight) {
setDefaultData(formData, props.flight);
formData.aircraft = {id: formData.aircraft.id, name: formData.aircraft.callSign};
formData.takeoffAirport = {id: formData.takeoffAirport.id, name: formData.takeoffAirport.name}
formData.landingAirport = {id: formData.landingAirport.id, name: formData.landingAirport.name}
watch(() => props.flight, (newVal) => {
if (newVal) {
setDefaultData(formData, newVal);
formData.aircraft = {id: newVal.aircraft.id, name: newVal.aircraft.callSign};
formData.takeoffAirport = {id: newVal.takeoffAirport.id, name: newVal.takeoffAirport.name}
formData.landingAirport = {id: newVal.landingAirport.id, name: newVal.landingAirport.name}
}
isMounted.value = true;
});
}, {immediate: true});
const aircrafts = computed(() => {
return props.aircrafts.map(a => ({id: a.id, name: a.callSign}));
});
watch(() => formData.takeoffDatetime, () => {
if (!formData.landingDatetime) {
formData.landingDatetime = formData.takeoffDatetime;
}
});
watch(() => formData.takeoffAirport, () => {
if (!formData.landingAirport) {
formData.landingAirport = {...formData.takeoffAirport};
}
});
</script>
<template>
<FormWrapper v-model="formData" v-if="isMounted">
<FormWrapper v-model="formData">
<div class="row">
<div class="col">
<ComboboxInput
v-bind="commonProps"
:options="aircrafts"
v-model="formData.aircraft"
:key="formData.aircraft"
label="Letadlo"
/>
<q-card class="q-mx-md q-my-md">
<q-card-section>
<div class="text-h6">Vyber letadlo</div>
</q-card-section>
<q-card-section>
<ComboboxInput
v-bind="commonProps"
:options="aircrafts"
v-model="formData.aircraft"
:key="formData.aircraft"
label="Letadlo"
/>
</q-card-section>
</q-card>
</div>
</div>
<div class="row">
<div class="col col-12 col-md-6">
<h3>Vzlet</h3>
<DatetimePicker
v-model="formData.takeoffDatetime"
label="Datum a čas vzletu: "
v-bind="commonProps"
/>
<ComboboxInput
:options="airports"
v-model="formData.takeoffAirport"
label="Letiště vzletu"
v-bind="commonProps"
:enable-new-values="false"
/>
<q-card class="q-mx-md q-my-md">
<q-card-section>
<div class="text-h6">Vzlet</div>
</q-card-section>
<q-card-section>
<DatetimePicker
v-model="formData.takeoffDatetime"
label="Datum a čas vzletu: "
v-bind="commonProps"
/>
<ComboboxInput
:options="airports"
v-model="formData.takeoffAirport"
label="Letiště vzletu"
v-bind="commonProps"
:enable-new-values="false"
/>
</q-card-section>
</q-card>
</div>
<div class="col col-12 col-md-6">
<h3>Přistání</h3>
<DatetimePicker
v-model="formData.landingDatetime"
:min-date="formData.takeoffDatetime"
label="Datum a čas přistání"
v-bind="commonProps"
/>
<q-card class="q-mx-md q-my-md">
<q-card-section>
<div class="text-h6">Přistání</div>
</q-card-section>
<q-card-section>
<DatetimePicker
v-model="formData.landingDatetime"
:min-date="formData.takeoffDatetime"
label="Datum a čas přistání"
v-bind="commonProps"
/>
<ComboboxInput
:options="airports"
v-model="formData.landingAirport"
label="Letiště přistání"
v-bind="commonProps"
:enable-new-values="false"
/>
</q-card-section>
</q-card>
<ComboboxInput
:options="airports"
v-model="formData.landingAirport"
label="Letiště přistání"
v-bind="commonProps"
:enable-new-values="false"
/>
</div>
</div>
</FormWrapper>
@@ -51,6 +51,11 @@ onMounted(() => {
<template>
<FormWrapper v-model="formData">
<q-banner class="bg-green text-white" v-if="flight.gpxTrackUrl">
<q-icon name="check"/>
Trasa nahrána
</q-banner>
<q-file
accept=".gpx"
v-model="formData.gpxTrack"
@@ -59,14 +64,10 @@ onMounted(() => {
hint="Slouží pro vykreslení kompletní a detailní trasy"
>
<template #prepend>
<q-icon name="upload" />
<q-icon name="upload"/>
</template>
</q-file>
<template v-if="flight.gpxTrackUrl">
<q-icon name="check" color="green" /> Trasa nahrána
</template>
<ComboboxInput
v-bind="commonProps"
v-model="poi"