Norberto Montalvo García commited on
Commit
18da12f
·
unverified ·
2 Parent(s): b5cf713 ac76757

Merge pull request #10 from CascoArcilla/HU4

Browse files

Se agrega monitoreo para revisar los catadores activos

tecnicas/controllers/__init__.py CHANGED
@@ -15,4 +15,5 @@ from .models_controller.dato_controller import DatoController
15
  from .views_controller.detalles_sesion_controller import DetallesSesionController
16
  from .views_controller.login_tester_controller import LoginTesterController
17
  from .views_controller.main_tester_form_controller import MainTesterFormController
18
- from .views_controller.api_rating_controller import ApiRatingController
 
 
15
  from .views_controller.detalles_sesion_controller import DetallesSesionController
16
  from .views_controller.login_tester_controller import LoginTesterController
17
  from .views_controller.main_tester_form_controller import MainTesterFormController
18
+ from .views_controller.api_rating_controller import ApiRatingController
19
+ from .views_controller.monitor_sesion_controller import MonitorSesionController
tecnicas/controllers/models_controller/particiapacion_controller.py CHANGED
@@ -1,4 +1,4 @@
1
- from ...models import Participacion
2
  from ...utils import controller_error
3
 
4
 
@@ -34,3 +34,15 @@ class ParticipacionController():
34
  return participation
35
  except Participacion.DoesNotExist:
36
  return controller_error("No se ha encontrado la participación")
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ...models import Participacion, Tecnica
2
  from ...utils import controller_error
3
 
4
 
 
34
  return participation
35
  except Participacion.DoesNotExist:
36
  return controller_error("No se ha encontrado la participación")
37
+
38
+ @staticmethod
39
+ def getParticipationsInTechinique(technique: Tecnica| int):
40
+ filters = {}
41
+
42
+ if isinstance(technique, int):
43
+ filters["tecnica_id"] = technique
44
+ else:
45
+ filters["tecnica"] = technique
46
+
47
+ participations = list(Participacion.objects.filter(**filters))
48
+ return participations
tecnicas/controllers/views_controller/login_tester_controller.py CHANGED
@@ -56,7 +56,8 @@ class LoginTesterController():
56
 
57
  self.taster_participation = Participacion.objects.create(
58
  tecnica=self.session.tecnica,
59
- catador=self.tester
 
60
  )
61
 
62
  return self.taster_participation
 
56
 
57
  self.taster_participation = Participacion.objects.create(
58
  tecnica=self.session.tecnica,
59
+ catador=self.tester,
60
+ finalizado=False
61
  )
62
 
63
  return self.taster_participation
tecnicas/controllers/views_controller/monitor_sesion_controller.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from tecnicas.models import SesionSensorial
2
+ from tecnicas.controllers import ParticipacionController
3
+ from tecnicas.utils import controller_error
4
+
5
+
6
+ class MonitorSesionController():
7
+ def __init__(self, session_code: str):
8
+ self.code_session = session_code
9
+
10
+ def monitorView(self):
11
+ try:
12
+ self.sensorial_session = SesionSensorial.objects.select_related(
13
+ "tecnica"
14
+ ).only(
15
+ "nombre_sesion",
16
+ "tecnica__limite_catadores",
17
+ ).get(codigo_sesion=self.code_session)
18
+
19
+ self.participations = ParticipacionController.getParticipationsInTechinique(
20
+ self.sensorial_session.tecnica)
21
+ except SesionSensorial.DoesNotExist as error:
22
+ return controller_error("No existe Sesión sensorial")
23
+
24
+ context = {
25
+ "session_name": self.sensorial_session.nombre_sesion,
26
+ "max_testers": self.sensorial_session.tecnica.limite_catadores,
27
+ "current_testers": len(self.participations),
28
+ "active_testers": len([part for part in self.participations if part.activo]),
29
+ "participations": self.participations
30
+ }
31
+
32
+ return context
tecnicas/templates/tecnicas/manage_sesions/detalles-sesion.html CHANGED
@@ -158,13 +158,15 @@
158
  </figure>
159
  </button>
160
  {% else %}
161
- <button
162
- class="ct-btn-start-repition flex-1 uppercase text-lg max-sm:text-base tracking-wider p-4 border-b-2 active:border-b-0 active:border-t-2 active:border-orange-500 border-orange-800 transition-all rounded-xl bg-orange-600 text-white font-bold disabled:bg-amber-600 flex flex-col justify-center items-center gap-2">
163
- Monitorear repetición
164
- <figure class="w-10">
165
- <img src="{% static 'img/monitor.svg' %}" alt="flechas girando" class="invert">
166
- </figure>
167
- </button>
 
 
168
  {% endif %}
