Skip to content

Commit 089bb87

Browse files
authored
Merge pull request #2555 from gtech-mulearn/dev
Editable Ig pages and role assign when editing ig
2 parents 192024d + adeb331 commit 089bb87

File tree

4 files changed

+167
-2
lines changed

4 files changed

+167
-2
lines changed

api/dashboard/ig/dash_ig_serializer.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from rest_framework import serializers
2+
import json
23

34
from db.task import InterestGroup
45

@@ -17,6 +18,16 @@ class Meta:
1718
fields = [
1819
"id",
1920
"name",
21+
"resource",
22+
"about",
23+
"prerequisites",
24+
"career_opportunities",
25+
"top_blogs",
26+
"people_to_follow",
27+
"leads",
28+
"mentors",
29+
"thinktank",
30+
"office_hours",
2031
"icon",
2132
"code",
2233
"category",
@@ -30,9 +41,50 @@ class Meta:
3041
def get_members(self, obj):
3142
return obj.user_ig_link_ig.all().count()
3243

44+
def to_representation(self, instance):
45+
"""Convert JSON-serialized text fields back to Python objects for API output."""
46+
data = super().to_representation(instance)
47+
json_fields = [
48+
"prerequisites",
49+
"career_opportunities",
50+
"top_blogs",
51+
"people_to_follow",
52+
"mentors",
53+
"leads",
54+
]
55+
56+
for field in json_fields:
57+
val = data.get(field)
58+
if isinstance(val, str) and val:
59+
try:
60+
parsed = json.loads(val)
61+
data[field] = parsed
62+
except Exception:
63+
# leave as-is (plain string)
64+
pass
65+
66+
return data
67+
3368

3469
class InterestGroupCreateUpdateSerializer(serializers.ModelSerializer):
3570

3671
class Meta:
3772
model = InterestGroup
38-
fields = ["name", "code", "category", "icon", "created_by", "updated_by"]
73+
fields = [
74+
"name",
75+
"code",
76+
"category",
77+
"icon",
78+
"about",
79+
"prerequisites",
80+
"career_opportunities",
81+
"resource",
82+
"top_blogs",
83+
"people_to_follow",
84+
"leads",
85+
"mentors",
86+
"thinktank",
87+
"office_hours",
88+
"created_by",
89+
"updated_by",
90+
]

api/dashboard/ig/dash_ig_view.py

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
InterestGroupSerializer,
1212
InterestGroupCreateUpdateSerializer,
1313
)
14+
import json
1415
from django.utils.decorators import method_decorator
1516
from django.views.decorators.cache import cache_page
1617
from api.dashboard.roles.dash_roles_serializer import RoleDashboardSerializer
@@ -59,6 +60,21 @@ def post(self, request):
5960

6061
request_data = request.data
6162

63+
# serialize JSON-able fields to strings for DB storage
64+
for fld in [
65+
"prerequisites",
66+
"career_opportunities",
67+
"top_blogs",
68+
"people_to_follow",
69+
"leads",
70+
"mentors",
71+
]:
72+
if fld in request_data and not isinstance(request_data.get(fld), str):
73+
try:
74+
request_data[fld] = json.dumps(request_data.get(fld))
75+
except Exception:
76+
pass
77+
6278
request_data["created_by"] = request_data["updated_by"] = user_id
6379

