delete app tasks
This commit is contained in:
@@ -56,7 +56,6 @@ INSTALLED_APPS = [
|
|||||||
"posts.apps.PostsConfig",
|
"posts.apps.PostsConfig",
|
||||||
"members.apps.MembersConfig",
|
"members.apps.MembersConfig",
|
||||||
"blackboard.apps.BlackboardConfig",
|
"blackboard.apps.BlackboardConfig",
|
||||||
"tasks.apps.TasksConfig",
|
|
||||||
"gallery.apps.GalleryConfig",
|
"gallery.apps.GalleryConfig",
|
||||||
"intern.apps.InternConfig",
|
"intern.apps.InternConfig",
|
||||||
"finance.apps.FinanceConfig",
|
"finance.apps.FinanceConfig",
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ urlpatterns = [
|
|||||||
path("jobs/", include("blackboard.urls")),
|
path("jobs/", include("blackboard.urls")),
|
||||||
path("posts/", include("posts.urls")),
|
path("posts/", include("posts.urls")),
|
||||||
path("search/", include("search.urls")),
|
path("search/", include("search.urls")),
|
||||||
path("tasks/", include("tasks.urls")),
|
|
||||||
path(
|
path(
|
||||||
"discord/",
|
"discord/",
|
||||||
RedirectView.as_view(url="https://discord.com/invite/7qRuuMA"),
|
RedirectView.as_view(url="https://discord.com/invite/7qRuuMA"),
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ from ckeditor_uploader.widgets import CKEditorUploadingWidget
|
|||||||
from django import forms
|
from django import forms
|
||||||
from django.forms.widgets import HiddenInput
|
from django.forms.widgets import HiddenInput
|
||||||
|
|
||||||
from tasks.models import Task, TaskList
|
|
||||||
|
|
||||||
from .models import Attachment, Etherpad, FileUpload, Topic, TopicGroup
|
from .models import Attachment, Etherpad, FileUpload, Topic, TopicGroup
|
||||||
|
|
||||||
|
|
||||||
@@ -33,7 +31,6 @@ class TopicAdminForm(forms.ModelForm):
|
|||||||
labels = {
|
labels = {
|
||||||
"title": "Titel",
|
"title": "Titel",
|
||||||
"slug": "Permalink",
|
"slug": "Permalink",
|
||||||
"task_list": "Aufgabenbereich",
|
|
||||||
"description": "Beschreibung",
|
"description": "Beschreibung",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Generated by Django 4.1.2 on 2022-12-21 11:42
|
# Generated by Django 4.2.6 on 2023-11-08 11:32
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
@@ -7,12 +7,9 @@ import fet2020.utils
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = []
|
||||||
("tasks", "0004_set_fields_unique"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
@@ -83,15 +80,6 @@ class Migration(migrations.Migration):
|
|||||||
("slug", models.SlugField()),
|
("slug", models.SlugField()),
|
||||||
("archive", models.BooleanField(default=False, verbose_name="Archiv")),
|
("archive", models.BooleanField(default=False, verbose_name="Archiv")),
|
||||||
("description", models.TextField(blank=True, null=True)),
|
("description", models.TextField(blank=True, null=True)),
|
||||||
(
|
|
||||||
"task_list",
|
|
||||||
models.ForeignKey(
|
|
||||||
blank=True,
|
|
||||||
null=True,
|
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
|
||||||
to="tasks.tasklist",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
"topic_group",
|
"topic_group",
|
||||||
models.ForeignKey(
|
models.ForeignKey(
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ from django.utils.text import slugify
|
|||||||
from documents import create_pad, get_pad_html
|
from documents import create_pad, get_pad_html
|
||||||
from documents.api import get_pad_link
|
from documents.api import get_pad_link
|
||||||
from fet2020.utils import create_random_id
|
from fet2020.utils import create_random_id
|
||||||
from tasks.models import TaskList
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -58,9 +57,6 @@ class Topic(models.Model):
|
|||||||
topic_group = models.ForeignKey(
|
topic_group = models.ForeignKey(
|
||||||
TopicGroup, on_delete=models.CASCADE, verbose_name="Themenbereich"
|
TopicGroup, on_delete=models.CASCADE, verbose_name="Themenbereich"
|
||||||
)
|
)
|
||||||
task_list = models.ForeignKey(
|
|
||||||
TaskList, blank=True, on_delete=models.CASCADE, null=True
|
|
||||||
)
|
|
||||||
|
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ from .views import (
|
|||||||
AttachmentUpdateView,
|
AttachmentUpdateView,
|
||||||
EtherpadCreateView,
|
EtherpadCreateView,
|
||||||
FileUploadCreateView,
|
FileUploadCreateView,
|
||||||
TaskCreateView,
|
|
||||||
TopicCreateView,
|
TopicCreateView,
|
||||||
TopicDetailView,
|
TopicDetailView,
|
||||||
TopicUpdateView,
|
TopicUpdateView,
|
||||||
@@ -50,7 +49,6 @@ topic_urlpatterns = [
|
|||||||
AttachmentCreateView.as_view(),
|
AttachmentCreateView.as_view(),
|
||||||
name="attachment_create",
|
name="attachment_create",
|
||||||
),
|
),
|
||||||
path("create-task/", TaskCreateView.as_view(), name="task_create"),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ from django.views.generic.edit import CreateView, UpdateView
|
|||||||
from authentications.decorators import authenticated_user
|
from authentications.decorators import authenticated_user
|
||||||
from documents.etherpadlib import add_ep_cookie
|
from documents.etherpadlib import add_ep_cookie
|
||||||
from fet2020.utils import add_log_action
|
from fet2020.utils import add_log_action
|
||||||
from tasks.forms import InternTaskCreateForm
|
|
||||||
from tasks.models import Task
|
|
||||||
|
|
||||||
from .forms import (
|
from .forms import (
|
||||||
AttachmentCreateForm,
|
AttachmentCreateForm,
|
||||||
@@ -70,21 +68,8 @@ class TopicDetailView(LoginRequiredMixin, DetailView):
|
|||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
|
|
||||||
attachments = Attachment.objects.filter(topic=self.object).order_by("title")
|
attachments = Attachment.objects.filter(topic=self.object).order_by("title")
|
||||||
|
|
||||||
tasks = None
|
|
||||||
if self.object.task_list:
|
|
||||||
tasks = deque(
|
|
||||||
Task.taskmanager.get_tasks(
|
|
||||||
user=None,
|
|
||||||
assigned_tasks=True,
|
|
||||||
task_list=self.object.task_list,
|
|
||||||
completed=False,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
context["topic"] = self.object
|
|
||||||
context["attachments"] = attachments
|
context["attachments"] = attachments
|
||||||
context["tasks"] = tasks
|
context["topic"] = self.object
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
@@ -238,24 +223,3 @@ class FileUploadCreateView(LoginRequiredMixin, CreateView):
|
|||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
return reverse("intern:attachment", kwargs=self.kwargs)
|
return reverse("intern:attachment", kwargs=self.kwargs)
|
||||||
|
|
||||||
|
|
||||||
class TaskCreateView(LoginRequiredMixin, CreateView):
|
|
||||||
form_class = InternTaskCreateForm
|
|
||||||
model = Task
|
|
||||||
template_name = "intern/task_create.html"
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
|
||||||
form.instance.created_by = self.request.user
|
|
||||||
add_log_action(self.request, form, "tasks", "task", True)
|
|
||||||
return super().form_valid(form)
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super().get_context_data(**kwargs)
|
|
||||||
slug = self.kwargs.get("slug")
|
|
||||||
topic = Topic.objects.get(slug=slug)
|
|
||||||
context["topic"] = topic
|
|
||||||
return context
|
|
||||||
|
|
||||||
def get_success_url(self):
|
|
||||||
return reverse("intern:topic", kwargs=self.kwargs)
|
|
||||||
|
|||||||
@@ -1,127 +0,0 @@
|
|||||||
from django.contrib import admin
|
|
||||||
|
|
||||||
from .forms import DocumentInlineForm, TaskAdminForm, TaskListAdminForm
|
|
||||||
from .models import Document, Task, TaskList
|
|
||||||
|
|
||||||
|
|
||||||
class DocumentInline(admin.TabularInline):
|
|
||||||
form = DocumentInlineForm
|
|
||||||
model = Document
|
|
||||||
extra = 0
|
|
||||||
verbose_name = "Dokument"
|
|
||||||
verbose_name_plural = "Dokumentensammlung"
|
|
||||||
|
|
||||||
|
|
||||||
class TaskListAdmin(admin.ModelAdmin):
|
|
||||||
form = TaskListAdminForm
|
|
||||||
model = TaskList
|
|
||||||
|
|
||||||
fieldsets = (
|
|
||||||
(
|
|
||||||
None,
|
|
||||||
{
|
|
||||||
"fields": (
|
|
||||||
"name",
|
|
||||||
"shortterm",
|
|
||||||
"slug",
|
|
||||||
"users",
|
|
||||||
)
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
readonly_fields = ("slug",)
|
|
||||||
|
|
||||||
def add_view(self, request, form_url="", extra_context=None):
|
|
||||||
extra_context = extra_context or {}
|
|
||||||
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
|
|
||||||
return super().add_view(
|
|
||||||
request,
|
|
||||||
form_url,
|
|
||||||
extra_context=extra_context,
|
|
||||||
)
|
|
||||||
|
|
||||||
def change_view(self, request, object_id, form_url="", extra_context=None):
|
|
||||||
extra_context = extra_context or {}
|
|
||||||
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
|
|
||||||
return super().change_view(
|
|
||||||
request,
|
|
||||||
object_id,
|
|
||||||
form_url,
|
|
||||||
extra_context=extra_context,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class TaskAdmin(admin.ModelAdmin):
|
|
||||||
form = TaskAdminForm
|
|
||||||
model = Task
|
|
||||||
inlines = (DocumentInline,)
|
|
||||||
|
|
||||||
fieldsets = (
|
|
||||||
(
|
|
||||||
None,
|
|
||||||
{
|
|
||||||
"fields": (
|
|
||||||
"title",
|
|
||||||
"task_list",
|
|
||||||
"note",
|
|
||||||
"priority",
|
|
||||||
),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"Fälligkeit",
|
|
||||||
{
|
|
||||||
"fields": (
|
|
||||||
"due_date",
|
|
||||||
"assigned_to",
|
|
||||||
),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"Abgeschlossen",
|
|
||||||
{
|
|
||||||
"fields": (
|
|
||||||
"completed_date",
|
|
||||||
"completed",
|
|
||||||
),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
list_display = [
|
|
||||||
"title",
|
|
||||||
"task_list",
|
|
||||||
"assigned_to",
|
|
||||||
"due_date",
|
|
||||||
"completed",
|
|
||||||
"priority",
|
|
||||||
]
|
|
||||||
list_filter = ("task_list",)
|
|
||||||
search_fields = ("title",)
|
|
||||||
|
|
||||||
def add_view(self, request, form_url="", extra_context=None):
|
|
||||||
extra_context = extra_context or {}
|
|
||||||
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
|
|
||||||
return super().add_view(
|
|
||||||
request,
|
|
||||||
form_url,
|
|
||||||
extra_context=extra_context,
|
|
||||||
)
|
|
||||||
|
|
||||||
def change_view(self, request, object_id, form_url="", extra_context=None):
|
|
||||||
extra_context = extra_context or {}
|
|
||||||
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
|
|
||||||
return super().change_view(
|
|
||||||
request,
|
|
||||||
object_id,
|
|
||||||
form_url,
|
|
||||||
extra_context=extra_context,
|
|
||||||
)
|
|
||||||
|
|
||||||
def save_model(self, request, obj, form, change):
|
|
||||||
obj.created_by = request.user
|
|
||||||
super().save_model(request, obj, form, change)
|
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(TaskList, TaskListAdmin)
|
|
||||||
admin.site.register(Task, TaskAdmin)
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
from django.apps import AppConfig
|
|
||||||
from django.db.models.signals import post_migrate
|
|
||||||
|
|
||||||
from fet2020.utils import create_perms
|
|
||||||
|
|
||||||
|
|
||||||
class TasksConfig(AppConfig):
|
|
||||||
name = "tasks"
|
|
||||||
|
|
||||||
def ready(self):
|
|
||||||
post_migrate.connect(create_perms, sender=self)
|
|
||||||
@@ -1,221 +0,0 @@
|
|||||||
from ckeditor.widgets import CKEditorWidget
|
|
||||||
from django import forms
|
|
||||||
from django.contrib.admin.widgets import FilteredSelectMultiple
|
|
||||||
from django.contrib.auth.models import User
|
|
||||||
from django.core.validators import ValidationError
|
|
||||||
from django.forms.widgets import HiddenInput
|
|
||||||
from django.utils import timezone
|
|
||||||
|
|
||||||
from .models import Document, Task, TaskList
|
|
||||||
|
|
||||||
|
|
||||||
class DateInput(forms.DateInput):
|
|
||||||
input_type = "date"
|
|
||||||
|
|
||||||
|
|
||||||
class DocumentInlineForm(forms.ModelForm):
|
|
||||||
class Meta:
|
|
||||||
model = Document
|
|
||||||
fields = [
|
|
||||||
"title",
|
|
||||||
"date",
|
|
||||||
]
|
|
||||||
|
|
||||||
labels = {
|
|
||||||
"title": "Titel",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class TaskListAdminForm(forms.ModelForm):
|
|
||||||
users = forms.ModelMultipleChoiceField(
|
|
||||||
label="Benutzer",
|
|
||||||
help_text="Es können nur die Benutzer ausgewählt werden, die sich auf der Homepage angemeldet haben.",
|
|
||||||
queryset=User.objects.all().order_by("username"),
|
|
||||||
widget=FilteredSelectMultiple("User", is_stacked=False),
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = TaskList
|
|
||||||
fields = "__all__"
|
|
||||||
|
|
||||||
labels = {
|
|
||||||
"name": "Titel",
|
|
||||||
"shortterm": "Kürzel für den Link",
|
|
||||||
"slug": "Permalink",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class TaskAdminForm(forms.ModelForm):
|
|
||||||
class Meta:
|
|
||||||
model = Task
|
|
||||||
fields = "__all__"
|
|
||||||
|
|
||||||
labels = {
|
|
||||||
"title": "Titel",
|
|
||||||
"shortterm": "Kürzel für den Link",
|
|
||||||
"slug": "Permalink",
|
|
||||||
"task_list": "Aufgabenbereich",
|
|
||||||
"due_date": "Fälligkeit",
|
|
||||||
"completed": "Abgeschlossen",
|
|
||||||
"completed_date": "Datum der Fertigstellung",
|
|
||||||
"assigned_to": "Zuweisen an",
|
|
||||||
"note": "Notizen",
|
|
||||||
"priority": "Priorität",
|
|
||||||
}
|
|
||||||
|
|
||||||
widgets = {
|
|
||||||
"note": CKEditorWidget(config_name="default"),
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs) # to get the self.fields set
|
|
||||||
self.fields["assigned_to"].empty_label = "Alle"
|
|
||||||
self.fields["assigned_to"].queryset = self.fields[
|
|
||||||
"assigned_to"
|
|
||||||
].queryset.order_by("username")
|
|
||||||
|
|
||||||
|
|
||||||
class TaskCreateForm(forms.ModelForm):
|
|
||||||
class Meta:
|
|
||||||
model = Task
|
|
||||||
|
|
||||||
fields = [
|
|
||||||
"title",
|
|
||||||
"task_list",
|
|
||||||
"due_date",
|
|
||||||
"assigned_to",
|
|
||||||
"note",
|
|
||||||
]
|
|
||||||
|
|
||||||
labels = {
|
|
||||||
"title": "Titel des Tasks",
|
|
||||||
"task_list": "Task-Gruppe",
|
|
||||||
"assigned_to": "Zuweisen an",
|
|
||||||
"due_date": "Fälligkeitsdatum",
|
|
||||||
"note": "Notizen",
|
|
||||||
}
|
|
||||||
|
|
||||||
widgets = {
|
|
||||||
"due_date": DateInput(format=("%Y-%m-%d")),
|
|
||||||
"note": CKEditorWidget(config_name="intern"),
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
if "user" in kwargs:
|
|
||||||
user = kwargs.pop("user")
|
|
||||||
else:
|
|
||||||
user = None
|
|
||||||
|
|
||||||
super().__init__(*args, **kwargs) # to get the self.fields set
|
|
||||||
self.fields["assigned_to"].empty_label = "Alle"
|
|
||||||
qs = self.fields["assigned_to"].queryset
|
|
||||||
self.fields["assigned_to"].queryset = qs.order_by("username")
|
|
||||||
|
|
||||||
if user:
|
|
||||||
self.fields["task_list"].queryset = TaskList.objects.filter(users=user)
|
|
||||||
|
|
||||||
def clean(self):
|
|
||||||
cleaned_data = super().clean()
|
|
||||||
assigned_to = cleaned_data["assigned_to"]
|
|
||||||
|
|
||||||
if assigned_to:
|
|
||||||
task_list = TaskList.objects.get(id=cleaned_data["task_list"].id)
|
|
||||||
if not task_list.users.filter(username=assigned_to.username):
|
|
||||||
raise ValidationError(
|
|
||||||
_(
|
|
||||||
f"User '{assigned_to}' gibt es nicht in der User-Liste der Task-Gruppe '{task_list}'."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
return cleaned_data
|
|
||||||
|
|
||||||
|
|
||||||
class TaskUpdateForm(forms.ModelForm):
|
|
||||||
class Meta:
|
|
||||||
model = Task
|
|
||||||
|
|
||||||
fields = [
|
|
||||||
"assigned_to",
|
|
||||||
"due_date",
|
|
||||||
"completed",
|
|
||||||
"completed_date",
|
|
||||||
"note",
|
|
||||||
"task_list",
|
|
||||||
]
|
|
||||||
|
|
||||||
labels = {
|
|
||||||
"assigned_to": "Zuweisen an",
|
|
||||||
"due_date": "Fälligkeitsdatum",
|
|
||||||
"completed": "Abgeschlossen",
|
|
||||||
"completed_date": "Datum der Fertigstellung",
|
|
||||||
"note": "Notizen",
|
|
||||||
}
|
|
||||||
|
|
||||||
widgets = {
|
|
||||||
"due_date": DateInput(
|
|
||||||
format=("%Y-%m-%d"),
|
|
||||||
),
|
|
||||||
"note": CKEditorWidget(config_name="intern"),
|
|
||||||
"task_list": HiddenInput,
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
if "task_list" in kwargs:
|
|
||||||
task_list = kwargs.pop("task_list")
|
|
||||||
else:
|
|
||||||
task_list = None
|
|
||||||
|
|
||||||
super().__init__(*args, **kwargs) # to get the self.fields set
|
|
||||||
self.fields["assigned_to"].empty_label = "Alle"
|
|
||||||
if task_list:
|
|
||||||
qs = TaskList.objects.get(id=task_list.id).users
|
|
||||||
self.fields["assigned_to"].queryset = qs.order_by("username")
|
|
||||||
|
|
||||||
|
|
||||||
class DocumentCreateForm(forms.ModelForm):
|
|
||||||
class Meta:
|
|
||||||
model = Document
|
|
||||||
|
|
||||||
fields = [
|
|
||||||
"title",
|
|
||||||
"date",
|
|
||||||
"task",
|
|
||||||
]
|
|
||||||
|
|
||||||
labels = {
|
|
||||||
"title": "Titel",
|
|
||||||
"date": "Datum",
|
|
||||||
}
|
|
||||||
|
|
||||||
widgets = {
|
|
||||||
"date": DateInput(format=("%d-%m-%Y")),
|
|
||||||
"task": HiddenInput,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class InternTaskCreateForm(TaskCreateForm):
|
|
||||||
# form for creating a task from intern page.
|
|
||||||
class Meta:
|
|
||||||
model = Task
|
|
||||||
|
|
||||||
fields = [
|
|
||||||
"title",
|
|
||||||
"task_list",
|
|
||||||
"due_date",
|
|
||||||
"assigned_to",
|
|
||||||
"note",
|
|
||||||
]
|
|
||||||
|
|
||||||
labels = {
|
|
||||||
"title": "Titel des Tasks",
|
|
||||||
"task_list": "Task-Gruppe",
|
|
||||||
"due_date": "Fälligkeitsdatum",
|
|
||||||
"assigned_to": "Zuweisen an",
|
|
||||||
}
|
|
||||||
|
|
||||||
widgets = {
|
|
||||||
"due_date": DateInput(
|
|
||||||
format=("%d-%m-%Y"),
|
|
||||||
),
|
|
||||||
"task_list": HiddenInput,
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
from django.db import models
|
|
||||||
from django.db.models import Q
|
|
||||||
|
|
||||||
|
|
||||||
class TaskManager(models.Manager):
|
|
||||||
def get_tasks(self, user, assigned_tasks, task_list, completed):
|
|
||||||
# None ... assigned to all users
|
|
||||||
qs_all = self.get_queryset()
|
|
||||||
qs = qs_all.filter(assigned_to__id=user)
|
|
||||||
|
|
||||||
if not assigned_tasks:
|
|
||||||
qs_tmp = qs_all.filter(
|
|
||||||
Q(assigned_to=None) & Q(task_list__users__id__exact=user)
|
|
||||||
)
|
|
||||||
qs = (qs | qs_tmp).distinct()
|
|
||||||
|
|
||||||
if task_list:
|
|
||||||
qs = qs.filter(task_list=task_list)
|
|
||||||
|
|
||||||
return qs.filter(completed=completed)
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
# Generated by Django 3.1.5 on 2021-01-29 18:35
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
initial = True
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='TaskList',
|
|
||||||
fields=[
|
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('name', models.CharField(max_length=60)),
|
|
||||||
('slug', models.SlugField(blank=True, null=True, unique=True)),
|
|
||||||
('users', models.ManyToManyField(blank=True, to=settings.AUTH_USER_MODEL)),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'verbose_name': 'Auf\xadga\xadben\xadbe\xadreich',
|
|
||||||
'verbose_name_plural': 'Auf\xadga\xadben\xadbe\xadreiche',
|
|
||||||
},
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='Task',
|
|
||||||
fields=[
|
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('title', models.CharField(max_length=140, verbose_name='Titel')),
|
|
||||||
('created_date', models.DateTimeField(auto_now_add=True)),
|
|
||||||
('due_date', models.DateField(blank=True, null=True, verbose_name='Fälligkeit')),
|
|
||||||
('completed', models.BooleanField(default=False, verbose_name='Abgeschlossen')),
|
|
||||||
('completed_date', models.DateField(blank=True, null=True)),
|
|
||||||
('note', models.TextField(blank=True, null=True, verbose_name='Notizen')),
|
|
||||||
('priority', models.PositiveIntegerField(blank=True, null=True, verbose_name='Priorität')),
|
|
||||||
('assigned_to', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='assigned_to', to=settings.AUTH_USER_MODEL, verbose_name='Zugewiesen an')),
|
|
||||||
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='created_by', to=settings.AUTH_USER_MODEL)),
|
|
||||||
('task_list', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='tasks.tasklist', verbose_name='Aufgabenbereich')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'verbose_name': 'Aufgabe',
|
|
||||||
'verbose_name_plural': 'Aufgaben',
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
# Generated by Django 4.1.2 on 2022-12-21 11:42
|
|
||||||
|
|
||||||
import datetime
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
import fet2020.utils
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("tasks", "0001_initial"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterModelOptions(
|
|
||||||
name="task",
|
|
||||||
options={
|
|
||||||
"ordering": (
|
|
||||||
"task_list",
|
|
||||||
models.OrderBy(
|
|
||||||
models.F("due_date"), descending=True, nulls_first=True
|
|
||||||
),
|
|
||||||
),
|
|
||||||
"verbose_name": "Aufgabe",
|
|
||||||
"verbose_name_plural": "Aufgaben",
|
|
||||||
},
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="task",
|
|
||||||
name="slug",
|
|
||||||
field=models.SlugField(blank=True, null=True),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="task",
|
|
||||||
name="slug_id",
|
|
||||||
field=models.CharField(
|
|
||||||
default=fet2020.utils.create_random_id,
|
|
||||||
editable=False,
|
|
||||||
max_length=8,
|
|
||||||
null=True,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="tasklist",
|
|
||||||
name="shortterm",
|
|
||||||
field=models.CharField(blank=True, max_length=128, null=True),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name="task",
|
|
||||||
name="title",
|
|
||||||
field=models.CharField(max_length=128, verbose_name="Titel"),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name="tasklist",
|
|
||||||
name="name",
|
|
||||||
field=models.CharField(max_length=128),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name="tasklist",
|
|
||||||
name="slug",
|
|
||||||
field=models.SlugField(blank=True, null=True),
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name="Document",
|
|
||||||
fields=[
|
|
||||||
(
|
|
||||||
"id",
|
|
||||||
models.AutoField(
|
|
||||||
auto_created=True,
|
|
||||||
primary_key=True,
|
|
||||||
serialize=False,
|
|
||||||
verbose_name="ID",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
("title", models.CharField(max_length=128, verbose_name="Titel")),
|
|
||||||
(
|
|
||||||
"slug_id",
|
|
||||||
models.CharField(
|
|
||||||
default=fet2020.utils.create_random_id,
|
|
||||||
editable=False,
|
|
||||||
max_length=8,
|
|
||||||
unique=True,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
("etherpad_key", models.CharField(blank=True, max_length=50)),
|
|
||||||
(
|
|
||||||
"date",
|
|
||||||
models.DateField(default=datetime.date.today, verbose_name="Datum"),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"task",
|
|
||||||
models.ForeignKey(
|
|
||||||
on_delete=django.db.models.deletion.CASCADE, to="tasks.task"
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
"verbose_name": "Dokument",
|
|
||||||
"verbose_name_plural": "Dokumente",
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
# Generated by Django 4.1.2 on 2022-12-21 11:43
|
|
||||||
|
|
||||||
from django.db import migrations
|
|
||||||
import fet2020.utils
|
|
||||||
from django.utils.text import slugify
|
|
||||||
|
|
||||||
|
|
||||||
def forwards_func(apps, schema_editor):
|
|
||||||
Tasks = apps.get_model("tasks", "Task")
|
|
||||||
for elem in Tasks.objects.all():
|
|
||||||
elem.slug_id = fet2020.utils.create_random_id()
|
|
||||||
elem.slug = elem.slug_id + "-" + slugify(elem.title)
|
|
||||||
elem.save(update_fields=["slug_id", "slug"])
|
|
||||||
|
|
||||||
TaskLists = apps.get_model("tasks", "TaskList")
|
|
||||||
for elem in TaskLists.objects.all():
|
|
||||||
elem.shortterm = slugify(elem.name)
|
|
||||||
elem.slug = slugify(elem.shortterm)
|
|
||||||
elem.save(update_fields=["shortterm", "slug"])
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("tasks", "0002_alter_task_options_task_slug_task_slug_id_and_more"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.RunPython(forwards_func, reverse_code=migrations.RunPython.noop),
|
|
||||||
]
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
# Generated by Django 4.1.2 on 2022-12-21 11:43
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import fet2020.utils
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("tasks", "0003_populate_unique_values"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name="task",
|
|
||||||
name="slug",
|
|
||||||
field=models.SlugField(blank=True, unique=True),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name="task",
|
|
||||||
name="slug_id",
|
|
||||||
field=models.CharField(
|
|
||||||
default=fet2020.utils.create_random_id,
|
|
||||||
editable=False,
|
|
||||||
max_length=8,
|
|
||||||
unique=True,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name="tasklist",
|
|
||||||
name="shortterm",
|
|
||||||
field=models.CharField(blank=True, max_length=128, unique=True),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name="tasklist",
|
|
||||||
name="slug",
|
|
||||||
field=models.SlugField(blank=True, unique=True),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,145 +0,0 @@
|
|||||||
from datetime import date
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.contrib.auth.models import User
|
|
||||||
from django.core.validators import ValidationError
|
|
||||||
from django.db import models
|
|
||||||
from django.db.models import F
|
|
||||||
from django.db.models.constraints import UniqueConstraint
|
|
||||||
from django.urls import reverse
|
|
||||||
from django.utils import timezone
|
|
||||||
from django.utils.text import slugify
|
|
||||||
|
|
||||||
from documents import create_pad
|
|
||||||
from documents.api import get_pad_link
|
|
||||||
from fet2020.utils import create_random_id
|
|
||||||
|
|
||||||
from .managers import TaskManager
|
|
||||||
|
|
||||||
|
|
||||||
class TaskList(models.Model):
|
|
||||||
name = models.CharField(max_length=128)
|
|
||||||
|
|
||||||
shortterm = models.CharField(max_length=128, unique=True, blank=True)
|
|
||||||
slug = models.SlugField(unique=True, blank=True)
|
|
||||||
|
|
||||||
users = models.ManyToManyField(User, blank=True)
|
|
||||||
|
|
||||||
objects = models.Manager()
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = "Aufgabenbereich"
|
|
||||||
verbose_name_plural = "Aufgabenbereiche"
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
def get_absolute_url(self):
|
|
||||||
return reverse("tasks:index")
|
|
||||||
|
|
||||||
def clean(self):
|
|
||||||
if not self.shortterm:
|
|
||||||
self.shortterm = slugify(self.name)
|
|
||||||
self.slug = slugify(self.shortterm)
|
|
||||||
|
|
||||||
|
|
||||||
class Task(models.Model):
|
|
||||||
title = models.CharField(verbose_name="Titel", max_length=128)
|
|
||||||
|
|
||||||
slug_id = models.CharField(
|
|
||||||
default=create_random_id, max_length=8, unique=True, editable=False
|
|
||||||
)
|
|
||||||
slug = models.SlugField(unique=True, blank=True)
|
|
||||||
|
|
||||||
task_list = models.ForeignKey(
|
|
||||||
TaskList, verbose_name="Aufgabenbereich", on_delete=models.CASCADE, null=True
|
|
||||||
)
|
|
||||||
|
|
||||||
created_date = models.DateTimeField(auto_now_add=True)
|
|
||||||
due_date = models.DateField(verbose_name="Fälligkeit", blank=True, null=True)
|
|
||||||
|
|
||||||
completed = models.BooleanField(verbose_name="Abgeschlossen", default=False)
|
|
||||||
completed_date = models.DateField(blank=True, null=True)
|
|
||||||
|
|
||||||
created_by = models.ForeignKey(
|
|
||||||
User,
|
|
||||||
related_name="created_by",
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
)
|
|
||||||
assigned_to = models.ForeignKey(
|
|
||||||
User,
|
|
||||||
blank=True,
|
|
||||||
null=True,
|
|
||||||
related_name="assigned_to",
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
verbose_name="Zugewiesen an",
|
|
||||||
)
|
|
||||||
|
|
||||||
note = models.TextField(verbose_name="Notizen", blank=True, null=True)
|
|
||||||
priority = models.PositiveIntegerField(
|
|
||||||
verbose_name="Priorität", blank=True, null=True
|
|
||||||
)
|
|
||||||
|
|
||||||
objects = models.Manager()
|
|
||||||
taskmanager = TaskManager()
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
ordering = ("task_list", F("due_date").desc(nulls_first=True))
|
|
||||||
verbose_name = "Aufgabe"
|
|
||||||
verbose_name_plural = "Aufgaben"
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.title
|
|
||||||
|
|
||||||
def get_absolute_url(self):
|
|
||||||
return reverse("tasks:task", kwargs={"slug": self.slug})
|
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
|
||||||
if not self.slug:
|
|
||||||
self.slug = self.slug_id + "-" + slugify(self.title)
|
|
||||||
|
|
||||||
if self.completed and not self.completed_date:
|
|
||||||
self.completed_date = timezone.now().date()
|
|
||||||
|
|
||||||
if not self.completed and self.completed_date:
|
|
||||||
self.completed_date = None
|
|
||||||
|
|
||||||
super().save(*args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class Document(models.Model):
|
|
||||||
title = models.CharField(verbose_name="Titel", max_length=128)
|
|
||||||
|
|
||||||
slug_id = models.CharField(
|
|
||||||
default=create_random_id, max_length=8, unique=True, editable=False
|
|
||||||
)
|
|
||||||
etherpad_key = models.CharField(max_length=50, blank=True)
|
|
||||||
|
|
||||||
date = models.DateField(verbose_name="Datum", default=date.today)
|
|
||||||
|
|
||||||
task = models.ForeignKey(Task, on_delete=models.CASCADE)
|
|
||||||
|
|
||||||
objects = models.Manager()
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = "Dokument"
|
|
||||||
verbose_name_plural = "Dokumente"
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.title
|
|
||||||
|
|
||||||
def get_absolute_url(self):
|
|
||||||
return get_pad_link(self.etherpad_key)
|
|
||||||
|
|
||||||
def clean(self):
|
|
||||||
pad_name = slugify(str(self.slug_id) + "-" + self.title[:40])
|
|
||||||
if len(pad_name) > 50:
|
|
||||||
raise ValidationError(
|
|
||||||
f"Name zum Erstellen des Etherpads ist zu lange - max. 50 Zeichen. (Länge: {len(pad_name)}, Name: {pad_name})"
|
|
||||||
)
|
|
||||||
|
|
||||||
self.etherpad_key = create_pad(pad_name)
|
|
||||||
if not self.etherpad_key:
|
|
||||||
raise ValidationError(
|
|
||||||
f"Etherpad '{pad_name}' konnte nicht erstellt werden."
|
|
||||||
)
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
from django.urls import path
|
|
||||||
|
|
||||||
from . import apps, views
|
|
||||||
from .views import DocumentCreateView, TaskCreateView, TaskDetailView, TaskUpdateView
|
|
||||||
|
|
||||||
app_name = apps.TasksConfig.name
|
|
||||||
|
|
||||||
urlpatterns = [
|
|
||||||
path("", views.index, name="index"),
|
|
||||||
path("create-task/", TaskCreateView.as_view(), name="task_create"),
|
|
||||||
path("<slug:slug>/", TaskDetailView.as_view(), name="task"),
|
|
||||||
path("<slug:slug>/update/", TaskUpdateView.as_view(), name="task_update"),
|
|
||||||
path(
|
|
||||||
"<slug:slug>/create-document/", DocumentCreateView.as_view(), name="docu_create"
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
import logging
|
|
||||||
from collections import deque
|
|
||||||
|
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
|
||||||
from django.contrib.auth.models import User
|
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
|
||||||
from django.shortcuts import render
|
|
||||||
from django.urls import reverse, reverse_lazy
|
|
||||||
from django.utils import timezone
|
|
||||||
from django.views.generic.detail import DetailView
|
|
||||||
from django.views.generic.edit import CreateView, UpdateView
|
|
||||||
|
|
||||||
from authentications.decorators import authenticated_user
|
|
||||||
from documents.api import get_pad_link
|
|
||||||
from documents.etherpadlib import add_ep_cookie
|
|
||||||
from fet2020.utils import add_log_action
|
|
||||||
from intern.models import Topic
|
|
||||||
|
|
||||||
from .forms import DocumentCreateForm, TaskCreateForm, TaskUpdateForm
|
|
||||||
from .models import Document, Task, TaskList
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
@authenticated_user
|
|
||||||
def index(request):
|
|
||||||
tasklist = None
|
|
||||||
show_tasklist = None
|
|
||||||
assigned_tasks = None
|
|
||||||
completed = False
|
|
||||||
state_open = False
|
|
||||||
state_closed = False
|
|
||||||
|
|
||||||
if request.method == "POST":
|
|
||||||
if "btn_checkbox" in request.POST:
|
|
||||||
for task_id in request.POST.getlist("checkbox"):
|
|
||||||
task = Task.objects.get(id=task_id)
|
|
||||||
|
|
||||||
if not task.completed:
|
|
||||||
task.completed = True
|
|
||||||
task.completed_date = timezone.now().date()
|
|
||||||
task.save()
|
|
||||||
|
|
||||||
if request.method == "GET":
|
|
||||||
if request.GET.get("tasklist"):
|
|
||||||
if request.GET.get("tasklist") != "all":
|
|
||||||
tasklist = TaskList.objects.filter(id=request.GET["tasklist"]).first()
|
|
||||||
show_tasklist = tasklist.id
|
|
||||||
|
|
||||||
if request.GET.get("tasks") == "assigned":
|
|
||||||
assigned_tasks = True
|
|
||||||
|
|
||||||
if request.GET.get("open_tasks"):
|
|
||||||
completed = False
|
|
||||||
state_open = True
|
|
||||||
|
|
||||||
if request.GET.get("closed_tasks"):
|
|
||||||
completed = True
|
|
||||||
state_closed = True
|
|
||||||
|
|
||||||
tasks = Task.taskmanager.get_tasks(
|
|
||||||
user=request.user.id,
|
|
||||||
assigned_tasks=assigned_tasks,
|
|
||||||
task_list=tasklist,
|
|
||||||
completed=completed,
|
|
||||||
)
|
|
||||||
|
|
||||||
context = {
|
|
||||||
"tasks": tasks,
|
|
||||||
"show_tasklist": show_tasklist,
|
|
||||||
"assigned_tasks": assigned_tasks,
|
|
||||||
"state_open": state_open,
|
|
||||||
"state_closed": state_closed,
|
|
||||||
}
|
|
||||||
|
|
||||||
return render(request, "tasks/index.html", context)
|
|
||||||
|
|
||||||
|
|
||||||
class TaskCreateView(LoginRequiredMixin, CreateView):
|
|
||||||
model = Task
|
|
||||||
success_url = reverse_lazy("tasks:index")
|
|
||||||
template_name = "tasks/task_create.html"
|
|
||||||
form_class = TaskCreateForm
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
|
||||||
form.instance.created_by = self.request.user
|
|
||||||
add_log_action(self.request, form, "tasks", "task", True)
|
|
||||||
return super().form_valid(form)
|
|
||||||
|
|
||||||
def get_form_kwargs(self):
|
|
||||||
kwargs = super().get_form_kwargs()
|
|
||||||
kwargs["user"] = self.request.user
|
|
||||||
return kwargs
|
|
||||||
|
|
||||||
|
|
||||||
class TaskUpdateView(LoginRequiredMixin, UpdateView):
|
|
||||||
form_class = TaskUpdateForm
|
|
||||||
model = Task
|
|
||||||
template_name = "tasks/task_update.html"
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
|
||||||
add_log_action(self.request, form, "tasks", "task", False)
|
|
||||||
return super().form_valid(form)
|
|
||||||
|
|
||||||
|
|
||||||
class TaskDetailView(LoginRequiredMixin, DetailView):
|
|
||||||
model = Task
|
|
||||||
template_name = "tasks/task_detail.html"
|
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
|
||||||
response = super().get(request, *args, **kwargs)
|
|
||||||
|
|
||||||
try:
|
|
||||||
response = add_ep_cookie(self.request, response)
|
|
||||||
except Exception as e:
|
|
||||||
logger.info("Etherpad Server doesn't work. Error: %s", e)
|
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super().get_context_data(**kwargs)
|
|
||||||
|
|
||||||
docus = Document.objects.filter(task__id=self.object.id).order_by("-date")
|
|
||||||
context["documents"] = docus
|
|
||||||
try:
|
|
||||||
context["topic"] = Topic.objects.get(task_list=self.object.task_list)
|
|
||||||
except ObjectDoesNotExist:
|
|
||||||
context["topic"] = None
|
|
||||||
return context
|
|
||||||
|
|
||||||
|
|
||||||
class DocumentCreateView(LoginRequiredMixin, CreateView):
|
|
||||||
model = Document
|
|
||||||
template_name = "tasks/attachment_create.html"
|
|
||||||
form_class = DocumentCreateForm
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
|
||||||
form.instance.created_by = self.request.user
|
|
||||||
add_log_action(self.request, form, "tasks", "document", True)
|
|
||||||
return super().form_valid(form)
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super().get_context_data(**kwargs)
|
|
||||||
slug = self.kwargs.get("slug")
|
|
||||||
context["task"] = Task.objects.get(slug=slug)
|
|
||||||
return context
|
|
||||||
|
|
||||||
def get_success_url(self):
|
|
||||||
return reverse("tasks:task", kwargs=self.kwargs)
|
|
||||||
@@ -161,7 +161,6 @@
|
|||||||
x-transition:leave-end="transform origin-top opacity-0 scale-95"
|
x-transition:leave-end="transform origin-top opacity-0 scale-95"
|
||||||
>
|
>
|
||||||
<li class="navInternal"><a href="{% url 'admin:index' %}"><i class="fa-fw fa-solid fa-user-secret mr-2"></i>Admin</a></li>
|
<li class="navInternal"><a href="{% url 'admin:index' %}"><i class="fa-fw fa-solid fa-user-secret mr-2"></i>Admin</a></li>
|
||||||
<li class="navInternal"><a href="{% url 'tasks:index' %}"><i class="fa-fw fa-solid fa-list-check mr-2"></i>Tasks</a></li>
|
|
||||||
<li class="navInternal"><a href="{% url 'intern:index' %}"><i class="fa-fw fa-solid fa-database mr-2"></i>Intern</a></li>
|
<li class="navInternal"><a href="{% url 'intern:index' %}"><i class="fa-fw fa-solid fa-database mr-2"></i>Intern</a></li>
|
||||||
<li class="navInternal"><a href="https://wiki.fet.at"><i class="fa-fw fa-brands fa-wikipedia-w mr-2"></i></i>Wiki</a></li>
|
<li class="navInternal"><a href="https://wiki.fet.at"><i class="fa-fw fa-brands fa-wikipedia-w mr-2"></i></i>Wiki</a></li>
|
||||||
<li class="navInternal"><a href="https://mail.fet.at"><i class="fa-fw fa-solid fa-inbox mr-2"></i></i>Mail</a></li>
|
<li class="navInternal"><a href="https://mail.fet.at"><i class="fa-fw fa-solid fa-inbox mr-2"></i></i>Mail</a></li>
|
||||||
|
|||||||
@@ -19,17 +19,6 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<!-- TODO: tasks -->
|
|
||||||
{% if tasks %}
|
|
||||||
<ul class="flex flex-col gap-1 max-w-fit">
|
|
||||||
{% for task in tasks %}
|
|
||||||
<li>
|
|
||||||
<span class="ml-2">{{ task.title|truncatechars:45 }} <a href="{% url 'tasks:task' task.slug %}" class="inline-block text-proprietary dark:text-proprietary-lighter">Link <i class="fa-solid fa-link"></i></a></span>
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<ul class="flex flex-col gap-1 max-w-fit">
|
<ul class="flex flex-col gap-1 max-w-fit">
|
||||||
{% for attachment in attachments %}
|
{% for attachment in attachments %}
|
||||||
<li><a href="{% url 'intern:attachment' topic.topic_group.slug topic.slug attachment.slug %}" class="py-1 inline-block">{{ attachment.title }}</a></li>
|
<li><a href="{% url 'intern:attachment' topic.topic_group.slug topic.slug attachment.slug %}" class="py-1 inline-block">{{ attachment.title }}</a></li>
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
{% extends 'base.html' %}
|
|
||||||
|
|
||||||
{% block title %}Etherpad hinzufügen{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<!-- Main Content -->
|
|
||||||
<main class="container mx-auto w-full px-4 my-8 flex-1">
|
|
||||||
<h1 class="page-title">Etherpad hinzufügen</h1>
|
|
||||||
<div class="w-full h-full flex-1 flex justify-center items-center">
|
|
||||||
<form action="" method="POST" class="w-full max-w-prose sm:px-28 sm:py-4 grid grid-cols-1 gap-y-3 sm:gap-y-6 text-gray-900">
|
|
||||||
{% csrf_token %}
|
|
||||||
|
|
||||||
{% if form.non_field_errors %}
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<i class="alert-icon fa-solid fa-check-circle"></i>
|
|
||||||
<h2 class="alert-title">Fehler:</h2>
|
|
||||||
<div class="alert-body">{{ form.non_field_errors }}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<label class="block">
|
|
||||||
<span class="text-gray-700 dark:text-gray-200">{{ form.title.label }}</span>
|
|
||||||
{% if form.title.errors %}
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<div class="alert-body">{{ form.title.errors }}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<input type="text" id="id_title" name="title" class="mt-1 block w-full rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50" required>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label>
|
|
||||||
<span class="text-gray-700 dark:text-gray-200">{{ form.date.label }}</span>
|
|
||||||
{% if form.date.errors %}
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<div class="alert-body">{{ form.date.errors }}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<input type="date" id="id_date" name="date" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<input type="hidden" name="task" value="{{ task.id }}" id="id_task">
|
|
||||||
|
|
||||||
<input type="submit" class="block btn btn-primary" value="Hinzufügen">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
{% extends 'base.html' %}
|
|
||||||
|
|
||||||
{% block title %}Tasks{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<!-- Main Content -->
|
|
||||||
<main x-data="modal" class="container mx-auto w-full px-4 my-8 flex-1">
|
|
||||||
<h1 class="page-title">Tasks</h1>
|
|
||||||
<div class="sm:flex sm:flex-row-reverse justify-center">
|
|
||||||
<aside class="sm:w-2/5 sm:max-w-xs sm:pl-4 lg:pl-8 my-8 sm:my-0">
|
|
||||||
<div class="z-10 fixed sm:sticky top-0 sm:top-4 lg:top-8 left-0 w-full h-full sm:h-auto bg-black sm:bg-transparent bg-opacity-70 flex sm:block items-center justify-center"
|
|
||||||
x-show="getShowModal"
|
|
||||||
x-transition:enter="transition duration-300 ease-out"
|
|
||||||
x-transition:enter-start="opacity-0"
|
|
||||||
x-transition:enter-end="opacity-100"
|
|
||||||
x-transition:leave="transition duration-150 ease-in"
|
|
||||||
x-transition:leave-start="opacity-100"
|
|
||||||
x-transition:leave-end="opacity-0"
|
|
||||||
>
|
|
||||||
<div class="max-w-sm sm:w-full mx-4 sm:mx-0 p-4 rounded bg-white dark:bg-gray-800 sm:shadow-lg sm:dark:border-2 sm:dark:border-gray-700"
|
|
||||||
@click.outside="toggle"
|
|
||||||
x-show="getShowModal"
|
|
||||||
x-transition:enter="transition transform ease-out duration-300"
|
|
||||||
x-transition:enter-start="scale-110 opacity-0"
|
|
||||||
x-transition:enter-end="scale-100 opacity-100"
|
|
||||||
x-transition:leave="transition transform ease-in duration-150"
|
|
||||||
x-transition:leave-start="scale-100 opacity-100"
|
|
||||||
x-transition:leave-end="scale-110 opacity-0"
|
|
||||||
>
|
|
||||||
<div class="flex justify-between items-center mb-2">
|
|
||||||
<h2 class="text-gray-800 dark:text-gray-100 sm:section-title sm:section-title-margins sm:w-full">
|
|
||||||
<span class="mr-1 text-gray-400 sm:hidden">
|
|
||||||
<i class="fa-solid fa-filter"></i>
|
|
||||||
</span>
|
|
||||||
Auswahl einschränken
|
|
||||||
</h2>
|
|
||||||
<div class="ml-4 -mr-2 px-2 rounded text-xl text-gray-600 dark:text-gray-400 sm:hidden cursor-pointer" @click="closeModal">
|
|
||||||
<i class="fa-solid fa-xmark"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<form action="" method="post" class="grid grid-cols-1 gap-2 sm:gap-4">
|
|
||||||
{% csrf_token %}
|
|
||||||
<label class="block">
|
|
||||||
<span class="text-gray-700 dark:text-gray-200">Task-Gruppe</span>
|
|
||||||
<select id="id_tasklist" name="tasklist" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
|
|
||||||
<option value="all" {% if not show_tasklist %}selected{% endif %}>alle Task-Gruppen</option>
|
|
||||||
{% regroup tasks by task_list as section_list %}
|
|
||||||
{% for group in section_list %}
|
|
||||||
<option value="{{ group.grouper.id }}" {% if show_tasklist == group.grouper.id %}selected{% endif %}>{{ group.grouper.name }}</option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<span class="text-gray-700 dark:text-gray-200">Tasks</span>
|
|
||||||
<select id="id_task" name="tasks" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
|
|
||||||
<option value="assigned" {% if assigned_tasks %}selected{% endif %}>dir zugewiesene</option>
|
|
||||||
<option value="all" {% if not assigned_tasks %}selected{% endif %}>alle</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
<label class="inline-flex items-center">
|
|
||||||
<input type="checkbox" name="open_tasks" {% if state_open %}checked{% endif %} class="rounded border-gray-300 dark:border-none text-proprietary shadow-sm focus:border-blue-300 focus:ring focus:ring-offset-0 focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
|
|
||||||
<span class="ml-2 text-gray-700 dark:text-gray-200">Offene Tasks</span>
|
|
||||||
</label>
|
|
||||||
<label class="inline-flex items-center">
|
|
||||||
<input type="checkbox" name="closed_tasks" {% if state_closed %}checked{% endif %} class="rounded border-gray-300 dark:border-none text-proprietary shadow-sm focus:border-blue-300 focus:ring focus:ring-offset-0 focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
|
|
||||||
<span class="ml-2 text-gray-700 dark:text-gray-200">Geschlossene Tasks</span>
|
|
||||||
</label>
|
|
||||||
<input type="submit" class="block btn btn-primary" value="Anzeigen">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button id="modal-trigger-1" class="z-10 trigger fixed bottom-4 right-4 bg-proprietary-darker dark:bg-sky-500 text-blue-50 dark:text-sky-900 shadow-lg text-2xl rounded sm:hidden"
|
|
||||||
@click="openModal"
|
|
||||||
x-show="getNotShowModal"
|
|
||||||
x-transition:enter="transition duration-100 ease-in"
|
|
||||||
x-transition:enter-start="opacity-0"
|
|
||||||
x-transition:enter-end="opacity-100"
|
|
||||||
x-transition:leave="transition duration-100 ease-out"
|
|
||||||
x-transition:leave-start="opacity-100"
|
|
||||||
x-transition:leave-end="opacity-0"
|
|
||||||
>
|
|
||||||
<i class="fa-solid fa-filter p-2"></i>
|
|
||||||
</button>
|
|
||||||
</aside>
|
|
||||||
|
|
||||||
{% if tasks %}
|
|
||||||
<form action="" method="post" class="my-8 sm:my-0 sm:w-3/5 xl:w-2/5 flex flex-col gap-2 text-gray-600 dark:text-gray-300">
|
|
||||||
{% csrf_token %}
|
|
||||||
|
|
||||||
{% regroup tasks by task_list as section_list %}
|
|
||||||
{% for group in section_list %}
|
|
||||||
<section>
|
|
||||||
<h2 class="mb-1 text-gray-700 dark:text-gray-200">{{ group.grouper }}</h2>
|
|
||||||
|
|
||||||
{% for task in group.list %}
|
|
||||||
<label class="mb-2 flex justify-between items-start">
|
|
||||||
<div class="inline-flex items-baseline mr-2">
|
|
||||||
<input type="checkbox" name="checkbox" value="{{ task.id }}" {% if task.completed %}checked{% endif %} class="rounded border-gray-300 dark:border-none text-proprietary shadow-sm focus:border-blue-300 focus:ring focus:ring-offset-0 focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
|
|
||||||
<span class="ml-2">{{ task.title|truncatechars:45 }} <a href="{% url 'tasks:task' task.slug %}" class="inline-block text-proprietary dark:text-proprietary-lighter">Link <i class="fa-solid fa-link"></i></a></span>
|
|
||||||
</div>
|
|
||||||
{% if task.due_date %}
|
|
||||||
<div class="inline-flex gap-2 flex-shrink-0">
|
|
||||||
<span class="px-2 py-0.5 rounded-full text-sm font-medium text-proprietary dark:text-blue-100 bg-blue-200 dark:bg-proprietary-dark"><i class="fa-solid fa-hourglass mr-1"></i>{{ task.due_date|date:"d.m.Y" }}</span>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</label>
|
|
||||||
{% endfor %}
|
|
||||||
</section>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
<div class="flex flex-col md:flex-row gap-y-2 md:gap-y-0 md:gap-x-2 lg:justify-end mt-4">
|
|
||||||
<input type="submit" name="btn_checkbox" value="Tasks abschließen" class="btn btn-success block md:flex-grow lg:flex-grow-0">
|
|
||||||
|
|
||||||
<a href="{% url 'tasks:task_create' %}" class="btn btn-primary block md:flex-grow lg:flex-grow-0"><i class="fa-solid fa-plus-square mr-2"></i>Task hinzufügen</a>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
{% else %}
|
|
||||||
<section>
|
|
||||||
<h2 class="mb-1 text-gray-700 dark:text-gray-200">Keine Tasks in dieser Liste für dich.</h2>
|
|
||||||
|
|
||||||
<div class="flex flex-col md:flex-row gap-y-2 md:gap-y-0 md:gap-x-2 lg:justify-end mt-4">
|
|
||||||
<a href="{% url 'tasks:task_create' %}" class="btn btn-primary block md:flex-grow lg:flex-grow-0"><i class="fa-solid fa-plus-square mr-2"></i>Task hinzufügen</a>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
{% extends 'base.html' %}
|
|
||||||
|
|
||||||
{% block title %}Task hinzufügen{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<!-- Main Content -->
|
|
||||||
<main class="container mx-auto w-full px-4 my-8 flex-1">
|
|
||||||
<h1 class="page-title">Task hinzufügen</h1>
|
|
||||||
<div class="w-full h-full flex-1 flex justify-center items-center">
|
|
||||||
<form action="" method="POST" class="w-full max-w-xs sm:max-w-prose sm:px-28 sm:py-4 grid grid-cols-1 gap-y-3 sm:gap-y-6 text-gray-900">
|
|
||||||
{% csrf_token %}
|
|
||||||
|
|
||||||
{% if form.non_field_errors %}
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<i class="alert-icon fa-solid fa-check-circle"></i>
|
|
||||||
<h2 class="alert-title">Fehler:</h2>
|
|
||||||
<div class="alert-body">{{ form.non_field_errors }}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<label class="block">
|
|
||||||
<span class="text-gray-700 dark:text-gray-200">{{ form.title.label }}</span>
|
|
||||||
{% if form.title.errors %}
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<div class="alert-body">{{ form.title.errors }}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<input type="text" id="id_title" name="title" class="mt-1 block w-full rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50" required>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label>
|
|
||||||
<span class="text-gray-700 dark:text-gray-200">{{ form.task_list.label }}</span>
|
|
||||||
{% if form.task_list.errors %}
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<div class="alert-body">{{ form.task_list.errors }}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<select id="id_task_list" name="task_list" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50" required>
|
|
||||||
{% for elem in form.task_list %}
|
|
||||||
{% if forloop.first %}
|
|
||||||
<option value="">---------</option>
|
|
||||||
{% else %}
|
|
||||||
{{ elem }}
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label>
|
|
||||||
<span class="text-gray-700 dark:text-gray-200">{{ form.due_date.label }}</span>
|
|
||||||
{% if form.due_date.errors %}
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<div class="alert-body">{{ form.due_date.errors }}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<input type="date" id="id_due_date" name="due_date" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label>
|
|
||||||
<span class="text-gray-700 dark:text-gray-200">{{ form.assigned_to.label }}</span>
|
|
||||||
{% if form.assigned_to.errors %}
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<div class="alert-body">{{ form.assigned_to.errors }}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<select id="id_assigned_to" name="assigned_to" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
|
|
||||||
{% for elem in form.assigned_to %}
|
|
||||||
{% if forloop.first %}
|
|
||||||
<option value="">Alle</option>
|
|
||||||
{% else %}
|
|
||||||
{{ elem }}
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<div class="flex flex-col-reverse sm:flex-row gap-3 justify-end pt-4 sm:pt-0">
|
|
||||||
<a href="{% url 'admin:tasks_tasklist_add' %}" class="block btn btn-secondary-proprietary">Task-Gruppe hinzufügen</a>
|
|
||||||
<input type="submit" class="block btn btn-primary" value="Hinzufügen">
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
{% extends 'base.html' %}
|
|
||||||
|
|
||||||
{% block title %}{{ task.title }}{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<!-- Main Content -->
|
|
||||||
<main class="container mx-auto w-full px-4 my-8 flex-1">
|
|
||||||
<h1 class="page-title">Task-Detailansicht</h1>
|
|
||||||
<div class="flex flex-col gap-y-4 sm:gap-y-4 max-w-prose mx-auto text-gray-700 dark:text-gray-300">
|
|
||||||
<aside class="flex gap-2 flex-wrap align-bottom text-sm sm:text-base text-gray-600 dark:text-gray-300">
|
|
||||||
<a class="underline hover:text-gray-900 dark:hover:text-gray-100" href="{% url 'tasks:index' %}">{{ task.task_list.name }}</a>
|
|
||||||
<span><i class="fa-solid fa-angle-right"></i></span>
|
|
||||||
<span class="cursor-default">{{ task.title }}</span>
|
|
||||||
</aside>
|
|
||||||
{% if task.note %}
|
|
||||||
<div class="db-page-content-left">
|
|
||||||
{{ task.note|safe }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if task.due_date %}
|
|
||||||
<div class="text-right -mt-6">
|
|
||||||
{{ task.due_date }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<div class="documentList rounded divide-y divide-gray-300 dark:divide-gray-600">
|
|
||||||
<a href="{% url 'tasks:docu_create' task.slug %}" class="flex justify-between">
|
|
||||||
<h3 class="text-gray-800 dark:text-gray-200"><i class="fa-solid fa-plus fa-fw mr-1"></i>Neues Etherpad erstellen</h2>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{% for document in documents %}
|
|
||||||
<a href="{{ document.get_absolute_url }}" class="flex justify-between items-center gap-2">
|
|
||||||
<h3 class="text-gray-800 dark:text-gray-200">{{ document.title }}</h2>
|
|
||||||
<span class=" text-gray-700 dark:text-gray-300">{{ document.date }}<span class="ml-2 hidden sm:inline-block"><i class="fa-solid fa-angle-right text-gray-400 dark:text-gray-600"></i></span>
|
|
||||||
</a>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<a href="{% url 'tasks:task_update' task.slug %}" class="btn btn-primary block place-self-end"><i class="fa-solid fa-pen-to-square mr-2"></i>Task bearbeiten</a>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
{% extends 'base.html' %}
|
|
||||||
|
|
||||||
{% block title %}{{ task.title }} bearbeiten{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<!-- Main Content -->
|
|
||||||
<main class="container mx-auto w-full px-4 my-8 flex-1">
|
|
||||||
<h1 class="page-title">Task '{{ task.title }}' bearbeiten</h1>
|
|
||||||
<div class="w-full h-full flex-1 flex justify-center items-center">
|
|
||||||
<form action="" method="POST" class="w-full max-w-prose sm:px-28 sm:py-4 grid grid-cols-1 gap-y-3 sm:gap-y-6 text-gray-900">
|
|
||||||
{% csrf_token %}
|
|
||||||
|
|
||||||
{% if form.non_field_errors %}
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<i class="alert-icon fa-solid fa-check-circle"></i>
|
|
||||||
<h2 class="alert-title">Fehler:</h2>
|
|
||||||
<div class="alert-body">{{ form.non_field_errors }}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<label>
|
|
||||||
<span class="text-gray-700 dark:text-gray-200">{{ form.assigned_to.label }}</span>
|
|
||||||
{% if form.assigned_to.errors %}
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<div class="alert-body">{{ form.assigned_to.errors }}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<select id="id_assigned_to" name="assigned_to" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
|
|
||||||
{% for elem in form.assigned_to %}
|
|
||||||
{% if forloop.first %}
|
|
||||||
<option value="">Alle</option>
|
|
||||||
{% else %}
|
|
||||||
{{ elem }}
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label>
|
|
||||||
<span class="text-gray-700 dark:text-gray-200">{{ form.due_date.label }}</span>
|
|
||||||
{% if form.due_date.errors %}
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<div class="alert-body">{{ form.due_date.errors }}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<input type="date" id="id_due_date" name="due_date" value="{{ task.due_date|date:"Y-m-d" }}" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label>
|
|
||||||
<span class="text-gray-700 dark:text-gray-200">{{ form.completed_date.label }}</span>
|
|
||||||
{% if form.completed_date.errors %}
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<div class="alert-body">{{ form.completed_date.errors }}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<input type="date" id="id_completed_date" name="completed_date" value="{{ task.completed_date|date:"Y-m-d" }}" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label>
|
|
||||||
<input type="checkbox" id="id_completed" name="completed" value="{{ task.id }}" {% if task.completed %}checked{% endif %} class="rounded border-gray-300 dark:border-none text-proprietary shadow-sm focus:border-blue-300 focus:ring focus:ring-offset-0 focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
|
|
||||||
<span class="text-gray-700 dark:text-gray-200">{{ form.completed.label }}</span>
|
|
||||||
{% if form.completed.errors %}
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<div class="alert-body">{{ form.completed.errors }}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label class="block">
|
|
||||||
<span class="text-gray-700 dark:text-gray-200">{{ form.note.label }}</span>
|
|
||||||
{% if form.note.errors %}
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<div class="alert-body">{{ form.note.errors }}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{{ form.media }}
|
|
||||||
{{ form.note }}
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<input type="hidden" name="task_list" value="{{ task.task_list.id }}" id="id_task_list">
|
|
||||||
|
|
||||||
<div class="flex flex-col-reverse sm:flex-row gap-3 justify-end pt-4 sm:pt-0">
|
|
||||||
<a href="{% url 'admin:tasks_task_change' task.id %}" class="block btn btn-secondary-proprietary">Task im Admin bearbeiten</a>
|
|
||||||
<input type="submit" class="block btn btn-primary" value="Speichern">
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
{% endblock %}
|
|
||||||
Reference in New Issue
Block a user