Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions LICENSE.md
Comment thread
janno42 marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

The software is licensed under the MIT license. The source code includes other
components in whole or in part, used under these licenses:
* [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0): Bootstrap Datetimepicker, Tom Select
* [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0): Tom Select
* [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode): Font Awesome Icons
* [OFL-1.1](https://scripts.sil.org/OFL): Font Awesome Fonts
* [MIT](https://opensource.org/licenses/MIT): Bootstrap, Font Awesome Code, jQuery, Moment, Sisyphus, Sortable
* [MIT](https://opensource.org/licenses/MIT): Bootstrap, Font Awesome Code, jQuery, Moment, Sisyphus, Sortable, Tempus Dominus
* [BSD-2-Clause](https://opensource.org/licenses/bsd-license.php): jQuery Formset

The source repository may include logos, names or other trademarks of the
Expand Down
5 changes: 5 additions & 0 deletions evap/contributor/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ class Meta:
"participants": UserModelMultipleChoiceField,
}

widgets = {
"vote_start_datetime": forms.DateTimeInput(),
"vote_end_date": forms.DateInput(attrs={"type": "date", "class": "form-control"}),
}

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

Expand Down
6 changes: 5 additions & 1 deletion evap/evaluation/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@
<title>{% block title %}EvaP{% endblock %}</title>

<link rel="stylesheet" href="{% static 'css/tom-select.bootstrap5.min.css' %}" />
<link rel="stylesheet" href="{% static 'css/bootstrap-datetimepicker.min.css' %}" />
<link rel="stylesheet" href="{% static 'css/evap.css' %}" />
<link rel="stylesheet" href="{% static 'tempus-dominus/tempus-dominus.min.css' %}" />
<script src="{% static 'js/popper.min.js' %}"></script>
<script src="{% static 'tempus-dominus/tempus-dominus.min.js' %}"></script>
<script type="module" src="{% static 'js/tempus-dominus-date-init.js' %}"></script>
<script type="module" src="{% static 'js/tempus-dominus-datetime-init.js' %}"></script>
{% if debug %}
<link rel="icon" type="image/png" sizes="64x64" href="{% static 'images/favicon_gray.png' %}" />
{% else %}
Expand Down
32 changes: 0 additions & 32 deletions evap/evaluation/templates/bootstrap_datetimepicker.html

This file was deleted.

14 changes: 14 additions & 0 deletions evap/evaluation/templates/django/forms/widgets/date.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<div class="input-group" id="datepicker1" data-td-target-input="nearest" data-td-target-toggle="nearest">

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ids need to be unique in the full HTML document. This widget HTML snippet here may be used on one page multiple times, so we cannot put any ids in here.

Do we use this for anything? If not, let's just remove it. Otherwise, we have to use some other mechanism to identify these elements (probably classes)?

<input id="datetimepickerInput"
type="text"
class="form-control"
data-td-target="#datetimepicker"
name="{{ widget.name }}"
{% if widget.value and widget.value != 'None' %}
value="{{ widget.value }}"{% endif %}
{% include 'django/forms/widgets/attrs.html' %}
/>
<span class="input-group-text" data-td-target="#datetimepicker" data-td-toggle="datetimepicker">
<i class="fas fa-calendar"></i>
</span>
</div>
14 changes: 14 additions & 0 deletions evap/evaluation/templates/django/forms/widgets/datetime.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<div class="input-group" id="datetimepicker" data-td-target-input="nearest" data-td-target-toggle="nearest">
<input id="datetimepickerInput"
type="text"
class="form-control"
data-td-target="#datetimepicker"
name="{{ widget.name }}"
{% if widget.value and widget.value != 'None' %}
value="{{ widget.value }}"{% endif %}
{% include 'django/forms/widgets/attrs.html' %}
/>
<span class="input-group-text" data-td-target="#datetimepicker" data-td-toggle="datetimepicker">
<i class="fas fa-calendar"></i>
</span>
</div>
4 changes: 0 additions & 4 deletions evap/evaluation/templates/evap_evaluation_edit_js.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,3 @@
}
}
</script>

{% block additional_javascript %}
{% include 'bootstrap_datetimepicker.html' %}
{% endblock %}
4 changes: 4 additions & 0 deletions evap/rewards/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ class RewardPointRedemptionEventForm(forms.ModelForm):
class Meta:
model = RewardPointRedemptionEvent
fields = ("name_en", "name_de", "date", "redeem_end_date", "step")
widgets = {
"date": forms.DateInput(attrs={"type": "date", "class": "form-control"}),
"redeem_end_date": forms.DateInput(attrs={"type": "date", "class": "form-control"}),
}

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,3 @@
</div>
</form>
{% endblock %}

{% block additional_javascript %}
{% include 'bootstrap_datetimepicker.html' %}
{% endblock %}
33 changes: 29 additions & 4 deletions evap/staff/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,19 @@ def clean(self):
class ImportForm(forms.Form):
use_required_attribute = False

vote_start_datetime = forms.DateTimeField(label=_("Start of evaluation"), localize=True, required=False)
vote_end_date = forms.DateField(label=_("End of evaluation"), localize=True, required=False)
vote_start_datetime = forms.DateTimeField(
label=_("Start of evaluation"),
widget=forms.DateTimeInput(),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? I would have expected tht forms.DateTimeInput is the default widget for a forms.DateTimeField.

localize=True,
required=False,
)

vote_end_date = forms.DateField(
label=_("End of evaluation"),
widget=forms.DateInput(attrs={"type": "date", "class": "form-control"}),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do we need "type": "date" for here? Should it just be part of the default for the widget? (And I guess the same for "class": "form-control")

localize=True,
required=False,
)

excel_file = forms.FileField(
label=_("Excel file"),
Expand Down Expand Up @@ -283,8 +294,18 @@ def __init__(self, *args, **kwargs):

class CourseCopyForm(CourseFormMixin, forms.ModelForm): # type: ignore[misc]
semester = forms.ModelChoiceField(Semester.objects.all())
vote_start_datetime = forms.DateTimeField(label=_("Start of evaluations"), localize=True)
vote_end_date = forms.DateField(label=_("Last day of evaluations"), localize=True)

vote_start_datetime = forms.DateTimeField(
label=_("Start of evaluations"),
localize=True,
widget=forms.DateTimeInput(),
)

vote_end_date = forms.DateField(
label=_("Last day of evaluations"),
localize=True,
widget=forms.DateInput(attrs={"type": "date", "class": "form-control"}),
)

field_order = ["semester"]

Expand Down Expand Up @@ -401,6 +422,10 @@ class Meta:
field_classes = {
"participants": UserModelMultipleChoiceField,
}
widgets = {
"vote_start_datetime": forms.DateTimeInput(),
"vote_end_date": forms.DateInput(attrs={"type": "date", "class": "form-control"}),
}

def __init__(self, *args, requires_decided_main_language=False, **kwargs):
semester = kwargs.pop("semester", None)
Expand Down
4 changes: 0 additions & 4 deletions evap/staff/templates/staff_course_copyform.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,3 @@ <h5 class="card-title">{% translate 'Evaluations that will be copied' %}</h5>
</div>
</form>
{% endblock %}

{% block additional_javascript %}
{% include 'bootstrap_datetimepicker.html' %}
{% endblock %}
1 change: 0 additions & 1 deletion evap/staff/templates/staff_semester_import.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ <h3>{% translate 'Import semester data' %}</h3>
{% endblock %}
Comment thread
HannesClausnitzer marked this conversation as resolved.

{% block additional_javascript %}
{% include 'bootstrap_datetimepicker.html' %}
<script type="module">
import { copyHeaders } from "{% static 'js/copy-to-clipboard.js' %}";

Expand Down
5 changes: 0 additions & 5 deletions evap/static/css/bootstrap-datetimepicker.min.css

This file was deleted.

2 changes: 0 additions & 2 deletions evap/static/js/bootstrap-datetimepicker.min.js

This file was deleted.

7 changes: 7 additions & 0 deletions evap/static/js/popper.min.js

Large diffs are not rendered by default.

14 changes: 0 additions & 14 deletions evap/static/scss/_adjustments.scss
Original file line number Diff line number Diff line change
Expand Up @@ -110,20 +110,6 @@ $alert-colors: (
padding-top: 0.25rem;
}

// datetimepicker adjustments
.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
width: 33em;

.datepicker {
flex: 0 0 60%;
max-width: 60%;
}

.timepicker {
flex: 0 0 40%;
}
}

// tomselect adjustments
.ts-wrapper.multi .ts-control > div.active {
background-color: $component-active-bg;
Expand Down
1 change: 1 addition & 0 deletions evap/static/scss/_components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@
@import "components/staff-index";
@import "components/notebook";
@import "components/range-slider";
@import "components/datetime-picker";
68 changes: 68 additions & 0 deletions evap/static/scss/components/_datetime-picker.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// fix datetimepicker time selector width
.time-container-clock,
.time-container-hour,
.time-container-minute {
width: 100%;
}

/* Overall widget wider */
.tempus-dominus-widget.timepicker-sbs {
width: auto !important;
max-width: 540px;
}

/* Time container - wider to accommodate bigger inner elements */
.tempus-dominus-widget.timepicker-sbs .time-container {
flex: 0 0 160px !important;
width: 160px !important;
padding: 6px !important;
display: flex !important;
flex-direction: column;
justify-content: center !important;
align-items: center !important;
}

/* Clock - vertical centering */
.tempus-dominus-widget.timepicker-sbs .time-container .clock {
padding: 0 !important;
margin: 0 !important;
display: flex !important;
flex-direction: column;
justify-content: center !important;
align-items: center !important;
}

/* Hour/Minute display - WIDER to fill horizontal space */
.tempus-dominus-widget.timepicker-sbs .time-container .clock .hour,
.tempus-dominus-widget.timepicker-sbs .time-container .clock .minute {
Comment on lines +36 to +37

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find the .clock and .hour/.minute classes in the HTML. Is this part correct?
There is a .time-container-clock in .time-container though.

min-width: 65px !important; /* Increased from 50px */
width: 65px !important; /* Increased from 50px */
font-size: 1.2em !important;
padding: 4px !important;
}

/* Up/down buttons - WIDER to match hour/minute width */
.tempus-dominus-widget.timepicker-sbs .time-container .clock button {
min-width: 65px !important; /* Increased from 50px */
width: 65px !important; /* Increased from 50px */
padding: 6px 8px !important;
margin: 2px !important;
}

/* Clock face - LARGER */
.tempus-dominus-widget.timepicker-sbs .time-container .clock .clock-face {
width: 110px !important;
height: 110px !important;
}

/* Separator between hour/minute */
.tempus-dominus-widget.timepicker-sbs .time-container .clock .separator {
padding: 0 8px !important;
font-size: 1.2em !important;
}

/* Date container */
.tempus-dominus-widget.timepicker-sbs .date-container {
flex: 1 1 auto;
min-width: 290px;
}
1 change: 1 addition & 0 deletions evap/static/tempus-dominus/tempus-dominus.min.css

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions evap/static/tempus-dominus/tempus-dominus.min.js

Large diffs are not rendered by default.

50 changes: 50 additions & 0 deletions evap/static/ts/src/tempus-dominus-date-init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { tempusDominus } from "./tempus-dominus.js";

document.addEventListener("DOMContentLoaded", () => {
const pickerElements = document.querySelectorAll<HTMLElement>("[id^='datepicker']");
pickerElements.forEach(pickerElement => {
const inputElement = pickerElement.querySelector("input");
if (!inputElement) {
return;
}

const toggleElement = pickerElement.querySelector("[data-td-toggle]");
if (!toggleElement) {
return;
}

const picker = new tempusDominus.TempusDominus(pickerElement, {
display: {
theme: "light",
icons: {
time: "fa fa-clock",
date: "fa fa-calendar",
up: "fa fa-arrow-up",
down: "fa fa-arrow-down",
previous: "fa fa-chevron-left",
next: "fa fa-chevron-right",
today: "fa fa-calendar-check",
clear: "fa fa-trash",
close: "fa fa-times",
},
components: {
clock: false,
hours: false,
minutes: false,
seconds: false,
},
},
localization: {
format: "yyyy-MM-dd",
startOfTheWeek: 1,
hourCycle: "h23",
},
});

const openPicker = (): void => {
picker.show();
};

inputElement.addEventListener("click", openPicker);
});
});
Loading
Loading