branch feature/pollen-riot-js updated (e34256d -> 29ccbc0)
This is an automated email from the git hooks/post-receive script. New change to branch feature/pollen-riot-js in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git from e34256d fix node build new d960be5 Début de documentation de l'api REST new 29ccbc0 Mise en place des commentaires sur sondage + continue page de vote The 2 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit 29ccbc0591b65ad75a550aeacf966dced96e0264 Author: Tony CHEMIT <dev@tchemit.fr> Date: Mon Jan 23 16:15:32 2017 +0100 Mise en place des commentaires sur sondage + continue page de vote commit d960be52ef806a295fbafd6abf91cfbbdfeb86ca Author: Tony CHEMIT <dev@tchemit.fr> Date: Fri Jan 20 09:06:57 2017 +0100 Début de documentation de l'api REST Summary of changes: pollen-rest-api/pom.xml | 2 + .../chorem/pollen/rest/api/v1/PollenUserApi.java | 3 + pollen-rest-api/src/site/markdown/auth.md | 53 ++++++ pollen-rest-api/src/site/markdown/index.md | 5 + pollen-rest-api/src/site/markdown/poll.md | 13 ++ .../src/site/site_en.xml | 29 ++- pollen-ui-riot-js/src/main/web/i18n.json | 18 ++ .../src/main/web/js/CommentService.js | 55 ++++++ pollen-ui-riot-js/src/main/web/js/FetchService.js | 20 +++ pollen-ui-riot-js/src/main/web/js/Pagination.js | 12 ++ pollen-ui-riot-js/src/main/web/js/PollService.js | 7 + pollen-ui-riot-js/src/main/web/tag/Header.tag | 7 +- pollen-ui-riot-js/src/main/web/tag/Pagination.tag | 130 ++++++++++++++ pollen-ui-riot-js/src/main/web/tag/Pollen.tag | 70 +++++--- pollen-ui-riot-js/src/main/web/tag/SignIn.tag | 5 +- .../NewPassword.tag => poll/CommentPopup.tag} | 107 ++++++------ pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag | 112 ++++++++++++ .../src/main/web/tag/poll/PollComments.tag | 194 +++++++++++++++++++++ .../src/main/web/tag/poll/PollSettings.tag | 9 +- .../src/main/web/tag/poll/PollVotes.tag | 5 + .../src/main/web/tag/polls/CreatedPolls.tag | 137 +++++++++++++++ 21 files changed, 905 insertions(+), 88 deletions(-) create mode 100644 pollen-rest-api/src/site/markdown/auth.md create mode 100644 pollen-rest-api/src/site/markdown/index.md create mode 100644 pollen-rest-api/src/site/markdown/poll.md copy pollen-ui-riot-js/src/main/webapp/WEB-INF/web.xml => pollen-rest-api/src/site/site_en.xml (59%) create mode 100644 pollen-ui-riot-js/src/main/web/js/CommentService.js create mode 100644 pollen-ui-riot-js/src/main/web/js/Pagination.js create mode 100644 pollen-ui-riot-js/src/main/web/tag/Pagination.tag copy pollen-ui-riot-js/src/main/web/tag/{popup/NewPassword.tag => poll/CommentPopup.tag} (58%) create mode 100644 pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag create mode 100644 pollen-ui-riot-js/src/main/web/tag/poll/PollComments.tag create mode 100644 pollen-ui-riot-js/src/main/web/tag/poll/PollVotes.tag create mode 100644 pollen-ui-riot-js/src/main/web/tag/polls/CreatedPolls.tag -- 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 feature/pollen-riot-js in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit d960be52ef806a295fbafd6abf91cfbbdfeb86ca Author: Tony CHEMIT <dev@tchemit.fr> Date: Fri Jan 20 09:06:57 2017 +0100 Début de documentation de l'api REST --- pollen-rest-api/pom.xml | 2 ++ pollen-rest-api/src/site/markdown/auth.md | 53 ++++++++++++++++++++++++++++++ pollen-rest-api/src/site/markdown/index.md | 5 +++ pollen-rest-api/src/site/markdown/poll.md | 13 ++++++++ pollen-rest-api/src/site/site_en.xml | 44 +++++++++++++++++++++++++ 5 files changed, 117 insertions(+) diff --git a/pollen-rest-api/pom.xml b/pollen-rest-api/pom.xml index de336ad..d5ab2fa 100644 --- a/pollen-rest-api/pom.xml +++ b/pollen-rest-api/pom.xml @@ -51,6 +51,8 @@ ${project.build.directory}/${project.build.finalName}.war </redmine.releaseFiles> + <siteSourcesType>md</siteSourcesType> + <maven.deploy.skip>true</maven.deploy.skip> </properties> diff --git a/pollen-rest-api/src/site/markdown/auth.md b/pollen-rest-api/src/site/markdown/auth.md new file mode 100644 index 0000000..c7d1462 --- /dev/null +++ b/pollen-rest-api/src/site/markdown/auth.md @@ -0,0 +1,53 @@ +# Auth API + +## /v1/login + +Method **POST** or **PUT** + +Use basic authentication. + +This will send you back two cookies: ``pollen-auth`` and ``pollen-connected``. + +## /v1/login2 + +Method **POST** or **PUT** + +Use POST form with parameters: `` login, password `` + +This will send you back two cookies: ``pollen-auth`` and ``pollen-connected``. + +## /v1/logout + +Method **GET** + +No parameters. Will remove the two cookies ``pollen-auth`` and ``pollen-connected`` from you browser. + +## /v1/lostpassword/{email} + +Method **GET** + +Generates a new password and send it to user by email. + +## /v1/resendValidation/{email} + +Method **GET** + +Generates a new invitation and send it to user by email. + +## /v1/users + +Method **POST** + +Create the user given in ``user`` request parameter. + +## /v1/users/connected + +Method **GET** + +Return the connected user. + +## /v1/users/{userId}?{token} + +Method **GET** + +Validate user account. diff --git a/pollen-rest-api/src/site/markdown/index.md b/pollen-rest-api/src/site/markdown/index.md new file mode 100644 index 0000000..0b67bb2 --- /dev/null +++ b/pollen-rest-api/src/site/markdown/index.md @@ -0,0 +1,5 @@ +# Pollen Rest Api + +This module exposes a simple REST API to communicate with Pollen. + +You will find here how to make it real. diff --git a/pollen-rest-api/src/site/markdown/poll.md b/pollen-rest-api/src/site/markdown/poll.md new file mode 100644 index 0000000..9df6d89 --- /dev/null +++ b/pollen-rest-api/src/site/markdown/poll.md @@ -0,0 +1,13 @@ +# Poll API + +## /v1/polls + +Method **POST** or **PUT** + +Create a new poll. + +## /v1/polls/created + +Method **GET** + +Get polls created by connected user. \ No newline at end of file diff --git a/pollen-rest-api/src/site/site_en.xml b/pollen-rest-api/src/site/site_en.xml new file mode 100644 index 0000000..3286be0 --- /dev/null +++ b/pollen-rest-api/src/site/site_en.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + Pollen + %% + 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% + --> + +<project name="${project.name}" xmlns="http://maven.apache.org/DECORATION/1.3.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/DECORATION/1.3.0 http://maven.apache.org/xsd/decoration-1.3.0.xsd"> + + <body> + + <breadcrumbs> + <item name="${project.version}" href="./index.html"/> + </breadcrumbs> + + <menu name="User documentation"> + <item name="Home" href="./index.html"/> + <item name="Auth API" href="./auth.html"/> + <item name="Poll API" href="./poll.html"/> + </menu> + + <menu ref="reports"/> + + </body> + +</project> + -- 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 feature/pollen-riot-js in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 29ccbc0591b65ad75a550aeacf966dced96e0264 Author: Tony CHEMIT <dev@tchemit.fr> Date: Mon Jan 23 16:15:32 2017 +0100 Mise en place des commentaires sur sondage + continue page de vote --- .../chorem/pollen/rest/api/v1/PollenUserApi.java | 3 + pollen-ui-riot-js/src/main/web/i18n.json | 18 ++ .../src/main/web/js/CommentService.js | 55 ++++++ pollen-ui-riot-js/src/main/web/js/FetchService.js | 20 +++ pollen-ui-riot-js/src/main/web/js/Pagination.js | 12 ++ pollen-ui-riot-js/src/main/web/js/PollService.js | 7 + pollen-ui-riot-js/src/main/web/tag/Header.tag | 7 +- pollen-ui-riot-js/src/main/web/tag/Pagination.tag | 130 ++++++++++++++ pollen-ui-riot-js/src/main/web/tag/Pollen.tag | 70 +++++--- pollen-ui-riot-js/src/main/web/tag/SignIn.tag | 5 +- .../src/main/web/tag/poll/CommentPopup.tag | 191 ++++++++++++++++++++ pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag | 112 ++++++++++++ .../src/main/web/tag/poll/PollComments.tag | 194 +++++++++++++++++++++ .../src/main/web/tag/poll/PollSettings.tag | 9 +- .../src/main/web/tag/poll/PollVotes.tag | 5 + .../src/main/web/tag/polls/CreatedPolls.tag | 137 +++++++++++++++ 16 files changed, 945 insertions(+), 30 deletions(-) diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java index 3b1ac5d..86dbe9e 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java @@ -34,6 +34,8 @@ import org.chorem.pollen.services.service.security.PollenInvalidEmailActivationT import org.debux.webmotion.server.WebMotionController; import org.debux.webmotion.server.call.HttpContext; +import java.util.Objects; + /** * TODO * @@ -51,6 +53,7 @@ public class PollenUserApi extends WebMotionController { public PollenUserBean getConnectedUser(HttpContext context, PollenUserService pollenUserService) { PollenRestApiRequestContext pollenRestApiRequestContext = PollenRestApiRequestContext.getRequestContext(context); PollenUser pollenUser = pollenRestApiRequestContext.getSecurityContext().getPollenUser(); + Objects.requireNonNull(pollenUser,"Could not find connected user"); return pollenUserService.getUser(pollenUser.getTopiaId()); } diff --git a/pollen-ui-riot-js/src/main/web/i18n.json b/pollen-ui-riot-js/src/main/web/i18n.json index 5a7e1aa..68fae6a 100644 --- a/pollen-ui-riot-js/src/main/web/i18n.json +++ b/pollen-ui-riot-js/src/main/web/i18n.json @@ -1,5 +1,14 @@ { "fr": { + "comment_popup_create":"Créer un commentaire", + "comment_popup_edit":"Éditer un commentaire", + "comment_popup_action":"Enregistrer", + "comment_popup_authorPlaceholder":"Saisir votre nom", + "comment_popup_textPlaceholder":"Saisir le commentaire", + "polls_created_title":"Mes sondages", + "polls_created_name":"Nom", + "polls_created_createDate":"Date de création", + "polls_created_status":"Statut", "signup_title": "Créer un compte", "signup_email": "Email", "signup_email_placeholder": "Entrer l'email", @@ -132,6 +141,15 @@ "": "" }, "en": { + "comment_popup_create":"Create a comment", + "comment_popup_edit":"edit a comment", + "comment_popup_action":"Save", + "comment_popup_authorPlaceholder":"Fill your name", + "comment_popup_textPlaceholder":"Fill your comment", + "polls_created_title":"My polls", + "polls_created_name":"Name", + "polls_created_createDate":"Created date", + "polls_created_status":"Status", "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/CommentService.js b/pollen-ui-riot-js/src/main/web/js/CommentService.js new file mode 100644 index 0000000..6604f72 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/js/CommentService.js @@ -0,0 +1,55 @@ +/*- + * #%L + * Pollen :: UI (Riot Js) + * %% + * Copyright (C) 2009 - 2017 CodeLutin + * %% + * 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% + */ +let singleton = require("./Singleton"); +let FetchService = require("./FetchService"); + +class CommentService extends FetchService { + + getComments(pollId, pagination, permission) { + let args = {paginationParameter: pagination}; + if (permission) { + args.permission = permission; + } + return this.getWithParams("/v1/polls/" + pollId + "/comments", args); + } + + createComment(pollId, form) { + return this.form("/v1/polls/" + pollId + "/comments", {comment: form}); + } + + updateComment(pollId, form, permission) { + let url = "/v1/polls/" + pollId + "/comments/" + form.id; + if (permission) { + url += "?permission=" + permission; + } + return this.form(url, {comment: form}); + } + + deleteComment(pollId, commentId, permission) { + let url = "/v1/polls/" + pollId + "/comments/" + commentId; + if (permission) { + url += "?permission=" + permission; + } + return this.doDelete(url); + } +} + +module.exports = singleton(CommentService); diff --git a/pollen-ui-riot-js/src/main/web/js/FetchService.js b/pollen-ui-riot-js/src/main/web/js/FetchService.js index 8f5dcd9..aff3396 100644 --- a/pollen-ui-riot-js/src/main/web/js/FetchService.js +++ b/pollen-ui-riot-js/src/main/web/js/FetchService.js @@ -69,6 +69,22 @@ class FetchService { return this.fetch(url, "GET"); } + getWithParams(url, params) { + let query = "?"; + let keys = Object.keys(params); + keys.forEach((key) => { + let value = params[key]; + if (typeof value === 'object') { + value = JSON.stringify(value); + } + if (query.length > 1) { + query += "&"; + } + query += key + "=" + value; + }); + return this.fetch(url + query, "GET"); + } + post(url, body) { return this.fetch(url, "POST", null, body); } @@ -77,6 +93,10 @@ class FetchService { return this.fetch(url, "PUT", null, body); } + doDelete(url, body) { + return this.fetch(url, "DELETE", null, body); + } + form(url, data) { let formData = null; if (data) { diff --git a/pollen-ui-riot-js/src/main/web/js/Pagination.js b/pollen-ui-riot-js/src/main/web/js/Pagination.js new file mode 100644 index 0000000..e2ac3ed --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/js/Pagination.js @@ -0,0 +1,12 @@ +class Pagination { + + constructor() { + this.pageNumber = 0; + this.pageSize = 25; + this.order = ""; + this.desc = false; + } + +} + +module.exports = Pagination; \ No newline at end of file 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 7e59e15..4318798 100644 --- a/pollen-ui-riot-js/src/main/web/js/PollService.js +++ b/pollen-ui-riot-js/src/main/web/js/PollService.js @@ -31,6 +31,13 @@ class PollService extends FetchService { return this.form("/v1/polls/create", {poll: form, choices:choices}); } + createdPolls(pagination) { + return this.getWithParams("/v1/polls/created", {paginationParameter: pagination}); + } + + getPoll(pollId) { + return this.get("/v1/polls/"+pollId); + } } module.exports = singleton(PollService); diff --git a/pollen-ui-riot-js/src/main/web/tag/Header.tag b/pollen-ui-riot-js/src/main/web/tag/Header.tag index 583b0d3..75c6841 100644 --- a/pollen-ui-riot-js/src/main/web/tag/Header.tag +++ b/pollen-ui-riot-js/src/main/web/tag/Header.tag @@ -25,14 +25,14 @@ require("./HeaderI18n.tag"); </div> <div class="header-separator"></div> <div class="header-space"></div> - <a class="button header-button header-signin" if="{!user}" href="#signin">{__.signin}</a> + <a class="button header-button header-signin" if="{!user}" onclick="{signIn}">{__.signin}</a> <a class="button header-button header-signup" if="{!user}" href="#signup">{__.signup}</a> <div if="{user}" class="dropdown"> <a class="header-link">{user.email}</a> <div class="dropdown-content"> <a href="#user/profile">{__.myProfile}</a> - <a href="#user/polls">{__.myPolls}</a> + <a href="#polls/created">{__.myPolls}</a> <a href="#user/favoriteLists">{__.myFavoriteLists}</a> <span role="separator" class="divider"></span> <a onclick="{signOut}">{__.signout}</a> @@ -47,6 +47,9 @@ require("./HeaderI18n.tag"); this.installBundle(session, "header"); + this.signIn= ()=> { + route("signin?url="+window.location.hash.substring(1)); + }; this.signOut = () => { let callback = () => { this.user = null; diff --git a/pollen-ui-riot-js/src/main/web/tag/Pagination.tag b/pollen-ui-riot-js/src/main/web/tag/Pagination.tag new file mode 100644 index 0000000..6dfe1ce --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/Pagination.tag @@ -0,0 +1,130 @@ +<Pagination> + + <div class="pagination-controls"> + <div class="pagination-config"> + Résultats par page: + <select ref="pageSize" onchange="{onChangePageSize}"> + <option each="{a in sizes}" value="{a}">{a}</option> + + </select> + </div> + + <div class="pagination-pager"> + <button class="{pageNumber > 0 ? '' : 'disabled'}" onclick="{onPreviousPage}"> + <i class="fa fa-chevron-left"></i> + </button> + <div class="pagination-right"> + Page {pageNumber + 1} sur {lastPageNumber} + </div> + <button class="{(pageNumber + 1) < lastPageNumber ? '' : 'disabled'}" onclick="{onNextPage}"> + <i class="fa fa-chevron-right"></i> + </button> + </div> + </div> + + <script> + + this.on('mount', () => { + this.refs.pageSize.value = this.pageSize; + this.refresh(); + }); + + this.sizes = [1, 5, 10, 15, 25, 50, 100, 250, 500]; + this.pageNumber = 0; + this.lastPageNumber = 0; + this.pageSize = 5; + this.callback = opts.callback; + this.sortName = opts.sortName; + this.sortValue = opts.sortValue; + + this.onContextChange = function (newContext) { + this.paginationContext = newContext; + + console.info("onContextChange"); + console.info(newContext); + let count = this.paginationContext.count; + let size = this.paginationContext.pageSize; + this.lastPageNumber = Math.ceil(count / size); + this.pageNumber = this.paginationContext.currentPage; + this.pageSize = this.paginationContext.pageSize; + this.sortName = this.paginationContext.order; + this.sortValue = !this.paginationContext.desc; + }; + + this.onSortChange = function (sortName, sortValue) { + this.pageNumber = 0; + this.sortName = sortName; + this.sortValue = sortValue; + console.info("on sort change: "+sortName+" --> "+sortValue) + this.refresh(); + }; + this.onChangePageSize = function (e) { + this.pageNumber = 0; + if (e) { + + console.info("Page size change: " + e.target.value) + this.pageSize = e.target.value; + } + this.refresh(); + }; + + this.onPreviousPage = function () { + if (this.pageNumber > 0) { + this.pageNumber--; + this.refresh(); + } + }; + + this.onNextPage = function () { + if (this.pageNumber + 1 < this.lastPageNumber) { + this.pageNumber++; + this.refresh(); + } + }; + + this.refresh = function () { + let pagination = { + pageNumber: this.pageNumber, + pageSize: this.pageSize, + order: this.sortName, + desc: this.sortValue + }; + console.info("Request: "); + console.info(pagination); + this.callback(pagination).then((result) => { + console.info("update pagination"); + console.info(result.pagination); + this.onContextChange(result.pagination); + this.update(); + }); + }; + + </script> + <style> + + .disabled { + color: gray; + cursor: not-allowed; + } + + .pagination-right { + padding-left: 5px; + padding-right: 5px; + } + + .pagination-controls { + padding-top: 10px; + display: flex; + flex-direction: row; + justify-content: space-between; + } + + .pagination-pager { + display: flex; + flex-direction: row; + align-items: center; + justify-self: flex-end; + } + + </style> +</Pagination> \ No newline at end of file diff --git a/pollen-ui-riot-js/src/main/web/tag/Pollen.tag b/pollen-ui-riot-js/src/main/web/tag/Pollen.tag index de95131..b9fed83 100644 --- a/pollen-ui-riot-js/src/main/web/tag/Pollen.tag +++ b/pollen-ui-riot-js/src/main/web/tag/Pollen.tag @@ -1,23 +1,23 @@ /*- - * #%L - * Pollen :: UI (Riot Js) - * %% - * Copyright (C) 2009 - 2017 CodeLutin - * %% - * 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% - */ +* #%L +* Pollen :: UI (Riot Js) +* %% +* Copyright (C) 2009 - 2017 CodeLutin +* %% +* 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% +*/ require("./Header.tag"); require("./Footer.tag"); require("./SignIn.tag"); @@ -25,6 +25,8 @@ require("./SignUp.tag"); require("./SignCheck.tag"); require("./Home.tag"); require("./poll/CreatePoll.tag"); +require("./poll/Poll.tag"); +require("./polls/CreatedPolls.tag"); <Pollen class="body-wrapper"> <Header></Header> <div class="body-content" ref="content"></div> @@ -39,6 +41,10 @@ require("./poll/CreatePoll.tag"); route("/signin", () => { riot.mount(this.refs.content, "signin"); }); + route("/signin..", (url) => { + let q = route.query(); + riot.mount(this.refs.content, "signin", {url: q.url}); + }); route("/signup", () => { riot.mount(this.refs.content, "signup"); }); @@ -51,18 +57,34 @@ require("./poll/CreatePoll.tag"); route("/poll", () => { riot.mount(this.refs.content, "polls"); }); - route("/poll/*", (pollId) => { - riot.mount(this.refs.content, "poll", {pollId}); + + route("/poll/*/vote", (pollId) => { + riot.mount(this.refs.content, "poll", {pollId: pollId, tabName: 'votes'}); + }); + route("/poll/*/vote/*", (pollId, permission) => { + riot.mount(this.refs.content, "poll", {pollId: pollId, tabName: 'votes', permission: permission}); + }); + route("/poll/*/comment", (pollId) => { + riot.mount(this.refs.content, "poll", {pollId: pollId, tabName: 'comments'}); + }); + route("/poll/*/comment/*", (pollId, permission) => { + riot.mount(this.refs.content, "poll", {pollId: pollId, tabName: 'comments', permission: permission}); }); + route("/user/profile", () => { riot.mount(this.refs.content, "userprofile"); }); - route("/user/poll", () => { - riot.mount(this.refs.content, "userpolls"); - }); route("/user/favoriteList", () => { riot.mount(this.refs.content, "userfavoritelists"); }); + + route("/polls/created", () => { + if (!session.isConnected()) { + route("/signin?url=/polls/created"); + } else { + riot.mount(this.refs.content, "createdpolls"); + } + }); route("/poll/new/*/*", (type, step) => { riot.mount(this.refs.content, "createpoll", {type: type, step: step}); }); diff --git a/pollen-ui-riot-js/src/main/web/tag/SignIn.tag b/pollen-ui-riot-js/src/main/web/tag/SignIn.tag index 4b64681..8501483 100644 --- a/pollen-ui-riot-js/src/main/web/tag/SignIn.tag +++ b/pollen-ui-riot-js/src/main/web/tag/SignIn.tag @@ -62,7 +62,10 @@ require("./popup/NewPassword.tag"); authService.signIn(this.refs.login.value, this.refs.password.value) .then(() => { - route(this.opts.link || "/"); + let back = opts.url || "/"; + console.info("After login url:" +back); + route(back); + this.update(); }) .catch((code) => { this.message = this.__.error_signin; diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/CommentPopup.tag b/pollen-ui-riot-js/src/main/web/tag/poll/CommentPopup.tag new file mode 100644 index 0000000..e4801cf --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/poll/CommentPopup.tag @@ -0,0 +1,191 @@ +/*- +* #%L +* Pollen :: UI (Riot Js) +* %% +* Copyright (C) 2009 - 2017 CodeLutin +* %% +* 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% +*/ +<CommentPopup class="close"> + + <div class="popup-background"></div> + + <div class="popup-content"> + <div class="popup-close" onclick="{close}"> + <i class="fa fa-times"></i> + </div> + <div class="popup-title">{title}</div> + <form class="popup-message" onsubmit="{action}"> + <div class="popup-message-header"> + <div if="{error}" class="error">{error}</div> + </div> + <input ref="author" type="text" required placeholder="{__.authorPlaceholder}"> + <textarea ref="text" required placeholder="{__.textPlaceholder}"/> + <input type="submit" class="button" value="{__.action}"> + </form> + + </div> + + <script> + let session = require("../../js/Session"); + this.installBundle(session, "comment_popup"); + + this.error = ""; + + this.oldParent = this.parent.root; + + this.openForEdit = (pollId, comment, callback) => { + this.title = this.__.edit; + this.open(pollId, comment, callback); + }; + + this.openForCreate = (pollId, comment, callback) => { + this.title = this.__.create; + this.open(pollId, comment, callback); + }; + + this.open = (pollId, comment, callback) => { + this.comment = Object.assign({}, comment); + this.refs.author.value = comment.authorName; + this.refs.text.value = comment.text; + this.pollId = pollId; + this.callback = callback; + this.error = ""; + document.body.appendChild(this.root); + this.root.classList.toggle("close"); + this.root.classList.toggle("open"); + } + + this.close = () => { + this.oldParent.appendChild(this.root); + this.root.classList.toggle("close"); + this.root.classList.toggle("open"); + }; + + this.action = (e) => { + e.preventDefault(); + e.stopPropagation(); + this.error = ""; + this.comment.authorName = this.refs.author.value; + this.comment.text = this.refs.text.value; + this.callback(this.comment).then(result => { + this.close(); + }).catch((e) => { + this.error = e; + this.update(); + }); + }; + </script> + + <style> + commentpopup { + justify-content: center; + align-items: center; + flex-direction: column; + position: absolute; + top: 0; + width: 100%; + height: 100%; + } + + .popup-background { + width: 100%; + height: 100%; + background-color: white; + opacity: .8; + position: absolute; + top: 0; + } + + commentpopup.close { + display: none; + } + + commentpopup.open { + display: flex; + } + + .popup-title { + height: 70px; + border-bottom: 1px solid #b2c7d3; + background-color: white; + display: flex; + justify-content: center; + align-items: center; + margin-bottom: 20px; + font-size: 20px; + } + + .popup-content { + position: relative; + z-index: 1; + border-radius: 10px; + background-color: #f2f2f2; + box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.1); + } + + .popup-content .button { + padding: 0; + border: none; + border-radius: 0; + width: 100%; + margin: 20px 0 0; + } + + .popup-close { + cursor: pointer; + position: absolute; + top: 20px; + right: 20px; + } + + .popup-message { + display: flex; + flex-direction: column; + width: 420px; + text-align: left; + } + + .popup-message > div { + margin-right: 22px; + } + + .popup-message-header { + display: flex; + flex-direction: row; + justify-content: flex-end; + height: 30px; + } + + .popup-message > input { + width: 390px; + margin-top: 10px; + margin-bottom: 5px; + } + + .popup-message > textarea { + width: 390px; + margin-top: 10px; + margin-bottom: 5px; + } + + .error { + margin: 3px; + color: red; + } + + </style> + +</CommentPopup> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag b/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag new file mode 100644 index 0000000..9ef8b61 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag @@ -0,0 +1,112 @@ +require('./PollVotes.tag'); +require('./PollComments.tag'); +<Poll> + + <div class="container"> + + <div class="legend"> + {poll.title} + </div> + + <div class="tab-header"> + <div class="{selectedTab=='votes'?'tab-selected':'tab-not-selected'}"> + <a href="#poll/{pollId}/vote"> + <i class="fa fa-thumbs-o-up fa-flip-horizontal"></i>Votes + </a> + </div> + <div class="{selectedTab=='comments'?'tab-selected':'tab-not-selected'}"> + <a href="#poll/{pollId}/comment"> + <i class="fa fa-comments-o"></i>Comments + </a> + </div> + + </div> + <div ref="content" class="tab-content"/> + </div> + + <script> + this.poll = {title: ""}; + this.pollId = opts.pollId; + this.selectedTab = opts.tabName; + this.permission = opts.permission; + let session = require("../../js/Session"); + this.installBundle(session, "poll"); + + + this.on('mount', () => { + let pollService = require('../../js/PollService'); + pollService.getPoll(this.pollId).then(result => { + this.poll = result; + console.info(this.poll); + this.update(); + + if (this.selectedTab == 'votes') { + riot.mount(this.refs.content, "pollvotes", { + pollId: this.pollId, + session: session, + permission: this.permission + }); + } + if (this.selectedTab == 'comments') { + riot.mount(this.refs.content, "pollcomments", { + pollId: this.pollId, + session: session, + permission: this.permission + }); + } + }); + + }); + + + </script> + <style> + + .container { + display: flex; + justify-content: space-around; + align-items: flex-start; + flex-direction: column; + background: white; + border: solid 2px #c8ccca; + border-radius: 10px; + padding: 15px 15px; + width: 90%; + margin-left: 20px; + } + + .tab-content { + margin-top: 20px; + min-height: 300px; + } + + .legend { + width: 100%; + height: 30px; + border-bottom: 1px solid #b2c7d3; + display: flex; + justify-content: center; + align-items: center; + padding-bottom: 10px; + font-size: 20px; + } + + .tab-header { + display: flex; + flex-direction: row; + padding-top: 20px; + } + + .tab-header > div { + padding-right: 20px; + } + + .tab-selected { + color: #13a2ff; + } + + .tab-not-selected > a { + color: black; + } + </style> +</Poll> \ No newline at end of file diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/PollComments.tag b/pollen-ui-riot-js/src/main/web/tag/poll/PollComments.tag new file mode 100644 index 0000000..b863063 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/poll/PollComments.tag @@ -0,0 +1,194 @@ +require('../Pagination.tag'); +require('./CommentPopup.tag'); +<PollComments> + <div class="comment-container"> + <div class="legend"> + Comments <a if="{comments.length > -1}" onclick="{toggleSort}"><i ref="sortOwner" + class="fa fa-sort-amount-desc"></i></a> + </div> + <div class="body"> + + <div if="{comments.length == 0}">Pas de commentaire</div> + <table show="{comments.length > 0}"> + <tbody> + <tr each="{comment in comments}"> + <td> + <div class="comment-header"> + <div> + <i class="fa fa-user"/> + {comment.authorName} + </div> + <div> + <i class="fa fa-calendar-o"/> + {comment.postDate} + </div> + <div if="{comment.permission}" id="{comment.id}"> + <a onclick="{parent.openEditComment}"><i class="fa fa-pencil-square-o"/></a> + <a onclick="{parent.deleteComment}"><i class="fa fa-trash danger"/></a> + </div> + </div> + + </td> + <td> + <div class="comment-content"> + {comment.text} + </div> + </td> + </tr> + </tbody> + <tfoot> + <tr> + <th colspan="3"> + <div> + <Pagination ref=pagination" sortName='"postDate"' sortValue='true' callback="{callback}"/> + </div> + </th> + </tr> + </tfoot> + </table> + + <div class="actions"> + <a class="button mainColorBackground" onclick="{openAddComment}">Ajouter un commentaire</a> + </div> + </div> + </div> + + <CommentPopup ref="commentPopup"/> + + <script> + + let session = require("../../js/Session"); + this.installBundle(session, "poll_comments"); + let commentService = require("../../js/CommentService"); + + this.pollId = opts.pollId; + this.permission = opts.permission; + console.info("permission:: " + this.permission); + this.on('mount', () => { + this.pagination = this.tags.pagination; + }); + + this.sortName = 'postDate'; + this.sortValue = true; // means desc + + this.comments = []; + this.toggleSort = (e) => { + this.refs.sortOwner.classList.toggle('fa-sort-amount-desc'); + this.refs.sortOwner.classList.toggle('fa-sort-amount-asc'); + this.sortValue = !this.sortValue; + this.pagination.onSortChange('postDate', this.sortValue); + }; + + this.openAddComment = (e) => { + let comment = { + text: '', + authorName: '' + }; + if (session.isConnected()) { + comment.authorName = session.user.name; + } + this.refs.commentPopup.openForCreate(this.pollId, comment, this.addComment); + }; + + this.addComment = (comment) => { + return commentService.createComment(this.pollId, comment) + .then((result) => { + console.info("created comment"); + console.info(result); + this.pagination.refresh(); + }); + }; + + this.openEditComment = (e) => { + let commentId = e.target.parentNode.parentNode.id; + this.comments.forEach(comment => { + if (comment.id == commentId) { + console.info('edit comment ' + commentId); + this.refs.commentPopup.openForEdit(this.pollId, comment, this.editComment); + } + }); + + }; + + this.editComment = (comment) => { + return commentService.updateComment(this.pollId, comment, this.permission || comment.permission || '') + .then((result) => { + console.info("updated comment"); + console.info(result); + this.pagination.refresh(); + }); + }; + + this.deleteComment = (e) => { + let commentId = e.target.parentNode.parentNode.id; + this.comments.forEach(comment => { + if (comment.id == commentId) { + let response = confirm('Delete comment ?'); + if (response) { + return commentService.deleteComment(this.pollId, commentId, this.permission || comment.permission || '') + .then((result) => { + console.info("delete comment"); + console.info(result); + this.pagination.onChangePageSize(); + }); + } + } + }); + }; + + this.callback = (pagination) => { + if (!this.pollId) { + return Promise.resolve({elements: []}); + } + console.info("Request data with pagination::"); + if (!pagination.sortName) { + pagination.order = this.sortName; + pagination.desc = this.sortValue; + } + console.info(pagination); + return commentService.getComments(this.pollId, pagination, this.permission).then((result) => { + this.comments = result.elements; + console.info(this.comments); + this.update(); + return result; + }); + }; + + </script> + <style> + .danger { + color: red; + } + + .comment-container { + width: 800px; + } + + .comment-header { + width: 200px; + } + + .legend { + width: 800px; + } + + .actions { + margin-top: 10px; + } + + tr > td:first-child { + border-right: 1px solid #ddd; + } + + tr td { + border-bottom: 1px solid #ddd; + vertical-align: top; + padding: 5px 5px 15px; + } + + table { + width: 800px; + } + + </style> +</PollComments> \ No newline at end of file diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/PollSettings.tag b/pollen-ui-riot-js/src/main/web/tag/poll/PollSettings.tag index 0964d5e..32772fa 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/PollSettings.tag +++ b/pollen-ui-riot-js/src/main/web/tag/poll/PollSettings.tag @@ -56,7 +56,7 @@ <a onclick="{scrollTo}" href="#Choice">{__.nav_choices}</a> <ul class="nav nav-stacked"> <li> - <a onclick="{scrollTo}" href="#ChoiceaddChoices">{__.nav_addChoices}</a> + <a onclick="{scrollTo}" href="#Choice_addChoices">{__.nav_addChoices}</a> </li> <li> <a onclick="{scrollTo}" href="#Choice_limitChoices">{__.nav_limitChoices}</a> @@ -269,8 +269,11 @@ let model = this.form.model; let form = this.refs.form; - let FormHelper = require('../../js/FormHelper'); - FormHelper.fillForm(form, model); + if (form) { + let FormHelper = require('../../js/FormHelper'); + FormHelper.fillForm(form, model); + } + }); this.previousStep = (e) => { diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/PollVotes.tag b/pollen-ui-riot-js/src/main/web/tag/poll/PollVotes.tag new file mode 100644 index 0000000..69efb7c --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/poll/PollVotes.tag @@ -0,0 +1,5 @@ +<PollVotes> + <div> + Votes + </div> +</PollVotes> \ No newline at end of file diff --git a/pollen-ui-riot-js/src/main/web/tag/polls/CreatedPolls.tag b/pollen-ui-riot-js/src/main/web/tag/polls/CreatedPolls.tag new file mode 100644 index 0000000..ce76ca7 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/polls/CreatedPolls.tag @@ -0,0 +1,137 @@ +require('../Pagination.tag'); +<CreatedPolls> + <div class="body-container"> + + <div class="container"> + + <div class="legend">{__.title}</div> + <table> + <thead> + <tr> + <th class="wide" onclick="{toggleSort}">{__.name} <i ref="sortName" + class="fa fa-sort-amount-asc"></i></th> + <th onclick="{toggleSort}">{__.createDate} <i ref="sortCreateDate" + class="disabled fa fa-sort"></i></th> + <th onclick="{toggleSort}">{__.status}</th> + </tr> + </thead> + <tbody> + <tr each="{poll in polls}"> + <td> + <a href="#poll/{poll.id}/vote">{poll.title}</a> + </td> + <td>{poll.beginDate}</td> + <td>{poll.status}</td> + </tr> + </tbody> + <tfoot> + <tr> + <th colspan="3"> + <div> + <Pagination ref=pagination" sortName='{sortName}' sortValue='false' callback="{callback}"/> + </div> + </th> + </tr> + </tfoot> + </table> + </div> + + </div> + + <script> + this.sortName = 'title'; + this.sortValue = false; // means asc + let pollService = require('../../js/PollService'); + this.callback = (pagination) => { + console.info("Request data with pagination::"); + if (!pagination.sortName) { + pagination.order = this.sortName; + pagination.desc = this.sortValue; + } + console.info(pagination); + return pollService.createdPolls(pagination).then((result) => { + this.polls = result.elements; + console.info(this.polls); + this.update(); + return result; + }); + }; + this.polls = null; + + let session = require("../../js/Session"); + this.installBundle(session, "polls_created"); + this.on('mount', () => { + this.pagination = this.tags.pagination; + this.sortOwner = this.refs.sortName; + this.refs.sortName.setAttribute('sortName', 'title'); + this.refs.sortCreateDate.setAttribute('sortName', 'topiaCreatedDate'); + }); + + this.toggleSort = (e) => { + console.info(this.refs.sortName); + if (this.sortOwner === e.target) { + this.sortOwner.classList.toggle('fa-sort-amount-asc'); + this.sortOwner.classList.toggle('fa-sort-amount-desc'); + this.sortValue = !this.sortValue; + } else { + + this.sortOwner.classList.add('fa-sort'); + this.sortOwner.classList.add('disabled'); + this.sortOwner.classList.remove('fa-sort-amount-desc'); + this.sortOwner.classList.remove('fa-sort-amount-asc'); + + this.sortOwner = e.target; + + this.sortOwner.classList.remove('disabled'); + this.sortOwner.classList.remove('fa-sort'); + this.sortOwner.classList.remove('fa-sort-amount-desc'); + this.sortOwner.classList.add('fa-sort-amount-asc'); + this.sortValue = true; + } + + this.pagination.onSortChange(this.sortOwner.getAttribute('sortName'), this.sortValue); + }; + + </script> + <style> + + .disabled { + color: gray; + } + + .wide { + width: 400px; + } + + .container { + display: flex; + justify-content: space-around; + align-items: center; + flex-direction: column; + background: white; + border: solid 2px #c8ccca; + border-radius: 10px; + padding: 15px 0; + width: 90%; + } + + table { + padding-top: 10px; + } + + thead > tr > th { + text-align: left; + } + + .legend { + width: 100%; + height: 30px; + border-bottom: 1px solid #b2c7d3; + display: flex; + justify-content: center; + align-items: center; + padding-bottom: 10px; + font-size: 20px; + } + </style> +</CreatedPolls> \ No newline at end of file -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm