Uprava publikovani objektu, bugfixing

This commit is contained in:
Michal Kváček
2024-01-18 06:52:39 +01:00
parent 5a5c7cb645
commit 0c89884b23
17 changed files with 105 additions and 46 deletions
+2 -2
View File
@@ -34,7 +34,7 @@ const props = defineProps({
<q-item-section>
<router-link
:to="{...aircraftDetailRoute, params: {id: flight.aircraft.id, callSign: flight.aircraft.callSign}}"
v-if="aircraftDetailRoute"
v-if="flight.aircraft.isPublic"
>
{{ flight.aircraft.callSign }}
</router-link>
@@ -79,7 +79,7 @@ const props = defineProps({
<q-item-section>
<template v-if="poi.pointOfInterest">
<router-link
:to="{name: poiDetailRoute.name, params: {...poiDetailRoute.params, poiSlug: poi.pointOfInterest.urlSlug, id: poi.pointOfInterest.id}}"
:to="{name: poiDetailRoute.name, params: {...poiDetailRoute.params, slug: poi.pointOfInterest.urlSlug, id: poi.pointOfInterest.id}}"
v-if="poi.pointOfInterest.isPublic"
>
{{ poi.pointOfInterest.name }}
@@ -52,6 +52,7 @@ watch(poi, (newVal) => {
});
watch(() => props.flight.track, (newVal) => {
formData.track = [];
for (const i in newVal) {
const trackInfo = newVal[i];
const info = {landingDuration: trackInfo.landingDuration};
@@ -16,7 +16,7 @@ const props = defineProps({
<template>
<div class="text-h4">
<router-link :class="`text-${props.textColor}`" :to="{name: 'publicFlightDetail', params: {username: flight.pilot.publicUsername, id: flight.id}}">
<router-link :class="`text-${props.textColor}`" :to="{name: 'publicFlightDetail', params: {username: flight.pilot.publicUsername, flightSlug: flight.urlSlug}}">
{{ flightName(flight) }}
</router-link>
</div>
+5 -10
View File
@@ -13,14 +13,9 @@ export const setDefaultData = (formData, defaultData) => {
}
}
export const toggleVisibility = ({store, $q, object, urlSlug = undefined}) => {
const newVisibility = !object.isPublic;
const variables = {isPublic: newVisibility};
if (urlSlug) {
variables['urlSlug'] = urlSlug;
}
store.update(object.id, variables)
.then(() => {
$q.notify(successObject(newVisibility ? "Úspěšně publikováno" : "Úspěšně skryto"));
});
export const toggleVisibility = ({store, $q, object, variables, mutation = undefined}) => {
store.update(object.id, variables, mutation)
.then(() => {
$q.notify(successObject(variables.isPublic ? "Úspěšně publikováno" : "Úspěšně skryto"));
});
}
+4 -1
View File
@@ -12,8 +12,11 @@ export const commonKeywords = [
];
export const metaData = ({title, description, keywords, image}) => {
export const aircraftKeywords = (aircraft) => {
return [aircraft.callSign, aircraft.manufacturer, aircraft.model]
};
export const metaData = ({title, description, keywords, image}) => {
const filteredKeywords = (keywords || []).filter(kw => !!kw);
const filteredDescription = stripHtml(description);
+8
View File
@@ -20,6 +20,14 @@ mutation editFlight($id: Int!, $input: EditFlightInput!) {
${FRAGMENT_FLIGHT_FULL_PRIVATE_INFO}
`;
export const TOGGLE_FLIGHT_PUBLISH = gql`
mutation toggleFlightPublish($id: Int!, $input: EditFlightInput!) {
editFlight(id: $id, input: $input) {
isPublic
urlSlug
}
}
`;
export const DELETE_FLIGHT = gql`
mutation deleteFlight($id: Int!) {
@@ -49,8 +49,8 @@ const deleteAircraft = (id) => {
});
};
const togglePublicVisibility = () => toggleVisibility({
$q, store: useAircraftsStore(), object: aircraft.value
const togglePublicVisibility = (variables) => toggleVisibility({
$q, store: useAircraftsStore(), object: aircraft.value, variables
});
const loadNextFlightsPage = (appendItems) => loadPage({
@@ -39,8 +39,8 @@ const {isQueryRunning, copilot} = storeToRefs(useCopilotsStore());
const loggedUser = storeToRefs(useLoggedUserStore()).user;
const $q = useQuasar();
const togglePublicVisibility = (data) => toggleVisibility({
$q, store: useCopilotsStore(), object: copilot.value, urlSlug: data.urlSlug
const togglePublicVisibility = (variables) => toggleVisibility({
$q, store: useCopilotsStore(), object: copilot.value, variables
});
</script>
@@ -10,6 +10,12 @@ import {useEventsStore} from "stores/Events";
import {storeToRefs} from "pinia";
import {loadPage, paginationLimit} from "src/composables/pagination";
import {useFlightsStore} from "stores/Flights";
import PublishButton from "components/inputs/PublishButton.vue";
import {useLoggedUserStore} from "stores/LoggedUser";
import {toggleVisibility} from "src/composables/form/formHandling";
import {TOGGLE_FLIGHT_PUBLISH} from "src/graphql/mutations/flight";
import {useQuasar} from "quasar";
import CopyLinkButton from "components/inputs/CopyLinkButton.vue";
const eventId = parseInt(useRoute().params.id);
onMounted(() => {
@@ -32,6 +38,13 @@ const loadNextFlightsPage = (appendItems) => loadPage({
});
const {isQueryRunning: areFlightsLoading, totalItemsCount, flights} = storeToRefs(useFlightsStore());
const loggedUser = storeToRefs(useLoggedUserStore()).user;
const $q = useQuasar();
const togglePublicVisibility = (variables) => toggleVisibility({
$q, store: useEventsStore(), object: event.value, variables
});
</script>
<template>
@@ -52,6 +65,16 @@ const {isQueryRunning: areFlightsLoading, totalItemsCount, flights} = storeToRef
</q-item>
</q-list>
<PublishButton
:url-prefix="`${loggedUser.publicUsername}/udalosti/`"
:is-public="event.isPublic"
:require-url-slug="event.urlSlug === ''"
@change-visibility="togglePublicVisibility"
/>
<CopyLinkButton
:route="{name: 'publicEventDetail', params: {username: loggedUser.publicUsername, eventSlug: event.urlSlug}}"
/>
<article v-html="event.description"/>
<h3>Lety</h3>
+13 -7
View File
@@ -1,3 +1,13 @@
<script>
import {useFlightsStore} from "stores/Flights";
export default {
preFetch({currentRoute}) {
useFlightsStore().fetchDetail(currentRoute.params.id);
}
}
</script>
<script setup>
import {useRoute, useRouter} from "vue-router";
import {watch} from "vue";
@@ -7,7 +17,6 @@ import {useAppStore} from "stores/App";
import FlightBasicInfo from "components/flights/FlightBasicInfo.vue";
import {useQuasar} from "quasar";
import {confirmObject, successObject} from "src/composables/dialog";
import {useFlightsStore} from "stores/Flights";
import FlightTrackMap from "components/flights/FlightTrackMap.vue";
import {useLoggedUserStore} from "stores/LoggedUser";
import {storeToRefs} from "pinia";
@@ -18,11 +27,11 @@ import ContentCardEditButton from "components/ContentCardEditButton.vue";
import {toggleVisibility} from "src/composables/form/formHandling";
import PublishButton from "components/inputs/PublishButton.vue";
import CopyLinkButton from "components/inputs/CopyLinkButton.vue";
import {TOGGLE_FLIGHT_PUBLISH} from "src/graphql/mutations/flight";
const flightId = parseInt(useRoute().params.id);
const loggedUser = storeToRefs(useLoggedUserStore()).user;
useFlightsStore().fetchDetail(flightId);
const {isQueryRunning, flight} = storeToRefs(useFlightsStore());
watch(() => flight.value, (f) => {
if (!f) return;
@@ -46,11 +55,8 @@ const handleDeleteAndRedirect = () => {
});
}
const togglePublicVisibility = (data) => toggleVisibility({
$q,
store: useFlightsStore(),
object: flight.value,
urlSlug: data.isPublic ? data.urlSlug : undefined
const togglePublicVisibility = (variables) => toggleVisibility({
$q, store: useFlightsStore(), object: flight.value, mutation: TOGGLE_FLIGHT_PUBLISH, variables
});
</script>
@@ -43,8 +43,8 @@ const {isQueryRunning: areFlightsLoading, totalItemsCount, flights} = storeToRef
const {isQueryRunning, pointOfInterest} = storeToRefs(usePointsOfInterestStore());
const $q = useQuasar();
const togglePublicVisibility = (data) => toggleVisibility({
$q, store: usePointsOfInterestStore(), object: pointOfInterest.value, urlSlug: data.urlSlug
const togglePublicVisibility = (variables) => toggleVisibility({
$q, store: usePointsOfInterestStore(), object: pointOfInterest.value, variables
});
</script>
@@ -10,6 +10,7 @@ import {loadPage, paginationLimit} from "src/composables/pagination";
useAppStore().setPageTitle("Zajímavá místa");
paginationLimit.value = 15;
const loadNextPage = (appendItems) => loadPage({
fetchFunc: usePointsOfInterestStore().fetch,
appendItems
@@ -21,6 +21,7 @@ import {useMeta} from "quasar";
import {metaData} from "src/composables/meta";
import PhotoGallerySkeleton from "components/photos/skeletons/PhotoGallerySkeleton.vue";
import {loadPage, paginationLimit} from "src/composables/pagination";
import BasicInfoBanner from "components/banners/BasicInfoBanner.vue";
const props = defineProps({
pilot: {
@@ -70,6 +71,9 @@ onMounted(() => {
<h3>Společné lety</h3>
<FlightsListSkeleton v-if="areFlightsLoading && flights.length === 0"/>
<BasicInfoBanner v-else-if="!areFlightsLoading && flights.length === 0">
Zatím tu není žádný zveřejněný let.
</BasicInfoBanner>
<FlightsList
v-else
:items="flights"
@@ -19,7 +19,7 @@ import PhotoGallery from "components/photos/PhotoGallery.vue";
import {storeToRefs} from "pinia";
import {flightName} from "src/composables/flight";
import {useMeta} from "quasar";
import {metaData} from "src/composables/meta";
import {aircraftKeywords, metaData} from "src/composables/meta";
import ContentCard from "components/ContentCard.vue";
import {usePhotosStore} from "stores/Photos";
@@ -45,7 +45,7 @@ useAppStore().setBreadcrumbs([
useMeta(() => metaData({
title: `${flightNameFormatted} - ${props.pilot.name}`,
keywords: ["let", "výlet", "letadlo", props.pilot.name, flight.value.aircraft.callSign],
keywords: ["let", "výlet", "letadlo", props.pilot.name, aircraftKeywords(flight.value.aircraft)],
description: flight.value.description,
image: flight.value.titlePhoto?.url
}
@@ -62,7 +62,7 @@ useMeta(() => metaData({
<FlightBasicInfo
:flight="flight"
:poi-detail-route="{name: 'publicPOIDetail'}"
:aircraft-detail-route="flight.aircraft.isPublic ? {name: 'publicAircraftDetail'} : null"
:aircraft-detail-route="{name: 'publicAircraftDetail'}"
:copilot-detail-route="{name: 'publicCopilotDetail', params: {username: pilot.publicUsername}}"
/>
+6 -2
View File
@@ -1,6 +1,6 @@
import {defineStore} from 'pinia'
import {CREATE_EVENT, EDIT_EVENT} from "src/graphql/mutations/event";
import {mutate, query, setItems, updateInItems} from "stores/helpers";
import {mutate, query, rewriteObject, setItems, updateInItems} from "stores/helpers";
import {ref} from "vue";
import {EVENT_DETAIL, EVENT_PUBLIC_DETAIL, EVENTS_LIST, EVENTS_PUBLIC_LIST} from "src/graphql/queries/event";
@@ -56,7 +56,11 @@ export const useEventsStore = defineStore('Events', () => {
isMutationRunning,
mutation: EDIT_EVENT,
variables: {id, input}
}).then(item => updateInItems(events.value, 'id', item))
}).then(item => {
updateInItems(events.value, 'id', item);
event.value = rewriteObject(item, event.value);
return item;
})
}
return {
+4 -4
View File
@@ -1,7 +1,7 @@
import {defineStore} from 'pinia'
import {FLIGHT_DETAIL, FLIGHT_PUBLIC_DETAIL, FLIGHTS_LIST, FLIGHTS_PUBLIC_LIST} from "src/graphql/queries/flights";
import {EDIT_FLIGHT, CREATE_FLIGHT, DELETE_FLIGHT} from "src/graphql/mutations/flight";
import {deleteFromItems, mutate, query, updateInItems, setItems} from "stores/helpers";
import {deleteFromItems, mutate, query, updateInItems, setItems, rewriteObject} from "stores/helpers";
import {ref} from "vue";
export const useFlightsStore = defineStore('Flights', () => {
@@ -66,13 +66,13 @@ export const useFlightsStore = defineStore('Flights', () => {
return item;
})
const update = (id, input) => mutate({
const update = (id, input, overridenMutation = undefined) => mutate({
isMutationRunning,
mutation: EDIT_FLIGHT,
mutation: overridenMutation || EDIT_FLIGHT,
variables: {id, input}
}).then(item => {
updateInItems(flights.value, 'id', item);
flight.value = item;
flight.value = rewriteObject(item, flight.value);
return item;
})
+24 -10
View File
@@ -1,18 +1,26 @@
import {apolloWrapper} from "boot/apollo";
import {getOperationName} from "@apollo/client/utilities";
export const setItems = (data, appendItems, itemsModel, totalItemsCount) => {
const originalData = appendItems ? [...itemsModel.value] : [];
itemsModel.value = [...originalData, ...data.items];
totalItemsCount.value = data.totalItemsCount;
return data.items;
export const setItems = (data, appendItems, itemsModel, totalItemsCount) => {
const originalData = appendItems ? [...itemsModel.value] : [];
itemsModel.value = [...originalData, ...data.items];
totalItemsCount.value = data.totalItemsCount;
return data.items;
}
export const rewriteObject = (partialObject, wholeObject) => {
const result = {...wholeObject};
for (const key in partialObject) {
result[key] = partialObject[key];
}
return result;
}
export const updateInItems = (items, key, data) => {
const idx = items.findIndex(i => i[key] === data[key]);
if (idx >= 0)
items[idx] = data;
else items.push(data);
if (idx >= 0) {
items[idx] = rewriteObject(data, items[idx]);
} else items.push(data);
return items;
}
@@ -46,8 +54,14 @@ export const query = ({isQueryRunning, query, variables, refreshUnauthorized}) =
export const mutate = ({isMutationRunning, mutation, variables}) => {
isMutationRunning.value = true;
const mutationName = getOperationName(mutation);
let mutationName = getOperationName(mutation);
return apolloWrapper.mutate(mutation, variables)
.then(result => result.data[mutationName])
.then(result => {
if (typeof result.data[mutationName] === 'undefined') {
const keys = Object.keys(result.data);
mutationName = keys[0];
}
return result.data[mutationName]
})
.finally(() => isMutationRunning.value = false);
}