Rework the restore/clone dialogs

This commit is contained in:
Johannes Zellner
2019-07-12 17:18:21 +02:00
parent 2835d1bd87
commit 88bc30bbea
2 changed files with 177 additions and 162 deletions

View File

@@ -257,107 +257,115 @@
<!-- Modal restore app -->
<div class="modal fade" id="appRestoreModal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Backups - {{ appRestore.app.fqdn }}</h4>
</div>
<div class="modal-body" style="padding: 0 15px">
<p class="text-center" ng-show="appRestore.busyFetching"><i class="fa fa-circle-notch fa-spin"></i> Fetching backups</p>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
Backups - {{ appRestore.app.fqdn }}
<button type="button" class="btn btn-primary pull-right" ng-click="appRestore.createBackup()" ng-hide="appRestore.busyFetching" ng-disabled="appRestore.app.installationState === 'pending_backup'"><i class="fa fa-circle-notch fa-spin" ng-show="appRestore.app.installationState === 'pending_backup'"></i> Create Backup</button>
</h4>
</div>
<div class="modal-body" style="padding: 0 15px">
<p class="text-center" ng-show="appRestore.busyFetching"><i class="fa fa-circle-notch fa-spin"></i> Fetching backups</p>
<p ng-hide="appRestore.backups.length">This app has no backups yet.</p>
<button type="button" class="btn btn-primary pull-right" ng-click="appRestore.createBackup()" ng-hide="appRestore.busyFetching" ng-disabled="appRestore.app.installationState === 'pending_backup'"><i class="fa fa-circle-notch fa-spin" ng-show="appRestore.app.installationState === 'pending_backup'"></i> Create Backup</button>
<!-- backup id copy helper -->
<input type="text" class="offscreen" aria-hidden="true" id="appRestoreBackupIdHelper" value="">
<uib-tabset active="appRestore.action" ng-show="!appRestore.busyFetching">
<!-- restore -->
<uib-tab index="'restore'" heading="Restore">
<br/>
<p class="text-danger" ng-hide="appRestore.backups.length">This app has no backups to restore or clone from yet.</p>
<div ng-show="appRestore.backups.length">
<p>Restoring the app will lose all it's data since the backup.</p>
<label class="control-label">Select Backup</label>
<div class="dropdown">
<button type="button" class="btn btn-default" data-toggle="dropdown">{{ appRestore.selectedBackup.creationTime | prettyDate }} - v{{appRestore.selectedBackup.version}} ({{ appRestore.selectedBackup.creationTime | prettyLongDate }}) <span class="caret"></span></button>
<ul class="dropdown-menu" role="menu">
<li ng-repeat="backup in appRestore.backups | orderBy:'-creationTime'">
<a href="" ng-click="appRestore.selectBackup(backup)">{{ backup.creationTime | prettyDate }} - v{{backup.version}} ({{ backup.creationTime | prettyLongDate }})</a>
</li>
</ul>
<input type="text" class="offscreen" aria-hidden="true" id="appRestoreSelectedBackupId" value="{{appRestore.selectedBackup.id}}">
<i style="margin-left: 10px;" class="fa fa-copy hand" uib-tooltip="{{ appRestore.copyBackupIdDone ? 'Copied to clipboard' : 'Click to copy backup id' }}" tooltip-placement="right" ng-click="appRestore.copyBackupId()"></i>
</div>
<br/>
</div>
</uib-tab>
<table class="table table-hover" style="margin: 0;" ng-show="appRestore.backups.length">
<thead>
<tr>
<th width="25px">&nbsp;</th>
<th>Created</th>
<th>Version</th>
<th class="text-right" width="180px">Actions</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="backup in appRestore.backups">
<td><div ng-click="appRestore.copyBackupId(backup)" class="hand" uib-tooltip="{{ appRestore.copyBackupIdDone ? 'Copied to clipboard' : 'Click to copy backup id' }}" tooltip-placement="right"><i class="fa fa-copy"></i></div></td>
<td>{{ backup.creationTime | prettyDate }}</td>
<td>v{{ backup.version }}</td>
<td class="text-right no-wrap" style="vertical-align: bottom">
<button class="btn btn-xs btn-default" ng-hide="backup.ackRestore" ng-click="appClone.show(appRestore.app, backup)" uib-tooltip="Clone from this Backup"><i class="far fa-clone"></i></button>
<button class="btn btn-xs btn-danger" ng-hide="backup.ackRestore" ng-click="backup.ackRestore = true" uib-tooltip="Restore to this Backup"><i class="fas fa-history"></i></button>
<button class="btn btn-xs btn-danger" ng-show="backup.ackRestore" ng-click="appRestore.restore(backup)">Yes restore now</button>
<button class="btn btn-xs btn-default" ng-show="backup.ackRestore" ng-click="backup.ackRestore = false">Back</button>
</td>
</tr>
</tbody>
</table>
<br/>
</div>
<!-- clone -->
<uib-tab index="'clone'" heading="Clone">
<br/>
<p class="text-danger" ng-hide="appRestore.backups.length">This app has no backups to restore or clone from yet.</p>
<div ng-show="appRestore.backups.length">
<label class="control-label">Select Backup</label>
<div class="dropdown">
<button type="button" class="btn btn-default" data-toggle="dropdown">{{ appRestore.selectedBackup.creationTime | prettyDate }} - v{{appRestore.selectedBackup.version}} ({{ appRestore.selectedBackup.creationTime | prettyLongDate }}) <span class="caret"></span></button>
<ul class="dropdown-menu" role="menu">
<li ng-repeat="backup in appRestore.backups | orderBy:'-creationTime'">
<a href="" ng-click="appRestore.selectBackup(backup)">{{ backup.creationTime | prettyDate }} - v{{backup.version}} ({{ backup.creationTime | prettyLongDate }})</a>
</li>
</ul>
</div>
<br/>
<fieldset>
<form role="form" ng-submit="appRestore.clone()" autocomplete="off">
<div class="form-group" ng-class="{ 'has-error': appRestore.error.location }">
<label class="control-label" for="appRestoreLocationInput">Location</label>
<div ng-show="appRestore.error.location"><small>{{ appRestore.error.location }}</small></div>
<div class="input-group form-inline">
<input type="text" class="form-control" ng-model="appRestore.location" id="appRestoreLocationInput" name="location" placeholder="Leave empty to use bare domain" autofocus>
<div class="input-group-btn">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span>{{ (!appRestore.location ? '' : (appRestore.domain.config.hyphenatedSubdomains ? '-' : '.')) + appRestore.domain.domain }}</span>
<span class="caret"></span>
</button>
<ul class="dropdown-menu dropdown-menu-right" role="menu">
<li ng-repeat="domain in domains">
<a href="" ng-click="appRestore.domain = domain">{{ domain.domain }}</a>
</li>
</ul>
</div>
</div>
</div>
<p class="text-center" ng-show="appRestore.location && appRestore.domain.provider === 'manual'">
<b>Add an A record manually for {{ appRestore.location }} to this Cloudron's public IP</b>
<br>
</p>
<div class="has-error text-center" ng-show="appRestore.error.port">{{ appRestore.error.port }}</div>
<div ng-repeat="(env, info) in appRestore.portBindingsInfo">
<ng-form name="portInfo_form">
<div class="form-group" ng-class="{ 'has-error': (!appRestore.itemName{{$index}}.$dirty && appRestore.error.port) || (portInfo_form.itemName{{$index}}.$dirty && portInfo_form.itemName{{$index}}.$invalid) }">
<label class="control-label" for="inputPortInfo{{env}}"><input type="checkbox" ng-model="appRestore.portBindingsEnabled[env]">
{{ info.title }}
<sup>
<a popover-placement="top-right" popover-trigger="outsideClick" uib-popover="{{info.description}} ({{ HOST_PORT_MIN }} - {{ HOST_PORT_MAX }})"><i class="fa fa-question-circle"></i></a>
</sup>
</label>
<input type="number" class="form-control" ng-model="appRestore.portBindings[env]" ng-disabled="!appRestore.portBindingsEnabled[env]" id="inputPortInfo{{env}}" later-name="itemName{{$index}}" min="{{hostPortMin}}" max="{{hostPortMax}}" required>
</div>
</ng-form>
</div>
</form>
</fieldset>
</div>
</uib-tab>
</uib-tabset>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-success" ng-click="appRestore.clone()" ng-show="appRestore.action === 'clone' && appRestore.backups.length !== 0" ng-disabled="appRestore.busy || !appRestore.selectedBackup"><i class="fa fa-circle-notch fa-spin" ng-show="appRestore.busy"></i> Clone</button>
<button type="button" class="btn btn-danger" ng-click="appRestore.restore()" ng-show="appRestore.action === 'restore' && appRestore.backups.length !== 0" ng-disabled="appRestore.busy || !appRestore.selectedBackup"><i class="fa fa-circle-notch fa-spin" ng-show="appRestore.busy"></i> Restore</button>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- Modal clone app -->
<div class="modal fade" id="appCloneModal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
Clone - {{ appClone.app.fqdn }}
</h4>
</div>
<div class="modal-body" style="padding: 0 15px">
<p>Using backup from <b>{{ appClone.backup.creationTime | prettyDate }}</b> and version <b>v{{ appClone.backup.version }}</b></p>
<fieldset>
<form role="form" ng-submit="appClone.submit()" autocomplete="off">
<div class="form-group" ng-class="{ 'has-error': appClone.error.location }">
<label class="control-label" for="appCloneLocationInput">Location</label>
<div ng-show="appClone.error.location"><small>{{ appClone.error.location }}</small></div>
<div class="input-group form-inline">
<input type="text" class="form-control" ng-model="appClone.location" id="appCloneLocationInput" name="location" placeholder="Leave empty to use bare domain" autofocus>
<div class="input-group-btn">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span>{{ (!appClone.location ? '' : (appClone.domain.config.hyphenatedSubdomains ? '-' : '.')) + appClone.domain.domain }}</span>
<span class="caret"></span>
</button>
<ul class="dropdown-menu dropdown-menu-right" role="menu">
<li ng-repeat="domain in domains">
<a href="" ng-click="appClone.domain = domain">{{ domain.domain }}</a>
</li>
</ul>
</div>
</div>
</div>
<p class="text-center" ng-show="appClone.location && appClone.domain.provider === 'manual'">
<b>Add an A record manually for {{ appClone.location }} to this Cloudron's public IP</b>
<br>
</p>
<div class="has-error text-center" ng-show="appClone.error.port">{{ appClone.error.port }}</div>
<div ng-repeat="(env, info) in appClone.portBindingsInfo">
<ng-form name="portInfo_form">
<div class="form-group" ng-class="{ 'has-error': (!appClone.itemName{{$index}}.$dirty && appClone.error.port) || (portInfo_form.itemName{{$index}}.$dirty && portInfo_form.itemName{{$index}}.$invalid) }">
<label class="control-label" for="inputPortInfo{{env}}"><input type="checkbox" ng-model="appClone.portBindingsEnabled[env]">
{{ info.title }}
<sup>
<a popover-placement="top-right" popover-trigger="outsideClick" uib-popover="{{info.description}} ({{ HOST_PORT_MIN }} - {{ HOST_PORT_MAX }})"><i class="fa fa-question-circle"></i></a>
</sup>
</label>
<input type="number" class="form-control" ng-model="appClone.portBindings[env]" ng-disabled="!appClone.portBindingsEnabled[env]" id="inputPortInfo{{env}}" later-name="itemName{{$index}}" min="{{hostPortMin}}" max="{{hostPortMax}}" required>
</div>
</ng-form>
</div>
</form>
</fieldset>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-success" ng-click="appClone.submit()"><i class="far fa-clone"></i> Clone</button>
</div>
</div>
</div>
</div>
<!-- Modal information of app -->