You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ma...@apache.org on 2023/08/21 22:22:29 UTC

[camel-karavan] 02/03: Scroll works

This is an automated email from the ASF dual-hosted git repository.

marat pushed a commit to branch feature-836
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git

commit a2c1b127d71ed51d471e1781d5e605fa7b80eea1
Author: Marat Gubaidullin <ma...@Marats-MacBook-Pro.local>
AuthorDate: Mon Aug 21 16:53:47 2023 -0400

    Scroll works
---
 karavan-designer/public/example/demo.camel.yaml    | 30 +++++++++
 karavan-designer/src/App.tsx                       | 33 +++++-----
 karavan-designer/src/DesignerPage.tsx              |  6 +-
 karavan-designer/src/designer/KaravanDesigner.tsx  | 13 ++--
 karavan-designer/src/designer/KaravanStore.ts      |  4 +-
 karavan-designer/src/designer/karavan.css          | 14 ++--
 .../src/designer/route/DslConnections.tsx          | 30 +++++----
 karavan-designer/src/designer/route/DslElement.tsx | 28 ++++++--
 .../src/designer/route/ElementResizeListener.tsx   | 75 ----------------------
 .../src/designer/route/RouteDesigner.tsx           | 50 ++++++++-------
 .../route/useResizeObserver.tsx}                   | 42 ++++++++----
 karavan-designer/src/index.css                     |  6 --
 karavan-designer/src/index.tsx                     |  4 +-
 13 files changed, 167 insertions(+), 168 deletions(-)

diff --git a/karavan-designer/public/example/demo.camel.yaml b/karavan-designer/public/example/demo.camel.yaml
index 2db92f8d..878ed244 100644
--- a/karavan-designer/public/example/demo.camel.yaml
+++ b/karavan-designer/public/example/demo.camel.yaml
@@ -39,3 +39,33 @@
               - routingSlip:
                   expression: {}
                   id: routingSlip-a85a
+- route:
+    id: route-178a
+    from:
+      uri: kamelet:aws-cloudtrail-source
+      id: from-3e7d
+      steps:
+        - multicast:
+            id: multicast-eef7
+            steps:
+              - bean:
+                  id: bean-a5ef
+              - aggregate:
+                  id: aggregate-f5d8
+              - aggregate:
+                  id: aggregate-b9e7
+              - aggregate:
+                  id: aggregate-5eb8
+              - aggregate:
+                  id: aggregate-c57e
+              - aggregate:
+                  id: aggregate-1cd4
+              - bean:
+                  id: bean-72a1
+              - choice:
+                  when:
+                    - expression: {}
+                      id: when-a56b
+                  otherwise:
+                    id: otherwise-9f31
+                  id: choice-1905
diff --git a/karavan-designer/src/App.tsx b/karavan-designer/src/App.tsx
index 3e98dc50..4e751d60 100644
--- a/karavan-designer/src/App.tsx
+++ b/karavan-designer/src/App.tsx
@@ -18,8 +18,8 @@ import * as React from "react";
 import {
     Alert,
     AlertActionCloseButton, AlertGroup,
-    Bullseye, Button, Divider, Flex, FlexItem,
-    Page, Spinner, Tooltip,
+    Bullseye, Button, Divider, Flex, FlexItem, Masthead, MastheadBrand, MastheadContent, MastheadMain, MastheadToggle,
+    Page, PageSidebar, PageSidebarBody, PageToggleButton, Spinner, Tooltip,
 } from "@patternfly/react-core";
 import {KameletApi} from "karavan-core/lib/api/KameletApi";
 import {ComponentApi} from "karavan-core/lib/api/ComponentApi";
@@ -145,7 +145,7 @@ class App extends React.Component<Props, State> {
             new MenuItem("designer", "Designer", <BlueprintIcon/>),
             new MenuItem("knowledgebase", "Knowledgebase", <KnowledgebaseIcon/>),
         ]
