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/12/18 22:26:38 UTC

(camel-karavan) branch main updated: Fix #1008

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 2560e36e Fix #1008
2560e36e is described below

commit 2560e36e63c900d8c278a91f46ea398f16135774
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Mon Dec 18 17:26:31 2023 -0500

    Fix #1008
---
 karavan-core/src/core/api/CamelDefinitionApiExt.ts | 18 +++++++
 karavan-core/src/core/model/CamelMetadata.ts       | 14 +++++
 karavan-designer/public/example/demo.camel.yaml    | 40 +++++++--------
 karavan-designer/src/designer/beans/BeanCard.tsx   |  8 ++-
 .../src/designer/beans/BeansDesigner.tsx           | 25 ++++-----
 .../src/designer/kamelet/KameletDesigner.tsx       |  2 +-
 .../designer/{route => property}/DslProperties.css |  0
 .../designer/{route => property}/DslProperties.tsx | 11 ++--
 .../property}/BeanProperties.tsx                   | 60 +++++-----------------
 .../property/ComponentParameterField.tsx           |  0
 .../property/DataFormatField.tsx                   |  0
 .../property/DslPropertyField.css                  |  0
 .../property/DslPropertyField.tsx                  | 26 ++++++++--
 .../property/ExpressionField.tsx                   |  0
 .../property/InfrastructureSelector.tsx            |  0
 .../property/KameletPropertyField.tsx              |  0
 .../{route => property}/property/ModalEditor.tsx   |  0
 .../{route => property}/property/ObjectField.tsx   |  0
 .../{route => property}/usePropertiesHook.tsx      | 25 +++++++--
 .../src/designer/rest/RestDesigner.tsx             |  4 +-
 .../src/designer/route/RouteDesigner.tsx           |  4 +-
 .../src/topology/TopologyPropertiesPanel.tsx       |  4 +-
 .../camel/karavan/generator/AbstractGenerator.java | 11 ++++
 .../karavan/generator/CamelMetadataGenerator.java  | 24 +++++++--
 karavan-space/src/designer/beans/BeanCard.tsx      |  8 ++-
 karavan-space/src/designer/beans/BeansDesigner.tsx | 25 ++++-----
 .../src/designer/kamelet/KameletDesigner.tsx       |  2 +-
 .../src/designer/property}/DslProperties.css       |  0
 .../src/designer/property}/DslProperties.tsx       | 11 ++--
 .../designer/property/property}/BeanProperties.tsx | 60 +++++-----------------
 .../property}/property/ComponentParameterField.tsx |  0
 .../property}/property/DataFormatField.tsx         |  0
 .../property}/property/DslPropertyField.css        |  0
 .../property}/property/DslPropertyField.tsx        | 26 ++++++++--
 .../property}/property/ExpressionField.tsx         |  0
 .../property}/property/InfrastructureSelector.tsx  |  0
 .../property}/property/KameletPropertyField.tsx    |  0
 .../designer/property}/property/ModalEditor.tsx    |  0
 .../designer/property}/property/ObjectField.tsx    |  0
 .../src/designer/property}/usePropertiesHook.tsx   | 25 +++++++--
 karavan-space/src/designer/rest/RestDesigner.tsx   |  4 +-
 karavan-space/src/designer/route/RouteDesigner.tsx |  4 +-
 .../src/topology/TopologyPropertiesPanel.tsx       |  4 +-
 .../webview/topology/TopologyPropertiesPanel.tsx   |  4 +-
 .../src/main/webui/src/designer/beans/BeanCard.tsx |  8 ++-
 .../webui/src/designer/beans/BeansDesigner.tsx     | 25 ++++-----
 .../webui/src/designer/kamelet/KameletDesigner.tsx |  2 +-
 .../webui/src/designer/property}/DslProperties.css |  0
 .../webui/src/designer/property}/DslProperties.tsx | 11 ++--
 .../designer/property/property}/BeanProperties.tsx | 60 +++++-----------------
 .../property}/property/ComponentParameterField.tsx |  0
 .../property}/property/DataFormatField.tsx         |  0
 .../property}/property/DslPropertyField.css        |  0
 .../property}/property/DslPropertyField.tsx        | 26 ++++++++--
 .../property}/property/ExpressionField.tsx         |  0
 .../property}/property/InfrastructureSelector.tsx  |  0
 .../property}/property/KameletPropertyField.tsx    |  0
 .../designer/property}/property/ModalEditor.tsx    |  0
 .../designer/property}/property/ObjectField.tsx    |  0
 .../src/designer/property}/usePropertiesHook.tsx   | 25 +++++++--
 .../main/webui/src/designer/rest/RestDesigner.tsx  |  4 +-
 .../webui/src/designer/route/RouteDesigner.tsx     |  4 +-
 .../webui/src/topology/TopologyPropertiesPanel.tsx |  4 +-
 63 files changed, 339 insertions(+), 279 deletions(-)

diff --git a/karavan-core/src/core/api/CamelDefinitionApiExt.ts b/karavan-core/src/core/api/CamelDefinitionApiExt.ts
index f9372830..4ea7dc16 100644
--- a/karavan-core/src/core/api/CamelDefinitionApiExt.ts
+++ b/karavan-core/src/core/api/CamelDefinitionApiExt.ts
@@ -600,6 +600,24 @@ export class CamelDefinitionApiExt {
         return int;
     };
 
