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 2024/03/14 22:20:44 UTC

(camel-karavan) branch main updated: FIx #1175

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 1a5b5b52 FIx #1175
1a5b5b52 is described below

commit 1a5b5b52bf77d08c041c2608d56e64f1f31a3dfe
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Thu Mar 14 18:20:37 2024 -0400

    FIx #1175
---
 karavan-app/src/main/webui/package.json            |    3 +-
 .../property/property/ComponentParameterField.tsx  |  349 ---
 .../property/property/ComponentPropertyField.tsx   |   18 +-
 .../ComponentPropertyPlaceholderDropdown.tsx       |  178 --
 .../property/property/DslPropertyField.tsx         |   50 +-
 .../src/main/webui/src/editor/DesignerEditor.tsx   |    1 -
 .../webui/src/expression/ExpressionBottomPanel.tsx |   80 +
 .../src/expression/ExpressionContextModel.tsx      |  193 ++
 .../webui/src/expression/ExpressionModalEditor.css |   53 +-
 .../webui/src/expression/ExpressionModalEditor.tsx |   58 +-
 karavan-designer/public/example/demo.camel.yaml    |    8 +-
 .../property/property/ComponentPropertyField.tsx   |   18 +-
 .../property/property/DslPropertyField.tsx         |   50 +-
 .../src/expression/ExpressionBottomPanel.tsx       |   80 +
 .../src/expression/ExpressionContextModel.tsx      |  193 ++
 .../src/expression/ExpressionModalEditor.css       |   53 +-
 .../src/expression/ExpressionModalEditor.tsx       |   58 +-
 karavan-space/package.json                         |    3 +-
 karavan-space/src/App.tsx                          |    4 +-
 karavan-space/src/designer/KaravanStore.ts         |  252 ---
 .../src/designer/beans/BeanProperties.tsx          |  342 ---
 .../property/property/ComponentParameterField.tsx  |  349 ---
 .../property/property/ComponentPropertyField.tsx   |   18 +-
 .../ComponentPropertyPlaceholderDropdown.tsx       |  178 --
 .../property/property/DslPropertyField.tsx         |   50 +-
 karavan-space/src/designer/route/DslSelector.css   |  122 -
 karavan-space/src/designer/route/DslSelector.tsx   |  251 ---
 .../src/designer/templates/TemplatesDesigner.tsx   |   71 -
 .../src/designer/utils/KaravanComponents.tsx       |   44 -
 karavan-space/src/designer/utils/KaravanIcons.tsx  | 2347 --------------------
 .../src/expression/ExpressionBottomPanel.tsx       |   80 +
 .../src/expression/ExpressionContextModel.tsx      |  193 ++
 .../ExpressionModalEditor.css}                     |   60 +-
 .../src/expression/ExpressionModalEditor.tsx       |   58 +-
 karavan-vscode/package.json                        |    2 +-
 .../webview/expression/ExpressionBottomPanel.tsx   |   80 +
 .../webview/expression/ExpressionContextModel.tsx  |  193 ++
 .../webview/expression/ExpressionModalEditor.css   |   53 +-
 .../webview/expression/ExpressionModalEditor.tsx   |   58 +-
 39 files changed, 1532 insertions(+), 4719 deletions(-)

diff --git a/karavan-app/src/main/webui/package.json b/karavan-app/src/main/webui/package.json
index 573fc9f9..30229474 100644
--- a/karavan-app/src/main/webui/package.json
+++ b/karavan-app/src/main/webui/package.json
@@ -4,9 +4,10 @@
   "private": true,
   "scripts": {
     "copy-designer": "cp -r ../../../../karavan-designer/src/designer src",
+    "copy-expression": "cp -r ../../../../karavan-designer/src/expression src",
     "copy-knowledgebase": "cp -r ../../../../karavan-designer/src/knowledgebase src",
     "copy-topology": "cp -r ../../../../karavan-designer/src/topology src",
-    "copy-code": " npm run copy-designer &&  npm run copy-knowledgebase &&  npm run copy-topology",
+    "copy-code": " npm run copy-designer && npm run copy-expression && npm run copy-knowledgebase &&  npm run copy-topology",
     "start": "export PORT=3003 && npm run copy-code && react-scripts start",
     "build": "npm run copy-code && DISABLE_ESLINT_PLUGIN=true react-scripts build"
   },
diff --git a/karavan-app/src/main/webui/src/designer/property/property/ComponentParameterField.tsx b/karavan-app/src/main/webui/src/designer/property/property/ComponentParameterField.tsx
deleted file mode 100644
index 7186616d..00000000
--- a/karavan-app/src/main/webui/src/designer/property/property/ComponentParameterField.tsx
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React, {useRef, useState} from 'react';
-import {
-    FormGroup,
-    TextInput,
-    Popover,
-    Switch,
-    InputGroup,
-    TextArea,
-    Tooltip,
-    Button,
-    capitalize, InputGroupItem
-} from '@patternfly/react-core';
-import {
-    Select,
-    SelectVariant,
-    SelectDirection,
-    SelectOption
-} from '@patternfly/react-core/deprecated';
-import '../../karavan.css';
-import "@patternfly/patternfly/patternfly.css";
-import HelpIcon from "@patternfly/react-icons/dist/js/icons/help-icon";
-import {ComponentProperty} from "karavan-core/lib/model/ComponentModels";
-import {CamelUi, RouteToCreate} from "../../utils/CamelUi";
-import {CamelElement} from "karavan-core/lib/model/IntegrationDefinition";
-import {ToDefinition} from "karavan-core/lib/model/CamelDefinition";
-import CompressIcon from "@patternfly/react-icons/dist/js/icons/compress-icon";
-import ExpandIcon from "@patternfly/react-icons/dist/js/icons/expand-icon";
-import {InfrastructureSelector} from "./InfrastructureSelector";
-import {InfrastructureAPI} from "../../utils/InfrastructureAPI";
-import DockerIcon from "@patternfly/react-icons/dist/js/icons/docker-icon";
-import ShowIcon from "@patternfly/react-icons/dist/js/icons/eye-icon";
-import HideIcon from "@patternfly/react-icons/dist/js/icons/eye-slash-icon";
-import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
-import {usePropertiesHook} from "../usePropertiesHook";
-import {useIntegrationStore} from "../../DesignerStore";
-import {shallow} from "zustand/shallow";
-import {KubernetesIcon} from "../../icons/ComponentIcons";
-
-const prefix = "parameters";
-const beanPrefix = "#bean:";
-
-interface Props {
-    property: ComponentProperty,
-    element?: CamelElement,
-    value: any,
-    onParameterChange?: (parameter: string, value: string | number | boolean | any, pathParameter?: boolean, newRoute?: RouteToCreate) => void
-}
-
-export function ComponentParameterField(props: Props) {
-
-    const {onParametersChange, getInternalComponentName} = usePropertiesHook();
-
-    const [integration] = useIntegrationStore((state) => [state.integration], shallow)
-
-    const [selectStatus, setSelectStatus] = useState<Map<string, boolean>>(new Map<string, boolean>());
-    const [showEditor, setShowEditor] = useState<boolean>(false);
-    const [showPassword, setShowPassword] = useState<boolean>(false);
-    const [infrastructureSelector, setInfrastructureSelector] = useState<boolean>(false);
-    const [infrastructureSelectorProperty, setInfrastructureSelectorProperty] = useState<string | undefined>(undefined);
-
-    const [id, setId] = useState<string>(prefix + "-" + props.property.name);
-    const ref = useRef<any>(null);
-
-
-    function parametersChanged(parameter: string, value: string | number | boolean | any, pathParameter?: boolean, newRoute?: RouteToCreate) {
-        onParametersChange(parameter, value, pathParameter, newRoute);
-        setSelectStatus(new Map<string, boolean>([[parameter, false]]))
-    }
-
-    function openSelect(propertyName: string, isExpanded: boolean) {
-        setSelectStatus(new Map<string, boolean>([[propertyName, isExpanded]]))
-    }
-
-    function isSelectOpen(propertyName: string): boolean {
-        return selectStatus.has(propertyName) && selectStatus.get(propertyName) === true;
-    }
-
-    function getSelectBean(property: ComponentProperty, value: any) {
-        const selectOptions: JSX.Element[] = [];
-        const beans = CamelUi.getBeans(integration);
-        if (beans) {
-            selectOptions.push(<SelectOption key={0} value={"Select..."} isPlaceholder/>);
-            selectOptions.push(...beans.map((bean) => <SelectOption key={bean.name} value={beanPrefix + bean.name}
-                                                                    description={bean.type}/>));
-        }
-        return (
-            <Select
-                id={id} name={id}
-                variant={SelectVariant.typeahead}
-                aria-label={property.name}
-                onToggle={(_event, isExpanded) => {
-                    openSelect(property.name, isExpanded)
-                }}
-                onSelect={(e, value, isPlaceholder) => parametersChanged(property.name, (!isPlaceholder ? value : undefined))}
-                selections={value}
-                isCreatable={true}
-                createText=""
-                isOpen={isSelectOpen(property.name)}
-                aria-labelledby={property.name}
-                direction={SelectDirection.down}
-            >
-                {selectOptions}
-            </Select>
-        )
-    }
-
-    function canBeInternalUri(property: ComponentProperty): boolean {
-        if (props.element && props.element.dslName === 'ToDefinition' && property.name === 'name') {
-            const uri: string = (props.element as ToDefinition).uri || '';
-            return uri.startsWith("direct") || uri.startsWith("seda");
-        } else {
-            return false;
-        }
-    }
-
-    function getInternalUriSelect(property: ComponentProperty, value: any) {
-        const selectOptions: JSX.Element[] = [];
-        const componentName = getInternalComponentName(property.name, props.element);
-        const internalUris = CamelUi.getInternalRouteUris(integration, componentName, false);
-        const uris: string [] = [];
-        uris.push(...internalUris);
-        if (value && value.length > 0 && !uris.includes(value)) {
-            uris.unshift(value);
-        }
-        if (uris && uris.length > 0) {
-            selectOptions.push(...uris.map((value: string) =>
-                <SelectOption key={value} value={value ? value.trim() : value}/>));
-        }
-        return <InputGroup id={id} name={id}>
-            <InputGroupItem isFill>
-                <Select
-                    id={id} name={id}
-                    placeholderText="Select or type an URI"
-                    variant={SelectVariant.typeahead}
-                    aria-label={property.name}
-                    onToggle={(_event, isExpanded) => {
-                        openSelect(property.name, isExpanded)
-                    }}
-                    onSelect={(e, value, isPlaceholder) => {
-                        parametersChanged(property.name, (!isPlaceholder ? value : undefined), property.kind === 'path', undefined);
-                    }}
-                    selections={value}
-                    isOpen={isSelectOpen(property.name)}
-                    isCreatable={true}
-                    createText=""
-                    isInputFilterPersisted={true}
-                    aria-labelledby={property.name}
-                    direction={SelectDirection.down}>
-                    {selectOptions}
-                </Select>
-            </InputGroupItem>
-            <InputGroupItem>
-                <Tooltip position="bottom-end" content={"Create route"}>
-                    <Button isDisabled={value === undefined} variant="control" onClick={e => {
-                        if (value) {
-                            const newRoute = !internalUris.includes(value.toString())
-                                ? CamelUi.createNewInternalRoute(componentName.concat(...':',value.toString()))
-                                : undefined;
-                            parametersChanged(property.name, value, property.kind === 'path', newRoute);
-                        }
-                    }}>
-                        {<PlusIcon/>}
-                    </Button>
-                </Tooltip>
-            </InputGroupItem>
-        </InputGroup>
-    }
-
-    function selectInfrastructure(value: string) {
-        // check if there is a selection
-        const textVal = ref.current;
-        const cursorStart = textVal.selectionStart;
-        const cursorEnd = textVal.selectionEnd;
-        if (cursorStart !== cursorEnd) {
-            const prevValue = props.value;
-            const selectedText = prevValue.substring(cursorStart, cursorEnd)
-            value = prevValue.replace(selectedText, value);
-        }
-        const propertyName = infrastructureSelectorProperty;
-        if (propertyName) {
-            if (value.startsWith("config") || value.startsWith("secret")) value = "{{" + value + "}}";
-            parametersChanged(propertyName, value);
-            setInfrastructureSelector(false);
-            setInfrastructureSelectorProperty(undefined);
-        }
-    }
-
-    function openInfrastructureSelector(propertyName: string) {
-        setInfrastructureSelector(true);
-        setInfrastructureSelectorProperty(propertyName);
-    }
-
-
-    function getInfrastructureSelectorModal() {
-        return (
-            <InfrastructureSelector
-                dark={false}
-                isOpen={infrastructureSelector}
-                onClose={() => setInfrastructureSelector(false)}
-                onSelect={selectInfrastructure}/>)
-    }
-
-    function getStringInput(property: ComponentProperty, value: any) {
-        const inInfrastructure = InfrastructureAPI.infrastructure !== 'local';
-        const noInfraSelectorButton = ["uri", "id", "description", "group"].includes(property.name);
-        const icon = InfrastructureAPI.infrastructure === 'kubernetes' ? KubernetesIcon("infra-button") : <DockerIcon/>
-        return <InputGroup>
-            {inInfrastructure && !showEditor && !noInfraSelectorButton &&
-                <Tooltip position="bottom-end"
-                         content={"Select from " + capitalize((InfrastructureAPI.infrastructure))}>
-                    <Button variant="control" onClick={e => openInfrastructureSelector(property.name)}>
-                        {icon}
-                    </Button>
-                </Tooltip>}
-            {(!showEditor || property.secret) &&
-                <TextInput className="text-field" isRequired ref={ref}
-                           type={property.secret && !showPassword ? "password" : "text"}
-                           id={id} name={id}
-                           value={value !== undefined ? value : property.defaultValue}
-                           onChange={(e, value) => parametersChanged(property.name, value, property.kind === 'path')}/>}
-            {showEditor && !property.secret &&
-                <TextArea autoResize={true} ref={ref}
-                          className="text-field" isRequired
-                          type="text"
-                          id={id} name={id}
-                          value={value !== undefined ? value : property.defaultValue}
-                          onChange={(e, value) => parametersChanged(property.name, value, property.kind === 'path')}/>}
-            {!property.secret &&
-                <Tooltip position="bottom-end" content={showEditor ? "Change to TextField" : "Change to Text Area"}>
-                    <Button variant="control" onClick={e => setShowEditor(!showEditor)}>
-                        {showEditor ? <CompressIcon/> : <ExpandIcon/>}
-                    </Button>
-                </Tooltip>
-            }
-            {property.secret &&
-                <Tooltip position="bottom-end" content={showPassword ? "Hide" : "Show"}>
-                    <Button variant="control" onClick={e => setShowPassword(!showPassword)}>
-                        {showPassword ? <ShowIcon/> : <HideIcon/>}
-                    </Button>
-                </Tooltip>
-            }
-        </InputGroup>
-    }
-
-    function getTextInput(property: ComponentProperty, value: any) {
-        return (
-            <TextInput
-                className="text-field" isRequired
-                type={['integer', 'int', 'number'].includes(property.type) ? 'number' : (property.secret ? "password" : "text")}
-                id={id} name={id}
-                value={value !== undefined ? value : property.defaultValue}
-                onChange={(_, value) => {
-                    parametersChanged(property.name, ['integer', 'int', 'number'].includes(property.type) ? Number(value) : value, property.kind === 'path')
-                }}/>
-        )
-    }
-
-    function getSelect(property: ComponentProperty, value: any) {
-        const selectOptions: JSX.Element[] = []
-        if (property.enum && property.enum.length > 0) {
-            selectOptions.push(<SelectOption key={0} value={"Select ..."} isPlaceholder/>);
-            property.enum.forEach(v => selectOptions.push(<SelectOption key={v} value={v}/>));
-        }
-        return (
-            <Select
-                id={id} name={id}
-                variant={SelectVariant.single}
-                aria-label={property.name}
-                onToggle={(_event, isExpanded) => {
-                    openSelect(property.name, isExpanded)
-                }}
-                onSelect={(e, value, isPlaceholder) => parametersChanged(property.name, (!isPlaceholder ? value : undefined), property.kind === 'path')}
-                selections={value !== undefined ? value.toString() : property.defaultValue}
-                isOpen={isSelectOpen(property.name)}
-                aria-labelledby={property.name}
-                direction={SelectDirection.down}
-            >
-                {selectOptions}
-            </Select>
-        )
-    }
-
-    function getSwitch(property: ComponentProperty, value: any) {
-        const isChecked = value !== undefined ? Boolean(value) : (property.defaultValue !== undefined && ['true', true].includes(property.defaultValue))
-        return (
-            <Switch
-                id={id} name={id}
-                value={value?.toString()}
-                aria-label={id}
-                isChecked={isChecked}
-                onChange={(e, checked) => parametersChanged(property.name, checked)}/>
-        )
-    }
-
-    const property: ComponentProperty = props.property;
-    const value = props.value;
-    return (
-        <FormGroup
-            key={id}
-            label={property.displayName}
-            isRequired={property.required}
-            labelIcon={
-                <Popover
-                    position={"left"}
-                    headerContent={property.displayName}
-                    bodyContent={property.description}
-                    footerContent={
-                        <div>
-                            {property.defaultValue !== undefined && <div>{"Default: " + property.defaultValue}</div>}
-                            {property.required && <div>{property.displayName + " is required"}</div>}
-                        </div>
-                    }>
-                    <button type="button" aria-label="More info" onClick={e => e.preventDefault()}
-                            className="pf-v5-c-form__group-label-help">
-                        <HelpIcon/>
-                    </button>
-                </Popover>
-            }>
-            {canBeInternalUri(property) && getInternalUriSelect(property, value)}
-            {property.type === 'string' && property.enum === undefined && !canBeInternalUri(property)
-                && getStringInput(property, value)}
-            {['duration', 'integer', 'int', 'number'].includes(property.type) && property.enum === undefined && !canBeInternalUri(property)
-                && getTextInput(property, value)}
-            {['object'].includes(property.type) && !property.enum
-                && getSelectBean(property, value)}
-            {['string', 'object'].includes(property.type) && property.enum
-                && getSelect(property, value)}
-            {property.type === 'boolean'
-                && getSwitch(property, value)}
-            {getInfrastructureSelectorModal()}
-        </FormGroup>
-    )
-}
diff --git a/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyField.tsx b/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyField.tsx
index e7460847..52488a89 100644
--- a/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyField.tsx
+++ b/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyField.tsx
@@ -53,7 +53,7 @@ import {useDesignerStore, useIntegrationStore} from "../../DesignerStore";
 import {shallow} from "zustand/shallow";
 import {KubernetesIcon} from "../../icons/ComponentIcons";
 import EditorIcon from "@patternfly/react-icons/dist/js/icons/code-icon";
-import {ModalEditor} from "./ModalEditor";
+import {ExpressionModalEditor} from "../../../expression/ExpressionModalEditor";
 import {PropertyPlaceholderDropdown} from "./PropertyPlaceholderDropdown";
 
 const prefix = "parameters";
