Robmoen has uploaded a new change for review. https://gerrit.wikimedia.org/r/207002
Change subject: WIP: Create collection button on Special:Gather ...................................................................... WIP: Create collection button on Special:Gather Allows creation of a collection from a users list of collections. * Add is-owner data property to collection list * Created CreateCollectionButton class * Make collection api allow edits to a collection with a null id. * Make tweaks to CollectionEditOverlay to allow initial null collection id TODO: Minor styling, button icon and some i18n Bug: T95214 Change-Id: I9f845238d43b3696fd1b3b1ceacef51d9f34ec75 --- M includes/models/CollectionsList.php M includes/specials/SpecialGather.php M includes/views/CollectionsList.php M resources/Resources.php M resources/ext.gather.api/CollectionsApi.js M resources/ext.gather.collection.editor/CollectionEditOverlay.js M resources/ext.gather.collection.editor/content.hogan A resources/ext.gather.special/CreateCollectionButton.js M resources/ext.gather.special/init.js 9 files changed, 122 insertions(+), 35 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Gather refs/changes/02/207002/1 diff --git a/includes/models/CollectionsList.php b/includes/models/CollectionsList.php index 9f09027..c5eeb3d 100644 --- a/includes/models/CollectionsList.php +++ b/includes/models/CollectionsList.php @@ -93,6 +93,15 @@ } /** + * Returns if the user is the owner of the list of collections + * @param User $user user to check if it is the owner + * @return boolean + */ + public function isOwner( User $user ) { + return $this->user->equals( $user ); + } + + /** * Return local url for list of collections * Example: /wiki/Special:Gather/by/user * diff --git a/includes/specials/SpecialGather.php b/includes/specials/SpecialGather.php index 0246c9a..960c16a 100644 --- a/includes/specials/SpecialGather.php +++ b/includes/specials/SpecialGather.php @@ -191,7 +191,7 @@ wfMessage( 'gather-meta-description', $user->getName() ), models\Image::getThumbnail( $collectionsList->getFile() ) ); - $this->render( new views\CollectionsList( $collectionsList ) ); + $this->render( new views\CollectionsList( $this->getUser(), $collectionsList ) ); } else { $this->renderError( new views\NoPublic() ); } diff --git a/includes/views/CollectionsList.php b/includes/views/CollectionsList.php index 12db333..2721729 100644 --- a/includes/views/CollectionsList.php +++ b/includes/views/CollectionsList.php @@ -13,9 +13,11 @@ */ class CollectionsList extends View { /** + * @param User $user that is viewing the collection * @param models\CollectionsList $collectionsList */ - public function __construct( $collectionsList ) { + public function __construct( $user, $collectionsList ) { + $this->user = $user; $this->collectionsList = $collectionsList; } @@ -56,7 +58,10 @@ public function getHtml( $data = array() ) { $html = Html::openElement( 'div', - array( 'class' => 'collections-list content view-border-box' ) + array( + 'class' => 'collections-list content view-border-box', + 'data-is-owner' => $this->collectionsList->isOwner( $this->user ) ? true : false, + ) ); // Get items $html .= $this->getListItemsHtml( $this->collectionsList ); diff --git a/resources/Resources.php b/resources/Resources.php index 8b9cade..12fd082 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -345,6 +345,7 @@ 'ext.gather.moderation', ), 'scripts' => array( + 'ext.gather.special/CreateCollectionButton.js', 'ext.gather.special/init.js', ), 'messages' => array( diff --git a/resources/ext.gather.api/CollectionsApi.js b/resources/ext.gather.api/CollectionsApi.js index 8ff4146..1a08afa 100644 --- a/resources/ext.gather.api/CollectionsApi.js +++ b/resources/ext.gather.api/CollectionsApi.js @@ -207,20 +207,23 @@ /** * Edits a collection * @method - * @param {Number} id unique identifier of collection + * @param {Number} id optional unique identifier of collection * @param {String} title of collection * @param {String} description of collection * @param {Boolean} isPrivate whether it should be stored as private * @return {jQuery.Promise} */ editCollection: function ( id, title, description, isPrivate ) { - return this.postWithToken( 'watch', { + var params = { action: 'editlist', - id: id, label: title, description: description, perm: isPrivate ? 'private' : 'public' - } ); + }; + if ( id !== null ) { + params.id = id; + } + return this.postWithToken( 'watch', params ); }, /** * Set collection privacy diff --git a/resources/ext.gather.collection.editor/CollectionEditOverlay.js b/resources/ext.gather.collection.editor/CollectionEditOverlay.js index a38a26a..0fffe2b 100644 --- a/resources/ext.gather.collection.editor/CollectionEditOverlay.js +++ b/resources/ext.gather.collection.editor/CollectionEditOverlay.js @@ -75,26 +75,32 @@ } ), /** @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(); - Overlay.prototype.initialize.apply( this, arguments ); + if ( options && options.collection ) { + this.id = options.collection.id; } + this.api = new CollectionsApi(); + Overlay.prototype.initialize.apply( this, arguments ); this.$clear = this.$( '.search-header .clear' ); }, /** @inheritdoc */ - postRender: function ( options ) { - var self = this, - id = this.id; - + postRender: function () { + var id = this.id; Overlay.prototype.postRender.apply( this, arguments ); - this.api.getCollectionMembers( id ).done( function ( pages ) { + + if ( id ) { + this.populateCollectionMembers(); + } else { + this.id = null; + this._switchToEditPane(); + } + + }, + populateCollectionMembers: function () { + var self = this; + $( '.manage-members-pane' ).removeClass( 'hidden' ); + this.api.getCollectionMembers( this.id ).done( function ( pages ) { self.searchPanel = new CollectionSearchPanel( { - collection: options.collection, + collection: self.options.collection, pages: pages, el: self.$( '.panel' ) } ); @@ -189,12 +195,15 @@ * Event handler when the back button is clicked on the title/edit description pane. */ onBackClick: function () { - var collection = this.options.collection; - // reset the values to their original values. - this.$( 'input.title' ).val( collection.title ); - this.$( '.description' ).val( collection.description ); - // Note: we will need to reset checkbox when enabling private/public toggle. - this._switchToFirstPane(); + if ( this.id ) { + // reset the values to their original values. + this.$( 'input.title' ).val( this.options.collection.title ); + this.$( '.description' ).val( this.options.collection.description ); + // Note: we will need to reset checkbox when enabling private/public toggle. + this._switchToFirstPane(); + } else { + Overlay.prototype.hide.apply( this, arguments ); + } }, /** * Refresh the page @@ -211,14 +220,15 @@ */ onFirstPaneSaveClick: function () { var self = this; - if ( this._stateChanged ) { - this.hide(); - this._reloadCollection(); - } else if ( this.searchPanel.hasChanges() ) { + + if ( this.searchPanel.hasChanges() ) { this.$( '.save' ).prop( 'disabled', true ); this.searchPanel.saveChanges().done( function () { self._reloadCollection(); } ); + } else if ( this._stateChanged ) { + this.hide(); + this._reloadCollection(); } else { // nothing to do. self.hide(); @@ -238,7 +248,7 @@ // disable button and inputs this.showSpinner(); this.$( '.mw-ui-input, .save-description' ).prop( 'disabled', true ); - this.api.editCollection( this.id, title, description, isPrivate ).done( function () { + this.api.editCollection( this.id, title, description, isPrivate ).done( function ( data ) { schema.log( { eventName: 'edit-collection' } ).always( function () { @@ -248,6 +258,16 @@ } ); self.$( '.mw-ui-input, .save-description' ).prop( 'disabled', false ); toast.show( self.options.editSuccessMsg, 'toast' ); + if ( self.id === null ) { + // Set the overlay id to the newly created collection id + self.id = data.editlist.id; + self.options.collection = { + id: data.editlist.id, + title: title, + description: description + }; + self.populateCollectionMembers(); + } } ).fail( function ( errMsg ) { toast.show( self.options.editFailedError, 'toast error' ); // Make it possible to try again. diff --git a/resources/ext.gather.collection.editor/content.hogan b/resources/ext.gather.collection.editor/content.hogan index 75ead4b..c2c249f 100644 --- a/resources/ext.gather.collection.editor/content.hogan +++ b/resources/ext.gather.collection.editor/content.hogan @@ -1,4 +1,4 @@ -<div class="manage-members-pane"> +<div class="manage-members-pane hidden"> <div class="panel">{{{spinner}}}</div> <div class="content"> <button class="mw-ui-button mw-ui-progressive edit-action action">{{editMsg}}</button> diff --git a/resources/ext.gather.special/CreateCollectionButton.js b/resources/ext.gather.special/CreateCollectionButton.js new file mode 100644 index 0000000..b47800b --- /dev/null +++ b/resources/ext.gather.special/CreateCollectionButton.js @@ -0,0 +1,42 @@ +( function ( M ) { + + var CollectionEditOverlay = M.require( 'ext.gather.edit/CollectionEditOverlay' ), + Button = M.require( 'Button' ), + CreateCollectionButton; + + /** + * A button used to create a collection + * @class CreateCollectionButton + * @extends Button + */ + CreateCollectionButton = Button.extend( { + /** @inheritdoc */ + defaults: { + tagName: 'div', + progressive: true, + label: 'Create a collection' + }, + events: { + click: 'onCreateCollectionButtonClick' + }, + /** @inheritdoc */ + postRender: function () { + Button.prototype.postRender.apply( this, arguments ); + this.$el.attr( 'title', this.options.title ); + }, + /** + * Click handler for create collection button + * @param {Object} ev Event Object + */ + onCreateCollectionButtonClick: function ( ev ) { + var editOverlay; + ev.stopPropagation(); + ev.preventDefault(); + + editOverlay = new CollectionEditOverlay(); + editOverlay.show(); + } + } ); + M.define( 'ext.gather.special/CreateCollectionButton', CreateCollectionButton ); + +}( mw.mobileFrontend ) ); diff --git a/resources/ext.gather.special/init.js b/resources/ext.gather.special/init.js index fa71e38..1a997b8 100644 --- a/resources/ext.gather.special/init.js +++ b/resources/ext.gather.special/init.js @@ -1,9 +1,11 @@ ( function ( M, $ ) { - var CollectionFlagButton = M.require( 'ext.gather.flag/CollectionFlagButton' ); + var CollectionFlagButton = M.require( 'ext.gather.flag/CollectionFlagButton' ), + CreateCollectionButton = M.require( 'ext.gather.special/CreateCollectionButton' ); $( function () { - var $collection = $( '.collection' ); + var $collection = $( '.collection' ), + $collectionsList = $( '.collections-list' ); if ( !$collection.data( 'is-owner' ) && mw.config.get( 'skin' ) === 'minerva' ) { new CollectionFlagButton( { @@ -11,6 +13,11 @@ } ).prependTo( '.collection-moderation' ); } + // If the viewer is looking at their own collections list + if ( $collectionsList.length !== 0 && $collectionsList.data( 'is-owner' ) ) { + new CreateCollectionButton().appendTo( $collectionsList ); + } + $( '.collection-actions' ).addClass( 'visible' ); } ); }( mw.mobileFrontend, jQuery ) ); -- To view, visit https://gerrit.wikimedia.org/r/207002 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9f845238d43b3696fd1b3b1ceacef51d9f34ec75 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