Adjusted to new template structure. WIP!

Problems:
- timeout upon print start due to first line not being properly sent apparently
- extruder count not taken from printer profiles yet (which are not available on comm layer), hence wrong end code
This commit is contained in:
Gina Häußge 2015-01-19 15:40:23 +01:00
parent 83204eda3b
commit e3cba0d4c2
4 changed files with 34 additions and 706 deletions

View file

@ -183,6 +183,7 @@ def index():
(gettext("Printer Profiles"), dict(template="dialogs/settings/printerprofiles.jinja2", _div="settings_printerProfiles", custom_bindings=False)),
(gettext("Temperatures"), dict(template="dialogs/settings/temperatures.jinja2", _div="settings_temperature", custom_bindings=False)),
(gettext("Terminal Filters"), dict(template="dialogs/settings/terminalfilters.jinja2", _div="settings_terminalFilters", custom_bindings=False)),
(gettext("GCODE Scripts"), dict(template="dialogs/settings/gcodescripts.jinja2", _div="settings_gcodeScripts", custom_bindings=False)),
(gettext("Features"), None),
(gettext("Features"), dict(template="dialogs/settings/features.jinja2", _div="settings_features", custom_bindings=False)),
(gettext("Webcam"), dict(template="dialogs/settings/webcam.jinja2", _div="settings_webcam", custom_bindings=False)),

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,32 @@
<form class="form-horizontal">
<div class="control-group">
<label class="control-label">{{ _('Before print job starts') }}</label>
<div class="controls">
<textarea rows="3" class="block" data-bind="value: scripts_gcode_beforePrintStarted"></textarea>
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('After print job completes') }}</label>
<div class="controls">
<textarea rows="3" class="block" data-bind="value: scripts_gcode_afterPrintDone"></textarea>
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('After print job is cancelled') }}</label>
<div class="controls">
<textarea rows="3" class="block" data-bind="value: scripts_gcode_afterPrintCancelled"></textarea>
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('After print job is paused') }}</label>
<div class="controls">
<textarea rows="3" class="block" data-bind="value: scripts_gcode_afterPrintPaused"></textarea>
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('Before print job is resumed') }}</label>
<div class="controls">
<textarea rows="3" class="block" data-bind="value: scripts_gcode_beforePrintResumed"></textarea>
</div>
</div>
</form>

View file

