Implemented more user-friendly editing for advanced options in ngax
This commit is contained in:
@@ -70,12 +70,14 @@
|
||||
<script type="text/javascript" src="scripts/directives/targetFolderPicker.js"></script>
|
||||
<script type="text/javascript" src="scripts/directives/parseFilterType.js"></script>
|
||||
<script type="text/javascript" src="scripts/directives/parseSizeNumber.js"></script>
|
||||
<script type="text/javascript" src="scripts/directives/parseAdvancedOption.js"></script>
|
||||
<script type="text/javascript" src="scripts/directives/stringArrayAsText.js"></script>
|
||||
<script type="text/javascript" src="scripts/directives/waitArea.js"></script>
|
||||
<script type="text/javascript" src="scripts/directives/restoreFilePicker.js"></script>
|
||||
<script type="text/javascript" src="scripts/directives/keyboardHandlers.js"></script>
|
||||
<script type="text/javascript" src="scripts/directives/notificationArea.js"></script>
|
||||
<script type="text/javascript" src="scripts/directives/progressBar.js"></script>
|
||||
<script type="text/javascript" src="scripts/directives/advancedOptionsEditor.js"></script>
|
||||
|
||||
<script type="text/javascript" src="scripts/oem.js"></script>
|
||||
<script type="text/javascript" src="../customized/customized.js"></script>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
backupApp.controller('EditBackupController', function ($scope, $routeParams, $location, AppService, AppUtils, SystemInfo) {
|
||||
backupApp.controller('EditBackupController', function ($scope, $routeParams, $location, $timeout, AppService, AppUtils, SystemInfo) {
|
||||
|
||||
$scope.SystemInfo = SystemInfo.watch($scope);
|
||||
$scope.AppUtils = AppUtils;
|
||||
@@ -233,7 +233,7 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
|
||||
delete extopts['--exclude-files-attributes'];
|
||||
delete extopts['--no-encryption'];
|
||||
|
||||
$scope.ExtendedOptions = AppUtils.serializeAdvancedOptions(extopts);
|
||||
$scope.ExtendedOptions = AppUtils.serializeAdvancedOptionsToArray(extopts);
|
||||
|
||||
var now = new Date();
|
||||
if ($scope.Schedule != null) {
|
||||
@@ -266,6 +266,27 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
|
||||
}
|
||||
}
|
||||
|
||||
function reloadOptionsList()
|
||||
{
|
||||
if ($scope.Options == null)
|
||||
return;
|
||||
|
||||
var encmodule = $scope.Options['encryption-module'] || '';
|
||||
var compmodule = $scope.Options['compression-module'] || $scope.Options['--compression-module'] || 'zip';
|
||||
var backmodule = $scope.Backup.TargetURL || '';
|
||||
var ix = backmodule.indexOf(':');
|
||||
if (ix > 0)
|
||||
backmodule = backmodule.substr(0, ix);
|
||||
|
||||
$scope.ExtendedOptionList = AppUtils.buildOptionList($scope.SystemInfo, encmodule, compmodule, backmodule);
|
||||
};
|
||||
|
||||
$scope.$watch("Options['encryption-module']", reloadOptionsList);
|
||||
$scope.$watch("Options['compression-module']", reloadOptionsList);
|
||||
$scope.$watch("Options['--compression-module']", reloadOptionsList);
|
||||
$scope.$watch("Backup.TargetURL", reloadOptionsList);
|
||||
$scope.$on('systeminfochanged', reloadOptionsList);
|
||||
|
||||
if ($routeParams.backupid == null) {
|
||||
|
||||
AppService.get('/backupdefaults').then(function(data) {
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
backupApp.controller('SystemSettingsController', function($scope, $location, AppService, AppUtils, Localization) {
|
||||
backupApp.controller('SystemSettingsController', function($scope, $location, AppService, AppUtils, Localization, SystemInfo) {
|
||||
|
||||
$scope.SystemInfo = SystemInfo.watch($scope);
|
||||
|
||||
function reloadOptionsList() {
|
||||
$scope.advancedOptionList = AppUtils.buildOptionList($scope.SystemInfo, false, false, false);
|
||||
};
|
||||
|
||||
reloadOptionsList();
|
||||
|
||||
$scope.$on('systeminfochanged', reloadOptionsList);
|
||||
|
||||
AppService.get('/serversettings').then(function(data) {
|
||||
|
||||
@@ -9,7 +19,8 @@ backupApp.controller('SystemSettingsController', function($scope, $location, App
|
||||
$scope.allowRemoteAccess = data.data['server-listen-interface'] != 'loopback';
|
||||
$scope.startupDelayDurationValue = data.data['startup-delay'].substr(0, data.data['startup-delay'].length - 1);
|
||||
$scope.startupDelayDurationMultiplier = data.data['startup-delay'].substr(-1);
|
||||
$scope.advancedOptions = AppUtils.serializeAdvancedOptions(data.data);
|
||||
$scope.advancedOptions = AppUtils.serializeAdvancedOptionsToArray(data.data);
|
||||
|
||||
}, AppUtils.connectionError);
|
||||
|
||||
|
||||
@@ -38,7 +49,7 @@ backupApp.controller('SystemSettingsController', function($scope, $location, App
|
||||
|
||||
AppUtils.mergeAdvancedOptions($scope.advancedOptions, patchdata, $scope.rawdata);
|
||||
|
||||
AppService.patch('/serversettings', patchdata).then(
|
||||
AppService.patch('/serversettings', patchdata, {headers: {'Content-Type': 'application/json; charset=utf-8'}}).then(
|
||||
function() {
|
||||
$location.path('/');
|
||||
},
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
backupApp.directive('advancedOptionsEditor', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
ngModel: '=',
|
||||
ngOptionList: '='
|
||||
},
|
||||
templateUrl: 'templates/advancedoptionseditor.html',
|
||||
controller: function($scope, $timeout) {
|
||||
$scope.NewItem = null;
|
||||
|
||||
var optionmap = null;
|
||||
|
||||
function rebuildOptionMap() {
|
||||
optionmap = {};
|
||||
|
||||
for(var n in $scope.ngOptionList)
|
||||
optionmap[$scope.ngOptionList[n].Name.toLowerCase()] = $scope.ngOptionList[n];
|
||||
}
|
||||
|
||||
function coreName(name) {
|
||||
if (name == null)
|
||||
return '';
|
||||
if (typeof(name) != typeof(''))
|
||||
name = name.Name;
|
||||
|
||||
name = name || '';
|
||||
if (name.indexOf('--') == 0)
|
||||
name = name.substr(2);
|
||||
if (name.indexOf('=') >= 0)
|
||||
name = name.substr(0, name.indexOf('='));
|
||||
return name;
|
||||
}
|
||||
|
||||
$scope.getEntry = function(key) {
|
||||
if (optionmap == null)
|
||||
return null;
|
||||
|
||||
return optionmap[coreName(key)];
|
||||
};
|
||||
|
||||
$scope.getDisplayName = function(name) {
|
||||
var item = $scope.getEntry(name);
|
||||
if (item == null)
|
||||
return coreName(name);
|
||||
|
||||
return item.Name + ': ' + item.ShortDescription;
|
||||
};
|
||||
|
||||
$scope.getInputType = function(item) {
|
||||
var item = $scope.getEntry(item);
|
||||
if (item == null)
|
||||
return 'text';
|
||||
|
||||
if (item.Type == 'Enumeration')
|
||||
return 'enum';
|
||||
else if (item.Type == 'Boolean')
|
||||
return 'bool';
|
||||
else if (item.Type == 'Password')
|
||||
return 'password';
|
||||
else if (item.Type == 'Integer')
|
||||
return 'int';
|
||||
else if (item.Type == 'Size')
|
||||
return 'size';
|
||||
else if (item.Type == 'Timespan')
|
||||
return 'timespan';
|
||||
else
|
||||
return 'text';
|
||||
};
|
||||
|
||||
$scope.getShortName = function(name) {
|
||||
var item = $scope.getEntry(name);
|
||||
if (item == null)
|
||||
return coreName(name);
|
||||
|
||||
return item.Name;
|
||||
};
|
||||
|
||||
$scope.getShortDescription = function(item) {
|
||||
var item = $scope.getEntry(item);
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
return item.ShortDescription;
|
||||
};
|
||||
|
||||
$scope.getLongDescription = function(item) {
|
||||
var item = $scope.getEntry(item);
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
return item.LongDescription;
|
||||
};
|
||||
|
||||
$scope.getEnumerations = function(item) {
|
||||
var item = $scope.getEntry(item);
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
return item.ValidValues;
|
||||
};
|
||||
|
||||
$scope.deleteItem = function(item) {
|
||||
for (var i = $scope.ngModel.length - 1; i >= 0; i--) {
|
||||
if ($scope.ngModel[i] == item) {
|
||||
$scope.ngModel.splice(i, 1);
|
||||
return;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
$scope.$watch('ngOptionList', rebuildOptionMap);
|
||||
$scope.$watch('NewItem', function() {
|
||||
if ($scope.NewItem != null) {
|
||||
var opt = '--' + $scope.NewItem.Name;
|
||||
var itm = $scope.getEntry(opt);
|
||||
if (itm != null && itm.DefaultValue != null)
|
||||
opt += '=' + itm.DefaultValue;
|
||||
|
||||
$scope.ngModel.push(opt);
|
||||
$scope.NewItem = null;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -69,7 +69,7 @@ backupApp.directive('backupEditUri', function() {
|
||||
if (confirm('The server certificate could not be validated.\nDo you want to approve the SSL certificate with the hash: ' + hash + '?' )) {
|
||||
|
||||
hasTriedCert = true;
|
||||
scope.AdvancedOptions += '\r\n--accept-specified-ssl-hash=' + hash;
|
||||
scope.AdvancedOptions.push('--accept-specified-ssl-hash=' + hash);
|
||||
|
||||
testConnection();
|
||||
}
|
||||
@@ -141,7 +141,7 @@ backupApp.directive('backupEditUri', function() {
|
||||
delete parts['--auth-username'];
|
||||
delete parts['--auth-password'];
|
||||
delete parts['--use-ssl'];
|
||||
scope.AdvancedOptions = AppUtils.serializeAdvancedOptions(parts);
|
||||
scope.AdvancedOptions = AppUtils.serializeAdvancedOptionsToArray(parts);
|
||||
};
|
||||
|
||||
$scope.SystemInfo = SystemInfo.watch($scope, function() {
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
backupApp.directive('parseAdvancedOption', function(AppUtils) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: ['ngModel'],
|
||||
link: function(scope, element, attr, ctrl) {
|
||||
|
||||
var name = null;
|
||||
|
||||
ctrl[0].$parsers.push(function(txt) {
|
||||
if (name == null)
|
||||
return null;
|
||||
|
||||
return name + '=' + txt;
|
||||
});
|
||||
|
||||
ctrl[0].$formatters.push(function(src) {
|
||||
src = src || '';
|
||||
var ix = src.indexOf('=');
|
||||
if (ix >= 0) {
|
||||
name = src.substr(0, ix);
|
||||
return src.substr(ix + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
name = src;
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
backupApp.directive('parseAdvancedOptionBool', function(AppUtils) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: ['ngModel'],
|
||||
link: function(scope, element, attr, ctrl) {
|
||||
|
||||
var name = null;
|
||||
|
||||
ctrl[0].$parsers.push(function(txt) {
|
||||
if (name == null)
|
||||
return null;
|
||||
|
||||
return name + '=' + txt;
|
||||
});
|
||||
|
||||
ctrl[0].$formatters.push(function(src) {
|
||||
src = src || '';
|
||||
var ix = src.indexOf('=');
|
||||
if (ix >= 0) {
|
||||
name = src.substr(0, ix);
|
||||
return AppUtils.parseBoolString(src.substr(ix + 1), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
name = src;
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
backupApp.directive('parseAdvancedOptionInteger', function(AppUtils) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: ['ngModel'],
|
||||
link: function(scope, element, attr, ctrl) {
|
||||
|
||||
var name = null;
|
||||
|
||||
ctrl[0].$parsers.push(function(txt) {
|
||||
if (name == null)
|
||||
return null;
|
||||
|
||||
return name + '=' + txt;
|
||||
});
|
||||
|
||||
ctrl[0].$formatters.push(function(src) {
|
||||
src = src || '';
|
||||
var ix = src.indexOf('=');
|
||||
if (ix >= 0) {
|
||||
name = src.substr(0, ix);
|
||||
return parseInt(src.substr(ix + 1), 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
name = src;
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
backupApp.directive('parseAdvancedOptionSizeNumber', function(AppUtils) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: ['ngModel'],
|
||||
link: function(scope, element, attr, ctrl) {
|
||||
|
||||
var name = null;
|
||||
var multiplier = null;
|
||||
|
||||
ctrl[0].$parsers.push(function(txt) {
|
||||
if (name == null)
|
||||
return null;
|
||||
|
||||
return name + '=' + txt + multiplier;
|
||||
});
|
||||
|
||||
ctrl[0].$formatters.push(function(src) {
|
||||
src = src || '';
|
||||
var ix = src.indexOf('=');
|
||||
if (ix >= 0) {
|
||||
name = src.substr(0, ix);
|
||||
var parts = AppUtils.splitSizeString(src.substr(ix + 1));
|
||||
if (parts == null)
|
||||
{
|
||||
multiplier = null;
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
multiplier = parts[1];
|
||||
return parseInt(parts[0], 10);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
name = src;
|
||||
multiplier = '';
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
backupApp.directive('parseAdvancedOptionSizeMultiplier', function(AppUtils) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: ['ngModel'],
|
||||
link: function(scope, element, attr, ctrl) {
|
||||
|
||||
var name = null;
|
||||
var number = null;
|
||||
|
||||
ctrl[0].$parsers.push(function(txt) {
|
||||
if (name == null)
|
||||
return null;
|
||||
|
||||
return name + '=' + (number || '') + txt;
|
||||
});
|
||||
|
||||
ctrl[0].$formatters.push(function(src) {
|
||||
src = src || '';
|
||||
var ix = src.indexOf('=');
|
||||
if (ix >= 0) {
|
||||
name = src.substr(0, ix);
|
||||
var parts = AppUtils.splitSizeString(src.substr(ix + 1));
|
||||
if (parts == null)
|
||||
{
|
||||
number = null;
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
number = parseInt(parts[0]);
|
||||
return parts[1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
name = src;
|
||||
number = 0;
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -40,7 +40,17 @@ backupApp.service('AppUtils', function() {
|
||||
{name: 'Fri', value: 'fri'},
|
||||
{name: 'Sat', value: 'sat'},
|
||||
{name: 'Sun', value: 'sun'}
|
||||
];
|
||||
];
|
||||
|
||||
this.parseBoolString = function(txt, def) {
|
||||
txt = (txt || '').toLowerCase();
|
||||
if (txt == '0' || txt == 'false' || txt == 'off' || txt == 'no' || txt == 'f')
|
||||
return false;
|
||||
else if (txt == '1' || txt == 'true' || txt == 'on' || txt == 'yes' || txt == 't')
|
||||
return true;
|
||||
else
|
||||
return def === undefined ? false : def;
|
||||
};
|
||||
|
||||
|
||||
this.splitSizeString = function(val) {
|
||||
@@ -83,7 +93,14 @@ backupApp.service('AppUtils', function() {
|
||||
|
||||
this.parseOptionStrings = function(val, dict, validateCallback) {
|
||||
dict = dict || {};
|
||||
var lines = this.replace_all(val || '', '\r', '\n').split('\n');
|
||||
|
||||
var lines = null;
|
||||
|
||||
if (val != null && typeof(val) == typeof([]))
|
||||
lines = val;
|
||||
else
|
||||
lines = this.replace_all(val || '', '\r', '\n').split('\n');
|
||||
|
||||
for(var i in lines) {
|
||||
var line = lines[i].trim();
|
||||
if (line != '' && line[0] != '#') {
|
||||
@@ -124,12 +141,16 @@ backupApp.service('AppUtils', function() {
|
||||
};
|
||||
|
||||
this.serializeAdvancedOptions = function(opts) {
|
||||
var advopts = '';
|
||||
return this.serializeAdvancedOptionsToArray(opts).join('\n');
|
||||
};
|
||||
|
||||
this.serializeAdvancedOptionsToArray = function(opts) {
|
||||
var res = [];
|
||||
for(var n in opts)
|
||||
if (n.indexOf('--') == 0)
|
||||
advopts += n + '=' + opts[n] + '\n';
|
||||
res.push(n + '=' + opts[n]);
|
||||
|
||||
return advopts;
|
||||
return res;
|
||||
};
|
||||
|
||||
this.mergeAdvancedOptions = function(advStr, target, source) {
|
||||
@@ -478,7 +499,7 @@ backupApp.service('AppUtils', function() {
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
this.evalFilter = function(path, filters, include) {
|
||||
for(var i = 0; i < filters.length; i++) {
|
||||
@@ -488,6 +509,40 @@ backupApp.service('AppUtils', function() {
|
||||
}
|
||||
|
||||
return include === undefined ? true : include;
|
||||
}
|
||||
};
|
||||
|
||||
this.buildOptionList = function(sysinfo, encmodule, compmodule, backmodule) {
|
||||
if (sysinfo == null || sysinfo.Options == null)
|
||||
return null;
|
||||
|
||||
var items = angular.copy(sysinfo.Options);
|
||||
for(var n in items)
|
||||
items[n].Category = 'Core options';
|
||||
|
||||
function copyToList(lst, key) {
|
||||
for(var n in lst)
|
||||
{
|
||||
if (key == null || key.toLowerCase() == lst[n].Key.toLowerCase())
|
||||
{
|
||||
var m = angular.copy(lst[n].Options);
|
||||
for(var i in m)
|
||||
m[i].Category = lst[n].DisplayName;
|
||||
items.push.apply(items, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
copyToList(sysinfo.GenericModules);
|
||||
copyToList(sysinfo.ConnectionModules);
|
||||
|
||||
if (encmodule !== false)
|
||||
copyToList(sysinfo.EncryptionModules, encmodule);
|
||||
if (compmodule !== false)
|
||||
copyToList(sysinfo.CompressionModules, compmodule);
|
||||
if (backmodule !== false)
|
||||
copyToList(sysinfo.BackendModules, backmodule);
|
||||
|
||||
return items;
|
||||
};
|
||||
|
||||
});
|
||||
@@ -582,3 +582,33 @@ ul.notification {
|
||||
.resizable {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.advanced-toggle {
|
||||
float: right;
|
||||
margin-right: 25px;
|
||||
}
|
||||
|
||||
.advancedoptions li {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.advancedoptions .advancedentry {
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 4px;
|
||||
border-bottom: 1px lightgray solid;
|
||||
}
|
||||
|
||||
.advancedentry .multiple {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.advancedentry .shortname {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.advancedentry .longdescription {
|
||||
margin-left: 190px;
|
||||
clear: both;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
|
||||
@@ -249,11 +249,19 @@
|
||||
<option value="">custom</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="input textarea">
|
||||
<label for="backupOptions"><a href id="backupOptionsPopup" data-remodal-target="backupOptions">Options</a><span class="info">i</span></label>
|
||||
<textarea id="backupOptions" ng-model="ExtendedOptions" placeholder="Enter one option per line in command-line format, eg. --dblock-size=100MB"></textarea>
|
||||
|
||||
<div class="input textarea" ng-show="ShowAdvancedTextArea">
|
||||
<label for="backupOptions">Advanced options</label>
|
||||
<a href ng-click="ShowAdvancedTextArea = false" class="advanced-toggle">Edit as list</a>
|
||||
<textarea id="backupOptions" ng-model="ExtendedOptions" string-array-as-text placeholder="Enter one option per line in command-line format, eg. --dblock-size=100MB"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="input" ng-hide="ShowAdvancedTextArea">
|
||||
<label for="backupOptions">Advanced options</label>
|
||||
<a href ng-click="ShowAdvancedTextArea = true" class="advanced-toggle">Edit as text</a>
|
||||
<advanced-options-editor ng-option-list="ExtendedOptionList" ng-model="ExtendedOptions"></advanced-options-editor>
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<input class="submit save" type="submit" id="save" ng-click="save()" value="Save" />
|
||||
<input class="submit prev" type="button" id="prevStep4" ng-click="prevPage()" value="< Previous" />
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
<ul class="advancedoptions">
|
||||
<li ng-repeat="item in ngModel | orderBy: 'item' as nn track by $index" class="advancedentry">
|
||||
<div>
|
||||
<label class="shortname">{{getShortName(item)}}</label>
|
||||
|
||||
<select ng-if="getInputType(item) == 'enum'" ng-options="n for n in getEnumerations(item)" ng-model="$parent.ngModel[$index]" parse-advanced-option ></select>
|
||||
<input ng-if="getInputType(item) == 'bool'" type="checkbox" ng-model="$parent.ngModel[$index]" parse-advanced-option-bool ></input>
|
||||
<input ng-if="getInputType(item) == 'password'" type="password" ng-model="$parent.ngModel[$index]" parse-advanced-option ></input>
|
||||
<input ng-if="getInputType(item) == 'text'" type="text" ng-model="$parent.ngModel[$index]" parse-advanced-option ></input>
|
||||
<input ng-if="getInputType(item) == 'int'" type="number" ng-model="$parent.ngModel[$index]" parse-advanced-option-integer ></input>
|
||||
|
||||
<div ng-if="getInputType(item) == 'size'" class="input type multiple">
|
||||
<input type="number" parse-advanced-option-size-number ng-model="$parent.ngModel[$index]" />
|
||||
<select parse-advanced-option-size-multiplier ng-model="$parent.ngModel[$index]">
|
||||
<option value="kb">KByte</option>
|
||||
<option value="mb">MByte</option>
|
||||
<option value="gb">GByte</option>
|
||||
<option value="tb">TByte</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div ng-if="getInputType(item) == 'timespan'" class="input type multiple">
|
||||
<input parse-advanced-option-size-number type="number" ng-model="$parent.ngModel[$index]" />
|
||||
<select parse-advanced-option-size-multiplier ng-model="$parent.ngModel[$index]">
|
||||
<option value="D">Days</option>
|
||||
<option value="W">Weeks</option>
|
||||
<option value="M">Months</option>
|
||||
<option value="Y">Years</option>
|
||||
<option value="">custom</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<a href ng-click="deleteItem(item)" title="Remove option">x</a>
|
||||
|
||||
<div class="longdescription">{{getLongDescription(item)}}</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<label>Add advanced option</label>
|
||||
<select ng-options="getDisplayName(opt.Name) group by opt.Category for opt in ngOptionList | orderBy: 'Name' " ng-model="NewItem">
|
||||
<option value="">- pick an option -</option>
|
||||
</select>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -17,10 +17,18 @@
|
||||
<h3>Chose a storage type to get started</h3>
|
||||
</div>
|
||||
|
||||
<div class="input textarea">
|
||||
<label for="targetOptions">Options<span class="info">i</span></label>
|
||||
<textarea id="targetOptions" name="targetOptions" ng-model="AdvancedOptions"></textarea>
|
||||
<div class="input textarea" ng-show="ShowAdvancedTextArea">
|
||||
<label for="targetOptions">Options</label>
|
||||
<a href ng-click="ShowAdvancedTextArea = false" class="advanced-toggle">Edit as list</a>
|
||||
<textarea id="targetOptions" name="targetOptions" string-array-as-text ng-model="AdvancedOptions"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="input" ng-hide="ShowAdvancedTextArea">
|
||||
<label for="backupOptions">Options</label>
|
||||
<a href ng-click="ShowAdvancedTextArea = true" class="advanced-toggle">Edit as text</a>
|
||||
<advanced-options-editor ng-option-list="Backend.Options" ng-model="AdvancedOptions"></advanced-options-editor>
|
||||
</div>
|
||||
|
||||
<div class="buttons" ng-hide="Testing">
|
||||
<a href ng-click="save()" class="save">OK</a>
|
||||
<a href ng-click="testConnection()" class="test-connection" >Test connection</a>
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
<input type="checkbox" class="checkbox" id="remote" name="remote" ng-model="allowRemoteAccess" />
|
||||
<label for="remote">Allow remote access (requires restart)</label>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<h2>Pause after startup or hibernation<span class="info">i</span></h2>
|
||||
<div class="input mixed multiple">
|
||||
@@ -36,10 +34,17 @@
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<h2>Advanced Options</h2>
|
||||
<div class="input textarea">
|
||||
<label for="options">Options<span class="info">i</span></label>
|
||||
<textarea id="options" name="options" ng-model="advancedOptions"></textarea>
|
||||
<h2>Default options</h2>
|
||||
<div class="input textarea" ng-show="ShowAdvancedTextArea">
|
||||
<label for="backupOptions">Options</label>
|
||||
<a href ng-click="ShowAdvancedTextArea = false" class="advanced-toggle">Edit as list</a>
|
||||
<textarea id="backupOptions" ng-model="advancedOptions" string-array-as-text placeholder="Enter one option per line in command-line format, eg. --dblock-size=100MB"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="input" ng-hide="ShowAdvancedTextArea">
|
||||
<label for="backupOptions">Options</label>
|
||||
<a href ng-click="ShowAdvancedTextArea = true" class="advanced-toggle">Edit as text</a>
|
||||
<advanced-options-editor ng-option-list="advancedOptionList" ng-model="advancedOptions"></advanced-options-editor>
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
|
||||
Reference in New Issue
Block a user