Santhosh has submitted this change and it was merged.

Change subject: Fix workflow selector in TUX
......................................................................


Fix workflow selector in TUX

Refactored it into separate resource loader module and jQuery
plugin. Fixed the api to not return empty arrays but false or
object. Simplified and cleaned up the logic.

Bug: 45558
Change-Id: Ib0f874af7356b8affced73139dff9510c6c970f1
---
M Resources.php
M api/ApiQueryMessageGroups.php
M resources/css/ext.translate.special.translate.css
A resources/css/ext.translate.workflowselector.css
M resources/js/ext.translate.messagetable.js
M resources/js/ext.translate.special.translate.js
A resources/js/ext.translate.workflowselector.js
M specials/SpecialTranslate.php
8 files changed, 231 insertions(+), 161 deletions(-)

Approvals:
  Santhosh: Verified; Looks good to me, approved



diff --git a/Resources.php b/Resources.php
index 1380aa3..43d8fa4 100644
--- a/Resources.php
+++ b/Resources.php
@@ -298,13 +298,13 @@
                'ext.translate.base',
                'ext.translate.groupselector',
                'ext.translate.messagetable',
+               'ext.translate.workflowselector',
                'ext.uls.init',
        ),
        'messages' => array(
                'translate-workflow-set-do',
                'translate-workflow-set-doing',
                'translate-workflow-set-done',
-               'translate-workflowstatus',
                'translate-workflow-set-error-alreadyset',
                'translate-documentation-language',
                'translate-workflow-state-',
@@ -333,6 +333,14 @@
        'position' => 'top',
 ) + $resourcePaths;
 
+$wgResourceModules['ext.translate.workflowselector'] = array(
+       'styles' => 'resources/css/ext.translate.workflowselector.css',
+       'scripts' => 'resources/js/ext.translate.workflowselector.js',
+       'messages' => array(
+               'translate-workflowstatus',
+       ),
+) + $resourcePaths;
+
 $wgResourceModules['jquery.autoresize'] = array(
        'scripts' => 'resources/js/jquery.autoresize.js',
 ) + $resourcePaths;
diff --git a/api/ApiQueryMessageGroups.php b/api/ApiQueryMessageGroups.php
index 6562ca2..a2c5532 100644
--- a/api/ApiQueryMessageGroups.php
+++ b/api/ApiQueryMessageGroups.php
@@ -216,8 +216,8 @@
 
                $stateConfig = $group->getMessageGroupStates()->getStates();
 
-               if ( !is_array( $stateConfig ) ) {
-                       return $stateConfig;
+               if ( !is_array( $stateConfig ) || $stateConfig === array() ) {
+                       return false;
                }
 
                $user = $this->getUser();
diff --git a/resources/css/ext.translate.special.translate.css 
b/resources/css/ext.translate.special.translate.css
index 9be382c..43f7e6a 100644
--- a/resources/css/ext.translate.special.translate.css
+++ b/resources/css/ext.translate.special.translate.css
@@ -128,66 +128,6 @@
        display: none;
 }
 
