318 lines
7.7 KiB
Vue
318 lines
7.7 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';
|
|
|
|
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) {
|
|
if (!user) return;
|
|
if (this.$resources.role.addUser.loading) return;
|
|
|
|
toast.success(`已添加 ${user} 到 ${this.role.title}`, { duration: 2000 });
|
|
this.member = {};
|
|
this.$resources.role.addUser.submit({ user });
|
|
// 刷新角色数据
|
|
setTimeout(() => {
|
|
if (this.$resources.role) {
|
|
this.$resources.role.reload();
|
|
}
|
|
}, 500);
|
|
},
|
|
removeUser(user) {
|
|
if (!user) return;
|
|
if (this.$resources.role.removeUser.loading) return;
|
|
|
|
toast.success(`已从 ${this.role.title} 中移除 ${user}`, { duration: 2000 });
|
|
this.$resources.role.removeUser.submit({ user });
|
|
// 刷新角色数据
|
|
setTimeout(() => {
|
|
if (this.$resources.role) {
|
|
this.$resources.role.reload();
|
|
}
|
|
}, 500);
|
|
},
|
|
},
|
|
};
|
|
</script> |