editDeviceModalView.html 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. <modal id="editDevice" status="default" icon="{{editDeviceModalIcon()}}" heading="{{editDeviceModalTitle()}}" large="yes" closeable="yes">
  2. <div class="modal-body">
  3. <form role="form" name="deviceEditor">
  4. <ul class="nav nav-tabs" ng-init="loadFormIntoScope(deviceEditor)">
  5. <li class="active"><a data-toggle="tab" href="#device-general"><span class="fas fa-cog"></span> <span translate>General</span></a></li>
  6. <li ng-if="!editingDeviceDefaults()"><a data-toggle="tab" href="#device-sharing"><span class="fas fa-share-alt"></span> <span translate>Sharing</span></a></li>
  7. <li><a data-toggle="tab" href="#device-advanced"><span class="fas fa-cogs"></span> <span translate>Advanced</span></a></li>
  8. </ul>
  9. <div class="tab-content">
  10. <div id="device-general" class="tab-pane in active">
  11. <div ng-if="!editingDeviceDefaults()" class="form-group" ng-class="{'has-error': deviceEditor.deviceID.$invalid && deviceEditor.deviceID.$dirty}" ng-init="loadFormIntoScope(deviceEditor)">
  12. <label translate for="deviceID">Device ID</label>
  13. <div class="input-group">
  14. <input ng-if="editingDeviceNew()" name="deviceID" id="deviceID" class="form-control text-monospace" type="text" ng-model="currentDevice.deviceID" required="" valid-deviceid list="discovery-list" aria-required="true" />
  15. <div ng-if="!editingDeviceNew()" class="well well-sm form-control text-monospace" style="height: auto;" select-on-click>{{currentDevice.deviceID}}</div>
  16. <div id="shareDeviceIdButtons" class="input-group-btn">
  17. <button type="button" class="btn btn-default" ng-click="copyToClipboard($event, currentDevice.deviceID)" ng-disabled="editingDeviceNew() && !deviceEditor.deviceID.$valid" tooltip data-original-title="{{ 'Copy' | translate }}">
  18. <span class="fa fa-lg fa-clone"></span>
  19. </button>
  20. <button type="button" class="btn btn-default" ng-click="shareDeviceIdDialog('email')" ng-disabled="editingDeviceNew() && !deviceEditor.deviceID.$valid" tooltip data-original-title="{{ 'Share by Email' | translate }}">
  21. <span class="fa fa-lg fa-envelope-o"></span>
  22. </button>
  23. <button type="button" class="btn btn-default" ng-click="shareDeviceIdDialog('sms')" ng-disabled="editingDeviceNew() && !deviceEditor.deviceID.$valid" tooltip data-original-title="{{ 'Share by SMS' | translate }}">
  24. <span class="fa fa-lg fa-comments-o"></span>
  25. </button>
  26. <button type="button" class="btn btn-default" data-toggle="modal" data-target="#idqr" ng-disabled="editingDeviceNew() && !deviceEditor.deviceID.$valid" tooltip data-original-title="{{ 'Show QR' | translate }}">
  27. <span class="fa fa-lg fa-qrcode"></span>
  28. </button>
  29. </div>
  30. </div>
  31. <div ng-if="editingDeviceNew()">
  32. <datalist id="discovery-list">
  33. <option ng-repeat="id in discoveryUnknown" value="{{id}}" />
  34. </datalist>
  35. <div class="help-block" ng-if="discoveryUnknown && discoveryUnknown.length !== 0">
  36. <span translate>You can also select one of these nearby devices:</span>
  37. <ul>
  38. <li ng-repeat="id in discoveryUnknown.slice(0, 5)" style="list-style-type: none;">
  39. <a href="#" ng-click="currentDevice.deviceID = id">
  40. <identicon data-value="id"></identicon>&nbsp;&nbsp;{{id}}
  41. </a>
  42. </li>
  43. </ul>
  44. </div>
  45. <p class="help-block">
  46. <span translate ng-if="deviceEditor.deviceID.$valid || deviceEditor.deviceID.$pristine">The device ID to enter here can be found in the "Actions &gt; Show ID" dialog on the other device. Spaces and dashes are optional (ignored).</span>
  47. <span translate ng-show="deviceEditor.deviceID.$valid || deviceEditor.deviceID.$pristine">When adding a new device, keep in mind that this device must be added on the other side too.</span>
  48. <span translate ng-if="deviceEditor.deviceID.$error.required && deviceEditor.deviceID.$dirty">The device ID cannot be blank.</span>
  49. <span translate ng-if="deviceEditor.deviceID.$error.validDeviceid && deviceEditor.deviceID.$dirty">The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.</span>
  50. <span translate ng-if="deviceEditor.deviceID.$error.unique && deviceEditor.deviceID.$dirty">A device with that ID is already added.</span>
  51. </p>
  52. </div>
  53. </div>
  54. <div class="form-group">
  55. <label translate for="name">Device Name</label>
  56. <input id="name" class="form-control" type="text" ng-model="currentDevice.name" />
  57. <p translate ng-if="currentDevice.deviceID == myID" class="help-block">Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.</p>
  58. <p translate ng-if="currentDevice.deviceID != myID" class="help-block">Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.</p>
  59. </div>
  60. </div>
  61. <div ng-if="!editingDeviceDefaults()" id="device-sharing" class="tab-pane">
  62. <div class="row">
  63. <div class="col-md-6">
  64. <div class="form-group">
  65. <div ng-disabled="currentDevice.untrusted" class="checkbox" ng-attr-tooltip="{{currentDevice.untrusted ? null : undefined}}" ng-attr-data-original-title="{{currentDevice.untrusted ? ('Always disabled for untrusted devices' | translate) : undefined}}">
  66. <label>
  67. <input ng-disabled="currentDevice.untrusted" type="checkbox" ng-model="currentDevice.introducer">
  68. <span translate>Introducer</span>
  69. <p translate class="help-block">Add devices from the introducer to our device list, for mutually shared folders.</p>
  70. </label>
  71. </div>
  72. </div>
  73. </div>
  74. <div class="col-md-6">
  75. <div class="form-group">
  76. <div ng-disabled="currentDevice.untrusted" class="checkbox" ng-attr-tooltip="{{currentDevice.untrusted ? null : undefined}}" ng-attr-data-original-title="{{currentDevice.untrusted ? ('Always disabled for untrusted devices' | translate) : undefined}}">
  77. <label>
  78. <input ng-disabled="currentDevice.untrusted" type="checkbox" ng-model="currentDevice.autoAcceptFolders">
  79. <span translate>Auto Accept</span>
  80. <p translate class="help-block">Automatically create or share folders that this device advertises at the default path.</p>
  81. </label>
  82. </div>
  83. </div>
  84. </div>
  85. </div>
  86. <div class="form-group">
  87. <div class="form-horizontal" ng-if="currentSharing.shared.length">
  88. <label translate for="folders">Shared Folders</label>
  89. <p class="help-block">
  90. <span translate>Deselect folders to stop sharing with this device.</span>&emsp;
  91. <small><a href="#" ng-click="selectAllSharedFolders(true)" translate>Select All</a>&emsp;
  92. <a href="#" ng-click="selectAllSharedFolders(false)" translate>Deselect All</a></small>
  93. </p>
  94. <div class="form-group" ng-repeat="folder in currentSharing.shared">
  95. <share-template selected="currentSharing.selected" encryption-passwords="currentSharing.encryptionPasswords" id="{{folder.id}}" label="{{folderLabel(folder.id)}}" folder-type="{{folder.type}}" untrusted="currentDevice.untrusted" remote-state="{{completion[currentDevice.deviceID][folder.id].remoteState}}" />
  96. </div>
  97. <p class="help-block" ng-if="deviceHasUnacceptedFolders(currentDevice)">
  98. <sup>1</sup> <span translate>The remote device has not accepted sharing this folder.</span>
  99. </p>
  100. <p class="help-block" ng-if="deviceHasPausedFolders(currentDevice)">
  101. <sup>2</sup> <span translate>The remote device has paused this folder.</span>
  102. </p>
  103. </div>
  104. <div class="form-horizontal" ng-if="currentSharing.unrelated.length">
  105. <label translate for="folders">Unshared Folders</label>
  106. <p class="help-block" ng-if="folderList().length > 0">
  107. <span translate>Select additional folders to share with this device.</span>&emsp;
  108. <small><a href="#" ng-click="selectAllUnrelatedFolders(true)" translate>Select All</a>&emsp;
  109. <a href="#" ng-click="selectAllUnrelatedFolders(false)" translate>Deselect All</a></small>
  110. </p>
  111. <p class="help-block" ng-if="folderList().length == 0">
  112. <span translate>There are no folders to share with this device.</span>
  113. </p>
  114. <div class="form-group" ng-repeat="folder in currentSharing.unrelated">
  115. <share-template selected="currentSharing.selected" encryption-passwords="currentSharing.encryptionPasswords" id="{{folder.id}}" label="{{folderLabel(folder.id)}}" folder-type="{{folder.type}}" untrusted="currentDevice.untrusted" />
  116. </div>
  117. </div>
  118. </div>
  119. </div>
  120. <div id="device-advanced" class="tab-pane">
  121. <div class="row form-group">
  122. <div class="col-md-6">
  123. <div class="form-group">
  124. <label translate for="addresses">Addresses</label>
  125. <input ng-disabled="currentDevice.deviceID == myID" id="addresses" class="form-control" type="text" ng-model="currentDevice._addressesStr"></input>
  126. <p translate class="help-block">Enter comma separated ("tcp://ip:port", "tcp://host:port") addresses or "dynamic" to perform automatic discovery of the address.</p>
  127. </div>
  128. </div>
  129. <div class="col-md-6">
  130. <div class="form-group">
  131. <label translate>Compression</label>
  132. <select class="form-control" ng-model="currentDevice.compression">
  133. <option value="always" translate>All Data</option>
  134. <option value="metadata" translate>Metadata Only</option>
  135. <option value="never" translate>Off</option>
  136. </select>
  137. </div>
  138. </div>
  139. </div>
  140. <div class="row form-group">
  141. <div class="col-md-12">
  142. <label translate>Device rate limits</label>
  143. <div class="row">
  144. <div class="col-md-6" ng-class="{'has-error': deviceEditor.maxRecvKbps.$invalid && deviceEditor.maxRecvKbps.$dirty}">
  145. <div class="row">
  146. <span class="col-md-8" translate>Incoming Rate Limit (KiB/s)</span>
  147. <div class="col-md-4">
  148. <input name="maxRecvKbps" id="maxRecvKbps" class="form-control" type="number" pattern="\d+" ng-model="currentDevice.maxRecvKbps" min="0" />
  149. </div>
  150. </div>
  151. <p class="help-block" ng-if="!deviceEditor.maxRecvKbps.$valid && deviceEditor.maxRecvKbps.$dirty" translate>The rate limit must be a non-negative number (0: no limit)</p>
  152. </div>
  153. <div class="col-md-6" ng-class="{'has-error': deviceEditor.maxSendKbps.$invalid && deviceEditor.maxSendKbps.$dirty}">
  154. <div class="row">
  155. <span class="col-md-8" translate>Outgoing Rate Limit (KiB/s)</span>
  156. <div class="col-md-4">
  157. <input name="maxSendKbps" id="maxSendKbps" class="form-control" type="number" pattern="\d+" ng-model="currentDevice.maxSendKbps" min="0" />
  158. </div>
  159. </div>
  160. <p class="help-block" ng-if="!deviceEditor.maxSendKbps.$valid && deviceEditor.maxSendKbps.$dirty" translate>The rate limit must be a non-negative number (0: no limit)</p>
  161. </div>
  162. </div>
  163. </div>
  164. </div>
  165. <div class="row">
  166. <div class="form-group col-md-6">
  167. <input type="checkbox" id="untrusted" ng-model="currentDevice.untrusted" ng-change="editDeviceUntrustedChanged()"/>
  168. <label for="untrusted" translate>Untrusted</label>
  169. <p translate class="help-block">All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.</p>
  170. </div>
  171. </div>
  172. </div>
  173. </div>
  174. </form>
  175. </div>
  176. <div class="modal-footer">
  177. <button type="button" class="btn btn-primary btn-sm" ng-click="saveDevice()" ng-disabled="deviceEditor.$invalid">
  178. <span class="fas fa-check"></span>&nbsp;<span translate>Save</span>
  179. </button>
  180. <button type="button" class="btn btn-default btn-sm" data-dismiss="modal">
  181. <span class="fas fa-times"></span>&nbsp;<span translate>Close</span>
  182. </button>
  183. <div ng-if="editingDeviceExisting()" class="pull-left">
  184. <button type="button" class="btn btn-warning btn-sm" data-toggle="modal" data-target="#remove-device-confirmation">
  185. <span class="fas fa-minus-circle"></span>&nbsp;<span translate>Remove</span>
  186. </button>
  187. </div>
  188. </div>
  189. </modal>