Moznost nahravat fotky copilotem

This commit is contained in:
Michal Kváček
2024-03-07 06:45:22 +01:00
parent f0a4c439dc
commit cd9c7351e9
22 changed files with 550 additions and 216 deletions
+38 -87
View File
@@ -1,29 +1,39 @@
<script>
import {useFlightsStore} from "stores/Flights";
export default {
preFetch({currentRoute}) {
const flightId = currentRoute.params.id
return useFlightsStore().fetchDetail(flightId);
}
};
</script>
<script setup>
import FlightFormSteps from "components/flights/form/FlightFormSteps.vue";
import {computed, onMounted, ref, watch} from "vue";
import {onMounted, ref, toRefs, 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 {useQuasar} from "quasar";
import {storeToRefs} from "pinia";
import {flightName} from "src/composables/flight";
import FlightFormCopilot from "components/flights/form/FlightFormCopilot.vue";
import {useCopilotsStore} from "stores/Copilots";
import FlightFormNotes from "components/flights/form/FlightFormNotes.vue";
import FlightFormPhotos from "components/flights/form/FlightFormPhotos.vue";
import {usePhotosStore} from "stores/Photos";
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 {useAppStore} from "stores/App";
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";
const $q = useQuasar();
const $route = useRoute();
@@ -34,29 +44,33 @@ const {pointsOfInterest} = storeToRefs(usePointsOfInterestStore());
const {airports} = storeToRefs(useAirportsStore());
const {copilots} = storeToRefs(useCopilotsStore());
const {events} = storeToRefs(useEventsStore());
const {flight, isQueryRunning, isMutationRunning} = storeToRefs(useFlightsStore());
const {photos} = storeToRefs(usePhotosStore());
const {flight, isQueryRunning, isRequestPending: isMutationRunning} = storeToRefs(useFlightsStore());
const formStep = ref("basic");
watch(() => $route.params.step, (val) => formStep.value = val);
onMounted(() => {
formStep.value = $route.params.step || "basic";
import {flightName} from "src/composables/flight";
import {useAppStore} from "stores/App";
const flightNameFormatted = flightName(flight.value);
useAppStore().setPageTitle(`Editace - ${flightNameFormatted}`);
useAppStore().setBreadcrumbs([
{to: {name: "myFlights"}, label: "Moje lety"},
{to: {name: "flightDetail", params: {id: flight.id}}, label: flightNameFormatted},
{label: "Editace"}
]);
onMounted(() => {
photos.value = flight.value.photos;
formStep.value = $route.params.step || "basic";
useAircraftsStore().fetch({});
usePointsOfInterestStore().fetch({});
useAirportsStore().fetch();
useCopilotsStore().fetch();
useEventsStore().fetch({});
useFlightsStore().fetchDetail(flightId).then((f) => {
const flightNameFormatted = flightName(f);
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) => {
@@ -64,40 +78,9 @@ const handleFlightEdit = (data) => {
$q.notify(successObject("Úspěšně upraveno"));
})
}
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}).then((data) => {
flight.value.photos.push(data);
photo._uploaded = true;
}));
}
Promise.allSettled(promises).then((values) => {
const success = values.filter(v => v.status === 'fulfilled');
const failed = values.filter(v => v.status === 'rejected'); // TODO: nebo vse - success?
if (success.length > 0)
$q.notify(successObject(`Úspěšně nahráno ${success.length} fotek`));
if (failed.length > 0)
$q.notify(warningObject(`Nepovedlo se nahrát ${failed.length} fotek. Zde jsou důvody: ${failed.map(f => f.reason)}`));
data.photos = [];
}).finally(() => uploadInProgress.value = false);
}
const _findPhotoIndex = (photoId) => flight.value.photos.findIndex((object) => object.id === photoId);
const deletePhoto = (id) => {
usePhotosStore().destroy(id).then((data) => {
flight.value.photos.splice(_findPhotoIndex(data.id), 1);
});
}
const {
uploadInProgress, handlePhotosUpload, batchRotatePhotos, deletePhoto, updateSinglePhoto
} = useBasicPhotoOperations({});
const setTitlePhoto = (photo) => {
useFlightsStore().update(flight.value.id, {titlePhotoId: photo.id}).then(f => {
@@ -105,38 +88,6 @@ const setTitlePhoto = (photo) => {
});
}
const rotatePhotos = ({photos, direction}) => {
const promises = [];
for (const photo of photos) {
promises.push(usePhotosStore().changeOrientation(photo.id, direction).then(data => {
const idx = _findPhotoIndex(data.id);
data.thumbnailUrl += "?t=" + (new Date()).getTime();
flight.value.photos[idx] = 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("Otočeno " + success + " fotografií"));
if (error > 0) $q.notify(errorObject(`Nepovedlo se otočit ${error} fotografi`))
});
}
const updateSinglePhoto = (id, formData) => {
formData.copilots = formData.copilots.map(c => ({id: c.id, name: c.name}));
return usePhotosStore().update(id, formData).then((data) => {
const idx = _findPhotoIndex(data.id);
flight.value.photos[idx] = data;
usePointsOfInterestStore().fetch({});
});
}
const handlePhotoUpdate = (flightId, formData) => {
const photoId = formData.id;
delete formData.id;
@@ -240,18 +191,18 @@ const handleBatchPhotoEdit = async (flightId, data) => {
<q-tab-panel name="photos">
<FlightFormPhotos
:flight="flight"
:is-request-pending="isRequestPending || uploadInProgress"
:is-request-pending="uploadInProgress"
@save="handlePhotosUpload"
/>
<template v-if="flight">
<PhotosEditorList
:title-photo="flight.titlePhoto"
:photos="flight.photos"
:photos="photos"
:show-actions="true"
@edit="openPhotoEdit"
@batch-edit="openBatchPhotoForm"
@batch-rotate="rotatePhotos"
@batch-rotate="batchRotatePhotos"
@delete="deletePhoto"
@set-title-photo="setTitlePhoto"
/>
@@ -97,6 +97,7 @@ const togglePublicVisibility = (variables) => toggleVisibility({
:event-detail-route="flight.event ? {name: 'eventDetail', params: {id: flight.event.id}} : null"
:aircraft-detail-route="{name: 'aircraftDetail'}"
:copilot-detail-route="{name: 'copilotDetail'}"
:logged-user="loggedUser"
/>
<ContentCardEditButton