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/
######################
# Visual Studio Code
######################
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.vscode/
*.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 {
@Column(name = "name", nullable = false, unique = true)
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
*/
......@@ -79,19 +86,16 @@ public class Screen implements Serializable {
@Column(name = "items", nullable = false)
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
@JsonIgnoreProperties(value = { "screens", "variables", "workspace" }, allowSetters = true)
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
public Long getId() {
return id;
......@@ -115,6 +119,15 @@ public class Screen implements Serializable {
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) {
this.name = name;
}
......@@ -203,51 +216,34 @@ public class Screen implements Serializable {
this.items = items;
}
public Screen getPrevious() {
return this.previous;
public Form getForm() {
return this.form;
}
public Screen previous(Screen screen) {
this.setPrevious(screen);
public Screen form(Form form) {
this.setForm(form);
return this;
}
public void setPrevious(Screen screen) {
this.previous = screen;
}
public Screen getNext() {
return this.next;
}
public Screen next(Screen screen) {
this.setNext(screen);
return this;
public void setForm(Form form) {
this.form = form;
}
public void setNext(Screen screen) {
if (this.next != null) {
this.next.setPrevious(null);
}
if (next != null) {
next.setPrevious(this);
}
this.next = screen;
public Integer getIndex() {
return index;
}
public Form getForm() {
return this.form;
public void setIndex(Integer index) {
this.index = index;
}
public Screen form(Form form) {
this.setForm(form);
return this;
public String getNameBo() {
return nameBo;
}
public void setForm(Form form) {
this.form = form;
public void setNameBo(String nameBo) {
this.nameBo = nameBo;
}
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here
@Override
......
......@@ -67,8 +67,6 @@ public class FilArianeController {
public String getUserHome() {
if (PermissionService.currentUserHasAuthority(AuthoritiesConstants.AUTHORITY_VIEW_WORKSPACE)) {
return Path.LIST_WORKSPACES;
} else if (PermissionService.currentUserHasAuthority(AuthoritiesConstants.AUTHORITY_VIEW_FORMS)) {
return Path.LIST_FORMS;
} else if (PermissionService.currentUserHasAuthority(AuthoritiesConstants.AUTHORITY_VIEW_FORM)) {
return Path.LIST_FORMS;
}
......
......@@ -5,10 +5,10 @@ package com.unantes.orientactive.filariane;
*/
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 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";
}
......@@ -335,4 +335,22 @@ public class NavigationService {
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;
import com.unantes.orientactive.service.dto.ScreenDTO;
import com.unantes.orientactive.service.dto.VariableDTO;
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.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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é.
*/
......@@ -48,8 +49,9 @@ public class ScreenNavigationService {
/**
* Constructure.
* @param screenService {@link #screenService}
* @param answerService {@link #answerService}
*
* @param screenService {@link #screenService}
* @param answerService {@link #answerService}
* @param variableService {@link #variableService}
*/
public ScreenNavigationService(ScreenService screenService, AnswerService answerService, VariableService variableService) {
......@@ -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.
* 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.
*
* @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
* @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 {
// 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();
}
// 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 {
/**
* 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 screen l'écran courant
* @param screen l'écran courant
* @return
*/
private ScreenDTO getNextScreenFromExpressions(final Expression expression, final ScreenDTO screen) {
......@@ -112,30 +116,33 @@ public class ScreenNavigationService {
/**
* Deux écrans par défaut possibles :
* <ul>
* <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#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>
* </ul>
*
* @param screen
* @return
*/
private ScreenDTO getDefaultNextScreen(final ScreenDTO screen) {
if (StringUtils.isBlank(screen.getDefaultNextScreenReference())) {
return getScreenById(screen.getNextId());
return getScreenByIndexAndFormId(screen.getNextIndex(), screen.getFormId());
}
return getScreenByRef(screen.getDefaultNextScreenReference());
}
/**
* Wrapper de la méthode {@link ScreenService#findOne(Long)}; Jette une exception si l'écran n'existe pas.
*
* @param nextId
* @return
*/
private ScreenDTO getScreenById(final Long nextId) {
return screenService.findOne(nextId).orElseThrow(() -> new UnableToFindNextScreenException("l'écran n'existe pas en base"));
private ScreenDTO getScreenByIndexAndFormId(final Integer index, final Long formId) {
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.
*
* @param screenRef
* @return
*/
......@@ -147,8 +154,9 @@ public class ScreenNavigationService {
/**
* 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 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) {
final Expression expression = initializeExpression(screen.getFormId(), sessionId);
......@@ -157,7 +165,8 @@ public class ScreenNavigationService {
/**
* 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
*/
protected void filterScreenItems(final ScreenDTO screen, final Expression expressionEngine) {
......@@ -179,7 +188,8 @@ public class ScreenNavigationService {
/**
* 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
* @return
*/
......@@ -196,6 +206,7 @@ public class ScreenNavigationService {
/**
* 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
* @return
*/
......
......@@ -2,11 +2,13 @@ package com.unantes.orientactive.repository;
import com.unantes.orientactive.domain.Screen;
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.repository.query.Param;
import org.springframework.stereotype.Repository;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Optional;
/**
......@@ -15,7 +17,6 @@ import java.util.Optional;
@SuppressWarnings("unused")
@Repository
public interface ScreenRepository extends JpaRepository<Screen, Long> {
/**
* Récupération d'un écran par sa référence.
*
......@@ -30,7 +31,10 @@ public interface ScreenRepository extends JpaRepository<Screen, Long> {
* @param formId L'identifiant du formulaire.
* @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);
/**
......@@ -40,7 +44,10 @@ public interface ScreenRepository extends JpaRepository<Screen, Long> {
* @param sessionId L'identifiant de la session de l'utilisateur.
* @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);
/**
......@@ -50,7 +57,10 @@ public interface ScreenRepository extends JpaRepository<Screen, Long> {
* @param sessionId L'identifiant de la session de l'utilisateur.
* @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);
/**
......@@ -62,6 +72,44 @@ public interface ScreenRepository extends JpaRepository<Screen, Long> {
* @param screenId L'identifiant de l'écran.
* @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);
/**
* 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",
nativeQuery = true
)
@Modifying(flushAutomatically = true, clearAutomatically = true)
void decreaseScreenIndex(@Param("formId") Long formId, @Param("index") Integer index);
}
......@@ -19,8 +19,6 @@ public final class AuthoritiesConstants {
public static final SimpleGrantedAuthority AUTHORITY_VIEW_WORKSPACE = new SimpleGrantedAuthority(VIEW_WORKSPACE);
public static final String EDIT_WORKSPACE = "EDIT_WORKSPACE";
public static final SimpleGrantedAuthority AUTHORITY_EDIT_WORKSPACE = new SimpleGrantedAuthority(EDIT_WORKSPACE);
public static final String VIEW_FORMS = "VIEW_FORMS";
public static final SimpleGrantedAuthority AUTHORITY_VIEW_FORMS = new SimpleGrantedAuthority(VIEW_FORMS);
public static final String VIEW_FORM = "VIEW_FORM";
public static final SimpleGrantedAuthority AUTHORITY_VIEW_FORM = new SimpleGrantedAuthority(VIEW_FORM);
public static final String EDIT_FORM = "EDIT_FORM";
......
......@@ -175,7 +175,7 @@ public class FormService extends PermissionService<FormDTO> {
formRepository.removePermission(user.getId(), element.getId());
}
@PreAuthorize("hasAuthority('VIEW_FORMS')")
@PreAuthorize("hasAuthority('VIEW_FORM')")
@Override
protected List<FormDTO> findWithPermission(User user, Long idParentElement) {
return formRepository
......@@ -185,7 +185,7 @@ public class FormService extends PermissionService<FormDTO> {
.collect(Collectors.toList());
}
@PreAuthorize("hasAuthority('VIEW_FORMS')")
@PreAuthorize("hasAuthority('VIEW_FORM')")
@Override
public List<FormDTO> findAllByParent(Long idParentElement) {
return formRepository
......@@ -195,7 +195,7 @@ public class FormService extends PermissionService<FormDTO> {
.collect(Collectors.toCollection(LinkedList::new));
}
@PreAuthorize("hasAuthority('VIEW_FORMS')")
@PreAuthorize("hasAuthority('VIEW_FORM')")
@Override
protected boolean hasWildcard(User user) {
return formRepository.hasWildcard(user.getId(), Role.CONTRIBUTEUR.getId());
......@@ -206,9 +206,13 @@ public class FormService extends PermissionService<FormDTO> {
return userService.findAllWithPermissionOnForm(Role.CONTRIBUTEUR.getId(), element.getId());
}
@PreAuthorize("hasAuthority('VIEW_FORMS')")
@Override
protected boolean existPermission(User user, FormDTO element) {
return formRepository.existPermission(user.getId(), element.getId());
return existPermission(user, element.getId());
}
@PreAuthorize("hasAuthority('VIEW_FORM')")
protected boolean existPermission(User user, Long formId) {
return formRepository.existPermission(user.getId(), formId);
}
}
package com.unantes.orientactive.service;
import com.unantes.orientactive.domain.Screen;
import com.unantes.orientactive.repository.ScreenRepository;
import com.unantes.orientactive.service.dto.ScreenDTO;
import com.unantes.orientactive.service.mapper.ScreenMapper;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import org.slf4j.Logger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.stereotype.Service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.annotation.Transactional;
import com.unantes.orientactive.domain.Screen;
import com.unantes.orientactive.domain.User;
import com.unantes.orientactive.repository.ScreenRepository;
import com.unantes.orientactive.service.dto.FormDTO;
import com.unantes.orientactive.service.dto.ScreenDTO;
import com.unantes.orientactive.service.dto.ScreenPanelDTO;
import com.unantes.orientactive.service.mapper.ScreenMapper;
import com.unantes.orientactive.service.mapper.ScreenPanelMapper;
import com.unantes.orientactive.service.exception.EntityNotFoundException;
/**
* Service Implementation for managing {@link Screen}.
*/
......@@ -31,9 +35,20 @@ public class ScreenService {
private final ScreenMapper screenMapper;
public ScreenService(ScreenRepository screenRepository, ScreenMapper screenMapper) {
private final ScreenPanelMapper screenPanelMapper;
private final FormService formService;
public ScreenService(
ScreenRepository screenRepository,
ScreenMapper screenMapper,
ScreenPanelMapper screenPanelMapper,
FormService formService
) {
this.screenRepository = screenRepository;
this.screenMapper = screenMapper;
this.screenPanelMapper = screenPanelMapper;
this.formService = formService;
}
/**
......@@ -81,21 +96,6 @@ public class ScreenService {
return screenRepository.findAll().stream().map(screenMapper::toDto).collect(Collectors.toCollection(LinkedList::new));
}
/**
* Get all the screens where Next is {@code null}.
*
* @return the list of entities.
*/
@Transactional(readOnly = true)
public List<ScreenDTO> findAllWhereNextIsNull() {
log.debug("Request to get all screens where Next is null");
return StreamSupport
.stream(screenRepository.findAll().spliterator(), false)
.filter(screen -> screen.getNext() == null)
.map(screenMapper::toDto)
.collect(Collectors.toCollection(LinkedList::new));
}
/**
* Get one screen by id.