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 <marat.gubaidul...@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}>