Skip to content

Commit a219e47

Browse files
committed
Vision
More realistic alternative to `current` Add custom elements scaffold looks right, doesn't open found a way to use import, but not have icons modal texts displayed before script is loaded fix usage of custom elements prototype before it was loaded make it open the modal dont know some progess with native dialogs make it look somewhat like bootstrap progress? make animations work implement confirmation logic ough, now the slots inherit values from the .card-header bar Use `:defined` instead of `.loaded` class more modals and fix blocktrans Allow putting extra stuff under `confirmation-modal` more modals format more modals
1 parent 23c3757 commit a219e47

14 files changed

+386
-212
lines changed

evap/contributor/templates/contributor_evaluation_form.html

+12-19
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,18 @@ <h5 class="card-title me-auto">{% trans 'Evaluation data' %}</h5>
9090
{% if editable %}
9191
<button name="operation" value="preview" type="submit" class="btn btn-light">{% trans 'Preview' %}</button>
9292
<button name="operation" value="save" type="submit" class="btn btn-primary">{% trans 'Save' %}</button>
93-
{# webtest does not allow submission with value "approve" if no such button exists #}
94-
<button style="display: none" name="operation" value="approve" type="submit"></button>
95-
<button type="button" onclick="approveEvaluationModalShow(0, '');" class="btn btn-success">{% trans 'Save and approve' %}</button>
93+
94+
<confirmation-modal type="submit" name="operation" value="approve">
95+
<span slot="title">{% trans 'Approve evaluation' %}</span>
96+
<span slot="action-text">{% trans 'Approve evaluation' %}</span>
97+
<span slot="question">
98+
{% blocktrans %}
99+
Do you want to approve this evaluation? This will allow the evaluation team to proceed with the preparation, but you won't be able to make any further changes.
100+
{% endblocktrans %}
101+
</span>
102+
103+
<button slot="show-button" type="button" class="btn btn-success">{% trans 'Save and approve' %}</button>
104+
</confirmation-modal>
96105
{% endif %}
97106
<a href="{% url 'contributor:index' %}" class="btn btn-light">{% if edit %}{% trans 'Cancel' %}{% else %}{% trans 'Back' %}{% endif %}</a>
98107
</div>
@@ -121,22 +130,6 @@ <h5 class="modal-title" id="previewModalLabel">{% trans 'Preview' %}</h5>
121130

122131
{% block modals %}
123132
{{ block.super }}
124-
{% trans 'Approve evaluation' as title %}
125-
{% blocktrans asvar question%}Do you want to approve this evaluation? This will allow the evaluation team to proceed with the preparation, but you won't be able to make any further changes.{% endblocktrans %}
126-
{% trans 'Approve evaluation' as action_text %}
127-
{% include 'confirmation_modal.html' with modal_id='approveEvaluationModal' title=title question=question action_text=action_text btn_type='primary' %}
128-
<script type="text/javascript">
129-
function approveEvaluationModalAction(dataId) {
130-
const input = document.createElement("input");
131-
input.type = "hidden";
132-
input.name = "operation";
133-
input.value = "approve";
134-
135-
const form = document.getElementById("evaluation-form");
136-
form.appendChild(input);
137-
form.requestSubmit();
138-
};
139-
</script>
140133

141134
{% blocktrans asvar title with evaluation_name=evaluation.full_name %}Request account creation for {{ evaluation_name }}{% endblocktrans %}
142135
{% trans 'Please tell us which new account we should create. We need the name and email for all new accounts.' as teaser %}

evap/contributor/templates/contributor_index.html

+18-55
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,22 @@
157157
<span class="fas fa-pencil"></span>
158158
</a>
159159
{% if not evaluation|has_nonresponsible_editor %}
160-
<a href="#" class="btn btn-sm btn-dark" data-bs-toggle="tooltip"
161-
data-bs-placement="top" title="{% trans 'Delegate preparation' %}"
162-
onclick="delegateSelectionModalShow(`{{ evaluation.full_name }}`, `{% url 'contributor:evaluation_direct_delegation' evaluation.id %}`);return false;"
163-
>
164-
<span class="fas fa-hand-point-left"></span>
165-
</a>
160+
<confirmation-modal data-evaluation-direct-delegation-url="{% url 'contributor:evaluation_direct_delegation' evaluation.id %}">
161+
<span slot="title">{% trans 'Delegate preparation' %}</span>
162+
<span slot="action-text">{% trans 'Delegate preparation' %}</span>
163+
<span slot="question">
164+
{% blocktrans with evaluation_name=evaluation.full_name %}
165+
Do you really want to delegate the preparation of the evaluation {{ evaluation_name }}?
166+
{% endblocktrans %}
167+
<div class="my-4">
168+
{% include 'bootstrap_form.html' with form=delegate_selection_form wide=True %}
169+
</div>
170+
</span>
171+
172+
<a slot="show-button" href="#" class="btn btn-sm btn-dark" data-bs-toggle="tooltip" data-bs-placement="top" title="{% trans 'Delegate preparation' %}">
173+
<span class="fas fa-hand-point-left"></span>
174+
</a>
175+
</confirmation-modal>
166176
{% endif %}
167177
{% elif evaluation.state == evaluation.State.EDITOR_APPROVED or evaluation.state == evaluation.State.APPROVED %}
168178
<a href="{% url 'contributor:evaluation_view' evaluation.id %}" class="btn btn-sm btn-light"
@@ -191,57 +201,10 @@
191201
{% endfor %}
192202
</tbody>
193203
</table>
204+
205+
<!-- TODO: javascript to submit it above -->
194206
</div>
195207
</div>
196208
{% endif %}
197209
{% endfor %}
198210
{% endblock %}
199-
200-
{% block modals %}
201-
{{ block.super }}
202-
203-
{% with modal_id='delegateSelectionModal' %}
204-
<div class="modal fade" id="{{ modal_id }}" role="dialog" aria-labelledby="{{ modal_id }}Label" aria-hidden="true">
205-
<div class="modal-dialog" role="document">
206-
<div class="modal-content">
207-
<form method="POST">
208-
{% csrf_token %}
209-
<div class="modal-header">
210-
<h5 class="modal-title" id="{{ modal_id }}Label">{% trans 'Delegate preparation' %}</h5>
211-
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
212-
</div>
213-
<div class="modal-body">
214-
{% trans 'Do you really want to delegate the preparation of the evaluation <strong data-label=""></strong>?' %}
215-
<div class="my-4">
216-
{% include 'bootstrap_form.html' with form=delegate_selection_form wide=True %}
217-
</div>
218-
<div class="modal-submit-group">
219-
<button type="button" class="btn btn-light" data-bs-dismiss="modal">{% trans 'Cancel' %}</button>
220-
<button type="submit" id="btn-action" class="btn btn-primary ms-2">{% trans 'Delegate preparation' %}</button>
221-
</div>
222-
</div>
223-
224-
</form>
225-
</div>
226-
</div>
227-
</div>
228-
229-
<script type="text/javascript">
230-
function {{ modal_id }}Show(evaluationName, action) {
231-
const modal = document.getElementById("{{ modal_id }}");
232-
// set form's action location
233-
modal.querySelectorAll("form").forEach(form => form.action = action);
234-
235-
// put the correct evaluation name in the modal
236-
modal.querySelectorAll('[data-label=""]').forEach(el => el.innerText = evaluationName);
237-
238-
// unselect any previously selected options in the modal
239-
modal.querySelectorAll("select").forEach(select => select.tomselect.clear());
240-
241-
// show modal
242-
var {{ modal_id }} = new bootstrap.Modal(document.getElementById('{{ modal_id }}'));
243-
{{ modal_id }}.show();
244-
}
245-
</script>
246-
{% endwith %}
247-
{% endblock %}

evap/evaluation/templates/base.html

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
<body>
2929
<script type="text/javascript" src="{% static 'bootstrap/dist/js/bootstrap.bundle.min.js' %}"></script>
3030

31+
{% include "custom_elements.html" %}
32+
3133
{% block modals %}
3234
{% if user.is_authenticated %}
3335
{% trans 'Feedback' as title %}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{% load static %}
2+
3+
<template id="confirmation-modal-template">
4+
<link rel="stylesheet" href="{% static 'css/evap.css' %}" />
5+
6+
<dialog class="evap-modal-dialog">
7+
<form method="dialog">
8+
<div class="evap-modal-container">
9+
<header>
10+
<h5><slot name="title"></slot></h5>
11+
<button class="btn-close"></button>
12+
</header>
13+
<section class="question-area">
14+
<slot name="question"></slot>
15+
<slot name="extra-inputs"></slot>
16+
</section>
17+
<section class="button-area">
18+
<button class="btn btn-light">{% trans 'Cancel' %}</button>
19+
<slot name="submit-group">
20+
<button class="btn ms-2" data-event-type="confirm">
21+
<slot name="action-text"></slot>
22+
</button>
23+
</slot>
24+
</section>
25+
</div>
26+
</form>
27+
</dialog>
28+
29+
<slot name="show-button"></slot>
30+
31+
{# All children without the "slot" attribute go into this unnamed slot #}
32+
<slot></slot>
33+
</template>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{% load static %}
2+
3+
{% include "confirmation_modal_template.html" %}
4+
5+
<script type="module">
6+
import { ConfirmationModal } from "{% static 'js/confirmation-modal.js' %}";
7+
8+
customElements.define("confirmation-modal", ConfirmationModal);
9+
</script>

evap/grades/templates/grades_course_view.html

+36-23
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{% extends 'grades_course_base.html' %}
2+
{% load static %}
23

34
{% block content %}
45
{{ block.super }}
@@ -30,13 +31,45 @@ <h3 class="mb-3">{{ course.name }} ({{ semester.name }})</h3>
3031
<a href="{% url 'grades:download_grades' grade_document.id %}" class="btn btn-sm btn-light" data-bs-toggle="tooltip" data-bs-placement="top" title="{% trans 'Download' %}"><span class="fas fa-download"></span></a>
3132
{% if user.is_grade_publisher %}
3233
<a href="{% url 'grades:edit_grades' grade_document.id %}" class="btn btn-sm btn-light" data-bs-toggle="tooltip" data-bs-placement="top" title="{% trans 'Edit' %}"><span class="fas fa-pencil"></span></a>
33-
<button type="button" onclick="deleteGradedocumentModalShow({{ grade_document.id }}, '{{ grade_document.description|escapejs }}');" class="btn btn-sm btn-danger" data-bs-toggle="tooltip" data-bs-placement="top" title="{% trans 'Delete' %}">
34-
<span class="fas fa-trash"></span>
35-
</button>
34+
<confirmation-modal confirm-button-class="btn-danger" data-delete-document="{{ grade_document.id }}">
35+
<span slot="title">{% trans 'Delete grade document' %}</span>
36+
<span slot="action-text">{% trans 'Delete grade document' %}</span>
37+
<span slot="question">
38+
{% blocktrans with description=grade_document.description %}
39+
Do you really want to delete the grade document <strong>{{ description }}</strong>?
40+
{% endblocktrans %}
41+
</span>
42+
43+
<button slot="show-button" type="button" {{ disable_if_archived }} class="btn btn-sm btn-danger" data-bs-toggle="tooltip" data-bs-placement="top" title="{% trans 'Delete' %}">
44+
<span class="fas fa-trash"></span>
45+
</button>
46+
</confirmation-modal>
3647
{% endif %}
3748
</td>
3849
</tr>
3950
{% endfor %}
51+
52+
<script type="module">
53+
import { CSRF_HEADERS } from "{% static 'js/csrf-utils.js' %}";
54+
55+
document.querySelectorAll("confirmation-modal[data-delete-document]").forEach(modal => {
56+
modal.addEventListener("confirmed", async () => {
57+
const response = await fetch("{% url 'grades:delete_grades' %}", {
58+
body: new URLSearchParams({grade_document_id: modal.dataset.deleteDocument}),
59+
headers: CSRF_HEADERS,
60+
method: "POST",
61+
});
62+
63+
if (response.ok) {
64+
const row = modal.closest("tr");
65+
// TODO: animate
66+
row.remove();
67+
} else {
68+
window.alert("{% trans 'The server is not responding.' %}");
69+
}
70+
});
71+
});
72+
</script>
4073
</tbody>
4174
</table>
4275
{% else %}
@@ -49,23 +82,3 @@ <h3 class="mb-3">{{ course.name }} ({{ semester.name }})</h3>
4982
<a href="{% url 'grades:upload_grades' course.id %}?final=true" class="btn btn-dark">{% trans 'Upload new final grades' %}</a>
5083
{% endif %}
5184
{% endblock %}
52-
53-
{% block modals %}
54-
{{ block.super }}
55-
{% trans 'Delete grade document' as title %}
56-
{% trans 'Do you really want to delete the grade document <strong data-label=""></strong>?' as question %}
57-
{% trans 'Delete grade document' as action_text %}
58-
{% include 'confirmation_modal.html' with modal_id='deleteGradedocumentModal' title=title question=question action_text=action_text btn_type='danger' %}
59-
<script type="text/javascript">
60-
function deleteGradedocumentModalAction(dataId) {
61-
fetch("{% url 'grades:delete_grades' %}", {
62-
body: new URLSearchParams({grade_document_id: dataId}),
63-
headers: CSRF_HEADERS,
64-
method: "POST",
65-
}).then(response => {
66-
assert(response.ok);
67-
fadeOutThenRemove(document.getElementById('grade_document-row-'+dataId));
68-
}).catch(error => {window.alert("{% trans 'The server is not responding.' %}");});
69-
};
70-
</script>
71-
{% endblock %}

0 commit comments

Comments
 (0)