Robmoen has uploaded a new change for review. https://gerrit.wikimedia.org/r/204201
Change subject: Add flag collection button and overlay ...................................................................... Add flag collection button and overlay Added flag icon to collection when not watchlist or ** collection owner Factored ConfirmationOverlay from CollectionDeleteOverlay Added CollectionFlagOverlay for flag confirmation Added SchemaGatherFlags NEEDS: * Review * Schema logging tested * userGroups is currently an empty string bug: T94871 Change-Id: I1b732712573a4f71d60434a80191964544219508 --- M i18n/en.json M i18n/qqq.json M includes/Gather.hooks.php M includes/views/Collection.php M resources/Resources.php A resources/ext.gather.collection.confirm/ConfirmationOverlay.js A resources/ext.gather.collection.confirm/confirmationOverlay.hogan C resources/ext.gather.collection.confirm/confirmationOverlay.less M resources/ext.gather.collection.delete/CollectionDeleteOverlay.js A resources/ext.gather.collection.flag/CollectionFlagOverlay.js R resources/ext.gather.collection.flag/content.hogan R resources/ext.gather.collection.flag/flagOverlay.less A resources/ext.gather.icons/flag.svg A resources/ext.gather.logging/SchemaGatherFlags.js M resources/ext.gather.special/init.js M resources/ext.gather.styles/collections.less 16 files changed, 265 insertions(+), 69 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Gather refs/changes/01/204201/1 diff --git a/i18n/en.json b/i18n/en.json index 567ead9..b974dce 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -40,9 +40,13 @@ "gather-delete-collection-confirm": "Are you sure you want to delete this collection?", "gather-delete-collection-heading": "Delete collection", "gather-delete-collection-delete-label": "Delete", - "gather-delete-collection-cancel-label": "Cancel", "gather-delete-collection-success": "Collection was successfully deleted.", "gather-delete-collection-failed-error": "There was a problem deleting this collection.", + "gather-flag-collection-heading": "Flag collection", + "gather-flag-collection-confirm": "Are you sure you want to flag this collection for review?", + "gather-flag-collection-flag-label": "Flag", + "gather-flag-collection-success": "Collection was successfully flagged.", + "gather-confirmation-cancel-button-label": "Cancel", "gather-error-unknown-collection": "Cannot find the requested collection to edit.", "gather-collection-member": "Is member of collection.", "gather-collection-non-member": "Is not member of collection.", diff --git a/i18n/qqq.json b/i18n/qqq.json index d7a66ff..1d1c9b4 100644 --- a/i18n/qqq.json +++ b/i18n/qqq.json @@ -43,11 +43,15 @@ "gather-edit-collection-save-label": "Label for save button in collection editor.\n{{Identical|Done}}", "gather-edit-collection-failed-error": "There was a problem saving the changes.", "gather-delete-collection-confirm": "Text under the heading asking the user if they would like to delete a collection.", - "gather-delete-collection-heading": "Heading for collection delete overlay", - "gather-delete-collection-delete-label": "Label for delete button in delete overlay.\n{{Identical|Delete}}", - "gather-delete-collection-cancel-label": "Label for cancel button in delete overlay.\n{{Identical|Cancel}}", + "gather-delete-collection-heading": "Heading for collection delete confirmation overlay", + "gather-delete-collection-delete-label": "Label for delete button in delete confirmation overlay.\n{{Identical|Delete}}", "gather-delete-collection-success": "Toast message indicating that deletion was successful.", "gather-delete-collection-failed-error": "Toast error indicating there was a problem deleting the collection.", + "gather-flag-collection-heading": "Heading text for collection flag conirmation overlay", + "gather-flag-collection-confirm": "Text under the heading asking the user if they would like to flag a collection for review.", + "gather-flag-collection-flag-label": "Label for flag button in flag collection confirmation overlay.", + "gather-flag-collection-success": "Toast message indicating that flagging the collection was successful.", + "gather-confirmation-cancel-button-label": "Label for cancel button in confirmation overlay.\n{{Identical|Cancel}}", "gather-error-unknown-collection": "Error message test when you try to edit a collection you do not own or that does not exist.", "gather-collection-member": "Alternative text displayed next to collection name when page is a member.", "gather-collection-non-member": "Alternative text displayed next to collection name when page is not a member.", diff --git a/includes/Gather.hooks.php b/includes/Gather.hooks.php index 119e5cb..5351ff1 100644 --- a/includes/Gather.hooks.php +++ b/includes/Gather.hooks.php @@ -62,8 +62,9 @@ public static function onEventLoggingRegisterSchemas( &$schemas ) { $schemas += array( 'GatherClicks' => 11770314, + 'GatherFlags' => 11793295, ); - self::registerSchemas( array( 'schema.GatherClicks' ) ); + self::registerSchemas( array( 'schema.GatherClicks', 'schema.GatherFlags' ) ); return true; } diff --git a/includes/views/Collection.php b/includes/views/Collection.php index 3abde95..4492740 100644 --- a/includes/views/Collection.php +++ b/includes/views/Collection.php @@ -50,7 +50,10 @@ $privacy = $collection->isPublic() ? 'Public' : 'Private'; } - $html = Html::openElement( 'div', array( 'class' => 'collection-header' ) ) . + $html = Html::openElement( 'div', array( 'class' => 'collection-moderation' ) ) . + $this->getModerationButtons() . + Html::closeElement( 'div' ) . + Html::openElement( 'div', array( 'class' => 'collection-header' ) ) . Html::openElement( 'div', array( 'class' => 'collection-meta' ) ) . Html::element( 'div', array( 'class' => 'collection-privacy' ), $privacy ) . Html::closeElement( 'div' ) . @@ -80,6 +83,26 @@ $owner->getName() . Html::closeElement( 'a' ); } + /** + * Returns the html for moderation buttons + * + * @return string Html + */ + private function getModerationButtons() { + $id = $this->collection->getId(); + // Don't show for watchlist as its private, don't show for owner + if ( $id !== 0 && !$this->collection->isOwner( $this->user ) ) { + return Html::openElement( 'a', array( + 'href' => '#/collection/flag/' . $id, + 'class' => 'collection-flag', + ) ) . + Html::element( 'span', array( + 'class' => CSS::iconClass( 'collection-flag', 'before', 'collection-flag-icon' ) ) ) . + Html::closeElement( 'a' ); + } else { + return ''; + } + } /** * Get action buttons of the header diff --git a/resources/Resources.php b/resources/Resources.php index a1f6385..9adb9d5 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -63,6 +63,7 @@ 'images' => array( 'collections-read-more' => 'ext.gather.icons/next.svg', 'collection-owner' => 'ext.gather.icons/user.svg', + 'collection-flag' => 'ext.gather.icons/flag.svg', ), ), @@ -96,6 +97,7 @@ ), 'scripts' => array( 'ext.gather.logging/SchemaGather.js', + 'ext.gather.logging/SchemaGatherFlags.js', ), ), @@ -119,6 +121,25 @@ ), 'scripts' => array( 'ext.gather.collection.base/CollectionsContentOverlayBase.js', + ), + ), + + 'ext.gather.collection.confirm' => $wgGatherResourceFileModuleBoilerplate + array( + 'dependencies' => array( + 'ext.gather.collection.base', + ), + 'styles' => array( + 'ext.gather.collection.confirm/confirmationOverlay.less', + ), + 'messages' => array( + 'gather-error-unknown-collection', + 'gather-confirmation-cancel-button-label', + ), + 'templates' => array( + 'confirmationOverlay.hogan' => 'ext.gather.collection.confirm/confirmationOverlay.hogan', + ), + 'scripts' => array( + 'ext.gather.collection.confirm/ConfirmationOverlay.js', ), ), @@ -241,7 +262,7 @@ 'ext.gather.collection.delete' => $wgGatherResourceFileModuleBoilerplate + array( 'dependencies' => array( - 'ext.gather.collection.base', + 'ext.gather.collection.confirm', 'mobile.toast', 'ext.gather.api', 'mediawiki.util' @@ -250,19 +271,29 @@ 'gather-delete-collection-confirm', 'gather-delete-collection-heading', 'gather-delete-collection-delete-label', - 'gather-delete-collection-cancel-label', 'gather-delete-collection-success', 'gather-delete-collection-failed-error', - 'gather-error-unknown-collection', - ), - 'templates' => array( - 'content.hogan' => 'ext.gather.collection.delete/content.hogan', ), 'scripts' => array( 'ext.gather.collection.delete/CollectionDeleteOverlay.js', ), - 'styles' => array( - 'ext.gather.collection.delete/deleteOverlay.less', + ), + + 'ext.gather.collection.flag' => $wgGatherResourceFileModuleBoilerplate + array( + 'dependencies' => array( + 'ext.gather.collection.confirm', + 'mobile.toast', + 'ext.gather.api', + 'mediawiki.util' + ), + 'messages' => array( + 'gather-flag-collection-confirm', + 'gather-flag-collection-heading', + 'gather-flag-collection-flag-label', + 'gather-flag-collection-success', + ), + 'scripts' => array( + 'ext.gather.collection.flag/CollectionFlagOverlay.js', ), ), @@ -270,6 +301,7 @@ 'dependencies' => array( 'ext.gather.collection.editor', 'ext.gather.collection.delete', + 'ext.gather.collection.flag', ), 'scripts' => array( 'ext.gather.special/init.js', diff --git a/resources/ext.gather.collection.confirm/ConfirmationOverlay.js b/resources/ext.gather.collection.confirm/ConfirmationOverlay.js new file mode 100644 index 0000000..aa3ee26 --- /dev/null +++ b/resources/ext.gather.collection.confirm/ConfirmationOverlay.js @@ -0,0 +1,54 @@ +( function ( M, $ ) { + + var ConfirmationOverlay, + toast = M.require( 'toast' ), + icons = M.require( 'icons' ), + CollectionsContentOverlayBase = M.require( 'ext.gather.collection.base/CollectionsContentOverlayBase' ); + + /** + * Action confirmation overlay base class + * @extends CollectionsContentOverlayBase + * @class ConfirmationOverlay + */ + ConfirmationOverlay = CollectionsContentOverlayBase.extend( { + /** @inheritdoc */ + className: 'collection-confirmation-overlay content-overlay position-fixed', + /** @inheritdoc */ + defaults: $.extend( {}, CollectionsContentOverlayBase.prototype.defaults, { + fixedHeader: false, + collection: null, + spinner: icons.spinner().toHtmlString(), + unknownCollectionError: mw.msg( 'gather-error-unknown-collection' ), + cancelButtonClass: 'mw-ui-progressive', + cancelButtonLabel: mw.msg( 'gather-confirmation-cancel-button-label' ) + } ), + /** @inheritdoc */ + events: $.extend( {}, CollectionsContentOverlayBase.prototype.events, { + 'click .cancel': 'onCancelClick' + } ), + /** @inheritdoc */ + templatePartials: $.extend( {}, CollectionsContentOverlayBase.prototype.templatePartials, { + content: mw.template.get( 'ext.gather.collection.confirm', 'confirmationOverlay.hogan' ) + } ), + /** @inheritdoc */ + initialize: function ( options ) { + var collection = options.collection; + if ( !collection ) { + // use toast + toast.show( options.unknownCollectionError, 'toast error' ); + } else { + this.id = collection.id; + CollectionsContentOverlayBase.prototype.initialize.apply( this, arguments ); + } + }, + /** + * Event handler when the cancel button is clicked. + */ + onCancelClick: function () { + this.hide(); + } + } ); + + M.define( 'ext.gather.confirm/ConfirmationOverlay', ConfirmationOverlay ); + +}( mw.mobileFrontend, jQuery ) ); diff --git a/resources/ext.gather.collection.confirm/confirmationOverlay.hogan b/resources/ext.gather.collection.confirm/confirmationOverlay.hogan new file mode 100644 index 0000000..a16bb72 --- /dev/null +++ b/resources/ext.gather.collection.confirm/confirmationOverlay.hogan @@ -0,0 +1,9 @@ +{{{spinner}}} +<div class="confirm-collection-content"> + <h3>{{subheading}}</h3> + <span>{{confirmMessage}}</span> + <div class="collection-confirm-actions"> + <button class='mw-ui-button {{confirmButtonClass}} confirm'>{{confirmButtonLabel}}</button> + <button class='mw-ui-button {{cancelButtonClass}} cancel'>{{cancelButtonLabel}}</button> + </div> +</div> diff --git a/resources/ext.gather.collection.delete/deleteOverlay.less b/resources/ext.gather.collection.confirm/confirmationOverlay.less similarity index 78% copy from resources/ext.gather.collection.delete/deleteOverlay.less copy to resources/ext.gather.collection.confirm/confirmationOverlay.less index b1912b8..00e7c5e 100644 --- a/resources/ext.gather.collection.delete/deleteOverlay.less +++ b/resources/ext.gather.collection.confirm/confirmationOverlay.less @@ -1,7 +1,7 @@ @import "minerva.variables"; @import "minerva.mixins"; -.content-overlay.collection-delete-overlay { +.content-overlay.collection-confirmation-overlay { font-size: .9em; text-align: center; @@ -14,7 +14,7 @@ padding: 0.5em; } - .collection-delete-actions { + .collection-confirm-actions { padding: 0.5em; } diff --git a/resources/ext.gather.collection.delete/CollectionDeleteOverlay.js b/resources/ext.gather.collection.delete/CollectionDeleteOverlay.js index 1ce42d4..f54668a 100644 --- a/resources/ext.gather.collection.delete/CollectionDeleteOverlay.js +++ b/resources/ext.gather.collection.delete/CollectionDeleteOverlay.js @@ -4,60 +4,41 @@ SchemaGather = M.require( 'ext.gather.logging/SchemaGather' ), schema = new SchemaGather(), toast = M.require( 'toast' ), - icons = M.require( 'icons' ), CollectionsApi = M.require( 'ext.gather.watchstar/CollectionsApi' ), - CollectionsContentOverlayBase = M.require( 'ext.gather.collection.base/CollectionsContentOverlayBase' ); + ConfirmationOverlay = M.require( 'ext.gather.confirm/ConfirmationOverlay' ); /** * Overlay for deleting a collection - * @extends CollectionsContentOverlayBase + * @extends ConfirmationOverlay * @class CollectionDeleteOverlay */ - CollectionDeleteOverlay = CollectionsContentOverlayBase.extend( { + CollectionDeleteOverlay = ConfirmationOverlay.extend( { /** @inheritdoc */ - className: 'collection-delete-overlay content-overlay position-fixed', - /** @inheritdoc */ - defaults: $.extend( {}, CollectionsContentOverlayBase.prototype.defaults, { - fixedHeader: false, - collection: null, - spinner: icons.spinner().toHtmlString(), + defaults: $.extend( {}, ConfirmationOverlay.prototype.defaults, { deleteSuccessMsg: mw.msg( 'gather-delete-collection-success' ), deleteFailedError: mw.msg( 'gather-delete-collection-failed-error' ), - unknownCollectionError: mw.msg( 'gather-error-unknown-collection' ), - subheadingDeleteCollection: mw.msg( 'gather-delete-collection-heading' ), + subheading: mw.msg( 'gather-delete-collection-heading' ), confirmMessage: mw.msg( 'gather-delete-collection-confirm' ), - deleteButtonLabel: mw.msg( 'gather-delete-collection-delete-label' ), - cancelButtonLabel: mw.msg( 'gather-delete-collection-cancel-label' ) + confirmButtonClass: 'mw-ui-destructive', + confirmButtonLabel: mw.msg( 'gather-delete-collection-delete-label' ) } ), /** @inheritdoc */ - events: $.extend( {}, CollectionsContentOverlayBase.prototype.events, { - 'click .delete-collection': 'onDeleteClick', - 'click .cancel-delete': 'onCancelClick' + events: $.extend( {}, ConfirmationOverlay.prototype.events, { + 'click .confirm': 'onDeleteClick' } ), /** @inheritdoc */ - templatePartials: $.extend( {}, CollectionsContentOverlayBase.prototype.templatePartials, { - content: mw.template.get( 'ext.gather.collection.delete', 'content.hogan' ) - } ), - /** @inheritdoc */ - initialize: function ( options ) { - var collection = options.collection; - if ( !collection ) { - // use toast - toast.show( options.unknownCollectionError, 'toast error' ); - } else { - this.id = collection.id; - this.api = new CollectionsApi(); - CollectionsContentOverlayBase.prototype.initialize.apply( this, arguments ); - } + initialize: function () { + this.api = new CollectionsApi(); + ConfirmationOverlay.prototype.initialize.apply( this, arguments ); }, /** - * Event handler when the save button is clicked. + * Event handler when the delete button is clicked. */ onDeleteClick: function () { var self = this; this.showSpinner(); // disable button and inputs - this.$( '.delete-collection, .cancel-delete' ).prop( 'disabled', true ); + this.$( '.confirm, .cancel' ).prop( 'disabled', true ); this.api.removeCollection( this.id ).done( function () { // Show toast self.$( '.spinner' ).hide(); @@ -74,18 +55,12 @@ toast.show( self.options.deleteFailedError, 'toast error' ); self.hide(); // Make it possible to try again. - self.$( '.delete-collection, .cancel-delete' ).prop( 'disabled', false ); + self.$( '.confirm, .cancel' ).prop( 'disabled', false ); schema.log( { eventName: 'delete-collection-error', errorText: errMsg } ); } ); - }, - /** - * Event handler when the cancel button is clicked. - */ - onCancelClick: function () { - this.hide(); } } ); diff --git a/resources/ext.gather.collection.flag/CollectionFlagOverlay.js b/resources/ext.gather.collection.flag/CollectionFlagOverlay.js new file mode 100644 index 0000000..b2e55d7 --- /dev/null +++ b/resources/ext.gather.collection.flag/CollectionFlagOverlay.js @@ -0,0 +1,46 @@ +( function ( M, $ ) { + + var CollectionFlagOverlay, + ConfirmationOverlay = M.require( 'ext.gather.confirm/ConfirmationOverlay' ), + SchemaGatherFlags = M.require( 'ext.gather.logging/SchemaGatherFlags' ), + schema = new SchemaGatherFlags(), + toast = M.require( 'toast' ); + + /** + * Overlay for deleting a collection + * @extends ConfirmationOverlay + * @class CollectionFlagOverlay + */ + CollectionFlagOverlay = ConfirmationOverlay.extend( { + /** @inheritdoc */ + defaults: $.extend( {}, ConfirmationOverlay.prototype.defaults, { + flagSuccessMsg: mw.msg( 'gather-flag-collection-success' ), + subheading: mw.msg( 'gather-flag-collection-heading' ), + confirmMessage: mw.msg( 'gather-flag-collection-confirm' ), + confirmButtonClass: 'mw-ui-destructive', + confirmButtonLabel: mw.msg( 'gather-flag-collection-flag-label' ) + } ), + /** @inheritdoc */ + events: $.extend( {}, ConfirmationOverlay.prototype.events, { + 'click .confirm': 'onFlagClick' + } ), + /** + * Event handler when the delete button is clicked. + */ + onFlagClick: function () { + var self = this; + this.showSpinner(); + // disable buttons + this.$( '.confirm, .cancel' ).prop( 'disabled', true ); + schema.log( { + collectionId: self.id + } ).always( function () { + toast.show( self.options.flagSuccessMsg, 'toast' ); + self.hide(); + } ); + } + } ); + + M.define( 'ext.gather.flag/CollectionFlagOverlay', CollectionFlagOverlay ); + +}( mw.mobileFrontend, jQuery ) ); diff --git a/resources/ext.gather.collection.delete/content.hogan b/resources/ext.gather.collection.flag/content.hogan similarity index 100% rename from resources/ext.gather.collection.delete/content.hogan rename to resources/ext.gather.collection.flag/content.hogan diff --git a/resources/ext.gather.collection.delete/deleteOverlay.less b/resources/ext.gather.collection.flag/flagOverlay.less similarity index 80% rename from resources/ext.gather.collection.delete/deleteOverlay.less rename to resources/ext.gather.collection.flag/flagOverlay.less index b1912b8..e99838d 100644 --- a/resources/ext.gather.collection.delete/deleteOverlay.less +++ b/resources/ext.gather.collection.flag/flagOverlay.less @@ -1,7 +1,7 @@ @import "minerva.variables"; @import "minerva.mixins"; -.content-overlay.collection-delete-overlay { +.content-overlay.collection-flag-overlay { font-size: .9em; text-align: center; @@ -14,7 +14,7 @@ padding: 0.5em; } - .collection-delete-actions { + .collection-flag-actions { padding: 0.5em; } diff --git a/resources/ext.gather.icons/flag.svg b/resources/ext.gather.icons/flag.svg new file mode 100644 index 0000000..4cbf19a --- /dev/null +++ b/resources/ext.gather.icons/flag.svg @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve"> +<path d="M13,7.5c0-0.6,0-1.1,0-1.5c-1.4-1.5-5.2-1.2-6,0c0-1,0-1,0-1H6v15h1c0,0,0-3.1,0-7c0.8-0.8,3.4-0.9,5-0.5c0,0.6,0,1.1,0,1.5 + c1.2,1.5,4.3,1.2,5,0V7C16.3,7.7,14.3,7.9,13,7.5z"/> +</svg> diff --git a/resources/ext.gather.logging/SchemaGatherFlags.js b/resources/ext.gather.logging/SchemaGatherFlags.js new file mode 100644 index 0000000..25b5ddf --- /dev/null +++ b/resources/ext.gather.logging/SchemaGatherFlags.js @@ -0,0 +1,30 @@ +( function ( M, $ ) { + var SchemaGatherFlags, + Schema = M.require( 'Schema' ), + user = M.require( 'user' ); + + /** + * @class SchemaGatherFlags + * @extends Schema + */ + SchemaGatherFlags = Schema.extend( { + /** + * @inheritdoc + */ + defaults: $.extend( {}, Schema.prototype.defaults, { + userId: mw.user.getId(), + // FIXME: use mw.user when method available + // Null when user is anon, set to 0 + userEditCount: user.getEditCount() || 0, + // FIXME: Needs + userGroups: '' + } ), + /** + * @inheritdoc + */ + name: 'GatherFlags' + } ); + + M.define( 'ext.gather.logging/SchemaGatherFlags', SchemaGatherFlags ); + +}( mw.mobileFrontend, jQuery ) ); diff --git a/resources/ext.gather.special/init.js b/resources/ext.gather.special/init.js index 919fe98..bcd6753 100644 --- a/resources/ext.gather.special/init.js +++ b/resources/ext.gather.special/init.js @@ -2,6 +2,7 @@ var CollectionEditOverlay = M.require( 'ext.gather.edit/CollectionEditOverlay' ), CollectionDeleteOverlay = M.require( 'ext.gather.delete/CollectionDeleteOverlay' ), + CollectionFlagOverlay = M.require( 'ext.gather.flag/CollectionFlagOverlay' ), toast = M.require( 'toast' ), overlayManager = M.require( 'overlayManager' ); @@ -11,17 +12,22 @@ var collection = mw.config.get( 'wgGatherCollections' ); if ( collection ) { - if ( action === 'edit' ) { - return new CollectionEditOverlay( { - collection: collection - } ); - } else if ( action === 'delete' ) { - return new CollectionDeleteOverlay( { - collection: collection - } ); - } else { - toast.show( mw.msg( 'gather-no-such-action' ), 'error' ); - return $.Deferred(); + switch ( action ) { + case 'edit': + return new CollectionEditOverlay( { + collection: collection + } ); + case 'delete': + return new CollectionDeleteOverlay( { + collection: collection + } ); + case 'flag': + return new CollectionFlagOverlay( { + collection: collection + } ); + default: + toast.show( mw.msg( 'gather-no-such-action' ), 'error' ); + return $.Deferred(); } } else { toast.show( mw.msg( 'gather-unknown-error' ), 'error' ); diff --git a/resources/ext.gather.styles/collections.less b/resources/ext.gather.styles/collections.less index 84d3c90..af86550 100644 --- a/resources/ext.gather.styles/collections.less +++ b/resources/ext.gather.styles/collections.less @@ -42,6 +42,10 @@ margin-top: 0; padding-top: 0; } + .collection-moderation { + position: absolute; + right: 0; + } .collection-header { text-align: center; -- To view, visit https://gerrit.wikimedia.org/r/204201 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1b732712573a4f71d60434a80191964544219508 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Gather Gerrit-Branch: master Gerrit-Owner: Robmoen <rm...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits