Merge pull request #11543 from strapi/v4/tracking

[V4] Tracking
This commit is contained in:
cyril lopez 2021-11-15 14:06:38 +01:00 committed by GitHub
commit b356766f1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 187 additions and 85 deletions

View File

@ -51,7 +51,7 @@ const TableRows = ({
key={data.id} key={data.id}
{...onRowClick({ {...onRowClick({
fn: () => { fn: () => {
trackUsage('willEditEntryFromButton'); trackUsage('willEditEntryFromList');
push({ push({
pathname: `${pathname}/${data.id}`, pathname: `${pathname}/${data.id}`,
state: { from: pathname }, state: { from: pathname },
@ -141,7 +141,11 @@ const TableRows = ({
{canDelete && ( {canDelete && (
<Box paddingLeft={1}> <Box paddingLeft={1}>
<IconButton <IconButton
onClick={() => onClickDelete(data.id)} onClick={() => {
trackUsage('willDeleteEntryFromList');
onClickDelete(data.id);
}}
label={formatMessage( label={formatMessage(
{ id: 'app.component.table.delete', defaultMessage: 'Delete {target}' }, { id: 'app.component.table.delete', defaultMessage: 'Delete {target}' },
{ target: itemLineText } { target: itemLineText }

View File

@ -81,6 +81,7 @@ const DynamicTable = ({
headers={tableHeaders} headers={tableHeaders}
onConfirmDelete={onConfirmDelete} onConfirmDelete={onConfirmDelete}
onConfirmDeleteAll={onConfirmDeleteAll} onConfirmDeleteAll={onConfirmDeleteAll}
onOpenDeleteAllModalTrackedEvent="willBulkDeleteEntries"
rows={rows} rows={rows}
withBulkActions withBulkActions
withMainAction={canDelete && isBulkable} withMainAction={canDelete && isBulkable}

View File

@ -26,6 +26,8 @@ const FieldPicker = ({ layout }) => {
const values = displayedHeaders.map(({ name }) => name); const values = displayedHeaders.map(({ name }) => name);
const handleChange = updatedValues => { const handleChange = updatedValues => {
trackUsage('didChangeDisplayedFields');
// removing a header // removing a header
if (updatedValues.length < values.length) { if (updatedValues.length < values.length) {
const removedHeader = values.filter(value => { const removedHeader = values.filter(value => {
@ -34,7 +36,6 @@ const FieldPicker = ({ layout }) => {
dispatch(onChangeListHeaders({ name: removedHeader[0], value: true })); dispatch(onChangeListHeaders({ name: removedHeader[0], value: true }));
} else { } else {
trackUsage('didChangeDisplayedFields');
const addedHeader = updatedValues.filter(value => { const addedHeader = updatedValues.filter(value => {
return values.indexOf(value) === -1; return values.indexOf(value) === -1;
}); });

View File

@ -7,7 +7,6 @@ import { bindActionCreators, compose } from 'redux';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
import { useHistory, useLocation } from 'react-router-dom'; import { useHistory, useLocation } from 'react-router-dom';
import get from 'lodash/get'; import get from 'lodash/get';
import isEmpty from 'lodash/isEmpty';
import { stringify } from 'qs'; import { stringify } from 'qs';
import { import {
NoPermissions, NoPermissions,
@ -171,18 +170,6 @@ function ListView({
const handleConfirmDeleteData = useCallback( const handleConfirmDeleteData = useCallback(
async idToDelete => { async idToDelete => {
try { 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}`)); await axiosInstance.delete(getRequestUrl(`collection-types/${slug}/${idToDelete}`));
const requestUrl = getRequestUrl(`collection-types/${slug}${params}`); const requestUrl = getRequestUrl(`collection-types/${slug}${params}`);
@ -192,8 +179,6 @@ function ListView({
type: 'success', type: 'success',
message: { id: getTrad('success.record.delete') }, message: { id: getTrad('success.record.delete') },
}); });
trackUsageRef.current('didDeleteEntry', trackerProperty);
} catch (err) { } catch (err) {
const errorMessage = get( const errorMessage = get(
err, err,
@ -207,7 +192,7 @@ function ListView({
}); });
} }
}, },
[hasDraftAndPublish, slug, params, fetchData, toggleNotification, data, formatMessage] [slug, params, fetchData, toggleNotification, formatMessage]
); );
useEffect(() => { useEffect(() => {
@ -282,8 +267,11 @@ function ListView({
<FieldPicker layout={layout} /> <FieldPicker layout={layout} />
<CheckPermissions permissions={cmPermissions.collectionTypesConfigurations}> <CheckPermissions permissions={cmPermissions.collectionTypesConfigurations}>
<IconButtonCustom <IconButtonCustom
onClick={() => onClick={() => {
push({ pathname: `${slug}/configurations/list`, search: pluginsQueryParams })} trackUsage('willEditListLayout');
push({ pathname: `${slug}/configurations/list`, search: pluginsQueryParams });
}}
icon={<Cog />} icon={<Cog />}
label={formatMessage({ label={formatMessage({
id: 'app.links.configure-view', id: 'app.links.configure-view',

View File

@ -1,8 +1,8 @@
import React from 'react'; import React, { useEffect } from 'react';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
import styled from 'styled-components'; import styled from 'styled-components';
import { Helmet } from 'react-helmet'; 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 { Layout, HeaderLayout, ContentLayout } from '@strapi/design-system/Layout';
import { Flex } from '@strapi/design-system/Flex'; import { Flex } from '@strapi/design-system/Flex';
import { Box } from '@strapi/design-system/Box'; import { Box } from '@strapi/design-system/Box';
@ -27,6 +27,11 @@ const StackCentered = styled(Stack)`
const MarketPlacePage = () => { const MarketPlacePage = () => {
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
const { trackUsage } = useTracking();
useEffect(() => {
trackUsage('didGoToMarketplace');
}, [trackUsage]);
return ( return (
<CheckPagePermissions permissions={adminPermissions.marketplace.main}> <CheckPagePermissions permissions={adminPermissions.marketplace.main}>

View File

@ -2,11 +2,13 @@ import React from 'react';
import { render } from '@testing-library/react'; import { render } from '@testing-library/react';
import { IntlProvider } from 'react-intl'; import { IntlProvider } from 'react-intl';
import { ThemeProvider, lightTheme } from '@strapi/design-system'; import { ThemeProvider, lightTheme } from '@strapi/design-system';
import { useTracking } from '@strapi/helper-plugin';
import MarketPlacePage from '../index'; import MarketPlacePage from '../index';
jest.mock('@strapi/helper-plugin', () => ({ jest.mock('@strapi/helper-plugin', () => ({
pxToRem: jest.fn(), pxToRem: jest.fn(),
CheckPagePermissions: ({ children }) => children, CheckPagePermissions: ({ children }) => children,
useTracking: jest.fn(() => ({ trackUsage: jest.fn() })),
})); }));
const App = ( const App = (
@ -440,4 +442,12 @@ describe('Marketplace coming soon', () => {
</div> </div>
`); `);
}); });
it('sends an event when the user enters the marketplace', () => {
const trackUsage = jest.fn();
useTracking.mockImplementation(() => ({ trackUsage }));
render(App);
expect(trackUsage).toHaveBeenCalledWith('didGoToMarketplace');
});
}); });

View File

@ -9,6 +9,7 @@ import { useIntl } from 'react-intl';
import Trash from '@strapi/icons/Trash'; import Trash from '@strapi/icons/Trash';
import styled from 'styled-components'; import styled from 'styled-components';
import useQueryParams from '../../hooks/useQueryParams'; import useQueryParams from '../../hooks/useQueryParams';
import useTracking from '../../hooks/useTracking';
import ConfirmDialog from '../ConfirmDialog'; import ConfirmDialog from '../ConfirmDialog';
import EmptyBodyTable from '../EmptyBodyTable'; import EmptyBodyTable from '../EmptyBodyTable';
import TableHead from './TableHead'; import TableHead from './TableHead';
@ -29,6 +30,7 @@ const Table = ({
isLoading, isLoading,
onConfirmDeleteAll, onConfirmDeleteAll,
onConfirmDelete, onConfirmDelete,
onOpenDeleteAllModalTrackedEvent,
rows, rows,
withBulkActions, withBulkActions,
withMainAction, withMainAction,
@ -40,6 +42,7 @@ const Table = ({
const [isConfirmButtonLoading, setIsConfirmButtonLoading] = useState(false); const [isConfirmButtonLoading, setIsConfirmButtonLoading] = useState(false);
const [{ query }] = useQueryParams(); const [{ query }] = useQueryParams();
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
const { trackUsage } = useTracking();
const ROW_COUNT = rows.length + 1; const ROW_COUNT = rows.length + 1;
const COL_COUNT = headers.length + (withBulkActions ? 1 : 0) + (withMainAction ? 1 : 0); const COL_COUNT = headers.length + (withBulkActions ? 1 : 0) + (withMainAction ? 1 : 0);
const hasFilters = query?.filters !== undefined; const hasFilters = query?.filters !== undefined;
@ -88,6 +91,10 @@ const Table = ({
}; };
const handleToggleConfirmDeleteAll = () => { const handleToggleConfirmDeleteAll = () => {
if (!showConfirmDeleteAll && onOpenDeleteAllModalTrackedEvent) {
trackUsage(onOpenDeleteAllModalTrackedEvent);
}
setShowConfirmDeleteAll(prev => !prev); setShowConfirmDeleteAll(prev => !prev);
}; };
@ -203,6 +210,7 @@ Table.defaultProps = {
isLoading: false, isLoading: false,
onConfirmDeleteAll: () => {}, onConfirmDeleteAll: () => {},
onConfirmDelete: () => {}, onConfirmDelete: () => {},
onOpenDeleteAllModalTrackedEvent: undefined,
rows: [], rows: [],
withBulkActions: false, withBulkActions: false,
withMainAction: false, withMainAction: false,
@ -229,6 +237,7 @@ Table.propTypes = {
isLoading: PropTypes.bool, isLoading: PropTypes.bool,
onConfirmDeleteAll: PropTypes.func, onConfirmDeleteAll: PropTypes.func,
onConfirmDelete: PropTypes.func, onConfirmDelete: PropTypes.func,
onOpenDeleteAllModalTrackedEvent: PropTypes.string,
rows: PropTypes.array, rows: PropTypes.array,
withBulkActions: PropTypes.bool, withBulkActions: PropTypes.bool,
withMainAction: PropTypes.bool, withMainAction: PropTypes.bool,

View File

@ -29,6 +29,7 @@ export const AssetDialog = ({
onValidate, onValidate,
multiple, multiple,
initiallySelectedAssets, initiallySelectedAssets,
trackedLocation,
}) => { }) => {
const [assetToEdit, setAssetToEdit] = useState(undefined); const [assetToEdit, setAssetToEdit] = useState(undefined);
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
@ -153,6 +154,7 @@ export const AssetDialog = ({
canUpdate={canUpdate} canUpdate={canUpdate}
canCopyLink={canCopyLink} canCopyLink={canCopyLink}
canDownload={canDownload} canDownload={canDownload}
trackedLocation={trackedLocation}
/> />
); );
} }
@ -232,6 +234,7 @@ AssetDialog.defaultProps = {
allowedTypes: [], allowedTypes: [],
initiallySelectedAssets: [], initiallySelectedAssets: [],
multiple: false, multiple: false,
trackedLocation: undefined,
}; };
AssetDialog.propTypes = { AssetDialog.propTypes = {
@ -241,4 +244,5 @@ AssetDialog.propTypes = {
onAddAsset: PropTypes.func.isRequired, onAddAsset: PropTypes.func.isRequired,
onClose: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired,
onValidate: PropTypes.func.isRequired, onValidate: PropTypes.func.isRequired,
trackedLocation: PropTypes.string,
}; };

View File

@ -1,16 +1,23 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { useRef } from 'react'; import React, { useRef } from 'react';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
import { useTracking } from '@strapi/helper-plugin';
import { Button } from '@strapi/design-system/Button'; import { Button } from '@strapi/design-system/Button';
import { VisuallyHidden } from '@strapi/design-system/VisuallyHidden'; import { VisuallyHidden } from '@strapi/design-system/VisuallyHidden';
import { getTrad } from '../../utils'; import { getTrad } from '../../utils';
export const ReplaceMediaButton = ({ onSelectMedia, acceptedMime, ...props }) => { export const ReplaceMediaButton = ({ onSelectMedia, acceptedMime, trackedLocation, ...props }) => {
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
const inputRef = useRef(null); const inputRef = useRef(null);
const { trackUsage } = useTracking();
const handleClick = e => { const handleClick = e => {
e.preventDefault(); e.preventDefault();
if (trackedLocation) {
trackUsage('didReplaceMedia', { location: trackedLocation });
}
inputRef.current.click(); inputRef.current.click();
}; };
@ -43,7 +50,12 @@ export const ReplaceMediaButton = ({ onSelectMedia, acceptedMime, ...props }) =>
); );
}; };
ReplaceMediaButton.defaultProps = {
trackedLocation: undefined,
};
ReplaceMediaButton.propTypes = { ReplaceMediaButton.propTypes = {
acceptedMime: PropTypes.string.isRequired, acceptedMime: PropTypes.string.isRequired,
onSelectMedia: PropTypes.func.isRequired, onSelectMedia: PropTypes.func.isRequired,
trackedLocation: PropTypes.string,
}; };

View File

@ -36,7 +36,14 @@ const fileInfoSchema = yup.object({
caption: yup.string(), 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 { formatMessage, formatDate } = useIntl();
const submitButtonRef = useRef(null); const submitButtonRef = useRef(null);
const [isCropping, setIsCropping] = useState(false); const [isCropping, setIsCropping] = useState(false);
@ -183,6 +190,7 @@ export const EditAssetDialog = ({ onClose, asset, canUpdate, canCopyLink, canDow
onSelectMedia={setReplacementFile} onSelectMedia={setReplacementFile}
acceptedMime={asset.mime} acceptedMime={asset.mime}
disabled={formDisabled} disabled={formDisabled}
trackedLocation={trackedLocation}
/> />
<Button <Button
@ -200,10 +208,15 @@ export const EditAssetDialog = ({ onClose, asset, canUpdate, canCopyLink, canDow
); );
}; };
EditAssetDialog.defaultProps = {
trackedLocation: undefined,
};
EditAssetDialog.propTypes = { EditAssetDialog.propTypes = {
asset: AssetDefinition.isRequired, asset: AssetDefinition.isRequired,
canUpdate: PropTypes.bool.isRequired, canUpdate: PropTypes.bool.isRequired,
canCopyLink: PropTypes.bool.isRequired, canCopyLink: PropTypes.bool.isRequired,
canDownload: PropTypes.bool.isRequired, canDownload: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired,
trackedLocation: PropTypes.string,
}; };

View File

@ -23,6 +23,7 @@ export const CarouselAssets = ({
onNext, onNext,
onPrevious, onPrevious,
selectedAssetIndex, selectedAssetIndex,
trackedLocation,
}) => { }) => {
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
const [isEditingAsset, setIsEditingAsset] = useState(false); const [isEditingAsset, setIsEditingAsset] = useState(false);
@ -105,6 +106,7 @@ export const CarouselAssets = ({
canUpdate canUpdate
canCopyLink canCopyLink
canDownload canDownload
trackedLocation={trackedLocation}
/> />
)} )}
</> </>
@ -116,6 +118,7 @@ CarouselAssets.defaultProps = {
error: undefined, error: undefined,
hint: undefined, hint: undefined,
onDropAsset: undefined, onDropAsset: undefined,
trackedLocation: undefined,
}; };
CarouselAssets.propTypes = { CarouselAssets.propTypes = {
@ -132,4 +135,5 @@ CarouselAssets.propTypes = {
onNext: PropTypes.func.isRequired, onNext: PropTypes.func.isRequired,
onPrevious: PropTypes.func.isRequired, onPrevious: PropTypes.func.isRequired,
selectedAssetIndex: PropTypes.number.isRequired, selectedAssetIndex: PropTypes.number.isRequired,
trackedLocation: PropTypes.string,
}; };

View File

@ -150,6 +150,7 @@ export const MediaLibraryInput = ({
error={errorMessage} error={errorMessage}
hint={hint} hint={hint}
selectedAssetIndex={selectedIndex} selectedAssetIndex={selectedIndex}
trackedLocation="content-manager"
/> />
{step === Steps.SelectAsset && ( {step === Steps.SelectAsset && (
@ -160,6 +161,7 @@ export const MediaLibraryInput = ({
onValidate={handleValidation} onValidate={handleValidation}
multiple={multiple} multiple={multiple}
onAddAsset={() => setStep(Steps.UploadAsset)} onAddAsset={() => setStep(Steps.UploadAsset)}
trackedLocation="content-manager"
/> />
)} )}
@ -168,6 +170,7 @@ export const MediaLibraryInput = ({
onClose={() => setStep(Steps.SelectAsset)} onClose={() => setStep(Steps.SelectAsset)}
initialAssetsToAdd={droppedAssets} initialAssetsToAdd={droppedAssets}
addUploadedFiles={handleFilesUploadSucceeded} addUploadedFiles={handleFilesUploadSucceeded}
trackedLocation="content-manager"
/> />
)} )}
</> </>

View File

@ -10,7 +10,7 @@ import { FromUrlForm } from './FromUrlForm';
import { FromComputerForm } from './FromComputerForm'; import { FromComputerForm } from './FromComputerForm';
import getTrad from '../../../utils/getTrad'; import getTrad from '../../../utils/getTrad';
export const AddAssetStep = ({ onClose, onAddAsset }) => { export const AddAssetStep = ({ onClose, onAddAsset, trackedLocation }) => {
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
return ( return (
@ -51,10 +51,18 @@ export const AddAssetStep = ({ onClose, onAddAsset }) => {
</Box> </Box>
<TabPanels> <TabPanels>
<TabPanel> <TabPanel>
<FromComputerForm onClose={onClose} onAddAssets={onAddAsset} /> <FromComputerForm
onClose={onClose}
onAddAssets={onAddAsset}
trackedLocation={trackedLocation}
/>
</TabPanel> </TabPanel>
<TabPanel> <TabPanel>
<FromUrlForm onClose={onClose} onAddAsset={onAddAsset} /> <FromUrlForm
onClose={onClose}
onAddAsset={onAddAsset}
trackedLocation={trackedLocation}
/>
</TabPanel> </TabPanel>
</TabPanels> </TabPanels>
</TabGroup> </TabGroup>
@ -62,7 +70,12 @@ export const AddAssetStep = ({ onClose, onAddAsset }) => {
); );
}; };
AddAssetStep.defaultProps = {
trackedLocation: undefined,
};
AddAssetStep.propTypes = { AddAssetStep.propTypes = {
onClose: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired,
onAddAsset: PropTypes.func.isRequired, onAddAsset: PropTypes.func.isRequired,
trackedLocation: PropTypes.string,
}; };

View File

@ -5,6 +5,7 @@ import styled from 'styled-components';
import { Box } from '@strapi/design-system/Box'; import { Box } from '@strapi/design-system/Box';
import { Flex } from '@strapi/design-system/Flex'; import { Flex } from '@strapi/design-system/Flex';
import { H3 } from '@strapi/design-system/Text'; import { H3 } from '@strapi/design-system/Text';
import { useTracking } from '@strapi/helper-plugin';
import { ModalFooter } from '@strapi/design-system/ModalLayout'; import { ModalFooter } from '@strapi/design-system/ModalLayout';
import { Button } from '@strapi/design-system/Button'; import { Button } from '@strapi/design-system/Button';
import PicturePlus from '@strapi/icons/PicturePlus'; import PicturePlus from '@strapi/icons/PicturePlus';
@ -34,10 +35,11 @@ const OpaqueBox = styled(Box)`
cursor: pointer; cursor: pointer;
`; `;
export const FromComputerForm = ({ onClose, onAddAssets }) => { export const FromComputerForm = ({ onClose, onAddAssets, trackedLocation }) => {
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
const [dragOver, setDragOver] = useState(false); const [dragOver, setDragOver] = useState(false);
const inputRef = useRef(null); const inputRef = useRef(null);
const { trackUsage } = useTracking();
const handleDragEnter = () => setDragOver(true); const handleDragEnter = () => setDragOver(true);
const handleDragLeave = () => setDragOver(false); const handleDragLeave = () => setDragOver(false);
@ -58,6 +60,10 @@ export const FromComputerForm = ({ onClose, onAddAssets }) => {
assets.push(asset); assets.push(asset);
} }
if (trackedLocation) {
trackUsage('didSelectFile', { source: 'computer', location: trackedLocation });
}
onAddAssets(assets); onAddAssets(assets);
}; };
@ -136,7 +142,12 @@ export const FromComputerForm = ({ onClose, onAddAssets }) => {
); );
}; };
FromComputerForm.defaultProps = {
trackedLocation: undefined,
};
FromComputerForm.propTypes = { FromComputerForm.propTypes = {
onClose: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired,
onAddAssets: PropTypes.func.isRequired, onAddAssets: PropTypes.func.isRequired,
trackedLocation: PropTypes.string,
}; };

View File

@ -5,16 +5,17 @@ import { ModalFooter } from '@strapi/design-system/ModalLayout';
import { Textarea } from '@strapi/design-system/Textarea'; import { Textarea } from '@strapi/design-system/Textarea';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
import { Button } from '@strapi/design-system/Button'; 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 { Formik } from 'formik';
import getTrad from '../../../utils/getTrad'; import getTrad from '../../../utils/getTrad';
import { urlSchema } from '../../../utils/urlYupSchema'; import { urlSchema } from '../../../utils/urlYupSchema';
import { urlsToAssets } from '../../../utils/urlsToAssets'; import { urlsToAssets } from '../../../utils/urlsToAssets';
export const FromUrlForm = ({ onClose, onAddAsset }) => { export const FromUrlForm = ({ onClose, onAddAsset, trackedLocation }) => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [error, setError] = useState(undefined); const [error, setError] = useState(undefined);
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
const { trackUsage } = useTracking();
const handleSubmit = async ({ urls }) => { const handleSubmit = async ({ urls }) => {
setLoading(true); setLoading(true);
@ -22,6 +23,10 @@ export const FromUrlForm = ({ onClose, onAddAsset }) => {
try { try {
const assets = await urlsToAssets(urlArray); 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 // no need to set the loading to false since the component unmounts
onAddAsset(assets); onAddAsset(assets);
} catch (e) { } catch (e) {
@ -83,7 +88,12 @@ export const FromUrlForm = ({ onClose, onAddAsset }) => {
); );
}; };
FromUrlForm.defaultProps = {
trackedLocation: undefined,
};
FromUrlForm.propTypes = { FromUrlForm.propTypes = {
onClose: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired,
onAddAsset: PropTypes.func.isRequired, onAddAsset: PropTypes.func.isRequired,
trackedLocation: PropTypes.string,
}; };

View File

@ -106,55 +106,6 @@ describe('FromComputerForm', () => {
color: #666687; 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 { .c15 {
font-weight: 600; font-weight: 600;
color: #32324d; color: #32324d;
@ -232,7 +183,7 @@ describe('FromComputerForm', () => {
background: #4945ff; background: #4945ff;
} }
.c13 .sc-jcRCNh { .c13 .sc-gfaqzF {
display: -webkit-box; display: -webkit-box;
display: -webkit-flex; display: -webkit-flex;
display: -ms-flexbox; display: -ms-flexbox;
@ -297,7 +248,7 @@ describe('FromComputerForm', () => {
background: #ffffff; background: #ffffff;
} }
.c21 .sc-jcRCNh { .c21 .sc-gfaqzF {
display: -webkit-box; display: -webkit-box;
display: -webkit-flex; display: -webkit-flex;
display: -ms-flexbox; display: -ms-flexbox;
@ -357,6 +308,55 @@ describe('FromComputerForm', () => {
fill: #32324d; 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 { .c5 {
-webkit-flex-direction: column; -webkit-flex-direction: column;
-ms-flex-direction: column; -ms-flex-direction: column;

View File

@ -10,7 +10,12 @@ const Steps = {
PendingAsset: 'PendingAsset', 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 [step, setStep] = useState(initialAssetsToAdd ? Steps.PendingAsset : Steps.AddAsset);
const [assets, setAssets] = useState(initialAssetsToAdd || []); const [assets, setAssets] = useState(initialAssetsToAdd || []);
@ -45,7 +50,11 @@ export const UploadAssetDialog = ({ initialAssetsToAdd, onClose, addUploadedFile
return ( return (
<ModalLayout onClose={onClose} labelledBy="title"> <ModalLayout onClose={onClose} labelledBy="title">
{step === Steps.AddAsset && ( {step === Steps.AddAsset && (
<AddAssetStep onClose={onClose} onAddAsset={handleAddToPendingAssets} /> <AddAssetStep
onClose={onClose}
onAddAsset={handleAddToPendingAssets}
trackedLocation={trackedLocation}
/>
)} )}
{step === Steps.PendingAsset && ( {step === Steps.PendingAsset && (
<PendingAssetStep <PendingAssetStep
@ -65,10 +74,12 @@ export const UploadAssetDialog = ({ initialAssetsToAdd, onClose, addUploadedFile
UploadAssetDialog.defaultProps = { UploadAssetDialog.defaultProps = {
addUploadedFiles: undefined, addUploadedFiles: undefined,
initialAssetsToAdd: undefined, initialAssetsToAdd: undefined,
trackedLocation: undefined,
}; };
UploadAssetDialog.propTypes = { UploadAssetDialog.propTypes = {
addUploadedFiles: PropTypes.func, addUploadedFiles: PropTypes.func,
initialAssetsToAdd: PropTypes.arrayOf(AssetDefinition), initialAssetsToAdd: PropTypes.arrayOf(AssetDefinition),
onClose: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired,
trackedLocation: PropTypes.string,
}; };

View File

@ -198,7 +198,9 @@ export const MediaLibrary = () => {
</ContentLayout> </ContentLayout>
</Main> </Main>
{showUploadAssetDialog && <UploadAssetDialog onClose={toggleUploadAssetDialog} />} {showUploadAssetDialog && (
<UploadAssetDialog onClose={toggleUploadAssetDialog} trackedLocation="upload" />
)}
{assetToEdit && ( {assetToEdit && (
<EditAssetDialog <EditAssetDialog
onClose={() => setAssetToEdit(undefined)} onClose={() => setAssetToEdit(undefined)}
@ -206,6 +208,7 @@ export const MediaLibrary = () => {
canUpdate={canUpdate} canUpdate={canUpdate}
canCopyLink={canCopyLink} canCopyLink={canCopyLink}
canDownload={canDownload} canDownload={canDownload}
trackedLocation="upload"
/> />
)} )}
</Layout> </Layout>