chore: ai agent sing up flow (#39943)

## Description
Part of [EE PR](https://github.com/appsmithorg/appsmith-ee/pull/6704)


Fixes #`Issue Number`  
_or_  
Fixes `Issue URL`
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

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

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!IMPORTANT]
> 🟣 🟣 🟣 Your tests are running.
> Tests running at:
<https://github.com/appsmithorg/appsmith/actions/runs/14106727889>
> Commit: 0fb8b6d7309a98d961c88923465f384bb2f518ea
> Workflow: `PR Automation test suite`
> Tags: `@tag.Sanity`
> Spec: ``
> <hr>Thu, 27 Mar 2025 12:36:47 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 informative messaging for AI Agent features in the
applications and sign-up experiences.
- Enabled dynamic interface behavior that conditionally displays content
based on the activation of AI Agent functionality.

- **Style**
- Enhanced text formatting in authentication views to improve
readability and support multi-line content.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Valera Melnikov 2025-03-27 15:48:12 +03:00 committed by GitHub
parent 79cdfef7a0
commit 7f3a66de2b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 75 additions and 40 deletions

View File

@ -214,6 +214,10 @@ export const NEW_APPLICATION = () => `New application`;
export const APPLICATIONS = () => `Applications`;
export const FIXED_APPLICATIONS = () => `Classic Applications`;
export const AI_AGENTS_APPLICATIONS = () => `AI Agents`;
export const AI_APPLICATION_CARD_LIST_ZERO_STATE = () =>
`There are no AI Agents in this workspace.`;
export const AI_AGENT_AUTH_SUBTITLE = () =>
`Sign up with any Google account.\n Support for email will be available soon.`;
export const USER_PROFILE_PICTURE_UPLOAD_FAILED = () =>
"Unable to upload display picture.";

View File

@ -17,6 +17,7 @@ export const FEATURE_FLAG = {
"release_show_publish_app_to_community_enabled",
license_gac_enabled: "license_gac_enabled",
release_anvil_enabled: "release_anvil_enabled",
license_ai_agent_enabled: "license_ai_agent_enabled",
license_git_branch_protection_enabled:
"license_git_branch_protection_enabled",
license_git_continuous_delivery_enabled:
@ -75,6 +76,7 @@ export const DEFAULT_FEATURE_FLAG_VALUE: FeatureFlags = {
release_show_publish_app_to_community_enabled: false,
license_gac_enabled: false,
release_anvil_enabled: false,
license_ai_agent_enabled: false,
release_drag_drop_building_blocks_enabled: false,
license_git_branch_protection_enabled: false,
license_git_continuous_delivery_enabled: false,

View File

@ -9,6 +9,7 @@ import {
import type { UpdateApplicationPayload } from "ee/api/ApplicationApi";
import {
AI_AGENTS_APPLICATIONS,
AI_APPLICATION_CARD_LIST_ZERO_STATE,
APPLICATIONS,
CREATE_A_NEW_WORKSPACE,
createMessage,
@ -17,6 +18,7 @@ import {
NO_WORKSPACE_HEADING,
WORKSPACES_HEADING,
} from "ee/constants/messages";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors";
import type { ApplicationPayload } from "entities/Application";
import { ReduxActionTypes } from "ee/constants/ReduxActionConstants";
import { createWorkspaceSubmitHandler } from "ee/pages/workspace/helpers";
@ -552,6 +554,7 @@ export function ApplicationsSection(props: any) {
// This checks if the Anvil feature flag is enabled and shows different sections in the workspace
// for Anvil and Classic applications
const isAnvilEnabled = useSelector(getIsAnvilLayoutEnabled);
const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled);
const currentUser = useSelector(getCurrentUser);
const isMobile = useIsMobileDevice();
const urlParams = new URLSearchParams(location.search);
@ -896,42 +899,47 @@ export function ApplicationsSection(props: any) {
<ResourceListLoader isMobile={isMobile} resources={applications} />
) : (
<>
<ApplicationCardList
applications={nonAnvilApplications}
canInviteToWorkspace={canInviteToWorkspace}
deleteApplication={deleteApplication}
enableImportExport={enableImportExport}
hasCreateNewApplicationPermission={
hasCreateNewApplicationPermission
}
hasManageWorkspacePermissions={hasManageWorkspacePermissions}
isMobile={isMobile}
onClickAddNewButton={onClickAddNewAppButton}
title={createMessage(APPLICATIONS)}
updateApplicationDispatch={updateApplicationDispatch}
workspaceId={activeWorkspace.id}
/>
{isAnvilEnabled &&
anvilApplications.length > 0 && ( // AI Agents list
<ApplicationCardList
applications={anvilApplications}
canInviteToWorkspace={canInviteToWorkspace}
deleteApplication={deleteApplication}
enableImportExport={enableImportExport}
hasCreateNewApplicationPermission={
hasCreateNewApplicationPermission
}
hasManageWorkspacePermissions={
hasManageWorkspacePermissions
}
isMobile={isMobile}
onClickAddNewButton={onClickAddNewAppButton}
title={createMessage(AI_AGENTS_APPLICATIONS)}
titleTag={BetaTag}
updateApplicationDispatch={updateApplicationDispatch}
workspaceId={activeWorkspace.id}
/>
)}
{!isAiAgentFlowEnabled && (
<ApplicationCardList
applications={nonAnvilApplications}
canInviteToWorkspace={canInviteToWorkspace}
deleteApplication={deleteApplication}
enableImportExport={enableImportExport}
hasCreateNewApplicationPermission={
hasCreateNewApplicationPermission
}
hasManageWorkspacePermissions={hasManageWorkspacePermissions}
isMobile={isMobile}
onClickAddNewButton={onClickAddNewAppButton}
title={createMessage(APPLICATIONS)}
updateApplicationDispatch={updateApplicationDispatch}
workspaceId={activeWorkspace.id}
/>
)}
{((isAnvilEnabled && anvilApplications.length > 0) ||
isAiAgentFlowEnabled) && (
<ApplicationCardList
applications={anvilApplications}
canInviteToWorkspace={canInviteToWorkspace}
deleteApplication={deleteApplication}
emptyStateMessage={
isAiAgentFlowEnabled
? createMessage(AI_APPLICATION_CARD_LIST_ZERO_STATE)
: undefined
}
enableImportExport={enableImportExport}
hasCreateNewApplicationPermission={
hasCreateNewApplicationPermission
}
hasManageWorkspacePermissions={hasManageWorkspacePermissions}
isMobile={isMobile}
onClickAddNewButton={onClickAddNewAppButton}
title={createMessage(AI_AGENTS_APPLICATIONS)}
titleTag={BetaTag}
updateApplicationDispatch={updateApplicationDispatch}
workspaceId={activeWorkspace.id}
/>
)}
<PackageCardList
isMobile={isMobile}
packages={packages}

View File

@ -1,3 +1,11 @@
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
import type { AppState } from "ee/reducers";
import { selectFeatureFlagCheck } from "ee/selectors/featureFlagsSelectors";
export const getAgentChatQuery = () => {
return undefined;
};
export const getIsAiAgentFlowEnabled = (state: AppState) => {
return selectFeatureFlagCheck(state, FEATURE_FLAG.license_ai_agent_enabled);
};

View File

@ -68,7 +68,7 @@ function Container(props: ContainerProps) {
{title}
</h1>
{subtitle && (
<p className="text-[14px] text-center text-[color:var(--ads-v2\-color-fg)]">
<p className="text-[14px] text-center text-[color:var(--ads-v2\-color-fg)] whitespace-pre-line">
{subtitle}
</p>
)}

View File

@ -28,6 +28,8 @@ import {
VISIT_OUR_DOCS,
ALREADY_USING_APPSMITH,
SIGN_IN_TO_AN_EXISTING_ORGANISATION,
AI_AGENT_AUTH_SUBTITLE,
LOGIN_PAGE_TITLE,
} from "ee/constants/messages";
import FormTextField from "components/utils/ReduxFormTextField";
import ThirdPartyAuth from "pages/UserAuth/ThirdPartyAuth";
@ -63,6 +65,7 @@ import * as Sentry from "@sentry/react";
import CsrfTokenInput from "pages/UserAuth/CsrfTokenInput";
import { useIsCloudBillingEnabled } from "hooks";
import { isLoginHostname } from "utils/cloudBillingUtils";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors";
declare global {
interface Window {
@ -100,9 +103,10 @@ type SignUpFormProps = InjectedFormProps<
export function SignUp(props: SignUpFormProps) {
const history = useHistory();
const isFormLoginEnabled = useSelector(getIsFormLoginEnabled);
const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled);
useEffect(() => {
if (!isFormLoginEnabled) {
if (!isFormLoginEnabled && !isAiAgentFlowEnabled) {
const search = new URL(window.location.href)?.searchParams?.toString();
history.replace({
@ -226,7 +230,7 @@ export function SignUp(props: SignUpFormProps) {
</Link>
</div>
)}
{cloudHosting && (
{cloudHosting && !isAiAgentFlowEnabled && (
<>
<OrWithLines>or</OrWithLines>
<div className="px-2 text-center text-[color:var(--ads-v2\-color-fg)] text-[14px]">
@ -247,7 +251,15 @@ export function SignUp(props: SignUpFormProps) {
);
return (
<Container footer={footerSection} title={createMessage(SIGNUP_PAGE_TITLE)}>
<Container
footer={footerSection}
subtitle={
isAiAgentFlowEnabled ? createMessage(AI_AGENT_AUTH_SUBTITLE) : ""
}
title={createMessage(
isAiAgentFlowEnabled ? SIGNUP_PAGE_TITLE : LOGIN_PAGE_TITLE,
)}
>
<Helmet>
<title>{htmlPageTitle}</title>
</Helmet>

View File

@ -15,6 +15,7 @@ import {
export const AvailableFeaturesToOverride: FeatureFlag[] = [
"release_anvil_enabled",
"release_layout_conversion_enabled",
"license_ai_agent_enabled",
];
export type OverriddenFeatureFlags = Partial<Record<FeatureFlag, boolean>>;