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 63e20dc0d688946921947a6b1fee1ae1ac264aaa
Author: Marat Gubaidullin <[email protected]>
AuthorDate: Thu Sep 12 10:57:29 2024 -0400

    Fixed #1402
---
 .../webui/src/designer/property/DslProperties.tsx  | 70 ++++++++++++++++++--
 .../property/property/ComponentPropertyField.tsx   |  8 +--
 .../property/property/DslPropertyField.tsx         | 74 +++++++++++++++++-----
 .../property/property/KameletPropertyField.tsx     |  1 -
 karavan-designer/public/example/demo.camel.yaml    |  3 +
 .../src/designer/property/DslProperties.tsx        | 70 ++++++++++++++++++--
 .../src/designer/property/PropertyStore.ts         | 42 ++++++++++++
 .../property/property/ComponentPropertyField.tsx   |  8 +--
 .../property/property/DslPropertyField.tsx         | 74 +++++++++++++++++-----
 .../designer/property/property/PropertyUtil.tsx    | 40 ++++++++++++
 .../src/designer/property/DslProperties.tsx        | 70 ++++++++++++++++++--
 .../property/property/ComponentPropertyField.tsx   |  8 +--
 .../property/property/DslPropertyField.tsx         | 74 +++++++++++++++++-----
 .../property/property/KameletPropertyField.tsx     |  1 -
 14 files changed, 451 insertions(+), 92 deletions(-)

diff --git a/karavan-app/src/main/webui/src/designer/property/DslProperties.tsx 
b/karavan-app/src/main/webui/src/designer/property/DslProperties.tsx
index 993f825f..afd0eb76 100644
--- a/karavan-app/src/main/webui/src/designer/property/DslProperties.tsx
+++ b/karavan-app/src/main/webui/src/designer/property/DslProperties.tsx
@@ -22,7 +22,7 @@ import {
     TextVariants,
     ExpandableSection,
     Button,
-    Tooltip,
+    Tooltip, ToggleGroupItem, ToggleGroup, TextInput,
 } from '@patternfly/react-core';
 import '../karavan.css';
 import './DslProperties.css';
@@ -39,6 +39,8 @@ import {shallow} from "zustand/shallow";
 import {usePropertiesHook} from "./usePropertiesHook";
 import {CamelDisplayUtil} from "karavan-core/lib/api/CamelDisplayUtil";
 import {PropertiesHeader} from "./PropertiesHeader";
+import {PropertyUtil} from "./property/PropertyUtil";
+import {usePropertiesStore} from "./PropertyStore";
 
 interface Props {
     designerType: 'routes' | 'rest' | 'beans'
@@ -60,6 +62,9 @@ export function DslProperties(props: Props) {
     const [selectedStep, dark]
         = useDesignerStore((s) => [s.selectedStep, s.dark], shallow)
 
+    const [propertyFilter, changedOnly, requiredOnly, setChangedOnly, 
setPropertyFilter, setRequiredOnly]
+        = usePropertiesStore((s) => [s.propertyFilter, s.changedOnly, 
s.requiredOnly, s.setChangedOnly, s.setPropertyFilter, s.setRequiredOnly], 
shallow)
+
     const [showAdvanced, setShowAdvanced] = useState<boolean>(false);
 
     function getClonableElementHeader(): React.JSX.Element {
@@ -89,7 +94,7 @@ export function DslProperties(props: Props) {
         const dslName = selectedStep?.dslName;
         return CamelDefinitionApiExt.getElementProperties(dslName)
             .filter((p: PropertyMeta) => !(p.name === 'uri' && dslName !== 
'ToDynamicDefinition')) // show uri only to Dynamic To
-            // .filter((p: PropertyMeta) => (showAdvanced && 
p.label.includes('advanced')) || (!showAdvanced && 
!p.label.includes('advanced')))
+            // .filer((p: PropertyMeta) => (showAdvanced && 
p.label.includes('advanced')) || (!showAdvanced && 
!p.label.includes('advanced')))
             .filter((p: PropertyMeta) => !p.isObject || (p.isObject && 
!CamelUi.dslHasSteps(p.type)) || (dslName === 'CatchDefinition' && p.name === 
'onWhen'))
             .filter((p: PropertyMeta) => !(dslName === 'RestDefinition' && 
['get', 'post', 'put', 'patch', 'delete', 'head'].includes(p.name)));
         // .filter((p: PropertyMeta) => dslName && !(['RestDefinition', 
'GetDefinition', 'PostDefinition', 'PutDefinition', 'PatchDefinition', 
'DeleteDefinition', 'HeadDefinition'].includes(dslName) && ['param', 
'responseMessage'].includes(p.name))) // TODO: configure this properties
@@ -101,7 +106,7 @@ export function DslProperties(props: Props) {
                 <DslPropertyField key={property.name}
                                   property={property}
                                   element={selectedStep}
-                                  value={selectedStep ? (selectedStep as 
any)[property.name] : undefined}
+                                  value={getPropertyValue(property)}
                                   onExpressionChange={onExpressionChange}
                                   onParameterChange={onParametersChange}
                                   onDataFormatChange={onDataFormatChange}
@@ -111,26 +116,77 @@ export function DslProperties(props: Props) {
         </>)
     }
 
+    function getPropertyValue(property: PropertyMeta) {
+        return selectedStep ? (selectedStep as any)[property.name] : undefined;
+    }
+
+    function getFilteredProperties(): PropertyMeta[] {
+        let props = !dataFormatElement ? getProperties() : 
getProperties().filter(p => !dataFormats.includes(p.name));
+        const filter = propertyFilter.toLocaleLowerCase()
+        props = props.filter(p => p.name === 'parameters' || 
p.name.toLocaleLowerCase().includes(filter) || 
p.label.toLocaleLowerCase().includes(filter) || 
p.displayName.toLocaleLowerCase().includes(filter));
+        if (requiredOnly) {
+            props = props.filter(p => p.name === 'parameters' || p.required);
+        }
+        if (changedOnly) {
+            props = props.filter(p =>p.name === 'parameters' || 
PropertyUtil.hasDslPropertyValueChanged(p, getPropertyValue(p)));
+        }
+        return props
+    }
+
     const dataFormats = DataFormats.map(value => value[0]);
     const dataFormatElement = selectedStep !== undefined && 
