feat(web): create api support rate_limit & daily_request_limit config
This commit is contained in:
@@ -195,53 +195,55 @@ const Api: FC<{ application: Application | null }> = ({ application }) => {
|
||||
</Col>
|
||||
</Row>
|
||||
{/* API Key List */}
|
||||
{apiKeyList.sort((a, b) => b.created_at - a.created_at).map(item => (
|
||||
<div key={item.id} className="rb:p-4 rb-border rb:rounded-xl">
|
||||
<Flex align="center" justify="space-between">
|
||||
<Flex vertical className="rb:max-w-[calc(100%-92px)]" gap={4}>
|
||||
<div className="rb:text-ellipsis rb:overflow-hidden rb:whitespace-nowrap rb:flex-1 rb:leading-5 rb:font-medium">{item.name}</div>
|
||||
<div className="rb:text-[#5B6167] rb:leading-4.5">ID: {item.id}</div>
|
||||
</Flex>
|
||||
<Space size={12}>
|
||||
<div
|
||||
className="rb:w-6 rb:h-6 rb:cursor-pointer rb:bg-[url('@/assets/images/editBorder.svg')] rb:hover:bg-[url('@/assets/images/editBg.svg')]"
|
||||
onClick={() => handleEdit(item)}
|
||||
></div>
|
||||
<div
|
||||
className="rb:w-6 rb:h-6 rb:cursor-pointer rb:bg-[url('@/assets/images/deleteBorder.svg')] rb:hover:bg-[url('@/assets/images/deleteBg.svg')]"
|
||||
onClick={() => handleDelete(item)}
|
||||
></div>
|
||||
</Space>
|
||||
</Flex>
|
||||
|
||||
<Row className="rb:mt-4">
|
||||
<Col span={8}>
|
||||
<Row className="rb:px-4 rb:py-2">
|
||||
<Col span={12}>
|
||||
<div className="rb:font-[MiSans-Bold] rb:font-bold rb:text-[16px] rb:leading-5.5">{item.total_requests}</div>
|
||||
<div className="rb:mt-1 rb:text-[#5B6167] rb:text-[12px] rb:leading-4.5">{t('application.apiKeyRequestTotal')}</div>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<div className="rb:font-[MiSans-Bold] rb:font-bold rb:text-[16px] rb:leading-5.5">{item.rate_limit}</div>
|
||||
<div className="rb:mt-1 rb:text-[#5B6167] rb:text-[12px] rb:leading-4.5">{t('application.qpsLimit')}</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col span={16}>
|
||||
<Flex align="center" justify="space-between" className="rb:text-[#5B6167] rb:py-5! rb:px-4! rb:bg-white rb-border rb:rounded-lg rb:leading-5">
|
||||
{maskApiKeys(item.api_key)}
|
||||
|
||||
<Button className="rb:px-2! rb:h-7! rb:group rb:-mt-1.75!" onClick={() => handleCopy(item.api_key)}>
|
||||
<div
|
||||
className="rb:w-4 rb:h-4 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/copy.svg')] rb:group-hover:bg-[url('@/assets/images/copy_active.svg')]"
|
||||
></div>
|
||||
{t('common.copy')}
|
||||
</Button>
|
||||
<Flex vertical gap={12}>
|
||||
{apiKeyList.sort((a, b) => b.created_at - a.created_at).map(item => (
|
||||
<div key={item.id} className="rb:p-4 rb-border rb:rounded-xl">
|
||||
<Flex align="center" justify="space-between">
|
||||
<Flex vertical className="rb:max-w-[calc(100%-92px)]" gap={4}>
|
||||
<div className="rb:text-ellipsis rb:overflow-hidden rb:whitespace-nowrap rb:flex-1 rb:leading-5 rb:font-medium">{item.name}</div>
|
||||
<div className="rb:text-[#5B6167] rb:leading-4.5">ID: {item.id}</div>
|
||||
</Flex>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
))}
|
||||
<Space size={12}>
|
||||
<div
|
||||
className="rb:w-6 rb:h-6 rb:cursor-pointer rb:bg-[url('@/assets/images/editBorder.svg')] rb:hover:bg-[url('@/assets/images/editBg.svg')]"
|
||||
onClick={() => handleEdit(item)}
|
||||
></div>
|
||||
<div
|
||||
className="rb:w-6 rb:h-6 rb:cursor-pointer rb:bg-[url('@/assets/images/deleteBorder.svg')] rb:hover:bg-[url('@/assets/images/deleteBg.svg')]"
|
||||
onClick={() => handleDelete(item)}
|
||||
></div>
|
||||
</Space>
|
||||
</Flex>
|
||||
|
||||
<Row className="rb:mt-4">
|
||||
<Col span={8}>
|
||||
<Row className="rb:px-4 rb:py-2">
|
||||
<Col span={12}>
|
||||
<div className="rb:font-[MiSans-Bold] rb:font-bold rb:text-[16px] rb:leading-5.5">{item.total_requests}</div>
|
||||
<div className="rb:mt-1 rb:text-[#5B6167] rb:text-[12px] rb:leading-4.5">{t('application.apiKeyRequestTotal')}</div>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<div className="rb:font-[MiSans-Bold] rb:font-bold rb:text-[16px] rb:leading-5.5">{item.rate_limit}</div>
|
||||
<div className="rb:mt-1 rb:text-[#5B6167] rb:text-[12px] rb:leading-4.5">{t('application.qpsLimit')}</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col span={16}>
|
||||
<Flex align="center" justify="space-between" className="rb:text-[#5B6167] rb:py-5! rb:px-4! rb:bg-white rb-border rb:rounded-lg rb:leading-5">
|
||||
{maskApiKeys(item.api_key)}
|
||||
|
||||
<Button className="rb:px-2! rb:h-7! rb:group rb:-mt-1.75!" onClick={() => handleCopy(item.api_key)}>
|
||||
<div
|
||||
className="rb:w-4 rb:h-4 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/copy.svg')] rb:group-hover:bg-[url('@/assets/images/copy_active.svg')]"
|
||||
></div>
|
||||
{t('common.copy')}
|
||||
</Button>
|
||||
</Flex>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
))}
|
||||
</Flex>
|
||||
</RbCard>
|
||||
</Flex>
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import type { Application } from '@/views/ApplicationManagement/types'
|
||||
import type { ApiKeyModalRef } from '../types'
|
||||
import { createApiKey } from '@/api/apiKey';
|
||||
import RbModal from '@/components/RbModal'
|
||||
import RbSlider from '@/components/RbSlider'
|
||||
|
||||
const FormItem = Form.Item;
|
||||
|
||||
@@ -97,6 +98,10 @@ const ApiKeyModal = forwardRef<ApiKeyModalRef, ApiKeyModalProps>(({
|
||||
form={form}
|
||||
layout="vertical"
|
||||
scrollToFirstError={{ behavior: 'instant', block: 'end', focus: true }}
|
||||
initialValues={{
|
||||
rate_limit: 50,
|
||||
daily_request_limit: 100000
|
||||
}}
|
||||
>
|
||||
{/* Key name */}
|
||||
<FormItem
|
||||
@@ -116,6 +121,36 @@ const ApiKeyModal = forwardRef<ApiKeyModalRef, ApiKeyModalProps>(({
|
||||
>
|
||||
<Input.TextArea placeholder={t('application.apiKeyDescPlaceholder')} />
|
||||
</FormItem>
|
||||
<FormItem
|
||||
name="rate_limit"
|
||||
label={<>{t(`application.qpsLimit`)}({t('application.qpsLimitTip')}, {t('application.qpsLimitUnit')})</>}
|
||||
extra={t('application.qpsLimitDesc')}
|
||||
rules={[
|
||||
{ required: true, message: t('common.pleaseEnter') },
|
||||
]}
|
||||
>
|
||||
<RbSlider
|
||||
min={1}
|
||||
max={100}
|
||||
step={1}
|
||||
isInput={true}
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem
|
||||
name="daily_request_limit"
|
||||
label={<>{t(`application.dailyUsageLimit`)} ({t('application.dailyUsageLimitUnit')})</>}
|
||||
extra={t('application.dailyUsageLimitDesc')}
|
||||
rules={[
|
||||
{ required: true, message: t('common.pleaseEnter') },
|
||||
]}
|
||||
>
|
||||
<RbSlider
|
||||
min={100}
|
||||
max={100000}
|
||||
step={100}
|
||||
isInput={true}
|
||||
/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</RbModal>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user