This is an automated email from the ASF dual-hosted git repository.

marat pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git

commit cb23be36f7c2b5b7b868aefc5075244c6b39df3a
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Fri Feb 2 19:04:49 2024 -0500

    COmponent properties #1098
---
 .../property/property/ComponentPropertyField.tsx   | 10 +--
 .../property/property/DslPropertyField.tsx         |  2 +-
 ...ropdown.css => PropertyPlaceholderDropdown.css} |  0
 ...ropdown.tsx => PropertyPlaceholderDropdown.tsx} | 73 ++++++++++++++++------
 .../property/property/ComponentPropertyField.tsx   |  2 +-
 .../ComponentPropertyPlaceholderDropdown.tsx       | 69 ++++++++++++++------
 .../property/property/ComponentPropertyField.tsx   |  2 +-
 .../ComponentPropertyPlaceholderDropdown.tsx       | 69 ++++++++++++++------
 8 files changed, 163 insertions(+), 64 deletions(-)

diff --git 
a/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx 
b/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx
index 1287c18a..e32a4fb9 100644
--- a/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx
+++ b/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx
@@ -27,7 +27,7 @@ import {
     InputGroupItem,
     TextInputGroup,
     TextVariants,
-    Text,
+    Text
 } from '@patternfly/react-core';
 import {
     Select,
@@ -54,7 +54,7 @@ import {shallow} from "zustand/shallow";
 import {KubernetesIcon} from "../../icons/ComponentIcons";
 import EditorIcon from "@patternfly/react-icons/dist/js/icons/code-icon";
 import {ModalEditor} from "./ModalEditor";
-import {ComponentPropertyPlaceholderDropdown} from 
"./ComponentPropertyPlaceholderDropdown";
+import {PropertyPlaceholderDropdown} from "./PropertyPlaceholderDropdown";
 
 const prefix = "parameters";
 const beanPrefix = "#bean:";
@@ -267,7 +267,7 @@ export function ComponentPropertyField(props: Props) {
                 </Tooltip>
             }
             <InputGroupItem>
-                <ComponentPropertyPlaceholderDropdown property={property} 
value={value}/>
+                <PropertyPlaceholderDropdown property={property} 
value={value}/>
             </InputGroupItem>
         </InputGroup>
     }
@@ -287,7 +287,7 @@ export function ComponentPropertyField(props: Props) {
                         }}/>
                 </InputGroupItem>
                 <InputGroupItem>
-                    <ComponentPropertyPlaceholderDropdown property={property} 
value={value}/>
+                    <PropertyPlaceholderDropdown property={property} 
value={value}/>
                 </InputGroupItem>
             </InputGroup>
         )
@@ -345,7 +345,7 @@ export function ComponentPropertyField(props: Props) {
                     />
                 </InputGroupItem>
                 <InputGroupItem>
-                    <ComponentPropertyPlaceholderDropdown property={property} 
value={value}/>
+                    <PropertyPlaceholderDropdown property={property} 
value={value}/>
                 </InputGroupItem>
             </TextInputGroup>
         )
