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 2025/11/18 18:09:28 UTC
(camel-karavan) branch main updated: Redesign
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 f99fdb98 Redesign
f99fdb98 is described below
commit f99fdb98d79748b38db6fcd584e6fd4aee695b8f
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Tue Nov 18 13:09:22 2025 -0500
Redesign
---
.../src/main/resources/application.properties | 2 +-
.../src/accelerator/toolbar/DevModeToolbar.tsx | 1 -
.../src/integration-runtime/MainConfigLogTab.tsx | 55 -----------
.../src/integration-runtime/PodEventsLogTab.tsx | 66 -------------
.../webui/src/integration-runtime/RoutesTab.tsx | 107 ---------------------
.../webui/src/integration-runtime/RuntimePanel.tsx | 12 ---
.../webui/src/integration-runtime/ThreadsTab.tsx | 61 ------------
7 files changed, 1 insertion(+), 303 deletions(-)
diff --git a/karavan-app/src/main/resources/application.properties b/karavan-app/src/main/resources/application.properties
index 45f8a9d5..f01f7586 100644
--- a/karavan-app/src/main/resources/application.properties
+++ b/karavan-app/src/main/resources/application.properties
@@ -24,7 +24,7 @@ karavan.container.status.interval=2s
karavan.container.statistics.interval=10s
# karavan.container.statistics.interval should be off in kubernetes
-karavan.devmode.image=ghcr.io/apache/camel-karavan-devmode:4.14.2
+karavan.devmode.image=ghcr.io/apache/camel-karavan-devmode:4.14.0
karavan.devmode.service.account=karavan
karavan.builder.service.account=karavan
karavan.secret.name=karavan
diff --git a/karavan-app/src/main/webui/src/accelerator/toolbar/DevModeToolbar.tsx b/karavan-app/src/main/webui/src/accelerator/toolbar/DevModeToolbar.tsx
index c58326c9..f799d968 100644
--- a/karavan-app/src/main/webui/src/accelerator/toolbar/DevModeToolbar.tsx
+++ b/karavan-app/src/main/webui/src/accelerator/toolbar/DevModeToolbar.tsx
@@ -1,7 +1,6 @@
import React, {useEffect, useState} from 'react';
import {Button, Dropdown, DropdownItem, DropdownList, MenuToggle, MenuToggleElement, Spinner, Tooltip, TooltipPosition} from '@patternfly/react-core';
import DevIcon from "@patternfly/react-icons/dist/esm/icons/dev-icon";
-import DebugIcon from "@patternfly/react-icons/dist/esm/icons/bug-icon";
import ReloadIcon from "@patternfly/react-icons/dist/esm/icons/bolt-icon";
import DeleteIcon from "@patternfly/react-icons/dist/esm/icons/trash-icon";
import {useAppConfigStore, useFileStore, useLogStore, useProjectStore} from "@/api/ProjectStore";
diff --git a/karavan-app/src/main/webui/src/integration-runtime/MainConfigLogTab.tsx b/karavan-app/src/main/webui/src/integration-runtime/MainConfigLogTab.tsx
deleted file mode 100644
index 5c65bef9..00000000
--- a/karavan-app/src/main/webui/src/integration-runtime/MainConfigLogTab.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import React, {useEffect, useState} from 'react';
-import './ProjectLog.css';
-import {Table, Tbody, Td, Th, Thead, Tr} from "@patternfly/react-table";
-import {Bullseye, Content, Spinner} from "@patternfly/react-core";
-import {APPLICATION_PROPERTIES} from "@/api/ProjectModels";
-import {MainConfiguration} from "@/integration-runtime/RuntimeModels";
-import {RuntimeApi} from "@/integration-runtime/RuntimeApi";
-
-interface Props {
- currentPodName: string
- header?: React.ReactNode
-}
-
-export function MainConfigLogTab (props: Props) {
-
- const [mainConfig, setMainConfig ] = useState<MainConfiguration[]>([]);
-
- useEffect(() => {
- RuntimeApi.getMainConfiguration(props.currentPodName, pes => setMainConfig(pes));
- }, []);
-
- const showConfig = mainConfig?.length > 0;
-
- return (
- <div style={{display: "flex", flexDirection:"column", position: "relative", height: "100%", backgroundColor: 'var(--pf-t--global--background--color--primary--default)'}}>
- {props.header}
- {!showConfig && <Bullseye height={'100%'}><Spinner></Spinner></Bullseye>}
- {showConfig && <div style={{overflow: "auto"}}>
- <Table aria-label="Main configuration table" height={"100vh"} variant='compact'>
- <Thead>
- <Tr>
- <Th>Key</Th>
- <Th>Value</Th>
- <Th>Location</Th>
- </Tr>
- </Thead>
- <Tbody className='event-table'>
- {mainConfig.sort((a, b) => a.key.localeCompare(b.key)).map((config) => {
- const bgColor = (config.location.endsWith(APPLICATION_PROPERTIES) || config.location === 'initial') ? 'transparent' : 'yellow';
- return (
- <Tr key={config.key}>
- <Td>{config.key}</Td>
- <Td>{config.value}</Td>
- <Td>
- <Content component="p" style={{width: 'fit-content', backgroundColor: bgColor}}>{config.location}</Content>
- </Td>
- </Tr>
- )
- })}
- </Tbody>
- </Table>
- </div>}
- </div>
- );
-}
diff --git a/karavan-app/src/main/webui/src/integration-runtime/PodEventsLogTab.tsx b/karavan-app/src/main/webui/src/integration-runtime/PodEventsLogTab.tsx
deleted file mode 100644
index 6ec81ef6..00000000
--- a/karavan-app/src/main/webui/src/integration-runtime/PodEventsLogTab.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.
- */
-
-import React, {useEffect, useState} from 'react';
-import './ProjectLog.css';
-import {Table, Tbody, Td, Th, Thead, Tr} from "@patternfly/react-table";
-import {Bullseye, Spinner} from "@patternfly/react-core";
-import {KaravanApi} from "@/api/KaravanApi";
-import {PodEvent} from "@/api/ProjectModels";
-
-interface Props {
- currentPodName: string
- header?: React.ReactNode
-}
-
-export function PodEventsLogTab (props: Props) {
-
- const [podEvents,setPodEvents ] = useState<PodEvent[]>([]);
-
- useEffect(() => {
- KaravanApi.getPodEvents(props.currentPodName, pes => setPodEvents(pes));
- }, []);
-
- return (
- <div style={{display: "flex", flexDirection:"column", position: "relative", height: "100%"}}>
- {props.header}
- {podEvents.length === 0 && <Bullseye height={'100%'}><Spinner></Spinner></Bullseye>}
- {podEvents.length > 0 && <div style={{overflow: "auto"}}>
- <Table aria-label="Simple table" height={"100vh"} variant='compact'>
- <Thead>
- <Tr>
- <Th>ID</Th>
- <Th>Reason</Th>
- <Th>Note</Th>
- <Th>TimeStamp</Th>
- </Tr>
- </Thead>
- <Tbody className='event-table'>
- {podEvents.map((podEvent) => (
- <Tr key={podEvent.id}>
- <Td>{podEvent.id}</Td>
- <Td>{podEvent.reason}</Td>
- <Td>{podEvent.note}</Td>
- <Td>{podEvent.creationTimestamp}</Td>
- </Tr>
- ))}
- </Tbody>
- </Table>
- </div>}
- </div>
- );
-}
diff --git a/karavan-app/src/main/webui/src/integration-runtime/RoutesTab.tsx b/karavan-app/src/main/webui/src/integration-runtime/RoutesTab.tsx
deleted file mode 100644
index ed90a848..00000000
--- a/karavan-app/src/main/webui/src/integration-runtime/RoutesTab.tsx
+++ /dev/null
@@ -1,107 +0,0 @@
-import React from 'react';
-import './ProjectLog.css';
-import {Table, Tbody, Td, Th, Thead, Tr} from "@patternfly/react-table";
-import {useAppConfigStore, useProjectStore} from "@/api/ProjectStore";
-import {Bullseye, Button, Label, Spinner, Tooltip} from "@patternfly/react-core";
-import TimeAgo from "javascript-time-ago";
-import {PauseIcon, PlayIcon, StopIcon} from "@patternfly/react-icons";
-import {RuntimeApi} from "@/integration-runtime/RuntimeApi";
-
-interface Props {
- currentPodName: string
- header?: React.ReactNode
-}
-
-export function RoutesTab(props: Props) {
-
- const config = useAppConfigStore((state) => state.config);
- const project = useProjectStore((state) => state.project);
- const camelStatuses = useProjectStore((state) => state.camelStatuses);
- const route = camelStatuses[0]?.statuses.find(s => s.name === 'route');
- const statusText = route?.status;
- const status = statusText !== undefined ? JSON.parse(statusText) : {};
- const routes = status?.route?.routes;
- const show = routes !== undefined && Array.isArray(routes);
- const timeAgo = new TimeAgo('en-US')
-
-
- function execRouteAction(routeId: string, action: string) {
- RuntimeApi.getRuntimeRouteAction(project.projectId, config.environment, routeId, action, res => {
-
- })
- }
-
- return (
- <div style={{display: "flex", flexDirection: "column", position: "relative", height: "100%", backgroundColor: "var(--pf-t--global--background--color--primary--default)"}}>
- {props.header}
- {!show && <Bullseye height={'100%'}><Spinner></Spinner></Bullseye>}
- {show &&
- <div style={{overflow: "auto"}}>
- <Table aria-label="Main configuration table" height={"100vh"} variant='compact'>
- <Thead>
- <Tr>
- <Th modifier='nowrap'>RouteId</Th>
- <Th modifier='nowrap'>Description</Th>
- <Th modifier='nowrap'>State</Th>
- <Th modifier='nowrap'>Uptime</Th>
- <Th modifier='nowrap'>From</Th>
- <Th modifier='nowrap'>Exchanges Total</Th>
- <Th modifier='nowrap'>Exchanges Inflight</Th>
- <Th modifier='nowrap'>Exchanges Failed</Th>
- <Th modifier='nowrap'>Last Failed</Th>
- <Th textCenter>Actions</Th>
- </Tr>
- </Thead>
- <Tbody className='route-table'>
- {routes.map((t) => {
- const time = t.statistics.lastFailedExchangeTimestamp;
- const dateString = time ? new Date(time).toISOString() : undefined;
- const date = time ? timeAgo.format(new Date(time), 'mini-now') : undefined;
- const failedGap = Date.now() - (time ?? 0);
- const failedColor = failedGap < 30000 ? 'red' : 'grey'
- const isStoppable = ['Started', 'Suspended'].includes(t.state);
- const isSuspendable = t.state === 'Started';
- const isStartable = t.state === 'Stopped';
- const isResumable = t.state === 'Suspended';
- const colorDanger = 'var(--pf-t--global--icon--color--status--danger--default)';
- const colorWarning = 'var(--pf-t--global--icon--color--status--warning--default)';
- const colorNormal = 'var(--pf-t--global--color--brand--default)';
- const colorState = t.state === 'Started' ? 'green' : (t.state === 'Stopped' ? 'red' : 'yellow');
- return (
- <Tr key={t.routeId} style={{verticalAlign: "middle"}}>
- <Td>{t.routeId}</Td>
- <Td>{t.description}</Td>
- <Td><Label color={colorState}>{t.state}</Label></Td>
- <Td>{t.uptime}</Td>
- <Td>{t.from}</Td>
- <Td>{t.statistics.exchangesTotal}</Td>
- <Td>{t.statistics.exchangesInflight}</Td>
- <Td>{t.statistics.exchangesFailed}</Td>
- <Td> {date &&
- <Tooltip content={dateString} position={'left'}>
- <Label color={failedColor}>{`${date} ago`}</Label>
- </Tooltip>
- }
- </Td>
- <Td style={{paddingInlineEnd: '0.5rem'}}>
- <div style={{display: "flex", flexDirection: "row", justifyContent: "space-between", width: "fit-content"}}>
- {isSuspendable && <Button variant={'plain'} icon={<PauseIcon color={colorWarning}/>}
- onClick={_ => execRouteAction(t.routeId, "suspend")}/>}
- {isResumable && <Button variant={'plain'} icon={<PlayIcon color={colorNormal}/>}
- onClick={_ => execRouteAction(t.routeId, "resume")}/>}
- {isStoppable && <Button variant={'plain'} icon={<StopIcon color={colorDanger}/>}
- onClick={_ => execRouteAction(t.routeId, "stop")}/>}
- {isStartable && <Button variant={'plain'} icon={<PlayIcon color={colorNormal}/>}
- onClick={_ => execRouteAction(t.routeId, "start")}/>}
- </div>
- </Td>
- </Tr>
- )
- })}
- </Tbody>
- </Table>
- </div>
- }
- </div>
- );
-}
diff --git a/karavan-app/src/main/webui/src/integration-runtime/RuntimePanel.tsx b/karavan-app/src/main/webui/src/integration-runtime/RuntimePanel.tsx
index 3c22ca5b..f7e8c674 100644
--- a/karavan-app/src/main/webui/src/integration-runtime/RuntimePanel.tsx
+++ b/karavan-app/src/main/webui/src/integration-runtime/RuntimePanel.tsx
@@ -7,12 +7,8 @@ import {shallow} from "zustand/shallow";
import {ProjectEventBus} from "@/api/ProjectEventBus";
import {ProjectLogTab} from "./ProjectLogTab";
import {LogWatchApi} from "@/api/LogWatchApi";
-import {PodEventsLogTab} from "./PodEventsLogTab";
-import {MainConfigLogTab} from "./MainConfigLogTab";
import {InformationTab} from "./InformationTab";
import {LogViewerSearch} from '@patternfly/react-log-viewer';
-import {ThreadsTab} from "@/integration-runtime/ThreadsTab";
-import {RoutesTab} from "@/integration-runtime/RoutesTab";
const INITIAL_LOG_HEIGHT = "50%";
@@ -62,10 +58,6 @@ export function RuntimePanel() {
<NavList>
<NavItem preventDefault key={'info'} itemId={'info'} isActive={tab === 'info'} to={`#`}>Information</NavItem>
<NavItem preventDefault key={'log'} itemId={'log'} isActive={tab === 'log'} to={`#`}>Log</NavItem>
- <NavItem preventDefault key={'routes'} itemId={'routes'} isActive={tab === 'routes'} to={`#`}>Routes</NavItem>
- {showMain && <NavItem preventDefault key={'main-configuration'} itemId={'main-configuration'} isActive={tab === 'main-configuration'} to={`#`}>Main Configuration</NavItem>}
- {showMain && <NavItem preventDefault key={'threads'} itemId={'threads'} isActive={tab === 'threads'} to={`#`}>Threads</NavItem>}
- {isKubernetes && <NavItem preventDefault key={'events'} itemId={'events'} isActive={tab === 'events'} to={`#`}>Events</NavItem>}
</NavList>
</Nav>
);
@@ -113,10 +105,6 @@ export function RuntimePanel() {
<div className="project-log" style={{height: height}}>
{tab === 'info' && currentPodName && <InformationTab currentPodName={currentPodName} header={getButtons()}/>}
{tab === 'log' && <ProjectLogTab autoScroll={autoScroll} isTextWrapped={isTextWrapped} header={getButtons()}/>}
- {tab === 'events' && currentPodName && <PodEventsLogTab currentPodName={currentPodName} header={getButtons()}/>}
- {tab === 'main-configuration' && currentPodName && <MainConfigLogTab currentPodName={currentPodName} header={getButtons()}/>}
- {tab === 'threads' && currentPodName && <ThreadsTab currentPodName={currentPodName} header={getButtons()}/>}
- {tab === 'routes' && currentPodName && <RoutesTab currentPodName={currentPodName} header={getButtons()}/>}
</div>
: <></>);
}
diff --git a/karavan-app/src/main/webui/src/integration-runtime/ThreadsTab.tsx b/karavan-app/src/main/webui/src/integration-runtime/ThreadsTab.tsx
deleted file mode 100644
index 9ae8cb3a..00000000
--- a/karavan-app/src/main/webui/src/integration-runtime/ThreadsTab.tsx
+++ /dev/null
@@ -1,61 +0,0 @@
-import React from 'react';
-import './ProjectLog.css';
-import {Table, Tbody, Td, Th, Thead, Tr} from "@patternfly/react-table";
-import {useProjectStore} from "@/api/ProjectStore";
-import {Bullseye, Spinner} from "@patternfly/react-core";
-
-interface Props {
- currentPodName: string
- header?: React.ReactNode
-}
-
-export function ThreadsTab (props: Props) {
-
- const camelStatuses = useProjectStore((state) => state.camelStatuses);
- const thread = camelStatuses[0]?.statuses.find(s => s.name === 'thread');
- const statusText = thread?.status;
- const status = statusText !== undefined ? JSON.parse(statusText) : {};
- const threads = status?.thread?.threads;
- const show = threads !== undefined && Array.isArray(threads);
-
- return (
- <div style={{display: "flex", flexDirection:"column", position: "relative", height: "100%", backgroundColor: "var(--pf-t--global--background--color--primary--default)"}}>
- {props.header}
- {!show && <Bullseye height={'100%'}><Spinner></Spinner></Bullseye>}
- {show &&
- <div style={{overflow: "auto"}}>
- <Table aria-label="Main configuration table" height={"100vh"} variant='compact'>
- <Thead>
- <Tr>
- <Th modifier='nowrap'>Id</Th>
- <Th modifier='nowrap'>Name</Th>
- <Th modifier='nowrap'>State</Th>
- <Th modifier='nowrap'>Blocked Count</Th>
- <Th modifier='nowrap'>Blocked Time</Th>
- <Th modifier='nowrap'>Lock Name</Th>
- <Th modifier='nowrap'>Waited Count</Th>
- <Th modifier='nowrap'>Waited Time</Th>
- </Tr>
- </Thead>
- <Tbody className='event-table'>
- {threads.map((t) => {
- return (
- <Tr key={t.id}>
- <Td>{t.id}</Td>
- <Td>{t.name}</Td>
- <Td>{t.state}</Td>
- <Td>{t.blockedCount}</Td>
- <Td>{t.blockedTime}</Td>
- <Td>{t.lockName}</Td>
- <Td>{t.waitedCount}</Td>
- <Td>{t.waitedTime}</Td>
- </Tr>
- )
- })}
- </Tbody>
- </Table>
- </div>
- }
- </div>
- );
-}