2020-07-08 17:30:37 +02:00
<!DOCTYPE html>
< html ng-app = "Application" ng-controller = "FileManagerController" >
< head >
< meta charset = "utf-8" / >
< meta name = "viewport" content = "user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height" / >
< title > FileManager < / title >
< link id = "favicon" href = "/api/v1/cloudron/avatar" rel = "icon" type = "image/png" >
< link rel = "apple-touch-icon" href = "/api/v1/cloudron/avatar" >
< link rel = "icon" href = "/api/v1/cloudron/avatar" >
<!-- CSS -->
< link type = "text/css" rel = "stylesheet" href = "/3rdparty/angular-ui-notification.css" / >
< link type = "text/css" rel = "stylesheet" href = "/theme.css" >
<!-- Custom Fonts -->
< link type = "text/css" rel = "stylesheet" href = "/3rdparty/fontawesome/css/all.min.css" >
<!-- jQuery -->
< script type = "text/javascript" src = "/3rdparty/js/jquery.min.js" > < / script >
<!-- async -->
< script type = "text/javascript" src = "/3rdparty/js/async-3.2.0.min.js" > < / script >
2020-07-10 15:27:44 +02:00
<!-- Showdown (markdown converter) -->
< script type = "text/javascript" src = "/3rdparty/js/showdown-1.6.4.min.js?<%= revision %>" > < / script >
< script type = "text/javascript" src = "/3rdparty/js/showdown-target-blank.min.js?<%= revision %>" > < / script >
2020-07-08 17:30:37 +02:00
<!-- Bootstrap Core JavaScript -->
< script type = "text/javascript" src = "/3rdparty/js/bootstrap.min.js" > < / script >
<!-- Angularjs scripts -->
< script type = "text/javascript" src = "/3rdparty/js/angular.min.js" > < / script >
< script type = "text/javascript" src = "/3rdparty/js/angular-loader.min.js" > < / script >
< script type = "text/javascript" src = "/3rdparty/js/angular-animate.min.js" > < / script >
< script type = "text/javascript" src = "/3rdparty/js/angular-base64.min.js" > < / script >
< script type = "text/javascript" src = "/3rdparty/js/angular-md5.min.js" > < / script >
< script type = "text/javascript" src = "/3rdparty/js/angular-sanitize.min.js" > < / script >
< script type = "text/javascript" src = "/3rdparty/js/angular-ui-notification.js" > < / script >
<!-- Angular directives for bootstrap https://angular - ui.github.io/bootstrap/ -->
< script type = "text/javascript" src = "/3rdparty/js/ui-bootstrap-tpls-1.3.3.min.js" > < / script >
<!-- colors -->
< script type = "text/javascript" src = "/3rdparty/js/colors.js" > < / script >
<!-- moment -->
< script type = "text/javascript" src = "/3rdparty/js/moment.min.js" > < / script >
2020-07-21 16:27:51 +02:00
<!-- https://github.com/data - uri/mimer -->
< script type = "text/javascript" src = "/3rdparty/js/mimer.min.js" > < / script >
2020-07-13 23:35:49 +02:00
2020-07-14 23:49:14 +02:00
<!-- ui.bootstrap.contextMenu -->
< script type = "text/javascript" src = "/3rdparty/js/contextMenu.js" > < / script >
2020-07-21 16:27:51 +02:00
<!-- WARNING this adds an AMD loader! Make sure script tag includes like mimer are above -->
<!-- monaco - editor -->
< script type = "text/javascript" src = "/3rdparty/vs/loader.js" > < / script >
2020-07-08 17:30:37 +02:00
<!-- Main Application -->
< script type = "text/javascript" src = "/js/filemanager.js" > < / script >
< / head >
2020-07-14 15:32:31 +02:00
< body class = "filemanager" ng-drop = "drop($event)" ng-dragover = "dragEnter($event)" ng-dragleave = "dragExit($event)" >
2020-07-08 17:30:37 +02:00
< a class = "offline-banner animateMe" ng-show = "client.offline" ng-cloak href = "https://cloudron.io/documentation/troubleshooting/" target = "_blank" > < i class = "fa fa-circle-notch fa-spin" > < / i > Cloudron is offline. Reconnecting...< / a >
2020-07-13 23:35:49 +02:00
<!-- Modal text editor -->
< div class = "modal fade" id = "textEditorModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" style = "width: 90%; max-width: 1280px;" >
< div class = "modal-content" >
< div class = "modal-header" >
< h4 class = "modal-title" >
Edit < b > {{ textEditor.entry.fileName }}< / b >
< button type = "button" class = "btn btn-success pull-right" ng-click = "textEditor.submit()" ng-disabled = "textEditor.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "textEditor.busy" > < / i > Save< / button >
< button type = "button" class = "btn btn-default pull-right" data-dismiss = "modal" > Cancel< / button >
< / h4 >
< / div >
< div class = "modal-body" style = "padding-top: 0;" >
< div id = "textEditorContainer" style = "width: 100%; height: 600px; border: 0px solid black" > < / div >
< / div >
< / div >
< / div >
< / div >
2020-07-21 16:27:51 +02:00
<!-- Modal image/video viewer -->
< div class = "modal fade" id = "mediaViewerModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" style = "width: calc(100% - 60px); max-width: 1280px; height: 800px; max-height: calc(100% - 60px);" >
< div class = "modal-content" style = "height: 100%; height: 100%; display: flex; background-color: #000; background-clip: border-box;" >
< img ng-show = "mediaViewer.type === 'image'" ng-src = "{{ mediaViewer.src }}" style = "display: block; margin: auto;" / >
< video ng-show = "mediaViewer.type === 'video'" controls preload = "auto" autoplay ng-src = "{{ mediaViewer.src | trustUrl}}" > < / video >
< / div >
< / div >
< / div >
2020-07-09 11:00:11 +02:00
<!-- Modal remove entry -->
< div class = "modal fade" id = "entryRemoveModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-body" >
< p class = "text-bold text-danger" ng-show = "entryRemove.error" > {{ entryRemove.error }}< / p >
2020-07-10 15:11:09 +02:00
< h4 ng-hide = "entryRemove.error" > Really delete {{ entryRemove.entry.fileName }}?< / h4 >
2020-07-09 11:00:11 +02:00
< / div >
< div class = "modal-footer" >
2020-07-10 15:11:09 +02:00
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > No< / button >
< button type = "button" class = "btn btn-danger" ng-click = "entryRemove.submit()" ng-hide = "entryRemove.error" ng-disabled = "entryRemove.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "entryRemove.busy" > < / i > Yes< / button >
2020-07-09 11:00:11 +02:00
< / div >
< / div >
< / div >
< / div >
2020-07-09 12:05:14 +02:00
<!-- Modal new directory -->
< div class = "modal fade" id = "newDirectoryModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
2020-07-10 15:11:09 +02:00
< h4 class = "modal-title" > New Folder< / h4 >
2020-07-09 12:05:14 +02:00
< / div >
< div class = "modal-body" >
< form role = "form" name = "newDirectoryForm" ng-submit = "newDirectory.submit()" autocomplete = "off" >
< fieldset >
2020-07-10 15:11:09 +02:00
< div class = "form-group" ng-class = "{ 'has-error': newDirectory.error || (newDirectoryForm.directoryName.$dirty && newDirectoryForm.directoryName.$invalid) }" >
< input type = "text" class = "form-control" id = "inputDirectoryName" name = "directoryName" ng-model = "newDirectory.name" required autofocus >
2020-07-09 12:05:14 +02:00
< div class = "control-label" ng-show = "newDirectory.error" > {{ newDirectory.error }}< / div >
< / div >
< input class = "ng-hide" type = "submit" ng-disabled = "newDirectoryForm.$invalid || newDirectory.busy" / >
< / fieldset >
< / form >
< / div >
< div class = "modal-footer" >
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > Close< / button >
2020-07-10 15:11:09 +02:00
< button type = "button" class = "btn btn-danger" ng-click = "newDirectory.submit()" ng-disabled = "newDirectory.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "newDirectory.busy" > < / i > Create< / button >
2020-07-09 12:05:14 +02:00
< / div >
< / div >
< / div >
< / div >
2020-07-09 12:59:29 +02:00
<!-- Modal rename entry -->
< div class = "modal fade" id = "renameEntryModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
2020-07-09 16:26:23 +02:00
< h4 class = "modal-title" > Rename {{ renameEntry.entry.fileName }}< / h4 >
2020-07-09 12:59:29 +02:00
< / div >
< div class = "modal-body" >
< form role = "form" name = "renameEntryForm" ng-submit = "renameEntry.submit()" autocomplete = "off" >
< fieldset >
< div class = "form-group" ng-class = "{ 'has-error': (renameEntryForm.newName.$dirty && renameEntryForm.newName.$invalid) }" >
< label class = "control-label" > New Name< / label >
< div class = "control-label" ng-show = "renameEntry.error" > {{ renameEntry.error }}< / div >
2020-07-13 17:05:01 +02:00
< input type = "text" class = "form-control" id = "inputNewName" name = "newName" ng-model = "renameEntry.newName" required autofocus >
2020-07-09 12:59:29 +02:00
< / div >
< input class = "ng-hide" type = "submit" ng-disabled = "renameEntryForm.$invalid || renameEntry.busy" / >
< / fieldset >
< / form >
< / div >
< div class = "modal-footer" >
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > Close< / button >
< button type = "button" class = "btn btn-danger" ng-click = "renameEntry.submit()" ng-hide = "renameEntry.error" ng-disabled = "renameEntry.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "renameEntry.busy" > < / i > Rename< / button >
< / div >
< / div >
< / div >
< / div >
2020-07-13 18:30:29 +02:00
<!-- Modal chown entry -->
< div class = "modal fade" id = "chownEntryModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
< h4 class = "modal-title" > Change ownership for {{ chownEntry.entry.fileName }}< / h4 >
< / div >
< div class = "modal-body" >
< form role = "form" name = "chownEntryForm" ng-submit = "chownEntry.submit()" autocomplete = "off" >
< fieldset >
< div class = "form-group" ng-class = "{ 'has-error': (chownEntryForm.newOwner.$dirty && chownEntry.error) }" >
< label class = "control-label" > New Owner< / label >
< div class = "control-label" for = "inputNewOwner" ng-show = "chownEntry.error" > {{ chownEntry.error }}< / div >
< select class = "form-control" id = "inputNewOwner" name = "newOwner" ng-model = "chownEntry.newOwner" ng-options = "a.value as a.name for a in owners" ng-disabled = "chownEntry.busy" > < / select >
< / div >
< div class = "form-group" ng-show = "chownEntry.entry.isDirectory" >
< input type = "checkbox" id = "inputNewOwnerRecursive" ng-model = "chownEntry.recursive" >
< label class = "control-label" for = "inputNewOwnerRecursive" > Change ownership recursively< / label >
< / div >
< input class = "ng-hide" type = "submit" ng-disabled = "chownEntryForm.$invalid || chownEntry.busy" / >
< / fieldset >
< / form >
< / div >
< div class = "modal-footer" >
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > Close< / button >
< button type = "button" class = "btn btn-danger" ng-click = "chownEntry.submit()" ng-hide = "chownEntry.error" ng-disabled = "chownEntry.busy" > < i class = "fa fa-circle-notch fa-spin" ng-show = "chownEntry.busy" > < / i > Change Owner< / button >
< / div >
< / div >
< / div >
< / div >
2020-07-10 19:10:29 +02:00
<!-- Modal upload -->
< div class = "modal fade" id = "uploadModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
< h4 class = "modal-title" > Uploading files ({{ uploadStatus.countDone }}/{{ uploadStatus.count }})< / h4 >
< / div >
< div class = "modal-body" >
< div class = "progress progress-striped active" >
< div class = "progress-bar progress-bar-success" role = "progressbar" style = "width: {{ uploadStatus.percentDone || 0 }}%" > < / div >
< / div >
< p class = "no-wrap" > {{ uploadStatus.fileName }}< / p >
< / div >
< div class = "modal-footer" style = "text-align: left;" >
< small > Do not refresh the page until upload has finished.< / small >
< / div >
< / div >
< / div >
< / div >
2020-07-10 15:27:44 +02:00
< div class = "main-container animateMe ng-hide layout-root" ng-show = "initialized" >
< div class = "layout-content container" >
2020-07-10 16:10:49 +02:00
< div class = "row" ng-hide = "app" >
< div class = "col-md-12 text-center" >
< h3 > App not found< / h3 >
< / div >
< / div >
2020-07-08 17:30:37 +02:00
2020-07-14 14:03:40 +02:00
< div class = "card card-large" ng-show = "app" >
2020-07-09 15:59:06 +02:00
2020-07-14 14:03:40 +02:00
< input type = "file" id = "uploadFileInput" style = "display: none" multiple / >
< input type = "file" id = "uploadFolderInput" style = "display: none" multiple webkitdirectory directory / >
2020-07-10 15:01:56 +02:00
2020-07-14 14:03:40 +02:00
< h4 class = "text-center" > {{ app.fqdn }}< / h4 >
2020-07-10 15:27:44 +02:00
2020-07-14 14:03:40 +02:00
< div style = "margin-bottom: 10px;" >
< div class = "btn-group" role = "group" >
< button class = "btn btn-primary" ng-click = "goDirectoryUp()" ng-disabled = "cwd === '/'" > < i class = "fas fa-arrow-left" > < / i > < / button >
< button class = "btn btn-primary" ng-click = "refresh()" > < i class = "fas fa-sync-alt" > < / i > < / button >
2020-07-10 15:27:44 +02:00
< / div >
2020-07-14 14:03:40 +02:00
< div class = "btn-group" role = "group" >
< button class = "btn btn-default" ng-disabled = "cwd === '/'" ng-click = "changeDirectory('/')" > < i class = "fas fa-home" > < / i > / < / button >
< button class = "btn btn-default" ng-disabled = "part.path === cwd" ng-click = "changeDirectory(part.path)" ng-repeat = "part in cwdParts" > {{ part.name }}< / button >
< / div >
< div class = "btn-group pull-right" role = "group" >
< button class = "btn btn-primary" ng-click = "newDirectory.show()" > New Folder< / button >
< button class = "btn btn-primary" ng-click = "onUploadFile()" > Upload File< / button >
< button class = "btn btn-primary" ng-click = "onUploadFolder()" > Upload Folder< / button >
< / div >
< / div >
2020-07-15 14:48:29 +02:00
< div class = "file-list" ng-class = "{ 'entry-hovered': dropToBody, 'busy': busy }" >
2020-07-14 15:28:08 +02:00
< table class = "table table-hover" style = "margin: 0;" >
2020-07-14 14:03:40 +02:00
< thead >
< tr >
< th style = "width: 3%;" > < / th >
2020-07-14 23:49:14 +02:00
< th style = "width:77%" > Name< / th >
2020-07-14 14:03:40 +02:00
< th style = "width:10%" > Size< / th >
< th style = "width:10%" > Owner< / th >
< / tr >
< / thead >
< tbody >
< tr ng-show = "entries.length === 0" >
< td colspan = "5" class = "text-center" > No files< / td >
< / tr >
2020-07-14 23:49:14 +02:00
< tr ng-repeat = "entry in entries" ng-drop = "drop($event, entry)" context-menu = "menuOptions" model = "entry" ng-dragleave = "dragExit($event, entry)" ng-dragover = "dragEnter($event, entry)" ng-class = "{ 'entry-hovered': entry.hovered }" >
2020-07-18 18:21:23 +02:00
< td ng-click = "open(entry)" ng-class = "{ 'hand': !entry.isSymbolicLink }" class = "text-center" >
2020-07-14 14:03:40 +02:00
< i class = "fas fa-folder fa-lg" ng-show = "entry.isDirectory" > < / i >
< i class = "far fa-file fa-lg" ng-show = "entry.isFile" > < / i >
2020-07-18 18:21:23 +02:00
< i class = "fas fa-link fa-lg" ng-show = "entry.isSymbolicLink" > < / i >
2020-07-14 14:03:40 +02:00
< / td >
2020-07-18 18:21:23 +02:00
< td ng-class = "{ 'hand': !entry.isSymbolicLink }" class = "elide-table-cell" ng-click = "open(entry)" > {{ entry.fileName }}< span ng-show = "entry.isSymbolicLink" class = "text-muted" style = "margin-left: 20px;" > symlink to {{ entry.target }}< / span > < / td >
< td ng-class = "{ 'hand': !entry.isSymbolicLink }" class = "elide-table-cell" ng-click = "open(entry)" > {{ entry.size | prettyByteSize }}< / td >
< td ng-class = "{ 'hand': !entry.isSymbolicLink }" class = "elide-table-cell" ng-click = "open(entry)" > {{ entry.uid | prettyOwner }}< / td >
2020-07-14 14:03:40 +02:00
< / tr >
< / tbody >
< / table >
2020-07-08 17:30:37 +02:00
< / div >
< / div >
< / div >
2020-07-10 15:27:44 +02:00
< footer class = "text-center ng-cloak" >
< span class = "text-muted" ng-bind-html = "status.footer | markdown2html" > < / span >
< span class = "version" > v{{status.version}}< / span >
< / footer >
2020-07-08 17:30:37 +02:00
< / div >
< / body >
< / html >