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>
-    );
-}