Skip to content

Commit 1de4ede

Browse files
authored
Merge pull request #71 from joanmdrs/bug/issue69
Bug/issue69
2 parents c257b29 + d77bb75 commit 1de4ede

File tree

42 files changed

+441
-169
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+441
-169
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 5.0.3 on 2025-03-30 17:34
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('feedback', '0001_initial'),
10+
]
11+
12+
operations = [
13+
migrations.AlterField(
14+
model_name='feedback',
15+
name='tipo',
16+
field=models.CharField(choices=[('sugestao', 'Sugestão'), ('reclamacao', 'Reclamação'), ('bug', 'Bug'), ('nova_funcionalidade', 'Nova Funcionalidade'), ('melhoria_funcionalidade', 'Melhoria de Funcionalidade'), ('experiencia_usuario', 'Experiência do Usuário'), ('duvida_uso', 'Dúvida sobre o uso'), ('problema_acessibilidade', 'Problemas de Acessibilidade')]),
17+
),
18+
]

apps/feedback/models.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ class Feedback(models.Model):
66
TIPOS = [
77
('sugestao', 'Sugestão'),
88
('reclamacao', 'Reclamação'),
9+
('bug', 'Bug'),
10+
('nova_funcionalidade', 'Nova Funcionalidade'),
11+
('melhoria_funcionalidade', 'Melhoria de Funcionalidade'),
12+
('experiencia_usuario', 'Experiência do Usuário'),
13+
('duvida_uso', 'Dúvida sobre o uso'),
14+
('problema_acessibilidade', 'Problemas de Acessibilidade')
15+
916
]
1017

1118
STATUS = [
@@ -16,7 +23,7 @@ class Feedback(models.Model):
1623

1724
titulo = models.CharField(max_length=200)
1825
descricao = models.TextField()
19-
tipo = models.CharField(max_length=10, choices=TIPOS)
26+
tipo = models.CharField(choices=TIPOS)
2027
status = models.CharField(max_length=15, choices=STATUS, default='pendente')
2128
created_at = models.DateTimeField(auto_now_add=True)
2229
created_by = models.ForeignKey(

apps/membro/urls.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
path('listar/', ListarMembrosView.as_view(), name='listar_membros_por_lista_ids'),
1414
path('buscar-por-nome/', BuscarMembrosPorNomeView.as_view(), name='buscar_membro_por_nome'),
1515
path('buscar-por-id/', BuscarMembroPorIdView.as_view(), name='buscar_membro_por_id'),
16-
path('buscar-por-nome-e-grupo/', BuscarMembroPorGrupoView.as_view(), name='buscar_membro_por_nome_e_grupo'),
16+
path('buscar-por-grupo/', BuscarMembroPorGrupoView.as_view(), name='buscar_membro_por_nome_e_grupo'),
1717
path('buscar-por-id-usuario/', BuscarMembroPorIdUsuarioView.as_view(), name='buscar_membro_por_usuario'),
1818
path('buscar-usuario-github/<int:id_membro_projeto>/', BuscarUsuarioPorIdMembroProjeto.as_view(), name='buscar_usuario_github_pelo_id_membro_projeto'),
1919
path('listar-grupos/', ListarGruposView.as_view(), name='listar_grupos_de_usuário'),

apps/membro/views.py

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -114,38 +114,44 @@ def get(self, request):
114114

115115
except Exception as e:
116116
return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
117-
117+
118+
118119
class BuscarMembroPorGrupoView(APIView):
119120
permission_classes = [IsAuthenticated]
120121

121122
def get(self, request):
122123
try:
123-
nome = request.query_params.get('nome', None)
124-
group_member = request.query_params.get('grupo', None)
124+
# Obtém os IDs dos grupos como uma string (exemplo: "1,2,3")
125+
grupos_ids_str = request.GET.get('grupos_ids', '')
126+
127+
if not grupos_ids_str:
128+
return Response({'error': 'Parâmetro grupos_ids não fornecido!'}, status=status.HTTP_400_BAD_REQUEST)
125129

126-
if not group_member:
127-
return Response({'error': 'Parâmetro grupo não fornecido!'}, status=status.HTTP_400_BAD_REQUEST)
130+
# Converte a string em uma lista de inteiros
131+
try:
132+
grupos_ids = [int(id.strip()) for id in grupos_ids_str.split(',') if id.strip().isdigit()]
133+
except ValueError:
134+
return Response({'error': 'IDs dos grupos devem ser números inteiros!'}, status=status.HTTP_400_BAD_REQUEST)
128135

129-
# Busca o grupo pelo nome
130-
group = Group.objects.filter(name=group_member).first()
136+
if not grupos_ids:
137+
return Response({'error': 'Nenhum ID de grupo válido fornecido!'}, status=status.HTTP_400_BAD_REQUEST)
131138

132-
if not group:
133-
return Response({'error': 'Grupo não encontrado!'}, status=status.HTTP_404_NOT_FOUND)
139+
# Filtra os grupos pelos IDs
140+
grupos = Group.objects.filter(id__in=grupos_ids)
134141

135-
# Filtra membros cujo usuário pertence ao grupo
136-
membros = Membro.objects.filter(usuario__groups=group)
142+
if not grupos.exists():
143+
return Response({'error': 'Nenhum grupo encontrado com os IDs fornecidos!'}, status=status.HTTP_404_NOT_FOUND)
137144

138-
# Filtra por nome, se fornecido
139-
if nome:
140-
membros = membros.filter(nome__icontains=nome)
145+
# Busca membros cujos usuários pertencem a esses grupos
146+
membros = Membro.objects.filter(usuario__groups__in=grupos).distinct()
141147

142-
# Serializa os resultados
143148
serializer = MembroSerializer(membros, many=True)
144149

145-
return Response({'message': 'Membros encontrados com sucesso.', 'results': serializer.data}, status=status.HTTP_200_OK)
150+
return Response(serializer.data, status=status.HTTP_200_OK)
146151

147152
except Exception as e:
148153
return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
154+
149155

150156
class BuscarMembroPorIdUsuarioView(APIView):
151157
permission_classes = [IsAuthenticated]

apps/membro_projeto/serializers.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class MembroProjetoSerializer(serializers.ModelSerializer):
2828
funcoes_membro = serializers.SerializerMethodField()
2929
equipe = serializers.SerializerMethodField()
3030
dados_projeto = serializers.SerializerMethodField()
31+
coordenador = serializers.SerializerMethodField()
32+
nome_coordenador = serializers.SerializerMethodField()
3133

3234
class Meta:
3335
model = MembroProjeto
@@ -39,6 +41,8 @@ class Meta:
3941
'descricao_projeto',
4042
'grupo',
4143
'nome_grupo',
44+
'coordenador',
45+
'nome_coordenador',
4246
'usuario_github',
4347
'status_projeto',
4448
'data_inicio_projeto',
@@ -53,6 +57,16 @@ class Meta:
5357
'dados_projeto'
5458
]
5559

60+
def get_coordenador(self, obj):
61+
if obj.projeto.coordenador:
62+
return obj.projeto.coordenador.id
63+
return None
64+
65+
def get_nome_coordenador(self, obj):
66+
if obj.projeto.coordenador:
67+
return obj.projeto.coordenador.nome
68+
return None
69+
5670
def get_grupo(self, obj):
5771
if obj.membro.usuario and obj.membro.usuario.groups.exists():
5872
return obj.membro.usuario.groups.first().id
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Generated by Django 5.0.3 on 2025-03-30 18:23
2+
3+
import django.db.models.deletion
4+
from django.db import migrations, models
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('membro', '0005_remove_membro_grupo_alter_membro_avatar'),
11+
('projeto', '0003_alter_projeto_status'),
12+
]
13+
14+
operations = [
15+
migrations.AddField(
16+
model_name='projeto',
17+
name='coordenador',
18+
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='coordenador', to='membro.membro'),
19+
),
20+
]

