Skip to content

Commit

Permalink
♻️ [open-formulieren/open-forms#4929] Move analytics tool config load…
Browse files Browse the repository at this point in the history
…ing into own component

Instead of hooking this up to the Form component, we can instead wrap
the context provider and let it fetch the config by itself. This way,
we slim down the Form component, and get a small performance boost
since loading the analytics tool config is not immediately relevant.

Since context is used, only when the config loading is resolved will
the consumers be re-rendered, which at this point is mostly the
AbortButton component. We deliberately don't show a loader when
the config is being retrieved as this would block the entire page
without good reason and we have a faster time-to-interact this way.
  • Loading branch information
sergei-maertens committed Jan 18, 2025
1 parent f530400 commit 0f1e874
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 31 deletions.
16 changes: 1 addition & 15 deletions src/Context.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,6 @@ const FormContext = React.createContext({
});
FormContext.displayName = 'FormContext';

const AnalyticsToolsConfigContext = React.createContext({
govmetricSourceIdFormFinished: '',
govmetricSourceIdFormAborted: '',
govmetricSecureGuidFormFinished: '',
govmetricSecureGuidFormAborted: '',
enableGovmetricAnalytics: false,
});

const ConfigContext = React.createContext({
baseUrl: '',
clientBaseUrl: window.location.href,
Expand All @@ -51,10 +43,4 @@ FormioTranslations.displayName = 'FormioTranslations';
const SubmissionContext = React.createContext({submission: null});
SubmissionContext.displayName = 'SubmissionContext';

export {
FormContext,
ConfigContext,
FormioTranslations,
SubmissionContext,
AnalyticsToolsConfigContext,
};
export {FormContext, ConfigContext, FormioTranslations, SubmissionContext};
5 changes: 2 additions & 3 deletions src/components/AbortButton/AbortButton.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import PropTypes from 'prop-types';
import {useContext} from 'react';
import {FormattedMessage, useIntl} from 'react-intl';

import {AnalyticsToolsConfigContext} from 'Context';
import {OFButton} from 'components/Button';
import {useAnalyticsToolsConfig} from 'components/analytics/AnalyticsToolConfigProvider';
import {buildGovMetricUrl} from 'components/analytics/utils';
import useFormContext from 'hooks/useFormContext';

const AbortButton = ({isAuthenticated, onDestroySession}) => {
const intl = useIntl();
const analyticsToolsConfig = useContext(AnalyticsToolsConfigContext);
const analyticsToolsConfig = useAnalyticsToolsConfig;
const form = useFormContext();

const confirmationMessage = isAuthenticated
Expand Down
18 changes: 8 additions & 10 deletions src/components/Form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ import {
useNavigate,
useSearchParams,
} from 'react-router-dom';
import {useAsync, usePrevious} from 'react-use';
import {usePrevious} from 'react-use';

import {AnalyticsToolsConfigContext, ConfigContext} from 'Context';
import {destroy, get} from 'api';
import {ConfigContext} from 'Context';
import {destroy} from 'api';
import Loader from 'components/Loader';
import ProgressIndicator from 'components/ProgressIndicator';
import AnalyticsToolsConfigProvider from 'components/analytics/AnalyticsToolConfigProvider';
import {
PI_TITLE,
START_FORM_QUERY_PARAM,
Expand Down Expand Up @@ -72,16 +73,13 @@ const Form = () => {
};

// if there is an active submission still, re-load that (relevant for hard-refreshes)
// TODO: should probably move to the router loader
const [loading, setSubmissionId, removeSubmissionId] = useRecycleSubmission(
form,
submission,
onSubmissionLoaded
);

const {value: analyticsToolsConfigInfo, loading: loadingAnalyticsConfig} = useAsync(async () => {
return await get(`${config.baseUrl}analytics/analytics-tools-config-info`);
}, [intl.locale]);

useEffect(
() => {
if (prevLocale === undefined) return;
Expand Down Expand Up @@ -120,7 +118,7 @@ const Form = () => {
);
}

if (loading || loadingAnalyticsConfig || shouldAutomaticallyRedirect) {
if (loading || shouldAutomaticallyRedirect) {
return <Loader modifiers={['centered']} />;
}

Expand Down Expand Up @@ -204,7 +202,7 @@ const Form = () => {
// render the form step if there's an active submission (and no summary)
return (
<FormDisplay progressIndicator={progressIndicator}>
<AnalyticsToolsConfigContext.Provider value={analyticsToolsConfigInfo}>
<AnalyticsToolsConfigProvider>
<SubmissionProvider
submission={submission}
onSubmissionObtained={submission => {
Expand All @@ -216,7 +214,7 @@ const Form = () => {
>
<Outlet />
</SubmissionProvider>
</AnalyticsToolsConfigContext.Provider>
</AnalyticsToolsConfigProvider>
</FormDisplay>
);
};
Expand Down
40 changes: 40 additions & 0 deletions src/components/analytics/AnalyticsToolConfigProvider.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import PropTypes from 'prop-types';
import React, {useContext} from 'react';
import {useIntl} from 'react-intl';
import {useAsync} from 'react-use';

import {ConfigContext} from 'Context';
import {get} from 'api';

const AnalyticsToolsConfigContext = React.createContext({
govmetricSourceIdFormFinished: '',
govmetricSourceIdFormAborted: '',
govmetricSecureGuidFormFinished: '',
govmetricSecureGuidFormAborted: '',
enableGovmetricAnalytics: false,
});

AnalyticsToolsConfigContext.displayName = 'AnalyticsToolsConfigContext';

const AnalyticsToolsConfigProvider = ({children}) => {
const {locale} = useIntl();
const {baseUrl} = useContext(ConfigContext);

const {value} = useAsync(async () => {
return await get(`${baseUrl}analytics/analytics-tools-config-info`);
}, [locale]);

return (
<AnalyticsToolsConfigContext.Provider value={value}>
{children}
</AnalyticsToolsConfigContext.Provider>
);
};

AnalyticsToolsConfigProvider.propTypes = {
children: PropTypes.node,
};

export const useAnalyticsToolsConfig = () => useContext(AnalyticsToolsConfigContext);

export default AnalyticsToolsConfigProvider;
5 changes: 2 additions & 3 deletions src/components/analytics/GovMetricSnippet.jsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import govmetricAverageImg from 'img/govmetric/average.png';
import govmetricGoodImg from 'img/govmetric/good.png';
import govmetricPoorImg from 'img/govmetric/poor.png';
import {useContext} from 'react';
import {FormattedMessage, useIntl} from 'react-intl';

import {AnalyticsToolsConfigContext} from 'Context';
import useFormContext from 'hooks/useFormContext';

import {useAnalyticsToolsConfig} from './AnalyticsToolConfigProvider';
import {buildGovMetricUrl, govMetricURLWithRating} from './utils';

const GovMetricSnippet = () => {
const {enableGovmetricAnalytics, govmetricSourceIdFormFinished, govmetricSecureGuidFormFinished} =
useContext(AnalyticsToolsConfigContext);
useAnalyticsToolsConfig();
const form = useFormContext();
const intl = useIntl();

Expand Down

0 comments on commit 0f1e874

Please sign in to comment.