From bf4264cdd582f23f3256e35fb74819e3920223c0 Mon Sep 17 00:00:00 2001 From: Fredrik Rombach Ekelund Date: Tue, 24 Sep 2024 10:56:31 +0200 Subject: [PATCH] Convert `ServerSettings` to Typescript (#94669) * Converted ServerSettings to Typescript * Address review suggestion * Type fixes * Fix nested paragraph tags --- .../components/hosting-upsell-nudge/index.tsx | 2 +- .../components/sftp-card/index.js | 22 +- .../server-settings/{main.js => main.tsx} | 218 ++++++++++-------- ...get-atomic-hosting-is-loading-sftp-data.js | 2 +- .../state/selectors/is-site-wpcom-atomic.js | 2 +- .../trials/is-site-on-business-trial.ts | 4 +- .../trials/is-site-on-ecommerce-trial.ts | 4 +- .../trials/is-site-on-hosting-trial.ts | 4 +- .../trials/is-site-on-migration-trial.ts | 4 +- client/state/sites/selectors/get-site.js | 2 +- 10 files changed, 138 insertions(+), 126 deletions(-) rename client/hosting/server-settings/{main.js => main.tsx} (63%) diff --git a/client/hosting/server-settings/components/hosting-upsell-nudge/index.tsx b/client/hosting/server-settings/components/hosting-upsell-nudge/index.tsx index 8e510e8df4df3..c994def2d70e8 100644 --- a/client/hosting/server-settings/components/hosting-upsell-nudge/index.tsx +++ b/client/hosting/server-settings/components/hosting-upsell-nudge/index.tsx @@ -27,7 +27,7 @@ interface HostingUpsellNudgeTargetPlan { } interface HostingUpsellNudgeProps { - siteId: number; + siteId: number | null; targetPlan?: HostingUpsellNudgeTargetPlan; secondaryCallToAction?: string; secondaryOnClick?: () => void; diff --git a/client/hosting/server-settings/components/sftp-card/index.js b/client/hosting/server-settings/components/sftp-card/index.js index 0271d551396c1..e21a4a9338025 100644 --- a/client/hosting/server-settings/components/sftp-card/index.js +++ b/client/hosting/server-settings/components/sftp-card/index.js @@ -227,18 +227,16 @@ export const SftpCard = ( { > { ! hasSftpFeatureAndIsLoading && ( -

- { username - ? translate( - 'Use the credentials below to access and edit your website files using an SFTP client. {{a}}Learn more about SFTP on WordPress.com{{/a}}.', - { - components: { - a: , - }, - } - ) - : featureExplanation } -

+ { username + ? translate( + 'Use the credentials below to access and edit your website files using an SFTP client. {{a}}Learn more about SFTP on WordPress.com{{/a}}.', + { + components: { + a: , + }, + } + ) + : featureExplanation }
) } { displayQuestionsAndButton && ( diff --git a/client/hosting/server-settings/main.js b/client/hosting/server-settings/main.tsx similarity index 63% rename from client/hosting/server-settings/main.js rename to client/hosting/server-settings/main.tsx index 5a69073d9dbd7..fe9a989b78d48 100644 --- a/client/hosting/server-settings/main.js +++ b/client/hosting/server-settings/main.tsx @@ -4,9 +4,9 @@ import { WPCOM_FEATURES_ATOMIC, } from '@automattic/calypso-products'; import { Button } from '@automattic/components'; -import { localize } from 'i18n-calypso'; -import { Fragment, useState, useCallback } from 'react'; -import { connect } from 'react-redux'; +import { useTranslate } from 'i18n-calypso'; +import React, { Fragment, useState, useCallback } from 'react'; +import { useDispatch } from 'react-redux'; import DocumentHead from 'calypso/components/data/document-head'; import QueryJetpackModules from 'calypso/components/data/query-jetpack-modules'; import QueryReaderTeams from 'calypso/components/data/query-reader-teams'; @@ -18,14 +18,21 @@ import NavigationHeader from 'calypso/components/navigation-header'; import Notice from 'calypso/components/notice'; import NoticeAction from 'calypso/components/notice/notice-action'; import { ScrollToAnchorOnMount } from 'calypso/components/scroll-to-anchor-on-mount'; +import CacheCard from 'calypso/hosting/server-settings/components/cache-card'; +import { HostingUpsellNudge } from 'calypso/hosting/server-settings/components/hosting-upsell-nudge'; +import PhpMyAdminCard from 'calypso/hosting/server-settings/components/phpmyadmin-card'; +import RestorePlanSoftwareCard from 'calypso/hosting/server-settings/components/restore-plan-software-card'; +import SFTPCard from 'calypso/hosting/server-settings/components/sftp-card'; +import WebServerSettingsCard from 'calypso/hosting/server-settings/components/web-server-settings-card'; +import HostingActivateStatus from 'calypso/hosting/server-settings/hosting-activate-status'; import PageViewTracker from 'calypso/lib/analytics/page-view-tracker'; import TrackComponentView from 'calypso/lib/analytics/track-component-view'; import { TrialAcknowledgeModal } from 'calypso/my-sites/plans/trials/trial-acknowledge/acknowlege-modal'; import { WithOnclickTrialRequest } from 'calypso/my-sites/plans/trials/trial-acknowledge/with-onclick-trial-request'; import TrialBanner from 'calypso/my-sites/plans/trials/trial-banner'; import SiteAdminInterface from 'calypso/my-sites/site-settings/site-admin-interface'; +import { useSelector } from 'calypso/state'; import { recordTracksEvent } from 'calypso/state/analytics/actions'; -import { fetchAutomatedTransferStatus } from 'calypso/state/automated-transfer/actions'; import { transferStates } from 'calypso/state/automated-transfer/constants'; import { getAutomatedTransferStatus } from 'calypso/state/automated-transfer/selectors'; import { getAtomicHostingIsLoadingSftpData } from 'calypso/state/selectors/get-atomic-hosting-is-loading-sftp-data'; @@ -33,27 +40,35 @@ import isSiteWpcomAtomic from 'calypso/state/selectors/is-site-wpcom-atomic'; import isSiteWpcomStaging from 'calypso/state/selectors/is-site-wpcom-staging'; import { isUserEligibleForFreeHostingTrial } from 'calypso/state/selectors/is-user-eligible-for-free-hosting-trial'; import siteHasFeature from 'calypso/state/selectors/site-has-feature'; -import { requestSite } from 'calypso/state/sites/actions'; import { isSiteOnBusinessTrial, isSiteOnECommerceTrial } from 'calypso/state/sites/plans/selectors'; import isJetpackSite from 'calypso/state/sites/selectors/is-jetpack-site'; -import { getReaderTeams } from 'calypso/state/teams/selectors'; import { getSelectedSite, getSelectedSiteId, getSelectedSiteSlug, } from 'calypso/state/ui/selectors'; -import CacheCard from './components/cache-card'; -import { HostingUpsellNudge } from './components/hosting-upsell-nudge'; -import PhpMyAdminCard from './components/phpmyadmin-card'; -import RestorePlanSoftwareCard from './components/restore-plan-software-card'; -import SFTPCard from './components/sftp-card'; -import WebServerSettingsCard from './components/web-server-settings-card'; -import HostingActivateStatus from './hosting-activate-status'; + import './style.scss'; const HEADING_OFFSET = 30; -const ShowEnabledFeatureCards = ( { availableTypes, cards, showDisabledCards = true } ) => { +type CardEntry = { + feature: string; + content: React.ReactElement; + type: 'basic' | 'advanced'; +}; + +type ShowEnabledFeatureCardsProps = { + availableTypes: CardEntry[ 'type' ][]; + cards: CardEntry[]; + showDisabledCards?: boolean; +}; + +const ShowEnabledFeatureCards = ( { + availableTypes, + cards, + showDisabledCards = true, +}: ShowEnabledFeatureCardsProps ) => { const enabledCards = cards.filter( ( card ) => ! card.type || availableTypes.includes( card.type ) ); @@ -77,8 +92,21 @@ const ShowEnabledFeatureCards = ( { availableTypes, cards, showDisabledCards = t ); }; -const AllCards = ( { isAdvancedHostingDisabled, isBasicHostingDisabled, siteId, siteSlug } ) => { - const allCards = [ +type AllCardsProps = { + isAdvancedHostingDisabled?: boolean; + isBasicHostingDisabled?: boolean; + isBusinessTrial?: boolean; + siteId: number | null; + siteSlug: string | null; +}; + +const AllCards = ( { + isAdvancedHostingDisabled, + isBasicHostingDisabled, + siteId, + siteSlug, +}: AllCardsProps ) => { + const allCards: CardEntry[] = [ { feature: 'sftp', content: , @@ -91,7 +119,7 @@ const AllCards = ( { isAdvancedHostingDisabled, isBasicHostingDisabled, siteId, }, { feature: 'restore-plan-software', - content: , + content: , type: 'basic', }, { @@ -99,71 +127,81 @@ const AllCards = ( { isAdvancedHostingDisabled, isBasicHostingDisabled, siteId, content: , type: 'basic', }, - siteId && { + ]; + + if ( siteId ) { + allCards.push( { feature: 'wp-admin', content: , type: 'basic', - }, - { - feature: 'web-server-settings', - content: , - type: 'advanced', - }, - ].filter( ( card ) => card !== null ); + } ); + } - const availableTypes = [ - ! isAdvancedHostingDisabled ? 'advanced' : null, - ! isBasicHostingDisabled ? 'basic' : null, - ].filter( ( type ) => type !== null ); + allCards.push( { + feature: 'web-server-settings', + content: , + type: 'advanced', + } ); + + const availableTypes: CardEntry[ 'type' ][] = []; + + if ( ! isAdvancedHostingDisabled ) { + availableTypes.push( 'advanced' ); + } + if ( ! isBasicHostingDisabled ) { + availableTypes.push( 'basic' ); + } return ; }; -const ServerSettings = ( props ) => { - const { - clickActivate, - isECommerceTrial, - isBusinessTrial, - isWpcomStagingSite, - siteId, - siteSlug, - translate, - isLoadingSftpData, - hasAtomicFeature, - hasSftpFeature, - isJetpack, - isEligibleForHostingTrial, - fetchUpdatedData, - isSiteAtomic, - transferState, - } = props; +type ServerSettingsProps = { + fetchUpdatedData: () => void; +}; + +const ServerSettings = ( { fetchUpdatedData }: ServerSettingsProps ) => { + const translate = useTranslate(); + const dispatch = useDispatch(); + + const clickActivate = () => + dispatch( recordTracksEvent( 'calypso_hosting_configuration_activate_click' ) ); + + const siteId = useSelector( getSelectedSiteId ); + const hasAtomicFeature = useSelector( ( state ) => + siteHasFeature( state, siteId, WPCOM_FEATURES_ATOMIC ) + ); + const hasSftpFeature = useSelector( ( state ) => siteHasFeature( state, siteId, FEATURE_SFTP ) ); + const site = useSelector( getSelectedSite ); + const isEligibleForHostingTrial = + useSelector( isUserEligibleForFreeHostingTrial ) && site && site.plan?.is_free; + const isSiteAtomic = useSelector( ( state ) => isSiteWpcomAtomic( state, siteId ) ); + + const isJetpack = useSelector( ( state ) => isJetpackSite( state, siteId ) ); + const isECommerceTrial = useSelector( ( state ) => isSiteOnECommerceTrial( state, siteId ) ); + const isBusinessTrial = useSelector( ( state ) => isSiteOnBusinessTrial( state, siteId ) ); + const transferState = useSelector( ( state ) => getAutomatedTransferStatus( state, siteId ) ); + const isLoadingSftpData = useSelector( ( state ) => + getAtomicHostingIsLoadingSftpData( state, siteId ) + ); + const siteSlug = useSelector( ( state ) => getSelectedSiteSlug( state ) ); + const isWpcomStagingSite = useSelector( ( state ) => isSiteWpcomStaging( state, siteId ) ); const [ isTrialAcknowledgeModalOpen, setIsTrialAcknowledgeModalOpen ] = useState( false ); const [ hasTransfer, setHasTransferring ] = useState( - transferState && - ! [ - transferStates.NONE, - transferStates.INQUIRING, - transferStates.ERROR, - transferStates.COMPLETED, - transferStates.COMPLETE, - transferStates.REVERTED, - ].includes( transferState ) + !! transferState && + transferState !== transferStates.NONE && + transferState !== transferStates.INQUIRING && + transferState !== transferStates.ERROR && + transferState !== transferStates.COMPLETED && + transferState !== transferStates.COMPLETE && + transferState !== transferStates.REVERTED ); const canSiteGoAtomic = ! isSiteAtomic && hasSftpFeature; const showHostingActivationBanner = canSiteGoAtomic && ! hasTransfer; - const setOpenModal = ( isOpen ) => { - setIsTrialAcknowledgeModalOpen( isOpen ); - }; - - const trialRequested = () => { - setHasTransferring( true ); - }; - const requestUpdatedSiteData = useCallback( - ( isTransferring, wasTransferring, isTransferCompleted ) => { + ( isTransferring?: boolean, wasTransferring?: boolean, isTransferCompleted?: boolean ) => { if ( isTransferring && ! hasTransfer ) { setHasTransferring( true ); } @@ -220,7 +258,7 @@ const ServerSettings = ( props ) => { return ( <> { isSiteAtomic && } - { isJetpack && } + { isJetpack && siteId && } { ( '.item-preview__content' ) ?? undefined + } /> ) } @@ -280,44 +320,18 @@ const ServerSettings = ( props ) => { ) } { getContent() } { isEligibleForHostingTrial && isTrialAcknowledgeModalOpen && ( - + { + setIsTrialAcknowledgeModalOpen( isOpen ); + } } + trialRequested={ () => { + setHasTransferring( true ); + } } + /> ) } ); }; -const clickActivate = () => recordTracksEvent( 'calypso_hosting_configuration_activate_click' ); - -export default connect( - ( state ) => { - const siteId = getSelectedSiteId( state ); - const hasAtomicFeature = siteHasFeature( state, siteId, WPCOM_FEATURES_ATOMIC ); - const hasSftpFeature = siteHasFeature( state, siteId, FEATURE_SFTP ); - const site = getSelectedSite( state ); - const isEligibleForHostingTrial = - isUserEligibleForFreeHostingTrial( state ) && site && site.plan?.is_free; - const isSiteAtomic = isSiteWpcomAtomic( state, siteId ); - - return { - teams: getReaderTeams( state ), - isJetpack: isJetpackSite( state, siteId ), - isECommerceTrial: isSiteOnECommerceTrial( state, siteId ), - isBusinessTrial: isSiteOnBusinessTrial( state, siteId ), - transferState: getAutomatedTransferStatus( state, siteId ), - hasSftpFeature, - hasAtomicFeature, - isLoadingSftpData: getAtomicHostingIsLoadingSftpData( state, siteId ), - siteSlug: getSelectedSiteSlug( state ), - siteId, - isWpcomStagingSite: isSiteWpcomStaging( state, siteId ), - isEligibleForHostingTrial, - isSiteAtomic, - }; - }, - { - clickActivate, - fetchAutomatedTransferStatus, - requestSiteById: requestSite, - } -)( localize( WithOnclickTrialRequest( ServerSettings ) ) ); +export default WithOnclickTrialRequest( ServerSettings ); diff --git a/client/state/selectors/get-atomic-hosting-is-loading-sftp-data.js b/client/state/selectors/get-atomic-hosting-is-loading-sftp-data.js index 01f368dd89c0c..a50fe5a59e1f6 100644 --- a/client/state/selectors/get-atomic-hosting-is-loading-sftp-data.js +++ b/client/state/selectors/get-atomic-hosting-is-loading-sftp-data.js @@ -5,7 +5,7 @@ import { getAtomicHostingIsLoadingSshAccess } from './get-atomic-hosting-is-load /** * Returns if the SFTP users and SSH access data have loaded for given site. * @param {Object} state Global state tree - * @param {number} siteId The ID of the site we're querying + * @param {number|null} siteId The ID of the site we're querying * @returns {boolean} If the SFTP users and SSH access data has finished the first request */ export function getAtomicHostingIsLoadingSftpData( state, siteId ) { diff --git a/client/state/selectors/is-site-wpcom-atomic.js b/client/state/selectors/is-site-wpcom-atomic.js index b0dc35f405b4a..cdcb3b094829c 100644 --- a/client/state/selectors/is-site-wpcom-atomic.js +++ b/client/state/selectors/is-site-wpcom-atomic.js @@ -3,7 +3,7 @@ import { get } from 'lodash'; /** * Retruns true if the questioned site is a WPCOM Atomic site. * @param {Object} state the global state tree - * @param {number} siteId the questioned site ID. + * @param {number|null} siteId the questioned site ID. * @returns {boolean} Whether the site is a WPCOM Atomic site. */ export default ( state, siteId ) => diff --git a/client/state/sites/plans/selectors/trials/is-site-on-business-trial.ts b/client/state/sites/plans/selectors/trials/is-site-on-business-trial.ts index b90cda2c268cc..69e4039e7a6c8 100644 --- a/client/state/sites/plans/selectors/trials/is-site-on-business-trial.ts +++ b/client/state/sites/plans/selectors/trials/is-site-on-business-trial.ts @@ -4,9 +4,9 @@ import type { AppState } from 'calypso/types'; /** * Checks whether the current site is on any type of Business trial. * @param {AppState} state Global state tree - * @param {number} siteId - Site ID + * @param {number|null} siteId - Site ID * @returns {boolean} Returns true if the site is on a Business trial */ -export default function isSiteOnBusinessTrial( state: AppState, siteId: number ): boolean { +export default function isSiteOnBusinessTrial( state: AppState, siteId: number | null ): boolean { return isSiteOnMigrationTrial( state, siteId ) || isSiteOnHostingTrial( state, siteId ); } diff --git a/client/state/sites/plans/selectors/trials/is-site-on-ecommerce-trial.ts b/client/state/sites/plans/selectors/trials/is-site-on-ecommerce-trial.ts index c930c3e18bec3..eca08b36d3dfe 100644 --- a/client/state/sites/plans/selectors/trials/is-site-on-ecommerce-trial.ts +++ b/client/state/sites/plans/selectors/trials/is-site-on-ecommerce-trial.ts @@ -6,10 +6,10 @@ import type { AppState } from 'calypso/types'; /** * Checks whether the current site is on the Woo Trial. * @param {AppState} state Global state tree - * @param {number} siteId - Site ID + * @param {number|null} siteId - Site ID * @returns {boolean} Returns true if the site is on the trial */ -export default function isSiteOnECommerceTrial( state: AppState, siteId: number ): boolean { +export default function isSiteOnECommerceTrial( state: AppState, siteId: number | null ): boolean { const currentPlan = getCurrentPlan( state, siteId ); const site = getSite( state, siteId ); const productSlug = currentPlan?.productSlug || site?.plan?.product_slug; diff --git a/client/state/sites/plans/selectors/trials/is-site-on-hosting-trial.ts b/client/state/sites/plans/selectors/trials/is-site-on-hosting-trial.ts index a6d737d433438..deb8efa46ac01 100644 --- a/client/state/sites/plans/selectors/trials/is-site-on-hosting-trial.ts +++ b/client/state/sites/plans/selectors/trials/is-site-on-hosting-trial.ts @@ -6,10 +6,10 @@ import type { AppState } from 'calypso/types'; /** * Checks whether the current site is on the hosting trial. * @param {AppState} state Global state tree - * @param {number} siteId - Site ID + * @param {number|null} siteId - Site ID * @returns {boolean} Returns true if the site is on the trial */ -export default function isSiteOnHostingTrial( state: AppState, siteId: number ): boolean { +export default function isSiteOnHostingTrial( state: AppState, siteId: number | null ): boolean { const currentPlan = getCurrentPlan( state, siteId ); const site = getSite( state, siteId ); const productSlug = currentPlan?.productSlug || site?.plan?.product_slug; diff --git a/client/state/sites/plans/selectors/trials/is-site-on-migration-trial.ts b/client/state/sites/plans/selectors/trials/is-site-on-migration-trial.ts index fe5147ec20811..563d10e523d90 100644 --- a/client/state/sites/plans/selectors/trials/is-site-on-migration-trial.ts +++ b/client/state/sites/plans/selectors/trials/is-site-on-migration-trial.ts @@ -7,10 +7,10 @@ import type { AppState } from 'calypso/types'; /** * Checks whether the current site is on the migration trial. * @param {AppState} state Global state tree - * @param {number} siteId - Site ID + * @param {number|null} siteId - Site ID * @returns {boolean} Returns true if the site is on the trial */ -export default function isSiteOnMigrationTrial( state: AppState, siteId: number ): boolean { +export default function isSiteOnMigrationTrial( state: AppState, siteId: number | null ): boolean { if ( ! isEnabled( 'plans/migration-trial' ) ) { return false; } diff --git a/client/state/sites/selectors/get-site.js b/client/state/sites/selectors/get-site.js index 98bff1e14e097..7d9a01e3a5e96 100644 --- a/client/state/sites/selectors/get-site.js +++ b/client/state/sites/selectors/get-site.js @@ -11,7 +11,7 @@ let getSiteCache = new WeakMap(); /** * Returns a normalized site object by its ID or site slug. * @param {Object} state Global state tree - * @param {number|string|undefined} siteIdOrSlug Site ID or site slug + * @param {number|string|null|undefined} siteIdOrSlug Site ID or site slug * @returns {import('@automattic/data-stores').SiteDetails|null|undefined} Site object */ export default function getSite( state, siteIdOrSlug ) {