Skip to content

Commit

Permalink
Refactor rule-condition component to fix unexpected API callings
Browse files Browse the repository at this point in the history
  • Loading branch information
jeradrutnam committed Jan 12, 2025
1 parent fa020aa commit c7926f8
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ const RulesProperties: FunctionComponent<RulesPropertiesPropsInterface> = ({
/* eslint-disable @typescript-eslint/no-unused-vars */
const handleGetRuleValue = () => {
const ruleValue: RuleExecuteCollectionInterface = getRuleInstanceValue();

// eslint-disable-next-line no-console
console.log(ruleValue);
};
/* eslint-enable @typescript-eslint/no-unused-vars */

Expand Down
182 changes: 103 additions & 79 deletions features/admin.rules.v1/components/rule-conditions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,10 @@ import "./rules-component.scss";
* Value input autocomplete props interface.
*/
interface ValueInputAutocompleteProps {
metaValue: ExpressionValueInterface;
localValue: string;
resourceType: string;
initialResourcesLoadUrl: string;
filterBaseResourcesUrl: string;
}

/**
Expand All @@ -65,6 +67,11 @@ interface ConditionValueInputProps {
metaValue: ExpressionValueInterface;
}

interface ResourceListSelectProps {
initialResourcesLoadUrl: string;
filterBaseResourcesUrl: string;
}

/**
* Props interface of {@link RulesComponent}
*/
Expand Down Expand Up @@ -110,26 +117,9 @@ const RuleConditions: FunctionComponent<RulesComponentPropsInterface> = ({
index: number;
isConditionExpressionRemovable: boolean;
}) => {
const [ localField, setLocalField ] = useState<string>(expression.field);
const [ localOperator, setLocalOperator ] = useState<string>(expression.operator);
const [ localValue, setLocalValue ] = useState<string>(expression.value);

const [ metaOperators, setMetaOperators ] =
useState<ListDataInterface[]>(conditionExpressionsMeta[0]?.operators);
const [ metaValue, setMetaValue ] = useState<ExpressionValueInterface>(conditionExpressionsMeta[0]?.value);

useEffect(() => {
conditionExpressionsMeta?.map((expressionMeta: ConditionExpressionMetaInterface) => {
if (expressionMeta.field.name === localField) {
setMetaOperators(expressionMeta.operators);
setMetaValue(expressionMeta.value);

return;
}

return;
});
}, [ localField ]);
const findMetaValuesAgainst: ConditionExpressionMetaInterface = conditionExpressionsMeta.find(
(expressionMeta: ConditionExpressionMetaInterface) => expressionMeta.field.name === expression.field
);

/**
* Debounced function to handle the change of the condition expression.
Expand Down Expand Up @@ -168,19 +158,20 @@ const RuleConditions: FunctionComponent<RulesComponentPropsInterface> = ({
* @returns Value input autocomplete component.
*/
const ValueInputAutocomplete: FunctionComponent<ValueInputAutocompleteProps> = ({
metaValue,
resourceType
localValue,
resourceType,
initialResourcesLoadUrl,
filterBaseResourcesUrl
}: ValueInputAutocompleteProps) => {
const [ inputValue, setInputValue ] = useState<string>(localValue);
const [ options, setOptions ] = useState([]);
const [ open, setOpen ] = useState<boolean>(false);

const initialLoadUrl: string = metaValue?.links.find((link: LinkInterface) => link.rel === "values")?.href;
const filterBaseUrl: string = metaValue?.links.find((link: LinkInterface) => link.rel === "filter")?.href;
const filterUrl: string = inputValue ? filterBaseUrl?.replace("*", inputValue) : null;

const { data: initialResources = [], isLoading: isInitialLoading } = useGetResourcesList(initialLoadUrl);

const filterUrl: string = inputValue ?
filterBaseResourcesUrl?.replace("*", inputValue) : initialResourcesLoadUrl;
const { data: initialResources = [], isLoading: isInitialLoading } = useGetResourcesList(
initialResourcesLoadUrl
);
const { data: filteredResources = [], isLoading: isFiltering } = useGetResourcesList(filterUrl);

useEffect(() => {
Expand All @@ -203,10 +194,11 @@ const RuleConditions: FunctionComponent<RulesComponentPropsInterface> = ({
options={ options || [] }
getOptionLabel={ (option: { name: string }) => option.name || "" }
loading={ isInitialLoading || isFiltering }
value={ options.find((option: any) => option.name === inputValue) || null }
value={ (options || []).some((option: any) => option.name === inputValue)
? options.find((option: any) => option.name === inputValue)
: null }
onChange={ (event: React.SyntheticEvent, value: { name: string } | null) => {
if (value) {
setLocalValue(value.name);
handleExpressionChangeDebounced(
value.name,
ruleId,
Expand Down Expand Up @@ -235,44 +227,87 @@ const RuleConditions: FunctionComponent<RulesComponentPropsInterface> = ({
} }
/>
) }
renderOption={ (props: any, option: { name: string }) => (
<li { ...props } key={ option.name }>
{ option.name }
</li>
) }
/>
);
};

/**
* Condition value input component.
* Resource list select component.
*
* @param metaValue - Meta value.
* @returns Condition value input component.
* @returns Resource list select component.
*/
const ConditionValueInput: FunctionComponent<ConditionValueInputProps> = (props: any) => {
const { metaValue } = props;
const ResourceListSelect: FunctionComponent<ResourceListSelectProps> = (props: any) => {
const { initialResourcesLoadUrl, filterBaseResourcesUrl } = props;

let resourcesList: any = null;
let resourceType: string = "";

// Handle fetching data unconditionally
const resourcesListLink: string = metaValue?.links?.find((link: LinkInterface) => link.rel === "values")
?.href;
const { data: fetchedResourcesList } = useGetResourcesList(initialResourcesLoadUrl);

const { data: fetchedResourcesList } = useGetResourcesList(resourcesListLink || null);
// Determine resourcesList if it's needed
if (findMetaValuesAgainst?.value?.links?.length > 1 && fetchedResourcesList) {
resourcesList = fetchedResourcesList;
}

// TODO: Handle other resource types once the API is ready
if (localField === "application") {
if (expression.field === "application") {
resourceType = "applications";
}

// Determine resourcesList if it's needed
if (metaValue?.links?.length > 1 && fetchedResourcesList) {
resourcesList = fetchedResourcesList;
if (resourcesList) {
if (resourcesList.count < 10) {
return (
<ValueInputAutocomplete
localValue={ expression.value }
resourceType={ resourceType }
initialResourcesLoadUrl={ initialResourcesLoadUrl }
filterBaseResourcesUrl={ filterBaseResourcesUrl }
/>
);
}

return (
<Select
value={ expression.value }
onChange={ (e: SelectChangeEvent) => {
updateConditionExpression(
e.target.value,
ruleId,
conditionId,
expression.id,
ExpressionFieldTypes.Value
);
} }
>
{ resourcesList[resourceType]?.map((item: any, index: number) => (
<MenuItem value={ item.id } key={ `${expression.id}-${index}` }>
{ item.name }
</MenuItem>
)) }
</Select>
);
}
};

if (metaValue?.inputType === "input") {
/**
* Condition value input component.
*
* @param metaValue - Meta value.
* @returns Condition value input component.
*/
const ConditionValueInput: FunctionComponent<ConditionValueInputProps> = (props: any) => {
const { metaValue } = props;

if (metaValue?.inputType === "input" || null) {
return (
<TextField
value={ localValue }
value={ expression.value }
onChange={ (e: React.ChangeEvent<HTMLInputElement>) => {
setLocalValue(e.target.value);
handleExpressionChangeDebounced(
e.target.value,
ruleId,
Expand All @@ -289,9 +324,8 @@ const RuleConditions: FunctionComponent<RulesComponentPropsInterface> = ({
if (metaValue?.values?.length > 1) {
return (
<Select
value={ localValue }
value={ expression.value }
onChange={ (e: SelectChangeEvent) => {
setLocalValue(e.target.value);
updateConditionExpression(
e.target.value,
ruleId,
Expand All @@ -310,32 +344,24 @@ const RuleConditions: FunctionComponent<RulesComponentPropsInterface> = ({
);
}

if (resourcesList) {
if (resourcesList.count > 10) {
return <ValueInputAutocomplete metaValue={ metaValue } resourceType={ resourceType } />;
if (metaValue?.links?.length > 1) {
const initialResourcesLoadUrl: string = metaValue?.links.find(
(link: LinkInterface) => link.rel === "values"
)?.href;
const filterBaseResourcesUrl: string = metaValue?.links.find(
(link: LinkInterface) => link.rel === "filter"
)?.href;

if (initialResourcesLoadUrl && filterBaseResourcesUrl) {
return (
<ResourceListSelect
initialResourcesLoadUrl={ initialResourcesLoadUrl }
filterBaseResourcesUrl={ filterBaseResourcesUrl }
/>
);
}

return (
<Select
value={ localValue }
onChange={ (e: SelectChangeEvent) => {
setLocalValue(e.target.value);
updateConditionExpression(
e.target.value,
ruleId,
conditionId,
expression.id,
ExpressionFieldTypes.Value
);
} }
>
{ resourcesList[resourceType]?.map((item: any, index: number) => (
<MenuItem value={ item.id } key={ `${expression.id}-${index}` }>
{ item.name }
</MenuItem>
)) }
</Select>
);
return null;
}

return null;
Expand All @@ -353,9 +379,8 @@ const RuleConditions: FunctionComponent<RulesComponentPropsInterface> = ({
>
<FormControl fullWidth size="small">
<Select
value={ localField }
value={ expression.field }
onChange={ (e: SelectChangeEvent) => {
setLocalField(e.target.value);
updateConditionExpression(
e.target.value,
ruleId,
Expand All @@ -381,9 +406,8 @@ const RuleConditions: FunctionComponent<RulesComponentPropsInterface> = ({
</FormControl>
<FormControl sx={ { mb: 1, minWidth: 120, mt: 1 } } size="small">
<Select
value={ localOperator }
value={ expression.operator }
onChange={ (e: SelectChangeEvent) => {
setLocalOperator(e.target.value);
updateConditionExpression(
e.target.value,
ruleId,
Expand All @@ -393,15 +417,15 @@ const RuleConditions: FunctionComponent<RulesComponentPropsInterface> = ({
);
} }
>
{ metaOperators?.map((item: ListDataInterface, index: number) => (
{ findMetaValuesAgainst?.operators?.map((item: ListDataInterface, index: number) => (
<MenuItem value={ item.name } key={ `${expression.id}-${index}` }>
{ item.displayName }
</MenuItem>
)) }
</Select>
</FormControl>
<FormControl fullWidth size="small">
<ConditionValueInput metaValue={ metaValue } />
<ConditionValueInput metaValue={ findMetaValuesAgainst?.value } />
</FormControl>
<FormControl sx={ { mt: 1 } } size="small">
<Button
Expand Down

0 comments on commit c7926f8

Please sign in to comment.