respiratory create forms

This commit is contained in:
Julian Krauser 2025-05-21 09:38:16 +02:00
parent def32b786c
commit d70edd0086
7 changed files with 303 additions and 40 deletions

View file

@ -523,6 +523,13 @@ const router = createRouter({
component: () => import("@/views/admin/unit/respiratoryGear/RespiratoryGear.vue"),
beforeEnter: [resetRespiratoryGearStores],
},
{
path: "create",
name: "admin-unit-respiratory_gear-create",
component: () => import("@/views/admin/unit/respiratoryGear/CreateRespiratoryGear.vue"),
meta: { type: "create", section: "unit", module: "respiratory_gear" },
beforeEnter: [abilityAndNavUpdate],
},
{
path: ":respiratoryGearId",
name: "admin-unit-respiratory_gear-routing",
@ -554,14 +561,6 @@ const router = createRouter({
component: () => import("@/views/admin/ViewSelect.vue"),
props: true,
},
{
path: "edit",
name: "admin-unit-respiratory_gear-edit",
component: () => import("@/views/admin/ViewSelect.vue"),
meta: { type: "update", section: "unit", module: "respiratory_gear" },
beforeEnter: [abilityAndNavUpdate],
props: true,
},
],
},
],
@ -579,6 +578,13 @@ const router = createRouter({
component: () => import("@/views/admin/unit/respiratoryWearer/RespiratoryWearer.vue"),
beforeEnter: [resetRespiratoryWearerStores],
},
{
path: "create",
name: "admin-unit-respiratory_wearer-create",
component: () => import("@/views/admin/unit/respiratoryWearer/CreateRespiratoryWearer.vue"),
meta: { type: "create", section: "unit", module: "respiratory_wearer" },
beforeEnter: [abilityAndNavUpdate],
},
{
path: ":respiratoryWearerId",
name: "admin-unit-respiratory_wearer-routing",
@ -622,14 +628,6 @@ const router = createRouter({
component: () => import("@/views/admin/ViewSelect.vue"),
props: true,
},
{
path: "edit",
name: "admin-unit-respiratory_wearer-edit",
component: () => import("@/views/admin/ViewSelect.vue"),
meta: { type: "update", section: "unit", module: "respiratory_wearer" },
beforeEnter: [abilityAndNavUpdate],
props: true,
},
],
},
],
@ -647,6 +645,13 @@ const router = createRouter({
component: () => import("@/views/admin/unit/respiratoryMission/RespiratoryMission.vue"),
beforeEnter: [resetRespiratoryMissionStores],
},
{
path: "create",
name: "admin-unit-respiratory_mission-create",
component: () => import("@/views/admin/unit/respiratoryMission/CreateRespiratoryMission.vue"),
meta: { type: "create", section: "unit", module: "respiratory_mission" },
beforeEnter: [abilityAndNavUpdate],
},
{
path: ":respiratoryMissionId",
name: "admin-unit-respiratory_mission-routing",
@ -672,14 +677,6 @@ const router = createRouter({
component: () => import("@/views/admin/ViewSelect.vue"),
props: true,
},
{
path: "edit",
name: "admin-unit-respiratory_mission-edit",
component: () => import("@/views/admin/ViewSelect.vue"),
meta: { type: "update", section: "unit", module: "respiratory_mission" },
beforeEnter: [abilityAndNavUpdate],
props: true,
},
],
},
],

View file

