Jhernandez has uploaded a new change for review. https://gerrit.wikimedia.org/r/214320
Change subject: WIP: Show related pages when editing 1 item collection ...................................................................... WIP: Show related pages when editing 1 item collection When editing a collection if it has one item it will show related pages to that item to help creators of new collections fill their collections up. Depends on having the GettingStarted extension installed * http://www.mediawiki.org/wiki/Extension:GettingStarted * vagrant roles enable gettingstarted WIP because I can't get the extension to return meaningful results from the api so I can't actually test it. Bug: T100634 Change-Id: I53c82175b66465177d057c3a012631f526f63df2 --- M extension.json M includes/Gather.hooks.php A resources/ext.gather.api/RelatedPagesApi.js M resources/ext.gather.collection.editor/CollectionEditOverlay.js M resources/ext.gather.collection.editor/content.hogan A resources/ext.gather.relatedpages/RelatedPages.js A tests/qunit/ext.gather.api/test_RelatedPagesApi.js M tests/qunit/ext.gather.collection.editor/test_CollectionEditOverlay.js M tests/qunit/ext.gather.watchstar/test_CollectionsContentOverlay.js 9 files changed, 230 insertions(+), 4 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Gather refs/changes/20/214320/1 diff --git a/extension.json b/extension.json index 3723251..bda3f8e 100644 --- a/extension.json +++ b/extension.json @@ -189,7 +189,8 @@ "mobile.startup" ], "scripts": [ - "resources/ext.gather.api/CollectionsApi.js" + "resources/ext.gather.api/CollectionsApi.js", + "resources/ext.gather.api/RelatedPagesApi.js" ] }, "ext.gather.collections.list": { @@ -363,6 +364,20 @@ "minerva": "resources/ext.gather.init/minerva.less" } }, + "ext.gather.relatedpages": { + "targets": [ + "mobile", + "desktop" + ], + "dependencies": [ + "mobile.view", + "ext.gather.api", + "ext.gather.page.search" + ], + "scripts": [ + "resources/ext.gather.relatedpages/RelatedPages.js" + ] + }, "ext.gather.collection.editor": { "targets": [ "mobile", @@ -370,6 +385,7 @@ ], "dependencies": [ "ext.gather.page.search", + "ext.gather.relatedpages", "ext.gather.logging", "mobile.overlays", "mobile.toast", diff --git a/includes/Gather.hooks.php b/includes/Gather.hooks.php index 3e2302a..9f9bd8c 100644 --- a/includes/Gather.hooks.php +++ b/includes/Gather.hooks.php @@ -265,6 +265,7 @@ $modules['qunit']['ext.gather.api.tests'] = $boilerplate + array( 'scripts' => array( + 'ext.gather.api/test_RelatedPagesApi.js', ), 'dependencies' => array( 'ext.gather.api' ), ); diff --git a/resources/ext.gather.api/RelatedPagesApi.js b/resources/ext.gather.api/RelatedPagesApi.js new file mode 100644 index 0000000..ed97add --- /dev/null +++ b/resources/ext.gather.api/RelatedPagesApi.js @@ -0,0 +1,52 @@ +( function ( M, $ ) { + + var Api = M.require( 'api' ).Api, + RelatedPagesApi; + + /** + * API for managing collection items + * + * @class RelatedPagesApi + * @extends Api + */ + RelatedPagesApi = Api.extend( { + /** + * @method + * @param {String} title Title of the page to find related pages of. + * @param {Number} [limit] How many related pages to return. Defaults to 3. + * @returns {jQuery.Deferred} + */ + getRelatedPages: function ( title, limit ) { + limit = limit || 3; + + return this.get( { + action: 'query', + prop: 'pageimages', + piprop: 'thumbnail|name|original', + pilimit: limit, + pithumbsize: mw.config.get( 'wgMFThumbnailSizes' ).tiny, + generator: 'gettingstartedgetpages', + ggsgptaskname: 'morelike', + ggsgpexcludedtitle: title, + ggsgpcount: limit + } ).then( cleanApiResults ); + } + } ); + + /** + * Clean api results by extracting query.pages into an array + * @param {Object} results Results from the API to clean up + */ + function cleanApiResults( results ) { + if ( results && results.query && results.query.pages ) { + return $.map( results.query.pages, function ( p ) { + return p; + } ); + } else { + return null; + } + } + + M.define( 'ext.gather.api/RelatedPagesApi', RelatedPagesApi ); + +}( mw.mobileFrontend, jQuery ) ); diff --git a/resources/ext.gather.collection.editor/CollectionEditOverlay.js b/resources/ext.gather.collection.editor/CollectionEditOverlay.js index 640102b..df63f2e 100644 --- a/resources/ext.gather.collection.editor/CollectionEditOverlay.js +++ b/resources/ext.gather.collection.editor/CollectionEditOverlay.js @@ -9,7 +9,8 @@ SchemaGather = M.require( 'ext.gather.logging/SchemaGather' ), schema = new SchemaGather(), router = M.require( 'router' ), - CollectionDeleteOverlay = M.require( 'ext.gather.collection.delete/CollectionDeleteOverlay' ); + CollectionDeleteOverlay = M.require( 'ext.gather.collection.delete/CollectionDeleteOverlay' ), + RelatedPages = M.require( 'ext.gather.relatedpages/RelatedPages' ); /** * Overlay for editing a collection @@ -136,6 +137,15 @@ } ); self.searchPanel.on( 'change', $.proxy( self, 'onCollectionMembersChange' ) ); self.searchPanel.show(); + + // If there is only one element set up related results + if ( pages.length === 1 ) { + self.relatedPanel = new RelatedPages( { + title: pages[0].title, + el: self.$( '.related-pages' ) + } ); + self.relatedPanel.on( 'change', $.proxy( self, 'onCollectionMembersChange' ) ); + } } ); }, /** diff --git a/resources/ext.gather.collection.editor/content.hogan b/resources/ext.gather.collection.editor/content.hogan index 52523ad..99ea614 100644 --- a/resources/ext.gather.collection.editor/content.hogan +++ b/resources/ext.gather.collection.editor/content.hogan @@ -7,6 +7,7 @@ </div> </div> <div class="panel">{{{spinner}}}</div> + <div class="related-pages"></div> <div class="content"> <div class="actions"> <a class="mw-ui-button delete-action action">{{deleteMsg}}</a> diff --git a/resources/ext.gather.relatedpages/RelatedPages.js b/resources/ext.gather.relatedpages/RelatedPages.js new file mode 100644 index 0000000..8ae90c9 --- /dev/null +++ b/resources/ext.gather.relatedpages/RelatedPages.js @@ -0,0 +1,97 @@ +( function ( M, $ ) { + + var RelatedPagesApi = M.require( 'ext.gather.api/RelatedPagesApi' ), + View = M.require( 'View' ), + CollectionPageList = M.require( 'ext.gather.page.search/CollectionPageList' ), + icons = M.require( 'icons' ), + RelatedPages; + + /** + * @class RelatedPages + * @extends View + * @uses CollectionPageList + */ + RelatedPages = View.extend( { + defaults: { + spinner: icons.spinner().toHtmlString() + }, + /** @inheritdoc */ + initialize: function () { + this.api = new RelatedPagesApi(); + this.relatedPages = []; + this.pageList = null; + View.prototype.initialize.apply( this, arguments ); + this.search().then( $.proxy( this, 'render' ) ); + }, + /** @inheritdoc */ + postRender: function () { + var self = this, + pages = this.relatedPages; + if ( !this.pageList ) { + this.pageList = new CollectionPageList( { + pages: pages, + collection: this.options.collection, + el: this.$( '.results' ) + } ); + this.pageList.on( 'member-removed', function ( page ) { + self.change( page, true ); + } ); + this.pageList.on( 'member-added', function ( page ) { + self.change( page ); + } ); + } else { + this.pageList.options.pages = pages; + this.pageList.render(); + } + }, + /** + * Search for related pages + * @returns {$.Deferred} Resolves when results have updated + */ + search: function () { + var self = this, + title = this.options.title; + if ( title ) { + this.loading( true ); + this.relatedPages = []; + return this.api.getRelatedPages( title ).then( function ( relatedPages ) { + if ( relatedPages ) { + self.relatedPages = relatedPages; + } + } ).always( function () { + self.loading( false ); + } ); + } else { + return $.Deferred().reject( new Error( 'Invalid title' ) ); + } + }, + /** + * Respond to change on the list of members + * @param {Page} page + * @param {Boolean} isRemoved + */ + change: function ( page, isRemoved ) { + /** + * @event change + * @param {Page} page + * @param {Boolean} isRemoved + * Fired when the pages change from the collection + */ + this.emit( 'change', page, isRemoved ); + }, + /** + * Set loading state. When loading, set spinner, when not, clear up + * @param {Boolean} isLoading + */ + loading: function ( isLoading ) { + if ( isLoading ) { + this.$el.html( this.options.spinner ); + } else { + this.$( '.spinner' ).remove(); + } + } + } ); + + M.define( 'ext.gather.relatedpages/RelatedPages', RelatedPages ); + +}( mw.mobileFrontend, jQuery ) ); diff --git a/tests/qunit/ext.gather.api/test_RelatedPagesApi.js b/tests/qunit/ext.gather.api/test_RelatedPagesApi.js new file mode 100644 index 0000000..3ace8a3 --- /dev/null +++ b/tests/qunit/ext.gather.api/test_RelatedPagesApi.js @@ -0,0 +1,49 @@ +( function ( M, $ ) { + var Api = M.require( 'api' ).Api, + RelatedPagesApi = M.require( 'ext.gather.api/RelatedPagesApi' ), + relatedPages = { + query: { + pages: { + 123: { + id: 123, + title: 'Oh noes', + ns: 0, + thumbnail: { + source: 'http://placehold.it/200x100' + } + } + } + } + }, + emptyRelatedPages = { + query: { + pages: { + } + } + }; + + QUnit.module( 'Gather - Related pages api', { + /** @inherit */ + setup: function () { + } + } ); + + QUnit.test( 'Returns an array with the results when api responds', 2, function ( assert ) { + this.sandbox.stub( Api.prototype, 'get' ).returns( $.Deferred().resolve( relatedPages ) ); + var api = new RelatedPagesApi(); + api.getRelatedPages( 'Oh' ).then( function ( results ) { + assert.ok( $.isArray( results ), 'Results must be an array' ); + assert.strictEqual( results[0].title, 'Oh noes' ); + } ); + } ); + + QUnit.test( 'Empty related pages is handled fine.', 2, function ( assert ) { + this.sandbox.stub( Api.prototype, 'get' ).returns( $.Deferred().resolve( emptyRelatedPages ) ); + var api = new RelatedPagesApi(); + api.getRelatedPages( 'Oh' ).then( function ( results ) { + assert.ok( $.isArray( results ), 'Results must be an array' ); + assert.strictEqual( results.length, 0 ); + } ); + } ); + +}( mw.mobileFrontend, jQuery ) ); diff --git a/tests/qunit/ext.gather.collection.editor/test_CollectionEditOverlay.js b/tests/qunit/ext.gather.collection.editor/test_CollectionEditOverlay.js index 1fd73e6..8dc5d61 100644 --- a/tests/qunit/ext.gather.collection.editor/test_CollectionEditOverlay.js +++ b/tests/qunit/ext.gather.collection.editor/test_CollectionEditOverlay.js @@ -2,7 +2,7 @@ var CollectionEditOverlay = M.require( 'ext.gather.collection.edit/CollectionEditOverlay' ), CollectionsApi = M.require( 'ext.gather.api/CollectionsApi' ); - QUnit.module( 'Gather', { + QUnit.module( 'Gather: CollectionEditOverlay', { setup: function () { var collection, maxLengthDesc = CollectionEditOverlay.prototype.descriptionMaxLength, diff --git a/tests/qunit/ext.gather.watchstar/test_CollectionsContentOverlay.js b/tests/qunit/ext.gather.watchstar/test_CollectionsContentOverlay.js index 857bac8..e25ab77 100644 --- a/tests/qunit/ext.gather.watchstar/test_CollectionsContentOverlay.js +++ b/tests/qunit/ext.gather.watchstar/test_CollectionsContentOverlay.js @@ -7,7 +7,7 @@ var CollectionsApi = M.require( 'ext.gather.api/CollectionsApi' ), CollectionsContentOverlay = M.require( 'ext.gather.watchstar/CollectionsContentOverlay' ); - QUnit.module( 'Gather', { + QUnit.module( 'Gather: Add to collection overlay', { setup: function () { var d = $.Deferred().resolve( { id: 2 -- To view, visit https://gerrit.wikimedia.org/r/214320 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I53c82175b66465177d057c3a012631f526f63df2 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Gather Gerrit-Branch: master Gerrit-Owner: Jhernandez <[email protected]> _______________________________________________ MediaWiki-commits mailing list [email protected] https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
