update permissions

This commit is contained in:
Julian Krauser 2025-07-23 10:28:37 +02:00
parent 6c1140f7d2
commit 8c4a53bc17
22 changed files with 89 additions and 24 deletions

View file

@ -1,6 +1,7 @@
<template> <template>
<RouterLink <RouterLink
:to="{ name: 'admin-unit-inspection_plan-overview', params: { inspectionPlanId: inspectionPlan.id } }" :to="{ name: 'admin-unit-inspection_plan-overview', params: { inspectionPlanId: inspectionPlan.id } }"
:disabled="!can('create', 'unit', 'inspection_plan')"
class="flex flex-col h-fit w-full border border-primary rounded-md" 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">
@ -15,6 +16,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { defineComponent, type PropType } from "vue"; import { defineComponent, type PropType } from "vue";
import type { InspectionPlanViewModel } from "@/viewmodels/admin/unit/inspection/inspectionPlan.models"; import type { InspectionPlanViewModel } from "@/viewmodels/admin/unit/inspection/inspectionPlan.models";
import { mapState } from "pinia";
import { useAbilityStore } from "@/stores/ability";
</script> </script>
<script lang="ts"> <script lang="ts">
@ -25,5 +28,8 @@ export default defineComponent({
default: {}, default: {},
}, },
}, },
computed: {
...mapState(useAbilityStore, ["can"]),
},
}); });
</script> </script>

View file

