unit/#103-base-management #110
19 changed files with 457 additions and 25 deletions
|
@ -14,6 +14,8 @@
|
|||
type="number"
|
||||
required
|
||||
v-model="value"
|
||||
:min="inspectionPoint.min"
|
||||
:max="inspectionPoint.max"
|
||||
/>
|
||||
<textarea v-else :id="inspectionPoint.id" :name="inspectionPoint.id" required class="h-18" v-model="value" />
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
<template>
|
||||
<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 justify-between items-center gap-2">
|
||||
<ClipboardDocumentCheckIcon v-if="modelValue.type == InspectionPointEnum.oknok" class="w-6 h-6" />
|
||||
<CalculatorIcon v-else-if="modelValue.type == InspectionPointEnum.number" class="w-6 h-6" />
|
||||
<BoldIcon v-else-if="modelValue.type == InspectionPointEnum.text" class="w-6 h-6" />
|
||||
<DocumentIcon v-else-if="modelValue.type == InspectionPointEnum.file" class="w-6 h-6" />
|
||||
|
||||
<input type="text" placeholder="Titel" v-model="title" />
|
||||
|
||||
<div class="flex flex-col">
|
||||
<ChevronUpIcon v-if="index != 0" class="text-white w-4 h-4 stroke-2 cursor-pointer" @click="$emit('up')" />
|
||||
<ChevronDownIcon
|
||||
v-if="index != totalCount - 1"
|
||||
class="text-white w-4 h-4 stroke-2 cursor-pointer"
|
||||
@click="$emit('down')"
|
||||
/>
|
||||
</div>
|
||||
<TrashIcon class="h-5 w-5 cursor-pointer" @click="$emit('remove')" />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<textarea name="description" placeholder="Beschreibung" v-model="description"></textarea>
|
||||
<div v-if="modelValue.type == InspectionPointEnum.number">
|
||||
<label for="min">Mindestens</label>
|
||||
<input type="number" v-model="min" min="0" />
|
||||
</div>
|
||||
<div v-if="modelValue.type == InspectionPointEnum.number">
|
||||
<label for="max">Maximal</label>
|
||||
<input type="number" v-model="max" min="0" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { defineComponent, type PropType } from "vue";
|
||||
import type { InspectionPointViewModel } from "@/viewmodels/admin/unit/inspection/inspectionPlan.models";
|
||||
import { InspectionPointEnum } from "@/enums/inspectionEnum";
|
||||
import {
|
||||
BoldIcon,
|
||||
CalculatorIcon,
|
||||
ClipboardDocumentCheckIcon,
|
||||
TrashIcon,
|
||||
ChevronUpIcon,
|
||||
ChevronDownIcon,
|
||||
DocumentIcon,
|
||||
} from "@heroicons/vue/24/outline";
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default defineComponent({
|
||||
props: {
|
||||
index: { type: Number, default: 0 },
|
||||
totalCount: { type: Number, default: 0 },
|
||||
modelValue: {
|
||||
type: Object as PropType<InspectionPointViewModel>,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
emits: ["up", "down", "remove", "update:model-value"],
|
||||
computed: {
|
||||
title: {
|
||||
get() {
|
||||
return this.modelValue.title;
|
||||
},
|
||||
set(val: InspectionPointViewModel) {
|
||||
this.$emit("update:model-value", { ...this.modelValue, title: val });
|
||||
},
|
||||
},
|
||||
description: {
|
||||
get() {
|
||||
return this.modelValue.description;
|
||||
},
|
||||
set(val: InspectionPointViewModel) {
|
||||
this.$emit("update:model-value", { ...this.modelValue, description: val });
|
||||
},
|
||||
},
|
||||
min: {
|
||||
get() {
|
||||
return this.modelValue.min;
|
||||
},
|
||||
set(val: InspectionPointViewModel) {
|
||||
this.$emit("update:model-value", { ...this.modelValue, min: val });
|
||||
},
|
||||
},
|
||||
max: {
|
||||
get() {
|
||||
return this.modelValue.max;
|
||||
},
|
||||
set(val: InspectionPointViewModel) {
|
||||
this.$emit("update:model-value", { ...this.modelValue, max: val });
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
|
@ -6,6 +6,9 @@
|
|||
<div class="bg-primary p-2 text-white flex flex-row justify-between items-center">
|
||||
<p>{{ vehicle.name }}</p>
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<p v-if="vehicle.code">Code: {{ vehicle.code }}</p>
|
||||
</div>
|
||||
</RouterLink>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -2,4 +2,5 @@ export enum InspectionPointEnum {
|
|||
oknok = "oknok",
|
||||
text = "text",
|
||||
number = "number",
|
||||
file = "file",
|
||||
}
|
||||
|
|
|
@ -898,7 +898,15 @@ const router = createRouter({
|
|||
{
|
||||
path: "edit",
|
||||
name: "admin-unit-inspection_plan-edit",
|
||||
component: () => import("@/views/admin/ViewSelect.vue"),
|
||||
component: () => import("@/views/admin/unit/inspectionPlan/UpdateInspectionPlan.vue"),
|
||||
meta: { type: "update", section: "unit", module: "inspection_plan" },
|
||||
beforeEnter: [abilityAndNavUpdate],
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: "pointedit",
|
||||
name: "admin-unit-inspection_plan-pointedit",
|
||||
component: () => import("@/views/admin/unit/inspectionPlan/UpdateInspectionPlanPoints.vue"),
|
||||
meta: { type: "update", section: "unit", module: "inspection_plan" },
|
||||
beforeEnter: [abilityAndNavUpdate],
|
||||
props: true,
|
||||
|
@ -916,13 +924,25 @@ const router = createRouter({
|
|||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "admin-unit-inspection",
|
||||
redirect: { name: "admin-unit-inspection-plan" },
|
||||
name: "admin-unit-inspection-routing",
|
||||
component: () => import("@/views/admin/unit/inspection/InspectionRouting.vue"),
|
||||
children: [
|
||||
{
|
||||
path: "next",
|
||||
name: "admin-unit-inspection",
|
||||
component: () => import("@/views/admin/unit/inspection/NextInspection.vue"),
|
||||
},
|
||||
{
|
||||
path: "running",
|
||||
name: "admin-unit-inspection-running",
|
||||
component: () => import("@/views/admin/unit/inspection/NextInspection.vue"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "plan/:type?/:relatedId?/:inspectionPlanId?",
|
||||
name: "admin-unit-inspection-plan",
|
||||
component: () => import("@/views/admin/unit/inspection/InspectionPlan.vue"),
|
||||
path: "start/:type?/:relatedId?/:inspectionPlanId?",
|
||||
name: "admin-unit-inspection-start",
|
||||
component: () => import("@/views/admin/unit/inspection/InspectionStart.vue"),
|
||||
beforeEnter: [],
|
||||
props: true,
|
||||
},
|
||||
|
|
|
@ -110,13 +110,13 @@ export const useNavigationStore = defineStore("navigation", {
|
|||
...(abilityStore.can("read", "unit", "equipment") ? [{ key: "equipment", title: "Gerätschaften" }] : []),
|
||||
...(abilityStore.can("read", "unit", "vehicle") ? [{ key: "vehicle", title: "Fahrzeuge" }] : []),
|
||||
...(abilityStore.can("read", "unit", "wearable") ? [{ key: "wearable", title: "Kleidung" }] : []),
|
||||
...(abilityStore.can("read", "unit", "respiratory_gear")
|
||||
...(false && abilityStore.can("read", "unit", "respiratory_gear")
|
||||
? [{ key: "respiratory_gear", title: "Atemschutz-Geräte" }]
|
||||
: []),
|
||||
...(abilityStore.can("read", "unit", "respiratory_wearer")
|
||||
...(false && abilityStore.can("read", "unit", "respiratory_wearer")
|
||||
? [{ key: "respiratory_wearer", title: "Atemschutz-Träger" }]
|
||||
: []),
|
||||
...(abilityStore.can("read", "unit", "respiratory_mission")
|
||||
...(false && abilityStore.can("read", "unit", "respiratory_mission")
|
||||
? [{ key: "respiratory_mission", title: "Atemschutz-Einsätze" }]
|
||||
: []),
|
||||
...(abilityStore.can("create", "unit", "inspection") ? [{ key: "inspection", title: "Prüfungen" }] : []),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="flex flex-col w-full h-full gap-2 justify-center px-7">
|
||||
<div class="flex flex-col w-full h-full gap-2 justify-center">
|
||||
<Pagination
|
||||
:items="damageReports"
|
||||
:totalCount="totalCount"
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<div class="flex flex-row gap-4">
|
||||
<RouterLink
|
||||
v-if="can('create', 'unit', 'equipment')"
|
||||
:to="{ name: 'admin-unit-inspection-plan', params: { type: 'equipment', relatedId: equipmentId } }"
|
||||
:to="{ name: 'admin-unit-inspection-start', params: { type: 'equipment', relatedId: equipmentId } }"
|
||||
button
|
||||
primary
|
||||
class="w-fit!"
|
||||
|
|
54
src/views/admin/unit/inspection/InspectionRouting.vue
Normal file
54
src/views/admin/unit/inspection/InspectionRouting.vue
Normal file
|
@ -0,0 +1,54 @@
|
|||
<template>
|
||||
<MainTemplate title="Prüfungen">
|
||||
<template #diffMain>
|
||||
<div class="flex flex-col gap-2 grow px-7 overflow-hidden">
|
||||
<div class="flex flex-col grow gap-2 overflow-hidden">
|
||||
<div class="w-full flex flex-row max-lg:flex-wrap justify-center">
|
||||
<RouterLink
|
||||
v-for="tab in tabs"
|
||||
:key="tab.route"
|
||||
v-slot="{ isExactActive }"
|
||||
:to="{ name: tab.route }"
|
||||
class="w-1/2 md:w-1/3 lg:w-full p-0.5 first:pl-0 last:pr-0"
|
||||
>
|
||||
<p
|
||||
:class="[
|
||||
'w-full rounded-lg py-2.5 text-sm text-center font-medium leading-5 focus:ring-0 outline-hidden',
|
||||
isExactActive ? 'bg-red-200 shadow-sm border-b-2 border-primary rounded-b-none' : ' hover:bg-red-200',
|
||||
]"
|
||||
>
|
||||
{{ tab.title }}
|
||||
</p>
|
||||
</RouterLink>
|
||||
</div>
|
||||
<RouterView />
|
||||
</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 { RouterLink, RouterView } from "vue-router";
|
||||
import { useAbilityStore } from "@/stores/ability";
|
||||
import { useEquipmentStore } from "@/stores/admin/unit/equipment/equipment";
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default defineComponent({
|
||||
data() {
|
||||
return {
|
||||
tabs: [
|
||||
{ route: "admin-unit-inspection", title: "anstehend" },
|
||||
{ route: "admin-unit-inspection-running", title: "in Arbeit" },
|
||||
],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(useAbilityStore, ["can"]),
|
||||
},
|
||||
});
|
||||
</script>
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<MainTemplate title="Prüfung erstellen">
|
||||
<MainTemplate title="Prüfung starten">
|
||||
<template #main>
|
||||
<form class="flex flex-col gap-4 py-2 w-full max-w-xl mx-auto" @submit.prevent="">
|
||||
<div class="flex flex-row">
|
||||
|
@ -47,7 +47,7 @@
|
|||
>
|
||||
abbrechen
|
||||
</RouterLink>
|
||||
<button primary type="submit" class="w-fit!" :disabled="status == 'loading'">speichern</button>
|
||||
<button primary type="submit" class="w-fit!" :disabled="status == 'loading'">starten</button>
|
||||
<Spinner v-if="status == 'loading'" class="my-auto" />
|
||||
<SuccessCheckmark v-else-if="status?.status == 'success'" />
|
||||
<FailureXMark v-else-if="status?.status == 'failed'" />
|
||||
|
@ -64,11 +64,10 @@ import MainTemplate from "@/templates/Main.vue";
|
|||
import Spinner from "@/components/Spinner.vue";
|
||||
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
|
||||
import FailureXMark from "@/components/FailureXMark.vue";
|
||||
import ScanInput from "@/components/ScanInput.vue";
|
||||
import InspectionPlanSearchSelect from "@/components/search/InspectionPlanSearchSelect.vue";
|
||||
import EquipmentSearchSelect from "@/components/search/EquipmentSearchSelect.vue";
|
||||
import VehicleSearchSelect from "@/components/search/VehicleSearchSelect.vue";
|
||||
import WearableSearchSelect from "../../../../components/search/wearableSearchSelect.vue";
|
||||
import WearableSearchSelect from "@/components/search/WearableSearchSelect.vue";
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
45
src/views/admin/unit/inspection/NextInspection.vue
Normal file
45
src/views/admin/unit/inspection/NextInspection.vue
Normal file
|
@ -0,0 +1,45 @@
|
|||
<template>
|
||||
<div class="flex flex-col w-full h-full gap-2 justify-center">
|
||||
<Pagination
|
||||
:items="[]"
|
||||
:totalCount="0"
|
||||
:indicateLoading="false"
|
||||
@load-data="(offset, count, search) => {}"
|
||||
@search="(search) => {}"
|
||||
>
|
||||
<template #pageRow="{ row }: { row: any }">
|
||||
{{ row }}
|
||||
</template>
|
||||
</Pagination>
|
||||
|
||||
<div class="flex flex-row gap-4">
|
||||
<RouterLink
|
||||
v-if="can('create', 'unit', 'inspection')"
|
||||
:to="{ name: 'admin-unit-inspection-start' }"
|
||||
primary
|
||||
button
|
||||
class="w-fit!"
|
||||
>
|
||||
Prüfung starten
|
||||
</RouterLink>
|
||||
</div>
|
||||
</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";
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default defineComponent({
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
computed: {
|
||||
...mapState(useAbilityStore, ["can"]),
|
||||
},
|
||||
});
|
||||
</script>
|
|
@ -159,7 +159,7 @@ export default defineComponent({
|
|||
|
||||
this.timeout = setTimeout(() => {
|
||||
this.$router.push({
|
||||
name: "admin-unit-inspectionPlan-overview",
|
||||
name: "admin-unit-inspection_plan-overview",
|
||||
params: {
|
||||
inspectionPlanId: res.data,
|
||||
},
|
||||
|
|
|
@ -4,9 +4,17 @@
|
|||
<RouterLink to="./" class="text-primary">zurück zur Liste</RouterLink>
|
||||
</template>
|
||||
<template #topBar>
|
||||
<RouterLink v-if="can('update', 'unit', 'inspection_plan')" :to="{ name: 'admin-unit-inspection_plan-edit' }">
|
||||
<PencilIcon class="w-5 h-5" />
|
||||
</RouterLink>
|
||||
<div class="flex flex-row gap-2">
|
||||
<RouterLink v-if="can('update', 'unit', 'inspection_plan')" :to="{ name: 'admin-unit-inspection_plan-edit' }">
|
||||
<PencilIcon class="w-5 h-5" />
|
||||
</RouterLink>
|
||||
<RouterLink
|
||||
v-if="can('update', 'unit', 'inspection_plan')"
|
||||
:to="{ name: 'admin-unit-inspection_plan-pointedit' }"
|
||||
>
|
||||
<RectangleStackIcon class="w-5 h-5" />
|
||||
</RouterLink>
|
||||
</div>
|
||||
</template>
|
||||
<template #diffMain>
|
||||
<div class="flex flex-col gap-2 grow px-7 overflow-hidden">
|
||||
|
@ -21,7 +29,7 @@ import { defineComponent } from "vue";
|
|||
import { mapActions, mapState } from "pinia";
|
||||
import MainTemplate from "@/templates/Main.vue";
|
||||
import { RouterLink, RouterView } from "vue-router";
|
||||
import { PencilIcon, TrashIcon } from "@heroicons/vue/24/outline";
|
||||
import { PencilIcon, RectangleStackIcon, TrashIcon } from "@heroicons/vue/24/outline";
|
||||
import { useAbilityStore } from "@/stores/ability";
|
||||
import { useInspectionPlanStore } from "@/stores/admin/unit/inspectionPlan/inspectionPlan";
|
||||
</script>
|
||||
|
|
|
@ -7,7 +7,11 @@
|
|||
</div>
|
||||
<div>
|
||||
<label for="interval">Intervall</label>
|
||||
<input type="text" id="interval" :value="activeInspectionPlanObj.inspectionInterval" reaonly />
|
||||
<input type="text" id="interval" :value="activeInspectionPlanObj.inspectionInterval" readonly />
|
||||
</div>
|
||||
<div>
|
||||
<label for="remind">Erinnerung vor Fälligkeit</label>
|
||||
<input type="text" id="remind" :value="activeInspectionPlanObj.remindTime" readonly />
|
||||
</div>
|
||||
</div>
|
||||
<p>Prüfungspunkte:</p>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<template>
|
||||
<div class="flex flex-col gap-2 h-full w-full overflow-y-auto">
|
||||
<RouterLink to="./" class="text-primary">zurück zur Übersicht</RouterLink>
|
||||
<Spinner v-if="loading == 'loading'" class="mx-auto" />
|
||||
<p v-else-if="loading == 'failed'">laden fehlgeschlagen</p>
|
||||
<form
|
||||
|
@ -7,7 +8,7 @@
|
|||
class="flex flex-col gap-4 py-2 w-full max-w-xl mx-auto"
|
||||
@submit.prevent="triggerUpdate"
|
||||
>
|
||||
<p class="mx-auto">Ausrüstung bearbeiten</p>
|
||||
<p class="mx-auto">Prüfplan bearbeiten</p>
|
||||
<div>
|
||||
<label for="name">Bezeichnung</label>
|
||||
<input type="text" id="name" required v-model="inspectionPlan.title" />
|
||||
|
|
|
@ -0,0 +1,199 @@
|
|||
<template>
|
||||
<div class="flex flex-col gap-2 h-full w-full overflow-y-auto">
|
||||
<RouterLink to="./" class="text-primary">zurück zur Übersicht</RouterLink>
|
||||
<Spinner v-if="loading == 'loading'" class="mx-auto" />
|
||||
<p v-else-if="loading == 'failed'">laden fehlgeschlagen</p>
|
||||
<div
|
||||
v-else-if="inspectionPlan != null"
|
||||
class="flex flex-col grow gap-4 py-2 w-full max-w-xl mx-auto overflow-hidden"
|
||||
>
|
||||
<p class="mx-auto">Prüfplan-Punkte bearbeiten</p>
|
||||
|
||||
<div class="flex flex-row justify-center gap-4">
|
||||
<div
|
||||
class="p-3 border border-gray-300 rounded-md shadow cursor-pointer"
|
||||
@click="addItemToArray(InspectionPointEnum.oknok)"
|
||||
>
|
||||
<ClipboardDocumentCheckIcon class="w-7 h-7" />
|
||||
</div>
|
||||
<div
|
||||
class="p-3 border border-gray-300 rounded-md shadow cursor-pointer pointer-events-none opacity-50"
|
||||
@click="addItemToArray(InspectionPointEnum.file)"
|
||||
>
|
||||
<DocumentIcon class="w-7 h-7" />
|
||||
</div>
|
||||
<div
|
||||
class="p-3 border border-gray-300 rounded-md shadow cursor-pointer"
|
||||
@click="addItemToArray(InspectionPointEnum.number)"
|
||||
>
|
||||
<CalculatorIcon class="w-7 h-7" />
|
||||
</div>
|
||||
<div
|
||||
class="p-3 border border-gray-300 rounded-md shadow cursor-pointer"
|
||||
@click="addItemToArray(InspectionPointEnum.text)"
|
||||
>
|
||||
<BoldIcon class="w-7 h-7" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grow flex flex-col gap-2 overflow-y-scroll">
|
||||
<InspectionPointListItem
|
||||
v-for="(point, index) in sortedPoints"
|
||||
:key="index"
|
||||
:model-value="point"
|
||||
:index="index"
|
||||
:total-count="inspectionPoints.length"
|
||||
@update:model-value="updateItemFromArray"
|
||||
@up="changeSort('up', point.id, index)"
|
||||
@down="changeSort('down', point.id, index)"
|
||||
@remove="removeItemFromArray(point.id)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row justify-end gap-2">
|
||||
<button primary-outline type="reset" class="w-fit!" :disabled="canSaveOrReset" @click="resetForm">
|
||||
abbrechen
|
||||
</button>
|
||||
<button primary type="submit" class="w-fit!" :disabled="status == 'loading'" @click="triggerUpdate">
|
||||
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>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { defineComponent } from "vue";
|
||||
import { mapActions, mapState } from "pinia";
|
||||
import { useInspectionPlanStore } from "@/stores/admin/unit/inspectionPlan/inspectionPlan";
|
||||
import type {
|
||||
CreateInspectionPlanViewModel,
|
||||
InspectionPlanViewModel,
|
||||
InspectionPointViewModel,
|
||||
UpdateInspectionPlanViewModel,
|
||||
} from "@/viewmodels/admin/unit/inspection/inspectionPlan.models";
|
||||
import Spinner from "@/components/Spinner.vue";
|
||||
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
|
||||
import FailureXMark from "@/components/FailureXMark.vue";
|
||||
import isEqual from "lodash.isequal";
|
||||
import cloneDeep from "lodash.clonedeep";
|
||||
import { BoldIcon, CalculatorIcon, ClipboardDocumentCheckIcon, DocumentIcon } from "@heroicons/vue/24/outline";
|
||||
import { InspectionPointEnum } from "@/enums/inspectionEnum";
|
||||
import { v4 as uuid } from "uuid";
|
||||
import InspectionPointListItem from "@/components/admin/unit/inspectionPlan/InspectionPointListItem.vue";
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default defineComponent({
|
||||
props: {
|
||||
inspectionPlanId: String,
|
||||
},
|
||||
watch: {
|
||||
loadingActive() {
|
||||
if (this.loading == "loading") {
|
||||
this.loading = this.loadingActive;
|
||||
}
|
||||
if (this.loadingActive == "fetched") this.inspectionPlan = cloneDeep(this.activeInspectionPlanObj);
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: "loading" as "loading" | "fetched" | "failed",
|
||||
status: null as null | "loading" | { status: "success" | "failed"; reason?: string },
|
||||
inspectionPlan: null as null | InspectionPlanViewModel,
|
||||
timeout: null as any,
|
||||
inspectionPoints: [] as Array<InspectionPointViewModel>,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
canSaveOrReset(): boolean {
|
||||
return isEqual(this.activeInspectionPlanObj, this.inspectionPlan);
|
||||
},
|
||||
...mapState(useInspectionPlanStore, ["activeInspectionPlanObj", "loadingActive"]),
|
||||
sortedPoints() {
|
||||
return this.inspectionPoints.slice().sort((a, b) => a.sort - b.sort);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.fetchItem();
|
||||
},
|
||||
beforeUnmount() {
|
||||
try {
|
||||
clearTimeout(this.timeout);
|
||||
} catch (error) {}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useInspectionPlanStore, ["updateActiveInspectionPlan", "fetchInspectionPlanByActiveId"]),
|
||||
resetForm() {
|
||||
this.inspectionPlan = cloneDeep(this.activeInspectionPlanObj);
|
||||
},
|
||||
fetchItem() {
|
||||
this.fetchInspectionPlanByActiveId();
|
||||
},
|
||||
addItemToArray(type: InspectionPointEnum) {
|
||||
this.inspectionPoints.push({
|
||||
id: uuid(),
|
||||
title: "",
|
||||
description: "",
|
||||
type,
|
||||
sort: this.inspectionPoints.length,
|
||||
});
|
||||
},
|
||||
updateItemFromArray(pkg: InspectionPointViewModel) {
|
||||
let index = this.inspectionPoints.findIndex((ip) => ip.id == pkg.id);
|
||||
this.inspectionPoints[index] = pkg;
|
||||
},
|
||||
removeItemFromArray(id: string) {
|
||||
let index = this.inspectionPoints.findIndex((ip) => ip.id == id);
|
||||
if (index !== -1) {
|
||||
this.inspectionPoints.splice(index, 1);
|
||||
this.normalizeSort();
|
||||
}
|
||||
},
|
||||
changeSort(dir: "up" | "down", thisId: string, index: number) {
|
||||
let affected = this.sortedPoints[dir == "up" ? index - 1 : index + 1];
|
||||
if (affected) {
|
||||
this.inspectionPoints.find((a) => a.id == thisId)!.sort = dir == "up" ? index - 1 : index + 1;
|
||||
this.inspectionPoints.find((a) => a.id == affected.id)!.sort =
|
||||
dir == "up" ? affected.sort + 1 : affected.sort - 1;
|
||||
}
|
||||
this.normalizeSort();
|
||||
},
|
||||
normalizeSort() {
|
||||
let rightSort = this.sortedPoints.every((val, index) => val.sort == index);
|
||||
if (!rightSort) {
|
||||
this.inspectionPoints.forEach((e, index) => {
|
||||
e.sort = this.sortedPoints.findIndex((sp) => sp.id == e.id);
|
||||
});
|
||||
}
|
||||
},
|
||||
triggerUpdate(e: any) {
|
||||
if (this.inspectionPlan == null) return;
|
||||
let formData = e.target.elements;
|
||||
let updateInspectionPlan: UpdateInspectionPlanViewModel = {
|
||||
id: this.inspectionPlan.id,
|
||||
title: formData.name.value,
|
||||
inspectionInterval: formData.interval.value,
|
||||
remindTime: formData.remind.value,
|
||||
};
|
||||
this.status = "loading";
|
||||
this.updateActiveInspectionPlan(updateInspectionPlan)
|
||||
.then((res) => {
|
||||
this.fetchItem();
|
||||
this.status = { status: "success" };
|
||||
})
|
||||
.catch((err) => {
|
||||
this.status = { status: "failed" };
|
||||
})
|
||||
.finally(() => {
|
||||
this.timeout = setTimeout(() => {
|
||||
this.status = null;
|
||||
}, 2000);
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="flex flex-col w-full h-full gap-2 justify-center px-7">
|
||||
<div class="flex flex-col w-full h-full gap-2 justify-center">
|
||||
<Pagination
|
||||
:items="maintenances"
|
||||
:totalCount="totalCount"
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<div class="flex flex-row gap-4">
|
||||
<RouterLink
|
||||
v-if="can('create', 'unit', 'vehicle')"
|
||||
:to="{ name: 'admin-unit-inspection-plan', params: { type: 'vehicle', relatedId: vehicleId } }"
|
||||
:to="{ name: 'admin-unit-inspection-start', params: { type: 'vehicle', relatedId: vehicleId } }"
|
||||
button
|
||||
primary
|
||||
class="w-fit!"
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<div class="flex flex-row gap-4">
|
||||
<RouterLink
|
||||
v-if="can('create', 'unit', 'wearable')"
|
||||
:to="{ name: 'admin-unit-inspection-plan', params: { type: 'wearable', relatedId: wearableId } }"
|
||||
:to="{ name: 'admin-unit-inspection-start', params: { type: 'wearable', relatedId: wearableId } }"
|
||||
button
|
||||
primary
|
||||
class="w-fit!"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue