From 31109fe46fee1ce995812fc4f9e61a26128e4796 Mon Sep 17 00:00:00 2001 From: SungChul Hong Date: Mon, 28 Oct 2024 17:26:17 +0900 Subject: [PATCH] feat: WebUI NEO start page --- react/package.json | 1 + ...cape-design__board-components@3.0.60.patch | 153 ++++++++--- react/pnpm-lock.yaml | 38 ++- react/src/App.tsx | 16 +- react/src/components/ActionItemContent.tsx | 122 +++++++++ react/src/components/BAIBoard.tsx | 40 +-- .../src/components/MainLayout/WebUISider.tsx | 10 +- .../SummaryItemDownloadApp.tsx | 92 ------- .../SummaryItemInvitation.tsx | 169 ------------- .../SummaryPageItems/SummaryItemStartMenu.tsx | 146 ----------- react/src/hooks/useBAISetting.tsx | 4 +- react/src/pages/Page401.tsx | 2 +- react/src/pages/Page404.tsx | 2 +- react/src/pages/StartPage.tsx | 239 ++++++++++++++++++ react/src/pages/SummaryPage.tsx | 85 ------- resources/i18n/de.json | 24 +- resources/i18n/el.json | 24 +- resources/i18n/en.json | 24 +- resources/i18n/es.json | 24 +- resources/i18n/fi.json | 24 +- resources/i18n/fr.json | 24 +- resources/i18n/id.json | 24 +- resources/i18n/it.json | 24 +- resources/i18n/ja.json | 24 +- resources/i18n/ko.json | 24 +- resources/i18n/mn.json | 24 +- resources/i18n/ms.json | 24 +- resources/i18n/pl.json | 24 +- resources/i18n/pt-BR.json | 24 +- resources/i18n/pt.json | 24 +- resources/i18n/ru.json | 24 +- resources/i18n/th.json | 24 +- resources/i18n/tr.json | 24 +- resources/i18n/vi.json | 24 +- resources/i18n/zh-CN.json | 24 +- resources/i18n/zh-TW.json | 24 +- resources/theme.json | 2 +- src/backend-ai-app.ts | 1 + src/components/backend-ai-error-view.ts | 6 +- .../backend-ai-permission-denied-view.ts | 6 +- src/components/backend-ai-storage-list.ts | 2 +- .../backend-ai-storage-proxy-list.ts | 2 +- src/components/backend-ai-summary-view.ts | 2 +- src/components/backend-ai-webui.ts | 3 +- 44 files changed, 1058 insertions(+), 589 deletions(-) create mode 100644 react/src/components/ActionItemContent.tsx delete mode 100644 react/src/components/SummaryPageItems/SummaryItemDownloadApp.tsx delete mode 100644 react/src/components/SummaryPageItems/SummaryItemInvitation.tsx delete mode 100644 react/src/components/SummaryPageItems/SummaryItemStartMenu.tsx create mode 100644 react/src/pages/StartPage.tsx delete mode 100644 react/src/pages/SummaryPage.tsx diff --git a/react/package.json b/react/package.json index b796de348a..553e296de5 100644 --- a/react/package.json +++ b/react/package.json @@ -10,6 +10,7 @@ "@cloudscape-design/board-components": "3.0.60", "@codemirror/language": "^6.10.2", "@melloware/react-logviewer": "^5.2.4", + "@react-hook/resize-observer": "^2.0.2", "@storybook/test": "^8.2.8", "@tanstack/react-query": "^5.51.15", "@testing-library/jest-dom": "^6.4.8", diff --git a/react/patches/@cloudscape-design__board-components@3.0.60.patch b/react/patches/@cloudscape-design__board-components@3.0.60.patch index 7fcfea5d48..faf5e1788c 100644 --- a/react/patches/@cloudscape-design__board-components@3.0.60.patch +++ b/react/patches/@cloudscape-design__board-components@3.0.60.patch @@ -99,54 +99,143 @@ index 9ce96efb6b78053be6c29b4ab98115e465c02372..cd0a89e0e5f5b092ba03ff191c720d29 //# sourceMappingURL=internal.js.map \ No newline at end of file diff --git a/board-item/styles.css.js b/board-item/styles.css.js -index 1dcaf7ccab588a3e3a1a9bfdab40d1b3e7d4a69f..f1d982c4f3451cb351c817e4e62b8bc3028caeea 100644 +index 1dcaf7ccab588a3e3a1a9bfdab40d1b3e7d4a69f..39416d9d804f3addcea8a70836da994802028526 100644 --- a/board-item/styles.css.js +++ b/board-item/styles.css.js -@@ -2,15 +2,15 @@ - import './styles.scoped.css'; - export default { - "root": "awsui_root_9ckv7_1974t_1", +@@ -1,16 +1,17 @@ ++import './styles.scoped.css'; + +- import './styles.scoped.css'; +- export default { +- "root": "awsui_root_9ckv7_1974t_1", - "container-override": "awsui_container-override_9ckv7_1974t_6", -+ "container-override": "awsui_container-override_9ckv7_1974t_6 bai_board_container-override", - "active": "awsui_active_9ckv7_1974t_6", +- "active": "awsui_active_9ckv7_1974t_6", - "header": "awsui_header_9ckv7_1974t_28", -+ "header": "awsui_header_9ckv7_1974t_28 bai_board_header", - "flexible": "awsui_flexible_9ckv7_1974t_34", +- "flexible": "awsui_flexible_9ckv7_1974t_34", - "handle": "awsui_handle_9ckv7_1974t_38", -+ "handle": "awsui_handle_9ckv7_1974t_38 bai_board_handle", - "refresh": "awsui_refresh_9ckv7_1974t_41", - "header-content": "awsui_header-content_9ckv7_1974t_45", - "settings": "awsui_settings_9ckv7_1974t_49", - "fixed": "awsui_fixed_9ckv7_1974t_57", +- "refresh": "awsui_refresh_9ckv7_1974t_41", +- "header-content": "awsui_header-content_9ckv7_1974t_45", +- "settings": "awsui_settings_9ckv7_1974t_49", +- "fixed": "awsui_fixed_9ckv7_1974t_57", - "resizer": "awsui_resizer_9ckv7_1974t_61" -+ "resizer": "awsui_resizer_9ckv7_1974t_61 bai_board_resizer", ++export default { ++ root: 'awsui_root_9ckv7_1974t_1', ++ 'container-override': ++ 'awsui_container-override_9ckv7_1974t_6 bai_board_container-override', ++ active: 'awsui_active_9ckv7_1974t_6', ++ header: 'awsui_header_9ckv7_1974t_28 bai_board_header', ++ flexible: 'awsui_flexible_9ckv7_1974t_34', ++ handle: 'awsui_handle_9ckv7_1974t_38 bai_board_handle', ++ refresh: 'awsui_refresh_9ckv7_1974t_41', ++ 'header-content': 'awsui_header-content_9ckv7_1974t_45', ++ settings: 'awsui_settings_9ckv7_1974t_49', ++ fixed: 'awsui_fixed_9ckv7_1974t_57', ++ resizer: 'awsui_resizer_9ckv7_1974t_61 bai_board_resizer', ++ content: 'awsui_content_14iqq_1ml84_220 bai_board_content', }; - +- \ No newline at end of file +diff --git a/board-item/styles.scoped.css b/board-item/styles.scoped.css +index 4ec7adae84985a34199e770b659fc9b8f121c4d4..8ecc2cc3e53e9024e9213bf1e827748f59c443f1 100644 +--- a/board-item/styles.scoped.css ++++ b/board-item/styles.scoped.css +@@ -4,16 +4,24 @@ + + /* TODO: use container API instead of styles override */ + .awsui_container-override_9ckv7_1974t_6.awsui_active_9ckv7_1974t_6:not(#\9) { +- box-shadow: var(--shadow-container-active-kl29x9, 0px 1px 1px 1px #e9ebed, 0px 6px 36px rgba(0, 7, 22, 0.1019607843)); ++ box-shadow: var( ++ --shadow-container-active-kl29x9, ++ 0px 1px 1px 1px #e9ebed, ++ 0px 6px 36px rgba(0, 7, 22, 0.1019607843) ++ ); + } +-[data-awsui-focus-visible] .awsui_container-override_9ckv7_1974t_6.awsui_active_9ckv7_1974t_6:not(#\9) { ++[data-awsui-focus-visible] ++ .awsui_container-override_9ckv7_1974t_6.awsui_active_9ckv7_1974t_6:not(#\9) { + position: relative; + box-sizing: border-box; + outline: 2px dotted transparent; + outline-offset: -1px; + } +-[data-awsui-focus-visible] .awsui_container-override_9ckv7_1974t_6.awsui_active_9ckv7_1974t_6:not(#\9)::before { +- content: " "; ++[data-awsui-focus-visible] ++ .awsui_container-override_9ckv7_1974t_6.awsui_active_9ckv7_1974t_6:not( ++ #\9 ++ )::before { ++ content: ' '; + display: block; + position: absolute; + box-sizing: border-box; +@@ -28,7 +36,11 @@ + .awsui_header_9ckv7_1974t_28:not(#\9) { + display: flex; + justify-items: center; +- padding: var(--space-scaled-s-aqzyko, 12px) calc(var(--space-container-horizontal-wfukh3, 20px) - var(--space-scaled-xs-26e2du, 8px)); ++ padding: var(--space-scaled-s-aqzyko, 12px) ++ calc( ++ var(--space-container-horizontal-wfukh3, 20px) - ++ var(--space-scaled-xs-26e2du, 8px) ++ ); + } + + .awsui_flexible_9ckv7_1974t_34:not(#\9) { +@@ -60,6 +72,14 @@ + + .awsui_resizer_9ckv7_1974t_61:not(#\9) { + position: absolute; +- bottom: calc(var(--space-static-xs-7sfb63, 8px) - var(--space-static-xxxs-3gu9os, 2px)); +- right: calc(var(--space-static-xs-7sfb63, 8px) - var(--space-static-xxxs-3gu9os, 2px)); ++ bottom: calc( ++ var(--space-static-xs-7sfb63, 8px) - var(--space-static-xxxs-3gu9os, 2px) ++ ); ++ right: calc( ++ var(--space-static-xs-7sfb63, 8px) - var(--space-static-xxxs-3gu9os, 2px) ++ ); ++} ++ ++.awsui_content_14iqq_1ml84_220 { ++ padding: 0 !important; + } diff --git a/board-item/styles.selectors.js b/board-item/styles.selectors.js -index 2acfd3b34f880ec39462ec5d44f7f780e041fbec..beebd8d83a48e0326fb8d68e67e2549f1ffcd2b3 100644 +index 2acfd3b34f880ec39462ec5d44f7f780e041fbec..e73f107b533a3e0a68d231ede87e2d59d448fe9d 100644 --- a/board-item/styles.selectors.js +++ b/board-item/styles.selectors.js -@@ -3,15 +3,15 @@ - Object.defineProperty(exports, "__esModule", { value: true }); - module.exports.default = { - "root": "awsui_root_9ckv7_1974t_1", +@@ -1,17 +1,17 @@ +- +- // es-module interop with Babel and Typescript +- Object.defineProperty(exports, "__esModule", { value: true }); +- module.exports.default = { +- "root": "awsui_root_9ckv7_1974t_1", - "container-override": "awsui_container-override_9ckv7_1974t_6", -+ "container-override": "awsui_container-override_9ckv7_1974t_6 bai_board_container-override", - "active": "awsui_active_9ckv7_1974t_6", +- "active": "awsui_active_9ckv7_1974t_6", - "header": "awsui_header_9ckv7_1974t_28", -+ "header": "awsui_header_9ckv7_1974t_28 bai_board_header", - "flexible": "awsui_flexible_9ckv7_1974t_34", +- "flexible": "awsui_flexible_9ckv7_1974t_34", - "handle": "awsui_handle_9ckv7_1974t_38", -+ "handle": "awsui_handle_9ckv7_1974t_38 bai_board_handle", - "refresh": "awsui_refresh_9ckv7_1974t_41", - "header-content": "awsui_header-content_9ckv7_1974t_45", - "settings": "awsui_settings_9ckv7_1974t_49", - "fixed": "awsui_fixed_9ckv7_1974t_57", +- "refresh": "awsui_refresh_9ckv7_1974t_41", +- "header-content": "awsui_header-content_9ckv7_1974t_45", +- "settings": "awsui_settings_9ckv7_1974t_49", +- "fixed": "awsui_fixed_9ckv7_1974t_57", - "resizer": "awsui_resizer_9ckv7_1974t_61" -+ "resizer": "awsui_resizer_9ckv7_1974t_61 bai_board_resizer" ++// es-module interop with Babel and Typescript ++Object.defineProperty(exports, '__esModule', { value: true }); ++module.exports.default = { ++ root: 'awsui_root_9ckv7_1974t_1', ++ 'container-override': ++ 'awsui_container-override_9ckv7_1974t_6 bai_board_container-override', ++ active: 'awsui_active_9ckv7_1974t_6', ++ header: 'awsui_header_9ckv7_1974t_28 bai_board_header', ++ flexible: 'awsui_flexible_9ckv7_1974t_34', ++ handle: 'awsui_handle_9ckv7_1974t_38 bai_board_handle', ++ refresh: 'awsui_refresh_9ckv7_1974t_41', ++ 'header-content': 'awsui_header-content_9ckv7_1974t_45', ++ settings: 'awsui_settings_9ckv7_1974t_49', ++ fixed: 'awsui_fixed_9ckv7_1974t_57', ++ resizer: 'awsui_resizer_9ckv7_1974t_61 bai_board_resizer', ++ content: 'awsui_content_14iqq_1ml84_220 bai_board_content', }; - +- \ No newline at end of file diff --git a/internal/grid/styles.css.js b/internal/grid/styles.css.js index ec202e1a6c757f5513ffa0a2566a1691b8ed18df..0c0ed570ea9c72e7e484c0371825c9710896085c 100644 diff --git a/react/pnpm-lock.yaml b/react/pnpm-lock.yaml index 87bbf718a4..aafdb364cc 100644 --- a/react/pnpm-lock.yaml +++ b/react/pnpm-lock.yaml @@ -6,7 +6,7 @@ settings: patchedDependencies: '@cloudscape-design/board-components@3.0.60': - hash: rsmnk3j6im54fq6gec5lp7suky + hash: sl2ax5liun5nztm65pxt6fd2ku path: patches/@cloudscape-design__board-components@3.0.60.patch importers: @@ -27,13 +27,16 @@ importers: version: 5.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@cloudscape-design/board-components': specifier: 3.0.60 - version: 3.0.60(patch_hash=rsmnk3j6im54fq6gec5lp7suky)(@cloudscape-design/components@3.0.677(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@cloudscape-design/design-tokens@3.0.40)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.0.60(patch_hash=sl2ax5liun5nztm65pxt6fd2ku)(@cloudscape-design/components@3.0.677(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@cloudscape-design/design-tokens@3.0.40)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@codemirror/language': specifier: ^6.10.2 version: 6.10.2 '@melloware/react-logviewer': specifier: ^5.2.4 version: 5.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@react-hook/resize-observer': + specifier: ^2.0.2 + version: 2.0.2(react@18.3.1) '@storybook/test': specifier: ^8.2.8 version: 8.2.8(@types/jest@29.5.12)(jest@27.5.1(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4)))(storybook@8.2.8(@babel/preset-env@7.25.3(@babel/core@7.25.2))) @@ -1971,6 +1974,21 @@ packages: react: '>=16.9.0' react-dom: '>=16.9.0' + '@react-hook/latest@1.0.3': + resolution: {integrity: sha512-dy6duzl+JnAZcDbNTfmaP3xHiKtbXYOaz3G51MGVljh548Y8MWzTr+PHLOfvpypEVW9zwvl+VyKjbWKEVbV1Rg==} + peerDependencies: + react: '>=16.8' + + '@react-hook/passive-layout-effect@1.2.1': + resolution: {integrity: sha512-IwEphTD75liO8g+6taS+4oqz+nnroocNfWVHWz7j+N+ZO2vYrc6PV1q7GQhuahL0IOR7JccFTsFKQ/mb6iZWAg==} + peerDependencies: + react: '>=16.8' + + '@react-hook/resize-observer@2.0.2': + resolution: {integrity: sha512-tzKKzxNpfE5TWmxuv+5Ae3IF58n0FQgQaWJmcbYkjXTRZATXxClnTprQ2uuYygYTpu1pqbBskpwMpj6jpT1djA==} + peerDependencies: + react: '>=18' + '@remix-run/router@1.19.0': resolution: {integrity: sha512-zDICCLKEwbVYTS6TjYaWtHXxkdoUvD/QXvyVZjGCsWz5vyH7aFeONlPffPdW+Y/t6KT0MgXb2Mfjun9YpWN1dA==} engines: {node: '>=14.0.0'} @@ -9770,7 +9788,7 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} - '@cloudscape-design/board-components@3.0.60(patch_hash=rsmnk3j6im54fq6gec5lp7suky)(@cloudscape-design/components@3.0.677(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@cloudscape-design/design-tokens@3.0.40)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@cloudscape-design/board-components@3.0.60(patch_hash=sl2ax5liun5nztm65pxt6fd2ku)(@cloudscape-design/components@3.0.677(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@cloudscape-design/design-tokens@3.0.40)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@cloudscape-design/component-toolkit': 1.0.0-beta.64 '@cloudscape-design/components': 3.0.677(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -10906,6 +10924,20 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + '@react-hook/latest@1.0.3(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@react-hook/passive-layout-effect@1.2.1(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@react-hook/resize-observer@2.0.2(react@18.3.1)': + dependencies: + '@react-hook/latest': 1.0.3(react@18.3.1) + '@react-hook/passive-layout-effect': 1.2.1(react@18.3.1) + react: 18.3.1 + '@remix-run/router@1.19.0': {} '@replit/codemirror-lang-csharp@6.2.0(@codemirror/autocomplete@6.18.0(@codemirror/language@6.10.2)(@codemirror/state@6.4.1)(@codemirror/view@6.30.0)(@lezer/common@1.2.1))(@codemirror/language@6.10.2)(@codemirror/state@6.4.1)(@codemirror/view@6.30.0)(@lezer/common@1.2.1)(@lezer/highlight@1.2.0)(@lezer/lr@1.4.2)': diff --git a/react/src/App.tsx b/react/src/App.tsx index 123b595931..a7d19cf409 100644 --- a/react/src/App.tsx +++ b/react/src/App.tsx @@ -29,7 +29,7 @@ const ServingPage = React.lazy(() => import('./pages/ServingPage')); const EndpointDetailPage = React.lazy( () => import('./pages/EndpointDetailPage'), ); -// const SummaryPage = React.lazy(() => import('./pages/SummaryPage')); +const StartPage = React.lazy(() => import('./pages/StartPage')); const EnvironmentPage = React.lazy(() => import('./pages/EnvironmentPage')); const MyEnvironmentPage = React.lazy(() => import('./pages/MyEnvironmentPage')); const StorageHostSettingPage = React.lazy( @@ -101,18 +101,23 @@ const router = createBrowserRouter([ ), children: [ { - path: '/', - element: , + path: '/start', + element: ( + + + + ), + handle: { labelKey: 'webui.menu.Start' }, }, { //for electron dev mode path: '/build/electron-app/app/index.html', - element: , + element: , }, { //for electron prod mode path: '/app/index.html', - element: , + element: , }, { path: '/summary', @@ -127,7 +132,6 @@ const router = createBrowserRouter([ style={{ marginBottom: token.paddingContentVerticalLG }} closable /> - {/* */} ); }, diff --git a/react/src/components/ActionItemContent.tsx b/react/src/components/ActionItemContent.tsx new file mode 100644 index 0000000000..85cc55003a --- /dev/null +++ b/react/src/components/ActionItemContent.tsx @@ -0,0 +1,122 @@ +import Flex from './Flex'; +import useResizeObserver from '@react-hook/resize-observer'; +import { Button, Divider, Typography, theme } from 'antd'; +import { useRef, useState } from 'react'; + +interface StartItemContentProps { + title: string; + description?: string; + icon?: React.ReactNode; + buttonText: string; + onClick?: () => void; + themeColor?: string; + iconBgColor?: string; + itemRole?: 'user' | 'admin'; +} + +const ActionItemContent: React.FC = ({ + title, + description, + icon, + buttonText, + onClick, + themeColor, + iconBgColor, + itemRole = 'user', +}) => { + const { token } = theme.useToken(); + const [needScroll, setNeedScroll] = useState(false); + const containerRef = useRef(null); + const colorPrimaryWithAlpha = `rgba(${parseInt(token.colorPrimary.slice(1, 3), 16)}, ${parseInt(token.colorPrimary.slice(3, 5), 16)}, ${parseInt(token.colorPrimary.slice(5, 7), 16)}, 0.15)`; + const colorInfoWithAlpha = `rgba(${parseInt(token.colorInfo.slice(1, 3), 16)}, ${parseInt(token.colorInfo.slice(3, 5), 16)}, ${parseInt(token.colorInfo.slice(5, 7), 16)}, 0.15)`; + + useResizeObserver(containerRef, (entry) => { + entry.contentRect.width <= 220 ? setNeedScroll(true) : setNeedScroll(false); + }); + + return ( + + + + {icon} + + + + {title} + + + + {!needScroll && description} + + + + {description && ( + + )} + + + + + + ); +}; + +export default ActionItemContent; diff --git a/react/src/components/BAIBoard.tsx b/react/src/components/BAIBoard.tsx index 4f75ed034d..e0ae218e44 100644 --- a/react/src/components/BAIBoard.tsx +++ b/react/src/components/BAIBoard.tsx @@ -1,7 +1,6 @@ -import Flex from './Flex'; import Board, { BoardProps } from '@cloudscape-design/board-components/board'; import BoardItem from '@cloudscape-design/board-components/board-item'; -import { Skeleton, Typography } from 'antd'; +import { Skeleton } from 'antd'; import { createStyles } from 'antd-style'; import { Suspense } from 'react'; @@ -23,29 +22,31 @@ const useStyles = createStyles(({ css }) => { board: css` ${defaultBoard} `, - disableCustomize: css` - ${defaultBoard} - .bai_board_handle { + disableResize: css` + .bai_board_resizer { display: none !important; } - .bai_board_resizer { + `, + disableMove: css` + .bai_board_handle { display: none !important; } .bai_board_header { - height: var(--token-boardHeaderHeight, 55px) !important; + display: none !important; } `, boardItems: css` & > div:first-child { - border: 1px solid var(--token-colorBorder) !important ; + border: none !important ; border-radius: var(--token-borderRadius) !important ; background-color: var(--token-colorBgContainer) !important ; } & > div:first-child > div:first-child > div:first-child { - border-bottom: 1px solid var(--token-colorBorder) !important; margin-bottom: var(--token-margin); background-color: var(--token-colorBgContainer) !important ; + position: absolute; + z-index: 1; } `, }; @@ -56,19 +57,27 @@ interface BAICustomizableGridProps { onItemsChange: ( event: CustomEvent>, ) => void; - customizable?: boolean; + resizable?: boolean; + movable?: boolean; } const BAIBoard: React.FC = ({ items: parsedItems, - customizable = false, + resizable = false, + movable = false, ...BoardProps }) => { const { styles } = useStyles(); + + const boardStyles = [ + styles.board, + !movable && styles.disableMove, + !resizable && styles.disableResize, + ].join(' '); + return ( { return ( @@ -82,11 +91,6 @@ const BAIBoard: React.FC = ({ resizeHandleAriaLabel: '', resizeHandleAriaDescription: '', }} - header={ - - {item.data.title} - - } > }> {item.data.content} diff --git a/react/src/components/MainLayout/WebUISider.tsx b/react/src/components/MainLayout/WebUISider.tsx index f8e749f10d..a20c668e4a 100644 --- a/react/src/components/MainLayout/WebUISider.tsx +++ b/react/src/components/MainLayout/WebUISider.tsx @@ -24,6 +24,7 @@ import { FileDoneOutlined, HddOutlined, InfoCircleOutlined, + PlayCircleOutlined, SolutionOutlined, ToolOutlined, UserOutlined, @@ -85,6 +86,11 @@ const WebUISider: React.FC = (props) => { const primaryColors = usePrimaryColors(); const generalMenu = filterEmptyItem([ + { + label: {t('webui.menu.Start')}, + icon: , + key: 'start', + }, { label: {t('webui.menu.Summary')}, icon: , @@ -255,7 +261,7 @@ const WebUISider: React.FC = (props) => { height: themeConfig?.logo?.size?.height || 24, cursor: 'pointer', }} - onClick={() => webuiNavigate(themeConfig?.logo?.href || '/summary')} + onClick={() => webuiNavigate(themeConfig?.logo?.href || '/start')} /> } theme={currentSiderTheme} @@ -275,7 +281,7 @@ const WebUISider: React.FC = (props) => { height: themeConfig?.logo.sizeCollapsed?.height ?? 24, cursor: 'pointer', }} - onClick={() => webuiNavigate(themeConfig?.logo?.href || '/summary')} + onClick={() => webuiNavigate(themeConfig?.logo?.href || '/start')} /> } logoTitle={themeConfig?.logo?.logoTitle || siteDescription || 'WebUI'} diff --git a/react/src/components/SummaryPageItems/SummaryItemDownloadApp.tsx b/react/src/components/SummaryPageItems/SummaryItemDownloadApp.tsx deleted file mode 100644 index b2e487d2ce..0000000000 --- a/react/src/components/SummaryPageItems/SummaryItemDownloadApp.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import { useSuspendedBackendaiClient } from '../../hooks'; -import Flex from '../Flex'; -import { Button, Select, Typography, theme } from 'antd'; -import { useState } from 'react'; - -const detectDefaultOS = () => { - if (navigator.userAgent.indexOf('Mac') !== -1) return 'MacOS'; - if (navigator.userAgent.indexOf('Win') !== -1) return 'Windows'; - if (navigator.userAgent.indexOf('Linux') !== -1) return 'Linux'; - return 'MacOS'; -}; - -const SummaryItemDownloadApp: React.FC = () => { - const { token } = theme.useToken(); - const [OS, setOS] = useState(detectDefaultOS()); - - const baiClient = useSuspendedBackendaiClient(); - const url = baiClient._config.appDownloadUrl; - const windowOS = baiClient.supports('use-win-instead-of-win32') - ? 'win' - : 'win32'; - - const appDownloadMap: Record = { - Linux: { - os: 'linux', - architecture: ['arm64', 'x64'], - extension: 'zip', - }, - MacOS: { - os: 'macos', - architecture: ['arm64', 'x64'], - extension: 'dmg', - }, - Windows: { - os: windowOS, - architecture: ['arm64', 'x64'], - extension: 'zip', - }, - }; - const downloadApp = (architecture: string) => { - //@ts-ignore - const pkgVersion = globalThis.packageVersion; - const os = appDownloadMap[OS].os; - const extension = appDownloadMap[OS].extension; - const downloadLink = `${url}/v${pkgVersion}/backend.ai-desktop-${pkgVersion}-${os}-${architecture}.${extension}`; - window.open(downloadLink, '_blank'); - }; - - return ( - -