diff --git a/core/admin.py b/core/admin.py index 251f357..4c12be2 100644 --- a/core/admin.py +++ b/core/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin -from .models import ApiKey, Attachment, Item, Tag +from .models import ApiKey, Attachment, Item, Tag, UserPreference class AttachmentInline(admin.TabularInline): @@ -22,3 +22,4 @@ class ApiKeyAdmin(admin.ModelAdmin): admin.site.register(Tag) +admin.site.register(UserPreference) diff --git a/core/forms.py b/core/forms.py index ab68d3b..f65a482 100644 --- a/core/forms.py +++ b/core/forms.py @@ -1,10 +1,22 @@ from django import forms from django.contrib.auth.models import User -from .models import ApiKey, Attachment, Item +from .models import ApiKey, Attachment, Item, UserPreference + + +class MultipleFileInput(forms.ClearableFileInput): + allow_multiple_selected = True + + +class MultipleFileField(forms.FileField): + def clean(self, data, initial=None): + if not data: + return [] + files = data if isinstance(data, (list, tuple)) else [data] + return [super(MultipleFileField, self).clean(file, initial) for file in files] class QuickItemForm(forms.ModelForm): - files = forms.FileField(required=False, widget=forms.ClearableFileInput(attrs={'multiple': False})) + files = MultipleFileField(required=False, widget=MultipleFileInput(attrs={'multiple': True})) class Meta: model = Item @@ -21,7 +33,7 @@ class QuickItemForm(forms.ModelForm): class EditItemForm(forms.ModelForm): - files = forms.FileField(required=False, widget=forms.ClearableFileInput()) + files = MultipleFileField(required=False, widget=MultipleFileInput(attrs={'multiple': True})) class Meta: model = Item @@ -44,6 +56,21 @@ class UserSettingsForm(forms.ModelForm): widgets = {field: forms.TextInput(attrs={'class': 'form-control'}) for field in ['first_name', 'last_name', 'email']} +class UserPreferenceForm(forms.ModelForm): + class Meta: + model = UserPreference + fields = ['show_notes', 'show_open_todos', 'show_done_todos', 'show_links', 'show_journal', 'overview_lines'] + labels = { + 'show_notes': 'Notizen anzeigen', + 'show_open_todos': 'Offene Aufgaben anzeigen', + 'show_done_todos': 'Erledigte Aufgaben anzeigen', + 'show_links': 'Links anzeigen', + 'show_journal': 'Journal anzeigen', + 'overview_lines': 'Zeilen in der Übersicht', + } + widgets = {'overview_lines': forms.NumberInput(attrs={'class': 'form-control', 'min': 1, 'max': 50})} + + class ApiKeyForm(forms.ModelForm): class Meta: model = ApiKey diff --git a/core/migrations/0005_journal_kind.py b/core/migrations/0005_journal_kind.py new file mode 100644 index 0000000..bcc0a8f --- /dev/null +++ b/core/migrations/0005_journal_kind.py @@ -0,0 +1,12 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [('core', '0004_item_comment')] + operations = [ + migrations.AlterField( + model_name='item', + name='kind', + field=models.CharField(choices=[('todo', 'Aufgabe'), ('note', 'Notiz'), ('link', 'Link'), ('journal', 'Journal')], default='note', max_length=10), + ), + ] diff --git a/core/migrations/0006_userpreference.py b/core/migrations/0006_userpreference.py new file mode 100644 index 0000000..343885b --- /dev/null +++ b/core/migrations/0006_userpreference.py @@ -0,0 +1,21 @@ +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [('core', '0005_journal_kind'), migrations.swappable_dependency(settings.AUTH_USER_MODEL)] + operations = [ + migrations.CreateModel( + name='UserPreference', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('show_notes', models.BooleanField(default=True)), + ('show_open_todos', models.BooleanField(default=True)), + ('show_done_todos', models.BooleanField(default=False)), + ('show_links', models.BooleanField(default=True)), + ('show_journal', models.BooleanField(default=False)), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='preferences', to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/core/migrations/0007_userpreference_overview_lines.py b/core/migrations/0007_userpreference_overview_lines.py new file mode 100644 index 0000000..0080961 --- /dev/null +++ b/core/migrations/0007_userpreference_overview_lines.py @@ -0,0 +1,12 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [('core', '0006_userpreference')] + operations = [ + migrations.AddField( + model_name='userpreference', + name='overview_lines', + field=models.PositiveSmallIntegerField(default=4), + ), + ] diff --git a/core/models.py b/core/models.py index 23049d2..f56b768 100644 --- a/core/models.py +++ b/core/models.py @@ -23,6 +23,7 @@ class Item(models.Model): TODO = 'todo', 'Aufgabe' NOTE = 'note', 'Notiz' LINK = 'link', 'Link' + JOURNAL = 'journal', 'Journal' class Visibility(models.TextChoices): PRIVATE = 'private', 'Privat' @@ -58,6 +59,19 @@ class Item(models.Model): self.linked_items.set(Item.objects.filter(id__in=ids).exclude(id=self.id)) +class UserPreference(models.Model): + user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='preferences') + show_notes = models.BooleanField(default=True) + show_open_todos = models.BooleanField(default=True) + show_done_todos = models.BooleanField(default=False) + show_links = models.BooleanField(default=True) + show_journal = models.BooleanField(default=False) + overview_lines = models.PositiveSmallIntegerField(default=4) + + def __str__(self): + return f'Einstellungen {self.user}' + + class ApiKey(models.Model): owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='api_keys') name = models.CharField(max_length=120, default='API Key') diff --git a/core/templates/core/_edit_form.html b/core/templates/core/_edit_form.html index 419c3c8..505968b 100644 --- a/core/templates/core/_edit_form.html +++ b/core/templates/core/_edit_form.html @@ -1,4 +1,4 @@ -