| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
|
|
| import React from 'react';
|
| import {
|
| Card,
|
| Button,
|
| Spin,
|
| Tabs,
|
| TabPane,
|
| Tag,
|
| Empty,
|
| } from '@douyinfe/semi-ui';
|
| import { Gauge, RefreshCw } from 'lucide-react';
|
| import {
|
| IllustrationConstruction,
|
| IllustrationConstructionDark,
|
| } from '@douyinfe/semi-illustrations';
|
| import ScrollableContainer from '../common/ui/ScrollableContainer';
|
|
|
| const UptimePanel = ({
|
| uptimeData,
|
| uptimeLoading,
|
| activeUptimeTab,
|
| setActiveUptimeTab,
|
| loadUptimeData,
|
| uptimeLegendData,
|
| renderMonitorList,
|
| CARD_PROPS,
|
| ILLUSTRATION_SIZE,
|
| t,
|
| }) => {
|
| return (
|
| <Card
|
| {...CARD_PROPS}
|
| className='shadow-sm !rounded-2xl lg:col-span-1'
|
| title={
|
| <div className='flex items-center justify-between w-full gap-2'>
|
| <div className='flex items-center gap-2'>
|
| <Gauge size={16} />
|
| {t('服务可用性')}
|
| </div>
|
| <Button
|
| icon={<RefreshCw size={14} />}
|
| onClick={loadUptimeData}
|
| loading={uptimeLoading}
|
| size='small'
|
| theme='borderless'
|
| type='tertiary'
|
| className='text-gray-500 hover:text-blue-500 hover:bg-blue-50 !rounded-full'
|
| />
|
| </div>
|
| }
|
| bodyStyle={{ padding: 0 }}
|
| >
|
| {/* 内容区域 */}
|
| <div className='relative'>
|
| <Spin spinning={uptimeLoading}>
|
| {uptimeData.length > 0 ? (
|
| uptimeData.length === 1 ? (
|
| <ScrollableContainer maxHeight='24rem'>
|
| {renderMonitorList(uptimeData[0].monitors)}
|
| </ScrollableContainer>
|
| ) : (
|
| <Tabs
|
| type='card'
|
| collapsible
|
| activeKey={activeUptimeTab}
|
| onChange={setActiveUptimeTab}
|
| size='small'
|
| >
|
| {uptimeData.map((group, groupIdx) => (
|
| <TabPane
|
| tab={
|
| <span className='flex items-center gap-2'>
|
| <Gauge size={14} />
|
| {group.categoryName}
|
| <Tag
|
| color={
|
| activeUptimeTab === group.categoryName
|
| ? 'red'
|
| : 'grey'
|
| }
|
| size='small'
|
| shape='circle'
|
| >
|
| {group.monitors ? group.monitors.length : 0}
|
| </Tag>
|
| </span>
|
| }
|
| itemKey={group.categoryName}
|
| key={groupIdx}
|
| >
|
| <ScrollableContainer maxHeight='21.5rem'>
|
| {renderMonitorList(group.monitors)}
|
| </ScrollableContainer>
|
| </TabPane>
|
| ))}
|
| </Tabs>
|
| )
|
| ) : (
|
| <div className='flex justify-center items-center py-8'>
|
| <Empty
|
| image={<IllustrationConstruction style={ILLUSTRATION_SIZE} />}
|
| darkModeImage={
|
| <IllustrationConstructionDark style={ILLUSTRATION_SIZE} />
|
| }
|
| title={t('暂无监控数据')}
|
| description={t('请联系管理员在系统设置中配置Uptime')}
|
| />
|
| </div>
|
| )}
|
| </Spin>
|
| </div>
|
|
|
| {/* 图例 */}
|
| {uptimeData.length > 0 && (
|
| <div className='p-3 bg-gray-50 rounded-b-2xl'>
|
| <div className='flex flex-wrap gap-3 text-xs justify-center'>
|
| {uptimeLegendData.map((legend, index) => (
|
| <div key={index} className='flex items-center gap-1'>
|
| <div
|
| className='w-2 h-2 rounded-full'
|
| style={{ backgroundColor: legend.color }}
|
| />
|
| <span className='text-gray-600'>{legend.label}</span>
|
| </div>
|
| ))}
|
| </div>
|
| </div>
|
| )}
|
| </Card>
|
| );
|
| };
|
|
|
| export default UptimePanel;
|
|
|