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/01 17:22:38 UTC

[camel-karavan] 05/06: Merging for #809

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 4ff9f403194d19d01420abfb78009c4415ff2426
Author: Marat Gubaidullin <ma...@gmail.com>
AuthorDate: Sat Jul 1 13:14:38 2023 -0400

    Merging for #809
---
 .../src/main/webui/src/api/ProjectEventBus.ts      |  11 --
 .../src/main/webui/src/api/ProjectService.ts       |  24 +++-
 karavan-app/src/main/webui/src/api/ProjectStore.ts |   6 +-
 .../src/main/webui/src/project/ProjectToolbar.tsx  | 119 +++++++---------
 .../src/main/webui/src/project/RunnerToolbar.tsx   | 152 +++++++++------------
 .../webui/src/project/dashboard/DashboardTab.tsx   |   2 +-
 .../src/project/dashboard/RunnerInfoContext.tsx    |   2 -
 7 files changed, 144 insertions(+), 172 deletions(-)

diff --git a/karavan-app/src/main/webui/src/api/ProjectEventBus.ts b/karavan-app/src/main/webui/src/api/ProjectEventBus.ts
index 142785b8..81e3a944 100644
--- a/karavan-app/src/main/webui/src/api/ProjectEventBus.ts
+++ b/karavan-app/src/main/webui/src/api/ProjectEventBus.ts
@@ -18,10 +18,8 @@ import {BehaviorSubject, Subject} from 'rxjs';
 import {Project} from "./ProjectModels";
 
 const selectedProject = new BehaviorSubject<Project | undefined>(undefined);
-const currentRunner = new BehaviorSubject<string | undefined>(undefined);
 const currentFile = new BehaviorSubject<string | undefined>(undefined);
 const showLog = new BehaviorSubject<ShowLogCommand | undefined>(undefined);
-const showTrace = new BehaviorSubject<ShowTraceCommand | undefined>(undefined);
 const refreshTrace = new BehaviorSubject<boolean>(false);
 const mode = new BehaviorSubject<"design" | "code">("design");
 const config = new BehaviorSubject<any>({});