apps/projeto/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class Projeto(models.Model):
2323
link_repo = models.CharField(max_length=200, null=True, blank=True)
2424
link_site = models.CharField(max_length=200, null=True, blank=True)
2525
token = models.CharField(max_length=200, null=True, blank=True)
26+
coordenador = models.ForeignKey(Membro, on_delete=models.SET_NULL, related_name='coordenador', null=True, blank=True)
2627
fluxo = models.ForeignKey(Fluxo, on_delete=models.SET_NULL, related_name='projetos', null=True, blank=True)
2728

2829
def __str__(self):

apps/projeto/serializers.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,19 @@ class Meta:
1818
'link_repo',
1919
'link_site',
2020
'token',
21+
'coordenador',
2122
'fluxo',
2223
'nome_fluxo']
2324

2425
def get_nome_fluxo(self, obj):
2526
if obj.fluxo:
2627
return obj.fluxo.nome
2728
return None
29+
30+
def get_nome_coordenador(self, obj):
31+
if obj.coordenador:
32+
return obj.coordenador.nome
33+
return None
2834

2935

3036

5.93 KB
Binary file not shown.

frontend/academic_dev_flow/public/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
<html lang="en">
33
<head>
44
<meta charset="utf-8" />
5-
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
5+
66
<meta name="viewport" content="width=device-width, initial-scale=1" />
77
<meta name="theme-color" content="#000000" />
88
<meta
99
name="description"
1010
content="Web site created using create-react-app"
1111
/>
12-
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
12+
<link rel="icon" type="image/x-icon" href="%PUBLIC_URL%/favicon.ico" />
1313
<!--
1414
manifest.json provides metadata used when your web app is installed on a
1515
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
@@ -24,7 +24,7 @@
2424
work correctly both with client-side routing and a non-root public URL.
2525
Learn how to configure a non-root public URL by running `npm run build`.
2626
-->
27-
<title>React App</title>
27+
<title>Academic Flow</title>
2828
</head>
2929
<body>
3030
<noscript>You need to enable JavaScript to run this app.</noscript>

0 commit comments

Comments
 (0)