['MarshalDefinition', 'UnmarshalDefinition'].includes(selectedStep.dslName);
-    const properties = !dataFormatElement
-        ? getProperties()
-        : getProperties().filter(p => !dataFormats.includes(p.name));
+    const properties = getFilteredProperties();
     const propertiesMain = properties.filter(p => 
!p.label.includes("advanced"));
     const propertiesAdvanced = properties.filter(p => 
p.label.includes("advanced"));
+
+    function getPropertySelector() {
+        return (
+            <div style={{display: 'flex', flexDirection: 'row', alignItems: 
'center', gap: '3px'}}>
+                <ToggleGroup aria-label="properties selctor">
+                    <ToggleGroupItem
+                        text="Required"
+                        buttonId="requiredOnly"
+                        isSelected={requiredOnly}
+                        onChange={(_, selected) => setRequiredOnly(selected)}
+                    />
+                    <ToggleGroupItem
+                        text="Changed"
+                        buttonId="changedOnly"
+                        isSelected={changedOnly}
+                        onChange={(_, selected) => setChangedOnly(selected)}
+                    />
+                </ToggleGroup>
+                <TextInput
+                    placeholder="filter by name"
+                    value={propertyFilter}
+                    onChange={(_, value) => setPropertyFilter(value)}
+                />
+            </div>
+        )
+    }
+
+    function getPropertySelectorChanged(): boolean {
+        return requiredOnly || changedOnly || propertyFilter?.trim().length > 
0;
+    }
+
+    function getShowExpanded(): boolean {
+        return showAdvanced || getPropertySelectorChanged();
+    }
+
     return (
         <div key={selectedStep ? selectedStep.uuid : 'integration'}
              className='properties'>
             <Form autoComplete="off" onSubmit={event => 
event.preventDefault()}>
                 {selectedStep === undefined && <IntegrationHeader/>}
                 {selectedStep && getComponentHeader()}
+                {selectedStep !== undefined && getPropertySelector()}
                 {getPropertyFields(propertiesMain)}
                 {selectedStep && !['MarshalDefinition', 
'UnmarshalDefinition'].includes(selectedStep.dslName)
                     && propertiesAdvanced.length > 0 &&
                     <ExpandableSection
                         toggleText={'EIP advanced properties'}
                         onToggle={(_event, isExpanded) => 
setShowAdvanced(!showAdvanced)}
-                        isExpanded={showAdvanced}>
+                        isExpanded={getShowExpanded()}>
                         <div className="parameters">
                             {getPropertyFields(propertiesAdvanced)}
                         </div>
diff --git 
a/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyField.tsx
 
b/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyField.tsx
index 7669a114..262e2eb5 100644
--- 
a/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyField.tsx
+++ 
b/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyField.tsx
@@ -56,6 +56,7 @@ import EditorIcon from 
"@patternfly/react-icons/dist/js/icons/code-icon";
 import {ExpressionModalEditor} from 
"../../../expression/ExpressionModalEditor";
 import {PropertyPlaceholderDropdown} from "./PropertyPlaceholderDropdown";
 import {INTERNAL_COMPONENTS} from "karavan-core/lib/api/ComponentApi";
+import {PropertyUtil} from "./PropertyUtil";
 
 const prefix = "parameters";
 const beanPrefix = "#bean:";
@@ -414,14 +415,9 @@ export function ComponentPropertyField(props: Props) {
         )
     }
 
-    function hasValueChanged(property: ComponentProperty, value: any): boolean 
{
-        const isSet = value !== undefined;
-        const isDefault = property.defaultValue !== undefined && 
value?.toString() === property.defaultValue?.toString();
-        return isSet && !isDefault;
-    }
 
     function getLabel(property: ComponentProperty, value: any) {
-        const bgColor = hasValueChanged(property, value) ? 'yellow' : 
'transparent';
+        const bgColor = 
PropertyUtil.hasComponentPropertyValueChanged(property, value) ? 'yellow' : 
'transparent';
         return (
             <div style={{display: "flex", flexDirection: 'row', alignItems: 
'center', gap: '3px'}}>
                 <Text style={{backgroundColor: 
bgColor}}>{property.displayName}</Text>
diff --git 
a/karavan-app/src/main/webui/src/designer/property/property/DslPropertyField.tsx
 
b/karavan-app/src/main/webui/src/designer/property/property/DslPropertyField.tsx
index b35ca3be..09f259f6 100644
--- 
a/karavan-app/src/main/webui/src/designer/property/property/DslPropertyField.tsx
+++ 
b/karavan-app/src/main/webui/src/designer/property/property/DslPropertyField.tsx
@@ -80,6 +80,9 @@ import {VariablesDropdown} from "./VariablesDropdown";
 import {ROUTE, GLOBAL} from "karavan-core/lib/api/VariableUtil";
 import {SpiBeanApi} from "karavan-core/lib/api/SpiBeanApi";
 import {SelectField} from "./SelectField";
+import {PropertyUtil} from "./PropertyUtil";
+import {usePropertiesStore} from "../PropertyStore";
+import {Property} from "karavan-core/lib/model/KameletModels";
 
 const beanPrefix = "#bean:";
 const classPrefix = "#class:";
@@ -100,6 +103,7 @@ export function DslPropertyField(props: Props) {
 
     const [integration, setIntegration, addVariable, files] = 
useIntegrationStore((s) => [s.integration, s.setIntegration, s.addVariable, 
s.files], shallow)
     const [dark, setSelectedStep, beans] = useDesignerStore((s) => [s.dark, 
s.setSelectedStep, s.beans], shallow)
+    const [propertyFilter, changedOnly, requiredOnly] = usePropertiesStore((s) 
=> [s.propertyFilter, s.changedOnly, s.requiredOnly], shallow)
 
     const [isShowAdvanced, setIsShowAdvanced] = useState<string[]>([]);
     const [arrayValues, setArrayValues] = useState<Map<string, string>>(new 
Map<string, string>());
@@ -204,14 +208,8 @@ export function DslPropertyField(props: Props) {
         return property.name === 'parameters' && property.description === 
'parameters';
     }
 
-    function hasValueChanged(property: PropertyMeta, value: any): boolean {
-        const isSet = value !== undefined && !['id', 
'uri'].includes(property.name);
-        const isDefault = property.defaultValue !== undefined && 
value?.toString() === property.defaultValue?.toString();
-        return isSet && !isDefault;
-    }
-
     function getLabel(property: PropertyMeta, value: any, isKamelet: boolean) {
-        const bgColor = hasValueChanged(property, value) ? 'yellow' : 
'transparent';
+        const bgColor = PropertyUtil.hasDslPropertyValueChanged(property, 
value) ? 'yellow' : 'transparent';
         if (!isMultiValueField(property) && property.isObject && 
!property.isArray && !["ExpressionDefinition"].includes(property.type)) {
             const tooltip = value ? "Delete " + property.name : "Add " + 
property.name;
             const className = value ? "change-button delete-button" : 
"change-button add-button";
@@ -906,32 +904,55 @@ export function DslPropertyField(props: Props) {
         )
     }
 
+    function getKameletPropertyValue(property: Property) {
+        const element = props.element;
+        return CamelDefinitionApiExt.getParametersValue(element, property.id)
+    }
+
+    function getFilteredKameletProperties(): Property[] {
+        const element = props.element;
+        const requiredParameters = 
CamelUtil.getKameletRequiredParameters(element);
+        let properties = CamelUtil.getKameletProperties(element)
+        const filter = propertyFilter.toLocaleLowerCase()
+        properties = properties.filter(p => 
p.title?.toLocaleLowerCase().includes(filter) || 
p.id?.toLocaleLowerCase().includes(filter));
+        if (requiredOnly) {
+            properties = properties.filter(p => 
requiredParameters.includes(p.id));
+        }
+        if (changedOnly) {
+            properties = properties.filter(p => 
PropertyUtil.hasKameletPropertyValueChanged(p, getKameletPropertyValue(p)));
+        }
+        return properties;
+    }
+
     function getKameletParameters() {
         const element = props.element;
         const requiredParameters = 
CamelUtil.getKameletRequiredParameters(element);
         return (
             <div className="parameters">
-                {CamelUtil.getKameletProperties(element).map(property =>
+                {getFilteredKameletProperties().map(property =>
                     <KameletPropertyField
                         key={property.id}
                         property={property}
-                        
value={CamelDefinitionApiExt.getParametersValue(element, property.id)}
+                        value={getKameletPropertyValue(property)}
                         required={requiredParameters?.includes(property.id)}
                     />)}
             </div>
         )
     }
 
-    function getMainComponentParameters(properties: ComponentProperty[]) {
+    function getComponentPropertyValue(kp: ComponentProperty) {
         const element = props.element;
+        return CamelDefinitionApiExt.getParametersValue(element, kp.name, 
kp.kind === 'path');
+    }
+
+    function getMainComponentParameters(properties: ComponentProperty[]) {
         return (
             <div className="parameters">
                 {properties.map(kp => {
-                    const value = 
CamelDefinitionApiExt.getParametersValue(element, kp.name, kp.kind === 'path');
                     return (<ComponentPropertyField
                         key={kp.name}
                         property={kp}
-                        value={value}
+                        value={getComponentPropertyValue(kp)}
                         element={props.element}
                         onParameterChange={props.onParameterChange}
                     />)
@@ -941,8 +962,6 @@ export function DslPropertyField(props: Props) {
     }
 
     function getExpandableComponentProperties(properties: ComponentProperty[], 
label: string) {
-        const element = props.element;
-
         return (
             <ExpandableSection
                 toggleText={label}
@@ -956,13 +975,13 @@ export function DslPropertyField(props: Props) {
                         return prevState;
                     })
                 }}
-                isExpanded={isShowAdvanced.includes(label)}>
+                isExpanded={getShowExpanded(label)}>
                 <div className="parameters">
                     {properties.map(kp =>
                         <ComponentPropertyField
                             key={kp.name}
                             property={kp}
-                            
value={CamelDefinitionApiExt.getParametersValue(element, kp.name, kp.kind === 
'path')}
+                            value={getComponentPropertyValue(kp)}
                             onParameterChange={props.onParameterChange}
                         />
                     )}
@@ -1012,9 +1031,30 @@ export function DslPropertyField(props: Props) {
         return ['string'].includes(property.type) && property.name !== 
'expression' && property.isArray && !property.enumVals;
     }
 
+    function getFilteredComponentProperties(): ComponentProperty[] {
+        let props = CamelUtil.getComponentProperties(element);
+        const filter = propertyFilter.toLocaleLowerCase()
+        props = props.filter(p => p.name?.toLocaleLowerCase().includes(filter) 
|| p.label.toLocaleLowerCase().includes(filter) || 
p.displayName.toLocaleLowerCase().includes(filter));
+        if (requiredOnly) {
+            props = props.filter(p => p.required);
+        }
+        if (changedOnly) {
+            props = props.filter(p => 
PropertyUtil.hasComponentPropertyValueChanged(p, getComponentPropertyValue(p)));
+        }
+        return props
+    }
+
+    function getPropertySelectorChanged(): boolean {
+        return requiredOnly || changedOnly || propertyFilter?.trim().length > 
0;
+    }
+
+    function getShowExpanded(label: string): boolean {
+        return isShowAdvanced.includes(label) || getPropertySelectorChanged();
+    }
+
     function getComponentParameters(property: PropertyMeta) {
         const element = props.element;
-        const properties = CamelUtil.getComponentProperties(element);
+        const properties = getFilteredComponentProperties();
         const propertiesMain = properties.filter(p => 
!p.label.includes("advanced") && !p.label.includes("security") && 
!p.label.includes("scheduler"));
         const propertiesAdvanced = properties.filter(p => 
p.label.includes("advanced"));
         const propertiesScheduler = properties.filter(p => 
p.label.includes("scheduler"));
diff --git 
a/karavan-app/src/main/webui/src/designer/property/property/KameletPropertyField.tsx
 
b/karavan-app/src/main/webui/src/designer/property/property/KameletPropertyField.tsx
index fe52431c..f9f1bf87 100644
--- 
a/karavan-app/src/main/webui/src/designer/property/property/KameletPropertyField.tsx
+++ 
b/karavan-app/src/main/webui/src/designer/property/property/KameletPropertyField.tsx
@@ -38,7 +38,6 @@ import EditorIcon from 
"@patternfly/react-icons/dist/js/icons/code-icon";
 import {ExpressionModalEditor} from 
"../../../expression/ExpressionModalEditor";
 import {useDesignerStore} from "../../DesignerStore";
 import {shallow} from "zustand/shallow";
-import {ComponentProperty} from 
"../../../../../karavan-core/src/core/model/ComponentModels";
 
 interface Props {
     property: Property,
diff --git a/karavan-designer/public/example/demo.camel.yaml 
b/karavan-designer/public/example/demo.camel.yaml
index 25bd3079..136dc156 100644
--- a/karavan-designer/public/example/demo.camel.yaml
+++ b/karavan-designer/public/example/demo.camel.yaml
@@ -12,3 +12,6 @@
         - to:
             id: to-7baa
             uri: jms
+        - to:
+            id: to-7f8a
+            uri: kamelet:aws-kinesis-firehose-sink
diff --git a/karavan-designer/src/designer/property/DslProperties.tsx 
b/karavan-designer/src/designer/property/DslProperties.tsx
index 993f825f..afd0eb76 100644
--- a/karavan-designer/src/designer/property/DslProperties.tsx
+++ b/karavan-designer/src/designer/property/DslProperties.tsx
@@ -22,7 +22,7 @@ import {
     TextVariants,
     ExpandableSection,
     Button,
-    Tooltip,
+    Tooltip, ToggleGroupItem, ToggleGroup, TextInput,
 } from '@patternfly/react-core';
 import '../karavan.css';
 import './DslProperties.css';
@@ -39,6 +39,8 @@ import {shallow} from "zustand/shallow";
 import {usePropertiesHook} from "./usePropertiesHook";
 import {CamelDisplayUtil} from "karavan-core/lib/api/CamelDisplayUtil";
 import {PropertiesHeader} from "./PropertiesHeader";
+import {PropertyUtil} from "./property/PropertyUtil";
+import {usePropertiesStore} from "./PropertyStore";
 
 interface Props {
     designerType: 'routes' | 'rest' | 'beans'
@@ -60,6 +62,9 @@ export function DslProperties(props: Props) {
     const [selectedStep, dark]
         = useDesignerStore((s) => [s.selectedStep, s.dark], shallow)
 
+    const [propertyFilter, changedOnly, requiredOnly, setChangedOnly, 
setPropertyFilter, setRequiredOnly]
+        = usePropertiesStore((s) => [s.propertyFilter, s.changedOnly, 
s.requiredOnly, s.setChangedOnly, s.setPropertyFilter, s.setRequiredOnly], 
shallow)
+
     const [showAdvanced, setShowAdvanced] = useState<boolean>(false);
 
     function getClonableElementHeader(): React.JSX.Element {
@@ -89,7 +94,7 @@ export function DslProperties(props: Props) {
         const dslName = selectedStep?.dslName;
         return CamelDefinitionApiExt.getElementProperties(dslName)
             .filter((p: PropertyMeta) => !(p.name === 'uri' && dslName !== 
'ToDynamicDefinition')) // show uri only to Dynamic To
-            // .filter((p: PropertyMeta) => (showAdvanced && 
p.label.includes('advanced')) || (!showAdvanced && 
!p.label.includes('advanced')))
+            // .filer((p: PropertyMeta) => (showAdvanced && 
p.label.includes('advanced')) || (!showAdvanced && 
!p.label.includes('advanced')))
             .filter((p: PropertyMeta) => !p.isObject || (p.isObject && 
!CamelUi.dslHasSteps(p.type)) || (dslName === 'CatchDefinition' && p.name === 
'onWhen'))
             .filter((p: PropertyMeta) => !(dslName === 'RestDefinition' && 
['get', 'post', 'put', 'patch', 'delete', 'head'].includes(p.name)));
         // .filter((p: PropertyMeta) => dslName && !(['RestDefinition', 
'GetDefinition', 'PostDefinition', 'PutDefinition', 'PatchDefinition', 
'DeleteDefinition', 'HeadDefinition'].includes(dslName) && ['param', 
'responseMessage'].includes(p.name))) // TODO: configure this properties
@@ -101,7 +106,7 @@ export function DslProperties(props: Props) {
                 <DslPropertyField key={property.name}
                                   property={property}
                                   element={selectedStep}
-                                  value={selectedStep ? (selectedStep as 
any)[property.name] : undefined}
+                                  value={getPropertyValue(property)}
                                   onExpressionChange={onExpressionChange}
                                   onParameterChange={onParametersChange}
                                   onDataFormatChange={onDataFormatChange}
@@ -111,26 +116,77 @@ export function DslProperties(props: Props) {
         </>)
     }
 
+    function getPropertyValue(property: PropertyMeta) {
+        return selectedStep ? (selectedStep as any)[property.name] : undefined;
+    }
+
+    function getFilteredProperties(): PropertyMeta[] {
+        let props = !dataFormatElement ? getProperties() : 
getProperties().filter(p => !dataFormats.includes(p.name));
+        const filter = propertyFilter.toLocaleLowerCase()
+        props = props.filter(p => p.name === 'parameters' || 
p.name.toLocaleLowerCase().includes(filter) || 
p.label.toLocaleLowerCase().includes(filter) || 
p.displayName.toLocaleLowerCase().includes(filter));
+        if (requiredOnly) {
+            props = props.filter(p => p.name === 'parameters' || p.required);
+        }
+        if (changedOnly) {
+            props = props.filter(p =>p.name === 'parameters' || 
PropertyUtil.hasDslPropertyValueChanged(p, getPropertyValue(p)));
+        }
+        return props
+    }
+
     const dataFormats = DataFormats.map(value => value[0]);
     const dataFormatElement = selectedStep !== undefined && 
['MarshalDefinition', 'UnmarshalDefinition'].includes(selectedStep.dslName);
-    const properties = !dataFormatElement
-        ? getProperties()
-        : getProperties().filter(p => !dataFormats.includes(p.name));
+    const properties = getFilteredProperties();
     const propertiesMain = properties.filter(p => 
!p.label.includes("advanced"));
     const propertiesAdvanced = properties.filter(p => 
p.label.includes("advanced"));
+
+    function getPropertySelector() {
+        return (
+            <div style={{display: 'flex', flexDirection: 'row', alignItems: 
'center', gap: '3px'}}>
+                <ToggleGroup aria-label="properties selctor">
+                    <ToggleGroupItem
+                        text="Required"
+                        buttonId="requiredOnly"
+                        isSelected={requiredOnly}
+                        onChange={(_, selected) => setRequiredOnly(selected)}
+                    />
+                    <ToggleGroupItem
+                        text="Changed"
+                        buttonId="changedOnly"
+                        isSelected={changedOnly}
+                        onChange={(_, selected) => setChangedOnly(selected)}
+                    />
+                </ToggleGroup>
+                <TextInput
+                    placeholder="filter by name"
+                    value={propertyFilter}
+                    onChange={(_, value) => setPropertyFilter(value)}
+                />
+            </div>
+        )
+    }
+
+    function getPropertySelectorChanged(): boolean {
+        return requiredOnly || changedOnly || propertyFilter?.trim().length > 
0;
+    }
+
+    function getShowExpanded(): boolean {
+        return showAdvanced || getPropertySelectorChanged();
+    }
+
     return (
         <div key={selectedStep ? selectedStep.uuid : 'integration'}
              className='properties'>
             <Form autoComplete="off" onSubmit={event => 
event.preventDefault()}>
                 {selectedStep === undefined && <IntegrationHeader/>}
                 {selectedStep && getComponentHeader()}
+                {selectedStep !== undefined && getPropertySelector()}
                 {getPropertyFields(propertiesMain)}
                 {selectedStep && !['MarshalDefinition', 
'UnmarshalDefinition'].includes(selectedStep.dslName)
                     && propertiesAdvanced.length > 0 &&
                     <ExpandableSection
                         toggleText={'EIP advanced properties'}
                         onToggle={(_event, isExpanded) => 
setShowAdvanced(!showAdvanced)}
-                        isExpanded={showAdvanced}>
+                        isExpanded={getShowExpanded()}>
                         <div className="parameters">
                             {getPropertyFields(propertiesAdvanced)}
                         </div>
diff --git a/karavan-designer/src/designer/property/PropertyStore.ts 
b/karavan-designer/src/designer/property/PropertyStore.ts
new file mode 100644
index 00000000..b9d0e511
--- /dev/null
+++ b/karavan-designer/src/designer/property/PropertyStore.ts
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import {createWithEqualityFn} from "zustand/traditional";
+import {shallow} from "zustand/shallow";
+
+interface PropertiesState {
+    propertyFilter: string;
+    setPropertyFilter: (propertyFilter: string) => void
+    requiredOnly: boolean;
+    setRequiredOnly: (requiredOnly: boolean) => void
+    changedOnly: boolean;
+    setChangedOnly: (changedOnly: boolean) => void
+}
+
+export const usePropertiesStore = createWithEqualityFn<PropertiesState>((set, 
get) => ({
+    requiredOnly: false,
+    changedOnly: false,
+    propertyFilter: '',
+    setPropertyFilter: (propertyFilter: string) => {
+        set({propertyFilter: propertyFilter});
+    },
+    setRequiredOnly: (requiredOnly: boolean) => {
+        set({requiredOnly: requiredOnly});
+    },
+    setChangedOnly: (changedOnly: boolean) => {
+        set({changedOnly: changedOnly});
+    },
+}), shallow)
diff --git 
a/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx 
b/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx
index 7669a114..262e2eb5 100644
--- a/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx
+++ b/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx
@@ -56,6 +56,7 @@ import EditorIcon from 
"@patternfly/react-icons/dist/js/icons/code-icon";
 import {ExpressionModalEditor} from 
"../../../expression/ExpressionModalEditor";
 import {PropertyPlaceholderDropdown} from "./PropertyPlaceholderDropdown";
 import {INTERNAL_COMPONENTS} from "karavan-core/lib/api/ComponentApi";
+import {PropertyUtil} from "./PropertyUtil";
 
 const prefix = "parameters";
 const beanPrefix = "#bean:";
@@ -414,14 +415,9 @@ export function ComponentPropertyField(props: Props) {
         )
     }
 
-    function hasValueChanged(property: ComponentProperty, value: any): boolean 
{
-        const isSet = value !== undefined;
-        const isDefault = property.defaultValue !== undefined && 
value?.toString() === property.defaultValue?.toString();
-        return isSet && !isDefault;
-    }
 
     function getLabel(property: ComponentProperty, value: any) {
-        const bgColor = hasValueChanged(property, value) ? 'yellow' : 
'transparent';
+        const bgColor = 
PropertyUtil.hasComponentPropertyValueChanged(property, value) ? 'yellow' : 
'transparent';
         return (
             <div style={{display: "flex", flexDirection: 'row', alignItems: 
'center', gap: '3px'}}>
                 <Text style={{backgroundColor: 
bgColor}}>{property.displayName}</Text>
diff --git 
a/karavan-designer/src/designer/property/property/DslPropertyField.tsx 
b/karavan-designer/src/designer/property/property/DslPropertyField.tsx
index b35ca3be..09f259f6 100644
--- a/karavan-designer/src/designer/property/property/DslPropertyField.tsx
+++ b/karavan-designer/src/designer/property/property/DslPropertyField.tsx
@@ -80,6 +80,9 @@ import {VariablesDropdown} from "./VariablesDropdown";
 import {ROUTE, GLOBAL} from "karavan-core/lib/api/VariableUtil";
 import {SpiBeanApi} from "karavan-core/lib/api/SpiBeanApi";
 import {SelectField} from "./SelectField";
+import {PropertyUtil} from "./PropertyUtil";
+import {usePropertiesStore} from "../PropertyStore";
+import {Property} from "karavan-core/lib/model/KameletModels";
 
 const beanPrefix = "#bean:";
 const classPrefix = "#class:";
@@ -100,6 +103,7 @@ export function DslPropertyField(props: Props) {
 
     const [integration, setIntegration, addVariable, files] = 
useIntegrationStore((s) => [s.integration, s.setIntegration, s.addVariable, 
s.files], shallow)
     const [dark, setSelectedStep, beans] = useDesignerStore((s) => [s.dark, 
s.setSelectedStep, s.beans], shallow)
+    const [propertyFilter, changedOnly, requiredOnly] = usePropertiesStore((s) 
=> [s.propertyFilter, s.changedOnly, s.requiredOnly], shallow)
 
     const [isShowAdvanced, setIsShowAdvanced] = useState<string[]>([]);
     const [arrayValues, setArrayValues] = useState<Map<string, string>>(new 
Map<string, string>());
@@ -204,14 +208,8 @@ export function DslPropertyField(props: Props) {
         return property.name === 'parameters' && property.description === 
'parameters';
     }
 
-    function hasValueChanged(property: PropertyMeta, value: any): boolean {
-        const isSet = value !== undefined && !['id', 
'uri'].includes(property.name);
-        const isDefault = property.defaultValue !== undefined && 
value?.toString() === property.defaultValue?.toString();
-        return isSet && !isDefault;
-    }
-
     function getLabel(property: PropertyMeta, value: any, isKamelet: boolean) {
-        const bgColor = hasValueChanged(property, value) ? 'yellow' : 
'transparent';
+        const bgColor = PropertyUtil.hasDslPropertyValueChanged(property, 
value) ? 'yellow' : 'transparent';
         if (!isMultiValueField(property) && property.isObject && 
!property.isArray && !["ExpressionDefinition"].includes(property.type)) {
             const tooltip = value ? "Delete " + property.name : "Add " + 
property.name;
             const className = value ? "change-button delete-button" : 
"change-button add-button";
@@ -906,32 +904,55 @@ export function DslPropertyField(props: Props) {
         )
     }
 
+    function getKameletPropertyValue(property: Property) {
+        const element = props.element;
+        return CamelDefinitionApiExt.getParametersValue(element, property.id)
+    }
+
+    function getFilteredKameletProperties(): Property[] {
+        const element = props.element;
+        const requiredParameters = 
CamelUtil.getKameletRequiredParameters(element);
+        let properties = CamelUtil.getKameletProperties(element)
+        const filter = propertyFilter.toLocaleLowerCase()
+        properties = properties.filter(p => 
p.title?.toLocaleLowerCase().includes(filter) || 
p.id?.toLocaleLowerCase().includes(filter));
+        if (requiredOnly) {
+            properties = properties.filter(p => 
requiredParameters.includes(p.id));
+        }
+        if (changedOnly) {
+            properties = properties.filter(p => 
PropertyUtil.hasKameletPropertyValueChanged(p, getKameletPropertyValue(p)));
+        }
+        return properties;
+    }
+
     function getKameletParameters() {
         const element = props.element;
         const requiredParameters = 
CamelUtil.getKameletRequiredParameters(element);
         return (
             <div className="parameters">
-                {CamelUtil.getKameletProperties(element).map(property =>
+                {getFilteredKameletProperties().map(property =>
                     <KameletPropertyField
                         key={property.id}
                         property={property}
-                        
value={CamelDefinitionApiExt.getParametersValue(element, property.id)}
+                        value={getKameletPropertyValue(property)}
                         required={requiredParameters?.includes(property.id)}
                     />)}
             </div>
         )
     }
 
-    function getMainComponentParameters(properties: ComponentProperty[]) {
+    function getComponentPropertyValue(kp: ComponentProperty) {
         const element = props.element;
+        return CamelDefinitionApiExt.getParametersValue(element, kp.name, 
kp.kind === 'path');
+    }
+
+    function getMainComponentParameters(properties: ComponentProperty[]) {
         return (
             <div className="parameters">
                 {properties.map(kp => {
-                    const value = 
CamelDefinitionApiExt.getParametersValue(element, kp.name, kp.kind === 'path');
                     return (<ComponentPropertyField
                         key={kp.name}
                         property={kp}
-                        value={value}
+                        value={getComponentPropertyValue(kp)}
                         element={props.element}
                         onParameterChange={props.onParameterChange}
                     />)
@@ -941,8 +962,6 @@ export function DslPropertyField(props: Props) {
     }
 
     function getExpandableComponentProperties(properties: ComponentProperty[], 
label: string) {
-        const element = props.element;
-
         return (
             <ExpandableSection
                 toggleText={label}
@@ -956,13 +975,13 @@ export function DslPropertyField(props: Props) {
                         return prevState;
                     })
                 }}
-                isExpanded={isShowAdvanced.includes(label)}>
+                isExpanded={getShowExpanded(label)}>
                 <div className="parameters">
                     {properties.map(kp =>
                         <ComponentPropertyField
                             key={kp.name}
                             property={kp}
-                            
value={CamelDefinitionApiExt.getParametersValue(element, kp.name, kp.kind === 
'path')}
+                            value={getComponentPropertyValue(kp)}
                             onParameterChange={props.onParameterChange}
                         />
                     )}
@@ -1012,9 +1031,30 @@ export function DslPropertyField(props: Props) {
         return ['string'].includes(property.type) && property.name !== 
'expression' && property.isArray && !property.enumVals;
     }
 
+    function getFilteredComponentProperties(): ComponentProperty[] {
+        let props = CamelUtil.getComponentProperties(element);
+        const filter = propertyFilter.toLocaleLowerCase()
+        props = props.filter(p => p.name?.toLocaleLowerCase().includes(filter) 
|| p.label.toLocaleLowerCase().includes(filter) || 
p.displayName.toLocaleLowerCase().includes(filter));
+        if (requiredOnly) {
+            props = props.filter(p => p.required);
+        }
+        if (changedOnly) {
+            props = props.filter(p => 
PropertyUtil.hasComponentPropertyValueChanged(p, getComponentPropertyValue(p)));
+        }
+        return props
+    }
+
+    function getPropertySelectorChanged(): boolean {
+        return requiredOnly || changedOnly || propertyFilter?.trim().length > 
0;
+    }
+
+    function getShowExpanded(label: string): boolean {
+        return isShowAdvanced.includes(label) || getPropertySelectorChanged();
+    }
+
     function getComponentParameters(property: PropertyMeta) {
         const element = props.element;
-        const properties = CamelUtil.getComponentProperties(element);
+        const properties = getFilteredComponentProperties();
         const propertiesMain = properties.filter(p => 
!p.label.includes("advanced") && !p.label.includes("security") && 
!p.label.includes("scheduler"));
         const propertiesAdvanced = properties.filter(p => 
p.label.includes("advanced"));
         const propertiesScheduler = properties.filter(p => 
p.label.includes("scheduler"));
diff --git a/karavan-designer/src/designer/property/property/PropertyUtil.tsx 
b/karavan-designer/src/designer/property/property/PropertyUtil.tsx
new file mode 100644
index 00000000..57ba1a3c
--- /dev/null
+++ b/karavan-designer/src/designer/property/property/PropertyUtil.tsx
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import {PropertyMeta} from "karavan-core/lib/model/CamelMetadata";
+import {ComponentProperty} from "karavan-core/lib/model/ComponentModels";
+import {Property} from "karavan-core/lib/model/KameletModels";
+
+export class PropertyUtil {
+
+    static hasDslPropertyValueChanged(property: PropertyMeta, value: any): 
boolean {
+        const isSet = value !== undefined && !['id', 'uri', 
'nodePrefixId'].includes(property.name);
+        const isDefault = property.defaultValue !== undefined && 
value?.toString() === property.defaultValue?.toString();
+        return isSet && !isDefault;
+    }
+
+    static hasComponentPropertyValueChanged(property: ComponentProperty, 
value: any): boolean {
+        const isSet = value !== undefined;
+        const isDefault = property.defaultValue !== undefined && 
value?.toString() === property.defaultValue?.toString();
+        return isSet && !isDefault;
+    }
+
+    static hasKameletPropertyValueChanged(property: Property, value: any): 
boolean {
+        const isSet = value !== undefined;
+        const isDefault = property.default !== undefined && value?.toString() 
=== property.default?.toString();
+        return isSet && !isDefault;
+    }
+}
\ No newline at end of file
diff --git a/karavan-space/src/designer/property/DslProperties.tsx 
b/karavan-space/src/designer/property/DslProperties.tsx
index 993f825f..afd0eb76 100644
--- a/karavan-space/src/designer/property/DslProperties.tsx
+++ b/karavan-space/src/designer/property/DslProperties.tsx
@@ -22,7 +22,7 @@ import {
     TextVariants,
     ExpandableSection,
     Button,
-    Tooltip,
+    Tooltip, ToggleGroupItem, ToggleGroup, TextInput,
 } from '@patternfly/react-core';
 import '../karavan.css';
 import './DslProperties.css';
@@ -39,6 +39,8 @@ import {shallow} from "zustand/shallow";
 import {usePropertiesHook} from "./usePropertiesHook";
 import {CamelDisplayUtil} from "karavan-core/lib/api/CamelDisplayUtil";
 import {PropertiesHeader} from "./PropertiesHeader";
+import {PropertyUtil} from "./property/PropertyUtil";
+import {usePropertiesStore} from "./PropertyStore";
 
 interface Props {
     designerType: 'routes' | 'rest' | 'beans'
@@ -60,6 +62,9 @@ export function DslProperties(props: Props) {
     const [selectedStep, dark]
         = useDesignerStore((s) => [s.selectedStep, s.dark], shallow)
 
+    const [propertyFilter, changedOnly, requiredOnly, setChangedOnly, 
setPropertyFilter, setRequiredOnly]
+        = usePropertiesStore((s) => [s.propertyFilter, s.changedOnly, 
s.requiredOnly, s.setChangedOnly, s.setPropertyFilter, s.setRequiredOnly], 
shallow)
+
     const [showAdvanced, setShowAdvanced] = useState<boolean>(false);
 
     function getClonableElementHeader(): React.JSX.Element {
@@ -89,7 +94,7 @@ export function DslProperties(props: Props) {
         const dslName = selectedStep?.dslName;
         return CamelDefinitionApiExt.getElementProperties(dslName)
             .filter((p: PropertyMeta) => !(p.name === 'uri' && dslName !== 
'ToDynamicDefinition')) // show uri only to Dynamic To
-            // .filter((p: PropertyMeta) => (showAdvanced && 
p.label.includes('advanced')) || (!showAdvanced && 
!p.label.includes('advanced')))
+            // .filer((p: PropertyMeta) => (showAdvanced && 
p.label.includes('advanced')) || (!showAdvanced && 
!p.label.includes('advanced')))
             .filter((p: PropertyMeta) => !p.isObject || (p.isObject && 
!CamelUi.dslHasSteps(p.type)) || (dslName === 'CatchDefinition' && p.name === 
'onWhen'))
             .filter((p: PropertyMeta) => !(dslName === 'RestDefinition' && 
['get', 'post', 'put', 'patch', 'delete', 'head'].includes(p.name)));
         // .filter((p: PropertyMeta) => dslName && !(['RestDefinition', 
'GetDefinition', 'PostDefinition', 'PutDefinition', 'PatchDefinition', 
'DeleteDefinition', 'HeadDefinition'].includes(dslName) && ['param', 
'responseMessage'].includes(p.name))) // TODO: configure this properties
@@ -101,7 +106,7 @@ export function DslProperties(props: Props) {
                 <DslPropertyField key={property.name}
                                   property={property}
                                   element={selectedStep}
-                                  value={selectedStep ? (selectedStep as 
any)[property.name] : undefined}
+                                  value={getPropertyValue(property)}
                                   onExpressionChange={onExpressionChange}
                                   onParameterChange={onParametersChange}
                                   onDataFormatChange={onDataFormatChange}
@@ -111,26 +116,77 @@ export function DslProperties(props: Props) {
         </>)
     }
 
+    function getPropertyValue(property: PropertyMeta) {
+        return selectedStep ? (selectedStep as any)[property.name] : undefined;
+    }
+
+    function getFilteredProperties(): PropertyMeta[] {
+        let props = !dataFormatElement ? getProperties() : 
getProperties().filter(p => !dataFormats.includes(p.name));
+        const filter = propertyFilter.toLocaleLowerCase()
+        props = props.filter(p => p.name === 'parameters' || 
p.name.toLocaleLowerCase().includes(filter) || 
p.label.toLocaleLowerCase().includes(filter) || 
p.displayName.toLocaleLowerCase().includes(filter));
+        if (requiredOnly) {
+            props = props.filter(p => p.name === 'parameters' || p.required);
+        }
+        if (changedOnly) {
+            props = props.filter(p =>p.name === 'parameters' || 
PropertyUtil.hasDslPropertyValueChanged(p, getPropertyValue(p)));
+        }
+        return props
+    }
+
     const dataFormats = DataFormats.map(value => value[0]);
     const dataFormatElement = selectedStep !== undefined && 
['MarshalDefinition', 'UnmarshalDefinition'].includes(selectedStep.dslName);
-    const properties = !dataFormatElement
-        ? getProperties()
-        : getProperties().filter(p => !dataFormats.includes(p.name));
+    const properties = getFilteredProperties();
     const propertiesMain = properties.filter(p => 
!p.label.includes("advanced"));
     const propertiesAdvanced = properties.filter(p => 
p.label.includes("advanced"));
+
+    function getPropertySelector() {
+        return (
+            <div style={{display: 'flex', flexDirection: 'row', alignItems: 
'center', gap: '3px'}}>
+                <ToggleGroup aria-label="properties selctor">
+                    <ToggleGroupItem
+                        text="Required"
+                        buttonId="requiredOnly"
+                        isSelected={requiredOnly}
+                        onChange={(_, selected) => setRequiredOnly(selected)}
+                    />
+                    <ToggleGroupItem
+                        text="Changed"
+                        buttonId="changedOnly"
+                        isSelected={changedOnly}
+                        onChange={(_, selected) => setChangedOnly(selected)}
+                    />
+                </ToggleGroup>
+                <TextInput
+                    placeholder="filter by name"
+                    value={propertyFilter}
+                    onChange={(_, value) => setPropertyFilter(value)}
+                />
+            </div>
+        )
+    }
+
+    function getPropertySelectorChanged(): boolean {
+        return requiredOnly || changedOnly || propertyFilter?.trim().length > 
0;
+    }
+
+    function getShowExpanded(): boolean {
+        return showAdvanced || getPropertySelectorChanged();
+    }
+
     return (
         <div key={selectedStep ? selectedStep.uuid : 'integration'}
              className='properties'>
             <Form autoComplete="off" onSubmit={event => 
event.preventDefault()}>
                 {selectedStep === undefined && <IntegrationHeader/>}
                 {selectedStep && getComponentHeader()}
+                {selectedStep !== undefined && getPropertySelector()}
                 {getPropertyFields(propertiesMain)}
                 {selectedStep && !['MarshalDefinition', 
'UnmarshalDefinition'].includes(selectedStep.dslName)
                     && propertiesAdvanced.length > 0 &&
                     <ExpandableSection
                         toggleText={'EIP advanced properties'}
                         onToggle={(_event, isExpanded) => 
setShowAdvanced(!showAdvanced)}
-                        isExpanded={showAdvanced}>
+                        isExpanded={getShowExpanded()}>
                         <div className="parameters">
                             {getPropertyFields(propertiesAdvanced)}
                         </div>
diff --git 
a/karavan-space/src/designer/property/property/ComponentPropertyField.tsx 
b/karavan-space/src/designer/property/property/ComponentPropertyField.tsx
index 7669a114..262e2eb5 100644
--- a/karavan-space/src/designer/property/property/ComponentPropertyField.tsx
+++ b/karavan-space/src/designer/property/property/ComponentPropertyField.tsx
@@ -56,6 +56,7 @@ import EditorIcon from 
"@patternfly/react-icons/dist/js/icons/code-icon";
 import {ExpressionModalEditor} from 
"../../../expression/ExpressionModalEditor";
 import {PropertyPlaceholderDropdown} from "./PropertyPlaceholderDropdown";
 import {INTERNAL_COMPONENTS} from "karavan-core/lib/api/ComponentApi";
+import {PropertyUtil} from "./PropertyUtil";
 
 const prefix = "parameters";
 const beanPrefix = "#bean:";
@@ -414,14 +415,9 @@ export function ComponentPropertyField(props: Props) {
         )
     }
 
-    function hasValueChanged(property: ComponentProperty, value: any): boolean 
{
-        const isSet = value !== undefined;
-        const isDefault = property.defaultValue !== undefined && 
value?.toString() === property.defaultValue?.toString();
-        return isSet && !isDefault;
-    }
 
     function getLabel(property: ComponentProperty, value: any) {
-        const bgColor = hasValueChanged(property, value) ? 'yellow' : 
'transparent';
+        const bgColor = 
PropertyUtil.hasComponentPropertyValueChanged(property, value) ? 'yellow' : 
'transparent';
         return (
             <div style={{display: "flex", flexDirection: 'row', alignItems: 
'center', gap: '3px'}}>
                 <Text style={{backgroundColor: 
bgColor}}>{property.displayName}</Text>
diff --git a/karavan-space/src/designer/property/property/DslPropertyField.tsx 
b/karavan-space/src/designer/property/property/DslPropertyField.tsx
index b35ca3be..09f259f6 100644
--- a/karavan-space/src/designer/property/property/DslPropertyField.tsx
+++ b/karavan-space/src/designer/property/property/DslPropertyField.tsx
@@ -80,6 +80,9 @@ import {VariablesDropdown} from "./VariablesDropdown";
 import {ROUTE, GLOBAL} from "karavan-core/lib/api/VariableUtil";
 import {SpiBeanApi} from "karavan-core/lib/api/SpiBeanApi";
 import {SelectField} from "./SelectField";
+import {PropertyUtil} from "./PropertyUtil";
+import {usePropertiesStore} from "../PropertyStore";
+import {Property} from "karavan-core/lib/model/KameletModels";
 
 const beanPrefix = "#bean:";
 const classPrefix = "#class:";
@@ -100,6 +103,7 @@ export function DslPropertyField(props: Props) {
 
     const [integration, setIntegration, addVariable, files] = 
useIntegrationStore((s) => [s.integration, s.setIntegration, s.addVariable, 
s.files], shallow)
     const [dark, setSelectedStep, beans] = useDesignerStore((s) => [s.dark, 
s.setSelectedStep, s.beans], shallow)
+    const [propertyFilter, changedOnly, requiredOnly] = usePropertiesStore((s) 
=> [s.propertyFilter, s.changedOnly, s.requiredOnly], shallow)
 
     const [isShowAdvanced, setIsShowAdvanced] = useState<string[]>([]);
     const [arrayValues, setArrayValues] = useState<Map<string, string>>(new 
Map<string, string>());
@@ -204,14 +208,8 @@ export function DslPropertyField(props: Props) {
         return property.name === 'parameters' && property.description === 
'parameters';
     }
 
-    function hasValueChanged(property: PropertyMeta, value: any): boolean {
-        const isSet = value !== undefined && !['id', 
'uri'].includes(property.name);
-        const isDefault = property.defaultValue !== undefined && 
value?.toString() === property.defaultValue?.toString();
-        return isSet && !isDefault;
-    }
-
     function getLabel(property: PropertyMeta, value: any, isKamelet: boolean) {
-        const bgColor = hasValueChanged(property, value) ? 'yellow' : 
'transparent';
+        const bgColor = PropertyUtil.hasDslPropertyValueChanged(property, 
value) ? 'yellow' : 'transparent';
         if (!isMultiValueField(property) && property.isObject && 
!property.isArray && !["ExpressionDefinition"].includes(property.type)) {
             const tooltip = value ? "Delete " + property.name : "Add " + 
property.name;
             const className = value ? "change-button delete-button" : 
"change-button add-button";
@@ -906,32 +904,55 @@ export function DslPropertyField(props: Props) {
         )
     }
 
+    function getKameletPropertyValue(property: Property) {
+        const element = props.element;
+        return CamelDefinitionApiExt.getParametersValue(element, property.id)
+    }
+
+    function getFilteredKameletProperties(): Property[] {
+        const element = props.element;
+        const requiredParameters = 
CamelUtil.getKameletRequiredParameters(element);
+        let properties = CamelUtil.getKameletProperties(element)
+        const filter = propertyFilter.toLocaleLowerCase()
+        properties = properties.filter(p => 
p.title?.toLocaleLowerCase().includes(filter) || 
p.id?.toLocaleLowerCase().includes(filter));
+        if (requiredOnly) {
+            properties = properties.filter(p => 
requiredParameters.includes(p.id));
+        }
+        if (changedOnly) {
+            properties = properties.filter(p => 
PropertyUtil.hasKameletPropertyValueChanged(p, getKameletPropertyValue(p)));
+        }
+        return properties;
+    }
+
     function getKameletParameters() {
         const element = props.element;
         const requiredParameters = 
CamelUtil.getKameletRequiredParameters(element);
         return (
             <div className="parameters">
-                {CamelUtil.getKameletProperties(element).map(property =>
+                {getFilteredKameletProperties().map(property =>
                     <KameletPropertyField
                         key={property.id}
                         property={property}
-                        
value={CamelDefinitionApiExt.getParametersValue(element, property.id)}
+                        value={getKameletPropertyValue(property)}
                         required={requiredParameters?.includes(property.id)}
                     />)}
             </div>
         )
     }
 
-    function getMainComponentParameters(properties: ComponentProperty[]) {
+    function getComponentPropertyValue(kp: ComponentProperty) {
         const element = props.element;
+        return CamelDefinitionApiExt.getParametersValue(element, kp.name, 
kp.kind === 'path');
+    }
+
+    function getMainComponentParameters(properties: ComponentProperty[]) {
         return (
             <div className="parameters">
                 {properties.map(kp => {
-                    const value = 
CamelDefinitionApiExt.getParametersValue(element, kp.name, kp.kind === 'path');
                     return (<ComponentPropertyField
                         key={kp.name}
                         property={kp}
-                        value={value}
+                        value={getComponentPropertyValue(kp)}
                         element={props.element}
                         onParameterChange={props.onParameterChange}
                     />)
@@ -941,8 +962,6 @@ export function DslPropertyField(props: Props) {
     }
 
     function getExpandableComponentProperties(properties: ComponentProperty[], 
label: string) {
-        const element = props.element;
-
         return (
             <ExpandableSection
                 toggleText={label}
@@ -956,13 +975,13 @@ export function DslPropertyField(props: Props) {
                         return prevState;
                     })
                 }}
-                isExpanded={isShowAdvanced.includes(label)}>
+                isExpanded={getShowExpanded(label)}>
                 <div className="parameters">
                     {properties.map(kp =>
                         <ComponentPropertyField
                             key={kp.name}
                             property={kp}
-                            
value={CamelDefinitionApiExt.getParametersValue(element, kp.name, kp.kind === 
'path')}
+                            value={getComponentPropertyValue(kp)}
                             onParameterChange={props.onParameterChange}
                         />
                     )}
@@ -1012,9 +1031,30 @@ export function DslPropertyField(props: Props) {
         return ['string'].includes(property.type) && property.name !== 
'expression' && property.isArray && !property.enumVals;
     }
 
+    function getFilteredComponentProperties(): ComponentProperty[] {
+        let props = CamelUtil.getComponentProperties(element);
+        const filter = propertyFilter.toLocaleLowerCase()
+        props = props.filter(p => p.name?.toLocaleLowerCase().includes(filter) 
|| p.label.toLocaleLowerCase().includes(filter) || 
p.displayName.toLocaleLowerCase().includes(filter));
+        if (requiredOnly) {
+            props = props.filter(p => p.required);
+        }
+        if (changedOnly) {
+            props = props.filter(p => 
PropertyUtil.hasComponentPropertyValueChanged(p, getComponentPropertyValue(p)));
+        }
+        return props
+    }
+
+    function getPropertySelectorChanged(): boolean {
+        return requiredOnly || changedOnly || propertyFilter?.trim().length > 
0;
+    }
+
+    function getShowExpanded(label: string): boolean {
+        return isShowAdvanced.includes(label) || getPropertySelectorChanged();
+    }
+
     function getComponentParameters(property: PropertyMeta) {
         const element = props.element;
-        const properties = CamelUtil.getComponentProperties(element);
+        const properties = getFilteredComponentProperties();
         const propertiesMain = properties.filter(p => 
!p.label.includes("advanced") && !p.label.includes("security") && 
!p.label.includes("scheduler"));
         const propertiesAdvanced = properties.filter(p => 
p.label.includes("advanced"));
         const propertiesScheduler = properties.filter(p => 
p.label.includes("scheduler"));
diff --git 
a/karavan-space/src/designer/property/property/KameletPropertyField.tsx 
b/karavan-space/src/designer/property/property/KameletPropertyField.tsx
index fe52431c..f9f1bf87 100644
--- a/karavan-space/src/designer/property/property/KameletPropertyField.tsx
+++ b/karavan-space/src/designer/property/property/KameletPropertyField.tsx
@@ -38,7 +38,6 @@ import EditorIcon from 
"@patternfly/react-icons/dist/js/icons/code-icon";
 import {ExpressionModalEditor} from 
"../../../expression/ExpressionModalEditor";
 import {useDesignerStore} from "../../DesignerStore";
 import {shallow} from "zustand/shallow";
-import {ComponentProperty} from 
"../../../../../karavan-core/src/core/model/ComponentModels";
 
 interface Props {
     property: Property,

Reply via email to