diff --git a/services/web/frontend/js/features/share-project-modal/components/add-collaborators.js b/services/web/frontend/js/features/share-project-modal/components/add-collaborators.js
index a0684a6b4a..b99859b5e6 100644
--- a/services/web/frontend/js/features/share-project-modal/components/add-collaborators.js
+++ b/services/web/frontend/js/features/share-project-modal/components/add-collaborators.js
@@ -8,6 +8,7 @@ import { resendInvite, sendInvite } from '../utils/api'
import { useUserContacts } from '../hooks/use-user-contacts'
import useIsMounted from '../../../shared/hooks/use-is-mounted'
import { useProjectContext } from '../../../shared/context/project-context'
+import { sendMB } from '../../../infrastructure/event-tracking'
export default function AddCollaborators() {
const [privileges, setPrivileges] = useState('readAndWrite')
@@ -82,6 +83,15 @@ export default function AddCollaborators() {
} else {
data = await sendInvite(projectId, email, privileges)
}
+
+ sendMB('collaborator-invited', {
+ project_id: projectId,
+ // invitation is only populated on successful invite, meaning that for paywall and other cases this will be null
+ successful_invite: !!data.invite,
+ users_updated: !!(data.users || data.user),
+ current_collaborators_amount: members.length,
+ current_invites_amount: invites.length,
+ })
} catch (error) {
setInFlight(false)
setError(
diff --git a/services/web/frontend/js/features/share-project-modal/components/edit-member.js b/services/web/frontend/js/features/share-project-modal/components/edit-member.js
index 00d82e94eb..205d55c7a6 100644
--- a/services/web/frontend/js/features/share-project-modal/components/edit-member.js
+++ b/services/web/frontend/js/features/share-project-modal/components/edit-member.js
@@ -8,6 +8,7 @@ import { Button, Col, Form, FormControl, FormGroup } from 'react-bootstrap'
import Tooltip from '../../../shared/components/tooltip'
import Icon from '../../../shared/components/icon'
import { useProjectContext } from '../../../shared/context/project-context'
+import { sendMB } from '../../../infrastructure/event-tracking'
export default function EditMember({ member }) {
const [privileges, setPrivileges] = useState(member.privileges)
@@ -112,15 +113,21 @@ SelectPrivilege.propTypes = {
function RemoveMemberAction({ member }) {
const { t } = useTranslation()
const { updateProject, monitorRequest } = useShareProjectContext()
- const { _id: projectId, members } = useProjectContext()
+ const { _id: projectId, members, invites } = useProjectContext()
function handleClick(event) {
event.preventDefault()
monitorRequest(() => removeMemberFromProject(projectId, member)).then(
() => {
+ const updatedMembers = members.filter(existing => existing !== member)
updateProject({
- members: members.filter(existing => existing !== member),
+ members: updatedMembers,
+ })
+ sendMB('collaborator-removed', {
+ project_id: projectId,
+ current_collaborators_amount: updatedMembers.length,
+ current_invites_amount: invites.length,
})
}
)
diff --git a/services/web/frontend/js/features/share-project-modal/components/invite.js b/services/web/frontend/js/features/share-project-modal/components/invite.js
index 03e009bebe..42c1fc8a74 100644
--- a/services/web/frontend/js/features/share-project-modal/components/invite.js
+++ b/services/web/frontend/js/features/share-project-modal/components/invite.js
@@ -8,6 +8,7 @@ import { Trans, useTranslation } from 'react-i18next'
import MemberPrivileges from './member-privileges'
import { resendInvite, revokeInvite } from '../utils/api'
import { useProjectContext } from '../../../shared/context/project-context'
+import { sendMB } from '../../../infrastructure/event-tracking'
export default function Invite({ invite, isProjectOwner }) {
return (
@@ -77,14 +78,20 @@ ResendInvite.propTypes = {
function RevokeInvite({ invite }) {
const { t } = useTranslation()
const { updateProject, monitorRequest } = useShareProjectContext()
- const { _id: projectId, invites } = useProjectContext()
+ const { _id: projectId, invites, members } = useProjectContext()
function handleClick(event) {
event.preventDefault()
monitorRequest(() => revokeInvite(projectId, invite)).then(() => {
+ const updatedInvites = invites.filter(existing => existing !== invite)
updateProject({
- invites: invites.filter(existing => existing !== invite),
+ invites: updatedInvites,
+ })
+ sendMB('collaborator-invite-revoked', {
+ project_id: projectId,
+ current_invites_amount: updatedInvites.length,
+ current_collaborators_amount: members.length,
})
})
}
diff --git a/services/web/frontend/js/features/share-project-modal/components/link-sharing.js b/services/web/frontend/js/features/share-project-modal/components/link-sharing.js
index 512c1154e7..3fd796494c 100644
--- a/services/web/frontend/js/features/share-project-modal/components/link-sharing.js
+++ b/services/web/frontend/js/features/share-project-modal/components/link-sharing.js
@@ -10,6 +10,7 @@ import CopyLink from '../../../shared/components/copy-link'
import { useProjectContext } from '../../../shared/context/project-context'
import * as eventTracking from '../../../infrastructure/event-tracking'
import { useUserContext } from '../../../shared/context/user-context'
+import { sendMB } from '../../../infrastructure/event-tracking'
import { getJSON } from '../../../infrastructure/fetch-json'
import useAbortController from '../../../shared/hooks/use-abort-controller'
@@ -24,6 +25,9 @@ export default function LinkSharing({ canAddCollaborators }) {
const setAccessLevel = useCallback(
newPublicAccessLevel => {
setInflight(true)
+ sendMB('link-sharing-click-off', {
+ project_id: projectId,
+ })
monitorRequest(() =>
setProjectAccessLevel(projectId, newPublicAccessLevel)
)
@@ -43,7 +47,11 @@ export default function LinkSharing({ canAddCollaborators }) {
// Private (with token-access available)
case 'private':
return (
-
+
)
// Token-based access
@@ -76,7 +84,7 @@ LinkSharing.propTypes = {
canAddCollaborators: PropTypes.bool,
}
-function PrivateSharing({ setAccessLevel, inflight }) {
+function PrivateSharing({ setAccessLevel, inflight, projectId }) {
return (
@@ -88,7 +96,7 @@ function PrivateSharing({ setAccessLevel, inflight }) {
className="btn-inline-link"
onClick={() => {
setAccessLevel('tokenBased')
- eventTracking.sendMB('link-sharing-click')
+ eventTracking.sendMB('link-sharing-click', { projectId })
}}
disabled={inflight}
>
@@ -104,6 +112,7 @@ function PrivateSharing({ setAccessLevel, inflight }) {
PrivateSharing.propTypes = {
setAccessLevel: PropTypes.func.isRequired,
inflight: PropTypes.bool,
+ projectId: PropTypes.string,
}
function TokenBasedSharing({ setAccessLevel, inflight, canAddCollaborators }) {
diff --git a/services/web/frontend/js/features/share-project-modal/components/share-project-modal.js b/services/web/frontend/js/features/share-project-modal/components/share-project-modal.js
index 45c1186bf7..c11ed8785d 100644
--- a/services/web/frontend/js/features/share-project-modal/components/share-project-modal.js
+++ b/services/web/frontend/js/features/share-project-modal/components/share-project-modal.js
@@ -58,9 +58,10 @@ const ShareProjectModal = React.memo(function ShareProjectModal({
if (show) {
sendMB('share-modal-opened', {
splitTestVariant: splitTestVariants['null-test-share-modal'],
+ project_id: project._id,
})
}
- }, [splitTestVariants, show])
+ }, [splitTestVariants, project._id, show])
// reset error when the modal is opened
useEffect(() => {