Skip to content

Commit

Permalink
Make eligibility checks more async (#88452)
Browse files Browse the repository at this point in the history
  • Loading branch information
TimBroddin authored Mar 13, 2024
1 parent 4cbccfc commit ba1e802
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 61 deletions.
4 changes: 0 additions & 4 deletions client/blocks/plugins-update-manager/context/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type { SiteSlug } from 'calypso/types';

interface PluginUpdateManagerContextProps {
siteSlug: SiteSlug;
isEligibleForFeature: boolean;
}

interface PluginUpdateManagerContextState {
Expand All @@ -15,23 +14,20 @@ const PluginUpdateManagerContext = createContext<
PluginUpdateManagerContextProps & PluginUpdateManagerContextState
>( {
siteSlug: '',
isEligibleForFeature: false,
siteHasEligiblePlugins: true,
setSiteHasEligiblePlugins: () => {},
} );

const PluginUpdateManagerContextProvider = ( {
siteSlug,
children,
isEligibleForFeature,
}: PluginUpdateManagerContextProps & { children: ReactNode } ) => {
const [ siteHasEligiblePlugins, setSiteHasEligiblePlugins ] = useState( true );

return (
<PluginUpdateManagerContext.Provider
value={ {
siteSlug,
isEligibleForFeature,
siteHasEligiblePlugins,
setSiteHasEligiblePlugins,
} }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,33 @@
import { useContext } from 'react';
import { PluginUpdateManagerContext } from '../context';
import { WPCOM_FEATURES_SCHEDULED_UPDATES } from '@automattic/calypso-products';
import { useSelector } from 'calypso/state';
import getHasLoadedSiteFeatures from 'calypso/state/selectors/has-loaded-site-features';
import isSiteWpcomAtomic from 'calypso/state/selectors/is-site-wpcom-atomic';
import siteHasFeature from 'calypso/state/selectors/site-has-feature';
import { hasLoadedSitePlansFromServer } from 'calypso/state/sites/plans/selectors';
import { getSelectedSiteId } from 'calypso/state/ui/selectors';

export function useIsEligibleForFeature() {
const { isEligibleForFeature } = useContext( PluginUpdateManagerContext );
return isEligibleForFeature;
}
export const useIsEligibleForFeature = function () {
const siteId = useSelector( getSelectedSiteId );

const isFeaturesLoaded: boolean = useSelector( ( state ) =>
getHasLoadedSiteFeatures( state, siteId )
);

const isSitePlansLoaded: boolean = useSelector( ( state ) =>
hasLoadedSitePlansFromServer( state, siteId )
);

const hasScheduledUpdatesFeature = useSelector( ( state ) =>
siteHasFeature( state, siteId, WPCOM_FEATURES_SCHEDULED_UPDATES )
);
const isAtomic = useSelector( ( state ) => isSiteWpcomAtomic( state, siteId as number ) );
const isEligibleForFeature = hasScheduledUpdatesFeature && isAtomic;
return {
isEligibleForFeature,
isAtomic,
hasScheduledUpdatesFeature,
isFeaturesLoaded,
isSitePlansLoaded,
loading: ! isFeaturesLoaded || ! isSitePlansLoaded,
};
};
39 changes: 6 additions & 33 deletions client/blocks/plugins-update-manager/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { WPCOM_FEATURES_SCHEDULED_UPDATES } from '@automattic/calypso-products';
import { Button, Spinner } from '@wordpress/components';
import { Button } from '@wordpress/components';
import { plus } from '@wordpress/icons';
import { useEffect } from 'react';
import { useIsEligibleForFeature } from 'calypso/blocks/plugins-update-manager/hooks/use-is-eligible-for-feature';
import DocumentHead from 'calypso/components/data/document-head';
import QuerySitePlans from 'calypso/components/data/query-site-plans';
import MainComponent from 'calypso/components/main';
Expand All @@ -10,10 +10,6 @@ import ScheduledUpdatesGate from 'calypso/components/scheduled-updates/scheduled
import { useUpdateScheduleQuery } from 'calypso/data/plugins/use-update-schedules-query';
import { recordTracksEvent } from 'calypso/lib/analytics/tracks';
import { useSelector } from 'calypso/state';
import getHasLoadedSiteFeatures from 'calypso/state/selectors/has-loaded-site-features';
import isSiteWpcomAtomic from 'calypso/state/selectors/is-site-wpcom-atomic';
import siteHasFeature from 'calypso/state/selectors/site-has-feature';
import { hasLoadedSitePlansFromServer } from 'calypso/state/sites/plans/selectors';
import { getSelectedSiteId } from 'calypso/state/ui/selectors';
import { MAX_SCHEDULES } from './config';
import { PluginUpdateManagerContextProvider } from './context';
Expand All @@ -35,19 +31,9 @@ interface Props {
export const PluginsUpdateManager = ( props: Props ) => {
const { siteSlug, context, scheduleId, onNavBack, onCreateNewSchedule, onEditSchedule } = props;
const siteId = useSelector( getSelectedSiteId );
const hasScheduledUpdatesFeature = useSelector( ( state ) =>
siteHasFeature( state, siteId, WPCOM_FEATURES_SCHEDULED_UPDATES )
);
const isAtomic = useSelector( ( state ) => isSiteWpcomAtomic( state, siteId as number ) );
const isEligibleForFeature = hasScheduledUpdatesFeature && isAtomic;
const { data: schedules = [] } = useUpdateScheduleQuery( siteSlug, isEligibleForFeature );
const isFeaturesLoaded: boolean = useSelector( ( state ) =>
getHasLoadedSiteFeatures( state, siteId )
);

const isSitePlansLoaded: boolean = useSelector( ( state ) =>
hasLoadedSitePlansFromServer( state, siteId )
);
const { isEligibleForFeature, isSitePlansLoaded } = useIsEligibleForFeature();
const { data: schedules = [] } = useUpdateScheduleQuery( siteSlug, isEligibleForFeature );

const hideCreateButton =
! isEligibleForFeature || schedules.length === MAX_SCHEDULES || schedules.length === 0;
Expand Down Expand Up @@ -82,10 +68,7 @@ export const PluginsUpdateManager = ( props: Props ) => {
}[ context ];

return (
<PluginUpdateManagerContextProvider
siteSlug={ siteSlug }
isEligibleForFeature={ isEligibleForFeature }
>
<PluginUpdateManagerContextProvider siteSlug={ siteSlug }>
<DocumentHead title={ title } />
{ ! isSitePlansLoaded && <QuerySitePlans siteId={ siteId } /> }
<MainComponent wideLayout>
Expand All @@ -106,17 +89,7 @@ export const PluginsUpdateManager = ( props: Props ) => {
</Button>
) }
</NavigationHeader>
{ ! isFeaturesLoaded || ! isSitePlansLoaded ? (
<Spinner className="plugins-update-manager-spinner" />
) : (
<ScheduledUpdatesGate
hasScheduledUpdatesFeature={ hasScheduledUpdatesFeature }
isAtomic={ isAtomic }
siteId={ siteId as number }
>
{ component }
</ScheduledUpdatesGate>
) }
<ScheduledUpdatesGate siteId={ siteId as number }>{ component }</ScheduledUpdatesGate>
</MainComponent>
</PluginUpdateManagerContextProvider>
);
Expand Down
2 changes: 1 addition & 1 deletion client/blocks/plugins-update-manager/schedule-create.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ interface Props {
export const ScheduleCreate = ( props: Props ) => {
const siteSlug = useSiteSlug();
const { createMonitor } = useCreateMonitor( siteSlug );
const isEligibleForFeature = useIsEligibleForFeature();
const { isEligibleForFeature } = useIsEligibleForFeature();
const siteHasEligiblePlugins = useSiteHasEligiblePlugins();
const { onNavBack } = props;
const { data: schedules = [], isFetched } = useUpdateScheduleQuery(
Expand Down
2 changes: 1 addition & 1 deletion client/blocks/plugins-update-manager/schedule-edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ interface Props {
}
export const ScheduleEdit = ( props: Props ) => {
const siteSlug = useSiteSlug();
const isEligibleForFeature = useIsEligibleForFeature();
const { isEligibleForFeature } = useIsEligibleForFeature();
const { scheduleId, onNavBack } = props;
const { data: schedules = [], isFetched } = useUpdateScheduleQuery(
siteSlug,
Expand Down
2 changes: 1 addition & 1 deletion client/blocks/plugins-update-manager/schedule-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ interface Props {
export const ScheduleForm = ( props: Props ) => {
const moment = useLocalizedMoment();
const siteSlug = useSiteSlug();
const isEligibleForFeature = useIsEligibleForFeature();
const { isEligibleForFeature } = useIsEligibleForFeature();
const { scheduleForEdit, onSyncSuccess, onSyncError } = props;
const initDate = scheduleForEdit
? moment( scheduleForEdit?.timestamp * 1000 )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface Props {
}
export const ScheduleListCards = ( props: Props ) => {
const siteSlug = useSiteSlug();
const isEligibleForFeature = useIsEligibleForFeature();
const { isEligibleForFeature } = useIsEligibleForFeature();
const moment = useLocalizedMoment();
const { onEditClick, onRemoveClick } = props;
const { data: schedules = [] } = useUpdateScheduleQuery( siteSlug, isEligibleForFeature );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface Props {
}
export const ScheduleListTable = ( props: Props ) => {
const siteSlug = useSiteSlug();
const isEligibleForFeature = useIsEligibleForFeature();
const { isEligibleForFeature } = useIsEligibleForFeature();
const moment = useLocalizedMoment();
const { onEditClick, onRemoveClick } = props;
const { data: schedules = [] } = useUpdateScheduleQuery( siteSlug, isEligibleForFeature );
Expand Down
8 changes: 5 additions & 3 deletions client/blocks/plugins-update-manager/schedule-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ interface Props {
}
export const ScheduleList = ( props: Props ) => {
const siteSlug = useSiteSlug();
const isEligibleForFeature = useIsEligibleForFeature();
const { isEligibleForFeature, loading: isEligibleForFeatureLoading } = useIsEligibleForFeature();
const isMobile = useMobileBreakpoint();

const { onNavBack, onCreateNewSchedule, onEditSchedule } = props;
Expand All @@ -52,7 +52,7 @@ export const ScheduleList = ( props: Props ) => {
);

const showScheduleListEmpty =
! isEligibleForFeature ||
( ! isEligibleForFeature && ! isEligibleForFeatureLoading ) ||
( isFetched &&
! isLoadingCanCreateSchedules &&
( schedules.length === 0 || ! canCreateSchedules ) );
Expand Down Expand Up @@ -99,7 +99,9 @@ export const ScheduleList = ( props: Props ) => {
<div className="ch-placeholder"></div>
</CardHeader>
<CardBody>
{ ( isLoading || isLoadingCanCreateSchedules ) && <Spinner /> }
{ ( isLoading || isLoadingCanCreateSchedules || isEligibleForFeatureLoading ) && (
<Spinner />
) }
{ showScheduleListEmpty && (
<ScheduleListEmpty
onCreateNewSchedule={ onCreateNewSchedule }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,19 @@ import './style.scss';

interface ScheduledUpdatesGateProps {
children: ReactNode;
hasScheduledUpdatesFeature: boolean;
isAtomic: boolean;
siteId: SiteId;
}

const ScheduledUpdatesGate: FC< ScheduledUpdatesGateProps > = ( {
children,
hasScheduledUpdatesFeature,
isAtomic,
siteId,
} ) => {
const ScheduledUpdatesGate: FC< ScheduledUpdatesGateProps > = ( { children, siteId } ) => {
const translate = useTranslate();
const dispatch = useDispatch();
const transferState = useSelector( ( state ) => getAutomatedTransferStatus( state, siteId ) );
const isEligibleForFeature = useIsEligibleForFeature();
const {
isEligibleForFeature,
hasScheduledUpdatesFeature,
isAtomic,
loading: isEligibleForFeatureLoading,
} = useIsEligibleForFeature();
const [ hasTransfer, setHasTransferring ] = useState(
!! (
transferState &&
Expand Down Expand Up @@ -75,7 +73,7 @@ const ScheduledUpdatesGate: FC< ScheduledUpdatesGateProps > = ( {
return null;
};

if ( ! isEligibleForFeature ) {
if ( ! isEligibleForFeature && ! isEligibleForFeatureLoading ) {
return (
<div tabIndex={ -1 } className="scheduled-updates-gate" onFocus={ handleFocus }>
{ getNoticeBanner() }
Expand Down

0 comments on commit ba1e802

Please sign in to comment.