damage report and inspections

This commit is contained in:
Julian Krauser 2025-05-14 09:13:47 +02:00
parent 0ea9601ea3
commit a49babe48d
48 changed files with 701 additions and 117 deletions

View file

@ -0,0 +1,55 @@
<template>
<div class="flex flex-col gap-2 h-full w-full">
<Pagination
:items="damageReports"
:totalCount="totalCount"
:indicateLoading="false"
@load-data="(offset, count, search) => {}"
@search="(search) => {}"
>
<template #pageRow="{ row }: { row: DamageReportViewModel }">
<div class="flex flex-col h-fit w-full border border-primary rounded-md">
<div class="bg-primary p-2 text-white flex flex-row gap-2 items-center">
<PencilSquareIcon v-if="!row.done" class="w-5 h-5" />
<PhotoIcon v-if="row.providedImage" />
<p>{{ row.reported }} - {{ row.status }}</p>
</div>
<div class="p-2">
<p>Beschreibung: {{ row.description }}</p>
</div>
</div>
</template>
</Pagination>
</div>
</template>
<script setup lang="ts">
import { defineComponent } from "vue";
import { mapActions, mapState } from "pinia";
import { useAbilityStore } from "@/stores/ability";
import { useEquipmentDamageReportStore } from "@/stores/admin/unit/equipment/damageReport";
import Pagination from "@/components/Pagination.vue";
import type { DamageReportViewModel } from "@/viewmodels/admin/unit/damageReport/damageReport.models";
import { PhotoIcon, PencilSquareIcon } from "@heroicons/vue/24/outline";
</script>
<script lang="ts">
export default defineComponent({
props: {
equipmentId: String,
},
computed: {
...mapState(useAbilityStore, ["can"]),
...mapState(useEquipmentDamageReportStore, ["damageReports", "loading", "totalCount"]),
},
mounted() {
this.fetchItem();
},
methods: {
...mapActions(useEquipmentDamageReportStore, ["fetchDamageReportForEquipment"]),
fetchItem() {
this.fetchDamageReportForEquipment();
},
},
});
</script>

View file

@ -0,0 +1,58 @@
<template>
<div class="flex flex-col gap-2 h-full w-full">
<Pagination
:items="inspections"
:totalCount="totalCount"
:indicateLoading="false"
@load-data="(offset, count, search) => {}"
@search="(search) => {}"
>
<template #pageRow="{ row }: { row: InspectionViewModel }">
<div class="flex flex-col h-fit w-full border border-primary rounded-md">
<div class="bg-primary p-2 text-white flex flex-row gap-2 items-center">
<PencilSquareIcon v-if="row.isOpen" class="w-5 h-5" />
<p>{{ row.inspectionPlan.title }} - {{ row.finished }}</p>
</div>
<div class="p-2">
<p v-if="row.context">Kontext: {{ row.context }}</p>
<p v-if="row.nextInspection">nächste Inspektion: {{ row.nextInspection }}</p>
</div>
</div>
</template>
</Pagination>
<div class="flex flex-row gap-4">
<button v-if="can('create', 'unit', 'equipment')" primary class="w-fit!" @click="">Prüfung durchführen</button>
</div>
</div>
</template>
<script setup lang="ts">
import { defineComponent } from "vue";
import { mapActions, mapState } from "pinia";
import { useAbilityStore } from "@/stores/ability";
import { useEquipmentInspectionStore } from "@/stores/admin/unit/equipment/inspection";
import { PencilSquareIcon } from "@heroicons/vue/24/outline";
import Pagination from "@/components/Pagination.vue";
import type { InspectionViewModel } from "@/viewmodels/admin/unit/inspectionPlan/inspectionPlan.models";
</script>
<script lang="ts">
export default defineComponent({
props: {
equipmentId: String,
},
computed: {
...mapState(useAbilityStore, ["can"]),
...mapState(useEquipmentInspectionStore, ["inspections", "loading", "totalCount"]),
},
mounted() {
this.fetchItem();
},
methods: {
...mapActions(useEquipmentInspectionStore, ["fetchInspectionForEquipment"]),
fetchItem() {
this.fetchInspectionForEquipment();
},
},
});
</script>

