| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- /*
- Copyright (C) 2025 QuantumNous
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
- For commercial licensing, please contact support@quantumnous.com
- */
- import React, { useState } from 'react';
- import { Card, Divider, Typography, Button } from '@douyinfe/semi-ui';
- import PropTypes from 'prop-types';
- import { useIsMobile } from '../../../hooks/common/useIsMobile';
- import { IconEyeOpened, IconEyeClosed } from '@douyinfe/semi-icons';
- const { Text } = Typography;
- /**
- * CardPro 高级卡片组件
- *
- * 布局分为5个区域:
- * 1. 统计信息区域 (statsArea)
- * 2. 描述信息区域 (descriptionArea)
- * 3. 类型切换/标签区域 (tabsArea)
- * 4. 操作按钮区域 (actionsArea)
- * 5. 搜索表单区域 (searchArea)
- *
- * 支持三种布局类型:
- * - type1: 操作型 (如TokensTable) - 描述信息 + 操作按钮 + 搜索表单
- * - type2: 查询型 (如LogsTable) - 统计信息 + 搜索表单
- * - type3: 复杂型 (如ChannelsTable) - 描述信息 + 类型切换 + 操作按钮 + 搜索表单
- */
- const CardPro = ({
- type = 'type1',
- className = '',
- children,
- // 各个区域的内容
- statsArea,
- descriptionArea,
- tabsArea,
- actionsArea,
- searchArea,
- // 卡片属性
- shadows = 'always',
- bordered = false,
- // 自定义样式
- style,
- // 国际化函数
- t = (key) => key, // 默认函数,直接返回key
- ...props
- }) => {
- const isMobile = useIsMobile();
- const [showMobileActions, setShowMobileActions] = useState(false);
- // 切换移动端操作项显示状态
- const toggleMobileActions = () => {
- setShowMobileActions(!showMobileActions);
- };
- // 检查是否有需要在移动端隐藏的内容
- const hasMobileHideableContent = actionsArea || searchArea;
- // 渲染头部内容
- const renderHeader = () => {
- const hasContent = statsArea || descriptionArea || tabsArea || actionsArea || searchArea;
- if (!hasContent) return null;
- return (
- <div className="flex flex-col w-full">
- {/* 统计信息区域 - 用于type2 */}
- {type === 'type2' && statsArea && (
- <>
- {statsArea}
- </>
- )}
- {/* 描述信息区域 - 用于type1和type3 */}
- {(type === 'type1' || type === 'type3') && descriptionArea && (
- <>
- {descriptionArea}
- </>
- )}
- {/* 第一个分隔线 - 在描述信息或统计信息后面 */}
- {((type === 'type1' || type === 'type3') && descriptionArea) ||
- (type === 'type2' && statsArea) ? (
- <Divider margin="12px" />
- ) : null}
- {/* 类型切换/标签区域 - 主要用于type3 */}
- {type === 'type3' && tabsArea && (
- <>
- {tabsArea}
- </>
- )}
- {/* 移动端操作切换按钮 */}
- {isMobile && hasMobileHideableContent && (
- <>
- <div className="w-full mb-2">
- <Button
- onClick={toggleMobileActions}
- icon={showMobileActions ? <IconEyeClosed /> : <IconEyeOpened />}
- type="tertiary"
- size="small"
- block
- >
- {showMobileActions ? t('隐藏操作项') : t('显示操作项')}
- </Button>
- </div>
- </>
- )}
- {/* 操作按钮和搜索表单的容器 */}
- <div
- className={`flex flex-col gap-2 ${isMobile && !showMobileActions ? 'hidden' : ''}`}
- >
- {/* 操作按钮区域 - 用于type1和type3 */}
- {(type === 'type1' || type === 'type3') && actionsArea && (
- <div className="w-full">
- {actionsArea}
- </div>
- )}
- {/* 搜索表单区域 - 所有类型都可能有 */}
- {searchArea && (
- <div className="w-full">
- {searchArea}
- </div>
- )}
- </div>
- </div>
- );
- };
- const headerContent = renderHeader();
- return (
- <Card
- className={`table-scroll-card !rounded-2xl ${className}`}
- title={headerContent}
- shadows={shadows}
- bordered={bordered}
- style={style}
- {...props}
- >
- {children}
- </Card>
- );
- };
- CardPro.propTypes = {
- // 布局类型
- type: PropTypes.oneOf(['type1', 'type2', 'type3']),
- // 样式相关
- className: PropTypes.string,
- style: PropTypes.object,
- shadows: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
- bordered: PropTypes.bool,
- // 内容区域
- statsArea: PropTypes.node,
- descriptionArea: PropTypes.node,
- tabsArea: PropTypes.node,
- actionsArea: PropTypes.node,
- searchArea: PropTypes.node,
- // 表格内容
- children: PropTypes.node,
- // 国际化函数
- t: PropTypes.func,
- };
- export default CardPro;
|