+    static updateIntegrationBeanElement = (integration: Integration, e: CamelElement): Integration => {
+        const elementClone = CamelUtil.cloneStep(e);
+        const int: Integration = CamelUtil.cloneIntegration(integration);
+        const flows: CamelElement[] = [];
+
+        for (const flow of integration.spec.flows ?? []) {
+            if (flow.dslName === 'Beans') {
+                const route = CamelDefinitionApiExt.updateElement(flow, elementClone) as RegistryBeanDefinition;
+                flows.push(CamelDefinitionApi.createRegistryBeanDefinition(route));
+            } else {
+                flows.push(flow);
+            }
+        }
+
+        int.spec.flows = flows;
+        return int;
+    };
+
     static updateElement = (element: CamelElement, e: CamelElement): CamelElement => {
         if (element.uuid === e.uuid) {
             return e;
diff --git a/karavan-core/src/core/model/CamelMetadata.ts b/karavan-core/src/core/model/CamelMetadata.ts
index 8722364e..5f647778 100644
--- a/karavan-core/src/core/model/CamelMetadata.ts
+++ b/karavan-core/src/core/model/CamelMetadata.ts
@@ -1873,6 +1873,20 @@ export const CamelModelMetadata: ElementMeta[] = [
     new ElementMeta('value', 'ValueDefinition', 'Value', "A single value", 'configuration', [
         new PropertyMeta('value', 'Value', "Property value", 'string', '', '', true, false, false, false, '', '', false),
     ]),
+    new ElementMeta('registryBean', 'RegistryBeanDefinition', 'Bean', "Define custom beans that can be used in your Camel routes and in general.", 'configuration', [
+        new PropertyMeta('name', 'Name', "The name of the bean (bean id)", 'string', '', '', true, false, false, false, '', '', false),
+        new PropertyMeta('type', 'Type', "The class name (fully qualified) of the bean", 'string', '', '', true, false, false, false, '', '', false),
+        new PropertyMeta('initMethod', 'Init Method', "The name of the custom initialization method to invoke after setting bean properties. The method must have no arguments, but may throw any exception.", 'string', '', '', false, false, false, false, '', '', false),
+        new PropertyMeta('destroyMethod', 'Destroy Method', "The name of the custom destroy method to invoke on bean shutdown, such as when Camel is shutting down. The method must have no arguments, but may throw any exception.", 'string', '', '', false, false, false, false, '', '', false),
+        new PropertyMeta('factoryMethod', 'Factory Method', "Name of method to invoke when creating the bean via a factory bean.", 'string', '', '', false, false, false, false, '', '', false),
+        new PropertyMeta('factoryBean', 'Factory Bean', "Name of factory bean (bean id) to use for creating the bean.", 'string', '', '', false, false, false, false, '', '', false),
+        new PropertyMeta('builderClass', 'Builder Class', "Fully qualified class name of builder class to use for creating and configuring the bean. The builder will use the properties values to configure the bean.", 'string', '', '', false, false, false, false, '', '', false),
+        new PropertyMeta('builderMethod', 'Builder Method', "Name of method when using builder class. This method is invoked after configuring to create the actual bean. This method is often named build (used by default).", 'string', '', 'build', false, false, false, false, '', '', false),
+        new PropertyMeta('scriptLanguage', 'Script Language', "The script language to use when using inlined script for creating the bean, such as groovy, java, javascript etc.", 'string', '', '', false, false, false, false, 'advanced', '', false),
+        new PropertyMeta('constructors', 'Constructors', "Optional constructor arguments for creating the bean. Arguments correspond to specific index of the constructor argument list, starting from zero.", 'object', '', '', false, false, false, false, '', '', false),
+        new PropertyMeta('properties', 'Properties', "Optional properties to set on the created bean.", 'object', '', '', false, false, false, false, '', '', false),
+        new PropertyMeta('script', 'Script', "The script to execute that creates the bean when using scripting languages. If the script use the prefix resource: such as resource:classpath:com/foo/myscript.groovy, resource:file:/var/myscript.groovy, then its loaded from the external resource.", 'string', '', '', false, false, false, false, 'advanced', '', false),
+    ]),
     new ElementMeta('serviceCallConfiguration', 'ServiceCallConfigurationDefinition', 'Service Call Configuration', "Remote service call configuration", 'routing,cloud', [
         new PropertyMeta('id', 'Id', "The id of this node", 'string', '', '', false, false, false, false, '', '', false),
         new PropertyMeta('expression', 'Expression', "Configures the Expression using the given configuration.", 'ExpressionDefinition', '', '', false, false, false, true, '', '', false),
diff --git a/karavan-designer/public/example/demo.camel.yaml b/karavan-designer/public/example/demo.camel.yaml
index 2e125534..5f3d364c 100644
--- a/karavan-designer/public/example/demo.camel.yaml
+++ b/karavan-designer/public/example/demo.camel.yaml
@@ -1,23 +1,23 @@
-- route:
-    nodePrefixId: route-1e7
-    id: route-3f85
-    from:
-      uri: timer
-      id: from-cfa5
-      steps:
-        - choice:
-            when:
-              - expression:
-                  simple:
-                    id: simple-d546
-                id: when-f549
-            otherwise:
-              id: otherwise-cda7
-            id: choice-50fe
-- rest:
-    id: rest-2333
-    put:
-      - id: put-5a13
+#- route:
+#    nodePrefixId: route-1e7
+#    id: route-3f85
+#    from:
+#      uri: timer
+#      id: from-cfa5
+#      steps:
+#        - choice:
+#            when:
+#              - expression:
+#                  simple:
+#                    id: simple-d546
+#                id: when-f549
+#            otherwise:
+#              id: otherwise-cda7
+#            id: choice-50fe
+#- rest:
+#    id: rest-2333
+#    put:
+#      - id: put-5a13
 - beans:
     - constructors: {}
     - constructors: {}
diff --git a/karavan-designer/src/designer/beans/BeanCard.tsx b/karavan-designer/src/designer/beans/BeanCard.tsx
index 7a6d77b0..36d7822e 100644
--- a/karavan-designer/src/designer/beans/BeanCard.tsx
+++ b/karavan-designer/src/designer/beans/BeanCard.tsx
@@ -20,20 +20,18 @@ import {
 } from '@patternfly/react-core';
 import './bean.css';
 import {RegistryBeanDefinition} from "karavan-core/lib/model/CamelDefinition";
-import {useDesignerStore} from "../DesignerStore";
-import {shallow} from "zustand/shallow";
 import {DeleteElementIcon} from "../utils/ElementIcons";
+import {CamelElement} from "karavan-core/lib/model/IntegrationDefinition";
 
 interface Props {
     bean: RegistryBeanDefinition
+    selectedStep?: CamelElement
     selectElement: (element: RegistryBeanDefinition) => void
     deleteElement: (element: RegistryBeanDefinition) => void
 }
 
 export function BeanCard (props: Props) {
 
-    const [ selectedStep] = useDesignerStore((s) => [s.selectedStep], shallow)
-
     function selectElement (evt: React.MouseEvent) {
         evt.stopPropagation();
         props.selectElement(props.bean);
@@ -47,7 +45,7 @@ export function BeanCard (props: Props) {
     const bean = props.bean;
     return (
         <Flex direction={{default: "row"}}
-              className={selectedStep?.uuid === bean.uuid ? "bean-card bean-card-selected" : "bean-card bean-card-unselected"}
+              className={props.selectedStep?.uuid === bean.uuid ? "bean-card bean-card-selected" : "bean-card bean-card-unselected"}
               onClick={e => selectElement(e)}
         >
             <FlexItem flex={{default:"flex_1"}} className="title">Bean</FlexItem>
diff --git a/karavan-designer/src/designer/beans/BeansDesigner.tsx b/karavan-designer/src/designer/beans/BeansDesigner.tsx
index ceca2c21..8ef5c4a8 100644
--- a/karavan-designer/src/designer/beans/BeansDesigner.tsx
+++ b/karavan-designer/src/designer/beans/BeansDesigner.tsx
@@ -30,18 +30,18 @@ import {RegistryBeanDefinition} from "karavan-core/lib/model/CamelDefinition";
 import {CamelUi} from "../utils/CamelUi";
 import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
 import {CamelDefinitionApiExt} from "karavan-core/lib/api/CamelDefinitionApiExt";
-import {BeanProperties} from "./BeanProperties";
 import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
 import {BeanCard} from "./BeanCard";
 import {useDesignerStore, useIntegrationStore} from "../DesignerStore";
 import {shallow} from "zustand/shallow";
+import {DslProperties} from "../property/DslProperties";
 
 export function BeansDesigner() {
 
     const [integration, setIntegration] = useIntegrationStore((s) => [s.integration, s.setIntegration], shallow)
-    const [dark, selectedStep, showDeleteConfirmation, setShowDeleteConfirmation, setSelectedStep, setNotification]
+    const [selectedStep, showDeleteConfirmation, setShowDeleteConfirmation, setSelectedStep, setNotification]
         = useDesignerStore((s) =>
-        [s.dark, s.selectedStep, s.showDeleteConfirmation, s.setShowDeleteConfirmation, s.setSelectedStep, s.setNotification], shallow)
+        [s.selectedStep, s.showDeleteConfirmation, s.setShowDeleteConfirmation, s.setSelectedStep, s.setNotification], shallow)
 
     useEffect(() => {
         return () => {
@@ -61,12 +61,7 @@ export function BeansDesigner() {
         setSelectedStep(undefined);
     }
 
-    function changeBean(bean: RegistryBeanDefinition) {
-        const clone = CamelUtil.cloneIntegration(integration);
-        const i = CamelDefinitionApiExt.addBeanToIntegration(clone, bean);
-        setIntegration(i, false);
-        setSelectedStep(bean);
-    }
+
 
     function getDeleteConfirmation() {
         return (<Modal
@@ -98,7 +93,11 @@ export function BeansDesigner() {
     };
 
     function createBean() {
-        changeBean(new RegistryBeanDefinition());
+        const bean = new RegistryBeanDefinition();
+        const clone = CamelUtil.cloneIntegration(integration);
+        const i = CamelDefinitionApiExt.addBeanToIntegration(clone, bean);
+        setIntegration(i, false);
+        setSelectedStep(bean);
     }
 
     function getPropertiesPanel() {
@@ -108,10 +107,7 @@ export function BeansDesigner() {
                                 defaultSize={'400px'}
                                 maxSize={'800px'}
                                 minSize={'400px'}>
-                <BeanProperties integration={integration}
-                                dark={dark}
-                                onChange={changeBean}
-                                onClone={changeBean}/>
+                <DslProperties designerType={'beans'}/>
             </DrawerPanelContent>
         )
     }
@@ -131,6 +127,7 @@ export function BeansDesigner() {
                             {beans?.map((bean, index) => (
                                 <GalleryItem key={bean.uuid + index}>
                                     <BeanCard bean={bean}
+                                              selectedStep={selectedStep}
                                               selectElement={selectBean}
                                               deleteElement={onShowDeleteConfirmation}
                                     />
diff --git a/karavan-designer/src/designer/kamelet/KameletDesigner.tsx b/karavan-designer/src/designer/kamelet/KameletDesigner.tsx
index c235ef9b..4d2122f1 100644
--- a/karavan-designer/src/designer/kamelet/KameletDesigner.tsx
+++ b/karavan-designer/src/designer/kamelet/KameletDesigner.tsx
@@ -33,7 +33,7 @@ import {CamelDefinitionApiExt} from "karavan-core/lib/api/CamelDefinitionApiExt"
 import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
 import {useDesignerStore, useIntegrationStore} from "../DesignerStore";
 import {shallow} from "zustand/shallow";
-import {BeanProperties} from "../beans/BeanProperties";
+import {BeanProperties} from "../property/property/BeanProperties";
 import {BeanCard} from "../beans/BeanCard";
 import {KameletAnnotationsPanel} from "./KameletAnnotationsPanel";
 import {KameletDefinitionsPanel} from "./KameletDefinitionsPanel";
diff --git a/karavan-designer/src/designer/route/DslProperties.css b/karavan-designer/src/designer/property/DslProperties.css
similarity index 100%
copy from karavan-designer/src/designer/route/DslProperties.css
copy to karavan-designer/src/designer/property/DslProperties.css
diff --git a/karavan-designer/src/designer/route/DslProperties.tsx b/karavan-designer/src/designer/property/DslProperties.tsx
similarity index 96%
copy from karavan-designer/src/designer/route/DslProperties.tsx
copy to karavan-designer/src/designer/property/DslProperties.tsx
index b958b2b3..212a5f68 100644
--- a/karavan-designer/src/designer/route/DslProperties.tsx
+++ b/karavan-designer/src/designer/property/DslProperties.tsx
@@ -38,17 +38,18 @@ import {usePropertiesHook} from "./usePropertiesHook";
 import {CamelDisplayUtil} from "karavan-core/lib/api/CamelDisplayUtil";
 
 interface Props {
-    isRouteDesigner: boolean
+    designerType: 'routes' | 'rest' | 'beans'
 }
 
 export function DslProperties(props: Props) {
 
-    const [integration] = useIntegrationStore((state) => [state.integration], shallow)
+    const [integration] = useIntegrationStore((s) => [s.integration], shallow)
 
     const {convertStep, cloneElement, onDataFormatChange, onPropertyChange, onParametersChange, onExpressionChange} =
-        usePropertiesHook(props.isRouteDesigner);
+        usePropertiesHook(props.designerType);
 
-    const [selectedStep, dark] = useDesignerStore((s) => [s.selectedStep, s.dark], shallow)
+    const [selectedStep, dark]
+        = useDesignerStore((s) => [s.selectedStep, s.dark], shallow)
 
     const [showAdvanced, setShowAdvanced] = useState<boolean>(false);
     const [isDescriptionExpanded, setIsDescriptionExpanded] = useState<boolean>(false);
@@ -109,7 +110,7 @@ export function DslProperties(props: Props) {
     }
 
     function getComponentHeader(): JSX.Element {
-        if (props.isRouteDesigner) return getRouteHeader()
+        if (props.designerType === 'routes') return getRouteHeader()
         else return getClonableElementHeader();
     }
 
diff --git a/karavan-designer/src/designer/beans/BeanProperties.tsx b/karavan-designer/src/designer/property/property/BeanProperties.tsx
similarity index 84%
copy from karavan-designer/src/designer/beans/BeanProperties.tsx
copy to karavan-designer/src/designer/property/property/BeanProperties.tsx
index c3147828..2322d8f4 100644
--- a/karavan-designer/src/designer/beans/BeanProperties.tsx
+++ b/karavan-designer/src/designer/property/property/BeanProperties.tsx
@@ -16,37 +16,32 @@
  */
 import React, {useEffect, useState} from 'react';
 import {
-    Form,
     FormGroup,
-    TextInput, Button, Title, Tooltip, Popover, InputGroup, InputGroupItem, capitalize,
+    TextInput, Button, Tooltip, Popover, InputGroup, InputGroupItem, capitalize,
 } from '@patternfly/react-core';
-import '../karavan.css';
+import '../../karavan.css';
 import "@patternfly/patternfly/patternfly.css";
 import {
     RegistryBeanDefinition,
 } from "karavan-core/lib/model/CamelDefinition";
-import {Integration} from "karavan-core/lib/model/IntegrationDefinition";
 import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
 import {SensitiveKeys} from "karavan-core/lib/model/CamelMetadata";
 import {v4 as uuidv4} from "uuid";
 import DeleteIcon from "@patternfly/react-icons/dist/js/icons/times-icon";
 import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-circle-icon";
-import CloneIcon from '@patternfly/react-icons/dist/esm/icons/clone-icon'
 import HelpIcon from "@patternfly/react-icons/dist/js/icons/help-icon";
-import {InfrastructureSelector} from "../route/property/InfrastructureSelector";
-import {InfrastructureAPI} from "../utils/InfrastructureAPI";
+import {InfrastructureSelector} from "./InfrastructureSelector";
+import {InfrastructureAPI} from "../../utils/InfrastructureAPI";
 import ShowIcon from "@patternfly/react-icons/dist/js/icons/eye-icon";
 import HideIcon from "@patternfly/react-icons/dist/js/icons/eye-slash-icon";
 import DockerIcon from "@patternfly/react-icons/dist/js/icons/docker-icon";
-import {useDesignerStore} from "../DesignerStore";
+import {useDesignerStore} from "../../DesignerStore";
 import {shallow} from "zustand/shallow";
-import {IntegrationHeader} from "../utils/IntegrationHeader";
-import {KubernetesIcon} from "../icons/ComponentIcons";
+import {KubernetesIcon} from "../../icons/ComponentIcons";
 
 
 interface Props {
-    integration: Integration
-    dark: boolean
+    type: 'constructors' | 'properties'
     onChange: (bean: RegistryBeanDefinition) => void
     onClone: (bean: RegistryBeanDefinition) => void
 }
@@ -202,7 +197,7 @@ export function BeanProperties (props: Props) {
 
     function getBeanConstructors() {
         return (
-            <FormGroup label="Constructors" fieldId="constructors" className="bean-properties">
+            <>
                 {Array.from(constructors.entries()).map((v, index, array) => {
                     const i = v[0];
                     const key = v[1][0];
@@ -244,13 +239,13 @@ export function BeanProperties (props: Props) {
                 })}
                 <Button variant="link" className="add-button" onClick={e => constructorChanged(uuidv4(), constructors.size, '', false)}>
                     <AddIcon/>Add argument</Button>
-            </FormGroup>
+            </>
         )
     }
 
     function getBeanProperties() {
         return (
-                <FormGroup label="Properties" fieldId="properties" className="bean-properties">
+                <>
                     {Array.from(properties.entries()).map((v, index, array) => {
                         const i = v[0];
                         const key = v[1][0];
@@ -298,44 +293,15 @@ export function BeanProperties (props: Props) {
                     })}
                     <Button variant="link" className="add-button" onClick={e => propertyChanged(uuidv4(), '', '', false)}>
                         <AddIcon/>Add property</Button>
-                </FormGroup>
-        )
-    }
-
-
-    function getBeanForm() {
-        const bean = (selectedStep as RegistryBeanDefinition);
-        return (
-            <>
-                <div className="headers">
-                    <div className="top">
-                        <Title headingLevel="h1" size="md">Bean</Title>
-                        <Tooltip content="Clone bean" position="bottom">
-                            <Button variant="link" onClick={() => cloneBean()} icon={<CloneIcon/>}/>
-                        </Tooltip>
-                    </div>
-                </div>
-                <FormGroup label="Name" fieldId="name" isRequired labelIcon={getLabelIcon("Name", "Bean name used as a reference ex: myBean")}>
-                    <TextInput className="text-field" isRequired type="text" id="name" name="name" value={bean?.name}
-                                onChange={(_, value)=> beanFieldChanged("name", value)}/>
-                </FormGroup>
-                <FormGroup label="Type" fieldId="type" isRequired labelIcon={getLabelIcon("Type", "Bean class Canonical Name ex: org.demo.MyBean")}>
-                    <TextInput className="text-field" isRequired type="text" id="type" name="type" value={bean?.type}
-                        onChange={(_, value) => beanFieldChanged("type", value)}/>
-                </FormGroup>
-                {getBeanConstructors()}
-                {getBeanProperties()}
-            </>
+                </>
         )
     }
 
     const bean = (selectedStep as RegistryBeanDefinition);
     return (
         <div className='properties' key={bean ? bean.uuid : 'integration'}>
-            <Form autoComplete="off" onSubmit={event => event.preventDefault()}>
-                {bean === undefined && <IntegrationHeader/>}
-                {bean !== undefined && getBeanForm()}
-            </Form>
+            {props.type === 'constructors' && getBeanConstructors()}
+            {props.type === 'properties' && getBeanProperties()}
             {getInfrastructureSelectorModal()}
         </div>
     )
diff --git a/karavan-designer/src/designer/route/property/ComponentParameterField.tsx b/karavan-designer/src/designer/property/property/ComponentParameterField.tsx
similarity index 100%
copy from karavan-designer/src/designer/route/property/ComponentParameterField.tsx
copy to karavan-designer/src/designer/property/property/ComponentParameterField.tsx
diff --git a/karavan-designer/src/designer/route/property/DataFormatField.tsx b/karavan-designer/src/designer/property/property/DataFormatField.tsx
similarity index 100%
copy from karavan-designer/src/designer/route/property/DataFormatField.tsx
copy to karavan-designer/src/designer/property/property/DataFormatField.tsx
diff --git a/karavan-designer/src/designer/route/property/DslPropertyField.css b/karavan-designer/src/designer/property/property/DslPropertyField.css
similarity index 100%
copy from karavan-designer/src/designer/route/property/DslPropertyField.css
copy to karavan-designer/src/designer/property/property/DslPropertyField.css
diff --git a/karavan-designer/src/designer/route/property/DslPropertyField.tsx b/karavan-designer/src/designer/property/property/DslPropertyField.tsx
similarity index 96%
copy from karavan-designer/src/designer/route/property/DslPropertyField.tsx
copy to karavan-designer/src/designer/property/property/DslPropertyField.tsx
index f092a795..e138a88a 100644
--- a/karavan-designer/src/designer/route/property/DslPropertyField.tsx
+++ b/karavan-designer/src/designer/property/property/DslPropertyField.tsx
@@ -68,9 +68,14 @@ import {ModalEditor} from "./ModalEditor";
 import DockerIcon from "@patternfly/react-icons/dist/js/icons/docker-icon";
 import {useDesignerStore, useIntegrationStore} from "../../DesignerStore";
 import {shallow} from "zustand/shallow";
-import {DataFormatDefinition, ExpressionDefinition} from "karavan-core/lib/model/CamelDefinition";
+import {
+    DataFormatDefinition,
+    ExpressionDefinition,
+    RegistryBeanDefinition
+} from "karavan-core/lib/model/CamelDefinition";
 import {TemplateApi} from "karavan-core/lib/api/TemplateApi";
 import {KubernetesIcon} from "../../icons/ComponentIcons";
+import {BeanProperties} from "./BeanProperties";
 
 interface Props {
     property: PropertyMeta,
@@ -86,8 +91,8 @@ interface Props {
 
 export function DslPropertyField(props: Props) {
 
-    const [integration] = useIntegrationStore((state) => [state.integration], shallow)
-    const [dark] = useDesignerStore((s) => [s.dark], shallow)
+    const [integration, setIntegration] = useIntegrationStore((s) => [s.integration, s.setIntegration], shallow)
+    const [dark, setSelectedStep] = useDesignerStore((s) => [s.dark, s.setSelectedStep], shallow)
 
     const [isShowAdvanced, setIsShowAdvanced] = useState<string[]>([]);
     const [arrayValues, setArrayValues] = useState<Map<string, string>>(new Map<string, string>());
@@ -748,6 +753,17 @@ export function DslPropertyField(props: Props) {
     }
 
 
+    function changeBean(bean: RegistryBeanDefinition) {
+        const clone = CamelUtil.cloneIntegration(integration);
+        const i = CamelDefinitionApiExt.addBeanToIntegration(clone, bean);
+        setIntegration(i, false);
+        setSelectedStep(bean);
+    }
+
+    function getBeanProperties(type: 'constructors' | 'properties') {
+        return <BeanProperties type={type} onChange={changeBean} onClone={changeBean}/>
+    }
+
     function isMultiValueField(property: PropertyMeta): boolean {
         return ['string'].includes(property.type) && property.name !== 'expression' && property.isArray && !property.enumVals;
     }
@@ -776,6 +792,8 @@ export function DslPropertyField(props: Props) {
     const isKamelet = CamelUtil.isKameletComponent(element);
     const property: PropertyMeta = props.property;
     const value = props.value;
+    const beanConstructors = element?.dslName === 'RegistryBeanDefinition' && property.name === 'constructors'
+    const beanProperties = element?.dslName === 'RegistryBeanDefinition' && property.name === 'properties'
     return (
         <div>
             <FormGroup
@@ -812,6 +830,8 @@ export function DslPropertyField(props: Props) {
                     && getSelect(property, value)}
                 {isKamelet && property.name === 'parameters' && getKameletParameters()}
                 {!isKamelet && property.name === 'parameters' && getComponentParameters(property)}
+                {beanConstructors && getBeanProperties('constructors')}
+                {beanProperties && getBeanProperties('properties')}
             </FormGroup>
             {getInfrastructureSelectorModal()}
         </div>
diff --git a/karavan-designer/src/designer/route/property/ExpressionField.tsx b/karavan-designer/src/designer/property/property/ExpressionField.tsx
similarity index 100%
copy from karavan-designer/src/designer/route/property/ExpressionField.tsx
copy to karavan-designer/src/designer/property/property/ExpressionField.tsx
diff --git a/karavan-designer/src/designer/route/property/InfrastructureSelector.tsx b/karavan-designer/src/designer/property/property/InfrastructureSelector.tsx
similarity index 100%
copy from karavan-designer/src/designer/route/property/InfrastructureSelector.tsx
copy to karavan-designer/src/designer/property/property/InfrastructureSelector.tsx
diff --git a/karavan-designer/src/designer/route/property/KameletPropertyField.tsx b/karavan-designer/src/designer/property/property/KameletPropertyField.tsx
similarity index 100%
copy from karavan-designer/src/designer/route/property/KameletPropertyField.tsx
copy to karavan-designer/src/designer/property/property/KameletPropertyField.tsx
diff --git a/karavan-designer/src/designer/route/property/ModalEditor.tsx b/karavan-designer/src/designer/property/property/ModalEditor.tsx
similarity index 100%
copy from karavan-designer/src/designer/route/property/ModalEditor.tsx
copy to karavan-designer/src/designer/property/property/ModalEditor.tsx
diff --git a/karavan-designer/src/designer/route/property/ObjectField.tsx b/karavan-designer/src/designer/property/property/ObjectField.tsx
similarity index 100%
copy from karavan-designer/src/designer/route/property/ObjectField.tsx
copy to karavan-designer/src/designer/property/property/ObjectField.tsx
diff --git a/karavan-designer/src/designer/route/usePropertiesHook.tsx b/karavan-designer/src/designer/property/usePropertiesHook.tsx
similarity index 84%
copy from karavan-designer/src/designer/route/usePropertiesHook.tsx
copy to karavan-designer/src/designer/property/usePropertiesHook.tsx
index a9bd9ef9..41ac95af 100644
--- a/karavan-designer/src/designer/route/usePropertiesHook.tsx
+++ b/karavan-designer/src/designer/property/usePropertiesHook.tsx
@@ -26,17 +26,19 @@ import {RouteToCreate} from "../utils/CamelUi";
 import {useDesignerStore, useIntegrationStore} from "../DesignerStore";
 import {shallow} from "zustand/shallow";
 
-export function usePropertiesHook (isRouteDesigner: boolean = true) {
+export function usePropertiesHook (designerType: 'routes' | 'rest' | 'beans' = 'routes') {
 
     const [integration, setIntegration] = useIntegrationStore((state) => [state.integration, state.setIntegration], shallow)
     const [ selectedStep, setSelectedStep, setSelectedUuids] = useDesignerStore((s) =>
         [s.selectedStep, s.setSelectedStep, s.setSelectedUuids], shallow)
 
     function onPropertyUpdate (element: CamelElement, newRoute?: RouteToCreate) {
-        if (isRouteDesigner) {
+        if (designerType === 'routes') {
             onRoutePropertyUpdate(element, newRoute);
-        } else {
+        } else if (designerType === 'rest') {
             onRestPropertyUpdate(element, newRoute);
+        } else if (designerType === 'beans') {
+            onBeanPropertyUpdate(element, newRoute);
         }
     }
 
@@ -74,6 +76,23 @@ export function usePropertiesHook (isRouteDesigner: boolean = true) {
         }
     }
 
+    function onBeanPropertyUpdate (element: CamelElement, newRoute?: RouteToCreate) {
+        if (newRoute) {
+            let i = CamelDefinitionApiExt.updateIntegrationBeanElement(integration, element);
+            const f = CamelDefinitionApi.createFromDefinition({uri: newRoute.componentName, parameters: {name: newRoute.name}});
+            const r = CamelDefinitionApi.createRouteDefinition({from: f, id: newRoute.name})
+            i = CamelDefinitionApiExt.addStepToIntegration(i, r, '');
+            const clone = CamelUtil.cloneIntegration(i);
+            setIntegration(clone, false);
+            setSelectedStep(element);
+        } else {
+            const clone = CamelUtil.cloneIntegration(integration);
+            const i = CamelDefinitionApiExt.updateIntegrationBeanElement(clone, element);
+            setIntegration(i, true);
+            // setSelectedStep(element);
+        }
+    }
+
     function onPropertyChange (fieldId: string, value: string | number | boolean | any, newRoute?: RouteToCreate){
         value = value === '' ? undefined : value;
         if (selectedStep) {
diff --git a/karavan-designer/src/designer/rest/RestDesigner.tsx b/karavan-designer/src/designer/rest/RestDesigner.tsx
index 303e6bb8..d9b71d4f 100644
--- a/karavan-designer/src/designer/rest/RestDesigner.tsx
+++ b/karavan-designer/src/designer/rest/RestDesigner.tsx
@@ -22,7 +22,7 @@ import {
 import './rest.css';
 import '../karavan.css';
 import {CamelElement} from "karavan-core/lib/model/IntegrationDefinition";
-import {DslProperties} from "../route/DslProperties";
+import {DslProperties} from "../property/DslProperties";
 import {RestCard} from "./RestCard";
 import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
 import {
@@ -201,7 +201,7 @@ export function RestDesigner() {
     function getPropertiesPanel() {
         return (
             <DrawerPanelContent isResizable hasNoBorder defaultSize={'400px'} maxSize={'800px'} minSize={'100px'}>
-                <DslProperties isRouteDesigner={false}/>
+                <DslProperties designerType={'rest'}/>
             </DrawerPanelContent>
         )
     }
diff --git a/karavan-designer/src/designer/route/RouteDesigner.tsx b/karavan-designer/src/designer/route/RouteDesigner.tsx
index 3719d3c6..c2ebf292 100644
--- a/karavan-designer/src/designer/route/RouteDesigner.tsx
+++ b/karavan-designer/src/designer/route/RouteDesigner.tsx
@@ -24,7 +24,7 @@ import {
 } from '@patternfly/react-core';
 import '../karavan.css';
 import {DslSelector} from "./DslSelector";
-import {DslProperties} from "./DslProperties";
+import {DslProperties} from "../property/DslProperties";
 import {DslConnections} from "./DslConnections";
 import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
 import {DslElement} from "./element/DslElement";
@@ -102,7 +102,7 @@ export function RouteDesigner() {
                                 maxSize={'800px'}
                                 minSize={'400px'}
             >
-                <DslProperties isRouteDesigner={true}/>
+                <DslProperties designerType={'routes'}/>
             </DrawerPanelContent>
         )
     }
diff --git a/karavan-designer/src/topology/TopologyPropertiesPanel.tsx b/karavan-designer/src/topology/TopologyPropertiesPanel.tsx
index 24deca24..8387ce1f 100644
--- a/karavan-designer/src/topology/TopologyPropertiesPanel.tsx
+++ b/karavan-designer/src/topology/TopologyPropertiesPanel.tsx
@@ -19,7 +19,7 @@ import '../designer/karavan.css';
 import {shallow} from "zustand/shallow";
 import {TopologySideBar} from "@patternfly/react-topology";
 import {useTopologyStore} from "./TopologyStore";
-import {DslProperties} from "../designer/route/DslProperties";
+import {DslProperties} from "../designer/property/DslProperties";
 import {Button, Flex, FlexItem, Text, Tooltip, TooltipPosition} from "@patternfly/react-core";
 import CloseIcon from "@patternfly/react-icons/dist/esm/icons/times-icon";
 
@@ -62,7 +62,7 @@ export function TopologyPropertiesPanel (props: Props) {
         show={selectedIds.length > 0}
         header={getHeader()}
     >
-        <DslProperties isRouteDesigner={false}/>
+        <DslProperties designerType={'routes'}/>
     </TopologySideBar>
     )
 }
diff --git a/karavan-generator/src/main/java/org/apache/camel/karavan/generator/AbstractGenerator.java b/karavan-generator/src/main/java/org/apache/camel/karavan/generator/AbstractGenerator.java
index dc2b48b3..4d9aaa83 100644
--- a/karavan-generator/src/main/java/org/apache/camel/karavan/generator/AbstractGenerator.java
+++ b/karavan-generator/src/main/java/org/apache/camel/karavan/generator/AbstractGenerator.java
@@ -305,6 +305,17 @@ public class AbstractGenerator {
                 : str.substring(0, 1).toLowerCase() + str.substring(1);
     }
 
+    protected String getMetaModelApp(String name) {
+        try {
+            InputStream inputStream = CamelCatalog.class.getResourceAsStream("/org/apache/camel/catalog/models-app/" + name + ".json");
+            String data = new BufferedReader(new InputStreamReader(inputStream))
+                    .lines().collect(Collectors.joining(System.getProperty("line.separator")));
+            return data;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
     protected String getMetaModel(String name) {
         try {
             InputStream inputStream = CamelCatalog.class.getResourceAsStream("/org/apache/camel/catalog/models/" + name + ".json");
diff --git a/karavan-generator/src/main/java/org/apache/camel/karavan/generator/CamelMetadataGenerator.java b/karavan-generator/src/main/java/org/apache/camel/karavan/generator/CamelMetadataGenerator.java
index cb69b8ee..a0003d6c 100644
--- a/karavan-generator/src/main/java/org/apache/camel/karavan/generator/CamelMetadataGenerator.java
+++ b/karavan-generator/src/main/java/org/apache/camel/karavan/generator/CamelMetadataGenerator.java
@@ -159,7 +159,20 @@ public final class CamelMetadataGenerator extends AbstractGenerator {
             String name = entry.getKey();
             JsonObject properties = entry.getValue();
             String stepName = getStepNameForClass(name);
-            String json = folder.equals("model") ? getMetaModel(stepName) : (folder.equals("language") ? getMetaLanguage(stepName) : getMetaDataFormat(stepName));
+//            String json = folder.equals("model") ? getMetaModel(stepName) : (folder.equals("language") ? getMetaLanguage(stepName) : getMetaDataFormat(stepName));
+            String json = null;
+            if (Objects.equals(name, "RegistryBeanDefinition")) {
+                json = getMetaModelApp("bean");
+            } else if (folder.equals("model")) {
+                json = getMetaModel(stepName);
+            } else {
+                if (folder.equals("language")) {
+                    json = getMetaLanguage(stepName);
+                } else {
+                    json = getMetaDataFormat(stepName);
+                }
+            }
+
             if (json != null) {
                 JsonObject model = new JsonObject(json).getJsonObject("model");
                 JsonObject props = new JsonObject(json).getJsonObject("properties");
@@ -189,7 +202,7 @@ public final class CamelMetadataGenerator extends AbstractGenerator {
                         String defaultValue = p != null && p.containsKey("defaultValue") ? p.getString("defaultValue") : "";
                         defaultValue = defaultValue.length() == 1 && defaultValue.toCharArray()[0] == '\\' ? "\\\\" : defaultValue;
                         String labels = p != null && p.containsKey("label") ? p.getString("label") : "";
-                        String javaType = getJavaType(p);
+                        String javaType = getJavaType(name, p);
                         Boolean placeholder = Objects.equals(typeInCatalog, "string") && !Objects.equals(typeInCatalog, pm.type);
                         if (name.equals("ProcessDefinition") && pname.equals("ref")) javaType = "org.apache.camel.Processor"; // exception for processor
                         code.append(String.format(
@@ -199,18 +212,19 @@ public final class CamelMetadataGenerator extends AbstractGenerator {
                 });
                 code.append("    ]),\n");
             } else {
-                System.out.println("Empty JSON for class: " + name + " as a stepName " + stepName);
+//                System.out.println("Empty JSON for class: " + name + " as a stepName " + stepName);
             }
         });
         code.append("]\n\n");
         return code.toString();
     }
 
-    private String getJavaType(JsonObject p) {
+    private String getJavaType(String dslName, JsonObject p) {
         if (p != null
                 && p.containsKey("type")
                 && p.getString("type").equals("object")
-                && (p.getString("javaType").equals("org.apache.camel.AggregationStrategy") || p.getString("javaType").equals("org.apache.camel.Processor")) ) {
+                && (p.getString("javaType").equals("org.apache.camel.AggregationStrategy") || p.getString("javaType").equals("org.apache.camel.Processor"))
+        ) {
             String javaName = p.getString("javaType");
             try {
                 Class clazz = Class.forName(javaName);
diff --git a/karavan-space/src/designer/beans/BeanCard.tsx b/karavan-space/src/designer/beans/BeanCard.tsx
index 7a6d77b0..36d7822e 100644
--- a/karavan-space/src/designer/beans/BeanCard.tsx
+++ b/karavan-space/src/designer/beans/BeanCard.tsx
@@ -20,20 +20,18 @@ import {
 } from '@patternfly/react-core';
 import './bean.css';
 import {RegistryBeanDefinition} from "karavan-core/lib/model/CamelDefinition";
-import {useDesignerStore} from "../DesignerStore";
-import {shallow} from "zustand/shallow";
 import {DeleteElementIcon} from "../utils/ElementIcons";
+import {CamelElement} from "karavan-core/lib/model/IntegrationDefinition";
 
 interface Props {
     bean: RegistryBeanDefinition
+    selectedStep?: CamelElement
     selectElement: (element: RegistryBeanDefinition) => void
     deleteElement: (element: RegistryBeanDefinition) => void
 }
 
 export function BeanCard (props: Props) {
 
-    const [ selectedStep] = useDesignerStore((s) => [s.selectedStep], shallow)
-
     function selectElement (evt: React.MouseEvent) {
         evt.stopPropagation();
         props.selectElement(props.bean);
@@ -47,7 +45,7 @@ export function BeanCard (props: Props) {
     const bean = props.bean;
     return (
         <Flex direction={{default: "row"}}
-              className={selectedStep?.uuid === bean.uuid ? "bean-card bean-card-selected" : "bean-card bean-card-unselected"}
+              className={props.selectedStep?.uuid === bean.uuid ? "bean-card bean-card-selected" : "bean-card bean-card-unselected"}
               onClick={e => selectElement(e)}
         >
             <FlexItem flex={{default:"flex_1"}} className="title">Bean</FlexItem>
diff --git a/karavan-space/src/designer/beans/BeansDesigner.tsx b/karavan-space/src/designer/beans/BeansDesigner.tsx
index ceca2c21..8ef5c4a8 100644
--- a/karavan-space/src/designer/beans/BeansDesigner.tsx
+++ b/karavan-space/src/designer/beans/BeansDesigner.tsx
@@ -30,18 +30,18 @@ import {RegistryBeanDefinition} from "karavan-core/lib/model/CamelDefinition";
 import {CamelUi} from "../utils/CamelUi";
 import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
 import {CamelDefinitionApiExt} from "karavan-core/lib/api/CamelDefinitionApiExt";
-import {BeanProperties} from "./BeanProperties";
 import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
 import {BeanCard} from "./BeanCard";
 import {useDesignerStore, useIntegrationStore} from "../DesignerStore";
 import {shallow} from "zustand/shallow";
+import {DslProperties} from "../property/DslProperties";
 
 export function BeansDesigner() {
 
     const [integration, setIntegration] = useIntegrationStore((s) => [s.integration, s.setIntegration], shallow)
-    const [dark, selectedStep, showDeleteConfirmation, setShowDeleteConfirmation, setSelectedStep, setNotification]
+    const [selectedStep, showDeleteConfirmation, setShowDeleteConfirmation, setSelectedStep, setNotification]
         = useDesignerStore((s) =>
-        [s.dark, s.selectedStep, s.showDeleteConfirmation, s.setShowDeleteConfirmation, s.setSelectedStep, s.setNotification], shallow)
+        [s.selectedStep, s.showDeleteConfirmation, s.setShowDeleteConfirmation, s.setSelectedStep, s.setNotification], shallow)
 
     useEffect(() => {
         return () => {
@@ -61,12 +61,7 @@ export function BeansDesigner() {
         setSelectedStep(undefined);
     }
 
-    function changeBean(bean: RegistryBeanDefinition) {
-        const clone = CamelUtil.cloneIntegration(integration);
-        const i = CamelDefinitionApiExt.addBeanToIntegration(clone, bean);
-        setIntegration(i, false);
-        setSelectedStep(bean);
-    }
+
 
     function getDeleteConfirmation() {
         return (<Modal
@@ -98,7 +93,11 @@ export function BeansDesigner() {
     };
 
     function createBean() {
-        changeBean(new RegistryBeanDefinition());
+        const bean = new RegistryBeanDefinition();
+        const clone = CamelUtil.cloneIntegration(integration);
+        const i = CamelDefinitionApiExt.addBeanToIntegration(clone, bean);
+        setIntegration(i, false);
+        setSelectedStep(bean);
     }
 
     function getPropertiesPanel() {
@@ -108,10 +107,7 @@ export function BeansDesigner() {
                                 defaultSize={'400px'}
                                 maxSize={'800px'}
                                 minSize={'400px'}>
-                <BeanProperties integration={integration}
-                                dark={dark}
-                                onChange={changeBean}
-                                onClone={changeBean}/>
+                <DslProperties designerType={'beans'}/>
             </DrawerPanelContent>
         )
     }
@@ -131,6 +127,7 @@ export function BeansDesigner() {
                             {beans?.map((bean, index) => (
                                 <GalleryItem key={bean.uuid + index}>
                                     <BeanCard bean={bean}
+                                              selectedStep={selectedStep}
                                               selectElement={selectBean}
                                               deleteElement={onShowDeleteConfirmation}
                                     />
diff --git a/karavan-space/src/designer/kamelet/KameletDesigner.tsx b/karavan-space/src/designer/kamelet/KameletDesigner.tsx
index c235ef9b..4d2122f1 100644
--- a/karavan-space/src/designer/kamelet/KameletDesigner.tsx
+++ b/karavan-space/src/designer/kamelet/KameletDesigner.tsx
@@ -33,7 +33,7 @@ import {CamelDefinitionApiExt} from "karavan-core/lib/api/CamelDefinitionApiExt"
 import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
 import {useDesignerStore, useIntegrationStore} from "../DesignerStore";
 import {shallow} from "zustand/shallow";
-import {BeanProperties} from "../beans/BeanProperties";
+import {BeanProperties} from "../property/property/BeanProperties";
 import {BeanCard} from "../beans/BeanCard";
 import {KameletAnnotationsPanel} from "./KameletAnnotationsPanel";
 import {KameletDefinitionsPanel} from "./KameletDefinitionsPanel";
diff --git a/karavan-designer/src/designer/route/DslProperties.css b/karavan-space/src/designer/property/DslProperties.css
similarity index 100%
copy from karavan-designer/src/designer/route/DslProperties.css
copy to karavan-space/src/designer/property/DslProperties.css
diff --git a/karavan-designer/src/designer/route/DslProperties.tsx b/karavan-space/src/designer/property/DslProperties.tsx
similarity index 96%
copy from karavan-designer/src/designer/route/DslProperties.tsx
copy to karavan-space/src/designer/property/DslProperties.tsx
index b958b2b3..212a5f68 100644
--- a/karavan-designer/src/designer/route/DslProperties.tsx
+++ b/karavan-space/src/designer/property/DslProperties.tsx
@@ -38,17 +38,18 @@ import {usePropertiesHook} from "./usePropertiesHook";
 import {CamelDisplayUtil} from "karavan-core/lib/api/CamelDisplayUtil";
 
 interface Props {
-    isRouteDesigner: boolean
+    designerType: 'routes' | 'rest' | 'beans'
 }
 
 export function DslProperties(props: Props) {
 
-    const [integration] = useIntegrationStore((state) => [state.integration], shallow)
+    const [integration] = useIntegrationStore((s) => [s.integration], shallow)
 
     const {convertStep, cloneElement, onDataFormatChange, onPropertyChange, onParametersChange, onExpressionChange} =
-        usePropertiesHook(props.isRouteDesigner);
+        usePropertiesHook(props.designerType);
 
-    const [selectedStep, dark] = useDesignerStore((s) => [s.selectedStep, s.dark], shallow)
+    const [selectedStep, dark]
+        = useDesignerStore((s) => [s.selectedStep, s.dark], shallow)
 
     const [showAdvanced, setShowAdvanced] = useState<boolean>(false);
     const [isDescriptionExpanded, setIsDescriptionExpanded] = useState<boolean>(false);
@@ -109,7 +110,7 @@ export function DslProperties(props: Props) {
     }
 
     function getComponentHeader(): JSX.Element {
-        if (props.isRouteDesigner) return getRouteHeader()
+        if (props.designerType === 'routes') return getRouteHeader()
         else return getClonableElementHeader();
     }
 
diff --git a/karavan-designer/src/designer/beans/BeanProperties.tsx b/karavan-space/src/designer/property/property/BeanProperties.tsx
similarity index 84%
copy from karavan-designer/src/designer/beans/BeanProperties.tsx
copy to karavan-space/src/designer/property/property/BeanProperties.tsx
index c3147828..2322d8f4 100644
--- a/karavan-designer/src/designer/beans/BeanProperties.tsx
+++ b/karavan-space/src/designer/property/property/BeanProperties.tsx
@@ -16,37 +16,32 @@
  */
 import React, {useEffect, useState} from 'react';
 import {
-    Form,
     FormGroup,
-    TextInput, Button, Title, Tooltip, Popover, InputGroup, InputGroupItem, capitalize,
+    TextInput, Button, Tooltip, Popover, InputGroup, InputGroupItem, capitalize,
 } from '@patternfly/react-core';
-import '../karavan.css';
+import '../../karavan.css';
 import "@patternfly/patternfly/patternfly.css";
 import {
     RegistryBeanDefinition,
 } from "karavan-core/lib/model/CamelDefinition";
-import {Integration} from "karavan-core/lib/model/IntegrationDefinition";
 import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
 import {SensitiveKeys} from "karavan-core/lib/model/CamelMetadata";
 import {v4 as uuidv4} from "uuid";
 import DeleteIcon from "@patternfly/react-icons/dist/js/icons/times-icon";
 import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-circle-icon";
-import CloneIcon from '@patternfly/react-icons/dist/esm/icons/clone-icon'
 import HelpIcon from "@patternfly/react-icons/dist/js/icons/help-icon";
-import {InfrastructureSelector} from "../route/property/InfrastructureSelector";
-import {InfrastructureAPI} from "../utils/InfrastructureAPI";
+import {InfrastructureSelector} from "./InfrastructureSelector";
+import {InfrastructureAPI} from "../../utils/InfrastructureAPI";
 import ShowIcon from "@patternfly/react-icons/dist/js/icons/eye-icon";
 import HideIcon from "@patternfly/react-icons/dist/js/icons/eye-slash-icon";
 import DockerIcon from "@patternfly/react-icons/dist/js/icons/docker-icon";
-import {useDesignerStore} from "../DesignerStore";
+import {useDesignerStore} from "../../DesignerStore";
 import {shallow} from "zustand/shallow";
-import {IntegrationHeader} from "../utils/IntegrationHeader";
-import {KubernetesIcon} from "../icons/ComponentIcons";
+import {KubernetesIcon} from "../../icons/ComponentIcons";
 
 
 interface Props {
-    integration: Integration
-    dark: boolean
+    type: 'constructors' | 'properties'
     onChange: (bean: RegistryBeanDefinition) => void
     onClone: (bean: RegistryBeanDefinition) => void
 }
@@ -202,7 +197,7 @@ export function BeanProperties (props: Props) {
 
     function getBeanConstructors() {
         return (
-            <FormGroup label="Constructors" fieldId="constructors" className="bean-properties">
+            <>
                 {Array.from(constructors.entries()).map((v, index, array) => {
                     const i = v[0];
                     const key = v[1][0];
@@ -244,13 +239,13 @@ export function BeanProperties (props: Props) {
                 })}
                 <Button variant="link" className="add-button" onClick={e => constructorChanged(uuidv4(), constructors.size, '', false)}>
                     <AddIcon/>Add argument</Button>
-            </FormGroup>
+            </>
         )
     }
 
     function getBeanProperties() {
         return (
-                <FormGroup label="Properties" fieldId="properties" className="bean-properties">
+                <>
                     {Array.from(properties.entries()).map((v, index, array) => {
                         const i = v[0];
                         const key = v[1][0];
@@ -298,44 +293,15 @@ export function BeanProperties (props: Props) {
                     })}
                     <Button variant="link" className="add-button" onClick={e => propertyChanged(uuidv4(), '', '', false)}>
                         <AddIcon/>Add property</Button>
-                </FormGroup>
-        )
-    }
-
-
-    function getBeanForm() {
-        const bean = (selectedStep as RegistryBeanDefinition);
-        return (
-            <>
-                <div className="headers">
-                    <div className="top">
-                        <Title headingLevel="h1" size="md">Bean</Title>
-                        <Tooltip content="Clone bean" position="bottom">
-                            <Button variant="link" onClick={() => cloneBean()} icon={<CloneIcon/>}/>
-                        </Tooltip>
-                    </div>
-                </div>
-                <FormGroup label="Name" fieldId="name" isRequired labelIcon={getLabelIcon("Name", "Bean name used as a reference ex: myBean")}>
-                    <TextInput className="text-field" isRequired type="text" id="name" name="name" value={bean?.name}
-                                onChange={(_, value)=> beanFieldChanged("name", value)}/>
-                </FormGroup>
-                <FormGroup label="Type" fieldId="type" isRequired labelIcon={getLabelIcon("Type", "Bean class Canonical Name ex: org.demo.MyBean")}>
-                    <TextInput className="text-field" isRequired type="text" id="type" name="type" value={bean?.type}
-                        onChange={(_, value) => beanFieldChanged("type", value)}/>
-                </FormGroup>
-                {getBeanConstructors()}
-                {getBeanProperties()}
-            </>
+                </>
         )
     }
 
     const bean = (selectedStep as RegistryBeanDefinition);
     return (
         <div className='properties' key={bean ? bean.uuid : 'integration'}>
-            <Form autoComplete="off" onSubmit={event => event.preventDefault()}>
-                {bean === undefined && <IntegrationHeader/>}
-                {bean !== undefined && getBeanForm()}
-            </Form>
+            {props.type === 'constructors' && getBeanConstructors()}
+            {props.type === 'properties' && getBeanProperties()}
             {getInfrastructureSelectorModal()}
         </div>
     )
diff --git a/karavan-designer/src/designer/route/property/ComponentParameterField.tsx b/karavan-space/src/designer/property/property/ComponentParameterField.tsx
similarity index 100%
copy from karavan-designer/src/designer/route/property/ComponentParameterField.tsx
copy to karavan-space/src/designer/property/property/ComponentParameterField.tsx
diff --git a/karavan-designer/src/designer/route/property/DataFormatField.tsx b/karavan-space/src/designer/property/property/DataFormatField.tsx
similarity index 100%
copy from karavan-designer/src/designer/route/property/DataFormatField.tsx
copy to karavan-space/src/designer/property/property/DataFormatField.tsx
diff --git a/karavan-designer/src/designer/route/property/DslPropertyField.css b/karavan-space/src/designer/property/property/DslPropertyField.css
similarity index 100%
copy from karavan-designer/src/designer/route/property/DslPropertyField.css
copy to karavan-space/src/designer/property/property/DslPropertyField.css
diff --git a/karavan-designer/src/designer/route/property/DslPropertyField.tsx b/karavan-space/src/designer/property/property/DslPropertyField.tsx
similarity index 96%
copy from karavan-designer/src/designer/route/property/DslPropertyField.tsx
copy to karavan-space/src/designer/property/property/DslPropertyField.tsx
index f092a795..e138a88a 100644
--- a/karavan-designer/src/designer/route/property/DslPropertyField.tsx
+++ b/karavan-space/src/designer/property/property/DslPropertyField.tsx
@@ -68,9 +68,14 @@ import {ModalEditor} from "./ModalEditor";
 import DockerIcon from "@patternfly/react-icons/dist/js/icons/docker-icon";
 import {useDesignerStore, useIntegrationStore} from "../../DesignerStore";
 import {shallow} from "zustand/shallow";
-import {DataFormatDefinition, ExpressionDefinition} from "karavan-core/lib/model/CamelDefinition";
+import {
+    DataFormatDefinition,
+    ExpressionDefinition,
+    RegistryBeanDefinition
+} from "karavan-core/lib/model/CamelDefinition";
 import {TemplateApi} from "karavan-core/lib/api/TemplateApi";
 import {KubernetesIcon} from "../../icons/ComponentIcons";
+import {BeanProperties} from "./BeanProperties";
 
 interface Props {
     property: PropertyMeta,
@@ -86,8 +91,8 @@ interface Props {
 
 export function DslPropertyField(props: Props) {
 
-    const [integration] = useIntegrationStore((state) => [state.integration], shallow)
-    const [dark] = useDesignerStore((s) => [s.dark], shallow)
+    const [integration, setIntegration] = useIntegrationStore((s) => [s.integration, s.setIntegration], shallow)
+    const [dark, setSelectedStep] = useDesignerStore((s) => [s.dark, s.setSelectedStep], shallow)
 
     const [isShowAdvanced, setIsShowAdvanced] = useState<string[]>([]);
     const [arrayValues, setArrayValues] = useState<Map<string, string>>(new Map<string, string>());
@@ -748,6 +753,17 @@ export function DslPropertyField(props: Props) {
     }
 
 
+    function changeBean(bean: RegistryBeanDefinition) {
+        const clone = CamelUtil.cloneIntegration(integration);
+        const i = CamelDefinitionApiExt.addBeanToIntegration(clone, bean);
+        setIntegration(i, false);
+        setSelectedStep(bean);
+    }
+
+    function getBeanProperties(type: 'constructors' | 'properties') {
+        return <BeanProperties type={type} onChange={changeBean} onClone={changeBean}/>
+    }
+
     function isMultiValueField(property: PropertyMeta): boolean {
         return ['string'].includes(property.type) && property.name !== 'expression' && property.isArray && !property.enumVals;
     }
@@ -776,6 +792,8 @@ export function DslPropertyField(props: Props) {
     const isKamelet = CamelUtil.isKameletComponent(element);
     const property: PropertyMeta = props.property;
     const value = props.value;
+    const beanConstructors = element?.dslName === 'RegistryBeanDefinition' && property.name === 'constructors'
+    const beanProperties = element?.dslName === 'RegistryBeanDefinition' && property.name === 'properties'
     return (
         <div>
             <FormGroup
@@ -812,6 +830,8 @@ export function DslPropertyField(props: Props) {
                     && getSelect(property, value)}
                 {isKamelet && property.name === 'parameters' && getKameletParameters()}
                 {!isKamelet && property.name === 'parameters' && getComponentParameters(property)}
+                {beanConstructors && getBeanProperties('constructors')}
+                {beanProperties && getBeanProperties('properties')}
             </FormGroup>
             {getInfrastructureSelectorModal()}
         </div>
diff --git a/karavan-designer/src/designer/route/property/ExpressionField.tsx b/karavan-space/src/designer/property/property/ExpressionField.tsx
similarity index 100%
copy from karavan-designer/src/designer/route/property/ExpressionField.tsx
copy to karavan-space/src/designer/property/property/ExpressionField.tsx
diff --git a/karavan-designer/src/designer/route/property/InfrastructureSelector.tsx b/karavan-space/src/designer/property/property/InfrastructureSelector.tsx
similarity index 100%
copy from karavan-designer/src/designer/route/property/InfrastructureSelector.tsx
copy to karavan-space/src/designer/property/property/InfrastructureSelector.tsx
diff --git a/karavan-designer/src/designer/route/property/KameletPropertyField.tsx b/karavan-space/src/designer/property/property/KameletPropertyField.tsx
similarity index 100%
copy from karavan-designer/src/designer/route/property/KameletPropertyField.tsx
copy to karavan-space/src/designer/property/property/KameletPropertyField.tsx
diff --git a/karavan-designer/src/designer/route/property/ModalEditor.tsx b/karavan-space/src/designer/property/property/ModalEditor.tsx
similarity index 100%
copy from karavan-designer/src/designer/route/property/ModalEditor.tsx
copy to karavan-space/src/designer/property/property/ModalEditor.tsx
diff --git a/karavan-designer/src/designer/route/property/ObjectField.tsx b/karavan-space/src/designer/property/property/ObjectField.tsx
similarity index 100%
copy from karavan-designer/src/designer/route/property/ObjectField.tsx
copy to karavan-space/src/designer/property/property/ObjectField.tsx
diff --git a/karavan-designer/src/designer/route/usePropertiesHook.tsx b/karavan-space/src/designer/property/usePropertiesHook.tsx
similarity index 84%
copy from karavan-designer/src/designer/route/usePropertiesHook.tsx
copy to karavan-space/src/designer/property/usePropertiesHook.tsx
index a9bd9ef9..41ac95af 100644
--- a/karavan-designer/src/designer/route/usePropertiesHook.tsx
+++ b/karavan-space/src/designer/property/usePropertiesHook.tsx
@@ -26,17 +26,19 @@ import {RouteToCreate} from "../utils/CamelUi";
 import {useDesignerStore, useIntegrationStore} from "../DesignerStore";
 import {shallow} from "zustand/shallow";
 
-export function usePropertiesHook (isRouteDesigner: boolean = true) {
+export function usePropertiesHook (designerType: 'routes' | 'rest' | 'beans' = 'routes') {
 
     const [integration, setIntegration] = useIntegrationStore((state) => [state.integration, state.setIntegration], shallow)
     const [ selectedStep, setSelectedStep, setSelectedUuids] = useDesignerStore((s) =>
         [s.selectedStep, s.setSelectedStep, s.setSelectedUuids], shallow)
 
     function onPropertyUpdate (element: CamelElement, newRoute?: RouteToCreate) {
-        if (isRouteDesigner) {
+        if (designerType === 'routes') {
             onRoutePropertyUpdate(element, newRoute);
-        } else {
+        } else if (designerType === 'rest') {
             onRestPropertyUpdate(element, newRoute);
+        } else if (designerType === 'beans') {
+            onBeanPropertyUpdate(element, newRoute);
         }
     }
 
@@ -74,6 +76,23 @@ export function usePropertiesHook (isRouteDesigner: boolean = true) {
         }
     }
 
+    function onBeanPropertyUpdate (element: CamelElement, newRoute?: RouteToCreate) {
+        if (newRoute) {
+            let i = CamelDefinitionApiExt.updateIntegrationBeanElement(integration, element);
+            const f = CamelDefinitionApi.createFromDefinition({uri: newRoute.componentName, parameters: {name: newRoute.name}});
+            const r = CamelDefinitionApi.createRouteDefinition({from: f, id: newRoute.name})
+            i = CamelDefinitionApiExt.addStepToIntegration(i, r, '');
+            const clone = CamelUtil.cloneIntegration(i);
+            setIntegration(clone, false);
+            setSelectedStep(element);
+        } else {
+            const clone = CamelUtil.cloneIntegration(integration);
+            const i = CamelDefinitionApiExt.updateIntegrationBeanElement(clone, element);
+            setIntegration(i, true);
+            // setSelectedStep(element);
+        }
+    }
+
     function onPropertyChange (fieldId: string, value: string | number | boolean | any, newRoute?: RouteToCreate){
         value = value === '' ? undefined : value;
         if (selectedStep) {
diff --git a/karavan-space/src/designer/rest/RestDesigner.tsx b/karavan-space/src/designer/rest/RestDesigner.tsx
index 303e6bb8..d9b71d4f 100644
--- a/karavan-space/src/designer/rest/RestDesigner.tsx
+++ b/karavan-space/src/designer/rest/RestDesigner.tsx
@@ -22,7 +22,7 @@ import {
 import './rest.css';
 import '../karavan.css';
 import {CamelElement} from "karavan-core/lib/model/IntegrationDefinition";
-import {DslProperties} from "../route/DslProperties";
+import {DslProperties} from "../property/DslProperties";
 import {RestCard} from "./RestCard";
 import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
 import {
@@ -201,7 +201,7 @@ export function RestDesigner() {
     function getPropertiesPanel() {
         return (
             <DrawerPanelContent isResizable hasNoBorder defaultSize={'400px'} maxSize={'800px'} minSize={'100px'}>
-                <DslProperties isRouteDesigner={false}/>
+                <DslProperties designerType={'rest'}/>
             </DrawerPanelContent>
         )
     }
diff --git a/karavan-space/src/designer/route/RouteDesigner.tsx b/karavan-space/src/designer/route/RouteDesigner.tsx
index 3719d3c6..c2ebf292 100644
--- a/karavan-space/src/designer/route/RouteDesigner.tsx
+++ b/karavan-space/src/designer/route/RouteDesigner.tsx
@@ -24,7 +24,7 @@ import {
 } from '@patternfly/react-core';
 import '../karavan.css';
 import {DslSelector} from "./DslSelector";
-import {DslProperties} from "./DslProperties";
+import {DslProperties} from "../property/DslProperties";
 import {DslConnections} from "./DslConnections";
 import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
 import {DslElement} from "./element/DslElement";
@@ -102,7 +102,7 @@ export function RouteDesigner() {
                                 maxSize={'800px'}
                                 minSize={'400px'}
             >
-                <DslProperties isRouteDesigner={true}/>
+                <DslProperties designerType={'routes'}/>
             </DrawerPanelContent>
         )
     }
diff --git a/karavan-space/src/topology/TopologyPropertiesPanel.tsx b/karavan-space/src/topology/TopologyPropertiesPanel.tsx
index 24deca24..8387ce1f 100644
--- a/karavan-space/src/topology/TopologyPropertiesPanel.tsx
+++ b/karavan-space/src/topology/TopologyPropertiesPanel.tsx
@@ -19,7 +19,7 @@ import '../designer/karavan.css';
 import {shallow} from "zustand/shallow";
 import {TopologySideBar} from "@patternfly/react-topology";
 import {useTopologyStore} from "./TopologyStore";
-import {DslProperties} from "../designer/route/DslProperties";
+import {DslProperties} from "../designer/property/DslProperties";
 import {Button, Flex, FlexItem, Text, Tooltip, TooltipPosition} from "@patternfly/react-core";
 import CloseIcon from "@patternfly/react-icons/dist/esm/icons/times-icon";
 
@@ -62,7 +62,7 @@ export function TopologyPropertiesPanel (props: Props) {
         show={selectedIds.length > 0}
         header={getHeader()}
     >
-        <DslProperties isRouteDesigner={false}/>
+        <DslProperties designerType={'routes'}/>
     </TopologySideBar>
     )
 }
diff --git a/karavan-vscode/webview/topology/TopologyPropertiesPanel.tsx b/karavan-vscode/webview/topology/TopologyPropertiesPanel.tsx
index 24deca24..8387ce1f 100644
--- a/karavan-vscode/webview/topology/TopologyPropertiesPanel.tsx
+++ b/karavan-vscode/webview/topology/TopologyPropertiesPanel.tsx
@@ -19,7 +19,7 @@ import '../designer/karavan.css';
 import {shallow} from "zustand/shallow";
 import {TopologySideBar} from "@patternfly/react-topology";
 import {useTopologyStore} from "./TopologyStore";
-import {DslProperties} from "../designer/route/DslProperties";
+import {DslProperties} from "../designer/property/DslProperties";
 import {Button, Flex, FlexItem, Text, Tooltip, TooltipPosition} from "@patternfly/react-core";
 import CloseIcon from "@patternfly/react-icons/dist/esm/icons/times-icon";
 
@@ -62,7 +62,7 @@ export function TopologyPropertiesPanel (props: Props) {
         show={selectedIds.length > 0}
         header={getHeader()}
     >
-        <DslProperties isRouteDesigner={false}/>
+        <DslProperties designerType={'routes'}/>
     </TopologySideBar>
     )
 }
diff --git a/karavan-web/karavan-app/src/main/webui/src/designer/beans/BeanCard.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/beans/BeanCard.tsx
index 7a6d77b0..36d7822e 100644
--- a/karavan-web/karavan-app/src/main/webui/src/designer/beans/BeanCard.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/beans/BeanCard.tsx
@@ -20,20 +20,18 @@ import {
 } from '@patternfly/react-core';
 import './bean.css';
 import {RegistryBeanDefinition} from "karavan-core/lib/model/CamelDefinition";
-import {useDesignerStore} from "../DesignerStore";
-import {shallow} from "zustand/shallow";
 import {DeleteElementIcon} from "../utils/ElementIcons";
+import {CamelElement} from "karavan-core/lib/model/IntegrationDefinition";
 
 interface Props {
     bean: RegistryBeanDefinition
+    selectedStep?: CamelElement
     selectElement: (element: RegistryBeanDefinition) => void
     deleteElement: (element: RegistryBeanDefinition) => void
 }
 
 export function BeanCard (props: Props) {
 
-    const [ selectedStep] = useDesignerStore((s) => [s.selectedStep], shallow)
-
     function selectElement (evt: React.MouseEvent) {
         evt.stopPropagation();
         props.selectElement(props.bean);
@@ -47,7 +45,7 @@ export function BeanCard (props: Props) {
     const bean = props.bean;
     return (
         <Flex direction={{default: "row"}}
-              className={selectedStep?.uuid === bean.uuid ? "bean-card bean-card-selected" : "bean-card bean-card-unselected"}
+              className={props.selectedStep?.uuid === bean.uuid ? "bean-card bean-card-selected" : "bean-card bean-card-unselected"}
               onClick={e => selectElement(e)}
         >
             <FlexItem flex={{default:"flex_1"}} className="title">Bean</FlexItem>
diff --git a/karavan-web/karavan-app/src/main/webui/src/designer/beans/BeansDesigner.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/beans/BeansDesigner.tsx
index ceca2c21..8ef5c4a8 100644
--- a/karavan-web/karavan-app/src/main/webui/src/designer/beans/BeansDesigner.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/beans/BeansDesigner.tsx
@@ -30,18 +30,18 @@ import {RegistryBeanDefinition} from "karavan-core/lib/model/CamelDefinition";
 import {CamelUi} from "../utils/CamelUi";
 import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
 import {CamelDefinitionApiExt} from "karavan-core/lib/api/CamelDefinitionApiExt";
-import {BeanProperties} from "./BeanProperties";
 import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
 import {BeanCard} from "./BeanCard";
 import {useDesignerStore, useIntegrationStore} from "../DesignerStore";
 import {shallow} from "zustand/shallow";
+import {DslProperties} from "../property/DslProperties";
 
 export function BeansDesigner() {
 
     const [integration, setIntegration] = useIntegrationStore((s) => [s.integration, s.setIntegration], shallow)
-    const [dark, selectedStep, showDeleteConfirmation, setShowDeleteConfirmation, setSelectedStep, setNotification]
+    const [selectedStep, showDeleteConfirmation, setShowDeleteConfirmation, setSelectedStep, setNotification]
         = useDesignerStore((s) =>
-        [s.dark, s.selectedStep, s.showDeleteConfirmation, s.setShowDeleteConfirmation, s.setSelectedStep, s.setNotification], shallow)
+        [s.selectedStep, s.showDeleteConfirmation, s.setShowDeleteConfirmation, s.setSelectedStep, s.setNotification], shallow)
 
     useEffect(() => {
         return () => {
@@ -61,12 +61,7 @@ export function BeansDesigner() {
         setSelectedStep(undefined);
     }
 
-    function changeBean(bean: RegistryBeanDefinition) {
-        const clone = CamelUtil.cloneIntegration(integration);
-        const i = CamelDefinitionApiExt.addBeanToIntegration(clone, bean);
-        setIntegration(i, false);
-        setSelectedStep(bean);
-    }
+
 
     function getDeleteConfirmation() {
         return (<Modal
@@ -98,7 +93,11 @@ export function BeansDesigner() {
     };
 
     function createBean() {
-        changeBean(new RegistryBeanDefinition());
+        const bean = new RegistryBeanDefinition();
+        const clone = CamelUtil.cloneIntegration(integration);
+        const i = CamelDefinitionApiExt.addBeanToIntegration(clone, bean);
+        setIntegration(i, false);
+        setSelectedStep(bean);
     }
 
     function getPropertiesPanel() {
@@ -108,10 +107,7 @@ export function BeansDesigner() {
                                 defaultSize={'400px'}
                                 maxSize={'800px'}
                                 minSize={'400px'}>
-                <BeanProperties integration={integration}
-                                dark={dark}
-                                onChange={changeBean}
-                                onClone={changeBean}/>
+                <DslProperties designerType={'beans'}/>
             </DrawerPanelContent>
         )
     }
@@ -131,6 +127,7 @@ export function BeansDesigner() {
                             {beans?.map((bean, index) => (
                                 <GalleryItem key={bean.uuid + index}>
                                     <BeanCard bean={bean}
+                                              selectedStep={selectedStep}
                                               selectElement={selectBean}
                                               deleteElement={onShowDeleteConfirmation}
                                     />
diff --git a/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletDesigner.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletDesigner.tsx
index c235ef9b..4d2122f1 100644
--- a/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletDesigner.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletDesigner.tsx
@@ -33,7 +33,7 @@ import {CamelDefinitionApiExt} from "karavan-core/lib/api/CamelDefinitionApiExt"
 import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
 import {useDesignerStore, useIntegrationStore} from "../DesignerStore";
 import {shallow} from "zustand/shallow";
-import {BeanProperties} from "../beans/BeanProperties";
+import {BeanProperties} from "../property/property/BeanProperties";
 import {BeanCard} from "../beans/BeanCard";
 import {KameletAnnotationsPanel} from "./KameletAnnotationsPanel";
 import {KameletDefinitionsPanel} from "./KameletDefinitionsPanel";
diff --git a/karavan-designer/src/designer/route/DslProperties.css b/karavan-web/karavan-app/src/main/webui/src/designer/property/DslProperties.css
similarity index 100%
rename from karavan-designer/src/designer/route/DslProperties.css
rename to karavan-web/karavan-app/src/main/webui/src/designer/property/DslProperties.css
diff --git a/karavan-designer/src/designer/route/DslProperties.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/property/DslProperties.tsx
similarity index 96%
rename from karavan-designer/src/designer/route/DslProperties.tsx
rename to karavan-web/karavan-app/src/main/webui/src/designer/property/DslProperties.tsx
index b958b2b3..212a5f68 100644
--- a/karavan-designer/src/designer/route/DslProperties.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/property/DslProperties.tsx
@@ -38,17 +38,18 @@ import {usePropertiesHook} from "./usePropertiesHook";
 import {CamelDisplayUtil} from "karavan-core/lib/api/CamelDisplayUtil";
 
 interface Props {
-    isRouteDesigner: boolean
+    designerType: 'routes' | 'rest' | 'beans'
 }
 
 export function DslProperties(props: Props) {
 
-    const [integration] = useIntegrationStore((state) => [state.integration], shallow)
+    const [integration] = useIntegrationStore((s) => [s.integration], shallow)
 
     const {convertStep, cloneElement, onDataFormatChange, onPropertyChange, onParametersChange, onExpressionChange} =
-        usePropertiesHook(props.isRouteDesigner);
+        usePropertiesHook(props.designerType);
 
-    const [selectedStep, dark] = useDesignerStore((s) => [s.selectedStep, s.dark], shallow)
+    const [selectedStep, dark]
+        = useDesignerStore((s) => [s.selectedStep, s.dark], shallow)
 
     const [showAdvanced, setShowAdvanced] = useState<boolean>(false);
     const [isDescriptionExpanded, setIsDescriptionExpanded] = useState<boolean>(false);
@@ -109,7 +110,7 @@ export function DslProperties(props: Props) {
     }
 
     function getComponentHeader(): JSX.Element {
-        if (props.isRouteDesigner) return getRouteHeader()
+        if (props.designerType === 'routes') return getRouteHeader()
         else return getClonableElementHeader();
     }
 
diff --git a/karavan-designer/src/designer/beans/BeanProperties.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/property/property/BeanProperties.tsx
similarity index 84%
rename from karavan-designer/src/designer/beans/BeanProperties.tsx
rename to karavan-web/karavan-app/src/main/webui/src/designer/property/property/BeanProperties.tsx
index c3147828..2322d8f4 100644
--- a/karavan-designer/src/designer/beans/BeanProperties.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/property/property/BeanProperties.tsx
@@ -16,37 +16,32 @@
  */
 import React, {useEffect, useState} from 'react';
 import {
-    Form,
     FormGroup,
-    TextInput, Button, Title, Tooltip, Popover, InputGroup, InputGroupItem, capitalize,
+    TextInput, Button, Tooltip, Popover, InputGroup, InputGroupItem, capitalize,
 } from '@patternfly/react-core';
-import '../karavan.css';
+import '../../karavan.css';
 import "@patternfly/patternfly/patternfly.css";
 import {
     RegistryBeanDefinition,
 } from "karavan-core/lib/model/CamelDefinition";
-import {Integration} from "karavan-core/lib/model/IntegrationDefinition";
 import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
 import {SensitiveKeys} from "karavan-core/lib/model/CamelMetadata";
 import {v4 as uuidv4} from "uuid";
 import DeleteIcon from "@patternfly/react-icons/dist/js/icons/times-icon";
 import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-circle-icon";
-import CloneIcon from '@patternfly/react-icons/dist/esm/icons/clone-icon'
 import HelpIcon from "@patternfly/react-icons/dist/js/icons/help-icon";
-import {InfrastructureSelector} from "../route/property/InfrastructureSelector";
-import {InfrastructureAPI} from "../utils/InfrastructureAPI";
+import {InfrastructureSelector} from "./InfrastructureSelector";
+import {InfrastructureAPI} from "../../utils/InfrastructureAPI";
 import ShowIcon from "@patternfly/react-icons/dist/js/icons/eye-icon";
 import HideIcon from "@patternfly/react-icons/dist/js/icons/eye-slash-icon";
 import DockerIcon from "@patternfly/react-icons/dist/js/icons/docker-icon";
-import {useDesignerStore} from "../DesignerStore";
+import {useDesignerStore} from "../../DesignerStore";
 import {shallow} from "zustand/shallow";
-import {IntegrationHeader} from "../utils/IntegrationHeader";
-import {KubernetesIcon} from "../icons/ComponentIcons";
+import {KubernetesIcon} from "../../icons/ComponentIcons";
 
 
 interface Props {
-    integration: Integration
-    dark: boolean
+    type: 'constructors' | 'properties'
     onChange: (bean: RegistryBeanDefinition) => void
     onClone: (bean: RegistryBeanDefinition) => void
 }
@@ -202,7 +197,7 @@ export function BeanProperties (props: Props) {
 
     function getBeanConstructors() {
         return (
-            <FormGroup label="Constructors" fieldId="constructors" className="bean-properties">
+            <>
                 {Array.from(constructors.entries()).map((v, index, array) => {
                     const i = v[0];
                     const key = v[1][0];
@@ -244,13 +239,13 @@ export function BeanProperties (props: Props) {
                 })}
                 <Button variant="link" className="add-button" onClick={e => constructorChanged(uuidv4(), constructors.size, '', false)}>
                     <AddIcon/>Add argument</Button>
-            </FormGroup>
+            </>
         )
     }
 
     function getBeanProperties() {
         return (
-                <FormGroup label="Properties" fieldId="properties" className="bean-properties">
+                <>
                     {Array.from(properties.entries()).map((v, index, array) => {
                         const i = v[0];
                         const key = v[1][0];
@@ -298,44 +293,15 @@ export function BeanProperties (props: Props) {
                     })}
                     <Button variant="link" className="add-button" onClick={e => propertyChanged(uuidv4(), '', '', false)}>
                         <AddIcon/>Add property</Button>
-                </FormGroup>
-        )
-    }
-
-
-    function getBeanForm() {
-        const bean = (selectedStep as RegistryBeanDefinition);
-        return (
-            <>
-                <div className="headers">
-                    <div className="top">
-                        <Title headingLevel="h1" size="md">Bean</Title>
-                        <Tooltip content="Clone bean" position="bottom">
-                            <Button variant="link" onClick={() => cloneBean()} icon={<CloneIcon/>}/>
-                        </Tooltip>
-                    </div>
-                </div>
-                <FormGroup label="Name" fieldId="name" isRequired labelIcon={getLabelIcon("Name", "Bean name used as a reference ex: myBean")}>
-                    <TextInput className="text-field" isRequired type="text" id="name" name="name" value={bean?.name}
-                                onChange={(_, value)=> beanFieldChanged("name", value)}/>
-                </FormGroup>
-                <FormGroup label="Type" fieldId="type" isRequired labelIcon={getLabelIcon("Type", "Bean class Canonical Name ex: org.demo.MyBean")}>
-                    <TextInput className="text-field" isRequired type="text" id="type" name="type" value={bean?.type}
-                        onChange={(_, value) => beanFieldChanged("type", value)}/>
-                </FormGroup>
-                {getBeanConstructors()}
-                {getBeanProperties()}
-            </>
+                </>
         )
     }
 
     const bean = (selectedStep as RegistryBeanDefinition);
     return (
         <div className='properties' key={bean ? bean.uuid : 'integration'}>
-            <Form autoComplete="off" onSubmit={event => event.preventDefault()}>
-                {bean === undefined && <IntegrationHeader/>}
-                {bean !== undefined && getBeanForm()}
-            </Form>
+            {props.type === 'constructors' && getBeanConstructors()}
+            {props.type === 'properties' && getBeanProperties()}
             {getInfrastructureSelectorModal()}
         </div>
     )
diff --git a/karavan-designer/src/designer/route/property/ComponentParameterField.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/property/property/ComponentParameterField.tsx
similarity index 100%
rename from karavan-designer/src/designer/route/property/ComponentParameterField.tsx
rename to karavan-web/karavan-app/src/main/webui/src/designer/property/property/ComponentParameterField.tsx
diff --git a/karavan-designer/src/designer/route/property/DataFormatField.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/property/property/DataFormatField.tsx
similarity index 100%
rename from karavan-designer/src/designer/route/property/DataFormatField.tsx
rename to karavan-web/karavan-app/src/main/webui/src/designer/property/property/DataFormatField.tsx
diff --git a/karavan-designer/src/designer/route/property/DslPropertyField.css b/karavan-web/karavan-app/src/main/webui/src/designer/property/property/DslPropertyField.css
similarity index 100%
rename from karavan-designer/src/designer/route/property/DslPropertyField.css
rename to karavan-web/karavan-app/src/main/webui/src/designer/property/property/DslPropertyField.css
diff --git a/karavan-designer/src/designer/route/property/DslPropertyField.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/property/property/DslPropertyField.tsx
similarity index 96%
rename from karavan-designer/src/designer/route/property/DslPropertyField.tsx
rename to karavan-web/karavan-app/src/main/webui/src/designer/property/property/DslPropertyField.tsx
index f092a795..e138a88a 100644
--- a/karavan-designer/src/designer/route/property/DslPropertyField.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/property/property/DslPropertyField.tsx
@@ -68,9 +68,14 @@ import {ModalEditor} from "./ModalEditor";
 import DockerIcon from "@patternfly/react-icons/dist/js/icons/docker-icon";
 import {useDesignerStore, useIntegrationStore} from "../../DesignerStore";
 import {shallow} from "zustand/shallow";
-import {DataFormatDefinition, ExpressionDefinition} from "karavan-core/lib/model/CamelDefinition";
+import {
+    DataFormatDefinition,
+    ExpressionDefinition,
+    RegistryBeanDefinition
+} from "karavan-core/lib/model/CamelDefinition";
 import {TemplateApi} from "karavan-core/lib/api/TemplateApi";
 import {KubernetesIcon} from "../../icons/ComponentIcons";
+import {BeanProperties} from "./BeanProperties";
 
 interface Props {
     property: PropertyMeta,
@@ -86,8 +91,8 @@ interface Props {
 
 export function DslPropertyField(props: Props) {
 
-    const [integration] = useIntegrationStore((state) => [state.integration], shallow)
-    const [dark] = useDesignerStore((s) => [s.dark], shallow)
+    const [integration, setIntegration] = useIntegrationStore((s) => [s.integration, s.setIntegration], shallow)
+    const [dark, setSelectedStep] = useDesignerStore((s) => [s.dark, s.setSelectedStep], shallow)
 
     const [isShowAdvanced, setIsShowAdvanced] = useState<string[]>([]);
     const [arrayValues, setArrayValues] = useState<Map<string, string>>(new Map<string, string>());
@@ -748,6 +753,17 @@ export function DslPropertyField(props: Props) {
     }
 
 
+    function changeBean(bean: RegistryBeanDefinition) {
+        const clone = CamelUtil.cloneIntegration(integration);
+        const i = CamelDefinitionApiExt.addBeanToIntegration(clone, bean);
+        setIntegration(i, false);
+        setSelectedStep(bean);
+    }
+
+    function getBeanProperties(type: 'constructors' | 'properties') {
+        return <BeanProperties type={type} onChange={changeBean} onClone={changeBean}/>
+    }
+
     function isMultiValueField(property: PropertyMeta): boolean {
         return ['string'].includes(property.type) && property.name !== 'expression' && property.isArray && !property.enumVals;
     }
@@ -776,6 +792,8 @@ export function DslPropertyField(props: Props) {
     const isKamelet = CamelUtil.isKameletComponent(element);
     const property: PropertyMeta = props.property;
     const value = props.value;
+    const beanConstructors = element?.dslName === 'RegistryBeanDefinition' && property.name === 'constructors'
+    const beanProperties = element?.dslName === 'RegistryBeanDefinition' && property.name === 'properties'
     return (
         <div>
             <FormGroup
@@ -812,6 +830,8 @@ export function DslPropertyField(props: Props) {
                     && getSelect(property, value)}
                 {isKamelet && property.name === 'parameters' && getKameletParameters()}
                 {!isKamelet && property.name === 'parameters' && getComponentParameters(property)}
+                {beanConstructors && getBeanProperties('constructors')}
+                {beanProperties && getBeanProperties('properties')}
             </FormGroup>
             {getInfrastructureSelectorModal()}
         </div>
diff --git a/karavan-designer/src/designer/route/property/ExpressionField.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/property/property/ExpressionField.tsx
similarity index 100%
rename from karavan-designer/src/designer/route/property/ExpressionField.tsx
rename to karavan-web/karavan-app/src/main/webui/src/designer/property/property/ExpressionField.tsx
diff --git a/karavan-designer/src/designer/route/property/InfrastructureSelector.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/property/property/InfrastructureSelector.tsx
similarity index 100%
rename from karavan-designer/src/designer/route/property/InfrastructureSelector.tsx
rename to karavan-web/karavan-app/src/main/webui/src/designer/property/property/InfrastructureSelector.tsx
diff --git a/karavan-designer/src/designer/route/property/KameletPropertyField.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/property/property/KameletPropertyField.tsx
similarity index 100%
rename from karavan-designer/src/designer/route/property/KameletPropertyField.tsx
rename to karavan-web/karavan-app/src/main/webui/src/designer/property/property/KameletPropertyField.tsx
diff --git a/karavan-designer/src/designer/route/property/ModalEditor.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/property/property/ModalEditor.tsx
similarity index 100%
rename from karavan-designer/src/designer/route/property/ModalEditor.tsx
rename to karavan-web/karavan-app/src/main/webui/src/designer/property/property/ModalEditor.tsx
diff --git a/karavan-designer/src/designer/route/property/ObjectField.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/property/property/ObjectField.tsx
similarity index 100%
rename from karavan-designer/src/designer/route/property/ObjectField.tsx
rename to karavan-web/karavan-app/src/main/webui/src/designer/property/property/ObjectField.tsx
diff --git a/karavan-designer/src/designer/route/usePropertiesHook.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/property/usePropertiesHook.tsx
similarity index 84%
rename from karavan-designer/src/designer/route/usePropertiesHook.tsx
rename to karavan-web/karavan-app/src/main/webui/src/designer/property/usePropertiesHook.tsx
index a9bd9ef9..41ac95af 100644
--- a/karavan-designer/src/designer/route/usePropertiesHook.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/property/usePropertiesHook.tsx
@@ -26,17 +26,19 @@ import {RouteToCreate} from "../utils/CamelUi";
 import {useDesignerStore, useIntegrationStore} from "../DesignerStore";
 import {shallow} from "zustand/shallow";
 
-export function usePropertiesHook (isRouteDesigner: boolean = true) {
+export function usePropertiesHook (designerType: 'routes' | 'rest' | 'beans' = 'routes') {
 
     const [integration, setIntegration] = useIntegrationStore((state) => [state.integration, state.setIntegration], shallow)
     const [ selectedStep, setSelectedStep, setSelectedUuids] = useDesignerStore((s) =>
         [s.selectedStep, s.setSelectedStep, s.setSelectedUuids], shallow)
 
     function onPropertyUpdate (element: CamelElement, newRoute?: RouteToCreate) {
-        if (isRouteDesigner) {
+        if (designerType === 'routes') {
             onRoutePropertyUpdate(element, newRoute);
-        } else {
+        } else if (designerType === 'rest') {
             onRestPropertyUpdate(element, newRoute);
+        } else if (designerType === 'beans') {
+            onBeanPropertyUpdate(element, newRoute);
         }
     }
 
@@ -74,6 +76,23 @@ export function usePropertiesHook (isRouteDesigner: boolean = true) {
         }
     }
 
+    function onBeanPropertyUpdate (element: CamelElement, newRoute?: RouteToCreate) {
+        if (newRoute) {
+            let i = CamelDefinitionApiExt.updateIntegrationBeanElement(integration, element);
+            const f = CamelDefinitionApi.createFromDefinition({uri: newRoute.componentName, parameters: {name: newRoute.name}});
+            const r = CamelDefinitionApi.createRouteDefinition({from: f, id: newRoute.name})
+            i = CamelDefinitionApiExt.addStepToIntegration(i, r, '');
+            const clone = CamelUtil.cloneIntegration(i);
+            setIntegration(clone, false);
+            setSelectedStep(element);
+        } else {
+            const clone = CamelUtil.cloneIntegration(integration);
+            const i = CamelDefinitionApiExt.updateIntegrationBeanElement(clone, element);
+            setIntegration(i, true);
+            // setSelectedStep(element);
+        }
+    }
+
     function onPropertyChange (fieldId: string, value: string | number | boolean | any, newRoute?: RouteToCreate){
         value = value === '' ? undefined : value;
         if (selectedStep) {
diff --git a/karavan-web/karavan-app/src/main/webui/src/designer/rest/RestDesigner.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/rest/RestDesigner.tsx
index 303e6bb8..d9b71d4f 100644
--- a/karavan-web/karavan-app/src/main/webui/src/designer/rest/RestDesigner.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/rest/RestDesigner.tsx
@@ -22,7 +22,7 @@ import {
 import './rest.css';
 import '../karavan.css';
 import {CamelElement} from "karavan-core/lib/model/IntegrationDefinition";
-import {DslProperties} from "../route/DslProperties";
+import {DslProperties} from "../property/DslProperties";
 import {RestCard} from "./RestCard";
 import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
 import {
@@ -201,7 +201,7 @@ export function RestDesigner() {
     function getPropertiesPanel() {
         return (
             <DrawerPanelContent isResizable hasNoBorder defaultSize={'400px'} maxSize={'800px'} minSize={'100px'}>
-                <DslProperties isRouteDesigner={false}/>
+                <DslProperties designerType={'rest'}/>
             </DrawerPanelContent>
         )
     }
diff --git a/karavan-web/karavan-app/src/main/webui/src/designer/route/RouteDesigner.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/route/RouteDesigner.tsx
index 3719d3c6..c2ebf292 100644
--- a/karavan-web/karavan-app/src/main/webui/src/designer/route/RouteDesigner.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/route/RouteDesigner.tsx
@@ -24,7 +24,7 @@ import {
 } from '@patternfly/react-core';
 import '../karavan.css';
 import {DslSelector} from "./DslSelector";
-import {DslProperties} from "./DslProperties";
+import {DslProperties} from "../property/DslProperties";
 import {DslConnections} from "./DslConnections";
 import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
 import {DslElement} from "./element/DslElement";
@@ -102,7 +102,7 @@ export function RouteDesigner() {
                                 maxSize={'800px'}
                                 minSize={'400px'}
             >
-                <DslProperties isRouteDesigner={true}/>
+                <DslProperties designerType={'routes'}/>
             </DrawerPanelContent>
         )
     }
diff --git a/karavan-web/karavan-app/src/main/webui/src/topology/TopologyPropertiesPanel.tsx b/karavan-web/karavan-app/src/main/webui/src/topology/TopologyPropertiesPanel.tsx
index 24deca24..8387ce1f 100644
--- a/karavan-web/karavan-app/src/main/webui/src/topology/TopologyPropertiesPanel.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/topology/TopologyPropertiesPanel.tsx
@@ -19,7 +19,7 @@ import '../designer/karavan.css';
 import {shallow} from "zustand/shallow";
 import {TopologySideBar} from "@patternfly/react-topology";
 import {useTopologyStore} from "./TopologyStore";
-import {DslProperties} from "../designer/route/DslProperties";
+import {DslProperties} from "../designer/property/DslProperties";
 import {Button, Flex, FlexItem, Text, Tooltip, TooltipPosition} from "@patternfly/react-core";
 import CloseIcon from "@patternfly/react-icons/dist/esm/icons/times-icon";
 
@@ -62,7 +62,7 @@ export function TopologyPropertiesPanel (props: Props) {
         show={selectedIds.length > 0}
         header={getHeader()}
     >
-        <DslProperties isRouteDesigner={false}/>
+        <DslProperties designerType={'routes'}/>
     </TopologySideBar>
     )
 }