summaryrefslogtreecommitdiffstats
path: root/webapp/components
diff options
context:
space:
mode:
authorGeorge Goldberg <george@gberg.me>2017-02-24 17:34:21 +0000
committerGitHub <noreply@github.com>2017-02-24 17:34:21 +0000
commit97cc0a0d73dcacfefcdff785c802762e2a0a60d6 (patch)
treec584bb28511980bde3bf09a6fffc1f8feacf9ddf /webapp/components
parentf182d196fffc9da89ad63bdbd7bbb2e41da3146e (diff)
downloadchat-97cc0a0d73dcacfefcdff785c802762e2a0a60d6.tar.gz
chat-97cc0a0d73dcacfefcdff785c802762e2a0a60d6.tar.bz2
chat-97cc0a0d73dcacfefcdff785c802762e2a0a60d6.zip
PLT-5071: Client side component of Telemetry. (#5516)
Diffstat (limited to 'webapp/components')
-rw-r--r--webapp/components/create_post.jsx1
-rw-r--r--webapp/components/create_team/components/display_name.jsx8
-rw-r--r--webapp/components/create_team/components/team_url.jsx10
-rw-r--r--webapp/components/logged_in.jsx16
-rw-r--r--webapp/components/root.jsx21
-rw-r--r--webapp/components/sidebar.jsx9
-rw-r--r--webapp/components/sidebar_right.jsx5
-rw-r--r--webapp/components/signup/components/signup_email.jsx11
-rw-r--r--webapp/components/signup/components/signup_ldap.jsx8
-rw-r--r--webapp/components/team_sidebar/components/team_button.jsx2
-rw-r--r--webapp/components/tutorial/tutorial_intro_screens.jsx26
-rw-r--r--webapp/components/tutorial/tutorial_tip.jsx31
-rw-r--r--webapp/components/user_settings/user_settings_general.jsx12
-rw-r--r--webapp/components/webrtc/webrtc_controller.jsx5
14 files changed, 132 insertions, 33 deletions
diff --git a/webapp/components/create_post.jsx b/webapp/components/create_post.jsx
index 581ed16a0..7bdcf6888 100644
--- a/webapp/components/create_post.jsx
+++ b/webapp/components/create_post.jsx
@@ -497,6 +497,7 @@ export default class CreatePost extends React.Component {
placement='top'
screens={screens}
overlayClass='tip-overlay--chat'
+ diagnosticsTag='tutorial_tip_1_sending_messages'
/>
);
}
diff --git a/webapp/components/create_team/components/display_name.jsx b/webapp/components/create_team/components/display_name.jsx
index 29077bd24..aeb8afbb9 100644
--- a/webapp/components/create_team/components/display_name.jsx
+++ b/webapp/components/create_team/components/display_name.jsx
@@ -1,7 +1,7 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
-import {track} from 'actions/analytics_actions.jsx';
+import {trackEvent} from 'actions/diagnostics_actions.jsx';
import Constants from 'utils/constants.jsx';
import {cleanUpUrlable} from 'utils/url.jsx';
@@ -22,6 +22,10 @@ export default class TeamSignupDisplayNamePage extends React.Component {
this.state = {};
}
+ componentDidMount() {
+ trackEvent('signup', 'signup_team_01_name');
+ }
+
submitNext(e) {
e.preventDefault();
@@ -60,8 +64,6 @@ export default class TeamSignupDisplayNamePage extends React.Component {
}
render() {
- track('signup', 'signup_team_02_name');
-
var nameError = null;
var nameDivClass = 'form-group';
if (this.state.nameError) {
diff --git a/webapp/components/create_team/components/team_url.jsx b/webapp/components/create_team/components/team_url.jsx
index 2ab143d7f..c8a60cdf9 100644
--- a/webapp/components/create_team/components/team_url.jsx
+++ b/webapp/components/create_team/components/team_url.jsx
@@ -2,7 +2,7 @@
// See License.txt for license information.
import {checkIfTeamExists, createTeam} from 'actions/team_actions.jsx';
-import {track} from 'actions/analytics_actions.jsx';
+import {trackEvent} from 'actions/diagnostics_actions.jsx';
import Constants from 'utils/constants.jsx';
import * as URL from 'utils/url.jsx';
@@ -27,6 +27,10 @@ export default class TeamUrl extends React.Component {
};
}
+ componentDidMount() {
+ trackEvent('signup', 'signup_team_02_url');
+ }
+
submitBack(e) {
e.preventDefault();
this.props.state.wizard = 'display_name';
@@ -106,7 +110,7 @@ export default class TeamUrl extends React.Component {
createTeam(teamSignup.team,
() => {
- track('signup', 'signup_team_08_complete');
+ trackEvent('signup', 'signup_team_03_complete');
},
(err) => {
this.setState({nameError: err.message});
@@ -126,8 +130,6 @@ export default class TeamUrl extends React.Component {
}
render() {
- track('signup', 'signup_team_03_url');
-
let nameError = null;
let nameDivClass = 'form-group';
if (this.state.nameError) {
diff --git a/webapp/components/logged_in.jsx b/webapp/components/logged_in.jsx
index 9282e74ca..8d7a00653 100644
--- a/webapp/components/logged_in.jsx
+++ b/webapp/components/logged_in.jsx
@@ -26,7 +26,6 @@ export default class LoggedIn extends React.Component {
super(params);
this.onUserChanged = this.onUserChanged.bind(this);
- this.setupUser = this.setupUser.bind(this);
// Because current CSS requires the root tag to have specific stuff
$('#root').attr('class', 'channel-view');
@@ -45,9 +44,7 @@ export default class LoggedIn extends React.Component {
user: UserStore.getCurrentUser()
};
- if (this.state.user) {
- this.setupUser(this.state.user);
- } else {
+ if (!this.state.user) {
GlobalActions.emitUserLoggedOutEvent('/login');
}
}
@@ -56,21 +53,10 @@ export default class LoggedIn extends React.Component {
return this.state.user != null;
}
- setupUser(user) {
- // Update segment indentify
- if (global.window.mm_config.SegmentDeveloperKey != null && global.window.mm_config.SegmentDeveloperKey !== '') {
- global.window.analytics.identify(user.id, {
- createdAt: user.create_at,
- id: user.id
- });
- }
- }
-
onUserChanged() {
// Grab the current user
const user = UserStore.getCurrentUser();
if (!Utils.areObjectsEqual(this.state.user, user)) {
- this.setupUser(user);
this.setState({
user
});
diff --git a/webapp/components/root.jsx b/webapp/components/root.jsx
index 465df5d79..4e7c19452 100644
--- a/webapp/components/root.jsx
+++ b/webapp/components/root.jsx
@@ -14,6 +14,7 @@ import $ from 'jquery';
import {browserHistory} from 'react-router/es6';
import UserStore from 'stores/user_store.jsx';
import BrowserStore from 'stores/browser_store.jsx';
+import Constants from 'utils/constants.jsx';
export default class Root extends React.Component {
constructor(props) {
@@ -26,12 +27,26 @@ export default class Root extends React.Component {
this.localizationChanged = this.localizationChanged.bind(this);
this.redirectIfNecessary = this.redirectIfNecessary.bind(this);
+ const segmentKey = Constants.DIAGNOSTICS_SEGMENT_KEY;
+
// Ya....
/*eslint-disable */
- if (window.mm_config.SegmentDeveloperKey != null && window.mm_config.SegmentDeveloperKey !== "") {
+ if (segmentKey != null && segmentKey !== '' && window.mm_config.DiagnosticsEnabled) {
!function(){var analytics=global.window.analytics=global.window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","group","track","ready","alias","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="3.0.1";
- analytics.load(window.mm_config.SegmentDeveloperKey);
- analytics.page();
+ analytics.load(segmentKey);
+
+ analytics.page('ApplicationLoaded', {
+ path: '',
+ referrer: '',
+ search: '',
+ title: '',
+ url: '',
+ },
+ {
+ context: {
+ ip: '0.0.0.0'
+ },
+ });
}}();
}
/*eslint-enable */
diff --git a/webapp/components/sidebar.jsx b/webapp/components/sidebar.jsx
index 08962682d..048122897 100644
--- a/webapp/components/sidebar.jsx
+++ b/webapp/components/sidebar.jsx
@@ -21,6 +21,7 @@ import * as Utils from 'utils/utils.jsx';
import * as ChannelUtils from 'utils/channel_utils.jsx';
import * as ChannelActions from 'actions/channel_actions.jsx';
+import {trackEvent} from 'actions/diagnostics_actions.jsx';
import Constants from 'utils/constants.jsx';
import {FormattedMessage, FormattedHTMLMessage} from 'react-intl';
@@ -363,6 +364,7 @@ export default class Sidebar extends React.Component {
showMoreChannelsModal() {
this.setState({showMoreChannelsModal: true});
+ trackEvent('ui', 'ui_channels_more_public');
}
hideMoreChannelsModal() {
@@ -378,6 +380,7 @@ export default class Sidebar extends React.Component {
}
showMoreDirectChannelsModal() {
+ trackEvent('ui', 'ui_channels_more_direct');
this.setState({showDirectChannelsModal: true});
}
@@ -448,6 +451,7 @@ export default class Sidebar extends React.Component {
placement='right'
screens={screens}
overlayClass='tip-overlay--sidebar'
+ diagnosticsTag='tutorial_tip_2_channels'
/>
);
}
@@ -566,6 +570,7 @@ export default class Sidebar extends React.Component {
<Link
to={link}
className={rowClass}
+ onClick={this.trackChannelSelectedEvent}
>
{icon}
{channel.display_name}
@@ -577,6 +582,10 @@ export default class Sidebar extends React.Component {
);
}
+ trackChannelSelectedEvent() {
+ trackEvent('ui', 'ui_channel_selected');
+ }
+
render() {
// Check if we have all info needed to render
if (this.state.currentTeam == null || this.state.currentUser == null) {
diff --git a/webapp/components/sidebar_right.jsx b/webapp/components/sidebar_right.jsx
index da7ff818d..fb120337a 100644
--- a/webapp/components/sidebar_right.jsx
+++ b/webapp/components/sidebar_right.jsx
@@ -12,6 +12,7 @@ import PreferenceStore from 'stores/preference_store.jsx';
import WebrtcStore from 'stores/webrtc_store.jsx';
import {getFlaggedPosts} from 'actions/post_actions.jsx';
+import {trackEvent} from 'actions/diagnostics_actions.jsx';
import * as Utils from 'utils/utils.jsx';
import Constants from 'utils/constants.jsx';
@@ -71,6 +72,10 @@ export default class SidebarRight extends React.Component {
const isOpen = this.state.searchVisible || this.state.postRightVisible;
const willOpen = nextState.searchVisible || nextState.postRightVisible;
+ if (!isOpen && willOpen) {
+ trackEvent('ui', 'ui_rhs_opened');
+ }
+
if (isOpen !== willOpen) {
PostStore.jumpPostsViewSidebarOpen();
}
diff --git a/webapp/components/signup/components/signup_email.jsx b/webapp/components/signup/components/signup_email.jsx
index 8325c9f56..cf4ff0a95 100644
--- a/webapp/components/signup/components/signup_email.jsx
+++ b/webapp/components/signup/components/signup_email.jsx
@@ -4,8 +4,9 @@
import LoadingScreen from 'components/loading_screen.jsx';
import * as GlobalActions from 'actions/global_actions.jsx';
+import {trackEvent} from 'actions/diagnostics_actions.jsx';
+
import BrowserStore from 'stores/browser_store.jsx';
-import {track} from 'actions/analytics_actions.jsx';
import {getInviteInfo} from 'actions/team_actions.jsx';
import {loginById, createUserWithInvite} from 'actions/user_actions.jsx';
@@ -37,6 +38,10 @@ export default class SignupEmail extends React.Component {
this.state = this.getInviteInfo();
}
+ componentDidMount() {
+ trackEvent('signup', 'signup_user_01_welcome');
+ }
+
getInviteInfo() {
let data = this.props.location.query.d;
let hash = this.props.location.query.h;
@@ -117,7 +122,7 @@ export default class SignupEmail extends React.Component {
}
handleSignupSuccess(user, data) {
- track('signup', 'signup_user_02_complete');
+ trackEvent('signup', 'signup_user_02_complete');
loginById(
data.id,
user.password,
@@ -401,8 +406,6 @@ export default class SignupEmail extends React.Component {
}
render() {
- track('signup', 'signup_user_01_welcome');
-
let serverError = null;
if (this.state.serverError) {
serverError = (
diff --git a/webapp/components/signup/components/signup_ldap.jsx b/webapp/components/signup/components/signup_ldap.jsx
index bf98d0461..0e02d5db7 100644
--- a/webapp/components/signup/components/signup_ldap.jsx
+++ b/webapp/components/signup/components/signup_ldap.jsx
@@ -4,9 +4,9 @@
import FormError from 'components/form_error.jsx';
import * as GlobalActions from 'actions/global_actions.jsx';
-import {track} from 'actions/analytics_actions.jsx';
import {addUserToTeamFromInvite} from 'actions/team_actions.jsx';
import {webLoginByLdap} from 'actions/user_actions.jsx';
+import {trackEvent} from 'actions/diagnostics_actions.jsx';
import * as Utils from 'utils/utils.jsx';
@@ -39,6 +39,10 @@ export default class SignupLdap extends React.Component {
});
}
+ componentDidMount() {
+ trackEvent('signup', 'signup_user_01_welcome');
+ }
+
handleLdapIdChange(e) {
this.setState({
ldapId: e.target.value
@@ -107,8 +111,6 @@ export default class SignupLdap extends React.Component {
}
render() {
- track('signup', 'signup_user_01_welcome');
-
let ldapIdPlaceholder;
if (global.window.mm_config.LdapLoginFieldName) {
ldapIdPlaceholder = global.window.mm_config.LdapLoginFieldName;
diff --git a/webapp/components/team_sidebar/components/team_button.jsx b/webapp/components/team_sidebar/components/team_button.jsx
index 6fbf8aef9..894567538 100644
--- a/webapp/components/team_sidebar/components/team_button.jsx
+++ b/webapp/components/team_sidebar/components/team_button.jsx
@@ -3,6 +3,7 @@
import Constants from 'utils/constants.jsx';
+import {trackEvent} from 'actions/diagnostics_actions.jsx';
import {switchTeams} from 'actions/team_actions.jsx';
import React from 'react';
@@ -19,6 +20,7 @@ export default class TeamButton extends React.Component {
handleSwitch(e) {
e.preventDefault();
+ trackEvent('ui', 'ui_team_sidebar_switch_team');
switchTeams(this.props.url);
}
diff --git a/webapp/components/tutorial/tutorial_intro_screens.jsx b/webapp/components/tutorial/tutorial_intro_screens.jsx
index a0b6118d3..c266191b8 100644
--- a/webapp/components/tutorial/tutorial_intro_screens.jsx
+++ b/webapp/components/tutorial/tutorial_intro_screens.jsx
@@ -6,6 +6,7 @@ import TeamStore from 'stores/team_store.jsx';
import PreferenceStore from 'stores/preference_store.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import * as GlobalActions from 'actions/global_actions.jsx';
+import {trackEvent} from 'actions/diagnostics_actions.jsx';
import {Constants, Preferences} from 'utils/constants.jsx';
@@ -31,10 +32,23 @@ export default class TutorialIntroScreens extends React.Component {
this.handleNext = this.handleNext.bind(this);
this.createScreen = this.createScreen.bind(this);
this.createCircles = this.createCircles.bind(this);
+ this.skipTutorial = this.skipTutorial.bind(this);
this.state = {currentScreen: 0};
}
handleNext() {
+ switch (this.state.currentScreen) {
+ case 0:
+ trackEvent('tutorial', 'tutorial_screen_1_welcome_to_mattermost_next');
+ break;
+ case 1:
+ trackEvent('tutorial', 'tutorial_screen_2_how_mattermost_works_next');
+ break;
+ case 2:
+ trackEvent('tutorial', 'tutorial_screen_3_youre_all_set_next');
+ break;
+ }
+
if (this.state.currentScreen < 2) {
this.setState({currentScreen: this.state.currentScreen + 1});
return;
@@ -53,6 +67,18 @@ export default class TutorialIntroScreens extends React.Component {
skipTutorial(e) {
e.preventDefault();
+ switch (this.state.currentScreen) {
+ case 0:
+ trackEvent('tutorial', 'tutorial_screen_1_welcome_to_mattermost_skip');
+ break;
+ case 1:
+ trackEvent('tutorial', 'tutorial_screen_2_how_mattermost_works_skip');
+ break;
+ case 2:
+ trackEvent('tutorial', 'tutorial_screen_3_youre_all_set_skip');
+ break;
+ }
+
AsyncClient.savePreference(
Preferences.TUTORIAL_STEP,
UserStore.getCurrentId(),
diff --git a/webapp/components/tutorial/tutorial_tip.jsx b/webapp/components/tutorial/tutorial_tip.jsx
index 7b613fe51..e78668b10 100644
--- a/webapp/components/tutorial/tutorial_tip.jsx
+++ b/webapp/components/tutorial/tutorial_tip.jsx
@@ -4,6 +4,7 @@
import UserStore from 'stores/user_store.jsx';
import PreferenceStore from 'stores/preference_store.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
+import {trackEvent} from 'actions/diagnostics_actions.jsx';
import Constants from 'utils/constants.jsx';
@@ -25,6 +26,7 @@ export default class TutorialTip extends React.Component {
this.handleNext = this.handleNext.bind(this);
this.toggle = this.toggle.bind(this);
+ this.skipTutorial = this.skipTutorial.bind(this);
this.state = {currentScreen: 0, show: false};
}
@@ -48,6 +50,22 @@ export default class TutorialTip extends React.Component {
return;
}
+ if (this.props.diagnosticsTag) {
+ let tag = this.props.diagnosticsTag;
+
+ if (this.props.screens.length > 1) {
+ tag += '_' + (this.state.currentScreen + 1).toString();
+ }
+
+ if (this.state.currentScreen === this.props.screens.length - 1) {
+ tag += '_okay';
+ } else {
+ tag += '_next';
+ }
+
+ trackEvent('tutorial', tag);
+ }
+
this.closeRightSidebar();
this.toggle();
}
@@ -62,6 +80,15 @@ export default class TutorialTip extends React.Component {
skipTutorial(e) {
e.preventDefault();
+ if (this.props.diagnosticsTag) {
+ let tag = this.props.diagnosticsTag;
+ if (this.props.screens.length > 1) {
+ tag += '_' + this.state.currentScreen;
+ }
+ tag += '_skip';
+ trackEvent('tutorial', tag);
+ }
+
AsyncClient.savePreference(
Preferences.TUTORIAL_STEP,
UserStore.getCurrentId(),
@@ -174,7 +201,8 @@ TutorialTip.defaultProps = {
TutorialTip.propTypes = {
screens: React.PropTypes.array.isRequired,
placement: React.PropTypes.string.isRequired,
- overlayClass: React.PropTypes.string
+ overlayClass: React.PropTypes.string,
+ diagnosticsTag: React.PropTypes.string
};
export function createMenuTip(toggleFunc, onBottom) {
@@ -207,6 +235,7 @@ export function createMenuTip(toggleFunc, onBottom) {
placement={placement}
screens={screens}
overlayClass={'tip-overlay--header--' + arrow}
+ diagnosticsTag='tutorial_tip_3_main_menu'
/>
</div>
);
diff --git a/webapp/components/user_settings/user_settings_general.jsx b/webapp/components/user_settings/user_settings_general.jsx
index d79507511..f9c624aa0 100644
--- a/webapp/components/user_settings/user_settings_general.jsx
+++ b/webapp/components/user_settings/user_settings_general.jsx
@@ -16,6 +16,7 @@ import * as Utils from 'utils/utils.jsx';
import {intlShape, injectIntl, defineMessages, FormattedMessage, FormattedHTMLMessage, FormattedDate} from 'react-intl';
import {updateUser, uploadProfileImage} from 'actions/user_actions.jsx';
+import {trackEvent} from 'actions/diagnostics_actions.jsx';
const holders = defineMessages({
usernameReserved: {
@@ -127,6 +128,8 @@ class UserSettingsGeneralTab extends React.Component {
user.username = username;
+ trackEvent('settings', 'user_settings_update', {field: 'username'});
+
this.submitUser(user, Constants.UserUpdateEvents.USERNAME, false);
}
@@ -143,6 +146,8 @@ class UserSettingsGeneralTab extends React.Component {
user.nickname = nickname;
+ trackEvent('settings', 'user_settings_update', {field: 'username'});
+
this.submitUser(user, Constants.UserUpdateEvents.NICKNAME, false);
}
@@ -161,6 +166,8 @@ class UserSettingsGeneralTab extends React.Component {
user.first_name = firstName;
user.last_name = lastName;
+ trackEvent('settings', 'user_settings_update', {field: 'fullname'});
+
this.submitUser(user, Constants.UserUpdateEvents.FULLNAME, false);
}
@@ -189,6 +196,7 @@ class UserSettingsGeneralTab extends React.Component {
}
user.email = email;
+ trackEvent('settings', 'user_settings_update', {field: 'email'});
this.submitUser(user, Constants.UserUpdateEvents.EMAIL, true);
}
@@ -228,6 +236,8 @@ class UserSettingsGeneralTab extends React.Component {
return;
}
+ trackEvent('settings', 'user_settings_update', {field: 'picture'});
+
const {formatMessage} = this.props.intl;
const picture = this.state.picture;
@@ -268,6 +278,8 @@ class UserSettingsGeneralTab extends React.Component {
user.position = position;
+ trackEvent('settings', 'user_settings_update', {field: 'position'});
+
this.submitUser(user, Constants.UserUpdateEvents.Position, false);
}
diff --git a/webapp/components/webrtc/webrtc_controller.jsx b/webapp/components/webrtc/webrtc_controller.jsx
index b8d3d4db6..0fab0d2e7 100644
--- a/webapp/components/webrtc/webrtc_controller.jsx
+++ b/webapp/components/webrtc/webrtc_controller.jsx
@@ -13,6 +13,7 @@ import SearchBox from '../search_bar.jsx';
import WebrtcHeader from './components/webrtc_header.jsx';
import ConnectingScreen from 'components/loading_screen.jsx';
+import {trackEvent} from 'actions/diagnostics_actions.jsx';
import * as WebrtcActions from 'actions/webrtc_actions.jsx';
import * as Utils from 'utils/utils.jsx';
@@ -600,6 +601,8 @@ export default class WebrtcController extends React.Component {
}
onFailed() {
+ trackEvent('api', 'api_users_webrtc_failed');
+
this.setState({
isCalling: false,
isAnswering: false,
@@ -733,6 +736,7 @@ export default class WebrtcController extends React.Component {
}
doAnswer(jsep) {
+ trackEvent('api', 'api_users_webrtc_start');
this.videocall.createAnswer({
jsep,
stream: this.localMedia,
@@ -747,6 +751,7 @@ export default class WebrtcController extends React.Component {
}
doHangup(error, manual) {
+ trackEvent('api', 'api_users_webrtc_end');
if (this.videocall && this.state.callInProgress) {
this.videocall.send({message: {request: 'hangup'}});
this.videocall.hangup();