diff options
Diffstat (limited to 'templates/staff')
-rw-r--r-- | templates/staff/index.html | 23 | ||||
-rw-r--r-- | templates/staff/jams/create.html | 78 | ||||
-rw-r--r-- | templates/staff/jams/edit_basics.html | 79 | ||||
-rw-r--r-- | templates/staff/jams/edit_ending.html | 152 | ||||
-rw-r--r-- | templates/staff/jams/edit_info.html | 309 | ||||
-rw-r--r-- | templates/staff/jams/forms/preamble_edit.html | 150 | ||||
-rw-r--r-- | templates/staff/jams/forms/questions_edit.html | 354 | ||||
-rw-r--r-- | templates/staff/jams/forms/questions_view.html | 593 | ||||
-rw-r--r-- | templates/staff/jams/forms/view.html | 755 | ||||
-rw-r--r-- | templates/staff/jams/index.html | 252 | ||||
-rw-r--r-- | templates/staff/jams/infractions/view.html | 328 | ||||
-rw-r--r-- | templates/staff/jams/participants.html | 163 | ||||
-rw-r--r-- | templates/staff/jams/teams/view.html | 513 | ||||
-rw-r--r-- | templates/staff/tables/edit.html | 50 | ||||
-rw-r--r-- | templates/staff/tables/index.html | 32 | ||||
-rw-r--r-- | templates/staff/tables/table.html | 165 |
16 files changed, 0 insertions, 3996 deletions
diff --git a/templates/staff/index.html b/templates/staff/index.html deleted file mode 100644 index 31fddceb..00000000 --- a/templates/staff/index.html +++ /dev/null @@ -1,23 +0,0 @@ -{% extends "main/base.html" %} -{% block title %}Staff | Home{% endblock %} -{% block og_title %}Staff | Home{% endblock %} -{% block og_description %}Landing page for the staff management area{% endblock %} -{% block content %} - <div class="uk-container uk-container-small uk-section"> - <h1 class="uk-text-center"> - Management links - </h1> - - <a class="uk-button uk-button-primary" href="{{ url_for("staff.jams.index") }}">Code Jams</a> - {% if manager %} - <a class="uk-button uk-button-primary" href="{{ url_for("staff.tables.index") }}">Table Management</a> - {% endif %} - - <h1 class="uk-title uk-text-center"> - App config - </h1> - <pre> - {{ app_config | safe }} - </pre> - </div> -{% endblock %}
\ No newline at end of file diff --git a/templates/staff/jams/create.html b/templates/staff/jams/create.html deleted file mode 100644 index c19addd3..00000000 --- a/templates/staff/jams/create.html +++ /dev/null @@ -1,78 +0,0 @@ -{% extends "main/base.html" %} -{% block title %}Staff | Jams | Create{% endblock %} -{% block og_title %}Staff | Jams | Create{% endblock %} -{% block og_description %}Create a brand new code jam{% endblock %} -{% block content %} - <div class="uk-container uk-container-small uk-section"> - <h1 class="uk-text-center">Code Jam: Create</h1> - - <form action="{{ url_for("staff.jams.create") }}" method="post" class="uk-form-horizontal"> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="title">Title</label> - </div> - - <div class="uk-form-controls uk-form-controls-text"> - <input class="uk-input" name="title" id="title" type="text" required /> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="number">Number</label> - </div> - - <div class="uk-form-controls uk-form-controls-text"> - <input class="uk-input" name="number" id="number" type="text" value="{{ number }}" disabled /> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="date_start">Starting date (UTC)</label> - </div> - - <div class="uk-form-controls uk-form-controls-text"> - <input class="uk-input" name="date_start" id="date_start" type="text" required /> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="date_end">Ending date (UTC)</label> - </div> - - <div class="uk-form-controls uk-form-controls-text"> - <input class="uk-input" name="date_end" id="date_end" type="text" required /> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="state">State</label> - </div> - - <div class="uk-form-controls uk-form-controls-text"> - <select class="uk-select" name="state" id="state" disabled> - <option value="planning" selected>Planning</option> - </select> - </div> - </div> - - <input type="hidden" name="csrf_token" id="csrf_token" value="{{ csrf_token() }}"/> - - <div class="uk-align-center uk-text-center"> - <a id="back" class="uk-button uk-button-default" href="{{ url_for("staff.jams.index") }}"> - <i class="uk-icon fa-fw far fa-arrow-left"></i> Back - </a> - <button id="done" class="uk-button uk-button-primary" type="submit"> - <i class="uk-icon fa-fw far fa-check"></i> Done - </button> - </div> - </form> - - </div> - - <script type="application/javascript"> - window.onload = () => { - const date_start = flatpickr("#date_start", {enableTime: true, altInput: true}); - const date_end = flatpickr("#date_end", {enableTime: true, altInput: true}); - } - </script> -{% endblock %} diff --git a/templates/staff/jams/edit_basics.html b/templates/staff/jams/edit_basics.html deleted file mode 100644 index 1208e5d2..00000000 --- a/templates/staff/jams/edit_basics.html +++ /dev/null @@ -1,79 +0,0 @@ -{% extends "main/base.html" %} -{% block title %}Staff | Jams | Edit (Basics){% endblock %} -{% block og_title %}Staff | Jams | Edit (Basics){% endblock %} -{% block og_description %}Edit the basic info for a code jam{% endblock %} -{% block page_classes %}uses-rst{% endblock %} - -{% block content %} - <div class="uk-container uk-container-small uk-section"> - <h1 class="uk-text-center">Code Jam: Edit (Basics)</h1> - - <form action="{{ url_for("staff.jams.edit.basics", jam=jam.number) }}" method="post" class="uk-form-horizontal"> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="title">Title</label> - </div> - - <div class="uk-form-controls uk-form-controls-text"> - <input class="uk-input" name="title" id="title" type="text" value="{{ jam.title }}" required /> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="number">Number</label> - </div> - - <div class="uk-form-controls uk-form-controls-text"> - <input class="uk-input" name="number" id="number" type="text" value="{{ jam.number }}" disabled /> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="date_start">Starting date (UTC)</label> - </div> - - <div class="uk-form-controls uk-form-controls-text"> - <input class="uk-input" name="date_start" id="date_start" type="text" value="{{ jam.date_start }}" required /> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="date_end">Ending date (UTC)</label> - </div> - - <div class="uk-form-controls uk-form-controls-text"> - <input class="uk-input" name="date_end" id="date_end" type="text" value="{{ jam.date_end }}" required /> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="state">State</label> - </div> - - <div class="uk-form-controls uk-form-controls-text"> - <select class="uk-select" name="state" id="state" disabled> - <option value="{{ jam.state }}" selected>{{ jam.state.title() }}</option> - </select> - </div> - </div> - - <input type="hidden" name="csrf_token" id="csrf_token" value="{{ csrf_token() }}"/> - - <div class="uk-align-center uk-text-center"> - <a id="back" class="uk-button uk-button-default" href="{{ url_for("staff.jams.index") }}"> - <i class="uk-icon fa-fw far fa-arrow-left"></i> Back - </a> - <button id="done" class="uk-button uk-button-primary" type="submit"> - <i class="uk-icon fa-fw far fa-check"></i> Done - </button> - </div> - </form> - </div> - - <script type="application/javascript"> - window.onload = () => { - const date_start = flatpickr("#date_start", {enableTime: true, altInput: true}); - const date_end = flatpickr("#date_end", {enableTime: true, altInput: true}); - } - </script> -{% endblock %} diff --git a/templates/staff/jams/edit_ending.html b/templates/staff/jams/edit_ending.html deleted file mode 100644 index a0c5e8ff..00000000 --- a/templates/staff/jams/edit_ending.html +++ /dev/null @@ -1,152 +0,0 @@ -{% extends "main/base.html" %} -{% block title %}Staff | Jams | Edit (Ending Comments){% endblock %} -{% block og_title %}Staff | Jams | Edit (Ending Comments){% endblock %} -{% block og_description %}Edit the ending comments for a code jam{% endblock %} - -{% block page_classes %}uses-rst{% endblock %} - -{% block content %} - <div class="uk-container uk-container-small uk-section"> - <h1 class="uk-text-center">Code Jam: Edit (Ending Comments)</h1> - - <form action="{{ url_for("staff.jams.edit.ending", jam=jam.number) }}" method="post" class="uk-form-horizontal"> - <div> - <div class="uk-form-label"> - <label class="uk-form-label">Comments (RST)</label> - </div> - - <div class="uk-form-controls uk-form-controls-text"> - <div id="editor" class="uk-textarea">{{ jam.end_rst }}</div> - </div> - - <input type="hidden" name="end_rst" id="end_rst" value="{{ jam.end_rst }}" /> - </div> - - <input type="hidden" name="csrf_token" id="csrf_token" value="{{ csrf_token() }}"/> - - <div class="uk-align-center uk-text-center"> - <a id="back" class="uk-button uk-button-default" href="{{ url_for("staff.jams.index") }}"> - <i class="uk-icon fa-fw far fa-arrow-left"></i> Back - </a> - <button class="uk-button uk-button-secondary" type="button" id="preview"> - <i class="uk-icon fa-fw far fa-eye"></i> Preview - </button> - <button id="done" class="uk-button uk-button-primary" type="submit" disabled> - <i class="uk-icon fa-fw far fa-check"></i> Done - </button> - </div> - </form> - </div> - - <div id="preview-modal" class="uk-flex-top" uk-modal> - <div class="uk-modal-dialog"> - <button class="uk-modal-close-default" type="button" uk-close></button> - - <div class="uk-modal-body"> - <h2>Code Jam {{ jam.number }}: {{ jam.title }} <a href="{{ jam.repo }}" id="preview-url"><i class="uk-icon fa-fw fab fa-gitlab"></i></a></h2> - <p class="uk-text-meta">Theme: <span id="preview-theme">{{ jam.theme }}</span></p> - - <div id="preview-div"> - {{ jam.end_rst | safe }} - </div> - </div> - - <div class="uk-modal-footer"> - <div class="uk-text-center"> - <button class="uk-button uk-button-default uk-modal-close" type="button" id="state-cancel"> - <i class="uk-icon fa-fw far fa-arrow-left"></i> Close - </button> - </div> - </div> - </div> - </div> - - <script type="application/javascript"> - "use strict"; - - window.onload = () => { - let csrf_token = "{{ csrf_token() }}"; - let modal = UIkit.modal(document.getElementById("preview-modal")); - let preview_url = "{{ url_for("staff.render") }}"; - - function do_preview(callback) { - let oReq = new XMLHttpRequest(); - - oReq.addEventListener("load", function () { - let response = JSON.parse(this.responseText); - - if (response.error !== undefined) { - document.getElementById("done").disabled = true; - - if (response.error_lines !== undefined) { - editor.session.setAnnotations(response.error_lines); - document.getElementById("preview-div").innerHTML = "<h3>Error - see editor margin</h3>"; - } else { - console.log("Error: " + response.error); - document.getElementById("preview-div").innerHTML = "<h3>Error</h3><p>" + response.error + "<p>"; - } - } else { - document.getElementById("done").disabled = false; - document.getElementById("preview-div").innerHTML = response.data; - - editor.session.setAnnotations([]); - } - - if (callback !== undefined) { - callback(); - } - }); - - let data = editor.getValue(); - - if (data.replace("\s", "").length < 1) { - document.getElementById("done").disabled = true; - - if (callback !== undefined) { - UIkit.notification({ - "message": "Please enter some text to preview", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000 - }); - } - return false; - } - - oReq.open("POST", preview_url); - - oReq.setRequestHeader("Content-type", "application/json"); - oReq.setRequestHeader("X-CSRFToken", csrf_token); - - oReq.send(JSON.stringify({"data": editor.getValue()})); - - return false; - } - - document.getElementById("preview").onclick = function () { - do_preview(function () { - modal.show(); - }) - }; - - let editor = ace.edit("editor"); - let timer; - - editor.session.setMode("ace/mode/rst"); - editor.session.setUseWrapMode(true); - - editor.setTheme("ace/theme/iplastic"); - editor.setShowPrintMargin(false); - - editor.on("input", function () { - document.getElementById("done").disabled = true; - document.getElementById("end_rst").value = editor.getValue(); - - if (timer !== undefined) { - clearTimeout(timer); - } - timer = setTimeout(do_preview, 1000); - }); - }; - </script> -{% endblock %} diff --git a/templates/staff/jams/edit_info.html b/templates/staff/jams/edit_info.html deleted file mode 100644 index 75df1957..00000000 --- a/templates/staff/jams/edit_info.html +++ /dev/null @@ -1,309 +0,0 @@ -{% extends "main/base.html" %} -{% block title %}Staff | Jams | Edit (Info){% endblock %} -{% block og_title %}Staff | Jams | Edit (Info){% endblock %} -{% block og_description %}Edit the basic info for a code jam{% endblock %} - -{% block page_classes %}uses-rst{% endblock %} - -{% block content %} - <div class="uk-container uk-container-small uk-section"> - <h1 class="uk-text-center">Code Jam: Edit (Info)</h1> - - <form action="{{ url_for("staff.jams.edit.info", jam=jam.number) }}" method="post" class="uk-form-horizontal"> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="repo">Repo URL</label> - </div> - - <div class="uk-form-controls uk-form-controls-text"> - <input class="uk-input" name="repo" id="repo" type="text" value="{{ jam.repo }}" required /> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="theme">Theme</label> - </div> - - <div class="uk-form-controls uk-form-controls-text"> - <input class="uk-input" name="theme" id="theme" type="text" value="{{ jam.theme }}" required /> - </div> - </div> - - <div> - <div class="uk-form-label"> - <label class="uk-form-label"> - Info (RST) - <br /> - <span class="uk-text-meta">Will be available as soon as the jam state is "Announced"</span> - <br /> - <br /> - <button class="uk-button uk-button-secondary" type="button" id="preview-info-button"> - <i class="uk-icon fa-fw far fa-eye"></i> Preview - </button> - </label> - </div> - - <div class="uk-form-controls uk-form-controls-text"> - <div id="info_editor" class="uk-textarea editor">{{ jam.info_rst }}</div> - </div> - - <input type="hidden" name="info_rst" id="info_rst" value="{{ jam.info_rst }}" /> - </div> - - <div> - <div class="uk-form-label"> - <label class="uk-form-label"> - Task (RST) - <br/> - <span class="uk-text-meta">Will not be available until the jam state is "Running"</span> - <br /> - <br /> - <button class="uk-button uk-button-secondary" type="button" id="preview-task-button"> - <i class="uk-icon fa-fw far fa-eye"></i> Preview - </button> - </label> - </div> - - <div class="uk-form-controls uk-form-controls-text"> - <div id="task_editor" class="uk-textarea editor">{{ jam.task_rst }}</div> - </div> - - <input type="hidden" name="task_rst" id="task_rst" value="{{ jam.task_rst }}" /> - </div> - - <input type="hidden" name="csrf_token" id="csrf_token" value="{{ csrf_token() }}"/> - - <div class="uk-align-center uk-text-center"> - <a id="back" class="uk-button uk-button-default" href="{{ url_for("staff.jams.index") }}"> - <i class="uk-icon fa-fw far fa-arrow-left"></i> Back - </a> - <button id="done" class="uk-button uk-button-primary" type="submit" disabled> - <i class="uk-icon fa-fw far fa-check"></i> Done - </button> - </div> - </form> - </div> - - <div id="preview-info-modal" class="uk-flex-top" uk-modal> - <div class="uk-modal-dialog"> - <button class="uk-modal-close-default" type="button" uk-close></button> - - <div class="uk-modal-body"> - <h2>Code Jam {{ jam.number }}: {{ jam.title }} <a href="{{ jam.repo }}" id="preview-info-url"><i class="uk-icon fa-fw fab fa-gitlab"></i></a></h2> - <p class="uk-text-meta">Theme: <span id="preview-info-theme">{{ jam.theme }}</span></p> - - <div id="preview-info-div"> - {{ jam.task_html | safe }} - </div> - </div> - - <div class="uk-modal-footer"> - <div class="uk-text-center"> - <button class="uk-button uk-button-default uk-modal-close" type="button" id="state-cancel"> - <i class="uk-icon fa-fw far fa-arrow-left"></i> Close - </button> - </div> - </div> - </div> - </div> - - <div id="preview-task-modal" class="uk-flex-top" uk-modal> - <div class="uk-modal-dialog"> - <button class="uk-modal-close-default" type="button" uk-close></button> - - <div class="uk-modal-body"> - <h2>Code Jam {{ jam.number }}: {{ jam.title }} <a href="{{ jam.repo }}" id="preview-task-url"><i class="uk-icon fa-fw fab fa-gitlab"></i></a></h2> - <p class="uk-text-meta">Theme: <span id="preview-task-theme">{{ jam.theme }}</span></p> - - <div id="preview-task-div"> - {{ jam.task_html | safe }} - </div> - </div> - - <div class="uk-modal-footer"> - <div class="uk-text-center"> - <button class="uk-button uk-button-default uk-modal-close" type="button" id="state-cancel"> - <i class="uk-icon fa-fw far fa-arrow-left"></i> Close - </button> - </div> - </div> - </div> - </div> - - <script type="application/javascript"> - "use strict"; - - window.onload = () => { - let csrf_token = "{{ csrf_token() }}"; - let info_modal = UIkit.modal(document.getElementById("preview-info-modal")); - let task_modal = UIkit.modal(document.getElementById("preview-task-modal")); - let preview_url = "{{ url_for("staff.render") }}"; - - function do_preview_info(callback) { - let oReq = new XMLHttpRequest(); - - oReq.addEventListener("load", function () { - let response = JSON.parse(this.responseText); - - if (response.error !== undefined) { - document.getElementById("done").disabled = true; - - if (response.error_lines !== undefined) { - info_editor.session.setAnnotations(response.error_lines); - document.getElementById("preview-info-div").innerHTML = "<h3>Error - see editor margin</h3>"; - } else { - console.log("Error: " + response.error); - document.getElementById("preview-info-div").innerHTML = "<h3>Error</h3><p>" + response.error + "<p>"; - } - } else { - document.getElementById("done").disabled = false; - document.getElementById("preview-info-div").innerHTML = response.data; - - info_editor.session.setAnnotations([]); - } - - if (callback !== undefined) { - callback(); - } - }); - - let data = info_editor.getValue(); - - if (data.replace("\s", "").length < 1) { - document.getElementById("done").disabled = true; - - if (callback !== undefined) { - UIkit.notification({ - "message": "Please enter some text to preview", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000 - }); - } - return false; - } - - oReq.open("POST", preview_url); - - oReq.setRequestHeader("Content-type", "application/json"); - oReq.setRequestHeader("X-CSRFToken", csrf_token); - - oReq.send(JSON.stringify({"data": data})); - - return false; - } - - function do_preview_task(callback) { - let oReq = new XMLHttpRequest(); - - oReq.addEventListener("load", function () { - let response = JSON.parse(this.responseText); - - if (response.error !== undefined) { - document.getElementById("done").disabled = true; - - if (response.error_lines !== undefined) { - task_editor.session.setAnnotations(response.error_lines); - document.getElementById("preview-task-div").innerHTML = "<h3>Error - see editor margin</h3>"; - } else { - console.log("Error: " + response.error); - document.getElementById("preview-task-div").innerHTML = "<h3>Error</h3><p>" + response.error + "<p>"; - } - } else { - document.getElementById("done").disabled = false; - document.getElementById("preview-task-div").innerHTML = response.data; - - task_editor.session.setAnnotations([]); - } - - if (callback !== undefined) { - callback(); - } - }); - - let data = task_editor.getValue(); - - if (data.replace("\s", "").length < 1) { - document.getElementById("done").disabled = true; - - if (callback !== undefined) { - UIkit.notification({ - "message": "Please enter some text to preview", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000 - }); - } - return false; - } - - oReq.open("POST", preview_url); - - oReq.setRequestHeader("Content-type", "application/json"); - oReq.setRequestHeader("X-CSRFToken", csrf_token); - - oReq.send(JSON.stringify({"data": data})); - - return false; - } - - document.getElementById("preview-task-button").onclick = function () { - do_preview_task(function () { - task_modal.show(); - }) - }; - - document.getElementById("preview-info-button").onclick = function () { - do_preview_info(function () { - info_modal.show(); - }) - }; - - document.getElementById("theme").oninput = function () { - document.getElementById("preview-task-theme").textContent = this.value; - document.getElementById("preview-info-theme").textContent = this.value; - }; - - document.getElementById("repo").oninput = function () { - document.getElementById("preview-task-url").href = this.value; - document.getElementById("preview-info-url").href = this.value; - }; - - let info_editor = ace.edit("info_editor"); - let task_editor = ace.edit("task_editor"); - let info_timer, task_timer; - - info_editor.session.setMode("ace/mode/rst"); - info_editor.session.setUseWrapMode(true); - - info_editor.setTheme("ace/theme/iplastic"); - info_editor.setShowPrintMargin(false); - - info_editor.on("input", function () { - document.getElementById("done").disabled = true; - document.getElementById("info_rst").value = info_editor.getValue(); - - if (info_timer !== undefined) { - clearTimeout(info_timer); - } - info_timer = setTimeout(do_preview_info, 1000); - }); - - task_editor.session.setMode("ace/mode/rst"); - task_editor.session.setUseWrapMode(true); - - task_editor.setTheme("ace/theme/iplastic"); - task_editor.setShowPrintMargin(false); - - task_editor.on("input", function () { - document.getElementById("done").disabled = true; - document.getElementById("task_rst").value = task_editor.getValue(); - - if (task_timer !== undefined) { - clearTimeout(task_timer); - } - task_timer = setTimeout(do_preview_task, 1000); - }); - }; - </script> -{% endblock %} diff --git a/templates/staff/jams/forms/preamble_edit.html b/templates/staff/jams/forms/preamble_edit.html deleted file mode 100644 index 85747713..00000000 --- a/templates/staff/jams/forms/preamble_edit.html +++ /dev/null @@ -1,150 +0,0 @@ -{% extends "main/base.html" %} -{% block title %}Staff | Forms | Edit Preamble{% endblock %} -{% block og_title %}Staff | Forms | Edit Preamble{% endblock %} - -{% block page_classes %}uses-rst{% endblock %} - -{% block content %} - <div class="uk-container uk-container-small uk-section"> - <h1 class="uk-text-center">Form: Edit Preamble</h1> - - <form action="{{ url_for("staff.jams.forms.preamble.edit", jam=jam.number) }}" method="post" class="uk-form-horizontal"> - <div> - <div class="uk-form-label"> - <label class="uk-form-label">Preamble (RST)</label> - </div> - - <div class="uk-form-controls uk-form-controls-text"> - <div id="editor" class="uk-textarea">{{ form.preamble_rst }}</div> - </div> - - <input type="hidden" name="preamble_rst" id="preamble_rst" value="{{ form.preamble_rst }}" /> - </div> - - <input type="hidden" name="csrf_token" id="csrf_token" value="{{ csrf_token() }}"/> - - <div class="uk-align-center uk-text-center"> - <a id="back" class="uk-button uk-button-default" href="{{ url_for("staff.jams.forms.view", jam=jam.number) }}"> - <i class="uk-icon fa-fw far fa-arrow-left"></i> Back - </a> - <button class="uk-button uk-button-secondary" type="button" id="preview"> - <i class="uk-icon fa-fw far fa-eye"></i> Preview - </button> - <button id="done" class="uk-button uk-button-primary" type="submit" disabled> - <i class="uk-icon fa-fw far fa-check"></i> Done - </button> - </div> - </form> - </div> - - <div id="preview-modal" class="uk-flex-top" uk-modal> - <div class="uk-modal-dialog"> - <button class="uk-modal-close-default" type="button" uk-close></button> - - <div class="uk-modal-body"> - <h2>Form: {{ jam.number }}</h2> - - <div id="preview-div"> - {{ jam.preamble_html | safe }} - </div> - </div> - - <div class="uk-modal-footer"> - <div class="uk-text-center"> - <button class="uk-button uk-button-default uk-modal-close" type="button" id="state-cancel"> - <i class="uk-icon fa-fw far fa-arrow-left"></i> Close - </button> - </div> - </div> - </div> - </div> - - <script type="application/javascript"> - "use strict"; - - window.onload = () => { - let csrf_token = "{{ csrf_token() }}"; - let modal = UIkit.modal(document.getElementById("preview-modal")); - let preview_url = "{{ url_for("staff.render") }}"; - - function do_preview(callback) { - let oReq = new XMLHttpRequest(); - - oReq.addEventListener("load", function () { - let response = JSON.parse(this.responseText); - - if (response.error !== undefined) { - document.getElementById("done").disabled = true; - - if (response.error_lines !== undefined) { - editor.session.setAnnotations(response.error_lines); - document.getElementById("preview-div").innerHTML = "<h3>Error - see editor margin</h3>"; - } else { - console.log("Error: " + response.error); - document.getElementById("preview-div").innerHTML = "<h3>Error</h3><p>" + response.error + "<p>"; - } - } else { - document.getElementById("done").disabled = false; - document.getElementById("preview-div").innerHTML = response.data; - - editor.session.setAnnotations([]); - } - - if (callback !== undefined) { - callback(); - } - }); - - let data = editor.getValue(); - - if (data.replace("\s", "").length < 1) { - document.getElementById("done").disabled = true; - - if (callback !== undefined) { - UIkit.notification({ - "message": "Please enter some text to preview", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000 - }); - } - return false; - } - - oReq.open("POST", preview_url); - - oReq.setRequestHeader("Content-type", "application/json"); - oReq.setRequestHeader("X-CSRFToken", csrf_token); - - oReq.send(JSON.stringify({"data": editor.getValue()})); - - return false; - } - - document.getElementById("preview").onclick = function () { - do_preview(function () { - modal.show(); - }) - }; - - let editor = ace.edit("editor"); - let timer; - - editor.session.setMode("ace/mode/rst"); - editor.session.setUseWrapMode(true); - - editor.setTheme("ace/theme/iplastic"); - editor.setShowPrintMargin(false); - - editor.on("input", function () { - document.getElementById("done").disabled = true; - document.getElementById("preamble_rst").value = editor.getValue(); - - if (timer !== undefined) { - clearTimeout(timer); - } - timer = setTimeout(do_preview, 1000); - }); - }; - </script> -{% endblock %} diff --git a/templates/staff/jams/forms/questions_edit.html b/templates/staff/jams/forms/questions_edit.html deleted file mode 100644 index d6fe082c..00000000 --- a/templates/staff/jams/forms/questions_edit.html +++ /dev/null @@ -1,354 +0,0 @@ -{% extends "main/base.html" %} -{% block title %}Staff | Jams | Question Edit{% endblock %} -{% block og_title %}Staff | Jams | Question Edit{% endblock %} -{% block og_description %}Edit a question{% endblock %} -{% block content %} - <div class="uk-container uk-container-small uk-section"> - <h1>Question Edit</h1> - - <form class="uk-form-horizontal" method="post" action="{{ url_for("staff.jams.forms.questions.edit", question=question.id) }}"> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="title">Title</label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <input type="text" id="title" name="title" class="uk-input" value="{{ question.title }}"> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="optional">Optional</label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <select class="uk-select" id="optional" name="optional"> - {% if question.optional %} - <option value="optional" selected>Optional</option> - <option value="required">Required</option> - {% else %} - <option value="optional">Optional</option> - <option value="required" selected>Required</option> - {% endif %} - </select> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="type">Type</label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <select class="uk-select" id="type" name="type"> - {% if question.type == "checkbox" %} - <option value="checkbox" selected>Checkbox</option> - {% else %} - <option value="checkbox">Checkbox</option> - {% endif %} - - {% if question.type == "email" %} - <option value="email" selected>Email</option> - {% else %} - <option value="email">Email</option> - {% endif %} - - {% if question.type == "number" %} - <option value="number" selected>Number</option> - {% else %} - <option value="number">Number</option> - {% endif %} - - {% if question.type == "radio" %} - <option value="radio" selected>Radio</option> - {% else %} - <option value="radio">Radio</option> - {% endif %} - - {% if question.type == "range" %} - <option value="range" selected>Range</option> - {% else %} - <option value="range">Range</option> - {% endif %} - - {% if question.type == "slider" %} - <option value="slider" selected>Slider</option> - {% else %} - <option value="slider">Slider</option> - {% endif %} - - {% if question.type == "textarea" %} - <option value="textarea" selected>Text (Block)</option> - {% else %} - <option value="textarea">Text (Block)</option> - {% endif %} - - {% if question.type == "text" %} - <option value="text" selected>Text (Line)</option> - {% else %} - <option value="text">Text (Line)</option> - {% endif %} - </select> - </div> - </div> - - {% if question.type == "radio" %} - <div id="radio-section"> - {% else %} - <div id="radio-section" hidden="hidden"> - {% endif %} - <br /> - <div> - <div class="uk-form-label"> - <button type="button" class="uk-button uk-button-primary uk-width-1-1" id="radio-add-button"><i class="uk-icon fa-fw far fa-plus"></i> Add</button> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <input type="text" id="radio-add-input" class="uk-input" placeholder="Item"> - </div> - </div> - <div> - <div class="uk-form-label"> - <button type="button" class="uk-button uk-button-danger uk-width-1-1" id="radio-remove-button"><i class="uk-icon fa-fw far fa-minus"></i> Remove</button> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <select class="uk-select" id="radio-options"> - <option hidden="hidden" disabled selected value="none"></option> - - {% for option in question.data.options %} - <option value="{{ option }}">{{ option }}</option> - {% endfor %} - </select> - {% if question.data.options %} - <input type="hidden" id="options" name="options" value="{{ "{\"options\": " + question.data.options.__str__() + "}" | safe }}"> - {% else %} - <input type="hidden" id="options" name="options" value="{{ "{\"options\": []}" }}"> - {% endif %} - </div> - </div> - </div> - - {% if question.type in ["number", "range", "slider"] %} - <div id="number-section"> - {% else %} - <div id="number-section" hidden="hidden"> - {% endif %} - <br /> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="min">Min Value</label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <input type="text" id="min" name="min" class="uk-input" value="{{ question.data.min }}"> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="max">Max Value</label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <input type="text" id="max" name="max" class="uk-input" value="{{ question.data.max }}"> - </div> - </div> - </div> - - <br /> - - <div> - <input type="hidden" name="csrf_token" id="csrf_token" value="{{ csrf_token() }}"/> - - <a class="uk-button uk-button-danger uk-modal-close" href="{{ url_for("staff.jams.forms.questions") }}"> - <i class="uk-icon fa-fw far fa-times"></i> Cancel - </a> - <button class="uk-button uk-button-primary" type="submit" id="question-submit"> - <i class="uk-icon fa-fw far fa-check"></i> Save - </button> - </div> - </form> - </div> - - <script type="application/javascript"> - "use strict"; - const new_question_title = document.getElementById("title"); - const new_question_optional = document.getElementById("optional"); - const new_question_type = document.getElementById("type"); - - const radio_section = document.getElementById("radio-section"); - - const radio_add_button = document.getElementById("radio-add-button"); - const radio_add_input = document.getElementById("radio-add-input"); - const radio_remove_button = document.getElementById("radio-remove-button"); - const radio_options = document.getElementById("radio-options"); - const hidden_radio_options = document.getElementById("options"); - - const number_section = document.getElementById("number-section"); - - const number_min = document.getElementById("min"); - const number_max = document.getElementById("max"); - - const submit_button = document.getElementById("question-submit"); - - let current_radio_options; - - {% if question.data.options %} - current_radio_options = {{ question.data.options | safe }}; - {% else %} - current_radio_options = Array(); - {% endif %} - - new_question_type.onchange = function() { - if (this.value === "checkbox") { - radio_section.setAttribute("hidden", "hidden"); - number_section.setAttribute("hidden", "hidden"); - } else if (this.value === "email") { - radio_section.setAttribute("hidden", "hidden"); - number_section.setAttribute("hidden", "hidden"); - } else if (this.value === "number") { - radio_section.setAttribute("hidden", "hidden"); - number_section.removeAttribute("hidden"); - } else if (this.value === "radio") { - radio_section.removeAttribute("hidden"); - number_section.setAttribute("hidden", "hidden"); - } else if (this.value === "range") { - radio_section.setAttribute("hidden", "hidden"); - number_section.removeAttribute("hidden"); - } else if (this.value === "slider") { - radio_section.setAttribute("hidden", "hidden"); - number_section.removeAttribute("hidden"); - } else if (this.value === "textarea") { - radio_section.setAttribute("hidden", "hidden"); - number_section.setAttribute("hidden", "hidden"); - } else if (this.value === "text") { - radio_section.setAttribute("hidden", "hidden"); - number_section.setAttribute("hidden", "hidden"); - } else { - radio_section.setAttribute("hidden", "hidden"); - number_section.setAttribute("hidden", "hidden"); - } - - checkValid(); - }; - - new_question_title.oninput = checkValid; - new_question_optional.onchange = checkValid; - - radio_add_input.onkeyup = function(event) { - event.preventDefault(); - - if (event.which === 13 || event.keyCode === 13) { - radio_add_button.onclick(undefined); - } - }; - - radio_add_button.onclick = function() { - let value = radio_add_input.value; - - if (value.length < 1) { - radio_add_input.classList.add("uk-form-danger"); - radio_add_input.focus(); - } else { - let index = current_radio_options.indexOf(value); - - if (index > -1 || value === "none") { - radio_add_input.classList.add("uk-form-danger"); - radio_add_input.focus(); - } else { - radio_add_input.classList.remove("uk-form-danger"); - radio_add_input.value = ""; - - let element = document.createElement("option"); - element.value = value; - element.text = value; - - radio_options.appendChild(element); - current_radio_options.push(value); - hidden_radio_options.value = JSON.stringify({"options": current_radio_options}); - } - } - - checkValid(); - }; - - radio_remove_button.onclick = function() { - let value = radio_options.value; - - if (value === "none") { - return; - } - - let index = current_radio_options.indexOf(value); - - if (index < 0) { // We have a problem! - console.log("Unable to remove value from radio values because it doesn't exist: " + value) - } else { - current_radio_options.splice(index, 1); - } - - for (let element of radio_options.getElementsByTagName("option")) { - if (element.value === "none") { - continue; - } - - if (element.value === value) { - radio_options.removeChild(element); - } - } - - hidden_radio_options.value = JSON.stringify({"options": current_radio_options}); - radio_options.value = "none"; - radio_add_input.focus(); - checkValid(); - }; - - number_min.oninput = function() { - if (this.value.length > 0 && isNaN(parseInt(this.value))) { - this.classList.add("uk-form-danger") - } else { - this.classList.remove("uk-form-danger") - } - - checkValid(); - }; - - number_max.oninput = function() { - if (this.value.length > 0 && isNaN(parseInt(this.value))) { - this.classList.add("uk-form-danger") - } else { - this.classList.remove("uk-form-danger") - } - - checkValid(); - }; - - function checkValid() { - if (new_question_title.value.length < 1) { - return setButtonEnabled(false); - } - - let question_type = new_question_type.value; - - if (question_type === "radio") { - if (current_radio_options.length < 1) { - return setButtonEnabled(false); - } - } - - if ( question_type === "number" - || question_type === "range" - || question_type === "slider" - ) { - if (isNaN(parseInt(number_min.value))) { - return setButtonEnabled(false); - } - if (isNaN(parseInt(number_max.value))) { - return setButtonEnabled(false); - } - - if (number_min.value.length < 1 || number_max.value.length < 1) { - return setButtonEnabled(false); - } - } - - return setButtonEnabled(true); - } - - function setButtonEnabled(enabled) { - submit_button.disabled = !enabled; - } - </script> -{% endblock %} diff --git a/templates/staff/jams/forms/questions_view.html b/templates/staff/jams/forms/questions_view.html deleted file mode 100644 index f8eeea40..00000000 --- a/templates/staff/jams/forms/questions_view.html +++ /dev/null @@ -1,593 +0,0 @@ -{% extends "main/base.html" %} -{% block title %}Staff | Jams | Questions{% endblock %} -{% block og_title %}Staff | Jams | Questions{% endblock %} -{% block og_description %}Manage all created questions{% endblock %} -{% block content %} - <div class="uk-container uk-container-small uk-section"> - <h1>Questions List</h1> - - <a class="uk-button uk-button-default" href="{{ url_for("staff.jams.index") }}"><i class="uk-icon fa-fw far fa-arrow-left"></i> Back</a> - <button class="uk-button uk-button-primary" id="add-button"><i class="uk-icon fa-fw far fa-plus"></i> Add Question</button> - {# <a class="uk-button uk-button-secondary" target="_blank" href="{{ url_for("staff.index") }}"><i class="uk-icon fa-fw far fa-eye"></i> Preview</a> #} - - {% if not questions %} - <p id="no-questions-paragraph">No questions found. Add one above!</p> - <table class="uk-table uk-table-divider uk-table-striped uk-border" id="table" hidden="hidden"> - <thead> - <tr> - <th class="uk-table-shrink"> </th> - <th><strong>ID</strong></th> - <th class="uk-table-shrink">Optional</th> - <th>Title</th> - <th class="uk-table-shrink">Type</th> - <th>Data</th> - </tr> - </thead> - <tbody id="table-body"> - </tbody> - </table> - {% else %} - <p id="no-questions-paragraph" hidden="hidden">No questions found. Add one above!</p> - - <div class="uk-overflow-auto"> - <br /> - <table class="uk-table uk-table-divider uk-table-striped uk-border" id="table"> - <thead> - <tr> - <th class="uk-table-shrink"> </th> - <th><strong>ID</strong></th> - <th class="uk-table-shrink">Optional</th> - <th>Title</th> - <th class="uk-table-shrink">Type</th> - <th>Data</th> - </tr> - </thead> - <tbody id="table-body"> - {% for question in questions %} - <tr id="row-{{ question.id }}"> - <td class="uk-table-shrink"> - <button class="uk-button-small uk-button uk-button-danger delete-question-button" data-question-id="{{ question.id }}"><i class="uk-icon fa-fw far fa-trash"></i></button> - <a href="{{ url_for("staff.jams.forms.questions.edit", question=question.id) }}" class="uk-button-small uk-button uk-button-primary edit-question-button"><i class="uk-icon fa-fw far fa-pencil"></i></a> - </td> - <td class="uk-text-truncate" title="{{ question.id }}">{{ question.id }}</td> - <td class="uk-table-shrink"> - {% if question.optional %} - <i class="uk-icon uk-text-success fa-fw far fa-check"></i> - {% else %} - <i class="uk-icon uk-text-danger fa-fw far fa-times"></i> - {% endif %} - </td> - <td title="{{ question.title }}">{{ question.title }}</td> - <td class="uk-table-shrink" title="{{ question.type.title() }}">{{ question.type.title() }}</td> - <td> - {% if question.type == "text" %} - - {% elif question.type == "number" %} - <i class="uk-icon fa-fw far fa-arrow-up" title="Max value"></i> {{ question.data.max }} - <br /> - <i class="uk-icon fa-fw far fa-arrow-down" title="Min value"></i> {{ question.data.min }} - {% elif question.type == "checkbox" %} - - {% elif question.type == "email" %} - - {% elif question.type == "textarea" %} - - {% elif question.type == "radio" %} - <ul> - {% for option in question.data.options %} - <li>{{ option }}</li> - {% endfor %} - </ul> - {% elif question.type == "range" %} - <i class="uk-icon fa-fw far fa-arrow-up" title="Max value"></i> {{ question.data.max }} - <br /> - <i class="uk-icon fa-fw far fa-arrow-down" title="Min value"></i> {{ question.data.min }} - {% elif question.type == "slider" %} - <i class="uk-icon fa-fw far fa-arrow-up" title="Max value"></i> {{ question.data.max }} - <br /> - <i class="uk-icon fa-fw far fa-arrow-down" title="Min value"></i> {{ question.data.min }} - {% else %} - {{ question.data }} - {% endif %} - </td> - </tr> - {% endfor %} - </tbody> - </table> - </div> - {% endif %} - </div> - - <div id="question-modal" class="uk-flex-top" uk-modal> - <div class="uk-modal-dialog"> - <button class="uk-modal-close-default" type="button" uk-close></button> - - <div class="uk-modal-header"> - <h2 class="uk-modal-title">Add Question</h2> - </div> - - <div class="uk-modal-body"> - <form class="uk-form-horizontal"> - <div id="loading-spinner" class="uk-text-center uk-margin-small-top" hidden="hidden"> - <div uk-spinner></div> - </div> - <div id="new-question-section"> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="new-question-title">Title</label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <input type="text" id="new-question-title" class="uk-input"> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="new-question-optional">Optional</label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <select class="uk-select" id="new-question-optional"> - <option hidden="hidden" disabled selected value="none"></option> - <option value="optional">Optional</option> - <option value="required">Required</option> - </select> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="new-question-type">Type</label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <select class="uk-select" id="new-question-type"> - <option hidden="hidden" disabled selected value="none"></option> - <option value="checkbox">Checkbox</option> - <option value="email">Email</option> - <option value="number">Number</option> - <option value="radio">Radio</option> - <option value="range">Range</option> - <option value="slider">Slider</option> - <option value="textarea">Text (Block)</option> - <option value="text">Text (Line)</option> - </select> - </div> - </div> - </div> - - <div id="radio-section" hidden="hidden"> - <br /> - <div> - <div class="uk-form-label"> - <button type="button" class="uk-button uk-button-primary uk-width-1-1" id="radio-add-button"><i class="uk-icon fa-fw far fa-plus"></i> Add</button> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <input type="text" id="radio-add-input" class="uk-input" placeholder="Item"> - </div> - </div> - <div> - <div class="uk-form-label"> - <button type="button" class="uk-button uk-button-danger uk-width-1-1" id="radio-remove-button"><i class="uk-icon fa-fw far fa-minus"></i> Remove</button> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <select class="uk-select" id="radio-options"> - <option hidden="hidden" disabled selected value="none"></option> - </select> - </div> - </div> - </div> - - <div id="number-section" hidden="hidden"> - <br /> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="number-min">Min Value</label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <input type="text" id="number-min" class="uk-input"> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="number-max">Max Value</label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <input type="text" id="number-max" class="uk-input"> - </div> - </div> - </div> - </form> - </div> - - <div class="uk-modal-footer"> - <div class="uk-text-center"> - <button class="uk-button uk-button-danger uk-modal-close" type="button" id="state-cancel"> - <i class="uk-icon fa-fw far fa-times"></i> Cancel - </button> - <button class="uk-button uk-button-primary" type="button" id="question-submit" disabled> - <i class="uk-icon fa-fw far fa-check"></i> Save - </button> - </div> - </div> - </div> - </div> - - <script type="application/javascript"> - "use strict"; - - const actions = new JamActions("{{ url_for("staff.jams.action") }}", "{{ csrf_token() }}"); - const table_body = document.getElementById("table-body"); - const table = document.getElementById("table"); - const no_questions_paragraph = document.getElementById("no-questions-paragraph"); - - let all_questions = {{ question_ids | safe }}; - const question_edit_url = "{{ url_for("staff.jams.forms.questions.edit", question="NONE") }}"; - - const add_button = document.getElementById("add-button"); - const modal = UIkit.modal(document.getElementById("question-modal")); - const loading_spinner = document.getElementById("loading-spinner"); - - const new_question_section = document.getElementById("new-question-section"); - const new_question_title = document.getElementById("new-question-title"); - const new_question_optional = document.getElementById("new-question-optional"); - const new_question_type = document.getElementById("new-question-type"); - - const radio_section = document.getElementById("radio-section"); - - const radio_add_button = document.getElementById("radio-add-button"); - const radio_add_input = document.getElementById("radio-add-input"); - const radio_remove_button = document.getElementById("radio-remove-button"); - const radio_options = document.getElementById("radio-options"); - - const number_section = document.getElementById("number-section"); - - const number_min = document.getElementById("number-min"); - const number_max = document.getElementById("number-max"); - - const submit_button = document.getElementById("question-submit"); - - let current_radio_options = Array(); - - add_button.onclick = function() { - clearModal(); - checkModal(); - modal.show(); - }; - - new_question_type.onchange = function() { - if (this.value === "checkbox") { - radio_section.setAttribute("hidden", "hidden"); - number_section.setAttribute("hidden", "hidden"); - } else if (this.value === "email") { - radio_section.setAttribute("hidden", "hidden"); - number_section.setAttribute("hidden", "hidden"); - } else if (this.value === "number") { - radio_section.setAttribute("hidden", "hidden"); - number_section.removeAttribute("hidden"); - } else if (this.value === "radio") { - radio_section.removeAttribute("hidden"); - number_section.setAttribute("hidden", "hidden"); - } else if (this.value === "range") { - radio_section.setAttribute("hidden", "hidden"); - number_section.removeAttribute("hidden"); - } else if (this.value === "slider") { - radio_section.setAttribute("hidden", "hidden"); - number_section.removeAttribute("hidden"); - } else if (this.value === "textarea") { - radio_section.setAttribute("hidden", "hidden"); - number_section.setAttribute("hidden", "hidden"); - } else if (this.value === "text") { - radio_section.setAttribute("hidden", "hidden"); - number_section.setAttribute("hidden", "hidden"); - } else { - radio_section.setAttribute("hidden", "hidden"); - number_section.setAttribute("hidden", "hidden"); - } - - checkModal(); - }; - - new_question_title.oninput = checkModal; - new_question_optional.onchange = checkModal; - - radio_add_input.onkeyup = function(event) { - event.preventDefault(); - - if (event.which === 13 || event.keyCode === 13) { - radio_add_button.onclick(undefined); - } - }; - - radio_add_button.onclick = function() { - let value = radio_add_input.value; - - if (value.length < 1) { - radio_add_input.classList.add("uk-form-danger"); - radio_add_input.focus(); - } else { - let index = current_radio_options.indexOf(value); - - if (index > -1 || value === "none") { - radio_add_input.classList.add("uk-form-danger"); - radio_add_input.focus(); - } else { - radio_add_input.classList.remove("uk-form-danger"); - radio_add_input.value = ""; - - let element = document.createElement("option"); - element.value = value; - element.text = value; - - radio_options.appendChild(element); - current_radio_options.push(value); - } - } - - checkModal(); - }; - - radio_remove_button.onclick = function() { - let value = radio_options.value; - - if (value === "none") { - return; - } - - let index = current_radio_options.indexOf(value); - - if (index < 0) { // We have a problem! - console.log("Unable to remove value from radio values because it doesn't exist: " + value) - } else { - current_radio_options.splice(index, 1); - } - - for (let element of radio_options.getElementsByTagName("option")) { - if (element.value === "none") { - continue; - } - - if (element.value === value) { - radio_options.removeChild(element); - } - } - - radio_options.value = "none"; - radio_add_input.focus(); - checkModal(); - }; - - number_min.oninput = function() { - if (this.value.length > 0 && isNaN(parseInt(this.value))) { - this.classList.add("uk-form-danger") - } else { - this.classList.remove("uk-form-danger") - } - - checkModal(); - }; - - number_max.oninput = function() { - if (this.value.length > 0 && isNaN(parseInt(this.value))) { - this.classList.add("uk-form-danger") - } else { - this.classList.remove("uk-form-danger") - } - - checkModal(); - }; - - submit_button.onclick = function () { - let type = new_question_type.value; - let optional = new_question_optional.value === "optional"; - let title = new_question_title.value; - - let question_data = { - "type": type, - "optional": optional, - "title": title - }; - - if (type === "radio") { - question_data.data = {"options": current_radio_options}; - } else if (type === "number" - || type === "range" - || type === "slider") { - question_data.data = { - "max": parseInt(number_max.value), - "min": parseInt(number_min.value) - }; - } - - number_section.setAttribute("hidden", "hidden"); - new_question_section.setAttribute("hidden", "hidden"); - radio_section.setAttribute("hidden", "hidden"); - loading_spinner.removeAttribute("hidden"); - - actions.create_question(question_data, function(result, data) { - if (result) { - question_data["id"] = data.id; - addToTable(question_data); - modal.hide(); - clearModal(); - - UIkit.notification({ - "message": "Question added", - "status": "success", - "pos": "bottom-center", - "timeout": 5000, - }); - } else { - console.log(data); - UIkit.notification({ - "message": "Failed to create question", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000, - }); - } - }) - }; - - const toTitleCase = (str) => str.replace(/\b\S/g, t => t.toUpperCase()); - - function hookUpDeleteButtons() { - for (let element of document.getElementsByClassName("delete-question-button")) { - element.onclick = function() { - let question_id = this.getAttribute("data-question-id"); - let row = document.getElementById("row-" + question_id); - - actions.delete_question(question_id, function(result, data) { - if (result) { - document.getElementById("table-body").removeChild(row); - UIkit.notification({ - "message": "Question deleted", - "status": "success", - "pos": "bottom-center", - "timeout": 5000, - }); - } else { - console.log(data); - UIkit.notification({ - "message": "Failed to delete question", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000, - }); - } - }) - } - } - } - - function clearModal() { - // Existing question section - loading_spinner.setAttribute("hidden", "hidden"); - - new_question_section.removeAttribute("hidden"); - - // New question section - new_question_title.value = ""; - new_question_optional.value = "none"; - new_question_type.value = "none"; - - // Radio question section - radio_section.setAttribute("hidden", "hidden"); - - radio_add_input.value = ""; - radio_options.innerHTML = "<option hidden=\"hidden\" disabled selected value=\"none\"></option>"; - radio_options.value = "none"; - - current_radio_options = Array(); - - // Number question section - number_section.setAttribute("hidden", "hidden"); - } - - function checkModal() { - if (new_question_title.value.length < 1) { - return setButtonEnabled(false); - } - - if (new_question_optional.value === "none") { - return setButtonEnabled(false); - } - - let question_type = new_question_type.value; - - if (question_type === "none") { - return setButtonEnabled(false); - } - - if (question_type === "radio") { - if (current_radio_options.length < 1) { - return setButtonEnabled(false); - } - } - - if ( question_type === "number" - || question_type === "range" - || question_type === "slider" - ) { - if (isNaN(parseInt(number_min.value))) { - return setButtonEnabled(false); - } - if (isNaN(parseInt(number_max.value))) { - return setButtonEnabled(false); - } - - if (number_min.value.length < 1 || number_max.value.length < 1) { - return setButtonEnabled(false); - } - } - - return setButtonEnabled(true); - } - - function setButtonEnabled(enabled) { - submit_button.disabled = !enabled; - } - - function addToTable(question) { - console.log(question); - if (all_questions.indexOf(question.id) === -1) { - all_questions.push(question.id); - - let element = document.createElement("tr"); - element.id = "row-" + question.id; - element.innerHTML = getRowHTML(question); - - table_body.appendChild(element); - } - - if (all_questions.length > 0) { - table.removeAttribute("hidden"); - no_questions_paragraph.setAttribute("hidden", "hidden"); - } - hookUpDeleteButtons(); - } - - function getRowHTML(question) { - let optional; - let data; - - if (question.optional) { - optional = "<i class=\"uk-icon uk-text-success fa-fw far fa-check\"></i>" - } else { - optional = "<i class=\"uk-icon uk-text-danger fa-fw far fa-times\"></i>" - } - - if (question.type === "number" || question.type === "range" || question.type === "slider") { - data = ` -<i class="uk-icon fa-fw far fa-arrow-up" title="Max value"></i> ${question.data.max} -<br /> -<i class="uk-icon fa-fw far fa-arrow-down" title="Min value"></i> ${question.data.min} - ` - - } else if (question.type === "radio") { - data = "<ul>"; - - for (let option of question.data.options) { - data = data + `<li>${option}</li>` - } - data = data + "</ul>"; - } else { - data = "" - } - - let type = toTitleCase(question.type); - let q_url = question_edit_url.replace("NONE", question.id); - - const row = ` - <td class="uk-table-shrink"> - <button class="uk-button-small uk-button uk-button-danger delete-question-button" data-question-id="${question.id}"><i class="uk-icon fa-fw far fa-trash"></i></button> - <a href="${q_url}" class="uk-button-small uk-button uk-button-primary edit-question-button"><i class="uk-icon fa-fw far fa-pencil"></i></a> - </td> - <td class="uk-text-truncate" title="${question.id}">${question.id}</td> - <td class="uk-table-shrink">${optional}</td> - <td title="${question.title}">${question.title}</td> - <td class="uk-table-shrink" title="${type}">${type}</td> - <td>${data}</td> - `; - return row - } - - hookUpDeleteButtons(); - </script> -{% endblock %} diff --git a/templates/staff/jams/forms/view.html b/templates/staff/jams/forms/view.html deleted file mode 100644 index 49ea672d..00000000 --- a/templates/staff/jams/forms/view.html +++ /dev/null @@ -1,755 +0,0 @@ -{% extends "main/base.html" %} -{% block title %}Staff | Jams | Form{% endblock %} -{% block og_title %}Staff | Jams | Form{% endblock %} -{% block og_description %}Manage the form for a code jam{% endblock %} -{% block content %} - <div class="uk-container uk-container-small uk-section"> - <h1>Application Form {{ jam.number }}: {{ jam.title }}</h1> - - <a class="uk-button uk-button-default" href="{{ url_for("staff.jams.index") }}"><i class="uk-icon fa-fw far fa-arrow-left"></i> Back</a> - <a class="uk-button uk-button-secondary" href="{{ url_for("staff.jams.forms.preamble.edit", jam=jam.number) }}" id="preamble-button"><i class="uk-icon fa-fw far fa-pencil"></i> Edit Preamble</a> - <button class="uk-button uk-button-primary" id="add-button"><i class="uk-icon fa-fw far fa-plus"></i> Add Question</button> - {# <a class="uk-button uk-button-secondary" target="_blank" href="{{ url_for("staff.index") }}"><i class="uk-icon fa-fw far fa-eye"></i> Preview</a> #} - - {% if not questions %} - <p id="no-questions-paragraph">No questions found. Add one above!</p> - <table class="uk-table uk-table-divider uk-table-striped uk-border" id="table" hidden="hidden"> - <thead> - <tr> - <th class="uk-table-shrink"> </th> - <th><strong>ID</strong></th> - <th class="uk-table-shrink">Optional</th> - <th>Title</th> - <th class="uk-table-shrink">Type</th> - <th>Data</th> - </tr> - </thead> - <tbody id="table-body"> - </tbody> - </table> - {% else %} - <p id="no-questions-paragraph" hidden="hidden">No questions found. Add one above!</p> - - <div class="uk-overflow-auto"> - <br /> - <table class="uk-table uk-table-divider uk-table-striped uk-border" id="table"> - <thead> - <tr> - <th class="uk-table-shrink"> </th> - <th><strong>ID</strong></th> - <th class="uk-table-shrink">Optional</th> - <th>Title</th> - <th class="uk-table-shrink">Type</th> - <th>Data</th> - </tr> - </thead> - <tbody id="table-body"> - {% for question in questions %} - <tr id="row-{{ question.id }}"> - <td class="uk-table-shrink"> - <button class="uk-button-small uk-button uk-button-danger delete-question-button" data-question-id="{{ question.id }}"><i class="uk-icon fa-fw far fa-times"></i></button> - </td> - <td class="uk-text-truncate" title="{{ question.id }}">{{ question.id }}</td> - <td class="uk-table-shrink"> - {% if question.optional %} - <i class="uk-icon uk-text-success fa-fw far fa-check"></i> - {% else %} - <i class="uk-icon uk-text-danger fa-fw far fa-times"></i> - {% endif %} - </td> - <td title="{{ question.title }}">{{ question.title }}</td> - <td class="uk-table-shrink" title="{{ question.type.title() }}">{{ question.type.title() }}</td> - <td> - {% if question.type == "text" %} - - {% elif question.type == "number" %} - <i class="uk-icon fa-fw far fa-arrow-up" title="Max value"></i> {{ question.data.max }} - <br /> - <i class="uk-icon fa-fw far fa-arrow-down" title="Min value"></i> {{ question.data.min }} - {% elif question.type == "checkbox" %} - - {% elif question.type == "email" %} - - {% elif question.type == "textarea" %} - - {% elif question.type == "radio" %} - <ul> - {% for option in question.data.options %} - <li>{{ option }}</li> - {% endfor %} - </ul> - {% elif question.type == "range" %} - <i class="uk-icon fa-fw far fa-arrow-up" title="Max value"></i> {{ question.data.max }} - <br /> - <i class="uk-icon fa-fw far fa-arrow-down" title="Min value"></i> {{ question.data.min }} - {% elif question.type == "slider" %} - <i class="uk-icon fa-fw far fa-arrow-up" title="Max value"></i> {{ question.data.max }} - <br /> - <i class="uk-icon fa-fw far fa-arrow-down" title="Min value"></i> {{ question.data.min }} - {% else %} - {{ question.data }} - {% endif %} - </td> - </tr> - {% endfor %} - </tbody> - </table> - </div> - {% endif %} - </div> - - <div id="question-modal" class="uk-flex-top" uk-modal> - <div class="uk-modal-dialog"> - <button class="uk-modal-close-default" type="button" uk-close></button> - - <div class="uk-modal-header"> - <h2 class="uk-modal-title">Add Question</h2> - </div> - - <div class="uk-modal-body"> - <form class="uk-form-horizontal"> - <div id="question-source-section"> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="question-source">Source</label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <select class="uk-select" id="question-source" required> - <option hidden="hidden" disabled selected value="none"></option> - <option value="new">New</option> - <option value="existing">Existing</option> - </select> - </div> - </div> - </div> - <div id="loading-spinner" class="uk-text-center uk-margin-small-top" hidden="hidden"> - <div uk-spinner></div> - </div> - <div id="new-question-section" hidden="hidden"> - <br /> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="new-question-title">Title</label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <input type="text" id="new-question-title" class="uk-input"> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="new-question-optional">Optional</label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <select class="uk-select" id="new-question-optional"> - <option hidden="hidden" disabled selected value="none"></option> - <option value="optional">Optional</option> - <option value="required">Required</option> - </select> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="new-question-type">Type</label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <select class="uk-select" id="new-question-type"> - <option hidden="hidden" disabled selected value="none"></option> - <option value="checkbox">Checkbox</option> - <option value="email">Email</option> - <option value="number">Number</option> - <option value="radio">Radio</option> - <option value="range">Range</option> - <option value="slider">Slider</option> - <option value="textarea">Text (Block)</option> - <option value="text">Text (Line)</option> - </select> - </div> - </div> - </div> - - <div id="radio-section" hidden="hidden"> - <br /> - <div> - <div class="uk-form-label"> - <button type="button" class="uk-button uk-button-primary uk-width-1-1" id="radio-add-button"><i class="uk-icon fa-fw far fa-plus"></i> Add</button> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <input type="text" id="radio-add-input" class="uk-input" placeholder="Item"> - </div> - </div> - <div> - <div class="uk-form-label"> - <button type="button" class="uk-button uk-button-danger uk-width-1-1" id="radio-remove-button"><i class="uk-icon fa-fw far fa-minus"></i> Remove</button> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <select class="uk-select" id="radio-options"> - <option hidden="hidden" disabled selected value="none"></option> - </select> - </div> - </div> - </div> - - <div id="number-section" hidden="hidden"> - <br /> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="number-min">Min Value</label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <input type="text" id="number-min" class="uk-input"> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="number-max">Max Value</label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <input type="text" id="number-max" class="uk-input"> - </div> - </div> - </div> - - <div id="existing-question-section" hidden="hidden"> - <br /> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="existing-question">Question</label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <select class="uk-select" id="existing-question"> - <option hidden="hidden" disabled selected value="none"></option> - </select> - </div> - </div> - </div> - </form> - </div> - - <div class="uk-modal-footer"> - <div class="uk-text-center"> - <button class="uk-button uk-button-danger uk-modal-close" type="button" id="state-cancel"> - <i class="uk-icon fa-fw far fa-times"></i> Cancel - </button> - <button class="uk-button uk-button-primary" type="button" id="question-submit" disabled> - <i class="uk-icon fa-fw far fa-check"></i> Save - </button> - </div> - </div> - </div> - </div> - - <script type="application/javascript"> - "use strict"; - const actions = new JamActions("{{ url_for("staff.jams.action") }}", "{{ csrf_token() }}"); - const form = parseInt("{{ jam.number }}"); - const table_body = document.getElementById("table-body"); - const table = document.getElementById("table"); - const no_questions_paragraph = document.getElementById("no-questions-paragraph"); - - let all_questions = {{ question_ids | safe }}; - - const add_button = document.getElementById("add-button"); - const modal = UIkit.modal(document.getElementById("question-modal")); - - const question_source_section = document.getElementById("question-source-section"); - const question_source = document.getElementById("question-source"); - const loading_spinner = document.getElementById("loading-spinner"); - - const new_question_section = document.getElementById("new-question-section"); - const new_question_title = document.getElementById("new-question-title"); - const new_question_optional = document.getElementById("new-question-optional"); - const new_question_type = document.getElementById("new-question-type"); - - const radio_section = document.getElementById("radio-section"); - - const radio_add_button = document.getElementById("radio-add-button"); - const radio_add_input = document.getElementById("radio-add-input"); - const radio_remove_button = document.getElementById("radio-remove-button"); - const radio_options = document.getElementById("radio-options"); - - const number_section = document.getElementById("number-section"); - - const number_min = document.getElementById("number-min"); - const number_max = document.getElementById("number-max"); - - const existing_question_section = document.getElementById("existing-question-section"); - const existing_question_select = document.getElementById("existing-question"); - - const submit_button = document.getElementById("question-submit"); - - let current_radio_options = Array(); - - add_button.onclick = function() { - clearModal(); - checkModal(); - modal.show(); - }; - - question_source.onchange = function () { - checkModal(); - - if (this.value === "new") { - existing_question_section.setAttribute("hidden", "hidden"); - loading_spinner.setAttribute("hidden", "hidden"); - new_question_section.removeAttribute("hidden"); - } else { - new_question_section.setAttribute("hidden", "hidden"); - loading_spinner.removeAttribute("hidden"); - - actions.get_questions(function(result, data) { - existing_question_section.setAttribute("hidden", "hidden"); - loading_spinner.setAttribute("hidden", "hidden"); - - if (!result) { - UIkit.notification({ - "message": "Failed to fetch questions", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000 - }) - } else { - existing_question_select.innerHTML = "<option hidden=\"hidden\" disabled selected value=\"none\"></option>"; - - for (let question of data.questions) { - let element = document.createElement("option"); - element.value = question.id; - element.text = question.title; - - existing_question_select.appendChild(element); - } - - existing_question_section.removeAttribute("hidden"); - } - }) - } - }; - - existing_question_select.onchange = function() { - if (all_questions.indexOf(existing_question_select.value) > -1) { - existing_question_select.classList.add("uk-form-danger"); - } else { - existing_question_select.classList.remove("uk-form-danger"); - } - - checkModal(); - }; - - new_question_type.onchange = function() { - if (this.value === "checkbox") { - radio_section.setAttribute("hidden", "hidden"); - number_section.setAttribute("hidden", "hidden"); - } else if (this.value === "email") { - radio_section.setAttribute("hidden", "hidden"); - number_section.setAttribute("hidden", "hidden"); - } else if (this.value === "number") { - radio_section.setAttribute("hidden", "hidden"); - number_section.removeAttribute("hidden"); - } else if (this.value === "radio") { - radio_section.removeAttribute("hidden"); - number_section.setAttribute("hidden", "hidden"); - } else if (this.value === "range") { - radio_section.setAttribute("hidden", "hidden"); - number_section.removeAttribute("hidden"); - } else if (this.value === "slider") { - radio_section.setAttribute("hidden", "hidden"); - number_section.removeAttribute("hidden"); - } else if (this.value === "textarea") { - radio_section.setAttribute("hidden", "hidden"); - number_section.setAttribute("hidden", "hidden"); - } else if (this.value === "text") { - radio_section.setAttribute("hidden", "hidden"); - number_section.setAttribute("hidden", "hidden"); - } else { - radio_section.setAttribute("hidden", "hidden"); - number_section.setAttribute("hidden", "hidden"); - } - - checkModal(); - }; - - new_question_title.oninput = checkModal; - new_question_optional.onchange = checkModal; - - radio_add_input.onkeyup = function(event) { - event.preventDefault(); - - if (event.which === 13 || event.keyCode === 13) { - radio_add_button.onclick(undefined); - } - }; - - radio_add_button.onclick = function() { - let value = radio_add_input.value; - - if (value.length < 1) { - radio_add_input.classList.add("uk-form-danger"); - radio_add_input.focus(); - } else { - let index = current_radio_options.indexOf(value); - - if (index > -1 || value === "none") { - radio_add_input.classList.add("uk-form-danger"); - radio_add_input.focus(); - } else { - radio_add_input.classList.remove("uk-form-danger"); - radio_add_input.value = ""; - - let element = document.createElement("option"); - element.value = value; - element.text = value; - - radio_options.appendChild(element); - current_radio_options.push(value); - } - } - - checkModal(); - }; - - radio_remove_button.onclick = function() { - let value = radio_options.value; - - if (value === "none") { - return; - } - - let index = current_radio_options.indexOf(value); - - if (index < 0) { // We have a problem! - console.log("Unable to remove value from radio values because it doesn't exist: " + value) - } else { - current_radio_options.splice(index, 1); - } - - for (let element of radio_options.getElementsByTagName("option")) { - if (element.value === "none") { - continue; - } - - if (element.value === value) { - radio_options.removeChild(element); - } - } - - radio_options.value = "none"; - radio_add_input.focus(); - checkModal(); - }; - - number_min.oninput = function() { - if (this.value.length > 0 && isNaN(parseInt(this.value))) { - this.classList.add("uk-form-danger") - } else { - this.classList.remove("uk-form-danger") - } - - checkModal(); - }; - - number_max.oninput = function() { - if (this.value.length > 0 && isNaN(parseInt(this.value))) { - this.classList.add("uk-form-danger") - } else { - this.classList.remove("uk-form-danger") - } - - checkModal(); - }; - - submit_button.onclick = function () { - if (question_source.value === "existing") { - number_section.setAttribute("hidden", "hidden"); - existing_question_section.setAttribute("hidden", "hidden"); - new_question_section.setAttribute("hidden", "hidden"); - radio_section.setAttribute("hidden", "hidden"); - question_source_section.setAttribute("hidden", "hidden"); - loading_spinner.removeAttribute("hidden"); - - actions.associate_question(form, existing_question_select.value, function(result, data) { - if (result) { - addToTable(data.question); - modal.hide(); - clearModal(); - - UIkit.notification({ - "message": "Question added", - "status": "success", - "pos": "bottom-center", - "timeout": 5000, - }); - } else { - console.log(data); - UIkit.notification({ - "message": "Failed to add question to form", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000, - }); - } - }) - } else { - let type = new_question_type.value; - let optional = new_question_optional.value === "optional"; - let title = new_question_title.value; - - let question_data = { - "type": type, - "optional": optional, - "title": title - }; - - if (type === "radio") { - question_data.data = {"options": current_radio_options}; - } else if (type === "number" - || type === "range" - || type === "slider") { - question_data.data = { - "max": parseInt(number_max.value), - "min": parseInt(number_min.value) - }; - } - - number_section.setAttribute("hidden", "hidden"); - existing_question_section.setAttribute("hidden", "hidden"); - new_question_section.setAttribute("hidden", "hidden"); - radio_section.setAttribute("hidden", "hidden"); - question_source_section.setAttribute("hidden", "hidden"); - loading_spinner.removeAttribute("hidden"); - - actions.create_question(question_data, function(result, data) { - if (result) { - actions.associate_question(form, data.id, function(result, data) { - modal.hide(); - clearModal(); - - if (result) { - addToTable(data.question); - - UIkit.notification({ - "message": "Question added", - "status": "success", - "pos": "bottom-center", - "timeout": 5000, - }); - } else { - console.log(data); - UIkit.notification({ - "message": "Question created, but failed to associate with the form", - "status": "warning", - "pos": "bottom-center", - "timeout": 5000, - }); - } - }) - } else { - console.log(data); - UIkit.notification({ - "message": "Failed to create question", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000, - }); - } - }) - } - }; - - const toTitleCase = (str) => str.replace(/\b\S/g, t => t.toUpperCase()); - - function hookUpDeleteButtons() { - for (let element of document.getElementsByClassName("delete-question-button")) { - element.onclick = function() { - let question_id = this.getAttribute("data-question-id"); - let row = document.getElementById("row-" + question_id); - - actions.disassociate_question(form, question_id, function(result, data) { - if (result) { - table_body.removeChild(row); - - let index = all_questions.indexOf(question_id); - - if (index < 0) { // We have a problem! - console.log("Unable to remove question from memory because it doesn't exist: " + question_id) - } else { - all_questions.splice(index, 1); - } - - if (all_questions.length < 1) { - table.setAttribute("hidden", "hidden"); - no_questions_paragraph.removeAttribute("hidden"); - } - - UIkit.notification({ - "message": "Question removed", - "status": "success", - "pos": "bottom-center", - "timeout": 5000, - }); - } else { - console.log(data); - UIkit.notification({ - "message": "Failed to remove question", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000, - }); - } - }) - } - } - } - - function clearModal() { - // Question source section - question_source.value = "none"; - question_source_section.removeAttribute("hidden"); - - // Existing question section - loading_spinner.setAttribute("hidden", "hidden"); - - new_question_section.setAttribute("hidden", "hidden"); - - // New question section - new_question_title.value = ""; - new_question_optional.value = "none"; - new_question_type.value = "none"; - - // Radio question section - radio_section.setAttribute("hidden", "hidden"); - - radio_add_input.value = ""; - radio_options.innerHTML = "<option hidden=\"hidden\" disabled selected value=\"none\"></option>"; - radio_options.value = "none"; - - current_radio_options = Array(); - - // Number question section - number_section.setAttribute("hidden", "hidden"); - - existing_question_section.setAttribute("hidden", "hidden"); - - existing_question_select.innerHTML = "<option hidden=\"hidden\" disabled selected value=\"none\"></option>"; - existing_question_select.value = "none"; - } - - function checkModal() { - if (question_source.value === "none") { - return setButtonEnabled(false); - } else if (question_source.value === "new") { - if (new_question_title.value.length < 1) { - return setButtonEnabled(false); - } - - if (new_question_optional.value === "none") { - return setButtonEnabled(false); - } - - let question_type = new_question_type.value; - - if (question_type === "none") { - return setButtonEnabled(false); - } - - if (question_type === "radio") { - if (current_radio_options.length < 1) { - return setButtonEnabled(false); - } - } - - if ( question_type === "number" - || question_type === "range" - || question_type === "slider" - ) { - if (isNaN(parseInt(number_min.value))) { - return setButtonEnabled(false); - } - if (isNaN(parseInt(number_max.value))) { - return setButtonEnabled(false); - } - - if (number_min.value.length < 1 || number_max.value.length < 1) { - return setButtonEnabled(false); - } - } - } else { - if (existing_question_select.value === "none"){ - return setButtonEnabled(false); - } - - if (all_questions.indexOf(existing_question_select.value) > -1) { - return setButtonEnabled(false); - } - } - - return setButtonEnabled(true); - } - - function setButtonEnabled(enabled) { - submit_button.disabled = !enabled; - } - - function addToTable(question) { - console.log(question); - if (all_questions.indexOf(question.id) === -1) { - all_questions.push(question.id); - - let element = document.createElement("tr"); - element.id = "row-" + question.id; - element.innerHTML = getRowHTML(question); - - table_body.appendChild(element); - } - - if (all_questions.length > 0) { - table.removeAttribute("hidden"); - no_questions_paragraph.setAttribute("hidden", "hidden"); - } - hookUpDeleteButtons(); - } - - function getRowHTML(question) { - let optional; - let data; - - if (question.optional) { - optional = "<i class=\"uk-icon uk-text-success fa-fw far fa-check\"></i>" - } else { - optional = "<i class=\"uk-icon uk-text-danger fa-fw far fa-times\"></i>" - } - - if (question.type === "number" || question.type === "range" || question.type === "slider") { - data = ` -<i class="uk-icon fa-fw far fa-arrow-up" title="Max value"></i> ${question.data.max} -<br /> -<i class="uk-icon fa-fw far fa-arrow-down" title="Min value"></i> ${question.data.min} - ` - - } else if (question.type === "radio") { - data = "<ul>"; - - for (let option of question.data.options) { - data = data + `<li>${option}</li>` - } - data = data + "</ul>"; - } else { - data = "" - } - - let type = toTitleCase(question.type); - - const row = ` - <td class="uk-table-shrink"> - <button class="uk-button-small uk-button uk-button-danger delete-question-button" data-question-id="${question.id}"><i class="uk-icon fa-fw far fa-times"></i></button> - </td> - <td class="uk-text-truncate" title="${question.id}">${question.id}</td> - <td class="uk-table-shrink">${optional}</td> - <td title="${question.title}">${question.title}</td> - <td class="uk-table-shrink" title="${type}">${type}</td> - <td>${data}</td> - `; - return row - } - - hookUpDeleteButtons(); - </script> -{% endblock %} diff --git a/templates/staff/jams/index.html b/templates/staff/jams/index.html deleted file mode 100644 index e4e1e242..00000000 --- a/templates/staff/jams/index.html +++ /dev/null @@ -1,252 +0,0 @@ -{% extends "main/base.html" %} -{% block title %}Staff | Code Jams{% endblock %} -{% block og_title %}Staff | Code Jams{% endblock %} -{% block content %} - <div class="uk-container uk-container-small uk-section"> - <h1>Code Jams</h1> - - <a class="uk-button uk-button-default" href="{{ url_for("staff.index") }}"><i class="uk-icon fa-fw far fa-arrow-left"></i> Back</a> - <a class="uk-button uk-button-secondary" href="{{ url_for("staff.jams.forms.questions") }}"><i class="uk-icon fa-fw far fa-list"></i> Questions</a> - <a class="uk-button uk-button-secondary" href="{{ url_for("staff.jams.infractions") }}"><i class="uk-icon fa-fw far fa-exclamation-triangle"></i> Infractions</a> - <a class="uk-button uk-button-primary" href="{{ url_for("staff.jams.create") }}"><i class="uk-icon fa-fw far fa-plus"></i> Create</a> - - {% if not jams %} - <p> - No code jams found. Create one above! - </p> - {% else %} - {% for jam in jams %} - <h2 class="uk-heading-divider"> - Code Jam {{ jam.number }}: {{ jam.title }} - - <span class="uk-align-right"> - {% if jam.state == "planning" %} - <i class="uk-icon uk-text-muted fa-fw far fa-edit state-{{ jam.number }}" title="State: Planning" id="state-{{ jam.number }}-planning"></i> - {% else %} - <i class="uk-icon uk-text-muted fa-fw far fa-edit state-{{ jam.number }}" hidden="hidden" title="State: Planning" id="state-{{ jam.number }}-planning"></i> - {% endif %} - - {% if jam.state == "announced" %} - <i class="uk-icon uk-text-primary fa-fw far fa-bullhorn state-{{ jam.number }}" title="State: Announced" id="state-{{ jam.number }}-announced"></i> - {% else %} - <i class="uk-icon uk-text-primary fa-fw far fa-bullhorn state-{{ jam.number }}" hidden="hidden" title="State: Announced" id="state-{{ jam.number }}-announced"></i> - {% endif %} - - {% if jam.state == "preparing" %} - <i class="uk-icon uk-text-muted fa-fw fal fa-ellipsis-h-alt state-{{ jam.number }}" title="State: Preparing" id="state-{{ jam.number }}-preparing"></i> - {% else %} - <i class="uk-icon uk-text-muted fa-fw fal fa-ellipsis-h-alt state-{{ jam.number }}" hidden="hidden" title="State: Preparing" id="state-{{ jam.number }}-preparing"></i> - {% endif %} - - {% if jam.state == "running" %} - <i class="uk-icon uk-text-success fa-fw far fa-play state-{{ jam.number }}" title="State: Running" id="state-{{ jam.number }}-running"></i> - {% else %} - <i class="uk-icon uk-text-success fa-fw far fa-play state-{{ jam.number }}" hidden="hidden" title="State: Running" id="state-{{ jam.number }}-running"></i> - {% endif %} - - {% if jam.state == "judging" %} - <i class="uk-icon uk-text-primary fa-fw far fa-balance-scale state-{{ jam.number }}" title="State: Judging" id="state-{{ jam.number }}-judging"></i> - {% else %} - <i class="uk-icon uk-text-primary fa-fw far fa-balance-scale state-{{ jam.number }}" hidden="hidden" title="State: Judging" id="state-{{ jam.number }}-judging"></i> - {% endif %} - - {% if jam.state == "finished" %} - <i class="uk-icon uk-text-success fa-fw far fa-check-square state-{{ jam.number }}" title="State: Finished" id="state-{{ jam.number }}-finished"></i> - {% else %} - <i class="uk-icon uk-text-success fa-fw far fa-check-square state-{{ jam.number }}" hidden="hidden" title="State: Finished" id="state-{{ jam.number }}-finished"></i> - {% endif %} - - {% if not jam.state in states %} - <i class="uk-icon uk-text-danger fa-fw far fa-question-square" title="Unknown state" id="state-{{ jam.number }}-unknown"></i> - {% else %} - <i class="uk-icon uk-text-danger fa-fw far fa-question-square" hidden="hidden" title="Unknown state" id="state-{{ jam.number }}-unknown"></i> - {% endif %} - </span> - </h2> - - <span class="uk-label">Participants: {{ jam.participants | length }}</span> - <span class="uk-label uk-label-success">Start: {{ format_datetime(jam.date_start) }} (UTC)</span> - <span class="uk-label uk-label-danger">End: {{ format_datetime(jam.date_end) }} (UTC)</span> - - <section class="uk-section"> - <div class="uk-button-group uk-width-1-1"> - <a class="uk-button uk-button-default uk-width-expand state-button" data-jam="{{ jam.number }}" id="jam-{{ jam.number }}-button-state"> - <i class="uk-icon fa-fw far fa-pencil"></i> State - </a> - - <a class="uk-button uk-button-default uk-width-expand" data-jam="{{ jam.number }}" id="jam-{{ jam.number }}-button-basics" href="{{ url_for("staff.jams.edit.basics", jam=jam.number) }}"> - <i class="uk-icon fa-fw far fa-pencil"></i> Basics - </a> - - {% if jam.state in ["planning", "announced", "preparing", "finished"] %} - <a class="uk-button uk-button-default uk-width-expand" data-jam="{{ jam.number }}" id="jam-{{ jam.number }}-button-info" href="{{ url_for("staff.jams.edit.info", jam=jam.number) }}"> - <i class="uk-icon fa-fw far fa-pencil"></i> Info - </a> - {% else %} - <a class="uk-button uk-button-default uk-width-expand" hidden="hidden" data-jam="{{ jam.number }}" id="jam-{{ jam.number }}-button-info" href="{{ url_for("staff.jams.edit.info", jam=jam.number) }}"> - <i class="uk-icon fa-fw far fa-pencil"></i> Info - </a> - {% endif %} - - {% if jam.state in ["judging", "finished"] %} - <a class="uk-button uk-button-default uk-width-expand" data-jam="{{ jam.number }}" id="jam-{{ jam.number }}-button-ending" href="{{ url_for("staff.jams.edit.ending", jam=jam.number) }}"> - <i class="uk-icon fa-fw far fa-pencil"></i> Ending - </a> - {% else %} - <a class="uk-button uk-button-default uk-width-expand" hidden="hidden" data-jam="{{ jam.number }}" id="jam-{{ jam.number }}-button-ending" href="{{ url_for("staff.jams.edit.ending", jam=jam.number) }}"> - <i class="uk-icon fa-fw far fa-pencil"></i> Ending - </a> - {% endif %} - </div> - <br/> - <div class="uk-button-group uk-width-1-1"> - <a class="uk-button uk-button-danger uk-width-expand" href="{{ url_for("staff.jams.forms.view", jam=jam.number) }}"> - <i class="uk-icon fa-fw far fa-list"></i> Form - </a> - <a class="uk-button uk-button-secondary uk-width-expand" href="{{ url_for("staff.jams.participants", jam=jam.number) }}"> - <i class="uk-icon fa-fw far fa-user"></i> Participants - </a> - <a class="uk-button uk-button-primary uk-width-expand" href="{{ url_for("staff.jams.teams", jam=jam.number) }}"> - <i class="uk-icon fa-fw far fa-users"></i> Teams - </a> - </div> - </section> - {% endfor %} - {% endif %} - </div> - - <div id="state-modal" class="uk-flex-top" uk-modal> - <div class="uk-modal-dialog"> - <button class="uk-modal-close-default" type="button" uk-close></button> - - <div class="uk-modal-header"> - <h2 class="uk-modal-title">Set State</h2> - </div> - - <div class="uk-modal-body"> - <form class="uk-form-horizontal"> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="state">State</label> - </div> - - <div class="uk-form-controls uk-form-controls-text"> - <select class="uk-select" name="state" id="state"> - {% for state in states %} - <option value="{{ state }}">{{ state.title() }}</option> - {% endfor %} - </select> - </div> - </div> - </form> - </div> - - <div class="uk-modal-footer"> - <div class="uk-text-center"> - <button class="uk-button uk-button-default uk-modal-close" type="button" id="state-cancel"> - <i class="uk-icon fa-fw far fa-arrow-left"></i> Cancel - </button> - <a class="uk-button uk-button-primary" type="button" id="state-submit"> - <i class="uk-icon fa-fw far fa-check"></i> Save - </a> - </div> - </div> - </div> - </div> - - <script type="application/javascript"> - "use strict"; - const actions = new JamActions("{{ url_for("staff.jams.action") }}", "{{ csrf_token() }}"); - - // State modal objects - const state_modal = UIkit.modal(document.getElementById("state-modal")); - const state_input = document.getElementById("state"); - const state_cancel = document.getElementById("state-cancel"); - const state_submit = document.getElementById("state-submit"); - - state_cancel.onclick = function() { - state_modal.hide(); - }; - - for (let button of document.getElementsByClassName("state-button")) { - button.onclick = function() { - state_modal.show(); - - state_submit.onclick = function() { - let jam = parseInt(button.getAttribute("data-jam")); - let state = state_input.value; - - actions.set_state(jam, state, function(success, data) { - if (success) { - UIkit.notification({ - "message": "State set successfully", - "status": "success", - "pos": "bottom-center", - "timeout": 5000, - }); - - for (let icon of document.getElementsByClassName("state-" + jam)) { - icon.setAttribute("hidden", "hidden"); - } - - switch (state) { // Set the state on the page too so there's no reloading - case "planning": - document.getElementById("state-" + jam + "-planning").removeAttribute("hidden"); - - document.getElementById("jam-" + jam + "-button-info").removeAttribute("hidden"); - document.getElementById("jam-" + jam + "-button-ending").setAttribute("hidden", "hidden"); - break; - case "announced": - document.getElementById("state-" + jam + "-announced").removeAttribute("hidden"); - - document.getElementById("jam-" + jam + "-button-info").removeAttribute("hidden"); - document.getElementById("jam-" + jam + "-button-ending").setAttribute("hidden", "hidden"); - break; - case "preparing": - document.getElementById("state-" + jam + "-preparing").removeAttribute("hidden"); - - document.getElementById("jam-" + jam + "-button-info").setAttribute("hidden", "hidden"); - document.getElementById("jam-" + jam + "-button-ending").setAttribute("hidden", "hidden"); - break; - case "running": - document.getElementById("state-" + jam + "-running").removeAttribute("hidden"); - - document.getElementById("jam-" + jam + "-button-info").setAttribute("hidden", "hidden"); - document.getElementById("jam-" + jam + "-button-ending").setAttribute("hidden", "hidden"); - break; - case "judging": - document.getElementById("state-" + jam + "-judging").removeAttribute("hidden"); - - document.getElementById("jam-" + jam + "-button-info").setAttribute("hidden", "hidden"); - document.getElementById("jam-" + jam + "-button-ending").removeAttribute("hidden"); - break; - case "finished": - document.getElementById("state-" + jam + "-finished").removeAttribute("hidden"); - - document.getElementById("jam-" + jam + "-button-info").removeAttribute("hidden"); - document.getElementById("jam-" + jam + "-button-ending").removeAttribute("hidden"); - break; - default: - document.getElementById("state-" + jam + "-unknown").removeAttribute("hidden"); - - document.getElementById("jam-" + jam + "-button-info").setAttribute("hidden", "hidden"); - document.getElementById("jam-" + jam + "-button-ending").setAttribute("hidden", "hidden"); - break; - } - - state_modal.hide(); - } else { - console.log(data); - UIkit.notification({ - "message": "Failed to set state", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000 - }) - } - }); - }; - } - } - </script> -{% endblock %}
\ No newline at end of file diff --git a/templates/staff/jams/infractions/view.html b/templates/staff/jams/infractions/view.html deleted file mode 100644 index a4391c53..00000000 --- a/templates/staff/jams/infractions/view.html +++ /dev/null @@ -1,328 +0,0 @@ -{% extends "main/base.html" %} -{% block title %}Staff | Jams | Infractions{% endblock %} -{% block og_title %}Staff | Jams | Infractions{% endblock %} -{% block og_description %}Manage infractions{% endblock %} -{% block content %} - <div class="uk-container uk-container-small uk-section"> - <h1>Infractions</h1> - - <a class="uk-button uk-button-default" href="{{ url_for("staff.jams.index") }}"><i class="uk-icon fa-fw far fa-arrow-left"></i> Back</a> - <button class="uk-button uk-button-primary" id="add-button"><i class="uk-icon fa-fw far fa-plus"></i> Add Infraction</button> - - {% if not infractions %} - <p id="no-infractions-paragraph">No infractions found.</p> - <table class="uk-table uk-table-divider uk-table-striped uk-border" id="table" hidden="hidden"> - <thead> - <tr> - <th class="uk-table-shrink"> </th> - <th class="uk-table-shrink"><strong>ID</strong></th> - <th class="uk-table-shrink">Participant</th> - <th>Reason</th> - <th class="uk-table-shrink">Number</th> - </tr> - </thead> - <tbody id="table-body"> - </tbody> - </table> - {% else %} - <p id="no-infractions-paragraph" hidden="hidden">No questions found.</p> - - <div class="uk-overflow-auto"> - <br /> - <table class="uk-table uk-table-divider uk-table-striped uk-border" id="table"> - <thead> - <tr> - <th class="uk-table-shrink"> </th> - <th class="uk-table-shrink"><strong>ID</strong></th> - <th class="uk-table-shrink">Participant</th> - <th>Reason</th> - <th class="uk-table-shrink">Number</th> - </tr> - </thead> - <tbody id="table-body"> - {% for infraction in infractions %} - <tr id="row-{{ infraction.id }}"> - <td class="uk-table-shrink"> - <button class="uk-button-small uk-button uk-button-danger delete-infraction-button" data-infraction-id="{{ infraction.id }}"><i class="uk-icon fa-fw far fa-trash"></i></button> - </td> - <td class="uk-text-truncate" title="{{ infraction.id }}">{{ infraction.id }}</td> - <td class="uk-table-shrink"> - {% if infraction.participant is not string %} - <code>{{ infraction.participant.user_id }}</code> - <br /> - ({{ infraction.participant.username }}#{{ infraction.participant.discriminator }}) - {% else %} - <code>{{ infraction.participant }}</code> - {% endif %} - </td> - <td title="{{ infraction.reason }}">{{ infraction.reason }}</td> - <td class="uk-table-shrink">{{ infraction.number }}</td> - </tr> - {% endfor %} - </tbody> - </table> - </div> - {% endif %} - </div> - - <div id="add-modal" class="uk-flex-top" uk-modal> - <div class="uk-modal-dialog"> - <button class="uk-modal-close-default" type="button" uk-close></button> - - <div class="uk-modal-header"> - <h2 class="uk-modal-title">Add Infraction</h2> - </div> - - <div class="uk-modal-body"> - <form class="uk-form-horizontal"> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="user-id">User ID</label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <input class="uk-input" id="user-id" name="user-id"> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="reason">Reason</label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <input class="uk-input" id="reason" name="reason"> - </div> - </div> - <div> - <div class="uk-form-label"> - <label class="uk-form-label" for="number"> - Number of jams - </label> - </div> - <div class="uk-form-controls-text uk-form-controls"> - <input class="uk-input" id="number" name="number" placeholder="Jams to ban for / -1 for infinite"> - </div> - </div> - <div id="loading-spinner" class="uk-text-center uk-margin-small-top" hidden="hidden"> - <div uk-spinner></div> - </div> - </form> - </div> - - <div class="uk-modal-footer"> - <div class="uk-text-center"> - <button class="uk-button uk-button-danger uk-modal-close" type="button" id="state-cancel"> - <i class="uk-icon fa-fw far fa-times"></i> Cancel - </button> - <button class="uk-button uk-button-primary" type="button" id="state-submit" disabled> - <i class="uk-icon fa-fw far fa-check"></i> Save - </button> - </div> - </div> - </div> - </div> - - <script type="application/javascript"> - "use strict"; - const actions = new JamActions("{{ url_for("staff.jams.action") }}", "{{ csrf_token() }}"); - - const table_body = document.getElementById("table-body"); - const table = document.getElementById("table"); - const no_infractions_paragraph = document.getElementById("no-infractions-paragraph"); - - let all_infractions = {{ infraction_ids | safe }}; - - const add_button = document.getElementById("add-button"); - const modal = UIkit.modal(document.getElementById("add-modal")); - const loading_spinner = document.getElementById("loading-spinner"); - - const input_user_id = document.getElementById("user-id"); - const input_reason = document.getElementById("reason"); - const input_number = document.getElementById("number"); - - const submit_button = document.getElementById("state-submit"); - - add_button.onclick = function() { - clearModal(); - checkModal(); - modal.show(); - }; - - input_user_id.oninput = function() { - if (isNaN(parseInt(this.value))) { - this.classList.add("uk-form-danger"); - } else { - this.classList.remove("uk-form-danger"); - } - - checkModal(); - }; - - input_reason.oninput = function() { - checkModal(); - }; - - input_number.oninput = function() { - if (isNaN(parseInt(this.value))) { - this.classList.add("uk-form-danger"); - } else { - this.classList.remove("uk-form-danger"); - } - - checkModal(); - }; - - submit_button.onclick = function () { - loading_spinner.removeAttribute("hidden"); - - let user_id = input_user_id.value; - let reason = input_reason.value; - let number = input_number.value; - - actions.create_infraction(user_id, reason, number, function(result, data) { - if (result) { - let infraction = { - "id": data.id, - "participant": user_id, - "reason": reason, - "number": number - }; - - addToTable(infraction); - modal.hide(); - clearModal(); - - UIkit.notification({ - "message": "Infraction added", - "status": "success", - "pos": "bottom-center", - "timeout": 5000, - }); - } else { - console.log(data); - UIkit.notification({ - "message": "Failed to add infraction", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000, - }); - } - }); - }; - - function hookUpDeleteButtons() { - for (let element of document.getElementsByClassName("delete-infraction-button")) { - element.onclick = function() { - let infraction_id = this.getAttribute("data-infraction-id"); - let row = document.getElementById("row-" + infraction_id); - - actions.delete_infraction(infraction_id, function(result, data) { - if (result) { - table_body.removeChild(row); - - let index = all_infractions.indexOf(infraction_id); - - if (index < 0) { // We have a problem! - console.log("Unable to remove infraction from memory because it doesn't exist: " + infraction_id) - } else { - all_infractions.splice(index, 1); - } - - if (all_infractions.length < 1) { - table.setAttribute("hidden", "hidden"); - no_infractions_paragraph.removeAttribute("hidden"); - } - - UIkit.notification({ - "message": "Infraction removed", - "status": "success", - "pos": "bottom-center", - "timeout": 5000, - }); - } else { - console.log(data); - UIkit.notification({ - "message": "Failed to remove infraction", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000, - }); - } - }) - } - } - } - - function clearModal() { - - // Existing question section - loading_spinner.setAttribute("hidden", "hidden"); - - input_number.value = ""; - input_reason.value = ""; - input_user_id.value = ""; - } - - function checkModal() { - if (input_reason.value.length < 1 - || input_number.value.length < 1 - || input_user_id.value.length < 1) { - return setButtonEnabled(false); - } - - if (isNaN(parseInt(input_number.value))) { - return setButtonEnabled(false); - } - - if (isNaN(parseInt(input_user_id.value))) { - return setButtonEnabled(false); - } - - return setButtonEnabled(true); - } - - function setButtonEnabled(enabled) { - submit_button.disabled = !enabled; - } - - function addToTable(infraction) { - console.log(infraction); - if (all_infractions.indexOf(infraction.id) === -1) { - all_infractions.push(infraction.id); - - let element = document.createElement("tr"); - element.id = "row-" + infraction.id; - element.innerHTML = getRowHTML(infraction); - - table_body.appendChild(element); - } - - if (all_infractions.length > 0) { - table.removeAttribute("hidden"); - no_infractions_paragraph.setAttribute("hidden", "hidden"); - } - hookUpDeleteButtons(); - } - - function getRowHTML(infraction) { - let participant; - - if (typeof infraction.participant === 'string' || infraction.participant instanceof String) { - participant = infraction.participant; - } else { - participant = infraction.participant; - participant = `${participant.username}#${participant.discrminiator} (${participant.id})` - } - const row = ` - <td class="uk-table-shrink"> - <button class="uk-button-small uk-button uk-button-danger delete-infraction-button" data-infraction-id="${infraction.id}"><i class="uk-icon fa-fw far fa-trash"></i></button> - </td> - <td class="uk-text-truncate" title="${infraction.id}">${infraction.id}</td> - <td class="uk-table-shrink"><code>${participant}</code></td> - <td title="${infraction.reason}">${infraction.reason}</td> - <td class="uk-table-shrink">${infraction.number}</td> - `; - return row - } - - hookUpDeleteButtons(); - </script> -{% endblock %} diff --git a/templates/staff/jams/participants.html b/templates/staff/jams/participants.html deleted file mode 100644 index 726d407c..00000000 --- a/templates/staff/jams/participants.html +++ /dev/null @@ -1,163 +0,0 @@ -{% extends "main/base.html" %} -{% block title %}Staff | Jams | Participants{% endblock %} -{% block og_title %}Staff | Jams | Participants{% endblock %} -{% block og_description %}Listing of participant applications and their status{% endblock %} -{% block content %} - {% macro card_header(app) %} - <div> - <h2 class="uk-float-left"> - <i class="uk-icon fa-fw far fa-check status-icon" title="Approved"></i> - <i class="uk-icon fa-fw far fa-times status-icon" title="Not Approved"></i> - <img src="{{ app.avatar }}" height="20px" class="uk-border-circle" /> - {{ app.username }}#{{ app.discriminator }} - </h2> - <span class="uk-float-right"> - {% if jam.state in ["announced", "preparing"] %} - {% if app.approved %} - <button class="uk-button uk-button-success approve-button" data-app="{{ app.id }}" data-app-user="{{ app.username }}#{{ app.discriminator }}" id="approve-button-{{ app.id }}" disabled> - <i class="uk-icon fa-fw far fa-check"></i> - </button> - <button class="uk-button uk-button-danger unapprove-button" data-app="{{ app.id }}" data-app-user="{{ app.username }}#{{ app.discriminator }}" id="unapprove-button-{{ app.id }}"> - <i class="uk-icon fa-fw far fa-times"></i> - </button> - {% else %} - <button class="uk-button uk-button-success approve-button" data-app="{{ app.id }}" data-app-user="{{ app.username }}#{{ app.discriminator }}" id="approve-button-{{ app.id }}"> - <i class="uk-icon fa-fw far fa-check"></i> - </button> - <button class="uk-button uk-button-danger unapprove-button" data-app="{{ app.id }}" data-app-user="{{ app.username }}#{{ app.discriminator }}" id="unapprove-button-{{ app.id }}" disabled> - <i class="uk-icon fa-fw far fa-times"></i> - </button> - {% endif %} - {% endif %} - - <a class="uk-button uk-button-primary expand-button" data-app="{{ app.id }}" data-app-user="{{ app.username }}#{{ app.discriminator }}"> - <i class="uk-icon far fa-fw fa-plus expand-icon"></i> - <i class="uk-icon far fa-fw fa-minus contract-icon"></i> - </a> - </span> - </div> - {% endmacro %} - - <div class="uk-container uk-container-small uk-section"> - <h1 class="uk-text-center">Code Jam {{ jam.number }}: Participants</h1> - <a class="uk-button uk-button-default" href="{{ url_for("staff.jams.index") }}"><i class="uk-icon fa-fw far fa-arrow-left"></i> Back</a> - - <br /> - <br /> - - {% for app in jam.participants %} - <div class="uk-card approval-card collapsed" id="{{ app.id }}"> - {% if app.approved %} - <div class="uk-card-header approved" id="header-{{ app.id }}"> - {{ card_header(app) }} - </div> - {% else %} - <div class="uk-card-header unapproved" id="header-{{ app.id }}"> - {{ card_header(app) }} - </div> - {% endif %} - <div class="uk-card-body"> - <span class="uk-align-right user-id"> - <span class="uk-text-muted">User ID:</span> {{ app.user_id }} - </span> - - {% for response in app.answers %} - <div> - <strong>{{ questions[response.question].title }}</strong> - <br /> - <pre class="fira-code">{{ response.value }}</pre> - </div> - {% endfor %} - </div> - </div> - <br /> - {% endfor %} - </div> - - <script> - const actions = new JamActions("{{ url_for("staff.jams.action") }}", "{{ csrf_token() }}"); - - for (let elem of document.getElementsByClassName("expand-button")) { - elem.onclick = function(result, data) { - let app = this.getAttribute("data-app"); - let card = document.getElementById(app); - - if (card.classList.contains("collapsed")) { - card.classList.remove("collapsed"); - } else { - card.classList.add("collapsed"); - } - } - } - - {% if jam.state in ["announced", "preparing"] %} - for (let elem of document.getElementsByClassName("approve-button")) { - elem.onclick = function() { - let app = this.getAttribute("data-app"); - let header = document.getElementById("header-" + app); - let unapprove_button = document.getElementById("unapprove-button-" + app); - let user = this.getAttribute("data-app-user"); - - actions.approve_application(app, function(result, data) { - if (!result) { - console.log(data); - return UIkit.notification({ - "message": "Approval failed", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000 - }); - } - - header.classList.add("approved"); - header.classList.remove("unapproved"); - - elem.disabled = true; - unapprove_button.disabled = false; - - UIkit.notification({ - "message": "Approved: " + user, - "status": "success", - "pos": "bottom-center", - "timeout": 5000 - }); - }); - } - } - - for (let elem of document.getElementsByClassName("unapprove-button")) { - elem.onclick = function() { - let app = this.getAttribute("data-app"); - let approve_button = document.getElementById("approve-button-" + app); - let header = document.getElementById("header-" + app); - let user = this.getAttribute("data-app-user"); - - actions.unapprove_application(app, function(result, data) { - if (!result) { - console.log(data); - return UIkit.notification({ - "message": "Unapproval failed", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000 - }); - } - - header.classList.add("unapproved"); - header.classList.remove("approved"); - - elem.disabled = true; - approve_button.disabled = false; - - UIkit.notification({ - "message": "Unapproved: " + user, - "status": "success", - "pos": "bottom-center", - "timeout": 5000 - }); - }); - } - } - {% endif %} - </script> -{% endblock %} diff --git a/templates/staff/jams/teams/view.html b/templates/staff/jams/teams/view.html deleted file mode 100644 index 659a60c2..00000000 --- a/templates/staff/jams/teams/view.html +++ /dev/null @@ -1,513 +0,0 @@ -{% extends "main/base.html" %} -{% block title %}Staff | Jams | Teams{% endblock %} -{% block og_title %}Staff | Jams | Teams{% endblock %} -{% block og_description %}Manage Teams{% endblock %} -{% block page_classes %}page-staff-jams-edit-teams{% endblock %} -{% block content %} - <div class="uk-flex"> - <div class="uk-flex-column uk-padding-small uk-background-muted" id="member-answers-sidebar"> - <h3 class="uk-text-center" id="user-info-hint">Hover a user to show their information here</h3> - - <div id="visible-user-info"> - - </div> - <div id="hidden-user-info" hidden> - {% for participant in jam.participants %} - <div class="user-info" id="user-info-{{ participant.user_id }}"> - <img src="{{ participant.avatar }}" class="uk-border-circle avatar"/> - <div class="uk-text-center"> - <strong>{{ participant.username }}#{{ participant.discriminator }}</strong> - </div> - <div class="uk-text-center"> - <span class="uk-text-muted">{{ participant.user_id }}</span> - </div> - <div class="uk-text-center"> - <i class="uk-icon far fa-fw fa-clock"></i> {{ participant.profile.timezone }} | - <a href="https://gitlab.com/{{ participant.profile.gitlab_username }}"> - <i class="uk-icon fab fa-fw fa-gitlab"></i> {{ participant.profile.gitlab_username }} - </a> - </div> - <hr class="uk-divider-icon"/> - - {% for answer in participant.answers %} - <strong>{{ questions[answer.question].title }}</strong> - <br/> - <span class="fira-code">{{ answer.value }}</span> - <br/> - <br/> - {% endfor %} - </div> - {% endfor %} - </div> - </div> - <div class="uk-section uk-flex-column uk-flex-stretch"> - <h1>Code Jam {{ jam.number }}: Teams</h1> - - <a class="uk-button uk-button-default" href="{{ url_for("staff.jams.index") }}"><i - class="uk-icon fa-fw far fa-arrow-left"></i> Back</a> - - {% if teams %} - <button class="uk-button uk-button-primary" id="init-button" disabled><i - class="uk-icon fa-fw far fa-play"></i> Generate Teams - </button> - {% else %} - <button class="uk-button uk-button-primary" id="init-button"><i class="uk-icon fa-fw far fa-play"></i> - Generate Teams - </button> - {% endif %} - - <button class="uk-button uk-button-secondary" id="add-button"><i class="uk-icon fa-fw far fa-plus"></i> - Add Team - </button> - - {% if jam.winning_team %} - <button class="uk-button team-winner-unset-button uk-button-secondary" id="winner-unset-button"><i - class="uk-icon fa-fw far fa-trophy"></i> - Unset Winner - </button> - {% else %} - <button class="uk-button team-winner-unset-button uk-hidden" id="winner-unset-button"><i - class="uk-icon fa-fw far fa-trophy"></i> - Unset Winner - </button> - {% endif %} - - <br/> - <br/> - <div class="uk-hidden hidden-participants" hidden> - {% for participant in jam.participants %} - {% if participant.user_id not in assigned %} - <div class="uk-margin-small-bottom uk-margin-small-right uk-margin-small-top uk-margin-small-left" - id="participant-line-{{ participant.user_id }}" title="{{ participant.user_id }}"> - <span class="participant-handle" draggable="true" data-user-id="{{ participant.user_id }}"> - <img class="uk-icon-image uk-border-circle" draggable="false" - src="{{ participant.avatar }}"/> - {{ participant.username }}#{{ participant.discriminator }} ({{ participant.profile.timezone }}) - </span> - </div> - {% endif %} - {% endfor %} - </div> - <div class="uk-flex uk-flex-row uk-flex-wrap" id="participant-handles"> - {% for participant in jam.participants %} - {% if participant.user_id not in assigned %} - <div class="participant-handle uk-margin-small-bottom uk-margin-small-right uk-margin-small-top uk-margin-small-left" - id="participant-{{ participant.user_id }}" - title="{{ participant.profile.timezone }} - {{ participant.user_id }}" draggable="true" - data-user-id="{{ participant.user_id }}"> - <div class="uk-card uk-card-primary uk-card-small" - id="participant-{{ participant.user_id }}-card"> - <div class="uk-card-body"> - <img class="uk-icon-image uk-border-circle" draggable="false" - src="{{ participant.avatar }}"/> - {{ participant.username }}#{{ participant.discriminator }} - </div> - </div> - </div> - {% else %} - <div class="participant-handle uk-margin-small-bottom uk-margin-small-right uk-margin-small-top uk-margin-small-left" - id="participant-{{ participant.user_id }}" - title="{{ participant.profile.timezone }} - {{ participant.user_id }}" draggable="true" - data-user-id="{{ participant.user_id }}"> - <div class="uk-card uk-card-secondary uk-card-small" - id="participant-{{ participant.user_id }}-card"> - <div class="uk-card-body"> - <img class="uk-icon-image uk-border-circle" draggable="false" - src="{{ participant.avatar }}"/> - {{ participant.username }}#{{ participant.discriminator }} - </div> - </div> - </div> - {% endif %} - {% endfor %} - </div> - - {% if not teams %} - <p id="no-teams-paragraph">No teams found.</p> - - <div class="uk-flex uk-flex-row uk-flex-stretch uk-flex-wrap uk-flex-center" id="team-targets"> - </div> - {% else %} - <p id="no-teams-paragraph" hidden="hidden">No teams found.</p> - - <div class="uk-flex uk-flex-row uk-flex-stretch uk-flex-wrap uk-flex-center" id="team-targets"> - {% for id, team in teams.items() %} - <div class="team-handle uk-margin-small-bottom uk-margin-small-right uk-margin-small-top uk-margin-small-left" - id="team-{{ team.id }}" data-team-id="{{ team.id }}"> - <div class="uk-card uk-card-default uk-card-small - {% if jam.winning_team and jam.winning_team == team.id %} - team-card-winner - {% endif %} - "> - <div class="uk-card-header"> - <h3 class="uk-card-title"> - {{ team.name }} - </h3> - </div> - <div class="uk-card-body team-target" data-team-id="{{ team.id }}"> - <p>Drop users here to assign them</p> - - {% for user_id in team.members %} - <div class="uk-margin-small-bottom uk-margin-small-right uk-margin-small-top uk-margin-small-left" - id="participant-line-{{ user_id }}" - title="{{ participants[user_id].user_id }}"> - <span class="participant-handle" draggable="true" - data-user-id="{{ participants[user_id].user_id }}"> - <img class="uk-icon-image uk-border-circle" draggable="false" - src="{{ participants[user_id].avatar }}"/> - {{ participants[user_id].username }}#{{ participants[user_id].discriminator }} ({{ participants[user_id].profile.timezone }}) - </span> - </div> - {% endfor %} - </div> - <div class="uk-card-footer uk-text-right"> - <button class="team-winner-button uk-button uk-button-small - {% if jam.winning_team %} - uk-hidden - {% endif %}" - data-team-id="{{ team.id }}"> - <i class="uk-icon fa-fw far fa-trophy"></i> - </button> - <button class="team-reroll-button uk-button uk-button-primary uk-button-small" - data-team-id="{{ team.id }}"> - <i class="uk-icon fa-fw far fa-dice"></i> - </button> - <button class="team-delete-button uk-button uk-button-danger uk-button-small" - data-team-id="{{ team.id }}"> - <i class="uk-icon fa-fw far fa-trash"></i> - </button> - </div> - </div> - </div> - {% endfor %} - </div> - {% endif %} - </div> - </div> - - <script type="application/javascript"> - "use strict"; - const jam = parseInt("{{ jam.number }}"); - const actions = new JamActions("{{ url_for("staff.jams.action") }}", "{{ csrf_token() }}"); - let jam_winning_team = "{{ jam.winning_tam or "" }}"; - const has_winner = function () { - return jam_winning_team !== ""; - }; - const set_winner_button = function (team) { - return ` - <button class="team-winner-button uk-button uk-button-small ${has_winner() ? "uk-hidden" : ""}" data-team-id="${team.id}"> - <i class="uk-icon fa-fw far fa-trophy"></i> - </button> - ` - }; - - $("#init-button").on( - "click", - () => actions.generate_teams(jam, (result, data) => { - if (result) { - data.teams.forEach((team) => { - let elem = ` - <div class="team-handle uk-margin-small-bottom uk-margin-small-right uk-margin-small-top uk-margin-small-left" id="team-${team.id}" data-team-id="${team.id}"> - <div class="uk-card uk-card-default uk-card-small"> - <div class="uk-card-header"> - <h3 class="uk-card-title">${team.name}</h3> - </div> - <div class="uk-card-body team-target" data-team-id="${team.id}"> - <p>Drop users here to assign them</p> - </div> - <div class="uk-card-footer uk-text-right"> - ${set_winner_button(team)} - <button class="team-reroll-button uk-button uk-button-primary uk-button-small" data-team-id="${team.id}"> - <i class="uk-icon fa-fw far fa-dice"></i> - </button> - <button class="team-delete-button uk-button uk-button-danger uk-button-small" data-team-id="${team.id}"> - <i class="uk-icon fa-fw far fa-trash"></i> - </button> - </div> - </div> - </div>`; - - $("#team-targets").append(elem); - assign_handlers(); - }); - - $("#init-button").prop('disabled', true); - - UIkit.notification({ - "message": `Generated ${data.teams.length} teams`, - "status": "success", - "pos": "bottom-center", - "timeout": 5000 - }); - } else { - console.log(data); - - UIkit.notification({ - "message": "Failed to generate teams", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000 - }); - } - }) - ); - - $("#add-button").on( - "click", - () => actions.create_team(jam, (result, data) => { - if (result) { - let team = data.team; - let elem = ` - <div class="team-handle uk-margin-small-bottom uk-margin-small-right uk-margin-small-top uk-margin-small-left" id="team-${team.id}" data-team-id="${team.id}"> - <div class="uk-card uk-card-default uk-card-small"> - <div class="uk-card-header"> - <h3 class="uk-card-title">${team.name}</h3> - </div> - <div class="uk-card-body team-target" data-team-id="${team.id}"> - <p>Drop users here to assign them</p> - </div> - <div class="uk-card-footer uk-text-right"> - ${set_winner_button(team)} - <button class="team-reroll-button uk-button uk-button-primary uk-button-small" data-team-id="${team.id}"> - <i class="uk-icon fa-fw far fa-dice"></i> - </button> - <button class="team-delete-button uk-button uk-button-danger uk-button-small" data-team-id="${team.id}"> - <i class="uk-icon fa-fw far fa-trash"></i> - </button> - </div> - </div> - </div>`; - - $("#team-targets").append(elem); - assign_handlers(); - - UIkit.notification({ - "message": `Created team: ${team.name}`, - "status": "success", - "pos": "bottom-center", - "timeout": 5000 - }); - } else { - console.log(data); - - UIkit.notification({ - "message": "Failed to create team", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000 - }); - } - }) - ); - - function unset_winning_team(callback) { - actions.unset_winning_team(jam, (result, data) => { - if (result) { - $("#winner-unset-button").addClass("uk-hidden"); - $(".team-winner-button").removeClass("uk-hidden"); - $(".team-card-winner").removeClass("team-card-winner"); - UIkit.notification({ - "message": "Winning team unset", - "status": "success", - "pos": "bottom-center", - "timeout": 5000 - }); - jam_winning_team = ""; - if (callback) { - callback(true); - } - } else { - console.error(data); - UIkit.notification({ - "message": "Failed to unset winning team", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000 - }); - if (callback) { - callback(false); - } - } - }); - } - - $("#winner-unset-button").on( - "click", unset_winning_team - ); - - $(".participant-handle").on( - "dragstart", - (e) => { - e.originalEvent.dataTransfer.setData( - "pydis/member", - e.target.getAttribute("data-user-id") - ); - } - ).on( - "mouseenter", - (e) => { - $("#user-info-hint").prop("hidden", true); - $(".user-info").appendTo("#hidden-user-info"); - - console.log(e.target); - let target = e.target; - let member = target.getAttribute("data-user-id"); - - if (member === null) { - target = e.target.parentNode.parentNode; - member = target.getAttribute("data-user-id"); - } - - console.log(member); - - $(`#user-info-${member}`).appendTo("#visible-user-info"); - } - ); - - function drag_over(e) { - e.preventDefault(); - e.stopPropagation(); - - e.originalEvent.dropEffect = "move"; - } - - function drop(e) { - e.preventDefault(); - e.stopPropagation(); - - let member = e.originalEvent.dataTransfer.getData("pydis/member"); - - if (!member) { - return; - } - - let target = e.target; - - if (target.tagName === "p" || target.tagName === "P") { - target = target.parentNode; - } - - let team = target.getAttribute("data-team-id"); - - $(`#participant-line-${member}`).appendTo(target); - actions.set_team_member(jam, member, team, (result, data) => { - if (result) { - UIkit.notification({ - "message": `Team assigned successfully`, - "status": "success", - "pos": "bottom-center", - "timeout": 5000 - }); - - $(`#participant-${member}-card`).removeClass("uk-card-primary").addClass("uk-card-secondary"); - } else { - console.log(data); - - UIkit.notification({ - "message": "Failed to assign user to team", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000 - }); - } - }); - } - - function set_winning_team(e) { - let team = this.getAttribute("data-team-id"); - - actions.set_winning_team(team, (result, data) => { - if (result) { - $(".team-winner-button").addClass("uk-hidden"); - $("#winner-unset-button").removeClass("uk-hidden"); - $(".team-card-winner").removeClass("team-card-winner"); - $(`#team-${team}`).find(".uk-card").addClass("team-card-winner"); - UIkit.notification({ - "message": "Winning team updated", - "status": "success", - "pos": "bottom-center", - "timeout": 5000 - }); - jam_winning_team = team; - } else { - console.error(data); - UIkit.notification({ - "message": "Failed to set winning team", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000 - }); - } - }); - } - - function reroll_team(e) { - let team = this.getAttribute("data-team-id"); - - actions.reroll_team(team, (result, data) => { - if (result) { - $(`#team-${team}`).find("h3").text(data.name); - - UIkit.notification({ - "message": `Team rerolled: ${data.name}`, - "status": "success", - "pos": "bottom-center", - "timeout": 5000 - }); - } else { - console.log(data); - - UIkit.notification({ - "message": "Failed to reroll team", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000 - }); - } - }) - } - - function delete_team(e) { - let team = this.getAttribute("data-team-id"); - const perform = () => { - actions.delete_team(team, (result, data) => { - if (result) { - let target = $(`#team-${team}`); - - target.find(".team-target").children("div").appendTo(".hidden-participants"); - target.remove(); - } else { - console.log(data); - - UIkit.notification({ - "message": "Failed to delete team", - "status": "danger", - "pos": "bottom-center", - "timeout": 5000 - }); - } - }) - }; - - if (jam_winning_team === team) { - // unset the winning team first - unset_winning_team(result => { - if (result) { - perform(); - } - }); - } else { - perform(); - } - } - - function assign_handlers() { - $(".team-target").off("dragover").off("drop").on("dragover", drag_over).on("drop", drop); - $(".team-winner-button").off("click").on("click", set_winning_team); - $(".team-reroll-button").off("click").on("click", reroll_team); - $(".team-delete-button").off("click").on("click", delete_team); - } - - assign_handlers(); - </script> -{% endblock %} diff --git a/templates/staff/tables/edit.html b/templates/staff/tables/edit.html deleted file mode 100644 index b3b9faae..00000000 --- a/templates/staff/tables/edit.html +++ /dev/null @@ -1,50 +0,0 @@ -{% extends "main/base.html" %} -{% block title %}Staff | Home{% endblock %} -{% block og_title %}Staff | Home{% endblock %} -{% block og_description %}Landing page for the staff management area{% endblock %} -{% block content %} - <div class="uk-container uk-section uk-container-small"> - {% if message %} - <div class="uk-alert uk-alert-warning"> - {{ message }} - </div> - {% endif %} - <form uk-grid class="uk-grid-small" action="{{ url_for("staff.tables.edit", table=table) }}" method="post"> - <div class="uk-width-expand"> - <p>Primary key: <strong>"<span class="fira-code">{{ primary_key }}</span>"</strong></p> - </div> - <div class="uk-width-auto"> - <a class="uk-button uk-button-default" href="{{ url_for("staff.tables.table", table=table, page=1) }}"><i class="uk-icon fa-fw fas fa-arrow-left"></i> Back</a> - <input class="uk-button uk-button-primary" type="submit" id="submit" value="Save" /> - </div> - <div class="uk-width-1-1"> - <div id="editor" class="uk-textarea">{{ document }}</div> - <input type="hidden" name="json" id="json" /> - </div> - - <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/> - - {% if old_primary %} - <input type="hidden" name="old_primary" value="{{ old_primary }}"/> - {% endif %} - </form> - - <script type="application/javascript"> - "use strict"; - - window.onload = () => { - let editor = ace.edit("editor"); - - editor.session.setMode("ace/mode/json"); - editor.session.setUseWrapMode(true); - - editor.setTheme("ace/theme/iplastic"); - editor.setShowPrintMargin(false); - - editor.on("input", function () { - document.getElementById("json").value = editor.getValue(); - }); - }; - </script> - </div> -{% endblock %} diff --git a/templates/staff/tables/index.html b/templates/staff/tables/index.html deleted file mode 100644 index 206234bb..00000000 --- a/templates/staff/tables/index.html +++ /dev/null @@ -1,32 +0,0 @@ -{% extends "main/base.html" %} -{% block title %}Staff | Tables{% endblock %} -{% block og_title %}Staff | Tables{% endblock %} -{% block og_description %}Table management and editor{% endblock %} -{% block content %} - <div class="uk-container uk-section uk-container-small"> - <a class="uk-button uk-button-default" href="{{ url_for("staff.index") }}"><i class="uk-icon fa-fw fas fa-arrow-left"></i> Back</a> - <h1 class="uk-title uk-text-center"> - Table manager - </h1> - <p> - Click one of the tables below to manage its data: - </p> - <ul> - {% for table, obj in tables.items() %} - {% if obj.locked %} - <li> - <a href="{{ url_for("staff.tables.table", table=table, page=1) }}" title="Table locked for editing"> - <i class="uk-icon fa-fw fas fa-lock"></i> {{ table }} - </a> - </li> - {% else %} - <li> - <a href="{{ url_for("staff.tables.table", table=table, page=1) }}"> - <i class="uk-icon fa-fw fas fa-pencil"></i> {{ table }} - </a> - </li> - {% endif %} - {% endfor %} - </ul> - </div> -{% endblock %}
\ No newline at end of file diff --git a/templates/staff/tables/table.html b/templates/staff/tables/table.html deleted file mode 100644 index 87d981a0..00000000 --- a/templates/staff/tables/table.html +++ /dev/null @@ -1,165 +0,0 @@ -{% extends "main/base.html" %} -{% block title %}Staff | Home{% endblock %} -{% block og_title %}Staff | Home{% endblock %} -{% block og_description %}Landing page for the staff management area{% endblock %} -{% block content %} - <div class="uk-container uk-section uk-container-small"> - <a class="uk-button uk-button-default" href="{{ url_for("staff.tables.index") }}"><i class="uk-icon fa-fw fas fa-arrow-left"></i> Back</a> - - {% if page == "all" %} - <a class="uk-button uk-button-dark" href="{{ url_for("staff.tables.table", table=table, page=1) }}"><i class="uk-icon fa-fw fas fa-bars"></i> Page 1</a> - {% else %} - <a class="uk-button uk-button-dark" href="{{ url_for("staff.tables.table", table=table, page="all") }}"><i class="uk-icon fa-fw fas fa-bars"></i> All Data</a> - {% endif %} - - {% if not table_obj.locked %} - <a class="uk-button uk-button-primary" href="{{ url_for("staff.tables.edit", table=table) }}"><i class="uk-icon fa-fw fas fa-plus"></i> Add</a> - {% endif %} - - <h1 class="uk-title uk-text-center"> - <span class="fira-code"> - {{ table }} - - {% if table_obj.locked %} - <i class="uk-icon fa-fw fas fa-lock" title="Table locked for editing"></i> - {% endif %} - </span> - </h1> - - <form action="{{ url_for("staff.tables.table", table=table, page="all") }}" method="get" class="uk-width-1-1"> - <div class="uk-form-custom uk-width-1-1 uk-flex"> - {% if search %} - <input class="uk-input uk-width-expand" name="search" type="text" placeholder="Search (RE2)" value="{{ search }}" /> - {% else %} - <input class="uk-input uk-width-expand" name="search" type="text" placeholder="Search (RE2)" /> - {% endif %} - - <div class="uk-width-auto uk-flex-auto"> - <select class="uk-select uk-width-1-1" name="search-key" title="Table Key"> - <option class="uk-text-bold">{{ table_obj.primary_key }}</option> - {% for key in table_obj.keys %} - {% if key != table_obj.primary_key %} - {% if search_key == key %} - <option selected>{{ key }}</option> - {% else %} - <option>{{ key }}</option> - {% endif %} - {% endif %} - {% endfor %} - </select> - </div> - - <button class="uk-button uk-button-primary uk-width-auto" type="submit"><i class="uk-icon fas fa-search"></i></button> - <a class="uk-button uk-button-dark uk-width-auto" target="_blank" href="https://github.com/google/re2/wiki/Syntax"><i class="uk-icon fas fa-question-circle"></i></a> - </div> - </form> - - {% macro paginate() %} - {% if pages != "all" %} - <ul class="uk-pagination uk-flex-center" uk-margin> - {% if page > 1 %} - <li><a href="{{ url_for("staff.tables.table", table=table, page=page - 1) }}"><span uk-pagination-previous></span></a></li> - {% else %} - <li class="uk-disabled"><a><span uk-pagination-previous></span></a></li> - {% endif %} - - {% if page == 1 %} - <li class="uk-active"><a href="{{ url_for("staff.tables.table", table=table, page=1) }}">1</a></li> - {% else %} - <li><a href="{{ url_for("staff.tables.table", table=table, page=1) }}">1</a></li> - {% endif %} - - {% if page >= 5 %} - <li class="uk-disabled"><a>...</a></li> - {% endif %} - - {% set current_page = page - 2 %} - - {% for num in range(5) %} - {% if current_page + num > 1 and current_page + num < pages %} - {% if current_page + num == page %} - <li class="uk-active"><a href="{{ url_for("staff.tables.table", table=table, page=current_page + num) }}">{{ current_page + num }}</a></li> - {% else %} - <li><a href="{{ url_for("staff.tables.table", table=table, page=current_page + num) }}">{{ current_page + num }}</a></li> - {% endif %} - {% endif %} - {% set current_page = current_page - 1 %} - {% endfor %} - - {% if pages - page > 3 %} - <li class="uk-disabled"><a>...</a></li> - {% endif %} - - {% if pages != 1 %} - {% if page == pages %} - <li class="uk-active"><a href="{{ url_for("staff.tables.table", table=table, page=pages) }}">{{ pages }}</a></li> - {% else %} - <li><a href="{{ url_for("staff.tables.table", table=table, page=pages) }}">{{ pages }}</a></li> - {% endif %} - {% endif %} - - {% if page < pages %} - <li><a href="{{ url_for("staff.tables.table", table=table, page=page + 1) }}"><span uk-pagination-next></span></a></li> - {% else %} - <li class="uk-disabled"><a><span uk-pagination-next></span></a></li> - {% endif %} - </ul> - {% endif %} - {% endmacro %} - - {{ paginate() }} - - </div> - <div class="uk-container uk-section"> - {% if documents %} - <table class="uk-table uk-table-striped uk-overflow-auto"> - <thead> - <tr> - {% if not table_obj.locked %} - <th class="uk-table-shrink uk-text-center"> - <i class="uk-icon fa-fw fas fa-pencil"></i> - </th> - {% endif %} - - {% for key in table_obj.keys %} - <th title="{{ key }}"> - {% if key == table_obj.primary_key %} - <strong>{{ key }}</strong> - {% else %} - {{ key }} - {% endif %} - </th> - {% endfor %} - </tr> - </thead> - <tbody> - {% for doc in documents %} - <tr> - {% if not table_obj.locked %} - <td class="uk-table-shrink"> - <a href="{{ url_for("staff.tables.edit", table=table, key=doc[table_obj.primary_key]) }}"> - <i class="uk-icon fa-fw fas fa-pencil"></i> - </a> - </td> - {% endif %} - - {% for key in table_obj.keys %} - <td class="uk-text-truncate fira-code" title="{{ doc[key] }}"> - {% if key == table_obj.primary_key %} - <strong>{{ doc[key] }}</strong> - {% else %} - {{ doc[key] }} - {% endif %} - </td> - {% endfor %} - </tr> - {% endfor %} - </tbody> - </table> - {% else %} - <p class="uk-text-center">No documents found</p> - {% endif %} - - {{ paginate() }} - </div> -{% endblock %}
\ No newline at end of file |