67 lines
2.1 KiB
Vue

<script setup lang="ts">
import allLocalesRaw from '~/locale/locales.ts';
import { PERMISSION_AREAS } from '~/src/helpers.js';
import type { User } from '~/src/user.ts';
const allLocales = ['*'];
for (const { code } of allLocalesRaw) {
allLocales.push(code);
}
const props = defineProps<{
user: Pick<User, 'id' | 'username' | 'roles'>;
}>();
const { $translator: translator } = useNuxtApp();
const config = useConfig();
const roleItems = ref((props.user.roles ? props.user.roles.split('|') : []).map((r) => {
if (r === '*') {
r = '*-*';
}
const [locale, area] = r.split('-');
return { locale, area };
}));
const dialogue = useDialogue();
const save = async () => {
const roles = roleItems.value.map((r) => {
if (r.locale === '*' && r.area === '*') {
return '*';
}
return `${r.locale}-${r.area}`;
}).join('|');
await dialogue.confirm(translator.translate('admin.user.confirmRole', { username: props.user.username, role: roles }));
await dialogue.postWithAlertOnError(`/api/user/${props.user.id}/set-roles`, { roles });
props.user.roles = roles;
};
</script>
<template>
<form v-if="$isGranted('*')" @submit.prevent="save">
<ListInput v-slot="s" v-model="roleItems" :prototype="{ locale: config.locale, area: '*' }">
<select v-model="s.val.locale" class="form-control">
<option v-for="locale in allLocales" :key="locale" :value="locale">
{{ locale }}
</option>
</select>
<select v-model="s.val.area" class="form-control">
<option v-for="area in PERMISSION_AREAS" :key="area" :value="area">
{{ area }}
</option>
</select>
</ListInput>
<button type="submit" class="btn btn-outline-primary">
Save
</button>
</form>
<ul v-else class="list-unstyled">
<li v-for="role in user.roles.split('|')" :key="role">
<span class="badge bg-primary text-white">{{ role }}</span>
</li>
</ul>
</template>