feat(invite): add basic analytics for AddPeople dialog (#2641)

* feat(invite): add basic analytics for AddPeople dialog

Analytics for opening the dialog, closing the dialog, the
count of invites sent, and the count of invites errored.

* squash: fix typo, change default count init, remove extra analytics param
This commit is contained in:
virtuacoplenny 2018-03-22 17:53:16 -07:00 committed by bbaldino
parent a39da15c94
commit 83f47c2df1
2 changed files with 78 additions and 6 deletions

View File

@ -129,16 +129,21 @@ export function createFeedbackOpenEvent() {
}
/**
* Creates an event which indicates that the invite dialog was closed. This is
* not a TYPE_UI event, since it is not necessarily the result of a user
* interaction.
* Creates an event for an action regarding the AddPeopleDialog (invites).
*
* @param {string} action - The action that the event represents.
* @param {string} actionSubject - The subject that was acted upon.
* @param {boolean} attributes - Additional attributes to attach to the event.
* @returns {Object} The event in a format suitable for sending via
* sendAnalytics.
*/
export function createInviteDialogClosedEvent() {
export function createInviteDialogEvent(
action, actionSubject, attributes = {}) {
return {
action: 'invite.dialog.closed'
action,
actionSubject,
attributes,
source: 'inviteDialog'
};
}

View File

@ -6,6 +6,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createInviteDialogEvent, sendAnalytics } from '../../analytics';
import { getInviteURL } from '../../base/connection';
import { Dialog, hideDialog } from '../../base/dialog';
import { translate } from '../../base/i18n';
@ -143,6 +144,17 @@ class AddPeopleDialog extends Component<*, *> {
};
}
/**
* Sends an analytics event to record the dialog has been shown.
*
* @inheritdoc
* @returns {void}
*/
componentDidMount() {
sendAnalytics(createInviteDialogEvent(
'invite.dialog.opened', 'dialog'));
}
/**
* React Component method that executes once component is updated.
*
@ -162,6 +174,17 @@ class AddPeopleDialog extends Component<*, *> {
}
}
/**
* Sends an analytics event to record the dialog has been closed.
*
* @inheritdoc
* @returns {void}
*/
componentWillUnmount() {
sendAnalytics(createInviteDialogEvent(
'invite.dialog.closed', 'dialog'));
}
/**
* Renders the content of this component.
*
@ -231,6 +254,32 @@ class AddPeopleDialog extends Component<*, *> {
return text.replace(/\D/g, '');
}
/**
* Helper for determining how many of each type of user is being invited.
* Used for logging and sending analytics related to invites.
*
* @param {Array} inviteItems - An array with the invite items, as created
* in {@link _parseQueryResults}.
* @private
* @returns {Object} An object with keys as user types and values as the
* number of invites for that type.
*/
_getInviteTypeCounts(inviteItems = []) {
const inviteTypeCounts = {};
inviteItems.forEach(i => {
const type = i.item.type;
if (!inviteTypeCounts[type]) {
inviteTypeCounts[type] = 0;
}
inviteTypeCounts[type]++;
});
return inviteTypeCounts;
}
_isAddDisabled: () => boolean;
/**
@ -313,6 +362,15 @@ class AddPeopleDialog extends Component<*, *> {
* @returns {void}
*/
_onSubmit() {
const inviteTypeCounts
= this._getInviteTypeCounts(this.state.inviteItems);
sendAnalytics(createInviteDialogEvent(
'clicked', 'inviteButton', {
...inviteTypeCounts,
inviteAllowed: this._isAddDisabled()
}));
if (this._isAddDisabled()) {
return;
}
@ -393,7 +451,16 @@ class AddPeopleDialog extends Component<*, *> {
// If any invites are left that means something failed to send
// so treat it as an error.
if (invitesLeftToSend.length) {
logger.error(`${invitesLeftToSend.length} invites failed`);
const erroredInviteTypeCounts
= this._getInviteTypeCounts(invitesLeftToSend);
logger.error(`${invitesLeftToSend.length} invites failed`,
erroredInviteTypeCounts);
sendAnalytics(createInviteDialogEvent(
'error', 'invite', {
...erroredInviteTypeCounts
}));
this.setState({
addToCallInProgress: false,