You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

171 lines
6.8 KiB

import { useMemo, useState } from 'react'
import { BetaSchemaForm, ProColumns, ProFormColumnsType, ProTable } from '@ant-design/pro-components'
import { IAcmeAccount } from '@/types/website/acme'
import { useTranslation } from '@/i18n.ts'
import { AcmeAccountTypes, acmeListAtom, acmePageAtom, AcmeType, saveOrUpdateAcmeAtom } from '@/store/websites/acme.ts'
import { useAtom, useAtomValue } from 'jotai'
import { Alert, Button, Form, Popconfirm } from 'antd'
import { KeyTypeEnum, KeyTypes } from '@/store/websites/ssl.ts'
import { deleteDNSAtom } from '@/store/websites/dns.ts'
const AcmeList = () => {
const { t } = useTranslation()
const [ form ] = Form.useForm()
const [ page, setPage ] = useAtom(acmePageAtom)
const { data, isLoading, refetch } = useAtomValue(acmeListAtom)
const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateAcmeAtom)
const { mutate: deleteDNS, isPending: isDeleting } = useAtomValue(deleteDNSAtom)
const [ open, setOpen ] = useState(false)
const columns = useMemo<ProColumns<IAcmeAccount>[]>(() => {
return [
{
title: 'ID',
dataIndex: 'id',
hideInTable: true,
formItemProps: {
hidden: true,
}
},
{
title: t('website.ssl.acme.columns.email', '邮箱'),
dataIndex: 'email',
valueType: 'text',
formItemProps: {
rules: [
{ required: true, message: t('message.required', '请输入') }
]
}
},
{
title: t('website.ssl.acme.columns.type', '帐号类型'),
dataIndex: 'type',
valueType: 'select',
fieldProps: {
options: AcmeAccountTypes
},
formItemProps: {
rules: [
{ required: true, message: t('message.required', '请选择') }
]
}
},
{
title: t('website.ssl.acme.columns.keyType', '密钥算法'),
dataIndex: 'keyType',
valueType: 'select',
fieldProps: {
options: KeyTypes
},
formItemProps: {
rules: [
{ required: true, message: t('message.required', '请选择') }
]
},
},
{
title: t('website.ssl.acme.columns.url', 'URL'),
dataIndex: 'url',
valueType: 'text',
ellipsis: true, // 文本溢出省略
hideInForm: true,
}, {
title: '操作',
valueType: 'option',
render: (_, record) => {
return [
<Popconfirm
key={'del_confirm'}
disabled={isDeleting}
onConfirm={() => {
deleteDNS(record.id)
}}
title={t('message.deleteConfirm')}>
<a key="del">
{t('actions.delete', '删除')}
</a>
</Popconfirm>
]
}
}
]
}, [])
return (
<>
<Alert message={t('website.ssl.acme.tip', 'Acme账户用于申请免费证书')}/>
<ProTable<IAcmeAccount>
cardProps={{
bodyStyle: {
padding: 0,
}
}}
rowKey="id"
headerTitle={
<Button
onClick={() => {
form.setFieldsValue({
id: 0,
type: AcmeType.LetsEncrypt,
keyType: KeyTypeEnum.EC256,
})
setOpen(true)
}}
type={'primary'}>{t('website.ssl.acme.add', '添加Acme帐户')}</Button>
}
loading={isLoading}
dataSource={data?.rows ?? []}
columns={columns}
search={false}
options={{
reload: () => {
refetch()
},
}}
pagination={{
total: data?.total,
pageSize: page.pageSize,
current: page.page,
onChange: (current, pageSize) => {
setPage(prev => {
return {
...prev,
page: current,
pageSize: pageSize,
}
})
},
}}
/>
<BetaSchemaForm<IAcmeAccount>
shouldUpdate={false}
width={600}
form={form}
layout={'horizontal'}
scrollToFirstError={true}
title={t(`website.ssl.acme.title_${form.getFieldValue('id') !== 0 ? 'edit' : 'add'}`, form.getFieldValue('id') !== 0 ? '证书编辑' : '证书添加')}
// colProps={{ span: 24 }}
labelCol={{ span: 6 }}
wrapperCol={{ span: 14 }}
layoutType={'ModalForm'}
open={open}
modalProps={{
maskClosable: false,
}}
onOpenChange={(open) => {
setOpen(open)
}}
loading={isSubmitting}
onFinish={async (values) => {
// console.log('values', values)
saveOrUpdate(values)
return isSuccess
}}
columns={columns as ProFormColumnsType[]}/>
</>
)
}
export default AcmeList