mirror of
https://github.com/octoleo/syncthing.git
synced 2025-01-22 14:48:30 +00:00
gui: Modal dialog for listeners and discovery status (#7539)
This commit is contained in:
parent
18592af993
commit
ea0a408849
@ -286,6 +286,8 @@
|
||||
"Sharing": "Sharing",
|
||||
"Show ID": "Show ID",
|
||||
"Show QR": "Show QR",
|
||||
"Show detailed discovery status": "Show detailed discovery status",
|
||||
"Show detailed listener status": "Show detailed listener status",
|
||||
"Show diff with previous version": "Show diff with previous version",
|
||||
"Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.": "Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.",
|
||||
"Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.": "Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.",
|
||||
@ -295,7 +297,9 @@
|
||||
"Single level wildcard (matches within a directory only)": "Single level wildcard (matches within a directory only)",
|
||||
"Size": "Size",
|
||||
"Smallest First": "Smallest First",
|
||||
"Some discovery methods could not be established for finding other devices or announcing this device:": "Some discovery methods could not be established for finding other devices or announcing this device:",
|
||||
"Some items could not be restored:": "Some items could not be restored:",
|
||||
"Some listening addresses could not be enabled to accept connections:": "Some listening addresses could not be enabled to accept connections:",
|
||||
"Source Code": "Source Code",
|
||||
"Stable releases and release candidates": "Stable releases and release candidates",
|
||||
"Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.": "Stable releases are delayed by about two weeks. During this time they go through testing as release candidates.",
|
||||
@ -312,6 +316,8 @@
|
||||
"Syncthing has been shut down.": "Syncthing has been shut down.",
|
||||
"Syncthing includes the following software or portions thereof:": "Syncthing includes the following software or portions thereof:",
|
||||
"Syncthing is Free and Open Source Software licensed as MPL v2.0.": "Syncthing is Free and Open Source Software licensed as MPL v2.0.",
|
||||
"Syncthing is listening on the following network addresses for connection attempts from other devices:": "Syncthing is listening on the following network addresses for connection attempts from other devices:",
|
||||
"Syncthing is not listening for connection attempts from other devices on any address. Only outgoing connections from this device may work.": "Syncthing is not listening for connection attempts from other devices on any address. Only outgoing connections from this device may work.",
|
||||
"Syncthing is restarting.": "Syncthing is restarting.",
|
||||
"Syncthing is upgrading.": "Syncthing is upgrading.",
|
||||
"Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.": "Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.",
|
||||
@ -336,6 +342,7 @@
|
||||
"The following intervals are used: for the first hour a version is kept every 30 seconds, for the first day a version is kept every hour, for the first 30 days a version is kept every day, until the maximum age a version is kept every week.": "The following intervals are used: for the first hour a version is kept every 30 seconds, for the first day a version is kept every hour, for the first 30 days a version is kept every day, until the maximum age a version is kept every week.",
|
||||
"The following items could not be synchronized.": "The following items could not be synchronized.",
|
||||
"The following items were changed locally.": "The following items were changed locally.",
|
||||
"The following methods are used to discover other devices on the network and announce this device to be found by others:": "The following methods are used to discover other devices on the network and announce this device to be found by others:",
|
||||
"The following unexpected items were found.": "The following unexpected items were found.",
|
||||
"The interval must be a positive number of seconds.": "The interval must be a positive number of seconds.",
|
||||
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.",
|
||||
@ -353,6 +360,7 @@
|
||||
"They are retried automatically and will be synced when the error is resolved.": "They are retried automatically and will be synced when the error is resolved.",
|
||||
"This Device": "This Device",
|
||||
"This can easily give hackers access to read and change any files on your computer.": "This can easily give hackers access to read and change any files on your computer.",
|
||||
"This device cannot automatically discover other devices or announce its own address to be found by others. Only devices with statically configured addresses can connect.": "This device cannot automatically discover other devices or announce its own address to be found by others. Only devices with statically configured addresses can connect.",
|
||||
"This is a major version upgrade.": "This is a major version upgrade.",
|
||||
"This setting controls the free space required on the home (i.e., index database) disk.": "This setting controls the free space required on the home (i.e., index database) disk.",
|
||||
"Time": "Time",
|
||||
|
@ -655,26 +655,20 @@
|
||||
<tr>
|
||||
<th><span class="fas fa-fw fa-sitemap"></span> <span translate>Listeners</span></th>
|
||||
<td class="text-right">
|
||||
<span ng-if="listenersFailed.length == 0" class="data text-success">
|
||||
<span>{{listenersTotal}}/{{listenersTotal}}</span>
|
||||
</span>
|
||||
<span ng-if="listenersFailed.length != 0" class="data" ng-class="{'text-danger': listenersFailed.length == listenersTotal}">
|
||||
<span popover data-trigger="hover" data-placement="bottom" data-html="true" data-content="{{listenersFailed.join('<br>\n')}}">
|
||||
{{listenersTotal-listenersFailed.length}}/{{listenersTotal}}
|
||||
</span>
|
||||
<span class="data" tooltip data-original-title="{{'Show detailed listener status' | translate}}.">
|
||||
<a href="" style="color:inherit" ng-class="{'text-success': listenersFailed.length == 0, 'text-danger': listenersFailed.length == listenersTotal}" ng-click="showListenerStatus()">
|
||||
{{listenersTotal-listenersFailed.length}}/{{listenersTotal}}
|
||||
</a>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-if="system.discoveryEnabled">
|
||||
<th><span class="fas fa-fw fa-map-signs"></span> <span translate>Discovery</span></th>
|
||||
<td class="text-right">
|
||||
<span ng-if="discoveryFailed.length == 0" class="data text-success">
|
||||
<span>{{discoveryTotal}}/{{discoveryTotal}}</span>
|
||||
</span>
|
||||
<span ng-if="discoveryFailed.length != 0" class="data" ng-class="{'text-danger': discoveryFailed.length == discoveryTotal}">
|
||||
<span popover data-trigger="hover" data-placement="bottom" data-content="{{'Click to see discovery failures' | translate}}.">
|
||||
<a href="" style="color:inherit" ng-click="showDiscoveryFailures()">{{discoveryTotal-discoveryFailed.length}}/{{discoveryTotal}}</a>
|
||||
</span>
|
||||
<span class="data" tooltip data-original-title="{{'Show detailed discovery status' | translate}}.">
|
||||
<a href="" style="color:inherit" ng-class="{'text-success': discoveryFailed.length == 0, 'text-danger': discoveryFailed.length == discoveryTotal}" ng-click="showDiscoveryStatus()">
|
||||
{{discoveryTotal-discoveryFailed.length}}/{{discoveryTotal}}
|
||||
</a>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
@ -921,7 +915,7 @@
|
||||
<ng-include src="'syncthing/core/upgradeModalView.html'"></ng-include>
|
||||
<ng-include src="'syncthing/core/majorUpgradeModalView.html'"></ng-include>
|
||||
<ng-include src="'syncthing/core/aboutModalView.html'"></ng-include>
|
||||
<ng-include src="'syncthing/core/discoveryFailuresModalView.html'"></ng-include>
|
||||
<ng-include src="'syncthing/core/connectivityStatusModalView.html'"></ng-include>
|
||||
<ng-include src="'syncthing/folder/removeFolderDialogView.html'"></ng-include>
|
||||
<ng-include src="'syncthing/folder/revertOverrideView.html'"></ng-include>
|
||||
<ng-include src="'syncthing/device/removeDeviceDialogView.html'"></ng-include>
|
||||
|
60
gui/default/syncthing/core/connectivityStatusModalView.html
Normal file
60
gui/default/syncthing/core/connectivityStatusModalView.html
Normal file
@ -0,0 +1,60 @@
|
||||
<modal id="connectivity-status" status="{{connectivityStatusParams.status}}" icon="fas fa-fw {{connectivityStatusParams.type == 'listeners' ? 'fa-sitemap' : 'fa-map-signs'}}" heading="{{connectivityStatusParams.heading}}" large="no" closeable="yes">
|
||||
<div class="modal-body" ng-switch="connectivityStatusParams.type">
|
||||
<div ng-switch-when="listeners">
|
||||
<p translate ng-if="listenersRunning.length == 0">
|
||||
Syncthing is not listening for connection attempts from other devices on any address. Only outgoing connections from this device may work.
|
||||
</p>
|
||||
<div ng-if="listenersRunning.length > 0">
|
||||
<p translate>
|
||||
Syncthing is listening on the following network addresses for connection attempts from other devices:
|
||||
</p>
|
||||
<ul>
|
||||
<li ng-repeat="listener in listenersRunning">{{listener}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div ng-if="listenersFailed.length > 0">
|
||||
<p translate>
|
||||
Some listening addresses could not be enabled to accept connections:
|
||||
</p>
|
||||
<ul>
|
||||
<li ng-repeat="listener in listenersFailed">{{listener}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-default><!-- discovery methods -->
|
||||
<p translate ng-if="discoveryRunning.length == 0">
|
||||
This device cannot automatically discover other devices or announce its own address to be found by others. Only devices with statically configured addresses can connect.
|
||||
</p>
|
||||
<div ng-if="discoveryRunning.length > 0">
|
||||
<p translate>
|
||||
The following methods are used to discover other devices on the network and announce this device to be found by others:
|
||||
</p>
|
||||
<ul>
|
||||
<li ng-repeat="discovery in discoveryRunning">{{discovery}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div ng-if="discoveryFailed.length > 0">
|
||||
<p translate>
|
||||
Some discovery methods could not be established for finding other devices or announcing this device:
|
||||
</p>
|
||||
<ul>
|
||||
<li ng-repeat="discovery in discoveryFailed">{{discovery}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-offset-2 col-md-8">
|
||||
<div class="panel panel-default">
|
||||
<div translate class="panel-body">
|
||||
Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">
|
||||
<span class="fas fa-times"></span> <span translate>Close</span>
|
||||
</button>
|
||||
</div>
|
||||
</modal>
|
@ -1,21 +0,0 @@
|
||||
<modal id="discovery-failures" status="danger" icon="fas fa-exclamation-circle" heading="{{'Discovery Failures' | translate}}" large="yes" closeable="yes">
|
||||
<div class="modal-body">
|
||||
<ul>
|
||||
<li ng-repeat="failure in discoveryFailed">{{failure}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-offset-2 col-md-8">
|
||||
<div class="panel panel-default">
|
||||
<div translate class="panel-body">
|
||||
Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">
|
||||
<span class="fas fa-times"></span> <span translate>Close</span>
|
||||
</button>
|
||||
</div>
|
||||
</modal>
|
@ -471,22 +471,30 @@ angular.module('syncthing.core')
|
||||
}
|
||||
|
||||
var listenersFailed = [];
|
||||
var listenersRunning = [];
|
||||
for (var address in data.connectionServiceStatus) {
|
||||
if (data.connectionServiceStatus[address].error) {
|
||||
listenersFailed.push(address + ": " + data.connectionServiceStatus[address].error);
|
||||
} else {
|
||||
listenersRunning.push(address);
|
||||
}
|
||||
}
|
||||
$scope.listenersFailed = listenersFailed;
|
||||
$scope.listenersRunning = listenersRunning;
|
||||
$scope.listenersTotal = $scope.sizeOf(data.connectionServiceStatus);
|
||||
|
||||
$scope.discoveryTotal = data.discoveryMethods;
|
||||
var discoveryFailed = [];
|
||||
for (var disco in data.discoveryErrors) {
|
||||
if (data.discoveryErrors[disco]) {
|
||||
discoveryFailed.push(disco + ": " + data.discoveryErrors[disco]);
|
||||
var discoveryRunning = [];
|
||||
for (var disco in data.discoveryStatus) {
|
||||
if (data.discoveryStatus[disco] && data.discoveryStatus[disco].error) {
|
||||
discoveryFailed.push(disco + ": " + data.discoveryStatus[disco].error);
|
||||
} else {
|
||||
discoveryRunning.push(disco);
|
||||
}
|
||||
}
|
||||
$scope.discoveryFailed = discoveryFailed;
|
||||
$scope.discoveryRunning = discoveryRunning;
|
||||
$scope.discoveryTotal = $scope.sizeOf(data.discoveryStatus);
|
||||
|
||||
refreshNoAuthWarning();
|
||||
|
||||
@ -1249,8 +1257,34 @@ angular.module('syncthing.core')
|
||||
}
|
||||
};
|
||||
|
||||
$scope.showDiscoveryFailures = function () {
|
||||
$('#discovery-failures').modal();
|
||||
$scope.showListenerStatus = function () {
|
||||
var params = {
|
||||
type: 'listeners',
|
||||
};
|
||||
if ($scope.listenersFailed.length > 0) {
|
||||
params.status = 'danger';
|
||||
params.heading = $translate.instant("Listener Failures");
|
||||
} else {
|
||||
params.status = 'default';
|
||||
params.heading = $translate.instant("Listener Status");
|
||||
}
|
||||
$scope.connectivityStatusParams = params;
|
||||
$('#connectivity-status').modal();
|
||||
};
|
||||
|
||||
$scope.showDiscoveryStatus = function () {
|
||||
var params = {
|
||||
type: 'discovery',
|
||||
};
|
||||
if ($scope.discoveryFailed.length > 0) {
|
||||
params.status = 'danger';
|
||||
params.heading = $translate.instant("Discovery Failures");
|
||||
} else {
|
||||
params.status = 'default';
|
||||
params.heading = $translate.instant("Discovery Status");
|
||||
}
|
||||
$scope.connectivityStatusParams = params;
|
||||
$('#connectivity-status').modal();
|
||||
};
|
||||
|
||||
$scope.logging = {
|
||||
|
@ -1023,16 +1023,16 @@ func (s *service) getSystemStatus(w http.ResponseWriter, r *http.Request) {
|
||||
res["tilde"] = tilde
|
||||
if s.cfg.Options().LocalAnnEnabled || s.cfg.Options().GlobalAnnEnabled {
|
||||
res["discoveryEnabled"] = true
|
||||
discoErrors := make(map[string]string)
|
||||
discoMethods := 0
|
||||
for disco, err := range s.discoverer.ChildErrors() {
|
||||
discoMethods++
|
||||
if err != nil {
|
||||
discoErrors[disco] = err.Error()
|
||||
discoStatus := s.discoverer.ChildErrors()
|
||||
res["discoveryStatus"] = discoveryStatusMap(discoStatus)
|
||||
res["discoveryMethods"] = len(discoStatus) // DEPRECATED: Redundant, only for backwards compatibility, should be removed.
|
||||
discoErrors := make(map[string]*string, len(discoStatus))
|
||||
for s, e := range discoStatus {
|
||||
if e != nil {
|
||||
discoErrors[s] = errorString(e)
|
||||
}
|
||||
}
|
||||
res["discoveryMethods"] = discoMethods
|
||||
res["discoveryErrors"] = discoErrors
|
||||
res["discoveryErrors"] = discoErrors // DEPRECATED: Redundant, only for backwards compatibility, should be removed.
|
||||
}
|
||||
|
||||
res["connectionServiceStatus"] = s.connectionsService.ListenerStatus()
|
||||
@ -1905,6 +1905,20 @@ func errorString(err error) *string {
|
||||
return nil
|
||||
}
|
||||
|
||||
type discoveryStatusEntry struct {
|
||||
Error *string `json:"error"`
|
||||
}
|
||||
|
||||
func discoveryStatusMap(errs map[string]error) map[string]discoveryStatusEntry {
|
||||
out := make(map[string]discoveryStatusEntry, len(errs))
|
||||
for s, e := range errs {
|
||||
out[s] = discoveryStatusEntry{
|
||||
Error: errorString(e),
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// sanitizedHostname returns the given name in a suitable form for use as
|
||||
// the common name in a certificate, or an error.
|
||||
func sanitizedHostname(name string) (string, error) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user