From 363c6518ed99b487dff7b98be062ebb8263435b3 Mon Sep 17 00:00:00 2001 From: mmelko Date: Mon, 24 Jun 2024 15:55:30 +0200 Subject: [PATCH] feat(camel-source): Make Source editor editable when it's enabled in the CamelContext --- .../src/plugins/camel/routes/Source.tsx | 65 +++++++++++++++++-- .../plugins/camel/routes/routes-service.ts | 16 +++++ 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/packages/hawtio/src/plugins/camel/routes/Source.tsx b/packages/hawtio/src/plugins/camel/routes/Source.tsx index beeed59f..2d6c4e4e 100644 --- a/packages/hawtio/src/plugins/camel/routes/Source.tsx +++ b/packages/hawtio/src/plugins/camel/routes/Source.tsx @@ -1,24 +1,81 @@ import { CamelContext } from '@hawtiosrc/plugins/camel/context' -import { CodeEditor, Language } from '@patternfly/react-code-editor' +import { CodeEditor, CodeEditorControl, Language } from '@patternfly/react-code-editor' import React, { useContext, useEffect, useState } from 'react' import { log } from '../globals' +import { CheckCircleIcon, SaveIcon } from '@patternfly/react-icons' +import { isRouteNode, isRoutesFolder } from '@hawtiosrc/plugins/camel/camel-service' +import { routesService } from './routes-service' +import { eventService } from '@hawtiosrc/core' export const Source: React.FunctionComponent = () => { const { selectedNode } = useContext(CamelContext) const [xmlSource, setXmlSource] = useState('') + const [isUpdateEnabled, setIsUpdateEnabled] = useState(false) + const [codeChanged, setCodeChanged] = useState(false) + const isRoute: boolean = isRouteNode(selectedNode!) && !isRoutesFolder(selectedNode!) useEffect(() => { - const xml = selectedNode?.getMetadata('xml') + if (!selectedNode) return + + const xml = selectedNode.getMetadata('xml') + + if (isRoute) { + routesService.isRouteUpdateEnabled(selectedNode).then(enabled => { + setIsUpdateEnabled(enabled) + }) + } + if (xml) { setXmlSource(xml) } else { log.warn('Source - Unable to fetch XML from', selectedNode) } - }, [selectedNode]) + }, [isRoute, selectedNode]) + + //SelectedNode should be always selected when this view is routed + if (!selectedNode) { + return + } + + const onCodeChange = (code: string) => { + setCodeChanged(code !== xmlSource) + } + + const onSaveClick = (code: string) => { + if (isRoute && code !== xmlSource) { + try { + routesService.saveRoute(selectedNode, code) + setCodeChanged(false) + eventService.notify({ + type: 'success', + message: 'Route was updated', + }) + } catch (e) { + eventService.notify({ type: 'danger', message: 'Failed to save route' }) + } + } + } + + const saveButton = ( + : } + isVisible={isUpdateEnabled} + aria-label='Execute code' + tooltipProps={{ content: codeChanged ? 'Save source' : 'Saved' }} + onClick={onSaveClick} + /> + ) return (
- +
) } diff --git a/packages/hawtio/src/plugins/camel/routes/routes-service.ts b/packages/hawtio/src/plugins/camel/routes/routes-service.ts index 09b04fc6..db931ef0 100644 --- a/packages/hawtio/src/plugins/camel/routes/routes-service.ts +++ b/packages/hawtio/src/plugins/camel/routes/routes-service.ts @@ -7,6 +7,8 @@ export const ROUTE_OPERATIONS = { start: 'start()', stop: 'stop()', remove: 'remove()', + isUpdateEnabled: 'isUpdateRouteEnabled()', + updateRoute: 'updateRouteFromXml', } as const interface IRoutesService { @@ -89,12 +91,26 @@ class RoutesService implements IRoutesService { return node.hasInvokeRights(ROUTE_OPERATIONS.remove) } + async isRouteUpdateEnabled(node: MBeanNode): Promise { + const { objectName } = node + if (!objectName) return false + + return (await jolokiaService.execute(objectName, ROUTE_OPERATIONS.isUpdateEnabled)) as boolean + } + async deleteRoute(node: MBeanNode) { const { objectName } = node if (!objectName) return await jolokiaService.execute(objectName, ROUTE_OPERATIONS.remove) } + + saveRoute(node: MBeanNode, code: string) { + const { objectName } = node + if (!objectName) return + + jolokiaService.execute(objectName, ROUTE_OPERATIONS.updateRoute, [code]) + } } export const routesService = new RoutesService()