2018-01-22 13:01:38 -08:00
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html ng-app="Application" ng-controller="TerminalController">
|
|
|
|
|
<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" />
|
|
|
|
|
|
|
|
|
|
<!-- this gets changed once we get the config (because angular has not loaded yet, we see template string for a flash) -->
|
|
|
|
|
<title> Terminal </title>
|
|
|
|
|
|
|
|
|
|
<link id="favicon" href="/api/v1/cloudron/avatar" rel="icon" type="image/png">
|
2018-07-30 22:05:20 +02:00
|
|
|
<link rel="apple-touch-icon" href="/api/v1/cloudron/avatar">
|
|
|
|
|
<link rel="icon" href="/api/v1/cloudron/avatar">
|
2018-01-22 13:01:38 -08:00
|
|
|
|
|
|
|
|
<!-- CSS -->
|
2019-01-07 17:23:26 +01:00
|
|
|
<link type="text/css" rel="stylesheet" href="/3rdparty/angular-ui-notification.css"/>
|
2018-04-10 14:49:49 +02:00
|
|
|
<link type="text/css" rel="stylesheet" href="/3rdparty/xterm/xterm.css">
|
|
|
|
|
<link type="text/css" rel="stylesheet" href="/theme.css">
|
2018-01-22 13:01:38 -08:00
|
|
|
|
|
|
|
|
<!-- Custom Fonts -->
|
2018-11-15 17:42:29 +01:00
|
|
|
<link type="text/css" rel="stylesheet" href="/3rdparty/fontawesome/css/all.min.css">
|
2018-01-22 13:01:38 -08:00
|
|
|
|
|
|
|
|
<!-- jQuery-->
|
2018-04-10 14:49:49 +02:00
|
|
|
<script type="text/javascript" src="/3rdparty/js/jquery.min.js"></script>
|
2018-01-22 13:01:38 -08:00
|
|
|
|
|
|
|
|
<!-- Bootstrap Core JavaScript -->
|
2018-04-10 14:49:49 +02:00
|
|
|
<script type="text/javascript" src="/3rdparty/js/bootstrap.min.js"></script>
|
2018-01-22 13:01:38 -08:00
|
|
|
|
|
|
|
|
<!-- Angularjs scripts -->
|
2018-04-10 14:49:49 +02:00
|
|
|
<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>
|
2019-01-07 17:23:26 +01:00
|
|
|
<script type="text/javascript" src="/3rdparty/js/angular-ui-notification.js"></script>
|
2018-01-22 13:01:38 -08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Angular directives for bootstrap https://angular-ui.github.io/bootstrap/ -->
|
2018-04-10 14:49:49 +02:00
|
|
|
<script type="text/javascript" src="/3rdparty/js/ui-bootstrap-tpls-1.3.3.min.js"></script>
|
2018-01-22 13:01:38 -08:00
|
|
|
|
|
|
|
|
<!-- Clipboard handling -->
|
2018-04-10 14:49:49 +02:00
|
|
|
<script type="text/javascript" src="/3rdparty/js/clipboard.min.js"></script>
|
2018-01-22 13:01:38 -08:00
|
|
|
|
|
|
|
|
<!-- xterm -->
|
2018-04-10 14:49:49 +02:00
|
|
|
<script type="text/javascript" src="/3rdparty/xterm/xterm.js"></script>
|
|
|
|
|
<script type="text/javascript" src="/3rdparty/xterm/addons/attach/attach.js"></script>
|
|
|
|
|
<script type="text/javascript" src="/3rdparty/xterm/addons/fit/fit.js"></script>
|
2018-01-22 13:01:38 -08:00
|
|
|
|
|
|
|
|
<!-- Main Application -->
|
2018-04-10 14:49:49 +02:00
|
|
|
<script type="text/javascript" src="/js/terminal.js"></script>
|
2018-01-22 13:01:38 -08:00
|
|
|
|
|
|
|
|
</head>
|
|
|
|
|
|
2018-05-15 18:31:52 +02:00
|
|
|
<body style="overflow: hidden;">
|
2018-01-22 13:01:38 -08:00
|
|
|
|
|
|
|
|
<!-- Modal download file -->
|
|
|
|
|
<div class="modal fade" id="downloadFileModal" tabindex="-1" role="dialog">
|
|
|
|
|
<div class="modal-dialog">
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
<div class="modal-header">
|
|
|
|
|
<h4 class="modal-title">Download from {{ selected.name }}</h4>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
<form name="downloadFileForm" ng-submit="downloadFile.submit()">
|
|
|
|
|
<div class="form-group" ng-class="{ 'has-error': downloadFileForm.filePath.$dirty && downloadFile.error }">
|
|
|
|
|
<label class="control-label" for="inputDownloadFilePath">Path to file or directory</label>
|
|
|
|
|
<div class="control-label" ng-show="{ 'has-error': downloadFileForm.filePath.$dirty && downloadFile.error }">
|
|
|
|
|
<small>{{ downloadFile.error }}</small>
|
|
|
|
|
</div>
|
|
|
|
|
<input type="text" class="form-control" name="filePath" ng-model="downloadFile.filePath" required autofocus>
|
|
|
|
|
</div>
|
|
|
|
|
<input id="inputDownloadFilePath" class="ng-hide" type="submit" ng-disabled="!downloadFile.filePath"/>
|
|
|
|
|
</form>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-footer">
|
|
|
|
|
<a id="fileDownloadLink" class="" ng-href="{{ downloadFile.downloadUrl() }}" target="_blank"></a>
|
|
|
|
|
|
|
|
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
2018-11-16 17:03:21 +01:00
|
|
|
<button type="button" class="btn btn-success" ng-click="downloadFile.submit()" ng-disabled="!downloadFile.filePath"><i class="fa fa-circle-notch fa-spin" ng-show="downloadFile.busy"></i> Download</button>
|
2018-01-22 13:01:38 -08:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Modal upload progress -->
|
|
|
|
|
<div class="modal fade" id="uploadProgressModal" tabindex="-1" role="dialog">
|
|
|
|
|
<div class="modal-dialog">
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
<div class="modal-header">
|
|
|
|
|
<h4 class="modal-title">Uploading file to {{ selected.name }}</h4>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
<span><b>{{ (uploadProgress.current/1000/1000).toFixed(2) }}MB</b> (total {{ (uploadProgress.total/1000/1000).toFixed(2) }}MB)</span>
|
|
|
|
|
<div class="progress progress-striped active">
|
|
|
|
|
<div class="progress-bar progress-bar-success" role="progressbar" style="width: {{ 100*(uploadProgress.current/uploadProgress.total) }}%"></div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-footer">
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2019-09-26 22:06:56 -07:00
|
|
|
<!-- Modal pause info -->
|
|
|
|
|
<div class="modal fade" id="pauseAppModal" tabindex="-1" role="dialog">
|
2018-01-22 13:01:38 -08:00
|
|
|
<div class="modal-dialog">
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
<div class="modal-header">
|
2019-09-26 22:06:56 -07:00
|
|
|
<h4 class="modal-title">Pause app {{ selected.name }} ?</h4>
|
2018-01-22 13:01:38 -08:00
|
|
|
</div>
|
|
|
|
|
<div class="modal-body">
|
2019-09-26 22:06:56 -07:00
|
|
|
<p>The app will start in a paused state and can be used to fix broken plugins or database content.</p>
|
|
|
|
|
<p class="text-danger text-bold">The app will not be reachable in paused mode.</p>
|
2018-01-22 13:01:38 -08:00
|
|
|
</div>
|
|
|
|
|
<div class="modal-footer">
|
|
|
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
2019-09-26 22:06:56 -07:00
|
|
|
<button type="button" class="btn btn-danger" ng-click="pauseAppBegin()">Pause</button>
|
2018-01-22 13:01:38 -08:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="animateMe ng-hide layout-root terminal-view" ng-show="initialized">
|
|
|
|
|
|
|
|
|
|
<div class="terminal-controls">
|
|
|
|
|
<h3 style="display: inline-block;">{{ selected.name }}</h3>
|
|
|
|
|
|
|
|
|
|
<input type="file" id="fileUpload" class="hide"/>
|
|
|
|
|
|
|
|
|
|
<div class="pull-right">
|
2018-05-11 10:40:11 +02:00
|
|
|
<div class="btn-group" ng-show="usesAddon('scheduler')">
|
2019-09-27 19:13:01 +02:00
|
|
|
<button type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" ng-disabled="appBusy">
|
2018-05-11 10:40:11 +02:00
|
|
|
Scheduler/Cron <span class="caret"></span>
|
|
|
|
|
</button>
|
|
|
|
|
<ul class="dropdown-menu">
|
|
|
|
|
<li ng-repeat="task in schedulerTasks"><a href="" ng-click="terminalInject('scheduler', task)">{{ task.name }}</a></li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
|
2018-01-22 13:01:38 -08:00
|
|
|
<!-- addon actions -->
|
2019-09-27 19:13:01 +02:00
|
|
|
<button class="btn btn-success" ng-click="terminalInject('mysql')" ng-show="usesAddon('mysql')" ng-disabled="appBusy">MySQL</button>
|
|
|
|
|
<button class="btn btn-success" ng-click="terminalInject('postgresql')" ng-show="usesAddon('postgresql')" ng-disabled="appBusy">Postgres</button>
|
|
|
|
|
<button class="btn btn-success" ng-click="terminalInject('mongodb')" ng-show="usesAddon('mongodb')" ng-disabled="appBusy">MongoDB</button>
|
|
|
|
|
<button class="btn btn-success" ng-click="terminalInject('redis')" ng-show="usesAddon('redis')" ng-disabled="appBusy">Redis</button>
|
2018-01-22 13:01:38 -08:00
|
|
|
|
|
|
|
|
<!-- terminal actions -->
|
2019-09-27 19:13:01 +02:00
|
|
|
<button class="btn btn-primary" ng-click="restartApp()" ng-show="selected.type === 'app'" ng-disabled="appBusy"><i class="fa fa-sync-alt" ng-class="{ 'fa-spin': restartAppBusy }"></i> Restart</button>
|
|
|
|
|
<button class="btn btn-primary" ng-click="uploadFile()" ng-show="selected.type === 'app' && !uploadProgress.busy" ng-disabled="appBusy"><i class="fa fa-upload"></i> Upload to /tmp</button>
|
|
|
|
|
<button class="btn btn-primary" ng-click="uploadProgress.show()" ng-show="uploadProgress.busy" ng-disabled="appBusy"><i class="fa fa-circle-notch fa-spin"></i> Uploading...</button>
|
|
|
|
|
<button class="btn btn-primary" ng-click="downloadFile.show()" ng-show="selected.type === 'app'" ng-disabled="appBusy"><i class="fa fa-download"></i> Download</button>
|
|
|
|
|
<button class="btn btn-primary" ng-click="pauseApp()" ng-show="selected.type === 'app' && !selectedAppInfo.debugMode" ng-disabled="appBusy"><i class="fa fa-pause"></i> Pause</button>
|
|
|
|
|
<button class="btn btn-danger" ng-click="pauseAppDone()" ng-show="selectedAppInfo.debugMode" ng-disabled="appBusy"><i class="fa fa-play"></i> Resume</button>
|
2018-01-22 13:01:38 -08:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="terminal-container" id="terminalContainer" ng-hide="appBusy"></div>
|
|
|
|
|
<div class="terminal-container placeholder" ng-show="appBusy">
|
|
|
|
|
<h4>
|
2019-09-27 19:13:01 +02:00
|
|
|
<span ng-show="restartAppBusy">Restarting app...</span>
|
2019-09-26 22:06:56 -07:00
|
|
|
<span ng-show="selectedAppInfo.installationState === 'pending_debug' && selectedAppInfo.debugMode">Restarting app in paused mode...</span>
|
2019-09-27 19:13:01 +02:00
|
|
|
<span ng-show="selectedAppInfo.installationState === 'pending_debug' && !selectedAppInfo.debugMode ">App is being resumed...</span>
|
2018-01-22 13:01:38 -08:00
|
|
|
<span ng-show="selectedAppInfo.installationState === 'pending_installed'">App is being installed...</span>
|
|
|
|
|
</h4>
|
|
|
|
|
|
|
|
|
|
<div class="progress" ng-show="appBusy" style="width: 80%">
|
|
|
|
|
<div class="progress-bar progress-bar-striped active" role="progressbar" style="width: 100%"></div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="contextMenuBackdrop">
|
|
|
|
|
<ul class="dropdown-menu" id="terminalContextMenu" style="position: absolute; display:none;">
|
|
|
|
|
<li><a href="" ng-click="terminalCopy()">Copy</a></li>
|
|
|
|
|
<li class="disabled"><a>For Paste use Ctrl+v</a></li>
|
|
|
|
|
<li role="separator" class="divider"></li>
|
|
|
|
|
<li><a href="" ng-click="terminalClear()">Clear</a></li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|