@ -84,10 +84,17 @@ button[primary-outline]:not([primary-outline="false"]),
button:disabled, button:disabled,
[button]:disabled, [button]:disabled,
[button].disabled { [button].disabled,
[button][disabled="true"] {
@apply opacity-75 pointer-events-none; @apply opacity-75 pointer-events-none;
} }
a:disabled,
a.disabled,
a[disabled="true"] {
@apply cursor-default pointer-events-none;
}
input:not([type="checkbox"]), input:not([type="checkbox"]),
textarea, textarea,
select { select {

View file

@ -805,7 +805,8 @@ const router = createRouter({
path: "create/:type?/:relatedId?", path: "create/:type?/:relatedId?",
name: "admin-unit-repair-create", name: "admin-unit-repair-create",
component: () => import("@/views/admin/unit/repair/RepairCreate.vue"), component: () => import("@/views/admin/unit/repair/RepairCreate.vue"),
beforeEnter: [], meta: { type: "create", section: "unit", module: "repair" },
beforeEnter: [abilityAndNavUpdate],
props: true, props: true,
}, },
{ {
@ -1061,7 +1062,8 @@ const router = createRouter({
path: "start/:type?/:relatedId?/:inspectionPlanId?", path: "start/:type?/:relatedId?/:inspectionPlanId?",
name: "admin-unit-inspection-start", name: "admin-unit-inspection-start",
component: () => import("@/views/admin/unit/inspection/InspectionStart.vue"), component: () => import("@/views/admin/unit/inspection/InspectionStart.vue"),
beforeEnter: [], meta: { type: "create", section: "unit", module: "inspection_plan" },
beforeEnter: [abilityAndNavUpdate],
props: true, props: true,
}, },
{ {

View file

@ -19,6 +19,7 @@
v-if="!editStatus && !activeDamageReportObj.done" v-if="!editStatus && !activeDamageReportObj.done"
primary primary
class="w-fit! self-end" class="w-fit! self-end"
:disabled="!can('update', 'unit', 'damage_report')"
@click="editStatus = true" @click="editStatus = true"
> >
Status ändern Status ändern

View file

@ -10,6 +10,7 @@
<template #pageRow="{ row }: { row: DamageReportViewModel }"> <template #pageRow="{ row }: { row: DamageReportViewModel }">
<RouterLink <RouterLink
:to="{ name: 'admin-unit-damage_report-overview', params: { damageReportId: row.id } }" :to="{ name: 'admin-unit-damage_report-overview', params: { damageReportId: row.id } }"
:disabled="!can('create', 'unit', 'damage_report')"
class="flex flex-col h-fit w-full border border-primary rounded-md" 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"> <div class="bg-primary p-2 text-white flex flex-row gap-2 items-center">

View file

@ -9,6 +9,7 @@
<template #pageRow="{ row }: { row: InspectionViewModel }"> <template #pageRow="{ row }: { row: InspectionViewModel }">
<RouterLink <RouterLink
:to="{ name: 'admin-unit-inspection-execute', params: { inspectionId: row.id } }" :to="{ name: 'admin-unit-inspection-execute', params: { inspectionId: row.id } }"
:disabled="!can('create', 'unit', 'inspection')"
class="flex flex-col h-fit w-full border border-primary rounded-md" 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"> <div class="bg-primary p-2 text-white flex flex-row gap-2 items-center">
@ -24,8 +25,8 @@
</Pagination> </Pagination>
<div class="flex flex-row gap-4"> <div class="flex flex-row gap-4">
<RouterLink <RouterLink
v-if="can('create', 'unit', 'equipment')"
:to="{ name: 'admin-unit-inspection-start', params: { type: 'equipment', relatedId: equipmentId } }" :to="{ name: 'admin-unit-inspection-start', params: { type: 'equipment', relatedId: equipmentId } }"
:disable="!can('create', 'unit', 'inspection')"
button button
primary primary
class="w-fit!" class="w-fit!"

View file

@ -10,6 +10,7 @@
<template #pageRow="{ row }: { row: RepairViewModel }"> <template #pageRow="{ row }: { row: RepairViewModel }">
<RouterLink <RouterLink
:to="{ name: 'admin-unit-repair-overview', params: { repairId: row.id } }" :to="{ name: 'admin-unit-repair-overview', params: { repairId: row.id } }"
:disabled="!can('create', 'unit', 'repair')"
class="flex flex-col h-fit w-full border border-primary rounded-md" 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"> <div class="bg-primary p-2 text-white flex flex-row gap-2 items-center">
@ -24,6 +25,7 @@
</Pagination> </Pagination>
<RouterLink <RouterLink
:to="{ name: 'admin-unit-repair-create', params: { type: 'equipment', relatedId: equipmentId } }" :to="{ name: 'admin-unit-repair-create', params: { type: 'equipment', relatedId: equipmentId } }"
:disabled="!can('create', 'unit', 'repair')"
button button
primary primary
class="w-fit!" class="w-fit!"

View file

@ -8,8 +8,8 @@
</div> </div>
<div class="flex flex-row gap-4"> <div class="flex flex-row gap-4">
<RouterLink <RouterLink
v-if="can('create', 'unit', 'equipment_type')"
:to="{ name: 'admin-unit-inspection_plan-create', query: { type: 'equipment', id: equipmentTypeId } }" :to="{ name: 'admin-unit-inspection_plan-create', query: { type: 'equipment', id: equipmentTypeId } }"
:disabled="!can('create', 'unit', 'inspection_plan')"
button button
primary primary
class="w-fit!" class="w-fit!"

View file

@ -31,35 +31,38 @@
<OkNotOk <OkNotOk
v-if="point.type == InspectionPointEnum.oknok" v-if="point.type == InspectionPointEnum.oknok"
:inspectionPoint="point" :inspectionPoint="point"
:editable="activeInspectionObj.isOpen" :editable="activeInspectionObj.isOpen && can('update', 'unit', 'inspection')"
:modelValue="boolPointResult(point.id)" :modelValue="boolPointResult(point.id)"
@update:model-value="(val) => updateCheckResult(point.id, val)" @update:model-value="(val) => updateCheckResult(point.id, val)"
/> />
<NumberInput <NumberInput
v-else-if="point.type == InspectionPointEnum.number" v-else-if="point.type == InspectionPointEnum.number"
:inspectionPoint="point" :inspectionPoint="point"
:editable="activeInspectionObj.isOpen" :editable="activeInspectionObj.isOpen && can('update', 'unit', 'inspection')"
:modelValue="pointResult(point.id)" :modelValue="pointResult(point.id)"
@update:model-value="(val) => updateCheckResult(point.id, val)" @update:model-value="(val) => updateCheckResult(point.id, val)"
/> />
<TextInput <TextInput
v-else-if="point.type == InspectionPointEnum.text" v-else-if="point.type == InspectionPointEnum.text"
:inspectionPoint="point" :inspectionPoint="point"
:editable="activeInspectionObj.isOpen" :editable="activeInspectionObj.isOpen && can('update', 'unit', 'inspection')"
:modelValue="pointResult(point.id)" :modelValue="pointResult(point.id)"
@update:model-value="(val) => updateCheckResult(point.id, val)" @update:model-value="(val) => updateCheckResult(point.id, val)"
/> />
<FileInput <FileInput
v-else-if="point.type == InspectionPointEnum.file" v-else-if="point.type == InspectionPointEnum.file"
:inspectionPoint="point" :inspectionPoint="point"
:editable="activeInspectionObj.isOpen" :editable="activeInspectionObj.isOpen && can('update', 'unit', 'inspection')"
:modelValue="pointResult(point.id)" :modelValue="pointResult(point.id)"
@update:model-value="(val) => updateCheckResult(point.id, val)" @update:model-value="(val) => updateCheckResult(point.id, val)"
@update:upload="(val) => (fileStore[point.id] = val)" @update:upload="(val) => (fileStore[point.id] = val)"
/> />
</div> </div>
</div> </div>
<div v-if="activeInspectionObj.isOpen" class="flex flex-row justify-end flex-wrap min-h-fit gap-2"> <div
v-if="activeInspectionObj.isOpen && can('update', 'unit', 'inspection')"
class="flex flex-row justify-end flex-wrap min-h-fit gap-2"
>
<button primary-outline type="reset" class="w-fit!" :disabled="canSaveOrReset" @click="resetForm"> <button primary-outline type="reset" class="w-fit!" :disabled="canSaveOrReset" @click="resetForm">
verwerfen verwerfen
</button> </button>
@ -85,7 +88,7 @@
<SuccessCheckmark v-else-if="status?.status == 'success'" /> <SuccessCheckmark v-else-if="status?.status == 'success'" />
<FailureXMark v-else-if="status?.status == 'failed'" /> <FailureXMark v-else-if="status?.status == 'failed'" />
</div> </div>
<div v-else> <div v-else-if="!activeInspectionObj.isOpen">
<button primary type="button" @click="openPrintModal">Bericht anzeigen</button> <button primary type="button" @click="openPrintModal">Bericht anzeigen</button>
</div> </div>
</div> </div>

View file

@ -18,8 +18,8 @@
<div class="flex flex-row gap-4"> <div class="flex flex-row gap-4">
<RouterLink <RouterLink
v-if="can('create', 'unit', 'inspection_plan')"
:to="{ name: 'admin-unit-inspection_plan-create' }" :to="{ name: 'admin-unit-inspection_plan-create' }"
:disabled="!can('create', 'unit', 'inspection_plan')"
primary primary
button button
class="w-fit!" class="w-fit!"

View file

@ -5,7 +5,7 @@
:related="activeRepairObj.assigned" :related="activeRepairObj.assigned"
:relatedId="activeRepairObj.relatedId" :relatedId="activeRepairObj.relatedId"
:model-value="activeRepairObj.reports.map((r) => r.id)" :model-value="activeRepairObj.reports.map((r) => r.id)"
:disabled="!!activeRepairObj.finishedAt" :disabled="!!activeRepairObj.finishedAt || !can('update', 'unit', 'repair')"
@add:damage-report="handleReportAdd" @add:damage-report="handleReportAdd"
@remove:difference="handleReportRemove" @remove:difference="handleReportRemove"
/> />
@ -28,7 +28,12 @@
</div> </div>
</div> </div>
</div> </div>
<button primary class="w-fit! self-end" :disabled="!!activeRepairObj.finishedAt" @click="saveReports"> <button
primary
class="w-fit! self-end"
:disabled="!!activeRepairObj.finishedAt || !can('update', 'unit', 'repair')"
@click="saveReports"
>
Änderungen speichern Änderungen speichern
</button> </button>
</div> </div>

View file

@ -6,6 +6,7 @@
</div> </div>
<button <button
v-if="!editStatus && !activeRepairObj.finishedAt" v-if="!editStatus && !activeRepairObj.finishedAt"
:disabled="!can('update', 'unit', 'repair')"
primary primary
class="w-fit! self-end" class="w-fit! self-end"
@click="editStatus = true" @click="editStatus = true"
@ -20,17 +21,39 @@
<form class="flex flex-col gap-2" @submit.prevent="saveData"> <form class="flex flex-col gap-2" @submit.prevent="saveData">
<div> <div>
<label for="title">Kurzbeschreibung</label> <label for="title">Kurzbeschreibung</label>
<input id="title" type="text" placeholder="---" :value="activeRepairObj.title" /> <input
id="title"
type="text"
placeholder="---"
:value="activeRepairObj.title"
:disabled="!!activeRepairObj.finishedAt || !can('update', 'unit', 'repair')"
/>
</div> </div>
<div> <div>
<label for="description">Beschreibung der Reparatur</label> <label for="description">Beschreibung der Reparatur</label>
<textarea id="description" placeholder="---" :value="activeRepairObj.description"></textarea> <textarea
id="description"
placeholder="---"
:value="activeRepairObj.description"
:disabled="!!activeRepairObj.finishedAt || !can('update', 'unit', 'repair')"
></textarea>
</div> </div>
<div> <div>
<label for="responsible">Verantwortlich</label> <label for="responsible">Verantwortlich</label>
<input id="responsible" type="text" placeholder="---" :value="activeRepairObj.responsible" /> <input
id="responsible"
type="text"
placeholder="---"
:value="activeRepairObj.responsible"
:disabled="!!activeRepairObj.finishedAt || !can('update', 'unit', 'repair')"
/>
</div> </div>
<button primary type="submit" class="w-fit! self-end" :disabled="!!activeRepairObj.finishedAt"> <button
primary
type="submit"
class="w-fit! self-end"
:disabled="!!activeRepairObj.finishedAt || !can('update', 'unit', 'repair')"
>
Änderungen speichern Änderungen speichern
</button> </button>
</form> </form>

View file

@ -21,7 +21,13 @@
</RouterLink> </RouterLink>
</div> </div>
<RouterView /> <RouterView />
<RouterLink :to="{ name: 'admin-unit-repair-create' }" button primary class="w-fit!"> <RouterLink
:to="{ name: 'admin-unit-repair-create' }"
button
primary
class="w-fit!"
:disabled="!can('create', 'unit', 'repair')"
>
Reparatur erstellen Reparatur erstellen
</RouterLink> </RouterLink>
</div> </div>

View file

@ -10,6 +10,7 @@
<template #pageRow="{ row }: { row: DamageReportViewModel }"> <template #pageRow="{ row }: { row: DamageReportViewModel }">
<RouterLink <RouterLink
:to="{ name: 'admin-unit-damage_report-overview', params: { damageReportId: row.id } }" :to="{ name: 'admin-unit-damage_report-overview', params: { damageReportId: row.id } }"
:disabled="!can('read', 'unit', 'damage_report')"
class="flex flex-col h-fit w-full border border-primary rounded-md" 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"> <div class="bg-primary p-2 text-white flex flex-row gap-2 items-center">

View file

@ -10,6 +10,7 @@
<template #pageRow="{ row }: { row: InspectionViewModel }"> <template #pageRow="{ row }: { row: InspectionViewModel }">
<RouterLink <RouterLink
:to="{ name: 'admin-unit-inspection-execute', params: { inspectionId: row.id } }" :to="{ name: 'admin-unit-inspection-execute', params: { inspectionId: row.id } }"
:disabled="!can('read', 'unit', 'inspection')"
class="flex flex-col h-fit w-full border border-primary rounded-md" 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"> <div class="bg-primary p-2 text-white flex flex-row gap-2 items-center">
@ -25,8 +26,8 @@
</Pagination> </Pagination>
<div class="flex flex-row gap-4"> <div class="flex flex-row gap-4">
<RouterLink <RouterLink
v-if="can('create', 'unit', 'vehicle')"
:to="{ name: 'admin-unit-inspection-start', params: { type: 'vehicle', relatedId: vehicleId } }" :to="{ name: 'admin-unit-inspection-start', params: { type: 'vehicle', relatedId: vehicleId } }"
:disabled="!can('read', 'unit', 'damage_report')"
button button
primary primary
class="w-fit!" class="w-fit!"

View file

@ -10,6 +10,7 @@
<template #pageRow="{ row }: { row: RepairViewModel }"> <template #pageRow="{ row }: { row: RepairViewModel }">
<RouterLink <RouterLink
:to="{ name: 'admin-unit-repair-overview', params: { repairId: row.id } }" :to="{ name: 'admin-unit-repair-overview', params: { repairId: row.id } }"
:disabled="!can('read', 'unit', 'repair')"
class="flex flex-col h-fit w-full border border-primary rounded-md" 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"> <div class="bg-primary p-2 text-white flex flex-row gap-2 items-center">
@ -24,6 +25,7 @@
</Pagination> </Pagination>
<RouterLink <RouterLink
:to="{ name: 'admin-unit-repair-create', params: { type: 'vehicle', relatedId: vehicleId } }" :to="{ name: 'admin-unit-repair-create', params: { type: 'vehicle', relatedId: vehicleId } }"
:disabled="!can('read', 'unit', 'repair')"
button button
primary primary
class="w-fit!" class="w-fit!"

View file

@ -18,7 +18,7 @@
<div class="flex flex-row gap-4"> <div class="flex flex-row gap-4">
<RouterLink <RouterLink
v-if="can('create', 'unit', 'equipment')" v-if="can('create', 'unit', 'vehicle')"
:to="{ name: 'admin-unit-vehicle-create' }" :to="{ name: 'admin-unit-vehicle-create' }"
primary primary
button button

View file

@ -9,8 +9,8 @@
<div class="flex flex-row gap-4"> <div class="flex flex-row gap-4">
<RouterLink <RouterLink
v-if="can('create', 'unit', 'vehicle_type')"
:to="{ name: 'admin-unit-inspection_plan-create', query: { type: 'vehicle', id: vehicleTypeId } }" :to="{ name: 'admin-unit-inspection_plan-create', query: { type: 'vehicle', id: vehicleTypeId } }"
:disabled="!can('read', 'unit', 'inspection_plan')"
button button
primary primary
class="w-fit!" class="w-fit!"

View file

@ -10,6 +10,7 @@
<template #pageRow="{ row }: { row: DamageReportViewModel }"> <template #pageRow="{ row }: { row: DamageReportViewModel }">
<RouterLink <RouterLink
:to="{ name: 'admin-unit-damage_report-overview', params: { damageReportId: row.id } }" :to="{ name: 'admin-unit-damage_report-overview', params: { damageReportId: row.id } }"
:disabled="!can('read', 'unit', 'damage_report')"
class="flex flex-col h-fit w-full border border-primary rounded-md" 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"> <div class="bg-primary p-2 text-white flex flex-row gap-2 items-center">

View file

@ -10,6 +10,7 @@
<template #pageRow="{ row }: { row: InspectionViewModel }"> <template #pageRow="{ row }: { row: InspectionViewModel }">
<RouterLink <RouterLink
:to="{ name: 'admin-unit-inspection-execute', params: { inspectionId: row.id } }" :to="{ name: 'admin-unit-inspection-execute', params: { inspectionId: row.id } }"
:disabled="!can('read', 'unit', 'inspection')"
class="flex flex-col h-fit w-full border border-primary rounded-md" 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"> <div class="bg-primary p-2 text-white flex flex-row gap-2 items-center">
@ -25,8 +26,8 @@
</Pagination> </Pagination>
<div class="flex flex-row gap-4"> <div class="flex flex-row gap-4">
<RouterLink <RouterLink
v-if="can('create', 'unit', 'wearable')"
:to="{ name: 'admin-unit-inspection-start', params: { type: 'wearable', relatedId: wearableId } }" :to="{ name: 'admin-unit-inspection-start', params: { type: 'wearable', relatedId: wearableId } }"
:disabled="!can('create', 'unit', 'inspection')"
button button
primary primary
class="w-fit!" class="w-fit!"

View file

@ -10,6 +10,7 @@
<template #pageRow="{ row }: { row: RepairViewModel }"> <template #pageRow="{ row }: { row: RepairViewModel }">
<RouterLink <RouterLink
:to="{ name: 'admin-unit-repair-overview', params: { repairId: row.id } }" :to="{ name: 'admin-unit-repair-overview', params: { repairId: row.id } }"
:disabled="!can('read', 'unit', 'repair')"
class="flex flex-col h-fit w-full border border-primary rounded-md" 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"> <div class="bg-primary p-2 text-white flex flex-row gap-2 items-center">
@ -24,6 +25,7 @@
</Pagination> </Pagination>
<RouterLink <RouterLink
:to="{ name: 'admin-unit-repair-create', params: { type: 'wearable', relatedId: wearableId } }" :to="{ name: 'admin-unit-repair-create', params: { type: 'wearable', relatedId: wearableId } }"
:disabled="!can('read', 'unit', 'repair')"
button button
primary primary
class="w-fit!" class="w-fit!"

View file

@ -9,8 +9,8 @@
<div class="flex flex-row gap-4"> <div class="flex flex-row gap-4">
<RouterLink <RouterLink
v-if="can('create', 'unit', 'vehicle_type')"
:to="{ name: 'admin-unit-inspection_plan-create', query: { type: 'vehicle', id: vehicleTypeId } }" :to="{ name: 'admin-unit-inspection_plan-create', query: { type: 'vehicle', id: vehicleTypeId } }"
:disabled="!can('read', 'unit', 'inspection_plan')"
button button
primary primary
class="w-fit!" class="w-fit!"