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/08 23:31:34 UTC
[camel-karavan] 02/02: Simplified picker #844
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
commit 6c642c7a4d4b6d418368395b3164e8cfaf2f33de
Author: Marat Gubaidullin <ma...@gmail.com>
AuthorDate: Tue Aug 8 19:31:25 2023 -0400
Simplified picker #844
---
karavan-designer/src/designer/karavan.css | 2 +-
.../src/designer/route/DslSelector.tsx | 112 +++++++++++++--------
karavan-designer/src/designer/utils/CamelUi.tsx | 11 +-
.../src/knowledgebase/KnowledgebasePage.tsx | 4 +-
karavan-space/src/designer/karavan.css | 2 +-
karavan-space/src/designer/route/DslSelector.tsx | 112 +++++++++++++--------
karavan-space/src/designer/utils/CamelUi.tsx | 11 +-
.../src/knowledgebase/KnowledgebasePage.tsx | 4 +-
.../src/main/webui/src/designer/karavan.css | 2 +-
.../main/webui/src/designer/route/DslSelector.tsx | 112 +++++++++++++--------
.../src/main/webui/src/designer/utils/CamelUi.tsx | 11 +-
.../webui/src/knowledgebase/KnowledgebasePage.tsx | 4 +-
12 files changed, 243 insertions(+), 144 deletions(-)
diff --git a/karavan-designer/src/designer/karavan.css b/karavan-designer/src/designer/karavan.css
index f8f9f634..5bfd3fef 100644
--- a/karavan-designer/src/designer/karavan.css
+++ b/karavan-designer/src/designer/karavan.css
@@ -940,7 +940,7 @@
padding: 5px;
display: flex;
flex-direction: row;
- justify-content: flex-end;
+ justify-content: space-between;
}
.dsl-modal .pf-c-card.pf-m-compact .footer-labels {
diff --git a/karavan-designer/src/designer/route/DslSelector.tsx b/karavan-designer/src/designer/route/DslSelector.tsx
index 8c6d741a..3baca8d8 100644
--- a/karavan-designer/src/designer/route/DslSelector.tsx
+++ b/karavan-designer/src/designer/route/DslSelector.tsx
@@ -17,14 +17,13 @@
import React from 'react';
import {
Badge,
- Card, CardBody, CardFooter, CardHeader, Flex, FlexItem, Form, FormGroup, Gallery, Modal, PageSection,
+ Card, CardBody, CardFooter, CardHeader, Flex, FlexItem, Form, FormGroup, Gallery, Label, Modal, PageSection,
Tab, Tabs, TabTitleText,
- Text, TextInput,
+ Text, TextInput, ToggleGroup, ToggleGroupItem,
} from '@patternfly/react-core';
import '../karavan.css';
import {CamelUi} from "../utils/CamelUi";
import {DslMetaModel} from "../utils/DslMetaModel";
-import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
interface Props {
onDslSelect: (dsl: DslMetaModel, parentId: string, position?: number | undefined) => void,
@@ -41,23 +40,19 @@ interface Props {
interface State {
tabIndex: string | number
filter: string;
+ selectedLabels: string []
}
export class DslSelector extends React.Component<Props, State> {
- getDefaultTabIndex = () => {
- const x = CamelUi.getSelectorModelTypes(this.props.parentDsl, this.props.showSteps);
- if (x.length > 0) return x[0][0]
- else return '';
- }
-
public state: State = {
- tabIndex: this.props.tabIndex ? this.props.tabIndex : this.getDefaultTabIndex(),
- filter: ''
+ tabIndex: this.props.tabIndex ? this.props.tabIndex : (this.props.parentDsl ? 'eip' : 'kamelet'),
+ filter: '',
+ selectedLabels: []
}
selectTab = (evt: React.MouseEvent<HTMLElement, MouseEvent>, eventKey: string | number) => {
- this.setState({tabIndex: eventKey})
+ this.setState({tabIndex: eventKey});
}
componentDidUpdate = (prevProps: Readonly<Props>, prevState: Readonly<State>, snapshot?: any) => {
@@ -68,7 +63,7 @@ export class DslSelector extends React.Component<Props, State> {
selectDsl = (evt: React.MouseEvent, dsl: any) => {
evt.stopPropagation();
- this.setState({filter:""});
+ this.setState({filter: ""});
this.props.onDslSelect.call(this, dsl, this.props.parentId, this.props.position);
}
@@ -85,12 +80,15 @@ export class DslSelector extends React.Component<Props, State> {
}
getCard(dsl: DslMetaModel, index: number) {
+ const labels = dsl.labels !== undefined ? dsl.labels.split(",").filter(label => label !== 'eip') : [];
return (
- <Card key={dsl.dsl + index} isHoverable isCompact className="dsl-card"
+ <Card key={dsl.dsl + index} isCompact className="dsl-card"
onClick={event => this.selectDsl(event, dsl)}>
<CardHeader className="header-labels">
- {dsl.supportType === 'Supported' && <Badge isRead className="support-type labels">{dsl.supportType}</Badge>}
<Badge isRead className="support-level labels">{dsl.supportLevel}</Badge>
+ {['kamelet', 'component'].includes(dsl.navigation.toLowerCase()) &&
+ <Badge isRead className="version labels">{dsl.version}</Badge>
+ }
</CardHeader>
<CardHeader>
{CamelUi.getIconForDsl(dsl)}
@@ -99,30 +97,53 @@ export class DslSelector extends React.Component<Props, State> {
<CardBody>
<Text>{dsl.description}</Text>
</CardBody>
- {dsl.navigation.toLowerCase() === "kamelet"
- && <CardFooter className="footer-labels">
- <Badge isRead className="labels">{dsl.labels}</Badge>
- <Badge isRead className="version labels">{dsl.version}</Badge>
- </CardFooter>}
- {dsl.navigation.toLowerCase() === "component"
- && <CardFooter className="footer-labels">
- <Badge isRead className="labels">{dsl.labels}</Badge>
- <Badge isRead className="version labels">{dsl.version}</Badge>
- </CardFooter>
- }
+ <CardFooter className="footer-labels">
+ <div style={{display: "flex", flexDirection: "row", justifyContent: "start"}}>
+ {labels.map(label => <Badge isRead className="labels">{label}</Badge>)}
+ </div>
+
+ </CardFooter>
</Card>
)
}
close = () => {
- this.setState({filter:""});
+ this.setState({filter: ""});
this.props.onClose?.call(this);
}
+ selectLabel = (eipLabel: string) => {
+ if (!this.state.selectedLabels.includes(eipLabel)) {
+ this.setState((state) => {
+ state.selectedLabels.push(eipLabel);
+ return state
+ })
+ } else {
+ this.setState((state) => {
+ const index = state.selectedLabels.findIndex((label) => label === eipLabel);
+ state.selectedLabels.splice(index, 1);
+ return state;
+ })
+ }
+ }
+
render() {
+ const isEip = this.state.tabIndex === 'eip';
const {parentDsl, isOpen} = this.props;
const title = parentDsl === undefined ? "Select source" : "Select step";
- const labelText: string = this.state.tabIndex ? this.state.tabIndex.toString() : "";
+ const navigation: string = this.state.tabIndex ? this.state.tabIndex.toString() : "";
+ const elements = CamelUi.getSelectorModelsForParentFiltered(parentDsl, navigation, this.props.showSteps);
+ const eipLabels = [...new Set(elements.map(e => e.labels).join(",").split(",").filter(e => e !== 'eip'))];
+ const filteredElement = elements
+ .filter((dsl: DslMetaModel) => CamelUi.checkFilter(dsl, this.state.filter))
+ .filter((dsl: DslMetaModel) => {
+ if (!isEip || this.state.selectedLabels.length === 0) {
+ return true;
+ } else {
+ return dsl.labels.split(",").some(r => this.state.selectedLabels.includes(r));
+ }
+ });
+
return (
<Modal
aria-label={title}
@@ -139,26 +160,33 @@ export class DslSelector extends React.Component<Props, State> {
<FlexItem>
<Tabs style={{overflow: 'hidden'}} activeKey={this.state.tabIndex}
onSelect={this.selectTab}>
- {CamelUi.getSelectorModelTypes(parentDsl, this.props.showSteps,this.state.filter).map((label: [string, number], index: number) => {
- const labelText = label[0];
- const count = label[1];
- const title = ['kamelet', 'component'].includes(labelText.toLowerCase()) ? labelText + "s (" + count + ")" : labelText;
- return (
- <Tab eventKey={labelText} key={"tab-" + labelText}
- title={<TabTitleText>{CamelUtil.capitalizeName(title)}</TabTitleText>}>
- </Tab>
- )
- })}
+ {parentDsl !== undefined &&
+ <Tab eventKey={"eip"} key={"tab-eip"}
+ title={<TabTitleText>Integration Patterns</TabTitleText>}>
+ </Tab>
+ }
+ <Tab eventKey={'kamelet'} key={"tab-kamelet"}
+ title={<TabTitleText>Kamelets</TabTitleText>}>
+ </Tab>
+ <Tab eventKey={'component'} key={'tab-component'}
+ title={<TabTitleText>Components</TabTitleText>}>
+ </Tab>
</Tabs>
</FlexItem>
</Flex>
}
actions={{}}>
<PageSection variant={this.props.dark ? "darker" : "light"}>
- <Gallery key={"gallery-" + labelText} hasGutter className="dsl-gallery">
- {isOpen && CamelUi.getSelectorModelsForParentFiltered(parentDsl, labelText, this.props.showSteps)
- .filter((dsl: DslMetaModel) => CamelUi.checkFilter(dsl, this.state.filter))
- .map((dsl: DslMetaModel, index: number) => this.getCard(dsl, index))}
+ {isEip && <ToggleGroup aria-label="Labels" isCompact>
+ {eipLabels.map(eipLabel => <ToggleGroupItem
+ text={eipLabel}
+ buttonId={eipLabel}
+ isSelected={this.state.selectedLabels.includes(eipLabel)}
+ onChange={selected => this.selectLabel(eipLabel)}
+ />)}
+ </ToggleGroup>}
+ <Gallery key={"gallery-" + navigation} hasGutter className="dsl-gallery">
+ {isOpen && filteredElement.map((dsl: DslMetaModel, index: number) => this.getCard(dsl, index))}
</Gallery>
</PageSection>
</Modal>
diff --git a/karavan-designer/src/designer/utils/CamelUi.tsx b/karavan-designer/src/designer/utils/CamelUi.tsx
index 9749fe68..a94ed0ac 100644
--- a/karavan-designer/src/designer/utils/CamelUi.tsx
+++ b/karavan-designer/src/designer/utils/CamelUi.tsx
@@ -157,6 +157,9 @@ export class RouteToCreate {
}
}
+const INTEGRATION_PATTERNS = 'Integration Patterns';
+const connectorNavs = ['routing', "transformation", "error", "configuration", "endpoint", "kamelet", "component"];
+
export class CamelUi {
static getSelectorModelTypes = (parentDsl: string | undefined, showSteps: boolean = true, filter: string | undefined = undefined): [string, number][] => {
@@ -164,7 +167,8 @@ export class CamelUi {
.reduce((accumulator, value) => accumulator.concat(value), [])
.filter((nav, i, arr) => arr.findIndex(l => l === nav) === i)
.filter((nav, i, arr) => !['dataformat'].includes(nav));
- const connectorNavs = ['routing', "transformation", "error", "configuration", "endpoint", "kamelet", "component"];
+ console.log(navs);
+ const connectorNavs = [INTEGRATION_PATTERNS, "kamelet", "component"];
const eipLabels = connectorNavs.filter(n => navs.includes(n));
return eipLabels.map(label => [label, this.getSelectorModelsForParentFiltered(parentDsl, label, true)
.filter((dsl: DslMetaModel) => filter === undefined ? true : CamelUi.checkFilter(dsl, filter)).length]);
@@ -173,7 +177,8 @@ export class CamelUi {
static checkFilter = (dsl: DslMetaModel, filter: string | undefined = undefined): boolean => {
if (filter !== undefined && filter !== "") {
return dsl.title.toLowerCase().includes(filter.toLowerCase())
- || dsl.description.toLowerCase().includes(filter.toLowerCase());
+ || dsl.description.toLowerCase().includes(filter.toLowerCase())
+ || dsl.labels.toLowerCase().includes(filter.toLowerCase());
} else {
return true;
}
@@ -229,7 +234,7 @@ export class CamelUi {
title: el?.title,
description: el?.description,
labels: el?.labels,
- navigation: el?.labels,
+ navigation: 'eip',
type: "DSL"
})
}
diff --git a/karavan-designer/src/knowledgebase/KnowledgebasePage.tsx b/karavan-designer/src/knowledgebase/KnowledgebasePage.tsx
index 7af978d2..d7856f55 100644
--- a/karavan-designer/src/knowledgebase/KnowledgebasePage.tsx
+++ b/karavan-designer/src/knowledgebase/KnowledgebasePage.tsx
@@ -28,7 +28,7 @@ interface Props {
export const KnowledgebasePage = (props: Props) => {
- const [tab, setTab] = useState<string | number>("kamelets");
+ const [tab, setTab] = useState<string | number>("eip");
const [filter, setFilter] = useState<string>("");
const [customOnly, setCustomOnly] = useState<boolean>(false);
@@ -68,7 +68,7 @@ export const KnowledgebasePage = (props: Props) => {
<Flex direction={{default: "column"}} spaceItems={{default: "spaceItemsNone"}}>
<FlexItem className="knowledge-tabs">
<Tabs activeKey={tab} onSelect={(event, tabIndex) => setTab(tabIndex)}>
- <Tab eventKey="eip" title="Enterprise Integration Patterns"/>
+ <Tab eventKey="eip" title="Integration Patterns"/>
<Tab eventKey="kamelets" title="Kamelets"/>
<Tab eventKey="components" title="Components"/>
</Tabs>
diff --git a/karavan-space/src/designer/karavan.css b/karavan-space/src/designer/karavan.css
index f8f9f634..5bfd3fef 100644
--- a/karavan-space/src/designer/karavan.css
+++ b/karavan-space/src/designer/karavan.css
@@ -940,7 +940,7 @@
padding: 5px;
display: flex;
flex-direction: row;
- justify-content: flex-end;
+ justify-content: space-between;
}
.dsl-modal .pf-c-card.pf-m-compact .footer-labels {
diff --git a/karavan-space/src/designer/route/DslSelector.tsx b/karavan-space/src/designer/route/DslSelector.tsx
index 8c6d741a..3baca8d8 100644
--- a/karavan-space/src/designer/route/DslSelector.tsx
+++ b/karavan-space/src/designer/route/DslSelector.tsx
@@ -17,14 +17,13 @@
import React from 'react';
import {
Badge,
- Card, CardBody, CardFooter, CardHeader, Flex, FlexItem, Form, FormGroup, Gallery, Modal, PageSection,
+ Card, CardBody, CardFooter, CardHeader, Flex, FlexItem, Form, FormGroup, Gallery, Label, Modal, PageSection,
Tab, Tabs, TabTitleText,
- Text, TextInput,
+ Text, TextInput, ToggleGroup, ToggleGroupItem,
} from '@patternfly/react-core';
import '../karavan.css';
import {CamelUi} from "../utils/CamelUi";
import {DslMetaModel} from "../utils/DslMetaModel";
-import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
interface Props {
onDslSelect: (dsl: DslMetaModel, parentId: string, position?: number | undefined) => void,
@@ -41,23 +40,19 @@ interface Props {
interface State {
tabIndex: string | number
filter: string;
+ selectedLabels: string []
}
export class DslSelector extends React.Component<Props, State> {
- getDefaultTabIndex = () => {
- const x = CamelUi.getSelectorModelTypes(this.props.parentDsl, this.props.showSteps);
- if (x.length > 0) return x[0][0]
- else return '';
- }
-
public state: State = {
- tabIndex: this.props.tabIndex ? this.props.tabIndex : this.getDefaultTabIndex(),
- filter: ''
+ tabIndex: this.props.tabIndex ? this.props.tabIndex : (this.props.parentDsl ? 'eip' : 'kamelet'),
+ filter: '',
+ selectedLabels: []
}
selectTab = (evt: React.MouseEvent<HTMLElement, MouseEvent>, eventKey: string | number) => {
- this.setState({tabIndex: eventKey})
+ this.setState({tabIndex: eventKey});
}
componentDidUpdate = (prevProps: Readonly<Props>, prevState: Readonly<State>, snapshot?: any) => {
@@ -68,7 +63,7 @@ export class DslSelector extends React.Component<Props, State> {
selectDsl = (evt: React.MouseEvent, dsl: any) => {
evt.stopPropagation();
- this.setState({filter:""});
+ this.setState({filter: ""});
this.props.onDslSelect.call(this, dsl, this.props.parentId, this.props.position);
}
@@ -85,12 +80,15 @@ export class DslSelector extends React.Component<Props, State> {
}
getCard(dsl: DslMetaModel, index: number) {
+ const labels = dsl.labels !== undefined ? dsl.labels.split(",").filter(label => label !== 'eip') : [];
return (
- <Card key={dsl.dsl + index} isHoverable isCompact className="dsl-card"
+ <Card key={dsl.dsl + index} isCompact className="dsl-card"
onClick={event => this.selectDsl(event, dsl)}>
<CardHeader className="header-labels">
- {dsl.supportType === 'Supported' && <Badge isRead className="support-type labels">{dsl.supportType}</Badge>}
<Badge isRead className="support-level labels">{dsl.supportLevel}</Badge>
+ {['kamelet', 'component'].includes(dsl.navigation.toLowerCase()) &&
+ <Badge isRead className="version labels">{dsl.version}</Badge>
+ }
</CardHeader>
<CardHeader>
{CamelUi.getIconForDsl(dsl)}
@@ -99,30 +97,53 @@ export class DslSelector extends React.Component<Props, State> {
<CardBody>
<Text>{dsl.description}</Text>
</CardBody>
- {dsl.navigation.toLowerCase() === "kamelet"
- && <CardFooter className="footer-labels">
- <Badge isRead className="labels">{dsl.labels}</Badge>
- <Badge isRead className="version labels">{dsl.version}</Badge>
- </CardFooter>}
- {dsl.navigation.toLowerCase() === "component"
- && <CardFooter className="footer-labels">
- <Badge isRead className="labels">{dsl.labels}</Badge>
- <Badge isRead className="version labels">{dsl.version}</Badge>
- </CardFooter>
- }
+ <CardFooter className="footer-labels">
+ <div style={{display: "flex", flexDirection: "row", justifyContent: "start"}}>
+ {labels.map(label => <Badge isRead className="labels">{label}</Badge>)}
+ </div>
+
+ </CardFooter>
</Card>
)
}
close = () => {
- this.setState({filter:""});
+ this.setState({filter: ""});
this.props.onClose?.call(this);
}
+ selectLabel = (eipLabel: string) => {
+ if (!this.state.selectedLabels.includes(eipLabel)) {
+ this.setState((state) => {
+ state.selectedLabels.push(eipLabel);
+ return state
+ })
+ } else {
+ this.setState((state) => {
+ const index = state.selectedLabels.findIndex((label) => label === eipLabel);
+ state.selectedLabels.splice(index, 1);
+ return state;
+ })
+ }
+ }
+
render() {
+ const isEip = this.state.tabIndex === 'eip';
const {parentDsl, isOpen} = this.props;
const title = parentDsl === undefined ? "Select source" : "Select step";
- const labelText: string = this.state.tabIndex ? this.state.tabIndex.toString() : "";
+ const navigation: string = this.state.tabIndex ? this.state.tabIndex.toString() : "";
+ const elements = CamelUi.getSelectorModelsForParentFiltered(parentDsl, navigation, this.props.showSteps);
+ const eipLabels = [...new Set(elements.map(e => e.labels).join(",").split(",").filter(e => e !== 'eip'))];
+ const filteredElement = elements
+ .filter((dsl: DslMetaModel) => CamelUi.checkFilter(dsl, this.state.filter))
+ .filter((dsl: DslMetaModel) => {
+ if (!isEip || this.state.selectedLabels.length === 0) {
+ return true;
+ } else {
+ return dsl.labels.split(",").some(r => this.state.selectedLabels.includes(r));
+ }
+ });
+
return (
<Modal
aria-label={title}
@@ -139,26 +160,33 @@ export class DslSelector extends React.Component<Props, State> {
<FlexItem>
<Tabs style={{overflow: 'hidden'}} activeKey={this.state.tabIndex}
onSelect={this.selectTab}>
- {CamelUi.getSelectorModelTypes(parentDsl, this.props.showSteps,this.state.filter).map((label: [string, number], index: number) => {
- const labelText = label[0];
- const count = label[1];
- const title = ['kamelet', 'component'].includes(labelText.toLowerCase()) ? labelText + "s (" + count + ")" : labelText;
- return (
- <Tab eventKey={labelText} key={"tab-" + labelText}
- title={<TabTitleText>{CamelUtil.capitalizeName(title)}</TabTitleText>}>
- </Tab>
- )
- })}
+ {parentDsl !== undefined &&
+ <Tab eventKey={"eip"} key={"tab-eip"}
+ title={<TabTitleText>Integration Patterns</TabTitleText>}>
+ </Tab>
+ }
+ <Tab eventKey={'kamelet'} key={"tab-kamelet"}
+ title={<TabTitleText>Kamelets</TabTitleText>}>
+ </Tab>
+ <Tab eventKey={'component'} key={'tab-component'}
+ title={<TabTitleText>Components</TabTitleText>}>
+ </Tab>
</Tabs>
</FlexItem>
</Flex>
}
actions={{}}>
<PageSection variant={this.props.dark ? "darker" : "light"}>
- <Gallery key={"gallery-" + labelText} hasGutter className="dsl-gallery">
- {isOpen && CamelUi.getSelectorModelsForParentFiltered(parentDsl, labelText, this.props.showSteps)
- .filter((dsl: DslMetaModel) => CamelUi.checkFilter(dsl, this.state.filter))
- .map((dsl: DslMetaModel, index: number) => this.getCard(dsl, index))}
+ {isEip && <ToggleGroup aria-label="Labels" isCompact>
+ {eipLabels.map(eipLabel => <ToggleGroupItem
+ text={eipLabel}
+ buttonId={eipLabel}
+ isSelected={this.state.selectedLabels.includes(eipLabel)}
+ onChange={selected => this.selectLabel(eipLabel)}
+ />)}
+ </ToggleGroup>}
+ <Gallery key={"gallery-" + navigation} hasGutter className="dsl-gallery">
+ {isOpen && filteredElement.map((dsl: DslMetaModel, index: number) => this.getCard(dsl, index))}
</Gallery>
</PageSection>
</Modal>
diff --git a/karavan-space/src/designer/utils/CamelUi.tsx b/karavan-space/src/designer/utils/CamelUi.tsx
index 9749fe68..a94ed0ac 100644
--- a/karavan-space/src/designer/utils/CamelUi.tsx
+++ b/karavan-space/src/designer/utils/CamelUi.tsx
@@ -157,6 +157,9 @@ export class RouteToCreate {
}
}
+const INTEGRATION_PATTERNS = 'Integration Patterns';
+const connectorNavs = ['routing', "transformation", "error", "configuration", "endpoint", "kamelet", "component"];
+
export class CamelUi {
static getSelectorModelTypes = (parentDsl: string | undefined, showSteps: boolean = true, filter: string | undefined = undefined): [string, number][] => {
@@ -164,7 +167,8 @@ export class CamelUi {
.reduce((accumulator, value) => accumulator.concat(value), [])
.filter((nav, i, arr) => arr.findIndex(l => l === nav) === i)
.filter((nav, i, arr) => !['dataformat'].includes(nav));
- const connectorNavs = ['routing', "transformation", "error", "configuration", "endpoint", "kamelet", "component"];
+ console.log(navs);
+ const connectorNavs = [INTEGRATION_PATTERNS, "kamelet", "component"];
const eipLabels = connectorNavs.filter(n => navs.includes(n));
return eipLabels.map(label => [label, this.getSelectorModelsForParentFiltered(parentDsl, label, true)
.filter((dsl: DslMetaModel) => filter === undefined ? true : CamelUi.checkFilter(dsl, filter)).length]);
@@ -173,7 +177,8 @@ export class CamelUi {
static checkFilter = (dsl: DslMetaModel, filter: string | undefined = undefined): boolean => {
if (filter !== undefined && filter !== "") {
return dsl.title.toLowerCase().includes(filter.toLowerCase())
- || dsl.description.toLowerCase().includes(filter.toLowerCase());
+ || dsl.description.toLowerCase().includes(filter.toLowerCase())
+ || dsl.labels.toLowerCase().includes(filter.toLowerCase());
} else {
return true;
}
@@ -229,7 +234,7 @@ export class CamelUi {
title: el?.title,
description: el?.description,
labels: el?.labels,
- navigation: el?.labels,
+ navigation: 'eip',
type: "DSL"
})
}
diff --git a/karavan-space/src/knowledgebase/KnowledgebasePage.tsx b/karavan-space/src/knowledgebase/KnowledgebasePage.tsx
index 4d3ccd8e..d7856f55 100644
--- a/karavan-space/src/knowledgebase/KnowledgebasePage.tsx
+++ b/karavan-space/src/knowledgebase/KnowledgebasePage.tsx
@@ -28,7 +28,7 @@ interface Props {
export const KnowledgebasePage = (props: Props) => {
- const [tab, setTab] = useState<string | number>("kamelets");
+ const [tab, setTab] = useState<string | number>("eip");
const [filter, setFilter] = useState<string>("");
const [customOnly, setCustomOnly] = useState<boolean>(false);
@@ -68,8 +68,8 @@ export const KnowledgebasePage = (props: Props) => {
<Flex direction={{default: "column"}} spaceItems={{default: "spaceItemsNone"}}>
<FlexItem className="knowledge-tabs">
<Tabs activeKey={tab} onSelect={(event, tabIndex) => setTab(tabIndex)}>
+ <Tab eventKey="eip" title="Integration Patterns"/>
<Tab eventKey="kamelets" title="Kamelets"/>
- <Tab eventKey="eip" title="Enterprise Integration Patterns"/>
<Tab eventKey="components" title="Components"/>
</Tabs>
</FlexItem>
diff --git a/karavan-web/karavan-app/src/main/webui/src/designer/karavan.css b/karavan-web/karavan-app/src/main/webui/src/designer/karavan.css
index f8f9f634..5bfd3fef 100644
--- a/karavan-web/karavan-app/src/main/webui/src/designer/karavan.css
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/karavan.css
@@ -940,7 +940,7 @@
padding: 5px;
display: flex;
flex-direction: row;
- justify-content: flex-end;
+ justify-content: space-between;
}
.dsl-modal .pf-c-card.pf-m-compact .footer-labels {
diff --git a/karavan-web/karavan-app/src/main/webui/src/designer/route/DslSelector.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/route/DslSelector.tsx
index 8c6d741a..3baca8d8 100644
--- a/karavan-web/karavan-app/src/main/webui/src/designer/route/DslSelector.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/route/DslSelector.tsx
@@ -17,14 +17,13 @@
import React from 'react';
import {
Badge,
- Card, CardBody, CardFooter, CardHeader, Flex, FlexItem, Form, FormGroup, Gallery, Modal, PageSection,
+ Card, CardBody, CardFooter, CardHeader, Flex, FlexItem, Form, FormGroup, Gallery, Label, Modal, PageSection,
Tab, Tabs, TabTitleText,
- Text, TextInput,
+ Text, TextInput, ToggleGroup, ToggleGroupItem,
} from '@patternfly/react-core';
import '../karavan.css';
import {CamelUi} from "../utils/CamelUi";
import {DslMetaModel} from "../utils/DslMetaModel";
-import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
interface Props {
onDslSelect: (dsl: DslMetaModel, parentId: string, position?: number | undefined) => void,
@@ -41,23 +40,19 @@ interface Props {
interface State {
tabIndex: string | number
filter: string;
+ selectedLabels: string []
}
export class DslSelector extends React.Component<Props, State> {
- getDefaultTabIndex = () => {
- const x = CamelUi.getSelectorModelTypes(this.props.parentDsl, this.props.showSteps);
- if (x.length > 0) return x[0][0]
- else return '';
- }
-
public state: State = {
- tabIndex: this.props.tabIndex ? this.props.tabIndex : this.getDefaultTabIndex(),
- filter: ''
+ tabIndex: this.props.tabIndex ? this.props.tabIndex : (this.props.parentDsl ? 'eip' : 'kamelet'),
+ filter: '',
+ selectedLabels: []
}
selectTab = (evt: React.MouseEvent<HTMLElement, MouseEvent>, eventKey: string | number) => {
- this.setState({tabIndex: eventKey})
+ this.setState({tabIndex: eventKey});
}
componentDidUpdate = (prevProps: Readonly<Props>, prevState: Readonly<State>, snapshot?: any) => {
@@ -68,7 +63,7 @@ export class DslSelector extends React.Component<Props, State> {
selectDsl = (evt: React.MouseEvent, dsl: any) => {
evt.stopPropagation();
- this.setState({filter:""});
+ this.setState({filter: ""});
this.props.onDslSelect.call(this, dsl, this.props.parentId, this.props.position);
}
@@ -85,12 +80,15 @@ export class DslSelector extends React.Component<Props, State> {
}
getCard(dsl: DslMetaModel, index: number) {
+ const labels = dsl.labels !== undefined ? dsl.labels.split(",").filter(label => label !== 'eip') : [];
return (
- <Card key={dsl.dsl + index} isHoverable isCompact className="dsl-card"
+ <Card key={dsl.dsl + index} isCompact className="dsl-card"
onClick={event => this.selectDsl(event, dsl)}>
<CardHeader className="header-labels">
- {dsl.supportType === 'Supported' && <Badge isRead className="support-type labels">{dsl.supportType}</Badge>}
<Badge isRead className="support-level labels">{dsl.supportLevel}</Badge>
+ {['kamelet', 'component'].includes(dsl.navigation.toLowerCase()) &&
+ <Badge isRead className="version labels">{dsl.version}</Badge>
+ }
</CardHeader>
<CardHeader>
{CamelUi.getIconForDsl(dsl)}
@@ -99,30 +97,53 @@ export class DslSelector extends React.Component<Props, State> {
<CardBody>
<Text>{dsl.description}</Text>
</CardBody>
- {dsl.navigation.toLowerCase() === "kamelet"
- && <CardFooter className="footer-labels">
- <Badge isRead className="labels">{dsl.labels}</Badge>
- <Badge isRead className="version labels">{dsl.version}</Badge>
- </CardFooter>}
- {dsl.navigation.toLowerCase() === "component"
- && <CardFooter className="footer-labels">
- <Badge isRead className="labels">{dsl.labels}</Badge>
- <Badge isRead className="version labels">{dsl.version}</Badge>
- </CardFooter>
- }
+ <CardFooter className="footer-labels">
+ <div style={{display: "flex", flexDirection: "row", justifyContent: "start"}}>
+ {labels.map(label => <Badge isRead className="labels">{label}</Badge>)}
+ </div>
+
+ </CardFooter>
</Card>
)
}
close = () => {
- this.setState({filter:""});
+ this.setState({filter: ""});
this.props.onClose?.call(this);
}
+ selectLabel = (eipLabel: string) => {
+ if (!this.state.selectedLabels.includes(eipLabel)) {
+ this.setState((state) => {
+ state.selectedLabels.push(eipLabel);
+ return state
+ })
+ } else {
+ this.setState((state) => {
+ const index = state.selectedLabels.findIndex((label) => label === eipLabel);
+ state.selectedLabels.splice(index, 1);
+ return state;
+ })
+ }
+ }
+
render() {
+ const isEip = this.state.tabIndex === 'eip';
const {parentDsl, isOpen} = this.props;
const title = parentDsl === undefined ? "Select source" : "Select step";
- const labelText: string = this.state.tabIndex ? this.state.tabIndex.toString() : "";
+ const navigation: string = this.state.tabIndex ? this.state.tabIndex.toString() : "";
+ const elements = CamelUi.getSelectorModelsForParentFiltered(parentDsl, navigation, this.props.showSteps);
+ const eipLabels = [...new Set(elements.map(e => e.labels).join(",").split(",").filter(e => e !== 'eip'))];
+ const filteredElement = elements
+ .filter((dsl: DslMetaModel) => CamelUi.checkFilter(dsl, this.state.filter))
+ .filter((dsl: DslMetaModel) => {
+ if (!isEip || this.state.selectedLabels.length === 0) {
+ return true;
+ } else {
+ return dsl.labels.split(",").some(r => this.state.selectedLabels.includes(r));
+ }
+ });
+
return (
<Modal
aria-label={title}
@@ -139,26 +160,33 @@ export class DslSelector extends React.Component<Props, State> {
<FlexItem>
<Tabs style={{overflow: 'hidden'}} activeKey={this.state.tabIndex}
onSelect={this.selectTab}>
- {CamelUi.getSelectorModelTypes(parentDsl, this.props.showSteps,this.state.filter).map((label: [string, number], index: number) => {
- const labelText = label[0];
- const count = label[1];
- const title = ['kamelet', 'component'].includes(labelText.toLowerCase()) ? labelText + "s (" + count + ")" : labelText;
- return (
- <Tab eventKey={labelText} key={"tab-" + labelText}
- title={<TabTitleText>{CamelUtil.capitalizeName(title)}</TabTitleText>}>
- </Tab>
- )
- })}
+ {parentDsl !== undefined &&
+ <Tab eventKey={"eip"} key={"tab-eip"}
+ title={<TabTitleText>Integration Patterns</TabTitleText>}>
+ </Tab>
+ }
+ <Tab eventKey={'kamelet'} key={"tab-kamelet"}
+ title={<TabTitleText>Kamelets</TabTitleText>}>
+ </Tab>
+ <Tab eventKey={'component'} key={'tab-component'}
+ title={<TabTitleText>Components</TabTitleText>}>
+ </Tab>
</Tabs>
</FlexItem>
</Flex>
}
actions={{}}>
<PageSection variant={this.props.dark ? "darker" : "light"}>
- <Gallery key={"gallery-" + labelText} hasGutter className="dsl-gallery">
- {isOpen && CamelUi.getSelectorModelsForParentFiltered(parentDsl, labelText, this.props.showSteps)
- .filter((dsl: DslMetaModel) => CamelUi.checkFilter(dsl, this.state.filter))
- .map((dsl: DslMetaModel, index: number) => this.getCard(dsl, index))}
+ {isEip && <ToggleGroup aria-label="Labels" isCompact>
+ {eipLabels.map(eipLabel => <ToggleGroupItem
+ text={eipLabel}
+ buttonId={eipLabel}
+ isSelected={this.state.selectedLabels.includes(eipLabel)}
+ onChange={selected => this.selectLabel(eipLabel)}
+ />)}
+ </ToggleGroup>}
+ <Gallery key={"gallery-" + navigation} hasGutter className="dsl-gallery">
+ {isOpen && filteredElement.map((dsl: DslMetaModel, index: number) => this.getCard(dsl, index))}
</Gallery>
</PageSection>
</Modal>
diff --git a/karavan-web/karavan-app/src/main/webui/src/designer/utils/CamelUi.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/utils/CamelUi.tsx
index 9749fe68..a94ed0ac 100644
--- a/karavan-web/karavan-app/src/main/webui/src/designer/utils/CamelUi.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/utils/CamelUi.tsx
@@ -157,6 +157,9 @@ export class RouteToCreate {
}
}
+const INTEGRATION_PATTERNS = 'Integration Patterns';
+const connectorNavs = ['routing', "transformation", "error", "configuration", "endpoint", "kamelet", "component"];
+
export class CamelUi {
static getSelectorModelTypes = (parentDsl: string | undefined, showSteps: boolean = true, filter: string | undefined = undefined): [string, number][] => {
@@ -164,7 +167,8 @@ export class CamelUi {
.reduce((accumulator, value) => accumulator.concat(value), [])
.filter((nav, i, arr) => arr.findIndex(l => l === nav) === i)
.filter((nav, i, arr) => !['dataformat'].includes(nav));
- const connectorNavs = ['routing', "transformation", "error", "configuration", "endpoint", "kamelet", "component"];
+ console.log(navs);
+ const connectorNavs = [INTEGRATION_PATTERNS, "kamelet", "component"];
const eipLabels = connectorNavs.filter(n => navs.includes(n));
return eipLabels.map(label => [label, this.getSelectorModelsForParentFiltered(parentDsl, label, true)
.filter((dsl: DslMetaModel) => filter === undefined ? true : CamelUi.checkFilter(dsl, filter)).length]);
@@ -173,7 +177,8 @@ export class CamelUi {
static checkFilter = (dsl: DslMetaModel, filter: string | undefined = undefined): boolean => {
if (filter !== undefined && filter !== "") {
return dsl.title.toLowerCase().includes(filter.toLowerCase())
- || dsl.description.toLowerCase().includes(filter.toLowerCase());
+ || dsl.description.toLowerCase().includes(filter.toLowerCase())
+ || dsl.labels.toLowerCase().includes(filter.toLowerCase());
} else {
return true;
}
@@ -229,7 +234,7 @@ export class CamelUi {
title: el?.title,
description: el?.description,
labels: el?.labels,
- navigation: el?.labels,
+ navigation: 'eip',
type: "DSL"
})
}
diff --git a/karavan-web/karavan-app/src/main/webui/src/knowledgebase/KnowledgebasePage.tsx b/karavan-web/karavan-app/src/main/webui/src/knowledgebase/KnowledgebasePage.tsx
index 4d3ccd8e..d7856f55 100644
--- a/karavan-web/karavan-app/src/main/webui/src/knowledgebase/KnowledgebasePage.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/knowledgebase/KnowledgebasePage.tsx
@@ -28,7 +28,7 @@ interface Props {
export const KnowledgebasePage = (props: Props) => {
- const [tab, setTab] = useState<string | number>("kamelets");
+ const [tab, setTab] = useState<string | number>("eip");
const [filter, setFilter] = useState<string>("");
const [customOnly, setCustomOnly] = useState<boolean>(false);
@@ -68,8 +68,8 @@ export const KnowledgebasePage = (props: Props) => {
<Flex direction={{default: "column"}} spaceItems={{default: "spaceItemsNone"}}>
<FlexItem className="knowledge-tabs">
<Tabs activeKey={tab} onSelect={(event, tabIndex) => setTab(tabIndex)}>
+ <Tab eventKey="eip" title="Integration Patterns"/>
<Tab eventKey="kamelets" title="Kamelets"/>
- <Tab eventKey="eip" title="Enterprise Integration Patterns"/>
<Tab eventKey="components" title="Components"/>
</Tabs>
</FlexItem>