You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ma...@apache.org on 2023/07/23 18:52:15 UTC

[camel-karavan] 01/03: Main.tsx as functional #817

This is an automated email from the ASF dual-hosted git repository.

marat pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git

commit f73201e13fa023395e6db83e06baf610432cf54a
Author: Marat Gubaidullin <ma...@gmail.com>
AuthorDate: Sun Jul 23 13:32:51 2023 -0400

    Main.tsx as functional #817
---
 .../karavan-app/src/main/webui/src/Main.tsx        | 162 +++++++++------------
 1 file changed, 71 insertions(+), 91 deletions(-)

diff --git a/karavan-web/karavan-app/src/main/webui/src/Main.tsx b/karavan-web/karavan-app/src/main/webui/src/Main.tsx
index a9f46911..11bf54f0 100644
--- a/karavan-web/karavan-app/src/main/webui/src/Main.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/Main.tsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, {useEffect, useState} from 'react';
 import {
     Page,
     Button,
@@ -18,13 +18,12 @@ import {ProjectsPage} from "./projects/ProjectsPage";
 import UserIcon from "@patternfly/react-icons/dist/js/icons/user-icon";
 import ProjectsIcon from "@patternfly/react-icons/dist/js/icons/repository-icon";
 import KnowledgebaseIcon from "@patternfly/react-icons/dist/js/icons/book-open-icon";
-import ServicesIcon from "@patternfly/react-icons/dist/js/icons/registry-icon";
+import ContainersIcon from "@patternfly/react-icons/dist/js/icons/cubes-icon";
 import DashboardIcon from "@patternfly/react-icons/dist/js/icons/tachometer-alt-icon";
-import EipIcon from "@patternfly/react-icons/dist/js/icons/topology-icon";
+import ServicesIcon from "@patternfly/react-icons/dist/js/icons/services-icon";
 import ComponentsIcon from "@patternfly/react-icons/dist/js/icons/module-icon";
 import {MainLogin} from "./MainLogin";
 import {DashboardPage} from "./dashboard/DashboardPage";
-import {Subscription} from "rxjs";
 import {ProjectEventBus} from "./api/ProjectEventBus";
 import {AppConfig, ContainerStatus, Project, ToastMessage} from "./api/ProjectModels";
 import {ProjectPage} from "./project/ProjectPage";
@@ -33,6 +32,7 @@ import {Notification} from "./Notification";
 import {InfrastructureAPI} from "./designer/utils/InfrastructureAPI";
 import {KnowledgebasePage} from "./knowledgebase/KnowledgebasePage";
 import {ServicesPage} from "./services/ServicesPage";
+import {shallow} from "zustand/shallow";
 
 class MenuItem {
     pageId: string = '';
@@ -46,38 +46,21 @@ class MenuItem {
     }
 }
 
-interface Props {
-}
-
-interface State {
-    config: any,
-    pageId: string,
-    isModalOpen: boolean,
-    openapi: string,
-    request: string,
-    filename: string,
-    key: string,
-    showUser?: boolean,
-}
-
-export class Main extends React.Component<Props, State> {
-
-    public state: State = {
-        config: {},
-        pageId: "projects",
-        isModalOpen: false,
-        request: uuidv4(),
-        openapi: '',
-        filename: '',
-        key: '',
-    };
-
-    designer = React.createRef();
-    sub?: Subscription;
-
-    componentDidMount() {
-        this.sub = ProjectEventBus.onSelectProject()?.subscribe((project: Project | undefined) => {
-            if (project) this.setState({pageId: "project"});
+export const Main = () => {
+
+    const [config, setConfig] = useAppConfigStore((state) => [state.config, state.setConfig], shallow)
+    const [pageId, setPageId] = useState<string>('projects');
+    const [openapi, setOpenapi] = useState<string>('');
+    const [filename, setFileName] = useState<string>('');
+    const [key, setKey] = useState<string>('');
+    const [request, setRequest] = useState<string>(uuidv4());
+    const [isModalOpen, setIsModelOpen] = useState<boolean>(false);
+    const [showUser, setShowUser] = useState<boolean>(false);
+
+    useEffect(() => {
+        console.log("Main Start");
+        const sub = ProjectEventBus.onSelectProject()?.subscribe((project: Project | undefined) => {
+            if (project) setPageId("project");
         });
         KaravanApi.getAuthType((authType: string) => {
             console.log("authType", authType);
@@ -85,44 +68,45 @@ export class Main extends React.Component<Props, State> {
                 SsoApi.auth(() => {
                     KaravanApi.getMe((user: any) => {
                         console.log("me", user);
-                        this.getData();
+                        getData();
                     });
                 });
             } else {
-                this.setState({key: Math.random().toString()})
+                setKey(Math.random().toString())
             }
             if (KaravanApi.isAuthorized || KaravanApi.authType === 'public') {
-                this.getData();
+                getData();
             }
         });
-    }
-
-    componentWillUnmount() {
-        this.sub?.unsubscribe();
-    }
+        return () => {
+            console.log("Main End");
+            sub?.unsubscribe();
+        };
+    }, []);
 
-    onLogin = (username: string, password: string) => {
+    function onLogin(username: string, password: string) {
         KaravanApi.auth(username, password, (res: any) => {
             if (res?.status === 200) {
-                this.getData();
+                getData();
             } else {
-                this.toast("Error", "Incorrect username and/or password!", "danger");
+                toast("Error", "Incorrect username and/or password!", "danger");
             }
         });
     }
 
-    getData() {
+    function getData() {
         KaravanApi.getConfiguration((config: AppConfig) => {
-            this.setState({config: config, request: uuidv4()});
+            setRequest(uuidv4());
+            setConfig(config);
             useAppConfigStore.setState({config: config});
             InfrastructureAPI.infrastructure = config.infrastructure;
         });
-        this.updateKamelets();
-        this.updateComponents();
-        // this.updateSupportedComponents(); // not implemented yet
+        updateKamelets();
+        updateComponents();
+        // updateSupportedComponents(); // not implemented yet
     }
 
-    updateKamelets: () => Promise<void> = async () => {
+    async function updateKamelets(): Promise<void> {
         await new Promise(resolve => {
             KaravanApi.getKamelets(yamls => {
                 const kamelets: string[] = [];
@@ -135,7 +119,7 @@ export class Main extends React.Component<Props, State> {
         });
     }
 
-    updateComponents: () => Promise<void> = async () => {
+    async function updateComponents(): Promise<void> {
         await new Promise(resolve => {
             KaravanApi.getComponents(code => {
                 const components: [] = JSON.parse(code);
@@ -146,7 +130,7 @@ export class Main extends React.Component<Props, State> {
         });
     }
 
-    updateSupportedComponents: () => Promise<void> = async () => {
+    async function updateSupportedComponents(): Promise<void> {
         await new Promise(resolve => {
             KaravanApi.getSupportedComponents(jsons => {
                 ComponentApi.saveSupportedComponents(jsons);
@@ -154,33 +138,33 @@ export class Main extends React.Component<Props, State> {
         });
     }
 
-    pageNav = () => {
+    function pageNav() {
         const pages: MenuItem[] = [
             new MenuItem("dashboard", "Dashboard", <DashboardIcon/>),
             new MenuItem("projects", "Projects", <ProjectsIcon/>),
             new MenuItem("services", "Services", <ServicesIcon/>),
+            new MenuItem("containers", "Containers", <ContainersIcon/>),
             new MenuItem("knowledgebase", "Knowledgebase", <KnowledgebaseIcon/>),
-            // new MenuItem("eip", "Enterprise Integration Patterns", <EipIcon/>),
             // new MenuItem("components", "Components", <ComponentsIcon/>)
         ]
         return (<Flex className="nav-buttons" direction={{default: "column"}} style={{height: "100%"}}
                       spaceItems={{default: "spaceItemsNone"}}>
             <FlexItem alignSelf={{default: "alignSelfCenter"}}>
-                <Tooltip className="logo-tooltip" content={"Apache Camel Karavan " + this.state.config.version}
+                <Tooltip className="logo-tooltip" content={"Apache Camel Karavan " + config.version}
                          position={"right"}>
                     {Icon()}
                 </Tooltip>
             </FlexItem>
             {pages.map(page =>
-                <FlexItem key={page.pageId} className={this.state.pageId === page.pageId ? "nav-button-selected" : ""}>
+                <FlexItem key={page.pageId} className={pageId === page.pageId ? "nav-button-selected" : ""}>
                     <Tooltip content={page.tooltip} position={"right"}>
                         <Button id={page.pageId} icon={page.icon} variant={"plain"}
-                                className={this.state.pageId === page.pageId ? "nav-button-selected" : ""}
+                                className={pageId === page.pageId ? "nav-button-selected" : ""}
                                 onClick={event => {
-                                    useFileStore.setState({operation:'none', file: undefined})
+                                    useFileStore.setState({operation: 'none', file: undefined})
                                     useDevModeStore.setState({podName: undefined, status: "none"})
-                                    useProjectStore.setState({containerStatus: new ContainerStatus({}), })
-                                    this.setState({pageId: page.pageId});
+                                    useProjectStore.setState({containerStatus: new ContainerStatus({}),})
+                                    setPageId(page.pageId);
                                 }}
                         />
                     </Tooltip>
@@ -195,9 +179,9 @@ export class Main extends React.Component<Props, State> {
                         aria-label="Current user"
                         position={"right-end"}
                         hideOnOutsideClick={false}
-                        isVisible={this.state.showUser === true}
-                        shouldClose={tip => this.setState({showUser: false})}
-                        shouldOpen={tip => this.setState({showUser: true})}
+                        isVisible={showUser}
+                        shouldClose={tip => setShowUser(false)}
+                        shouldOpen={tip => setShowUser(true)}
                         headerContent={<div>{KaravanApi.me.userName}</div>}
                         bodyContent={
                             <Flex direction={{default: "row"}}>
@@ -214,45 +198,41 @@ export class Main extends React.Component<Props, State> {
         </Flex>)
     }
 
-    toast = (title: string, text: string, variant: 'success' | 'danger' | 'warning' | 'info' | 'default') => {
+    function toast(title: string, text: string, variant: 'success' | 'danger' | 'warning' | 'info' | 'default') {
         ProjectEventBus.sendAlert(new ToastMessage(title, text, variant))
     }
 
-    getMain() {
+    function getMain() {
         return (
             <>
                 <Flex direction={{default: "row"}} style={{width: "100%", height: "100%"}}
                       alignItems={{default: "alignItemsStretch"}} spaceItems={{default: 'spaceItemsNone'}}>
                     <FlexItem>
-                        {this.pageNav()}
+                        {pageNav()}
                     </FlexItem>
                     <FlexItem flex={{default: "flex_2"}} style={{height: "100%"}}>
-                        {this.state.pageId === 'dashboard' && <DashboardPage key={this.state.request}
-                                                                             toast={this.toast}
-                                                                             config={this.state.config}/>}
-                        {this.state.pageId === 'projects' && <ProjectsPage key={this.state.request}/>}
-                        {this.state.pageId === 'project' && <ProjectPage key="projects"/>}
-                        {this.state.pageId === 'services' && <ServicesPage key="services"/>}
-                        {this.state.pageId === 'knowledgebase' && <KnowledgebasePage dark={false}/>}
+                        {pageId === 'dashboard' && <DashboardPage key={request} toast={toast} config={config}/>}
+                        {pageId === 'projects' && <ProjectsPage key={request}/>}
+                        {pageId === 'project' && <ProjectPage key="projects"/>}
+                        {pageId === 'services' && <ServicesPage key="services"/>}
+                        {pageId === 'knowledgebase' && <KnowledgebasePage dark={false}/>}
                     </FlexItem>
                 </Flex>
             </>
         )
     }
 
-    render() {
-        return (
-            <Page className="karavan">
-                {KaravanApi.authType === undefined &&
-                    <Bullseye className="loading-page">
-                        <Spinner className="spinner" isSVG diameter="140px" aria-label="Loading..."/>
-                        <div className="logo-placeholder">{Icon()}</div>
-                    </Bullseye>}
-                {(KaravanApi.isAuthorized || KaravanApi.authType === 'public') && this.getMain()}
-                {!KaravanApi.isAuthorized && KaravanApi.authType === 'basic' &&
-                    <MainLogin config={this.state.config} onLogin={this.onLogin}/>}
-                <Notification/>
-            </Page>
-        )
-    }
+    return (
+        <Page className="karavan">
+            {KaravanApi.authType === undefined &&
+                <Bullseye className="loading-page">
+                    <Spinner className="spinner" isSVG diameter="140px" aria-label="Loading..."/>
+                    <div className="logo-placeholder">{Icon()}</div>
+                </Bullseye>}
+            {(KaravanApi.isAuthorized || KaravanApi.authType === 'public') && getMain()}
+            {!KaravanApi.isAuthorized && KaravanApi.authType === 'basic' &&
+                <MainLogin config={config} onLogin={onLogin}/>}
+            <Notification/>
+        </Page>
+    )
 }
\ No newline at end of file