-.tux-workflow-status {
-       background: #eee;
-       border: 1px solid #ddd;
-       color: #252525;
-       cursor: pointer;
-       display: inline-block;
-       padding: 2px 4px;
-       margin: 5px 0;
-}
-
-.tux-workflow-status:hover {
-       border: 1px solid #c9c9c9;
-}
-
-.tux-workflow-status:after {
-       margin-left: 3px;
-       border-left: 3px solid transparent;
-       border-right: 3px solid transparent;
-       border-top: 3px solid #555;
-       content: "";
-       display: inline-block;
-       vertical-align: middle;
-}
-
-ul.tux-workflow-status-selector {
-       padding-top: 2em;
-       border: 1px solid #c9c9c9;
-       /* @noflip */
-       -webkit-box-shadow: 0 3px 3px -3px rgba(0, 0, 0, 0.5);
-       /* @noflip */
-       box-shadow: 0 3px 3px -3px rgba(0, 0, 0, 0.5);
-       font-size: 14px;
-       margin: 0 5px;
-       list-style: none;
-       cursor: pointer;
-       padding: 4px;
-       width: 200px;
-       z-index: 10;
-       background: #fff;
-       display: block;
-       position: absolute;
-}
-
-ul.tux-workflow-status-selector li {
-       color: #555555;
-       font-size: 14px;
-       padding: 0 2px;
-}
-
-ul.tux-workflow-status-selector li:hover {
-       background-color: #f0f0f0;
-       color: #252525;
-}
-
-ul.tux-workflow-status-selector li.selected {
-       /* @embed */
-       background: url(../images/label-tick.png) right no-repeat;
-       color: #252525;
-}
-
 .tux-messagetable-header {
        padding-top: 5px;
        border-bottom: 1px solid #777;
diff --git a/resources/css/ext.translate.workflowselector.css 
b/resources/css/ext.translate.workflowselector.css
new file mode 100644
index 0000000..7c25995
--- /dev/null
+++ b/resources/css/ext.translate.workflowselector.css
@@ -0,0 +1,59 @@
+.tux-workflow-status {
+       background: #eee;
+       border: 1px solid #ddd;
+       color: #252525;
+       cursor: pointer;
+       display: inline-block;
+       padding: 2px 4px;
+       margin: 5px 0;
+}
+
+.tux-workflow-status:hover {
+       border: 1px solid #c9c9c9;
+}
+
+.tux-workflow-status:after {
+       margin-left: 3px;
+       border-left: 3px solid transparent;
+       border-right: 3px solid transparent;
+       border-top: 3px solid #555;
+       content: "";
+       display: inline-block;
+       vertical-align: middle;
+}
+
+.tux-workflow-status-selector {
+       padding-top: 2em;
+       border: 1px solid #c9c9c9;
+       /* @noflip */
+       -webkit-box-shadow: 0 3px 3px -3px rgba(0, 0, 0, 0.5);
+       /* @noflip */
+       box-shadow: 0 3px 3px -3px rgba(0, 0, 0, 0.5);
+       font-size: 14px;
+       margin: 0 5px;
+       list-style: none;
+       padding: 4px;
+       width: 200px;
+       z-index: 10;
+       background: #fff;
+       display: block;
+       position: absolute;
+}
+
+.tux-workflow-status-selector li {
+       color: #555555;
+       font-size: 14px;
+       padding: 0 2px;
+}
+
+.tux-workflow-status-selector li.changeable:hover {
+       cursor: pointer;
+       background-color: #f0f0f0;
+       color: #252525;
+}
+
+.tux-workflow-status-selector li.selected {
+       /* @embed */
+       background: url(../images/label-tick.png) right no-repeat;
+       color: #252525;
+}
diff --git a/resources/js/ext.translate.messagetable.js 
b/resources/js/ext.translate.messagetable.js
index 7deed81..e390ab1 100644
--- a/resources/js/ext.translate.messagetable.js
+++ b/resources/js/ext.translate.messagetable.js
@@ -375,7 +375,7 @@
                        mw.translate.getMessages( messagegroup, targetLanguage, 
offset, pageSize, filter )
                                .done( function ( result ) {
                                        var messages = 
result.query.messagecollection,
-                                               $workflowSelector = $( 
'ul.tux-workflow-status-selector ' );
+                                               state;
 
                                        // No new messages were loaded
                                        if ( messages.length === 0 ) {
@@ -393,6 +393,9 @@
                                                        $( '.tux-message:first' 
).data( 'translateeditor' ).init();
                                                }
                                        } );
+
+                                       state = result.query.metadata && 
result.query.metadata.state;
+                                       $( '.tux-workflow' ).workflowselector( 
messagegroup, targetLanguage, state );
 
                                        if ( result['query-continue'] === 
undefined ) {
                                                // End of messages
@@ -419,21 +422,6 @@
                                                mw.msg( 
'tux-messagetable-loading-messages', Math.min( remaining, pageSize ) )
                                        );
 
-                                       mw.translate.getMessageGroup( 
messagegroup ).done( function ( group ) {
-                                               
mw.translate.prepareWorkflowSelector( group );
-                                       } );
-                                       if ( result.query.metadata && 
result.query.metadata.state ) {
-                                               $workflowSelector.find( 'li' 
).each( function () {
-                                                       var $this = $( this );
-
-                                                       if ( $this.data( 
'state' ).id === result.query.metadata.state ) {
-                                                               $( 
'.tux-workflow-status' ).text( mw.msg( 'translate-workflowstatus', $this.text() 
) );
-                                                               $this.addClass( 
'selected' );
-                                                       } else {
-                                                               
$this.removeClass( 'selected' );
-                                                       }
-                                               } );
-                                       }
                                } )
                                .fail( function ( errorCode, response ) {
                                        if ( response.error.code === 
'mctranslate-language-disabled' ) {
diff --git a/resources/js/ext.translate.special.translate.js 
b/resources/js/ext.translate.special.translate.js
index 2d16d05..19add80 100644
--- a/resources/js/ext.translate.special.translate.js
+++ b/resources/js/ext.translate.special.translate.js
@@ -78,9 +78,8 @@
                                mw.log( 'Error parsing description for group ' 
+ group.id );
                        } );
 
-                       mw.translate.loadMessages( changes );
                        mw.translate.changeUrl( changes );
-                       mw.translate.prepareWorkflowSelector( group );
+                       mw.translate.loadMessages( changes );
                        updateGroupWarning();
                },
 
