diff --git a/apps/editing-toolkit/editing-toolkit-plugin/help-center/class-help-center.php b/apps/editing-toolkit/editing-toolkit-plugin/help-center/class-help-center.php
index c13df180a03311..da7817a225cef8 100644
--- a/apps/editing-toolkit/editing-toolkit-plugin/help-center/class-help-center.php
+++ b/apps/editing-toolkit/editing-toolkit-plugin/help-center/class-help-center.php
@@ -124,11 +124,21 @@ public function enqueue_script() {
'before'
);
+ $user_id = get_current_user_id();
+ $user = get_userdata( $user_id );
+ $primary_site_id = $user->primary_blog;
+ $user_email = $user->user_email;
+
wp_localize_script(
'help-center-script',
'helpCenterData',
array(
- 'currentSite' => $this->get_current_site(),
+ 'currentSite' => $this->get_current_site(),
+ 'adminUrl' => admin_url(),
+ 'locale' => get_locale(),
+ 'currentUserId' => get_current_user_id(),
+ 'primarySiteId' => $primary_site_id,
+ 'userEmail' => $user_email,
)
);
diff --git a/apps/editing-toolkit/editing-toolkit-plugin/help-center/src/CalypsoStateProvider.js b/apps/editing-toolkit/editing-toolkit-plugin/help-center/src/CalypsoStateProvider.js
deleted file mode 100644
index 8a88d98ebca0e3..00000000000000
--- a/apps/editing-toolkit/editing-toolkit-plugin/help-center/src/CalypsoStateProvider.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * Global polyfills
- */
-import '@automattic/calypso-polyfills';
-import i18n from 'i18n-calypso';
-import { Provider } from 'react-redux';
-import { createStore, applyMiddleware, compose } from 'redux';
-import thunkMiddleware from 'redux-thunk';
-import QuerySites from 'calypso/components/data/query-sites';
-import { initializeAnalytics } from 'calypso/lib/analytics/init';
-import getSuperProps from 'calypso/lib/analytics/super-props';
-import { rawCurrentUserFetch, filterUserObject } from 'calypso/lib/user/shared-utils';
-import analyticsMiddleware from 'calypso/state/analytics/middleware';
-import consoleDispatcher from 'calypso/state/console-dispatch';
-import { setCurrentUser } from 'calypso/state/current-user/actions';
-import currentUser from 'calypso/state/current-user/reducer';
-import { setStore } from 'calypso/state/redux-store';
-import sites from 'calypso/state/sites/reducer';
-import { setSelectedSiteId } from 'calypso/state/ui/actions';
-import { setSection } from 'calypso/state/ui/section/actions';
-import { combineReducers, addReducerEnhancer } from 'calypso/state/utils';
-
-const rootReducer = combineReducers( {
- currentUser,
- sites,
-} );
-
-const store = createStore(
- rootReducer,
- compose(
- consoleDispatcher,
- addReducerEnhancer,
- applyMiddleware( thunkMiddleware, analyticsMiddleware )
- )
-);
-
-setStore( store );
-
-const section = window?.helpCenterAdminBar?.isLoaded ? 'wp-admin' : 'gutenberg-editor';
-const currentSite = window.helpCenterData.currentSite;
-currentSite && store.dispatch( setSelectedSiteId( currentSite.ID ) );
-store.dispatch( setSection( { name: section } ) );
-
-i18n.configure( { defaultLocaleSlug: window.helpCenterLocale?.locale } );
-
-rawCurrentUserFetch()
- .then( filterUserObject )
- .then( ( user ) => {
- if ( user ) {
- store.dispatch( setCurrentUser( user ) );
- }
- initializeAnalytics( user || undefined, getSuperProps( store ) );
- } );
-
-export default function CalypsoStateProvider( { children } ) {
- return (
-
- <>
-
- { children }
- >
-
- );
-}
diff --git a/apps/editing-toolkit/editing-toolkit-plugin/help-center/src/admin-bar.js b/apps/editing-toolkit/editing-toolkit-plugin/help-center/src/admin-bar.js
index 769d22566925e4..b28dedb0643773 100644
--- a/apps/editing-toolkit/editing-toolkit-plugin/help-center/src/admin-bar.js
+++ b/apps/editing-toolkit/editing-toolkit-plugin/help-center/src/admin-bar.js
@@ -5,7 +5,6 @@ import { useDispatch, useSelect } from '@wordpress/data';
import { useEffect, useCallback } from '@wordpress/element';
import * as ReactDOM from 'react-dom';
import { whatsNewQueryClient } from '../../common/what-new-query-client';
-import CalypsoStateProvider from './CalypsoStateProvider';
function AdminHelpCenterContent() {
const { setShowHelpCenter } = useDispatch( 'automattic/help-center' );
@@ -34,15 +33,27 @@ function AdminHelpCenterContent() {
button.onclick = handleToggleHelpCenter;
- return ;
+ return (
+
+ );
}
if ( window?.helpCenterAdminBar?.isLoaded ) {
ReactDOM.render(
-
-
-
+
,
document.getElementById( 'help-center-masterbar' )
);
diff --git a/apps/editing-toolkit/editing-toolkit-plugin/help-center/src/help-center.js b/apps/editing-toolkit/editing-toolkit-plugin/help-center/src/help-center.js
index 6c458ab7b77203..eb0482c633f0ab 100644
--- a/apps/editing-toolkit/editing-toolkit-plugin/help-center/src/help-center.js
+++ b/apps/editing-toolkit/editing-toolkit-plugin/help-center/src/help-center.js
@@ -1,6 +1,5 @@
import { recordTracksEvent } from '@automattic/calypso-analytics';
import HelpCenter, { HelpIcon } from '@automattic/help-center';
-import { LocaleProvider } from '@automattic/i18n-utils';
import { QueryClientProvider } from '@tanstack/react-query';
import { Button, Fill } from '@wordpress/components';
import { useMediaQuery } from '@wordpress/compose';
@@ -8,16 +7,12 @@ import { useDispatch, useSelect } from '@wordpress/data';
import { useCallback, useEffect, useState } from '@wordpress/element';
import { registerPlugin } from '@wordpress/plugins';
import clsx from 'clsx';
-import { useSelector } from 'react-redux';
-import { getSectionName } from 'calypso/state/ui/selectors';
import { whatsNewQueryClient } from '../../common/what-new-query-client';
-import CalypsoStateProvider from './CalypsoStateProvider';
import useActionHooks from './use-action-hooks';
function HelpCenterContent() {
const [ helpIconRef, setHelpIconRef ] = useState();
const isDesktop = useMediaQuery( '(min-width: 480px)' );
- const sectionName = useSelector( getSectionName );
const [ showHelpIcon, setShowHelpIcon ] = useState( false );
const { setShowHelpCenter } = useDispatch( 'automattic/help-center' );
@@ -27,7 +22,7 @@ function HelpCenterContent() {
recordTracksEvent( `calypso_inlinehelp_${ show ? 'close' : 'show' }`, {
force_site_id: true,
location: 'help-center',
- section: sectionName,
+ section: 'gutenberg-editor',
} );
setShowHelpCenter( ! show );
@@ -67,7 +62,19 @@ function HelpCenterContent() {
return (
<>
{ isDesktop && showHelpIcon && { content } }
-
+
>
);
}
@@ -76,11 +83,7 @@ registerPlugin( 'etk-help-center', {
render: () => {
return (
-
-
-
-
-
+
);
},
diff --git a/client/blocks/inline-help/inline-help-search-card.tsx b/client/blocks/inline-help/inline-help-search-card.tsx
index 615a4fecc2be1d..a1976c222bdc76 100644
--- a/client/blocks/inline-help/inline-help-search-card.tsx
+++ b/client/blocks/inline-help/inline-help-search-card.tsx
@@ -2,11 +2,8 @@
import { recordTracksEvent } from '@automattic/calypso-analytics';
import debugFactory from 'debug';
import { useTranslate } from 'i18n-calypso';
-import PropTypes from 'prop-types';
import { useRef, useEffect } from 'react';
import SearchCard from 'calypso/components/search-card';
-import { useSelector } from 'calypso/state';
-import { getSectionName } from 'calypso/state/ui/selectors';
/**
* Module variables
@@ -19,6 +16,7 @@ type Props = {
isVisible?: boolean;
placeholder?: string;
onSearch?: ( query: string ) => void;
+ sectionName: string;
};
const AUTO_FOCUS_LOCATION = [ 'help-center', 'inline-help-popover' ];
@@ -29,10 +27,10 @@ const InlineHelpSearchCard = ( {
isVisible = true,
placeholder,
onSearch,
+ sectionName,
}: Props ) => {
const cardRef = useRef< { searchInput: HTMLInputElement } >();
const translate = useTranslate();
- const sectionName = useSelector( getSectionName );
// Focus in the input element.
useEffect( () => {
@@ -81,11 +79,4 @@ const InlineHelpSearchCard = ( {
);
};
-InlineHelpSearchCard.propTypes = {
- searchQuery: PropTypes.string,
- onSearch: PropTypes.func,
- placeholder: PropTypes.string,
- location: PropTypes.string,
-};
-
export default InlineHelpSearchCard;
diff --git a/client/landing/stepper/declarative-flow/internals/components/help-center/async.tsx b/client/landing/stepper/declarative-flow/internals/components/help-center/async.tsx
index 154e795349320f..b5eaf04994b8bb 100644
--- a/client/landing/stepper/declarative-flow/internals/components/help-center/async.tsx
+++ b/client/landing/stepper/declarative-flow/internals/components/help-center/async.tsx
@@ -1,6 +1,15 @@
+import { isWpComBusinessPlan, isWpComEcommercePlan } from '@automattic/calypso-products';
import { HelpCenter, HelpCenterSelect } from '@automattic/data-stores';
+import { useLocale } from '@automattic/i18n-utils';
import { useDispatch, useSelect } from '@wordpress/data';
import AsyncLoad from 'calypso/components/async-load';
+import { useSelector } from 'calypso/state';
+import { getCurrentUserEmail, getCurrentUserId } from 'calypso/state/current-user/selectors';
+import { getUserPurchases } from 'calypso/state/purchases/selectors';
+import getPrimarySiteId from 'calypso/state/selectors/get-primary-site-id';
+import hasCancelableUserPurchases from 'calypso/state/selectors/has-cancelable-user-purchases';
+import { getSiteAdminUrl, isJetpackSite } from 'calypso/state/sites/selectors';
+import { getSection, getSelectedSiteId } from 'calypso/state/ui/selectors';
const HELP_CENTER_STORE = HelpCenter.register();
@@ -10,6 +19,24 @@ const AsyncHelpCenter = () => {
( select ) => ( select( HELP_CENTER_STORE ) as HelpCenterSelect ).isHelpCenterShown(),
[]
);
+ const locale = useLocale();
+ const sectionName = useSelector( getSection );
+ const currentUserId = useSelector( getCurrentUserId );
+ const currentUserEmail = useSelector( getCurrentUserEmail );
+ const selectedSiteId = useSelector( getSelectedSiteId );
+ const userPurchases = useSelector( getUserPurchases );
+ const hasPurchases = useSelector( hasCancelableUserPurchases );
+ const primarySiteId = useSelector( getPrimarySiteId );
+ const adminUrl = useSelector( ( state ) => getSiteAdminUrl( state, selectedSiteId ) );
+ const isJetpack = useSelector( ( state ) =>
+ isJetpackSite( state, selectedSiteId, { treatAtomicAsJetpackSite: false } )
+ );
+ const purchases = useSelector( getUserPurchases );
+ const purchaseSlugs = purchases && purchases.map( ( purchase ) => purchase.productSlug );
+ const isBusinessOrEcomPlanUser = !! (
+ purchaseSlugs &&
+ ( purchaseSlugs.some( isWpComBusinessPlan ) || purchaseSlugs.some( isWpComEcommercePlan ) )
+ );
const handleClose = () => setShowHelpCenter( false );
@@ -18,7 +45,22 @@ const AsyncHelpCenter = () => {
}
return (
-
+
);
};
diff --git a/client/layout/index.jsx b/client/layout/index.jsx
index fce910bba32f21..62b2188076b588 100644
--- a/client/layout/index.jsx
+++ b/client/layout/index.jsx
@@ -1,6 +1,6 @@
import config from '@automattic/calypso-config';
import { HelpCenter } from '@automattic/data-stores';
-import { shouldLoadInlineHelp } from '@automattic/help-center';
+import { useLocale } from '@automattic/i18n-utils';
import { isWithinBreakpoint, subscribeIsWithinBreakpoint } from '@automattic/viewport';
import { useBreakpoint } from '@automattic/viewport-react';
import { useShouldShowCriticalAnnouncementsQuery } from '@automattic/whats-new';
@@ -32,9 +32,14 @@ import { isWcMobileApp, isWpMobileApp } from 'calypso/lib/mobile-app';
import isReaderTagEmbedPage from 'calypso/lib/reader/is-reader-tag-embed-page';
import { getMessagePathForJITM } from 'calypso/lib/route';
import UserVerificationChecker from 'calypso/lib/user/verification-checker';
+import { useSelector } from 'calypso/state';
import { getAdminColor } from 'calypso/state/admin-color/selectors';
import { isOffline } from 'calypso/state/application/selectors';
-import { isUserLoggedIn } from 'calypso/state/current-user/selectors';
+import {
+ isUserLoggedIn,
+ getCurrentUserEmail,
+ getCurrentUserId,
+} from 'calypso/state/current-user/selectors';
import {
getShouldShowCollapsedGlobalSidebar,
getShouldShowGlobalSidebar,
@@ -43,11 +48,14 @@ import {
import { isUserNewerThan, WEEK_IN_MILLISECONDS } from 'calypso/state/guided-tours/contexts';
import { getCurrentOAuth2Client } from 'calypso/state/oauth2-clients/ui/selectors';
import { getPreference } from 'calypso/state/preferences/selectors';
+import { getUserPurchases } from 'calypso/state/purchases/selectors';
import getCurrentQueryArguments from 'calypso/state/selectors/get-current-query-arguments';
+import getPrimarySiteId from 'calypso/state/selectors/get-primary-site-id';
+import hasCancelableUserPurchases from 'calypso/state/selectors/has-cancelable-user-purchases';
import isAtomicSite from 'calypso/state/selectors/is-site-automated-transfer';
import isWooCommerceCoreProfilerFlow from 'calypso/state/selectors/is-woocommerce-core-profiler-flow';
import { getIsOnboardingAffiliateFlow } from 'calypso/state/signup/flow/selectors';
-import { isJetpackSite } from 'calypso/state/sites/selectors';
+import { getSiteAdminUrl, isJetpackSite } from 'calypso/state/sites/selectors';
import { isSupportSession } from 'calypso/state/support/selectors';
import { getCurrentLayoutFocus } from 'calypso/state/ui/layout-focus/selectors';
import {
@@ -58,7 +66,8 @@ import {
import BodySectionCssClass from './body-section-css-class';
import GlobalNotifications from './global-notifications';
import LayoutLoader from './loader';
-import { handleScroll } from './utils';
+import { shouldLoadInlineHelp, handleScroll } from './utils';
+
// goofy import for environment badge, which is SSR'd
import 'calypso/components/environment-badge/style.scss';
@@ -136,6 +145,18 @@ function HelpCenterLoader( { sectionName, loadHelpCenter, currentRoute } ) {
setShowHelpCenter( false );
}, [ setShowHelpCenter ] );
+ const locale = useLocale();
+ const currentUserId = useSelector( getCurrentUserId );
+ const currentUserEmail = useSelector( getCurrentUserEmail );
+ const selectedSiteId = useSelector( getSelectedSiteId );
+ const userPurchases = useSelector( getUserPurchases );
+ const hasPurchases = useSelector( hasCancelableUserPurchases );
+ const primarySiteId = useSelector( getPrimarySiteId );
+ const adminUrl = useSelector( ( state ) => getSiteAdminUrl( state, selectedSiteId ) );
+ const isJetpack = useSelector( ( state ) =>
+ isJetpackSite( state, selectedSiteId, { treatAtomicAsJetpackSite: false } )
+ );
+
if ( ! loadHelpCenter ) {
return null;
}
@@ -143,9 +164,19 @@ function HelpCenterLoader( { sectionName, loadHelpCenter, currentRoute } ) {
return (
diff --git a/client/layout/utils.ts b/client/layout/utils.ts
index 7e2f98d8b8bfba..d600971e858238 100644
--- a/client/layout/utils.ts
+++ b/client/layout/utils.ts
@@ -1,9 +1,35 @@
+import { isWpMobileApp } from 'calypso/lib/mobile-app';
let lastScrollPosition = 0; // Used for calculating scroll direction.
let sidebarTop = 0; // Current sidebar top position.
let pinnedSidebarTop = true; // We pin sidebar to the top by default.
let pinnedSidebarBottom = false;
let ticking = false; // Used for Scroll event throttling.
+export function shouldLoadInlineHelp( sectionName: string, currentRoute: string ) {
+ if ( isWpMobileApp() ) {
+ return false;
+ }
+
+ const exemptedSections = [ 'jetpack-connect', 'devdocs', 'help', 'home' ];
+ const exemptedRoutes = [ '/log-in/jetpack' ];
+ const exemptedRoutesStartingWith = [
+ '/start/p2',
+ '/start/videopress',
+ '/start/setup-site',
+ '/start/newsletter',
+ '/plugins/domain',
+ '/plugins/marketplace/setup',
+ ];
+
+ return (
+ ! exemptedSections.includes( sectionName ) &&
+ ! exemptedRoutes.includes( currentRoute ) &&
+ ! exemptedRoutesStartingWith.some( ( startsWithString ) =>
+ currentRoute.startsWith( startsWithString )
+ )
+ );
+}
+
export const handleScroll = ( event: React.UIEvent< HTMLElement > ): void => {
// Do not run until next requestAnimationFrame or if running out of browser context.
if ( ticking ) {
diff --git a/client/state/reader/posts/actions.js b/client/state/reader/posts/actions.js
index 027f683c07ccf6..2fba94f372ef1b 100644
--- a/client/state/reader/posts/actions.js
+++ b/client/state/reader/posts/actions.js
@@ -1,7 +1,5 @@
-import apiFetch from '@wordpress/api-fetch';
import { filter, forEach, partition, get } from 'lodash';
import { v4 as uuid } from 'uuid';
-import wpcomRequest, { canAccessWpcomApis } from 'wpcom-proxy-request';
import { bumpStat } from 'calypso/lib/analytics/mc';
import wpcom from 'calypso/lib/wp';
import readerContentWidth from 'calypso/reader/lib/content-width';
@@ -26,7 +24,7 @@ function trackRailcarRender( post ) {
tracks.recordTracksEvent( 'calypso_traintracks_render', post.railcar );
}
-function fetchForKey( postKey, isHelpCenter = false ) {
+function fetchForKey( postKey ) {
const query = {};
const contentWidth = readerContentWidth();
@@ -35,23 +33,6 @@ function fetchForKey( postKey, isHelpCenter = false ) {
}
if ( postKey.blogId ) {
- if ( isHelpCenter ) {
- return canAccessWpcomApis()
- ? wpcomRequest( {
- path: `help/article/${ encodeURIComponent( postKey.blogId ) }/${ encodeURIComponent(
- postKey.postId
- ) }`,
- apiNamespace: 'wpcom/v2/',
- apiVersion: '2',
- } )
- : apiFetch( {
- global: true,
- path: `/help-center/fetch-post?post_id=${ encodeURIComponent(
- postKey.postId
- ) }&blog_id=${ encodeURIComponent( postKey.blogId ) }`,
- } );
- }
-
return wpcom.req.get(
`/read/sites/${ encodeURIComponent( postKey.blogId ) }/posts/${ encodeURIComponent(
postKey.postId
diff --git a/packages/data-stores/src/contextual-help/contextual-help.tsx b/packages/data-stores/src/contextual-help/contextual-help.tsx
index 259a68ec1416c8..5b6d64bb366563 100644
--- a/packages/data-stores/src/contextual-help/contextual-help.tsx
+++ b/packages/data-stores/src/contextual-help/contextual-help.tsx
@@ -604,7 +604,7 @@ type SectionForPostsAndPages = 'posts' | 'pages';
export type Section = SectionForVideos | SectionForTours | SectionForPostsAndPages;
-export function getContextResults( section: Section, siteIntent: string ) {
+export function getContextResults( section: string, siteIntent: string ) {
// Posts and Pages have a common help section
if ( section === 'posts' || section === 'pages' ) {
section = 'posts-pages';
diff --git a/packages/help-center/src/components/help-center-article-fetching-content.tsx b/packages/help-center/src/components/help-center-article-fetching-content.tsx
index 8522d5a9cec880..e1e68afe542246 100644
--- a/packages/help-center/src/components/help-center-article-fetching-content.tsx
+++ b/packages/help-center/src/components/help-center-article-fetching-content.tsx
@@ -1,14 +1,12 @@
/* eslint-disable no-restricted-imports */
import { useLocale } from '@automattic/i18n-utils';
import { useEffect } from 'react';
-import { useSelector } from 'react-redux';
import { SUPPORT_BLOG_ID } from 'calypso/blocks/inline-help/constants';
import QueryReaderPost from 'calypso/components/data/query-reader-post';
import QueryReaderSite from 'calypso/components/data/query-reader-site';
import useSupportArticleAlternatesQuery from 'calypso/data/support-article-alternates/use-support-article-alternates-query';
-import { getPostByKey } from 'calypso/state/reader/posts/selectors';
+import { usePostByKey } from '../hooks/use-post-by-key';
import ArticleContent from './help-center-article-content';
-
// import './style.scss';
import './help-center-article-content.scss';
@@ -36,7 +34,7 @@ interface ArticleFetchingContentProps {
const ArticleFetchingContent = ( { postId, blogId, articleUrl }: ArticleFetchingContentProps ) => {
const postKey = useSupportArticleAlternatePostKey( +( blogId ?? SUPPORT_BLOG_ID ), postId );
- const post = useSelector( ( state ) => getPostByKey( state, postKey ) );
+ const post = usePostByKey( postKey ).data;
const isLoading = ! post?.content || ! postKey;
const siteId = post?.site_ID;
const shouldQueryReaderPost = ! post && postKey;
diff --git a/packages/help-center/src/components/help-center-contact-form.tsx b/packages/help-center/src/components/help-center-contact-form.tsx
index 67374d4ace4bf9..288d5bedf1c7f8 100644
--- a/packages/help-center/src/components/help-center-contact-form.tsx
+++ b/packages/help-center/src/components/help-center-contact-form.tsx
@@ -14,17 +14,15 @@ import { useDispatch, useSelect } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import { Icon, info } from '@wordpress/icons';
import { useCallback, useEffect, useRef, useState } from 'react';
-import { useSelector } from 'react-redux';
import { useNavigate, useLocation } from 'react-router-dom';
import { useDebounce } from 'use-debounce';
import { decodeEntities, preventWidows } from 'calypso/lib/formatting';
import { isWcMobileApp } from 'calypso/lib/mobile-app';
import { getQueryArgs } from 'calypso/lib/query-args';
-import { getCurrentUserEmail, getCurrentUserId } from 'calypso/state/current-user/selectors';
-import { getSectionName } from 'calypso/state/ui/selectors';
/**
* Internal Dependencies
*/
+import { useHelpCenterContext } from '../contexts/HelpCenterContext';
import { useJetpackSearchAIQuery } from '../data/use-jetpack-search-ai';
import { useSiteAnalysis } from '../data/use-site-analysis';
import { useSubmitForumsMutation } from '../data/use-submit-forums-topic';
@@ -94,7 +92,8 @@ type HelpCenterContactFormProps = {
export const HelpCenterContactForm = ( props: HelpCenterContactFormProps ) => {
const { search } = useLocation();
- const sectionName = useSelector( getSectionName );
+ const helpCenterContext = useHelpCenterContext();
+ const sectionName = helpCenterContext.sectionName;
const params = new URLSearchParams( search );
const mode = params.get( 'mode' ) as Mode;
const { onSubmit } = props;
@@ -106,11 +105,11 @@ export const HelpCenterContactForm = ( props: HelpCenterContactFormProps ) => {
const locale = useLocale();
const { isPending: submittingTicket, mutateAsync: submitTicket } = useSubmitTicketMutation();
const { isPending: submittingTopic, mutateAsync: submitTopic } = useSubmitForumsMutation();
- const userId = useSelector( getCurrentUserId );
+ const userId = helpCenterContext?.currentUserId;
const { data: userSites } = useUserSites( userId );
const userWithNoSites = userSites?.sites.length === 0;
const queryClient = useQueryClient();
- const email = useSelector( getCurrentUserEmail );
+ const email = helpCenterContext.currentUserEmail;
const [ sitePickerChoice, setSitePickerChoice ] = useState< 'CURRENT_SITE' | 'OTHER_SITE' >(
'CURRENT_SITE'
);
diff --git a/packages/help-center/src/components/help-center-contact-page.tsx b/packages/help-center/src/components/help-center-contact-page.tsx
index fa04c657177be9..9d427e31877b74 100644
--- a/packages/help-center/src/components/help-center-contact-page.tsx
+++ b/packages/help-center/src/components/help-center-contact-page.tsx
@@ -16,13 +16,12 @@ import { comment, Icon } from '@wordpress/icons';
import { useI18n } from '@wordpress/react-i18n';
import clsx from 'clsx';
import { FC, useState } from 'react';
-import { useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
-import { getSectionName } from 'calypso/state/ui/selectors';
/**
* Internal Dependencies
*/
import { BackButton } from '..';
+import { useHelpCenterContext } from '../contexts/HelpCenterContext';
import {
useChatStatus,
useChatWidget,
@@ -85,8 +84,9 @@ export const HelpCenterContactPage: FC< HelpCenterContactPageProps > = ( {
isEligibleForChat || hasActiveChats
);
+ const helpCenterContext = useHelpCenterContext();
+ const sectionName = helpCenterContext.sectionName;
const [ hasSubmittingError, setHasSubmittingError ] = useState< boolean >( false );
- const sectionName = useSelector( getSectionName );
const currentSite = useSelect( ( select ) => {
const helpCenterSelect: HelpCenterSelect = select( HELP_CENTER_STORE );
return helpCenterSelect.getSite();
@@ -284,7 +284,8 @@ export const HelpCenterContactPage: FC< HelpCenterContactPageProps > = ( {
export const HelpCenterContactButton: FC = () => {
const { __ } = useI18n();
const { url, isLoading } = useStillNeedHelpURL();
- const sectionName = useSelector( getSectionName );
+ const helpCenterContext = useHelpCenterContext();
+ const sectionName = helpCenterContext.sectionName;
const redirectToWpcom = url === 'https://wordpress.com/help/contact';
const trackContactButtonClicked = () => {
diff --git a/packages/help-center/src/components/help-center-content.tsx b/packages/help-center/src/components/help-center-content.tsx
index f9ecc642e842de..3938eccc2ab248 100644
--- a/packages/help-center/src/components/help-center-content.tsx
+++ b/packages/help-center/src/components/help-center-content.tsx
@@ -8,12 +8,11 @@ import { CardBody, Disabled } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { useEffect, useRef } from '@wordpress/element';
import React, { useCallback, useState } from 'react';
-import { useSelector } from 'react-redux';
import { Route, Routes, useLocation, useNavigate } from 'react-router-dom';
-import { getSectionName, getSelectedSiteId } from 'calypso/state/ui/selectors';
/**
* Internal Dependencies
*/
+import { useHelpCenterContext } from '../contexts/HelpCenterContext';
import { useShouldUseWapuu } from '../hooks';
import { HELP_CENTER_STORE } from '../stores';
import { HelpCenterContactForm } from './help-center-contact-form';
@@ -47,7 +46,9 @@ const HelpCenterContent: React.FC< { isRelative?: boolean; currentRoute?: string
const location = useLocation();
const navigate = useNavigate();
const containerRef = useRef< HTMLDivElement >( null );
- const section = useSelector( getSectionName );
+ //const {}
+
+ const { sectionName, selectedSiteId } = useHelpCenterContext();
const shouldUseWapuu = useShouldUseWapuu();
const { isMinimized } = useSelect( ( select ) => {
const store = select( HELP_CENTER_STORE ) as HelpCenterSelect;
@@ -55,17 +56,16 @@ const HelpCenterContent: React.FC< { isRelative?: boolean; currentRoute?: string
isMinimized: store.getIsMinimized(),
};
}, [] );
- const selectedSiteId = useSelector( getSelectedSiteId );
useEffect( () => {
recordTracksEvent( 'calypso_helpcenter_page_open', {
pathname: location.pathname,
search: location.search,
- section,
+ section: sectionName,
force_site_id: true,
location: 'help-center',
} );
- }, [ location, section ] );
+ }, [ location, sectionName ] );
const { initialRoute } = useSelect(
( select ) => ( {
diff --git a/packages/help-center/src/components/help-center-embed-result.tsx b/packages/help-center/src/components/help-center-embed-result.tsx
index f68d7c6141d240..8403a7079f084d 100644
--- a/packages/help-center/src/components/help-center-embed-result.tsx
+++ b/packages/help-center/src/components/help-center-embed-result.tsx
@@ -4,9 +4,8 @@ import { Button, Flex, FlexItem } from '@wordpress/components';
import { useEffect } from '@wordpress/element';
import { Icon, external } from '@wordpress/icons';
import React from 'react';
-import { useSelector } from 'react-redux';
import { useLocation, useNavigate } from 'react-router-dom';
-import { getSectionName } from 'calypso/state/ui/selectors';
+import { useHelpCenterContext } from '../contexts/HelpCenterContext';
import { BackButton } from './back-button';
import { BackToTopButton } from './back-to-top-button';
import ArticleFetchingContent from './help-center-article-fetching-content';
@@ -14,7 +13,7 @@ import ArticleFetchingContent from './help-center-article-fetching-content';
export const HelpCenterEmbedResult: React.FC = () => {
const { search } = useLocation();
const navigate = useNavigate();
- const sectionName = useSelector( getSectionName );
+ const { sectionName } = useHelpCenterContext();
const params = new URLSearchParams( search );
const postId = params.get( 'postId' );
diff --git a/packages/help-center/src/components/help-center-launchpad.tsx b/packages/help-center/src/components/help-center-launchpad.tsx
index 81cb6f4e584e6c..0c8b387a668dc6 100644
--- a/packages/help-center/src/components/help-center-launchpad.tsx
+++ b/packages/help-center/src/components/help-center-launchpad.tsx
@@ -7,8 +7,7 @@ import { localizeUrl } from '@automattic/i18n-utils';
import { useSelect } from '@wordpress/data';
import { chevronRight, Icon } from '@wordpress/icons';
import { useI18n } from '@wordpress/react-i18n';
-import { useSelector } from 'react-redux';
-import { getSectionName, getSelectedSiteId } from 'calypso/state/ui/selectors';
+import { useHelpCenterContext } from '../contexts/HelpCenterContext';
import { SITE_STORE } from '../stores';
import type { SiteSelect } from '@automattic/data-stores';
@@ -30,15 +29,15 @@ const getEnvironmentHostname = () => {
export const HelpCenterLaunchpad = () => {
const { __ } = useI18n();
+ const { selectedSiteId, sectionName } = useHelpCenterContext();
- const siteId = useSelector( getSelectedSiteId );
const site = useSelect(
( select ) => {
- if ( siteId ) {
- return ( select( SITE_STORE ) as SiteSelect ).getSite( siteId );
+ if ( selectedSiteId ) {
+ return ( select( SITE_STORE ) as SiteSelect ).getSite( selectedSiteId );
}
},
- [ siteId ]
+ [ selectedSiteId ]
);
let siteIntent = site && site?.options?.site_intent;
let siteSlug = site && new URL( site.URL ).host;
@@ -54,7 +53,6 @@ export const HelpCenterLaunchpad = () => {
data?.checklist?.filter( ( checklistItem ) => checklistItem.completed ).length || 1;
const launchpadURL = `${ getEnvironmentHostname() }/setup/${ siteIntent }/launchpad?siteSlug=${ siteSlug }`;
- const sectionName = useSelector( getSectionName );
const handleLaunchpadHelpLinkClick = () => {
recordTracksEvent( 'calypso_help_launchpad_click', {
link: launchpadURL,
diff --git a/packages/help-center/src/components/help-center-more-resources.tsx b/packages/help-center/src/components/help-center-more-resources.tsx
index 1f9bc7be1a56ba..622d036c63cdbc 100644
--- a/packages/help-center/src/components/help-center-more-resources.tsx
+++ b/packages/help-center/src/components/help-center-more-resources.tsx
@@ -1,7 +1,6 @@
/* eslint-disable no-restricted-imports */
/* eslint-disable wpcalypso/jsx-classname-namespace */
import { recordTracksEvent } from '@automattic/calypso-analytics';
-import { isWpComBusinessPlan, isWpComEcommercePlan } from '@automattic/calypso-products';
import { localizeUrl } from '@automattic/i18n-utils';
import WhatsNewGuide, { useWhatsNewAnnouncementsQuery } from '@automattic/whats-new';
import { Button, SVG, Circle } from '@wordpress/components';
@@ -9,9 +8,7 @@ import { useSelect, useDispatch } from '@wordpress/data';
import { useState } from '@wordpress/element';
import { Icon, captureVideo, formatListNumbered, external, institution } from '@wordpress/icons';
import { useI18n } from '@wordpress/react-i18n';
-import { useSelector } from 'react-redux';
-import { getUserPurchases } from 'calypso/state/purchases/selectors';
-import { getSectionName, getSelectedSiteId } from 'calypso/state/ui/selectors';
+import { useHelpCenterContext } from '../contexts/HelpCenterContext';
import { NewReleases } from '../icons';
import { HELP_CENTER_STORE } from '../stores';
import type { HelpCenterSelect } from '@automattic/data-stores';
@@ -28,15 +25,8 @@ type CoreDataPlaceholder = {
export const HelpCenterMoreResources = () => {
const { __ } = useI18n();
- const sectionName = useSelector( getSectionName );
- const purchases = useSelector( getUserPurchases );
- const siteId = useSelector( getSelectedSiteId );
- const purchaseSlugs = purchases && purchases.map( ( purchase ) => purchase.productSlug );
- const isBusinessOrEcomPlanUser = !! (
- purchaseSlugs &&
- ( purchaseSlugs.some( isWpComBusinessPlan ) || purchaseSlugs.some( isWpComEcommercePlan ) )
- );
- const { data } = useWhatsNewAnnouncementsQuery( siteId?.toString() );
+ const { sectionName, isBusinessOrEcomPlanUser, selectedSiteId } = useHelpCenterContext();
+ const { data } = useWhatsNewAnnouncementsQuery( selectedSiteId?.toString() );
const showWhatsNewItem = data && data.length > 0;
@@ -160,7 +150,7 @@ export const HelpCenterMoreResources = () => {
{ showGuide && (
setShowGuide( false ) }
- siteId={ siteId?.toString() || '' }
+ siteId={ selectedSiteId?.toString() || '' }
/>
) }
>
diff --git a/packages/help-center/src/components/help-center-search-results.tsx b/packages/help-center/src/components/help-center-search-results.tsx
index 02a548c4c7ac39..4d3c2112cfc42b 100644
--- a/packages/help-center/src/components/help-center-search-results.tsx
+++ b/packages/help-center/src/components/help-center-search-results.tsx
@@ -22,16 +22,15 @@ import { useRtl } from 'i18n-calypso';
import { debounce } from 'lodash';
import PropTypes from 'prop-types';
import { Fragment, useEffect, useMemo } from 'react';
-import { useDispatch, useSelector } from 'react-redux';
+import { useDispatch } from 'react-redux';
import { useDebounce } from 'use-debounce';
import QueryUserPurchases from 'calypso/components/data/query-user-purchases';
import { useHelpSearchQuery } from 'calypso/data/help/use-help-search-query';
import { decodeEntities, preventWidows } from 'calypso/lib/formatting';
import { recordTracksEvent } from 'calypso/state/analytics/actions';
-import getAdminHelpResults from 'calypso/state/selectors/get-admin-help-results';
-import hasCancelableUserPurchases from 'calypso/state/selectors/has-cancelable-user-purchases';
import { useSiteOption } from 'calypso/state/sites/hooks';
-import { getSectionName } from 'calypso/state/ui/selectors';
+import { useHelpCenterContext } from '../contexts/HelpCenterContext';
+import { useAdminResults } from '../hooks/use-admin-results';
import { useContextBasedSearchMapping } from '../hooks/use-context-based-search-mapping';
import PlaceholderLines from './placeholder-lines';
import type { SearchResult } from '../types';
@@ -112,9 +111,9 @@ function HelpSearchResults( {
currentRoute,
}: HelpSearchResultsProps ) {
const dispatch = useDispatch();
- const hasPurchases = useSelector( hasCancelableUserPurchases );
- const sectionName = useSelector( getSectionName );
- const adminResults = useSelector( ( state ) => getAdminHelpResults( state, searchQuery, 3 ) );
+ const { hasPurchases, sectionName } = useHelpCenterContext();
+
+ const adminResults = useAdminResults( searchQuery );
const isPurchasesSection = [ 'purchases', 'site-purchases' ].includes( sectionName );
const siteIntent = useSiteOption( 'site_intent' );
diff --git a/packages/help-center/src/components/help-center-search.tsx b/packages/help-center/src/components/help-center-search.tsx
index 4b1e0815958abe..6a9ddaf129626b 100644
--- a/packages/help-center/src/components/help-center-search.tsx
+++ b/packages/help-center/src/components/help-center-search.tsx
@@ -4,11 +4,10 @@ import { recordTracksEvent } from '@automattic/calypso-analytics';
import { useDispatch, useSelect } from '@wordpress/data';
import { useState, useCallback, useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
-import { useSelector } from 'react-redux';
import { useNavigate, useLocation } from 'react-router-dom';
import InlineHelpSearchCard from 'calypso/blocks/inline-help/inline-help-search-card';
import { decodeEntities, preventWidows } from 'calypso/lib/formatting';
-import { getSelectedSiteId } from 'calypso/state/ui/selectors';
+import { useHelpCenterContext } from '../contexts/HelpCenterContext';
import { HELP_CENTER_STORE, SITE_STORE } from '../stores';
import { SearchResult } from '../types';
import { HelpCenterLaunchpad } from './help-center-launchpad';
@@ -28,6 +27,7 @@ export const HelpCenterSearch = ( { onSearchChange, currentRoute }: HelpCenterSe
const { search } = useLocation();
const params = new URLSearchParams( search );
const query = params.get( 'query' );
+ const { sectionName } = useHelpCenterContext();
const [ searchQuery, setSearchQuery ] = useState( query || '' );
const { setSubject, setMessage } = useDispatch( HELP_CENTER_STORE );
@@ -46,10 +46,12 @@ export const HelpCenterSearch = ( { onSearchChange, currentRoute }: HelpCenterSe
[ setSubject, setMessage, onSearchChange ]
);
- const siteId = useSelector( getSelectedSiteId );
+ const { selectedSiteId } = useHelpCenterContext();
+
const site = useSelect(
- ( select ) => siteId && ( select( SITE_STORE ) as SiteSelect ).getSite( siteId ),
- [ siteId ]
+ ( select ) =>
+ selectedSiteId && ( select( SITE_STORE ) as SiteSelect ).getSite( selectedSiteId ),
+ [ selectedSiteId ]
);
let launchpadEnabled = site && site?.options?.launchpad_screen === 'full';
@@ -109,6 +111,7 @@ export const HelpCenterSearch = ( { onSearchChange, currentRoute }: HelpCenterSe
location="help-center"
isVisible
placeholder={ __( 'Search for help', __i18n_text_domain__ ) }
+ sectionName={ sectionName }
/>
{
const { __ } = useI18n();
- const sectionName = useSelector( getSectionName );
+ const { sectionName } = useHelpCenterContext();
useEffect( () => {
recordTracksEvent( 'calypso_helpcenter_third_party_cookies_notice_open', {
diff --git a/packages/help-center/src/components/help-center.tsx b/packages/help-center/src/components/help-center.tsx
index c23aa6cc4d8c49..dbdad2d68649dc 100644
--- a/packages/help-center/src/components/help-center.tsx
+++ b/packages/help-center/src/components/help-center.tsx
@@ -4,12 +4,14 @@
*/
import { useSelect, useDispatch } from '@wordpress/data';
import { createPortal, useEffect, useRef } from '@wordpress/element';
-import { useSelector } from 'react-redux';
-import getPrimarySiteId from 'calypso/state/selectors/get-primary-site-id';
-import { getSelectedSiteId } from 'calypso/state/ui/selectors';
/**
* Internal Dependencies
*/
+import {
+ HelpCenterRequiredContextProvider,
+ useHelpCenterContext,
+ type HelpCenterRequiredInformation,
+} from '../contexts/HelpCenterContext';
import { useChatStatus, useZendeskMessaging, useStillNeedHelpURL } from '../hooks';
import { HELP_CENTER_STORE, USER_STORE, SITE_STORE } from '../stores';
import { Container } from '../types';
@@ -84,9 +86,7 @@ const HelpCenter: React.FC< Container > = ( {
};
}, [] );
const { setSite } = useDispatch( HELP_CENTER_STORE );
-
- const siteId = useSelector( getSelectedSiteId );
- const primarySiteId = useSelector( getPrimarySiteId );
+ const { selectedSiteId, primarySiteId } = useHelpCenterContext();
useSelect( ( select ) => ( select( USER_STORE ) as UserSelect ).getCurrentUser(), [] );
@@ -98,8 +98,8 @@ const HelpCenter: React.FC< Container > = ( {
const backendProvidedSite = window?.helpCenterData?.currentSite;
const site = useSelect(
- ( select ) => ( select( SITE_STORE ) as SiteSelect ).getSite( siteId || primarySiteId ),
- [ siteId || primarySiteId ]
+ ( select ) => ( select( SITE_STORE ) as SiteSelect ).getSite( selectedSiteId || primarySiteId ),
+ [ selectedSiteId || primarySiteId ]
);
const usedSite = backendProvidedSite || site;
@@ -144,4 +144,12 @@ const HelpCenter: React.FC< Container > = ( {
);
};
-export default HelpCenter;
+export default function ContextualizedHelpCenter(
+ props: Container & HelpCenterRequiredInformation
+) {
+ return (
+
+
+
+ );
+}
diff --git a/packages/help-center/src/components/index.d.ts b/packages/help-center/src/components/index.d.ts
index 6efd8c9d438b3b..f5a996c03ae595 100644
--- a/packages/help-center/src/components/index.d.ts
+++ b/packages/help-center/src/components/index.d.ts
@@ -11,10 +11,6 @@ declare module 'calypso/components/search-card' {
const SearchCard: FC;
export = SearchCard;
}
-declare module 'calypso/blocks/inline-help/inline-help-search-card' {
- const InlineHelpSearchCard: FC;
- export = InlineHelpSearchCard;
-}
declare module 'calypso/blocks/inline-help/inline-help-search-results' {
const InlineHelpSearchResults: FC;
diff --git a/packages/help-center/src/components/ticket-success-screen.tsx b/packages/help-center/src/components/ticket-success-screen.tsx
index 3393a3008360eb..c05c57a46f3c4d 100644
--- a/packages/help-center/src/components/ticket-success-screen.tsx
+++ b/packages/help-center/src/components/ticket-success-screen.tsx
@@ -2,16 +2,15 @@
import { recordTracksEvent } from '@automattic/calypso-analytics';
import { useI18n } from '@wordpress/react-i18n';
import React from 'react';
-import { useSelector } from 'react-redux';
import { useLocation } from 'react-router-dom';
-import { getSectionName } from 'calypso/state/ui/selectors';
+import { useHelpCenterContext } from '../contexts/HelpCenterContext';
import { BackButton } from './back-button';
import { SuccessIcon } from './success-icon';
export const SuccessScreen: React.FC = () => {
const { __ } = useI18n();
const { search } = useLocation();
- const sectionName = useSelector( getSectionName );
+ const { sectionName } = useHelpCenterContext();
const params = new URLSearchParams( search );
const forumTopicUrl = params.get( 'forumTopic' );
diff --git a/packages/help-center/src/components/types.d.ts b/packages/help-center/src/components/types.d.ts
index b8c2a880eb7cb9..1c9ababf0782cd 100644
--- a/packages/help-center/src/components/types.d.ts
+++ b/packages/help-center/src/components/types.d.ts
@@ -1,7 +1,26 @@
// context here: https://wp.me/pbAok1-1Ao
declare const __i18n_text_domain__: string;
interface Window {
- helpCenterData: any;
+ helpCenterData: {
+ currentSite: {
+ ID: number;
+ name: string;
+ URL: string;
+ plan: {
+ product_slug: string;
+ };
+ is_wpcom_atomic: boolean;
+ jetpack: boolean;
+ site_intent: string;
+ launchpad_screen: string;
+ logo: {
+ id: number;
+ sizes: string[];
+ url: string;
+ };
+ };
+ admin_url: string;
+ };
zE?: (
action: string,
value: string,
@@ -10,4 +29,5 @@ interface Window {
| { id: number; value: string }[]
) => void;
}
+
declare module '*.jpg';
diff --git a/packages/help-center/src/contexts/HelpCenterContext.tsx b/packages/help-center/src/contexts/HelpCenterContext.tsx
new file mode 100644
index 00000000000000..e1c66523673c7d
--- /dev/null
+++ b/packages/help-center/src/contexts/HelpCenterContext.tsx
@@ -0,0 +1,47 @@
+import * as React from 'react';
+import { useContext } from 'react';
+
+export type HelpCenterRequiredInformation = {
+ locale: string;
+ sectionName: string;
+ currentUserId: number;
+ currentUserEmail: string;
+ selectedSiteId: number;
+ hasPurchases: boolean;
+ primarySiteId: number;
+ getGoogleMailServiceFamily: string;
+ onboardingUrl: string;
+ isJetpackSite: boolean;
+ adminUrl: string;
+ isBusinessOrEcomPlanUser: boolean;
+};
+
+const HelpCenterRequiredContext = React.createContext< HelpCenterRequiredInformation >( {
+ locale: '',
+ sectionName: '',
+ currentUserId: 0,
+ currentUserEmail: '',
+ selectedSiteId: 0,
+ hasPurchases: false,
+ primarySiteId: 0,
+ getGoogleMailServiceFamily: '',
+ onboardingUrl: '',
+ isJetpackSite: false,
+ adminUrl: '',
+ isBusinessOrEcomPlanUser: false,
+} );
+
+export const HelpCenterRequiredContextProvider: React.FC< {
+ children: JSX.Element;
+ value: HelpCenterRequiredInformation;
+} > = function ( { children, value } ) {
+ return (
+
+ { children }
+
+ );
+};
+
+export function useHelpCenterContext() {
+ return useContext( HelpCenterRequiredContext );
+}
diff --git a/packages/help-center/src/hooks/use-admin-results.ts b/packages/help-center/src/hooks/use-admin-results.ts
new file mode 100644
index 00000000000000..8e32893453fbde
--- /dev/null
+++ b/packages/help-center/src/hooks/use-admin-results.ts
@@ -0,0 +1,83 @@
+import { generateAdminSections } from '@automattic/data-stores';
+import { useHelpCenterContext } from '../contexts/HelpCenterContext';
+import { useCustomizerUrls } from './use-customizer-url';
+import { useSiteSlug } from './use-site-slug';
+
+/**
+ * Returns a filtered site admin collection.
+ * @param searchTerm The search term
+ * @param collection A collection of site admin objects
+ * @param limit The maximum number of filtered results to return
+ * @returns A filtered (or empty) array
+ */
+export function filterListBySearchTerm(
+ searchTerm = '',
+ collection: ReturnType< typeof generateAdminSections > = [],
+ limit = 4,
+ locale = 'en'
+) {
+ // Early return if search term is empty.
+ if ( ! searchTerm.length ) {
+ return [];
+ }
+
+ const searchTermWords = searchTerm
+ // Split to words.
+ .split( /[\W_]+/g )
+ // Eliminate any empty string results.
+ .filter( Boolean )
+ // Lowercase all words.
+ .map( ( word ) => word.toLowerCase() );
+ if ( ! searchTermWords.length ) {
+ return [];
+ }
+
+ const searchRegex = new RegExp(
+ // Join a series of look aheads
+ // matching full and partial works
+ // Example: "Add a dom" => /(?=.*\badd\b)(?=.*\ba\b)(?=.*\bdom).+/gi
+ searchTermWords
+ .map( ( word, i ) =>
+ // if it's the last word, don't look for a end word boundary
+ // otherwise
+ i + 1 === searchTermWords.length ? `(?=.*\\b${ word })` : `(?=.*\\b${ word }\\b)`
+ )
+ .join( '' ) + '.+',
+ 'gi'
+ );
+
+ const exactMatches: typeof collection = [];
+ const partialMatches: typeof collection = [];
+ const synonymMatches: typeof collection = [];
+
+ collection.forEach( ( item ) => {
+ if ( item.title.toLowerCase() === searchTerm.toLowerCase() ) {
+ exactMatches.push( item );
+ } else if ( searchRegex.test( item.title ) ) {
+ partialMatches.push( item );
+ } else if ( 'en' === locale && item.synonyms?.some( ( s ) => searchTermWords.includes( s ) ) ) {
+ synonymMatches.push( item );
+ }
+ } );
+
+ return [ ...exactMatches, ...partialMatches, ...synonymMatches ].slice( 0, limit );
+}
+
+export function useAdminResults( searchTerm: string ) {
+ const siteSlug = useSiteSlug();
+ const customizerUrls = useCustomizerUrls();
+
+ const { getGoogleMailServiceFamily, locale, onboardingUrl } = useHelpCenterContext();
+ if ( siteSlug ) {
+ const sections = generateAdminSections(
+ siteSlug,
+ customizerUrls,
+ getGoogleMailServiceFamily,
+ onboardingUrl
+ );
+ const filteredSections = filterListBySearchTerm( searchTerm, sections, 4, locale );
+
+ return filteredSections;
+ }
+ return [];
+}
diff --git a/packages/help-center/src/hooks/use-chat-widget.ts b/packages/help-center/src/hooks/use-chat-widget.ts
index f1e76fcf9a52fd..356412a9d04e0c 100644
--- a/packages/help-center/src/hooks/use-chat-widget.ts
+++ b/packages/help-center/src/hooks/use-chat-widget.ts
@@ -3,11 +3,10 @@
*/
import { useZendeskMessaging } from '@automattic/help-center/src/hooks';
import { useDispatch } from '@wordpress/data';
-import { useSelector } from 'react-redux';
/**
* External Dependencies
*/
-import { getSectionName } from 'calypso/state/ui/selectors'; /* eslint-disable-line no-restricted-imports */
+import { useHelpCenterContext } from '../contexts/HelpCenterContext';
import { useUpdateZendeskUserFieldsMutation } from '../data/use-update-zendesk-user-fields';
import { HELP_CENTER_STORE } from '../stores';
import type { ZendeskConfigName } from '@automattic/help-center/src/hooks/use-zendesk-messaging';
@@ -26,7 +25,7 @@ export default function useChatWidget(
configName: ZendeskConfigName = 'zendesk_support_chat_key',
enabled = true
) {
- const sectionName = useSelector( getSectionName );
+ const { sectionName } = useHelpCenterContext();
const { isPending: isSubmittingZendeskUserFields, mutateAsync: submitZendeskUserFields } =
useUpdateZendeskUserFieldsMutation();
const { setShowHelpCenter, resetStore } = useDispatch( HELP_CENTER_STORE );
diff --git a/packages/help-center/src/hooks/use-customizer-url.ts b/packages/help-center/src/hooks/use-customizer-url.ts
new file mode 100644
index 00000000000000..19380290755ff4
--- /dev/null
+++ b/packages/help-center/src/hooks/use-customizer-url.ts
@@ -0,0 +1,60 @@
+import { addQueryArgs } from '@wordpress/url';
+import { useHelpCenterContext } from '../contexts/HelpCenterContext';
+import { useSiteSlug } from './use-site-slug';
+
+/**
+ * Mapping from Calypso panel slug to tuple of focus key and value.
+ */
+export const PANEL_MAPPINGS: Record< string, [ string, string ] > = {
+ widgets: [ 'panel', 'widgets' ],
+ fonts: [ 'section', 'jetpack_fonts' ],
+ identity: [ 'section', 'title_tagline' ],
+ 'custom-css': [ 'section', 'jetpack_custom_css' ],
+ amp: [ 'section', 'amp_design' ],
+ menus: [ 'panel', 'nav_menus' ],
+ homepage: [ 'section', 'static_front_page' ],
+ jetpack_search: [ 'section', 'jetpack_search' ],
+};
+
+/**
+ * Given the name of a Calypso customizer panel, returns an object containing
+ * the section or panel to be used in autofocus. Returns null if the panel is
+ * not recognized.
+ * @param panel Calypso panel slug
+ * @returns WordPress autofocus argument object
+ */
+export function getCustomizerFocus( panel: string ) {
+ if ( PANEL_MAPPINGS.hasOwnProperty( panel ) ) {
+ const [ key, value ] = PANEL_MAPPINGS[ panel ];
+ return { [ `autofocus[${ key }]` ]: value };
+ }
+
+ return null;
+}
+const panels = [ 'root', 'homepage', 'identity', 'menus' ] as const;
+
+export function useCustomizerUrls() {
+ const { adminUrl, isJetpackSite } = useHelpCenterContext();
+ const siteSlug = useSiteSlug();
+ const returnUrl = window.location.href;
+
+ return panels.reduce(
+ ( acc, panel ) => {
+ if ( ! isJetpackSite && siteSlug ) {
+ const url = [ '' ].concat( [ 'customize', panel, siteSlug ].filter( Boolean ) ).join( '/' );
+ acc[ panel ] = addQueryArgs( url, {
+ return: returnUrl,
+ } );
+ } else {
+ const customizerUrl = adminUrl + 'customize.php';
+
+ acc[ panel ] = addQueryArgs( customizerUrl, {
+ return: returnUrl,
+ ...( panel ? getCustomizerFocus( panel ) : {} ),
+ } );
+ }
+ return acc;
+ },
+ {} as Record< ( typeof panels )[ number ], string >
+ );
+}
diff --git a/packages/help-center/src/hooks/use-post-by-key.ts b/packages/help-center/src/hooks/use-post-by-key.ts
new file mode 100644
index 00000000000000..1ed2a0fbdef914
--- /dev/null
+++ b/packages/help-center/src/hooks/use-post-by-key.ts
@@ -0,0 +1,29 @@
+import { useQuery } from '@tanstack/react-query';
+import apiFetch from '@wordpress/api-fetch';
+import wpcomRequest, { canAccessWpcomApis } from 'wpcom-proxy-request';
+
+function fetchForKey( postKey: { blogId: number; postId: number } ) {
+ return canAccessWpcomApis()
+ ? wpcomRequest( {
+ path: `help/article/${ encodeURIComponent( postKey.blogId ) }/${ encodeURIComponent(
+ postKey.postId
+ ) }`,
+ apiNamespace: 'wpcom/v2/',
+ apiVersion: '2',
+ } )
+ : apiFetch( {
+ path: `/help-center/fetch-post?post_id=${ encodeURIComponent(
+ postKey.postId
+ ) }&blog_id=${ encodeURIComponent( postKey.blogId ) }`,
+ } );
+}
+
+export function usePostByKey( postKey: { blogId: number; postId: number } | null ) {
+ return useQuery( {
+ queryKey: [ 'support-status', postKey ],
+ queryFn: () => postKey && fetchForKey( postKey ),
+ enabled: !! postKey,
+ refetchOnWindowFocus: false,
+ staleTime: 12 * 3600, // 12 hours
+ } );
+}
diff --git a/packages/help-center/src/hooks/use-site-slug.ts b/packages/help-center/src/hooks/use-site-slug.ts
new file mode 100644
index 00000000000000..1ef49280743eda
--- /dev/null
+++ b/packages/help-center/src/hooks/use-site-slug.ts
@@ -0,0 +1,17 @@
+import { SiteSelect } from '@automattic/data-stores';
+import { useSelect } from '@wordpress/data';
+import { useHelpCenterContext } from '../contexts/HelpCenterContext';
+import { SITE_STORE } from '../stores';
+
+export function useSiteSlug() {
+ const { selectedSiteId } = useHelpCenterContext();
+ const site = useSelect(
+ ( select ) => {
+ if ( selectedSiteId ) {
+ return ( select( SITE_STORE ) as SiteSelect ).getSite( selectedSiteId );
+ }
+ },
+ [ selectedSiteId ]
+ );
+ return site && new URL( site.URL ).host;
+}
diff --git a/packages/help-center/src/index.ts b/packages/help-center/src/index.ts
index 4c71f8eb6c08b7..0002744851b535 100644
--- a/packages/help-center/src/index.ts
+++ b/packages/help-center/src/index.ts
@@ -7,4 +7,3 @@ export { HelpCenterContactForm } from './components/help-center-contact-form';
export { default as Mail } from './icons/mail';
export { default as NewReleases } from './icons/new-releases';
export * from './support-variations';
-export { shouldLoadInlineHelp } from './utils';
diff --git a/packages/help-center/src/utils.ts b/packages/help-center/src/utils.ts
deleted file mode 100644
index 26eaa6f2bb7b81..00000000000000
--- a/packages/help-center/src/utils.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-/* eslint-disable no-restricted-imports */
-import { isWpMobileApp } from 'calypso/lib/mobile-app';
-
-export function shouldLoadInlineHelp( sectionName: string, currentRoute: string ) {
- if ( isWpMobileApp() ) {
- return false;
- }
-
- const exemptedSections = [ 'jetpack-connect', 'devdocs', 'help', 'home' ];
- const exemptedRoutes = [ '/log-in/jetpack' ];
- const exemptedRoutesStartingWith = [
- '/start/p2',
- '/start/videopress',
- '/start/setup-site',
- '/start/newsletter',
- '/plugins/domain',
- '/plugins/marketplace/setup',
- ];
-
- return (
- ! exemptedSections.includes( sectionName ) &&
- ! exemptedRoutes.includes( currentRoute ) &&
- ! exemptedRoutesStartingWith.some( ( startsWithString ) =>
- currentRoute.startsWith( startsWithString )
- )
- );
-}