Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { useTrackFlagpageImpactMetrics } from 'component/impact-metrics/useImpac
import { useUiFlag } from 'hooks/useUiFlag';
import { RegisterMetricDialog } from 'component/impact-metrics/RegisterMetricDialog/RegisterMetricDialog';
import { useTrackRegisterImpactMetrics } from 'component/impact-metrics/RegisterMetricDialog/useTrackRegisterImpactMetrics';
import { useRegisterImpactMetric } from 'component/impact-metrics/ImpactMetricRegistrationContext';

type MetricOption = {
name: string;
Expand Down Expand Up @@ -128,9 +129,15 @@ export const MetricSelector: FC<MetricSelectorProps> = ({
}) => {
const allOptions = withSelectedValue(options, value, valueSource);
const registerImpactMetricsEnabled = useUiFlag('registerImpactMetrics');
const [registerDialogOpen, setRegisterDialogOpen] = useState(false);
const registrationContext = useRegisterImpactMetric();
const [registerMetricDialogOpen, setRegisterMetricDialogOpen] =
useState(false);
const { trackFormOpened } = useTrackRegisterImpactMetrics();

const switchToRegisterDialog = registrationContext?.openRegisterDialog;
const handleRegisterClick =
switchToRegisterDialog ?? (() => setRegisterMetricDialogOpen(true));

return (
<>
<Autocomplete
Expand Down Expand Up @@ -188,7 +195,7 @@ export const MetricSelector: FC<MetricSelectorProps> = ({
onRegisterClick={
registerImpactMetricsEnabled
? () => {
setRegisterDialogOpen(true);
handleRegisterClick();
trackFormOpened();
}
: undefined
Expand All @@ -197,10 +204,12 @@ export const MetricSelector: FC<MetricSelectorProps> = ({
}
sx={{ minWidth: 300 }}
/>
<RegisterMetricDialog
open={registerDialogOpen}
onClose={() => setRegisterDialogOpen(false)}
/>
{!registrationContext && (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having trouble understanding why this is here? What's it doing?

<RegisterMetricDialog
open={registerMetricDialogOpen}
onClose={() => setRegisterMetricDialogOpen(false)}
/>
)}
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createContext, useContext } from 'react';

type ImpactMetricRegistrationContextType = {
openRegisterDialog: () => void;
};

const ImpactMetricRegistrationContext = createContext<

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not super set on the name here

ImpactMetricRegistrationContextType | undefined
>(undefined);

export const ImpactMetricRegistrationProvider =
ImpactMetricRegistrationContext.Provider;

export const useRegisterImpactMetric = () =>
useContext(ImpactMetricRegistrationContext);
41 changes: 29 additions & 12 deletions frontend/src/component/impact-metrics/ImpactMetrics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { Typography, styled, Box } from '@mui/material';
import { PageHeader } from 'component/common/PageHeader/PageHeader.tsx';
import { useImpactMetricsOptions } from 'hooks/api/getters/useImpactMetricsMetadata/useImpactMetricsMetadata';
import { ImpactMetricModal } from './ImpactMetricModal/ImpactMetricModal.tsx';
import { RegisterMetricDialog } from './RegisterMetricDialog/RegisterMetricDialog';
import { ImpactMetricRegistrationProvider } from './ImpactMetricRegistrationContext';
import { ChartItem } from './ChartItem.tsx';
import { PlausibleChartItem } from './PlausibleChartItem.tsx';
import { GridLayoutWrapper, type GridItem } from './GridLayoutWrapper.tsx';
Expand Down Expand Up @@ -31,7 +33,9 @@ const _StyledDragHandle = styled(Box)(({ theme }) => ({
}));

export const ImpactMetrics: FC = () => {
const [modalOpen, setModalOpen] = useState(false);
const [createChartDialogOpen, setCreateChartDialogOpen] = useState(false);
const [registerMetricDialogOpen, setRegisterMetricDialogOpen] =
useState(false);
Comment on lines +36 to +38

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if they're both true, though? Instead of two independent pieces of state, could we model this as

const [openDialog, setOpenDialog] useState<'createChart' | 'registerMetrics' | null>(null)

Or something like that?

const [editingChart, setEditingChart] = useState<ChartConfig | undefined>();
const { setToastApiError } = useToast();
const plausibleMetricsEnabled = useUiFlag('plausibleMetrics');
Expand All @@ -54,7 +58,7 @@ export const ImpactMetrics: FC = () => {

const handleAddChart = () => {
setEditingChart(undefined);
setModalOpen(true);
setCreateChartDialogOpen(true);
trackEvent('impact-metrics', {
props: {
eventType: 'global chart modal open',
Expand All @@ -64,7 +68,7 @@ export const ImpactMetrics: FC = () => {

const handleEditChart = (config: ChartConfig) => {
setEditingChart(config);
setModalOpen(true);
setCreateChartDialogOpen(true);
};

const handleSaveChart = async (config: Omit<ChartConfig, 'id'>) => {
Expand All @@ -74,7 +78,7 @@ export const ImpactMetrics: FC = () => {
} else {
await addChart(config);
}
setModalOpen(false);
setCreateChartDialogOpen(false);
} catch (error) {
setToastApiError(formatUnknownError(error));
}
Expand Down Expand Up @@ -180,14 +184,27 @@ export const ImpactMetrics: FC = () => {
</>
)}

<ImpactMetricModal
open={modalOpen}
onClose={() => setModalOpen(false)}
onSave={handleSaveChart}
initialConfig={editingChart}
metrics={metricOptions}
loading={metadataLoading || settingsLoading}
/>
<ImpactMetricRegistrationProvider

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could have also achieved the same thing by prop drilling (which is what I initially did), but I'm kinda allergic to it

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a more generic way to solve this, though? We can probably assume that modals should replace one another, and it'd be neat to not have to this over and over again?

Also, we're assuming that we don't want that. Are we sure we don't? (we should check with ux)

value={{
openRegisterDialog: () => {
setCreateChartDialogOpen(false);
setRegisterMetricDialogOpen(true);
},
}}
>
<ImpactMetricModal
open={createChartDialogOpen}
onClose={() => setCreateChartDialogOpen(false)}
onSave={handleSaveChart}
initialConfig={editingChart}
metrics={metricOptions}
loading={metadataLoading || settingsLoading}
/>
<RegisterMetricDialog
open={registerMetricDialogOpen}
onClose={() => setRegisterMetricDialogOpen(false)}
/>
</ImpactMetricRegistrationProvider>
</>
);
};
Loading