2014-01-05 22:54:57 +00:00
<!DOCTYPE html>
2014-06-01 20:50:14 +00:00
<!--
Copyright (C) 2014 Jakob Borg and other contributors. All rights reserved.
Use of this source code is governed by an MIT-style license that can be
found in the LICENSE file.
-->
2014-05-16 16:42:22 +00:00
< html lang = "en" ng-app = "syncthing" ng-controller = "SyncthingCtrl" class = "ng-cloak" >
2014-01-05 22:54:57 +00:00
< head >
2014-04-09 21:00:23 +00:00
< meta charset = "utf-8" >
< meta http-equiv = "X-UA-Compatible" content = "IE=edge" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< meta name = "description" content = "" >
< meta name = "author" content = "" >
< link rel = "shortcut icon" href = "favicon.png" >
2014-05-16 16:42:22 +00:00
< title > Syncthing | {{thisNodeName()}}< / title >
2014-04-09 21:00:23 +00:00
< link href = "bootstrap/css/bootstrap.min.css" rel = "stylesheet" >
< style type = "text/css" >
body {
padding-bottom: 70px;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
ul+h5 {
margin-top: 1.5em;
}
.text-monospace {
2014-05-20 17:36:37 +00:00
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
2014-04-09 21:00:23 +00:00
}
.table-condensed>thead>tr>th, .table-condensed>tbody>tr>th, .table-condensed>tfoot>tr>th, .table-condensed>thead>tr>td, .table-condensed>tbody>tr>td, .table-condensed>tfoot>tr>td {
border-top: none;
}
.logo {
margin: 0;
padding: 0;
top: -5px;
position: relative;
}
.list-no-bullet {
list-style-type: none
}
.li-column {
display: inline-block;
min-width: 7em;
margin-right: 1em;
background-color: rgb(236, 240, 241);
border-radius: 3px;
padding: 1px 4px;
margin: 2px 2px;
}
.li-column span.data {
margin-left: 0.5em;
min-width: 10em;
text-align: right;
display: inline-block;
}
2014-04-15 17:14:31 +00:00
.ng-cloak {
display: none !important;
}
2014-05-20 17:36:37 +00:00
.table th {
2014-05-27 08:56:36 +00:00
white-space:nowrap;
2014-05-20 17:36:37 +00:00
font-weight: 400;
}
.table td {
padding-left: 20px !important;
}
2014-06-02 21:30:53 +00:00
@media (max-width:767px) {
.table-responsive>.table>tbody>tr>td {
2014-06-02 08:18:45 +00:00
/* revert a bootstrap setting e.g.:
* for mobile phones to allow linebreaks in long repro folder/shared with
* columns. */
2014-06-02 21:30:53 +00:00
white-space: normal;
2014-06-02 08:18:45 +00:00
}
}
2014-04-09 21:00:23 +00:00
< / style >
2014-01-05 22:54:57 +00:00
< / head >
2014-05-16 16:42:22 +00:00
< body >
2014-04-09 21:00:23 +00:00
<!-- Top bar -->
< nav class = "navbar navbar-top navbar-default" role = "navigation" >
2014-01-08 12:52:17 +00:00
< div class = "container" >
2014-05-20 17:36:37 +00:00
< span class = "navbar-brand" > < img class = "logo" src = "st-logo-128.png" width = "32" height = "32" / > Syncthing< small class = "hidden-xs" > < span class = "text-muted" > |< / span > {{thisNodeName()}}< / small > < / span >
< ul class = "nav navbar-nav navbar-right" >
2014-05-24 19:56:09 +00:00
< li class = "dropdown" >
2014-05-20 17:36:37 +00:00
< a href = "#" class = "dropdown-toggle" data-toggle = "dropdown" > Edit < b class = "caret" > < / b > < / a >
< ul class = "dropdown-menu" >
2014-05-21 18:06:14 +00:00
< li > < a href = "" ng-click = "addRepo()" > < span class = "glyphicon glyphicon-hdd" > < / span >   Add Repository< / a > < / li >
< li > < a href = "" ng-click = "addNode()" > < span class = "glyphicon glyphicon-retweet" > < / span >   Add Node< / a > < / li >
2014-05-20 17:36:37 +00:00
< li class = "divider" > < / li >
2014-05-21 18:06:14 +00:00
< li > < a href = "" ng-click = "editSettings()" > < span class = "glyphicon glyphicon-cog" > < / span >   Settings< / a > < / li >
2014-05-24 19:56:09 +00:00
< li > < a href = "" ng-click = "idNode()" > < span class = "glyphicon glyphicon-qrcode" > < / span >   Show ID< / a > < / li >
2014-05-20 17:36:37 +00:00
< li class = "divider" > < / li >
2014-05-21 18:06:14 +00:00
< li > < a href = "" ng-click = "shutdown()" > < span class = "glyphicon glyphicon-off" > < / span >   Shutdown< / a > < / li >
< li > < a href = "" ng-click = "restart()" > < span class = "glyphicon glyphicon-refresh" > < / span >   Restart< / a > < / li >
2014-05-20 17:36:37 +00:00
< / ul >
< / li >
2014-05-24 19:56:09 +00:00
< / ul >
2014-02-12 11:10:44 +00:00
< / div >
2014-04-09 21:00:23 +00:00
< / nav >
2014-01-05 22:54:57 +00:00
2014-04-09 21:00:23 +00:00
< div class = "container" >
2014-02-12 22:18:41 +00:00
2014-04-09 21:00:23 +00:00
<!-- First row, only shown if necessary; Restart warning -->
< div ng-if = "!configInSync" class = "row" >
< div class = "col-md-12" >
< div class = "panel panel-warning" >
< div class = "panel-heading" > < h3 class = "panel-title" > Restart Needed< / h3 > < / div >
< div class = "panel-body" >
< p > The configuration has been saved but not activated. Syncthing must restart to activate the new configuration.< / p >
< / div >
< div class = "panel-footer" >
2014-05-21 13:37:28 +00:00
< button type = "button" class = "btn btn-sm btn-default pull-right" ng-click = "restart()" > < span class = "glyphicon glyphicon-refresh" > < / span >   Restart< / button >
2014-04-09 21:00:23 +00:00
< div class = "clearfix" > < / div >
< / div >
2014-01-05 22:54:57 +00:00
< / div >
2014-04-09 21:00:23 +00:00
< / div >
2014-02-12 11:10:44 +00:00
< / div >
2014-04-09 21:00:23 +00:00
<!-- First regular row -->
2014-02-12 11:10:44 +00:00
< div class = "row" >
2014-04-09 21:00:23 +00:00
<!-- Repository list (top left) -->
< div class = "col-md-6" >
2014-05-24 19:56:09 +00:00
< div class = "panel-group" id = "repositories" >
< div class = "panel panel-{{repoClass(repo.ID)}}" ng-repeat = "repo in repoList()" >
< div class = "panel-heading" >
< h3 class = "panel-title" >
2014-06-02 21:30:53 +00:00
< a data-toggle = "collapse" data-parent = "#repositories" href = "#repo-{{$index}}" >
2014-05-24 19:56:09 +00:00
< span class = "glyphicon glyphicon-hdd" > < / span > {{repo.Directory | shortPath}}
< span class = "pull-right hidden-xs" > {{repoStatus(repo.ID)}}< / span >
< / a >
< / h3 >
< / div >
2014-06-02 21:30:53 +00:00
< div id = "repo-{{$index}}" class = "panel-collapse collapse" >
2014-05-24 19:56:09 +00:00
< div class = "panel-body" >
< div class = "table-responsive" >
< table class = "table table-condensed table-striped" >
< tbody >
< tr >
< th > < span class = "glyphicon glyphicon-tag" > < / span >   Repository ID< / th >
< td class = "text-right" > {{repo.ID}}< / td >
< / tr >
< tr >
< th > < span class = "glyphicon glyphicon-folder-open" > < / span >   Folder< / th >
< td class = "text-right" > {{repo.Directory}}< / td >
< / tr >
2014-05-28 04:55:30 +00:00
< tr ng-if = "model[repo.ID].invalid" >
< th > < span class = "glyphicon glyphicon-warning-sign" > < / span >   Error< / th >
< td class = "text-right" > {{model[repo.ID].invalid}}< / td >
< / tr >
2014-05-24 19:56:09 +00:00
< tr >
< th > < span class = "glyphicon glyphicon-comment" > < / span >   Synchronization< / th >
< td class = "text-right" > {{repoStatus(repo.ID)}}< / td >
< / tr >
< tr >
< th > < span class = "glyphicon glyphicon-globe" > < / span >   Global Repository< / th >
< td class = "text-right" > {{model[repo.ID].globalFiles | alwaysNumber}} files, {{model[repo.ID].globalBytes | binary}}B< / td >
< / tr >
< tr >
< th > < span class = "glyphicon glyphicon-home" > < / span >   Local Repository< / th >
< td class = "text-right" > {{model[repo.ID].localFiles | alwaysNumber}} files, {{model[repo.ID].localBytes | binary}}B< / td >
< / tr >
< tr >
< th > < span class = "glyphicon glyphicon-cloud-download" > < / span >   Out of Sync< / th >
< td class = "text-right" > {{model[repo.ID].needFiles | alwaysNumber}} files, {{model[repo.ID].needBytes | binary}}B< / td >
< / tr >
< tr >
< th > < span class = "glyphicon glyphicon-lock" > < / span >   Master Repository< / th >
< td class = "text-right" >
< span ng-if = "repo.ReadOnly" > Yes< / span >
< span ng-if = "!repo.ReadOnly" > No< / span >
< / td >
< / tr >
< tr >
< th > < span class = "glyphicon glyphicon-unchecked" > < / span >   Ignore Permissions< / th >
< td class = "text-right" >
< span ng-if = "repo.IgnorePerms" > Yes< / span >
< span ng-if = "!repo.IgnorePerms" > No< / span >
< / td >
< / tr >
< tr >
< th > < span class = "glyphicon glyphicon-share-alt" > < / span >   Shared With< / th >
< td class = "text-right" > {{sharesRepo(repo)}}< / td >
< / tr >
< / tbody >
< / table >
< / div >
< span class = "pull-right" > < a class = "btn btn-sm btn-primary" href = "" ng-click = "editRepo(repo)" > < span class = "glyphicon glyphicon-pencil" > < / span >   Edit< / a > < / span >
< / div >
2014-05-20 17:36:37 +00:00
< / div >
2014-04-09 21:00:23 +00:00
< / div >
2014-02-12 11:10:44 +00:00
< / div >
2014-04-09 21:00:23 +00:00
< / div >
2014-01-05 22:54:57 +00:00
2014-04-09 21:00:23 +00:00
<!-- Node list (top right) -->
< div class = "col-md-6" >
2014-05-24 19:56:09 +00:00
< div class = "panel-group" id = "nodes" >
< div class = "panel panel-default" ng-repeat = "nodeCfg in [thisNode()]" >
< div class = "panel-heading" >
< h3 class = "panel-title" >
2014-06-02 21:30:53 +00:00
< a data-toggle = "collapse" data-parent = "#nodes" href = "#node-this" > < span class = "glyphicon glyphicon-home" > < / span > {{nodeName(nodeCfg)}}< / a >
2014-05-24 19:56:09 +00:00
< / h3 >
< / div >
2014-06-02 21:30:53 +00:00
< div id = "node-this" class = "panel-collapse collapse in" >
2014-05-24 19:56:09 +00:00
< div class = "panel-body" >
< div class = "table-responsive" >
< table class = "table table-condensed table-striped" >
< tbody >
< tr >
< th > < span class = "glyphicon glyphicon-th" > < / span >   RAM Utilization< / th >
< td class = "text-right" > {{system.sys | binary}}B< / td >
< / tr >
< tr >
< th > < span class = "glyphicon glyphicon-tasks" > < / span >   CPU Utilization< / th >
< td class = "text-right" > {{system.cpuPercent | alwaysNumber | natural:1}}%< / td >
< / tr >
< tr >
< th > < span class = "glyphicon glyphicon-cloud-download" > < / span >   Download Rate< / th >
< td class = "text-right" > {{connections['total'].inbps | metric}}bps ({{connections['total'].InBytesTotal | binary}}B)< / td >
< / tr >
< tr >
< th > < span class = "glyphicon glyphicon-cloud-upload" > < / span >   Upload Rate< / th >
< td class = "text-right" > {{connections['total'].outbps | metric}}bps ({{connections['total'].OutBytesTotal | binary}}B)< / td >
< / tr >
< tr ng-if = "system.extAnnounceOK != undefined" >
< th > < span class = "glyphicon glyphicon-bullhorn" > < / span >   Announce Server< / th >
< td class = "text-right" >
< span class = "data text-success" ng-if = "system.extAnnounceOK" > Online< / span >
< span class = "data text-danger" ng-if = "!system.extAnnounceOK" > Offline< / span >
< / td >
< / tr >
< tr >
< th > < span class = "glyphicon glyphicon-tag" > < / span >   Version< / th >
< td class = "text-right" > {{version}}< / td >
< / tr >
< / tbody >
< / table >
< / div >
< span class = "pull-right" > < a class = "btn btn-sm btn-primary" href = "" ng-click = "editNode(nodeCfg)" > < span class = "glyphicon glyphicon-pencil" > < / span >   Edit< / a > < / span >
< / div >
2014-05-20 17:36:37 +00:00
< / div >
< / div >
2014-04-09 21:00:23 +00:00
2014-05-24 19:56:09 +00:00
< div class = "panel panel-{{nodeClass(nodeCfg)}}" ng-repeat = "nodeCfg in otherNodes()" >
< div class = "panel-heading" >
< h3 class = "panel-title" >
2014-06-02 21:30:53 +00:00
< a data-toggle = "collapse" data-parent = "#nodes" href = "#node-{{$index}}" >
2014-05-24 19:56:09 +00:00
< span class = "glyphicon glyphicon-retweet" > < / span >
{{nodeName(nodeCfg)}}
< span class = "pull-right hidden-xs" > {{nodeStatus(nodeCfg)}}< / span >
< / a >
< / h3 >
< / div >
2014-06-02 21:30:53 +00:00
< div id = "node-{{$index}}" class = "panel-collapse collapse" >
2014-05-24 19:56:09 +00:00
< div class = "panel-body" >
< div class = "table-responsive" >
< table class = "table table-condensed table-striped" >
< tbody >
< tr >
< th > < span class = "glyphicon glyphicon-link" > < / span >   Address< / th >
< td class = "text-right" > {{nodeAddr(nodeCfg)}}< / td >
< / tr >
< tr >
< th > < span class = "glyphicon glyphicon-comment" > < / span >   Synchronization< / th >
< td class = "text-right" > {{nodeStatus(nodeCfg)}}< / td >
< / tr >
< tr >
< th > < span class = "glyphicon glyphicon-cloud-download" > < / span >   Download Rate< / th >
< td class = "text-right" > {{connections[nodeCfg.NodeID].inbps | metric}}bps ({{connections[nodeCfg.NodeID].InBytesTotal | binary}}B)< / td >
< / tr >
< tr >
< th > < span class = "glyphicon glyphicon-cloud-upload" > < / span >   Upload Rate< / th >
< td class = "text-right" > {{connections[nodeCfg.NodeID].outbps | metric}}bps ({{connections[nodeCfg.NodeID].OutBytesTotal | binary}}B)< / td >
< / tr >
< tr >
< th > < span class = "glyphicon glyphicon-tag" > < / span >   Version< / th >
< td class = "text-right" > {{nodeVer(nodeCfg)}}< / td >
< / tr >
< / tbody >
< / table >
< / div >
< span class = "pull-right" > < a class = "btn btn-sm btn-primary" href = "" ng-click = "editNode(nodeCfg)" > < span class = "glyphicon glyphicon-pencil" > < / span >   Edit< / a > < / span >
< / div >
2014-05-20 17:36:37 +00:00
< / div >
2014-04-09 21:00:23 +00:00
< / div >
2014-01-05 22:54:57 +00:00
< / div >
2014-04-09 21:00:23 +00:00
< / div >
< / div > <!-- /row -->
<!-- Errors -->
< div ng-if = "errorList().length > 0" class = "row" >
< div class = "col-md-12" >
< div class = "panel panel-warning" >
< div class = "panel-heading" > < h3 class = "panel-title" > Notice< / h3 > < / div >
< div class = "panel-body" >
2014-04-22 13:59:16 +00:00
< p ng-repeat = "err in errorList()" > < small > {{err.Time | date:"H:mm:ss"}}:< / small > {{friendlyNodes(err.Error)}}< / p >
2014-04-09 21:00:23 +00:00
< / div >
< div class = "panel-footer" >
2014-05-21 13:37:28 +00:00
< button type = "button" class = "pull-right btn btn-sm btn-default" ng-click = "clearErrors()" > < span class = "glyphicon glyphicon-ok" > < / span >   OK< / button >
2014-04-09 21:00:23 +00:00
< div class = "clearfix" > < / div >
< / div >
< / div >
< / div >
2014-01-05 22:54:57 +00:00
< / div >
2014-02-12 11:10:44 +00:00
2014-04-09 21:00:23 +00:00
< / div > <!-- /container -->
<!-- Bottom bar -->
< nav class = "navbar navbar-default navbar-fixed-bottom hidden-xs" >
2014-02-12 11:10:44 +00:00
< div class = "container" >
2014-05-20 17:36:37 +00:00
< ul class = "nav navbar-nav" >
2014-04-09 21:00:23 +00:00
< li > < a class = "navbar-link" href = "http://discourse.syncthing.net/" > Support / Forum< / a > < / li >
2014-05-20 17:36:37 +00:00
< li > < a class = "navbar-link" href = "https://github.com/calmh/syncthing/releases" > Latest Release< / a > < / li >
2014-05-14 07:32:11 +00:00
< li > < a class = "navbar-link" href = "http://discourse.syncthing.net/category/documentation" > Documentation< / a > < / li >
2014-05-20 17:36:37 +00:00
< li > < a class = "navbar-link" href = "https://github.com/calmh/syncthing/issues" > Bugs< / a > < / li >
< li > < a class = "navbar-link" href = "https://github.com/calmh/syncthing" > Source Code< / a > < / li >
2014-04-09 21:00:23 +00:00
< / ul >
2014-02-12 11:10:44 +00:00
< / div >
2014-04-09 21:00:23 +00:00
< / nav >
<!-- Network error modal -->
2014-01-05 22:54:57 +00:00
2014-04-09 21:00:23 +00:00
< div id = "networkError" class = "modal fade" >
2014-01-09 09:31:27 +00:00
< div class = "modal-dialog" >
2014-04-09 21:00:23 +00:00
< div class = "modal-content" >
< div class = "modal-header alert alert-danger" >
< h4 class = "modal-title" >
< span class = "glyphicon glyphicon-exclamation-sign" > < / span >
Connection Error
< / h4 >
< / div >
< div class = "modal-body" >
< p >
Syncthing seems to be down, or there is a problem with your Internet connection.
Retrying…
< / p >
< / div >
< / div >
< / div >
< / div >
2014-04-16 13:16:44 +00:00
<!-- Restarting modal -->
< div id = "restarting" class = "modal fade" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header alert alert-info" >
< h4 class = "modal-title" >
< span class = "glyphicon glyphicon-refresh" > < / span >
Restarting
< / h4 >
< / div >
< div class = "modal-body" >
< p >
Syncthing is restarting. Please hold…
< / p >
< / div >
< / div >
< / div >
< / div >
2014-05-21 17:35:56 +00:00
<!-- Shutdown modal -->
< div id = "shutdown" class = "modal fade" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header alert alert-success" >
< h4 class = "modal-title" >
< span class = "glyphicon glyphicon-off" > < / span >
Shutdown Complete
< / h4 >
< / div >
< div class = "modal-body" >
< p >
Syncthing has been shut down.
< / p >
< / div >
< / div >
< / div >
< / div >
2014-05-21 18:06:14 +00:00
<!-- ID modal -->
< div id = "idqr" class = "modal fade" >
< div class = "modal-dialog modal-lg" >
< div class = "modal-content" >
< div class = "modal-header" >
< h4 class = "modal-title" >
< span class = "glyphicon glyphicon-qrcode" > < / span >
Node Identification — {{nodeName(thisNode())}}
< / h4 >
< / div >
< div class = "modal-body" >
2014-06-05 09:29:05 +00:00
< div class = "well well-sm text-monospace text-center" > {{myID | chunkID}}< / div >
2014-05-24 19:56:09 +00:00
< img ng-if = "myID" class = "center-block img-thumbnail" src = "qr/{{myID | chunkID}}" / >
2014-05-21 18:06:14 +00:00
< / div >
< div class = "modal-footer" >
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > < span class = "glyphicon glyphicon-remove" > < / span >   Close< / button >
2014-05-24 19:56:09 +00:00
< / div >
2014-05-21 18:06:14 +00:00
< / div >
< / div >
< / div >
2014-04-09 21:00:23 +00:00
<!-- Node editor modal -->
< div id = "editNode" class = "modal fade" >
< div class = "modal-dialog modal-lg" >
< div class = "modal-content" >
< div class = "modal-header" >
< h4 ng-show = "!editingExisting" class = "modal-title" > Add Node< / h4 >
< h4 ng-show = "editingExisting" class = "modal-title" > Edit Node< / h4 >
< / div >
< div class = "modal-body" >
2014-05-14 10:55:00 +00:00
< form role = "form" name = "nodeEditor" >
< div class = "form-group" ng-class = "{'has-error': nodeEditor.nodeID.$invalid && nodeEditor.nodeID.$dirty}" >
2014-04-09 21:00:23 +00:00
< label for = "nodeID" > Node ID< / label >
2014-05-28 03:16:11 +00:00
< input ng-if = "!editingExisting" name = "nodeID" id = "nodeID" class = "form-control text-monospace" type = "text" ng-model = "currentNode.NodeID" required valid-nodeid > < / input >
2014-05-18 10:05:17 +00:00
< div ng-if = "editingExisting" class = "well well-sm text-monospace" > {{currentNode.NodeID | chunkID}}< / div >
2014-05-14 10:55:00 +00:00
< p class = "help-block" >
2014-05-21 18:06:14 +00:00
< span ng-if = "nodeEditor.nodeID.$valid || nodeEditor.nodeID.$pristine" > The node ID to enter here can be found in the "Edit > Show ID" dialog on the other node. Spaces and dashes are optional (ignored).
2014-05-24 19:56:09 +00:00
< span ng-show = "!editingExisting" > When adding a new node, keep in mind that < em > this node< / em > must be added on the other side too.< / span >
2014-05-21 18:06:14 +00:00
< / span >
2014-05-14 10:55:00 +00:00
< span ng-if = "nodeEditor.nodeID.$error.required && nodeEditor.nodeID.$dirty" > The node ID cannot be blank.< / span >
2014-05-28 03:16:11 +00:00
< span ng-if = "nodeEditor.nodeID.$error.validNodeid && nodeEditor.nodeID.$dirty" > The entered node ID does not look valid. It should be a 52 character string consisting of letters and numbers, with spaces and dashes being optional.< / span >
2014-05-14 10:55:00 +00:00
< / p >
2014-04-09 21:00:23 +00:00
< / div >
< div class = "form-group" >
2014-06-10 11:46:29 +00:00
< label for = "name" > Node Name< / label >
2014-04-09 21:00:23 +00:00
< input placeholder = "Home Server" id = "name" class = "form-control" type = "text" ng-model = "currentNode.Name" > < / input >
< p class = "help-block" > Shown instead of Node ID in the cluster status.< / p >
2014-01-09 09:31:27 +00:00
< / div >
2014-04-09 21:00:23 +00:00
< div class = "form-group" >
< label for = "addresses" > Addresses< / label >
< input placeholder = "dynamic" ng-disabled = "currentNode.NodeID == myID" id = "addresses" class = "form-control" type = "text" ng-model = "currentNode.AddressesStr" > < / input >
< p class = "help-block" > Enter comma separated < span class = "text-monospace" > ip:port< / span > addresses or < span class = "text-monospace" > dynamic< / span > to perform automatic discovery of the address.< / p >
2014-01-09 09:31:27 +00:00
< / div >
2014-04-09 21:00:23 +00:00
< / form >
< / div >
< div class = "modal-footer" >
2014-05-21 13:37:28 +00:00
< button type = "button" class = "btn btn-primary" ng-click = "saveNode()" ng-disabled = "nodeEditor.$invalid" > < span class = "glyphicon glyphicon-ok" > < / span >   Save< / button >
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > < span class = "glyphicon glyphicon-remove" > < / span >   Close< / button >
< button ng-if = "editingExisting && !editingSelf" type = "button" class = "btn btn-danger pull-left" ng-click = "deleteNode()" > < span class = "glyphicon glyphicon-minus" > < / span >   Delete< / button >
2014-01-09 09:31:27 +00:00
< / div >
2014-04-09 21:00:23 +00:00
< / div >
2014-01-09 09:31:27 +00:00
< / div >
2014-04-09 21:00:23 +00:00
< / div >
2014-01-09 09:31:27 +00:00
2014-04-09 21:00:23 +00:00
<!-- Repo editor modal -->
< div id = "editRepo" class = "modal fade" >
2014-02-01 19:23:19 +00:00
< div class = "modal-dialog modal-lg" >
2014-04-09 21:00:23 +00:00
< div class = "modal-content" >
< div class = "modal-header" >
< h4 ng-show = "!editingExisting" class = "modal-title" > Add Repository< / h4 >
< h4 ng-show = "editingExisting" class = "modal-title" > Edit Repository< / h4 >
< / div >
< div class = "modal-body" >
2014-05-14 10:55:00 +00:00
< form role = "form" name = "repoEditor" >
2014-05-25 18:49:08 +00:00
< div class = "row" >
< div class = "col-md-12" >
< div class = "form-group" ng-class = "{'has-error': repoEditor.repoID.$invalid && repoEditor.repoID.$dirty}" >
< label for = "repoID" > Repository ID< / label >
2014-06-02 05:21:22 +00:00
< input name = "repoID" placeholder = "documents" ng-disabled = "editingExisting" id = "repoID" class = "form-control" type = "text" ng-model = "currentRepo.ID" required unique-repo ng-pattern = "/^[a-zA-Z0-9-_.]{1,64}$/" > < / input >
2014-05-25 18:49:08 +00:00
< p class = "help-block" >
< span ng-if = "repoEditor.repoID.$valid || repoEditor.repoID.$pristine" > Short identifier for the repository. Must be the same on all cluster nodes.< / span >
< span ng-if = "repoEditor.repoID.$error.uniqueRepo" > The repository ID must be unique.< / span >
< span ng-if = "repoEditor.repoID.$error.required && repoEditor.repoID.$dirty" > The repository ID cannot be blank.< / span >
2014-05-28 03:16:11 +00:00
< span ng-if = "repoEditor.repoID.$error.pattern && repoEditor.repoID.$dirty" > The repository ID must be a short identifier (64 characters or less) consisting of letters, numbers and the the < code > -_.< / code > characters only.< / span >
2014-05-25 18:49:08 +00:00
< / p >
< / div >
< div class = "form-group" ng-class = "{'has-error': repoEditor.repoPath.$invalid && repoEditor.repoPath.$dirty}" >
< label for = "repoPath" > Repository Path< / label >
< input name = "repoPath" placeholder = "~/Documents" id = "repoPath" class = "form-control" type = "text" ng-model = "currentRepo.Directory" required > < / input >
< p class = "help-block" >
< span ng-if = "repoEditor.repoPath.$valid || repoEditor.repoPath.$pristine" > Path to the repository on the local computer. Will be created if it does not exist. The tilde character < code > ~< / code > can be used as a shortcut for < code > {{system.tilde}}< / code > .< / span >
< span ng-if = "repoEditor.repoPath.$error.required && repoEditor.repoPath.$dirty" > The repository path cannot be blank.< / span >
< / p >
< / div >
2014-04-09 21:00:23 +00:00
< / div >
< / div >
2014-05-25 18:49:08 +00:00
< div class = "row" >
< div class = "col-md-6" >
< div class = "form-group" >
< div class = "checkbox" >
< label >
< input type = "checkbox" ng-model = "currentRepo.ReadOnly" > Repository Master
< / label >
< / div >
< p class = "help-block" > Files are protected from changes made on other nodes, but changes made on < em > this< / em > node will be sent to the rest of the cluster.< / p >
< / div >
< div class = "form-group" >
< div class = "checkbox" >
< label >
< input type = "checkbox" ng-model = "currentRepo.IgnorePerms" > Ignore Permissions
< / label >
< / div >
< p class = "help-block" > File permission bits are ignored when looking for changes. Use on FAT filesystems.< / p >
< / div >
< div class = "form-group" >
2014-06-04 13:05:23 +00:00
< label for = "nodes" > Share With Nodes< / label >
2014-05-25 18:49:08 +00:00
< div class = "checkbox" ng-repeat = "node in otherNodes()" >
< label >
< input type = "checkbox" ng-model = "currentRepo.selectedNodes[node.NodeID]" > {{nodeName(node)}}
< / label >
< / div >
< p class = "help-block" > Select the nodes to share this repository with.< / p >
< / div >
2014-05-23 12:31:16 +00:00
< / div >
2014-05-25 18:49:08 +00:00
< div class = "col-md-6" >
< div class = "form-group" >
< div class = "checkbox" >
< label >
2014-05-28 08:03:56 +00:00
< input type = "checkbox" ng-model = "currentRepo.simpleFileVersioning" > File Versioning
2014-05-25 18:49:08 +00:00
< / label >
< / div >
< p class = "help-block" > Files are moved to date stamped versions in a < code > .stversions< / code > folder when replaced or deleted by syncthing.< / p >
< / div >
< div class = "form-group" ng-if = "currentRepo.simpleFileVersioning" ng-class = "{'has-error': repoEditor.simpleKeep.$invalid && repoEditor.simpleKeep.$dirty}" >
< label for = "simpleKeep" > Keep Versions< / label >
< input name = "simpleKeep" id = "simpleKeep" class = "form-control" type = "number" ng-model = "currentRepo.simpleKeep" required min = "1" > < / input >
< p class = "help-block" >
< span ng-if = "repoEditor.simpleKeep.$valid || repoEditor.simpleKeep.$pristine" > The number of old versions to keep, per file.< / span >
< span ng-if = "repoEditor.simpleKeep.$error.required && repoEditor.simpleKeep.$dirty" > The number of versions must be a number and cannot be blank.< / span >
< span ng-if = "repoEditor.simpleKeep.$error.min && repoEditor.simpleKeep.$dirty" > You must keep at least one version.< / span >
< / p >
< / div >
2014-04-09 21:00:23 +00:00
< / div >
2014-02-01 19:23:19 +00:00
< / div >
2014-04-09 21:00:23 +00:00
< / form >
< div ng-show = "!editingExisting" >
When adding a new repository, keep in mind that the Repository ID is used to tie repositories together between nodes. They are case sensitive and must match exactly between all nodes.
< / div >
< / div >
< div class = "modal-footer" >
2014-05-21 13:37:28 +00:00
< button type = "button" class = "btn btn-primary" ng-click = "saveRepo()" ng-disabled = "repoEditor.$invalid" > < span class = "glyphicon glyphicon-ok" > < / span >   Save< / button >
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > < span class = "glyphicon glyphicon-remove" > < / span >   Close< / button >
< button ng-if = "editingExisting" type = "button" class = "btn btn-danger pull-left" ng-click = "deleteRepo()" > < span class = "glyphicon glyphicon-minus" > < / span >   Delete< / button >
2014-04-09 21:00:23 +00:00
< / div >
< / div >
< / div >
< / div >
<!-- Settings modal -->
< div id = "settings" class = "modal fade" >
< div class = "modal-dialog modal-lg" >
< div class = "modal-content" >
< div class = "modal-header" >
< h4 class = "modal-title" > Settings< / h4 >
< / div >
< div class = "modal-body" >
< form role = "form" >
< div class = "row" >
< div class = "col-md-6" >
< div class = "form-group" ng-repeat = "setting in settings" >
< div ng-if = "setting.type == 'text' || setting.type == 'number'" >
< label for = "{{setting.id}}" > {{setting.descr}}< / label >
2014-05-21 19:54:16 +00:00
< input id = "{{setting.id}}" class = "form-control" type = "{{setting.type}}" ng-model = "config.workingOptions[setting.id]" > < / input >
2014-04-09 21:00:23 +00:00
< / div >
< div class = "checkbox" ng-if = "setting.type == 'bool'" >
< label >
2014-05-21 19:54:16 +00:00
{{setting.descr}} < input id = "{{setting.id}}" type = "checkbox" ng-model = "config.workingOptions[setting.id]" > < / input >
2014-04-09 21:00:23 +00:00
< / label >
< / div >
< / div >
< / div >
< div class = "col-md-6" >
< div class = "form-group" ng-repeat = "setting in guiSettings" >
< div ng-if = "setting.type == 'text' || setting.type == 'number' || setting.type == 'password'" >
< label for = "{{setting.id}}" > {{setting.descr}}< / label >
2014-05-21 19:54:16 +00:00
< input id = "{{setting.id}}" class = "form-control" type = "{{setting.type}}" ng-model = "config.workingGUI[setting.id]" > < / input >
2014-04-09 21:00:23 +00:00
< / div >
< div class = "checkbox" ng-if = "setting.type == 'bool'" >
< label >
2014-05-21 19:54:16 +00:00
{{setting.descr}} < input id = "{{setting.id}}" type = "checkbox" ng-model = "config.workingGUI[setting.id]" > < / input >
2014-04-09 21:00:23 +00:00
< / label >
< / div >
2014-06-04 20:00:55 +00:00
< div ng-if = "setting.type == 'apikey'" >
< label > {{setting.descr}} (< a href = "http://discourse.syncthing.net/t/v0-8-14-api-keys/335" > Usage< / a > )< / label >
< div class = "well well-sm text-monospace" > {{config.workingGUI[setting.id] || "-"}}< / div >
< button type = "button" class = "btn btn-sm btn-default" ng-click = "setAPIKey(config.workingGUI)" > Generate< / button >
< / div >
2014-04-09 21:00:23 +00:00
< / div >
< / div >
2014-02-01 19:23:19 +00:00
< / div >
2014-04-09 21:00:23 +00:00
< / form >
2014-02-01 19:23:19 +00:00
< / div >
2014-04-09 21:00:23 +00:00
< div class = "modal-footer" >
2014-05-21 13:37:28 +00:00
< button type = "button" class = "btn btn-primary" ng-click = "saveSettings()" > < span class = "glyphicon glyphicon-ok" > < / span >   Save< / button >
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > < span class = "glyphicon glyphicon-remove" > < / span >   Close< / button >
2014-04-09 21:00:23 +00:00
< / div >
< / div >
2014-02-01 19:23:19 +00:00
< / div >
2014-04-09 21:00:23 +00:00
< / div >
2014-02-01 19:23:19 +00:00
2014-04-09 21:00:23 +00:00
< script src = "angular.min.js" > < / script >
< script src = "jquery-2.0.3.min.js" > < / script >
< script src = "bootstrap/js/bootstrap.min.js" > < / script >
< script src = "app.js" > < / script >
2014-01-05 22:54:57 +00:00
< / body >
< / html >