Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions apps/ui/src/components/settings-view/account-section.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { fireEvent, render, screen } from '@testing-library/react';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { useConnector } from '@/data/core';
import { useAuthUser, useLogin, useLogout } from '@/data/queries/use-auth-user';
import { useUserLocale } from '@/data/queries/use-user-locale';
import { AccountSection } from './account-section';
import type { ButtonHTMLAttributes, ReactNode } from 'react';

Expand Down Expand Up @@ -44,6 +45,10 @@ vi.mock( '@/data/queries/use-auth-user', () => ( {
useLogout: vi.fn(),
} ) );

vi.mock( '@/data/queries/use-user-locale', () => ( {
useUserLocale: vi.fn(),
} ) );

vi.mock( '@/hooks/use-color-scheme', () => ( {
useColorScheme: () => 'light',
} ) );
Expand All @@ -52,6 +57,7 @@ const useConnectorMock = vi.mocked( useConnector );
const useAuthUserMock = vi.mocked( useAuthUser );
const useLoginMock = vi.mocked( useLogin );
const useLogoutMock = vi.mocked( useLogout );
const useUserLocaleMock = vi.mocked( useUserLocale );

describe( 'AccountSection', () => {
const loginMutate = vi.fn();
Expand All @@ -62,6 +68,7 @@ describe( 'AccountSection', () => {
vi.clearAllMocks();

useConnectorMock.mockReturnValue( { openExternalUrl } as never );
useUserLocaleMock.mockReturnValue( undefined );
useAuthUserMock.mockReturnValue( {
data: { id: 1, displayName: 'Ada Lovelace', email: 'ada@example.com' },
isLoading: false,
Expand Down Expand Up @@ -115,4 +122,16 @@ describe( 'AccountSection', () => {
'https://github.com/Automattic/studio/issues/new/choose'
);
} );

it( 'opens localized docs when the locale has a translation', () => {
useUserLocaleMock.mockReturnValue( 'es' );

render( <AccountSection /> );

fireEvent.click( screen.getByRole( 'button', { name: 'Docs' } ) );

expect( openExternalUrl ).toHaveBeenCalledWith(
'https://developer.wordpress.com/es/docs/herramientas-para-desarrolladores/studio/'
);
} );
} );
8 changes: 4 additions & 4 deletions apps/ui/src/components/settings-view/account-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import { clsx } from 'clsx';
import { Gravatar } from '@/components/gravatar';
import { useConnector } from '@/data/core';
import { useAuthUser, useLogin, useLogout } from '@/data/queries/use-auth-user';
import { useUserLocale } from '@/data/queries/use-user-locale';
import { useColorScheme } from '@/hooks/use-color-scheme';
import { getLocalizedLink, REPORT_ISSUE_URL } from '@/lib/docs-links';
import styles from './style.module.css';

const DOCS_URL = 'https://developer.wordpress.com/docs/developer-tools/studio/';
const REPORT_ISSUE_URL = 'https://github.com/Automattic/studio/issues/new/choose';

function AccountHelpActions() {
const connector = useConnector();
const locale = useUserLocale();

const openLink = ( url: string ) => {
void connector.openExternalUrl( url );
Expand All @@ -24,7 +24,7 @@ function AccountHelpActions() {
variant="minimal"
tone="neutral"
size="small"
onClick={ () => openLink( DOCS_URL ) }
onClick={ () => openLink( getLocalizedLink( locale, 'docsStudio' ) ) }
>
{ __( 'Docs' ) }
</Button>
Expand Down
10 changes: 7 additions & 3 deletions apps/ui/src/components/user-menu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import * as Menu from '@/components/menu';
import { SidebarButton } from '@/components/sidebar-button';
import { useConnector } from '@/data/core';
import { useAuthUser, useLogin, useLogout } from '@/data/queries/use-auth-user';
import { useUserLocale } from '@/data/queries/use-user-locale';
import { useColorScheme } from '@/hooks/use-color-scheme';
import { useOffline } from '@/hooks/use-offline';
import { getLocalizedLink, REPORT_ISSUE_URL } from '@/lib/docs-links';
import styles from './style.module.css';

const WPCOM_PROFILE_URL = 'https://wordpress.com/me';
const DOCS_URL = 'https://developer.wordpress.com/docs/developer-tools/studio/';
const REPORT_ISSUE_URL = 'https://github.com/Automattic/studio/issues/new/choose';

export function UserMenu() {
const connector = useConnector();
Expand All @@ -23,6 +23,7 @@ export function UserMenu() {
const navigate = useNavigate();

const isOffline = useOffline();
const locale = useUserLocale();
const themeIsDark = useColorScheme() === 'dark';

const openLink = ( url: string ) => {
Expand Down Expand Up @@ -52,7 +53,10 @@ export function UserMenu() {
<Menu.Item disabled={ isOffline } onClick={ () => openLink( WPCOM_PROFILE_URL ) }>
{ __( 'Edit WordPress.com profile' ) }
</Menu.Item>
<Menu.Item disabled={ isOffline } onClick={ () => openLink( DOCS_URL ) }>
<Menu.Item
disabled={ isOffline }
onClick={ () => openLink( getLocalizedLink( locale, 'docsStudio' ) ) }
>
{ __( 'Documentation' ) }
</Menu.Item>
<Menu.Item disabled={ isOffline } onClick={ () => openLink( REPORT_ISSUE_URL ) }>
Expand Down
10 changes: 2 additions & 8 deletions apps/ui/src/data/core/connectors/ipc/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { sanitizeFolderName } from '@studio/common/lib/sanitize-folder-name';
import { fetchWordPressVersions } from '@studio/common/lib/wordpress-versions';
import { __ } from '@wordpress/i18n';
import { buildPublishCheckoutUrl } from '../publish-checkout-url';
import type {
ActiveAgentRun,
AiSessionSummary,
Expand Down Expand Up @@ -467,14 +468,7 @@ export function createIpcConnector(): Connector {
},

getPublishCheckoutUrl( site ): string {
const url = new URL( 'https://wordpress.com/setup/new-hosted-site' );
url.searchParams.set( 'ref', 'studio' );
url.searchParams.set( 'section', 'publish-site' );
url.searchParams.set( 'showDomainStep', 'true' );
url.searchParams.set( 'studioSiteId', site.id );
url.searchParams.set( 'new', site.customDomain ?? site.name );
url.searchParams.set( 'autoOpenPush', 'true' );
return url.toString();
return buildPublishCheckoutUrl( site );
},

// AI sessions
Expand Down
17 changes: 5 additions & 12 deletions apps/ui/src/data/core/connectors/local/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { getAuthenticationUrl } from '@studio/common/lib/oauth';
import { fetchWordPressVersions } from '@studio/common/lib/wordpress-versions';
import { __ } from '@wordpress/i18n';
import { applyStoredSiteOrder, storeSiteOrder } from '../browser-site-order';
import { buildPublishCheckoutUrl } from '../publish-checkout-url';
import { UnsupportedError } from '../unsupported-error';
import type {
ActiveAgentRun,
Expand Down Expand Up @@ -518,18 +519,10 @@ export function createLocalConnector( { apiBaseUrl }: LocalConnectorOptions ): C
} );
},
getPublishCheckoutUrl( site ): string {
// The same WordPress.com hosted-site checkout the desktop opens — a pure
// URL builder, so it ports verbatim. (The post-checkout auto-connect still
// relies on the deep-link listener, which a browser tab can't receive, so
// the user finishes by connecting the new site from the picker.)
const url = new URL( 'https://wordpress.com/setup/new-hosted-site' );
url.searchParams.set( 'ref', 'studio' );
url.searchParams.set( 'section', 'publish-site' );
url.searchParams.set( 'showDomainStep', 'true' );
url.searchParams.set( 'studioSiteId', site.id );
url.searchParams.set( 'new', site.customDomain ?? site.name );
url.searchParams.set( 'autoOpenPush', 'true' );
return url.toString();
// The post-checkout auto-connect relies on the deep-link listener, which
// a browser tab can't receive, so the user finishes by connecting the
// new site from the picker.
return buildPublishCheckoutUrl( site );
},

// AI sessions — the headline. HTTP routes on the local server, backed by
Expand Down
12 changes: 12 additions & 0 deletions apps/ui/src/data/core/connectors/publish-checkout-url.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { SiteDetails } from '../types';

export function buildPublishCheckoutUrl( site: SiteDetails ): string {
const url = new URL( 'https://wordpress.com/setup/new-hosted-site' );
url.searchParams.set( 'ref', 'studio' );
url.searchParams.set( 'section', 'publish-site' );
url.searchParams.set( 'showDomainStep', 'true' );
url.searchParams.set( 'studioSiteId', site.id );
url.searchParams.set( 'new', site.customDomain ?? site.name );
url.searchParams.set( 'autoOpenPush', 'true' );
return url.toString();
}
6 changes: 6 additions & 0 deletions apps/ui/src/lib/docs-links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ const DOCS_LINKS = {
docsSslInStudio: {
en: 'https://developer.wordpress.com/docs/developer-tools/studio/ssl-in-studio/',
},
docsStudio: {
en: 'https://developer.wordpress.com/docs/developer-tools/studio/',
es: 'https://developer.wordpress.com/es/docs/herramientas-para-desarrolladores/studio/',
},
} as const satisfies Record< string, TranslatedLink >;

export const REPORT_ISSUE_URL = 'https://github.com/Automattic/studio/issues/new/choose';

export type DocsLinkKey = keyof typeof DOCS_LINKS;

export function getLocalizedLink( locale: SupportedLocale | undefined, key: DocsLinkKey ): string {
Expand Down
Loading