Fix #991
diff --git a/karavan-core/src/core/api/ComponentApi.ts b/karavan-core/src/core/api/ComponentApi.ts
index 5e4f372..0de142a 100644
--- a/karavan-core/src/core/api/ComponentApi.ts
+++ b/karavan-core/src/core/api/ComponentApi.ts
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { Component, ComponentProperty, SupportedComponent } from '../model/ComponentModels';
+import { Component, ComponentHeader, ComponentProperty, SupportedComponent } from '../model/ComponentModels';
import { CamelElement } from '../model/IntegrationDefinition';
const Components: Component[] = [];
@@ -293,4 +293,33 @@
);
return Array.from(new Map(result.map(item => [item.name, item])).values());
};
+
+
+ static getComponentHeaders = (componentName: string, type: 'consumer' | 'producer'): ComponentHeader[] => {
+ const invertedType = type === 'consumer' ? 'producer' : 'consumer';
+ const component: Component | undefined = ComponentApi.findByName(componentName);
+ const properties: ComponentHeader[] = [];
+ if (component !== undefined && component.headers) {
+ for (const [key, value] of Object.entries(component.headers) as [string, any][]) {
+ const prop = new ComponentHeader();
+ prop.name = key;
+ prop.label = value.label;
+ prop.description = value.description;
+ prop.index = value.index;
+ prop.displayName = value.displayName;
+ prop.group = value.group;
+ prop.deprecated = value.deprecated;
+ prop.secret = value.secret;
+ prop.kind = value.kind;
+ prop.constantName = value.constantName;
+ prop.defaultValue = value.defaultValue;
+ prop.javaType = value.javaType;
+ prop.autowired = value.autowired;
+ if (!value.deprecated) {
+ properties.push(prop);
+ }
+ }
+ }
+ return Array.from(new Map(properties.map(item => [item.name, item])).values());
+ };
}
diff --git a/karavan-core/src/core/model/ComponentModels.ts b/karavan-core/src/core/model/ComponentModels.ts
index 8810a0e..3936ee9 100644
--- a/karavan-core/src/core/model/ComponentModels.ts
+++ b/karavan-core/src/core/model/ComponentModels.ts
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-export class Header {
+export class ComponentTitle {
kind: string = '';
name: string = '';
title: string = '';
@@ -38,14 +38,35 @@
lenientProperties: boolean = false;
componentProperties: any;
- public constructor(init?: Partial<Header>) {
+ public constructor(init?: Partial<ComponentTitle>) {
+ Object.assign(this, init);
+ }
+}
+export class ComponentHeader {
+ name: string = '';
+ index: number = 0;
+ kind: string = '';
+ displayName: string = '';
+ group: string = '';
+ label: boolean = false;
+ javaType: string = '';
+ deprecated: boolean = false;
+ deprecationNote: string = '';
+ defaultValue: string = '';
+ secret: boolean = false;
+ autowired: boolean = false;
+ description: string = '';
+ constantName: string = '';
+
+ public constructor(init?: Partial<ComponentHeader>) {
Object.assign(this, init);
}
}
export class Component {
- component: Header = new Header();
+ component: ComponentTitle = new ComponentTitle();
properties: any;
+ headers: any;
public constructor(init?: Partial<Component>) {
Object.assign(this, init);
diff --git a/karavan-designer/src/knowledgebase/components/ComponentModal.tsx b/karavan-designer/src/knowledgebase/components/ComponentModal.tsx
index da8f158..acffc97 100644
--- a/karavan-designer/src/knowledgebase/components/ComponentModal.tsx
+++ b/karavan-designer/src/knowledgebase/components/ComponentModal.tsx
@@ -14,20 +14,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import React from 'react';
+import React, {useState} from 'react';
import {
Button,
Modal,
ActionGroup,
Text,
CardHeader,
- Badge, Flex, CardTitle,
+ Badge, Flex, CardTitle, Tabs, Tab, TabTitleText,
} from '@patternfly/react-core';
import '../../designer/karavan.css';
import {Table, Tbody, Td, Th, Thead, Tr} from "@patternfly/react-table";
import {CamelUi} from "../../designer/utils/CamelUi";
import {ComponentApi} from "karavan-core/lib/api/ComponentApi";
-import {ComponentProperty} from "karavan-core/lib/model/ComponentModels";
+import {ComponentHeader, ComponentProperty} from "karavan-core/lib/model/ComponentModels";
import {useKnowledgebaseStore} from "../KnowledgebaseStore";
import {shallow} from "zustand/shallow";
@@ -36,15 +36,98 @@
const [component, isModalOpen, setModalOpen] = useKnowledgebaseStore((s) =>
[s.component, s.isModalOpen, s.setModalOpen], shallow)
+ const [tab, setTab] = useState<string | number>('properties');
+
const props = new Map<string, ComponentProperty>();
if (component) {
ComponentApi.getComponentProperties(component?.component.name, "consumer").forEach(cp => props.set(cp.name, cp));
ComponentApi.getComponentProperties(component?.component.name, "producer").forEach(cp => props.set(cp.name, cp));
}
+
+ const headers = new Map<string, ComponentHeader>();
+ if (component) {
+ ComponentApi.getComponentHeaders(component?.component.name, "consumer").forEach(cp => headers.set(cp.name, cp));
+ ComponentApi.getComponentHeaders(component?.component.name, "producer").forEach(cp => headers.set(cp.name, cp));
+ }
+
+
+ function getPropertiesTable() {
+ return (
+ <Table aria-label="Properties table" variant='compact'>
+ <Thead>
+ <Tr>
+ <Th key='name'>Display Name / Name</Th>
+ <Th key='desc'>Description</Th>
+ <Th key='type'>Type</Th>
+ <Th key='label'>Label</Th>
+ </Tr>
+ </Thead>
+ <Tbody>
+ {Array.from(props.values()).map((p: ComponentProperty, idx: number) => (
+ <Tr key={idx}>
+ <Td key={`${idx}_name`}>
+ <div>
+ <b>{p.displayName}</b>
+ <div>{p.name}</div>
+ </div>
+ </Td>
+ <Td key={`${idx}_desc`}>
+ <div>
+ <div>{p.description}</div>
+ {p.defaultValue && p.defaultValue.toString().length > 0 &&
+ <div>{"Default value: " + p.defaultValue}</div>}
+ </div>
+ </Td>
+ <Td key={`${idx}_type`}>{p.type}</Td>
+ <Td key={`${idx}_label`}>{p.label}</Td>
+ </Tr>
+ ))}
+ </Tbody>
+ </Table>
+ )
+ }
+
+ function getHeadersTable() {
+ return (
+ <Table aria-label="Headers table" variant='compact'>
+ <Thead>
+ <Tr>
+ <Th key='name'>Name</Th>
+ <Th key='desc' modifier={"breakWord"}>Description</Th>
+ <Th key='type'>Group</Th>
+ <Th key='label'>Java Type</Th>
+ <Th key='label'>Default Value</Th>
+ <Th key='label'>Autowired</Th>
+ </Tr>
+ </Thead>
+ <Tbody>
+ {Array.from(headers.values()).map((p: ComponentHeader, idx: number) => (
+ <Tr key={idx}>
+ <Td key={`${idx}_name`}>
+ <div>
+ <b>{p.displayName}</b>
+ <div>{p.name}</div>
+ </div>
+ </Td>
+ <Td key={`${idx}_type`}>{p.description}</Td>
+ <Td key={`${idx}_label`}>{p.group}</Td>
+ <Td key={`${idx}_label`}>{p.javaType}</Td>
+ <Td key={`${idx}_label`}>{p.defaultValue}</Td>
+ <Td key={`${idx}_label`}>{p.autowired}</Td>
+ </Tr>
+ ))}
+ </Tbody>
+ </Table>
+ )
+ }
+
+ const showProps = props.size !== 0;
+ const showHeaders = headers.size !== 0;
+
return (
<Modal
aria-label={"Kamelet"}
- width={'fit-content'}
+ width={'80%'}
maxLength={200}
title={component?.component.title}
isOpen={isModalOpen}
@@ -70,42 +153,17 @@
</CardHeader>
<Text className="description">{component?.component.description}</Text>
- {props.size !== 0 &&
- <div>
- <CardTitle>Properties</CardTitle>
- <Table aria-label="Simple table" variant='compact'>
- <Thead>
- <Tr>
- <Th key='name'>Display Name / Name</Th>
- <Th key='desc'>Description</Th>
- <Th key='type'>Type</Th>
- <Th key='label'>Label</Th>
- </Tr>
- </Thead>
- <Tbody>
- {Array.from(props.values()).map((p: ComponentProperty, idx: number) => (
- <Tr key={idx}>
- <Td key={`${idx}_name`}>
- <div>
- <b>{p.displayName}</b>
- <div>{p.name}</div>
- </div>
- </Td>
- <Td key={`${idx}_desc`}>
- <div>
- <div>{p.description}</div>
- {p.defaultValue && p.defaultValue.toString().length > 0 &&
- <div>{"Default value: " + p.defaultValue}</div>}
- </div>
- </Td>
- <Td key={`${idx}_type`}>{p.type}</Td>
- <Td key={`${idx}_label`}>{p.label}</Td>
- </Tr>
- ))}
- </Tbody>
- </Table>
- </div>
- }
+ <Tabs
+ activeKey={tab}
+ onSelect={(event, eventKey) => setTab(eventKey)}
+ aria-label="Tabs in the default example"
+ role="region"
+ >
+ <Tab eventKey={'properties'} title={<TabTitleText>Properties</TabTitleText>}/>
+ <Tab eventKey={'headers'} title={<TabTitleText>Headers</TabTitleText>}/>
+ </Tabs>
+ {tab === 'properties' && showProps && getPropertiesTable()}
+ {tab === 'headers' && showHeaders && getHeadersTable()}
</Flex>
</Modal>
)
diff --git a/karavan-space/src/knowledgebase/components/ComponentModal.tsx b/karavan-space/src/knowledgebase/components/ComponentModal.tsx
index da8f158..acffc97 100644
--- a/karavan-space/src/knowledgebase/components/ComponentModal.tsx
+++ b/karavan-space/src/knowledgebase/components/ComponentModal.tsx
@@ -14,20 +14,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import React from 'react';
+import React, {useState} from 'react';
import {
Button,
Modal,
ActionGroup,
Text,
CardHeader,
- Badge, Flex, CardTitle,
+ Badge, Flex, CardTitle, Tabs, Tab, TabTitleText,
} from '@patternfly/react-core';
import '../../designer/karavan.css';
import {Table, Tbody, Td, Th, Thead, Tr} from "@patternfly/react-table";
import {CamelUi} from "../../designer/utils/CamelUi";
import {ComponentApi} from "karavan-core/lib/api/ComponentApi";
-import {ComponentProperty} from "karavan-core/lib/model/ComponentModels";
+import {ComponentHeader, ComponentProperty} from "karavan-core/lib/model/ComponentModels";
import {useKnowledgebaseStore} from "../KnowledgebaseStore";
import {shallow} from "zustand/shallow";
@@ -36,15 +36,98 @@
const [component, isModalOpen, setModalOpen] = useKnowledgebaseStore((s) =>
[s.component, s.isModalOpen, s.setModalOpen], shallow)
+ const [tab, setTab] = useState<string | number>('properties');
+
const props = new Map<string, ComponentProperty>();
if (component) {
ComponentApi.getComponentProperties(component?.component.name, "consumer").forEach(cp => props.set(cp.name, cp));
ComponentApi.getComponentProperties(component?.component.name, "producer").forEach(cp => props.set(cp.name, cp));
}
+
+ const headers = new Map<string, ComponentHeader>();
+ if (component) {
+ ComponentApi.getComponentHeaders(component?.component.name, "consumer").forEach(cp => headers.set(cp.name, cp));
+ ComponentApi.getComponentHeaders(component?.component.name, "producer").forEach(cp => headers.set(cp.name, cp));
+ }
+
+
+ function getPropertiesTable() {
+ return (
+ <Table aria-label="Properties table" variant='compact'>
+ <Thead>
+ <Tr>
+ <Th key='name'>Display Name / Name</Th>
+ <Th key='desc'>Description</Th>
+ <Th key='type'>Type</Th>
+ <Th key='label'>Label</Th>
+ </Tr>
+ </Thead>
+ <Tbody>
+ {Array.from(props.values()).map((p: ComponentProperty, idx: number) => (
+ <Tr key={idx}>
+ <Td key={`${idx}_name`}>
+ <div>
+ <b>{p.displayName}</b>
+ <div>{p.name}</div>
+ </div>
+ </Td>
+ <Td key={`${idx}_desc`}>
+ <div>
+ <div>{p.description}</div>
+ {p.defaultValue && p.defaultValue.toString().length > 0 &&
+ <div>{"Default value: " + p.defaultValue}</div>}
+ </div>
+ </Td>
+ <Td key={`${idx}_type`}>{p.type}</Td>
+ <Td key={`${idx}_label`}>{p.label}</Td>
+ </Tr>
+ ))}
+ </Tbody>
+ </Table>
+ )
+ }
+
+ function getHeadersTable() {
+ return (
+ <Table aria-label="Headers table" variant='compact'>
+ <Thead>
+ <Tr>
+ <Th key='name'>Name</Th>
+ <Th key='desc' modifier={"breakWord"}>Description</Th>
+ <Th key='type'>Group</Th>
+ <Th key='label'>Java Type</Th>
+ <Th key='label'>Default Value</Th>
+ <Th key='label'>Autowired</Th>
+ </Tr>
+ </Thead>
+ <Tbody>
+ {Array.from(headers.values()).map((p: ComponentHeader, idx: number) => (
+ <Tr key={idx}>
+ <Td key={`${idx}_name`}>
+ <div>
+ <b>{p.displayName}</b>
+ <div>{p.name}</div>
+ </div>
+ </Td>
+ <Td key={`${idx}_type`}>{p.description}</Td>
+ <Td key={`${idx}_label`}>{p.group}</Td>
+ <Td key={`${idx}_label`}>{p.javaType}</Td>
+ <Td key={`${idx}_label`}>{p.defaultValue}</Td>
+ <Td key={`${idx}_label`}>{p.autowired}</Td>
+ </Tr>
+ ))}
+ </Tbody>
+ </Table>
+ )
+ }
+
+ const showProps = props.size !== 0;
+ const showHeaders = headers.size !== 0;
+
return (
<Modal
aria-label={"Kamelet"}
- width={'fit-content'}
+ width={'80%'}
maxLength={200}
title={component?.component.title}
isOpen={isModalOpen}
@@ -70,42 +153,17 @@
</CardHeader>
<Text className="description">{component?.component.description}</Text>
- {props.size !== 0 &&
- <div>
- <CardTitle>Properties</CardTitle>
- <Table aria-label="Simple table" variant='compact'>
- <Thead>
- <Tr>
- <Th key='name'>Display Name / Name</Th>
- <Th key='desc'>Description</Th>
- <Th key='type'>Type</Th>
- <Th key='label'>Label</Th>
- </Tr>
- </Thead>
- <Tbody>
- {Array.from(props.values()).map((p: ComponentProperty, idx: number) => (
- <Tr key={idx}>
- <Td key={`${idx}_name`}>
- <div>
- <b>{p.displayName}</b>
- <div>{p.name}</div>
- </div>
- </Td>
- <Td key={`${idx}_desc`}>
- <div>
- <div>{p.description}</div>
- {p.defaultValue && p.defaultValue.toString().length > 0 &&
- <div>{"Default value: " + p.defaultValue}</div>}
- </div>
- </Td>
- <Td key={`${idx}_type`}>{p.type}</Td>
- <Td key={`${idx}_label`}>{p.label}</Td>
- </Tr>
- ))}
- </Tbody>
- </Table>
- </div>
- }
+ <Tabs
+ activeKey={tab}
+ onSelect={(event, eventKey) => setTab(eventKey)}
+ aria-label="Tabs in the default example"
+ role="region"
+ >
+ <Tab eventKey={'properties'} title={<TabTitleText>Properties</TabTitleText>}/>
+ <Tab eventKey={'headers'} title={<TabTitleText>Headers</TabTitleText>}/>
+ </Tabs>
+ {tab === 'properties' && showProps && getPropertiesTable()}
+ {tab === 'headers' && showHeaders && getHeadersTable()}
</Flex>
</Modal>
)