/* * @Author: ZhaoYing * @Date: 2026-02-03 16:29:41 * @Last Modified by: ZhaoYing * @Last Modified time: 2026-03-18 20:57:24 */ import { type FC, useState, useEffect, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import clsx from 'clsx'; import { Button, Space, Input, Form, App } from 'antd'; import Tag, { type TagProps } from './components/Tag' import RbCard from '@/components/RbCard/Card' import { getReleaseList, rollbackRelease, appExport } from '@/api/application' import ReleaseModal from './components/ReleaseModal' import ReleaseShareModal from './components/ReleaseShareModal' import AppSharingModal from './components/AppSharingModal' import type { Release, ReleaseModalRef, ReleaseShareModalRef, AppSharingModalRef } from './types' import type { Application } from '@/views/ApplicationManagement/types' import Empty from '@/components/Empty' import { formatDateTime } from '@/utils/format'; import Markdown from '@/components/Markdown' /** * Tag color mapping for release versions */ const tagColors: Record = { current: 'processing', rolledBack: 'warning', history: 'default', } /** * Release page component * Manages application version releases, rollbacks, and version history * @param data - Application data * @param refresh - Function to refresh application data */ const ReleasePage: FC<{data: Application; refresh: () => void}> = ({data, refresh}) => { const { t } = useTranslation(); const { message } = App.useApp() const releaseModalRef = useRef(null) const releaseShareModalRef = useRef(null) const appSharingModalRef = useRef(null) const [selectedVersion, setSelectedVersion] = useState(null); const [releaseList, setReleaseList] = useState([]) useEffect(() => { getData() }, [data.id]) /** * Fetch release list data */ const getData = () => { refresh() getReleaseList(data.id).then(res => { const response = res as Release[] || [] setReleaseList(response) setSelectedVersion(response?.[0]) }) } /** * Rollback to selected version */ const handleRollback = () => { if (!selectedVersion) return rollbackRelease(data.id, selectedVersion.version).then(() => { getData() message.success(t('common.operateSuccess')) }) } const handleExport = () => { if (!selectedVersion) return appExport(data.id, data.name, { release_id: selectedVersion.id}) } return (
{t('application.versionList')}
{t('application.versionListDesc')}
{releaseList.length === 0 ? : selectedVersion && releaseList.map((version, index) => { const tagKey = version.id === data.current_release_id && index === 0 ? 'current' : version.id === data.current_release_id ? 'rolledBack' : 'history' return ( {version.version_name && version.version_name[0].toLocaleLowerCase() === 'v' ? version.version_name : version.version_name ? `v${version.version_name}` : `v${version.version}`} {tagKey && {tagKey} } } className={clsx("rb:hover:border-[#155EEF]! rb:cursor-pointer", { 'rb:bg-[rgba(21,94,239,0.06)]! rb:border-[#155EEF]!': version.id === selectedVersion.id, 'rb:border-[#DFE4ED] rb:bg-[#FBFDFF]': version.id !== selectedVersion.id })} headerType="borderless" onClick={() => setSelectedVersion(version)} >
{t('application.publishedOn')} {formatDateTime(version.published_at, 'YYYY-MM-DD HH:mm:ss')}
{t('application.publisher')}: {version.publisher_name}
) }) }
{selectedVersion && t('application.DetailsOfVersion', { version: selectedVersion.version_name && selectedVersion.version_name[0].toLocaleLowerCase() === 'v' ? selectedVersion.version_name : selectedVersion.version_name ? `v${selectedVersion.version_name}` : `v${selectedVersion.version}` || '-' })} {selectedVersion && <> {data?.type !== 'multi_agent' && } {data.current_release_id !== selectedVersion.id && } {data?.type !== 'multi_agent' && } }
{selectedVersion &&
{/* Logs */} {selectedVersion && ( {formatDateTime(selectedVersion.published_at, 'YYYY-MM-DD HH:mm:ss')}
} extra={{selectedVersion.publisher_name}} >
)} }
); } export default ReleasePage;