branch develop updated (c3ba73e2 -> 2ac90b4c)
This is an automated email from the git hooks/post-receive script. New change to branch develop in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git from c3ba73e2 style new 98067a3b refs #68 throw exception when the user wants to login or forgot his password but he did not validate his email address new fea97cc3 style new 2ac90b4c refs #61 Export des resultat d'un sondage (version imprimable de la page des résultats) The 3 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 2ac90b4c3472ce580d9ba5f7a3b8c7bc12060b81 Author: Kevin Morin <morin@codelutin.com> Date: Thu Jul 6 17:06:58 2017 +0200 refs #61 Export des resultat d'un sondage (version imprimable de la page des résultats) commit fea97cc3cd78a5ac40558aad954c276e2eb406c7 Author: Kevin Morin <morin@codelutin.com> Date: Thu Jul 6 17:06:14 2017 +0200 style commit 98067a3b703819e11daf135069182c8c43fa2609 Author: Kevin Morin <morin@codelutin.com> Date: Thu Jul 6 17:04:41 2017 +0200 refs #68 throw exception when the user wants to login or forgot his password but he did not validate his email address Summary of changes: .../pollen/persistence/entity/PollenUserImpl.java | 12 + pollen-persistence/src/main/xmi/pollen.zargo | Bin 26098 -> 26300 bytes .../org/chorem/pollen/rest/api/v1/AuthApi.java | 14 +- pollen-rest-api/src/main/resources/mapping | 1 + ....java => PollenEmailNotValidatedException.java} | 13 +- .../services/service/security/SecurityService.java | 12 +- .../pollen/services/AbstractPollenServiceTest.java | 4 +- .../services/service/FavoriteListServiceTest.java | 11 +- .../pollen/services/service/PollServiceTest.java | 3 +- .../services/service/PollenUserServiceTest.java | 7 +- .../services/service/VoterListServiceTest.java | 3 +- pollen-ui-riot-js/src/main/web/css/custom.css | 1 + pollen-ui-riot-js/src/main/web/css/print.css | 31 ++ pollen-ui-riot-js/src/main/web/i18n.json | 17 +- pollen-ui-riot-js/src/main/web/index.html | 9 +- .../src/main/web/tag/SignCheck.tag.html | 5 +- .../src/main/web/tag/UserProfile.tag.html | 244 +++++++------- .../web/tag/components/ContextualMenu.tag.html | 6 +- .../web/tag/favoriteList/FavoriteList.tag.html | 32 +- .../web/tag/favoriteList/FavoriteLists.tag.html | 62 ++-- .../src/main/web/tag/poll/Comments.tag.html | 2 +- .../src/main/web/tag/poll/Poll.tag.html | 19 +- .../src/main/web/tag/poll/Polls.tag.html | 18 +- .../src/main/web/tag/poll/Report.tag.html | 2 +- .../src/main/web/tag/poll/Votes.tag.html | 372 ++++++++++----------- 25 files changed, 478 insertions(+), 422 deletions(-) create mode 100644 pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollenUserImpl.java copy pollen-services/src/main/java/org/chorem/pollen/services/service/security/{PollenAuthenticationException.java => PollenEmailNotValidatedException.java} (74%) create mode 100644 pollen-ui-riot-js/src/main/web/css/print.css -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
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 98067a3b703819e11daf135069182c8c43fa2609 Author: Kevin Morin <morin@codelutin.com> Date: Thu Jul 6 17:04:41 2017 +0200 refs #68 throw exception when the user wants to login or forgot his password but he did not validate his email address --- .../pollen/persistence/entity/PollenUserImpl.java | 12 ++++++++ pollen-persistence/src/main/xmi/pollen.zargo | Bin 26098 -> 26300 bytes .../org/chorem/pollen/rest/api/v1/AuthApi.java | 14 +++++++-- pollen-rest-api/src/main/resources/mapping | 1 + .../security/PollenEmailNotValidatedException.java | 34 +++++++++++++++++++++ .../services/service/security/SecurityService.java | 12 ++++++-- .../pollen/services/AbstractPollenServiceTest.java | 4 ++- .../services/service/FavoriteListServiceTest.java | 11 ++++--- .../pollen/services/service/PollServiceTest.java | 3 +- .../services/service/PollenUserServiceTest.java | 7 +++-- .../services/service/VoterListServiceTest.java | 3 +- 11 files changed, 85 insertions(+), 16 deletions(-) diff --git a/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollenUserImpl.java b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollenUserImpl.java new file mode 100644 index 00000000..c45245ca --- /dev/null +++ b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollenUserImpl.java @@ -0,0 +1,12 @@ +package org.chorem.pollen.persistence.entity; + +/** + * @author Kevin Morin (Code Lutin) + */ +public class PollenUserImpl extends PollenUserAbstract { + + @Override + public boolean isEmailValidated() { + return emailActivationToken == null; + } +} diff --git a/pollen-persistence/src/main/xmi/pollen.zargo b/pollen-persistence/src/main/xmi/pollen.zargo index 2ad42e70..aef16793 100644 Binary files a/pollen-persistence/src/main/xmi/pollen.zargo and b/pollen-persistence/src/main/xmi/pollen.zargo differ diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java index 1c506063..0f3d6bcd 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java @@ -34,6 +34,7 @@ import org.chorem.pollen.services.service.PollenUserService; import org.chorem.pollen.services.service.security.MissingAuthenticationException; import org.chorem.pollen.services.service.security.PollenAuthenticationException; import org.chorem.pollen.services.service.security.PollenCypherTechnicalException; +import org.chorem.pollen.services.service.security.PollenEmailNotValidatedException; import org.chorem.pollen.services.service.security.PollenInvalidSessionTokenException; import org.chorem.pollen.services.service.security.SecurityService; import org.debux.webmotion.server.WebMotionController; @@ -70,7 +71,12 @@ public class AuthApi extends WebMotionController { } - public PollenEntityRef<PollenUser> login(HttpContext requestContext, SecurityService securityService) throws PollenAuthenticationException, MissingAuthenticationException, PollenInvalidSessionTokenException, PollenCypherTechnicalException { + public PollenEntityRef<PollenUser> login(HttpContext requestContext, SecurityService securityService) + throws PollenAuthenticationException, + MissingAuthenticationException, + PollenInvalidSessionTokenException, + PollenCypherTechnicalException, + PollenEmailNotValidatedException { String authHeader = requestContext.getHeader("Authorization"); @@ -122,7 +128,9 @@ public class AuthApi extends WebMotionController { } - public PollenEntityRef<PollenUser> login2(SecurityService securityService, String login, String password, Boolean rememberMe) throws PollenAuthenticationException { + public PollenEntityRef<PollenUser> login2(SecurityService securityService, String login, String password, Boolean rememberMe) + throws PollenAuthenticationException, + PollenEmailNotValidatedException { return securityService.login(login, password, rememberMe); @@ -141,7 +149,7 @@ public class AuthApi extends WebMotionController { } - public void lostPassword(SecurityService securityService, String login) { + public void lostPassword(SecurityService securityService, String login) throws PollenEmailNotValidatedException { securityService.lostPassword(login); diff --git a/pollen-rest-api/src/main/resources/mapping b/pollen-rest-api/src/main/resources/mapping index 6239c1a9..d6076def 100644 --- a/pollen-rest-api/src/main/resources/mapping +++ b/pollen-rest-api/src/main/resources/mapping @@ -38,6 +38,7 @@ default.render=org.chorem.pollen.rest.api.PollenRender org.chorem.pollen.services.service.security.PollenAuthenticationException ErrorAction.on401 org.chorem.pollen.services.service.security.PollenInvalidSessionTokenException ErrorAction.on401 org.chorem.pollen.services.service.security.PollenUnauthorizedException ErrorAction.on403 +org.chorem.pollen.services.service.security.PollenEmailNotValidatedException ErrorAction.on403 org.chorem.pollen.services.service.security.PollenInvalidPermissionException ErrorAction.on403 org.chorem.pollen.services.service.security.PollenInvalidEmailActivationTokenException ErrorAction.on403 org.chorem.pollen.services.service.InvalidFormException ErrorAction.on400Form diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenEmailNotValidatedException.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenEmailNotValidatedException.java new file mode 100644 index 00000000..e978b5d0 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenEmailNotValidatedException.java @@ -0,0 +1,34 @@ +package org.chorem.pollen.services.service.security; + +/* + * #%L + * Pollen :: Service + * %% + * Copyright (C) 2009 - 2017 Code Lutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + +/** + * Error thrown when the user tires to login although he has not yet validated his email. + * + * @author Kevin Morin - morin@codelutin.com + */ +public class PollenEmailNotValidatedException extends Exception { + + public PollenEmailNotValidatedException() { + super("emailNotValidated"); + } +} 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 42163426..057bf7e2 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 @@ -121,7 +121,8 @@ public class SecurityService extends PollenServiceSupport { } - public PollenEntityRef<PollenUser> login(String login, String password, Boolean rememberMe) throws PollenAuthenticationException { + public PollenEntityRef<PollenUser> login(String login, String password, Boolean rememberMe) + throws PollenAuthenticationException, PollenEmailNotValidatedException { Subject subject = getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(login, password); @@ -136,6 +137,9 @@ public class SecurityService extends PollenServiceSupport { } PollenUser user = getPollenUserDao().forEmailEquals(login).findUnique(); + if (!user.isEmailValidated()) { + throw new PollenEmailNotValidatedException(); + } // Generate a token PollenToken pollenToken = generateNewToken(); @@ -172,7 +176,7 @@ public class SecurityService extends PollenServiceSupport { } - public void lostPassword(String login) { + public void lostPassword(String login) throws PollenEmailNotValidatedException { Preconditions.checkNotNull(login); @@ -182,6 +186,10 @@ public class SecurityService extends PollenServiceSupport { throw new PollenUnauthorizedException(login); } + if (!user.isEmailValidated()) { + throw new PollenEmailNotValidatedException(); + } + String newPassword = serviceContext.generatePassword(); getSecurityService().setUserPassword(user, newPassword); diff --git a/pollen-services/src/test/java/org/chorem/pollen/services/AbstractPollenServiceTest.java b/pollen-services/src/test/java/org/chorem/pollen/services/AbstractPollenServiceTest.java index a84c9095..b2cd7c11 100644 --- a/pollen-services/src/test/java/org/chorem/pollen/services/AbstractPollenServiceTest.java +++ b/pollen-services/src/test/java/org/chorem/pollen/services/AbstractPollenServiceTest.java @@ -27,6 +27,7 @@ import org.chorem.pollen.persistence.entity.SessionToken; import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.service.InvalidFormException; import org.chorem.pollen.services.service.security.PollenAuthenticationException; +import org.chorem.pollen.services.service.security.PollenEmailNotValidatedException; import org.chorem.pollen.services.service.security.PollenInvalidSessionTokenException; import org.chorem.pollen.services.service.security.SecurityService; import org.chorem.pollen.services.test.FakePollenApplicationContext; @@ -85,7 +86,8 @@ public abstract class AbstractPollenServiceTest { } } - protected void login(String login, String password) throws PollenInvalidSessionTokenException, PollenAuthenticationException { + protected void login(String login, String password) throws PollenInvalidSessionTokenException, + PollenAuthenticationException, PollenEmailNotValidatedException { SecurityService securityService = newService(SecurityService.class); diff --git a/pollen-services/src/test/java/org/chorem/pollen/services/service/FavoriteListServiceTest.java b/pollen-services/src/test/java/org/chorem/pollen/services/service/FavoriteListServiceTest.java index 04551bf9..1d9baedb 100644 --- a/pollen-services/src/test/java/org/chorem/pollen/services/service/FavoriteListServiceTest.java +++ b/pollen-services/src/test/java/org/chorem/pollen/services/service/FavoriteListServiceTest.java @@ -34,6 +34,7 @@ import org.chorem.pollen.services.bean.PaginationParameterBean; import org.chorem.pollen.services.bean.PaginationResultBean; import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.service.security.PollenAuthenticationException; +import org.chorem.pollen.services.service.security.PollenEmailNotValidatedException; import org.chorem.pollen.services.service.security.PollenInvalidSessionTokenException; import org.junit.Assert; import org.junit.Before; @@ -75,7 +76,7 @@ public class FavoriteListServiceTest extends AbstractPollenServiceTest { "user2@pollen.org"; @Test - public void importFavoriteListFromFile() throws PollenInvalidSessionTokenException, PollenAuthenticationException, InvalidFormException, IOException, FavoriteListImportException { + public void importFavoriteListFromFile() throws PollenInvalidSessionTokenException, PollenAuthenticationException, InvalidFormException, IOException, FavoriteListImportException, PollenEmailNotValidatedException { login("jean@pollen.fake", "fake"); @@ -105,7 +106,7 @@ public class FavoriteListServiceTest extends AbstractPollenServiceTest { } @Test - public void createFavoriteList() throws PollenInvalidSessionTokenException, PollenAuthenticationException, InvalidFormException { + public void createFavoriteList() throws PollenInvalidSessionTokenException, PollenAuthenticationException, InvalidFormException, PollenEmailNotValidatedException { login("jean@pollen.fake", "fake"); @@ -222,7 +223,7 @@ public class FavoriteListServiceTest extends AbstractPollenServiceTest { } @Test - public void editFavoriteList() throws PollenInvalidSessionTokenException, PollenAuthenticationException, InvalidFormException { + public void editFavoriteList() throws PollenInvalidSessionTokenException, PollenAuthenticationException, InvalidFormException, PollenEmailNotValidatedException { login("jean@pollen.fake", "fake"); @@ -291,7 +292,7 @@ public class FavoriteListServiceTest extends AbstractPollenServiceTest { } @Test - public void editFavoriteListMember() throws PollenInvalidSessionTokenException, PollenAuthenticationException, InvalidFormException { + public void editFavoriteListMember() throws PollenInvalidSessionTokenException, PollenAuthenticationException, InvalidFormException, PollenEmailNotValidatedException { login("jean@pollen.fake", "fake"); @@ -386,7 +387,7 @@ public class FavoriteListServiceTest extends AbstractPollenServiceTest { @Test - public void editChildFavoriteList() throws PollenInvalidSessionTokenException, PollenAuthenticationException, InvalidFormException { + public void editChildFavoriteList() throws PollenInvalidSessionTokenException, PollenAuthenticationException, InvalidFormException, PollenEmailNotValidatedException { login("jean@pollen.fake", "fake"); // create a first list diff --git a/pollen-services/src/test/java/org/chorem/pollen/services/service/PollServiceTest.java b/pollen-services/src/test/java/org/chorem/pollen/services/service/PollServiceTest.java index 41de7296..0f67bc10 100644 --- a/pollen-services/src/test/java/org/chorem/pollen/services/service/PollServiceTest.java +++ b/pollen-services/src/test/java/org/chorem/pollen/services/service/PollServiceTest.java @@ -31,6 +31,7 @@ import org.chorem.pollen.services.bean.ChoiceBean; import org.chorem.pollen.services.bean.PollBean; import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.service.security.PollenAuthenticationException; +import org.chorem.pollen.services.service.security.PollenEmailNotValidatedException; import org.chorem.pollen.services.service.security.PollenInvalidPermissionException; import org.chorem.pollen.services.service.security.PollenInvalidSessionTokenException; import org.chorem.pollen.services.service.security.PollenUnauthorizedException; @@ -536,7 +537,7 @@ public class PollServiceTest extends AbstractPollenServiceTest { // } @Test - public void testAssignPollToConnectedUser() throws PollenInvalidSessionTokenException, PollenAuthenticationException { + public void testAssignPollToConnectedUser() throws PollenInvalidSessionTokenException, PollenAuthenticationException, PollenEmailNotValidatedException { Poll poll = fixture(PollenFixtures.POLL_NORMAL_ID); Assert.assertNull(poll.getCreator().getPollenUser()); try { diff --git a/pollen-services/src/test/java/org/chorem/pollen/services/service/PollenUserServiceTest.java b/pollen-services/src/test/java/org/chorem/pollen/services/service/PollenUserServiceTest.java index be6d46eb..c3cb03db 100644 --- a/pollen-services/src/test/java/org/chorem/pollen/services/service/PollenUserServiceTest.java +++ b/pollen-services/src/test/java/org/chorem/pollen/services/service/PollenUserServiceTest.java @@ -29,6 +29,7 @@ import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.bean.PollenUserBean; import org.chorem.pollen.services.service.security.PollenAuthenticationException; +import org.chorem.pollen.services.service.security.PollenEmailNotValidatedException; import org.chorem.pollen.services.service.security.PollenInvalidSessionTokenException; import org.junit.Assert; import org.junit.Before; @@ -63,7 +64,7 @@ public class PollenUserServiceTest extends AbstractPollenServiceTest { } @Test - public void testGetPollenUsers() throws PollenAuthenticationException, PollenInvalidSessionTokenException { + public void testGetPollenUsers() throws PollenAuthenticationException, PollenInvalidSessionTokenException, PollenEmailNotValidatedException { login("jean@pollen.fake", "fake"); @@ -75,7 +76,7 @@ public class PollenUserServiceTest extends AbstractPollenServiceTest { } @Test - public void testGetPollenUser() throws PollenInvalidSessionTokenException, PollenAuthenticationException { + public void testGetPollenUser() throws PollenInvalidSessionTokenException, PollenAuthenticationException, PollenEmailNotValidatedException { login("jean@pollen.fake", "fake"); @@ -182,7 +183,7 @@ public class PollenUserServiceTest extends AbstractPollenServiceTest { } @Test - public void testEditUser() throws InvalidFormException, PollenInvalidSessionTokenException, PollenAuthenticationException { + public void testEditUser() throws InvalidFormException, PollenInvalidSessionTokenException, PollenAuthenticationException, PollenEmailNotValidatedException { login("jean@pollen.fake", "fake"); diff --git a/pollen-services/src/test/java/org/chorem/pollen/services/service/VoterListServiceTest.java b/pollen-services/src/test/java/org/chorem/pollen/services/service/VoterListServiceTest.java index dcf62172..f1f2e990 100644 --- a/pollen-services/src/test/java/org/chorem/pollen/services/service/VoterListServiceTest.java +++ b/pollen-services/src/test/java/org/chorem/pollen/services/service/VoterListServiceTest.java @@ -34,6 +34,7 @@ import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.bean.VoterListBean; import org.chorem.pollen.services.bean.VoterListMemberBean; import org.chorem.pollen.services.service.security.PollenAuthenticationException; +import org.chorem.pollen.services.service.security.PollenEmailNotValidatedException; import org.chorem.pollen.services.service.security.PollenInvalidSessionTokenException; import org.junit.Assert; import org.junit.Before; @@ -142,7 +143,7 @@ public class VoterListServiceTest extends AbstractPollenServiceTest { // } @Test - public void createVoterList() throws InvalidFormException, PollenInvalidSessionTokenException, PollenAuthenticationException { + public void createVoterList() throws InvalidFormException, PollenInvalidSessionTokenException, PollenAuthenticationException, PollenEmailNotValidatedException { login("jean@pollen.fake", "fake"); -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
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 fea97cc3cd78a5ac40558aad954c276e2eb406c7 Author: Kevin Morin <morin@codelutin.com> Date: Thu Jul 6 17:06:14 2017 +0200 style --- pollen-ui-riot-js/src/main/web/css/custom.css | 1 + .../src/main/web/tag/SignCheck.tag.html | 5 +- .../src/main/web/tag/UserProfile.tag.html | 244 +++++++------- .../web/tag/components/ContextualMenu.tag.html | 6 +- .../web/tag/favoriteList/FavoriteList.tag.html | 32 +- .../web/tag/favoriteList/FavoriteLists.tag.html | 62 ++-- .../src/main/web/tag/poll/Polls.tag.html | 18 +- .../src/main/web/tag/poll/Votes.tag.html | 372 ++++++++++----------- 8 files changed, 360 insertions(+), 380 deletions(-) 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 bdf67d1b..bdd25ab7 100644 --- a/pollen-ui-riot-js/src/main/web/css/custom.css +++ b/pollen-ui-riot-js/src/main/web/css/custom.css @@ -1,6 +1,7 @@ :root{ --main: #04c4bb; + --main-hover: #129993; --background: #ffffff; --default: #2c3e50; --field-border: #96a8b2; diff --git a/pollen-ui-riot-js/src/main/web/tag/SignCheck.tag.html b/pollen-ui-riot-js/src/main/web/tag/SignCheck.tag.html index a7c695f7..6bad4cbc 100644 --- a/pollen-ui-riot-js/src/main/web/tag/SignCheck.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/SignCheck.tag.html @@ -19,8 +19,9 @@ * #L% */ <SignCheck> + <h1><i class="fa fa-user"/> {__.title}</h1> + <div class="container"> - <h1 class="c-heading"><i class="fa fa-user"/> {__.title}</h1> <div show={waiting}> {__.validating} @@ -79,7 +80,7 @@ <style> .container { - width: 500px; + padding: 20px 20px 40px 20px; } </style> diff --git a/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html b/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html index bbc65b4f..b33a4482 100644 --- a/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html @@ -2,117 +2,120 @@ require("./components/HumanInput.tag.html"); <UserProfile> <div class="container"> - <h1 class="c-heading"><i class="fa fa-user"/> {__.title}</h1> - <hr> - <form ref="identity-form" class="identity-form"> - <HumanInput onsubmit={submitIdentity}/> - <h3 class="c-heading"><i class="fa fa-address-card"/> {__.identity}</h3> - <div class="o-form-element"> - <label class="c-label" for="name">{__.name}</label> - <input class="c-field {c-field--error : errors.name}" - type="text" - name="name" - ref="name" - value={user.name} - placeholder="{__.name_placeholder}" - required> - <div if="{errors.name}" - class="c-hint--static c-hint--error"> - {errors.name} + <h1><i class="fa fa-user"/> {__.title}</h1> + + <div class="main-content"> + + <form ref="identity-form" class="identity-form"> + <HumanInput onsubmit={submitIdentity}/> + <h3 class="c-heading"><i class="fa fa-address-card"/> {__.identity}</h3> + <div class="o-form-element"> + <label class="c-label" for="name">{__.name}</label> + <input class="c-field {c-field--error : errors.name}" + type="text" + name="name" + ref="name" + value={user.name} + placeholder="{__.name_placeholder}" + required> + <div if="{errors.name}" + class="c-hint--static c-hint--error"> + {errors.name} + </div> </div> - </div> - - <div class="o-form-element"> - <label class="c-label" for="email">{__.email}</label> - <div class="o-field o-field--icon-right"> - <input class="c-field {c-field--error : errors.email}" - type="email" - name="email" - ref="email" - value={user.email} - placeholder="{__.email_placeholder}" - required> - <i class="fa fa-fw fa-{user.emailIsValidate ? 'check' : 'refresh'} c-icon" - title={user.emailIsValidate ? __.emailValidate : __.emailValidationWaiting}></i> - </div> - <div if="{errors.email}" - class="c-hint--static c-hint--error"> - {errors.email} + + <div class="o-form-element"> + <label class="c-label" for="email">{__.email}</label> + <div class="o-field o-field--icon-right"> + <input class="c-field {c-field--error : errors.email}" + type="email" + name="email" + ref="email" + value={user.email} + placeholder="{__.email_placeholder}" + required> + <i class="fa fa-fw fa-{user.emailIsValidate ? 'check' : 'refresh'} c-icon" + title={user.emailIsValidate ? __.emailValidate : __.emailValidationWaiting}></i> + </div> + <div if="{errors.email}" + class="c-hint--static c-hint--error"> + {errors.email} + </div> + </div> + + <div class="actions-right"> + <button type="button" + class="c-button c-button--gost-info" + if={!user.emailIsValidate} + onclick={resendValidation}> + <i class="fa fa-paper-plane" aria-hidden="true"></i> + {__.resendValidation} + </button> + <button type="submit" + class="c-button c-button--info"> + <i class="fa fa-check" aria-hidden="true"></i> + {__.saveIdentity} + </button> </div> - </div> - - <div class="actions-right"> - <button type="button" - class="c-button c-button--gost-info" - if={!user.emailIsValidate} - onclick={resendValidation}> - <i class="fa fa-paper-plane" aria-hidden="true"></i> - {__.resendValidation} - </button> - <button type="submit" - class="c-button c-button--info"> - <i class="fa fa-check" aria-hidden="true"></i> - {__.saveIdentity} - </button> - </div> - </form> - <hr> - <form ref="password-form" class="password-form"> - <HumanInput onsubmit={submitPassword}/> - <h3 class="c-heading"><i class="fa fa-key"/> {__.passwordChange}</h3> - <div class="o-form-element"> - <label class="c-label" for="oldPassword">{__.oldPassword}</label> - <input class="c-field {c-field--error : errors.oldPassword}" - type="password" - name="oldPassword" - ref="oldPassword" - placeholder="{__.oldPassword_placeholder}" - required> - <div if="{errors.oldPassword}" - class="c-hint--static c-hint--error"> - {errors.oldPassword} + </form> + + <form ref="password-form" class="password-form"> + <HumanInput onsubmit={submitPassword}/> + <h3 class="c-heading"><i class="fa fa-key"/> {__.passwordChange}</h3> + <div class="o-form-element"> + <label class="c-label" for="oldPassword">{__.oldPassword}</label> + <input class="c-field {c-field--error : errors.oldPassword}" + type="password" + name="oldPassword" + ref="oldPassword" + placeholder="{__.oldPassword_placeholder}" + required> + <div if="{errors.oldPassword}" + class="c-hint--static c-hint--error"> + {errors.oldPassword} + </div> </div> - </div> - - <div class="o-form-element"> - <label class="c-label" for="newPassword">{__.newPassword}</label> - <input class="c-field {c-field--error : errors.newPassword}" - type="password" - name="newPassword" - ref="newPassword" - placeholder="{__.newPassword_placeholder}" - onblur="{checkNewPassword}" - required> - <div if="{errors.newPassword}" - class="c-hint--static c-hint--error"> - {errors.newPassword} + + <div class="o-form-element"> + <label class="c-label" for="newPassword">{__.newPassword}</label> + <input class="c-field {c-field--error : errors.newPassword}" + type="password" + name="newPassword" + ref="newPassword" + placeholder="{__.newPassword_placeholder}" + onblur="{checkNewPassword}" + required> + <div if="{errors.newPassword}" + class="c-hint--static c-hint--error"> + {errors.newPassword} + </div> </div> - </div> - - <div class="o-form-element"> - <label class="c-label" for="email">{__.repeatPassword}</label> - <input class="c-field {c-field--error : errors.repeatPassword}" - type="password" - name="repeatPassword" - ref="repeatPassword" - placeholder="{__.repeatPassword_placeholder}" - onblur="{checkPassword}" - onkeypress="{clearPasswordError}" - required> - <div if="{errors.repeatPassword}" - class="c-hint--static c-hint--error"> - {errors.repeatPassword} + + <div class="o-form-element"> + <label class="c-label" for="email">{__.repeatPassword}</label> + <input class="c-field {c-field--error : errors.repeatPassword}" + type="password" + name="repeatPassword" + ref="repeatPassword" + placeholder="{__.repeatPassword_placeholder}" + onblur="{checkPassword}" + onkeypress="{clearPasswordError}" + required> + <div if="{errors.repeatPassword}" + class="c-hint--static c-hint--error"> + {errors.repeatPassword} + </div> + </div> + + <div class="actions-right"> + <button type="submit" + class="c-button c-button--info"> + <i class="fa fa-check" aria-hidden="true"></i> + {__.savePassword} + </button> </div> - </div> - - <div class="actions-right"> - <button type="submit" - class="c-button c-button--info"> - <i class="fa fa-check" aria-hidden="true"></i> - {__.savePassword} - </button> - </div> - </form> + </form> + </div> </div> <script type="es6"> @@ -182,28 +185,17 @@ require("./components/HumanInput.tag.html"); </script> <style> - h1.c-heading { - text-align: center; - } - - @media (min-width: 640px) { - .o-form-element .c-label:first-child { - width: 25%; - display: inline-block; - text-align: right; - float: left; - padding-top: 0.5em; - padding-right: 5px; - } - .o-form-element .c-field { - width: 75%; - display: inline-block; - } + .main-content { + display: flex; + flex-wrap: wrap; + justify-content: space-around; + } - .o-form-element .c-hint--static { - margin-left: 25%; - } + .main-content > form { + flex-grow: 1; + max-width: 500px; + padding: 0 5px; } </style> diff --git a/pollen-ui-riot-js/src/main/web/tag/components/ContextualMenu.tag.html b/pollen-ui-riot-js/src/main/web/tag/components/ContextualMenu.tag.html index e6458f6f..63f27cab 100644 --- a/pollen-ui-riot-js/src/main/web/tag/components/ContextualMenu.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/components/ContextualMenu.tag.html @@ -13,7 +13,7 @@ display: block; border-radius: 1.5em; overflow: hidden; - background-color: var(--success); + background-color: var(--main); color:var(--background); } @@ -33,7 +33,7 @@ .links { max-width: 0; max-height: 0; - transition: max-width 1s, max-height 1s; + transition: max-width 0.75s, max-height 0.75s; } @@ -53,7 +53,7 @@ } .links a:hover { - background-color: var(--success-hover) + background-color: var(--main-hover) } @media (max-width: 640px) { diff --git a/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteList.tag.html b/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteList.tag.html index 9602c7ef..7677196c 100644 --- a/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteList.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteList.tag.html @@ -20,23 +20,22 @@ require("../components/LoadingCard.tag.html"); <li class="c-breadcrumbs__crumb c-text--loud">{favoriteList.name}</li> </ol> - <h1 class="c-heading">{favoriteList.name} - <div class="c-heading__sub"> - <span if={favoriteList.countChildren > 0}> - {favoriteList.countChildren} {favoriteList.countChildren > 1 ? __.children : __.child} - </span> - <span if={favoriteList.countChildren === 0 && favoriteList.countMembers == 0}> - {__.noMember} - </span> - <span if={favoriteList.countMembers > 0}> - {favoriteList.countMembers} {favoriteList.countMembers > 1 ? __.members : __.member} - </span> - </div> - </h1> + <h1>{favoriteList.name}</h1> + + <div class="c-alert c-alert--info"> + <span if={favoriteList.countChildren > 0}> + {favoriteList.countChildren} {favoriteList.countChildren > 1 ? __.children : __.child} + </span> + <span if={favoriteList.countChildren === 0 && favoriteList.countMembers == 0}> + {__.noMember} + </span> + <span if={favoriteList.countMembers > 0}> + {favoriteList.countMembers} {favoriteList.countMembers > 1 ? __.members : __.member} + </span> + </div> <Search onsearch={refresh} search={search}/> - <LazyLoad pagination={pagination} onload={lazyLoad} load-size="20" ref="lazyLoad" class="elements"> <yield to="element"> <ChildListCard if={element.child} child-list={element} favorite-list={parent.parent.favoriteList} on-child-list-change={parent.parent.refresh}/> @@ -145,11 +144,6 @@ require("../components/LoadingCard.tag.html"); <style> - .c-heading, - .c-heading .c-heading__sub { - text-align: center; - } - .elements { display: flex; flex-wrap: wrap; diff --git a/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteLists.tag.html b/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteLists.tag.html index c261e97c..c1216a51 100644 --- a/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteLists.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteLists.tag.html @@ -13,8 +13,10 @@ require("./FavoriteListEditModal.tag.html"); </ol> <div show="{loaded}"> - <h1 class="c-heading">{__.title} - <div class="c-heading__sub"> + <h1>{__.title}</h1> + + <div class="main-content"> + <div class="c-alert c-alert--info"> {count === 0 ? __.noFavoriteList : (count + " " + (count === 1 ? __.one : __.many))} <a class="c-button c-button--info" if={pagination.count > 0} @@ -24,29 +26,29 @@ require("./FavoriteListEditModal.tag.html"); <i class="fa fa-download"></i> </a> </div> - </h1> - - <Search onsearch={refresh} search={search}/> - - <LazyLoad pagination={pagination} onload={lazyLoad} load-size="20" ref="lazyLoad" class="elements"> - <yield to="element"> - <FavoriteListCard favorite-list={element} on-favorite-list-change={parent.parent.refresh}/> - </yield> - <yield to="loading"> - <LoadingCard loading={nbNextGroup}> - {parent.parent._l("loading", nbNext)} - </LoadingCard> - </yield> - </LazyLoad> - - <ContextualMenu> - <a onclick={parent.addFavoriteList}> - {parent.__.addFavoriteList} - </a> - <a onclick={parent.openImportModal} > - {parent.__.importFavoriteLists} - </a> - </ContextualMenu> + + <Search onsearch="{refresh}" search="{search}" /> + + <LazyLoad pagination={pagination} onload={lazyLoad} load-size="20" ref="lazyLoad" class="elements"> + <yield to="element"> + <FavoriteListCard favorite-list={element} on-favorite-list-change={parent.parent.refresh}/> + </yield> + <yield to="loading"> + <LoadingCard loading={nbNextGroup}> + {parent.parent._l("loading", nbNext)} + </LoadingCard> + </yield> + </LazyLoad> + + <ContextualMenu> + <a onclick={parent.addFavoriteList}> + {parent.__.addFavoriteList} + </a> + <a onclick={parent.openImportModal} > + {parent.__.importFavoriteLists} + </a> + </ContextualMenu> + </div> <Modal ref="importModal" onsubmit={import} header={__.importFavoriteLists} label={__.import} type="success"> <div class="o-form-element"> @@ -127,14 +129,8 @@ require("./FavoriteListEditModal.tag.html"); </script> <style> - .c-heading, - .c-heading .c-heading__sub { - text-align: center; - } - - .c-heading .c-heading__sub .c-button { - opacity: inherit; - font-size: 1rem; + .main-content { + padding: 20px; } .exemple { 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 9cb22265..4790c1e2 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 @@ -2,9 +2,10 @@ require("../Pagination.tag.html"); require("./PollCard.tag.html"); require("../components/HumanInput.tag.html"); <Polls> - <div class="container" > - <div show="{loaded}"> - <h1>{__[opts.method]}</h1> + <div class="container" show="{loaded}"> + <h1>{__[opts.method]}</h1> + + <div class="main-content"> <div show={polls.length > 0} > <div class="o-form-element sort"> @@ -65,9 +66,6 @@ require("../components/HumanInput.tag.html"); </div> </div> -</Polls> - -<style> <script type="es6"> this.loaded = false; let session = require("../../js/Session"); @@ -126,12 +124,11 @@ require("../components/HumanInput.tag.html"); } }); }; - </script> - <style> - .c-heading { - text-align: center; + <style> + .main-content { + padding: 20px 20px 40px 20px; } .o-form-element.sort .c-label:first-child { @@ -146,6 +143,5 @@ require("../components/HumanInput.tag.html"); .o-form-element.sort .c-input-group { width: 200px; } - </style> </Polls> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html index 87409d0c..51bd3f8c 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html @@ -3,205 +3,205 @@ require("./ChoiceView.tag.html"); require("./Podium.tag.html"); require("../components/HumanInput.tag.html"); <Votes> - <div class="container"> - <div show="{loaded}"> - <div class="voters"> - <form ref="formAddVote" class="fix"> - <HumanInput onsubmit="{addVote}"/> - <div class="current-voter"> - <div class="o-field o-field--icon-left o-field--icon-right" - if={poll.canVote} > - <i class="fa fa-fw fa-user c-icon"></i> - <input class="c-field {c-field--error: !voteId && error && error['voter.name']}" - type="text" - ref="voterName" - name="voterName" - required={!voteId} - disabled={voteId} - placeholder={__.authorPlaceHolder} - value={poll.voterName}> - </div> - <div if={!poll.canVote} - class="choices-label"> - {__.choices} - </div> - </div> - <div each={choice in poll.choices} class="choice separator-top"> - <div class="choice-value"> - <ChoiceView choice={choice} center="true"/> - </div> - <div class="current-choice" - if={poll.canVote}> - <input if={poll.voteCountingTypeValue && poll.voteCountingTypeValue.renderType==='checkbox'} - class="check" - type="checkbox" - onchange="{onVoteChanged}" - ref="{choice.id}_voteValue" - disabled={voteId}> - <input if={poll.voteCountingTypeValue && poll.voteCountingTypeValue.renderType==='text'} - class="text c-field {c-field--error: !voteId && error && (error['vote.voteValue#' + choice.id] || error['vote.totalVoteValue'])}" - type="number" - min="{poll.voteCountingTypeValue.minimumValue}" - max="{poll.voteCountingTypeValue.maximumValue}" - onchange="{onVoteChanged}" - ref="{choice.id}_voteValue" - disabled={voteId}> - </div> + <div class="container" show="{loaded}"> + <div class="voters"> + <form ref="formAddVote" class="fix separator-top separator-left separator-bottom"> + <HumanInput onsubmit="{addVote}"/> + <div class="current-voter"> + <div class="o-field o-field--icon-left o-field--icon-right" + if={poll.canVote} > + <i class="fa fa-fw fa-user c-icon"></i> + <input class="c-field {c-field--error: !voteId && error && error['voter.name']}" + type="text" + ref="voterName" + name="voterName" + required={!voteId} + disabled={voteId} + placeholder={__.authorPlaceHolder} + value={poll.voterName}> </div> - <div class="current-voter-actions separator-top"> - <button if={poll.canVote} - class="c-button c-button--brand pull-right" - type="submit" - name="newVote" - disabled={voteId || tooManyChoicesSelected}> - {__.toVote} - </button> + <div if={!poll.canVote} + class="choices-label"> + {__.choices} </div> - <div class="c-hint--static c-hint--error" if="{!voteId && tooManyChoicesSelected}"> - {__.tooManyChoicesSelected} {poll.maxChoiceNumber} + </div> + <div each={choice in poll.choices} class="choice separator-top"> + <div class="choice-value"> + <ChoiceView choice={choice} center="true"/> </div> - <div class="c-hint--static c-hint--error" if="{!voteId && error}"> - <div each={fields in error}> - {fields} - </div> + <div class="current-choice" + if={poll.canVote}> + <input if={poll.voteCountingTypeValue && poll.voteCountingTypeValue.renderType==='checkbox'} + class="check" + type="checkbox" + onchange="{onVoteChanged}" + ref="{choice.id}_voteValue" + disabled={voteId}> + <input if={poll.voteCountingTypeValue && poll.voteCountingTypeValue.renderType==='text'} + class="text c-field {c-field--error: !voteId && error && (error['vote.voteValue#' + choice.id] || error['vote.totalVoteValue'])}" + type="number" + min="{poll.voteCountingTypeValue.minimumValue}" + max="{poll.voteCountingTypeValue.maximumValue}" + onchange="{onVoteChanged}" + ref="{choice.id}_voteValue" + disabled={voteId}> </div> + </div> + <div class="current-voter-actions separator-top"> + <button if={poll.canVote} + class="c-button c-button--brand pull-right" + type="submit" + name="newVote" + disabled={voteId || tooManyChoicesSelected}> + <i class="fa fa-envelope"></i> + {__.toVote} + </button> + </div> + <div class="c-hint--static c-hint--error" if="{!voteId && tooManyChoicesSelected}"> + {__.tooManyChoicesSelected} {poll.maxChoiceNumber} + </div> + <div class="c-hint--static c-hint--error" if="{!voteId && error}"> + <div each={fields in error}> + {fields} + </div> + </div> + </form> - </form> - <div class="window"> - <div class="frame"> - <div if={poll.resultIsVisible} class="results separator-left"> - <div class="result-label"> - {__.results} - </div> - <div each={choice in poll.choices} class="score-choice separator-top"> - <span if={!choice.score}>{parent.__.noVote}</span> - <span if={choice.score}> - <i if={choice.score.scoreOrder === 0} class="fa fa-trophy fa-15x winner"></i> - {choice.score.scoreValue} - {parent.__["results_unit_" + poll.voteCountingType + "_" + (choice.score.scoreValue > 1 ? "many" : "one")]} - </span> - </div> - <div class="results-actions separator-top"> + <div class="window separator-top separator-left separator-bottom separator-right"> + <div class="frame"> + <div if={poll.resultIsVisible} class="results"> + <div class="result-label"> + {__.results} + </div> + <div each={choice in poll.choices} class="score-choice separator-top"> + <span if={!choice.score}>{parent.__.noVote}</span> + <span if={choice.score}> + <i if={choice.score.scoreOrder === 0} class="fa fa-trophy fa-15x winner"></i> + {choice.score.scoreValue} + {parent.__["results_unit_" + poll.voteCountingType + "_" + (choice.score.scoreValue > 1 ? "many" : "one")]} + </span> + </div> + <div class="results-actions separator-top"> - </div> </div> - <button type="button" - if={poll.votes && poll.votes.length && !showVotes} - class="expand c-button c-button--info" - onclick="{onShowVotes}"> - <i class="fa fa-caret-right"/> - </button> - <button type="button" - if={poll.votes && poll.votes.length && showVotes} - class="collapse c-button c-button--info" - onclick="{onHideVotes}"> - <i class="fa fa-caret-left"/> - </button> - <form if={showVotes} each={vote, index in poll.votes} class="vote {separator-right : index < (poll.votes.length -1)}"> - <HumanInput onsubmit="{updateVote(vote)}"/> - <div class="voter"> - <span class="voter-name" - if="{vote.id !== voteId}"> - <i class="fa fa-user"/> - <span if="{!vote.anonymous}">{vote.voterName}</span> - <span if="{vote.anonymous}" class="anonymous-voter">{parent.__.anonymousVoter}</span> - </span> - <div class="o-field o-field--icon-left" - if={vote.id === voteId}> - <i class="fa fa-fw fa-user c-icon"></i> - <input ref="vote_{vote.id}_voter" - name="vote_{vote.id}_voter" - type="text" - class="c-field {c-field--error: error && error['voter.name']}" - value="{vote.voterName}" - required={vote.id === voteId} - disabled={vote.id !== voteId} - placeholder="{__.authorPlaceHolder}"> - </div> - </div> - <div each={choice in poll.choices} class="vote-choice separator-top" > - <input if={poll.voteCountingTypeValue && poll.voteCountingTypeValue.renderType==='checkbox' && (poll.getVoteChoice(vote, choice) || voteId === vote.id)} - ref="vote_{vote.id}_{choice.id}" - name="vote_{vote.id}_{choice.id}" - class="check {c-field--error: vote.id === voteId && error && error['vote.voteValue#' + choice.id]}" - type="checkbox" - checked={poll.getVoteValue(vote, choice) == 1} - disabled={voteId !== vote.id}> - <input if={poll.voteCountingTypeValue.renderType === 'text' && (poll.getVoteChoice(vote, choice) || voteId === vote.id)} - ref="vote_{vote.id}_{choice.id}" - class="text c-field {c-field--error: vote.id === voteId && error && error['vote.voteValue#' + choice.id]}" - name="vote_{vote.id}_{choice.id}" - type="number" - min="{poll.voteCountingTypeValue.minimumValue}" - max="{poll.voteCountingTypeValue.maximumValue}" - required={vote.id === voteId} - disabled={voteId !== vote.id} - value={poll.getVoteValue(vote, choice)}> - </div> - <div class="vote-actions separator-top"> - <span class="c-input-group"> - <button type="button" - class="c-button c-button--error" - if="{(poll.permission || !poll.isClosed && vote.permission) && (!voteId || voteId != vote.id)}" - onclick="{parent.deleteVote(vote)}"> - <i class="fa fa-trash"/> - </button> - <button type="button" - class="c-button c-button--brand" - if="{!poll.isClosed && vote.permission && (!voteId || voteId != vote.id)}" - onclick="{parent.onEditVote(vote)}"> - <i class="fa fa-pencil-square-o"/> - </button> - </span> - <span class="c-input-group" - if={vote.id === voteId}> - <button class="c-button c-button--error" - type="button" - onclick="{cancelEditVote(vote)}"> - <i class="fa fa-remove"/> - </button> - <button class="c-button c-button--success" - ref="vote_{vote.id}_vote" - type="submit"> - <i class="fa fa-check"/> - </button> - </span> - </div> - <div class="c-hint--static c-hint--error" if="{vote.id === voteId && tooManyChoicesSelected}"> - {__.tooManyChoicesSelected} {poll.maxChoiceNumber} - </div> - <div class="c-hint--static c-hint--error" if="{vote.id === voteId && error}"> - <div each={fields in error}> - {fields} - </div> - </div> - </form> </div> + <button type="button" + if={poll.votes && poll.votes.length && !showVotes} + class="expand c-button c-button--info" + onclick="{onShowVotes}"> + <i class="fa fa-caret-right"/> + </button> + <button type="button" + if={poll.votes && poll.votes.length && showVotes} + class="collapse c-button c-button--info" + onclick="{onHideVotes}"> + <i class="fa fa-caret-left"/> + </button> + + <form if={showVotes} each={vote, index in poll.votes} class="vote separator-right"> + <HumanInput onsubmit="{updateVote(vote)}"/> + <div class="voter"> + <span class="voter-name" + if="{vote.id !== voteId}"> + <i class="fa fa-user"/> + <span if="{!vote.anonymous}">{vote.voterName}</span> + <span if="{vote.anonymous}" class="anonymous-voter">{parent.__.anonymousVoter}</span> + </span> + <div class="o-field o-field--icon-left" + if={vote.id === voteId}> + <i class="fa fa-fw fa-user c-icon"></i> + <input ref="vote_{vote.id}_voter" + name="vote_{vote.id}_voter" + type="text" + class="c-field {c-field--error: error && error['voter.name']}" + value="{vote.voterName}" + required={vote.id === voteId} + disabled={vote.id !== voteId} + placeholder="{__.authorPlaceHolder}"> + </div> + </div> + <div each={choice in poll.choices} class="vote-choice separator-top" > + <input if={poll.voteCountingTypeValue && poll.voteCountingTypeValue.renderType==='checkbox' && (poll.getVoteChoice(vote, choice) || voteId === vote.id)} + ref="vote_{vote.id}_{choice.id}" + name="vote_{vote.id}_{choice.id}" + class="check {c-field--error: vote.id === voteId && error && error['vote.voteValue#' + choice.id]}" + type="checkbox" + checked={poll.getVoteValue(vote, choice) == 1} + disabled={voteId !== vote.id}> + <input if={poll.voteCountingTypeValue.renderType === 'text' && (poll.getVoteChoice(vote, choice) || voteId === vote.id)} + ref="vote_{vote.id}_{choice.id}" + class="text c-field {c-field--error: vote.id === voteId && error && error['vote.voteValue#' + choice.id]}" + name="vote_{vote.id}_{choice.id}" + type="number" + min="{poll.voteCountingTypeValue.minimumValue}" + max="{poll.voteCountingTypeValue.maximumValue}" + required={vote.id === voteId} + disabled={voteId !== vote.id} + value={poll.getVoteValue(vote, choice)}> + </div> + <div class="vote-actions separator-top"> + <span class="c-input-group"> + <button type="button" + class="c-button c-button--error" + if="{(poll.permission || !poll.isClosed && vote.permission) && (!voteId || voteId != vote.id)}" + onclick="{parent.deleteVote(vote)}"> + <i class="fa fa-trash"/> + </button> + <button type="button" + class="c-button c-button--brand" + if="{!poll.isClosed && vote.permission && (!voteId || voteId != vote.id)}" + onclick="{parent.onEditVote(vote)}"> + <i class="fa fa-pencil-square-o"/> + </button> + </span> + <span class="c-input-group" + if={vote.id === voteId}> + <button class="c-button c-button--error" + type="button" + onclick="{cancelEditVote(vote)}"> + <i class="fa fa-remove"/> + </button> + <button class="c-button c-button--success" + ref="vote_{vote.id}_vote" + type="submit"> + <i class="fa fa-check"/> + </button> + </span> + </div> + <div class="c-hint--static c-hint--error" if="{vote.id === voteId && tooManyChoicesSelected}"> + {__.tooManyChoicesSelected} {poll.maxChoiceNumber} + </div> + <div class="c-hint--static c-hint--error" if="{vote.id === voteId && error}"> + <div each={fields in error}> + {fields} + </div> + </div> + </form> </div> </div> + </div> - <form ref="formAddChoice" - if={poll.status === "ADDING_CHOICES"}> - <HumanInput onsubmit="{addChoice}"/> - <div class="o-form-element"> - <label class="c-label" for="choice">{__.addChoice}</label> - <div class="c-input-group"> - <div class="o-field"> - <Choice ref="choice" - class="choice c-field" - name="choice" - choice="{choiceToAdd}"/> - </div> - <button type="submit" - class="c-button c-button--success" - tooltips="{__.addChoice}"> - <i class="fa fa-plus"/> - </button> - </div> + <form ref="formAddChoice" + if={poll.status === "ADDING_CHOICES"}> + <HumanInput onsubmit="{addChoice}"/> + <div class="o-form-element"> + <label class="c-label" for="choice">{__.addChoice}</label> + <div class="c-input-group"> + <div class="o-field"> + <Choice ref="choice" + class="choice c-field" + name="choice" + choice="{choiceToAdd}"/> + </div> + <button type="submit" + class="c-button c-button--success" + tooltips="{__.addChoice}"> + <i class="fa fa-plus"/> + </button> </div> + </div> - </form> - </div> + </form> </div> <script type="es6"> -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
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 2ac90b4c3472ce580d9ba5f7a3b8c7bc12060b81 Author: Kevin Morin <morin@codelutin.com> Date: Thu Jul 6 17:06:58 2017 +0200 refs #61 Export des resultat d'un sondage (version imprimable de la page des résultats) --- pollen-ui-riot-js/src/main/web/css/print.css | 31 ++++++++++++++++++++++ pollen-ui-riot-js/src/main/web/i18n.json | 17 +++++++----- pollen-ui-riot-js/src/main/web/index.html | 9 ++++--- .../src/main/web/tag/poll/Comments.tag.html | 2 +- .../src/main/web/tag/poll/Poll.tag.html | 19 ++++++++----- .../src/main/web/tag/poll/Report.tag.html | 2 +- 6 files changed, 62 insertions(+), 18 deletions(-) diff --git a/pollen-ui-riot-js/src/main/web/css/print.css b/pollen-ui-riot-js/src/main/web/css/print.css new file mode 100644 index 00000000..52dce3d1 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/css/print.css @@ -0,0 +1,31 @@ +.not-printable { + display: none!important; +} + +pollenheader { + background-color: transparent; +} + +pollenheader .header-actions { + display: none!important; +} + +h1, .tabs { + background-color: transparent!important; +} + +/* print only the selected tab */ +.tabs .tab, .tabs .dropdown { + display: none!important; +} + +.tabs .tab.selected { + display: block!important; + border: none; + background-color: transparent; + font-size: 2em; +} + +pollenfooter { + display: none!important; +} \ 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 80581654..9e929a37 100644 --- a/pollen-ui-riot-js/src/main/web/i18n.json +++ b/pollen-ui-riot-js/src/main/web/i18n.json @@ -39,11 +39,10 @@ "poll_editPoll": "Modifier le sondage", "poll_creationSuccess": "Votre sondage {0} a été créé avec succès.", "poll_saveSuccess": "Votre sondage {0} a été enregistré avec succès.", - "poll_votes": "Votes", + "poll_tab_votes": "Votes", "poll_summaryTab": "Résumé", "poll_settings": "Configuration", - "poll_choices": "Choix", - "poll_results": "Résultats", + "poll_tab_results": "Résultats", "poll_CLOSED": "Fermé", "poll_ADDING_CHOICES": "Ajout de choix", "poll_VOTING": "Ouvert", @@ -53,6 +52,7 @@ "poll_dateVotes": "Période de vote", "poll_dateAddChoices": "Période d'ajout de choix", "poll_dateFrom": "Du", + "poll_dateFromNoEnd": "À partir du", "poll_dateTo": "Au", "poll_noChoice": "aucun choix", "poll_choice": "choix", @@ -67,6 +67,9 @@ "poll_urlForAdmin" : "Administrer ce sondage avec cette adresse", "poll_urlForVote" : "Inviter de nouveaux participants en leur envoyant cette adresse", "poll_urlForEditVote" : "Vote enregistré, vous pourrez le modifier à l'adresse suivante (lorsque vous n'êtes pas connecté) : ", + "poll_qrcode": "Afficher un QR code pour partager le sondage", + "poll_rss": "Vous abonner au flux du sondage", + "poll_print": "Imprimer la page", "poll_results_title": "Résultats", "poll_results_noResult": "Les résultats ne sont pas encore disponibles.", "poll_results_ranks": "Rangs", @@ -541,8 +544,7 @@ "summary_members": "Participants", "summary_membersNb": "participants received an email with a link to vote.", "poll_403": "Error : the poll is not available", - "poll_choices": "Choices", - "poll_votes": "Votes", + "poll_tab_votes": "Votes", "poll_summaryTab": "Summary", "poll_settings": "Settings", "poll_closePoll": "Close poll", @@ -550,7 +552,7 @@ "poll_clonePoll": "Clone poll", "poll_deletePoll": "Delete poll", "poll_editPoll": "Edit poll", - "poll_results": "Results", + "poll_tab_results": "Results", "poll_CLOSED": "Closed", "poll_ADDING_CHOICES": "Adding choices", "poll_VOTING": "Voting", @@ -574,6 +576,9 @@ "poll_urlForAdmin" : "Administrate poll with this address", "poll_urlForVote" : "Invited new participants with this address", "poll_urlForEditVote" : "Vote saved, you can modify it using this address when you are not connected: ", + "poll_qrcode": "Show a QR code to share the poll", + "poll_rss": "Subscribe to the poll stream", + "poll_print": "Print the page", "poll_results_noResult": "Results are not yet available.", "poll_results_title": "Results", "poll_results_ranks": "Ranks", diff --git a/pollen-ui-riot-js/src/main/web/index.html b/pollen-ui-riot-js/src/main/web/index.html index 5d8f1ed7..d96d4ae7 100644 --- a/pollen-ui-riot-js/src/main/web/index.html +++ b/pollen-ui-riot-js/src/main/web/index.html @@ -25,10 +25,11 @@ <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Pollen</title> - <link href="./css/font-awesome.css" rel="stylesheet"> - <link href="./css/custom.css" rel="stylesheet"> - <link href="./css/blaze.css" rel="stylesheet"> - <link href="./css/main.css" rel="stylesheet"> + <link href="./css/font-awesome.css" rel="stylesheet" type="text/css"/> + <link href="./css/custom.css" rel="stylesheet" type="text/css"/> + <link href="./css/blaze.css" rel="stylesheet" type="text/css"/> + <link href="./css/main.css" rel="stylesheet" type="text/css"/> + <link href="./css/print.css" rel="stylesheet" type="text/css" media="print"/> </head> <body> <Pollen/> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Comments.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Comments.tag.html index 85169071..dbe2bb68 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Comments.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Comments.tag.html @@ -179,7 +179,7 @@ require("./Report.tag.html"); </div> <button type="button" - class="c-button c-button--info open-btn {open : open}" + class="c-button c-button--info open-btn not-printable {open : open}" onclick="{openComments}"> <i class="fa fa-comment"/> {poll.commentCount} {poll.commentCount <= 1 ? __.one : __.many} </button> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html index 64eed951..3e648b3f 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html @@ -11,10 +11,17 @@ require("./Report.tag.html"); <h1 class="no-border"> <span class="title">{poll.title}</span> - <QrCodeButton if="{poll.pollType === 'FREE'}" value="{window.location.origin}{window.location.pathname}#poll/{poll.id}/vote"/> - <a href="{session.configuration.endPoint}/v1/polls/{poll.id}/feed?permission={poll.permission}" class="c-button c-button--info"> + <QrCodeButton if="{poll.pollType === 'FREE'}" class="not-printable" + value="{window.location.origin}{window.location.pathname}#poll/{poll.id}/vote" + title="{__.qrcode}"/> + <a href="{session.configuration.endPoint}/v1/polls/{poll.id}/feed?permission={poll.permission}" + class="c-button c-button--info not-printable" + title="{__.rss}"> <i class="fa fa-rss" aria-hidden="true"></i> </a> + <a class="c-button c-button--info not-printable" href="javascript:window.print()" title="{__.print}"> + <i class="fa fa-print" aria-hidden="true"></i> + </a> <Report target={poll}/> </h1> @@ -22,12 +29,12 @@ require("./Report.tag.html"); <div class="tab-container"> <div class="tab {selected : selectedTab === 'votes'}"> <a href="#poll/{poll.id}/vote{poll.getPermission()?'/' + poll.getPermission() : ''}"> - <i class="fa fa-thumbs-o-up fa-flip-horizontal fa-15x"></i> {__.votes} ({poll.voteCount}) + <i class="fa fa-thumbs-o-up fa-flip-horizontal fa-15x"></i> {__.tab_votes} ({poll.voteCount}) </a> </div> <div class="tab {selected : selectedTab === 'results'}"> <a href="#poll/{poll.id}/result{poll.getPermission()?'/' + poll.getPermission() : ''}"> - <i class="fa fa-trophy fa-15x"></i> {__.results} + <i class="fa fa-trophy fa-15x"></i> {__.tab_results} </a> </div> </div> @@ -64,14 +71,14 @@ require("./Report.tag.html"); <div class="left-icon"> <i class="fa fa-clock-o"></i> <p>{__.dateVotes}</p> - <p>{__.dateFrom} <span class="brand">{formatDate(poll.beginDate)}</span></p> + <p>{poll.endDate ? __.dateFrom : __.dateFromNoEnd} <span class="brand">{formatDate(poll.beginDate)}</span></p> <p if={poll.endDate}> {__.dateTo} <span class="brand">{formatDate(poll.endDate)}</span></p> </div> <div class="left-icon" if={poll.choiceAddAllowed}> <i class="fa fa-check-square"></i> <p>{__.dateAddChoices}</p> - <p>{__.dateFrom} <span class="brand">{formatDate(poll.beginChoiceDate)}</span></p> + <p>{poll.endDate ? __.dateFrom : __.dateFromNoEnd} <span class="brand">{formatDate(poll.beginChoiceDate)}</span></p> <p if={poll.endDate}> {__.dateTo} <span class="brand">{formatDate(poll.endChoiceDate)}</span></p> </div> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Report.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Report.tag.html index b3cc2ef7..40d237df 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Report.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Report.tag.html @@ -1,7 +1,7 @@ require("../popup/Modal.tag.html"); <Report> - <span class="label info-label" + <span class="label info-label not-printable" show={!poll.permission} onclick={openModalAddReport} title={__.title}> <i class="fa fa-bell" aria-hidden="true"></i> -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm