Skip to content

Commit

Permalink
Redirect to Massviews with auto-PagePile if user requests over 10 pages
Browse files Browse the repository at this point in the history
More JSDoc, some minor fixes

Bug: T142325
  • Loading branch information
MusikAnimal committed Aug 10, 2016
1 parent f4861ce commit e1fda62
Show file tree
Hide file tree
Showing 19 changed files with 413 additions and 244 deletions.
14 changes: 14 additions & 0 deletions javascripts/massviews/massviews.js
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,20 @@ class MassViews extends mix(Pv).with(ChartHelpers, ListHelpers) {

this.patchUsage('mv');

/**
* If they requested more than 10 pages in Pageviews (via typing it in the URL)
* they are redirected to Massviews with an auto-generated PagePile.
* This shows a message explaining what happened.
*/
if (params.overflow && params.source === 'pagepile' && params.target) {
this.addSiteNotice(
'info',
$.i18n('massviews-redirect', $.i18n('title'), 10, this.getPileLink(params.target)),
'',
true
);
}

/**
* Check if we're using a valid range, and if so ignore any start/end dates.
* If an invalid range, throw and error and use default dates.
Expand Down
82 changes: 68 additions & 14 deletions javascripts/pageviews.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,27 +138,47 @@ class PageViews extends mix(Pv).with(ChartHelpers) {

this.resetSelect2();

if (!params.pages || params.pages.length === 1 && !params.pages[0]) {
/**
* Normalizes the page names then sets the Select2 defaults,
* which triggers the Select2 listener and renders the chart
* @param {Array} pages - pages to pass to Massviews
* @return {null} nothing
*/
const normalizeAndSetDefaults = pages => {
if (this.normalized) {
pages = this.underscorePageNames(pages);
this.setSelect2Defaults(pages);
} else {
this.normalizePageNames(pages).then(data => {
this.normalized = true;
pages = data;
this.setSelect2Defaults(this.underscorePageNames(pages));
});
}
};

// set up default pages if none were passed in
if (!params.pages || (params.pages.length === 1 && !params.pages[0])) {
// only set default of Cat and Dog for enwiki
if (this.project === 'en.wikipedia') {
params.pages = ['Cat', 'Dog'];
this.setSelect2Defaults(params.pages);
this.setInitialChartType(params.pages.length);
normalizeAndSetDefaults(params.pages);
} else {
params.pages = [];
// leave Select2 empty and put focus on it so they can type in pages
this.focusSelect2();
this.stopSpinny();
this.stopSpinny(); // manually hide spinny since we aren't drawing the chart
this.setInitialChartType();
}
} else if (this.normalized) {
params.pages = this.underscorePageNames(params.pages);
this.setSelect2Defaults(params.pages);
// If there's more than 10 articles attempt to create a PagePile and open it in Massviews
} else if (params.pages.length > 10) {
// If a PagePile is successfully created we are redirected to Massviews and the promise is never resolved,
// otherwise we just take the first 10 and process as we would normally
this.massviewsRedirectWithPagePile(params.pages).then(normalizeAndSetDefaults);
} else {
this.normalizePageNames(params.pages).then(data => {
this.normalized = true;
params.pages = data;
this.setSelect2Defaults(this.underscorePageNames(params.pages));
});
this.setInitialChartType(params.pages.length);
normalizeAndSetDefaults(params.pages);
}
this.setInitialChartType(params.pages.length);
}

/**
Expand Down Expand Up @@ -343,9 +363,13 @@ class PageViews extends mix(Pv).with(ChartHelpers) {
return;
}

// clear out old error messages unless the is the first time rendering the chart
if (this.prevChartType) {
this.clearMessages();
}

this.params = location.search;
this.prevChartType = this.chartType;
this.clearMessages(); // clear out old error messages
this.destroyChart();
this.startSpinny(); // show spinny and capture against fatal errors

Expand Down Expand Up @@ -378,6 +402,36 @@ class PageViews extends mix(Pv).with(ChartHelpers) {
return true;
}
}

/**
* Create a PagePile with given pages using the API and redirect to Massviews.
* This is used when the user passes in more than 10 pages
* @param {Array} pages - pages to convert to a PagePile and open in Massviews
* @returns {Deferred} promise resolved only if creation of PagePile failed
*/
massviewsRedirectWithPagePile(pages) {
const dfd = $.Deferred(),
dbName = Object.keys(siteMap).find(key => siteMap[key] === `${this.project}.org`);

$.ajax({
url: '//tools.wmflabs.org/pagepile/api.php',
data: {
action: 'create_pile_with_data',
wiki: dbName,
data: pages.join('\n')
}
}).success(pileData => {
const params = this.getParams();
delete params.project;
document.location = `/massviews?overflow=1&${$.param(params)}&source=pagepile&target=${pileData.pile.id}`;
}).fail(() => {
// just grab first 10 pages and throw an error
this.writeMessage($.i18n('auto-pagepile-error', 'PagePile', 10));
dfd.resolve(pages.slice(0, 10));
});

return dfd;
}
}