View file

@ -1,42 +1,42 @@
<template>
<div class="flex flex-col gap-2 h-full w-full overflow-y-auto">
<Pagination
:items="[]"
:totalCount="0"
:indicateLoading="false"
@load-data="(offset, count, search) => {}"
@search="(search) => {}"
>
<template #pageRow="{ row }: { row: { id: string } }">
<p>{{ row }}</p>
</template>
</Pagination>
<div class="flex flex-row gap-4">
<button v-if="can('create', 'unit', 'equipment_type')" primary class="w-fit!" @click="">
Prüfplan erstellen
</button>
<div v-if="inspectionPlans != null" class="flex flex-col gap-2 w-full">
<TypeInspectionPlanListItem v-for="plan in inspectionPlans" :inspection-plan="plan" />
</div>
<Spinner v-if="loading == 'loading'" class="mx-auto" />
<p v-else-if="loading == 'failed'" @click="fetchItem" class="cursor-pointer">&#8634; laden fehlgeschlagen</p>
</div>
<div class="flex flex-row gap-4">
<button v-if="can('create', 'unit', 'equipment_type')" primary class="w-fit!" @click="">Prüfplan erstellen</button>
</div>
</template>
<script setup lang="ts">
import { defineComponent } from "vue";
import { mapActions, mapState } from "pinia";
import Pagination from "@/components/Pagination.vue";
import { useAbilityStore } from "@/stores/ability";
import { useEquipmentTypeInspectionPlanStore } from "@/stores/admin/unit/equipmentType/inspectionPlan";
import Spinner from "@/components/Spinner.vue";
import TypeInspectionPlanListItem from "@/components/admin/unit/inspectionPlan/TypeInspectionPlanListItem.vue";
</script>
<script lang="ts">
export default defineComponent({
data() {
return {
currentPage: 0,
maxEntriesPerPage: 25,
};
props: {
equipmentTypeId: String,
},
computed: {
...mapState(useAbilityStore, ["can"]),
...mapState(useEquipmentTypeInspectionPlanStore, ["inspectionPlans", "loading"]),
},
mounted() {
this.fetchItem();
},
methods: {
...mapActions(useEquipmentTypeInspectionPlanStore, ["fetchInspectionPlanForEquipmentType"]),
fetchItem() {
this.fetchInspectionPlanForEquipmentType();
},
},
});
</script>

View file

@ -101,8 +101,8 @@ import { CheckIcon, ChevronUpDownIcon } from "@heroicons/vue/20/solid";
import { useInspectionPlanStore } from "@/stores/admin/unit/inspectionPlan/inspectionPlan";
import type { CreateInspectionPlanViewModel } from "@/viewmodels/admin/unit/inspectionPlan/inspectionPlan.models";
import ScanInput from "@/components/ScanInput.vue";
import type { EquipmentTypeViewModel } from "../../../../viewmodels/admin/unit/equipmentType/equipmentType.models";
import { useEquipmentTypeStore } from "../../../../stores/admin/unit/equipmentType/equipmentType";
import type { EquipmentTypeViewModel } from "@/viewmodels/admin/unit/equipmentType/equipmentType.models";
import { useEquipmentTypeStore } from "@/stores/admin/unit/equipmentType/equipmentType";
import EquipmentTypeSearchSelect from "@/components/search/EquipmentTypeSearchSelect.vue";
import VehicleTypeSearchSelect from "@/components/search/VehicleTypeSearchSelect.vue";
</script>

View file

@ -0,0 +1,55 @@
<template>
<div class="flex flex-col gap-2 h-full w-full">
<Pagination
:items="damageReports"
:totalCount="totalCount"
:indicateLoading="false"
@load-data="(offset, count, search) => {}"
@search="(search) => {}"
>
<template #pageRow="{ row }: { row: DamageReportViewModel }">
<div class="flex flex-col h-fit w-full border border-primary rounded-md">
<div class="bg-primary p-2 text-white flex flex-row gap-2 items-center">
<PencilSquareIcon v-if="!row.done" class="w-5 h-5" />
<PhotoIcon v-if="row.providedImage" />
<p>{{ row.reported }} - {{ row.status }}</p>
</div>
<div class="p-2">
<p>Beschreibung: {{ row.description }}</p>
</div>
</div>
</template>
</Pagination>
</div>
</template>
<script setup lang="ts">
import { defineComponent } from "vue";
import { mapActions, mapState } from "pinia";
import { useAbilityStore } from "@/stores/ability";
import { useVehicleDamageReportStore } from "@/stores/admin/unit/vehicle/damageReport";
import Pagination from "@/components/Pagination.vue";
import type { DamageReportViewModel } from "@/viewmodels/admin/unit/damageReport/damageReport.models";
import { PhotoIcon, PencilSquareIcon } from "@heroicons/vue/24/outline";
</script>
<script lang="ts">
export default defineComponent({
props: {
vehicleId: String,
},
computed: {
...mapState(useAbilityStore, ["can"]),
...mapState(useVehicleDamageReportStore, ["damageReports", "loading", "totalCount"]),
},
mounted() {
this.fetchItem();
},
methods: {
...mapActions(useVehicleDamageReportStore, ["fetchDamageReportForVehicle"]),
fetchItem() {
this.fetchDamageReportForVehicle();
},
},
});
</script>

View file

@ -0,0 +1,58 @@
<template>
<div class="flex flex-col gap-2 h-full w-full">
<Pagination
:items="inspections"
:totalCount="totalCount"
:indicateLoading="false"
@load-data="(offset, count, search) => {}"
@search="(search) => {}"
>
<template #pageRow="{ row }: { row: InspectionViewModel }">
<div class="flex flex-col h-fit w-full border border-primary rounded-md">
<div class="bg-primary p-2 text-white flex flex-row gap-2 items-center">
<PencilSquareIcon v-if="row.isOpen" class="w-5 h-5" />
<p>{{ row.inspectionPlan.title }} - {{ row.finished }}</p>
</div>
<div class="p-2">
<p v-if="row.context">Kontext: {{ row.context }}</p>
<p v-if="row.nextInspection">nächste Inspektion: {{ row.nextInspection }}</p>
</div>
</div>
</template>
</Pagination>
<div class="flex flex-row gap-4">
<button v-if="can('create', 'unit', 'vehicle')" primary class="w-fit!" @click="">Prüfung durchführen</button>
</div>
</div>
</template>
<script setup lang="ts">
import { defineComponent } from "vue";
import { mapActions, mapState } from "pinia";
import { useAbilityStore } from "@/stores/ability";
import { useVehicleInspectionStore } from "@/stores/admin/unit/vehicle/inspection";
import { PencilSquareIcon } from "@heroicons/vue/24/outline";
import Pagination from "@/components/Pagination.vue";
import type { InspectionViewModel } from "@/viewmodels/admin/unit/inspectionPlan/inspectionPlan.models";
</script>
<script lang="ts">
export default defineComponent({
props: {
vehicleId: String,
},
computed: {
...mapState(useAbilityStore, ["can"]),
...mapState(useVehicleInspectionStore, ["inspections", "loading", "totalCount"]),
},
mounted() {
this.fetchItem();
},
methods: {
...mapActions(useVehicleInspectionStore, ["fetchInspectionForVehicle"]),
fetchItem() {
this.fetchInspectionForVehicle();
},
},
});
</script>

View file

@ -0,0 +1,51 @@
<template>
<div class="flex flex-col gap-2 h-full w-full overflow-y-auto">
<div v-if="activeVehicleObj != null" class="flex flex-col gap-2 w-full">
<div>
<label for="type">Typ</label>
<input type="text" id="type" :value="activeVehicleObj.vehicleType.type" readonly />
</div>
<div>
<label for="name">Bezeichnung</label>
<input type="text" id="name" :value="activeVehicleObj.name" readonly />
</div>
<div>
<label for="code">Code</label>
<input type="text" id="code" :value="activeVehicleObj.code" readonly />
</div>
<div>
<label for="location">Verortung</label>
<input type="text" id="location" :value="activeVehicleObj.location" readonly />
</div>
</div>
<Spinner v-if="loadingActive == 'loading'" class="mx-auto" />
<p v-else-if="loadingActive == 'failed'" @click="fetchVehicleByActiveId" class="cursor-pointer">
&#8634; laden fehlgeschlagen
</p>
</div>
</template>
<script setup lang="ts">
import { defineComponent } from "vue";
import { mapActions, mapState } from "pinia";
import Spinner from "@/components/Spinner.vue";
import { useVehicleStore } from "@/stores/admin/unit/vehicle/vehicle";
</script>
<script lang="ts">
export default defineComponent({
props: {
vehicleId: String,
},
computed: {
...mapState(useVehicleStore, ["activeVehicleObj", "loadingActive"]),
},
mounted() {
this.fetchVehicleByActiveId();
},
methods: {
...mapActions(useVehicleStore, ["fetchVehicleByActiveId"]),
},
});
</script>

View file

@ -1,42 +1,43 @@
<template>
<div class="flex flex-col gap-2 h-full w-full overflow-y-auto">
<Pagination
:items="[]"
:totalCount="0"
:indicateLoading="false"
@load-data="(offset, count, search) => {}"
@search="(search) => {}"
>
<template #pageRow="{ row }: { row: { id: string } }">
<p>{{ row }}</p>
</template>
</Pagination>
<div class="flex flex-row gap-4">
<button v-if="can('create', 'unit', 'equipment_type')" primary class="w-fit!" @click="">
Prüfplan erstellen
</button>
<div v-if="inspectionPlans != null" class="flex flex-col gap-2 w-full">
<TypeInspectionPlanListItem v-for="plan in inspectionPlans" :inspection-plan="plan" />
</div>
<Spinner v-if="loading == 'loading'" class="mx-auto" />
<p v-else-if="loading == 'failed'" @click="fetchItem" class="cursor-pointer">&#8634; laden fehlgeschlagen</p>
</div>
<div class="flex flex-row gap-4">
<button v-if="can('create', 'unit', 'vehicle_type')" primary class="w-fit!" @click="">Prüfplan erstellen</button>
</div>
</template>
<script setup lang="ts">
import { defineComponent } from "vue";
import { mapActions, mapState } from "pinia";
import Pagination from "@/components/Pagination.vue";
import { useAbilityStore } from "@/stores/ability";
import { useVehicleTypeInspectionPlanStore } from "@/stores/admin/unit/vehicleType/inspectionPlan";
import TypeInspectionPlanListItem from "@/components/admin/unit/inspectionPlan/TypeInspectionPlanListItem.vue";
import Spinner from "@/components/Spinner.vue";
</script>
<script lang="ts">
export default defineComponent({
data() {
return {
currentPage: 0,
maxEntriesPerPage: 25,
};
props: {
vehicleTypeId: String,
},
computed: {
...mapState(useAbilityStore, ["can"]),
...mapState(useVehicleTypeInspectionPlanStore, ["inspectionPlans", "loading"]),
},
mounted() {
this.fetchItem();
},
methods: {
...mapActions(useVehicleTypeInspectionPlanStore, ["fetchInspectionPlanForVehicleType"]),
fetchItem() {
this.fetchInspectionPlanForVehicleType();
},
},
});
</script>