@@ -131,59 +130,6 @@
                                // For old browsers, just reload
                                window.location.href = uri.toString();
                        }
-               },
-
-               changeWorkflowStatus: function ( group, language, state, token 
) {
-                       var api = new mw.Api(),
-                               params = {
-                                       action: 'groupreview',
-                                       group: group,
-                                       language: language,
-                                       state: state,
-                                       token: token,
-                                       format: 'json'
-                               };
-
-                       return api.post( params );
-               },
-
-
-               prepareWorkflowSelector: function ( group ) {
-                       var $workflowStateSelector,
-                               $workflowStatusTrigger = $( 
'.tux-workflow-status' );
-
-                       if ( !group.workflowstates ) {
-                               $workflowStatusTrigger.addClass( 'hide' );
-
-                               return;
-                       }
-
-                       $workflowStateSelector = $( 
'ul.tux-workflow-status-selector' );
-
-                       $workflowStateSelector.empty();
-
-                       $.each( group.workflowstates, function ( id, 
workflowstate ) {
-                               if ( workflowstate._canchange ) {
-                                       workflowstate.id = id;
-
-                                       $workflowStateSelector.append( $( 
'<li>' )
-                                               .data( 'state', workflowstate )
-                                               .text( workflowstate._name )
-                                               .on( 'click', function () {
-                                                       var $this = $( this );
-
-                                                       
$workflowStateSelector.find( '.selected' ).removeClass( 'selected' );
-                                                       $this.addClass( 
'selected' )
-                                                               
.parent().addClass( 'hide' );
-                                                       
workflowSelectionHandler( $this.data( 'state' ) );
-                                               } )
-                                       );
-                               }
-                       } );
-
-                       $workflowStatusTrigger
-                               .text( mw.msg( 'translate-workflow-state-' ) )
-                               .removeClass( 'hide' );
                }
        } );
 
@@ -194,19 +140,6 @@
                $translateContainer = $translateContainer || $( 
'.ext-translate-container' );
                return $translateContainer.find( '.tux-message-item' )
                        .filter( '.translated, .proofread' );
