Skip to content

Commit

Permalink
create modal for monitoring file copying
Browse files Browse the repository at this point in the history
  • Loading branch information
badescuga authored and davidebbo committed Oct 15, 2015
1 parent 3f22884 commit 0c14488
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 32 deletions.
132 changes: 103 additions & 29 deletions Kudu.Services.Web/Content/Scripts/FileBrowser.js
Expand Up @@ -80,39 +80,51 @@ function showAceHelpModal() {
});
}

// File upload progress indicator
var copyProgressObjects = {};

var copyObjectsManager = {
init: function() {
copyProgressObjects = {};
this._copyProgressObjects = {};
this.infoMessage = '';
},
getInfoMessage: function() {
return this._infoMessage;
},
setInfoMessage: function(message) {
this._infoMessage = message;
},
addCopyStats: function (uri, loadedData, totalData
) {
if (copyProgressObjects[uri]) {
if (loadedData === totalData) {
copyProgressObjects[uri].endDate = $.now();
addCopyStats: function (uri, loadedData, totalData) {

uri = uri.substring(uri.indexOf('/vfs') + 5, uri.length); // slice uri to be prettier[ex: http://localhost:37911/api/vfs/ttesstt//Kudu.FunctionalTests/Vfs/VfsControllerTest.cs => ttesstt//Kudu.FunctionalTests/Vfs/VfsControllerTest.cs]
if (this._copyProgressObjects[uri]) {
if (loadedData === totalData) {
this._copyProgressObjects[uri].endDate = $.now();
} else {
this._copyProgressObjects[uri].copyPackEnded = false;
}
} else {
copyProgressObjects[uri] = {};
copyProgressObjects[uri].startDate = $.now();
//this is used for when copying multiple files in the same time so that i may stii have a coherent percentage
copyProgressObjects[uri].transactionPackFinished = false;
this._copyProgressObjects[uri] = {};
this._copyProgressObjects[uri].startDate = $.now();
this._copyProgressObjects[uri].copyPackEnded = false; //this is used for when copying multiple files in the same time so that i may still have a coherent percentage
}

copyProgressObjects[uri].loadedData = loadedData;
copyProgressObjects[uri].totalData = totalData;
if (totalData === 0) { // empty files appear to have size 0
totalData = loadedData = 1;
}

this._copyProgressObjects[uri].loadedData = loadedData;
this._copyProgressObjects[uri].totalData = totalData;
},
getCopyStats: function () {
return copyProgressObjects;
return this._copyProgressObjects;
},
getCurrentPercentCompletion: function () {
var currentTransfered = 0;
var finalTransfered = 0;
var foundItem = false;

for (var key in copyProgressObjects) {
var co = copyProgressObjects[key];
if(co.transactionPackFinished === false) {
for (var key in this._copyProgressObjects) {
var co = this._copyProgressObjects[key];
if(co.copyPackEnded === false) {
foundItem = true;
currentTransfered += co.loadedData;
finalTransfered += co.totalData;
Expand All @@ -127,12 +139,20 @@ var copyObjectsManager = {
}

if (perc === 100 && foundItem) { // if all transactions have finished & have some unmarked transaction pack, cancel it out
for (var key in copyProgressObjects) {
copyProgressObjects[key].transactionPackFinished = true;
for (var key in this._copyProgressObjects) {
this._copyProgressObjects[key].copyPackEnded = true;
}
}

return perc;
},
removeAtIndex: function(index) {
delete this._copyProgressObjects[index];
},
clearData: function () {
var date = new Date();
this._infoMessage = 'You have cleared the cache at ' + date.toLocaleString();
this._copyProgressObjects = {};
}
}

Expand All @@ -154,15 +174,16 @@ $.connection.hub.start().done(function () {
},

setContent: function (item, text) {
var _url = item.href.replace(/#/g, encodeURIComponent("#"));
return $.ajax({
url: item.href.replace(/#/g, encodeURIComponent("#")),
url: _url,
data: text,
method: "PUT",
xhr: function () { // Custom XMLHttpRequest
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) { // Check if upload property exists
myXhr.upload.addEventListener('progress', function (e) {
copyProgressHandlingFunction(e, item.href);
copyProgressHandlingFunction(e, _url);
}, false); // For handling the progress of the upload
}
return myXhr;
Expand All @@ -189,7 +210,9 @@ $.connection.hub.start().done(function () {
return whenArray(
$.map(files, function (item) {
var baseHref = unzip ? viewModel.selected().href.replace(/\/vfs\//, "/zip/") : viewModel.selected().href;
return Vfs.setContent({ href: (baseHref + (unzip ? "" : item.name)) }, item.contents);
var finalHref = (baseHref + (unzip ? "" : item.name));
copyObjectsManager.addCopyStats(finalHref, 0, item.contents.size); //files copy progress data for monitory
return Vfs.setContent({ href: finalHref }, item.contents);
})
);
},
Expand Down Expand Up @@ -376,11 +399,13 @@ $.connection.hub.start().done(function () {
workingDirChanging = false,
viewModel = {
root: root,
copyProgStats: ko.observable(),
specialDirs: ko.observableArray([]),
selected: ko.observable(root),
koprocessing: ko.observable(false),
fileEdit: ko.observable(null),
editText: ko.observable(""),
isTransferInProgress: ko.observable(false),
cancelEdit: function () {
viewModel.fileEdit(null);
statusbarObj.reset();
Expand All @@ -391,11 +416,30 @@ $.connection.hub.start().done(function () {
item.selectNode();
}
},
showCopyProgressModal: function() {
$('#files-transfered-modal').modal();
copyProgressHandlingFunction(null,null,true);
},
clearCopyProgressCache: function() {
copyObjectsManager.clearData();
viewModel.copyProgStats("");
},
getCopyPercentage: function(item) {
return (item.loadedData * 100 / item.totalData).toFixed(1);
},
getCopyPercentageDisplay: function (item) {
return formatHandler.fileSize(item.loadedData, true) + " / " + formatHandler.fileSize(item.totalData, true);
},
errorText: ko.observable(),
inprocessing: 0,
processing: function (value) {
value ? viewModel.inprocessing++ : viewModel.inprocessing--;
viewModel.inprocessing > 0 ? viewModel.koprocessing(true) : viewModel.koprocessing(false);
if (viewModel.inprocessing > 0) {
viewModel.koprocessing(true);
} else {
viewModel.koprocessing(false);
viewModel.isTransferInProgress(false);
}
}
};

Expand Down Expand Up @@ -501,12 +545,42 @@ $.connection.hub.start().done(function () {
};

//monitor file upload progress
function copyProgressHandlingFunction(e,uniqueUrl) {
if (e.lengthComputable) {
copyObjectsManager.addCopyStats(uniqueUrl, e.loaded, e.total);
var perc = copyObjectsManager.getCurrentPercentCompletion();
$('#copy-percentage').text(perc + "%");
function copyProgressHandlingFunction(e,uniqueUrl,forceUpdateModal) {
if (e && uniqueUrl && e.lengthComputable) {
copyObjectsManager.addCopyStats(uniqueUrl, e.loaded, e.total); //add/update stats
}
var perc = copyObjectsManager.getCurrentPercentCompletion(); // perc-per-total transaction
var copyObjs = copyObjectsManager.getCopyStats();

$('#copy-percentage').text(perc + "%");

if(perc != 100 && perc != 0) {
viewModel.isTransferInProgress(true);
}

//handler for clearing out cache once it gets too large
var currentObjCount = Object.keys(copyObjs).length;
if (currentObjCount > 2000) {
for (var i = 0; i < 1000; i++) { //delete oldest 1000 copy prog objects
copyObjectsManager.removeAtIndex(0);
}
var date = new Date();
copyObjectsManager.setInfoMessage('Cache was partialy auto-cleared at ' + date.toLocaleString() + ' for performance improvements');
}

if ($('#files-transfered-modal').is(':visible') || forceUpdateModal) { // update if modal visible
viewModel.copyProgStats(copyObjs); // update viewmodel

var modalHeaderText = '';
if (perc < 100) {
modalHeaderText = 'Transfered Files (<b>' + perc + '%</b>).';
} else {
modalHeaderText = '<b style =\' color:green\'> Transfered Files (' + perc + '%).</b>';
}
modalHeaderText += ' ' +((_temp = copyObjectsManager.getInfoMessage()) ? _temp : "");
$('#files-transfered-modal .modal-header').html(modalHeaderText);
}

}

function setupFileSystemWatcher() {
Expand Down
17 changes: 17 additions & 0 deletions Kudu.Services.Web/Content/Scripts/HelperScript.js
@@ -0,0 +1,17 @@
var formatHandler = {
fileSize: function(bytes, si) {
var thresh = si ? 1000 : 1024;
if (Math.abs(bytes) < thresh) {
return bytes + ' B';
}
var units = si
? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
var u = -1;
do {
bytes /= thresh;
++u;
} while (Math.abs(bytes) >= thresh && u < units.length - 1);
return bytes.toFixed(1) + ' ' + units[u];
}
};
8 changes: 8 additions & 0 deletions Kudu.Services.Web/Content/Styles/FileBrowser.css
Expand Up @@ -203,3 +203,11 @@ div.editor {
transition: border-left-color 0.35s ease;
}

.table-nonfluid {
table-layout: fixed;
word-wrap: break-word;
}

.box-border{
border:solid 2px grey;
}
43 changes: 41 additions & 2 deletions Kudu.Services.Web/DebugConsole/Default.cshtml
Expand Up @@ -34,7 +34,9 @@
<i class="h4 glyphicon glyphicon-hdd" title="System Drive"></i>
</a>
<div class="spinner">
<span data-bind="visible: koprocessing()" id="copy-percentage" title="percentage copy"></span>
<button class="btn btn-info box-border" style="display:none" data-bind="visible: isTransferInProgress(), click: showCopyProgressModal">
<span id="copy-percentage" title="percentage copy"></span>
</button>
<i data-bind="visible: koprocessing()" class="fa fa-spinner fa-spin" title="Please wait"></i>
<i data-bind="visible: errorText, attr: {title: errorText}" class="alert-warning glyphicon glyphicon-exclamation-sign" style="display: none"></i>
</div>
Expand Down Expand Up @@ -100,8 +102,44 @@
</div>
<a id="SwitchConsoleLink" href="javascript:SwitchConsole();" class="right">Use old console</a>
<div id="KuduExecConsoleV2" class="left-aligned"></div>
<!-- tranfered files modal -->
<div class="modal fade" id="files-transfered-modal" tabindex="-1" role="dialog" aria-labelledby="errorTitle" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header" style="border: 0">


<!-- <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="errorTitle">Session expired</h4>
-->
</div>
<div class="modal-body" data-bind="if: copyProgStats" style='overflow-y: scroll; height:400px; '>

<table class="table table-striped table-nonfluid">
<tbody data-bind="foreach: { data: Object.keys(copyProgStats()), as: 'item' }">
<tr>
<td>
<span style="font-family: Consolas, monospace; word-wrap: break-word;" data-bind="text: item"></span>
<div class="progress">
<div class="progress-bar progress-bar-info progress-bar-striped" role="progressbar"
aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width:70%" data-bind=" style : { width: $root.getCopyPercentage($parent.copyProgStats()[item]) + '%'} , css: { 'progress-bar-info' : $root.getCopyPercentage($parent.copyProgStats()[item]) < 100, 'progress-bar-success': $root.getCopyPercentage($parent.copyProgStats()[item]) >= 100 }, text: $root.getCopyPercentageDisplay($parent.copyProgStats()[item])">
0%
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer" style="border: 0">
<button type="button" class="btn btn-default" data-bind="click: clearCopyProgressCache">Clear cache</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
<div class="view edit-view" data-bind="visible: fileEdit()" style="display: none">
<div class="view edit-view" data-bind="visible: fileEdit() " style="display: none">
<div class="form-group">
<form role="form">
<p>
Expand Down Expand Up @@ -145,3 +183,4 @@
<script src="~/content/scripts/filebrowser.js"></script>
<script src="~/content/scripts/jquery-console/jquery.console.js"></script>
<script src="~/content/scripts/ace-init.js"></script>
<script src="~/content/scripts/HelperScript.js"></script>
3 changes: 2 additions & 1 deletion Kudu.Services.Web/Kudu.Services.Web.csproj
Expand Up @@ -149,6 +149,7 @@
<Content Include="Content\Images\jquery-ui-theme\ui-icons_f6cf3b_256x240.png" />
<Content Include="Content\Images\Kudu.svg" />
<Content Include="Content\Images\Windows Azure Web Site.png" />
<Content Include="Content\Scripts\HelperScript.js" />
<Content Include="Content\Scripts\jquery.contextMenu.js" />
<Content Include="Content\Scripts\KuduExec.js" />
<Content Include="Content\Scripts\ProcessExplorer.js" />
Expand Down Expand Up @@ -307,4 +308,4 @@
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
</Target>
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
</Project>
</Project>

0 comments on commit 0c14488

Please sign in to comment.