Matthias Mullie has uploaded a new change for review.
https://gerrit.wikimedia.org/r/171791
Change subject: [WIP] Log Flow topic and post actions (FlowReplies)
......................................................................
[WIP] Log Flow topic and post actions (FlowReplies)
Todo:
* preview & keep-editing actions
* make sure cancels aren't executed on after-save (I assume cancel callbacks
are used to destruct form)
* add more properties than just 'action' (share them somewhere so we don't have
to repeat)
* not sure how to do 'entrypoints' yet
* no-JS cases
* probably lots more
Change-Id: Ic011a6130184aadae539eced307bf982f84c990d
---
M Resources.php
M modules/engine/components/board/base/flow-board-api-events.js
M modules/engine/components/board/base/flow-board-interactive-events.js
M modules/engine/components/board/base/flow-boardandhistory-base.js
M modules/engine/components/common/flow-component-engines.js
M modules/engine/components/common/flow-component-events.js
A modules/engine/misc/flow-eventlog.js
7 files changed, 115 insertions(+), 25 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Flow
refs/changes/91/171791/1
diff --git a/Resources.php b/Resources.php
index bfd7f89..038f878 100644
--- a/Resources.php
+++ b/Resources.php
@@ -324,6 +324,8 @@
'engine/misc/mw-ui.modal.js',
// FlowApi
'engine/misc/flow-api.js',
+ // FlowEventLog
+ 'engine/misc/flow-eventlog.js',
// Component registry
'engine/components/flow-registry.js',
// FlowComponent must come before actual components
diff --git a/modules/engine/components/board/base/flow-board-api-events.js
b/modules/engine/components/board/base/flow-board-api-events.js
index cfd6c78..8192066 100644
--- a/modules/engine/components/board/base/flow-board-api-events.js
+++ b/modules/engine/components/board/base/flow-board-api-events.js
@@ -712,13 +712,16 @@
*/
FlowBoardComponentApiEventsMixin.UI.events.apiHandlers.submitReply =
function ( info, data, jqxhr ) {
var $form = $( this ).closest( 'form' ),
- flowBoard = mw.flow.getPrototypeMethod( 'board',
'getInstanceByElement' )( $form );
+ flowBoard = mw.flow.getPrototypeMethod( 'board',
'getInstanceByElement' )( $form ),
+ eventLog = new mw.flow.EventLog( 'FlowReplies' ); //
@todo: create a shared object somewhere with the shared properties for
FlowReplies schema
if ( info.status !== 'done' ) {
// Error will be displayed by default, nothing else to
wrap up
return;
}
+ eventLog.logEvent( { action: 'save' } );
+
flowBoard.emitWithReturn( 'cancelForm', $form );
// Target should be flow-topic
diff --git
a/modules/engine/components/board/base/flow-board-interactive-events.js
b/modules/engine/components/board/base/flow-board-interactive-events.js
index b0e87ca..6299242 100644
--- a/modules/engine/components/board/base/flow-board-interactive-events.js
+++ b/modules/engine/components/board/base/flow-board-interactive-events.js
@@ -164,7 +164,8 @@
postId = $targetPost.data( 'flow-id' ),
topicTitle = $post.closest( '.flow-topic' ).find(
'.flow-topic-title' ).text(),
replyToContent = $post.find( '.flow-post-content'
).filter( ':first' ).text() || topicTitle,
- author = $.trim( $post.find( '.flow-author' ).filter(
':first' ).find( '.mw-userlink' ).text() );
+ author = $.trim( $post.find( '.flow-author' ).filter(
':first' ).find( '.mw-userlink' ).text() ),
+ eventLog = new mw.flow.EventLog( 'FlowReplies' ); //
@todo: create a shared object somewhere with the shared properties for
FlowReplies schema
// Check if reply form has already been opened
if ( $post.data( 'flow-replying' ) ) {
@@ -197,14 +198,27 @@
// We have to make sure the data attribute is added to the
form; the
// addBack is failsafe for when form is actually the root node
in $form
// already (there may or may not be parent containers)
- flowBoard.emitWithReturn( 'addFormCancelCallback', $form.find(
'form' ).addBack( 'form' ), function () {
- $post.removeData( 'flow-replying' );
- $form.remove();
- } );
+ flowBoard.emitWithReturn(
+ 'addFormCancelCallback',
+ $form.find( 'form' ).addBack( 'form' ),
+ function () {
+ $post.removeData( 'flow-replying' );
+ $form.remove();
+ }
+ );
+
+ // Assign event log object to log cancel event
+ flowBoard.emitWithReturn(
+ 'setFormCancelEventLog',
+ $form.find( 'form' ).addBack( 'form' ),
+ eventLog
+ );
// Add reply form below the post being replied to (WRT max
depth)
$targetPost.children( '.flow-replies' ).append( $form );
$form.conditionalScrollIntoView();
+
+ eventLog.logEvent( { action: 'initiate' } );
};
/**
diff --git a/modules/engine/components/board/base/flow-boardandhistory-base.js
b/modules/engine/components/board/base/flow-boardandhistory-base.js
index 1d4297b..1f4c814 100644
--- a/modules/engine/components/board/base/flow-boardandhistory-base.js
+++ b/modules/engine/components/board/base/flow-boardandhistory-base.js
@@ -110,9 +110,13 @@
$form = $( this ).closest( 'form' ),
flowComponent = mw.flow.getPrototypeMethod(
'boardAndHistoryBase', 'getInstanceByElement' )( $form ),
$fields = $form.find( 'textarea, :text' ),
- changedFieldCount = 0;
+ changedFieldCount = 0,
+ callbacks = $form.data( 'flow-cancel-callback' ) || [],
+ eventLog = $form.data( 'flow-cancel-eventlog' ) || {
logEvent: function() {} };
event.preventDefault();
+
+ eventLog.logEvent( { action: 'cancel-attempt' } );
// Check for non-empty fields of text
$fields.each( function () {
@@ -121,27 +125,36 @@
return false;
}
} );
- // If all the text fields are empty, OR if the user confirms to
close this with text already entered, do it.
- if ( !changedFieldCount || confirm(
flowComponent.constructor.static.TemplateEngine.l10n( 'flow-cancel-warning' ) )
) {
- // Reset the form content
- $form[0].reset();
- // Trigger for flow-actions-disabler
- $form.find( 'textarea, :text' ).trigger( 'keyup' );
+ // If fields are not empty, AND the user confirms to close this
with text already entered, log it as abort.
+ if ( changedFieldCount && !confirm(
flowComponent.constructor.static.TemplateEngine.l10n( 'flow-cancel-warning' ) )
) {
+ eventLog.logEvent( { action: 'cancel-abort' } );
- // Hide the form
- flowComponent.emitWithReturn( 'hideForm', $form );
-
- // Get rid of existing error messages
- flowComponent.emitWithReturn( 'removeError', $form );
-
- // Trigger the cancel callback
- if ( $form.data( 'flow-cancel-callback' ) ) {
- $.each( $form.data( 'flow-cancel-callback' ),
function ( idx, fn ) {
- fn.call( target, event );
- } );
- }
+ // Don't cancel!
+ return;
}
+
+ // Only log if user had already entered text (= confirmed to
close)
+ if ( changedFieldCount ) {
+ eventLog.logEvent( { action: 'cancel' } );
+ }
+
+ // Reset the form content
+ $form[0].reset();
+
+ // Trigger for flow-actions-disabler
+ $form.find( 'textarea, :text' ).trigger( 'keyup' );
+
+ // Hide the form
+ flowComponent.emitWithReturn( 'hideForm', $form );
+
+ // Get rid of existing error messages
+ flowComponent.emitWithReturn( 'removeError', $form );
+
+ // Trigger the cancel callback
+ $.each( callbacks, function ( idx, fn ) {
+ fn.call( target, event );
+ } );
};
//
diff --git a/modules/engine/components/common/flow-component-engines.js
b/modules/engine/components/common/flow-component-engines.js
index 2769efd..3d8a928 100644
--- a/modules/engine/components/common/flow-component-engines.js
+++ b/modules/engine/components/common/flow-component-engines.js
@@ -28,6 +28,12 @@
*/
mw.flow.Api = new mw.flow.FlowApi(
FlowComponentEnginesMixin.static.StorageEngine );
+ /**
+ * EventLogging wrapper
+ * @type {FlowEventLog}
+ */
+ mw.flow.EventLog = mw.flow.FlowEventLog;
+
// Copy static and prototype from mixin to main class
mw.flow.mixinComponent( 'component', FlowComponentEnginesMixin );
}( jQuery, mediaWiki, mediaWiki.flow.vendor.initStorer ) );
diff --git a/modules/engine/components/common/flow-component-events.js
b/modules/engine/components/common/flow-component-events.js
index 9a81c89..ddc7864 100644
--- a/modules/engine/components/common/flow-component-events.js
+++ b/modules/engine/components/common/flow-component-events.js
@@ -666,6 +666,16 @@
FlowComponentEventsMixin.eventHandlers.addFormCancelCallback =
flowEventsMixinAddFormCancelCallback;
/**
+ * Adds a flow-cancel-eventlog to a given form, to be triggered on
click of the "cancel" button.
+ * @param {jQuery} $form
+ * @param {FlowEventLog} eventLog
+ */
+ function flowEventsMixinSetFormCancelCallback( $form, eventLog ) {
+ $form.data( 'flow-cancel-eventlog', eventLog );
+ }
+ FlowComponentEventsMixin.eventHandlers.setFormCancelEventLog =
flowEventsMixinSetFormCancelCallback;
+
+ /**
* @param {FlowBoardComponent|jQuery} $node or entire FlowBoard
*/
function flowEventsMixinRemoveError( $node ) {
diff --git a/modules/engine/misc/flow-eventlog.js
b/modules/engine/misc/flow-eventlog.js
new file mode 100644
index 0000000..a2291aa
--- /dev/null
+++ b/modules/engine/misc/flow-eventlog.js
@@ -0,0 +1,42 @@
+/*!
+ *
+ */
+
+window.mw = window.mw || {}; // mw-less testing
+
+( function ( mw, $ ) {
+ mw.flow = mw.flow || {}; // create mw.flow globally
+
+ /**
+ * @param {String} schemaName Canonical schema name.
+ * @param {Object} [eventInstance] Shared event instance data.
+ * @returns {FlowEventLog}
+ * @constructor
+ */
+ function FlowEventLog( schemaName, eventInstance ) {
+ this.schemaName = schemaName;
+ this.eventInstance = eventInstance || {};
+
+ /**
+ * @param {Object} eventInstance Additional event instance data
for this
+ * particular event.
+ * @returns {$.Deferred}
+ */
+ function logEvent( eventInstance ) {
+ if ( mw.eventLog ) {
+ return mw.eventLog.logEvent(
+ this.schema,
+ $.extend( this.eventInstance,
eventInstance )
+ );
+ } else {
+ // for compatibility: a deferred that never
resolves
+ return $.Deferred().promise();
+ }
+ }
+
+ this.logEvent = logEvent;
+ }
+
+ // Export
+ mw.flow.FlowEventLog = FlowEventLog;
+}( mw, jQuery ) );
--
To view, visit https://gerrit.wikimedia.org/r/171791
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic011a6130184aadae539eced307bf982f84c990d
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Flow
Gerrit-Branch: master
Gerrit-Owner: Matthias Mullie <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits