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