263 lines
6.3 KiB
Vue
263 lines
6.3 KiB
Vue
<template>
|
||
<Dialog
|
||
:options="{
|
||
title: '管理数据库用户',
|
||
size: planSupportsDatabaseAccess ? '3xl' : 'xl',
|
||
}"
|
||
v-model="show"
|
||
>
|
||
<template #body-content>
|
||
<!-- 当前计划不可用,推荐升级计划 -->
|
||
<div v-if="!planSupportsDatabaseAccess">
|
||
<div>
|
||
<p class="text-base">
|
||
数据库访问在当前计划中不可用。<br />请升级到更高计划以使用此功能。
|
||
</p>
|
||
|
||
<Button
|
||
class="mt-4 w-full"
|
||
variant="solid"
|
||
@click="showChangePlanDialog = true"
|
||
>
|
||
升级站点计划
|
||
</Button>
|
||
<ManageSitePlansDialog
|
||
:site="site"
|
||
v-model="showChangePlanDialog"
|
||
v-if="showChangePlanDialog"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 当前计划可用 -->
|
||
<div v-else>
|
||
<ObjectList :options="listOptions" />
|
||
</div>
|
||
</template>
|
||
</Dialog>
|
||
|
||
<SiteDatabaseUserCredentialDialog
|
||
:name="selectedUser"
|
||
v-model="showDatabaseUserCredentialDialog"
|
||
v-if="showDatabaseUserCredentialDialog"
|
||
/>
|
||
|
||
<SiteDatabaseAddEditUserDialog
|
||
:site="site"
|
||
:key="selectedUser ? selectedUser : 'new'"
|
||
:db_user_name="selectedUser"
|
||
v-model="showDatabaseAddEditUserDialog"
|
||
v-if="showDatabaseAddEditUserDialog"
|
||
@success="this.hideSiteDatabaseAddEditUserDialog"
|
||
/>
|
||
</template>
|
||
<script>
|
||
import { defineAsyncComponent } from 'vue';
|
||
import { getCachedDocumentResource } from 'jingrow-ui';
|
||
import ClickToCopyField from './ClickToCopyField.vue';
|
||
import ObjectList from './ObjectList.vue';
|
||
import { date } from '../utils/format';
|
||
import { confirmDialog, icon } from '../utils/components';
|
||
import SiteDatabaseUserCredentialDialog from './site_database_user/SiteDatabaseUserCredentialDialog.vue';
|
||
import SiteDatabaseAddEditUserDialog from './site_database_user/SiteDatabaseAddEditUserDialog.vue';
|
||
import { toast } from 'vue-sonner';
|
||
|
||
export default {
|
||
name: 'SiteDatabaseAccessDialog',
|
||
props: ['site'],
|
||
components: {
|
||
ManageSitePlansDialog: defineAsyncComponent(
|
||
() => import('./ManageSitePlansDialog.vue'),
|
||
),
|
||
ClickToCopyField,
|
||
ObjectList,
|
||
SiteDatabaseUserCredentialDialog,
|
||
SiteDatabaseAddEditUserDialog,
|
||
},
|
||
data() {
|
||
return {
|
||
mode: 'read_only',
|
||
show: true,
|
||
showChangePlanDialog: false,
|
||
selectedUser: '',
|
||
showDatabaseUserCredentialDialog: false,
|
||
showDatabaseAddEditUserDialog: false,
|
||
};
|
||
},
|
||
watch: {
|
||
showDatabaseUserCredentialDialog(val) {
|
||
if (!val) {
|
||
this.show = true;
|
||
}
|
||
},
|
||
showDatabaseAddEditUserDialog(val) {
|
||
if (!val) {
|
||
this.show = true;
|
||
}
|
||
},
|
||
},
|
||
resources: {
|
||
deleteSiteDatabaseUser() {
|
||
return {
|
||
url: 'jcloud.api.client.run_pg_method',
|
||
onSuccess() {
|
||
toast.success('数据库用户即将被删除');
|
||
},
|
||
onError(err) {
|
||
toast.error(
|
||
err.messages.length
|
||
? err.messages.join('\n')
|
||
: '无法启动数据库用户删除',
|
||
);
|
||
},
|
||
};
|
||
},
|
||
},
|
||
computed: {
|
||
listOptions() {
|
||
return {
|
||
pagetype: 'Site Database User',
|
||
filters: {
|
||
site: this.site,
|
||
status: ['!=', 'Archived'],
|
||
},
|
||
searchField: 'label',
|
||
filterControls() {
|
||
return [
|
||
{
|
||
type: 'select',
|
||
label: '状态',
|
||
fieldname: 'status',
|
||
options: ['', 'Pending', 'Active', 'Failed'],
|
||
},
|
||
];
|
||
},
|
||
columns: [
|
||
{
|
||
label: '标签',
|
||
fieldname: 'label',
|
||
width: '150px',
|
||
},
|
||
{
|
||
label: '状态',
|
||
fieldname: 'status',
|
||
width: 0.5,
|
||
align: 'center',
|
||
type: 'Badge',
|
||
},
|
||
{
|
||
label: '数据库连接',
|
||
fieldname: 'max_connections',
|
||
width: 0.5,
|
||
align: 'center',
|
||
format: (value) => `${value} 连接` + (value > 1 ? 's' : ''),
|
||
},
|
||
{
|
||
label: '模式',
|
||
fieldname: 'mode',
|
||
width: 0.5,
|
||
align: 'center',
|
||
format: (value, row) => {
|
||
return {
|
||
read_only: '只读',
|
||
read_write: '读写',
|
||
granular: '细粒度',
|
||
}[value];
|
||
},
|
||
},
|
||
{
|
||
label: '创建时间',
|
||
fieldname: 'creation',
|
||
width: 0.5,
|
||
align: 'center',
|
||
format: (value) => date(value, 'll'),
|
||
},
|
||
],
|
||
rowActions: ({ row, listResource, documentResource }) => {
|
||
if (row.status === 'Archived' || row.status === 'Pending') {
|
||
return [];
|
||
}
|
||
return [
|
||
{
|
||
label: '查看凭证',
|
||
onClick: () => {
|
||
this.show = false;
|
||
this.selectedUser = row.name;
|
||
this.showDatabaseUserCredentialDialog = true;
|
||
},
|
||
},
|
||
{
|
||
label: '配置用户',
|
||
onClick: () => {
|
||
this.selectedUser = row.name;
|
||
this.show = false;
|
||
this.showDatabaseAddEditUserDialog = true;
|
||
},
|
||
},
|
||
{
|
||
label: '删除用户',
|
||
onClick: () => {
|
||
this.show = false;
|
||
confirmDialog({
|
||
title: '删除数据库用户',
|
||
message: `确定要删除该数据库用户吗?<br>`,
|
||
primaryAction: {
|
||
label: '删除',
|
||
variant: 'solid',
|
||
theme: 'red',
|
||
onClick: ({ hide }) => {
|
||
this.$resources.deleteSiteDatabaseUser.submit({
|
||
dt: 'Site Database User',
|
||
dn: row.name,
|
||
method: 'archive',
|
||
});
|
||
this.$resources.deleteSiteDatabaseUser.promise.then(
|
||
() => {
|
||
hide();
|
||
this.show = true;
|
||
},
|
||
);
|
||
return this.$resources.deleteSiteDatabaseUser.promise;
|
||
},
|
||
},
|
||
onSuccess: () => {
|
||
listResource.refresh();
|
||
},
|
||
});
|
||
},
|
||
},
|
||
];
|
||
},
|
||
primaryAction: () => {
|
||
return {
|
||
label: '添加用户',
|
||
variant: 'solid',
|
||
slots: {
|
||
prefix: icon('plus'),
|
||
},
|
||
onClick: () => {
|
||
this.show = false;
|
||
this.selectedUser = null;
|
||
this.showDatabaseAddEditUserDialog = true;
|
||
},
|
||
};
|
||
},
|
||
};
|
||
},
|
||
sitePlan() {
|
||
return this.$site.pg.current_plan;
|
||
},
|
||
planSupportsDatabaseAccess() {
|
||
return this.sitePlan?.database_access;
|
||
},
|
||
$site() {
|
||
return getCachedDocumentResource('Site', this.site);
|
||
},
|
||
},
|
||
methods: {
|
||
hideSiteDatabaseAddEditUserDialog() {
|
||
this.showDatabaseAddEditUserDialog = false;
|
||
},
|
||
},
|
||
};
|
||
</script> |