chartManD commited on
Commit
6f7e77f
·
1 Parent(s): 2312654

Catador puede crear su lista de palabras

Browse files
tecnicas/controllers/__init__.py CHANGED
@@ -31,9 +31,11 @@ from .views_controller.session_management.monitor_pf_controller import MonitorPF
31
 
32
  from .views_controller.sessions_tester.login_session_tester_controller import LoginSessionTesterController
33
  from .views_controller.sessions_tester.list_sessions_tester_controller import ListSessionsTesterController
34
- from .views_controller.sessions_tester.test_scales_controller import TestScalesController
35
- from .views_controller.sessions_tester.test_rata_controller import TestRataController
36
- from .views_controller.sessions_tester.test_cata_controller import TestCataController
 
 
37
 
38
  from .views_controller.sessions_tester.init_session.init_session_escalas_controller import InitSessionEscalasController
39
  from .views_controller.sessions_tester.init_session.init_session_rata_controller import InitSessionRATAController
 
31
 
32
  from .views_controller.sessions_tester.login_session_tester_controller import LoginSessionTesterController
33
  from .views_controller.sessions_tester.list_sessions_tester_controller import ListSessionsTesterController
34
+
35
+ from .views_controller.sessions_tester.tests_forms.test_scales_controller import TestScalesController
36
+ from .views_controller.sessions_tester.tests_forms.test_rata_controller import TestRataController
37
+ from .views_controller.sessions_tester.tests_forms.test_cata_controller import TestCataController
38
+ from .views_controller.sessions_tester.tests_forms.test_pf_controller import TestPFController
39
 
40
  from .views_controller.sessions_tester.init_session.init_session_escalas_controller import InitSessionEscalasController
41
  from .views_controller.sessions_tester.init_session.init_session_rata_controller import InitSessionRATAController
tecnicas/controllers/views_controller/sessions_tester/init_session/init_session_pf_controller.py CHANGED
@@ -4,18 +4,13 @@ from django.urls import reverse
4
  from tecnicas.models import Participacion, Producto, Dato, ListaPalabras
5
  from tecnicas.controllers import ParticipacionController
6
  from .init_session_controller import InitSessionController
7
- from tecnicas.utils import controller_error
8
 
9
 
10
  class InitSessionPFController(InitSessionController):
11
- pf_ph1_direcction = "cata_system:session_pf_ph1"
12
- pf_ph2_direcction = "cata_system:session_pf_ph2"
13
- pf_rep_direcction = "cata_system:session_pf_rep"
14
-
15
  def __init__(self, sensorial_session, user_tester):
16
  super().__init__(sensorial_session, user_tester)
17
  self.current_direction = "tecnicas/forms_tester/init_session_pf.html"
18
- self.pf_direction = "cata_system:session_convencional"
19
 
20
  def controllGet(self, request: HttpRequest):
