1
0
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:
Fredrik Strand Oseberg 2023-02-28 14:29:14 +01:00 committed by GitHub
parent 90e4054c90
commit 87312f90ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 10 deletions

View File

@ -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',

View File

@ -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>
} }

View File

@ -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>

View File

@ -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);