@ -0,0 +1,82 @@
<template>
<MainTemplate title="Ausrüstung erfassen">
<template #diffMain>
<div class="flex flex-col gap-2 h-full w-full overflow-y-auto">
<form class="flex flex-col gap-4 py-2 w-full max-w-xl mx-auto" @submit.prevent="triggerCreate">
<EquipmentSearchSelect title="Gerät" useScanner v-model="selectedRespiratoryGear" />
<div class="flex flex-row justify-end gap-2">
<RouterLink
:to="{ name: 'admin-unit-respiratory_gear' }"
primary-outline
button
class="w-fit!"
:disabled="status == 'loading' || status?.status == 'success'"
>
abbrechen
</RouterLink>
<button primary type="submit" class="w-fit!" :disabled="status == 'loading'">speichern</button>
<Spinner v-if="status == 'loading'" class="my-auto" />
<SuccessCheckmark v-else-if="status?.status == 'success'" />
<FailureXMark v-else-if="status?.status == 'failed'" />
</div>
</form>
</div>
</template>
</MainTemplate>
</template>
<script setup lang="ts">
import { defineComponent } from "vue";
import { mapActions, mapState } from "pinia";
import MainTemplate from "@/templates/Main.vue";
import { useRespiratoryGearStore } from "@/stores/admin/unit/respiratoryGear/respiratoryGear";
import type { CreateRespiratoryGearViewModel } from "@/viewmodels/admin/unit/respiratoryGear/respiratoryGear.models";
import Spinner from "@/components/Spinner.vue";
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
import FailureXMark from "@/components/FailureXMark.vue";
import EquipmentSearchSelect from "@/components/search/EquipmentSearchSelect.vue";
</script>
<script lang="ts">
export default defineComponent({
data() {
return {
status: null as null | "loading" | { status: "success" | "failed"; reason?: string },
timeout: null as any,
selectedRespiratoryGear: "" as string,
};
},
beforeUnmount() {
try {
clearTimeout(this.timeout);
} catch (error) {}
},
methods: {
...mapActions(useRespiratoryGearStore, ["createRespiratoryGear"]),
triggerCreate(e: any) {
if (this.selectedRespiratoryGear == null) return;
let formData = e.target.elements;
let createRespiratoryGear: CreateRespiratoryGearViewModel = {
equipmentId: this.selectedRespiratoryGear,
};
this.status = "loading";
this.createRespiratoryGear(createRespiratoryGear)
.then((res) => {
this.status = { status: "success" };
this.timeout = setTimeout(() => {
this.$router.push({
name: "admin-unit-respiratory_gear-overview",
params: {
respiratoryGearId: res.data,
},
});
}, 1500);
})
.catch((err) => {
this.status = { status: "failed" };
});
},
},
});
</script>

View file

@ -16,9 +16,15 @@
</Pagination>
<div class="flex flex-row gap-4">
<button v-if="can('create', 'unit', 'respiratory_gear')" primary class="w-fit!" @click="openCreateModal">
<RouterLink
v-if="can('create', 'unit', 'respiratory_gear')"
:to="{ name: 'admin-unit-respiratory_gear-create' }"
primary
button
class="w-fit!"
>
Gerät erfassen
</button>
</RouterLink>
</div>
</div>
</template>

View file

@ -0,0 +1,94 @@
<template>
<MainTemplate title="Ausrüstung erfassen">
<template #diffMain>
<div class="flex flex-col gap-2 h-full w-full overflow-y-auto">
<form class="flex flex-col gap-4 py-2 w-full max-w-xl mx-auto" @submit.prevent="triggerCreate">
<div>
<label for="title">Titel</label>
<input type="text" id="title" required />
</div>
<div>
<label for="description">Bezeichnung</label>
<textarea type="text" id="description" required />
</div>
<div>
<label for="date">Datum & Uhrzeit</label>
<input type="datetime-local" id="date" required />
</div>
<div class="flex flex-row justify-end gap-2">
<RouterLink
:to="{ name: 'admin-unit-respiratory_mission' }"
primary-outline
button
class="w-fit!"
:disabled="status == 'loading' || status?.status == 'success'"
>
abbrechen
</RouterLink>
<button primary type="submit" class="w-fit!" :disabled="status == 'loading'">speichern</button>
<Spinner v-if="status == 'loading'" class="my-auto" />
<SuccessCheckmark v-else-if="status?.status == 'success'" />
<FailureXMark v-else-if="status?.status == 'failed'" />
</div>
</form>
</div>
</template>
</MainTemplate>
</template>
<script setup lang="ts">
import { defineComponent } from "vue";
import { mapActions, mapState } from "pinia";
import MainTemplate from "@/templates/Main.vue";
import { useRespiratoryMissionStore } from "@/stores/admin/unit/respiratoryMission/respiratoryMission";
import type { CreateRespiratoryMissionViewModel } from "@/viewmodels/admin/unit/respiratoryMission/respiratoryMission.models";
import Spinner from "@/components/Spinner.vue";
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
import FailureXMark from "@/components/FailureXMark.vue";
</script>
<script lang="ts">
export default defineComponent({
data() {
return {
status: null as null | "loading" | { status: "success" | "failed"; reason?: string },
timeout: null as any,
selectedRespiratoryMission: "" as string,
};
},
beforeUnmount() {
try {
clearTimeout(this.timeout);
} catch (error) {}
},
methods: {
...mapActions(useRespiratoryMissionStore, ["createRespiratoryMission"]),
triggerCreate(e: any) {
if (this.selectedRespiratoryMission == null) return;
let formData = e.target.elements;
let createRespiratoryMission: CreateRespiratoryMissionViewModel = {
date: formData.date.value,
title: formData.title.value,
description: formData.description.value,
};
this.status = "loading";
this.createRespiratoryMission(createRespiratoryMission)
.then((res) => {
this.status = { status: "success" };
this.timeout = setTimeout(() => {
this.$router.push({
name: "admin-unit-respiratory_mission-overview",
params: {
respiratoryMissionId: res.data,
},
});
}, 1500);
})
.catch((err) => {
this.status = { status: "failed" };
});
},
},
});
</script>

