You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

115 lines
4.0 KiB

from django.contrib import admin
from django.utils.translation import gettext_lazy as _
from unfold.admin import ModelAdmin, TabularInline, StackedInline
from unfold.decorators import display, action
from apps.projects.models.project import (
Project,
KanbanColumn,
KanbanTask,
ProjectDocument,
)
from utils.admin import project_admin_site
class KanbanTaskInline(TabularInline):
model = KanbanTask
extra = 0
fields = ('title', 'column', 'priority', 'assignee', 'due_date', 'order')
class ProjectDocumentInline(TabularInline):
model = ProjectDocument
extra = 0
fields = ('title', 'file', 'doc_type', 'uploaded_at')
readonly_fields = ('uploaded_at',)
@admin.register(Project, site=project_admin_site)
class ProjectAdmin(ModelAdmin):
list_display = (
'title',
'owner_institution',
'category',
'status_badge',
'progress_percentage_display',
'budget',
'team_size',
'start_date',
'estimated_end_date',
)
list_filter = ('status', 'category', 'owner_institution')
search_fields = ('title', 'description', 'owner_institution__name')
prepopulated_fields = {'slug': ('title',)}
filter_horizontal = ('collaborating_institutions',)
inlines = [KanbanTaskInline, ProjectDocumentInline]
actions = ['mark_as_completed', 'mark_as_active']
fieldsets = (
(_('Project Definition'), {
'fields': ('title', 'slug', 'description', 'category', 'status')
}),
(_('Institutional Governance'), {
'fields': ('owner_institution', 'collaborating_institutions', 'created_by')
}),
(_('Progress & Budget'), {
'fields': ('progress_percentage', 'budget', 'team_size', 'cover_image')
}),
(_('Timeline Schedule'), {
'fields': ('start_date', 'estimated_end_date', 'actual_end_date')
}),
)
@display(description=_('Status'), label={
Project.Status.ACTIVE: "info",
Project.Status.COMPLETED: "success",
Project.Status.PLANNING: "warning",
Project.Status.ON_HOLD: "danger",
})
def status_badge(self, obj):
return obj.get_status_display()
@display(description=_('Progress'))
def progress_percentage_display(self, obj):
return f"{obj.progress_percentage}%"
@action(description=_('Mark selected projects as Completed'))
def mark_as_completed(self, request, queryset):
count = queryset.update(status=Project.Status.COMPLETED, progress_percentage=100)
self.message_user(request, _(f"{count} project(s) marked as completed."))
@action(description=_('Mark selected projects as Active'))
def mark_as_active(self, request, queryset):
count = queryset.update(status=Project.Status.ACTIVE)
self.message_user(request, _(f"{count} project(s) marked as active."))
@admin.register(KanbanColumn, site=project_admin_site)
class KanbanColumnAdmin(ModelAdmin):
list_display = ('name', 'project', 'code', 'order', 'color')
list_filter = ('project',)
search_fields = ('name', 'project__title')
@admin.register(KanbanTask, site=project_admin_site)
class KanbanTaskAdmin(ModelAdmin):
list_display = ('title', 'project', 'column', 'priority_badge', 'assignee', 'due_date', 'order')
list_filter = ('priority', 'project', 'column')
search_fields = ('title', 'description', 'project__title', 'assignee__fullname')
@display(description=_('Priority'), label={
KanbanTask.Priority.URGENT: "danger",
KanbanTask.Priority.HIGH: "warning",
KanbanTask.Priority.MEDIUM: "info",
KanbanTask.Priority.LOW: "success",
})
def priority_badge(self, obj):
return obj.get_priority_display()
@admin.register(ProjectDocument, site=project_admin_site)
class ProjectDocumentAdmin(ModelAdmin):
list_display = ('title', 'project', 'doc_type', 'uploaded_by', 'uploaded_at')
list_filter = ('doc_type', 'uploaded_at')
search_fields = ('title', 'project__title')
readonly_fields = ('uploaded_at',)