169
 
170
  <button
 
158
  </figure>
159
  </button>
160
  {% else %}
161
+ <a href="{% url 'cata_system:monitor_sesion' session_code=sesion.codigo_sesion %}" class="flex-1 w-fit">
162
+ <button
163
+ class="ct-btn-start-repition w-full uppercase text-lg max-sm:text-base tracking-wider p-4 border-b-2 active:border-b-0 active:border-t-2 active:border-orange-500 border-orange-800 transition-all rounded-xl bg-orange-600 text-white font-bold disabled:bg-amber-600 flex flex-col justify-center items-center gap-2">
164
+ Monitorear repetición
165
+ <figure class="w-10">
166
+ <img src="{% static 'img/monitor.svg' %}" alt="flechas girando" class="invert">
167
+ </figure>
168
+ </button>
169
+ </a>
170
  {% endif %}
171
 
172
  <button
tecnicas/templates/tecnicas/manage_sesions/monitor-sesion.html ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% extends 'tecnicas/layouts/base.html' %}
2
+
3
+ {% block title %}Monitoreo{% endblock %}
4
+
5
+ {% block content %}
6
+ <article class="w-full flex flex-col justify-center items-center bg-gray-600 mt-10 mb-10">
7
+ <article
8
+ class="flex flex-col gap-8 bg-gray-400 p-10 max-lg:p-6 max-sm:px-2 max-sm:w-full rounded-2xl max-lg:rounded-none">
9
+ <header class="text-center">
10
+ <h1 class="text-3xl font-bold">Sesión sensorial en curso</h1>
11
+ </header>
12
+
13
+ {% if error %}
14
+ <article class="bg-red-600 p-4 text-white rounded-xl ct-notification-error">
15
+ <p class="block font-sans text-white text-xl antialiased font-bold uppercase tracking-wider text-center">
16
+ {{ error }}
17
+ </p>
18
+ </article>
19
+ {% endif %}
20
+
21
+ <section class="flex flex-col sm:flex-row justify-between items-center gap-10 mb-6">
22
+ <p class="text-xl text-center bg-gray-600 p-4 text-white rounded-lg">
23
+ Código de sesión:<br>
24
+ <span class="font-mono text-2xl font-bold">{{ code_session }}</span>
25
+ </p>
26
+ <button
27
+ class="uppercase text-lg max-sm:text-base tracking-wider p-4 border-b-2 active:border-b-0 active:border-t-2 active:border-red-500 border-red-800 transition-all rounded-xl bg-red-600 text-white font-bold disabled:bg-amber-600">
28
+ Finalizar sesión
29
+ </button>
30
+ </section>
31
+
32
+ <section aria-labelledby="catadores-titulo">
33
+ <article
34
+ class="flex max-sm:flex-col justify-around bg-gray-200 border border-gray-300 rounded-md p-3 mb-4 items-center">
35
+ <button
36
+ class="uppercase text-lg max-sm:text-base tracking-wider p-2 px-3 border-b-3 active:border-b-0 active:border-t-3 active:border-blue-500 border-blue-800 transition-all rounded-xl bg-blue-600 text-white font-bold"
37
+ onclick="reloadPage()">
38
+ Actualizar lista
39
+ </button>
40
+ <h2 id="catadores-titulo" class="text-2xl text-center font-bold rounded-lg text-gray-700 py-2 px-3">
41
+ Catadores activos
42
+ </h2>
43
+ </article>
44
+
45
+ <article
46
+ class="flex flex-col justify-center gap-3 bg-gray-200 border border-gray-300 rounded-md p-3 mb-4 text-lg max-sm:text-sm text-gray-700">
47
+ <div class="flex justify-center items-center">
48
+ <h2 class="text-xl font-semibold">Participantes</h2>
49
+ </div>
50
+ <section class="flex flex-wrap justify-around items-center">
51
+ <div class="flex flex-col sm:flex-row sm:items-center sm:gap-2">
52
+ <span class="font-semibold">Máximo:</span>
53
+ <span>{{ max_testers }}</span>
54
+ </div>
55
+ <div class="flex flex-col sm:flex-row sm:items-center sm:gap-2">
56
+ <span class="font-semibold">Actuales:</span>
57
+ <span>{{ current_testers }}</span>
58
+ </div>
59
+ <div class="flex flex-col sm:flex-row sm:items-center sm:gap-2">
60
+ <span class="font-semibold">Activos:</span>
61
+ <span class="text-green-600 font-semibold">{{ active_testers }}</span>
62
+ </div>
63
+ </section>
64
+ </article>
65
+
66
+ <article class="max-sm:overflow-x-auto">
67
+ <div class="min-w-[400px] sm:min-w-0">
68
+ <div
69
+ class="grid grid-cols-4 bg-gray-300 text-center font-semibold text-sm rounded-t-lg max-sm:w-full [&_>*]:px-2">
70
+ <div class="py-2 border-r border-gray-400">Usuario</div>
71
+ <div class="py-2 border-r border-gray-400">Nombre</div>
72
+ <div class="py-2 border-r border-gray-400">Estado</div>
73
+ <div class="py-2">Finalizado</div>
74
+ </div>
75
+
76
+ <ul class="divide-y divide-gray-400 max-sm:w-full">
77
+ {% for parti in participations %}
78
+ <li class="grid grid-cols-4 text-center bg-gray-200 py-2 [&_>*]:px-2">
79
+ <p class="border-r border-gray-400">{{ parti.catador.usuarioCatador }}</p>
80
+ <p class="border-r border-gray-400">
81
+ {{ parti.catador.nombre }}
82
+ {{ parti.catador.apellido}}
83
+ </p>
84
+
85
+ {% if parti.activo %}
86
+ <p class="border-r border-gray-400 text-green-600 font-semibold">Activo</p>
87
+ {% else %}
88
+ <p class="border-r border-gray-400 text-red-500 font-semibold">No activo</p>
89
+ {% endif %}
90
+
91
+ {% if parti.finalizado %}
92
+ <p class="text-green-600 font-semibold">Si</p>
93
+ {% else %}
94
+ <p class="text-red-500 font-semibold">No</p>
95
+ {% endif %}
96
+ </li>
97
+ {% endfor %}
98
+ </ul>
99
+ </div>
100
+ </article>
101
+ </section>
102
+ </article>
103
+ </article>
104
+ {% endblock %}
105
+
106
+ {% block extra_js %}
107
+ <script>
108
+ function reloadPage () {
109
+ location.reload()
110
+ }
111
+ </script>
112
+ {% endblock %}
tecnicas/urls.py CHANGED
@@ -62,6 +62,10 @@ urlpatterns = [
62
  views.sessionDetails,
63
  name="detalles_sesion"),
