add fileupload, create views, detail view of task
This commit is contained in:
@@ -2,7 +2,13 @@ from django.contrib import admin
|
|||||||
from django.db.models import F
|
from django.db.models import F
|
||||||
|
|
||||||
from .models import TopicGroup, Topic, Documentation, Document, FileUpload
|
from .models import TopicGroup, Topic, Documentation, Document, FileUpload
|
||||||
from .forms import TopicGroupAdminForm, TopicAdminForm, DocumentationAdminForm, DocumentAdminForm, FileUploadAdminForm
|
from .forms import (
|
||||||
|
TopicGroupAdminForm,
|
||||||
|
TopicAdminForm,
|
||||||
|
DocumentationAdminForm,
|
||||||
|
DocumentAdminForm,
|
||||||
|
FileUploadAdminForm,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DocumentationInline(admin.TabularInline):
|
class DocumentationInline(admin.TabularInline):
|
||||||
@@ -39,7 +45,7 @@ class TopicInline(admin.TabularInline):
|
|||||||
class TopicGroupAdmin(admin.ModelAdmin):
|
class TopicGroupAdmin(admin.ModelAdmin):
|
||||||
form = TopicGroupAdminForm
|
form = TopicGroupAdminForm
|
||||||
model = TopicGroup
|
model = TopicGroup
|
||||||
search_fields = ("title", )
|
search_fields = ("title",)
|
||||||
inlines = (TopicInline,)
|
inlines = (TopicInline,)
|
||||||
|
|
||||||
list_display = ["title", "order"]
|
list_display = ["title", "order"]
|
||||||
@@ -54,7 +60,7 @@ class TopicAdmin(admin.ModelAdmin):
|
|||||||
form = TopicAdminForm
|
form = TopicAdminForm
|
||||||
model = Topic
|
model = Topic
|
||||||
search_fields = ("title",)
|
search_fields = ("title",)
|
||||||
inlines = (DocumentationInline, )
|
inlines = (DocumentationInline,)
|
||||||
|
|
||||||
list_filter = ["topic_group", "archive"]
|
list_filter = ["topic_group", "archive"]
|
||||||
list_display = ["title", "topic_group", "archive"]
|
list_display = ["title", "topic_group", "archive"]
|
||||||
@@ -68,9 +74,15 @@ class TopicAdmin(admin.ModelAdmin):
|
|||||||
class DocumentationAdmin(admin.ModelAdmin):
|
class DocumentationAdmin(admin.ModelAdmin):
|
||||||
form = DocumentationAdminForm
|
form = DocumentationAdminForm
|
||||||
model = Documentation
|
model = Documentation
|
||||||
inlines = (DocumentInline, FileUploadInline, )
|
inlines = (
|
||||||
|
DocumentInline,
|
||||||
|
FileUploadInline,
|
||||||
|
)
|
||||||
|
|
||||||
list_display = ["title", "topic",]
|
list_display = [
|
||||||
|
"title",
|
||||||
|
"topic",
|
||||||
|
]
|
||||||
|
|
||||||
def save_model(self, request, obj, form, change):
|
def save_model(self, request, obj, form, change):
|
||||||
obj.created_by = request.user
|
obj.created_by = request.user
|
||||||
@@ -81,8 +93,14 @@ class DocumentAdmin(admin.ModelAdmin):
|
|||||||
form = DocumentAdminForm
|
form = DocumentAdminForm
|
||||||
model = Document
|
model = Document
|
||||||
|
|
||||||
list_filter = ["documentation",]
|
list_filter = [
|
||||||
list_display = ["title", "date", "documentation",]
|
"documentation",
|
||||||
|
]
|
||||||
|
list_display = [
|
||||||
|
"title",
|
||||||
|
"date",
|
||||||
|
"documentation",
|
||||||
|
]
|
||||||
ordering = ["-date"]
|
ordering = ["-date"]
|
||||||
|
|
||||||
def save_model(self, request, obj, form, change):
|
def save_model(self, request, obj, form, change):
|
||||||
@@ -94,8 +112,13 @@ class FileUploadAdmin(admin.ModelAdmin):
|
|||||||
form = FileUploadAdminForm
|
form = FileUploadAdminForm
|
||||||
model = FileUpload
|
model = FileUpload
|
||||||
|
|
||||||
list_filter = ["documentation",]
|
list_filter = [
|
||||||
list_display = ["title", "documentation",]
|
"documentation",
|
||||||
|
]
|
||||||
|
list_display = [
|
||||||
|
"title",
|
||||||
|
"documentation",
|
||||||
|
]
|
||||||
|
|
||||||
def save_model(self, request, obj, form, change):
|
def save_model(self, request, obj, form, change):
|
||||||
obj.created_by = request.user
|
obj.created_by = request.user
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class TopicAdminForm(forms.ModelForm):
|
|||||||
"archive",
|
"archive",
|
||||||
"description",
|
"description",
|
||||||
"topic_group",
|
"topic_group",
|
||||||
|
"task_list",
|
||||||
]
|
]
|
||||||
|
|
||||||
widgets = {"description": CKEditorUploadingWidget(config_name="default")}
|
widgets = {"description": CKEditorUploadingWidget(config_name="default")}
|
||||||
@@ -82,3 +83,13 @@ class DocumentForm(forms.ModelForm):
|
|||||||
widgets = {
|
widgets = {
|
||||||
"date": DateInput(format=("%d-%m-%Y")),
|
"date": DateInput(format=("%d-%m-%Y")),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class FileUploadForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = FileUpload
|
||||||
|
fields = [
|
||||||
|
"title",
|
||||||
|
"file_field",
|
||||||
|
"documentation",
|
||||||
|
]
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from django.utils.text import slugify
|
|||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from documents import createPadifNotExists
|
from documents import createPadifNotExists
|
||||||
|
from tasks.models import TaskList
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -18,7 +19,9 @@ class TopicGroup(models.Model):
|
|||||||
title = models.CharField(verbose_name="Titel", max_length=128)
|
title = models.CharField(verbose_name="Titel", max_length=128)
|
||||||
slug = models.SlugField(max_length=10, unique=True)
|
slug = models.SlugField(max_length=10, unique=True)
|
||||||
|
|
||||||
order = models.PositiveSmallIntegerField(verbose_name="Reihenfolge", unique=True, null=True, blank=True)
|
order = models.PositiveSmallIntegerField(
|
||||||
|
verbose_name="Reihenfolge", unique=True, null=True, blank=True
|
||||||
|
)
|
||||||
|
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
|
|
||||||
@@ -47,7 +50,12 @@ class Topic(models.Model):
|
|||||||
|
|
||||||
description = models.TextField(null=True, blank=True)
|
description = models.TextField(null=True, blank=True)
|
||||||
|
|
||||||
topic_group = models.ForeignKey(TopicGroup, on_delete=models.CASCADE, verbose_name="Themenbereich")
|
topic_group = models.ForeignKey(
|
||||||
|
TopicGroup, on_delete=models.CASCADE, verbose_name="Themenbereich"
|
||||||
|
)
|
||||||
|
task_list = models.ForeignKey(
|
||||||
|
TaskList, on_delete=models.CASCADE, null=True, blank=True
|
||||||
|
)
|
||||||
|
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
|
|
||||||
@@ -82,7 +90,9 @@ class Documentation(models.Model):
|
|||||||
return self.topic.title + " / " + self.title
|
return self.topic.title + " / " + self.title
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse("docu", kwargs={"topic_slug": self.topic.slug, "slug": self.slug})
|
return reverse(
|
||||||
|
"docu", kwargs={"topic_slug": self.topic.slug, "slug": self.slug}
|
||||||
|
)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
if not self.slug:
|
if not self.slug:
|
||||||
@@ -105,21 +115,39 @@ class Document(models.Model):
|
|||||||
verbose_name_plural = "Dokumente"
|
verbose_name_plural = "Dokumente"
|
||||||
|
|
||||||
constraints = [
|
constraints = [
|
||||||
UniqueConstraint(fields=['title', 'date', 'documentation'], name='unique_intern_document'),
|
UniqueConstraint(
|
||||||
|
fields=["title", "date", "documentation"], name="unique_intern_document"
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
pad_name = slugify(str(self.date) + "-" + self.documentation.topic.slug + "-" + self.documentation.slug + "-" + slugify(self.title))
|
pad_name = slugify(
|
||||||
|
str(self.date)
|
||||||
|
+ "-"
|
||||||
|
+ self.documentation.topic.slug
|
||||||
|
+ "-"
|
||||||
|
+ self.documentation.slug
|
||||||
|
+ "-"
|
||||||
|
+ slugify(self.title)
|
||||||
|
)
|
||||||
|
|
||||||
if len(pad_name) > 50:
|
if len(pad_name) > 50:
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
_('Name zum Erstellen des Etherpads ist zu lange - max. 50 Zeichen. (Länge: %(length)s, Name: %(pad_name)s)'),
|
_(
|
||||||
params={'length': len(pad_name), 'pad_name': pad_name},
|
"Name zum Erstellen des Etherpads ist zu lange - max. 50 Zeichen. (Länge: %(length)s, Name: %(pad_name)s)"
|
||||||
|
),
|
||||||
|
params={"length": len(pad_name), "pad_name": pad_name},
|
||||||
)
|
)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
self.etherpad_key = createPadifNotExists(
|
self.etherpad_key = createPadifNotExists(
|
||||||
slugify(self.date) + "-" + self.documentation.topic.slug + "-" + self.documentation.slug + "-" + slugify(self.title)
|
slugify(self.date)
|
||||||
|
+ "-"
|
||||||
|
+ self.documentation.topic.slug
|
||||||
|
+ "-"
|
||||||
|
+ self.documentation.slug
|
||||||
|
+ "-"
|
||||||
|
+ slugify(self.title)
|
||||||
)
|
)
|
||||||
|
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
@@ -130,7 +158,9 @@ class Document(models.Model):
|
|||||||
|
|
||||||
class FileUpload(models.Model):
|
class FileUpload(models.Model):
|
||||||
title = models.CharField(verbose_name="Titel", max_length=128)
|
title = models.CharField(verbose_name="Titel", max_length=128)
|
||||||
file_field = models.FileField(verbose_name="Dokument", upload_to="uploads/intern/files/")
|
file_field = models.FileField(
|
||||||
|
verbose_name="Dokument", upload_to="uploads/intern/files/"
|
||||||
|
)
|
||||||
date = models.DateField(verbose_name="Datum", default=date.today)
|
date = models.DateField(verbose_name="Datum", default=date.today)
|
||||||
|
|
||||||
documentation = models.ForeignKey(Documentation, on_delete=models.CASCADE)
|
documentation = models.ForeignKey(Documentation, on_delete=models.CASCADE)
|
||||||
|
|||||||
@@ -1,10 +1,21 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
from .views import EtherpadCreateView, FileUploadCreateView
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", views.index, name="intern"),
|
path("", views.index, name="intern"),
|
||||||
path("<slug:slug>/", views.show_topic, name="topic"),
|
path("<slug:slug>/", views.show_topic, name="topic"),
|
||||||
path("<slug:topic_slug>/<slug:slug>/", views.show_docu, name="docu"),
|
path("<slug:topic_slug>/<slug:slug>/", views.show_docu, name="docu"),
|
||||||
|
path(
|
||||||
|
"<slug:topic_slug>/<slug:slug>/etherpad-create/",
|
||||||
|
EtherpadCreateView.as_view(),
|
||||||
|
name="etherpad-create",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"<slug:topic_slug>/<slug:slug>/file-create/",
|
||||||
|
FileUploadCreateView.as_view(),
|
||||||
|
name="file-create",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,23 +1,31 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from collections import deque
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.db.models import F, Q
|
from django.db.models import F, Q
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect, Http404
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
from django.views.generic.edit import CreateView
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
from authentications.decorators import authenticated_user
|
||||||
from documents.api import get_pad_link
|
from documents.api import get_pad_link
|
||||||
from documents.etherpadlib import add_ep_cookie
|
from documents.etherpadlib import add_ep_cookie
|
||||||
from collections import deque
|
from tasks.models import Task
|
||||||
|
from .forms import DocumentForm, FileUploadForm
|
||||||
from .forms import DocumentForm
|
|
||||||
from .models import TopicGroup, Topic, Documentation, Document, FileUpload
|
from .models import TopicGroup, Topic, Documentation, Document, FileUpload
|
||||||
from authentications.decorators import authenticated_user
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@authenticated_user
|
@authenticated_user
|
||||||
def index(request):
|
def index(request):
|
||||||
topic = deque(Topic.objects.filter(archive=False).order_by(F('topic_group__order').asc(nulls_last=True), 'topic_group', 'title'))
|
topic = deque(
|
||||||
|
Topic.objects.filter(archive=False).order_by(
|
||||||
|
F("topic_group__order").asc(nulls_last=True), "topic_group", "title"
|
||||||
|
)
|
||||||
|
)
|
||||||
archive_topic = deque(Topic.objects.filter(archive=True))
|
archive_topic = deque(Topic.objects.filter(archive=True))
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
@@ -31,11 +39,26 @@ def index(request):
|
|||||||
@authenticated_user
|
@authenticated_user
|
||||||
def show_topic(request, slug=None):
|
def show_topic(request, slug=None):
|
||||||
active_topic = Topic.objects.filter(slug=slug).first()
|
active_topic = Topic.objects.filter(slug=slug).first()
|
||||||
docu = deque(Documentation.objects.filter(topic__slug=slug).order_by('title'))
|
if not active_topic:
|
||||||
|
raise Http404("wrong topic")
|
||||||
|
|
||||||
|
docu = deque(Documentation.objects.filter(topic__slug=slug).order_by("title"))
|
||||||
|
|
||||||
|
tasks = None
|
||||||
|
if active_topic.task_list:
|
||||||
|
tasks = deque(
|
||||||
|
Task.taskmanager.get_tasks(
|
||||||
|
user=request.user.id,
|
||||||
|
completed=False,
|
||||||
|
task_list=active_topic.task_list,
|
||||||
|
all_tasks=True,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
"active_topic": active_topic,
|
"active_topic": active_topic,
|
||||||
"docus": docu,
|
"docus": docu,
|
||||||
|
"tasks": tasks,
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, "intern/topic.html", context)
|
return render(request, "intern/topic.html", context)
|
||||||
@@ -43,34 +66,47 @@ def show_topic(request, slug=None):
|
|||||||
|
|
||||||
@authenticated_user
|
@authenticated_user
|
||||||
def show_docu(request, topic_slug=None, slug=None):
|
def show_docu(request, topic_slug=None, slug=None):
|
||||||
active_docu = Documentation.objects.filter(Q(topic__slug=topic_slug) & Q(slug=slug)).first()
|
active_docu = Documentation.objects.filter(
|
||||||
|
Q(topic__slug=topic_slug) & Q(slug=slug)
|
||||||
|
).first()
|
||||||
|
if not active_docu:
|
||||||
|
raise Http404("wrong docu")
|
||||||
|
|
||||||
active_topic = Topic.objects.filter(slug=topic_slug).first()
|
active_topic = Topic.objects.filter(slug=topic_slug).first()
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
if "btn_input" in request.POST:
|
if "btn_etherpad" in request.POST:
|
||||||
form = DocumentForm(request.POST)
|
form = DocumentForm(request.POST)
|
||||||
|
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
docu = form.save(commit=False)
|
form.save()
|
||||||
docu.created_by = request.user
|
|
||||||
# docu.documentation = active_docu
|
|
||||||
docu.save()
|
|
||||||
|
|
||||||
return HttpResponseRedirect(request.path)
|
return HttpResponseRedirect(request.path)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
for elem in list(form.errors.values()):
|
for elem in list(form.errors.values()):
|
||||||
messages.info(request, '; '.join(elem))
|
messages.info(request, "; ".join(elem))
|
||||||
|
|
||||||
|
if "btn_fileupload" in request.POST:
|
||||||
|
form = FileUploadForm(request.POST, request.FILES)
|
||||||
|
|
||||||
|
if form.is_valid():
|
||||||
|
form.save()
|
||||||
|
return HttpResponseRedirect(request.path)
|
||||||
|
|
||||||
|
else:
|
||||||
|
for elem in list(form.errors.values()):
|
||||||
|
messages.info(request, "; ".join(elem))
|
||||||
|
|
||||||
initial = {
|
initial = {
|
||||||
"documentation": active_docu,
|
"documentation": active_docu,
|
||||||
}
|
}
|
||||||
|
|
||||||
form = DocumentForm(initial=initial)
|
form_add_etherpad = DocumentForm(initial=initial)
|
||||||
|
form_add_file = FileUploadForm(initial=initial)
|
||||||
|
|
||||||
files = deque(FileUpload.objects.filter(documentation=active_docu))
|
files = deque(FileUpload.objects.filter(documentation=active_docu))
|
||||||
|
|
||||||
docus = deque(Document.objects.filter(documentation=active_docu).order_by('-date'))
|
docus = deque(Document.objects.filter(documentation=active_docu).order_by("-date"))
|
||||||
documents = deque([])
|
documents = deque([])
|
||||||
|
|
||||||
# list of etherpad url-link of any documents
|
# list of etherpad url-link of any documents
|
||||||
@@ -84,7 +120,8 @@ def show_docu(request, topic_slug=None, slug=None):
|
|||||||
)
|
)
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
"formset": form,
|
"form_add_etherpad": form_add_etherpad,
|
||||||
|
"form_add_file": form_add_file,
|
||||||
"active_topic": active_topic,
|
"active_topic": active_topic,
|
||||||
"active_docu": active_docu,
|
"active_docu": active_docu,
|
||||||
"documents": documents,
|
"documents": documents,
|
||||||
@@ -99,3 +136,72 @@ def show_docu(request, topic_slug=None, slug=None):
|
|||||||
logger.info("Etherpad Server doesn't work. Error: %s", e)
|
logger.info("Etherpad Server doesn't work. Error: %s", e)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
class EtherpadCreateView(LoginRequiredMixin, CreateView):
|
||||||
|
model = Document
|
||||||
|
template_name = "intern/etherpad_create.html"
|
||||||
|
form_class = DocumentForm
|
||||||
|
|
||||||
|
topic_slug = None
|
||||||
|
slug = None
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context["topic_slug"] = self.topic_slug
|
||||||
|
context["slug"] = self.slug
|
||||||
|
return context
|
||||||
|
|
||||||
|
def get_initial(self):
|
||||||
|
self.topic_slug = self.kwargs.get("topic_slug")
|
||||||
|
self.slug = self.kwargs.get("slug")
|
||||||
|
|
||||||
|
active_docu = Documentation.objects.filter(slug=self.kwargs.get("slug")).first()
|
||||||
|
context = {
|
||||||
|
"documentation": active_docu,
|
||||||
|
}
|
||||||
|
|
||||||
|
return context
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
context = {
|
||||||
|
"topic_slug": self.topic_slug,
|
||||||
|
"slug": self.slug,
|
||||||
|
}
|
||||||
|
|
||||||
|
return reverse("docu", kwargs=context)
|
||||||
|
|
||||||
|
|
||||||
|
class FileUploadCreateView(LoginRequiredMixin, CreateView):
|
||||||
|
model = FileUpload
|
||||||
|
template_name = "intern/file_create.html"
|
||||||
|
form_class = FileUploadForm
|
||||||
|
|
||||||
|
topic_slug = None
|
||||||
|
slug = None
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context["topic_slug"] = self.topic_slug
|
||||||
|
context["slug"] = self.slug
|
||||||
|
|
||||||
|
return context
|
||||||
|
|
||||||
|
def get_initial(self):
|
||||||
|
self.topic_slug = self.kwargs.get("topic_slug")
|
||||||
|
self.slug = self.kwargs.get("slug")
|
||||||
|
|
||||||
|
active_docu = Documentation.objects.filter(slug=self.kwargs.get("slug")).first()
|
||||||
|
context = {
|
||||||
|
"documentation": active_docu,
|
||||||
|
}
|
||||||
|
|
||||||
|
return context
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
context = {
|
||||||
|
"topic_slug": self.topic_slug,
|
||||||
|
"slug": self.slug,
|
||||||
|
}
|
||||||
|
|
||||||
|
return reverse("docu", kwargs=context)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from django.contrib.admin.widgets import FilteredSelectMultiple
|
|||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from .models import Task, TaskList
|
from .models import Task, TaskList, Document
|
||||||
|
|
||||||
|
|
||||||
class DateInput(forms.DateInput):
|
class DateInput(forms.DateInput):
|
||||||
@@ -77,3 +77,23 @@ class TaskListForm(forms.ModelForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = TaskList
|
model = TaskList
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
|
|
||||||
|
|
||||||
|
class DocumentForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Document
|
||||||
|
|
||||||
|
fields = [
|
||||||
|
"title",
|
||||||
|
"date",
|
||||||
|
"task",
|
||||||
|
]
|
||||||
|
|
||||||
|
labels = {
|
||||||
|
"title": _("Titel"),
|
||||||
|
"date": _("Datum"),
|
||||||
|
}
|
||||||
|
|
||||||
|
widgets = {
|
||||||
|
"date": DateInput(format=("%d-%m-%Y")),
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,15 @@
|
|||||||
|
from datetime import date
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.core.validators import ValidationError
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
from django.db.models.constraints import UniqueConstraint
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.utils.text import slugify
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from documents import createPadifNotExists
|
||||||
|
|
||||||
|
|
||||||
class TaskQuerySet(models.QuerySet):
|
class TaskQuerySet(models.QuerySet):
|
||||||
@@ -100,3 +107,50 @@ class Task(models.Model):
|
|||||||
self.completed_date = None
|
self.completed_date = None
|
||||||
|
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class Document(models.Model):
|
||||||
|
title = models.CharField(verbose_name="Titel", max_length=128)
|
||||||
|
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"
|
||||||
|
|
||||||
|
constraints = [
|
||||||
|
UniqueConstraint(
|
||||||
|
fields=["title", "date", "task"], name="unique_task_document"
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
pad_name = slugify(
|
||||||
|
str(self.date) + "-" + self.task.title + "-" + slugify(self.title)
|
||||||
|
)
|
||||||
|
|
||||||
|
print("clean")
|
||||||
|
|
||||||
|
if len(pad_name) > 50:
|
||||||
|
raise ValidationError(
|
||||||
|
_(
|
||||||
|
"Name zum Erstellen des Etherpads ist zu lange - max. 50 Zeichen. (Länge: %(length)s, Name: %(pad_name)s)"
|
||||||
|
),
|
||||||
|
params={"length": len(pad_name), "pad_name": pad_name},
|
||||||
|
)
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
self.etherpad_key = createPadifNotExists(
|
||||||
|
slugify(str(self.date) + "-" + self.task.title + "-" + slugify(self.title))
|
||||||
|
)
|
||||||
|
|
||||||
|
print("save")
|
||||||
|
|
||||||
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.title
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
from .views import TaskCreate, TaskDetail, TaskUpdate, DocumentCreate
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", views.index, name="tasks"),
|
path("", views.index, name="tasks"),
|
||||||
|
path("task-create/", TaskCreate.as_view(), name="task-create"),
|
||||||
|
path("<int:pk>/docu-create/", DocumentCreate.as_view(), name="docu-create"),
|
||||||
|
path("<int:pk>/detail/", TaskDetail.as_view(), name="task-detail"),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,45 +1,33 @@
|
|||||||
from django.contrib import messages
|
import logging
|
||||||
from django.contrib.auth.models import User
|
|
||||||
from django.shortcuts import render
|
|
||||||
from django.utils import timezone
|
|
||||||
|
|
||||||
from collections import deque
|
from collections import deque
|
||||||
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.shortcuts import render
|
||||||
|
from django.views.generic.detail import DetailView
|
||||||
|
from django.views.generic.edit import CreateView, UpdateView
|
||||||
|
from django.urls import reverse_lazy, reverse
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
from .forms import TaskForm
|
|
||||||
from .models import Task, TaskList
|
|
||||||
from authentications.decorators import authenticated_user
|
from authentications.decorators import authenticated_user
|
||||||
|
from documents.api import get_pad_link
|
||||||
|
from documents.etherpadlib import add_ep_cookie
|
||||||
|
|
||||||
|
from .forms import TaskForm, DocumentForm
|
||||||
|
from .models import Task, TaskList, Document
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@authenticated_user
|
@authenticated_user
|
||||||
def index(request):
|
def index(request):
|
||||||
current_user = request.user.id
|
|
||||||
current_action = False
|
current_action = False
|
||||||
|
tasklist = None
|
||||||
show_tasklist = None
|
show_tasklist = None
|
||||||
show_all_tasks = True
|
show_all_tasks = True
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
if "btn_input" in request.POST:
|
if "btn_checkbox" in request.POST:
|
||||||
form = TaskForm(request.POST)
|
|
||||||
|
|
||||||
if form.is_valid():
|
|
||||||
task = form.save(commit=False)
|
|
||||||
|
|
||||||
if task.assigned_to:
|
|
||||||
if TaskList.objects.filter(users=task.assigned_to):
|
|
||||||
task.created_by = request.user
|
|
||||||
task.save()
|
|
||||||
else:
|
|
||||||
messages.info(
|
|
||||||
request,
|
|
||||||
"User '{}' ist nicht in der Liste von Task-Gruppe '{}'.".format(
|
|
||||||
task.assigned_to, task.task_list.name
|
|
||||||
),
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
task.created_by = request.user
|
|
||||||
task.save()
|
|
||||||
|
|
||||||
elif "btn_checkbox" in request.POST:
|
|
||||||
for task_id in request.POST.getlist("checkbox"):
|
for task_id in request.POST.getlist("checkbox"):
|
||||||
task = Task.objects.get(id=task_id)
|
task = Task.objects.get(id=task_id)
|
||||||
|
|
||||||
@@ -48,16 +36,15 @@ def index(request):
|
|||||||
task.completed_date = timezone.now().date()
|
task.completed_date = timezone.now().date()
|
||||||
task.save()
|
task.save()
|
||||||
|
|
||||||
elif "btn_user" in request.POST:
|
if "btn_user" in request.POST:
|
||||||
if request.POST["action"] == "show_incompleted":
|
if request.POST["action"] == "show_incompleted":
|
||||||
current_action = False
|
current_action = False
|
||||||
else:
|
else:
|
||||||
current_action = True
|
current_action = True
|
||||||
|
|
||||||
if request.POST["tasklist"] != "all":
|
if request.POST["tasklist"] != "all":
|
||||||
show_tasklist = TaskList.objects.filter(
|
tasklist = TaskList.objects.filter(id=request.POST["tasklist"]).first()
|
||||||
id=request.POST["tasklist"]
|
show_tasklist = tasklist.id
|
||||||
).first()
|
|
||||||
|
|
||||||
if request.POST["tasks"] == "all":
|
if request.POST["tasks"] == "all":
|
||||||
show_all_tasks = True
|
show_all_tasks = True
|
||||||
@@ -67,9 +54,9 @@ def index(request):
|
|||||||
form = TaskForm()
|
form = TaskForm()
|
||||||
tasks = deque(
|
tasks = deque(
|
||||||
Task.taskmanager.get_tasks(
|
Task.taskmanager.get_tasks(
|
||||||
user=current_user,
|
user=request.user.id,
|
||||||
completed=current_action,
|
completed=current_action,
|
||||||
task_list=show_tasklist,
|
task_list=tasklist,
|
||||||
all_tasks=show_all_tasks,
|
all_tasks=show_all_tasks,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -79,8 +66,97 @@ def index(request):
|
|||||||
"formset": form,
|
"formset": form,
|
||||||
"tasks": tasks,
|
"tasks": tasks,
|
||||||
"tasklists": tasklists,
|
"tasklists": tasklists,
|
||||||
"current_user": current_user,
|
"current_user": request.user.id,
|
||||||
"current_action": current_action,
|
"current_action": current_action,
|
||||||
|
"show_tasklist": show_tasklist,
|
||||||
|
"show_all_tasks": show_all_tasks,
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, "tasks/index.html", context)
|
return render(request, "tasks/index.html", context)
|
||||||
|
|
||||||
|
|
||||||
|
class TaskCreate(LoginRequiredMixin, CreateView):
|
||||||
|
model = Task
|
||||||
|
success_url = reverse_lazy("tasks")
|
||||||
|
template_name = "tasks/task_create.html"
|
||||||
|
form_class = TaskForm
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
form.instance.created_by = self.request.user
|
||||||
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
|
class TaskUpdate(LoginRequiredMixin, UpdateView):
|
||||||
|
model = Task
|
||||||
|
success_url = reverse_lazy("tasks")
|
||||||
|
template_name = "tasks/task_create.html"
|
||||||
|
form_class = TaskForm
|
||||||
|
|
||||||
|
|
||||||
|
class TaskDetail(LoginRequiredMixin, DetailView):
|
||||||
|
model = Task
|
||||||
|
success_url = reverse_lazy("tasks")
|
||||||
|
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 = deque(
|
||||||
|
Document.objects.filter(task__id=self.object.id).order_by("-date")
|
||||||
|
)
|
||||||
|
documents = deque([])
|
||||||
|
|
||||||
|
# list of etherpad url-link of any documents
|
||||||
|
for elem in docus:
|
||||||
|
documents.append(
|
||||||
|
{
|
||||||
|
"title": elem.title,
|
||||||
|
"date": elem.date,
|
||||||
|
"etherpad_key": get_pad_link(elem.etherpad_key),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
context["documents"] = documents
|
||||||
|
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class DocumentCreate(LoginRequiredMixin, CreateView):
|
||||||
|
model = Document
|
||||||
|
# success_url = reverse_lazy('tasks')
|
||||||
|
template_name = "tasks/docu_create.html"
|
||||||
|
form_class = DocumentForm
|
||||||
|
|
||||||
|
task_id = None
|
||||||
|
|
||||||
|
def get_initial(self):
|
||||||
|
self.task_id = self.kwargs.get("pk")
|
||||||
|
|
||||||
|
task = Task.objects.get(pk=self.task_id)
|
||||||
|
context = {
|
||||||
|
"task": task,
|
||||||
|
}
|
||||||
|
|
||||||
|
return context
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context["task_id"] = self.task_id
|
||||||
|
|
||||||
|
return context
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
context = {
|
||||||
|
"task_id": self.task_id,
|
||||||
|
}
|
||||||
|
|
||||||
|
return reverse("task-detail", kwargs=context)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "layout.html" %}
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="grid-container">
|
<div class="grid-container">
|
||||||
<div class="grid-x grid-padding-x">
|
<div class="grid-x grid-padding-x">
|
||||||
<div class="cell padding-top-1">
|
<div class="cell padding-top-1">
|
||||||
@@ -22,23 +22,56 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
will man diese Buttons haben?
|
||||||
|
<div class="grid-x padding-top-1 padding-left-1 padding-right-1">
|
||||||
|
<div class="cell large-3 medium-4 small-10">
|
||||||
|
<a class="button" href="{% url 'etherpad-create' active_topic.slug active_docu.slug %}">neues Etherpad erstellen</a>
|
||||||
|
</div>
|
||||||
|
<div class="cell large-3 medium-4 small-10">
|
||||||
|
<a class="button" href="{% url 'file-create' active_topic.slug active_docu.slug %}">neue Datei hochladen</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
oder direkt hier es erstellen?
|
||||||
<form action="" method="post">
|
<form action="" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
|
||||||
<div class="grid-x grid-padding-x padding-top-1">
|
<div class="grid-x grid-padding-x padding-top-1">
|
||||||
|
|
||||||
{{ formset.management_form }}
|
{{ form_add_etherpad.management_form }}
|
||||||
|
|
||||||
{% for form in formset %}
|
{% for form in form_add_etherpad %}
|
||||||
<div class="cell medium-3 large-2 small-10">
|
<div class="cell medium-3 large-2 small-10">
|
||||||
{{ form }}
|
{{ form }}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{{ formset.non_field_errors }}
|
{{ form_add_etherpad.non_field_errors }}
|
||||||
|
|
||||||
<div class="cell medium-3 large-2 small-10 align-self-bottom">
|
<div class="cell medium-3 large-2 small-10 align-self-bottom">
|
||||||
<input type="submit" class="button" name="btn_input" value="Hinzufügen">
|
<input type="submit" class="button" name="btn_etherpad" value="Etherpad neu erstellen">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<form action="" method="post" enctype="multipart/form-data">
|
||||||
|
{% csrf_token %}
|
||||||
|
|
||||||
|
<div class="grid-x grid-padding-x padding-top-1">
|
||||||
|
|
||||||
|
{{ form_add_file.management_form }}
|
||||||
|
|
||||||
|
{% for form in form_add_file %}
|
||||||
|
<div class="cell medium-3 large-2 small-10">
|
||||||
|
{{ form }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{{ form_add_file.non_field_errors }}
|
||||||
|
|
||||||
|
<div class="cell medium-3 large-2 small-10 align-self-bottom">
|
||||||
|
<input type="submit" class="button" name="btn_fileupload" value="Dokument hochladen">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@@ -49,6 +82,7 @@
|
|||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
|
|
||||||
<div class="grid-x grid-padding-x">
|
<div class="grid-x grid-padding-x">
|
||||||
<div class="cell">
|
<div class="cell">
|
||||||
{% if documents %}
|
{% if documents %}
|
||||||
|
|||||||
22
fet2020/templates/intern/etherpad_create.html
Normal file
22
fet2020/templates/intern/etherpad_create.html
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{% extends "layout.html" %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="grid-container">
|
||||||
|
<div class="grid-x padding-top-1 padding-left-1 padding-right-1">
|
||||||
|
<a class="button" href="{% url 'docu' topic_slug slug %}">Zurück</a>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h2>Neues Etherpad erstellen</h2>
|
||||||
|
<div class="grid-x">
|
||||||
|
<div class="cell">
|
||||||
|
<form action="" method="post" enctype="multipart/form-data">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form }}
|
||||||
|
<input type="submit" class="button" name="btn_input" value="Hinzufügen">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
22
fet2020/templates/intern/file_create.html
Normal file
22
fet2020/templates/intern/file_create.html
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{% extends "layout.html" %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="grid-container">
|
||||||
|
<div class="grid-x padding-top-1 padding-left-1 padding-right-1">
|
||||||
|
<a class="button" href="{% url 'docu' topic_slug slug %}">Zurück</a>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h2>Neue Datei hochladen</h2>
|
||||||
|
<div class="grid-x">
|
||||||
|
<div class="cell">
|
||||||
|
<form action="" method="post" enctype="multipart/form-data">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form }}
|
||||||
|
<input type="submit" class="button" name="btn_input" value="Hinzufügen">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
{% extends "layout.html" %}
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="grid-container">
|
<div class="grid-container">
|
||||||
|
|
||||||
{% regroup topic by topic_group as topic_list %}
|
{% regroup topic by topic_group as topic_list %}
|
||||||
|
|
||||||
{% for topic in topic_list %}
|
{% for topic in topic_list %}
|
||||||
<div class="internheader">
|
<div class="internheader">
|
||||||
<h3>{{ topic.grouper.title }}<a class="headerlink" id="{{topic.list.0.topic_group.slug}}" href="#{{topic.list.0.topic_group.slug}}" title="Permalink to {{topic.grouper}}" style="color: lightgrey;"> #</a></h3>
|
<h3>{{ topic.grouper.title }}<a class="headerlink" id="{{topic.list.0.topic_group.slug}}" href="#{{topic.list.0.topic_group.slug}}" title="Permalink to {{topic.grouper}}" style="color: lightgrey;"> #</a></h3>
|
||||||
@@ -46,4 +44,5 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "layout.html" %}
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="grid-container">
|
<div class="grid-container">
|
||||||
<div class="grid-x grid-padding-x">
|
<div class="grid-x grid-padding-x">
|
||||||
<div class="cell padding-top-1">
|
<div class="cell padding-top-1">
|
||||||
@@ -12,13 +12,34 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="intern-hero">
|
<div class="intern-hero">
|
||||||
{% if active_topic.description %}
|
<div class="grid-x padding-top-1 padding-left-1 padding-right-1">
|
||||||
<div class="padding-top-1 padding-left-1 padding-right-1">
|
<div class="cell large-3 medium-4 small-10">
|
||||||
<a href="{% url 'admin:intern_topic_change' active_topic.id %}">Beschreibung bearbeiten</a>
|
<a class="button" href="{% url 'admin:intern_topic_change' active_topic.id %}">Beschreibung bearbeiten</a>
|
||||||
<hr>
|
|
||||||
{{ active_topic.description|safe }}
|
|
||||||
<hr>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="cell large-3 medium-4 small-10">
|
||||||
|
<a class="button" href="{% url 'task-create' %}">neuen Task hinzufügen</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if active_topic.description %}
|
||||||
|
<div class="grid-x padding-top-1 padding-left-1 padding-right-1">
|
||||||
|
{{ active_topic.description|safe }}
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if tasks %}
|
||||||
|
<div class="grid-x grid-padding-x">
|
||||||
|
<div class="cell">offene Tasks:</div>
|
||||||
|
|
||||||
|
{% for task in tasks %}
|
||||||
|
<div class="cell">
|
||||||
|
<a href="{% url 'task-detail' task.id %}">{{ task }}</a>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="grid-x grid-padding-x">
|
<div class="grid-x grid-padding-x">
|
||||||
|
|||||||
22
fet2020/templates/tasks/docu_create.html
Normal file
22
fet2020/templates/tasks/docu_create.html
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{% extends 'layout.html' %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="grid-container">
|
||||||
|
<div class="grid-x padding-top-1 padding-left-1 padding-right-1">
|
||||||
|
<a class="button" href="{% url 'task-detail' task_id %}">Zurück</a>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h2>Neues Etherpad hinzufügen</h2>
|
||||||
|
<div class="grid-x">
|
||||||
|
<div class="cell">
|
||||||
|
<form action="" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form }}
|
||||||
|
<input type="submit" class="button" name="btn_input" value="Hinzufügen">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -2,63 +2,80 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="grid-container">
|
<div class="grid-container">
|
||||||
|
<div class="grid-x padding-top-1">
|
||||||
|
<a class="button" href="{% url 'task-create' %}">neuen Task hinzufügen</a>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
{% if current_user == user.id %}
|
<form action="" method="post">
|
||||||
<h1>Task-Übersicht für {{ user.username }}</h1>
|
{% csrf_token %}
|
||||||
{% endif %}
|
<div class="grid-x grid-margin-x">
|
||||||
|
<div class="cell medium-4 large-3 small-10">
|
||||||
{% for message in messages %}
|
<label>Task-Gruppe</label>
|
||||||
<p id="messages" style="background-color: red">{{message}}</p>
|
<select id="id_tasklist" name="tasklist">
|
||||||
|
<option value="all" {% if not show_tasklist %} selected {% endif %}>alle Task-Gruppen</option>
|
||||||
|
{% for elem in tasklists %}
|
||||||
|
<option value="{{ elem.id }}" {% if show_tasklist == elem.id %} selected {% endif %}>{{ elem.name }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell medium-4 large-3 small-10">
|
||||||
|
<label>Tasks</label>
|
||||||
|
<select id="id_task" name="tasks">
|
||||||
|
<option value="own" {% if not show_all_tasks %} selected {% endif %}>nur die eigenen Tasks</option>
|
||||||
|
<option value="all" {% if show_all_tasks %} selected {% endif %}>die an alle zugewiesenen Tasks</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell medium-4 large-3 small-10">
|
||||||
|
<label>Aktion</label>
|
||||||
|
<select id="id_action" name="action">
|
||||||
|
<option value="show_incompleted" {% if not current_action %} selected {% endif %}>offenen Tasks</option>
|
||||||
|
<option value="show_all" {% if current_action %} selected {% endif %}>alle Tasks</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell medium-3 large-3 small-10 align-self-bottom">
|
||||||
|
<input type="submit" class="button" name="btn_user" value="Anzeigen">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<hr>
|
||||||
|
|
||||||
{% if tasks %}
|
{% if tasks %}
|
||||||
<form action="" method="post">
|
<form action="" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
|
||||||
<div class="grid-x grid-margin-x">
|
<div class="grid-x grid-margin-x">
|
||||||
|
|
||||||
{% regroup tasks by task_list as section_list %}
|
{% regroup tasks by task_list as section_list %}
|
||||||
{% for group in section_list %}
|
{% for group in section_list %}
|
||||||
|
|
||||||
<div class="cell">
|
<div class="cell">
|
||||||
<ul class="no-bullet">
|
<ul class="no-bullet">
|
||||||
|
|
||||||
<h3>{{ group.grouper }}</h3>
|
<h3>{{ group.grouper }}</h3>
|
||||||
|
|
||||||
{% for task in group.list %}
|
{% for task in group.list %}
|
||||||
|
|
||||||
<div class="grid-x">
|
<div class="grid-x">
|
||||||
|
|
||||||
<div class="cell medium-3 large-3 small-10">
|
<div class="cell medium-3 large-3 small-10">
|
||||||
<input type="checkbox" name="checkbox" value="{{ task.id }}" {% if task.completed %} checked {% endif %}>
|
<input type="checkbox" name="checkbox" value="{{ task.id }}" {% if task.completed %} checked {% endif %}>
|
||||||
{{ task.title }}</a>
|
<a href="{% url 'task-detail' task.id %}">{{ task.title }}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="cell medium-4 large-4 small-10">
|
<div class="cell medium-3 large-3 small-10">
|
||||||
{% if task.due_date %}
|
{% if task.due_date %}
|
||||||
Fälligkeitsdatum: {{ task.due_date|date:"d.m.Y" }}
|
Fällig bis: {{ task.due_date|date:"d.m.Y" }}
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="cell medium-4 large-4 small-10">
|
|
||||||
{% if task.assigned_to %}
|
|
||||||
nur dir zugewiesen!
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
<div class="cell">
|
<div class="cell">
|
||||||
<ul class="no-bullet">
|
<ul class="no-bullet">
|
||||||
|
|
||||||
<input type="submit" class="button" name="btn_checkbox" value="Task abschließen">
|
<input type="submit" class="button" name="btn_checkbox" value="Task abschließen">
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -70,82 +87,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<h2>Andere Task-Übersicht anzeigen</h2>
|
|
||||||
|
|
||||||
<form action="" method="post">
|
|
||||||
{% csrf_token %}
|
|
||||||
|
|
||||||
<div class="grid-x grid-margin-x">
|
|
||||||
<div class="cell medium-4 large-3 small-10">
|
|
||||||
<label>Task-Gruppe
|
|
||||||
<select id="id_tasklist" name="tasklist">
|
|
||||||
<option value="all">
|
|
||||||
alle Task-Gruppen
|
|
||||||
</option>
|
|
||||||
{% for elem in tasklists %}
|
|
||||||
<option value="{{ elem.id }}">
|
|
||||||
{{ elem.name }}
|
|
||||||
</option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="cell medium-4 large-3 small-10">
|
|
||||||
<label>Tasks
|
|
||||||
<select id="id_task" name="tasks">
|
|
||||||
<option value="own">
|
|
||||||
nur die eigenen Tasks
|
|
||||||
</option>
|
|
||||||
<option value="all">
|
|
||||||
die an alle zugewiesenen Tasks
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="cell medium-4 large-3 small-10">
|
|
||||||
<label>Aktion
|
|
||||||
<select id="id_action" name="action">
|
|
||||||
<option value="show_incompleted" {% if not current_action %} selected {% endif %}>unvollständige Tasks</option>
|
|
||||||
<option value="show_all" {% if current_action %} selected {% endif %}>alle Tasks</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="cell medium-3 large-3 small-10 align-self-bottom">
|
|
||||||
<input type="submit" class="button" name="btn_user" value="Anzeigen">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
|
|
||||||
<h2>Neuen Task hinzufügen</h2>
|
|
||||||
|
|
||||||
<form action="" method="post">
|
|
||||||
{% csrf_token %}
|
|
||||||
|
|
||||||
<div class="grid-x grid-margin-x">
|
|
||||||
|
|
||||||
{{ formset.management_form }}
|
|
||||||
|
|
||||||
{% for form in formset %}
|
|
||||||
<div class="cell medium-3 large-2 small-10">
|
|
||||||
{{ form.label }}
|
|
||||||
{{ form }}
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
<div class="cell medium-3 large-2 small-10 align-self-bottom">
|
|
||||||
<input type="submit" class="button" name="btn_input" value="Hinzufügen">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
22
fet2020/templates/tasks/task_create.html
Normal file
22
fet2020/templates/tasks/task_create.html
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{% extends 'layout.html' %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="grid-container">
|
||||||
|
<div class="grid-x padding-top-1">
|
||||||
|
<a class="button" href="{% url 'tasks' %}">Zurück</a>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h2>Neuen Task hinzufügen</h2>
|
||||||
|
<div class="grid-x">
|
||||||
|
<div class="cell">
|
||||||
|
<form action="" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form }}
|
||||||
|
<input type="submit" class="button" name="btn_input" value="Hinzufügen">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
46
fet2020/templates/tasks/task_detail.html
Normal file
46
fet2020/templates/tasks/task_detail.html
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
{% extends 'layout.html' %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="grid-container">
|
||||||
|
<div class="grid-x padding-top-1">
|
||||||
|
<div class="cell large-2 medium-4 small-6">
|
||||||
|
<a class="button" href="{% url 'tasks' %}">Zurück</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell large-2 medium-4 small-6">
|
||||||
|
<a class="button" href="{% url 'docu-create' task.id %}">Etherpad hinzufügen</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="grid-x padding-bottom-1">
|
||||||
|
<div class="cell">
|
||||||
|
<h2>{{ task.title }}</h2>
|
||||||
|
|
||||||
|
<p>Fällig am: {{ task.due_date }}</p>
|
||||||
|
|
||||||
|
{% if task.completed %}
|
||||||
|
<p>Erledigt am: {{ task.completed_date }}</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if task.note %}
|
||||||
|
{{ task.note }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% for document in documents %}
|
||||||
|
<a href="{{ document.etherpad_key }}">
|
||||||
|
<div class="news-hero-compact">
|
||||||
|
<div class="news-hero-compact-text">
|
||||||
|
<p style="margin-bottom: 0rem;">{{ document.title }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="news-hero-compact-right">
|
||||||
|
<p style="margin-bottom: 0rem;">{{ document.date }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user