389 lines
22 KiB
HTML
389 lines
22 KiB
HTML
<!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">
|
|
|
|
<!-- Fontawesome -->
|
|
<link type="text/css" rel="stylesheet" href="/3rdparty/fontawesome/css/all.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>
|
|
|
|
<!-- Showdown (markdown converter) -->
|
|
<script type="text/javascript" src="/3rdparty/js/showdown-1.9.1.min.js"></script>
|
|
|
|
<!-- 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-cookies.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>
|
|
|
|
<!-- Angular translate https://angular-translate.github.io/ -->
|
|
<script type="text/javascript" src="/3rdparty/js/angular-translate.min.js"></script>
|
|
<script type="text/javascript" src="/3rdparty/js/angular-translate-loader-static-files.min.js"></script>
|
|
<script type="text/javascript" src="/3rdparty/js/angular-translate-storage-cookie.min.js"></script>
|
|
<script type="text/javascript" src="/3rdparty/js/angular-translate-storage-local.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>
|
|
|
|
<!-- https://github.com/Templarian/ui.bootstrap.contextMenu 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>
|
|
|
|
<!-- 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)">
|
|
|
|
<a class="offline-banner animateMe" ng-show="client.offline" ng-cloak href="https://docs.cloudron.io/troubleshooting/" target="_blank"><i class="fa fa-circle-notch fa-spin"></i> {{ 'main.offline' | tr }}</a>
|
|
|
|
<!-- Modal image/video viewer -->
|
|
<div class="modal fade" id="mediaViewerModal" tabindex="-1" role="dialog">
|
|
<div class="modal-dialog" style="max-width: 1280px; 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; max-width: 100%; max-height: 100%;" />
|
|
<video ng-show="mediaViewer.type === 'video'" controls preload="auto" autoplay ng-src="{{ mediaViewer.src | trustUrl}}" style="display: block; margin: auto; max-width: 100%; max-height: 100%;"></video>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 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>
|
|
<h4 ng-hide="entryRemove.error">{{ 'filemanager.removeDialog.reallyDelete' | tr:{ fileName: entryRemove.entry.fileName } }}</h4>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'main.dialog.no' | tr }}</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> {{ 'main.dialog.yes' | tr }}</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 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">
|
|
<h4 class="modal-title">{{ 'filemanager.newDirectoryDialog.title' | tr }}</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form role="form" name="newDirectoryForm" ng-submit="newDirectory.submit()" autocomplete="off">
|
|
<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>
|
|
<div class="control-label" ng-show="newDirectory.error === 'exists'">{{ 'filemanager.newDirectory.errorAlreadyExists' | tr }}</div>
|
|
</div>
|
|
<input class="ng-hide" type="submit" ng-disabled="newDirectoryForm.$invalid || newDirectory.busy"/>
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'main.dialog.close' | tr }}</button>
|
|
<button type="button" class="btn btn-primary" ng-click="newDirectory.submit()" ng-disabled="newDirectory.busy"><i class="fa fa-circle-notch fa-spin" ng-show="newDirectory.busy"></i> {{ 'filemanager.newDirectoryDialog.create' | tr }}</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal new file -->
|
|
<div class="modal fade" id="newFileModal" tabindex="-1" role="dialog">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h4 class="modal-title">{{ 'filemanager.newFileDialog.title' | tr }}</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form role="form" name="newFileForm" ng-submit="newFile.submit()" autocomplete="off">
|
|
<div class="form-group" ng-class="{ 'has-error': newFile.error || (newFileForm.fileName.$dirty && newFileForm.fileName.$invalid) }">
|
|
<input type="text" class="form-control" id="inputFileName" name="fileName" ng-model="newFile.name" required autofocus>
|
|
<div class="control-label" ng-show="newFile.error === 'exists'">{{ 'filemanager.newFile.errorAlreadyExists' | tr }}</div>
|
|
</div>
|
|
<input class="ng-hide" type="submit" ng-disabled="newFileForm.$invalid || newFile.busy"/>
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'main.dialog.close' | tr }}</button>
|
|
<button type="button" class="btn btn-primary" ng-click="newFile.submit()" ng-disabled="newFile.busy"><i class="fa fa-circle-notch fa-spin" ng-show="newFile.busy"></i> {{ 'filemanager.newFileDialog.create' | tr }}</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 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">
|
|
<h4 class="modal-title">{{ 'filemanager.renameDialog.title' | tr:{ fileName: renameEntry.entry.fileName } }}</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form role="form" name="renameEntryForm" ng-submit="renameEntry.submit()" autocomplete="off">
|
|
<div class="form-group" ng-class="{ 'has-error': (renameEntryForm.newName.$dirty && renameEntryForm.newName.$invalid) }">
|
|
<label class="control-label">{{ 'filemanager.renameDialog.newName' | tr }}</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>
|
|
</div>
|
|
<input class="ng-hide" type="submit" ng-disabled="renameEntryForm.$invalid || renameEntry.busy"/>
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'main.dialog.close' | tr }}</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> {{ 'filemanager.renameDialog.rename' | tr }}</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 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">{{ 'filemanager.chownDialog.title' | tr:{ fileName: chownEntry.entry.fileName } }}</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form role="form" name="chownEntryForm" ng-submit="chownEntry.submit()" autocomplete="off">
|
|
<div class="form-group" ng-class="{ 'has-error': (chownEntryForm.newOwner.$dirty && chownEntry.error) }">
|
|
<label class="control-label">{{ 'filemanager.chownDialog.newOwner' | tr }}</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">{{ 'filemanager.chownDialog.recursiveCheckbox' | tr }}</label>
|
|
</div>
|
|
<input class="ng-hide" type="submit" ng-disabled="chownEntryForm.$invalid || chownEntry.busy"/>
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'main.dialog.close' | tr }}</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> {{ 'filemanager.chownDialog.change' | tr }}</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 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">{{ 'filemanager.uploadingDialog.title' | tr:{ countDone: uploadStatus.countDone, count: uploadStatus.count } }}</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div ng-show="uploadStatus.error">
|
|
<p class="text-danger" ng-show="uploadStatus.error === 'exists'">{{ 'filemanager.uploadingDialog.errorAlreadyExists' | tr }}</p>
|
|
<p class="text-danger" ng-show="uploadStatus.error === 'generic'">{{ 'filemanager.uploadingDialog.errorFailed' | tr }}</p>
|
|
</div>
|
|
<div class="progress progress-striped active" ng-hide="uploadStatus.error">
|
|
<div class="progress-bar progress-bar-success" role="progressbar" style="width: {{ uploadStatus.percentDone || 0 }}%"></div>
|
|
</div>
|
|
<p class="no-wrap" ng-hide="uploadStatus.error">{{ uploadStatus.fileName }}</p>
|
|
</div>
|
|
<div class="modal-footer" style="text-align: left;">
|
|
<small ng-hide="uploadStatus.error">{{ 'filemanager.uploadingDialog.closeWarning' | tr }}</small>
|
|
<button class="btn btn-default pull-right" ng-show="uploadStatus.error" data-dismiss="modal">{{ 'main.dialog.close' | tr }}</button>
|
|
<button class="btn btn-primary pull-right" ng-show="uploadStatus.error === 'generic'" ng-click="retryUpload(false)">{{ 'filemanager.uploadingDialog.retry' | tr }}</button>
|
|
<button class="btn btn-danger pull-right" ng-show="uploadStatus.error === 'exists'" ng-click="retryUpload(true)">{{ 'filemanager.uploadingDialog.overwrite' | tr }}</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal extract -->
|
|
<div class="modal fade" id="extractModal" tabindex="-1" role="dialog">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h4 class="modal-title">{{ 'filemanager.extractDialog.title' | tr:{ fileName: extractStatus.fileName } }}</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div ng-show="extractStatus.error">
|
|
<p class="text-danger">{{ extractStatus.error }}</p>
|
|
</div>
|
|
<div class="progress progress-striped active" ng-hide="extractStatus.error">
|
|
<div class="progress-bar" role="progressbar" style="width: 100%">
|
|
</div>
|
|
</div>
|
|
<p class="no-wrap" ng-hide="extractStatus.error">{{ extractStatus.fileName }}</p>
|
|
</div>
|
|
<div class="modal-footer" style="text-align: left;">
|
|
<small ng-hide="extractStatus.error">{{ 'filemanager.extractDialog.closeWarning' | tr }}</small>
|
|
<button class="btn btn-primary pull-right" ng-show="extractStatus.error" data-dismiss="modal">{{ 'main.dialog.close' | tr }}</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal editor close -->
|
|
<div class="modal fade" id="textEditorCloseModal" tabindex="-1" role="dialog">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h4 class="modal-title">{{ 'filemanager.textEditorCloseDialog.title' | tr }}</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p class="text-bold text-danger">{{ 'filemanager.textEditorCloseDialog.details' | tr }}</p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-default" ng-click="textEditor.close()">{{ 'filemanager.textEditorCloseDialog.dontSave' | tr }}</button>
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'main.dialog.cancel' | tr }}</button>
|
|
<button type="button" class="btn btn-success" ng-click="textEditor.saveAndClose()"><i class="fa fa-circle-notch fa-spin" ng-show="textEditor.busy"></i> {{ 'main.dialog.save' | tr }}</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="main-container animateMe ng-hide layout-root" ng-show="initialized">
|
|
<div ng-show="view === 'fileTree'" class="layout-content container">
|
|
<div class="row" ng-hide="title">
|
|
<div class="col-md-12 text-center">
|
|
<h3>{{ 'filemanager.notFound' | tr }}</h3>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card card-large" ng-show="restartAppBusy">
|
|
<h3 class="text-center">
|
|
<br/>
|
|
<i class="fa fa-circle-notch fa-spin"></i>
|
|
<br/>
|
|
<br/>
|
|
restarting {{ title }}
|
|
</h3>
|
|
</div>
|
|
|
|
<div class="card card-large" ng-show="title && !restartAppBusy">
|
|
|
|
<input type="file" id="uploadFileInput" style="display: none" multiple/>
|
|
<input type="file" id="uploadFolderInput" style="display: none" multiple webkitdirectory directory/>
|
|
|
|
<h4 class="text-center">{{ title }}</h4>
|
|
|
|
<div class="toolbar">
|
|
<div class="btn-group" role="group" style="display: block;">
|
|
<!-- TODO figure out why a line break in code between the two buttons results in a gap visually without any margin/padding set -->
|
|
<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>
|
|
</div>
|
|
<div class="btn-group path-parts" 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 style="display: block;">
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fas fa-plus"></i> {{ 'filemanager.toolbar.new' | tr }}</button>
|
|
<ul class="dropdown-menu">
|
|
<li><a class="hand" ng-click="newFile.show()">{{ 'filemanager.toolbar.newFile' | tr }}</a></li>
|
|
<li><a class="hand" ng-click="newDirectory.show()">{{ 'filemanager.toolbar.newFolder' | tr }}</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fas fa-upload"></i> {{ 'filemanager.toolbar.upload' | tr }}</button>
|
|
<ul class="dropdown-menu dropdown-menu-right">
|
|
<li><a class="hand" ng-click="onUploadFile()">{{ 'filemanager.toolbar.uploadFile' | tr }}</a></li>
|
|
<li><a class="hand" ng-click="onUploadFolder()">{{ 'filemanager.toolbar.uploadFolder' | tr }}</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="btn-group" ng-show="type === 'app'">
|
|
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fas fa-ellipsis-h"></i></button>
|
|
<ul class="dropdown-menu dropdown-menu-right">
|
|
<li><a class="hand" ng-click="onRestartApp()"><i class="fas fa-sync-alt fa-fw"></i> {{ 'filemanager.toolbar.restartApp' | tr }}</a></li>
|
|
<li><a class="hand" ng-href="{{ '/logs.html?appId=' + id }}" target="_blank"><i class="fas fa-align-left fa-fw"></i> {{ 'filemanager.toolbar.openLogs' | tr }}</a></li>
|
|
<li><a class="hand" ng-href="{{ '/terminal.html?id=' + id }}" target="_blank"><i class="fa fa-terminal fa-fw"></i> {{ 'filemanager.toolbar.openTerminal' | tr }}</a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="file-list-header">
|
|
<table class="table" style="margin: 0;">
|
|
<thead>
|
|
<tr>
|
|
<th style="width: 40px;"> </th>
|
|
<th style="">{{ 'filemanager.list.name' | tr }}</th>
|
|
<th style="width: 80px">{{ 'filemanager.list.size' | tr }}</th>
|
|
<th style="width:100px">{{ 'filemanager.list.owner' | tr }}</th>
|
|
<th style="width: 40px"> </th>
|
|
</tr>
|
|
</thead>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="file-list" ng-class="{ 'entry-hovered': dropToBody, 'busy': busy }">
|
|
<table class="table table-hover" style="margin: 0;">
|
|
<tbody>
|
|
<tr ng-show="entries.length === 0">
|
|
<td colspan="5" class="text-center">{{ 'filemanager.list.empty' | tr }}</td>
|
|
</tr>
|
|
<tr ng-repeat="entry in entries | orderBy:sortProperty:sortAsc | orderBy:'isDirectory':true" draggable="true" ng-dragstart="dragStart($event, entry)" 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 style="width: 40px" 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>
|
|
<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;">{{ 'filemanager.list.symlink' | tr:{ target: entry.target } }}</span></td>
|
|
<td style="width: 80px" ng-class="{ 'hand': !entry.isSymbolicLink }" class="elide-table-cell" ng-click="open(entry)">{{ entry.size | prettyByteSize }}</td>
|
|
<td style="width:100px" ng-class="{ 'hand': !entry.isSymbolicLink }" class="elide-table-cell" ng-click="open(entry)">{{ entry.uid | prettyOwner }}</td>
|
|
<td style="width: 40px" 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>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div ng-show="view === 'textEditor'" class="text-editor">
|
|
<div>
|
|
<div class="toolbar">
|
|
<div><span>{{ textEditor.entry.fileName }}</span></div>
|
|
<button type="button" class="btn btn-primary" ng-click="textEditor.maybeClose()">{{ 'main.dialog.close' | tr }}</button>
|
|
<button type="button" class="btn btn-success" ng-click="textEditor.save()" ng-disabled="textEditor.busy"><i class="fa fa-circle-notch fa-spin" ng-show="textEditor.busy"></i> {{ 'main.dialog.save' | tr }}</button>
|
|
</div>
|
|
</div>
|
|
<div id="textEditorContainer" style="flex-grow: 2; border: 0px solid black"></div>
|
|
</div>
|
|
|
|
<footer class="text-center ng-cloak">
|
|
<span class="text-muted" ng-bind-html="status.footer | markdown2html"></span>
|
|
</footer>
|
|
</div>
|
|
|
|
</body>
|
|
</html>
|