Sprava eventu a organizaci

This commit is contained in:
Michal Kváček
2023-09-20 13:26:13 +02:00
parent 6fbaef4a1e
commit 8c3c5ee48d
42 changed files with 624 additions and 56 deletions
@@ -2,6 +2,8 @@
import {aircraft} from "src/composables/objects/aircraft";
import {confirmObject} from "src/composables/dialog";
import {useQuasar} from "quasar";
import {storeToRefs} from "pinia";
import {useUserStore} from "stores/User";
const props = defineProps({
aircraft: {
@@ -11,9 +13,11 @@ const props = defineProps({
});
const emits = defineEmits(["delete"]);
const $q = useQuasar();
const loggedUser = storeToRefs(useUserStore()).user;
const confirmDelete = (aircraftId) => {
$q.dialog(confirmObject('Opravdu chceš smazat toto letadlo?'))
.onOk(() => {
@@ -26,7 +30,7 @@ const confirmDelete = (aircraftId) => {
<q-card class="q-mx-md q-my-md flight-detail-card">
<q-img :src="aircraft.photoUrl" v-if="aircraft.photoUrl"/>
<q-card-actions class="q-my-md">
<q-card-actions class="q-my-md" v-if="aircraft.createdById === loggedUser.id">
<div class="col-grow">
<q-btn
flat
@@ -41,6 +45,11 @@ const confirmDelete = (aircraftId) => {
<q-card-section>
<q-list>
<q-item v-if="aircraft.organization">
Provozovatel: {{ aircraft.organization.name }}
</q-item>
<q-item v-if="aircraft.manufacturer">
Výrobce: {{ aircraft.manufacturer }}
</q-item>
+30 -11
View File
@@ -5,6 +5,7 @@ import {setDefaultData} from "src/composables/form/formHandling";
import {defaultValues, isRequestPending} from "src/composables/form/props";
import {isNumber, isRequired, maxLength, minLength} from "src/composables/form/rules";
import {commonProps} from "src/composables/inputs";
import ComboboxInput from "components/inputs/ComboboxInput.vue";
const formData = reactive({
id: null,
@@ -14,12 +15,16 @@ const formData = reactive({
manufacturer: "",
description: "",
photo: null,
organizationId: null
organization: null
});
const props = defineProps({
defaultValues,
isRequestPending
isRequestPending,
organizations: {
type: Array,
required: true,
}
});
const rules = {
@@ -28,8 +33,12 @@ const rules = {
};
onMounted(() => {
if (Object.keys(props.defaultValues).length > 0)
if (Object.keys(props.defaultValues).length > 0) {
setDefaultData(formData, props.defaultValues);
if (props.defaultValues.organization) {
formData.organization = {id: props.defaultValues.organization.id, name: props.defaultValues.organization.name};
}
}
})
</script>
@@ -45,6 +54,23 @@ onMounted(() => {
v-bind="commonProps"
/>
<q-input
type="number"
v-model.number="formData.seats"
label="Počet míst (včetně pilota)"
min="1"
:rules="rules.seats"
v-bind="commonProps"
/>
<ComboboxInput
:options="organizations"
label="Organizace"
v-model="formData.organization"
v-bind="commonProps"
hint="Vyber provozovatele letadla. Tím se stane dostupné i pro ostatní členy vybrané organizace."
/>
<q-input
type="text"
v-model="formData.manufacturer"
@@ -58,14 +84,7 @@ onMounted(() => {
v-bind="commonProps"
/>
<q-input
type="number"
v-model.number="formData.seats"
label="Počet míst (včetně pilota)"
min="1"
:rules="rules.seats"
v-bind="commonProps"
/>
<q-input
type="textarea"
@@ -36,7 +36,11 @@ useAppStore().setPageTitle("Letadla");
({{ aircraft.manufacturer }})
</template>
</q-item-label>
<q-item-label caption v-if="aircraft.organization">
Provozovatel: {{ aircraft.organization.name }}
</q-item-label>
</q-item-section>
</q-item>
</q-list>
</template>
@@ -8,7 +8,7 @@ const props = defineProps({
</script>
<template>
<div style="height: 80px">
<div style="height: 60px">
<q-avatar
v-for="(avatar, idx) in avatars"
:key="idx"
@@ -16,7 +16,6 @@ const props = defineProps({
:style="`left: ${(idx+1) * 20}px`"
>
<img :src="avatar"/>
<!-- <q-icon name="flight" v-else />-->
</q-avatar>
</div>
</template>
+6 -4
View File
@@ -11,14 +11,16 @@ const props = defineProps({
<template>
<q-list bordered separator>
<q-item clickable v-ripple v-for="pilot of items" :key="pilot">
<q-item
clickable
:to="{name: 'copilotDetail', params: {id: pilot.id }}"
v-ripple
v-for="pilot of items" :key="pilot">
<q-item-section avatar>
<q-avatar icon="person" color="primary" text-color="white"/>
</q-item-section>
<q-item-section>
<router-link :to="{name: 'copilotDetail', params: {id: pilot.id }}">
{{ pilot.name }}
</router-link>
{{ pilot.name }}
</q-item-section>
</q-item>
</q-list>
+7 -4
View File
@@ -1,6 +1,5 @@
<script setup>
import AvatarsGroup from "components/AvatarsGroup.vue";
import AvatarsGroup from "components/avatars/AvatarsGroup.vue";
const props = defineProps({
items: {
@@ -14,10 +13,14 @@ const getCoverPhotos = (item) => item.flights.filter(f => !!f.coverPhoto).map(f
<template>
<q-list bordered separator>
<q-item clickable v-ripple v-for="event of items" :key="event" :to="{name: 'eventDetail', params: {id: event.id }}">
<q-item
clickable
:to="{name: 'eventDetail', params: {id: event.id }}"
v-ripple
v-for="event of items" :key="event"
>
<q-item-section>
<q-item-label>
<q-avatar icon="event" color="primary" text-color="white" v-if="event.flights.length === 0"/>
<AvatarsGroup :avatars="getCoverPhotos(event)" v-else/>
+7 -2
View File
@@ -1,7 +1,7 @@
<script setup>
import {minutesToHumanReadable} from "src/composables/datetimeUtils";
import {flightName} from "src/composables/objects/flight";
import AvatarFromPhoto from "components/AvatarFromPhoto.vue";
import AvatarFromPhoto from "components/avatars/AvatarFromPhoto.vue";
const props = defineProps({
items: {
@@ -28,7 +28,7 @@ const props = defineProps({
v-for="flight of items" :key="flight"
ripple
clickable
:to="{name: routeDetail.name, params:{...routeDetail.params, id: flight.id}}"
:to="{name: routeDetail.name, params: {...routeDetail.params, id: flight.id}}"
>
<q-item-section avatar>
<AvatarFromPhoto :size="120" v-if="flight.coverPhoto" :src="flight.coverPhoto.thumbnailUrl"/>
@@ -49,6 +49,11 @@ const props = defineProps({
<q-icon name="flight"/>
{{ flight.aircraft.callSign }}
</div>
<div class="text-secondary" v-if="flight.event">
<q-icon name="event" />
{{ flight.event.name }}
</div>
</q-item-section>
<q-item-section side top v-if="flight.isPublic && displayVisibilityInfo">
@@ -0,0 +1,9 @@
<script setup>
import BasicListSkeleton from "components/basicSkeletons/BasicListSkeleton.vue";
</script>
<template>
<q-card class="flight-detail-card">
<BasicListSkeleton :items-count-min="1" :items-count-max="5"/>
</q-card>
</template>
@@ -0,0 +1,5 @@
<script setup></script>
<template>
<em>Copilot skeleton</em>
</template>
@@ -0,0 +1,43 @@
<script setup>
import {onMounted, reactive} from "vue";
import {setDefaultData} from "src/composables/form/formHandling";
import FormWrapper from "components/FormWrapper.vue";
import {commonProps} from "src/composables/inputs";
import {isRequestPending} from "src/composables/form/props";
import {isRequired} from "src/composables/form/rules";
import RichTextEditor from "components/inputs/RichTextEditor.vue";
const props = defineProps({
event: {
type: Object
},
isRequestPending
})
const formData = reactive({
name: null,
});
const rules = {
name: [isRequired]
}
onMounted(() => {
if (props.event) {
setDefaultData(formData, props.event);
}
})
</script>
<template>
<FormWrapper v-model="formData" :is-request-pending="props.isRequestPending">
<q-input
v-bind="commonProps"
label="Jméno"
:rules="rules.name"
v-model="formData.name"
/>
</FormWrapper>
</template>
@@ -0,0 +1,36 @@
<script setup>
const props = defineProps({
items: {
type: Array,
required: true
},
myOrganizationsIds: {
type: Array,
required: false
}
})
</script>
<template>
<q-list bordered separator>
<q-item
clickable
:to="{name: 'organizationDetail', params: {id: organization.id }}"
v-ripple
v-for="organization of items"
:key="organization"
>
<q-item-section avatar>
<q-avatar icon="groups" color="primary" text-color="white"/>
</q-item-section>
<q-item-section>
<q-item-label>
{{ organization.name }}
<q-icon name="star" color="gold" v-if="myOrganizationsIds.includes(organization.id)"/>
</q-item-label>
</q-item-section>
</q-item>
</q-list>
</template>
+1 -1
View File
@@ -1,7 +1,7 @@
<script setup>
import {user as pilot} from "src/composables/objects/user";
import {FORMAT_DATE, formatDatetime} from "src/composables/datetimeUtils";
import AvatarFromPhoto from "components/AvatarFromPhoto.vue";
import AvatarFromPhoto from "components/avatars/AvatarFromPhoto.vue";
</script>
<template>
+1 -1
View File
@@ -3,7 +3,7 @@ import FormWrapper from "components/FormWrapper.vue";
import {commonProps} from "src/composables/inputs";
import {reactive, watch} from "vue";
import {setDefaultData} from "src/composables/form/formHandling";
import AvatarFromPhoto from "components/AvatarFromPhoto.vue";
import AvatarFromPhoto from "components/avatars/AvatarFromPhoto.vue";
import {isRequestPending} from "src/composables/form/props";
const props = defineProps({