You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ma...@apache.org on 2024/02/21 01:29:31 UTC
(camel-karavan) 03/07: Less diagramm rendering on properties changes for #731
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 621685f6edc3b4b7227c95704c8c15deeeed32e2
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Tue Feb 20 17:54:13 2024 -0500
Less diagramm rendering on properties changes for #731
---
karavan-designer/public/example/demo.camel.yaml | 130 ++++++++++-----------
karavan-designer/src/App.tsx | 2 +-
.../property/property/ComponentPropertyField.tsx | 94 +++++++++++----
.../property/property/DslPropertyField.tsx | 90 +++++++++-----
4 files changed, 200 insertions(+), 116 deletions(-)
diff --git a/karavan-designer/public/example/demo.camel.yaml b/karavan-designer/public/example/demo.camel.yaml
index 28340ccf..f568f58b 100644
--- a/karavan-designer/public/example/demo.camel.yaml
+++ b/karavan-designer/public/example/demo.camel.yaml
@@ -1,68 +1,68 @@
-- route:
- id: route-a947
- nodePrefixId: route-a32
- from:
- id: from-c489
- description: Receive Data
- uri: kamelet:aws-ddb-streams-source
- steps:
- - setHeader:
- id: setBody-4434
- expression:
- simple:
- id: simple-abd8
- expression: dddddd
- - filter:
- id: filter-929b
- expression:
- simple:
- id: simple-d932
- expression: Hello
- steps:
- - bean:
- id: bean-120b
- ref: xxx
- - log:
- id: log-d86e
- message: ${body}!!!
- - to:
- id: to-9f7d
- description: Send notification
- uri: kafka
- - to:
- id: to-53a3
- description: Send payments
- uri: amqp
-- route:
- id: route-8609
- nodePrefixId: route-ae2
- from:
- id: from-6aee
- uri: timer
- steps:
- - to:
- id: to-2df4
- uri: direct
- parameters:
- name: second_direct
- - to:
- id: to-e017
- uri: direct
- parameters:
- name: second_direct
-- route:
- id: first-firect
- from:
- id: from-f155
- uri: direct
- parameters:
- name: first-firect
- steps:
- - to:
- id: to-5c86
- uri: direct
- parameters:
- name: second_direct
+#- route:
+# id: route-a947
+# nodePrefixId: route-a32
+# from:
+# id: from-c489
+# description: Receive Data
+# uri: kamelet:aws-ddb-streams-source
+# steps:
+# - setHeader:
+# id: setBody-4434
+# expression:
+# simple:
+# id: simple-abd8
+# expression: dddddd
+# - filter:
+# id: filter-929b
+# expression:
+# simple:
+# id: simple-d932
+# expression: Hello
+# steps:
+# - bean:
+# id: bean-120b
+# ref: xxx
+# - log:
+# id: log-d86e
+# message: ${body}!!!
+# - to:
+# id: to-9f7d
+# description: Send notification
+# uri: kafka
+# - to:
+# id: to-53a3
+# description: Send payments
+# uri: amqp
+#- route:
+# id: route-8609
+# nodePrefixId: route-ae2
+# from:
+# id: from-6aee
+# uri: timer
+# steps:
+# - to:
+# id: to-2df4
+# uri: direct
+# parameters:
+# name: second_direct
+# - to:
+# id: to-e017
+# uri: direct
+# parameters:
+# name: second_direct
+#- route:
+# id: first-firect
+# from:
+# id: from-f155
+# uri: direct
+# parameters:
+# name: first-firect
+# steps:
+# - to:
+# id: to-5c86
+# uri: direct
+# parameters:
+# name: second_direct
- route:
id: second_direct
from:
diff --git a/karavan-designer/src/App.tsx b/karavan-designer/src/App.tsx
index 331aa343..03046460 100644
--- a/karavan-designer/src/App.tsx
+++ b/karavan-designer/src/App.tsx
@@ -114,7 +114,7 @@ export function App() {
});
function save(filename: string, yaml: string, propertyOnly: boolean) {
- // console.log(yaml);
+ console.log(yaml);
}
function getSpinner() {
diff --git a/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx b/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx
index 3798c4e4..3f13cb1e 100644
--- a/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx
+++ b/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import React, {useRef, useState} from 'react';
+import React, {useEffect, useRef, useState} from 'react';
import {
FormGroup,
TextInput,
@@ -80,11 +80,27 @@ export function ComponentPropertyField(props: Props) {
const [infrastructureSelector, setInfrastructureSelector] = useState<boolean>(false);
const [infrastructureSelectorProperty, setInfrastructureSelectorProperty] = useState<string | undefined>(undefined);
const [id, setId] = useState<string>(prefix + "-" + props.property.name);
-
+ const [textValue, setTextValue] = useState<any>();
const ref = useRef<any>(null);
+ const [checkChanges, setCheckChanges] = useState<boolean>(false);
+
+ useEffect(()=> setTextValue(value), [])
+ useEffect(()=> {
+ if (checkChanges) {
+ const interval = setInterval(() => {
+ if (props.value !== textValue) {
+ parametersChanged(property.name, textValue);
+ }
+ }, 3000);
+ return () => {
+ clearInterval(interval)
+ }
+ }
+ }, [checkChanges, textValue])
function parametersChanged(parameter: string, value: string | number | boolean | any, pathParameter?: boolean, newRoute?: RouteToCreate) {
+ setCheckChanges(false);
onParametersChange(parameter, value, pathParameter, newRoute);
setSelectStatus(new Map<string, boolean>([[parameter, false]]))
}
@@ -221,7 +237,7 @@ export function ComponentPropertyField(props: Props) {
onSelect={selectInfrastructure}/>)
}
- function getStringInput(property: ComponentProperty, value: any) {
+ function getStringInput(property: ComponentProperty) {
const inInfrastructure = InfrastructureAPI.infrastructure !== 'local';
const noInfraSelectorButton = ["uri", "id", "description", "group"].includes(property.name);
const icon = InfrastructureAPI.infrastructure === 'kubernetes' ? KubernetesIcon("infra-button") : <DockerIcon/>
@@ -237,8 +253,14 @@ export function ComponentPropertyField(props: Props) {
<TextInput className="text-field" isRequired ref={ref}
type={property.secret && !showPassword ? "password" : "text"}
id={id} name={id}
- value={value !== undefined ? value : property.defaultValue}
- onChange={(e, value) => parametersChanged(property.name, value, property.kind === 'path')}/>}
+ value={textValue !== undefined ? textValue : property.defaultValue}
+ onBlur={_ => parametersChanged(property.name, textValue, property.kind === 'path')}
+ onChange={(_, v) => {
+ setTextValue(v);
+ setCheckChanges(true);
+ }}
+ />
+ }
<InputGroupItem>
<Tooltip position="bottom-end" content={"Show Editor"}>
<Button variant="control" onClick={e => setShowEditor(!showEditor)}>
@@ -257,6 +279,7 @@ export function ComponentPropertyField(props: Props) {
onSave={(fieldId, value1) => {
parametersChanged(property.name, value1, property.kind === 'path')
setShowEditor(false);
+ setCheckChanges(false);
}}/>
</InputGroupItem>}
{property.secret &&
@@ -267,12 +290,16 @@ export function ComponentPropertyField(props: Props) {
</Tooltip>
}
<InputGroupItem>
- <PropertyPlaceholderDropdown property={property} value={value} onComponentPropertyChange={onParametersChange}/>
+ <PropertyPlaceholderDropdown property={property} value={value} onComponentPropertyChange={(parameter, v) => {
+ onParametersChange(parameter, v);
+ setTextValue(v);
+ setCheckChanges(false);
+ }}/>
</InputGroupItem>
</InputGroup>
}
- function getSpecialStringInput(property: ComponentProperty, value: any) {
+ function getSpecialStringInput(property: ComponentProperty) {
return (
<InputGroup>
<InputGroupItem isFill>
@@ -280,14 +307,21 @@ export function ComponentPropertyField(props: Props) {
className="text-field" isRequired
type={(property.secret ? "password" : "text")}
id={id} name={id}
- value={value !== undefined ? value : property.defaultValue}
+ value={textValue !== undefined ? textValue : property.defaultValue}
+ onBlur={_ => parametersChanged(property.name, textValue, property.kind === 'path')}
+ onChange={(_, v) => {
+ setTextValue(v);
+ setCheckChanges(true);
+ }}
customIcon={<Text component={TextVariants.p}>{property.type}</Text>}
- onChange={(_, value) => {
- parametersChanged(property.name, value, property.kind === 'path')
- }}/>
+ />
</InputGroupItem>
<InputGroupItem>
- <PropertyPlaceholderDropdown property={property} value={value} onComponentPropertyChange={onParametersChange}/>
+ <PropertyPlaceholderDropdown property={property} value={textValue} onComponentPropertyChange={(_, v) => {
+ setTextValue(v);
+ onParametersChange(property.name, v)
+ setCheckChanges(true);
+ }}/>
</InputGroupItem>
</InputGroup>
)
@@ -318,21 +352,25 @@ export function ComponentPropertyField(props: Props) {
)
}
- function getSwitch(property: ComponentProperty, value: any) {
- const isValueBoolean = (value === true || value === false);
- const isDisabled = value !== undefined && !isValueBoolean;
- const isChecked = value !== undefined ? Boolean(value) : (property.defaultValue !== undefined && ['true', true].includes(property.defaultValue))
+ function getSwitch(property: ComponentProperty) {
+ const isValueBoolean = (textValue?.toString() === 'true' || textValue?.toString() === 'false');
+ const isDisabled = textValue?.toString().includes("{") || textValue?.toString().includes("}")
+ const isChecked = textValue !== undefined ? Boolean(textValue) : (property.defaultValue !== undefined && ['true', true].includes(property.defaultValue))
return (
<TextInputGroup className="input-group">
<InputGroupItem>
<Switch
id={id} name={id}
- value={value?.toString()}
isDisabled={isDisabled}
className="switch-placeholder"
aria-label={id}
isChecked={isChecked}
- onChange={(e, checked) => parametersChanged(property.name, checked)}/>
+ value={textValue?.toString()}
+ onChange={(_, v) => {
+ setTextValue(v);
+ parametersChanged(property.name, v);
+ setCheckChanges(true);
+ }}/>
</InputGroupItem>
<InputGroupItem isFill>
<TextInput
@@ -340,12 +378,20 @@ export function ComponentPropertyField(props: Props) {
name={property.name + "-placeholder"}
type="text"
aria-label="placeholder"
- value={!isValueBoolean ? value?.toString() : undefined}
- onChange={(_, v) => parametersChanged(property.name, v)}
+ value={!isValueBoolean ? textValue?.toString() : undefined}
+ onBlur={_ => onParametersChange(property.name, textValue)}
+ onChange={(_, v) => {
+ setTextValue(v);
+ setCheckChanges(true);
+ }}
/>
</InputGroupItem>
<InputGroupItem>
- <PropertyPlaceholderDropdown property={property} value={value} onComponentPropertyChange={onParametersChange}/>
+ <PropertyPlaceholderDropdown property={property} value={value} onDslPropertyChange={(_, v) => {
+ setTextValue(v);
+ onParametersChange(property.name, v);
+ setCheckChanges(false);
+ }}/>
</InputGroupItem>
</TextInputGroup>
)
@@ -377,15 +423,15 @@ export function ComponentPropertyField(props: Props) {
}>
{canBeInternalUri(property) && getInternalUriSelect(property, value)}
{property.type === 'string' && property.enum === undefined && !canBeInternalUri(property)
- && getStringInput(property, value)}
+ && getStringInput(property)}
{['duration', 'integer', 'int', 'number'].includes(property.type) && property.enum === undefined && !canBeInternalUri(property)
- && getSpecialStringInput(property, value)}
+ && getSpecialStringInput(property)}
{['object'].includes(property.type) && !property.enum
&& getSelectBean(property, value)}
{['string', 'object'].includes(property.type) && property.enum
&& getSelect(property, value)}
{property.type === 'boolean'
- && getSwitch(property, value)}
+ && getSwitch(property)}
{getInfrastructureSelectorModal()}
</FormGroup>
)
diff --git a/karavan-designer/src/designer/property/property/DslPropertyField.tsx b/karavan-designer/src/designer/property/property/DslPropertyField.tsx
index 923b0e26..95bc3504 100644
--- a/karavan-designer/src/designer/property/property/DslPropertyField.tsx
+++ b/karavan-designer/src/designer/property/property/DslPropertyField.tsx
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import React, {useRef, useState} from 'react';
+import React, {useEffect, useRef, useState} from 'react';
import {
FormGroup,
TextInput,
@@ -99,9 +99,25 @@ export function DslPropertyField(props: Props) {
const [showEditor, setShowEditor] = useState<boolean>(false);
const [infrastructureSelector, setInfrastructureSelector] = useState<boolean>(false);
const [infrastructureSelectorProperty, setInfrastructureSelectorProperty] = useState<string | undefined>(undefined);
- const [customCode, setCustomCode] = useState<string | undefined>(undefined);
-
+ const [customCode, setCustomCode] = useState<string>('');
+ const [textValue, setTextValue] = useState<any>();
const ref = useRef<any>(null);
+ const [checkChanges, setCheckChanges] = useState<boolean>(false);
+
+ useEffect(()=> setTextValue(value), [])
+
+ useEffect(()=> {
+ if (checkChanges) {
+ const interval = setInterval(() => {
+ if (props.value !== textValue) {
+ propertyChanged(property.name, textValue);
+ }
+ }, 3000);
+ return () => {
+ clearInterval(interval)
+ }
+ }
+ }, [checkChanges, textValue])
function openSelect(propertyName: string, isExpanded: boolean) {
setSelectStatus(new Map<string, boolean>([[propertyName, isExpanded]]))
@@ -116,6 +132,7 @@ export function DslPropertyField(props: Props) {
}
function propertyChanged(fieldId: string, value: string | number | boolean | any, newRoute?: RouteToCreate) {
+ setCheckChanges(false);
if (fieldId === 'id' && CamelDefinitionApiExt.hasElementWithId(integration, value)) {
value = props.element;
}
@@ -224,14 +241,14 @@ export function DslPropertyField(props: Props) {
onSelect={selectInfrastructure}/>)
}
- function getStringInput(property: PropertyMeta, value: any) {
+ function getStringInput(property: PropertyMeta) {
const inInfrastructure = InfrastructureAPI.infrastructure !== 'local';
const noInfraSelectorButton = ["uri", "id", "description", "group"].includes(property.name);
const icon = InfrastructureAPI.infrastructure === 'kubernetes' ? KubernetesIcon("infra-button") : <DockerIcon/>
const isNumber = ['integer', 'number', 'duration'].includes(property.type);
const uriReadOnly = isUriReadOnly(property);
const showEditorButton = !uriReadOnly && !isNumber && !property.secret && !['id', 'description'].includes(property.name);
- return (<InputGroup>
+ return <InputGroup>
{inInfrastructure && !showEditor && !noInfraSelectorButton &&
<InputGroupItem>
<Tooltip position="bottom-end"
@@ -246,12 +263,16 @@ export function DslPropertyField(props: Props) {
<InputGroupItem isFill>
<TextInput ref={ref}
className="text-field" isRequired
- type={(property.secret ? "password" : "text")}
+ type={property.secret ? "password" : "text"}
id={property.name} name={property.name}
- value={value?.toString()}
+ value={textValue?.toString()}
customIcon={property.type !== 'string' ? <Text component={TextVariants.p}>{property.type}</Text> : undefined}
- onChange={(_, v) =>
- propertyChanged(property.name, v)}
+ onBlur={_ => propertyChanged(property.name, textValue)}
+ onFocus={_ => setCheckChanges(true)}
+ onChange={(_, v) => {
+ setTextValue(v);
+ setCheckChanges(true);
+ }}
readOnlyVariant={uriReadOnly? "default" : undefined}/>
</InputGroupItem>
}
@@ -275,14 +296,14 @@ export function DslPropertyField(props: Props) {
setShowEditor(false);
}}/>
</InputGroupItem>}
- </InputGroup>)
+ </InputGroup>
}
function showCode(name: string, javaType: string) {
const {property} = props;
InfrastructureAPI.onGetCustomCode?.(name, property.javaType).then(value => {
if (value === undefined) {
- const code = TemplateApi.generateCode(property.javaType, name);
+ const code = TemplateApi.generateCode(property.javaType, name) || '';
setCustomCode(code);
setShowEditor(true);
} else {
@@ -343,8 +364,13 @@ export function DslPropertyField(props: Props) {
id={property.name}
name={property.name}
height={"100px"}
- value={value?.toString()}
- onChange={(_, v) => propertyChanged(property.name, v)}/>
+ value={textValue?.toString()}
+ onBlur={_ => propertyChanged(property.name, textValue)}
+ onChange={(_, v) => {
+ setTextValue(v);
+ setCheckChanges(true);
+ }}
+ />
</InputGroupItem>
<InputGroupItem>
<Tooltip position="bottom-end" content={"Show Editor"}>
@@ -391,13 +417,13 @@ export function DslPropertyField(props: Props) {
)
}
- function getBooleanInput(property: PropertyMeta, value: any) {
- const isValueBoolean = (value === true || value === false);
- const isDisabled = value !== undefined && !isValueBoolean;
+ function getBooleanInput(property: PropertyMeta) {
+ const isValueBoolean = (textValue?.toString() === 'true' || textValue?.toString() === 'false');
+ const isDisabled = textValue?.toString().includes("{") || textValue?.toString().includes("}")
let isChecked = false;
- if (value !== undefined && isValueBoolean) {
- isChecked = Boolean(value);
- } else if ((value === undefined || value.toString().length > 0) && property.defaultValue !== undefined) {
+ if (textValue !== undefined && isValueBoolean) {
+ isChecked = Boolean(textValue);
+ } else if ((textValue === undefined || textValue.toString().length > 0) && property.defaultValue !== undefined) {
isChecked = property.defaultValue === 'true';
}
return (
@@ -408,10 +434,14 @@ export function DslPropertyField(props: Props) {
id={property.name + "-switch"}
name={property.name + "-switch"}
className="switch-placeholder"
- value={value?.toString()}
+ value={textValue?.toString()}
aria-label={property.name}
isChecked={isChecked}
- onChange={(_, v) => propertyChanged(property.name, v)}/>
+ onChange={(_, v) => {
+ setTextValue(v);
+ propertyChanged(property.name, v);
+ setCheckChanges(false);
+ }}/>
</InputGroupItem>
<InputGroupItem isFill>
<TextInput
@@ -419,12 +449,20 @@ export function DslPropertyField(props: Props) {
name={property.name + "-placeholder"}
type="text"
aria-label="placeholder"
- value={!isValueBoolean ? value?.toString() : undefined}
- onChange={(_, v) => propertyChanged(property.name, v)}
+ value={!isValueBoolean ? textValue?.toString() : undefined}
+ onBlur={_ => propertyChanged(property.name, textValue)}
+ onChange={(_, v) => {
+ setTextValue(v);
+ setCheckChanges(true);
+ }}
/>
</InputGroupItem>
<InputGroupItem>
- <PropertyPlaceholderDropdown property={property} value={value} onDslPropertyChange={propertyChanged}/>
+ <PropertyPlaceholderDropdown property={property} value={value} onDslPropertyChange={(_, v, newRoute) => {
+ setTextValue(v);
+ propertyChanged(property.name, v, newRoute);
+ setCheckChanges(false);
+ }}/>
</InputGroupItem>
</TextInputGroup>
)
@@ -830,13 +868,13 @@ export function DslPropertyField(props: Props) {
&& !canBeInternalUri(property, element)
&& !canBeMediaType(property, element)
&& !javaTypeGenerated(property)
- && getStringInput(property, value)}
+ && getStringInput(property)}
{['string'].includes(property.type) && property.name.endsWith("Ref") && !property.isArray && !property.enumVals
&& getSelectBean(property, value)}
{isMultiValueField(property)
&& getMultiValueField(property, value)}
{property.type === 'boolean'
- && getBooleanInput(property, value)}
+ && getBooleanInput(property)}
{property.enumVals
&& getSelect(property, value)}
{isKamelet && property.name === 'parameters' && getKameletParameters()}