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 d0f6837a331a78be143e72b7a9493aef63b8f947 Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Thu Apr 13 15:05:04 2017 +0200 gestion des listes de favoris --- pollen-ui-riot-js/src/main/web/i18n.json | 77 ++++- .../src/main/web/js/FavoriteListService.js | 76 +++++ pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html | 12 +- .../src/main/web/tag/PollenHeader.tag.html | 2 +- .../web/tag/favoriteList/FavoriteList.tag.html | 363 +++++++++++++++++++++ .../web/tag/favoriteList/FavoriteListCard.tag.html | 52 +++ .../web/tag/favoriteList/FavoriteLists.tag.html | 120 +++++++ .../main/web/tag/favoriteList/MemberCard.tag.html | 151 +++++++++ 8 files changed, 848 insertions(+), 5 deletions(-) diff --git a/pollen-ui-riot-js/src/main/web/i18n.json b/pollen-ui-riot-js/src/main/web/i18n.json index 4a29331..dfcb593 100644 --- a/pollen-ui-riot-js/src/main/web/i18n.json +++ b/pollen-ui-riot-js/src/main/web/i18n.json @@ -311,7 +311,44 @@ "choice_date": "Renseignez une date", "choice_time": "Ajouter une heure à la date", "choice_description": "Ajouter un descriptif du choix", - "choice_download": "Télécharger" + "choice_download": "Télécharger", + "favoriteList_title": "Mes listes de votants", + "favoriteList_addFavoriteList": "Ajouter une nouvelle liste de votants", + "favoriteList_name": "Nom", + "favoriteList_name_placdeholder": "Renseignez le nom de la nouvelle liste", + "favoriteList_add": "Ajouter", + "favoriteList_sort": "trier par", + "favoriteList_createDate": "Date de création", + "favoriteList_name": "Nom", + "favoriteList_email": "Courriel", + "favoriteList_noFavoriteList": "Aucune liste de votants", + "favoriteList_cancel": "Annuler", + "favoriteList_back": "Retour", + "favoriteList_save": "Enregistrer", + "favoriteList_edit": "Modifier la liste de votants", + "favoriteList_delete": "Supprimer", + "favoriteList_deleteMessage": "Supprimer la liste de votants ?", + "favoriteList_noMember": "Aucun membre dans cette liste", + "favoriteList_members": "Membres de la liste", + "favoriteList_member_new": "Nouveau Membre", + "favoriteList_member_import": "Importer", + "favoriteList_member_importCsv": "Importer des membres à partir d'un fichier", + "favoriteList_member_csvFile": "Fichier des membres", + "favoriteList_member_csvFile_exemple": "# Courriel Nom\ndupond@domaine.fr Jean Dupond \npseudo@bleu.fr Arnaud Lemaitre \nmiller@courriel.com Benjamin Miller ", + "favoriteList_member_csvFile_exemple_label": "Exemple de fichier", + "favoriteList_member_importLdap": "Importer des membres à partir d'un annuaire LDAP", + "favoriteList_member_ldap": "Adresse de l'annuaire LDAP", + "favoriteList_member_edit": "Modifier ce membre", + "favoriteList_member_delete": "Supprimer ce membre", + "favoriteList_member_deleteMessage": "Supprimer ce membre ?", + "favoriteList_member_cancel": "Annuler", + "favoriteList_member_save": "Enregistrer", + "favoriteList_member_name": "Nom", + "favoriteList_member_name_placeholder": "Le nom du membre", + "favoriteList_member_email": "Courriel", + "favoriteList_member_email_placeholder": "Le courriel du membre", + "favoriteList_member_ldap_placeholder": "L'adresse de l'annuaire LDAP", + "favoriteList_member_add": "Ajouter" }, "en": { "pagination_all": "All", @@ -616,6 +653,42 @@ "choice_date": "Set a date", "choice_time": "add hours to date", "choice_description": "add description", - "choice_download": "Download" + "choice_download": "Download", + "favoriteList_title": "My favorite lists", + "favoriteList_addFavoriteList": "Add new favorite list", + "favoriteList_name": "Name", + "favoriteList_name_placdeholder": "Enter new list name", + "favoriteList_add": "Add", + "favoriteList_sort": "Sort by", + "favoriteList_createDate": "Creation Date", + "favoriteList_email": "Email", + "favoriteList_noFavoriteList": "no favorite list", + "favoriteList_cancel": "Cancel", + "favoriteList_back": "Back", + "favoriteList_save": "Save", + "favoriteList_edit": "edit favorite list", + "favoriteList_delete": "Delete", + "favoriteList_deleteMessage": "Delete favorite list ?", + "favoriteList_noMember": "no member in this list", + "favoriteList_members": "list members", + "favoriteList_member_new": "New member", + "favoriteList_member_import": "Import", + "favoriteList_member_importCsv": "Import members from filer", + "favoriteList_member_csvFile": "members file", + "favoriteList_member_csvFile_exemple": "# Email Name\nsmith@domain.uk John Smith \npseudo@yellow.uk Mathieu Anderson \nmiller@courriel.com William Miller ", + "favoriteList_member_csvFile_exemple_label": "file exemple", + "favoriteList_member_importLdap": "Import members from LDAP repository", + "favoriteList_member_ldap": "LDAP repository address", + "favoriteList_member_edit": "Edit member", + "favoriteList_member_delete": "Delete Member", + "favoriteList_member_deleteMessage": "Delete member ?", + "favoriteList_member_cancel": "Cancel", + "favoriteList_member_save": "Save", + "favoriteList_member_name": "Name", + "favoriteList_member_name_placeholder": "Member name", + "favoriteList_member_email": "Email", + "favoriteList_member_email_placeholder": "Member email", + "favoriteList_member_ldap_placeholder": "LDAP repository address", + "favoriteList_member_add": "Add" } } diff --git a/pollen-ui-riot-js/src/main/web/js/FavoriteListService.js b/pollen-ui-riot-js/src/main/web/js/FavoriteListService.js new file mode 100644 index 0000000..0a46a25 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/js/FavoriteListService.js @@ -0,0 +1,76 @@ +/*- + * #%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 FavoriteListService extends FetchService { + + favoriteLists(pagination) { + return this.getWithParams("/v1/favoriteLists", {paginationParameter: pagination}); + } + + favoriteList(favoriteListId) { + return this.get("/v1/favoriteLists/" + favoriteListId); + } + + importCsv(favoriteListId, csvFile) { + return this.form("/v1/favoriteLists/" + favoriteListId + "/importCsv", {csvFile: csvFile}, true); + } + + importLdap(favoriteListId, ldap) { + return this.form("/v1/favoriteLists/" + favoriteListId + "/importLdap", {ldap: ldap}); + } + + createFavoriteList(favoriteList) { + return this.form("/v1/favoriteLists", {favoriteList: favoriteList}); + } + + saveFavoriteList(favoriteList) { + return this.form("/v1/favoriteLists/" + favoriteList.id, {favoriteList: favoriteList}); + } + + deleteFavoriteList(favoriteListId) { + return this.doDelete("/v1/favoriteLists/" + favoriteListId); + } + + members(favoriteListId, pagination) { + return this.getWithParams("/v1/favoriteLists/" + favoriteListId + "/members", {paginationParameter: pagination}); + } + + member(favoriteListId, memberId) { + return this.get("/v1/favoriteLists/" + favoriteListId + "/members/" + memberId); + } + + addMember(favoriteListId, member) { + return this.form("/v1/favoriteLists/" + favoriteListId + "/members", {member: member}); + } + + saveMember(favoriteListId, member) { + return this.form("/v1/favoriteLists/" + favoriteListId + "/members/" + member.id, {member: member}); + } + + deleteMember(favoriteListId, memberId) { + return this.doDelete("/v1/favoriteLists/" + favoriteListId + "/members/" + memberId); + } + +} + +module.exports = singleton(FavoriteListService); diff --git a/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html b/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html index 2d3449e..bae60bc 100644 --- a/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html @@ -30,6 +30,8 @@ require("./poll/Poll.tag.html"); require("./poll/Polls.tag.html"); require("./Users.tag.html"); require("./UserProfile.tag.html"); +require("./favoriteList/FavoriteLists.tag.html"); +require("./favoriteList/FavoriteList.tag.html"); <Pollen class="body-wrapper"> <PollenHeader/> <PollenWaiter parent-id="body-content"/> @@ -150,8 +152,14 @@ require("./UserProfile.tag.html"); route("/user/profile", () => { riot.mount(this.refs.content, "userprofile"); }); - route("/user/favoriteList", () => { - riot.mount(this.refs.content, "userfavoritelists"); + route("/favoriteLists", () => { + riot.mount(this.refs.content, "favoritelists"); + }); + route("/favoriteLists/new", () => { + riot.mount(this.refs.content, "favoritelist"); + }); + route("/favoriteLists/*", (favoriteListId) => { + riot.mount(this.refs.content, "favoritelist", {favoriteListId: favoriteListId}); }); route(() => { diff --git a/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html b/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html index 4db6b8a..4fd8d90 100644 --- a/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html @@ -53,7 +53,7 @@ require("./HeaderI18n.tag.html"); <a href="#poll/created">{__.myPolls}</a> <a href="#poll/invited">{__.myInvitedPolls}</a> <a href="#poll/participated">{__.myParticipatedPolls}</a> - <a href="#user/favoriteLists">{__.myFavoriteLists}</a> + <a href="#favoriteLists">{__.myFavoriteLists}</a> <span role="separator" class="divider"></span> <a onclick="{signOut}">{__.signout}</a> </virtual> 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 new file mode 100644 index 0000000..39eebb2 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteList.tag.html @@ -0,0 +1,363 @@ +require("../Pagination.tag.html"); +require("./MemberCard.tag.html"); +<FavoriteList> + <div class="container" > + <div show="{loaded}"> + <h1 class="c-heading">{favoriteList.name || __.title}</h1> + <form onsubmit={save}> + <div class="o-form-element"> + <label class="c-label" for="name">{__.name}</label> + <input type="text" + id="name" + ref="name" + class="c-field" + placeholder={__.name_placeholder} + value={favoriteList.name}> + </div> + <div class="actions"> + <a class="c-button c-button--ghost-info" + if={!favoriteList.id} + href="#/favoriteLists"> + <i class="fa fa-undo" aria-hidden="true"></i> + {__.cancel} + </a> + <a class="c-button c-button--ghost-info" + href="#/favoriteLists" + if={favoriteList.id}> + <i class="fa fa-chevron-left" aria-hidden="true"></i> + {__.back} + </a> + <div class="actions-right"> + <button class="c-button c-button--error" + type="button" + if={favoriteList.id} + onclick={delete}> + <i class="fa fa-times" aria-hidden="true"></i> + {__.delete} + </button> + <button class="c-button c-button--success" + type="submit"> + <i class="fa fa-check" aria-hidden="true"></i> + {__.save} + </button> + </div> + </div> + </form> + <virtual if={favoriteList.id}> + <hr/> + <h3 class="c-heading">{__.members}</h3> + <div show={members.length > 0} > + <div class="o-form-element sort"> + <label class="c-label" for="sort">{__.sort}</label> + <div class="c-input-group"> + <div class="o-field"> + <select class="c-field" + onchange={selectSort}> + <option value="topiaCreateDate">{__.createDate}</option> + <option value="name">{__.name}</option> + <option value="email">{__.email}</option> + </select> + </div> + <button class="c-button c-button--brand" + onclick={toggleSort}> + <i class="fa {pagination.desc ? 'fa-sort-amount-desc' : 'fa-sort-amount-asc'}"></i> + </button> + </div> + </div> + + <Pagination pagination={pagination} onchange="{refresh}"/> + + <MemberCard each={member in members} member={member} favorite-list={parent.favoriteList} on-member-change={parent.refresh}/> + + <Pagination pagination={pagination} onchange="{refresh}"/> + </div> + <div show={members.length === 0} class="c-alert c-alert--info"> + {__.noMember} + </div> + <hr/> + <form class="form-add" onsubmit={addMember}> + <h3 class="c-heading">{__.member_new}</h3> + <div class="o-form-element"> + <label class="c-label" for="nameMember">{__.member_name}</label> + <input type="text" + id="nameMember" + ref="nameMember" + placeholder={__.member_name_placeholder} + required + class="c-field {c-field--error : errors.name}"> + </div> + <div class="o-form-element"> + <label class="c-label" for="email">{__.member_email}</label> + <input type="email" + id="email" + ref="email" + required + placeholder={__.member_email_placeholder} + class="c-field {c-field--error : errors.email}"> + </div> + <div class="actions"> + <a class="c-button c-button--ghost-info" + href="#/favoriteLists" + if={favoriteList.id}> + <i class="fa fa-chevron-left" aria-hidden="true"></i> + {__.back} + </a> + <button class="c-button c-button--success" + type="submit"> + <i class="fa fa-user-plus" aria-hidden="true"></i> + {__.member_add} + </button> + </div> + </form> + <hr/> + <form class="form-add" onsubmit={importCsv}> + <h3 class="c-heading">{__.member_importCsv}</h3> + <div class="o-form-element"> + <label class="c-label" for="csvFile">{__.member_csvFile}</label> + <input type="file" + id="csvFile" + ref="csvFile" + required + class="c-field"> + <div class="file-exemple"> + {__.member_csvFile_exemple_label} + <code class="c-code c-code--multiline"> + {__.member_csvFile_exemple} + </code> + </div> + </div> + <div class="actions"> + <a class="c-button c-button--ghost-info" + href="#/favoriteLists" + if={favoriteList.id}> + <i class="fa fa-chevron-left" aria-hidden="true"></i> + {__.back} + </a> + <button class="c-button c-button--success" + type="submit"> + <i class="fa fa-upload" aria-hidden="true"></i> + {__.member_import} + </button> + </div> + </form> + <hr/> + <form class="form-add" onsubmit={importLdap}> + <h3 class="c-heading">{__.member_importLdap}</h3> + <div class="o-form-element"> + <label class="c-label" for="csvFile">{__.member_ldap}</label> + <input type="text" + id="ldapUrl" + ref="ldapUrl" + required + placeholder={__.member_ldap_placeholder} + class="c-field"> + </div> + <div class="actions"> + <a class="c-button c-button--ghost-info" + href="#/favoriteLists" + if={favoriteList.id}> + <i class="fa fa-chevron-left" aria-hidden="true"></i> + {__.back} + </a> + <button class="c-button c-button--success" + type="submit"> + <i class="fa fa-upload" aria-hidden="true"></i> + {__.member_import} + </button> + </div> + </form> + </virtual> + </div> + </div> + + <script type="es6"> + let session = require("../../js/Session"); + let route = require("riot-route"); + this.installBundle(session, "favoriteList"); + let favoriteListService = require("../../js/FavoriteListService"); + this.addType = "member"; + this.errors = {}; + this.pagination = { + order: "topiaCreateDate", + desc: true, + pageSize: 5, + pageNumber: 0 + }; + this.favoriteList = { + id: this.opts.favoriteListId + }; + this.members = []; + + this.delete = () => { + if (this.favoriteList.id && confirm(this.__.deleteMessage)) { + favoriteListService.deleteFavoriteList(this.favoriteList.id).then(() => { + route("/favoriteLists") + }); + } + }; + + this.save = e => { + e.preventDefault(); + e.stopPropagation(); + this.favoriteList.name = this.refs.name.value; + + if (this.favoriteList.id) { + favoriteListService.saveFavoriteList(this.favoriteList).then(() => { + this.errors = {}; + this.refresh(); + }, errors => { + this.errors = errors; + this.update(); + }); + } else { + favoriteListService.createFavoriteList(this.favoriteList).then((result) => { + route("/favoriteLists/" + result.id); + }, errors => { + this.errors = errors; + this.update(); + }); + } + }; + + this.onAddTypeChange = () => { + this.addType = this.refs.addType.value; + }; + + + this.refresh = () => { + if (this.favoriteList.id) { + Promise.all([ + favoriteListService.favoriteList(this.favoriteList.id), + favoriteListService.members(this.favoriteList.id, this.pagination) + ]).then((results) => { + this.favoriteList = results[0]; + this.members = results[1].elements; + Object.assign(this.pagination, results[1].pagination); + this.loaded = true; + this.update(); + return this.favoriteList; + }); + } else { + this.loaded = true; + } + }; + + this.addMember = (e) => { + e.preventDefault(); + e.stopPropagation(); + let member = { + name: this.refs.nameMember.value, + email: this.refs.email.value + }; + + favoriteListService.addMember(this.favoriteList.id, member).then(() => { + this.errors = {}; + this.refs.nameMember.value = ""; + this.refs.email.value = ""; + this.refresh(); + }, errors => { + this.errors = errors; + this.update(); + }); + }; + + this.importCsv = (e) => { + e.preventDefault(); + e.stopPropagation(); + let csvFile = this.refs.csvFile.files[0]; + favoriteListService.importCsv(this.favoriteList.id, csvFile).then(() => { + this.errors = {}; + this.refs.csvFile.value = ""; + this.refresh(); + }, errors => { + this.errors = errors; + this.update(); + }); + }; + + this.importLdap = (e) => { + e.preventDefault(); + e.stopPropagation(); + let ldap = this.refs.ldapUrl.value; + + favoriteListService.importLdap(this.favoriteList.id, ldap).then(() => { + this.errors = {}; + this.refs.nameMember.value = ""; + this.refs.email.value = ""; + this.refresh(); + }, errors => { + this.errors = errors; + this.update(); + }); + }; + + this.toggleSort = () => { + this.pagination.desc = !this.pagination.desc; + this.refresh(); + }; + + this.selectSort = (e) => { + this.pagination.order = e.target.value; + this.refresh(); + }; + + this.refresh(); + + </script> + + <style> + + h1.c-heading { + text-align: center; + } + + .o-form-element.sort .c-label:first-child { + width: 70px; + display: inline-block; + text-align: right; + float: left; + padding-top: 0.5em; + padding-right: 5px; + } + + .o-form-element.sort .c-input-group { + width: 200px; + } + + .o-form-element.sort .c-input-group .c-field { + width: 100%; + } + + @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; + } + + .file-exemple { + font-size: 0.9em; + padding-left: 25%; + padding-top: 0.5em; + width: 100%; + } + + .file-exemple code.c-code { + -webkit-user-select: text; /* Chrome all / Safari all */ + -moz-user-select: text; /* Firefox all */ + -ms-user-select: text; /* IE 10+ */ + user-select: text; + } + } + + + </style> +</FavoriteList> diff --git a/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteListCard.tag.html b/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteListCard.tag.html new file mode 100644 index 0000000..6dc72d3 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteListCard.tag.html @@ -0,0 +1,52 @@ +require("../Pagination.tag.html"); +require("./MemberCard.tag.html"); +<FavoriteListCard> + <div class="favoriteList-card-view"> + <div class="name"> + <a href="#/favoriteLists/{opts.favoriteList.id}"> + {opts.favoriteList.name} + </a> + </div> + + <div class="card-actions"> + <a title={__.delete} + onclick={delete}> + <i class="fa fa-times"></i> + </a> + </div> + </div> + + + <script type="es6"> + let session = require("../../js/Session"); + this.installBundle(session, "favoriteList"); + let favoriteListService = require("../../js/FavoriteListService"); + + this.delete = () => { + if (confirm(this.__.deleteMessage)) { + favoriteListService.deleteFavoriteList(this.opts.favoriteList.id).then(() => { + this.opts.onFavoriteListChange(); + }); + } + }; + </script> + + <style> + + favoritelistcard { + display: block; + margin: 5px auto; + border-radius: 4px; + border: 1px solid #13a2ff; + box-shadow: 0 0 1px hsla(0,0%,7%,.6); + padding: 0.5em; + color: #13a2ff; + } + + .favoriteList-card-view { + display: flex; + justify-content: space-between; + } + + </style> +</FavoriteListCard> 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 new file mode 100644 index 0000000..aa4841e --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteLists.tag.html @@ -0,0 +1,120 @@ +require("../Pagination.tag.html"); +require("./FavoriteListCard.tag.html"); +<FavoriteLists> + <div class="container" > + <div show="{loaded}"> + <h1 class="c-heading">{__.title}</h1> + + <div show={favoriteLists.length > 0} > + <div class="o-form-element sort"> + <label class="c-label" for="sort">{__.sort}</label> + <div class="c-input-group"> + <div class="o-field"> + <select class="c-field" + onchange={selectSort}> + <option value="topiaCreateDate">{__.createDate}</option> + <option value="name">{__.name}</option> + </select> + </div> + <button class="c-button c-button--brand" + onclick={toggleSort}> + <i class="fa {pagination.desc ? 'fa-sort-amount-desc' : 'fa-sort-amount-asc'}"></i> + </button> + </div> + </div> + + <Pagination pagination={pagination} onchange="{refresh}"/> + + <FavoriteListCard each={favoriteList in favoriteLists} favorite-list={favoriteList} on-favorite-list-change={parent.refresh}/> + + <Pagination pagination={pagination} onchange="{refresh}"/> + </div> + <div show={favoriteLists.length === 0} class="c-alert c-alert--info"> + {__.noFavoriteList} + </div> + + <div class="actions-right"> + <a class="c-button c-button--success" + href="#/favoriteLists/new"> + {__.addFavoriteList} + <i class="fa fa-plus"></i> + </a> + </div> + </div> + + <script type="es6"> + this.loaded = false; + let session = require("../../js/Session"); + this.installBundle(session, "favoriteList"); + + this.pagination = { + order: "topiaCreateDate", + desc: true, + pageSize: 5, + pageNumber: 0 + }; + this.favoriteLists = []; + + let favoriteListsService = require("../../js/FavoriteListService"); + + this.refresh = () => { + return favoriteListsService.favoriteLists(this.pagination).then((result) => { + this.favoriteLists = result.elements; + Object.assign(this.pagination, result.pagination); + this.loaded = true; + this.update(); + return result; + }); + }; + + this.addFavoriteList = (e) => { + e.preventDefault(); + e.stopPropagation(); + let favoriteList = { + name: this.refs.name.value + }; + + favoriteListsService.createFavoriteList(favoriteList).then(() => { + this.errors = {}; + this.refs.name.value = ""; + this.refresh(); + }, errors => { + this.errors = errors; + this.update(); + }); + }; + + this.refresh(); + + this.toggleSort = () => { + this.pagination.desc = !this.pagination.desc; + this.refresh(); + }; + + this.selectSort = (e) => { + this.pagination.order = e.target.value; + this.refresh(); + }; + + </script> + <style> + + .c-heading { + text-align: center; + } + + .o-form-element.sort .c-label:first-child { + width: 70px; + display: inline-block; + text-align: right; + float: left; + padding-top: 0.5em; + padding-right: 5px; + } + + .o-form-element.sort .c-input-group { + width: 200px; + } + + </style> +</FavoriteLists> diff --git a/pollen-ui-riot-js/src/main/web/tag/favoriteList/MemberCard.tag.html b/pollen-ui-riot-js/src/main/web/tag/favoriteList/MemberCard.tag.html new file mode 100644 index 0000000..bf72e66 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/favoriteList/MemberCard.tag.html @@ -0,0 +1,151 @@ +<MemberCard> + + <div class="member-card-view" if={!editing}> + <div class="info"> + <i class="fa fa-user" aria-hidden="true"></i> + <span if={opts.member.name !== opts.member.email}> + {opts.member.name} - + </span> + {opts.member.email} + </div> + + <div class="member-actions u-xsmall"> + <button class="c-button c-button--info" + title={__.edit} + onclick={startEdition}> + <i class="fa fa-pencil"></i> + </button> + <button class="c-button c-button--error" + title={__.delete} + onclick={delete}> + <i class="fa fa-times"></i> + </button> + </div> + + </div> + + <form class="member-card-edit" if={editing} onsubmit={save}> + <div class="o-form-element"> + <label class="c-label" for="name">{__.name}</label> + <input type="text" + id="name" + ref="name" + class="c-field" + value={opts.member.name}> + </div> + <div class="o-form-element"> + <label class="c-label" for="name">{__.email}</label> + <input type="email" + id="email" + ref="email" + required + class="c-field {c-field--error: errors.email}" + value={opts.member.email}> + <div class="c-hint c-hint--static c-hint--error" each={error in errors.email}>{error}</div> + </div> + <div class="actions"> + <button type="button" + class="c-button c-button--ghost-info" + onclick={cancelEdition}> + <i class="fa fa-undo" aria-hidden="true"></i> + {__.cancel} + </button> + <button type="submit" + class="c-button c-button--info"> + <i class="fa fa-check" aria-hidden="true"></i> + {__.save} + </button> + </div> + </form> + + <script type="es6"> + let session = require("../../js/Session"); + this.installBundle(session, "favoriteList_member"); + let favoriteListService = require("../../js/FavoriteListService"); + this.editing = false; + this.errors = {}; + + this.startEdition = () => { + this.editing = true; + }; + + this.cancelEdition = () => { + this.editing = false; + }; + + this.delete = () => { + if (confirm(this.__.deleteMessage)) { + favoriteListService.deleteMember(this.opts.favoriteList.id, this.opts.member.id).then(() => { + if (this.opts.onMemberChange) { + this.opts.onMemberChange(); + } + }); + } + }; + + this.save = e => { + e.preventDefault(); + e.stopPropagation(); + this.opts.member.name = this.refs.name.value; + this.opts.member.email = this.refs.email.value; + + favoriteListService.saveMemeber(this.opts.favoriteList.id, this.opts.member).then(() => { + this.errors = {}; + this.cancelEdition(); + this.update(); + }, errors => { + this.errors = errors; + this.update(); + }); + }; + + </script> + + <style> + + membercard { + display: block; + margin: 5px auto; + border-radius: 4px; + border: 1px solid #13a2ff; + box-shadow: 0 0 1px hsla(0,0%,7%,.6); + padding: 0.5em; + color: #13a2ff; + } + + .member-card-view { + display: flex; + justify-content: space-between; + } + + .member-actions { + display: flex; + align-items: flex-start; + } + + .member-actions button { + margin-left: 3px; + } + + .member-card-edit .o-form-element .c-label:first-child { + width: 25%; + display: inline-block; + text-align: right; + float: left; + padding-top: 0.5em; + padding-right: 5px; + } + + .member-card-edit .o-form-element .c-field { + width: 75%; + display: inline-block; + } + + .member-card-edit .o-form-element .c-toggle, + .member-card-edit .o-form-element .c-hint { + margin-left: 25%; + } + + </style> + +</MemberCard> -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.