Added informations about forms filled and being filled up
This commit is contained in:
parent
08262f3dfd
commit
d411d41cff
@ -2,9 +2,8 @@ package com.bernard.misael.model;
|
|||||||
|
|
||||||
import com.bernard.misael.questions.QTypes;
|
import com.bernard.misael.questions.QTypes;
|
||||||
import com.bernard.misael.questions.QuestionType;
|
import com.bernard.misael.questions.QuestionType;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.bernard.misael.service.JsonNodeConverter;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@ -36,19 +35,13 @@ public class Question {
|
|||||||
private Quizz quizz;
|
private Quizz quizz;
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
private String value;
|
@Convert(converter = JsonNodeConverter.class)
|
||||||
|
private JsonNode value;
|
||||||
|
|
||||||
transient QuestionType qtype = null;
|
transient QuestionType qtype = null;
|
||||||
public QuestionType getQT() {
|
public QuestionType getQT() {
|
||||||
if(qtype==null){
|
if(qtype==null){
|
||||||
ObjectMapper om = new ObjectMapper();
|
qtype = type.construct(value);
|
||||||
JsonNode jsNode;
|
|
||||||
try {
|
|
||||||
jsNode = om.readTree(value);
|
|
||||||
qtype = type.construct(jsNode);
|
|
||||||
} catch (JsonProcessingException e) {
|
|
||||||
throw new IllegalStateException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return qtype;
|
return qtype;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
package com.bernard.misael.repository;
|
package com.bernard.misael.repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
import com.bernard.misael.model.Answer;
|
import com.bernard.misael.model.Answer;
|
||||||
@ -9,5 +11,6 @@ import com.bernard.misael.model.QuizzForm;
|
|||||||
public interface AnswerRepository extends JpaRepository<Answer,Long> {
|
public interface AnswerRepository extends JpaRepository<Answer,Long> {
|
||||||
|
|
||||||
public Answer findByFormAndQuestion(QuizzForm qf, Question q);
|
public Answer findByFormAndQuestion(QuizzForm qf, Question q);
|
||||||
|
public List<Answer> findByFormAndQuestionIn(QuizzForm qf, List<Question> qz);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package com.bernard.misael.repository;
|
package com.bernard.misael.repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
@ -12,5 +13,6 @@ public interface QuestionRepository extends JpaRepository<Question,Long> {
|
|||||||
|
|
||||||
public Question findByQuizzAndIndex(Quizz quizz, int index);
|
public Question findByQuizzAndIndex(Quizz quizz, int index);
|
||||||
public Set<Question> findByQuizz(Quizz quizz);
|
public Set<Question> findByQuizz(Quizz quizz);
|
||||||
|
public List<Question> findByQuizzOrderByIndexAsc(Quizz quizz);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,5 +1,7 @@
|
|||||||
package com.bernard.misael.repository;
|
package com.bernard.misael.repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
import com.bernard.misael.model.Quizz;
|
import com.bernard.misael.model.Quizz;
|
||||||
@ -8,6 +10,10 @@ import com.bernard.misael.model.User;
|
|||||||
|
|
||||||
public interface QuizzFormRepository extends JpaRepository<QuizzForm,Long> {
|
public interface QuizzFormRepository extends JpaRepository<QuizzForm,Long> {
|
||||||
|
|
||||||
|
public List<QuizzForm> findByQuizz(Quizz q);
|
||||||
|
|
||||||
public QuizzForm findByUserAndQuizz(User u, Quizz q);
|
public QuizzForm findByUserAndQuizz(User u, Quizz q);
|
||||||
|
public List<QuizzForm> findByUserAndDoneTrue(User u);
|
||||||
|
public List<QuizzForm> findByUserAndDoneFalse(User u);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
package com.bernard.misael.service;
|
package com.bernard.misael.service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import com.bernard.misael.model.Quizz;
|
import com.bernard.misael.model.Quizz;
|
||||||
|
import com.bernard.misael.model.QuizzForm;
|
||||||
import com.bernard.misael.model.User;
|
import com.bernard.misael.model.User;
|
||||||
import com.bernard.misael.questions.QTypes;
|
import com.bernard.misael.questions.QTypes;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
@ -19,6 +21,8 @@ public interface QuizzManager {
|
|||||||
public List<Quizz> answerableQuizz(User user);
|
public List<Quizz> answerableQuizz(User user);
|
||||||
|
|
||||||
public boolean canEditQuizz(User user, long quizzId);
|
public boolean canEditQuizz(User user, long quizzId);
|
||||||
|
public Optional<QuizzForm> canViewQuizzForm(User user, long quizzFormId);
|
||||||
|
public Optional<Quizz> canViewQuizzFormsOfQuizz(User user, long quizzId);
|
||||||
|
|
||||||
public JsonNode getQuizzInfo(User user, long quizzId);
|
public JsonNode getQuizzInfo(User user, long quizzId);
|
||||||
public JsonNode setQuizzName(User user, long quizzId, String newName);
|
public JsonNode setQuizzName(User user, long quizzId, String newName);
|
||||||
@ -28,4 +32,7 @@ public interface QuizzManager {
|
|||||||
public JsonNode editQuestion(User user, long quizzId, long questionId, JsonNode value);
|
public JsonNode editQuestion(User user, long quizzId, long questionId, JsonNode value);
|
||||||
public JsonNode setQuestionType(User user, long quizzId, long questionId, QTypes type);
|
public JsonNode setQuestionType(User user, long quizzId, long questionId, QTypes type);
|
||||||
|
|
||||||
|
public JsonNode getQuizzFormData(User user, long quizzFormId);
|
||||||
|
public JsonNode getQuizzFormAdvancments(User user, long quizzId);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -14,16 +14,14 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import com.bernard.misael.model.Answer;
|
import com.bernard.misael.model.Answer;
|
||||||
|
import com.bernard.misael.model.Privilege;
|
||||||
import com.bernard.misael.model.Question;
|
import com.bernard.misael.model.Question;
|
||||||
import com.bernard.misael.model.Quizz;
|
import com.bernard.misael.model.Quizz;
|
||||||
import com.bernard.misael.model.QuizzForm;
|
import com.bernard.misael.model.QuizzForm;
|
||||||
import com.bernard.misael.model.User;
|
import com.bernard.misael.model.User;
|
||||||
import com.bernard.misael.questions.QTypes;
|
import com.bernard.misael.questions.QTypes;
|
||||||
import com.bernard.misael.questions.QuestionType.AnswerResult;
|
import com.bernard.misael.questions.QuestionType.AnswerResult;
|
||||||
import com.bernard.misael.repository.AnswerRepository;
|
import com.bernard.misael.repository.*;
|
||||||
import com.bernard.misael.repository.QuestionRepository;
|
|
||||||
import com.bernard.misael.repository.QuizzFormRepository;
|
|
||||||
import com.bernard.misael.repository.QuizzRepository;
|
|
||||||
import com.bernard.misael.service.exception.MalformedAnswerException;
|
import com.bernard.misael.service.exception.MalformedAnswerException;
|
||||||
import com.bernard.misael.service.exception.MalformedClientAnswerException;
|
import com.bernard.misael.service.exception.MalformedClientAnswerException;
|
||||||
import com.bernard.misael.service.exception.QuestionTypeException;
|
import com.bernard.misael.service.exception.QuestionTypeException;
|
||||||
@ -40,6 +38,9 @@ import jakarta.persistence.EntityNotFoundException;
|
|||||||
@Service
|
@Service
|
||||||
public class QuizzManagerImpl implements QuizzManager {
|
public class QuizzManagerImpl implements QuizzManager {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
UserRepository uRepository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
QuizzFormRepository qfRepository;
|
QuizzFormRepository qfRepository;
|
||||||
|
|
||||||
@ -52,6 +53,11 @@ public class QuizzManagerImpl implements QuizzManager {
|
|||||||
@Autowired
|
@Autowired
|
||||||
AnswerRepository answerRepository;
|
AnswerRepository answerRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
UserService uService;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonNode answer(User user, long quizzId, JsonNode data) {
|
public JsonNode answer(User user, long quizzId, JsonNode data) {
|
||||||
if(!data.has("index") || !data.get("index").isInt())
|
if(!data.has("index") || !data.get("index").isInt())
|
||||||
@ -268,12 +274,7 @@ public class QuizzManagerImpl implements QuizzManager {
|
|||||||
ObjectNode nn = JsonNodeFactory.instance.objectNode();
|
ObjectNode nn = JsonNodeFactory.instance.objectNode();
|
||||||
nn.set("id",JsonNodeFactory.instance.numberNode(q.getId()));
|
nn.set("id",JsonNodeFactory.instance.numberNode(q.getId()));
|
||||||
nn.set("type", JsonNodeFactory.instance.textNode(q.getType().name()));
|
nn.set("type", JsonNodeFactory.instance.textNode(q.getType().name()));
|
||||||
ObjectMapper om = new ObjectMapper();
|
nn.set("value",q.getValue());
|
||||||
try {
|
|
||||||
nn.set("value",om.readTree(q.getValue()));
|
|
||||||
} catch (JsonProcessingException e) {
|
|
||||||
throw new IllegalStateException("Value stored for question "+q.getId()+" is illegal (non-json)",e);
|
|
||||||
}
|
|
||||||
n.set(q.getIndex(),nn);
|
n.set(q.getIndex(),nn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +313,7 @@ public class QuizzManagerImpl implements QuizzManager {
|
|||||||
Question q = new Question();
|
Question q = new Question();
|
||||||
q.setType(DEFAULT_QTYPE);
|
q.setType(DEFAULT_QTYPE);
|
||||||
JsonNode n = DEFAULT_QTYPE.getDefaultQuestion();
|
JsonNode n = DEFAULT_QTYPE.getDefaultQuestion();
|
||||||
q.setValue(n.toString());
|
q.setValue(n);
|
||||||
q.setQuizz(quizz);
|
q.setQuizz(quizz);
|
||||||
q.setIndex(quizz.getQuestionCount());
|
q.setIndex(quizz.getQuestionCount());
|
||||||
quizz.setQuestionCount(quizz.getQuestionCount()+1);
|
quizz.setQuestionCount(quizz.getQuestionCount()+1);
|
||||||
@ -408,7 +409,7 @@ public class QuizzManagerImpl implements QuizzManager {
|
|||||||
|
|
||||||
if(!q.getType().validate(value))
|
if(!q.getType().validate(value))
|
||||||
return errorNode("Invalid question value");
|
return errorNode("Invalid question value");
|
||||||
q.setValue(value.toString());
|
q.setValue(value);
|
||||||
|
|
||||||
ObjectNode out = JsonNodeFactory.instance.objectNode();
|
ObjectNode out = JsonNodeFactory.instance.objectNode();
|
||||||
out.set("success", JsonNodeFactory.instance.booleanNode(true));
|
out.set("success", JsonNodeFactory.instance.booleanNode(true));
|
||||||
@ -438,14 +439,9 @@ public class QuizzManagerImpl implements QuizzManager {
|
|||||||
// Then we need to change
|
// Then we need to change
|
||||||
q.setType(type);
|
q.setType(type);
|
||||||
n = type.getDefaultQuestion();
|
n = type.getDefaultQuestion();
|
||||||
q.setValue(n.toString());
|
q.setValue(n);
|
||||||
} else {
|
} else {
|
||||||
ObjectMapper om = new ObjectMapper();
|
n =q.getValue();
|
||||||
try {
|
|
||||||
n = om.readTree(q.getValue());
|
|
||||||
} catch (JsonProcessingException e) {
|
|
||||||
throw new IllegalStateException("Value stored for question "+questionId+" is illegal (non-json)",e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectNode out = JsonNodeFactory.instance.objectNode();
|
ObjectNode out = JsonNodeFactory.instance.objectNode();
|
||||||
@ -454,4 +450,77 @@ public class QuizzManagerImpl implements QuizzManager {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<QuizzForm> canViewQuizzForm(User user, long quizzFormId) {
|
||||||
|
Optional<QuizzForm> oqf = qfRepository.findById(quizzFormId);
|
||||||
|
if(oqf.isEmpty()) return oqf;
|
||||||
|
QuizzForm qf = oqf.get();
|
||||||
|
if(!qf.isDone()) return Optional.empty();
|
||||||
|
if(qf.getUser().equals(user)) return oqf;
|
||||||
|
if(uService.hasPrivilege(user, Privilege.VIEW_ALL_FORMS)) return oqf;
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Quizz> canViewQuizzFormsOfQuizz(User user, long quizzId) {
|
||||||
|
Optional<Quizz> oq = qRepository.findById(quizzId);
|
||||||
|
if(oq.isEmpty()) return oq;
|
||||||
|
Quizz q = oq.get();
|
||||||
|
if(q.getOwner().equals(user)) return oq;
|
||||||
|
if(uService.hasPrivilege(user, Privilege.VIEW_ALL_FORMS)) return oq;
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonNode getQuizzFormData(User user, long quizzFormId) {
|
||||||
|
Optional<QuizzForm> oqf = canViewQuizzForm(user, quizzFormId);
|
||||||
|
if(oqf.isEmpty())
|
||||||
|
return errorNode("Could not access the quizzform"); //TODO more precise error node
|
||||||
|
QuizzForm form = oqf.get();
|
||||||
|
List<Question> questions = questionRepository.findByQuizzOrderByIndexAsc(form.getQuizz());
|
||||||
|
List<Answer> answers = answerRepository.findByFormAndQuestionIn(form, questions);
|
||||||
|
assert questions.size() == answers.size();
|
||||||
|
ArrayNode answersNode = JsonNodeFactory.instance.arrayNode();
|
||||||
|
for(int i=0;i<questions.size();i++) {
|
||||||
|
ObjectNode anode = JsonNodeFactory.instance.objectNode();
|
||||||
|
anode.set("qid", JsonNodeFactory.instance.numberNode(questions.get(i).getId()));
|
||||||
|
anode.set("type", JsonNodeFactory.instance.textNode(questions.get(i).getType().name()));
|
||||||
|
anode.set("qvalue", questions.get(i).getValue());
|
||||||
|
anode.set("aid", JsonNodeFactory.instance.numberNode(answers.get(i).getId()));
|
||||||
|
anode.set("avalue", answers.get(i).getValue());
|
||||||
|
answersNode.add(anode);
|
||||||
|
}
|
||||||
|
ObjectNode out = JsonNodeFactory.instance.objectNode();
|
||||||
|
out.set("success", JsonNodeFactory.instance.booleanNode(true));
|
||||||
|
out.set("data", answersNode);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonNode getQuizzFormAdvancments(User user, long quizzId) {
|
||||||
|
Optional<Quizz> oq = canViewQuizzFormsOfQuizz(user, quizzId);
|
||||||
|
if(oq.isEmpty())
|
||||||
|
return errorNode("Could not access the forms for this quizz"); //TODO more precise error node
|
||||||
|
Quizz quizz = oq.get();
|
||||||
|
List<QuizzForm> quizzForms = qfRepository.findByQuizz(quizz);
|
||||||
|
quizzForms.sort((qfa,qfb) -> qfa.getUser().getName().compareTo(qfb.getUser().getName()));
|
||||||
|
|
||||||
|
ArrayNode formsNode = JsonNodeFactory.instance.arrayNode();
|
||||||
|
for(QuizzForm qf : quizzForms) {
|
||||||
|
ObjectNode anode = JsonNodeFactory.instance.objectNode();
|
||||||
|
anode.set("qfid", JsonNodeFactory.instance.numberNode(qf.getId()));
|
||||||
|
anode.set("done", JsonNodeFactory.instance.booleanNode(qf.isDone()));
|
||||||
|
anode.set("position", JsonNodeFactory.instance.numberNode(qf.getCurrentQuestion()));
|
||||||
|
anode.set("step", JsonNodeFactory.instance.numberNode(qf.getAnswerStep()));
|
||||||
|
anode.set("username", JsonNodeFactory.instance.textNode(qf.getUser().getName()));
|
||||||
|
formsNode.add(anode);
|
||||||
|
}
|
||||||
|
ObjectNode out = JsonNodeFactory.instance.objectNode();
|
||||||
|
out.set("success", JsonNodeFactory.instance.booleanNode(true));
|
||||||
|
out.set("data", formsNode);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package com.bernard.misael.service;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.bernard.misael.model.Privilege;
|
||||||
import com.bernard.misael.model.User;
|
import com.bernard.misael.model.User;
|
||||||
import com.bernard.misael.service.dto.UserDto;
|
import com.bernard.misael.service.dto.UserDto;
|
||||||
|
|
||||||
@ -13,4 +14,6 @@ public interface UserService {
|
|||||||
User findUserByName(String name);
|
User findUserByName(String name);
|
||||||
|
|
||||||
List<UserDto> findAllUsers();
|
List<UserDto> findAllUsers();
|
||||||
|
|
||||||
|
boolean hasPrivilege(User u, Privilege p);
|
||||||
}
|
}
|
||||||
@ -5,6 +5,7 @@ import java.util.stream.Collectors;
|
|||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.bernard.misael.model.Privilege;
|
||||||
import com.bernard.misael.model.User;
|
import com.bernard.misael.model.User;
|
||||||
import com.bernard.misael.repository.UserRepository;
|
import com.bernard.misael.repository.UserRepository;
|
||||||
import com.bernard.misael.service.dto.UserDto;
|
import com.bernard.misael.service.dto.UserDto;
|
||||||
@ -54,4 +55,10 @@ public class UserServiceImpl implements UserService {
|
|||||||
userDto.setName(user.getName());
|
userDto.setName(user.getName());
|
||||||
return userDto;
|
return userDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPrivilege(User u, Privilege p) {
|
||||||
|
//TODO faire une query sql propre avec ça
|
||||||
|
return u.getRoles().stream().anyMatch(r -> r.getPrivileges().contains(p));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -43,7 +43,6 @@ public class AuthController {
|
|||||||
|
|
||||||
@GetMapping("/")
|
@GetMapping("/")
|
||||||
public String index(Model model) {
|
public String index(Model model) {
|
||||||
|
|
||||||
return "index";
|
return "index";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,16 +10,18 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.HttpStatusCode;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.access.annotation.Secured;
|
import org.springframework.security.access.annotation.Secured;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
import com.bernard.misael.model.Privilege;
|
|
||||||
import com.bernard.misael.model.Quizz;
|
import com.bernard.misael.model.Quizz;
|
||||||
|
import com.bernard.misael.model.QuizzForm;
|
||||||
import com.bernard.misael.model.User;
|
import com.bernard.misael.model.User;
|
||||||
import com.bernard.misael.questions.QTypes;
|
import com.bernard.misael.questions.QTypes;
|
||||||
|
import com.bernard.misael.repository.QuizzFormRepository;
|
||||||
import com.bernard.misael.repository.QuizzRepository;
|
import com.bernard.misael.repository.QuizzRepository;
|
||||||
import com.bernard.misael.repository.UserRepository;
|
import com.bernard.misael.repository.UserRepository;
|
||||||
import com.bernard.misael.service.QuizzManager;
|
import com.bernard.misael.service.QuizzManager;
|
||||||
@ -47,10 +49,13 @@ public class QuestionsController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
QuizzRepository qrepo;
|
QuizzRepository qrepo;
|
||||||
|
|
||||||
@GetMapping("/quizz")
|
@Autowired
|
||||||
|
QuizzFormRepository qfrepo;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* List all quizz
|
* List all quizz
|
||||||
*/
|
*/
|
||||||
|
@GetMapping("/quizz")
|
||||||
public String getQuizz(Model model, Principal p) {
|
public String getQuizz(Model model, Principal p) {
|
||||||
User u = null;
|
User u = null;
|
||||||
if (p!=null)
|
if (p!=null)
|
||||||
@ -63,14 +68,88 @@ public class QuestionsController {
|
|||||||
return "quizz.html";
|
return "quizz.html";
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/forms")
|
|
||||||
/*
|
/*
|
||||||
* List all forms started or finished by the user
|
* List all forms started or finished by the user
|
||||||
*/
|
*/
|
||||||
public String getForms() {
|
@GetMapping("/forms")
|
||||||
|
public String getForms(Model model, Principal p) {
|
||||||
|
User u = null;
|
||||||
|
if (p!=null)
|
||||||
|
u = ur.findByName(p.getName());
|
||||||
|
if(u!=null) {
|
||||||
|
model.addAttribute("finishedForms",qfrepo.findByUserAndDoneTrue(u));
|
||||||
|
model.addAttribute("openForms",qfrepo.findByUserAndDoneFalse(u));
|
||||||
|
}
|
||||||
|
|
||||||
return "forms.html";
|
return "forms.html";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show one (completed) form of one user
|
||||||
|
*/
|
||||||
|
@GetMapping("/showform/{id}")
|
||||||
|
public Object showForm(@PathVariable("id") long id, Model m, Principal p) {
|
||||||
|
User u = null;
|
||||||
|
if (p!=null)
|
||||||
|
u = ur.findByName(p.getName());
|
||||||
|
if(u==null)
|
||||||
|
return "redirect:/login?restricted";
|
||||||
|
Optional<QuizzForm> oqf = qm.canViewQuizzForm(u, id);
|
||||||
|
if (oqf.isEmpty())
|
||||||
|
//TODO Faire un mesasge d'erreur dépendant des circonstances (unatuhorized, not found, not complete ...)
|
||||||
|
return new ResponseEntity<>(JsonNodeFactory.instance.objectNode(),HttpStatus.UNAUTHORIZED);
|
||||||
|
|
||||||
|
m.addAttribute("formId", id);
|
||||||
|
return "showform.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show one (completed) form of one user
|
||||||
|
*/
|
||||||
|
@GetMapping("/showformsadvancements/{id}")
|
||||||
|
public Object showFormsAdvancements(@PathVariable("id") long id, Model m, Principal p) {
|
||||||
|
User u = null;
|
||||||
|
if (p!=null)
|
||||||
|
u = ur.findByName(p.getName());
|
||||||
|
if(u==null)
|
||||||
|
return "redirect:/login?restricted";
|
||||||
|
Optional<Quizz> oq = qm.canViewQuizzFormsOfQuizz(u, id);
|
||||||
|
if (oq.isEmpty())
|
||||||
|
//TODO Faire un mesasge d'erreur dépendant des circonstances (unatuhorized, not found, not complete ...)
|
||||||
|
return new ResponseEntity<>(JsonNodeFactory.instance.objectNode(),HttpStatus.UNAUTHORIZED);
|
||||||
|
|
||||||
|
m.addAttribute("quizzId", id);
|
||||||
|
return "showformadvancements.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* API get the form
|
||||||
|
*/
|
||||||
|
@PostMapping("/getformdata/{id}")
|
||||||
|
public Object showFormApi(@PathVariable("id") long id, Principal p) {
|
||||||
|
User u = null;
|
||||||
|
if (p!=null)
|
||||||
|
u = ur.findByName(p.getName());
|
||||||
|
if(u==null)
|
||||||
|
return "redirect:/login?restricted";
|
||||||
|
JsonNode out = qm.getQuizzFormData(u, id);
|
||||||
|
return new ResponseEntity<>(out, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* API get the form
|
||||||
|
*/
|
||||||
|
@PostMapping("/getformadvancements/{id}")
|
||||||
|
public Object showFormAdvancements(@PathVariable("id") long id, Principal p) {
|
||||||
|
User u = null;
|
||||||
|
if (p!=null)
|
||||||
|
u = ur.findByName(p.getName());
|
||||||
|
if(u==null)
|
||||||
|
return "redirect:/login?restricted";
|
||||||
|
JsonNode out = qm.getQuizzFormAdvancments(u, id);
|
||||||
|
return new ResponseEntity<>(out, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/form/{q}")
|
@GetMapping("/form/{q}")
|
||||||
public String formpage(@PathVariable("q") long quizzId, Principal p, Model m) {
|
public String formpage(@PathVariable("q") long quizzId, Principal p, Model m) {
|
||||||
if (p==null)
|
if (p==null)
|
||||||
|
|||||||
28
src/main/resources/static/css/showform.css
Normal file
28
src/main/resources/static/css/showform.css
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
main h1 input, main h1 span{
|
||||||
|
font-size: 30pt;
|
||||||
|
font-weight: bold;
|
||||||
|
color: teal;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol#questions-list {
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
ol#questions-list li {
|
||||||
|
width: 90%;
|
||||||
|
background-color: lemonchiffon;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* DCC */
|
||||||
|
ol#questions-list li.dcc-box {
|
||||||
|
background-color: gainsboro;
|
||||||
|
color: black;
|
||||||
|
font-size: 12pt;
|
||||||
|
}
|
||||||
|
li.dcc-box h5 {
|
||||||
|
font-size: 12pt;
|
||||||
|
font-weight: bold;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
33
src/main/resources/static/css/showformadvancements.css
Normal file
33
src/main/resources/static/css/showformadvancements.css
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
main h1 input, main h1 span{
|
||||||
|
font-size: 30pt;
|
||||||
|
font-weight: bold;
|
||||||
|
color: teal;
|
||||||
|
}
|
||||||
|
|
||||||
|
table#forms-table {
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
table#forms-table tr {
|
||||||
|
width: 90%;
|
||||||
|
background-color: lemonchiffon;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* DCC */
|
||||||
|
table#forms-table tbody tr.done-true {
|
||||||
|
background-color: rgb(161, 161, 161);
|
||||||
|
color: black;
|
||||||
|
font-size: 12pt;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
table#forms-table tbody tr {
|
||||||
|
background-color: gainsboro;
|
||||||
|
color: black;
|
||||||
|
font-size: 12pt;
|
||||||
|
}
|
||||||
|
table#forms-table thead tr {
|
||||||
|
font-size: 14pt;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
@ -7,11 +7,15 @@
|
|||||||
<body>
|
<body>
|
||||||
<div th:replace="~{header}"/>
|
<div th:replace="~{header}"/>
|
||||||
<main>
|
<main>
|
||||||
|
<h3>Formulaires terminés</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/questions/form?f=132">Formulaire de réponse au quizz numéro 1</a></li>
|
<li th:if="${#lists.isEmpty(finishedForms)}">Vous n'avez fini aucun formulaire !</li>
|
||||||
<li><a href="/questions/form?f=177">Formulaire de réponse au quizz numéro 2</a></li>
|
<li th:each="qf : ${finishedForms}"><a th:href="@{/questions/showform/{id}(id=${qf.id})}">Quizz <span th:text="${qf.quizz.name}"/></a></li>
|
||||||
<li><a href="/questions/form?f=16818">Formulaire de réponse au quizz numéro 3</a></li>
|
</ul>
|
||||||
|
<h3>Formulaires non terminés</h3>
|
||||||
|
<ul>
|
||||||
|
<li th:if="${#lists.isEmpty(openForms)}">Aucun formulaire ici !</li>
|
||||||
|
<li th:each="qf : ${openForms}"><a th:href="@{/questions/form/{id}(id=${qf.quizz.id})}">Quizz <span th:text="${qf.quizz.name}"/></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
83
src/main/resources/templates/showform.html
Normal file
83
src/main/resources/templates/showform.html
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<div th:replace="~{html-head}"/>
|
||||||
|
<link rel="stylesheet" th:href="@{/css/showform.css}"/>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div th:replace="~{header}"/>
|
||||||
|
<script th:src="@{/webjars/jquery/1.9.1/jquery.min.js}" type="text/javascript"></script>
|
||||||
|
<script th:src="@{/webjars/lodash/4.17.21/lodash.js}" type="text/javascript"></script>
|
||||||
|
<main>
|
||||||
|
|
||||||
|
<ol id="questions-list">
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<span id="error-textbox" style="color: red"></span>
|
||||||
|
|
||||||
|
<script th:inline="javascript">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
var formid = /*[[${formId}]]*/ -1;
|
||||||
|
/*]]>*/
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
function error(txt) {
|
||||||
|
console.log(txt)
|
||||||
|
$("#error-textbox").text(txt)
|
||||||
|
}
|
||||||
|
QTYPES = {
|
||||||
|
"DCC": makeAnswerBlockBCC,
|
||||||
|
}
|
||||||
|
|
||||||
|
// question position -> question data
|
||||||
|
questiondata=[]
|
||||||
|
|
||||||
|
function getdata() {
|
||||||
|
$.ajax({
|
||||||
|
url: "/questions/getformdata/"+formid,
|
||||||
|
type: "POST",
|
||||||
|
dataType: "json",
|
||||||
|
success: function(res) {
|
||||||
|
console.log(res)
|
||||||
|
if(!res["success"]) {
|
||||||
|
console.log(res["message"])
|
||||||
|
error(res["message"])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
questiondata=res["data"]
|
||||||
|
|
||||||
|
for(let qd of questiondata) {
|
||||||
|
content = QTYPES[qd["type"]](qd["qid"],qd["qvalue"],qd["avalue"])
|
||||||
|
$(`#questions-list`).append(content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeAnswerBlockBCC(id,qvalue,avalue) {
|
||||||
|
switch(avalue["type"]){
|
||||||
|
case 4:
|
||||||
|
dcc = "carré"
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
dcc = "duo"
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
dcc = "cache"
|
||||||
|
}
|
||||||
|
html = `
|
||||||
|
<li class="dcc-box" id="q-${id}">
|
||||||
|
<h5>${_.escape(qvalue["text"])}</h5>
|
||||||
|
Réponse ${dcc}: ${_.escape(avalue["answer"])}
|
||||||
|
</li>
|
||||||
|
`
|
||||||
|
out = $('<li/>').html(html).contents()
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
getdata()
|
||||||
|
</script>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
81
src/main/resources/templates/showformadvancements.html
Normal file
81
src/main/resources/templates/showformadvancements.html
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<div th:replace="~{html-head}"/>
|
||||||
|
<link rel="stylesheet" th:href="@{/css/showformadvancements.css}"/>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div th:replace="~{header}"/>
|
||||||
|
<script th:src="@{/webjars/jquery/1.9.1/jquery.min.js}" type="text/javascript"></script>
|
||||||
|
<script th:src="@{/webjars/lodash/4.17.21/lodash.js}" type="text/javascript"></script>
|
||||||
|
<main>
|
||||||
|
|
||||||
|
<button id="refresh-data">Refresh</button>
|
||||||
|
<table id="forms-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>User</th>
|
||||||
|
<th>Position</th>
|
||||||
|
<th>Step</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="forms-body">
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<span id="error-textbox" style="color: red"></span>
|
||||||
|
|
||||||
|
<script th:inline="javascript">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
var quizzid = /*[[${quizzId}]]*/ -1;
|
||||||
|
/*]]>*/
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
function error(txt) {
|
||||||
|
console.log(txt)
|
||||||
|
$("#error-textbox").text(txt)
|
||||||
|
}
|
||||||
|
|
||||||
|
formsdata=[]
|
||||||
|
|
||||||
|
function getdata() {
|
||||||
|
$('#refresh-data').prop('disabled',true)
|
||||||
|
$.ajax({
|
||||||
|
url: "/questions/getformadvancements/"+quizzid,
|
||||||
|
type: "POST",
|
||||||
|
dataType: "json",
|
||||||
|
success: function(res) {
|
||||||
|
console.log(res)
|
||||||
|
if(!res["success"]) {
|
||||||
|
console.log(res["message"])
|
||||||
|
error(res["message"])
|
||||||
|
$('#refresh-data').prop('disabled',false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
formsdata=res["data"]
|
||||||
|
|
||||||
|
$('.form-line').remove()
|
||||||
|
for(let qf of formsdata) {
|
||||||
|
html = `
|
||||||
|
<tr class="form-line done-${qf["done"]}" id="q-${qf["qfid"]}">
|
||||||
|
<td>${qf["username"]}</td>
|
||||||
|
<td>${qf["position"]}</td>
|
||||||
|
<td>${qf["step"]}</td>
|
||||||
|
</tr>
|
||||||
|
`
|
||||||
|
content = $('<li/>').html(html).contents()
|
||||||
|
$(`#forms-body`).append(content)
|
||||||
|
}
|
||||||
|
$('#refresh-data').prop('disabled',false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#refresh-data').on('click',getdata)
|
||||||
|
getdata()
|
||||||
|
</script>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
x
Reference in New Issue
Block a user