flaschengeist-users/src/components/settings/RoleSettings.vue

161 lines
4.3 KiB
Vue

<template>
<div>
<q-card class="col-12">
<q-form @submit="save" @reset="reset">
<q-card-section class="fit row justify-start content-center items-center">
<span class="col-xs-12 col-sm-6 text-center text-h6"> Rollen und Berechtigungen </span>
<q-select
filled
use-input
label="Rolle"
input-debounce="0"
class="col-xs-12 col-sm-6 q-pa-sm"
:model-value="role"
:options="roles"
option-label="name"
option-value="name"
map-options
clearable
@new-value="createRole"
@update:model-value="updateRole"
@clear="removeRole"
/>
</q-card-section>
<q-separator />
<q-card-section v-if="role">
<q-input v-if="role.id !== -1" v-model="newRoleName" filled label="neuer Name" />
<q-scroll-area style="height: 40vh; width: 100%" class="background-like-input">
<q-option-group
:model-value="role.permissions"
:options="permissions"
color="primary"
type="checkbox"
@update:model-value="updatePermissions"
/>
</q-scroll-area>
</q-card-section>
<q-card-actions v-if="role" align="right">
<q-btn label="Löschen" color="negative" @click="remove" />
<q-btn label="Reset" type="reset" />
<q-btn color="primary" type="submit" label="Speichern" />
</q-card-actions>
</q-form>
</q-card>
</div>
</template>
<script lang="ts">
import { computed, defineComponent, ref, onBeforeMount } from 'vue';
import { useUserStore } from '@flaschengeist/api';
export default defineComponent({
name: 'RoleSettings',
setup() {
const userStore = useUserStore();
onBeforeMount(() => {
void userStore.getRoles();
void userStore.getPermissions();
});
const role = ref<FG.Role | null>(null);
const roles = computed(() => userStore.roles);
const permissions = computed(() =>
userStore.permissions.map((perm) => {
return {
value: perm,
label: perm,
};
})
);
const newRoleName = ref<string>('');
function createRole(name: string, done: (arg0: string, arg1: string) => void): void {
role.value = { name: name, permissions: [], id: -1 };
done(name, 'add-unique');
}
function removeRole(): void {
role.value = null;
}
function updatePermissions(permissions: string[]) {
if (role.value) {
role.value.permissions = permissions;
}
}
function updateRole(rl: FG.Role | string | null) {
if (typeof rl === 'string' || rl === null) return;
role.value = {
id: rl.id,
name: rl.name,
permissions: Array.from(rl.permissions),
};
}
function save() {
if (role.value) {
if (role.value.id === -1)
void userStore.newRole(role.value).then((createdRole: FG.Role) => {
role.value = createdRole;
});
else {
if (newRoleName.value !== '') role.value.name = newRoleName.value;
void userStore.updateRole(role.value);
}
}
}
function reset() {
if (role.value && role.value.id !== -1) {
const original = roles.value.find((value) => value.name === role.value?.name);
if (original) updateRole(original);
} else {
role.value = null;
}
}
function remove() {
if (role.value) {
if (role.value.id === -1) {
role.value = null;
} else {
void userStore.deleteRole(role.value).then(() => (role.value = null));
}
}
}
return {
roles,
role,
permissions,
createRole,
updateRole,
updatePermissions,
save,
reset,
removeRole,
remove,
newRoleName,
};
},
});
</script>
<style lang="sass" scoped>
// Same colors like qinput with filled attribute set
.body--light .background-like-input
background-color: rgba(0, 0, 0, 0.05)
&:hover
background: rgba(0,0,0,.1)
border-bottom: 1px solid rgba(0, 0, 0, 0.42)
.body--dark .background-like-input
background-color: rgba(255, 255, 255, 0.07)
&:hover
background: rgba(255, 255, 255, 0.14)
border-bottom: 1px solid #fff
</style>