-        return (<Flex className="nav-buttons" direction={{default: "column"}} style={{height: "100%"}}
+        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"}
@@ -188,10 +188,21 @@ class App extends React.Component<Props, State> {
         }
     }
 
+    getHeader = () => (
+        <Masthead>
+        </Masthead>
+    );
+
+    getSidebar = () => (
+        <PageSidebar isSidebarOpen={true} id="fill-sidebar">
+            <PageSidebarBody>Navigation</PageSidebarBody>
+        </PageSidebar>
+    );
+
     public render() {
         const {loaded} = this.state;
         return (
-            <Page className="karavan">
+            <Page className="karavan" header={this.getHeader()} sidebar={this.pageNav()}>
                 <AlertGroup isToast isLiveRegion>
                     {this.state.alerts.map((e: ToastMessage) => (
                         // @ts-ignore
@@ -202,18 +213,8 @@ class App extends React.Component<Props, State> {
                         </Alert>
                     ))}
                 </AlertGroup>
-                <>
-                    <Flex direction={{default: "row"}} style={{width: "100%", height: "100%"}}
-                          alignItems={{default: "alignItemsStretch"}} spaceItems={{default: 'spaceItemsNone'}}>
-                        <FlexItem>
-                            {this.pageNav()}
-                        </FlexItem>
-                        <FlexItem flex={{default: "flex_2"}} style={{height: "100%"}}>
-                            {loaded !== true && this.getSpinner()}
-                            {loaded === true && this.getPage()}
-                        </FlexItem>
-                    </Flex>
-                </>
+                {loaded !== true && this.getSpinner()}
+                {loaded === true && this.getPage()}
             </Page>
         )
     }
diff --git a/karavan-designer/src/DesignerPage.tsx b/karavan-designer/src/DesignerPage.tsx
index 9bcc0a2e..5d3ed033 100644
--- a/karavan-designer/src/DesignerPage.tsx
+++ b/karavan-designer/src/DesignerPage.tsx
@@ -105,8 +105,8 @@ export class DesignerPage extends React.Component<Props, State> {
     render() {
         const {mode} = this.state;
         return (
-            <PageSection className="kamelet-section designer-page" padding={{default: 'noPadding'}}>
-                <PageSection className="tools-section" padding={{default: 'noPadding'}}
+            <PageSection className="designer-page" padding={{default: 'noPadding'}}>
+                <div className="tools-section" //padding={{default: 'noPadding'}}
                              style={{backgroundColor:"transparent", paddingLeft: "var(--pf-v5-c-page__main-section--PaddingLeft)"}}>
                     <Flex className="tools" justifyContent={{default: 'justifyContentSpaceBetween'}}>
                         <FlexItem>
@@ -143,7 +143,7 @@ export class DesignerPage extends React.Component<Props, State> {
                             </Toolbar>
                         </FlexItem>
                     </Flex>
-                </PageSection>
+                </div>
                 {mode === 'design' && this.getDesigner()}
                 {mode === 'code'  && this.getEditor()}
             </PageSection>
diff --git a/karavan-designer/src/designer/KaravanDesigner.tsx b/karavan-designer/src/designer/KaravanDesigner.tsx
index b65a66f1..5f25fe91 100644
--- a/karavan-designer/src/designer/KaravanDesigner.tsx
+++ b/karavan-designer/src/designer/KaravanDesigner.tsx
@@ -72,7 +72,6 @@ export const KaravanDesigner = (props: Props) => {
         [state.integration, state.setIntegration], shallow )
 
     useEffect(() => {
-        console.log("useEffect");
         setIntegration(makeIntegration(props.yaml, props.filename));
     }, []);
 
@@ -122,11 +121,13 @@ export const KaravanDesigner = (props: Props) => {
 
     return (
         <PageSection variant={props.dark ? PageSectionVariants.darker : PageSectionVariants.light} className="page" isFilled padding={{default: 'noPadding'}}>
-            <Tabs className="main-tabs" activeKey={tab} onSelect={(event, tabIndex) => setTab(tabIndex.toString())} style={{width: "100%"}}>
-                <Tab eventKey='routes' title={getTab("Routes", "Integration flows", "routes")}></Tab>
-                <Tab eventKey='rest' title={getTab("REST", "REST services", "rest")}></Tab>
-                <Tab eventKey='beans' title={getTab("Beans", "Beans Configuration", "beans")}></Tab>
-            </Tabs>
+            <div>
+                <Tabs className="main-tabs" activeKey={tab} onSelect={(event, tabIndex) => setTab(tabIndex.toString())} style={{width: "100%"}}>
+                    <Tab eventKey='routes' title={getTab("Routes", "Integration flows", "routes")}></Tab>
+                    <Tab eventKey='rest' title={getTab("REST", "REST services", "rest")}></Tab>
+                    <Tab eventKey='beans' title={getTab("Beans", "Beans Configuration", "beans")}></Tab>
+                </Tabs>
+            </div>
             {tab === 'routes' && <RouteDesigner
                 // integration={integration}
                                                 // onSave={(integration, propertyOnly) => save(integration, propertyOnly)}
diff --git a/karavan-designer/src/designer/KaravanStore.ts b/karavan-designer/src/designer/KaravanStore.ts
index 4e710e61..a28f7f21 100644
--- a/karavan-designer/src/designer/KaravanStore.ts
+++ b/karavan-designer/src/designer/KaravanStore.ts
@@ -117,8 +117,8 @@ export const useDesignerStore = createWithEqualityFn<DesignerState>((set) => ({
     setClipboardSteps: (clipboardSteps: string[]) => {
         set({clipboardSteps: clipboardSteps})
     },
-    width: 1000,
-    height: 1000,
+    width: 100,
+    height: 100,
     top: 0,
     left: 0,
     setPosition: (width: number, height: number, top: number, left: number) => {
diff --git a/karavan-designer/src/designer/karavan.css b/karavan-designer/src/designer/karavan.css
index d0cfcc36..71192fc2 100644
--- a/karavan-designer/src/designer/karavan.css
+++ b/karavan-designer/src/designer/karavan.css
@@ -231,10 +231,13 @@
     flex-direction: column;
 }
 
+.karavan main {
+    overflow: hidden;
+}
+
 /*DSL*/
 .karavan .dsl-page {
-    flex: 1;
-    overflow: auto;
+    height: 100%;
 }
 
 .karavan .dsl-page .dsl-page-columns {
@@ -551,8 +554,8 @@
 
 .karavan .dsl-page .flows {
     width: 100%;
-    position: relative;
-    margin-bottom: 80px;
+    position: absolute;
+    /*margin-bottom: 80px;*/
 }
 
 .karavan .dsl-page .flows .add-flow {
@@ -1384,6 +1387,9 @@
 
 .karavan .designer-page {
     background-color: white;
+    display: flex;
+    flex-direction: column;
+    height: 100%;
 }
 
 .karavan .designer-page .project-page-section {
diff --git a/karavan-designer/src/designer/route/DslConnections.tsx b/karavan-designer/src/designer/route/DslConnections.tsx
index db7cd2dd..7a618057 100644
--- a/karavan-designer/src/designer/route/DslConnections.tsx
+++ b/karavan-designer/src/designer/route/DslConnections.tsx
@@ -33,16 +33,17 @@ export const DslConnections = () => {
         [s.width, s.height, s.top, s.left])
     const [steps, setSteps] = useState<Map<string, DslPosition>>(new Map<string, DslPosition>());
 
-    useEffect(() => {
-        console.log("DslConnections Start", width, height, top, left);
-        const sub = EventBus.onPosition()?.subscribe((evt: DslPosition) => setPosition(evt));
-        return () => {
-            console.log("DslConnections Stop");
-            sub?.unsubscribe();
-        };
-    }, [width, height, top, left]);
+    // useEffect(() => {
+    //     console.log("DslConnections Start", width, height, top, left);
+    //     const sub = EventBus.onPosition()?.subscribe((evt: DslPosition) => setPosition(evt));
+    //     return () => {
+    //         console.log("DslConnections Stop");
+    //         sub?.unsubscribe();
+    //     };
+    // }, [width, height, top, left]);
 
     function setPosition(evt: DslPosition) {
+        console.log("setPosition", evt);
         if (evt.command === "add") {
             setSteps(prevSteps => {
                 prevSteps.set(evt.step.uuid, evt);
@@ -442,8 +443,8 @@ export const DslConnections = () => {
         const stepsArray = Array.from(steps.values());
         return (
             <svg
-                style={{width: width, height: height, position: "absolute", left: 0, top: 0}}
-                viewBox={"0 0 " + width + " " + height}>
+                style={{width: width - 5, height: height - 5, position: "absolute", left: 0, top: 0}}
+                viewBox={"0 0 " + (width - 5) + " " + (height -5)}>
                 <defs>
                     <marker id="arrowhead" markerWidth="9" markerHeight="6" refX="0" refY="3" orient="auto" className="arrow">
                         <polygon points="0 0, 9 3, 0 6"/>
@@ -458,11 +459,12 @@ export const DslConnections = () => {
         )
     }
 
+    console.log("RENDER CONNECTION")
     return (
-        <div className="connections" style={{width: width, height: height, marginTop: "0px"}}>
-            {getSvg()}
-            {getIncomings().map(p => getIncomingIcons(p))}
-            {getOutgoings().map(p => getOutgoingIcons(p))}
+        <div style={{position: "absolute", width: width + 5, height: height + 80, top: 0, left: 0, background: "red"}}>
+            {/*{getSvg()}*/}
+            {/*{getIncomings().map(p => getIncomingIcons(p))}*/}
+            {/*{getOutgoings().map(p => getOutgoingIcons(p))}*/}
         </div>
     )
 }
diff --git a/karavan-designer/src/designer/route/DslElement.tsx b/karavan-designer/src/designer/route/DslElement.tsx
index 2b498d02..212be87c 100644
--- a/karavan-designer/src/designer/route/DslElement.tsx
+++ b/karavan-designer/src/designer/route/DslElement.tsx
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import React, {createRef, CSSProperties, useState} from 'react';
+import React, {createRef, CSSProperties, useEffect, useRef, useState} from 'react';
 import {
     Button,
     Flex,
@@ -67,6 +67,24 @@ export const DslElement = (props: Props) => {
     const [isDraggedOver, setIsDraggedOver] = useState<boolean>(false);
     const [moveElements, setMoveElements] = useState<[string | undefined, string | undefined]>([undefined, undefined]);
 
+    const elementRef = useRef(null);
+    const [elementPosition, setElementPosition] = useState({ x: 0, y: 0 });
+
+    useEffect(() => {
+        // function handleResize() {
+        //     if (elementRef && elementRef.current !== undefined) {
+        //         const current: any = (elementRef.current as any);
+        //         const x = current.offsetLeft;
+        //         const y = current.offsetTop;
+        //         setElementPosition({x, y});
+        //         // console.log("setElementPosition", {x, y})
+        //     }
+        // }
+        //
+        // handleResize(); // initial call to get position of the element on mount
+        // window.addEventListener("resize", handleResize);
+        // return () => window.removeEventListener("resize", handleResize);
+    }, [elementRef]);
     //
     // componentDidUpdate = (prevProps: Readonly<Props>, prevState: Readonly<State>, snapshot?: any) => {
     //     if (prevselectedUuid !== props.selectedUuid) {
@@ -213,7 +231,7 @@ export const DslElement = (props: Props) => {
     }
 
     function sendPosition (el: HTMLDivElement | null, isSelected: boolean) {
-        // console.log("sendPosition", props.step)
+        console.log("sendPosition", props.step)
         const node = el;
         if (node && el) {
             const header = Array.from(node.childNodes.values()).filter((n: any) => n.classList.contains("header"))[0];
@@ -244,7 +262,8 @@ export const DslElement = (props: Props) => {
         return (
             <div className={headerClasses} style={getHeaderStyle()}>
                 {!['RouteConfigurationDefinition', 'RouteDefinition'].includes(props.step.dslName) &&
-                    <div ref={el => sendPosition(el, isSelected())}
+                    <div
+                        // ref={el => sendPosition(el, isSelected())}
                          className={"header-icon"}
                          style={isWide() ? {width: ""} : {}}>
                         {CamelUi.getIconForElement(step)}
@@ -439,7 +458,8 @@ export const DslElement = (props: Props) => {
     return (
         <div key={"root" + element.uuid}
              className={className}
-             ref={el => sendPosition(el, isSelected())}
+             ref={elementRef}
+             // ref={el => sendPosition(el, isSelected())}
              style={{
                  borderStyle: hasBorder() ? "dotted" : "none",
                  borderColor: isSelected() ? "var(--step-border-color-selected)" : "var(--step-border-color)",
diff --git a/karavan-designer/src/designer/route/ElementResizeListener.tsx b/karavan-designer/src/designer/route/ElementResizeListener.tsx
deleted file mode 100644
index 4ef53c64..00000000
--- a/karavan-designer/src/designer/route/ElementResizeListener.tsx
+++ /dev/null
@@ -1,75 +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 {RefObject, useCallback, useEffect, useRef} from "react";
-
-interface Props {
-    onResize: (event: Event) => void;
-};
-export const ElementResizeListener: React.FC<Props> = ({ onResize }) => {
-    const rafRef = useRef(0);
-    const objectRef: RefObject<HTMLObjectElement> = useRef(null);
-    const onResizeRef = useRef(onResize);
-
-    onResizeRef.current = onResize;
-
-    const _onResize = useCallback((e: Event) => {
-        if (rafRef.current) {
-            cancelAnimationFrame(rafRef.current);
-        }
-        rafRef.current = requestAnimationFrame(() => {
-            onResizeRef.current(e);
-        });
-    }, []);
-
-    const onLoad = useCallback(() => {
-        const obj = objectRef.current;
-        if (obj && obj.contentDocument && obj.contentDocument.defaultView) {
-            obj.contentDocument.defaultView.addEventListener('resize', _onResize);
-        }
-    }, []);
-
-    useEffect(() => {
-        return () => {
-            const obj = objectRef.current;
-            if (obj && obj.contentDocument && obj.contentDocument.defaultView) {
-                obj.contentDocument.defaultView.removeEventListener('resize', _onResize);
-            }
-        }
-    }, []);
-
-    return (
-        <object
-            aria-label="object"
-            onLoad={onLoad}
-            ref={objectRef} tabIndex={-1}
-            type={'text/html'}
-            data={'about:blank'}
-            title={''}
-            style={{
-                position: 'absolute',
-                top: 0,
-                left: 0,
-                height: '100%',
-                width: '100%',
-                pointerEvents: 'none',
-                zIndex: -1,
-                opacity: 0,
-            }}
-        />
-    )
-}
diff --git a/karavan-designer/src/designer/route/RouteDesigner.tsx b/karavan-designer/src/designer/route/RouteDesigner.tsx
index 101309bb..4f460933 100644
--- a/karavan-designer/src/designer/route/RouteDesigner.tsx
+++ b/karavan-designer/src/designer/route/RouteDesigner.tsx
@@ -38,7 +38,7 @@ import {shallow} from "zustand/shallow";
 import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
 import {RouteConfigurationDefinition} from "karavan-core/lib/model/CamelDefinition";
 import {CamelDefinitionApiExt} from "karavan-core/lib/api/CamelDefinitionApiExt";
-import {ElementResizeListener} from "./ElementResizeListener";
+import useResizeObserver from "./useResizeObserver";
 
 interface Props {
     // onSave?: (integration: Integration, propertyOnly: boolean) => void
@@ -48,25 +48,28 @@ interface Props {
 
 export const RouteDesigner = (props: Props) => {
 
-    const ref = React.createRef();
     const printerRef = React.createRef()
     const contentRef: React.RefObject<HTMLDivElement> = useRef(null);
     const flowRef: React.RefObject<HTMLDivElement> = useRef(null);
 
-    const { deleteElement, selectElement, moveElement, onShowDeleteConfirmation, onDslSelect, openSelector, createRouteConfiguration} = useRouteDesignerHook();
+    const {
+        deleteElement,
+        selectElement,
+        moveElement,
+        onShowDeleteConfirmation,
+        onDslSelect,
+        openSelector,
+        createRouteConfiguration
+    } = useRouteDesignerHook();
 
     const [integration, setIntegration] = useIntegrationStore((state) => [state.integration, state.setIntegration], shallow)
-    const [showSelector, showDeleteConfirmation, propertyOnly, showSteps,deleteMessage,parentId, selectedUuids,clipboardSteps, parentDsl,selectedPosition,selectedStep,selectorTabIndex,
-        setShowSelector, setShowDeleteConfirmation,setPropertyOnly,setShowSteps,setDeleteMessage, setParentId, setSelectedUuids, setClipboardSteps,setPosition,
+    const [showSelector, showDeleteConfirmation, propertyOnly, showSteps, deleteMessage, parentId, selectedUuids, clipboardSteps, parentDsl, selectedPosition, selectedStep, selectorTabIndex,
+        setShowSelector, setShowDeleteConfirmation, setPropertyOnly, setShowSteps, setDeleteMessage, setParentId, setSelectedUuids, setClipboardSteps, setPosition,
         width, height, top, left] = useDesignerStore((s) =>
-        [s.showSelector, s.showDeleteConfirmation, s.propertyOnly, s.showSteps,s.deleteMessage,s.parentId, s.selectedUuids,s.clipboardSteps, s.parentDsl, s.selectedPosition, s.selectedStep,s.selectorTabIndex,
-            s.setShowSelector, s.setShowDeleteConfirmation,s.setPropertyOnly,s.setShowSteps,s.setDeleteMessage, s.setParentId, s.setSelectedUuids, s.setClipboardSteps, s.setPosition,
+        [s.showSelector, s.showDeleteConfirmation, s.propertyOnly, s.showSteps, s.deleteMessage, s.parentId, s.selectedUuids, s.clipboardSteps, s.parentDsl, s.selectedPosition, s.selectedStep, s.selectorTabIndex,
+            s.setShowSelector, s.setShowDeleteConfirmation, s.setPropertyOnly, s.setShowSteps, s.setDeleteMessage, s.setParentId, s.setSelectedUuids, s.setClipboardSteps, s.setPosition,
             s.width, s.height, s.top, s.left], shallow)
 
-    useEffect(() => {
-        adaptResize();
-    })
-
     // function componentDidMount() {
     //     logic.componentDidMount();
     // }
@@ -150,28 +153,28 @@ export const RouteDesigner = (props: Props) => {
     //     }
     // }
 
-    const adaptResize = useCallback(() => {
-        if (contentRef.current && flowRef.current) {
-            const el = contentRef.current.getBoundingClientRect();
-            // flowRef.current.textContent = `width: ${elmRect.width}`;
-            console.log("elmRect", el)
+    const onResize = useCallback((target: HTMLDivElement) => {
+        const el = target.getBoundingClientRect();
+        if (width !== el.width || height !== el.height || top !== el.top || left !== el.left) {
             setPosition(el.width, el.height, el.top, el.left)
+            console.log("elmRect", el)
         }
     }, []);
 
+    const ref = useResizeObserver(onResize);
+
+    console.log("RENDER ROUTE_DESIGNER")
 
     function getGraph() {
         const routes = CamelUi.getRoutes(integration);
         const routeConfigurations = CamelUi.getRouteConfigurations(integration);
         return (
-            <div className="graph" ref={contentRef}>
+            <div className="graph">
                 <DslConnections/>
-                <ElementResizeListener onResize={adaptResize}/>
                 <div id="flows" className="flows" data-click="FLOWS" onClick={event => {
                     // logic.unselectElement(event)
                 }}
-                     // ref={el => onResizePage(el)}
-                     ref={flowRef}
+                     ref={ref}
                 >
                     {routeConfigurations?.map((routeConfiguration, index: number) => (
                         <DslElement key={routeConfiguration.uuid}
@@ -209,17 +212,18 @@ export const RouteDesigner = (props: Props) => {
             </div>)
     }
 
+    const hasFlows = integration?.spec?.flows?.length && integration?.spec?.flows?.length > 0;
     return (
-        <PageSection className="dsl-page" isFilled padding={{default: 'noPadding'}}>
+        <div className="dsl-page">
             <div className="dsl-page-columns">
                 <Drawer isExpanded isInline>
                     <DrawerContent panelContent={getPropertiesPanel()}>
-                        <DrawerContentBody>{getGraph()}</DrawerContentBody>
+                        <DrawerContentBody>{hasFlows && getGraph()}</DrawerContentBody>
                     </DrawerContent>
                 </Drawer>
             </div>
             {getSelectorModal()}
             {getDeleteConfirmation()}
-        </PageSection>
+        </div>
     );
 }
\ No newline at end of file
diff --git a/karavan-designer/src/index.tsx b/karavan-designer/src/designer/route/useResizeObserver.tsx
similarity index 56%
copy from karavan-designer/src/index.tsx
copy to karavan-designer/src/designer/route/useResizeObserver.tsx
index 3219d305..93141b20 100644
--- a/karavan-designer/src/index.tsx
+++ b/karavan-designer/src/designer/route/useResizeObserver.tsx
@@ -14,16 +14,32 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import React, {StrictMode} from 'react';
-import "./index.css";
-import "@patternfly/patternfly/patternfly.css";
-import App from "./App";
-import {createRoot} from "react-dom/client";
-
-const container = document.getElementById('root');
-const root = createRoot(container!);
-root.render(
-    <StrictMode>
-        <App />
-    </StrictMode>
-);
\ No newline at end of file
+
+import { useLayoutEffect, useRef } from 'react';
+
+function useResizeObserver<T extends HTMLElement>(
+    callback: (target: T, entry: ResizeObserverEntry) => void
+) {
+    const ref = useRef<T>(null)
+
+    useLayoutEffect(() => {
+        const element = ref?.current;
+
+        if (!element) {
+            return;
+        }
+
+        const observer = new ResizeObserver((entries) => {
+            callback(element, entries[0]);
+        });
+
+        observer.observe(element);
+        return () => {
+            observer.disconnect();
+        };
+    }, [callback, ref]);
+
+    return ref
+}
+
+export default useResizeObserver;
\ No newline at end of file
diff --git a/karavan-designer/src/index.css b/karavan-designer/src/index.css
index d2ffcae4..a7341d7a 100644
--- a/karavan-designer/src/index.css
+++ b/karavan-designer/src/index.css
@@ -8,14 +8,8 @@ body,
 #root {
   margin: 0;
   height: 100%;
-}
-
-#root {
   display: flex;
   flex-direction: column;
-}
-
-.karavan .pf-v5-c-page__main {
   overflow: hidden;
 }
 
diff --git a/karavan-designer/src/index.tsx b/karavan-designer/src/index.tsx
index 3219d305..5a495994 100644
--- a/karavan-designer/src/index.tsx
+++ b/karavan-designer/src/index.tsx
@@ -23,7 +23,7 @@ import {createRoot} from "react-dom/client";
 const container = document.getElementById('root');
 const root = createRoot(container!);
 root.render(
-    <StrictMode>
+    // <StrictMode>
         <App />
-    </StrictMode>
+    // </StrictMode>
 );
\ No newline at end of file