-       }
-
-       function workflowSelectionHandler( state ) {
-               var $status = $( '.tux-workflow-status' );
-
-               $status.text( mw.msg( 'translate-workflow-set-doing' ) );
-               mw.translate.changeWorkflowStatus( $status.data( 'group' ),
-                       $status.data( 'language' ),
-                       state.id,
-                       $status.data( 'token' )
-               ).done( function() {
-                       $status.text( mw.msg( 'translate-workflowstatus', 
state._name ) );
-               } );
        }
 
        function updateGroupWarning() {
@@ -267,6 +200,7 @@
                targetLanguage = $messageList.data( 'targetlangcode' ) || // 
for tux=1
                        mw.config.get( 'wgUserLanguage' ); // for tux=0
 
+               // This is the selector for non-TUX mode
                prepareWorkflowSelector();
                $( '.ext-translate-msggroup-selector .grouplink' 
).msggroupselector( {
                        onSelect: mw.translate.changeGroup
diff --git a/resources/js/ext.translate.workflowselector.js 
b/resources/js/ext.translate.workflowselector.js
new file mode 100644
index 0000000..0ad9448
--- /dev/null
+++ b/resources/js/ext.translate.workflowselector.js
@@ -0,0 +1,154 @@
+/*
+ * A jQuery plugin which handles the display and change of message group
+ * workflow sates.
+ *
+ * @author Niklas Laxström
+ * @license GPL2+
+ */
+
+( function ( $, mw ) {
+       'use strict';
+
+       function WorkflowSelector( container ) {
+               this.$container = $( container );
+       }
+
+       WorkflowSelector.prototype = {
+               /**
+                * Displays the current state and selector if relevant.
+                * @param {String} groupId
+                * @param {String} language
+                * @param {String] state
+                */
+               receiveState: function ( groupId, language, state ) {
+                       var instance = this;
+                       instance.currentState = state;
+                       instance.groupId = groupId;
+                       instance.language = language;
+
+                       mw.translate.getMessageGroup( groupId ).done(
+                               function ( group ) {
+                                       instance.states = group.workflowstates;
+                                       instance.display();
+                               }
+                       );
+               },
+
+               /**
+                * Calls the WebApi to change the state to a new value.
+                * @param {String} state
+                * @return {jQuery.Promise}
+                */
+               changeState: function ( state ) {
+                       var instance = this,
+                               tokenCall, deferred;
+
+                       deferred = new $.Deferred();
+                       tokenCall = new mw.Api().get( { action: 'tokens', type: 
'groupreview' } );
+
+                       tokenCall.fail( deferred.reject );
+                       tokenCall.done( function ( result ) {
+                               var params = {
+                                       action: 'groupreview',
+                                       group: instance.groupId,
+                                       language: instance.language,
+                                       state: state,
+                                       token: result.tokens.groupreviewtoken,
+                                       format: 'json'
+                               };
+                               new mw.Api().post( params )
+                                       .done( deferred.resolve )
+                                       .fail( deferred.reject );
+                       } );
+
+                       return deferred.promise();
+               },
+
+               /**
+                * Get the text which says that the current state is X.
+                * @param {String} state
+                * @return {String} Text which should be escaped.
+                */
+               getStateDisplay: function ( stateName ) {
+                       return mw.msg( 'translate-workflowstatus', stateName );
+               },
+
+               /**
+                * Actually constructs the DOM and displays the selector.
+                */
+               display: function () {
+                       var instance = this,
+                               $display, $list;
+
+                       instance.$container.empty();
+                       if ( !instance.states ) {
+                               return;
+                       }
+
+                       $list = $( '<ul>' )
+                               .addClass( 'tux-workflow-status-selector hide' 
);
+
+                       $display = $( '<div>' )
+                               .addClass( 'tux-workflow-status' )
+                               .text( mw.msg( 'translate-workflow-state-' ) )
+                               .click( function ( e ) {
+                                       $list.removeClass( 'hide' );
+                                       e.stopPropagation();
+                               } );
+
+                       $.each( this.states, function ( id, data ) {
+                               var $state;
+
+                               // Store the id also
+                               data.id = id;
+
+                               $state = $( '<li>' )
+                                       .data( 'state', data )
+                                       .text( data._name );
+
+                               if ( data._canchange && id !== 
instance.currentState ) {
+                                       $state.addClass( 'changeable' );
+                               } else {
+                                       $state.addClass( 'unchangeable' );
+                               }
+
+                               if ( id === instance.currentState ) {
+                                       $display.text( 
instance.getStateDisplay( data._name ) );
+                                       $state.addClass( 'selected' );
+                               }
+
+                               $state.appendTo( $list );
+                       } );
+
+                       $list.find( '.changeable' ).click( function () {
+                               var $this = $( this ), state;
+
+                               state = $this.data( 'state' ).id;
+
+                               instance.changeState( state )
+                                       .done( function () {
+                                               instance.receiveState( 
instance.groupId, instance.language, state );
+                                       } )
+                                       .fail( function () {
+                                               window.alert( 'Change of state 
failed' );
+                                       } );
+                       } );
+                       instance.$container.append( $display, $list );
+               }
+       };
+
+       /* workflowselector jQuery definitions */
+       $.fn.workflowselector = function ( groupId, language, state ) {
+               return this.each( function () {
+                       var $this = $( this ),
+                               data = $this.data( 'workflowselector' );
+
+                       if ( !data ) {
+                               $this.data( 'workflowselector', ( data = new 
WorkflowSelector( this ) ) );
+                       }
+                       $this.data( 'workflowselector' ).receiveState( groupId, 
language, state );
+               } );
+       };
+       $.fn.workflowselector.Constructor = WorkflowSelector;
+
+}( jQuery, mediaWiki ) );
diff --git a/specials/SpecialTranslate.php b/specials/SpecialTranslate.php
index aaae26e..6d59143 100644
--- a/specials/SpecialTranslate.php
+++ b/specials/SpecialTranslate.php
@@ -714,20 +714,7 @@
        }
 
        protected function tuxWorkflowSelector() {
-               $selector = Html::element( 'div', array(
-                       'class' => 'tux-workflow-status hide',
-                       'data-token' => ApiGroupReview::getToken( 0, '' ),
-                       'data-group' => $this->options['group'],
-                       'data-language' => $this->options['language'],
-               ) );
-
-               $selectorRow = Html::openElement( 'div', array( 'class' => 
'twelve columns' ) );
-
-               $selectorRow .= $selector;
-               $options = Html::openElement( 'ul', array( 'class' => 
'tux-workflow-status-selector hide' ) );
-               $options .= Html::closeElement( 'ul' );
-
-               return $selectorRow . $options . Html::closeElement( 'div' );
+               return Html::element( 'div', array( 'class' => 'tux-workflow 
twelve columns' ) );
        }
 
        protected function getWorkflowStatus() {

-- 
To view, visit https://gerrit.wikimedia.org/r/55782
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ib0f874af7356b8affced73139dff9510c6c970f1
Gerrit-PatchSet: 4
Gerrit-Project: mediawiki/extensions/Translate
Gerrit-Branch: master
Gerrit-Owner: Nikerabbit <niklas.laxst...@gmail.com>
Gerrit-Reviewer: Santhosh <santhosh.thottin...@gmail.com>
Gerrit-Reviewer: Siebrand <siebr...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to