21
  context = {
@@ -61,17 +56,14 @@ class InitSessionPFController(InitSessionController):
61
 
62
  request.session["id_participation"] = update_participation.id
63
 
64
- if self.session.tecnica.tipo_tecnica.nombre_tecnica == "cata":
65
- return redirect(reverse(self.cata_direction, kwargs=parameters))
66
-
67
- return redirect(reverse(self.escalas_direction, kwargs=parameters))
68
 
69
  elif request.POST["action"] == "exit_session":
70
  response = ParticipacionController.outSession(
71
  tester=request.user.user_catador, session=self.session)
72
  if isinstance(response, dict):
73
  context["error"] = response["error"]
74
- return render(request, self.current_direction, context)
75
 
76
  else:
77
  context["error"] = "Acción sin especificar"
 
4
  from tecnicas.models import Participacion, Producto, Dato, ListaPalabras
5
  from tecnicas.controllers import ParticipacionController
6
  from .init_session_controller import InitSessionController
 
7
 
8
 
9
  class InitSessionPFController(InitSessionController):
 
 
 
 
10
  def __init__(self, sensorial_session, user_tester):
11
  super().__init__(sensorial_session, user_tester)
12
  self.current_direction = "tecnicas/forms_tester/init_session_pf.html"
13
+ self.pf_direction = "cata_system:session_pf"
14
 
15
  def controllGet(self, request: HttpRequest):
16
  context = {
 
56
 
57
  request.session["id_participation"] = update_participation.id
58
 
59
+ return redirect(reverse(self.pf_direction, kwargs=parameters))
 
 
 
60
 
61
  elif request.POST["action"] == "exit_session":
62
  response = ParticipacionController.outSession(
63
  tester=request.user.user_catador, session=self.session)
64
  if isinstance(response, dict):
65
  context["error"] = response["error"]
66
+ return self.controllGet(request)
67
 
68
  else:
69
  context["error"] = "Acción sin especificar"
tecnicas/controllers/views_controller/sessions_tester/{general_test_controller.py → tests_forms/general_test_controller.py} RENAMED
File without changes
tecnicas/controllers/views_controller/sessions_tester/{test_cata_controller.py → tests_forms/test_cata_controller.py} RENAMED
File without changes
tecnicas/controllers/views_controller/sessions_tester/tests_forms/test_pf_controller.py ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from django.http import HttpRequest
2
+ from django.shortcuts import redirect, render
3
+ from django.urls import reverse
4
+ from tecnicas.models import Producto, Participacion, Palabra, Calificacion, ListaPalabras
5
+ from tecnicas.controllers import ParticipacionController, PalabrasController
6
+ from tecnicas.forms import ListWordsForm
7
+ from .general_test_controller import GenetalTestController
8
+
9
+
10
+ class TestPFController(GenetalTestController):
11
+ def __init__(self, sensorial_session, user_tester):
12
+ super().__init__(sensorial_session, user_tester)
13
+
14
+ def controllGet(self, request: HttpRequest):
15
+ self.participation = Participacion.objects.get(
16
+ tecnica=self.session.tecnica, catador=request.user.user_catador)
17
+ self.context["session"] = self.session
18
+
19
+ rep = self.session.tecnica.repeticion
20
+
21
+ if rep == 1:
22
+ self.current_directory = "tecnicas/forms_tester/test_pf_list_words.html"
23
+ response = self.getFirstPhase(request)
24
+ elif rep == 2:
25
+ response = self.getSecondPhase(request)
26
+ elif rep >= 3:
27
+ response = self.getRepetitionPhase(request)
28
+ else:
29
+ response = self.getErrorRepetition(request)
30
+
31
+ return response
32
+
33
+ def getFirstPhase(self, request: HttpRequest):
34
+ self.participation.refresh_from_db()
35
+
36
+ if self.participation.finalizado:
37
+ params = {
38
+ "code_sesion": self.session.codigo_sesion
39
+ }
40
+ return redirect(reverse(self.previus_directory, kwargs=params))
41
+
42
+ self.context["form"] = ListWordsForm()
43
+ self.context["initial_phase"] = True
44
+
45
+ return render(request, self.current_directory, self.context)
46
+
47
+ def getSecondPhase(self, request: HttpRequest):
48
+ self.participation.refresh_from_db()
49
+
50
+ if self.participation.finalizado:
51
+ params = {
52
+ "code_sesion": self.session.codigo_sesion
53
+ }
54
+ return redirect(reverse(self.previus_directory, kwargs=params))
55
+
56
+ list_words = list(
57
+ ListaPalabras.objects.get(
58
+ tecnica=self.session.tecnica,
59
+ catador=request.user.user_catador,
60
+ es_final=False
61
+ ).palabras.all()
62
+ )
63
+
64
+ self.context["form"] = ListWordsForm()
65
+ self.context["initial_phase"] = False
66
+ self.context["words"] = list_words
67
+
68
+ return render(request, self.current_directory, self.context)
69
+
70
+ def getRepetitionPhase(self, request: HttpRequest):
71
+ technique = self.session.tecnica
72
+
73
+ products_in_technique = Producto.objects.filter(id_tecnica=technique)
74
+
75
+ words = list(
76
+ ListaPalabras.objects.get(
77
+ tecnica=self.session.tecnica,
78
+ catador=request.user.user_catador,
79
+ es_final=True
80
+ ).palabras.all()
81
+ )
82
+
83
+ use_product: Producto = None
84
+ use_words: list[Palabra] = None
85
+
86
+ # Revisamos el producto que le falten calificaciones
87
+ for current_product in products_in_technique:
88
+ try:
89
+ rating = Calificacion.objects.get(
90
+ num_repeticion=technique.repeticion,
91
+ id_producto=current_product,
92
+ id_tecnica=technique,
93
+ id_catador=self.tester
94
+ )
95
+ except Calificacion.DoesNotExist:
96
+ # Si no hay calificacion mandamos el producto actual y todas la palabras
97
+ use_product = current_product
98
+ use_words = words
99
+ break
100
+
101
+ # Obtener los datos asociados para la calificacion para ver que palabras quedan por calificar
102
+ recoreded_data = rating.dato_calificacion.all()
103
+
104
+ if not recoreded_data:
105
+ # Si no hay datos entonces devolver el producto con todas las palabras
106
+ use_product = current_product
107
+ use_words = words
108
+ break
109
+ else:
110
+ words_to_use = PalabrasController.getWordsWithoutData(
111
+ recoreded_data=recoreded_data, words=words)
112
+
113
+ # Si quedan palabras por calificar mandar las palabras con el producto
114
+ if not isinstance(words_to_use, dict) and words_to_use:
115
+ use_product = current_product
116
+ use_words = words_to_use
117
+ break
118
+
119
+ # Si no hay producto que falta por calificar finalizar sesion para el Catador
120
+ if not use_product:
121
+ updated_participation = ParticipacionController.finishSession(
122
+ self.participation)
123
+ params = {
124
+ "code_sesion": self.session.codigo_sesion
125
+ }
126
+ return redirect(reverse(self.previus_directory, kwargs=params))
127
+
128
+ self.context["product"] = use_product
129
+ self.context["words"] = use_words
130
+
131
+ return render(request, self.current_directory, self.context)
132
+
133
+ def getErrorRepetition(self, request: HttpRequest):
134
+ params = {
135
+ "code_sesion": self.session.codigo_sesion
136
+ }
137
+ return redirect(reverse(self.previus_directory, kwargs=params))
tecnicas/controllers/views_controller/sessions_tester/{test_rata_controller.py → tests_forms/test_rata_controller.py} RENAMED
File without changes
tecnicas/controllers/views_controller/sessions_tester/{test_scales_controller.py → tests_forms/test_scales_controller.py} RENAMED
File without changes
tecnicas/forms/__init__.py CHANGED
@@ -8,3 +8,5 @@ from .codes_form import CodesForm
8
  from .catador_form import CatadorForm
9
  from .word_form import WordForm
10
  from .vocabulary_select import VocabularioSelectForm
 
 
 
8
  from .catador_form import CatadorForm
9
  from .word_form import WordForm
10
  from .vocabulary_select import VocabularioSelectForm
11
+
12
+ from .list_words_form import ListWordsForm
tecnicas/forms/list_words_form.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from django import forms
2
+ import re
3
+
4
+
5
+ class ListWordsForm(forms.Form):
6
+ regex = re.compile(r'^[a-zñ]{3,}$')
7
+
8
+ def __init__(self, *args, new_words=None, **kwargs):
9
+ super().__init__(*args, **kwargs)
10
+ new_words = new_words or []
11
+
12
+ if not new_words:
13
+ self.fields['nombre_palabra'] = forms.CharField(
14
+ label='Nombre de la palabra',
15
+ max_length=255,
16
+ widget=forms.TextInput(attrs={
17
+ 'placeholder': 'Escribe una palabra',
18
+ 'class': 'cts-input-list-word bg-surface-ligt p-1 border-b-1 text-center w-full',
19
+ 'pattern': self.regex.pattern,
20
+ 'title': 'Solo letras minúsculas y la letra ñ, no poner acentos. No se permiten mayúsculas ni caracteres especiales. Mínimo 3 letras',
21
+ })
22
+ )
23
+ else:
24
+ for index, name in enumerate(new_words, start=1):
25
+ self.fields[f'nombre_palabra_{index}'] = forms.CharField(
26
+ label=f'Palabra {index}',
27
+ max_length=255,
28
+ initial=name,
29
+ widget=forms.TextInput(attrs={
30
+ 'placeholder': 'Escribe una palabra',
31
+ 'class': 'cts-input-list-word bg-surface-ligt p-1 border-b-1 text-center w-full',
32
+ 'pattern': self.regex.pattern,
33
+ 'title': 'Solo letras minúsculas y la letra ñ. No se permiten mayúsculas ni caracteres especiales.'
34
+ })
35
+ )
36
+
37
+ def clean(self):
38
+ cleaned_data = super().clean()
39
+ errores = []
40
+
41
+ for field_name, value in cleaned_data.items():
42
+ if not self.regex.match(value):
43
+ errores.append(f"'{value}' contiene caracteres no permitidos.")
44
+ elif len(value) > 255:
45
+ errores.append(f"'{value}' excede los 255 caracteres.")
46
+
47
+ if errores:
48
+ raise forms.ValidationError(errores)
49
+
50
+ return cleaned_data
tecnicas/static/js/pf-make-list.js ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const FORM_DESCRIBE = document.querySelector(".cts-form-pf-word");
2
+ const BOX_WORDS = document.querySelector(".cts-box-words");
3
+ const IMG_LIST = document.querySelector(".cts-img-list");
4
+ const ERROR_INPUT_WORD = document.querySelector(".error-input-word");
5
+
6
+ const WORDS = [];
7
+ const STYLES_LI = [
8
+ "cts-item-words",
9
+ "bg-gray-400",
10
+ "text-black",
11
+ "rounded",
12
+ "font-bold",
13
+ "text-lg",
14
+ "px-4",
15
+ "py-3",
16
+ "flex",
17
+ "flex-wrap",
18
+ "flex-row",
19
+ "flex-1",
20
+ "min-w-fit",
21
+ "justify-center",
22
+ "items-center",
23
+ "gap-3",
24
+ ];
25
+
26
+ const STYLES_BTN = [
27
+ "cts-remove-word",
28
+ "px-4",
29
+ "border-b-2",
30
+ "active:border-b-0",
31
+ "active:border-t-2",
32
+ "transition-all",
33
+ "rounded-xl",
34
+ "font-black",
35
+ "w-fit",
36
+ "capitalize",
37
+ "active:border-red-500",
38
+ "border-red-800",
39
+ "bg-red-500",
40
+ ];
41
+
42
+ const itemWord = (wordName, index) => {
43
+ const btn = document.createElement("button");
44
+ btn.setAttribute("data-index", index);
45
+ btn.classList.add(...STYLES_BTN);
46
+ btn.textContent = "➖";
47
+
48
+ const ph = document.createElement("p");
49
+ ph.classList.add("ct-word-received");
50
+ ph.textContent = wordName;
51
+
52
+ const li = document.createElement("li");
53
+ li.setAttribute("id", `word-${index}`);
54
+ li.classList.add(...STYLES_LI);
55
+
56
+ li.appendChild(ph);
57
+ li.appendChild(btn);
58
+
59
+ return li;
60
+ };
61
+
62
+ function initWordsFromBox() {
63
+ if (!BOX_WORDS) return;
64
+ const current_words = BOX_WORDS.querySelectorAll(".cts-item-words");
65
+ if (!current_words.length) return;
66
+
67
+ WORDS.length = 0;
68
+ current_words.forEach((li) => {
69
+ const p = li.querySelector(".ct-word-received");
70
+ const text = p ? p.textContent.trim() : li.textContent.trim();
71
+ if (text) WORDS.push(text);
72
+ });
73
+ renderWords();
74
+ }
75
+
76
+ function renderWords() {
77
+ if (!BOX_WORDS) return;
78
+ if (!WORDS.length) {
79
+ BOX_WORDS.innerHTML = "";
80
+ IMG_LIST.classList.remove("hidden");
81
+ BOX_WORDS.appendChild(IMG_LIST);
82
+ return;
83
+ }
84
+
85
+ BOX_WORDS.innerHTML = "";
86
+ WORDS.forEach((word, index) => {
87
+ let liElement = itemWord(word, index);
88
+ BOX_WORDS.appendChild(liElement);
89
+ });
90
+
91
+ const removeButtons = BOX_WORDS.querySelectorAll("button.cts-remove-word");
92
+ removeButtons.forEach((btn) => {
93
+ btn.addEventListener("click", (e) => {
94
+ const idx = parseInt(btn.dataset.index);
95
+ if (!Number.isNaN(idx)) {
96
+ WORDS.splice(idx, 1);
97
+ renderWords();
98
+ }
99
+ });
100
+ });
101
+ }
102
+
103
+ function setupDescribeFormToAddWord() {
104
+ if (!FORM_DESCRIBE) return;
105
+ FORM_DESCRIBE.addEventListener("submit", (e) => {
106
+ e.preventDefault();
107
+
108
+ if (!FORM_DESCRIBE.reportValidity()) {
109
+ return;
110
+ }
111
+
112
+ const input = FORM_DESCRIBE.querySelector('input[type="text"]');
113
+ if (!input) return;
114
+
115
+ const value = input.value.trim();
116
+ if (!value) return;
117
+
118
+ if (WORDS.includes(value)) {
119
+ notifactionError("Esa palabra ya está en la lista");
120
+ return;
121
+ }
122
+
123
+ WORDS.push(value);
124
+ renderWords();
125
+
126
+ input.value = "";
127
+ input.focus();
128
+ });
129
+ }
130
+
131
+ function notifactionError(messageError) {
132
+ ERROR_INPUT_WORD.textContent = messageError;
133
+ ERROR_INPUT_WORD.classList.remove("hidden");
134
+ setTimeout(() => {
135
+ ERROR_INPUT_WORD.textContent = "";
136
+ ERROR_INPUT_WORD.classList.add("hidden");
137
+ }, 3000);
138
+ }
139
+
140
+ window.addEventListener("DOMContentLoaded", () => {
141
+ initWordsFromBox();
142
+ setupDescribeFormToAddWord();
143
+ });
tecnicas/templates/tecnicas/forms_tester/test_pf_list_words.html ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% extends 'tecnicas/layouts/base.html' %}
2
+
3
+ {% load static %}
4
+
5
+ {% block title %}Convencional{% endblock %}
6
+
7
+ {% block content %}
8
+ <article class="cts-container-main">
9
+ <article class="cts-wrap-content text-black max-w-4xl">
10
+ <header class="text-center flex-row w-full items-stretch flex justify-around flex-wrap gap-2">
11
+ <h1 class="rounded font-bold text-2xl bg-surface-ligt p-4 flex-1">
12
+ Sesión usando <br>técnica
13
+ <span class="uppercase">{{ session.tecnica.tipo_tecnica }}</span>
14
+ </h1>
15
+ <button class="cts-btn-general cts-btn-error btn-push" onclick="exit_sesion('form-actions')">
16
+ Salir de la sesión
17
+ </button>
18
+ </header>
19
+
20
+ <article class="hidden">
21
+ <form action="{% url 'cata_system:catador_init_session' code_sesion=session.codigo_sesion %}" method="post"
22
+ class="form-actions">
23
+ {% csrf_token %}
24
+ <input type="hidden" name="action" class="action-input">
25
+ </form>
26
+ </article>
27
+
28
+ <section class="hidden">
29
+ <input type="hidden" value="{{ session.tecnica.id }}" name="id-tecnica" class="ct-input-id-tech">
30
+ </section>
31
+
32
+ {% if error %}
33
+ <hr>
34
+ <article class="bg-red-600 p-4 text-white rounded-xl ct-notification-error">
35
+ <p class="block font-sans text-white text-xl antialiased font-bold uppercase tracking-wider text-center">
36
+ {{ error }}
37
+ </p>
38
+ </article>
39
+ {% endif %}
40
+
41
+ <article class="rounded flex flex-col gap-4">
42
+ <section class="flex items-center justify-center bg-surface-ligt p-2 rounded-lg">
43
+ <p class="text-lg font-medium text-center">
44
+ {{ session.tecnica.instrucciones }}
45
+ </p>
46
+ </section>
47
+ <section class="flex items-center justify-center flex-wrap gap-4 bg-surface-ligt p-2 rounded-lg">
48
+ {% if initial_phase %}
49
+ <p class="text-xl font-bold text-center">
50
+ Fase 1:
51
+ </p>
52
+ <p class="text-xl font-bold text-center">
53
+ Lista inicial
54
+ </p>
55
+ {% else %}
56
+ <p class="text-xl font-bold text-center">
57
+ Fase 2:
58
+ </p>
59
+ <p class="text-xl font-bold text-center">
60
+ Lista Final
61
+ </p>
62
+ {% endif %}
63
+ </section>
64
+ </article>
65
+
66
+ <article class="cts-list-words">
67
+ <article class="flex gap-4 flex-wrap">
68
+ <section class="bg-surface-card p-4 rounded-lg text-center space-y-4 sm:w-[300px] w-full flex-shrink-0">
69
+ <h3 class="text-xl font-bold border-b-1">Describe el producto</h3>
70
+
71
+ <form action="" method="get" class="cts-form-pf-word flex gap-4 flex-col">
72
+ <label for="{{ form.nombre_palabra.id_for_label }}" class="text-left">
73
+ <p class="text-lg font-semibold">
74
+ {{ form.nombre_palabra.label }}:
75
+ </p>
76
+ {{ form.nombre_palabra }}
77
+ <small>
78
+ Solo letras minúsculas y la letra ñ, no poner acentos. No se permiten mayúsculas ni
79
+ caracteres especiales. Mínimo 3 letras
80
+ </small>
81
+ </label>
82
+ <button type="submit" class="cts-btn-general-compress cts-btn-primary btn-push w-full py-2">
83
+ Agregar
84
+ </button>
85
+ <p class="error-input-word p-2 bg-red-500 rounded-lg hidden text-white font-semibold">
86
+ </p>
87
+ </form>
88
+ </section>
89
+
90
+ <section
91
+ class="bg-surface-card p-4 rounded-lg text-center w-[400px] max-w-[400px] h-[400px] min-h-[400px] max-h-[600px] flex-shrink-0 overflow-y-auto">
92
+ <div>
93
+ <p class="text-xl font-bold pb-3">Lista de palabras</p>
94
+ <hr>
95
+ </div>
96
+
97
+ <ul class="cts-box-words flex flex-col gap-3 overflow-y-auto mt-4">
98
+ {% if not words %}
99
+ <img src="{% static 'img/list.svg' %}" alt="lista de palabras" class="cts-img-list h-[300px]">
100
+ {% endif %}
101
+
102
+ {% for word in words %}
103
+ <img src="{% static 'img/list.svg' %}" alt="lista de palabras"
104
+ class="cts-img-list h-[300px] hidden">
105
+
106
+ <li class="cts-item-words bg-gray-400 text-black rounded font-bold text-lg
107
+ px-4 py-3 flex flex-wrap flex-row min-w-fit justify-center items-center gap-3">
108
+ <p class="ct-word-received">{{ word.nombre_palabra }}</p>
109
+
110
+ <button class="px-4 border-b-2 active:border-b-0 active:border-t-2
111
+ transition-all rounded-xl font-black capitalize
112
+ active:border-red-500 border-red-800 bg-red-500">
113
+
114
+ </button>
115
+ </li>
116
+ {% endfor %}
117
+ </ul>
118
+ </section>
119
+ </article>
120
+
121
+ </article>
122
+ </article>
123
+ </article>
124
+ {% endblock %}
125
+
126
+ {% block extra_js %}
127
+ <script src="{% static 'js/pf-make-list.js' %}"></script>
128
+ <script src="{% static 'js/actions-form.js' %}"></script>
129
+ {% endblock %}
tecnicas/urls.py CHANGED
@@ -114,6 +114,10 @@ urlpatterns = [
114
  views.cataTest,
115
  name="session_cata"),
116
 
 
 
 
 
117
 
118
  # APIs
119
  path("presenter/api/nueva-etiqueta",
 
114
  views.cataTest,
115
  name="session_cata"),
116
 
117
+ path("testers/init-session/<str:code_sesion>/perfil-flash",
118
+ views.pfTest,
119
+ name="session_pf"),
120
+
121
 
122
  # APIs
123
  path("presenter/api/nueva-etiqueta",
tecnicas/views/__init__.py CHANGED
@@ -34,3 +34,4 @@ from .tester_forms.login_session import loginSessionTester
34
  from .tester_forms.sessions_list_tester import sessionsListTester
35
  from .tester_forms.convencional_scales import convencionalScales
36
  from .tester_forms.cata_test import cataTest
 
 
34
  from .tester_forms.sessions_list_tester import sessionsListTester
35
  from .tester_forms.convencional_scales import convencionalScales
36
  from .tester_forms.cata_test import cataTest
37
+ from .tester_forms.pf_test import pfTest
tecnicas/views/tester_forms/cata_test.py CHANGED
@@ -1,7 +1,6 @@
1
  from django.http import HttpRequest
2
  from tecnicas.models import SesionSensorial
3
  from tecnicas.controllers import TestCataController
4
- from tecnicas.utils import noValidTechnique
5
 
6
 
7
  def cataTest(req: HttpRequest, code_sesion: str):
 
1
  from django.http import HttpRequest
2
  from tecnicas.models import SesionSensorial
3
  from tecnicas.controllers import TestCataController
 
4
 
5
 
6
  def cataTest(req: HttpRequest, code_sesion: str):
tecnicas/views/tester_forms/init_tester_form.py CHANGED
@@ -42,10 +42,9 @@ def initTesterForm(req: HttpRequest, code_sesion: str):
42
  response = view_controller.controllPost(request=req)
43
 
44
  elif type_technique == "perfil flash":
45
- # view_controller = InitSessionPFController(
46
- # sensorial_session=session, user_tester=req.user.user_catador)
47
- # response = view_controller.controllPost(request=req)
48
- response = JsonResponse({"message": "Aun estamos probando esta funcion"})
49
  else:
50
  context = {
51
  "session": session,
 
42
  response = view_controller.controllPost(request=req)
43
 
44
  elif type_technique == "perfil flash":
45
+ view_controller = InitSessionPFController(
46
+ sensorial_session=session, user_tester=req.user.user_catador)
47
+ response = view_controller.controllPost(request=req)
 
48
  else:
49
  context = {
50
  "session": session,
tecnicas/views/tester_forms/pf_test.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from django.http import HttpRequest
2
+ from tecnicas.models import SesionSensorial
3
+ from tecnicas.controllers import TestPFController
4
+
5
+
6
+ def pfTest(req: HttpRequest, code_sesion: str):
7
+ if req.method == "GET":
8
+ session = SesionSensorial.objects.get(codigo_sesion=code_sesion)
9
+ controll_view = TestPFController(
10
+ sensorial_session=session, user_tester=req.user.user_catador)
11
+ return controll_view.controllGet(request=req)