import { ref, reactive, computed } from 'vue' import { Notify } from 'quasar' import { usePermissions } from './usePermissions' export function usePermissionMatrix () { const { HUB_URL } = usePermissions() const permTab = ref('users') const permLoading = ref(false) const permSaving = ref(false) const permDirty = ref(false) const permGroups = ref([]) const permCapabilities = ref([]) const permMatrix = reactive({}) const allGroupNames = computed(() => permGroups.value.map(g => g.name)) const permCategories = computed(() => [...new Set(permCapabilities.value.map(c => c.category))]) const permCapsByCategory = computed(() => { const map = {} for (const c of permCapabilities.value) { if (!map[c.category]) map[c.category] = [] map[c.category].push(c) } return map }) async function loadPerms () { permLoading.value = true try { const res = await fetch(HUB_URL + '/auth/groups') const data = await res.json() permGroups.value = data.groups permCapabilities.value = data.capabilities for (const g of data.groups) { permMatrix[g.name] = {} for (const cap of data.capabilities) { permMatrix[g.name][cap.key] = g.permissions[cap.key] === true } } } catch (e) { Notify.create({ type: 'negative', message: 'Erreur chargement permissions: ' + e.message }) } finally { permLoading.value = false } } async function saveAllPerms () { permSaving.value = true try { for (const g of permGroups.value) { await fetch(HUB_URL + '/auth/groups/' + encodeURIComponent(g.name) + '/permissions', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(permMatrix[g.name]), }) } permDirty.value = false Notify.create({ type: 'positive', message: 'Permissions sauvegardees', timeout: 2000 }) } catch (e) { Notify.create({ type: 'negative', message: 'Erreur: ' + e.message }) } finally { permSaving.value = false } } async function saveGroupPerms (groupName) { permSaving.value = true try { await fetch(HUB_URL + '/auth/groups/' + encodeURIComponent(groupName) + '/permissions', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(permMatrix[groupName]), }) permDirty.value = false Notify.create({ type: 'positive', message: `Permissions "${groupName}" sauvegardees`, timeout: 2000 }) } catch (e) { Notify.create({ type: 'negative', message: 'Erreur: ' + e.message }) } finally { permSaving.value = false } } function countGroupPerms (g) { return Object.values(permMatrix[g.name] || {}).filter(Boolean).length } function effectivePerm (user, capKey) { if (typeof user.overrides[capKey] === 'boolean') return user.overrides[capKey] for (const gName of user.groups) { if (permMatrix[gName]?.[capKey]) return true } return false } async function setUserOverride (user, capKey, value) { if (value === true || value === false) { user.overrides[capKey] = value } else { delete user.overrides[capKey] } const clean = {} for (const [k, v] of Object.entries(user.overrides)) { if (typeof v === 'boolean') clean[k] = v } try { await fetch(HUB_URL + '/auth/users/' + encodeURIComponent(user.email) + '/overrides', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(clean), }) } catch (e) { Notify.create({ type: 'negative', message: 'Erreur override: ' + e.message }) } } return { permTab, permLoading, permSaving, permDirty, permGroups, permCapabilities, permMatrix, allGroupNames, permCategories, permCapsByCategory, loadPerms, saveAllPerms, saveGroupPerms, countGroupPerms, effectivePerm, setUserOverride, } }