Merge branch 'develop' into feature/skill_zy
This commit is contained in:
@@ -37,7 +37,7 @@ function App() {
|
||||
const { checkJump } = useUser();
|
||||
useEffect(() => {
|
||||
const authToken = cookieUtils.get('authToken')
|
||||
if (!authToken && !window.location.hash.includes('#/login') && !window.location.hash.includes('#/conversation/')) {
|
||||
if (!authToken && !window.location.hash.includes('#/login') && !window.location.hash.includes('#/conversation/') && !window.location.hash.includes('#/jump')) {
|
||||
window.location.href = `/#/login`;
|
||||
} else {
|
||||
checkJump()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-02 16:33:11
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-04 14:06:45
|
||||
* @Last Modified time: 2026-02-04 18:11:34
|
||||
*/
|
||||
/**
|
||||
* Route Configuration
|
||||
@@ -23,7 +23,6 @@ import { createHashRouter, createRoutesFromElements, Route } from 'react-router-
|
||||
/** Import route configuration JSON */
|
||||
import routesConfig from './routes.json';
|
||||
|
||||
|
||||
/** Recursively collect all element names from routes */
|
||||
function collectElements(routes: RouteConfig[]): Set<string> {
|
||||
const elements = new Set<string>();
|
||||
@@ -91,6 +90,7 @@ const componentMap: Record<string, LazyExoticComponent<ComponentType<object>>> =
|
||||
Prompt: lazy(() => import('@/views/Prompt')),
|
||||
Skills: lazy(() => import('@/views/Skills')),
|
||||
SkillConfig: lazy(() => import('@/views/Skills/pages/SkillConfig')),
|
||||
Jump: lazy(() => import('@/views/JumpPage')),
|
||||
Login: lazy(() => import('@/views/Login')),
|
||||
InviteRegister: lazy(() => import('@/views/InviteRegister')),
|
||||
NoPermission: lazy(() => import('@/views/NoPermission')),
|
||||
|
||||
@@ -61,7 +61,8 @@
|
||||
{
|
||||
"element": "NoAuthLayout",
|
||||
"children": [
|
||||
{ "path": "/conversation/:token", "element": "Conversation" }
|
||||
{ "path": "/conversation/:token", "element": "Conversation" },
|
||||
{ "path": "/jump", "element": "Jump" }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-02 16:33:54
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-02 16:33:54
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-04 18:30:10
|
||||
*/
|
||||
/**
|
||||
* User Store
|
||||
@@ -59,7 +59,8 @@ export interface UserState {
|
||||
export const whitePage = [
|
||||
'/conversation',
|
||||
'/login',
|
||||
'/invite-register'
|
||||
'/invite-register',
|
||||
'jump'
|
||||
]
|
||||
|
||||
/** User store */
|
||||
|
||||
@@ -35,7 +35,7 @@ interface ApplicationModalProps {
|
||||
/**
|
||||
* Supported application types
|
||||
*/
|
||||
const types = [
|
||||
export const types = [
|
||||
'agent',
|
||||
'multi_agent',
|
||||
'workflow'
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 16:34:12
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 16:34:12
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-04 18:57:35
|
||||
*/
|
||||
/**
|
||||
* Application Management Page
|
||||
@@ -12,12 +12,12 @@
|
||||
|
||||
import React, { useState, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button, Row, Col, App } from 'antd';
|
||||
import { Button, Row, Col, App, Select } from 'antd';
|
||||
import clsx from 'clsx';
|
||||
import { DeleteOutlined } from '@ant-design/icons';
|
||||
|
||||
import type { Application, ApplicationModalRef, Query } from './types';
|
||||
import ApplicationModal from './components/ApplicationModal';
|
||||
import ApplicationModal, { types } from './components/ApplicationModal';
|
||||
import SearchInput from '@/components/SearchInput'
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
import { getApplicationListUrl, deleteApplication } from '@/api/application'
|
||||
@@ -65,10 +65,25 @@ const ApplicationManagement: React.FC = () => {
|
||||
}
|
||||
})
|
||||
}
|
||||
const handleChangeType = (value?: string) => {
|
||||
setQuery(prev => ({...prev, type: value}))
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<Row gutter={16} className="rb:mb-4">
|
||||
<Col span={12}>
|
||||
<Col span={3}>
|
||||
<Select
|
||||
placeholder={t('application.applicationType')}
|
||||
options={types.map((type) => ({
|
||||
value: type,
|
||||
label: t(`application.${type}`),
|
||||
}))}
|
||||
allowClear
|
||||
className="rb:w-full"
|
||||
onChange={handleChangeType}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={9}>
|
||||
<SearchInput
|
||||
placeholder={t('application.searchPlaceholder')}
|
||||
onSearch={(value) => setQuery({ search: value })}
|
||||
|
||||
53
web/src/views/JumpPage.tsx
Normal file
53
web/src/views/JumpPage.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-04 18:34:36
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-04 18:49:59
|
||||
*/
|
||||
import { useEffect, type FC } from 'react'
|
||||
import { useNavigate, useSearchParams } from 'react-router-dom'
|
||||
|
||||
import { cookieUtils } from '@/utils/request'
|
||||
|
||||
/**
|
||||
* JumpPage Component
|
||||
*
|
||||
* This is an intermediate redirect page used for OAuth authentication flow.
|
||||
* It handles the callback from external authentication providers by:
|
||||
* 1. Extracting authentication tokens from URL query parameters
|
||||
* 2. Storing tokens in cookies for subsequent API requests
|
||||
* 3. Redirecting users to their intended destination
|
||||
*
|
||||
* Expected URL format:
|
||||
* /jump?access_token=xxx&refresh_token=yyy&target=/dashboard
|
||||
*
|
||||
* @returns null - This component doesn't render any UI, it only handles side effects
|
||||
*/
|
||||
const JumpPage: FC = () => {
|
||||
const navigate = useNavigate()
|
||||
const [searchParams] = useSearchParams()
|
||||
|
||||
useEffect(() => {
|
||||
// Convert URLSearchParams to a plain object for easier access
|
||||
const data = Object.fromEntries(searchParams)
|
||||
const { access_token, refresh_token, target } = data
|
||||
|
||||
// Store authentication tokens in cookies for API authorization
|
||||
cookieUtils.set('authToken', access_token)
|
||||
cookieUtils.set('refreshToken', refresh_token)
|
||||
|
||||
// Redirect to the target page if specified
|
||||
if (target) {
|
||||
// Use setTimeout to ensure cookie operations complete before navigation
|
||||
setTimeout(() => {
|
||||
// Replace current history entry to prevent users from going back to this page
|
||||
navigate(target, { replace: true })
|
||||
}, 0)
|
||||
}
|
||||
}, [searchParams, navigate])
|
||||
|
||||
// No UI rendering needed - this is a pure redirect handler
|
||||
return null
|
||||
}
|
||||
|
||||
export default JumpPage
|
||||
Reference in New Issue
Block a user