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 70ce664a Fix #1421
70ce664a is described below

commit 70ce664adcd89c1c22040001096b091ec5898ade
Author: Marat Gubaidullin <[email protected]>
AuthorDate: Tue Sep 17 10:57:24 2024 -0400

    Fix #1421
---
 .../src/main/webui/src/designer/DesignerStore.ts   |  21 ----
 .../src/designer/property/PropertiesHeader.tsx     |   2 +-
 .../webui/src/knowledgebase/KnowledgebasePage.tsx  |  55 +++++++--
 .../src/knowledgebase/components/ComponentCard.tsx |  11 +-
 .../src/knowledgebase/components/ComponentsTab.tsx |  15 +--
 .../main/webui/src/knowledgebase/eip/EipCard.tsx   |  10 +-
 .../main/webui/src/knowledgebase/eip/EipTab.tsx    |  45 ++------
 .../src/knowledgebase/kamelets/KameletCard.tsx     |   6 +-
 .../src/knowledgebase/kamelets/KameletsTab.tsx     |  14 +--
 .../main/webui/src/knowledgebase/knowledgebase.css | 124 ++++++++++++++++++++-
 karavan-designer/src/designer/DesignerStore.ts     |  21 ----
 .../src/designer/property/PropertiesHeader.tsx     |   2 +-
 .../src/knowledgebase/KnowledgebasePage.tsx        |  55 +++++++--
 .../src/knowledgebase/components/ComponentCard.tsx |  11 +-
 .../src/knowledgebase/components/ComponentsTab.tsx |  15 +--
 karavan-designer/src/knowledgebase/eip/EipCard.tsx |  10 +-
 karavan-designer/src/knowledgebase/eip/EipTab.tsx  |  45 ++------
 .../src/knowledgebase/kamelets/KameletCard.tsx     |   6 +-
 .../src/knowledgebase/kamelets/KameletsTab.tsx     |  14 +--
 .../src/knowledgebase/knowledgebase.css            | 124 ++++++++++++++++++++-
 karavan-space/src/designer/DesignerStore.ts        |  21 ----
 .../src/designer/property/PropertiesHeader.tsx     |   2 +-
 .../src/knowledgebase/KnowledgebasePage.tsx        |  55 +++++++--
 .../src/knowledgebase/components/ComponentCard.tsx |  11 +-
 .../src/knowledgebase/components/ComponentsTab.tsx |  15 +--
 karavan-space/src/knowledgebase/eip/EipCard.tsx    |  10 +-
 karavan-space/src/knowledgebase/eip/EipTab.tsx     |  45 ++------
 .../src/knowledgebase/kamelets/KameletCard.tsx     |   6 +-
 .../src/knowledgebase/kamelets/KameletsTab.tsx     |  14 +--
 karavan-space/src/knowledgebase/knowledgebase.css  | 124 ++++++++++++++++++++-
 30 files changed, 609 insertions(+), 300 deletions(-)

