) => (
-
-
-
-
-
- {!!inputValue && (
-
- )}
-
-
-
- );
-
return (
- dataFormatCatalogMap && (
-
-
- setIsExpanded(!isExpanded)}>
- Data Format
-
-
-
-
- {dataFormat && (
- handleOnChange(dataFormat.model.name, model)}
- />
- )}
-
-
-
-
- )
+
+
+
+ Data Format
+
+
+
+
+
+
+
+
);
};
diff --git a/packages/ui/src/components/Form/dataFormat/dataformat.service.ts b/packages/ui/src/components/Form/dataFormat/dataformat.service.ts
index 41f0b6691..53ac8dfdf 100644
--- a/packages/ui/src/components/Form/dataFormat/dataformat.service.ts
+++ b/packages/ui/src/components/Form/dataFormat/dataformat.service.ts
@@ -68,7 +68,7 @@ export class DataFormatService {
}
}
- private static getDefinitionFromModelName(
+ static getDefinitionFromModelName(
dataFormatCatalogMap: Record,
modelName: string,
): ICamelDataformatDefinition | undefined {
diff --git a/packages/ui/src/components/Form/expression/ExpressionEditor.scss b/packages/ui/src/components/Form/expression/ExpressionEditor.scss
index d979da493..e4140b972 100644
--- a/packages/ui/src/components/Form/expression/ExpressionEditor.scss
+++ b/packages/ui/src/components/Form/expression/ExpressionEditor.scss
@@ -3,6 +3,6 @@
overflow-y: auto;
}
-.metadata-editor {
+.pf-v5-c-form {
margin-top: 24px;
}
diff --git a/packages/ui/src/components/Form/expression/ExpressionEditor.tsx b/packages/ui/src/components/Form/expression/ExpressionEditor.tsx
index 4d3eb86a6..3cacb06a6 100644
--- a/packages/ui/src/components/Form/expression/ExpressionEditor.tsx
+++ b/packages/ui/src/components/Form/expression/ExpressionEditor.tsx
@@ -1,22 +1,9 @@
-import {
- Button,
- MenuToggle,
- MenuToggleElement,
- Select,
- SelectList,
- SelectOption,
- SelectOptionProps,
- TextInputGroup,
- TextInputGroupMain,
- TextInputGroupUtilities,
-} from '@patternfly/react-core';
-import { TimesIcon } from '@patternfly/react-icons';
-import { FunctionComponent, useCallback, useEffect, useMemo, useRef, useState } from 'react';
+import { SelectOptionProps } from '@patternfly/react-core';
+import { FunctionComponent, useCallback, useMemo, useState } from 'react';
import { ICamelLanguageDefinition } from '../../../models';
-import { MetadataEditor } from '../../MetadataEditor';
-import { SchemaService } from '../schema.service';
import './ExpressionEditor.scss';
import { ExpressionService } from './expression.service';
+import { TypeaheadEditor } from '../customField/TypeaheadEditor';
interface ExpressionEditorProps {
language?: ICamelLanguageDefinition;
@@ -41,216 +28,37 @@ export const ExpressionEditor: FunctionComponent = ({
});
}, []);
- const [isOpen, setIsOpen] = useState(false);
- const [inputValue, setInputValue] = useState(language?.model.title || '');
- const [filterValue, setFilterValue] = useState('');
- const [selectOptions, setSelectOptions] = useState(languageCatalogMap);
- const [focusedItemIndex, setFocusedItemIndex] = useState(null);
- const [activeItem, setActiveItem] = useState(null);
- const textInputRef = useRef();
- const [selected, setSelected] = useState(language?.model.title || '');
+ const languageOption = language && {
+ name: language!.model.name,
+ title: language!.model.title,
+ };
+ const [selectedLanguageOption, setSelectedLanguageOption] = useState<{ name: string; title: string } | undefined>(
+ languageOption,
+ );
const languageSchema = useMemo(() => {
return language && ExpressionService.getLanguageSchema(language);
}, [language]);
- const onSelect = useCallback(
- (_event: React.MouseEvent | undefined, value: string | number | undefined) => {
- const model = languageCatalogMap.find((model) => model.children === value);
- if (model && value !== 'no results') {
- setInputValue(value as string);
- setFilterValue('');
- onChangeExpressionModel(model!.value as string, {});
- setSelected(model!.children as string);
- }
- setIsOpen(false);
- setFocusedItemIndex(null);
- setActiveItem(null);
+ const handleOnChange = useCallback(
+ (
+ selectedLanguageOption: { name: string; title: string } | undefined,
+ newlanguageModel: Record,
+ ) => {
+ setSelectedLanguageOption(selectedLanguageOption);
+ onChangeExpressionModel(selectedLanguageOption ? selectedLanguageOption!.name : '', newlanguageModel);
},
- [languageCatalogMap, onChangeExpressionModel],
- );
-
- const onToggleClick = useCallback(() => {
- setIsOpen(!isOpen);
- }, [isOpen]);
-
- useEffect(() => {
- let newSelectOptions: SelectOptionProps[] = languageCatalogMap;
-
- // Filter menu items based on the text input value when one exists
- if (filterValue) {
- const lowerFilterValue = filterValue.toLowerCase();
- newSelectOptions = languageCatalogMap.filter((menuItem) => {
- return (
- String(menuItem.value).toLowerCase().includes(lowerFilterValue) ||
- String(menuItem.children).toLowerCase().includes(lowerFilterValue) ||
- String(menuItem.description).toLowerCase().includes(lowerFilterValue)
- );
- });
- // When no options are found after filtering, display 'No results found'
- if (!newSelectOptions.length) {
- newSelectOptions = [
- { isDisabled: false, children: `No results found for "${filterValue}"`, value: 'no results' },
- ];
- }
- // Open the menu when the input value changes and the new value is not empty
- if (!isOpen) {
- setIsOpen(true);
- }
- }
-
- setSelectOptions(newSelectOptions);
- setActiveItem(null);
- setFocusedItemIndex(null);
- }, [filterValue, isOpen, languageCatalogMap]);
-
- const onTextInputChange = (_event: React.FormEvent, value: string) => {
- setInputValue(value);
- setFilterValue(value);
- };
-
- const handleMenuArrowKeys = (key: string) => {
- let indexToFocus;
-
- if (isOpen) {
- if (key === 'ArrowUp') {
- // When no index is set or at the first index, focus to the last, otherwise decrement focus index
- if (focusedItemIndex === null || focusedItemIndex === 0) {
- indexToFocus = selectOptions.length - 1;
- } else {
- indexToFocus = focusedItemIndex - 1;
- }
- }
-
- if (key === 'ArrowDown') {
- // When no index is set or at the last index, focus to the first, otherwise increment focus index
- if (focusedItemIndex === null || focusedItemIndex === selectOptions.length - 1) {
- indexToFocus = 0;
- } else {
- indexToFocus = focusedItemIndex + 1;
- }
- }
-
- setFocusedItemIndex(indexToFocus!);
- const focusedItem = selectOptions.filter((option) => !option.isDisabled)[indexToFocus!];
- setActiveItem(`select-typeahead-${focusedItem.value.replace(' ', '-')}`);
- }
- };
-
- const onInputKeyDown = (event: React.KeyboardEvent) => {
- const enabledMenuItems = selectOptions.filter((option) => !option.isDisabled);
- const [firstMenuItem] = enabledMenuItems;
- const focusedItem = focusedItemIndex ? enabledMenuItems[focusedItemIndex] : firstMenuItem;
-
- switch (event.key) {
- // Select the first available option
- case 'Enter':
- if (isOpen && focusedItem.value !== 'no results') {
- setInputValue(String(focusedItem.children));
- setFilterValue('');
- setSelected(String(focusedItem.children));
- }
-
- setIsOpen((prevIsOpen) => !prevIsOpen);
- setFocusedItemIndex(null);
- setActiveItem(null);
- break;
- case 'Tab':
- case 'Escape':
- setIsOpen(false);
- setActiveItem(null);
- break;
- case 'ArrowUp':
- case 'ArrowDown':
- event.preventDefault();
- handleMenuArrowKeys(event.key);
- break;
- }
- };
-
- const toggle = (toggleRef: React.Ref) => (
-
-
-
-
-
- {!!inputValue && (
-
- )}
-
-
-
+ [languageCatalogMap],
);
return (
- languageCatalogMap && (
- <>
-
- {language && (
-
- onChangeExpressionModel(language.model.name, model)}
- />
-
- )}
- >
- )
+
);
};
diff --git a/packages/ui/src/components/Form/loadBalancer/LoadBalancerEditor.scss b/packages/ui/src/components/Form/loadBalancer/LoadBalancerEditor.scss
index e1115b4ba..c3f1518d6 100644
--- a/packages/ui/src/components/Form/loadBalancer/LoadBalancerEditor.scss
+++ b/packages/ui/src/components/Form/loadBalancer/LoadBalancerEditor.scss
@@ -1,3 +1,9 @@
-.load-balancer-editor {
- margin-top: 24px;
+.loadbalancer-metadata-editor {
+ .pf-v5-c-card {
+ margin-bottom: 24px;
+ }
+
+ .pf-v5-c-form {
+ margin-top: 24px;
+ }
}
diff --git a/packages/ui/src/components/Form/loadBalancer/LoadBalancerEditor.tsx b/packages/ui/src/components/Form/loadBalancer/LoadBalancerEditor.tsx
index 35c074270..3232f14c7 100644
--- a/packages/ui/src/components/Form/loadBalancer/LoadBalancerEditor.tsx
+++ b/packages/ui/src/components/Form/loadBalancer/LoadBalancerEditor.tsx
@@ -1,54 +1,30 @@
import {
- Button,
Card,
CardBody,
CardExpandableContent,
CardHeader,
CardTitle,
- MenuToggle,
- MenuToggleElement,
- Select,
- SelectList,
- SelectOption,
SelectOptionProps,
- TextInputGroup,
- TextInputGroupMain,
- TextInputGroupUtilities,
} from '@patternfly/react-core';
-import { FunctionComponent, Ref, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
+import { FunctionComponent, useCallback, useContext, useMemo, useState } from 'react';
import { EntitiesContext } from '../../../providers';
-import { MetadataEditor } from '../../MetadataEditor';
import { CanvasNode } from '../../Visualization/Canvas/canvas.models';
import { LoadBalancerService } from './loadbalancer.service';
-import { SchemaService } from '../schema.service';
import './LoadBalancerEditor.scss';
-import { TimesIcon } from '@patternfly/react-icons';
+import { TypeaheadEditor } from '../customField/TypeaheadEditor';
+
interface LoadBalancerEditorProps {
selectedNode: CanvasNode;
}
export const LoadBalancerEditor: FunctionComponent = (props) => {
const entitiesContext = useContext(EntitiesContext);
- const [isOpen, setIsOpen] = useState(false);
- const [isExpanded, setIsExpanded] = useState(true);
const loadBalancerCatalogMap = useMemo(() => {
return LoadBalancerService.getLoadBalancerMap();
}, []);
- const visualComponentSchema = props.selectedNode.data?.vizNode?.getComponentSchema();
- if (visualComponentSchema) {
- if (!visualComponentSchema.definition) {
- visualComponentSchema.definition = {};
- }
- }
- const { loadBalancer, model: loadBalancerModel } = LoadBalancerService.parseLoadBalancerModel(
- loadBalancerCatalogMap,
- visualComponentSchema?.definition,
- );
- const [selected, setSelected] = useState(loadBalancer?.model.name || '');
- const [inputValue, setInputValue] = useState(loadBalancer?.model.title || '');
- const initialLoadBalancerOptions = useMemo(() => {
+ const initialLoadBalancerOptions: SelectOptionProps[] = useMemo(() => {
return Object.values(loadBalancerCatalogMap).map((option) => {
return {
value: option.model.name,
@@ -57,62 +33,41 @@ export const LoadBalancerEditor: FunctionComponent = (p
};
});
}, [loadBalancerCatalogMap]);
- const [selectOptions, setSelectOptions] = useState(initialLoadBalancerOptions);
- const [focusedItemIndex, setFocusedItemIndex] = useState(null);
- const [activeItem, setActiveItem] = useState(null);
- const [filterValue, setFilterValue] = useState('');
- const textInputRef = useRef();
- useEffect(() => {
- loadBalancer ? setSelected(loadBalancer.model.name) : setSelected('');
- }, [loadBalancer]);
-
- useEffect(() => {
- let newSelectOptions: SelectOptionProps[] = initialLoadBalancerOptions;
-
- // Filter menu items based on the text input value when one exists
- if (filterValue) {
- const lowerFilterValue = filterValue.toLowerCase();
- newSelectOptions = initialLoadBalancerOptions.filter((menuItem) => {
- return (
- String(menuItem.value).toLowerCase().includes(lowerFilterValue) ||
- String(menuItem.children).toLowerCase().includes(lowerFilterValue) ||
- String(menuItem.description).toLowerCase().includes(lowerFilterValue)
- );
- });
- // When no options are found after filtering, display 'No results found'
- if (!newSelectOptions.length) {
- newSelectOptions = [
- { isDisabled: false, children: `No results found for "${filterValue}"`, value: 'no results' },
- ];
- }
- // Open the menu when the input value changes and the new value is not empty
- if (!isOpen) {
- setIsOpen(true);
- }
+ const visualComponentSchema = props.selectedNode.data?.vizNode?.getComponentSchema();
+ if (visualComponentSchema) {
+ if (!visualComponentSchema.definition) {
+ visualComponentSchema.definition = {};
}
-
- setSelectOptions(newSelectOptions);
- setActiveItem(null);
- setFocusedItemIndex(null);
- }, [filterValue, initialLoadBalancerOptions, isOpen]);
+ }
+ const { loadBalancer, model: loadBalancerModel } = LoadBalancerService.parseLoadBalancerModel(
+ loadBalancerCatalogMap,
+ visualComponentSchema?.definition,
+ );
+ const loadBalancerOption = loadBalancer && {
+ name: loadBalancer!.model.name,
+ title: loadBalancer!.model.title,
+ };
+ const [selectedLoadBalancerOption, setSelectedLoadBalancerOption] = useState<
+ { name: string; title: string } | undefined
+ >(loadBalancerOption);
const loadBalancerSchema = useMemo(() => {
return LoadBalancerService.getLoadBalancerSchema(loadBalancer);
}, [loadBalancer]);
- const onToggleClick = useCallback(() => {
- setIsOpen(!isOpen);
- }, [isOpen]);
-
const handleOnChange = useCallback(
- (selectedLoadBalancer: string, newLoadBalancerModel: Record) => {
+ (
+ selectedLoadBalancerOption: { name: string; title: string } | undefined,
+ newLoadBalancerModel: Record,
+ ) => {
+ setSelectedLoadBalancerOption(selectedLoadBalancerOption);
const model = props.selectedNode.data?.vizNode?.getComponentSchema()?.definition;
if (!model) return;
LoadBalancerService.setLoadBalancerModel(
loadBalancerCatalogMap,
model,
- selectedLoadBalancer,
+ selectedLoadBalancerOption ? selectedLoadBalancerOption!.name : '',
newLoadBalancerModel,
);
props.selectedNode.data?.vizNode?.updateModel(model);
@@ -121,176 +76,25 @@ export const LoadBalancerEditor: FunctionComponent = (p
[entitiesContext, loadBalancerCatalogMap, props.selectedNode.data?.vizNode],
);
- const onSelect = useCallback(
- (_event: React.MouseEvent | undefined, value: string | number | undefined) => {
- const option = selectOptions.find((option) => option.children === value);
- if (option && value !== 'no results') {
- setInputValue(value as string);
- setFilterValue('');
- handleOnChange(option!.value as string, {});
- setSelected(option!.children as string);
- }
- setIsOpen(false);
- setFocusedItemIndex(null);
- setActiveItem(null);
- },
- [handleOnChange, selectOptions],
- );
-
- const onTextInputChange = (_event: React.FormEvent, value: string) => {
- setInputValue(value);
- setFilterValue(value);
- };
-
- const handleMenuArrowKeys = (key: string) => {
- let indexToFocus;
-
- if (isOpen) {
- if (key === 'ArrowUp') {
- // When no index is set or at the first index, focus to the last, otherwise decrement focus index
- if (focusedItemIndex === null || focusedItemIndex === 0) {
- indexToFocus = selectOptions.length - 1;
- } else {
- indexToFocus = focusedItemIndex - 1;
- }
- }
-
- if (key === 'ArrowDown') {
- // When no index is set or at the last index, focus to the first, otherwise increment focus index
- if (focusedItemIndex === null || focusedItemIndex === selectOptions.length - 1) {
- indexToFocus = 0;
- } else {
- indexToFocus = focusedItemIndex + 1;
- }
- }
-
- setFocusedItemIndex(indexToFocus!);
- const focusedItem = selectOptions.filter((option) => !option.isDisabled)[indexToFocus!];
- setActiveItem(`select-typeahead-${focusedItem.value.replace(' ', '-')}`);
- }
- };
-
- const onInputKeyDown = (event: React.KeyboardEvent) => {
- const enabledMenuItems = selectOptions.filter((option) => !option.isDisabled);
- const [firstMenuItem] = enabledMenuItems;
- const focusedItem = focusedItemIndex ? enabledMenuItems[focusedItemIndex] : firstMenuItem;
-
- switch (event.key) {
- // Select the first available option
- case 'Enter':
- if (isOpen && focusedItem.value !== 'no results') {
- setInputValue(String(focusedItem.children));
- setFilterValue('');
- setSelected(String(focusedItem.children));
- }
-
- setIsOpen((prevIsOpen) => !prevIsOpen);
- setFocusedItemIndex(null);
- setActiveItem(null);
- break;
- case 'Tab':
- case 'Escape':
- setIsOpen(false);
- setActiveItem(null);
- break;
- case 'ArrowUp':
- case 'ArrowDown':
- event.preventDefault();
- handleMenuArrowKeys(event.key);
- break;
- }
- };
-
- const toggle = (toggleRef: Ref) => (
-
-
-
-
-
- {!!inputValue && (
-
- )}
-
-
-
- );
-
return (
- loadBalancerCatalogMap && (
-
- setIsExpanded(!isExpanded)}>
+
+
+
Load Balancer
-
- {loadBalancer && (
-
- handleOnChange(loadBalancer.model.name, model)}
- />
-
- )}
+
- )
+
);
};
diff --git a/packages/ui/src/components/Form/loadBalancer/loadbalancer.service.ts b/packages/ui/src/components/Form/loadBalancer/loadbalancer.service.ts
index 1855ca20c..56a6017a5 100644
--- a/packages/ui/src/components/Form/loadBalancer/loadbalancer.service.ts
+++ b/packages/ui/src/components/Form/loadBalancer/loadbalancer.service.ts
@@ -68,7 +68,7 @@ export class LoadBalancerService {
}
}
- private static getDefinitionFromModelName(
+ static getDefinitionFromModelName(
loadBalancerCatalogMap: Record,
modelName: string,
): ICamelLoadBalancerDefinition | undefined {