Commit 445e1a82 authored by François-Xavier Lebastard's avatar François-Xavier Lebastard
Browse files

Merge branch 'feature/gestion_des_ecrans' into 'develop'

gestion des écrans

See merge request !59
parents d9180922 fc8cb7e7
...@@ -69,11 +69,7 @@ out/ ...@@ -69,11 +69,7 @@ out/
###################### ######################
# Visual Studio Code # Visual Studio Code
###################### ######################
.vscode/* .vscode/
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace *.code-workspace
###################### ######################
......
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -47,6 +47,13 @@ public class Screen implements Serializable { ...@@ -47,6 +47,13 @@ public class Screen implements Serializable {
@Column(name = "name", nullable = false, unique = true) @Column(name = "name", nullable = false, unique = true)
private String name; private String name;
/**
* Nom de l'écran : pour l'affichage uniquement
*/
@NotNull
@Column(name = "name_bo", nullable = false, unique = true)
private String nameBo;
/** /**
* reference du screen pour constituer l'URL * reference du screen pour constituer l'URL
*/ */
...@@ -79,19 +86,16 @@ public class Screen implements Serializable { ...@@ -79,19 +86,16 @@ public class Screen implements Serializable {
@Column(name = "items", nullable = false) @Column(name = "items", nullable = false)
private String items; private String items;
@JsonIgnoreProperties(value = { "previous", "next", "form" }, allowSetters = true)
@OneToOne
@JoinColumn(unique = true)
private Screen previous;
@JsonIgnoreProperties(value = { "previous", "next", "form" }, allowSetters = true)
@OneToOne(mappedBy = "previous")
private Screen next;
@ManyToOne @ManyToOne
@JsonIgnoreProperties(value = { "screens", "variables", "workspace" }, allowSetters = true) @JsonIgnoreProperties(value = { "screens", "variables", "workspace" }, allowSetters = true)
private Form form; private Form form;
/**
* La position de l'écran dans le back-office.
*/
@Column(name = "index")
private Integer index;
// jhipster-needle-entity-add-field - JHipster will add fields here // jhipster-needle-entity-add-field - JHipster will add fields here
public Long getId() { public Long getId() {
return id; return id;
...@@ -115,6 +119,15 @@ public class Screen implements Serializable { ...@@ -115,6 +119,15 @@ public class Screen implements Serializable {
return this; return this;
} }
public Screen nameBo(final String nameBo) {
this.nameBo = nameBo;
return this;
}
public Screen index(final Integer index) {
this.index = index;
return this;
}
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
} }
...@@ -203,51 +216,34 @@ public class Screen implements Serializable { ...@@ -203,51 +216,34 @@ public class Screen implements Serializable {
this.items = items; this.items = items;
} }
public Screen getPrevious() { public Form getForm() {
return this.previous; return this.form;
} }
public Screen previous(Screen screen) { public Screen form(Form form) {
this.setPrevious(screen); this.setForm(form);
return this; return this;
} }
public void setPrevious(Screen screen) { public void setForm(Form form) {
this.previous = screen; this.form = form;
}
public Screen getNext() {
return this.next;
}
public Screen next(Screen screen) {
this.setNext(screen);
return this;
} }
public void setNext(Screen screen) { public Integer getIndex() {
if (this.next != null) { return index;
this.next.setPrevious(null);
}
if (next != null) {
next.setPrevious(this);
}
this.next = screen;
} }
public Form getForm() { public void setIndex(Integer index) {
return this.form; this.index = index;
} }
public Screen form(Form form) { public String getNameBo() {
this.setForm(form); return nameBo;
return this;
} }
public void setForm(Form form) { public void setNameBo(String nameBo) {
this.form = form; this.nameBo = nameBo;
} }
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here
@Override @Override
......
...@@ -67,8 +67,6 @@ public class FilArianeController { ...@@ -67,8 +67,6 @@ public class FilArianeController {
public String getUserHome() { public String getUserHome() {
if (PermissionService.currentUserHasAuthority(AuthoritiesConstants.AUTHORITY_VIEW_WORKSPACE)) { if (PermissionService.currentUserHasAuthority(AuthoritiesConstants.AUTHORITY_VIEW_WORKSPACE)) {
return Path.LIST_WORKSPACES; return Path.LIST_WORKSPACES;
} else if (PermissionService.currentUserHasAuthority(AuthoritiesConstants.AUTHORITY_VIEW_FORMS)) {
return Path.LIST_FORMS;
} else if (PermissionService.currentUserHasAuthority(AuthoritiesConstants.AUTHORITY_VIEW_FORM)) { } else if (PermissionService.currentUserHasAuthority(AuthoritiesConstants.AUTHORITY_VIEW_FORM)) {
return Path.LIST_FORMS; return Path.LIST_FORMS;
} }
......
...@@ -5,10 +5,10 @@ package com.unantes.orientactive.filariane; ...@@ -5,10 +5,10 @@ package com.unantes.orientactive.filariane;
*/ */
public class Path { public class Path {
public static final String HOME = "/admin/workspace/list"; public static final String HOME = "/admin/workspace";
public static final String WORKSPACE = "/admin/workspace"; public static final String WORKSPACE = "/admin/workspace";
public static final String FORMS = "/admin/forms"; public static final String FORMS = "/admin/forms";
public static final String LIST_WORKSPACES = "/admin/workspaces/list"; public static final String LIST_WORKSPACES = "/admin/workspaces";
public static final String LIST_FORMS = "/admin/forms"; public static final String LIST_FORMS = "/admin/forms";
} }
...@@ -335,4 +335,22 @@ public class NavigationService { ...@@ -335,4 +335,22 @@ public class NavigationService {
throw new RequiredAnswersMissingException(requiredQuestionsWithoutAnswers); throw new RequiredAnswersMissingException(requiredQuestionsWithoutAnswers);
} }
} }
/**
* Permet de savoir si un écran est le dernier écran du formulaire.
*
* @return Vrai si l'écran est le dernier écran, sinon faux.
*/
public boolean checkIsLastScreen(final ScreenDTO screenDTO) {
return screenService.findScreenByIndexAndFormId(screenDTO.getNextIndex(), screenDTO.getFormId()).isEmpty();
}
/**
* Permet de savoir si un écran est le premier écran du formulaire.
*
* @return Vrai si l'écran est le premier écran, sinon faux.
*/
public boolean checkIsFirstScreen(final ScreenDTO screenDTO) {
return screenDTO.getIndex() == 1;
}
} }
...@@ -12,17 +12,18 @@ import com.unantes.orientactive.service.dto.NextScreenExpressionDTO; ...@@ -12,17 +12,18 @@ import com.unantes.orientactive.service.dto.NextScreenExpressionDTO;
import com.unantes.orientactive.service.dto.ScreenDTO; import com.unantes.orientactive.service.dto.ScreenDTO;
import com.unantes.orientactive.service.dto.VariableDTO; import com.unantes.orientactive.service.dto.VariableDTO;
import com.unantes.orientactive.web.rest.errors.UnableToFindNextScreenException; import com.unantes.orientactive.web.rest.errors.UnableToFindNextScreenException;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/** /**
* Ce service contient la logique de navigation d'un écran vers le suivant. Il contient également les méthodes permettants de déterminer si un item doit être affiché. * Ce service contient la logique de navigation d'un écran vers le suivant. Il contient également les méthodes permettants de déterminer si un item doit être affiché.
*/ */
...@@ -48,8 +49,9 @@ public class ScreenNavigationService { ...@@ -48,8 +49,9 @@ public class ScreenNavigationService {
/** /**
* Constructure. * Constructure.
* @param screenService {@link #screenService} *
* @param answerService {@link #answerService} * @param screenService {@link #screenService}
* @param answerService {@link #answerService}
* @param variableService {@link #variableService} * @param variableService {@link #variableService}
*/ */
public ScreenNavigationService(ScreenService screenService, AnswerService answerService, VariableService variableService) { public ScreenNavigationService(ScreenService screenService, AnswerService answerService, VariableService variableService) {
...@@ -64,15 +66,16 @@ public class ScreenNavigationService { ...@@ -64,15 +66,16 @@ public class ScreenNavigationService {
* Chaque expression de {@link Screen#getNextScreenExpressions()} est évaluée : la première qui est vérifiée donne l'écran suivant. * Chaque expression de {@link Screen#getNextScreenExpressions()} est évaluée : la première qui est vérifiée donne l'écran suivant.
* Si aucune n'est vérifiée, {@link Screen#getDefaultNextScreenReference()} est utilisé s'il est non vide * Si aucune n'est vérifiée, {@link Screen#getDefaultNextScreenReference()} est utilisé s'il est non vide
* {@link Screen#getNext()} est utilisé en dernier recours. * {@link Screen#getNext()} est utilisé en dernier recours.
*
* @param sessionId une session de réponses (l'identifiant commun à toutes les réponses d'un utilisateur) * @param sessionId une session de réponses (l'identifiant commun à toutes les réponses d'un utilisateur)
* @param screen l'écran courant de l'utilisateur * @param screen l'écran courant de l'utilisateur
* @return * @return
* @throws UnableToFindNextScreenException la méthode a été appelée avec un écran final ou l'expression du screen courant retourne un screen qui n'existe pas * @throws UnableToFindNextScreenException la méthode a été appelée avec un écran final ou l'expression du screen courant retourne un screen qui n'existe pas
*
*/ */
public ScreenDTO getNextScreen(final String sessionId, final ScreenDTO screen) throws UnableToFindNextScreenException { public ScreenDTO getNextScreen(final String sessionId, final ScreenDTO screen) throws UnableToFindNextScreenException {
// il ne faut pas appeler cette méthode lorsque l'écran courant est le dernier ! // il ne faut pas appeler cette méthode lorsque l'écran courant est le dernier !
if (screen.getNextId() == null) { Optional<ScreenDTO> screenDTO = screenService.findScreenByIndexAndFormId(screen.getNextIndex(), screen.getFormId());
if (screenDTO.isEmpty()) {
throw new UnableToFindNextScreenException(); throw new UnableToFindNextScreenException();
} }
// initialisation d'une expression. Elle est utilisée pour evaluer les expressions permettant de déterminer les écrans suivants et pour filter les items affichés dans l'écran suivant. // initialisation d'une expression. Elle est utilisée pour evaluer les expressions permettant de déterminer les écrans suivants et pour filter les items affichés dans l'écran suivant.
...@@ -91,8 +94,9 @@ public class ScreenNavigationService { ...@@ -91,8 +94,9 @@ public class ScreenNavigationService {
/** /**
* Détermine l'écran suivant en fonction des expressions {@link ScreenDTO#getNextScreenExpressions()}. * Détermine l'écran suivant en fonction des expressions {@link ScreenDTO#getNextScreenExpressions()}.
*
* @param expression le moteur d'expressions SpEL initialisé avec les données de l'utilisateur * @param expression le moteur d'expressions SpEL initialisé avec les données de l'utilisateur
* @param screen l'écran courant * @param screen l'écran courant
* @return * @return
*/ */
private ScreenDTO getNextScreenFromExpressions(final Expression expression, final ScreenDTO screen) { private ScreenDTO getNextScreenFromExpressions(final Expression expression, final ScreenDTO screen) {
...@@ -112,30 +116,33 @@ public class ScreenNavigationService { ...@@ -112,30 +116,33 @@ public class ScreenNavigationService {
/** /**
* Deux écrans par défaut possibles : * Deux écrans par défaut possibles :
* <ul> * <ul>
* <li>{@link Screen#getDefaultNextScreenReference()}; utilisé si renseigné</li> * <li>{@link Screen#getDefaultNextScreenReference()}; utilisé si renseigné</li>
* <li>{@link Screen#getNext()}; champ obligatoire; utilisé pour définir l'ordre en back office et en dernier recours pour l'ordre en front.</li> * <li>{@link Screen#getNext()}; champ obligatoire; utilisé pour définir l'ordre en back office et en dernier recours pour l'ordre en front.</li>
* </ul> * </ul>
*
* @param screen * @param screen
* @return * @return
*/ */
private ScreenDTO getDefaultNextScreen(final ScreenDTO screen) { private ScreenDTO getDefaultNextScreen(final ScreenDTO screen) {
if (StringUtils.isBlank(screen.getDefaultNextScreenReference())) { if (StringUtils.isBlank(screen.getDefaultNextScreenReference())) {
return getScreenById(screen.getNextId()); return getScreenByIndexAndFormId(screen.getNextIndex(), screen.getFormId());
} }
return getScreenByRef(screen.getDefaultNextScreenReference()); return getScreenByRef(screen.getDefaultNextScreenReference());
} }
/** /**
* Wrapper de la méthode {@link ScreenService#findOne(Long)}; Jette une exception si l'écran n'existe pas. * Wrapper de la méthode {@link ScreenService#findOne(Long)}; Jette une exception si l'écran n'existe pas.
*
* @param nextId * @param nextId
* @return * @return
*/ */
private ScreenDTO getScreenById(final Long nextId) { private ScreenDTO getScreenByIndexAndFormId(final Integer index, final Long formId) {
return screenService.findOne(nextId).orElseThrow(() -> new UnableToFindNextScreenException("l'écran n'existe pas en base")); return screenService.findScreenByIndexAndFormId(index, formId).orElseThrow(() -> new UnableToFindNextScreenException("l'écran n'existe pas en base"));
} }
/** /**
* Wrapper de la méthode {@link ScreenService#findOneByReference(String)}; Jette une exception si l'écran n'existe pas. * Wrapper de la méthode {@link ScreenService#findOneByReference(String)}; Jette une exception si l'écran n'existe pas.
*
* @param screenRef * @param screenRef
* @return * @return
*/ */
...@@ -147,8 +154,9 @@ public class ScreenNavigationService { ...@@ -147,8 +154,9 @@ public class ScreenNavigationService {
/** /**
* Filtre les items de l'écran courant en fonction des conditions d'affichage de chaque item. * Filtre les items de l'écran courant en fonction des conditions d'affichage de chaque item.
*
* @param sessionId pour retrouver les réponses de la session courante * @param sessionId pour retrouver les réponses de la session courante
* @param screen un écran qui contient les items à filtrer * @param screen un écran qui contient les items à filtrer
*/ */
public void filterScreenItems(final String sessionId, final ScreenDTO screen) { public void filterScreenItems(final String sessionId, final ScreenDTO screen) {
final Expression expression = initializeExpression(screen.getFormId(), sessionId); final Expression expression = initializeExpression(screen.getFormId(), sessionId);
...@@ -157,7 +165,8 @@ public class ScreenNavigationService { ...@@ -157,7 +165,8 @@ public class ScreenNavigationService {
/** /**
* Filtre les items de l'écran courant en fonction des conditions d'affichage de chaque item. * Filtre les items de l'écran courant en fonction des conditions d'affichage de chaque item.
* @param screen un écran qui contient les items à filtrer *
* @param screen un écran qui contient les items à filtrer
* @param expressionEngine l'expression initialisée avec les réponses de l'utilisateur * @param expressionEngine l'expression initialisée avec les réponses de l'utilisateur
*/ */
protected void filterScreenItems(final ScreenDTO screen, final Expression expressionEngine) { protected void filterScreenItems(final ScreenDTO screen, final Expression expressionEngine) {
...@@ -179,7 +188,8 @@ public class ScreenNavigationService { ...@@ -179,7 +188,8 @@ public class ScreenNavigationService {
/** /**
* Créer une expresison à partir de la session et du formulaire. * Créer une expresison à partir de la session et du formulaire.
* @param formId pour charger les réponses et les variables associés au formulaire *
* @param formId pour charger les réponses et les variables associés au formulaire
* @param sessionId pour charger les réponses * @param sessionId pour charger les réponses
* @return * @return
*/ */
...@@ -196,6 +206,7 @@ public class ScreenNavigationService { ...@@ -196,6 +206,7 @@ public class ScreenNavigationService {
/** /**
* Construit une lambda qui pemet de déterminer si un item doit être affiché dans une écran. * Construit une lambda qui pemet de déterminer si un item doit être affiché dans une écran.
*
* @param expression une expression initialisée avec les réponses de l'utilisateur * @param expression une expression initialisée avec les réponses de l'utilisateur
* @return * @return
*/ */
......
...@@ -2,11 +2,13 @@ package com.unantes.orientactive.repository; ...@@ -2,11 +2,13 @@ package com.unantes.orientactive.repository;
import com.unantes.orientactive.domain.Screen; import com.unantes.orientactive.domain.Screen;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Optional; import java.util.Optional;
/** /**
...@@ -15,7 +17,6 @@ import java.util.Optional; ...@@ -15,7 +17,6 @@ import java.util.Optional;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Repository @Repository
public interface ScreenRepository extends JpaRepository<Screen, Long> { public interface ScreenRepository extends JpaRepository<Screen, Long> {
/** /**
* Récupération d'un écran par sa référence. * Récupération d'un écran par sa référence.
* *
...@@ -30,7 +31,10 @@ public interface ScreenRepository extends JpaRepository<Screen, Long> { ...@@ -30,7 +31,10 @@ public interface ScreenRepository extends JpaRepository<Screen, Long> {
* @param formId L'identifiant du formulaire. * @param formId L'identifiant du formulaire.
* @return Le premier écran du formulaire s'il existe. * @return Le premier écran du formulaire s'il existe.
*/ */
@Query(value = "select * from screen join form on form.id = screen.form_id where screen.previous_id is null and form.id = :formId", nativeQuery = true) @Query(
value = "select * from screen join form on form.id = screen.form_id where screen.index = 1 and form.id = :formId",
nativeQuery = true
)
Optional<Screen> findFirstScreenOfForm(final @Param("formId") Long formId); Optional<Screen> findFirstScreenOfForm(final @Param("formId") Long formId);
/** /**
...@@ -40,7 +44,10 @@ public interface ScreenRepository extends JpaRepository<Screen, Long> { ...@@ -40,7 +44,10 @@ public interface ScreenRepository extends JpaRepository<Screen, Long> {
* @param sessionId L'identifiant de la session de l'utilisateur. * @param sessionId L'identifiant de la session de l'utilisateur.
* @return L'écran précédent s'il existe. * @return L'écran précédent s'il existe.
*/ */
@Query(value = "select * from screen where id = (select previous.screen_id from answer current join answer previous on current.previous_id = previous.id where current.screen_id = :currentScreenId and current.session_id = :sessionId)", nativeQuery = true) @Query(
value = "select * from screen where id = (select previous.screen_id from answer current join answer previous on current.previous_id = previous.id where current.screen_id = :currentScreenId and current.session_id = :sessionId)",
nativeQuery = true
)
Optional<Screen> findPreviousScreen(final @Param("currentScreenId") Long currentScreenId, final @Param("sessionId") String sessionId); Optional<Screen> findPreviousScreen(final @Param("currentScreenId") Long currentScreenId, final @Param("sessionId") String sessionId);
/** /**
...@@ -50,7 +57,10 @@ public interface ScreenRepository extends JpaRepository<Screen, Long> { ...@@ -50,7 +57,10 @@ public interface ScreenRepository extends JpaRepository<Screen, Long> {
* @param sessionId L'identifiant de la session de l'utilisateur. * @param sessionId L'identifiant de la session de l'utilisateur.
* @return L'écran suivant s'il existe. * @return L'écran suivant s'il existe.
*/ */
@Query(value = "select * from screen where id = (select next.screen_id from answer current join answer next on next.previous_id = current.id where current.screen_id = :currentScreenId and current.session_id = :sessionId)", nativeQuery = true) @Query(
value = "select * from screen where id = (select next.screen_id from answer current join answer next on next.previous_id = current.id where current.screen_id = :currentScreenId and current.session_id = :sessionId)",
nativeQuery = true
)
Optional<Screen> findNextScreen(final @Param("currentScreenId") Long currentScreenId, final @Param("sessionId") String sessionId); Optional<Screen> findNextScreen(final @Param("currentScreenId") Long currentScreenId, final @Param("sessionId") String sessionId);
/** /**
...@@ -62,6 +72,44 @@ public interface ScreenRepository extends JpaRepository<Screen, Long> { ...@@ -62,6 +72,44 @@ public interface ScreenRepository extends JpaRepository<Screen, Long> {
* @param screenId L'identifiant de l'écran. * @param screenId L'identifiant de l'écran.
* @return Le nombre d'écran potentiellement restant. * @return Le nombre d'écran potentiellement restant.
*/ */
@Query(value = "WITH RECURSIVE previous AS (SELECT id, previous_id FROM screen WHERE id = :screenId UNION SELECT s.id, s.previous_id FROM screen s INNER JOIN previous p ON p.previous_id = s.id) SELECT (select count(*) from screen where form_id = :formId) - count(pr.*) FROM previous pr", nativeQuery = true) @Query(
value = "SELECT COUNT(*) FROM SCREEN WHERE INDEX > (SELECT INDEX FROM SCREEN WHERE ID = :screenId AND form_id = :formId) AND form_id = :formId",
nativeQuery = true
)
int countScreenLeft(final @Param("formId") Long formId, final @Param("screenId") Long screenId); int countScreenLeft(final @Param("formId") Long formId, final @Param("screenId") Long screenId);
/**
* Retourne les écrans d'un formulaire selon les permissions d'un utilisateur
*
* @param idUser identifiant d'utilisateur
* @param idForm identifiant de formulaire
* @return
*/
@Query(
value = "select screen.* from form f join scope_form sf on sf.id_form = f.id join scope s on s.id = sf.id_scope join screen on f.id = screen.form_id join jhi_user u on u.id = s.id_user where u.id = :idUser and f.id = :idForm",
nativeQuery = true
)
List<Screen> findWithPermission(@Param("idUser") Long idUser, @Param("idForm") Long idForm);
/**
* Récupération de tous les écrans d'un formulaire.
*
* @param formId L'identifiant du formulaire.
* @return Les écrans.
*/
List<Screen> findAllByFormId(final Long formId);
Optional<Screen> findScreenByIndexAndFormId(final Integer index, final Long formId);
/**
* Diminue l'index des écrans d'un formulaire dont l'index est supérieur à celui passé en paramètre.
* @param formId un identifiant de formulaire
* @param index un index (position) d'écran
*/
@Query(
value = "UPDATE screen SET index = (index - 1) WHERE index > :index AND form_id = :formId",