diff --git a/taiga/projects/admin.py b/taiga/projects/admin.py index 0dee8cde2..184fbcf13 100644 --- a/taiga/projects/admin.py +++ b/taiga/projects/admin.py @@ -17,8 +17,8 @@ from django.contrib import admin from taiga.projects.milestones.admin import MilestoneInline -from taiga.projects.notifications.admin import WatchedInline -from taiga.projects.votes.admin import VoteInline +from taiga.projects.notifications.admin import NotifyPolicyInline +from taiga.projects.likes.admin import LikeInline from taiga.users.admin import RoleInline from . import models @@ -26,19 +26,49 @@ class MembershipAdmin(admin.ModelAdmin): list_display = ['project', 'role', 'user'] list_display_links = list_display - list_filter = ['project', 'role'] + raw_id_fields = ["project"] + def get_object(self, *args, **kwargs): + self.obj = super().get_object(*args, **kwargs) + return self.obj + + def formfield_for_foreignkey(self, db_field, request, **kwargs): + if db_field.name in ["user", "invited_by"] and getattr(self, 'obj', None): + kwargs["queryset"] = db_field.related.model.objects.filter( + memberships__project=self.obj.project) + + elif db_field.name in ["role"] and getattr(self, 'obj', None): + kwargs["queryset"] = db_field.related.model.objects.filter( + project=self.obj.project) + + return super().formfield_for_foreignkey(db_field, request, **kwargs) class MembershipInline(admin.TabularInline): model = models.Membership extra = 0 + def get_formset(self, request, obj=None, **kwargs): + # Hack! Hook parent obj just in time to use in formfield_for_manytomany + self.parent_obj = obj + return super(MembershipInline, self).get_formset(request, obj, **kwargs) + + def formfield_for_foreignkey(self, db_field, request, **kwargs): + if (db_field.name in ["user", "invited_by"]): + kwargs["queryset"] = db_field.related.model.objects.filter( + memberships__project=self.parent_obj) + + elif (db_field.name in ["role"]): + kwargs["queryset"] = db_field.related.model.objects.filter( + project=self.parent_obj) + + return super().formfield_for_foreignkey(db_field, request, **kwargs) + class ProjectAdmin(admin.ModelAdmin): list_display = ["name", "owner", "created_date", "total_milestones", "total_story_points"] list_display_links = list_display - inlines = [RoleInline, MembershipInline, MilestoneInline, WatchedInline, VoteInline] + inlines = [RoleInline, MembershipInline, MilestoneInline, NotifyPolicyInline, LikeInline] def get_object(self, *args, **kwargs): self.obj = super().get_object(*args, **kwargs) @@ -49,10 +79,16 @@ def formfield_for_foreignkey(self, db_field, request, **kwargs): "default_priority", "default_severity", "default_issue_status", "default_issue_type"]): if getattr(self, 'obj', None): - kwargs["queryset"] = db_field.related.parent_model.objects.filter( + kwargs["queryset"] = db_field.related.model.objects.filter( project=self.obj) else: - kwargs["queryset"] = db_field.related.parent_model.objects.none() + kwargs["queryset"] = db_field.related.model.objects.none() + + elif (db_field.name in ["owner"] + and getattr(self, 'obj', None)): + kwargs["queryset"] = db_field.related.model.objects.filter( + memberships__project=self.obj.project) + return super().formfield_for_foreignkey(db_field, request, **kwargs) def formfield_for_manytomany(self, db_field, request, **kwargs): @@ -68,13 +104,13 @@ def formfield_for_manytomany(self, db_field, request, **kwargs): class PointsAdmin(admin.ModelAdmin): list_display = ["project", "order", "name", "value"] list_display_links = ["name"] - list_filter = ["project"] + raw_id_fields = ["project"] class UserStoryStatusAdmin(admin.ModelAdmin): list_display = ["project", "order", "name", "is_closed"] list_display_links = ["name"] - list_filter = ["project"] + raw_id_fields = ["project"] # Tasks common admins @@ -82,7 +118,7 @@ class UserStoryStatusAdmin(admin.ModelAdmin): class TaskStatusAdmin(admin.ModelAdmin): list_display = ["project", "order", "name", "is_closed", "color"] list_display_links = ["name"] - list_filter = ["project"] + raw_id_fields = ["project"] # Issues common admins @@ -90,25 +126,26 @@ class TaskStatusAdmin(admin.ModelAdmin): class SeverityAdmin(admin.ModelAdmin): list_display = ["project", "order", "name", "color"] list_display_links = ["name"] - list_filter = ["project"] + raw_id_fields = ["project"] class PriorityAdmin(admin.ModelAdmin): list_display = ["project", "order", "name", "color"] list_display_links = ["name"] - list_filter = ["project"] + raw_id_fields = ["project"] class IssueTypeAdmin(admin.ModelAdmin): list_display = ["project", "order", "name", "color"] list_display_links = ["name"] - list_filter = ["project"] + raw_id_fields = ["project"] class IssueStatusAdmin(admin.ModelAdmin): list_display = ["project", "order", "name", "is_closed", "color"] list_display_links = ["name"] - list_filter = ["project"] + raw_id_fields = ["project"] + class ProjectTemplateAdmin(admin.ModelAdmin): pass diff --git a/taiga/projects/attachments/admin.py b/taiga/projects/attachments/admin.py index c30b4f522..9f1d5eb30 100644 --- a/taiga/projects/attachments/admin.py +++ b/taiga/projects/attachments/admin.py @@ -23,7 +23,18 @@ class AttachmentAdmin(admin.ModelAdmin): list_display = ["id", "project", "attached_file", "owner", "content_type", "content_object"] list_display_links = ["id", "attached_file",] - list_filter = ["project", "content_type"] + search_fields = ["id", "attached_file", "project__name", "project__slug"] + raw_id_fields = ["project"] + + def get_object(self, *args, **kwargs): + self.obj = super().get_object(*args, **kwargs) + return self.obj + + def formfield_for_foreignkey(self, db_field, request, **kwargs): + if (db_field.name in ["owner"]and getattr(self, 'obj', None)): + kwargs["queryset"] = db_field.related.model.objects.filter( + memberships__project=self.obj.project) + return super().formfield_for_foreignkey(db_field, request, **kwargs) class AttachmentInline(generic.GenericTabularInline): diff --git a/taiga/projects/custom_attributes/admin.py b/taiga/projects/custom_attributes/admin.py index fe0e3c6b9..3f67ffafb 100644 --- a/taiga/projects/custom_attributes/admin.py +++ b/taiga/projects/custom_attributes/admin.py @@ -19,14 +19,12 @@ from . import models - -@admin.register(models.UserStoryCustomAttribute) -class UserStoryCustomAttributeAdmin(admin.ModelAdmin): - list_display = ["id", "name", "project", "order"] +class BaseCustomAttributeAdmin: + list_display = ["id", "name", "type", "project", "order"] list_display_links = ["id", "name"] fieldsets = ( (None, { - "fields": ("name", "description", ("project", "order")) + "fields": ("name", "type", "description", ("project", "order")) }), ("Advanced options", { "classes": ("collapse",), @@ -35,37 +33,19 @@ class UserStoryCustomAttributeAdmin(admin.ModelAdmin): ) readonly_fields = ("created_date", "modified_date") search_fields = ["id", "name", "project__name", "project__slug"] + raw_id_fields = ["project"] + + +@admin.register(models.UserStoryCustomAttribute) +class UserStoryCustomAttributeAdmin(BaseCustomAttributeAdmin, admin.ModelAdmin): + pass @admin.register(models.TaskCustomAttribute) -class TaskCustomAttributeAdmin(admin.ModelAdmin): - list_display = ["id", "name", "project", "order"] - list_display_links = ["id", "name"] - fieldsets = ( - (None, { - "fields": ("name", "description", ("project", "order")) - }), - ("Advanced options", { - "classes": ("collapse",), - "fields": (("created_date", "modified_date"),) - }) - ) - readonly_fields = ("created_date", "modified_date") - search_fields = ["id", "name", "project__name", "project__slug"] +class TaskCustomAttributeAdmin(BaseCustomAttributeAdmin, admin.ModelAdmin): + pass @admin.register(models.IssueCustomAttribute) -class IssueCustomAttributeAdmin(admin.ModelAdmin): - list_display = ["id", "name", "project", "order"] - list_display_links = ["id", "name"] - fieldsets = ( - (None, { - "fields": ("name", "description", ("project", "order")) - }), - ("Advanced options", { - "classes": ("collapse",), - "fields": (("created_date", "modified_date"),) - }) - ) - readonly_fields = ("created_date", "modified_date") - search_fields = ["id", "name", "project__name", "project__slug"] +class IssueCustomAttributeAdmin(BaseCustomAttributeAdmin, admin.ModelAdmin): + pass diff --git a/taiga/projects/issues/admin.py b/taiga/projects/issues/admin.py index 7da02b5b5..a11f1d21c 100644 --- a/taiga/projects/issues/admin.py +++ b/taiga/projects/issues/admin.py @@ -27,6 +27,8 @@ class IssueAdmin(admin.ModelAdmin): list_display = ["project", "milestone", "ref", "subject",] list_display_links = ["ref", "subject",] inlines = [WatchedInline, VoteInline] + raw_id_fields = ["project"] + search_fields = ["subject", "description", "id", "ref"] def get_object(self, *args, **kwargs): self.obj = super().get_object(*args, **kwargs) @@ -35,11 +37,11 @@ def get_object(self, *args, **kwargs): def formfield_for_foreignkey(self, db_field, request, **kwargs): if (db_field.name in ["status", "priority", "severity", "type", "milestone"] and getattr(self, 'obj', None)): - kwargs["queryset"] = db_field.related.parent_model.objects.filter( + kwargs["queryset"] = db_field.related.model.objects.filter( project=self.obj.project) elif (db_field.name in ["owner", "assigned_to"] and getattr(self, 'obj', None)): - kwargs["queryset"] = db_field.related.parent_model.objects.filter( + kwargs["queryset"] = db_field.related.model.objects.filter( memberships__project=self.obj.project) return super().formfield_for_foreignkey(db_field, request, **kwargs) diff --git a/taiga/projects/likes/admin.py b/taiga/projects/likes/admin.py index 802eaca4d..b48f23850 100644 --- a/taiga/projects/likes/admin.py +++ b/taiga/projects/likes/admin.py @@ -23,3 +23,4 @@ class LikeInline(GenericTabularInline): model = models.Like extra = 0 + raw_id_fields = ["user"] diff --git a/taiga/projects/milestones/admin.py b/taiga/projects/milestones/admin.py index 378928cea..866763739 100644 --- a/taiga/projects/milestones/admin.py +++ b/taiga/projects/milestones/admin.py @@ -25,14 +25,27 @@ class MilestoneInline(admin.TabularInline): model = models.Milestone extra = 0 + def get_formset(self, request, obj=None, **kwargs): + # Hack! Hook parent obj just in time to use in formfield_for_manytomany + self.parent_obj = obj + return super(MilestoneInline, self).get_formset(request, obj, **kwargs) + + def formfield_for_foreignkey(self, db_field, request, **kwargs): + if (db_field.name in ["owner"]): + kwargs["queryset"] = db_field.related.model.objects.filter( + memberships__project=self.parent_obj) + + return super().formfield_for_foreignkey(db_field, request, **kwargs) + class MilestoneAdmin(admin.ModelAdmin): list_display = ["name", "project", "owner", "closed", "estimated_start", "estimated_finish"] list_display_links = list_display - list_filter = ["project"] readonly_fields = ["owner"] inlines = [WatchedInline, VoteInline] + search_fields = ["name", "id"] + raw_id_fields = ["project"] admin.site.register(models.Milestone, MilestoneAdmin) diff --git a/taiga/projects/notifications/admin.py b/taiga/projects/notifications/admin.py index a2278932f..4036f787f 100644 --- a/taiga/projects/notifications/admin.py +++ b/taiga/projects/notifications/admin.py @@ -16,6 +16,7 @@ from django.contrib import admin from django.contrib.contenttypes.admin import GenericTabularInline +from django.contrib.admin import TabularInline from . import models @@ -23,3 +24,10 @@ class WatchedInline(GenericTabularInline): model = models.Watched extra = 0 + raw_id_fields = ["project", "user"] + +class NotifyPolicyInline(TabularInline): + model = models.NotifyPolicy + extra = 0 + readonly_fields = ("notify_level",) + raw_id_fields = ["user"] diff --git a/taiga/projects/tasks/admin.py b/taiga/projects/tasks/admin.py index 4c451c176..a9cbd823f 100644 --- a/taiga/projects/tasks/admin.py +++ b/taiga/projects/tasks/admin.py @@ -24,10 +24,11 @@ class TaskAdmin(admin.ModelAdmin): - list_display = ["project", "milestone", "user_story", "ref", "subject",] + list_display = ["project", "milestone", "user_story", "ref", "subject",] list_display_links = ["ref", "subject",] - list_filter = ["project"] inlines = [WatchedInline, VoteInline] + raw_id_fields = ["project"] + search_fields = ["subject", "description", "id", "ref"] def get_object(self, *args, **kwargs): self.obj = super().get_object(*args, **kwargs) @@ -36,11 +37,11 @@ def get_object(self, *args, **kwargs): def formfield_for_foreignkey(self, db_field, request, **kwargs): if (db_field.name in ["status", "milestone", "user_story"] and getattr(self, 'obj', None)): - kwargs["queryset"] = db_field.related.parent_model.objects.filter( + kwargs["queryset"] = db_field.related.model.objects.filter( project=self.obj.project) elif (db_field.name in ["owner", "assigned_to"] and getattr(self, 'obj', None)): - kwargs["queryset"] = db_field.related.parent_model.objects.filter( + kwargs["queryset"] = db_field.related.model.objects.filter( memberships__project=self.obj.project) return super().formfield_for_foreignkey(db_field, request, **kwargs) diff --git a/taiga/projects/userstories/admin.py b/taiga/projects/userstories/admin.py index 2887e8364..f1772320e 100644 --- a/taiga/projects/userstories/admin.py +++ b/taiga/projects/userstories/admin.py @@ -35,28 +35,28 @@ class RolePointsInline(admin.TabularInline): class RolePointsAdmin(admin.ModelAdmin): list_display = ["user_story", "role", "points"] list_display_links = list_display - list_filter = ["role", "user_story__project"] readonly_fields = ["user_story", "role", "points"] class UserStoryAdmin(admin.ModelAdmin): list_display = ["project", "milestone", "ref", "subject",] list_display_links = ["ref", "subject",] - list_filter = ["project"] inlines = [RolePointsInline, WatchedInline, VoteInline] + raw_id_fields = ["project"] + search_fields = ["subject", "description", "id", "ref"] def get_object(self, *args, **kwargs): self.obj = super().get_object(*args, **kwargs) return self.obj def formfield_for_foreignkey(self, db_field, request, **kwargs): - if (db_field.name in ["status", "milestone"] + if (db_field.name in ["status", "milestone", "generated_from_issue"] and getattr(self, 'obj', None)): - kwargs["queryset"] = db_field.related.parent_model.objects.filter( + kwargs["queryset"] = db_field.related.model.objects.filter( project=self.obj.project) elif (db_field.name in ["owner", "assigned_to"] and getattr(self, 'obj', None)): - kwargs["queryset"] = db_field.related.parent_model.objects.filter( + kwargs["queryset"] = db_field.related.model.objects.filter( memberships__project=self.obj.project) return super().formfield_for_foreignkey(db_field, request, **kwargs) diff --git a/taiga/projects/votes/admin.py b/taiga/projects/votes/admin.py index 3ab238aa3..d0e0a74e9 100644 --- a/taiga/projects/votes/admin.py +++ b/taiga/projects/votes/admin.py @@ -23,3 +23,4 @@ class VoteInline(GenericTabularInline): model = models.Vote extra = 0 + raw_id_fields = ["user"] diff --git a/taiga/projects/wiki/admin.py b/taiga/projects/wiki/admin.py index ed90f65c3..f6ffcf201 100644 --- a/taiga/projects/wiki/admin.py +++ b/taiga/projects/wiki/admin.py @@ -28,11 +28,23 @@ class WikiPageAdmin(admin.ModelAdmin): list_display = ["project", "slug", "owner"] list_display_links = list_display inlines = [WatchedInline, VoteInline] + raw_id_fields = ["project"] + + def get_object(self, *args, **kwargs): + self.obj = super().get_object(*args, **kwargs) + return self.obj + + def formfield_for_foreignkey(self, db_field, request, **kwargs): + if (db_field.name in ["owner", "last_modifier"] and getattr(self, 'obj', None)): + kwargs["queryset"] = db_field.related.model.objects.filter( + memberships__project=self.obj.project) + return super().formfield_for_foreignkey(db_field, request, **kwargs) admin.site.register(models.WikiPage, WikiPageAdmin) class WikiLinkAdmin(admin.ModelAdmin): list_display = ["project", "title"] list_display_links = list_display + raw_id_fields = ["project"] admin.site.register(models.WikiLink, WikiLinkAdmin)