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 7b921b7 Some improvements (#202)
7b921b7 is described below
commit 7b921b790b4dbd7f506e7cd91a749c4fe7b00ad3
Author: Marat Gubaidullin <[email protected]>
AuthorDate: Fri Feb 25 18:37:57 2022 -0500
Some improvements (#202)
* Rest database example
* Bean resign sync
* Dependency design sync
* Dependency design sync
* Experiments
* Remove MultiValueObjectField button
---
karavan-core/src/core/api/CamelDefinitionApiExt.ts | 2 +-
karavan-demo/integrations/README.MD | 9 --
.../integrations/{ => experiments}/Example.java | 0
.../{ => experiments}/docker-compose.yml | 20 ---
.../{ => experiments}/http-to-kafka.yaml | 0
.../integrations/{ => experiments}/postgres_db.sql | 0
.../integrations/{ => experiments}/rest-dsl.yaml | 0
.../{ => experiments}/sql-to-log-int.yaml | 0
.../integrations/{ => experiments}/sql-to-log.yaml | 0
.../integrations/{ => experiments}/xxx.groovy | 0
.../integrations/{ => experiments}/zzz-int.yaml | 2 +-
.../integrations/{ => experiments}/zzz.yaml | 0
karavan-demo/integrations/rest-database/README.MD | 28 ++++
.../integrations/rest-database/docker-compose.yml | 27 ++++
.../{ => rest-database}/postgres_db.sql | 0
.../integrations/rest-database/rest-database.yaml | 51 +++++++
karavan-demo/integrations/xxx.yaml | 12 ++
karavan-designer/src/App.tsx | 6 +-
karavan-designer/src/designer/KaravanDesigner.tsx | 4 +-
karavan-designer/src/designer/beans/BeanCard.tsx | 65 ++++++++
.../src/designer/beans/BeansDesigner.tsx | 65 +++-----
.../designer/dependencies/DependenciesDesigner.tsx | 67 +++------
.../src/designer/dependencies/DependencyCard.tsx | 63 ++++++++
karavan-designer/src/designer/karavan.css | 165 +++++----------------
.../src/designer/route/DslProperties.tsx | 2 +-
.../designer/route/property/DslPropertyField.tsx | 11 +-
karavan-designer/src/designer/utils/CamelUi.ts | 5 +-
27 files changed, 344 insertions(+), 260 deletions(-)
diff --git a/karavan-core/src/core/api/CamelDefinitionApiExt.ts
b/karavan-core/src/core/api/CamelDefinitionApiExt.ts
index 7fc1fff..d151748 100644
--- a/karavan-core/src/core/api/CamelDefinitionApiExt.ts
+++ b/karavan-core/src/core/api/CamelDefinitionApiExt.ts
@@ -438,7 +438,7 @@ export class CamelDefinitionApiExt {
let expression: any = undefined;
let parameters: any = undefined;
if (className) {
- const properties = className.endsWith("Definition")
+ const properties = (className.endsWith("Definition") ||
className.endsWith("BuilderRef"))
?
CamelMetadataApi.getCamelModelMetadataByClassName(className)?.properties
: (className.endsWith("DataFormat")
?
CamelMetadataApi.getCamelDataFormatMetadataByClassName(className)?.properties
diff --git a/karavan-demo/integrations/README.MD
b/karavan-demo/integrations/README.MD
deleted file mode 100644
index 70c04cc..0000000
--- a/karavan-demo/integrations/README.MD
+++ /dev/null
@@ -1,9 +0,0 @@
-# Examples
-
-1. Http to Kafka
-```
-curl -X POST -H "Content-Type: application/json" --data
'{"clientId":1,"amount":1000, "description":"some data"}'
http://0.0.0.0:8080/demo
-```
-```
-curl -X POST -H "Content-Type: application/json" --data
'{"clientId":2,"amount":10000, "description":"some data"}'
http://0.0.0.0:8080/demo
-```
\ No newline at end of file
diff --git a/karavan-demo/integrations/Example.java
b/karavan-demo/integrations/experiments/Example.java
similarity index 100%
rename from karavan-demo/integrations/Example.java
rename to karavan-demo/integrations/experiments/Example.java
diff --git a/karavan-demo/integrations/docker-compose.yml
b/karavan-demo/integrations/experiments/docker-compose.yml
similarity index 87%
rename from karavan-demo/integrations/docker-compose.yml
rename to karavan-demo/integrations/experiments/docker-compose.yml
index ad027df..4b88e47 100644
--- a/karavan-demo/integrations/docker-compose.yml
+++ b/karavan-demo/integrations/experiments/docker-compose.yml
@@ -11,8 +11,6 @@ services:
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
- networks:
- - karavan-demo
zookeeper:
container_name: zookeeper
@@ -22,8 +20,6 @@ services:
environment:
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 2000
- networks:
- - karavan-demo
kafka:
container_name: kafka
@@ -40,8 +36,6 @@ services:
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_CREATE_TOPICS: "events:1:1"
- networks:
- - karavan-demo
activemq:
image: registry.redhat.io/amq7/amq-broker:latest
@@ -52,8 +46,6 @@ services:
ports:
- "61616:61616"
- "8161:8161"
- networks:
- - karavan-demo
postgres:
image: postgres
@@ -68,8 +60,6 @@ services:
volumes:
- ./postgres_db.sql:/docker-entrypoint-initdb.d/postgres_db.sql
command: 'postgres --max_prepared_transactions=100'
- networks:
- - karavan-demo
pgadmin:
container_name: pgadmin
@@ -80,8 +70,6 @@ services:
PGADMIN_DEFAULT_PASSWORD: root
ports:
- "5050:80"
- networks:
- - karavan-demo
mysql:
image: mysql
@@ -98,8 +86,6 @@ services:
- '3306:3306'
expose:
- '3306'
- networks:
- - karavan-demo
adminer:
image: adminer
@@ -107,9 +93,3 @@ services:
restart: always
ports:
- 6060:8080
- networks:
- - karavan-demo
-
-networks:
- karavan-demo:
- name: karavan-demo
diff --git a/karavan-demo/integrations/http-to-kafka.yaml
b/karavan-demo/integrations/experiments/http-to-kafka.yaml
similarity index 100%
rename from karavan-demo/integrations/http-to-kafka.yaml
rename to karavan-demo/integrations/experiments/http-to-kafka.yaml
diff --git a/karavan-demo/integrations/postgres_db.sql
b/karavan-demo/integrations/experiments/postgres_db.sql
similarity index 100%
copy from karavan-demo/integrations/postgres_db.sql
copy to karavan-demo/integrations/experiments/postgres_db.sql
diff --git a/karavan-demo/integrations/rest-dsl.yaml
b/karavan-demo/integrations/experiments/rest-dsl.yaml
similarity index 100%
rename from karavan-demo/integrations/rest-dsl.yaml
rename to karavan-demo/integrations/experiments/rest-dsl.yaml
diff --git a/karavan-demo/integrations/sql-to-log-int.yaml
b/karavan-demo/integrations/experiments/sql-to-log-int.yaml
similarity index 100%
rename from karavan-demo/integrations/sql-to-log-int.yaml
rename to karavan-demo/integrations/experiments/sql-to-log-int.yaml
diff --git a/karavan-demo/integrations/sql-to-log.yaml
b/karavan-demo/integrations/experiments/sql-to-log.yaml
similarity index 100%
rename from karavan-demo/integrations/sql-to-log.yaml
rename to karavan-demo/integrations/experiments/sql-to-log.yaml
diff --git a/karavan-demo/integrations/xxx.groovy
b/karavan-demo/integrations/experiments/xxx.groovy
similarity index 100%
rename from karavan-demo/integrations/xxx.groovy
rename to karavan-demo/integrations/experiments/xxx.groovy
diff --git a/karavan-demo/integrations/zzz-int.yaml
b/karavan-demo/integrations/experiments/zzz-int.yaml
similarity index 89%
rename from karavan-demo/integrations/zzz-int.yaml
rename to karavan-demo/integrations/experiments/zzz-int.yaml
index ab35d5d..31007cf 100644
--- a/karavan-demo/integrations/zzz-int.yaml
+++ b/karavan-demo/integrations/experiments/zzz-int.yaml
@@ -16,7 +16,7 @@ spec:
- content: |-
beans {
myProcessor = processor {
- it.in.body = 'Hello Camel K!'
+ it.in.body = 'Hello World!'
}
}
name: xxx.groovy
diff --git a/karavan-demo/integrations/zzz.yaml
b/karavan-demo/integrations/experiments/zzz.yaml
similarity index 100%
rename from karavan-demo/integrations/zzz.yaml
rename to karavan-demo/integrations/experiments/zzz.yaml
diff --git a/karavan-demo/integrations/rest-database/README.MD
b/karavan-demo/integrations/rest-database/README.MD
new file mode 100644
index 0000000..271c1f2
--- /dev/null
+++ b/karavan-demo/integrations/rest-database/README.MD
@@ -0,0 +1,28 @@
+## REST service to store/retrieve data to/from database (Postgres)
+Localhost Integration prototype with Camel & Jbang
+
+## Prerequisites
+Docker, docker-compose, jbang, VSCode with Camel Karavan extension installed
+
+## How to
+
+1. Start Docker compose (Postgres and PgAdmin)
+```
+docker-compose up
+```
+
+2. Start Camel integration
+```
+jbang camel@apache/camel run rest-database.yaml --logging-level=info
+```
+
+3. Store data to database
+```
+curl -X POST -H "Content-Type: application/json" --data '{"id":1,"name":"John
Doe"}' http://0.0.0.0:8080/client
+curl -X POST -H "Content-Type: application/json" --data '{"id":2,"name":"Jane
Doe"}' http://0.0.0.0:8080/client
+```
+
+4. Retrieve data from database
+```
+curl -X GET -H "Content-Type: application/json" http://0.0.0.0:8080/client
+```
\ No newline at end of file
diff --git a/karavan-demo/integrations/rest-database/docker-compose.yml
b/karavan-demo/integrations/rest-database/docker-compose.yml
new file mode 100644
index 0000000..50a0394
--- /dev/null
+++ b/karavan-demo/integrations/rest-database/docker-compose.yml
@@ -0,0 +1,27 @@
+---
+version: '3.8'
+services:
+
+ postgres:
+ image: postgres
+ container_name: postgres
+ restart: always
+ environment:
+ - POSTGRES_USER=postgres
+ - POSTGRES_PASSWORD=postgres
+ - POSTGRES_DB=demo
+ ports:
+ - '5432:5432'
+ volumes:
+ - ./postgres_db.sql:/docker-entrypoint-initdb.d/postgres_db.sql
+ command: 'postgres --max_prepared_transactions=100'
+
+ pgadmin:
+ container_name: pgadmin
+ image: dpage/pgadmin4
+ restart: always
+ environment:
+ PGADMIN_DEFAULT_EMAIL: [email protected]
+ PGADMIN_DEFAULT_PASSWORD: root
+ ports:
+ - "5050:80"
\ No newline at end of file
diff --git a/karavan-demo/integrations/postgres_db.sql
b/karavan-demo/integrations/rest-database/postgres_db.sql
similarity index 100%
rename from karavan-demo/integrations/postgres_db.sql
rename to karavan-demo/integrations/rest-database/postgres_db.sql
diff --git a/karavan-demo/integrations/rest-database/rest-database.yaml
b/karavan-demo/integrations/rest-database/rest-database.yaml
new file mode 100644
index 0000000..8fd9a52
--- /dev/null
+++ b/karavan-demo/integrations/rest-database/rest-database.yaml
@@ -0,0 +1,51 @@
+- rest:
+ post:
+ - path: client
+ to: direct:post
+ get:
+ - path: client
+ to: direct:get
+ consumes: application/json
+ produces: application/json
+ bindingMode: 'off'
+- route:
+ from:
+ uri: direct:get
+ steps:
+ - setBody:
+ expression:
+ simple:
+ expression: '" "'
+ resultType: String
+ - kamelet:
+ name: postgresql-sink
+ parameters:
+ serverName: localhost
+ serverPort: '5432'
+ username: postgres
+ password: postgres
+ query: SELECT * FROM table1
+ databaseName: demo
+ - marshal:
+ json:
+ library: jackson
+ id: get
+- route:
+ from:
+ uri: direct:post
+ steps:
+ - kamelet:
+ name: postgresql-sink
+ parameters:
+ serverName: localhost
+ serverPort: '5432'
+ username: postgres
+ password: postgres
+ databaseName: demo
+ query: >-
+ INSERT INTO table1 (id,name) VALUES (:#id,:#name) ON CONFLICT
+ (id) DO UPDATE SET name = :#name
+ - marshal:
+ json:
+ library: jackson
+ id: post
diff --git a/karavan-demo/integrations/xxx.yaml
b/karavan-demo/integrations/xxx.yaml
new file mode 100644
index 0000000..e5196d9
--- /dev/null
+++ b/karavan-demo/integrations/xxx.yaml
@@ -0,0 +1,12 @@
+- route:
+ from:
+ uri: as2
+ steps:
+ - filter:
+ expression:
+ simple:
+ expression: ${body} != null
+ steps:
+ - unmarshal:
+ json:
+ library: jackson
diff --git a/karavan-designer/src/App.tsx b/karavan-designer/src/App.tsx
index 2c8ac9e..7693d24 100644
--- a/karavan-designer/src/App.tsx
+++ b/karavan-designer/src/App.tsx
@@ -41,9 +41,9 @@ class App extends React.Component<Props, State> {
'metadata:\n' +
' name: demo.yaml \n' +
'spec:\n' +
- ' dependencies:\n' +
- ' - "mvn:org.apache.commons:commons-dbcp2:2.9.0" \n' +
- ' - "mvn:org.postgresql:postgresql:42.2.14" \n' +
+ // ' dependencies:\n' +
+ // ' - "mvn:org.apache.commons:commons-dbcp2:2.9.0" \n' +
+ // ' - "mvn:org.postgresql:postgresql:42.2.14" \n' +
' flows:\n' +
// ' - route:\n' +
// ' from:\n' +
diff --git a/karavan-designer/src/designer/KaravanDesigner.tsx
b/karavan-designer/src/designer/KaravanDesigner.tsx
index 427645b..dda7bf8 100644
--- a/karavan-designer/src/designer/KaravanDesigner.tsx
+++ b/karavan-designer/src/designer/KaravanDesigner.tsx
@@ -75,13 +75,15 @@ export class KaravanDesigner extends React.Component<Props,
State> {
getTab(title: string, tooltip: string, icon: string) {
const counts = CamelUi.getFlowCounts(this.state.integration);
+ const count = counts.has(icon) && counts.get(icon) ? counts.get(icon)
: undefined;
+ const showCount = count && count > 0;
return (
<Tooltip position={"bottom"}
content={<div>{tooltip}</div>}>
<div className="top-menu-item">
<TabTitleIcon>{this.getIcon(icon)}</TabTitleIcon>
<TabTitleText>{title}</TabTitleText>
- {counts.has(icon) && <Badge isRead
className="count">{counts.get(icon)}</Badge>}
+ {showCount && <Badge isRead
className="count">{counts.get(icon)}</Badge>}
</div>
</Tooltip>
diff --git a/karavan-designer/src/designer/beans/BeanCard.tsx
b/karavan-designer/src/designer/beans/BeanCard.tsx
new file mode 100644
index 0000000..803272f
--- /dev/null
+++ b/karavan-designer/src/designer/beans/BeanCard.tsx
@@ -0,0 +1,65 @@
+/*
+ * 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
+} from '@patternfly/react-core';
+import '../karavan.css';
+import {Integration} from "karavan-core/lib/model/IntegrationDefinition";
+import {NamedBeanDefinition} from "karavan-core/lib/model/CamelDefinition";
+import DeleteIcon from
"@patternfly/react-icons/dist/js/icons/times-circle-icon";
+
+interface Props {
+ bean: NamedBeanDefinition
+ selectedStep?: NamedBeanDefinition
+ integration: Integration
+ selectElement: (element: NamedBeanDefinition) => void
+ deleteElement: (element: NamedBeanDefinition) => void
+}
+
+export class BeanCard extends React.Component<Props, any> {
+
+ selectElement = (evt: React.MouseEvent) => {
+ evt.stopPropagation();
+ this.props.selectElement.call(this, this.props.bean);
+ }
+
+ delete = (evt: React.MouseEvent) => {
+ evt.stopPropagation();
+ this.props.deleteElement.call(this, this.props.bean);
+ }
+
+ render() {
+ const bean = this.props.bean;
+ return (
+ <div className={this.props.selectedStep?.uuid === bean.uuid ?
"rest-card rest-card-selected" : "rest-card rest-card-unselected"} onClick={e
=> this.selectElement(e)}>
+ <div className="header">
+ <div className="title">BEAN</div>
+ <div className="title">{bean.name}</div>
+ <div className="description">{bean.type}</div>
+ {/*<Tooltip position={"bottom"} content={<div>Add REST
method</div>}>*/}
+ {/*<Button variant={"link"} icon={<AddIcon/>}
aria-label="Add" onClick={e => this.selectMethod(e)} className="add-button">Add
method</Button>*/}
+ {/*</Tooltip>*/}
+ <Button variant="link" className="delete-button"
onClick={e => this.delete(e)}><DeleteIcon/></Button>
+ </div>
+ <div className="rest-content" key={Math.random().toString()}>
+
+ </div>
+ </div>
+ );
+ }
+}
diff --git a/karavan-designer/src/designer/beans/BeansDesigner.tsx
b/karavan-designer/src/designer/beans/BeansDesigner.tsx
index 33bcf57..99bafba 100644
--- a/karavan-designer/src/designer/beans/BeansDesigner.tsx
+++ b/karavan-designer/src/designer/beans/BeansDesigner.tsx
@@ -16,7 +16,7 @@
*/
import React from 'react';
import {
- Button, Card, CardBody, CardFooter, CardHeader, CardTitle, Gallery, Modal,
PageSection
+ Button, Modal, PageSection
} from '@patternfly/react-core';
import '../karavan.css';
import {NamedBeanDefinition} from "karavan-core/lib/model/CamelDefinition";
@@ -24,10 +24,9 @@ import {Integration} from
"karavan-core/lib/model/IntegrationDefinition";
import {CamelUi} from "../utils/CamelUi";
import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
import {CamelDefinitionApiExt} from
"karavan-core/lib/api/CamelDefinitionApiExt";
-import DeleteIcon from
"@patternfly/react-icons/dist/js/icons/times-circle-icon";
-import {BeanIcon} from "../utils/KaravanIcons";
import {BeanProperties} from "./BeanProperties";
import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
+import {BeanCard} from "./BeanCard";
interface Props {
onSave?: (integration: Integration) => void
@@ -54,26 +53,13 @@ export class BeansDesigner extends React.Component<Props,
State> {
showBeanEditor: false,
};
- componentDidMount() {
- window.addEventListener('resize', this.handleResize);
- }
-
- componentWillUnmount() {
- window.removeEventListener('resize', this.handleResize);
- }
-
- handleResize = () => {
- this.setState({key: Math.random().toString()});
- }
-
componentDidUpdate = (prevProps: Readonly<Props>, prevState:
Readonly<State>, snapshot?: any) => {
if (prevState.key !== this.state.key) {
this.props.onSave?.call(this, this.state.integration);
}
}
- showDeleteConfirmation = (e: React.MouseEvent, bean: NamedBeanDefinition)
=> {
- e.stopPropagation();
+ showDeleteConfirmation = (bean: NamedBeanDefinition) => {
this.setState({selectedBean: bean, showDeleteConfirmation: true});
}
@@ -130,36 +116,27 @@ export class BeansDesigner extends React.Component<Props,
State> {
this.changeBean(new NamedBeanDefinition());
}
- getCard(bean: NamedBeanDefinition, index: number) {
- return (
- <Card key={bean.dslName + index} isHoverable isCompact
- className={this.state.selectedBean?.uuid === bean.uuid ?
"bean-card bean-card-selected" : "bean-card bean-card-unselected"}
- onClick={e => this.selectBean(bean)}>
- <Button variant="link" className="delete-button" onClick={e =>
this.showDeleteConfirmation(e, bean)}><DeleteIcon/></Button>
- <CardHeader>
- <div className="header-icon"><BeanIcon/></div>
- </CardHeader>
- <CardTitle>{bean.name}</CardTitle>
- <CardBody>{bean.type}</CardBody>
- <CardFooter className="">
- </CardFooter>
- </Card>
- )
- }
-
render() {
const beans = CamelUi.getBeans(this.state.integration);
return (
- <PageSection className="beans-page" isFilled padding={{default:
'noPadding'}}>
- <div className="beans-page-columns" data-click="BEANS"
onClick={event => this.unselectBean(event)}>
- <div className="beans-panel">
- <Gallery hasGutter className="beans-gallery"
data-click="BEANS" onClick={event => this.unselectBean(event)}>
- {beans.map((bean: NamedBeanDefinition, index:
number) => this.getCard(bean, index))}
- </Gallery>
- <div className="add-button-div" data-click="BEANS"
onClick={event => this.unselectBean(event)}>
- <Button icon={<PlusIcon/>} variant={beans.length
=== 0 ? "primary" : "secondary"} onClick={e => this.createBean()}
className="add-bean-button">
- Create new bean
- </Button>
+ <PageSection className="rest-page" isFilled padding={{default:
'noPadding'}}>
+ <div className="rest-page-columns">
+ <div className="graph" data-click="REST" onClick={event
=> this.unselectBean(event)}>
+ <div className="flows">
+ {beans?.map(bean => <BeanCard key={bean.uuid +
this.state.key}
+
selectedStep={this.state.selectedBean}
+ bean={bean}
+
integration={this.props.integration}
+
selectElement={this.selectBean}
+
deleteElement={this.showDeleteConfirmation}/>)}
+ <div className="add-rest">
+ <Button
+ variant={beans?.length === 0 ? "primary" :
"secondary"}
+ data-click="ADD_REST"
+ icon={<PlusIcon/>}
+ onClick={e => this.createBean()}>Create
new bean
+ </Button>
+ </div>
</div>
</div>
<BeanProperties integration={this.props.integration}
diff --git
a/karavan-designer/src/designer/dependencies/DependenciesDesigner.tsx
b/karavan-designer/src/designer/dependencies/DependenciesDesigner.tsx
index 877b132..e4c4f79 100644
--- a/karavan-designer/src/designer/dependencies/DependenciesDesigner.tsx
+++ b/karavan-designer/src/designer/dependencies/DependenciesDesigner.tsx
@@ -16,17 +16,16 @@
*/
import React from 'react';
import {
- Button, Card, CardFooter, CardHeader, CardTitle, Gallery, Modal,
PageSection
+ Button, Modal, PageSection
} from '@patternfly/react-core';
import '../karavan.css';
import {CamelUi} from "../utils/CamelUi";
import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
-import DeleteIcon from
"@patternfly/react-icons/dist/js/icons/times-circle-icon";
-import {DependencyIcon} from "../utils/KaravanIcons";
import {DependencyProperties} from "./DependencyProperties";
import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
import {Integration, Dependency} from
"karavan-core/lib/model/IntegrationDefinition";
import {CamelDefinitionApiExt} from
"karavan-core/lib/api/CamelDefinitionApiExt";
+import {DependencyCard} from "./DependencyCard";
interface Props {
onSave?: (integration: Integration) => void
@@ -53,26 +52,13 @@ export class DependenciesDesigner extends
React.Component<Props, State> {
showDepEditor: false,
};
- componentDidMount() {
- window.addEventListener('resize', this.handleResize);
- }
-
- componentWillUnmount() {
- window.removeEventListener('resize', this.handleResize);
- }
-
- handleResize = () => {
- this.setState({key: Math.random().toString()});
- }
-
componentDidUpdate = (prevProps: Readonly<Props>, prevState:
Readonly<State>, snapshot?: any) => {
if (prevState.key !== this.state.key) {
this.props.onSave?.call(this, this.state.integration);
}
}
- showDeleteConfirmation = (e: React.MouseEvent, dependency: Dependency) => {
- e.stopPropagation();
+ showDeleteConfirmation = (dependency: Dependency) => {
this.setState({selectedDep: dependency, showDeleteConfirmation: true});
}
@@ -133,36 +119,28 @@ export class DependenciesDesigner extends
React.Component<Props, State> {
this.changeDep(new Dependency());
}
- getCard(dep: Dependency, index: number) {
- return (
- <Card key={dep.uuid + index} isHoverable isCompact
- className={this.state.selectedDep?.uuid === dep.uuid ?
"bean-card bean-card-selected" : "bean-card bean-card-unselected"}
- onClick={e => this.selectDep(dep)}>
- <Button variant="link" className="delete-button" onClick={e =>
this.showDeleteConfirmation(e, dep)}><DeleteIcon/></Button>
- <CardHeader>
- <div className="header-icon"><DependencyIcon/></div>
- </CardHeader>
- <CardTitle>{dep.getFullName()}</CardTitle>
- {/*<CardBody>{dep}</CardBody>*/}
- <CardFooter className="">
- </CardFooter>
- </Card>
- )
- }
-
render() {
const deps = CamelUi.getDependencies(this.state.integration).sort((a,
b) => a.getFullName() > b.getFullName() ? 1 : -1 );
return (
- <PageSection className="beans-page" isFilled padding={{default:
'noPadding'}}>
- <div className="beans-page-columns" data-click="BEANS"
onClick={event => this.unselectDep(event)}>
- <div className="beans-panel">
- <Gallery hasGutter className="beans-gallery"
data-click="BEANS" onClick={event => this.unselectDep(event)}>
- {deps.map((dep: Dependency, index: number) =>
this.getCard(dep, index))}
- </Gallery>
- <div className="add-button-div" data-click="BEANS"
onClick={event => this.unselectDep(event)}>
- <Button icon={<PlusIcon/>} variant={deps.length
=== 0 ? "primary" : "secondary"} onClick={e => this.createDep()}
className="add-bean-button">
- Create new dependency
- </Button>
+ <PageSection className="rest-page" isFilled padding={{default:
'noPadding'}}>
+ <div className="rest-page-columns">
+ <div className="graph" data-click="REST" onClick={event
=> this.unselectDep(event)}>
+ <div className="flows">
+ {deps?.map(dep => <DependencyCard key={dep.uuid +
this.state.key}
+
selectedDep={this.state.selectedDep}
+ dep={dep}
+
integration={this.props.integration}
+
selectElement={this.selectDep}
+
deleteElement={this.showDeleteConfirmation}/>)
+ }
+ <div className="add-rest">
+ <Button
+ variant={deps?.length === 0 ? "primary" :
"secondary"}
+ data-click="ADD_DEPENDENCY"
+ icon={<PlusIcon/>}
+ onClick={e => this.createDep()}>Create new
dependency
+ </Button>
+ </div>
</div>
</div>
<DependencyProperties integration={this.props.integration}
@@ -172,6 +150,7 @@ export class DependenciesDesigner extends
React.Component<Props, State> {
</div>
{this.getDeleteConfirmation()}
</PageSection>
+
);
}
}
diff --git a/karavan-designer/src/designer/dependencies/DependencyCard.tsx
b/karavan-designer/src/designer/dependencies/DependencyCard.tsx
new file mode 100644
index 0000000..e6bf983
--- /dev/null
+++ b/karavan-designer/src/designer/dependencies/DependencyCard.tsx
@@ -0,0 +1,63 @@
+/*
+ * 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
+} from '@patternfly/react-core';
+import '../karavan.css';
+import {Dependency, Integration} from
"karavan-core/lib/model/IntegrationDefinition";
+import DeleteIcon from
"@patternfly/react-icons/dist/js/icons/times-circle-icon";
+
+interface Props {
+ dep: Dependency
+ selectedDep?: Dependency
+ integration: Integration
+ selectElement: (element: Dependency) => void
+ deleteElement: (element: Dependency) => void
+}
+
+export class DependencyCard extends React.Component<Props, any> {
+
+ selectElement = (evt: React.MouseEvent) => {
+ evt.stopPropagation();
+ this.props.selectElement.call(this, this.props.dep);
+ }
+
+ delete = (evt: React.MouseEvent) => {
+ evt.stopPropagation();
+ this.props.deleteElement.call(this, this.props.dep);
+ }
+
+ render() {
+ const dep = this.props.dep;
+ return (
+ <div className={this.props.selectedDep?.uuid === dep.uuid ?
"rest-card rest-card-selected" : "rest-card rest-card-unselected"} onClick={e
=> this.selectElement(e)}>
+ <div className="header">
+ <div className="title">DEPENDENCY</div>
+ <div className="title">{dep.getFullName()}</div>
+ {/*<Tooltip position={"bottom"} content={<div>Add REST
method</div>}>*/}
+ {/*<Button variant={"link"} icon={<AddIcon/>}
aria-label="Add" onClick={e => this.selectMethod(e)} className="add-button">Add
method</Button>*/}
+ {/*</Tooltip>*/}
+ <Button variant="link" className="delete-button"
onClick={e => this.delete(e)}><DeleteIcon/></Button>
+ </div>
+ <div className="rest-content" key={Math.random().toString()}>
+
+ </div>
+ </div>
+ );
+ }
+}
diff --git a/karavan-designer/src/designer/karavan.css
b/karavan-designer/src/designer/karavan.css
index c8aa7dd..aeba6a4 100644
--- a/karavan-designer/src/designer/karavan.css
+++ b/karavan-designer/src/designer/karavan.css
@@ -367,6 +367,19 @@
border-style: solid;
}
+.karavan .properties .object-value {
+ display: flex;
+ flex-direction: row;
+ margin-bottom: 3px;
+}
+
+.karavan .properties .object-value .delete-button {
+ margin: 0;
+ padding: 5px 3px 0px 6px;
+ height: 16px;
+ color: #909090;
+}
+
.karavan .properties .expression,
.karavan .properties .object,
.karavan .properties .dataformat,
@@ -375,6 +388,7 @@
padding-left: 16px;
row-gap: 6px;
display: grid;
+ width: 100%;
}
.karavan .properties .expression .pf-c-form__group-label,
@@ -803,138 +817,6 @@
background-color: #fca338;
}
-/*Beans*/
-.karavan .beans-page {
- flex: 1 1;
- overflow: auto;
-}
-.karavan .beans-page-columns {
- height: 100%;
- background: #fafafa;
- display: flex;
- flex-direction: row;
-}
-
-.karavan .beans-panel {
- padding: 16px;
- display: block;
- flex-direction: column;
- height: 100%;
- width: 100%;
- position: relative;
- overflow-y: auto;
-}
-.karavan .beans-page .add-button-div {
- width: 100%;
- margin-top: 16px;
- display: flex;
-}
-
-.karavan .beans-page .add-bean-button {
- margin: auto;
-}
-
-.karavan .beans-page .bean-card-selected {
- border-color: rgb(48, 50, 132);
- background-color: rgb(171, 172, 224, 0.1);
-}
-
-.karavan .beans-page .bean-card-unselected {
- border-color: #fb8824;
- background-color: transparent;
-}
-
-.karavan .beans-page .bean-card,
-.karavan .beans-page .bean-card:hover {
- border-radius: 16px;
- border-width: 1px;
- border-style: dotted;
- box-shadow: none;
-}
-
-.karavan .beans-page .bean-card .pf-c-card__header {
- padding-right: 6px;
- word-wrap:anywhere;
- width: 100%;
-}
-
-.karavan .beans-page .bean-card .pf-c-card__title {
- text-align: center;
- font-size: 14px;
-}
-
-.karavan .beans-page .bean-card .pf-c-card__body {
- word-wrap:anywhere;
- text-align: center;
- font-size: 14px;
-}
-
-.karavan .beans-page .bean-card .header-icon {
- border-style: solid;
- border-radius: 30px;
- border-width: 1px;
- width: 30px;
- height: 30px;
- margin: 6px auto auto auto;
- display: flex;
- justify-content: center;
- align-items: center;
-}
-
-.karavan .beans-page .bean-card-unselected .header-icon {
- border-color: #fb8824;
- background: transparent;
- border-width: 1px;
-}
-
-.karavan .beans-page .bean-card-selected .header-icon {
- border-color: rgb(48, 50, 132);
- background-color: rgb(171, 172, 224);
- border-width: 2px;
-}
-
-.karavan .beans-page .bean-card .icon {
- height: 20px;
- width: auto;
- border: none;
-}
-
-.karavan .beans-page .bean-card .delete-button {
- position: absolute;
- top: 4px;
- right: 4px;
- font-size: 14px;
- line-height: 1;
- border: 0;
- padding: 0;
- margin: 0;
- background: transparent;
- color: #909090;
- visibility: hidden;
-}
-
-.karavan .beans-page .bean-card:hover .delete-button {
- visibility: visible;
-}
-
-.karavan .beans-page .properties .bean-properties .pf-c-form__group-control {
- display: flex;
- flex-direction: column;
- gap: 6px;
-}
-
-.karavan .beans-page .properties .bean-property {
- display: flex;
- flex-direction: row;
- gap: 3px;
-}
-
-.karavan .beans-page .properties .bean-property .delete-button {
- padding: 3px;
- color: #b1b1b7;
- font-size: 14px;
-}
-
/*REST Page*/
.karavan .rest-page {
flex: 1;
@@ -1084,6 +966,25 @@
margin-top: 16px;
}
+/*Beans*/
+.karavan .rest-page .properties .bean-properties .pf-c-form__group-control {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+}
+
+.karavan .rest-page .properties .bean-property {
+ display: flex;
+ flex-direction: row;
+ gap: 3px;
+}
+
+.karavan .rest-page .properties .bean-property .delete-button {
+ padding: 3px;
+ color: #b1b1b7;
+ font-size: 14px;
+}
+
/*Exception*/
/*Template*/
/*Error*/
diff --git a/karavan-designer/src/designer/route/DslProperties.tsx
b/karavan-designer/src/designer/route/DslProperties.tsx
index 3e25b92..d709a76 100644
--- a/karavan-designer/src/designer/route/DslProperties.tsx
+++ b/karavan-designer/src/designer/route/DslProperties.tsx
@@ -131,7 +131,7 @@ export class DslProperties extends React.Component<Props,
State> {
.filter((p: PropertyMeta) => (showAdvanced &&
p.label.includes('advanced')) || (!showAdvanced &&
!p.label.includes('advanced')))
.filter((p: PropertyMeta) => !p.isObject || (p.isObject &&
!CamelUi.dslHasSteps(p.type)) || (dslName === 'CatchDefinition' && p.name ===
'onWhen'))
.filter((p: PropertyMeta) => !(dslName === 'RestDefinition' &&
['get', 'post', 'put', 'patch', 'delete', 'head'].includes(p.name)))
- .filter((p: PropertyMeta) => dslName && !(['RestDefinition',
'GetDefinition', 'PostDefinition', 'PutDefinition', 'PatchDefinition',
'DeleteDefinition', 'HeadDefinition'].includes(dslName) && ['param',
'responseMessage', 'security'].includes(p.name))) // TODO: configure this
properties
+ .filter((p: PropertyMeta) => dslName && !(['RestDefinition',
'GetDefinition', 'PostDefinition', 'PutDefinition', 'PatchDefinition',
'DeleteDefinition', 'HeadDefinition'].includes(dslName) && ['param',
'responseMessage'].includes(p.name))) // TODO: configure this properties
}
getPropertyFields = (showAdvanced: boolean) => {
diff --git a/karavan-designer/src/designer/route/property/DslPropertyField.tsx
b/karavan-designer/src/designer/route/property/DslPropertyField.tsx
index 5749147..9ef0872 100644
--- a/karavan-designer/src/designer/route/property/DslPropertyField.tsx
+++ b/karavan-designer/src/designer/route/property/DslPropertyField.tsx
@@ -23,7 +23,7 @@ import {
Select,
SelectVariant,
SelectDirection,
- SelectOption, ExpandableSection, TextArea, Chip, TextInputGroup,
TextInputGroupMain, TextInputGroupUtilities, ChipGroup, Button, Text, Tooltip
+ SelectOption, ExpandableSection, TextArea, Chip, TextInputGroup,
TextInputGroupMain, TextInputGroupUtilities, ChipGroup, Button, Text, Tooltip,
Card
} from '@patternfly/react-core';
import '../../karavan.css';
import "@patternfly/patternfly/patternfly.css";
@@ -334,11 +334,16 @@ export class DslPropertyField extends
React.Component<Props, State> {
return (
<div>
{value && Array.from(value).map((v: any, index: number) => (
- <div key={property + "-" + index}>
+ <Card key={property + "-" + index}
className="object-value">
<div className="object">
{value && <ObjectField property={property}
value={v} onPropertyUpdate={(f, v) => this.onMultiValueObjectUpdate(index, f,
v)} integration={this.props.integration} />}
</div>
- </div>
+ <Button variant="link" className="delete-button"
onClick={e => {
+ const v = Array.from(value);
+ v.splice(index, 1);
+ this.propertyChanged(property.name,v);
+ }}><DeleteIcon/></Button>
+ </Card>
))}
<Button variant="link" className="add-button" onClick={e =>
this.propertyChanged(property.name, [...value,
CamelDefinitionApi.createStep(property.type, {})])}><AddIcon/>{"Add " +
property.displayName}</Button>
</div>
diff --git a/karavan-designer/src/designer/utils/CamelUi.ts
b/karavan-designer/src/designer/utils/CamelUi.ts
index 2003e3d..fa1996a 100644
--- a/karavan-designer/src/designer/utils/CamelUi.ts
+++ b/karavan-designer/src/designer/utils/CamelUi.ts
@@ -19,7 +19,7 @@ import {KameletModel, Property} from
"karavan-core/lib/model/KameletModels";
import {DslMetaModel} from "./DslMetaModel";
import {ComponentApi} from "karavan-core/lib/api/ComponentApi";
import {ComponentProperty} from "karavan-core/lib/model/ComponentModels";
-import {CamelMetadataApi, PropertyMeta} from
"karavan-core/lib/model/CamelMetadata";
+import {CamelMetadataApi} from "karavan-core/lib/model/CamelMetadata";
import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
import {CamelDefinitionApiExt} from
"karavan-core/lib/api/CamelDefinitionApiExt";
import {KameletDefinition, NamedBeanDefinition, RouteDefinition,
SagaDefinition} from "karavan-core/lib/model/CamelDefinition";
@@ -33,6 +33,7 @@ const StepElements: string[] = [
"ConvertBodyDefinition",
"DynamicRouterDefinition",
"EnrichDefinition",
+ "ErrorHandlerBuilderRef",
"FilterDefinition",
"LogDefinition",
"LoopDefinition",
@@ -428,6 +429,8 @@ export class CamelUi {
return "data:image/svg+xml,%3Csvg
xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'
version='1.1' id='Capa_1' x='0px' y='0px' width='235.506px' height='235.506px'
viewBox='0 0 235.506 235.506' style='enable-background:new 0 0 235.506
235.506;' xml:space='preserve'%3E%3Cg%3E%3Cpath
d='M234.099,29.368c-3.025-4.861-10.303-7.123-22.915-7.123c-13.492,0-28.304,2.661-28.625,2.733
c-20.453,2.098-27.254,26.675-32.736,46.436c-1.924,6.969-3.755,13.549-5.8 [...]
case "DynamicRouterDefinition":
return "data:image/svg+xml,%3Csvg width='32' height='32'
xmlns='http://www.w3.org/2000/svg'
xmlns:svg='http://www.w3.org/2000/svg'%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill:none;%7D%3C/style%3E%3C/defs%3E%3Ctitle%3Einsert%3C/title%3E%3Cg
class='layer'%3E%3Ctitle%3ELayer 1%3C/title%3E%3Crect class='cls-1'
data-name='<Transparent Rectangle>' height='32'
id='_Transparent_Rectangle_' width='31.94228' x='0' y='0'/%3E%3Cg id='svg_5'
transform='matrix(1 0 0 1 0 0) rotate(180 16 [...]
+ case "ErrorHandlerBuilderRef":
+ return "data:image/svg+xml,%3Csvg
xmlns='http://www.w3.org/2000/svg' class='top-icon' width='36px' height='36px'
viewBox='0 0 36 36' version='1.1' preserveAspectRatio='xMidYMid
meet'%3E%3Ccircle class='clr-i-outline clr-i-outline-path-1' cx='18' cy='26.06'
r='1.33'%3E%3C/circle%3E%3Cpath class='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'%3E%3C/path%3E%3Cpath
class='clr-i-outline clr-i-outline-path-3' d='M18,34A1 [...]
default:
return camelIcon;
}