$(document).ready(() => {
Expand Down
2 changes: 1 addition & 1 deletion javascripts/shared/chart_helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ const ChartHelpers = superclass => class extends superclass {
* @param {Number} [numDatasets] - number of datasets
* @returns {null} nothing
*/
setInitialChartType(numDatasets) {
setInitialChartType(numDatasets = 1) {
if (this.rememberChart === 'true') {
this.chartType = this.getFromLocalStorage('pageviews-chart-preference') || this.config.defaults.chartType(numDatasets);
} else {
Expand Down
53 changes: 28 additions & 25 deletions javascripts/shared/pv.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,41 +62,44 @@ class Pv extends PvConfig {
$.i18n({
locale: i18nLang
}).load(messagesToLoad).then(this.initialize.bind(this));

// this.addGlobalErrorHandling();
}

// addGlobalErrorHandling() {
// window.onerror = (msg, url, line, col, error) => {
// /** col & error are new to the HTML 5 spec and may not be supported in every browser. */
// let extra = col ? '\ncolumn: ' + col : '';
// extra += error ? '\nerror: ' + error : '';
/**
* Add a site notice (Bootstrap alert)
* @param {String} level - one of 'success', 'info', 'warning' or 'danger'
* @param {String} message - message to show
* @param {String} [title] - will appear in bold and in front of the message
* @param {Boolean} [dismissable] - whether or not to add a X
* that allows the user to dismiss the notice
* @returns {null} nothing
*/
addSiteNotice(level, message, title, dismissable) {
title = title ? `<strong>${title}</strong> ` : '';

// // You can view the information in an alert to see things working like this:
// const errorMessage = `Error: ${msg}\nurl: ${url}\nline: ${line + extra}`;
// console.log(errorMessage);
// };
// }
let markup = title + message;

/** add relevant CSS class and dismiss link if dismissable */
if (dismissable) {
dismissable = ' alert-dismissable';
markup = `
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>` + markup;
} else {
dismissable = '';
}

addSiteNotice(level, message, title, autodismiss) {
title = title ? `<strong>${title}</strong> ` : '';
autodismiss = autodismiss ? ' autodismiss' : '';
$('.site-notice').append(
`<div class='alert alert-${level}${autodismiss}'>${title}${message}</div>`
`<div class='alert alert-${level}${dismissable}'>${markup}</div>`
);
$('.site-notice-wrapper').show();
}

clearMessages() {
$('.message-container').html('');
}

clearSiteNotices() {
$('.site-notice .autodismiss').remove();
$('.site-notice').html('');
}

if (!$('.site-notice .alert').length) {
$('.site-notice-wrapper').hide();
}
clearMessages() {
$('.message-container').html('');
}

/**
Expand Down
12 changes: 6 additions & 6 deletions javascripts/siteviews/siteviews.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,14 @@ class SiteViews extends mix(Pv).with(ChartHelpers) {

this.resetSelect2();

if (!params.sites || params.sites.length === 1 && !params.sites[0]) {
if (!params.sites || (params.sites.length === 1 && !params.sites[0])) {
params.sites = this.config.defaults.projects;
this.setInitialChartType(params.sites.length);
this.setSelect2Defaults(params.sites);
} else {
this.setInitialChartType(params.sites.length);
this.setSelect2Defaults(params.sites);
} else if (params.sites.length > 10) {
params.sites = params.sites.slice(0, 10); // max 10 sites
}

this.setInitialChartType(params.sites.length);
this.setSelect2Defaults(params.sites);
}

/**
Expand Down
4 changes: 3 additions & 1 deletion messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@
"massviews-empty-set": "$1 contains no pages!",
"massviews-oversized-set": "$1 contains $2 pages. For performance reasons, only the first $3 pages will be processed.",
"massviews-oversized-set-unknown": "$1 contains over $2 pages. For performance reasons, only the first $2 pages will be processed.",
"massviews-redirect": "You have been redirected from $1 because you requested more than $2 pages.<br/>$3 was automatically created and will be processed.",
"url-structure-sort-massviews": "Which column to sort. Either $1 or $2",
"pageviews-description": "Comparison of pageviews across multiple pages",
"topviews-description": "Most viewed pages of a project",
Expand Down Expand Up @@ -250,5 +251,6 @@
"redirects": "Redirects",
"target": "target",
"localization": "Localization:",
"chart-preferences": "Chart preferences:"
"chart-preferences": "Chart preferences:",
"auto-pagepile-error": "Unable to create $1. Showing the first $2 requested pages."
}
4 changes: 3 additions & 1 deletion messages/qqq.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@
"massviews-empty-set": "An error message saying that $1 (a category or page pile) contains no pages",
"massviews-oversized-set": "An error message saying $1 (a category or page pile) contains too many pages to process. $2 is the total number of requested pages, $3 is the number of pages that will actually be processed.",
"massviews-oversized-set-unknown": "An error message saying $1 (a data source) contains too many pages to process. Same as the 'massviews-oversized-set' except here we don't know how many there are total. $2 is the number of pages that will actually be processed.",
"massviews-redirect": "Notice saying the user was redirected from the Pageviews app because they requested too many pages. $1 is the translation for 'title' (Pageviews app name), $2 is the number pages Pageviews can handle, and $3 is a link to the PagePile that was created.",
"url-structure-sort-massviews": "Documentation for the 'sort' parameter for the Massviews application. $1 and $2 are the valid values",
"pageviews-description": "Brief description of the Pageviews tool. Shown directly under the header.",
"topviews-description": "Brief description of the Topviews tool. Shown directly under the header.",
Expand Down Expand Up @@ -258,5 +259,6 @@
"redirects": "Link to show all redirects for an article.\n{{Identical|Redirects}}",
"target": "In the Redirect Views app, a page of all redirects to a given page are shown. This 'Target' text is shown next to the given page, which is the target of all the other redirects. This text should be lowercased, if possible.\n{{Identical|Target}}",
"localization": "Label for localization options in the settings interface.",
"chart-preferences": "Label for chart options in the settings interface."
"chart-preferences": "Label for chart options in the settings interface.",
"auto-pagepile-error": "Error message shown when an automated PagePile failed to generate. $1 is the title 'PagePile' (not translatable) and $2 is the number of pages the tool will use instead of the PagePile."
}
8 changes: 4 additions & 4 deletions public_html/application.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions public_html/langviews/application.js

Large diffs are not rendered by default.

56 changes: 30 additions & 26 deletions public_html/langviews/langviews.js
Original file line number Diff line number Diff line change
Expand Up @@ -1041,7 +1041,9 @@ var ChartHelpers = function ChartHelpers(superclass) {

_createClass(_class, [{
key: 'setInitialChartType',
value: function setInitialChartType(numDatasets) {
value: function setInitialChartType() {
var numDatasets = arguments.length <= 0 || arguments[0] === undefined ? 1 : arguments[0];

if (this.rememberChart === 'true') {
this.chartType = this.getFromLocalStorage('pageviews-chart-preference') || this.config.defaults.chartType(numDatasets);
} else {
Expand Down Expand Up @@ -2393,45 +2395,47 @@ var Pv = function (_PvConfig) {
$.i18n({
locale: i18nLang
}).load(messagesToLoad).then(_this.initialize.bind(_this));

// this.addGlobalErrorHandling();
return _this;
}

// addGlobalErrorHandling() {
// window.onerror = (msg, url, line, col, error) => {
// /** col & error are new to the HTML 5 spec and may not be supported in every browser. */
// let extra = col ? '\ncolumn: ' + col : '';
// extra += error ? '\nerror: ' + error : '';
/**
* Add a site notice (Bootstrap alert)
* @param {String} level - one of 'success', 'info', 'warning' or 'danger'
* @param {String} message - message to show
* @param {String} [title] - will appear in bold and in front of the message
* @param {Boolean} [dismissable] - whether or not to add a X
* that allows the user to dismiss the notice
* @returns {null} nothing
*/

// // You can view the information in an alert to see things working like this:
// const errorMessage = `Error: ${msg}\nurl: ${url}\nline: ${line + extra}`;
// console.log(errorMessage);
// };
// }

_createClass(Pv, [{
key: 'addSiteNotice',
value: function addSiteNotice(level, message, title, autodismiss) {
value: function addSiteNotice(level, message, title, dismissable) {
title = title ? '<strong>' + title + '</strong> ' : '';
autodismiss = autodismiss ? ' autodismiss' : '';
$('.site-notice').append('<div class=\'alert alert-' + level + autodismiss + '\'>' + title + message + '</div>');
$('.site-notice-wrapper').show();

var markup = title + message;

/** add relevant CSS class and dismiss link if dismissable */
if (dismissable) {
dismissable = ' alert-dismissable';
markup = '\n <button type="button" class="close" data-dismiss="alert" aria-label="Close">\n <span aria-hidden="true">&times;</span>\n </button>' + markup;
} else {
dismissable = '';
}

$('.site-notice').append('<div class=\'alert alert-' + level + dismissable + '\'>' + markup + '</div>');
}
}, {
key: 'clearSiteNotices',
value: function clearSiteNotices() {
$('.site-notice').html('');
}
}, {
key: 'clearMessages',
value: function clearMessages() {
$('.message-container').html('');
}
}, {
key: 'clearSiteNotices',
value: function clearSiteNotices() {
$('.site-notice .autodismiss').remove();

if (!$('.site-notice .alert').length) {
$('.site-notice-wrapper').hide();
}
}

/**
* Get date format to use based on settings
Expand Down
6 changes: 3 additions & 3 deletions public_html/massviews/application.js

Large diffs are not rendered by default.

Loading

0 comments on commit e1fda62

Please sign in to comment.