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 2022/08/03 16:12:00 UTC

[camel-karavan] branch main updated: Kubernetes selector improvements (#445)

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 a7091eb  Kubernetes selector improvements (#445)
a7091eb is described below

commit a7091ebfc8a3757e33d72fd6e6d25209f33c29f0
Author: Marat Gubaidullin <ma...@gmail.com>
AuthorDate: Wed Aug 3 12:11:55 2022 -0400

    Kubernetes selector improvements (#445)
---
 .../route/property/ComponentParameterField.tsx     | 58 ++++++++++++++++++++--
 .../designer/route/property/DslPropertyField.tsx   | 13 +++++
 .../route/property/KameletPropertyField.tsx        | 12 +++++
 .../designer/route/property/KubernetesSelector.tsx | 14 +++---
 4 files changed, 87 insertions(+), 10 deletions(-)

diff --git a/karavan-designer/src/designer/route/property/ComponentParameterField.tsx b/karavan-designer/src/designer/route/property/ComponentParameterField.tsx
index 4116b1b..af2e013 100644
--- a/karavan-designer/src/designer/route/property/ComponentParameterField.tsx
+++ b/karavan-designer/src/designer/route/property/ComponentParameterField.tsx
@@ -34,6 +34,9 @@ import {CamelElement, Integration} from "karavan-core/lib/model/IntegrationDefin
 import {ToDefinition} from "karavan-core/lib/model/CamelDefinition";
 import CompressIcon from "@patternfly/react-icons/dist/js/icons/compress-icon";
 import ExpandIcon from "@patternfly/react-icons/dist/js/icons/expand-icon";
+import {KubernetesSelector} from "./KubernetesSelector";
+import {KubernetesAPI} from "../../utils/KubernetesAPI";
+import KubernetesIcon from "@patternfly/react-icons/dist/js/icons/openshift-icon";
 
 const prefix = "parameters";
 const beanPrefix = "#bean:";
@@ -49,13 +52,18 @@ interface Props {
 interface State {
     selectStatus: Map<string, boolean>
     showEditor: boolean
+    showKubernetesSelector: boolean
+    kubernetesSelectorProperty?: string
+    ref: any
 }
 
 export class ComponentParameterField extends React.Component<Props, State> {
 
     public state: State = {
         selectStatus: new Map<string, boolean>(),
-        showEditor: false
+        showEditor: false,
+        showKubernetesSelector: false,
+        ref: React.createRef(),
     }
 
     parametersChanged = (parameter: string, value: string | number | boolean | any, pathParameter?: boolean, newRoute?: RouteToCreate) => {
@@ -148,18 +156,61 @@ export class ComponentParameterField extends React.Component<Props, State> {
         )
     }
 
+    selectKubernetes = (value: string) => {
+        // check if there is a selection
+        const textVal = this.state.ref.current;
+        const cursorStart = textVal.selectionStart;
+        const cursorEnd = textVal.selectionEnd;
+        if (cursorStart !== cursorEnd){
+            const prevValue = this.props.value;
+            const selectedText = prevValue.substring(cursorStart, cursorEnd)
+            value = prevValue.replace(selectedText, value);
+        }
+        const propertyName = this.state.kubernetesSelectorProperty;
+        if (propertyName) {
+            if (value.startsWith("config") || value.startsWith("secret")) value = "{{" + value + "}}";
+            this.parametersChanged(propertyName, value);
+            this.setState({showKubernetesSelector: false, kubernetesSelectorProperty: undefined})
+        }
+    }
+
+    openKubernetesSelector = (propertyName: string) => {
+        this.setState({kubernetesSelectorProperty: propertyName, showKubernetesSelector: true});
+    }
+
+    closeKubernetesSelector = () => {
+        this.setState({showKubernetesSelector: false})
+    }
+
+    getKubernetesSelectorModal() {
+        return (
+            <KubernetesSelector
+                dark={false}
+                isOpen={this.state.showKubernetesSelector}
+                onClose={() => this.closeKubernetesSelector()}
+                onSelect={this.selectKubernetes}/>)
+    }
+
     getStringInput(property: ComponentProperty, value: any) {
         const showEditor = this.state.showEditor;
+        const inKubernetes = KubernetesAPI.inKubernetes;
         const id = prefix + "-" + property.name;
+        const noKubeSelectorButton = ["uri", "id", "description", "group"].includes(property.name);
         return <InputGroup>
+            {inKubernetes && !showEditor && !noKubeSelectorButton &&
+                <Tooltip position="bottom-end" content="Select from Kubernetes">
+                    <Button variant="control" onClick={e => this.openKubernetesSelector(property.name)}>
+                        <KubernetesIcon/>
+                    </Button>
+                </Tooltip>}
             {(!showEditor || property.secret) &&
-                <TextInput className="text-field" isRequired
+                <TextInput className="text-field" isRequired ref={this.state.ref}
                            type={property.secret ? "password" : "text"}
                            id={id} name={id}
                            value={value !== undefined ? value : property.defaultValue}
                            onChange={e => this.parametersChanged(property.name, e, property.kind === 'path')}/>}
             {showEditor && !property.secret &&
-                <TextArea autoResize={true}
+                <TextArea autoResize={true} ref={this.state.ref}
                           className="text-field" isRequired
                           type="text"
                           id={id} name={id}
@@ -261,6 +312,7 @@ export class ComponentParameterField extends React.Component<Props, State> {
                     && this.getSelect(property, value)}
                 {property.type === 'boolean'
                     && this.getSwitch(property, value)}
+                {this.getKubernetesSelectorModal()}
             </FormGroup>
         )
     }
diff --git a/karavan-designer/src/designer/route/property/DslPropertyField.tsx b/karavan-designer/src/designer/route/property/DslPropertyField.tsx
index ede27fc..cad850e 100644
--- a/karavan-designer/src/designer/route/property/DslPropertyField.tsx
+++ b/karavan-designer/src/designer/route/property/DslPropertyField.tsx
@@ -70,6 +70,7 @@ interface State {
     showEditor: boolean
     showKubernetesSelector: boolean
     kubernetesSelectorProperty?: string
+    ref: any
 }
 
 export class DslPropertyField extends React.Component<Props, State> {
@@ -80,6 +81,7 @@ export class DslPropertyField extends React.Component<Props, State> {
         isShowAdvanced: new Map<string, boolean>(),
         showEditor: false,
         showKubernetesSelector: false,
+        ref: React.createRef(),
     };
 
     openSelect = (propertyName: string, isExpanded: boolean) => {
@@ -151,6 +153,15 @@ export class DslPropertyField extends React.Component<Props, State> {
     }
 
     selectKubernetes = (value: string) => {
+        // check if there is a selection
+        const textVal = this.state.ref.current;
+        const cursorStart = textVal.selectionStart;
+        const cursorEnd = textVal.selectionEnd;
+        if (cursorStart !== cursorEnd){
+            const prevValue = this.props.value;
+            const selectedText = prevValue.substring(cursorStart, cursorEnd)
+            value = prevValue.replace(selectedText, value);
+        }
         const propertyName = this.state.kubernetesSelectorProperty;
         if (propertyName) {
             if (value.startsWith("config") || value.startsWith("secret")) value = "{{" + value + "}}";
@@ -188,6 +199,7 @@ export class DslPropertyField extends React.Component<Props, State> {
                     </Button>
                 </Tooltip>}
             {(!showEditor || property.secret) && <TextInput
+                ref={this.state.ref}
                 className="text-field" isRequired isReadOnly={this.isUriReadOnly(property)}
                 type={['integer', 'number'].includes(property.type) ? 'number' : (property.secret ? "password" : "text")}
                 id={property.name} name={property.name}
@@ -195,6 +207,7 @@ export class DslPropertyField extends React.Component<Props, State> {
                 onChange={e => this.propertyChanged(property.name, ['integer', 'number'].includes(property.type) ? Number(e) : e)}/>
             }
             {showEditor && !property.secret && <TextArea
+                ref={this.state.ref}
                 autoResize={true}
                 className="text-field" isRequired isReadOnly={this.isUriReadOnly(property)}
                 type="text"
diff --git a/karavan-designer/src/designer/route/property/KameletPropertyField.tsx b/karavan-designer/src/designer/route/property/KameletPropertyField.tsx
index 4bee8ce..675ba25 100644
--- a/karavan-designer/src/designer/route/property/KameletPropertyField.tsx
+++ b/karavan-designer/src/designer/route/property/KameletPropertyField.tsx
@@ -45,6 +45,7 @@ interface State {
     showPassword: boolean
     showKubernetesSelector: boolean
     kubernetesSelectorProperty?: string
+    ref: any
 }
 
 export class KameletPropertyField extends React.Component<Props, State> {
@@ -54,6 +55,7 @@ export class KameletPropertyField extends React.Component<Props, State> {
         showEditor: false,
         showPassword: false,
         showKubernetesSelector: false,
+        ref: React.createRef(),
     }
 
     openSelect = () => {
@@ -66,6 +68,15 @@ export class KameletPropertyField extends React.Component<Props, State> {
     }
 
     selectKubernetes = (value: string) => {
+        // check if there is a selection
+        const textVal = this.state.ref.current;
+        const cursorStart = textVal.selectionStart;
+        const cursorEnd = textVal.selectionEnd;
+        if (cursorStart !== cursorEnd){
+            const prevValue = this.props.value;
+            const selectedText = prevValue.substring(cursorStart, cursorEnd)
+            value = prevValue.replace(selectedText, value);
+        }
         const propertyId = this.state.kubernetesSelectorProperty;
         if (propertyId){
             if (value.startsWith("config") || value.startsWith("secret")) value = "{{" + value + "}}";
@@ -109,6 +120,7 @@ export class KameletPropertyField extends React.Component<Props, State> {
                 </Tooltip>}
             {(!showEditor || property.format === "password") &&
                 <TextInput
+                    ref={this.state.ref}
                     className="text-field" isRequired
                     type={property.format && !showPassword ? "password" : "text"}
                     id={id} name={id}
diff --git a/karavan-designer/src/designer/route/property/KubernetesSelector.tsx b/karavan-designer/src/designer/route/property/KubernetesSelector.tsx
index 9791af2..a18b6bd 100644
--- a/karavan-designer/src/designer/route/property/KubernetesSelector.tsx
+++ b/karavan-designer/src/designer/route/property/KubernetesSelector.tsx
@@ -177,15 +177,15 @@ export class KubernetesSelector extends React.Component<Props, State> {
                                     <Td noPadding isActionCell>
                                         <Badge>S</Badge>
                                     </Td>
-                                    <Td noPadding>
-                                        {serviceName}
-                                    </Td>
                                     {/*<Td noPadding>*/}
-                                    {/*    <Button style={{padding: '6px'}} variant={"link"} onClick={*/}
-                                    {/*        e => this.props.onSelect?.call(this, hostPort)}>*/}
-                                    {/*        {hostPort}*/}
-                                    {/*    </Button>*/}
+                                    {/*    {serviceName}*/}
                                     {/*</Td>*/}
+                                    <Td noPadding>
+                                        <Button style={{padding: '6px'}} variant={"link"} onClick={
+                                            e => this.props.onSelect?.call(this, hostPort)}>
+                                            {serviceName}
+                                        </Button>
+                                    </Td>
                                     <Td noPadding>
                                         <Button style={{padding: '6px'}} variant={"link"} onClick={
                                             e => this.props.onSelect?.call(this, host)}>