diff --git a/dashboard-ui/scripts/librarybrowser.js b/dashboard-ui/scripts/librarybrowser.js
index 5f732786df..fe782e02ee 100644
--- a/dashboard-ui/scripts/librarybrowser.js
+++ b/dashboard-ui/scripts/librarybrowser.js
@@ -1363,7 +1363,7 @@
html += '
';
- html += '
';
+ html += '';
var startAtDisplay = totalRecordCount ? query.StartIndex + 1 : 0;
html += startAtDisplay + '-' + recordsEnd + ' of ' + totalRecordCount;
diff --git a/dashboard-ui/scripts/libraryreport.js b/dashboard-ui/scripts/libraryreport.js
index df4427283e..f5175553a1 100644
--- a/dashboard-ui/scripts/libraryreport.js
+++ b/dashboard-ui/scripts/libraryreport.js
@@ -6,187 +6,417 @@
SortBy: "SeriesSortName,SortName",
SortOrder: "Ascending",
Recursive: true,
- Fields: "MediaStreams,DateCreated,Settings",
+ Fields: "MediaStreams,DateCreated,Settings,Studios",
StartIndex: 0,
- IncludeItemTypes: "Movie"
+ IncludeItemTypes: "Movie",
+ IsMissing: false,
+ IsVirtualUnaired: false
};
- function getCodecName(stream) {
+ function getHeaderCells(reportType) {
- var val = stream.Codec || '';
- val = val.toUpperCase();
+ switch (reportType) {
- if (val == 'DCA') {
- return stream.Profile;
+ case 'Season':
+ {
+ return [
+ {},
+ { name: 'Series' },
+ { name: 'Season' },
+ { name: 'Date Added' }
+ ];
+ }
+ case 'Series':
+ {
+ return [
+ {},
+ { name: 'Name' },
+ { name: 'Network' },
+ { name: 'Date Added' },
+ { name: 'Year' },
+ { name: 'Rating' },
+ { name: 'Runtime' },
+ { name: 'Trailers' },
+ { name: 'Specials' }
+ ];
+ }
+ case 'Game':
+ {
+ return [
+ {},
+ { name: 'Name' },
+ { name: 'Game System' },
+ { name: 'Date Added' },
+ { name: 'Release Date' },
+ { name: 'Rating' },
+ { name: 'Players' },
+ { name: 'Trailers' }
+ ];
+ }
+ case 'Audio':
+ {
+ return [
+ {},
+ { name: 'Album Artist' },
+ { name: 'Album' },
+ { name: 'Track' },
+ { name: 'Name' },
+ { name: 'Date Added' },
+ { name: 'Release Date' },
+ { name: 'Runtime' },
+ { name: 'Audio' },
+ { name: 'Embedded Image' }
+ ];
+ }
+ case 'Episode':
+ {
+ return [
+ {},
+ { name: 'Series' },
+ { name: 'Season' },
+ { name: 'Name' },
+ { name: 'Date Added' },
+ { name: 'Release Date' },
+ { name: 'Runtime' },
+ { name: 'Video' },
+ { name: 'Audio' },
+ { name: 'Subtitles' }
+ ];
+ }
+ case 'BoxSet':
+ {
+ return [
+ {},
+ { name: 'Name' },
+ { name: 'Date Added' },
+ { name: 'Release Date' },
+ { name: 'Rating' },
+ { name: 'Trailers' }
+ ];
+ }
+ case 'Book':
+ {
+ return [
+ {},
+ { name: 'Series' },
+ { name: 'Name' },
+ { name: 'Date Added' },
+ { name: 'Release Date' },
+ { name: 'Rating' }
+ ];
+ }
+ case 'MusicArtist':
+ {
+ return [
+ {},
+ { name: 'Name' },
+ { name: 'Date Added' }
+ ];
+ }
+ case 'MusicAlbum':
+ {
+ return [
+ {},
+ { name: 'Album Artist' },
+ { name: 'Name' },
+ { name: 'Date Added' },
+ { name: 'Release Date' },
+ { name: 'Rating' },
+ { name: 'Runtime' }
+ ];
+ }
+ default:
+ {
+ return [
+ {},
+ { name: 'Name' },
+ { name: 'Date Added' },
+ { name: 'Release Date' },
+ { name: 'Rating' },
+ { name: 'Runtime' },
+ { name: 'Video' },
+ { name: 'Audio' },
+ { name: 'Subtitles' },
+ { name: 'Trailers' },
+ { name: 'Specials' }
+ ];
+ }
}
-
- return val;
}
- function getTableRowsHtml(items, includeParentInfo, includeSubtitles, includePlayers) {
+ function getItemCellsHtml(item, headercells) {
+
+ return headercells.map(function (cell) {
+
+ var html = '';
+ html += '';
+
+ switch (cell.type || cell.name) {
+
+ case 'Album Artist':
+ {
+ html += item.AlbumArtist || ' ';
+ break;
+ }
+ case 'Album':
+ {
+ html += item.Album || ' ';
+ break;
+ }
+ case 'Series':
+ {
+ html += item.SeriesName || ' ';
+ break;
+ }
+ case 'Game System':
+ {
+ html += item.GameSystem || ' ';
+ break;
+ }
+ case 'Network':
+ {
+ html += item.Studios.length ? item.Studios[0].Name : ' ';
+ break;
+ }
+ case 'Track':
+ {
+ html += item.IndexNumber == null ? '' : item.IndexNumber;
+ break;
+ }
+ case 'Players':
+ {
+ html += item.Players || ' ';
+ break;
+ }
+ case 'Audio':
+ {
+ var stream = (item.MediaStreams || []).filter(function (s) {
+
+ return s.Type == 'Audio';
+
+ })[0];
+
+ if (stream) {
+
+ var name = (stream.Codec || '').toUpperCase();
+ html += name == 'DCA' ? (stream.Profile || '').toUpperCase() : name;
+ }
+ break;
+ }
+ case 'Video':
+ {
+ var stream = (item.MediaStreams || []).filter(function (s) {
+
+ return s.Type == 'Video';
+
+ })[0];
+
+ if (stream) {
+ html += (stream.Codec || '').toUpperCase();
+ }
+ break;
+ }
+ case 'Embedded Image':
+ {
+ if ((item.MediaStreams || []).filter(function (s) {
+
+ return s.Type == 'Video';
+
+ }).length) {
+ html += '';
+ }
+ break;
+ }
+ case 'Subtitles':
+ {
+ var hasSubtitles = (item.MediaStreams || []).filter(function (s) {
+
+ return s.Type == 'Subtitle';
+
+ }).length;
+
+ if (hasSubtitles) {
+ html += '';
+ }
+ break;
+ }
+ case 'Runtime':
+ {
+ if (item.RunTimeTicks) {
+ html += Dashboard.getDisplayTime(item.RunTimeTicks);
+ } else {
+ html += ' ';
+ }
+ break;
+ }
+ case 'Trailers':
+ {
+ if (item.LocalTrailerCount) {
+
+ html += '';
+ }
+ break;
+ }
+ case 'Specials':
+ {
+ if (item.SpecialFeatureCount) {
+
+ html += '';
+ }
+ break;
+ }
+
+ case 'Season':
+ {
+ if (item.Type == "Episode") {
+ html += item.ParentIndexNumber == null ? '' : ('Season ' + item.ParentIndexNumber);
+ } else {
+ html += '' + LibraryBrowser.getPosterViewDisplayName(item, false, false) + '';
+ }
+ break;
+ }
+
+ case 'Name':
+ {
+ html += '' + LibraryBrowser.getPosterViewDisplayName(item, false, false) + '';
+ break;
+ }
+ case 'Rating':
+ {
+ html += item.OfficialRating || ' ';
+ break;
+ }
+
+ case 'Year':
+ case 'Release Date':
+ {
+ if (item.PremiereDate && item.Type != "Series") {
+ try {
+ var date = parseISO8601Date(item.PremiereDate, { toLocal: true });
+
+ html += date.toLocaleDateString();
+ }
+ catch (e) {
+ html += ' ';
+ }
+ }
+ else if (item.ProductionYear) {
+ html += item.ProductionYear;
+
+ if (item.Status == "Continuing") {
+ html += "-Present";
+ }
+ else if (item.EndDate) {
+
+ try {
+
+ var endYear = parseISO8601Date(item.EndDate, { toLocal: true }).getFullYear();
+
+ if (endYear != item.ProductionYear) {
+ html += "-" + parseISO8601Date(item.EndDate, { toLocal: true }).getFullYear();
+ }
+
+ }
+ catch (e) {
+ console.log("Error parsing date: " + item.EndDate);
+ }
+ }
+
+ } else {
+ html += ' ';
+ }
+ break;
+ }
+ case 'Date Added':
+ {
+ if (item.DateCreated) {
+ try {
+ html += parseISO8601Date(item.DateCreated, { toLocal: true }).toLocaleDateString();
+ }
+ catch (e) {
+ html += ' ';
+ }
+ }
+ break;
+ }
+ default:
+ {
+ if (item.LockData) {
+ html += ' ';
+ }
+ if (item.IsUnidentified) {
+ html += '';
+ }
+
+ if (!item.LocalTrailerCount && item.Type == "Movie") {
+ html += ' ';
+ }
+
+ if (!item.ImageTags || !item.ImageTags.Primary) {
+ html += ' ';
+ }
+
+ if (!item.BackdropImageTags || !item.BackdropImageTags.length) {
+ if (item.Type !== "Episode" && item.Type !== "Season" && item.MediaType !== "Audio" && item.Type !== "Channel") {
+ html += ' ';
+ }
+ }
+
+ if (!item.ImageTags || !item.ImageTags.Logo) {
+ if (item.Type == "Movie" || item.Type == "Trailer" || item.Type == "Series" || item.Type == "MusicArtist" || item.Type == "BoxSet") {
+ html += ' ';
+ }
+ }
+
+ break;
+ }
+ }
+
+ html += ' | ';
+ return html;
+
+ }).join('');
+ }
+
+ function getReportHtml(items, reportType) {
var html = '';
+ html += '
';
+
+ html += '';
+ html += '';
+
+ var cells = getHeaderCells(reportType);
+
+ html += cells.map(function (c) {
+
+ return '' + (c.name || ' ') + ' | ';
+
+ }).join('');
+
+ html += '
';
+ html += '';
+
+ html += '';
+
for (var i = 0, length = items.length; i < length; i++) {
var item = items[i];
html += '';
-
- html += '';
-
- if (item.LockData) {
- html += ' ';
- }
- if (item.IsUnidentified) {
- html += '';
- }
- html += ' | ';
-
- if (includeParentInfo) {
- html += '';
- if (item.SeriesName) {
- html += '' + item.SeriesName + '';
- }
- else if (item.Album) {
- html += item.Album;
- }
- else if (item.AlbumArtist) {
- html += item.AlbumArtist;
- }
- else if (item.GameSystem) {
- html += item.GameSystem;
- }
- else {
- html += ' ';
- }
- html += ' | ';
- }
-
- html += '';
- html += '' + LibraryBrowser.getPosterViewDisplayName(item, false, true) + '';
- html += ' | ';
-
- html += '';
- if (item.DateCreated) {
- try {
- html += parseISO8601Date(item.DateCreated, { toLocal: true }).toLocaleDateString();
- }
- catch (e) {
- html += ' ';
- }
- }
- html += ' | ';
-
- html += '';
- if (item.PremiereDate && item.Type != "Series") {
- try {
- var date = parseISO8601Date(item.PremiereDate, { toLocal: true });
-
- html += date.toLocaleDateString();
- }
- catch (e) {
- html += ' ';
- }
- }
- else if (item.ProductionYear) {
- html += item.ProductionYear;
-
- if (item.Status == "Continuing") {
- html += "-Present";
- }
- else if (item.EndDate) {
-
- try {
-
- var endYear = parseISO8601Date(item.EndDate, { toLocal: true }).getFullYear();
-
- if (endYear != item.ProductionYear) {
- html += "-" + parseISO8601Date(item.EndDate, { toLocal: true }).getFullYear();
- }
-
- }
- catch (e) {
- console.log("Error parsing date: " + item.EndDate);
- }
- }
-
- } else {
- html += ' ';
- }
- html += ' | ';
-
- html += '';
- html += item.OfficialRating || ' ';
- html += ' | ';
-
- html += '';
-
- if (item.RunTimeTicks) {
- html += Dashboard.getDisplayTime(item.RunTimeTicks);
- } else {
- html += ' ';
- }
- html += ' | ';
-
- if (includePlayers) {
- html += '';
- html += item.Players || ' ';
- html += ' | ';
- }
-
- html += '';
- html += (item.MediaStreams || []).filter(function (s) {
-
- return s.Type != 'Subtitle';
-
- }).map(getCodecName).filter(function (s) {
- return s;
- }).join(' ');
-
- html += ' | ';
-
- if (includeSubtitles) {
- html += '';
- html += (item.MediaStreams || []).filter(function (s) {
-
- return s.Type == 'Subtitle';
-
- }).map(function (s) {
-
- return (s.Language || 'und') + ' - ' + s.Codec;
-
- }).join(' ');
-
- html += ' | ';
- }
-
- html += '';
- if (item.SpecialFeatureCount == 1) {
-
- html += '1 Special ';
- }
- else if (item.SpecialFeatureCount) {
-
- html += item.SpecialFeatureCount + ' Specials ';
- }
- if (item.LocalTrailerCount == 1) {
-
- html += '1 Trailer ';
- }
- else if (item.LocalTrailerCount) {
-
- html += item.LocalTrailerCount + ' Trailers ';
- }
- html += ' | ';
-
+ html += getItemCellsHtml(item, cells);
html += '
';
}
+ html += '';
+
+ html += '
';
+
return html;
}
- function renderItems(page, result) {
+ function renderItems(page, result, reportType) {
// Scroll back up so they can see the results from the beginning
$(document).scrollTop(0);
@@ -197,46 +427,7 @@
$('.listBottomPaging', page).html(LibraryBrowser.getPagingHtml(query, result.TotalRecordCount)).trigger('create');
- var includeParentInfo = query.IncludeItemTypes == "Audio" || query.IncludeItemTypes == "MusicAlbum" || query.IncludeItemTypes == "Episode" || query.IncludeItemTypes == "Book" || query.IncludeItemTypes == "Game";
- var includeSubtitles = query.IncludeItemTypes == "Movie" || query.IncludeItemTypes == "Trailer" || query.IncludeItemTypes == "Episode" || query.IncludeItemTypes == "AdultVideo" || query.IncludeItemTypes == "MusicVideo" || query.IncludeItemTypes == "Video";
- var includePlayers = query.IncludeItemTypes == "Game";
-
- if (includeParentInfo) {
-
- var parentLabel = "Series";
-
- if (query.IncludeItemTypes == "Audio") {
- parentLabel = "Album";
- }
- else if (query.IncludeItemTypes == "MusicAlbum") {
- parentLabel = "Artist";
- }
- else if (query.IncludeItemTypes == "Game") {
- parentLabel = "Game System";
- }
-
- $('.thParent', page).html(parentLabel).show();
-
- } else {
- $('.thParent', page).hide();
- }
-
- if (includeSubtitles) {
- $('.thSubtitles', page).show();
-
- } else {
- $('.thSubtitles', page).hide();
- }
-
- if (includePlayers) {
- $('.thPlayers', page).show();
-
- } else {
- $('.thPlayers', page).hide();
- }
-
- var rowsHtml = getTableRowsHtml(result.Items, includeParentInfo, includeSubtitles, includePlayers);
- $('.resultBody', page).html(rowsHtml).parents('.tblLibraryReport').table("refresh").trigger('create');
+ $('.reportContainer', page).html(getReportHtml(result.Items, reportType)).trigger('create');
$('.btnNextPage', page).on('click', function () {
query.StartIndex += query.Limit;
@@ -258,10 +449,11 @@
function reloadItems(page) {
var url = ApiClient.getUrl("Items", query);
+ var reportType = $('#selectView', page).val();
$.getJSON(url).done(function (result) {
- renderItems(page, result);
+ renderItems(page, result, reportType);
});
}
@@ -288,12 +480,18 @@
$('#chkSpecialFeature', page).checked(query.HasSpecialFeature == true).checkboxradio('refresh');
$('#chkThemeSong', page).checked(query.HasThemeSong == true).checkboxradio('refresh');
$('#chkThemeVideo', page).checked(query.HasThemeVideo == true).checkboxradio('refresh');
+ $('#chkIsPlaceHolder', page).checked(query.IsPlaceHolder == true).checkboxradio('refresh');
+ $('#chkMissingRating', page).checked(query.HasOfficialRating == false).checkboxradio('refresh');
$('#chkMissingOverview', page).checked(query.HasOverview == false).checkboxradio('refresh');
$('#chkYearMismatch', page).checked(query.IsYearMismatched == true).checkboxradio('refresh');
$('#chkIsUnidentified', page).checked(query.IsUnidentified == true).checkboxradio('refresh');
$('#chkIsLocked', page).checked(query.IsLocked == true).checkboxradio('refresh');
+
+ $('#chkSpecialEpisode', page).checked(query.ParentIndexNumber == 0).checkboxradio('refresh');
+ $('#chkMissingEpisode', page).checked(query.IsMissing == true).checkboxradio('refresh');
+ $('#chkFutureEpisode', page).checked(query.IsUnaired == true).checkboxradio('refresh');
}
$(document).on('pageinit', "#libraryReportPage", function () {
@@ -406,6 +604,14 @@
reloadItems(page);
});
+ $('#chkIsPlaceHolder', page).on('change', function () {
+
+ query.StartIndex = 0;
+ query.IsPlaceHolder = this.checked ? true : null;
+
+ reloadItems(page);
+ });
+
$('#chkThemeSong', page).on('change', function () {
query.StartIndex = 0;
@@ -430,6 +636,14 @@
reloadItems(page);
});
+ $('#chkMissingRating', page).on('change', function () {
+
+ query.StartIndex = 0;
+ query.HasOfficialRating = this.checked ? false : null;
+
+ reloadItems(page);
+ });
+
$('#chkYearMismatch', page).on('change', function () {
query.StartIndex = 0;
@@ -454,6 +668,37 @@
reloadItems(page);
});
+ $('#chkMissingEpisode', page).on('change', function () {
+
+ query.StartIndex = 0;
+ query.IsMissing = this.checked ? true : false;
+
+ reloadItems(page);
+ });
+
+ $('#chkFutureEpisode', page).on('change', function () {
+
+ query.StartIndex = 0;
+
+ if (this.checked) {
+ query.IsUnaired = true;
+ query.IsVirtualUnaired = null;
+ } else {
+ query.IsUnaired = null;
+ query.IsVirtualUnaired = false;
+ }
+
+
+ reloadItems(page);
+ });
+
+ $('#chkSpecialEpisode', page).on('change', function () {
+
+ query.ParentIndexNumber = this.checked ? 0 : null;
+
+ reloadItems(page);
+ });
+
}).on('pagebeforeshow', "#libraryReportPage", function () {
var page = this;
diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js
index 07296f29dc..5996033318 100644
--- a/dashboard-ui/scripts/site.js
+++ b/dashboard-ui/scripts/site.js
@@ -713,7 +713,7 @@ var Dashboard = {
href: "dashboard.html",
selected: page.hasClass("dashboardHomePage")
}, {
- name: "Media Library",
+ name: "Library",
divider: true,
href: "library.html",
selected: page.hasClass("mediaLibraryPage")
@@ -1347,9 +1347,6 @@ $(function () {
footerHtml += '
';
- footerHtml += '
';
- footerHtml += '
';
-
footerHtml += '
';
footerHtml += '