chore: Add datasource link control (#39841)

/ok-to-test tags="@tag.Sanity"

This PR adds an datasource link control that is required to on query
page of AI datasource.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

- **New Features**
- Introduced a new form control that allows users to navigate directly
to datasource-related views.
- Enhanced forms with dynamic styling capabilities, enabling sections to
apply custom visual configurations.

- **Style**
- Adjusted the width of a key configuration button to improve layout
consistency.

- **Bug Fixes**
- Resolved issues related to the application of inline styles in form
components.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/13986086739>
> Commit: 456b2858fd9669ae8f683d34bf10261fc5a86228
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=13986086739&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Sanity`
> Spec:
> <hr>Fri, 21 Mar 2025 07:20:48 UTC
<!-- end of auto-generated comment: Cypress test results  -->
This commit is contained in:
Pawan Kumar 2025-03-21 13:23:44 +05:30 committed by GitHub
parent 51be07f485
commit db25d123da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 81 additions and 1 deletions

View File

@ -183,6 +183,7 @@ const FormRender = (props: Props) => {
<FieldWrapper
className="uqi-form-wrapper"
key={`${configProperty}_${idx}`}
style={{ ...(section.zoneCustomStyle || {}) }}
>
<FormControl config={modifiedSection} formName={formName} />
</FieldWrapper>
@ -221,7 +222,11 @@ const FormRender = (props: Props) => {
? "single_column"
: "double_column";
return <Zone layout={layout}>{children}</Zone>;
return (
<Zone layout={layout} style={{ ...(section.zoneCustomStyle || {}) }}>
{children}
</Zone>
);
}
default:
return children;

View File

@ -0,0 +1,59 @@
import React, { useCallback } from "react";
import omit from "lodash/omit";
import history from "utils/history";
import { Button, type ButtonProps } from "@appsmith/ads";
import type { ControlType } from "constants/PropertyControlConstants";
import BaseControl from "./BaseControl";
import type { ControlProps } from "./BaseControl";
import { useParentEntityInfo } from "ee/IDE/hooks/useParentEntityInfo";
import { getIDETypeByUrl } from "ee/entities/IDE/utils";
import { datasourcesEditorIdURL } from "ee/RouteBuilder";
import { getQueryParams } from "utils/URLUtils";
export interface DatasourceLinkControlProps extends ControlProps {
href: string;
text: string;
size?: ButtonProps["size"];
kind?: ButtonProps["kind"];
icon?: ButtonProps["startIcon"];
}
class DatasourceLinkControl extends BaseControl<DatasourceLinkControlProps> {
getControlType(): ControlType {
return "DATASOURCE_LINK";
}
render() {
return <DatasourceLink {...this.props} />;
}
}
function DatasourceLink(props: DatasourceLinkControlProps) {
const { icon, kind = "secondary", size = "sm", text } = props;
const ideType = getIDETypeByUrl(location.pathname);
const { parentEntityId } = useParentEntityInfo(ideType);
const onPress = useCallback(() => {
const url = datasourcesEditorIdURL({
baseParentEntityId: parentEntityId,
datasourceId: props.datasourceId as string,
params: { ...omit(getQueryParams(), "viewMode"), viewMode: false },
});
history.push(url);
}, [parentEntityId, props.datasourceId]);
return (
<Button
UNSAFE_width="110px"
kind={kind}
onClick={onPress}
size={size}
startIcon={icon}
>
{text}
</Button>
);
}
export { DatasourceLinkControl };

View File

@ -59,6 +59,7 @@ export const FunctionCallingConfigForm = ({
</div>
<Button
UNSAFE_width="110px"
kind="secondary"
onClick={handleAddFunctionButtonClick}
startIcon="plus"

View File

@ -47,6 +47,10 @@ import {
} from "components/formControls/SliderControl";
import { HybridSearchControl } from "components/formControls/HybridSearch";
import FunctionCallingConfigControl from "components/formControls/FunctionCallingConfigControl";
import {
DatasourceLinkControl,
type DatasourceLinkControlProps,
} from "components/formControls/DatasourceLinkControl";
/**
* NOTE: If you are adding a component that uses FormControl
@ -240,6 +244,16 @@ class FormControlRegistry {
},
},
);
FormControlFactory.registerControlBuilder(
formControlTypes.DATASOURCE_LINK,
{
buildPropertyControl(
controlProps: DatasourceLinkControlProps,
): JSX.Element {
return <DatasourceLinkControl {...controlProps} />;
},
},
);
}
}

View File

@ -24,4 +24,5 @@ export default {
RAG_DOCUMENTS_SELECTOR: "RAG_DOCUMENTS_SELECTOR",
HYBRID_SEARCH: "HYBRID_SEARCH",
FUNCTION_CALLING_CONFIG_FORM: "FUNCTION_CALLING_CONFIG_FORM",
DATASOURCE_LINK: "DATASOURCE_LINK",
};