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/27 22:22:48 UTC
[camel-karavan] 03/03: devservices logs #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 17084c371fd0d0523463f6b69e88b0a218134942
Author: Marat Gubaidullin <ma...@gmail.com>
AuthorDate: Thu Jul 27 18:22:36 2023 -0400
devservices logs #817
---
.../karavan-app/src/main/webui/src/Main.tsx | 41 +++++++++++-------
.../src/main/webui/src/api/ProjectService.ts | 50 +++++++++++-----------
.../src/main/webui/src/api/ProjectStore.ts | 8 ----
.../main/webui/src/containers/ContainersPage.tsx | 29 ++-----------
.../karavan-app/src/main/webui/src/index.css | 16 +++----
.../src/main/webui/src/project/DevModeToolbar.tsx | 19 ++++----
.../src/main/webui/src/project/ProjectPage.tsx | 19 ++++----
.../webui/src/project/dashboard/DashboardTab.tsx | 19 ++++----
.../main/webui/src/project/log/ProjectLogPanel.tsx | 14 +++---
.../webui/src/project/pipeline/ProjectStatus.tsx | 5 +--
.../src/main/webui/src/services/ServicesPage.tsx | 23 +++-------
.../main/webui/src/services/ServicesTableRow.tsx | 21 +++++++--
12 files changed, 125 insertions(+), 139 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 8adfe79d..98ca08f1 100644
--- a/karavan-web/karavan-app/src/main/webui/src/Main.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/Main.tsx
@@ -28,12 +28,13 @@ import {ContainersPage} from "./containers/ContainersPage";
import {ProjectEventBus} from "./api/ProjectEventBus";
import {AppConfig, ContainerStatus, Project, ToastMessage} from "./api/ProjectModels";
import {ProjectPage} from "./project/ProjectPage";
-import {useAppConfigStore, useDevModeStore, useFileStore, useProjectStore} from "./api/ProjectStore";
+import {useAppConfigStore, useDevModeStore, useFileStore, useProjectStore, useStatusesStore} from "./api/ProjectStore";
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";
+import {ProjectService} from "./api/ProjectService";
class MenuItem {
pageId: string = '';
@@ -50,12 +51,16 @@ class MenuItem {
export const Main = () => {
const [config, setConfig] = useAppConfigStore((state) => [state.config, state.setConfig], shallow)
+ const [setContainers] = useStatusesStore((state) => [state.setContainers], shallow);
const [pageId, setPageId] = useState<string>('projects');
const [request, setRequest] = useState<string>(uuidv4());
const [showUser, setShowUser] = useState<boolean>(false);
useEffect(() => {
console.log("Main Start");
+ const interval = setInterval(() => {
+ getStatuses();
+ }, 1000);
const sub = ProjectEventBus.onSelectProject()?.subscribe((project: Project | undefined) => {
if (project) setPageId("project");
});
@@ -64,17 +69,15 @@ export const Main = () => {
if (authType === 'oidc') {
SsoApi.auth(() => {
KaravanApi.getMe((user: any) => {
- console.log("me", user);
getData();
});
});
}
- if (KaravanApi.isAuthorized || KaravanApi.authType === 'public') {
- getData();
- }
+ getData();
});
return () => {
console.log("Main End");
+ clearInterval(interval);
sub?.unsubscribe();
};
}, []);
@@ -88,17 +91,26 @@ export const Main = () => {
}
});
}
+ function getStatuses() {
+ if (KaravanApi.isAuthorized || KaravanApi.authType === 'public') {
+ KaravanApi.getAllContainerStatuses((statuses: ContainerStatus[]) => {
+ setContainers(statuses);
+ });
+ }
+ }
function getData() {
- KaravanApi.getConfiguration((config: AppConfig) => {
- setRequest(uuidv4());
- setConfig(config);
- useAppConfigStore.setState({config: config});
- InfrastructureAPI.infrastructure = config.infrastructure;
- });
- updateKamelets();
- updateComponents();
- // updateSupportedComponents(); // not implemented yet
+ if (KaravanApi.isAuthorized || KaravanApi.authType === 'public') {
+ KaravanApi.getConfiguration((config: AppConfig) => {
+ setRequest(uuidv4());
+ setConfig(config);
+ useAppConfigStore.setState({config: config});
+ InfrastructureAPI.infrastructure = config.infrastructure;
+ });
+ updateKamelets();
+ updateComponents();
+ // updateSupportedComponents(); // not implemented yet
+ }
}
async function updateKamelets(): Promise<void> {
@@ -165,7 +177,6 @@ export const Main = () => {
onClick={event => {
useFileStore.setState({operation: 'none', file: undefined})
useDevModeStore.setState({podName: undefined, status: "none"})
- useProjectStore.setState({containerStatus: new ContainerStatus({}),})
setPageId(page.pageId);
}}
/>
diff --git a/karavan-web/karavan-app/src/main/webui/src/api/ProjectService.ts b/karavan-web/karavan-app/src/main/webui/src/api/ProjectService.ts
index cdfada6f..14f42cbb 100644
--- a/karavan-web/karavan-app/src/main/webui/src/api/ProjectService.ts
+++ b/karavan-web/karavan-app/src/main/webui/src/api/ProjectService.ts
@@ -45,7 +45,7 @@ export class ProjectService {
KaravanApi.manageContainer('dev', 'devmove', project.projectId, 'stop', res => {
useDevModeStore.setState({status: 'none'})
if (res.status === 200) {
- useLogStore.setState({showLog: false, type: 'container', isRunning: false})
+ useLogStore.setState({showLog: false, type: 'container'})
} else {
ProjectEventBus.sendAlert(new ToastMessage('Error stopping DevMode container', res.statusText, 'warning'))
}
@@ -57,7 +57,7 @@ export class ProjectService {
KaravanApi.manageContainer('dev', 'devmove', project.projectId, 'pause', res => {
useDevModeStore.setState({status: 'none'})
if (res.status === 200) {
- useLogStore.setState({showLog: false, type: 'container', isRunning: false})
+ useLogStore.setState({showLog: false, type: 'container'})
} else {
ProjectEventBus.sendAlert(new ToastMessage('Error stopping DevMode container', res.statusText, 'warning'))
}
@@ -70,35 +70,35 @@ export class ProjectService {
KaravanApi.deleteDevModeContainer(project.projectId, false, res => {
useDevModeStore.setState({status: 'none'})
if (res.status === 202) {
- useLogStore.setState({showLog: false, type: 'container', isRunning: false})
+ useLogStore.setState({showLog: false, type: 'container'})
} else {
ProjectEventBus.sendAlert(new ToastMessage('Error delete runner', res.statusText, 'warning'))
}
});
}
- public static getDevModeStatus(project: Project) {
- const projectId = project.projectId;
- KaravanApi.getDevModePodStatus(projectId, res => {
- if (res.status === 200) {
- unstable_batchedUpdates(() => {
- const containerStatus = res.data;
- if (useDevModeStore.getState().podName !== containerStatus.containerName){
- useDevModeStore.setState({podName: containerStatus.containerName})
- }
- if (useDevModeStore.getState().status !== 'wip'){
- useLogStore.setState({isRunning: true})
- }
- useProjectStore.setState({containerStatus: containerStatus});
- })
- } else {
- unstable_batchedUpdates(() => {
- useDevModeStore.setState({status: 'none', podName: undefined})
- useProjectStore.setState({containerStatus: new ContainerStatus({})});
- })
- }
- });
- }
+ // public static getDevModeStatus(project: Project) {
+ // const projectId = project.projectId;
+ // KaravanApi.getDevModePodStatus(projectId, res => {
+ // if (res.status === 200) {
+ // unstable_batchedUpdates(() => {
+ // const containerStatus = res.data;
+ // if (useDevModeStore.getState().podName !== containerStatus.containerName){
+ // useDevModeStore.setState({podName: containerStatus.containerName})
+ // }
+ // if (useDevModeStore.getState().status !== 'wip'){
+ // useLogStore.setState({isRunning: true})
+ // }
+ // useStatusesStore.setState({containerStatus: containerStatus});
+ // })
+ // } else {
+ // unstable_batchedUpdates(() => {
+ // useDevModeStore.setState({status: 'none', podName: undefined})
+ // useStatusesStore.setState({containerStatus: new ContainerStatus({})});
+ // })
+ // }
+ // });
+ // }
public static pushProject(project: Project, commitMessage: string) {
useProjectStore.setState({isPushing: true})
diff --git a/karavan-web/karavan-app/src/main/webui/src/api/ProjectStore.ts b/karavan-web/karavan-app/src/main/webui/src/api/ProjectStore.ts
index 80c99593..4c554926 100644
--- a/karavan-web/karavan-app/src/main/webui/src/api/ProjectStore.ts
+++ b/karavan-web/karavan-app/src/main/webui/src/api/ProjectStore.ts
@@ -59,7 +59,6 @@ interface ProjectState {
project: Project;
isPushing: boolean,
isRunning: boolean,
- containerStatus: ContainerStatus,
operation: "create" | "select" | "delete" | "none" | "copy";
setProject: (project: Project, operation: "create" | "select" | "delete"| "none" | "copy") => void;
setOperation: (o: "create" | "select" | "delete"| "none" | "copy") => void;
@@ -70,7 +69,6 @@ export const useProjectStore = create<ProjectState>((set) => ({
operation: "none",
isPushing: false,
isRunning: false,
- containerStatus: new ContainerStatus(),
setProject: (project: Project, operation: "create" | "select" | "delete"| "none" | "copy") => {
set((state: ProjectState) => ({
project: project,
@@ -191,7 +189,6 @@ export const useStatusesStore = create<StatusesState>((set) => ({
interface LogState {
podName?: string,
- isRunning: boolean,
data: string;
setData: (data: string) => void;
addData: (data: string) => void;
@@ -202,13 +199,11 @@ interface LogState {
setShowLog: (showLog: boolean) => void;
type: 'container' | 'pipeline' | 'none',
setType: (type: 'container' | 'pipeline' | 'none') => void,
- setIsRunning: (isRunning: boolean) => void;
}
export const useLogStore = create<LogState>((set) => ({
podName: undefined,
data: '',
- isRunning: false,
setData: (data: string) => {
set({data: data})
},
@@ -232,9 +227,6 @@ export const useLogStore = create<LogState>((set) => ({
setShowLog: (showLog: boolean) => {
set(() => ({showLog: showLog}));
},
- setIsRunning: (isRunning: boolean) => {
- set(() => ({isRunning: isRunning}));
- },
type: "none",
setType: (type: 'container' | 'pipeline' | 'none') => {
set((state: LogState) => ({type: type}));
diff --git a/karavan-web/karavan-app/src/main/webui/src/containers/ContainersPage.tsx b/karavan-web/karavan-app/src/main/webui/src/containers/ContainersPage.tsx
index 08539413..a2ae7686 100644
--- a/karavan-web/karavan-app/src/main/webui/src/containers/ContainersPage.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/containers/ContainersPage.tsx
@@ -1,7 +1,7 @@
-import React, {useEffect, useState} from 'react';
+import React, {useState} from 'react';
import {
Bullseye,
- Button, EmptyState, EmptyStateIcon, EmptyStateVariant,
+ EmptyState, EmptyStateIcon, EmptyStateVariant,
PageSection, Spinner,
Text,
TextContent,
@@ -13,8 +13,6 @@ import {
import '../designer/karavan.css';
import {ContainerStatus} from "../api/ProjectModels";
import {TableComposable, TableVariant, Tbody, Td, Th, Thead, Tr} from "@patternfly/react-table";
-import {KaravanApi} from "../api/KaravanApi";
-import RefreshIcon from "@patternfly/react-icons/dist/esm/icons/sync-alt-icon";
import SearchIcon from "@patternfly/react-icons/dist/esm/icons/search-icon";
import {MainToolbar} from "../designer/MainToolbar";
import {useAppConfigStore, useStatusesStore} from "../api/ProjectStore";
@@ -24,27 +22,11 @@ import {ContainerTableRow} from "./ContainerTableRow";
export const ContainersPage = () => {
const [config] = useAppConfigStore((state) => [state.config], shallow)
- const [containers, setContainers] = useStatusesStore((state) => [state.containers, state.setContainers], shallow);
+ const [containers] = useStatusesStore((state) => [state.containers, state.setContainers], shallow);
const [filter, setFilter] = useState<string>('');
- const [loading, setLoading] = useState<boolean>(true);
+ const [loading] = useState<boolean>(true);
const [selectedEnv, setSelectedEnv] = useState<string[]>([config.environment]);
- useEffect(() => {
- const interval = setInterval(() => {
- updateContainerStatuses()
- }, 700);
- return () => {
- clearInterval(interval)
- };
- }, []);
-
- function updateContainerStatuses() {
- KaravanApi.getAllContainerStatuses((statuses: ContainerStatus[]) => {
- setContainers(statuses);
- setLoading(false);
- });
- }
-
function selectEnvironment(name: string, selected: boolean) {
if (selected && !selectedEnv.includes(name)) {
setSelectedEnv((state: string[]) => {
@@ -61,9 +43,6 @@ export const ContainersPage = () => {
function tools() {
return (<Toolbar id="toolbar-group-types">
<ToolbarContent>
- <ToolbarItem>
- <Button variant="link" icon={<RefreshIcon/>} onClick={e => updateContainerStatuses()}/>
- </ToolbarItem>
<ToolbarItem>
<ToggleGroup aria-label="Default with single selectable">
{config.environments.map(env => (
diff --git a/karavan-web/karavan-app/src/main/webui/src/index.css b/karavan-web/karavan-app/src/main/webui/src/index.css
index 54dbc583..0367351c 100644
--- a/karavan-web/karavan-app/src/main/webui/src/index.css
+++ b/karavan-web/karavan-app/src/main/webui/src/index.css
@@ -180,7 +180,7 @@
margin-bottom: 100px;
}
-.karavan .project-page .project-log {
+.karavan .project-log {
position: absolute;
bottom: 0;
right: 0;
@@ -191,7 +191,7 @@
align-items: stretch;
}
-.karavan .project-page .project-log .buttons {
+.karavan .project-log .buttons {
display: flex;
flex-direction: row;
justify-content: flex-end;
@@ -199,26 +199,26 @@
padding-right: 6px;
}
-.karavan .project-page .project-log .buttons button,
-.karavan .project-page .project-log .buttons .pf-c-check {
+.karavan .project-log .buttons button,
+.karavan .project-log .buttons .pf-c-check {
padding: 8px;
}
-.karavan .project-page .project-log .buttons .pf-c-check .pf-c-check__label{
+.karavan .project-log .buttons .pf-c-check .pf-c-check__label{
font-size: 12px;
line-height: 20px;
padding: 0;
}
-.karavan .project-page .project-log .pf-c-log-viewer__scroll-container {
+.karavan .project-log .pf-c-log-viewer__scroll-container {
/*height: 100% !important;*/
}
-.karavan .project-page .project-log .pf-c-log-viewer__text {
+.karavan .project-log .pf-c-log-viewer__text {
font-size: 12px;
}
-.karavan .project-page .project-log .log-name {
+.karavan .project-log .log-name {
--pf-c-label__content--before--BorderWidth: 0;
--pf-c-label--BackgroundColor: transparent;
margin-right: auto;
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx b/karavan-web/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx
index 9777019b..9401aeb0 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx
@@ -4,8 +4,7 @@ import '../designer/karavan.css';
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/trash-icon";
-import PauseIcon from "@patternfly/react-icons/dist/esm/icons/pause-icon";
-import {useDevModeStore, useLogStore, useProjectStore} from "../api/ProjectStore";
+import {useDevModeStore, useLogStore, useProjectStore, useStatusesStore} from "../api/ProjectStore";
import {ProjectService} from "../api/ProjectService";
import {shallow} from "zustand/shallow";
import UpIcon from "@patternfly/react-icons/dist/esm/icons/check-circle-icon";
@@ -20,23 +19,25 @@ interface Props {
export const DevModeToolbar = (props: Props) => {
const [status] = useDevModeStore((state) => [state.status], shallow)
- const [project, containerStatus ] = useProjectStore((state) => [state.project, state.containerStatus], shallow)
+ const [project ] = useProjectStore((state) => [state.project], shallow)
+ const [containers] = useStatusesStore((state) => [state.containers], shallow);
const [verbose, setVerbose] = useState(false);
- const commands = containerStatus.commands;
- const isRunning = containerStatus.state === 'running';
- const inTransit = containerStatus.inTransit;
+ const containerStatus = containers.filter(c => c.containerName === project.projectId).at(0);
+ const commands = containerStatus?.commands || ['run'];
+ const isRunning = containerStatus?.state === 'running';
+ const inTransit = containerStatus?.inTransit;
const isLoading= status === 'wip';
- const color = containerStatus.state === 'running' ? "green" : "grey";
+ const color = containerStatus?.state === 'running' ? "green" : "grey";
const icon = isRunning ? <UpIcon/> : <DownIcon/>;
return (<Flex className="toolbar" direction={{default: "row"}} alignItems={{default: "alignItemsCenter"}}>
<FlexItem>
{(inTransit || isLoading) && <Spinner isSVG size="lg" aria-label="spinner"/>}
</FlexItem>
- {containerStatus.containerId && <FlexItem>
+ {containerStatus?.containerId && <FlexItem>
<Label icon={icon} color={color}>
<Tooltip content={"Show log"} position={TooltipPosition.bottom}>
- <Button variant="link"
+ <Button variant="link" isDisabled={!isRunning}
onClick={e =>
useLogStore.setState({showLog: true, type: 'container', podName: containerStatus.containerName})}>
{containerStatus.containerName}
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/ProjectPage.tsx b/karavan-web/karavan-app/src/main/webui/src/project/ProjectPage.tsx
index cab863b6..976123ef 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/ProjectPage.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/project/ProjectPage.tsx
@@ -13,7 +13,6 @@ import {MainToolbar} from "../designer/MainToolbar";
import {ProjectTitle} from "./ProjectTitle";
import {ProjectPanel} from "./ProjectPanel";
import {FileEditor} from "./file/FileEditor";
-import {ProjectService} from "../api/ProjectService";
import {shallow} from "zustand/shallow";
export const ProjectPage = () => {
@@ -23,15 +22,15 @@ export const ProjectPage = () => {
const [key, setKey] = useState<string>('');
const [project] = useProjectStore((state) => [state.project], shallow )
- useEffect(() => {
- // TODO: make status request only when started or just opened
- const interval = setInterval(() => {
- ProjectService.getDevModeStatus(project);
- }, 1000);
- return () => {
- clearInterval(interval)
- };
- }, []);
+ // useEffect(() => {
+ // // TODO: make status request only when started or just opened
+ // const interval = setInterval(() => {
+ // ProjectService.getDevModeStatus(project);
+ // }, 1000);
+ // return () => {
+ // clearInterval(interval)
+ // };
+ // }, []);
function post (file: ProjectFile) {
KaravanApi.postProjectFile(file, res => {
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx b/karavan-web/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx
index 9aa0a0f8..beceb5c8 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/project/dashboard/DashboardTab.tsx
@@ -24,11 +24,14 @@ import {InfoContainer} from "./InfoContainer";
import {InfoContext} from "./InfoContext";
import {InfoMemory} from "./InfoMemory";
import {KaravanApi} from "../../api/KaravanApi";
-import {useProjectStore} from "../../api/ProjectStore";
+import {useProjectStore, useStatusesStore} from "../../api/ProjectStore";
+import {shallow} from "zustand/shallow";
+import {ContainerStatus} from "../../api/ProjectModels";
export const DashboardTab = () => {
- const {project, containerStatus} = useProjectStore();
+ const [project] = useProjectStore((state) => [state.project], shallow);
+ const [containers] = useStatusesStore((state) => [state.containers], shallow);
const [memory, setMemory] = useState({});
const [jvm, setJvm] = useState({});
const [context, setContext] = useState({});
@@ -67,10 +70,8 @@ export const DashboardTab = () => {
})
}
- function showConsole(): boolean {
- return containerStatus.lifeCycle === 'ready';
- }
-
+ const containerStatus = containers.filter(c => c.containerName === project.projectId).at(0);
+ const showConsole = containerStatus?.state === 'running'
return (
<PageSection className="project-tab-panel" padding={{default: "padding"}}>
<Card className="project-development">
@@ -78,15 +79,15 @@ export const DashboardTab = () => {
<Flex direction={{default: "row"}}
justifyContent={{default: "justifyContentSpaceBetween"}}>
<FlexItem flex={{default: "flex_1"}}>
- <InfoContainer containerStatus={containerStatus}/>
+ <InfoContainer containerStatus={containerStatus || new ContainerStatus()}/>
</FlexItem>
<Divider orientation={{default: "vertical"}}/>
<FlexItem flex={{default: "flex_1"}}>
- <InfoMemory jvm={jvm} memory={memory} showConsole={showConsole()}/>
+ <InfoMemory jvm={jvm} memory={memory} showConsole={showConsole}/>
</FlexItem>
<Divider orientation={{default: "vertical"}}/>
<FlexItem flex={{default: "flex_1"}}>
- <InfoContext context={context} showConsole={showConsole()}/>
+ <InfoContext context={context} showConsole={showConsole}/>
</FlexItem>
</Flex>
</CardBody>
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/log/ProjectLogPanel.tsx b/karavan-web/karavan-app/src/main/webui/src/project/log/ProjectLogPanel.tsx
index 619b1ff7..d02ee9ac 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/log/ProjectLogPanel.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/project/log/ProjectLogPanel.tsx
@@ -5,7 +5,7 @@ import CloseIcon from '@patternfly/react-icons/dist/esm/icons/times-icon';
import ExpandIcon from '@patternfly/react-icons/dist/esm/icons/expand-icon';
import CollapseIcon from '@patternfly/react-icons/dist/esm/icons/compress-icon';
import CleanIcon from '@patternfly/react-icons/dist/esm/icons/trash-alt-icon';
-import {useLogStore} from "../../api/ProjectStore";
+import {useLogStore, useProjectStore, useStatusesStore} from "../../api/ProjectStore";
import {KaravanApi} from "../../api/KaravanApi";
import {shallow} from "zustand/shallow";
import {ProjectEventBus} from "../../api/ProjectEventBus";
@@ -14,9 +14,10 @@ import {ProjectLog} from "./ProjectLog";
const INITIAL_LOG_HEIGHT = "50%";
export const ProjectLogPanel = () => {
- const [showLog, type, setShowLog, podName, isRunning] = useLogStore(
- (state) => [state.showLog, state.type, state.setShowLog, state.podName, state.isRunning], shallow)
+ const [showLog, type, setShowLog, podName] = useLogStore(
+ (state) => [state.showLog, state.type, state.setShowLog, state.podName], shallow)
+ const [containers] = useStatusesStore((state) => [state.containers], shallow);
const [height, setHeight] = useState(INITIAL_LOG_HEIGHT);
const [isTextWrapped, setIsTextWrapped] = useState(true);
const [autoScroll, setAutoScroll] = useState(true);
@@ -24,9 +25,10 @@ export const ProjectLogPanel = () => {
const [currentPodName, setCurrentPodName] = useState<string | undefined>(undefined);
useEffect(() => {
- console.log("ProjectLogPanel", showLog, type, podName, isRunning);
+ const containerStatus = containers.filter(c => c.containerName === podName).at(0);
+ console.log("ProjectLogPanel", showLog, type, podName, containerStatus);
const controller = new AbortController();
- if (showLog && type !== 'none' && podName !== undefined && isRunning) {
+ if (showLog && type !== 'none' && podName !== undefined) {
const f = KaravanApi.fetchData(type, podName, controller).then(value => {
console.log("Fetch Started for: " + podName)
});
@@ -37,7 +39,7 @@ export const ProjectLogPanel = () => {
console.log("end");
controller.abort();
};
- }, [showLog, type, podName, isRunning]);
+ }, [showLog, type, podName]);
useEffect(() => {
if (currentPodName !== podName) {
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx b/karavan-web/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx
index 14dc1eaa..ba26da23 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/project/pipeline/ProjectStatus.tsx
@@ -207,8 +207,7 @@ export class ProjectStatus extends React.Component<Props, State> {
useLogStore.setState({
showLog: true,
type: 'container',
- podName: pod.containerName,
- isRunning: true
+ podName: pod.containerName
});
}}>
{pod.containerName}
@@ -287,7 +286,7 @@ export class ProjectStatus extends React.Component<Props, State> {
<Label icon={isRunning ? <Spinner isSVG diameter="16px" className="spinner"/> : icon} color={color}>
{pipeline
? <Button variant="link" onClick={e =>
- useLogStore.setState({showLog: true, type: 'pipeline', podName: pipeline, isRunning: true})
+ useLogStore.setState({showLog: true, type: 'pipeline', podName: pipeline})
}>
{pipeline}
</Button>
diff --git a/karavan-web/karavan-app/src/main/webui/src/services/ServicesPage.tsx b/karavan-web/karavan-app/src/main/webui/src/services/ServicesPage.tsx
index 87606ac9..b7dd8fde 100644
--- a/karavan-web/karavan-app/src/main/webui/src/services/ServicesPage.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/services/ServicesPage.tsx
@@ -23,36 +23,24 @@ import {DeleteServiceModal} from "./DeleteServiceModal";
import {CreateServiceModal} from "./CreateServiceModal";
import {useProjectStore, useStatusesStore} from "../api/ProjectStore";
import {MainToolbar} from "../designer/MainToolbar";
-import {ContainerStatus, Project, ProjectType} from "../api/ProjectModels";
+import {Project, ProjectType} from "../api/ProjectModels";
import {KaravanApi} from "../api/KaravanApi";
import {DevService, Services, ServicesYaml} from "../api/ServiceModels";
import {shallow} from "zustand/shallow";
+import {ProjectLogPanel} from "../project/log/ProjectLogPanel";
export const ServicesPage = () => {
const [services, setServices] = useState<Services>();
- const [containers, setContainers] = useStatusesStore((state) => [state.containers, state.setContainers], shallow);
- const [operation, setOperation] = useState<'create' | 'delete' | 'none'>('none');
- const [loading, setLoading] = useState<boolean>(false);
+ const [containers] = useStatusesStore((state) => [state.containers, state.setContainers], shallow);
+ const [operation] = useState<'create' | 'delete' | 'none'>('none');
+ const [loading] = useState<boolean>(false);
useEffect(() => {
getServices();
- const interval = setInterval(() => {
- updateContainerStatuses()
- }, 700);
- return () => {
- clearInterval(interval)
- };
}, []);
- function updateContainerStatuses() {
- KaravanApi.getAllContainerStatuses((statuses: ContainerStatus[]) => {
- setContainers(statuses);
- setLoading(false);
- });
- }
-
function getServices() {
KaravanApi.getFiles(ProjectType.services, files => {
const file = files.at(0);
@@ -142,6 +130,7 @@ export const ServicesPage = () => {
</PageSection>
{["create"].includes(operation) && <CreateServiceModal/>}
{["delete"].includes(operation) && <DeleteServiceModal/>}
+ <ProjectLogPanel/>
</PageSection>
)
}
\ No newline at end of file
diff --git a/karavan-web/karavan-app/src/main/webui/src/services/ServicesTableRow.tsx b/karavan-web/karavan-app/src/main/webui/src/services/ServicesTableRow.tsx
index fab5456d..c5bc953a 100644
--- a/karavan-web/karavan-app/src/main/webui/src/services/ServicesTableRow.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/services/ServicesTableRow.tsx
@@ -2,7 +2,7 @@ import React, {useState} from 'react';
import {
Button,
Tooltip,
- Flex, FlexItem, Label, ToolbarContent, Toolbar, ToolbarItem, Spinner
+ Flex, FlexItem, Label, ToolbarContent, Toolbar, ToolbarItem, Spinner, TooltipPosition
} from '@patternfly/react-core';
import '../designer/karavan.css';
import {ActionsColumn, ExpandableRowContent, Tbody, Td, Tr} from "@patternfly/react-table";
@@ -12,9 +12,11 @@ import {DevService} from "../api/ServiceModels";
import {ContainerStatus} from "../api/ProjectModels";
import PauseIcon from "@patternfly/react-icons/dist/esm/icons/pause-icon";
import DeleteIcon from "@patternfly/react-icons/dist/js/icons/times-icon";
-import {useAppConfigStore} from "../api/ProjectStore";
+import {useAppConfigStore, useLogStore} from "../api/ProjectStore";
import {shallow} from "zustand/shallow";
import {KaravanApi} from "../api/KaravanApi";
+import UpIcon from "@patternfly/react-icons/dist/esm/icons/check-circle-icon";
+import DownIcon from "@patternfly/react-icons/dist/esm/icons/error-circle-o-icon";
interface Props {
index: number
@@ -80,7 +82,8 @@ export const ServicesTableRow = (props: Props) => {
const container = props.container;
const isRunning = container?.state === 'running';
const inTransit = container?.inTransit;
- const color = container?.state === 'running' ? "green" : "grey";
+ const color = isRunning ? "green" : "grey";
+ const icon = isRunning ? <UpIcon/> : <DownIcon/>;
return (
<Tbody isExpanded={isExpanded}>
<Tr key={service.container_name}>
@@ -96,7 +99,17 @@ export const ServicesTableRow = (props: Props) => {
modifier={"fitContent"}>
</Td>
<Td>
- <Label color={color}>{service.container_name}</Label>
+ {container && <Label icon={icon} color={color}>
+ <Tooltip content={"Show log"} position={TooltipPosition.bottom}>
+ <Button variant="link" isDisabled={!isRunning}
+ onClick={e => {
+ useLogStore.setState({showLog: true, type: 'container', podName: container.containerName});
+ }}>
+ {service.container_name}
+ </Button>
+ </Tooltip>
+ </Label>}
+ {!container && <Label color={color}>{service.container_name}</Label>}
</Td>
<Td>{service.container_name}</Td>
<Td>{service.image}</Td>