mirror of
https://github.com/octoleo/syncthing.git
synced 2024-12-22 19:08:58 +00:00
Implement "advanced configuration" dialog (fixes #2010)
This commit is contained in:
parent
e9e13474c9
commit
dec6540967
@ -10,6 +10,8 @@
|
||||
"Add new folder?": "Add new folder?",
|
||||
"Address": "Address",
|
||||
"Addresses": "Addresses",
|
||||
"Advanced": "Advanced",
|
||||
"Advanced Configuration": "Advanced Configuration",
|
||||
"All Data": "All Data",
|
||||
"Allow Anonymous Usage Reporting?": "Allow Anonymous Usage Reporting?",
|
||||
"Alphabetic": "Alphabetic",
|
||||
@ -17,6 +19,7 @@
|
||||
"Anonymous Usage Reporting": "Anonymous Usage Reporting",
|
||||
"Any devices configured on an introducer device will be added to this device as well.": "Any devices configured on an introducer device will be added to this device as well.",
|
||||
"Automatic upgrades": "Automatic upgrades",
|
||||
"Be careful!": "Be careful!",
|
||||
"Bugs": "Bugs",
|
||||
"CPU Utilization": "CPU Utilization",
|
||||
"Changelog": "Changelog",
|
||||
@ -57,10 +60,12 @@
|
||||
"Files are moved to .stversions folder when replaced or deleted by Syncthing.": "Files are moved to .stversions folder when replaced or deleted by Syncthing.",
|
||||
"Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.": "Files are moved to date stamped versions in a .stversions folder when replaced or deleted by Syncthing.",
|
||||
"Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.": "Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.",
|
||||
"Folder": "Folder",
|
||||
"Folder ID": "Folder ID",
|
||||
"Folder Master": "Folder Master",
|
||||
"Folder Path": "Folder Path",
|
||||
"Folders": "Folders",
|
||||
"GUI": "GUI",
|
||||
"GUI Authentication Password": "GUI Authentication Password",
|
||||
"GUI Authentication User": "GUI Authentication User",
|
||||
"GUI Listen Addresses": "GUI Listen Addresses",
|
||||
@ -73,6 +78,7 @@
|
||||
"Ignore Patterns": "Ignore Patterns",
|
||||
"Ignore Permissions": "Ignore Permissions",
|
||||
"Incoming Rate Limit (KiB/s)": "Incoming Rate Limit (KiB/s)",
|
||||
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "Incorrect configuration may damage your folder contents and render Syncthing inoperable.",
|
||||
"Introducer": "Introducer",
|
||||
"Inversion of the given condition (i.e. do not exclude)": "Inversion of the given condition (i.e. do not exclude)",
|
||||
"Keep Versions": "Keep Versions",
|
||||
@ -98,6 +104,7 @@
|
||||
"OK": "OK",
|
||||
"Off": "Off",
|
||||
"Oldest First": "Oldest First",
|
||||
"Options": "Options",
|
||||
"Out of Sync": "Out of Sync",
|
||||
"Out of Sync Items": "Out of Sync Items",
|
||||
"Outgoing Rate Limit (KiB/s)": "Outgoing Rate Limit (KiB/s)",
|
||||
|
@ -63,6 +63,8 @@
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="" ng-click="about()"><span class="glyphicon glyphicon-heart-empty"></span> <span translate>About</span></a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="" ng-click="advanced()"><span class="glyphicon glyphicon-cog"></span> <span translate>Advanced</span></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
@ -221,7 +223,7 @@
|
||||
<td class="text-right">{{model[folder.id].localFiles | alwaysNumber}} <span translate>items</span>, ~{{model[folder.id].localBytes | binary}}B</td>
|
||||
</tr>
|
||||
<tr ng-if="model[folder.id].needFiles > 0">
|
||||
<th><span class="glyphicon glyphicon-cloud-download"></span> <span translate>Out Of Sync</span></th>
|
||||
<th><span class="glyphicon glyphicon-cloud-download"></span> <span translate>Out of Sync</span></th>
|
||||
<td class="text-right">
|
||||
<a ng-click="showNeed(folder.id)" href="">{{model[folder.id].needFiles | alwaysNumber}} <span translate>items</span>, ~{{model[folder.id].needBytes | binary}}B</a>
|
||||
</td>
|
||||
@ -573,7 +575,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label translate for="addresses">Addresses</label>
|
||||
<input ng-disabled="currentDevice.deviceID == myID" id="addresses" class="form-control" type="text" ng-model="currentDevice.addressesStr"></input>
|
||||
<input ng-disabled="currentDevice.deviceID == myID" id="addresses" class="form-control" type="text" ng-model="currentDevice._addressesStr"></input>
|
||||
<p translate class="help-block">Enter comma separated "ip:port" addresses or "dynamic" to perform automatic discovery of the address.</p>
|
||||
</div>
|
||||
<div ng-if="!editingSelf" class="form-group">
|
||||
@ -837,7 +839,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label translate for="ListenAddressStr">Sync Protocol Listen Addresses</label>
|
||||
<input id="ListenAddressStr" class="form-control" type="text" ng-model="tmpOptions.listenAddressStr">
|
||||
<input id="ListenAddressStr" class="form-control" type="text" ng-model="tmpOptions._listenAddressStr">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label translate for="MaxRecvKbps">Incoming Rate Limit (KiB/s)</label>
|
||||
@ -881,7 +883,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label translate for="GlobalAnnServersStr">Global Discovery Server</label>
|
||||
<input ng-disabled="!tmpOptions.globalAnnounceEnabled" id="GlobalAnnServersStr" class="form-control" type="text" ng-model="tmpOptions.globalAnnounceServersStr">
|
||||
<input ng-disabled="!tmpOptions.globalAnnounceEnabled" id="GlobalAnnServersStr" class="form-control" type="text" ng-model="tmpOptions._globalAnnounceServersStr">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1149,12 +1151,95 @@
|
||||
</ul>
|
||||
</modal>
|
||||
|
||||
<!-- Advanced modal -->
|
||||
|
||||
<div id="advanced" class="modal fade" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header alert alert-danger">
|
||||
<h4 translate class="modal-title">Advanced Configuration</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<p class="text-danger">
|
||||
<b translate>Be careful!</b>
|
||||
<span translate>Incorrect configuration may damage your folder contents and render Syncthing inoperable.</span>
|
||||
</p>
|
||||
|
||||
<div class="panel-group" id="advancedAccordion" role="tablist" aria-multiselectable="true">
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading" role="tab" id="guiHeading" data-toggle="collapse" data-parent="#advancedAccordion" href="#guiConfig" aria-expanded="true" aria-controls="guiConfig" style="cursor: pointer">
|
||||
<h4 class="panel-title" translate>GUI</h4>
|
||||
</div>
|
||||
<div id="guiConfig" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="guiHeading">
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal" role="form">
|
||||
<div ng-repeat="(key, value) in config.gui" ng-init="type = inputTypeFor(key, value)" ng-if="type != 'skip'" class="form-group">
|
||||
<label for="guiInput{{$index}}" class="col-sm-4 control-label">{{key}}</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="guiInput{{$index}}" class="form-control" type="{{type}}" ng-model="config.gui[key]" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading" role="tab" id="optionsHeading" data-toggle="collapse" data-parent="#advancedAccordion" href="#optionsConfig" aria-expanded="true" aria-controls="optionsConfig" style="cursor: pointer">
|
||||
<h4 class="panel-title" translate>Options</h4>
|
||||
</div>
|
||||
<div id="optionsConfig" class="panel-collapse collapse" role="tabpanel" aria-labelledby="optionsHeading">
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal" role="form">
|
||||
<div ng-repeat="(key, value) in config.options" ng-if="inputTypeFor(key, value) != 'skip'" class="form-group">
|
||||
<label for="optionsInput{{$index}}" class="col-sm-4 control-label">{{key}}</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="optionsInput{{$index}}" class="form-control" type="{{inputTypeFor(key, value)}}" ng-model="config.options[key]" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default" ng-repeat="(folder, _) in folders">
|
||||
<div class="panel-heading" role="tab" id="folder{{folder}}Heading" data-toggle="collapse" data-parent="#advancedAccordion" href="#folder{{folder}}Config" aria-expanded="true" aria-controls="folder{{folder}}Config" style="cursor: pointer">
|
||||
<h4 class="panel-title">
|
||||
<span translate>Folder</span> "{{folder}}"
|
||||
</h4>
|
||||
</div>
|
||||
<div id="folder{{folder}}Config" class="panel-collapse collapse" role="tabpanel" aria-labelledby="folder{{folder}}Heading">
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal" role="form">
|
||||
<div ng-repeat="(key, value) in folders[folder]" ng-if="inputTypeFor(key, value) != 'skip'" class="form-group">
|
||||
<label for="foldre{{folder}}Input{{$index}}" class="col-sm-4 control-label">{{key}}</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="folder{{folder}}Input{{$index}}" class="form-control" type="{{inputTypeFor(key, value)}}" ng-model="folders[folder][key]" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary btn-sm" ng-click="saveAdvanced()"><span class="glyphicon glyphicon-ok"></span> <span translate>Save</span></button>
|
||||
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span> <span translate>Close</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- vendor scripts -->
|
||||
<script src="vendor/jquery/jquery-2.0.3.min.js"></script>
|
||||
<script src="vendor/angular/angular.min.js"></script>
|
||||
<script src="vendor/angular/angular-translate.min.js"></script>
|
||||
<script src="vendor/angular/angular-translate-loader.min.js"></script>
|
||||
<script src="vendor/angular/angular-dirPagination.js"></script>
|
||||
<script src="vendor/jquery/jquery-2.0.3.min.js"></script>
|
||||
<script src="vendor/bootstrap/js/bootstrap.min.js"></script>
|
||||
<!-- / vendor scripts -->
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
var syncthing = angular.module('syncthing', [
|
||||
'angularUtils.directives.dirPagination',
|
||||
'pascalprecht.translate',
|
||||
|
||||
'syncthing.core'
|
||||
]);
|
||||
|
||||
|
@ -314,8 +314,8 @@ angular.module('syncthing.core')
|
||||
var hasConfig = !isEmptyObject($scope.config);
|
||||
|
||||
$scope.config = config;
|
||||
$scope.config.options.listenAddressStr = $scope.config.options.listenAddress.join(', ');
|
||||
$scope.config.options.globalAnnounceServersStr = $scope.config.options.globalAnnounceServers.join(', ');
|
||||
$scope.config.options._listenAddressStr = $scope.config.options.listenAddress.join(', ');
|
||||
$scope.config.options._globalAnnounceServersStr = $scope.config.options.globalAnnounceServers.join(', ');
|
||||
|
||||
$scope.devices = $scope.config.devices;
|
||||
$scope.devices.forEach(function (deviceCfg) {
|
||||
@ -746,7 +746,7 @@ angular.module('syncthing.core')
|
||||
$scope.config.gui = angular.copy($scope.tmpGUI);
|
||||
|
||||
['listenAddress', 'globalAnnounceServers'].forEach(function (key) {
|
||||
$scope.config.options[key] = $scope.config.options[key + "Str"].split(/[ ,]+/).map(function (x) {
|
||||
$scope.config.options[key] = $scope.config.options["_" + key + "Str"].split(/[ ,]+/).map(function (x) {
|
||||
return x.trim();
|
||||
});
|
||||
});
|
||||
@ -757,6 +757,11 @@ angular.module('syncthing.core')
|
||||
$('#settings').modal("hide");
|
||||
};
|
||||
|
||||
$scope.saveAdvanced = function () {
|
||||
$scope.saveConfig();
|
||||
$('#advanced').modal("hide");
|
||||
};
|
||||
|
||||
$scope.restart = function () {
|
||||
restarting = true;
|
||||
$('#restarting').modal();
|
||||
@ -807,7 +812,7 @@ angular.module('syncthing.core')
|
||||
$scope.currentDevice = $.extend({}, deviceCfg);
|
||||
$scope.editingExisting = true;
|
||||
$scope.editingSelf = (deviceCfg.deviceID == $scope.myID);
|
||||
$scope.currentDevice.addressesStr = deviceCfg.addresses.join(', ');
|
||||
$scope.currentDevice._addressesStr = deviceCfg.addresses.join(', ');
|
||||
if (!$scope.editingSelf) {
|
||||
$scope.currentDevice.selectedFolders = {};
|
||||
$scope.deviceFolders($scope.currentDevice).forEach(function (folder) {
|
||||
@ -829,7 +834,7 @@ angular.module('syncthing.core')
|
||||
})
|
||||
.then(function () {
|
||||
$scope.currentDevice = {
|
||||
addressesStr: 'dynamic',
|
||||
_addressesStr: 'dynamic',
|
||||
compression: 'metadata',
|
||||
introducer: false,
|
||||
selectedFolders: {}
|
||||
@ -874,7 +879,7 @@ angular.module('syncthing.core')
|
||||
$scope.addNewDeviceID = function (device) {
|
||||
var deviceCfg = {
|
||||
deviceID: device,
|
||||
addressesStr: 'dynamic',
|
||||
_addressesStr: 'dynamic',
|
||||
compression: 'metadata',
|
||||
introducer: false,
|
||||
selectedFolders: {}
|
||||
@ -885,7 +890,7 @@ angular.module('syncthing.core')
|
||||
|
||||
$scope.saveDeviceConfig = function (deviceCfg) {
|
||||
var done, i;
|
||||
deviceCfg.addresses = deviceCfg.addressesStr.split(',').map(function (x) {
|
||||
deviceCfg.addresses = deviceCfg._addressesStr.split(',').map(function (x) {
|
||||
return x.trim();
|
||||
});
|
||||
|
||||
@ -1311,6 +1316,10 @@ angular.module('syncthing.core')
|
||||
$('#about').modal('show');
|
||||
};
|
||||
|
||||
$scope.advanced = function () {
|
||||
$('#advanced').modal('show');
|
||||
};
|
||||
|
||||
$scope.showReportPreview = function () {
|
||||
$scope.reportPreview = true;
|
||||
};
|
||||
@ -1361,6 +1370,22 @@ angular.module('syncthing.core')
|
||||
return $scope.version.version + ', ' + os + ' (' + arch + ')';
|
||||
};
|
||||
|
||||
$scope.inputTypeFor = function (key, value) {
|
||||
if (key.substr(0, 1) === '_') {
|
||||
return 'skip';
|
||||
}
|
||||
if (typeof value === 'number') {
|
||||
return 'number';
|
||||
}
|
||||
if (typeof value === 'boolean') {
|
||||
return 'checkbox';
|
||||
}
|
||||
if (typeof value === 'object') {
|
||||
return 'skip';
|
||||
}
|
||||
return 'text';
|
||||
};
|
||||
|
||||
// pseudo main. called on all definitions assigned
|
||||
initController();
|
||||
});
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user