Files
cloudron-box/src/filemanager.html

289 lines
15 KiB
HTML
Raw Normal View History

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>
<!-- 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
<!-- ui.bootstrap.contextMenu -->
<script type="text/javascript" src="/3rdparty/js/contextMenu.js"></script>
<!-- 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>
<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>
<!-- 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>
<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">
<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>
<div class="file-list" ng-class="{ 'entry-hovered': dropToBody, 'busy': busy }">
<table class="table table-hover" style="margin: 0;">
2020-07-14 14:03:40 +02:00
<thead>
<tr>
<th style="width: 3%;">&nbsp;</th>
<th style="width:82%">Name</th>
2020-07-14 14:03:40 +02:00
<th style="width:10%">Size</th>
<th style="width:10%">Owner</th>
<th style="width: 5%">&nbsp;</th>
2020-07-14 14:03:40 +02:00
</tr>
</thead>
<tbody>
<tr ng-show="entries.length === 0">
<td colspan="5" class="text-center">No files</td>
</tr>
2020-07-23 15:01:50 +02:00
<tr ng-repeat="entry in entries | orderBy:sortProperty:sortAsc | orderBy:'isDirectory':true" 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 }">
<td ng-click="open(entry)" ng-class="{ 'hand': !entry.isSymbolicLink }" class="text-center">
<i class="fas fa-lg {{ entry.icon }}" ng-class="{ 'text-primary': entry.isDirectory }"></i>
</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>
<td class="text-right no-wrap" style="vertical-align: bottom">
<button class="btn btn-xs btn-link" context-menu="menuOptions" model="entry" context-menu-on="click"><i class="fas fa-bars"></i></button>
</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>