diff --git a/packages/core/admin/admin/src/content-manager/components/DynamicTable/TableRows/index.js b/packages/core/admin/admin/src/content-manager/components/DynamicTable/TableRows/index.js
index 2fcb1da4c0..406b5e4aba 100644
--- a/packages/core/admin/admin/src/content-manager/components/DynamicTable/TableRows/index.js
+++ b/packages/core/admin/admin/src/content-manager/components/DynamicTable/TableRows/index.js
@@ -51,7 +51,7 @@ const TableRows = ({
key={data.id}
{...onRowClick({
fn: () => {
- trackUsage('willEditEntryFromButton');
+ trackUsage('willEditEntryFromList');
push({
pathname: `${pathname}/${data.id}`,
state: { from: pathname },
@@ -141,7 +141,11 @@ const TableRows = ({
{canDelete && (
onClickDelete(data.id)}
+ onClick={() => {
+ trackUsage('willDeleteEntryFromList');
+
+ onClickDelete(data.id);
+ }}
label={formatMessage(
{ id: 'app.component.table.delete', defaultMessage: 'Delete {target}' },
{ target: itemLineText }
diff --git a/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js b/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js
index e958f00781..94871749cc 100644
--- a/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js
+++ b/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js
@@ -81,6 +81,7 @@ const DynamicTable = ({
headers={tableHeaders}
onConfirmDelete={onConfirmDelete}
onConfirmDeleteAll={onConfirmDeleteAll}
+ onOpenDeleteAllModalTrackedEvent="willBulkDeleteEntries"
rows={rows}
withBulkActions
withMainAction={canDelete && isBulkable}
diff --git a/packages/core/admin/admin/src/content-manager/pages/ListView/FieldPicker/index.js b/packages/core/admin/admin/src/content-manager/pages/ListView/FieldPicker/index.js
index f3be1d19ff..3fe7db35b3 100644
--- a/packages/core/admin/admin/src/content-manager/pages/ListView/FieldPicker/index.js
+++ b/packages/core/admin/admin/src/content-manager/pages/ListView/FieldPicker/index.js
@@ -26,6 +26,8 @@ const FieldPicker = ({ layout }) => {
const values = displayedHeaders.map(({ name }) => name);
const handleChange = updatedValues => {
+ trackUsage('didChangeDisplayedFields');
+
// removing a header
if (updatedValues.length < values.length) {
const removedHeader = values.filter(value => {
@@ -34,7 +36,6 @@ const FieldPicker = ({ layout }) => {
dispatch(onChangeListHeaders({ name: removedHeader[0], value: true }));
} else {
- trackUsage('didChangeDisplayedFields');
const addedHeader = updatedValues.filter(value => {
return values.indexOf(value) === -1;
});
diff --git a/packages/core/admin/admin/src/content-manager/pages/ListView/index.js b/packages/core/admin/admin/src/content-manager/pages/ListView/index.js
index 10d445ba60..41652efd49 100644
--- a/packages/core/admin/admin/src/content-manager/pages/ListView/index.js
+++ b/packages/core/admin/admin/src/content-manager/pages/ListView/index.js
@@ -7,7 +7,6 @@ import { bindActionCreators, compose } from 'redux';
import { useIntl } from 'react-intl';
import { useHistory, useLocation } from 'react-router-dom';
import get from 'lodash/get';
-import isEmpty from 'lodash/isEmpty';
import { stringify } from 'qs';
import {
NoPermissions,
@@ -171,18 +170,6 @@ function ListView({
const handleConfirmDeleteData = useCallback(
async idToDelete => {
try {
- let trackerProperty = {};
-
- if (hasDraftAndPublish) {
- const dataToDelete = data.find(obj => obj.id.toString() === idToDelete.toString());
- const isDraftEntry = isEmpty(dataToDelete.publishedAt);
- const status = isDraftEntry ? 'draft' : 'published';
-
- trackerProperty = { status };
- }
-
- trackUsageRef.current('willDeleteEntry', trackerProperty);
-
await axiosInstance.delete(getRequestUrl(`collection-types/${slug}/${idToDelete}`));
const requestUrl = getRequestUrl(`collection-types/${slug}${params}`);
@@ -192,8 +179,6 @@ function ListView({
type: 'success',
message: { id: getTrad('success.record.delete') },
});
-
- trackUsageRef.current('didDeleteEntry', trackerProperty);
} catch (err) {
const errorMessage = get(
err,
@@ -207,7 +192,7 @@ function ListView({
});
}
},
- [hasDraftAndPublish, slug, params, fetchData, toggleNotification, data, formatMessage]
+ [slug, params, fetchData, toggleNotification, formatMessage]
);
useEffect(() => {
@@ -282,8 +267,11 @@ function ListView({
- push({ pathname: `${slug}/configurations/list`, search: pluginsQueryParams })}
+ onClick={() => {
+ trackUsage('willEditListLayout');
+
+ push({ pathname: `${slug}/configurations/list`, search: pluginsQueryParams });
+ }}
icon={}
label={formatMessage({
id: 'app.links.configure-view',
diff --git a/packages/core/admin/admin/src/pages/MarketplacePage/index.js b/packages/core/admin/admin/src/pages/MarketplacePage/index.js
index 0cbd7e23c7..f6cc804d09 100644
--- a/packages/core/admin/admin/src/pages/MarketplacePage/index.js
+++ b/packages/core/admin/admin/src/pages/MarketplacePage/index.js
@@ -1,8 +1,8 @@
-import React from 'react';
+import React, { useEffect } from 'react';
import { useIntl } from 'react-intl';
import styled from 'styled-components';
import { Helmet } from 'react-helmet';
-import { pxToRem, CheckPagePermissions } from '@strapi/helper-plugin';
+import { pxToRem, CheckPagePermissions, useTracking } from '@strapi/helper-plugin';
import { Layout, HeaderLayout, ContentLayout } from '@strapi/design-system/Layout';
import { Flex } from '@strapi/design-system/Flex';
import { Box } from '@strapi/design-system/Box';
@@ -27,6 +27,11 @@ const StackCentered = styled(Stack)`
const MarketPlacePage = () => {
const { formatMessage } = useIntl();
+ const { trackUsage } = useTracking();
+
+ useEffect(() => {
+ trackUsage('didGoToMarketplace');
+ }, [trackUsage]);
return (
diff --git a/packages/core/admin/admin/src/pages/MarketplacePage/tests/index.test.js b/packages/core/admin/admin/src/pages/MarketplacePage/tests/index.test.js
index 69238a7394..1995b8b6a3 100644
--- a/packages/core/admin/admin/src/pages/MarketplacePage/tests/index.test.js
+++ b/packages/core/admin/admin/src/pages/MarketplacePage/tests/index.test.js
@@ -2,11 +2,13 @@ import React from 'react';
import { render } from '@testing-library/react';
import { IntlProvider } from 'react-intl';
import { ThemeProvider, lightTheme } from '@strapi/design-system';
+import { useTracking } from '@strapi/helper-plugin';
import MarketPlacePage from '../index';
jest.mock('@strapi/helper-plugin', () => ({
pxToRem: jest.fn(),
CheckPagePermissions: ({ children }) => children,
+ useTracking: jest.fn(() => ({ trackUsage: jest.fn() })),
}));
const App = (
@@ -440,4 +442,12 @@ describe('Marketplace coming soon', () => {
`);
});
+
+ it('sends an event when the user enters the marketplace', () => {
+ const trackUsage = jest.fn();
+ useTracking.mockImplementation(() => ({ trackUsage }));
+ render(App);
+
+ expect(trackUsage).toHaveBeenCalledWith('didGoToMarketplace');
+ });
});
diff --git a/packages/core/helper-plugin/lib/src/components/DynamicTable/index.js b/packages/core/helper-plugin/lib/src/components/DynamicTable/index.js
index ad6f19d8ca..65bd6f79ac 100644
--- a/packages/core/helper-plugin/lib/src/components/DynamicTable/index.js
+++ b/packages/core/helper-plugin/lib/src/components/DynamicTable/index.js
@@ -9,6 +9,7 @@ import { useIntl } from 'react-intl';
import Trash from '@strapi/icons/Trash';
import styled from 'styled-components';
import useQueryParams from '../../hooks/useQueryParams';
+import useTracking from '../../hooks/useTracking';
import ConfirmDialog from '../ConfirmDialog';
import EmptyBodyTable from '../EmptyBodyTable';
import TableHead from './TableHead';
@@ -29,6 +30,7 @@ const Table = ({
isLoading,
onConfirmDeleteAll,
onConfirmDelete,
+ onOpenDeleteAllModalTrackedEvent,
rows,
withBulkActions,
withMainAction,
@@ -40,6 +42,7 @@ const Table = ({
const [isConfirmButtonLoading, setIsConfirmButtonLoading] = useState(false);
const [{ query }] = useQueryParams();
const { formatMessage } = useIntl();
+ const { trackUsage } = useTracking();
const ROW_COUNT = rows.length + 1;
const COL_COUNT = headers.length + (withBulkActions ? 1 : 0) + (withMainAction ? 1 : 0);
const hasFilters = query?.filters !== undefined;
@@ -88,6 +91,10 @@ const Table = ({
};
const handleToggleConfirmDeleteAll = () => {
+ if (!showConfirmDeleteAll && onOpenDeleteAllModalTrackedEvent) {
+ trackUsage(onOpenDeleteAllModalTrackedEvent);
+ }
+
setShowConfirmDeleteAll(prev => !prev);
};
@@ -203,6 +210,7 @@ Table.defaultProps = {
isLoading: false,
onConfirmDeleteAll: () => {},
onConfirmDelete: () => {},
+ onOpenDeleteAllModalTrackedEvent: undefined,
rows: [],
withBulkActions: false,
withMainAction: false,
@@ -229,6 +237,7 @@ Table.propTypes = {
isLoading: PropTypes.bool,
onConfirmDeleteAll: PropTypes.func,
onConfirmDelete: PropTypes.func,
+ onOpenDeleteAllModalTrackedEvent: PropTypes.string,
rows: PropTypes.array,
withBulkActions: PropTypes.bool,
withMainAction: PropTypes.bool,
diff --git a/packages/core/upload/admin/src/components/AssetDialog/index.js b/packages/core/upload/admin/src/components/AssetDialog/index.js
index f76e3afad0..2ece995b23 100644
--- a/packages/core/upload/admin/src/components/AssetDialog/index.js
+++ b/packages/core/upload/admin/src/components/AssetDialog/index.js
@@ -29,6 +29,7 @@ export const AssetDialog = ({
onValidate,
multiple,
initiallySelectedAssets,
+ trackedLocation,
}) => {
const [assetToEdit, setAssetToEdit] = useState(undefined);
const { formatMessage } = useIntl();
@@ -153,6 +154,7 @@ export const AssetDialog = ({
canUpdate={canUpdate}
canCopyLink={canCopyLink}
canDownload={canDownload}
+ trackedLocation={trackedLocation}
/>
);
}
@@ -232,6 +234,7 @@ AssetDialog.defaultProps = {
allowedTypes: [],
initiallySelectedAssets: [],
multiple: false,
+ trackedLocation: undefined,
};
AssetDialog.propTypes = {
@@ -241,4 +244,5 @@ AssetDialog.propTypes = {
onAddAsset: PropTypes.func.isRequired,
onClose: PropTypes.func.isRequired,
onValidate: PropTypes.func.isRequired,
+ trackedLocation: PropTypes.string,
};
diff --git a/packages/core/upload/admin/src/components/EditAssetDialog/ReplaceMediaButton.js b/packages/core/upload/admin/src/components/EditAssetDialog/ReplaceMediaButton.js
index eb3ef2b324..4819d6b991 100644
--- a/packages/core/upload/admin/src/components/EditAssetDialog/ReplaceMediaButton.js
+++ b/packages/core/upload/admin/src/components/EditAssetDialog/ReplaceMediaButton.js
@@ -1,16 +1,23 @@
import PropTypes from 'prop-types';
import React, { useRef } from 'react';
import { useIntl } from 'react-intl';
+import { useTracking } from '@strapi/helper-plugin';
import { Button } from '@strapi/design-system/Button';
import { VisuallyHidden } from '@strapi/design-system/VisuallyHidden';
import { getTrad } from '../../utils';
-export const ReplaceMediaButton = ({ onSelectMedia, acceptedMime, ...props }) => {
+export const ReplaceMediaButton = ({ onSelectMedia, acceptedMime, trackedLocation, ...props }) => {
const { formatMessage } = useIntl();
const inputRef = useRef(null);
+ const { trackUsage } = useTracking();
const handleClick = e => {
e.preventDefault();
+
+ if (trackedLocation) {
+ trackUsage('didReplaceMedia', { location: trackedLocation });
+ }
+
inputRef.current.click();
};
@@ -43,7 +50,12 @@ export const ReplaceMediaButton = ({ onSelectMedia, acceptedMime, ...props }) =>
);
};
+ReplaceMediaButton.defaultProps = {
+ trackedLocation: undefined,
+};
+
ReplaceMediaButton.propTypes = {
acceptedMime: PropTypes.string.isRequired,
onSelectMedia: PropTypes.func.isRequired,
+ trackedLocation: PropTypes.string,
};
diff --git a/packages/core/upload/admin/src/components/EditAssetDialog/index.js b/packages/core/upload/admin/src/components/EditAssetDialog/index.js
index e5f4f41b27..f56f710e28 100644
--- a/packages/core/upload/admin/src/components/EditAssetDialog/index.js
+++ b/packages/core/upload/admin/src/components/EditAssetDialog/index.js
@@ -36,7 +36,14 @@ const fileInfoSchema = yup.object({
caption: yup.string(),
});
-export const EditAssetDialog = ({ onClose, asset, canUpdate, canCopyLink, canDownload }) => {
+export const EditAssetDialog = ({
+ onClose,
+ asset,
+ canUpdate,
+ canCopyLink,
+ canDownload,
+ trackedLocation,
+}) => {
const { formatMessage, formatDate } = useIntl();
const submitButtonRef = useRef(null);
const [isCropping, setIsCropping] = useState(false);
@@ -183,6 +190,7 @@ export const EditAssetDialog = ({ onClose, asset, canUpdate, canCopyLink, canDow
onSelectMedia={setReplacementFile}
acceptedMime={asset.mime}
disabled={formDisabled}
+ trackedLocation={trackedLocation}
/>
-
+
-
+
@@ -62,7 +70,12 @@ export const AddAssetStep = ({ onClose, onAddAsset }) => {
);
};
+AddAssetStep.defaultProps = {
+ trackedLocation: undefined,
+};
+
AddAssetStep.propTypes = {
onClose: PropTypes.func.isRequired,
onAddAsset: PropTypes.func.isRequired,
+ trackedLocation: PropTypes.string,
};
diff --git a/packages/core/upload/admin/src/components/UploadAssetDialog/AddAssetStep/FromComputerForm.js b/packages/core/upload/admin/src/components/UploadAssetDialog/AddAssetStep/FromComputerForm.js
index 41ff7f50b1..277c6e89f5 100644
--- a/packages/core/upload/admin/src/components/UploadAssetDialog/AddAssetStep/FromComputerForm.js
+++ b/packages/core/upload/admin/src/components/UploadAssetDialog/AddAssetStep/FromComputerForm.js
@@ -5,6 +5,7 @@ import styled from 'styled-components';
import { Box } from '@strapi/design-system/Box';
import { Flex } from '@strapi/design-system/Flex';
import { H3 } from '@strapi/design-system/Text';
+import { useTracking } from '@strapi/helper-plugin';
import { ModalFooter } from '@strapi/design-system/ModalLayout';
import { Button } from '@strapi/design-system/Button';
import PicturePlus from '@strapi/icons/PicturePlus';
@@ -34,10 +35,11 @@ const OpaqueBox = styled(Box)`
cursor: pointer;
`;
-export const FromComputerForm = ({ onClose, onAddAssets }) => {
+export const FromComputerForm = ({ onClose, onAddAssets, trackedLocation }) => {
const { formatMessage } = useIntl();
const [dragOver, setDragOver] = useState(false);
const inputRef = useRef(null);
+ const { trackUsage } = useTracking();
const handleDragEnter = () => setDragOver(true);
const handleDragLeave = () => setDragOver(false);
@@ -58,6 +60,10 @@ export const FromComputerForm = ({ onClose, onAddAssets }) => {
assets.push(asset);
}
+ if (trackedLocation) {
+ trackUsage('didSelectFile', { source: 'computer', location: trackedLocation });
+ }
+
onAddAssets(assets);
};
@@ -136,7 +142,12 @@ export const FromComputerForm = ({ onClose, onAddAssets }) => {
);
};
+FromComputerForm.defaultProps = {
+ trackedLocation: undefined,
+};
+
FromComputerForm.propTypes = {
onClose: PropTypes.func.isRequired,
onAddAssets: PropTypes.func.isRequired,
+ trackedLocation: PropTypes.string,
};
diff --git a/packages/core/upload/admin/src/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js b/packages/core/upload/admin/src/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js
index 2a3a00b336..b6ba6d022b 100644
--- a/packages/core/upload/admin/src/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js
+++ b/packages/core/upload/admin/src/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js
@@ -5,16 +5,17 @@ import { ModalFooter } from '@strapi/design-system/ModalLayout';
import { Textarea } from '@strapi/design-system/Textarea';
import { useIntl } from 'react-intl';
import { Button } from '@strapi/design-system/Button';
-import { Form } from '@strapi/helper-plugin';
+import { Form, useTracking } from '@strapi/helper-plugin';
import { Formik } from 'formik';
import getTrad from '../../../utils/getTrad';
import { urlSchema } from '../../../utils/urlYupSchema';
import { urlsToAssets } from '../../../utils/urlsToAssets';
-export const FromUrlForm = ({ onClose, onAddAsset }) => {
+export const FromUrlForm = ({ onClose, onAddAsset, trackedLocation }) => {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(undefined);
const { formatMessage } = useIntl();
+ const { trackUsage } = useTracking();
const handleSubmit = async ({ urls }) => {
setLoading(true);
@@ -22,6 +23,10 @@ export const FromUrlForm = ({ onClose, onAddAsset }) => {
try {
const assets = await urlsToAssets(urlArray);
+ if (trackedLocation) {
+ trackUsage('didSelectFile', { source: 'url', location: trackedLocation });
+ }
+
// no need to set the loading to false since the component unmounts
onAddAsset(assets);
} catch (e) {
@@ -83,7 +88,12 @@ export const FromUrlForm = ({ onClose, onAddAsset }) => {
);
};
+FromUrlForm.defaultProps = {
+ trackedLocation: undefined,
+};
+
FromUrlForm.propTypes = {
onClose: PropTypes.func.isRequired,
onAddAsset: PropTypes.func.isRequired,
+ trackedLocation: PropTypes.string,
};
diff --git a/packages/core/upload/admin/src/components/UploadAssetDialog/AddAssetStep/tests/FromComputerForm.test.js b/packages/core/upload/admin/src/components/UploadAssetDialog/AddAssetStep/tests/FromComputerForm.test.js
index 427c8391cd..fbd1521ea8 100644
--- a/packages/core/upload/admin/src/components/UploadAssetDialog/AddAssetStep/tests/FromComputerForm.test.js
+++ b/packages/core/upload/admin/src/components/UploadAssetDialog/AddAssetStep/tests/FromComputerForm.test.js
@@ -106,55 +106,6 @@ describe('FromComputerForm', () => {
color: #666687;
}
- .c16 {
- background: #f6f6f9;
- padding-top: 16px;
- padding-right: 20px;
- padding-bottom: 16px;
- padding-left: 20px;
- }
-
- .c18 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: justify;
- -webkit-justify-content: space-between;
- -ms-flex-pack: justify;
- justify-content: space-between;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- }
-
- .c19 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- }
-
- .c17 {
- border-radius: 0 0 4px 4px;
- border-top: 1px solid #eaeaef;
- }
-
- .c20 > * + * {
- margin-left: 8px;
- }
-
.c15 {
font-weight: 600;
color: #32324d;
@@ -232,7 +183,7 @@ describe('FromComputerForm', () => {
background: #4945ff;
}
- .c13 .sc-jcRCNh {
+ .c13 .sc-gfaqzF {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
@@ -297,7 +248,7 @@ describe('FromComputerForm', () => {
background: #ffffff;
}
- .c21 .sc-jcRCNh {
+ .c21 .sc-gfaqzF {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
@@ -357,6 +308,55 @@ describe('FromComputerForm', () => {
fill: #32324d;
}
+ .c16 {
+ background: #f6f6f9;
+ padding-top: 16px;
+ padding-right: 20px;
+ padding-bottom: 16px;
+ padding-left: 20px;
+ }
+
+ .c18 {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-direction: row;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-pack: justify;
+ -webkit-justify-content: space-between;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ }
+
+ .c19 {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-direction: row;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ }
+
+ .c17 {
+ border-radius: 0 0 4px 4px;
+ border-top: 1px solid #eaeaef;
+ }
+
+ .c20 > * + * {
+ margin-left: 8px;
+ }
+
.c5 {
-webkit-flex-direction: column;
-ms-flex-direction: column;
diff --git a/packages/core/upload/admin/src/components/UploadAssetDialog/UploadAssetDialog.js b/packages/core/upload/admin/src/components/UploadAssetDialog/UploadAssetDialog.js
index c3261bab91..34da33e767 100644
--- a/packages/core/upload/admin/src/components/UploadAssetDialog/UploadAssetDialog.js
+++ b/packages/core/upload/admin/src/components/UploadAssetDialog/UploadAssetDialog.js
@@ -10,7 +10,12 @@ const Steps = {
PendingAsset: 'PendingAsset',
};
-export const UploadAssetDialog = ({ initialAssetsToAdd, onClose, addUploadedFiles }) => {
+export const UploadAssetDialog = ({
+ initialAssetsToAdd,
+ onClose,
+ addUploadedFiles,
+ trackedLocation,
+}) => {
const [step, setStep] = useState(initialAssetsToAdd ? Steps.PendingAsset : Steps.AddAsset);
const [assets, setAssets] = useState(initialAssetsToAdd || []);
@@ -45,7 +50,11 @@ export const UploadAssetDialog = ({ initialAssetsToAdd, onClose, addUploadedFile
return (
{step === Steps.AddAsset && (
-
+
)}
{step === Steps.PendingAsset && (
{
- {showUploadAssetDialog && }
+ {showUploadAssetDialog && (
+
+ )}
{assetToEdit && (
setAssetToEdit(undefined)}
@@ -206,6 +208,7 @@ export const MediaLibrary = () => {
canUpdate={canUpdate}
canCopyLink={canCopyLink}
canDownload={canDownload}
+ trackedLocation="upload"
/>
)}