Merge pull request #21183 from strapi/fix/guided-tour

fix: guided tour
This commit is contained in:
Alexandre BODIN 2024-09-09 15:05:24 +02:00 committed by GitHub
commit 640da651db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 54 additions and 57 deletions

View File

@ -19,6 +19,7 @@ function createContext<ContextValueType extends object | null>(
// Only re-memoize when prop values change
// eslint-disable-next-line react-hooks/exhaustive-deps
const value = React.useMemo(() => context, Object.values(context)) as ContextValueType;
return <Context.Provider value={value}>{children}</Context.Provider>;
};

View File

@ -9,6 +9,8 @@ import { LAYOUT_DATA, States, STATES } from './constants';
import { Number, VerticalDivider } from './Ornaments';
import { GuidedTourContextValue, useGuidedTour } from './Provider';
type SectionName = keyof GuidedTourContextValue['guidedTourState'];
const GuidedTourHomepage = () => {
const guidedTourState = useGuidedTour('GuidedTourHomepage', (state) => state.guidedTourState);
const setSkipped = useGuidedTour('GuidedTourHomepage', (state) => state.setSkipped);
@ -28,9 +30,7 @@ const GuidedTourHomepage = () => {
{formatMessage(val.home.cta.title)}
</LinkButton>
),
isDone: Object.entries(
guidedTourState[key as keyof GuidedTourContextValue['guidedTourState']]
).every(([, value]) => value),
isDone: Object.values(guidedTourState[key as SectionName]).every((value) => value === true),
}));
const activeSectionIndex = sections.findIndex((section) => !section.isDone);
@ -60,6 +60,7 @@ const GuidedTourHomepage = () => {
<Box>
{sections.map((section, index) => {
const state = getState(activeSectionIndex, index);
return (
<Box key={section.key}>
<Flex>

View File

@ -28,15 +28,16 @@ import { GuidedTourContextValue, useGuidedTour } from './Provider';
* -----------------------------------------------------------------------------------------------*/
const GuidedTourModal = () => {
const currentStep = useGuidedTour('GuidedTourModal', (state) => state.currentStep);
const guidedTourState = useGuidedTour('GuidedTourModal', (state) => state.guidedTourState);
const setCurrentStep = useGuidedTour('GuidedTourModal', (state) => state.setCurrentStep);
const setStepState = useGuidedTour('GuidedTourModal', (state) => state.setStepState);
const isGuidedTourVisible = useGuidedTour(
'GuidedTourModal',
(state) => state.isGuidedTourVisible
);
const setSkipped = useGuidedTour('GuidedTourModal', (state) => state.setSkipped);
const guidedTour = useGuidedTour('GuidedTourModal', (state) => state);
const {
currentStep,
guidedTourState,
setCurrentStep,
setStepState,
isGuidedTourVisible,
setSkipped,
} = guidedTour;
const { formatMessage } = useIntl();
const { trackUsage } = useTracking();

View File

@ -38,10 +38,6 @@ interface GuidedTourContextValue {
create: boolean;
success: boolean;
};
transferTokens: {
create: boolean;
success: boolean;
};
};
isGuidedTourVisible: boolean;
isSkipped: boolean;
@ -175,10 +171,6 @@ const initialState = {
create: false,
success: false,
},
transferTokens: {
create: false,
success: false,
},
},
isGuidedTourVisible: false,
isSkipped: false,
@ -246,7 +238,7 @@ const initialiseState = (initialState: State) => {
window.localStorage.getItem(GUIDED_TOUR_CURRENT_STEP) ?? 'null'
);
const skippedLocaleStorage = JSON.parse(
window.localStorage.getItem(GUIDED_TOUR_SKIPPED) ?? 'false'
window.localStorage.getItem(GUIDED_TOUR_SKIPPED) ?? 'null'
);
if (Array.isArray(guidedTourLocaleStorage)) {

View File

@ -4,8 +4,6 @@ import { Register } from '../Register';
const FIELD_LABELS = ['Firstname', 'Lastname', 'Email', 'Password', 'Confirm Password'];
jest.mock('../../../../components/GuidedTour/Provider');
describe('Register', () => {
it('renders correctly', () => {
const { getByText, getByRole, getByLabelText } = render(<Register />, {

View File

@ -2,8 +2,6 @@ import { render } from '@tests/utils';
import { EditView } from '../EditViewPage';
jest.mock('../../../../../../components/GuidedTour/Provider');
describe('ADMIN | Pages | API TOKENS | EditView', () => {
it('renders and matches the snapshot when creating token', async () => {
const { findByText } = render(<EditView />, {

View File

@ -169,7 +169,6 @@ const EditView = () => {
replace: true,
state: { transferToken: res.data },
});
setCurrentStep('transferTokens.success');
} else {
const res = await updateToken({
id: id!,

View File

@ -9,8 +9,6 @@ jest.mock('../../features/AppInfo', () => ({
useAppInfo: jest.fn((name, getter) => getter({ communityEdition: true })),
}));
jest.mock('../../components/GuidedTour/Provider');
/**
* TODO: remove this mock.
*/

View File

@ -24,6 +24,7 @@ import { QueryClient, QueryClientProvider, setLogger } from 'react-query';
import { Provider } from 'react-redux';
import { MemoryRouterProps, RouterProvider, createMemoryRouter } from 'react-router-dom';
import { GuidedTourProvider } from '../src/components/GuidedTour/Provider';
import { LanguageProvider } from '../src/components/LanguageProvider';
import { Theme } from '../src/components/Theme';
import { RBAC } from '../src/core/apis/rbac';
@ -151,29 +152,31 @@ const Providers = ({ children, initialEntries, storeConfig, permissions = [] }:
}}
>
<NotificationsProvider>
<ConfigurationContextProvider
showReleaseNotification={false}
showTutorials={false}
logos={{
auth: { default: 'default' },
menu: { default: 'default' },
}}
updateProjectSettings={jest.fn()}
>
<AppInfoProvider
autoReload
useYarn
dependencies={{
'@strapi/plugin-documentation': '4.2.0',
'@strapi/provider-upload-cloudinary': '4.2.0',
<GuidedTourProvider>
<ConfigurationContextProvider
showReleaseNotification={false}
showTutorials={false}
logos={{
auth: { default: 'default' },
menu: { default: 'default' },
}}
strapiVersion="4.1.0"
communityEdition
shouldUpdateStrapi={false}
updateProjectSettings={jest.fn()}
>
{children}
</AppInfoProvider>
</ConfigurationContextProvider>
<AppInfoProvider
autoReload
useYarn
dependencies={{
'@strapi/plugin-documentation': '4.2.0',
'@strapi/provider-upload-cloudinary': '4.2.0',
}}
strapiVersion="4.1.0"
communityEdition
shouldUpdateStrapi={false}
>
{children}
</AppInfoProvider>
</ConfigurationContextProvider>
</GuidedTourProvider>
</NotificationsProvider>
</Theme>
</LanguageProvider>

View File

@ -6,6 +6,7 @@ import {
useTracking,
type TrackingEvent,
useAPIErrorHandler,
useGuidedTour,
} from '@strapi/admin/strapi-admin';
import { useIntl, type MessageDescriptor } from 'react-intl';
import { useNavigate } from 'react-router-dom';
@ -193,6 +194,7 @@ const useDocumentActions: UseDocumentActions = () => {
const { trackUsage } = useTracking();
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
const navigate = useNavigate();
const setCurrentStep = useGuidedTour('useDocumentActions', (state) => state.setCurrentStep);
const [deleteDocument] = useDeleteDocumentMutation();
const _delete: IUseDocumentActs['delete'] = React.useCallback(
@ -577,6 +579,8 @@ const useDocumentActions: UseDocumentActions = () => {
}),
});
setCurrentStep('contentManager.success');
return res.data;
} catch (err) {
toggleNotification({

View File

@ -83,7 +83,7 @@ const DataManagerProvider = ({ children }: DataManagerProviderProps) => {
} = useSelector(makeSelectDataManagerProvider());
const { toggleNotification } = useNotification();
const { lockAppWithAutoreload, unlockAppWithAutoreload } = useAutoReloadOverlayBlocker();
const setCurrentStep = useGuidedTour('DataManagerProvider', (state) => state.setCurrentStep);
const { setCurrentStep, setStepState } = useGuidedTour('DataManagerProvider', (state) => state);
const getPlugin = useStrapiApp('DataManagerProvider', (state) => state.getPlugin);
@ -548,18 +548,14 @@ const DataManagerProvider = ({ children }: DataManagerProviderProps) => {
await put(requestURL, body);
}
// Make sure the server has restarted
await serverRestartWatcher(true);
// Unlock the app
unlockAppWithAutoreload?.();
if (
isCreating &&
(initialData.contentType?.schema.kind === 'collectionType' ||
initialData.contentType?.schema.kind === 'singleType')
) {
setCurrentStep('contentTypeBuilder.success');
setStepState('contentTypeBuilder.success', true);
trackUsage('didCreateGuidedTourCollectionType');
setCurrentStep(null);
}
// Submit ct tracking success
@ -576,6 +572,12 @@ const DataManagerProvider = ({ children }: DataManagerProviderProps) => {
trackUsage('didSaveComponent');
}
// Make sure the server has restarted
await serverRestartWatcher(true);
// Unlock the app
unlockAppWithAutoreload?.();
// refetch and update initial state after the data has been saved
await getDataRef.current();
dispatch({ type: UPDATE_INITIAL_STATE });