diff --git 
a/karavan-designer/src/designer/property/property/DslPropertyField.tsx 
b/karavan-designer/src/designer/property/property/DslPropertyField.tsx
index 59066667..e5f4cec0 100644
--- a/karavan-designer/src/designer/property/property/DslPropertyField.tsx
+++ b/karavan-designer/src/designer/property/property/DslPropertyField.tsx
@@ -74,7 +74,7 @@ import {
 import {TemplateApi} from "karavan-core/lib/api/TemplateApi";
 import {KubernetesIcon} from "../../icons/ComponentIcons";
 import {BeanProperties} from "./BeanProperties";
-import {ComponentPropertyPlaceholderDropdown} from 
"./ComponentPropertyPlaceholderDropdown";
+import {PropertyPlaceholderDropdown} from "./PropertyPlaceholderDropdown";
 
 interface Props {
     property: PropertyMeta,
diff --git 
a/karavan-designer/src/designer/property/property/ComponentPropertyPlaceholderDropdown.css
 
b/karavan-designer/src/designer/property/property/PropertyPlaceholderDropdown.css
similarity index 100%
rename from 
karavan-designer/src/designer/property/property/ComponentPropertyPlaceholderDropdown.css
rename to 
karavan-designer/src/designer/property/property/PropertyPlaceholderDropdown.css
diff --git 
a/karavan-designer/src/designer/property/property/ComponentPropertyPlaceholderDropdown.tsx
 
b/karavan-designer/src/designer/property/property/PropertyPlaceholderDropdown.tsx
similarity index 70%
rename from 
karavan-designer/src/designer/property/property/ComponentPropertyPlaceholderDropdown.tsx
rename to 
karavan-designer/src/designer/property/property/PropertyPlaceholderDropdown.tsx
index 136f90fb..85899749 100644
--- 
a/karavan-designer/src/designer/property/property/ComponentPropertyPlaceholderDropdown.tsx
+++ 
b/karavan-designer/src/designer/property/property/PropertyPlaceholderDropdown.tsx
@@ -19,10 +19,19 @@ import {
     Dropdown,
     MenuToggleElement,
     MenuToggle,
-    DropdownList, DropdownItem, Popover, Badge, TextVariants, Text, Flex, 
TextInput, FormGroup, Form, Button, FlexItem
+    DropdownList,
+    DropdownItem,
+    Popover,
+    Flex,
+    TextInput,
+    FormGroup,
+    Form,
+    Button,
+    FlexItem,
+    DropdownGroup, Divider
 } from '@patternfly/react-core';
 import '../../karavan.css';
-import './ComponentPropertyPlaceholderDropdown.css';
+import './PropertyPlaceholderDropdown.css';
 import "@patternfly/patternfly/patternfly.css";
 import {ComponentProperty} from "karavan-core/lib/model/ComponentModels";
 import {RouteToCreate} from "../../utils/CamelUi";
@@ -33,12 +42,19 @@ import EllipsisVIcon from 
"@patternfly/react-icons/dist/esm/icons/ellipsis-v-ico
 import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-icon";
 import {InfrastructureAPI} from "../../utils/InfrastructureAPI";
 
+const SYNTAX_EXAMPLES = [
+    {key: 'property:', value: 'group.property', description: 'Application 
property'},
+    {key: 'env:', value: 'env:ENV_NAME', description: 'OS environment 
variable'},
+    {key: 'sys:', value: 'sys:JvmPropertyName', description: 'JVM system 
property'},
+    {key: 'bean:', value: 'bean:beanName.method', description: 'Bean’s method'}
+]
+
 interface Props {
     property: ComponentProperty,
     value: any
 }
 
-export function ComponentPropertyPlaceholderDropdown(props: Props) {
+export function PropertyPlaceholderDropdown(props: Props) {
 
     const {onParametersChange} = usePropertiesHook();
     const [propertyPlaceholders, setPropertyPlaceholders] = 
useDesignerStore((s) =>
@@ -47,12 +63,21 @@ export function ComponentPropertyPlaceholderDropdown(props: 
Props) {
     const [propValue, setPropValue] = useState<string>('');
     const [isVisible, setIsVisible] = React.useState(false);
 
+    function removeBrackets(val: string) {
+        return val.replace('{{', '').replace('}}', '');
+    }
+
     const {property, value} = props;
     const valueIsPlaceholder: boolean = value && 
value.toString().startsWith('{{') && value.toString().endsWith('}}');
     const placeholderValue = valueIsPlaceholder ? 
value.toString().replace('{{', '').replace('}}', '') : undefined;
-    const showAddButton = valueIsPlaceholder && 
!propertyPlaceholders.includes(placeholderValue);
+    const showAddButton = valueIsPlaceholder
+        && !propertyPlaceholders.includes(placeholderValue)
+        && !SYNTAX_EXAMPLES.map(se=> 
se.value).includes(removeBrackets(placeholderValue))
+        && SYNTAX_EXAMPLES.findIndex(se=> 
removeBrackets(placeholderValue).startsWith(se.key)) === -1;
     const popoverId = "popover-selector-" + property.name;
 
+    const hasPlaceholders = (propertyPlaceholders && 
propertyPlaceholders.length > 0 );
+
     function parametersChanged(parameter: string, value: string | number | 
boolean | any, pathParameter?: boolean, newRoute?: RouteToCreate) {
         onParametersChange(parameter, value, pathParameter, newRoute);
     }
@@ -122,24 +147,32 @@ export function 
ComponentPropertyPlaceholderDropdown(props: Props) {
     }
 
     return (
-        (propertyPlaceholders && propertyPlaceholders.length > 0 ) || 
showAddButton ?
-            <Dropdown
-                popperProps={{position: "end"}}
-                isOpen={isOpenPlaceholdersDropdown}
-                onSelect={(_, value) => {
-                    parametersChanged(property.name, `{{${value}}}`, 
property.kind === 'path')
-                    setOpenPlaceholdersDropdown(false);
-                }}
-                onOpenChange={(isOpen: boolean) => 
setOpenPlaceholdersDropdown(isOpen)}
-                toggle={(toggleRef: React.Ref<MenuToggleElement>) => 
getToggle(toggleRef)}
-                shouldFocusToggleOnSelect
-            >
-                <DropdownList>
+        <Dropdown
+            popperProps={{position: "end"}}
+            isOpen={isOpenPlaceholdersDropdown}
+            onSelect={(_, value) => {
+                parametersChanged(property.name, `{{${value}}}`, property.kind 
=== 'path')
+                setOpenPlaceholdersDropdown(false);
+            }}
+            onOpenChange={(isOpen: boolean) => 
setOpenPlaceholdersDropdown(isOpen)}
+            toggle={(toggleRef: React.Ref<MenuToggleElement>) => 
getToggle(toggleRef)}
+            shouldFocusToggleOnSelect
+        >
+            <DropdownList>
+                {hasPlaceholders && <DropdownGroup label="Application 
Properties">
                     {propertyPlaceholders.map((pp, index) =>
                         <DropdownItem value={pp} 
key={index}>{pp}</DropdownItem>
                     )}
-                </DropdownList>
-            </Dropdown>
-            : <></>
+                </DropdownGroup>}
+                {hasPlaceholders && <Divider component="li"/>}
+                <DropdownGroup label="Syntax examples">
+                    {SYNTAX_EXAMPLES.map(se =>
+                        <DropdownItem value={se.value} key={se.key} 
description={se.description}>
+                            {se.value}
+                        </DropdownItem>)
+                    }
+                </DropdownGroup>
+            </DropdownList>
+        </Dropdown>
     )
 }
diff --git 
a/karavan-space/src/designer/property/property/ComponentPropertyField.tsx 
b/karavan-space/src/designer/property/property/ComponentPropertyField.tsx
index 1287c18a..72c145e0 100644
--- a/karavan-space/src/designer/property/property/ComponentPropertyField.tsx
+++ b/karavan-space/src/designer/property/property/ComponentPropertyField.tsx
@@ -27,7 +27,7 @@ import {
     InputGroupItem,
     TextInputGroup,
     TextVariants,
-    Text,
+    Text
 } from '@patternfly/react-core';
 import {
     Select,
diff --git 
a/karavan-space/src/designer/property/property/ComponentPropertyPlaceholderDropdown.tsx
 
b/karavan-space/src/designer/property/property/ComponentPropertyPlaceholderDropdown.tsx
index 136f90fb..f287c300 100644
--- 
a/karavan-space/src/designer/property/property/ComponentPropertyPlaceholderDropdown.tsx
+++ 
b/karavan-space/src/designer/property/property/ComponentPropertyPlaceholderDropdown.tsx
@@ -19,7 +19,16 @@ import {
     Dropdown,
     MenuToggleElement,
     MenuToggle,
-    DropdownList, DropdownItem, Popover, Badge, TextVariants, Text, Flex, 
TextInput, FormGroup, Form, Button, FlexItem
+    DropdownList,
+    DropdownItem,
+    Popover,
+    Flex,
+    TextInput,
+    FormGroup,
+    Form,
+    Button,
+    FlexItem,
+    DropdownGroup, Divider
 } from '@patternfly/react-core';
 import '../../karavan.css';
 import './ComponentPropertyPlaceholderDropdown.css';
@@ -33,6 +42,13 @@ import EllipsisVIcon from 
"@patternfly/react-icons/dist/esm/icons/ellipsis-v-ico
 import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-icon";
 import {InfrastructureAPI} from "../../utils/InfrastructureAPI";
 
+const SYNTAX_EXAMPLES = [
+    {key: 'property:', value: 'group.property', description: 'Application 
property'},
+    {key: 'env:', value: 'env:ENV_NAME', description: 'OS environment 
variable'},
+    {key: 'sys:', value: 'sys:JvmPropertyName', description: 'JVM system 
property'},
+    {key: 'bean:', value: 'bean:beanName.method', description: 'Bean’s method'}
+]
+
 interface Props {
     property: ComponentProperty,
     value: any
@@ -47,12 +63,21 @@ export function ComponentPropertyPlaceholderDropdown(props: 
Props) {
     const [propValue, setPropValue] = useState<string>('');
     const [isVisible, setIsVisible] = React.useState(false);
 
+    function removeBrackets(val: string) {
+        return val.replace('{{', '').replace('}}', '');
+    }
+
     const {property, value} = props;
     const valueIsPlaceholder: boolean = value && 
value.toString().startsWith('{{') && value.toString().endsWith('}}');
     const placeholderValue = valueIsPlaceholder ? 
value.toString().replace('{{', '').replace('}}', '') : undefined;
-    const showAddButton = valueIsPlaceholder && 
!propertyPlaceholders.includes(placeholderValue);
+    const showAddButton = valueIsPlaceholder
+        && !propertyPlaceholders.includes(placeholderValue)
+        && !SYNTAX_EXAMPLES.map(se=> 
se.value).includes(removeBrackets(placeholderValue))
+        && SYNTAX_EXAMPLES.findIndex(se=> 
removeBrackets(placeholderValue).startsWith(se.key)) === -1;
     const popoverId = "popover-selector-" + property.name;
 
+    const hasPlaceholders = (propertyPlaceholders && 
propertyPlaceholders.length > 0 );
+
     function parametersChanged(parameter: string, value: string | number | 
boolean | any, pathParameter?: boolean, newRoute?: RouteToCreate) {
         onParametersChange(parameter, value, pathParameter, newRoute);
     }
@@ -122,24 +147,32 @@ export function 
ComponentPropertyPlaceholderDropdown(props: Props) {
     }
 
     return (
-        (propertyPlaceholders && propertyPlaceholders.length > 0 ) || 
showAddButton ?
-            <Dropdown
-                popperProps={{position: "end"}}
-                isOpen={isOpenPlaceholdersDropdown}
-                onSelect={(_, value) => {
-                    parametersChanged(property.name, `{{${value}}}`, 
property.kind === 'path')
-                    setOpenPlaceholdersDropdown(false);
-                }}
-                onOpenChange={(isOpen: boolean) => 
setOpenPlaceholdersDropdown(isOpen)}
-                toggle={(toggleRef: React.Ref<MenuToggleElement>) => 
getToggle(toggleRef)}
-                shouldFocusToggleOnSelect
-            >
-                <DropdownList>
+        <Dropdown
+            popperProps={{position: "end"}}
+            isOpen={isOpenPlaceholdersDropdown}
+            onSelect={(_, value) => {
+                parametersChanged(property.name, `{{${value}}}`, property.kind 
=== 'path')
+                setOpenPlaceholdersDropdown(false);
+            }}
+            onOpenChange={(isOpen: boolean) => 
setOpenPlaceholdersDropdown(isOpen)}
+            toggle={(toggleRef: React.Ref<MenuToggleElement>) => 
getToggle(toggleRef)}
+            shouldFocusToggleOnSelect
+        >
+            <DropdownList>
+                {hasPlaceholders && <DropdownGroup label="Application 
Properties">
                     {propertyPlaceholders.map((pp, index) =>
                         <DropdownItem value={pp} 
key={index}>{pp}</DropdownItem>
                     )}
-                </DropdownList>
-            </Dropdown>
-            : <></>
+                </DropdownGroup>}
+                {hasPlaceholders && <Divider component="li"/>}
+                <DropdownGroup label="Syntax examples">
+                    {SYNTAX_EXAMPLES.map(se =>
+                        <DropdownItem value={se.value} key={se.key} 
description={se.description}>
+                            {se.value}
+                        </DropdownItem>)
+                    }
+                </DropdownGroup>
+            </DropdownList>
+        </Dropdown>
     )
 }
diff --git 
a/karavan-web/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyField.tsx
 
b/karavan-web/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyField.tsx
index 1287c18a..72c145e0 100644
--- 
a/karavan-web/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyField.tsx
+++ 
b/karavan-web/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyField.tsx
@@ -27,7 +27,7 @@ import {
     InputGroupItem,
     TextInputGroup,
     TextVariants,
-    Text,
+    Text
 } from '@patternfly/react-core';
 import {
     Select,
diff --git 
a/karavan-web/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyPlaceholderDropdown.tsx
 
b/karavan-web/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyPlaceholderDropdown.tsx
index 136f90fb..f287c300 100644
--- 
a/karavan-web/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyPlaceholderDropdown.tsx
+++ 
b/karavan-web/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyPlaceholderDropdown.tsx
@@ -19,7 +19,16 @@ import {
     Dropdown,
     MenuToggleElement,
     MenuToggle,
-    DropdownList, DropdownItem, Popover, Badge, TextVariants, Text, Flex, 
TextInput, FormGroup, Form, Button, FlexItem
+    DropdownList,
+    DropdownItem,
+    Popover,
+    Flex,
+    TextInput,
+    FormGroup,
+    Form,
+    Button,
+    FlexItem,
+    DropdownGroup, Divider
 } from '@patternfly/react-core';
 import '../../karavan.css';
 import './ComponentPropertyPlaceholderDropdown.css';
@@ -33,6 +42,13 @@ import EllipsisVIcon from 
"@patternfly/react-icons/dist/esm/icons/ellipsis-v-ico
 import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-icon";
 import {InfrastructureAPI} from "../../utils/InfrastructureAPI";
 
+const SYNTAX_EXAMPLES = [
+    {key: 'property:', value: 'group.property', description: 'Application 
property'},
+    {key: 'env:', value: 'env:ENV_NAME', description: 'OS environment 
variable'},
+    {key: 'sys:', value: 'sys:JvmPropertyName', description: 'JVM system 
property'},
+    {key: 'bean:', value: 'bean:beanName.method', description: 'Bean’s method'}
+]
+
 interface Props {
     property: ComponentProperty,
     value: any
@@ -47,12 +63,21 @@ export function ComponentPropertyPlaceholderDropdown(props: 
Props) {
     const [propValue, setPropValue] = useState<string>('');
     const [isVisible, setIsVisible] = React.useState(false);
 
+    function removeBrackets(val: string) {
+        return val.replace('{{', '').replace('}}', '');
+    }
+
     const {property, value} = props;
     const valueIsPlaceholder: boolean = value && 
value.toString().startsWith('{{') && value.toString().endsWith('}}');
     const placeholderValue = valueIsPlaceholder ? 
value.toString().replace('{{', '').replace('}}', '') : undefined;
-    const showAddButton = valueIsPlaceholder && 
!propertyPlaceholders.includes(placeholderValue);
+    const showAddButton = valueIsPlaceholder
+        && !propertyPlaceholders.includes(placeholderValue)
+        && !SYNTAX_EXAMPLES.map(se=> 
se.value).includes(removeBrackets(placeholderValue))
+        && SYNTAX_EXAMPLES.findIndex(se=> 
removeBrackets(placeholderValue).startsWith(se.key)) === -1;
     const popoverId = "popover-selector-" + property.name;
 
+    const hasPlaceholders = (propertyPlaceholders && 
propertyPlaceholders.length > 0 );
+
     function parametersChanged(parameter: string, value: string | number | 
boolean | any, pathParameter?: boolean, newRoute?: RouteToCreate) {
         onParametersChange(parameter, value, pathParameter, newRoute);
     }
@@ -122,24 +147,32 @@ export function 
ComponentPropertyPlaceholderDropdown(props: Props) {
     }
 
     return (
-        (propertyPlaceholders && propertyPlaceholders.length > 0 ) || 
showAddButton ?
-            <Dropdown
-                popperProps={{position: "end"}}
-                isOpen={isOpenPlaceholdersDropdown}
-                onSelect={(_, value) => {
-                    parametersChanged(property.name, `{{${value}}}`, 
property.kind === 'path')
-                    setOpenPlaceholdersDropdown(false);
-                }}
-                onOpenChange={(isOpen: boolean) => 
setOpenPlaceholdersDropdown(isOpen)}
-                toggle={(toggleRef: React.Ref<MenuToggleElement>) => 
getToggle(toggleRef)}
-                shouldFocusToggleOnSelect
-            >
-                <DropdownList>
+        <Dropdown
+            popperProps={{position: "end"}}
+            isOpen={isOpenPlaceholdersDropdown}
+            onSelect={(_, value) => {
+                parametersChanged(property.name, `{{${value}}}`, property.kind 
=== 'path')
+                setOpenPlaceholdersDropdown(false);
+            }}
+            onOpenChange={(isOpen: boolean) => 
setOpenPlaceholdersDropdown(isOpen)}
+            toggle={(toggleRef: React.Ref<MenuToggleElement>) => 
getToggle(toggleRef)}
+            shouldFocusToggleOnSelect
+        >
+            <DropdownList>
+                {hasPlaceholders && <DropdownGroup label="Application 
Properties">
                     {propertyPlaceholders.map((pp, index) =>
                         <DropdownItem value={pp} 
key={index}>{pp}</DropdownItem>
                     )}
-                </DropdownList>
-            </Dropdown>
-            : <></>
+                </DropdownGroup>}
+                {hasPlaceholders && <Divider component="li"/>}
+                <DropdownGroup label="Syntax examples">
+                    {SYNTAX_EXAMPLES.map(se =>
+                        <DropdownItem value={se.value} key={se.key} 
description={se.description}>
+                            {se.value}
+                        </DropdownItem>)
+                    }
+                </DropdownGroup>
+            </DropdownList>
+        </Dropdown>
     )
 }

Reply via email to