From 7ec9146d149bada32f2af275d835f8a26f3d9e6c Mon Sep 17 00:00:00 2001 From: panteliselef Date: Wed, 18 Oct 2023 11:23:39 +0300 Subject: [PATCH] chore(clerk-js): Improve relative url creation in DomainList --- .../OrganizationProfile/DomainList.tsx | 69 ++++++++++--------- .../OrganizationMembersTabInvitations.tsx | 2 +- .../OrganizationMembersTabRequests.tsx | 2 +- .../OrganizationSettings.tsx | 2 +- packages/clerk-js/src/utils/url.ts | 13 ++++ 5 files changed, 53 insertions(+), 35 deletions(-) diff --git a/packages/clerk-js/src/ui/components/OrganizationProfile/DomainList.tsx b/packages/clerk-js/src/ui/components/OrganizationProfile/DomainList.tsx index 8430061f1ab..db0639f0001 100644 --- a/packages/clerk-js/src/ui/components/OrganizationProfile/DomainList.tsx +++ b/packages/clerk-js/src/ui/components/OrganizationProfile/DomainList.tsx @@ -2,6 +2,7 @@ import type { GetDomainsParams, OrganizationDomainResource, OrganizationEnrollme import type { OrganizationDomainVerificationStatus } from '@clerk/types'; import React, { useMemo } from 'react'; +import { stripOrigin, toURL, trimLeadingSlash } from '../../../utils'; import { useGate, withGate } from '../../common'; import { useCoreOrganization } from '../../contexts'; import { Box, Col, localizationKeys, Spinner } from '../../customizables'; @@ -17,7 +18,7 @@ type DomainListProps = GetDomainsParams & { * Enables internal links to navigate to the correct page * based on when this component is used */ - redirectSubPath: string; + redirectSubPath: 'organization-settings/domain' | 'domain'; fallback?: React.ReactNode; }; @@ -32,42 +33,46 @@ const useDomainList = () => { }; }; +const buildDomainListRelativeURL = (parentPath: string, domainId: string, mode?: 'verify' | 'remove') => + trimLeadingSlash(stripOrigin(toURL(`${parentPath}/${domainId}/${mode || ''}`))); + +const useMenuActions = (parentPath: string, domainId: string) => { + const { canDeleteDomain, canVerifyDomain } = useDomainList(); + const { navigate } = useRouter(); + + return [ + ...(canVerifyDomain + ? [ + { + label: localizationKeys( + 'organizationProfile.profilePage.domainSection.unverifiedDomain_menuAction__verify', + ), + onClick: () => navigate(buildDomainListRelativeURL(parentPath, domainId, 'verify')), + }, + ] + : []), + ...(canDeleteDomain + ? [ + { + label: localizationKeys( + 'organizationProfile.profilePage.domainSection.unverifiedDomain_menuAction__remove', + ), + isDestructive: true, + onClick: () => navigate(buildDomainListRelativeURL(parentPath, domainId, 'remove')), + }, + ] + : []), + ]; +}; + const DomainListDotMenu = ({ redirectSubPath, domainId, }: Pick & { domainId: OrganizationDomainResource['id']; }) => { - const { navigate } = useRouter(); - const { canDeleteDomain, canVerifyDomain } = useDomainList(); - - return ( - navigate(`${redirectSubPath}${domainId}/verify`), - }, - ] - : []), - ...(canDeleteDomain - ? [ - { - label: localizationKeys( - 'organizationProfile.profilePage.domainSection.unverifiedDomain_menuAction__remove', - ), - isDestructive: true, - onClick: () => navigate(`${redirectSubPath}${domainId}/remove`), - }, - ] - : []), - ]} - /> - ); + const actions = useMenuActions(redirectSubPath, domainId); + return ; }; export const DomainList = withGate( @@ -155,7 +160,7 @@ export const DomainList = withGate( padding: `${t.space.$3} ${t.space.$4}`, minHeight: t.sizes.$10, })} - onClick={() => navigate(`${redirectSubPath}${d.id}`)} + onClick={() => navigate(buildDomainListRelativeURL(redirectSubPath, d.id))} > {d.name} diff --git a/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationMembersTabInvitations.tsx b/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationMembersTabInvitations.tsx index 7a57c04c7c3..a533393fe36 100644 --- a/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationMembersTabInvitations.tsx +++ b/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationMembersTabInvitations.tsx @@ -58,7 +58,7 @@ export const OrganizationMembersTabInvitations = () => { onClick={() => navigate('organization-settings/domain')} /> } - redirectSubPath={'organization-settings/domain/'} + redirectSubPath={'organization-settings/domain'} verificationStatus={'verified'} enrollmentMode={'automatic_invitation'} /> diff --git a/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationMembersTabRequests.tsx b/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationMembersTabRequests.tsx index b46caafd9b7..a5078b639dd 100644 --- a/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationMembersTabRequests.tsx +++ b/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationMembersTabRequests.tsx @@ -57,7 +57,7 @@ export const OrganizationMembersTabRequests = () => { onClick={() => navigate('organization-settings/domain')} /> } - redirectSubPath={'organization-settings/domain/'} + redirectSubPath={'organization-settings/domain'} verificationStatus={'verified'} enrollmentMode={'automatic_suggestion'} /> diff --git a/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationSettings.tsx b/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationSettings.tsx index 1681b673ec9..faca9fa90c3 100644 --- a/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationSettings.tsx +++ b/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationSettings.tsx @@ -85,7 +85,7 @@ const OrganizationDomainsSection = () => { subtitle={localizationKeys('organizationProfile.profilePage.domainSection.subtitle')} id='organizationDomains' > - + { return (path || '').replace(/\/+$/, ''); }; +/** + * trimLeadingSlash(path: string): string + * + * Strips the leading slashes from a string + * + * @returns {string} Returns the string without leading slashes + * @param path + */ +export const trimLeadingSlash = (path: string): string => { + return (path || '').replace(/^\/+/, ''); +}; + + export const stripSameOrigin = (url: URL, baseUrl: URL): string => { const sameOrigin = baseUrl.origin === url.origin; return sameOrigin ? stripOrigin(url) : `${url}`;