@ -1,705 +0,0 @@
<div id="settings_dialog" class="modal hide fade container" tabindex="-1" role="dialog" aria-labelledby="settings_dialog_label" aria-hidden="true" data-replace="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h3 id="settings_dialog_label">{{ _('OctoPrint Settings') }}</h3>
</div>
<div class="modal-body">
<div class="tabbable">
<ul class="nav nav-list span3" id="settingsTabs">
<li class="nav-header">{{ _('Printer') }}</li>
<li class="active"><a href="#settings_serialConnection" data-toggle="tab">{{ _('Serial Connection') }}</a></li>
<li><a href="#settings_printerParameters" data-toggle="tab">{{ _('Printer Parameters') }}</a></li>
<li><a href="#settings_temperature" data-toggle="tab">{{ _('Temperatures') }}</a></li>
<li><a href="#settings_terminalFilters" data-toggle="tab">{{ _('Terminal filters') }}</a></li>
<li><a href="#settings_gcodeScripts" data-toggle="tab">{{ _('GCODE Scripts') }}</a></li>
<li class="nav-header">{{ _('Features') }}</li>
<li><a href="#settings_features" data-toggle="tab">{{ _('Features') }}</a></li>
<li><a href="#settings_webcam" data-toggle="tab">{{ _('Webcam') }}</a></li>
{% if enableAccessControl %}<li><a href="#settings_users" data-toggle="tab">{{ _('Access Control') }}</a></li>{% endif %}
<li><a href="#settings_api" data-toggle="tab">{{ _('API') }}</a></li>
<li class="nav-header">OctoPrint</li>
<li><a href="#settings_folder" data-toggle="tab">{{ _('Folders') }}</a></li>
<li><a href="#settings_appearance" data-toggle="tab">{{ _('Appearance') }}</a></li>
<li><a href="#settings_logs" data-toggle="tab">{{ _('Logs') }}</a></li>
{% if settingsPlugins %}
<li class="nav-header">Plugins</li>
{% for plugin_name, vars in settingsPlugins.items() %}
{% if vars._settings_menu_entry %}
<li><a href="#settings_plugin_{{ plugin_name }}" data-toggle="tab">{{ vars._settings_menu_entry }}</a></li>
{% endif %}
{% endfor %}
{% endif %}
</ul>
<div class="tab-content span9">
<div class="tab-pane active" id="settings_serialConnection">
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="settings-serialPort">{{ _('Serial Port') }}</label>
<div class="controls">
<select id="settings-serialPort" data-bind="options: serial_portOptions, optionsCaption: 'AUTO', value: serial_port"></select>
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-baudrate">{{ _('Baudrate') }}</label>
<div class="controls">
<select id="settings-baudrate" data-bind="options: serial_baudrateOptions, optionsCaption: 'AUTO', value: serial_baudrate"></select>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: serial_autoconnect" id="settings-serialAutoconnect"> {{ _('Auto-connect to printer on server start') }}
</label>
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-serialTimeoutCommunication">{{ _('Communication timeout') }}</label>
<div class="controls">
<div class="input-append">
<input type="number" step="any" min="0" class="input-mini text-right" data-bind="value: serial_timeoutCommunication" id="settings-serialTimeoutCommunication">
<span class="add-on">s</span>
</div>
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-movementSpeedE">{{ _('Temperature timeout') }}</label>
<div class="controls">
<div class="input-append">
<input type="number" step="any" min="0" class="input-mini text-right" data-bind="value: serial_timeoutTemperature" id="settings-serialTimeoutTemperature">
<span class="add-on">s</span>
</div>
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-serialTimeoutSdStatus">{{ _('SD status timeout') }}</label>
<div class="controls">
<div class="input-append">
<input type="number" step="any" min="0" class="input-mini text-right" data-bind="value: serial_timeoutSdStatus" id="settings-serialTimeoutSdStatus">
<span class="add-on">s</span>
</div>
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-serialTimeoutConnection">{{ _('Connection timeout') }}</label>
<div class="controls">
<div class="input-append">
<input type="number" step="any" min="0" class="input-mini text-right" data-bind="value: serial_timeoutConnection" id="settings-serialTimeoutConnection">
<span class="add-on">s</span>
</div>
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-serialTimeoutDetection">{{ _('Autodetection timeout') }}</label>
<div class="controls">
<div class="input-append">
<input type="number" step="any" min="0" class="input-mini text-right" data-bind="value: serial_timeoutDetection" id="settings-serialTimeoutDetection">
<span class="add-on">s</span>
</div>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: serial_log" id="settings-serialLog"> {{ _('Log communication to serial.log (might negatively impact performance)') }} <span class="label label-important">{{ _('Warning') }}</span>
</label>
</div>
</div>
</form>
</div>
<div class="tab-pane" id="settings_printerParameters">
<form class="form-horizontal">
<div class="control-group">
<label class="control-label">{{ _('Axis') }}</label>
<div class="controls form-inline">
<label>{{ _('X') }}:</label>
<div class="input-append">
<input type="number" class="input-mini text-right" data-bind="value: printer_movementSpeedX" id="settings-movementSpeedX">
<span class="add-on">mm/min</span>
</div>
<label class="checkbox">
<input type="checkbox" data-bind="checked: printer_invertX" id="settings-printerInvertX"> {{ _('Invert control') }}
</label>
</div>
<div class="controls form-inline">
<label>{{ _('Y') }}:</label>
<div class="input-append">
<input type="number" class="input-mini text-right" data-bind="value: printer_movementSpeedY" id="settings-movementSpeedY">
<span class="add-on">mm/min</span>
</div>
<label class="checkbox">
<input type="checkbox" data-bind="checked: printer_invertY" id="settings-printerInvertY"> {{ _('Invert control') }}
</label>
</div>
<div class="controls form-inline">
<label>{{ _('Z') }}:</label>
<div class="input-append">
<input type="number" class="input-mini text-right" data-bind="value: printer_movementSpeedZ" id="settings-movementSpeedZ">
<span class="add-on">mm/min</span>
</div>
<label class="checkbox">
<input type="checkbox" data-bind="checked: printer_invertZ" id="settings-printerInvertZ"> {{ _('Invert control') }}
</label>
</div>
<div class="controls form-inline">
<label>{{ _('E') }}:</label>
<div class="input-append">
<input type="number" class="input-mini text-right" data-bind="value: printer_movementSpeedE" id="settings-movementSpeedE">
<span class="add-on">mm/min</span>
</div>
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-defaultExtrusionLength">{{ _('Default extrusion length') }}</label>
<div class="controls">
<input type="number" class="input-mini text-right" min="1" data-bind="value: printer_defaultExtrusionLength" id="settings-defaultExtrusionLength">
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-numExtruders">{{ _('Number of Extruders') }}</label>
<div class="controls">
<input type="number" class="input-mini text-right" min="1" max="5" data-bind="value: printer_numExtruders" id="settings-numExtruders">
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-extruderOffsets">{{ _('Extruder Offsets') }}</label>
<!-- ko foreach: ko_printer_extruderOffsets -->
<div class="controls form-inline">
<label>X:</label>
<div class="input-append">
<input type="number" step="0.01" class="input-mini text-right" data-bind="value: x">
<span class="add-on">mm</span>
</div>
<label>Y:</label>
<div class="input-append">
<input type="number" step="0.01" class="input-mini text-right" data-bind="value: y">
<span class="add-on">mm</span>
</div>
</div>
<!-- /ko -->
</div>
<div class="control-group">
<label class="control-label" for="settings-bedSize">{{ _('Bed Size') }}</label>
<div class="controls form-inline" data-bind="ifnot: printer_bedCircular">
<label>{{ _('X') }}:</label>
<div class="input-append">
<input type="number" step="0.01" class="input-mini text-right" data-bind="value: printer_bedDimensionX" id="settings-bedX">
<span class="add-on">mm</span>
</div>
<label>{{ _('Y') }}:</label>
<div class="input-append">
<input type="number" step="0.01" class="input-mini text-right" data-bind="value: printer_bedDimensionY" id="settings-bedY">
<span class="add-on">mm</span>
</div>
</div>
<div class="controls form-inline" data-bind="if: printer_bedCircular">
<label>{{ _('Radius') }}:</label>
<div class="input-append">
<input type="number" step="0.01" class="input-mini text-right" data-bind="value: printer_bedDimensionR" id="settings-bedR">
<span class="add-on">mm</span>
</div>
</div>
<div class="controls form-inline">
<label class="checkbox">
<input type="checkbox" data-bind="checked: printer_bedCircular" id="settings-bedCircular"> {{ _('Circular') }}
</label>
</div>
</div>
</form>
</div>
<div class="tab-pane" id="settings_webcam">
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="settings-webcamStreamUrl">{{ _('Stream URL') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: webcam_streamUrl" id="settings-webcamStreamUrl">
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-webcamStreamUrl">{{ _('Snapshot URL') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: webcam_snapshotUrl" id="settings-webcamSnapshotUrl">
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-webcamStreamUrl">{{ _('Path to FFMPEG') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: webcam_ffmpegPath" id="settings-webcamFfmpegPath">
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-webcamBitrate">{{ _('Timelapse bitrate') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: webcam_bitrate" id="settings-webcamBitrate">
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: webcam_watermark" id="settings-webcamWatermark"> {{ _('Enable OctoPrint watermark in timelapse movies') }}
</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: webcam_flipH" id="settings-webcamFlipH"> {{ _('Flip webcam horizontally') }}
</label>
</div>
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: webcam_flipV" id="settings-webcamFlipV"> {{ _('Flip webcam vertically') }}
</label>
</div>
</div>
</form>
</div>
<div class="tab-pane" id="settings_features">
<form class="form-horizontal">
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: feature_temperatureGraph" id="settings-featureTemperatureGraph"> {{ _('Enable Temperature Graph') }}
</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: feature_gcodeViewer" id="settings-featureGcodeViewer"> {{ _('Enable GCode Visualizer') }}
</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: feature_sdSupport" id="settings-featureSdSupport"> {{ _('Enable SD support') }}
</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: feature_sdAlwaysAvailable" id="settings-featureSdAlwaysAvailable"> {{ _('Always assume SD card is present') }} <span class="label">{{ _('Repetier') }}</span>
</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: feature_waitForStart" id="settings-featureWaitForStart"> {{ _('Wait for <code>start</code> on connect') }}
</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: feature_alwaysSendChecksum" id="settings-featureAlwaysSendChecksum"> {{ _('Send a checksum with <strong>every</strong> command') }} <span class="label">{{ _('Repetier') }}</span>
</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: feature_repetierTargetTemp" id="settings-featureRepetierTargetTemp"> {{ _('Support <code>TargetExtr%%n</code>/<code>TargetBed</code> target temperature format') }} <span class="label">{{ _('Repetier') }}</span>
</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: feature_swallowOkAfterResend" id="settings-swallowOkAfterResend"> {{ _('Swallow the first "ok" after a resend response') }}
</label>
</div>
</div>
</form>
</div>
<div class="tab-pane" id="settings_folder">
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="settings-folderUploads">{{ _('Upload Folder') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: folder_uploads" id="settings-folderUploads">
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-folderTimelapse">{{ _('Timelapse Folder') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: folder_timelapse" id="settings-folderTimelapse">
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-folderTimelapseTemp">{{ _('Timelapse Temp Folder') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: folder_timelapseTmp" id="settings-folderTimelapseTemp">
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-folderLogs">{{ _('Logs Folder') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: folder_logs" id="settings-folderLogs">
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-watchedLogs">{{ _('Watched Folder') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: folder_watched" id="settings-folderWatched">
</div>
</div>
</form>
</div>
<div class="tab-pane" id="settings_temperature">
<form class="form-horizontal">
<div class="row-fluid">
<div class="offset3 span3"><h4>{{ _('Extruder') }}</h4></div>
<div class="span3"><h4>{{ _('Bed') }}</h4></div>
</div>
<div data-bind="foreach: temperature_profiles">
<div class="row-fluid" style="margin-bottom: 5px">
<div class="span3">
<input type="text" class="span12 text-right" data-bind="value: name">
</div>
<div class="input-append span3">
<input type="number" class="input-mini text-right" data-bind="value: extruder">
<span class="add-on">&deg;C</span>
</div>
<div class="input-append span3">
<input type="number" class="input-mini text-right" data-bind="value: bed">
<span class="add-on">&deg;C</span>
</div>
<div class="span2">
<a title="Remove profile" class="btn btn-danger" data-bind="click: $parent.removeTemperatureProfile"><i class="icon-trash"></i></a>
</div>
</div>
</div>
<div class="row-fluid">
<div class="offset9 span2">
<a title="Add Profile" class="btn btn-primary" data-bind="click: addTemperatureProfile"><i class="icon-plus"></i></a>
</div>
</div>
</form>
</div>
<div class="tab-pane" id="settings_terminalFilters">
<form class="form-horizontal">
<div class="row-fluid">
<div class="span4"><h4>{{ _('Name') }}</h4></div>
<div class="span6"><h4>{{ _('RegExp') }} <small><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions">?</a></small></h4></div>
</div>
<div data-bind="foreach: terminalFilters">
<div class="row-fluid" style="margin-bottom: 5px">
<div class="span4">
<input type="text" class="span12" data-bind="value: name">
</div>
<div class="span6">
<input type="text" class="span12" data-bind="value: regex">
</div>
<div class="span2">
<a title="Remove Filter" class="btn btn-danger" data-bind="click: $parent.removeTerminalFilter"><i class="icon-trash"></i></a>
</div>
</div>
</div>
<div class="row-fluid">
<div class="offset10 span2">
<a title="Add Filter" class="btn btn-primary" data-bind="click: addTerminalFilter"><i class="icon-plus"></i></a>
</div>
</div>
</form>
</div>
<div class="tab-pane" id="settings_gcodeScripts">
<form class="form-horizontal">
<div class="control-group">
<label class="control-label">{{ _('Before print job starts') }}</label>
<div class="controls">
<textarea rows="3" class="block" data-bind="value: scripts_gcode_beforePrintStarted"></textarea>
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('After print job completes') }}</label>
<div class="controls">
<textarea rows="3" class="block" data-bind="value: scripts_gcode_afterPrintDone"></textarea>
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('After print job is cancelled') }}</label>
<div class="controls">
<textarea rows="3" class="block" data-bind="value: scripts_gcode_afterPrintCancelled"></textarea>
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('After print job is paused') }}</label>
<div class="controls">
<textarea rows="3" class="block" data-bind="value: scripts_gcode_afterPrintPaused"></textarea>
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('Before print job is resumed') }}</label>
<div class="controls">
<textarea rows="3" class="block" data-bind="value: scripts_gcode_beforePrintResumed"></textarea>
</div>
</div>
</form>
</div>
<div class="tab-pane" id="settings_appearance">
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="settings-appearanceName">{{ _('Title') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: appearance_name" id="settings-appearanceName">
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-appearanceColor">{{ _('Color') }}</label>
<div class="controls">
<select id="settings-appearanceColor" data-bind="value: appearance_color, options: appearance_available_colors, optionsText: 'name', optionsValue: 'key'">
</select>
</div>
</div>
</form>
</div>
<div class="tab-pane" id="settings_api">
<form class="form-horizontal">
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" id="settings-apiEnabled" data-bind="checked: api_enabled"> {{ _('Enable') }}
</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" id="settings-apiCors" data-bind="checked: api_allowCrossOrigin"> {{ _('Allow <a href="%(url)s">Cross Origin Resource Sharing (CORS)</a>', url = "https://en.wikipedia.org/wiki/Cross-origin_resource_sharing") }}
</label>
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-apiKey">{{ _('API Key') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: api_key" id="settings-apikey">
</div>
</div>
</form>
</div>
{% if enableAccessControl %}
<div class="tab-pane" id="settings_users">
<table class="table table-condensed table-hover" id="system_users">
<thead>
<tr>
<th class="settings_users_name">{{ _('Name') }}</th>
<th class="settings_users_active">{{ _('Active') }}</th>
<th class="settings_users_admin">{{ _('Admin') }}</th>
<th class="settings_users_actions">{{ _('Action') }}</th>
</tr>
</thead>
<tbody data-bind="foreach: users.listHelper.paginatedItems">
<tr>
<td class="settings_users_name"><span data-bind="text: name"></span><span class="muted" data-bind="visible: $root.api_enabled() && apikey"><br /><small>{{ _('API Key') }}: <span data-bind="text: apikey"></span></small></span></td>
<td class="settings_users_active"><i data-bind="css: { 'icon-check': active, 'icon-check-empty': !active }"></i></td>
<td class="settings_users_admin"><i data-bind="css: { 'icon-check': admin, 'icon-check-empty': !admin }"></i></td>
<td class="settings_users_actions" class="system_users_action">
<a href="#" class="icon-pencil" title="{{ _('Update User') }}" data-bind="click: function() { $root.users.showEditUserDialog($data); }"></a>&nbsp;|&nbsp;<a href="#" class="icon-key" title="{{ _('Change password') }}" data-bind="click: function() { $root.users.showChangePasswordDialog($data); }"></a>&nbsp;|&nbsp;<a href="#" class="icon-trash" title="{{ _('Delete user') }}" data-bind="click: function() { $root.users.removeUser($data); }"></a>
</td>
</tr>
</tbody>
</table>
<div class="pagination pagination-mini pagination-centered">
<ul>
<li data-bind="css: {disabled: users.listHelper.currentPage() === 0}"><a href="#" data-bind="click: users.listHelper.prevPage">«</a></li>
</ul>
<ul data-bind="foreach: users.listHelper.pages">
<li data-bind="css: { active: $data.number === $root.users.listHelper.currentPage(), disabled: $data.number === -1 }"><a href="#" data-bind="text: $data.text, click: function() { $root.users.listHelper.changePage($data.number); }"></a></li>
</ul>
<ul>
<li data-bind="css: {disabled: users.listHelper.currentPage() === users.listHelper.lastPage()}"><a href="#" data-bind="click: users.listHelper.nextPage">»</a></li>
</ul>
</div>
<button title="Add user" class="btn" data-bind="click: $root.users.showAddUserDialog"><i class="icon-plus"></i> {{ _('Add user') }}</button>
<!-- Modals for user management -->
<div id="settings-usersDialogAddUser" class="modal hide fade">
<div class="modal-header">
<a href="#" class="close" data-dismiss="modal" aria-hidden="true">&times;</a>
<h3>{{ _('Add user') }}</h3>
</div>
<div class="modal-body">
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="settings-usersDialogAddUserName">{{ _('Username') }}</label>
<div class="controls">
<input type="text" class="input-block-level" id="settings-usersDialogAddUserName" data-bind="value: $root.users.editorUsername" required>
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-usersDialogAddUserPassword1">{{ _('Password') }}</label>
<div class="controls">
<input type="password" class="input-block-level" id="settings-usersDialogAddUserPassword1" data-bind="value: $root.users.editorPassword" required>
</div>
</div>
<div class="control-group" data-bind="css: {error: $root.users.editorPasswordMismatch()}">
<label class="control-label" for="settings-usersDialogAddUserPassword2">{{ _('Repeat Password') }}</label>
<div class="controls">
<input type="password" class="input-block-level" id="settings-usersDialogAddUserPassword2" data-bind="value: $root.users.editorRepeatedPassword, valueUpdate: 'afterkeydown'" required>
<span class="help-inline" data-bind="visible: $root.users.editorPasswordMismatch()">{{ _('Passwords do not match') }}</span>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" id="settings-usersDialogAddUserActive" data-bind="checked: $root.users.editorActive"> {{ _('Active') }}
</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" id="settings-usersDialogAddUserAdmin" data-bind="checked: $root.users.editorAdmin"> {{ _('Admin') }}
</label>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">{{ _('Abort') }}</button>
<button class="btn btn-primary" data-bind="click: function() { $root.users.confirmAddUser(); }, enable: !$root.users.editorPasswordMismatch()">{{ _('Confirm') }}</button>
</div>
</div>
<div id="settings-usersDialogEditUser" class="modal hide fade">
<div class="modal-header">
<a href="#" class="close" data-dismiss="modal" aria-hidden="true">&times;</a>
<h3>{{ _('Edit user "%(user)s"', user = '<span data-bind="text: $root.users.editorUsername"></span>') }}</h3>
</div>
<div class="modal-body">
<form class="form-horizontal">
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" id="settings-usersDialogEditUserActive" data-bind="checked: $root.users.editorActive"> {{ _('Active') }}
</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" id="settings-usersDialogEditUserAdmin" data-bind="checked: $root.users.editorAdmin"> {{ _('Admin') }}
</label>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">{{ _('Abort') }}</button>
<button class="btn btn-primary" data-bind="click: function() { $root.users.confirmEditUser(); }">{{ _('Confirm') }}</button>
</div>
</div>
<div id="settings-usersDialogChangePassword" class="modal hide fade">
<div class="modal-header">
<a href="#" class="close" data-dismiss="modal" aria-hidden="true">&times;</a>
<h3>{{ _('Change password for user "%(user)s"', user='<span data-bind="text: $root.users.editorUsername"></span>') }}</h3>
</div>
<div class="modal-body">
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="settings-usersDialogChangePasswordPassword1">{{ _('New Password') }}</label>
<div class="controls">
<input type="password" class="input-block-level" id="settings-usersDialogChangePasswordPassword1" data-bind="value: $root.users.editorPassword" required>
</div>
</div>
<div class="control-group" data-bind="css: {error: $root.users.editorPasswordMismatch()}">
<label class="control-label" for="settings-usersDialogChangePasswordPassword2">{{ _('Repeat Password') }}</label>
<div class="controls">
<input type="password" class="input-block-level" id="settings-usersDialogChangePasswordPassword2" data-bind="value: $root.users.editorRepeatedPassword, valueUpdate: 'afterkeydown'" required>
<span class="help-inline" data-bind="visible: $root.users.editorPasswordMismatch()">{{ _('Passwords do not match') }}</span>
</div>
</div>
<fieldset data-bind="visible: api_enabled">
<legend>Apikey</legend>
<div class="control-group">
<label class="control-label">{{ _('Current API Key') }}</label>
<div class="controls">
<div class="input-append">
<input type="text" class="input-block-level uneditable-input" data-bind="value: $root.users.editorApikey, attr: {placeholder: '{{ _('N/A') }}'}">
<a class="btn" title="Generate new Apikey" data-bind="click: function() { $root.users.confirmGenerateApikey(); }"><i class="icon-refresh"></i></a>
<a class="btn btn-danger" title="Delete Apikey" data-bind="click: function() { $root.users.confirmDeleteApikey(); }"><i class="icon-trash"></i></a>
</div>
</div>
</div>
</fieldset>
</form>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">{{ _('Abort') }}</button>
<button class="btn btn-primary" data-bind="click: function() { $root.users.confirmChangePassword(); }, enable: !$root.users.editorPasswordMismatch()">{{ _('Confirm') }}</button>
</div>
</div>
</div>
{% endif %}
{% for plugin_name, vars in settingsPlugins.items() %}
<div class="tab-pane" id="settings_plugin_{{ plugin_name }}" data-bind="allowBindings: false">
{% include plugin_name+"_settings_dialog.jinja2" ignore missing %}
</div>
{% endfor %}
<div class="tab-pane" id="settings_logs" data-bind="allowBindings: false">
<div id="logs">
<h1>{{ _('Logs') }}</h1>
<div class="pull-right">
<small>
{{ _('Sort by') }}: <a href="#" data-bind="click: function() { listHelper.changeSorting('name'); }">{{ _('Name') }} ({{ _('ascending') }})</a> | <a href="#" data-bind="click: function() { listHelper.changeSorting('modification'); }">{{ _('Modification date') }} ({{ _('descending') }})</a> | <a href="#" data-bind="click: function() { listHelper.changeSorting('size'); }">{{ _('Size') }} ({{ _('descending') }})</a>
</small>
</div>
<table class="table table-striped table-hover table-condensed table-hover" id="log_files">
<thead>
<tr>
<th class="settings_logs_name">{{ _('Name') }}</th>
<th class="settings_logs_size">{{ _('Size') }}</th>
<th class="settings_logs_date">{{ _('Date') }}</th>
<th class="settings_logs_action">{{ _('Action') }}</th>
</tr>
</thead>
<tbody data-bind="foreach: listHelper.paginatedItems">
<tr data-bind="attr: {title: name}">
<td class="settings_logs_name" data-bind="text: name"></td>
<td class="settings_logs_size" data-bind="text: formatSize(size)"></td>
<td class="settings_logs_date" data-bind="text: formatDate(date)"></td>
<td class="settings_logs_action">
<a href="#" class="icon-trash" data-bind="click: function() { if ($root.loginState.isUser()) { $parent.removeFile($data.name); } else { return; } }, css: {disabled: !$root.loginState.isUser()}"></a>&nbsp;|&nbsp;<a href="#" class="icon-download" data-bind="attr: {href: refs.download}"></a>
</td>
</tr>
</tbody>
</table>
<div class="pagination pagination-mini pagination-centered">
<ul>
<li data-bind="css: {disabled: listHelper.currentPage() === 0}">
<a href="#" data-bind="click: listHelper.prevPage">«</a>
</li>
</ul>
<ul data-bind="foreach: listHelper.pages">
<li data-bind="css: { active: $data.number === $root.listHelper.currentPage(), disabled: $data.number === -1 }">
<a href="#" data-bind="text: $data.text, click: function() { $root.listHelper.changePage($data.number); }"></a>
</li>
</ul>
<ul>
<li data-bind="css: {disabled: listHelper.currentPage() === listHelper.lastPage()}">
<a href="#" data-bind="click: listHelper.nextPage">»</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">{{ _('Cancel') }}</button>
<button class="btn btn-primary" data-bind="click: saveData">{{ _('Save') }}</button>
</div>
</div>