64
 
 
 
 
 
65
 
66
  # Vistas para catadores
67
  path("catador-login",
 
62
  views.sessionDetails,
63
  name="detalles_sesion"),
64
 
65
+ path("monitor/<str:session_code>",
66
+ views.sessionMonitor,
67
+ name="monitor_sesion"),
68
+
69
 
70
  # Vistas para catadores
71
  path("catador-login",
tecnicas/views/__init__.py CHANGED
@@ -4,6 +4,7 @@ from .main_panel import mainPanel
4
 
5
  from .sessions_management.sessions_panel import sesionsPanel
6
  from .sessions_management.session_details import sessionDetails
 
7
 
8
  from .sessions_config.seleccion_tecnica import selecionTecnica
9
  from .sessions_config.configuration_panel_basic import configurationPanelBasic
 
4
 
5
  from .sessions_management.sessions_panel import sesionsPanel
6
  from .sessions_management.session_details import sessionDetails
7
+ from .sessions_management.session_monitor import sessionMonitor
8
 
9
  from .sessions_config.seleccion_tecnica import selecionTecnica
10
  from .sessions_config.configuration_panel_basic import configurationPanelBasic
tecnicas/views/sessions_management/session_monitor.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from django.http import HttpRequest, JsonResponse
2
+ from django.shortcuts import render
3
+ from tecnicas.controllers import MonitorSesionController
4
+
5
+
6
+ def sessionMonitor(req: HttpRequest, session_code: str):
7
+ if req.method == "GET":
8
+ controll_view = MonitorSesionController(session_code)
9
+
10
+ context = controll_view.monitorView()
11
+ if "error" in context:
12
+ return render(req, "tecnicas/manage_sesions/monitor-sesion.html", context)
13
+
14
+ context["code_session"] = session_code
15
+ return render(req, "tecnicas/manage_sesions/monitor-sesion.html", context)
16
+ else:
17
+ return JsonResponse({"error": "Método no permitido"})