refactor: extract RecentDomainsSection into reusable component (#41020)
### Description Refactored the recent domains section from being an inline constant in `SignUp.tsx` into a dedicated, reusable React component. This improves code organization, maintainability, and testability. ### Changes Made - **Created new component**: `RecentDomainsSection.tsx` - Encapsulates all logic for rendering recent organization domains - Handles conditional rendering internally (returns null when no domains) - Includes proper TypeScript types and imports - **Updated SignUp component**: - Removed inline `recentDomainsSection` constant definition - Added import for new `RecentDomainsSection` component - Replaced usage with JSX component - **Improved avatar logic**: - Changed from alphabetical cycling (`String.fromCharCode(65 + (index % 26))`) to using the actual organization name's first letter (`orgName.charAt(0).toUpperCase()`) - This provides more meaningful and recognizable avatars for users ## Automation /ok-to-test tags="@tag.Sanity, @tag.Authentication" ### 🔍 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/15838492574> > Commit: f4c799f7fd76851b404ddddd441728d9bd6445ca > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=15838492574&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.Sanity, @tag.Authentication` > Spec: > <hr>Tue, 24 Jun 2025 01:35:51 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced a dedicated section to display recently accessed domains during user sign-up, allowing quick access to previously used domains. - **Refactor** - Modularized the recent domains display by moving its logic and UI into a separate component for improved maintainability and clarity. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
959f5108c2
commit
2e6ede2419
74
app/client/src/pages/UserAuth/RecentDomainsSection.tsx
Normal file
74
app/client/src/pages/UserAuth/RecentDomainsSection.tsx
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
import { Button, Text } from "@appsmith/ads";
|
||||||
|
import {
|
||||||
|
createMessage,
|
||||||
|
YOU_VE_ALREADY_SIGNED_INTO,
|
||||||
|
} from "ee/constants/messages";
|
||||||
|
import React from "react";
|
||||||
|
import { getRecentDomains, isValidAppsmithDomain } from "utils/multiOrgDomains";
|
||||||
|
|
||||||
|
const RecentDomainsSection: React.FC = () => {
|
||||||
|
const recentDomains = getRecentDomains();
|
||||||
|
|
||||||
|
if (recentDomains.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="mt-8">
|
||||||
|
<div className="mb-2">
|
||||||
|
<Text kind="body-m">{createMessage(YOU_VE_ALREADY_SIGNED_INTO)}</Text>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="max-h-48 overflow-y-auto border border-gray-200 rounded-md py-4 px-3">
|
||||||
|
{recentDomains.map((domain, index) => {
|
||||||
|
const orgName = domain
|
||||||
|
.split(".")[0]
|
||||||
|
.split("-")
|
||||||
|
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
||||||
|
.join(" ");
|
||||||
|
|
||||||
|
const avatarLetter = orgName.charAt(0).toUpperCase();
|
||||||
|
|
||||||
|
const isLastItem = index === recentDomains.length - 1;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`flex items-center justify-between p-1 ${
|
||||||
|
isLastItem ? "mb-0" : "mb-3"
|
||||||
|
}`}
|
||||||
|
key={domain}
|
||||||
|
>
|
||||||
|
<div className="flex items-center space-x-3">
|
||||||
|
<div className="w-8 h-8 bg-[color:var(--ads-color-background-secondary)] rounded-full flex items-center justify-center text-gray-600 font-light text-sm">
|
||||||
|
{avatarLetter}
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<span className="text-md font-semibold text-gray-700 max-w-[180px] line-clamp-1">
|
||||||
|
{orgName}
|
||||||
|
</span>
|
||||||
|
<span className="text-xs font-light text-gray-500 max-w-[180px] line-clamp-1">
|
||||||
|
{domain}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
className="px-4 py-2 text-sm"
|
||||||
|
kind="secondary"
|
||||||
|
onClick={() => {
|
||||||
|
if (isValidAppsmithDomain(domain)) {
|
||||||
|
window.location.href = `https://${domain}/user/login`;
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
size="md"
|
||||||
|
>
|
||||||
|
Open
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RecentDomainsSection;
|
||||||
|
|
@ -28,7 +28,6 @@ import {
|
||||||
VISIT_OUR_DOCS,
|
VISIT_OUR_DOCS,
|
||||||
SIGN_IN_TO_AN_EXISTING_ORGANISATION,
|
SIGN_IN_TO_AN_EXISTING_ORGANISATION,
|
||||||
USING_APPSMITH,
|
USING_APPSMITH,
|
||||||
YOU_VE_ALREADY_SIGNED_INTO,
|
|
||||||
} from "ee/constants/messages";
|
} from "ee/constants/messages";
|
||||||
import FormTextField from "components/utils/ReduxFormTextField";
|
import FormTextField from "components/utils/ReduxFormTextField";
|
||||||
import ThirdPartyAuth from "pages/UserAuth/ThirdPartyAuth";
|
import ThirdPartyAuth from "pages/UserAuth/ThirdPartyAuth";
|
||||||
|
|
@ -66,7 +65,7 @@ import { isLoginHostname } from "utils/cloudBillingUtils";
|
||||||
import { appsmithTelemetry } from "instrumentation";
|
import { appsmithTelemetry } from "instrumentation";
|
||||||
import { getIsAiAgentInstanceEnabled } from "ee/selectors/aiAgentSelectors";
|
import { getIsAiAgentInstanceEnabled } from "ee/selectors/aiAgentSelectors";
|
||||||
import { getSafeErrorMessage } from "ee/constants/approvedErrorMessages";
|
import { getSafeErrorMessage } from "ee/constants/approvedErrorMessages";
|
||||||
import { getRecentDomains, isValidAppsmithDomain } from "utils/multiOrgDomains";
|
import RecentDomainsSection from "./RecentDomainsSection";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
|
|
@ -76,7 +75,6 @@ declare global {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const { cloudHosting, googleRecaptchaSiteKey } = getAppsmithConfigs();
|
const { cloudHosting, googleRecaptchaSiteKey } = getAppsmithConfigs();
|
||||||
const recentDomains = getRecentDomains();
|
|
||||||
|
|
||||||
const validate = (values: SignupFormValues) => {
|
const validate = (values: SignupFormValues) => {
|
||||||
const errors: SignupFormValues = {};
|
const errors: SignupFormValues = {};
|
||||||
|
|
@ -96,63 +94,6 @@ const validate = (values: SignupFormValues) => {
|
||||||
return errors;
|
return errors;
|
||||||
};
|
};
|
||||||
|
|
||||||
const recentDomainsSection = recentDomains.length > 0 && (
|
|
||||||
<div className="mt-8">
|
|
||||||
<div className="mb-2">
|
|
||||||
<Text kind="body-m">{createMessage(YOU_VE_ALREADY_SIGNED_INTO)}</Text>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="max-h-48 overflow-y-auto border border-gray-200 rounded-md py-4 px-3">
|
|
||||||
{recentDomains.map((domain, index) => {
|
|
||||||
const orgName = domain
|
|
||||||
.split(".")[0]
|
|
||||||
.split("-")
|
|
||||||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
||||||
.join(" ");
|
|
||||||
|
|
||||||
const avatarLetter = String.fromCharCode(65 + (index % 26));
|
|
||||||
|
|
||||||
const isLastItem = index === recentDomains.length - 1;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={`flex items-center justify-between p-1 ${
|
|
||||||
isLastItem ? "mb-0" : "mb-3"
|
|
||||||
}`}
|
|
||||||
key={domain}
|
|
||||||
>
|
|
||||||
<div className="flex items-center space-x-3">
|
|
||||||
<div className="w-8 h-8 bg-[color:var(--ads-color-background-secondary)] rounded-full flex items-center justify-center text-gray-600 font-light text-sm">
|
|
||||||
{avatarLetter}
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col">
|
|
||||||
<span className="text-md font-semibold text-gray-700 max-w-[180px] line-clamp-1">
|
|
||||||
{orgName}
|
|
||||||
</span>
|
|
||||||
<span className="text-xs font-light text-gray-500 max-w-[180px] line-clamp-1">
|
|
||||||
{domain}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Button
|
|
||||||
className="px-4 py-2 text-sm"
|
|
||||||
kind="secondary"
|
|
||||||
onClick={() => {
|
|
||||||
if (isValidAppsmithDomain(domain)) {
|
|
||||||
window.location.href = `https://${domain}/user/login`;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
size="md"
|
|
||||||
>
|
|
||||||
Open
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
type SignUpFormProps = InjectedFormProps<
|
type SignUpFormProps = InjectedFormProps<
|
||||||
SignupFormValues,
|
SignupFormValues,
|
||||||
{ emailValue: string }
|
{ emailValue: string }
|
||||||
|
|
@ -372,7 +313,9 @@ export function SignUp(props: SignUpFormProps) {
|
||||||
</SpacedSubmitForm>
|
</SpacedSubmitForm>
|
||||||
)}
|
)}
|
||||||
{isCloudBillingEnabled && isHostnameEqualtoLogin && cloudBillingSignIn}
|
{isCloudBillingEnabled && isHostnameEqualtoLogin && cloudBillingSignIn}
|
||||||
{isCloudBillingEnabled && isHostnameEqualtoLogin && recentDomainsSection}
|
{isCloudBillingEnabled && isHostnameEqualtoLogin && (
|
||||||
|
<RecentDomainsSection />
|
||||||
|
)}
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user