| |
@@ -0,0 +1,126 @@
|
| |
+ {% macro form_error(element) %} {% if element.errors %}
|
| |
+ <span class='text-danger small'>
|
| |
+ {% for error in element.errors %}
|
| |
+ {{ error }}
|
| |
+ {% endfor %}
|
| |
+ </span>
|
| |
+ {% endif %} {%- endmacro %}
|
| |
+ {% extends 'admin/master.html' %}
|
| |
+
|
| |
+ {% block body %}
|
| |
+
|
| |
+ <h5>Sync DB</h5>
|
| |
+
|
| |
+ <div class="alert alert-danger" id="syncalert" style="display: none;">
|
| |
+ Sync in progress, you can't perform sync until the current one ends.
|
| |
+ <button type="button" class="btn btn-danger" id="release-lock">Force unlock</button>
|
| |
+ </div>
|
| |
+
|
| |
+ <form method="POST" action="{{ url_for('admin.index') }}" class="form-horizontal">
|
| |
+ {{ syncform.csrf_token }}
|
| |
+ <div class="form-group">
|
| |
+ <div class="col-sm-12">
|
| |
+ <div class="checkbox">
|
| |
+ <label for="sync_bugs">
|
| |
+ {{ syncform.sync_bugs }} {{ syncform.sync_bugs.label.text }} {{ form_error(syncform.sync_bugs) }}
|
| |
+ </label>
|
| |
+ </div>
|
| |
+ </div>
|
| |
+ </div>
|
| |
+
|
| |
+ <div class="form-group">
|
| |
+ <div class="col-sm-12">
|
| |
+ <div class="checkbox">
|
| |
+ <label for="sync_discussions">
|
| |
+ {{ syncform.sync_discussions }} {{ syncform.sync_discussions.label.text }} {{ form_error(syncform.sync_discussions) }}
|
| |
+ </label>
|
| |
+ </div>
|
| |
+ </div>
|
| |
+ </div>
|
| |
+
|
| |
+ <div class="form-group">
|
| |
+ <div class="col-sm-12">
|
| |
+ <div class="checkbox">
|
| |
+ <label for="sync_updates">
|
| |
+ {{ syncform.sync_updates }} {{ syncform.sync_updates.label.text }} {{ form_error(syncform.sync_updates) }}
|
| |
+ </label>
|
| |
+ </div>
|
| |
+ </div>
|
| |
+ </div>
|
| |
+
|
| |
+ <div class="form-group">
|
| |
+ <div class="col-sm-12">
|
| |
+ <input type="submit" value="Sync" class="btn btn-default" id="syncsubmit">
|
| |
+ </div>
|
| |
+ </div>
|
| |
+ </form>
|
| |
+
|
| |
+ <h5 style="margin-top: 4em">Log</h5>
|
| |
+ <div style="display: flex; justify-content: space-between;">
|
| |
+ <div class="checkbox">
|
| |
+ <label>
|
| |
+ <input type="checkbox" value="" id="follow" checked>
|
| |
+ Follow the output
|
| |
+ </label>
|
| |
+ </div>
|
| |
+
|
| |
+ <div style="display: flex; align-items: center;">
|
| |
+ <div style="margin-left: 2em;">
|
| |
+ <a href="/api/v0/logs" target="_blank">raw</a>
|
| |
+ </div>
|
| |
+ </div>
|
| |
+ </div>
|
| |
+ <div id="logs"></div>
|
| |
+
|
| |
+ <script>
|
| |
+ document.addEventListener("DOMContentLoaded", function(event) {
|
| |
+ const syncCheck = () => {
|
| |
+ fetch("/api/v0/lock/sync")
|
| |
+ .then((response) => response.json())
|
| |
+ .then(
|
| |
+ (data) => {
|
| |
+ if (data.locked) {
|
| |
+ $("#syncalert").show()
|
| |
+ $("#syncsubmit").prop('disabled', true);
|
| |
+ } else {
|
| |
+ $("#syncalert").hide()
|
| |
+ $("#syncsubmit").prop('disabled', false);
|
| |
+ }
|
| |
+ }
|
| |
+ )}
|
| |
+
|
| |
+ syncCheck()
|
| |
+ setInterval(syncCheck, 5000)
|
| |
+
|
| |
+ var output = document.getElementById('logs');
|
| |
+ var xhr = new XMLHttpRequest();
|
| |
+ xhr.open('GET', '/api/v0/logs', true);
|
| |
+ xhr.send();
|
| |
+ setInterval(function() {
|
| |
+ output.textContent = xhr.responseText;
|
| |
+ if($("#follow").is(':checked')){
|
| |
+ output.scrollTop = output.scrollHeight;
|
| |
+ }
|
| |
+ }, 500);
|
| |
+
|
| |
+ $("#logs").on('scroll', (e) => {
|
| |
+ const output = document.getElementById('logs');
|
| |
+ if (Math.abs(output.scrollHeight - output.clientHeight - output.scrollTop) <= 1) {
|
| |
+ $("#follow").prop("checked", true);
|
| |
+ } else {
|
| |
+ $("#follow").prop("checked", false);
|
| |
+ }
|
| |
+ })
|
| |
+
|
| |
+ $("#release-lock").on("click", (e) => {
|
| |
+ fetch("/api/v0/lock_force_unlock/sync")
|
| |
+ .then((response) => response.json())
|
| |
+ .then((data) => {
|
| |
+ console.log(data)
|
| |
+ syncCheck()
|
| |
+ })
|
| |
+ })
|
| |
+ });
|
| |
+ </script>
|
| |
+
|
| |
+ {% endblock %}
|
| |
\ No newline at end of file
|
| |
Fixes #248