From 553eeb7bfbed4c9206a8f41c2c08b889b0a9ce15 Mon Sep 17 00:00:00 2001 From: Julian Krauser Date: Tue, 1 Apr 2025 16:11:39 +0200 Subject: [PATCH] wearable --- .../admin/unit/wearable/WearableListItem.vue | 33 +++ .../wearableType/CreateWearableTypeModal.vue | 82 +++++++ .../wearableType/DeleteWearableTypeModal.vue | 84 +++++++ .../wearableType/WearableTypeListItem.vue | 27 +++ src/demodata/wearable.ts | 22 ++ src/demodata/wearableType.ts | 9 + src/router/index.ts | 74 ++++++ src/router/unit/wearable.ts | 20 ++ src/stores/admin/navigation.ts | 4 + src/stores/admin/unit/wearable/wearable.ts | 108 +++++++++ .../admin/unit/wearableType/wearableType.ts | 81 +++++++ src/types/permissionTypes.ts | 6 + .../admin/unit/wearable/wearable.models.ts | 29 +++ .../unit/wearableType/wearableType.models.ts | 16 ++ .../admin/unit/wearable/CreateWearable.vue | 214 ++++++++++++++++++ src/views/admin/unit/wearable/Overview.vue | 51 +++++ .../admin/unit/wearable/UpdateWearable.vue | 121 ++++++++++ src/views/admin/unit/wearable/Wearable.vue | 70 ++++++ .../admin/unit/wearable/WearableRouting.vue | 79 +++++++ .../unit/wearableType/UpdateWearableType.vue | 118 ++++++++++ .../admin/unit/wearableType/WearableType.vue | 70 ++++++ 21 files changed, 1318 insertions(+) create mode 100644 src/components/admin/unit/wearable/WearableListItem.vue create mode 100644 src/components/admin/unit/wearableType/CreateWearableTypeModal.vue create mode 100644 src/components/admin/unit/wearableType/DeleteWearableTypeModal.vue create mode 100644 src/components/admin/unit/wearableType/WearableTypeListItem.vue create mode 100644 src/demodata/wearable.ts create mode 100644 src/demodata/wearableType.ts create mode 100644 src/router/unit/wearable.ts create mode 100644 src/stores/admin/unit/wearable/wearable.ts create mode 100644 src/stores/admin/unit/wearableType/wearableType.ts create mode 100644 src/viewmodels/admin/unit/wearable/wearable.models.ts create mode 100644 src/viewmodels/admin/unit/wearableType/wearableType.models.ts create mode 100644 src/views/admin/unit/wearable/CreateWearable.vue create mode 100644 src/views/admin/unit/wearable/Overview.vue create mode 100644 src/views/admin/unit/wearable/UpdateWearable.vue create mode 100644 src/views/admin/unit/wearable/Wearable.vue create mode 100644 src/views/admin/unit/wearable/WearableRouting.vue create mode 100644 src/views/admin/unit/wearableType/UpdateWearableType.vue create mode 100644 src/views/admin/unit/wearableType/WearableType.vue 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 @@ + + + + + diff --git a/src/components/admin/unit/wearableType/CreateWearableTypeModal.vue b/src/components/admin/unit/wearableType/CreateWearableTypeModal.vue new file mode 100644 index 0000000..8a97cfb --- /dev/null +++ b/src/components/admin/unit/wearableType/CreateWearableTypeModal.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/src/components/admin/unit/wearableType/DeleteWearableTypeModal.vue b/src/components/admin/unit/wearableType/DeleteWearableTypeModal.vue new file mode 100644 index 0000000..1fc1576 --- /dev/null +++ b/src/components/admin/unit/wearableType/DeleteWearableTypeModal.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/src/components/admin/unit/wearableType/WearableTypeListItem.vue b/src/components/admin/unit/wearableType/WearableTypeListItem.vue new file mode 100644 index 0000000..8f959ad --- /dev/null +++ b/src/components/admin/unit/wearableType/WearableTypeListItem.vue @@ -0,0 +1,27 @@ + + + + + diff --git a/src/demodata/wearable.ts b/src/demodata/wearable.ts new file mode 100644 index 0000000..745c829 --- /dev/null +++ b/src/demodata/wearable.ts @@ -0,0 +1,22 @@ +import type { WearableViewModel } from "../viewmodels/admin/unit/wearable/wearable.models"; +import { wearableTypeDemoData } from "./wearableType"; + +export const wearableDemoData: Array = [ + { + id: "abc", + code: "0456984224498", + name: "B-Schlauch", + wearerId: "9469991d-fa22-4899-82ce-b1ba5de990dc", + wearer: { + id: "9469991d-fa22-4899-82ce-b1ba5de990dc", + salutation: { id: 3, salutation: "Herr" }, + firstname: "Julian", + lastname: "Krauser", + nameaffix: "", + birthdate: new Date("2003-09-20"), + internalId: "1312", + }, + wearableTypeId: wearableTypeDemoData[0].id, + wearableType: wearableTypeDemoData[0], + }, +]; diff --git a/src/demodata/wearableType.ts b/src/demodata/wearableType.ts new file mode 100644 index 0000000..44cff0c --- /dev/null +++ b/src/demodata/wearableType.ts @@ -0,0 +1,9 @@ +import type { WearableTypeViewModel } from "../viewmodels/admin/unit/wearableType/wearableType.models"; + +export const wearableTypeDemoData: Array = [ + { + id: "xyz", + type: "B-Schlauch", + description: "Shläuche vom Typ B", + }, +]; diff --git a/src/router/index.ts b/src/router/index.ts index 172e5ab..61b8b92 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -17,6 +17,7 @@ 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"; const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), @@ -450,6 +451,57 @@ const router = createRouter({ }, ], }, + { + 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: "report", + name: "admin-unit-wearable-damage_report", + component: () => import("@/views/admin/ViewSelect.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", @@ -687,6 +739,28 @@ const router = createRouter({ }, ], }, + { + 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/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, + }, + ], + }, ], }, { diff --git a/src/router/unit/wearable.ts b/src/router/unit/wearable.ts new file mode 100644 index 0000000..1a0fb91 --- /dev/null +++ b/src/router/unit/wearable.ts @@ -0,0 +1,20 @@ +import { useWearableStore } from "@/stores/admin/unit/wearable/wearable"; + +export async function setWearableId(to: any, from: any, next: any) { + const WearableStore = useWearableStore(); + WearableStore.activeWearable = to.params?.wearableId ?? null; + + //useXYStore().$reset(); + + next(); +} + +export async function resetWearableStores(to: any, from: any, next: any) { + const WearableStore = useWearableStore(); + WearableStore.activeWearable = null; + WearableStore.activeWearableObj = null; + + //useXYStore().$reset(); + + next(); +} diff --git a/src/stores/admin/navigation.ts b/src/stores/admin/navigation.ts index dc7176b..fd5e108 100644 --- a/src/stores/admin/navigation.ts +++ b/src/stores/admin/navigation.ts @@ -109,6 +109,7 @@ export const useNavigationStore = defineStore("navigation", { 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" }] : []), ...(abilityStore.can("read", "unit", "respiratory_gear") ? [{ key: "respiratory_gear", title: "Atemschutz-Geräte" }] : []), @@ -125,6 +126,9 @@ export const useNavigationStore = defineStore("navigation", { ...(abilityStore.can("read", "unit", "equipment_type") ? [{ key: "equipment_type", title: "Geräte-Typen" }] : []), + ...(abilityStore.can("read", "unit", "wearable_type") + ? [{ key: "wearable_type", title: "Kleidungs-Arten" }] + : []), ], }, configuration: { diff --git a/src/stores/admin/unit/wearable/wearable.ts b/src/stores/admin/unit/wearable/wearable.ts new file mode 100644 index 0000000..e21892d --- /dev/null +++ b/src/stores/admin/unit/wearable/wearable.ts @@ -0,0 +1,108 @@ +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"; +import { wearableDemoData } from "../../../../demodata/wearable"; + +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) { + this.wearables = wearableDemoData.map((e, i) => ({ ...e, tab_pos: i })); + this.totalCount = this.wearables.length; + this.loading = "fetched"; + return; + 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.activeWearableObj = wearableDemoData.find((e) => e.id == this.activeWearable) as WearableViewModel; + this.loading = "fetched"; + return; + 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`, { + // TODO: data + }); + this.fetchWearables(); + return result; + }, + async updateActiveWearable(wearable: UpdateWearableViewModel): Promise> { + const result = await http.patch(`/admin/wearable/${wearable.id}`, { + // TODO: data + }); + 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/wearableType.ts b/src/stores/admin/unit/wearableType/wearableType.ts new file mode 100644 index 0000000..fdd9488 --- /dev/null +++ b/src/stores/admin/unit/wearableType/wearableType.ts @@ -0,0 +1,81 @@ +import { defineStore } from "pinia"; +import type { + WearableTypeViewModel, + CreateWearableTypeViewModel, + UpdateWearableTypeViewModel, +} from "@/viewmodels/admin/unit/wearableType/wearableType.models"; +import { http } from "@/serverCom"; +import type { AxiosResponse } from "axios"; +import { wearableTypeDemoData } from "../../../../demodata/wearableType"; + +export const useWearableTypeStore = defineStore("wearableType", { + state: () => { + return { + wearableTypes: [] as Array, + totalCount: 0 as number, + loading: "loading" as "loading" | "fetched" | "failed", + }; + }, + actions: { + fetchWearableTypes(offset = 0, count = 25, search = "", clear = false) { + this.wearableTypes = wearableTypeDemoData.map((e, i) => ({ ...e, tab_pos: i })); + this.totalCount = this.wearableTypes.length; + this.loading = "fetched"; + return; + 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.wearables + .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.wearables }; + }); + }, + async searchWearableTypes(search: string): Promise> { + return await http.get(`/admin/wearableType?search=${search}&noLimit=true`).then((res) => { + return { ...res, data: res.data.wearables }; + }); + }, + fetchWearableTypeById(id: string) { + return http.get(`/admin/wearableType/${id}`); + }, + async createWearableType(wearableType: CreateWearableTypeViewModel): Promise> { + const result = await http.post(`/admin/wearableType`, { + // TODO: data + }); + this.fetchWearableTypes(); + return result; + }, + async updateWearableType(wearableType: UpdateWearableTypeViewModel): Promise> { + const result = await http.patch(`/admin/wearableType/${wearableType.id}`, { + // TODO: data + }); + 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/types/permissionTypes.ts b/src/types/permissionTypes.ts index b184c78..9c6a354 100644 --- a/src/types/permissionTypes.ts +++ b/src/types/permissionTypes.ts @@ -16,6 +16,8 @@ export type PermissionModule = | "respiratory_wearer" | "respiratory_mission" | "damage_report" + | "wearable" + | "wearable_type" // configuration | "qualification" | "award" @@ -72,6 +74,8 @@ export const permissionModules: Array = [ "respiratory_wearer", "respiratory_mission", "damage_report", + "wearable", + "wearable_type", // configuration "qualification", "award", @@ -101,6 +105,8 @@ export const sectionsAndModules: SectionsAndModulesObject = { "respiratory_wearer", "respiratory_mission", "damage_report", + "wearable", + "wearable_type", ], configuration: [ "qualification", 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..88eac64 --- /dev/null +++ b/src/viewmodels/admin/unit/wearable/wearable.models.ts @@ -0,0 +1,29 @@ +import type { MemberViewModel } from "../../club/member/member.models"; +import type { WearableTypeViewModel } from "../wearableType/wearableType.models"; + +export interface WearableViewModel { + id: string; + code: string; + name: string; + location?: string; + wearerId?: string; + wearer: MemberViewModel; + wearableTypeId: string; + wearableType: WearableTypeViewModel; +} + +export interface CreateWearableViewModel { + code: string; + name: string; + wearerId?: string; + location?: string; + wearableTypeId: string; +} + +export interface UpdateWearableViewModel { + id: string; + code: string; + name: string; + location?: string; + wearerId?: string; +} diff --git a/src/viewmodels/admin/unit/wearableType/wearableType.models.ts b/src/viewmodels/admin/unit/wearableType/wearableType.models.ts new file mode 100644 index 0000000..b3f49fc --- /dev/null +++ b/src/viewmodels/admin/unit/wearableType/wearableType.models.ts @@ -0,0 +1,16 @@ +export interface WearableTypeViewModel { + id: string; + type: string; + description: string; +} + +export interface CreateWearableTypeViewModel { + type: string; + description: string; +} + +export interface UpdateWearableTypeViewModel { + id: string; + type: string; + description: string; +} diff --git a/src/views/admin/unit/wearable/CreateWearable.vue b/src/views/admin/unit/wearable/CreateWearable.vue new file mode 100644 index 0000000..e8cd414 --- /dev/null +++ b/src/views/admin/unit/wearable/CreateWearable.vue @@ -0,0 +1,214 @@ + + + + + diff --git a/src/views/admin/unit/wearable/Overview.vue b/src/views/admin/unit/wearable/Overview.vue new file mode 100644 index 0000000..0f78f94 --- /dev/null +++ b/src/views/admin/unit/wearable/Overview.vue @@ -0,0 +1,51 @@ + + + + + diff --git a/src/views/admin/unit/wearable/UpdateWearable.vue b/src/views/admin/unit/wearable/UpdateWearable.vue new file mode 100644 index 0000000..993f1a6 --- /dev/null +++ b/src/views/admin/unit/wearable/UpdateWearable.vue @@ -0,0 +1,121 @@ + + + + + diff --git a/src/views/admin/unit/wearable/Wearable.vue b/src/views/admin/unit/wearable/Wearable.vue new file mode 100644 index 0000000..54f54b9 --- /dev/null +++ b/src/views/admin/unit/wearable/Wearable.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/src/views/admin/unit/wearable/WearableRouting.vue b/src/views/admin/unit/wearable/WearableRouting.vue new file mode 100644 index 0000000..c8ef9e9 --- /dev/null +++ b/src/views/admin/unit/wearable/WearableRouting.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/src/views/admin/unit/wearableType/UpdateWearableType.vue b/src/views/admin/unit/wearableType/UpdateWearableType.vue new file mode 100644 index 0000000..1f755b0 --- /dev/null +++ b/src/views/admin/unit/wearableType/UpdateWearableType.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/src/views/admin/unit/wearableType/WearableType.vue b/src/views/admin/unit/wearableType/WearableType.vue new file mode 100644 index 0000000..e4dbfca --- /dev/null +++ b/src/views/admin/unit/wearableType/WearableType.vue @@ -0,0 +1,70 @@ + + + + +