6480
serializer = InterestGroupCreateUpdateSerializer(
@@ -142,6 +158,19 @@ def put(self, request, pk):
142158
ig_old_code = ig.code
143159

144160
request_data = request.data
161+
for fld in [
162+
"prerequisites",
163+
"career_opportunities",
164+
"top_blogs",
165+
"people_to_follow",
166+
"leads",
167+
"mentors",
168+
]:
169+
if fld in request_data and not isinstance(request_data.get(fld), str):
170+
try:
171+
request_data[fld] = json.dumps(request_data.get(fld))
172+
except Exception:
173+
pass
145174
request_data["updated_by"] = user_id
146175

147176
serializer = InterestGroupCreateUpdateSerializer(
@@ -243,7 +272,6 @@ def get(self, request):
243272

244273
class InterestGroupGetAPI(APIView):
245274
authentication_classes = [CustomizePermission]
246-
247275
@role_required([RoleType.ADMIN.value])
248276
def get(self, request, pk):
249277
ig_data = InterestGroup.objects.filter(id=pk).first()
@@ -259,6 +287,44 @@ def get(self, request, pk):
259287
response={"interestGroup": serializer.data}
260288
).get_success_response()
261289

290+
@role_required([RoleType.ADMIN.value])
291+
def patch(self, request, pk):
292+
"""Allow IG Lead or Admin to update IG editable fields."""
293+
user_id = JWTUtils.fetch_user_id(request)
294+
roles = JWTUtils.fetch_role(request)
295+
ig = InterestGroup.objects.filter(id=pk).first()
296+
if not ig:
297+
return CustomResponse(general_message="Interest Group Does Not Exist").get_failure_response()
298+
299+
# Permission: Admins or IG Lead role for this IG code
300+
ig_lead_role_title = RoleType.IG_LEAD_ROLE(ig.code)
301+
if (RoleType.ADMIN.value not in roles) and (ig_lead_role_title not in roles):
302+
return CustomResponse(general_message="You do not have permission to update this Interest Group").get_failure_response()
303+
304+
request_data = request.data
305+
for fld in [
306+
"prerequisites",
307+
"career_opportunities",
308+
"top_blogs",
309+
"people_to_follow",
310+
"leads",
311+
"mentors",
312+
]:
313+
if fld in request_data and not isinstance(request_data.get(fld), str):
314+
try:
315+
request_data[fld] = json.dumps(request_data.get(fld))
316+
except Exception:
317+
pass
318+
request_data["updated_by"] = user_id
319+
320+
serializer = InterestGroupCreateUpdateSerializer(data=request_data, instance=ig, partial=True)
321+
322+
if serializer.is_valid():
323+
serializer.save()
324+
return CustomResponse(response={"interestGroup": serializer.data}).get_success_response()
325+
326+
return CustomResponse(message=serializer.errors).get_failure_response()
327+
262328

263329
class InterestGroupListApi(APIView):
264330
@method_decorator(cache_page(60 * 10))

api/dashboard/profile/profile_view.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
from rest_framework.views import APIView
1313
from django.db.models import Sum
1414
from django.core.cache import cache
15+
from db.user import Role, UserRoleLink
16+
1517
from django.utils.timezone import now
1618

1719
from db.organization import UserOrganizationLink
@@ -103,6 +105,11 @@ def patch(self, request):
103105
user_id = JWTUtils.fetch_user_id(request)
104106
user = User.objects.get(id=user_id)
105107

108+
old_ig_links = list(user.user_ig_link_user.all())
109+
old_ig_ids = set(link.ig_id for link in old_ig_links)
110+
old_role_links = list(user.user_role_link_user.all())
111+
old_role_ids = set(link.role_id for link in old_role_links)
112+
106113
serializer = profile_serializer.UserIgEditSerializer(
107114
user, data=request.data, partial=True
108115
)
@@ -111,6 +118,36 @@ def patch(self, request):
111118
return CustomResponse(response=serializer.errors).get_failure_response()
112119

113120
serializer.save()
121+
new_ig_links = list(user.user_ig_link_user.all())
122+
new_ig_ids = set(link.ig_id for link in new_ig_links)
123+
124+
old_ig_roles = set()
125+
for ig_id in old_ig_ids:
126+
ig = InterestGroup.objects.filter(id=ig_id).first()
127+
if ig:
128+
role = Role.objects.filter(title=ig.name).first()
129+
if role:
130+
old_ig_roles.add(role.id)
131+
UserRoleLink.objects.filter(user=user, role_id__in=old_ig_roles).delete()
132+
133+
134+
new_ig_roles = set()
135+
for ig_id in new_ig_ids:
136+
ig = InterestGroup.objects.filter(id=ig_id).first()
137+
if ig:
138+
role = Role.objects.filter(title=ig.name).first()
139+
if role:
140+
new_ig_roles.add(role.id)
141+
142+
for role_id in new_ig_roles:
143+
if not UserRoleLink.objects.filter(user=user, role_id=role_id).exists():
144+
UserRoleLink.objects.create(
145+
user=user,
146+
role_id=role_id,
147+
created_by=user,
148+
verified=True,
149+
)
150+
114151
DiscordWebhooks.general_updates(
115152
WebHookCategory.USER.value,
116153
WebHookActions.UPDATE.value,

db/task.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ class InterestGroup(models.Model):
4141
code = models.CharField(max_length=10, unique=True)
4242
icon = models.CharField(max_length=10)
4343
category =models.CharField(max_length=20,default="others",blank=False,null=False)
44+
about = models.TextField(blank=True, null=True)
45+
prerequisites = models.TextField(blank=True, null=True)
46+
career_opportunities = models.TextField(blank=True, null=True)
47+
top_blogs = models.TextField(blank=True, null=True)
48+
people_to_follow = models.TextField(blank=True, null=True)
49+
resource = models.TextField(blank=True, null=True)
50+
leads = models.TextField(blank=True, null=True)
51+
mentors = models.TextField(blank=True, null=True)
52+
thinktank = models.TextField(blank=True, null=True)
53+
office_hours = models.CharField(max_length=200, blank=True, null=True)
4454
updated_by = models.ForeignKey(User, on_delete=models.SET(settings.SYSTEM_ADMIN_ID), db_column="updated_by",
4555
related_name="interest_group_updated_by")
4656
updated_at = models.DateTimeField(auto_now=True)

0 commit comments

Comments
 (0)