This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 3df70cecb8064fea8f24e560f1f3b036cc4ccf2e Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Tue Jul 18 08:58:17 2017 +0200 UI des sondages --- .../pollen/persistence/entity/PollTopiaDao.java | 89 +++++++---- .../InvalidFormExceptionMapper.java | 2 +- .../org/chorem/pollen/rest/api/v1/PollApi.java | 23 +-- .../pollen/services/service/PollService.java | 16 +- .../services/service/security/SecurityService.java | 2 +- pollen-ui-riot-js/package.json | 4 +- pollen-ui-riot-js/src/main/web/css/custom.css | 8 +- pollen-ui-riot-js/src/main/web/css/main.css | 24 +-- pollen-ui-riot-js/src/main/web/i18n.json | 10 +- pollen-ui-riot-js/src/main/web/js/PollService.js | 24 ++- .../src/main/web/tag/components/Card.tag.html | 2 +- .../main/web/tag/components/LoadingCard.tag.html | 2 +- .../src/main/web/tag/poll/PollCard.tag.html | 128 ++++++++++----- .../src/main/web/tag/poll/Polls.tag.html | 171 +++++++++------------ .../src/main/web/tag/popup/Modal.tag.html | 6 +- 15 files changed, 287 insertions(+), 224 deletions(-) diff --git a/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollTopiaDao.java b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollTopiaDao.java index 6db12e0b..19be3a5c 100644 --- a/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollTopiaDao.java +++ b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollTopiaDao.java @@ -22,15 +22,19 @@ package org.chorem.pollen.persistence.entity; */ import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; +import org.apache.commons.lang3.StringUtils; +import org.chorem.pollen.persistence.DaoUtils; +import org.nuiton.util.pagination.PaginationOrder; import org.nuiton.util.pagination.PaginationParameter; import org.nuiton.util.pagination.PaginationResult; -import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -40,43 +44,74 @@ import java.util.stream.Collectors; */ public class PollTopiaDao extends AbstractPollTopiaDao<Poll> { - public PaginationResult<Poll> findAllCreated(PollenUser user, PaginationParameter paginationParameter) { - return forEquals(Poll.PROPERTY_CREATOR + "." + PollenPrincipal.PROPERTY_POLLEN_USER, user).findPage(paginationParameter); + public PaginationResult<Poll> findAll(PaginationParameter page, String search) { + + Map<String, Object> parameters = Maps.newHashMap(); + + String hql = "SELECT poll FROM " + Poll.class.getName() + " as poll"; + if (StringUtils.isNotBlank(search)) { + hql += " WHERE " + DaoUtils.getSearchClause("poll", parameters, Poll.PROPERTY_TITLE, search); + } + + return findPage(hql, parameters, page); + } - public PaginationResult<Poll> findAllInvited(PollenUser user, PaginationParameter paginationParameter) { - //TODO : use HQL + public PaginationResult<Poll> findAllCreated(PollenUser user, PaginationParameter page, String search) { - VoterListMemberTopiaDao voterListMemberDao = - topiaDaoSupplier.getDao(VoterListMember.class, VoterListMemberTopiaDao.class); + Map<String, Object> parameters = Maps.newHashMap(); + parameters.put("user", user); - List<VoterListMember> voterListMembers = - voterListMemberDao.forEquals(VoterListMember.PROPERTY_MEMBER + "." + PollenPrincipal.PROPERTY_POLLEN_USER, user).findAll(); + String hql = "SELECT poll FROM " + Poll.class.getName() + " as poll" + + " WHERE poll." + Poll.PROPERTY_CREATOR + "." + PollenPrincipal.PROPERTY_POLLEN_USER + " = :user"; + if (StringUtils.isNotBlank(search)) { + hql += " AND " + DaoUtils.getSearchClause("poll", parameters, Poll.PROPERTY_TITLE, search); + } - VoterListTopiaDao voterListDao = topiaDaoSupplier.getDao(VoterList.class, VoterListTopiaDao.class); + return findPage(hql, parameters, page); + } - Set<Poll> polls = new HashSet<>(); - for (VoterListMember member : voterListMembers) { - polls.add( - voterListDao.forEquals( - VoterList.PROPERTY_TOPIA_ID, - member.getVoterList().getTopiaId() - ).findUnique().getPoll() - ); + public PaginationResult<Poll> findAllInvited(PollenUser user, PaginationParameter page, String search) { + + Map<String, Object> parameters = Maps.newHashMap(); + parameters.put("user", user); + + String hql = "FROM " + VoterListMember.class.getName() + " as mem" + + " INNER JOIN mem." + VoterListMember.PROPERTY_VOTER_LIST + "." + VoterList.PROPERTY_POLL + " as poll" + + " WHERE mem." + VoterListMember.PROPERTY_MEMBER + "." + PollenPrincipal.PROPERTY_POLLEN_USER + " = :user"; + if (StringUtils.isNotBlank(search)) { + hql += " AND " + DaoUtils.getSearchClause("poll", parameters, Poll.PROPERTY_TITLE, search); } - return PaginationResult.of(new ArrayList<>(polls), 0, paginationParameter); + PaginationOrder order = page.getOrderClauses().get(0); + + PaginationParameter page2 = PaginationParameter.of(page.getPageNumber(), page.getPageSize(), "poll." + order.getClause(), order.isDesc()); + + List<Poll> polls = find("SELECT poll " + hql, parameters, page2); + long count = count("SELECT COUNT(poll.topiaId) " + hql, parameters); + return PaginationResult.of(polls, count, page); + } - public PaginationResult<Poll> findAllParticipated(PollenUser user, PaginationParameter paginationParameter) { - // TODO : use hql - VoteTopiaDao dao = topiaDaoSupplier.getDao(Vote.class, VoteTopiaDao.class); - List<Vote> votes = dao.forEquals(Vote.PROPERTY_VOTER + "." + PollenPrincipal.PROPERTY_POLLEN_USER, user).findAll(); - Set<Poll> polls = new HashSet<>(); - for (Vote vote : votes) { - polls.add(vote.getPoll()); + public PaginationResult<Poll> findAllParticipated(PollenUser user, PaginationParameter page, String search) { + + Map<String, Object> parameters = Maps.newHashMap(); + parameters.put("user", user); + + String hql = "FROM " + Vote.class.getName() + " as vote " + + " INNER JOIN vote." + Vote.PROPERTY_POLL + " as poll" + + " WHERE vote." + Vote.PROPERTY_VOTER + "." + PollenPrincipal.PROPERTY_POLLEN_USER + " = :user"; + if (StringUtils.isNotBlank(search)) { + hql += " AND " + DaoUtils.getSearchClause("poll", parameters, Poll.PROPERTY_TITLE, search); } - return PaginationResult.of(new ArrayList<>(polls), 0, paginationParameter); + + PaginationOrder order = page.getOrderClauses().get(0); + + PaginationParameter page2 = PaginationParameter.of(page.getPageNumber(), page.getPageSize(), "poll." + order.getClause(), order.isDesc()); + + List<Poll> polls = find("SELECT poll " + hql, parameters, page2); + long count = count("SELECT COUNT(poll.topiaId) " + hql, parameters); + return PaginationResult.of(polls, count, page); } public Set<Poll> findAllFreePolls() { diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/exceptionMappers/InvalidFormExceptionMapper.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/exceptionMappers/InvalidFormExceptionMapper.java index f074ff48..a08254ec 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/exceptionMappers/InvalidFormExceptionMapper.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/exceptionMappers/InvalidFormExceptionMapper.java @@ -15,6 +15,6 @@ public class InvalidFormExceptionMapper extends PollenAbstractExceptionMapper<In @Override protected Object getEntity(InvalidFormException exception) { - return exception; + return exception.getErrors(); } } diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java index e4598517..b3dfda64 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java @@ -45,6 +45,7 @@ import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -70,39 +71,43 @@ public class PollApi { } - @Path("/polls/polls") + @Path("/polls") @GET public PaginationResultBean<PollBean> getPolls(@Context PollService pollService, - @BeanParam PaginationParameterBean paginationParameter) { + @BeanParam PaginationParameterBean paginationParameter, + @QueryParam("search") String search) { - return pollService.getPolls(paginationParameter); + return pollService.getPolls(paginationParameter, search); } @GET @Path("/polls/created") public PaginationResultBean<PollBean> getCreatedPolls(@Context PollService pollService, - @BeanParam PaginationParameterBean paginationParameter) { + @BeanParam PaginationParameterBean paginationParameter, + @QueryParam("search") String search) { - return pollService.getCreatedPolls(paginationParameter); + return pollService.getCreatedPolls(paginationParameter, search); } @GET @Path("/polls/invited") public PaginationResultBean<PollBean> getInvitedPolls(@Context PollService pollService, - @BeanParam PaginationParameterBean paginationParameter) { + @BeanParam PaginationParameterBean paginationParameter, + @QueryParam("search") String search) { - return pollService.getInvitedPolls(paginationParameter); + return pollService.getInvitedPolls(paginationParameter, search); } @GET @Path("/polls/participated") public PaginationResultBean<PollBean> getParticipatedPolls(@Context PollService pollService, - @BeanParam PaginationParameterBean paginationParameter) { + @BeanParam PaginationParameterBean paginationParameter, + @QueryParam("search") String search) { - return pollService.getParticipatedPolls(paginationParameter); + return pollService.getParticipatedPolls(paginationParameter, search); } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java index f43cc72c..2954b0b9 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java @@ -109,49 +109,49 @@ public class PollService extends PollenServiceSupport { return input; }; - public PaginationResultBean<PollBean> getPolls(PaginationParameterBean paginationParameter) { + public PaginationResultBean<PollBean> getPolls(PaginationParameterBean paginationParameter, String search) { checkIsConnected(); checkIsAdmin(); PaginationParameter page = getPaginationParameter(paginationParameter); - PaginationResult<Poll> polls = getPollDao().forAll().findPage(page); + PaginationResult<Poll> polls = getPollDao().findAll(page, search); return toPaginationListBean(PollBean.class, polls, pollBeanFunction); } - public PaginationResultBean<PollBean> getCreatedPolls(PaginationParameterBean paginationParameter) { + public PaginationResultBean<PollBean> getCreatedPolls(PaginationParameterBean paginationParameter, String search) { checkIsConnected(); PollenUser connectedUser = getConnectedUser(); PaginationParameter page = getPaginationParameter(paginationParameter); - PaginationResult<Poll> polls = getPollDao().findAllCreated(connectedUser, page); + PaginationResult<Poll> polls = getPollDao().findAllCreated(connectedUser, page, search); return toPaginationListBean(PollBean.class, polls, pollBeanFunction); } - public PaginationResultBean<PollBean> getInvitedPolls(PaginationParameterBean paginationParameter) { + public PaginationResultBean<PollBean> getInvitedPolls(PaginationParameterBean paginationParameter, String search) { checkIsConnected(); PollenUser connectedUser = getConnectedUser(); PaginationParameter page = getPaginationParameter(paginationParameter); - PaginationResult<Poll> polls = getPollDao().findAllInvited(connectedUser, page); + PaginationResult<Poll> polls = getPollDao().findAllInvited(connectedUser, page, search); return toPaginationListBean(PollBean.class, polls, pollBeanFunction); } - public PaginationResultBean<PollBean> getParticipatedPolls(PaginationParameterBean paginationParameter) { + public PaginationResultBean<PollBean> getParticipatedPolls(PaginationParameterBean paginationParameter, String search) { checkIsConnected(); PollenUser connectedUser = getConnectedUser(); PaginationParameter page = getPaginationParameter(paginationParameter); - PaginationResult<Poll> polls = getPollDao().findAllParticipated(connectedUser, page); + PaginationResult<Poll> polls = getPollDao().findAllParticipated(connectedUser, page, search); return toPaginationListBean(PollBean.class, polls, pollBeanFunction); } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/SecurityService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/SecurityService.java index 057bf7e2..19f45119 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/SecurityService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/SecurityService.java @@ -567,7 +567,7 @@ public class SecurityService extends PollenServiceSupport { PaginationParameterBean paginationParameter = new PaginationParameterBean(); paginationParameter.setPageNumber(0); paginationParameter.setPageSize(-1); - invitedPoll.addAll(getPollDao().findAllInvited(user, paginationParameter.toPaginationParameter()).getElements()); + invitedPoll.addAll(getPollDao().findAllInvited(user, paginationParameter.toPaginationParameter(), "").getElements()); } diff --git a/pollen-ui-riot-js/package.json b/pollen-ui-riot-js/package.json index ac02cda4..a32ec03e 100644 --- a/pollen-ui-riot-js/package.json +++ b/pollen-ui-riot-js/package.json @@ -24,8 +24,8 @@ } ], "scripts": { - "start": "./node_modules/.bin/webpack-dev-server --hot --inline --host 0.0.0.0 --public localhost:8080", - "package": "./node_modules/.bin/webpack --bail" + "start": "webpack-dev-server --hot --inline --host 0.0.0.0 --public localhost:8080", + "package": "webpack --bail" }, "devDependencies": { "babel": "^6.5.2", diff --git a/pollen-ui-riot-js/src/main/web/css/custom.css b/pollen-ui-riot-js/src/main/web/css/custom.css index bdd25ab7..c854c8af 100644 --- a/pollen-ui-riot-js/src/main/web/css/custom.css +++ b/pollen-ui-riot-js/src/main/web/css/custom.css @@ -9,10 +9,10 @@ --winner: #ff9e0d; --anonymous: #666666; - --poll-created: grey; - --poll-adding_choices: orange; - --poll-voting: #04c4bb; - --poll-closed: #53bd41; + --poll-created: #eeeff8; + --poll-adding_choices: #fafaf0; + --poll-voting: #effff9; + --poll-closed: #f0faf1; --link: #96a8b2; diff --git a/pollen-ui-riot-js/src/main/web/css/main.css b/pollen-ui-riot-js/src/main/web/css/main.css index bd434d0d..67f94bd6 100644 --- a/pollen-ui-riot-js/src/main/web/css/main.css +++ b/pollen-ui-riot-js/src/main/web/css/main.css @@ -194,16 +194,6 @@ ul { border-color: var(--background); } -.card { - display: block; - margin: 5px auto; - padding: 0.5em; - border-radius: 4px; - border: 1px solid var(--main); - box-shadow: 0 0 1px hsla(0,0%,7%,.6); - color: var(--main); -} - .list-card { background-color: var(--favorit-list) } @@ -213,23 +203,19 @@ ul { } .poll-created { - color: var(--poll-created); - border-color: var(--poll-created); + background-color: var(--poll-created); } .poll-adding_choices { - color: var(--poll-adding_choices); - border-color: var(--poll-adding_choices); + background-color: var(--poll-adding_choices); } .poll-voting { - color: var(--poll-voting); - border-color: var(--poll-voting); + background-color: var(--poll-voting); } .poll-closed { - color: var(--poll-closed); - border-color: var(--poll-closed); + background-color: var(--poll-closed); } .info-label { @@ -474,4 +460,4 @@ pollenfooter a:hover { .no-border { border: 0; -} \ No newline at end of file +} diff --git a/pollen-ui-riot-js/src/main/web/i18n.json b/pollen-ui-riot-js/src/main/web/i18n.json index 947699a3..a729fe70 100644 --- a/pollen-ui-riot-js/src/main/web/i18n.json +++ b/pollen-ui-riot-js/src/main/web/i18n.json @@ -150,7 +150,8 @@ "polls_assignPollToMe": "Attacher le sondage", "polls_assignPollToMe_title": "Attacher un sondage à mon compte", "polls_assignPollToMe_desc": "Si vous avez créé un sondage sans être connecté, vous pouvez le rattacher à votre compte en remplissant ce formulaire avec l'url d'administration du sondage.", - "polls_assignSuccessMessage": "Le sondage suivant a bien été rattaché à votre compte :", + "polls_assignSuccessMessage": "Le sondage « {0} » a bien été rattaché à votre compte.", + "polls_alreadyAssignMessage": "Le sondage est déjà rattaché à votre compte", "polls_invitedPolls": "Mes invitations", "polls_participatedPolls": "Mes participations", "polls_polls": "Tous les sondages", @@ -158,6 +159,8 @@ "polls_sort": "Trier par", "polls_createDate": "Date de création", "polls_noPoll": "Aucun sondage", + "polls_one": "sondage", + "polls_many": "sondages", "signup_title": "Créer un compte", "signup_email": "Email", "signup_email_placeholder": "Entrez votre adresse email", @@ -660,13 +663,16 @@ "polls_assignPollToMe": "Link a poll to my account", "polls_assignPollToMe_title": "Link the poll", "polls_assignPollToMe_desc": "If you created a poll without being connected, you can link it to your account by fillin the form below with the administration url of the poll.", - "polls_assignSuccessMessage": "The following poll has successfully been linked to your account:", + "polls_assignSuccessMessage": "The poll \"{0}\" has successfully been linked to your account:", + "polls_alreadyAssignMessage": "Th poll is already linked to your account", "polls_invitedPolls": "My invitations", "polls_participatedPolls": "My participations", "polls_polls": "All polls", "polls_name": "Name", "polls_sort": "Sort by", "polls_noPoll": "No poll", + "polls_one": "poll", + "polls_many": "polls", "signup_title": "Create an account", "signup_email": "Email", "signup_email_placeholder": "Enter your email", diff --git a/pollen-ui-riot-js/src/main/web/js/PollService.js b/pollen-ui-riot-js/src/main/web/js/PollService.js index cd27b87a..4d087f46 100644 --- a/pollen-ui-riot-js/src/main/web/js/PollService.js +++ b/pollen-ui-riot-js/src/main/web/js/PollService.js @@ -60,24 +60,32 @@ class PollService extends FetchService { return this.post(url, poll2, {permission: poll.permission}); } - createdPolls(pagination) { + createdPolls(pagination, search) { + let params = Object.assign({}, pagination); + params.search = search || ""; let url = this._getUrlPrefix() + "/created"; - return this.get(url, pagination); + return this.get(url, params); } - invitedPolls(pagination) { + invitedPolls(pagination, search) { + let params = Object.assign({}, pagination); + params.search = search || ""; let url = this._getUrlPrefix() + "/invited"; - return this.get(url, pagination); + return this.get(url, params); } - participatedPolls(pagination) { + participatedPolls(pagination, search) { + let params = Object.assign({}, pagination); + params.search = search || ""; let url = this._getUrlPrefix() + "/participated"; - return this.get(url, pagination); + return this.get(url, params); } - polls(pagination) { + polls(pagination, search) { + let params = Object.assign({}, pagination); + params.search = search || ""; let url = this._getUrlPrefix(); - return this.get(url, pagination); + return this.get(url, params); } deletePoll(pollId, permission) { diff --git a/pollen-ui-riot-js/src/main/web/tag/components/Card.tag.html b/pollen-ui-riot-js/src/main/web/tag/components/Card.tag.html index 3701b44b..7e225428 100644 --- a/pollen-ui-riot-js/src/main/web/tag/components/Card.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/components/Card.tag.html @@ -44,7 +44,7 @@ require("./LetterAvatar.tag.html"); position: relative; display: block; padding: 10px 0; - margin: 5px; + margin: 10px; box-shadow: 0 0 10px hsla(0,0%,7%,.6); width: 180px; overflow: hidden; diff --git a/pollen-ui-riot-js/src/main/web/tag/components/LoadingCard.tag.html b/pollen-ui-riot-js/src/main/web/tag/components/LoadingCard.tag.html index 01032e12..b55e0257 100644 --- a/pollen-ui-riot-js/src/main/web/tag/components/LoadingCard.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/components/LoadingCard.tag.html @@ -13,7 +13,7 @@ flex-direction: column; align-items: center; padding: 10px 0; - margin: 5px; + margin: 10px; width: 180px; overflow: hidden; height: 207px; diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/PollCard.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/PollCard.tag.html index 02322db8..96366e19 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/PollCard.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/PollCard.tag.html @@ -1,61 +1,109 @@ -<PollCard class="card poll-{opts.poll.status.toLowerCase()}"> - <div class="poll-header"> - <a class="poll-title" href="#poll/{opts.poll.id}/vote/{opts.poll.permission}"> - {opts.poll.title} +<PollCard class="poll-{opts.poll.status.toLowerCase()}"> + + <div class="card-actions"> + <a class="info" + title={__.edit} + href="#poll/{opts.poll.id}/vote/{opts.poll.permission}"> + <i class="fa fa-pencil"></i> + </a> + <a class="error" + if={opts.poll.permission} + title={__.delete} + onclick={deletePoll}> + <i class="fa fa-times"></i> </a> - <div class="poll-status"> - {__[opts.poll.status]} - </div> </div> - <p>{opts.poll.description}</p> - <div> - {__.createdBy} {opts.poll.creatorName} {__.createdIn} {formatDate(opts.poll.createDate)} - </div> - <div if={opts.poll.status === "CREATED" && opts.poll.choiceAddAllowed}> - {__.beginChoiceFrom} {formatDate(opts.poll.beginChoiceDate)} - </div> - <div if={opts.poll.status === "CREATED"}> - {__.votingFrom} {formatDate(opts.poll.beginDate)} - <span if={opts.poll.endDate}> {__votingFromTo} {formatDate(opts.poll.endDate)}</span> - </div> + <div class="card-content"> - <div if={opts.poll.status === "ADDING_CHOICES"}> - {__.beginChoiceTo} {formatDate(opts.poll.endChoiceDate)} ( - <span if={opts.poll.choiceCount === 0}>{__.noChoice}</span> - <span if={opts.poll.choiceCount === 1}>1 {__.choice}</span> - <span if={opts.poll.choiceCount > 1}>{opts.poll.choiceCount} {__.choices}</span> - ) - </div> + <div class="poll-title" title={opts.poll.title}> + {opts.poll.title} + </div> - <div if={opts.poll.status === "VOTING"}> - <span if={opts.poll.voteCount === 0}>{__.noVote}</span> - <span if={opts.poll.voteCount === 1}>1 {__.vote}</span> - <span if={opts.poll.voteCount > 1}>{opts.poll.voteCount} {__.votes}</span> - <span if={opts.poll.endDate}> {__.votingTo} {formatDate(opts.poll.endDate)}</span> - </div> + <div class="poll-creator-avatar"> + <LetterAvatar name={opts.poll.creatorName} rounded="true"/> + </div> + <div class="poll-creator-name" title={opts.poll.creatorName}> + {opts.poll.creatorName} + </div> + <div class="poll-creation-date"> + {formatDate(opts.poll.createDate, "LL")} + <br\> + {formatDate(opts.poll.createDate, "LT")} + </div> - <div if={opts.poll.status === "CLOSED"}> - <span if={opts.poll.voteCount === 0}>{__.noVote}</span> - <span if={opts.poll.voteCount === 1}>1 {__.vote}</span> - <span if={opts.poll.voteCount > 1}>{opts.poll.voteCount} {__.votes}</span> - <span if={opts.poll.endDate}> {__.closedFrom} {formatDate(opts.poll.endDate)}</span> + <div class="poll-votes"> + {opts.poll.voteCount === 0 ? __.noVote : (opts.poll.voteCount + " " + (count === 1 ? __.vote : __.votes))} + </div> </div> <script type="es6"> let session = require("../../js/Session"); + let pollService = require("../../js/PollService"); this.installBundle(session, "poll"); + + this.deletePoll = (e) => { + e.preventDefault(); + e.stopPropagation(); + this.confirm(this.__.deletePoll).then((confirm) => { + if (confirm) { + pollService.deletePoll(this.opts.poll.id, this.opts.poll.permission).then(() => { + this.opts.onPollListChange(); + }); + } + }); + }; + </script> <style> - .poll-title { - color: inherit; + pollcard { + height: 207px; + position: relative; + display: block; + padding: 10px 0; + margin: 10px; + box-shadow: 0 0 10px hsla(0,0%,7%,.6); + width: 180px; + overflow: hidden; + } + + .card-actions { + position: absolute; + top: 0; + right: 0; + transform: translate3d(32px, 0px, 0px); + transition: transform 0.6s; + } + + pollcard:hover .card-actions { + transform: translate3d(0px, 0px, 0px); } - .poll-header { + .card-content { display: flex; - justify-content: space-between; + flex-direction: column; + align-items: center; + } + + .poll-title { + width: 100%; + font-size: 1.5em; + white-space: nowrap; + overflow: hidden; + text-align: center; + text-overflow: ellipsis; + } + + .poll-title, + .poll-creator-name, + .poll-creation-date { + margin-bottom: 20px; + } + + .poll-creator-avatar { + font-size: 1.5em; } </style> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Polls.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Polls.tag.html index 4790c1e2..396f4035 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Polls.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Polls.tag.html @@ -1,147 +1,118 @@ -require("../Pagination.tag.html"); require("./PollCard.tag.html"); +require("../components/LazyLoad.tag.html"); +require("../components/LoadingCard.tag.html"); require("../components/HumanInput.tag.html"); <Polls> <div class="container" show="{loaded}"> <h1>{__[opts.method]}</h1> - <div class="main-content"> + <div class="c-alert c-alert--info"> + {count === 0 ? __.noPoll : (count + " " + (count === 1 ? __.one : __.many))} + </div> - <div show={polls.length > 0} > - <div class="o-form-element sort"> - <label class="c-label" for="sort">{__.sort}</label> - <div class="c-input-group"> - <div class="o-field"> - <select class="c-field" - onchange={selectSort}> - <option value="topiaCreateDate">{__.createDate}</option> - <option value="title">{__.name}</option> - </select> - </div> - <button class="c-button c-button--brand" - onclick={toggleSort}> - <i class="fa {pagination.desc ? 'fa-sort-amount-desc' : 'fa-sort-amount-asc'}"></i> - </button> - </div> + <Search onsearch="{refresh}" search="{search}" /> + + <LazyLoad pagination={pagination} onload={lazyLoad} load-size="20" ref="lazyLoad" class="elements"> + <yield to="element"> + <PollCard poll={element} on-poll-list-change={parent.parent.refresh}/> + </yield> + <yield to="loading"> + <LoadingCard loading={nbNextGroup}> + {parent.parent._l("loading", nbNext)} + </LoadingCard> + </yield> + </LazyLoad> + + <ContextualMenu if={opts.method === "createdPolls"}> + <a onclick={parent.assignPoll}> + {parent.__.assignPollToMe_title} + </a> + </ContextualMenu> + + <Modal ref="assignModal" onsubmit={assign} header={__.assignPollToMe_title} label={__.assignPollToMe} type="success"> + <div class="o-form-element"> + <label class="c-label" for="pollToAssign">{parent.__.assignPollToMe_desc}</label> + <div class="o-field o-field--icon-left"> + <i class="fa fa-fw fa-link c-icon"></i> + <input class="c-field" + type="text" + name="pollToAssign" + ref="pollToAssign" + placeholder={parent.pollToAssignPlaceholder} + pattern={parent.pollToAssignUrlPattern} + required> </div> - - <Pagination pagination={pagination} onchange="{refresh}" /> - - <PollCard each={poll in polls} poll={poll} /> - - <Pagination pagination={pagination} onchange="{refresh}" /> </div> - <div show={polls.length === 0} class="c-alert c-alert--info"> - {__.noPoll} - </div> - - <div if={opts.method === "createdPolls"}> - <hr/> - <form class="assign-form"> - <HumanInput onsubmit="{assignPoll}"/> - <h3 class="c-heading">{__.assignPollToMe_title}</h3> - - <div class="o-form-element"> - <label class="c-label" for="pollToAssign">{__.assignPollToMe_desc}</label> - <div class="o-field o-field--icon-left"> - <i class="fa fa-fw fa-link c-icon"></i> - <input class="c-field" - type="text" - name="pollToAssign" - ref="pollToAssign" - placeholder={pollToAssignPlaceholder} - pattern={pollToAssignUrlPattern} - required> - </div> - </div> - <div class="actions-right"> - <button type="submit" - class="c-button c-button--success"> - <i class="fa fa-link"/> - {__.assignPollToMe} - </button> - </div> - </form> - </div> - </div> + </Modal> </div> <script type="es6"> this.loaded = false; let session = require("../../js/Session"); + let Message = require("../../js/Message"); this.installBundle(session, "polls"); this.pollToAssignPlaceholder = session.pollenUIContext.uiEndPoint + "/#poll/xxxx/vote/xxxx"; this.pollToAssignUrlPattern = session.pollenUIContext.uiEndPoint + "/#poll/(.+)/vote/(.+)"; - this.assignedPollTitle = undefined; this.pagination = { - order: "topiaCreateDate", - desc: true, - pageSize: 5, + order: "title", + desc: false, + pageSize: -1, pageNumber: 0 }; this.polls = []; + this.search = {value: ""}; let pollService = require("../../js/PollService"); this.refresh = () => { - this.assignedPollTitle = undefined; - return pollService[this.opts.method](this.pagination).then((result) => { - this.polls = result.elements; - Object.assign(this.pagination, result.pagination); - this.loaded = true; - this.update(); - return result; - }); + this.refs.lazyLoad.reload(); }; - this.refresh(); - - this.toggleSort = () => { - this.pagination.desc = !this.pagination.desc; - this.refresh(); + this.lazyLoad = pagination => { + return pollService[this.opts.method](pagination, this.search.value).then((result) => { + if (!this.loaded) { + this.count = result.pagination.count; + this.loaded = true; + this.update(); + } + return result; + }); }; - this.selectSort = (e) => { - this.pagination.order = e.target.value; - this.refresh(); + this.assignPoll = () => { + this.refs.assignModal.open().then(() => { + this.update(); + }, () => {}); + this.update(); }; - this.assignPoll = (e) => { - e.preventDefault(); - e.stopPropagation(); - var pollUrl = this.refs.pollToAssign.value; + this.assign = () => { + var pollUrl = this.refs.assignModal.refs.pollToAssign.value; var regex = new RegExp(this.pollToAssignUrlPattern); var finds = regex.exec(pollUrl); return pollService.assignPoll(finds[1], finds[2]).then((result) => { if (result) { this.refresh(); - this.logger.log(result); - this.info(this.__.assignSuccessMessage, result.title, null, "success"); - this.refs.pollToAssign.value = ""; - this.update(); + this.bus.trigger("message", new Message(this._l("assignSuccessMessage", result.title), "succes")); + } else { + this.bus.trigger("message", new Message(this.__.alreadyAssignMessage, "warning")); } + this.refs.assignModal.refs.pollToAssign.value = ""; + this.update(); + }, errors => { + this.bus.trigger("message", errors); + this.update(); }); }; </script> <style> - .main-content { - padding: 20px 20px 40px 20px; - } - - .o-form-element.sort .c-label:first-child { - width: 70px; - display: inline-block; - text-align: right; - float: left; - padding-top: 0.5em; - padding-right: 5px; - } - - .o-form-element.sort .c-input-group { - width: 200px; + .elements { + display: flex; + flex-wrap: wrap; + justify-content: flex-start; } </style> </Polls> diff --git a/pollen-ui-riot-js/src/main/web/tag/popup/Modal.tag.html b/pollen-ui-riot-js/src/main/web/tag/popup/Modal.tag.html index 7dfbc060..474e6d6b 100644 --- a/pollen-ui-riot-js/src/main/web/tag/popup/Modal.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/popup/Modal.tag.html @@ -52,7 +52,11 @@ require("../components/HumanInput.tag.html"); let promise = this.opts.onsubmit ? this.opts.onsubmit() : Promise.resolve(); - promise.then(() => {this.close();}, () => {}); + promise.then(() => { + this.close(); + }, (error) => { + this.logger.error(error); + }); }; -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.