diff --git a/package-lock.json b/package-lock.json
index 0e154ef..1d82798 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "ff-admin",
- "version": "1.7.5",
+ "version": "1.8.0-beta1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ff-admin",
- "version": "1.7.5",
+ "version": "1.8.0-beta1",
"license": "AGPL-3.0-only",
"dependencies": {
"@fullcalendar/core": "^6.1.18",
@@ -43,6 +43,7 @@
"unplugin-vue-markdown": "^29.1.0",
"uuid": "^11.1.0",
"vue": "^3.5.18",
+ "vue-qrcode-reader": "^5.7.1",
"vue-router": "^4.5.1"
},
"devDependencies": {
@@ -3792,6 +3793,18 @@
"@types/underscore": "*"
}
},
+ "node_modules/@types/dom-webcodecs": {
+ "version": "0.1.14",
+ "resolved": "https://registry.npmjs.org/@types/dom-webcodecs/-/dom-webcodecs-0.1.14.tgz",
+ "integrity": "sha512-ba9aF0qARLLQpLihONIRbj8VvAdUxO+5jIxlscVcDAQTcJmq5qVr781+ino5qbQUJUmO21cLP2eLeXYWzao5Vg==",
+ "license": "MIT"
+ },
+ "node_modules/@types/emscripten": {
+ "version": "1.40.1",
+ "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.40.1.tgz",
+ "integrity": "sha512-sr53lnYkQNhjHNN0oJDdUm5564biioI5DuOpycufDVK7D3y+GR3oUswe2rlwY1nPNyusHbrJ9WoTyIHl4/Bpwg==",
+ "license": "MIT"
+ },
"node_modules/@types/eslint": {
"version": "9.6.1",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
@@ -4912,6 +4925,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/barcode-detector": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/barcode-detector/-/barcode-detector-2.2.2.tgz",
+ "integrity": "sha512-JcSekql+EV93evfzF9zBr+Y6aRfkR+QFvgyzbwQ0dbymZXoAI9+WgT7H1E429f+3RKNncHz2CW98VQtaaKpmfQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/dom-webcodecs": "^0.1.11",
+ "zxing-wasm": "1.1.3"
+ }
+ },
"node_modules/birpc": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/birpc/-/birpc-2.3.0.tgz",
@@ -9443,6 +9466,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/sdp": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/sdp/-/sdp-3.2.0.tgz",
+ "integrity": "sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw==",
+ "license": "MIT"
+ },
"node_modules/section-matter": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
@@ -11009,6 +11038,19 @@
"url": "https://opencollective.com/eslint"
}
},
+ "node_modules/vue-qrcode-reader": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/vue-qrcode-reader/-/vue-qrcode-reader-5.7.2.tgz",
+ "integrity": "sha512-MRwo8IWM+1UzvfRhOQQBqEap06nl0E8QFIb+/HxS1KiH8BqL2qhlzMVvJgMUti4m5x+XH2YlGS0v1Qshpg+Hbw==",
+ "license": "MIT",
+ "dependencies": {
+ "barcode-detector": "2.2.2",
+ "webrtc-adapter": "8.2.3"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
"node_modules/vue-router": {
"version": "4.5.1",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz",
@@ -11060,6 +11102,19 @@
"integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
"license": "MIT"
},
+ "node_modules/webrtc-adapter": {
+ "version": "8.2.3",
+ "resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-8.2.3.tgz",
+ "integrity": "sha512-gnmRz++suzmvxtp3ehQts6s2JtAGPuDPjA1F3a9ckNpG1kYdYuHWYpazoAnL9FS5/B21tKlhkorbdCXat0+4xQ==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "sdp": "^3.2.0"
+ },
+ "engines": {
+ "node": ">=6.0.0",
+ "npm": ">=3.10.0"
+ }
+ },
"node_modules/whatwg-url": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
@@ -11752,6 +11807,15 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
+ },
+ "node_modules/zxing-wasm": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/zxing-wasm/-/zxing-wasm-1.1.3.tgz",
+ "integrity": "sha512-MYm9k/5YVs4ZOTIFwlRjfFKD0crhefgbnt1+6TEpmKUDFp3E2uwqGSKwQOd2hOIsta/7Usq4hnpNRYTLoljnfA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/emscripten": "^1.39.10"
+ }
}
}
}
diff --git a/package.json b/package.json
index 4403864..0bd5c3f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "ff-admin",
- "version": "1.7.5",
+ "version": "1.8.0-beta1",
"description": "Feuerwehr/Verein Mitgliederverwaltung UI",
"type": "module",
"scripts": {
@@ -58,6 +58,7 @@
"unplugin-vue-markdown": "^29.1.0",
"uuid": "^11.1.0",
"vue": "^3.5.18",
+ "vue-qrcode-reader": "^5.7.1",
"vue-router": "^4.5.1"
},
"devDependencies": {
diff --git a/src/components/CopyPasteContextMenu.vue b/src/components/CopyPasteContextMenu.vue
index 80dd642..599c0af 100644
--- a/src/components/CopyPasteContextMenu.vue
+++ b/src/components/CopyPasteContextMenu.vue
@@ -36,12 +36,9 @@ export default defineComponent({
document.getSelection()?.toString() || this.clickedOnEl.value || this.clickedOnEl.innerText || "";
let selection = document.getSelection()?.toString();
- console.log(selection);
if (selection == "") {
- console.log("jo");
const range = document.createRange();
range.selectNode(this.clickedOnEl);
- console.log(range);
window.getSelection()?.removeAllRanges();
window.getSelection()?.addRange(range);
}
diff --git a/src/components/Modal.vue b/src/components/Modal.vue
index 1a9039e..3fc79d6 100644
--- a/src/components/Modal.vue
+++ b/src/components/Modal.vue
@@ -4,24 +4,27 @@
class="absolute inset-0 w-full h-full flex justify-center items-center bg-black/50 select-none z-50 p-2"
v-show="show"
>
-
+
diff --git a/src/components/Notification.vue b/src/components/Notification.vue
index e320e19..d302eef 100644
--- a/src/components/Notification.vue
+++ b/src/components/Notification.vue
@@ -20,6 +20,7 @@
notification.type == 'error' ? 'border border-red-400' : '',
notification.type == 'warning' ? 'border border-red-400' : '',
notification.type == 'info' ? 'border border-gray-400' : '',
+ notification.type == 'success' ? 'border border-green-400' : '',
]"
>
diff --git a/src/components/TextCopy.vue b/src/components/TextCopy.vue
index 6c13613..7a23ec3 100644
--- a/src/components/TextCopy.vue
+++ b/src/components/TextCopy.vue
@@ -1,5 +1,5 @@
-
+
+
+
+
+
+
Schaden melden Link anzeigen
@@ -60,6 +76,10 @@ export default defineComponent({
key: "app.show_link_to_calendar",
value: formData.show_link_to_calendar.checked,
},
+ {
+ key: "app.show_link_to_damagereport",
+ value: formData.show_link_to_damagereport.checked,
+ },
]);
},
},
diff --git a/src/components/admin/unit/InspectionTimeFormatExplainIcon.vue b/src/components/admin/unit/InspectionTimeFormatExplainIcon.vue
new file mode 100644
index 0000000..9f27541
--- /dev/null
+++ b/src/components/admin/unit/InspectionTimeFormatExplainIcon.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/InspectionTimeFormatExplainModal.vue b/src/components/admin/unit/InspectionTimeFormatExplainModal.vue
new file mode 100644
index 0000000..d0719c2
--- /dev/null
+++ b/src/components/admin/unit/InspectionTimeFormatExplainModal.vue
@@ -0,0 +1,55 @@
+
+
+
+
+
Zeit Format für Erinnerung und Intervall
+
+
+
+
+
+ <zahl>-(d|m|y)
+
+ Ein Intervall, z.B. 7-d für alle 7 Tage,
+ 1-m für jeden Monat.
+
+
+
+ DD/MM
+
+ Ein bestimmtes Datum, z.B. 15/06 für den 15. Juni.
+
+
+
+ DD/*
+
+ Ein Tag jeden Monats, z.B. 01/* für den ersten Tag jedes Monats.
+
+
+
+
+
Im Fall von Erinnerungen wird das Format als zeitliche Angabe vor einem Datum verwendet.
+
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/damageReport/DamageReportListItem.vue b/src/components/admin/unit/damageReport/DamageReportListItem.vue
new file mode 100644
index 0000000..574c584
--- /dev/null
+++ b/src/components/admin/unit/damageReport/DamageReportListItem.vue
@@ -0,0 +1,52 @@
+
+
+
+
+ {{ damageReport.title }} -
+ {{ damageReport?.related?.name ?? "Ohne Zuordnung" }}
+ ({{ damageReport.related.code }})
+
+
+
+
+
gemeldet: {{ new Date(damageReport.reportedAt).toLocaleString("de") }}
+
Status: {{ damageReport.status }}
+
Beschreibung: {{ damageReport.description }}
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/equipment/EquipmentListItem.vue b/src/components/admin/unit/equipment/EquipmentListItem.vue
new file mode 100644
index 0000000..dc9d7f3
--- /dev/null
+++ b/src/components/admin/unit/equipment/EquipmentListItem.vue
@@ -0,0 +1,33 @@
+
+
+
+
+ {{ equipment.name }}
+
+
+
+
Code: {{ equipment.code }}
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/equipmentType/CreateEquipmentTypeModal.vue b/src/components/admin/unit/equipmentType/CreateEquipmentTypeModal.vue
new file mode 100644
index 0000000..e0f50b5
--- /dev/null
+++ b/src/components/admin/unit/equipmentType/CreateEquipmentTypeModal.vue
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/equipmentType/DeleteEquipmentTypeModal.vue b/src/components/admin/unit/equipmentType/DeleteEquipmentTypeModal.vue
new file mode 100644
index 0000000..355117d
--- /dev/null
+++ b/src/components/admin/unit/equipmentType/DeleteEquipmentTypeModal.vue
@@ -0,0 +1,84 @@
+
+
+
+
Ausrüstung-Type löschen
+
+
+
Type {{ equipmentType?.type }} löschen?
+
+
+
+
+ löschen
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/equipmentType/EquipmentTypeListItem.vue b/src/components/admin/unit/equipmentType/EquipmentTypeListItem.vue
new file mode 100644
index 0000000..91e8e9b
--- /dev/null
+++ b/src/components/admin/unit/equipmentType/EquipmentTypeListItem.vue
@@ -0,0 +1,40 @@
+
+
+
+
+ {{ equipmentType.type }}
+
+
+
+
+
Anzahl angelegter Geräte:
+
{{ equipmentType.equipmentCount }}
+
+
+
Beschreibung:
+
{{ equipmentType.description }}
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/inspection/DeleteInspectionModal.vue b/src/components/admin/unit/inspection/DeleteInspectionModal.vue
new file mode 100644
index 0000000..334080c
--- /dev/null
+++ b/src/components/admin/unit/inspection/DeleteInspectionModal.vue
@@ -0,0 +1,85 @@
+
+
+
+
angefangene Prüfung löschen
+
+
+
+ {{ activeInspectionObj?.inspectionPlan.title }} zu {{ activeInspectionObj?.related.name }}
+ ({{ activeInspectionObj?.related.code }}) begonnen am
+ {{ new Date(activeInspectionObj?.created ?? "").toLocaleDateString("de-de") }} löschen?
+
+
+
+
+
+ löschen
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/inspection/FileInput.vue b/src/components/admin/unit/inspection/FileInput.vue
new file mode 100644
index 0000000..de9d27f
--- /dev/null
+++ b/src/components/admin/unit/inspection/FileInput.vue
@@ -0,0 +1,91 @@
+
+
+
+
{{ inspectionPoint.title }}
+
+
+
+
Beschreibung: {{ inspectionPoint.description }}
+
+
{{ inspectionPoint.others == "pdf" ? "PDF" : "Bild" }}-Datei
+
+ Datei wählen Datei gewählt
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/inspection/InspectionFinishModal.vue b/src/components/admin/unit/inspection/InspectionFinishModal.vue
new file mode 100644
index 0000000..b2628e1
--- /dev/null
+++ b/src/components/admin/unit/inspection/InspectionFinishModal.vue
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+ Nach abschluss der Prüfung können keine Änderung mehr an
+ dieser vorgenommen werden.
+ Es wird ein PDF ausgedruckt und ist dann zu dieser Prüfung verfügbar.
+
+
+
+
+ Prüfung abschließen
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/inspection/InspectionPrintModal.vue b/src/components/admin/unit/inspection/InspectionPrintModal.vue
new file mode 100644
index 0000000..734ed64
--- /dev/null
+++ b/src/components/admin/unit/inspection/InspectionPrintModal.vue
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/inspection/NumberInput.vue b/src/components/admin/unit/inspection/NumberInput.vue
new file mode 100644
index 0000000..b93b720
--- /dev/null
+++ b/src/components/admin/unit/inspection/NumberInput.vue
@@ -0,0 +1,80 @@
+
+
+
+
{{ inspectionPoint.title }}
+
+
+
Beschreibung: {{ inspectionPoint.description }}
+
+
+ Zahl {{ restrictedRange }}
+
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/inspection/OkNotOk.vue b/src/components/admin/unit/inspection/OkNotOk.vue
new file mode 100644
index 0000000..177ed92
--- /dev/null
+++ b/src/components/admin/unit/inspection/OkNotOk.vue
@@ -0,0 +1,71 @@
+
+
+
+
{{ inspectionPoint.title }}
+
+
+
Beschreibung: {{ inspectionPoint.description }}
+
+
+
+ {{ option.title }}
+
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/inspection/TextInput.vue b/src/components/admin/unit/inspection/TextInput.vue
new file mode 100644
index 0000000..664c3d4
--- /dev/null
+++ b/src/components/admin/unit/inspection/TextInput.vue
@@ -0,0 +1,55 @@
+
+
+
+
{{ inspectionPoint.title }}
+
+
+
Beschreibung: {{ inspectionPoint.description }}
+
+
Freitext
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/inspection/UploadedFileViewModal.vue b/src/components/admin/unit/inspection/UploadedFileViewModal.vue
new file mode 100644
index 0000000..d9f1487
--- /dev/null
+++ b/src/components/admin/unit/inspection/UploadedFileViewModal.vue
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/inspectionPlan/InspectionPlanListItem.vue b/src/components/admin/unit/inspectionPlan/InspectionPlanListItem.vue
new file mode 100644
index 0000000..7d99320
--- /dev/null
+++ b/src/components/admin/unit/inspectionPlan/InspectionPlanListItem.vue
@@ -0,0 +1,37 @@
+
+
+
+
{{ inspectionPlan.title }} - {{ inspectionPlan.related.type }}
+
+
+
Prüfinterval: {{ inspectionPlan.inspectionInterval }}
+
Erinnerung: {{ inspectionPlan.remindTime }}
+
+
+
Prüfplan noch nicht fertig gestellt. Es fehlen Prüfpunkte!
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/inspectionPlan/InspectionPointListItem.vue b/src/components/admin/unit/inspectionPlan/InspectionPointListItem.vue
new file mode 100644
index 0000000..46a359d
--- /dev/null
+++ b/src/components/admin/unit/inspectionPlan/InspectionPointListItem.vue
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mindestens
+
+
+
+ Maximal
+
+
+
+
Dateiart
+
+
+ Bild
+
+
+ PDF
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/inspectionPlan/TypeInspectionPlanListItem.vue b/src/components/admin/unit/inspectionPlan/TypeInspectionPlanListItem.vue
new file mode 100644
index 0000000..73394c8
--- /dev/null
+++ b/src/components/admin/unit/inspectionPlan/TypeInspectionPlanListItem.vue
@@ -0,0 +1,35 @@
+
+
+
+
{{ inspectionPlan.title }}
+
+
+
Interval: {{ inspectionPlan.inspectionInterval }}
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/maintenance/MaintenanceListItem.vue b/src/components/admin/unit/maintenance/MaintenanceListItem.vue
new file mode 100644
index 0000000..a838973
--- /dev/null
+++ b/src/components/admin/unit/maintenance/MaintenanceListItem.vue
@@ -0,0 +1,31 @@
+
+
+
+
+ {{ damageReport.related.name }}
+
+
+
+
Code: {{ damageReport.related.code }}
+
Beschreibung: {{ damageReport.description }}
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/repair/RepairListItem.vue b/src/components/admin/unit/repair/RepairListItem.vue
new file mode 100644
index 0000000..69986ee
--- /dev/null
+++ b/src/components/admin/unit/repair/RepairListItem.vue
@@ -0,0 +1,39 @@
+
+
+
+
+ {{ repair.title }} -
+ {{ repair?.related?.name ?? "Ohne Zuordnung" }}
+ ({{ repair.related.code }})
+
+
+
+
begonnen: {{ new Date(repair.createdAt).toLocaleString("de") }}
+
Status: {{ repair.status }}
+
Verantwortlich: {{ repair.responsible }}
+
Beschreibung: {{ repair.description }}
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/respiratoryGear/CreateRespiratoryGearModal.vue b/src/components/admin/unit/respiratoryGear/CreateRespiratoryGearModal.vue
new file mode 100644
index 0000000..c5ece71
--- /dev/null
+++ b/src/components/admin/unit/respiratoryGear/CreateRespiratoryGearModal.vue
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/respiratoryGear/RespiratoryGearListItem.vue b/src/components/admin/unit/respiratoryGear/RespiratoryGearListItem.vue
new file mode 100644
index 0000000..7b55acf
--- /dev/null
+++ b/src/components/admin/unit/respiratoryGear/RespiratoryGearListItem.vue
@@ -0,0 +1,33 @@
+
+
+
+
+ {{ respiratoryGear.equipment.name }}
+
+
+
+
Code: {{ respiratoryGear.equipment.code }}
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/respiratoryMission/CreateRespiratoryMissionModal.vue b/src/components/admin/unit/respiratoryMission/CreateRespiratoryMissionModal.vue
new file mode 100644
index 0000000..c5ece71
--- /dev/null
+++ b/src/components/admin/unit/respiratoryMission/CreateRespiratoryMissionModal.vue
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/respiratoryMission/RespiratoryMissionListItem.vue b/src/components/admin/unit/respiratoryMission/RespiratoryMissionListItem.vue
new file mode 100644
index 0000000..913b132
--- /dev/null
+++ b/src/components/admin/unit/respiratoryMission/RespiratoryMissionListItem.vue
@@ -0,0 +1,31 @@
+
+
+
+
{{ respiratoryMission.title }} - {{ respiratoryMission.date }}
+
+
+
{{ respiratoryMission.description }}
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/respiratoryWearer/CreateRespiratoryWearerModal.vue b/src/components/admin/unit/respiratoryWearer/CreateRespiratoryWearerModal.vue
new file mode 100644
index 0000000..c5ece71
--- /dev/null
+++ b/src/components/admin/unit/respiratoryWearer/CreateRespiratoryWearerModal.vue
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/respiratoryWearer/RespiratoryWearerListItem.vue b/src/components/admin/unit/respiratoryWearer/RespiratoryWearerListItem.vue
new file mode 100644
index 0000000..291237e
--- /dev/null
+++ b/src/components/admin/unit/respiratoryWearer/RespiratoryWearerListItem.vue
@@ -0,0 +1,34 @@
+
+
+
+
+ {{ respiratoryWearer.member.lastname }}, {{ respiratoryWearer.member.firstname }}
+ {{ respiratoryWearer.member.nameaffix ? `- ${respiratoryWearer.member.nameaffix}` : "" }}
+
+
+
+
ID: {{ respiratoryWearer.member.internalId }}
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/vehicle/VehicleListItem.vue b/src/components/admin/unit/vehicle/VehicleListItem.vue
new file mode 100644
index 0000000..c4a9254
--- /dev/null
+++ b/src/components/admin/unit/vehicle/VehicleListItem.vue
@@ -0,0 +1,31 @@
+
+
+
+
+
Code: {{ vehicle.code }}
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/vehicleType/CreateVehicleTypeModal.vue b/src/components/admin/unit/vehicleType/CreateVehicleTypeModal.vue
new file mode 100644
index 0000000..b7a570e
--- /dev/null
+++ b/src/components/admin/unit/vehicleType/CreateVehicleTypeModal.vue
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+ Typ
+
+
+
+ Beschreibung (optional)
+
+
+
+
+ erstellen
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/vehicleType/DeleteVehicleTypeModal.vue b/src/components/admin/unit/vehicleType/DeleteVehicleTypeModal.vue
new file mode 100644
index 0000000..25217eb
--- /dev/null
+++ b/src/components/admin/unit/vehicleType/DeleteVehicleTypeModal.vue
@@ -0,0 +1,83 @@
+
+
+
+
Ausrüstung-Type löschen
+
+
+
Type {{ vehicleType?.type }} löschen?
+
+
+
+
+ löschen
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/vehicleType/VehicleTypeListItem.vue b/src/components/admin/unit/vehicleType/VehicleTypeListItem.vue
new file mode 100644
index 0000000..c3658b8
--- /dev/null
+++ b/src/components/admin/unit/vehicleType/VehicleTypeListItem.vue
@@ -0,0 +1,40 @@
+
+
+
+
+ {{ vehicleType.type }}
+
+
+
+
+
Anzahl angelegter Fahrzeuge:
+
{{ vehicleType.vehicleCount }}
+
+
+
Beschreibung:
+
{{ vehicleType.description }}
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/wearable/WearableListItem.vue b/src/components/admin/unit/wearable/WearableListItem.vue
new file mode 100644
index 0000000..6358323
--- /dev/null
+++ b/src/components/admin/unit/wearable/WearableListItem.vue
@@ -0,0 +1,33 @@
+
+
+
+
+ {{ wearable.name }}
+
+
+
+
Code: {{ wearable.code }}
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/wearableType/CreateWearableTypeModal.vue b/src/components/admin/unit/wearableType/CreateWearableTypeModal.vue
new file mode 100644
index 0000000..b7df9d0
--- /dev/null
+++ b/src/components/admin/unit/wearableType/CreateWearableTypeModal.vue
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+ Typ
+
+
+
+ Beschreibung (optional)
+
+
+
+
+ erstellen
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/wearableType/DeleteWearableTypeModal.vue b/src/components/admin/unit/wearableType/DeleteWearableTypeModal.vue
new file mode 100644
index 0000000..d54d099
--- /dev/null
+++ b/src/components/admin/unit/wearableType/DeleteWearableTypeModal.vue
@@ -0,0 +1,84 @@
+
+
+
+
Ausrüstung-Type löschen
+
+
+
Type {{ wearableType?.type }} löschen?
+
+
+
+
+ löschen
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/unit/wearableType/WearableTypeListItem.vue b/src/components/admin/unit/wearableType/WearableTypeListItem.vue
new file mode 100644
index 0000000..3b9d0ed
--- /dev/null
+++ b/src/components/admin/unit/wearableType/WearableTypeListItem.vue
@@ -0,0 +1,51 @@
+
+
+
+
+ {{ wearableType.type }}
+
+
+
+
+
Anzahl angelegter Kleidung:
+
{{ wearableType.wearableCount }}
+
+
+
Beschreibung:
+
{{ wearableType.description }}
+
+
+
+
+
+
+
+
diff --git a/src/components/public/damageReport/CheckEntry.vue b/src/components/public/damageReport/CheckEntry.vue
new file mode 100644
index 0000000..a187a32
--- /dev/null
+++ b/src/components/public/damageReport/CheckEntry.vue
@@ -0,0 +1,132 @@
+
+
+
zurück
+
+
Eingaben prüfen
+
+
+ {{ check.gear.name }} ({{ check.gear.code }})
+
+
Typ: {{ check.gear.type }}
+
+
+ Kurzbeschreibung (Titel)
+
+
+
+ Beschreibung des Schadens
+
+
+
+ Fundort (optional)
+
+
+
+ Anmerkung für Bearbeiter (optional)
+
+
+
+ Gemeldet von (optional)
+
+
+
+
Bild (optional)
+
+
+
+
+
+
+ Schadensmeldung absenden
+
+
+
+
+
+
{{ message }}
+
+
+
+
+
+
diff --git a/src/components/public/damageReport/InputData.vue b/src/components/public/damageReport/InputData.vue
new file mode 100644
index 0000000..20a35ee
--- /dev/null
+++ b/src/components/public/damageReport/InputData.vue
@@ -0,0 +1,103 @@
+
+
+ zurück
+
+
+ Kurzbeschreibung (Titel)
+
+
+
+ Beschreibung des Schadens
+
+
+
+ Fundort (optional)
+
+
+
+ Anmerkung für Bearbeiter (optional)
+
+
+
+ Gemeldet von (optional)
+
+
+
+
Bild (optional)
+
setImage(e.target.files[0])" />
+
+
+
+ weiter
+
+
+
+
+
+
diff --git a/src/components/public/damageReport/Result.vue b/src/components/public/damageReport/Result.vue
new file mode 100644
index 0000000..0263d76
--- /dev/null
+++ b/src/components/public/damageReport/Result.vue
@@ -0,0 +1,28 @@
+
+
+
Schadensmeldung eingereicht
+
+
+ Deine Schadensmeldung wurde erfolgreich übermittelt.
+
+ Die Verwantwortlichen werden benachtichtigt.
+
+ Du kannst diese Seite jetzt schließen.
+
+
+
+
neue Meldung einreichen
+
+
+
+
+
+
diff --git a/src/components/public/damageReport/SelectGear.vue b/src/components/public/damageReport/SelectGear.vue
new file mode 100644
index 0000000..129c101
--- /dev/null
+++ b/src/components/public/damageReport/SelectGear.vue
@@ -0,0 +1,116 @@
+
+
+
zurück
+
+
+
+
+
+
+ mit ausgewähltem fortfahren
+
+
+ neu Scannen
+
+
+
{{ message }}
+
+
+
+
+
+
diff --git a/src/components/public/damageReport/Start.vue b/src/components/public/damageReport/Start.vue
new file mode 100644
index 0000000..cbb4d75
--- /dev/null
+++ b/src/components/public/damageReport/Start.vue
@@ -0,0 +1,19 @@
+
+
+
+ Barcode verwenden
+ ohne Barcode fortfahren
+
+
+
+
+
+
diff --git a/src/components/scanner/ManageScanModal.vue b/src/components/scanner/ManageScanModal.vue
new file mode 100644
index 0000000..8c73f0a
--- /dev/null
+++ b/src/components/scanner/ManageScanModal.vue
@@ -0,0 +1,64 @@
+
+
+
+
+
commit(c)" />
+ commit(c)" />
+
+
+
+
+
+
diff --git a/src/components/scanner/Phone.vue b/src/components/scanner/Phone.vue
new file mode 100644
index 0000000..10a3cb2
--- /dev/null
+++ b/src/components/scanner/Phone.vue
@@ -0,0 +1,91 @@
+
+
+
+ Smartphone als Scanner verwenden
+
+
+
+
+
+
+
Link zur Scanoberfläche:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/scanner/ScanInput.vue b/src/components/scanner/ScanInput.vue
new file mode 100644
index 0000000..83637e9
--- /dev/null
+++ b/src/components/scanner/ScanInput.vue
@@ -0,0 +1,57 @@
+
+
+
{{ label }}{{ required ? "" : " (optional)" }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/scanner/ScanQRCodeModal.vue b/src/components/scanner/ScanQRCodeModal.vue
new file mode 100644
index 0000000..864136f
--- /dev/null
+++ b/src/components/scanner/ScanQRCodeModal.vue
@@ -0,0 +1,51 @@
+
+
+
+
Link zur Scanoberfläche
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/scanner/ScanResultsModal.vue b/src/components/scanner/ScanResultsModal.vue
new file mode 100644
index 0000000..3e90b9b
--- /dev/null
+++ b/src/components/scanner/ScanResultsModal.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
diff --git a/src/components/scanner/ScanSidebarInfo.vue b/src/components/scanner/ScanSidebarInfo.vue
new file mode 100644
index 0000000..46fd6dd
--- /dev/null
+++ b/src/components/scanner/ScanSidebarInfo.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
Externer Scanner aktiviert
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/scanner/Scanner.vue b/src/components/scanner/Scanner.vue
new file mode 100644
index 0000000..4ef9cd6
--- /dev/null
+++ b/src/components/scanner/Scanner.vue
@@ -0,0 +1,77 @@
+
+
+
+
+ {{ c.label }}
+
+
+ Code eingeben
+
+
+
+ weiter scannen
+ bestätigen
+
+
+
+
+
+
+
diff --git a/src/components/search/DamageReportSearchSelectMultipleWithRelated.vue b/src/components/search/DamageReportSearchSelectMultipleWithRelated.vue
new file mode 100644
index 0000000..dc7e016
--- /dev/null
+++ b/src/components/search/DamageReportSearchSelectMultipleWithRelated.vue
@@ -0,0 +1,233 @@
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
+
+
+ suche
+
+
+
+
+ tippe, um zu suchen...
+
+
+
+
+ Keine Auswahl gefunden.
+
+
+
+
+
+
+ {{ damageReport.title }} von {{ damageReport.reportedBy }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/search/DamageReportSearchSelectSingleWithRelated.vue b/src/components/search/DamageReportSearchSelectSingleWithRelated.vue
new file mode 100644
index 0000000..ea77b31
--- /dev/null
+++ b/src/components/search/DamageReportSearchSelectSingleWithRelated.vue
@@ -0,0 +1,216 @@
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
+
+
+ suche
+
+
+
+
+ tippe, um zu suchen...
+
+
+
+
+ Keine Auswahl gefunden.
+
+
+
+
+
+
+ {{ damageReport.title }} von {{ damageReport.reportedBy }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/search/EquipmentSearchSelect.vue b/src/components/search/EquipmentSearchSelect.vue
new file mode 100644
index 0000000..877e338
--- /dev/null
+++ b/src/components/search/EquipmentSearchSelect.vue
@@ -0,0 +1,212 @@
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
+
+
+
+ suche
+
+
+
+
+ tippe, um zu suchen...
+
+
+
+
+ Keine Auswahl gefunden.
+
+
+
+
+
+
+ {{ equipment.name }} - Code: {{ equipment.code }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/search/EquipmentTypeSearchSelect.vue b/src/components/search/EquipmentTypeSearchSelect.vue
new file mode 100644
index 0000000..6dc4f4a
--- /dev/null
+++ b/src/components/search/EquipmentTypeSearchSelect.vue
@@ -0,0 +1,190 @@
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
+
+
+ suche
+
+
+
+
+ tippe, um zu suchen...
+
+
+
+
+ Keine Auswahl gefunden.
+
+
+
+
+
+
+ {{ equipmentType.type }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/search/InspectionPlanSearchSelect.vue b/src/components/search/InspectionPlanSearchSelect.vue
new file mode 100644
index 0000000..5c86179
--- /dev/null
+++ b/src/components/search/InspectionPlanSearchSelect.vue
@@ -0,0 +1,194 @@
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
+
+
+ suche
+
+
+
+
+ tippe, um zu suchen...
+
+
+
+
+ Keine Auswahl gefunden.
+
+
+
+
+
+
+ {{ inspectionPlan.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/search/InspectionPlanSearchSelectWithRelated.vue b/src/components/search/InspectionPlanSearchSelectWithRelated.vue
new file mode 100644
index 0000000..e6d0c3b
--- /dev/null
+++ b/src/components/search/InspectionPlanSearchSelectWithRelated.vue
@@ -0,0 +1,215 @@
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
+
+
+ suche
+
+
+
+
+ tippe, um zu suchen...
+
+
+
+
+ Keine Auswahl gefunden.
+
+
+
+
+
+
+ {{ inspectionPlan.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/admin/MemberSearchSelect.vue b/src/components/search/MemberSearchSelectMultiple.vue
similarity index 99%
rename from src/components/admin/MemberSearchSelect.vue
rename to src/components/search/MemberSearchSelectMultiple.vue
index b5e0bd0..5b5c29a 100644
--- a/src/components/admin/MemberSearchSelect.vue
+++ b/src/components/search/MemberSearchSelectMultiple.vue
@@ -18,7 +18,7 @@
@after-leave="query = ''"
>
diff --git a/src/components/search/MemberSearchSelectSingle.vue b/src/components/search/MemberSearchSelectSingle.vue
new file mode 100644
index 0000000..d81e2a4
--- /dev/null
+++ b/src/components/search/MemberSearchSelectSingle.vue
@@ -0,0 +1,174 @@
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
+
+
+ suche
+
+
+
+
+ tippe, um zu suchen...
+
+
+
+
+ Keine Auswahl gefunden.
+
+
+
+
+
+
+ {{ member.firstname }} {{ member.lastname }} {{ member.nameaffix }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/search/VehicleSearchSelect.vue b/src/components/search/VehicleSearchSelect.vue
new file mode 100644
index 0000000..ce1ea2e
--- /dev/null
+++ b/src/components/search/VehicleSearchSelect.vue
@@ -0,0 +1,212 @@
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
+
+
+
+ suche
+
+
+
+
+ tippe, um zu suchen...
+
+
+
+
+ Keine Auswahl gefunden.
+
+
+
+
+
+
+ {{ vehicle.name }} - Code: {{ vehicle.code }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/search/VehicleTypeSearchSelect.vue b/src/components/search/VehicleTypeSearchSelect.vue
new file mode 100644
index 0000000..1f3901f
--- /dev/null
+++ b/src/components/search/VehicleTypeSearchSelect.vue
@@ -0,0 +1,190 @@
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
+
+
+ suche
+
+
+
+
+ tippe, um zu suchen...
+
+
+
+
+ Keine Auswahl gefunden.
+
+
+
+
+
+
+ {{ vehicleType.type }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/search/WearableSearchSelect.vue b/src/components/search/WearableSearchSelect.vue
new file mode 100644
index 0000000..3c614d3
--- /dev/null
+++ b/src/components/search/WearableSearchSelect.vue
@@ -0,0 +1,212 @@
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
+
+
+
+ suche
+
+
+
+
+ tippe, um zu suchen...
+
+
+
+
+ Keine Auswahl gefunden.
+
+
+
+
+
+
+ {{ wearable.name }} - Code: {{ wearable.code }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/search/WearableTypeSearchSelect.vue b/src/components/search/WearableTypeSearchSelect.vue
new file mode 100644
index 0000000..15deee2
--- /dev/null
+++ b/src/components/search/WearableTypeSearchSelect.vue
@@ -0,0 +1,190 @@
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
+
+
+ suche
+
+
+
+
+ tippe, um zu suchen...
+
+
+
+
+ Keine Auswahl gefunden.
+
+
+
+
+
+
+ {{ wearableType.type }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/enums/inspectionEnum.ts b/src/enums/inspectionEnum.ts
new file mode 100644
index 0000000..58143e6
--- /dev/null
+++ b/src/enums/inspectionEnum.ts
@@ -0,0 +1,6 @@
+export enum InspectionPointEnum {
+ oknok = "oknok",
+ text = "text",
+ number = "number",
+ file = "file",
+}
diff --git a/src/enums/socketEnum.ts b/src/enums/socketEnum.ts
new file mode 100644
index 0000000..4aed946
--- /dev/null
+++ b/src/enums/socketEnum.ts
@@ -0,0 +1,4 @@
+export enum SocketConnectionTypes {
+ scanner = "/scanner",
+ pscanner = "/public_scanner",
+}
diff --git a/src/global.ts b/src/global.ts
new file mode 100644
index 0000000..883938e
--- /dev/null
+++ b/src/global.ts
@@ -0,0 +1,4 @@
+declare global {
+ //type Optional = T | { [K in keyof T]?: never };
+ type Optional = T | never;
+}
diff --git a/src/helpers/scanner.ts b/src/helpers/scanner.ts
new file mode 100644
index 0000000..6894088
--- /dev/null
+++ b/src/helpers/scanner.ts
@@ -0,0 +1,143 @@
+import type { BarcodeFormat, DetectedBarcode } from "barcode-detector/pure";
+
+/*** select camera ***/
+export interface Camera {
+ label: string;
+ constraints: {
+ deviceId?: string;
+ facingMode: string;
+ };
+}
+export const defaultConstraintOptions: Array = [
+ { label: "rear camera", constraints: { facingMode: "environment" } },
+ { label: "front camera", constraints: { facingMode: "user" } },
+];
+
+export async function getAvailableCameras(useDefault: boolean = false): Promise> {
+ // NOTE: on iOS we can't invoke `enumerateDevices` before the user has given
+ // camera access permission. `QrcodeStream` internally takes care of
+ // requesting the permissions. The `camera-on` event should guarantee that this
+ // has happened.
+ const devices = await navigator.mediaDevices.enumerateDevices();
+ const videoDevices = devices.filter(({ kind }) => kind === "videoinput");
+
+ return [
+ ...(useDefault ? defaultConstraintOptions : []),
+ ...videoDevices.map(({ deviceId, label }) => ({
+ label: `${label}`, //(ID: ${deviceId})
+ constraints: { deviceId, facingMode: "custom" },
+ })),
+ ];
+}
+
+/*** track functons ***/
+export function paintOutline(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) {
+ for (const detectedCode of detectedCodes) {
+ const [firstPoint, ...otherPoints] = detectedCode.cornerPoints;
+
+ ctx.strokeStyle = "red";
+
+ ctx.beginPath();
+ ctx.moveTo(firstPoint.x, firstPoint.y);
+ for (const { x, y } of otherPoints) {
+ ctx.lineTo(x, y);
+ }
+ ctx.lineTo(firstPoint.x, firstPoint.y);
+ ctx.closePath();
+ ctx.stroke();
+ }
+}
+export function paintBoundingBox(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) {
+ for (const detectedCode of detectedCodes) {
+ const {
+ boundingBox: { x, y, width, height },
+ } = detectedCode;
+
+ ctx.lineWidth = 2;
+ ctx.strokeStyle = "#007bff";
+ ctx.strokeRect(x, y, width, height);
+ }
+}
+export function paintCenterText(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) {
+ for (const detectedCode of detectedCodes) {
+ const { boundingBox, rawValue } = detectedCode;
+
+ const centerX = boundingBox.x + boundingBox.width / 2;
+ const centerY = boundingBox.y + boundingBox.height / 2;
+
+ const fontSize = Math.max(12, (50 * boundingBox.width) / ctx.canvas.width);
+
+ ctx.font = `bold ${fontSize}px sans-serif`;
+ ctx.textAlign = "center";
+
+ ctx.lineWidth = 3;
+ ctx.strokeStyle = "#35495e";
+ ctx.strokeText(detectedCode.rawValue, centerX, centerY);
+
+ ctx.fillStyle = "#5cb984";
+ ctx.fillText(rawValue, centerX, centerY);
+ }
+}
+export const trackFunctionOptions = [
+ { text: "nothing (default)", value: undefined },
+ { text: "outline", value: paintOutline },
+ { text: "centered text", value: paintCenterText },
+ { text: "bounding box", value: paintBoundingBox },
+ {
+ text: "mixed",
+ value: (detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D) => {
+ paintOutline(detectedCodes, ctx);
+ paintCenterText(detectedCodes, ctx);
+ },
+ },
+];
+
+/*** barcode formats ***/
+export const barcodeFormats: Array = [
+ "aztec",
+ "code_128",
+ "code_39",
+ "code_93",
+ "codabar",
+ "databar",
+ "databar_expanded",
+ "data_matrix",
+ "dx_film_edge",
+ "ean_13",
+ "ean_8",
+ "itf",
+ "maxi_code",
+ "micro_qr_code",
+ "pdf417",
+ "qr_code",
+ "rm_qr_code",
+ "upc_a",
+ "upc_e",
+ "linear_codes",
+ "matrix_codes",
+];
+
+/*** error handling ***/
+export function handleScannerError(err: Error) {
+ let error = `[${err.name}]: `;
+
+ if (err.name === "NotAllowedError") {
+ error += "you need to grant camera access permission";
+ } else if (err.name === "NotFoundError") {
+ error += "no camera on this device";
+ } else if (err.name === "NotSupportedError") {
+ error += "secure context required (HTTPS, localhost)";
+ } else if (err.name === "NotReadableError") {
+ error += "is the camera already in use?";
+ } else if (err.name === "OverconstrainedError") {
+ error += "installed cameras are not suitable";
+ } else if (err.name === "StreamApiNotSupportedError") {
+ error += "Stream API is not supported in this browser";
+ } else if (err.name === "InsecureContextError") {
+ error += "Camera access is only permitted in secure context. Use HTTPS or localhost rather than HTTP.";
+ } else {
+ error += err.message;
+ }
+
+ return error;
+}
diff --git a/src/main.css b/src/main.css
index a334a51..9c0b7b3 100644
--- a/src/main.css
+++ b/src/main.css
@@ -68,26 +68,33 @@ body {
/*:not([headlessui]):not([id*="headlessui"]):not([class*="headlessui"])*/
button:not([class*="ql"] *):not([class*="fc"]):not([id*="headlessui-combobox"]),
-a[button] {
+[button] {
@apply cursor-pointer relative box-border h-10 w-full flex justify-center py-2 px-4 text-sm font-medium rounded-md focus:outline-hidden focus:ring-0;
}
button[primary]:not([primary="false"]),
-a[button][primary]:not([primary="false"]) {
- @apply border-2 border-transparent text-white bg-primary hover:bg-primary;
+[button][primary]:not([primary="false"]) {
+ @apply border-2 border-transparent text-white bg-primary hover:bg-accent;
}
button[primary-outline]:not([primary-outline="false"]),
-a[button][primary-outline]:not([primary-outline="false"]) {
- @apply border-2 border-primary text-black hover:bg-primary;
+[button][primary-outline]:not([primary-outline="false"]) {
+ @apply border-2 border-primary text-black hover:bg-primary hover:text-white;
}
button:disabled,
-a[button]:disabled,
-a[button].disabled {
+[button]:disabled,
+[button].disabled,
+[button][disabled="true"] {
@apply opacity-75 pointer-events-none;
}
+a:disabled,
+a.disabled,
+a[disabled="true"] {
+ @apply cursor-default pointer-events-none;
+}
+
input:not([type="checkbox"]),
textarea,
select {
@@ -97,12 +104,14 @@ select {
input[readonly],
textarea[readonly],
select[readonly] {
- @apply select-none;
+ @apply select-none focus:border-gray-300 cursor-default;
/* pointer-events-none; */
}
input[disabled],
-textarea[disabled],
+textarea[disabled] {
+ @apply opacity-75;
+}
select[disabled] {
@apply opacity-75 pointer-events-none;
}
diff --git a/src/router/memberGuard.ts b/src/router/club/memberGuard.ts
similarity index 93%
rename from src/router/memberGuard.ts
rename to src/router/club/memberGuard.ts
index de09386..843be39 100644
--- a/src/router/memberGuard.ts
+++ b/src/router/club/memberGuard.ts
@@ -4,7 +4,7 @@ import { useMemberAwardStore } from "@/stores/admin/club/member/memberAward";
import { useMemberExecutivePositionStore } from "@/stores/admin/club/member/memberExecutivePosition";
import { useMemberQualificationStore } from "@/stores/admin/club/member/memberQualification";
import { useMembershipStore } from "@/stores/admin/club/member/membership";
-import { useMemberEducationStore } from "../stores/admin/club/member/memberEducation";
+import { useMemberEducationStore } from "@/stores/admin/club/member/memberEducation";
export async function setMemberId(to: any, from: any, next: any) {
const member = useMemberStore();
diff --git a/src/router/newsletterGuard.ts b/src/router/club/newsletterGuard.ts
similarity index 100%
rename from src/router/newsletterGuard.ts
rename to src/router/club/newsletterGuard.ts
diff --git a/src/router/protocolGuard.ts b/src/router/club/protocolGuard.ts
similarity index 100%
rename from src/router/protocolGuard.ts
rename to src/router/club/protocolGuard.ts
diff --git a/src/router/index.ts b/src/router/index.ts
index 35b677a..207acd2 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -5,10 +5,23 @@ import { isAuthenticated } from "./authGuard";
import { isSetup } from "./setupGuard";
import { abilityAndNavUpdate } from "./adminGuard";
import type { PermissionType, PermissionSection, PermissionModule } from "@/types/permissionTypes";
-import { resetMemberStores, setMemberId } from "./memberGuard";
-import { resetProtocolStores, setProtocolId } from "./protocolGuard";
-import { resetNewsletterStores, setNewsletterId } from "./newsletterGuard";
-import { setBackupPage } from "./backupGuard";
+import { resetMemberStores, setMemberId } from "./club/memberGuard";
+import { resetProtocolStores, setProtocolId } from "./club/protocolGuard";
+import { resetNewsletterStores, setNewsletterId } from "./club/newsletterGuard";
+import { setBackupPage } from "./management/backupGuard";
+import { resetEquipmentTypeStores, setEquipmentTypeId } from "./unit/equipmentType";
+import { resetEquipmentStores, setEquipmentId } from "./unit/equipment";
+import { resetVehicleStores, setVehicleId } from "./unit/vehicle";
+import { resetRespiratoryGearStores, setRespiratoryGearId } from "./unit/respiratoryGear";
+import { resetRespiratoryWearerStores, setRespiratoryWearerId } from "./unit/respiratoryWearer";
+import { resetRespiratoryMissionStores, setRespiratoryMissionId } from "./unit/respiratoryMission";
+import { resetWearableStores, setWearableId } from "./unit/wearable";
+import { resetInspectionPlanStores, setInspectionPlanId } from "./unit/inspectionPlan";
+import { setVehicleTypeId } from "./unit/vehicleType";
+import { resetInspectionStores, setInspectionId } from "./unit/inspection";
+import { setWearableTypeId } from "./unit/wearableType";
+import { resetDamageReportStores, setDamageReportId } from "./unit/damageReport";
+import { resetRepairStores, setRepairId } from "./unit/repair";
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
@@ -309,6 +322,761 @@ const router = createRouter({
},
],
},
+ {
+ path: "unit",
+ name: "admin-unit",
+ component: () => import("@/views/RouterView.vue"),
+ meta: { type: "read", section: "unit" },
+ beforeEnter: [abilityAndNavUpdate],
+ children: [
+ {
+ path: "",
+ name: "admin-unit-default",
+ component: () => import("@/views/admin/ViewSelect.vue"),
+ meta: { type: "read", section: "unit" },
+ beforeEnter: [abilityAndNavUpdate],
+ },
+ {
+ path: "equipment",
+ name: "admin-unit-equipment-route",
+ component: () => import("@/views/RouterView.vue"),
+ meta: { type: "read", section: "unit", module: "equipment" },
+ beforeEnter: [abilityAndNavUpdate],
+ children: [
+ {
+ path: "",
+ name: "admin-unit-equipment",
+ component: () => import("@/views/admin/unit/equipment/Equipment.vue"),
+ beforeEnter: [resetEquipmentStores],
+ },
+ {
+ path: "create",
+ name: "admin-unit-equipment-create",
+ component: () => import("@/views/admin/unit/equipment/CreateEquipment.vue"),
+ meta: { type: "create", section: "unit", module: "equipment" },
+ beforeEnter: [abilityAndNavUpdate],
+ },
+ {
+ path: ":equipmentId",
+ name: "admin-unit-equipment-routing",
+ component: () => import("@/views/admin/unit/equipment/EquipmentRouting.vue"),
+ beforeEnter: [setEquipmentId],
+ props: true,
+ children: [
+ {
+ path: "overview",
+ name: "admin-unit-equipment-overview",
+ component: () => import("@/views/admin/unit/equipment/Overview.vue"),
+ props: true,
+ },
+ {
+ path: "maintenance",
+ name: "admin-unit-equipment-maintenance",
+ component: () => import("@/views/admin/ViewSelect.vue"),
+ props: true,
+ },
+ {
+ path: "repair",
+ name: "admin-unit-equipment-repair",
+ component: () => import("@/views/admin/unit/equipment/Repair.vue"),
+ props: true,
+ },
+ {
+ path: "inspection",
+ name: "admin-unit-equipment-inspection",
+ component: () => import("@/views/admin/unit/equipment/Inspection.vue"),
+ props: true,
+ },
+ {
+ path: "report",
+ name: "admin-unit-equipment-damage_report",
+ component: () => import("@/views/admin/unit/equipment/DamageReport.vue"),
+ props: true,
+ },
+ {
+ path: "edit",
+ name: "admin-unit-equipment-edit",
+ component: () => import("@/views/admin/unit/equipment/UpdateEquipment.vue"),
+ meta: { type: "update", section: "unit", module: "equipment" },
+ beforeEnter: [abilityAndNavUpdate],
+ props: true,
+ },
+ ],
+ },
+ ],
+ },
+ {
+ path: "vehicle",
+ name: "admin-unit-vehicle-route",
+ component: () => import("@/views/RouterView.vue"),
+ meta: { type: "read", section: "unit", module: "vehicle" },
+ beforeEnter: [abilityAndNavUpdate],
+ children: [
+ {
+ path: "",
+ name: "admin-unit-vehicle",
+ component: () => import("@/views/admin/unit/vehicle/Vehicle.vue"),
+ beforeEnter: [resetVehicleStores],
+ },
+ {
+ path: "create",
+ name: "admin-unit-vehicle-create",
+ component: () => import("@/views/admin/unit/vehicle/CreateVehicle.vue"),
+ meta: { type: "create", section: "unit", module: "vehicle" },
+ beforeEnter: [abilityAndNavUpdate],
+ },
+ {
+ path: ":vehicleId",
+ name: "admin-unit-vehicle-routing",
+ component: () => import("@/views/admin/unit/vehicle/VehicleRouting.vue"),
+ beforeEnter: [setVehicleId],
+ props: true,
+ children: [
+ {
+ path: "overview",
+ name: "admin-unit-vehicle-overview",
+ component: () => import("@/views/admin/unit/vehicle/Overview.vue"),
+ props: true,
+ },
+ {
+ path: "maintenance",
+ name: "admin-unit-vehicle-maintenance",
+ component: () => import("@/views/admin/ViewSelect.vue"),
+ props: true,
+ },
+ {
+ path: "repair",
+ name: "admin-unit-vehicle-repair",
+ component: () => import("@/views/admin/unit/vehicle/Repair.vue"),
+ props: true,
+ },
+ {
+ path: "inspection",
+ name: "admin-unit-vehicle-inspection",
+ component: () => import("@/views/admin/unit/vehicle/Inspection.vue"),
+ props: true,
+ },
+ {
+ path: "report",
+ name: "admin-unit-vehicle-damage_report",
+ component: () => import("@/views/admin/unit/vehicle/DamageReport.vue"),
+ props: true,
+ },
+ {
+ path: "edit",
+ name: "admin-unit-vehicle-edit",
+ component: () => import("@/views/admin/unit/vehicle/UpdateVehicle.vue"),
+ meta: { type: "update", section: "unit", module: "vehicle" },
+ beforeEnter: [abilityAndNavUpdate],
+ props: true,
+ },
+ ],
+ },
+ ],
+ },
+ {
+ path: "wearable",
+ name: "admin-unit-wearable-route",
+ component: () => import("@/views/RouterView.vue"),
+ meta: { type: "read", section: "unit", module: "wearable" },
+ beforeEnter: [abilityAndNavUpdate],
+ children: [
+ {
+ path: "",
+ name: "admin-unit-wearable",
+ component: () => import("@/views/admin/unit/wearable/Wearable.vue"),
+ beforeEnter: [resetWearableStores],
+ },
+ {
+ path: "create",
+ name: "admin-unit-wearable-create",
+ component: () => import("@/views/admin/unit/wearable/CreateWearable.vue"),
+ meta: { type: "create", section: "unit", module: "wearable" },
+ beforeEnter: [abilityAndNavUpdate],
+ },
+ {
+ path: ":wearableId",
+ name: "admin-unit-wearable-routing",
+ component: () => import("@/views/admin/unit/wearable/WearableRouting.vue"),
+ beforeEnter: [setWearableId],
+ props: true,
+ children: [
+ {
+ path: "overview",
+ name: "admin-unit-wearable-overview",
+ component: () => import("@/views/admin/unit/wearable/Overview.vue"),
+ props: true,
+ },
+ {
+ path: "maintenance",
+ name: "admin-unit-wearable-maintenance",
+ component: () => import("@/views/admin/ViewSelect.vue"),
+ props: true,
+ },
+ {
+ path: "repair",
+ name: "admin-unit-wearable-repair",
+ component: () => import("@/views/admin/unit/wearable/Repair.vue"),
+ props: true,
+ },
+ {
+ path: "inspection",
+ name: "admin-unit-wearable-inspection",
+ component: () => import("@/views/admin/unit/wearable/Inspection.vue"),
+ props: true,
+ },
+ {
+ path: "report",
+ name: "admin-unit-wearable-damage_report",
+ component: () => import("@/views/admin/unit/wearable/DamageReport.vue"),
+ props: true,
+ },
+ {
+ path: "edit",
+ name: "admin-unit-wearable-edit",
+ component: () => import("@/views/admin/unit/wearable/UpdateWearable.vue"),
+ meta: { type: "update", section: "unit", module: "wearable" },
+ beforeEnter: [abilityAndNavUpdate],
+ props: true,
+ },
+ ],
+ },
+ ],
+ },
+ {
+ path: "respiratory-gear",
+ name: "admin-unit-respiratory_gear-route",
+ component: () => import("@/views/RouterView.vue"),
+ meta: { type: "read", section: "unit", module: "respiratory_gear" },
+ beforeEnter: [abilityAndNavUpdate],
+ children: [
+ {
+ path: "",
+ name: "admin-unit-respiratory_gear",
+ component: () => import("@/views/admin/unit/respiratoryGear/RespiratoryGear.vue"),
+ beforeEnter: [resetRespiratoryGearStores],
+ },
+ {
+ path: "create",
+ name: "admin-unit-respiratory_gear-create",
+ component: () => import("@/views/admin/unit/respiratoryGear/CreateRespiratoryGear.vue"),
+ meta: { type: "create", section: "unit", module: "respiratory_gear" },
+ beforeEnter: [abilityAndNavUpdate],
+ },
+ {
+ path: ":respiratoryGearId",
+ name: "admin-unit-respiratory_gear-routing",
+ component: () => import("@/views/admin/unit/respiratoryGear/RespiratoryGearRouting.vue"),
+ beforeEnter: [setRespiratoryGearId],
+ props: true,
+ children: [
+ {
+ path: "overview",
+ name: "admin-unit-respiratory_gear-overview",
+ component: () => import("@/views/admin/ViewSelect.vue"),
+ props: true,
+ },
+ {
+ path: "maintenance",
+ name: "admin-unit-respiratory_gear-maintenance",
+ component: () => import("@/views/admin/ViewSelect.vue"),
+ props: true,
+ },
+ {
+ path: "inspection",
+ name: "admin-unit-respiratory_gear-inspection",
+ component: () => import("@/views/admin/ViewSelect.vue"),
+ props: true,
+ },
+ {
+ path: "mission",
+ name: "admin-unit-respiratory_gear-mission",
+ component: () => import("@/views/admin/ViewSelect.vue"),
+ props: true,
+ },
+ ],
+ },
+ ],
+ },
+ {
+ path: "respiratory-wearer",
+ name: "admin-unit-respiratory_wearer-route",
+ component: () => import("@/views/RouterView.vue"),
+ meta: { type: "read", section: "unit", module: "respiratory_wearer" },
+ beforeEnter: [abilityAndNavUpdate],
+ children: [
+ {
+ path: "",
+ name: "admin-unit-respiratory_wearer",
+ component: () => import("@/views/admin/unit/respiratoryWearer/RespiratoryWearer.vue"),
+ beforeEnter: [resetRespiratoryWearerStores],
+ },
+ {
+ path: "create",
+ name: "admin-unit-respiratory_wearer-create",
+ component: () => import("@/views/admin/unit/respiratoryWearer/CreateRespiratoryWearer.vue"),
+ meta: { type: "create", section: "unit", module: "respiratory_wearer" },
+ beforeEnter: [abilityAndNavUpdate],
+ },
+ {
+ path: ":respiratoryWearerId",
+ name: "admin-unit-respiratory_wearer-routing",
+ component: () => import("@/views/admin/unit/respiratoryWearer/RespiratoryWearerRouting.vue"),
+ beforeEnter: [setRespiratoryWearerId],
+ props: true,
+ children: [
+ {
+ path: "overview",
+ name: "admin-unit-respiratory_wearer-overview",
+ component: () => import("@/views/admin/ViewSelect.vue"),
+ props: true,
+ },
+ {
+ path: "mission",
+ name: "admin-unit-respiratory_wearer-mission",
+ component: () => import("@/views/admin/ViewSelect.vue"),
+ props: true,
+ },
+ {
+ path: "education",
+ name: "admin-unit-respiratory_wearer-education",
+ component: () => import("@/views/admin/ViewSelect.vue"),
+ props: true,
+ },
+ {
+ path: "instruction",
+ name: "admin-unit-respiratory_wearer-instruction",
+ component: () => import("@/views/admin/ViewSelect.vue"),
+ props: true,
+ },
+ {
+ path: "screening",
+ name: "admin-unit-respiratory_wearer-screening",
+ component: () => import("@/views/admin/ViewSelect.vue"),
+ props: true,
+ },
+ {
+ path: "strain",
+ name: "admin-unit-respiratory_wearer-strain",
+ component: () => import("@/views/admin/ViewSelect.vue"),
+ props: true,
+ },
+ ],
+ },
+ ],
+ },
+ {
+ path: "respiratory-mission",
+ name: "admin-unit-respiratory_mission-route",
+ component: () => import("@/views/RouterView.vue"),
+ meta: { type: "read", section: "unit", module: "respiratory_mission" },
+ beforeEnter: [abilityAndNavUpdate],
+ children: [
+ {
+ path: "",
+ name: "admin-unit-respiratory_mission",
+ component: () => import("@/views/admin/unit/respiratoryMission/RespiratoryMission.vue"),
+ beforeEnter: [resetRespiratoryMissionStores],
+ },
+ {
+ path: "create",
+ name: "admin-unit-respiratory_mission-create",
+ component: () => import("@/views/admin/unit/respiratoryMission/CreateRespiratoryMission.vue"),
+ meta: { type: "create", section: "unit", module: "respiratory_mission" },
+ beforeEnter: [abilityAndNavUpdate],
+ },
+ {
+ path: ":respiratoryMissionId",
+ name: "admin-unit-respiratory_mission-routing",
+ component: () => import("@/views/admin/unit/respiratoryMission/RespiratoryMissionRouting.vue"),
+ beforeEnter: [setRespiratoryMissionId],
+ props: true,
+ children: [
+ {
+ path: "overview",
+ name: "admin-unit-respiratory_mission-overview",
+ component: () => import("@/views/admin/ViewSelect.vue"),
+ props: true,
+ },
+ {
+ path: "wearer",
+ name: "admin-unit-respiratory_mission-wearer",
+ component: () => import("@/views/admin/ViewSelect.vue"),
+ props: true,
+ },
+ {
+ path: "gear",
+ name: "admin-unit-respiratory_mission-gear",
+ component: () => import("@/views/admin/ViewSelect.vue"),
+ props: true,
+ },
+ ],
+ },
+ ],
+ },
+ {
+ path: "damage-report",
+ name: "admin-unit-damage_report-route",
+ component: () => import("@/views/RouterView.vue"),
+ meta: { type: "read", section: "unit", module: "damage_report" },
+ beforeEnter: [abilityAndNavUpdate],
+ children: [
+ {
+ path: "",
+ name: "admin-unit-damage_report",
+ redirect: { name: "admin-unit-damage_report-open" },
+ },
+ {
+ path: "status",
+ name: "admin-unit-damage_report-statusrouting",
+ component: () => import("@/views/admin/unit/damageReport/DamageReportStatusRouting.vue"),
+ beforeEnter: [resetDamageReportStores],
+ children: [
+ {
+ path: "",
+ name: "admin-unit-damage_report-status",
+ redirect: { name: "admin-unit-damage_report-open" },
+ },
+ {
+ path: "open",
+ name: "admin-unit-damage_report-open",
+ component: () => import("@/views/admin/unit/damageReport/DamageReport.vue"),
+ },
+ {
+ path: "done",
+ name: "admin-unit-damage_report-done",
+ component: () => import("@/views/admin/unit/damageReport/DamageReportClosed.vue"),
+ },
+ ],
+ },
+ {
+ path: ":damageReportId",
+ name: "admin-unit-damage_report-routing",
+ component: () => import("@/views/admin/unit/damageReport/DamageReportRouting.vue"),
+ beforeEnter: [setDamageReportId],
+ props: true,
+ children: [
+ {
+ path: "",
+ name: "admin-unit-damage_report-overview",
+ component: () => import("@/views/admin/unit/damageReport/Overview.vue"),
+ props: true,
+ },
+ ],
+ },
+ ],
+ },
+ {
+ path: "repair",
+ name: "admin-unit-repair-route",
+ component: () => import("@/views/RouterView.vue"),
+ meta: { type: "read", section: "unit", module: "repair" },
+ beforeEnter: [abilityAndNavUpdate],
+ children: [
+ {
+ path: "",
+ name: "admin-unit-repair",
+ redirect: { name: "admin-unit-repair-open" },
+ },
+ {
+ path: "status",
+ name: "admin-unit-repair-statusrouting",
+ component: () => import("@/views/admin/unit/repair/RepairStatusRouting.vue"),
+ beforeEnter: [resetRepairStores],
+ children: [
+ {
+ path: "",
+ name: "admin-unit-repair-status",
+ redirect: { name: "admin-unit-repair-open" },
+ },
+ {
+ path: "open",
+ name: "admin-unit-repair-open",
+ component: () => import("@/views/admin/unit/repair/RepairOpen.vue"),
+ },
+ {
+ path: "done",
+ name: "admin-unit-repair-done",
+ component: () => import("@/views/admin/unit/repair/RepairClosed.vue"),
+ },
+ ],
+ },
+ {
+ path: "create/:type?/:relatedId?",
+ name: "admin-unit-repair-create",
+ component: () => import("@/views/admin/unit/repair/RepairCreate.vue"),
+ meta: { type: "create", section: "unit", module: "repair" },
+ beforeEnter: [abilityAndNavUpdate],
+ props: true,
+ },
+ {
+ path: "execute/:repairId",
+ name: "admin-unit-repair-routing",
+ component: () => import("@/views/admin/unit/repair/RepairRouting.vue"),
+ beforeEnter: [setRepairId],
+ props: true,
+ children: [
+ {
+ path: "",
+ name: "admin-unit-repair-overview",
+ component: () => import("@/views/admin/unit/repair/Overview.vue"),
+ props: true,
+ },
+ {
+ path: "reports",
+ name: "admin-unit-repair-reports",
+ component: () => import("@/views/admin/unit/repair/DamageReports.vue"),
+ props: true,
+ },
+ ],
+ },
+ ],
+ },
+ {
+ path: "maintenance",
+ name: "admin-unit-maintenance-route",
+ component: () => import("@/views/admin/unit/maintenance/MaintenanceRouting.vue"),
+ meta: { type: "read", section: "unit", module: "maintenance" },
+ beforeEnter: [abilityAndNavUpdate],
+ children: [
+ {
+ path: "",
+ name: "admin-unit-maintenance",
+ component: () => import("@/views/admin/unit/maintenance/Maintenance.vue"),
+ },
+ {
+ path: "done",
+ name: "admin-unit-maintenance-done",
+ component: () => import("@/views/admin/unit/maintenance/Maintenance.vue"),
+ },
+ ],
+ },
+ {
+ path: "equipment-type",
+ name: "admin-unit-equipment_type-route",
+ component: () => import("@/views/RouterView.vue"),
+ meta: { type: "read", section: "unit", module: "equipment_type" },
+ beforeEnter: [abilityAndNavUpdate],
+ children: [
+ {
+ path: "",
+ name: "admin-unit-equipment_type",
+ component: () => import("@/views/admin/unit/equipmentType/EquipmentType.vue"),
+ beforeEnter: [resetEquipmentTypeStores],
+ },
+ {
+ path: ":equipmentTypeId",
+ name: "admin-unit-equipment_type-routing",
+ component: () => import("@/views/admin/unit/equipmentType/EquipmentTypeRouting.vue"),
+ beforeEnter: [setEquipmentTypeId],
+ props: true,
+ children: [
+ {
+ path: "overview",
+ name: "admin-unit-equipment_type-overview",
+ component: () => import("@/views/admin/unit/equipmentType/Overview.vue"),
+ props: true,
+ },
+ {
+ path: "inspection-plan",
+ name: "admin-unit-equipment_type-inspection_plan",
+ component: () => import("@/views/admin/unit/equipmentType/InspectionPlans.vue"),
+ props: true,
+ },
+ {
+ path: "edit",
+ name: "admin-unit-equipment_type-edit",
+ component: () => import("@/views/admin/unit/equipmentType/UpdateEquipmentType.vue"),
+ meta: { type: "update", section: "unit", module: "equipment_type" },
+ beforeEnter: [abilityAndNavUpdate],
+ props: true,
+ },
+ ],
+ },
+ ],
+ },
+ {
+ path: "vehicle-type",
+ name: "admin-unit-vehicle_type-route",
+ component: () => import("@/views/RouterView.vue"),
+ meta: { type: "read", section: "unit", module: "vehicle_type" },
+ beforeEnter: [abilityAndNavUpdate],
+ children: [
+ {
+ path: "",
+ name: "admin-unit-vehicle_type",
+ component: () => import("@/views/admin/unit/vehicleType/VehicleType.vue"),
+ },
+ {
+ path: ":vehicleTypeId",
+ name: "admin-unit-vehicle_type-routing",
+ component: () => import("@/views/admin/unit/vehicleType/VehicleTypeRouting.vue"),
+ beforeEnter: [setVehicleTypeId],
+ props: true,
+ children: [
+ {
+ path: "overview",
+ name: "admin-unit-vehicle_type-overview",
+ component: () => import("@/views/admin/unit/vehicleType/Overview.vue"),
+ props: true,
+ },
+ {
+ path: "inspection-plan",
+ name: "admin-unit-vehicle_type-inspection_plan",
+ component: () => import("@/views/admin/unit/vehicleType/InspectionPlans.vue"),
+ props: true,
+ },
+ {
+ path: "edit",
+ name: "admin-unit-vehicle_type-edit",
+ component: () => import("@/views/admin/unit/vehicleType/UpdateVehicleType.vue"),
+ meta: { type: "update", section: "unit", module: "vehicle_type" },
+ beforeEnter: [abilityAndNavUpdate],
+ props: true,
+ },
+ ],
+ },
+ ],
+ },
+ {
+ path: "wearable-type",
+ name: "admin-unit-wearable_type-route",
+ component: () => import("@/views/RouterView.vue"),
+ meta: { type: "read", section: "unit", module: "wearable_type" },
+ beforeEnter: [abilityAndNavUpdate],
+ children: [
+ {
+ path: "",
+ name: "admin-unit-wearable_type",
+ component: () => import("@/views/admin/unit/wearableType/WearableType.vue"),
+ },
+ {
+ path: ":wearableTypeId",
+ name: "admin-unit-wearable_type-routing",
+ component: () => import("@/views/admin/unit/wearableType/WearableTypeRouting.vue"),
+ beforeEnter: [setWearableTypeId],
+ props: true,
+ children: [
+ {
+ path: "overview",
+ name: "admin-unit-wearable_type-overview",
+ component: () => import("@/views/admin/unit/wearableType/Overview.vue"),
+ props: true,
+ },
+ {
+ path: "inspection-plan",
+ name: "admin-unit-wearable_type-inspection_plan",
+ component: () => import("@/views/admin/unit/wearableType/InspectionPlans.vue"),
+ props: true,
+ },
+ {
+ path: "edit",
+ name: "admin-unit-wearable_type-edit",
+ component: () => import("@/views/admin/unit/wearableType/UpdateWearableType.vue"),
+ meta: { type: "update", section: "unit", module: "wearable_type" },
+ beforeEnter: [abilityAndNavUpdate],
+ props: true,
+ },
+ ],
+ },
+ ],
+ },
+ {
+ path: "inspection-plan",
+ name: "admin-unit-inspection_plan-route",
+ component: () => import("@/views/RouterView.vue"),
+ meta: { type: "read", section: "unit", module: "inspection_plan" },
+ beforeEnter: [abilityAndNavUpdate],
+ children: [
+ {
+ path: "",
+ name: "admin-unit-inspection_plan",
+ component: () => import("@/views/admin/unit/inspectionPlan/InspectionPlan.vue"),
+ beforeEnter: [resetInspectionPlanStores],
+ },
+ {
+ path: "create",
+ name: "admin-unit-inspection_plan-create",
+ component: () => import("@/views/admin/unit/inspectionPlan/CreateInspectionPlan.vue"),
+ meta: { type: "create", section: "unit", module: "inspection_plan" },
+ beforeEnter: [abilityAndNavUpdate],
+ },
+ {
+ path: ":inspectionPlanId",
+ name: "admin-unit-inspection_plan-routing",
+ component: () => import("@/views/admin/unit/inspectionPlan/InspectionPlanRouting.vue"),
+ beforeEnter: [setInspectionPlanId],
+ props: true,
+ children: [
+ {
+ path: "",
+ name: "admin-unit-inspection_plan-overview",
+ component: () => import("@/views/admin/unit/inspectionPlan/Overview.vue"),
+ props: true,
+ },
+ {
+ path: "edit",
+ name: "admin-unit-inspection_plan-edit",
+ 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,
+ },
+ ],
+ },
+ ],
+ },
+ {
+ path: "inspection",
+ name: "admin-unit-inspection-route",
+ component: () => import("@/views/RouterView.vue"),
+ meta: { type: "create", section: "unit", module: "inspection" },
+ beforeEnter: [abilityAndNavUpdate, resetInspectionStores],
+ children: [
+ {
+ path: "",
+ 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/NextInspections.vue"),
+ },
+ {
+ path: "running",
+ name: "admin-unit-inspection-running",
+ component: () => import("@/views/admin/unit/inspection/RunningInspections.vue"),
+ },
+ ],
+ },
+ {
+ path: "start/:type?/:relatedId?/:inspectionPlanId?",
+ name: "admin-unit-inspection-start",
+ component: () => import("@/views/admin/unit/inspection/InspectionStart.vue"),
+ meta: { type: "create", section: "unit", module: "inspection_plan" },
+ beforeEnter: [abilityAndNavUpdate],
+ props: true,
+ },
+ {
+ path: "execute/:inspectionId",
+ name: "admin-unit-inspection-execute",
+ component: () => import("@/views/admin/unit/inspection/InspectionExecute.vue"),
+ beforeEnter: [setInspectionId],
+ props: true,
+ },
+ ],
+ },
+ ],
+ },
{
path: "configuration",
name: "admin-configuration",
@@ -778,6 +1546,29 @@ const router = createRouter({
name: "public-calendar-explain",
component: () => import("@/views/public/calendar/CalendarExplain.vue"),
},
+ {
+ path: "scanner",
+ name: "public-scanner-routing",
+ component: () => import("@/views/public/scanner/ScannerRouting.vue"),
+ children: [
+ {
+ path: "",
+ name: "public-scanner-select",
+ component: () => import("@/views/public/scanner/RoomSelect.vue"),
+ },
+ {
+ path: ":room",
+ name: "public-scanner-room",
+ component: () => import("@/views/public/scanner/Scanner.vue"),
+ props: true,
+ },
+ ],
+ },
+ {
+ path: "damagereport",
+ name: "public-damage_report",
+ component: () => import("@/views/public/damageReport/Report.vue"),
+ },
],
},
{
diff --git a/src/router/backupGuard.ts b/src/router/management/backupGuard.ts
similarity index 100%
rename from src/router/backupGuard.ts
rename to src/router/management/backupGuard.ts
diff --git a/src/router/unit/damageReport.ts b/src/router/unit/damageReport.ts
new file mode 100644
index 0000000..4a649bf
--- /dev/null
+++ b/src/router/unit/damageReport.ts
@@ -0,0 +1,20 @@
+import { useDamageReportStore } from "@/stores/admin/unit/damageReport";
+
+export async function setDamageReportId(to: any, from: any, next: any) {
+ const damageReportStore = useDamageReportStore();
+ damageReportStore.activeDamageReport = to.params?.damageReportId ?? null;
+
+ //xystore().$reset();
+
+ next();
+}
+
+export async function resetDamageReportStores(to: any, from: any, next: any) {
+ const damageReportStore = useDamageReportStore();
+ damageReportStore.activeDamageReport = null;
+ damageReportStore.activeDamageReportObj = null;
+
+ //xystore().$reset();
+
+ next();
+}
diff --git a/src/router/unit/equipment.ts b/src/router/unit/equipment.ts
new file mode 100644
index 0000000..99cb01c
--- /dev/null
+++ b/src/router/unit/equipment.ts
@@ -0,0 +1,27 @@
+import { useEquipmentStore } from "@/stores/admin/unit/equipment/equipment";
+import { useEquipmentDamageReportStore } from "@/stores/admin/unit/equipment/damageReport";
+import { useEquipmentInspectionStore } from "@/stores/admin/unit/equipment/inspection";
+import { useEquipmentRepairStore } from "@/stores/admin/unit/equipment/repair";
+
+export async function setEquipmentId(to: any, from: any, next: any) {
+ const equipmentStore = useEquipmentStore();
+ equipmentStore.activeEquipment = to.params?.equipmentId ?? null;
+
+ useEquipmentDamageReportStore().$reset();
+ useEquipmentInspectionStore().$reset();
+ useEquipmentRepairStore().$reset();
+
+ next();
+}
+
+export async function resetEquipmentStores(to: any, from: any, next: any) {
+ const equipmentStore = useEquipmentStore();
+ equipmentStore.activeEquipment = null;
+ equipmentStore.activeEquipmentObj = null;
+
+ useEquipmentDamageReportStore().$reset();
+ useEquipmentInspectionStore().$reset();
+ useEquipmentRepairStore().$reset();
+
+ next();
+}
diff --git a/src/router/unit/equipmentType.ts b/src/router/unit/equipmentType.ts
new file mode 100644
index 0000000..84ed750
--- /dev/null
+++ b/src/router/unit/equipmentType.ts
@@ -0,0 +1,21 @@
+import { useEquipmentTypeStore } from "@/stores/admin/unit/equipmentType/equipmentType";
+import { useEquipmentTypeInspectionPlanStore } from "@/stores/admin/unit/equipmentType/inspectionPlan";
+
+export async function setEquipmentTypeId(to: any, from: any, next: any) {
+ const equipmentTypeStore = useEquipmentTypeStore();
+ equipmentTypeStore.activeEquipmentType = to.params?.equipmentTypeId ?? null;
+
+ useEquipmentTypeInspectionPlanStore().$reset();
+
+ next();
+}
+
+export async function resetEquipmentTypeStores(to: any, from: any, next: any) {
+ const equipmentTypeStore = useEquipmentTypeStore();
+ equipmentTypeStore.activeEquipmentType = null;
+ equipmentTypeStore.activeEquipmentTypeObj = null;
+
+ useEquipmentTypeInspectionPlanStore().$reset();
+
+ next();
+}
diff --git a/src/router/unit/inspection.ts b/src/router/unit/inspection.ts
new file mode 100644
index 0000000..3c1a30f
--- /dev/null
+++ b/src/router/unit/inspection.ts
@@ -0,0 +1,20 @@
+import { useInspectionStore } from "@/stores/admin/unit/inspection/inspection";
+
+export async function setInspectionId(to: any, from: any, next: any) {
+ const inspectionStore = useInspectionStore();
+ inspectionStore.activeInspection = to.params?.inspectionId ?? null;
+
+ //useXYStore().$reset();
+
+ next();
+}
+
+export async function resetInspectionStores(to: any, from: any, next: any) {
+ const inspectionStore = useInspectionStore();
+ inspectionStore.activeInspection = null;
+ inspectionStore.activeInspectionObj = null;
+
+ //useXYStore().$reset();
+
+ next();
+}
diff --git a/src/router/unit/inspectionPlan.ts b/src/router/unit/inspectionPlan.ts
new file mode 100644
index 0000000..ad950c1
--- /dev/null
+++ b/src/router/unit/inspectionPlan.ts
@@ -0,0 +1,21 @@
+import { useInspectionPlanStore } from "@/stores/admin/unit/inspectionPlan/inspectionPlan";
+import { useInspectionPointStore } from "@/stores/admin/unit/inspectionPlan/inspectionPoint";
+
+export async function setInspectionPlanId(to: any, from: any, next: any) {
+ const inspectionPlanStore = useInspectionPlanStore();
+ inspectionPlanStore.activeInspectionPlan = to.params?.inspectionPlanId ?? null;
+
+ useInspectionPointStore().$reset();
+
+ next();
+}
+
+export async function resetInspectionPlanStores(to: any, from: any, next: any) {
+ const inspectionPlanStore = useInspectionPlanStore();
+ inspectionPlanStore.activeInspectionPlan = null;
+ inspectionPlanStore.activeInspectionPlanObj = null;
+
+ useInspectionPointStore().$reset();
+
+ next();
+}
diff --git a/src/router/unit/repair.ts b/src/router/unit/repair.ts
new file mode 100644
index 0000000..dab9374
--- /dev/null
+++ b/src/router/unit/repair.ts
@@ -0,0 +1,20 @@
+import { useRepairStore } from "@/stores/admin/unit/repair";
+
+export async function setRepairId(to: any, from: any, next: any) {
+ const repairStore = useRepairStore();
+ repairStore.activeRepair = to.params?.repairId ?? null;
+
+ //xystore().$reset();
+
+ next();
+}
+
+export async function resetRepairStores(to: any, from: any, next: any) {
+ const repairStore = useRepairStore();
+ repairStore.activeRepair = null;
+ repairStore.activeRepairObj = null;
+
+ //xystore().$reset();
+
+ next();
+}
diff --git a/src/router/unit/respiratoryGear.ts b/src/router/unit/respiratoryGear.ts
new file mode 100644
index 0000000..e681332
--- /dev/null
+++ b/src/router/unit/respiratoryGear.ts
@@ -0,0 +1,20 @@
+import { useRespiratoryGearStore } from "@/stores/admin/unit/respiratoryGear/respiratoryGear";
+
+export async function setRespiratoryGearId(to: any, from: any, next: any) {
+ const respiratoryGearStore = useRespiratoryGearStore();
+ respiratoryGearStore.activeRespiratoryGear = to.params?.respiratoryGearId ?? null;
+
+ //useXYStore().$reset();
+
+ next();
+}
+
+export async function resetRespiratoryGearStores(to: any, from: any, next: any) {
+ const respiratoryGearStore = useRespiratoryGearStore();
+ respiratoryGearStore.activeRespiratoryGear = null;
+ respiratoryGearStore.activeRespiratoryGearObj = null;
+
+ //useXYStore().$reset();
+
+ next();
+}
diff --git a/src/router/unit/respiratoryMission.ts b/src/router/unit/respiratoryMission.ts
new file mode 100644
index 0000000..25272f5
--- /dev/null
+++ b/src/router/unit/respiratoryMission.ts
@@ -0,0 +1,20 @@
+import { useRespiratoryMissionStore } from "@/stores/admin/unit/respiratoryMission/respiratoryMission";
+
+export async function setRespiratoryMissionId(to: any, from: any, next: any) {
+ const respiratoryMissionStore = useRespiratoryMissionStore();
+ respiratoryMissionStore.activeRespiratoryMission = to.params?.respiratoryMissionId ?? null;
+
+ //useXYStore().$reset();
+
+ next();
+}
+
+export async function resetRespiratoryMissionStores(to: any, from: any, next: any) {
+ const respiratoryMissionStore = useRespiratoryMissionStore();
+ respiratoryMissionStore.activeRespiratoryMission = null;
+ respiratoryMissionStore.activeRespiratoryMissionObj = null;
+
+ //useXYStore().$reset();
+
+ next();
+}
diff --git a/src/router/unit/respiratoryWearer.ts b/src/router/unit/respiratoryWearer.ts
new file mode 100644
index 0000000..6057ee5
--- /dev/null
+++ b/src/router/unit/respiratoryWearer.ts
@@ -0,0 +1,20 @@
+import { useRespiratoryWearerStore } from "@/stores/admin/unit/respiratoryWearer/respiratoryWearer";
+
+export async function setRespiratoryWearerId(to: any, from: any, next: any) {
+ const respiratoryWearerStore = useRespiratoryWearerStore();
+ respiratoryWearerStore.activeRespiratoryWearer = to.params?.respiratoryWearerId ?? null;
+
+ //useXYStore().$reset();
+
+ next();
+}
+
+export async function resetRespiratoryWearerStores(to: any, from: any, next: any) {
+ const respiratoryWearerStore = useRespiratoryWearerStore();
+ respiratoryWearerStore.activeRespiratoryWearer = null;
+ respiratoryWearerStore.activeRespiratoryWearerObj = null;
+
+ //useXYStore().$reset();
+
+ next();
+}
diff --git a/src/router/unit/vehicle.ts b/src/router/unit/vehicle.ts
new file mode 100644
index 0000000..42df6fa
--- /dev/null
+++ b/src/router/unit/vehicle.ts
@@ -0,0 +1,27 @@
+import { useVehicleStore } from "@/stores/admin/unit/vehicle/vehicle";
+import { useVehicleDamageReportStore } from "@/stores/admin/unit/vehicle/damageReport";
+import { useVehicleInspectionStore } from "@/stores/admin/unit/vehicle/inspection";
+import { useVehicleRepairStore } from "@/stores/admin/unit/vehicle/repair";
+
+export async function setVehicleId(to: any, from: any, next: any) {
+ const vehicleStore = useVehicleStore();
+ vehicleStore.activeVehicle = to.params?.vehicleId ?? null;
+
+ useVehicleDamageReportStore().$reset();
+ useVehicleInspectionStore().$reset();
+ useVehicleRepairStore().$reset();
+
+ next();
+}
+
+export async function resetVehicleStores(to: any, from: any, next: any) {
+ const vehicleStore = useVehicleStore();
+ vehicleStore.activeVehicle = null;
+ vehicleStore.activeVehicleObj = null;
+
+ useVehicleDamageReportStore().$reset();
+ useVehicleInspectionStore().$reset();
+ useVehicleRepairStore().$reset();
+
+ next();
+}
diff --git a/src/router/unit/vehicleType.ts b/src/router/unit/vehicleType.ts
new file mode 100644
index 0000000..d7418b9
--- /dev/null
+++ b/src/router/unit/vehicleType.ts
@@ -0,0 +1,21 @@
+import { useVehicleTypeStore } from "@/stores/admin/unit/vehicleType/vehicleType";
+import { useVehicleTypeInspectionPlanStore } from "@/stores/admin/unit/vehicleType/inspectionPlan";
+
+export async function setVehicleTypeId(to: any, from: any, next: any) {
+ const vehicleTypeStore = useVehicleTypeStore();
+ vehicleTypeStore.activeVehicleType = to.params?.vehicleTypeId ?? null;
+
+ useVehicleTypeInspectionPlanStore().$reset();
+
+ next();
+}
+
+export async function resetVehicleTypeStores(to: any, from: any, next: any) {
+ const vehicleTypeStore = useVehicleTypeStore();
+ vehicleTypeStore.activeVehicleType = null;
+ vehicleTypeStore.activeVehicleTypeObj = null;
+
+ useVehicleTypeInspectionPlanStore().$reset();
+
+ next();
+}
diff --git a/src/router/unit/wearable.ts b/src/router/unit/wearable.ts
new file mode 100644
index 0000000..b676831
--- /dev/null
+++ b/src/router/unit/wearable.ts
@@ -0,0 +1,27 @@
+import { useWearableStore } from "@/stores/admin/unit/wearable/wearable";
+import { useWearableDamageReportStore } from "@/stores/admin/unit/wearable/damageReport";
+import { useWearableRepairStore } from "@/stores/admin/unit/wearable/repair";
+import { useWearableInspectionStore } from "@/stores/admin/unit/wearable/inspection";
+
+export async function setWearableId(to: any, from: any, next: any) {
+ const wearableStore = useWearableStore();
+ wearableStore.activeWearable = to.params?.wearableId ?? null;
+
+ useWearableDamageReportStore().$reset();
+ useWearableInspectionStore().$reset();
+ useWearableRepairStore().$reset();
+
+ next();
+}
+
+export async function resetWearableStores(to: any, from: any, next: any) {
+ const wearableStore = useWearableStore();
+ wearableStore.activeWearable = null;
+ wearableStore.activeWearableObj = null;
+
+ useWearableDamageReportStore().$reset();
+ useWearableInspectionStore().$reset();
+ useWearableRepairStore().$reset();
+
+ next();
+}
diff --git a/src/router/unit/wearableType.ts b/src/router/unit/wearableType.ts
new file mode 100644
index 0000000..3b439ff
--- /dev/null
+++ b/src/router/unit/wearableType.ts
@@ -0,0 +1,21 @@
+import { useWearableTypeStore } from "@/stores/admin/unit/wearableType/wearableType";
+import { useWearableTypeInspectionPlanStore } from "@/stores/admin/unit/wearableType/inspectionPlan";
+
+export async function setWearableTypeId(to: any, from: any, next: any) {
+ const wearableTypeStore = useWearableTypeStore();
+ wearableTypeStore.activeWearableType = to.params?.wearableTypeId ?? null;
+
+ useWearableTypeInspectionPlanStore().$reset();
+
+ next();
+}
+
+export async function resetWearableTypeStores(to: any, from: any, next: any) {
+ const wearableTypeStore = useWearableTypeStore();
+ wearableTypeStore.activeWearableType = null;
+ wearableTypeStore.activeWearableTypeObj = null;
+
+ useWearableTypeInspectionPlanStore().$reset();
+
+ next();
+}
diff --git a/src/serverCom.ts b/src/serverCom.ts
index ad4d39f..5b10d28 100644
--- a/src/serverCom.ts
+++ b/src/serverCom.ts
@@ -78,7 +78,7 @@ http.interceptors.response.use(
}
);
-export async function refreshToken(): Promise {
+async function refreshToken(): Promise {
return new Promise(async (resolve, reject) => {
await http
.post(`/auth/refresh`, {
@@ -135,4 +135,4 @@ async function* streamingFetch(path: string, abort?: AbortController) {
}
}
-export { http, newEventSource, streamingFetch, host, url };
+export { http, newEventSource, streamingFetch, host, url, refreshToken };
diff --git a/src/socketManager.ts b/src/socketManager.ts
new file mode 100644
index 0000000..f2fd0a3
--- /dev/null
+++ b/src/socketManager.ts
@@ -0,0 +1,87 @@
+import { Manager, Socket } from "socket.io-client";
+import { refreshToken, url } from "./serverCom";
+import { useNotificationStore } from "./stores/notification";
+import { SocketConnectionTypes } from "./enums/socketEnum";
+
+export abstract class SocketManager {
+ private static readonly manager = new Manager(url, {
+ reconnection: true,
+ reconnectionDelayMax: 10000,
+ });
+ private static readonly connections = new Map();
+
+ public static establishConnection(
+ connection: SocketConnectionTypes,
+ restoreAfterDisconnect: boolean = false
+ ): Socket {
+ console.log("establish");
+ const existingSocket = this.connections.get(connection);
+ if (existingSocket !== undefined && existingSocket.connected) return existingSocket!;
+ console.log("create");
+ existingSocket?.removeAllListeners();
+
+ const notificationStore = useNotificationStore();
+ let socket = this.manager.socket(connection, {
+ auth: (cb) => {
+ cb({ token: localStorage.getItem("accessToken") });
+ },
+ });
+ socket.on("connect", () => {
+ notificationStore.push("Socket-Erfolg", `Verbindung aufgebaut`, "success");
+ });
+ socket.on("connect_error", (err) => {
+ this.socketHandleError(connection, err, true);
+ });
+ socket.on("disconnect", () => {
+ if (restoreAfterDisconnect) this.establishConnection(connection, restoreAfterDisconnect);
+ else notificationStore.push("Socket", `Verbindung getrennt`, "info");
+ });
+ socket.on("warning", (msg: string) => {
+ notificationStore.push("Socket-Warnung", msg, "warning");
+ });
+ socket.on("error", (msg: string) => {
+ this.socketHandleError(connection, {
+ name: "Error",
+ message: msg,
+ });
+ });
+
+ this.connections.set(connection, socket);
+ return socket;
+ }
+
+ public static getConnection(connection: SocketConnectionTypes) {
+ return this.connections.get(connection);
+ }
+
+ public static closeConnection(connection: SocketConnectionTypes) {
+ let socket = this.connections.get(connection);
+ if (socket) {
+ socket.removeAllListeners();
+ socket.disconnect();
+ this.connections.delete(connection);
+ }
+ }
+
+ private static socketHandleError(connection: SocketConnectionTypes, err: Error, onConnect = false) {
+ const notificationStore = useNotificationStore();
+
+ if (err.message == "xhr poll error") {
+ notificationStore.push("Socket-Netzwerk-Fehler", "Reconnect Versuch in 10s", "error");
+ } else if (err.message == "Token expired") {
+ notificationStore.push("Session", "Session wird verlängert", "info");
+ refreshToken()
+ .then(() => {
+ notificationStore.push("Session", "Session erfolgreich verlängert", "success");
+ this.closeConnection(connection);
+ })
+ .catch(() => {
+ notificationStore.push("Session-Fehler", "Anmeldung wurde nicht verlängert", "error");
+ });
+ } else if (onConnect) {
+ notificationStore.push("Socket-Fehler", `Verbindung fehlgeschlagen`, "error");
+ } else {
+ notificationStore.push("Socket-Fehler", err.message, "error");
+ }
+ }
+}
diff --git a/src/stores/admin/navigation.ts b/src/stores/admin/navigation.ts
index 566fccd..59f5df2 100644
--- a/src/stores/admin/navigation.ts
+++ b/src/stores/admin/navigation.ts
@@ -62,6 +62,15 @@ export const useNavigationStore = defineStore("navigation", {
} as topLevelNavigationModel,
]
: []),
+ ...(abilityStore.canAccessSection("unit")
+ ? [
+ {
+ key: "unit",
+ title: "Wehr",
+ levelDefault: "equipment",
+ } as topLevelNavigationModel,
+ ]
+ : []),
...(abilityStore.canAccessSection("configuration")
? [
{
@@ -100,8 +109,46 @@ export const useNavigationStore = defineStore("navigation", {
...(abilityStore.can("read", "club", "listprint") ? [{ key: "listprint", title: "Liste Drucken" }] : []),
],
},
+ unit: {
+ mainTitle: "Wehr",
+ main: [
+ ...(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" }] : []),
+ ...(false && abilityStore.can("read", "unit", "respiratory_gear")
+ ? [{ key: "respiratory_gear", title: "Atemschutz-Geräte" }]
+ : []),
+ ...(false && abilityStore.can("read", "unit", "respiratory_wearer")
+ ? [{ key: "respiratory_wearer", title: "Atemschutz-Träger" }]
+ : []),
+ ...(false && abilityStore.can("read", "unit", "respiratory_mission")
+ ? [{ key: "respiratory_mission", title: "Atemschutz-Einsätze" }]
+ : []),
+ ...(abilityStore.can("create", "unit", "inspection") ? [{ key: "inspection", title: "Prüfungen" }] : []),
+ ...(false && abilityStore.can("read", "unit", "maintenance")
+ ? [{ key: "maintenance", title: "Wartungen" }]
+ : []),
+ ...(abilityStore.can("read", "unit", "damage_report")
+ ? [{ key: "damage_report", title: "Schadensmeldungen" }]
+ : []),
+ ...(abilityStore.can("read", "unit", "repair") ? [{ key: "repair", title: "Reparaturen" }] : []),
+ { key: "divider1", title: "Basisdaten" },
+ ...(abilityStore.can("read", "unit", "equipment_type")
+ ? [{ key: "equipment_type", title: "Geräte-Typen" }]
+ : []),
+ ...(abilityStore.can("read", "unit", "vehicle_type")
+ ? [{ key: "vehicle_type", title: "Fahrzeug-Arten" }]
+ : []),
+ ...(abilityStore.can("read", "unit", "wearable_type")
+ ? [{ key: "wearable_type", title: "Kleidungs-Arten" }]
+ : []),
+ ...(abilityStore.can("read", "unit", "inspection_plan")
+ ? [{ key: "inspection_plan", title: "Prüfpläne" }]
+ : []),
+ ],
+ },
configuration: {
- mainTitle: "Einstellungen",
+ mainTitle: "Konfiguration",
main: [
{ key: "divider1", title: "Mitgliederdaten" },
...(abilityStore.can("read", "configuration", "salutation")
diff --git a/src/stores/admin/scanner.ts b/src/stores/admin/scanner.ts
new file mode 100644
index 0000000..b2e3b16
--- /dev/null
+++ b/src/stores/admin/scanner.ts
@@ -0,0 +1,58 @@
+import { defineStore } from "pinia";
+import { v4 as uuid } from "uuid";
+import { SocketManager } from "@/socketManager";
+import { SocketConnectionTypes } from "@/enums/socketEnum";
+import { useNotificationStore } from "../notification";
+
+export const useScannerStore = defineStore("scanner", {
+ state: () => {
+ return {
+ inUse: false as boolean,
+ roomId: undefined as undefined | string,
+ results: [] as Array,
+ connectedDevices: 0 as number,
+ };
+ },
+ actions: {
+ startSession() {
+ if (this.inUse) return;
+
+ const notificationStore = useNotificationStore();
+
+ this.roomId = uuid();
+ this.inUse = true;
+ let connection = SocketManager.establishConnection(SocketConnectionTypes.scanner);
+ connection.on("connect", () => {
+ SocketManager.getConnection(SocketConnectionTypes.scanner)?.emit("session:create", this.roomId);
+ });
+ connection.on("status-session:create", () => {
+ notificationStore.push("Socket-Erfolg", `Scan-Session gestartet`, "success");
+ });
+ connection.on("status-session:close", () => {
+ notificationStore.push("Socket", `Scan-Session beendet`, "info");
+ SocketManager.getConnection(SocketConnectionTypes.scanner)?.disconnect();
+ });
+ connection.on("package-scanner_join", (socketId: string) => {
+ this.connectedDevices++;
+ notificationStore.push("Scan-Verbindung", `Neuer Scanner verbunden`, "info");
+ });
+ connection.on("package-scanner_leave", (socketId: string) => {
+ this.connectedDevices--;
+ notificationStore.push("Scan-Verbindung", `Scanner getrennt`, "info");
+ });
+ connection.on("package-scan_receive", (result: string) => {
+ this.results.push(result);
+ notificationStore.push("Scan", `Neuen Scan erhalten`, "info");
+ });
+ },
+ endSession() {
+ this.inUse = false;
+ this.roomId = undefined;
+ this.results = [];
+ SocketManager.getConnection(SocketConnectionTypes.scanner)?.emit("session:close");
+ },
+ removeElementFromResults(el: string) {
+ this.results = this.results.filter((result) => result !== el);
+ },
+ },
+});
diff --git a/src/stores/admin/unit/damageReport.ts b/src/stores/admin/unit/damageReport.ts
new file mode 100644
index 0000000..d7a458a
--- /dev/null
+++ b/src/stores/admin/unit/damageReport.ts
@@ -0,0 +1,123 @@
+import { defineStore } from "pinia";
+import type { DamageReportViewModel, UpdateDamageReportViewModel } from "@/viewmodels/admin/unit/damageReport.models";
+import { http } from "@/serverCom";
+import type { AxiosResponse } from "axios";
+
+export const useDamageReportStore = defineStore("damageReport", {
+ state: () => {
+ return {
+ damageReports: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ activeDamageReport: null as string | null,
+ activeDamageReportObj: null as DamageReportViewModel | null,
+ loadingActive: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ formatQueryReturnToPagination(result: AxiosResponse, offset: number) {
+ this.totalCount = result.data.total;
+ result.data.damageReports
+ .filter((elem: DamageReportViewModel) => this.damageReports.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: DamageReportViewModel, index: number): DamageReportViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: DamageReportViewModel & { tab_pos: number }) => {
+ this.damageReports.push(elem);
+ });
+ },
+ fetchOpenDamageReports(offset = 0, count = 25, search = "", clear = false) {
+ if (clear) this.damageReports = [];
+ this.loading = "loading";
+ http
+ .get(`/admin/damageReport?done=false&offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`)
+ .then((result) => {
+ this.formatQueryReturnToPagination(result, offset);
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ fetchDoneDamageReports(offset = 0, count = 25, search = "", clear = false) {
+ if (clear) this.damageReports = [];
+ this.loading = "loading";
+ http
+ .get(`/admin/damageReport?done=true&offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`)
+ .then((result) => {
+ this.formatQueryReturnToPagination(result, offset);
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ async getAllDamageReports(): Promise> {
+ return await http.get(`/admin/damageReport?noLimit=true`).then((res) => {
+ return { ...res, data: res.data.damageReports };
+ });
+ },
+ async getDamageReportsByIds(ids: Array): Promise> {
+ return await http
+ .post(`/admin/damageReport/ids`, {
+ ids,
+ })
+ .then((res) => {
+ return { ...res, data: res.data.damageReports };
+ });
+ },
+ async searchDamageReports(search: string): Promise> {
+ return await http.get(`/admin/damageReport?search=${search}&noLimit=true`).then((res) => {
+ return { ...res, data: res.data.damageReports };
+ });
+ },
+ async getAllDamageReportsWithRelated(
+ related: "vehicle" | "equipment" | "wearable",
+ relatedId: string
+ ): Promise> {
+ return await http.get(`/admin/damageReport/${related}/${relatedId}?noLimit=true`).then((res) => {
+ return { ...res, data: res.data.damageReports };
+ });
+ },
+ async searchDamageReportsWithRelated(
+ related: "vehicle" | "equipment" | "wearable",
+ relatedId: string,
+ search: string
+ ): Promise> {
+ return await http.get(`/admin/damageReport/${related}/${relatedId}?search=${search}&noLimit=true`).then((res) => {
+ return { ...res, data: res.data.damageReports };
+ });
+ },
+ fetchDamageReportByActiveId() {
+ this.loadingActive = "loading";
+ http
+ .get(`/admin/damageReport/${this.activeDamageReport}`)
+ .then((res) => {
+ this.activeDamageReportObj = res.data;
+ this.loadingActive = "fetched";
+ })
+ .catch((err) => {
+ this.loadingActive = "failed";
+ });
+ },
+ fetchDamageReportById(id: string) {
+ return http.get(`/admin/damageReport/${id}`);
+ },
+ loadDamageReportImage(url: string) {
+ return http.get(`/admin/damageReport/${this.activeDamageReportObj?.id}/${url}`, {
+ responseType: "blob",
+ });
+ },
+ async updateDamageReport(damageReport: UpdateDamageReportViewModel): Promise> {
+ const result = await http.patch(`/admin/damageReport/${damageReport.id}`, {
+ status: damageReport.status,
+ noteByWorker: damageReport.noteByWorker,
+ done: damageReport.done,
+ });
+ return result;
+ },
+ },
+});
diff --git a/src/stores/admin/unit/equipment/damageReport.ts b/src/stores/admin/unit/equipment/damageReport.ts
new file mode 100644
index 0000000..9460582
--- /dev/null
+++ b/src/stores/admin/unit/equipment/damageReport.ts
@@ -0,0 +1,43 @@
+import { defineStore } from "pinia";
+import { http } from "@/serverCom";
+import { useEquipmentStore } from "./equipment";
+import type { DamageReportViewModel } from "@/viewmodels/admin/unit/damageReport.models";
+
+export const useEquipmentDamageReportStore = defineStore("equipmentDamageReport", {
+ state: () => {
+ return {
+ damageReports: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchDamageReportForEquipment(offset = 0, count = 25, search = "", clear = false) {
+ const equipmentId = useEquipmentStore().activeEquipment;
+ if (clear) this.damageReports = [];
+ this.loading = "loading";
+ http
+ .get(
+ `/admin/damagereport/equipment/${equipmentId}?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`
+ )
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.damageReports
+ .filter((elem: DamageReportViewModel) => this.damageReports.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: DamageReportViewModel, index: number): DamageReportViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: DamageReportViewModel & { tab_pos: number }) => {
+ this.damageReports.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ },
+});
diff --git a/src/stores/admin/unit/equipment/equipment.ts b/src/stores/admin/unit/equipment/equipment.ts
new file mode 100644
index 0000000..67e92c0
--- /dev/null
+++ b/src/stores/admin/unit/equipment/equipment.ts
@@ -0,0 +1,108 @@
+import { defineStore } from "pinia";
+import type {
+ EquipmentViewModel,
+ CreateEquipmentViewModel,
+ UpdateEquipmentViewModel,
+} from "@/viewmodels/admin/unit/equipment/equipment.models";
+import { http } from "@/serverCom";
+import type { AxiosResponse } from "axios";
+
+export const useEquipmentStore = defineStore("equipment", {
+ state: () => {
+ return {
+ equipments: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ activeEquipment: null as string | null,
+ activeEquipmentObj: null as EquipmentViewModel | null,
+ loadingActive: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchEquipments(offset = 0, count = 25, search = "", clear = false) {
+ if (clear) this.equipments = [];
+ this.loading = "loading";
+ http
+ .get(`/admin/equipment?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`)
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.equipments
+ .filter((elem: EquipmentViewModel) => this.equipments.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: EquipmentViewModel, index: number): EquipmentViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: EquipmentViewModel & { tab_pos: number }) => {
+ this.equipments.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ async getAllEquipments(): Promise> {
+ return await http.get(`/admin/equipment?noLimit=true`).then((res) => {
+ return { ...res, data: res.data.equipments };
+ });
+ },
+ async getEquipmentsByIds(ids: Array): Promise> {
+ return await http
+ .post(`/admin/equipment/ids`, {
+ ids,
+ })
+ .then((res) => {
+ return { ...res, data: res.data.equipments };
+ });
+ },
+ async searchEquipments(search: string): Promise> {
+ return await http.get(`/admin/equipment?search=${search}&noLimit=true`).then((res) => {
+ return { ...res, data: res.data.equipments };
+ });
+ },
+ fetchEquipmentByActiveId() {
+ this.loadingActive = "loading";
+ http
+ .get(`/admin/equipment/${this.activeEquipment}`)
+ .then((res) => {
+ this.activeEquipmentObj = res.data;
+ this.loadingActive = "fetched";
+ })
+ .catch((err) => {
+ this.loadingActive = "failed";
+ });
+ },
+ fetchEquipmentById(id: string) {
+ return http.get(`/admin/equipment/${id}`);
+ },
+ async createEquipment(equipment: CreateEquipmentViewModel): Promise> {
+ const result = await http.post(`/admin/equipment`, {
+ equipmentTypeId: equipment.equipmentTypeId,
+ name: equipment.name,
+ code: equipment.code,
+ location: equipment.location,
+ commissioned: equipment.commissioned,
+ });
+ this.fetchEquipments();
+ return result;
+ },
+ async updateActiveEquipment(equipment: UpdateEquipmentViewModel): Promise> {
+ const result = await http.patch(`/admin/equipment/${equipment.id}`, {
+ name: equipment.name,
+ code: equipment.code,
+ location: equipment.location,
+ commissioned: equipment.commissioned,
+ decommissioned: equipment.decommissioned,
+ });
+ this.fetchEquipments();
+ return result;
+ },
+ async deleteEquipment(equipment: number): Promise> {
+ const result = await http.delete(`/admin/equipment/${equipment}`);
+ this.fetchEquipments();
+ return result;
+ },
+ },
+});
diff --git a/src/stores/admin/unit/equipment/inspection.ts b/src/stores/admin/unit/equipment/inspection.ts
new file mode 100644
index 0000000..adbe911
--- /dev/null
+++ b/src/stores/admin/unit/equipment/inspection.ts
@@ -0,0 +1,41 @@
+import { defineStore } from "pinia";
+import { http } from "@/serverCom";
+import type { InspectionViewModel } from "@/viewmodels/admin/unit/inspection/inspection.models";
+import { useEquipmentStore } from "./equipment";
+
+export const useEquipmentInspectionStore = defineStore("equipmentInspection", {
+ state: () => {
+ return {
+ inspections: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchInspectionForEquipment(offset = 0, count = 25, clear = false) {
+ const equipmentId = useEquipmentStore().activeEquipment;
+ if (clear) this.inspections = [];
+ this.loading = "loading";
+ http
+ .get(`/admin/inspection/equipment/${equipmentId}?offset=${offset}&count=${count}`)
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.inspections
+ .filter((elem: InspectionViewModel) => this.inspections.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: InspectionViewModel, index: number): InspectionViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: InspectionViewModel & { tab_pos: number }) => {
+ this.inspections.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ },
+});
diff --git a/src/stores/admin/unit/equipment/repair.ts b/src/stores/admin/unit/equipment/repair.ts
new file mode 100644
index 0000000..a3db4ba
--- /dev/null
+++ b/src/stores/admin/unit/equipment/repair.ts
@@ -0,0 +1,43 @@
+import { defineStore } from "pinia";
+import { http } from "@/serverCom";
+import { useEquipmentStore } from "./equipment";
+import type { RepairViewModel } from "@/viewmodels/admin/unit/repair.models";
+
+export const useEquipmentRepairStore = defineStore("equipmentRepair", {
+ state: () => {
+ return {
+ repairs: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchRepairForEquipment(offset = 0, count = 25, search = "", clear = false) {
+ const equipmentId = useEquipmentStore().activeEquipment;
+ if (clear) this.repairs = [];
+ this.loading = "loading";
+ http
+ .get(
+ `/admin/repair/equipment/${equipmentId}?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`
+ )
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.repairs
+ .filter((elem: RepairViewModel) => this.repairs.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: RepairViewModel, index: number): RepairViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: RepairViewModel & { tab_pos: number }) => {
+ this.repairs.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ },
+});
diff --git a/src/stores/admin/unit/equipmentType/equipmentType.ts b/src/stores/admin/unit/equipmentType/equipmentType.ts
new file mode 100644
index 0000000..694e635
--- /dev/null
+++ b/src/stores/admin/unit/equipmentType/equipmentType.ts
@@ -0,0 +1,93 @@
+import { defineStore } from "pinia";
+import type {
+ EquipmentTypeViewModel,
+ CreateEquipmentTypeViewModel,
+ UpdateEquipmentTypeViewModel,
+} from "@/viewmodels/admin/unit/equipment/equipmentType.models";
+import { http } from "@/serverCom";
+import type { AxiosResponse } from "axios";
+
+export const useEquipmentTypeStore = defineStore("equipmentType", {
+ state: () => {
+ return {
+ equipmentTypes: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ activeEquipmentType: null as string | null,
+ activeEquipmentTypeObj: null as EquipmentTypeViewModel | null,
+ loadingActive: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchEquipmentTypes(offset = 0, count = 25, search = "", clear = false) {
+ if (clear) this.equipmentTypes = [];
+ this.loading = "loading";
+ http
+ .get(`/admin/equipmentType?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`)
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.equipmentTypes
+ .filter((elem: EquipmentTypeViewModel) => this.equipmentTypes.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: EquipmentTypeViewModel, index: number): EquipmentTypeViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: EquipmentTypeViewModel & { tab_pos: number }) => {
+ this.equipmentTypes.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ async getAllEquipmentTypes(): Promise> {
+ return await http.get(`/admin/equipmentType?noLimit=true`).then((res) => {
+ return { ...res, data: res.data.equipmentTypes };
+ });
+ },
+ async searchEquipmentTypes(search: string): Promise> {
+ return await http.get(`/admin/equipmentType?search=${search}&noLimit=true`).then((res) => {
+ return { ...res, data: res.data.equipmentTypes };
+ });
+ },
+ fetchEquipmentTypeByActiveId() {
+ this.loadingActive = "loading";
+ http
+ .get(`/admin/equipmentType/${this.activeEquipmentType}`)
+ .then((res) => {
+ this.activeEquipmentTypeObj = res.data;
+ this.loadingActive = "fetched";
+ })
+ .catch((err) => {
+ this.loadingActive = "failed";
+ });
+ },
+ fetchEquipmentTypeById(id: string) {
+ return http.get(`/admin/equipmentType/${id}`);
+ },
+ async createEquipmentType(equipmentType: CreateEquipmentTypeViewModel): Promise> {
+ const result = await http.post(`/admin/equipmentType`, {
+ type: equipmentType.type,
+ description: equipmentType.description,
+ });
+ this.fetchEquipmentTypes();
+ return result;
+ },
+ async updateActiveEquipmentType(equipmentType: UpdateEquipmentTypeViewModel): Promise> {
+ const result = await http.patch(`/admin/equipmentType/${equipmentType.id}`, {
+ type: equipmentType.type,
+ description: equipmentType.description,
+ });
+ this.fetchEquipmentTypes();
+ return result;
+ },
+ async deleteEquipmentType(equipmentType: number): Promise> {
+ const result = await http.delete(`/admin/equipmentType/${equipmentType}`);
+ this.fetchEquipmentTypes();
+ return result;
+ },
+ },
+});
diff --git a/src/stores/admin/unit/equipmentType/inspectionPlan.ts b/src/stores/admin/unit/equipmentType/inspectionPlan.ts
new file mode 100644
index 0000000..0496cd3
--- /dev/null
+++ b/src/stores/admin/unit/equipmentType/inspectionPlan.ts
@@ -0,0 +1,28 @@
+import { defineStore } from "pinia";
+import { http } from "@/serverCom";
+import type { InspectionPlanViewModel } from "@/viewmodels/admin/unit/inspection/inspectionPlan.models";
+import { useEquipmentTypeStore } from "./equipmentType";
+
+export const useEquipmentTypeInspectionPlanStore = defineStore("equipmentTypeInspectionPlan", {
+ state: () => {
+ return {
+ inspectionPlans: [] as Array,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchInspectionPlanForEquipmentType() {
+ const equipmentTypeId = useEquipmentTypeStore().activeEquipmentType;
+ this.loading = "loading";
+ http
+ .get(`/admin/inspectionPlan/equipmentType/${equipmentTypeId}?noLimit=true`)
+ .then((result) => {
+ this.inspectionPlans = result.data.inspectionPlans;
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ },
+});
diff --git a/src/stores/admin/unit/inspection/inspection.ts b/src/stores/admin/unit/inspection/inspection.ts
new file mode 100644
index 0000000..7da24c4
--- /dev/null
+++ b/src/stores/admin/unit/inspection/inspection.ts
@@ -0,0 +1,151 @@
+import { defineStore } from "pinia";
+import { http } from "@/serverCom";
+import type { AxiosResponse } from "axios";
+import type {
+ CreateInspectionViewModel,
+ CreateOrUpdateInspectionPointResultCommand,
+ InspectionNextViewModel,
+ InspectionViewModel,
+ MinifiedInspectionViewModel,
+ UpdateInspectionViewModel,
+} from "@/viewmodels/admin/unit/inspection/inspection.models";
+
+export const useInspectionStore = defineStore("inspection", {
+ state: () => {
+ return {
+ inspections: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ nextInspections: [] as Array,
+ nextTotalCount: 0 as number,
+ nextLoading: "loading" as "loading" | "fetched" | "failed",
+ activeInspection: null as string | null,
+ activeInspectionObj: null as InspectionViewModel | null,
+ loadingActive: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchRunningInspections(offset = 0, count = 25, search = "", clear = false) {
+ if (clear) this.inspections = [];
+ this.loading = "loading";
+ http
+ .get(`/admin/inspection/running?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`)
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.inspections
+ .filter((elem: MinifiedInspectionViewModel) => this.inspections.findIndex((m) => m.id == elem.id) == -1)
+ .map(
+ (elem: MinifiedInspectionViewModel, index: number): MinifiedInspectionViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ }
+ )
+ .forEach((elem: MinifiedInspectionViewModel & { tab_pos: number }) => {
+ this.inspections.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ fetchNextInspections(offset = 0, count = 25, search = "", clear = false) {
+ if (clear) this.nextInspections = [];
+ this.nextLoading = "loading";
+ http
+ .get(`/admin/inspection/next?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`)
+ .then((result) => {
+ this.nextTotalCount = result.data.total;
+ result.data.inspections
+ .filter((elem: InspectionNextViewModel) => this.nextInspections.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: InspectionNextViewModel, index: number): InspectionNextViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: InspectionNextViewModel & { tab_pos: number }) => {
+ this.nextInspections.push(elem);
+ });
+ this.nextLoading = "fetched";
+ })
+ .catch((err) => {
+ this.nextLoading = "failed";
+ });
+ },
+ fetchInspectionByActiveId() {
+ this.loadingActive = "loading";
+ http
+ .get(`/admin/inspection/${this.activeInspection}`)
+ .then((res) => {
+ this.activeInspectionObj = res.data;
+ this.loadingActive = "fetched";
+ })
+ .catch((err) => {
+ this.loadingActive = "failed";
+ });
+ },
+ fetchInspectionById(id: string) {
+ return http.get(`/admin/inspection/${id}`);
+ },
+ fetchInspectionPrintoutById() {
+ return http.get(`/admin/inspection/${this.activeInspectionObj?.id}/printout`, {
+ responseType: "blob",
+ });
+ },
+ fetchUploadedFileByPointId(id: string) {
+ return http.get(`/admin/inspection/${this.activeInspectionObj?.id}/${id}/upload`, {
+ responseType: "blob",
+ });
+ },
+ async createInspection(inspection: CreateInspectionViewModel): Promise> {
+ const result = await http.post(`/admin/inspection`, {
+ assigned: inspection.assigned,
+ relatedId: inspection.relatedId,
+ inspectionPlanId: inspection.inspectionPlanId,
+ nextInspection: inspection.nextInspection,
+ context: inspection.context,
+ });
+ return result;
+ },
+ async updateActiveInspection(inspection: UpdateInspectionViewModel): Promise> {
+ const result = await http.patch(`/admin/inspection/${this.activeInspection}`, {
+ nextInspection: inspection.nextInspection,
+ context: inspection.context,
+ });
+ this.fetchInspectionByActiveId();
+ return result;
+ },
+ async updateActiveInspectionResults(
+ results: Array,
+ files: { [key: string]: File | null }
+ ): Promise> {
+ 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> {
+ const result = await http.patch(`/admin/inspection/${this.activeInspection}/finish`);
+ this.fetchInspectionByActiveId();
+ return result;
+ },
+ async deleteInspection(inspection: string): Promise> {
+ const result = await http.delete(`/admin/inspection/${inspection}`);
+ return result;
+ },
+ },
+});
diff --git a/src/stores/admin/unit/inspectionPlan/inspectionPlan.ts b/src/stores/admin/unit/inspectionPlan/inspectionPlan.ts
new file mode 100644
index 0000000..a30f6e3
--- /dev/null
+++ b/src/stores/admin/unit/inspectionPlan/inspectionPlan.ts
@@ -0,0 +1,116 @@
+import { defineStore } from "pinia";
+import type {
+ InspectionPlanViewModel,
+ CreateInspectionPlanViewModel,
+ UpdateInspectionPlanViewModel,
+} from "@/viewmodels/admin/unit/inspection/inspectionPlan.models";
+import { http } from "@/serverCom";
+import type { AxiosResponse } from "axios";
+
+export const useInspectionPlanStore = defineStore("inspectionPlan", {
+ state: () => {
+ return {
+ inspectionPlans: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ activeInspectionPlan: null as string | null,
+ activeInspectionPlanObj: null as InspectionPlanViewModel | null,
+ loadingActive: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchInspectionPlans(offset = 0, count = 25, search = "", clear = false) {
+ if (clear) this.inspectionPlans = [];
+ this.loading = "loading";
+ http
+ .get(`/admin/inspectionPlan?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`)
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.inspectionPlans
+ .filter((elem: InspectionPlanViewModel) => this.inspectionPlans.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: InspectionPlanViewModel, index: number): InspectionPlanViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: InspectionPlanViewModel & { tab_pos: number }) => {
+ this.inspectionPlans.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ async getAllInspectionPlans(): Promise> {
+ return await http.get(`/admin/inspectionPlan?noLimit=true`).then((res) => {
+ return { ...res, data: res.data.inspectionPlans };
+ });
+ },
+ async searchInspectionPlans(search: string): Promise> {
+ return await http.get(`/admin/inspectionPlan?search=${search}&noLimit=true`).then((res) => {
+ return { ...res, data: res.data.inspectionPlans };
+ });
+ },
+ async getAllInspectionPlansWithRelated(
+ related: "vehicleType" | "equipmentType" | "wearableType",
+ relatedId: string
+ ): Promise> {
+ return await http.get(`/admin/inspectionPlan/${related}/${relatedId}?noLimit=true`).then((res) => {
+ return { ...res, data: res.data.inspectionPlans };
+ });
+ },
+ async searchInspectionPlansWithRelated(
+ related: "vehicleType" | "equipmentType" | "wearableType",
+ relatedId: string,
+ search: string
+ ): Promise> {
+ return await http
+ .get(`/admin/inspectionPlan/${related}/${relatedId}?search=${search}&noLimit=true`)
+ .then((res) => {
+ return { ...res, data: res.data.inspectionPlans };
+ });
+ },
+ fetchInspectionPlanByActiveId() {
+ this.loadingActive = "loading";
+ http
+ .get(`/admin/inspectionPlan/${this.activeInspectionPlan}`)
+ .then((res) => {
+ this.activeInspectionPlanObj = res.data;
+ this.loadingActive = "fetched";
+ })
+ .catch((err) => {
+ this.loadingActive = "failed";
+ });
+ },
+ fetchInspectionPlanById(id: string) {
+ return http.get(`/admin/inspectionPlan/${id}`);
+ },
+ async createInspectionPlan(inspectionPlan: CreateInspectionPlanViewModel): Promise> {
+ const result = await http.post(`/admin/inspectionPlan`, {
+ title: inspectionPlan.title,
+ inspectionInterval: inspectionPlan.inspectionInterval,
+ remindTime: inspectionPlan.remindTime,
+ relatedId: inspectionPlan.relatedId,
+ assigned: inspectionPlan.assigned,
+ });
+ this.fetchInspectionPlans();
+ return result;
+ },
+ async updateActiveInspectionPlan(inspectionPlan: UpdateInspectionPlanViewModel): Promise> {
+ const result = await http.patch(`/admin/inspectionPlan/${inspectionPlan.id}`, {
+ title: inspectionPlan.title,
+ inspectionInterval: inspectionPlan.inspectionInterval,
+ remindTime: inspectionPlan.remindTime,
+ });
+ this.fetchInspectionPlans();
+ return result;
+ },
+ async deleteInspectionPlan(inspectionPlan: number): Promise> {
+ const result = await http.delete(`/admin/inspectionPlan/${inspectionPlan}`);
+ this.fetchInspectionPlans();
+ return result;
+ },
+ },
+});
diff --git a/src/stores/admin/unit/inspectionPlan/inspectionPoint.ts b/src/stores/admin/unit/inspectionPlan/inspectionPoint.ts
new file mode 100644
index 0000000..7ce669e
--- /dev/null
+++ b/src/stores/admin/unit/inspectionPlan/inspectionPoint.ts
@@ -0,0 +1,37 @@
+import { defineStore } from "pinia";
+import type { InspectionPointViewModel } from "@/viewmodels/admin/unit/inspection/inspectionPlan.models";
+import { http } from "@/serverCom";
+import type { AxiosResponse } from "axios";
+import { useInspectionPlanStore } from "./inspectionPlan";
+
+export const useInspectionPointStore = defineStore("inspectionPoint", {
+ state: () => {
+ return {
+ inspectionPoints: [] as Array,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchInspectionPoints() {
+ const inspectionPlanId = useInspectionPlanStore().activeInspectionPlan;
+ this.loading = "loading";
+ http
+ .get(`/admin/inspectionPlan/${inspectionPlanId}/points`)
+ .then((result) => {
+ this.inspectionPoints = result.data;
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ async updateActiveInspectionPoints(
+ inspectionPoints: Array
+ ): Promise> {
+ const inspectionPlanId = useInspectionPlanStore().activeInspectionPlan;
+ const result = await http.patch(`/admin/inspectionPlan/${inspectionPlanId}/points`, inspectionPoints);
+ this.fetchInspectionPoints();
+ return result;
+ },
+ },
+});
diff --git a/src/stores/admin/unit/maintenance.ts b/src/stores/admin/unit/maintenance.ts
new file mode 100644
index 0000000..fd9fb79
--- /dev/null
+++ b/src/stores/admin/unit/maintenance.ts
@@ -0,0 +1,74 @@
+import { defineStore } from "pinia";
+import type {
+ MaintenanceViewModel,
+ CreateMaintenanceViewModel,
+ UpdateMaintenanceViewModel,
+} from "@/viewmodels/admin/unit/maintenance.models";
+import { http } from "@/serverCom";
+import type { AxiosResponse } from "axios";
+
+export const useMaintenanceStore = defineStore("maintenance", {
+ state: () => {
+ return {
+ maintenances: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchMaintenances(offset = 0, count = 25, search = "", clear = false) {
+ if (clear) this.maintenances = [];
+ this.loading = "loading";
+ //TODO enable fetch of done reports
+ http
+ .get(`/admin/maintenance?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`)
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.maintenances
+ .filter((elem: MaintenanceViewModel) => this.maintenances.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: MaintenanceViewModel, index: number): MaintenanceViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: MaintenanceViewModel & { tab_pos: number }) => {
+ this.maintenances.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ async getAllMaintenances(): Promise> {
+ return await http.get(`/admin/maintenance?noLimit=true`).then((res) => {
+ return { ...res, data: res.data.maintenances };
+ });
+ },
+ async getMaintenancesByIds(ids: Array): Promise> {
+ return await http
+ .post(`/admin/maintenance/ids`, {
+ ids,
+ })
+ .then((res) => {
+ return { ...res, data: res.data.maintenances };
+ });
+ },
+ async searchMaintenances(search: string): Promise> {
+ return await http.get(`/admin/maintenance?search=${search}&noLimit=true`).then((res) => {
+ return { ...res, data: res.data.maintenances };
+ });
+ },
+ fetchMaintenanceById(id: string) {
+ return http.get(`/admin/maintenance/${id}`);
+ },
+ async updateMaintenance(maintenance: UpdateMaintenanceViewModel): Promise> {
+ const result = await http.patch(`/admin/maintenance/${maintenance.id}`, {
+ // TODO: data
+ });
+ this.fetchMaintenances();
+ return result;
+ },
+ },
+});
diff --git a/src/stores/admin/unit/repair.ts b/src/stores/admin/unit/repair.ts
new file mode 100644
index 0000000..acf30c9
--- /dev/null
+++ b/src/stores/admin/unit/repair.ts
@@ -0,0 +1,135 @@
+import { defineStore } from "pinia";
+import type {
+ CreateRepairViewModel,
+ RepairViewModel,
+ UpdateRepairStatusViewModel,
+ UpdateRepairViewModel,
+} from "@/viewmodels/admin/unit/repair.models";
+import { http } from "@/serverCom";
+import type { AxiosResponse } from "axios";
+
+export const useRepairStore = defineStore("repair", {
+ state: () => {
+ return {
+ repairs: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ activeRepair: null as string | null,
+ activeRepairObj: null as RepairViewModel | null,
+ loadingActive: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ formatQueryReturnToPagination(result: AxiosResponse, offset: number) {
+ this.totalCount = result.data.total;
+ result.data.repairs
+ .filter((elem: RepairViewModel) => this.repairs.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: RepairViewModel, index: number): RepairViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: RepairViewModel & { tab_pos: number }) => {
+ this.repairs.push(elem);
+ });
+ },
+ fetchOpenRepairs(offset = 0, count = 25, search = "", clear = false) {
+ if (clear) this.repairs = [];
+ this.loading = "loading";
+ http
+ .get(`/admin/repair?done=false&offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`)
+ .then((result) => {
+ this.formatQueryReturnToPagination(result, offset);
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ fetchDoneRepairs(offset = 0, count = 25, search = "", clear = false) {
+ if (clear) this.repairs = [];
+ this.loading = "loading";
+ http
+ .get(`/admin/repair?done=true&offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`)
+ .then((result) => {
+ this.formatQueryReturnToPagination(result, offset);
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ async getAllRepairs(): Promise> {
+ return await http.get(`/admin/repair?noLimit=true`).then((res) => {
+ return { ...res, data: res.data.repairs };
+ });
+ },
+ async getRepairsByIds(ids: Array): Promise> {
+ return await http
+ .post(`/admin/repair/ids`, {
+ ids,
+ })
+ .then((res) => {
+ return { ...res, data: res.data.repairs };
+ });
+ },
+ async searchRepairs(search: string): Promise> {
+ return await http.get(`/admin/repair?search=${search}&noLimit=true`).then((res) => {
+ return { ...res, data: res.data.repairs };
+ });
+ },
+ fetchRepairByActiveId() {
+ this.loadingActive = "loading";
+ http
+ .get(`/admin/repair/${this.activeRepair}`)
+ .then((res) => {
+ this.activeRepairObj = res.data;
+ this.loadingActive = "fetched";
+ })
+ .catch((err) => {
+ this.loadingActive = "failed";
+ });
+ },
+ fetchRepairById(id: string) {
+ return http.get(`/admin/repair/${id}`);
+ },
+ loadRepairImage(url: string) {
+ return http.get(`/admin/repair/${this.activeRepairObj?.id}/${url}`, {
+ responseType: "blob",
+ });
+ },
+ async createRepair(repair: CreateRepairViewModel): Promise> {
+ const result = await http.post(`/admin/repair`, {
+ affected: repair.affected,
+ affectedId: repair.affectedId,
+ title: repair.title,
+ description: repair.description,
+ responsible: repair.responsible,
+ reports: repair.reports,
+ });
+ return result;
+ },
+ async updateRepair(repair: UpdateRepairViewModel): Promise> {
+ const result = await http.patch(`/admin/repair/${this.activeRepairObj?.id}`, {
+ title: repair.title,
+ description: repair.description,
+ responsible: repair.responsible,
+ });
+ return result;
+ },
+ async updateRepairReports(reports: Array): Promise> {
+ const result = await http.patch(`/admin/repair/${this.activeRepairObj?.id}/reports`, {
+ reports,
+ });
+ return result;
+ },
+ async updateRepairStatus(repair: UpdateRepairStatusViewModel): Promise> {
+ const result = await http.patch(`/admin/repair/${this.activeRepairObj?.id}/status`, {
+ status: repair.status,
+ done: repair.done,
+ });
+ return result;
+ },
+ },
+});
diff --git a/src/stores/admin/unit/respiratoryGear/respiratoryGear.ts b/src/stores/admin/unit/respiratoryGear/respiratoryGear.ts
new file mode 100644
index 0000000..a49110c
--- /dev/null
+++ b/src/stores/admin/unit/respiratoryGear/respiratoryGear.ts
@@ -0,0 +1,93 @@
+import { defineStore } from "pinia";
+import type {
+ RespiratoryGearViewModel,
+ CreateRespiratoryGearViewModel,
+ UpdateRespiratoryGearViewModel,
+} from "@/viewmodels/admin/unit/respiratory/respiratoryGear.models";
+import { http } from "@/serverCom";
+import type { AxiosResponse } from "axios";
+
+export const useRespiratoryGearStore = defineStore("respiratoryGear", {
+ state: () => {
+ return {
+ respiratoryGears: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ activeRespiratoryGear: null as string | null,
+ activeRespiratoryGearObj: null as RespiratoryGearViewModel | null,
+ loadingActive: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchRespiratoryGears(offset = 0, count = 25, search = "", clear = false) {
+ if (clear) this.respiratoryGears = [];
+ this.loading = "loading";
+ http
+ .get(`/admin/respiratoryGear?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`)
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.respiratoryGears
+ .filter((elem: RespiratoryGearViewModel) => this.respiratoryGears.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: RespiratoryGearViewModel, index: number): RespiratoryGearViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: RespiratoryGearViewModel & { tab_pos: number }) => {
+ this.respiratoryGears.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ async getAllRespiratoryGears(): Promise> {
+ return await http.get(`/admin/respiratoryGear?noLimit=true`).then((res) => {
+ return { ...res, data: res.data.respiratoryGears };
+ });
+ },
+ async searchRespiratoryGears(search: string): Promise> {
+ return await http.get(`/admin/respiratoryGear?search=${search}&noLimit=true`).then((res) => {
+ return { ...res, data: res.data.respiratoryGears };
+ });
+ },
+ fetchRespiratoryGearByActiveId() {
+ this.loadingActive = "loading";
+ http
+ .get(`/admin/respiratoryGear/${this.activeRespiratoryGear}`)
+ .then((res) => {
+ this.activeRespiratoryGearObj = res.data;
+ this.loadingActive = "fetched";
+ })
+ .catch((err) => {
+ this.loadingActive = "failed";
+ });
+ },
+ fetchRespiratoryGearById(id: string) {
+ return http.get(`/admin/respiratoryGear/${id}`);
+ },
+ async createRespiratoryGear(respiratoryGear: CreateRespiratoryGearViewModel): Promise> {
+ const result = await http.post(`/admin/respiratoryGear`, {
+ // TODO: data
+ });
+ this.fetchRespiratoryGears();
+ return result;
+ },
+ async updateActiveRespiratoryGear(
+ respiratoryGear: UpdateRespiratoryGearViewModel
+ ): Promise> {
+ const result = await http.patch(`/admin/respiratoryGear/${respiratoryGear.id}`, {
+ // TODO: data
+ });
+ this.fetchRespiratoryGears();
+ return result;
+ },
+ async deleteRespiratoryGear(respiratoryGear: number): Promise> {
+ const result = await http.delete(`/admin/respiratoryGear/${respiratoryGear}`);
+ this.fetchRespiratoryGears();
+ return result;
+ },
+ },
+});
diff --git a/src/stores/admin/unit/respiratoryMission/respiratoryMission.ts b/src/stores/admin/unit/respiratoryMission/respiratoryMission.ts
new file mode 100644
index 0000000..3b511fd
--- /dev/null
+++ b/src/stores/admin/unit/respiratoryMission/respiratoryMission.ts
@@ -0,0 +1,99 @@
+import { defineStore } from "pinia";
+import type {
+ RespiratoryMissionViewModel,
+ CreateRespiratoryMissionViewModel,
+ UpdateRespiratoryMissionViewModel,
+} from "@/viewmodels/admin/unit/respiratory/respiratoryMission.models";
+import { http } from "@/serverCom";
+import type { AxiosResponse } from "axios";
+
+export const useRespiratoryMissionStore = defineStore("respiratoryMission", {
+ state: () => {
+ return {
+ respiratoryMissions: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ activeRespiratoryMission: null as string | null,
+ activeRespiratoryMissionObj: null as RespiratoryMissionViewModel | null,
+ loadingActive: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchRespiratoryMissions(offset = 0, count = 25, search = "", clear = false) {
+ if (clear) this.respiratoryMissions = [];
+ this.loading = "loading";
+ http
+ .get(`/admin/respiratoryMission?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`)
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.respiratoryMissions
+ .filter(
+ (elem: RespiratoryMissionViewModel) => this.respiratoryMissions.findIndex((m) => m.id == elem.id) == -1
+ )
+ .map(
+ (elem: RespiratoryMissionViewModel, index: number): RespiratoryMissionViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ }
+ )
+ .forEach((elem: RespiratoryMissionViewModel & { tab_pos: number }) => {
+ this.respiratoryMissions.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ async getAllRespiratoryMissions(): Promise> {
+ return await http.get(`/admin/respiratoryMission?noLimit=true`).then((res) => {
+ return { ...res, data: res.data.respiratoryMissions };
+ });
+ },
+ async searchRespiratoryMissions(search: string): Promise> {
+ return await http.get(`/admin/respiratoryMission?search=${search}&noLimit=true`).then((res) => {
+ return { ...res, data: res.data.respiratoryMissions };
+ });
+ },
+ fetchRespiratoryMissionByActiveId() {
+ this.loadingActive = "loading";
+ http
+ .get(`/admin/respiratoryMission/${this.activeRespiratoryMission}`)
+ .then((res) => {
+ this.activeRespiratoryMissionObj = res.data;
+ this.loadingActive = "fetched";
+ })
+ .catch((err) => {
+ this.loadingActive = "failed";
+ });
+ },
+ fetchRespiratoryMissionById(id: string) {
+ return http.get(`/admin/respiratoryMission/${id}`);
+ },
+ async createRespiratoryMission(
+ respiratoryMission: CreateRespiratoryMissionViewModel
+ ): Promise> {
+ const result = await http.post(`/admin/respiratoryMission`, {
+ // TODO: data
+ });
+ this.fetchRespiratoryMissions();
+ return result;
+ },
+ async updateActiveRespiratoryMission(
+ respiratoryMission: UpdateRespiratoryMissionViewModel
+ ): Promise> {
+ const result = await http.patch(`/admin/respiratoryMission/${respiratoryMission.id}`, {
+ // TODO: data
+ });
+ this.fetchRespiratoryMissions();
+ return result;
+ },
+ async deleteRespiratoryMission(respiratoryMission: number): Promise> {
+ const result = await http.delete(`/admin/respiratoryMission/${respiratoryMission}`);
+ this.fetchRespiratoryMissions();
+ return result;
+ },
+ },
+});
diff --git a/src/stores/admin/unit/respiratoryWearer/respiratoryWearer.ts b/src/stores/admin/unit/respiratoryWearer/respiratoryWearer.ts
new file mode 100644
index 0000000..cdf1181
--- /dev/null
+++ b/src/stores/admin/unit/respiratoryWearer/respiratoryWearer.ts
@@ -0,0 +1,99 @@
+import { defineStore } from "pinia";
+import type {
+ RespiratoryWearerViewModel,
+ CreateRespiratoryWearerViewModel,
+ UpdateRespiratoryWearerViewModel,
+} from "@/viewmodels/admin/unit/respiratory/respiratoryWearer.models";
+import { http } from "@/serverCom";
+import type { AxiosResponse } from "axios";
+
+export const useRespiratoryWearerStore = defineStore("respiratoryWearer", {
+ state: () => {
+ return {
+ respiratoryWearers: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ activeRespiratoryWearer: null as string | null,
+ activeRespiratoryWearerObj: null as RespiratoryWearerViewModel | null,
+ loadingActive: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchRespiratoryWearers(offset = 0, count = 25, search = "", clear = false) {
+ if (clear) this.respiratoryWearers = [];
+ this.loading = "loading";
+ http
+ .get(`/admin/respiratoryWearer?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`)
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.respiratoryWearers
+ .filter(
+ (elem: RespiratoryWearerViewModel) => this.respiratoryWearers.findIndex((m) => m.id == elem.id) == -1
+ )
+ .map(
+ (elem: RespiratoryWearerViewModel, index: number): RespiratoryWearerViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ }
+ )
+ .forEach((elem: RespiratoryWearerViewModel & { tab_pos: number }) => {
+ this.respiratoryWearers.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ async getAllRespiratoryWearers(): Promise> {
+ return await http.get(`/admin/respiratoryWearer?noLimit=true`).then((res) => {
+ return { ...res, data: res.data.respiratoryWearers };
+ });
+ },
+ async searchRespiratoryWearers(search: string): Promise> {
+ return await http.get(`/admin/respiratoryWearer?search=${search}&noLimit=true`).then((res) => {
+ return { ...res, data: res.data.respiratoryWearers };
+ });
+ },
+ fetchRespiratoryWearerByActiveId() {
+ this.loadingActive = "loading";
+ http
+ .get(`/admin/respiratoryWearer/${this.activeRespiratoryWearer}`)
+ .then((res) => {
+ this.activeRespiratoryWearerObj = res.data;
+ this.loadingActive = "fetched";
+ })
+ .catch((err) => {
+ this.loadingActive = "failed";
+ });
+ },
+ fetchRespiratoryWearerById(id: string) {
+ return http.get(`/admin/respiratoryWearer/${id}`);
+ },
+ async createRespiratoryWearer(
+ respiratoryWearer: CreateRespiratoryWearerViewModel
+ ): Promise> {
+ const result = await http.post(`/admin/respiratoryWearer`, {
+ // TODO: data
+ });
+ this.fetchRespiratoryWearers();
+ return result;
+ },
+ async updateActiveRespiratoryWearer(
+ respiratoryWearer: UpdateRespiratoryWearerViewModel
+ ): Promise> {
+ const result = await http.patch(`/admin/respiratoryWearer/${respiratoryWearer.id}`, {
+ // TODO: data
+ });
+ this.fetchRespiratoryWearers();
+ return result;
+ },
+ async deleteRespiratoryWearer(respiratoryWearer: number): Promise> {
+ const result = await http.delete(`/admin/respiratoryWearer/${respiratoryWearer}`);
+ this.fetchRespiratoryWearers();
+ return result;
+ },
+ },
+});
diff --git a/src/stores/admin/unit/vehicle/damageReport.ts b/src/stores/admin/unit/vehicle/damageReport.ts
new file mode 100644
index 0000000..b4df77f
--- /dev/null
+++ b/src/stores/admin/unit/vehicle/damageReport.ts
@@ -0,0 +1,43 @@
+import { defineStore } from "pinia";
+import { http } from "@/serverCom";
+import { useVehicleStore } from "./vehicle";
+import type { DamageReportViewModel } from "@/viewmodels/admin/unit/damageReport.models";
+
+export const useVehicleDamageReportStore = defineStore("vehicleDamageReport", {
+ state: () => {
+ return {
+ damageReports: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchDamageReportForVehicle(offset = 0, count = 25, search = "", clear = false) {
+ const vehicleId = useVehicleStore().activeVehicle;
+ if (clear) this.damageReports = [];
+ this.loading = "loading";
+ http
+ .get(
+ `/admin/damagereport/vehicle/${vehicleId}?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`
+ )
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.damageReports
+ .filter((elem: DamageReportViewModel) => this.damageReports.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: DamageReportViewModel, index: number): DamageReportViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: DamageReportViewModel & { tab_pos: number }) => {
+ this.damageReports.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ },
+});
diff --git a/src/stores/admin/unit/vehicle/inspection.ts b/src/stores/admin/unit/vehicle/inspection.ts
new file mode 100644
index 0000000..23885b9
--- /dev/null
+++ b/src/stores/admin/unit/vehicle/inspection.ts
@@ -0,0 +1,43 @@
+import { defineStore } from "pinia";
+import { http } from "@/serverCom";
+import type { InspectionViewModel } from "@/viewmodels/admin/unit/inspection/inspection.models";
+import { useVehicleStore } from "./vehicle";
+
+export const useVehicleInspectionStore = defineStore("vehicleInspection", {
+ state: () => {
+ return {
+ inspections: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchInspectionForVehicle(offset = 0, count = 25, search = "", clear = false) {
+ const vehicleId = useVehicleStore().activeVehicle;
+ if (clear) this.inspections = [];
+ this.loading = "loading";
+ http
+ .get(
+ `/admin/inspection/vehicle/${vehicleId}?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`
+ )
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.inspections
+ .filter((elem: InspectionViewModel) => this.inspections.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: InspectionViewModel, index: number): InspectionViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: InspectionViewModel & { tab_pos: number }) => {
+ this.inspections.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ },
+});
diff --git a/src/stores/admin/unit/vehicle/repair.ts b/src/stores/admin/unit/vehicle/repair.ts
new file mode 100644
index 0000000..beb30a1
--- /dev/null
+++ b/src/stores/admin/unit/vehicle/repair.ts
@@ -0,0 +1,43 @@
+import { defineStore } from "pinia";
+import { http } from "@/serverCom";
+import { useVehicleStore } from "./vehicle";
+import type { RepairViewModel } from "@/viewmodels/admin/unit/repair.models";
+
+export const useVehicleRepairStore = defineStore("vehicleRepair", {
+ state: () => {
+ return {
+ repairs: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchRepairForVehicle(offset = 0, count = 25, search = "", clear = false) {
+ const vehicleId = useVehicleStore().activeVehicle;
+ if (clear) this.repairs = [];
+ this.loading = "loading";
+ http
+ .get(
+ `/admin/repair/vehicle/${vehicleId}?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`
+ )
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.repairs
+ .filter((elem: RepairViewModel) => this.repairs.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: RepairViewModel, index: number): RepairViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: RepairViewModel & { tab_pos: number }) => {
+ this.repairs.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ },
+});
diff --git a/src/stores/admin/unit/vehicle/vehicle.ts b/src/stores/admin/unit/vehicle/vehicle.ts
new file mode 100644
index 0000000..7138cea
--- /dev/null
+++ b/src/stores/admin/unit/vehicle/vehicle.ts
@@ -0,0 +1,108 @@
+import { defineStore } from "pinia";
+import type {
+ VehicleViewModel,
+ CreateVehicleViewModel,
+ UpdateVehicleViewModel,
+} from "@/viewmodels/admin/unit/vehicle/vehicle.models";
+import { http } from "@/serverCom";
+import type { AxiosResponse } from "axios";
+
+export const useVehicleStore = defineStore("vehicle", {
+ state: () => {
+ return {
+ vehicles: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ activeVehicle: null as string | null,
+ activeVehicleObj: null as VehicleViewModel | null,
+ loadingActive: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchVehicles(offset = 0, count = 25, search = "", clear = false) {
+ if (clear) this.vehicles = [];
+ this.loading = "loading";
+ http
+ .get(`/admin/vehicle?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`)
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.vehicles
+ .filter((elem: VehicleViewModel) => this.vehicles.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: VehicleViewModel, index: number): VehicleViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: VehicleViewModel & { tab_pos: number }) => {
+ this.vehicles.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ async getAllVehicles(): Promise> {
+ return await http.get(`/admin/vehicle?noLimit=true`).then((res) => {
+ return { ...res, data: res.data.vehicles };
+ });
+ },
+ async getVehiclesByIds(ids: Array): Promise> {
+ return await http
+ .post(`/admin/vehicle/ids`, {
+ ids,
+ })
+ .then((res) => {
+ return { ...res, data: res.data.vehicles };
+ });
+ },
+ async searchVehicles(search: string): Promise> {
+ return await http.get(`/admin/vehicle?search=${search}&noLimit=true`).then((res) => {
+ return { ...res, data: res.data.vehicles };
+ });
+ },
+ fetchVehicleByActiveId() {
+ this.loadingActive = "loading";
+ http
+ .get(`/admin/vehicle/${this.activeVehicle}`)
+ .then((res) => {
+ this.activeVehicleObj = res.data;
+ this.loadingActive = "fetched";
+ })
+ .catch((err) => {
+ this.loadingActive = "failed";
+ });
+ },
+ fetchVehicleById(id: string) {
+ return http.get(`/admin/vehicle/${id}`);
+ },
+ async createVehicle(vehicle: CreateVehicleViewModel): Promise> {
+ const result = await http.post(`/admin/vehicle`, {
+ vehicleTypeId: vehicle.vehicleTypeId,
+ name: vehicle.name,
+ code: vehicle.code,
+ location: vehicle.location,
+ commissioned: vehicle.commissioned,
+ });
+ this.fetchVehicles();
+ return result;
+ },
+ async updateActiveVehicle(vehicle: UpdateVehicleViewModel): Promise> {
+ const result = await http.patch(`/admin/vehicle/${vehicle.id}`, {
+ name: vehicle.name,
+ code: vehicle.code,
+ location: vehicle.location,
+ commissioned: vehicle.commissioned,
+ decommissioned: vehicle.decommissioned,
+ });
+ this.fetchVehicles();
+ return result;
+ },
+ async deleteVehicle(vehicle: number): Promise> {
+ const result = await http.delete(`/admin/vehicle/${vehicle}`);
+ this.fetchVehicles();
+ return result;
+ },
+ },
+});
diff --git a/src/stores/admin/unit/vehicleType/inspectionPlan.ts b/src/stores/admin/unit/vehicleType/inspectionPlan.ts
new file mode 100644
index 0000000..e7184ab
--- /dev/null
+++ b/src/stores/admin/unit/vehicleType/inspectionPlan.ts
@@ -0,0 +1,29 @@
+import { defineStore } from "pinia";
+import { http } from "@/serverCom";
+import type { InspectionPlanViewModel } from "@/viewmodels/admin/unit/inspection/inspectionPlan.models";
+import { useVehicleTypeStore } from "./vehicleType";
+
+export const useVehicleTypeInspectionPlanStore = defineStore("vehicleTypeInspectionPlan", {
+ state: () => {
+ return {
+ inspectionPlans: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchInspectionPlanForVehicleType() {
+ const vehicleTypeId = useVehicleTypeStore().activeVehicleType;
+ this.loading = "loading";
+ http
+ .get(`/admin/inspectionPlan/vehicleType/${vehicleTypeId}?noLimit=true`)
+ .then((result) => {
+ this.inspectionPlans = result.data.inspectionPlans;
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ },
+});
diff --git a/src/stores/admin/unit/vehicleType/vehicleType.ts b/src/stores/admin/unit/vehicleType/vehicleType.ts
new file mode 100644
index 0000000..9ec3904
--- /dev/null
+++ b/src/stores/admin/unit/vehicleType/vehicleType.ts
@@ -0,0 +1,93 @@
+import { defineStore } from "pinia";
+import type {
+ VehicleTypeViewModel,
+ CreateVehicleTypeViewModel,
+ UpdateVehicleTypeViewModel,
+} from "@/viewmodels/admin/unit/vehicle/vehicleType.models";
+import { http } from "@/serverCom";
+import type { AxiosResponse } from "axios";
+
+export const useVehicleTypeStore = defineStore("vehicleType", {
+ state: () => {
+ return {
+ vehicleTypes: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ activeVehicleType: null as string | null,
+ activeVehicleTypeObj: null as VehicleTypeViewModel | null,
+ loadingActive: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchVehicleTypes(offset = 0, count = 25, search = "", clear = false) {
+ if (clear) this.vehicleTypes = [];
+ this.loading = "loading";
+ http
+ .get(`/admin/vehicleType?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`)
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.vehicleTypes
+ .filter((elem: VehicleTypeViewModel) => this.vehicleTypes.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: VehicleTypeViewModel, index: number): VehicleTypeViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: VehicleTypeViewModel & { tab_pos: number }) => {
+ this.vehicleTypes.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ async getAllVehicleTypes(): Promise> {
+ return await http.get(`/admin/vehicleType?noLimit=true`).then((res) => {
+ return { ...res, data: res.data.vehicleTypes };
+ });
+ },
+ async searchVehicleTypes(search: string): Promise> {
+ return await http.get(`/admin/vehicleType?search=${search}&noLimit=true`).then((res) => {
+ return { ...res, data: res.data.vehicleTypes };
+ });
+ },
+ fetchVehicleTypeByActiveId() {
+ this.loadingActive = "loading";
+ http
+ .get(`/admin/vehicleType/${this.activeVehicleType}`)
+ .then((res) => {
+ this.activeVehicleTypeObj = res.data;
+ this.loadingActive = "fetched";
+ })
+ .catch((err) => {
+ this.loadingActive = "failed";
+ });
+ },
+ fetchVehicleTypeById(id: string) {
+ return http.get(`/admin/vehicleType/${id}`);
+ },
+ async createVehicleType(vehicleType: CreateVehicleTypeViewModel): Promise> {
+ const result = await http.post(`/admin/vehicleType`, {
+ type: vehicleType.type,
+ description: vehicleType.description,
+ });
+ this.fetchVehicleTypes();
+ return result;
+ },
+ async updateActiveVehicleType(vehicleType: UpdateVehicleTypeViewModel): Promise> {
+ const result = await http.patch(`/admin/vehicleType/${vehicleType.id}`, {
+ type: vehicleType.type,
+ description: vehicleType.description,
+ });
+ this.fetchVehicleTypes();
+ return result;
+ },
+ async deleteVehicleType(vehicleType: number): Promise> {
+ const result = await http.delete(`/admin/vehicleType/${vehicleType}`);
+ this.fetchVehicleTypes();
+ return result;
+ },
+ },
+});
diff --git a/src/stores/admin/unit/wearable/damageReport.ts b/src/stores/admin/unit/wearable/damageReport.ts
new file mode 100644
index 0000000..e54a912
--- /dev/null
+++ b/src/stores/admin/unit/wearable/damageReport.ts
@@ -0,0 +1,43 @@
+import { defineStore } from "pinia";
+import { http } from "@/serverCom";
+import { useWearableStore } from "./wearable";
+import type { DamageReportViewModel } from "@/viewmodels/admin/unit/damageReport.models";
+
+export const useWearableDamageReportStore = defineStore("wearableDamageReport", {
+ state: () => {
+ return {
+ damageReports: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchDamageReportForWearable(offset = 0, count = 25, search = "", clear = false) {
+ const wearableId = useWearableStore().activeWearable;
+ if (clear) this.damageReports = [];
+ this.loading = "loading";
+ http
+ .get(
+ `/admin/damagereport/wearable/${wearableId}?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`
+ )
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.damageReports
+ .filter((elem: DamageReportViewModel) => this.damageReports.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: DamageReportViewModel, index: number): DamageReportViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: DamageReportViewModel & { tab_pos: number }) => {
+ this.damageReports.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ },
+});
diff --git a/src/stores/admin/unit/wearable/inspection.ts b/src/stores/admin/unit/wearable/inspection.ts
new file mode 100644
index 0000000..1596da6
--- /dev/null
+++ b/src/stores/admin/unit/wearable/inspection.ts
@@ -0,0 +1,43 @@
+import { defineStore } from "pinia";
+import { http } from "@/serverCom";
+import type { InspectionViewModel } from "@/viewmodels/admin/unit/inspection/inspection.models";
+import { useWearableStore } from "./wearable";
+
+export const useWearableInspectionStore = defineStore("wearableInspection", {
+ state: () => {
+ return {
+ inspections: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchInspectionForWearable(offset = 0, count = 25, search = "", clear = false) {
+ const wearableId = useWearableStore().activeWearable;
+ if (clear) this.inspections = [];
+ this.loading = "loading";
+ http
+ .get(
+ `/admin/inspection/wearable/${wearableId}?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`
+ )
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.inspections
+ .filter((elem: InspectionViewModel) => this.inspections.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: InspectionViewModel, index: number): InspectionViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: InspectionViewModel & { tab_pos: number }) => {
+ this.inspections.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ },
+});
diff --git a/src/stores/admin/unit/wearable/repair.ts b/src/stores/admin/unit/wearable/repair.ts
new file mode 100644
index 0000000..95f74e2
--- /dev/null
+++ b/src/stores/admin/unit/wearable/repair.ts
@@ -0,0 +1,43 @@
+import { defineStore } from "pinia";
+import { http } from "@/serverCom";
+import { useWearableStore } from "./wearable";
+import type { RepairViewModel } from "@/viewmodels/admin/unit/repair.models";
+
+export const useWearableRepairStore = defineStore("wearableRepair", {
+ state: () => {
+ return {
+ repairs: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchRepairForWearable(offset = 0, count = 25, search = "", clear = false) {
+ const wearableId = useWearableStore().activeWearable;
+ if (clear) this.repairs = [];
+ this.loading = "loading";
+ http
+ .get(
+ `/admin/repair/wearable/${wearableId}?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`
+ )
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.repairs
+ .filter((elem: RepairViewModel) => this.repairs.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: RepairViewModel, index: number): RepairViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: RepairViewModel & { tab_pos: number }) => {
+ this.repairs.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ },
+});
diff --git a/src/stores/admin/unit/wearable/wearable.ts b/src/stores/admin/unit/wearable/wearable.ts
new file mode 100644
index 0000000..a25cc49
--- /dev/null
+++ b/src/stores/admin/unit/wearable/wearable.ts
@@ -0,0 +1,110 @@
+import { defineStore } from "pinia";
+import type {
+ WearableViewModel,
+ CreateWearableViewModel,
+ UpdateWearableViewModel,
+} from "@/viewmodels/admin/unit/wearable/wearable.models";
+import { http } from "@/serverCom";
+import type { AxiosResponse } from "axios";
+
+export const useWearableStore = defineStore("wearable", {
+ state: () => {
+ return {
+ wearables: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ activeWearable: null as string | null,
+ activeWearableObj: null as WearableViewModel | null,
+ loadingActive: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchWearables(offset = 0, count = 25, search = "", clear = false) {
+ if (clear) this.wearables = [];
+ this.loading = "loading";
+ http
+ .get(`/admin/wearable?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`)
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.wearables
+ .filter((elem: WearableViewModel) => this.wearables.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: WearableViewModel, index: number): WearableViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: WearableViewModel & { tab_pos: number }) => {
+ this.wearables.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ async getAllWearables(): Promise> {
+ return await http.get(`/admin/wearable?noLimit=true`).then((res) => {
+ return { ...res, data: res.data.wearables };
+ });
+ },
+ async getWearablesByIds(ids: Array): Promise> {
+ return await http
+ .post(`/admin/wearable/ids`, {
+ ids,
+ })
+ .then((res) => {
+ return { ...res, data: res.data.wearables };
+ });
+ },
+ async searchWearables(search: string): Promise> {
+ return await http.get(`/admin/wearable?search=${search}&noLimit=true`).then((res) => {
+ return { ...res, data: res.data.wearables };
+ });
+ },
+ fetchWearableByActiveId() {
+ this.loadingActive = "loading";
+ http
+ .get(`/admin/wearable/${this.activeWearable}`)
+ .then((res) => {
+ this.activeWearableObj = res.data;
+ this.loadingActive = "fetched";
+ })
+ .catch((err) => {
+ this.loadingActive = "failed";
+ });
+ },
+ fetchWearableById(id: string) {
+ return http.get(`/admin/wearable/${id}`);
+ },
+ async createWearable(wearable: CreateWearableViewModel): Promise> {
+ const result = await http.post(`/admin/wearable`, {
+ wearableTypeId: wearable.wearableTypeId,
+ name: wearable.name,
+ code: wearable.code,
+ location: wearable.location,
+ commissioned: wearable.commissioned,
+ wearerId: wearable.wearerId,
+ });
+ this.fetchWearables();
+ return result;
+ },
+ async updateActiveWearable(wearable: UpdateWearableViewModel): Promise> {
+ const result = await http.patch(`/admin/wearable/${wearable.id}`, {
+ name: wearable.name,
+ code: wearable.code,
+ location: wearable.location,
+ commissioned: wearable.commissioned,
+ decommissioned: wearable.decommissioned,
+ wearerId: wearable.wearerId,
+ });
+ this.fetchWearables();
+ return result;
+ },
+ async deleteWearable(wearable: number): Promise> {
+ const result = await http.delete(`/admin/wearable/${wearable}`);
+ this.fetchWearables();
+ return result;
+ },
+ },
+});
diff --git a/src/stores/admin/unit/wearableType/inspectionPlan.ts b/src/stores/admin/unit/wearableType/inspectionPlan.ts
new file mode 100644
index 0000000..3622c37
--- /dev/null
+++ b/src/stores/admin/unit/wearableType/inspectionPlan.ts
@@ -0,0 +1,29 @@
+import { defineStore } from "pinia";
+import { http } from "@/serverCom";
+import type { InspectionPlanViewModel } from "@/viewmodels/admin/unit/inspection/inspectionPlan.models";
+import { useWearableTypeStore } from "./wearableType";
+
+export const useWearableTypeInspectionPlanStore = defineStore("wearableTypeInspectionPlan", {
+ state: () => {
+ return {
+ inspectionPlans: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchInspectionPlanForWearableType() {
+ const wearableTypeId = useWearableTypeStore().activeWearableType;
+ this.loading = "loading";
+ http
+ .get(`/admin/inspectionPlan/wearableType/${wearableTypeId}?noLimit=true`)
+ .then((result) => {
+ this.inspectionPlans = result.data.inspectionPlans;
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ },
+});
diff --git a/src/stores/admin/unit/wearableType/wearableType.ts b/src/stores/admin/unit/wearableType/wearableType.ts
new file mode 100644
index 0000000..bba5113
--- /dev/null
+++ b/src/stores/admin/unit/wearableType/wearableType.ts
@@ -0,0 +1,93 @@
+import { defineStore } from "pinia";
+import type {
+ WearableTypeViewModel,
+ CreateWearableTypeViewModel,
+ UpdateWearableTypeViewModel,
+} from "@/viewmodels/admin/unit/wearable/wearableType.models";
+import { http } from "@/serverCom";
+import type { AxiosResponse } from "axios";
+
+export const useWearableTypeStore = defineStore("wearableType", {
+ state: () => {
+ return {
+ wearableTypes: [] as Array,
+ totalCount: 0 as number,
+ loading: "loading" as "loading" | "fetched" | "failed",
+ activeWearableType: null as string | null,
+ activeWearableTypeObj: null as WearableTypeViewModel | null,
+ loadingActive: "loading" as "loading" | "fetched" | "failed",
+ };
+ },
+ actions: {
+ fetchWearableTypes(offset = 0, count = 25, search = "", clear = false) {
+ if (clear) this.wearableTypes = [];
+ this.loading = "loading";
+ http
+ .get(`/admin/wearableType?offset=${offset}&count=${count}${search != "" ? "&search=" + search : ""}`)
+ .then((result) => {
+ this.totalCount = result.data.total;
+ result.data.wearableTypes
+ .filter((elem: WearableTypeViewModel) => this.wearableTypes.findIndex((m) => m.id == elem.id) == -1)
+ .map((elem: WearableTypeViewModel, index: number): WearableTypeViewModel & { tab_pos: number } => {
+ return {
+ ...elem,
+ tab_pos: index + offset,
+ };
+ })
+ .forEach((elem: WearableTypeViewModel & { tab_pos: number }) => {
+ this.wearableTypes.push(elem);
+ });
+ this.loading = "fetched";
+ })
+ .catch((err) => {
+ this.loading = "failed";
+ });
+ },
+ async getAllWearableTypes(): Promise> {
+ return await http.get(`/admin/wearableType?noLimit=true`).then((res) => {
+ return { ...res, data: res.data.wearableTypes };
+ });
+ },
+ async searchWearableTypes(search: string): Promise> {
+ return await http.get(`/admin/wearableType?search=${search}&noLimit=true`).then((res) => {
+ return { ...res, data: res.data.wearableTypes };
+ });
+ },
+ fetchWearableTypeByActiveId() {
+ this.loadingActive = "loading";
+ http
+ .get(`/admin/wearableType/${this.activeWearableType}`)
+ .then((res) => {
+ this.activeWearableTypeObj = res.data;
+ this.loadingActive = "fetched";
+ })
+ .catch((err) => {
+ this.loadingActive = "failed";
+ });
+ },
+ fetchWearableTypeById(id: string) {
+ return http.get(`/admin/wearableType/${id}`);
+ },
+ async createWearableType(wearableType: CreateWearableTypeViewModel): Promise> {
+ const result = await http.post(`/admin/wearableType`, {
+ type: wearableType.type,
+ description: wearableType.description,
+ });
+ this.fetchWearableTypes();
+ return result;
+ },
+ async updateWearableType(wearableType: UpdateWearableTypeViewModel): Promise> {
+ const result = await http.patch(`/admin/wearableType/${wearableType.id}`, {
+ type: wearableType.type,
+ description: wearableType.description,
+ });
+ this.fetchWearableTypes();
+ return result;
+ },
+ async deleteWearableType(wearableType: number): Promise> {
+ const result = await http.delete(`/admin/wearableType/${wearableType}`);
+ this.fetchWearableTypes();
+ return result;
+ },
+ },
+});
diff --git a/src/stores/configuration.ts b/src/stores/configuration.ts
index 493b688..c1062c9 100644
--- a/src/stores/configuration.ts
+++ b/src/stores/configuration.ts
@@ -10,6 +10,7 @@ export const useConfigurationStore = defineStore("configuration", {
clubWebsite: "",
appCustom_login_message: "",
appShow_link_to_calendar: false as boolean,
+ appShow_link_to_damagereport: false as boolean,
serverOffline: false as boolean,
};
@@ -25,6 +26,7 @@ export const useConfigurationStore = defineStore("configuration", {
this.clubWebsite = res.data["club.website"];
this.appCustom_login_message = res.data["app.custom_login_message"];
this.appShow_link_to_calendar = res.data["app.show_link_to_calendar"];
+ this.appShow_link_to_damagereport = res.data["app.show_link_to_damagereport"];
})
.catch(() => {
this.serverOffline = true;
diff --git a/src/stores/modal.ts b/src/stores/modal.ts
index cdc4c49..a537848 100644
--- a/src/stores/modal.ts
+++ b/src/stores/modal.ts
@@ -4,19 +4,22 @@ export const useModalStore = defineStore("modal", {
state: () => {
return {
show: false,
- component_ref: null as any,
- data: null as any,
+ component_ref: undefined as any,
+ data: undefined as any,
+ callback: undefined as undefined | Function,
};
},
actions: {
- openModal(component_ref: any, data?: any) {
+ openModal(component_ref: any, data?: any, callback?: Function) {
this.component_ref = component_ref;
this.data = data;
+ this.callback = callback;
this.show = true;
},
closeModal() {
- this.component_ref = null;
- this.data = null;
+ this.component_ref = undefined;
+ this.data = undefined;
+ this.callback = undefined;
this.show = false;
},
},
diff --git a/src/stores/notification.ts b/src/stores/notification.ts
index 872b108..0ec8fc0 100644
--- a/src/stores/notification.ts
+++ b/src/stores/notification.ts
@@ -8,7 +8,7 @@ export interface Notification {
indicator: boolean;
}
-export type NotificationType = "info" | "warning" | "error";
+export type NotificationType = "info" | "warning" | "error" | "success";
export const useNotificationStore = defineStore("notification", {
state: () => {
diff --git a/src/types/permissionTypes.ts b/src/types/permissionTypes.ts
index 013615c..091c0c3 100644
--- a/src/types/permissionTypes.ts
+++ b/src/types/permissionTypes.ts
@@ -1,28 +1,46 @@
-export type PermissionSection = "club" | "configuration" | "management";
+export type PermissionSection = "club" | "unit" | "configuration" | "management";
export type PermissionModule =
+ // club
| "member"
| "calendar"
| "newsletter"
- | "newsletter_config"
| "protocol"
+ | "query"
| "listprint"
+ // unit
+ | "equipment"
+ | "equipment_type"
+ | "vehicle"
+ | "vehicle_type"
+ | "wearable"
+ | "wearable_type"
+ | "inspection"
+ | "inspection_plan"
+ | "respiratory_gear"
+ | "respiratory_wearer"
+ | "respiratory_mission"
+ | "damage_report"
+ | "maintenance"
+ | "repair"
+ // configuration
| "qualification"
| "award"
| "executive_position"
| "communication_type"
| "membership_status"
+ | "newsletter_config"
| "salutation"
| "education"
| "calendar_type"
- | "user"
- | "role"
- | "webapi"
- | "query"
| "query_store"
| "template"
| "template_usage"
| "backup"
+ // management
+ | "user"
+ | "role"
+ | "webapi"
| "setting";
export type PermissionType = "read" | "create" | "update" | "delete";
@@ -57,35 +75,69 @@ export type SectionsAndModulesObject = {
}>;
};
-export const permissionSections: Array = ["club", "configuration", "management"];
+export const permissionSections: Array = ["club", "unit", "configuration", "management"];
export const permissionModules: Array = [
+ // club
"member",
"calendar",
"newsletter",
- "newsletter_config",
"protocol",
+ "query",
"listprint",
+ // unit
+ "equipment",
+ "equipment_type",
+ "vehicle",
+ "vehicle_type",
+ "wearable",
+ "wearable_type",
+ "inspection",
+ "inspection_plan",
+ "respiratory_gear",
+ "respiratory_wearer",
+ "respiratory_mission",
+ "damage_report",
+ "maintenance",
+ "repair",
+ // configuration
"qualification",
"award",
"executive_position",
"communication_type",
"membership_status",
+ "newsletter_config",
"salutation",
"education",
"calendar_type",
- "user",
- "role",
- "webapi",
- "query",
"query_store",
"template",
"template_usage",
"backup",
+ // management
+ "user",
+ "role",
+ "webapi",
"setting",
];
export const permissionTypes: Array = ["read", "create", "update", "delete"];
export const sectionsAndModules: SectionsAndModulesObject = {
club: ["member", "calendar", "newsletter", "protocol", "query", "listprint"],
+ unit: [
+ "equipment",
+ "equipment_type",
+ "vehicle",
+ "vehicle_type",
+ "wearable",
+ "wearable_type",
+ "inspection",
+ "inspection_plan",
+ "respiratory_gear",
+ "respiratory_wearer",
+ "respiratory_mission",
+ "damage_report",
+ "maintenance",
+ "repair",
+ ],
configuration: [
"qualification",
"award",
diff --git a/src/types/settingTypes.ts b/src/types/settingTypes.ts
index 43d77a3..f865c74 100644
--- a/src/types/settingTypes.ts
+++ b/src/types/settingTypes.ts
@@ -8,6 +8,7 @@ export type SettingString =
| "club.website"
| "app.custom_login_message"
| "app.show_link_to_calendar"
+ | "app.show_link_to_damagereport"
| "session.jwt_expiration"
| "session.refresh_expiration"
| "session.pwa_refresh_expiration"
@@ -32,6 +33,7 @@ export type SettingValueMapping = {
"club.website": string;
"app.custom_login_message": string;
"app.show_link_to_calendar": boolean;
+ "app.show_link_to_damagereport": boolean;
"session.jwt_expiration": string;
"session.refresh_expiration": string;
"session.pwa_refresh_expiration": string;
@@ -66,6 +68,7 @@ export const settingsType: SettingsSchema = {
"club.website": { type: "url", optional: true },
"app.custom_login_message": { type: "string", optional: true },
"app.show_link_to_calendar": { type: "boolean", default: true },
+ "app.show_link_to_damagereport": { type: "boolean", default: false },
"session.jwt_expiration": { type: "ms", default: "15m" },
"session.refresh_expiration": { type: "ms", default: "1d" },
"session.pwa_refresh_expiration": { type: "ms", default: "5d" },
diff --git a/src/viewmodels/admin/unit/damageReport.models.ts b/src/viewmodels/admin/unit/damageReport.models.ts
new file mode 100644
index 0000000..461b316
--- /dev/null
+++ b/src/viewmodels/admin/unit/damageReport.models.ts
@@ -0,0 +1,52 @@
+import type { EquipmentViewModel } from "./equipment/equipment.models";
+import type { RepairViewModel } from "./repair.models";
+import type { VehicleViewModel } from "./vehicle/vehicle.models";
+import type { WearableViewModel } from "./wearable/wearable.models";
+
+export type DamageReportAssigned = {
+ relatedId: string;
+} & (
+ | {
+ assigned: "equipment";
+ related: EquipmentViewModel;
+ }
+ | {
+ assigned: "vehicle";
+ related: VehicleViewModel;
+ }
+ | {
+ assigned: "wearable";
+ related: WearableViewModel;
+ }
+);
+
+export type DamageReportViewModel = {
+ id: string;
+ title: string;
+ reportedAt: Date;
+ closedAt?: Date;
+ closedBy?: string;
+ status: string;
+ description: string;
+ location: string;
+ noteByReporter: string;
+ noteByWorker: string;
+ images: string[];
+ reportedBy: string;
+ repair?: RepairViewModel;
+} & Optional;
+
+export interface CreateDamageReportViewModel {
+ title: string;
+ description: string;
+ reportedBy: string;
+ affectedId: string;
+ affected: "equipment" | "vehicle" | "wearable";
+}
+
+export interface UpdateDamageReportViewModel {
+ id: string;
+ status: string;
+ noteByWorker: string;
+ done: boolean;
+}
diff --git a/src/viewmodels/admin/unit/equipment/equipment.models.ts b/src/viewmodels/admin/unit/equipment/equipment.models.ts
new file mode 100644
index 0000000..3c778e2
--- /dev/null
+++ b/src/viewmodels/admin/unit/equipment/equipment.models.ts
@@ -0,0 +1,37 @@
+import type { EquipmentTypeViewModel } from "./equipmentType.models";
+
+export interface EquipmentViewModel {
+ id: string;
+ code?: string;
+ name: string;
+ location: string;
+ commissioned: Date;
+ decommissioned?: Date;
+ equipmentTypeId: string;
+ equipmentType: EquipmentTypeViewModel;
+}
+
+export interface MinifiedEquipmentViewModel {
+ id: string;
+ code?: string;
+ name: string;
+ type: string;
+ assigned: "equipment";
+}
+
+export interface CreateEquipmentViewModel {
+ code?: string;
+ name: string;
+ location: string;
+ commissioned: Date;
+ equipmentTypeId: string;
+}
+
+export interface UpdateEquipmentViewModel {
+ id: string;
+ code?: string;
+ name: string;
+ location: string;
+ commissioned: Date;
+ decommissioned?: Date;
+}
diff --git a/src/viewmodels/admin/unit/equipment/equipmentType.models.ts b/src/viewmodels/admin/unit/equipment/equipmentType.models.ts
new file mode 100644
index 0000000..d7dfad9
--- /dev/null
+++ b/src/viewmodels/admin/unit/equipment/equipmentType.models.ts
@@ -0,0 +1,17 @@
+export interface EquipmentTypeViewModel {
+ id: string;
+ type: string;
+ description: string;
+ equipmentCount: number;
+}
+
+export interface CreateEquipmentTypeViewModel {
+ type: string;
+ description: string;
+}
+
+export interface UpdateEquipmentTypeViewModel {
+ id: string;
+ type: string;
+ description: string;
+}
diff --git a/src/viewmodels/admin/unit/inspection/inspection.models.ts b/src/viewmodels/admin/unit/inspection/inspection.models.ts
new file mode 100644
index 0000000..bf8f770
--- /dev/null
+++ b/src/viewmodels/admin/unit/inspection/inspection.models.ts
@@ -0,0 +1,87 @@
+import type { EquipmentViewModel } from "../equipment/equipment.models";
+import type {
+ InspectionPlanViewModel,
+ InspectionPointViewModel,
+ InspectionVersionedPlanViewModel,
+} from "./inspectionPlan.models";
+import type { VehicleViewModel } from "../vehicle/vehicle.models";
+import type { WearableViewModel } from "../wearable/wearable.models";
+
+export type InspectionRelated = {
+ relatedId: string;
+} & (
+ | {
+ assigned: "equipment";
+ related: EquipmentViewModel;
+ }
+ | {
+ assigned: "vehicle";
+ related: VehicleViewModel;
+ }
+ | {
+ assigned: "wearable";
+ related: WearableViewModel;
+ }
+);
+
+export type InspectionViewModel = {
+ id: string;
+ inspectionPlanId: string;
+ inspectionPlan: InspectionPlanViewModel;
+ inspectionVersionedPlanId: string;
+ inspectionVersionedPlan: InspectionVersionedPlanViewModel;
+ context: string;
+ created: Date;
+ finishedAt?: Date;
+ finishedBy?: string;
+ isOpen: boolean;
+ nextInspection?: Date;
+ checks: Array;
+ relatedId: string;
+} & InspectionRelated;
+
+export type MinifiedInspectionViewModel = {
+ id: string;
+ inspectionPlanId: string;
+ inspectionPlan: InspectionPlanViewModel;
+ context: string;
+ created: Date;
+ finished?: Date;
+ isOpen: boolean;
+ nextInspection?: Date;
+ relatedId: string;
+} & InspectionRelated;
+
+export type InspectionNextViewModel = {
+ id: string;
+ inspectionPlanId: string;
+ inspectionPlan: InspectionPlanViewModel;
+ dueDate: Date;
+ relatedId: string;
+} & InspectionRelated;
+
+export interface InspectionPointResultViewModel {
+ inspectionId: string;
+ inspectionPointId: string;
+ inspectionPoint?: InspectionPointViewModel;
+ value: string;
+}
+
+export type CreateInspectionViewModel = {
+ assigned: "equipment" | "vehicle" | "wearable";
+ relatedId: string;
+ inspectionPlanId: string;
+ nextInspection?: Date;
+ context?: string;
+};
+
+export type UpdateInspectionViewModel = {
+ id: string;
+ nextInspection?: Date;
+ context?: string;
+};
+
+export interface CreateOrUpdateInspectionPointResultCommand {
+ inspectionPointId: string;
+ value: string;
+}
diff --git a/src/viewmodels/admin/unit/inspection/inspectionPlan.models.ts b/src/viewmodels/admin/unit/inspection/inspectionPlan.models.ts
new file mode 100644
index 0000000..ad0478c
--- /dev/null
+++ b/src/viewmodels/admin/unit/inspection/inspectionPlan.models.ts
@@ -0,0 +1,65 @@
+import type { InspectionPointEnum } from "@/enums/inspectionEnum";
+import type { EquipmentViewModel } from "../equipment/equipment.models";
+import type { VehicleViewModel } from "../vehicle/vehicle.models";
+import type { EquipmentTypeViewModel } from "../equipment/equipmentType.models";
+import type { VehicleTypeViewModel } from "../vehicle/vehicleType.models";
+import type { WearableTypeViewModel } from "../wearable/wearableType.models";
+
+export type PlanTimeDefinition = `${number}-${"d" | "m" | "y"}` | `${number}/${number | "*"}`;
+
+export type InspectionPlanViewModel = {
+ id: string;
+ title: string;
+ inspectionInterval: PlanTimeDefinition;
+ remindTime: PlanTimeDefinition;
+ version: number;
+ created: Date;
+ inspectionPoints: InspectionPointViewModel[];
+ relatedId: string;
+} & (
+ | {
+ assigned: "equipment";
+ related: EquipmentTypeViewModel;
+ }
+ | {
+ assigned: "vehicle";
+ related: VehicleTypeViewModel;
+ }
+ | {
+ assigned: "wearable";
+ related: WearableTypeViewModel;
+ }
+);
+
+export interface InspectionVersionedPlanViewModel {
+ id: string;
+ version: number;
+ created: Date;
+ inspectionPoints: InspectionPointViewModel[];
+}
+
+export interface InspectionPointViewModel {
+ id: string;
+ title: string;
+ description: string;
+ type: InspectionPointEnum;
+ min?: number;
+ max?: number;
+ others?: string;
+ sort: number;
+}
+
+export interface CreateInspectionPlanViewModel {
+ title: string;
+ inspectionInterval: PlanTimeDefinition;
+ remindTime: PlanTimeDefinition;
+ relatedId: string;
+ assigned: "vehicle" | "equipment" | "wearable";
+}
+
+export interface UpdateInspectionPlanViewModel {
+ id: string;
+ title: string;
+ inspectionInterval: PlanTimeDefinition;
+ remindTime?: PlanTimeDefinition;
+}
diff --git a/src/viewmodels/admin/unit/maintenance.models.ts b/src/viewmodels/admin/unit/maintenance.models.ts
new file mode 100644
index 0000000..bfcf1e2
--- /dev/null
+++ b/src/viewmodels/admin/unit/maintenance.models.ts
@@ -0,0 +1,40 @@
+import type { EquipmentViewModel } from "./equipment/equipment.models";
+import type { VehicleViewModel } from "./vehicle/vehicle.models";
+import type { WearableViewModel } from "./wearable/wearable.models";
+
+export type MaintenanceAssigned = {
+ relatedId: string;
+} & (
+ | {
+ assigned: "equipment";
+ related: EquipmentViewModel;
+ }
+ | {
+ assigned: "vehicle";
+ related: VehicleViewModel;
+ }
+ | {
+ assigned: "wearable";
+ related: WearableViewModel;
+ }
+);
+
+export type MaintenanceViewModel = {
+ id: string;
+ createdAt: Date;
+ status: string;
+ description: string;
+} & MaintenanceAssigned;
+
+export interface CreateMaintenanceViewModel {
+ description: string;
+ reportedBy: string;
+ affectedId: string;
+ affected: "equipment" | "vehicle" | "wearable";
+}
+
+export interface UpdateMaintenanceViewModel {
+ id: string;
+ status: string;
+ done: boolean;
+}
diff --git a/src/viewmodels/admin/unit/repair.models.ts b/src/viewmodels/admin/unit/repair.models.ts
new file mode 100644
index 0000000..7d64743
--- /dev/null
+++ b/src/viewmodels/admin/unit/repair.models.ts
@@ -0,0 +1,58 @@
+import type { DamageReportViewModel } from "./damageReport.models";
+import type { EquipmentViewModel } from "./equipment/equipment.models";
+import type { MaintenanceViewModel } from "./maintenance.models";
+import type { VehicleViewModel } from "./vehicle/vehicle.models";
+import type { WearableViewModel } from "./wearable/wearable.models";
+
+export type RepairAssigned = {
+ relatedId: string;
+} & (
+ | {
+ assigned: "equipment";
+ related: EquipmentViewModel;
+ }
+ | {
+ assigned: "vehicle";
+ related: VehicleViewModel;
+ }
+ | {
+ assigned: "wearable";
+ related: WearableViewModel;
+ }
+);
+
+export type RepairViewModel = {
+ id: string;
+ createdAt: Date;
+ finishedAt?: Date;
+ finishedBy?: string;
+ status: string;
+ responsible: string;
+ title: string;
+ description: string;
+ images: string[];
+ reportDocument: string;
+ reports: DamageReportViewModel[];
+} & RepairAssigned;
+
+export interface CreateRepairViewModel {
+ affected: "equipment" | "vehicle" | "wearable";
+ affectedId: string;
+ title: string;
+ description: string;
+ responsible: string;
+ reports: string[];
+}
+
+export interface UpdateRepairStatusViewModel {
+ id: string;
+ status: string;
+ done: boolean;
+}
+
+export interface UpdateRepairViewModel {
+ id: string;
+ title: string;
+ description: string;
+ responsible: string;
+}
diff --git a/src/viewmodels/admin/unit/respiratory/respiratoryGear.models.ts b/src/viewmodels/admin/unit/respiratory/respiratoryGear.models.ts
new file mode 100644
index 0000000..07f4ec8
--- /dev/null
+++ b/src/viewmodels/admin/unit/respiratory/respiratoryGear.models.ts
@@ -0,0 +1,16 @@
+import type { EquipmentViewModel } from "../equipment/equipment.models";
+
+export interface RespiratoryGearViewModel {
+ id: string;
+ equipmentId: string;
+ equipment: EquipmentViewModel;
+}
+
+export interface CreateRespiratoryGearViewModel {
+ equipmentId: string;
+}
+
+export interface UpdateRespiratoryGearViewModel {
+ id: string;
+ equipmentId: string;
+}
diff --git a/src/viewmodels/admin/unit/respiratory/respiratoryMission.models.ts b/src/viewmodels/admin/unit/respiratory/respiratoryMission.models.ts
new file mode 100644
index 0000000..49c6e7f
--- /dev/null
+++ b/src/viewmodels/admin/unit/respiratory/respiratoryMission.models.ts
@@ -0,0 +1,20 @@
+export interface RespiratoryMissionViewModel {
+ id: string;
+ date: Date;
+ title: string;
+ description: string;
+ // refs to used respiratory gear and wearers
+}
+
+export interface CreateRespiratoryMissionViewModel {
+ date: Date;
+ title: string;
+ description: string;
+}
+
+export interface UpdateRespiratoryMissionViewModel {
+ id: string;
+ date: Date;
+ title: string;
+ description: string;
+}
diff --git a/src/viewmodels/admin/unit/respiratory/respiratoryWearer.models.ts b/src/viewmodels/admin/unit/respiratory/respiratoryWearer.models.ts
new file mode 100644
index 0000000..eca9194
--- /dev/null
+++ b/src/viewmodels/admin/unit/respiratory/respiratoryWearer.models.ts
@@ -0,0 +1,16 @@
+import type { MemberViewModel } from "@/viewmodels/admin/club/member/member.models";
+
+export interface RespiratoryWearerViewModel {
+ id: string;
+ memberId: string;
+ member: MemberViewModel;
+}
+
+export interface CreateRespiratoryWearerViewModel {
+ memberId: string;
+}
+
+export interface UpdateRespiratoryWearerViewModel {
+ id: string;
+ memberId: string;
+}
diff --git a/src/viewmodels/admin/unit/vehicle/vehicle.models.ts b/src/viewmodels/admin/unit/vehicle/vehicle.models.ts
new file mode 100644
index 0000000..8020444
--- /dev/null
+++ b/src/viewmodels/admin/unit/vehicle/vehicle.models.ts
@@ -0,0 +1,37 @@
+import type { VehicleTypeViewModel } from "./vehicleType.models";
+
+export interface VehicleViewModel {
+ id: string;
+ code?: string;
+ name: string;
+ location: string;
+ commissioned: Date;
+ decommissioned?: Date;
+ vehicleTypeId: string;
+ vehicleType: VehicleTypeViewModel;
+}
+
+export interface MinifiedVehicleViewModel {
+ id: string;
+ code?: string;
+ name: string;
+ type: string;
+ assigned: "vehicle";
+}
+
+export interface CreateVehicleViewModel {
+ code?: string;
+ name: string;
+ location: string;
+ commissioned: Date;
+ vehicleTypeId: string;
+}
+
+export interface UpdateVehicleViewModel {
+ id: string;
+ code?: string;
+ name: string;
+ location: string;
+ commissioned: Date;
+ decommissioned?: Date;
+}
diff --git a/src/viewmodels/admin/unit/vehicle/vehicleType.models.ts b/src/viewmodels/admin/unit/vehicle/vehicleType.models.ts
new file mode 100644
index 0000000..72e1203
--- /dev/null
+++ b/src/viewmodels/admin/unit/vehicle/vehicleType.models.ts
@@ -0,0 +1,17 @@
+export interface VehicleTypeViewModel {
+ id: string;
+ type: string;
+ description: string;
+ vehicleCount: number;
+}
+
+export interface CreateVehicleTypeViewModel {
+ type: string;
+ description: string;
+}
+
+export interface UpdateVehicleTypeViewModel {
+ id: string;
+ type: string;
+ description: string;
+}
diff --git a/src/viewmodels/admin/unit/wearable/wearable.models.ts b/src/viewmodels/admin/unit/wearable/wearable.models.ts
new file mode 100644
index 0000000..eed19e1
--- /dev/null
+++ b/src/viewmodels/admin/unit/wearable/wearable.models.ts
@@ -0,0 +1,42 @@
+import type { MemberViewModel } from "@/viewmodels/admin/club/member/member.models";
+import type { WearableTypeViewModel } from "./wearableType.models";
+
+export interface WearableViewModel {
+ id: string;
+ code?: string;
+ name: string;
+ location: string;
+ commissioned: Date;
+ decommissioned?: Date;
+ wearerId?: string;
+ wearer?: MemberViewModel;
+ wearableTypeId: string;
+ wearableType: WearableTypeViewModel;
+}
+
+export interface MinifiedWearableViewModel {
+ id: string;
+ code?: string;
+ name: string;
+ type: string;
+ assigned: "wearable";
+}
+
+export interface CreateWearableViewModel {
+ code?: string;
+ name: string;
+ wearerId?: string;
+ location?: string;
+ commissioned: Date;
+ wearableTypeId: string;
+}
+
+export interface UpdateWearableViewModel {
+ id: string;
+ code?: string;
+ name: string;
+ location?: string;
+ commissioned: Date;
+ decommissioned?: Date;
+ wearerId?: string;
+}
diff --git a/src/viewmodels/admin/unit/wearable/wearableType.models.ts b/src/viewmodels/admin/unit/wearable/wearableType.models.ts
new file mode 100644
index 0000000..d3c9c0e
--- /dev/null
+++ b/src/viewmodels/admin/unit/wearable/wearableType.models.ts
@@ -0,0 +1,17 @@
+export interface WearableTypeViewModel {
+ id: string;
+ type: string;
+ description: string;
+ wearableCount: number;
+}
+
+export interface CreateWearableTypeViewModel {
+ type: string;
+ description: string;
+}
+
+export interface UpdateWearableTypeViewModel {
+ id: string;
+ type: string;
+ description: string;
+}
diff --git a/src/views/Login.vue b/src/views/Login.vue
index bc9e251..33d22f6 100644
--- a/src/views/Login.vue
+++ b/src/views/Login.vue
@@ -69,6 +69,9 @@
zum Kalender
+
+ Schaden melden
+
@@ -100,7 +103,7 @@ export default defineComponent({
};
},
computed: {
- ...mapState(useConfigurationStore, ["clubName", "appShow_link_to_calendar"]),
+ ...mapState(useConfigurationStore, ["clubName", "appShow_link_to_calendar", "appShow_link_to_damagereport"]),
},
mounted() {
this.username = localStorage.getItem("username") ?? "";
diff --git a/src/views/admin/View.vue b/src/views/admin/View.vue
index 92f6466..685dd82 100644
--- a/src/views/admin/View.vue
+++ b/src/views/admin/View.vue
@@ -26,6 +26,9 @@
{{ item.title }}
+
+
+
@@ -43,6 +46,8 @@ import SidebarTemplate from "@/templates/Sidebar.vue";
import RoutingLink from "@/components/admin/RoutingLink.vue";
import { useAbilityStore } from "@/stores/ability";
import { RouterView } from "vue-router";
+import { useScannerStore } from "@/stores/admin/scanner";
+import ScanSidebarInfo from "@/components/scanner/ScanSidebarInfo.vue";
diff --git a/src/views/admin/club/protocol/ProtocolPresence.vue b/src/views/admin/club/protocol/ProtocolPresence.vue
index d3a0862..52772cf 100644
--- a/src/views/admin/club/protocol/ProtocolPresence.vue
+++ b/src/views/admin/club/protocol/ProtocolPresence.vue
@@ -5,7 +5,7 @@
↺ laden fehlgeschlagen
-
diff --git a/src/views/admin/unit/damageReport/DamageReport.vue b/src/views/admin/unit/damageReport/DamageReport.vue
new file mode 100644
index 0000000..a42ef70
--- /dev/null
+++ b/src/views/admin/unit/damageReport/DamageReport.vue
@@ -0,0 +1,45 @@
+
+
+
fetchOpenDamageReports(offset, count, search)"
+ >
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/damageReport/DamageReportClosed.vue b/src/views/admin/unit/damageReport/DamageReportClosed.vue
new file mode 100644
index 0000000..e6c236b
--- /dev/null
+++ b/src/views/admin/unit/damageReport/DamageReportClosed.vue
@@ -0,0 +1,45 @@
+
+
+
fetchDoneDamageReports(offset, count, search)"
+ >
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/damageReport/DamageReportRouting.vue b/src/views/admin/unit/damageReport/DamageReportRouting.vue
new file mode 100644
index 0000000..c876d31
--- /dev/null
+++ b/src/views/admin/unit/damageReport/DamageReportRouting.vue
@@ -0,0 +1,94 @@
+
+
+
+ zurück zur Liste
+
+
+
+ {{ activeDamageReportObj?.title }} -
+ {{ activeDamageReportObj?.related?.name ?? "Ohne Zuordnung" }}
+ ({{ activeDamageReportObj.related.code }})
+
+
+
+
+
+
+
+
+
+
+ {{ tab.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/damageReport/DamageReportStatusRouting.vue b/src/views/admin/unit/damageReport/DamageReportStatusRouting.vue
new file mode 100644
index 0000000..2ddb06c
--- /dev/null
+++ b/src/views/admin/unit/damageReport/DamageReportStatusRouting.vue
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ {{ tab.title }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/damageReport/Overview.vue b/src/views/admin/unit/damageReport/Overview.vue
new file mode 100644
index 0000000..a24aa2e
--- /dev/null
+++ b/src/views/admin/unit/damageReport/Overview.vue
@@ -0,0 +1,142 @@
+
+
+
+
+ Status
+
+
+
+ Anmerkung durch Bearbeiter
+
+
+
+ Status ändern
+
+
+ speichern und abschließen
+ Status speichern
+
+
+
+ Beschreibung des Schadens
+
+
+
+ Fundort
+
+
+
+ Anmerkung für Bearbeiter
+
+
+
+ Gemeldet von
+
+
+
+
Bild
+
+ Keine Bilder hochgeladen
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/equipment/CreateEquipment.vue b/src/views/admin/unit/equipment/CreateEquipment.vue
new file mode 100644
index 0000000..2699608
--- /dev/null
+++ b/src/views/admin/unit/equipment/CreateEquipment.vue
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/equipment/DamageReport.vue b/src/views/admin/unit/equipment/DamageReport.vue
new file mode 100644
index 0000000..790bd11
--- /dev/null
+++ b/src/views/admin/unit/equipment/DamageReport.vue
@@ -0,0 +1,68 @@
+
+
+
fetchDamageReportForEquipment(offset, count, search)"
+ >
+
+
+
+
+
{{ row.title }} - {{ new Date(row.reportedAt).toLocaleString("de") }} - {{ row.status }}
+
+
+
+
Beschreibung: {{ row.description }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/equipment/Equipment.vue b/src/views/admin/unit/equipment/Equipment.vue
new file mode 100644
index 0000000..4576190
--- /dev/null
+++ b/src/views/admin/unit/equipment/Equipment.vue
@@ -0,0 +1,65 @@
+
+
+
+
+
fetchEquipments(offset, count, search)"
+ @search="(search) => fetchEquipments(0, maxEntriesPerPage, search, true)"
+ >
+
+
+
+
+
+
+
+ Gerätschaft erfassen
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/equipment/EquipmentRouting.vue b/src/views/admin/unit/equipment/EquipmentRouting.vue
new file mode 100644
index 0000000..4b2bb34
--- /dev/null
+++ b/src/views/admin/unit/equipment/EquipmentRouting.vue
@@ -0,0 +1,76 @@
+
+
+
+ zurück zur Liste
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ tab.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/equipment/Inspection.vue b/src/views/admin/unit/equipment/Inspection.vue
new file mode 100644
index 0000000..e2a2b27
--- /dev/null
+++ b/src/views/admin/unit/equipment/Inspection.vue
@@ -0,0 +1,69 @@
+
+
+
fetchInspectionForEquipment(offset, count, false)"
+ >
+
+
+
+
+
{{ row.inspectionPlan.title }} - {{ row.finishedAt ?? "in Arbeit" }}
+
+
+
Kontext: {{ row.context }}
+
nächste Inspektion: {{ row.nextInspection }}
+
+
+
+
+
+
+ Prüfung durchführen
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/equipment/Overview.vue b/src/views/admin/unit/equipment/Overview.vue
new file mode 100644
index 0000000..99304e6
--- /dev/null
+++ b/src/views/admin/unit/equipment/Overview.vue
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+ ↺ laden fehlgeschlagen
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/equipment/Repair.vue b/src/views/admin/unit/equipment/Repair.vue
new file mode 100644
index 0000000..2cb4485
--- /dev/null
+++ b/src/views/admin/unit/equipment/Repair.vue
@@ -0,0 +1,63 @@
+
+
+
fetchRepairForEquipment(offset, count, search)"
+ >
+
+
+
+
+
{{ new Date(row.createdAt).toLocaleString("de") }} - {{ row.status }}
+
+
+
Beschreibung: {{ row.description }}
+
+
+
+
+
+ Reparatur erstellen
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/equipment/UpdateEquipment.vue b/src/views/admin/unit/equipment/UpdateEquipment.vue
new file mode 100644
index 0000000..17eff62
--- /dev/null
+++ b/src/views/admin/unit/equipment/UpdateEquipment.vue
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/equipmentType/EquipmentType.vue b/src/views/admin/unit/equipmentType/EquipmentType.vue
new file mode 100644
index 0000000..f7f3d6b
--- /dev/null
+++ b/src/views/admin/unit/equipmentType/EquipmentType.vue
@@ -0,0 +1,67 @@
+
+
+
+
+
fetchEquipmentTypes(offset, count, search)"
+ @search="(search) => fetchEquipmentTypes(0, maxEntriesPerPage, search, true)"
+ >
+
+
+
+
+
+
+
+ Geräte-Typ erstellen
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/equipmentType/EquipmentTypeRouting.vue b/src/views/admin/unit/equipmentType/EquipmentTypeRouting.vue
new file mode 100644
index 0000000..6a6aed1
--- /dev/null
+++ b/src/views/admin/unit/equipmentType/EquipmentTypeRouting.vue
@@ -0,0 +1,90 @@
+
+
+
+ zurück zur Liste
+
+
+
+
+
+
+
+
+
+
+ {{ tab.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/equipmentType/InspectionPlans.vue b/src/views/admin/unit/equipmentType/InspectionPlans.vue
new file mode 100644
index 0000000..5acfba9
--- /dev/null
+++ b/src/views/admin/unit/equipmentType/InspectionPlans.vue
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
↺ laden fehlgeschlagen
+
+
+
+ Prüfplan erstellen
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/equipmentType/Overview.vue b/src/views/admin/unit/equipmentType/Overview.vue
new file mode 100644
index 0000000..76418a1
--- /dev/null
+++ b/src/views/admin/unit/equipmentType/Overview.vue
@@ -0,0 +1,43 @@
+
+
+
+
+ Typ
+
+
+
+ Beschreibung
+
+
+
+
+
+
+ ↺ laden fehlgeschlagen
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/equipmentType/UpdateEquipmentType.vue b/src/views/admin/unit/equipmentType/UpdateEquipmentType.vue
new file mode 100644
index 0000000..997e0be
--- /dev/null
+++ b/src/views/admin/unit/equipmentType/UpdateEquipmentType.vue
@@ -0,0 +1,116 @@
+
+
+
+
laden fehlgeschlagen
+
+ Geräte-Typ bearbeiten
+
+ Typ
+
+
+
+ Beschreibung
+
+
+
+
+ abbrechen
+
+ speichern
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/inspection/InspectionExecute.vue b/src/views/admin/unit/inspection/InspectionExecute.vue
new file mode 100644
index 0000000..0a1e886
--- /dev/null
+++ b/src/views/admin/unit/inspection/InspectionExecute.vue
@@ -0,0 +1,243 @@
+
+
+
+
+ Prüfung durchführen: {{ activeInspectionObj?.related.name }}
+ ({{ activeInspectionObj?.related.code }}) -
+ {{ activeInspectionObj?.inspectionPlan.title }}
+
+
+
+
+
+
+
+ laden fehlgeschlagen
+
+
+
+
+
+
+ verwerfen
+
+
+ zwischenspeichern
+
+
+ abschließen
+
+
+
+
+
+
+ Bericht anzeigen
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/inspection/InspectionRouting.vue b/src/views/admin/unit/inspection/InspectionRouting.vue
new file mode 100644
index 0000000..6307df1
--- /dev/null
+++ b/src/views/admin/unit/inspection/InspectionRouting.vue
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+ {{ tab.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/inspection/InspectionStart.vue b/src/views/admin/unit/inspection/InspectionStart.vue
new file mode 100644
index 0000000..88e49c9
--- /dev/null
+++ b/src/views/admin/unit/inspection/InspectionStart.vue
@@ -0,0 +1,228 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dieser Prüfplan ist noch nicht fertig gestellt!
+
+
+
+
+ Nächste Prüfung
+
+ - Intervall: {{ selectedInspectionPlan.inspectionInterval }}
+
+ (optional)
+
+
+
+
+
+
+
+ Kontext
+
+
+
+
+
+ abbrechen
+
+ starten
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/inspection/NextInspections.vue b/src/views/admin/unit/inspection/NextInspections.vue
new file mode 100644
index 0000000..76ee7ec
--- /dev/null
+++ b/src/views/admin/unit/inspection/NextInspections.vue
@@ -0,0 +1,68 @@
+
+
+
fetchNextInspections(offset, count, search)"
+ >
+
+
+
+
+ {{ row.related.name }} ({{ row.related.code }}) -
+ {{ row.inspectionPlan.title }} - {{ row.dueDate ?? "ohne Fälligkeit" }}
+
+
+
+
+
+
+
+
+ Prüfung starten
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/inspection/RunningInspections.vue b/src/views/admin/unit/inspection/RunningInspections.vue
new file mode 100644
index 0000000..225a30e
--- /dev/null
+++ b/src/views/admin/unit/inspection/RunningInspections.vue
@@ -0,0 +1,67 @@
+
+
+
fetchRunningInspections(offset, count, search)"
+ >
+
+
+
+
+
{{ row.inspectionPlan.title }} - in Arbeit seit {{ row.created }}
+
+
+
Kontext: {{ row.context }}
+
+
+
+
+
+
+
+ Prüfung starten
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/inspectionPlan/CreateInspectionPlan.vue b/src/views/admin/unit/inspectionPlan/CreateInspectionPlan.vue
new file mode 100644
index 0000000..5170235
--- /dev/null
+++ b/src/views/admin/unit/inspectionPlan/CreateInspectionPlan.vue
@@ -0,0 +1,174 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/inspectionPlan/InspectionPlan.vue b/src/views/admin/unit/inspectionPlan/InspectionPlan.vue
new file mode 100644
index 0000000..fe91823
--- /dev/null
+++ b/src/views/admin/unit/inspectionPlan/InspectionPlan.vue
@@ -0,0 +1,65 @@
+
+
+
+
+
fetchInspectionPlans(offset, count, search)"
+ @search="(search) => fetchInspectionPlans(0, maxEntriesPerPage, search, true)"
+ >
+
+
+
+
+
+
+
+ Prüfplan erstellen
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/inspectionPlan/InspectionPlanRouting.vue b/src/views/admin/unit/inspectionPlan/InspectionPlanRouting.vue
new file mode 100644
index 0000000..a0299ab
--- /dev/null
+++ b/src/views/admin/unit/inspectionPlan/InspectionPlanRouting.vue
@@ -0,0 +1,58 @@
+
+
+
+ zurück zur Liste
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/inspectionPlan/Overview.vue b/src/views/admin/unit/inspectionPlan/Overview.vue
new file mode 100644
index 0000000..a1cb874
--- /dev/null
+++ b/src/views/admin/unit/inspectionPlan/Overview.vue
@@ -0,0 +1,80 @@
+
+
+
+
Prüfungspunkte:
+
+
+
+
+ ↺ laden fehlgeschlagen
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/inspectionPlan/UpdateInspectionPlan.vue b/src/views/admin/unit/inspectionPlan/UpdateInspectionPlan.vue
new file mode 100644
index 0000000..7756130
--- /dev/null
+++ b/src/views/admin/unit/inspectionPlan/UpdateInspectionPlan.vue
@@ -0,0 +1,144 @@
+
+
+
zurück zur Übersicht
+
+
laden fehlgeschlagen
+
+ Prüfplan bearbeiten
+
+ Bezeichnung
+
+
+
+
+ Intervall
+
+
+
+
+
+
+ Erinnerung vor Fälligkeit
+
+
+
+
+
+
+ abbrechen
+
+ speichern
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/inspectionPlan/UpdateInspectionPlanPoints.vue b/src/views/admin/unit/inspectionPlan/UpdateInspectionPlanPoints.vue
new file mode 100644
index 0000000..1cf03c2
--- /dev/null
+++ b/src/views/admin/unit/inspectionPlan/UpdateInspectionPlanPoints.vue
@@ -0,0 +1,192 @@
+
+
+
zurück zur Übersicht
+
+
laden fehlgeschlagen
+
+ Prüfplan-Punkte bearbeiten
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ abbrechen
+
+
+ speichern
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/maintenance/Maintenance.vue b/src/views/admin/unit/maintenance/Maintenance.vue
new file mode 100644
index 0000000..5afc9f4
--- /dev/null
+++ b/src/views/admin/unit/maintenance/Maintenance.vue
@@ -0,0 +1,45 @@
+
+
+
fetchMaintenances(offset, count, search)"
+ >
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/maintenance/MaintenanceRouting.vue b/src/views/admin/unit/maintenance/MaintenanceRouting.vue
new file mode 100644
index 0000000..0da37c4
--- /dev/null
+++ b/src/views/admin/unit/maintenance/MaintenanceRouting.vue
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+ {{ tab.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/repair/DamageReports.vue b/src/views/admin/unit/repair/DamageReports.vue
new file mode 100644
index 0000000..86250d3
--- /dev/null
+++ b/src/views/admin/unit/repair/DamageReports.vue
@@ -0,0 +1,96 @@
+
+
+
+
+
+ Änderungen speichern
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/repair/Overview.vue b/src/views/admin/unit/repair/Overview.vue
new file mode 100644
index 0000000..ba1f362
--- /dev/null
+++ b/src/views/admin/unit/repair/Overview.vue
@@ -0,0 +1,141 @@
+
+
+
+ Status
+
+
+
+ Status ändern
+
+
+ speichern und abschließen
+ Status speichern
+
+
+
+
+ Kurzbeschreibung
+
+
+
+ Beschreibung der Reparatur
+
+
+
+ Verantwortlich
+
+
+
+ Änderungen speichern
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/repair/RepairClosed.vue b/src/views/admin/unit/repair/RepairClosed.vue
new file mode 100644
index 0000000..2b96684
--- /dev/null
+++ b/src/views/admin/unit/repair/RepairClosed.vue
@@ -0,0 +1,45 @@
+
+
+
fetchDoneRepairs(offset, count, search)"
+ >
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/repair/RepairCreate.vue b/src/views/admin/unit/repair/RepairCreate.vue
new file mode 100644
index 0000000..6355228
--- /dev/null
+++ b/src/views/admin/unit/repair/RepairCreate.vue
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+
+
+
+
+
+ Kurzbeschreibung
+
+
+
+
+ Beschreibung (optional)
+
+
+
+
+ Verantwortlich (optional)
+
+
+
+
+
+
+
+ abbrechen
+
+ starten
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/repair/RepairOpen.vue b/src/views/admin/unit/repair/RepairOpen.vue
new file mode 100644
index 0000000..671c3e9
--- /dev/null
+++ b/src/views/admin/unit/repair/RepairOpen.vue
@@ -0,0 +1,45 @@
+
+
+
fetchOpenRepairs(offset, count, search)"
+ >
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/repair/RepairRouting.vue b/src/views/admin/unit/repair/RepairRouting.vue
new file mode 100644
index 0000000..06b45ca
--- /dev/null
+++ b/src/views/admin/unit/repair/RepairRouting.vue
@@ -0,0 +1,86 @@
+
+
+
+ zurück zur Liste
+
+
+
+ {{ activeRepairObj?.title }} -
+ {{ activeRepairObj?.related?.name ?? "Ohne Zuordnung" }}
+ ({{ activeRepairObj.related.code }})
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ tab.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/repair/RepairStatusRouting.vue b/src/views/admin/unit/repair/RepairStatusRouting.vue
new file mode 100644
index 0000000..9c9deed
--- /dev/null
+++ b/src/views/admin/unit/repair/RepairStatusRouting.vue
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+ {{ tab.title }}
+
+
+
+
+
+ Reparatur erstellen
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/respiratoryGear/CreateRespiratoryGear.vue b/src/views/admin/unit/respiratoryGear/CreateRespiratoryGear.vue
new file mode 100644
index 0000000..71f98f0
--- /dev/null
+++ b/src/views/admin/unit/respiratoryGear/CreateRespiratoryGear.vue
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+ abbrechen
+
+ speichern
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/respiratoryGear/RespiratoryGear.vue b/src/views/admin/unit/respiratoryGear/RespiratoryGear.vue
new file mode 100644
index 0000000..211bd36
--- /dev/null
+++ b/src/views/admin/unit/respiratoryGear/RespiratoryGear.vue
@@ -0,0 +1,73 @@
+
+
+
+
+
fetchRespiratoryGears(offset, count, search)"
+ @search="(search) => fetchRespiratoryGears(0, maxEntriesPerPage, search, true)"
+ >
+
+
+
+
+
+
+
+ Gerät erfassen
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/respiratoryGear/RespiratoryGearRouting.vue b/src/views/admin/unit/respiratoryGear/RespiratoryGearRouting.vue
new file mode 100644
index 0000000..c000096
--- /dev/null
+++ b/src/views/admin/unit/respiratoryGear/RespiratoryGearRouting.vue
@@ -0,0 +1,83 @@
+
+
+
+ zurück zur Liste
+
+
+ AGT-Gerät: {{ activeRespiratoryGearObj?.equipment.name }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ tab.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/respiratoryMission/CreateRespiratoryMission.vue b/src/views/admin/unit/respiratoryMission/CreateRespiratoryMission.vue
new file mode 100644
index 0000000..3687b54
--- /dev/null
+++ b/src/views/admin/unit/respiratoryMission/CreateRespiratoryMission.vue
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+ Titel
+
+
+
+ Bezeichnung
+
+
+
+ Datum & Uhrzeit
+
+
+
+
+ abbrechen
+
+ speichern
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/respiratoryMission/RespiratoryMission.vue b/src/views/admin/unit/respiratoryMission/RespiratoryMission.vue
new file mode 100644
index 0000000..c3f4834
--- /dev/null
+++ b/src/views/admin/unit/respiratoryMission/RespiratoryMission.vue
@@ -0,0 +1,65 @@
+
+
+
+
+
fetchRespiratoryMissions(offset, count, search)"
+ @search="(search) => fetchRespiratoryMissions(0, maxEntriesPerPage, search, true)"
+ >
+
+
+
+
+
+
+
+ Einsatz erfassen
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/respiratoryMission/RespiratoryMissionRouting.vue b/src/views/admin/unit/respiratoryMission/RespiratoryMissionRouting.vue
new file mode 100644
index 0000000..8aee76d
--- /dev/null
+++ b/src/views/admin/unit/respiratoryMission/RespiratoryMissionRouting.vue
@@ -0,0 +1,71 @@
+
+
+
+ zurück zur Liste
+
+
+ AGT-Einsatz: {{ activeRespiratoryMissionObj?.title }}
+
+
+
+
+
+
+
+ {{ tab.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/respiratoryWearer/CreateRespiratoryWearer.vue b/src/views/admin/unit/respiratoryWearer/CreateRespiratoryWearer.vue
new file mode 100644
index 0000000..7334432
--- /dev/null
+++ b/src/views/admin/unit/respiratoryWearer/CreateRespiratoryWearer.vue
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+ abbrechen
+
+ speichern
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/respiratoryWearer/RespiratoryWearer.vue b/src/views/admin/unit/respiratoryWearer/RespiratoryWearer.vue
new file mode 100644
index 0000000..58f664a
--- /dev/null
+++ b/src/views/admin/unit/respiratoryWearer/RespiratoryWearer.vue
@@ -0,0 +1,75 @@
+
+
+
+
+
fetchRespiratoryWearers(offset, count, search)"
+ @search="(search) => fetchRespiratoryWearers(0, maxEntriesPerPage, search, true)"
+ >
+
+
+
+
+
+
+
+ Träger erfassen
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/respiratoryWearer/RespiratoryWearerRouting.vue b/src/views/admin/unit/respiratoryWearer/RespiratoryWearerRouting.vue
new file mode 100644
index 0000000..a72cbc8
--- /dev/null
+++ b/src/views/admin/unit/respiratoryWearer/RespiratoryWearerRouting.vue
@@ -0,0 +1,77 @@
+
+
+
+ zurück zur Liste
+
+
+
+ AGT-Träger: {{ activeRespiratoryWearerObj?.member.lastname }},
+ {{ activeRespiratoryWearerObj?.member.firstname }}
+
+
+
+
+
+
+
+
+ {{ tab.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/vehicle/CreateVehicle.vue b/src/views/admin/unit/vehicle/CreateVehicle.vue
new file mode 100644
index 0000000..b3e9581
--- /dev/null
+++ b/src/views/admin/unit/vehicle/CreateVehicle.vue
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/vehicle/DamageReport.vue b/src/views/admin/unit/vehicle/DamageReport.vue
new file mode 100644
index 0000000..9a8b18a
--- /dev/null
+++ b/src/views/admin/unit/vehicle/DamageReport.vue
@@ -0,0 +1,68 @@
+
+
+
fetchDamageReportForVehicle(offset, count, search)"
+ >
+
+
+
+
+
{{ row.title }} - {{ new Date(row.reportedAt).toLocaleString("de") }} - {{ row.status }}
+
+
+
+
Beschreibung: {{ row.description }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/vehicle/Inspection.vue b/src/views/admin/unit/vehicle/Inspection.vue
new file mode 100644
index 0000000..1f94f37
--- /dev/null
+++ b/src/views/admin/unit/vehicle/Inspection.vue
@@ -0,0 +1,69 @@
+
+
+
fetchInspectionForVehicle(offset, count, search)"
+ >
+
+
+
+
+
{{ row.inspectionPlan.title }} - {{ row.finishedAt ?? "in Arbeit" }}
+
+
+
Kontext: {{ row.context }}
+
nächste Inspektion: {{ row.nextInspection }}
+
+
+
+
+
+
+ Prüfung durchführen
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/vehicle/Overview.vue b/src/views/admin/unit/vehicle/Overview.vue
new file mode 100644
index 0000000..3dbc194
--- /dev/null
+++ b/src/views/admin/unit/vehicle/Overview.vue
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+ ↺ laden fehlgeschlagen
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/vehicle/Repair.vue b/src/views/admin/unit/vehicle/Repair.vue
new file mode 100644
index 0000000..330ae96
--- /dev/null
+++ b/src/views/admin/unit/vehicle/Repair.vue
@@ -0,0 +1,63 @@
+
+
+
fetchRepairForVehicle(offset, count, search)"
+ >
+
+
+
+
+
{{ new Date(row.createdAt).toLocaleString("de") }} - {{ row.status }}
+
+
+
Beschreibung: {{ row.description }}
+
+
+
+
+
+ Reparatur erstellen
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/vehicle/UpdateVehicle.vue b/src/views/admin/unit/vehicle/UpdateVehicle.vue
new file mode 100644
index 0000000..bd0aeba
--- /dev/null
+++ b/src/views/admin/unit/vehicle/UpdateVehicle.vue
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/vehicle/Vehicle.vue b/src/views/admin/unit/vehicle/Vehicle.vue
new file mode 100644
index 0000000..4861759
--- /dev/null
+++ b/src/views/admin/unit/vehicle/Vehicle.vue
@@ -0,0 +1,65 @@
+
+
+
+
+
fetchVehicles(offset, count, search)"
+ @search="(search) => fetchVehicles(0, maxEntriesPerPage, search, true)"
+ >
+
+
+
+
+
+
+
+ Fahrzeug erfassen
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/vehicle/VehicleRouting.vue b/src/views/admin/unit/vehicle/VehicleRouting.vue
new file mode 100644
index 0000000..5a99b35
--- /dev/null
+++ b/src/views/admin/unit/vehicle/VehicleRouting.vue
@@ -0,0 +1,76 @@
+
+
+
+ zurück zur Liste
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ tab.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/vehicleType/InspectionPlans.vue b/src/views/admin/unit/vehicleType/InspectionPlans.vue
new file mode 100644
index 0000000..c0e3de1
--- /dev/null
+++ b/src/views/admin/unit/vehicleType/InspectionPlans.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
↺ laden fehlgeschlagen
+
+
+
+
+ Prüfplan erstellen
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/vehicleType/Overview.vue b/src/views/admin/unit/vehicleType/Overview.vue
new file mode 100644
index 0000000..d975f89
--- /dev/null
+++ b/src/views/admin/unit/vehicleType/Overview.vue
@@ -0,0 +1,43 @@
+
+
+
+
+ Typ
+
+
+
+ Beschreibung
+
+
+
+
+
+
+ ↺ laden fehlgeschlagen
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/vehicleType/UpdateVehicleType.vue b/src/views/admin/unit/vehicleType/UpdateVehicleType.vue
new file mode 100644
index 0000000..0878435
--- /dev/null
+++ b/src/views/admin/unit/vehicleType/UpdateVehicleType.vue
@@ -0,0 +1,116 @@
+
+
+
+
laden fehlgeschlagen
+
+ Fahrzeug-Typ bearbeiten
+
+ Typ
+
+
+
+ Beschreibung
+
+
+
+
+ abbrechen
+
+ speichern
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/vehicleType/VehicleType.vue b/src/views/admin/unit/vehicleType/VehicleType.vue
new file mode 100644
index 0000000..48aca02
--- /dev/null
+++ b/src/views/admin/unit/vehicleType/VehicleType.vue
@@ -0,0 +1,65 @@
+
+
+
+
+
fetchVehicleTypes(offset, count, search)"
+ @search="(search) => fetchVehicleTypes(0, maxEntriesPerPage, search, true)"
+ >
+
+
+
+
+
+
+
+ Fahrzeug-Typ erstellen
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/vehicleType/VehicleTypeRouting.vue b/src/views/admin/unit/vehicleType/VehicleTypeRouting.vue
new file mode 100644
index 0000000..c4e0321
--- /dev/null
+++ b/src/views/admin/unit/vehicleType/VehicleTypeRouting.vue
@@ -0,0 +1,88 @@
+
+
+
+ zurück zur Liste
+
+
+
+
+
+
+
+
+
+
+ {{ tab.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/wearable/CreateWearable.vue b/src/views/admin/unit/wearable/CreateWearable.vue
new file mode 100644
index 0000000..c04c8d2
--- /dev/null
+++ b/src/views/admin/unit/wearable/CreateWearable.vue
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/wearable/DamageReport.vue b/src/views/admin/unit/wearable/DamageReport.vue
new file mode 100644
index 0000000..7ee53af
--- /dev/null
+++ b/src/views/admin/unit/wearable/DamageReport.vue
@@ -0,0 +1,68 @@
+
+
+
fetchDamageReportForWearable(offset, count, search)"
+ >
+
+
+
+
+
{{ row.title }} - {{ new Date(row.reportedAt).toLocaleString("de") }} - {{ row.status }}
+
+
+
+
Beschreibung: {{ row.description }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/wearable/Inspection.vue b/src/views/admin/unit/wearable/Inspection.vue
new file mode 100644
index 0000000..3b4277a
--- /dev/null
+++ b/src/views/admin/unit/wearable/Inspection.vue
@@ -0,0 +1,69 @@
+
+
+
fetchInspectionForWearable(offset, count, search)"
+ >
+
+
+
+
+
{{ row.inspectionPlan.title }} - {{ row.finishedAt ?? "in Arbeit" }}
+
+
+
Kontext: {{ row.context }}
+
nächste Inspektion: {{ row.nextInspection }}
+
+
+
+
+
+
+ Prüfung durchführen
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/wearable/Overview.vue b/src/views/admin/unit/wearable/Overview.vue
new file mode 100644
index 0000000..656f456
--- /dev/null
+++ b/src/views/admin/unit/wearable/Overview.vue
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+ ↺ laden fehlgeschlagen
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/wearable/Repair.vue b/src/views/admin/unit/wearable/Repair.vue
new file mode 100644
index 0000000..7bc1f3c
--- /dev/null
+++ b/src/views/admin/unit/wearable/Repair.vue
@@ -0,0 +1,63 @@
+
+
+
fetchRepairForWearable(offset, count, search)"
+ >
+
+
+
+
+
{{ new Date(row.createdAt).toLocaleString("de") }} - {{ row.status }}
+
+
+
Beschreibung: {{ row.description }}
+
+
+
+
+
+ Reparatur erstellen
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/wearable/UpdateWearable.vue b/src/views/admin/unit/wearable/UpdateWearable.vue
new file mode 100644
index 0000000..541c69f
--- /dev/null
+++ b/src/views/admin/unit/wearable/UpdateWearable.vue
@@ -0,0 +1,134 @@
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/wearable/Wearable.vue b/src/views/admin/unit/wearable/Wearable.vue
new file mode 100644
index 0000000..46dea73
--- /dev/null
+++ b/src/views/admin/unit/wearable/Wearable.vue
@@ -0,0 +1,65 @@
+
+
+
+
+
fetchWearables(offset, count, search)"
+ @search="(search) => fetchWearables(0, maxEntriesPerPage, search, true)"
+ >
+
+
+
+
+
+
+
+ Kleidung erfassen
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/wearable/WearableRouting.vue b/src/views/admin/unit/wearable/WearableRouting.vue
new file mode 100644
index 0000000..caa5fd9
--- /dev/null
+++ b/src/views/admin/unit/wearable/WearableRouting.vue
@@ -0,0 +1,76 @@
+
+
+
+ zurück zur Liste
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ tab.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/wearableType/InspectionPlans.vue b/src/views/admin/unit/wearableType/InspectionPlans.vue
new file mode 100644
index 0000000..86a2bbe
--- /dev/null
+++ b/src/views/admin/unit/wearableType/InspectionPlans.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
↺ laden fehlgeschlagen
+
+
+
+
+ Prüfplan erstellen
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/wearableType/Overview.vue b/src/views/admin/unit/wearableType/Overview.vue
new file mode 100644
index 0000000..5e0444e
--- /dev/null
+++ b/src/views/admin/unit/wearableType/Overview.vue
@@ -0,0 +1,43 @@
+
+
+
+
+ Typ
+
+
+
+ Beschreibung
+
+
+
+
+
+
+ ↺ laden fehlgeschlagen
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/wearableType/UpdateWearableType.vue b/src/views/admin/unit/wearableType/UpdateWearableType.vue
new file mode 100644
index 0000000..cf85991
--- /dev/null
+++ b/src/views/admin/unit/wearableType/UpdateWearableType.vue
@@ -0,0 +1,116 @@
+
+
+
+
laden fehlgeschlagen
+
+ Kleidungstyp bearbeiten
+
+ Bezeichnung
+
+
+
+ Beschreibung (optional)
+
+
+
+
+ abbrechen
+
+ speichern
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/wearableType/WearableType.vue b/src/views/admin/unit/wearableType/WearableType.vue
new file mode 100644
index 0000000..fcf5958
--- /dev/null
+++ b/src/views/admin/unit/wearableType/WearableType.vue
@@ -0,0 +1,65 @@
+
+
+
+
+
fetchWearableTypes(offset, count, search)"
+ @search="(search) => fetchWearableTypes(0, maxEntriesPerPage, search, true)"
+ >
+
+
+
+
+
+
+
+ Kleidungs-Typ erstellen
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/unit/wearableType/WearableTypeRouting.vue b/src/views/admin/unit/wearableType/WearableTypeRouting.vue
new file mode 100644
index 0000000..f2750d3
--- /dev/null
+++ b/src/views/admin/unit/wearableType/WearableTypeRouting.vue
@@ -0,0 +1,88 @@
+
+
+
+ zurück zur Liste
+
+
+
+
+
+
+
+
+
+
+ {{ tab.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/public/damageReport/Report.vue b/src/views/public/damageReport/Report.vue
new file mode 100644
index 0000000..50380f4
--- /dev/null
+++ b/src/views/public/damageReport/Report.vue
@@ -0,0 +1,124 @@
+
+
+
+
+ {{ dictionary[step] == "result" ? "zurück zu Startseite" : "abbrechen" }}
+
+
+
+
+ (content.gear = gear)"
+ />
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/public/scanner/RoomSelect.vue b/src/views/public/scanner/RoomSelect.vue
new file mode 100644
index 0000000..6913c9c
--- /dev/null
+++ b/src/views/public/scanner/RoomSelect.vue
@@ -0,0 +1,67 @@
+
+
+
+
+ Scan-Id
+
+
+
+ Zugang prüfen
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/public/scanner/Scanner.vue b/src/views/public/scanner/Scanner.vue
new file mode 100644
index 0000000..b9b0174
--- /dev/null
+++ b/src/views/public/scanner/Scanner.vue
@@ -0,0 +1,114 @@
+
+
+
+ Zurück zur Sessionauswahl
+
+
+
+
+
+
+ {{ c.label }}
+
+
+ weiter scannen
+ bestätigen
+
+
+
+
+
+
+
+
diff --git a/src/views/public/scanner/ScannerRouting.vue b/src/views/public/scanner/ScannerRouting.vue
new file mode 100644
index 0000000..bc8c738
--- /dev/null
+++ b/src/views/public/scanner/ScannerRouting.vue
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+