Commit 1721df9b authored by dorothee.kueppers's avatar dorothee.kueppers
Browse files

alle Todos anzeigen

parent a165e78d
......@@ -30,7 +30,7 @@ urlpatterns = [
path('todo/add/', add_todo, name='add_todo'),
path('impressum/', get_impressum, name='impressum'),
path('todo/show/', get_show_todo, name='show_todo'),
path('todo/archiv', get_archiv, name='archv'),
path('todo/archiv/', get_archiv, name='archv'),
]
if settings.DEBUG:
......
......@@ -68,6 +68,7 @@
<a class="navbar-brand" href="/impressum">Impressum</a>
</nav>
<script type='text/javascript' src={% static 'js/selectionpage.js' %}></script>
<script type='text/javascript' src={% static 'js/showtodos.js' %}></script>
{% endblock %}
</body>
</html>
\ No newline at end of file
......@@ -5,26 +5,29 @@
{% block content %}
<script type="text/javascript"></script>
<div class="row">
<div class="col-sm" class="todo-box">
<div class="col-sm todo-box">
<form action="" enctype="multipart/form-data" method="POST">
{% csrf_token %}
<div class="row justify-content-center">
<h3>Wie viel Zeit hast du?</h3>
<h3 class="text-center">Wie viel Zeit hast du?</h3>
</div>
<div class="row justify-content-center">
{% bootstrap_form form %}
</div>
<div>
<div id="submit-time" class="row justify-content-center">
<button type="button" class="btn btn-danger">Aufgaben auswählen!</button>
</div>
<div id="timing-messages">
<p class="text-center" id="avail-time"></p>
<p class="text-center" id="chosen-time"></p>
<p class="text-center warning" id="time-warning">Wahrscheinlich nimmst du dir gerade zu viel vor. Konzentriere dich auf das Wichtigste ;)</p>
</div>
<div id="choices">
<ul class="list-group">
<li class="list-group-item" id="chosen-todos">Meine todos</li>
{# {% for todo in todos_selection %}#}
{# <div class="todo-text">{{ todo.0.text }}</div>#}
{# <div class="todo-due">{{ todo.1 }}</div>#}
{# <div class="todo-duration">{{ todo.0.duration }} Minuten</div>#}
{# {% endfor %}#}
<li class="list-group-item" id="chosen-todos">Meine Aufgaben</li>
</ul>
</div>
<div class="row justify-content-center">
<div id="submit-selection" class="row justify-content-center" disabled="disabled">
<input type="submit" class="btn btn-danger" value="Auswahl speichern und loslegen!">
</div>
</form>
......@@ -32,7 +35,7 @@
</div>
<div class="col-sm" id="todo-choices">
<div class="row justify-content-center">
<h3>Welche Todos willst du gleich erledigen?</h3>
<h3 class="text-center">Welche Aufgaben willst du jetzt erledigen?</h3>
</div>
<div class="row justify-content-center">
<div id="accordion">
......@@ -49,12 +52,12 @@
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne"
data-parent="#accordion">
<div class="card-body" id="body-late">
<div class="list-group list group-flush">
<div class="list-group list-group-flush">
{% for todo in todos_late %}
<div class="list-group-item list-group-item-action select-todo-grid">
<div class="todo-text">{{ todo.0.text }}</div>
<div class="todo-due">{{ todo.1 }}</div>
<div class="todo-duration">{{ todo.0.duration }} Minuten</div>
<div class="todo-due">{{ todo.1 }}</div>
<div class="todo-id" hidden>{{ todo.0.id }}</div>
</div>
{% endfor %}
......@@ -74,12 +77,12 @@
</div>
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordion">
<div class="card-body">
<div class="list-group list group-flush">
<div class="list-group list-group-flush">
{% for todo in todos_today %}
<div class="list-group-item list-group-item-action select-todo-grid">
<div class="todo-text">{{ todo.0.text }}</div>
<div class="todo-due">{{ todo.1 }}</div>
<div class="todo-duration">{{ todo.0.duration }} Minuten</div>
<div class="todo-due">{{ todo.1 }}</div>
<div class="todo-id" hidden>{{ todo.0.id }}</div>
</div>
{% endfor %}
......@@ -100,12 +103,12 @@
<div id="collapseThree" class="collapse" aria-labelledby="headingThree"
data-parent="#accordion">
<div class="card-body">
<div class="list-group list group-flush">
<div class="list-group list-group-flush">
{% for todo in todos_soon %}
<div class="list-group-item list-group-item-action select-todo-grid">
<div class="todo-text">{{ todo.0.text }}</div>
<div class="todo-due">{{ todo.1 }}</div>
<div class="todo-duration">{{ todo.0.duration }} Minuten</div>
<div class="todo-due">{{ todo.1 }}</div>
<div class="todo-id" hidden>{{ todo.0.id }}</div>
</div>
{% endfor %}
......@@ -126,7 +129,7 @@
<div id="collapseFour" class="collapse" aria-labelledby="headingFour"
data-parent="#accordion">
<div class="card-body">
<ul class="list-group list group-flush">
<ul class="list-group list-group-flush">
{% for todo in todos_someday %}
<div class="list-group-item list-group-item-action select-todo-grid">
<div class="todo-text">{{ todo.text }}</div>
......
......@@ -2,7 +2,123 @@
{% load bootstrap4 %}
{% block content %}
<div id="show-todos">
<div class="row justify-content-center">
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
<input type="submit" class="btn btn-primary" value="Änderungen speichern">
</form>
</div>
<div class="row justify-content-center">
<div id="accordion">
<div class="card">
<div class="card-header todo-late" id="headingOne">
<h5 class="mb-0">
<button class="btn btn-link todo-late" data-toggle="collapse" data-target="#collapseOne"
aria-expanded="true" aria-controls="collapseOne">
Dinge, die eigentlich schon getan sein sollten
</button>
</h5>
</div>
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne"
data-parent="#accordion">
<div class="card-body" id="body-late">
<div class="list-group list-group-flush">
{% for todo in todos_late %}
<div class="list-group-item list-group-item-action select-todo-grid-show">
<input class="todo-check" type="checkbox">
<div class="todo-text">{{ todo.0.text }}</div>
<div class="todo-duration">{{ todo.0.duration }} Minuten</div>
<div class="todo-due">{{ todo.1 }}</div>
<div class="todo-id" hidden>{{ todo.0.id }}</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header todo-today" id="headingTwo">
<h5 class="mb-0">
<button class="btn btn-link collapsed todo-today" data-toggle="collapse"
data-target="#collapseTwo"
aria-expanded="false" aria-controls="collapseTwo">
Dinge, die heute zu erledigen sind
</button>
</h5>
</div>
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordion">
<div class="card-body">
<div class="list-group list-group-flush">
{% for todo in todos_today %}
<div class="list-group-item list-group-item-action select-todo-grid-show">
<input class="todo-check" type="checkbox">
<div class="todo-text">{{ todo.0.text }}</div>
<div class="todo-duration">{{ todo.0.duration }} Minuten</div>
<div class="todo-due">{{ todo.1 }}</div>
<div class="todo-id" hidden>{{ todo.0.id }}</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header todo-soon" id="headingThree">
<h5 class="mb-0">
<button class="btn btn-link collapsed todo-soon" data-toggle="collapse"
data-target="#collapseThree" aria-expanded="false"
aria-controls="collapseThree">
Dinge, die bald zu erledigen sind
</button>
</h5>
</div>
<div id="collapseThree" class="collapse" aria-labelledby="headingThree"
data-parent="#accordion">
<div class="card-body">
<div class="list-group list-group-flush">
{% for todo in todos_soon %}
<div class="list-group-item list-group-item-action select-todo-grid-show">
<input class="todo-check" type="checkbox">
<div class="todo-text">{{ todo.0.text }}</div>
<div class="todo-duration">{{ todo.0.duration }} Minuten</div>
<div class="todo-due">{{ todo.1 }}</div>
<div class="todo-id" hidden>{{ todo.0.id }}</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header todo-someday" id="headingFour">
<h5 class="mb-0">
<button class="btn btn-link collapsed todo-someday" data-toggle="collapse"
data-target="#collapseFour" aria-expanded="false"
aria-controls="collapseFour">
Dinge, die keinen Zeitdruck haben
</button>
</h5>
</div>
<div id="collapseFour" class="collapse" aria-labelledby="headingFour"
data-parent="#accordion">
<div class="card-body">
<ul class="list-group list-group-flush">
{% for todo in todos_someday %}
<div class="list-group-item list-group-item-action select-todo-grid-show">
<input class="todo-check" type="checkbox">
<div class="todo-text">{{ todo.text }}</div>
<div class="todo-duration">{{ todo.duration }} Minuten</div>
<div class="todo-id" hidden>{{ todo.id }}</div>
</div>
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
\ No newline at end of file
......@@ -21,17 +21,17 @@ class SelectionForm(forms.Form):
label='Stunden',
max_value=24,
min_value=0,
widget=forms.NumberInput(attrs={'max': 24, 'min': 0, 'style': 'width:150px;'})
widget=forms.NumberInput(attrs={'max': 24, 'min': 0, 'style': 'width:150px;',
'id': 'duration-hours'})
)
duration_minutes = forms.IntegerField(
label='Minuten',
max_value=59,
min_value=0,
widget=forms.NumberInput(attrs={'max': 55, 'min': 0, 'step': 5, 'style': 'width: 150px;'})
widget=forms.NumberInput(attrs={'max': 55, 'min': 0, 'step': 5,
'style': 'width: 150px;', 'id': 'duration-minutes'})
)
selection = forms.CharField(
label='Selection',
max_length=100,
widget=forms.TextInput(attrs={'type': 'hidden', 'id': 'selection-hidden-input'})
)
......@@ -44,3 +44,14 @@ class SelectionForm(forms.Form):
def todos_string_to_list(self):
cleaned_data = super(SelectionForm, self).clean()
return cleaned_data['selection'].split(',')
class CheckedTodosForm(forms.Form):
checkedTodos = forms.CharField(
required=False,
widget=forms.TextInput(attrs={'type': 'hidden', 'id': 'checked-todos-hidden-input'})
)
def todos_string_to_list(self):
cleaned_data = super(CheckedTodosForm, self).clean()
return cleaned_data['checkedTodos'].split(',')
# Generated by Django 3.0.7 on 2020-07-05 13:38
import datetime
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('todo', '0008_auto_20200705_0002'),
]
operations = [
migrations.AddField(
model_name='selection',
name='active',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='selection',
name='endtime',
field=models.DateField(default=datetime.datetime.today),
preserve_default=False,
),
migrations.AddField(
model_name='selection',
name='started',
field=models.DateField(default=datetime.datetime.today),
),
]
# Generated by Django 3.0.7 on 2020-07-05 13:39
import datetime
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('todo', '0009_auto_20200705_1538'),
]
operations = [
migrations.AlterField(
model_name='selection',
name='endtime',
field=models.DateTimeField(),
),
migrations.AlterField(
model_name='selection',
name='started',
field=models.DateTimeField(default=datetime.datetime.today),
),
]
......@@ -8,6 +8,9 @@ class Selection(models.Model):
name = models.CharField(max_length=30, default="name")
# items = models.ManyToManyField(Todo)
total_time = models.IntegerField(default=0) # in minutes
active = models.BooleanField(default=False)
started = models.DateTimeField(default=datetime.datetime.today)
endtime = models.DateTimeField()
def __str__(self):
return f'{self.name}, total time: {self.total_time.__str__()}'
......
......@@ -55,3 +55,43 @@ div.form-control.recurrence-widget {
background: darkseagreen;
color: floralwhite;
}
.warning {
color: indianred;
}
/*show todos*/
.list-group-item.select-todo-grid-show {
display: grid;
grid-template-columns: 20px auto auto 30px 30px;
grid-template-rows: auto auto;
}
.select-todo-grid-show .todo-check {
grid-column-start: 1;
grid-row: 1 / 2;
align-self: center;
}
.select-todo-grid-show .todo-text {
grid-column-start: 2;
}
.select-todo-grid-show .todo-due {
grid-row-start: 2;
grid-column-start: 3;
font-size: small;
justify-self: end;
width: fit-content;
}
.select-todo-grid-show .todo-duration {
grid-column-start: 3;
justify-self: end;
width: fit-content;
}
#show-todos #accordion {
width: -webkit-fill-available;
}
\ No newline at end of file
let selections = [];
// hide todo elements before setting timer
// $('#todo-choices').hide();
if($('#todo-choices').length) {
let selections = [];
let duration_todos = 0;
let total_time = 0;
let formSubmittable = false;
let $todoChoices;
let $timingMessages;
let $timeWarning;
let $choices;
let $submitSelection;
let $submitTime;
let $durationHours;
let $durationMinutes;
let $form;
window.addEventListener('load', init, false);
function init() {
$todoChoices = $('#todo-choices');
$timingMessages = $('#timing-messages');
$timeWarning = $('#time-warning');
$choices = $('#choices');
$submitSelection = $('#submit-selection');
$submitTime = $('#submit-time');
$durationHours = $('#duration-hours');
$durationMinutes = $('#duration-minutes');
$form = $('form');
// hide everything before setting timer
$todoChoices.hide();
$timingMessages.hide();
$timeWarning.hide();
$submitSelection.hide();
$choices.hide();
$form.on('keyup keypress', e => {
const keyCode = e.keyCode || e.which;
if (e.keyCode === 13 && !formSubmittable) {
e.preventDefault();
return false;
}
})
//set avail_time string
$durationHours.on('blur', e => {
if ($submitTime.is(":visible")) {
return;
}
doTotalTimeThings();
})
$durationMinutes.on('blur', e => {
if ($submitTime.is(":visible")) {
return;
}
doTotalTimeThings();
})
$submitTime.on('click keyup keypress', e => {
const keyCode = e.keyCode || e.which;
if (e.keyCode && e.keyCode !== 13) {
return;
}
showWhenTimeSet();
doTotalTimeThings();
formSubmittable = true;
})
}
//event listener for choosing todos
$('.select-todo-grid').on('click', e => {
$('.select-todo-grid').on('click keyup keypress', e => {
const keyCode = e.keyCode || e.which;
if (e.keyCode && e.keyCode !== 13) {
return;
}
//get node with class "select-todo-grid"
let node = e.target.closest(".select-todo-grid");
......@@ -12,8 +82,54 @@ $('.select-todo-grid').on('click', e => {
selections.push(id);
$('#selection-hidden-input').val(selections.toString());
//show node under "Meine Aufgaben"
let clonedNode = node.cloneNode(true)
document.getElementById('chosen-todos').appendChild(clonedNode);
node.style.display = "none";
});
//set chosen-time string
let durationStr = node.children[1].textContent;
let duration = durationStr.substring(0, durationStr.indexOf(' '));
duration_todos += parseInt(duration);
let hours = Math.floor(duration_todos / 60);
let minutes = duration_todos % 60;
setChosenTimeString(hours, minutes);
if (duration_todos > total_time) {
$('#time-warning').show();
} else {
$('#time-warning').hide();
}
});
function setChosenTimeString(hours, minutes) {
let hoursStr = hours ? ((hours < 10) ? ('0' + hours) : hours) : '00';
let minutesStr = minutes ? ((minutes < 10) ? ('0' + minutes) : minutes) : '00';
$('#chosen-time').text(`Deine bisher gewählten Aufgaben dauern ${hoursStr}:${minutesStr} Stunden.`);
}
function doTotalTimeThings() {
if ($submitTime.is(":visible")) {
return;
}
let hours = parseInt($durationHours.val());
let minutes = parseInt($durationMinutes.val());
total_time = hours * 60 + minutes;
setAvailTimeString(hours, minutes);
}
function setAvailTimeString(hours, minutes) {
let hoursStr = hours ? ((hours < 10) ? ('0' + hours) : hours) : '00';
let minutesStr = minutes ? ((minutes < 10) ? ('0' + minutes) : minutes) : '00';
$('#avail-time').text(`Du hast ${hoursStr}:${minutesStr} Stunden Zeit.`);
}
function showWhenTimeSet() {
$todoChoices.show();
$timingMessages.show();
$submitSelection.show();
$choices.show();
$submitTime.hide();
}
}
if($('#show-todos').length) {
let checkedTodosList = [];
let $checkedTodos = $('#checked-todos-hidden-input');
window.addEventListener('load', init, false);
function init() {
$('.todo-check').on('click', e => {
let id = e.target.closest('.select-todo-grid-show').lastElementChild.textContent;
if (e.target.value) {
checkedTodosList.push(id);
} else {
checkedTodosList.remove(id);
}
$checkedTodos.val(checkedTodosList);
})
$('.select-todo-grid-show').on('click', e => {
$(e.target).children().css('class', 'todo-check').click();
})
}
}
\ No newline at end of file
......@@ -14,6 +14,7 @@ def get_landing_page(request):
context = {'todo_list': todo_list}
return render(request, 'todo/landing_page.html', {'page_title': 'Feierabend!'})
def add_todo(request):
todo = Todo()
......@@ -44,9 +45,8 @@ def get_selection_page(request):
form = SelectionForm(request.POST)
if form.is_valid():
selection.total_time = form.calc_total_time()
# chosen_todos = Todo.objects.filter(pk__in=form.todos_string_to_list())
# selection.items.addAll(chosen_todos)
# selection.items.add(Todo.objects.get(id=31))
selection.active = True
selection.endtime = selection.started + datetime.timedelta(minutes=selection.total_time)
selection.save()
for id in form.todos_string_to_list():
todo = Todo.objects.get(pk=id)
......@@ -60,12 +60,26 @@ def get_selection_page(request):
form = SelectionForm()
# für Anzeige - Anfang
todos_with_recurrence = Todo.objects.filter(complete=False).exclude(recurrences__exact='')
todos_without_recurrence = Todo.objects.filter(complete=False).filter(recurrences__exact='')
todos_today = []
todos_soon = []
todos_late = []
todos_someday = []
sort_todos(todos_late, todos_someday, todos_soon, todos_today)
content = {'page_title': 'Leg eine Liste an',
'form': form,
'todos_today': todos_today,
'todos_soon': todos_soon,
'todos_late': todos_late,
'todos_someday': todos_someday,
'todos_selection': [],
}
return render(request, 'todo/selection_page.html', content)
def sort_todos(todos_late, todos_someday, todos_soon, todos_today):
todos_with_recurrence = Todo.objects.filter(complete=False).exclude(recurrences__exact='')