Improving media library browsing

- Adding 'Recent' menu item
- Adding sorting
- Adding filtering

--HG--
branch : 1.x
This commit is contained in:
Sebastien Ros
2013-05-30 18:12:17 -07:00
parent adfc1b53b4
commit 91a9c8669c
8 changed files with 265 additions and 76 deletions

View File

@@ -9,7 +9,8 @@
Script.Require("jQueryUI_Droppable");
Script.Include("knockout-2.2.1.js");
Script.Include("history.js");
Style.Require("FontAwesome");
if (Model.DialogMode) {
Style.Include("dialog-mode.css");
}
@@ -20,28 +21,42 @@
<div id="media-library">
<div id="media-library-toolbar">
<a href="#" data-bind="visible: displayed(), click: importMedia" class="button" id="button-import">@T("Import")</a>
<a href="#" data-bind="visible: displayed(), attr: { href: '@HttpUtility.JavaScriptStringEncode(Url.Action("Create", "Folder", new { area = "Orchard.MediaLibrary"}))/' + displayed() }" class="button" id="button-create-folder">@T("Create Folder")</a>
<a href="#" data-bind="visible: displayed(), attr: { href: '@HttpUtility.JavaScriptStringEncode(Url.Action("Edit", "Folder", new { area = "Orchard.MediaLibrary"}))/' + displayed() }" class="button" id="button-edit-folder">@T("Edit Folder")</a>
<label for="filterMediaType">@T("Show")</label>
<select id="filterMediaType" name="FilteredMediaType" data-bind="selectedOptions: mediaType">
@Html.SelectOption("", true, T("Any (show all)").ToString())
@foreach(var mediaType in Model.MediaTypes) {
@Html.SelectOption(mediaType, false, mediaType)
}
</select>
<label for="orderMedia">@T("Ordered by")</label>
<select data-bind="selectedOptions: orderMedia" id="orderMedia" name="OrderMedia">
@Html.SelectOption("title", false, T("title").ToString())
@Html.SelectOption("created", true, T("recently created").ToString())
@Html.SelectOption("published", false, T("recently published").ToString())
@Html.SelectOption("modified", false, T("recently modified").ToString())
</select>
<div id="media-library-toolbar-actions">
<a href="@Url.Action("Create", "Folder", new {id = viewModel.Folder, area = "Orchard.MediaLibrary"})" class="button" id="button-create-folder">@T("Create Folder")</a>
<a href="#" data-bind="attr: { href: '@HttpUtility.JavaScriptStringEncode(Url.Action("Edit", "Folder", new { area = "Orchard.MediaLibrary"}))/' + displayed() }" class="button" id="button-edit-folder">@T("Edit Folder")</a>
</div>
</div>
<div id="media-library-main">
<div id="media-library-main-navigation">
<ul>
<li><a href="#" data-bind="click: selectRecent, css: { selected: !displayed() }" id="button-recent"><i class="icon-time"></i>@T("Recent")</a>
<li id="media-library-main-navigation-tree">
<h3>@T("Categories")</h3>
<ul class="">
<ul>
@foreach (var folder in viewModel.Folders) {
<li>
@Display.Partial(TemplateName: "MediaManagerFolder", Model: folder)
</li>
}
</ul>
</li>
<li><h3>@T("Recent")</h3></li>
<li><h3>@T("Starred")</h3></li>
</ul>
</div>
<div id="media-library-main-list-wrapper">
@@ -148,7 +163,9 @@
self.displayed = ko.observable();
self.pendingRequest = ko.observable(false);
self.mediaItemsCount = 0;
self.orderMedia = ko.observableArray(['created']);
self.mediaType = ko.observableArray([]);
self.getMediaItems = function (id, max) {
if (self.pendingRequest()) {
return;
@@ -161,7 +178,7 @@
self.pendingRequest(true);
var url = '@HttpUtility.JavaScriptStringEncode(Url.Action("MediaItems", "Admin"))/' + id + '?skip=' + self.results().length + '&count=' + max;
var url = '@HttpUtility.JavaScriptStringEncode(Url.Action("MediaItems", "Admin"))/' + id + '?skip=' + self.results().length + '&count=' + max + '&order=' + self.orderMedia() + '&mediaType=' + self.mediaType();
$.ajax({
type: "GET",
@@ -235,6 +252,51 @@
window.history.pushState({ action: 'displayFolder', folder: id }, '', '?folder=' + id);
self.displayFolder(id);
};
self.selectRecent = function () {
window.history.pushState({ action: 'selectRecent' }, '', '?recent');
self.results([]);
self.displayed(null);
var max = 20;
if (self.pendingRequest()) {
return;
}
if (self.results().length > 0 && self.results().length >= self.mediaItemsCount) {
console.log('no more content, mediaItemsCount: ' + self.mediaItemsCount);
return;
}
self.pendingRequest(true);
var url = '@HttpUtility.JavaScriptStringEncode(Url.Action("RecentMediaItems", "Admin"))?skip=' + self.results().length + '&count=' + max + '&order=' + self.orderMedia() + '&mediaType=' + self.mediaType();
$.ajax({
type: "GET",
url: url,
}).done(function (data) {
var mediaItems = data.mediaItems;
self.mediaItemsCount = data.mediaItemsCount;
for (var i = 0; i < mediaItems.length; i++) {
var item = new MediaPartViewModel(mediaItems[i]);
self.results.push(item);
// pre-select result which are already part of the selection
var selection = self.selection();
for (var j = 0; j < selection.length; j++) {
if (selection[j].data.id == item.data.id) {
viewModel.toggleSelect(item, true);
}
}
}
}).fail(function(data) {
console.error(data);
}).always(function () {
self.pendingRequest(false);
});
}
self.toggleSelect = function (searchResult, force) {
var index = $.inArray(searchResult, self.selection());
@@ -264,7 +326,13 @@
self.scrolled = function(data, event) {
var elem = event.target;
if (elem.scrollTop > (elem.scrollHeight - elem.offsetHeight - 300)) {
self.getMediaItems(self.displayed(), 20);
if(seld.displayed()) {
self.getMediaItems(self.displayed(), 20);
}
else {
// todo, infinite scrolling for 'recent'
}
}
};
@@ -272,6 +340,24 @@
var url = '@HttpUtility.JavaScriptStringEncode(Url.Action("Import", "Admin"))/' + self.displayed();
window.location = url;
};
self.orderMedia.subscribe(function (newValue) {
if(self.displayed()) {
self.selectFolder(self.displayed());
}
else {
self.selectRecent();
}
});
self.mediaType.subscribe(function (newValue) {
if(self.displayed()) {
self.selectFolder(self.displayed());
}
else {
self.selectRecent();
}
});
};
var viewModel = new MediaIndexViewModel();
@@ -283,11 +369,21 @@
window.history.pushState({ action: 'displayFolder', folder: @viewModel.Folder.Value }, '', '?folder=@viewModel.Folder.Value');
</text>
}
else {
<text>
viewModel.selectRecent();
window.history.pushState({ action: 'selectRecent' }, '', '?recent');
</text>
}
window.onpopstate = function (event) {
if (event && event.state && event.state.action == 'displayFolder') {
viewModel.displayFolder(event.state.folder);
}
if (event && event.state && event.state.action == 'selectRecent') {
viewModel.selectRecent();
}
};
$("#media-library-main-list").on("mousedown", "li", function (e) {
@@ -366,9 +462,11 @@
},
}).done(function (result) {
if (result) {
viewModel.results.remove(function(item) {
return ids.indexOf(item.data.id) != -1;
});
if(viewModel.displayed()) {
viewModel.results.remove(function(item) {
return ids.indexOf(item.data.id) != -1;
});
}
viewModel.clearSelection();
} else {