diff --git a/frontend/src/services/organization.service.ts b/frontend/src/services/organization.service.ts index 3f3721f..e0c18fb 100644 --- a/frontend/src/services/organization.service.ts +++ b/frontend/src/services/organization.service.ts @@ -17,6 +17,12 @@ const ROLE_PERMISSIONS: Record = { STAFF: { temperatureLogging: true, checklists: true, reports: false, deviations: true, userAdmin: false, settings: false }, } +interface BackendLocation { + id: number + name: string + address: string +} + interface BackendUser { id: number firstName: string @@ -76,7 +82,12 @@ export const organizationService = { })) }, - async updateUser(id: number, data: Partial): Promise { + async getLocations(): Promise { + const res = await api.get('/locations') + return res.data + }, + + async updateUser(id: number, data: Partial & { locationId?: number }): Promise { // Name update if (data.firstName !== undefined || data.lastName !== undefined) { await api.put(`/users/${id}`, { @@ -84,9 +95,9 @@ export const organizationService = { lastName: data.lastName, }) } - // Role update (separate endpoint) + // Role update (separate endpoint) — locationId required for MANAGER/STAFF if (data.role !== undefined) { - await api.put(`/users/${id}/role`, { role: data.role }) + await api.put(`/users/${id}/role`, { role: data.role, locationId: data.locationId ?? null }) } // Re-fetch the updated user from the list const users = await this.getUsers() @@ -95,12 +106,13 @@ export const organizationService = { return updated }, - async createUser(data: Omit): Promise { + async createUser(data: Omit & { locationId?: number | null }): Promise { const res = await api.post('/users', { firstName: data.firstName, lastName: data.lastName, email: data.email, role: data.role, + locationId: data.locationId ?? null, }) return { id: res.data.id, diff --git a/frontend/src/views/settings/UsersTab.vue b/frontend/src/views/settings/UsersTab.vue index ee4c903..0f2c7d0 100644 --- a/frontend/src/views/settings/UsersTab.vue +++ b/frontend/src/views/settings/UsersTab.vue @@ -86,6 +86,17 @@ +
+ + +
+

Tillatelser

@@ -139,6 +150,7 @@ import { organizationService } from '@/services/organization.service' import type { SettingsUser, UserRole } from '@/types' const users = ref([]) +const locations = ref<{ id: number; name: string }[]>([]) const loading = ref(false) const showModal = ref(false) const isEditing = ref(false) @@ -146,13 +158,14 @@ const editingId = ref(null) const originalRole = ref(null) const saveError = ref(null) -type FormData = Omit +type FormData = Omit & { locationId: number | null } const emptyForm = (): FormData => ({ firstName: '', lastName: '', email: '', role: 'STAFF', + locationId: null, isActive: true, permissions: { temperatureLogging: false, @@ -169,7 +182,10 @@ const form = reactive(emptyForm()) async function fetchUsers() { loading.value = true try { - users.value = await organizationService.getUsers() + ;[users.value, locations.value] = await Promise.all([ + organizationService.getUsers(), + organizationService.getLocations(), + ]) } finally { loading.value = false } @@ -207,6 +223,7 @@ function openAddModal() { isEditing.value = false editingId.value = null saveError.value = null + originalRole.value = null Object.assign(form, emptyForm()) showModal.value = true } @@ -223,20 +240,28 @@ function openEditModal(user: SettingsUser) { role: user.role, isActive: user.isActive, permissions: { ...user.permissions }, + locationId: null, }) showModal.value = true } async function save() { saveError.value = null + const needsLocation = form.role === 'MANAGER' || form.role === 'STAFF' + const roleChanged = form.role !== originalRole.value + if (needsLocation && (roleChanged || !isEditing.value) && !form.locationId) { + saveError.value = 'Velg en lokasjon for denne rollen.' + return + } + const colors = getAvatarColors(form.role) - const userData: Partial & { colorBg: string; colorText: string } = { + const userData: Partial & { colorBg: string; colorText: string; locationId?: number | null } = { ...form, colorBg: colors.bg, colorText: colors.text, } // Only send role if it actually changed — role endpoint returns 403 otherwise - if (isEditing.value && form.role === originalRole.value) { + if (isEditing.value && !roleChanged) { delete userData.role }