Refactor analytics events (#209)

* Refactor analytics.js

* Update analytics calls in app.vue

* Update analytics calls in presets.vue

* Update analytics calls in tools.vue (and app.vue)

* Update analytics calls in global.vue

* Update analytics calls in domain.vue

* Update analytics calls in setup.vue

* Add list of all events to analytics.js

* Add custom copy to clipboard that emits event

* Emit the events from the components

* Update copyright year in all files touched

* Update analytics calls in download.vue

* Update analytics calls in ssl.vue

* Update analytics calls in certbot.vue

* Update analytics calls in domain.vue

* Update analytics calls in app.vue

* Note down 'Code snippet copied' events
This commit is contained in:
Matt (IPv4) Cowley
2021-01-18 19:45:19 +00:00
committed by GitHub
parent c86fb3cf76
commit 3fdccfa68a
17 changed files with 650 additions and 113 deletions

View File

@@ -1,5 +1,5 @@
/*
Copyright 2020 DigitalOcean
Copyright 2021 DigitalOcean
This code is licensed under the MIT License.
You may obtain a copy of the License at
@@ -24,49 +24,234 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
export default (action, category, label, value, nonInteraction = false) => {
export default ({ category, action, label, value, nonInteraction }) => {
console.info('Analytics event:', { category, action, label, value, nonInteraction });
try {
const tracker = window.ga.getAll()[0];
if (tracker) {
tracker.send({
hitType: 'event',
eventCategory: category,
eventAction: action,
eventLabel: label,
eventValue: value,
nonInteraction,
});
}
// Google
window.ga('send', 'event', {
eventCategory: category,
eventAction: action,
eventLabel: label,
eventValue: value,
nonInteraction,
});
} catch (_) {
// If analytics fail, don't block anything else
}
/*try {
// gtag.js
if (window.gtag) {
window.gtag('event', action, {
event_category: category,
event_label: label,
value,
});
}
try {
// Segment
window.analytics.track(`${category} ${action}`, {
label,
value,
nonInteraction,
});
} catch (_) {
// If analytics fail, don't block anything else
}*/
/*try {
// analytics.js
if (window.ga) {
window.ga('send', {
hitType: 'event',
eventCategory: category,
eventAction: action,
eventLabel: label,
eventValue: value,
nonInteraction,
});
}
} catch (_) {
// If analytics fail, don't block anything else
}*/
}
};
/*
All analytics events in app:
# Initial language set (from browser or query param)
File: app.vue
Category: 'Language'
Action: 'Set'
Label: language pack name
Non-interaction: true
# User manually changing tool language
File: app.vue
Category: 'Language'
Action: 'Set'
Label: language pack name
Non-interaction: false
# Initial domains set (from query params)
File: app.vue
Category: 'Site'
Action: 'Added'
Value: total number of sites active in tool
Non-interaction: true
# User adding a domain
File: app.vue
Category: 'Site'
Action: 'Added'
Value: total number of sites active in tool
Non-interaction: false
# User removing a domain
File: app.vue
Category: 'Site'
Action: 'Removed'
Label: domain name being removed
Value: total number of sites active in tool after removal
# Initial split column mode (will always be disabled)
File: app.vue
Category: 'Split column'
Action: 'Disabled'
Non-interaction: true
# User changing the column mode
File: app.vue
Category: 'Split column'
Action: 'Disabled' / 'Enabled'
Non-interaction: false
# User applying a preset
File: domain_sections/presets.vue
Category: 'Preset'
Action: 'Applied'
Label: preset internal name
# User applying a preset with previous customisations
File: domain_sections/presets.vue
Category: 'Preset'
Action: 'Overwritten'
Label: preset internal name
# User resetting global settings
File: global_sections/tools.vue
Category: 'Tools'
Action: 'Global settings reset'
# User resetting a domain
File: global_sections/tools.vue
Category: 'Tools'
Action: 'Site reset'
Label: domain name being reset
# User removing a domain in the tools tab
Note: This will also trigger the regular site removal event in app.vue
File: global_sections/tools.vue
Category: 'Tools'
Action: 'Removed site'
Label: domain name being removed
# User resetting all domains
File: global_sections/tools.vue
Category: 'Tools'
Action: 'All sites reset'
Label: comma-separated list of domain names being reset
Value: total number of domains being reset
# User removing all domains
Note: This will also trigger the regular site removal event in app.vue for each domain removed
File: global_sections/tools.vue
Category: 'Tools'
Action: 'All sites removed'
Label: comma-separated list of domain names being removed
Value: total number of domains being removed
# User clicking a tab in global settings
File: global.vue
Category: 'Global'
Action: 'Tab clicked'
Label: from tab, to tab
# User clicking back in global settings
File: global.vue
Category: 'Global'
Action: 'Back clicked'
Label: from tab, to tab
# User clicking next in global settings
File: global.vue
Category: 'Global'
Action: 'Next clicked'
Label: from tab, to tab
# User clicking a tab in domain settings
File: domain.vue
Category: 'Site'
Action: 'Tab clicked'
Label: from tab, to tab
# User clicking back in domain settings
File: domain.vue
Category: 'Site'
Action: 'Back clicked'
Label: from tab, to tab
# User clicking next in domain settings
File: domain.vue
Category: 'Site'
Action: 'Next clicked'
Label: from tab, to tab
# User clicking a tab in setup
File: setup.vue
Category: 'Setup'
Action: 'Tab clicked'
Label: from tab, to tab
# User clicking back in setup
File: setup.vue
Category: 'Setup'
Action: 'Back clicked'
Label: from tab, to tab
# User clicking next in setup
File: setup.vue
Category: 'Setup'
Action: 'Next clicked'
Label: from tab, to tab
# User downloading the config
File: setup.vue
Category: 'Setup'
Action: 'Downloaded tar file'
Label: name of the tar file (incl. domain names)
Value: total number of active domains
# User copying the base64 config
File: setup.vue
Category: 'Setup'
Action: 'Copied base64 tar'
Label: name of the tar file (incl. domain names)
Value: total number of active domains
# User copying a code snippet in setup
File: setup.vue
Category: 'Setup'
Action: 'Code snippet copied'
Label: tab name: a summary of the code snippet
# User copying a config file
File: app.vue
Category: 'Config files'
Action: 'Code snippet copied'
Label: name of file without nginx directory
*/

