Frontend polish and fixes; make empty placeholder implementation more abstract and add placeholder to 'My Podcast' view

This commit is contained in:
Duncan Sommerville 2015-11-12 19:02:09 -05:00
parent 0e74229975
commit 55df7775c2
10 changed files with 81 additions and 36 deletions

View file

@ -72,30 +72,35 @@ var AIRTIME = (function(AIRTIME) {
/**
* Draw a placeholder for the given table to show if it has no data.
*
* @param {jQuery} table jQuery object containing the table DOM node
* @param {Object} table jQuery object containing the table DOM node
*/
mod.drawEmptyPlaceholder = function (table) {
var opts;
if (table instanceof AIRTIME.widgets.Table) {
opts = table.getEmptyPlaceholder();
table = table.getDatatable();
if (!table) {
return;
}
}
var emptyRow = table.find('tr:has(td.dataTables_empty)'),
wrapper = table.closest(".dataTables_wrapper");
var libEmpty = wrapper.find('.empty_placeholder');
wrapper = table.closest(".dataTables_wrapper"),
libEmpty = wrapper.find('.empty_placeholder');
if (emptyRow.length > 0) {
emptyRow.hide();
var mediaType = parseInt($('.media_type_selector.selected').data('selection-id')),
img = wrapper.find('.empty_placeholder_image');
if (isNaN(mediaType)) { return; }
if (isNaN(mediaType)) {
return;
}
// Remove all classes for when we change between empty media types
img.removeClass(function() { return $(this).attr("class"); });
if (table[0] == AIRTIME.library.podcastEpisodeDataTable[0]) {
img.addClass("empty_placeholder_image icon-white icon-th-list");
wrapper.find('.empty_placeholder_text').html(
$.i18n._("This podcast doesn't have any episodes!")
+ "<br/>" + $.i18n._("Make sure the RSS feed contains audio items (with enclosure tags).")
+ "<br/><a target='_blank' href='http://www.apple.com/ca/itunes/podcasts/specs.html'>" + $.i18n._("Learn about podcasts") + "</a>"
);
if (opts) {
img.addClass("empty_placeholder_image " + opts.iconClass);
wrapper.find('.empty_placeholder_text').html(opts.html);
} else {
var opts = AIRTIME.library.placeholder(mediaType);
opts = AIRTIME.library.placeholder(mediaType);
img.addClass("empty_placeholder_image icon-white " + opts.icon);
wrapper.find('.empty_placeholder_text').html(
$.i18n._("You haven't added any " + opts.media + ".")

View file

@ -1399,7 +1399,7 @@ var AIRTIME = (function(AIRTIME) {
// Add a button to view the station podcast
podcastToolbarButtons["StationPodcast"] = {
title : $.i18n._("Station Podcast"),
title : $.i18n._("My Podcast"),
iconClass : "icon-music",
extraBtnClass : "btn-small",
elementId : "",
@ -1419,9 +1419,6 @@ var AIRTIME = (function(AIRTIME) {
sAjaxSource : ajaxSourceURL,
oColReorder: {
iFixedColumns: 1 // Checkbox
},
fnDrawCallback: function () {
AIRTIME.library.drawEmptyPlaceholder($(this));
}
});
@ -1588,13 +1585,18 @@ var AIRTIME = (function(AIRTIME) {
},
oColReorder: {
iFixedColumns: 3 // Checkbox + imported
},
fnDrawCallback: function () {
AIRTIME.library.drawEmptyPlaceholder($(this));
}
},
buttons,
{ hideIngestCheckboxes: false }
{
hideIngestCheckboxes: false,
emptyPlaceholder: {
iconClass: "icon-white icon-th-list",
html: $.i18n._("This podcast doesn't have any episodes!")
+ "<br/>" + $.i18n._("Make sure the RSS feed contains audio items (with enclosure tags).")
+ "<br/><a target='_blank' href='http://www.apple.com/ca/itunes/podcasts/specs.html'>" + $.i18n._("Learn about podcasts") + "</a>"
}
}
);
mod.podcastEpisodeDataTable = $datatables[mod.DataTableTypeEnum.PODCAST_EPISODES] = mod.podcastEpisodeTableWidget.getDatatable();

View file

@ -40,7 +40,7 @@ var AIRTIME = (function (AIRTIME) {
$http.put(endpoint + $scope.podcast.id, {csrf_token: $scope.csrf, podcast: $scope.podcast})
.success(function () {
AIRTIME.library.podcastDataTable.fnDraw();
tab.setName($scope.podcast.title);
tab.close();
});
};
@ -205,9 +205,17 @@ var AIRTIME = (function (AIRTIME) {
buttons,
{
hideIngestCheckboxes: true,
podcastId: $scope.podcast.id
podcastId: $scope.podcast.id,
emptyPlaceholder: {
iconClass: "icon-white icon-th-list",
html: $.i18n._("You haven't published any episodes!")
+ "<br/>" + $.i18n._("You can publish your uploaded content from the 'Tracks' view.")
+ "<br/><a target='_parent' href='showbuilder#tracks'>" + $.i18n._("Try it now") + "</a>"
}
}
);
mod.stationPodcastTable = this.episodeTable.getDatatable();
};
/**
@ -215,8 +223,8 @@ var AIRTIME = (function (AIRTIME) {
*/
StationPodcastController.prototype.initialize = function() {
PodcastController.prototype.initialize.call(this);
// We want to override the default tab name behaviour and use "Station Podcast" for clarity
this.$scope.tab.setName(jQuery.i18n._("Station Podcast"));
// We want to override the default tab name behaviour and use "My Podcast" for clarity
this.$scope.tab.setName(jQuery.i18n._("My Podcast"));
this._initTable();
};
@ -317,7 +325,7 @@ var AIRTIME = (function (AIRTIME) {
this.config = config; // Internal configuration object
this._setupImportListener();
// Call the superconstructor
return AIRTIME.widgets.Table.call(this, wrapperDOMNode, bItemSelection, toolbarButtons, dataTablesOptions);
return AIRTIME.widgets.Table.call(this, wrapperDOMNode, bItemSelection, toolbarButtons, dataTablesOptions, config.emptyPlaceholder);
}; // Subclass AIRTIME.widgets.Table
PodcastEpisodeTable.prototype = Object.create(AIRTIME.widgets.Table.prototype);
PodcastEpisodeTable.prototype.constructor = PodcastEpisodeTable;
@ -459,7 +467,6 @@ var AIRTIME = (function (AIRTIME) {
*/
mod.addPodcast = function () {
$.post(endpoint, $("#podcast_url_dialog").find("form").serialize(), function(json) {
_initAppFromResponse(json);
// Open the episode view for the newly created podcast in the left-hand pane
AIRTIME.library.podcastEpisodeTableWidget.reload(JSON.parse(json.podcast).id);
AIRTIME.library.podcastTableWidget.clearSelection();
@ -613,6 +620,9 @@ var AIRTIME = (function (AIRTIME) {
connectToSortable: $("#show_builder_table, .active-tab .spl_sortable")
});
}
},
fnDrawCallback: function () {
AIRTIME.library.drawEmptyPlaceholder(this);
}
}
);

View file

@ -10,7 +10,21 @@ var AIRTIME = (function(AIRTIME) {
}
//Table widget constructor
var Table = function(wrapperDOMNode, bItemSelection, toolbarButtons, dataTablesOptions) {
/**
*
*
* @param wrapperDOMNode
* @param {boolean} bItemSelection
* @param {Object} toolbarButtons
* @param {Object} dataTablesOptions
* @param {Object} [emptyPlaceholder]
* @param {string} emptyPlaceholder.html
* @param {string} emptyPlaceholder.iconClass
*
* @returns {Table}
* @constructor
*/
var Table = function(wrapperDOMNode, bItemSelection, toolbarButtons, dataTablesOptions, emptyPlaceholder) {
var self = this;
@ -34,6 +48,7 @@ var AIRTIME = (function(AIRTIME) {
//Save some of the constructor parameters
self._$wrapperDOMNode = $(wrapperDOMNode);
self._toolbarButtons = toolbarButtons;
self._emptyPlaceholder = emptyPlaceholder;
// Exclude the leftmost column if we're implementing item selection
self._colVisExcludeColumns = bItemSelection ? [0] : [];
@ -93,6 +108,9 @@ var AIRTIME = (function(AIRTIME) {
if (options.fnCreatedRow) {
options.fnCreatedRow = options.fnCreatedRow.bind(this);
}
if (options.fnDrawCallback) {
options.fnDrawCallback = options.fnDrawCallback.bind(this);
}
self._datatable = self._$wrapperDOMNode.dataTable(options);
// self._datatable.fnDraw(); //Load the AJAX data now that our event handlers have been bound.
@ -372,6 +390,10 @@ var AIRTIME = (function(AIRTIME) {
return this._selectedRows;
};
Table.prototype.getEmptyPlaceholder = function () {
return this._emptyPlaceholder;
};
Table.prototype._handleAjaxError = function(r) {
// If the request was denied due to permissioning
if (r.status === 403) {