branch develop updated (cda9e55 -> 40d728b)
This is an automated email from the git hooks/post-receive script. New change to branch develop in repository coselmar. See http://git.codelutin.com/coselmar.git from cda9e55 fix simple search <-> advanced search change in ui new 7440c25 refs-40 #7858 Revue coté service de la recherche avancée de projet/questions new 40d728b fixes #7858 add advanced search on project in ui The 2 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit 40d728b611ae15a4db2668e31884d3c7a2eab839 Author: Yannick Martel <martel@©odelutin.com> Date: Thu Dec 24 14:51:49 2015 +0100 fixes #7858 add advanced search on project in ui commit 7440c251e020ab8d97ad31fbf8699e397952d44c Author: Yannick Martel <martel@©odelutin.com> Date: Wed Dec 23 17:44:41 2015 +0100 refs-40 #7858 Revue coté service de la recherche avancée de projet/questions Summary of changes: .../coselmar/beans/DocumentSearchExample.java | 24 +++ .../ifremer/coselmar/beans/QuestionSearchBean.java | 59 -------- .../coselmar/beans/QuestionSearchExample.java | 110 ++++++++++++++ .../fr/ifremer/coselmar/beans/SearchExample.java | 20 ++- .../persistence/entity/QuestionTopiaDao.java | 83 ++++++++--- ...UserSearchBean.java => QuestionSearchBean.java} | 47 ++++-- .../coselmar/converter/BeanEntityConverter.java | 58 +++++++ .../services/CoselmarRestApplicationListener.java | 4 +- .../indexation/QuestionsIndexationService.java | 1 + .../indexation/TransverseIndexationService.java | 13 -- .../coselmar/services/v1/DocumentsWebService.java | 28 ++-- .../coselmar/services/v1/HealthService.java | 1 + .../coselmar/services/v1/QuestionsWebService.java | 69 ++++++--- .../coselmar/services/QuestionsWebServiceTest.java | 2 +- coselmar-ui/src/main/webapp/i18n/en.js | 5 + coselmar-ui/src/main/webapp/i18n/fr.js | 5 + .../src/main/webapp/js/coselmar-controllers.js | 46 ++++++ .../src/main/webapp/views/questions/questions.html | 15 +- .../src/main/webapp/views/questions/toolsPart.html | 166 +++++++++++++++++++++ 19 files changed, 599 insertions(+), 157 deletions(-) delete mode 100644 coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/QuestionSearchBean.java create mode 100644 coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/QuestionSearchExample.java copy coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/{UserSearchBean.java => QuestionSearchBean.java} (58%) create mode 100644 coselmar-ui/src/main/webapp/views/questions/toolsPart.html -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository coselmar. See http://git.codelutin.com/coselmar.git commit 7440c251e020ab8d97ad31fbf8699e397952d44c Author: Yannick Martel <martel@©odelutin.com> Date: Wed Dec 23 17:44:41 2015 +0100 refs-40 #7858 Revue coté service de la recherche avancée de projet/questions --- .../coselmar/beans/DocumentSearchExample.java | 24 +++++ .../ifremer/coselmar/beans/QuestionSearchBean.java | 59 ----------- .../coselmar/beans/QuestionSearchExample.java | 110 +++++++++++++++++++++ .../fr/ifremer/coselmar/beans/SearchExample.java | 20 +++- .../persistence/entity/QuestionTopiaDao.java | 77 +++++++++++---- .../ifremer/coselmar/beans/QuestionSearchBean.java | 105 ++++++++++++++++++++ .../coselmar/converter/BeanEntityConverter.java | 58 +++++++++++ .../services/CoselmarRestApplicationListener.java | 4 +- .../indexation/QuestionsIndexationService.java | 1 + .../indexation/TransverseIndexationService.java | 13 --- .../coselmar/services/v1/DocumentsWebService.java | 28 +++--- .../coselmar/services/v1/HealthService.java | 1 + .../coselmar/services/v1/QuestionsWebService.java | 67 ++++++++----- .../coselmar/services/QuestionsWebServiceTest.java | 2 +- 14 files changed, 436 insertions(+), 133 deletions(-) diff --git a/coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/DocumentSearchExample.java b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/DocumentSearchExample.java index d63ac3b..2b8c463 100644 --- a/coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/DocumentSearchExample.java +++ b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/DocumentSearchExample.java @@ -36,6 +36,8 @@ public class DocumentSearchExample extends SearchExample<Document> { DocumentSearchExample searchExample = new DocumentSearchExample(); searchExample.setPage(DEFAULT_PAGE); searchExample.setLimit(DEFAULT_PAGE_SIZE); + searchExample.setOrderClause(Document.PROPERTY_DEPOSIT_DATE); + searchExample.setOrderDesc(true); return searchExample; } @@ -49,6 +51,10 @@ public class DocumentSearchExample extends SearchExample<Document> { protected String ownerName; + protected String orderClause; + + protected boolean orderDesc; + public Date getPublicationAfterDate() { return publicationAfterDate; } @@ -88,4 +94,22 @@ public class DocumentSearchExample extends SearchExample<Document> { public void setOwnerName(String ownerName) { this.ownerName = ownerName; } + + @Override + public String getOrderClause() { + return orderClause; + } + + public void setOrderClause(String orderClause) { + this.orderClause = orderClause; + } + + @Override + public boolean isOrderDesc() { + return orderDesc; + } + + public void setOrderDesc(boolean orderDesc) { + this.orderDesc = orderDesc; + } } diff --git a/coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/QuestionSearchBean.java b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/QuestionSearchBean.java deleted file mode 100644 index 656fb3e..0000000 --- a/coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/QuestionSearchBean.java +++ /dev/null @@ -1,59 +0,0 @@ -package fr.ifremer.coselmar.beans; - -/* - * #%L - * Coselmar :: Persistence - * $Id:$ - * $HeadURL:$ - * %% - * Copyright (C) 2014 - 2015 Ifremer, Code Lutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -import fr.ifremer.coselmar.persistence.entity.Question; - -import java.io.Serializable; -import java.util.List; - -/** - * @author ymartel <martel@codelutin.com> - */ -public class QuestionSearchBean extends SearchExample<Question> { - - private static final long serialVersionUID = -3318003570685481073L; - - protected String status; - protected String privacy; - - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public String getPrivacy() { - return privacy; - } - - public void setPrivacy(String privacy) { - this.privacy = privacy; - } - -} diff --git a/coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/QuestionSearchExample.java b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/QuestionSearchExample.java new file mode 100644 index 0000000..3ac3c15 --- /dev/null +++ b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/QuestionSearchExample.java @@ -0,0 +1,110 @@ +package fr.ifremer.coselmar.beans; + +/* + * #%L + * Coselmar :: Persistence + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer, Code Lutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ifremer.coselmar.persistence.entity.Question; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * @author ymartel <martel@codelutin.com> + */ +public class QuestionSearchExample extends SearchExample<Question> { + + private static final long serialVersionUID = -3318003570685481073L; + + public static final QuestionSearchExample newDefaultSearchExample() { + QuestionSearchExample searchExample = new QuestionSearchExample(); + searchExample.setPage(DEFAULT_PAGE); + searchExample.setLimit(DEFAULT_PAGE_SIZE); + searchExample.setOrderClause(Question.PROPERTY_SUBMISSION_DATE); + searchExample.setOrderDesc(true); + return searchExample; + } + + protected Date submissionAfterDate; + + protected Date submissionBeforeDate; + + protected Date deadlineAfterDate; + + protected Date deadlineBeforeDate; + + protected String orderClause; + + protected boolean orderDesc; + + public Date getSubmissionAfterDate() { + return submissionAfterDate; + } + + public void setSubmissionAfterDate(Date submissionAfterDate) { + this.submissionAfterDate = submissionAfterDate; + } + + public Date getSubmissionBeforeDate() { + return submissionBeforeDate; + } + + public void setSubmissionBeforeDate(Date submissionBeforeDate) { + this.submissionBeforeDate = submissionBeforeDate; + } + + public Date getDeadlineAfterDate() { + return deadlineAfterDate; + } + + public void setDeadlineAfterDate(Date deadlineAfterDate) { + this.deadlineAfterDate = deadlineAfterDate; + } + + public Date getDeadlineBeforeDate() { + return deadlineBeforeDate; + } + + public void setDeadlineBeforeDate(Date deadlineBeforeDate) { + this.deadlineBeforeDate = deadlineBeforeDate; + } + + @Override + public String getOrderClause() { + return orderClause; + } + + public void setOrderClause(String orderClause) { + this.orderClause = orderClause; + } + + @Override + public boolean isOrderDesc() { + return orderDesc; + } + + public void setOrderDesc(boolean orderDesc) { + this.orderDesc = orderDesc; + } +} diff --git a/coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/SearchExample.java b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/SearchExample.java index 029767f..376d2e6 100644 --- a/coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/SearchExample.java +++ b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/SearchExample.java @@ -22,7 +22,9 @@ package fr.ifremer.coselmar.beans; * #L% */ +import fr.ifremer.coselmar.persistence.entity.Question; import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.util.pagination.PaginationParameter; import java.io.Serializable; import java.util.List; @@ -30,13 +32,26 @@ import java.util.List; /** * @author ymartel (martel@codelutin.com) */ -public class SearchExample<E extends TopiaEntity> implements Serializable { +public abstract class SearchExample<E extends TopiaEntity> implements Serializable { private static final long serialVersionUID = 4024861043438299258L; public static final int DEFAULT_PAGE_SIZE = -1; public static final int DEFAULT_PAGE = 0; + public PaginationParameter getPaginationParameter() { + + PaginationParameter paginationParameter = null; + if (this.limit != null) { + int wantedPage = this.page != null ? this.page.intValue() : 0; + paginationParameter = PaginationParameter.of(wantedPage, this.limit.intValue(), getOrderClause(), isOrderDesc()); + } else { + paginationParameter = PaginationParameter.of(DEFAULT_PAGE, DEFAULT_PAGE_SIZE, getOrderClause(), isOrderDesc()); + } + + return paginationParameter; + } + protected E example; protected List<String> fullTextSearch; @@ -84,4 +99,7 @@ public class SearchExample<E extends TopiaEntity> implements Serializable { this.page = page; } } + + public abstract String getOrderClause(); + public abstract boolean isOrderDesc(); } diff --git a/coselmar-persistence/src/main/java/fr/ifremer/coselmar/persistence/entity/QuestionTopiaDao.java b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/persistence/entity/QuestionTopiaDao.java index 9983f18..b23f1e3 100644 --- a/coselmar-persistence/src/main/java/fr/ifremer/coselmar/persistence/entity/QuestionTopiaDao.java +++ b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/persistence/entity/QuestionTopiaDao.java @@ -28,7 +28,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import fr.ifremer.coselmar.beans.QuestionSearchBean; +import fr.ifremer.coselmar.beans.QuestionSearchExample; import fr.ifremer.coselmar.persistence.DaoUtils; import org.apache.commons.lang3.StringUtils; import org.nuiton.topia.persistence.TopiaQueryBuilderAddCriteriaOrRunQueryStep; @@ -36,7 +36,7 @@ import org.nuiton.util.pagination.PaginationParameter; public class QuestionTopiaDao extends AbstractQuestionTopiaDao<Question> { - public List<Question> findForExpert(CoselmarUser expert, QuestionSearchBean searchBean, PaginationParameter page) { + public List<Question> findForExpert(CoselmarUser expert, QuestionSearchExample questionSearchExample, PaginationParameter page) { StringBuilder hqlBuilder = new StringBuilder("SELECT Q FROM " + Question.class.getName() + " Q " + " INNER JOIN Q." + Question.PROPERTY_PARTICIPANTS + " CUG "); @@ -58,7 +58,7 @@ public class QuestionTopiaDao extends AbstractQuestionTopiaDao<Question> { hqlBuilder.append(clientCondition + ") )"); - String finerHql = refineSearch(searchBean, "Q", args); + String finerHql = refineSearch(questionSearchExample, "Q", args); hqlBuilder.append(" AND (" + finerHql + ")" ); @@ -135,7 +135,7 @@ public class QuestionTopiaDao extends AbstractQuestionTopiaDao<Question> { return questions; } - public List<Question> findForClient(CoselmarUser client, QuestionSearchBean searchBean, PaginationParameter page) { + public List<Question> findForClient(CoselmarUser client, QuestionSearchExample searchExample, PaginationParameter page) { StringBuilder hqlBuilder = new StringBuilder("SELECT Q FROM " + Question.class.getName() + " Q "); @@ -145,8 +145,8 @@ public class QuestionTopiaDao extends AbstractQuestionTopiaDao<Question> { hqlBuilder.append(" WHERE 1=1 AND (" + clientCondition + " ) "); - if (searchBean != null) { - String finerHql = refineSearch(searchBean, "Q", args); + if (searchExample != null) { + String finerHql = refineSearch(searchExample, "Q", args); hqlBuilder.append(" AND (" + finerHql + ")" ); } @@ -175,14 +175,14 @@ public class QuestionTopiaDao extends AbstractQuestionTopiaDao<Question> { return questions; } - public List<Question> findWithSearchBean(QuestionSearchBean searchBean, PaginationParameter page) { + public List<Question> findWithSearchExample(QuestionSearchExample searchExample, PaginationParameter page) { StringBuilder hqlBuilder = new StringBuilder("SELECT Q FROM " + Question.class.getName() + " Q "); Map<String, Object> args = new HashMap<>(); - if (searchBean != null) { - String finerHql = refineSearch(searchBean, "Q", args); + if (searchExample != null) { + String finerHql = refineSearch(searchExample, "Q", args); hqlBuilder.append(" WHERE (" + finerHql + ")" ); } @@ -219,25 +219,62 @@ public class QuestionTopiaDao extends AbstractQuestionTopiaDao<Question> { return values; } - public String refineSearch(QuestionSearchBean searchBean, String alias, Map args) { + public String refineSearch(QuestionSearchExample searchExample, String alias, Map args) { StringBuilder finerHqlBuilder = new StringBuilder(" 1=1 "); - String privacy = searchBean.getPrivacy(); + Question example = searchExample.getExample(); - if (StringUtils.isNotBlank(privacy)) { - String privacyHql = DaoUtils.andAttributeEquals(alias, Question.PROPERTY_PRIVACY, args, Privacy.valueOf(privacy.toUpperCase())); - finerHqlBuilder.append(privacyHql); - } + if (example != null) { + + Privacy privacy = example.getPrivacy(); + if (privacy != null) { + String privacyHql = DaoUtils.andAttributeEquals(alias, Question.PROPERTY_PRIVACY, args, privacy); + finerHqlBuilder.append(privacyHql); + } + + Status status = example.getStatus(); + if (status != null) { + String statusHql = DaoUtils.andAttributeEquals(alias, Question.PROPERTY_STATUS, args, status); + finerHqlBuilder.append(statusHql); + } + + if (StringUtils.isNotBlank(example.getTitle())) { + String titleHql = DaoUtils.andAttributeEquals(alias, Question.PROPERTY_TITLE, args, example.getTitle()); + finerHqlBuilder.append(titleHql); + } + + if (example.getTheme() != null && !example.getTheme().isEmpty()) { + for (String keyword : example.getTheme()) { + String themesCondition = DaoUtils.andAttributeContains(alias, Question.PROPERTY_THEME, args, keyword); + finerHqlBuilder.append(themesCondition); + } + } + + // Manage date range + if (searchExample.getSubmissionBeforeDate() != null) { + String submissionDateConditionBefore = DaoUtils.andAttributeLesserOrEquals(alias, Question.PROPERTY_SUBMISSION_DATE, args, searchExample.getSubmissionBeforeDate()); + finerHqlBuilder.append(submissionDateConditionBefore); + } + + if (searchExample.getSubmissionAfterDate() != null) { + String submissionDateConditionAfter = DaoUtils.andAttributeGreaterOrEquals(alias, Question.PROPERTY_SUBMISSION_DATE, args, searchExample.getSubmissionAfterDate()); + finerHqlBuilder.append(submissionDateConditionAfter); + } + + if (searchExample.getDeadlineBeforeDate() != null) { + String deadlineConditionBefore = DaoUtils.andAttributeLesserOrEquals(alias, Question.PROPERTY_DEADLINE, args, searchExample.getDeadlineBeforeDate()); + finerHqlBuilder.append(deadlineConditionBefore); + } - String status = searchBean.getStatus(); + if (searchExample.getDeadlineAfterDate() != null) { + String deadlineDateConditionAfter = DaoUtils.andAttributeGreaterOrEquals(alias, Question.PROPERTY_DEADLINE, args, searchExample.getDeadlineAfterDate()); + finerHqlBuilder.append(deadlineDateConditionAfter); + } - if (StringUtils.isNotBlank(status)) { - String statusHql = DaoUtils.andAttributeEquals(alias, Question.PROPERTY_STATUS, args, Status.valueOf(status.toUpperCase())); - finerHqlBuilder.append(statusHql); } - List<String> keywords = searchBean.getFullTextSearch(); + List<String> keywords = searchExample.getFullTextSearch(); if (keywords != null && !keywords.isEmpty()) { // should be like : """ ( (1=1) // AND ( 1=0 OR title like keyword1 OR summary like keyword1 OR theme contains keyword1 ) diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/QuestionSearchBean.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/QuestionSearchBean.java new file mode 100644 index 0000000..3ef65bd --- /dev/null +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/QuestionSearchBean.java @@ -0,0 +1,105 @@ +package fr.ifremer.coselmar.beans; + +/* + * #%L + * Coselmar :: Rest Services + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Ifremer, Code Lutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import java.util.Collection; +import java.util.Date; +import java.util.List; + +/** + * @author ymartel <martel@codelutin.com> + */ +public class QuestionSearchBean extends QuestionBean { + + private static final long serialVersionUID = -2665085000774964576L; + + protected Integer limit; + protected Integer page; + protected List<String> fullTextSearch; + + protected Date submissionAfterDate; + + protected Date submissionBeforeDate; + + protected Date deadlineAfterDate; + + protected Date deadlineBeforeDate; + + public Integer getLimit() { + return limit; + } + + public void setLimit(Integer limit) { + this.limit = limit; + } + + public Integer getPage() { + return page; + } + + public void setPage(Integer page) { + this.page = page; + } + + public List<String> getFullTextSearch() { + return fullTextSearch; + } + + public void setFullTextSearch(List<String> fullTextSearch) { + this.fullTextSearch = fullTextSearch; + } + + public Date getSubmissionAfterDate() { + return submissionAfterDate; + } + + public void setSubmissionAfterDate(Date submissionAfterDate) { + this.submissionAfterDate = submissionAfterDate; + } + + public Date getSubmissionBeforeDate() { + return submissionBeforeDate; + } + + public void setSubmissionBeforeDate(Date submissionBeforeDate) { + this.submissionBeforeDate = submissionBeforeDate; + } + + public Date getDeadlineAfterDate() { + return deadlineAfterDate; + } + + public void setDeadlineAfterDate(Date deadlineAfterDate) { + this.deadlineAfterDate = deadlineAfterDate; + } + + public Date getDeadlineBeforeDate() { + return deadlineBeforeDate; + } + + public void setDeadlineBeforeDate(Date deadlineBeforeDate) { + this.deadlineBeforeDate = deadlineBeforeDate; + } +} diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/converter/BeanEntityConverter.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/converter/BeanEntityConverter.java index 25914fe..e7ca0b2 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/converter/BeanEntityConverter.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/converter/BeanEntityConverter.java @@ -31,6 +31,7 @@ import java.util.LinkedList; import java.util.Set; import com.google.common.collect.Sets; +import com.google.common.primitives.Booleans; import fr.ifremer.coselmar.beans.DocumentBean; import fr.ifremer.coselmar.beans.QuestionBean; import fr.ifremer.coselmar.beans.UserBean; @@ -42,6 +43,9 @@ import fr.ifremer.coselmar.persistence.entity.Document; import fr.ifremer.coselmar.persistence.entity.DocumentImpl; import fr.ifremer.coselmar.persistence.entity.Privacy; import fr.ifremer.coselmar.persistence.entity.Question; +import fr.ifremer.coselmar.persistence.entity.QuestionImpl; +import fr.ifremer.coselmar.persistence.entity.Status; +import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.nuiton.topia.persistence.TopiaIdFactory; @@ -322,5 +326,59 @@ public class BeanEntityConverter { return document; } + /** + * Convert simple fields from {@link QuestionBean} into a {@link Question}. + * So, this does not convert : + * <ul> + * <li>Question#experts</li> + * <li>Question#contributors</li> + * <li>Question#clients</li> + * <li>Question#documents</li> + * </ul> + * If questionBean is null, simply return null Question. + */ + public static Question fromBean(QuestionBean questionBean) { + Question question = new QuestionImpl(); + + question.setTitle(questionBean.getTitle()); + question.setSummary(questionBean.getSummary()); + question.setType(questionBean.getType()); + + String privacy = questionBean.getPrivacy(); + if (StringUtils.isNotBlank(privacy)) { + question.setPrivacy(Privacy.valueOf(privacy.toUpperCase())); + } + + String status = questionBean.getStatus(); + if (StringUtils.isNotBlank(status)) { + question.setStatus(Status.valueOf(status.toUpperCase())); + } + + Collection<String> theme = questionBean.getThemes(); + if (theme != null && !theme.isEmpty()) { + question.setTheme(new HashSet(theme)); + } + + Date submissionDate = questionBean.getSubmissionDate(); + if (submissionDate != null){ + question.setSubmissionDate(new Date(submissionDate.getTime())); + } + + Date deadline = questionBean.getDeadline(); + if (deadline != null){ + question.setDeadline(new Date(deadline.getTime())); + } + + Date closingDate = questionBean.getClosingDate(); + if (closingDate != null){ + question.setClosingDate(new Date(closingDate.getTime())); + question.setConclusion(questionBean.getConclusion()); + } + + question.setUnavailable(BooleanUtils.toBoolean(questionBean.getIsRestricted())); + + return question; + } + } diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/CoselmarRestApplicationListener.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/CoselmarRestApplicationListener.java index 58b4b23..d0df76f 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/CoselmarRestApplicationListener.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/CoselmarRestApplicationListener.java @@ -32,6 +32,7 @@ import fr.ifremer.coselmar.beans.DocumentBean; import fr.ifremer.coselmar.beans.DocumentSearchBean; import fr.ifremer.coselmar.beans.QuestionBean; import fr.ifremer.coselmar.beans.QuestionSearchBean; +import fr.ifremer.coselmar.beans.QuestionSearchExample; import fr.ifremer.coselmar.beans.UserBean; import fr.ifremer.coselmar.beans.UserSearchBean; import fr.ifremer.coselmar.converter.DateConverter; @@ -54,7 +55,8 @@ public class CoselmarRestApplicationListener implements WebMotionServerListener QuestionBean.class, UserSearchBean.class, QuestionSearchBean.class, - DocumentSearchBean.class + DocumentSearchBean.class, + QuestionSearchExample.class ); @Override diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/indexation/QuestionsIndexationService.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/indexation/QuestionsIndexationService.java index 65756af..b59fb41 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/indexation/QuestionsIndexationService.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/indexation/QuestionsIndexationService.java @@ -26,6 +26,7 @@ package fr.ifremer.coselmar.services.indexation; import fr.ifremer.coselmar.beans.QuestionBean; import fr.ifremer.coselmar.beans.QuestionSearchBean; +import fr.ifremer.coselmar.beans.QuestionSearchExample; import fr.ifremer.coselmar.services.CoselmarSimpleServiceSupport; import org.apache.commons.lang3.StringUtils; import org.apache.lucene.document.Document; diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/indexation/TransverseIndexationService.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/indexation/TransverseIndexationService.java index ab15112..7510e9a 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/indexation/TransverseIndexationService.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/indexation/TransverseIndexationService.java @@ -25,13 +25,7 @@ package fr.ifremer.coselmar.services.indexation; */ import fr.ifremer.coselmar.beans.QuestionBean; -import fr.ifremer.coselmar.beans.QuestionSearchBean; import fr.ifremer.coselmar.services.CoselmarSimpleServiceSupport; -import org.apache.commons.lang3.StringUtils; -import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; -import org.apache.lucene.document.StringField; -import org.apache.lucene.document.TextField; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.Term; import org.apache.lucene.misc.HighFreqTerms; @@ -40,18 +34,11 @@ import org.apache.lucene.misc.TermStats; import org.apache.lucene.queryparser.classic.ParseException; import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanQuery; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TermQuery; -import org.apache.lucene.search.TopDocs; -import org.apache.lucene.search.WildcardQuery; import java.io.IOException; -import java.util.ArrayList; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; -import java.util.Set; /** * This Services provides operations about indexed Objects. diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/DocumentsWebService.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/DocumentsWebService.java index 8848067..91f56cf 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/DocumentsWebService.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/DocumentsWebService.java @@ -24,18 +24,6 @@ package fr.ifremer.coselmar.services.v1; * #L% */ -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - import com.google.common.base.Function; import com.google.common.base.Preconditions; import com.google.common.collect.Collections2; @@ -44,13 +32,10 @@ import fr.ifremer.coselmar.beans.DocumentBean; import fr.ifremer.coselmar.beans.DocumentSearchBean; import fr.ifremer.coselmar.beans.DocumentSearchExample; import fr.ifremer.coselmar.beans.QuestionBean; -import fr.ifremer.coselmar.beans.QuestionSearchBean; import fr.ifremer.coselmar.beans.UserBean; -import fr.ifremer.coselmar.beans.UserSearchBean; import fr.ifremer.coselmar.beans.UserWebToken; import fr.ifremer.coselmar.converter.BeanEntityConverter; import fr.ifremer.coselmar.exceptions.CoselmarTechnicalException; -import fr.ifremer.coselmar.persistence.SearchRequestBean; import fr.ifremer.coselmar.persistence.entity.CoselmarUser; import fr.ifremer.coselmar.persistence.entity.CoselmarUserGroup; import fr.ifremer.coselmar.persistence.entity.CoselmarUserRole; @@ -64,7 +49,6 @@ import fr.ifremer.coselmar.services.errors.UnauthorizedException; import fr.ifremer.coselmar.services.indexation.DocumentsIndexationService; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.logging.Log; import org.apache.lucene.queryparser.classic.ParseException; @@ -73,6 +57,18 @@ import org.debux.webmotion.server.render.Render; import org.nuiton.topia.persistence.TopiaNoResultException; import org.nuiton.util.DateUtil; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + import static org.apache.commons.logging.LogFactory.getLog; /** diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/HealthService.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/HealthService.java index 8415042..5b68539 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/HealthService.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/HealthService.java @@ -2,6 +2,7 @@ package fr.ifremer.coselmar.services.v1; import fr.ifremer.coselmar.beans.HealthBean; import fr.ifremer.coselmar.beans.QuestionSearchBean; +import fr.ifremer.coselmar.beans.QuestionSearchExample; import fr.ifremer.coselmar.persistence.entity.Privacy; import fr.ifremer.coselmar.services.CoselmarWebServiceSupport; import fr.ifremer.coselmar.services.indexation.QuestionsIndexationService; diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java index 457cac9..0ce8299 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java @@ -25,9 +25,6 @@ package fr.ifremer.coselmar.services.v1; */ import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; -import java.io.Writer; import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -43,6 +40,7 @@ import fr.ifremer.coselmar.beans.DocumentBean; import fr.ifremer.coselmar.beans.QuestionBean; import fr.ifremer.coselmar.beans.QuestionExportModel; import fr.ifremer.coselmar.beans.QuestionSearchBean; +import fr.ifremer.coselmar.beans.QuestionSearchExample; import fr.ifremer.coselmar.beans.UserBean; import fr.ifremer.coselmar.beans.UserWebToken; import fr.ifremer.coselmar.converter.BeanEntityConverter; @@ -59,7 +57,6 @@ import fr.ifremer.coselmar.services.errors.InvalidCredentialException; import fr.ifremer.coselmar.services.errors.UnauthorizedException; import fr.ifremer.coselmar.services.indexation.QuestionsIndexationService; import org.apache.commons.io.IOUtils; -import org.apache.commons.io.output.WriterOutputStream; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -68,10 +65,9 @@ import org.debux.webmotion.server.render.Render; import org.nuiton.csv.Export; import org.nuiton.topia.persistence.TopiaIdFactory; import org.nuiton.topia.persistence.TopiaNoResultException; +import org.nuiton.util.DateUtil; import org.nuiton.util.pagination.PaginationParameter; -import javax.activation.MimeType; - /** * @author ymartel <martel@codelutin.com> */ @@ -262,15 +258,15 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { public List<QuestionBean> getPublicQuestions() throws InvalidCredentialException, UnauthorizedException { // No authentication needed, just filter to get last 5 public questions - QuestionSearchBean searchOption = new QuestionSearchBean(); - searchOption.setPrivacy(Privacy.PUBLIC.name()); - searchOption.setStatus(Status.OPEN.name()); + QuestionSearchExample searchOption = QuestionSearchExample.newDefaultSearchExample(); + searchOption.getExample().setPrivacy(Privacy.PUBLIC); + searchOption.getExample().setStatus(Status.OPEN); searchOption.setLimit(5); searchOption.setPage(1); PaginationParameter paginationParameter = PaginationParameter.of(0, 5, Question.PROPERTY_SUBMISSION_DATE, true); - List<Question> questionList = getQuestionDao().findWithSearchBean(searchOption, paginationParameter); + List<Question> questionList = getQuestionDao().findWithSearchExample(searchOption, paginationParameter); List<QuestionBean> result = new ArrayList<>(questionList.size()); @@ -1028,17 +1024,44 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { List<Question> questionList; String currentUserRole = currentUser.getRole().name(); - Integer limit = searchBean.getLimit(); - PaginationParameter paginationParameter = null; - if (limit != null) { - Integer page = searchBean.getPage(); - int wantedPage = page != null ? page.intValue() : 0; - paginationParameter = PaginationParameter.of(wantedPage, limit.intValue(), Question.PROPERTY_SUBMISSION_DATE, true); - } else { - paginationParameter = PaginationParameter.of(0, Integer.MAX_VALUE, Question.PROPERTY_SUBMISSION_DATE, true); + + QuestionSearchExample searchExample = QuestionSearchExample.newDefaultSearchExample(); + if (searchBean != null) { + if (searchBean.getPage() != null) { + searchExample.setPage(searchBean.getPage()); + } + if (searchBean.getLimit() != null) { + searchExample.setLimit(searchBean.getLimit()); + } + searchExample.setFullTextSearch(searchBean.getFullTextSearch()); + + Question example = BeanEntityConverter.fromBean(searchBean); + searchExample.setExample(example); + + if (searchBean.getSubmissionAfterDate() != null) { + Date submissionAfterDate = DateUtil.getEndOfDay(DateUtil.getYesterday(searchBean.getSubmissionAfterDate())); + searchExample.setSubmissionAfterDate(submissionAfterDate); + } + + if (searchBean.getSubmissionBeforeDate() != null) { + Date submissionBeforeDate = DateUtil.getEndOfDay((searchBean.getSubmissionBeforeDate())); + searchExample.setSubmissionBeforeDate(submissionBeforeDate); + } + + if (searchBean.getDeadlineAfterDate() != null) { + Date deadlineAfterDate = DateUtil.getEndOfDay(DateUtil.getYesterday(searchBean.getDeadlineAfterDate())); + searchExample.setDeadlineAfterDate(deadlineAfterDate); + } + + if (searchBean.getDeadlineBeforeDate() != null) { + Date deadlineBeforeDate = DateUtil.getEndOfDay((searchBean.getDeadlineBeforeDate())); + searchExample.setDeadlineBeforeDate(deadlineBeforeDate); + } } + // Supervisor or Admin : access to all questions, no restriction + PaginationParameter paginationParameter = searchExample.getPaginationParameter(); if (StringUtils.equalsIgnoreCase(CoselmarUserRole.ADMIN.name(), currentUserRole) || StringUtils.equalsIgnoreCase(CoselmarUserRole.SUPERVISOR.name(), currentUserRole)) { @@ -1047,7 +1070,7 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { // classical search with DAO } else { - questionList = getQuestionDao().findWithSearchBean(searchBean, paginationParameter); + questionList = getQuestionDao().findWithSearchExample(searchExample, paginationParameter); } @@ -1065,7 +1088,7 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { // classical search with DAO } else { - questionList = getQuestionDao().findWithSearchBean(searchBean, paginationParameter); + questionList = getQuestionDao().findWithSearchExample(searchExample, paginationParameter); } } @@ -1075,7 +1098,7 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { questionList = getQuestionDao().findForExpert(currentUser, fromIndexQuestionIds, paginationParameter); } else { - questionList = getQuestionDao().findForExpert(currentUser, searchBean, paginationParameter); + questionList = getQuestionDao().findForExpert(currentUser, searchExample, paginationParameter); } // Client : access to question he is client @@ -1084,7 +1107,7 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { questionList = getQuestionDao().findForClient(currentUser, fromIndexQuestionIds, paginationParameter); } else { - questionList = getQuestionDao().findForClient(currentUser, searchBean, paginationParameter); + questionList = getQuestionDao().findForClient(currentUser, searchExample, paginationParameter); } } else { diff --git a/coselmar-rest/src/test/java/fr/ifremer/coselmar/services/QuestionsWebServiceTest.java b/coselmar-rest/src/test/java/fr/ifremer/coselmar/services/QuestionsWebServiceTest.java index 1d8903f..fd56396 100644 --- a/coselmar-rest/src/test/java/fr/ifremer/coselmar/services/QuestionsWebServiceTest.java +++ b/coselmar-rest/src/test/java/fr/ifremer/coselmar/services/QuestionsWebServiceTest.java @@ -139,7 +139,7 @@ public class QuestionsWebServiceTest extends AbstractCoselmarWebServiceTest { // Second search : as supervisor, searchBean only with public privacy : retrieve two documents (one and two) searchRequest = createRequest("/v1/questions") - .addParameter("searchOption", "{privacy : 'public'}") + .addParameter("searchOption", "{privacy : 'PUBLIC'}") .Get() .addHeader("Authorization", "Bearer " + supervisorToken); -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository coselmar. See http://git.codelutin.com/coselmar.git commit 40d728b611ae15a4db2668e31884d3c7a2eab839 Author: Yannick Martel <martel@©odelutin.com> Date: Thu Dec 24 14:51:49 2015 +0100 fixes #7858 add advanced search on project in ui --- .../persistence/entity/QuestionTopiaDao.java | 8 +- .../coselmar/services/v1/QuestionsWebService.java | 2 +- coselmar-ui/src/main/webapp/i18n/en.js | 5 + coselmar-ui/src/main/webapp/i18n/fr.js | 5 + .../src/main/webapp/js/coselmar-controllers.js | 46 ++++++ .../src/main/webapp/views/questions/questions.html | 15 +- .../src/main/webapp/views/questions/toolsPart.html | 166 +++++++++++++++++++++ 7 files changed, 231 insertions(+), 16 deletions(-) diff --git a/coselmar-persistence/src/main/java/fr/ifremer/coselmar/persistence/entity/QuestionTopiaDao.java b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/persistence/entity/QuestionTopiaDao.java index b23f1e3..68f1417 100644 --- a/coselmar-persistence/src/main/java/fr/ifremer/coselmar/persistence/entity/QuestionTopiaDao.java +++ b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/persistence/entity/QuestionTopiaDao.java @@ -239,8 +239,14 @@ public class QuestionTopiaDao extends AbstractQuestionTopiaDao<Question> { finerHqlBuilder.append(statusHql); } + String type = example.getType(); + if (StringUtils.isNotBlank(type)) { + String statusHql = DaoUtils.andAttributeEquals(alias, Question.PROPERTY_TYPE, args, type); + finerHqlBuilder.append(statusHql); + } + if (StringUtils.isNotBlank(example.getTitle())) { - String titleHql = DaoUtils.andAttributeEquals(alias, Question.PROPERTY_TITLE, args, example.getTitle()); + String titleHql = DaoUtils.andAttributeLike(alias, Question.PROPERTY_TITLE, args, example.getTitle()); finerHqlBuilder.append(titleHql); } diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java index 0ce8299..d264076 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java @@ -1005,7 +1005,7 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { //Try to retrieve corresponding questionIds from the index if searchBean given List<String> fromIndexQuestionIds = null; - if (searchBean != null) { + if (searchBean != null && searchBean.getFullTextSearch() != null && !searchBean.getFullTextSearch().isEmpty()) { try { List<String> questionIds = questionsIndexationService.searchQuestion(searchBean); fromIndexQuestionIds = getQuestionsFullId(questionIds); diff --git a/coselmar-ui/src/main/webapp/i18n/en.js b/coselmar-ui/src/main/webapp/i18n/en.js index 1c8811a..cde94dd 100644 --- a/coselmar-ui/src/main/webapp/i18n/en.js +++ b/coselmar-ui/src/main/webapp/i18n/en.js @@ -159,6 +159,11 @@ var translateEN = { "question.metadata.childrenPhrase" : "Has produced or inspired", "question.metadata.participants" : "Participants", +"question.metadata.submitBefore" : "Submit before", +"question.metadata.submitAfter" : "Submit after", +"question.metadata.deadlineBefore" : "Deadline before", +"question.metadata.deadlineAfter" : "Deadline after", + "question.message.requiredTitle" : "Title is required, minimum 10 characters.", "question.message.requiredType" : "Type is required.", "question.message.requiredSummary" : "A summary is required.", diff --git a/coselmar-ui/src/main/webapp/i18n/fr.js b/coselmar-ui/src/main/webapp/i18n/fr.js index 412f946..8a344c6 100644 --- a/coselmar-ui/src/main/webapp/i18n/fr.js +++ b/coselmar-ui/src/main/webapp/i18n/fr.js @@ -159,6 +159,11 @@ var translateFR = { "question.metadata.childrenPhrase" : "A provoqué ou inspiré", "question.metadata.participants" : "Participants", +"question.metadata.submitBefore" : "Soumis avant le", +"question.metadata.submitAfter" : "Soumis après le", +"question.metadata.deadlineBefore" : "Date limite avant le", +"question.metadata.deadlineAfter" : "Date limite après le", + "question.message.requiredTitle" : "Le titre est requis, avec au minimum 10 caractères.", "question.message.requiredType" : "Le type est requis..", "question.message.requiredSummary" : "Un résumé est requis.", diff --git a/coselmar-ui/src/main/webapp/js/coselmar-controllers.js b/coselmar-ui/src/main/webapp/js/coselmar-controllers.js index 39c6537..1255517 100644 --- a/coselmar-ui/src/main/webapp/js/coselmar-controllers.js +++ b/coselmar-ui/src/main/webapp/js/coselmar-controllers.js @@ -912,6 +912,13 @@ coselmarControllers.controller("QuestionsCtrl", ['$scope', '$route', '$routePara $scope.searchOptions = { 'privacy' : '', 'status' : '', 'fullTextSearch' : []}; + var advancedSearch = $routeParams.advancedSearch; + if (advancedSearch) { + $scope.advanced = advancedSearch; + } else { + $scope.advanced = false; + } + questionsService.getQuestions($scope.searchOptions, function(questions) { // success : just get the questions $scope.questions = questions; @@ -925,6 +932,45 @@ coselmarControllers.controller("QuestionsCtrl", ['$scope', '$route', '$routePara }; + $scope.searchMode = function(type) { + if (type == 'advanced') { + $location.search('advancedSearch'); + $scope.advanced = true; + } else { + $location.search(""); + $scope.advanced = false; + } + }; + + $scope.advancedSearchQuestions = function() { + + //Convert Dates to timestamp + if (angular.isDate($scope.searchOptions.submissionAfterDate)) { + $scope.searchOptions.submissionAfterDate = $scope.searchOptions.submissionAfterDate.getTime(); + } + + if (angular.isDate($scope.searchOptions.submissionBeforeDate)) { + $scope.searchOptions.submissionBeforeDate = $scope.searchOptions.submissionBeforeDate.getTime(); + } + + if (angular.isDate($scope.searchOptions.deadlineAfterDate)) { + $scope.searchOptions.deadlineAfterDate = $scope.searchOptions.deadlineAfterDate.getTime(); + } + + if (angular.isDate($scope.searchOptions.deadlineBeforeDate)) { + $scope.searchOptions.deadlineBeforeDate = $scope.searchOptions.deadlineBeforeDate.getTime(); + } + + questionsService.getQuestions($scope.searchOptions, function(questions){ + $scope.questions = questions; + }, errorService.defaultFailOnCall); + + }; + + $scope.openDatePicker = function(datePickerParam) { + datePickerParam = true; + } + $scope.deleteQuestion = function(questionId) { questionsService.deleteQuestion(questionId, function(questions) { diff --git a/coselmar-ui/src/main/webapp/views/questions/questions.html b/coselmar-ui/src/main/webapp/views/questions/questions.html index 9d0da29..15373f3 100644 --- a/coselmar-ui/src/main/webapp/views/questions/questions.html +++ b/coselmar-ui/src/main/webapp/views/questions/questions.html @@ -31,20 +31,7 @@ </div> <div> - <div> - <div class="form-group" ng-if="context.currentUser.role == 'SUPERVISOR'"> - <a href="#/questions/new" class="form-inline navbar-left btn btn-primary">{{ 'question.button.add' | translate }}</a> - </div> - <form class="form-inline pull-right search-zone" role="questionOptions" ng-submit="searchQuestions()"> - <div class="form-group"> - <span class="fa fa-info-circle" tooltip-placement="bottom" tooltip-html-unsafe="{{ 'common.message.info.searchKeywords' | translate }}"></span> - <input type="search" class="form-control" placeholder="keyword1,keyword2,..." ng-model="searchOptions.fullTextSearch" ng-list /> - </div> - <div class="form-group"> - <button type="submit" class="btn btn-primary glyphicon glyphicon-search"></button> - </div> - </form> - </div> + <div ng-include="src='views/questions/toolsPart.html'"></div> <div class="clear table-responsive paddingLeft10"> <table class="table table-bordered"> <thead> diff --git a/coselmar-ui/src/main/webapp/views/questions/toolsPart.html b/coselmar-ui/src/main/webapp/views/questions/toolsPart.html new file mode 100644 index 0000000..55881be --- /dev/null +++ b/coselmar-ui/src/main/webapp/views/questions/toolsPart.html @@ -0,0 +1,166 @@ +<!-- + #%L + Coselmar :: UI + $Id:$ + $HeadURL:$ + %% + Copyright (C) 2014 - 2015 Ifremer, Code Lutin + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/gpl-3.0.html>. + #L% + --> + +<div> + <!-- New Document --> + <div class="form-group"> + <div class="form-group" ng-if="context.currentUser.role == 'SUPERVISOR'"> + <a href="#/questions/new" class="form-inline navbar-left btn btn-primary">{{ 'question.button.add' | translate }}</a> + </div> + + <!-- Simple search part --> + + <form class="form-inline pull-right search-zone" role="questionOptions" ng-submit="searchQuestions()" ng-show="!advanced"> + <div class="form-group"> + <span class="fa fa-info-circle" tooltip-placement="bottom" tooltip-html-unsafe="{{ 'common.message.info.searchKeywords' | translate }}"></span> + <input type="search" class="form-control" placeholder="keyword1,keyword2,..." ng-model="searchOptions.fullTextSearch" ng-list /> + </div> + <div class="form-group"> + <button type="submit" class="btn btn-primary glyphicon glyphicon-search"></button> + </div> + <div class="form-group" ng-show="!advanced"> + <a ng-click="searchMode('advanced')" class="btn btn-action"> + <span class="fa fa-expand" aria-hidden="true"></span> + {{'common.button.advanceSearch' | translate }} + </a> + </div> + </form> + + </div> +</div> + +<div class="text-right clear"> +</div> + +<!-- Advanced Search part --> +<div ng-show="advanced" class="search-zone marginVertical20"> + <div class="form-group text-right"> + <a ng-click="searchMode('simple')" class="btn btn-action"><span class="fa fa-compress" aria-hidden="true"></span> {{ 'common.button.simpleSearch' | translate }}</a> + </div> + <form class="form-horizontal" name="questionFullOption" ng-submit="advancedSearchQuestions()"> + + <div class="form-group row"> + + <label class="col-md-1 control-label">{{ 'question.metadata.title' | translate }}</label> + <div class="col-md-2"> + <input class="form-control" type="search" class="form-control" placeholder="Titre" ng-model="searchOptions.title" /> + </div> + + <label class="col-md-1 control-label">{{ 'question.metadata.type' | translate }}</label> + <div class="col-md-2"> + <select class="form-control" name="type" ng-model="searchOptions.type"> + <option value=""></option> + <option value="REUNION">{{ 'question.metadata.type.reunion' | translate }}</option> + <option value="EXPERTISE">{{ 'question.metadata.type.expertise' | translate }}</option> + <option value="PROJECT">{{ 'question.metadata.type.project' | translate }}</option> + </select> + </div> + + <label class="col-md-1 control-label">{{ 'question.metadata.privacy' | translate }}</label> + <div class="col-md-2"> + <select class="form-control" name="privacy" ng-model="searchOptions.privacy"> + <option value=""></option> + <option value="PRIVATE">{{ 'common.privacy.private' | translate }}</option> + <option value="PUBLIC">{{ 'common.privacy.public' | translate }}</option> + </select> + </div> + + <label class="col-md-1 control-label">{{ 'question.metadata.status' | translate }}</label> + <div class="col-md-2"> + <select class="form-control" name="privacy" ng-model="searchOptions.status"> + <option value=""></option> + <option value="OPEN">{{ 'OPEN' | translate }}</option> + <option value="IN_PROGRESS">{{ 'IN_PROGRESS' | translate }}</option> + <option value="CLOSED">{{ 'CLOSED' | translate }}</option> + <option value="ADJOURNED">{{ 'ADJOURNED' | translate }}</option> + </select> + </div> + + </div> + + <div class="form-group row"> + + + <label class="col-md-2 control-label">{{ 'question.metadata.submitAfter' | translate }}</label> + <div class="col-md-3"> + <div class="input-group"> + <input type="text" class="form-control" name="submitAfterDate" + placeholder="dd/MM/yyyy" + ng-model="searchOptions.submissionAfterDate" + uib-datepicker-popup="dd/MM/yyyy" is-open="submitAfterDateOpened" + ng-click="submitAfterDateOpened = true"/> + <span class="input-group-addon"><span class="fa fa-calendar" aria-hidden="true" ng-click="openDatePicker(submitAfterDate)"></span></span> + </div> + </div> + + <label class="col-md-2 control-label">{{ 'question.metadata.submitBefore' | translate }}</label> + <div class="col-md-3"> + <div class="input-group"> + <input type="text" class="form-control" name="submitBeforeDate" + placeholder="dd/MM/yyyy" + ng-model="searchOptions.submissionBeforeDate" + uib-datepicker-popup="dd/MM/yyyy" is-open="submitBeforeDateOpened" + ng-click="submitBeforeDateOpened = true"/> + <span class="input-group-addon"><span class="fa fa-calendar" aria-hidden="true" ng-click="openDatePicker(submitBeforeDate)"></span></span> + </div> + + </div> + + <div class="col-md-2"/> + + </div> + + <div class="form-group row"> + + <label class="col-md-2 control-label" for="deadlineAfterDate">{{ 'question.metadata.deadlineAfter' | translate }}</label> + <div class="col-md-3"> + <div class="input-group"> + <input type="text" class="form-control" id="deadlineAfterDate" + placeholder="dd/MM/yyyy" + ng-model="searchOptions.deadlineAfterDate" + uib-datepicker-popup="dd/MM/yyyy" is-open="deadlineAfterDateOpened" + ng-click="deadlineAfterDateOpened = true"/> + <span class="input-group-addon"><span class="fa fa-calendar" aria-hidden="true" ng-click="openDatePicker(deadlineAfterDateOpened)"></span></span> + </div> + </div> + + <label class="col-md-2 control-label" for="deadlineBeforeDate">{{ 'question.metadata.deadlineBefore' | translate }}</label> + <div class="col-md-3"> + <div class="input-group"> + <input type="text" class="form-control" id="deadlineBeforeDate" + placeholder="dd/MM/yyyy" + ng-model="searchOptions.deadlineBeforeDate" + uib-datepicker-popup="dd/MM/yyyy" is-open="deadlineBeforeDateOpened" + ng-click="deadlineBeforeDateOpened = true"/> + <span class="input-group-addon"><span class="fa fa-calendar" aria-hidden="true" ng-click="openDatePicker(deadlineBeforeDateOpened)"></span></span> + </div> + + </div> + <div class="col-md-2 text-right"> + <button type="submit" class="btn btn-primary fa fa-search" ng-click="advancedSearchQuestions()"><span class="paddingLeft10">{{ 'common.button.search' | translate }}</span></button> + </div> + + </div> + </form> +</div> \ No newline at end of file -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
participants (1)
-
codelutin.com scm