Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
036958b7
Commit
036958b7
authored
Oct 03, 2018
by
Martin Wortschack
Committed by
Tim Zallmann
Oct 03, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Resolve "Create a generic event listener for tracking clicks on GitLab.com"
parent
9b5e7122
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
125 additions
and
32 deletions
+125
-32
app/views/projects/_import_project_pane.html.haml
app/views/projects/_import_project_pane.html.haml
+14
-11
app/views/projects/_new_project_fields.html.haml
app/views/projects/_new_project_fields.html.haml
+7
-6
app/views/projects/_project_templates.html.haml
app/views/projects/_project_templates.html.haml
+1
-1
app/views/projects/new.html.haml
app/views/projects/new.html.haml
+3
-3
app/views/projects/project_templates/_built_in_templates.html.haml
.../projects/project_templates/_built_in_templates.html.haml
+4
-2
app/views/shared/_visibility_radios.html.haml
app/views/shared/_visibility_radios.html.haml
+2
-1
ee/app/assets/javascripts/pages/projects/new/index.js
ee/app/assets/javascripts/pages/projects/new/index.js
+5
-1
ee/app/assets/javascripts/projects/track_project_new.js
ee/app/assets/javascripts/projects/track_project_new.js
+7
-0
ee/app/assets/javascripts/stats.js
ee/app/assets/javascripts/stats.js
+68
-0
ee/app/views/layouts/_snowplow.html.haml
ee/app/views/layouts/_snowplow.html.haml
+2
-1
ee/app/views/projects/_new_ci_cd_only_project_pane.html.haml
ee/app/views/projects/_new_ci_cd_only_project_pane.html.haml
+4
-3
ee/app/views/projects/_new_ci_cd_only_project_tab.html.haml
ee/app/views/projects/_new_ci_cd_only_project_tab.html.haml
+2
-2
ee/app/views/projects/_project_templates.html.haml
ee/app/views/projects/_project_templates.html.haml
+1
-1
ee/changelogs/unreleased/7424-create-a-generic-event-listener-for-tracking-clicks-on-gitlab-com.yml
...eric-event-listener-for-tracking-clicks-on-gitlab-com.yml
+5
-0
No files found.
app/views/projects/_import_project_pane.html.haml
View file @
036958b7
-
active_tab
=
local_assigns
.
fetch
(
:active_tab
,
'blank'
)
-
track_label
=
local_assigns
.
fetch
(
:track_label
,
'import_project'
)
.project-import
.form-group.import-btn-container.clearfix
...
...
@@ -7,60 +8,62 @@
.import-buttons
-
if
gitlab_project_import_enabled?
.import_gitlab_project.has-tooltip
{
data:
{
container:
'body'
}
}
=
link_to
new_import_gitlab_project_path
,
class:
'btn btn_import_gitlab_project project-submit'
do
=
link_to
new_import_gitlab_project_path
,
class:
'btn btn_import_gitlab_project project-submit'
,
data:
{
track_label:
"
#{
track_label
}
"
,
track_event:
"click_button"
,
track_property:
"gitlab_export"
}
do
=
icon
(
'gitlab'
,
text:
'GitLab export'
)
-
if
github_import_enabled?
%div
=
link_to
new_import_github_path
,
class:
'btn js-import-github'
do
=
link_to
new_import_github_path
,
class:
'btn js-import-github'
,
data:
{
track_label:
"
#{
track_label
}
"
,
track_event:
"click_button"
,
track_property:
"github"
}
do
=
icon
(
'github'
,
text:
'GitHub'
)
-
if
bitbucket_import_enabled?
%div
=
link_to
status_import_bitbucket_path
,
class:
"btn import_bitbucket
#{
'how_to_import_link'
unless
bitbucket_import_configured?
}
"
do
=
link_to
status_import_bitbucket_path
,
class:
"btn import_bitbucket
#{
'how_to_import_link'
unless
bitbucket_import_configured?
}
"
,
data:
{
track_label:
"
#{
track_label
}
"
,
track_event:
"click_button"
,
track_property:
"bitbucket_cloud"
}
do
=
icon
(
'bitbucket'
,
text:
'Bitbucket Cloud'
)
-
unless
bitbucket_import_configured?
=
render
'bitbucket_import_modal'
-
if
bitbucket_server_import_enabled?
%div
=
link_to
status_import_bitbucket_server_path
,
class:
"btn import_bitbucket"
do
=
link_to
status_import_bitbucket_server_path
,
class:
"btn import_bitbucket"
,
data:
{
track_label:
"
#{
track_label
}
"
,
track_event:
"click_button"
,
track_property:
"bitbucket_server"
}
do
=
icon
(
'bitbucket-square'
,
text:
'Bitbucket Server'
)
%div
-
if
gitlab_import_enabled?
%div
=
link_to
status_import_gitlab_path
,
class:
"btn import_gitlab
#{
'how_to_import_link'
unless
gitlab_import_configured?
}
"
do
=
link_to
status_import_gitlab_path
,
class:
"btn import_gitlab
#{
'how_to_import_link'
unless
gitlab_import_configured?
}
"
,
data:
{
track_label:
"
#{
track_label
}
"
,
track_event:
"click_button"
,
track_property:
"gitlab_com"
}
do
=
icon
(
'gitlab'
,
text:
'GitLab.com'
)
-
unless
gitlab_import_configured?
=
render
'gitlab_import_modal'
-
if
google_code_import_enabled?
%div
=
link_to
new_import_google_code_path
,
class:
'btn import_google_code'
do
=
link_to
new_import_google_code_path
,
class:
'btn import_google_code'
,
data:
{
track_label:
"
#{
track_label
}
"
,
track_event:
"click_button"
,
track_property:
"google_code"
}
do
=
icon
(
'google'
,
text:
'Google Code'
)
-
if
fogbugz_import_enabled?
%div
=
link_to
new_import_fogbugz_path
,
class:
'btn import_fogbugz'
do
=
link_to
new_import_fogbugz_path
,
class:
'btn import_fogbugz'
,
data:
{
track_label:
"
#{
track_label
}
"
,
track_event:
"click_button"
,
track_property:
"fogbugz"
}
do
=
icon
(
'bug'
,
text:
'Fogbugz'
)
-
if
gitea_import_enabled?
%div
=
link_to
new_import_gitea_path
,
class:
'btn import_gitea'
do
=
link_to
new_import_gitea_path
,
class:
'btn import_gitea'
,
data:
{
track_label:
"
#{
track_label
}
"
,
track_event:
"click_button"
,
track_property:
"gitea"
}
do
=
custom_icon
(
'go_logo'
)
Gitea
-
if
git_import_enabled?
%div
%button
.btn.js-toggle-button.js-import-git-toggle-button
{
type:
"button"
,
data:
{
toggle_open_class:
'active'
}
}
%button
.btn.js-toggle-button.js-import-git-toggle-button
{
type:
"button"
,
data:
{
toggle_open_class:
'active'
,
track_label:
"#{track_label}"
,
track_event:
"click_button"
,
track_property:
"repo_url"
}
}
=
icon
(
'git'
,
text:
'Repo by URL'
)
-
if
manifest_import_enabled?
%div
=
link_to
new_import_manifest_path
,
class:
'btn import_manifest'
do
=
link_to
new_import_manifest_path
,
class:
'btn import_manifest'
,
data:
{
track_label:
"
#{
track_label
}
"
,
track_event:
"click_button"
,
track_property:
"manifest_file"
}
do
=
icon
(
'file-text-o'
,
text:
'Manifest file'
)
.js-toggle-content.toggle-import-form
{
class:
(
'hide'
if
active_tab
!=
'import'
)
}
=
form_for
@project
,
html:
{
class:
'new_project'
}
do
|
f
|
%hr
=
render
"shared/import_form"
,
f:
f
=
render
'new_project_fields'
,
f:
f
,
project_name_id:
"import-url-name"
,
hide_init_with_readme:
true
=
render
'new_project_fields'
,
f:
f
,
project_name_id:
"import-url-name"
,
hide_init_with_readme:
true
,
track_label:
track_label
app/views/projects/_new_project_fields.html.haml
View file @
036958b7
-
visibility_level
=
params
.
dig
(
:project
,
:visibility_level
)
||
default_project_visibility
-
ci_cd_only
=
local_assigns
.
fetch
(
:ci_cd_only
,
false
)
-
hide_init_with_readme
=
local_assigns
.
fetch
(
:hide_init_with_readme
,
false
)
-
track_label
=
local_assigns
.
fetch
(
:track_label
,
'blank_project'
)
.row
{
id:
project_name_id
}
=
f
.
hidden_field
:ci_cd_only
,
value:
ci_cd_only
.form-group.project-name.col-sm-12
=
f
.
label
:name
,
class:
'label-bold'
do
%span
=
_
(
"Project name"
)
=
f
.
text_field
:name
,
placeholder:
"My awesome project"
,
class:
"form-control input-lg"
,
autofocus:
true
=
f
.
text_field
:name
,
placeholder:
"My awesome project"
,
class:
"form-control input-lg"
,
autofocus:
true
,
data:
{
track_label:
"
#{
track_label
}
"
,
track_event:
"activate_form_input"
,
track_property:
"project_name"
,
track_value:
""
}
.form-group.project-path.col-sm-6
=
f
.
label
:namespace_id
,
class:
'label-bold'
do
%span
=
s_
(
"Project URL"
)
...
...
@@ -22,7 +23,7 @@
display_path:
true
,
extra_group:
namespace_id
),
{},
{
class:
'select2 js-select-namespace qa-project-namespace-select'
,
tabindex:
1
})
{
class:
'select2 js-select-namespace qa-project-namespace-select'
,
tabindex:
1
,
data:
{
track_label:
"
#{
track_label
}
"
,
track_event:
"activate_form_input"
,
track_property:
"project_path"
,
track_value:
""
}
})
-
else
.input-group-prepend.static-namespace.has-tooltip
{
title:
user_url
(
current_user
.
username
)
+
'/'
}
...
...
@@ -42,7 +43,7 @@
=
f
.
label
:description
,
class:
'label-bold'
do
Project description
%span
(optional)
=
f
.
text_area
:description
,
placeholder:
'Description format'
,
class:
"form-control"
,
rows:
3
,
maxlength:
250
=
f
.
text_area
:description
,
placeholder:
'Description format'
,
class:
"form-control"
,
rows:
3
,
maxlength:
250
,
data:
{
track_label:
"
#{
track_label
}
"
,
track_event:
"activate_form_input"
,
track_property:
"project_description"
,
track_value:
""
}
=
f
.
label
:visibility_level
,
class:
'label-bold'
do
Visibility Level
...
...
@@ -53,12 +54,12 @@
.form-group.row.initialize-with-readme-setting
%div
{
:class
=>
"col-sm-12"
}
.form-check
=
check_box_tag
'project[initialize_with_readme]'
,
'1'
,
false
,
class:
'form-check-input'
=
check_box_tag
'project[initialize_with_readme]'
,
'1'
,
false
,
class:
'form-check-input'
,
data:
{
track_label:
"
#{
track_label
}
"
,
track_event:
"activate_form_input"
,
track_property:
"init_with_readme"
}
=
label_tag
'project[initialize_with_readme]'
,
class:
'form-check-label'
do
.option-title
%strong
Initialize repository with a README
.option-description
Allows you to immediately clone this project’s repository. Skip this if you plan to push up an existing repository.
=
f
.
submit
'Create project'
,
class:
"btn btn-
success project-submit"
,
tabindex:
4
=
link_to
'Cancel'
,
dashboard_projects_path
,
class:
'btn btn-cancel'
=
f
.
submit
'Create project'
,
class:
"btn btn-
create project-submit"
,
tabindex:
4
,
data:
{
track_label:
"
#{
track_label
}
"
,
track_event:
"click_button"
,
track_property:
"create_project"
,
track_value:
""
}
=
link_to
'Cancel'
,
dashboard_projects_path
,
class:
'btn btn-cancel'
,
data:
{
track_label:
"
#{
track_label
}
"
,
track_event:
"click_button"
,
track_property:
"cancel"
}
app/views/projects/_project_templates.html.haml
View file @
036958b7
...
...
@@ -5,4 +5,4 @@
.project-fields-form
=
render
'projects/project_templates/project_fields_form'
=
render
'projects/new_project_fields'
,
f:
f
,
project_name_id:
"template-project-name"
,
hide_init_with_readme:
true
=
render
'projects/new_project_fields'
,
f:
f
,
project_name_id:
"template-project-name"
,
hide_init_with_readme:
true
,
track_label:
"create_from_template"
app/views/projects/new.html.haml
View file @
036958b7
...
...
@@ -34,15 +34,15 @@
.col-lg-9.js-toggle-container
%ul
.nav.nav-tabs.nav-links.gitlab-tabs
{
role:
'tablist'
}
%li
.nav-item
{
role:
'presentation'
}
%a
.nav-link.active
{
href:
'#blank-project-pane'
,
id:
'blank-project-tab'
,
data:
{
toggle:
'tab'
},
role:
'tab'
}
%a
.nav-link.active
{
href:
'#blank-project-pane'
,
id:
'blank-project-tab'
,
data:
{
toggle:
'tab'
,
track_label:
'blank_project'
,
track_event:
"click_tab"
},
role:
'tab'
}
%span
.d-none.d-sm-block
Blank project
%span
.d-block.d-sm-none
Blank
%li
.nav-item
{
role:
'presentation'
}
%a
.nav-link
{
href:
'#create-from-template-pane'
,
id:
'create-from-template-tab'
,
data:
{
toggle:
'tab'
},
role:
'tab'
}
%a
.nav-link
{
href:
'#create-from-template-pane'
,
id:
'create-from-template-tab'
,
data:
{
toggle:
'tab'
,
track_label:
'create_from_template'
,
track_event:
"click_tab"
},
role:
'tab'
}
%span
.d-none.d-sm-block
Create from template
%span
.d-block.d-sm-none
Template
%li
.nav-item
{
role:
'presentation'
}
%a
.nav-link
{
href:
'#import-project-pane'
,
id:
'import-project-tab'
,
data:
{
toggle:
'tab'
},
role:
'tab'
}
%a
.nav-link
{
href:
'#import-project-pane'
,
id:
'import-project-tab'
,
data:
{
toggle:
'tab'
,
track_label:
'import_project'
,
track_event:
"click_tab"
},
role:
'tab'
}
%span
.d-none.d-sm-block
Import project
%span
.d-block.d-sm-none
Import
-# EE-specific start
...
...
app/views/projects/project_templates/_built_in_templates.html.haml
View file @
036958b7
...
...
@@ -10,8 +10,10 @@
=
template
.
description
.controls.d-flex.align-items-center
%label
.btn.btn-success.template-button.choose-template.append-right-10.append-bottom-0
{
for:
template
.
name
}
%input
{
type:
"radio"
,
autocomplete:
"off"
,
name:
"project[template_name]"
,
id:
template
.
name
,
value:
template
.
name
}
%input
{
type:
"radio"
,
autocomplete:
"off"
,
name:
"project[template_name]"
,
id:
template
.
name
,
value:
template
.
name
,
data:
{
track_label:
"create_from_template"
,
track_property:
"template_use"
,
track_event:
"click_button"
}
}
%span
=
_
(
"Use template"
)
%a
.btn.btn-default
{
href:
template
.
preview
,
rel:
'noopener noreferrer'
,
target:
'_blank'
}
%a
.btn.btn-default
{
href:
template
.
preview
,
rel:
'noopener noreferrer'
,
target:
'_blank'
,
data:
{
track_label:
"create_from_template"
,
track_property:
"template_preview"
,
track_event:
"click_button"
,
track_value:
template
.
name
}
}
=
_
(
"Preview"
)
app/views/shared/_visibility_radios.html.haml
View file @
036958b7
...
...
@@ -3,7 +3,8 @@
-
restricted
=
restricted_visibility_levels
.
include?
(
level
)
-
disabled
=
disallowed
||
restricted
.form-check
{
class:
[(
'disabled'
if
disabled
),
(
'restricted'
if
restricted
)]
}
=
form
.
radio_button
model_method
,
level
,
checked:
(
selected_level
==
level
),
disabled:
disabled
,
class:
'form-check-input'
=
form
.
radio_button
model_method
,
level
,
checked:
(
selected_level
==
level
),
disabled:
disabled
,
class:
'form-check-input'
,
data:
{
track_label:
"blank_project"
,
track_event:
"activate_form_input"
,
track_property:
"
#{
model_method
}
"
,
track_value:
"
#{
level
}
"
}
=
form
.
label
"
#{
model_method
}
_
#{
level
}
"
,
class:
'form-check-label'
do
=
visibility_level_icon
(
level
)
.option-title
...
...
ee/app/assets/javascripts/pages/projects/new/index.js
View file @
036958b7
import
'
~/pages/projects/new/index
'
;
import
initCustomProjectTemplates
from
'
ee/projects/custom_project_templates
'
;
import
bindTrackEvents
from
'
ee/projects/track_project_new
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
initCustomProjectTemplates
);
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
initCustomProjectTemplates
();
bindTrackEvents
(
'
.js-toggle-container
'
);
});
ee/app/assets/javascripts/projects/track_project_new.js
0 → 100644
View file @
036958b7
import
Stats
from
'
ee/stats
'
;
const
bindTrackEvents
=
(
container
)
=>
{
Stats
.
bindTrackableContainer
(
container
);
};
export
default
bindTrackEvents
;
ee/app/assets/javascripts/stats.js
0 → 100644
View file @
036958b7
import
$
from
'
jquery
'
;
const
snowPlowEnabled
=
()
=>
typeof
window
.
snowplow
===
'
function
'
;
const
trackEvent
=
(
category
,
eventName
,
additionalData
=
{
label
:
''
,
property
:
''
,
value
:
''
})
=>
{
if
(
!
snowPlowEnabled
())
{
return
;
}
if
(
!
category
||
!
eventName
)
{
return
;
}
const
{
label
,
property
,
value
}
=
additionalData
;
try
{
window
.
snowplow
(
'
trackStructEvent
'
,
category
,
eventName
,
label
,
property
,
value
,
);
}
catch
(
e
)
{
// do nothing
}
};
const
bindTrackableContainer
=
(
container
=
''
,
category
=
document
.
body
.
dataset
.
page
)
=>
{
if
(
!
snowPlowEnabled
())
{
return
;
}
const
clickHandler
=
(
e
)
=>
{
const
target
=
e
.
currentTarget
;
const
label
=
target
.
getAttribute
(
'
data-track-label
'
);
const
property
=
target
.
getAttribute
(
'
data-track-property
'
)
||
''
;
const
eventName
=
target
.
getAttribute
(
'
data-track-event
'
);
let
value
=
target
.
value
||
''
;
// overrides value for checkboxes
if
(
target
.
type
===
'
checkbox
'
)
{
value
=
target
.
checked
;
}
// overrides value if data-track_value is set
if
(
typeof
target
.
getAttribute
(
'
data-track-value
'
)
!==
'
undefined
'
&&
target
.
getAttribute
(
'
data-track-value
'
)
!==
null
)
{
value
=
target
.
getAttribute
(
'
data-track-value
'
);
}
trackEvent
(
category
,
eventName
,
{
label
,
property
,
value
});
};
const
trackableElements
=
document
.
querySelectorAll
(
`
${
container
}
[data-track-label]`
);
trackableElements
.
forEach
(
element
=>
{
element
.
addEventListener
(
'
click
'
,
(
e
)
=>
clickHandler
(
e
));
});
// jquery required for select2 events
// see: https://github.com/select2/select2/issues/4686#issuecomment-264747428
$
(
`
${
container
}
.select2[data-track-label]`
).
on
(
'
click
'
,
(
e
)
=>
clickHandler
(
e
));
};
export
default
{
trackEvent
,
bindTrackableContainer
,
};
ee/app/views/layouts/_snowplow.html.haml
View file @
036958b7
...
...
@@ -14,7 +14,8 @@
post
:
true
,
contexts
:
{
webPage
:
true
,
}
},
stateStorageStrategy
:
"
localStorage
"
});
window
.
snowplow
(
'
enableActivityTracking
'
,
30
,
30
);
...
...
ee/app/views/projects/_new_ci_cd_only_project_pane.html.haml
View file @
036958b7
-
return
unless
ci_cd_projects_available?
-
track_label
=
local_assigns
.
fetch
(
:track_label
,
'cicd_for_external_repo'
)
.tab-pane.js-toggle-container
{
id:
'ci-cd-project-pane'
,
class:
active_when
(
active_tab
==
'ci_cd_only'
),
role:
'tabpanel'
}
=
form_for
@project
,
html:
{
class:
'new_project'
}
do
|
f
|
...
...
@@ -18,14 +19,14 @@
.import-buttons
%div
-
if
github_import_enabled?
=
link_to
new_import_github_path
(
ci_cd_only:
true
),
class:
'btn js-import-github'
do
=
link_to
new_import_github_path
(
ci_cd_only:
true
),
class:
'btn js-import-github'
,
data:
{
track_label:
"
#{
track_label
}
"
,
track_property:
'github'
,
track_event:
"click_button"
}
do
=
icon
(
'github'
,
text:
'GitHub'
)
%div
-
if
git_import_enabled?
%button
.btn.js-toggle-button.js-import-git-toggle-button
{
type:
"button"
,
data:
{
toggle_open_class:
'active'
}
}
%button
.btn.js-toggle-button.js-import-git-toggle-button
{
type:
"button"
,
data:
{
toggle_open_class:
'active'
,
track_label:
"#{track_label}"
,
track_property:
'repo_url'
,
track_event:
"click_button"
}
}
=
icon
(
'git'
,
text:
_
(
'Repo by URL'
))
.col-lg-12
.js-toggle-content.toggle-import-form
{
class:
(
'hide'
if
active_tab
!=
'ci_cd_only'
)
}
%hr
=
render
"shared/import_form"
,
f:
f
,
ci_cd_only:
true
=
render
'new_project_fields'
,
f:
f
,
project_name_id:
"import-url-name"
,
ci_cd_only:
true
,
hide_init_with_readme:
true
=
render
'new_project_fields'
,
f:
f
,
project_name_id:
"import-url-name"
,
ci_cd_only:
true
,
hide_init_with_readme:
true
,
track_label:
track_label
ee/app/views/projects/_new_ci_cd_only_project_tab.html.haml
View file @
036958b7
-
return
unless
ci_cd_projects_available?
%li
{
class:
active_when
(
active_tab
==
'ci_cd_only'
),
role:
'presentation'
}
%a
{
href:
'#ci-cd-project-pane'
,
id:
'ci-cd-project-tab'
,
data:
{
toggle:
'tab'
},
role:
'tab'
}
%li
.nav-item
{
class:
active_when
(
active_tab
==
'ci_cd_only'
),
role:
'presentation'
}
%a
.nav-link
{
href:
'#ci-cd-project-pane'
,
id:
'ci-cd-project-tab'
,
data:
{
toggle:
'tab'
,
track_label:
'cicd_for_external_repo'
,
track_event:
"click_tab"
},
role:
'tab'
}
%span
.d-none.d-sm-block
=
_
(
'CI/CD for external repo'
)
%span
.d-block.d-sm-none
...
...
ee/app/views/projects/_project_templates.html.haml
View file @
036958b7
...
...
@@ -21,7 +21,7 @@
.project-fields-form
=
render
'projects/project_templates/project_fields_form'
=
f
.
hidden_field
(
:use_custom_template
,
value:
false
)
=
render
'projects/new_project_fields'
,
f:
f
,
project_name_id:
"template-project-name"
,
hide_init_with_readme:
true
=
render
'projects/new_project_fields'
,
f:
f
,
project_name_id:
"template-project-name"
,
hide_init_with_readme:
true
,
track_label:
"create_from_template"
-
else
=
render_ce
'projects/project_templates'
,
f:
f
ee/changelogs/unreleased/7424-create-a-generic-event-listener-for-tracking-clicks-on-gitlab-com.yml
0 → 100644
View file @
036958b7
---
title
:
Create a generic JS function that we can apply to being able to track arbitrary events
merge_request
:
7403
author
:
type
:
other
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment