jcloud/dashboard/src2/components/settings/RoleConfigureDialog.vue
2025-04-12 17:39:38 +08:00

309 lines
7.6 KiB
Vue

<template>
<Dialog
v-if="role"
:options="{ title: `${role.title}`, size: 'xl' }"
v-model="show"
>
<template v-slot:body-content>
<FTabs
:tabs="[
{
label: '成员',
value: 'members',
},
{
label: '设置',
value: 'settings',
},
]"
v-model="tabIndex"
>
<TabList v-slot="{ tab, selected }" class="pl-0">
<div
class="flex cursor-pointer items-center gap-1.5 border-b border-transparent py-3 text-base text-gray-600 duration-300 ease-in-out hover:border-gray-400 hover:text-gray-900 focus:outline-none focus:transition-none [&>div]:pl-0"
:class="{ 'text-gray-900': selected }"
>
<span>{{ tab.label }}</span>
</div>
</TabList>
<TabPanel v-slot="{ tab }">
<div v-if="tab.value === 'members'" class="text-base">
<div class="my-4 flex gap-2">
<div class="flex-1">
<Autocomplete
:options="autoCompleteList"
v-model="member"
placeholder="选择要添加的成员"
/>
</div>
<Button
variant="solid"
label="添加成员"
:disabled="!member?.value"
:loading="$resources.role.addUser?.loading"
@click="() => addUser(member.value)"
/>
</div>
<div class="rounded border px-3">
<div class="mt-2 text-gray-600">成员</div>
<div
v-if="roleUsers.length === 0"
class="p-6 text-center text-gray-500"
>
<span>此角色尚未添加任何成员</span>
</div>
<div v-else class="flex flex-col divide-y">
<div
v-for="user in roleUsers"
class="flex justify-between py-3"
>
<UserWithAvatarCell
:avatarImage="user.user_image"
:fullName="user.full_name"
:email="user.user"
:key="user.user"
/>
<Button variant="ghost" @click="() => removeUser(user.user)">
<template #icon>
<i-lucide-x class="h-4 w-4 text-gray-600" />
</template>
</Button>
</div>
</div>
</div>
</div>
<div v-else-if="tab.value === 'settings'" class="mt-4 text-base">
<div class="space-y-3">
<div class="rounded border p-4">
<Switch
class="ml-2"
v-model="adminAccess"
label="管理员权限"
description="授予成员类似团队所有者的权限。包括访问所有页面和设置。"
/>
</div>
<div class="space-y-1 rounded border p-4">
<h2 class="mb-2 ml-2 font-semibold">页面访问权限</h2>
<Switch
v-model="allowBilling"
label="允许访问计费"
:disabled="adminAccess"
/>
<Switch
v-model="allowApps"
label="允许访问应用"
:disabled="adminAccess"
/>
<Switch
v-if="$team.pg.jerp_partner"
v-model="allowPartner"
label="允许访问合作伙伴"
:disabled="adminAccess"
/>
<Switch
v-model="allowSiteCreation"
label="允许创建站点"
:disabled="adminAccess"
/>
<Switch
v-model="allowBenchCreation"
label="允许创建站点分组"
:disabled="adminAccess"
/>
<Switch
v-model="allowServerCreation"
label="允许创建服务器"
:disabled="adminAccess"
/>
<Switch
v-model="allowWebhookConfiguration"
label="允许配置Webhook"
:disabled="adminAccess"
/>
</div>
</div>
</div>
</TabPanel>
</FTabs>
</template>
</Dialog>
</template>
<script>
import { Switch, Tabs, TabList, TabPanel } from 'jingrow-ui';
import { toast } from 'vue-sonner';
import UserWithAvatarCell from '../UserWithAvatarCell.vue';
import { getToastErrorMessage } from '../../utils/toast';
export default {
props: {
roleId: { type: String, required: true },
},
components: {
UserWithAvatarCell,
FTabs: Tabs,
TabPanel,
TabList,
Switch,
},
data() {
return {
member: {},
show: true,
tabIndex: 0,
};
},
resources: {
role() {
return {
type: 'document',
pagetype: 'Jcloud Role',
name: this.roleId,
whitelistedMethods: {
addUser: 'add_user',
removeUser: 'remove_user',
bulkDelete: 'delete_permissions',
},
};
},
},
computed: {
role() {
return this.$resources.role.pg;
},
roleUsers() {
return this.role?.users || [];
},
autoCompleteList() {
const isNotGroupMember = (u) =>
!this.roleUsers.map(({ user }) => user).includes(u);
return this.$team.pg.team_members
?.filter(({ user }) => isNotGroupMember(user))
.map(({ user }) => ({ label: user, value: user }));
},
adminAccess: {
get() {
return !!this.role?.admin_access;
},
set(value) {
this.$resources.role.setValue.submit(
{
admin_access: value,
},
{ onSuccess: this.$session.roles.reload },
);
},
},
allowBilling: {
get() {
return !!this.role?.allow_billing;
},
set(value) {
this.$resources.role.setValue.submit(
{
allow_billing: value,
},
{ onSuccess: this.$session.roles.reload },
);
},
},
allowApps: {
get() {
return !!this.role?.allow_apps;
},
set(value) {
this.$resources.role.setValue.submit(
{
allow_apps: value,
},
{ onSuccess: this.$session.roles.reload },
);
},
},
allowPartner: {
get() {
return !!this.role?.allow_partner;
},
set(value) {
this.$resources.role.setValue.submit(
{
allow_partner: value,
},
{ onSuccess: this.$session.roles.reload },
);
},
},
allowSiteCreation: {
get() {
return !!this.role?.allow_site_creation;
},
set(value) {
this.$resources.role.setValue.submit(
{
allow_site_creation: value,
},
{ onSuccess: this.$session.roles.reload },
);
},
},
allowBenchCreation: {
get() {
return !!this.role?.allow_bench_creation;
},
set(value) {
this.$resources.role.setValue.submit(
{
allow_bench_creation: value,
},
{ onSuccess: this.$session.roles.reload },
);
},
},
allowServerCreation: {
get() {
return !!this.role?.allow_server_creation;
},
set(value) {
this.$resources.role.setValue.submit(
{
allow_server_creation: value,
},
{ onSuccess: this.$session.roles.reload },
);
},
},
allowWebhookConfiguration: {
get() {
return !!this.role?.allow_webhook_configuration;
},
set(value) {
this.$resources.role.setValue.submit(
{
allow_webhook_configuration: value,
},
{ onSuccess: this.$session.roles.reload },
);
},
},
},
methods: {
addUser(user) {
return toast.promise(this.$resources.role.addUser.submit({ user }), {
loading: `正在将 ${user} 添加到 ${this.role.title}`,
success: () => {
this.member = {};
return `${user} 已添加到 ${this.role.title}`;
},
error: (e) => getToastErrorMessage(e),
});
},
removeUser(user) {
return toast.promise(this.$resources.role.removeUser.submit({ user }), {
loading: `正在将 ${user}${this.role.title} 中移除`,
success: () => `${user} 已从 ${this.role.title} 中移除`,
error: (e) => getToastErrorMessage(e),
});
},
},
};
</script>