unit/#103-base-management #110
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.
|
||||
</p>
|
||||
<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>
|
||||
<br />
|
||||
|
||||
<div class="flex flex-row justify-end">
|
||||
<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>
|
||||
|
@ -28,12 +37,47 @@ import { defineComponent } from "vue";
|
|||
import { mapState, mapActions } from "pinia";
|
||||
import { useModalStore } from "@/stores/modal";
|
||||
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 lang="ts">
|
||||
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: {
|
||||
...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>
|
||||
|
|
|
@ -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>
|
||||
<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">
|
||||
<p>{{ inspectionPlan.title }}</p>
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<p>Interval: {{ inspectionPlan.inspectionInterval }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</RouterLink>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
|
|
@ -102,8 +102,8 @@ export default defineComponent({
|
|||
default: false,
|
||||
},
|
||||
relatedType: {
|
||||
type: String as PropType<"vehicle" | "equipment" | "wearable">,
|
||||
default: "equipment",
|
||||
type: String as PropType<"vehicleType" | "equipmentType" | "wearableType">,
|
||||
default: "equipmentType",
|
||||
},
|
||||
relatedTypeId: {
|
||||
type: String,
|
||||
|
|
|
@ -3,6 +3,7 @@ import { http } from "@/serverCom";
|
|||
import type { AxiosResponse } from "axios";
|
||||
import type {
|
||||
CreateInspectionViewModel,
|
||||
CreateOrUpdateInspectionPointResultCommand,
|
||||
InspectionNextViewModel,
|
||||
InspectionViewModel,
|
||||
MinifiedInspectionViewModel,
|
||||
|
@ -89,6 +90,11 @@ export const useInspectionStore = defineStore("inspection", {
|
|||
fetchInspectionById(id: string) {
|
||||
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>> {
|
||||
const result = await http.post(`/admin/inspection`, {
|
||||
assigned: inspection.assigned,
|
||||
|
@ -100,17 +106,41 @@ export const useInspectionStore = defineStore("inspection", {
|
|||
return result;
|
||||
},
|
||||
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,
|
||||
context: inspection.context,
|
||||
});
|
||||
this.fetchInspectionByActiveId();
|
||||
return result;
|
||||
},
|
||||
async deleteInspection(inspection: number): Promise<AxiosResponse<any, any>> {
|
||||
const result = await http.delete(`/admin/inspection/${inspection}`);
|
||||
async updateActiveInspectionResults(
|
||||
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();
|
||||
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(
|
||||
related: "vehicle" | "equipment" | "wearable",
|
||||
related: "vehicleType" | "equipmentType" | "wearableType",
|
||||
relatedId: string
|
||||
): Promise<AxiosResponse<any, any>> {
|
||||
return await http.get(`/admin/inspectionPlan/${related}/${relatedId}?noLimit=true`).then((res) => {
|
||||
|
@ -62,7 +62,7 @@ export const useInspectionPlanStore = defineStore("inspectionPlan", {
|
|||
});
|
||||
},
|
||||
async searchInspectionPlansWithRelated(
|
||||
related: "vehicle" | "equipment" | "wearable",
|
||||
related: "vehicleType" | "equipmentType" | "wearableType",
|
||||
relatedId: string,
|
||||
search: string
|
||||
): Promise<AxiosResponse<any, any>> {
|
||||
|
|
|
@ -79,3 +79,8 @@ export type UpdateInspectionViewModel = {
|
|||
nextInspection?: Date;
|
||||
context?: string;
|
||||
};
|
||||
|
||||
export interface CreateOrUpdateInspectionPointResultCommand {
|
||||
inspectionPointId: string;
|
||||
value: string;
|
||||
}
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
:items="inspections"
|
||||
:totalCount="totalCount"
|
||||
:indicateLoading="false"
|
||||
@load-data="(offset, count, search) => {}"
|
||||
@search="(search) => {}"
|
||||
@load-data="(offset, count, search) => fetchInspectionForEquipment(offset, count, false)"
|
||||
>
|
||||
<template #pageRow="{ row }: { row: InspectionViewModel }">
|
||||
<RouterLink
|
||||
|
|
|
@ -6,6 +6,13 @@
|
|||
<small v-if="activeInspectionObj?.related.code">({{ activeInspectionObj?.related.code }})</small> -
|
||||
{{ activeInspectionObj?.inspectionPlan.title }}
|
||||
</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 #main>
|
||||
<Spinner v-if="loading == 'loading'" class="mx-auto" />
|
||||
|
@ -79,7 +86,7 @@
|
|||
<FailureXMark v-else-if="status?.status == 'failed'" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<button primary type="button" @click="">Bericht anzeigen</button>
|
||||
<button primary type="button" @click="openPrintModal">Bericht anzeigen</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -103,6 +110,8 @@ import { useModalStore } from "@/stores/modal";
|
|||
import NumberInput from "@/components/admin/unit/inspection/NumberInput.vue";
|
||||
import TextInput from "@/components/admin/unit/inspection/TextInput.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 lang="ts">
|
||||
|
@ -137,8 +146,11 @@ export default defineComponent({
|
|||
);
|
||||
},
|
||||
...mapState(useInspectionStore, ["activeInspectionObj", "loadingActive"]),
|
||||
...mapState(useAbilityStore, ["can"]),
|
||||
points() {
|
||||
return this.activeInspectionObj?.inspectionVersionedPlan.inspectionPoints ?? [];
|
||||
return (this.activeInspectionObj?.inspectionVersionedPlan.inspectionPoints ?? [])
|
||||
.slice()
|
||||
.sort((a, b) => (a.sort ?? 0) - (b.sort ?? 0));
|
||||
},
|
||||
pointResult() {
|
||||
return (pointId: string) => {
|
||||
|
@ -172,8 +184,24 @@ export default defineComponent({
|
|||
} catch (error) {}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useInspectionStore, ["fetchInspectionByActiveId"]),
|
||||
...mapActions(useInspectionStore, ["fetchInspectionByActiveId", "updateActiveInspectionResults"]),
|
||||
...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() {
|
||||
this.checks = cloneDeep(this.activeInspectionObj?.checks ?? []);
|
||||
},
|
||||
|
@ -194,9 +222,7 @@ export default defineComponent({
|
|||
triggerUpdate(e: any) {
|
||||
if (this.activeInspectionObj == null) return;
|
||||
this.status = "loading";
|
||||
new Promise<void>((resolve, reject) => {
|
||||
resolve();
|
||||
})
|
||||
this.updateActiveInspectionResults(this.checks, this.fileStore)
|
||||
.then(() => {
|
||||
this.status = { status: "success" };
|
||||
})
|
||||
|
@ -209,11 +235,6 @@ export default defineComponent({
|
|||
}, 2000);
|
||||
});
|
||||
},
|
||||
finishInspection() {
|
||||
this.openModal(
|
||||
markRaw(defineAsyncComponent(() => import("@/components/admin/unit/inspection/InspectionFinishModal.vue")))
|
||||
);
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -32,14 +32,15 @@
|
|||
|
||||
<InspectionPlanSearchSelectWithRelated
|
||||
title="Prüfplan"
|
||||
:relatedType="active"
|
||||
:relatedType="`${active}Type`"
|
||||
:relatedTypeId="relatedType"
|
||||
v-model="inspectionPlan"
|
||||
/>
|
||||
|
||||
<div>
|
||||
<label for="nextInspection">
|
||||
Nächste Prüfung (optional) - Intervall: {{ selectedInspectionPlan?.inspectionInterval }}
|
||||
<label for="nextInspection" class="flex flex-row justify-between">
|
||||
Nächste Prüfung (optional) - Intervall: {{ selectedInspectionPlan?.inspectionInterval ?? "xx" }}
|
||||
<InspectionTimeFormatExplainIcon />
|
||||
</label>
|
||||
<input id="nextInspection" type="date" />
|
||||
</div>
|
||||
|
@ -87,6 +88,7 @@ import { useVehicleStore } from "@/stores/admin/unit/vehicle/vehicle";
|
|||
import { useWearableStore } from "@/stores/admin/unit/wearable/wearable";
|
||||
import type { CreateInspectionViewModel } from "@/viewmodels/admin/unit/inspection/inspection.models";
|
||||
import { useInspectionStore } from "@/stores/admin/unit/inspection/inspection";
|
||||
import InspectionTimeFormatExplainIcon from "@/components/admin/unit/InspectionTimeFormatExplainIcon.vue";
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
|
|
|
@ -34,7 +34,10 @@
|
|||
<input type="text" id="name" required />
|
||||
</div>
|
||||
<div>
|
||||
<label for="interval">Intervall</label>
|
||||
<label for="interval" class="flex flex-row justify-between">
|
||||
Intervall
|
||||
<InspectionTimeFormatExplainIcon />
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="interval"
|
||||
|
@ -45,7 +48,10 @@
|
|||
/>
|
||||
</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
|
||||
type="text"
|
||||
id="remind"
|
||||
|
@ -88,6 +94,7 @@ import type { CreateInspectionPlanViewModel } from "@/viewmodels/admin/unit/insp
|
|||
import { useEquipmentTypeStore } from "@/stores/admin/unit/equipmentType/equipmentType";
|
||||
import EquipmentTypeSearchSelect from "@/components/search/EquipmentTypeSearchSelect.vue";
|
||||
import VehicleTypeSearchSelect from "@/components/search/VehicleTypeSearchSelect.vue";
|
||||
import InspectionTimeFormatExplainIcon from "@/components/admin/unit/InspectionTimeFormatExplainIcon.vue";
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue