mirror of
https://github.com/strapi/strapi.git
synced 2025-12-05 03:21:22 +00:00
commit
640da651db
@ -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>;
|
||||
};
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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 />, {
|
||||
|
||||
@ -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 />, {
|
||||
|
||||
@ -169,7 +169,6 @@ const EditView = () => {
|
||||
replace: true,
|
||||
state: { transferToken: res.data },
|
||||
});
|
||||
setCurrentStep('transferTokens.success');
|
||||
} else {
|
||||
const res = await updateToken({
|
||||
id: id!,
|
||||
|
||||
@ -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.
|
||||
*/
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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({
|
||||
|
||||
@ -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 });
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user