import AutoTooltip from '@/components/auto-tooltip'; import DropdownButtons from '@/components/drop-down-buttons'; import { TooltipOverlayScroller } from '@/components/overlay-scroller'; import StatusTag from '@/components/status-tag'; import { modelSourceMap } from '@/pages/llmodels/config'; import { modelFileActions } from '@/pages/llmodels/config/button-actions'; import { convertFileSize } from '@/utils'; import { CheckCircleFilled, CopyOutlined, InfoCircleOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; import { Tag, Typography } from 'antd'; import { ColumnsType } from 'antd/lib/table'; import dayjs from 'dayjs'; import _ from 'lodash'; import { useMemo } from 'react'; import styled from 'styled-components'; import { ModelfileState, ModelfileStateMap, ModelfileStateMapValue } from '../config'; import { ModelFile as ListItem } from '../config/types'; const { Paragraph } = Typography; const TextWrapper = styled.div` display: flex; align-items: center; cursor: pointer; height: 100%; `; const PathWrapper = styled.div` display: flex; align-items: center; justify-content: flex-start; height: 100%; &::after { content: ''; display: block; width: 20px; height: 100%; position: absolute; top: 0; right: 0; z-index: 1; } .btn-wrapper { display: flex; opacity: 0; width: 0; align-items: center; } &:hover { .btn-wrapper { width: auto; opacity: 1; } } `; const FilesTag = styled(Tag)` cursor: pointer; display: flex; align-items: center; margin-inline: 4px 0; height: 22px; border-radius: var(--border-radius-base); `; const TypographyPara = styled(Paragraph)` background: transparent; color: inherit; margin-bottom: 0; font-size: 13px; `; const ItemWrapper = styled.ul` max-width: 300px; margin: 0; padding-inline: 13px 0; word-break: break-word; li { line-height: 1.6; } `; const getResolvedPath = (pathList: string[]) => { return _.split(pathList?.[0], /[\\/]/).pop(); }; const setActionList = (record: ListItem) => { return _.filter(modelFileActions, (item: { key: string }) => { if (item.key === 'deploy') { return record.state === ModelfileStateMap.Ready; } return true; }); }; const TooltipTitle: React.FC<{ path: string }> = ({ path }) => { const intl = useIntl(); return ( , ], text: path, tooltips: [ intl.formatMessage({ id: 'common.button.copy' }), intl.formatMessage({ id: 'common.button.copied' }) ] }} > {path} ); }; const InstanceStatusTag = (props: { data: ListItem }) => { const { data } = props; if (!data.state) { return null; } return ( ); }; const getModelInfo = (record: ListItem) => { const source = _.get(modelSourceMap, record.source, ''); if (record.source === modelSourceMap.huggingface_value) { return { source: `${source}/${record.huggingface_repo_id}`, repo_id: record.huggingface_repo_id, title: `${record.huggingface_repo_id}/${record.huggingface_filename}`, filename: record.huggingface_filename || record.huggingface_repo_id }; } if (record.source === modelSourceMap.modelscope_value) { return { source: `${source}/${record.model_scope_model_id}`, repo_id: record.model_scope_model_id, title: `${record.model_scope_model_id}/${record.model_scope_file_path}`, filename: record.model_scope_file_path || record.model_scope_model_id }; } return { source: `${source}${record.local_path}`, repo_id: record.local_path, title: record.local_path, filename: _.split(record.local_path, /[\\/]/).pop() }; }; const RenderParts = (props: { record: ListItem }) => { const { record } = props; const intl = useIntl(); const parts = record.resolved_paths || []; if (parts.length <= 1) { return null; } const renderItem = () => { return ( {parts.map((item: string, index: number) => { return
  • {_.split(item, /[\\/]/).pop()}
  • ; })}
    ); }; return ( }> {record.resolved_paths?.length}{' '} {intl.formatMessage({ id: 'models.form.files' })} ); }; const ResolvedPathColumn = (props: { record: ListItem }) => { const { record } = props; const intl = useIntl(); if ( !record.resolved_paths.length && record.state === ModelfileStateMap.Downloading ) { return ( {intl.formatMessage({ id: 'resources.modelfiles.storagePath.holder' })} ); } return ( record.resolved_paths?.length > 0 && ( } > {getResolvedPath(record.resolved_paths)} ) ); }; const getWorkerName = ( id: number, workersList: Global.BaseOption[] ) => { const worker = workersList.find((item) => item.value === id); return worker?.label || ''; }; const useFilesColumns = (props: { handleSelect: (action: string, record: ListItem) => void; workersList: Global.BaseOption[]; }): ColumnsType => { const { workersList, handleSelect } = props; const intl = useIntl(); return useMemo(() => { return [ { title: intl.formatMessage({ id: 'models.form.source' }), dataIndex: 'source', ellipsis: { showTitle: false }, render: (text: string, record: ListItem) => { const modelInfo = getModelInfo(record); const { source } = modelInfo; return ( {source} ); } }, { title: intl.formatMessage({ id: 'resources.worker' }), dataIndex: 'worker_name', ellipsis: { showTitle: false }, render: (text: string, record: ListItem) => { return ( {getWorkerName(record.worker_id, workersList)} ); } }, { title: intl.formatMessage({ id: 'common.table.status' }), dataIndex: 'state', width: 132, render: (text: string, record: ListItem) => { return ; } }, { title: intl.formatMessage({ id: 'resources.modelfiles.form.path' }), dataIndex: 'resolved_paths', width: '20%', ellipsis: { showTitle: false }, render: (text: string, record: ListItem) => ( ) }, { title: intl.formatMessage({ id: 'resources.modelfiles.size' }), dataIndex: 'size', width: 110, align: 'right', ellipsis: { showTitle: false }, render: (text: string, record: ListItem) => { return ( {convertFileSize(record.size, 1, true)} ); } }, { title: intl.formatMessage({ id: 'common.table.createTime' }), dataIndex: 'created_at', sorter: false, width: 180, ellipsis: { showTitle: false }, render: (text: number) => ( {dayjs(text).format('YYYY-MM-DD HH:mm:ss')} ) }, { title: intl.formatMessage({ id: 'common.table.operation' }), dataIndex: 'operation', width: 120, render: (text: string, record: ListItem) => ( handleSelect(val, record)} > ) } ]; }, [intl, workersList, handleSelect]); }; export default useFilesColumns;