View file

@ -16,9 +16,15 @@
</Pagination>
<div class="flex flex-row gap-4">
<button v-if="can('create', 'unit', 'respiratory_mission')" primary class="w-fit!" @click="openCreateModal">
<RouterLink
v-if="can('create', 'unit', 'respiratory_mission')"
:to="{ name: 'admin-unit-respiratory_mission-create' }"
primary
button
class="w-fit!"
>
Einsatz erfassen
</button>
</RouterLink>
</div>
</div>
</template>
@ -54,16 +60,6 @@ export default defineComponent({
},
methods: {
...mapActions(useRespiratoryMissionStore, ["fetchRespiratoryMissions"]),
...mapActions(useModalStore, ["openModal"]),
openCreateModal() {
this.openModal(
markRaw(
defineAsyncComponent(
() => import("@/components/admin/unit/respiratoryMission/CreateRespiratoryMissionModal.vue")
)
)
);
},
},
});
</script>

View file

@ -0,0 +1,82 @@
<template>
<MainTemplate title="Ausrüstung erfassen">
<template #diffMain>
<div class="flex flex-col gap-2 h-full w-full overflow-y-auto">
<form class="flex flex-col gap-4 py-2 w-full max-w-xl mx-auto" @submit.prevent="triggerCreate">
<MemberSearchSelectSingle title="Träger" useScanner v-model="selectedRespiratoryWearer" />
<div class="flex flex-row justify-end gap-2">
<RouterLink
:to="{ name: 'admin-unit-respiratory_wearer' }"
primary-outline
button
class="w-fit!"
:disabled="status == 'loading' || status?.status == 'success'"
>
abbrechen
</RouterLink>
<button primary type="submit" class="w-fit!" :disabled="status == 'loading'">speichern</button>
<Spinner v-if="status == 'loading'" class="my-auto" />
<SuccessCheckmark v-else-if="status?.status == 'success'" />
<FailureXMark v-else-if="status?.status == 'failed'" />
</div>
</form>
</div>
</template>
</MainTemplate>
</template>
<script setup lang="ts">
import { defineComponent } from "vue";
import { mapActions, mapState } from "pinia";
import MainTemplate from "@/templates/Main.vue";
import { useRespiratoryWearerStore } from "@/stores/admin/unit/respiratoryWearer/respiratoryWearer";
import type { CreateRespiratoryWearerViewModel } from "@/viewmodels/admin/unit/respiratoryWearer/respiratoryWearer.models";
import Spinner from "@/components/Spinner.vue";
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
import FailureXMark from "@/components/FailureXMark.vue";
import MemberSearchSelectSingle from "@/components/search/MemberSearchSelectSingle.vue";
</script>
<script lang="ts">
export default defineComponent({
data() {
return {
status: null as null | "loading" | { status: "success" | "failed"; reason?: string },
timeout: null as any,
selectedRespiratoryWearer: "" as string,
};
},
beforeUnmount() {
try {
clearTimeout(this.timeout);
} catch (error) {}
},
methods: {
...mapActions(useRespiratoryWearerStore, ["createRespiratoryWearer"]),
triggerCreate(e: any) {
if (this.selectedRespiratoryWearer == null) return;
let formData = e.target.elements;
let createRespiratoryWearer: CreateRespiratoryWearerViewModel = {
memberId: this.selectedRespiratoryWearer,
};
this.status = "loading";
this.createRespiratoryWearer(createRespiratoryWearer)
.then((res) => {
this.status = { status: "success" };
this.timeout = setTimeout(() => {
this.$router.push({
name: "admin-unit-respiratory_wearer-overview",
params: {
respiratoryWearerId: res.data,
},
});
}, 1500);
})
.catch((err) => {
this.status = { status: "failed" };
});
},
},
});
</script>

View file

@ -16,9 +16,15 @@
</Pagination>
<div class="flex flex-row gap-4">
<button v-if="can('create', 'unit', 'respiratory_wearer')" primary class="w-fit!" @click="openCreateModal">
<RouterLink
v-if="can('create', 'unit', 'respiratory_wearer')"
:to="{ name: 'admin-unit-respiratory_wearer-create' }"
primary
button
class="w-fit!"
>
Träger erfassen
</button>
</RouterLink>
</div>
</div>
</template>