From 4265f5b48f4ff8604b3163def81c10adbe0f9c3b Mon Sep 17 00:00:00 2001 From: "Mark L. Chang" Date: Wed, 3 Apr 2013 22:07:23 -0400 Subject: [PATCH 01/17] studio: added segment.io tracking --- cms/envs/aws.py | 2 ++ cms/envs/common.py | 3 ++- cms/envs/dev.py | 3 +++ cms/templates/base.html | 2 ++ cms/templates/widgets/segment-io.html | 16 ++++++++++++++++ 5 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 cms/templates/widgets/segment-io.html diff --git a/cms/envs/aws.py b/cms/envs/aws.py index be7816d21f..ef69c51d12 100644 --- a/cms/envs/aws.py +++ b/cms/envs/aws.py @@ -46,6 +46,8 @@ SESSION_COOKIE_DOMAIN = ENV_TOKENS.get('SESSION_COOKIE_DOMAIN') for feature, value in ENV_TOKENS.get('MITX_FEATURES', {}).items(): MITX_FEATURES[feature] = value +SEGMENT_IO_KEY = ENV_TOKENS.get('SEGMENT_IO_KEY') + LOGGING = get_logger_config(LOG_DIR, logging_env=ENV_TOKENS['LOGGING_ENV'], syslog_addr=(ENV_TOKENS['SYSLOG_SERVER'], 514), diff --git a/cms/envs/common.py b/cms/envs/common.py index 5ad9068636..adf5add063 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -34,7 +34,8 @@ MITX_FEATURES = { 'ENABLE_DISCUSSION_SERVICE': False, 'AUTH_USE_MIT_CERTIFICATES': False, 'STUB_VIDEO_FOR_TESTING': False, # do not display video when running automated acceptance tests - 'STUDIO_NPS_SURVEY': True, + 'STUDIO_NPS_SURVEY': True, + 'SEGMENT_IO': True, } ENABLE_JASMINE = False diff --git a/cms/envs/dev.py b/cms/envs/dev.py index ae78b93f06..5489d2d733 100644 --- a/cms/envs/dev.py +++ b/cms/envs/dev.py @@ -150,3 +150,6 @@ DEBUG_TOOLBAR_MONGO_STACKTRACES = True # disable NPS survey in dev mode MITX_FEATURES['STUDIO_NPS_SURVEY'] = False + +# segment-io key for dev +SEGMENT_IO_KEY = 'mty8edrrsg' \ No newline at end of file diff --git a/cms/templates/base.html b/cms/templates/base.html index 15f4c556bb..e4f5befd63 100644 --- a/cms/templates/base.html +++ b/cms/templates/base.html @@ -23,6 +23,8 @@ + <%include file="widgets/segment-io.html" /> + <%block name="header_extras"> diff --git a/cms/templates/widgets/segment-io.html b/cms/templates/widgets/segment-io.html new file mode 100644 index 0000000000..1ccee8cff1 --- /dev/null +++ b/cms/templates/widgets/segment-io.html @@ -0,0 +1,16 @@ +% if settings.MITX_FEATURES.get('SEGMENT_IO'): + + + +% endif \ No newline at end of file From 2e482127151edc697e1d8b9013608d6a238dba5c Mon Sep 17 00:00:00 2001 From: "Mark L. Chang" Date: Wed, 3 Apr 2013 22:21:18 -0400 Subject: [PATCH 02/17] newline --- cms/envs/dev.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cms/envs/dev.py b/cms/envs/dev.py index 5489d2d733..dbf9c5574c 100644 --- a/cms/envs/dev.py +++ b/cms/envs/dev.py @@ -152,4 +152,4 @@ DEBUG_TOOLBAR_MONGO_STACKTRACES = True MITX_FEATURES['STUDIO_NPS_SURVEY'] = False # segment-io key for dev -SEGMENT_IO_KEY = 'mty8edrrsg' \ No newline at end of file +SEGMENT_IO_KEY = 'mty8edrrsg' From 1ce2affdd2f8ce267a842f5425fba3da5401570e Mon Sep 17 00:00:00 2001 From: "Mark L. Chang" Date: Wed, 3 Apr 2013 23:45:05 -0400 Subject: [PATCH 03/17] outline page event tracking --- cms/static/js/base.js | 48 ++++++++++++++++++++++++++- cms/templates/widgets/segment-io.html | 7 +++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/cms/static/js/base.js b/cms/static/js/base.js index 6ea918cc36..7b930a176b 100644 --- a/cms/static/js/base.js +++ b/cms/static/js/base.js @@ -331,6 +331,12 @@ function createNewUnit(e) { var parent = $(this).data('parent'); var template = $(this).data('template'); + analytics.track('Created a Unit', { + 'course': course_location_analytics, + 'parent_location': parent + }); + + $.post('/clone_item', {'parent_location': parent, 'template': template, @@ -363,6 +369,12 @@ function _deleteItem($el) { var id = $el.data('id'); + analytics.track('Deleted an Item', { + 'course': course_location_analytics, + 'id': id + }); + + $.post('/delete_item', {'id': id, 'delete_children': true, 'delete_all_versions': true}, function (data) { @@ -426,6 +438,11 @@ function displayFinishedUpload(xhr) { var html = Mustache.to_html(template, resp); $('table > tbody').prepend(html); + analytics.track('Uploaded a File', { + 'course': course_location_analytics, + 'asset_url': resp.url + }); + } function markAsLoaded() { @@ -555,6 +572,11 @@ function saveNewSection(e) { var template = $saveButton.data('template'); var display_name = $(this).find('.new-section-name').val(); + analytics.track('Created a Section', { + 'course': course_location_analytics, + 'display_name': display_name + }); + $.post('/clone_item', { 'parent_location': parent, 'template': template, @@ -600,6 +622,12 @@ function saveNewCourse(e) { return; } + analytics.track('Created a Course', { + 'org': org, + 'number': number, + 'display_name': display_name + }); + $.post('/create_new_course', { 'template': template, 'org': org, @@ -646,9 +674,14 @@ function saveNewSubsection(e) { var parent = $(this).find('.new-subsection-name-save').data('parent'); var template = $(this).find('.new-subsection-name-save').data('template'); - var display_name = $(this).find('.new-subsection-name-input').val(); + analytics.track('Created a Subsection', { + 'course': course_location_analytics, + 'display_name': display_name + }); + + $.post('/clone_item', { 'parent_location': parent, 'template': template, @@ -702,6 +735,13 @@ function saveEditSectionName(e) { return; } + analytics.track('Edited Section Name', { + 'course': course_location_analytics, + 'display_name': display_name, + 'id': id + }); + + var $_this = $(this); // call into server to commit the new order $.ajax({ @@ -741,6 +781,12 @@ function saveSetSectionScheduleDate(e) { var id = $modal.attr('data-id'); + analytics.track('Edited Section Release Date', { + 'course': course_location_analytics, + 'id': id, + 'start': start + }); + // call into server to commit the new order $.ajax({ url: "/save_item", diff --git a/cms/templates/widgets/segment-io.html b/cms/templates/widgets/segment-io.html index 1ccee8cff1..7d00c731b0 100644 --- a/cms/templates/widgets/segment-io.html +++ b/cms/templates/widgets/segment-io.html @@ -1,6 +1,11 @@ % if settings.MITX_FEATURES.get('SEGMENT_IO'): -% endif \ No newline at end of file +% endif From c6f8b32dd44bcec58b01b23db3b9cc90154d8d12 Mon Sep 17 00:00:00 2001 From: "Mark L. Chang" Date: Thu, 4 Apr 2013 00:34:37 -0400 Subject: [PATCH 04/17] added event tracking to static pages --- cms/static/coffee/src/views/module_edit.coffee | 7 ++++++- cms/static/coffee/src/views/tabs.coffee | 12 ++++++++++++ cms/static/js/views/course_info_edit.js | 15 +++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/cms/static/coffee/src/views/module_edit.coffee b/cms/static/coffee/src/views/module_edit.coffee index 9f7e3a5e60..3cb3b1703f 100644 --- a/cms/static/coffee/src/views/module_edit.coffee +++ b/cms/static/coffee/src/views/module_edit.coffee @@ -15,7 +15,7 @@ class CMS.Views.ModuleEdit extends Backbone.View $component_editor: => @$el.find('.component-editor') loadDisplay: -> - XModule.loadModule(@$el.find('.xmodule_display')) + XModule.loadModule(@$el.find('.xmodule_display')) loadEdit: -> if not @module @@ -55,6 +55,11 @@ class CMS.Views.ModuleEdit extends Backbone.View clickSaveButton: (event) => event.preventDefault() data = @module.save() + + analytics.track "Saved Module", + course: course_location_analytics + id: _this.model.id + data.metadata = _.extend(data.metadata || {}, @metadata()) @hideModal() @model.save(data).done( => diff --git a/cms/static/coffee/src/views/tabs.coffee b/cms/static/coffee/src/views/tabs.coffee index 9fbe4e5789..1034fc988e 100644 --- a/cms/static/coffee/src/views/tabs.coffee +++ b/cms/static/coffee/src/views/tabs.coffee @@ -28,6 +28,10 @@ class CMS.Views.TabsEdit extends Backbone.View @$('.component').each((idx, element) => tabs.push($(element).data('id')) ) + + analytics.track "Reordered Static Pages", + course: course_location_analytics + $.ajax({ type:'POST', url: '/reorder_static_tabs', @@ -56,10 +60,18 @@ class CMS.Views.TabsEdit extends Backbone.View 'i4x://edx/templates/static_tab/Empty' ) + analytics.track "Added Static Page", + course: course_location_analytics + deleteTab: (event) => if not confirm 'Are you sure you want to delete this component? This action cannot be undone.' return $component = $(event.currentTarget).parents('.component') + + analytics.track "Deleted Static Page", + course: course_location_analytics + id: $component.data('id') + $.post('/delete_item', { id: $component.data('id') }, => diff --git a/cms/static/js/views/course_info_edit.js b/cms/static/js/views/course_info_edit.js index ce959fd443..a6d42e1927 100644 --- a/cms/static/js/views/course_info_edit.js +++ b/cms/static/js/views/course_info_edit.js @@ -107,6 +107,11 @@ CMS.Views.ClassInfoUpdateView = Backbone.View.extend({ // push change to display, hide the editor, submit the change targetModel.save({}, {error : CMS.ServerError}); this.closeEditor(this); + + analytics.track('Saved Course Update', { + 'course': course_location_analytics, + 'date': this.dateEntry(event).val() + }); }, onCancel: function(event) { @@ -147,6 +152,11 @@ CMS.Views.ClassInfoUpdateView = Backbone.View.extend({ return; } + analytics.track('Deleted Course Update', { + 'course': course_location_analytics, + 'date': this.dateEntry(event).val() + }); + var targetModel = this.eventModel(event); this.modelDom(event).remove(); var cacheThis = this; @@ -284,6 +294,11 @@ CMS.Views.ClassInfoHandoutsView = Backbone.View.extend({ this.model.save({}, {error: CMS.ServerError}); this.$form.hide(); this.closeEditor(this); + + analytics.track('Saved Course Handouts', { + 'course': course_location_analytics + }); + }, onCancel: function(event) { From bab42b1cce9aff0ab45a63f4c268b1d8d50d9fdf Mon Sep 17 00:00:00 2001 From: "Mark L. Chang" Date: Thu, 4 Apr 2013 00:40:06 -0400 Subject: [PATCH 05/17] instrumented advanced settings --- cms/static/js/views/settings/advanced_view.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cms/static/js/views/settings/advanced_view.js b/cms/static/js/views/settings/advanced_view.js index e3ff098efb..52c5ed78d0 100644 --- a/cms/static/js/views/settings/advanced_view.js +++ b/cms/static/js/views/settings/advanced_view.js @@ -137,6 +137,10 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({ success : function() { self.render(); self.showMessage(self.successful_changes); + analytics.track('Saved Advanced Settings', { + 'course': course_location_analytics + }); + }, error : CMS.ServerError }); From 405b18618cbd5a88dc59945cbca2418b54988872 Mon Sep 17 00:00:00 2001 From: "Mark L. Chang" Date: Thu, 4 Apr 2013 00:49:09 -0400 Subject: [PATCH 06/17] instrumented checklists --- cms/static/js/views/checklists_view.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cms/static/js/views/checklists_view.js b/cms/static/js/views/checklists_view.js index e553c7a2ca..85c0f5242b 100644 --- a/cms/static/js/views/checklists_view.js +++ b/cms/static/js/views/checklists_view.js @@ -77,11 +77,18 @@ CMS.Views.Checklists = Backbone.View.extend({ var task_index = $checkbox.data('task'); var model = this.collection.at(checklist_index); model.attributes.items[task_index].is_checked = $task.hasClass(completed); + model.save({}, { success : function() { var updatedTemplate = self.renderTemplate(model, checklist_index); self.$el.find('#course-checklist'+checklist_index).first().replaceWith(updatedTemplate); + + analytics.track('Toggled a Checklist Task', { + 'course': course_location_analytics, + 'task': model.attributes.items[task_index].short_description, + 'state': model.attributes.items[task_index].is_checked + }); }, error : CMS.ServerError }); From 587402cddc6aeab0298e0680e80379c5d5766039 Mon Sep 17 00:00:00 2001 From: "Mark L. Chang" Date: Thu, 4 Apr 2013 01:47:37 -0400 Subject: [PATCH 07/17] added tracking to unit page and components --- cms/static/coffee/src/views/unit.coffee | 38 +++++++++++++++++++++++++ cms/templates/unit.html | 1 + 2 files changed, 39 insertions(+) diff --git a/cms/static/coffee/src/views/unit.coffee b/cms/static/coffee/src/views/unit.coffee index 42127b2800..e23477ccfa 100644 --- a/cms/static/coffee/src/views/unit.coffee +++ b/cms/static/coffee/src/views/unit.coffee @@ -35,6 +35,10 @@ class CMS.Views.UnitEdit extends Backbone.View @$('.components').sortable( handle: '.drag-handle' update: (event, ui) => + analytics.track "Reordered Components", + course: course_location_analytics + id: unit_location_analytics + payload = children : @components() options = success : => @model.unset('children') @model.save(payload, options) @@ -89,6 +93,11 @@ class CMS.Views.UnitEdit extends Backbone.View $(event.currentTarget).data('location') ) + analytics.track "Added a Component", + course: course_location_analytics + unit_id: unit_location_analytics + type: $(event.currentTarget).data('location') + @closeNewComponent(event) components: => @$('.component').map((idx, el) -> $(el).data('id')).get() @@ -111,6 +120,11 @@ class CMS.Views.UnitEdit extends Backbone.View $.post('/delete_item', { id: $component.data('id') }, => + analytics.track "Deleted a Component", + course: course_location_analytics + unit_id: unit_location_analytics + id: $component.data('id') + $component.remove() # b/c we don't vigilantly keep children up to date # get rid of it before it hurts someone @@ -129,6 +143,10 @@ class CMS.Views.UnitEdit extends Backbone.View id: @$el.data('id') delete_children: true }, => + analytics.track "Deleted Draft", + course: course_location_analytics + unit_id: unit_location_analytics + window.location.reload() ) @@ -138,6 +156,10 @@ class CMS.Views.UnitEdit extends Backbone.View $.post('/create_draft', { id: @$el.data('id') }, => + analytics.track "Created Draft", + course: course_location_analytics + unit_id: unit_location_analytics + @model.set('state', 'draft') ) @@ -148,20 +170,31 @@ class CMS.Views.UnitEdit extends Backbone.View $.post('/publish_draft', { id: @$el.data('id') }, => + analytics.track "Published Draft", + course: course_location_analytics + unit_id: unit_location_analytics + @model.set('state', 'public') ) setVisibility: (event) -> if @$('.visibility-select').val() == 'private' target_url = '/unpublish_unit' + visibility = "private" else target_url = '/publish_draft' + visibility = "public" @wait(true) $.post(target_url, { id: @$el.data('id') }, => + analytics.track "Set Unit Visibility", + course: course_location_analytics + unit_id: unit_location_analytics + visibility: visibility + @model.set('state', @$('.visibility-select').val()) ) @@ -193,6 +226,11 @@ class CMS.Views.UnitEdit.NameEdit extends Backbone.View @model.save(metadata: metadata) # Update name shown in the right-hand side location summary. $('.unit-location .editing .unit-name').html(metadata.display_name) + analytics.track "Edited Unit Name", + course: course_location_analytics + unit_id: unit_location_analytics + display_name: metadata.display_name + class CMS.Views.UnitEdit.LocationState extends Backbone.View initialize: => diff --git a/cms/templates/unit.html b/cms/templates/unit.html index e1a020dfca..1b9e49620b 100644 --- a/cms/templates/unit.html +++ b/cms/templates/unit.html @@ -28,6 +28,7 @@ }); }); + var unit_location_analytics = '${unit_location}'; From 8439013f64b2b0738c55fe7bde2f59f7d3478a3c Mon Sep 17 00:00:00 2001 From: "Mark L. Chang" Date: Wed, 3 Apr 2013 22:07:23 -0400 Subject: [PATCH 08/17] studio: added segment.io tracking --- cms/envs/aws.py | 2 ++ cms/envs/common.py | 3 ++- cms/envs/dev.py | 3 +++ cms/templates/base.html | 2 ++ cms/templates/widgets/segment-io.html | 16 ++++++++++++++++ 5 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 cms/templates/widgets/segment-io.html diff --git a/cms/envs/aws.py b/cms/envs/aws.py index be7816d21f..ef69c51d12 100644 --- a/cms/envs/aws.py +++ b/cms/envs/aws.py @@ -46,6 +46,8 @@ SESSION_COOKIE_DOMAIN = ENV_TOKENS.get('SESSION_COOKIE_DOMAIN') for feature, value in ENV_TOKENS.get('MITX_FEATURES', {}).items(): MITX_FEATURES[feature] = value +SEGMENT_IO_KEY = ENV_TOKENS.get('SEGMENT_IO_KEY') + LOGGING = get_logger_config(LOG_DIR, logging_env=ENV_TOKENS['LOGGING_ENV'], syslog_addr=(ENV_TOKENS['SYSLOG_SERVER'], 514), diff --git a/cms/envs/common.py b/cms/envs/common.py index 5ad9068636..adf5add063 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -34,7 +34,8 @@ MITX_FEATURES = { 'ENABLE_DISCUSSION_SERVICE': False, 'AUTH_USE_MIT_CERTIFICATES': False, 'STUB_VIDEO_FOR_TESTING': False, # do not display video when running automated acceptance tests - 'STUDIO_NPS_SURVEY': True, + 'STUDIO_NPS_SURVEY': True, + 'SEGMENT_IO': True, } ENABLE_JASMINE = False diff --git a/cms/envs/dev.py b/cms/envs/dev.py index ae78b93f06..5489d2d733 100644 --- a/cms/envs/dev.py +++ b/cms/envs/dev.py @@ -150,3 +150,6 @@ DEBUG_TOOLBAR_MONGO_STACKTRACES = True # disable NPS survey in dev mode MITX_FEATURES['STUDIO_NPS_SURVEY'] = False + +# segment-io key for dev +SEGMENT_IO_KEY = 'mty8edrrsg' \ No newline at end of file diff --git a/cms/templates/base.html b/cms/templates/base.html index 15f4c556bb..e4f5befd63 100644 --- a/cms/templates/base.html +++ b/cms/templates/base.html @@ -23,6 +23,8 @@ + <%include file="widgets/segment-io.html" /> + <%block name="header_extras"> diff --git a/cms/templates/widgets/segment-io.html b/cms/templates/widgets/segment-io.html new file mode 100644 index 0000000000..1ccee8cff1 --- /dev/null +++ b/cms/templates/widgets/segment-io.html @@ -0,0 +1,16 @@ +% if settings.MITX_FEATURES.get('SEGMENT_IO'): + + + +% endif \ No newline at end of file From d9bbed305ef610672f366df522d9caf26d0e1c0e Mon Sep 17 00:00:00 2001 From: "Mark L. Chang" Date: Wed, 3 Apr 2013 22:21:18 -0400 Subject: [PATCH 09/17] newline --- cms/envs/dev.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cms/envs/dev.py b/cms/envs/dev.py index 5489d2d733..dbf9c5574c 100644 --- a/cms/envs/dev.py +++ b/cms/envs/dev.py @@ -152,4 +152,4 @@ DEBUG_TOOLBAR_MONGO_STACKTRACES = True MITX_FEATURES['STUDIO_NPS_SURVEY'] = False # segment-io key for dev -SEGMENT_IO_KEY = 'mty8edrrsg' \ No newline at end of file +SEGMENT_IO_KEY = 'mty8edrrsg' From 64b7603d37dc3b765acf30101819f44e68696f87 Mon Sep 17 00:00:00 2001 From: "Mark L. Chang" Date: Wed, 3 Apr 2013 23:45:05 -0400 Subject: [PATCH 10/17] outline page event tracking --- cms/static/js/base.js | 48 ++++++++++++++++++++++++++- cms/templates/widgets/segment-io.html | 7 +++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/cms/static/js/base.js b/cms/static/js/base.js index 6ea918cc36..7b930a176b 100644 --- a/cms/static/js/base.js +++ b/cms/static/js/base.js @@ -331,6 +331,12 @@ function createNewUnit(e) { var parent = $(this).data('parent'); var template = $(this).data('template'); + analytics.track('Created a Unit', { + 'course': course_location_analytics, + 'parent_location': parent + }); + + $.post('/clone_item', {'parent_location': parent, 'template': template, @@ -363,6 +369,12 @@ function _deleteItem($el) { var id = $el.data('id'); + analytics.track('Deleted an Item', { + 'course': course_location_analytics, + 'id': id + }); + + $.post('/delete_item', {'id': id, 'delete_children': true, 'delete_all_versions': true}, function (data) { @@ -426,6 +438,11 @@ function displayFinishedUpload(xhr) { var html = Mustache.to_html(template, resp); $('table > tbody').prepend(html); + analytics.track('Uploaded a File', { + 'course': course_location_analytics, + 'asset_url': resp.url + }); + } function markAsLoaded() { @@ -555,6 +572,11 @@ function saveNewSection(e) { var template = $saveButton.data('template'); var display_name = $(this).find('.new-section-name').val(); + analytics.track('Created a Section', { + 'course': course_location_analytics, + 'display_name': display_name + }); + $.post('/clone_item', { 'parent_location': parent, 'template': template, @@ -600,6 +622,12 @@ function saveNewCourse(e) { return; } + analytics.track('Created a Course', { + 'org': org, + 'number': number, + 'display_name': display_name + }); + $.post('/create_new_course', { 'template': template, 'org': org, @@ -646,9 +674,14 @@ function saveNewSubsection(e) { var parent = $(this).find('.new-subsection-name-save').data('parent'); var template = $(this).find('.new-subsection-name-save').data('template'); - var display_name = $(this).find('.new-subsection-name-input').val(); + analytics.track('Created a Subsection', { + 'course': course_location_analytics, + 'display_name': display_name + }); + + $.post('/clone_item', { 'parent_location': parent, 'template': template, @@ -702,6 +735,13 @@ function saveEditSectionName(e) { return; } + analytics.track('Edited Section Name', { + 'course': course_location_analytics, + 'display_name': display_name, + 'id': id + }); + + var $_this = $(this); // call into server to commit the new order $.ajax({ @@ -741,6 +781,12 @@ function saveSetSectionScheduleDate(e) { var id = $modal.attr('data-id'); + analytics.track('Edited Section Release Date', { + 'course': course_location_analytics, + 'id': id, + 'start': start + }); + // call into server to commit the new order $.ajax({ url: "/save_item", diff --git a/cms/templates/widgets/segment-io.html b/cms/templates/widgets/segment-io.html index 1ccee8cff1..7d00c731b0 100644 --- a/cms/templates/widgets/segment-io.html +++ b/cms/templates/widgets/segment-io.html @@ -1,6 +1,11 @@ % if settings.MITX_FEATURES.get('SEGMENT_IO'): -% endif \ No newline at end of file +% endif From 22bd8da1f2e4a84f45101da61222e687987bb1b2 Mon Sep 17 00:00:00 2001 From: "Mark L. Chang" Date: Thu, 4 Apr 2013 00:34:37 -0400 Subject: [PATCH 11/17] added event tracking to static pages --- cms/static/coffee/src/views/module_edit.coffee | 7 ++++++- cms/static/coffee/src/views/tabs.coffee | 12 ++++++++++++ cms/static/js/views/course_info_edit.js | 15 +++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/cms/static/coffee/src/views/module_edit.coffee b/cms/static/coffee/src/views/module_edit.coffee index 9f7e3a5e60..3cb3b1703f 100644 --- a/cms/static/coffee/src/views/module_edit.coffee +++ b/cms/static/coffee/src/views/module_edit.coffee @@ -15,7 +15,7 @@ class CMS.Views.ModuleEdit extends Backbone.View $component_editor: => @$el.find('.component-editor') loadDisplay: -> - XModule.loadModule(@$el.find('.xmodule_display')) + XModule.loadModule(@$el.find('.xmodule_display')) loadEdit: -> if not @module @@ -55,6 +55,11 @@ class CMS.Views.ModuleEdit extends Backbone.View clickSaveButton: (event) => event.preventDefault() data = @module.save() + + analytics.track "Saved Module", + course: course_location_analytics + id: _this.model.id + data.metadata = _.extend(data.metadata || {}, @metadata()) @hideModal() @model.save(data).done( => diff --git a/cms/static/coffee/src/views/tabs.coffee b/cms/static/coffee/src/views/tabs.coffee index 9fbe4e5789..1034fc988e 100644 --- a/cms/static/coffee/src/views/tabs.coffee +++ b/cms/static/coffee/src/views/tabs.coffee @@ -28,6 +28,10 @@ class CMS.Views.TabsEdit extends Backbone.View @$('.component').each((idx, element) => tabs.push($(element).data('id')) ) + + analytics.track "Reordered Static Pages", + course: course_location_analytics + $.ajax({ type:'POST', url: '/reorder_static_tabs', @@ -56,10 +60,18 @@ class CMS.Views.TabsEdit extends Backbone.View 'i4x://edx/templates/static_tab/Empty' ) + analytics.track "Added Static Page", + course: course_location_analytics + deleteTab: (event) => if not confirm 'Are you sure you want to delete this component? This action cannot be undone.' return $component = $(event.currentTarget).parents('.component') + + analytics.track "Deleted Static Page", + course: course_location_analytics + id: $component.data('id') + $.post('/delete_item', { id: $component.data('id') }, => diff --git a/cms/static/js/views/course_info_edit.js b/cms/static/js/views/course_info_edit.js index ce959fd443..a6d42e1927 100644 --- a/cms/static/js/views/course_info_edit.js +++ b/cms/static/js/views/course_info_edit.js @@ -107,6 +107,11 @@ CMS.Views.ClassInfoUpdateView = Backbone.View.extend({ // push change to display, hide the editor, submit the change targetModel.save({}, {error : CMS.ServerError}); this.closeEditor(this); + + analytics.track('Saved Course Update', { + 'course': course_location_analytics, + 'date': this.dateEntry(event).val() + }); }, onCancel: function(event) { @@ -147,6 +152,11 @@ CMS.Views.ClassInfoUpdateView = Backbone.View.extend({ return; } + analytics.track('Deleted Course Update', { + 'course': course_location_analytics, + 'date': this.dateEntry(event).val() + }); + var targetModel = this.eventModel(event); this.modelDom(event).remove(); var cacheThis = this; @@ -284,6 +294,11 @@ CMS.Views.ClassInfoHandoutsView = Backbone.View.extend({ this.model.save({}, {error: CMS.ServerError}); this.$form.hide(); this.closeEditor(this); + + analytics.track('Saved Course Handouts', { + 'course': course_location_analytics + }); + }, onCancel: function(event) { From 7b5ec1bc416ba61202b80b04131db10841d8e2d0 Mon Sep 17 00:00:00 2001 From: "Mark L. Chang" Date: Thu, 4 Apr 2013 00:40:06 -0400 Subject: [PATCH 12/17] instrumented advanced settings --- cms/static/js/views/settings/advanced_view.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cms/static/js/views/settings/advanced_view.js b/cms/static/js/views/settings/advanced_view.js index e3ff098efb..52c5ed78d0 100644 --- a/cms/static/js/views/settings/advanced_view.js +++ b/cms/static/js/views/settings/advanced_view.js @@ -137,6 +137,10 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({ success : function() { self.render(); self.showMessage(self.successful_changes); + analytics.track('Saved Advanced Settings', { + 'course': course_location_analytics + }); + }, error : CMS.ServerError }); From 4ce34fa298a5e476ebedbc47f7e32a3f9d5bac62 Mon Sep 17 00:00:00 2001 From: "Mark L. Chang" Date: Thu, 4 Apr 2013 00:49:09 -0400 Subject: [PATCH 13/17] instrumented checklists --- cms/static/js/views/checklists_view.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cms/static/js/views/checklists_view.js b/cms/static/js/views/checklists_view.js index e553c7a2ca..85c0f5242b 100644 --- a/cms/static/js/views/checklists_view.js +++ b/cms/static/js/views/checklists_view.js @@ -77,11 +77,18 @@ CMS.Views.Checklists = Backbone.View.extend({ var task_index = $checkbox.data('task'); var model = this.collection.at(checklist_index); model.attributes.items[task_index].is_checked = $task.hasClass(completed); + model.save({}, { success : function() { var updatedTemplate = self.renderTemplate(model, checklist_index); self.$el.find('#course-checklist'+checklist_index).first().replaceWith(updatedTemplate); + + analytics.track('Toggled a Checklist Task', { + 'course': course_location_analytics, + 'task': model.attributes.items[task_index].short_description, + 'state': model.attributes.items[task_index].is_checked + }); }, error : CMS.ServerError }); From 8fb6ce2ecad28b53ff31f67fa7492367eb669162 Mon Sep 17 00:00:00 2001 From: "Mark L. Chang" Date: Thu, 4 Apr 2013 01:47:37 -0400 Subject: [PATCH 14/17] added tracking to unit page and components --- cms/static/coffee/src/views/unit.coffee | 38 +++++++++++++++++++++++++ cms/templates/unit.html | 1 + 2 files changed, 39 insertions(+) diff --git a/cms/static/coffee/src/views/unit.coffee b/cms/static/coffee/src/views/unit.coffee index 42127b2800..e23477ccfa 100644 --- a/cms/static/coffee/src/views/unit.coffee +++ b/cms/static/coffee/src/views/unit.coffee @@ -35,6 +35,10 @@ class CMS.Views.UnitEdit extends Backbone.View @$('.components').sortable( handle: '.drag-handle' update: (event, ui) => + analytics.track "Reordered Components", + course: course_location_analytics + id: unit_location_analytics + payload = children : @components() options = success : => @model.unset('children') @model.save(payload, options) @@ -89,6 +93,11 @@ class CMS.Views.UnitEdit extends Backbone.View $(event.currentTarget).data('location') ) + analytics.track "Added a Component", + course: course_location_analytics + unit_id: unit_location_analytics + type: $(event.currentTarget).data('location') + @closeNewComponent(event) components: => @$('.component').map((idx, el) -> $(el).data('id')).get() @@ -111,6 +120,11 @@ class CMS.Views.UnitEdit extends Backbone.View $.post('/delete_item', { id: $component.data('id') }, => + analytics.track "Deleted a Component", + course: course_location_analytics + unit_id: unit_location_analytics + id: $component.data('id') + $component.remove() # b/c we don't vigilantly keep children up to date # get rid of it before it hurts someone @@ -129,6 +143,10 @@ class CMS.Views.UnitEdit extends Backbone.View id: @$el.data('id') delete_children: true }, => + analytics.track "Deleted Draft", + course: course_location_analytics + unit_id: unit_location_analytics + window.location.reload() ) @@ -138,6 +156,10 @@ class CMS.Views.UnitEdit extends Backbone.View $.post('/create_draft', { id: @$el.data('id') }, => + analytics.track "Created Draft", + course: course_location_analytics + unit_id: unit_location_analytics + @model.set('state', 'draft') ) @@ -148,20 +170,31 @@ class CMS.Views.UnitEdit extends Backbone.View $.post('/publish_draft', { id: @$el.data('id') }, => + analytics.track "Published Draft", + course: course_location_analytics + unit_id: unit_location_analytics + @model.set('state', 'public') ) setVisibility: (event) -> if @$('.visibility-select').val() == 'private' target_url = '/unpublish_unit' + visibility = "private" else target_url = '/publish_draft' + visibility = "public" @wait(true) $.post(target_url, { id: @$el.data('id') }, => + analytics.track "Set Unit Visibility", + course: course_location_analytics + unit_id: unit_location_analytics + visibility: visibility + @model.set('state', @$('.visibility-select').val()) ) @@ -193,6 +226,11 @@ class CMS.Views.UnitEdit.NameEdit extends Backbone.View @model.save(metadata: metadata) # Update name shown in the right-hand side location summary. $('.unit-location .editing .unit-name').html(metadata.display_name) + analytics.track "Edited Unit Name", + course: course_location_analytics + unit_id: unit_location_analytics + display_name: metadata.display_name + class CMS.Views.UnitEdit.LocationState extends Backbone.View initialize: => diff --git a/cms/templates/unit.html b/cms/templates/unit.html index e1a020dfca..1b9e49620b 100644 --- a/cms/templates/unit.html +++ b/cms/templates/unit.html @@ -28,6 +28,7 @@ }); }); + var unit_location_analytics = '${unit_location}'; From db1c0bf081a01748d50c9109d4131502129cc279 Mon Sep 17 00:00:00 2001 From: "Mark L. Chang" Date: Thu, 4 Apr 2013 12:14:34 -0400 Subject: [PATCH 15/17] added dev key so tests run --- cms/envs/test.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cms/envs/test.py b/cms/envs/test.py index 59664bfd40..7d898de478 100644 --- a/cms/envs/test.py +++ b/cms/envs/test.py @@ -118,3 +118,6 @@ PASSWORD_HASHERS = ( 'django.contrib.auth.hashers.SHA1PasswordHasher', 'django.contrib.auth.hashers.MD5PasswordHasher', ) + +# segment-io key for dev +SEGMENT_IO_KEY = 'mty8edrrsg' From 10377bc41c2fd7071da2b489fe072cec31886487 Mon Sep 17 00:00:00 2001 From: "Mark L. Chang" Date: Thu, 4 Apr 2013 16:08:10 -0400 Subject: [PATCH 16/17] added a dummy key for segment.io so it doesn't ever fail --- cms/envs/aws.py | 3 ++- cms/envs/test.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cms/envs/aws.py b/cms/envs/aws.py index ef69c51d12..edf67badfe 100644 --- a/cms/envs/aws.py +++ b/cms/envs/aws.py @@ -46,7 +46,8 @@ SESSION_COOKIE_DOMAIN = ENV_TOKENS.get('SESSION_COOKIE_DOMAIN') for feature, value in ENV_TOKENS.get('MITX_FEATURES', {}).items(): MITX_FEATURES[feature] = value -SEGMENT_IO_KEY = ENV_TOKENS.get('SEGMENT_IO_KEY') +# load segment.io key, provide a dummy if it does not exist +SEGMENT_IO_KEY = ENV_TOKENS.get('SEGMENT_IO_KEY', '***REMOVED***') LOGGING = get_logger_config(LOG_DIR, logging_env=ENV_TOKENS['LOGGING_ENV'], diff --git a/cms/envs/test.py b/cms/envs/test.py index 7d898de478..820b2cbe23 100644 --- a/cms/envs/test.py +++ b/cms/envs/test.py @@ -119,5 +119,5 @@ PASSWORD_HASHERS = ( 'django.contrib.auth.hashers.MD5PasswordHasher', ) -# segment-io key for dev -SEGMENT_IO_KEY = 'mty8edrrsg' +# dummy segment-io key +SEGMENT_IO_KEY = '***REMOVED***' From 28522568981083543a483c5ff52a46d551e58c3c Mon Sep 17 00:00:00 2001 From: "Mark L. Chang" Date: Thu, 4 Apr 2013 23:44:40 -0400 Subject: [PATCH 17/17] added dummy analytics object --- cms/templates/widgets/segment-io.html | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cms/templates/widgets/segment-io.html b/cms/templates/widgets/segment-io.html index 7d00c731b0..f623c47542 100644 --- a/cms/templates/widgets/segment-io.html +++ b/cms/templates/widgets/segment-io.html @@ -18,4 +18,15 @@ % endif +% else: + + + % endif