handleCancelOne(item)}
+ />
+
+
+ {item.source_app_name[0]}
+
+ {item.source_app_name}
+
+
+
+ {t('application.type')}
+
+ {t(`application.${item.source_app_type}`)}
+
+
+
+ {t('application.version')}
+ {item.source_app_version}
+
+
+ {t('application.permission')}
+
+ {t(`application.${item.permission}`)}
+
+
+
+ {t('application.souceStatus')}
+ {item.source_app_is_active ? t('application.sourceActive') : t('application.sourceInactive')}
+
+
+
+ ))}
+
+ ),
+ }]}
+ />
+ ))}
+
+ );
+};
+
+export default MySharing;
diff --git a/web/src/views/ApplicationManagement/index.tsx b/web/src/views/ApplicationManagement/index.tsx
index 62c02574..32652bc3 100644
--- a/web/src/views/ApplicationManagement/index.tsx
+++ b/web/src/views/ApplicationManagement/index.tsx
@@ -2,7 +2,7 @@
* @Author: ZhaoYing
* @Date: 2026-02-03 16:34:12
* @Last Modified by: ZhaoYing
- * @Last Modified time: 2026-03-02 17:48:51
+ * @Last Modified time: 2026-03-16 09:56:02
*/
/**
* Application Management Page
@@ -10,9 +10,9 @@
* Supports creating, editing, and deleting applications
*/
-import React, { useState, useRef, useEffect } from 'react';
+import React, { useState, useRef, useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
-import { Button, Row, Col, App, Select, Space, Dropdown } from 'antd';
+import { Button, App, Select, Space, Dropdown, type SegmentedProps, Flex, Form } from 'antd';
import clsx from 'clsx';
import { DeleteOutlined } from '@ant-design/icons';
import { useSearchParams } from 'react-router-dom'
@@ -21,12 +21,16 @@ 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 { getApplicationListUrl, deleteApplication, copyApplication } 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'
+import PageTabs from '@/components/PageTabs'
+import MySharing from './MySharing'
+
+const tabKeys = ['apps', 'sharing', 'myShare']
/**
* Application management main component
*/
@@ -34,20 +38,19 @@ 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);
+ const [form] = Form.useForm()
+ const query = Form.useWatch([], form)
+ const [activeTab, setActiveTab] = useState('apps');
useEffect(() => {
// Convert URLSearchParams to a plain object for easier access
const data = Object.fromEntries(searchParams)
const { type } = data
- setQuery(prev => ({
- ...prev,
- type: type || undefined
- }))
+ form.setFieldValue('type', type || undefined)
}, [searchParams])
/** Refresh application list */
@@ -61,7 +64,11 @@ const ApplicationManagement: React.FC = () => {
}
/** Navigate to application configuration page */
const handleEdit = (item: Application) => {
- window.open(`/#/application/config/${item.id}`);
+ let url = `/#/application/config/${item.id}`
+ if (item.is_shared) {
+ url += `/${activeTab}`
+ }
+ window.open(url);
}
/** Delete application with confirmation */
const handleDelete = (item: Application) => {
@@ -81,9 +88,6 @@ const ApplicationManagement: React.FC = () => {
}
})
}
- const handleChangeType = (value?: string) => {
- setQuery(prev => ({...prev, type: value}))
- }
const handleImport = () => {
uploadWorkflowModalRef.current?.handleOpen()
@@ -97,90 +101,137 @@ const ApplicationManagement: React.FC = () => {
uploadModalRef.current?.handleOpen()
}
}
+ const formatTabItems = useMemo(() => {
+ return tabKeys.map(value => ({
+ value,
+ label: t(`application.${value}`),
+ }))
+ }, [tabKeys, t])
+ /** Handle tab change */
+ const handleChangeTab = (value: SegmentedProps['value']) => {
+ setActiveTab(value as string);
+ form.resetFields()
+ }
+ const handleCopy = (item: Application) => {
+ modal.confirm({
+ title: t('application.confirmCopyDesc', { app: item.name }),
+ okText: t('common.copy'),
+ cancelText: t('common.cancel'),
+ onOk: () => {
+ copyApplication(item.id)
+ .then(() => {
+ setActiveTab('apps')
+ })
+ }
+ });
+ }
return (
<>
-
-
-
+ }
>
-