Rozdeleni editace letu do samostatnych views
This commit is contained in:
@@ -19,42 +19,11 @@ const formData = reactive({
|
|||||||
copilots: [],
|
copilots: [],
|
||||||
})
|
})
|
||||||
|
|
||||||
const solo = ref(false);
|
|
||||||
watch(() => solo.value, (newVal) => {
|
|
||||||
if (!newVal) {
|
|
||||||
formData.copilots = [];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
watch(() => props.flight, (newVal) => {
|
|
||||||
if (newVal) {
|
|
||||||
formData.copilots = newVal.copilots.map(copilot => ({id: copilot.id, name: copilot.name}));
|
|
||||||
solo.value = formData.copilots.length === 0;
|
|
||||||
}
|
|
||||||
}, {deep: true, immediate: true});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FormWrapper v-model="formData">
|
<FormWrapper v-model="formData">
|
||||||
<q-btn-toggle
|
|
||||||
spread
|
|
||||||
no-caps
|
|
||||||
v-model="solo"
|
|
||||||
toggle-color="primary"
|
|
||||||
:options="[{label: 'Solo', value: true}, {label: 'S někým', value: false}]"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div v-if="!solo">
|
|
||||||
<ComboboxInput
|
|
||||||
v-for="i in flight.aircraft.seats - 1"
|
|
||||||
:key="i"
|
|
||||||
v-bind="commonProps"
|
|
||||||
:options="copilots"
|
|
||||||
v-model="formData.copilots[i-1]"
|
|
||||||
:clearable="true"
|
|
||||||
:label="i === 1 ? 'Kopilot' : 'Pasažér'"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</FormWrapper>
|
</FormWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ const props = defineProps({
|
|||||||
type: Array,
|
type: Array,
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
|
copilots: {
|
||||||
|
type: Array,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
isRequestPending: {
|
isRequestPending: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
@@ -32,7 +36,8 @@ const formData = reactive({
|
|||||||
description: "",
|
description: "",
|
||||||
debriefingNotes: "",
|
debriefingNotes: "",
|
||||||
urlSlug: "",
|
urlSlug: "",
|
||||||
isPublic: null
|
isPublic: null,
|
||||||
|
copilots: []
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@@ -48,6 +53,20 @@ watch(() => props.flight, (newVal) => {
|
|||||||
}
|
}
|
||||||
}, {immediate: true});
|
}, {immediate: true});
|
||||||
|
|
||||||
|
const solo = ref(false);
|
||||||
|
watch(() => solo.value, (newVal) => {
|
||||||
|
if (!newVal) {
|
||||||
|
formData.copilots = [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(() => props.flight, (newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
formData.copilots = newVal.copilots.map(copilot => ({id: copilot.id, name: copilot.name}));
|
||||||
|
solo.value = formData.copilots.length === 0;
|
||||||
|
}
|
||||||
|
}, {deep: true, immediate: true});
|
||||||
|
|
||||||
const descriptionTab = ref("description");
|
const descriptionTab = ref("description");
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -67,6 +86,32 @@ const descriptionTab = ref("description");
|
|||||||
<q-checkbox v-model="formData.isPublic" label="Veřejný?"/>
|
<q-checkbox v-model="formData.isPublic" label="Veřejný?"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
Letel jsi
|
||||||
|
<q-radio
|
||||||
|
v-model="solo"
|
||||||
|
:val="true"
|
||||||
|
label="Sólo"
|
||||||
|
/>
|
||||||
|
<q-radio
|
||||||
|
v-model="solo"
|
||||||
|
:val="false"
|
||||||
|
label="S někým"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="!solo">
|
||||||
|
<ComboboxInput
|
||||||
|
v-for="i in flight.aircraft.seats - 1"
|
||||||
|
:key="i"
|
||||||
|
v-bind="commonProps"
|
||||||
|
:options="copilots"
|
||||||
|
v-model="formData.copilots[i-1]"
|
||||||
|
:clearable="true"
|
||||||
|
:label="i === 1 ? 'Kopilot' : 'Pasažér'"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<q-tabs v-model="descriptionTab" active-color="primary">
|
<q-tabs v-model="descriptionTab" active-color="primary">
|
||||||
<q-tab name="description">Popis</q-tab>
|
<q-tab name="description">Popis</q-tab>
|
||||||
<q-tab name="debriefing">Debriefing (soukromé poznámky)</q-tab>
|
<q-tab name="debriefing">Debriefing (soukromé poznámky)</q-tab>
|
||||||
@@ -75,8 +120,8 @@ const descriptionTab = ref("description");
|
|||||||
<q-tab-panel name="description">
|
<q-tab-panel name="description">
|
||||||
<RichTextEditor v-model="formData.description" v-bind="commonProps" height="30vh"/>
|
<RichTextEditor v-model="formData.description" v-bind="commonProps" height="30vh"/>
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
<q-tab-panel name="debriefing">
|
|
||||||
|
|
||||||
|
<q-tab-panel name="debriefing">
|
||||||
<BasicInfoBanner>
|
<BasicInfoBanner>
|
||||||
Debriefing by měl obsahovat minimálně následující body:
|
Debriefing by měl obsahovat minimálně následující body:
|
||||||
<ul>
|
<ul>
|
||||||
@@ -85,9 +130,7 @@ const descriptionTab = ref("description");
|
|||||||
<li><strong>Stav letadla:</strong> Funkčnost přístrojů, případné problémy.</li>
|
<li><strong>Stav letadla:</strong> Funkčnost přístrojů, případné problémy.</li>
|
||||||
<li><strong>Bezpečnostní postupy:</strong> Dodržení bezpečnostních pravidel, řešení neočekávaných situací.</li>
|
<li><strong>Bezpečnostní postupy:</strong> Dodržení bezpečnostních pravidel, řešení neočekávaných situací.</li>
|
||||||
<li><strong>Zpětná vazba:</strong> Pocity z letu, spokojenost pasažéra, návrhy na zlepšení.</li>
|
<li><strong>Zpětná vazba:</strong> Pocity z letu, spokojenost pasažéra, návrhy na zlepšení.</li>
|
||||||
<li><strong>Dokumentace:</strong> Zápis do deníku, technická kontrola, záznamy o počasí.</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</BasicInfoBanner>
|
</BasicInfoBanner>
|
||||||
|
|
||||||
<RichTextEditor v-model="formData.debriefingNotes" v-bind="commonProps" height="20vh"/>
|
<RichTextEditor v-model="formData.debriefingNotes" v-bind="commonProps" height="20vh"/>
|
||||||
|
|||||||
@@ -25,12 +25,11 @@ onMounted(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const steps = [
|
const steps = [
|
||||||
{name: "basic", icon: "flight_takeoff", label: "Základní informace"},
|
{name: "editFlightBasic", icon: "flight_takeoff", label: "Základní informace"},
|
||||||
{name: "copilot", icon: "person_add", label: "Spolucestující"},
|
{name: "editFlightTrack", icon: "route", label: "Trasa"},
|
||||||
{name: "track", icon: "route", label: "Trasa"},
|
{name: "editFlightPhotos", icon: "add_a_photo", label: "Fotky"},
|
||||||
{name: "photos", icon: "add_a_photo", label: "Fotky"},
|
{name: "editFlightNotes", icon: "edit_note", label: "Poznámky"},
|
||||||
{name: "notes", icon: "edit_note", label: "Poznámky"},
|
{name: "editFlightSetPlan", icon: "pin_drop", label: "Plán"},
|
||||||
{name: "plan", icon: "pin_drop", label: "Plán"},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const emit = defineEmits(["update:modelValue"])
|
const emit = defineEmits(["update:modelValue"])
|
||||||
@@ -38,14 +37,20 @@ watch(currentStep, (val) => emit("update:modelValue", val));
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<q-tabs v-if="routerEditMode" active-color="primary" class="q-mb-lg">
|
<q-tabs
|
||||||
|
v-if="routerEditMode"
|
||||||
|
active-color="primary"
|
||||||
|
class="q-mb-lg"
|
||||||
|
left-icon="chevron_left"
|
||||||
|
right-icon="chevron_right"
|
||||||
|
>
|
||||||
<q-route-tab
|
<q-route-tab
|
||||||
v-for="step in steps"
|
v-for="step in steps"
|
||||||
:key="step.name"
|
:key="step.name"
|
||||||
:icon="step.icon"
|
:icon="step.icon"
|
||||||
:label="step.label"
|
:label="step.label"
|
||||||
replace
|
replace
|
||||||
:to="{name: 'flightEdit', params: {id: flightId, step: step.name}}"
|
:to="{name: step.name, params: {id: flightId}}"
|
||||||
:disable="disabled.includes(step.name)"
|
:disable="disabled.includes(step.name)"
|
||||||
exact
|
exact
|
||||||
/>
|
/>
|
||||||
@@ -61,7 +66,6 @@ watch(currentStep, (val) => emit("update:modelValue", val));
|
|||||||
active-color="primary"
|
active-color="primary"
|
||||||
class="q-mb-lg"
|
class="q-mb-lg"
|
||||||
>
|
>
|
||||||
|
|
||||||
<q-tab v-for="step in steps" :key="step.name" v-bind="step" :disable="disabled.includes(step.name)"/>
|
<q-tab v-for="step in steps" :key="step.name" v-bind="step" :disable="disabled.includes(step.name)"/>
|
||||||
</q-tabs>
|
</q-tabs>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<script setup></script>`
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<q-card class="q-my-sm">
|
||||||
|
<q-card-section>
|
||||||
|
<q-skeleton type="QInput" class="q-my-sm" v-for="i in 2" :key="i"/>
|
||||||
|
</q-card-section>
|
||||||
|
</q-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col col-12 col-md-6" v-for="i in 2" :key="i">
|
||||||
|
<q-card class="q-mr-md-sm q-my-sm">
|
||||||
|
<q-card-section>
|
||||||
|
<q-skeleton type="QInput" class="q-my-sm" v-for="i in 2" :key="i"/>
|
||||||
|
</q-card-section>
|
||||||
|
</q-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<script setup></script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<q-skeleton type="QInput" class="q-my-sm" v-for="i in 2" :key="i"/>
|
||||||
|
<q-skeleton type="rect" width="100%" height="500px"/>
|
||||||
|
</template>
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
<script setup>
|
|
||||||
import BasicListSkeleton from "components/basicSkeletons/BasicListSkeleton.vue";
|
|
||||||
import {randomInt} from "src/composables/random";
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
step: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<template v-if="step === 'basic'">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<q-card class="q-my-sm">
|
|
||||||
<q-card-section>
|
|
||||||
<q-skeleton type="QInput" class="q-my-sm" v-for="i in 2" :key="i"/>
|
|
||||||
</q-card-section>
|
|
||||||
</q-card>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col col-12 col-md-6" v-for="i in 2" :key="i">
|
|
||||||
<q-card class="q-mr-md-sm q-my-sm">
|
|
||||||
<q-card-section>
|
|
||||||
<q-skeleton type="QInput" class="q-my-sm" v-for="i in 2" :key="i"/>
|
|
||||||
</q-card-section>
|
|
||||||
</q-card>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<q-card v-else-if="step === 'copilot'">
|
|
||||||
<q-card class="q-mr-md-sm q-my-sm">
|
|
||||||
<q-card-section>
|
|
||||||
<q-skeleton type="QInput" class="q-my-sm"/>
|
|
||||||
</q-card-section>
|
|
||||||
</q-card>
|
|
||||||
</q-card>
|
|
||||||
|
|
||||||
<template v-else-if="step === 'track'">
|
|
||||||
<q-card>
|
|
||||||
<q-card-section>
|
|
||||||
<q-skeleton type="QInput" class="q-my-sm" v-for="i in 2" :key="i"/>
|
|
||||||
</q-card-section>
|
|
||||||
</q-card>
|
|
||||||
|
|
||||||
<BasicListSkeleton :items-count-min="2" :items-count-max="6"/>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-else-if="step === 'photos'">
|
|
||||||
<q-card class="q-my-lg">
|
|
||||||
<q-card-section>
|
|
||||||
<q-skeleton type="QInput" class="q-my-sm"/>
|
|
||||||
</q-card-section>
|
|
||||||
</q-card>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-6 col-sm-4 col-md-4 col-lg-3" v-for="i in randomInt(3, 10)" :key="i">
|
|
||||||
<q-card class="q-ma-md">
|
|
||||||
<q-skeleton height="300px" type="rect"/>
|
|
||||||
</q-card>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<div v-else-if="step === 'notes'">
|
|
||||||
<q-skeleton type="QInput" class="q-my-sm" v-for="i in 2" :key="i"/>
|
|
||||||
<q-skeleton type="rect" width="100%" height="500px"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<script setup>
|
||||||
|
import BasicListSkeleton from "components/basicSkeletons/BasicListSkeleton.vue";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<q-card>
|
||||||
|
<q-card-section>
|
||||||
|
<q-skeleton type="QInput" class="q-my-sm" v-for="i in 2" :key="i"/>
|
||||||
|
</q-card-section>
|
||||||
|
</q-card>
|
||||||
|
|
||||||
|
<BasicListSkeleton :items-count-min="2" :items-count-max="6"/>
|
||||||
|
</template>
|
||||||
@@ -19,6 +19,9 @@ const props = defineProps({
|
|||||||
copilots: {
|
copilots: {
|
||||||
type: Array
|
type: Array
|
||||||
},
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
@@ -44,7 +47,12 @@ const setup = () => {
|
|||||||
<q-card-section class="text-center">
|
<q-card-section class="text-center">
|
||||||
<q-img :src="photo.thumbnailUrl" width="80px" class="q-ma-sm" v-for="photo in photos" :key="photo.thumbnailUrl"/>
|
<q-img :src="photo.thumbnailUrl" width="80px" class="q-ma-sm" v-for="photo in photos" :key="photo.thumbnailUrl"/>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section>
|
|
||||||
|
<q-card-section v-if="loading">
|
||||||
|
<q-spinner />
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-card-section v-else>
|
||||||
<FormWrapper :save-button="false">
|
<FormWrapper :save-button="false">
|
||||||
<ComboboxInput
|
<ComboboxInput
|
||||||
:options="locations"
|
:options="locations"
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
copilots: {
|
copilots: {
|
||||||
type: Array
|
type: Array
|
||||||
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -38,7 +41,10 @@ const setup = (() => {
|
|||||||
<template>
|
<template>
|
||||||
<DialogWrapper :formData="formData" :object-id="photoId" @show="setup">
|
<DialogWrapper :formData="formData" :object-id="photoId" @show="setup">
|
||||||
<q-img :src="photo.thumbnailUrl"/>
|
<q-img :src="photo.thumbnailUrl"/>
|
||||||
<q-card-section>
|
<q-card-section v-if="loading">
|
||||||
|
<q-spinner />
|
||||||
|
</q-card-section>
|
||||||
|
<q-card-section v-else>
|
||||||
<FormWrapper :save-button="false">
|
<FormWrapper :save-button="false">
|
||||||
<ComboboxInput
|
<ComboboxInput
|
||||||
:options="locations"
|
:options="locations"
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ const showLarge = (displayedPhoto) => {
|
|||||||
</div>
|
</div>
|
||||||
<q-btn flat icon="edit" color="blue" @click="openEdit(photo)"/>
|
<q-btn flat icon="edit" color="blue" @click="openEdit(photo)"/>
|
||||||
<q-btn flat icon="tune" color="black" :to="{name: 'photoEditor', params: {id: photo.id}}"/>
|
<q-btn flat icon="tune" color="black" :to="{name: 'photoEditor', params: {id: photo.id}}"/>
|
||||||
<q-btn flat icon="delete" color="red" @click="confirmPhotoDelete(photo.id)"/>
|
<q-btn flat icon="delete" color="red" :disabled="titlePhoto?.id === photo.id" @click="confirmPhotoDelete(photo.id)"/>
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
</q-card>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,53 +7,19 @@ export default {
|
|||||||
return useFlightsStore().fetchDetail(flightId);
|
return useFlightsStore().fetchDetail(flightId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import FlightFormSteps from "components/flights/form/FlightFormSteps.vue";
|
import FlightFormSteps from "components/flights/form/FlightFormSteps.vue";
|
||||||
import {onMounted, ref, toRefs, watch} from "vue";
|
|
||||||
import {useRoute} from "vue-router";
|
import {useRoute} from "vue-router";
|
||||||
import FlightFormBasic from "components/flights/form/FlightFormBasic.vue";
|
|
||||||
import {useAircraftsStore} from "stores/Aircrafts";
|
|
||||||
import {usePointsOfInterestStore} from "stores/PointsOfInterest";
|
|
||||||
import {useAirportsStore} from "stores/Airports";
|
|
||||||
import {useQuasar} from "quasar";
|
import {useQuasar} from "quasar";
|
||||||
import {storeToRefs} from "pinia";
|
import {storeToRefs} from "pinia";
|
||||||
import FlightFormCopilot from "components/flights/form/FlightFormCopilot.vue";
|
import {successObject} from "src/composables/dialog";
|
||||||
import {useCopilotsStore} from "stores/Copilots";
|
|
||||||
import FlightFormNotes from "components/flights/form/FlightFormNotes.vue";
|
|
||||||
import FlightFormPhotos from "components/flights/form/FlightFormPhotos.vue";
|
|
||||||
import PhotosEditorList from "components/photos/PhotosEditorList.vue";
|
|
||||||
import {errorObject, successObject, warningObject} from "src/composables/dialog";
|
|
||||||
import PhotoFormDialog from "components/photos/PhotoFormDialog.vue";
|
|
||||||
import FlightFormTrack from "components/flights/form/FlightFormTrack.vue";
|
|
||||||
import FlightEditSkeleton from "components/flights/skeletons/FlightEditSkeleton.vue";
|
|
||||||
import BatchPhotoFormDialog from "components/photos/BatchPhotoFormDialog.vue";
|
|
||||||
import {useEventsStore} from "stores/Events";
|
|
||||||
import FlightEditCopilotSkeleton from "components/flights/skeletons/FlightEditCopilotSkeleton.vue";
|
|
||||||
import {useBasicPhotoOperations} from "src/composables/photos/basicOperations";
|
|
||||||
import {usePhotosStore} from "stores/Photos";
|
|
||||||
import {flightName} from "src/composables/flight";
|
import {flightName} from "src/composables/flight";
|
||||||
import {useAppStore} from "stores/App";
|
import {useAppStore} from "stores/App";
|
||||||
import {useFlightPlansStore} from "stores/FlightPlans";
|
|
||||||
|
|
||||||
const $q = useQuasar();
|
|
||||||
const $route = useRoute();
|
|
||||||
const flightId = parseInt($route.params.id);
|
|
||||||
|
|
||||||
const {aircrafts} = storeToRefs(useAircraftsStore());
|
|
||||||
const {pointsOfInterest} = storeToRefs(usePointsOfInterestStore());
|
|
||||||
const {airports} = storeToRefs(useAirportsStore());
|
|
||||||
const {copilots} = storeToRefs(useCopilotsStore());
|
|
||||||
const {events} = storeToRefs(useEventsStore());
|
|
||||||
const {photos} = storeToRefs(usePhotosStore());
|
|
||||||
const {flightPlan, flightPlans} = storeToRefs(useFlightPlansStore());
|
|
||||||
const {flight, isQueryRunning, isRequestPending: isMutationRunning} = storeToRefs(useFlightsStore());
|
const {flight, isQueryRunning, isRequestPending: isMutationRunning} = storeToRefs(useFlightsStore());
|
||||||
|
|
||||||
const formStep = ref("basic");
|
|
||||||
watch(() => $route.params.step, (val) => formStep.value = val);
|
|
||||||
|
|
||||||
const flightNameFormatted = flightName(flight.value);
|
const flightNameFormatted = flightName(flight.value);
|
||||||
useAppStore().setPageTitle(`Editace - ${flightNameFormatted}`);
|
useAppStore().setPageTitle(`Editace - ${flightNameFormatted}`);
|
||||||
useAppStore().setBreadcrumbs([
|
useAppStore().setBreadcrumbs([
|
||||||
@@ -62,192 +28,18 @@ useAppStore().setBreadcrumbs([
|
|||||||
{label: "Editace"}
|
{label: "Editace"}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const $q = useQuasar();
|
||||||
onMounted(() => {
|
const $route = useRoute();
|
||||||
photos.value = flight.value.photos;
|
|
||||||
|
|
||||||
formStep.value = $route.params.step || "basic";
|
|
||||||
useAircraftsStore().fetch({});
|
|
||||||
usePointsOfInterestStore().fetch({});
|
|
||||||
useAirportsStore().fetch();
|
|
||||||
useCopilotsStore().fetch();
|
|
||||||
useEventsStore().fetch({});
|
|
||||||
|
|
||||||
useFlightPlansStore().fetch();
|
|
||||||
if (flight.value.flightPlanId) {
|
|
||||||
useFlightPlansStore().fetchDetail(flight.value.flightPlanId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleFlightEdit = (data) => {
|
const handleFlightEdit = (data) => {
|
||||||
|
const flightId = parseInt($route.params.id);
|
||||||
useFlightsStore().update(flightId, data).then((data) => {
|
useFlightsStore().update(flightId, data).then((data) => {
|
||||||
$q.notify(successObject("Úspěšně upraveno"));
|
$q.notify(successObject("Úspěšně upraveno"));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const {
|
|
||||||
uploadInProgress, handlePhotosUpload, batchRotatePhotos, deletePhoto, updateSinglePhoto
|
|
||||||
} = useBasicPhotoOperations({});
|
|
||||||
|
|
||||||
const setTitlePhoto = (photo) => {
|
|
||||||
useFlightsStore().update(flight.value.id, {titlePhotoId: photo.id}).then(f => {
|
|
||||||
$q.notify(successObject("Úvodní fotografie úspěšně nastavena"));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const handlePhotoUpdate = (flightId, formData) => {
|
|
||||||
const photoId = formData.id;
|
|
||||||
delete formData.id;
|
|
||||||
|
|
||||||
return updateSinglePhoto(photoId, formData);
|
|
||||||
};
|
|
||||||
|
|
||||||
const openEdit = ref(false);
|
|
||||||
const editPhoto = ref(null);
|
|
||||||
|
|
||||||
const openPhotoEdit = (photo) => {
|
|
||||||
openEdit.value = true;
|
|
||||||
editPhoto.value = photo;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// batch edit
|
|
||||||
const openBatchEdit = ref(false);
|
|
||||||
const editBatchPhotos = ref([]);
|
|
||||||
const openBatchPhotoForm = (photos) => {
|
|
||||||
openBatchEdit.value = true;
|
|
||||||
editBatchPhotos.value = photos;
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleBatchPhotoEdit = async (data) => {
|
|
||||||
const photoIds = data.photoIds;
|
|
||||||
delete data.photoIds;
|
|
||||||
delete data.id;
|
|
||||||
|
|
||||||
if (data.pointOfInterest && !data.pointOfInterest.id) {
|
|
||||||
const poiData = {
|
|
||||||
...data.pointOfInterest,
|
|
||||||
isPublic: false,
|
|
||||||
description: "",
|
|
||||||
urlSlug: "",
|
|
||||||
}
|
|
||||||
await usePointsOfInterestStore().create(poiData).then(poi => data.pointOfInterest = {id: poi.id, name: poi.name});
|
|
||||||
}
|
|
||||||
|
|
||||||
const promises = [];
|
|
||||||
for (const id of photoIds) {
|
|
||||||
const updateData = {
|
|
||||||
isAircraft: data.isAircraft,
|
|
||||||
copilots: data.copilots.map(c => ({id: c.id, name: c.name}))
|
|
||||||
};
|
|
||||||
if (data.name !== '') updateData.name = data.name;
|
|
||||||
if (data.description !== '') updateData.description = data.description;
|
|
||||||
if (data.pointOfInterest) updateData.pointOfInterest = data.pointOfInterest;
|
|
||||||
|
|
||||||
promises.push(updateSinglePhoto(id, data));
|
|
||||||
}
|
|
||||||
|
|
||||||
let success = 0;
|
|
||||||
Promise.allSettled(promises).then(result => {
|
|
||||||
for (const item of result) {
|
|
||||||
if (item.status === 'fulfilled') success++;
|
|
||||||
}
|
|
||||||
const error = result.length - success;
|
|
||||||
|
|
||||||
if (success > 0) $q.notify(successObject("Upraveno " + success + " fotografií"));
|
|
||||||
if (error > 0) $q.notify(errorObject(`Nepovedlo se uložit ${error} fotografií`))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FlightFormSteps :router-edit-mode="true" :flightId="flightId"/>
|
<FlightFormSteps :router-edit-mode="true" :flightId="flight.id"/>
|
||||||
|
|
||||||
<q-tab-panels v-model="formStep">
|
<router-view :flight="flight" @save="handleFlightEdit"/>
|
||||||
<q-tab-panel name="basic">
|
|
||||||
<FlightEditSkeleton :step="formStep" v-if="isQueryRunning || !flight"/>
|
|
||||||
<FlightFormBasic
|
|
||||||
v-else
|
|
||||||
@save="handleFlightEdit"
|
|
||||||
:flight="flight"
|
|
||||||
:locations="pointsOfInterest"
|
|
||||||
:airports="airports"
|
|
||||||
:aircrafts="aircrafts"
|
|
||||||
/>
|
|
||||||
</q-tab-panel>
|
|
||||||
|
|
||||||
<q-tab-panel name="copilot">
|
|
||||||
<FlightEditCopilotSkeleton v-if="isQueryRunning || !flight"/>
|
|
||||||
<FlightFormCopilot
|
|
||||||
v-else
|
|
||||||
@save="handleFlightEdit"
|
|
||||||
:flight="flight"
|
|
||||||
:copilots="copilots"/>
|
|
||||||
</q-tab-panel>
|
|
||||||
|
|
||||||
<q-tab-panel name="track">
|
|
||||||
<FlightEditSkeleton :step="formStep" v-if="isQueryRunning || !flight"/>
|
|
||||||
<FlightFormTrack
|
|
||||||
v-if="flight && pointsOfInterest"
|
|
||||||
:flight="flight"
|
|
||||||
:locations="pointsOfInterest"
|
|
||||||
:airports="airports"
|
|
||||||
@save="handleFlightEdit"
|
|
||||||
/>
|
|
||||||
</q-tab-panel>
|
|
||||||
|
|
||||||
<q-tab-panel name="photos">
|
|
||||||
<FlightFormPhotos
|
|
||||||
:flight="flight"
|
|
||||||
:is-request-pending="uploadInProgress"
|
|
||||||
@save="handlePhotosUpload"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<template v-if="flight">
|
|
||||||
<PhotosEditorList
|
|
||||||
:title-photo="flight.titlePhoto"
|
|
||||||
:photos="photos"
|
|
||||||
:show-actions="true"
|
|
||||||
@edit="openPhotoEdit"
|
|
||||||
@batch-edit="openBatchPhotoForm"
|
|
||||||
@batch-rotate="batchRotatePhotos"
|
|
||||||
@delete="deletePhoto"
|
|
||||||
@set-title-photo="setTitlePhoto"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- Dialogs for photo edit -->
|
|
||||||
<PhotoFormDialog
|
|
||||||
v-model="openEdit"
|
|
||||||
:copilots="flight.copilots"
|
|
||||||
:aircrafts="aircrafts"
|
|
||||||
:locations="pointsOfInterest"
|
|
||||||
:photo="editPhoto"
|
|
||||||
@save="handlePhotoUpdate(flightId, $event)"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<BatchPhotoFormDialog
|
|
||||||
v-model="openBatchEdit"
|
|
||||||
:locations="pointsOfInterest"
|
|
||||||
:photos="editBatchPhotos"
|
|
||||||
:copilots="flight.copilots"
|
|
||||||
:aircrafts="aircrafts"
|
|
||||||
@save="handleBatchPhotoEdit"
|
|
||||||
@delete="deletePhoto"
|
|
||||||
/>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
</q-tab-panel>
|
|
||||||
|
|
||||||
<q-tab-panel name="notes">
|
|
||||||
<FlightFormNotes @save="handleFlightEdit" :events="events" :flight="flight"/>
|
|
||||||
</q-tab-panel>
|
|
||||||
|
|
||||||
<q-tab-panel name="plan">
|
|
||||||
<template v-if="flight.flightPlanId">
|
|
||||||
{{ flightPlan.name }}
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
Bez planu
|
|
||||||
</template>
|
|
||||||
</q-tab-panel>
|
|
||||||
</q-tab-panels>
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ const togglePublicVisibility = (variables) => toggleVisibility({
|
|||||||
<template #content>
|
<template #content>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<ContentCardEditButton
|
<ContentCardEditButton
|
||||||
:to="{name: 'flightEdit', params: {id: flightId, step: 'basic'}}"
|
:to="{name: 'editFlightBasic', params: {id: flightId}}"
|
||||||
label="Upravit informace"
|
label="Upravit informace"
|
||||||
/>
|
/>
|
||||||
<FlightBasicInfo
|
<FlightBasicInfo
|
||||||
@@ -114,7 +114,7 @@ const togglePublicVisibility = (variables) => toggleVisibility({
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<ContentCardEditButton
|
<ContentCardEditButton
|
||||||
:to="{name: 'flightEdit', params: {id: flightId, step: 'notes'}}"
|
:to="{name: 'editFlightNotes', params: {id: flightId}}"
|
||||||
label="Upravit text"
|
label="Upravit text"
|
||||||
/>
|
/>
|
||||||
<article class="q-my-lg" v-html="flight.description"/>
|
<article class="q-my-lg" v-html="flight.description"/>
|
||||||
@@ -129,12 +129,12 @@ const togglePublicVisibility = (variables) => toggleVisibility({
|
|||||||
<q-separator/>
|
<q-separator/>
|
||||||
|
|
||||||
<ContentCardEditButton
|
<ContentCardEditButton
|
||||||
:to="{name: 'flightEdit', params: {id: flightId, step: 'photos'}}"
|
:to="{name: 'editFlightPhotos', params: {id: flightId}}"
|
||||||
label="Upravit fotografie"
|
label="Upravit fotografie"
|
||||||
/>
|
/>
|
||||||
<BasicInfoBanner
|
<BasicInfoBanner
|
||||||
v-if="flight.photos.length === 0"
|
v-if="flight.photos.length === 0"
|
||||||
:route-add="{name: 'flightEdit', params: {id: flightId, step: 'photos'}}"
|
:route-add="{name: 'editFlightPhotos', params: {id: flightId,}}"
|
||||||
>
|
>
|
||||||
U tohoto letu nemáš nahrané žádné fotografie.
|
U tohoto letu nemáš nahrané žádné fotografie.
|
||||||
</BasicInfoBanner>
|
</BasicInfoBanner>
|
||||||
@@ -145,12 +145,12 @@ const togglePublicVisibility = (variables) => toggleVisibility({
|
|||||||
<q-separator/>
|
<q-separator/>
|
||||||
|
|
||||||
<ContentCardEditButton
|
<ContentCardEditButton
|
||||||
:to="{name: 'flightEdit', params: {id: flightId, step: 'track'}}"
|
:to="{name: 'editFlightTrack', params: {id: flightId}}"
|
||||||
label="Upravit trasu"
|
label="Upravit trasu"
|
||||||
/>
|
/>
|
||||||
<BasicInfoBanner
|
<BasicInfoBanner
|
||||||
v-if="flight.turnPoints.length === 0 && !flight.track"
|
v-if="flight.turnPoints.length === 0 && !flight.track"
|
||||||
:route-add="{name: 'flightEdit', params: {id: flightId, step: 'track'}}"
|
:route-add="{name: 'editFlightTrack', params: {id: flightId}}"
|
||||||
>
|
>
|
||||||
Nemáš nastavenou žádnou trasu.
|
Nemáš nastavenou žádnou trasu.
|
||||||
</BasicInfoBanner>
|
</BasicInfoBanner>
|
||||||
|
|||||||
@@ -32,10 +32,10 @@ const loading = computed(() => [
|
|||||||
useAircraftsStore().isQueryRunning, usePointsOfInterestStore().isQueryRunning, useAirportsStore().isQueryRunning
|
useAircraftsStore().isQueryRunning, usePointsOfInterestStore().isQueryRunning, useAirportsStore().isQueryRunning
|
||||||
].some(i => i.value))
|
].some(i => i.value))
|
||||||
|
|
||||||
const router = useRouter();
|
const $router = useRouter();
|
||||||
const handleSave = (formData) => {
|
const handleSave = (formData) => {
|
||||||
useFlightsStore().create(formData).then((flight) => {
|
useFlightsStore().create(formData).then((flight) => {
|
||||||
router.push({name: "flightEdit", params: {id: flight.id, step: "copilot"}});
|
$router.push({name: "flightEdit", params: {id: flight.id, step: "copilot"}});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -44,13 +44,12 @@ const handleSave = (formData) => {
|
|||||||
<FlightFormSteps :disabled="['copilot', 'track', 'photos', 'notes']"/>
|
<FlightFormSteps :disabled="['copilot', 'track', 'photos', 'notes']"/>
|
||||||
|
|
||||||
<FlightEditSkeleton step="basic" v-if="loading"/>
|
<FlightEditSkeleton step="basic" v-if="loading"/>
|
||||||
<template v-else>
|
|
||||||
<FlightFormBasic
|
<FlightFormBasic
|
||||||
@save="handleSave"
|
v-else
|
||||||
:is-request-pending="isMutationRunning"
|
:is-request-pending="isMutationRunning"
|
||||||
:aircrafts="aircrafts"
|
:aircrafts="aircrafts"
|
||||||
:airports="airports"
|
:airports="airports"
|
||||||
:locations="pointsOfInterest"
|
:locations="pointsOfInterest"
|
||||||
|
@save="handleSave"
|
||||||
/>
|
/>
|
||||||
</template>
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<script setup>
|
||||||
|
import FlightFormBasic from "components/flights/form/FlightFormBasic.vue";
|
||||||
|
import {onMounted} from "vue";
|
||||||
|
import {useAircraftsStore} from "stores/Aircrafts";
|
||||||
|
import {usePointsOfInterestStore} from "stores/PointsOfInterest";
|
||||||
|
import {useAirportsStore} from "stores/Airports";
|
||||||
|
import {storeToRefs} from "pinia";
|
||||||
|
import {useFlightsStore} from "stores/Flights";
|
||||||
|
import FlightEditBasicInfoSkeleton from "components/flights/skeletons/FlightEditBasicInfoSkeleton.vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
flight: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
useAircraftsStore().fetch({});
|
||||||
|
usePointsOfInterestStore().fetch({});
|
||||||
|
useAirportsStore().fetch();
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["save"]);
|
||||||
|
|
||||||
|
const {aircrafts} = storeToRefs(useAircraftsStore());
|
||||||
|
const {pointsOfInterest} = storeToRefs(usePointsOfInterestStore());
|
||||||
|
const {airports} = storeToRefs(useAirportsStore());
|
||||||
|
const {isQueryRunning, isRequestPending: isMutationRunning} = storeToRefs(useFlightsStore());
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<FlightEditBasicInfoSkeleton v-if="isQueryRunning || !flight"/>
|
||||||
|
<FlightFormBasic
|
||||||
|
v-else
|
||||||
|
:flight="flight"
|
||||||
|
:locations="pointsOfInterest"
|
||||||
|
:airports="airports"
|
||||||
|
:aircrafts="aircrafts"
|
||||||
|
@save="emits('save', $event)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<script setup>
|
||||||
|
import FlightFormNotes from "components/flights/form/FlightFormNotes.vue";
|
||||||
|
import {computed, onMounted} from "vue";
|
||||||
|
import {useEventsStore} from "stores/Events";
|
||||||
|
import {storeToRefs} from "pinia";
|
||||||
|
import {useCopilotsStore} from "stores/Copilots";
|
||||||
|
import FlightEditExtraInfoSkeleton from "components/flights/skeletons/FlightEditExtraInfoSkeleton.vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
flight: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const emits = defineEmits(["save"]);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
useEventsStore().fetch({});
|
||||||
|
useCopilotsStore().fetch();
|
||||||
|
});
|
||||||
|
|
||||||
|
const {events, isQueryRunning: loadingEvents} = storeToRefs(useEventsStore());
|
||||||
|
const {copilots, isQueryRunning: loadingCopilots} = storeToRefs(useCopilotsStore())
|
||||||
|
|
||||||
|
const isLoading = computed(() => loadingCopilots.value || loadingEvents.value);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<FlightEditExtraInfoSkeleton v-if="isLoading" />
|
||||||
|
<FlightFormNotes
|
||||||
|
v-else
|
||||||
|
:events="events"
|
||||||
|
:flight="flight"
|
||||||
|
:copilots="copilots"
|
||||||
|
@save="emits('save', $event)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
<script setup>
|
||||||
|
import BatchPhotoFormDialog from "components/photos/BatchPhotoFormDialog.vue";
|
||||||
|
import PhotoFormDialog from "components/photos/PhotoFormDialog.vue";
|
||||||
|
import FlightFormPhotos from "components/flights/form/FlightFormPhotos.vue";
|
||||||
|
import PhotosEditorList from "components/photos/PhotosEditorList.vue";
|
||||||
|
import {errorObject, successObject} from "src/composables/dialog";
|
||||||
|
import {computed, onMounted, ref, watch} from "vue";
|
||||||
|
import {usePointsOfInterestStore} from "stores/PointsOfInterest";
|
||||||
|
import {useFlightsStore} from "stores/Flights";
|
||||||
|
import {useBasicPhotoOperations} from "src/composables/photos/basicOperations";
|
||||||
|
import {storeToRefs} from "pinia";
|
||||||
|
import {useAircraftsStore} from "stores/Aircrafts";
|
||||||
|
import {usePhotosStore} from "stores/Photos";
|
||||||
|
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
flight: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const emits = defineEmits(["save"]);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
photos.value = props.flight.photos;
|
||||||
|
})
|
||||||
|
|
||||||
|
const {aircrafts, isQueryRunning: aircraftsLoading} = storeToRefs(useAircraftsStore());
|
||||||
|
const {pointsOfInterest, isQueryRunning: poisLoading} = storeToRefs(usePointsOfInterestStore());
|
||||||
|
const {photos, isQueryRunning: photosLoading} = storeToRefs(usePhotosStore());
|
||||||
|
|
||||||
|
const isLoading = computed(() => aircraftsLoading.value || poisLoading.value || photosLoading.value);
|
||||||
|
|
||||||
|
const setTitlePhoto = (photo) => {
|
||||||
|
useFlightsStore().update(props.flight.id, {titlePhotoId: photo.id}).then(f => {
|
||||||
|
$q.notify(successObject("Úvodní fotografie úspěšně nastavena"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlePhotoUpdate = (flightId, formData) => {
|
||||||
|
const photoId = formData.id;
|
||||||
|
delete formData.id;
|
||||||
|
|
||||||
|
return updateSinglePhoto(photoId, formData);
|
||||||
|
};
|
||||||
|
|
||||||
|
const openEdit = ref(false);
|
||||||
|
const editPhoto = ref(null);
|
||||||
|
|
||||||
|
const openPhotoEdit = (photo) => {
|
||||||
|
openEdit.value = true;
|
||||||
|
editPhoto.value = photo;
|
||||||
|
};
|
||||||
|
|
||||||
|
const {
|
||||||
|
uploadInProgress, handlePhotosUpload, batchRotatePhotos, deletePhoto, updateSinglePhoto
|
||||||
|
} = useBasicPhotoOperations({});
|
||||||
|
|
||||||
|
|
||||||
|
// batch edit
|
||||||
|
const openBatchEdit = ref(false);
|
||||||
|
const editBatchPhotos = ref([]);
|
||||||
|
const openBatchPhotoForm = (photos) => {
|
||||||
|
openBatchEdit.value = true;
|
||||||
|
editBatchPhotos.value = photos;
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleBatchPhotoEdit = async (data) => {
|
||||||
|
const photoIds = data.photoIds;
|
||||||
|
delete data.photoIds;
|
||||||
|
delete data.id;
|
||||||
|
|
||||||
|
if (data.pointOfInterest && !data.pointOfInterest.id) {
|
||||||
|
const poiData = {
|
||||||
|
...data.pointOfInterest,
|
||||||
|
isPublic: false,
|
||||||
|
description: "",
|
||||||
|
urlSlug: "",
|
||||||
|
}
|
||||||
|
await usePointsOfInterestStore().create(poiData).then(poi => data.pointOfInterest = {id: poi.id, name: poi.name});
|
||||||
|
}
|
||||||
|
|
||||||
|
const promises = [];
|
||||||
|
for (const id of photoIds) {
|
||||||
|
const updateData = {
|
||||||
|
isAircraft: data.isAircraft,
|
||||||
|
copilots: data.copilots.map(c => ({id: c.id, name: c.name}))
|
||||||
|
};
|
||||||
|
if (data.name !== '') updateData.name = data.name;
|
||||||
|
if (data.description !== '') updateData.description = data.description;
|
||||||
|
if (data.pointOfInterest) updateData.pointOfInterest = data.pointOfInterest;
|
||||||
|
|
||||||
|
promises.push(updateSinglePhoto(id, data));
|
||||||
|
}
|
||||||
|
|
||||||
|
let success = 0;
|
||||||
|
Promise.allSettled(promises).then(result => {
|
||||||
|
for (const item of result) {
|
||||||
|
if (item.status === 'fulfilled') success++;
|
||||||
|
}
|
||||||
|
const error = result.length - success;
|
||||||
|
|
||||||
|
if (success > 0) $q.notify(successObject("Upraveno " + success + " fotografií"));
|
||||||
|
if (error > 0) $q.notify(errorObject(`Nepovedlo se uložit ${error} fotografií`))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => [openEdit.value, openBatchEdit.value], (newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
// load new data on each dialog open
|
||||||
|
useAircraftsStore().fetch({});
|
||||||
|
usePointsOfInterestStore().fetch({});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<FlightFormPhotos
|
||||||
|
:flight="flight"
|
||||||
|
:is-request-pending="uploadInProgress"
|
||||||
|
@save="handlePhotosUpload"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<PhotosEditorList
|
||||||
|
:title-photo="flight.titlePhoto"
|
||||||
|
:photos="flight.photos"
|
||||||
|
:show-actions="true"
|
||||||
|
@edit="openPhotoEdit"
|
||||||
|
@batch-edit="openBatchPhotoForm"
|
||||||
|
@batch-rotate="batchRotatePhotos"
|
||||||
|
@delete="deletePhoto"
|
||||||
|
@set-title-photo="setTitlePhoto"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<PhotoFormDialog
|
||||||
|
v-model="openEdit"
|
||||||
|
:copilots="flight.copilots"
|
||||||
|
:loading="isLoading"
|
||||||
|
:aircrafts="aircrafts"
|
||||||
|
:locations="pointsOfInterest"
|
||||||
|
:photo="editPhoto"
|
||||||
|
@save="handlePhotoUpdate(flight.id, $event)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<BatchPhotoFormDialog
|
||||||
|
v-model="openBatchEdit"
|
||||||
|
:loading="isLoading"
|
||||||
|
:locations="pointsOfInterest"
|
||||||
|
:photos="editBatchPhotos"
|
||||||
|
:copilots="flight.copilots"
|
||||||
|
:aircrafts="aircrafts"
|
||||||
|
@save="handleBatchPhotoEdit"
|
||||||
|
@delete="deletePhoto"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<script setup>
|
||||||
|
import {onMounted} from "vue";
|
||||||
|
import {useFlightPlansStore} from "stores/FlightPlans";
|
||||||
|
import {storeToRefs} from "pinia";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
flight: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const emits = defineEmits(["save"]);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (props.flight.flightPlanId) {
|
||||||
|
useFlightPlansStore().fetchDetail(props.flight.flightPlanId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const {flightPlan} = storeToRefs(useFlightPlansStore());
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<template v-if="flight.flightPlanId">
|
||||||
|
{{ flightPlan.name }}
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
Bez planu
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<script setup>
|
||||||
|
import FlightFormTrack from "components/flights/form/FlightFormTrack.vue";
|
||||||
|
import {storeToRefs} from "pinia";
|
||||||
|
import {computed, onMounted} from "vue";
|
||||||
|
import {usePointsOfInterestStore} from "stores/PointsOfInterest";
|
||||||
|
import {useAirportsStore} from "stores/Airports";
|
||||||
|
import FlightEditTrackSkeleton from "components/flights/skeletons/FlightEditTrackSkeleton.vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
flight: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const emits = defineEmits(["save"]);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
usePointsOfInterestStore().fetch({});
|
||||||
|
useAirportsStore().fetch();
|
||||||
|
});
|
||||||
|
|
||||||
|
const {pointsOfInterest, isQueryRunning: poisLoading} = storeToRefs(usePointsOfInterestStore());
|
||||||
|
const {airports, isQueryRunning: airportsLoading} = storeToRefs(useAirportsStore());
|
||||||
|
const isLoading = computed(() => poisLoading.value || airportsLoading.value);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<FlightEditTrackSkeleton v-if="isLoading"/>
|
||||||
|
<FlightFormTrack
|
||||||
|
v-else
|
||||||
|
:flight="flight"
|
||||||
|
:locations="pointsOfInterest"
|
||||||
|
:airports="airports"
|
||||||
|
@save="emits('save', $event)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
+10
-3
@@ -53,10 +53,17 @@ const routes = [
|
|||||||
{path: '', name: "myFlights", component: () => import('pages/profile/flight/FlightsPage.vue')},
|
{path: '', name: "myFlights", component: () => import('pages/profile/flight/FlightsPage.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',
|
||||||
|
component: () => import('pages/profile/flight/EditFlightPage.vue'),
|
||||||
|
children: [
|
||||||
|
{path: '', name: "editFlightBasic", component: () => import('pages/profile/flight/edit/EditFlightBasicInfoPage.vue')},
|
||||||
|
{path: 'trasa', name: "editFlightTrack", component: () => import('pages/profile/flight/edit/EditFlightTrackPage.vue')},
|
||||||
|
{path: 'foto', name: "editFlightPhotos", component: () => import('pages/profile/flight/edit/EditFlightPhotosPage.vue')},
|
||||||
|
{path: 'poznamky', name: "editFlightNotes", component: () => import('pages/profile/flight/edit/EditFlightExtraInfoPage.vue')},
|
||||||
|
{path: 'plan', name: "editFlightSetPlan", component: () => import('pages/profile/flight/edit/EditFlightPlanPage.vue')},
|
||||||
|
]},
|
||||||
{path: 'nastaveni', name: "profile", component: () => import('pages/profile/ProfilePage.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')},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user