Rozdeleni editace letu do samostatnych views

This commit is contained in:
Michal Kváček
2024-10-03 22:41:14 +02:00
parent 86e8dbf8e7
commit bffdd96be2
19 changed files with 454 additions and 359 deletions
@@ -19,42 +19,11 @@ const formData = reactive({
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>
<template>
<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>
</template>
@@ -19,6 +19,10 @@ const props = defineProps({
type: Array,
required: false,
},
copilots: {
type: Array,
required: false,
},
isRequestPending: {
type: Boolean,
required: false,
@@ -32,7 +36,8 @@ const formData = reactive({
description: "",
debriefingNotes: "",
urlSlug: "",
isPublic: null
isPublic: null,
copilots: []
})
@@ -48,6 +53,20 @@ watch(() => props.flight, (newVal) => {
}
}, {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");
</script>
@@ -67,6 +86,32 @@ const descriptionTab = ref("description");
<q-checkbox v-model="formData.isPublic" label="Veřejný?"/>
</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-tab name="description">Popis</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">
<RichTextEditor v-model="formData.description" v-bind="commonProps" height="30vh"/>
</q-tab-panel>
<q-tab-panel name="debriefing">
<q-tab-panel name="debriefing">
<BasicInfoBanner>
Debriefing by měl obsahovat minimálně následující body:
<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>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>Dokumentace:</strong> Zápis do deníku, technická kontrola, záznamy o počasí.</li>
</ul>
</BasicInfoBanner>
<RichTextEditor v-model="formData.debriefingNotes" v-bind="commonProps" height="20vh"/>
@@ -25,12 +25,11 @@ onMounted(() => {
})
const steps = [
{name: "basic", icon: "flight_takeoff", label: "Základní informace"},
{name: "copilot", icon: "person_add", label: "Spolucestující"},
{name: "track", icon: "route", label: "Trasa"},
{name: "photos", icon: "add_a_photo", label: "Fotky"},
{name: "notes", icon: "edit_note", label: "Poznámky"},
{name: "plan", icon: "pin_drop", label: "Plán"},
{name: "editFlightBasic", icon: "flight_takeoff", label: "Základní informace"},
{name: "editFlightTrack", icon: "route", label: "Trasa"},
{name: "editFlightPhotos", icon: "add_a_photo", label: "Fotky"},
{name: "editFlightNotes", icon: "edit_note", label: "Poznámky"},
{name: "editFlightSetPlan", icon: "pin_drop", label: "Plán"},
];
const emit = defineEmits(["update:modelValue"])
@@ -38,14 +37,20 @@ watch(currentStep, (val) => emit("update:modelValue", val));
</script>
<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
v-for="step in steps"
:key="step.name"
:icon="step.icon"
:label="step.label"
replace
:to="{name: 'flightEdit', params: {id: flightId, step: step.name}}"
:to="{name: step.name, params: {id: flightId}}"
:disable="disabled.includes(step.name)"
exact
/>
@@ -61,7 +66,6 @@ watch(currentStep, (val) => emit("update:modelValue", val));
active-color="primary"
class="q-mb-lg"
>
<q-tab v-for="step in steps" :key="step.name" v-bind="step" :disable="disabled.includes(step.name)"/>
</q-tabs>
</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: {
type: Array
},
loading: {
type: Boolean
}
});
const formData = ref({
@@ -44,7 +47,12 @@ const setup = () => {
<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-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">
<ComboboxInput
:options="locations"
+8 -2
View File
@@ -18,6 +18,9 @@ const props = defineProps({
},
copilots: {
type: Array
},
loading: {
type: Boolean
}
});
@@ -38,7 +41,10 @@ const setup = (() => {
<template>
<DialogWrapper :formData="formData" :object-id="photoId" @show="setup">
<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">
<ComboboxInput
:options="locations"
@@ -67,7 +73,7 @@ const setup = (() => {
option-value="id"
emit-value
map-options
/>
/>
<q-input v-model="formData.name" label="Název" v-bind="commonProps"/>
<q-input type="textarea" v-model="formData.description" label="Popis" v-bind="commonProps"/>
+1 -1
View File
@@ -86,7 +86,7 @@ const showLarge = (displayedPhoto) => {
</div>
<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="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>
</div>