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> ) }