@@ -55,19 +53,10 @@ export const ProjectEventBus = {
     selectProject: (project: Project) => selectedProject.next(project),
     onSelectProject: () => selectedProject.asObservable(),
 
-    setCurrentRunner: (name: string | undefined) => currentRunner.next(name),
-    onCurrentRunner: () => currentRunner.asObservable(),
-
-    selectProjectFile: (fileName: string) => currentFile.next(fileName),
-    onSelectProjectFile: () => currentFile.asObservable(),
-
     showLog: (type: 'container' | 'pipeline', name: string, environment: string, show: boolean = true) =>
         showLog.next(new ShowLogCommand(type, name, environment, show)),
     onShowLog: () => showLog.asObservable(),
 
-    showTrace: (name: string, show: boolean = true) => showTrace.next(new ShowTraceCommand(name, show)),
-    onShowTrace: () => showTrace.asObservable(),
-
     refreshTrace: (refresh: boolean) => refreshTrace.next(refresh),
     onRefreshTrace: () => refreshTrace.asObservable(),
 
diff --git a/karavan-app/src/main/webui/src/api/ProjectService.ts b/karavan-app/src/main/webui/src/api/ProjectService.ts
index feca6ec3..5f3aeccb 100644
--- a/karavan-app/src/main/webui/src/api/ProjectService.ts
+++ b/karavan-app/src/main/webui/src/api/ProjectService.ts
@@ -1,5 +1,5 @@
 import {KaravanApi} from "./KaravanApi";
-import {DeploymentStatus, Project, ProjectFile} from "./ProjectModels";
+import {DeploymentStatus, PodStatus, Project, ProjectFile} from "./ProjectModels";
 import {TemplateApi} from "karavan-core/lib/api/TemplateApi";
 import {KubernetesAPI} from "../designer/utils/KubernetesAPI";
 import { unstable_batchedUpdates } from 'react-dom'
@@ -14,6 +14,28 @@ import {
 
 export class ProjectService {
 
+    public static runProject(project: Project) {
+        KaravanApi.runProject(project, res => {
+            if (res.status === 200 || res.status === 201) {
+            } else {
+                // Todo notification
+            }
+        });
+    }
+
+    public static getRunnerPodStatus(project: Project) {
+        const projectId = project.projectId;
+        const name = projectId + "-runner";
+        KaravanApi.getRunnerPodStatus(projectId, name, res => {
+            if (res.status === 200) {
+                useProjectStore.setState({podStatus: res.data});
+            } else {
+                useProjectStore.setState({podStatus: new PodStatus()});
+                // Todo notification
+            }
+        });
+    }
+
     public static pushProject (project: Project, commitMessage: string) {
         useProjectStore.setState({isPushing: true})
         const params = {
diff --git a/karavan-app/src/main/webui/src/api/ProjectStore.ts b/karavan-app/src/main/webui/src/api/ProjectStore.ts
index 4edce361..c323ddac 100644
--- a/karavan-app/src/main/webui/src/api/ProjectStore.ts
+++ b/karavan-app/src/main/webui/src/api/ProjectStore.ts
@@ -16,7 +16,7 @@
  */
 
 import {create} from 'zustand'
-import {AppConfig, DeploymentStatus, Project, ProjectFile} from "./ProjectModels";
+import {AppConfig, DeploymentStatus, PodStatus, Project, ProjectFile} from "./ProjectModels";
 
 interface AppConfigState {
     config: AppConfig;
@@ -56,6 +56,8 @@ export const useProjectsStore = create<ProjectsState>((set) => ({
 interface ProjectState {
     project: Project;
     isPushing: boolean,
+    isRunning: boolean,
+    podStatus: PodStatus,
     operation: "create" | "select" | "delete" | "none" | "copy";
     setProject: (project: Project, operation:  "create" | "select" | "delete"| "none" | "copy") => void;
 }
@@ -64,6 +66,8 @@ export const useProjectStore = create<ProjectState>((set) => ({
     project: new Project(),
     operation: "none",
     isPushing: false,
+    isRunning: false,
+    podStatus: new PodStatus(),
     setProject: (p: Project, o: "create" | "select" | "delete"| "none" | "copy") => {
         set((state: ProjectState) => ({
             project: p,
diff --git a/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx b/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx
index 8c27e40c..81368c14 100644
--- a/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx
+++ b/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx
@@ -48,24 +48,26 @@ export const ProjectToolbar = (props: Props) => {
 
     const [commitMessageIsOpen, setCommitMessageIsOpen] = useState(false);
     const [commitMessage, setCommitMessage] = useState('');
-    const [currentRunner, setCurrentRunner] = useState('');
-    const [isJbangRunning, setJbangIsRunning] = useState(false);
-    const [isRunning, setIsRunning] = useState(false);
-    const [isDeletingPod, setIsDeletingPod] = useState(false);
-    const [isReloadingPod, setIsReloadingPod] = useState(false);
+    const [isFile, setIsFile] = useState(false);
+    const [isYaml, setIsYaml] = useState(false);
+    const [isIntegration, setIsIntegration] = useState(false);
+    const [isProperties, setIsProperties] = useState(false);
     const {project, isPushing} = useProjectStore();
     const {files} = useFilesStore();
     const {config} = useAppConfigStore();
 
     useEffect(() => {
-        console.log("ProjectToolbar useEffect", isPushing, project.lastCommitTimestamp)
-        const sub1 = ProjectEventBus.onCurrentRunner()?.subscribe((result) => {
-            setCurrentRunner(result || '');
-            setJbangIsRunning(result === project.name);
-        });
-        return () => {
-            sub1.unsubscribe();
-        };
+        console.log("ProjectToolbar useEffect", isPushing, project.lastCommitTimestamp);
+        const {file, mode, editAdvancedProperties,
+            setEditAdvancedProperties, setUploadModalOpen} = props;
+        const isFile = file !== undefined;
+        const isYaml = file !== undefined && file.name.endsWith("yaml");
+        const isIntegration = isYaml && file?.code !== undefined && CamelDefinitionYaml.yamlIsIntegration(file.code);
+        const isProperties = file !== undefined && file.name.endsWith("properties");
+        setIsFile(isFile);
+        setIsYaml(isYaml);
+        setIsIntegration(isIntegration);
+        setIsProperties(isProperties);
     });
 
     function podName() {
@@ -90,46 +92,6 @@ export const ProjectToolbar = (props: Props) => {
         // }
     }
 
-    function jbangRun() {
-        setJbangIsRunning(true);
-        KaravanApi.runProject(project, res => {
-            if (res.status === 200 || res.status === 201) {
-                ProjectEventBus.setCurrentRunner(project.name);
-                setJbangIsRunning(false);
-                ProjectEventBus.showLog('container', res.data, config.environment)
-            } else {
-                // Todo notification
-                setJbangIsRunning(false);
-                ProjectEventBus.setCurrentRunner(undefined);
-            }
-        });
-    }
-
-    function reloadRunner() {
-        setIsReloadingPod(true);
-        KaravanApi.getRunnerReload(project.projectId, res => {
-            if (res.status === 200 || res.status === 201) {
-                setIsReloadingPod(false);
-            } else {
-                // Todo notification
-                setIsReloadingPod(false);
-            }
-        });
-    }
-
-    function deleteRunner() {
-        ProjectEventBus.setCurrentRunner(undefined);
-        setIsDeletingPod(true);
-        KaravanApi.deleteRunner(podName(), false, res => {
-            if (res.status === 202) {
-                setIsDeletingPod(false);
-            } else {
-                // Todo notification
-                setIsDeletingPod(false);
-            }
-        });
-    }
-
     function push () {
         setCommitMessageIsOpen(false);
         ProjectService.pushProject(project, commitMessage);
@@ -168,8 +130,6 @@ export const ProjectToolbar = (props: Props) => {
 
     function getTemplatesToolbar() {
         const {file, editAdvancedProperties, setUploadModalOpen} = props;
-        const isFile = file !== undefined;
-        const isProperties = file !== undefined && file.name.endsWith("properties");
         return <Toolbar id="toolbar-group-types">
             <ToolbarContent>
                 <ToolbarItem>
@@ -212,13 +172,9 @@ export const ProjectToolbar = (props: Props) => {
         </Toolbar>
     }
 
-    function getProjectToolbar() {
+    function getFileToolbar() {
         const {file, mode, editAdvancedProperties,
-             setEditAdvancedProperties, setUploadModalOpen} = props;
-        const isFile = file !== undefined;
-        const isYaml = file !== undefined && file.name.endsWith("yaml");
-        const isIntegration = isYaml && file?.code && CamelDefinitionYaml.yamlIsIntegration(file.code);
-        const isProperties = file !== undefined && file.name.endsWith("properties");
+            setEditAdvancedProperties, setUploadModalOpen} = props;
         return <Toolbar id="toolbar-group-types">
             <ToolbarContent>
                 <Flex className="toolbar" direction={{default: "row"}} alignItems={{default: "alignItemsCenter"}}>
@@ -267,14 +223,40 @@ export const ProjectToolbar = (props: Props) => {
                             <Button isSmall variant="control" icon={<DownloadImageIcon/>} onClick={e => downloadImage()}/>
                         </Tooltip>
                     </FlexItem>}
-                    {isYaml && currentRunner === project.name && <FlexItem>
-                        <RunnerToolbar project={project} showConsole={false} reloadOnly={true} />
-                    </FlexItem>}
+                    {/*{isYaml && currentRunner === project.name && <FlexItem>*/}
+                    {/*    <RunnerToolbar project={project} showConsole={false} reloadOnly={true} />*/}
+                    {/*</FlexItem>}*/}
                 </Flex>
             </ToolbarContent>
         </Toolbar>
     }
 
+    function getProjectToolbar() {
+        return (<Toolbar id="toolbar-group-types">
+            <ToolbarContent>
+                <Flex className="toolbar" direction={{default: "row"}} alignItems={{default: "alignItemsCenter"}}>
+                    <FlexItem>{getLastUpdatePanel()}</FlexItem>
+                    <FlexItem>
+                        <Tooltip content="Commit and push to git" position={"bottom-end"}>
+                            <Button isLoading={isPushing ? true : undefined}
+                                    isSmall
+                                    variant={needCommit() ? "primary" : "secondary"}
+                                    className="project-button"
+                                    icon={!isPushing ? <PushIcon/> : <div></div>}
+                                    onClick={() => {
+                                        setCommitMessage(commitMessage === '' ? new Date().toLocaleString() : commitMessage);
+                                        setCommitMessageIsOpen(true);
+                                    }}>
+                                {isPushing ? "..." : "Push"}
+                            </Button>
+                        </Tooltip>
+                    </FlexItem>
+                    {isRunnable() && <RunnerToolbar/>}
+                </Flex>
+            </ToolbarContent>
+        </Toolbar>)
+    }
+
     function getCommitModal() {
         return (
             <Modal
@@ -305,11 +287,16 @@ export const ProjectToolbar = (props: Props) => {
         return project.projectId === 'templates';
     }
 
+    function isRunnable(): boolean {
+        return !isKameletsProject() && !isTemplatesProject();
+    }
+
     const isTemplates = isTemplatesProject();
     return  (
          <>
-            {isTemplates && getTemplatesToolbar()}
-            {!isTemplates && getProjectToolbar()}
+            {/*{isTemplates && getTemplatesToolbar()}*/}
+            {/*{!isTemplates && getProjectToolbar()}*/}
+             {!isFile && getProjectToolbar()}
              {getCommitModal()}
         </>
     )
diff --git a/karavan-app/src/main/webui/src/project/RunnerToolbar.tsx b/karavan-app/src/main/webui/src/project/RunnerToolbar.tsx
index e309a531..8fc52840 100644
--- a/karavan-app/src/main/webui/src/project/RunnerToolbar.tsx
+++ b/karavan-app/src/main/webui/src/project/RunnerToolbar.tsx
@@ -1,6 +1,6 @@
 import React, {useEffect, useState} from 'react';
 import {
-    Button,
+    Button, FlexItem,
     Tooltip,
     TooltipPosition
 } from '@patternfly/react-core';
@@ -9,54 +9,44 @@ import RocketIcon from "@patternfly/react-icons/dist/esm/icons/rocket-icon";
 import ReloadIcon from "@patternfly/react-icons/dist/esm/icons/bolt-icon";
 import DeleteIcon from "@patternfly/react-icons/dist/esm/icons/times-circle-icon";
 import {KaravanApi} from "../api/KaravanApi";
-import {Project} from "../api/ProjectModels";
-import {ProjectEventBus} from "../api/ProjectEventBus";
-import {useAppConfigStore} from "../api/ProjectStore";
+import {useAppConfigStore, useProjectStore} from "../api/ProjectStore";
+import {ProjectService} from "../api/ProjectService";
 
 
-interface Props {
-    project: Project,
-    showConsole: boolean,
-    reloadOnly: boolean
-}
-
-export const RunnerToolbar = (props: Props) => {
+export const RunnerToolbar = () => {
 
-    const [podName, setPodName] = useState(props.project.projectId + '-runner');
-    const [isJbangRunning, setJbangIsRunning] = useState(false);
-    const [isRunning, setIsRunning] = useState(false);
+    const [isStartingPod, setIsStartingPod] = useState(false);
     const [isDeletingPod, setIsDeletingPod] = useState(false);
     const [isReloadingPod, setIsReloadingPod] = useState(false);
     const {config} = useAppConfigStore();
+    const {project, podStatus} = useProjectStore();
+
+    function isRunning() {
+        return podStatus.started;
+    }
 
     useEffect(() => {
-        const sub1 = ProjectEventBus.onCurrentRunner()?.subscribe((result) => {
-            setJbangIsRunning(result === props.project.name);
-        });
+        console.log("Runner toolbar", podStatus);
+        const interval = setInterval(() => {
+            if (isRunning()) {
+                ProjectService.getRunnerPodStatus(project);
+                if (isStartingPod) setIsStartingPod(false);
+            }
+        }, 1000);
         return () => {
-            sub1.unsubscribe();
+            clearInterval(interval)
         };
-    });
+
+    }, []);
 
     function jbangRun() {
-        setJbangIsRunning(true);
-        KaravanApi.runProject(props.project, res => {
-            if (res.status === 200 || res.status === 201) {
-                ProjectEventBus.setCurrentRunner(props.project.name);
-                setJbangIsRunning(false);
-                setPodName(res.data);
-                ProjectEventBus.showLog('container', res.data, config.environment)
-            } else {
-                // Todo notification
-                setJbangIsRunning(false);
-                ProjectEventBus.setCurrentRunner(undefined);
-            }
-        });
+        setIsStartingPod(true);
+        ProjectService.runProject(project);
     }
 
     function reloadRunner() {
         setIsReloadingPod(true);
-        KaravanApi.getRunnerReload(props.project.projectId, res => {
+        KaravanApi.getRunnerReload(project.projectId, res => {
             if (res.status === 200 || res.status === 201) {
                 setIsReloadingPod(false);
             } else {
@@ -67,9 +57,8 @@ export const RunnerToolbar = (props: Props) => {
     }
 
     function deleteRunner() {
-        ProjectEventBus.setCurrentRunner(undefined);
         setIsDeletingPod(true);
-        KaravanApi.deleteRunner(podName, false, res => {
+        KaravanApi.deleteRunner(project.projectId + "-runner", false, res => {
             if (res.status === 202) {
                 setIsDeletingPod(false);
             } else {
@@ -79,59 +68,42 @@ export const RunnerToolbar = (props: Props) => {
         });
     }
 
-    return (
-            <div className="runner-toolbar">
-                {!props.showConsole && !props.reloadOnly  &&
-                    <div className="row">
-                        <Tooltip content="Run in development mode" position={TooltipPosition.left}>
-                            <Button isLoading={isJbangRunning ? true : undefined}
-                                    isSmall
-                                    variant={"primary"}
-                                    className="project-button"
-                                    icon={!isJbangRunning ? <RocketIcon/> : <div></div>}
-                                    onClick={() => jbangRun()}>
-                                {isJbangRunning ? "..." : "Run"}
-                            </Button>
-                        </Tooltip>
-                    </div>}
-                {props.reloadOnly &&
-                    <div className="row">
-                        <Tooltip content="Reload" position={TooltipPosition.left}>
-                            <Button isLoading={isReloadingPod ? true : undefined}
-                                    isSmall
-                                    variant={"primary"}
-                                    className="project-button"
-                                    icon={!isReloadingPod ? <ReloadIcon/> : <div></div>}
-                                    onClick={() => reloadRunner()}>
-                                {isReloadingPod ? "..." : "Reload"}
-                            </Button>
-                        </Tooltip>
-                    </div>
-                }
-                {props.showConsole && <>
-                    <div className="row">
-                        <Tooltip content="Reload" position={TooltipPosition.left}>
-                            <Button isLoading={isReloadingPod ? true : undefined}
-                                    isSmall
-                                    variant={"primary"}
-                                    className="project-button"
-                                    icon={!isReloadingPod ? <ReloadIcon/> : <div></div>}
-                                    onClick={() => reloadRunner()}>
-                                {isReloadingPod ? "..." : "Reload"}
-                            </Button>
-                        </Tooltip>
-                    </div>
-                    <Tooltip content="Stop runner" position={TooltipPosition.left}>
-                        <Button isLoading={isDeletingPod ? true : undefined}
-                                isSmall
-                                variant={"secondary"}
-                                className="project-button"
-                                icon={!isRunning ? <DeleteIcon/> : <div></div>}
-                                onClick={() => deleteRunner()}>
-                            {isDeletingPod ? "..." : "Stop"}
-                        </Button>
-                    </Tooltip>
-                </>}
-            </div>
-    );
+    return (<>
+        {!isRunning() && <FlexItem>
+            <Tooltip content="Run in development mode" position={TooltipPosition.bottomEnd}>
+                <Button isLoading={isStartingPod ? true : undefined}
+                        isSmall
+                        variant={"primary"}
+                        className="project-button"
+                        icon={!isStartingPod ? <RocketIcon/> : <div></div>}
+                        onClick={() => jbangRun()}>
+                    {isStartingPod ? "..." : "Run"}
+                </Button>
+            </Tooltip>
+        </FlexItem>}
+        {isRunning() && <FlexItem>
+            <Tooltip content="Reload" position={TooltipPosition.bottomEnd}>
+                <Button isLoading={isReloadingPod ? true : undefined}
+                        isSmall
+                        variant={"primary"}
+                        className="project-button"
+                        icon={!isReloadingPod ? <ReloadIcon/> : <div></div>}
+                        onClick={() => reloadRunner()}>
+                    {isReloadingPod ? "..." : "Reload"}
+                </Button>
+            </Tooltip>
+        </FlexItem>}
+        {isRunning() && <FlexItem>
+        <Tooltip content="Stop runner" position={TooltipPosition.bottomEnd}>
+            <Button isLoading={isDeletingPod ? true : undefined}
+                    isSmall
+                    variant={"secondary"}
+                    className="project-button"
+                    icon={!isRunning ? <DeleteIcon/> : <div></div>}
+                    onClick={() => deleteRunner()}>
+                {isDeletingPod ? "..." : "Stop"}
+            </Button>
+        </Tooltip>
+        </FlexItem>}
+    </>);
 }
diff --git a/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx b/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx
index 6f919cad..07bb5541 100644
--- a/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx
+++ b/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx
@@ -18,7 +18,7 @@ export function isRunning(status: PodStatus): boolean {
 
 export const DashboardTab = () => {
 
-    const {project, setProject} = useProjectStore();
+    const {project} = useProjectStore();
     const [podStatus, setPodStatus] = useState(new PodStatus());
     const previousValue = useRef(new PodStatus());
     const [memory, setMemory] = useState({});
diff --git a/karavan-app/src/main/webui/src/project/dashboard/RunnerInfoContext.tsx b/karavan-app/src/main/webui/src/project/dashboard/RunnerInfoContext.tsx
index 7683be64..c07cf810 100644
--- a/karavan-app/src/main/webui/src/project/dashboard/RunnerInfoContext.tsx
+++ b/karavan-app/src/main/webui/src/project/dashboard/RunnerInfoContext.tsx
@@ -19,8 +19,6 @@ interface Props {
 
 export const RunnerInfoContext = (props: Props) => {
 
-
-
     function getContextInfo() {
         return (
             <LabelGroup numLabels={3}>