@@ -280,14 +280,14 @@ export function ComponentPropertyField(props: Props) {
                 </Tooltip>
             </InputGroupItem>
             {showEditor && <InputGroupItem>
-                <ModalEditor name={property.name}
-                             customCode={value}
-                             showEditor={showEditor}
-                             dark={dark}
-                             dslLanguage={undefined}
-                             title={property.displayName}
-                             onClose={() => setShowEditor(false)}
-                             onSave={(fieldId, value1) => {
+                <ExpressionModalEditor name={property.name}
+                                       customCode={value}
+                                       showEditor={showEditor}
+                                       dark={dark}
+                                       dslLanguage={undefined}
+                                       title={property.displayName}
+                                       onClose={() => setShowEditor(false)}
+                                       onSave={(fieldId, value1) => {
                                  setTextValue(value1);
                                  parametersChanged(property.name, value1, property.kind === 'path')
                                  setShowEditor(false);
diff --git a/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyPlaceholderDropdown.tsx b/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyPlaceholderDropdown.tsx
deleted file mode 100644
index f287c300..00000000
--- a/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyPlaceholderDropdown.tsx
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React, {useState} from 'react';
-import {
-    Dropdown,
-    MenuToggleElement,
-    MenuToggle,
-    DropdownList,
-    DropdownItem,
-    Popover,
-    Flex,
-    TextInput,
-    FormGroup,
-    Form,
-    Button,
-    FlexItem,
-    DropdownGroup, Divider
-} from '@patternfly/react-core';
-import '../../karavan.css';
-import './ComponentPropertyPlaceholderDropdown.css';
-import "@patternfly/patternfly/patternfly.css";
-import {ComponentProperty} from "karavan-core/lib/model/ComponentModels";
-import {RouteToCreate} from "../../utils/CamelUi";
-import {usePropertiesHook} from "../usePropertiesHook";
-import {useDesignerStore} from "../../DesignerStore";
-import {shallow} from "zustand/shallow";
-import EllipsisVIcon from "@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon";
-import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-icon";
-import {InfrastructureAPI} from "../../utils/InfrastructureAPI";
-
-const SYNTAX_EXAMPLES = [
-    {key: 'property:', value: 'group.property', description: 'Application property'},
-    {key: 'env:', value: 'env:ENV_NAME', description: 'OS environment variable'},
-    {key: 'sys:', value: 'sys:JvmPropertyName', description: 'JVM system property'},
-    {key: 'bean:', value: 'bean:beanName.method', description: 'Bean’s method'}
-]
-
-interface Props {
-    property: ComponentProperty,
-    value: any
-}
-
-export function ComponentPropertyPlaceholderDropdown(props: Props) {
-
-    const {onParametersChange} = usePropertiesHook();
-    const [propertyPlaceholders, setPropertyPlaceholders] = useDesignerStore((s) =>
-        [s.propertyPlaceholders, s.setPropertyPlaceholders], shallow)
-    const [isOpenPlaceholdersDropdown, setOpenPlaceholdersDropdown] = useState<boolean>(false);
-    const [propValue, setPropValue] = useState<string>('');
-    const [isVisible, setIsVisible] = React.useState(false);
-
-    function removeBrackets(val: string) {
-        return val.replace('{{', '').replace('}}', '');
-    }
-
-    const {property, value} = props;
-    const valueIsPlaceholder: boolean = value && value.toString().startsWith('{{') && value.toString().endsWith('}}');
-    const placeholderValue = valueIsPlaceholder ? value.toString().replace('{{', '').replace('}}', '') : undefined;
-    const showAddButton = valueIsPlaceholder
-        && !propertyPlaceholders.includes(placeholderValue)
-        && !SYNTAX_EXAMPLES.map(se=> se.value).includes(removeBrackets(placeholderValue))
-        && SYNTAX_EXAMPLES.findIndex(se=> removeBrackets(placeholderValue).startsWith(se.key)) === -1;
-    const popoverId = "popover-selector-" + property.name;
-
-    const hasPlaceholders = (propertyPlaceholders && propertyPlaceholders.length > 0 );
-
-    function parametersChanged(parameter: string, value: string | number | boolean | any, pathParameter?: boolean, newRoute?: RouteToCreate) {
-        onParametersChange(parameter, value, pathParameter, newRoute);
-    }
-
-    function onMenuToggleClick() {
-        if (!showAddButton) {
-            setOpenPlaceholdersDropdown(!isOpenPlaceholdersDropdown)
-        }
-    }
-
-    function saveProperty() {
-        InfrastructureAPI.onSavePropertyPlaceholder(placeholderValue, propValue);
-        setIsVisible(false);
-        const p = [...propertyPlaceholders]
-        p.push(placeholderValue);
-        setPropertyPlaceholders(p);
-    }
-
-    function getPopover() {
-        return (
-            <Popover
-                isVisible={isVisible}
-                shouldOpen={(_event, _fn) => setIsVisible(true)}
-                shouldClose={(_event, _fn) => setIsVisible(false)}
-                aria-label="Add property"
-                headerContent={"Add property"}
-                bodyContent={
-                    <Form isHorizontal className="property-placeholder-toggle-form" autoComplete="off">
-                        <FormGroup isInline label="Property" isRequired fieldId="property">
-                            <TextInput id="property" readOnly value={placeholderValue}/>
-                        </FormGroup>
-                        <FormGroup isInline label="Value" isRequired fieldId="value">
-                            <TextInput id="value" isRequired value={propValue}
-                                       onChange={(_, value) => setPropValue(value)}/>
-                        </FormGroup>
-                    </Form>
-                }
-                footerContent={
-                    <Flex>
-                        <FlexItem align={{default: "alignRight"}}>
-                            <Button
-                                onClick={() => saveProperty()}>
-                                Save
-                            </Button>
-                        </FlexItem>
-                    </Flex>
-                }
-                triggerRef={() => document.getElementById(popoverId) as HTMLButtonElement}
-            />
-        )
-    }
-
-    function getToggle(toggleRef: React.Ref<MenuToggleElement>) {
-        return (
-            <MenuToggle className="property-placeholder-toggle"
-                        id={popoverId}
-                        ref={toggleRef}
-                        aria-label="placeholder menu"
-                        variant="default"
-                        onClick={() => onMenuToggleClick()}
-                        isExpanded={isOpenPlaceholdersDropdown}
-            >
-                {showAddButton ? <AddIcon/> : <EllipsisVIcon/>}
-                {showAddButton && getPopover()}
-            </MenuToggle>
-        )
-    }
-
-    return (
-        <Dropdown
-            popperProps={{position: "end"}}
-            isOpen={isOpenPlaceholdersDropdown}
-            onSelect={(_, value) => {
-                parametersChanged(property.name, `{{${value}}}`, property.kind === 'path')
-                setOpenPlaceholdersDropdown(false);
-            }}
-            onOpenChange={(isOpen: boolean) => setOpenPlaceholdersDropdown(isOpen)}
-            toggle={(toggleRef: React.Ref<MenuToggleElement>) => getToggle(toggleRef)}
-            shouldFocusToggleOnSelect
-        >
-            <DropdownList>
-                {hasPlaceholders && <DropdownGroup label="Application Properties">
-                    {propertyPlaceholders.map((pp, index) =>
-                        <DropdownItem value={pp} key={index}>{pp}</DropdownItem>
-                    )}
-                </DropdownGroup>}
-                {hasPlaceholders && <Divider component="li"/>}
-                <DropdownGroup label="Syntax examples">
-                    {SYNTAX_EXAMPLES.map(se =>
-                        <DropdownItem value={se.value} key={se.key} description={se.description}>
-                            {se.value}
-                        </DropdownItem>)
-                    }
-                </DropdownGroup>
-            </DropdownList>
-        </Dropdown>
-    )
-}
diff --git a/karavan-app/src/main/webui/src/designer/property/property/DslPropertyField.tsx b/karavan-app/src/main/webui/src/designer/property/property/DslPropertyField.tsx
index cd137961..86240ed7 100644
--- a/karavan-app/src/main/webui/src/designer/property/property/DslPropertyField.tsx
+++ b/karavan-app/src/main/webui/src/designer/property/property/DslPropertyField.tsx
@@ -62,7 +62,7 @@ import {ComponentProperty} from "karavan-core/lib/model/ComponentModels";
 import {InfrastructureSelector} from "./InfrastructureSelector";
 import {InfrastructureAPI} from "../../utils/InfrastructureAPI";
 import EditorIcon from "@patternfly/react-icons/dist/js/icons/code-icon";
-import {ModalEditor} from "./ModalEditor";
+import {ExpressionModalEditor} from "../../../expression/ExpressionModalEditor";
 import DockerIcon from "@patternfly/react-icons/dist/js/icons/docker-icon";
 import {useDesignerStore, useIntegrationStore} from "../../DesignerStore";
 import {shallow} from "zustand/shallow";
@@ -394,14 +394,14 @@ export function DslPropertyField(props: Props) {
                 </Tooltip>
             </InputGroupItem>}
             {showEditor && <InputGroupItem>
-                <ModalEditor name={property.name}
-                             customCode={value}
-                             showEditor={showEditor}
-                             dark={dark}
-                             dslLanguage={undefined}
-                             title={property.displayName}
-                             onClose={() => setShowEditor(false)}
-                             onSave={(fieldId, value1) => {
+                <ExpressionModalEditor name={property.name}
+                                       customCode={value}
+                                       showEditor={showEditor}
+                                       dark={dark}
+                                       dslLanguage={undefined}
+                                       title={property.displayName}
+                                       onClose={() => setShowEditor(false)}
+                                       onSave={(fieldId, value1) => {
                                  propertyChanged(property.name, value1)
                                  setTextValue(value1);
                                  setShowEditor(false);
@@ -448,14 +448,14 @@ export function DslPropertyField(props: Props) {
                 </Tooltip>
             </InputGroupItem>
             {showEditor && <InputGroupItem>
-                <ModalEditor name={property.name}
-                             customCode={customCode}
-                             showEditor={showEditor}
-                             dark={dark}
-                             dslLanguage={dslLanguage}
-                             title="Java Class"
-                             onClose={() => setShowEditor(false)}
-                             onSave={(fieldId, value1) => {
+                <ExpressionModalEditor name={property.name}
+                                       customCode={customCode}
+                                       showEditor={showEditor}
+                                       dark={dark}
+                                       dslLanguage={dslLanguage}
+                                       title="Java Class"
+                                       onClose={() => setShowEditor(false)}
+                                       onSave={(fieldId, value1) => {
                                  propertyChanged(fieldId, value);
                                  InfrastructureAPI.onSaveCustomCode?.(value, value1);
                                  setShowEditor(false)
@@ -491,14 +491,14 @@ export function DslPropertyField(props: Props) {
                     </Tooltip>
                 </InputGroupItem>
                 {showEditor && <InputGroupItem>
-                    <ModalEditor name={property.name}
-                                 customCode={value}
-                                 showEditor={showEditor}
-                                 dark={dark}
-                                 dslLanguage={dslLanguage}
-                                 title={`Expression (${dslLanguage?.[0]})`}
-                                 onClose={() => setShowEditor(false)}
-                                 onSave={(fieldId, value1) => {
+                    <ExpressionModalEditor name={property.name}
+                                           customCode={value}
+                                           showEditor={showEditor}
+                                           dark={dark}
+                                           dslLanguage={dslLanguage}
+                                           title={`Expression (${dslLanguage?.[0]})`}
+                                           onClose={() => setShowEditor(false)}
+                                           onSave={(fieldId, value1) => {
                                      propertyChanged(fieldId, value1);
                                      setTextValue(value1);
                                      setShowEditor(false);
diff --git a/karavan-app/src/main/webui/src/editor/DesignerEditor.tsx b/karavan-app/src/main/webui/src/editor/DesignerEditor.tsx
index a4391f72..1ff1e947 100644
--- a/karavan-app/src/main/webui/src/editor/DesignerEditor.tsx
+++ b/karavan-app/src/main/webui/src/editor/DesignerEditor.tsx
@@ -16,7 +16,6 @@
  */
 import React, {useEffect, useState} from 'react';
 import '../designer/karavan.css';
-import Editor from "@monaco-editor/react";
 import {ProjectFile} from "../api/ProjectModels";
 import {useFilesStore, useFileStore} from "../api/ProjectStore";
 import {KaravanDesigner} from "../designer/KaravanDesigner";
diff --git a/karavan-app/src/main/webui/src/expression/ExpressionBottomPanel.tsx b/karavan-app/src/main/webui/src/expression/ExpressionBottomPanel.tsx
new file mode 100644
index 00000000..4aef03a4
--- /dev/null
+++ b/karavan-app/src/main/webui/src/expression/ExpressionBottomPanel.tsx
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React from 'react';
+import {ClipboardCopy, Text, TextContent} from '@patternfly/react-core';
+import './ExpressionModalEditor.css'
+import {Table, Tbody, Td, Tr} from "@patternfly/react-table";
+import {Context, ExpressionFunctions, ExpressionVariables} from "./ExpressionContextModel";
+
+interface Props {
+    dslLanguage?: [string, string, string],
+}
+
+export function ExpressionBottomPanel(props: Props) {
+
+    const {dslLanguage} = props;
+    const language = dslLanguage?.[0];
+    const vars: Context[] = ExpressionVariables.filter(e => e.name === language)?.[0]?.information || [];
+    const funcs: Context[] = ExpressionFunctions.filter(e => e.name === language)?.at(0)?.information || []
+    const showVars = vars.length > 0;
+    const showFuncs = funcs.length > 0;
+
+    function getRows(data: Context[]) {
+        return (
+            data?.map((context, index, array) =>
+                <Tr key={index} style={{padding: '0'}}>
+                    <Td style={{padding: '0px 0px 6px 0px'}} modifier='fitContent'>
+                        <ClipboardCopy key={index} hoverTip="Copy" clickTip="Copied"
+                                       variant="inline-compact">
+                            {context.key}
+                        </ClipboardCopy>
+                    </Td>
+                    <Td style={{padding: '0px 0px 0px 16px'}}>
+                        {context.value}
+                    </Td>
+                </Tr>
+            )
+        )
+    }
+
+    function getRowHeader(data: string) {
+        return (
+            <Tr key='vars' style={{padding: '0'}}>
+                <Td style={{padding: '16px 6px 6px 0px'}}>
+                    <TextContent>
+                        <Text component='h3'>{data}</Text>
+                    </TextContent>
+                </Td>
+            </Tr>
+        )
+    }
+
+    return (
+        <div className='context'>
+            <div className='context-column'>
+                <Table variant='compact' borders={false}>
+                    <Tbody>
+                        {showVars && getRowHeader('Variables')}
+                        {showVars && getRows(vars)}
+                        {showFuncs && getRowHeader('Functions')}
+                        {showFuncs && getRows(funcs)}
+                    </Tbody>
+                </Table>
+            </div>
+        </div>
+    )
+}
diff --git a/karavan-app/src/main/webui/src/expression/ExpressionContextModel.tsx b/karavan-app/src/main/webui/src/expression/ExpressionContextModel.tsx
new file mode 100644
index 00000000..3f0a3411
--- /dev/null
+++ b/karavan-app/src/main/webui/src/expression/ExpressionContextModel.tsx
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export class ExpressionContext {
+    name: string = '';
+    information: Context[] = [];
+
+    constructor(name: string, information: Context[]) {
+        this.name = name;
+        this.information = information;
+    }
+}
+
+export class Context {
+    key: string = '';
+    value: string = '';
+
+    constructor(key: string, value: string) {
+        this.key = key;
+        this.value = value;
+    }
+}
+
+export const ExpressionVariables: ExpressionContext[] = [
+    new ExpressionContext('groovy', [
+            new Context('exchange', 'The Exchange itself.'),
+            new Context('exchangeProperties', 'The Exchange properties.'),
+            new Context('variables', 'The variables'),
+            new Context('headers', 'The headers of the In message.'),
+            new Context('camelContext', 'The Camel Context.'),
+            new Context('request', 'The In message.'),
+            new Context('body', 'The message body'),
+            new Context('response', 'The Out message (only for InOut message exchange pattern).')
+        ]
+    ),
+    new ExpressionContext('java', [
+            new Context('exchange', 'The Exchange itself.'),
+            new Context('message', 'The Camel message.'),
+            new Context('context', 'The Camel Context.'),
+            new Context('body', 'The message body')
+        ]
+    ),
+    new ExpressionContext('javascript', [
+            new Context('this', 'the Exchange is the root object.'),
+            new Context('context', 'The Camel Context.'),
+            new Context('exchange', 'The Exchange itself.'),
+            new Context('exchangeId', 'The ExchangeID.'),
+            new Context('message', 'The Camel message.'),
+            new Context('body', 'The message body'),
+            new Context('headers', 'The message headers'),
+            new Context('properties', 'The message properties')
+        ]
+    ),
+    new ExpressionContext('jq', [
+            new Context('header', 'Allow accessing the Message header ex. header(\\"MyHeader\\")'),
+            new Context('property', 'Allow accessing the Message property ex. property(\\"MyProperty\\")'),
+            new Context('constant', 'Allow accessing constant value as-is '),
+
+        ]
+    ),
+    new ExpressionContext('simple', [
+            new Context('camelId', 'the CamelContext name'),
+            new Context('camelContext.*OGNL*', 'the CamelContext invoked using a Camel OGNL expression.'),
+            new Context('exchange', 'the Exchange'),
+            new Context('exchange.*OGNL*', 'the Exchange invoked using a Camel OGNL expression.'),
+            new Context('exchangeId', 'the exchange id'),
+            new Context('id', 'the message id'),
+            new Context('messageTimestamp', 'the message timestamp (millis since epoc) that this message originates from.'),
+            new Context('body ', 'the body'),
+            new Context('body.*OGNL*', 'the body invoked using a Camel OGNL expression.'),
+            new Context('bodyAs(_type_)', 'Converts the body to the given type determined by its classname. The converted body can be null.'),
+            new Context('bodyAs(_type_).*OGNL* ', 'Converts the body to the given type determined by its classname and then invoke methods using a Camel OGNL expression. The converted body can be null.'),
+            new Context('bodyOneLine', 'Converts the body to a String and removes all line-breaks so the string is in one line.'),
+            new Context('prettyBody', 'Converts the body to a String, and attempts to pretty print if JSon or XML, otherwise the body is returned as the String value.'),
+            new Context('originalBody', 'The original incoming body (only available if allowUseOriginalMessage=true).'),
+            new Context('mandatoryBodyAs(_type_)', 'Converts the body to the given type determined by its classname, and expects the body to be not null.'),
+            new Context('mandatoryBodyAs(_type_).*OGNL* ', 'Converts the body to the given type determined by its classname and then invoke methods using a Camel OGNL expression.'),
+            new Context('header.foo ', 'refer to the foo header'),
+            new Context('header[foo] ', 'refer to the foo header'),
+            new Context('headers.foo ', 'refer to the foo header'),
+            new Context('headers:foo ', 'refer to the foo header'),
+            new Context('headers[foo] ', 'refer to the foo header'),
+            new Context('header.foo[bar] ', 'regard foo header as a map and perform lookup on the map with bar as key'),
+            new Context('header.foo.*OGNL*', 'refer to the foo header and invoke its value using a Camel OGNL expression.'),
+            new Context('headerAs(_key_,_type_)', 'converts the header to the given type determined by its classname'),
+            new Context('headers', 'refer to the headers'),
+            new Context('variable.foo ', 'refer to the foo variable'),
+            new Context('variable[foo] ', 'refer to the foo variable'),
+            new Context('variable.foo.*OGNL* ', 'refer to the foo variable and invoke its value using a Camel OGNL expression.'),
+            new Context('variableAs(_key_,_type_)', 'converts the variable to the given type determined by its classname'),
+            new Context('variables', 'refer to the variables'),
+            new Context('exchangeProperty.foo ', 'refer to the foo property on the exchange'),
+            new Context('exchangeProperty[foo] ', 'refer to the foo property on the exchange'),
+            new Context('exchangeProperty.foo.*OGNL* ', 'refer to the foo property on the exchange and invoke its value using a Camel OGNL expression.'),
+            new Context('messageAs(_type_)', 'Converts the message to the given type determined by its classname. The converted message can be null. '),
+            new Context('messageAs(_type_).*OGNL* ', 'Converts the message to the given type determined by its classname and then invoke methods using a Camel OGNL expression. The converted message can be null. '),
+            new Context('sys.foo', 'refer to the JVM system property'),
+            new Context('sysenv.foo', 'refer to the system environment variable'),
+            new Context('env.foo', 'refer to the system environment variable'),
+            new Context('exception ', 'refer to the exception object on the exchange, is *null* if no exception set on exchange. Will fallback and grab caught exceptions (`Exchange.EXCEPTION_CAUGHT`) if the Exchange has any.'),
+            new Context('exception.*OGNL* ', 'refer to the exchange exception invoked using a Camel OGNL expression object'),
+            new Context('exception.message', 'refer to the exception.message on the exchange, is *null* if no exception set on exchange. Will fallback and grab caught exceptions (`Exchange.EXCEPTION_CAUGHT`) if the Exchange has any.'),
+            new Context('exception.stacktrace', 'refer to the exception.stracktrace on the exchange, is  *null* if no exception set on exchange. Will fallback and grab caught exceptions (`Exchange.EXCEPTION_CAUGHT`) if the Exchange has any.'),
+            new Context('date:_command_', `evaluates to a Date object. Supported commands are: *now* for current timestamp,
+*exchangeCreated* for the timestamp when the current exchange was created,
+*header.xxx* to use the Long/Date object in the header with the key xxx.
+*variable.xxx* to use the Long/Date in the variable with the key xxx.
+*exchangeProperty.xxx* to use the Long/Date object in the exchange property with the key xxx.
+*file* for the last modified timestamp of the file (available with a File consumer).
+Command accepts offsets such as: *now-24h* or *header.xxx+1h* or even *now+1h30m-100*.`),
+            new Context('date:_command:pattern_', 'Date formatting using `java.text.SimpleDateFormat` patterns.'),
+            new Context('date-with-timezone:_command:timezone:pattern_', 'Date formatting using `java.text.SimpleDateFormat` timezones and patterns.'),
+            new Context('bean:_bean expression_ ', `Invoking a bean expression using the xref:components::bean-component.adoc[Bean] language.'),
+Specifying a method name you must use dot as separator. We also support
+the ?method=methodname syntax that is used by the xref:components::bean-component.adoc[Bean]
+component. Camel will by default lookup a bean by the given name. However if you need to refer
+to a bean class (such as calling a static method) then you can prefix with type, such as 'bean:type:fqnClassName'. `),
+            new Context('properties:key:default', 'Lookup a property with the given key. If the key does not exists or has no value, then an optional default value can be specified.'),
+            new Context('propertiesExist:key', 'Checks whether a property placeholder with the given key exists or not. The result can be negated by prefixing the key with `!`.'),
+            new Context('routeId', 'Returns the route id of the current route the Exchange is being routed.'),
+            new Context('routeGroup', 'Returns the route group of the current route the Exchange is being routed. Not all routes has a group assigned, so this may be null.'),
+            new Context('stepId', 'Returns the id of the current step the Exchange is being routed.'),
+            new Context('threadId', 'Returns the id of the current thread. Can be used for logging purpose.'),
+            new Context('threadName', 'Returns the name of the current thread. Can be used for logging purpose.'),
+            new Context('hostname', 'Returns the local hostname (may be empty if not possible to resolve).'),
+            new Context('ref:xxx ', 'To lookup a bean from the Registry with the given id.'),
+            new Context('type:name.field ', 'To refer to a type or field by its FQN name. To refer to a field you can append .FIELD_NAME. For example, you can refer to the constant field from Exchange as: `org.apache.camel.Exchange.FILE_NAME`'),
+            new Context('empty(type)', `Creates a new empty object of the type given as parameter. The type-parameter-Strings are case-insensitive. +
+'string' -> empty String
+'list'   -> empty ArrayList 
+'map'    -> empty HashMap `),
+            new Context('null', 'represents a *null*'),
+            new Context('random(value)', 'returns a random Integer between 0 (included) and _value_ (excluded)'),
+            new Context('random(min,max)', 'returns a random Integer between _min_ (included) and _max_ (excluded)'),
+            new Context('collate(group)', `The collate function iterates the message body and groups
+the data into sub lists of specified size. This can be used with the
+Splitter EIP to split a message body and group/batch
+the split sub message into a group of N sub lists. This method works
+similar to the collate method in Groovy.`),
+            new Context('skip(number)', ' The skip function iterates the message body and skips the first number of items. This can be used with the Splitter EIP to split a message body and skip the first N number of items.'),
+            new Context('join(separator,prefix,exp)', `The join function iterates the message body (by default) and joins the data into a string. The separator is by default a comma. The prefix is optional.'),
+
+The join uses the message body as source by default. It is possible to refer to another
+source (simple language) such as a header via the exp parameter. For example join('&','id=','$\{header.ids}')`),
+            new Context('messageHistory', 'The message history of the current exchange how it has been routed. This is similar to the route stack-trace message history the error handler logs in case of an unhandled exception.'),
+            new Context('messageHistory(false)', 'As messageHistory but without the exchange details (only includes the route stack-trace). This can be used if you do not want to log sensitive data from the message itself.'),
+            new Context('uuid(type)', 'Returns an UUID using the Camel `UuidGenerator`. You can choose between `default`, `classic`, `short` and `simple` as the type. If no type is given the default is used. It is also possible to use a custom `UuidGenerator` and bind the bean to the xref:manual::registry.adoc[Registry] with an id. For example `${uuid(myGenerator}` where the ID is _myGenerator_.'),
+            new Context('hash(exp,algorithm)', 'Returns a hashed value (string in hex decimal) using JDK MessageDigest. The algorithm can be SHA-256 (default) or SHA3-256.'),
+            new Context('jsonpath(exp)', 'When working with JSon data, then this allows to use the JsonPath language for example to extract data from the message body (in JSon format). This requires having camel-jsonpath JAR on the classpath.'),
+            new Context('jsonpath(input,exp)', 'When working with JSon data, then this allows to use the JsonPath language for example to extract data from the message body (in JSon format). This requires having camel-jsonpath JAR on the classpath. For _input_ you can choose `header:key`, `exchangeProperty:key` or `variable:key` to use as input for the JSon payload instead of the message body.'),
+            new Context('jq(exp)', 'When working with JSon data, then this allows to use the JQ language for example to extract data from the message body (in JSon format). This requires having camel-jq JAR on the classpath.'),
+            new Context('jq(input,exp)', 'When working with JSon data, then this allows to use the JQ language for example to extract data from the message body (in JSon format). This requires having camel-jq JAR on the classpath. For _input_ you can choose `header:key`, `exchangeProperty:key` or `variable:key` to use as input for the JSon payload instead of the message body.'),
+            new Context('xpath(exp)', 'When working with XML data, then this allows to use the XPath language for example to extract data from the message body (in XML format). This requires having camel-xpath JAR on the classpath.'),
+            new Context('xpath(input,exp)', 'When working with XML data, then this allows to use the XPath language for example to extract data from the message body (in XML format). This requires having camel-xpath JAR on the classpath. For _input_ you can choose `header:key`, `exchangeProperty:key` or `variable:key` to use as input for the JSon payload instead of the message body.'),
+            new Context('pretty(exp)', 'Converts the inlined expression to a String, and attempts to pretty print if JSon or XML, otherwise the expression is returned as the String value.'),
+        ]
+    )
+]
+
+export const ExpressionFunctions: ExpressionContext[] = [
+    new ExpressionContext('java', [
+            new Context('bodyAs(type)', 'To convert the body to the given type'),
+            new Context('headerAs(name, type)', 'To convert the header with the name to the given type.'),
+            new Context('headerAs(name, defaultValue, type)', 'To convert the header with the name to the given type. If no header exists, then use the given default value.'),
+            new Context('exchangePropertyAs(name, type)', 'To convert the exchange property with the name to the given type.'),
+            new Context('exchangePropertyAs(name, defaultValue, type)', 'To convert the exchange property with the name to the given type. If no exchange property exists, then use the given default value.'),
+            new Context('optionalBodyAs(type)', 'To convert the body to the given type, returned wrapped in java.util.Optional.'),
+            new Context('optionalHeaderAs(name, type)', 'To convert the header with the name to the given type, returned wrapped in java.util.Optional.'),
+            new Context('optionalExchangePropertyAs(name, type)', 'To convert the exchange property with the name to the given type, returned wrapped in java.util.Optional.')
+        ]
+    ),
+    new ExpressionContext('xpath', [
+            new Context('in:body', 'Will return the message body.'),
+            new Context('in:header', 'Will return the message header.'),
+            new Context('function:properties', 'To use a Property Placeholder.'),
+            new Context('function:simple', 'To evaluate a Simple language.'),
+        ]
+    )
+]
diff --git a/karavan-space/src/designer/property/property/ComponentPropertyPlaceholderDropdown.css b/karavan-app/src/main/webui/src/expression/ExpressionModalEditor.css
similarity index 52%
copy from karavan-space/src/designer/property/property/ComponentPropertyPlaceholderDropdown.css
copy to karavan-app/src/main/webui/src/expression/ExpressionModalEditor.css
index 43991634..732d3abd 100644
--- a/karavan-space/src/designer/property/property/ComponentPropertyPlaceholderDropdown.css
+++ b/karavan-app/src/main/webui/src/expression/ExpressionModalEditor.css
@@ -14,24 +14,55 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+.expression-modal {
+    height: 80%;
+}
+
+.container {
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    gap: 16px;
+    justify-content: space-between;
+    align-items: stretch;
+}
+
+.panel-top {
+    flex: 1;
+    height: 100%;
+    border: 1px solid lightgray;
+}
+
+.panel-middle {
+    /*height: 64px;*/
+}
+
+.panel-bottom {
+    flex: 1;
+    height: 100%;
+    overflow-y: auto;
+}
 
-.karavan .properties .property-placeholder-toggle {
-    padding-left: 6px;
-    padding-right: 6px;
+.context {
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+    gap: 64px;
 }
 
-.karavan .properties .property-placeholder-toggle .pf-v5-c-button__icon.pf-m-start {
-    margin-inline-end: 0;
+.context-column {
+    flex: 1;
 }
 
-.karavan .properties .property-placeholder-toggle .pf-v5-c-menu-toggle__controls {
-    display: none;
+.context-column-right {
+    margin-left: 12px;
 }
 
-.pf-v5-c-popover .property-placeholder-toggle-form {
-    width: 300px;
+.context-column .pf-v5-c-clipboard-copy.pf-m-inline {
+    display: flex;
+    width: fit-content;
 }
 
-.pf-v5-c-popover .property-placeholder-toggle-form .pf-v5-c-form__group {
-    grid-template-columns: 1fr 2fr;
+.context-column .pf-v5-c-clipboard-copy__text{
+    white-space: nowrap;
 }
\ No newline at end of file
diff --git a/karavan-designer/src/designer/property/property/ModalEditor.tsx b/karavan-app/src/main/webui/src/expression/ExpressionModalEditor.tsx
similarity index 56%
copy from karavan-designer/src/designer/property/property/ModalEditor.tsx
copy to karavan-app/src/main/webui/src/expression/ExpressionModalEditor.tsx
index d3df2a27..3a96ce7a 100644
--- a/karavan-designer/src/designer/property/property/ModalEditor.tsx
+++ b/karavan-app/src/main/webui/src/expression/ExpressionModalEditor.tsx
@@ -16,13 +16,12 @@
  */
 import React, {useEffect, useState} from 'react';
 import {
-    Button,
-    Modal,
-    ModalVariant, Title, TitleSizes
+    Button, Modal, Title, TitleSizes
 } from '@patternfly/react-core';
-import '../../karavan.css';
-import "@patternfly/patternfly/patternfly.css";
 import Editor from "@monaco-editor/react";
+import {ExpressionBottomPanel} from "./ExpressionBottomPanel";
+import './ExpressionModalEditor.css'
+import {Context, ExpressionFunctions, ExpressionVariables} from "./ExpressionContextModel";
 
 interface Props {
     name: string,
@@ -35,11 +34,12 @@ interface Props {
     showEditor: boolean
 }
 
-export function ModalEditor(props: Props) {
+export function ExpressionModalEditor(props: Props) {
 
     const [customCode, setCustomCode] = useState<string | undefined>();
 
     useEffect(() => {
+        console.log(title, dslLanguage)
         setCustomCode(props.customCode)
     },[]);
 
@@ -52,10 +52,16 @@ export function ModalEditor(props: Props) {
     }
 
     const {dark, dslLanguage, title, showEditor} = props;
+    const language = dslLanguage?.[0];
+    const showVars = ExpressionVariables.findIndex(e => e.name === language) > - 1;
+    const showFuncs = ExpressionFunctions.findIndex(e => e.name === language) > - 1;
+    const show = showVars || showFuncs;
+
     return (
         <Modal
-            aria-label={"expression"}
-            variant={ModalVariant.large}
+            aria-label="Expression"
+            className='expression-modal'
+            width={"80%"}
             header={<React.Fragment>
                 <Title id="modal-custom-header-label" headingLevel="h1" size={TitleSizes['2xl']}>
                     {title}
@@ -71,17 +77,31 @@ export function ModalEditor(props: Props) {
                         onClick={e => close()}>Close</Button>
             ]}
             onEscapePress={e => close()}>
-            <Editor
-                height="400px"
-                width="100%"
-                defaultLanguage={'java'}
-                language={'java'}
-                theme={dark ? 'vs-dark' : 'light'}
-                options={{lineNumbers: "off", folding: false, lineNumbersMinChars: 10, showUnused: false, fontSize: 12, minimap: {enabled: false}}}
-                value={customCode?.toString()}
-                className={'code-editor'}
-                onChange={(value,_) => setCustomCode(value)}
-            />
+            <div className='container'>
+                <div className='panel-top'>
+                    <Editor
+                        height="50%"
+                        width="100%"
+                        defaultLanguage={'java'}
+                        language={'java'}
+                        theme={dark ? 'vs-dark' : 'light'}
+                        options={{
+                            lineNumbers: "off",
+                            folding: false,
+                            lineNumbersMinChars: 10,
+                            showUnused: false,
+                            fontSize: 12,
+                            minimap: {enabled: false}
+                        }}
+                        value={customCode?.toString()}
+                        className={'code-editor'}
+                        onChange={(value, _) => setCustomCode(value)}
+                    />
+                </div>
+                {show && <div className='panel-bottom'>
+                    {dslLanguage && <ExpressionBottomPanel dslLanguage={dslLanguage}/>}
+                </div>}
+            </div>
         </Modal>
     )
 }
diff --git a/karavan-designer/public/example/demo.camel.yaml b/karavan-designer/public/example/demo.camel.yaml
index 747447bc..b751e86b 100644
--- a/karavan-designer/public/example/demo.camel.yaml
+++ b/karavan-designer/public/example/demo.camel.yaml
@@ -23,11 +23,9 @@
             id: setVariable-439c
             name: alc1
             expression:
-              jq:
-                id: jq-c893
+              java:
+                id: java-6ac5
                 expression: .alcohol | rtrimstr("%")
-                source: beer1
-                resultType: float
         - setVariable:
             id: setVariable-14bc
             name: alc2
@@ -60,4 +58,4 @@
                     message: >-
                       Beer battle: ${jq(variable:beer1,.name)}
                       (${variable.alc1}%) is weaker than
-                      ${jq(variable:beer2,.name)} (${variable.alc2}%)
\ No newline at end of file
+                      ${jq(variable:beer2,.name)} (${variable.alc2}%)
diff --git a/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx b/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx
index e7460847..52488a89 100644
--- a/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx
+++ b/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx
@@ -53,7 +53,7 @@ import {useDesignerStore, useIntegrationStore} from "../../DesignerStore";
 import {shallow} from "zustand/shallow";
 import {KubernetesIcon} from "../../icons/ComponentIcons";
 import EditorIcon from "@patternfly/react-icons/dist/js/icons/code-icon";
-import {ModalEditor} from "./ModalEditor";
+import {ExpressionModalEditor} from "../../../expression/ExpressionModalEditor";
 import {PropertyPlaceholderDropdown} from "./PropertyPlaceholderDropdown";
 
 const prefix = "parameters";
@@ -280,14 +280,14 @@ export function ComponentPropertyField(props: Props) {
                 </Tooltip>
             </InputGroupItem>
             {showEditor && <InputGroupItem>
-                <ModalEditor name={property.name}
-                             customCode={value}
-                             showEditor={showEditor}
-                             dark={dark}
-                             dslLanguage={undefined}
-                             title={property.displayName}
-                             onClose={() => setShowEditor(false)}
-                             onSave={(fieldId, value1) => {
+                <ExpressionModalEditor name={property.name}
+                                       customCode={value}
+                                       showEditor={showEditor}
+                                       dark={dark}
+                                       dslLanguage={undefined}
+                                       title={property.displayName}
+                                       onClose={() => setShowEditor(false)}
+                                       onSave={(fieldId, value1) => {
                                  setTextValue(value1);
                                  parametersChanged(property.name, value1, property.kind === 'path')
                                  setShowEditor(false);
diff --git a/karavan-designer/src/designer/property/property/DslPropertyField.tsx b/karavan-designer/src/designer/property/property/DslPropertyField.tsx
index cd137961..86240ed7 100644
--- a/karavan-designer/src/designer/property/property/DslPropertyField.tsx
+++ b/karavan-designer/src/designer/property/property/DslPropertyField.tsx
@@ -62,7 +62,7 @@ import {ComponentProperty} from "karavan-core/lib/model/ComponentModels";
 import {InfrastructureSelector} from "./InfrastructureSelector";
 import {InfrastructureAPI} from "../../utils/InfrastructureAPI";
 import EditorIcon from "@patternfly/react-icons/dist/js/icons/code-icon";
-import {ModalEditor} from "./ModalEditor";
+import {ExpressionModalEditor} from "../../../expression/ExpressionModalEditor";
 import DockerIcon from "@patternfly/react-icons/dist/js/icons/docker-icon";
 import {useDesignerStore, useIntegrationStore} from "../../DesignerStore";
 import {shallow} from "zustand/shallow";
@@ -394,14 +394,14 @@ export function DslPropertyField(props: Props) {
                 </Tooltip>
             </InputGroupItem>}
             {showEditor && <InputGroupItem>
-                <ModalEditor name={property.name}
-                             customCode={value}
-                             showEditor={showEditor}
-                             dark={dark}
-                             dslLanguage={undefined}
-                             title={property.displayName}
-                             onClose={() => setShowEditor(false)}
-                             onSave={(fieldId, value1) => {
+                <ExpressionModalEditor name={property.name}
+                                       customCode={value}
+                                       showEditor={showEditor}
+                                       dark={dark}
+                                       dslLanguage={undefined}
+                                       title={property.displayName}
+                                       onClose={() => setShowEditor(false)}
+                                       onSave={(fieldId, value1) => {
                                  propertyChanged(property.name, value1)
                                  setTextValue(value1);
                                  setShowEditor(false);
@@ -448,14 +448,14 @@ export function DslPropertyField(props: Props) {
                 </Tooltip>
             </InputGroupItem>
             {showEditor && <InputGroupItem>
-                <ModalEditor name={property.name}
-                             customCode={customCode}
-                             showEditor={showEditor}
-                             dark={dark}
-                             dslLanguage={dslLanguage}
-                             title="Java Class"
-                             onClose={() => setShowEditor(false)}
-                             onSave={(fieldId, value1) => {
+                <ExpressionModalEditor name={property.name}
+                                       customCode={customCode}
+                                       showEditor={showEditor}
+                                       dark={dark}
+                                       dslLanguage={dslLanguage}
+                                       title="Java Class"
+                                       onClose={() => setShowEditor(false)}
+                                       onSave={(fieldId, value1) => {
                                  propertyChanged(fieldId, value);
                                  InfrastructureAPI.onSaveCustomCode?.(value, value1);
                                  setShowEditor(false)
@@ -491,14 +491,14 @@ export function DslPropertyField(props: Props) {
                     </Tooltip>
                 </InputGroupItem>
                 {showEditor && <InputGroupItem>
-                    <ModalEditor name={property.name}
-                                 customCode={value}
-                                 showEditor={showEditor}
-                                 dark={dark}
-                                 dslLanguage={dslLanguage}
-                                 title={`Expression (${dslLanguage?.[0]})`}
-                                 onClose={() => setShowEditor(false)}
-                                 onSave={(fieldId, value1) => {
+                    <ExpressionModalEditor name={property.name}
+                                           customCode={value}
+                                           showEditor={showEditor}
+                                           dark={dark}
+                                           dslLanguage={dslLanguage}
+                                           title={`Expression (${dslLanguage?.[0]})`}
+                                           onClose={() => setShowEditor(false)}
+                                           onSave={(fieldId, value1) => {
                                      propertyChanged(fieldId, value1);
                                      setTextValue(value1);
                                      setShowEditor(false);
diff --git a/karavan-designer/src/expression/ExpressionBottomPanel.tsx b/karavan-designer/src/expression/ExpressionBottomPanel.tsx
new file mode 100644
index 00000000..4aef03a4
--- /dev/null
+++ b/karavan-designer/src/expression/ExpressionBottomPanel.tsx
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React from 'react';
+import {ClipboardCopy, Text, TextContent} from '@patternfly/react-core';
+import './ExpressionModalEditor.css'
+import {Table, Tbody, Td, Tr} from "@patternfly/react-table";
+import {Context, ExpressionFunctions, ExpressionVariables} from "./ExpressionContextModel";
+
+interface Props {
+    dslLanguage?: [string, string, string],
+}
+
+export function ExpressionBottomPanel(props: Props) {
+
+    const {dslLanguage} = props;
+    const language = dslLanguage?.[0];
+    const vars: Context[] = ExpressionVariables.filter(e => e.name === language)?.[0]?.information || [];
+    const funcs: Context[] = ExpressionFunctions.filter(e => e.name === language)?.at(0)?.information || []
+    const showVars = vars.length > 0;
+    const showFuncs = funcs.length > 0;
+
+    function getRows(data: Context[]) {
+        return (
+            data?.map((context, index, array) =>
+                <Tr key={index} style={{padding: '0'}}>
+                    <Td style={{padding: '0px 0px 6px 0px'}} modifier='fitContent'>
+                        <ClipboardCopy key={index} hoverTip="Copy" clickTip="Copied"
+                                       variant="inline-compact">
+                            {context.key}
+                        </ClipboardCopy>
+                    </Td>
+                    <Td style={{padding: '0px 0px 0px 16px'}}>
+                        {context.value}
+                    </Td>
+                </Tr>
+            )
+        )
+    }
+
+    function getRowHeader(data: string) {
+        return (
+            <Tr key='vars' style={{padding: '0'}}>
+                <Td style={{padding: '16px 6px 6px 0px'}}>
+                    <TextContent>
+                        <Text component='h3'>{data}</Text>
+                    </TextContent>
+                </Td>
+            </Tr>
+        )
+    }
+
+    return (
+        <div className='context'>
+            <div className='context-column'>
+                <Table variant='compact' borders={false}>
+                    <Tbody>
+                        {showVars && getRowHeader('Variables')}
+                        {showVars && getRows(vars)}
+                        {showFuncs && getRowHeader('Functions')}
+                        {showFuncs && getRows(funcs)}
+                    </Tbody>
+                </Table>
+            </div>
+        </div>
+    )
+}
diff --git a/karavan-designer/src/expression/ExpressionContextModel.tsx b/karavan-designer/src/expression/ExpressionContextModel.tsx
new file mode 100644
index 00000000..3f0a3411
--- /dev/null
+++ b/karavan-designer/src/expression/ExpressionContextModel.tsx
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export class ExpressionContext {
+    name: string = '';
+    information: Context[] = [];
+
+    constructor(name: string, information: Context[]) {
+        this.name = name;
+        this.information = information;
+    }
+}
+
+export class Context {
+    key: string = '';
+    value: string = '';
+
+    constructor(key: string, value: string) {
+        this.key = key;
+        this.value = value;
+    }
+}
+
+export const ExpressionVariables: ExpressionContext[] = [
+    new ExpressionContext('groovy', [
+            new Context('exchange', 'The Exchange itself.'),
+            new Context('exchangeProperties', 'The Exchange properties.'),
+            new Context('variables', 'The variables'),
+            new Context('headers', 'The headers of the In message.'),
+            new Context('camelContext', 'The Camel Context.'),
+            new Context('request', 'The In message.'),
+            new Context('body', 'The message body'),
+            new Context('response', 'The Out message (only for InOut message exchange pattern).')
+        ]
+    ),
+    new ExpressionContext('java', [
+            new Context('exchange', 'The Exchange itself.'),
+            new Context('message', 'The Camel message.'),
+            new Context('context', 'The Camel Context.'),
+            new Context('body', 'The message body')
+        ]
+    ),
+    new ExpressionContext('javascript', [
+            new Context('this', 'the Exchange is the root object.'),
+            new Context('context', 'The Camel Context.'),
+            new Context('exchange', 'The Exchange itself.'),
+            new Context('exchangeId', 'The ExchangeID.'),
+            new Context('message', 'The Camel message.'),
+            new Context('body', 'The message body'),
+            new Context('headers', 'The message headers'),
+            new Context('properties', 'The message properties')
+        ]
+    ),
+    new ExpressionContext('jq', [
+            new Context('header', 'Allow accessing the Message header ex. header(\\"MyHeader\\")'),
+            new Context('property', 'Allow accessing the Message property ex. property(\\"MyProperty\\")'),
+            new Context('constant', 'Allow accessing constant value as-is '),
+
+        ]
+    ),
+    new ExpressionContext('simple', [
+            new Context('camelId', 'the CamelContext name'),
+            new Context('camelContext.*OGNL*', 'the CamelContext invoked using a Camel OGNL expression.'),
+            new Context('exchange', 'the Exchange'),
+            new Context('exchange.*OGNL*', 'the Exchange invoked using a Camel OGNL expression.'),
+            new Context('exchangeId', 'the exchange id'),
+            new Context('id', 'the message id'),
+            new Context('messageTimestamp', 'the message timestamp (millis since epoc) that this message originates from.'),
+            new Context('body ', 'the body'),
+            new Context('body.*OGNL*', 'the body invoked using a Camel OGNL expression.'),
+            new Context('bodyAs(_type_)', 'Converts the body to the given type determined by its classname. The converted body can be null.'),
+            new Context('bodyAs(_type_).*OGNL* ', 'Converts the body to the given type determined by its classname and then invoke methods using a Camel OGNL expression. The converted body can be null.'),
+            new Context('bodyOneLine', 'Converts the body to a String and removes all line-breaks so the string is in one line.'),
+            new Context('prettyBody', 'Converts the body to a String, and attempts to pretty print if JSon or XML, otherwise the body is returned as the String value.'),
+            new Context('originalBody', 'The original incoming body (only available if allowUseOriginalMessage=true).'),
+            new Context('mandatoryBodyAs(_type_)', 'Converts the body to the given type determined by its classname, and expects the body to be not null.'),
+            new Context('mandatoryBodyAs(_type_).*OGNL* ', 'Converts the body to the given type determined by its classname and then invoke methods using a Camel OGNL expression.'),
+            new Context('header.foo ', 'refer to the foo header'),
+            new Context('header[foo] ', 'refer to the foo header'),
+            new Context('headers.foo ', 'refer to the foo header'),
+            new Context('headers:foo ', 'refer to the foo header'),
+            new Context('headers[foo] ', 'refer to the foo header'),
+            new Context('header.foo[bar] ', 'regard foo header as a map and perform lookup on the map with bar as key'),
+            new Context('header.foo.*OGNL*', 'refer to the foo header and invoke its value using a Camel OGNL expression.'),
+            new Context('headerAs(_key_,_type_)', 'converts the header to the given type determined by its classname'),
+            new Context('headers', 'refer to the headers'),
+            new Context('variable.foo ', 'refer to the foo variable'),
+            new Context('variable[foo] ', 'refer to the foo variable'),
+            new Context('variable.foo.*OGNL* ', 'refer to the foo variable and invoke its value using a Camel OGNL expression.'),
+            new Context('variableAs(_key_,_type_)', 'converts the variable to the given type determined by its classname'),
+            new Context('variables', 'refer to the variables'),
+            new Context('exchangeProperty.foo ', 'refer to the foo property on the exchange'),
+            new Context('exchangeProperty[foo] ', 'refer to the foo property on the exchange'),
+            new Context('exchangeProperty.foo.*OGNL* ', 'refer to the foo property on the exchange and invoke its value using a Camel OGNL expression.'),
+            new Context('messageAs(_type_)', 'Converts the message to the given type determined by its classname. The converted message can be null. '),
+            new Context('messageAs(_type_).*OGNL* ', 'Converts the message to the given type determined by its classname and then invoke methods using a Camel OGNL expression. The converted message can be null. '),
+            new Context('sys.foo', 'refer to the JVM system property'),
+            new Context('sysenv.foo', 'refer to the system environment variable'),
+            new Context('env.foo', 'refer to the system environment variable'),
+            new Context('exception ', 'refer to the exception object on the exchange, is *null* if no exception set on exchange. Will fallback and grab caught exceptions (`Exchange.EXCEPTION_CAUGHT`) if the Exchange has any.'),
+            new Context('exception.*OGNL* ', 'refer to the exchange exception invoked using a Camel OGNL expression object'),
+            new Context('exception.message', 'refer to the exception.message on the exchange, is *null* if no exception set on exchange. Will fallback and grab caught exceptions (`Exchange.EXCEPTION_CAUGHT`) if the Exchange has any.'),
+            new Context('exception.stacktrace', 'refer to the exception.stracktrace on the exchange, is  *null* if no exception set on exchange. Will fallback and grab caught exceptions (`Exchange.EXCEPTION_CAUGHT`) if the Exchange has any.'),
+            new Context('date:_command_', `evaluates to a Date object. Supported commands are: *now* for current timestamp,
+*exchangeCreated* for the timestamp when the current exchange was created,
+*header.xxx* to use the Long/Date object in the header with the key xxx.
+*variable.xxx* to use the Long/Date in the variable with the key xxx.
+*exchangeProperty.xxx* to use the Long/Date object in the exchange property with the key xxx.
+*file* for the last modified timestamp of the file (available with a File consumer).
+Command accepts offsets such as: *now-24h* or *header.xxx+1h* or even *now+1h30m-100*.`),
+            new Context('date:_command:pattern_', 'Date formatting using `java.text.SimpleDateFormat` patterns.'),
+            new Context('date-with-timezone:_command:timezone:pattern_', 'Date formatting using `java.text.SimpleDateFormat` timezones and patterns.'),
+            new Context('bean:_bean expression_ ', `Invoking a bean expression using the xref:components::bean-component.adoc[Bean] language.'),
+Specifying a method name you must use dot as separator. We also support
+the ?method=methodname syntax that is used by the xref:components::bean-component.adoc[Bean]
+component. Camel will by default lookup a bean by the given name. However if you need to refer
+to a bean class (such as calling a static method) then you can prefix with type, such as 'bean:type:fqnClassName'. `),
+            new Context('properties:key:default', 'Lookup a property with the given key. If the key does not exists or has no value, then an optional default value can be specified.'),
+            new Context('propertiesExist:key', 'Checks whether a property placeholder with the given key exists or not. The result can be negated by prefixing the key with `!`.'),
+            new Context('routeId', 'Returns the route id of the current route the Exchange is being routed.'),
+            new Context('routeGroup', 'Returns the route group of the current route the Exchange is being routed. Not all routes has a group assigned, so this may be null.'),
+            new Context('stepId', 'Returns the id of the current step the Exchange is being routed.'),
+            new Context('threadId', 'Returns the id of the current thread. Can be used for logging purpose.'),
+            new Context('threadName', 'Returns the name of the current thread. Can be used for logging purpose.'),
+            new Context('hostname', 'Returns the local hostname (may be empty if not possible to resolve).'),
+            new Context('ref:xxx ', 'To lookup a bean from the Registry with the given id.'),
+            new Context('type:name.field ', 'To refer to a type or field by its FQN name. To refer to a field you can append .FIELD_NAME. For example, you can refer to the constant field from Exchange as: `org.apache.camel.Exchange.FILE_NAME`'),
+            new Context('empty(type)', `Creates a new empty object of the type given as parameter. The type-parameter-Strings are case-insensitive. +
+'string' -> empty String
+'list'   -> empty ArrayList 
+'map'    -> empty HashMap `),
+            new Context('null', 'represents a *null*'),
+            new Context('random(value)', 'returns a random Integer between 0 (included) and _value_ (excluded)'),
+            new Context('random(min,max)', 'returns a random Integer between _min_ (included) and _max_ (excluded)'),
+            new Context('collate(group)', `The collate function iterates the message body and groups
+the data into sub lists of specified size. This can be used with the
+Splitter EIP to split a message body and group/batch
+the split sub message into a group of N sub lists. This method works
+similar to the collate method in Groovy.`),
+            new Context('skip(number)', ' The skip function iterates the message body and skips the first number of items. This can be used with the Splitter EIP to split a message body and skip the first N number of items.'),
+            new Context('join(separator,prefix,exp)', `The join function iterates the message body (by default) and joins the data into a string. The separator is by default a comma. The prefix is optional.'),
+
+The join uses the message body as source by default. It is possible to refer to another
+source (simple language) such as a header via the exp parameter. For example join('&','id=','$\{header.ids}')`),
+            new Context('messageHistory', 'The message history of the current exchange how it has been routed. This is similar to the route stack-trace message history the error handler logs in case of an unhandled exception.'),
+            new Context('messageHistory(false)', 'As messageHistory but without the exchange details (only includes the route stack-trace). This can be used if you do not want to log sensitive data from the message itself.'),
+            new Context('uuid(type)', 'Returns an UUID using the Camel `UuidGenerator`. You can choose between `default`, `classic`, `short` and `simple` as the type. If no type is given the default is used. It is also possible to use a custom `UuidGenerator` and bind the bean to the xref:manual::registry.adoc[Registry] with an id. For example `${uuid(myGenerator}` where the ID is _myGenerator_.'),
+            new Context('hash(exp,algorithm)', 'Returns a hashed value (string in hex decimal) using JDK MessageDigest. The algorithm can be SHA-256 (default) or SHA3-256.'),
+            new Context('jsonpath(exp)', 'When working with JSon data, then this allows to use the JsonPath language for example to extract data from the message body (in JSon format). This requires having camel-jsonpath JAR on the classpath.'),
+            new Context('jsonpath(input,exp)', 'When working with JSon data, then this allows to use the JsonPath language for example to extract data from the message body (in JSon format). This requires having camel-jsonpath JAR on the classpath. For _input_ you can choose `header:key`, `exchangeProperty:key` or `variable:key` to use as input for the JSon payload instead of the message body.'),
+            new Context('jq(exp)', 'When working with JSon data, then this allows to use the JQ language for example to extract data from the message body (in JSon format). This requires having camel-jq JAR on the classpath.'),
+            new Context('jq(input,exp)', 'When working with JSon data, then this allows to use the JQ language for example to extract data from the message body (in JSon format). This requires having camel-jq JAR on the classpath. For _input_ you can choose `header:key`, `exchangeProperty:key` or `variable:key` to use as input for the JSon payload instead of the message body.'),
+            new Context('xpath(exp)', 'When working with XML data, then this allows to use the XPath language for example to extract data from the message body (in XML format). This requires having camel-xpath JAR on the classpath.'),
+            new Context('xpath(input,exp)', 'When working with XML data, then this allows to use the XPath language for example to extract data from the message body (in XML format). This requires having camel-xpath JAR on the classpath. For _input_ you can choose `header:key`, `exchangeProperty:key` or `variable:key` to use as input for the JSon payload instead of the message body.'),
+            new Context('pretty(exp)', 'Converts the inlined expression to a String, and attempts to pretty print if JSon or XML, otherwise the expression is returned as the String value.'),
+        ]
+    )
+]
+
+export const ExpressionFunctions: ExpressionContext[] = [
+    new ExpressionContext('java', [
+            new Context('bodyAs(type)', 'To convert the body to the given type'),
+            new Context('headerAs(name, type)', 'To convert the header with the name to the given type.'),
+            new Context('headerAs(name, defaultValue, type)', 'To convert the header with the name to the given type. If no header exists, then use the given default value.'),
+            new Context('exchangePropertyAs(name, type)', 'To convert the exchange property with the name to the given type.'),
+            new Context('exchangePropertyAs(name, defaultValue, type)', 'To convert the exchange property with the name to the given type. If no exchange property exists, then use the given default value.'),
+            new Context('optionalBodyAs(type)', 'To convert the body to the given type, returned wrapped in java.util.Optional.'),
+            new Context('optionalHeaderAs(name, type)', 'To convert the header with the name to the given type, returned wrapped in java.util.Optional.'),
+            new Context('optionalExchangePropertyAs(name, type)', 'To convert the exchange property with the name to the given type, returned wrapped in java.util.Optional.')
+        ]
+    ),
+    new ExpressionContext('xpath', [
+            new Context('in:body', 'Will return the message body.'),
+            new Context('in:header', 'Will return the message header.'),
+            new Context('function:properties', 'To use a Property Placeholder.'),
+            new Context('function:simple', 'To evaluate a Simple language.'),
+        ]
+    )
+]
diff --git a/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyPlaceholderDropdown.css b/karavan-designer/src/expression/ExpressionModalEditor.css
similarity index 52%
rename from karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyPlaceholderDropdown.css
rename to karavan-designer/src/expression/ExpressionModalEditor.css
index 43991634..732d3abd 100644
--- a/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyPlaceholderDropdown.css
+++ b/karavan-designer/src/expression/ExpressionModalEditor.css
@@ -14,24 +14,55 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+.expression-modal {
+    height: 80%;
+}
+
+.container {
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    gap: 16px;
+    justify-content: space-between;
+    align-items: stretch;
+}
+
+.panel-top {
+    flex: 1;
+    height: 100%;
+    border: 1px solid lightgray;
+}
+
+.panel-middle {
+    /*height: 64px;*/
+}
+
+.panel-bottom {
+    flex: 1;
+    height: 100%;
+    overflow-y: auto;
+}
 
-.karavan .properties .property-placeholder-toggle {
-    padding-left: 6px;
-    padding-right: 6px;
+.context {
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+    gap: 64px;
 }
 
-.karavan .properties .property-placeholder-toggle .pf-v5-c-button__icon.pf-m-start {
-    margin-inline-end: 0;
+.context-column {
+    flex: 1;
 }
 
-.karavan .properties .property-placeholder-toggle .pf-v5-c-menu-toggle__controls {
-    display: none;
+.context-column-right {
+    margin-left: 12px;
 }
 
-.pf-v5-c-popover .property-placeholder-toggle-form {
-    width: 300px;
+.context-column .pf-v5-c-clipboard-copy.pf-m-inline {
+    display: flex;
+    width: fit-content;
 }
 
-.pf-v5-c-popover .property-placeholder-toggle-form .pf-v5-c-form__group {
-    grid-template-columns: 1fr 2fr;
+.context-column .pf-v5-c-clipboard-copy__text{
+    white-space: nowrap;
 }
\ No newline at end of file
diff --git a/karavan-space/src/designer/property/property/ModalEditor.tsx b/karavan-designer/src/expression/ExpressionModalEditor.tsx
similarity index 56%
rename from karavan-space/src/designer/property/property/ModalEditor.tsx
rename to karavan-designer/src/expression/ExpressionModalEditor.tsx
index d3df2a27..3a96ce7a 100644
--- a/karavan-space/src/designer/property/property/ModalEditor.tsx
+++ b/karavan-designer/src/expression/ExpressionModalEditor.tsx
@@ -16,13 +16,12 @@
  */
 import React, {useEffect, useState} from 'react';
 import {
-    Button,
-    Modal,
-    ModalVariant, Title, TitleSizes
+    Button, Modal, Title, TitleSizes
 } from '@patternfly/react-core';
-import '../../karavan.css';
-import "@patternfly/patternfly/patternfly.css";
 import Editor from "@monaco-editor/react";
+import {ExpressionBottomPanel} from "./ExpressionBottomPanel";
+import './ExpressionModalEditor.css'
+import {Context, ExpressionFunctions, ExpressionVariables} from "./ExpressionContextModel";
 
 interface Props {
     name: string,
@@ -35,11 +34,12 @@ interface Props {
     showEditor: boolean
 }
 
-export function ModalEditor(props: Props) {
+export function ExpressionModalEditor(props: Props) {
 
     const [customCode, setCustomCode] = useState<string | undefined>();
 
     useEffect(() => {
+        console.log(title, dslLanguage)
         setCustomCode(props.customCode)
     },[]);
 
@@ -52,10 +52,16 @@ export function ModalEditor(props: Props) {
     }
 
     const {dark, dslLanguage, title, showEditor} = props;
+    const language = dslLanguage?.[0];
+    const showVars = ExpressionVariables.findIndex(e => e.name === language) > - 1;
+    const showFuncs = ExpressionFunctions.findIndex(e => e.name === language) > - 1;
+    const show = showVars || showFuncs;
+
     return (
         <Modal
-            aria-label={"expression"}
-            variant={ModalVariant.large}
+            aria-label="Expression"
+            className='expression-modal'
+            width={"80%"}
             header={<React.Fragment>
                 <Title id="modal-custom-header-label" headingLevel="h1" size={TitleSizes['2xl']}>
                     {title}
@@ -71,17 +77,31 @@ export function ModalEditor(props: Props) {
                         onClick={e => close()}>Close</Button>
             ]}
             onEscapePress={e => close()}>
-            <Editor
-                height="400px"
-                width="100%"
-                defaultLanguage={'java'}
-                language={'java'}
-                theme={dark ? 'vs-dark' : 'light'}
-                options={{lineNumbers: "off", folding: false, lineNumbersMinChars: 10, showUnused: false, fontSize: 12, minimap: {enabled: false}}}
-                value={customCode?.toString()}
-                className={'code-editor'}
-                onChange={(value,_) => setCustomCode(value)}
-            />
+            <div className='container'>
+                <div className='panel-top'>
+                    <Editor
+                        height="50%"
+                        width="100%"
+                        defaultLanguage={'java'}
+                        language={'java'}
+                        theme={dark ? 'vs-dark' : 'light'}
+                        options={{
+                            lineNumbers: "off",
+                            folding: false,
+                            lineNumbersMinChars: 10,
+                            showUnused: false,
+                            fontSize: 12,
+                            minimap: {enabled: false}
+                        }}
+                        value={customCode?.toString()}
+                        className={'code-editor'}
+                        onChange={(value, _) => setCustomCode(value)}
+                    />
+                </div>
+                {show && <div className='panel-bottom'>
+                    {dslLanguage && <ExpressionBottomPanel dslLanguage={dslLanguage}/>}
+                </div>}
+            </div>
         </Modal>
     )
 }
diff --git a/karavan-space/package.json b/karavan-space/package.json
index 1d424054..dc8f2794 100644
--- a/karavan-space/package.json
+++ b/karavan-space/package.json
@@ -4,11 +4,12 @@
   "license": "Apache-2.0",
   "scripts": {
     "cp-designer": "cp -r ../karavan-designer/src/designer src",
+    "cp-expression": "cp -r ../karavan-designer/src/expression src",
     "cp-knowledgebase": "cp -r ../karavan-designer/src/knowledgebase src",
     "cp-topology": "cp -r ../karavan-designer/src/topology src",
     "cp-public-kamelets": "cp -r ../karavan-designer/public/kamelets public",
     "cp-public-components": "cp -r ../karavan-designer/public/components public",
-    "copy": "npm run cp-designer && npm run cp-knowledgebase && npm run cp-topology && npm run cp-public-components && npm run cp-public-kamelets",
+    "copy": "npm run cp-designer && npm run cp-expression && npm run cp-knowledgebase && npm run cp-topology && npm run cp-public-components && npm run cp-public-kamelets",
     "start": "npm run copy && react-scripts start",
     "build": "npm run copy && react-scripts build",
     "prod": "npm run copy && react-scripts build --dest && rsync -a build/* ../resources/META-INF/resources"
diff --git a/karavan-space/src/App.tsx b/karavan-space/src/App.tsx
index 5bddc2a6..c4d15e14 100644
--- a/karavan-space/src/App.tsx
+++ b/karavan-space/src/App.tsx
@@ -24,7 +24,6 @@ import {ComponentApi} from "karavan-core/lib/api/ComponentApi";
 import {BlueprintIcon} from "@patternfly/react-icons";
 import KnowledgebaseIcon from "@patternfly/react-icons/dist/js/icons/book-open-icon";
 import TopologyIcon from "@patternfly/react-icons/dist/js/icons/topology-icon";
-import {KaravanIcon} from "./designer/utils/KaravanIcons";
 import './designer/karavan.css';
 import {SpacePage} from "./space/SpacePage";
 import {GithubModal} from "./space/GithubModal";
@@ -34,6 +33,7 @@ import {EventBus} from "./designer/utils/EventBus";
 import {Notification} from "./designer/utils/Notification";
 import {TopologyTab} from "./topology/TopologyTab";
 import {IntegrationFile} from "karavan-core/lib/model/IntegrationDefinition";
+import {KaravanIcon} from "./designer/icons/KaravanIcons";
 
 class MenuItem {
     pageId: string = '';
@@ -137,7 +137,7 @@ class App extends React.Component<Props, State> {
         return (<Flex className="nav-buttons" direction={{default: "column"}} style={{height: "100%"}}
                       spaceItems={{default: "spaceItemsNone"}}>
             <FlexItem alignSelf={{default: "alignSelfCenter"}}>
-                <Tooltip className="logo-tooltip" content={"Apache Camel Karavan"}
+                <Tooltip className="logo-tooltip" content={"Apache Camel Karavan 4.4.1"}
                          position={"right"}>
                     {KaravanIcon()}
                 </Tooltip>
diff --git a/karavan-space/src/designer/KaravanStore.ts b/karavan-space/src/designer/KaravanStore.ts
deleted file mode 100644
index 15a9b7be..00000000
--- a/karavan-space/src/designer/KaravanStore.ts
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import {CamelElement, Integration} from "karavan-core/lib/model/IntegrationDefinition";
-import {DslPosition, EventBus} from "./utils/EventBus";
-import {createWithEqualityFn} from "zustand/traditional";
-import {shallow} from "zustand/shallow";
-
-interface IntegrationState {
-    integration: Integration;
-    json: string;
-    setIntegration: (integration: Integration, propertyOnly: boolean) => void;
-    propertyOnly: boolean;
-    reset: () => void;
-}
-
-export const useIntegrationStore = createWithEqualityFn<IntegrationState>((set) => ({
-    integration: Integration.createNew("demo", "plain"),
-    propertyOnly: false,
-    json: '{}',
-    setIntegration: (integration: Integration, propertyOnly: boolean) => {
-        set((state: IntegrationState) => {
-            const json = JSON.stringify(integration);
-            if (state.json === json) {
-                return {integration: state.integration, propertyOnly: state.propertyOnly, json: state.json};
-            } else {
-                EventBus.sendIntegrationUpdate(integration, propertyOnly);
-                return {integration: integration, propertyOnly: propertyOnly, json: json};
-            }
-        })
-    },
-    reset: () => {
-        set({integration: Integration.createNew("demo", "plain"), json: '{}', propertyOnly: false});
-    }
-}), shallow)
-
-
-interface SelectorStateState {
-    showSelector: boolean;
-    setShowSelector: (showSelector: boolean) => void;
-    showSteps: boolean;
-    setShowSteps: (showSteps: boolean) => void;
-    parentDsl?: string;
-    setParentDsl: (parentDsl?: string) => void;
-    parentId: string;
-    setParentId: (parentId: string) => void;
-    selectorTabIndex?: string | number
-    setSelectorTabIndex: (selectorTabIndex?: string | number) => void;
-    selectedPosition?: number;
-    setSelectedPosition: (selectedPosition?: number) => void;
-    selectedLabels: string [];
-    addSelectedLabel: (label: string) => void;
-    deleteSelectedLabel: (label: string) => void;
-    clearSelectedLabels: () => void;
-}
-
-export const useSelectorStore = createWithEqualityFn<SelectorStateState>((set) => ({
-    showSelector: false,
-    deleteMessage: '',
-    parentId: '',
-    showSteps: true,
-    selectedLabels: [],
-    addSelectedLabel: (label: string) => {
-        set(state => ({
-            selectedLabels: [...state.selectedLabels, label]
-        }))
-    },
-    deleteSelectedLabel: (label: string) => {
-        set(state => ({
-            selectedLabels: [...state.selectedLabels.filter(x => x !== label)]
-        }))
-    },
-    clearSelectedLabels: () => {
-        set((state: SelectorStateState) => {
-            state.selectedLabels.length = 0;
-            return state;
-        })
-    },
-    setSelectedLabels: (selectedLabels: string []) => {
-        set({selectedLabels: selectedLabels})
-    },
-    setSelectorTabIndex: (selectorTabIndex?: string | number) => {
-        set({selectorTabIndex: selectorTabIndex})
-    },
-    setParentDsl: (parentDsl?: string) => {
-        set({parentDsl: parentDsl})
-    },
-    setShowSelector: (showSelector: boolean) => {
-        set({showSelector: showSelector})
-    },
-    setShowSteps: (showSteps: boolean) => {
-        set({showSteps: showSteps})
-    },
-    setParentId: (parentId: string) => {
-        set({parentId: parentId})
-    },
-    setSelectedPosition: (selectedPosition?: number) => {
-        set({selectedPosition: selectedPosition})
-    },
-}), shallow)
-
-
-interface ConnectionsState {
-    steps: Map<string, DslPosition>;
-    addStep: (uuid: string, position: DslPosition) => void;
-    deleteStep: (uuid: string) => void;
-    clearSteps: () => void;
-    setSteps: (steps: Map<string, DslPosition>) => void;
-}
-
-export const useConnectionsStore = createWithEqualityFn<ConnectionsState>((set) => ({
-    steps: new Map<string, DslPosition>(),
-    addStep: (uuid: string, position: DslPosition) => {
-        set(state => ({
-            steps: new Map(state.steps).set(uuid, position),
-        }))
-    },
-    deleteStep: (uuid: string) => {
-        set((state: ConnectionsState) => {
-            // state.steps.clear();
-            Array.from(state.steps.entries())
-                .filter(value => value[1]?.parent?.uuid !== uuid)
-                .forEach(value => state.steps.set(value[0], value[1]));
-            state.steps.delete(uuid)
-            return state;
-        })
-    },
-    clearSteps: () => {
-        set((state: ConnectionsState) => {
-            state.steps.clear();
-            return state;
-        })
-    },
-    setSteps: (steps: Map<string, DslPosition>) => {
-        set({steps: steps})
-    },
-}), shallow)
-
-type DesignerState = {
-    dark: boolean;
-    notificationBadge: boolean;
-    notificationMessage: [string, string];
-    hideLogDSL: boolean;
-    shiftKeyPressed: boolean;
-    showDeleteConfirmation: boolean;
-    showMoveConfirmation: boolean;
-    deleteMessage: string;
-    selectedStep?: CamelElement;
-    selectedUuids: string[];
-    clipboardSteps: CamelElement[];
-    width: number,
-    height: number,
-    top: number,
-    left: number,
-}
-const designerState: DesignerState = {
-    notificationBadge: false,
-    notificationMessage: ['', ''],
-    dark: false,
-    hideLogDSL: false,
-    shiftKeyPressed: false,
-    showDeleteConfirmation: false,
-    showMoveConfirmation: false,
-    deleteMessage: '',
-    selectedUuids: [],
-    clipboardSteps: [],
-    width: 0,
-    height: 0,
-    top: 0,
-    left: 0,
-};
-
-type DesignerAction = {
-    setDark: (dark: boolean) => void;
-    setHideLogDSL: (hideLogDSL: boolean) => void;
-    setShiftKeyPressed: (shiftKeyPressed: boolean) => void;
-    setShowDeleteConfirmation: (showDeleteConfirmation: boolean) => void;
-    setShowMoveConfirmation: (showMoveConfirmation: boolean) => void;
-    setDeleteMessage: (deleteMessage: string) => void;
-    setSelectedStep: (selectedStep?: CamelElement) => void;
-    setSelectedUuids: (selectedUuids: string[]) => void;
-    setClipboardSteps: (clipboardSteps: CamelElement[]) => void;
-    setPosition: (width: number, height: number, top: number, left: number) => void;
-    reset: () => void;
-    setNotification: (notificationBadge: boolean, notificationMessage: [string, string]) => void;
-}
-
-export const useDesignerStore = createWithEqualityFn<DesignerState & DesignerAction>((set) => ({
-    ...designerState,
-    setDark: (dark: boolean) => {
-        set({dark: dark})
-    },
-    setHideLogDSL: (hideLogDSL: boolean) => {
-        set({hideLogDSL: hideLogDSL})
-    },
-    setShiftKeyPressed: (shiftKeyPressed: boolean) => {
-        set({shiftKeyPressed: shiftKeyPressed})
-    },
-    setSelectedStep: (selectedStep?: CamelElement) => {
-        set({selectedStep: selectedStep})
-    },
-    setShowDeleteConfirmation: (showDeleteConfirmation: boolean) => {
-        set({showDeleteConfirmation: showDeleteConfirmation})
-    },
-    setShowMoveConfirmation: (showMoveConfirmation: boolean) => {
-        set({showMoveConfirmation: showMoveConfirmation})
-    },
-    setDeleteMessage: (deleteMessage: string) => {
-        set({deleteMessage: deleteMessage})
-    },
-    setSelectedUuids: (selectedUuids: string[]) => {
-        set((state: DesignerState) => {
-            state.selectedUuids.length = 0;
-            state.selectedUuids.push(...selectedUuids);
-            return state;
-        })
-    },
-    setClipboardSteps: (clipboardSteps: CamelElement[]) => {
-        set((state: DesignerState) => {
-            state.clipboardSteps.length = 0;
-            state.clipboardSteps.push(...clipboardSteps);
-            return state;
-        })
-    },
-    width: 100,
-    height: 100,
-    top: 0,
-    left: 0,
-    setPosition: (width: number, height: number, top: number, left: number) => {
-        set({width: width, height: height, top: top, left: left})
-    },
-    reset: () => {
-        set(designerState);
-    },
-    setNotification: (notificationBadge: boolean, notificationMessage: [string, string]) => {
-        set({notificationBadge: notificationBadge, notificationMessage: notificationMessage})
-    }
-}), shallow)
\ No newline at end of file
diff --git a/karavan-space/src/designer/beans/BeanProperties.tsx b/karavan-space/src/designer/beans/BeanProperties.tsx
deleted file mode 100644
index e31954ac..00000000
--- a/karavan-space/src/designer/beans/BeanProperties.tsx
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React, {useEffect, useState} from 'react';
-import {
-    Form,
-    FormGroup,
-    TextInput, Button, Title, Tooltip, Popover, InputGroup, InputGroupItem, capitalize,
-} from '@patternfly/react-core';
-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 {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 {shallow} from "zustand/shallow";
-import {IntegrationHeader} from "../utils/IntegrationHeader";
-import {KubernetesIcon} from "../icons/ComponentIcons";
-import {InfrastructureSelector} from "../property/property/InfrastructureSelector";
-
-
-interface Props {
-    integration: Integration
-    dark: boolean
-    onChange: (bean: RegistryBeanDefinition) => void
-    onClone: (bean: RegistryBeanDefinition) => void
-}
-
-export function BeanProperties (props: Props) {
-
-    const [selectedStep] = useDesignerStore((s) => [s.selectedStep], shallow);
-    const [infrastructureSelector, setInfrastructureSelector] = useState<boolean>(false);
-    const [infrastructureSelectorProperty, setInfrastructureSelectorProperty] = useState<string | undefined>(undefined);
-    const [infrastructureSelectorUuid, setInfrastructureSelectorUuid] = useState<string | undefined>(undefined);
-    const [properties, setProperties] = useState<Map<string, [string, string, boolean]>>(new Map<string, [string, string, boolean]>());
-    const [constructors, setConstructors] = useState<Map<string, [number, string, boolean]>>(new Map<string, [number, string, boolean]>());
-
-    useEffect(()=> {
-        setProperties(preparePropertiesMap((selectedStep as RegistryBeanDefinition)?.properties))
-        setConstructors(prepareConstructorsMap((selectedStep as RegistryBeanDefinition)?.constructors))
-    }, [selectedStep?.uuid])
-
-    function preparePropertiesMap (properties: any): Map<string, [string, string, boolean]>  {
-        const result = new Map<string, [string, string, boolean]>();
-        if (properties) {
-            Object.keys(properties).forEach((k, i, a) => result.set(uuidv4(), [k, properties[k], false]));
-        }
-        return result;
-    }
-
-    function prepareConstructorsMap (constructors: any): Map<string, [number, string, boolean]>  {
-        const result = new Map<string, [number, string, boolean]>();
-        if (constructors) {
-            Object.keys(constructors).forEach((k, i, a) => result.set(uuidv4(), [parseInt(k), constructors[k], false]));
-        }
-        return result;
-    }
-
-    function onBeanPropertyUpdate ()  {
-        if (selectedStep) {
-            const bean = CamelUtil.cloneBean(selectedStep as RegistryBeanDefinition);
-            const beanProperties: any = {};
-            properties.forEach((p: any) => beanProperties[p[0]] = p[1]);
-            bean.properties = beanProperties;
-            props.onChange(bean);
-        }
-    }
-
-    function onBeanConstructorsUpdate ()  {
-        if (selectedStep) {
-            const bean = CamelUtil.cloneBean(selectedStep as RegistryBeanDefinition);
-            const beanConstructors: any = {};
-            constructors.forEach((p: any) => beanConstructors[p[0]] = p[1]);
-            bean.constructors = beanConstructors;
-            props.onChange(bean);
-        }
-    }
-
-    function beanFieldChanged (fieldId: string, value: string) {
-        if (selectedStep) {
-            const bean = CamelUtil.cloneBean(selectedStep as RegistryBeanDefinition);
-            (bean as any)[fieldId] = value;
-            props.onChange(bean);
-        }
-    }
-
-    function propertyChanged (uuid: string, key: string, value: string, showPassword: boolean)  {
-        setProperties(prevState => {
-            prevState.set(uuid, [key, value, showPassword]);
-            return prevState;
-        });
-        onBeanPropertyUpdate();
-    }
-
-    function constructorChanged (uuid: string, key: number, value: string, showPassword: boolean)  {
-        setConstructors(prevState => {
-            prevState.set(uuid, [key, value, showPassword]);
-            return prevState;
-        });
-        onBeanConstructorsUpdate();
-    }
-
-    function propertyDeleted (uuid: string)  {
-        setProperties(prevState => {
-            prevState.delete(uuid);
-            return prevState;
-        })
-        onBeanPropertyUpdate();
-    }
-
-    function constructorDeleted (uuid: string)  {
-        setConstructors(prevState => {
-            prevState.delete(uuid);
-            return prevState;
-        })
-        onBeanConstructorsUpdate();
-    }
-
-    function selectInfrastructure (value: string)  {
-        const propertyId = infrastructureSelectorProperty;
-        const uuid = infrastructureSelectorUuid;
-        if (propertyId && uuid){
-            if (value.startsWith("config") || value.startsWith("secret")) value = "{{" + value + "}}";
-            propertyChanged(uuid, propertyId, value, false);
-            setInfrastructureSelector(false);
-            setInfrastructureSelectorProperty(undefined);
-        }
-    }
-
-    function openInfrastructureSelector (uuid: string, propertyName: string)  {
-        setInfrastructureSelector(true);
-        setInfrastructureSelectorProperty(propertyName);
-        setInfrastructureSelectorUuid(uuid);
-    }
-
-    function closeInfrastructureSelector ()  {
-        setInfrastructureSelector(false);
-    }
-
-    function getInfrastructureSelectorModal() {
-        return (
-            <InfrastructureSelector
-                dark={false}
-                isOpen={infrastructureSelector}
-                onClose={() => closeInfrastructureSelector()}
-                onSelect={selectInfrastructure}/>)
-    }
-
-    function cloneBean ()  {
-        if (selectedStep) {
-            const bean = CamelUtil.cloneBean(selectedStep as RegistryBeanDefinition);
-            bean.uuid = uuidv4();
-            props.onClone(bean);
-        }
-    }
-
-    function getLabelIcon (displayName: string, description: string)  {
-        return (
-            <Popover
-                    position={"left"}
-                    headerContent={displayName}
-                    bodyContent={description}
-                    footerContent={
-                        <div>
-                            <b>Required</b>
-                        </div>
-                    }>
-                    <button type="button" aria-label="More info" onClick={e => {
-                        e.preventDefault();
-                        e.stopPropagation();
-                    }} className="pf-v5-c-form__group-label-help">
-                        <HelpIcon />
-                    </button>
-                </Popover>
-        )
-    }
-
-    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];
-                    const value = v[1][1];
-                    const showPassword = v[1][2];
-                    const isSecret = false;
-                    return (
-                        <div key={"key-" + i} className="bean-property">
-                            <TextInput placeholder="Argument Index" className="text-field" isRequired type="text" id={"key-" + i}
-                                       name={"key-" + i} value={key}
-                                       onChange={(_, beanFieldName) => {
-                                           constructorChanged(i, parseInt(beanFieldName) , value, showPassword)
-                                       }}/>
-                            <InputGroup>
-                                <InputGroupItem isFill>
-                                    <TextInput
-                                        placeholder="Argument Value"
-                                        type={isSecret && !showPassword ? "password" : "text"}
-                                        className="text-field"
-                                        isRequired
-                                        id={"value-" + i}
-                                        name={"value-" + i}
-                                        value={value}
-                                        onChange={(_, value) => {
-                                            constructorChanged(i, key, value, showPassword)
-                                        }}/>
-                                </InputGroupItem>
-                                {isSecret && <Tooltip position="bottom-end" content={showPassword ? "Hide" : "Show"}>
-                                    <Button variant="control" onClick={e => constructorChanged(i, key, value, !showPassword)}>
-                                        {showPassword ? <ShowIcon/> : <HideIcon/>}
-                                    </Button>
-                                </Tooltip>}
-                            </InputGroup>
-                            <Button variant="link" className="delete-button" onClick={e => constructorDeleted(i)}>
-                                <DeleteIcon/>
-                            </Button>
-                        </div>
-                    )
-                })}
-                <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];
-                        const value = v[1][1];
-                        const showPassword = v[1][2];
-                        const isSecret = key !== undefined && SensitiveKeys.includes(key.toLowerCase());
-                        const inInfrastructure = InfrastructureAPI.infrastructure !== 'local';
-                        const icon = InfrastructureAPI.infrastructure === 'kubernetes' ? KubernetesIcon("infra-button"): <DockerIcon/>
-                        return (
-                            <div key={"key-" + i} className="bean-property">
-                                <TextInput placeholder="Bean Field Name" className="text-field" isRequired type="text" id={"key-" + i}
-                                           name={"key-" + i} value={key}
-                                           onChange={(_, beanFieldName) => {
-                                               propertyChanged(i, beanFieldName, value, showPassword)
-                                           }}/>
-                                <InputGroup>
-                                    {inInfrastructure &&
-                                        <Tooltip position="bottom-end" content={"Select from " + capitalize(InfrastructureAPI.infrastructure)}>
-                                            <Button variant="control" onClick={e => openInfrastructureSelector(i, key)}>
-                                                {icon}
-                                            </Button>
-                                        </Tooltip>}
-                                    <InputGroupItem isFill>
-                                        <TextInput
-                                            placeholder="Bean Field Value"
-                                            type={isSecret && !showPassword ? "password" : "text"}
-                                            className="text-field"
-                                            isRequired
-                                            id={"value-" + i}
-                                            name={"value-" + i}
-                                            value={value}
-                                            onChange={(_, value) => {
-                                                propertyChanged(i, key, value, showPassword)
-                                            }}/>
-                                    </InputGroupItem>
-                                    {isSecret && <Tooltip position="bottom-end" content={showPassword ? "Hide" : "Show"}>
-                                        <Button variant="control" onClick={e => propertyChanged(i, key, value, !showPassword)}>
-                                            {showPassword ? <ShowIcon/> : <HideIcon/>}
-                                        </Button>
-                                    </Tooltip>}
-                                </InputGroup>
-                                <Button variant="link" className="delete-button" onClick={e => propertyDeleted(i)}><DeleteIcon/></Button>
-                            </div>
-                        )
-                    })}
-                    <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>
-            {getInfrastructureSelectorModal()}
-        </div>
-    )
-}
diff --git a/karavan-space/src/designer/property/property/ComponentParameterField.tsx b/karavan-space/src/designer/property/property/ComponentParameterField.tsx
deleted file mode 100644
index 7186616d..00000000
--- a/karavan-space/src/designer/property/property/ComponentParameterField.tsx
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React, {useRef, useState} from 'react';
-import {
-    FormGroup,
-    TextInput,
-    Popover,
-    Switch,
-    InputGroup,
-    TextArea,
-    Tooltip,
-    Button,
-    capitalize, InputGroupItem
-} from '@patternfly/react-core';
-import {
-    Select,
-    SelectVariant,
-    SelectDirection,
-    SelectOption
-} from '@patternfly/react-core/deprecated';
-import '../../karavan.css';
-import "@patternfly/patternfly/patternfly.css";
-import HelpIcon from "@patternfly/react-icons/dist/js/icons/help-icon";
-import {ComponentProperty} from "karavan-core/lib/model/ComponentModels";
-import {CamelUi, RouteToCreate} from "../../utils/CamelUi";
-import {CamelElement} from "karavan-core/lib/model/IntegrationDefinition";
-import {ToDefinition} from "karavan-core/lib/model/CamelDefinition";
-import CompressIcon from "@patternfly/react-icons/dist/js/icons/compress-icon";
-import ExpandIcon from "@patternfly/react-icons/dist/js/icons/expand-icon";
-import {InfrastructureSelector} from "./InfrastructureSelector";
-import {InfrastructureAPI} from "../../utils/InfrastructureAPI";
-import DockerIcon from "@patternfly/react-icons/dist/js/icons/docker-icon";
-import ShowIcon from "@patternfly/react-icons/dist/js/icons/eye-icon";
-import HideIcon from "@patternfly/react-icons/dist/js/icons/eye-slash-icon";
-import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
-import {usePropertiesHook} from "../usePropertiesHook";
-import {useIntegrationStore} from "../../DesignerStore";
-import {shallow} from "zustand/shallow";
-import {KubernetesIcon} from "../../icons/ComponentIcons";
-
-const prefix = "parameters";
-const beanPrefix = "#bean:";
-
-interface Props {
-    property: ComponentProperty,
-    element?: CamelElement,
-    value: any,
-    onParameterChange?: (parameter: string, value: string | number | boolean | any, pathParameter?: boolean, newRoute?: RouteToCreate) => void
-}
-
-export function ComponentParameterField(props: Props) {
-
-    const {onParametersChange, getInternalComponentName} = usePropertiesHook();
-
-    const [integration] = useIntegrationStore((state) => [state.integration], shallow)
-
-    const [selectStatus, setSelectStatus] = useState<Map<string, boolean>>(new Map<string, boolean>());
-    const [showEditor, setShowEditor] = useState<boolean>(false);
-    const [showPassword, setShowPassword] = useState<boolean>(false);
-    const [infrastructureSelector, setInfrastructureSelector] = useState<boolean>(false);
-    const [infrastructureSelectorProperty, setInfrastructureSelectorProperty] = useState<string | undefined>(undefined);
-
-    const [id, setId] = useState<string>(prefix + "-" + props.property.name);
-    const ref = useRef<any>(null);
-
-
-    function parametersChanged(parameter: string, value: string | number | boolean | any, pathParameter?: boolean, newRoute?: RouteToCreate) {
-        onParametersChange(parameter, value, pathParameter, newRoute);
-        setSelectStatus(new Map<string, boolean>([[parameter, false]]))
-    }
-
-    function openSelect(propertyName: string, isExpanded: boolean) {
-        setSelectStatus(new Map<string, boolean>([[propertyName, isExpanded]]))
-    }
-
-    function isSelectOpen(propertyName: string): boolean {
-        return selectStatus.has(propertyName) && selectStatus.get(propertyName) === true;
-    }
-
-    function getSelectBean(property: ComponentProperty, value: any) {
-        const selectOptions: JSX.Element[] = [];
-        const beans = CamelUi.getBeans(integration);
-        if (beans) {
-            selectOptions.push(<SelectOption key={0} value={"Select..."} isPlaceholder/>);
-            selectOptions.push(...beans.map((bean) => <SelectOption key={bean.name} value={beanPrefix + bean.name}
-                                                                    description={bean.type}/>));
-        }
-        return (
-            <Select
-                id={id} name={id}
-                variant={SelectVariant.typeahead}
-                aria-label={property.name}
-                onToggle={(_event, isExpanded) => {
-                    openSelect(property.name, isExpanded)
-                }}
-                onSelect={(e, value, isPlaceholder) => parametersChanged(property.name, (!isPlaceholder ? value : undefined))}
-                selections={value}
-                isCreatable={true}
-                createText=""
-                isOpen={isSelectOpen(property.name)}
-                aria-labelledby={property.name}
-                direction={SelectDirection.down}
-            >
-                {selectOptions}
-            </Select>
-        )
-    }
-
-    function canBeInternalUri(property: ComponentProperty): boolean {
-        if (props.element && props.element.dslName === 'ToDefinition' && property.name === 'name') {
-            const uri: string = (props.element as ToDefinition).uri || '';
-            return uri.startsWith("direct") || uri.startsWith("seda");
-        } else {
-            return false;
-        }
-    }
-
-    function getInternalUriSelect(property: ComponentProperty, value: any) {
-        const selectOptions: JSX.Element[] = [];
-        const componentName = getInternalComponentName(property.name, props.element);
-        const internalUris = CamelUi.getInternalRouteUris(integration, componentName, false);
-        const uris: string [] = [];
-        uris.push(...internalUris);
-        if (value && value.length > 0 && !uris.includes(value)) {
-            uris.unshift(value);
-        }
-        if (uris && uris.length > 0) {
-            selectOptions.push(...uris.map((value: string) =>
-                <SelectOption key={value} value={value ? value.trim() : value}/>));
-        }
-        return <InputGroup id={id} name={id}>
-            <InputGroupItem isFill>
-                <Select
-                    id={id} name={id}
-                    placeholderText="Select or type an URI"
-                    variant={SelectVariant.typeahead}
-                    aria-label={property.name}
-                    onToggle={(_event, isExpanded) => {
-                        openSelect(property.name, isExpanded)
-                    }}
-                    onSelect={(e, value, isPlaceholder) => {
-                        parametersChanged(property.name, (!isPlaceholder ? value : undefined), property.kind === 'path', undefined);
-                    }}
-                    selections={value}
-                    isOpen={isSelectOpen(property.name)}
-                    isCreatable={true}
-                    createText=""
-                    isInputFilterPersisted={true}
-                    aria-labelledby={property.name}
-                    direction={SelectDirection.down}>
-                    {selectOptions}
-                </Select>
-            </InputGroupItem>
-            <InputGroupItem>
-                <Tooltip position="bottom-end" content={"Create route"}>
-                    <Button isDisabled={value === undefined} variant="control" onClick={e => {
-                        if (value) {
-                            const newRoute = !internalUris.includes(value.toString())
-                                ? CamelUi.createNewInternalRoute(componentName.concat(...':',value.toString()))
-                                : undefined;
-                            parametersChanged(property.name, value, property.kind === 'path', newRoute);
-                        }
-                    }}>
-                        {<PlusIcon/>}
-                    </Button>
-                </Tooltip>
-            </InputGroupItem>
-        </InputGroup>
-    }
-
-    function selectInfrastructure(value: string) {
-        // check if there is a selection
-        const textVal = ref.current;
-        const cursorStart = textVal.selectionStart;
-        const cursorEnd = textVal.selectionEnd;
-        if (cursorStart !== cursorEnd) {
-            const prevValue = props.value;
-            const selectedText = prevValue.substring(cursorStart, cursorEnd)
-            value = prevValue.replace(selectedText, value);
-        }
-        const propertyName = infrastructureSelectorProperty;
-        if (propertyName) {
-            if (value.startsWith("config") || value.startsWith("secret")) value = "{{" + value + "}}";
-            parametersChanged(propertyName, value);
-            setInfrastructureSelector(false);
-            setInfrastructureSelectorProperty(undefined);
-        }
-    }
-
-    function openInfrastructureSelector(propertyName: string) {
-        setInfrastructureSelector(true);
-        setInfrastructureSelectorProperty(propertyName);
-    }
-
-
-    function getInfrastructureSelectorModal() {
-        return (
-            <InfrastructureSelector
-                dark={false}
-                isOpen={infrastructureSelector}
-                onClose={() => setInfrastructureSelector(false)}
-                onSelect={selectInfrastructure}/>)
-    }
-
-    function getStringInput(property: ComponentProperty, value: any) {
-        const inInfrastructure = InfrastructureAPI.infrastructure !== 'local';
-        const noInfraSelectorButton = ["uri", "id", "description", "group"].includes(property.name);
-        const icon = InfrastructureAPI.infrastructure === 'kubernetes' ? KubernetesIcon("infra-button") : <DockerIcon/>
-        return <InputGroup>
-            {inInfrastructure && !showEditor && !noInfraSelectorButton &&
-                <Tooltip position="bottom-end"
-                         content={"Select from " + capitalize((InfrastructureAPI.infrastructure))}>
-                    <Button variant="control" onClick={e => openInfrastructureSelector(property.name)}>
-                        {icon}
-                    </Button>
-                </Tooltip>}
-            {(!showEditor || property.secret) &&
-                <TextInput className="text-field" isRequired ref={ref}
-                           type={property.secret && !showPassword ? "password" : "text"}
-                           id={id} name={id}
-                           value={value !== undefined ? value : property.defaultValue}
-                           onChange={(e, value) => parametersChanged(property.name, value, property.kind === 'path')}/>}
-            {showEditor && !property.secret &&
-                <TextArea autoResize={true} ref={ref}
-                          className="text-field" isRequired
-                          type="text"
-                          id={id} name={id}
-                          value={value !== undefined ? value : property.defaultValue}
-                          onChange={(e, value) => parametersChanged(property.name, value, property.kind === 'path')}/>}
-            {!property.secret &&
-                <Tooltip position="bottom-end" content={showEditor ? "Change to TextField" : "Change to Text Area"}>
-                    <Button variant="control" onClick={e => setShowEditor(!showEditor)}>
-                        {showEditor ? <CompressIcon/> : <ExpandIcon/>}
-                    </Button>
-                </Tooltip>
-            }
-            {property.secret &&
-                <Tooltip position="bottom-end" content={showPassword ? "Hide" : "Show"}>
-                    <Button variant="control" onClick={e => setShowPassword(!showPassword)}>
-                        {showPassword ? <ShowIcon/> : <HideIcon/>}
-                    </Button>
-                </Tooltip>
-            }
-        </InputGroup>
-    }
-
-    function getTextInput(property: ComponentProperty, value: any) {
-        return (
-            <TextInput
-                className="text-field" isRequired
-                type={['integer', 'int', 'number'].includes(property.type) ? 'number' : (property.secret ? "password" : "text")}
-                id={id} name={id}
-                value={value !== undefined ? value : property.defaultValue}
-                onChange={(_, value) => {
-                    parametersChanged(property.name, ['integer', 'int', 'number'].includes(property.type) ? Number(value) : value, property.kind === 'path')
-                }}/>
-        )
-    }
-
-    function getSelect(property: ComponentProperty, value: any) {
-        const selectOptions: JSX.Element[] = []
-        if (property.enum && property.enum.length > 0) {
-            selectOptions.push(<SelectOption key={0} value={"Select ..."} isPlaceholder/>);
-            property.enum.forEach(v => selectOptions.push(<SelectOption key={v} value={v}/>));
-        }
-        return (
-            <Select
-                id={id} name={id}
-                variant={SelectVariant.single}
-                aria-label={property.name}
-                onToggle={(_event, isExpanded) => {
-                    openSelect(property.name, isExpanded)
-                }}
-                onSelect={(e, value, isPlaceholder) => parametersChanged(property.name, (!isPlaceholder ? value : undefined), property.kind === 'path')}
-                selections={value !== undefined ? value.toString() : property.defaultValue}
-                isOpen={isSelectOpen(property.name)}
-                aria-labelledby={property.name}
-                direction={SelectDirection.down}
-            >
-                {selectOptions}
-            </Select>
-        )
-    }
-
-    function getSwitch(property: ComponentProperty, value: any) {
-        const isChecked = value !== undefined ? Boolean(value) : (property.defaultValue !== undefined && ['true', true].includes(property.defaultValue))
-        return (
-            <Switch
-                id={id} name={id}
-                value={value?.toString()}
-                aria-label={id}
-                isChecked={isChecked}
-                onChange={(e, checked) => parametersChanged(property.name, checked)}/>
-        )
-    }
-
-    const property: ComponentProperty = props.property;
-    const value = props.value;
-    return (
-        <FormGroup
-            key={id}
-            label={property.displayName}
-            isRequired={property.required}
-            labelIcon={
-                <Popover
-                    position={"left"}
-                    headerContent={property.displayName}
-                    bodyContent={property.description}
-                    footerContent={
-                        <div>
-                            {property.defaultValue !== undefined && <div>{"Default: " + property.defaultValue}</div>}
-                            {property.required && <div>{property.displayName + " is required"}</div>}
-                        </div>
-                    }>
-                    <button type="button" aria-label="More info" onClick={e => e.preventDefault()}
-                            className="pf-v5-c-form__group-label-help">
-                        <HelpIcon/>
-                    </button>
-                </Popover>
-            }>
-            {canBeInternalUri(property) && getInternalUriSelect(property, value)}
-            {property.type === 'string' && property.enum === undefined && !canBeInternalUri(property)
-                && getStringInput(property, value)}
-            {['duration', 'integer', 'int', 'number'].includes(property.type) && property.enum === undefined && !canBeInternalUri(property)
-                && getTextInput(property, value)}
-            {['object'].includes(property.type) && !property.enum
-                && getSelectBean(property, value)}
-            {['string', 'object'].includes(property.type) && property.enum
-                && getSelect(property, value)}
-            {property.type === 'boolean'
-                && getSwitch(property, value)}
-            {getInfrastructureSelectorModal()}
-        </FormGroup>
-    )
-}
diff --git a/karavan-space/src/designer/property/property/ComponentPropertyField.tsx b/karavan-space/src/designer/property/property/ComponentPropertyField.tsx
index e7460847..52488a89 100644
--- a/karavan-space/src/designer/property/property/ComponentPropertyField.tsx
+++ b/karavan-space/src/designer/property/property/ComponentPropertyField.tsx
@@ -53,7 +53,7 @@ import {useDesignerStore, useIntegrationStore} from "../../DesignerStore";
 import {shallow} from "zustand/shallow";
 import {KubernetesIcon} from "../../icons/ComponentIcons";
 import EditorIcon from "@patternfly/react-icons/dist/js/icons/code-icon";
-import {ModalEditor} from "./ModalEditor";
+import {ExpressionModalEditor} from "../../../expression/ExpressionModalEditor";
 import {PropertyPlaceholderDropdown} from "./PropertyPlaceholderDropdown";
 
 const prefix = "parameters";
@@ -280,14 +280,14 @@ export function ComponentPropertyField(props: Props) {
                 </Tooltip>
             </InputGroupItem>
             {showEditor && <InputGroupItem>
-                <ModalEditor name={property.name}
-                             customCode={value}
-                             showEditor={showEditor}
-                             dark={dark}
-                             dslLanguage={undefined}
-                             title={property.displayName}
-                             onClose={() => setShowEditor(false)}
-                             onSave={(fieldId, value1) => {
+                <ExpressionModalEditor name={property.name}
+                                       customCode={value}
+                                       showEditor={showEditor}
+                                       dark={dark}
+                                       dslLanguage={undefined}
+                                       title={property.displayName}
+                                       onClose={() => setShowEditor(false)}
+                                       onSave={(fieldId, value1) => {
                                  setTextValue(value1);
                                  parametersChanged(property.name, value1, property.kind === 'path')
                                  setShowEditor(false);
diff --git a/karavan-space/src/designer/property/property/ComponentPropertyPlaceholderDropdown.tsx b/karavan-space/src/designer/property/property/ComponentPropertyPlaceholderDropdown.tsx
deleted file mode 100644
index f287c300..00000000
--- a/karavan-space/src/designer/property/property/ComponentPropertyPlaceholderDropdown.tsx
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React, {useState} from 'react';
-import {
-    Dropdown,
-    MenuToggleElement,
-    MenuToggle,
-    DropdownList,
-    DropdownItem,
-    Popover,
-    Flex,
-    TextInput,
-    FormGroup,
-    Form,
-    Button,
-    FlexItem,
-    DropdownGroup, Divider
-} from '@patternfly/react-core';
-import '../../karavan.css';
-import './ComponentPropertyPlaceholderDropdown.css';
-import "@patternfly/patternfly/patternfly.css";
-import {ComponentProperty} from "karavan-core/lib/model/ComponentModels";
-import {RouteToCreate} from "../../utils/CamelUi";
-import {usePropertiesHook} from "../usePropertiesHook";
-import {useDesignerStore} from "../../DesignerStore";
-import {shallow} from "zustand/shallow";
-import EllipsisVIcon from "@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon";
-import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-icon";
-import {InfrastructureAPI} from "../../utils/InfrastructureAPI";
-
-const SYNTAX_EXAMPLES = [
-    {key: 'property:', value: 'group.property', description: 'Application property'},
-    {key: 'env:', value: 'env:ENV_NAME', description: 'OS environment variable'},
-    {key: 'sys:', value: 'sys:JvmPropertyName', description: 'JVM system property'},
-    {key: 'bean:', value: 'bean:beanName.method', description: 'Bean’s method'}
-]
-
-interface Props {
-    property: ComponentProperty,
-    value: any
-}
-
-export function ComponentPropertyPlaceholderDropdown(props: Props) {
-
-    const {onParametersChange} = usePropertiesHook();
-    const [propertyPlaceholders, setPropertyPlaceholders] = useDesignerStore((s) =>
-        [s.propertyPlaceholders, s.setPropertyPlaceholders], shallow)
-    const [isOpenPlaceholdersDropdown, setOpenPlaceholdersDropdown] = useState<boolean>(false);
-    const [propValue, setPropValue] = useState<string>('');
-    const [isVisible, setIsVisible] = React.useState(false);
-
-    function removeBrackets(val: string) {
-        return val.replace('{{', '').replace('}}', '');
-    }
-
-    const {property, value} = props;
-    const valueIsPlaceholder: boolean = value && value.toString().startsWith('{{') && value.toString().endsWith('}}');
-    const placeholderValue = valueIsPlaceholder ? value.toString().replace('{{', '').replace('}}', '') : undefined;
-    const showAddButton = valueIsPlaceholder
-        && !propertyPlaceholders.includes(placeholderValue)
-        && !SYNTAX_EXAMPLES.map(se=> se.value).includes(removeBrackets(placeholderValue))
-        && SYNTAX_EXAMPLES.findIndex(se=> removeBrackets(placeholderValue).startsWith(se.key)) === -1;
-    const popoverId = "popover-selector-" + property.name;
-
-    const hasPlaceholders = (propertyPlaceholders && propertyPlaceholders.length > 0 );
-
-    function parametersChanged(parameter: string, value: string | number | boolean | any, pathParameter?: boolean, newRoute?: RouteToCreate) {
-        onParametersChange(parameter, value, pathParameter, newRoute);
-    }
-
-    function onMenuToggleClick() {
-        if (!showAddButton) {
-            setOpenPlaceholdersDropdown(!isOpenPlaceholdersDropdown)
-        }
-    }
-
-    function saveProperty() {
-        InfrastructureAPI.onSavePropertyPlaceholder(placeholderValue, propValue);
-        setIsVisible(false);
-        const p = [...propertyPlaceholders]
-        p.push(placeholderValue);
-        setPropertyPlaceholders(p);
-    }
-
-    function getPopover() {
-        return (
-            <Popover
-                isVisible={isVisible}
-                shouldOpen={(_event, _fn) => setIsVisible(true)}
-                shouldClose={(_event, _fn) => setIsVisible(false)}
-                aria-label="Add property"
-                headerContent={"Add property"}
-                bodyContent={
-                    <Form isHorizontal className="property-placeholder-toggle-form" autoComplete="off">
-                        <FormGroup isInline label="Property" isRequired fieldId="property">
-                            <TextInput id="property" readOnly value={placeholderValue}/>
-                        </FormGroup>
-                        <FormGroup isInline label="Value" isRequired fieldId="value">
-                            <TextInput id="value" isRequired value={propValue}
-                                       onChange={(_, value) => setPropValue(value)}/>
-                        </FormGroup>
-                    </Form>
-                }
-                footerContent={
-                    <Flex>
-                        <FlexItem align={{default: "alignRight"}}>
-                            <Button
-                                onClick={() => saveProperty()}>
-                                Save
-                            </Button>
-                        </FlexItem>
-                    </Flex>
-                }
-                triggerRef={() => document.getElementById(popoverId) as HTMLButtonElement}
-            />
-        )
-    }
-
-    function getToggle(toggleRef: React.Ref<MenuToggleElement>) {
-        return (
-            <MenuToggle className="property-placeholder-toggle"
-                        id={popoverId}
-                        ref={toggleRef}
-                        aria-label="placeholder menu"
-                        variant="default"
-                        onClick={() => onMenuToggleClick()}
-                        isExpanded={isOpenPlaceholdersDropdown}
-            >
-                {showAddButton ? <AddIcon/> : <EllipsisVIcon/>}
-                {showAddButton && getPopover()}
-            </MenuToggle>
-        )
-    }
-
-    return (
-        <Dropdown
-            popperProps={{position: "end"}}
-            isOpen={isOpenPlaceholdersDropdown}
-            onSelect={(_, value) => {
-                parametersChanged(property.name, `{{${value}}}`, property.kind === 'path')
-                setOpenPlaceholdersDropdown(false);
-            }}
-            onOpenChange={(isOpen: boolean) => setOpenPlaceholdersDropdown(isOpen)}
-            toggle={(toggleRef: React.Ref<MenuToggleElement>) => getToggle(toggleRef)}
-            shouldFocusToggleOnSelect
-        >
-            <DropdownList>
-                {hasPlaceholders && <DropdownGroup label="Application Properties">
-                    {propertyPlaceholders.map((pp, index) =>
-                        <DropdownItem value={pp} key={index}>{pp}</DropdownItem>
-                    )}
-                </DropdownGroup>}
-                {hasPlaceholders && <Divider component="li"/>}
-                <DropdownGroup label="Syntax examples">
-                    {SYNTAX_EXAMPLES.map(se =>
-                        <DropdownItem value={se.value} key={se.key} description={se.description}>
-                            {se.value}
-                        </DropdownItem>)
-                    }
-                </DropdownGroup>
-            </DropdownList>
-        </Dropdown>
-    )
-}
diff --git a/karavan-space/src/designer/property/property/DslPropertyField.tsx b/karavan-space/src/designer/property/property/DslPropertyField.tsx
index cd137961..86240ed7 100644
--- a/karavan-space/src/designer/property/property/DslPropertyField.tsx
+++ b/karavan-space/src/designer/property/property/DslPropertyField.tsx
@@ -62,7 +62,7 @@ import {ComponentProperty} from "karavan-core/lib/model/ComponentModels";
 import {InfrastructureSelector} from "./InfrastructureSelector";
 import {InfrastructureAPI} from "../../utils/InfrastructureAPI";
 import EditorIcon from "@patternfly/react-icons/dist/js/icons/code-icon";
-import {ModalEditor} from "./ModalEditor";
+import {ExpressionModalEditor} from "../../../expression/ExpressionModalEditor";
 import DockerIcon from "@patternfly/react-icons/dist/js/icons/docker-icon";
 import {useDesignerStore, useIntegrationStore} from "../../DesignerStore";
 import {shallow} from "zustand/shallow";
@@ -394,14 +394,14 @@ export function DslPropertyField(props: Props) {
                 </Tooltip>
             </InputGroupItem>}
             {showEditor && <InputGroupItem>
-                <ModalEditor name={property.name}
-                             customCode={value}
-                             showEditor={showEditor}
-                             dark={dark}
-                             dslLanguage={undefined}
-                             title={property.displayName}
-                             onClose={() => setShowEditor(false)}
-                             onSave={(fieldId, value1) => {
+                <ExpressionModalEditor name={property.name}
+                                       customCode={value}
+                                       showEditor={showEditor}
+                                       dark={dark}
+                                       dslLanguage={undefined}
+                                       title={property.displayName}
+                                       onClose={() => setShowEditor(false)}
+                                       onSave={(fieldId, value1) => {
                                  propertyChanged(property.name, value1)
                                  setTextValue(value1);
                                  setShowEditor(false);
@@ -448,14 +448,14 @@ export function DslPropertyField(props: Props) {
                 </Tooltip>
             </InputGroupItem>
             {showEditor && <InputGroupItem>
-                <ModalEditor name={property.name}
-                             customCode={customCode}
-                             showEditor={showEditor}
-                             dark={dark}
-                             dslLanguage={dslLanguage}
-                             title="Java Class"
-                             onClose={() => setShowEditor(false)}
-                             onSave={(fieldId, value1) => {
+                <ExpressionModalEditor name={property.name}
+                                       customCode={customCode}
+                                       showEditor={showEditor}
+                                       dark={dark}
+                                       dslLanguage={dslLanguage}
+                                       title="Java Class"
+                                       onClose={() => setShowEditor(false)}
+                                       onSave={(fieldId, value1) => {
                                  propertyChanged(fieldId, value);
                                  InfrastructureAPI.onSaveCustomCode?.(value, value1);
                                  setShowEditor(false)
@@ -491,14 +491,14 @@ export function DslPropertyField(props: Props) {
                     </Tooltip>
                 </InputGroupItem>
                 {showEditor && <InputGroupItem>
-                    <ModalEditor name={property.name}
-                                 customCode={value}
-                                 showEditor={showEditor}
-                                 dark={dark}
-                                 dslLanguage={dslLanguage}
-                                 title={`Expression (${dslLanguage?.[0]})`}
-                                 onClose={() => setShowEditor(false)}
-                                 onSave={(fieldId, value1) => {
+                    <ExpressionModalEditor name={property.name}
+                                           customCode={value}
+                                           showEditor={showEditor}
+                                           dark={dark}
+                                           dslLanguage={dslLanguage}
+                                           title={`Expression (${dslLanguage?.[0]})`}
+                                           onClose={() => setShowEditor(false)}
+                                           onSave={(fieldId, value1) => {
                                      propertyChanged(fieldId, value1);
                                      setTextValue(value1);
                                      setShowEditor(false);
diff --git a/karavan-space/src/designer/route/DslSelector.css b/karavan-space/src/designer/route/DslSelector.css
deleted file mode 100644
index 4bca7774..00000000
--- a/karavan-space/src/designer/route/DslSelector.css
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-.dsl-modal {
-    height: 80%;
-    color: var(--pf-v5-global--Color--100);
-}
-
-.dsl-modal .dsl-card {
-    cursor: pointer;
-}
-
-.dsl-modal .dsl-card .pf-v5-c-card__header-main {
-    display: flex;
-    flex-direction: row;
-}
-
-.dsl-modal .dsl-card .header-labels .pf-v5-c-card__header-main {
-    display: flex;
-    flex-direction: row;
-    justify-content: space-between;
-}
-
-.dsl-modal .dsl-card .icon {
-    height: 20px;
-    width: auto;
-    border: none;
-    margin-right: 6px;
-    -webkit-user-select: none;
-    -khtml-user-select: none;
-    -moz-user-select: none;
-    -o-user-select: none;
-    user-select: none;
-}
-
-.dsl-modal .search {
-    position: absolute;
-    top: 24px;
-    right: 72px;
-    display:flex;
-    justify-content:flex-end;
-}
-
-.dsl-modal .search .pf-v5-c-form__group-label {
-    padding: 0;
-    margin: auto;
-}
-
-.dsl-modal .search .text-field {
-    height: auto;
-}
-
-.dsl-modal .pf-v5-c-form.pf-v5-m-horizontal .pf-v5-c-form__group {
-    display: contents;
-}
-
-.dsl-modal .pf-v5-c-card__body {
-    padding-bottom: 0;
-    height: 54px;
-}
-
-
-.dsl-modal .dsl-card p {
-    overflow: hidden;
-    display: -webkit-box;
-    -webkit-line-clamp: 2;
-    -webkit-box-orient: vertical;
-}
-.dsl-modal .pf-v5-c-card__footer {
-    padding-bottom: 1em;
-}
-
-.dsl-modal .footer {
-    display: flex;
-    flex-direction: row;
-    margin-top: 6px;
-    flex-wrap: wrap;
-}
-
-.dsl-modal .dsl-card .header-labels {
-    padding: 5px;
-    display: flex;
-    flex-direction: row;
-    justify-content: space-between;
-}
-
-.dsl-modal .dsl-card .footer-labels {
-    padding: 5px;
-    display: flex;
-    flex-direction: row;
-    justify-content: space-between;
-}
-
-.dsl-modal .version,
-.dsl-modal .support-type,
-.dsl-modal .support-level {
-    white-space: nowrap;
-}
-
-.dsl-modal .labels {
-    opacity: 0.5;
-    font-weight: 200;
-    text-wrap: nowrap;
-}
-
-.dsl-modal .dsl-card:hover .labels {
-    opacity: 1;
-}
diff --git a/karavan-space/src/designer/route/DslSelector.tsx b/karavan-space/src/designer/route/DslSelector.tsx
deleted file mode 100644
index c7dde3e7..00000000
--- a/karavan-space/src/designer/route/DslSelector.tsx
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React, {useEffect, useState} from 'react';
-import {
-    Badge,
-    Card,
-    CardBody,
-    CardFooter,
-    CardHeader,
-    Flex,
-    FlexItem,
-    Form,
-    FormGroup,
-    Gallery,
-    Modal,
-    PageSection,
-    Tab,
-    Tabs,
-    TabTitleText,
-    Text,
-    ToggleGroup,
-    ToggleGroupItem,
-    Switch,
-    TextInputGroup,
-    TextInputGroupMain,
-    TextInputGroupUtilities,
-    Button
-} from '@patternfly/react-core';
-import './DslSelector.css';
-import {CamelUi} from "../utils/CamelUi";
-import {DslMetaModel} from "../utils/DslMetaModel";
-import {useDesignerStore, useSelectorStore} from "../DesignerStore";
-import {shallow} from "zustand/shallow";
-import {useRouteDesignerHook} from "./useRouteDesignerHook";
-import { ComponentApi } from 'karavan-core/lib/api/ComponentApi';
-import { KameletApi } from 'karavan-core/lib/api/KameletApi';
-import TimesIcon from "@patternfly/react-icons/dist/esm/icons/times-icon";
-
-interface Props {
-    tabIndex?: string | number
-}
-
-export function DslSelector (props: Props) {
-
-    const [showSelector, showSteps, parentId, parentDsl, selectorTabIndex, setShowSelector, setSelectorTabIndex,
-        selectedPosition, selectedLabels, addSelectedLabel, deleteSelectedLabel] =
-        useSelectorStore((s) =>
-            [s.showSelector, s.showSteps, s.parentId, s.parentDsl, s.selectorTabIndex, s.setShowSelector, s.setSelectorTabIndex,
-                s.selectedPosition, s.selectedLabels, s.addSelectedLabel, s.deleteSelectedLabel], shallow)
-
-    const [dark] = useDesignerStore((s) => [s.dark], shallow)
-
-    const {onDslSelect} = useRouteDesignerHook();
-
-
-    const [filter, setFilter] = useState<string>('');
-    const [customOnly, setCustomOnly] = useState<boolean>(false);
-
-    useEffect(() => {
-    }, [selectedLabels]);
-
-
-    function selectTab(evt: React.MouseEvent<HTMLElement, MouseEvent>, eventKey: string | number) {
-        setSelectorTabIndex(eventKey);
-    }
-
-    function selectDsl(evt: React.MouseEvent, dsl: any) {
-        evt.stopPropagation();
-        setFilter('');
-        setShowSelector(false);
-        onDslSelect(dsl, parentId, selectedPosition);
-    }
-
-    function searchInput() {
-        return (
-            <Flex className="search">
-                {selectorTabIndex === 'kamelet' && <FlexItem>
-                    <Switch
-                        label="Custom only"
-                        id="switch"
-                        isChecked={customOnly}
-                        onChange={(_event, checked) => setCustomOnly(checked)}
-                    />
-                </FlexItem>}
-                <FlexItem>
-                    <TextInputGroup>
-                        <TextInputGroupMain className="text-field" type="text" autoComplete={"off"}
-                               value={filter}
-                               onChange={(_, value) => setFilter(value)}/>
-                        <TextInputGroupUtilities>
-                            <Button variant="plain" onClick={_ => setFilter('')}>
-                                <TimesIcon />
-                            </Button>
-                        </TextInputGroupUtilities>
-                    </TextInputGroup>
-                </FlexItem>
-            </Flex>
-        )
-    }
-
-    function getCard(dsl: DslMetaModel, index: number) {
-        const labels = dsl.labels !== undefined ? dsl.labels.split(",").filter(label => label !== 'eip') : [];
-        const isCustom = KameletApi.getCustomKameletNames().includes(dsl.name);
-        return (
-            <Card key={dsl.dsl + index} isCompact className="dsl-card"
-                  onClick={event => selectDsl(event, dsl)}>
-                <CardHeader className="header-labels">
-                    <Badge isRead className="support-level labels">{dsl.supportLevel}</Badge>
-                    {['kamelet', 'component'].includes(dsl.navigation.toLowerCase()) &&
-                        <Badge isRead className="version labels">{dsl.version}</Badge>
-                    }
-                    {isCustom && <Badge className="custom">custom</Badge>}
-                </CardHeader>
-                <CardHeader>
-                    {CamelUi.getIconForDsl(dsl)}
-                    <Text>{dsl.title}</Text>
-                </CardHeader>
-                <CardBody>
-                    <Text>{dsl.description}</Text>
-                </CardBody>
-                <CardFooter className="footer-labels">
-                    <div style={{display: "flex", flexDirection: "row", justifyContent: "start"}}>
-                        {labels.map((label, index) => <Badge key={label + "-" + index} isRead
-                                                             className="labels">{label}</Badge>)}
-                    </div>
-
-                </CardFooter>
-            </Card>
-        )
-    }
-
-    function close() {
-        setFilter('');
-        setShowSelector(false);
-    }
-
-    function selectLabel(eipLabel: string) {
-        if (!selectedLabels.includes(eipLabel)) {
-            addSelectedLabel(eipLabel);
-        } else {
-            deleteSelectedLabel(eipLabel);
-        }
-    }
-
-    function filterElements(elements: DslMetaModel[]):DslMetaModel[] {
-        return elements.filter((dsl: DslMetaModel) => CamelUi.checkFilter(dsl, filter))
-            .filter((dsl: DslMetaModel) => {
-                if (!isEip || selectedLabels.length === 0) {
-                    return true;
-                } else {
-                    return dsl.labels.split(",").some(r => selectedLabels.includes(r));
-                }
-            });
-    }
-
-    const isEip = selectorTabIndex === 'eip';
-    const isRouteConfig = parentDsl === 'RouteConfigurationDefinition';
-    const title = parentDsl === undefined ? "Select source" : "Select step";
-    const navigation: string = selectorTabIndex ? selectorTabIndex.toString() : '';
-    const blockedComponents = ComponentApi.getBlockedComponentNames();
-    const blockedKamelets = KameletApi.getBlockedKameletNames();
-
-    const eipElements = CamelUi.getSelectorModelsForParentFiltered(parentDsl, 'eip', showSteps);
-    const componentElements = CamelUi.getSelectorModelsForParentFiltered(parentDsl, 'component', showSteps)
-        .filter(dsl => (!blockedComponents.includes(dsl.uri || dsl.name)));
-    let kameletElements = CamelUi.getSelectorModelsForParentFiltered(parentDsl, 'kamelet', showSteps)
-        .filter(dsl => (!blockedKamelets.includes(dsl.name)));
-    if (customOnly) kameletElements = kameletElements.filter(k => KameletApi.getCustomKameletNames().includes(k.name));
-
-    const filteredEipElements = filterElements(eipElements);
-    const filteredComponentElements = filterElements(componentElements);
-    const filteredKameletElements = filterElements(kameletElements);
-
-    const eipLabels = [...new Set(eipElements.map(e => e.labels).join(",").split(",").filter(e => e !== 'eip'))];
-
-
-    const filteredElement = navigation === 'component'
-        ? filteredComponentElements
-        : (navigation === 'kamelet' ? filteredKameletElements : filteredEipElements);
-
-    console.log(parentDsl)
-
-    return (
-        <Modal
-            aria-label={title}
-            width={'90%'}
-            className='dsl-modal'
-            isOpen={showSelector}
-            onClose={() => close()}
-            header={
-                <Flex direction={{default: "column"}}>
-                    <FlexItem>
-                        <h3>{title}</h3>
-                        {searchInput()}
-                    </FlexItem>
-                    <FlexItem>
-                        <Tabs style={{overflow: 'hidden'}} activeKey={selectorTabIndex}
-                              onSelect={selectTab}>
-                            {parentDsl !== undefined &&
-                                <Tab eventKey={"eip"} key={"tab-eip"}
-                                     title={<TabTitleText>{`Integration Patterns (${filteredEipElements?.length})`}</TabTitleText>}>
-                                </Tab>
-                            }
-                            {!isRouteConfig &&
-                                <Tab eventKey={'kamelet'} key={"tab-kamelet"}
-                                     title={
-                                         <TabTitleText>{`Kamelets (${filteredKameletElements?.length})`}</TabTitleText>}>
-                                </Tab>
-                            }
-                            {!isRouteConfig &&
-                                <Tab eventKey={'component'} key={'tab-component'}
-                                     title={
-                                         <TabTitleText>{`Components (${filteredComponentElements?.length})`}</TabTitleText>}>
-                                </Tab>
-                            }
-                        </Tabs>
-                    </FlexItem>
-                </Flex>
-            }
-            actions={{}}>
-            <PageSection padding={{default: "noPadding"}} variant={dark ? "darker" : "light"}>
-                {isEip && <ToggleGroup aria-label="Labels" isCompact>
-                    {eipLabels.map(eipLabel => <ToggleGroupItem
-                        key={eipLabel}
-                        text={eipLabel}
-                        buttonId={eipLabel}
-                        isSelected={selectedLabels.includes(eipLabel)}
-                        onChange={selected => selectLabel(eipLabel)}
-                    />)}
-                </ToggleGroup>}
-                <Gallery key={"gallery-" + navigation} hasGutter className="dsl-gallery">
-                    {showSelector && filteredElement.map((dsl: DslMetaModel, index: number) => getCard(dsl, index))}
-                </Gallery>
-            </PageSection>
-        </Modal>
-    )
-}
\ No newline at end of file
diff --git a/karavan-space/src/designer/templates/TemplatesDesigner.tsx b/karavan-space/src/designer/templates/TemplatesDesigner.tsx
deleted file mode 100644
index ffc5d9d9..00000000
--- a/karavan-space/src/designer/templates/TemplatesDesigner.tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React from 'react';
-import {
-     EmptyState, EmptyStateBody, EmptyStateIcon,
-    PageSection, EmptyStateHeader, 
-} from '@patternfly/react-core';
-import '../karavan.css';
-import {CamelElement, Integration} from "karavan-core/lib/model/IntegrationDefinition";
-import CubesIcon from '@patternfly/react-icons/dist/esm/icons/cubes-icon';
-
-interface Props {
-    onSave?: (integration: Integration, propertyOnly: boolean) => void
-    integration: Integration
-    dark: boolean
-}
-
-interface State {
-    integration: Integration
-    selectedStep?: CamelElement
-    key: string
-    propertyOnly: boolean
-}
-
-export class TemplatesDesigner extends React.Component<Props, State> {
-
-    public state: State = {
-        integration: this.props.integration,
-        key: "",
-        propertyOnly: false
-    };
-
-    componentDidUpdate = (prevProps: Readonly<Props>, prevState: Readonly<State>, snapshot?: any) => {
-        if (prevState.key !== this.state.key) {
-            this.props.onSave?.call(this, this.state.integration, this.state.propertyOnly);
-        }
-    }
-
-    onIntegrationUpdate = (i: Integration) => {
-        this.setState({integration: i, key: Math.random().toString()});
-    }
-
-    render() {
-        return (
-            <PageSection className="templates-page" isFilled padding={{default: 'noPadding'}}>
-                <div className="templates-page-columns">
-                    <EmptyState>
-                        <EmptyStateHeader titleText="Templates" icon={<EmptyStateIcon icon={CubesIcon} />} headingLevel="h4" />
-                        <EmptyStateBody>
-                            Templates not implemented yet
-                        </EmptyStateBody>
-                    </EmptyState>
-                </div>
-            </PageSection>
-        );
-    }
-}
diff --git a/karavan-space/src/designer/utils/KaravanComponents.tsx b/karavan-space/src/designer/utils/KaravanComponents.tsx
deleted file mode 100644
index faddd84d..00000000
--- a/karavan-space/src/designer/utils/KaravanComponents.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React from 'react';
-import {FormGroup, TextInput, Title} from "@patternfly/react-core";
-import {Integration} from "karavan-core/lib/model/IntegrationDefinition";
-
-interface Props {
-    integration: Integration,
-}
-
-export class IntegrationHeader extends React.Component<Props> {
-
-    render() {
-        return (
-            <div className="headers">
-                <Title headingLevel="h1" size="md">Integration</Title>
-                {/*<FormGroup label="Title" fieldId="title" isRequired>*/}
-                {/*    <TextInput className="text-field" type="text" id="title" name="title" isReadOnly*/}
-                {/*               value={*/}
-                {/*                   CamelUi.titleFromName(this.props.integration.metadata.name)*/}
-                {/*               }/>*/}
-                {/*</FormGroup>*/}
-                <FormGroup label="Name" fieldId="name" isRequired>
-                    <TextInput className="text-field" type="text" id="name" name="name" 
-                               value={this.props.integration.metadata.name} readOnlyVariant="default"/>
-                </FormGroup>
-            </div>
-        )
-    }
-}
diff --git a/karavan-space/src/designer/utils/KaravanIcons.tsx b/karavan-space/src/designer/utils/KaravanIcons.tsx
deleted file mode 100644
index 906ba86e..00000000
--- a/karavan-space/src/designer/utils/KaravanIcons.tsx
+++ /dev/null
@@ -1,2347 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React from 'react';
-
-export function KaravanIcon(className?: string) {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            xmlnsXlink="http://www.w3.org/1999/xlink"
-            id="svg50"
-            width="256"
-            height="256"
-            preserveAspectRatio="xMidYMid"
-            version="1.1"
-            viewBox="0 0 256 256"
-            className={className ? className : "logo"}
-        >
-            <defs id="defs31">
-                <linearGradient id="linearGradient1351">
-                    <stop
-                        id="stop1347"
-                        offset="0"
-                        stopColor="#dcffff"
-                        stopOpacity="1"
-                    ></stop>
-                    <stop
-                        id="stop1349"
-                        offset="1"
-                        stopColor="#96d2e6"
-                        stopOpacity="1"
-                    ></stop>
-                </linearGradient>
-                <circle id="path-1" cx="128" cy="128" r="128"></circle>
-                <linearGradient
-                    id="linearGradient-3"
-                    x1="-26.051"
-                    x2="254.316"
-                    y1="271.331"
-                    y2="0.048"
-                    gradientUnits="userSpaceOnUse"
-                >
-                    <stop
-                        id="stop10"
-                        offset="0%"
-                        stopColor="#4790bb"
-                        stopOpacity="1"
-                    ></stop>
-                    <stop
-                        id="stop12"
-                        offset="10.996%"
-                        stopColor="#64b7db"
-                        stopOpacity="1"
-                    ></stop>
-                    <stop
-                        id="stop14"
-                        offset="94.502%"
-                        stopColor="#326ea0"
-                        stopOpacity="1"
-                    ></stop>
-                </linearGradient>
-                <linearGradient
-                    id="linearGradient-4"
-                    x1="-32.163"
-                    x2="259.338"
-                    y1="277.029"
-                    y2="-5.028"
-                    gradientUnits="userSpaceOnUse"
-                >
-                    <stop id="stop17" offset="0%" stopColor="#F69923"></stop>
-                    <stop id="stop19" offset="8.048%" stopColor="#F79A23"></stop>
-                    <stop id="stop21" offset="41.874%" stopColor="#E97826"></stop>
-                </linearGradient>
-                <linearGradient
-                    id="linearGradient-5"
-                    x1="217.945"
-                    x2="99.459"
-                    y1="67.505"
-                    y2="247.005"
-                    gradientTransform="scale(.96442 1.0369)"
-                    gradientUnits="userSpaceOnUse"
-                    xlinkHref="#linearGradient-4"
-                >
-                    <stop
-                        id="stop24"
-                        offset="0%"
-                        stopColor="#92d6d5"
-                        stopOpacity="1"
-                    ></stop>
-                    <stop
-                        id="stop26"
-                        offset="41.191%"
-                        stopColor="#79b7cc"
-                        stopOpacity="1"
-                    ></stop>
-                    <stop
-                        id="stop28"
-                        offset="73.271%"
-                        stopColor="#5891c5"
-                        stopOpacity="1"
-                    ></stop>
-                </linearGradient>
-                <mask id="mask-2" fill="#fff">
-                    <use id="use33" xlinkHref="#path-1"></use>
-                </mask>
-                <mask id="mask-2-7" fill="#fff">
-                    <use id="use137" xlinkHref="#path-1"></use>
-                </mask>
-                <linearGradient
-                    id="linearGradient1345"
-                    x1="233.122"
-                    x2="2.24"
-                    y1="56.015"
-                    y2="242.78"
-                    gradientUnits="userSpaceOnUse"
-                    xlinkHref="#linearGradient1351"
-                ></linearGradient>
-            </defs>
-            <circle
-                id="circle38"
-                cx="127.994"
-                cy="127.994"
-                r="123.111"
-                fill="url(#linearGradient-3)"
-                fillRule="nonzero"
-                mask="url(#mask-2)"
-            ></circle>
-            <g id="g2266">
-                <path
-                    id="path42"
-                    fill="url(#linearGradient-5)"
-                    fillOpacity="1"
-                    fillRule="nonzero"
-                    d="M98.044 75.517c-1.751-.002-3.524.01-5.292.061-2.056.06-4.817.713-8 1.785 53.775 40.834 73.108 114.497 39.875 178.514 1.129.03 2.249.123 3.385.123 60.736 0 111.492-42.323 124.609-99.071-38.542-45.178-90.813-81.314-154.578-81.412z"
-                    mask="url(#mask-2)"
-                    opacity="0.75"
-                ></path>
-            </g>
-            <path
-                id="path44"
-                fill="#1e4b7b"
-                fillOpacity="1"
-                fillRule="nonzero"
-                d="M84.752 77.368C66.895 83.378 32.83 104.546.079 132.81c2.487 67.334 57.028 121.313 124.548 123.07 33.233-64.016 13.901-137.68-39.875-178.513z"
-                mask="url(#mask-2)"
-                opacity="0.75"
-            ></path>
-            <path
-                id="path150"
-                fill="url(#linearGradient1345)"
-                fillOpacity="1"
-                fillRule="nonzero"
-                d="M128.747 54.005c-10.985 5.495 0 27.466 0 27.466C95.774 108.954 102.78 155.9 64.312 155.9c-20.97 0-42.242-24.077-64.233-38.828-.283 3.479-.785 6.972-.785 10.524 0 48.095 26.263 89.924 65.42 111.897 10.952-1.38 22.838-4.114 31.05-9.592 43.146-28.765 53.857-83.491 71.487-109.925 10.979-16.492 62.434-15.061 65.906-22.01 5.502-10.991-10.99-27.467-16.491-27.467h-43.958c-3.071 0-7.897-5.456-10.974-5.456h-16.492s-7.307-11.085-13.794-11.526c-.93-.066-1.83.053-2.7.488z"
-                mask="url(#mask-2-7)"
-                transform="translate(-.769 -.133)"
-            ></path>
-            <path
-                id="path40"
-                fill="#2d4150"
-                fillOpacity="1"
-                fillRule="nonzero"
-                d="M128 256C57.308 256 0 198.692 0 128 0 57.308 57.308 0 128 0c70.692 0 128 57.308 128 128 0 70.692-57.308 128-128 128zm0-9.768c65.298 0 118.232-52.934 118.232-118.232S193.298 9.768 128 9.768 9.768 62.702 9.768 128 62.702 246.232 128 246.232z"
-                mask="url(#mask-2)"
-                transform="translate(-.59) scale(1.00078)"
-            ></path>
-        </svg>
-    );
-}
-
-export function CamelIcon(props?: (JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>) | undefined) {
-    return (<svg
-            xmlns="http://www.w3.org/2000/svg"
-            xmlnsXlink="http://www.w3.org/1999/xlink"
-            width={24}
-            height={24}
-            preserveAspectRatio="xMidYMid"
-            viewBox="0 0 256 256"
-            {...props}
-            className="icon">
-            <defs>
-                <linearGradient
-                    id="b"
-                    x1="-12.564%"
-                    x2="101.304%"
-                    y1="108.214%"
-                    y2="-1.964%"
-                >
-                    <stop offset="0%" stopColor="#F69923"/>
-                    <stop offset="10.996%" stopColor="#F79A23"/>
-                    <stop offset="94.502%" stopColor="#E97826"/>
-                </linearGradient>
-                <linearGradient
-                    id="d"
-                    x1="-12.564%"
-                    x2="101.304%"
-                    y1="108.214%"
-                    y2="-1.964%"
-                >
-                    <stop offset="0%" stopColor="#F69923"/>
-                    <stop offset="8.048%" stopColor="#F79A23"/>
-                    <stop offset="41.874%" stopColor="#E97826"/>
-                </linearGradient>
-                <linearGradient
-                    id="e"
-                    x1="74.724%"
-                    x2="6.653%"
-                    y1="-3.059%"
-                    y2="100.066%"
-                >
-                    <stop offset="0%" stopColor="#F6E423"/>
-                    <stop offset="41.191%" stopColor="#F79A23"/>
-                    <stop offset="73.271%" stopColor="#E97826"/>
-                </linearGradient>
-                <circle id="a" cx={128} cy={128} r={128}/>
-            </defs>
-            <mask id="c" fill="#fff">
-                <use xlinkHref="#a"/>
-            </mask>
-            <circle
-                cx={127.994}
-                cy={127.994}
-                r={123.111}
-                fill="url(#b)"
-                mask="url(#c)"
-            />
-            <path
-                fill="url(#d)"
-                d="M128 256C57.308 256 0 198.692 0 128 0 57.308 57.308 0 128 0c70.692 0 128 57.308 128 128 0 70.692-57.308 128-128 128Zm0-9.768c65.298 0 118.232-52.934 118.232-118.232S193.298 9.768 128 9.768 9.768 62.702 9.768 128 62.702 246.232 128 246.232Z"
-                mask="url(#c)"
-            />
-            <path
-                fill="url(#e)"
-                d="M98.044 75.517c-1.751-.002-3.524.01-5.292.061-2.056.06-4.817.713-8 1.785 53.775 40.834 73.108 114.497 39.875 178.514 1.129.03 2.249.123 3.385.123 60.736 0 111.492-42.323 124.609-99.071-38.542-45.178-90.813-81.314-154.578-81.412Z"
-                mask="url(#c)"
-                opacity={0.75}
-            />
-            <path
-                fill="#28170B"
-                d="M84.752 77.368C66.895 83.378 32.83 104.546.079 132.81c2.487 67.334 57.028 121.313 124.548 123.07 33.233-64.016 13.901-137.68-39.875-178.513Z"
-                mask="url(#c)"
-                opacity={0.75}
-            />
-            <path
-                fill="#FFF"
-                d="M128.747 54.005c-10.985 5.495 0 27.466 0 27.466C95.774 108.954 102.78 155.9 64.312 155.9c-20.97 0-42.242-24.077-64.233-38.828-.283 3.479-.785 6.972-.785 10.524 0 48.095 26.263 89.924 65.42 111.897 10.952-1.38 22.838-4.114 31.05-9.592 43.146-28.765 53.857-83.491 71.487-109.925 10.979-16.492 62.434-15.061 65.906-22.01 5.502-10.991-10.99-27.467-16.491-27.467h-43.958c-3.071 0-7.897-5.456-10.974-5.456h-16.492s-7.307-11.085-13.794-11.526c-.93-.066-1.83.053-2.7.488Z"
-                mask="url(#c)"
-            />
-        </svg>
-    );
-}
-
-export function getDesignerIcon(icon: string) {
-    if (icon === 'kamelet') return (
-        <svg
-            className="top-icon" id="icon"
-            xmlns="http://www.w3.org/2000/svg"
-            viewBox="0 0 32 32"
-        >
-            <title>{"application"}</title>
-            <path d="M16 18H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2ZM6 6v10h10V6ZM26 12v4h-4v-4h4m0-2h-4a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2v-4a2 2 0 0 0-2-2ZM26 22v4h-4v-4h4m0-2h-4a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2v-4a2 2 0 0 0-2-2ZM16 22v4h-4v-4h4m0-2h-4a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2v-4a2 2 0 0 0-2-2Z" />
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-        )
-    if (icon === 'code') return (
-        <svg
-
-            xmlns="http://www.w3.org/2000/svg"
-            width="24"
-            height="24"
-            fill="none"
-            viewBox="0 0 24 24"
-        >
-            <path
-                fill="#000000"
-                d="M8.502 5.387a.75.75 0 00-1.004-1.115L5.761 5.836c-.737.663-1.347 1.212-1.767 1.71-.44.525-.754 1.088-.754 1.784 0 .695.313 1.258.754 1.782.42.499 1.03 1.049 1.767 1.711l1.737 1.564a.75.75 0 101.004-1.115l-1.697-1.527c-.788-.709-1.319-1.19-1.663-1.598-.33-.393-.402-.622-.402-.817 0-.196.072-.425.402-.818.344-.409.875-.889 1.663-1.598l1.697-1.527zM14.18 4.275a.75.75 0 01.532.918l-3.987 15a.75.75 0 11-1.45-.386l3.987-15a.75.75 0 01.918-.532zM15.443 10.498a.75.75 0 011.059 [...]
-            ></path>
-        </svg>
-    )
-    if (icon === 'routes') return (
-        <svg className="top-icon" width="32px" height="32px" viewBox="0 0 32 32" id="icon">
-            <defs>
-                <style>{".cls-1{fill:none;}"}</style>
-            </defs>
-            <path
-                d="M29,10H24v2h5v6H22v2h3v2.142a4,4,0,1,0,2,0V20h2a2.0027,2.0027,0,0,0,2-2V12A2.0023,2.0023,0,0,0,29,10ZM28,26a2,2,0,1,1-2-2A2.0027,2.0027,0,0,1,28,26Z"/>
-            <path
-                d="M19,6H14V8h5v6H12v2h3v6.142a4,4,0,1,0,2,0V16h2a2.0023,2.0023,0,0,0,2-2V8A2.0023,2.0023,0,0,0,19,6ZM18,26a2,2,0,1,1-2-2A2.0027,2.0027,0,0,1,18,26Z"/>
-            <path
-                d="M9,2H3A2.002,2.002,0,0,0,1,4v6a2.002,2.002,0,0,0,2,2H5V22.142a4,4,0,1,0,2,0V12H9a2.002,2.002,0,0,0,2-2V4A2.002,2.002,0,0,0,9,2ZM8,26a2,2,0,1,1-2-2A2.0023,2.0023,0,0,1,8,26ZM3,10V4H9l.0015,6Z"/>
-            <rect id="_Transparent_Rectangle_" data-name="&lt;Transparent Rectangle&gt;" className="cls-1" width="32"
-                  height="32"/>
-        </svg>)
-    if (icon === 'route') return (
-        <svg className="top-icon" width="32px" height="32px" viewBox="0 0 32 32" id="icon">
-            <title>{"category"}</title>
-            <path d="M27 22.141V18a2 2 0 0 0-2-2h-8v-4h2a2.002 2.002 0 0 0 2-2V4a2.002 2.002 0 0 0-2-2h-6a2.002 2.002 0 0 0-2 2v6a2.002 2.002 0 0 0 2 2h2v4H7a2 2 0 0 0-2 2v4.142a4 4 0 1 0 2 0V18h8v4.142a4 4 0 1 0 2 0V18h8v4.141a4 4 0 1 0 2 0ZM13 4h6l.001 6H13ZM8 26a2 2 0 1 1-2-2 2.002 2.002 0 0 1 2 2Zm10 0a2 2 0 1 1-2-2 2.003 2.003 0 0 1 2 2Zm8 2a2 2 0 1 1 2-2 2.002 2.002 0 0 1-2 2Z" />
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    )
-    if (icon === 'rest') return (
-        <svg className="top-icon" viewBox="0 0 32 32" width="32px" height="32px">
-            <g className="layer">
-                <title>Layer 1</title>
-                <path
-                    d="m23.50007,22l-0.5,0l0,-2l0.5,0a4.4975,4.4975 0 0 0 0.3564,-8.981l-0.8154,-0.0639l-0.0986,-0.812a6.9938,6.9938 0 0 0 -13.8838,0l-0.0991,0.812l-0.8155,0.0639a4.4975,4.4975 0 0 0 0.356,8.981l0.5,0l0,2l-0.5,0a6.4973,6.4973 0 0 1 -1.3,-12.8638a8.9943,8.9943 0 0 1 17.6006,0a6.4974,6.4974 0 0 1 -1.3006,12.8638z"
-                    id="svg_1"/>
-                <path
-                    d="m22.9724,22.26637l0,-2l-2.1011,0a4.9678,4.9678 0 0 0 -0.7319,-1.7529l1.49,-1.49l-1.414,-1.414l-1.49,1.49a4.9678,4.9678 0 0 0 -1.753,-0.732l0,-2.1011l-2,0l0,2.1011a4.9678,4.9678 0 0 0 -1.7529,0.7319l-1.49,-1.49l-1.414,1.414l1.49,1.49a4.9678,4.9678 0 0 0 -0.732,1.753l-2.1011,0l0,2l2.1011,0a4.9678,4.9678 0 0 0 0.7319,1.7529l-1.49,1.49l1.414,1.414l1.49,-1.49a4.9678,4.9678 0 0 0 1.753,0.732l0,2.1011l2,0l0,-2.1011a4.9678,4.9678 0 0 0 1.7529,-0.7319l1.49,1.49l1.414,-1.414 [...]
-                    id="svg_2" transform="rotate(25 15.9724 21.2664)" xmlns="http://www.w3.org/2000/svg"/>
-            </g>
-        </svg>
-    )
-    if (icon === 'beans') return (
-        <svg className="top-icon" width="32px" height="32px" viewBox="0 0 32 32" id="icon">
-            <defs>
-                <style>{".cls-1 {fill: none;}"}</style>
-            </defs>
-            <title>data--1</title>
-            <rect x="15" y="6" width="13" height="2"/>
-            <rect x="15" y="24" width="13" height="2"/>
-            <rect x="4" y="15" width="13" height="2"/>
-            <path d="M7,11a4,4,0,1,1,4-4A4,4,0,0,1,7,11ZM7,5A2,2,0,1,0,9,7,2,2,0,0,0,7,5Z" transform="translate(0 0)"/>
-            <path d="M7,29a4,4,0,1,1,4-4A4,4,0,0,1,7,29Zm0-6a2,2,0,1,0,2,2A2,2,0,0,0,7,23Z" transform="translate(0 0)"/>
-            <path d="M25,20a4,4,0,1,1,4-4A4,4,0,0,1,25,20Zm0-6a2,2,0,1,0,2,2A2,2,0,0,0,25,14Z"
-                  transform="translate(0 0)"/>
-            <g id="_Transparent_Rectangle_" data-name="&lt;Transparent Rectangle&gt;">
-                <rect className="cls-1" width="32" height="32"/>
-            </g>
-        </svg>
-    )
-    if (icon === 'dependencies') return (
-        <svg className="top-icon" width="32px" height="32px" viewBox="0 0 32 32" id="icon">
-            <defs>
-                <style>{".cls-1 {fill: none;}"}</style>
-            </defs>
-            <title>application</title>
-            <path d="M16,18H6a2,2,0,0,1-2-2V6A2,2,0,0,1,6,4H16a2,2,0,0,1,2,2V16A2,2,0,0,1,16,18ZM6,6V16H16V6Z"
-                  transform="translate(0 0)"/>
-            <path d="M26,12v4H22V12h4m0-2H22a2,2,0,0,0-2,2v4a2,2,0,0,0,2,2h4a2,2,0,0,0,2-2V12a2,2,0,0,0-2-2Z"
-                  transform="translate(0 0)"/>
-            <path d="M26,22v4H22V22h4m0-2H22a2,2,0,0,0-2,2v4a2,2,0,0,0,2,2h4a2,2,0,0,0,2-2V22a2,2,0,0,0-2-2Z"
-                  transform="translate(0 0)"/>
-            <path d="M16,22v4H12V22h4m0-2H12a2,2,0,0,0-2,2v4a2,2,0,0,0,2,2h4a2,2,0,0,0,2-2V22a2,2,0,0,0-2-2Z"
-                  transform="translate(0 0)"/>
-            <g id="_Transparent_Rectangle_" data-name="&lt;Transparent Rectangle&gt;">
-                <rect className="cls-1" width="32" height="32"/>
-            </g>
-        </svg>
-    )
-    if (icon === 'error') return (
-        <svg className="top-icon" width="36px" height="36px" viewBox="0 0 36 36" version="1.1"
-             preserveAspectRatio="xMidYMid meet">
-            <circle className="clr-i-outline clr-i-outline-path-1" cx="18" cy="26.06" r="1.33"/>
-            <path className="clr-i-outline clr-i-outline-path-2"
-                  d="M18,22.61a1,1,0,0,1-1-1v-12a1,1,0,1,1,2,0v12A1,1,0,0,1,18,22.61Z"/>
-            <path className="clr-i-outline clr-i-outline-path-3"
-                  d="M18,34A16,16,0,1,1,34,18,16,16,0,0,1,18,34ZM18,4A14,14,0,1,0,32,18,14,14,0,0,0,18,4Z"/>
-            <rect x="0" y="0" width="36" height="36" fillOpacity="0"/>
-        </svg>)
-    if (icon === 'exception') return (
-        <svg className="top-icon" width="32px" height="32px" viewBox="0 0 32 32" id="icon">
-            <defs>
-                <style>{".cls-1{fill:none;}"}</style>
-            </defs>
-            <title>misuse--alt</title>
-            <polygon
-                points="21.41 23 16 17.591 10.59 23 9 21.41 14.409 16 9 10.591 10.591 9 16 14.409 21.409 9 23 10.591 17.591 16 23 21.41 21.41 23"/>
-            <path d="M16,4A12,12,0,1,1,4,16,12.0136,12.0136,0,0,1,16,4m0-2A14,14,0,1,0,30,16,14,14,0,0,0,16,2Z"
-                  transform="translate(0)"/>
-            <rect id="_Transparent_Rectangle_" data-name="&lt;Transparent Rectangle&gt;" className="cls-1" width="32"
-                  height="32"/>
-        </svg>)
-    if (icon === 'routeConfiguration') return (
-        <svg className="top-icon" width="32" height="32" viewBox="0 0 32 32">
-            <defs>
-                <style>{".cls-1{fill:none;}"}</style>
-            </defs>
-            <path
-                d="M28.83 21.17L25 17.37l.67-.67a1 1 0 000-1.41l-6-6a1 1 0 00-1.41 0l-.79.79-6.76-6.79a1 1 0 00-1.41 0l-4 4-.12.15-4 6a1 1 0 00.12 1.26l3 3a1 1 0 001.42 0L10 13.41l2.09 2.09-4.8 4.79a1 1 0 000 1.41l2 2a1 1 0 00.71.3 1 1 0 00.52-.15l4.33-2.6 2.44 2.45a1 1 0 001.41 0l.67-.7 3.79 3.83a4 4 0 005.66-5.66zM10 10.58l-5 5-1.71-1.71 3.49-5.24L10 5.41l6.09 6.09-2.59 2.58zm8 11l-2.84-2.84-5 3-.74-.74L19 11.41 23.59 16zm9.42 3.83a2 2 0 01-2.83 0l-3.8-3.79 2.83-2.83 3.8 3.79a2 2 0 010 [...]
-            <path
-                d="M0 0H32V32H0z"
-                className="cls-1"
-                data-name="&lt;Transparent Rectangle&gt;"
-            ></path>
-        </svg>)
-    if (icon === 'yaml') return (
-        <svg className="top-icon" x="0px" y="0px" width="32px" height="32px"
-             viewBox="0 0 32 32">
-            <style type="text/css">{".st0{fill:none;}"}</style>
-            <title>document</title>
-            <path
-                d="M25.7,9.3l-7-7C18.5,2.1,18.3,2,18,2H8C6.9,2,6,2.9,6,4v24c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V10C26,9.7,25.9,9.5,25.7,9.3  z M18,4.4l5.6,5.6H18V4.4z M24,28H8V4h8v6c0,1.1,0.9,2,2,2h6V28z"/>
-            <rect x="10" y="22" width="12" height="2"/>
-            <rect x="10" y="16" width="12" height="2"/>
-            <rect className="st0" width="32" height="32"/>
-        </svg>)
-    if (icon === 'code') return (
-        <svg className="top-icon" width="32px" height="32px" viewBox="0 0 32 32" id="icon">
-            <defs>
-                <style>{".cls-1{fill:none;}"}</style>
-            </defs>
-            <title>code</title>
-            <polygon points="31 16 24 23 22.59 21.59 28.17 16 22.59 10.41 24 9 31 16"/>
-            <polygon points="1 16 8 9 9.41 10.41 3.83 16 9.41 21.59 8 23 1 16"/>
-            <rect x="5.91" y="15" width="20.17" height="2" transform="translate(-3.6 27.31) rotate(-75)"/>
-            <rect id="_Transparent_Rectangle_" data-name="&lt;Transparent Rectangle&gt;" className="cls-1" width="32"
-                  height="32" transform="translate(0 32) rotate(-90)"/>
-        </svg>)
-}
-
-
-export class BeanIcon extends React.Component<any> {
-
-    render() {
-        return (
-            <svg className="icon" width="32px" height="32px" viewBox="0 0 32 32" id="icon">
-                <defs>
-                    <style>{".cls-1 {fill: none;}"}</style>
-                </defs>
-                <title>data--1</title>
-                <rect x="15" y="6" width="13" height="2"/>
-                <rect x="15" y="24" width="13" height="2"/>
-                <rect x="4" y="15" width="13" height="2"/>
-                <path d="M7,11a4,4,0,1,1,4-4A4,4,0,0,1,7,11ZM7,5A2,2,0,1,0,9,7,2,2,0,0,0,7,5Z"
-                      transform="translate(0 0)"/>
-                <path d="M7,29a4,4,0,1,1,4-4A4,4,0,0,1,7,29Zm0-6a2,2,0,1,0,2,2A2,2,0,0,0,7,23Z"
-                      transform="translate(0 0)"/>
-                <path d="M25,20a4,4,0,1,1,4-4A4,4,0,0,1,25,20Zm0-6a2,2,0,1,0,2,2A2,2,0,0,0,25,14Z"
-                      transform="translate(0 0)"/>
-                <g id="_Transparent_Rectangle_" data-name="&lt;Transparent Rectangle&gt;">
-                    <rect className="cls-1" width="32" height="32"/>
-                </g>
-            </svg>
-        )
-    }
-}
-
-export class DependencyIcon extends React.Component<any> {
-
-    render() {
-        return (
-            <svg className="icon" width="32px" height="32px" viewBox="0 0 32 32" id="icon">
-                <defs>
-                    <style>{".cls-1 {fill: none;}"}</style>
-                </defs>
-                <title>application</title>
-                <path d="M16,18H6a2,2,0,0,1-2-2V6A2,2,0,0,1,6,4H16a2,2,0,0,1,2,2V16A2,2,0,0,1,16,18ZM6,6V16H16V6Z"
-                      transform="translate(0 0)"/>
-                <path d="M26,12v4H22V12h4m0-2H22a2,2,0,0,0-2,2v4a2,2,0,0,0,2,2h4a2,2,0,0,0,2-2V12a2,2,0,0,0-2-2Z"
-                      transform="translate(0 0)"/>
-                <path d="M26,22v4H22V22h4m0-2H22a2,2,0,0,0-2,2v4a2,2,0,0,0,2,2h4a2,2,0,0,0,2-2V22a2,2,0,0,0-2-2Z"
-                      transform="translate(0 0)"/>
-                <path d="M16,22v4H12V22h4m0-2H12a2,2,0,0,0-2,2v4a2,2,0,0,0,2,2h4a2,2,0,0,0,2-2V22a2,2,0,0,0-2-2Z"
-                      transform="translate(0 0)"/>
-                <g id="_Transparent_Rectangle_" data-name="&lt;Transparent Rectangle&gt;">
-                    <rect className="cls-1" width="32" height="32"/>
-                </g>
-            </svg>
-        )
-    }
-}
-
-export class RestIcon extends React.Component<any> {
-
-    render() {
-        return (
-            <svg className="icon" viewBox="0 0 32 32">
-                <g className="layer">
-                    <title>Layer 1</title>
-                    <path
-                        d="m23.50007,22l-0.5,0l0,-2l0.5,0a4.4975,4.4975 0 0 0 0.3564,-8.981l-0.8154,-0.0639l-0.0986,-0.812a6.9938,6.9938 0 0 0 -13.8838,0l-0.0991,0.812l-0.8155,0.0639a4.4975,4.4975 0 0 0 0.356,8.981l0.5,0l0,2l-0.5,0a6.4973,6.4973 0 0 1 -1.3,-12.8638a8.9943,8.9943 0 0 1 17.6006,0a6.4974,6.4974 0 0 1 -1.3006,12.8638z"
-                        id="svg_1"/>
-                    <path
-                        d="m22.9724,22.26637l0,-2l-2.1011,0a4.9678,4.9678 0 0 0 -0.7319,-1.7529l1.49,-1.49l-1.414,-1.414l-1.49,1.49a4.9678,4.9678 0 0 0 -1.753,-0.732l0,-2.1011l-2,0l0,2.1011a4.9678,4.9678 0 0 0 -1.7529,0.7319l-1.49,-1.49l-1.414,1.414l1.49,1.49a4.9678,4.9678 0 0 0 -0.732,1.753l-2.1011,0l0,2l2.1011,0a4.9678,4.9678 0 0 0 0.7319,1.7529l-1.49,1.49l1.414,1.414l1.49,-1.49a4.9678,4.9678 0 0 0 1.753,0.732l0,2.1011l2,0l0,-2.1011a4.9678,4.9678 0 0 0 1.7529,-0.7319l1.49,1.49l1.414,-1 [...]
-                        id="svg_2" transform="rotate(25 15.9724 21.2664)" xmlns="http://www.w3.org/2000/svg"/>
-                </g>
-            </svg>
-        )
-    }
-}
-
-export class ConceptIcon extends React.Component<any> {
-
-    render() {
-        return (
-            <svg className="icon" width="32px" height="32px" viewBox="0 0 32 32">
-                <defs>
-                    <style>{".cls-1 {fill: none;}"}</style>
-                </defs>
-                <title>concept</title>
-                <path
-                    d="M20.8851,19.4711a5.9609,5.9609,0,0,0,0-6.9422L23,10.4141l1.293,1.2929a.9995.9995,0,0,0,1.414,0l4-4a.9994.9994,0,0,0,0-1.414l-4-4a.9994.9994,0,0,0-1.414,0l-4,4a.9994.9994,0,0,0,0,1.414L21.5859,9l-2.1148,2.1149a5.9609,5.9609,0,0,0-6.9422,0L10,8.5859V2H2v8H8.5859l2.529,2.5289a5.9609,5.9609,0,0,0,0,6.9422L9,21.5859,7.707,20.293a.9994.9994,0,0,0-1.414,0l-4,4a.9994.9994,0,0,0,0,1.414l4,4a.9995.9995,0,0,0,1.414,0l4-4a.9994.9994,0,0,0,0-1.414L10.4141,23l2.1148-2.1149a5.960 [...]
-                <rect id="_Transparent_Rectangle_" data-name="&lt;Transparent Rectangle&gt;" className="cls-1"
-                      width="32" height="32"/>
-            </svg>
-        )
-    }
-}
-
-export function AggregateIcon() {
-    return (
-        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 700" className="icon">
-            <path
-                d="M496.2 417.71l-130.22 101.1c-.19.14-.39.29-.59.42a28.39 28.39 0 01-30.77 0c-.21-.13-.4-.28-.59-.42L203.8 417.71h292.4z"></path>
-            <path
-                d="M516.1 426.23v202.1c0 4.12-3.34 7.46-7.45 7.46H191.36c-4.11 0-7.46-3.34-7.46-7.46V426.22l138.52 107.53c.68.53 1.31.98 1.94 1.38 7.79 5.04 16.72 7.55 25.66 7.55s17.86-2.52 25.66-7.55c.62-.4 1.25-.85 1.94-1.38l138.5-107.52zM247.14 358.45l-12.91 30.22-.03.06v.03c-.11.21-.21.43-.32.64s-.23.42-.36.61c-.08.14-.17.27-.27.4-.08.11-.16.21-.24.31-.1.13-.21.25-.31.36-.08.09-.16.18-.24.25-.05.06-.1.11-.16.15l-.27.25c-.17.15-.33.29-.51.42-.15.13-.3.23-.47.33-.19.13-.39.25-.59.36s-. [...]
-            <path
-                d="M277.46 154.15V264.2c0 5.52-4.48 10-10 10H82.69c-5.52 0-10-4.48-10-10V154.14l82.79 62.29c5.77 4.34 12.69 6.51 19.6 6.51s13.83-2.17 19.6-6.51l82.78-62.28z"></path>
-            <g>
-                <path d="M610.57 145.6l-76.07 57.24c-5.52 4.16-13.24 4.16-18.76 0l-76.08-57.24h170.91z"></path>
-                <path
-                    d="M627.5 154.15V264.2c0 5.52-4.48 10-10 10H432.73c-5.52 0-10-4.48-10-10V154.14l82.79 62.29c5.77 4.34 12.69 6.51 19.6 6.51s13.83-2.17 19.6-6.51l82.78-62.28z"></path>
-            </g>
-        </svg>
-    );
-}
-
-export function ToIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon"
-        >
-            <path
-                d="M24 22v-1h6v-2h-6v-6h6v-2h-6v-1a2 2 0 0 0-2-2h-6a8.007 8.007 0 0 0-7.93 7v2A8.007 8.007 0 0 0 16 24h6a2 2 0 0 0 2-2zm-8 0a6 6 0 1 1 0-12h6v12z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function ChoiceIcon() {
-    return (
-        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 700" className="icon">
-            <path
-                d="M407.33 113.97V609.2c0 2.75-1.9 5-4.22 5H291.55c-2.33 0-4.22-2.25-4.22-5V113.97c0-2.76 1.89-5 4.22-5h111.56c2.32 0 4.22 2.24 4.22 5zM27.1 437.55l60.87-57.64c.95-.9 2.32-1.41 3.76-1.41H258.2c2.76 0 5 1.87 5 4.17v111.65c0 2.3-2.24 4.17-5 4.17H91.54c-1.38 0-2.7-.48-3.65-1.32L27.2 443.15c-1.77-1.58-1.81-3.99-.1-5.61zM667.57 285.62l-60.87 57.64c-.95.9-2.32 1.41-3.76 1.41H436.47c-2.76 0-5-1.87-5-4.17V228.85c0-2.3 2.24-4.17 5-4.17h166.66c1.38 0 2.7.48 3.65 1.32l60.69 54.02c1. [...]
-        </svg>
-    );
-}
-
-
-export function SplitIcon() {
-    return (
-        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 700" className="icon">
-            <path
-                d="M496.2 83.65l-130.22 101.1c-.19.14-.39.29-.59.42a28.39 28.39 0 01-30.77 0c-.21-.13-.4-.28-.59-.42L203.8 83.65h292.4z"></path>
-            <path
-                d="M516.1 92.17v202.1c0 4.12-3.34 7.46-7.45 7.46H191.36c-4.11 0-7.46-3.34-7.46-7.46V92.16l138.52 107.53c.68.53 1.31.98 1.94 1.38 7.79 5.04 16.72 7.55 25.66 7.55s17.86-2.52 25.66-7.55c.62-.4 1.25-.85 1.94-1.38l138.5-107.52zM524.34 397.22l-12.91 30.22-.03.06v.03c-.11.21-.21.43-.32.64s-.23.42-.36.61c-.08.14-.17.27-.27.4-.08.11-.16.21-.24.31-.1.13-.21.25-.31.36-.08.09-.16.18-.24.25-.05.06-.1.11-.16.15l-.27.25c-.17.15-.33.29-.51.42-.15.13-.3.23-.47.33-.19.13-.39.25-.59.36s-.42 [...]
-            <path
-                d="M277.36 476.26v110.05c0 5.52-4.48 10-10 10H82.59c-5.52 0-10-4.48-10-10V476.25l82.79 62.29c5.77 4.34 12.69 6.51 19.6 6.51s13.83-2.17 19.6-6.51l82.78-62.28z"></path>
-            <g>
-                <path d="M610.48 467.71l-76.07 57.24c-5.52 4.16-13.24 4.16-18.76 0l-76.08-57.24h170.91z"></path>
-                <path
-                    d="M627.41 476.26v110.05c0 5.52-4.48 10-10 10H432.64c-5.52 0-10-4.48-10-10V476.25l82.79 62.29c5.77 4.34 12.69 6.51 19.6 6.51s13.83-2.17 19.6-6.51l82.78-62.28z"></path>
-            </g>
-        </svg>
-    );
-}
-
-export function SagaIcon() {
-    return (
-        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 700" className="icon">
-            <path
-                d="M626.41 255.77c-.56-4.77-2.95-9.03-6.71-11.99l-46.46-36.64-1.06-1.09-.8-.28c-.81-.52-1.67-.98-2.56-1.36-.43-.19-.85-.36-1.25-.5-.47-.16-.96-.31-1.51-.45-.47-.11-.96-.22-1.45-.3-.49-.08-.97-.14-1.43-.18-.96-.08-1.95-.08-2.91-.01-.41.03-.83.08-1.23.14-.41.06-.82.14-1.25.23l-.58.14c-.1.03-.2.05-.31.08-.11.03-.21.06-.3.09-.29.08-.57.18-.86.28-.49.17-.99.37-1.53.61l-.16.08c-.32.15-.65.31-.97.49-.49.26-.93.53-1.34.81-.39.26-.76.52-1.12.8l-46.96 37.05a17.823 17.823 0 00-6.72  [...]
-        </svg>
-    );
-}
-
-export function TransformIcon() {
-    return (
-        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 700" className="icon">
-            <path
-                d="M441.77 277.51l-82.73 64.23c-.07.05-.13.09-.19.13-5.37 3.48-12.33 3.48-17.69.01-.07-.05-.13-.09-.18-.13l-82.76-64.24h183.54z"></path>
-            <path
-                d="M462.2 287.02V420.7c0 .98-.79 1.77-1.77 1.77H239.57c-.98 0-1.77-.79-1.77-1.77V287.02l90.91 70.56c.54.44 1.06.8 1.57 1.12 5.99 3.88 12.86 5.81 19.72 5.81s13.73-1.94 19.73-5.81c.49-.32 1.01-.68 1.58-1.13l90.89-70.55zM622.28 330.68l-35.89 31.78a1.48 1.48 0 01-1.98 0l-35.89-31.78c-.3-.26-.48-.63-.51-1.03-.02-.4.11-.79.38-1.09l11.28-12.73c.55-.61 1.49-.67 2.11-.12l12.44 11.02c-5.24-51.26-28.18-99.47-64.84-136.12-35.82-35.82-81.13-58.05-131.04-64.27-.1 0-.19-.03-.28-.06v.09s [...]
-        </svg>
-    );
-}
-
-export function FilterIcon() {
-    return (
-        <svg xmlns="http://www.w3.org/2000/svg" id="a" viewBox="0 0 700 700" className="icon">
-            <path
-                d="M565.62 156.56L413.36 350.33a10.032 10.032 0 00-2.14 6.18v190.52c0 19.05-25.01 34.49-55.86 34.49s-55.86-15.44-55.86-34.49V356.51c0-2.24-.75-4.42-2.14-6.18L145.1 156.56c-5.15-6.56-.48-16.18 7.87-16.18h404.79c8.34 0 13.02 9.62 7.86 16.18z"></path>
-        </svg>
-    );
-}
-
-export function SortIcon() {
-    return (
-        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 700" className="icon">
-            <defs>
-                <style>{".b{stroke-linejoin: round;}.b,.c {stroke-linecap: round;}.b,.c,.d {fill: none;stroke: #000;stroke-width: 35px;}.c,.d {stroke-miterlimit: 10;}"}</style>
-            </defs>
-            <path d="M160.63 168.63L160.63 531.37" className="d"></path>
-            <path d="M576.31 170.27L269.3 170.27" className="c"></path>
-            <path d="M517.53 290.64L269.3 290.64" className="c"></path>
-            <path d="M458.75 411L269.3 411" className="c"></path>
-            <path d="M399.97 531.37L269.3 531.37" className="c"></path>
-            <path d="M197.7 197.95L160.63 168.71 123.55 197.95" className="b"></path>
-            <path d="M123.55 502.12L160.62 531.37 197.7 502.12" className="b"></path>
-        </svg>
-    );
-}
-
-export function OnCompletion() {
-    return (
-        <svg
-            className="icon" width="32px" height="32px"
-            xmlns="http://www.w3.org/2000/svg"
-            id="icon"
-            fill="#000"
-            viewBox="0 0 32 32"
-        >
-            <defs>
-                <style>{".cls-1 { fill: none; }"}</style>
-            </defs>
-            <path d="M22 26.59L19.41 24 18 25.41 22 29.41 30 21.41 28.59 20 22 26.59z"></path>
-            <circle cx="16" cy="16" r="2"></circle>
-            <path d="M16 22a6 6 0 116-6 6.007 6.007 0 01-6 6zm0-10a4 4 0 104 4 4.005 4.005 0 00-4-4z"></path>
-            <path d="M28 16a12 12 0 10-12 12v-2a10 10 0 1110-10z"></path>
-            <path
-                id="_Transparent_Rectangle_"
-                d="M0 0H32V32H0z"
-                className="cls-1"
-                data-name="&lt;Transparent Rectangle&gt;"
-            ></path>
-        </svg>
-    );
-}
-
-export function Intercept() {
-    return (
-        <svg
-            className="icon" width="32px" height="32px"
-            xmlns="http://www.w3.org/2000/svg"
-            id="icon"
-            fill="#000"
-            viewBox="0 0 32 32"
-        >
-            <defs>
-                <style>{".cls-1 {    fill: none; }"}</style>
-            </defs>
-            <path d="M15 4H17V28H15z"></path>
-            <path
-                d="M10 7v18H4V7h6m0-2H4a2 2 0 00-2 2v18a2 2 0 002 2h6a2 2 0 002-2V7a2 2 0 00-2-2zM28 7v18h-6V7h6m0-2h-6a2 2 0 00-2 2v18a2 2 0 002 2h6a2 2 0 002-2V7a2 2 0 00-2-2z"></path>
-            <path
-                id="_Transparent_Rectangle_"
-                d="M0 0H32V32H0z"
-                className="cls-1"
-                data-name="&lt;Transparent Rectangle&gt;"
-            ></path>
-        </svg>
-    );
-}
-
-export function InterceptFrom() {
-    return (
-        <svg
-            className="icon" width="32px" height="32px"
-            xmlns="http://www.w3.org/2000/svg"
-            id="icon"
-            fill="#000"
-            viewBox="0 0 32 32"
-        >
-            <defs>
-                <style>{".cls-1 {    fill: none; }"}</style>
-            </defs>
-            <path d="M26 30H14a2 2 0 01-2-2v-3h2v3h12V4H14v3h-2V4a2 2 0 012-2h12a2 2 0 012 2v24a2 2 0 01-2 2z"></path>
-            <path d="M14.59 20.59L18.17 17 4 17 4 15 18.17 15 14.59 11.41 16 10 22 16 16 22 14.59 20.59z"></path>
-            <path
-                id="_Transparent_Rectangle_"
-                d="M0 0H32V32H0z"
-                className="cls-1"
-                data-name="&lt;Transparent Rectangle&gt;"
-            ></path>
-        </svg>
-    );
-}
-
-export function InterceptSendToEndpoint() {
-    return (
-        <svg
-            className="icon" width="32px" height="32px"
-            xmlns="http://www.w3.org/2000/svg"
-            id="icon"
-            fill="#000"
-            viewBox="0 0 32 32"
-        >
-            <defs>
-                <style>{".cls-1 {    fill: none; }"}</style>
-            </defs>
-            <path
-                d="M6 30h12a2.002 2.002 0 002-2v-3h-2v3H6V4h12v3h2V4a2.002 2.002 0 00-2-2H6a2.002 2.002 0 00-2 2v24a2.002 2.002 0 002 2z"></path>
-            <path
-                d="M20.586 20.586L24.172 17 10 17 10 15 24.172 15 20.586 11.414 22 10 28 16 22 22 20.586 20.586z"></path>
-            <path
-                id="_Transparent_Rectangle_"
-                d="M0 0H32V32H0z"
-                className="cls-1"
-                data-name="&lt;Transparent Rectangle&gt;"
-            ></path>
-        </svg>
-    );
-}
-
-
-export function SpringIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width="24"
-            height="24"
-            viewBox="0 0 32 32"
-            className="icon">
-            <g fill="none" fillRule="evenodd">
-                <path d="M0 0h32v32H0z"></path>
-                <path
-                    fill="#70AD51"
-                    d="M5.466 27.993a1.364 1.364 0 10-.087-.076l-.266-.234C1.972 24.762 0 20.597 0 15.978 0 7.168 7.168 0 15.98 0c4.48 0 8.53 1.857 11.435 4.836a14.681 14.681 0 001.7-3.015c2.036 6.118 3.233 11.26 2.795 15.31-.592 8.274-7.508 14.83-15.93 14.83a15.903 15.903 0 01-10.276-3.757l-.238-.21zm23.58-4.982c4.01-5.336 1.775-13.965-.085-19.48-1.657 3.453-5.738 6.094-9.262 6.93-3.303.788-6.226.142-9.283 1.318-6.97 2.68-6.86 10.992-3.02 12.86.002 0 .23.124.227.12 0-.002 5.644-1.122 8. [...]
-                ></path>
-            </g>
-        </svg>
-    );
-}
-
-export function QuarkusIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width="24"
-            height="24"
-            preserveAspectRatio="xMidYMid"
-            viewBox="-0.5 0 257 257"
-            className="icon">
-            <path
-                fill="#4695EB"
-                d="M213.554 0c23.418.08 42.377 19.052 42.443 42.47v171.084c-.066 23.428-19.042 42.404-42.47 42.47h-25.439l-11.661-28.318h37.127c7.774-.1 14.051-6.378 14.152-14.152V42.47c-.1-7.774-6.378-14.051-14.152-14.152H42.47c-7.774.1-14.051 6.378-14.152 14.152v171.084c.1 7.774 6.378 14.051 14.152 14.152h62.607l22.935-48.494 31.625 76.812H42.47C19.042 255.958.066 236.982 0 213.554V42.47C.066 19.042 19.042.066 42.47 0h171.084zm-43.983 139.727v45.51l-39.417-22.748 39.417-22.762zM86.453  [...]
-            ></path>
-            <path
-                fill="#FF004A"
-                d="M86.453 139.727l39.417 22.762-39.417 22.748v-45.51zm83.118-45.509l39.418 22.748-39.418 22.761V94.218zM88.595 44.987l39.417 22.748-39.417 22.761V44.987z"
-            ></path>
-            <path
-                fill="#091313"
-                d="M86.453 94.218l39.417 22.748v45.523l-39.417-22.762V94.218zm83.118 0v45.51l-39.417 22.76v-45.522l39.417-22.748zm-41.559-26.483l39.417 22.761-39.417 22.761-39.417-22.76 39.417-22.762z"
-            ></path>
-        </svg>
-    );
-}
-
-export function DatabaseIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width="800"
-            height="800"
-            viewBox="0 0 24 24"
-            className="icon">
-            <path
-                fillRule="evenodd"
-                d="M12 1.25c-2.487 0-4.774.402-6.466 1.079-.844.337-1.577.758-2.112 1.264C2.886 4.1 2.5 4.744 2.5 5.5v12.987l.026.013H2.5c0 .756.386 1.4.922 1.907.535.506 1.268.927 2.112 1.264 1.692.677 3.979 1.079 6.466 1.079s4.773-.402 6.466-1.079c.844-.337 1.577-.758 2.112-1.264.536-.507.922-1.151.922-1.907h-.026l.026-.013V5.5c0-.756-.386-1.4-.922-1.907-.535-.506-1.268-.927-2.112-1.264C16.773 1.652 14.487 1.25 12 1.25zM4 5.5c0-.21.104-.487.453-.817.35-.332.899-.666 1.638-.962C7.566 3. [...]
-            ></path>
-        </svg>
-    );
-}
-
-export function CloudIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <path
-                d="M16 7a7.66 7.66 0 0 1 1.51.15 8 8 0 0 1 6.35 6.34l.26 1.35 1.35.24a5.5 5.5 0 0 1-1 10.92H7.5a5.5 5.5 0 0 1-1-10.92l1.34-.24.26-1.35A8 8 0 0 1 16 7m0-2a10 10 0 0 0-9.83 8.12A7.5 7.5 0 0 0 7.49 28h17a7.5 7.5 0 0 0 1.32-14.88 10 10 0 0 0-7.94-7.94A10.27 10.27 0 0 0 16 5Z"/>
-            <path
-                d="M0 0h32v32H0z"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function FileIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            xmlSpace="preserve"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <title>{"document"}</title>
-            <path
-                d="m25.7 9.3-7-7c-.2-.2-.4-.3-.7-.3H8c-1.1 0-2 .9-2 2v24c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V10c0-.3-.1-.5-.3-.7zM18 4.4l5.6 5.6H18V4.4zM24 28H8V4h8v6c0 1.1.9 2 2 2h6v16z"/>
-            <path d="M10 22h12v2H10zM10 16h12v2H10z"/>
-            <path
-                d="M0 0h32v32H0z"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function MessagingIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <path d="M28 28H4a2.002 2.002 0 0 1-2-2v-5h2v5h24v-5h2v5a2.002 2.002 0 0 1-2 2Z"/>
-            <path d="M7 21h18v2H7zM7 16h18v2H7zM7 11h18v2H7zM7 6h18v2H7z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function SchedulingIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <path d="M16 30a14 14 0 1 1 14-14 14 14 0 0 1-14 14Zm0-26a12 12 0 1 0 12 12A12 12 0 0 0 16 4Z"/>
-            <path d="M20.59 22 15 16.41V7h2v8.58l5 5.01L20.59 22z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function HttpIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <path
-                d="M30 11h-5v10h2v-3h3a2.003 2.003 0 0 0 2-2v-3a2.002 2.002 0 0 0-2-2Zm-3 5v-3h3l.001 3ZM10 13h2v8h2v-8h2v-2h-6v2zM23 11h-6v2h2v8h2v-8h2v-2zM6 11v4H3v-4H1v10h2v-4h3v4h2V11H6z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function GoogleCloudIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            preserveAspectRatio="xMidYMid"
-            viewBox="0 -25 256 256"
-            className="icon">
-            <path
-                fill="#EA4335"
-                d="m170.252 56.819 22.253-22.253 1.483-9.37C153.437-11.677 88.976-7.496 52.42 33.92 42.267 45.423 34.734 59.764 30.717 74.573l7.97-1.123 44.505-7.34 3.436-3.513c19.797-21.742 53.27-24.667 76.128-6.168l7.496.39Z"
-            />
-            <path
-                fill="#4285F4"
-                d="M224.205 73.918a100.249 100.249 0 0 0-30.217-48.722l-31.232 31.232a55.515 55.515 0 0 1 20.379 44.037v5.544c15.35 0 27.797 12.445 27.797 27.796 0 15.352-12.446 27.485-27.797 27.485h-55.671l-5.466 5.934v33.34l5.466 5.231h55.67c39.93.311 72.553-31.494 72.864-71.424a72.303 72.303 0 0 0-31.793-60.453"
-            />
-            <path
-                fill="#34A853"
-                d="M71.87 205.796h55.593V161.29H71.87a27.275 27.275 0 0 1-11.399-2.498l-7.887 2.42-22.409 22.253-1.952 7.574c12.567 9.489 27.9 14.825 43.647 14.757"
-            />
-            <path
-                fill="#FBBC05"
-                d="M71.87 61.425C31.94 61.664-.237 94.228.001 134.159a72.301 72.301 0 0 0 28.222 56.88l32.248-32.246c-13.99-6.322-20.208-22.786-13.887-36.776 6.32-13.99 22.786-20.208 36.775-13.888a27.796 27.796 0 0 1 13.887 13.888l32.248-32.248A72.224 72.224 0 0 0 71.87 61.425"
-            />
-        </svg>
-    );
-}
-
-export function AwsIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            fill="none"
-            viewBox="0 0 16 16"
-            className="icon">
-            <path
-                fill="#252F3E"
-                d="M4.51 7.687c0 .197.02.357.058.475.042.117.096.245.17.384a.233.233 0 0 1 .037.123c0 .053-.032.107-.1.16l-.336.224a.255.255 0 0 1-.138.048c-.054 0-.107-.026-.16-.074a1.652 1.652 0 0 1-.192-.251 4.137 4.137 0 0 1-.165-.315c-.415.491-.936.737-1.564.737-.447 0-.804-.129-1.064-.385-.261-.256-.394-.598-.394-1.025 0-.454.16-.822.484-1.1.325-.278.756-.416 1.304-.416.18 0 .367.016.564.042.197.027.4.07.612.118v-.39c0-.406-.085-.689-.25-.854-.17-.166-.458-.246-.868-.246-.186 0-.37 [...]
-            />
-            <g fill="#F90" fillRule="evenodd" clipRule="evenodd">
-                <path
-                    d="M14.465 11.813c-1.75 1.297-4.294 1.986-6.481 1.986-3.065 0-5.827-1.137-7.913-3.027-.165-.15-.016-.353.18-.235 2.257 1.313 5.04 2.109 7.92 2.109 1.941 0 4.075-.406 6.039-1.239.293-.133.543.192.255.406z"/>
-                <path
-                    d="M15.194 10.98c-.223-.287-1.479-.138-2.048-.069-.17.022-.197-.128-.043-.24 1-.705 2.645-.502 2.836-.267.192.24-.053 1.89-.99 2.68-.143.123-.281.06-.218-.1.213-.53.687-1.72.463-2.003z"/>
-            </g>
-        </svg>
-    );
-}
-
-export function MailIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <title>{"email"}</title>
-            <path
-                d="M28 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2Zm-2.2 2L16 14.78 6.2 8ZM4 24V8.91l11.43 7.91a1 1 0 0 0 1.14 0L28 8.91V24Z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function IotIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <title>{"iot--platform"}</title>
-            <path
-                d="M30 19h-4v-4h-2v9H8V8h9V6h-4V2h-2v4H8a2.002 2.002 0 0 0-2 2v3H2v2h4v6H2v2h4v3a2.002 2.002 0 0 0 2 2h3v4h2v-4h6v4h2v-4h3a2.003 2.003 0 0 0 2-2v-3h4Z"/>
-            <path d="M21 21H11V11h10Zm-8-2h6v-6h-6ZM31 13h-2A10.012 10.012 0 0 0 19 3V1a12.013 12.013 0 0 1 12 12Z"/>
-            <path d="M26 13h-2a5.006 5.006 0 0 0-5-5V6a7.008 7.008 0 0 1 7 7Z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function GithubIcon() {
-    return (
-        <svg
-            width={32}
-            height={32}
-            aria-hidden="true"
-            data-view-component="true"
-            viewBox="0 0 16 16"
-            className="icon">
-            <path
-                d="M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45 [...]
-        </svg>
-    );
-}
-
-export function CassandraIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            xmlnsXlink="http://www.w3.org/1999/xlink"
-            width={113.636}
-            height={58.899}
-            viewBox="0 0 113.63554 58.899029"
-            className="icon">
-            <defs>
-                <path id="a" d="M24.216.082v24.141H.053V.082z"/>
-            </defs>
-            <g
-                style={{
-                    fill: "none",
-                    fillRule: "evenodd",
-                    stroke: "none",
-                    strokeWidth: 1,
-                }}
-            >
-                <path
-                    fill="#bbe6fb"
-                    d="M90.565 20.787C91.4 30.202 76.112 39.163 56.422 40.8c-19.69 1.638-36.329-4.669-37.162-14.083C18.426 17.3 33.713 8.34 53.404 6.702c19.69-1.636 36.329 4.669 37.161 14.085"
-                />
-                <path
-                    fill="#fff"
-                    d="M53.334 6.75c-4.16-.255-11.326 1.915-17.302 4.08a17.762 17.762 0 0 0-1.413 6.948c0 10.096 9.154 18.28 18.837 18.28 9.62 0 18.13-8.197 18.836-18.28.23-3.283-.9-6.377-2.47-9.044-6.196-1.091-12.771-1.758-16.488-1.984"
-                />
-                <image
-                    xlinkHref="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUwAAADqCAYAAADJXHwYAAAABGdBTUEAALGOfPtRkwAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAABTKADAAQAAAABAAAA6gAAAAAGjBs3AAAWs0lEQVR4Ae2d+dPctAGG+SABQkI5AyFQ7hZaekA7nbbT0v7J/bkz7bRQGGDKGaCcIRAg5CBAIBchJH3fjfxh79q78q4P2X40o3hty7b02N8T2ZLlrasIEGiIwOXLl7e0qxtCvF7Ta0K8Ovc7W1Y2XZbO6y4pXlT8Pkzzv7Nl2bTuuotbW1uXtV8CBCoJ+AInQCCKgIR4rRJaiLvDNP/by3YpDvmamhdyJt9sWiZhL3P8NsTzYXoBAYvEyMKQL+6RnYp+i5O [...]
-                    width={43.164}
-                    height={31.532}
-                    x={31.672}
-                    y={6.587}
-                    opacity={0.596}
-                />
-                <path
-                    fill="#373535"
-                    d="M42.663 16.453c.51-1.13 1.282-1.683 2.031-2.63-.083-.224-.265-.958-.265-1.212 0-1.128.928-2.056 2.056-2.056.26 0 .517.05.758.146a14.985 14.985 0 0 1 13.597-2.39c-4.45-.617-9.466.96-12.878 3.713.104.246.393.949.393 1.232 0 1.135-.735 1.411-1.87 1.411-.258 0-.504-.05-.732-.136-.771 1.035-1.715 3.006-2.178 4.239 1.887 1.687 3.592 2.299 5.813 3.13-.006-.106.076-.205.076-.312 0-3.424 3.014-6.206 6.438-6.206a6.195 6.195 0 0 1 6.105 5.158c1.53-.974 3.01-1.72 4.139-3.164-. [...]
-                />
-                <path
-                    fill="#373535"
-                    d="M68.25 14.909c.303.265.555.58.748.932.502.9-.503 1.724-1.533 1.724a1.846 1.846 0 0 1-.306-.031c-1.161 1.814-3.194 4.14-5 5.311 2.769.454 5.38 1.563 7.46 3.277 1.513-2.711 2.673-6.627 2.673-9.953 0-2.532-1.117-4.387-2.804-5.748-.089 1.356-.813 3.252-1.236 4.488M45.77 32.084c.922-2.549 3.192-4.524 5.34-6.26-.315-.43-.786-1.496-.982-2a15.027 15.027 0 0 1-6.733-4.261l-.044.17a13.62 13.62 0 0 0-.232 4.52 2.709 2.709 0 0 1 2.203 2.654c0 .783-.687 1.92-1.22 2.414.58 1.25. [...]
-                />
-                <path
-                    fill="#373535"
-                    d="M45.607 34.222c-1.1-1.094-1.862-3.277-2.576-4.648a2.707 2.707 0 0 1-.41.035c-1.494 0-3.058-1.253-2.704-2.702.196-.803.75-1.327 1.652-1.765-.206-1.662-.261-4.051.124-5.78.111-.494.345-.726.5-1.196-1.647-2.41-2.711-5.574-2.711-8.713 0-.115.005-.228.008-.342-2.783 1.396-4.87 3.595-4.87 7.058 0 7.659 4.41 15.171 10.973 18.116l.014-.062m16.138-10.588a6.196 6.196 0 0 1-5.843 4.145 6.167 6.167 0 0 1-3.826-1.327c-2.173 1.692-4.143 4.664-5.145 7.242.45.484.763.882 1.267 1.3 [...]
-                />
-                <path
-                    fill="#1287b1"
-                    d="M42.493 17.348a14.975 14.975 0 0 1 1.898-3.122 2.057 2.057 0 0 1-.132-.72c0-1.127.929-2.056 2.056-2.056.26 0 .517.05.758.147A14.985 14.985 0 0 1 59.46 8.879c.407.093.811.202 1.21.328-4.45-.617-9.048.747-12.46 3.5.107.253.162.525.162.799a2.066 2.066 0 0 1-2.056 2.056 2.05 2.05 0 0 1-.733-.136 13.841 13.841 0 0 0-1.863 3.412c1.62 1.746 3.61 3.127 5.83 3.957-.005-.106-.016-.21-.016-.319a6.195 6.195 0 0 1 12.303-1.04 16.065 16.065 0 0 0 4.019-3.669 1.843 1.843 0 0 1-.4 [...]
-                />
-                <path
-                    fill="#1287b1"
-                    d="M68.54 15.214c.394.35.62.852.622 1.38a1.876 1.876 0 0 1-1.866 1.866 1.85 1.85 0 0 1-.307-.032 15.102 15.102 0 0 1-4.506 4.533 15.09 15.09 0 0 1 7.261 3.263 18.739 18.739 0 0 0 2.379-9.16c0-2.532-1.118-4.387-2.805-5.748a15.01 15.01 0 0 1-.778 3.898M46.054 32.696a15.04 15.04 0 0 1 4.674-6.572 6.186 6.186 0 0 1-.77-1.406 15.025 15.025 0 0 1-6.733-4.26c-.013.057-.03.113-.043.17a13.593 13.593 0 0 0-.232 4.52 2.71 2.71 0 0 1 2.203 2.653c0 .754-.316 1.473-.87 1.984a16.22  [...]
-                />
-                <path
-                    fill="#1287b1"
-                    d="M45.6 34.192a15.07 15.07 0 0 1-2.739-3.722 2.704 2.704 0 0 1-.41.034h-.004c-1.482 0-2.7-1.219-2.7-2.7 0-1.035.594-1.983 1.526-2.432-.273-2.209-.05-4.45.651-6.561a14.95 14.95 0 0 1-2.612-8.463c0-.115.006-.228.008-.341-2.783 1.395-4.87 3.595-4.87 7.057 0 7.659 4.573 14.245 11.136 17.19l.014-.062m15.976-9.661a6.198 6.198 0 0 1-5.843 4.144 6.17 6.17 0 0 1-3.826-1.327c-2.173 1.692-3.813 3.998-4.814 6.577.45.484.929.941 1.433 1.369 1.555.404 3.154.608 4.76.607 6.617 0 12 [...]
-                />
-                <g transform="translate(43.304 10.642)">
-                    <mask id="b" fill="#fff">
-                        <use xlinkHref="#a"/>
-                    </mask>
-                    <path
-                        fill="#fff"
-                        d="M14.783 6.242 14.704.147l-2.251 5.43L10.576.081l.101 6.472L7.433.753l1.755 6.16-5.262-3.827 4.122 5.18-6.533-2.403 5.156 3.815-6.612.203 6.76 1.745L.053 13.09l6.68.484L1.1 17.18l5.8-2.103-4.024 5.097 5.085-4.101-1.832 6.838 3.926-5.565-.55 6.573 2.228-5.958 1.897 6.262.461-6.281 2.815 5.36-1.663-6.131 5.155 3.993-3.328-5.091 5.656 2.203-4.325-4.25 5.8.456-5.712-2.192 5.727-1.366-5.748-.293 4.678-3.575-5.309 1.903 3.608-5-4.983 3.312 1.743-5.852z"
-                        mask="url(#b)"
-                    />
-                </g>
-                <image
-                    xlinkHref="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAx4AAADpCAYAAACqReECAAAABGdBTUEAALGOfPtRkwAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAADHqADAAQAAAABAAAA6QAAAADa02YqAABAAElEQVR4Ae292XcT19ruq6qS5B4bm76zMQYSDAZ34AYSyPedMc4a5+Jc5a/M7R5f9l5NFknArYwNiUnnhU2T0BuDbdlqStrPKyQjy2qqpKpSSXpqDLBUzWx+s1Q13/l2Hg83EiABEiABEiABEqhRAn19fU1ff/21VqPdZ7dJgARIgARIgARIgARIgATsJjA4ONg4MjLSZXc9LJ8ESIAESIAESIAESIAESMABAjdv3vSiGsWBqgxX0dvb67969eoNXKAavog [...]
-                    width={111.814}
-                    height={32.542}
-                    x={1.822}
-                    y={1.682}
-                    opacity={0.487}
-                />
-                <path
-                    fill="#373535"
-                    d="M46.372 6.794c1.704-.331 2.026-4.053 2.026-4.053s.238 2.743 1.43 3.1c1.193.357 2.742-4.291 2.742-4.291s-1.43 4.172 0 4.41c1.43.238 4.053-4.053 4.053-4.053s-1.072 3.695-.358 3.933c.715.239 4.291-5.364 4.291-5.364s-2.145 3.695-.119 4.053c2.027.358 4.984-2.521 4.984-2.521s-2.325 2.634-1.289 2.998c4.412 1.55 7.98-4.183 7.98-4.183s-.827 2.514-2.972 5.256C73.788 7.27 77.24.267 77.24.267L73.788 7.27C75.576 8.224 82.728 0 82.728 0s-3.694 6.436-5.84 7.747c1.192.954 5.483-2. [...]
-                />
-                <path
-                    fill="#373535"
-                    d="M0 34.76c9.388 4.71 17.97-.714 28.788 2.334 8.224 2.318 18.239 5.176 31.828 3.209 13.589-1.967 25.21-7.867 30.755-18.416 1.728-4.709 8.76 1.072 8.76 1.072s-5.125-2.145-5.006-1.132c.12 1.013 7.689 4.53 7.689 4.53s-6.855-2.146-6.437-.536c.417 1.608 8.583 8.045 8.583 8.045s-9.239-7.033-10.013-6.079c-.775.953 3.933 4.828 3.933 4.828s-7.808-4.828-10.55-3.405c-1.972 1.024 8.106 7.637 8.106 7.637S89.88 31.84 88.33 33.15c-1.55 1.312 7.391 12.04 7.391 12.04S85.588 34.223 84 [...]
-                />
-            </g>
-        </svg>
-    );
-}
-
-export function ActivemqIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={116.42}
-            height={167.526}
-            viewBox="0 0 30.803 44.324"
-            className="icon">
-            <defs>
-                <filter
-                    id="a"
-                    width={1.068}
-                    height={1.046}
-                    x={-0.017}
-                    y={-0.011}
-                >
-                    <feFlood floodColor="#000" floodOpacity={0.498} result="flood"/>
-                    <feComposite
-                        in="flood"
-                        in2="SourceGraphic"
-                        operator="in"
-                        result="composite1"
-                    />
-                    <feGaussianBlur in="composite1" result="blur" stdDeviation={0.2}/>
-                    <feOffset dx={1} dy={1} result="offset"/>
-                    <feComposite in="SourceGraphic" in2="offset" result="composite2"/>
-                </filter>
-            </defs>
-            <g
-                style={{
-                    display: "inline",
-                }}
-            >
-                <g
-                    style={{
-                        filter: "url(#a)",
-                    }}
-                    transform="translate(-39.667 -110.707)"
-                >
-                    <path
-                        d="m64.697 153.552-8.352-.05-4.133-7.257 4.218-7.208 8.352.049 4.134 7.257z"
-                        style={{
-                            fill: "#fff",
-                            strokeWidth: 0.394699,
-                            strokeMiterlimit: 4,
-                            strokeDasharray: "none",
-                        }}
-                    />
-                    <path
-                        d="m52.632 146.553-8.352-.049-4.133-7.257 4.218-7.209 8.352.05 4.134 7.257z"
-                        style={{
-                            display: "inline",
-                            fill: "#fff",
-                            strokeWidth: 0.394699,
-                            strokeMiterlimit: 4,
-                            strokeDasharray: "none",
-                        }}
-                    />
-                    <path
-                        d="m64.771 139.589-8.352-.05-4.133-7.257 4.218-7.208 8.352.05 4.134 7.257z"
-                        style={{
-                            display: "inline",
-                            fill: "#fff",
-                            strokeWidth: 0.394699,
-                            strokeMiterlimit: 4,
-                            strokeDasharray: "none",
-                        }}
-                    />
-                    <path
-                        d="m64.765 125.702-8.351-.049-4.134-7.257 4.219-7.209 8.352.05 4.133 7.257z"
-                        style={{
-                            display: "inline",
-                            fill: "#fff",
-                            strokeWidth: 0.394699,
-                            strokeMiterlimit: 4,
-                            strokeDasharray: "none",
-                        }}
-                    />
-                    <path
-                        d="m52.696 132.676-8.352-.049-4.133-7.257 4.218-7.209 8.352.05 4.133 7.257z"
-                        style={{
-                            display: "inline",
-                            fill: "#fff",
-                            strokeWidth: 0.394699,
-                            strokeMiterlimit: 4,
-                            strokeDasharray: "none",
-                        }}
-                    />
-                </g>
-            </g>
-            <g
-                style={{
-                    display: "inline",
-                }}
-                transform="translate(-39.667 -110.707)"
-            >
-                <path
-                    d="m1849.139 640.353-96.824 20.558-66.216-73.574 30.608-94.13 96.824-20.559 66.216 73.573z"
-                    style={{
-                        opacity: 1,
-                        fill: "#c12766",
-                        fillOpacity: 1,
-                        stroke: "none",
-                        strokeWidth: 3,
-                        strokeMiterlimit: 4,
-                        strokeDasharray: "none",
-                        strokeOpacity: 1,
-                    }}
-                    transform="matrix(.07206 .01553 -.01553 .07206 -59.031 63.796)"
-                />
-                <path
-                    d="m1849.139 640.353-96.824 20.558-66.216-73.574 30.608-94.13 96.824-20.559 66.216 73.573z"
-                    style={{
-                        opacity: 1,
-                        fill: "#3e489f",
-                        fillOpacity: 1,
-                        stroke: "none",
-                        strokeWidth: 15,
-                        strokeMiterlimit: 4,
-                        strokeDasharray: "none",
-                        strokeOpacity: 1,
-                    }}
-                    transform="matrix(.07206 .01553 -.01553 .07206 -71.17 70.76)"
-                />
-                <path
-                    d="m1849.139 640.353-96.824 20.558-66.216-73.574 30.608-94.13 96.824-20.559 66.216 73.573z"
-                    style={{
-                        opacity: 1,
-                        fill: "#714099",
-                        fillOpacity: 1,
-                        stroke: "none",
-                        strokeWidth: 3,
-                        strokeMiterlimit: 4,
-                        strokeDasharray: "none",
-                        strokeOpacity: 1,
-                    }}
-                    transform="matrix(.07206 .01553 -.01553 .07206 -59.106 77.758)"
-                />
-                <path
-                    d="m1849.139 640.353-96.824 20.558-66.216-73.574 30.608-94.13 96.824-20.559 66.216 73.573z"
-                    style={{
-                        opacity: 1,
-                        fill: "#78932c",
-                        fillOpacity: 1,
-                        stroke: "none",
-                        strokeWidth: 3,
-                        strokeMiterlimit: 4,
-                        strokeDasharray: "none",
-                        strokeOpacity: 1,
-                    }}
-                    transform="matrix(.07206 .01553 -.01553 .07206 -71.106 56.883)"
-                />
-                <path
-                    d="m1849.139 640.353-96.824 20.558-66.216-73.574 30.608-94.13 96.824-20.559 66.216 73.573z"
-                    style={{
-                        opacity: 1,
-                        fill: "#cf242a",
-                        fillOpacity: 1,
-                        stroke: "none",
-                        strokeWidth: 3,
-                        strokeMiterlimit: 4,
-                        strokeDasharray: "none",
-                        strokeOpacity: 1,
-                    }}
-                    transform="matrix(.07206 .01553 -.01553 .07206 -59.037 49.91)"
-                />
-                <circle
-                    cx={60.564}
-                    cy={146.294}
-                    r={1.6}
-                    style={{
-                        opacity: 1,
-                        fill: "#fff",
-                        fillOpacity: 1,
-                        stroke: "none",
-                        strokeWidth: 0.320071,
-                        strokeMiterlimit: 4,
-                        strokeDasharray: "none",
-                        strokeOpacity: 1,
-                    }}
-                />
-                <path
-                    d="m61.748 117.71-14.267 8.174M48.514 124.197l.048 16.442M47.525 138.715l14.136 8.397M60.59 117.133l.048 16.442"
-                    style={{
-                        fill: "none",
-                        fillRule: "evenodd",
-                        stroke: "#fff",
-                        strokeWidth: 0.523753,
-                        strokeLinecap: "butt",
-                        strokeLinejoin: "miter",
-                        strokeMiterlimit: 4,
-                        strokeDasharray: "none",
-                        strokeOpacity: 1,
-                    }}
-                />
-                <path
-                    d="m60.657 131.093.048 16.442"
-                    style={{
-                        fill: "none",
-                        fillRule: "evenodd",
-                        stroke: "#fff",
-                        strokeWidth: 0.5238,
-                        strokeLinecap: "butt",
-                        strokeLinejoin: "miter",
-                        strokeMiterlimit: 4,
-                        strokeDasharray: "none",
-                        strokeOpacity: 1,
-                    }}
-                />
-                <path
-                    d="m61.766 131.708-14.267 8.174M47.564 124.84l14.136 8.398"
-                    style={{
-                        fill: "none",
-                        fillRule: "evenodd",
-                        stroke: "#fff",
-                        strokeWidth: 0.523753,
-                        strokeLinecap: "butt",
-                        strokeLinejoin: "miter",
-                        strokeMiterlimit: 4,
-                        strokeDasharray: "none",
-                        strokeOpacity: 1,
-                    }}
-                />
-                <circle
-                    cx={48.334}
-                    cy={139.242}
-                    r={1.6}
-                    style={{
-                        opacity: 1,
-                        fill: "#fff",
-                        fillOpacity: 1,
-                        stroke: "none",
-                        strokeWidth: 0.320071,
-                        strokeMiterlimit: 4,
-                        strokeDasharray: "none",
-                        strokeOpacity: 1,
-                    }}
-                />
-                <circle
-                    cx={60.901}
-                    cy={132.486}
-                    r={1.6}
-                    style={{
-                        opacity: 1,
-                        fill: "#fff",
-                        fillOpacity: 1,
-                        stroke: "none",
-                        strokeWidth: 0.320071,
-                        strokeMiterlimit: 4,
-                        strokeDasharray: "none",
-                        strokeOpacity: 1,
-                    }}
-                />
-                <circle
-                    cx={48.563}
-                    cy={125.419}
-                    r={1.6}
-                    style={{
-                        opacity: 1,
-                        fill: "#fff",
-                        fillOpacity: 1,
-                        stroke: "none",
-                        strokeWidth: 0.320071,
-                        strokeMiterlimit: 4,
-                        strokeDasharray: "none",
-                        strokeOpacity: 1,
-                    }}
-                />
-                <circle
-                    cx={60.632}
-                    cy={118.445}
-                    r={1.6}
-                    style={{
-                        opacity: 1,
-                        fill: "#fff",
-                        fillOpacity: 1,
-                        stroke: "none",
-                        strokeWidth: 0.320071,
-                        strokeMiterlimit: 4,
-                        strokeDasharray: "none",
-                        strokeOpacity: 1,
-                    }}
-                />
-            </g>
-        </svg>
-    );
-}
-
-export function KafkaIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            preserveAspectRatio="xMidYMid"
-            viewBox="-78.5 0 413 413"
-            className="icon">
-            <path
-                fill="#1A1919"
-                d="M87.932 36.714c-4.55-4.571-10.896-7.394-17.951-7.394-7.029 0-13.326 2.823-17.822 7.394h-.13c-4.535 4.55-7.358 10.9-7.358 17.93 0 7.055 2.823 13.352 7.359 17.875l.129.102c4.496 4.55 10.793 7.346 17.822 7.346 7.055 0 13.402-2.797 17.951-7.346L88 72.52c4.558-4.523 7.354-10.82 7.354-17.876 0-7.029-2.796-13.38-7.354-17.929h-.067Zm-17.951 346.64a25.504 25.504 0 0 0 17.951-7.368l.067-.134c4.558-4.487 7.354-10.838 7.354-17.817 0-7.056-2.796-13.38-7.354-17.952h-.067c-4.55-4.625 [...]
-            />
-        </svg>
-    );
-}
-
-export function GrapeIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            xmlSpace="preserve"
-            viewBox="0 0 512 512"
-            className="icon">
-            <path
-                d="M438.557 512H19.785c-8.216 0-14.876-6.66-14.876-14.876V256.916c0-8.216 6.66-14.876 14.876-14.876s14.876 6.66 14.876 14.876v225.332h389.021v-32.833c0-8.216 6.661-14.876 14.876-14.876s14.876 6.66 14.876 14.876v47.709c-.001 8.216-6.662 14.876-14.877 14.876z"
-                style={{
-                    fill: "#2d527c",
-                }}
-            />
-            <path
-                d="M19.785 177.122v-4.79L175.581 14.876v162.246zM196.154 219.435h296.061v163.65H196.154z"
-                style={{
-                    fill: "#cee8fa",
-                }}
-            />
-            <path
-                d="M492.215 204.559h-38.782V14.876C453.433 6.66 446.772 0 438.557 0H175.581c-.182 0-.361.021-.543.027a14.949 14.949 0 0 0-2.41.269c-.018.003-.036.01-.054.013-.613.126-1.211.302-1.8.504-.158.054-.315.11-.472.171-.58.22-1.148.466-1.697.756-.024.012-.048.021-.071.034-.567.305-1.105.66-1.63 1.037a10.84 10.84 0 0 0-.403.302c-.521.402-1.026.827-1.495 1.3L9.21 161.868c-.35.353-.678.721-.988 1.104-.207.254-.388.521-.576.784-.092.131-.195.256-.283.388a15.3 15.3 0 0 0-.592.998c-.04 [...]
-                style={{
-                    fill: "#2d527c",
-                }}
-            />
-            <path
-                d="M265.4 270.343c-3.927 0-6.153-4.188-6.153-9.031 0-4.189 1.831-8.771 6.153-8.771h22.907c4.451 0 8.902 2.095 8.902 6.285v59.298c0 22.516-14.269 30.894-31.418 30.894-18.718 0-32.857-9.949-32.857-27.36 0-7.854 3.273-9.687 10.342-9.687 5.236 0 9.687 1.309 10.078 6.153.393 5.105 1.047 13.091 11.521 13.091 7.593 0 11.913-4.188 11.913-13.091v-47.78H265.4v-.001zM304.411 339.854c0-.393.131-.916.262-1.44l24.349-79.853c1.44-4.58 7.331-6.806 13.353-6.806s11.913 2.225 13.353 6.806l2 [...]
-                style={{
-                    fill: "#2d527c",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function MachineLearningIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <path
-                d="M27 24a2.96 2.96 0 0 0-1.285.3l-4.3-4.3H18v2h2.586l3.715 3.715A2.966 2.966 0 0 0 24 27a3 3 0 1 0 3-3Zm0 4a1 1 0 1 1 1-1 1 1 0 0 1-1 1ZM27 13a2.995 2.995 0 0 0-2.816 2H18v2h6.184A2.995 2.995 0 1 0 27 13Zm0 4a1 1 0 1 1 1-1 1 1 0 0 1-1 1ZM27 2a3.003 3.003 0 0 0-3 3 2.966 2.966 0 0 0 .348 1.373L20.596 10H18v2h3.404l4.4-4.252A2.999 2.999 0 1 0 27 2Zm0 4a1 1 0 1 1 1-1 1 1 0 0 1-1 1Z"/>
-            <path
-                d="M18 6h2V4h-2a3.976 3.976 0 0 0-3 1.382A3.976 3.976 0 0 0 12 4h-1a9.01 9.01 0 0 0-9 9v6a9.01 9.01 0 0 0 9 9h1a3.976 3.976 0 0 0 3-1.382A3.976 3.976 0 0 0 18 28h2v-2h-2a2.002 2.002 0 0 1-2-2V8a2.002 2.002 0 0 1 2-2Zm-6 20h-1a7.005 7.005 0 0 1-6.92-6H6v-2H4v-4h3a3.003 3.003 0 0 0 3-3V9H8v2a1 1 0 0 1-1 1H4.08A7.005 7.005 0 0 1 11 6h1a2.002 2.002 0 0 1 2 2v4h-2v2h2v4h-2a3.003 3.003 0 0 0-3 3v2h2v-2a1 1 0 0 1 1-1h2v4a2.002 2.002 0 0 1-2 2Z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function TerminalIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <title>{"terminal"}</title>
-            <path
-                d="M26 4.01H6a2 2 0 0 0-2 2v20a2 2 0 0 0 2 2h20a2 2 0 0 0 2-2v-20a2 2 0 0 0-2-2Zm0 2v4H6v-4Zm-20 20v-14h20v14Z"/>
-            <path d="m10.76 16.18 2.82 2.83-2.82 2.83 1.41 1.41 4.24-4.24-4.24-4.24-1.41 1.41z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function SapIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 1024 1024"
-            className="icon">
-            <circle
-                cx={512}
-                cy={512}
-                r={512}
-                style={{
-                    fill: "#007cc5",
-                }}
-            />
-            <path
-                d="M256 359.88v304.24h310.82L871 359.88zm83.62 56.58h.14c22.11 0 49.06 6.29 68.56 16.22l-21 36.64C365.92 459 355.17 458 343 457.36c-18.14-1-27.26 5.51-27.4 12.5-.18 8.52 17.13 16.23 33.45 21.47 24.7 7.85 56.1 18.33 60.9 48.7l45.15-119.36h52.45l52.88 142.91-.2-142.86H621c57.84 0 85 19.58 85 64.53 0 40.36-28 64.42-75.25 64.42h-19.56l-.19 53.69-92-.09-6.38-23.27a101.65 101.65 0 0 1-31.56 4.83 100.52 100.52 0 0 1-32.32-5.12l-9.19 23.54-51.25.16 2.3-11.84c-.73.64-1.43 1.29-2.2 [...]
-                style={{
-                    fill: "#fff",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function ScriptIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <title>{"script"}</title>
-            <path
-                d="m18.83 26 2.58-2.58L20 22l-4 4 4 4 1.42-1.41L18.83 26zM27.17 26l-2.58 2.58L26 30l4-4-4-4-1.42 1.41L27.17 26z"/>
-            <path
-                d="M14 28H8V4h8v6a2.006 2.006 0 0 0 2 2h6v6h2v-8a.91.91 0 0 0-.3-.7l-7-7A.909.909 0 0 0 18 2H8a2.006 2.006 0 0 0-2 2v24a2.006 2.006 0 0 0 2 2h6Zm4-23.6 5.6 5.6H18Z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function ValidationIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <path d="m22 27.18-2.59-2.59L18 26l4 4 8-8-1.41-1.41L22 27.18z"/>
-            <path
-                d="M15 28H8V4h8v6a2.006 2.006 0 0 0 2 2h6v6h2v-8a.91.91 0 0 0-.3-.7l-7-7A.909.909 0 0 0 18 2H8a2.006 2.006 0 0 0-2 2v24a2.006 2.006 0 0 0 2 2h7Zm3-23.6 5.6 5.6H18Z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function OpenstackIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            preserveAspectRatio="xMidYMid"
-            viewBox="0 -2.5 256 256"
-            className="icon">
-            <path
-                fill="#DA1A32"
-                d="M57.82 170.723v9.156c0 7.104 5.756 12.86 12.86 12.86h114.65c7.104 0 12.86-5.756 12.86-12.86v-9.156H256v56.051c0 13.082-10.703 23.785-23.785 23.785H23.785C10.703 250.559 0 239.856 0 226.774v-56.051h57.82Zm-.01-74.353v57.809H0v-57.81h57.81Zm198.19 0v57.809h-57.81v-57.81H256ZM232.215 0C245.297 0 256 10.703 256 23.795v56.041h-57.81V70.68c0-7.104-5.756-12.86-12.86-12.86H70.67c-7.104 0-12.86 5.756-12.86 12.86v9.156H0V23.785C0 10.703 10.703 0 23.785 0Z"
-            />
-        </svg>
-    );
-}
-
-export function OpenshiftIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            preserveAspectRatio="xMidYMid"
-            viewBox="0 -9.5 256 256"
-            className="icon">
-            <path
-                fill="#DA2430"
-                d="m74.84 106.893-40.869 14.87c.525 6.552 1.652 13.024 3.24 19.366l38.818-14.137c-1.244-6.552-1.689-13.32-1.18-20.1M255.444 61.702c-2.85-5.879-6.147-11.561-9.966-16.916l-40.857 14.87c4.755 4.864 8.743 10.33 12.007 16.176L255.445 61.7v.002Z"
-            />
-            <path
-                fill="#DA2430"
-                d="M182.95 61.461c-5.14-4.46-10.946-8.31-17.408-11.324h-.003C127.6 32.449 82.33 48.905 64.642 86.859a73.976 73.976 0 0 0-2.653 6.487c-2.208 6.423-3.498 12.99-3.991 19.546l-.144.054-.011.144-24.596 8.95-15.826 5.849-.007-.088-.434.158c-1.536-19.435 1.74-39.512 10.553-58.411a117.952 117.952 0 0 1 3.687-7.246c29.054-54.116 95.164-76.736 150.918-50.33a115.314 115.314 0 0 1 30.557 21.074 116.597 116.597 0 0 1 15.78 17.94L187.618 65.86a79.69 79.69 0 0 0-.635-.641l-.113.041a78.6 [...]
-            />
-            <path
-                fill="#E82429"
-                d="m19.261 193.896-.064.024A118.404 118.404 0 0 1 .939 154.347l38.825-14.14.002.003.024.125.252-.093.006.015c1.994 10.56 6.145 20.635 12.198 29.494a75.287 75.287 0 0 0 7.722 9.326l-.154.057.294.308-40.488 14.97c-.12-.171-.24-.343-.359-.516Z"
-            />
-            <path
-                fill="#DA2430"
-                d="M173.465 183.447c-21.051 13.017-48.053 15.532-72.113 4.312a75.139 75.139 0 0 1-22.118-15.695l-40.772 14.844.313.437-.02.008c11.21 16.016 26.502 29.404 45.266 38.298 40.47 19.163 86.387 12.501 119.634-13.284 14.888-11.152 27.317-26.016 35.713-44.02 8.819-18.895 12.076-38.964 10.515-58.384l-1.136.414c-.015-.208-.03-.416-.047-.624l-40.49 14.957.002.004a76.457 76.457 0 0 1-6.806 26.46c-6.315 13.753-16.164 24.708-27.94 32.273Z"
-            />
-            <path
-                fill="#E82429"
-                d="m218.552 75.13.607-.222v-.001a117.732 117.732 0 0 1 11.454 42.055l-40.773 14.834.022-.304-.77.285c1.11-15.088-2.275-30.093-9.435-43.123l38.548-14.25.002-.004c.116.243.231.486.345.73Z"
-            />
-            <path
-                fill="#C22035"
-                d="M74.89 106.654 34.31 121.65c.52 6.61 1.64 13.136 3.219 19.532l38.546-14.258c-1.247-6.622-1.695-13.438-1.169-20.274M254.227 61.083c-2.83-5.929-6.106-11.658-9.898-17.059L203.76 59.02c4.72 4.906 8.68 10.418 11.92 16.315l38.542-14.256.006.004Z"
-            />
-            <path
-                fill="#AC223B"
-                d="m34.308 121.653 40.482-14.829-.165 8.133-39.056 14.749-1.266-8.063.005.01ZM203.766 58.897l41.113-14.108 4.273 6.449-39.946 14.121-5.434-6.465-.006.003Z"
-            />
-            <path
-                fill="#B92135"
-                d="m38.764 187.201 40.53-14.749 12.258 11.565-42.503 15.956-10.283-12.776-.002.004ZM249.38 109.862l-41.165 14.844-3.032 16.478 43.892-15.643.311-15.677-.005-.002Z"
-            />
-        </svg>
-    );
-}
-
-export function RefIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <path
-                d="M4 20v2h4.586L2 28.586 3.414 30 10 23.414V28h2v-8H4zM30 30h-8v-8h8Zm-6-2h4v-4h-4ZM20 20h-8v-8h8Zm-6-2h4v-4h-4Z"/>
-            <path d="M24 17h-2v-2h2a4 4 0 0 0 0-8H12V5h12a6 6 0 0 1 0 12ZM10 10H2V2h8ZM4 8h4V4H4Z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function RedisIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            preserveAspectRatio="xMidYMid"
-            viewBox="0 -18 256 256"
-            className="icon">
-            <path
-                fill="#912626"
-                d="M245.97 168.943c-13.662 7.121-84.434 36.22-99.501 44.075-15.067 7.856-23.437 7.78-35.34 2.09-11.902-5.69-87.216-36.112-100.783-42.597C3.566 169.271 0 166.535 0 163.951v-25.876s98.05-21.345 113.879-27.024c15.828-5.679 21.32-5.884 34.79-.95 13.472 4.936 94.018 19.468 107.331 24.344l-.006 25.51c.002 2.558-3.07 5.364-10.024 8.988"
-            />
-            <path
-                fill="#C6302B"
-                d="M245.965 143.22c-13.661 7.118-84.431 36.218-99.498 44.072-15.066 7.857-23.436 7.78-35.338 2.09-11.903-5.686-87.214-36.113-100.78-42.594-13.566-6.485-13.85-10.948-.524-16.166 13.326-5.22 88.224-34.605 104.055-40.284 15.828-5.677 21.319-5.884 34.789-.948 13.471 4.934 83.819 32.935 97.13 37.81 13.316 4.881 13.827 8.9.166 16.02"
-            />
-            <path
-                fill="#912626"
-                d="M245.97 127.074c-13.662 7.122-84.434 36.22-99.501 44.078-15.067 7.853-23.437 7.777-35.34 2.087-11.903-5.687-87.216-36.112-100.783-42.597C3.566 127.402 0 124.67 0 122.085V96.206s98.05-21.344 113.879-27.023c15.828-5.679 21.32-5.885 34.79-.95C162.142 73.168 242.688 87.697 256 92.574l-.006 25.513c.002 2.557-3.07 5.363-10.024 8.987"
-            />
-            <path
-                fill="#C6302B"
-                d="M245.965 101.351c-13.661 7.12-84.431 36.218-99.498 44.075-15.066 7.854-23.436 7.777-35.338 2.087-11.903-5.686-87.214-36.112-100.78-42.594-13.566-6.483-13.85-10.947-.524-16.167C23.151 83.535 98.05 54.148 113.88 48.47c15.828-5.678 21.319-5.884 34.789-.949 13.471 4.934 83.819 32.933 97.13 37.81 13.316 4.88 13.827 8.9.166 16.02"
-            />
-            <path
-                fill="#912626"
-                d="M245.97 83.653c-13.662 7.12-84.434 36.22-99.501 44.078-15.067 7.854-23.437 7.777-35.34 2.087-11.903-5.687-87.216-36.113-100.783-42.595C3.566 83.98 0 81.247 0 78.665v-25.88s98.05-21.343 113.879-27.021c15.828-5.68 21.32-5.884 34.79-.95C162.142 29.749 242.688 44.278 256 49.155l-.006 25.512c.002 2.555-3.07 5.361-10.024 8.986"
-            />
-            <path
-                fill="#C6302B"
-                d="M245.965 57.93c-13.661 7.12-84.431 36.22-99.498 44.074-15.066 7.854-23.436 7.777-35.338 2.09C99.227 98.404 23.915 67.98 10.35 61.497-3.217 55.015-3.5 50.55 9.825 45.331 23.151 40.113 98.05 10.73 113.88 5.05c15.828-5.679 21.319-5.883 34.789-.948 13.471 4.935 83.819 32.934 97.13 37.811 13.316 4.876 13.827 8.897.166 16.017"
-            />
-            <path
-                fill="#FFF"
-                d="m159.283 32.757-22.01 2.285-4.927 11.856-7.958-13.23-25.415-2.284 18.964-6.839-5.69-10.498 17.755 6.944 16.738-5.48-4.524 10.855 17.067 6.391M131.032 90.275 89.955 73.238l58.86-9.035-17.783 26.072M74.082 39.347c17.375 0 31.46 5.46 31.46 12.194 0 6.736-14.085 12.195-31.46 12.195s-31.46-5.46-31.46-12.195c0-6.734 14.085-12.194 31.46-12.194"
-            />
-            <path
-                fill="#621B1C"
-                d="m185.295 35.998 34.836 13.766-34.806 13.753-.03-27.52"
-            />
-            <path
-                fill="#9A2928"
-                d="m146.755 51.243 38.54-15.245.03 27.519-3.779 1.478-34.791-13.752"
-            />
-        </svg>
-    );
-}
-
-export function SearchIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <path
-                d="m29 27.586-7.552-7.552a11.018 11.018 0 1 0-1.414 1.414L27.586 29ZM4 13a9 9 0 1 1 9 9 9.01 9.01 0 0 1-9-9Z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function BlockchainIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <title>{"blockchain"}</title>
-            <path d="M6 24H4V8h2ZM28 8h-2v16h2Zm-4-2V4H8v2Zm0 22v-2H8v2Z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function ChatIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <title>{"chat"}</title>
-            <path
-                d="M17.74 30 16 29l4-7h6a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h9v2H6a4 4 0 0 1-4-4V8a4 4 0 0 1 4-4h20a4 4 0 0 1 4 4v12a4 4 0 0 1-4 4h-4.84Z"/>
-            <path d="M8 10h16v2H8zM8 16h10v2H8z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function WorkflowIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            xmlSpace="preserve"
-            width={800}
-            height={800}
-            viewBox="0 0 512 512"
-            className="icon">
-            <path
-                d="M445.66 49.341H340.206L294.008 3.143c-4.192-4.191-10.99-4.191-15.183 0l-49.341 49.342c-4.192 4.192-4.192 10.99 0 15.183l46.198 46.198v38.494h-80.516c-5.929 0-10.736 4.806-10.736 10.735v21.471h-42.942v-21.471c0-5.929-4.806-10.735-10.736-10.735H66.34c-5.929 0-10.735 4.806-10.735 10.735v64.413c0 5.929 4.806 10.735 10.735 10.735h20.755v93.798c0 5.929 4.806 10.736 10.735 10.736h95.437l-10.346 10.346c-4.192 4.192-4.193 10.99 0 15.182a10.7 10.7 0 0 0 7.591 3.144c2.747 0 5.495 [...]
-        </svg>
-    );
-}
-
-export function WebserviceIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <title>{"fog"}</title>
-            <path
-                d="M25.829 13.116A10.02 10.02 0 0 0 16 5v2a8.023 8.023 0 0 1 7.865 6.493l.259 1.346 1.349.245A5.502 5.502 0 0 1 24.508 26H16v2h8.508a7.502 7.502 0 0 0 1.32-14.884ZM8 24h6v2H8zM4 24h2v2H4zM6 20h8v2H6zM2 20h2v2H2zM8 16h6v2H8zM4 16h2v2H4zM10 12h4v2h-4zM6 12h2v2H6zM12 8h2v2h-2z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function MobileIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <path d="M23 7h4v4h-4zM23 13h4v4h-4zM17 7h4v4h-4zM17 13h4v4h-4z"/>
-            <circle cx={14.5} cy={24.5} r={1.5}/>
-            <path
-                d="M21 30H8a2.002 2.002 0 0 1-2-2V4a2.002 2.002 0 0 1 2-2h13v2H8v24h13v-8h2v8a2.002 2.002 0 0 1-2 2Z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function ClusterIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <path
-                d="M16 7a3 3 0 1 1 3-3 3.003 3.003 0 0 1-3 3Zm0-4a1 1 0 1 0 1 1 1.001 1.001 0 0 0-1-1ZM11 30a3 3 0 1 1 3-3 3.003 3.003 0 0 1-3 3Zm0-4a1 1 0 1 0 1 1 1.001 1.001 0 0 0-1-1ZM7 11a3 3 0 1 1 3-3 3.003 3.003 0 0 1-3 3Zm0-4a1 1 0 1 0 1 1 1.001 1.001 0 0 0-1-1ZM21 30a3 3 0 1 1 3-3 3.003 3.003 0 0 1-3 3Zm0-4a1 1 0 1 0 1 1 1.001 1.001 0 0 0-1-1ZM25 11a3 3 0 1 1 3-3 3.003 3.003 0 0 1-3 3Zm0-4a1 1 0 1 0 1 1 1.001 1.001 0 0 0-1-1ZM4 21a3 3 0 1 1 3-3 3.003 3.003 0 0 1-3 3Zm0-4a1 1 0 1  [...]
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function RpcIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <path d="m14 26 1.41-1.41L7.83 17H28v-2H7.83l7.58-7.59L14 6 4 16l10 10z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function InfinispanIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            id="artwork"
-            viewBox="0 0 1024 1024"
-            className="icon">
-            <defs>
-                <style>{".cls-2{fill:#fff}"}</style>
-            </defs>
-            <path
-                d="M1 1h1022v1022H1z"
-                style={{
-                    fill: "#599fc6",
-                }}
-            />
-            <path
-                d="M566.84 512c0-221.39-179.47-400.86-400.86-400.86v109.68c160.56 0 291.18 130.62 291.18 291.18 0 221.39 179.47 400.86 400.86 400.86V803.18c-160.56 0-291.18-130.62-291.18-291.18Z"
-                className="cls-2"
-            />
-            <path
-                d="M436.76 618.86C394.05 726.69 288.82 803.18 166 803.18v109.68c134.26 0 253-66.07 325.76-167.4a432.16 432.16 0 0 1-55-126.6ZM587.24 405.14C630 297.31 735.19 220.82 858 220.82V111.14c-134.26 0-253 66.07-325.77 167.4a431.92 431.92 0 0 1 55.01 126.6Z"
-                className="cls-2"
-            />
-        </svg>
-    );
-}
-
-export function TransformationIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <title>{"data-share"}</title>
-            <path
-                d="M5 25v-9.172l-3.586 3.586L0 18l6-6 6 6-1.414 1.414L7 15.828V25h12v2H7a2.002 2.002 0 0 1-2-2ZM24 22h4a2.002 2.002 0 0 1 2 2v4a2.002 2.002 0 0 1-2 2h-4a2.002 2.002 0 0 1-2-2v-4a2.002 2.002 0 0 1 2-2Zm4 6v-4h-4.002L24 28ZM27 6v9.172l3.586-3.586L32 13l-6 6-6-6 1.414-1.414L25 15.172V6H13V4h12a2.002 2.002 0 0 1 2 2ZM2 6h6v2H2zM2 2h8v2H2z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function TestingIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <path
-                d="M28 17v5H4V6h10V4H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h8v4H8v2h16v-2h-4v-4h8a2 2 0 0 0 2-2v-5ZM18 28h-4v-4h4Z"/>
-            <path
-                d="M30 10V8h-2.101a4.968 4.968 0 0 0-.732-1.753l1.49-1.49-1.414-1.414-1.49 1.49A4.968 4.968 0 0 0 24 4.101V2h-2v2.101a4.968 4.968 0 0 0-1.753.732l-1.49-1.49-1.414 1.414 1.49 1.49A4.968 4.968 0 0 0 18.101 8H16v2h2.101a4.968 4.968 0 0 0 .732 1.753l-1.49 1.49 1.414 1.414 1.49-1.49a4.968 4.968 0 0 0 1.753.732V16h2v-2.101a4.968 4.968 0 0 0 1.753-.732l1.49 1.49 1.414-1.414-1.49-1.49A4.968 4.968 0 0 0 27.899 10Zm-7 2a3 3 0 1 1 3-3 3.003 3.003 0 0 1-3 3Z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function ApiIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <title>{"api"}</title>
-            <path
-                d="M26 22a3.86 3.86 0 0 0-2 .57l-3.09-3.1a6 6 0 0 0 0-6.94L24 9.43a3.86 3.86 0 0 0 2 .57 4 4 0 1 0-4-4 3.86 3.86 0 0 0 .57 2l-3.1 3.09a6 6 0 0 0-6.94 0L9.43 8A3.86 3.86 0 0 0 10 6a4 4 0 1 0-4 4 3.86 3.86 0 0 0 2-.57l3.09 3.1a6 6 0 0 0 0 6.94L8 22.57A3.86 3.86 0 0 0 6 22a4 4 0 1 0 4 4 3.86 3.86 0 0 0-.57-2l3.1-3.09a6 6 0 0 0 6.94 0l3.1 3.09a3.86 3.86 0 0 0-.57 2 4 4 0 1 0 4-4Zm0-18a2 2 0 1 1-2 2 2 2 0 0 1 2-2ZM4 6a2 2 0 1 1 2 2 2 2 0 0 1-2-2Zm2 22a2 2 0 1 1 2-2 2 2 0 0 1-2 [...]
-            <path
-                d="M0 0h32v32H0z"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function MonitoringIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <path
-                d="M28 16v6H4V6h7V4H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h8v4H8v2h16v-2h-4v-4h8a2 2 0 0 0 2-2v-6ZM18 28h-4v-4h4Z"/>
-            <path
-                d="M18 18h-.01a1 1 0 0 1-.951-.725L15.246 11H11V9h5a1 1 0 0 1 .962.725l1.074 3.76 3.009-9.78A1.014 1.014 0 0 1 22 3a.98.98 0 0 1 .949.684L24.72 9H30v2h-6a1 1 0 0 1-.949-.684l-1.013-3.04-3.082 10.018A1 1 0 0 1 18 18Z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function NetworkingIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            xmlSpace="preserve"
-            width={800}
-            height={800}
-            viewBox="0 0 511.984 511.984"
-            className="icon">
-            <path
-                d="M207.29 287.991H48.735C30.687 287.991 16 302.375 16 320.054v111.868c0 17.679 14.688 32.063 32.735 32.063H207.29c18.031 0 32.703-14.384 32.703-32.063V320.054c0-17.679-14.672-32.063-32.703-32.063zm0 143.996-159.291-.064.736-111.932 159.259.064.048 111.645c0 .015-.192.287-.752.287z"/>
-            <path
-                d="M383.988 239.992H127.996c-8.832 0-16 7.168-16 16v47.998c0 8.832 7.168 16 16 16s15.999-7.168 15.999-16v-31.999h223.993v31.999c0 8.832 7.168 16 16 16s15.999-7.168 15.999-16v-47.998c0-8.832-7.167-16-15.999-16z"/>
-            <path
-                d="M463.25 287.991H304.727c-18.047 0-32.735 14.384-32.735 32.063v111.868c0 17.679 14.688 32.063 32.735 32.063H463.25c18.047 0 32.735-14.384 32.735-32.063V320.054c-.001-17.679-14.688-32.063-32.735-32.063zm0 143.996-159.259-.064.736-111.932 159.259.064.064 111.645c-.016-.001-.208.287-.8.287zM415.987 479.985h-63.998c-8.832 0-16 7.168-16 16s7.168 16 16 16h63.998c8.832 0 16-7.168 16-16s-7.168-16-16-16zM335.253 0H176.73c-18.047 0-32.735 14.384-32.735 32.063v111.869c0 17.679 14. [...]
-            <path
-                d="M255.992 191.994c-8.832 0-16 7.168-16 16v47.998c0 8.832 7.168 16 16 16s15.999-7.168 15.999-16v-47.998c.001-8.832-7.167-16-15.999-16z"/>
-        </svg>
-    );
-}
-
-export function HealthIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            xmlSpace="preserve"
-            id="Icons"
-            viewBox="0 0 32 32"
-            className="icon">
-            <style>
-                {
-                    ".st0{fill:none;stroke:#000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10}"
-                }
-            </style>
-            <path
-                d="M27 7h0c-2.6-2.7-6.9-2.7-9.5 0l-1.3 1.4c-.1.1-.4.1-.5 0L14.4 7C11.8 4.3 7.6 4.3 5 7h0c-2.6 2.7-2.6 7.1 0 9.8l1.6 1.6 9.2 9.5c.1.1.4.1.5 0l9.2-9.5 1.6-1.6c2.6-2.7 2.6-7.1-.1-9.8z"
-                className="st0"
-            />
-            <path d="M9 15h3l2-2 2 4 2-5 2 3h3" className="st0"/>
-        </svg>
-    );
-}
-
-export function KubernetesIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 -10.44 722.846 722.846"
-            className="icon">
-            <path
-                fill="#326ce5"
-                d="M358.986 10.06a46.725 46.342 0 0 0-17.906 4.531L96.736 131.341a46.725 46.342 0 0 0-25.28 31.438l-60.282 262.25a46.725 46.342 0 0 0 6.344 35.531 46.725 46.342 0 0 0 2.656 3.688l169.125 210.28a46.725 46.342 0 0 0 36.531 17.438l271.219-.062a46.725 46.342 0 0 0 36.531-17.406l169.063-210.313a46.725 46.342 0 0 0 9.03-39.219L651.3 162.716a46.725 46.342 0 0 0-25.281-31.437L381.643 14.59a46.725 46.342 0 0 0-22.657-4.53z"
-            />
-            <path
-                fill="#fff"
-                stroke="#fff"
-                strokeWidth={0.25}
-                d="M361.408 99.307c-8.077.001-14.626 7.276-14.625 16.25 0 .138.028.27.03.406-.011 1.22-.07 2.689-.03 3.75.192 5.176 1.32 9.138 2 13.907 1.23 10.206 2.26 18.667 1.625 26.531-.62 2.965-2.803 5.677-4.75 7.562l-.344 6.188a190.337 190.337 0 0 0-26.438 4.062c-37.974 8.623-70.67 28.184-95.562 54.594a245.167 245.167 0 0 1-5.281-3.75c-2.612.353-5.25 1.159-8.688-.844-6.545-4.405-12.506-10.486-19.719-17.812-3.305-3.504-5.698-6.841-9.625-10.219-.891-.767-2.252-1.804-3.25-2.594-3.07-2 [...]
-                color="#000"
-                fontFamily="Sans"
-                fontWeight={400}
-                overflow="visible"
-                style={{
-                    textIndent: 0,
-                    textAlign: "start",
-                    lineHeight: "normal",
-                    textTransform: "none",
-                    marker: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function DocumentIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 32 32"
-            className="icon">
-            <title>{"document--blank"}</title>
-            <path
-                d="m25.7 9.3-7-7A.908.908 0 0 0 18 2H8a2.006 2.006 0 0 0-2 2v24a2.006 2.006 0 0 0 2 2h16a2.006 2.006 0 0 0 2-2V10a.908.908 0 0 0-.3-.7ZM18 4.4l5.6 5.6H18ZM24 28H8V4h8v6a2.006 2.006 0 0 0 2 2h6Z"/>
-            <path
-                d="M0 0h32v32H0z"
-                data-name="&lt;Transparent Rectangle&gt;"
-                style={{
-                    fill: "none",
-                }}
-            />
-        </svg>
-    );
-}
-
-export function GitIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            fill="none"
-            viewBox="0 0 24 24"
-            className="icon">
-            <path
-                fill="#000"
-                fillRule="evenodd"
-                d="M13.414 3.828a2 2 0 0 0-2.828 0l-.672.672 1.568 1.568a2.002 2.002 0 0 1 2.45 2.45l2.05 2.05a2 2 0 1 1-1.414 1.414L13 10.414v4.854A2 2 0 0 1 12 19a2 2 0 0 1-1-3.732V9.732a2 2 0 0 1-.932-2.25L8.5 5.914l-4.672 4.672a2 2 0 0 0 0 2.828l6.758 6.758a2 2 0 0 0 2.828 0l6.758-6.758a2 2 0 0 0 0-2.828l-6.758-6.758ZM9.172 2.414a4 4 0 0 1 5.656 0l6.758 6.758a4 4 0 0 1 0 5.656l-6.758 6.758a4 4 0 0 1-5.656 0l-6.758-6.758a4 4 0 0 1 0-5.656l6.758-6.758Z"
-                clipRule="evenodd"
-            />
-        </svg>
-    );
-}
-
-export function SocialIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={800}
-            height={800}
-            viewBox="0 0 1024 1024"
-            className="icon">
-            <path
-                fill="#FFB89A"
-                d="M570.2 842c-50.6 0-278.7-180-278.7-401.9 0-58.8-2.9-133.1-1-183.9-50.8 3.2-91.4 45.7-91.4 97.3v272.1c37.4 194.7 137.5 334 255.2 334 69.5 0 132.9-48.6 180.9-128.5-20.8 7.1-42.6 10.9-65 10.9z"
-            />
-            <path
-                fill="#4E5155"
-                d="M926.1 191.8C900.5 74.1 817.9 62.1 704.9 62.1c-29.1 0-60.3.8-93 .8-36 0-70.5-1.1-102.5-1.1-109.7 0-189.8 12.5-201.3 123.7-20.4 198.3 30 617.1 306.1 617.1S939 414.3 926.1 191.8zm-76.9 268.5c-9.5 47.9-22.3 90.8-38.1 127.7-16.8 39.2-37 71.4-60 95.8-37.3 39.5-82.1 58.7-137 58.7-53.4 0-97.6-20.1-134.9-61.6-45.5-50.5-79.8-131.5-99-234.2-15.6-83.5-20.3-178.9-12.4-255.2 1.8-17.3 5.7-30.7 11.6-39.8 4.4-6.8 10.1-11.7 18.7-15.8 25.8-12.5 70.8-14.2 111.4-14.2 15 0 30.7.2 47.3.5 17 [...]
-            />
-            <path
-                fill="#4E5155"
-                d="M532 841.7c-32.5 22.3-70.6 33.7-113.2 33.7-29.7 0-57.3-6-82.1-17.7-23.2-11-44.7-27.4-63.9-48.7-46-50.9-80.3-131.3-99.2-232.4-15.1-80.6-19.6-172.9-12-246.8 3-29.5 12-50.2 27.5-63.2 14.2-12 35.1-19.2 65.8-22.9 16.5-2 28.2-16.9 26.3-33.3-2-16.5-16.9-28.2-33.3-26.3-42.9 5.1-73.8 16.7-97.4 36.5-27.9 23.5-43.8 57.2-48.5 103-8.2 79.3-3.4 178.1 12.7 264 9.7 51.9 23.4 99.4 40.6 141.2 19.8 48.1 44.4 88.6 73 120.4 51.6 57.2 115.7 86.2 190.6 86.2 55 0 104.5-14.9 147.2-44.2 13.7-9. [...]
-            />
-            <path
-                fill="#3C9"
-                d="M519.7 248.5c-16.6 0-30 13.4-30 30v91.3c0 16.6 13.4 30 30 30s30-13.4 30-30v-91.3c0-16.6-13.5-30-30-30zm-220.2 137c0-16.6-13.4-30-30-30s-30 13.4-30 30v91.3c0 16.6 13.4 30 30 30s30-13.4 30-30v-91.3zm455.1-137c-16.6 0-30 13.4-30 30v91.3c0 16.6 13.4 30 30 30s30-13.4 30-30v-91.3c0-16.6-13.4-30-30-30zm-37.9 306c0-16.6-13.4-30-30-30H551v30c0 58.5 38.1 123.7 92.8 123.7 22.9 0 45-11.9 62.2-33.6 10.3-13 8.1-31.9-4.9-42.1-13-10.3-31.9-8.1-42.1 4.9-5.3 6.7-11.1 10.9-15.1 10.9-4.3  [...]
-            />
-        </svg>
-    );
-}
-
-export function DebeziumIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            xmlnsXlink="http://www.w3.org/1999/xlink"
-            viewBox="0 0 130.93 130.93"
-            className="icon">
-            <defs>
-                <linearGradient
-                    id="linear-gradient"
-                    x1={19.74}
-                    x2={114.03}
-                    y1={19.73}
-                    y2={114.02}
-                    gradientUnits="userSpaceOnUse"
-                >
-                    <stop offset={0} stopColor="#91d443"/>
-                    <stop offset={1} stopColor="#48bfe0"/>
-                </linearGradient>
-                <linearGradient
-                    xlinkHref="#linear-gradient"
-                    id="linear-gradient-2"
-                    x1={43.19}
-                    x2={137.48}
-                    y1={-3.72}
-                    y2={90.57}
-                />
-                <linearGradient
-                    xlinkHref="#linear-gradient"
-                    id="linear-gradient-3"
-                    x1={66.56}
-                    x2={160.85}
-                    y1={-27.09}
-                    y2={67.2}
-                />
-                <linearGradient
-                    xlinkHref="#linear-gradient"
-                    id="linear-gradient-4"
-                    x1={-3.72}
-                    x2={90.57}
-                    y1={43.18}
-                    y2={137.47}
-                />
-                <linearGradient
-                    xlinkHref="#linear-gradient"
-                    id="linear-gradient-5"
-                    x1={-27.09}
-                    x2={67.2}
-                    y1={66.55}
-                    y2={160.84}
-                />
-                <style>{".cls-1{fill:#fff}"}</style>
-            </defs>
-            <g id="Layer_1" data-name="Layer 1">
-                <path
-                    d="M93.79 114.29a16.65 16.65 0 0 0 16.63 16.63h20.53v-20.53a16.65 16.65 0 0 0-16.63-16.63h-3.91A26.39 26.39 0 0 1 84 67.4v-3.89a16.65 16.65 0 0 0-16.59-16.62h-3.9a26.39 26.39 0 0 1-26.35-26.37v-3.9A16.65 16.65 0 0 0 20.53 0H0v20.52a16.65 16.65 0 0 0 16.63 16.63h3.91A26.39 26.39 0 0 1 46.9 63.51v3.89A16.65 16.65 0 0 0 63.53 84h3.9a26.39 26.39 0 0 1 26.36 26.36Z"
-                    style={{
-                        fill: "url(#linear-gradient)",
-                    }}
-                />
-                <path
-                    d="M130.94 63.51a16.65 16.65 0 0 0-16.63-16.63h-3.91A26.39 26.39 0 0 1 84 20.52v-3.9A16.65 16.65 0 0 0 67.41 0H46.9v20.75a16.64 16.64 0 0 0 16.62 16.4h3.91a26.39 26.39 0 0 1 26.36 26.36v3.89A16.65 16.65 0 0 0 110.36 84h20.58Z"
-                    style={{
-                        fill: "url(#linear-gradient-2)",
-                    }}
-                />
-                <path
-                    d="M130.94 16.49A16.63 16.63 0 0 0 115 0H93.47v20.7a16.64 16.64 0 0 0 16.62 16.44h20.85Z"
-                    style={{
-                        fill: "url(#linear-gradient-3)",
-                    }}
-                />
-                <path
-                    d="M0 67.44a16.65 16.65 0 0 0 16.64 16.62h3.91a26.39 26.39 0 0 1 26.36 26.36v3.89a16.65 16.65 0 0 0 16.63 16.63H84v-20.75A16.64 16.64 0 0 0 67.43 93.8h-3.9a26.39 26.39 0 0 1-26.37-26.36v-3.9a16.65 16.65 0 0 0-16.57-16.63H0Z"
-                    style={{
-                        fill: "url(#linear-gradient-4)",
-                    }}
-                />
-                <path
-                    d="M0 114.45a16.63 16.63 0 0 0 16 16.5h21.48v-20.71A16.64 16.64 0 0 0 20.86 93.8H0Z"
-                    style={{
-                        fill: "url(#linear-gradient-5)",
-                    }}
-                />
-            </g>
-        </svg>
-    );
-}
-
-export function IgniteIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={48}
-            height={48}
-            fill="none"
-            viewBox="0 0 48 48"
-            className="icon">
-            <path
-                fill="#ED1C24"
-                d="M7.686 8.136S-8.95 18.28 6.73 28.355c3.016 1.962 13.956 7.418 13.644 12.466 0 0 6.631-9.81-3.064-15.983C7.351 18.52 4.862 11.772 7.686 8.135Z"
-            />
-            <path
-                fill="#ED1C24"
-                d="M1.893 27.517s-5.936 8.997 5.745 10.84c1.15.144 9.6 1.029 11.802 3.804 0 0-.192-4.785-7.086-7.609-6.87-2.823-9.695-3.517-10.46-7.035Zm22.981-9.451C17.74 10.6 15.754 5.982 18.818 0c0 0-21.281 8.183-.264 22.708 7.517 5.192 6.272 10.504 6.272 10.696 1.173-1.22 7.181-7.873.048-15.338Z"
-            />
-        </svg>
-    );
-}
-
-export function HazelcastIcon() {
-    return (
-        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 133.3 133.3" className="icon">
-            <defs>
-                <style>{".a{fill:#00e1e1}"}</style>
-            </defs>
-            <path
-                d="M133.3 92.85h-.38c-6.07 0-12.48-6.42-12.48-12.49V80h-.93v.38c0 6.07-6.42 12.49-12.49 12.49h-.38v.93h.36c6.07 0 12.49 6.41 12.49 12.48v.38h.93v-.38c0-6.07 6.41-12.48 12.48-12.48h.38v-.93ZM26.66 12.86h-.38C20.21 12.86 13.8 6.45 13.8.38V0h-.94v.38c0 6.07-6.41 12.48-12.48 12.48H0v.94h.38c6.07 0 12.48 6.41 12.48 12.48v.38h.94v-.38c0-6.07 6.41-12.48 12.48-12.48h.38v-.94Z"
-                className="a"
-            />
-            <path
-                d="M26.66 39.53h-.38c-6.07 0-12.48-6.42-12.48-12.53v-.38h-.94V27c0 6.07-6.41 12.49-12.48 12.49H0v.93h.38c6.07 0 12.48 6.41 12.48 12.48v.38h.94v-.38c0-6.07 6.41-12.48 12.48-12.48h.38v-.93Z"
-                className="a"
-            />
-            <path
-                d="M53.32 39.53h-.38c-6.07 0-12.48-6.42-12.48-12.49v-.38h-.94V27c0 6.07-6.41 12.49-12.48 12.49h-.38v.93H27c6.07 0 12.48 6.41 12.48 12.48v.38h.94v-.38c0-6.07 6.41-12.48 12.48-12.48h.38v-.93ZM26.66 66.19h-.38c-6.07 0-12.48-6.42-12.48-12.49v-.38h-.94v.38c0 6.07-6.41 12.49-12.48 12.49H0v.93h.38c6.07 0 12.48 6.41 12.48 12.48v.4h.94v-.4c0-6.07 6.41-12.48 12.48-12.48h.38v-.93Z"
-                className="a"
-            />
-            <path
-                d="M53.32 66.19h-.38c-6.07 0-12.48-6.42-12.48-12.49v-.38h-.94v.38c0 6.07-6.41 12.49-12.48 12.49h-.38v.93H27c6.07 0 12.48 6.41 12.48 12.48v.4h.94v-.4c0-6.07 6.41-12.48 12.48-12.48h.38v-.93Z"
-                className="a"
-            />
-            <path
-                d="M80 66.19h-.4c-6.07 0-12.48-6.42-12.48-12.49v-.38h-.94v.38c0 6.07-6.41 12.49-12.48 12.49h-.38v.93h.38c6.07 0 12.48 6.41 12.48 12.48v.4h.94v-.4c0-6.07 6.41-12.48 12.48-12.48h.4v-.93ZM26.66 92.85h-.38c-6.07 0-12.48-6.42-12.48-12.49V80h-.94v.38c0 6.07-6.41 12.49-12.48 12.49H0v.93h.38c6.07 0 12.48 6.41 12.48 12.48v.38h.94v-.38c0-6.07 6.41-12.48 12.48-12.48h.38v-.93Z"
-                className="a"
-            />
-            <path
-                d="M53.32 92.85h-.38c-6.07 0-12.48-6.42-12.48-12.49V80h-.94v.38c0 6.07-6.41 12.49-12.48 12.49h-.38v.93H27c6.07 0 12.48 6.41 12.48 12.48v.38h.94v-.38c0-6.07 6.41-12.48 12.48-12.48h.38v-.93ZM106.64 39.53h-.38c-6.07 0-12.48-6.42-12.48-12.49v-.38h-.93V27c0 6.07-6.42 12.49-12.49 12.49H80v.93h.38c6.07 0 12.49 6.41 12.49 12.48v.38h.93v-.38c0-6.07 6.41-12.48 12.48-12.48h.38v-.93ZM106.64 66.19h-.38c-6.07 0-12.48-6.42-12.48-12.49v-.38h-.93v.38c0 6.07-6.42 12.49-12.49 12.49H80v.93h. [...]
-                className="a"
-            />
-            <path
-                d="M106.64 92.85h-.38c-6.07 0-12.48-6.42-12.48-12.49V80h-.93v.38c0 6.07-6.42 12.49-12.49 12.49H80v.93h.38c6.07 0 12.49 6.41 12.49 12.48v.38h.93v-.38c0-6.07 6.41-12.48 12.48-12.48h.38v-.93ZM133.3 39.53h-.38c-6.07 0-12.48-6.42-12.48-12.49v-.38h-.93V27c0 6.07-6.42 12.49-12.49 12.49h-.38v.93h.36c6.07 0 12.49 6.41 12.49 12.48v.38h.93v-.38c0-6.07 6.41-12.48 12.48-12.48h.38v-.93ZM133.3 12.86h-.38c-6.07 0-12.48-6.41-12.48-12.48V0h-.93v.38c0 6.07-6.42 12.48-12.49 12.48h-.38v.94h.3 [...]
-                className="a"
-            />
-        </svg>
-    );
-}
-
-export function AzureIcon() {
-    return (
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width={150}
-            height={150}
-            viewBox="0 0 96 96"
-            className="icon">
-            <defs>
-                <linearGradient
-                    id="a"
-                    x1={-1032.172}
-                    x2={-1059.213}
-                    y1={145.312}
-                    y2={65.426}
-                    gradientTransform="matrix(1 0 0 -1 1075 158)"
-                    gradientUnits="userSpaceOnUse"
-                >
-                    <stop offset={0} stopColor="#114a8b"/>
-                    <stop offset={1} stopColor="#0669bc"/>
-                </linearGradient>
-                <linearGradient
-                    id="b"
-                    x1={-1023.725}
-                    x2={-1029.98}
-                    y1={108.083}
-                    y2={105.968}
-                    gradientTransform="matrix(1 0 0 -1 1075 158)"
-                    gradientUnits="userSpaceOnUse"
-                >
-                    <stop offset={0} stopOpacity={0.3}/>
-                    <stop offset={0.071} stopOpacity={0.2}/>
-                    <stop offset={0.321} stopOpacity={0.1}/>
-                    <stop offset={0.623} stopOpacity={0.05}/>
-                    <stop offset={1} stopOpacity={0}/>
-                </linearGradient>
-                <linearGradient
-                    id="c"
-                    x1={-1027.165}
-                    x2={-997.482}
-                    y1={147.642}
-                    y2={68.561}
-                    gradientTransform="matrix(1 0 0 -1 1075 158)"
-                    gradientUnits="userSpaceOnUse"
-                >
-                    <stop offset={0} stopColor="#3ccbf4"/>
-                    <stop offset={1} stopColor="#2892df"/>
-                </linearGradient>
-            </defs>
-            <path
-                fill="url(#a)"
-                d="M33.338 6.544h26.038l-27.03 80.087a4.152 4.152 0 0 1-3.933 2.824H8.149a4.145 4.145 0 0 1-3.928-5.47L29.404 9.368a4.152 4.152 0 0 1 3.934-2.825z"
-            />
-            <path
-                fill="#0078d4"
-                d="M71.175 60.261h-41.29a1.911 1.911 0 0 0-1.305 3.309l26.532 24.764a4.171 4.171 0 0 0 2.846 1.121h23.38z"
-            />
-            <path
-                fill="url(#b)"
-                d="M33.338 6.544a4.118 4.118 0 0 0-3.943 2.879L4.252 83.917a4.14 4.14 0 0 0 3.908 5.538h20.787a4.443 4.443 0 0 0 3.41-2.9l5.014-14.777 17.91 16.705a4.237 4.237 0 0 0 2.666.972H81.24L71.024 60.261l-29.781.007L59.47 6.544z"
-            />
-            <path
-                fill="url(#c)"
-                d="M66.595 9.364a4.145 4.145 0 0 0-3.928-2.82H33.648a4.146 4.146 0 0 1 3.928 2.82l25.184 74.62a4.146 4.146 0 0 1-3.928 5.472h29.02a4.146 4.146 0 0 0 3.927-5.472z"
-            />
-        </svg>
-    );
-}
-
-
diff --git a/karavan-space/src/expression/ExpressionBottomPanel.tsx b/karavan-space/src/expression/ExpressionBottomPanel.tsx
new file mode 100644
index 00000000..4aef03a4
--- /dev/null
+++ b/karavan-space/src/expression/ExpressionBottomPanel.tsx
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React from 'react';
+import {ClipboardCopy, Text, TextContent} from '@patternfly/react-core';
+import './ExpressionModalEditor.css'
+import {Table, Tbody, Td, Tr} from "@patternfly/react-table";
+import {Context, ExpressionFunctions, ExpressionVariables} from "./ExpressionContextModel";
+
+interface Props {
+    dslLanguage?: [string, string, string],
+}
+
+export function ExpressionBottomPanel(props: Props) {
+
+    const {dslLanguage} = props;
+    const language = dslLanguage?.[0];
+    const vars: Context[] = ExpressionVariables.filter(e => e.name === language)?.[0]?.information || [];
+    const funcs: Context[] = ExpressionFunctions.filter(e => e.name === language)?.at(0)?.information || []
+    const showVars = vars.length > 0;
+    const showFuncs = funcs.length > 0;
+
+    function getRows(data: Context[]) {
+        return (
+            data?.map((context, index, array) =>
+                <Tr key={index} style={{padding: '0'}}>
+                    <Td style={{padding: '0px 0px 6px 0px'}} modifier='fitContent'>
+                        <ClipboardCopy key={index} hoverTip="Copy" clickTip="Copied"
+                                       variant="inline-compact">
+                            {context.key}
+                        </ClipboardCopy>
+                    </Td>
+                    <Td style={{padding: '0px 0px 0px 16px'}}>
+                        {context.value}
+                    </Td>
+                </Tr>
+            )
+        )
+    }
+
+    function getRowHeader(data: string) {
+        return (
+            <Tr key='vars' style={{padding: '0'}}>
+                <Td style={{padding: '16px 6px 6px 0px'}}>
+                    <TextContent>
+                        <Text component='h3'>{data}</Text>
+                    </TextContent>
+                </Td>
+            </Tr>
+        )
+    }
+
+    return (
+        <div className='context'>
+            <div className='context-column'>
+                <Table variant='compact' borders={false}>
+                    <Tbody>
+                        {showVars && getRowHeader('Variables')}
+                        {showVars && getRows(vars)}
+                        {showFuncs && getRowHeader('Functions')}
+                        {showFuncs && getRows(funcs)}
+                    </Tbody>
+                </Table>
+            </div>
+        </div>
+    )
+}
diff --git a/karavan-space/src/expression/ExpressionContextModel.tsx b/karavan-space/src/expression/ExpressionContextModel.tsx
new file mode 100644
index 00000000..3f0a3411
--- /dev/null
+++ b/karavan-space/src/expression/ExpressionContextModel.tsx
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export class ExpressionContext {
+    name: string = '';
+    information: Context[] = [];
+
+    constructor(name: string, information: Context[]) {
+        this.name = name;
+        this.information = information;
+    }
+}
+
+export class Context {
+    key: string = '';
+    value: string = '';
+
+    constructor(key: string, value: string) {
+        this.key = key;
+        this.value = value;
+    }
+}
+
+export const ExpressionVariables: ExpressionContext[] = [
+    new ExpressionContext('groovy', [
+            new Context('exchange', 'The Exchange itself.'),
+            new Context('exchangeProperties', 'The Exchange properties.'),
+            new Context('variables', 'The variables'),
+            new Context('headers', 'The headers of the In message.'),
+            new Context('camelContext', 'The Camel Context.'),
+            new Context('request', 'The In message.'),
+            new Context('body', 'The message body'),
+            new Context('response', 'The Out message (only for InOut message exchange pattern).')
+        ]
+    ),
+    new ExpressionContext('java', [
+            new Context('exchange', 'The Exchange itself.'),
+            new Context('message', 'The Camel message.'),
+            new Context('context', 'The Camel Context.'),
+            new Context('body', 'The message body')
+        ]
+    ),
+    new ExpressionContext('javascript', [
+            new Context('this', 'the Exchange is the root object.'),
+            new Context('context', 'The Camel Context.'),
+            new Context('exchange', 'The Exchange itself.'),
+            new Context('exchangeId', 'The ExchangeID.'),
+            new Context('message', 'The Camel message.'),
+            new Context('body', 'The message body'),
+            new Context('headers', 'The message headers'),
+            new Context('properties', 'The message properties')
+        ]
+    ),
+    new ExpressionContext('jq', [
+            new Context('header', 'Allow accessing the Message header ex. header(\\"MyHeader\\")'),
+            new Context('property', 'Allow accessing the Message property ex. property(\\"MyProperty\\")'),
+            new Context('constant', 'Allow accessing constant value as-is '),
+
+        ]
+    ),
+    new ExpressionContext('simple', [
+            new Context('camelId', 'the CamelContext name'),
+            new Context('camelContext.*OGNL*', 'the CamelContext invoked using a Camel OGNL expression.'),
+            new Context('exchange', 'the Exchange'),
+            new Context('exchange.*OGNL*', 'the Exchange invoked using a Camel OGNL expression.'),
+            new Context('exchangeId', 'the exchange id'),
+            new Context('id', 'the message id'),
+            new Context('messageTimestamp', 'the message timestamp (millis since epoc) that this message originates from.'),
+            new Context('body ', 'the body'),
+            new Context('body.*OGNL*', 'the body invoked using a Camel OGNL expression.'),
+            new Context('bodyAs(_type_)', 'Converts the body to the given type determined by its classname. The converted body can be null.'),
+            new Context('bodyAs(_type_).*OGNL* ', 'Converts the body to the given type determined by its classname and then invoke methods using a Camel OGNL expression. The converted body can be null.'),
+            new Context('bodyOneLine', 'Converts the body to a String and removes all line-breaks so the string is in one line.'),
+            new Context('prettyBody', 'Converts the body to a String, and attempts to pretty print if JSon or XML, otherwise the body is returned as the String value.'),
+            new Context('originalBody', 'The original incoming body (only available if allowUseOriginalMessage=true).'),
+            new Context('mandatoryBodyAs(_type_)', 'Converts the body to the given type determined by its classname, and expects the body to be not null.'),
+            new Context('mandatoryBodyAs(_type_).*OGNL* ', 'Converts the body to the given type determined by its classname and then invoke methods using a Camel OGNL expression.'),
+            new Context('header.foo ', 'refer to the foo header'),
+            new Context('header[foo] ', 'refer to the foo header'),
+            new Context('headers.foo ', 'refer to the foo header'),
+            new Context('headers:foo ', 'refer to the foo header'),
+            new Context('headers[foo] ', 'refer to the foo header'),
+            new Context('header.foo[bar] ', 'regard foo header as a map and perform lookup on the map with bar as key'),
+            new Context('header.foo.*OGNL*', 'refer to the foo header and invoke its value using a Camel OGNL expression.'),
+            new Context('headerAs(_key_,_type_)', 'converts the header to the given type determined by its classname'),
+            new Context('headers', 'refer to the headers'),
+            new Context('variable.foo ', 'refer to the foo variable'),
+            new Context('variable[foo] ', 'refer to the foo variable'),
+            new Context('variable.foo.*OGNL* ', 'refer to the foo variable and invoke its value using a Camel OGNL expression.'),
+            new Context('variableAs(_key_,_type_)', 'converts the variable to the given type determined by its classname'),
+            new Context('variables', 'refer to the variables'),
+            new Context('exchangeProperty.foo ', 'refer to the foo property on the exchange'),
+            new Context('exchangeProperty[foo] ', 'refer to the foo property on the exchange'),
+            new Context('exchangeProperty.foo.*OGNL* ', 'refer to the foo property on the exchange and invoke its value using a Camel OGNL expression.'),
+            new Context('messageAs(_type_)', 'Converts the message to the given type determined by its classname. The converted message can be null. '),
+            new Context('messageAs(_type_).*OGNL* ', 'Converts the message to the given type determined by its classname and then invoke methods using a Camel OGNL expression. The converted message can be null. '),
+            new Context('sys.foo', 'refer to the JVM system property'),
+            new Context('sysenv.foo', 'refer to the system environment variable'),
+            new Context('env.foo', 'refer to the system environment variable'),
+            new Context('exception ', 'refer to the exception object on the exchange, is *null* if no exception set on exchange. Will fallback and grab caught exceptions (`Exchange.EXCEPTION_CAUGHT`) if the Exchange has any.'),
+            new Context('exception.*OGNL* ', 'refer to the exchange exception invoked using a Camel OGNL expression object'),
+            new Context('exception.message', 'refer to the exception.message on the exchange, is *null* if no exception set on exchange. Will fallback and grab caught exceptions (`Exchange.EXCEPTION_CAUGHT`) if the Exchange has any.'),
+            new Context('exception.stacktrace', 'refer to the exception.stracktrace on the exchange, is  *null* if no exception set on exchange. Will fallback and grab caught exceptions (`Exchange.EXCEPTION_CAUGHT`) if the Exchange has any.'),
+            new Context('date:_command_', `evaluates to a Date object. Supported commands are: *now* for current timestamp,
+*exchangeCreated* for the timestamp when the current exchange was created,
+*header.xxx* to use the Long/Date object in the header with the key xxx.
+*variable.xxx* to use the Long/Date in the variable with the key xxx.
+*exchangeProperty.xxx* to use the Long/Date object in the exchange property with the key xxx.
+*file* for the last modified timestamp of the file (available with a File consumer).
+Command accepts offsets such as: *now-24h* or *header.xxx+1h* or even *now+1h30m-100*.`),
+            new Context('date:_command:pattern_', 'Date formatting using `java.text.SimpleDateFormat` patterns.'),
+            new Context('date-with-timezone:_command:timezone:pattern_', 'Date formatting using `java.text.SimpleDateFormat` timezones and patterns.'),
+            new Context('bean:_bean expression_ ', `Invoking a bean expression using the xref:components::bean-component.adoc[Bean] language.'),
+Specifying a method name you must use dot as separator. We also support
+the ?method=methodname syntax that is used by the xref:components::bean-component.adoc[Bean]
+component. Camel will by default lookup a bean by the given name. However if you need to refer
+to a bean class (such as calling a static method) then you can prefix with type, such as 'bean:type:fqnClassName'. `),
+            new Context('properties:key:default', 'Lookup a property with the given key. If the key does not exists or has no value, then an optional default value can be specified.'),
+            new Context('propertiesExist:key', 'Checks whether a property placeholder with the given key exists or not. The result can be negated by prefixing the key with `!`.'),
+            new Context('routeId', 'Returns the route id of the current route the Exchange is being routed.'),
+            new Context('routeGroup', 'Returns the route group of the current route the Exchange is being routed. Not all routes has a group assigned, so this may be null.'),
+            new Context('stepId', 'Returns the id of the current step the Exchange is being routed.'),
+            new Context('threadId', 'Returns the id of the current thread. Can be used for logging purpose.'),
+            new Context('threadName', 'Returns the name of the current thread. Can be used for logging purpose.'),
+            new Context('hostname', 'Returns the local hostname (may be empty if not possible to resolve).'),
+            new Context('ref:xxx ', 'To lookup a bean from the Registry with the given id.'),
+            new Context('type:name.field ', 'To refer to a type or field by its FQN name. To refer to a field you can append .FIELD_NAME. For example, you can refer to the constant field from Exchange as: `org.apache.camel.Exchange.FILE_NAME`'),
+            new Context('empty(type)', `Creates a new empty object of the type given as parameter. The type-parameter-Strings are case-insensitive. +
+'string' -> empty String
+'list'   -> empty ArrayList 
+'map'    -> empty HashMap `),
+            new Context('null', 'represents a *null*'),
+            new Context('random(value)', 'returns a random Integer between 0 (included) and _value_ (excluded)'),
+            new Context('random(min,max)', 'returns a random Integer between _min_ (included) and _max_ (excluded)'),
+            new Context('collate(group)', `The collate function iterates the message body and groups
+the data into sub lists of specified size. This can be used with the
+Splitter EIP to split a message body and group/batch
+the split sub message into a group of N sub lists. This method works
+similar to the collate method in Groovy.`),
+            new Context('skip(number)', ' The skip function iterates the message body and skips the first number of items. This can be used with the Splitter EIP to split a message body and skip the first N number of items.'),
+            new Context('join(separator,prefix,exp)', `The join function iterates the message body (by default) and joins the data into a string. The separator is by default a comma. The prefix is optional.'),
+
+The join uses the message body as source by default. It is possible to refer to another
+source (simple language) such as a header via the exp parameter. For example join('&','id=','$\{header.ids}')`),
+            new Context('messageHistory', 'The message history of the current exchange how it has been routed. This is similar to the route stack-trace message history the error handler logs in case of an unhandled exception.'),
+            new Context('messageHistory(false)', 'As messageHistory but without the exchange details (only includes the route stack-trace). This can be used if you do not want to log sensitive data from the message itself.'),
+            new Context('uuid(type)', 'Returns an UUID using the Camel `UuidGenerator`. You can choose between `default`, `classic`, `short` and `simple` as the type. If no type is given the default is used. It is also possible to use a custom `UuidGenerator` and bind the bean to the xref:manual::registry.adoc[Registry] with an id. For example `${uuid(myGenerator}` where the ID is _myGenerator_.'),
+            new Context('hash(exp,algorithm)', 'Returns a hashed value (string in hex decimal) using JDK MessageDigest. The algorithm can be SHA-256 (default) or SHA3-256.'),
+            new Context('jsonpath(exp)', 'When working with JSon data, then this allows to use the JsonPath language for example to extract data from the message body (in JSon format). This requires having camel-jsonpath JAR on the classpath.'),
+            new Context('jsonpath(input,exp)', 'When working with JSon data, then this allows to use the JsonPath language for example to extract data from the message body (in JSon format). This requires having camel-jsonpath JAR on the classpath. For _input_ you can choose `header:key`, `exchangeProperty:key` or `variable:key` to use as input for the JSon payload instead of the message body.'),
+            new Context('jq(exp)', 'When working with JSon data, then this allows to use the JQ language for example to extract data from the message body (in JSon format). This requires having camel-jq JAR on the classpath.'),
+            new Context('jq(input,exp)', 'When working with JSon data, then this allows to use the JQ language for example to extract data from the message body (in JSon format). This requires having camel-jq JAR on the classpath. For _input_ you can choose `header:key`, `exchangeProperty:key` or `variable:key` to use as input for the JSon payload instead of the message body.'),
+            new Context('xpath(exp)', 'When working with XML data, then this allows to use the XPath language for example to extract data from the message body (in XML format). This requires having camel-xpath JAR on the classpath.'),
+            new Context('xpath(input,exp)', 'When working with XML data, then this allows to use the XPath language for example to extract data from the message body (in XML format). This requires having camel-xpath JAR on the classpath. For _input_ you can choose `header:key`, `exchangeProperty:key` or `variable:key` to use as input for the JSon payload instead of the message body.'),
+            new Context('pretty(exp)', 'Converts the inlined expression to a String, and attempts to pretty print if JSon or XML, otherwise the expression is returned as the String value.'),
+        ]
+    )
+]
+
+export const ExpressionFunctions: ExpressionContext[] = [
+    new ExpressionContext('java', [
+            new Context('bodyAs(type)', 'To convert the body to the given type'),
+            new Context('headerAs(name, type)', 'To convert the header with the name to the given type.'),
+            new Context('headerAs(name, defaultValue, type)', 'To convert the header with the name to the given type. If no header exists, then use the given default value.'),
+            new Context('exchangePropertyAs(name, type)', 'To convert the exchange property with the name to the given type.'),
+            new Context('exchangePropertyAs(name, defaultValue, type)', 'To convert the exchange property with the name to the given type. If no exchange property exists, then use the given default value.'),
+            new Context('optionalBodyAs(type)', 'To convert the body to the given type, returned wrapped in java.util.Optional.'),
+            new Context('optionalHeaderAs(name, type)', 'To convert the header with the name to the given type, returned wrapped in java.util.Optional.'),
+            new Context('optionalExchangePropertyAs(name, type)', 'To convert the exchange property with the name to the given type, returned wrapped in java.util.Optional.')
+        ]
+    ),
+    new ExpressionContext('xpath', [
+            new Context('in:body', 'Will return the message body.'),
+            new Context('in:header', 'Will return the message header.'),
+            new Context('function:properties', 'To use a Property Placeholder.'),
+            new Context('function:simple', 'To evaluate a Simple language.'),
+        ]
+    )
+]
diff --git a/karavan-space/src/designer/utils/KubernetesAPI.ts b/karavan-space/src/expression/ExpressionModalEditor.css
similarity index 52%
rename from karavan-space/src/designer/utils/KubernetesAPI.ts
rename to karavan-space/src/expression/ExpressionModalEditor.css
index eeb225cf..732d3abd 100644
--- a/karavan-space/src/designer/utils/KubernetesAPI.ts
+++ b/karavan-space/src/expression/ExpressionModalEditor.css
@@ -14,23 +14,55 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+.expression-modal {
+    height: 80%;
+}
 
-export class KubernetesAPI {
+.container {
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    gap: 16px;
+    justify-content: space-between;
+    align-items: stretch;
+}
 
-    static inKubernetes: boolean = false;
-    static configMaps: string[] = [];
-    static secrets: string[] = [];
-    static services: string[] = [];
+.panel-top {
+    flex: 1;
+    height: 100%;
+    border: 1px solid lightgray;
+}
 
-    static setConfigMaps(configMaps: string[]){
-        this.configMaps = configMaps
-    }
+.panel-middle {
+    /*height: 64px;*/
+}
 
-    static setSecrets(secrets: string[]){
-        this.secrets = secrets
-    }
+.panel-bottom {
+    flex: 1;
+    height: 100%;
+    overflow-y: auto;
+}
 
-    static setServices(services: string[]){
-        this.services = services
-    }
+.context {
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+    gap: 64px;
+}
+
+.context-column {
+    flex: 1;
+}
+
+.context-column-right {
+    margin-left: 12px;
+}
+
+.context-column .pf-v5-c-clipboard-copy.pf-m-inline {
+    display: flex;
+    width: fit-content;
+}
+
+.context-column .pf-v5-c-clipboard-copy__text{
+    white-space: nowrap;
 }
\ No newline at end of file
diff --git a/karavan-app/src/main/webui/src/designer/property/property/ModalEditor.tsx b/karavan-space/src/expression/ExpressionModalEditor.tsx
similarity index 56%
rename from karavan-app/src/main/webui/src/designer/property/property/ModalEditor.tsx
rename to karavan-space/src/expression/ExpressionModalEditor.tsx
index d3df2a27..3a96ce7a 100644
--- a/karavan-app/src/main/webui/src/designer/property/property/ModalEditor.tsx
+++ b/karavan-space/src/expression/ExpressionModalEditor.tsx
@@ -16,13 +16,12 @@
  */
 import React, {useEffect, useState} from 'react';
 import {
-    Button,
-    Modal,
-    ModalVariant, Title, TitleSizes
+    Button, Modal, Title, TitleSizes
 } from '@patternfly/react-core';
-import '../../karavan.css';
-import "@patternfly/patternfly/patternfly.css";
 import Editor from "@monaco-editor/react";
+import {ExpressionBottomPanel} from "./ExpressionBottomPanel";
+import './ExpressionModalEditor.css'
+import {Context, ExpressionFunctions, ExpressionVariables} from "./ExpressionContextModel";
 
 interface Props {
     name: string,
@@ -35,11 +34,12 @@ interface Props {
     showEditor: boolean
 }
 
-export function ModalEditor(props: Props) {
+export function ExpressionModalEditor(props: Props) {
 
     const [customCode, setCustomCode] = useState<string | undefined>();
 
     useEffect(() => {
+        console.log(title, dslLanguage)
         setCustomCode(props.customCode)
     },[]);
 
@@ -52,10 +52,16 @@ export function ModalEditor(props: Props) {
     }
 
     const {dark, dslLanguage, title, showEditor} = props;
+    const language = dslLanguage?.[0];
+    const showVars = ExpressionVariables.findIndex(e => e.name === language) > - 1;
+    const showFuncs = ExpressionFunctions.findIndex(e => e.name === language) > - 1;
+    const show = showVars || showFuncs;
+
     return (
         <Modal
-            aria-label={"expression"}
-            variant={ModalVariant.large}
+            aria-label="Expression"
+            className='expression-modal'
+            width={"80%"}
             header={<React.Fragment>
                 <Title id="modal-custom-header-label" headingLevel="h1" size={TitleSizes['2xl']}>
                     {title}
@@ -71,17 +77,31 @@ export function ModalEditor(props: Props) {
                         onClick={e => close()}>Close</Button>
             ]}
             onEscapePress={e => close()}>
-            <Editor
-                height="400px"
-                width="100%"
-                defaultLanguage={'java'}
-                language={'java'}
-                theme={dark ? 'vs-dark' : 'light'}
-                options={{lineNumbers: "off", folding: false, lineNumbersMinChars: 10, showUnused: false, fontSize: 12, minimap: {enabled: false}}}
-                value={customCode?.toString()}
-                className={'code-editor'}
-                onChange={(value,_) => setCustomCode(value)}
-            />
+            <div className='container'>
+                <div className='panel-top'>
+                    <Editor
+                        height="50%"
+                        width="100%"
+                        defaultLanguage={'java'}
+                        language={'java'}
+                        theme={dark ? 'vs-dark' : 'light'}
+                        options={{
+                            lineNumbers: "off",
+                            folding: false,
+                            lineNumbersMinChars: 10,
+                            showUnused: false,
+                            fontSize: 12,
+                            minimap: {enabled: false}
+                        }}
+                        value={customCode?.toString()}
+                        className={'code-editor'}
+                        onChange={(value, _) => setCustomCode(value)}
+                    />
+                </div>
+                {show && <div className='panel-bottom'>
+                    {dslLanguage && <ExpressionBottomPanel dslLanguage={dslLanguage}/>}
+                </div>}
+            </div>
         </Modal>
     )
 }
diff --git a/karavan-vscode/package.json b/karavan-vscode/package.json
index 5b1e0923..ba601ee4 100644
--- a/karavan-vscode/package.json
+++ b/karavan-vscode/package.json
@@ -721,7 +721,7 @@
   },
   "scripts": {
     "copy-core": "cp -r ../karavan-core/src/core webview",
-    "copy-designer": "cp -r ../karavan-designer/src/designer webview && cp -r ../karavan-designer/src/knowledgebase webview && cp -r ../karavan-designer/src/topology webview",
+    "copy-designer": "cp -r ../karavan-designer/src/designer webview && cp -r ../karavan-designer/src/expression webview && cp -r ../karavan-designer/src/knowledgebase webview && cp -r ../karavan-designer/src/topology webview",
     "replace-import": "run-script-os",
     "replace-import:darwin": "find webview -type f -name '*.ts*' -exec sed -i '' 's!karavan-core/lib!core!g' {} +",
     "replace-import:linux": "find webview -type f -name '*.ts*' -exec sed -i 's!karavan-core/lib!core!g' {} +",
diff --git a/karavan-vscode/webview/expression/ExpressionBottomPanel.tsx b/karavan-vscode/webview/expression/ExpressionBottomPanel.tsx
new file mode 100644
index 00000000..4aef03a4
--- /dev/null
+++ b/karavan-vscode/webview/expression/ExpressionBottomPanel.tsx
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React from 'react';
+import {ClipboardCopy, Text, TextContent} from '@patternfly/react-core';
+import './ExpressionModalEditor.css'
+import {Table, Tbody, Td, Tr} from "@patternfly/react-table";
+import {Context, ExpressionFunctions, ExpressionVariables} from "./ExpressionContextModel";
+
+interface Props {
+    dslLanguage?: [string, string, string],
+}
+
+export function ExpressionBottomPanel(props: Props) {
+
+    const {dslLanguage} = props;
+    const language = dslLanguage?.[0];
+    const vars: Context[] = ExpressionVariables.filter(e => e.name === language)?.[0]?.information || [];
+    const funcs: Context[] = ExpressionFunctions.filter(e => e.name === language)?.at(0)?.information || []
+    const showVars = vars.length > 0;
+    const showFuncs = funcs.length > 0;
+
+    function getRows(data: Context[]) {
+        return (
+            data?.map((context, index, array) =>
+                <Tr key={index} style={{padding: '0'}}>
+                    <Td style={{padding: '0px 0px 6px 0px'}} modifier='fitContent'>
+                        <ClipboardCopy key={index} hoverTip="Copy" clickTip="Copied"
+                                       variant="inline-compact">
+                            {context.key}
+                        </ClipboardCopy>
+                    </Td>
+                    <Td style={{padding: '0px 0px 0px 16px'}}>
+                        {context.value}
+                    </Td>
+                </Tr>
+            )
+        )
+    }
+
+    function getRowHeader(data: string) {
+        return (
+            <Tr key='vars' style={{padding: '0'}}>
+                <Td style={{padding: '16px 6px 6px 0px'}}>
+                    <TextContent>
+                        <Text component='h3'>{data}</Text>
+                    </TextContent>
+                </Td>
+            </Tr>
+        )
+    }
+
+    return (
+        <div className='context'>
+            <div className='context-column'>
+                <Table variant='compact' borders={false}>
+                    <Tbody>
+                        {showVars && getRowHeader('Variables')}
+                        {showVars && getRows(vars)}
+                        {showFuncs && getRowHeader('Functions')}
+                        {showFuncs && getRows(funcs)}
+                    </Tbody>
+                </Table>
+            </div>
+        </div>
+    )
+}
diff --git a/karavan-vscode/webview/expression/ExpressionContextModel.tsx b/karavan-vscode/webview/expression/ExpressionContextModel.tsx
new file mode 100644
index 00000000..3f0a3411
--- /dev/null
+++ b/karavan-vscode/webview/expression/ExpressionContextModel.tsx
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export class ExpressionContext {
+    name: string = '';
+    information: Context[] = [];
+
+    constructor(name: string, information: Context[]) {
+        this.name = name;
+        this.information = information;
+    }
+}
+
+export class Context {
+    key: string = '';
+    value: string = '';
+
+    constructor(key: string, value: string) {
+        this.key = key;
+        this.value = value;
+    }
+}
+
+export const ExpressionVariables: ExpressionContext[] = [
+    new ExpressionContext('groovy', [
+            new Context('exchange', 'The Exchange itself.'),
+            new Context('exchangeProperties', 'The Exchange properties.'),
+            new Context('variables', 'The variables'),
+            new Context('headers', 'The headers of the In message.'),
+            new Context('camelContext', 'The Camel Context.'),
+            new Context('request', 'The In message.'),
+            new Context('body', 'The message body'),
+            new Context('response', 'The Out message (only for InOut message exchange pattern).')
+        ]
+    ),
+    new ExpressionContext('java', [
+            new Context('exchange', 'The Exchange itself.'),
+            new Context('message', 'The Camel message.'),
+            new Context('context', 'The Camel Context.'),
+            new Context('body', 'The message body')
+        ]
+    ),
+    new ExpressionContext('javascript', [
+            new Context('this', 'the Exchange is the root object.'),
+            new Context('context', 'The Camel Context.'),
+            new Context('exchange', 'The Exchange itself.'),
+            new Context('exchangeId', 'The ExchangeID.'),
+            new Context('message', 'The Camel message.'),
+            new Context('body', 'The message body'),
+            new Context('headers', 'The message headers'),
+            new Context('properties', 'The message properties')
+        ]
+    ),
+    new ExpressionContext('jq', [
+            new Context('header', 'Allow accessing the Message header ex. header(\\"MyHeader\\")'),
+            new Context('property', 'Allow accessing the Message property ex. property(\\"MyProperty\\")'),
+            new Context('constant', 'Allow accessing constant value as-is '),
+
+        ]
+    ),
+    new ExpressionContext('simple', [
+            new Context('camelId', 'the CamelContext name'),
+            new Context('camelContext.*OGNL*', 'the CamelContext invoked using a Camel OGNL expression.'),
+            new Context('exchange', 'the Exchange'),
+            new Context('exchange.*OGNL*', 'the Exchange invoked using a Camel OGNL expression.'),
+            new Context('exchangeId', 'the exchange id'),
+            new Context('id', 'the message id'),
+            new Context('messageTimestamp', 'the message timestamp (millis since epoc) that this message originates from.'),
+            new Context('body ', 'the body'),
+            new Context('body.*OGNL*', 'the body invoked using a Camel OGNL expression.'),
+            new Context('bodyAs(_type_)', 'Converts the body to the given type determined by its classname. The converted body can be null.'),
+            new Context('bodyAs(_type_).*OGNL* ', 'Converts the body to the given type determined by its classname and then invoke methods using a Camel OGNL expression. The converted body can be null.'),
+            new Context('bodyOneLine', 'Converts the body to a String and removes all line-breaks so the string is in one line.'),
+            new Context('prettyBody', 'Converts the body to a String, and attempts to pretty print if JSon or XML, otherwise the body is returned as the String value.'),
+            new Context('originalBody', 'The original incoming body (only available if allowUseOriginalMessage=true).'),
+            new Context('mandatoryBodyAs(_type_)', 'Converts the body to the given type determined by its classname, and expects the body to be not null.'),
+            new Context('mandatoryBodyAs(_type_).*OGNL* ', 'Converts the body to the given type determined by its classname and then invoke methods using a Camel OGNL expression.'),
+            new Context('header.foo ', 'refer to the foo header'),
+            new Context('header[foo] ', 'refer to the foo header'),
+            new Context('headers.foo ', 'refer to the foo header'),
+            new Context('headers:foo ', 'refer to the foo header'),
+            new Context('headers[foo] ', 'refer to the foo header'),
+            new Context('header.foo[bar] ', 'regard foo header as a map and perform lookup on the map with bar as key'),
+            new Context('header.foo.*OGNL*', 'refer to the foo header and invoke its value using a Camel OGNL expression.'),
+            new Context('headerAs(_key_,_type_)', 'converts the header to the given type determined by its classname'),
+            new Context('headers', 'refer to the headers'),
+            new Context('variable.foo ', 'refer to the foo variable'),
+            new Context('variable[foo] ', 'refer to the foo variable'),
+            new Context('variable.foo.*OGNL* ', 'refer to the foo variable and invoke its value using a Camel OGNL expression.'),
+            new Context('variableAs(_key_,_type_)', 'converts the variable to the given type determined by its classname'),
+            new Context('variables', 'refer to the variables'),
+            new Context('exchangeProperty.foo ', 'refer to the foo property on the exchange'),
+            new Context('exchangeProperty[foo] ', 'refer to the foo property on the exchange'),
+            new Context('exchangeProperty.foo.*OGNL* ', 'refer to the foo property on the exchange and invoke its value using a Camel OGNL expression.'),
+            new Context('messageAs(_type_)', 'Converts the message to the given type determined by its classname. The converted message can be null. '),
+            new Context('messageAs(_type_).*OGNL* ', 'Converts the message to the given type determined by its classname and then invoke methods using a Camel OGNL expression. The converted message can be null. '),
+            new Context('sys.foo', 'refer to the JVM system property'),
+            new Context('sysenv.foo', 'refer to the system environment variable'),
+            new Context('env.foo', 'refer to the system environment variable'),
+            new Context('exception ', 'refer to the exception object on the exchange, is *null* if no exception set on exchange. Will fallback and grab caught exceptions (`Exchange.EXCEPTION_CAUGHT`) if the Exchange has any.'),
+            new Context('exception.*OGNL* ', 'refer to the exchange exception invoked using a Camel OGNL expression object'),
+            new Context('exception.message', 'refer to the exception.message on the exchange, is *null* if no exception set on exchange. Will fallback and grab caught exceptions (`Exchange.EXCEPTION_CAUGHT`) if the Exchange has any.'),
+            new Context('exception.stacktrace', 'refer to the exception.stracktrace on the exchange, is  *null* if no exception set on exchange. Will fallback and grab caught exceptions (`Exchange.EXCEPTION_CAUGHT`) if the Exchange has any.'),
+            new Context('date:_command_', `evaluates to a Date object. Supported commands are: *now* for current timestamp,
+*exchangeCreated* for the timestamp when the current exchange was created,
+*header.xxx* to use the Long/Date object in the header with the key xxx.
+*variable.xxx* to use the Long/Date in the variable with the key xxx.
+*exchangeProperty.xxx* to use the Long/Date object in the exchange property with the key xxx.
+*file* for the last modified timestamp of the file (available with a File consumer).
+Command accepts offsets such as: *now-24h* or *header.xxx+1h* or even *now+1h30m-100*.`),
+            new Context('date:_command:pattern_', 'Date formatting using `java.text.SimpleDateFormat` patterns.'),
+            new Context('date-with-timezone:_command:timezone:pattern_', 'Date formatting using `java.text.SimpleDateFormat` timezones and patterns.'),
+            new Context('bean:_bean expression_ ', `Invoking a bean expression using the xref:components::bean-component.adoc[Bean] language.'),
+Specifying a method name you must use dot as separator. We also support
+the ?method=methodname syntax that is used by the xref:components::bean-component.adoc[Bean]
+component. Camel will by default lookup a bean by the given name. However if you need to refer
+to a bean class (such as calling a static method) then you can prefix with type, such as 'bean:type:fqnClassName'. `),
+            new Context('properties:key:default', 'Lookup a property with the given key. If the key does not exists or has no value, then an optional default value can be specified.'),
+            new Context('propertiesExist:key', 'Checks whether a property placeholder with the given key exists or not. The result can be negated by prefixing the key with `!`.'),
+            new Context('routeId', 'Returns the route id of the current route the Exchange is being routed.'),
+            new Context('routeGroup', 'Returns the route group of the current route the Exchange is being routed. Not all routes has a group assigned, so this may be null.'),
+            new Context('stepId', 'Returns the id of the current step the Exchange is being routed.'),
+            new Context('threadId', 'Returns the id of the current thread. Can be used for logging purpose.'),
+            new Context('threadName', 'Returns the name of the current thread. Can be used for logging purpose.'),
+            new Context('hostname', 'Returns the local hostname (may be empty if not possible to resolve).'),
+            new Context('ref:xxx ', 'To lookup a bean from the Registry with the given id.'),
+            new Context('type:name.field ', 'To refer to a type or field by its FQN name. To refer to a field you can append .FIELD_NAME. For example, you can refer to the constant field from Exchange as: `org.apache.camel.Exchange.FILE_NAME`'),
+            new Context('empty(type)', `Creates a new empty object of the type given as parameter. The type-parameter-Strings are case-insensitive. +
+'string' -> empty String
+'list'   -> empty ArrayList 
+'map'    -> empty HashMap `),
+            new Context('null', 'represents a *null*'),
+            new Context('random(value)', 'returns a random Integer between 0 (included) and _value_ (excluded)'),
+            new Context('random(min,max)', 'returns a random Integer between _min_ (included) and _max_ (excluded)'),
+            new Context('collate(group)', `The collate function iterates the message body and groups
+the data into sub lists of specified size. This can be used with the
+Splitter EIP to split a message body and group/batch
+the split sub message into a group of N sub lists. This method works
+similar to the collate method in Groovy.`),
+            new Context('skip(number)', ' The skip function iterates the message body and skips the first number of items. This can be used with the Splitter EIP to split a message body and skip the first N number of items.'),
+            new Context('join(separator,prefix,exp)', `The join function iterates the message body (by default) and joins the data into a string. The separator is by default a comma. The prefix is optional.'),
+
+The join uses the message body as source by default. It is possible to refer to another
+source (simple language) such as a header via the exp parameter. For example join('&','id=','$\{header.ids}')`),
+            new Context('messageHistory', 'The message history of the current exchange how it has been routed. This is similar to the route stack-trace message history the error handler logs in case of an unhandled exception.'),
+            new Context('messageHistory(false)', 'As messageHistory but without the exchange details (only includes the route stack-trace). This can be used if you do not want to log sensitive data from the message itself.'),
+            new Context('uuid(type)', 'Returns an UUID using the Camel `UuidGenerator`. You can choose between `default`, `classic`, `short` and `simple` as the type. If no type is given the default is used. It is also possible to use a custom `UuidGenerator` and bind the bean to the xref:manual::registry.adoc[Registry] with an id. For example `${uuid(myGenerator}` where the ID is _myGenerator_.'),
+            new Context('hash(exp,algorithm)', 'Returns a hashed value (string in hex decimal) using JDK MessageDigest. The algorithm can be SHA-256 (default) or SHA3-256.'),
+            new Context('jsonpath(exp)', 'When working with JSon data, then this allows to use the JsonPath language for example to extract data from the message body (in JSon format). This requires having camel-jsonpath JAR on the classpath.'),
+            new Context('jsonpath(input,exp)', 'When working with JSon data, then this allows to use the JsonPath language for example to extract data from the message body (in JSon format). This requires having camel-jsonpath JAR on the classpath. For _input_ you can choose `header:key`, `exchangeProperty:key` or `variable:key` to use as input for the JSon payload instead of the message body.'),
+            new Context('jq(exp)', 'When working with JSon data, then this allows to use the JQ language for example to extract data from the message body (in JSon format). This requires having camel-jq JAR on the classpath.'),
+            new Context('jq(input,exp)', 'When working with JSon data, then this allows to use the JQ language for example to extract data from the message body (in JSon format). This requires having camel-jq JAR on the classpath. For _input_ you can choose `header:key`, `exchangeProperty:key` or `variable:key` to use as input for the JSon payload instead of the message body.'),
+            new Context('xpath(exp)', 'When working with XML data, then this allows to use the XPath language for example to extract data from the message body (in XML format). This requires having camel-xpath JAR on the classpath.'),
+            new Context('xpath(input,exp)', 'When working with XML data, then this allows to use the XPath language for example to extract data from the message body (in XML format). This requires having camel-xpath JAR on the classpath. For _input_ you can choose `header:key`, `exchangeProperty:key` or `variable:key` to use as input for the JSon payload instead of the message body.'),
+            new Context('pretty(exp)', 'Converts the inlined expression to a String, and attempts to pretty print if JSon or XML, otherwise the expression is returned as the String value.'),
+        ]
+    )
+]
+
+export const ExpressionFunctions: ExpressionContext[] = [
+    new ExpressionContext('java', [
+            new Context('bodyAs(type)', 'To convert the body to the given type'),
+            new Context('headerAs(name, type)', 'To convert the header with the name to the given type.'),
+            new Context('headerAs(name, defaultValue, type)', 'To convert the header with the name to the given type. If no header exists, then use the given default value.'),
+            new Context('exchangePropertyAs(name, type)', 'To convert the exchange property with the name to the given type.'),
+            new Context('exchangePropertyAs(name, defaultValue, type)', 'To convert the exchange property with the name to the given type. If no exchange property exists, then use the given default value.'),
+            new Context('optionalBodyAs(type)', 'To convert the body to the given type, returned wrapped in java.util.Optional.'),
+            new Context('optionalHeaderAs(name, type)', 'To convert the header with the name to the given type, returned wrapped in java.util.Optional.'),
+            new Context('optionalExchangePropertyAs(name, type)', 'To convert the exchange property with the name to the given type, returned wrapped in java.util.Optional.')
+        ]
+    ),
+    new ExpressionContext('xpath', [
+            new Context('in:body', 'Will return the message body.'),
+            new Context('in:header', 'Will return the message header.'),
+            new Context('function:properties', 'To use a Property Placeholder.'),
+            new Context('function:simple', 'To evaluate a Simple language.'),
+        ]
+    )
+]
diff --git a/karavan-space/src/designer/property/property/ComponentPropertyPlaceholderDropdown.css b/karavan-vscode/webview/expression/ExpressionModalEditor.css
similarity index 52%
rename from karavan-space/src/designer/property/property/ComponentPropertyPlaceholderDropdown.css
rename to karavan-vscode/webview/expression/ExpressionModalEditor.css
index 43991634..732d3abd 100644
--- a/karavan-space/src/designer/property/property/ComponentPropertyPlaceholderDropdown.css
+++ b/karavan-vscode/webview/expression/ExpressionModalEditor.css
@@ -14,24 +14,55 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+.expression-modal {
+    height: 80%;
+}
+
+.container {
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    gap: 16px;
+    justify-content: space-between;
+    align-items: stretch;
+}
+
+.panel-top {
+    flex: 1;
+    height: 100%;
+    border: 1px solid lightgray;
+}
+
+.panel-middle {
+    /*height: 64px;*/
+}
+
+.panel-bottom {
+    flex: 1;
+    height: 100%;
+    overflow-y: auto;
+}
 
-.karavan .properties .property-placeholder-toggle {
-    padding-left: 6px;
-    padding-right: 6px;
+.context {
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+    gap: 64px;
 }
 
-.karavan .properties .property-placeholder-toggle .pf-v5-c-button__icon.pf-m-start {
-    margin-inline-end: 0;
+.context-column {
+    flex: 1;
 }
 
-.karavan .properties .property-placeholder-toggle .pf-v5-c-menu-toggle__controls {
-    display: none;
+.context-column-right {
+    margin-left: 12px;
 }
 
-.pf-v5-c-popover .property-placeholder-toggle-form {
-    width: 300px;
+.context-column .pf-v5-c-clipboard-copy.pf-m-inline {
+    display: flex;
+    width: fit-content;
 }
 
-.pf-v5-c-popover .property-placeholder-toggle-form .pf-v5-c-form__group {
-    grid-template-columns: 1fr 2fr;
+.context-column .pf-v5-c-clipboard-copy__text{
+    white-space: nowrap;
 }
\ No newline at end of file
diff --git a/karavan-designer/src/designer/property/property/ModalEditor.tsx b/karavan-vscode/webview/expression/ExpressionModalEditor.tsx
similarity index 56%
rename from karavan-designer/src/designer/property/property/ModalEditor.tsx
rename to karavan-vscode/webview/expression/ExpressionModalEditor.tsx
index d3df2a27..3a96ce7a 100644
--- a/karavan-designer/src/designer/property/property/ModalEditor.tsx
+++ b/karavan-vscode/webview/expression/ExpressionModalEditor.tsx
@@ -16,13 +16,12 @@
  */
 import React, {useEffect, useState} from 'react';
 import {
-    Button,
-    Modal,
-    ModalVariant, Title, TitleSizes
+    Button, Modal, Title, TitleSizes
 } from '@patternfly/react-core';
-import '../../karavan.css';
-import "@patternfly/patternfly/patternfly.css";
 import Editor from "@monaco-editor/react";
+import {ExpressionBottomPanel} from "./ExpressionBottomPanel";
+import './ExpressionModalEditor.css'
+import {Context, ExpressionFunctions, ExpressionVariables} from "./ExpressionContextModel";
 
 interface Props {
     name: string,
@@ -35,11 +34,12 @@ interface Props {
     showEditor: boolean
 }
 
-export function ModalEditor(props: Props) {
+export function ExpressionModalEditor(props: Props) {
 
     const [customCode, setCustomCode] = useState<string | undefined>();
 
     useEffect(() => {
+        console.log(title, dslLanguage)
         setCustomCode(props.customCode)
     },[]);
 
@@ -52,10 +52,16 @@ export function ModalEditor(props: Props) {
     }
 
     const {dark, dslLanguage, title, showEditor} = props;
+    const language = dslLanguage?.[0];
+    const showVars = ExpressionVariables.findIndex(e => e.name === language) > - 1;
+    const showFuncs = ExpressionFunctions.findIndex(e => e.name === language) > - 1;
+    const show = showVars || showFuncs;
+
     return (
         <Modal
-            aria-label={"expression"}
-            variant={ModalVariant.large}
+            aria-label="Expression"
+            className='expression-modal'
+            width={"80%"}
             header={<React.Fragment>
                 <Title id="modal-custom-header-label" headingLevel="h1" size={TitleSizes['2xl']}>
                     {title}
@@ -71,17 +77,31 @@ export function ModalEditor(props: Props) {
                         onClick={e => close()}>Close</Button>
             ]}
             onEscapePress={e => close()}>
-            <Editor
-                height="400px"
-                width="100%"
-                defaultLanguage={'java'}
-                language={'java'}
-                theme={dark ? 'vs-dark' : 'light'}
-                options={{lineNumbers: "off", folding: false, lineNumbersMinChars: 10, showUnused: false, fontSize: 12, minimap: {enabled: false}}}
-                value={customCode?.toString()}
-                className={'code-editor'}
-                onChange={(value,_) => setCustomCode(value)}
-            />
+            <div className='container'>
+                <div className='panel-top'>
+                    <Editor
+                        height="50%"
+                        width="100%"
+                        defaultLanguage={'java'}
+                        language={'java'}
+                        theme={dark ? 'vs-dark' : 'light'}
+                        options={{
+                            lineNumbers: "off",
+                            folding: false,
+                            lineNumbersMinChars: 10,
+                            showUnused: false,
+                            fontSize: 12,
+                            minimap: {enabled: false}
+                        }}
+                        value={customCode?.toString()}
+                        className={'code-editor'}
+                        onChange={(value, _) => setCustomCode(value)}
+                    />
+                </div>
+                {show && <div className='panel-bottom'>
+                    {dslLanguage && <ExpressionBottomPanel dslLanguage={dslLanguage}/>}
+                </div>}
+            </div>
         </Modal>
     )
 }