diff --git a/dashboard-ui/autoorganizelog.html b/dashboard-ui/autoorganizelog.html index a851d909bd..5f00c5f44a 100644 --- a/dashboard-ui/autoorganizelog.html +++ b/dashboard-ui/autoorganizelog.html @@ -1,9 +1,8 @@ -
+
-
+ +
+ + + + + + + + + + + +
${HeaderDate}${HeaderSource}${HeaderDestination}
- - - - - - - - - - - -
${HeaderDate}${HeaderSource}${HeaderDestination}

diff --git a/dashboard-ui/autoorganizesmart.html b/dashboard-ui/autoorganizesmart.html index 26b68b72af..335f501369 100644 --- a/dashboard-ui/autoorganizesmart.html +++ b/dashboard-ui/autoorganizesmart.html @@ -1,4 +1,4 @@ -
+
diff --git a/dashboard-ui/autoorganizetv.html b/dashboard-ui/autoorganizetv.html index d05b65b760..06d3d5f919 100644 --- a/dashboard-ui/autoorganizetv.html +++ b/dashboard-ui/autoorganizetv.html @@ -1,5 +1,4 @@ -
- +
diff --git a/dashboard-ui/css/autoorganizetable.css b/dashboard-ui/css/autoorganizetable.css new file mode 100644 index 0000000000..cfc1da14ab --- /dev/null +++ b/dashboard-ui/css/autoorganizetable.css @@ -0,0 +1,68 @@ +.autoorganizetable > .table { + width: 100%; +} + + .autoorganizetable > .table > tbody > tr > td { + padding: 0.4em; + } + +.autoorganizetable .fileCell { + word-wrap: break-word; + word-break: break-all; +} + +.autoorganizetable > .table > thead > th { + text-align: left; +} + +.autoorganizetable tbody tr:nth-child(odd) td, +.autoorganizetable tbody tr:nth-child(odd) th { + background-color: #eeeeee; /* non-RGBA fallback */ + background-color: rgba(0,0,0,.04); +} + + +@media screen and (max-width: 800px) { + .autoorganizetable > .table { + margin-bottom: 0; + background-color: transparent; + } + + .autoorganizetable .spinnerCell { + display: none !important; + } + + .autoorganizetable > .table > thead, + .autoorganizetable > .table > tfoot { + display: none; + } + + .autoorganizetable > .table > tbody { + display: block; + } + + .autoorganizetable > .table > tbody > tr { + display: block; + border: 1px solid #e0e0e0; + border-radius: 2px; + margin-bottom: 1.6rem; + } + + .autoorganizetable > .table > tbody > tr > td { + background-color: #eeeeee; /* non-RGBA fallback */ + background-color: rgba(0,0,0,.04); + display: block; + vertical-align: middle; + text-align: left; + text-overflow: ellipsis; + padding: 0.4em; + } + + .autoorganizetable > .table > tbody > tr > td[data-title]:before { + content: attr(data-title); + float: left; + font-size: inherit; + font-weight: bold; + min-width: 20%; + } +} diff --git a/dashboard-ui/scripts/autoorganizelog.js b/dashboard-ui/scripts/autoorganizelog.js index ecaad558dc..63a6654a76 100644 --- a/dashboard-ui/scripts/autoorganizelog.js +++ b/dashboard-ui/scripts/autoorganizelog.js @@ -1,4 +1,4 @@ -define(['jQuery', 'serverNotifications', 'events', 'scripts/taskbutton', 'datetime', 'paper-icon-button-light'], function ($, serverNotifications, events, taskButton, datetime) { +define(['serverNotifications', 'events', 'scripts/taskbutton', 'datetime', 'paper-icon-button-light'], function (serverNotifications, events, taskButton, datetime) { var query = { @@ -7,6 +7,20 @@ }; var currentResult; + var page; + + function parentWithClass(elem, className) { + + while (!elem.classList || !elem.classList.contains(className)) { + elem = elem.parentNode; + + if (!elem) { + return null; + } + } + + return elem; + } function showStatusMessage(id) { @@ -167,28 +181,10 @@ return html; }).join(''); - var elem = $('.resultBody', page).html(rows).parents('.tblOrganizationResults').table('refresh').trigger('create'); + var resultBody = page.querySelector('.resultBody'); + resultBody.innerHTML = rows; - $('.btnShowStatusMessage', elem).on('click', function () { - - var id = this.getAttribute('data-resultid'); - - showStatusMessage(id); - }); - - $('.btnProcessResult', elem).on('click', function () { - - var id = this.getAttribute('data-resultid'); - - organizeFile(page, id); - }); - - $('.btnDeleteResult', elem).on('click', function () { - - var id = this.getAttribute('data-resultid'); - - deleteOriginalFile(page, id); - }); + resultBody.addEventListener('click', handleItemClick); var pagingHtml = LibraryBrowser.getQueryPagingHtml({ startIndex: query.StartIndex, @@ -198,32 +194,43 @@ updatePageSizeSetting: false }); - $(page)[0].querySelector('.listTopPaging').innerHTML = pagingHtml; + var topPaging = page.querySelector('.listTopPaging'); + topPaging.innerHTML = pagingHtml; - if (result.TotalRecordCount > query.Limit && result.TotalRecordCount > 50) { + var bottomPaging = page.querySelector('.listBottomPaging'); + bottomPaging.innerHTML = pagingHtml; - $('.listBottomPaging', page).html(pagingHtml).trigger('create'); - } else { - - $('.listBottomPaging', page).empty(); - } - - $('.btnNextPage', page).on('click', function () { + var btnNextTop = topPaging.querySelector(".btnNextPage"); + var btnNextBottom = bottomPaging.querySelector(".btnNextPage"); + var btnPrevTop = topPaging.querySelector(".btnPreviousPage"); + var btnPrevBottom = bottomPaging.querySelector(".btnPreviousPage"); + btnNextTop.addEventListener('click', function () { query.StartIndex += query.Limit; reloadItems(page, true); }); - $('.btnPreviousPage', page).on('click', function () { + btnNextBottom.addEventListener('click', function () { + query.StartIndex += query.Limit; + reloadItems(page, true); + }); + btnPrevTop.addEventListener('click', function () { query.StartIndex -= query.Limit; reloadItems(page, true); }); + btnPrevBottom.addEventListener('click', function () { + query.StartIndex -= query.Limit; + reloadItems(page, true); + }); + + var btnClearLog = page.querySelector('.btnClearLog'); + if (result.TotalRecordCount) { - page.querySelector('.btnClearLog').classList.remove('hide'); + btnClearLog.classList.remove('hide'); } else { - page.querySelector('.btnClearLog').classList.add('hide'); + btnClearLog.classList.add('hide'); } } @@ -236,12 +243,12 @@ html += ''; html += ''; - html += ''; + html += ''; var date = datetime.parseISO8601Date(item.Date, true); html += date.toLocaleDateString(); html += ''; - html += ''; + html += ''; var status = item.Status; if (item.IsInProgress) { @@ -265,7 +272,7 @@ } html += ''; - html += ''; + html += ''; html += item.TargetPath || ''; html += ''; @@ -282,9 +289,33 @@ return html; } - function onServerEvent(e, apiClient, data) { + function handleItemClick(e) { - var page = $.mobile.activePage; + var id; + + var buttonStatus = parentWithClass(e.target, 'btnShowStatusMessage'); + if (buttonStatus) { + + id = buttonStatus.getAttribute('data-resultid'); + showStatusMessage(id); + } + + var buttonOrganize = parentWithClass(e.target, 'btnProcessResult'); + if (buttonOrganize) { + + id = buttonOrganize.getAttribute('data-resultid'); + organizeFile(e.view, id); + } + + var buttonDelete = parentWithClass(e.target, 'btnDeleteResult'); + if (buttonDelete) { + + id = buttonDelete.getAttribute('data-resultid'); + deleteOriginalFile(e.view, id); + } + } + + function onServerEvent(e, apiClient, data) { if (data) { @@ -322,49 +353,48 @@ }]; } - $(document).on('pageinit', "#libraryFileOrganizerLogPage", function () { - var page = this; + return function (view, params) { - $('.btnClearLog', page).on('click', function () { + page = view; + + var clearButton = view.querySelector('.btnClearLog'); + clearButton.addEventListener('click', function () { ApiClient.clearOrganizationLog().then(function () { - reloadItems(page, true); + reloadItems(view, true); }, Dashboard.processErrorResponse); }); - }).on('pageshow', '#libraryFileOrganizerLogPage', function () { + view.addEventListener('viewshow', function (e) { - LibraryMenu.setTabs('autoorganize', 0, getTabs); + LibraryMenu.setTabs('autoorganize', 0, getTabs); - var page = this; + reloadItems(view, true); - reloadItems(page, true); + events.on(serverNotifications, 'AutoOrganizeUpdate', onServerEvent); - // on here - taskButton({ - mode: 'on', - progressElem: page.querySelector('.organizeProgress'), - panel: page.querySelector('.organizeTaskPanel'), - taskKey: 'AutoOrganize', - button: page.querySelector('.btnOrganize') + // on here + taskButton({ + mode: 'on', + progressElem: view.querySelector('.organizeProgress'), + panel: view.querySelector('.organizeTaskPanel'), + taskKey: 'AutoOrganize', + button: view.querySelector('.btnOrganize') + }); }); - events.on(serverNotifications, 'AutoOrganizeUpdate', onServerEvent); + view.addEventListener('viewhide', function (e) { - }).on('pagebeforehide', '#libraryFileOrganizerLogPage', function () { + currentResult = null; - var page = this; + events.off(serverNotifications, 'AutoOrganizeUpdate', onServerEvent); - currentResult = null; - - // off here - taskButton({ - mode: 'off', - button: page.querySelector('.btnOrganize') + // off here + taskButton({ + mode: 'off', + button: view.querySelector('.btnOrganize') + }); }); - - events.off(serverNotifications, 'AutoOrganizeUpdate', onServerEvent); - }); - + }; }); \ No newline at end of file diff --git a/dashboard-ui/scripts/autoorganizesmart.js b/dashboard-ui/scripts/autoorganizesmart.js index 444487daf0..f1878dc3ca 100644 --- a/dashboard-ui/scripts/autoorganizesmart.js +++ b/dashboard-ui/scripts/autoorganizesmart.js @@ -1,4 +1,4 @@ -define(['jQuery', 'listViewStyle'], function ($) { +define(['listViewStyle'], function () { var query = { @@ -8,6 +8,19 @@ var currentResult; + function parentWithClass(elem, className) { + + while (!elem.classList || !elem.classList.contains(className)) { + elem = elem.parentNode; + + if (!elem) { + return null; + } + } + + return elem; + } + function reloadList(page) { Dashboard.showLoadingMsg(); @@ -93,7 +106,8 @@ html += "
"; } - $('.divMatchInfos', page).html(html); + var matchInfos = page.querySelector('.divMatchInfos'); + matchInfos.innerHTML = html; } function getTabs() { @@ -112,45 +126,47 @@ }]; } - $(document).on('pageinit', "#libraryFileOrganizerSmartMatchPage", function () { + return function (view, params) { - var page = this; + var self = this; - $('.divMatchInfos', page).on('click', '.btnDeleteMatchEntry', function () { + var divInfos = view.querySelector('.divMatchInfos'); - var button = this; - var index = parseInt(button.getAttribute('data-index')); - var matchIndex = parseInt(button.getAttribute('data-matchindex')); + divInfos.addEventListener('click', function (e) { - var info = currentResult.Items[index]; - var entries = [ - { - Name: info.ItemName, - Value: info.MatchStrings[matchIndex] - }]; + var button = parentWithClass(e.target, 'btnDeleteMatchEntry'); - ApiClient.deleteSmartMatchEntries(entries).then(function () { + if (button) { - reloadList(page); + var index = parseInt(button.getAttribute('data-index')); + var matchIndex = parseInt(button.getAttribute('data-matchindex')); - }, Dashboard.processErrorResponse); + var info = currentResult.Items[index]; + var entries = [ + { + Name: info.ItemName, + Value: info.MatchStrings[matchIndex] + }]; + ApiClient.deleteSmartMatchEntries(entries).then(function () { + + reloadList(view); + + }, Dashboard.processErrorResponse); + } }); - }).on('pageshow', "#libraryFileOrganizerSmartMatchPage", function () { + view.addEventListener('viewshow', function (e) { - var page = this; + LibraryMenu.setTabs('autoorganize', 2, getTabs); + Dashboard.showLoadingMsg(); - LibraryMenu.setTabs('autoorganize', 2, getTabs); + reloadList(view); + }); - Dashboard.showLoadingMsg(); - - reloadList(page); - - }).on('pagebeforehide', "#libraryFileOrganizerSmartMatchPage", function () { - - var page = this; - currentResult = null; - }); + view.addEventListener('viewhide', function (e) { + currentResult = null; + }); + }; }); \ No newline at end of file diff --git a/dashboard-ui/scripts/autoorganizetv.js b/dashboard-ui/scripts/autoorganizetv.js index 8a85790a7c..c9c97f92ca 100644 --- a/dashboard-ui/scripts/autoorganizetv.js +++ b/dashboard-ui/scripts/autoorganizetv.js @@ -1,13 +1,4 @@ -define(['jQuery'], function ($) { - - function updateSeasonPatternHelp(page, value) { - - var resultValue = value.replace('%s', '1').replace('%0s', '01').replace('%00s', '001'); - - var replacementHtmlResult = Globalize.translate('OrganizePatternResult').replace('{0}', resultValue); - - $('.seasonFolderFieldDescription', page).html(replacementHtmlResult); - } +define([], function () { function getEpisodeFileName(value, enableMultiEpisode) { @@ -38,70 +29,50 @@ .replace('%00e', '004'); } - function updateEpisodePatternHelp(page, value) { - - value = getEpisodeFileName(value, false); - - var replacementHtmlResult = Globalize.translate('OrganizePatternResult').replace('{0}', value); - - $('.episodePatternDescription', page).html(replacementHtmlResult); - } - - function updateMultiEpisodePatternHelp(page, value) { - - value = getEpisodeFileName(value, true); - - var replacementHtmlResult = Globalize.translate('OrganizePatternResult').replace('{0}', value); - - $('.multiEpisodePatternDescription', page).html(replacementHtmlResult); - } - - function loadPage(page, config) { + function loadPage(view, config) { var tvOptions = config.TvOptions; - $('#chkEnableTvSorting', page).checked(tvOptions.IsEnabled); - $('#chkOverwriteExistingEpisodes', page).checked(tvOptions.OverwriteExistingEpisodes); - $('#chkDeleteEmptyFolders', page).checked(tvOptions.DeleteEmptyFolders); + view.querySelector('#chkEnableTvSorting').checked = tvOptions.IsEnabled; + view.querySelector('#chkOverwriteExistingEpisodes').checked = tvOptions.OverwriteExistingEpisodes; + view.querySelector('#chkDeleteEmptyFolders').checked = tvOptions.DeleteEmptyFolders; - $('#txtMinFileSize', page).val(tvOptions.MinFileSizeMb); - $('#txtSeasonFolderPattern', page).val(tvOptions.SeasonFolderPattern).trigger('change'); - $('#txtSeasonZeroName', page).val(tvOptions.SeasonZeroFolderName); - $('#txtWatchFolder', page).val(tvOptions.WatchLocations[0] || ''); + view.querySelector('#txtMinFileSize').value = tvOptions.MinFileSizeMb; + view.querySelector('#txtSeasonFolderPattern').value = tvOptions.SeasonFolderPattern; + view.querySelector('#txtSeasonZeroName').value = tvOptions.SeasonZeroFolderName; + view.querySelector('#txtWatchFolder').value = tvOptions.WatchLocations[0] || ''; - $('#txtEpisodePattern', page).val(tvOptions.EpisodeNamePattern).trigger('change'); - $('#txtMultiEpisodePattern', page).val(tvOptions.MultiEpisodeNamePattern).trigger('change'); + view.querySelector('#txtEpisodePattern').value = tvOptions.EpisodeNamePattern; + view.querySelector('#txtMultiEpisodePattern').value = tvOptions.MultiEpisodeNamePattern; - $('#txtDeleteLeftOverFiles', page).val(tvOptions.LeftOverFileExtensionsToDelete.join(';')); - - $('#copyOrMoveFile', page).val(tvOptions.CopyOriginalFile.toString()); + view.querySelector('#txtDeleteLeftOverFiles').value = tvOptions.LeftOverFileExtensionsToDelete.join(';'); + view.querySelector('#copyOrMoveFile').value = tvOptions.CopyOriginalFile.toString(); } - function onSubmit() { - var form = this; + function onSubmit(view) { ApiClient.getNamedConfiguration('autoorganize').then(function (config) { var tvOptions = config.TvOptions; + + tvOptions.IsEnabled = view.querySelector('#chkEnableTvSorting').checked; + tvOptions.OverwriteExistingEpisodes = view.querySelector('#chkOverwriteExistingEpisodes').checked; + tvOptions.DeleteEmptyFolders = view.querySelector('#chkDeleteEmptyFolders').checked; - tvOptions.IsEnabled = $('#chkEnableTvSorting', form).checked(); - tvOptions.OverwriteExistingEpisodes = $('#chkOverwriteExistingEpisodes', form).checked(); - tvOptions.DeleteEmptyFolders = $('#chkDeleteEmptyFolders', form).checked(); + tvOptions.MinFileSizeMb = view.querySelector('#txtMinFileSize').value; + tvOptions.SeasonFolderPattern = view.querySelector('#txtSeasonFolderPattern').value; + tvOptions.SeasonZeroFolderName = view.querySelector('#txtSeasonZeroName').value; - tvOptions.MinFileSizeMb = $('#txtMinFileSize', form).val(); - tvOptions.SeasonFolderPattern = $('#txtSeasonFolderPattern', form).val(); - tvOptions.SeasonZeroFolderName = $('#txtSeasonZeroName', form).val(); + tvOptions.EpisodeNamePattern = view.querySelector('#txtEpisodePattern').value; + tvOptions.MultiEpisodeNamePattern = view.querySelector('#txtMultiEpisodePattern').value; - tvOptions.EpisodeNamePattern = $('#txtEpisodePattern', form).val(); - tvOptions.MultiEpisodeNamePattern = $('#txtMultiEpisodePattern', form).val(); + tvOptions.LeftOverFileExtensionsToDelete = view.querySelector('#txtDeleteLeftOverFiles').value.split(';'); - tvOptions.LeftOverFileExtensionsToDelete = $('#txtDeleteLeftOverFiles', form).val().split(';'); - - var watchLocation = $('#txtWatchFolder', form).val(); + var watchLocation = view.querySelector('#txtWatchFolder').value; tvOptions.WatchLocations = watchLocation ? [watchLocation] : []; - tvOptions.CopyOriginalFile = $('#copyOrMoveFile', form).val(); + tvOptions.CopyOriginalFile = view.querySelector('#copyOrMoveFile').value; ApiClient.updateNamedConfiguration('autoorganize', config).then(Dashboard.processServerConfigurationUpdateResult, Dashboard.processErrorResponse); }); @@ -125,29 +96,40 @@ }]; } - $(document).on('pageinit', "#libraryFileOrganizerPage", function () { + return function (view, params) { - var page = this; - $('#txtSeasonFolderPattern', page).on('change keyup', function () { + function updateSeasonPatternHelp() { - updateSeasonPatternHelp(page, this.value); + var value = view.querySelector('#txtSeasonFolderPattern').value; + value = value.replace('%s', '1').replace('%0s', '01').replace('%00s', '001'); - }); + var replacementHtmlResult = Globalize.translate('OrganizePatternResult').replace('{0}', value); - $('#txtEpisodePattern', page).on('change keyup', function () { + view.querySelector('.seasonFolderFieldDescription').innerHTML = replacementHtmlResult; + } - updateEpisodePatternHelp(page, this.value); + function updateEpisodePatternHelp() { - }); + var value = view.querySelector('#txtEpisodePattern').value; + var fileName = getEpisodeFileName(value, false); - $('#txtMultiEpisodePattern', page).on('change keyup', function () { + var replacementHtmlResult = Globalize.translate('OrganizePatternResult').replace('{0}', fileName); - updateMultiEpisodePatternHelp(page, this.value); + view.querySelector('.episodePatternDescription').innerHTML = replacementHtmlResult; + } - }); + function updateMultiEpisodePatternHelp() { - $('#btnSelectWatchFolder', page).on("click.selectDirectory", function () { + var value = view.querySelector('#txtMultiEpisodePattern').value; + var fileName = getEpisodeFileName(value, false); + + var replacementHtmlResult = Globalize.translate('OrganizePatternResult').replace('{0}', fileName); + + view.querySelector('.multiEpisodePatternDescription').innerHTML = replacementHtmlResult; + } + + function selectWatchFolder(e) { require(['directorybrowser'], function (directoryBrowser) { @@ -158,28 +140,42 @@ callback: function (path) { if (path) { - $('#txtWatchFolder', page).val(path); + + view.querySelector('#txtWatchFolder').value = path; } picker.close(); }, - header: Globalize.translate('HeaderSelectWatchFolder'), - instruction: Globalize.translate('HeaderSelectWatchFolderHelp') }); }); + } + + view.querySelector('#txtSeasonFolderPattern').addEventListener('change', updateSeasonPatternHelp); + view.querySelector('#txtSeasonFolderPattern').addEventListener('keyup', updateSeasonPatternHelp); + view.querySelector('#txtEpisodePattern').addEventListener('change', updateEpisodePatternHelp); + view.querySelector('#txtEpisodePattern').addEventListener('keyup', updateEpisodePatternHelp); + view.querySelector('#txtMultiEpisodePattern').addEventListener('change', updateMultiEpisodePatternHelp); + view.querySelector('#txtMultiEpisodePattern').addEventListener('keyup', updateMultiEpisodePatternHelp); + view.querySelector('#btnSelectWatchFolder').addEventListener('click', selectWatchFolder); + + view.querySelector('.libraryFileOrganizerForm').addEventListener('submit', function (e) { + + e.preventDefault(); + onSubmit(view); + return false; }); - $('.libraryFileOrganizerForm').off('submit', onSubmit).on('submit', onSubmit); + view.addEventListener('viewshow', function (e) { - }).on('pageshow', "#libraryFileOrganizerPage", function () { + LibraryMenu.setTabs('autoorganize', 1, getTabs); - var page = this; - - LibraryMenu.setTabs('autoorganize', 1, getTabs); - - ApiClient.getNamedConfiguration('autoorganize').then(function (config) { - loadPage(page, config); + ApiClient.getNamedConfiguration('autoorganize').then(function (config) { + loadPage(view, config); + updateSeasonPatternHelp(); + updateEpisodePatternHelp(); + updateMultiEpisodePatternHelp(); + }); }); - }); + }; }); \ No newline at end of file diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index 55b1527ef6..2226a98f6b 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -1758,6 +1758,7 @@ var AppInfo = {}; define("livetvcss", ['css!css/livetv.css']); define("detailtablecss", ['css!css/detailtable.css']); + define("autoorganizetablecss", ['css!css/autoorganizetable.css']); define("buttonenabled", ["legacy/buttonenabled"]); @@ -1905,20 +1906,23 @@ var AppInfo = {}; defineRoute({ path: '/autoorganizelog.html', - dependencies: [], + dependencies: ['scripts/taskbutton', 'autoorganizetablecss'], + controller: 'scripts/autoorganizelog', roles: 'admin' }); defineRoute({ path: '/autoorganizesmart.html', dependencies: [], + controller: 'scripts/autoorganizesmart', autoFocus: false, roles: 'admin' }); defineRoute({ path: '/autoorganizetv.html', - dependencies: [], + dependencies: ['jqmtable', 'paper-input', 'paper-checkbox'], + controller: 'scripts/autoorganizetv', autoFocus: false, roles: 'admin' });