/ok-to-test tags="@tag.Sanity" <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/14994848262> > Commit: 64bdb8cd0606bbc4c1b11d69b2d0e7cd7b5dd78a > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=14994848262&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.Sanity` > Spec: > <hr>Tue, 13 May 2025 11:39:41 UTC <!-- end of auto-generated comment: Cypress test results --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced a new feature flag for AI agent instances, allowing for more granular control over AI agent-related functionality. - **Refactor** - Updated various components and selectors to use the new AI agent instance feature flag and related selectors, replacing previous flags and logic. - Separated agent and non-agent template handling for clearer template management. - Improved feature flag override capabilities, enabling dynamic overrides via external sources. - Added new selectors to better represent AI agent app and creation states. - Refined UI components and modals to reflect updated AI agent state flags. - Enhanced user authentication and signup flows with updated feature flag conditions. - **Bug Fixes** - Ensured consistent UI behavior and conditional rendering based on the updated feature flag logic. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
330 lines
9.0 KiB
TypeScript
330 lines
9.0 KiB
TypeScript
import React, { useEffect, useState } from "react";
|
|
|
|
import { HELP_MODAL_WIDTH } from "constants/HelpConstants";
|
|
import AnalyticsUtil from "ee/utils/AnalyticsUtil";
|
|
import { getCurrentUser } from "selectors/usersSelectors";
|
|
import { useDispatch, useSelector } from "react-redux";
|
|
import bootIntercom, { updateIntercomProperties } from "utils/bootIntercom";
|
|
import {
|
|
APPSMITH_DISPLAY_VERSION,
|
|
CONTINUE,
|
|
createMessage,
|
|
HELP_RESOURCE_TOOLTIP,
|
|
INTERCOM_CONSENT_MESSAGE,
|
|
} from "ee/constants/messages";
|
|
import {
|
|
Button,
|
|
Menu,
|
|
MenuContent,
|
|
MenuItem,
|
|
MenuTrigger,
|
|
Tooltip,
|
|
MenuSeparator,
|
|
Text,
|
|
} from "@appsmith/ads";
|
|
import { getAppsmithConfigs } from "ee/configs";
|
|
import moment from "moment/moment";
|
|
import styled from "styled-components";
|
|
import {
|
|
getFirstTimeUserOnboardingModal,
|
|
getIsFirstTimeUserOnboardingEnabled,
|
|
getSignpostingSetOverlay,
|
|
getSignpostingTooltipVisible,
|
|
getSignpostingUnreadSteps,
|
|
} from "selectors/onboardingSelectors";
|
|
import SignpostingPopup from "pages/Editor/FirstTimeUserOnboarding/Modal";
|
|
import { showSignpostingModal } from "actions/onboardingActions";
|
|
import TooltipContent from "./FirstTimeUserOnboarding/TooltipContent";
|
|
import { getInstanceId } from "ee/selectors/organizationSelectors";
|
|
import { updateIntercomConsent, updateUserDetails } from "actions/userActions";
|
|
import { getIsAiAgentApp } from "ee/selectors/aiAgentSelectors";
|
|
import { DOCS_AI_BASE_URL } from "constants/ThirdPartyConstants";
|
|
|
|
const { appVersion, cloudHosting, intercomAppID } = getAppsmithConfigs();
|
|
|
|
const HelpFooter = styled.div`
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
font-size: 8px;
|
|
`;
|
|
const UnreadSteps = styled.div`
|
|
position: absolute;
|
|
height: 6px;
|
|
width: 6px;
|
|
border-radius: 50%;
|
|
top: 10px;
|
|
left: 22px;
|
|
background-color: var(--ads-v2-color-fg-error);
|
|
`;
|
|
const ConsentContainer = styled.div`
|
|
padding: 10px;
|
|
`;
|
|
const ActionsRow = styled.div`
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 8px;
|
|
`;
|
|
|
|
interface HelpItem {
|
|
label: string;
|
|
link?: string;
|
|
id?: string;
|
|
icon: string;
|
|
}
|
|
|
|
let HELP_MENU_ITEMS: HelpItem[] = [
|
|
{
|
|
icon: "book-line",
|
|
label: "Documentation",
|
|
link: "https://docs.appsmith.com/",
|
|
},
|
|
{
|
|
icon: "bug-line",
|
|
label: "Report a bug",
|
|
link: "https://github.com/appsmithorg/appsmith/issues/new/choose",
|
|
},
|
|
];
|
|
|
|
if (intercomAppID && window.Intercom) {
|
|
HELP_MENU_ITEMS.push({
|
|
icon: "chat-help",
|
|
label: "Chat with us",
|
|
id: "intercom-trigger",
|
|
});
|
|
}
|
|
|
|
export function IntercomConsent({
|
|
showIntercomConsent,
|
|
}: {
|
|
showIntercomConsent: (val: boolean) => void;
|
|
}) {
|
|
const user = useSelector(getCurrentUser);
|
|
const instanceId = useSelector(getInstanceId);
|
|
const dispatch = useDispatch();
|
|
|
|
const sendUserDataToIntercom = async () => {
|
|
const { email } = user || {};
|
|
|
|
updateIntercomProperties(instanceId, user);
|
|
dispatch(
|
|
updateUserDetails({
|
|
intercomConsentGiven: true,
|
|
}),
|
|
);
|
|
dispatch(updateIntercomConsent());
|
|
showIntercomConsent(false);
|
|
|
|
if (user?.enableTelemetry) {
|
|
await AnalyticsUtil.identifyUser(user, true);
|
|
AnalyticsUtil.logEvent("SUPPORT_REQUEST_INITIATED", {
|
|
email,
|
|
});
|
|
}
|
|
|
|
window.Intercom("show");
|
|
};
|
|
|
|
return (
|
|
<ConsentContainer>
|
|
<ActionsRow>
|
|
<Button
|
|
isIconButton
|
|
kind="tertiary"
|
|
onClick={() => showIntercomConsent(false)}
|
|
size="sm"
|
|
startIcon="arrow-left"
|
|
/>
|
|
</ActionsRow>
|
|
<div className="mb-3" data-testid="t--intercom-consent-text">
|
|
<Text kind="body-s" renderAs="p">
|
|
{createMessage(INTERCOM_CONSENT_MESSAGE)}
|
|
</Text>
|
|
</div>
|
|
<Button kind="primary" onClick={sendUserDataToIntercom} size="sm">
|
|
{createMessage(CONTINUE)}
|
|
</Button>
|
|
</ConsentContainer>
|
|
);
|
|
}
|
|
|
|
function HelpButtonTooltip(props: {
|
|
isFirstTimeUserOnboardingEnabled: boolean;
|
|
showSignpostingTooltip: boolean;
|
|
}) {
|
|
if (props.isFirstTimeUserOnboardingEnabled) {
|
|
return (
|
|
<TooltipContent showSignpostingTooltip={props.showSignpostingTooltip} />
|
|
);
|
|
}
|
|
|
|
return <>{createMessage(HELP_RESOURCE_TOOLTIP)}</>;
|
|
}
|
|
|
|
function HelpButton() {
|
|
const [showIntercomConsent, setShowIntercomConsent] = useState(false);
|
|
const [showTooltip, setShowTooltip] = useState(false);
|
|
const user = useSelector(getCurrentUser);
|
|
const dispatch = useDispatch();
|
|
const isFirstTimeUserOnboardingEnabled = useSelector(
|
|
getIsFirstTimeUserOnboardingEnabled,
|
|
);
|
|
const showSignpostingTooltip = useSelector(getSignpostingTooltipVisible);
|
|
const onboardingModalOpen = useSelector(getFirstTimeUserOnboardingModal);
|
|
const unreadSteps = useSelector(getSignpostingUnreadSteps);
|
|
const setOverlay = useSelector(getSignpostingSetOverlay);
|
|
const showUnreadSteps =
|
|
!!unreadSteps.length &&
|
|
isFirstTimeUserOnboardingEnabled &&
|
|
!onboardingModalOpen;
|
|
const menuProps = isFirstTimeUserOnboardingEnabled
|
|
? {
|
|
open: onboardingModalOpen,
|
|
}
|
|
: {};
|
|
const tooltipProps = isFirstTimeUserOnboardingEnabled
|
|
? {
|
|
visible: showTooltip || showSignpostingTooltip,
|
|
onVisibleChange: setShowTooltip,
|
|
}
|
|
: {};
|
|
|
|
const isAgentApp = useSelector(getIsAiAgentApp);
|
|
|
|
if (isAgentApp) {
|
|
const docItem = HELP_MENU_ITEMS.find(
|
|
(item) => item.label === "Documentation",
|
|
);
|
|
|
|
if (docItem) {
|
|
docItem.link = DOCS_AI_BASE_URL;
|
|
}
|
|
|
|
HELP_MENU_ITEMS = HELP_MENU_ITEMS.filter(
|
|
(item) => item.label !== "Report a bug",
|
|
);
|
|
}
|
|
|
|
useEffect(() => {
|
|
bootIntercom(user);
|
|
}, [user?.email]);
|
|
|
|
return (
|
|
<Menu
|
|
onOpenChange={(open) => {
|
|
if (open) {
|
|
if (isFirstTimeUserOnboardingEnabled) {
|
|
dispatch(showSignpostingModal(true));
|
|
setShowTooltip(false);
|
|
}
|
|
|
|
setShowIntercomConsent(false);
|
|
AnalyticsUtil.logEvent("OPEN_HELP", {
|
|
page: "Editor",
|
|
signpostingActive: isFirstTimeUserOnboardingEnabled,
|
|
});
|
|
}
|
|
}}
|
|
{...menuProps}
|
|
>
|
|
<MenuTrigger>
|
|
<div className="relative">
|
|
<Tooltip
|
|
align={{
|
|
targetOffset: [5, 0],
|
|
}}
|
|
content={
|
|
<HelpButtonTooltip
|
|
isFirstTimeUserOnboardingEnabled={
|
|
isFirstTimeUserOnboardingEnabled
|
|
}
|
|
showSignpostingTooltip={showSignpostingTooltip}
|
|
/>
|
|
}
|
|
destroyTooltipOnHide={isFirstTimeUserOnboardingEnabled}
|
|
isDisabled={onboardingModalOpen}
|
|
mouseLeaveDelay={0}
|
|
placement="bottomRight"
|
|
{...tooltipProps}
|
|
>
|
|
<Button
|
|
data-testid="t--help-button"
|
|
kind="tertiary"
|
|
size="md"
|
|
startIcon="question-line"
|
|
>
|
|
Help
|
|
</Button>
|
|
</Tooltip>
|
|
{showUnreadSteps && <UnreadSteps className="unread" />}
|
|
</div>
|
|
</MenuTrigger>
|
|
{isFirstTimeUserOnboardingEnabled ? (
|
|
<SignpostingPopup
|
|
setOverlay={setOverlay}
|
|
setShowIntercomConsent={setShowIntercomConsent}
|
|
showIntercomConsent={showIntercomConsent}
|
|
/>
|
|
) : (
|
|
<MenuContent collisionPadding={10} style={{ width: HELP_MODAL_WIDTH }}>
|
|
{showIntercomConsent ? (
|
|
<IntercomConsent showIntercomConsent={setShowIntercomConsent} />
|
|
) : (
|
|
<>
|
|
{HELP_MENU_ITEMS.map((item) => (
|
|
<MenuItem
|
|
id={item.id}
|
|
key={item.label}
|
|
onSelect={(e) => {
|
|
if (item.link) {
|
|
window.open(item.link, "_blank");
|
|
}
|
|
|
|
if (item.id === "intercom-trigger") {
|
|
e?.preventDefault();
|
|
|
|
if (intercomAppID && window.Intercom) {
|
|
if (user?.isIntercomConsentGiven || cloudHosting) {
|
|
window.Intercom("show");
|
|
} else {
|
|
setShowIntercomConsent(true);
|
|
}
|
|
}
|
|
}
|
|
}}
|
|
startIcon={item.icon}
|
|
>
|
|
{item.label}
|
|
</MenuItem>
|
|
))}
|
|
</>
|
|
)}
|
|
|
|
{appVersion.id && (
|
|
<>
|
|
<MenuSeparator />
|
|
<MenuItem className="menuitem-nohover">
|
|
<HelpFooter>
|
|
<span>
|
|
{createMessage(
|
|
APPSMITH_DISPLAY_VERSION,
|
|
appVersion.edition,
|
|
appVersion.id,
|
|
)}
|
|
</span>
|
|
<span>
|
|
Released {moment(appVersion.releaseDate).fromNow()}
|
|
</span>
|
|
</HelpFooter>
|
|
</MenuItem>
|
|
</>
|
|
)}
|
|
</MenuContent>
|
|
)}
|
|
</Menu>
|
|
);
|
|
}
|
|
|
|
export default HelpButton;
|