mirror of
https://github.com/strapi/strapi.git
synced 2025-09-25 16:29:34 +00:00
Merge pull request #15837 from strapi/data-transfer/tracking-api-token-transfer-token
This commit is contained in:
commit
3d6a31eb08
@ -5,13 +5,15 @@ import { useTracking, ConfirmDialog } from '@strapi/helper-plugin';
|
||||
import { useIntl } from 'react-intl';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const DeleteButton = ({ tokenName, onClickDelete }) => {
|
||||
const DeleteButton = ({ tokenName, onClickDelete, tokenType }) => {
|
||||
const { formatMessage } = useIntl();
|
||||
const { trackUsage } = useTracking(); // TODO: Track different types of tokens
|
||||
const { trackUsage } = useTracking();
|
||||
const [showConfirmDialog, setShowConfirmDialog] = useState(false);
|
||||
const handleClickDelete = () => {
|
||||
setShowConfirmDialog(false);
|
||||
trackUsage('willDeleteToken');
|
||||
trackUsage('willDeleteToken', {
|
||||
tokenType,
|
||||
});
|
||||
onClickDelete();
|
||||
};
|
||||
|
||||
@ -44,6 +46,7 @@ const DeleteButton = ({ tokenName, onClickDelete }) => {
|
||||
DeleteButton.propTypes = {
|
||||
tokenName: PropTypes.string.isRequired,
|
||||
onClickDelete: PropTypes.func.isRequired,
|
||||
tokenType: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default DeleteButton;
|
||||
|
@ -16,7 +16,12 @@ function ComponentToTest(props) {
|
||||
<IntlProvider locale="en" messages={{}}>
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<NotificationsProvider toggleNotification={() => {}}>
|
||||
<DeleteButton tokenName="test" onClickDelete={() => {}} {...props} />
|
||||
<DeleteButton
|
||||
tokenType="api-token"
|
||||
tokenName="test"
|
||||
onClickDelete={() => {}}
|
||||
{...props}
|
||||
/>
|
||||
</NotificationsProvider>
|
||||
</ThemeProvider>
|
||||
</IntlProvider>
|
||||
|
@ -14,7 +14,15 @@ import DeleteButton from './DeleteButton';
|
||||
import UpdateButton from './UpdateButton';
|
||||
import ReadButton from './ReadButton';
|
||||
|
||||
const Table = ({ permissions, headers, contentType, isLoading, tokens, onConfirmDelete }) => {
|
||||
const Table = ({
|
||||
permissions,
|
||||
headers,
|
||||
contentType,
|
||||
isLoading,
|
||||
tokens,
|
||||
onConfirmDelete,
|
||||
tokenType,
|
||||
}) => {
|
||||
const { canDelete, canUpdate, canRead } = permissions;
|
||||
const withBulkActions = canDelete || canUpdate || canRead;
|
||||
const [{ query }] = useQueryParams();
|
||||
@ -47,7 +55,9 @@ const Table = ({ permissions, headers, contentType, isLoading, tokens, onConfirm
|
||||
key={token.id}
|
||||
{...onRowClick({
|
||||
fn() {
|
||||
trackUsage('willEditTokenFromList');
|
||||
trackUsage('willEditTokenFromList', {
|
||||
tokenType,
|
||||
});
|
||||
push(`${pathname}/${token.id}`);
|
||||
},
|
||||
condition: canUpdate,
|
||||
@ -87,6 +97,7 @@ const Table = ({ permissions, headers, contentType, isLoading, tokens, onConfirm
|
||||
<DeleteButton
|
||||
tokenName={token.name}
|
||||
onClickDelete={() => onConfirmDelete(token.id)}
|
||||
tokenType={tokenType}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
@ -121,6 +132,7 @@ Table.propTypes = {
|
||||
contentType: PropTypes.string.isRequired,
|
||||
isLoading: PropTypes.bool,
|
||||
onConfirmDelete: PropTypes.func,
|
||||
tokenType: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
Table.defaultProps = {
|
||||
|
@ -6,7 +6,7 @@ import { Duplicate, Key } from '@strapi/icons';
|
||||
import PropTypes from 'prop-types';
|
||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
||||
|
||||
const TokenBox = ({ token }) => {
|
||||
const TokenBox = ({ token, tokenType }) => {
|
||||
const { formatMessage } = useIntl();
|
||||
const toggleNotification = useNotification();
|
||||
const { trackUsage } = useTracking(); // TODO: Track different types of tokens
|
||||
@ -19,7 +19,9 @@ const TokenBox = ({ token }) => {
|
||||
<span style={{ alignSelf: 'start' }}>
|
||||
<CopyToClipboard
|
||||
onCopy={() => {
|
||||
trackUsageRef.current('didCopyTokenKey');
|
||||
trackUsageRef.current('didCopyTokenKey', {
|
||||
tokenType,
|
||||
});
|
||||
toggleNotification({
|
||||
type: 'success',
|
||||
message: { id: 'Settings.tokens.notification.copied' },
|
||||
@ -70,6 +72,7 @@ TokenBox.defaultProps = {
|
||||
|
||||
TokenBox.propTypes = {
|
||||
token: PropTypes.string,
|
||||
tokenType: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default TokenBox;
|
||||
|
@ -0,0 +1,2 @@
|
||||
export const API_TOKEN_TYPE = 'api-token';
|
||||
export const TRANSFER_TOKEN_TYPE = 'transfer-token';
|
@ -26,6 +26,7 @@ import Permissions from './components/Permissions';
|
||||
import FormApiTokenContainer from './components/FormApiTokenContainer';
|
||||
import TokenBox from '../../../components/Tokens/TokenBox';
|
||||
import FormHead from '../../../components/Tokens/FormHead';
|
||||
import { API_TOKEN_TYPE } from '../../../components/Tokens/constants';
|
||||
|
||||
const MSG_ERROR_NAME_TAKEN = 'Name already taken';
|
||||
|
||||
@ -107,7 +108,9 @@ const ApiTokenCreateView = () => {
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
trackUsageRef.current(isCreating ? 'didAddTokenFromList' : 'didEditTokenFromList');
|
||||
trackUsageRef.current(isCreating ? 'didAddTokenFromList' : 'didEditTokenFromList', {
|
||||
tokenType: API_TOKEN_TYPE,
|
||||
});
|
||||
}, [isCreating]);
|
||||
|
||||
const { status } = useQuery(
|
||||
@ -152,7 +155,9 @@ const ApiTokenCreateView = () => {
|
||||
);
|
||||
|
||||
const handleSubmit = async (body, actions) => {
|
||||
trackUsageRef.current(isCreating ? 'willCreateToken' : 'willEditToken');
|
||||
trackUsageRef.current(isCreating ? 'willCreateToken' : 'willEditToken', {
|
||||
tokenType: API_TOKEN_TYPE,
|
||||
});
|
||||
lockApp();
|
||||
const lifespanVal =
|
||||
body.lifespan && parseInt(body.lifespan, 10) && body.lifespan !== '0'
|
||||
@ -199,6 +204,7 @@ const ApiTokenCreateView = () => {
|
||||
|
||||
trackUsageRef.current(isCreating ? 'didCreateToken' : 'didEditToken', {
|
||||
type: apiToken.type,
|
||||
tokenType: API_TOKEN_TYPE,
|
||||
});
|
||||
} catch (err) {
|
||||
const errors = formatAPIErrors(err.response.data);
|
||||
@ -297,7 +303,9 @@ const ApiTokenCreateView = () => {
|
||||
|
||||
<ContentLayout>
|
||||
<Stack spacing={6}>
|
||||
{Boolean(apiToken?.name) && <TokenBox token={apiToken?.accessKey} />}
|
||||
{Boolean(apiToken?.name) && (
|
||||
<TokenBox token={apiToken?.accessKey} tokenType={API_TOKEN_TYPE} />
|
||||
)}
|
||||
<FormApiTokenContainer
|
||||
errors={errors}
|
||||
onChange={handleChange}
|
||||
|
@ -22,6 +22,7 @@ import { Plus } from '@strapi/icons';
|
||||
import adminPermissions from '../../../../../permissions';
|
||||
import tableHeaders from './utils/tableHeaders';
|
||||
import Table from '../../../components/Tokens/Table';
|
||||
import { API_TOKEN_TYPE } from '../../../components/Tokens/constants';
|
||||
|
||||
const ApiTokenListView = () => {
|
||||
useFocusWhenNavigate();
|
||||
@ -62,12 +63,14 @@ const ApiTokenListView = () => {
|
||||
} = useQuery(
|
||||
['api-tokens'],
|
||||
async () => {
|
||||
trackUsage('willAccessTokenList');
|
||||
trackUsage('willAccessTokenList', {
|
||||
tokenType: API_TOKEN_TYPE,
|
||||
});
|
||||
const {
|
||||
data: { data },
|
||||
} = await get(`/admin/api-tokens`);
|
||||
|
||||
trackUsage('didAccessTokenList', { number: data.length });
|
||||
trackUsage('didAccessTokenList', { number: data.length, tokenType: API_TOKEN_TYPE });
|
||||
|
||||
return data;
|
||||
},
|
||||
@ -127,7 +130,11 @@ const ApiTokenListView = () => {
|
||||
data-testid="create-api-token-button"
|
||||
startIcon={<Plus />}
|
||||
size="S"
|
||||
onClick={() => trackUsage('willAddTokenFromList')}
|
||||
onClick={() =>
|
||||
trackUsage('willAddTokenFromList', {
|
||||
tokenType: API_TOKEN_TYPE,
|
||||
})
|
||||
}
|
||||
to="/settings/api-tokens/create"
|
||||
>
|
||||
{formatMessage({
|
||||
@ -149,6 +156,7 @@ const ApiTokenListView = () => {
|
||||
isLoading={isLoading}
|
||||
onConfirmDelete={(id) => deleteMutation.mutateAsync(id)}
|
||||
tokens={apiTokens}
|
||||
tokenType={API_TOKEN_TYPE}
|
||||
/>
|
||||
)}
|
||||
{shouldDisplayNoContentWithCreationButton && (
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { Formik } from 'formik';
|
||||
import { useRouteMatch, useHistory } from 'react-router-dom';
|
||||
@ -9,6 +9,7 @@ import {
|
||||
Form,
|
||||
useOverlayBlocker,
|
||||
useNotification,
|
||||
useTracking,
|
||||
useGuidedTour,
|
||||
useRBAC,
|
||||
useFetchClient,
|
||||
@ -21,6 +22,7 @@ import adminPermissions from '../../../../../permissions';
|
||||
import FormTransferTokenContainer from './components/FormTransferTokenContainer';
|
||||
import TokenBox from '../../../components/Tokens/TokenBox';
|
||||
import FormHead from '../../../components/Tokens/FormHead';
|
||||
import { TRANSFER_TOKEN_TYPE } from '../../../components/Tokens/constants';
|
||||
|
||||
const MSG_ERROR_NAME_TAKEN = 'Name already taken';
|
||||
|
||||
@ -37,6 +39,8 @@ const TransferTokenCreateView = () => {
|
||||
}
|
||||
: null
|
||||
);
|
||||
const { trackUsage } = useTracking();
|
||||
const trackUsageRef = useRef(trackUsage);
|
||||
const { setCurrentStep } = useGuidedTour();
|
||||
const {
|
||||
allowedActions: { canCreate, canUpdate, canRegenerate },
|
||||
@ -48,6 +52,12 @@ const TransferTokenCreateView = () => {
|
||||
|
||||
const isCreating = id === 'create';
|
||||
|
||||
useEffect(() => {
|
||||
trackUsageRef.current(isCreating ? 'didAddTokenFromList' : 'didEditTokenFromList', {
|
||||
tokenType: TRANSFER_TOKEN_TYPE,
|
||||
});
|
||||
}, [isCreating]);
|
||||
|
||||
const { status } = useQuery(
|
||||
['transfer-token', id],
|
||||
async () => {
|
||||
@ -73,6 +83,9 @@ const TransferTokenCreateView = () => {
|
||||
);
|
||||
|
||||
const handleSubmit = async (body, actions) => {
|
||||
trackUsageRef.current(isCreating ? 'willCreateToken' : 'willEditToken', {
|
||||
tokenType: TRANSFER_TOKEN_TYPE,
|
||||
});
|
||||
lockApp();
|
||||
const lifespanVal =
|
||||
body.lifespan && parseInt(body.lifespan, 10) && body.lifespan !== '0'
|
||||
@ -117,6 +130,11 @@ const TransferTokenCreateView = () => {
|
||||
defaultMessage: 'Transfer Token successfully edited',
|
||||
}),
|
||||
});
|
||||
|
||||
trackUsageRef.current(isCreating ? 'didCreateToken' : 'didEditToken', {
|
||||
type: transferToken?.type,
|
||||
tokenType: TRANSFER_TOKEN_TYPE,
|
||||
});
|
||||
} catch (err) {
|
||||
const errors = formatAPIErrors(err.response.data);
|
||||
actions.setErrors(errors);
|
||||
@ -177,7 +195,9 @@ const TransferTokenCreateView = () => {
|
||||
/>
|
||||
<ContentLayout>
|
||||
<Stack spacing={6}>
|
||||
{Boolean(transferToken?.name) && <TokenBox token={transferToken?.accessKey} />}
|
||||
{Boolean(transferToken?.name) && (
|
||||
<TokenBox token={transferToken?.accessKey} tokenType={TRANSFER_TOKEN_TYPE} />
|
||||
)}
|
||||
<FormTransferTokenContainer
|
||||
errors={errors}
|
||||
onChange={handleChange}
|
||||
|
@ -11,6 +11,7 @@ import {
|
||||
NoPermissions,
|
||||
useRBAC,
|
||||
NoContent,
|
||||
useTracking,
|
||||
useGuidedTour,
|
||||
LinkButton,
|
||||
useFetchClient,
|
||||
@ -21,6 +22,7 @@ import { Plus } from '@strapi/icons';
|
||||
import adminPermissions from '../../../../../permissions';
|
||||
import tableHeaders from './utils/tableHeaders';
|
||||
import Table from '../../../components/Tokens/Table';
|
||||
import { TRANSFER_TOKEN_TYPE } from '../../../components/Tokens/constants';
|
||||
|
||||
const TransferTokenListView = () => {
|
||||
useFocusWhenNavigate();
|
||||
@ -31,6 +33,7 @@ const TransferTokenListView = () => {
|
||||
allowedActions: { canCreate, canDelete, canUpdate, canRead },
|
||||
} = useRBAC(adminPermissions.settings['transfer-tokens']);
|
||||
const { push } = useHistory();
|
||||
const { trackUsage } = useTracking();
|
||||
|
||||
const { startSection } = useGuidedTour();
|
||||
const startSectionRef = useRef(startSection);
|
||||
@ -61,10 +64,15 @@ const TransferTokenListView = () => {
|
||||
} = useQuery(
|
||||
['transfer-tokens'],
|
||||
async () => {
|
||||
trackUsage('willAccessTokenList', {
|
||||
tokenType: TRANSFER_TOKEN_TYPE,
|
||||
});
|
||||
const {
|
||||
data: { data },
|
||||
} = await get(`/admin/transfer/tokens`);
|
||||
|
||||
trackUsage('didAccessTokenList', { number: data.length, tokenType: TRANSFER_TOKEN_TYPE });
|
||||
|
||||
return data;
|
||||
},
|
||||
{
|
||||
@ -125,6 +133,11 @@ const TransferTokenListView = () => {
|
||||
data-testid="create-transfer-token-button"
|
||||
startIcon={<Plus />}
|
||||
size="S"
|
||||
onClick={() =>
|
||||
trackUsage('willAddTokenFromList', {
|
||||
tokenType: TRANSFER_TOKEN_TYPE,
|
||||
})
|
||||
}
|
||||
to="/settings/transfer-tokens/create"
|
||||
>
|
||||
{formatMessage({
|
||||
@ -146,6 +159,7 @@ const TransferTokenListView = () => {
|
||||
isLoading={isLoading}
|
||||
onConfirmDelete={(id) => deleteMutation.mutateAsync(id)}
|
||||
tokens={transferTokens}
|
||||
tokenType={TRANSFER_TOKEN_TYPE}
|
||||
/>
|
||||
)}
|
||||
{shouldDisplayNoContentWithCreationButton && (
|
||||
|
Loading…
x
Reference in New Issue
Block a user