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'
});