Skip to content

Commit 1ed238e

Browse files
katinthehatsiteKateryna Kodonenko
andauthored
Studio: Add a warning when pushing a site with an outdated WordPress version (#2136)
* Add warning for when the site exceeds limits * Fix tests * Linter fix * Simplify solution * Test cleanup * Reset against trunk * Make the code more dry * Fix unit tests * Ensure database field is not cut off * Simplify code * Added blurred background --------- Co-authored-by: Kateryna Kodonenko <kateryna@automattic.com>
1 parent ea85c39 commit 1ed238e

4 files changed

Lines changed: 56 additions & 8 deletions

File tree

‎src/lib/version-utils.ts‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,17 @@ export function isDevRelease( version: string ): boolean {
1717
export function isWordPressDevVersion( version: string ): boolean {
1818
return /^\d+\.\d+-[a-zA-Z0-9]+-\d+$/.test( version );
1919
}
20+
21+
/**
22+
* Gets the latest stable WordPress version from a list of WordPress versions
23+
* Filters out 'latest', beta, and development versions to find the first stable release
24+
* @param versions Array of WordPress version objects
25+
* @returns The version string of the latest stable release, or undefined if none found
26+
*/
27+
export function getLatestStableWpVersion(
28+
versions: Array< { value: string; isBeta: boolean; isDevelopment: boolean } >
29+
): string | undefined {
30+
return versions.find(
31+
( version ) => version.value !== 'latest' && ! version.isBeta && ! version.isDevelopment
32+
)?.value;
33+
}

‎src/modules/preview-site/components/create-preview-button.tsx‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import { Tooltip } from 'src/components/tooltip';
88
import { useGetWpVersion } from 'src/hooks/use-get-wp-version';
99
import { useOffline } from 'src/hooks/use-offline';
1010
import { useSiteSize } from 'src/hooks/use-site-size';
11+
import { getLatestStableWpVersion } from 'src/lib/version-utils';
1112
import { hasVersionMismatch } from 'src/modules/preview-site/lib/version-comparison';
1213
import { useRootSelector } from 'src/stores';
13-
import { selectMinimumWordPressVersion } from 'src/stores/provider-constants-slice';
1414
import { snapshotSelectors } from 'src/stores/snapshot-slice';
1515
import { useGetWordPressVersions } from 'src/stores/wordpress-versions-api';
1616
import { useGetSnapshotUsage } from 'src/stores/wpcom-api';
@@ -42,16 +42,15 @@ export function CreatePreviewButton( { onClick, selectedSite, user }: CreatePrev
4242
const { isOverLimit } = useSiteSize( selectedSite.id );
4343
const isOffline = useOffline();
4444
const [ wpVersion ] = useGetWpVersion( selectedSite );
45-
const minimumWordPressVersion = useRootSelector( selectMinimumWordPressVersion );
4645
const { data: wpVersions = [] } = useGetWordPressVersions( {
47-
minimumVersion: minimumWordPressVersion,
46+
minimumVersion: '',
4847
} );
4948

5049
const isAnySiteArchiving = !! activeOperationsForAnySite.length;
5150
const isCurrentSiteArchiving = !! activeOperationsForCurrentSite;
5251
const isOtherSiteArchiving = isAnySiteArchiving && ! isCurrentSiteArchiving;
5352

54-
const latestWpVersion = wpVersions.find( ( version ) => version.value === 'latest' )?.value;
53+
const latestWpVersion = getLatestStableWpVersion( wpVersions );
5554
const shouldShowMismatchTooltip = hasVersionMismatch( {
5655
wpVersion,
5756
latestWpVersion,

‎src/modules/sync/components/sync-dialog.tsx‎

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,20 @@ import { TwoColorProgressBar } from 'src/components/progress-bar';
1212
import { Tooltip } from 'src/components/tooltip';
1313
import { TreeView, TreeNode, updateNodeById } from 'src/components/tree-view';
1414
import { SYNC_PUSH_SIZE_LIMIT_GB } from 'src/constants';
15+
import { useGetWpVersion } from 'src/hooks/use-get-wp-version';
1516
import { cx } from 'src/lib/cx';
1617
import { getIpcApi } from 'src/lib/get-ipc-api';
1718
import { getLocalizedLink } from 'src/lib/get-localized-link';
19+
import { getLatestStableWpVersion } from 'src/lib/version-utils';
20+
import { hasVersionMismatch } from 'src/modules/preview-site/lib/version-comparison';
1821
import { SiteNameBox } from 'src/modules/sync/components/site-name-box';
1922
import { useSelectedItemsPushSize } from 'src/modules/sync/hooks/use-selected-items-push-size';
2023
import { useSyncDialogTexts } from 'src/modules/sync/hooks/use-sync-dialog-texts';
2124
import { useTopLevelSyncTree } from 'src/modules/sync/hooks/use-top-level-sync-tree';
2225
import { getSiteEnvironment } from 'src/modules/sync/lib/environment-utils';
2326
import { useI18nLocale } from 'src/stores';
2427
import { useLatestRewindId, useRemoteFileTree, useLocalFileTree } from 'src/stores/sync';
28+
import { useGetWordPressVersions } from 'src/stores/wordpress-versions-api';
2529
import { TreeViewLoadingSkeleton } from './tree-view-loading-skeleton';
2630
import type { SyncSite } from 'src/hooks/use-fetch-wpcom-sites/types';
2731

@@ -154,6 +158,19 @@ export function SyncDialog( {
154158
const { fetchChildren, rewindId, isLoadingRewindId, isErrorRewindId, isLoadingLocalFileTree } =
155159
useDynamicTreeState( type, localSite.id, remoteSite.id, setTreeState );
156160

161+
const [ wpVersion ] = useGetWpVersion( localSite );
162+
const { data: wpVersions = [] } = useGetWordPressVersions( {
163+
minimumVersion: '',
164+
} );
165+
const latestWpVersion = getLatestStableWpVersion( wpVersions );
166+
const shouldShowVersionMismatch =
167+
type === 'push' &&
168+
hasVersionMismatch( {
169+
wpVersion,
170+
latestWpVersion,
171+
phpVersion: localSite.phpVersion,
172+
} );
173+
157174
const localSiteName = <SiteNameBox siteName={ localSite.name } envType="studio" />;
158175
const remoteSiteName = <SiteNameBox siteName={ remoteSite.name } envType={ siteEnv } />;
159176

@@ -227,10 +244,18 @@ export function SyncDialog( {
227244
if ( type === 'pull' ) {
228245
return 'pb-[70px]'; // Original padding for pull
229246
}
230-
if ( isPushSelectionOverLimit ) {
231-
return 'pb-[200px]'; // Progress bar + warning notice
247+
// Calculate dynamic padding based on number of notices shown
248+
const noticeCount = [ isPushSelectionOverLimit, shouldShowVersionMismatch ].filter(
249+
Boolean
250+
).length;
251+
252+
if ( noticeCount === 0 ) {
253+
return 'pb-[140px]'; // Just progress bar
232254
}
233-
return 'pb-[110px]'; // Just progress bar
255+
if ( noticeCount === 1 ) {
256+
return 'pb-[220px]'; // Progress bar + one notice
257+
}
258+
return 'pb-[300px]'; // Progress bar + two notices
234259
};
235260

236261
return (
@@ -336,7 +361,7 @@ export function SyncDialog( {
336361
</div>
337362
</Tooltip>
338363

339-
<div className="px-8 py-4 absolute left-0 right-0 bottom-0 bg-white z-10 border-t border-a8c-gray-5">
364+
<div className="px-8 py-4 absolute left-0 right-0 bottom-0 bg-white/[0.8] backdrop-blur-sm z-10 border-t border-a8c-gray-5">
340365
{ type === 'push' && (
341366
<div className="mb-4">
342367
<TwoColorProgressBar
@@ -361,6 +386,15 @@ export function SyncDialog( {
361386
</p>
362387
</Notice>
363388
) }
389+
{ shouldShowVersionMismatch && (
390+
<Notice status="warning" isDismissible={ false } className="mb-4">
391+
<p data-testid="push-version-mismatch-notice">
392+
{ __(
393+
'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.'
394+
) }
395+
</p>
396+
</Notice>
397+
) }
364398
<div className="flex justify-between items-center">
365399
<div>
366400
{ createInterpolateElement( syncTexts.envSync, {

‎src/modules/sync/tests/index.test.tsx‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ describe( 'ContentTabSync', () => {
140140
getConnectedWpcomSites: jest.fn().mockResolvedValue( [] ),
141141
getDirectorySize: jest.fn().mockResolvedValue( 0 ),
142142
connectWpcomSites: jest.fn(),
143+
getWpVersion: jest.fn().mockResolvedValue( '6.4.3' ),
143144
listLocalFileTree: jest.fn().mockResolvedValue( [
144145
{
145146
name: 'plugins',

0 commit comments

Comments
 (0)