Fullscreen u planovace
This commit is contained in:
+13
-3
@@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {computed, ref} from "vue";
|
import {computed, ref, watch} from "vue";
|
||||||
import {minutesToHumanReadable} from "src/composables/datetimeUtils";
|
import {minutesToHumanReadable} from "src/composables/datetimeUtils";
|
||||||
import {useFlightPlanUtils} from "src/composables/flightPlan";
|
import {useFlightPlanUtils} from "src/composables/flightPlan";
|
||||||
|
|
||||||
@@ -13,13 +13,17 @@ const props = defineProps({
|
|||||||
required: false,
|
required: false,
|
||||||
default: 150
|
default: 150
|
||||||
},
|
},
|
||||||
|
isFullscreen: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
insertPosition: {
|
insertPosition: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const emits = defineEmits(["open", "change-insert-position"])
|
const emits = defineEmits(["open", "change-insert-position", "fullscren-toggle"])
|
||||||
|
|
||||||
|
|
||||||
const getDuration = (distance, speed) => Math.round(distance / speed * 60)
|
const getDuration = (distance, speed) => Math.round(distance / speed * 60)
|
||||||
@@ -42,7 +46,7 @@ const totalTime = computed(() => {
|
|||||||
|
|
||||||
<q-item>
|
<q-item>
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
<div>
|
<div style="display: flex; justify-content: space-between">
|
||||||
<q-btn
|
<q-btn
|
||||||
@click="emits('change-insert-position', 0)"
|
@click="emits('change-insert-position', 0)"
|
||||||
icon="add"
|
icon="add"
|
||||||
@@ -51,6 +55,12 @@ const totalTime = computed(() => {
|
|||||||
>
|
>
|
||||||
<template v-if="insertPosition === 0">Přidávám na začátek</template>
|
<template v-if="insertPosition === 0">Přidávám na začátek</template>
|
||||||
</q-btn>
|
</q-btn>
|
||||||
|
|
||||||
|
<q-btn
|
||||||
|
@click='emits("fullscreen-toggle")'
|
||||||
|
size="sm"
|
||||||
|
:icon="isFullscreen ? 'mdi-fullscreen-exit' : 'mdi-fullscreen'"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
|
||||||
|
import {formatDatetime} from "../../composables/datetimeUtils";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
items: {
|
items: {
|
||||||
type: Array,
|
type: Array,
|
||||||
@@ -20,7 +22,15 @@ const props = defineProps({
|
|||||||
<q-avatar icon="person" color="primary" text-color="white"/>
|
<q-avatar icon="person" color="primary" text-color="white"/>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
{{ flightPlan.name }}
|
<q-item-label>
|
||||||
|
{{ flightPlan.name }}
|
||||||
|
</q-item-label>
|
||||||
|
<q-item-label caption v-if="flightPlan.plannedTakeoffDatetime">
|
||||||
|
{{ formatDatetime(flightPlan.plannedTakeoffDatetime) }}
|
||||||
|
</q-item-label>
|
||||||
|
<q-item-label caption v-if="flightPlan.aircraft">
|
||||||
|
{{ flightPlan.aircraft.callSign }}
|
||||||
|
</q-item-label>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
</q-list>
|
</q-list>
|
||||||
|
|||||||
@@ -83,26 +83,22 @@ const airspaces = computed(() => {
|
|||||||
|
|
||||||
return props.airspacesData
|
return props.airspacesData
|
||||||
.filter(airspace => !!colorsMap[airspace.type])
|
.filter(airspace => !!colorsMap[airspace.type])
|
||||||
.filter(airspace => {
|
.filter(airspace => displayAirspaceLayers.value[airspace.type])
|
||||||
if (['TMA'].includes(airspace.type)) return displayAirspaceLayers.value.TMA;
|
|
||||||
if (['TRAGA'].includes(airspace.type)) return displayAirspaceLayers.value.TRAGA;
|
|
||||||
if (airspace.type === 'CTR') return displayAirspaceLayers.value.CTR;
|
|
||||||
if (airspace.type === 'RMZ') return displayAirspaceLayers.value.RMZ;
|
|
||||||
if (airspace.type === 'DANGER') return displayAirspaceLayers.value.DANGER;
|
|
||||||
if (airspace.type === 'PROHIBIT') return displayAirspaceLayers.value.PROHIBIT;
|
|
||||||
if (airspace.type === 'RESTRICT') return displayAirspaceLayers.value.RESTRICT;
|
|
||||||
if (airspace.type === 'PARA') return displayAirspaceLayers.value.PARA;
|
|
||||||
if (airspace.type === 'ATZ') return displayAirspaceLayers.value.ATZ;
|
|
||||||
return true;
|
|
||||||
})
|
|
||||||
.map(airspace => {
|
.map(airspace => {
|
||||||
|
|
||||||
|
let fillOpacity = 0;
|
||||||
|
if (["PROHIBIT", "RESTRICT"].includes(airspace.type))
|
||||||
|
fillOpacity = 0.1;
|
||||||
|
if (highlightedAirspaces.value.includes(airspace.name))
|
||||||
|
fillOpacity = 0.2;
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
name: airspace.name,
|
name: airspace.name,
|
||||||
strokeColor: colorsMap[airspace.type],
|
strokeColor: colorsMap[airspace.type],
|
||||||
strokeOpacity: 0.3,
|
|
||||||
strokeWeight: 3,
|
|
||||||
fillColor: colorsMap[airspace.type],
|
fillColor: colorsMap[airspace.type],
|
||||||
fillOpacity: ["PROHIBIT", "RESTRICT"].includes(airspace.type) ? 0.1 : 0,
|
strokeOpacity: 0.5,
|
||||||
|
strokeWeight: 1,
|
||||||
|
fillOpacity,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (airspace.mapBounds.length > 0) {
|
if (airspace.mapBounds.length > 0) {
|
||||||
@@ -125,6 +121,7 @@ const airportsOnMap = computed(() => {
|
|||||||
const {isPointInPolygon, vectorDistanceToKm} = useVectorUtilities();
|
const {isPointInPolygon, vectorDistanceToKm} = useVectorUtilities();
|
||||||
const {vectorDistance} = useBasicVectorOperations();
|
const {vectorDistance} = useBasicVectorOperations();
|
||||||
|
|
||||||
|
const highlightedAirspaces = ref([]);
|
||||||
|
|
||||||
const getAirspacesAtCoordinates = (clickCoordinates) => {
|
const getAirspacesAtCoordinates = (clickCoordinates) => {
|
||||||
const airspacesUnderClick = []
|
const airspacesUnderClick = []
|
||||||
@@ -144,7 +141,11 @@ const getAirspacesAtCoordinates = (clickCoordinates) => {
|
|||||||
}
|
}
|
||||||
const handleMapClick = (e) => {
|
const handleMapClick = (e) => {
|
||||||
const clickCoordinates = {lat: e.latLng.lat(), lng: e.latLng.lng()}
|
const clickCoordinates = {lat: e.latLng.lat(), lng: e.latLng.lng()}
|
||||||
emits("map-click", {airspaces: getAirspacesAtCoordinates(clickCoordinates), clickCoordinates});
|
|
||||||
|
const airspacesUnderClick = getAirspacesAtCoordinates(clickCoordinates);
|
||||||
|
highlightedAirspaces.value = airspacesUnderClick.map(a => a.name);
|
||||||
|
|
||||||
|
emits("map-click", {airspaces: airspacesUnderClick, clickCoordinates});
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleReportingPointClick = (airport, reportingPoint) => {
|
const handleReportingPointClick = (airport, reportingPoint) => {
|
||||||
@@ -169,7 +170,7 @@ const handleAirportClick = (airport) => {
|
|||||||
ref="mapRef"
|
ref="mapRef"
|
||||||
>
|
>
|
||||||
<template v-for="airspace in airspaces" :key="airspace.name">
|
<template v-for="airspace in airspaces" :key="airspace.name">
|
||||||
<Polygon :options="airspace" @click="handleMapClick" />
|
<Polygon :options="airspace" @click="handleMapClick"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<slot/>
|
<slot/>
|
||||||
|
|||||||
@@ -44,5 +44,9 @@ export const FRAGMENT_FLIGHT_PLAN_LIST_INFO = gql`
|
|||||||
fragment flightPlanListInfo on FlightPlan {
|
fragment flightPlanListInfo on FlightPlan {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
|
plannedTakeoffDatetime
|
||||||
|
aircraft {
|
||||||
|
callSign
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import {useAppStore} from "stores/App";
|
|||||||
import {useFlightPlanObjects, useFlightPlanUtils} from "src/composables/flightPlan";
|
import {useFlightPlanObjects, useFlightPlanUtils} from "src/composables/flightPlan";
|
||||||
import FlightPlanMap from "components/flightPlans/FlightPlanMap.vue";
|
import FlightPlanMap from "components/flightPlans/FlightPlanMap.vue";
|
||||||
import FlightPlanRoute from "components/flightPlans/FlightPlanRoute.vue";
|
import FlightPlanRoute from "components/flightPlans/FlightPlanRoute.vue";
|
||||||
import FlightPlanMarkersList from "components/flightPlans/FlightPlanMarkersList.vue";
|
import FlightPlanSideControls from "components/flightPlans/FlightPlanSideControls.vue";
|
||||||
import DatetimePicker from "components/inputs/DatetimePicker.vue";
|
import DatetimePicker from "components/inputs/DatetimePicker.vue";
|
||||||
import {useAircraftsStore} from "stores/Aircrafts";
|
import {useAircraftsStore} from "stores/Aircrafts";
|
||||||
import ComboboxInput from "components/inputs/ComboboxInput.vue";
|
import ComboboxInput from "components/inputs/ComboboxInput.vue";
|
||||||
@@ -95,6 +95,7 @@ const handleFlightPlanInfoSave = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
const insertAtPosition = ref(flightPlanMarkers.value.length);
|
const insertAtPosition = ref(flightPlanMarkers.value.length);
|
||||||
|
const fullscreen = ref(false);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -112,7 +113,7 @@ const insertAtPosition = ref(flightPlanMarkers.value.length);
|
|||||||
|
|
||||||
<q-tab-panels v-model="openedTab">
|
<q-tab-panels v-model="openedTab">
|
||||||
<q-tab-panel name="route">
|
<q-tab-panel name="route">
|
||||||
<div class="row">
|
<div :class="{row: true, fullscreen}">
|
||||||
<div class="col" style="min-width: 1px">
|
<div class="col" style="min-width: 1px">
|
||||||
<FlightPlanMap
|
<FlightPlanMap
|
||||||
:insert-position="insertAtPosition"
|
:insert-position="insertAtPosition"
|
||||||
@@ -124,12 +125,14 @@ const insertAtPosition = ref(flightPlanMarkers.value.length);
|
|||||||
@markers-changed="handleMarkersChanges"
|
@markers-changed="handleMarkersChanges"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-md-3 col-lg-2">
|
<div class="col-12 col-md-3 col-lg-2 markers-control">
|
||||||
<FlightPlanMarkersList
|
<FlightPlanSideControls
|
||||||
|
:is-fullscreen="fullscreen"
|
||||||
:insert-position="insertAtPosition"
|
:insert-position="insertAtPosition"
|
||||||
:flight-plan="flightPlan"
|
:flight-plan="flightPlan"
|
||||||
@change-insert-position="insertAtPosition = $event"
|
@change-insert-position="insertAtPosition = $event"
|
||||||
@open="flightPlannerDialogOpen=true"
|
@open="flightPlannerDialogOpen=true"
|
||||||
|
@fullscreen-toggle="fullscreen = !fullscreen"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -182,3 +185,19 @@ const insertAtPosition = ref(flightPlanMarkers.value.length);
|
|||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.fullscreen {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 99999;
|
||||||
|
|
||||||
|
.markers-control {
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user