chore: add hybrid search control (#39258)
## Description Add hybrid search control for UQI forms.  Example of usage: ``` { "isRequired": false, "configProperty": "actionConfiguration.formData.hybridSearch", "controlType": "HYBRID_SEARCH", "initialValue": { "isEnabled": true, "keywordWeight": 0.5, "semanticWeight": 0.5 } } ``` Fixes https://github.com/appsmithorg/appsmith/issues/39236 ## Automation /ok-to-test tags="@tag.Datasource" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/13324291818> > Commit: 9495722fe3224474db772890f31730becfa45d79 > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=13324291818&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.Datasource` > Spec: > <hr>Fri, 14 Feb 2025 07:52:38 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [x] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced a new hybrid search control in the form. Users can now easily adjust search parameters with intuitive sliders for keyword and semantic weights, along with a toggle to activate or deactivate hybrid search. - Added a new control type for hybrid search to the form control registry, enhancing the flexibility of form configurations. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
23b2b9256e
commit
0e67bbc68c
78
app/client/src/components/formControls/HybridSearch.tsx
Normal file
78
app/client/src/components/formControls/HybridSearch.tsx
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
import React from "react";
|
||||
import { Field, type WrappedFieldInputProps } from "redux-form";
|
||||
import BaseControl from "./BaseControl";
|
||||
import type { ControlProps } from "./BaseControl";
|
||||
import { Slider, type SliderProps, Flex, Switch, Text } from "@appsmith/ads";
|
||||
|
||||
export interface HybridSearchControlProps
|
||||
extends ControlProps,
|
||||
Omit<SliderProps, "id" | "label"> {}
|
||||
|
||||
export class HybridSearchControl extends BaseControl<HybridSearchControlProps> {
|
||||
render() {
|
||||
const { configProperty, ...rest } = this.props;
|
||||
|
||||
return (
|
||||
<Field
|
||||
component={renderHybridSearchControl}
|
||||
name={configProperty}
|
||||
props={{ ...rest }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
getControlType(): string {
|
||||
return "HYBRID_SEARCH";
|
||||
}
|
||||
}
|
||||
|
||||
const renderHybridSearchControl = (
|
||||
props: {
|
||||
input?: WrappedFieldInputProps;
|
||||
} & HybridSearchControlProps,
|
||||
) => {
|
||||
const { input } = props;
|
||||
|
||||
const onSliderChange = (value: number) => {
|
||||
input?.onChange({
|
||||
...input?.value,
|
||||
keywordWeight: value,
|
||||
semanticWeight: (10 - value * 10) / 10, // Scale by 10 to avoid floating-point issues
|
||||
});
|
||||
};
|
||||
const onSwitchChange = (value: boolean) => {
|
||||
input?.onChange({
|
||||
...input?.value,
|
||||
isEnabled: value,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Flex flexDirection="column" gap="spaces-4">
|
||||
<Flex width="150px">
|
||||
<Switch
|
||||
defaultSelected={input?.value.isEnabled}
|
||||
onChange={onSwitchChange}
|
||||
>
|
||||
Hybrid search
|
||||
</Switch>
|
||||
</Flex>
|
||||
<Flex flexDirection="column">
|
||||
<Slider
|
||||
getValueLabel={() => "Semantic weight"}
|
||||
isDisabled={!input?.value.isEnabled}
|
||||
label="Keyword weight"
|
||||
maxValue={1}
|
||||
minValue={0}
|
||||
onChange={onSliderChange}
|
||||
step={0.1}
|
||||
value={input?.value.keywordWeight}
|
||||
/>
|
||||
<Flex justifyContent="space-between">
|
||||
<Text>{input?.value.keywordWeight}</Text>
|
||||
<Text>{input?.value.semanticWeight}</Text>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
|
@ -45,6 +45,7 @@ import {
|
|||
SliderControl,
|
||||
type SliderControlProps,
|
||||
} from "components/formControls/SliderControl";
|
||||
import { HybridSearchControl } from "components/formControls/HybridSearch";
|
||||
|
||||
/**
|
||||
* NOTE: If you are adding a component that uses FormControl
|
||||
|
|
@ -225,6 +226,11 @@ class FormControlRegistry {
|
|||
},
|
||||
},
|
||||
);
|
||||
FormControlFactory.registerControlBuilder(formControlTypes.HYBRID_SEARCH, {
|
||||
buildPropertyControl(controlProps: SliderControlProps): JSX.Element {
|
||||
return <HybridSearchControl {...controlProps} />;
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,4 +22,5 @@ export default {
|
|||
RAG_INTEGRATIONS: "RAG_INTEGRATIONS",
|
||||
SLIDER: "SLIDER",
|
||||
RAG_DOCUMENTS_SELECTOR: "RAG_DOCUMENTS_SELECTOR",
|
||||
HYBRID_SEARCH: "HYBRID_SEARCH",
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user