inspection finish and print
This commit is contained in:
parent
d96c73d5b1
commit
5d26885da3
14 changed files with 367 additions and 29 deletions
|
@ -0,0 +1,25 @@
|
||||||
|
<template>
|
||||||
|
<div @click="showInfo" class="cursor-pointer">
|
||||||
|
<InformationCircleIcon class="w-5 h-5" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { defineAsyncComponent, defineComponent, markRaw } from "vue";
|
||||||
|
import { mapState, mapActions } from "pinia";
|
||||||
|
import { useModalStore } from "@/stores/modal";
|
||||||
|
import { InformationCircleIcon } from "@heroicons/vue/24/outline";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default defineComponent({
|
||||||
|
methods: {
|
||||||
|
...mapActions(useModalStore, ["openModal"]),
|
||||||
|
showInfo() {
|
||||||
|
this.openModal(
|
||||||
|
markRaw(defineAsyncComponent(() => import("@/components/admin/unit/InspectionTimeFormatExplainModal.vue")))
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,55 @@
|
||||||
|
<template>
|
||||||
|
<div class="relative w-full md:max-w-md">
|
||||||
|
<div class="flex flex-row gap-2 items-center justify-center">
|
||||||
|
<InformationCircleIcon class="text-gray-500 h-5 w-5" />
|
||||||
|
<p class="text-xl font-medium">Zeit Format für Erinnerung und Intervall</p>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<table class="min-w-full text-sm border border-gray-200 rounded">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="px-3 py-2 font-mono text-gray-700 border-b border-gray-100"><zahl>-(d|m|y)</td>
|
||||||
|
<td class="px-3 py-2 text-gray-600 border-b border-gray-100">
|
||||||
|
Ein Intervall, z.B. <span class="font-mono">7-d</span> für alle 7 Tage,
|
||||||
|
<span class="font-mono">1-m</span> für jeden Monat.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="px-3 py-2 font-mono text-gray-700 border-b border-gray-100">DD/MM</td>
|
||||||
|
<td class="px-3 py-2 text-gray-600 border-b border-gray-100">
|
||||||
|
Ein bestimmtes Datum, z.B. <span class="font-mono">15/06</span> für den 15. Juni.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="px-3 py-2 font-mono text-gray-700">DD/*</td>
|
||||||
|
<td class="px-3 py-2 text-gray-600">
|
||||||
|
Ein Tag jeden Monats, z.B. <span class="font-mono">01/*</span> für den ersten Tag jedes Monats.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<p>Im Fall von Erinnerungen wird das Format als zeitliche Angabe vor einem Datum verwendet.</p>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<div class="flex flex-row justify-end">
|
||||||
|
<div class="flex flex-row gap-4 py-2">
|
||||||
|
<button primary-outline @click="closeModal">schließen</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { defineComponent } from "vue";
|
||||||
|
import { mapState, mapActions } from "pinia";
|
||||||
|
import { useModalStore } from "@/stores/modal";
|
||||||
|
import { InformationCircleIcon } from "@heroicons/vue/24/outline";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default defineComponent({
|
||||||
|
methods: {
|
||||||
|
...mapActions(useModalStore, ["closeModal"]),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,85 @@
|
||||||
|
<template>
|
||||||
|
<div class="w-full md:max-w-md">
|
||||||
|
<div class="flex flex-col items-center">
|
||||||
|
<p class="text-xl font-medium">angefangene Prüfung löschen</p>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<p class="text-center">
|
||||||
|
{{ activeInspectionObj?.inspectionPlan.title }} zu {{ activeInspectionObj?.related.name }}
|
||||||
|
<small v-if="activeInspectionObj?.related.code">({{ activeInspectionObj?.related.code }})</small> begonnen am
|
||||||
|
{{ new Date(activeInspectionObj?.created ?? "").toLocaleDateString("de-de") }} löschen?
|
||||||
|
</p>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<div class="flex flex-row gap-2">
|
||||||
|
<button
|
||||||
|
primary
|
||||||
|
type="submit"
|
||||||
|
:disabled="status == 'loading' || status?.status == 'success'"
|
||||||
|
@click="triggerDelete"
|
||||||
|
>
|
||||||
|
löschen
|
||||||
|
</button>
|
||||||
|
<Spinner v-if="status == 'loading'" class="my-auto" />
|
||||||
|
<SuccessCheckmark v-else-if="status?.status == 'success'" />
|
||||||
|
<FailureXMark v-else-if="status?.status == 'failed'" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-row justify-end">
|
||||||
|
<div class="flex flex-row gap-4 py-2">
|
||||||
|
<button primary-outline @click="closeModal" :disabled="status == 'loading' || status?.status == 'success'">
|
||||||
|
abbrechen
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { defineComponent } from "vue";
|
||||||
|
import { mapState, mapActions } from "pinia";
|
||||||
|
import { useModalStore } from "@/stores/modal";
|
||||||
|
import Spinner from "@/components/Spinner.vue";
|
||||||
|
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
|
||||||
|
import FailureXMark from "@/components/FailureXMark.vue";
|
||||||
|
import { useInspectionStore } from "@/stores/admin/unit/inspection/inspection";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default defineComponent({
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
status: null as null | "loading" | { status: "success" | "failed"; reason?: string },
|
||||||
|
timeout: undefined as any,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(useInspectionStore, ["activeInspectionObj"]),
|
||||||
|
},
|
||||||
|
beforeUnmount() {
|
||||||
|
try {
|
||||||
|
clearTimeout(this.timeout);
|
||||||
|
} catch (error) {}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions(useModalStore, ["closeModal"]),
|
||||||
|
...mapActions(useInspectionStore, ["deleteInspection"]),
|
||||||
|
triggerDelete() {
|
||||||
|
if (!this.activeInspectionObj) return;
|
||||||
|
|
||||||
|
this.status = "loading";
|
||||||
|
this.deleteInspection(this.activeInspectionObj.id)
|
||||||
|
.then(() => {
|
||||||
|
this.status = { status: "success" };
|
||||||
|
this.timeout = setTimeout(() => {
|
||||||
|
this.$router.push({ name: "admin-unit-inspection" });
|
||||||
|
this.closeModal();
|
||||||
|
}, 1500);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.status = { status: "failed" };
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -11,13 +11,22 @@
|
||||||
Es wird ein PDF ausgedruckt und ist dann zu dieser Prüfung verfügbar.
|
Es wird ein PDF ausgedruckt und ist dann zu dieser Prüfung verfügbar.
|
||||||
</p>
|
</p>
|
||||||
<br />
|
<br />
|
||||||
<button primary>Prüfung abschließen</button>
|
<div class="flex flex-row gap-2">
|
||||||
|
<button :disabled="status == 'loading' || status?.status == 'success'" primary @click="finishInspection">
|
||||||
|
Prüfung abschließen
|
||||||
|
</button>
|
||||||
|
<Spinner v-if="status == 'loading'" class="my-auto" />
|
||||||
|
<SuccessCheckmark v-else-if="status?.status == 'success'" />
|
||||||
|
<FailureXMark v-else-if="status?.status == 'failed'" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<div class="flex flex-row justify-end">
|
<div class="flex flex-row justify-end">
|
||||||
<div class="flex flex-row gap-4 py-2">
|
<div class="flex flex-row gap-4 py-2">
|
||||||
<button primary-outline @click="closeModal">abbrechen</button>
|
<button primary-outline @click="closeModal" :disabled="status == 'loading' || status?.status == 'success'">
|
||||||
|
abbrechen
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -28,12 +37,47 @@ import { defineComponent } from "vue";
|
||||||
import { mapState, mapActions } from "pinia";
|
import { mapState, mapActions } from "pinia";
|
||||||
import { useModalStore } from "@/stores/modal";
|
import { useModalStore } from "@/stores/modal";
|
||||||
import { InformationCircleIcon } from "@heroicons/vue/24/outline";
|
import { InformationCircleIcon } from "@heroicons/vue/24/outline";
|
||||||
|
import { useInspectionStore } from "@/stores/admin/unit/inspection/inspection";
|
||||||
|
import Spinner from "@/components/Spinner.vue";
|
||||||
|
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
|
||||||
|
import FailureXMark from "@/components/FailureXMark.vue";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
status: null as null | "loading" | { status: "success" | "failed"; reason?: string },
|
||||||
|
timeout: null as any,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
beforeUnmount() {
|
||||||
|
try {
|
||||||
|
clearTimeout(this.timeout);
|
||||||
|
} catch (error) {}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(useModalStore, ["closeModal"]),
|
...mapActions(useModalStore, ["closeModal"]),
|
||||||
|
...mapActions(useInspectionStore, ["finishActiveInspection"]),
|
||||||
|
|
||||||
|
finishInspection(e: any) {
|
||||||
|
this.status = "loading";
|
||||||
|
this.finishActiveInspection()
|
||||||
|
.then(() => {
|
||||||
|
this.status = { status: "success" };
|
||||||
|
this.timeout = setTimeout(() => {
|
||||||
|
this.closeModal();
|
||||||
|
}, 2100);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
this.status = { status: "failed" };
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.timeout = setTimeout(() => {
|
||||||
|
this.status = null;
|
||||||
|
}, 2000);
|
||||||
|
});
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
<template>
|
||||||
|
<div class="w-full h-full flex flex-col gap-2">
|
||||||
|
<Spinner v-if="status == 'loading'" />
|
||||||
|
<div class="grow">
|
||||||
|
<iframe ref="viewer" class="w-full h-full" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-row gap-2 justify-end">
|
||||||
|
<a ref="download" button primary class="w-fit!">download</a>
|
||||||
|
<button primary-outline class="w-fit!" @click="closeModal">schließen</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { defineComponent } from "vue";
|
||||||
|
import { mapState, mapActions } from "pinia";
|
||||||
|
import { useModalStore } from "@/stores/modal";
|
||||||
|
import Spinner from "@/components/Spinner.vue";
|
||||||
|
import { useInspectionStore } from "@/stores/admin/unit/inspection/inspection";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default defineComponent({
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
status: null as null | "loading" | { status: "success" | "failed"; reason?: string },
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(useModalStore, ["data"]),
|
||||||
|
...mapState(useInspectionStore, ["activeInspectionObj"]),
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.fetchItem();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions(useModalStore, ["closeModal"]),
|
||||||
|
...mapActions(useInspectionStore, ["fetchInspectionPrintoutById"]),
|
||||||
|
fetchItem() {
|
||||||
|
this.status = "loading";
|
||||||
|
this.fetchInspectionPrintoutById()
|
||||||
|
.then((response) => {
|
||||||
|
this.status = { status: "success" };
|
||||||
|
const blob = new Blob([response.data], { type: "application/pdf" });
|
||||||
|
(this.$refs.viewer as HTMLIFrameElement).src = window.URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
const fileURL = window.URL.createObjectURL(new Blob([response.data]));
|
||||||
|
const fileLink = this.$refs.download as HTMLAnchorElement;
|
||||||
|
fileLink.href = fileURL;
|
||||||
|
fileLink.setAttribute(
|
||||||
|
"download",
|
||||||
|
`Prüf-Ausdruck_${[this.activeInspectionObj?.related.code ?? "", this.activeInspectionObj?.related.name].join("_")}_${this.activeInspectionObj?.inspectionPlan.title}_${new Date(this.activeInspectionObj?.created ?? "").toLocaleDateString("de-de")}.pdf`
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.status = { status: "failed" };
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -1,12 +1,15 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col h-fit w-full border border-primary rounded-md">
|
<RouterLink
|
||||||
|
:to="{ name: 'admin-unit-inspection_plan-overview', params: { inspectionPlanId: inspectionPlan.id } }"
|
||||||
|
class="flex flex-col h-fit w-full border border-primary rounded-md"
|
||||||
|
>
|
||||||
<div class="bg-primary p-2 text-white flex flex-row justify-between items-center">
|
<div class="bg-primary p-2 text-white flex flex-row justify-between items-center">
|
||||||
<p>{{ inspectionPlan.title }}</p>
|
<p>{{ inspectionPlan.title }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-2">
|
<div class="p-2">
|
||||||
<p>Interval: {{ inspectionPlan.inspectionInterval }}</p>
|
<p>Interval: {{ inspectionPlan.inspectionInterval }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</RouterLink>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
|
@ -102,8 +102,8 @@ export default defineComponent({
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
relatedType: {
|
relatedType: {
|
||||||
type: String as PropType<"vehicle" | "equipment" | "wearable">,
|
type: String as PropType<"vehicleType" | "equipmentType" | "wearableType">,
|
||||||
default: "equipment",
|
default: "equipmentType",
|
||||||
},
|
},
|
||||||
relatedTypeId: {
|
relatedTypeId: {
|
||||||
type: String,
|
type: String,
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { http } from "@/serverCom";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosResponse } from "axios";
|
||||||
import type {
|
import type {
|
||||||
CreateInspectionViewModel,
|
CreateInspectionViewModel,
|
||||||
|
CreateOrUpdateInspectionPointResultCommand,
|
||||||
InspectionNextViewModel,
|
InspectionNextViewModel,
|
||||||
InspectionViewModel,
|
InspectionViewModel,
|
||||||
MinifiedInspectionViewModel,
|
MinifiedInspectionViewModel,
|
||||||
|
@ -89,6 +90,11 @@ export const useInspectionStore = defineStore("inspection", {
|
||||||
fetchInspectionById(id: string) {
|
fetchInspectionById(id: string) {
|
||||||
return http.get(`/admin/inspection/${id}`);
|
return http.get(`/admin/inspection/${id}`);
|
||||||
},
|
},
|
||||||
|
fetchInspectionPrintoutById() {
|
||||||
|
return http.get(`/admin/inspection/${this.activeInspectionObj?.id}/printout`, {
|
||||||
|
responseType: "blob",
|
||||||
|
});
|
||||||
|
},
|
||||||
async createInspection(inspection: CreateInspectionViewModel): Promise<AxiosResponse<any, any>> {
|
async createInspection(inspection: CreateInspectionViewModel): Promise<AxiosResponse<any, any>> {
|
||||||
const result = await http.post(`/admin/inspection`, {
|
const result = await http.post(`/admin/inspection`, {
|
||||||
assigned: inspection.assigned,
|
assigned: inspection.assigned,
|
||||||
|
@ -100,17 +106,41 @@ export const useInspectionStore = defineStore("inspection", {
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
async updateActiveInspection(inspection: UpdateInspectionViewModel): Promise<AxiosResponse<any, any>> {
|
async updateActiveInspection(inspection: UpdateInspectionViewModel): Promise<AxiosResponse<any, any>> {
|
||||||
const result = await http.patch(`/admin/inspection/${inspection.id}`, {
|
const result = await http.patch(`/admin/inspection/${this.activeInspection}`, {
|
||||||
nextInspection: inspection.nextInspection,
|
nextInspection: inspection.nextInspection,
|
||||||
context: inspection.context,
|
context: inspection.context,
|
||||||
});
|
});
|
||||||
this.fetchInspectionByActiveId();
|
this.fetchInspectionByActiveId();
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
async deleteInspection(inspection: number): Promise<AxiosResponse<any, any>> {
|
async updateActiveInspectionResults(
|
||||||
const result = await http.delete(`/admin/inspection/${inspection}`);
|
results: Array<CreateOrUpdateInspectionPointResultCommand>,
|
||||||
|
files: { [key: string]: File | null }
|
||||||
|
): Promise<AxiosResponse<any, any>> {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("results", JSON.stringify(results));
|
||||||
|
Object.entries(files).forEach(([key, file]) => {
|
||||||
|
if (file) {
|
||||||
|
const extension = file.name.split(".").pop() || "";
|
||||||
|
formData.append(`files`, new File([file], `${key}.${extension}`, { type: file.type }));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const result = await http.patch(`/admin/inspection/${this.activeInspection}/results`, formData, {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "multipart/form-data",
|
||||||
|
},
|
||||||
|
});
|
||||||
this.fetchInspectionByActiveId();
|
this.fetchInspectionByActiveId();
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
async finishActiveInspection(): Promise<AxiosResponse<any, any>> {
|
||||||
|
const result = await http.patch(`/admin/inspection/${this.activeInspection}/finish`);
|
||||||
|
this.fetchInspectionByActiveId();
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
async deleteInspection(inspection: string): Promise<AxiosResponse<any, any>> {
|
||||||
|
const result = await http.delete(`/admin/inspection/${inspection}`);
|
||||||
|
return result;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -54,7 +54,7 @@ export const useInspectionPlanStore = defineStore("inspectionPlan", {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
async getAllInspectionPlansWithRelated(
|
async getAllInspectionPlansWithRelated(
|
||||||
related: "vehicle" | "equipment" | "wearable",
|
related: "vehicleType" | "equipmentType" | "wearableType",
|
||||||
relatedId: string
|
relatedId: string
|
||||||
): Promise<AxiosResponse<any, any>> {
|
): Promise<AxiosResponse<any, any>> {
|
||||||
return await http.get(`/admin/inspectionPlan/${related}/${relatedId}?noLimit=true`).then((res) => {
|
return await http.get(`/admin/inspectionPlan/${related}/${relatedId}?noLimit=true`).then((res) => {
|
||||||
|
@ -62,7 +62,7 @@ export const useInspectionPlanStore = defineStore("inspectionPlan", {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
async searchInspectionPlansWithRelated(
|
async searchInspectionPlansWithRelated(
|
||||||
related: "vehicle" | "equipment" | "wearable",
|
related: "vehicleType" | "equipmentType" | "wearableType",
|
||||||
relatedId: string,
|
relatedId: string,
|
||||||
search: string
|
search: string
|
||||||
): Promise<AxiosResponse<any, any>> {
|
): Promise<AxiosResponse<any, any>> {
|
||||||
|
|
|
@ -79,3 +79,8 @@ export type UpdateInspectionViewModel = {
|
||||||
nextInspection?: Date;
|
nextInspection?: Date;
|
||||||
context?: string;
|
context?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export interface CreateOrUpdateInspectionPointResultCommand {
|
||||||
|
inspectionPointId: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
|
@ -4,8 +4,7 @@
|
||||||
:items="inspections"
|
:items="inspections"
|
||||||
:totalCount="totalCount"
|
:totalCount="totalCount"
|
||||||
:indicateLoading="false"
|
:indicateLoading="false"
|
||||||
@load-data="(offset, count, search) => {}"
|
@load-data="(offset, count, search) => fetchInspectionForEquipment(offset, count, false)"
|
||||||
@search="(search) => {}"
|
|
||||||
>
|
>
|
||||||
<template #pageRow="{ row }: { row: InspectionViewModel }">
|
<template #pageRow="{ row }: { row: InspectionViewModel }">
|
||||||
<RouterLink
|
<RouterLink
|
||||||
|
|
|
@ -6,6 +6,13 @@
|
||||||
<small v-if="activeInspectionObj?.related.code">({{ activeInspectionObj?.related.code }})</small> -
|
<small v-if="activeInspectionObj?.related.code">({{ activeInspectionObj?.related.code }})</small> -
|
||||||
{{ activeInspectionObj?.inspectionPlan.title }}
|
{{ activeInspectionObj?.inspectionPlan.title }}
|
||||||
</h1>
|
</h1>
|
||||||
|
<div class="flex flex-row gap-2">
|
||||||
|
<TrashIcon
|
||||||
|
v-if="activeInspectionObj?.isOpen && can('delete', 'unit', 'inspection')"
|
||||||
|
class="w-5 h-5 cursor-pointer"
|
||||||
|
@click="openDeleteModal"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #main>
|
<template #main>
|
||||||
<Spinner v-if="loading == 'loading'" class="mx-auto" />
|
<Spinner v-if="loading == 'loading'" class="mx-auto" />
|
||||||
|
@ -79,7 +86,7 @@
|
||||||
<FailureXMark v-else-if="status?.status == 'failed'" />
|
<FailureXMark v-else-if="status?.status == 'failed'" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<button primary type="button" @click="">Bericht anzeigen</button>
|
<button primary type="button" @click="openPrintModal">Bericht anzeigen</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -103,6 +110,8 @@ import { useModalStore } from "@/stores/modal";
|
||||||
import NumberInput from "@/components/admin/unit/inspection/NumberInput.vue";
|
import NumberInput from "@/components/admin/unit/inspection/NumberInput.vue";
|
||||||
import TextInput from "@/components/admin/unit/inspection/TextInput.vue";
|
import TextInput from "@/components/admin/unit/inspection/TextInput.vue";
|
||||||
import FileInput from "@/components/admin/unit/inspection/FileInput.vue";
|
import FileInput from "@/components/admin/unit/inspection/FileInput.vue";
|
||||||
|
import { useAbilityStore } from "@/stores/ability";
|
||||||
|
import { DocumentTextIcon, TrashIcon } from "@heroicons/vue/24/outline";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
@ -137,8 +146,11 @@ export default defineComponent({
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
...mapState(useInspectionStore, ["activeInspectionObj", "loadingActive"]),
|
...mapState(useInspectionStore, ["activeInspectionObj", "loadingActive"]),
|
||||||
|
...mapState(useAbilityStore, ["can"]),
|
||||||
points() {
|
points() {
|
||||||
return this.activeInspectionObj?.inspectionVersionedPlan.inspectionPoints ?? [];
|
return (this.activeInspectionObj?.inspectionVersionedPlan.inspectionPoints ?? [])
|
||||||
|
.slice()
|
||||||
|
.sort((a, b) => (a.sort ?? 0) - (b.sort ?? 0));
|
||||||
},
|
},
|
||||||
pointResult() {
|
pointResult() {
|
||||||
return (pointId: string) => {
|
return (pointId: string) => {
|
||||||
|
@ -172,8 +184,24 @@ export default defineComponent({
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(useInspectionStore, ["fetchInspectionByActiveId"]),
|
...mapActions(useInspectionStore, ["fetchInspectionByActiveId", "updateActiveInspectionResults"]),
|
||||||
...mapActions(useModalStore, ["openModal"]),
|
...mapActions(useModalStore, ["openModal"]),
|
||||||
|
openDeleteModal() {
|
||||||
|
this.openModal(
|
||||||
|
markRaw(defineAsyncComponent(() => import("@/components/admin/unit/inspection/DeleteInspectionModal.vue"))),
|
||||||
|
parseInt(this.inspectionId ?? "")
|
||||||
|
);
|
||||||
|
},
|
||||||
|
openPrintModal() {
|
||||||
|
this.openModal(
|
||||||
|
markRaw(defineAsyncComponent(() => import("@/components/admin/unit/inspection/InspectionPrintModal.vue")))
|
||||||
|
);
|
||||||
|
},
|
||||||
|
finishInspection() {
|
||||||
|
this.openModal(
|
||||||
|
markRaw(defineAsyncComponent(() => import("@/components/admin/unit/inspection/InspectionFinishModal.vue")))
|
||||||
|
);
|
||||||
|
},
|
||||||
resetForm() {
|
resetForm() {
|
||||||
this.checks = cloneDeep(this.activeInspectionObj?.checks ?? []);
|
this.checks = cloneDeep(this.activeInspectionObj?.checks ?? []);
|
||||||
},
|
},
|
||||||
|
@ -194,9 +222,7 @@ export default defineComponent({
|
||||||
triggerUpdate(e: any) {
|
triggerUpdate(e: any) {
|
||||||
if (this.activeInspectionObj == null) return;
|
if (this.activeInspectionObj == null) return;
|
||||||
this.status = "loading";
|
this.status = "loading";
|
||||||
new Promise<void>((resolve, reject) => {
|
this.updateActiveInspectionResults(this.checks, this.fileStore)
|
||||||
resolve();
|
|
||||||
})
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.status = { status: "success" };
|
this.status = { status: "success" };
|
||||||
})
|
})
|
||||||
|
@ -209,11 +235,6 @@ export default defineComponent({
|
||||||
}, 2000);
|
}, 2000);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
finishInspection() {
|
|
||||||
this.openModal(
|
|
||||||
markRaw(defineAsyncComponent(() => import("@/components/admin/unit/inspection/InspectionFinishModal.vue")))
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -32,14 +32,15 @@
|
||||||
|
|
||||||
<InspectionPlanSearchSelectWithRelated
|
<InspectionPlanSearchSelectWithRelated
|
||||||
title="Prüfplan"
|
title="Prüfplan"
|
||||||
:relatedType="active"
|
:relatedType="`${active}Type`"
|
||||||
:relatedTypeId="relatedType"
|
:relatedTypeId="relatedType"
|
||||||
v-model="inspectionPlan"
|
v-model="inspectionPlan"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="nextInspection">
|
<label for="nextInspection" class="flex flex-row justify-between">
|
||||||
Nächste Prüfung (optional) - Intervall: {{ selectedInspectionPlan?.inspectionInterval }}
|
Nächste Prüfung (optional) - Intervall: {{ selectedInspectionPlan?.inspectionInterval ?? "xx" }}
|
||||||
|
<InspectionTimeFormatExplainIcon />
|
||||||
</label>
|
</label>
|
||||||
<input id="nextInspection" type="date" />
|
<input id="nextInspection" type="date" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -87,6 +88,7 @@ import { useVehicleStore } from "@/stores/admin/unit/vehicle/vehicle";
|
||||||
import { useWearableStore } from "@/stores/admin/unit/wearable/wearable";
|
import { useWearableStore } from "@/stores/admin/unit/wearable/wearable";
|
||||||
import type { CreateInspectionViewModel } from "@/viewmodels/admin/unit/inspection/inspection.models";
|
import type { CreateInspectionViewModel } from "@/viewmodels/admin/unit/inspection/inspection.models";
|
||||||
import { useInspectionStore } from "@/stores/admin/unit/inspection/inspection";
|
import { useInspectionStore } from "@/stores/admin/unit/inspection/inspection";
|
||||||
|
import InspectionTimeFormatExplainIcon from "@/components/admin/unit/InspectionTimeFormatExplainIcon.vue";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
|
@ -34,7 +34,10 @@
|
||||||
<input type="text" id="name" required />
|
<input type="text" id="name" required />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="interval">Intervall</label>
|
<label for="interval" class="flex flex-row justify-between">
|
||||||
|
Intervall
|
||||||
|
<InspectionTimeFormatExplainIcon />
|
||||||
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="interval"
|
id="interval"
|
||||||
|
@ -45,7 +48,10 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="remind">Erinnerung vor Fälligkeit</label>
|
<label for="remind" class="flex flex-row justify-between">
|
||||||
|
Erinnerung vor Fälligkeit
|
||||||
|
<InspectionTimeFormatExplainIcon />
|
||||||
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="remind"
|
id="remind"
|
||||||
|
@ -88,6 +94,7 @@ import type { CreateInspectionPlanViewModel } from "@/viewmodels/admin/unit/insp
|
||||||
import { useEquipmentTypeStore } from "@/stores/admin/unit/equipmentType/equipmentType";
|
import { useEquipmentTypeStore } from "@/stores/admin/unit/equipmentType/equipmentType";
|
||||||
import EquipmentTypeSearchSelect from "@/components/search/EquipmentTypeSearchSelect.vue";
|
import EquipmentTypeSearchSelect from "@/components/search/EquipmentTypeSearchSelect.vue";
|
||||||
import VehicleTypeSearchSelect from "@/components/search/VehicleTypeSearchSelect.vue";
|
import VehicleTypeSearchSelect from "@/components/search/VehicleTypeSearchSelect.vue";
|
||||||
|
import InspectionTimeFormatExplainIcon from "@/components/admin/unit/InspectionTimeFormatExplainIcon.vue";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue