Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions frontend/src/components/layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, Suspense } from 'react';
import type { MenuProps } from 'antd';
import { Layout, Menu } from 'antd';
import { MenuFoldOutlined } from '@ant-design/icons';
Expand Down Expand Up @@ -155,19 +155,21 @@ const AppLayout: React.FC = () => {
<Layout className={setClassName()}>
<Provider store={store}>
<Content style={{ padding: (layoutValidate() || isSpaMode()) ? '0 16px' : '0', background: colorBgContainer }}>
<Switch>
{flattenRouteList.map((route) => (
<Route
exact
path={route.key}
key={route.key}
component={route.component}
/>
))}
<Route exact path='/' key='/' >
<Redirect to='/app-develop' />
</Route>
</Switch>
<Suspense fallback={<div style={{display:"none"}}>loading</div>}>
<Switch>
{flattenRouteList.map((route) => (
<Route
exact
path={route.key}
key={route.key}
component={route.component}
/>
))}
<Route exact path='/' key='/' >
<Redirect to='/app-develop' />
</Route>
</Switch>
</Suspense>
</Content>
</Provider>
</Layout>
Expand Down
21 changes: 4 additions & 17 deletions frontend/src/locale/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,17 @@ import i18n from 'i18next';
import { initReactI18next } from "react-i18next";
import en from './en_US.json';
import zh from './zh_CN.json';
import coreEn from '@fit-elsa/elsa-core/locales/en.json';
import coreZh from '@fit-elsa/elsa-core/locales/zh.json';
import reactEn from '@fit-elsa/elsa-react/locales/en.json';
import reactZh from '@fit-elsa/elsa-react/locales/zh.json';

const mergeTranslations = (...translationObjects) => {
// 从右向左合并(右侧优先级更高)
return translationObjects
.filter(obj => obj) // 过滤掉假值(undefined/null
.reduce((merged, current) => ({ ...merged, ...current }), {});
};

const resources = {
en: {
translation: mergeTranslations(coreEn, reactEn, en) // 优先级顺序: en > reactEn > coreEn
translation: en
},
zh: {
translation: mergeTranslations(coreZh, reactZh, zh) // 优先级顺序: zh > reactZh > coreZh
translation: zh
}
};

const getCookie = (cname) => {
const getCookie = (cname: string) => {
const name = `${cname}=`;
const ca = document.cookie.split(';');
for (let i = 0; i < ca.length; i++) {
Expand All @@ -49,6 +38,4 @@ i18n.use(initReactI18next).init({
returnNull: false
});



export default i18n;
export default i18n;
18 changes: 10 additions & 8 deletions frontend/src/pages/aippIndex/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import React, { useCallback, useEffect, useRef, useState } from 'react';
import React, { useCallback, useEffect, useRef, useState, lazy, Suspense } from 'react';
import { Spin } from 'antd';
import { useParams } from 'react-router-dom';
import AddFlow from '../addFlow';
import ConfigForm from '../configForm';
import CommonChat from '../chatPreview/chatComminPage';
const CommonChat = lazy(() => import('../chatPreview/chatComminPage'));
import ChoreographyHead from '../components/header';
import { getAppInfo, updateFormInfo } from '@/shared/http/aipp';
import { debounce, getCurrentTime, getUiD, setSpaClassName, getAppConfig } from '@/shared/utils/common';
Expand Down Expand Up @@ -215,12 +215,14 @@ const AippIndex = () => {
onChangeShowConfig={handleChangeShowConfig}
/>
)}
<CommonChat
showElsa={showElsa}
contextProvider={contextProvider}
previewBack={changeChat}
pluginName={pluginName}
/>
<Suspense fallback={<div style={{display:"none"}}>loading</div>}>
<CommonChat
showElsa={showElsa}
contextProvider={contextProvider}
previewBack={changeChat}
pluginName={pluginName}
/>
</Suspense>
</div>
</RenderContext.Provider>
</div>
Expand Down
2 changes: 0 additions & 2 deletions frontend/src/pages/chatPreview/components/chat-details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { CreateAppIcon } from '@/assets/icon';
import { useAppDispatch, useAppSelector } from '@/store/hook';
import { findConfigValue } from '@/shared/utils/common';
import { convertImgPath } from '@/common/util';
import EditModal from '@/pages/components/edit-modal';
import knowledgeBase from '@/assets/images/knowledge/knowledge-base.png';
import robot2 from '@/assets/images/ai/demo.png';
import '../styles/chat-details.scss';
Expand Down Expand Up @@ -103,7 +102,6 @@ const ChatDetail = ({ showMask = false }) => {
</div>
</div>
)) : <NormalAppInfo showMask={showMask} />}
<EditModal type='add' modalRef={modalRef} appInfo={modalInfo} addAippCallBack={addAippCallBack} />
</div>
)}</>;
};
Expand Down
31 changes: 16 additions & 15 deletions frontend/src/router/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,23 @@
*--------------------------------------------------------------------------------------------*/

