2025-02-20 12:01:12 +01:00
|
|
|
<template>
|
|
|
|
<MainTemplate :show-back="false">
|
|
|
|
<template #topBar>
|
|
|
|
<div class="flex flex-row items-center justify-between pt-5 pb-3 px-7">
|
|
|
|
<h1 class="font-bold text-xl h-8">Einsätze</h1>
|
|
|
|
<ArrowPathIcon
|
|
|
|
v-if="can('delete', 'operation', 'mission')"
|
|
|
|
class="w-5 h-5 cursor-pointer"
|
|
|
|
:class="loading == 'loading' ? 'animate-spin' : 'animate-[spin_1s_linear_1]'"
|
2025-03-07 10:37:10 +01:00
|
|
|
@click="fetchMissions(0, 25, true)"
|
2025-02-20 12:01:12 +01:00
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
<template #diffMain>
|
|
|
|
<div class="flex flex-col w-full h-full gap-2 justify-center px-7">
|
|
|
|
<div class="flex flex-col gap-2 grow overflow-y-scroll" @scrollend="reachedEnd">
|
|
|
|
<MissionListItem v-for="mission in missions" :key="mission.id" :mission="mission" />
|
2025-04-08 09:37:38 +02:00
|
|
|
<br />
|
2025-02-20 12:01:12 +01:00
|
|
|
<Spinner v-if="loading == 'loading'" class="mt-auto mx-auto" />
|
2025-04-08 09:37:38 +02:00
|
|
|
<p v-if="!hasReachedEnd" class="mt-auto mx-auto text-sm cursor-pointer select-none" @click="reachedEnd">
|
|
|
|
mehr laden?
|
|
|
|
</p>
|
|
|
|
<p v-else class="mt-auto mx-auto text-sm select-none">Ende der Liste!</p>
|
2025-02-20 12:01:12 +01:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="flex flex-row gap-4">
|
|
|
|
<button v-if="can('create', 'operation', 'mission')" primary class="!w-fit" @click="createNewMission">
|
|
|
|
Einsatz anlegen
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
</MainTemplate>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
import { defineComponent } from "vue";
|
|
|
|
import { mapActions, mapState } from "pinia";
|
|
|
|
import MainTemplate from "@/templates/Main.vue";
|
|
|
|
import { useAbilityStore } from "@/stores/ability";
|
|
|
|
import MissionListItem from "@/components/admin/operation/mission/MissionListItem.vue";
|
|
|
|
import { useMissionStore } from "@/stores/admin/operation/mission";
|
2025-02-21 11:55:49 +01:00
|
|
|
import { ArrowPathIcon, CloudIcon } from "@heroicons/vue/24/outline";
|
2025-02-20 12:01:12 +01:00
|
|
|
import Spinner from "@/components/Spinner.vue";
|
2025-02-21 11:55:49 +01:00
|
|
|
import { useConnectionStore } from "@/stores/admin/operation/connection";
|
2025-02-20 12:01:12 +01:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<script lang="ts">
|
|
|
|
export default defineComponent({
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
hasReachedEnd: false as boolean,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
watch: {
|
|
|
|
missions(before, after) {
|
|
|
|
if (before.length != after.length) {
|
|
|
|
this.hasReachedEnd = false;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
...mapState(useMissionStore, ["missions", "loading"]),
|
|
|
|
...mapState(useAbilityStore, ["can"]),
|
|
|
|
},
|
|
|
|
mounted() {
|
2025-03-09 09:55:12 +01:00
|
|
|
this.fetchMissions(0, 25, true);
|
2025-02-20 12:01:12 +01:00
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
...mapActions(useMissionStore, ["fetchMissions", "createMission"]),
|
|
|
|
reachedEnd() {
|
2025-04-08 09:37:38 +02:00
|
|
|
if (!this.hasReachedEnd) {
|
|
|
|
this.hasReachedEnd = true;
|
|
|
|
this.fetchMissions(this.missions.length);
|
|
|
|
}
|
2025-02-20 12:01:12 +01:00
|
|
|
},
|
|
|
|
createNewMission() {
|
|
|
|
this.createMission()
|
|
|
|
.then((res) => {
|
|
|
|
this.$router.push({
|
|
|
|
name: "admin-operation-mission-form",
|
|
|
|
params: {
|
|
|
|
id: res.data,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
})
|
|
|
|
.catch(() => {});
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
</script>
|