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/10/06 17:24:03 UTC
[camel-karavan] branch main updated: Fix #932
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 6682daf4 Fix #932
6682daf4 is described below
commit 6682daf4e7faeeea97372b6f86f16cbd8b9602cc
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Fri Oct 6 13:23:51 2023 -0400
Fix #932
---
karavan-designer/src/App.tsx | 4 +-
karavan-designer/src/designer/DesignerStore.ts | 7 ++
karavan-designer/src/designer/KaravanDesigner.tsx | 3 +-
karavan-designer/src/designer/route/DslElement.tsx | 45 ++----------
.../src/designer/route/DslElementMoveModal.tsx | 81 ++++++++++++++++++++++
.../src/designer/route/RouteDesigner.tsx | 7 +-
karavan-space/src/designer/DesignerStore.ts | 7 ++
karavan-space/src/designer/KaravanDesigner.tsx | 3 +-
karavan-space/src/designer/rest/rest.css | 5 +-
karavan-space/src/designer/route/DslElement.tsx | 45 ++----------
.../src/designer/route/DslElementMoveModal.tsx | 81 ++++++++++++++++++++++
karavan-space/src/designer/route/DslProperties.tsx | 3 +-
karavan-space/src/designer/route/RouteDesigner.tsx | 7 +-
.../src/main/webui/src/designer/DesignerStore.ts | 7 ++
.../main/webui/src/designer/KaravanDesigner.tsx | 3 +-
.../main/webui/src/designer/route/DslElement.tsx | 45 ++----------
.../src/designer/route/DslElementMoveModal.tsx | 81 ++++++++++++++++++++++
.../webui/src/designer/route/DslProperties.tsx | 3 +-
.../webui/src/designer/route/RouteDesigner.tsx | 7 +-
19 files changed, 304 insertions(+), 140 deletions(-)
diff --git a/karavan-designer/src/App.tsx b/karavan-designer/src/App.tsx
index f23eb43d..9e760223 100644
--- a/karavan-designer/src/App.tsx
+++ b/karavan-designer/src/App.tsx
@@ -69,8 +69,8 @@ class App extends React.Component<Props, State> {
fetch("components/components.json"),
fetch("snippets/org.apache.camel.AggregationStrategy"),
fetch("snippets/org.apache.camel.Processor"),
- // fetch("example/demo.camel.yaml")
- fetch("example/aws-s3-cdc-source.kamelet.yaml")
+ fetch("example/demo.camel.yaml")
+ // fetch("example/aws-s3-cdc-source.kamelet.yaml")
// fetch("components/supported-components.json"),
]).then(responses =>
Promise.all(responses.map(response => response.text()))
diff --git a/karavan-designer/src/designer/DesignerStore.ts b/karavan-designer/src/designer/DesignerStore.ts
index 15a9b7be..4831855f 100644
--- a/karavan-designer/src/designer/DesignerStore.ts
+++ b/karavan-designer/src/designer/DesignerStore.ts
@@ -166,7 +166,9 @@ type DesignerState = {
height: number,
top: number,
left: number,
+ moveElements: [string | undefined, string | undefined]
}
+
const designerState: DesignerState = {
notificationBadge: false,
notificationMessage: ['', ''],
@@ -182,6 +184,7 @@ const designerState: DesignerState = {
height: 0,
top: 0,
left: 0,
+ moveElements: [undefined, undefined]
};
type DesignerAction = {
@@ -197,6 +200,7 @@ type DesignerAction = {
setPosition: (width: number, height: number, top: number, left: number) => void;
reset: () => void;
setNotification: (notificationBadge: boolean, notificationMessage: [string, string]) => void;
+ setMoveElements: (moveElements: [string | undefined, string | undefined]) => void;
}
export const useDesignerStore = createWithEqualityFn<DesignerState & DesignerAction>((set) => ({
@@ -248,5 +252,8 @@ export const useDesignerStore = createWithEqualityFn<DesignerState & DesignerAct
},
setNotification: (notificationBadge: boolean, notificationMessage: [string, string]) => {
set({notificationBadge: notificationBadge, notificationMessage: notificationMessage})
+ },
+ setMoveElements: (moveElements: [string | undefined, string | undefined]) => {
+ set({moveElements: moveElements})
}
}), shallow)
\ No newline at end of file
diff --git a/karavan-designer/src/designer/KaravanDesigner.tsx b/karavan-designer/src/designer/KaravanDesigner.tsx
index 71914986..766b4e1f 100644
--- a/karavan-designer/src/designer/KaravanDesigner.tsx
+++ b/karavan-designer/src/designer/KaravanDesigner.tsx
@@ -134,7 +134,8 @@ export function KaravanDesigner(props: Props) {
const isKamelet = integration.type === 'kamelet';
return (
- <PageSection variant={props.dark ? PageSectionVariants.darker : PageSectionVariants.light} className="page"
+ <PageSection variant={props.dark ? PageSectionVariants.darker : PageSectionVariants.light}
+ className="page"
isFilled padding={{default: 'noPadding'}}>
<div className={"main-tabs-wrapper"}>
<Tabs className="main-tabs"
diff --git a/karavan-designer/src/designer/route/DslElement.tsx b/karavan-designer/src/designer/route/DslElement.tsx
index 5f2744c5..0d246b20 100644
--- a/karavan-designer/src/designer/route/DslElement.tsx
+++ b/karavan-designer/src/designer/route/DslElement.tsx
@@ -16,9 +16,6 @@
*/
import React, {CSSProperties, useMemo, useState} from 'react';
import {
- Button,
- Flex,
- Modal, ModalVariant,
Text, Tooltip,
} from '@patternfly/react-core';
import '../karavan.css';
@@ -49,13 +46,12 @@ export function DslElement(props: Props) {
const [integration] = useIntegrationStore((s) => [s.integration, s.setIntegration], shallow)
- const [selectedUuids, selectedStep, showMoveConfirmation, setShowMoveConfirmation, hideLogDSL] =
+ const [selectedUuids, setShowMoveConfirmation, hideLogDSL, setMoveElements] =
useDesignerStore((s) =>
- [s.selectedUuids, s.selectedStep, s.showMoveConfirmation, s.setShowMoveConfirmation, s.hideLogDSL], shallow)
+ [s.selectedUuids, s.setShowMoveConfirmation, s.hideLogDSL, s.setMoveElements], shallow)
const [isDragging, setIsDragging] = useState<boolean>(false);
const [isDraggedOver, setIsDraggedOver] = useState<boolean>(false);
- const [moveElements, setMoveElements] = useState<[string | undefined, string | undefined]>([undefined, undefined]);
function onOpenSelector(evt: React.MouseEvent, showSteps: boolean = true, isInsert: boolean = false) {
evt.stopPropagation();
@@ -92,20 +88,6 @@ export function DslElement(props: Props) {
}
}
- function confirmMove(asChild: boolean) {
- const sourceUuid = moveElements[0];
- const targetUuid = moveElements[1];
- if (sourceUuid && targetUuid && sourceUuid !== targetUuid) {
- moveElement(sourceUuid, targetUuid, asChild);
- cancelMove();
- }
- }
-
- function cancelMove() {
- setShowMoveConfirmation(false);
- setMoveElements([undefined, undefined]);
- }
-
function isElementSelected(): boolean {
return selectedUuids.includes(props.step.uuid);
}
@@ -388,7 +370,8 @@ export function DslElement(props: Props) {
function getAddElementButton() {
return (
- <Tooltip position={"bottom"} content={<div>{"Add DSL element to " + CamelDisplayUtil.getTitle(props.step)}</div>}>
+ <Tooltip position={"bottom"}
+ content={<div>{"Add DSL element to " + CamelDisplayUtil.getTitle(props.step)}</div>}>
<button
type="button"
aria-label="Add"
@@ -419,25 +402,6 @@ export function DslElement(props: Props) {
)
}
- function getMoveConfirmation() {
- return (
- <Modal
- aria-label="title"
- className='move-modal'
- isOpen={showMoveConfirmation}
- variant={ModalVariant.small}
- ><Flex direction={{default: "column"}}>
- <div>Select move type:</div>
- <Button key="place" variant="primary" onClick={event => confirmMove(false)}>Shift (target down)</Button>
- <Button key="child" variant="secondary" onClick={event => confirmMove(true)}>Move as target
- step</Button>
- <Button key="cancel" variant="tertiary" onClick={event => cancelMove()}>Cancel</Button>
- </Flex>
-
- </Modal>
- )
- }
-
const element: CamelElement = props.step;
const className = "step-element" + (isElementSelected() ? " step-element-selected" : "") + (!props.step.showChildren ? " hidden-step" : "");
return (
@@ -487,7 +451,6 @@ export function DslElement(props: Props) {
>
{getElementHeader()}
{getChildElements()}
- {getMoveConfirmation()}
</div>
)
}
diff --git a/karavan-designer/src/designer/route/DslElementMoveModal.tsx b/karavan-designer/src/designer/route/DslElementMoveModal.tsx
new file mode 100644
index 00000000..d1e17ecf
--- /dev/null
+++ b/karavan-designer/src/designer/route/DslElementMoveModal.tsx
@@ -0,0 +1,81 @@
+/*
+ * 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 {
+ Button,
+ Flex,
+ Modal, ModalVariant,
+} from '@patternfly/react-core';
+import '../karavan.css';
+import {useDesignerStore, useIntegrationStore} from "../DesignerStore";
+import {shallow} from "zustand/shallow";
+import {useRouteDesignerHook} from "./useRouteDesignerHook";
+import {CamelDefinitionApiExt} from "karavan-core/lib/api/CamelDefinitionApiExt";
+
+export function DslElementMoveModal() {
+
+ const {moveElement} = useRouteDesignerHook();
+ const [integration] = useIntegrationStore((s) => [s.integration, s.setIntegration], shallow)
+ const [ showMoveConfirmation, setShowMoveConfirmation, moveElements, setMoveElements] =
+ useDesignerStore((s) =>
+ [s.showMoveConfirmation, s.setShowMoveConfirmation, s.moveElements, s.setMoveElements], shallow)
+
+ function confirmMove(asChild: boolean) {
+ const sourceUuid = moveElements[0];
+ const targetUuid = moveElements[1];
+ if (sourceUuid && targetUuid && sourceUuid !== targetUuid) {
+ moveElement(sourceUuid, targetUuid, asChild);
+ cancelMove();
+ }
+ }
+
+ function cancelMove() {
+ setShowMoveConfirmation(false);
+ setMoveElements([undefined, undefined]);
+ }
+
+ function canReplace() {
+ const targetUuid = moveElements[1];
+ if (targetUuid) {
+ const targetElement = CamelDefinitionApiExt.findElementInIntegration(integration, targetUuid);
+ if (targetElement) {
+ return !['WhenDefinition', 'OtherwiseDefinition'].includes(targetElement?.dslName);
+ }
+ }
+ return true;
+ }
+
+ return (
+ <Modal
+ aria-label="title"
+ className='move-modal'
+ isOpen={showMoveConfirmation}
+ onClose={event => cancelMove()}
+ variant={ModalVariant.small}
+ >
+ <Flex direction={{default: "column"}}>
+ <div>Select move type:</div>
+ {canReplace() && <Button key="place" variant="primary" onClick={event => confirmMove(false)}
+ >
+ Replace (target down)
+ </Button>}
+ <Button key="child" variant="secondary" onClick={event => confirmMove(true)}>Set as child</Button>
+ <Button key="cancel" variant="tertiary" onClick={event => cancelMove()}>Cancel</Button>
+ </Flex>
+ </Modal>
+ )
+}
diff --git a/karavan-designer/src/designer/route/RouteDesigner.tsx b/karavan-designer/src/designer/route/RouteDesigner.tsx
index 7d3b5950..215f334b 100644
--- a/karavan-designer/src/designer/route/RouteDesigner.tsx
+++ b/karavan-designer/src/designer/route/RouteDesigner.tsx
@@ -36,14 +36,16 @@ import useResizeObserver from "./useResizeObserver";
import {Command, EventBus} from "../utils/EventBus";
import useMutationsObserver from "./useDrawerMutationsObserver";
import {DeleteConfirmation} from "./DeleteConfirmation";
+import {DslElementMoveModal} from "./DslElementMoveModal";
export function RouteDesigner() {
const {openSelector, createRouteConfiguration, onCommand, handleKeyDown, handleKeyUp, unselectElement} = useRouteDesignerHook();
const [integration] = useIntegrationStore((state) => [state.integration], shallow)
- const [showDeleteConfirmation, setPosition, width, height, top, left, hideLogDSL] = useDesignerStore((s) =>
- [s.showDeleteConfirmation, s.setPosition, s.width, s.height, s.top, s.left, s.hideLogDSL], shallow)
+ const [showDeleteConfirmation, setPosition, width, height, top, left, hideLogDSL, showMoveConfirmation, setShowMoveConfirmation] =
+ useDesignerStore((s) =>
+ [s.showDeleteConfirmation, s.setPosition, s.width, s.height, s.top, s.left, s.hideLogDSL, s.showMoveConfirmation, s.setShowMoveConfirmation], shallow)
const [showSelector] = useSelectorStore((s) => [s.showSelector], shallow)
@@ -161,6 +163,7 @@ export function RouteDesigner() {
</div>
{showSelector && <DslSelector/>}
{showDeleteConfirmation && <DeleteConfirmation/>}
+ {showMoveConfirmation && <DslElementMoveModal/>}
</div>
)
}
\ No newline at end of file
diff --git a/karavan-space/src/designer/DesignerStore.ts b/karavan-space/src/designer/DesignerStore.ts
index 15a9b7be..4831855f 100644
--- a/karavan-space/src/designer/DesignerStore.ts
+++ b/karavan-space/src/designer/DesignerStore.ts
@@ -166,7 +166,9 @@ type DesignerState = {
height: number,
top: number,
left: number,
+ moveElements: [string | undefined, string | undefined]
}
+
const designerState: DesignerState = {
notificationBadge: false,
notificationMessage: ['', ''],
@@ -182,6 +184,7 @@ const designerState: DesignerState = {
height: 0,
top: 0,
left: 0,
+ moveElements: [undefined, undefined]
};
type DesignerAction = {
@@ -197,6 +200,7 @@ type DesignerAction = {
setPosition: (width: number, height: number, top: number, left: number) => void;
reset: () => void;
setNotification: (notificationBadge: boolean, notificationMessage: [string, string]) => void;
+ setMoveElements: (moveElements: [string | undefined, string | undefined]) => void;
}
export const useDesignerStore = createWithEqualityFn<DesignerState & DesignerAction>((set) => ({
@@ -248,5 +252,8 @@ export const useDesignerStore = createWithEqualityFn<DesignerState & DesignerAct
},
setNotification: (notificationBadge: boolean, notificationMessage: [string, string]) => {
set({notificationBadge: notificationBadge, notificationMessage: notificationMessage})
+ },
+ setMoveElements: (moveElements: [string | undefined, string | undefined]) => {
+ set({moveElements: moveElements})
}
}), shallow)
\ No newline at end of file
diff --git a/karavan-space/src/designer/KaravanDesigner.tsx b/karavan-space/src/designer/KaravanDesigner.tsx
index 71914986..766b4e1f 100644
--- a/karavan-space/src/designer/KaravanDesigner.tsx
+++ b/karavan-space/src/designer/KaravanDesigner.tsx
@@ -134,7 +134,8 @@ export function KaravanDesigner(props: Props) {
const isKamelet = integration.type === 'kamelet';
return (
- <PageSection variant={props.dark ? PageSectionVariants.darker : PageSectionVariants.light} className="page"
+ <PageSection variant={props.dark ? PageSectionVariants.darker : PageSectionVariants.light}
+ className="page"
isFilled padding={{default: 'noPadding'}}>
<div className={"main-tabs-wrapper"}>
<Tabs className="main-tabs"
diff --git a/karavan-space/src/designer/rest/rest.css b/karavan-space/src/designer/rest/rest.css
index 25012e2d..3f1a53a5 100644
--- a/karavan-space/src/designer/rest/rest.css
+++ b/karavan-space/src/designer/rest/rest.css
@@ -185,6 +185,7 @@
margin-left: 6px;
cursor: pointer;
justify-content: space-between;
+ position: relative;
}
.karavan .rest-designer .rest-config-card,
@@ -238,8 +239,8 @@
.karavan .rest-designer .rest-card .delete-button,
.karavan .rest-designer .method-card .delete-button {
position: absolute;
- top: 3px;
- right: 3px;
+ top: -7px;
+ right: -7px;
line-height: 1;
border: 0;
padding: 0;
diff --git a/karavan-space/src/designer/route/DslElement.tsx b/karavan-space/src/designer/route/DslElement.tsx
index 5f2744c5..0d246b20 100644
--- a/karavan-space/src/designer/route/DslElement.tsx
+++ b/karavan-space/src/designer/route/DslElement.tsx
@@ -16,9 +16,6 @@
*/
import React, {CSSProperties, useMemo, useState} from 'react';
import {
- Button,
- Flex,
- Modal, ModalVariant,
Text, Tooltip,
} from '@patternfly/react-core';
import '../karavan.css';
@@ -49,13 +46,12 @@ export function DslElement(props: Props) {
const [integration] = useIntegrationStore((s) => [s.integration, s.setIntegration], shallow)
- const [selectedUuids, selectedStep, showMoveConfirmation, setShowMoveConfirmation, hideLogDSL] =
+ const [selectedUuids, setShowMoveConfirmation, hideLogDSL, setMoveElements] =
useDesignerStore((s) =>
- [s.selectedUuids, s.selectedStep, s.showMoveConfirmation, s.setShowMoveConfirmation, s.hideLogDSL], shallow)
+ [s.selectedUuids, s.setShowMoveConfirmation, s.hideLogDSL, s.setMoveElements], shallow)
const [isDragging, setIsDragging] = useState<boolean>(false);
const [isDraggedOver, setIsDraggedOver] = useState<boolean>(false);
- const [moveElements, setMoveElements] = useState<[string | undefined, string | undefined]>([undefined, undefined]);
function onOpenSelector(evt: React.MouseEvent, showSteps: boolean = true, isInsert: boolean = false) {
evt.stopPropagation();
@@ -92,20 +88,6 @@ export function DslElement(props: Props) {
}
}
- function confirmMove(asChild: boolean) {
- const sourceUuid = moveElements[0];
- const targetUuid = moveElements[1];
- if (sourceUuid && targetUuid && sourceUuid !== targetUuid) {
- moveElement(sourceUuid, targetUuid, asChild);
- cancelMove();
- }
- }
-
- function cancelMove() {
- setShowMoveConfirmation(false);
- setMoveElements([undefined, undefined]);
- }
-
function isElementSelected(): boolean {
return selectedUuids.includes(props.step.uuid);
}
@@ -388,7 +370,8 @@ export function DslElement(props: Props) {
function getAddElementButton() {
return (
- <Tooltip position={"bottom"} content={<div>{"Add DSL element to " + CamelDisplayUtil.getTitle(props.step)}</div>}>
+ <Tooltip position={"bottom"}
+ content={<div>{"Add DSL element to " + CamelDisplayUtil.getTitle(props.step)}</div>}>
<button
type="button"
aria-label="Add"
@@ -419,25 +402,6 @@ export function DslElement(props: Props) {
)
}
- function getMoveConfirmation() {
- return (
- <Modal
- aria-label="title"
- className='move-modal'
- isOpen={showMoveConfirmation}
- variant={ModalVariant.small}
- ><Flex direction={{default: "column"}}>
- <div>Select move type:</div>
- <Button key="place" variant="primary" onClick={event => confirmMove(false)}>Shift (target down)</Button>
- <Button key="child" variant="secondary" onClick={event => confirmMove(true)}>Move as target
- step</Button>
- <Button key="cancel" variant="tertiary" onClick={event => cancelMove()}>Cancel</Button>
- </Flex>
-
- </Modal>
- )
- }
-
const element: CamelElement = props.step;
const className = "step-element" + (isElementSelected() ? " step-element-selected" : "") + (!props.step.showChildren ? " hidden-step" : "");
return (
@@ -487,7 +451,6 @@ export function DslElement(props: Props) {
>
{getElementHeader()}
{getChildElements()}
- {getMoveConfirmation()}
</div>
)
}
diff --git a/karavan-space/src/designer/route/DslElementMoveModal.tsx b/karavan-space/src/designer/route/DslElementMoveModal.tsx
new file mode 100644
index 00000000..d1e17ecf
--- /dev/null
+++ b/karavan-space/src/designer/route/DslElementMoveModal.tsx
@@ -0,0 +1,81 @@
+/*
+ * 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 {
+ Button,
+ Flex,
+ Modal, ModalVariant,
+} from '@patternfly/react-core';
+import '../karavan.css';
+import {useDesignerStore, useIntegrationStore} from "../DesignerStore";
+import {shallow} from "zustand/shallow";
+import {useRouteDesignerHook} from "./useRouteDesignerHook";
+import {CamelDefinitionApiExt} from "karavan-core/lib/api/CamelDefinitionApiExt";
+
+export function DslElementMoveModal() {
+
+ const {moveElement} = useRouteDesignerHook();
+ const [integration] = useIntegrationStore((s) => [s.integration, s.setIntegration], shallow)
+ const [ showMoveConfirmation, setShowMoveConfirmation, moveElements, setMoveElements] =
+ useDesignerStore((s) =>
+ [s.showMoveConfirmation, s.setShowMoveConfirmation, s.moveElements, s.setMoveElements], shallow)
+
+ function confirmMove(asChild: boolean) {
+ const sourceUuid = moveElements[0];
+ const targetUuid = moveElements[1];
+ if (sourceUuid && targetUuid && sourceUuid !== targetUuid) {
+ moveElement(sourceUuid, targetUuid, asChild);
+ cancelMove();
+ }
+ }
+
+ function cancelMove() {
+ setShowMoveConfirmation(false);
+ setMoveElements([undefined, undefined]);
+ }
+
+ function canReplace() {
+ const targetUuid = moveElements[1];
+ if (targetUuid) {
+ const targetElement = CamelDefinitionApiExt.findElementInIntegration(integration, targetUuid);
+ if (targetElement) {
+ return !['WhenDefinition', 'OtherwiseDefinition'].includes(targetElement?.dslName);
+ }
+ }
+ return true;
+ }
+
+ return (
+ <Modal
+ aria-label="title"
+ className='move-modal'
+ isOpen={showMoveConfirmation}
+ onClose={event => cancelMove()}
+ variant={ModalVariant.small}
+ >
+ <Flex direction={{default: "column"}}>
+ <div>Select move type:</div>
+ {canReplace() && <Button key="place" variant="primary" onClick={event => confirmMove(false)}
+ >
+ Replace (target down)
+ </Button>}
+ <Button key="child" variant="secondary" onClick={event => confirmMove(true)}>Set as child</Button>
+ <Button key="cancel" variant="tertiary" onClick={event => cancelMove()}>Cancel</Button>
+ </Flex>
+ </Modal>
+ )
+}
diff --git a/karavan-space/src/designer/route/DslProperties.tsx b/karavan-space/src/designer/route/DslProperties.tsx
index 82fd3dd9..8231759c 100644
--- a/karavan-space/src/designer/route/DslProperties.tsx
+++ b/karavan-space/src/designer/route/DslProperties.tsx
@@ -41,8 +41,7 @@ interface Props {
export function DslProperties(props: Props) {
- const [integration, setIntegration] = useIntegrationStore((state) =>
- [state.integration, state.setIntegration], shallow)
+ const [integration] = useIntegrationStore((state) => [state.integration], shallow)
const {cloneElement, onDataFormatChange, onPropertyChange, onParametersChange, onExpressionChange} = usePropertiesHook(props.isRouteDesigner);
diff --git a/karavan-space/src/designer/route/RouteDesigner.tsx b/karavan-space/src/designer/route/RouteDesigner.tsx
index 7d3b5950..215f334b 100644
--- a/karavan-space/src/designer/route/RouteDesigner.tsx
+++ b/karavan-space/src/designer/route/RouteDesigner.tsx
@@ -36,14 +36,16 @@ import useResizeObserver from "./useResizeObserver";
import {Command, EventBus} from "../utils/EventBus";
import useMutationsObserver from "./useDrawerMutationsObserver";
import {DeleteConfirmation} from "./DeleteConfirmation";
+import {DslElementMoveModal} from "./DslElementMoveModal";
export function RouteDesigner() {
const {openSelector, createRouteConfiguration, onCommand, handleKeyDown, handleKeyUp, unselectElement} = useRouteDesignerHook();
const [integration] = useIntegrationStore((state) => [state.integration], shallow)
- const [showDeleteConfirmation, setPosition, width, height, top, left, hideLogDSL] = useDesignerStore((s) =>
- [s.showDeleteConfirmation, s.setPosition, s.width, s.height, s.top, s.left, s.hideLogDSL], shallow)
+ const [showDeleteConfirmation, setPosition, width, height, top, left, hideLogDSL, showMoveConfirmation, setShowMoveConfirmation] =
+ useDesignerStore((s) =>
+ [s.showDeleteConfirmation, s.setPosition, s.width, s.height, s.top, s.left, s.hideLogDSL, s.showMoveConfirmation, s.setShowMoveConfirmation], shallow)
const [showSelector] = useSelectorStore((s) => [s.showSelector], shallow)
@@ -161,6 +163,7 @@ export function RouteDesigner() {
</div>
{showSelector && <DslSelector/>}
{showDeleteConfirmation && <DeleteConfirmation/>}
+ {showMoveConfirmation && <DslElementMoveModal/>}
</div>
)
}
\ No newline at end of file
diff --git a/karavan-web/karavan-app/src/main/webui/src/designer/DesignerStore.ts b/karavan-web/karavan-app/src/main/webui/src/designer/DesignerStore.ts
index 15a9b7be..4831855f 100644
--- a/karavan-web/karavan-app/src/main/webui/src/designer/DesignerStore.ts
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/DesignerStore.ts
@@ -166,7 +166,9 @@ type DesignerState = {
height: number,
top: number,
left: number,
+ moveElements: [string | undefined, string | undefined]
}
+
const designerState: DesignerState = {
notificationBadge: false,
notificationMessage: ['', ''],
@@ -182,6 +184,7 @@ const designerState: DesignerState = {
height: 0,
top: 0,
left: 0,
+ moveElements: [undefined, undefined]
};
type DesignerAction = {
@@ -197,6 +200,7 @@ type DesignerAction = {
setPosition: (width: number, height: number, top: number, left: number) => void;
reset: () => void;
setNotification: (notificationBadge: boolean, notificationMessage: [string, string]) => void;
+ setMoveElements: (moveElements: [string | undefined, string | undefined]) => void;
}
export const useDesignerStore = createWithEqualityFn<DesignerState & DesignerAction>((set) => ({
@@ -248,5 +252,8 @@ export const useDesignerStore = createWithEqualityFn<DesignerState & DesignerAct
},
setNotification: (notificationBadge: boolean, notificationMessage: [string, string]) => {
set({notificationBadge: notificationBadge, notificationMessage: notificationMessage})
+ },
+ setMoveElements: (moveElements: [string | undefined, string | undefined]) => {
+ set({moveElements: moveElements})
}
}), shallow)
\ No newline at end of file
diff --git a/karavan-web/karavan-app/src/main/webui/src/designer/KaravanDesigner.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/KaravanDesigner.tsx
index 71914986..766b4e1f 100644
--- a/karavan-web/karavan-app/src/main/webui/src/designer/KaravanDesigner.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/KaravanDesigner.tsx
@@ -134,7 +134,8 @@ export function KaravanDesigner(props: Props) {
const isKamelet = integration.type === 'kamelet';
return (
- <PageSection variant={props.dark ? PageSectionVariants.darker : PageSectionVariants.light} className="page"
+ <PageSection variant={props.dark ? PageSectionVariants.darker : PageSectionVariants.light}
+ className="page"
isFilled padding={{default: 'noPadding'}}>
<div className={"main-tabs-wrapper"}>
<Tabs className="main-tabs"
diff --git a/karavan-web/karavan-app/src/main/webui/src/designer/route/DslElement.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/route/DslElement.tsx
index 5f2744c5..0d246b20 100644
--- a/karavan-web/karavan-app/src/main/webui/src/designer/route/DslElement.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/route/DslElement.tsx
@@ -16,9 +16,6 @@
*/
import React, {CSSProperties, useMemo, useState} from 'react';
import {
- Button,
- Flex,
- Modal, ModalVariant,
Text, Tooltip,
} from '@patternfly/react-core';
import '../karavan.css';
@@ -49,13 +46,12 @@ export function DslElement(props: Props) {
const [integration] = useIntegrationStore((s) => [s.integration, s.setIntegration], shallow)
- const [selectedUuids, selectedStep, showMoveConfirmation, setShowMoveConfirmation, hideLogDSL] =
+ const [selectedUuids, setShowMoveConfirmation, hideLogDSL, setMoveElements] =
useDesignerStore((s) =>
- [s.selectedUuids, s.selectedStep, s.showMoveConfirmation, s.setShowMoveConfirmation, s.hideLogDSL], shallow)
+ [s.selectedUuids, s.setShowMoveConfirmation, s.hideLogDSL, s.setMoveElements], shallow)
const [isDragging, setIsDragging] = useState<boolean>(false);
const [isDraggedOver, setIsDraggedOver] = useState<boolean>(false);
- const [moveElements, setMoveElements] = useState<[string | undefined, string | undefined]>([undefined, undefined]);
function onOpenSelector(evt: React.MouseEvent, showSteps: boolean = true, isInsert: boolean = false) {
evt.stopPropagation();
@@ -92,20 +88,6 @@ export function DslElement(props: Props) {
}
}
- function confirmMove(asChild: boolean) {
- const sourceUuid = moveElements[0];
- const targetUuid = moveElements[1];
- if (sourceUuid && targetUuid && sourceUuid !== targetUuid) {
- moveElement(sourceUuid, targetUuid, asChild);
- cancelMove();
- }
- }
-
- function cancelMove() {
- setShowMoveConfirmation(false);
- setMoveElements([undefined, undefined]);
- }
-
function isElementSelected(): boolean {
return selectedUuids.includes(props.step.uuid);
}
@@ -388,7 +370,8 @@ export function DslElement(props: Props) {
function getAddElementButton() {
return (
- <Tooltip position={"bottom"} content={<div>{"Add DSL element to " + CamelDisplayUtil.getTitle(props.step)}</div>}>
+ <Tooltip position={"bottom"}
+ content={<div>{"Add DSL element to " + CamelDisplayUtil.getTitle(props.step)}</div>}>
<button
type="button"
aria-label="Add"
@@ -419,25 +402,6 @@ export function DslElement(props: Props) {
)
}
- function getMoveConfirmation() {
- return (
- <Modal
- aria-label="title"
- className='move-modal'
- isOpen={showMoveConfirmation}
- variant={ModalVariant.small}
- ><Flex direction={{default: "column"}}>
- <div>Select move type:</div>
- <Button key="place" variant="primary" onClick={event => confirmMove(false)}>Shift (target down)</Button>
- <Button key="child" variant="secondary" onClick={event => confirmMove(true)}>Move as target
- step</Button>
- <Button key="cancel" variant="tertiary" onClick={event => cancelMove()}>Cancel</Button>
- </Flex>
-
- </Modal>
- )
- }
-
const element: CamelElement = props.step;
const className = "step-element" + (isElementSelected() ? " step-element-selected" : "") + (!props.step.showChildren ? " hidden-step" : "");
return (
@@ -487,7 +451,6 @@ export function DslElement(props: Props) {
>
{getElementHeader()}
{getChildElements()}
- {getMoveConfirmation()}
</div>
)
}
diff --git a/karavan-web/karavan-app/src/main/webui/src/designer/route/DslElementMoveModal.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/route/DslElementMoveModal.tsx
new file mode 100644
index 00000000..d1e17ecf
--- /dev/null
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/route/DslElementMoveModal.tsx
@@ -0,0 +1,81 @@
+/*
+ * 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 {
+ Button,
+ Flex,
+ Modal, ModalVariant,
+} from '@patternfly/react-core';
+import '../karavan.css';
+import {useDesignerStore, useIntegrationStore} from "../DesignerStore";
+import {shallow} from "zustand/shallow";
+import {useRouteDesignerHook} from "./useRouteDesignerHook";
+import {CamelDefinitionApiExt} from "karavan-core/lib/api/CamelDefinitionApiExt";
+
+export function DslElementMoveModal() {
+
+ const {moveElement} = useRouteDesignerHook();
+ const [integration] = useIntegrationStore((s) => [s.integration, s.setIntegration], shallow)
+ const [ showMoveConfirmation, setShowMoveConfirmation, moveElements, setMoveElements] =
+ useDesignerStore((s) =>
+ [s.showMoveConfirmation, s.setShowMoveConfirmation, s.moveElements, s.setMoveElements], shallow)
+
+ function confirmMove(asChild: boolean) {
+ const sourceUuid = moveElements[0];
+ const targetUuid = moveElements[1];
+ if (sourceUuid && targetUuid && sourceUuid !== targetUuid) {
+ moveElement(sourceUuid, targetUuid, asChild);
+ cancelMove();
+ }
+ }
+
+ function cancelMove() {
+ setShowMoveConfirmation(false);
+ setMoveElements([undefined, undefined]);
+ }
+
+ function canReplace() {
+ const targetUuid = moveElements[1];
+ if (targetUuid) {
+ const targetElement = CamelDefinitionApiExt.findElementInIntegration(integration, targetUuid);
+ if (targetElement) {
+ return !['WhenDefinition', 'OtherwiseDefinition'].includes(targetElement?.dslName);
+ }
+ }
+ return true;
+ }
+
+ return (
+ <Modal
+ aria-label="title"
+ className='move-modal'
+ isOpen={showMoveConfirmation}
+ onClose={event => cancelMove()}
+ variant={ModalVariant.small}
+ >
+ <Flex direction={{default: "column"}}>
+ <div>Select move type:</div>
+ {canReplace() && <Button key="place" variant="primary" onClick={event => confirmMove(false)}
+ >
+ Replace (target down)
+ </Button>}
+ <Button key="child" variant="secondary" onClick={event => confirmMove(true)}>Set as child</Button>
+ <Button key="cancel" variant="tertiary" onClick={event => cancelMove()}>Cancel</Button>
+ </Flex>
+ </Modal>
+ )
+}
diff --git a/karavan-web/karavan-app/src/main/webui/src/designer/route/DslProperties.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/route/DslProperties.tsx
index 82fd3dd9..8231759c 100644
--- a/karavan-web/karavan-app/src/main/webui/src/designer/route/DslProperties.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/route/DslProperties.tsx
@@ -41,8 +41,7 @@ interface Props {
export function DslProperties(props: Props) {
- const [integration, setIntegration] = useIntegrationStore((state) =>
- [state.integration, state.setIntegration], shallow)
+ const [integration] = useIntegrationStore((state) => [state.integration], shallow)
const {cloneElement, onDataFormatChange, onPropertyChange, onParametersChange, onExpressionChange} = usePropertiesHook(props.isRouteDesigner);
diff --git a/karavan-web/karavan-app/src/main/webui/src/designer/route/RouteDesigner.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/route/RouteDesigner.tsx
index 7d3b5950..215f334b 100644
--- a/karavan-web/karavan-app/src/main/webui/src/designer/route/RouteDesigner.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/route/RouteDesigner.tsx
@@ -36,14 +36,16 @@ import useResizeObserver from "./useResizeObserver";
import {Command, EventBus} from "../utils/EventBus";
import useMutationsObserver from "./useDrawerMutationsObserver";
import {DeleteConfirmation} from "./DeleteConfirmation";
+import {DslElementMoveModal} from "./DslElementMoveModal";
export function RouteDesigner() {
const {openSelector, createRouteConfiguration, onCommand, handleKeyDown, handleKeyUp, unselectElement} = useRouteDesignerHook();
const [integration] = useIntegrationStore((state) => [state.integration], shallow)
- const [showDeleteConfirmation, setPosition, width, height, top, left, hideLogDSL] = useDesignerStore((s) =>
- [s.showDeleteConfirmation, s.setPosition, s.width, s.height, s.top, s.left, s.hideLogDSL], shallow)
+ const [showDeleteConfirmation, setPosition, width, height, top, left, hideLogDSL, showMoveConfirmation, setShowMoveConfirmation] =
+ useDesignerStore((s) =>
+ [s.showDeleteConfirmation, s.setPosition, s.width, s.height, s.top, s.left, s.hideLogDSL, s.showMoveConfirmation, s.setShowMoveConfirmation], shallow)
const [showSelector] = useSelectorStore((s) => [s.showSelector], shallow)
@@ -161,6 +163,7 @@ export function RouteDesigner() {
</div>
{showSelector && <DslSelector/>}
{showDeleteConfirmation && <DeleteConfirmation/>}
+ {showMoveConfirmation && <DslElementMoveModal/>}
</div>
)
}
\ No newline at end of file