refactor(src): replace hardcoded role checks with is_admin attribute
Simplify permission logic by using the unified `is_admin` flag instead of duplicated role list checks.
This commit is contained in:
18 files changed
+269
-123
No files matched your search
@@ -184,40 +184,49 @@ class Command(BaseCommand):
|
||||
# ── Demo Users ───────────────────────────────────────────────────────
|
||||
|
||||
users = []
|
||||
for i in range(1, 10):
|
||||
dev_roles = [
|
||||
"backend_developer",
|
||||
"frontend_developer",
|
||||
"ui_ux_designer",
|
||||
"qa",
|
||||
"tester",
|
||||
"devops",
|
||||
"data_analyst",
|
||||
"product_owner",
|
||||
"scrum_master",
|
||||
]
|
||||
for role_name in dev_roles:
|
||||
user, _ = User.objects.get_or_create(
|
||||
username=f"user{i}",
|
||||
username=role_name,
|
||||
defaults={
|
||||
"email": f"user{i}@mail.com",
|
||||
"first_name": f"Developer{i}",
|
||||
"email": f"{role_name}@mail.com",
|
||||
"first_name": role_name.replace("_", " ").title(),
|
||||
"last_name": "User",
|
||||
"role": "member",
|
||||
"role": role_name,
|
||||
},
|
||||
)
|
||||
user.set_password("user123")
|
||||
if user.role != "member":
|
||||
user.role = "member"
|
||||
if user.role != role_name:
|
||||
user.role = role_name
|
||||
user.save()
|
||||
users.append(user)
|
||||
|
||||
# Additional specific roles
|
||||
roles = ["Manager", "Designer", "Tester", "DevOps"]
|
||||
for r_name in roles:
|
||||
u_role = "manager" if r_name == "Manager" else "member"
|
||||
user, _ = User.objects.get_or_create(
|
||||
username=r_name.lower(),
|
||||
defaults={
|
||||
"email": f"{r_name.lower()}@mail.com",
|
||||
"first_name": r_name,
|
||||
"last_name": "Staff",
|
||||
"role": u_role,
|
||||
},
|
||||
)
|
||||
user.set_password("user123")
|
||||
if user.role != u_role:
|
||||
user.role = u_role
|
||||
user.save()
|
||||
users.append(user)
|
||||
# Manager user
|
||||
manager_role = "manager"
|
||||
user, _ = User.objects.get_or_create(
|
||||
username="manager",
|
||||
defaults={
|
||||
"email": "manager@mail.com",
|
||||
"first_name": "Manager",
|
||||
"last_name": "Staff",
|
||||
"role": manager_role,
|
||||
},
|
||||
)
|
||||
user.set_password("user123")
|
||||
if user.role != manager_role:
|
||||
user.role = manager_role
|
||||
user.save()
|
||||
users.append(user)
|
||||
|
||||
all_users = [admin] + users
|
||||
self.stdout.write(f" ✓ {len(all_users)} users ready")
|
||||
@@ -256,6 +265,14 @@ class Command(BaseCommand):
|
||||
"Shopping Cart",
|
||||
"Payment Gateway",
|
||||
],
|
||||
"statuses": [
|
||||
("Backlog", "#6B7280", False),
|
||||
("Todo", "#3B82F6", False),
|
||||
("In Progress", "#F59E0B", False),
|
||||
("In Review", "#8B5CF6", False),
|
||||
("Staging", "#06B6D4", False),
|
||||
("Done", "#10B981", True),
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Org Website",
|
||||
@@ -268,6 +285,14 @@ class Command(BaseCommand):
|
||||
"Services Section",
|
||||
"Contact & Forms",
|
||||
],
|
||||
"statuses": [
|
||||
("Draft", "#6B7280", False),
|
||||
("Copy Review", "#3B82F6", False),
|
||||
("Design Review", "#8B5CF6", False),
|
||||
("Development", "#F59E0B", False),
|
||||
("Client Review", "#EC4899", False),
|
||||
("Published", "#10B981", True),
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Health Homeservice Website",
|
||||
@@ -280,6 +305,14 @@ class Command(BaseCommand):
|
||||
"Booking System",
|
||||
"Telehealth Video",
|
||||
],
|
||||
"statuses": [
|
||||
("Registration", "#6B7280", False),
|
||||
("Triage", "#3B82F6", False),
|
||||
("Provider Assigned", "#F59E0B", False),
|
||||
("In Service", "#8B5CF6", False),
|
||||
("Follow-up", "#EC4899", False),
|
||||
("Completed", "#10B981", True),
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Consultancy Website",
|
||||
@@ -292,6 +325,14 @@ class Command(BaseCommand):
|
||||
"Scheduling Integration",
|
||||
"Client Testimonials",
|
||||
],
|
||||
"statuses": [
|
||||
("Lead", "#6B7280", False),
|
||||
("Discovery", "#3B82F6", False),
|
||||
("Proposal", "#F59E0B", False),
|
||||
("Negotiation", "#EC4899", False),
|
||||
("Active", "#8B5CF6", False),
|
||||
("Closed", "#10B981", True),
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "School Website with Student Management",
|
||||
@@ -304,6 +345,13 @@ class Command(BaseCommand):
|
||||
"Grading & Attendance",
|
||||
"Public Admissions Page",
|
||||
],
|
||||
"statuses": [
|
||||
("Enrollment", "#6B7280", False),
|
||||
("Records Pending", "#3B82F6", False),
|
||||
("Active", "#10B981", False),
|
||||
("Graduating", "#F59E0B", False),
|
||||
("Alumni", "#8B5CF6", True),
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Human Resource Management Website",
|
||||
@@ -316,6 +364,14 @@ class Command(BaseCommand):
|
||||
"Leave Management",
|
||||
"Performance Reviews",
|
||||
],
|
||||
"statuses": [
|
||||
("Application", "#6B7280", False),
|
||||
("Screening", "#3B82F6", False),
|
||||
("Interview", "#F59E0B", False),
|
||||
("Onboarding", "#8B5CF6", False),
|
||||
("Active", "#10B981", False),
|
||||
("Offboarding", "#EF4444", True),
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Staff Location Tracking Application",
|
||||
@@ -328,6 +384,14 @@ class Command(BaseCommand):
|
||||
"Mobile App Core",
|
||||
"Reporting & Analytics",
|
||||
],
|
||||
"statuses": [
|
||||
("Logged", "#6B7280", False),
|
||||
("Dispatched", "#3B82F6", False),
|
||||
("En Route", "#F59E0B", False),
|
||||
("On Site", "#8B5CF6", False),
|
||||
("Returning", "#06B6D4", False),
|
||||
("Completed", "#10B981", True),
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Ecommerce App",
|
||||
@@ -340,6 +404,14 @@ class Command(BaseCommand):
|
||||
"Push Notifications",
|
||||
"Mobile Checkout",
|
||||
],
|
||||
"statuses": [
|
||||
("Backlog", "#6B7280", False),
|
||||
("Design", "#8B5CF6", False),
|
||||
("Development", "#F59E0B", False),
|
||||
("QA", "#EC4899", False),
|
||||
("Beta Review", "#06B6D4", False),
|
||||
("Published", "#10B981", True),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -378,15 +450,7 @@ class Command(BaseCommand):
|
||||
|
||||
# ── Statuses ────────────────────────────────────────────────────
|
||||
statuses = []
|
||||
for i, (name, color, completed) in enumerate(
|
||||
[
|
||||
("Backlog", "#6B7280", False),
|
||||
("Todo", "#3B82F6", False),
|
||||
("In Progress", "#F59E0B", False),
|
||||
("In Review", "#8B5CF6", False),
|
||||
("Done", "#10B981", True),
|
||||
]
|
||||
):
|
||||
for i, (name, color, completed) in enumerate(pd["statuses"]):
|
||||
st, _ = TicketStatus.objects.get_or_create(
|
||||
project=proj,
|
||||
name=name,
|
||||
|
||||
@@ -49,3 +49,21 @@ class Command(BaseCommand):
|
||||
admin.role = "superadmin"
|
||||
admin.save()
|
||||
self.stdout.write(" -> superuser 'admin' already exists (role verified)")
|
||||
|
||||
if not User.objects.filter(username="manager").exists():
|
||||
mgr = User.objects.create_user(
|
||||
username="manager",
|
||||
email="manager@dewakoding.com",
|
||||
password="admin123",
|
||||
first_name="Project",
|
||||
last_name="Manager",
|
||||
)
|
||||
mgr.role = "manager"
|
||||
mgr.save()
|
||||
self.stdout.write(" -> manager created: manager / admin123")
|
||||
else:
|
||||
mgr = User.objects.get(username="manager")
|
||||
if mgr.role != "manager":
|
||||
mgr.role = "manager"
|
||||
mgr.save()
|
||||
self.stdout.write(" -> manager 'manager' already exists (role verified)")
|
||||
+34
-3
@@ -1,15 +1,46 @@
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.db import models
|
||||
|
||||
ADMIN_ROLES = ("superadmin", "manager")
|
||||
DEVELOPER_ROLES = (
|
||||
"backend_developer",
|
||||
"frontend_developer",
|
||||
"ui_ux_designer",
|
||||
"qa",
|
||||
"tester",
|
||||
"devops",
|
||||
"data_analyst",
|
||||
"product_owner",
|
||||
"scrum_master",
|
||||
)
|
||||
|
||||
|
||||
class User(AbstractUser):
|
||||
ROLE_CHOICES = (
|
||||
("superadmin", "Superadmin"),
|
||||
("manager", "Manager"),
|
||||
("member", "Member"),
|
||||
("guest", "Guest"),
|
||||
("backend_developer", "Backend Developer"),
|
||||
("frontend_developer", "Frontend Developer"),
|
||||
("ui_ux_designer", "UI/UX Designer"),
|
||||
("qa", "QA"),
|
||||
("tester", "Tester"),
|
||||
("devops", "DevOps"),
|
||||
("data_analyst", "Data Analyst"),
|
||||
("product_owner", "Product Owner"),
|
||||
("scrum_master", "Scrum Master"),
|
||||
)
|
||||
role = models.CharField(max_length=20, choices=ROLE_CHOICES, default="member")
|
||||
role = models.CharField(
|
||||
max_length=30, choices=ROLE_CHOICES, default="backend_developer"
|
||||
)
|
||||
|
||||
@property
|
||||
def is_admin(self):
|
||||
return self.role in ADMIN_ROLES
|
||||
|
||||
@property
|
||||
def is_developer(self):
|
||||
return not self.is_admin
|
||||
|
||||
google_id = models.CharField(max_length=255, blank=True, null=True, unique=True)
|
||||
profile_image = models.ImageField(upload_to="profiles/", blank=True, null=True)
|
||||
receive_deadline_emails = models.BooleanField(
|
||||
|
||||
@@ -18,9 +18,6 @@ from src.tickets.models import (
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
DEFAULT_STATUS_NAMES = ["Backlog", "Todo", "In Progress", "In Review", "Done"]
|
||||
DEFAULT_STATUS_COLORS = ["#6B7280", "#3B82F6", "#F59E0B", "#8B5CF6", "#10B981"]
|
||||
|
||||
|
||||
@require_http_methods(["POST"])
|
||||
def board_create_ticket(request, project_id):
|
||||
@@ -101,6 +98,16 @@ def move_ticket(request, project_id, ticket_id):
|
||||
)
|
||||
|
||||
status = get_object_or_404(TicketStatus, pk=status_id, project_id=project_id)
|
||||
|
||||
if not request.user.is_admin and status.is_completed:
|
||||
return JsonResponse(
|
||||
{
|
||||
"success": False,
|
||||
"error": "Members cannot move tickets to completed statuses.",
|
||||
},
|
||||
status=403,
|
||||
)
|
||||
|
||||
ticket.status = status
|
||||
ticket.save(update_fields=["status", "updated_at"])
|
||||
|
||||
|
||||
@@ -16,33 +16,10 @@ from src.tickets.models import (
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
DEFAULT_STATUS_NAMES = ["Backlog", "Todo", "In Progress", "In Review", "Done"]
|
||||
DEFAULT_STATUS_COLORS = ["#6B7280", "#3B82F6", "#F59E0B", "#8B5CF6", "#10B981"]
|
||||
|
||||
|
||||
def _ensure_default_statuses(project):
|
||||
# Auto-migrate legacy 'Review' to 'In Review' if it exists
|
||||
review_status = TicketStatus.objects.filter(project=project, name="Review").first()
|
||||
if review_status:
|
||||
in_review_status, created = TicketStatus.objects.get_or_create(
|
||||
project=project,
|
||||
name="In Review",
|
||||
defaults={"color": "#8B5CF6", "sort_order": 3},
|
||||
)
|
||||
Ticket.objects.filter(status=review_status).update(status=in_review_status)
|
||||
review_status.delete()
|
||||
|
||||
for i, name in enumerate(DEFAULT_STATUS_NAMES):
|
||||
TicketStatus.objects.get_or_create(
|
||||
project=project,
|
||||
name=name,
|
||||
defaults={"color": DEFAULT_STATUS_COLORS[i], "sort_order": i},
|
||||
)
|
||||
|
||||
|
||||
def project_board(request, project_id=None):
|
||||
projects = Project.objects.all()
|
||||
if request.user.role == "member":
|
||||
if not request.user.is_admin:
|
||||
projects = projects.filter(members=request.user)
|
||||
projects = projects.annotate(
|
||||
member_count=Count("members", distinct=True),
|
||||
@@ -68,7 +45,6 @@ def project_board(request, project_id=None):
|
||||
),
|
||||
pk=project_id,
|
||||
)
|
||||
_ensure_default_statuses(selected_project)
|
||||
project_members = selected_project.project_members.select_related("user").all()
|
||||
statuses = TicketStatus.objects.filter(project=selected_project).order_by(
|
||||
"sort_order"
|
||||
@@ -120,10 +96,12 @@ def project_board(request, project_id=None):
|
||||
}
|
||||
)
|
||||
|
||||
can_move = request.user.role in ["superadmin", "manager"] or (
|
||||
is_admin = request.user.is_admin
|
||||
can_move = is_admin or (
|
||||
selected_project
|
||||
and selected_project.members.filter(id=request.user.id).exists()
|
||||
)
|
||||
can_move_to_completed = is_admin
|
||||
|
||||
priorities = TicketPriority.objects.all()
|
||||
epics = Epic.objects.filter(project=selected_project) if selected_project else []
|
||||
@@ -174,12 +152,14 @@ def project_board(request, project_id=None):
|
||||
"selected_project_id": project_id,
|
||||
"selected_project": selected_project,
|
||||
"project_members": project_members,
|
||||
"is_admin": is_admin,
|
||||
"columns": columns,
|
||||
"priorities": priorities,
|
||||
"epics": epics,
|
||||
"sort": sort,
|
||||
"search": search,
|
||||
"can_move": can_move,
|
||||
"can_move_to_completed": can_move_to_completed,
|
||||
"today": date.today(),
|
||||
"project_users": project_users,
|
||||
"project_users_json": json.dumps(project_users),
|
||||
@@ -200,7 +180,6 @@ def project_board(request, project_id=None):
|
||||
@require_http_methods(["GET"])
|
||||
def board_data(request, project_id):
|
||||
project = get_object_or_404(Project, pk=project_id)
|
||||
_ensure_default_statuses(project)
|
||||
statuses = TicketStatus.objects.filter(project=project).order_by("sort_order")
|
||||
tickets = (
|
||||
Ticket.objects.filter(project=project)
|
||||
@@ -236,6 +215,8 @@ def board_data(request, project_id):
|
||||
priorities = TicketPriority.objects.all()
|
||||
epics = Epic.objects.filter(project=project)
|
||||
|
||||
user_can_move_to_completed = request.user.is_admin
|
||||
|
||||
return render(
|
||||
request,
|
||||
"projects/partials/board_columns.html",
|
||||
@@ -246,5 +227,6 @@ def board_data(request, project_id):
|
||||
"epics": epics,
|
||||
"sort": sort,
|
||||
"today": date.today(),
|
||||
"user_can_move_to_completed": user_can_move_to_completed,
|
||||
},
|
||||
)
|
||||
@@ -14,9 +14,6 @@ from src.tickets.models import (
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
DEFAULT_STATUS_NAMES = ["Backlog", "Todo", "In Progress", "In Review", "Done"]
|
||||
DEFAULT_STATUS_COLORS = ["#6B7280", "#3B82F6", "#F59E0B", "#8B5CF6", "#10B981"]
|
||||
|
||||
|
||||
@require_http_methods(["POST"])
|
||||
def export_board_tickets(request, project_id):
|
||||
|
||||
@@ -30,7 +30,7 @@ def site_stats(request):
|
||||
User = get_user_model()
|
||||
|
||||
total_users = User.objects.filter(is_active=True).count()
|
||||
if request.user.is_authenticated and request.user.role == "member":
|
||||
if request.user.is_authenticated and not request.user.is_admin:
|
||||
total_tickets = Ticket.objects.filter(assignees=request.user).count()
|
||||
else:
|
||||
total_tickets = Ticket.objects.count()
|
||||
|
||||
@@ -77,7 +77,7 @@ def projects_list(request):
|
||||
)
|
||||
|
||||
projects = Project.objects.annotate()
|
||||
if request.user.role == "member":
|
||||
if not request.user.is_admin:
|
||||
projects = projects.filter(members=request.user)
|
||||
projects = projects.annotate(
|
||||
member_count=Count("members", distinct=True),
|
||||
|
||||
@@ -81,7 +81,7 @@ def tickets_list(request):
|
||||
"status", "priority", "project", "created_by", "epic"
|
||||
).prefetch_related("assignees")
|
||||
|
||||
if request.user.role == "member":
|
||||
if not request.user.is_admin:
|
||||
tickets = tickets.filter(assignees=request.user)
|
||||
|
||||
# Search across name, uuid, project name, assignee name, creator name, epic name
|
||||
|
||||
@@ -141,7 +141,7 @@ def epic_delete(request, epic_id):
|
||||
|
||||
def epics_overview(request, project_id=None):
|
||||
projects = Project.objects.all()
|
||||
if request.user.role == "member":
|
||||
if not request.user.is_admin:
|
||||
projects = projects.filter(members=request.user)
|
||||
projects = projects.annotate(
|
||||
ticket_count=Count("tickets"),
|
||||
@@ -154,7 +154,7 @@ def epics_overview(request, project_id=None):
|
||||
if project_id:
|
||||
selected_project = get_object_or_404(Project, pk=project_id)
|
||||
if (
|
||||
request.user.role == "member"
|
||||
not request.user.is_admin
|
||||
and not selected_project.members.filter(id=request.user.id).exists()
|
||||
):
|
||||
from django.contrib import messages
|
||||
|
||||
@@ -283,7 +283,7 @@ def ticket_priorities(request):
|
||||
|
||||
@require_http_methods(["POST"])
|
||||
def ticket_priority_add(request):
|
||||
if request.user.role == "member":
|
||||
if not request.user.is_admin:
|
||||
messages.error(request, "Permission denied.")
|
||||
return redirect("ticket-priorities")
|
||||
name = request.POST.get("name", "").strip()
|
||||
@@ -298,7 +298,7 @@ def ticket_priority_add(request):
|
||||
|
||||
@require_http_methods(["POST"])
|
||||
def ticket_priority_edit(request, priority_id):
|
||||
if request.user.role == "member":
|
||||
if not request.user.is_admin:
|
||||
messages.error(request, "Permission denied.")
|
||||
return redirect("ticket-priorities")
|
||||
priority = get_object_or_404(TicketPriority, pk=priority_id)
|
||||
@@ -316,7 +316,7 @@ def ticket_priority_edit(request, priority_id):
|
||||
|
||||
@require_http_methods(["POST"])
|
||||
def ticket_priority_delete(request, priority_id):
|
||||
if request.user.role == "member":
|
||||
if not request.user.is_admin:
|
||||
messages.error(request, "Permission denied.")
|
||||
return redirect("ticket-priorities")
|
||||
priority = get_object_or_404(TicketPriority, pk=priority_id)
|
||||
|
||||
@@ -16,7 +16,6 @@ from src.projects.models import Project, ProjectMember
|
||||
from src.tickets.models import (
|
||||
Ticket,
|
||||
TicketPriority,
|
||||
TicketStatus,
|
||||
)
|
||||
|
||||
User = get_user_model()
|
||||
@@ -48,7 +47,7 @@ COLOR_PALETTE = [
|
||||
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def project_create(request):
|
||||
if request.user.role == "member":
|
||||
if not request.user.is_admin:
|
||||
from django.contrib import messages
|
||||
from django.shortcuts import redirect
|
||||
|
||||
@@ -88,23 +87,6 @@ def project_create(request):
|
||||
except User.DoesNotExist:
|
||||
pass
|
||||
|
||||
if request.POST.get("use_default_statuses") == "1":
|
||||
default_statuses = ["Backlog", "Todo", "In Progress", "In Review", "Done"]
|
||||
for i, sname in enumerate(default_statuses):
|
||||
TicketStatus.objects.create(
|
||||
project=project,
|
||||
name=sname,
|
||||
sort_order=i,
|
||||
is_completed=(sname == "Done"),
|
||||
color={
|
||||
"Backlog": "#6B7280",
|
||||
"Todo": "#3B82F6",
|
||||
"In Progress": "#F59E0B",
|
||||
"In Review": "#8B5CF6",
|
||||
"Done": "#10B981",
|
||||
}.get(sname, "#6B7280"),
|
||||
)
|
||||
|
||||
messages.success(request, f"Project '{project.name}' created successfully.")
|
||||
|
||||
if request.POST.get("create_another") == "1":
|
||||
@@ -308,6 +290,7 @@ def project_detail(request, project_id):
|
||||
"pinned_display": pinned_display,
|
||||
"today": today,
|
||||
"external_access": external_access,
|
||||
"is_admin": request.user.is_admin,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -498,7 +481,7 @@ def project_edit(request, project_id):
|
||||
|
||||
@require_http_methods(["POST"])
|
||||
def project_delete(request, project_id):
|
||||
if request.user.role == "member":
|
||||
if not request.user.is_admin:
|
||||
from django.contrib import messages
|
||||
from django.shortcuts import redirect
|
||||
|
||||
@@ -529,7 +512,7 @@ def project_timeline(request):
|
||||
projects_qs = Project.objects.filter(
|
||||
start_date__isnull=False, end_date__isnull=False
|
||||
)
|
||||
if request.user.role == "member":
|
||||
if not request.user.is_admin:
|
||||
projects_qs = projects_qs.filter(members=request.user)
|
||||
projects_qs = projects_qs.order_by("start_date")
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ COLOR_PALETTE = [
|
||||
|
||||
def ticket_timeline(request, project_id=None):
|
||||
projects = Project.objects.all()
|
||||
if request.user.role == "member":
|
||||
if not request.user.is_admin:
|
||||
projects = projects.filter(members=request.user)
|
||||
projects = projects.annotate(
|
||||
ticket_count=Count("tickets"),
|
||||
@@ -482,7 +482,7 @@ def tickets_export(request):
|
||||
tickets = Ticket.objects.select_related(
|
||||
"project", "status", "priority", "created_by", "epic"
|
||||
)
|
||||
if request.user.role == "member":
|
||||
if not request.user.is_admin:
|
||||
tickets = tickets.filter(assignees=request.user)
|
||||
tickets = (
|
||||
tickets.select_related("status", "priority", "project", "created_by", "epic")
|
||||
|
||||
@@ -107,12 +107,31 @@ def users_list(request):
|
||||
"has_created": has_created,
|
||||
"role": role,
|
||||
"unverified": unverified,
|
||||
"roles": ["superadmin", "manager", "member", "guest"],
|
||||
"roles": [
|
||||
"superadmin",
|
||||
"manager",
|
||||
"backend_developer",
|
||||
"frontend_developer",
|
||||
"ui_ux_designer",
|
||||
"qa",
|
||||
"tester",
|
||||
"devops",
|
||||
"data_analyst",
|
||||
"product_owner",
|
||||
"scrum_master",
|
||||
],
|
||||
"roles_label": {
|
||||
"superadmin": "Superadmin",
|
||||
"manager": "Manager",
|
||||
"member": "Member",
|
||||
"guest": "Guest",
|
||||
"backend_developer": "Backend Developer",
|
||||
"frontend_developer": "Frontend Developer",
|
||||
"ui_ux_designer": "UI/UX Designer",
|
||||
"qa": "QA",
|
||||
"tester": "Tester",
|
||||
"devops": "DevOps",
|
||||
"data_analyst": "Data Analyst",
|
||||
"product_owner": "Product Owner",
|
||||
"scrum_master": "Scrum Master",
|
||||
},
|
||||
"per_page": per_page,
|
||||
"columns": columns,
|
||||
@@ -157,7 +176,7 @@ def user_create(request):
|
||||
user = form.save()
|
||||
user.is_active = True
|
||||
if request.user.role == "superadmin":
|
||||
role = request.POST.get("role", "member")
|
||||
role = request.POST.get("role", "backend_developer")
|
||||
user.role = role
|
||||
user.save()
|
||||
messages.success(
|
||||
@@ -173,12 +192,31 @@ def user_create(request):
|
||||
"users/form.html",
|
||||
{
|
||||
"form": form,
|
||||
"roles": ["superadmin", "manager", "member", "guest"],
|
||||
"roles": [
|
||||
"superadmin",
|
||||
"manager",
|
||||
"backend_developer",
|
||||
"frontend_developer",
|
||||
"ui_ux_designer",
|
||||
"qa",
|
||||
"tester",
|
||||
"devops",
|
||||
"data_analyst",
|
||||
"product_owner",
|
||||
"scrum_master",
|
||||
],
|
||||
"roles_label": {
|
||||
"superadmin": "Superadmin",
|
||||
"manager": "Manager",
|
||||
"member": "Member",
|
||||
"guest": "Guest",
|
||||
"backend_developer": "Backend Developer",
|
||||
"frontend_developer": "Frontend Developer",
|
||||
"ui_ux_designer": "UI/UX Designer",
|
||||
"qa": "QA",
|
||||
"tester": "Tester",
|
||||
"devops": "DevOps",
|
||||
"data_analyst": "Data Analyst",
|
||||
"product_owner": "Product Owner",
|
||||
"scrum_master": "Scrum Master",
|
||||
},
|
||||
"can_change_role": request.user.role == "superadmin",
|
||||
},
|
||||
@@ -204,8 +242,15 @@ def user_detail(request, user_id):
|
||||
"roles_label": {
|
||||
"superadmin": "Superadmin",
|
||||
"manager": "Manager",
|
||||
"member": "Member",
|
||||
"guest": "Guest",
|
||||
"backend_developer": "Backend Developer",
|
||||
"frontend_developer": "Frontend Developer",
|
||||
"ui_ux_designer": "UI/UX Designer",
|
||||
"qa": "QA",
|
||||
"tester": "Tester",
|
||||
"devops": "DevOps",
|
||||
"data_analyst": "Data Analyst",
|
||||
"product_owner": "Product Owner",
|
||||
"scrum_master": "Scrum Master",
|
||||
},
|
||||
"projects_count": project_count,
|
||||
"assigned_count": assigned_count,
|
||||
@@ -254,7 +299,7 @@ def user_edit(request, user_id):
|
||||
if form.is_valid():
|
||||
user_obj = form.save()
|
||||
if request.user.role == "superadmin":
|
||||
role = request.POST.get("role", "member")
|
||||
role = request.POST.get("role", "backend_developer")
|
||||
user_obj.role = role
|
||||
user_obj.save()
|
||||
messages.success(
|
||||
@@ -301,12 +346,31 @@ def user_edit(request, user_id):
|
||||
"editing": True,
|
||||
"user_obj": user_obj,
|
||||
"current_role": current_role,
|
||||
"roles": ["superadmin", "manager", "member", "guest"],
|
||||
"roles": [
|
||||
"superadmin",
|
||||
"manager",
|
||||
"backend_developer",
|
||||
"frontend_developer",
|
||||
"ui_ux_designer",
|
||||
"qa",
|
||||
"tester",
|
||||
"devops",
|
||||
"data_analyst",
|
||||
"product_owner",
|
||||
"scrum_master",
|
||||
],
|
||||
"roles_label": {
|
||||
"superadmin": "Superadmin",
|
||||
"manager": "Manager",
|
||||
"member": "Member",
|
||||
"guest": "Guest",
|
||||
"backend_developer": "Backend Developer",
|
||||
"frontend_developer": "Frontend Developer",
|
||||
"ui_ux_designer": "UI/UX Designer",
|
||||
"qa": "QA",
|
||||
"tester": "Tester",
|
||||
"devops": "DevOps",
|
||||
"data_analyst": "Data Analyst",
|
||||
"product_owner": "Product Owner",
|
||||
"scrum_master": "Scrum Master",
|
||||
},
|
||||
"can_change_role": request.user.role == "superadmin",
|
||||
"user_memberships": proj_page,
|
||||
|
||||
@@ -13,7 +13,7 @@ User = get_user_model()
|
||||
@require_http_methods(["GET"])
|
||||
def recent_activity(request):
|
||||
user = request.user
|
||||
is_super = user.role in ["superadmin", "manager"]
|
||||
is_super = user.is_admin
|
||||
|
||||
qs = TicketHistory.objects.select_related(
|
||||
"ticket", "user", "status", "ticket__project"
|
||||
@@ -37,7 +37,7 @@ def recent_activity(request):
|
||||
@require_http_methods(["GET"])
|
||||
def recent_activity_all(request):
|
||||
user = request.user
|
||||
is_super = user.role in ["superadmin", "manager"]
|
||||
is_super = user.is_admin
|
||||
|
||||
qs = TicketHistory.objects.select_related(
|
||||
"ticket", "user", "status", "ticket__project"
|
||||
|
||||
@@ -17,7 +17,7 @@ User = get_user_model()
|
||||
@require_http_methods(["GET"])
|
||||
def tickets_per_project_chart(request):
|
||||
user = request.user
|
||||
is_super = user.role in ["superadmin", "manager"]
|
||||
is_super = user.is_admin
|
||||
|
||||
qs = Project.objects.annotate(count=Count("tickets")).order_by("name")
|
||||
if not is_super:
|
||||
@@ -53,7 +53,7 @@ def tickets_per_project_chart(request):
|
||||
@require_http_methods(["GET"])
|
||||
def user_statistics_data(request):
|
||||
user = request.user
|
||||
is_super = user.role in ["superadmin", "manager"]
|
||||
is_super = user.is_admin
|
||||
|
||||
users_qs = User.objects.annotate(
|
||||
project_count=Count("projects", distinct=True),
|
||||
@@ -80,7 +80,7 @@ def user_statistics_chart(request):
|
||||
@require_http_methods(["GET"])
|
||||
def monthly_trend_chart(request):
|
||||
user = request.user
|
||||
is_super = user.role in ["superadmin", "manager"]
|
||||
is_super = user.is_admin
|
||||
|
||||
earliest = Ticket.objects.all()
|
||||
if not is_super:
|
||||
|
||||
@@ -21,7 +21,7 @@ def dashboard(request):
|
||||
days=now.weekday()
|
||||
)
|
||||
|
||||
is_super = user.role in ["superadmin", "manager"]
|
||||
is_super = user.is_admin
|
||||
|
||||
if is_super:
|
||||
total_projects = Project.objects.count()
|
||||
@@ -204,7 +204,7 @@ def stats_cards(request):
|
||||
days=now.weekday()
|
||||
)
|
||||
|
||||
is_super = user.role in ["superadmin", "manager"]
|
||||
is_super = user.is_admin
|
||||
|
||||
if is_super:
|
||||
total_projects = Project.objects.count()
|
||||
|
||||
@@ -13,10 +13,10 @@ User = get_user_model()
|
||||
def project_timeline_widget(request):
|
||||
filter_type = request.GET.get("filter", "pinned")
|
||||
user = request.user
|
||||
is_super = user.role in ["superadmin", "manager"]
|
||||
is_super = user.is_admin
|
||||
|
||||
qs = Project.objects.filter(start_date__isnull=False, end_date__isnull=False)
|
||||
if request.user.role == "member":
|
||||
if not request.user.is_admin:
|
||||
qs = qs.filter(members=request.user)
|
||||
if not is_super:
|
||||
qs = qs.filter(members=user)
|
||||
|
||||
Reference in new issue
Block a user