Copied over from settings. Moves ignore patterns from its own modal into a tab of the folder edit modal. Advanced settings are in a tab instead of a expandable section and versioning gets it's own tab. Also added modal hidden event handler to remove the anchor in the url.
216 lines
18 KiB
HTML
216 lines
18 KiB
HTML
<modal id="editFolder" status="default" icon="{{editingExisting ? 'pencil' : 'folder'}}" heading="{{editingExisting ? 'Edit Folder' : 'Add Folder' | translate}}" large="yes" closeable="yes">
|
|
<div class="modal-body">
|
|
<form role="form" name="folderEditor">
|
|
<ul class="nav nav-tabs" ng-init="loadFormIntoScope(folderEditor)">
|
|
<li class="active"><a data-toggle="tab" href="#folder-general" translate>General</a></li>
|
|
<li><a data-toggle="tab" href="#folder-versioning" translate>File Versioning</a></li>
|
|
<li><a data-toggle="tab" href="#folder-ignores" translate>Ignore Patterns</a></li>
|
|
<li><a data-toggle="tab" href="#folder-advanced" translate>Advanced</a></li>
|
|
</ul>
|
|
<div class="tab-content">
|
|
<div id="folder-general" class="tab-pane in active">
|
|
<div class="form-group" ng-class="{'has-error': folderEditor.folderLabel.$invalid && folderEditor.folderLabel.$dirty}">
|
|
<label for="folderLabel"><span translate>Folder Label</span></label>
|
|
<input name="folderLabel" id="folderLabel" class="form-control" type="text" ng-model="currentFolder.label" value="{{currentFolder.label}}"/>
|
|
<p class="help-block">
|
|
<span translate ng-if="folderEditor.folderLabel.$valid || folderEditor.folderLabel.$pristine">Optional descriptive label for the folder. Can be different on each device.</span>
|
|
</p>
|
|
</div>
|
|
<div class="form-group" ng-class="{'has-error': folderEditor.folderID.$invalid && folderEditor.folderID.$dirty}">
|
|
<label for="folderID"><span translate>Folder ID</span></label>
|
|
<input name="folderID" ng-readonly="editingExisting || (!editingExisting && currentFolder.viewFlags.importFromOtherDevice)" id="folderID" class="form-control" type="text" ng-model="currentFolder.id" required="" aria-required="true" unique-folder value="{{currentFolder.id}}"/>
|
|
<p class="help-block">
|
|
<span translate ng-if="folderEditor.folderID.$valid || folderEditor.folderID.$pristine">Required identifier for the folder. Must be the same on all cluster devices.</span>
|
|
<span translate ng-if="folderEditor.folderID.$error.uniqueFolder">The folder ID must be unique.</span>
|
|
<span translate ng-if="folderEditor.folderID.$error.required && folderEditor.folderID.$dirty">The folder ID cannot be blank.</span>
|
|
</p>
|
|
</div>
|
|
<div class="form-group" ng-class="{'has-error': folderEditor.folderPath.$invalid && folderEditor.folderPath.$dirty}">
|
|
<label translate for="folderPath">Folder Path</label>
|
|
<input name="folderPath" ng-readonly="editingExisting" id="folderPath" class="form-control" type="text" ng-model="currentFolder.path" list="directory-list" required="" aria-required="true" path-is-sub-dir/>
|
|
<datalist id="directory-list">
|
|
<option ng-repeat="directory in directoryList" value="{{ directory }}" />
|
|
</datalist>
|
|
<p class="help-block">
|
|
<span ng-if="folderEditor.folderPath.$valid || folderEditor.folderPath.$pristine"><span translate>Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for</span> <code>{{system.tilde}}</code>.</br></span>
|
|
<span translate ng-if="folderEditor.folderPath.$error.required && folderEditor.folderPath.$dirty">The folder path cannot be blank.</span>
|
|
<span class="text-danger" translate translate-value-other-folder="{{folderPathErrors.otherID}}" ng-if="folderPathErrors.isSub && folderPathErrors.otherLabel.length == 0">Warning, this path is a subdirectory of an existing folder "{%otherFolder%}".</span>
|
|
<span class="text-danger" translate translate-value-other-folder="{{folderPathErrors.otherID}}" translate-value-other-folder-label="{{folderPathErrors.otherLabel}}" ng-if="folderPathErrors.isSub && folderPathErrors.otherLabel.length != 0">Warning, this path is a subdirectory of an existing folder "{%otherFolderLabel%}" ({%otherFolder%}).</span>
|
|
<span class="text-danger" translate translate-value-other-folder="{{folderPathErrors.otherID}}" ng-if="folderPathErrors.isParent && folderPathErrors.otherLabel.length == 0">Warning, this path is a parent directory of an existing folder "{%otherFolder%}".</span>
|
|
<span class="text-danger" translate translate-value-other-folder="{{folderPathErrors.otherID}}" translate-value-other-folder-label="{{folderPathErrors.otherLabel}}" ng-if="folderPathErrors.isParent && folderPathErrors.otherLabel.length != 0">Warning, this path is a parent directory of an existing folder "{%otherFolderLabel%}" ({%otherFolder%}).</span>
|
|
</p>
|
|
</div>
|
|
<div class="form-group">
|
|
<label translate for="devices">Share With Devices</label>
|
|
<p translate class="help-block">Select the devices to share this folder with.</p>
|
|
<div class="row">
|
|
<div class="col-md-4" ng-repeat="device in otherDevices()">
|
|
<div class="checkbox">
|
|
<label>
|
|
<input type="checkbox" ng-model="currentFolder.selectedDevices[device.deviceID]"/> {{deviceName(device)}}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div translate ng-show="!editingExisting" class="help-block">When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.</div>
|
|
</div>
|
|
<div id="folder-versioning" class="tab-pane">
|
|
<div class="form-group">
|
|
<label translate>File Versioning</label> <a href="https://docs.syncthing.net/users/versioning.html" target="_blank"><span class="fa fa-book"></span> <span translate>Help</span></a>
|
|
<select class="form-control" ng-model="currentFolder.fileVersioningSelector">
|
|
<option value="none" translate>No File Versioning</option>
|
|
<option value="trashcan" translate>Trash Can File Versioning</option>
|
|
<option value="simple" translate>Simple File Versioning</option>
|
|
<option value="staggered" translate>Staggered File Versioning</option>
|
|
<option value="external" translate>External File Versioning</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group" ng-if="currentFolder.fileVersioningSelector=='trashcan'" ng-class="{'has-error': folderEditor.trashcanClean.$invalid && folderEditor.trashcanClean.$dirty}">
|
|
<p translate class="help-block">Files are moved to .stversions directory when replaced or deleted by Syncthing.</p>
|
|
<label translate for="trashcanClean">Clean out after</label>
|
|
<div class="input-group">
|
|
<input name="trashcanClean" id="trashcanClean" class="form-control text-right" type="number" ng-model="currentFolder.trashcanClean" required="" aria-required="true" min="0"/>
|
|
<div class="input-group-addon" translate>days</div>
|
|
</div>
|
|
<p class="help-block">
|
|
<span translate ng-if="folderEditor.trashcanClean.$valid || folderEditor.trashcanClean.$pristine">The number of days to keep files in the trash can. Zero means forever.</span>
|
|
<span translate ng-if="folderEditor.trashcanClean.$error.required && folderEditor.trashcanClean.$dirty">The number of days must be a number and cannot be blank.</span>
|
|
<span translate ng-if="folderEditor.trashcanClean.$error.min && folderEditor.trashcanClean.$dirty">A negative number of days doesn't make sense.</span>
|
|
</p>
|
|
</div>
|
|
<div class="form-group" ng-if="currentFolder.fileVersioningSelector=='simple'" ng-class="{'has-error': folderEditor.simpleKeep.$invalid && folderEditor.simpleKeep.$dirty}">
|
|
<p translate class="help-block">Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.</p>
|
|
<label translate for="simpleKeep">Keep Versions</label>
|
|
<input name="simpleKeep" id="simpleKeep" class="form-control" type="number" ng-model="currentFolder.simpleKeep" required="" aria-required="true" min="1"/>
|
|
<p class="help-block">
|
|
<span translate ng-if="folderEditor.simpleKeep.$valid || folderEditor.simpleKeep.$pristine">The number of old versions to keep, per file.</span>
|
|
<span translate ng-if="folderEditor.simpleKeep.$error.required && folderEditor.simpleKeep.$dirty">The number of versions must be a number and cannot be blank.</span>
|
|
<span translate ng-if="folderEditor.simpleKeep.$error.min && folderEditor.simpleKeep.$dirty">You must keep at least one version.</span>
|
|
</p>
|
|
</div>
|
|
<div class="form-group" ng-if="currentFolder.fileVersioningSelector=='staggered'" ng-class="{'has-error': folderEditor.staggeredMaxAge.$invalid && folderEditor.staggeredMaxAge.$dirty}">
|
|
<p class="help-block"><span translate>Files are moved to date stamped versions in a .stversions directory when replaced or deleted by Syncthing.</span> <span translate>Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.</span></p>
|
|
<p translate class="help-block">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.</p>
|
|
<label translate for="staggeredMaxAge">Maximum Age</label>
|
|
<input name="staggeredMaxAge" id="staggeredMaxAge" class="form-control" type="number" ng-model="currentFolder.staggeredMaxAge" required="" aria-required="true" min="0"/>
|
|
<p class="help-block">
|
|
<span translate ng-if="folderEditor.staggeredMaxAge.$valid || folderEditor.staggeredMaxAge.$pristine">The maximum time to keep a version (in days, set to 0 to keep versions forever).</span>
|
|
<span translate ng-if="folderEditor.staggeredMaxAge.$error.required && folderEditor.staggeredMaxAge.$dirty">The maximum age must be a number and cannot be blank.</span>
|
|
<span translate ng-if="folderEditor.staggeredMaxAge.$error.min && folderEditor.staggeredMaxAge.$dirty">A negative number of days doesn't make sense.</span>
|
|
</p>
|
|
</div>
|
|
<div class="form-group" ng-if="currentFolder.fileVersioningSelector == 'staggered'">
|
|
<label translate for="staggeredVersionsPath">Versions Path</label>
|
|
<input name="staggeredVersionsPath" id="staggeredVersionsPath" class="form-control" type="text" ng-model="currentFolder.staggeredVersionsPath"/>
|
|
<p translate class="help-block">Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).</p>
|
|
</div>
|
|
<div class="form-group" ng-if="currentFolder.fileVersioningSelector=='external'" ng-class="{'has-error': folderEditor.externalCommand.$invalid && folderEditor.externalCommand.$dirty}">
|
|
<p translate class="help-block">An external command handles the versioning. It has to remove the file from the shared folder. If the path to the application contains spaces, it should be quoted.</p>
|
|
<label translate for="externalCommand">Command</label>
|
|
<input name="externalCommand" id="externalCommand" class="form-control" type="text" ng-model="currentFolder.externalCommand" required="" aria-required="true" />
|
|
<p class="help-block">
|
|
<span translate ng-if="folderEditor.externalCommand.$valid || folderEditor.externalCommand.$pristine">See external versioning help for supported templated command line parameters.</span>
|
|
<span translate ng-if="folderEditor.externalCommand.$error.required && folderEditor.externalCommand.$dirty">The path cannot be blank.</span>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div id="folder-ignores" class="tab-pane">
|
|
<p translate>Enter ignore patterns, one per line.</p>
|
|
<textarea class="form-control" rows="5"></textarea>
|
|
<hr/>
|
|
<p class="small"><span translate>Quick guide to supported patterns</span> (<a href="https://docs.syncthing.net/users/ignoring.html" target="_blank" translate>full documentation</a>):</p>
|
|
<dl class="dl-horizontal dl-narrow small">
|
|
<dt><code>(?d)</code></dt> <dd><b><span translate>Prefix indicating that the file can be deleted if preventing directory removal</span></b></dd>
|
|
<dt><code>(?i)</code></dt> <dd><span translate>Prefix indicating that the pattern should be matched without case sensitivity</span></dd>
|
|
<dt><code>!</code></dt> <dd><span translate>Inversion of the given condition (i.e. do not exclude)</span></dd>
|
|
<dt><code>*</code></dt> <dd><span translate>Single level wildcard (matches within a directory only)</span></dd>
|
|
<dt><code>**</code></dt> <dd><span translate>Multi level wildcard (matches multiple directory levels)</span></dd>
|
|
<dt><code>//</code></dt> <dd><span translate>Comment, when used at the start of a line</span></dd>
|
|
</dl>
|
|
<hr/>
|
|
<div class="pull-left" ng-show="editingExisting"><span translate translate-value-path="{{currentFolder.path}}{{system.pathSeparator}}.stignore">Editing {%path%}.</span></div>
|
|
<div class="pull-left" ng-show="!editingExisting"><span translate translate-value-path="{{currentFolder.path}}{{system.pathSeparator}}.stignore">Creating ignore patterns, overwriting an existing file at {%path%}.</span></div>
|
|
</div>
|
|
<div id="folder-advanced" class="tab-pane">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group" ng-class="{'has-error': folderEditor.rescanIntervalS.$invalid && folderEditor.rescanIntervalS.$dirty}">
|
|
<label for="rescanIntervalS"><span translate>Rescan Interval</span> (s)</label><br/>
|
|
<input name="rescanIntervalS" id="rescanIntervalS" class="form-control" type="number" ng-model="currentFolder.rescanIntervalS" required="" aria-required="true" min="0"/>
|
|
<p class="help-block">
|
|
<span translate ng-if="!folderEditor.rescanIntervalS.$valid && folderEditor.rescanIntervalS.$dirty">The rescan interval must be a non-negative number of seconds.</span>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6 form-horizontal">
|
|
<div class="form-group" ng-class="{'has-error': folderEditor.minDiskFree.$invalid && folderEditor.minDiskFree.$dirty}">
|
|
<label class="col-xs-12" for="minDiskFree"><span translate>Minimum Free Disk Space</span></label><br/>
|
|
<div class="col-xs-9"><input name="minDiskFree" id="minDiskFree" class="form-control" type="number" ng-model="currentFolder.minDiskFree.value" required="" aria-required="true" min="0" step="0.01"/></div>
|
|
<div class="col-xs-3"><select class="col-sm-3 form-control" ng-model="currentFolder.minDiskFree.unit">
|
|
<option value="%">%</option>
|
|
<option value="kB">kB</option>
|
|
<option value="MB">MB</option>
|
|
<option value="GB">GB</option>
|
|
<option value="TB">TB</option>
|
|
</select></div>
|
|
<p class="col-xs-12 help-block" ng-show="folderEditor.minDiskFree.$invalid">
|
|
<span translate>Enter a non-negative number (e.g., "2.35") and select a unit. Percentages are as part of the total disk size.</span>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<!-- Left column -->
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label translate>Folder Type</label>
|
|
<a href="https://docs.syncthing.net/users/foldertypes.html" target="_blank"><span class="fa fa-book"></span> <span translate>Help</span></a>
|
|
<select class="form-control" ng-model="currentFolder.type">
|
|
<option value="readwrite" translate>Send & Receive</option>
|
|
<option value="readonly" translate>Send Only</option>
|
|
</select>
|
|
<p ng-if="currentFolder.type == 'readonly'" translate class="help-block">Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.</p>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="checkbox">
|
|
<label>
|
|
<input type="checkbox" ng-model="currentFolder.ignorePerms"/> <span translate>Ignore Permissions</span>
|
|
</label>
|
|
</div>
|
|
<p translate class="help-block">File permission bits are ignored when looking for changes. Use on FAT file systems.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Right column-->
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label translate>File Pull Order</label>
|
|
<select class="form-control" ng-model="currentFolder.order">
|
|
<option value="random" translate>Random</option>
|
|
<option value="alphabetic" translate>Alphabetic</option>
|
|
<option value="smallestFirst" translate>Smallest First</option>
|
|
<option value="largestFirst" translate>Largest First</option>
|
|
<option value="oldestFirst" translate>Oldest First</option>
|
|
<option value="newestFirst" translate>Newest First</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-primary btn-sm" ng-click="saveFolder()" ng-disabled="folderEditor.$invalid">
|
|
<span class="fa fa-check"></span> <span translate>Save</span>
|
|
</button>
|
|
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">
|
|
<span class="fa fa-times"></span> <span translate>Close</span>
|
|
</button>
|
|
<button type="button" class="btn btn-warning pull-left btn-sm" data-toggle="modal" data-target="#remove-folder-confirmation" ng-if="editingExisting">
|
|
<span class="fa fa-minus-circle"></span> <span translate>Remove</span>
|
|
</button>
|
|
</div>
|
|
</modal>
|