View File

@@ -1,5 +1,5 @@
/*
Copyright 2020 DigitalOcean
Copyright 2021 DigitalOcean
This code is licensed under the MIT License.
You may obtain a copy of the License at
@@ -24,10 +24,57 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
import 'prismjs';
import Clipboard from 'clipboard';
import Prism from 'prismjs';
import 'prismjs/components/prism-nginx';
import 'prismjs/components/prism-bash';
import 'prismjs/plugins/keep-markup/prism-keep-markup';
import 'prismjs/plugins/toolbar/prism-toolbar';
import 'prismjs/plugins/toolbar/prism-toolbar.css';
import 'prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard';
// Custom copy to clipboard (based on the Prism one)
const copyToClipboard = () => {
if (!Prism.plugins.toolbar) {
console.warn('Copy to Clipboard loaded before Toolbar.');
return;
}
Prism.plugins.toolbar.registerButton('copy-to-clipboard', env => {
const linkCopy = document.createElement('button');
linkCopy.textContent = 'Copy';
const element = env.element;
const clip = new Clipboard(linkCopy, {
'text': () => element.textContent,
});
const resetText = () => {
setTimeout(() => {
linkCopy.textContent = 'Copy';
}, 5000);
};
const emitEvent = () => {
linkCopy.dispatchEvent(new CustomEvent('copied', {
bubbles: true,
detail: { text: element.textContent },
}));
};
clip.on('success', () => {
linkCopy.textContent = 'Copied!';
emitEvent();
resetText();
});
clip.on('error', () => {
const isMac = navigator.platform.includes('Mac');
linkCopy.textContent = `Press ${isMac ? 'Cmd' : 'Ctrl'}+C to copy`;
resetText();
});
return linkCopy;
});
};
copyToClipboard();