import type { MenuProps } from 'antd';
import { ReactElement } from 'react';
import { ReactElement, lazy } from 'react';
import { Icons } from '../components/icons/index';
import IntelligentForm from '../pages/intelligent-form';
import Plugin from '../pages/plugin';
import ChatHome from '../pages/chatEngineHome/index';
import ChatRunning from '../pages/chatRunning/index';
import AppDetail from '../pages/appDetail';
import AippIndex from '../pages/aippIndex';
import AddFlow from '../pages/addFlow';
import FlowDetail from '../pages/detailFlow';
import Apps from '../pages/apps';
import AppDev from '../pages/appDev/index';
import PlugeDetail from '../pages/plugin/detail/plugin-list';
import PlugeFlowDetail from '../pages/plugin/detail/plugin-flow-detail';
import ViewReport from '../pages/appDetail/evaluate/task/viewReport';
import HttpTool from '../pages/httpTool';
const IntelligentForm = lazy(()=> import('../pages/intelligent-form'));
const Plugin = lazy(()=> import('../pages/plugin'));
const ChatHome = lazy(()=> import('../pages/chatEngineHome/index'));
const ChatRunning = lazy(()=> import('../pages/chatRunning/index'));
const AppDetail = lazy(()=> import('../pages/appDetail'));
const AippIndex = lazy(() => import('../pages/aippIndex'));
const AddFlow = lazy(()=> import('../pages/addFlow'));
const FlowDetail = lazy(()=> import('../pages/detailFlow'));
const Apps = lazy(()=> import('../pages/apps'));
const AppDev = lazy(()=> import('../pages/appDev/index'));
const PlugeDetail = lazy(()=> import('../pages/plugin/detail/plugin-list'));
const PlugeFlowDetail = lazy(()=> import('../pages/plugin/detail/plugin-flow-detail'));
const ViewReport = lazy(()=> import('../pages/appDetail/evaluate/task/viewReport'));
const HttpTool = lazy(()=> import('../pages/httpTool'));

import i18n from '../locale/i18n';

export type MenuItem = Required<MenuProps>['items'][number] & {
Expand Down
124 changes: 123 additions & 1 deletion frontend/src/shared/utils/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { useLocation } from 'react-router-dom';
import { useCallback, useMemo, useState } from 'react';
import { pick, find, filter } from 'lodash';
import { Message } from '@/shared/utils/message';
import { createGraphOperator } from '@fit-elsa/elsa-react';
import { storage } from '../storage';
import i18n from '@/locale/i18n';
import { getAppCategories } from "@/shared/http/aipp";
Expand Down Expand Up @@ -450,3 +449,126 @@ export const getAppConfig = (appInfo) => {
export const generateUniqueName = () => {
return 'guest-' + nanoid(16);
}

// ==================== GraphOperator ====================

// 数据类型常量
const DATA_TYPES = {
STRING: 'String',
INTEGER: 'Integer',
BOOLEAN: 'Boolean',
NUMBER: 'Number',
OBJECT: 'Object',
ARRAY: 'Array',
};

// 来源类型常量
const FROM_TYPE = {
EXPAND: 'Expand',
INPUT: 'Input',
REFERENCE: 'Reference',
};

/**
* 将配置数据转换为结构体
* @param config 配置数据
* @return {{}|*} 结构体
*/
const configToStruct = (config: any) => {
if (config.type === DATA_TYPES.ARRAY) {
return config.value.map(v => configToStruct(v));
} else if (config.type === DATA_TYPES.OBJECT) {
const obj = {};
config.value.forEach((item: any) => {
obj[item.name] = configToStruct(item);
});
return obj;
} else {
return Object.prototype.hasOwnProperty.call(config, 'value') ? config.value : config;
}
};

/**
* 创建画布操纵器
* @param graphString 画布字符串
* @return {{}} 画布操纵器对象
*/
export const createGraphOperator = (graphString: string) => {
const graph = JSON.parse(graphString);
const shapes = graph.pages[0].shapes;

const getInputParams = (shape: any) => {
if (shape.type === 'startNodeStart') {
return shape.flowMeta.inputParams;
} else if (shape.type === 'endNodeEnd') {
return shape.flowMeta.callback.converter.entity.inputParams;
} else {
return shape.flowMeta.jober.converter.entity.inputParams;
}
};

const getConfigByKeys = (keys: string[]) => {
if (!Array.isArray(keys)) {
throw new Error('Expected keys to be an array');
}

if (keys.length === 0) {
return null;
}

const tmpKeys = [...keys];
const shapeId = tmpKeys.shift();
const shape = getShapeById(shapeId);
const inputParams = getInputParams(shape);
if (!inputParams) {
throw new Error('Expected inputParams exists');
}
let config = {type: DATA_TYPES.OBJECT, value: inputParams};
while (tmpKeys.length > 0 && config && config.value) {
const key = tmpKeys.shift();
config = config.value.find(v => v.name === key);
}
return config;
};

const getShapeById = (shapeId: string) => {
return shapes.find((shape) => shape.id === shapeId);
};

return {
/**
* 获取配置信息
* @param keys 键值数组
* @return {{}|*|null} 配置信息
*/
getConfig: (keys: string[]) => {
const config = getConfigByKeys(keys);
return config ? configToStruct(config) : null;
},

/**
* 获取画布中开始节点的入参信息
* @return {array} 开始节点入参信息
*/
getStartNodeInputParams: (): any[] => {
return shapes.filter(shape => shape.type === 'startNodeStart').map(startNode => startNode.flowMeta.inputParams);
},

/**
* 根据节点类型获取对应节点id列表
* @param type 节点类型
* @returns {array} 对应节点id列表
*/
getShapeIdsByType: (type: string): string[] => {
return shapes.filter((shape) => shape.type === type).map((shape) => shape.id);
},

/**
* 获取画布数据
* @return {string} 画布数据
*/
getGraph: (): string => {
return JSON.stringify(graph);
}
};
};