Spaces:
Sleeping
Sleeping
Se crea plano para napping
Browse files- tecnicas/controllers/__init__.py +1 -0
- tecnicas/controllers/views_controller/sessions_tester/init_session/init_session_napping_controller.py +44 -2
- tecnicas/controllers/views_controller/sessions_tester/tests_forms/test_napping_controller.py +41 -0
- tecnicas/static/js/test-napping.js +92 -0
- tecnicas/templates/tecnicas/forms_tester/test_napping.html +131 -0
- tecnicas/urls.py +4 -0
- tecnicas/views/__init__.py +1 -0
- tecnicas/views/tester_forms/init_tester_form.py +7 -2
- tecnicas/views/tester_forms/napping_test.py +27 -0
tecnicas/controllers/__init__.py
CHANGED
|
@@ -47,6 +47,7 @@ from .views_controller.sessions_tester.tests_forms.test_rata_controller import T
|
|
| 47 |
from .views_controller.sessions_tester.tests_forms.test_cata_controller import TestCataController
|
| 48 |
from .views_controller.sessions_tester.tests_forms.test_pf_controller import TestPFController
|
| 49 |
from .views_controller.sessions_tester.tests_forms.test_sort_controller import TestSortController
|
|
|
|
| 50 |
|
| 51 |
from .views_controller.sessions_tester.init_session.init_session_escalas_controller import InitSessionEscalasController
|
| 52 |
from .views_controller.sessions_tester.init_session.init_session_rata_controller import InitSessionRATAController
|
|
|
|
| 47 |
from .views_controller.sessions_tester.tests_forms.test_cata_controller import TestCataController
|
| 48 |
from .views_controller.sessions_tester.tests_forms.test_pf_controller import TestPFController
|
| 49 |
from .views_controller.sessions_tester.tests_forms.test_sort_controller import TestSortController
|
| 50 |
+
from .views_controller.sessions_tester.tests_forms.test_napping_controller import TestNappingController
|
| 51 |
|
| 52 |
from .views_controller.sessions_tester.init_session.init_session_escalas_controller import InitSessionEscalasController
|
| 53 |
from .views_controller.sessions_tester.init_session.init_session_rata_controller import InitSessionRATAController
|
tecnicas/controllers/views_controller/sessions_tester/init_session/init_session_napping_controller.py
CHANGED
|
@@ -10,12 +10,13 @@ class InitSessionNappingController(InitSessionController):
|
|
| 10 |
def __init__(self, sensorial_session, user_tester):
|
| 11 |
super().__init__(sensorial_session, user_tester)
|
| 12 |
self.current_direction = "tecnicas/forms_tester/init_test_napping.html"
|
| 13 |
-
self.
|
| 14 |
|
| 15 |
def controllGet(self, request: HttpRequest):
|
| 16 |
self.context = {
|
| 17 |
"session": self.session,
|
| 18 |
"type_technique": "napping",
|
|
|
|
| 19 |
}
|
| 20 |
|
| 21 |
if self.session.tecnica.repeticion == 1:
|
|
@@ -29,4 +30,45 @@ class InitSessionNappingController(InitSessionController):
|
|
| 29 |
return render(request, self.current_direction, self.context)
|
| 30 |
|
| 31 |
def isEndedSession(self):
|
| 32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
def __init__(self, sensorial_session, user_tester):
|
| 11 |
super().__init__(sensorial_session, user_tester)
|
| 12 |
self.current_direction = "tecnicas/forms_tester/init_test_napping.html"
|
| 13 |
+
self.napping_direction = "cata_system:session_napping"
|
| 14 |
|
| 15 |
def controllGet(self, request: HttpRequest):
|
| 16 |
self.context = {
|
| 17 |
"session": self.session,
|
| 18 |
"type_technique": "napping",
|
| 19 |
+
"has_ended": self.isEndedSession()
|
| 20 |
}
|
| 21 |
|
| 22 |
if self.session.tecnica.repeticion == 1:
|
|
|
|
| 30 |
return render(request, self.current_direction, self.context)
|
| 31 |
|
| 32 |
def isEndedSession(self):
|
| 33 |
+
return Participacion.objects.get(
|
| 34 |
+
tecnica=self.session.tecnica, catador=self.tester).finalizado
|
| 35 |
+
|
| 36 |
+
def controllPost(self, request: HttpRequest):
|
| 37 |
+
context = {
|
| 38 |
+
"session": self.session,
|
| 39 |
+
"type_technique": self.session.tecnica.tipo_tecnica.nombre_tecnica
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
use_action = request.POST["action"]
|
| 43 |
+
|
| 44 |
+
if use_action == "start_posting":
|
| 45 |
+
parameters = {
|
| 46 |
+
"code_sesion": self.session.codigo_sesion
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
is_end = self.isEndedSession()
|
| 50 |
+
if is_end:
|
| 51 |
+
context["message"] = "El catador ha terminado de realizar su evaluación, espere instrucciones del presentador"
|
| 52 |
+
return render(request, self.current_direction, context)
|
| 53 |
+
|
| 54 |
+
update_participation = ParticipacionController.enterSession(
|
| 55 |
+
tester=request.user.user_catador, session=self.session)
|
| 56 |
+
|
| 57 |
+
if isinstance(update_participation, dict):
|
| 58 |
+
context["error"] = update_participation["error"]
|
| 59 |
+
return render(request, self.current_direction, context)
|
| 60 |
+
|
| 61 |
+
request.session["id_participation"] = update_participation.id
|
| 62 |
+
|
| 63 |
+
return redirect(reverse(self.napping_direction, kwargs=parameters))
|
| 64 |
+
|
| 65 |
+
elif use_action == "exit_session":
|
| 66 |
+
response = ParticipacionController.outSession(
|
| 67 |
+
tester=request.user.user_catador, session=self.session)
|
| 68 |
+
if isinstance(response, dict):
|
| 69 |
+
context["error"] = response["error"]
|
| 70 |
+
return render(request, self.current_direction, context)
|
| 71 |
+
|
| 72 |
+
else:
|
| 73 |
+
context["error"] = "Acción sin especificar"
|
| 74 |
+
return render(request, self.current_direction, context)
|
tecnicas/controllers/views_controller/sessions_tester/tests_forms/test_napping_controller.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from django.http import HttpRequest
|
| 2 |
+
from django.shortcuts import redirect, render
|
| 3 |
+
from django.urls import reverse
|
| 4 |
+
from tecnicas.models import Participacion, Producto
|
| 5 |
+
from .general_test_controller import GenetalTestController
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
class TestNappingController(GenetalTestController):
|
| 9 |
+
def __init__(self, sensorial_session, user_tester):
|
| 10 |
+
super().__init__(sensorial_session, user_tester)
|
| 11 |
+
self.napping_test = "tecnicas/forms_tester/test_napping.html"
|
| 12 |
+
|
| 13 |
+
def controllGet(self, request: HttpRequest):
|
| 14 |
+
technique = self.session.tecnica
|
| 15 |
+
|
| 16 |
+
self.participation = Participacion.objects.get(
|
| 17 |
+
tecnica=technique, catador=request.user.user_catador)
|
| 18 |
+
|
| 19 |
+
# Comprobar que el Catador no haya finalizado
|
| 20 |
+
if self.participation.finalizado:
|
| 21 |
+
params = {
|
| 22 |
+
"code_sesion": self.session.codigo_sesion
|
| 23 |
+
}
|
| 24 |
+
return redirect(reverse(self.previus_directory, kwargs=params))
|
| 25 |
+
|
| 26 |
+
if technique.repeticion == 1:
|
| 27 |
+
return self.nappingTest(request)
|
| 28 |
+
else:
|
| 29 |
+
params = {
|
| 30 |
+
"code_sesion": self.session.codigo_sesion
|
| 31 |
+
}
|
| 32 |
+
return redirect(reverse(self.previus_directory, kwargs=params))
|
| 33 |
+
|
| 34 |
+
def nappingTest(self, request: HttpRequest):
|
| 35 |
+
self.context["session"] = self.session
|
| 36 |
+
technique = self.session.tecnica
|
| 37 |
+
|
| 38 |
+
products_in_technique = Producto.objects.filter(id_tecnica=technique)
|
| 39 |
+
self.context["products"] = products_in_technique
|
| 40 |
+
|
| 41 |
+
return render(request, self.napping_test, self.context)
|
tecnicas/static/js/test-napping.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
const planeContainer = document.getElementById('napping-plane');
|
| 3 |
+
const productsContainer = document.getElementById('items');
|
| 4 |
+
const products = document.querySelectorAll('.item-product');
|
| 5 |
+
|
| 6 |
+
// Configuration for the physical dimensions of the tablecloth (in cm)
|
| 7 |
+
const PHYSICAL_WIDTH = 60;
|
| 8 |
+
const PHYSICAL_HEIGHT = 40;
|
| 9 |
+
|
| 10 |
+
let selectedProductCode = null;
|
| 11 |
+
let selectedProductId = null;
|
| 12 |
+
|
| 13 |
+
// Object to store coordinates: { "CODE": { x: 10.5, y: 20.1, id: 123 } }
|
| 14 |
+
const placedPoints = {};
|
| 15 |
+
|
| 16 |
+
// 1. Handle Product Selection
|
| 17 |
+
products.forEach(product => {
|
| 18 |
+
product.addEventListener('click', () => {
|
| 19 |
+
// Remove selection from others
|
| 20 |
+
products.forEach(p => p.classList.remove('ring-4', 'ring-primary'));
|
| 21 |
+
|
| 22 |
+
// Select current
|
| 23 |
+
product.classList.add('ring-4', 'ring-primary');
|
| 24 |
+
selectedProductCode = product.dataset.code;
|
| 25 |
+
selectedProductId = product.dataset.idProduct;
|
| 26 |
+
});
|
| 27 |
+
});
|
| 28 |
+
|
| 29 |
+
// 2. Handle Plane Click (Placing Points)
|
| 30 |
+
planeContainer.addEventListener('click', (e) => {
|
| 31 |
+
if (!selectedProductCode) {
|
| 32 |
+
spanNotifaction("Por favor, selecciona un producto primero")
|
| 33 |
+
return;
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
const rect = planeContainer.getBoundingClientRect();
|
| 37 |
+
|
| 38 |
+
// Calculate click position relative to the container (in pixels)
|
| 39 |
+
const xPixel = e.clientX - rect.left;
|
| 40 |
+
const yPixel = e.clientY - rect.top;
|
| 41 |
+
|
| 42 |
+
// Calculate scaled coordinates (0 to PHYSICAL_DIMENSIONS)
|
| 43 |
+
// X axis: 0 on left, 60 on right
|
| 44 |
+
const xCoord = (xPixel / rect.width) * PHYSICAL_WIDTH;
|
| 45 |
+
|
| 46 |
+
// Y axis: 0 on bottom, 40 on top (Invert Y because DOM Y is 0 at top)
|
| 47 |
+
const yCoord = PHYSICAL_HEIGHT - ((yPixel / rect.height) * PHYSICAL_HEIGHT);
|
| 48 |
+
|
| 49 |
+
// Update Data Object
|
| 50 |
+
placedPoints[selectedProductCode] = {
|
| 51 |
+
x: parseFloat(xCoord.toFixed(2)),
|
| 52 |
+
y: parseFloat(yCoord.toFixed(2)),
|
| 53 |
+
id: selectedProductId
|
| 54 |
+
};
|
| 55 |
+
|
| 56 |
+
// Render Point
|
| 57 |
+
renderPoint(selectedProductCode, xPixel, yPixel, xCoord, yCoord);
|
| 58 |
+
});
|
| 59 |
+
|
| 60 |
+
function renderPoint(code, xPx, yPx, xVal, yVal) {
|
| 61 |
+
// Remove existing point for this product if it exists
|
| 62 |
+
const existingPoint = document.getElementById(`point-${code}`);
|
| 63 |
+
if (existingPoint) {
|
| 64 |
+
existingPoint.remove();
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
const point = document.createElement('div');
|
| 68 |
+
point.id = `point-${code}`;
|
| 69 |
+
point.className = 'absolute w-4 h-4 bg-red-600 rounded-full transform -translate-x-1/2 -translate-y-1/2 cursor-pointer border-2 border-white shadow-md group';
|
| 70 |
+
point.style.left = `${xPx}px`;
|
| 71 |
+
point.style.top = `${yPx}px`;
|
| 72 |
+
|
| 73 |
+
// Tooltip/Label
|
| 74 |
+
const label = document.createElement('div');
|
| 75 |
+
label.className = 'absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 px-2 py-1 bg-gray-800 text-white text-xs rounded whitespace-nowrap z-10 hidden group-hover:block';
|
| 76 |
+
label.innerHTML = `
|
| 77 |
+
<strong>${code}</strong><br>
|
| 78 |
+
X: ${xVal.toFixed(1)}<br>
|
| 79 |
+
Y: ${yVal.toFixed(1)}
|
| 80 |
+
`;
|
| 81 |
+
|
| 82 |
+
point.appendChild(label);
|
| 83 |
+
planeContainer.appendChild(point);
|
| 84 |
+
|
| 85 |
+
// Also show a permanent label next to the point if desired,
|
| 86 |
+
// or just rely on the hover. For now, let's add a small text label below it.
|
| 87 |
+
const textLabel = document.createElement('span');
|
| 88 |
+
textLabel.className = 'absolute top-4 left-1/2 transform -translate-x-1/2 text-xs font-bold text-gray-700 pointer-events-none';
|
| 89 |
+
textLabel.innerText = code;
|
| 90 |
+
point.appendChild(textLabel);
|
| 91 |
+
}
|
| 92 |
+
|
tecnicas/templates/tecnicas/forms_tester/test_napping.html
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% extends 'tecnicas/layouts/base.html' %}
|
| 2 |
+
|
| 3 |
+
{% load static %}
|
| 4 |
+
|
| 5 |
+
{% block title %}Napping{% 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 |
+
{% include "../components/error-message.html" with message=error %}
|
| 34 |
+
{% endif %}
|
| 35 |
+
|
| 36 |
+
<article class="rounded flex flex-col gap-4">
|
| 37 |
+
<section class="flex items-center justify-center bg-surface-ligt p-2 rounded-lg">
|
| 38 |
+
<p class="text-lg font-medium text-center">
|
| 39 |
+
{{ session.tecnica.instrucciones }}
|
| 40 |
+
</p>
|
| 41 |
+
</section>
|
| 42 |
+
|
| 43 |
+
<section class="flex items-center justify-center flex-wrap gap-4 bg-surface-ligt p-2 rounded-lg">
|
| 44 |
+
<p class="text-xl font-bold text-center">
|
| 45 |
+
Modalidad: Napping
|
| 46 |
+
</p>
|
| 47 |
+
</section>
|
| 48 |
+
</article>
|
| 49 |
+
|
| 50 |
+
<article class="container-rating-word p-2 py-6 space-y-6 bg-surface-ligt rounded min-w-3xl">
|
| 51 |
+
<h2 class="text-xl font-bold">Productos en la sesión</h2>
|
| 52 |
+
<div id="items" class="original-products flex gap-4 flex-wrap justify-center"
|
| 53 |
+
data-original-products="original">
|
| 54 |
+
{% for product in products %}
|
| 55 |
+
<div class="item-product bg-btn-secondary text-black font-bold px-4 py-2 rounded cursor-grab transition-all"
|
| 56 |
+
data-id-product="{{ product.id }}" data-code="{{ product.codigoProducto }}">
|
| 57 |
+
{{ product.codigoProducto }}
|
| 58 |
+
</div>
|
| 59 |
+
{% endfor %}
|
| 60 |
+
</div>
|
| 61 |
+
|
| 62 |
+
<!-- Cartesian Plane Container -->
|
| 63 |
+
<div class="flex justify-center w-full">
|
| 64 |
+
<div class="relative w-full max-w-[800px] aspect-[3/2] bg-white border-2 border-gray-400 shadow-inner cursor-crosshair"
|
| 65 |
+
id="napping-plane"
|
| 66 |
+
style="background-image: linear-gradient(#e5e7eb 1px, transparent 1px), linear-gradient(90deg, #e5e7eb 1px, transparent 1px); background-size: 20px 20px;">
|
| 67 |
+
<!-- Axis Labels -->
|
| 68 |
+
<span class="absolute bottom-1 right-2 text-xs text-gray-500 font-bold">60cm (X)</span>
|
| 69 |
+
<span class="absolute top-2 left-1 text-xs text-gray-500 font-bold">40cm (Y)</span>
|
| 70 |
+
<span class="absolute bottom-1 left-1 text-xs text-gray-500 font-bold">0</span>
|
| 71 |
+
</div>
|
| 72 |
+
</div>
|
| 73 |
+
|
| 74 |
+
<!-- <section role="alert" class="alert alert-info">
|
| 75 |
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
| 76 |
+
class="h-6 w-6 shrink-0 stroke-current">
|
| 77 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
| 78 |
+
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 0 0118 0z"></path>
|
| 79 |
+
</svg>
|
| 80 |
+
<span class="text-lg">
|
| 81 |
+
Para guardar los datos sin finalizar su sesión use el botón
|
| 82 |
+
<b>"Guardar progreso"</b>
|
| 83 |
+
</span>
|
| 84 |
+
</section>
|
| 85 |
+
|
| 86 |
+
<section role="alert" class="alert alert-warning">
|
| 87 |
+
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 shrink-0 stroke-current" fill="none"
|
| 88 |
+
viewBox="0 0 24 24">
|
| 89 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
| 90 |
+
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
| 91 |
+
</svg>
|
| 92 |
+
<div class="flex-col">
|
| 93 |
+
<span class="text-lg block">
|
| 94 |
+
Si usas el botón <b>“Salir de la sesión”</b> asegúrese de guardar el progreso de lo contrario
|
| 95 |
+
perderás todo lo que no hayas guardado antes
|
| 96 |
+
</span>
|
| 97 |
+
<span class="text-lg block">
|
| 98 |
+
Con el botón <b>��Finalizar la sesión”</b>, se guardan las palabras, sales de la sesión y no
|
| 99 |
+
podrás ingresar otra vez
|
| 100 |
+
</span>
|
| 101 |
+
</div>
|
| 102 |
+
</section> -->
|
| 103 |
+
|
| 104 |
+
<!-- <section class="flex justify-end gap-4 max-sm:flex-col">
|
| 105 |
+
<button id="save-progress" class="cts-btn-general cts-btn-primary btn-push">
|
| 106 |
+
Guardar progreso
|
| 107 |
+
</button>
|
| 108 |
+
<div class="flex gap-2">
|
| 109 |
+
<button id="question-save" class="cts-btn-general cts-btn-secondary btn-push flex-1">
|
| 110 |
+
¿Finalizar sesión?
|
| 111 |
+
</button>
|
| 112 |
+
<button id="finish-session" class="cts-btn-general cts-btn-tertiary btn-push hidden flex-1">
|
| 113 |
+
Finalizar
|
| 114 |
+
</button>
|
| 115 |
+
<button id="cancel-save" class="cts-btn-general cts-btn-error btn-push hidden flex-1">
|
| 116 |
+
Cancelar
|
| 117 |
+
</button>
|
| 118 |
+
</div>
|
| 119 |
+
<span id="loading-data-save" class="loading loading-spinner loading-xl text-accent hidden"></span>
|
| 120 |
+
</section> -->
|
| 121 |
+
</article>
|
| 122 |
+
|
| 123 |
+
{% include "../components/toast-container.html" %}
|
| 124 |
+
</article>
|
| 125 |
+
</article>
|
| 126 |
+
{% endblock %}
|
| 127 |
+
|
| 128 |
+
{% block extra_js %}
|
| 129 |
+
<script src="{% static 'js/actions-form.js' %}"></script>
|
| 130 |
+
<script src="{% static 'js/test-napping.js' %}"></script>
|
| 131 |
+
{% endblock %}
|
tecnicas/urls.py
CHANGED
|
@@ -122,6 +122,10 @@ urlpatterns = [
|
|
| 122 |
views.sortTest,
|
| 123 |
name="session_sort"),
|
| 124 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
|
| 126 |
# APIs
|
| 127 |
path("presenter/api/nueva-etiqueta",
|
|
|
|
| 122 |
views.sortTest,
|
| 123 |
name="session_sort"),
|
| 124 |
|
| 125 |
+
path("testers/init-session/<str:code_sesion>/nappping",
|
| 126 |
+
views.nappingTest,
|
| 127 |
+
name="session_napping"),
|
| 128 |
+
|
| 129 |
|
| 130 |
# APIs
|
| 131 |
path("presenter/api/nueva-etiqueta",
|
tecnicas/views/__init__.py
CHANGED
|
@@ -38,3 +38,4 @@ from .tester_forms.convencional_scales import convencionalScales
|
|
| 38 |
from .tester_forms.cata_test import cataTest
|
| 39 |
from .tester_forms.pf_test import pfTest
|
| 40 |
from .tester_forms.sort_test import sortTest
|
|
|
|
|
|
| 38 |
from .tester_forms.cata_test import cataTest
|
| 39 |
from .tester_forms.pf_test import pfTest
|
| 40 |
from .tester_forms.sort_test import sortTest
|
| 41 |
+
from .tester_forms.napping_test import nappingTest
|
tecnicas/views/tester_forms/init_tester_form.py
CHANGED
|
@@ -46,7 +46,7 @@ def initTesterForm(req: HttpRequest, code_sesion: str):
|
|
| 46 |
return response
|
| 47 |
|
| 48 |
elif req.method == "POST":
|
| 49 |
-
if type_technique
|
| 50 |
view_controller = InitSessionEscalasController(
|
| 51 |
sensorial_session=session, user_tester=req.user.user_catador)
|
| 52 |
response = view_controller.controllPost(request=req)
|
|
@@ -60,7 +60,12 @@ def initTesterForm(req: HttpRequest, code_sesion: str):
|
|
| 60 |
view_controller = InitSessionSortController(
|
| 61 |
sensorial_session=session, user_tester=req.user.user_catador)
|
| 62 |
response = view_controller.controllPost(request=req)
|
| 63 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
else:
|
| 65 |
context = {
|
| 66 |
"session": session,
|
|
|
|
| 46 |
return response
|
| 47 |
|
| 48 |
elif req.method == "POST":
|
| 49 |
+
if type_technique in ["escalas", "rata", "cata"]:
|
| 50 |
view_controller = InitSessionEscalasController(
|
| 51 |
sensorial_session=session, user_tester=req.user.user_catador)
|
| 52 |
response = view_controller.controllPost(request=req)
|
|
|
|
| 60 |
view_controller = InitSessionSortController(
|
| 61 |
sensorial_session=session, user_tester=req.user.user_catador)
|
| 62 |
response = view_controller.controllPost(request=req)
|
| 63 |
+
|
| 64 |
+
elif type_technique == "napping":
|
| 65 |
+
view_controller = InitSessionNappingController(
|
| 66 |
+
sensorial_session=session, user_tester=req.user.user_catador)
|
| 67 |
+
response = view_controller.controllPost(request=req)
|
| 68 |
+
|
| 69 |
else:
|
| 70 |
context = {
|
| 71 |
"session": session,
|
tecnicas/views/tester_forms/napping_test.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from django.http import HttpRequest
|
| 2 |
+
from tecnicas.models import SesionSensorial
|
| 3 |
+
from tecnicas.controllers import TestNappingController
|
| 4 |
+
from tecnicas.utils import noValidTechnique
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
def nappingTest(req: HttpRequest, code_sesion: str):
|
| 8 |
+
if req.method == "GET":
|
| 9 |
+
session = SesionSensorial.objects.get(codigo_sesion=code_sesion)
|
| 10 |
+
controll_view = TestNappingController(
|
| 11 |
+
sensorial_session=session, user_tester=req.user.user_catador)
|
| 12 |
+
return controll_view.controllGet(request=req)
|
| 13 |
+
|
| 14 |
+
elif req.method == "POST":
|
| 15 |
+
# Se usa para finalizar la sesión
|
| 16 |
+
session = SesionSensorial.objects.get(codigo_sesion=code_sesion)
|
| 17 |
+
controll_view = TestNappingController(
|
| 18 |
+
sensorial_session=session, user_tester=req.user.user_catador)
|
| 19 |
+
return controll_view.controllPost(request=req)
|
| 20 |
+
|
| 21 |
+
else:
|
| 22 |
+
return noValidTechnique(
|
| 23 |
+
name_view="cata_system:catador_init_session",
|
| 24 |
+
query_params={
|
| 25 |
+
"error": "Método no valido"
|
| 26 |
+
}
|
| 27 |
+
)
|