draft planovace
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
<script setup>
|
||||
|
||||
const props = defineProps({
|
||||
items: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-list bordered separator>
|
||||
<q-item
|
||||
clickable
|
||||
:to="{name: 'flightPlan', params: {id: flightPlan.id }}"
|
||||
v-ripple
|
||||
v-for="flightPlan of items" :key="flightPlan">
|
||||
<q-item-section avatar>
|
||||
<q-avatar icon="person" color="primary" text-color="white"/>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
{{ flightPlan.name }}
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</template>
|
||||
@@ -1,7 +1,6 @@
|
||||
<script setup>
|
||||
import {Marker} from "vue3-google-map";
|
||||
import {defineEmits, onMounted, ref} from "vue";
|
||||
import axios from "axios";
|
||||
import {onMounted} from "vue";
|
||||
import MapWrapper from "components/map/MapWrapper.vue";
|
||||
import {useGeocode} from "src/composables/geocoding";
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script setup>
|
||||
import FlightsListSkeleton from "components/flights/skeletons/FlightsListSkeleton.vue";
|
||||
import LoadMoreList from "components/LoadMoreList.vue";
|
||||
import BasicListSkeleton from "components/basicSkeletons/BasicListSkeleton.vue";
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import gql from "graphql-tag";
|
||||
|
||||
export const FRAGMENT_FLIGHT_PLAN_FULL_INFO = gql`
|
||||
fragment flightPlanFullInfo on FlightPlan {
|
||||
id
|
||||
name
|
||||
markers {
|
||||
name
|
||||
position
|
||||
type
|
||||
gpsLatitude
|
||||
gpsLongitude
|
||||
}
|
||||
}`;
|
||||
|
||||
export const FRAGMENT_FLIGHT_PLAN_LIST_INFO = gql`
|
||||
fragment flightPlanListInfo on FlightPlanListInfo {
|
||||
id
|
||||
name
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import gql from "graphql-tag";
|
||||
import {FRAGMENT_FLIGHT_PLAN_FULL_INFO} from "src/graphql/fragments/flightPlan";
|
||||
|
||||
export const CREATE_FLIGHT_PLAN = gql`
|
||||
mutation createFlight_Plan($input: CreateFlightPlanInput!) {
|
||||
createFlightPlan(input: $input) {
|
||||
...flightPlanFullInfo
|
||||
}
|
||||
}
|
||||
|
||||
${FRAGMENT_FLIGHT_PLAN_FULL_INFO}
|
||||
`;
|
||||
|
||||
export const EDIT_FLIGHT_PLAN = gql`
|
||||
mutation editFlightPlan($id: Int!, $input: EditFlightPlanInput!) {
|
||||
editFlight_Plan(id: $id, input: $input) {
|
||||
...flight_planFullInfo
|
||||
}
|
||||
}
|
||||
${FRAGMENT_FLIGHT_PLAN_FULL_INFO}
|
||||
`;
|
||||
export const DELETE_FLIGHT_PLAN = gql`
|
||||
mutation deleteFlightPlan($id: Int!) {
|
||||
deleteFlightPlan(id: $id) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import gql from "graphql-tag";
|
||||
import {FRAGMENT_FLIGHT_PLAN_LIST_INFO} from "src/graphql/fragments/flightPlan";
|
||||
|
||||
export const FLIGHT_PLANS_LIST = gql`
|
||||
query flightPlansList {
|
||||
flightPlans {
|
||||
...flightPlanListInfo
|
||||
}
|
||||
}
|
||||
|
||||
${FRAGMENT_FLIGHT_PLAN_LIST_INFO}
|
||||
`;
|
||||
|
||||
@@ -11,16 +11,16 @@ import FlightFormSteps from "components/flights/form/FlightFormSteps.vue";
|
||||
import FlightFormBasic from "components/flights/form/FlightFormBasic.vue";
|
||||
import FlightEditSkeleton from "components/flights/skeletons/FlightEditSkeleton.vue";
|
||||
|
||||
useAppStore().setPageTitle("Nový let");
|
||||
useAppStore().setBreadcrumbs([
|
||||
{to: {name: "myFlights"}, label: "Moje lety"},
|
||||
{label: "Nový"}
|
||||
]);
|
||||
|
||||
onMounted(() => {
|
||||
useAircraftsStore().fetch({})
|
||||
usePointsOfInterestStore().fetch({})
|
||||
useAirportsStore().fetch()
|
||||
|
||||
useAppStore().setPageTitle("Nový let");
|
||||
useAppStore().setBreadcrumbs([
|
||||
{to: {name: "myFlights"}, label: "Moje lety"},
|
||||
{label: "Nový"}
|
||||
]);
|
||||
});
|
||||
|
||||
const {isMutationRunning} = storeToRefs(useFlightsStore());
|
||||
@@ -46,11 +46,11 @@ const handleSave = (formData) => {
|
||||
<FlightEditSkeleton step="basic" v-if="loading"/>
|
||||
<template v-else>
|
||||
<FlightFormBasic
|
||||
@save="handleSave"
|
||||
:is-request-pending="isMutationRunning"
|
||||
:aircrafts="aircrafts"
|
||||
:airports="airports"
|
||||
:locations="pointsOfInterest"
|
||||
@save="handleSave"
|
||||
:is-request-pending="isMutationRunning"
|
||||
:aircrafts="aircrafts"
|
||||
:airports="airports"
|
||||
:locations="pointsOfInterest"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
<script setup>
|
||||
import {computed, onMounted} from "vue";
|
||||
import {useAppStore} from "stores/App";
|
||||
import CopilotEditSkeleton from "components/copilots/skeletons/CopilotEditSkeleton.vue";
|
||||
import CopilotEditForm from "components/copilots/CopilotForm.vue";
|
||||
import {useRoute, useRouter} from "vue-router";
|
||||
import {useCopilotsStore} from "stores/Copilots";
|
||||
import {successObject} from "src/composables/dialog";
|
||||
import {useQuasar} from "quasar";
|
||||
import {storeToRefs} from "pinia";
|
||||
import PhotosEditorList from "components/photos/PhotosEditorList.vue";
|
||||
import CommonEditSwitcher from "components/navigation/CommonEditSwitcher.vue";
|
||||
import PhotoGallerySkeleton from "components/photos/skeletons/PhotoGallerySkeleton.vue";
|
||||
import BasicInfoBanner from "components/banners/BasicInfoBanner.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const $router = useRouter();
|
||||
const $route = useRoute();
|
||||
|
||||
const copilotId = parseInt($route.params.id);
|
||||
|
||||
onMounted(() => {
|
||||
useCopilotsStore().fetchDetail(copilotId).then(() => {
|
||||
useAppStore().setPageTitle(`${copilot.value.name} - editace`);
|
||||
useAppStore().setBreadcrumbs([
|
||||
{to: {name: "copilots"}, label: "Kopiloti"},
|
||||
{to: {name: "copilotDetail", params: {id: copilotId}}, label: copilot.value.name},
|
||||
{label: "Editace"}
|
||||
])
|
||||
});
|
||||
});
|
||||
|
||||
const handleSave = (formData) => {
|
||||
useCopilotsStore().update(copilotId, formData).then(() => {
|
||||
$q.notify(successObject("Kopilot úspěšně upraven"));
|
||||
$router.push({name: "copilotDetail", params: {id: copilotId}});
|
||||
});
|
||||
}
|
||||
|
||||
const {isQueryRunning, isMutationRunning, copilot} = storeToRefs(useCopilotsStore());
|
||||
|
||||
const formStep = computed(() => useRoute().params.step || "info");
|
||||
const setTitlePhoto = (titlePhoto) => {
|
||||
useCopilotsStore().update(copilotId, {titlePhotoId: titlePhoto.id}).then(() => {
|
||||
$q.notify(successObject("Úvodní fotka nastavena"));
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<CommonEditSwitcher :route="{name: 'copilotEdit', params: {id: copilot.id}}"/>
|
||||
|
||||
<template v-if="formStep === 'info'">
|
||||
<CopilotEditSkeleton v-if="isQueryRunning || !copilot"/>
|
||||
<CopilotEditForm
|
||||
v-else
|
||||
:copilot="copilot"
|
||||
:is-request-pending="isMutationRunning"
|
||||
@save="handleSave"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-else-if="formStep === 'photo'">
|
||||
<PhotoGallerySkeleton v-if="isQueryRunning || !copilot" />
|
||||
<BasicInfoBanner v-else-if="!isQueryRunning && copilot.photos.length === 0">
|
||||
U tohoto kopilota nemáš označenou žádnou fotku. Bez toho není možné zvolit úvodní fotografii.
|
||||
</BasicInfoBanner>
|
||||
<PhotosEditorList
|
||||
v-else
|
||||
:photos="copilot.photos"
|
||||
:title-photo="copilot.titlePhoto"
|
||||
:show-actions="false"
|
||||
@set-title-photo="setTitlePhoto"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
@@ -0,0 +1,38 @@
|
||||
<script setup>
|
||||
import {useFlightPlansStore} from "stores/FlightPlans";
|
||||
import {storeToRefs} from "pinia";
|
||||
import {onMounted} from "vue";
|
||||
import {useAppStore} from "stores/App";
|
||||
import BasicListSkeleton from "components/basicSkeletons/BasicListSkeleton.vue";
|
||||
import BasicInfoBanner from "components/banners/BasicInfoBanner.vue";
|
||||
import FAB from "components/FAB.vue";
|
||||
import FlightPlansList from "components/flightPlans/FlightPlansList.vue";
|
||||
|
||||
useAppStore().setPageTitle("Nový plán");
|
||||
useAppStore().setBreadcrumbs([
|
||||
{to: {name: "myFlights"}, label: "Moje lety"},
|
||||
{to: {name: "flightPlans"}, label: "Plány"},
|
||||
{label: "Nový"}
|
||||
]);
|
||||
|
||||
onMounted(() => {
|
||||
useFlightPlansStore().fetch();
|
||||
});
|
||||
|
||||
|
||||
const {flightPlans, isQueryRunning} = storeToRefs(useFlightPlansStore());
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BasicListSkeleton v-if="isQueryRunning || !flightPlans"/>
|
||||
|
||||
<BasicInfoBanner
|
||||
v-else-if="!isQueryRunning && flightPlans.length === 0"
|
||||
:route-add='{name: "addOrganization"}'
|
||||
>
|
||||
Aktuálně nemáš žádné naplánované lety.
|
||||
</BasicInfoBanner>
|
||||
|
||||
<FlightPlansList :items="flightPlans" v-else/>
|
||||
<FAB :router-link="{name: 'newFlightPlan'}" mode="add"/>
|
||||
</template>
|
||||
+35
-22
@@ -10,6 +10,7 @@ import MapWrapper from "components/map/MapWrapper.vue";
|
||||
import {useGeocode} from "src/composables/geocoding";
|
||||
import {errorObject} from "src/composables/dialog";
|
||||
import {useAirportsStore} from "stores/Airports";
|
||||
import {useFlightPlansStore} from "stores/FlightPlans";
|
||||
|
||||
|
||||
const place = ref("");
|
||||
@@ -29,20 +30,24 @@ onMounted(() => {
|
||||
const markers = ref([]);
|
||||
watch(() => markers.value, (newVal) => {
|
||||
|
||||
});
|
||||
}, {deep: true});
|
||||
|
||||
const addPoint = async (point) => {
|
||||
markers.value.push({
|
||||
label: point.name,
|
||||
type: point.type,
|
||||
position: {
|
||||
lat: point.gpsLatitude,
|
||||
lng: point.gpsLongitude
|
||||
}
|
||||
})
|
||||
if (!point) return;
|
||||
|
||||
markers.value.push(point);
|
||||
// {
|
||||
// label: point.name,
|
||||
// type: point.type,
|
||||
//
|
||||
// position: {
|
||||
// lat: point.gpsLatitude,
|
||||
// lng: point.gpsLongitude
|
||||
// }
|
||||
// })
|
||||
}
|
||||
const track = computed(() => {
|
||||
return markers.value.map(m => m.position);
|
||||
return markers.value.map(m => ({lat: m.gpsLatitude, lng: m.gpsLongitude}));
|
||||
})
|
||||
|
||||
const removeMarker = (idx) => {
|
||||
@@ -58,19 +63,11 @@ const {airports} = storeToRefs(useAirportsStore());
|
||||
const placesOptions = ref(null);
|
||||
const allPlacesOptions = computed(() => {
|
||||
return [
|
||||
...pointsOfInterest.value.map(poi => ({
|
||||
name: poi.name,
|
||||
type: "poi",
|
||||
id: poi.id,
|
||||
gpsLatitude: poi.gpsLatitude,
|
||||
gpsLongitude: poi.gpsLongitude
|
||||
})),
|
||||
...pointsOfInterest.value.map(poi => ({...poi, type: "poi"})),
|
||||
...airports.value.map(airport => ({
|
||||
...airport,
|
||||
name: `${airport.icaoCode} - ${airport.name}`,
|
||||
type: "airport",
|
||||
id: airport.id,
|
||||
gpsLatitude: airport.gpsLatitude,
|
||||
gpsLongitude: airport.gpsLongitude
|
||||
}))
|
||||
].map(i => ({...i, disabled: !i.gpsLatitude || !i.gpsLongitude}));
|
||||
});
|
||||
@@ -103,6 +100,20 @@ watch(() => place.value, (newVal) => {
|
||||
addPoint(newVal);
|
||||
place.value = null;
|
||||
});
|
||||
|
||||
|
||||
const saveMarkers = () => {
|
||||
useFlightPlansStore().create({
|
||||
name: "",
|
||||
isPublic: false,
|
||||
markers: markers.value.map(m => ({
|
||||
name: m.name,
|
||||
type: m.type,
|
||||
gpsLatitude: m.gpsLatitude,
|
||||
gpsLongitude: m.gpsLongitude,
|
||||
}))
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -110,7 +121,7 @@ watch(() => place.value, (newVal) => {
|
||||
<div class="col" style="min-width: 1px">
|
||||
<MapWrapper style="width: 100%; height: 500px" :center="center" :zoom="zoom" :airspaces-data="airspacesData">
|
||||
<template v-for="marker in markers" :key="marker">
|
||||
<Marker :options="marker"/>
|
||||
<Marker :options="{label: marker.name, position: {lat: marker.gpsLatitude, lng: marker.gpsLongitude}}"/>
|
||||
</template>
|
||||
<Polyline :options="{path: track, geodesic: true, strokeColor: '#ff0000', strokeOpacity: 0.5, strokeWeight: 5}"/>
|
||||
</MapWrapper>
|
||||
@@ -143,7 +154,6 @@ watch(() => place.value, (newVal) => {
|
||||
</q-item>
|
||||
</template>
|
||||
</q-list>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -168,6 +178,9 @@ watch(() => place.value, (newVal) => {
|
||||
<!-- </template>-->
|
||||
</q-select>
|
||||
|
||||
<q-btn @click="saveMarkers" color="primary">Save</q-btn>
|
||||
|
||||
|
||||
<!-- <q-input type="text" v-bind="commonProps" v-model="place" label="Misto"/>-->
|
||||
|
||||
<q-list bordered v-if="false">
|
||||
@@ -47,7 +47,10 @@ const routes = [
|
||||
{path: 'lety/novy', name: "addFlight", component: () => import('pages/profile/flight/NewFlightPage.vue')},
|
||||
{path: 'lety/:id', name: "flightDetail", component: () => import('pages/profile/flight/FlightDetailPage.vue')},
|
||||
{path: 'lety/:id/edit/:step?', name: "flightEdit", component: () => import('pages/profile/flight/EditFlightPage.vue')},
|
||||
{path: 'planovani', name: "flightPlanner", component: () => import('pages/profile/flight/PlannerPage.vue')},
|
||||
|
||||
{path: 'plany', name: "flightPlans", component: () => import('pages/profile/flightPlanner/FlightPlansPage.vue')},
|
||||
{path: 'plany/novy', name: "newFlightPlan", component: () => import('pages/profile/flightPlanner/NewFlightPlanPage.vue')},
|
||||
{path: 'plany/:id', name: "flightPlan", component: () => import('pages/profile/flightPlanner/FlightPlanEditPage.vue')},
|
||||
|
||||
{path: 'poi', name: "poi", component: () => import('pages/profile/poi/PointsOfInterestPage.vue')},
|
||||
{path: 'poi/novy', name: "addPOI", component: () => import('pages/profile/poi/NewPointOfInterestPage.vue')},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {defineStore} from 'pinia'
|
||||
import {FLIGHT_PLAN_DETAIL, FLIGHT_PLAN_PUBLIC_DETAIL, FLIGHT_PLAN_LIST} from "src/graphql/queries/flightPlans";
|
||||
import {FLIGHT_PLANS_LIST} from "src/graphql/queries/flightPlan";
|
||||
import {CREATE_FLIGHT_PLAN, EDIT_FLIGHT_PLAN} from "src/graphql/mutations/flightPlan";
|
||||
import {mutate, query, updateInItems} from "stores/helpers";
|
||||
import {ref} from "vue";
|
||||
@@ -10,24 +10,13 @@ export const useFlightPlansStore = defineStore('FlightPlans', () => {
|
||||
const isMutationRunning = ref(false);
|
||||
const isQueryRunning = ref(false);
|
||||
|
||||
const fetchDetail = (id) => {
|
||||
return query({
|
||||
isQueryRunning,
|
||||
query: FLIGHT_PLAN_DETAIL,
|
||||
variables: {id},
|
||||
}).then(item => flightPlan.value = item);
|
||||
};
|
||||
|
||||
const fetchPublicDetail = ({urlSlug, username, uploadToken, uploadFlightSlug}) => {
|
||||
return query({
|
||||
isQueryRunning,
|
||||
query: FLIGHT_PLAN_PUBLIC_DETAIL,
|
||||
variables: {urlSlug, pilotUsername: username, uploadToken, uploadFlightSlug},
|
||||
}).then(item => {
|
||||
flightPlan.value = item;
|
||||
return item;
|
||||
});
|
||||
};
|
||||
// const fetchDetail = (id) => {
|
||||
// return query({
|
||||
// isQueryRunning,
|
||||
// query: FLIGHT_PLAN_DETAIL,
|
||||
// variables: {id},
|
||||
// }).then(item => flightPlan.value = item);
|
||||
// };
|
||||
|
||||
const fetch = () => {
|
||||
return query({
|
||||
@@ -61,6 +50,6 @@ export const useFlightPlansStore = defineStore('FlightPlans', () => {
|
||||
|
||||
return {
|
||||
flightPlan, flightPlans, isMutationRunning, isQueryRunning,
|
||||
fetch, fetchDetail, create, update, fetchPublicDetail
|
||||
fetch, create, update
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user