diff --git a/src/components/flights/FlightHeaderInfo.vue b/src/components/flights/FlightHeaderInfo.vue new file mode 100644 index 0000000..f7ebcbb --- /dev/null +++ b/src/components/flights/FlightHeaderInfo.vue @@ -0,0 +1,59 @@ + + + + + + + {{ flight.name }} + + {{ flight.name }} + + + + {{ formatDatetime(flight.takeoffDatetime, FORMAT_DATE) }} + + + + + {{ turnPoint.pointOfInterest.name }} + • + + + + + + {{ flight.aircraft.callSign }} + + + + + + + + + + + + + diff --git a/src/components/flights/FlightsList.vue b/src/components/flights/FlightsList.vue index 76f0f7f..56c76c3 100644 --- a/src/components/flights/FlightsList.vue +++ b/src/components/flights/FlightsList.vue @@ -3,8 +3,6 @@ import {minutesToHumanReadable} from "src/composables/datetimeUtils"; import {flightName} from "src/composables/flight"; import AvatarFromPhoto from "components/avatars/AvatarFromPhoto.vue"; import {useInfiniteScroll} from "src/composables/pagination"; -import {useQuasar} from "quasar"; -import {computed} from "vue"; const props = defineProps({ items: { @@ -27,8 +25,6 @@ const routeDetail = (flight) => { else return {name: "flightDetail", params: {id: flight.id}} }; - -const $q = useQuasar() @@ -44,8 +40,6 @@ const $q = useQuasar() clickable :to="routeDetail(flight)" > - - diff --git a/src/components/flights/slider/LatestFlightsSlider.vue b/src/components/flights/LatestFlightsSlider.vue similarity index 52% rename from src/components/flights/slider/LatestFlightsSlider.vue rename to src/components/flights/LatestFlightsSlider.vue index 02107a0..a54c291 100644 --- a/src/components/flights/slider/LatestFlightsSlider.vue +++ b/src/components/flights/LatestFlightsSlider.vue @@ -1,7 +1,7 @@ - - - - - {{ flightName(flight) }} - - - - - @{{ flight.pilot.publicUsername }} - - diff --git a/src/components/photos/PhotoGallery.vue b/src/components/photos/PhotoGallery.vue index 870f1f6..8771f3f 100644 --- a/src/components/photos/PhotoGallery.vue +++ b/src/components/photos/PhotoGallery.vue @@ -75,7 +75,7 @@ watch(() => [openedPhoto.value, $lightbox.value], () => { { - return [aircraft.organization?.name, aircraft.callSign, aircraft.manufacturer, aircraft.model] + return ["letadlo", "letoun", aircraft.organization?.name, aircraft.callSign, aircraft.manufacturer, aircraft.model] }; export const flightEventKeywords = (event) => { diff --git a/src/composables/pagination.js b/src/composables/pagination.js index 5386ed9..292abba 100644 --- a/src/composables/pagination.js +++ b/src/composables/pagination.js @@ -11,33 +11,36 @@ export const usePagination = ({fetchFunction, itemsPerPage = 10}) => { const filters = ref({}); const hasMoreData = ref(true) + const isQueryRunning = ref(false) + const loadFirstPage = () => { paginationOffset.value = 0 + isQueryRunning.value = true return fetchFunction({ - ...filters.value, - limit: paginationLimit.value, - offset: 0, - appendItems: false + ...filters.value, limit: paginationLimit.value, offset: 0, appendItems: false }).then((data) => { - console.log("first page", data, data.length, paginationLimit.value) paginationOffset.value += paginationLimit.value; hasMoreData.value = data.length === paginationLimit.value; }) + .finally(() => { + isQueryRunning.value = false + }) } const loadPage = (index, done) => { - return fetchFunction({ - ...filters.value, - appendItems: true, - limit: paginationLimit.value, - offset: paginationOffset.value, - }).then((data) => { - console.log("load page", data, data.length, paginationOffset.value, paginationLimit.value) + if (isQueryRunning.value) return + isQueryRunning.value = true + return fetchFunction({ + ...filters.value, appendItems: true, limit: paginationLimit.value, offset: paginationOffset.value, + }).then((data) => { paginationOffset.value += paginationLimit.value; hasMoreData.value = data.length === paginationLimit.value; if (done) done() }) + .finally(() => { + isQueryRunning.value = false + }) } const handleFiltersChanged = (newFilters) => { @@ -65,9 +68,7 @@ export const useInfiniteScroll = (emits, props) => { const emitsDef = ["load-more"] const propsDef = { hasMoreData: { - type: Boolean, - required: false, - default: true + type: Boolean, required: false, default: true } } diff --git a/src/graphql/fragments/aircraft_basic.js b/src/graphql/fragments/aircraft_basic.js index ec00e16..b78a4b4 100644 --- a/src/graphql/fragments/aircraft_basic.js +++ b/src/graphql/fragments/aircraft_basic.js @@ -1,14 +1,14 @@ import gql from "graphql-tag"; export const FRAGMENT_AIRCRAFT_BASIC_INFO = gql` -fragment aircraftBasicInfo on Aircraft { - id - callSign - manufacturer - - organization { + fragment aircraftBasicInfo on Aircraft { id - name + callSign + manufacturer + + organization { + id + name + } } -} `; diff --git a/src/graphql/fragments/airport.js b/src/graphql/fragments/airport.js index c96f32c..bcbd29f 100644 --- a/src/graphql/fragments/airport.js +++ b/src/graphql/fragments/airport.js @@ -1,5 +1,17 @@ import gql from "graphql-tag"; +export const FRAGMENT_AIRPORT_LIST_INFO = gql` + fragment airportListInfo on Airport { + id + name + icaoCode + gpsLatitude + gpsLongitude + elevation + iconUrl + } +`; + export const FRAGMENT_AIRPORT_INFO = gql` fragment airportInfo on Airport { id diff --git a/src/graphql/fragments/flight_list.js b/src/graphql/fragments/flight_list.js index 99f0f6d..431026d 100644 --- a/src/graphql/fragments/flight_list.js +++ b/src/graphql/fragments/flight_list.js @@ -1,5 +1,5 @@ import gql from "graphql-tag"; -import {FRAGMENT_AIRPORT_INFO} from "src/graphql/fragments/airport"; +import {FRAGMENT_AIRPORT_LIST_INFO} from "src/graphql/fragments/airport"; import {FRAGMENT_AIRCRAFT_BASIC_INFO} from "src/graphql/fragments/aircraft_basic"; export const FRAGMENT_FLIGHT_LIST_INFO = gql` @@ -33,11 +33,11 @@ fragment flightListInfo on Flight { } takeoffAirport { - ...airportInfo + ...airportListInfo } landingAirport { - ...airportInfo + ...airportListInfo } aircraft { @@ -45,7 +45,7 @@ fragment flightListInfo on Flight { } } -${FRAGMENT_AIRPORT_INFO} +${FRAGMENT_AIRPORT_LIST_INFO} ${FRAGMENT_AIRCRAFT_BASIC_INFO} `; diff --git a/src/pages/public/IndexPage.vue b/src/pages/public/IndexPage.vue index 83bbbd8..be59486 100644 --- a/src/pages/public/IndexPage.vue +++ b/src/pages/public/IndexPage.vue @@ -2,7 +2,7 @@ import {useMeta} from "quasar"; import {metaData} from "src/composables/meta"; import AppFooter from "components/AppFooter.vue"; -import LatestFlightsSlider from "components/flights/slider/LatestFlightsSlider.vue"; +import LatestFlightsSlider from "components/flights/LatestFlightsSlider.vue"; import {onMounted} from "vue"; import {useFlightsStore} from "stores/Flights"; import {storeToRefs} from "pinia"; diff --git a/src/pages/public/aircraft/AircraftDetailPage.vue b/src/pages/public/aircraft/AircraftDetailPage.vue index e4538ed..937e34b 100644 --- a/src/pages/public/aircraft/AircraftDetailPage.vue +++ b/src/pages/public/aircraft/AircraftDetailPage.vue @@ -28,27 +28,24 @@ import {homepageBreadcrumbs} from "src/composables/breadcrumbs"; const {aircraft, isQueryRunning} = storeToRefs(useAircraftsStore()); const {photos, isQueryRunning: arePhotosLoading} = storeToRefs(usePhotosStore()); -const {flights, totalItemsCount, isQueryRunning: areFlightsLoading} = storeToRefs(useFlightsStore()); +const {flights, isQueryRunning: areFlightsLoading} = storeToRefs(useFlightsStore()); useAppStore().setPageTitle(aircraft.value.callSign); useMeta(() => metaData({ title: aircraft.value.callSign, image: aircraft.value.titleImage?.url, - keywords: [ - "letadlo", ...aircraftKeywords(aircraft.value) - ], + keywords: aircraftKeywords(aircraft.value), description: aircraft.value.description || `Detail letadla ${aircraft.value.callSign}.` })); useAppStore().setBreadcrumbs([ - ...homepageBreadcrumbs(), + ...homepageBreadcrumbs(), {label: "Letadla"}, {label: aircraft.value.callSign} ]); -const {filters, loadPage, paginationLimit} = usePagination({fetchFunction: useFlightsStore().fetchPublic}); -filters.value = {aircraftId: aircraft.value.id}; +const {handleFiltersChanged, hasMoreData, loadPage} = usePagination({fetchFunction: useFlightsStore().fetchPublic}); onMounted(() => { - loadPage(false); + handleFiltersChanged({aircraftId: aircraft.value.id}) usePhotosStore().fetchPublic({aircraftId: aircraft.value.id}); }); @@ -74,10 +71,9 @@ onMounted(() => { diff --git a/src/pages/public/pilotProfile/EventDetailPage.vue b/src/pages/public/pilotProfile/EventDetailPage.vue index 3239834..e4be0e6 100644 --- a/src/pages/public/pilotProfile/EventDetailPage.vue +++ b/src/pages/public/pilotProfile/EventDetailPage.vue @@ -39,46 +39,41 @@ useMeta(() => metaData({ description: event.value.description })) -const {filters, loadPage, paginationLimit} = usePagination({fetchFunction: useFlightsStore().fetchPublic}); -filters.value = {username: props.pilot.publicUsername, eventId: event.value.id}; +const {loadPage, hasMoreData, handleFiltersChanged} = usePagination({fetchFunction: useFlightsStore().fetchPublic}); onMounted(() => { - loadPage(false); + handleFiltersChanged({username: props.pilot.publicUsername, eventId: event.value.id}) }) -const {flights, totalItemsCount, isQueryRunning: areFlightsLoading} = storeToRefs(useFlightsStore()); +const {flights, isQueryRunning: areFlightsLoading} = storeToRefs(useFlightsStore()); - - + - - + + - + - - - + + + - Lety + Lety - - Zatím tu nemáš uložené žádné lety. - + + Zatím tu nemáš uložené žádné lety. + - + - - - + + diff --git a/src/pages/public/pilotProfile/FlightDetailPage.vue b/src/pages/public/pilotProfile/FlightDetailPage.vue index 6ce11fc..c3de4fb 100644 --- a/src/pages/public/pilotProfile/FlightDetailPage.vue +++ b/src/pages/public/pilotProfile/FlightDetailPage.vue @@ -35,6 +35,8 @@ import {useAirportsStore} from "stores/Airports"; import {useFlightPlansStore} from "stores/FlightPlans"; import {FORMAT_DATE, formatDatetime} from "src/composables/datetimeUtils"; import AvatarFromPhoto from "components/avatars/AvatarFromPhoto.vue"; +import BreadcrumbsNavigation from "components/navigation/BreadcrumbsNavigation.vue"; +import {publicFlightBreadcrumbs} from "src/composables/breadcrumbs"; const {isQueryRunning, flight} = storeToRefs(useFlightsStore()); @@ -58,7 +60,9 @@ const flightNameFormatted = flightName(flight.value); const event = computed(() => flight.value.event); useAppStore().setPageTitle(flightNameFormatted); -useAppStore().setBreadcrumbs([])//publicFlightBreadcrumbs(pilot.value, flight.value, event.value, false)); +useAppStore().setBreadcrumbs(publicFlightBreadcrumbs(pilot.value, flight.value, event.value, false)); +const {breadcrumbs} = storeToRefs(useAppStore()); + useMeta(() => metaData({ title: `${flightNameFormatted} - ${pilot.value.name}`, @@ -74,62 +78,58 @@ useMeta(() => metaData({ )); -const contentTabs = ref() +const titleImageBottomAnchor = ref() const scrollToContent = () => { - contentTabs.value.$el.scrollIntoView({behavior: "smooth"}); + console.log(titleImageBottomAnchor.value) + if (!titleImageBottomAnchor.value) { + console.log("nemam anchor") + return + } + + titleImageBottomAnchor.value.scrollIntoView({behavior: "smooth"}); } const tab = ref("photos") - - - - {{ flight.name }} - - - {{ formatDatetime(flight.takeoffDatetime, FORMAT_DATE) }} - - + + + + + + - - {{ turnPoint.pointOfInterest.name }} - • - - - - - {{ flight.description }} - - - - Detail letu - - - - - - {{ pilot.name }} - + + + + + + + + + + + + + + {{ pilot.name }} + + + + + + + - - - - - - diff --git a/src/pages/public/pilotProfile/FlightsListPage.vue b/src/pages/public/pilotProfile/FlightsListPage.vue index 3e1742a..a70ed2c 100644 --- a/src/pages/public/pilotProfile/FlightsListPage.vue +++ b/src/pages/public/pilotProfile/FlightsListPage.vue @@ -28,19 +28,18 @@ useMeta(() => metaData({ useAppStore().setPageTitle(props.pilot.publicUsername); useAppStore().setBreadcrumbs(publicProfileBreadcrumbs(props.pilot, false)) -const {filters, loadPage, paginationLimit} = usePagination({fetchFunction: useFlightsStore().fetchPublic}); -filters.value = {username: props.pilot.publicUsername}; +const {loadPage, handleFiltersChanged} = usePagination({fetchFunction: useFlightsStore().fetchPublic}); onMounted(() => { - loadPage(false); + handleFiltersChanged({username: props.pilot.publicUsername}) }); -const {flights, totalItemsCount, isQueryRunning: areFlightsLoading} = storeToRefs(useFlightsStore()); +const {flights, isQueryRunning: areFlightsLoading} = storeToRefs(useFlightsStore()); - + Tento pilot zatím nepublikoval žádný let. @@ -49,9 +48,6 @@ const {flights, totalItemsCount, isQueryRunning: areFlightsLoading} = storeToRef diff --git a/src/pages/public/poi/PointOfInterestDetailPage.vue b/src/pages/public/poi/PointOfInterestDetailPage.vue index 8e39626..6472b4c 100644 --- a/src/pages/public/poi/PointOfInterestDetailPage.vue +++ b/src/pages/public/poi/PointOfInterestDetailPage.vue @@ -41,11 +41,11 @@ useAppStore().setBreadcrumbs([ {label: pointOfInterest.value.name} ]); -const {filters, loadPage, paginationLimit} = usePagination({fetchFunction: useFlightsStore().fetchPublic}); -filters.value = {pointOfInterestId: pointOfInterest.value.id}; +const {loadPage, handleFiltersChanged, hasMoreData} = usePagination({fetchFunction: useFlightsStore().fetchPublic}); + onMounted(() => { usePhotosStore().fetchPublic({pointOfInterestId: pointOfInterest.value.id}); - loadPage(false); + handleFiltersChanged({pointOfInterestId: pointOfInterest.value.id}); }); @@ -79,7 +79,8 @@ onMounted(() => { :is-query-running="areFlightsLoading" :items-per-page="paginationLimit" :public="true" - @load-more="loadPage(true)" + :has-more-data="hasMoreData" + @load-more="loadPage($event.index, $event.done)" />