mirror of
https://github.com/Unleash/unleash.git
synced 2025-06-18 01:18:23 +02:00
feat: implement plausible tracking (#3212)
Adds plausible event tracking for notifications. Refactors Feedback component to be reusable and to ask whether or not this functionality is useful.
This commit is contained in:
parent
90e4054c90
commit
87312f90ca
@ -1,11 +1,13 @@
|
|||||||
import { useState, VFC } from 'react';
|
import { useState, VFC } from 'react';
|
||||||
import { Box, Paper, Button, styled } from '@mui/material';
|
import { Box, Paper, Button, styled } from '@mui/material';
|
||||||
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
|
import { CustomEvents, usePlausibleTracker } from 'hooks/usePlausibleTracker';
|
||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
import { createLocalStorage } from 'utils/createLocalStorage';
|
import { createLocalStorage } from 'utils/createLocalStorage';
|
||||||
|
|
||||||
interface IFeedbackProps {
|
interface IFeedbackProps {
|
||||||
id: string;
|
id: string;
|
||||||
|
eventName: CustomEvents;
|
||||||
|
localStorageKey: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const StyledBox = styled(Box)(({ theme }) => ({
|
const StyledBox = styled(Box)(({ theme }) => ({
|
||||||
@ -14,11 +16,15 @@ const StyledBox = styled(Box)(({ theme }) => ({
|
|||||||
marginTop: theme.spacing(0.5),
|
marginTop: theme.spacing(0.5),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const Feedback: VFC<IFeedbackProps> = ({ id }) => {
|
export const Feedback: VFC<IFeedbackProps> = ({
|
||||||
|
id,
|
||||||
|
localStorageKey,
|
||||||
|
eventName,
|
||||||
|
}) => {
|
||||||
const { uiConfig } = useUiConfig();
|
const { uiConfig } = useUiConfig();
|
||||||
const { value: selectedValue, setValue: setSelectedValue } =
|
const { value: selectedValue, setValue: setSelectedValue } =
|
||||||
createLocalStorage<{ value?: 'yes' | 'no' }>(
|
createLocalStorage<{ value?: 'yes' | 'no' }>(
|
||||||
`ProjectOverviewFeedback:v1:${id}`,
|
`${uiConfig.baseUriPath}:${localStorageKey}:v1:${id}`,
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
const [selected, setSelected] = useState<'yes' | 'no' | undefined>(
|
const [selected, setSelected] = useState<'yes' | 'no' | undefined>(
|
||||||
@ -26,14 +32,14 @@ export const Feedback: VFC<IFeedbackProps> = ({ id }) => {
|
|||||||
);
|
);
|
||||||
const { trackEvent } = usePlausibleTracker();
|
const { trackEvent } = usePlausibleTracker();
|
||||||
|
|
||||||
if (!uiConfig?.flags?.T) {
|
if (!uiConfig?.flags?.T || Boolean(selected)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const onTrackFeedback = (value: 'yes' | 'no') => {
|
const onTrackFeedback = (value: 'yes' | 'no') => {
|
||||||
setSelected(value);
|
setSelected(value);
|
||||||
setSelectedValue({ value });
|
setSelectedValue({ value });
|
||||||
trackEvent('project_overview', {
|
trackEvent(eventName, {
|
||||||
props: {
|
props: {
|
||||||
eventType: id,
|
eventType: id,
|
||||||
wasHelpful: value === 'yes',
|
wasHelpful: value === 'yes',
|
@ -9,7 +9,7 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { useNotifications } from 'hooks/api/getters/useNotifications/useNotifications';
|
import { useNotifications } from 'hooks/api/getters/useNotifications/useNotifications';
|
||||||
import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import NotificationsIcon from '@mui/icons-material/Notifications';
|
import NotificationsIcon from '@mui/icons-material/Notifications';
|
||||||
import { NotificationsHeader } from './NotificationsHeader';
|
import { NotificationsHeader } from './NotificationsHeader';
|
||||||
import { NotificationsList } from './NotificationsList';
|
import { NotificationsList } from './NotificationsList';
|
||||||
@ -18,6 +18,9 @@ import { EmptyNotifications } from './EmptyNotifications';
|
|||||||
import { NotificationsSchemaItem } from 'openapi';
|
import { NotificationsSchemaItem } from 'openapi';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { useNotificationsApi } from 'hooks/api/actions/useNotificationsApi/useNotificationsApi';
|
import { useNotificationsApi } from 'hooks/api/actions/useNotificationsApi/useNotificationsApi';
|
||||||
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
|
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
|
||||||
|
import { Feedback } from 'component/common/Feedback/Feedback';
|
||||||
|
|
||||||
const StyledPrimaryContainerBox = styled(Box)(() => ({
|
const StyledPrimaryContainerBox = styled(Box)(() => ({
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
@ -63,11 +66,20 @@ export const Notifications = () => {
|
|||||||
});
|
});
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { markAsRead } = useNotificationsApi();
|
const { markAsRead } = useNotificationsApi();
|
||||||
|
const { uiConfig } = useUiConfig();
|
||||||
|
const { trackEvent } = usePlausibleTracker();
|
||||||
|
|
||||||
const onNotificationClick = (notification: NotificationsSchemaItem) => {
|
const onNotificationClick = (notification: NotificationsSchemaItem) => {
|
||||||
if (notification.link) {
|
if (notification.link) {
|
||||||
navigate(notification.link);
|
navigate(notification.link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (uiConfig?.flags?.T) {
|
||||||
|
trackEvent('notifications', {
|
||||||
|
props: { eventType: notification.notificationType },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setShowNotifications(false);
|
setShowNotifications(false);
|
||||||
|
|
||||||
// Intentionally not wait for this request. We don't want to hold the user back
|
// Intentionally not wait for this request. We don't want to hold the user back
|
||||||
@ -154,6 +166,12 @@ export const Notifications = () => {
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</NotificationsList>
|
</NotificationsList>
|
||||||
|
<Feedback
|
||||||
|
eventName="notifications"
|
||||||
|
id="useful"
|
||||||
|
localStorageKey="NotificationsUsefulPrompt"
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
</StyledPaper>
|
</StyledPaper>
|
||||||
</ClickAwayListener>
|
</ClickAwayListener>
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
ClickAwayListener,
|
ClickAwayListener,
|
||||||
styled,
|
styled,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { Feedback } from './Feedback';
|
import { Feedback } from 'component/common/Feedback/Feedback';
|
||||||
|
|
||||||
interface IHelpPopperProps {
|
interface IHelpPopperProps {
|
||||||
id: string;
|
id: string;
|
||||||
@ -66,7 +66,11 @@ export const HelpPopper: FC<IHelpPopperProps> = ({ children, id }) => {
|
|||||||
/>
|
/>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
{children}
|
{children}
|
||||||
<Feedback id={id} />
|
<Feedback
|
||||||
|
id={id}
|
||||||
|
eventName="project_overview"
|
||||||
|
localStorageKey="ProjectOverviewFeedback"
|
||||||
|
/>
|
||||||
</StyledPaper>
|
</StyledPaper>
|
||||||
</ClickAwayListener>
|
</ClickAwayListener>
|
||||||
</Popper>
|
</Popper>
|
||||||
|
@ -8,7 +8,7 @@ import { EventOptions, PlausibleOptions } from 'plausible-tracker';
|
|||||||
* @see https://plausible.io/docs/custom-event-goals#2-create-a-custom-event-goal-in-your-plausible-analytics-account
|
* @see https://plausible.io/docs/custom-event-goals#2-create-a-custom-event-goal-in-your-plausible-analytics-account
|
||||||
* @example `'download | 'invite' | 'signup'`
|
* @example `'download | 'invite' | 'signup'`
|
||||||
**/
|
**/
|
||||||
type CustomEvents =
|
export type CustomEvents =
|
||||||
| 'invite'
|
| 'invite'
|
||||||
| 'upgrade_plan_clicked'
|
| 'upgrade_plan_clicked'
|
||||||
| 'change_request'
|
| 'change_request'
|
||||||
@ -20,7 +20,8 @@ type CustomEvents =
|
|||||||
| 'suggest_tags'
|
| 'suggest_tags'
|
||||||
| 'unknown_ui_error'
|
| 'unknown_ui_error'
|
||||||
| 'export_import'
|
| 'export_import'
|
||||||
| 'project_api_tokens';
|
| 'project_api_tokens'
|
||||||
|
| 'notifications';
|
||||||
|
|
||||||
export const usePlausibleTracker = () => {
|
export const usePlausibleTracker = () => {
|
||||||
const plausible = useContext(PlausibleContext);
|
const plausible = useContext(PlausibleContext);
|
||||||
|
Loading…
Reference in New Issue
Block a user