Added some metrics to monitor in Google Analytics

This commit is contained in:
Przemek Wiech
2019-03-17 23:36:53 +01:00
parent b594ea5315
commit 1a1f49f2e6
4 changed files with 46 additions and 5 deletions

4
src/analytics.ts Normal file
View File

@@ -0,0 +1,4 @@
/** Sends an event to Google Analytics. */
export function analyticsEvent(action: string, data?: any) {
(window as any).gtag('event', action, data);
}

View File

@@ -1,5 +1,6 @@
import * as queryString from 'query-string'; import * as queryString from 'query-string';
import * as React from 'react'; import * as React from 'react';
import {analyticsEvent} from './analytics';
import {Chart} from './chart'; import {Chart} from './chart';
import {Details} from './details'; import {Details} from './details';
import {getSelection, loadFromUrl, loadGedcom} from './load_data'; import {getSelection, loadFromUrl, loadGedcom} from './load_data';
@@ -8,7 +9,7 @@ import {Intro} from './intro';
import {Loader, Message, Responsive} from 'semantic-ui-react'; import {Loader, Message, Responsive} from 'semantic-ui-react';
import {Redirect, Route, RouteComponentProps, Switch} from 'react-router-dom'; import {Redirect, Route, RouteComponentProps, Switch} from 'react-router-dom';
import {TopBar} from './top_bar'; import {TopBar} from './top_bar';
import {TopolaData} from './gedcom_util'; import {TopolaData, getSoftware} from './gedcom_util';
/** Shows an error message. */ /** Shows an error message. */
export function ErrorMessage(props: {message: string}) { export function ErrorMessage(props: {message: string}) {
@@ -92,6 +93,15 @@ export class App extends React.Component<RouteComponentProps, {}> {
const data = hash const data = hash
? await loadGedcom(hash, gedcom, images) ? await loadGedcom(hash, gedcom, images)
: await loadFromUrl(url!, handleCors); : await loadFromUrl(url!, handleCors);
analyticsEvent(hash ? 'upload_file_loaded' : 'url_file_loaded');
if (images && images.size) {
analyticsEvent('images_uploaded');
}
const software = getSoftware(data.gedcom.head);
if (software) {
analyticsEvent('gedcom_software', {event_label: software});
}
// Set state with data. // Set state with data.
this.setState( this.setState(
Object.assign({}, this.state, { Object.assign({}, this.state, {
@@ -105,6 +115,7 @@ export class App extends React.Component<RouteComponentProps, {}> {
}), }),
); );
} catch (error) { } catch (error) {
analyticsEvent(hash ? 'upload_file_error' : 'url_file_error');
// Set error state. // Set error state.
this.setState( this.setState(
Object.assign({}, this.state, { Object.assign({}, this.state, {
@@ -138,6 +149,7 @@ export class App extends React.Component<RouteComponentProps, {}> {
* Updates the browser URL. * Updates the browser URL.
*/ */
private onSelection = (selection: IndiInfo) => { private onSelection = (selection: IndiInfo) => {
analyticsEvent('selection_changed');
const location = this.props.location; const location = this.props.location;
const search = queryString.parse(location.search); const search = queryString.parse(location.search);
search.indi = selection.id; search.indi = selection.id;
@@ -187,10 +199,22 @@ export class App extends React.Component<RouteComponentProps, {}> {
this.state.selection this.state.selection
) )
} }
onPrint={() => this.chartRef && this.chartRef.print()} onPrint={() => {
onDownloadPdf={() => this.chartRef && this.chartRef.downloadPdf()} analyticsEvent('print');
onDownloadPng={() => this.chartRef && this.chartRef.downloadPng()} this.chartRef && this.chartRef.print();
onDownloadSvg={() => this.chartRef && this.chartRef.downloadSvg()} }}
onDownloadPdf={() => {
analyticsEvent('download_pdf');
this.chartRef && this.chartRef.downloadPdf();
}}
onDownloadPng={() => {
analyticsEvent('download_png');
this.chartRef && this.chartRef.downloadPng();
}}
onDownloadSvg={() => {
analyticsEvent('download_svg');
this.chartRef && this.chartRef.downloadSvg();
}}
/> />
)} )}
/> />

View File

@@ -163,3 +163,11 @@ export function convertGedcom(
gedcom: prepareGedcom(entries), gedcom: prepareGedcom(entries),
}; };
} }
export function getSoftware(head: GedcomEntry): string | null {
const sour =
head && head.tree && head.tree.find((entry) => entry.tag === 'SOUR');
const name =
sour && sour.tree && sour.tree.find((entry) => entry.tag === 'NAME');
return (name && name.data) || null;
}

View File

@@ -1,6 +1,7 @@
import * as queryString from 'query-string'; import * as queryString from 'query-string';
import * as React from 'react'; import * as React from 'react';
import md5 from 'md5'; import md5 from 'md5';
import {analyticsEvent} from './analytics';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
import {Link} from 'react-router-dom'; import {Link} from 'react-router-dom';
import {RouteComponentProps} from 'react-router-dom'; import {RouteComponentProps} from 'react-router-dom';
@@ -59,6 +60,9 @@ export class TopBar extends React.Component<
} }
const filesArray = Array.from(files); const filesArray = Array.from(files);
(event.target as HTMLInputElement).value = ''; // Reset the file input. (event.target as HTMLInputElement).value = ''; // Reset the file input.
analyticsEvent('upload_files_selected', {
event_value: files.length,
});
const gedcomFile = const gedcomFile =
files.length === 1 files.length === 1
@@ -114,6 +118,7 @@ export class TopBar extends React.Component<
}), }),
); );
if (this.state.url) { if (this.state.url) {
analyticsEvent('url_selected');
this.props.history.push({ this.props.history.push({
pathname: '/view', pathname: '/view',
search: queryString.stringify({url: this.state.url}), search: queryString.stringify({url: this.state.url}),