-
-
+
+
{{ photo.name }}
@@ -40,16 +91,17 @@ const openDetail = (photo, idx) => {
-
+
+
-
-
-
+
+
+
-
+
diff --git a/src/composables/dialog.js b/src/composables/dialog.js
index c067ee4..b6366f1 100644
--- a/src/composables/dialog.js
+++ b/src/composables/dialog.js
@@ -8,11 +8,21 @@ export const confirmObject = (message, title) => ({
export const successObject = (message) => ({
message,
position: "top",
- color: "positive"
+ color: "positive",
+ progress: true,
});
+export const warningObject = (message) => ({
+ message,
+ position: "top",
+ color: "warning",
+});
+
+
export const errorObject = (message) => ({
message,
position: "top",
- color: "negative"
+ color: "negative",
+ timeout: 5 * 60 * 1000,
+ actions: [{ icon: 'close', color: 'white', round: true, handler: () => { }}]
})
diff --git a/src/composables/objects/aircraft.js b/src/composables/objects/aircraft.js
index 435a11d..d64bdf5 100644
--- a/src/composables/objects/aircraft.js
+++ b/src/composables/objects/aircraft.js
@@ -21,3 +21,5 @@ export const fetchAircrafts = () => {
loading.value = true;
useAircraftsStore().fetch().finally(() => loading.value = false);
}
+
+export const isRequestPending = storeToRefs(useAircraftsStore).isMutationRunning;
diff --git a/src/composables/objects/copilot.js b/src/composables/objects/copilot.js
index b8a8006..09f51b0 100644
--- a/src/composables/objects/copilot.js
+++ b/src/composables/objects/copilot.js
@@ -19,3 +19,5 @@ export const fetchCopilots = () => {
loading.value = true;
return useCopilotsStore().fetch().finally(() => loading.value = false);
}
+
+export const isRequestPending = storeToRefs(useCopilotsStore()).isMutationRunning;
diff --git a/src/composables/objects/flight.js b/src/composables/objects/flight.js
index bfabaf0..152c0b5 100644
--- a/src/composables/objects/flight.js
+++ b/src/composables/objects/flight.js
@@ -43,3 +43,5 @@ export const handleDeleteFlight = ($q, flightId, onOkCallback = () => {
useFlightsStore().delete(flightId).then(onOkCallback);
});
};
+
+export const isRequestPending = storeToRefs(useFlightsStore()).isRequestPending;
diff --git a/src/composables/photos/batchEdit.js b/src/composables/photos/batchEdit.js
new file mode 100644
index 0000000..694212c
--- /dev/null
+++ b/src/composables/photos/batchEdit.js
@@ -0,0 +1,30 @@
+import {ref} from "vue";
+import {usePhotosStore} from "stores/Photo";
+import {fetchFlight} from "src/composables/objects/flight";
+
+export const openBatchEdit = ref(false);
+export const editBatchPhotos = ref([]);
+export const openBatchPhotoForm = (photos) => {
+ openBatchEdit.value = true;
+ editBatchPhotos.value = photos;
+}
+
+export const handleBatchPhotoEdit = (flightId, data) => {
+ const photoIds = data.photoIds;
+ delete data.photoIds;
+ delete data.id;
+
+ const promises = [];
+ for (const id of photoIds) {
+ const updateData = {};
+ if (data.name !== '') updateData.name = data.name;
+ if (data.description !== '') updateData.description = data.description;
+ if (data.pointOfInterest) updateData.pointOfInterest = data.pointOfInterest;
+
+ if (Object.keys(updateData).length === 0) continue;
+
+ promises.push(usePhotosStore().update(id, updateData));
+ }
+
+ Promise.all(promises).finally(() => fetchFlight(flightId))
+}
diff --git a/src/composables/photos/simpleEdit.js b/src/composables/photos/simpleEdit.js
new file mode 100644
index 0000000..3b4b6a0
--- /dev/null
+++ b/src/composables/photos/simpleEdit.js
@@ -0,0 +1,22 @@
+import {usePhotosStore} from "stores/Photo";
+import {fetchFlight} from "src/composables/objects/flight";
+import {usePointsOfInterestStore} from "stores/PointsOfInterest";
+import {ref} from "vue";
+
+export const handlePhotoUpdate = (flightId, formData) => {
+ const photoId = formData.id;
+ delete formData.id;
+
+ usePhotosStore().update(photoId, formData).then((data) => {
+ fetchFlight(flightId); // nenacita se mi nove vytvoreny POI z comboboxu
+ usePointsOfInterestStore().fetch();
+ });
+};
+
+export const openEdit = ref(false);
+export const editPhoto = ref(null);
+
+export const openPhotoEdit = (photo) => {
+ openEdit.value = true;
+ editPhoto.value = photo;
+};
diff --git a/src/graphql/apollo.js b/src/graphql/apollo.js
index de299bd..5805c74 100644
--- a/src/graphql/apollo.js
+++ b/src/graphql/apollo.js
@@ -4,18 +4,20 @@ import {createUploadLink} from 'apollo-upload-client';
import {onError} from "@apollo/client/link/error";
import {useUserStore} from "stores/User";
import {useAppStore} from "stores/App";
+import {Notify} from "quasar";
+import {errorObject, warningObject} from "src/composables/dialog";
const uploadLink = createUploadLink({
- uri: process.env.API_URL+'/graphql',
+ uri: process.env.API_URL + '/graphql',
})
const handleRefreshToken = (forward, operation) => {
return fromPromise(
useUserStore().refreshAccessToken()
.catch((error) => {
- console.log("neumim refresh");
- // window.location = "/login";
+ Notify.create(warningObject("Tvoje přihlášení vypřešlo. Přihlaš se prosím znovu."));
+ window.location = "/login";
})
)
.filter((value) => Boolean(value))
@@ -40,17 +42,14 @@ const errorLink = onError(
}
if (graphQLErrors) {
- const messages = [];
for (const error of graphQLErrors) {
if (error.message === "Not found") {
useAppStore().appStatus = 404;
} else if (error.message.includes("401") || error.message.includes("Not authorized")) {
return handleRefreshToken(forward, operation);
} else {
- messages.push(error.message);
+ Notify.create(errorObject("API error: " + error.message));
}
-
- // TODO: zaridit zobrazeni erroru z messages
}
}
});
@@ -81,8 +80,7 @@ export const apolloWrapper = {
})
.then((response) => response)
.catch(err => {
- console.log(err.message);
- // console.error("Error during query: ", err)
+ console.error("Error during query: ", err)
return err;
})
},
diff --git a/src/graphql/fragments/flight.js b/src/graphql/fragments/flight.js
index 49d4d7d..1c95ac6 100644
--- a/src/graphql/fragments/flight.js
+++ b/src/graphql/fragments/flight.js
@@ -61,7 +61,6 @@ fragment flightFullInfo on Flight {
...weatherFullInfo
}
-
aircraft {
...aircraftFullInfo
}
diff --git a/src/graphql/fragments/photo.js b/src/graphql/fragments/photo.js
index 2904b9a..12b4064 100644
--- a/src/graphql/fragments/photo.js
+++ b/src/graphql/fragments/photo.js
@@ -9,7 +9,10 @@ export const FRAGMENT_PHOTO_FULL_INFO = gql`
name
description
flightId
- pointOfInterestId
+ pointOfInterest {
+ id
+ name
+ }
isFlightCover
gpsLatitude
gpsLongitude
diff --git a/src/layouts/ProfileLayout.vue b/src/layouts/ProfileLayout.vue
index 672ed49..ee4e693 100644
--- a/src/layouts/ProfileLayout.vue
+++ b/src/layouts/ProfileLayout.vue
@@ -75,11 +75,11 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Výrobce: {{ aircraft.manufacturer }}
-
-
- Model: {{ aircraft.model }}
-
-
-
-
-
-
-
-
-
+
Lety
-
- Zatím žádné lety.
-
-
+
+ Zatím žádné lety.
+
+
-
-
diff --git a/src/pages/profile/aircraft/AircraftsPage.vue b/src/pages/profile/aircraft/AircraftsPage.vue
index 9bd2bae..e71d065 100644
--- a/src/pages/profile/aircraft/AircraftsPage.vue
+++ b/src/pages/profile/aircraft/AircraftsPage.vue
@@ -4,6 +4,7 @@ import AircraftsList from "components/aircrafts/AircraftsList.vue";
import {aircrafts, fetchAircrafts, loading} from "src/composables/objects/aircraft";
import FAB from "components/FAB.vue";
import BasicListSkeleton from "components/basicSkeletons/BasicListSkeleton.vue";
+import BasicInfoBanner from "components/banners/BasicInfoBanner.vue";
onMounted(() => {
fetchAircrafts();
@@ -13,17 +14,13 @@ onMounted(() => {
-
-
-
-
-
- Aktuálně nemáš přidané žádné letadlo.
-
-
-
-
-
+
+ Aktuálně nemáš přidané žádné letadlo.
+
{
- isRequestPending.value = true;
useAircraftsStore().update(aircraftId, formData).then(() => {
$q.notify(successObject("Letadlo úspěšně upraveno"));
- $router.push({name: "aircrafts"});
- }).finally(() => {
- isRequestPending.value = false;
+ $router.push({name: "aircraftDetail", params: {id: aircraftId}});
})
}
diff --git a/src/pages/profile/aircraft/NewAircraftsPage.vue b/src/pages/profile/aircraft/NewAircraftsPage.vue
index c881fd7..420b8e4 100644
--- a/src/pages/profile/aircraft/NewAircraftsPage.vue
+++ b/src/pages/profile/aircraft/NewAircraftsPage.vue
@@ -6,21 +6,17 @@ import {useQuasar} from "quasar";
import {ref} from "vue";
import {useAppStore} from "stores/App";
import {successObject} from "src/composables/dialog";
+import {isRequestPending} from "src/composables/objects/aircraft";
const $q = useQuasar();
const router = useRouter();
-let isRequestPending = ref(false);
const handleSave = (formData) => {
- isRequestPending.value = true;
useAircraftsStore().create(formData).then(() => {
$q.notify(successObject("Letadlo úspěšně vytvořeno"));
router.push({name: "aircrafts"});
- }).finally(() => {
- isRequestPending.value = false;
- })
-}
-
+ });
+};
useAppStore().setPageTitle("Nové letadlo");
useAppStore().setBreadcrumbs([
diff --git a/src/pages/profile/copilot/CopilotDetailPage.vue b/src/pages/profile/copilot/CopilotDetailPage.vue
index fcdbda9..8a59619 100644
--- a/src/pages/profile/copilot/CopilotDetailPage.vue
+++ b/src/pages/profile/copilot/CopilotDetailPage.vue
@@ -24,9 +24,11 @@ onMounted(() => {
Společné lety
+
- Zatím žádné společné lety
+ Zatím tu nemáš uložené žádné společné lety.
+
diff --git a/src/pages/profile/copilot/CopilotsPage.vue b/src/pages/profile/copilot/CopilotsPage.vue
index 502c9b9..0f91197 100644
--- a/src/pages/profile/copilot/CopilotsPage.vue
+++ b/src/pages/profile/copilot/CopilotsPage.vue
@@ -5,7 +5,7 @@ import CopilotsList from "components/copilots/CopilotsList.vue";
import FAB from "components/FAB.vue";
import {useAppStore} from "stores/App";
import BasicListSkeleton from "components/basicSkeletons/BasicListSkeleton.vue";
-import BasicInfoBanner from "components/BasicInfoBanner.vue";
+import BasicInfoBanner from "components/banners/BasicInfoBanner.vue";
onMounted(() => {
fetchCopilots();
@@ -16,7 +16,10 @@ onMounted(() => {
-
+
Zatím tu není nikdo. Přidej si let s někým nebo kopilota vytvoř ručně tu.
diff --git a/src/pages/profile/copilot/EditCopilotPage.vue b/src/pages/profile/copilot/EditCopilotPage.vue
index 4893f3e..6d3dc92 100644
--- a/src/pages/profile/copilot/EditCopilotPage.vue
+++ b/src/pages/profile/copilot/EditCopilotPage.vue
@@ -1,10 +1,10 @@
-
+
diff --git a/src/pages/profile/copilot/NewCopilotPage.vue b/src/pages/profile/copilot/NewCopilotPage.vue
index b1b8195..cf641b8 100644
--- a/src/pages/profile/copilot/NewCopilotPage.vue
+++ b/src/pages/profile/copilot/NewCopilotPage.vue
@@ -1,24 +1,20 @@
-
- Moje lety
- {{ flightName(flight) }}
- Editace
-
-
-
+
@@ -126,33 +115,41 @@ const openPhotoEdit = (photo) => {
-
-
- Tu nejsou videt fotky po nahrani
-
+
+
+
+
+
diff --git a/src/pages/profile/flight/FlightDetailPage.vue b/src/pages/profile/flight/FlightDetailPage.vue
index 73a6cb1..eef7af6 100644
--- a/src/pages/profile/flight/FlightDetailPage.vue
+++ b/src/pages/profile/flight/FlightDetailPage.vue
@@ -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"))
});
};
-
@@ -82,6 +84,7 @@ const copyLinkToClipboard = () => {
diff --git a/src/pages/profile/flight/FlightsPage.vue b/src/pages/profile/flight/FlightsPage.vue
index f23cb30..bef3329 100644
--- a/src/pages/profile/flight/FlightsPage.vue
+++ b/src/pages/profile/flight/FlightsPage.vue
@@ -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(() => {
-
-
-
-
-
- Nemáš zaznamenaný žádný let.
-
-
-
-
-
+
+ Nemáš zaznamenaný žádný let.
+
-
+
diff --git a/src/pages/profile/flight/NewFlightPage.vue b/src/pages/profile/flight/NewFlightPage.vue
index 757896c..de121c1 100644
--- a/src/pages/profile/flight/NewFlightPage.vue
+++ b/src/pages/profile/flight/NewFlightPage.vue
@@ -1,5 +1,5 @@
@@ -25,12 +31,12 @@ const logUser = () => {
-
+
-
+
@@ -41,9 +47,9 @@ const logUser = () => {
-
- Zapomenuté heslo
-
+
+
+
diff --git a/src/pages/public/PilotProfilePage.vue b/src/pages/public/PilotProfilePage.vue
index d2691cf..82c1d62 100644
--- a/src/pages/public/PilotProfilePage.vue
+++ b/src/pages/public/PilotProfilePage.vue
@@ -41,6 +41,7 @@ onMounted(() => {
:items="flights"
:displayVisibilityInfo="loggedUser.id === pilot.id"
:route-detail="{name: 'publicFlightDetail', params: {username: username}}"
+ class="q-mb-md"
/>
diff --git a/src/pages/public/RegisterPage.vue b/src/pages/public/RegisterPage.vue
index 2419d84..c08cbdf 100644
--- a/src/pages/public/RegisterPage.vue
+++ b/src/pages/public/RegisterPage.vue
@@ -23,7 +23,6 @@ const registerUser = () => {
})
}).catch(({response}) => {
- console.log(response.detail);
if (response.detail === 'User already exists') {
$q.notify(errorObject("Uživatel s tímto e-mailem je již registrovaný. Zkus se přihlásit."));
} else {
diff --git a/src/stores/Copilots.js b/src/stores/Copilots.js
index e3d79c7..8f06695 100644
--- a/src/stores/Copilots.js
+++ b/src/stores/Copilots.js
@@ -6,7 +6,8 @@ import {updateInItems} from "stores/helpers";
export const useCopilotsStore = defineStore('SecondPilots', {
state: () => ({
- items: []
+ items: [],
+ isMutationRunning: false,
}),
actions: {
@@ -21,19 +22,20 @@ export const useCopilotsStore = defineStore('SecondPilots', {
},
create(formData) {
delete formData['id'];
- return apolloWrapper.mutate(CREATE_COPILOT, {input: formData}).then(({data}) => {
- this.items.push(data.createCopilot);
- return data.createCopilot;
- })
+ this.isMutationRunning = true;
+ return apolloWrapper.mutate(CREATE_COPILOT, {input: formData}).then(({data}) => {
+ const copilot = data.createCopilot;
+ this.items.push(copilot);
+ return copilot;
+ }).finally(() => this.isMutationRunning = false);
},
update(id, formData) {
return apolloWrapper.mutate(EDIT_COPILOT, {id: id, input: formData}).then(({data}) => {
const copilot = data.editCopilot;
-
updateInItems(this.items, "id", copilot);
return copilot;
- });
+ }).finally(() => this.isMutationRunning = false);
},
}
})
diff --git a/src/stores/FlashMessages.js b/src/stores/FlashMessages.js
deleted file mode 100644
index 5ed267b..0000000
--- a/src/stores/FlashMessages.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import {defineStore} from 'pinia'
-
-export const useFlashMessagesStore = defineStore('FlashMessages', {
- state: () => ({
- items: []
- }),
-
- actions: {
- add(title, content, type) {
-
- }
- }
-})
diff --git a/src/stores/Flights.js b/src/stores/Flights.js
index b435b9d..06b5222 100644
--- a/src/stores/Flights.js
+++ b/src/stores/Flights.js
@@ -49,11 +49,8 @@ export const useFlightsStore = defineStore('Flights', {
return apolloWrapper
.query(FLIGHTS_LIST, {username})
.then((resp) => {
- console.log(resp);
const data = resp.data;
-
this.items = data.flights;
-
return data.flights;
}).catch(err => console.log(err));
},
diff --git a/src/stores/Photo.js b/src/stores/Photo.js
index e45e126..4664f76 100644
--- a/src/stores/Photo.js
+++ b/src/stores/Photo.js
@@ -3,6 +3,9 @@ import {apolloWrapper} from "src/graphql/apollo";
import {DELETE_PHOTO, EDIT_PHOTO, UPLOAD_PHOTO} from "src/graphql/mutations/photo";
export const usePhotosStore = defineStore('photos', {
+ state: () => ({
+ isMutationRunning: false,
+ }),
actions: {
upload(flightId, formData) {
@@ -20,15 +23,17 @@ export const usePhotosStore = defineStore('photos', {
if (!formData.description) {
formData.description = "";
}
+
+ this.isMutationRunning = true;
return apolloWrapper.mutate(UPLOAD_PHOTO, {input: formData}).then(({data}) => {
return data.uploadPhoto;
- })
+ }).finally(() => this.isMutationRunning = false);
},
update(id, formData) {
-
+ this.isMutationRunning = true;
return apolloWrapper.mutate(EDIT_PHOTO, {id, input: formData}).then(({data}) => {
return data.editPhoto;
- })
+ }).finally(() => this.isMutationRunning = false);
},
delete(photoId) {
return apolloWrapper.mutate(DELETE_PHOTO, {id: photoId}).then(({data}) => {
diff --git a/src/stores/index.js b/src/stores/index.js
index 4746cfa..ca5bee5 100644
--- a/src/stores/index.js
+++ b/src/stores/index.js
@@ -13,7 +13,6 @@ import { createPinia } from 'pinia'
export default store((/* { ssrContext } */) => {
const pinia = createPinia()
- console.log("Pinia index");
// You can add Pinia plugins here
// pinia.use(SomePiniaPlugin)