/* * @Author: ZhaoYing * @Date: 2026-02-03 16:34:12 * @Last Modified by: ZhaoYing * @Last Modified time: 2026-03-02 17:48:51 */ /** * Application Management Page * Displays and manages all applications in the workspace * Supports creating, editing, and deleting applications */ import React, { useState, useRef, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { Button, Row, Col, App, Select, Space, Dropdown } from 'antd'; import clsx from 'clsx'; import { DeleteOutlined } from '@ant-design/icons'; import { useSearchParams } from 'react-router-dom' import ApplicationModal, { types } from './components/ApplicationModal'; import type { Application, ApplicationModalRef, Query, UploadWorkflowModalRef } from './types'; import SearchInput from '@/components/SearchInput' import RbCard from '@/components/RbCard/Card' import { getApplicationListUrl, deleteApplication } from '@/api/application' import PageScrollList, { type PageScrollListRef } from '@/components/PageScrollList' import { formatDateTime } from '@/utils/format'; import UploadWorkflowModal from './components/UploadWorkflowModal' import UploadModal from './components/UploadModal' /** * Application management main component */ const ApplicationManagement: React.FC = () => { const { t } = useTranslation(); const { modal } = App.useApp(); const [searchParams] = useSearchParams() const [query, setQuery] = useState({} as Query); const applicationModalRef = useRef(null); const scrollListRef = useRef(null) const uploadWorkflowModalRef = useRef(null); const uploadModalRef = useRef(null); useEffect(() => { // Convert URLSearchParams to a plain object for easier access const data = Object.fromEntries(searchParams) const { type } = data setQuery(prev => ({ ...prev, type: type || undefined })) }, [searchParams]) /** Refresh application list */ const refresh = () => { scrollListRef.current?.refresh(); } /** Open create application modal */ const handleCreate = () => { applicationModalRef.current?.handleOpen(); } /** Navigate to application configuration page */ const handleEdit = (item: Application) => { window.open(`/#/application/config/${item.id}`); } /** Delete application with confirmation */ const handleDelete = (item: Application) => { modal.confirm({ title: t('common.confirmDeleteDesc', { name: item.name }), okText: t('common.delete'), cancelText: t('common.cancel'), okType: 'danger', onOk: () => { deleteApplication(item.id) .then(() => { refresh(); }) .catch(() => { console.error('Failed to delete application'); }); } }) } const handleChangeType = (value?: string) => { setQuery(prev => ({...prev, type: value})) } const handleImport = () => { uploadWorkflowModalRef.current?.handleOpen() } const handleClick = ({ key }: { key: string } ) => { switch (key) { case 'thirdParty': handleImport() break; case 'import': uploadModalRef.current?.handleOpen() } } return ( <>