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
The following commit(s) were added to refs/heads/main by this push:
new eac538ef Improvements for #981
eac538ef is described below
commit eac538ef5e7298bc84d2384bae728d6909b4d484
Author: Marat Gubaidullin <[email protected]>
AuthorDate: Thu Nov 9 17:15:46 2023 -0500
Improvements for #981
---
.../camel/karavan/api/ContainerResource.java | 18 +++++---
.../apache/camel/karavan/docker/DockerService.java | 12 ++++--
.../src/main/webui/src/project/DevModeToolbar.tsx | 50 +++++++++++-----------
.../src/main/webui/src/project/ProjectPage.tsx | 27 ++++++------
.../main/webui/src/project/build/BuildPanel.tsx | 3 +-
.../webui/src/project/dashboard/DashboardTab.tsx | 2 +-
.../src/main/webui/src/project/devmode.css | 39 +++++++++++++++++
.../src/main/webui/src/project/trace/TraceTab.tsx | 1 -
8 files changed, 101 insertions(+), 51 deletions(-)
diff --git
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ContainerResource.java
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ContainerResource.java
index a288a2a7..5eefe265 100644
---
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ContainerResource.java
+++
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ContainerResource.java
@@ -32,15 +32,15 @@ import
org.apache.camel.karavan.infinispan.model.ContainerStatus;
import org.apache.camel.karavan.kubernetes.KubernetesService;
import org.apache.camel.karavan.service.ConfigService;
import org.apache.camel.karavan.service.ProjectService;
+import org.apache.camel.karavan.shared.Constants;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.jboss.logging.Logger;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
import java.util.stream.Collectors;
import static
org.apache.camel.karavan.service.ContainerStatusService.CONTAINER_STATUS;
+import static org.apache.camel.karavan.shared.Constants.*;
@Path("/api/container")
public class ContainerResource {
@@ -98,13 +98,21 @@ public class ContainerResource {
String code = projectService.getDevServiceCode();
DockerComposeService dockerComposeService =
DockerComposeConverter.fromCode(code, name);
if (dockerComposeService != null) {
-
dockerService.createContainerFromCompose(dockerComposeService,
ContainerStatus.ContainerType.devservice);
+ Map<String,String> labels = new HashMap<>();
+ labels.put(LABEL_TYPE,
ContainerStatus.ContainerType.devservice.name());
+ labels.put(LABEL_CAMEL_RUNTIME,
Constants.CamelRuntime.CAMEL_MAIN.getValue());
+ labels.put(LABEL_PROJECT_ID, name);
+
dockerService.createContainerFromCompose(dockerComposeService, labels);
dockerService.runContainer(dockerComposeService.getContainer_name());
}
} else if (Objects.equals(type,
ContainerStatus.ContainerType.project.name())) {
DockerComposeService dockerComposeService =
projectService.getProjectDockerComposeService(name);
if (dockerComposeService != null) {
-
dockerService.createContainerFromCompose(dockerComposeService,
ContainerStatus.ContainerType.project);
+ Map<String,String> labels = new HashMap<>();
+ labels.put(LABEL_TYPE,
ContainerStatus.ContainerType.project.name());
+ labels.put(LABEL_CAMEL_RUNTIME,
Constants.CamelRuntime.CAMEL_MAIN.getValue());
+ labels.put(LABEL_PROJECT_ID, name);
+
dockerService.createContainerFromCompose(dockerComposeService, labels);
dockerService.runContainer(dockerComposeService.getContainer_name());
}
} else if (Objects.equals(type,
ContainerStatus.ContainerType.devmode.name())) {
diff --git
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerService.java
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerService.java
index 23ce0464..02bcf76e 100644
---
a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerService.java
+++
b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerService.java
@@ -33,6 +33,7 @@ import jakarta.inject.Inject;
import org.apache.camel.karavan.code.CodeService;
import org.apache.camel.karavan.code.model.DockerComposeService;
import org.apache.camel.karavan.infinispan.model.ContainerStatus;
+import org.apache.camel.karavan.shared.Constants;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.io.IOUtils;
@@ -45,8 +46,7 @@ import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
-import static org.apache.camel.karavan.shared.Constants.LABEL_PROJECT_ID;
-import static org.apache.camel.karavan.shared.Constants.LABEL_TYPE;
+import static org.apache.camel.karavan.shared.Constants.*;
@ApplicationScoped
public class DockerService extends DockerServiceUtils {
@@ -147,6 +147,12 @@ public class DockerService extends DockerServiceUtils {
}
public Container createContainerFromCompose(DockerComposeService compose,
ContainerStatus.ContainerType type) throws InterruptedException {
+ Map<String,String> labels = new HashMap<>();
+ labels.put(LABEL_TYPE, type.name());
+ return createContainerFromCompose(compose, labels);
+ }
+
+ public Container createContainerFromCompose(DockerComposeService compose,
Map<String, String> labels) throws InterruptedException {
List<Container> containers =
findContainer(compose.getContainer_name());
if (containers.isEmpty()) {
LOGGER.infof("Compose Service starting for %s",
compose.getContainer_name());
@@ -164,7 +170,7 @@ public class DockerService extends DockerServiceUtils {
}
return createContainer(compose.getContainer_name(),
compose.getImage(),
- env, compose.getPortsMap(), healthCheck,
Map.of(LABEL_TYPE, type.name()), Map.of(), NETWORK_NAME, restartPolicy);
+ env, compose.getPortsMap(), healthCheck, labels, Map.of(),
NETWORK_NAME, restartPolicy);
} else {
LOGGER.info("Compose Service already exists: " +
containers.get(0).getId());
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 76092d4c..f9056c14 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
@@ -16,18 +16,7 @@
*/
import React, {useEffect, useState} from 'react';
-import {
- Badge,
- Button,
- Flex,
- FlexItem,
- Label,
- Spinner,
- Switch,
- ToolbarItem,
- Tooltip,
- TooltipPosition
-} from '@patternfly/react-core';
+import {Badge, Button, Flex, FlexItem, Label, Spinner, Switch, Tooltip,
TooltipPosition} from '@patternfly/react-core';
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";
@@ -38,8 +27,9 @@ import {shallow} from "zustand/shallow";
import UpIcon from "@patternfly/react-icons/dist/esm/icons/running-icon";
import DownIcon from
"@patternfly/react-icons/dist/esm/icons/error-circle-o-icon";
import RefreshIcon from "@patternfly/react-icons/dist/esm/icons/sync-alt-icon";
-import {KaravanApi} from "../api/KaravanApi";
+import StopIcon from "@patternfly/react-icons/dist/esm/icons/stop-icon";
import {ContainerStatus} from "../api/ProjectModels";
+import "./devmode.css"
interface Props {
reloadOnly?: boolean
@@ -49,7 +39,7 @@ export function DevModeToolbar(props: Props) {
const [config] = useAppConfigStore((state) => [state.config], shallow)
const [status] = useDevModeStore((state) => [state.status], shallow)
- const [project] = useProjectStore((state) => [state.project], shallow)
+ const [project, refreshTrace] = useProjectStore((state) => [state.project,
state.refreshTrace], shallow)
const [containers] = useStatusesStore((state) => [state.containers],
shallow);
const [verbose, setVerbose] = useState(false);
const [setShowLog] = useLogStore((s) => [s.setShowLog], shallow);
@@ -68,13 +58,18 @@ export function DevModeToolbar(props: Props) {
useEffect(() => {
const interval = setInterval(() => {
refreshContainer();
- }, 1000)
+ }, 1300)
return () => clearInterval(interval);
}, [poll, currentContainerStatus, containers]);
function refreshContainer(){
if (poll) {
ProjectService.refreshAllContainerStatuses();
+ ProjectService.refreshCamelStatus(project.projectId,
config.environment);
+ ProjectService.refreshImages(project.projectId);
+ if (refreshTrace) {
+ ProjectService.refreshCamelTraces(project.projectId,
config.environment);
+ }
if (currentContainerStatus && !containerStatus) {
setPoll(false);
}
@@ -83,16 +78,21 @@ export function DevModeToolbar(props: Props) {
}
return (<Flex className="toolbar" direction={{default: "row"}}
alignItems={{default: "alignItemsCenter"}}>
- <FlexItem>
- <Button icon={<RefreshIcon/>}
+ <FlexItem className="refresher">
+ {poll && <Spinner className="spinner" size="lg"
aria-label="Refresh"/>}
+ <Tooltip content={poll ? "Stop refresh" : "Refresh auto"}
position={TooltipPosition.bottom}>
+ <Button className="button"
+ icon={poll ? <StopIcon/> : <RefreshIcon/>}
variant={"link"}
- onClick={e =>
ProjectService.refreshAllContainerStatuses()}/>
+ onClick={e => setPoll(!poll)}/>
+ </Tooltip>
</FlexItem>
- {(inTransit || isLoading) &&
- <FlexItem>
- <Spinner size="lg" aria-label="spinner"/>
- </FlexItem>
- }
+ {/*Replace with something else because Spinner is used fo refresh*/}
+ {/*{(inTransit || isLoading) &&*/}
+ {/* <FlexItem>*/}
+ {/* <Spinner size="lg" aria-label="spinner"/>*/}
+ {/* </FlexItem>*/}
+ {/*}*/}
{containerStatus?.containerId && <FlexItem>
<Label icon={icon} color={color}>
<Tooltip content={"Show log"}
position={TooltipPosition.bottom}>
@@ -129,7 +129,7 @@ export function DevModeToolbar(props: Props) {
</Tooltip>
</FlexItem>}
{isRunning && inDevMode && <FlexItem>
- <Tooltip content="Reload" position={TooltipPosition.bottom}>
+ <Tooltip content="Reload" position={TooltipPosition.bottomEnd}>
<Button size="sm"
isDisabled={inTransit}
variant={"primary"}
@@ -140,7 +140,7 @@ export function DevModeToolbar(props: Props) {
</Tooltip>
</FlexItem>}
{inDevMode && <FlexItem>
- <Tooltip content="Delete container"
position={TooltipPosition.bottom}>
+ <Tooltip content="Delete container"
position={TooltipPosition.bottomEnd}>
<Button size="sm"
isDisabled={!commands.includes('delete') || inTransit}
variant={"control"}
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 7cc8eca2..8928d4f9 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
@@ -41,7 +41,8 @@ export function ProjectPage() {
const [config] = useAppConfigStore((state) => [state.config], shallow)
const {file, operation} = useFileStore();
const [projects] = useProjectsStore((state) => [state.projects], shallow)
- const [project, setProject, tab, setTab] = useProjectStore((s) =>
[s.project, s.setProject, s.tabIndex, s.setTabIndex], shallow);
+ const [project, setProject, tabIndex, setTabIndex, refreshTrace] =
+ useProjectStore((s) => [s.project, s.setProject, s.tabIndex,
s.setTabIndex, s.refreshTrace], shallow);
let {projectId} = useParams();
@@ -52,24 +53,20 @@ export function ProjectPage() {
} else if (projectId) {
KaravanApi.getProject(projectId, project1 => setProject(project1,
"select"));
}
- const interval = setInterval(() => onRefreshStatus(), 1000);
return () => {
- clearInterval(interval);
setProject(new Project(), "none");
}
}, []);
- function onRefreshStatus(){
- if (tab === 'dashboard') {
- ProjectService.refreshCamelStatus(project.projectId,
config.environment);
- } else if (tab === 'trace') {
- ProjectService.refreshCamelTraces(project.projectId,
config.environment);
- } else if (tab === 'build') {
- ProjectService.refreshImages(project.projectId);
- } else if (tab === 'container') {
-
- }
- }
+ useEffect(() => {
+ const interval = setInterval(() => {
+ if (tabIndex === 'build' || tabIndex === 'container') {
+ ProjectService.refreshAllContainerStatuses();
+ ProjectService.refreshImages(project.projectId);
+ }
+ }, 2000)
+ return () => clearInterval(interval);
+ }, [tabIndex]);
function isBuildIn(): boolean {
return ['kamelets', 'templates',
'services'].includes(project.projectId);
@@ -89,7 +86,7 @@ export function ProjectPage() {
<PageSection className="tools-section" padding={{default:
'noPadding'}}>
<Flex direction={{default: "column"}} spaceItems={{default:
"spaceItemsNone"}}>
<FlexItem className="project-tabs">
- {showTabs() && <Tabs activeKey={tab} onSelect={(event,
tabIndex) => setTab(tabIndex)}>
+ {showTabs() && <Tabs activeKey={tabIndex}
onSelect={(event, tabIndex) => setTabIndex(tabIndex)}>
<Tab eventKey="files" title="Files"/>
<Tab eventKey="topology" title="Topology"/>
<Tab eventKey="dashboard" title="Dashboard"/>
diff --git
a/karavan-web/karavan-app/src/main/webui/src/project/build/BuildPanel.tsx
b/karavan-web/karavan-app/src/main/webui/src/project/build/BuildPanel.tsx
index ad0a4d2f..f1dedba6 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/build/BuildPanel.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/project/build/BuildPanel.tsx
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import React, {useState} from 'react';
+import React, {useEffect, useState} from 'react';
import {
Button,
DescriptionList,
@@ -34,6 +34,7 @@ import DeleteIcon from
"@patternfly/react-icons/dist/esm/icons/times-circle-icon
import {useAppConfigStore, useLogStore, useProjectStore, useStatusesStore}
from "../../api/ProjectStore";
import {shallow} from "zustand/shallow";
import {EventBus} from "../../designer/utils/EventBus";
+import {ProjectService} from "../../api/ProjectService";
export function BuildPanel () {
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 bccb0faf..e05795d8 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
@@ -48,7 +48,7 @@ export function DashboardTab() {
return (
<PageSection className="project-tab-panel" padding={{default:
"padding"}}>
{camelContainers.map((containerStatus, index) =>
- <Card className="dashboard-card">
+ <Card className="dashboard-card"
key={containerStatus.containerId}>
<CardBody>
<Flex direction={{default: "row"}}
justifyContent={{default:
"justifyContentSpaceBetween"}}>
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/devmode.css
b/karavan-web/karavan-app/src/main/webui/src/project/devmode.css
new file mode 100644
index 00000000..fea70e8e
--- /dev/null
+++ b/karavan-web/karavan-app/src/main/webui/src/project/devmode.css
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.karavan .refresher {
+ width: 34px;
+ height: 34px;
+}
+
+.karavan .refresher .spinner {
+ position: absolute;
+ width: 34px;
+ height: 34px;
+}
+
+.karavan .refresher .button {
+ position: absolute;
+ width: 34px;
+ height: 34px;
+ padding: 0;
+ font-size: 16px;
+}
+
+.karavan .refresher .button .pf-v5-c-button__icon {
+ margin: 0;
+}
\ No newline at end of file
diff --git
a/karavan-web/karavan-app/src/main/webui/src/project/trace/TraceTab.tsx
b/karavan-web/karavan-app/src/main/webui/src/project/trace/TraceTab.tsx
index 2cdf25e3..b34a5361 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/trace/TraceTab.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/project/trace/TraceTab.tsx
@@ -59,7 +59,6 @@ import {InfoMemory} from "../dashboard/InfoMemory";
import {InfoContext} from "../dashboard/InfoContext";
import {TraceTable} from "./TraceTable";
-
export function TraceTab() {
const [project, refreshTrace, setRefreshTrace, camelStatuses] =
useProjectStore((state) =>