diff --git a/karavan-app/src/main/webui/src/designer/DesignerStore.ts 
b/karavan-app/src/main/webui/src/designer/DesignerStore.ts
index 9c855c5f..e207c546 100644
--- a/karavan-app/src/main/webui/src/designer/DesignerStore.ts
+++ b/karavan-app/src/main/webui/src/designer/DesignerStore.ts
@@ -105,10 +105,6 @@ interface SelectorStateState {
     setSelectorTabIndex: (selectorTabIndex?: string | number) => void;
     selectedPosition?: number;
     setSelectedPosition: (selectedPosition?: number) => void;
-    selectedLabels: string [];
-    addSelectedLabel: (label: string) => void;
-    deleteSelectedLabel: (label: string) => void;
-    clearSelectedLabels: () => void;
     selectedToggles: string [];
     addSelectedToggle: (label: string) => void;
     deleteSelectedToggle: (label: string) => void;
@@ -121,24 +117,7 @@ export const useSelectorStore = 
createWithEqualityFn<SelectorStateState>((set) =
     deleteMessage: '',
     parentId: '',
     showSteps: true,
-    selectedLabels: [],
     selectedToggles: ['eip', 'components', 'kamelets'],
-    addSelectedLabel: (label: string) => {
-        set(state => ({
-            selectedLabels: [...state.selectedLabels, label]
-        }))
-    },
-    deleteSelectedLabel: (label: string) => {
-        set(state => ({
-            selectedLabels: [...state.selectedLabels.filter(x => x !== label)]
-        }))
-    },
-    clearSelectedLabels: () => {
-        set((state: SelectorStateState) => {
-            state.selectedLabels.length = 0;
-            return {selectedLabels : [...state.selectedLabels]};
-        })
-    },
     addSelectedToggle: (toggle: string) => {
         set(state => ({
             selectedToggles: [...state.selectedToggles, toggle]
diff --git 
a/karavan-app/src/main/webui/src/designer/property/PropertiesHeader.tsx 
b/karavan-app/src/main/webui/src/designer/property/PropertiesHeader.tsx
index 30b0034b..b8aca6b4 100644
--- a/karavan-app/src/main/webui/src/designer/property/PropertiesHeader.tsx
+++ b/karavan-app/src/main/webui/src/designer/property/PropertiesHeader.tsx
@@ -94,7 +94,7 @@ export function PropertiesHeader(props: Props) {
                             openSelectorToReplaceFrom((selectedStep as any).id)
                             setMenuOpen(false);
                         }}>
-                            Change From Element
+                            Change From...
                         </DropdownItem>}
                     {hasSteps &&
                         <DropdownItem key="saveStepsRoute" onClick={(ev) => {
diff --git a/karavan-app/src/main/webui/src/knowledgebase/KnowledgebasePage.tsx 
b/karavan-app/src/main/webui/src/knowledgebase/KnowledgebasePage.tsx
index a7c1d514..cb2e7158 100644
--- a/karavan-app/src/main/webui/src/knowledgebase/KnowledgebasePage.tsx
+++ b/karavan-app/src/main/webui/src/knowledgebase/KnowledgebasePage.tsx
@@ -16,13 +16,30 @@
  */
 import React, {useState} from 'react';
 import '../designer/karavan.css';
-import {Flex, FlexItem, PageSection, Switch, Tab, Tabs, Text, TextContent, 
TextInput, Toolbar, ToolbarContent} from "@patternfly/react-core";
+import {
+    Badge,
+    Flex,
+    FlexItem,
+    PageSection,
+    Switch,
+    Tab,
+    Tabs,
+    Text,
+    TextContent,
+    TextInput,
+    Toolbar,
+    ToolbarContent
+} from "@patternfly/react-core";
 import {MainToolbar} from "../designer/MainToolbar";
 import {KameletsTab} from "./kamelets/KameletsTab";
 import {EipTab} from "./eip/EipTab";
 import {ComponentsTab} from "./components/ComponentsTab";
 import {useKnowledgebaseStore} from "./KnowledgebaseStore";
 import {shallow} from "zustand/shallow";
+import {KameletApi} from "karavan-core/lib/api/KameletApi";
+import {KameletModel} from "karavan-core/lib/model/KameletModels";
+import {ComponentApi} from "karavan-core/lib/api/ComponentApi";
+import {CamelModelMetadata, ElementMeta} from 
"karavan-core/lib/model/CamelMetadata";
 
 interface Props {
     dark: boolean,
@@ -33,7 +50,7 @@ interface Props {
 export const KnowledgebasePage = (props: Props) => {
 
     const [setShowBlockCheckbox] = useKnowledgebaseStore((s) => 
[s.setShowBlockCheckbox], shallow)
-    const [tab, setTab] = useState<string | number>("eip");
+    const [tab, setTab] = useState<string | number>("components");
     const [filter, setFilter] = useState<string>("");
     const [customOnly, setCustomOnly] = useState<boolean>(false);
 
@@ -71,8 +88,21 @@ export const KnowledgebasePage = (props: Props) => {
         </Toolbar>
     }
 
+    let kameletList: KameletModel[] = KameletApi.getKamelets().filter(kamelet 
=>
+            
kamelet.spec.definition.title.toLowerCase().includes(filter.toLowerCase()));
+    if (customOnly) kameletList = kameletList.filter(k => 
KameletApi.getCustomKameletNames().includes(k.metadata.name));
+
+    const components = ComponentApi.getComponents().filter(c => {
+        return c.component.name.toLowerCase().includes(filter.toLowerCase())
+            || c.component.title.toLowerCase().includes(filter.toLowerCase())
+            || 
c.component.description.toLowerCase().includes(filter.toLowerCase())
+    }).sort((a, b) => (a.component.title?.toLowerCase() > 
b.component.title?.toLowerCase() ? 1 : -1)) ;
+
+    const elements= CamelModelMetadata
+        .filter(c => 
c.name.toLowerCase().includes(filter.toLowerCase())).sort((a: ElementMeta, b: 
ElementMeta) => a.name > b.name ? 1 : -1);
+
     return (
-        <PageSection className="kamelet-section" padding={{default: 
'noPadding'}}>
+        <PageSection className="knowledgebase-section" padding={{default: 
'noPadding'}}>
             <PageSection className="tools-section" padding={{default: 
'noPadding'}}>
                 <MainToolbar title={title()} tools={getTools()}/>
             </PageSection>
@@ -80,17 +110,24 @@ export const KnowledgebasePage = (props: Props) => {
                 <Flex direction={{default: "column"}} spaceItems={{default: 
"spaceItemsNone"}}>
                     <FlexItem>
                         <Tabs activeKey={tab} onSelect={(event, tabIndex) => 
setTab(tabIndex)}>
-                            <Tab eventKey="eip" title="Integration Patterns"/>
-                            <Tab eventKey="kamelets" title="Kamelets"/>
-                            <Tab eventKey="components" title="Components"/>
+                            <Tab eventKey="components" title={<div 
style={{display: 'flex', gap:'6px'}}>Components<Badge 
className='label-component'>{components.length}</Badge></div>}/>
+                            <Tab eventKey="eip" title={<div style={{display: 
'flex', gap:'6px'}}>Integration Patterns<Badge 
className='label-eip'>{elements.length}</Badge></div>}/>
+                            <Tab eventKey="kamelets" title={<div 
style={{display: 'flex', gap:'6px'}}>Kamelets<Badge 
className='label-kamelet'>{kameletList.length}</Badge></div>}/>
                         </Tabs>
                     </FlexItem>
                 </Flex>
             </PageSection>
             <>
-                {tab === 'kamelets' && <KameletsTab dark={props.dark} 
filter={filter} customOnly={customOnly} onChange={(name: string, checked: 
boolean) => props.changeBlockList('kamelet', name, checked)}  />}
-                {tab === 'eip' && <EipTab dark={props.dark} filter={filter}/>}
-                {tab === 'components' && <ComponentsTab dark={props.dark} 
filter={filter} onChange={(name: string, checked: boolean) => 
props.changeBlockList('component', name, checked)}  />}
+                {tab === 'kamelets' && <KameletsTab dark={props.dark}
+                                                    kameletList={kameletList}
+                                                    onChange={(name: string, 
checked: boolean) => props.changeBlockList('kamelet', name, checked)} />
+                }
+                {tab === 'eip' && <EipTab dark={props.dark} 
elements={elements}/>
+                }
+                {tab === 'components' && <ComponentsTab dark={props.dark}
+                                                        components={components}
+                                                        onChange={(name: 
string, checked: boolean) => props.changeBlockList('component', name, checked)} 
/>
+                }
             </>
         </PageSection>
     )
diff --git 
a/karavan-app/src/main/webui/src/knowledgebase/components/ComponentCard.tsx 
b/karavan-app/src/main/webui/src/knowledgebase/components/ComponentCard.tsx
index c9f39d04..80d298c5 100644
--- a/karavan-app/src/main/webui/src/knowledgebase/components/ComponentCard.tsx
+++ b/karavan-app/src/main/webui/src/knowledgebase/components/ComponentCard.tsx
@@ -16,7 +16,7 @@
  */
 import React, {useEffect, useState} from 'react';
 import {
-    CardHeader, Card, CardTitle, CardBody, CardFooter, Badge, Checkbox, Flex
+    CardHeader, Card, CardTitle, CardBody, CardFooter, Badge, Checkbox, Flex, 
Text
 } from '@patternfly/react-core';
 import '../../designer/karavan.css';
 import {CamelUi} from "../../designer/utils/CamelUi";
@@ -56,14 +56,15 @@ export function ComponentCard(props: Props) {
 
     const isBlockedComponent = blockedComponents ? 
blockedComponents.findIndex(r => r === component.component.name) > -1 : false;
     const isRemote = component.component.remote;
+    const classNameBadge = 'label-component' + 
(component.component.supportLevel !== 'Stable' ? '-preview' : '')
     return (
-        <Card isCompact key={component.component.name} className="kamelet-card"
+        <Card isCompact key={component.component.name} 
className="knowledgebase-card"
               onClick={event => click(event)}
         >
             <CardHeader className="header-labels">
                 <Flex style={{width: '100%'}} gap={{default: 'gapSm'}} 
justifyContent={{default: 'justifyContentSpaceBetween'}}>
+                    <Badge className={classNameBadge}>Component</Badge>
                     <Badge isRead className="support-level 
labels">{component.component.supportLevel}</Badge>
-                    <Badge isRead className="version 
labels">{component.component.version}</Badge>
                 </Flex>
                 {showBlockCheckbox &&
                     <Checkbox id={component.component.name}
@@ -77,7 +78,9 @@ export function ComponentCard(props: Props) {
                 {CamelUi.getIconForComponent(component.component.title, 
component.component.label)}
                 <CardTitle>{component.component.title}</CardTitle>
             </CardHeader>
-            <CardBody>{component.component.description}</CardBody>
+            <CardBody>
+                <Text 
className="pf-v5-u-color-200">{component.component.description}</Text>
+            </CardBody>
             <CardFooter className="footer-labels">
                 <Badge isRead 
className="labels">{component.component.label}</Badge>
                 <Badge isRead className="labels">{isRemote ? 'remote' : 
'internal'}</Badge>
diff --git 
a/karavan-app/src/main/webui/src/knowledgebase/components/ComponentsTab.tsx 
b/karavan-app/src/main/webui/src/knowledgebase/components/ComponentsTab.tsx
index 9e9fb470..c4fdb592 100644
--- a/karavan-app/src/main/webui/src/knowledgebase/components/ComponentsTab.tsx
+++ b/karavan-app/src/main/webui/src/knowledgebase/components/ComponentsTab.tsx
@@ -22,28 +22,21 @@ import {
 import '../../designer/karavan.css';
 import {ComponentCard} from "./ComponentCard";
 import {ComponentModal} from "./ComponentModal";
-import {ComponentApi} from "karavan-core/lib/api/ComponentApi";
 import {shallow} from "zustand/shallow";
 import {useKnowledgebaseStore} from "../KnowledgebaseStore";
+import { Component } from 'karavan-core/lib/model/ComponentModels';
 
 interface Props {
     dark: boolean,
-    filter: string,
+    components: Component[],
     onChange: (name: string, checked: boolean) => void,
 }
 
 export function ComponentsTab(props: Props) {
 
-    const [isModalOpen] = useKnowledgebaseStore((s) =>
-        [s.isModalOpen], shallow)
+    const [isModalOpen] = useKnowledgebaseStore((s) => [s.isModalOpen], 
shallow)
 
-
-    const {filter} = props;
-    const components = ComponentApi.getComponents().filter(c => {
-        return c.component.name.toLowerCase().includes(filter.toLowerCase())
-            || c.component.title.toLowerCase().includes(filter.toLowerCase())
-            || 
c.component.description.toLowerCase().includes(filter.toLowerCase())
-    }).sort((a, b) => (a.component.title?.toLowerCase() > 
b.component.title?.toLowerCase() ? 1 : -1)) ;
+    const {components} = props;
     return (
         <PageSection variant={props.dark ? PageSectionVariants.darker : 
PageSectionVariants.light} padding={{ default: 'noPadding' }} 
className="kamelet-section">
             {isModalOpen && <ComponentModal/>}
diff --git a/karavan-app/src/main/webui/src/knowledgebase/eip/EipCard.tsx 
b/karavan-app/src/main/webui/src/knowledgebase/eip/EipCard.tsx
index fb47a932..bac46590 100644
--- a/karavan-app/src/main/webui/src/knowledgebase/eip/EipCard.tsx
+++ b/karavan-app/src/main/webui/src/knowledgebase/eip/EipCard.tsx
@@ -16,7 +16,7 @@
  */
 import React from 'react';
 import {
-    CardHeader, Card, CardTitle, CardBody, CardFooter,Badge
+    CardHeader, Card, CardTitle, CardBody, CardFooter, Badge, Text
 } from '@patternfly/react-core';
 import '../../designer/karavan.css';
 import {CamelUi} from "../../designer/utils/CamelUi";
@@ -39,18 +39,20 @@ export function EipCard(props: Props) {
         setElement(element)
         setModalOpen(true);
     }
-
     return (
-        <Card  isCompact key={element.name} className="kamelet-card"
+        <Card  isCompact key={element.name} className="knowledgebase-card"
                onClick={event => click(event)}
         >
             <CardHeader>
+                <Badge className='label-eip'>EIP</Badge>
             </CardHeader>
             <CardHeader>
                 {CamelUi.getIconForDslName(element.className)}
                 <CardTitle>{element.title}</CardTitle>
             </CardHeader>
-            <CardBody>{element.description}</CardBody>
+            <CardBody>
+                <Text 
className="pf-v5-u-color-200">{element.description}</Text>
+            </CardBody>
             <CardFooter className="footer-labels">
                 <div>
                     {element.labels.split(',').map((s: string,  i: number) => 
<Badge key={s + i} isRead
diff --git a/karavan-app/src/main/webui/src/knowledgebase/eip/EipTab.tsx 
b/karavan-app/src/main/webui/src/knowledgebase/eip/EipTab.tsx
index 35cc9741..7720bd29 100644
--- a/karavan-app/src/main/webui/src/knowledgebase/eip/EipTab.tsx
+++ b/karavan-app/src/main/webui/src/knowledgebase/eip/EipTab.tsx
@@ -17,66 +17,35 @@
 import React from 'react';
 import {
     Gallery,
-    PageSection, PageSectionVariants,ToggleGroup,ToggleGroupItem
+    PageSection, PageSectionVariants
 } from '@patternfly/react-core';
 import '../../designer/karavan.css';
 import {EipCard} from "./EipCard";
 import {EipModal} from "./EipModal";
-import {CamelModelMetadata, ElementMeta} from 
"karavan-core/lib/model/CamelMetadata";
 import {useKnowledgebaseStore} from "../KnowledgebaseStore";
 import {shallow} from "zustand/shallow";
-import { useSelectorStore } from '../../designer/DesignerStore';
+import {ElementMeta} from "karavan-core/lib/model/CamelMetadata";
 
 interface Props {
     dark: boolean,
-    filter: string,
+    elements: ElementMeta[],
 }
 
 export function EipTab(props: Props) {
 
-    const [isModalOpen] = useKnowledgebaseStore((s) =>
-        [s.isModalOpen], shallow)
+    const [isModalOpen] = useKnowledgebaseStore((s) => [s.isModalOpen], 
shallow)
+
+    const { elements } = props;
 
-        const [ selectedLabels, addSelectedLabel, deleteSelectedLabel] =
-        useSelectorStore((s) =>
-            [s.selectedLabels, s.addSelectedLabel, s.deleteSelectedLabel], 
shallow)
-        const { filter } = props;
-        const elements = CamelModelMetadata;
-        const filteredElements=CamelModelMetadata
-        .filter(c => 
c.name.toLowerCase().includes(filter.toLowerCase())).filter((dsl: ElementMeta) 
=> {
-            if (selectedLabels.length === 0) {
-                return true;
-            } else {
-                return dsl.labels.split(",").some(r => 
selectedLabels.includes(r));
-            }
-        })
-        .sort((a: ElementMeta, b: ElementMeta) => a.name > b.name ? 1 : -1);
-     const eipLabels = [...new Set(elements.map(e => 
e.labels).join(",").split(",").filter(e => e !== 'eip'))];
-    function selectLabel(eipLabel: string) {
-            if (!selectedLabels.includes(eipLabel)) {
-                addSelectedLabel(eipLabel);
-            } else {
-                deleteSelectedLabel(eipLabel);
-            }
-        }
     return (
         <PageSection variant={props.dark ? PageSectionVariants.darker : 
PageSectionVariants.light}
             padding={{ default: 'noPadding' }} className="kamelet-section 
knowledbase-eip-section">
-             <ToggleGroup aria-label="Labels" isCompact >
-                    {eipLabels.map(eipLabel => <ToggleGroupItem
-                        key={eipLabel}
-                        text={eipLabel}
-                        buttonId={eipLabel}
-                        isSelected={selectedLabels.includes(eipLabel)}
-                        onChange={selected => selectLabel(eipLabel)}
-                    />)}
-                </ToggleGroup>
 
             {isModalOpen && <EipModal/>}
             <PageSection isFilled className="kamelets-page"
                          variant={props.dark ? PageSectionVariants.darker : 
PageSectionVariants.light}>
                 <Gallery hasGutter>
-                    {filteredElements.map(c => (
+                    {elements.map(c => (
                         <EipCard key={c.name} element={c}/>
                     ))}
                 </Gallery>
diff --git 
a/karavan-app/src/main/webui/src/knowledgebase/kamelets/KameletCard.tsx 
b/karavan-app/src/main/webui/src/knowledgebase/kamelets/KameletCard.tsx
index a1a0f903..4fb6e662 100644
--- a/karavan-app/src/main/webui/src/knowledgebase/kamelets/KameletCard.tsx
+++ b/karavan-app/src/main/webui/src/knowledgebase/kamelets/KameletCard.tsx
@@ -56,14 +56,16 @@ export function KameletCard(props: Props) {
         setBlockedKamelets([...KameletApi.getBlockedKameletNames()]);
     }
     const isblockedKamelet = blockedKamelets ? blockedKamelets.findIndex(r => 
r === kamelet.metadata.name) > -1 : false;
+    const supportLevel = 
kamelet.metadata.annotations["camel.apache.org/kamelet.support.level"];
+    const classNameBadge = 'label-kamelet' + (supportLevel !== 'Stable' ? 
'-preview' : '')
     return (
-        <Card  isCompact key={kamelet.metadata.name} className="kamelet-card"
+        <Card  isCompact key={kamelet.metadata.name} 
className="knowledgebase-card"
                onClick={event => click(event)}
         >
             <CardHeader className="header-labels">
                 <Flex style={{width:'100%'}} gap={{default:'gapSm'}} 
justifyContent={{default: 'justifyContentSpaceBetween'}}>
+                    <Badge className={classNameBadge}>Kamelet</Badge>
                     <Badge isRead className="support-level 
labels">{kamelet.metadata.annotations["camel.apache.org/kamelet.support.level"]}</Badge>
-                    <Badge isRead className="version 
labels">{kamelet.metadata.annotations["camel.apache.org/catalog.version"].toLowerCase()}</Badge>
                 </Flex>
                 {showBlockCheckbox && <Checkbox id={kamelet.metadata.name} 
className="block-checkbox labels" isChecked={!isblockedKamelet}
                                                 onChange={(_, checked) => 
selectKamelet(_, checked)}/>}
diff --git 
a/karavan-app/src/main/webui/src/knowledgebase/kamelets/KameletsTab.tsx 
b/karavan-app/src/main/webui/src/knowledgebase/kamelets/KameletsTab.tsx
index 353819e4..83db2eb5 100644
--- a/karavan-app/src/main/webui/src/knowledgebase/kamelets/KameletsTab.tsx
+++ b/karavan-app/src/main/webui/src/knowledgebase/kamelets/KameletsTab.tsx
@@ -22,27 +22,23 @@ import {
 } from '@patternfly/react-core';
 import '../../designer/karavan.css';
 import {KameletCard} from "./KameletCard";
-import {KameletApi} from "karavan-core/lib/api/KameletApi";
 import {KameletModal} from "./KameletModal";
 import {useKnowledgebaseStore} from "../KnowledgebaseStore";
 import {shallow} from "zustand/shallow";
+import {KameletModel} from "karavan-core/lib/model/KameletModels";
 
 interface Props {
     dark: boolean,
-    filter: string,
-    customOnly: boolean,
+    kameletList: KameletModel[],
     onChange: (name: string, checked: boolean) => void
 }
 
 export function KameletsTab(props: Props) {
 
-    const [isModalOpen] = useKnowledgebaseStore((s) =>
-        [s.isModalOpen], shallow)
+    const [isModalOpen] = useKnowledgebaseStore((s) => [s.isModalOpen], 
shallow)
+
+    const {kameletList, dark} = props;
 
-    const {filter, customOnly, dark} = props;
-    let kameletList = KameletApi.getKamelets().filter(kamelet =>
-        
kamelet.spec.definition.title.toLowerCase().includes(filter.toLowerCase()));
-    if (customOnly) kameletList = kameletList.filter(k => 
KameletApi.getCustomKameletNames().includes(k.metadata.name));
     return (
         <PageSection variant={dark ? PageSectionVariants.darker : 
PageSectionVariants.light}
                      padding={{default: 'noPadding'}} 
className="kamelet-section">
diff --git a/karavan-app/src/main/webui/src/knowledgebase/knowledgebase.css 
b/karavan-app/src/main/webui/src/knowledgebase/knowledgebase.css
index 6fb889de..b0caf549 100644
--- a/karavan-app/src/main/webui/src/knowledgebase/knowledgebase.css
+++ b/karavan-app/src/main/webui/src/knowledgebase/knowledgebase.css
@@ -15,7 +15,129 @@
  * limitations under the License.
  */
 
-.kamelets-page .kamelet-card .block-checkbox {
+.karavan .knowledgebase-section {
+    display: flex;
+    flex-direction: column;
+    height: 100%;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card {
+    cursor: pointer;
+    height: 160px;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .pf-v5-c-card__header {
+    padding-top: var(--pf-v5-global--spacer--sm);
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .pf-v5-c-card__header 
.custom {
+    margin-left: auto;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .pf-v5-c-card__header 
.pf-v5-c-card__header-main {
+    display: flex;
+    flex-direction: row;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .pf-v5-c-card__title {
+    font-size: 15px;
+    font-weight: 400;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .pf-v5-c-card__body {
+    overflow: hidden;
+    position: relative;
+    line-height: 1.6em;
+}
+
+.knowledgebase-section .knowledgebase-card .icon {
+    height: 24px;
+    max-width: 24px;
+    margin-top: auto;
+    margin-bottom: auto;
+    margin-right: 5px;
+    border: none;
+    -webkit-user-select: none;
+    -khtml-user-select: none;
+    -moz-user-select: none;
+    -o-user-select: none;
+    user-select: none;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .header-labels {
+    padding: 5px;
+    display: flex;
+    flex-direction: row;
+    justify-content: flex-end;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .header-labels 
.pf-v5-c-card__header-main {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .footer-labels {
+    padding: 5px;
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .version,
+.karavan .knowledgebase-section .knowledgebase-card .support-type,
+.karavan .knowledgebase-section .knowledgebase-card .support-level {
+    white-space: nowrap;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .labels {
+    opacity: 0.5;
+    font-weight: 200;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card:hover .labels {
+    opacity: 1;
+}
+
+.knowledgebase-section .knowledgebase-card .block-checkbox {
     align-self: center;
     margin-left: 6px;
+}
+
+.knowledgebase-section .knowledgebase-card .pf-v5-c-card__body {
+    padding-bottom: 0;
+    height: 54px;
+}
+
+.knowledgebase-section .knowledgebase-card .pf-v5-c-card__body {
+    padding-bottom: 0;
+    height: 54px;
+}
+
+.knowledgebase-section .knowledgebase-card p {
+    overflow: hidden;
+    display: -webkit-box;
+    -webkit-line-clamp: 2;
+    -webkit-box-orient: vertical;
+    color: var(--pf-v5-global--Color--200);
+}
+
+.knowledgebase-section {
+    .label-eip {
+        --pf-v5-c-badge--BackgroundColor: 
var(--pf-v5-global--palette--orange-200);
+    }
+    .label-component {
+        --pf-v5-c-badge--BackgroundColor: 
var(--pf-v5-global--palette--blue-300);
+    }
+    .label-kamelet {
+        --pf-v5-c-badge--BackgroundColor: 
var(--pf-v5-global--palette--green-300);
+    }
+    .label-component-preview {
+        --pf-v5-c-badge--Color: var(--pf-v5-global--palette--blue-300);
+        --pf-v5-c-badge--BackgroundColor: 
var(--pf-v5-c-badge--m-read--BackgroundColor);
+    }
+    .label-kamelet-preview {
+        --pf-v5-c-badge--Color: var(--pf-v5-global--palette--green-300);
+        --pf-v5-c-badge--BackgroundColor: 
var(--pf-v5-c-badge--m-read--BackgroundColor);
+    }
 }
\ No newline at end of file
diff --git a/karavan-designer/src/designer/DesignerStore.ts 
b/karavan-designer/src/designer/DesignerStore.ts
index 9c855c5f..e207c546 100644
--- a/karavan-designer/src/designer/DesignerStore.ts
+++ b/karavan-designer/src/designer/DesignerStore.ts
@@ -105,10 +105,6 @@ interface SelectorStateState {
     setSelectorTabIndex: (selectorTabIndex?: string | number) => void;
     selectedPosition?: number;
     setSelectedPosition: (selectedPosition?: number) => void;
-    selectedLabels: string [];
-    addSelectedLabel: (label: string) => void;
-    deleteSelectedLabel: (label: string) => void;
-    clearSelectedLabels: () => void;
     selectedToggles: string [];
     addSelectedToggle: (label: string) => void;
     deleteSelectedToggle: (label: string) => void;
@@ -121,24 +117,7 @@ export const useSelectorStore = 
createWithEqualityFn<SelectorStateState>((set) =
     deleteMessage: '',
     parentId: '',
     showSteps: true,
-    selectedLabels: [],
     selectedToggles: ['eip', 'components', 'kamelets'],
-    addSelectedLabel: (label: string) => {
-        set(state => ({
-            selectedLabels: [...state.selectedLabels, label]
-        }))
-    },
-    deleteSelectedLabel: (label: string) => {
-        set(state => ({
-            selectedLabels: [...state.selectedLabels.filter(x => x !== label)]
-        }))
-    },
-    clearSelectedLabels: () => {
-        set((state: SelectorStateState) => {
-            state.selectedLabels.length = 0;
-            return {selectedLabels : [...state.selectedLabels]};
-        })
-    },
     addSelectedToggle: (toggle: string) => {
         set(state => ({
             selectedToggles: [...state.selectedToggles, toggle]
diff --git a/karavan-designer/src/designer/property/PropertiesHeader.tsx 
b/karavan-designer/src/designer/property/PropertiesHeader.tsx
index 30b0034b..b8aca6b4 100644
--- a/karavan-designer/src/designer/property/PropertiesHeader.tsx
+++ b/karavan-designer/src/designer/property/PropertiesHeader.tsx
@@ -94,7 +94,7 @@ export function PropertiesHeader(props: Props) {
                             openSelectorToReplaceFrom((selectedStep as any).id)
                             setMenuOpen(false);
                         }}>
-                            Change From Element
+                            Change From...
                         </DropdownItem>}
                     {hasSteps &&
                         <DropdownItem key="saveStepsRoute" onClick={(ev) => {
diff --git a/karavan-designer/src/knowledgebase/KnowledgebasePage.tsx 
b/karavan-designer/src/knowledgebase/KnowledgebasePage.tsx
index a7c1d514..cb2e7158 100644
--- a/karavan-designer/src/knowledgebase/KnowledgebasePage.tsx
+++ b/karavan-designer/src/knowledgebase/KnowledgebasePage.tsx
@@ -16,13 +16,30 @@
  */
 import React, {useState} from 'react';
 import '../designer/karavan.css';
-import {Flex, FlexItem, PageSection, Switch, Tab, Tabs, Text, TextContent, 
TextInput, Toolbar, ToolbarContent} from "@patternfly/react-core";
+import {
+    Badge,
+    Flex,
+    FlexItem,
+    PageSection,
+    Switch,
+    Tab,
+    Tabs,
+    Text,
+    TextContent,
+    TextInput,
+    Toolbar,
+    ToolbarContent
+} from "@patternfly/react-core";
 import {MainToolbar} from "../designer/MainToolbar";
 import {KameletsTab} from "./kamelets/KameletsTab";
 import {EipTab} from "./eip/EipTab";
 import {ComponentsTab} from "./components/ComponentsTab";
 import {useKnowledgebaseStore} from "./KnowledgebaseStore";
 import {shallow} from "zustand/shallow";
+import {KameletApi} from "karavan-core/lib/api/KameletApi";
+import {KameletModel} from "karavan-core/lib/model/KameletModels";
+import {ComponentApi} from "karavan-core/lib/api/ComponentApi";
+import {CamelModelMetadata, ElementMeta} from 
"karavan-core/lib/model/CamelMetadata";
 
 interface Props {
     dark: boolean,
@@ -33,7 +50,7 @@ interface Props {
 export const KnowledgebasePage = (props: Props) => {
 
     const [setShowBlockCheckbox] = useKnowledgebaseStore((s) => 
[s.setShowBlockCheckbox], shallow)
-    const [tab, setTab] = useState<string | number>("eip");
+    const [tab, setTab] = useState<string | number>("components");
     const [filter, setFilter] = useState<string>("");
     const [customOnly, setCustomOnly] = useState<boolean>(false);
 
@@ -71,8 +88,21 @@ export const KnowledgebasePage = (props: Props) => {
         </Toolbar>
     }
 
+    let kameletList: KameletModel[] = KameletApi.getKamelets().filter(kamelet 
=>
+            
kamelet.spec.definition.title.toLowerCase().includes(filter.toLowerCase()));
+    if (customOnly) kameletList = kameletList.filter(k => 
KameletApi.getCustomKameletNames().includes(k.metadata.name));
+
+    const components = ComponentApi.getComponents().filter(c => {
+        return c.component.name.toLowerCase().includes(filter.toLowerCase())
+            || c.component.title.toLowerCase().includes(filter.toLowerCase())
+            || 
c.component.description.toLowerCase().includes(filter.toLowerCase())
+    }).sort((a, b) => (a.component.title?.toLowerCase() > 
b.component.title?.toLowerCase() ? 1 : -1)) ;
+
+    const elements= CamelModelMetadata
+        .filter(c => 
c.name.toLowerCase().includes(filter.toLowerCase())).sort((a: ElementMeta, b: 
ElementMeta) => a.name > b.name ? 1 : -1);
+
     return (
-        <PageSection className="kamelet-section" padding={{default: 
'noPadding'}}>
+        <PageSection className="knowledgebase-section" padding={{default: 
'noPadding'}}>
             <PageSection className="tools-section" padding={{default: 
'noPadding'}}>
                 <MainToolbar title={title()} tools={getTools()}/>
             </PageSection>
@@ -80,17 +110,24 @@ export const KnowledgebasePage = (props: Props) => {
                 <Flex direction={{default: "column"}} spaceItems={{default: 
"spaceItemsNone"}}>
                     <FlexItem>
                         <Tabs activeKey={tab} onSelect={(event, tabIndex) => 
setTab(tabIndex)}>
-                            <Tab eventKey="eip" title="Integration Patterns"/>
-                            <Tab eventKey="kamelets" title="Kamelets"/>
-                            <Tab eventKey="components" title="Components"/>
+                            <Tab eventKey="components" title={<div 
style={{display: 'flex', gap:'6px'}}>Components<Badge 
className='label-component'>{components.length}</Badge></div>}/>
+                            <Tab eventKey="eip" title={<div style={{display: 
'flex', gap:'6px'}}>Integration Patterns<Badge 
className='label-eip'>{elements.length}</Badge></div>}/>
+                            <Tab eventKey="kamelets" title={<div 
style={{display: 'flex', gap:'6px'}}>Kamelets<Badge 
className='label-kamelet'>{kameletList.length}</Badge></div>}/>
                         </Tabs>
                     </FlexItem>
                 </Flex>
             </PageSection>
             <>
-                {tab === 'kamelets' && <KameletsTab dark={props.dark} 
filter={filter} customOnly={customOnly} onChange={(name: string, checked: 
boolean) => props.changeBlockList('kamelet', name, checked)}  />}
-                {tab === 'eip' && <EipTab dark={props.dark} filter={filter}/>}
-                {tab === 'components' && <ComponentsTab dark={props.dark} 
filter={filter} onChange={(name: string, checked: boolean) => 
props.changeBlockList('component', name, checked)}  />}
+                {tab === 'kamelets' && <KameletsTab dark={props.dark}
+                                                    kameletList={kameletList}
+                                                    onChange={(name: string, 
checked: boolean) => props.changeBlockList('kamelet', name, checked)} />
+                }
+                {tab === 'eip' && <EipTab dark={props.dark} 
elements={elements}/>
+                }
+                {tab === 'components' && <ComponentsTab dark={props.dark}
+                                                        components={components}
+                                                        onChange={(name: 
string, checked: boolean) => props.changeBlockList('component', name, checked)} 
/>
+                }
             </>
         </PageSection>
     )
diff --git a/karavan-designer/src/knowledgebase/components/ComponentCard.tsx 
b/karavan-designer/src/knowledgebase/components/ComponentCard.tsx
index c9f39d04..80d298c5 100644
--- a/karavan-designer/src/knowledgebase/components/ComponentCard.tsx
+++ b/karavan-designer/src/knowledgebase/components/ComponentCard.tsx
@@ -16,7 +16,7 @@
  */
 import React, {useEffect, useState} from 'react';
 import {
-    CardHeader, Card, CardTitle, CardBody, CardFooter, Badge, Checkbox, Flex
+    CardHeader, Card, CardTitle, CardBody, CardFooter, Badge, Checkbox, Flex, 
Text
 } from '@patternfly/react-core';
 import '../../designer/karavan.css';
 import {CamelUi} from "../../designer/utils/CamelUi";
@@ -56,14 +56,15 @@ export function ComponentCard(props: Props) {
 
     const isBlockedComponent = blockedComponents ? 
blockedComponents.findIndex(r => r === component.component.name) > -1 : false;
     const isRemote = component.component.remote;
+    const classNameBadge = 'label-component' + 
(component.component.supportLevel !== 'Stable' ? '-preview' : '')
     return (
-        <Card isCompact key={component.component.name} className="kamelet-card"
+        <Card isCompact key={component.component.name} 
className="knowledgebase-card"
               onClick={event => click(event)}
         >
             <CardHeader className="header-labels">
                 <Flex style={{width: '100%'}} gap={{default: 'gapSm'}} 
justifyContent={{default: 'justifyContentSpaceBetween'}}>
+                    <Badge className={classNameBadge}>Component</Badge>
                     <Badge isRead className="support-level 
labels">{component.component.supportLevel}</Badge>
-                    <Badge isRead className="version 
labels">{component.component.version}</Badge>
                 </Flex>
                 {showBlockCheckbox &&
                     <Checkbox id={component.component.name}
@@ -77,7 +78,9 @@ export function ComponentCard(props: Props) {
                 {CamelUi.getIconForComponent(component.component.title, 
component.component.label)}
                 <CardTitle>{component.component.title}</CardTitle>
             </CardHeader>
-            <CardBody>{component.component.description}</CardBody>
+            <CardBody>
+                <Text 
className="pf-v5-u-color-200">{component.component.description}</Text>
+            </CardBody>
             <CardFooter className="footer-labels">
                 <Badge isRead 
className="labels">{component.component.label}</Badge>
                 <Badge isRead className="labels">{isRemote ? 'remote' : 
'internal'}</Badge>
diff --git a/karavan-designer/src/knowledgebase/components/ComponentsTab.tsx 
b/karavan-designer/src/knowledgebase/components/ComponentsTab.tsx
index 9e9fb470..c4fdb592 100644
--- a/karavan-designer/src/knowledgebase/components/ComponentsTab.tsx
+++ b/karavan-designer/src/knowledgebase/components/ComponentsTab.tsx
@@ -22,28 +22,21 @@ import {
 import '../../designer/karavan.css';
 import {ComponentCard} from "./ComponentCard";
 import {ComponentModal} from "./ComponentModal";
-import {ComponentApi} from "karavan-core/lib/api/ComponentApi";
 import {shallow} from "zustand/shallow";
 import {useKnowledgebaseStore} from "../KnowledgebaseStore";
+import { Component } from 'karavan-core/lib/model/ComponentModels';
 
 interface Props {
     dark: boolean,
-    filter: string,
+    components: Component[],
     onChange: (name: string, checked: boolean) => void,
 }
 
 export function ComponentsTab(props: Props) {
 
-    const [isModalOpen] = useKnowledgebaseStore((s) =>
-        [s.isModalOpen], shallow)
+    const [isModalOpen] = useKnowledgebaseStore((s) => [s.isModalOpen], 
shallow)
 
-
-    const {filter} = props;
-    const components = ComponentApi.getComponents().filter(c => {
-        return c.component.name.toLowerCase().includes(filter.toLowerCase())
-            || c.component.title.toLowerCase().includes(filter.toLowerCase())
-            || 
c.component.description.toLowerCase().includes(filter.toLowerCase())
-    }).sort((a, b) => (a.component.title?.toLowerCase() > 
b.component.title?.toLowerCase() ? 1 : -1)) ;
+    const {components} = props;
     return (
         <PageSection variant={props.dark ? PageSectionVariants.darker : 
PageSectionVariants.light} padding={{ default: 'noPadding' }} 
className="kamelet-section">
             {isModalOpen && <ComponentModal/>}
diff --git a/karavan-designer/src/knowledgebase/eip/EipCard.tsx 
b/karavan-designer/src/knowledgebase/eip/EipCard.tsx
index fb47a932..bac46590 100644
--- a/karavan-designer/src/knowledgebase/eip/EipCard.tsx
+++ b/karavan-designer/src/knowledgebase/eip/EipCard.tsx
@@ -16,7 +16,7 @@
  */
 import React from 'react';
 import {
-    CardHeader, Card, CardTitle, CardBody, CardFooter,Badge
+    CardHeader, Card, CardTitle, CardBody, CardFooter, Badge, Text
 } from '@patternfly/react-core';
 import '../../designer/karavan.css';
 import {CamelUi} from "../../designer/utils/CamelUi";
@@ -39,18 +39,20 @@ export function EipCard(props: Props) {
         setElement(element)
         setModalOpen(true);
     }
-
     return (
-        <Card  isCompact key={element.name} className="kamelet-card"
+        <Card  isCompact key={element.name} className="knowledgebase-card"
                onClick={event => click(event)}
         >
             <CardHeader>
+                <Badge className='label-eip'>EIP</Badge>
             </CardHeader>
             <CardHeader>
                 {CamelUi.getIconForDslName(element.className)}
                 <CardTitle>{element.title}</CardTitle>
             </CardHeader>
-            <CardBody>{element.description}</CardBody>
+            <CardBody>
+                <Text 
className="pf-v5-u-color-200">{element.description}</Text>
+            </CardBody>
             <CardFooter className="footer-labels">
                 <div>
                     {element.labels.split(',').map((s: string,  i: number) => 
<Badge key={s + i} isRead
diff --git a/karavan-designer/src/knowledgebase/eip/EipTab.tsx 
b/karavan-designer/src/knowledgebase/eip/EipTab.tsx
index 35cc9741..7720bd29 100644
--- a/karavan-designer/src/knowledgebase/eip/EipTab.tsx
+++ b/karavan-designer/src/knowledgebase/eip/EipTab.tsx
@@ -17,66 +17,35 @@
 import React from 'react';
 import {
     Gallery,
-    PageSection, PageSectionVariants,ToggleGroup,ToggleGroupItem
+    PageSection, PageSectionVariants
 } from '@patternfly/react-core';
 import '../../designer/karavan.css';
 import {EipCard} from "./EipCard";
 import {EipModal} from "./EipModal";
-import {CamelModelMetadata, ElementMeta} from 
"karavan-core/lib/model/CamelMetadata";
 import {useKnowledgebaseStore} from "../KnowledgebaseStore";
 import {shallow} from "zustand/shallow";
-import { useSelectorStore } from '../../designer/DesignerStore';
+import {ElementMeta} from "karavan-core/lib/model/CamelMetadata";
 
 interface Props {
     dark: boolean,
-    filter: string,
+    elements: ElementMeta[],
 }
 
 export function EipTab(props: Props) {
 
-    const [isModalOpen] = useKnowledgebaseStore((s) =>
-        [s.isModalOpen], shallow)
+    const [isModalOpen] = useKnowledgebaseStore((s) => [s.isModalOpen], 
shallow)
+
+    const { elements } = props;
 
-        const [ selectedLabels, addSelectedLabel, deleteSelectedLabel] =
-        useSelectorStore((s) =>
-            [s.selectedLabels, s.addSelectedLabel, s.deleteSelectedLabel], 
shallow)
-        const { filter } = props;
-        const elements = CamelModelMetadata;
-        const filteredElements=CamelModelMetadata
-        .filter(c => 
c.name.toLowerCase().includes(filter.toLowerCase())).filter((dsl: ElementMeta) 
=> {
-            if (selectedLabels.length === 0) {
-                return true;
-            } else {
-                return dsl.labels.split(",").some(r => 
selectedLabels.includes(r));
-            }
-        })
-        .sort((a: ElementMeta, b: ElementMeta) => a.name > b.name ? 1 : -1);
-     const eipLabels = [...new Set(elements.map(e => 
e.labels).join(",").split(",").filter(e => e !== 'eip'))];
-    function selectLabel(eipLabel: string) {
-            if (!selectedLabels.includes(eipLabel)) {
-                addSelectedLabel(eipLabel);
-            } else {
-                deleteSelectedLabel(eipLabel);
-            }
-        }
     return (
         <PageSection variant={props.dark ? PageSectionVariants.darker : 
PageSectionVariants.light}
             padding={{ default: 'noPadding' }} className="kamelet-section 
knowledbase-eip-section">
-             <ToggleGroup aria-label="Labels" isCompact >
-                    {eipLabels.map(eipLabel => <ToggleGroupItem
-                        key={eipLabel}
-                        text={eipLabel}
-                        buttonId={eipLabel}
-                        isSelected={selectedLabels.includes(eipLabel)}
-                        onChange={selected => selectLabel(eipLabel)}
-                    />)}
-                </ToggleGroup>
 
             {isModalOpen && <EipModal/>}
             <PageSection isFilled className="kamelets-page"
                          variant={props.dark ? PageSectionVariants.darker : 
PageSectionVariants.light}>
                 <Gallery hasGutter>
-                    {filteredElements.map(c => (
+                    {elements.map(c => (
                         <EipCard key={c.name} element={c}/>
                     ))}
                 </Gallery>
diff --git a/karavan-designer/src/knowledgebase/kamelets/KameletCard.tsx 
b/karavan-designer/src/knowledgebase/kamelets/KameletCard.tsx
index a1a0f903..4fb6e662 100644
--- a/karavan-designer/src/knowledgebase/kamelets/KameletCard.tsx
+++ b/karavan-designer/src/knowledgebase/kamelets/KameletCard.tsx
@@ -56,14 +56,16 @@ export function KameletCard(props: Props) {
         setBlockedKamelets([...KameletApi.getBlockedKameletNames()]);
     }
     const isblockedKamelet = blockedKamelets ? blockedKamelets.findIndex(r => 
r === kamelet.metadata.name) > -1 : false;
+    const supportLevel = 
kamelet.metadata.annotations["camel.apache.org/kamelet.support.level"];
+    const classNameBadge = 'label-kamelet' + (supportLevel !== 'Stable' ? 
'-preview' : '')
     return (
-        <Card  isCompact key={kamelet.metadata.name} className="kamelet-card"
+        <Card  isCompact key={kamelet.metadata.name} 
className="knowledgebase-card"
                onClick={event => click(event)}
         >
             <CardHeader className="header-labels">
                 <Flex style={{width:'100%'}} gap={{default:'gapSm'}} 
justifyContent={{default: 'justifyContentSpaceBetween'}}>
+                    <Badge className={classNameBadge}>Kamelet</Badge>
                     <Badge isRead className="support-level 
labels">{kamelet.metadata.annotations["camel.apache.org/kamelet.support.level"]}</Badge>
-                    <Badge isRead className="version 
labels">{kamelet.metadata.annotations["camel.apache.org/catalog.version"].toLowerCase()}</Badge>
                 </Flex>
                 {showBlockCheckbox && <Checkbox id={kamelet.metadata.name} 
className="block-checkbox labels" isChecked={!isblockedKamelet}
                                                 onChange={(_, checked) => 
selectKamelet(_, checked)}/>}
diff --git a/karavan-designer/src/knowledgebase/kamelets/KameletsTab.tsx 
b/karavan-designer/src/knowledgebase/kamelets/KameletsTab.tsx
index 353819e4..83db2eb5 100644
--- a/karavan-designer/src/knowledgebase/kamelets/KameletsTab.tsx
+++ b/karavan-designer/src/knowledgebase/kamelets/KameletsTab.tsx
@@ -22,27 +22,23 @@ import {
 } from '@patternfly/react-core';
 import '../../designer/karavan.css';
 import {KameletCard} from "./KameletCard";
-import {KameletApi} from "karavan-core/lib/api/KameletApi";
 import {KameletModal} from "./KameletModal";
 import {useKnowledgebaseStore} from "../KnowledgebaseStore";
 import {shallow} from "zustand/shallow";
+import {KameletModel} from "karavan-core/lib/model/KameletModels";
 
 interface Props {
     dark: boolean,
-    filter: string,
-    customOnly: boolean,
+    kameletList: KameletModel[],
     onChange: (name: string, checked: boolean) => void
 }
 
 export function KameletsTab(props: Props) {
 
-    const [isModalOpen] = useKnowledgebaseStore((s) =>
-        [s.isModalOpen], shallow)
+    const [isModalOpen] = useKnowledgebaseStore((s) => [s.isModalOpen], 
shallow)
+
+    const {kameletList, dark} = props;
 
-    const {filter, customOnly, dark} = props;
-    let kameletList = KameletApi.getKamelets().filter(kamelet =>
-        
kamelet.spec.definition.title.toLowerCase().includes(filter.toLowerCase()));
-    if (customOnly) kameletList = kameletList.filter(k => 
KameletApi.getCustomKameletNames().includes(k.metadata.name));
     return (
         <PageSection variant={dark ? PageSectionVariants.darker : 
PageSectionVariants.light}
                      padding={{default: 'noPadding'}} 
className="kamelet-section">
diff --git a/karavan-designer/src/knowledgebase/knowledgebase.css 
b/karavan-designer/src/knowledgebase/knowledgebase.css
index 6fb889de..b0caf549 100644
--- a/karavan-designer/src/knowledgebase/knowledgebase.css
+++ b/karavan-designer/src/knowledgebase/knowledgebase.css
@@ -15,7 +15,129 @@
  * limitations under the License.
  */
 
-.kamelets-page .kamelet-card .block-checkbox {
+.karavan .knowledgebase-section {
+    display: flex;
+    flex-direction: column;
+    height: 100%;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card {
+    cursor: pointer;
+    height: 160px;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .pf-v5-c-card__header {
+    padding-top: var(--pf-v5-global--spacer--sm);
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .pf-v5-c-card__header 
.custom {
+    margin-left: auto;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .pf-v5-c-card__header 
.pf-v5-c-card__header-main {
+    display: flex;
+    flex-direction: row;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .pf-v5-c-card__title {
+    font-size: 15px;
+    font-weight: 400;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .pf-v5-c-card__body {
+    overflow: hidden;
+    position: relative;
+    line-height: 1.6em;
+}
+
+.knowledgebase-section .knowledgebase-card .icon {
+    height: 24px;
+    max-width: 24px;
+    margin-top: auto;
+    margin-bottom: auto;
+    margin-right: 5px;
+    border: none;
+    -webkit-user-select: none;
+    -khtml-user-select: none;
+    -moz-user-select: none;
+    -o-user-select: none;
+    user-select: none;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .header-labels {
+    padding: 5px;
+    display: flex;
+    flex-direction: row;
+    justify-content: flex-end;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .header-labels 
.pf-v5-c-card__header-main {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .footer-labels {
+    padding: 5px;
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .version,
+.karavan .knowledgebase-section .knowledgebase-card .support-type,
+.karavan .knowledgebase-section .knowledgebase-card .support-level {
+    white-space: nowrap;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .labels {
+    opacity: 0.5;
+    font-weight: 200;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card:hover .labels {
+    opacity: 1;
+}
+
+.knowledgebase-section .knowledgebase-card .block-checkbox {
     align-self: center;
     margin-left: 6px;
+}
+
+.knowledgebase-section .knowledgebase-card .pf-v5-c-card__body {
+    padding-bottom: 0;
+    height: 54px;
+}
+
+.knowledgebase-section .knowledgebase-card .pf-v5-c-card__body {
+    padding-bottom: 0;
+    height: 54px;
+}
+
+.knowledgebase-section .knowledgebase-card p {
+    overflow: hidden;
+    display: -webkit-box;
+    -webkit-line-clamp: 2;
+    -webkit-box-orient: vertical;
+    color: var(--pf-v5-global--Color--200);
+}
+
+.knowledgebase-section {
+    .label-eip {
+        --pf-v5-c-badge--BackgroundColor: 
var(--pf-v5-global--palette--orange-200);
+    }
+    .label-component {
+        --pf-v5-c-badge--BackgroundColor: 
var(--pf-v5-global--palette--blue-300);
+    }
+    .label-kamelet {
+        --pf-v5-c-badge--BackgroundColor: 
var(--pf-v5-global--palette--green-300);
+    }
+    .label-component-preview {
+        --pf-v5-c-badge--Color: var(--pf-v5-global--palette--blue-300);
+        --pf-v5-c-badge--BackgroundColor: 
var(--pf-v5-c-badge--m-read--BackgroundColor);
+    }
+    .label-kamelet-preview {
+        --pf-v5-c-badge--Color: var(--pf-v5-global--palette--green-300);
+        --pf-v5-c-badge--BackgroundColor: 
var(--pf-v5-c-badge--m-read--BackgroundColor);
+    }
 }
\ No newline at end of file
diff --git a/karavan-space/src/designer/DesignerStore.ts 
b/karavan-space/src/designer/DesignerStore.ts
index 9c855c5f..e207c546 100644
--- a/karavan-space/src/designer/DesignerStore.ts
+++ b/karavan-space/src/designer/DesignerStore.ts
@@ -105,10 +105,6 @@ interface SelectorStateState {
     setSelectorTabIndex: (selectorTabIndex?: string | number) => void;
     selectedPosition?: number;
     setSelectedPosition: (selectedPosition?: number) => void;
-    selectedLabels: string [];
-    addSelectedLabel: (label: string) => void;
-    deleteSelectedLabel: (label: string) => void;
-    clearSelectedLabels: () => void;
     selectedToggles: string [];
     addSelectedToggle: (label: string) => void;
     deleteSelectedToggle: (label: string) => void;
@@ -121,24 +117,7 @@ export const useSelectorStore = 
createWithEqualityFn<SelectorStateState>((set) =
     deleteMessage: '',
     parentId: '',
     showSteps: true,
-    selectedLabels: [],
     selectedToggles: ['eip', 'components', 'kamelets'],
-    addSelectedLabel: (label: string) => {
-        set(state => ({
-            selectedLabels: [...state.selectedLabels, label]
-        }))
-    },
-    deleteSelectedLabel: (label: string) => {
-        set(state => ({
-            selectedLabels: [...state.selectedLabels.filter(x => x !== label)]
-        }))
-    },
-    clearSelectedLabels: () => {
-        set((state: SelectorStateState) => {
-            state.selectedLabels.length = 0;
-            return {selectedLabels : [...state.selectedLabels]};
-        })
-    },
     addSelectedToggle: (toggle: string) => {
         set(state => ({
             selectedToggles: [...state.selectedToggles, toggle]
diff --git a/karavan-space/src/designer/property/PropertiesHeader.tsx 
b/karavan-space/src/designer/property/PropertiesHeader.tsx
index 30b0034b..b8aca6b4 100644
--- a/karavan-space/src/designer/property/PropertiesHeader.tsx
+++ b/karavan-space/src/designer/property/PropertiesHeader.tsx
@@ -94,7 +94,7 @@ export function PropertiesHeader(props: Props) {
                             openSelectorToReplaceFrom((selectedStep as any).id)
                             setMenuOpen(false);
                         }}>
-                            Change From Element
+                            Change From...
                         </DropdownItem>}
                     {hasSteps &&
                         <DropdownItem key="saveStepsRoute" onClick={(ev) => {
diff --git a/karavan-space/src/knowledgebase/KnowledgebasePage.tsx 
b/karavan-space/src/knowledgebase/KnowledgebasePage.tsx
index a7c1d514..cb2e7158 100644
--- a/karavan-space/src/knowledgebase/KnowledgebasePage.tsx
+++ b/karavan-space/src/knowledgebase/KnowledgebasePage.tsx
@@ -16,13 +16,30 @@
  */
 import React, {useState} from 'react';
 import '../designer/karavan.css';
-import {Flex, FlexItem, PageSection, Switch, Tab, Tabs, Text, TextContent, 
TextInput, Toolbar, ToolbarContent} from "@patternfly/react-core";
+import {
+    Badge,
+    Flex,
+    FlexItem,
+    PageSection,
+    Switch,
+    Tab,
+    Tabs,
+    Text,
+    TextContent,
+    TextInput,
+    Toolbar,
+    ToolbarContent
+} from "@patternfly/react-core";
 import {MainToolbar} from "../designer/MainToolbar";
 import {KameletsTab} from "./kamelets/KameletsTab";
 import {EipTab} from "./eip/EipTab";
 import {ComponentsTab} from "./components/ComponentsTab";
 import {useKnowledgebaseStore} from "./KnowledgebaseStore";
 import {shallow} from "zustand/shallow";
+import {KameletApi} from "karavan-core/lib/api/KameletApi";
+import {KameletModel} from "karavan-core/lib/model/KameletModels";
+import {ComponentApi} from "karavan-core/lib/api/ComponentApi";
+import {CamelModelMetadata, ElementMeta} from 
"karavan-core/lib/model/CamelMetadata";
 
 interface Props {
     dark: boolean,
@@ -33,7 +50,7 @@ interface Props {
 export const KnowledgebasePage = (props: Props) => {
 
     const [setShowBlockCheckbox] = useKnowledgebaseStore((s) => 
[s.setShowBlockCheckbox], shallow)
-    const [tab, setTab] = useState<string | number>("eip");
+    const [tab, setTab] = useState<string | number>("components");
     const [filter, setFilter] = useState<string>("");
     const [customOnly, setCustomOnly] = useState<boolean>(false);
 
@@ -71,8 +88,21 @@ export const KnowledgebasePage = (props: Props) => {
         </Toolbar>
     }
 
+    let kameletList: KameletModel[] = KameletApi.getKamelets().filter(kamelet 
=>
+            
kamelet.spec.definition.title.toLowerCase().includes(filter.toLowerCase()));
+    if (customOnly) kameletList = kameletList.filter(k => 
KameletApi.getCustomKameletNames().includes(k.metadata.name));
+
+    const components = ComponentApi.getComponents().filter(c => {
+        return c.component.name.toLowerCase().includes(filter.toLowerCase())
+            || c.component.title.toLowerCase().includes(filter.toLowerCase())
+            || 
c.component.description.toLowerCase().includes(filter.toLowerCase())
+    }).sort((a, b) => (a.component.title?.toLowerCase() > 
b.component.title?.toLowerCase() ? 1 : -1)) ;
+
+    const elements= CamelModelMetadata
+        .filter(c => 
c.name.toLowerCase().includes(filter.toLowerCase())).sort((a: ElementMeta, b: 
ElementMeta) => a.name > b.name ? 1 : -1);
+
     return (
-        <PageSection className="kamelet-section" padding={{default: 
'noPadding'}}>
+        <PageSection className="knowledgebase-section" padding={{default: 
'noPadding'}}>
             <PageSection className="tools-section" padding={{default: 
'noPadding'}}>
                 <MainToolbar title={title()} tools={getTools()}/>
             </PageSection>
@@ -80,17 +110,24 @@ export const KnowledgebasePage = (props: Props) => {
                 <Flex direction={{default: "column"}} spaceItems={{default: 
"spaceItemsNone"}}>
                     <FlexItem>
                         <Tabs activeKey={tab} onSelect={(event, tabIndex) => 
setTab(tabIndex)}>
-                            <Tab eventKey="eip" title="Integration Patterns"/>
-                            <Tab eventKey="kamelets" title="Kamelets"/>
-                            <Tab eventKey="components" title="Components"/>
+                            <Tab eventKey="components" title={<div 
style={{display: 'flex', gap:'6px'}}>Components<Badge 
className='label-component'>{components.length}</Badge></div>}/>
+                            <Tab eventKey="eip" title={<div style={{display: 
'flex', gap:'6px'}}>Integration Patterns<Badge 
className='label-eip'>{elements.length}</Badge></div>}/>
+                            <Tab eventKey="kamelets" title={<div 
style={{display: 'flex', gap:'6px'}}>Kamelets<Badge 
className='label-kamelet'>{kameletList.length}</Badge></div>}/>
                         </Tabs>
                     </FlexItem>
                 </Flex>
             </PageSection>
             <>
-                {tab === 'kamelets' && <KameletsTab dark={props.dark} 
filter={filter} customOnly={customOnly} onChange={(name: string, checked: 
boolean) => props.changeBlockList('kamelet', name, checked)}  />}
-                {tab === 'eip' && <EipTab dark={props.dark} filter={filter}/>}
-                {tab === 'components' && <ComponentsTab dark={props.dark} 
filter={filter} onChange={(name: string, checked: boolean) => 
props.changeBlockList('component', name, checked)}  />}
+                {tab === 'kamelets' && <KameletsTab dark={props.dark}
+                                                    kameletList={kameletList}
+                                                    onChange={(name: string, 
checked: boolean) => props.changeBlockList('kamelet', name, checked)} />
+                }
+                {tab === 'eip' && <EipTab dark={props.dark} 
elements={elements}/>
+                }
+                {tab === 'components' && <ComponentsTab dark={props.dark}
+                                                        components={components}
+                                                        onChange={(name: 
string, checked: boolean) => props.changeBlockList('component', name, checked)} 
/>
+                }
             </>
         </PageSection>
     )
diff --git a/karavan-space/src/knowledgebase/components/ComponentCard.tsx 
b/karavan-space/src/knowledgebase/components/ComponentCard.tsx
index c9f39d04..80d298c5 100644
--- a/karavan-space/src/knowledgebase/components/ComponentCard.tsx
+++ b/karavan-space/src/knowledgebase/components/ComponentCard.tsx
@@ -16,7 +16,7 @@
  */
 import React, {useEffect, useState} from 'react';
 import {
-    CardHeader, Card, CardTitle, CardBody, CardFooter, Badge, Checkbox, Flex
+    CardHeader, Card, CardTitle, CardBody, CardFooter, Badge, Checkbox, Flex, 
Text
 } from '@patternfly/react-core';
 import '../../designer/karavan.css';
 import {CamelUi} from "../../designer/utils/CamelUi";
@@ -56,14 +56,15 @@ export function ComponentCard(props: Props) {
 
     const isBlockedComponent = blockedComponents ? 
blockedComponents.findIndex(r => r === component.component.name) > -1 : false;
     const isRemote = component.component.remote;
+    const classNameBadge = 'label-component' + 
(component.component.supportLevel !== 'Stable' ? '-preview' : '')
     return (
-        <Card isCompact key={component.component.name} className="kamelet-card"
+        <Card isCompact key={component.component.name} 
className="knowledgebase-card"
               onClick={event => click(event)}
         >
             <CardHeader className="header-labels">
                 <Flex style={{width: '100%'}} gap={{default: 'gapSm'}} 
justifyContent={{default: 'justifyContentSpaceBetween'}}>
+                    <Badge className={classNameBadge}>Component</Badge>
                     <Badge isRead className="support-level 
labels">{component.component.supportLevel}</Badge>
-                    <Badge isRead className="version 
labels">{component.component.version}</Badge>
                 </Flex>
                 {showBlockCheckbox &&
                     <Checkbox id={component.component.name}
@@ -77,7 +78,9 @@ export function ComponentCard(props: Props) {
                 {CamelUi.getIconForComponent(component.component.title, 
component.component.label)}
                 <CardTitle>{component.component.title}</CardTitle>
             </CardHeader>
-            <CardBody>{component.component.description}</CardBody>
+            <CardBody>
+                <Text 
className="pf-v5-u-color-200">{component.component.description}</Text>
+            </CardBody>
             <CardFooter className="footer-labels">
                 <Badge isRead 
className="labels">{component.component.label}</Badge>
                 <Badge isRead className="labels">{isRemote ? 'remote' : 
'internal'}</Badge>
diff --git a/karavan-space/src/knowledgebase/components/ComponentsTab.tsx 
b/karavan-space/src/knowledgebase/components/ComponentsTab.tsx
index 9e9fb470..c4fdb592 100644
--- a/karavan-space/src/knowledgebase/components/ComponentsTab.tsx
+++ b/karavan-space/src/knowledgebase/components/ComponentsTab.tsx
@@ -22,28 +22,21 @@ import {
 import '../../designer/karavan.css';
 import {ComponentCard} from "./ComponentCard";
 import {ComponentModal} from "./ComponentModal";
-import {ComponentApi} from "karavan-core/lib/api/ComponentApi";
 import {shallow} from "zustand/shallow";
 import {useKnowledgebaseStore} from "../KnowledgebaseStore";
+import { Component } from 'karavan-core/lib/model/ComponentModels';
 
 interface Props {
     dark: boolean,
-    filter: string,
+    components: Component[],
     onChange: (name: string, checked: boolean) => void,
 }
 
 export function ComponentsTab(props: Props) {
 
-    const [isModalOpen] = useKnowledgebaseStore((s) =>
-        [s.isModalOpen], shallow)
+    const [isModalOpen] = useKnowledgebaseStore((s) => [s.isModalOpen], 
shallow)
 
-
-    const {filter} = props;
-    const components = ComponentApi.getComponents().filter(c => {
-        return c.component.name.toLowerCase().includes(filter.toLowerCase())
-            || c.component.title.toLowerCase().includes(filter.toLowerCase())
-            || 
c.component.description.toLowerCase().includes(filter.toLowerCase())
-    }).sort((a, b) => (a.component.title?.toLowerCase() > 
b.component.title?.toLowerCase() ? 1 : -1)) ;
+    const {components} = props;
     return (
         <PageSection variant={props.dark ? PageSectionVariants.darker : 
PageSectionVariants.light} padding={{ default: 'noPadding' }} 
className="kamelet-section">
             {isModalOpen && <ComponentModal/>}
diff --git a/karavan-space/src/knowledgebase/eip/EipCard.tsx 
b/karavan-space/src/knowledgebase/eip/EipCard.tsx
index fb47a932..bac46590 100644
--- a/karavan-space/src/knowledgebase/eip/EipCard.tsx
+++ b/karavan-space/src/knowledgebase/eip/EipCard.tsx
@@ -16,7 +16,7 @@
  */
 import React from 'react';
 import {
-    CardHeader, Card, CardTitle, CardBody, CardFooter,Badge
+    CardHeader, Card, CardTitle, CardBody, CardFooter, Badge, Text
 } from '@patternfly/react-core';
 import '../../designer/karavan.css';
 import {CamelUi} from "../../designer/utils/CamelUi";
@@ -39,18 +39,20 @@ export function EipCard(props: Props) {
         setElement(element)
         setModalOpen(true);
     }
-
     return (
-        <Card  isCompact key={element.name} className="kamelet-card"
+        <Card  isCompact key={element.name} className="knowledgebase-card"
                onClick={event => click(event)}
         >
             <CardHeader>
+                <Badge className='label-eip'>EIP</Badge>
             </CardHeader>
             <CardHeader>
                 {CamelUi.getIconForDslName(element.className)}
                 <CardTitle>{element.title}</CardTitle>
             </CardHeader>
-            <CardBody>{element.description}</CardBody>
+            <CardBody>
+                <Text 
className="pf-v5-u-color-200">{element.description}</Text>
+            </CardBody>
             <CardFooter className="footer-labels">
                 <div>
                     {element.labels.split(',').map((s: string,  i: number) => 
<Badge key={s + i} isRead
diff --git a/karavan-space/src/knowledgebase/eip/EipTab.tsx 
b/karavan-space/src/knowledgebase/eip/EipTab.tsx
index 35cc9741..7720bd29 100644
--- a/karavan-space/src/knowledgebase/eip/EipTab.tsx
+++ b/karavan-space/src/knowledgebase/eip/EipTab.tsx
@@ -17,66 +17,35 @@
 import React from 'react';
 import {
     Gallery,
-    PageSection, PageSectionVariants,ToggleGroup,ToggleGroupItem
+    PageSection, PageSectionVariants
 } from '@patternfly/react-core';
 import '../../designer/karavan.css';
 import {EipCard} from "./EipCard";
 import {EipModal} from "./EipModal";
-import {CamelModelMetadata, ElementMeta} from 
"karavan-core/lib/model/CamelMetadata";
 import {useKnowledgebaseStore} from "../KnowledgebaseStore";
 import {shallow} from "zustand/shallow";
-import { useSelectorStore } from '../../designer/DesignerStore';
+import {ElementMeta} from "karavan-core/lib/model/CamelMetadata";
 
 interface Props {
     dark: boolean,
-    filter: string,
+    elements: ElementMeta[],
 }
 
 export function EipTab(props: Props) {
 
-    const [isModalOpen] = useKnowledgebaseStore((s) =>
-        [s.isModalOpen], shallow)
+    const [isModalOpen] = useKnowledgebaseStore((s) => [s.isModalOpen], 
shallow)
+
+    const { elements } = props;
 
-        const [ selectedLabels, addSelectedLabel, deleteSelectedLabel] =
-        useSelectorStore((s) =>
-            [s.selectedLabels, s.addSelectedLabel, s.deleteSelectedLabel], 
shallow)
-        const { filter } = props;
-        const elements = CamelModelMetadata;
-        const filteredElements=CamelModelMetadata
-        .filter(c => 
c.name.toLowerCase().includes(filter.toLowerCase())).filter((dsl: ElementMeta) 
=> {
-            if (selectedLabels.length === 0) {
-                return true;
-            } else {
-                return dsl.labels.split(",").some(r => 
selectedLabels.includes(r));
-            }
-        })
-        .sort((a: ElementMeta, b: ElementMeta) => a.name > b.name ? 1 : -1);
-     const eipLabels = [...new Set(elements.map(e => 
e.labels).join(",").split(",").filter(e => e !== 'eip'))];
-    function selectLabel(eipLabel: string) {
-            if (!selectedLabels.includes(eipLabel)) {
-                addSelectedLabel(eipLabel);
-            } else {
-                deleteSelectedLabel(eipLabel);
-            }
-        }
     return (
         <PageSection variant={props.dark ? PageSectionVariants.darker : 
PageSectionVariants.light}
             padding={{ default: 'noPadding' }} className="kamelet-section 
knowledbase-eip-section">
-             <ToggleGroup aria-label="Labels" isCompact >
-                    {eipLabels.map(eipLabel => <ToggleGroupItem
-                        key={eipLabel}
-                        text={eipLabel}
-                        buttonId={eipLabel}
-                        isSelected={selectedLabels.includes(eipLabel)}
-                        onChange={selected => selectLabel(eipLabel)}
-                    />)}
-                </ToggleGroup>
 
             {isModalOpen && <EipModal/>}
             <PageSection isFilled className="kamelets-page"
                          variant={props.dark ? PageSectionVariants.darker : 
PageSectionVariants.light}>
                 <Gallery hasGutter>
-                    {filteredElements.map(c => (
+                    {elements.map(c => (
                         <EipCard key={c.name} element={c}/>
                     ))}
                 </Gallery>
diff --git a/karavan-space/src/knowledgebase/kamelets/KameletCard.tsx 
b/karavan-space/src/knowledgebase/kamelets/KameletCard.tsx
index a1a0f903..4fb6e662 100644
--- a/karavan-space/src/knowledgebase/kamelets/KameletCard.tsx
+++ b/karavan-space/src/knowledgebase/kamelets/KameletCard.tsx
@@ -56,14 +56,16 @@ export function KameletCard(props: Props) {
         setBlockedKamelets([...KameletApi.getBlockedKameletNames()]);
     }
     const isblockedKamelet = blockedKamelets ? blockedKamelets.findIndex(r => 
r === kamelet.metadata.name) > -1 : false;
+    const supportLevel = 
kamelet.metadata.annotations["camel.apache.org/kamelet.support.level"];
+    const classNameBadge = 'label-kamelet' + (supportLevel !== 'Stable' ? 
'-preview' : '')
     return (
-        <Card  isCompact key={kamelet.metadata.name} className="kamelet-card"
+        <Card  isCompact key={kamelet.metadata.name} 
className="knowledgebase-card"
                onClick={event => click(event)}
         >
             <CardHeader className="header-labels">
                 <Flex style={{width:'100%'}} gap={{default:'gapSm'}} 
justifyContent={{default: 'justifyContentSpaceBetween'}}>
+                    <Badge className={classNameBadge}>Kamelet</Badge>
                     <Badge isRead className="support-level 
labels">{kamelet.metadata.annotations["camel.apache.org/kamelet.support.level"]}</Badge>
-                    <Badge isRead className="version 
labels">{kamelet.metadata.annotations["camel.apache.org/catalog.version"].toLowerCase()}</Badge>
                 </Flex>
                 {showBlockCheckbox && <Checkbox id={kamelet.metadata.name} 
className="block-checkbox labels" isChecked={!isblockedKamelet}
                                                 onChange={(_, checked) => 
selectKamelet(_, checked)}/>}
diff --git a/karavan-space/src/knowledgebase/kamelets/KameletsTab.tsx 
b/karavan-space/src/knowledgebase/kamelets/KameletsTab.tsx
index 353819e4..83db2eb5 100644
--- a/karavan-space/src/knowledgebase/kamelets/KameletsTab.tsx
+++ b/karavan-space/src/knowledgebase/kamelets/KameletsTab.tsx
@@ -22,27 +22,23 @@ import {
 } from '@patternfly/react-core';
 import '../../designer/karavan.css';
 import {KameletCard} from "./KameletCard";
-import {KameletApi} from "karavan-core/lib/api/KameletApi";
 import {KameletModal} from "./KameletModal";
 import {useKnowledgebaseStore} from "../KnowledgebaseStore";
 import {shallow} from "zustand/shallow";
+import {KameletModel} from "karavan-core/lib/model/KameletModels";
 
 interface Props {
     dark: boolean,
-    filter: string,
-    customOnly: boolean,
+    kameletList: KameletModel[],
     onChange: (name: string, checked: boolean) => void
 }
 
 export function KameletsTab(props: Props) {
 
-    const [isModalOpen] = useKnowledgebaseStore((s) =>
-        [s.isModalOpen], shallow)
+    const [isModalOpen] = useKnowledgebaseStore((s) => [s.isModalOpen], 
shallow)
+
+    const {kameletList, dark} = props;
 
-    const {filter, customOnly, dark} = props;
-    let kameletList = KameletApi.getKamelets().filter(kamelet =>
-        
kamelet.spec.definition.title.toLowerCase().includes(filter.toLowerCase()));
-    if (customOnly) kameletList = kameletList.filter(k => 
KameletApi.getCustomKameletNames().includes(k.metadata.name));
     return (
         <PageSection variant={dark ? PageSectionVariants.darker : 
PageSectionVariants.light}
                      padding={{default: 'noPadding'}} 
className="kamelet-section">
diff --git a/karavan-space/src/knowledgebase/knowledgebase.css 
b/karavan-space/src/knowledgebase/knowledgebase.css
index 6fb889de..b0caf549 100644
--- a/karavan-space/src/knowledgebase/knowledgebase.css
+++ b/karavan-space/src/knowledgebase/knowledgebase.css
@@ -15,7 +15,129 @@
  * limitations under the License.
  */
 
-.kamelets-page .kamelet-card .block-checkbox {
+.karavan .knowledgebase-section {
+    display: flex;
+    flex-direction: column;
+    height: 100%;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card {
+    cursor: pointer;
+    height: 160px;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .pf-v5-c-card__header {
+    padding-top: var(--pf-v5-global--spacer--sm);
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .pf-v5-c-card__header 
.custom {
+    margin-left: auto;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .pf-v5-c-card__header 
.pf-v5-c-card__header-main {
+    display: flex;
+    flex-direction: row;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .pf-v5-c-card__title {
+    font-size: 15px;
+    font-weight: 400;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .pf-v5-c-card__body {
+    overflow: hidden;
+    position: relative;
+    line-height: 1.6em;
+}
+
+.knowledgebase-section .knowledgebase-card .icon {
+    height: 24px;
+    max-width: 24px;
+    margin-top: auto;
+    margin-bottom: auto;
+    margin-right: 5px;
+    border: none;
+    -webkit-user-select: none;
+    -khtml-user-select: none;
+    -moz-user-select: none;
+    -o-user-select: none;
+    user-select: none;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .header-labels {
+    padding: 5px;
+    display: flex;
+    flex-direction: row;
+    justify-content: flex-end;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .header-labels 
.pf-v5-c-card__header-main {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .footer-labels {
+    padding: 5px;
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .version,
+.karavan .knowledgebase-section .knowledgebase-card .support-type,
+.karavan .knowledgebase-section .knowledgebase-card .support-level {
+    white-space: nowrap;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card .labels {
+    opacity: 0.5;
+    font-weight: 200;
+}
+
+.karavan .knowledgebase-section .knowledgebase-card:hover .labels {
+    opacity: 1;
+}
+
+.knowledgebase-section .knowledgebase-card .block-checkbox {
     align-self: center;
     margin-left: 6px;
+}
+
+.knowledgebase-section .knowledgebase-card .pf-v5-c-card__body {
+    padding-bottom: 0;
+    height: 54px;
+}
+
+.knowledgebase-section .knowledgebase-card .pf-v5-c-card__body {
+    padding-bottom: 0;
+    height: 54px;
+}
+
+.knowledgebase-section .knowledgebase-card p {
+    overflow: hidden;
+    display: -webkit-box;
+    -webkit-line-clamp: 2;
+    -webkit-box-orient: vertical;
+    color: var(--pf-v5-global--Color--200);
+}
+
+.knowledgebase-section {
+    .label-eip {
+        --pf-v5-c-badge--BackgroundColor: 
var(--pf-v5-global--palette--orange-200);
+    }
+    .label-component {
+        --pf-v5-c-badge--BackgroundColor: 
var(--pf-v5-global--palette--blue-300);
+    }
+    .label-kamelet {
+        --pf-v5-c-badge--BackgroundColor: 
var(--pf-v5-global--palette--green-300);
+    }
+    .label-component-preview {
+        --pf-v5-c-badge--Color: var(--pf-v5-global--palette--blue-300);
+        --pf-v5-c-badge--BackgroundColor: 
var(--pf-v5-c-badge--m-read--BackgroundColor);
+    }
+    .label-kamelet-preview {
+        --pf-v5-c-badge--Color: var(--pf-v5-global--palette--green-300);
+        --pf-v5-c-badge--BackgroundColor: 
var(--pf-v5-c-badge--m-read--BackgroundColor);
+    }
 }
\ No newline at end of file

Reply via email to