diff --git a/src/lib/version-utils.ts b/src/lib/version-utils.ts index 74d88c9e85..ad4720cc5c 100644 --- a/src/lib/version-utils.ts +++ b/src/lib/version-utils.ts @@ -17,3 +17,17 @@ export function isDevRelease( version: string ): boolean { export function isWordPressDevVersion( version: string ): boolean { return /^\d+\.\d+-[a-zA-Z0-9]+-\d+$/.test( version ); } + +/** + * Gets the latest stable WordPress version from a list of WordPress versions + * Filters out 'latest', beta, and development versions to find the first stable release + * @param versions Array of WordPress version objects + * @returns The version string of the latest stable release, or undefined if none found + */ +export function getLatestStableWpVersion( + versions: Array< { value: string; isBeta: boolean; isDevelopment: boolean } > +): string | undefined { + return versions.find( + ( version ) => version.value !== 'latest' && ! version.isBeta && ! version.isDevelopment + )?.value; +} diff --git a/src/modules/preview-site/components/create-preview-button.tsx b/src/modules/preview-site/components/create-preview-button.tsx index f9399541ba..ab16085558 100644 --- a/src/modules/preview-site/components/create-preview-button.tsx +++ b/src/modules/preview-site/components/create-preview-button.tsx @@ -8,9 +8,9 @@ import { Tooltip } from 'src/components/tooltip'; import { useGetWpVersion } from 'src/hooks/use-get-wp-version'; import { useOffline } from 'src/hooks/use-offline'; import { useSiteSize } from 'src/hooks/use-site-size'; +import { getLatestStableWpVersion } from 'src/lib/version-utils'; import { hasVersionMismatch } from 'src/modules/preview-site/lib/version-comparison'; import { useRootSelector } from 'src/stores'; -import { selectMinimumWordPressVersion } from 'src/stores/provider-constants-slice'; import { snapshotSelectors } from 'src/stores/snapshot-slice'; import { useGetWordPressVersions } from 'src/stores/wordpress-versions-api'; import { useGetSnapshotUsage } from 'src/stores/wpcom-api'; @@ -42,16 +42,15 @@ export function CreatePreviewButton( { onClick, selectedSite, user }: CreatePrev const { isOverLimit } = useSiteSize( selectedSite.id ); const isOffline = useOffline(); const [ wpVersion ] = useGetWpVersion( selectedSite ); - const minimumWordPressVersion = useRootSelector( selectMinimumWordPressVersion ); const { data: wpVersions = [] } = useGetWordPressVersions( { - minimumVersion: minimumWordPressVersion, + minimumVersion: '', } ); const isAnySiteArchiving = !! activeOperationsForAnySite.length; const isCurrentSiteArchiving = !! activeOperationsForCurrentSite; const isOtherSiteArchiving = isAnySiteArchiving && ! isCurrentSiteArchiving; - const latestWpVersion = wpVersions.find( ( version ) => version.value === 'latest' )?.value; + const latestWpVersion = getLatestStableWpVersion( wpVersions ); const shouldShowMismatchTooltip = hasVersionMismatch( { wpVersion, latestWpVersion, diff --git a/src/modules/sync/components/sync-dialog.tsx b/src/modules/sync/components/sync-dialog.tsx index 1bf4ee8261..29bf9b5fca 100644 --- a/src/modules/sync/components/sync-dialog.tsx +++ b/src/modules/sync/components/sync-dialog.tsx @@ -12,9 +12,12 @@ import { TwoColorProgressBar } from 'src/components/progress-bar'; import { Tooltip } from 'src/components/tooltip'; import { TreeView, TreeNode, updateNodeById } from 'src/components/tree-view'; import { SYNC_PUSH_SIZE_LIMIT_GB } from 'src/constants'; +import { useGetWpVersion } from 'src/hooks/use-get-wp-version'; import { cx } from 'src/lib/cx'; import { getIpcApi } from 'src/lib/get-ipc-api'; import { getLocalizedLink } from 'src/lib/get-localized-link'; +import { getLatestStableWpVersion } from 'src/lib/version-utils'; +import { hasVersionMismatch } from 'src/modules/preview-site/lib/version-comparison'; import { SiteNameBox } from 'src/modules/sync/components/site-name-box'; import { useSelectedItemsPushSize } from 'src/modules/sync/hooks/use-selected-items-push-size'; import { useSyncDialogTexts } from 'src/modules/sync/hooks/use-sync-dialog-texts'; @@ -22,6 +25,7 @@ import { useTopLevelSyncTree } from 'src/modules/sync/hooks/use-top-level-sync-t import { getSiteEnvironment } from 'src/modules/sync/lib/environment-utils'; import { useI18nLocale } from 'src/stores'; import { useLatestRewindId, useRemoteFileTree, useLocalFileTree } from 'src/stores/sync'; +import { useGetWordPressVersions } from 'src/stores/wordpress-versions-api'; import { TreeViewLoadingSkeleton } from './tree-view-loading-skeleton'; import type { SyncSite } from 'src/hooks/use-fetch-wpcom-sites/types'; @@ -154,6 +158,19 @@ export function SyncDialog( { const { fetchChildren, rewindId, isLoadingRewindId, isErrorRewindId, isLoadingLocalFileTree } = useDynamicTreeState( type, localSite.id, remoteSite.id, setTreeState ); + const [ wpVersion ] = useGetWpVersion( localSite ); + const { data: wpVersions = [] } = useGetWordPressVersions( { + minimumVersion: '', + } ); + const latestWpVersion = getLatestStableWpVersion( wpVersions ); + const shouldShowVersionMismatch = + type === 'push' && + hasVersionMismatch( { + wpVersion, + latestWpVersion, + phpVersion: localSite.phpVersion, + } ); + const localSiteName = ; const remoteSiteName = ; @@ -227,10 +244,18 @@ export function SyncDialog( { if ( type === 'pull' ) { return 'pb-[70px]'; // Original padding for pull } - if ( isPushSelectionOverLimit ) { - return 'pb-[200px]'; // Progress bar + warning notice + // Calculate dynamic padding based on number of notices shown + const noticeCount = [ isPushSelectionOverLimit, shouldShowVersionMismatch ].filter( + Boolean + ).length; + + if ( noticeCount === 0 ) { + return 'pb-[140px]'; // Just progress bar } - return 'pb-[110px]'; // Just progress bar + if ( noticeCount === 1 ) { + return 'pb-[220px]'; // Progress bar + one notice + } + return 'pb-[300px]'; // Progress bar + two notices }; return ( @@ -336,7 +361,7 @@ export function SyncDialog( { -
+
{ type === 'push' && (
) } + { shouldShowVersionMismatch && ( + +

+ { __( + 'Your Studio site is using a different WordPress or PHP version than your WordPress.com site. The remote site will keep on using the newest supported versions.' + ) } +

+
+ ) }
{ createInterpolateElement( syncTexts.envSync, { diff --git a/src/modules/sync/tests/index.test.tsx b/src/modules/sync/tests/index.test.tsx index 5b1e49715b..98726d3eea 100644 --- a/src/modules/sync/tests/index.test.tsx +++ b/src/modules/sync/tests/index.test.tsx @@ -140,6 +140,7 @@ describe( 'ContentTabSync', () => { getConnectedWpcomSites: jest.fn().mockResolvedValue( [] ), getDirectorySize: jest.fn().mockResolvedValue( 0 ), connectWpcomSites: jest.fn(), + getWpVersion: jest.fn().mockResolvedValue( '6.4.3' ), listLocalFileTree: jest.fn().mockResolvedValue( [ { name: 'plugins',