#20542 adding "in progress" cursor to ajax directory requests

This commit is contained in:
Benjamin Grabkowitz 2014-03-10 12:54:58 -04:00 committed by Sebastien Ros
parent b27e1d5c00
commit 3c905bb7a2
3 changed files with 151 additions and 116 deletions

View File

@ -76,12 +76,34 @@ $(function () {
self.focus = ko.observable();
self.results = ko.observableArray();
self.displayed = ko.observable();
self.pendingRequest = ko.observable(false);
self.mediaItemsCount = 0;
self.orderMedia = ko.observableArray(['created']);
self.mediaType = ko.observableArray([]);
self.mediaFolders = ko.observableArray([]);
self.mediaFoldersRequestCount = ko.observable(0);
self.mediaFoldersPendingRequest = ko.computed({
read: function () {
return (self.mediaFoldersRequestCount() > 0);
},
write: function (value) {
if (value === true) {
self.mediaFoldersRequestCount(self.mediaFoldersRequestCount() + 1);
} else if (value === false) {
self.mediaFoldersRequestCount(self.mediaFoldersRequestCount() - 1);
}
}
});
self.mediaPendingRequest = ko.observable(false);
self.pendingRequest = ko.computed({
read: function () {
return (self.mediaFoldersPendingRequest() || self.mediaPendingRequest());
},
write: function (value) {
self.mediaPendingRequest(value);
}
});
self.getMediaItems = function (count, append) {
var folderPath = self.displayed() || '';
@ -264,6 +286,10 @@ $(function () {
});
self.folderClicked = function () {
if (self.mediaIndexViewModel.mediaFoldersPendingRequest()) {
return;
}
self.mediaIndexViewModel.selectFolder(self.folderPath());
var childFolders = self.childFolders();
@ -284,6 +310,8 @@ $(function () {
return settings.childFolderListingActionUrl + '?folderPath=' + encodeURIComponent(f);
};
var url = getChildFolderListUrl(self.folderPath());
self.mediaIndexViewModel.mediaFoldersPendingRequest(true);
$.ajax({
type: "GET",
@ -296,10 +324,13 @@ $(function () {
newChildFolder.isVisible(true);
self.childFolders.push(newChildFolder);
}
self.childFoldersFetchStatus = 2;
}).fail(function (data) {
console.error(data);
self.childFoldersFetchStatus = 0;
}).always(function () {
self.mediaIndexViewModel.mediaFoldersPendingRequest(false);
});
}

View File

@ -105,6 +105,10 @@
background-color: #e0e0e0;
}
.in-progress .media-library-folder-title:hover, .in-progress .media-library-folder-title.selected, .in-progress a {
cursor: progress;
}
.media-library-navigation-folder-link {
padding: 0;
}

View File

@ -1,117 +1,117 @@
@model Orchard.MediaLibrary.ViewModels.MediaManagerIndexViewModel
@{
var viewModel = Model;
Script.Require("ShapesBase");
Style.Require("MediaManagerAdmin");
Script.Require("jQuery");
Script.Require("jQueryUI_Droppable");
Script.Include("knockout-2.3.0.js");
Script.Include("history.js");
Script.Include("media-library.js");
Style.Require("FontAwesome");
Layout.Title = T("Media Library");
}
<div id="media-library" data-draft-text="@T("Draft")">
<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("Edit", "Folder", new { area = "Orchard.MediaLibrary"}))?folderPath=' + encodeURIComponent(displayed()) }" class="button" id="button-edit-folder">@T("Edit Folder")</a>
<a href="#" data-bind="attr: { href: '@HttpUtility.JavaScriptStringEncode(Url.Action("Create", "Folder", new { area = "Orchard.MediaLibrary"}))?folderPath=' + encodeURIComponent(displayed() ? displayed() : '') }" class="button" id="button-create-folder">@T("Create Folder")</a>
@Display(Model.CustomActionsShapes)
</div>
<div id="media-library-main">
<div id="media-library-main-navigation">
<ul>
@Display(Model.CustomNavigationShapes)
<li id="media-library-main-navigation-tree">
<ul data-bind="template: { name: 'media-folder-template', foreach: mediaFolders }">
</ul>
</li>
</ul>
</div>
<div id="media-library-main-list-wrapper">
<div id="media-library-main-list" data-bind="event: { scroll: scrolled }, css: { pending: pendingRequest() }">
<ul data-bind="foreach: results">
<li data-bind="css: cssClass">
<div class="thumbnail" data-bind="html: data.thumbnail">
</div>
<div class="media-library-main-list-overlay">
<p class="title" data-bind="text: data.title"></p>
<p class="publication-status" data-bind="text: publicationStatus"></p>
</div>
</li>
</ul>
</div>
</div>
<div id="media-library-main-editor">
<div id="media-library-main-editor-focus" data-bind="with: focus">
<h1>@T("PROPERTIES")</h1>
<div class="summary" data-bind="html: summary">
</div>
</div>
<article>
<header>
<div id="media-library-main-selection" data-bind="visible: selection().length > 0">
<h1>@T("SELECTION")</h1>
<ul data-bind="foreach: selection">
<li data-bind="css: cssClass">
<div class="thumbnail selection" data-bind="html: data.thumbnail, click: $parent.focus">
</div>
</li>
</ul>
<div id="media-library-main-selection-actions">
<button id="delete-selection-button">@T("Delete")</button>
</div>
</div>
</header>
<footer>
<div id="media-library-main-selection-select">
<button class="button-select" data-bind="visible: selection().length > 0">@T("Select")</button>
<button class="button-cancel">@T("Cancel")</button>
</div>
</footer>
</article>
</div>
</div>
</div>
@using (Script.Foot()) {
<script type="text/javascript">
//<![CDATA[
var mediaLibrarySettings = {
mediaItemActionUrl: '@HttpUtility.JavaScriptStringEncode(Url.Action("MediaItem", "Admin"))',
mediaItemsActionUrl: '@HttpUtility.JavaScriptStringEncode(Url.Action("MediaItems", "Admin"))',
recentMediaItemsActionUrl: '@HttpUtility.JavaScriptStringEncode(Url.Action("RecentMediaItems", "Admin"))',
childFolderListingActionUrl: '@HttpUtility.JavaScriptStringEncode(Url.Action("ChildFolders", "Admin"))',
importActionUrl: '@HttpUtility.JavaScriptStringEncode(Url.Action("Import", "Admin"))',
moveActionUrl: '@Url.Action("Move", "Folder", new {area = "Orchard.MediaLibrary"})',
deleteActionUrl: '@Url.Action("Delete", "Admin", new {area = "Orchard.MediaLibrary"})',
hasFolderPath: @(viewModel.FolderPath != null ? "true" : "false"),
folderPath: '@HttpUtility.JavaScriptStringEncode(viewModel.FolderPath)',
deleteConfirmationMessage: '@HttpUtility.JavaScriptStringEncode(T("Are you sure you want to delete these media items ?").Text)',
errorMessage: '@HttpUtility.JavaScriptStringEncode(T("An unexpected error occured, please refresh the page and try again.").Text)',
antiForgeryToken: '@Html.AntiForgeryTokenValueOrchard()',
childFolders: (@Display.Partial(TemplateName: "ChildFolders", Model: viewModel.ChildFoldersViewModel))['childFolders']
@model Orchard.MediaLibrary.ViewModels.MediaManagerIndexViewModel
@{
var viewModel = Model;
Script.Require("ShapesBase");
Style.Require("MediaManagerAdmin");
Script.Require("jQuery");
Script.Require("jQueryUI_Droppable");
Script.Include("knockout-2.3.0.js");
Script.Include("history.js");
Script.Include("media-library.js");
Style.Require("FontAwesome");
Layout.Title = T("Media Library");
}
<div id="media-library" data-draft-text="@T("Draft")">
<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("Edit", "Folder", new { area = "Orchard.MediaLibrary"}))?folderPath=' + encodeURIComponent(displayed()) }" class="button" id="button-edit-folder">@T("Edit Folder")</a>
<a href="#" data-bind="attr: { href: '@HttpUtility.JavaScriptStringEncode(Url.Action("Create", "Folder", new { area = "Orchard.MediaLibrary"}))?folderPath=' + encodeURIComponent(displayed() ? displayed() : '') }" class="button" id="button-create-folder">@T("Create Folder")</a>
@Display(Model.CustomActionsShapes)
</div>
<div id="media-library-main">
<div id="media-library-main-navigation">
<ul>
@Display(Model.CustomNavigationShapes)
<li id="media-library-main-navigation-tree">
<ul data-bind="template: { name: 'media-folder-template', foreach: mediaFolders }">
</ul>
</li>
</ul>
</div>
<div id="media-library-main-list-wrapper">
<div id="media-library-main-list" data-bind="event: { scroll: scrolled }, css: { pending: pendingRequest() }">
<ul data-bind="foreach: results">
<li data-bind="css: cssClass">
<div class="thumbnail" data-bind="html: data.thumbnail">
</div>
<div class="media-library-main-list-overlay">
<p class="title" data-bind="text: data.title"></p>
<p class="publication-status" data-bind="text: publicationStatus"></p>
</div>
</li>
</ul>
</div>
</div>
<div id="media-library-main-editor">
<div id="media-library-main-editor-focus" data-bind="with: focus">
<h1>@T("PROPERTIES")</h1>
<div class="summary" data-bind="html: summary">
</div>
</div>
<article>
<header>
<div id="media-library-main-selection" data-bind="visible: selection().length > 0">
<h1>@T("SELECTION")</h1>
<ul data-bind="foreach: selection">
<li data-bind="css: cssClass">
<div class="thumbnail selection" data-bind="html: data.thumbnail, click: $parent.focus">
</div>
</li>
</ul>
<div id="media-library-main-selection-actions">
<button id="delete-selection-button">@T("Delete")</button>
</div>
</div>
</header>
<footer>
<div id="media-library-main-selection-select">
<button class="button-select" data-bind="visible: selection().length > 0">@T("Select")</button>
<button class="button-cancel">@T("Cancel")</button>
</div>
</footer>
</article>
</div>
</div>
</div>
@using (Script.Foot()) {
<script type="text/javascript">
//<![CDATA[
var mediaLibrarySettings = {
mediaItemActionUrl: '@HttpUtility.JavaScriptStringEncode(Url.Action("MediaItem", "Admin"))',
mediaItemsActionUrl: '@HttpUtility.JavaScriptStringEncode(Url.Action("MediaItems", "Admin"))',
recentMediaItemsActionUrl: '@HttpUtility.JavaScriptStringEncode(Url.Action("RecentMediaItems", "Admin"))',
childFolderListingActionUrl: '@HttpUtility.JavaScriptStringEncode(Url.Action("ChildFolders", "Admin"))',
importActionUrl: '@HttpUtility.JavaScriptStringEncode(Url.Action("Import", "Admin"))',
moveActionUrl: '@Url.Action("Move", "Folder", new {area = "Orchard.MediaLibrary"})',
deleteActionUrl: '@Url.Action("Delete", "Admin", new {area = "Orchard.MediaLibrary"})',
hasFolderPath: @(viewModel.FolderPath != null ? "true" : "false"),
folderPath: '@HttpUtility.JavaScriptStringEncode(viewModel.FolderPath)',
deleteConfirmationMessage: '@HttpUtility.JavaScriptStringEncode(T("Are you sure you want to delete these media items ?").Text)',
errorMessage: '@HttpUtility.JavaScriptStringEncode(T("An unexpected error occured, please refresh the page and try again.").Text)',
antiForgeryToken: '@Html.AntiForgeryTokenValueOrchard()',
childFolders: (@Display.Partial(TemplateName: "ChildFolders", Model: viewModel.ChildFoldersViewModel))['childFolders']
};
//]]>
</script>
<script type="text/html" id="media-folder-template">
<li data-bind="visible: isVisible()">
<div class="media-library-folder">
<div class="media-library-folder-title" data-bind="click: folderClicked, css: { selected: isSelected() }">
<a data-bind="disable: $root.pendingRequest" href="#" class="media-library-navigation-folder-link"><i data-bind="css: {'icon-folder-open-alt': isExpanded(), 'icon-folder-close-alt': !isExpanded()}"></i><span data-bind="text: name"></span></a>
</div>
<ul data-bind="template: { name: 'media-folder-template', foreach: childFolders }, visible: childFolders().length > 0">
</ul>
</div>
</li>
</script>
//]]>
</script>
<script type="text/html" id="media-folder-template">
<li data-bind="visible: isVisible()">
<div class="media-library-folder" data-bind="css: { 'in-progress': $root.pendingRequest() }">
<div class="media-library-folder-title" data-bind="click: folderClicked, css: { selected: isSelected() }">
<a href="#" class="media-library-navigation-folder-link"><i data-bind=" css: {'icon-folder-open-alt': isExpanded(), 'icon-folder-close-alt': !isExpanded()}"></i><span data-bind=" text: name"></span></a>
</div>
<ul data-bind="template: { name: 'media-folder-template', foreach: childFolders}, visible: childFolders().length > 0">
</ul>
</div>
</li>
</script>
}