Upravy UI, refaktoring, davkove upravy a mazani fotek

This commit is contained in:
Michal Kváček
2023-08-28 22:02:24 +02:00
parent dcc3230cbe
commit dd248d4432
53 changed files with 636 additions and 357 deletions
+62 -65
View File
@@ -1,13 +1,13 @@
<script setup>
import FlightFormSteps from "components/flights/form/FlightFormSteps.vue";
import {computed, onMounted, reactive, ref, watch} from "vue";
import {onMounted, ref, watch} from "vue";
import {useRoute} from "vue-router";
import {useFlightsStore} from "stores/Flights";
import FlightFormBasic from "components/flights/form/FlightFormBasic.vue";
import {useAircraftsStore} from "stores/Aircrafts";
import {usePointsOfInterestStore} from "stores/PointsOfInterest";
import {useAirportsStore} from "stores/Airports";
import {useMeta, useQuasar} from "quasar";
import {useQuasar} from "quasar";
import {storeToRefs} from "pinia";
import {flightName} from "src/composables/objects/flight";
import FlightFormCopilot from "components/flights/form/FlightFormCopilot.vue";
@@ -16,17 +16,19 @@ import FlightFormNotes from "components/flights/form/FlightFormNotes.vue";
import FlightFormPhotos from "components/flights/form/FlightFormPhotos.vue";
import {usePhotosStore} from "stores/Photo";
import PhotosList from "components/photos/PhotosList.vue";
import {confirmObject, successObject} from "src/composables/dialog";
import PhotoForm from "components/photos/PhotoForm.vue";
import {successObject} from "src/composables/dialog";
import PhotoFormDialog from "components/photos/PhotoFormDialog.vue";
import FlightFormTrack from "components/flights/form/FlightFormTrack.vue";
import {fetchFlight, flight, loading} from "src/composables/objects/flight";
import FlightEditSkeleton from "components/flights/FlightEditSkeleton.vue";
useMeta({title: "Editace letu"});
import BatchPhotoFormDialog from "components/photos/BatchPhotoFormDialog.vue";
import {useAppStore} from "stores/App";
import {editBatchPhotos, handleBatchPhotoEdit, openBatchEdit, openBatchPhotoForm} from "src/composables/photos/batchEdit";
import {editPhoto, handlePhotoUpdate, openEdit, openPhotoEdit} from "src/composables/photos/simpleEdit";
const $q = useQuasar();
const route = useRoute();
const flightId = parseInt(route.params.id);
const $route = useRoute();
const flightId = parseInt($route.params.id);
const aircrafts = storeToRefs(useAircraftsStore()).items;
const locations = storeToRefs(usePointsOfInterestStore()).items;
@@ -34,17 +36,26 @@ const airports = storeToRefs(useAirportsStore()).items;
const copilots = storeToRefs(useCopilotsStore()).items;
const formStep = ref("");
watch(() => route.params.step, (val) => formStep.value = val);
watch(() => $route.params.step, (val) => formStep.value = val);
onMounted(() => {
formStep.value = route.params.step || "basic";
formStep.value = $route.params.step || "basic";
useAircraftsStore().fetch();
usePointsOfInterestStore().fetch();
useAirportsStore().fetch();
useCopilotsStore().fetch();
fetchFlight(flightId);
fetchFlight(flightId).then(() => {
const flightNameFormatted = flightName(flight.value);
useAppStore().setPageTitle(`Editace - ${flightNameFormatted}`);
useAppStore().setBreadcrumbs([
{to: {name: "myFlights"}, label: "Moje lety"},
{to: {name: "flightDetail", params: {id: flightId}}, label: flightNameFormatted},
{label: "Editace"}
]);
})
});
const handleFlightEdit = (data) => {
@@ -56,9 +67,11 @@ const handleFlightEdit = (data) => {
}
const isRequestPending = storeToRefs(useFlightsStore()).isMutationRunning;
const uploadInProgress = ref(false);
const handlePhotosUpload = (data) => {
const promises = [];
uploadInProgress.value = true;
for (const photo of data.photos) {
promises.push(usePhotosStore().upload(flightId, {photo}));
}
@@ -66,57 +79,33 @@ const handlePhotosUpload = (data) => {
Promise.all(promises).then(() => {
$q.notify(successObject("Úspěšně nahráno"));
fetchFlight(flightId);
});
}).finally(() => uploadInProgress.value = false);
}
const _findPhotoIndex = (photoId) => flight.value.photos.findIndex((object) => object.id === photoId);
const confirmPhotoDelete = (id) => {
$q.dialog(confirmObject("Opravdu chces smazat tuto fotku?"))
.onOk(() => {
usePhotosStore().delete(id).then((data) => {
flight.value.photos.splice(_findPhotoIndex(data.id), 1);
});
});
const deletePhoto = (id) => {
usePhotosStore().delete(id).then((data) => {
flight.value.photos.splice(_findPhotoIndex(data.id), 1);
});
}
const handlePhotoUpdate = (formData) => {
const photoId = formData.id;
delete formData.id;
usePhotosStore().update(photoId, formData).then((data) => {
const idx = _findPhotoIndex(data.id);
flight.value.photos[idx] = data;
})
}
const openEdit = ref(false);
const editPhoto = ref(null);
const openPhotoEdit = (photo) => {
openEdit.value = true;
editPhoto.value = photo;
}
</script>
<template>
<FlightEditSkeleton v-if="loading"/>
<template v-else>
<q-breadcrumbs :key="loading">
<q-breadcrumbs-el :to="{name: 'myFlights'}">Moje lety</q-breadcrumbs-el>
<q-breadcrumbs-el :to="{name: 'flightDetail', params: {id: flightId}}">{{ flightName(flight) }}</q-breadcrumbs-el>
<q-breadcrumbs-el>Editace</q-breadcrumbs-el>
</q-breadcrumbs>
<FlightFormSteps :router-edit-mode="true" :flightId="flightId" />
<FlightFormSteps :router-edit-mode="true" :flightId="flightId"/>
<q-tab-panels v-model="formStep">
<q-tab-panel name="basic">
<FlightFormBasic
@save="handleFlightEdit"
:flight="flight"
:locations="locations"
:airports="airports"
:aircrafts="aircrafts"
@save="handleFlightEdit"
:flight="flight"
:locations="locations"
:airports="airports"
:aircrafts="aircrafts"
/>
</q-tab-panel>
@@ -126,33 +115,41 @@ const openPhotoEdit = (photo) => {
<q-tab-panel name="track">
<FlightFormTrack
v-if="locations"
:flight="flight"
:locations="locations"
@save="handleFlightEdit"
v-if="locations"
:flight="flight"
:locations="locations"
@save="handleFlightEdit"
/>
</q-tab-panel>
<q-tab-panel name="photos">
<FlightFormPhotos
:flight="flight"
:is-request-pending="isRequestPending"
@save="handlePhotosUpload"
:flight="flight"
:is-request-pending="isRequestPending || uploadInProgress"
@save="handlePhotosUpload"
/>
<PhotoForm
v-model="openEdit"
:locations="locations"
:photo="editPhoto"
@save="handlePhotoUpdate"
/>
Tu nejsou videt fotky po nahrani
<PhotosList
:photos="flight.photos"
@edit="openPhotoEdit"
@delete="confirmPhotoDelete"
:photos="flight.photos"
@edit="openPhotoEdit"
@batch-edit="openBatchPhotoForm"
@delete="deletePhoto"
/>
<!-- Dialogs for photo edit -->
<PhotoFormDialog
v-model="openEdit"
:locations="locations"
:photo="editPhoto"
@save="handlePhotoUpdate(flightId, $event)"
/>
<BatchPhotoFormDialog
v-model="openBatchEdit"
:locations="locations"
:photos="editBatchPhotos"
@save="handleBatchPhotoEdit(flightId, $event)"
@delete="deletePhoto"
/>
</q-tab-panel>
@@ -11,11 +11,14 @@ import {useFlightsStore} from "stores/Flights";
import PhotoCarousel from "components/flights/PhotoCarousel.vue";
import FlightTrackMap from "components/flights/FlightTrackMap.vue";
import {useUserStore} from "stores/User";
import {storeToRefs} from "pinia";
const $q = useQuasar();
const $router = useRouter();
const flightId = parseInt(useRoute().params.id);
const loggedUser = storeToRefs(useUserStore()).user;
onMounted(() => {
fetchFlight(flightId);
})
@@ -59,7 +62,6 @@ const copyLinkToClipboard = () => {
$q.notify(successObject("Odkaz zkopírován"))
});
};
</script>
@@ -82,6 +84,7 @@ const copyLinkToClipboard = () => {
<q-btn
@click="togglePublicVisibility"
:icon="flight.isPublic ? 'visibility_off' : 'visibility'"
:disable="!loggedUser.publicUsername"
flat
:label="flight.isPublic ? 'Skrýt' : 'Zveřejnit'"
/>
+9 -12
View File
@@ -6,6 +6,7 @@ import FlightsListSkeleton from "components/flights/FlightsListSkeleton.vue";
import FAB from "components/FAB.vue";
import {fetchFlights, flights, handleDeleteFlight, loading} from "src/composables/objects/flight";
import {useAppStore} from "stores/App";
import BasicInfoBanner from "components/banners/BasicInfoBanner.vue";
const $q = useQuasar();
@@ -18,19 +19,15 @@ onMounted(() => {
<template>
<FlightsListSkeleton v-if="loading"/>
<div class="q-pa-md q-gutter-sm" v-else-if="!loading && flights.length === 0">
<q-banner class="bg-light-blue text-white">
<template v-slot:avatar>
<q-icon name="info"/>
</template>
Nemáš zaznamenaný žádný let.
<template v-slot:action>
<q-btn flat color="white" :to="{name: 'addFlight'}" label="Přidat let"/>
</template>
</q-banner>
</div>
<BasicInfoBanner
v-else-if="!loading && flights.length === 0"
:route-add="{name: 'addFlight'}"
label-add="Přidat let"
>
Nemáš zaznamenaný žádný let.
</BasicInfoBanner>
<FlightsList v-else :items="flights" @delete="handleDeleteFlight($q, $event)" />
<FlightsList v-else :items="flights" @delete="handleDeleteFlight($q, $event)"/>
<FAB mode="add" :router-link="{name: 'addFlight'}"/>
</template>
+24 -12
View File
@@ -1,5 +1,5 @@
<script setup>
import {onMounted} from "vue";
import {onMounted, ref} from "vue";
import {useAircraftsStore} from "stores/Aircrafts";
import {useFlightsStore} from "stores/Flights";
import {useRouter} from "vue-router";
@@ -9,13 +9,20 @@ import {useAirportsStore} from "stores/Airports";
import FlightFormSteps from "components/flights/form/FlightFormSteps.vue";
import FlightFormBasic from "components/flights/form/FlightFormBasic.vue";
import {useAppStore} from "stores/App";
import {isRequestPending} from "src/composables/objects/flight";
import FlightEditSkeleton from "components/flights/FlightEditSkeleton.vue";
const loading = ref(true);
onMounted(() => {
useAircraftsStore().fetch();
usePointsOfInterestStore().fetch();
useFlightsStore().fetch();
useAirportsStore().fetch();
const promises = [
useAircraftsStore().fetch(),
usePointsOfInterestStore().fetch(),
useFlightsStore().fetch(),
useAirportsStore().fetch(),
];
loading.value = true;
Promise.all(promises).finally(() => loading.value = false);
useAppStore().setPageTitle("Nový let");
useAppStore().setBreadcrumbs([
@@ -38,10 +45,15 @@ const handleSave = (formData) => {
<template>
<FlightFormSteps :disabled="['copilot', 'track', 'photos', 'notes']"/>
<FlightFormBasic
@save="handleSave"
:aircrafts="aircrafts"
:airports="airports"
:locations="locations"
/>
<FlightEditSkeleton v-if="loading"/>
<template v-else>
<FlightFormBasic
@save="handleSave"
:is-request-pending="isRequestPending"
:aircrafts="aircrafts"
:airports="airports"
:locations="locations"
/>
</template>
</template>