mirror of
https://github.com/strapi/strapi.git
synced 2025-08-05 07:16:02 +00:00
commit
b356766f1c
@ -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 }
|
||||||
|
@ -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}
|
||||||
|
@ -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;
|
||||||
});
|
});
|
||||||
|
@ -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',
|
||||||
|
@ -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}>
|
||||||
|
@ -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');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
@ -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"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
@ -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>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user