branch develop updated (5842a5b1 -> e6e2712f)
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 5842a5b1 refs #72 modif de la page de résumé (dans un onglet) new e6e2712f UI des des liste de votants (ref #77) The 1 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 e6e2712f4f944568bc1d2335d1e05b1673501b17 Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Wed Jun 21 17:45:02 2017 +0200 UI des des liste de votants (ref #77) Summary of changes: .../pollen/services/bean/FavoriteListBean.java | 20 +- .../services/service/FavoriteListService.java | 36 +- pollen-ui-riot-js/src/main/web/css/main.css | 50 ++ pollen-ui-riot-js/src/main/web/i18n.json | 36 +- pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html | 1 + .../src/main/web/tag/PollenHeader.tag.html | 30 -- .../src/main/web/tag/components/Card.tag.html | 94 ++++ .../web/tag/components/ContextualMenu.tag.html | 68 +++ .../main/web/tag/components/LetterAvatar.tag.html | 10 +- .../src/main/web/tag/components/Search.tag.html | 41 ++ .../web/tag/favoriteList/ChildListCard.tag.html | 146 ++---- .../tag/favoriteList/ChildListEditModal.tag.html | 105 +++++ .../web/tag/favoriteList/FavoriteList.tag.html | 517 ++++----------------- .../web/tag/favoriteList/FavoriteListCard.tag.html | 58 ++- .../favoriteList/FavoriteListEditModal.tag.html | 65 +++ .../web/tag/favoriteList/FavoriteLists.tag.html | 168 +++---- .../web/tag/favoriteList/ImportCsvModal.tag.html | 67 +++ .../web/tag/favoriteList/ImportLdapModal.tag.html | 70 +++ .../main/web/tag/favoriteList/MemberCard.tag.html | 127 ++--- .../web/tag/favoriteList/MemberEditModal.tag.html | 96 ++++ 20 files changed, 985 insertions(+), 820 deletions(-) create mode 100644 pollen-ui-riot-js/src/main/web/tag/components/Card.tag.html create mode 100644 pollen-ui-riot-js/src/main/web/tag/components/ContextualMenu.tag.html create mode 100644 pollen-ui-riot-js/src/main/web/tag/components/Search.tag.html create mode 100644 pollen-ui-riot-js/src/main/web/tag/favoriteList/ChildListEditModal.tag.html create mode 100644 pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteListEditModal.tag.html create mode 100644 pollen-ui-riot-js/src/main/web/tag/favoriteList/ImportCsvModal.tag.html create mode 100644 pollen-ui-riot-js/src/main/web/tag/favoriteList/ImportLdapModal.tag.html create mode 100644 pollen-ui-riot-js/src/main/web/tag/favoriteList/MemberEditModal.tag.html -- 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 e6e2712f4f944568bc1d2335d1e05b1673501b17 Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Wed Jun 21 17:45:02 2017 +0200 UI des des liste de votants (ref #77) --- .../pollen/services/bean/FavoriteListBean.java | 20 +- .../services/service/FavoriteListService.java | 36 +- pollen-ui-riot-js/src/main/web/css/main.css | 50 ++ pollen-ui-riot-js/src/main/web/i18n.json | 36 +- pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html | 1 + .../src/main/web/tag/PollenHeader.tag.html | 30 -- .../src/main/web/tag/components/Card.tag.html | 94 ++++ .../web/tag/components/ContextualMenu.tag.html | 68 +++ .../main/web/tag/components/LetterAvatar.tag.html | 10 +- .../src/main/web/tag/components/Search.tag.html | 41 ++ .../web/tag/favoriteList/ChildListCard.tag.html | 146 ++---- .../tag/favoriteList/ChildListEditModal.tag.html | 105 +++++ .../web/tag/favoriteList/FavoriteList.tag.html | 517 ++++----------------- .../web/tag/favoriteList/FavoriteListCard.tag.html | 58 ++- .../favoriteList/FavoriteListEditModal.tag.html | 65 +++ .../web/tag/favoriteList/FavoriteLists.tag.html | 168 +++---- .../web/tag/favoriteList/ImportCsvModal.tag.html | 67 +++ .../web/tag/favoriteList/ImportLdapModal.tag.html | 70 +++ .../main/web/tag/favoriteList/MemberCard.tag.html | 127 ++--- .../web/tag/favoriteList/MemberEditModal.tag.html | 96 ++++ 20 files changed, 985 insertions(+), 820 deletions(-) diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/FavoriteListBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/FavoriteListBean.java index 9d34b339..200ee182 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/FavoriteListBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/FavoriteListBean.java @@ -34,6 +34,10 @@ public class FavoriteListBean extends PollenBean<FavoriteList> { protected String name; + protected long countChildren; + + protected long countMembers; + public FavoriteListBean() { super(FavoriteList.class); } @@ -61,9 +65,23 @@ public class FavoriteListBean extends PollenBean<FavoriteList> { return name; } - public void setName(String name) { this.name = name; } + public long getCountChildren() { + return countChildren; + } + + public void setCountChildren(long countChildren) { + this.countChildren = countChildren; + } + + public long getCountMembers() { + return countMembers; + } + + public void setCountMembers(long countMembers) { + this.countMembers = countMembers; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/FavoriteListService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/FavoriteListService.java index 90ff4f7d..f80d7a7d 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/FavoriteListService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/FavoriteListService.java @@ -71,6 +71,30 @@ import static org.nuiton.i18n.I18n.l; */ public class FavoriteListService extends PollenServiceSupport { + public FavoriteListBean favoriteListBeanFunction(FavoriteListBean input) { + + + long countChildren = getChildFavoriteListDao() + .forProperties(ChildFavoriteList.PROPERTY_PARENT + "." + FavoriteList.PROPERTY_TOPIA_ID, input.getEntityId()) + .count(); + + input.setCountChildren(countChildren); + + long countMembers = getFavoriteListMemberDao() + .forProperties(FavoriteListMember.PROPERTY_FAVORITE_LIST + "." + FavoriteList.PROPERTY_TOPIA_ID, input.getEntityId()) + .count(); + + input.setCountMembers(countMembers); + + return input; + } + + public ChildFavoriteListBean childFavoriteListBeanFunction(ChildFavoriteListBean input) { + input.setChild(favoriteListBeanFunction(input.getChild())); + + return input; + } + public PaginationResultBean<FavoriteListBean> getFavoriteLists(PaginationParameterBean paginationParameter) { checkIsConnected(); @@ -80,7 +104,7 @@ public class FavoriteListService extends PollenServiceSupport { PaginationParameter page = getFavoriteListPaginationParameter(paginationParameter); PaginationResult<FavoriteList> favoriteLists = getFavoriteListDao().forPollenUserEquals(user).findPage(page); - return toPaginationListBean(FavoriteListBean.class, favoriteLists); + return toPaginationListBean(FavoriteListBean.class, favoriteLists, this::favoriteListBeanFunction); } @@ -92,7 +116,7 @@ public class FavoriteListService extends PollenServiceSupport { PollenUser user = getConnectedUser(); FavoriteList favoriteList = getFavoriteList0(user, favoriteListId); - return toBean(FavoriteListBean.class, favoriteList); + return toBean(FavoriteListBean.class, favoriteList, this::favoriteListBeanFunction); } @@ -137,7 +161,7 @@ public class FavoriteListService extends PollenServiceSupport { getNotificationService().onFavoriteListEdited(user, result); - return toBean(FavoriteListBean.class, result); + return toBean(FavoriteListBean.class, result, this::favoriteListBeanFunction); } @@ -605,7 +629,7 @@ public class FavoriteListService extends PollenServiceSupport { PaginationParameter page = getFavoriteListPaginationParameter(paginationParameter); PaginationResult<ChildFavoriteList> children = getChildFavoriteListDao().forParentEquals(favoriteList).findPage(page); - return toPaginationListBean(ChildFavoriteListBean.class, children); + return toPaginationListBean(ChildFavoriteListBean.class, children, this::childFavoriteListBeanFunction); } @@ -620,7 +644,7 @@ public class FavoriteListService extends PollenServiceSupport { FavoriteList favoriteList = getFavoriteList0(user, favoriteListId); ChildFavoriteList child = getChildList0(favoriteList, childListId); - return toBean(ChildFavoriteListBean.class, child); + return toBean(ChildFavoriteListBean.class, child, this::childFavoriteListBeanFunction); } @@ -665,7 +689,7 @@ public class FavoriteListService extends PollenServiceSupport { ChildFavoriteList result = saveChildFavoriteList(favoriteList, childList); commit(); - return toBean(ChildFavoriteListBean.class, result); + return toBean(ChildFavoriteListBean.class, result, this::childFavoriteListBeanFunction); } diff --git a/pollen-ui-riot-js/src/main/web/css/main.css b/pollen-ui-riot-js/src/main/web/css/main.css index d04b499b..701144db 100644 --- a/pollen-ui-riot-js/src/main/web/css/main.css +++ b/pollen-ui-riot-js/src/main/web/css/main.css @@ -262,6 +262,36 @@ time-picker .next:hover { background-color: var(--brand); } +/* The container <div> - needed to position the dropdown content */ +.dropdown { + position: relative; + display: inline-block; +} + +/* Dropdown Content (Hidden by Default) */ +.dropdown-content { + display: none; + position: absolute; + min-width: 188px; +} + +.dropdown-content.right { + right: 10px; +} + +/* Links inside the dropdown */ +.dropdown-content a { + padding: 12px 16px; + text-decoration: none; + display: block; +} + +/* Show the dropdown menu on hover */ +.dropdown:hover .dropdown-content { + display: block; + z-index: 1; +} + .dropdown-content { background-color: var(--dropdown); box-shadow: 0 8px 16px 0 var(--dropdown-shadow); @@ -315,3 +345,23 @@ pollenfooter a { pollenfooter a:hover { color: var(--footer-text-hover); } + +.brand { + color: var(--brand); +} + +.info { + color: var(--info); +} + +.warning { + color: var(--warning); +} + +.success { + color: var(--success); +} + +.error { + color: var(--error); +} diff --git a/pollen-ui-riot-js/src/main/web/i18n.json b/pollen-ui-riot-js/src/main/web/i18n.json index 01f0de84..b256996f 100644 --- a/pollen-ui-riot-js/src/main/web/i18n.json +++ b/pollen-ui-riot-js/src/main/web/i18n.json @@ -372,12 +372,21 @@ "choice_fileSizeMax_title": "Fichier trop lourd", "choice_fileSizeMax_message": "Le fichier « {0} » de taille de {1} ne doit pas dépasser {2}.", "favoriteList_title": "Mes listes de votants", + "favoriteList_one": "liste de votants", + "favoriteList_many": "listes de votants", "favoriteList_addFavoriteList": "Ajouter une nouvelle liste de votants", "favoriteList_export": "Exporter les listes de votants", + "favoriteList_children": "sous-listes", + "favoriteList_child": "sous-liste", + "favoriteList_members": "membres", + "favoriteList_member": "membre", + "favoriteList_noMember": "Aucun membre", + "favoriteList_new": "Nouvelle liste", + "favoriteList_edit": "Modifier cette liste", "favoriteList_name": "Nom", "favoriteList_name_placdeholder": "Renseignez le nom de la nouvelle liste", "favoriteList_add": "Ajouter", - "favoriteList_sort": "trier par", + "search_label": "Rechercher", "favoriteList_createDate": "Date de création", "favoriteList_name": "Nom", "favoriteList_email": "Courriel", @@ -388,16 +397,14 @@ "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_importCsv": "Importer un fichier CSV", "favoriteList_member_csvFile": "Fichier des membres", "favoriteList_member_csvFile_exemple": "# Courriel;Nom;Poids\ndupond@domaine.fr;Jean Dupond;1.00\npseudo@bleu.fr;Arnaud Lemaitre;4.50\nmiller@courriel.com;Benjamin Miller;3.00", "favoriteList_member_csvFile_exemple_label": "Exemple de fichier", "favoriteList_member_csvFile_exemple_detail": "Si le poids est omis, sa valeur par défaut est 1", - "favoriteList_member_importLdap": "Importer des membres à partir d'un annuaire LDAP", + "favoriteList_member_importLdap": "Importer un annuaire LDAP", "favoriteList_member_ldap": "Adresse de l'annuaire LDAP", "favoriteList_member_ldap_exemple": "ldap://ldap.domaine.org/ou=companies,o=entreprise?cn,mail?sub?(objectclass=people)\nldaps://login:password@ldap.domaine.org/ou=companies,o=libre-entreprise?cn,mail?sub?(objectclass=people)", "favoriteList_member_ldap_exemple_label": "Exemple d'adresse LDAP", @@ -424,6 +431,7 @@ "favoriteList_childList_cancel": "Annuler", "favoriteList_childList_save": "Enregistrer", "favoriteList_childList_add": "Ajouter", + "favoriteList_childList_edit": "Modifier la sous-liste", "favoriteList_childList_delete": "Retirer la sous-liste", "favoriteList_childList_deleteMessage": "Retirer la sou-liste ?", "favoriteList_importFavoriteLists": "Importer des listes de votants", @@ -838,11 +846,21 @@ "choice_fileSizeMax_title": "File to big", "choice_fileSizeMax_message": "File \"{0}\" for size {1} can't be over {2}.", "favoriteList_title": "My favorite lists", + "favoriteList_one": "favorite list", + "favoriteList_many": "favorite lists", "favoriteList_addFavoriteList": "Add new favorite list", "favoriteList_export": "Export favorite lists", + "favoriteList_children": "sub-lists", + "favoriteList_child": "sub-list", + "favoriteList_members": "members", + "favoriteList_member": "member", + "favoriteList_noMember": "No membre", + "favoriteList_new": "New list", + "favoriteList_edit": "Edit this list", "favoriteList_name": "Name", "favoriteList_name_placdeholder": "Enter new list name", "favoriteList_add": "Add", + "search_label": "Search", "favoriteList_sort": "Sort by", "favoriteList_createDate": "Creation Date", "favoriteList_email": "Email", @@ -850,19 +868,16 @@ "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_importCsv": "Import from CSV file", "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 example", "favoriteList_member_csvFile_exemple_detail": "If weight is mising, default value is 1", - "favoriteList_member_importLdap": "Import members from LDAP repository", + "favoriteList_member_importLdap": "Import from LDAP repository", "favoriteList_member_ldap": "LDAP repository address", "favoriteList_member_ldap_exemple": "ldap://ldap.domaine.org/ou=companies,o=entreprise?cn,mail?sub?(objectclass=people)\nldaps://login:password@ldap.domaine.org/ou=companies,o=libre-entreprise?cn,mail?sub?(objectclass=people)", "favoriteList_member_ldap_exemple_label": "LDAP example", @@ -889,6 +904,7 @@ "favoriteList_childList_cancel": "Cancel", "favoriteList_childList_save": "Save", "favoriteList_childList_add": "Ajouter", + "favoriteList_childList_edit": "Edit sub-list", "favoriteList_childList_delete": "Remove sub-list", "favoriteList_childList_deleteMessage": "Remove sub-list ?", "favoriteList_importFavoriteLists": "Import favorite lists", 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 8bf594ed..56c85f3d 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 @@ -239,6 +239,7 @@ require("./popup/InformationPopup.tag.html"); position: fixed; bottom: 20px; right: 0px; + z-index: 2; } </style> 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 dda1dc12..f91e4474 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 @@ -120,36 +120,6 @@ require("./HeaderI18n.tag.html"); cursor: pointer; } - /* The container <div> - needed to position the dropdown content */ - .dropdown { - position: relative; - display: inline-block; - } - - /* Dropdown Content (Hidden by Default) */ - .dropdown-content { - display: none; - position: absolute; - min-width: 188px; - } - - .dropdown-content.right { - right: 10px; - } - - /* Links inside the dropdown */ - .dropdown-content a { - padding: 12px 16px; - text-decoration: none; - display: block; - } - - /* Show the dropdown menu on hover */ - .dropdown:hover .dropdown-content { - display: block; - z-index: 1; - } - @media (max-width: 640px) { .user-name { display: none; diff --git a/pollen-ui-riot-js/src/main/web/tag/components/Card.tag.html b/pollen-ui-riot-js/src/main/web/tag/components/Card.tag.html new file mode 100644 index 00000000..4f825b02 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/components/Card.tag.html @@ -0,0 +1,94 @@ +require("./LetterAvatar.tag.html"); +<Card> + + <div class="card-actions"> + <a class="info" + title={parent.__.edit} + onclick={opts.onedit}> + <i class="fa fa-pencil"></i> + </a> + <a class="error" + title={parent.__.delete} + onclick={opts.ondelete}> + <i class="fa fa-times"></i> + </a> + </div> + + <div class="card-content"> + + <div if={!opts.href} class="card-avatar"> + <LetterAvatar name={opts.name} rounded="true"/> + </div> + + <a if={opts.href} href={opts.href} class="card-avatar"> + <LetterAvatar name={opts.name} rounded="true"/> + </a> + + <div class="card-name" title={opts.name}> + {opts.name} + </div> + + <div class="card-detail"> + <yield/> + + </div> + + <div class="card-weight" if={opts.weight}> + <i class="fa fa-balance-scale" aria-hidden="true"></i> + {opts.weight} + </div> + </div> + + <style> + card { + position: relative; + display: block; + padding: 10px 0; + margin: 5px; + box-shadow: 0 0 10px hsla(0,0%,7%,.6); + width: 180px; + overflow: hidden; + } + + .card-actions { + position: absolute; + top: 0; + right: 0; + transform: translate3d(32px, 0px, 0px); + transition: transform 0.6s; + } + + card:hover .card-actions { + transform: translate3d(0px, 0px, 0px); + } + + .card-content { + display: flex; + flex-direction: column; + align-items: center; + } + + .card-avatar { + margin: 5px 0; + font-size: 3em; + } + + .card-name { + width: 100%; + font-size: 1.5em; + white-space: nowrap; + overflow: hidden; + text-align: center; + text-overflow: ellipsis; + } + + .card-detail { + width: 100%; + } + + .card-weight { + + } + + </style> +</Card> 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 new file mode 100644 index 00000000..e6458f6f --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/components/ContextualMenu.tag.html @@ -0,0 +1,68 @@ +<ContextualMenu> + <i class="icon fa fa-plus"></i> + + <div class="links"> + <yield/> + </div> + + <style> + contextualmenu { + position: fixed; + right: 4em; + bottom: 4em; + display: block; + border-radius: 1.5em; + overflow: hidden; + background-color: var(--success); + color:var(--background); + } + + contextualmenu:hover { + width: inherit; + height: inherit; + } + + .icon { + font-size: 1.5em; + padding: 0.5em; + width: 2em; + height: 2em; + text-align: center; + } + + .links { + max-width: 0; + max-height: 0; + transition: max-width 1s, max-height 1s; + + } + + contextualmenu:hover .links { + max-width: 500px; + max-height: 500px; + transition: max-width 1s, max-height 1s; + } + + .links a { + padding: 0.75em 1em; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + display: block; + color:var(--background); + } + + .links a:hover { + background-color: var(--success-hover) + } + + @media (max-width: 640px) { + contextualmenu { + right: 1em; + bottom: 1em; + } + } + + </style> + +</ContextualMenu> diff --git a/pollen-ui-riot-js/src/main/web/tag/components/LetterAvatar.tag.html b/pollen-ui-riot-js/src/main/web/tag/components/LetterAvatar.tag.html index 9a17d9a9..2edbe438 100644 --- a/pollen-ui-riot-js/src/main/web/tag/components/LetterAvatar.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/components/LetterAvatar.tag.html @@ -8,14 +8,19 @@ <script type="es6"> this.redraw = () => { - this.avatarLetter = this.opts.name[0].toUpperCase(); + let nameSplit = this.opts.name.split(); + this.avatarLetter = nameSplit[0][0].toUpperCase(); + let secondLetter = (nameSplit.length > 1 ? nameSplit[1][0] : nameSplit[0][1]).toUpperCase(); let letterIndex = this.avatarLetter.charCodeAt() - 64; - let hue = (360 / 26) * letterIndex; + let secondIndex = secondLetter.charCodeAt() - 64; + let hue = (360 / (26 * 26)) * (secondIndex * 26 + letterIndex); this.backgroundColor = "hsl(" + hue + ", 68%, 48%)"; }; this.on("update", this.redraw); + this.redraw(); + </script> <style> @@ -36,7 +41,6 @@ fontSize: 1.70em; } - </style> </LetterAvatar> diff --git a/pollen-ui-riot-js/src/main/web/tag/components/Search.tag.html b/pollen-ui-riot-js/src/main/web/tag/components/Search.tag.html new file mode 100644 index 00000000..7865099e --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/components/Search.tag.html @@ -0,0 +1,41 @@ +<Search> + <div class="o-form-element search"> + <div class="o-field o-field--icon-left o-field--icon-right"> + <i class="fa fa-fw fa-search c-icon"></i> + <input class="c-field" + id="search" + name="search" + ref="search" + oninput={search} + placeholder={__.label} + type="text"> + <i class="fa fa-fw fa-times c-icon" + if={refs && refs.search.value} + onclick={deleteSearch}></i> + </div> + </div> + + <script type="es6"> + + let session = require("../../js/Session"); + this.installBundle(session, "search"); + + this.search = () => { + if (this.searchTimeoutId) { + window.clearTimeout(this.searchTimeoutId); + } + this.searchTimeoutId = window.setTimeout(() => { + delete this.searchTimeoutId; + if (this.opts.onsearch) { + this.opts.onsearch(); + } + }, 300); + }; + + this.deleteSearch = () => { + this.refs.search.value = ""; + this.search(); + }; + + </script> +</Search> diff --git a/pollen-ui-riot-js/src/main/web/tag/favoriteList/ChildListCard.tag.html b/pollen-ui-riot-js/src/main/web/tag/favoriteList/ChildListCard.tag.html index 43f9bd55..c5001534 100644 --- a/pollen-ui-riot-js/src/main/web/tag/favoriteList/ChildListCard.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/favoriteList/ChildListCard.tag.html @@ -1,77 +1,40 @@ -<ChildListCard class="card"> - - <div class="child-list-card-view" if={!editing}> - <div class="info"> - <a href="#favoriteLists/{opts.childList.child.id}"> - <i class="fa fa-users" aria-hidden="true"></i> - {opts.childList.child.name} - </a> - - {opts.childList.weight} - </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="childList-card-edit" if={editing} onsubmit={save}> - <div class="o-form-element"> - <label class="c-label" for="child">{__.child}</label> - <input type="text" - id="child" - ref="child" - class="c-field" - value={opts.childList.child.name} - disabled> - </div> - <div class="o-form-element"> - <label class="c-label" for="weight">{__.weight}</label> - <input type="number" - id="weight" - ref="weight" - required - value={opts.childList.weight} - step="0.01" - class="c-field {c-field--error : errors.weight}"> - </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> +require("../components/Card.tag.html"); +require("./ChildListEditModal.tag.html"); + +<ChildListCard> + + <Card name={opts.childList.child.name} + weight={opts.childList.weight} + ondelete={delete} + onedit={edit}> + <div> + {parent.opts.childList.child.countChildren} <i class="fa fa-users"></i> + </div> + <div> + {parent.opts.childList.child.countMembers} <i class="fa fa-user"></i> + </div> + </card> + + <ChildListEditModal ref="editModal" + child-list={opts.childList} + favorite-list={opts.favoriteList}/> <script type="es6"> let session = require("../../js/Session"); this.installBundle(session, "favoriteList_childList"); let favoriteListService = require("../../js/FavoriteListService"); - this.editing = false; - this.errors = {}; - this.startEdition = () => { - this.editing = true; - }; - - this.cancelEdition = () => { - this.editing = false; + this.edit = () => { + this.refs.editModal.open().then(() => { + if (this.opts.onChildListChange) { + this.opts.onChildListChange(); + } else { + this.update(); + } + }, () => { + this.update(); + }); + this.update(); }; this.delete = () => { @@ -86,56 +49,13 @@ }); }; - this.save = e => { - e.preventDefault(); - e.stopPropagation(); - this.opts.childList.weight = this.refs.weight.value; - - favoriteListService.saveChildList(this.opts.favoriteList.id, this.opts.childList).then(() => { - this.errors = {}; - this.cancelEdition(); - this.update(); - }, errors => { - this.errors = errors; - this.update(); - }); - }; - </script> <style> - .child-list-card-view { + .card-detail { display: flex; - justify-content: space-between; - } - - .child-list-actions { - display: flex; - align-items: flex-start; - } - - .child-list-actions button { - margin-left: 3px; - } - - .child-list-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; - } - - .child-list-card-edit .o-form-element .c-field { - width: 75%; - display: inline-block; - } - - .child-list-card-edit .o-form-element .c-toggle, - .child-list-card-edit .o-form-element .c-hint { - margin-left: 25%; + justify-content: space-around; } </style> diff --git a/pollen-ui-riot-js/src/main/web/tag/favoriteList/ChildListEditModal.tag.html b/pollen-ui-riot-js/src/main/web/tag/favoriteList/ChildListEditModal.tag.html new file mode 100644 index 00000000..8c569d6d --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/favoriteList/ChildListEditModal.tag.html @@ -0,0 +1,105 @@ +require("../popup/Modal.tag.html"); + +<ChildListEditModal> + <Modal ref="modal" + header={opts.childList.id ? __.edit : __.new} + label={opts.childList.id ? __.save : __.add} + type="success" + onsubmit={save}> + <div class="o-form-element"> + <label class="c-label" for="childList">{parent.__.child}</label> + <select if={!parent.opts.childList.id} + id="childList" + ref="childList" + placeholder={parent.__.member_name_placeholder} + required + disabled={parent.opts.childList.id} + class="c-field {c-field--error : parent.errors.child}"> + <option each={list, index in parent.favoriteLists} value={index}>{list.name}</option> + </select> + <input if={parent.opts.childList.id} + type="text" + id="childList" + ref="childList" + class="c-field" + value={parent.opts.childList.child.name} + disabled> + </div> + <div class="o-form-element"> + <label class="c-label" for="childListWeight">{parent.__.weight}</label> + <input type="number" + id="childListWeight" + ref="childListWeight" + required + value={parent.opts.childList.weight || 1} + step="0.01" + class="c-field {c-field--error : parent.errors.weight}"> + </div> + </Modal> + + <script type="es6"> + let session = require("../../js/Session"); + let Message = require("../../js/Message"); + this.installBundle(session, "favoriteList_childList"); + let favoriteListService = require("../../js/FavoriteListService"); + + this.favoriteLists = []; + + if (!this.opts.childList) { + this.opts.childList = {}; + } + + this.errors = {}; + + this.open = () => { + if (!this.opts.childList.id) { + this.refs.modal.refs.childList.value = 0; + this.refs.modal.refs.childListWeight.value = "1.00"; + favoriteListService.favoriteLists({ + order: "name", + desc: false, + pageSize: -1, + pageNumber: 0 + }).then(result => { + this.favoriteLists = result.elements; + this.update(); + }); + } + return this.refs.modal.open(); + }; + + this.save = () => { + + let childList = {}; + Object.assign(childList, this.opts.childList); + childList.weight = this.refs.modal.refs.childListWeight.value; + + let promise; + if (childList.id) { + promise = favoriteListService.saveChildList(this.opts.favoriteList.id, childList).then(() => { + this.errors = {}; + }, errors => { + this.errors = errors; + this.bus.trigger("message", new Message(errors, "error")); + this.update(); + return Promise.reject(); + }); + } else { + childList.child = this.favoriteLists[this.refs.modal.refs.childList.value]; + + promise = favoriteListService.addChildList(this.opts.favoriteList.id, childList).then(() => { + this.errors = {}; + }, errors => { + this.errors = errors; + this.bus.trigger("message", new Message(errors, "error")); + this.update(); + return Promise.reject(); + }); + } + + return promise; + }; + + </script> + +</ChildListEditModal> 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 f038cb97..6705e976 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 @@ -1,255 +1,60 @@ -require("../Pagination.tag.html"); require("./MemberCard.tag.html"); require("./ChildListCard.tag.html"); +require("./MemberEditModal.tag.html"); +require("./ImportCsvModal.tag.html"); +require("./ImportLdapModal.tag.html"); +require("./ChildListEditModal.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}> + <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> - <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/> - <h3 class="c-heading">{__.childrenLists}</h3> - <div show={childrenLists.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={selectSortChildrenLists}> - <option value="topiaCreateDate">{__.createDate}</option> - <option value="name">{__.name}</option> - <option value="weight">{__.weight}</option> - </select> - </div> - <button class="c-button c-button--brand" - onclick={toggleSortChildrenLists}> - <i class="fa {paginationChildrenLists.desc ? 'fa-sort-amount-desc' : 'fa-sort-amount-asc'}"></i> - </button> - </div> - </div> - - <Pagination pagination={paginationChildrenLists} onchange="{refresh}"/> + </h1> + <div show={members.length > 0} > + <Search onsearch={refresh}/> + <div class="elements"> <ChildListCard each={childList in childrenLists} child-list={childList} favorite-list={parent.favoriteList} on-child-list-change={parent.refresh}/> - - <Pagination pagination={paginationChildrenLists} onchange="{refresh}"/> - </div> - <div show={childrenLists.length === 0} class="c-alert c-alert--info"> - {__.noChildList} + <MemberCard each={member in members} member={member} favorite-list={parent.favoriteList} on-member-change={parent.refresh}/> </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 : addMemberErrors.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 : addMemberErrors.email}"> - </div> - <div class="o-form-element"> - <label class="c-label" for="email">{__.member_weight}</label> - <input type="number" - id="weight" - ref="weight" - required - value="1.00" - step="0.01" - class="c-field {c-field--error : addMemberErrors.weight}"> - </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 {c-field--error : csvErrors.error}"> - <div class="exemple"> - {__.member_csvFile_exemple_label} - <code class="c-code c-code--multiline">{__.member_csvFile_exemple}</code> - {__.member_csvFile_exemple_detail} - </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 {c-field--error : ldapErrors.error}"> - <div class="exemple"> - {__.member_ldap_exemple_label} - <code class="c-code c-code--multiline">{__.member_ldap_exemple}</code> - {__.member_ldap_exemple_detail} - </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={addChildList}> - <h3 class="c-heading">{__.childList_new}</h3> - <div class="o-form-element"> - <label class="c-label" for="childList">{__.childList_child}</label> - <select type="text" - id="childList" - ref="childList" - placeholder={__.member_name_placeholder} - required - class="c-field {c-field--error : childListErrors.child}"> - <option each={list, index in favoriteLists} value={index}>{list.name}</option> - </select> - </div> - <div class="o-form-element"> - <label class="c-label" for="childListWeight">{__.childList_weight}</label> - <input type="number" - id="childListWeight" - ref="childListWeight" - required - value="1.00" - step="0.01" - class="c-field {c-field--error : childListErrors.weight}"> - </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-users" aria-hidden="true"></i> - {__.childList_add} - </button> - </div> - </form> - </virtual> + </div> + + <ContextualMenu> + <a onclick={parent.addMember} > + {parent.__.member_new} + </a> + <a onclick={parent.importCsv} > + {parent.__.member_importCsv} + </a> + <a onclick={parent.importLdap} > + {parent.__.member_importLdap} + </a> + <a onclick={parent.createChildList} > + {parent.__.childList_new} + </a> + </ContextualMenu> + + <MemberEditModal ref="createMemberModal" + favorite-list={favoriteList} /> + + <ImportCsvModal ref="importCsvModal" + favorite-list={favoriteList}/> + + <ImportLdapModal ref="importLdapModal" + favorite-list={favoriteList}/> + + <ChildListEditModal ref="createChildListModal" + favorite-list={favoriteList}/> </div> </div> @@ -258,22 +63,16 @@ require("./ChildListCard.tag.html"); let route = require("riot-route"); this.installBundle(session, "favoriteList"); let favoriteListService = require("../../js/FavoriteListService"); - this.addType = "member"; - this.errors = {}; - this.addMemberErrors = {}; - this.csvErrors = {}; - this.ldapErrors = {}; - this.childListErrors = {}; this.pagination = { - order: "topiaCreateDate", - desc: true, - pageSize: 5, + order: "name", + desc: false, + pageSize: -1, pageNumber: 0 }; this.paginationChildrenLists = { - order: "topiaCreateDate", - desc: true, - pageSize: 5, + order: "child.name", + desc: false, + pageSize: -1, pageNumber: 0 }; this.favoriteList = { @@ -281,7 +80,6 @@ require("./ChildListCard.tag.html"); }; this.members = []; this.childrenLists = []; - this.favoriteLists = []; this.delete = () => { if (this.favoriteList.id) { @@ -295,33 +93,35 @@ require("./ChildListCard.tag.html"); } }; - this.save = e => { - e.preventDefault(); - e.stopPropagation(); - this.favoriteList.name = this.refs.name.value; + this.addMember = () => { + this.refs.createMemberModal.open().then(() => { + this.update(); + this.refresh(); + }, () => {}); + this.update(); + }; - if (this.favoriteList.id) { - favoriteListService.saveFavoriteList(this.favoriteList).then(() => { - this.errors = {}; - this.refresh(); - }, errors => { - this.errors = errors; - this.bus.trigger("message", errors); - this.update(); - }); - } else { - favoriteListService.createFavoriteList(this.favoriteList).then((result) => { - route("/favoriteLists/" + result.id); - }, errors => { - this.errors = errors; - this.bus.trigger("message", errors); - this.update(); - }); - } + this.importCsv = () => { + this.refs.importCsvModal.open().then(() => { + this.update(); + this.refresh(); + }, () => {}); + this.update(); }; - this.onAddTypeChange = () => { - this.addType = this.refs.addType.value; + this.importLdap = () => { + this.refs.importLdapModal.open().then(() => { + this.update(); + this.refresh(); + }, () => {}); + this.update(); + }; + + this.createChildList = () => { + this.refs.createChildListModal.open().then(() => { + this.refresh(); + }, () => {}); + this.update(); }; @@ -330,20 +130,13 @@ require("./ChildListCard.tag.html"); Promise.all([ favoriteListService.favoriteList(this.favoriteList.id), favoriteListService.members(this.favoriteList.id, this.pagination), - favoriteListService.childrenLists(this.favoriteList.id, this.paginationChildrenLists), - favoriteListService.favoriteLists({ - order: "name", - desc: false, - pageSize: -1, - pageNumber: 0 - }) + favoriteListService.childrenLists(this.favoriteList.id, this.paginationChildrenLists) ]).then((results) => { this.favoriteList = results[0]; this.members = results[1].elements; Object.assign(this.pagination, results[1].pagination); this.childrenLists = results[2].elements; Object.assign(this.paginationChildrenLists, results[2].pagination); - this.favoriteLists = results[3].elements; this.loaded = true; this.update(); return this.favoriteList; @@ -353,156 +146,22 @@ require("./ChildListCard.tag.html"); } }; - this.addMember = (e) => { - e.preventDefault(); - e.stopPropagation(); - let member = { - name: this.refs.nameMember.value, - email: this.refs.email.value, - weight: this.refs.weight.value - }; - - favoriteListService.addMember(this.favoriteList.id, member).then(() => { - this.addMemeberErrors = {}; - this.refs.nameMember.value = ""; - this.refs.email.value = ""; - this.refs.weight.value = "1.00"; - this.refresh(); - }, errors => { - this.addMemberErrors = errors; - this.bus.trigger("message", 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.csvErrors = {}; - this.refs.csvFile.value = ""; - this.refresh(); - }, errors => { - this.csvErrors = errors; - this.bus.trigger("message", errors); - this.update(); - }); - }; - - this.importLdap = (e) => { - e.preventDefault(); - e.stopPropagation(); - let ldap = this.refs.ldapUrl.value; - - favoriteListService.importLdap(this.favoriteList.id, ldap).then(() => { - this.ldapErrors = {}; - this.refs.nameMember.value = ""; - this.refs.email.value = ""; - this.refresh(); - }, errors => { - this.ldapErrors = errors; - this.bus.trigger("message", errors); - this.update(); - }); - }; - - this.addChildList = (e) => { - e.preventDefault(); - e.stopPropagation(); - let childList = { - child: this.favoriteLists[this.refs.childList.value], - weight: this.refs.childListWeight.value - }; - - favoriteListService.addChildList(this.favoriteList.id, childList).then(() => { - this.childListErrors = {}; - this.refs.childList.value = ""; - this.refs.childListWeight.value = "1.00"; - this.refresh(); - }, errors => { - this.childListErrors = errors; - this.bus.trigger("message", 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.toggleSortChildrenLists = () => { - this.paginationChildrenLists.desc = !this.paginationChildrenLists.desc; - this.refresh(); - }; - - this.selectSortChildrenLists = (e) => { - this.paginationChildrenLists.order = e.target.value; - this.refresh(); - }; - this.refresh(); </script> <style> - h1.c-heading { + .c-heading, + .c-heading .c-heading__sub { 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%; - } - - .exemple { - font-size: 0.9em; - padding-left: 25%; - padding-top: 0.5em; - width: 100%; + .elements { + display: flex; + flex-wrap: wrap; + justify-content: flex-start; } - - .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; - } - - @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; - } - } - + </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 index 6292dd8d..52d3ac0d 100644 --- 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 @@ -1,20 +1,21 @@ -require("../Pagination.tag.html"); -require("./MemberCard.tag.html"); -<FavoriteListCard class="card"> - <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> +require("../components/Card.tag.html"); +require("./FavoriteListEditModal.tag.html"); +<FavoriteListCard> + + <Card name={opts.favoriteList.name} + href="#favoriteLists/{opts.favoriteList.id}" + ondelete={delete} + onedit={edit}> + <div> + {parent.opts.favoriteList.countChildren} <i class="fa fa-users"></i> + </div> + <div> + {parent.opts.favoriteList.countMembers} <i class="fa fa-user"></i> + </div> + </Card> + + <FavoriteListEditModal ref="editModal" + favorite-list={opts.favoriteList}/> <script type="es6"> @@ -22,23 +23,36 @@ require("./MemberCard.tag.html"); this.installBundle(session, "favoriteList"); let favoriteListService = require("../../js/FavoriteListService"); + this.edit = () => { + this.refs.editModal.open().then(() => { + if (this.opts.onFavoriteListChange) { + this.opts.onFavoriteListChange(); + } else { + this.update(); + } + }, () => {this.update();}); + this.update(); + }; + this.delete = () => { this.confirm(this.__.deleteMessage).then((confirm) => { if (confirm) { favoriteListService.deleteFavoriteList(this.opts.favoriteList.id).then(() => { - this.opts.onFavoriteListChange(); + if (this.opts.onFavoriteListChange) { + this.opts.onFavoriteListChange(); + } }); } }); }; + </script> <style> - - .favoriteList-card-view { + .card-detail { display: flex; - justify-content: space-between; + justify-content: space-around; } - </style> + </FavoriteListCard> diff --git a/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteListEditModal.tag.html b/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteListEditModal.tag.html new file mode 100644 index 00000000..c122f388 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteListEditModal.tag.html @@ -0,0 +1,65 @@ +require("../popup/Modal.tag.html"); + +<FavoriteListEditModal> + <Modal ref="modal" + header={opts.favoriteList ? __.edit : __.new} + label={__.save} + type="success" + onsubmit={save}> + <div class="o-form-element"> + <label class="c-label" for="name">{parent.__.name}</label> + <input type="text" + id="name" + ref="name" + class="c-field" + placeholder={parent.__.name_placeholder} + value={parent.opts.favoriteList.name}> + </div> + </Modal> + + <script type="es6"> + let session = require("../../js/Session"); + let route = require("riot-route"); + let Message = require("../../js/Message"); + this.installBundle(session, "favoriteList"); + let favoriteListService = require("../../js/FavoriteListService"); + + if (!this.opts.favoriteList) { + this.opts.favoriteList = {}; + } + + this.errors = {}; + + this.open = () => { + return this.refs.modal.open(); + }; + + this.save = () => { + let favoriteList = {}; + Object.assign(favoriteList, this.opts.favoriteList); + favoriteList.name = this.refs.modal.refs.name.value; + + let promise; + if (favoriteList.id) { + promise = favoriteListService.saveFavoriteList(favoriteList).then(() => { + this.errors = {}; + }, errors => { + this.errors = errors; + this.bus.trigger("message", new Message(errors, "error")); + this.update(); + }); + } else { + promise = favoriteListService.createFavoriteList(favoriteList).then((result) => { + route("/favoriteLists/" + result.id); + }, errors => { + this.errors = errors; + this.bus.trigger("message", new Message(errors, "error")); + this.update(); + }); + } + return promise; + }; + + </script> + +</FavoriteListEditModal> 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 3060fafd..37495a23 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 @@ -1,74 +1,54 @@ -require("../Pagination.tag.html"); +require("../components/Search.tag.html"); +require("../components/ContextualMenu.tag.html"); require("./FavoriteListCard.tag.html"); +require("./FavoriteListEditModal.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> + <h1 class="c-heading">{__.title} + <div class="c-heading__sub"> + {pagination.count === 0 ? __.noFavoriteList : (pagination.count + " " + (pagination.count === 1 ? __.one : __.many))} + <a class="c-button c-button--info" + if={pagination.count > 0} + href="{session.configuration.endPoint}/v1/favoriteLists/exports" + target="_blank" + title={__.export}> + <i class="fa fa-download"></i> + </a> </div> + </h1> - <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 show={pagination.count > 0} > + <Search onsearch={refresh}/> + <div class="elements"> + <FavoriteListCard each={favoriteList in favoriteLists} favorite-list={favoriteList} on-favorite-list-change={parent.refresh}/> + </div> </div> - <div class="actions-right"> - <a class="c-button c-button--info" - if={pagination.count > 0} - href="{session.configuration.endPoint}/v1/favoriteLists/exports" - target="_blank"> - <i class="fa fa-download"></i> - {__.export} - </a> - <a class="c-button c-button--success" - href="#/favoriteLists/new"> - {__.addFavoriteList} - <i class="fa fa-plus"></i> - </a> - </div> - <hr/> - <form class="form-add" onsubmit={import}> - <h3 class="c-heading">{__.importFavoriteLists}</h3> + <ContextualMenu> + <a onclick={parent.addFavoriteList}> + {parent.__.addFavoriteList} + </a> + <a onclick={parent.openImportModal} > + {parent.__.importFavoriteLists} + </a> + </ContextualMenu> + + <Modal ref="importModal" onsubmit={import} header={__.importFavoriteLists} label={__.import} type="success"> <div class="o-form-element"> - <label class="c-label" for="importFile">{__.import_file}</label> + <label class="c-label" for="importFile">{parent.__.import_file}</label> <input type="file" id="importFile" ref="importFile" required - class="c-field {c-field--error : importErrors.error}"> + class="c-field {c-field--error : parent.importErrors.error}"> <div class="exemple"> - {__.import_file_detail} + {parent.__.import_file_detail} </div> </div> - <div class="actions-right"> - <button class="c-button c-button--success" - type="submit"> - <i class="fa fa-upload" aria-hidden="true"></i> - {__.import} - </button> - </div> - </form> + </Modal> + + <FavoriteListEditModal ref="createFavoriteListModal"> </div> </div> @@ -79,16 +59,17 @@ require("./FavoriteListCard.tag.html"); this.installBundle(this.session, "favoriteList"); this.pagination = { - order: "topiaCreateDate", - desc: true, - pageSize: 5, + order: "name", + desc: false, + pageSize: -1, pageNumber: 0 }; this.favoriteLists = []; this.importErrors = {}; this.refresh = () => { - return favoriteListsService.favoriteLists(this.pagination).then((result) => { + let search = this.refs.search && this.refs.search.value; + return favoriteListsService.favoriteLists(this.pagination, search).then((result) => { this.favoriteLists = result.elements; Object.assign(this.pagination, result.pagination); this.loaded = true; @@ -97,33 +78,18 @@ require("./FavoriteListCard.tag.html"); }); }; - 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.addFavoriteList = () => { + this.refs.createFavoriteListModal.open().then(() => { this.refresh(); - }, errors => { - this.errors = errors; - this.update(); - }); + }, () => {}); + 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(); + this.openImportModal = () => { + this.refs.importModal.open(); + this.update(); }; this.import = (e) => { @@ -144,48 +110,26 @@ require("./FavoriteListCard.tag.html"); </script> <style> - h1.c-heading { + .c-heading, + .c-heading .c-heading__sub { 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%; + .c-heading .c-heading__sub .c-button { + opacity: inherit; + font-size: 1rem; } .exemple { font-size: 0.9em; - padding-left: 25%; padding-top: 0.5em; 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; - } + .elements { + display: flex; + flex-wrap: wrap; + justify-content: flex-start; } </style> diff --git a/pollen-ui-riot-js/src/main/web/tag/favoriteList/ImportCsvModal.tag.html b/pollen-ui-riot-js/src/main/web/tag/favoriteList/ImportCsvModal.tag.html new file mode 100644 index 00000000..7707ac58 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/favoriteList/ImportCsvModal.tag.html @@ -0,0 +1,67 @@ +require("../popup/Modal.tag.html"); + +<ImportCsvModal> + <Modal ref="modal" + header={__.member_importCsv} + label={__.member_import} + type="success" + onsubmit={importCsv}> + <div class="o-form-element"> + <label class="c-label" for="csvFile">{parent.__.member_csvFile}</label> + <input type="file" + id="csvFile" + ref="csvFile" + required + class="c-field {c-field--error : parent.errors.error}"> + <div class="exemple"> + {parent.__.member_csvFile_exemple_label} + <code class="c-code c-code--multiline">{parent.__.member_csvFile_exemple}</code> + {parent.__.member_csvFile_exemple_detail} + </div> + </div> + </Modal> + + <script type="es6"> + let session = require("../../js/Session"); + let route = require("riot-route"); + this.installBundle(session, "favoriteList"); + let favoriteListService = require("../../js/FavoriteListService"); + + this.errors = {}; + + this.open = () => { + return this.refs.modal.open(); + }; + + this.importCsv = () => { + let csvFile = this.refs.modal.refs.csvFile.files[0]; + return favoriteListService.importCsv(this.opts.favoriteList.id, csvFile).then(() => { + this.errors = {}; + this.refs.modal.refs.csvFile.value = ""; + this.update(); + }, errors => { + this.errors = errors; + this.bus.trigger("message", errors); + this.update(); + }); + }; + + </script> + + <style> + .exemple { + font-size: 0.9em; + padding-top: 0.5em; + width: 100%; + } + + .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> + +</ImportCsvModal> diff --git a/pollen-ui-riot-js/src/main/web/tag/favoriteList/ImportLdapModal.tag.html b/pollen-ui-riot-js/src/main/web/tag/favoriteList/ImportLdapModal.tag.html new file mode 100644 index 00000000..b2269d5b --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/favoriteList/ImportLdapModal.tag.html @@ -0,0 +1,70 @@ +require("../popup/Modal.tag.html"); + +<ImportLdapModal> + <Modal ref="modal" + header={__.member_importLdap} + label={__.member_import} + type="success" + onsubmit={importLdap}> + <div class="o-form-element"> + <label class="c-label" for="ldapUrl">{parent.__.member_ldap}</label> + <input type="text" + id="ldapUrl" + ref="ldapUrl" + required + placeholder={parent.__.member_ldap_placeholder} + class="c-field {c-field--error :parent.errors.error}"> + <div class="exemple"> + {parent.__.member_ldap_exemple_label} + <code class="c-code c-code--multiline">{parent.__.member_ldap_exemple}</code> + {parent.__.member_ldap_exemple_detail} + </div> + </div> + </Modal> + + + <script type="es6"> + let session = require("../../js/Session"); + let route = require("riot-route"); + this.installBundle(session, "favoriteList"); + let favoriteListService = require("../../js/FavoriteListService"); + + this.errors = {}; + + this.open = () => { + return this.refs.modal.open(); + }; + + this.importLdap = () => { + let ldap = this.refs.modal.refs.ldapUrl.value; + + return favoriteListService.importLdap(this.opts.favoriteList.id, ldap).then(() => { + this.errors = {}; + this.refs.modal.refs.ldapUrl.value = ""; + this.update(); + }, errors => { + this.errors = errors; + this.bus.trigger("message", errors); + this.update(); + }); + }; + + </script> + + <style> + .exemple { + font-size: 0.9em; + padding-top: 0.5em; + width: 100%; + } + + .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> + +</ImportLdapModal> 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 index 9306d2de..0f3881b8 100644 --- 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 @@ -1,86 +1,34 @@ -<MemberCard class="card"> - - <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} - {opts.member.weight} - </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="o-form-element"> - <label class="c-label" for="email">{__.weight}</label> - <input type="number" - id="weight" - ref="weight" - required - value={opts.member.weight} - step="0.01" - class="c-field {c-field--error : errors.weight}"> - </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> +require("../components/Card.tag.html"); +require("./MemberEditModal.tag.html"); +<MemberCard> + + <Card name={opts.member.name} + weight={opts.member.weight} + ondelete={delete} + onEdit={edit}> + <span title={parent.opts.member.email}> + {parent.opts.member.email} + </span> + </Card> + + <MemberEditModal ref="editModal" + favorite-list={opts.favoriteList} + member={opts.member}/> <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.edit = () => { + this.refs.editModal.open().then(() => { + if (this.opts.onMemberChange) { + this.opts.onMemberChange(); + } else { + this.update(); + } + }, () => {this.update();}); + this.update(); }; this.delete = () => { @@ -95,27 +43,18 @@ }); }; - this.save = e => { - e.preventDefault(); - e.stopPropagation(); - this.opts.member.name = this.refs.name.value; - this.opts.member.email = this.refs.email.value; - this.opts.member.weight = this.refs.weight.value; - - favoriteListService.saveMember(this.opts.favoriteList.id, this.opts.member).then(() => { - this.errors = {}; - this.cancelEdition(); - this.update(); - }, errors => { - this.errors = errors; - this.update(); - }); - }; - </script> <style> + .card-detail { + font-size: 0.8em; + white-space: nowrap; + overflow: hidden; + text-align: center; + text-overflow: ellipsis; + } + .member-card-view { display: flex; justify-content: space-between; diff --git a/pollen-ui-riot-js/src/main/web/tag/favoriteList/MemberEditModal.tag.html b/pollen-ui-riot-js/src/main/web/tag/favoriteList/MemberEditModal.tag.html new file mode 100644 index 00000000..f6d5a5b5 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/favoriteList/MemberEditModal.tag.html @@ -0,0 +1,96 @@ +require("../popup/Modal.tag.html"); + +<MemberEditModal> + <Modal ref="modal" + header={opts.member ? __.edit : __.new} + label={__.save} + type="success" + onsubmit={save}> + <div class="o-form-element"> + <label class="c-label" for="name">{parent.__.name}</label> + <input type="text" + id="name" + ref="name" + required + class="c-field" + placeholder={parent.__.name_placeholder} + value={parent.opts.member.name}> + </div> + <div class="o-form-element"> + <label class="c-label" for="name">{parent.__.email}</label> + <input type="email" + id="email" + ref="email" + required + class="c-field {c-field--error: parent.errors.email}" + placeholder={parent.__.email_placeholder} + value={parent.opts.member.email}> + <div class="c-hint c-hint--static c-hint--error" each={error in parent.errors.email}>{error}</div> + </div> + <div class="o-form-element"> + <label class="c-label" for="email">{parent.__.weight}</label> + <input type="number" + id="weight" + ref="weight" + required + value={parent.opts.member.weight || 1} + step="0.01" + class="c-field {c-field--error : parent.errors.weight}"> + </div> + </Modal> + + <script type="es6"> + let session = require("../../js/Session"); + let Message = require("../../js/Message"); + this.installBundle(session, "favoriteList_member"); + let favoriteListService = require("../../js/FavoriteListService"); + + if (!this.opts.member) { + this.opts.member = {}; + } + + this.errors = {}; + + this.open = () => { + if (!this.opts.member.id) { + this.refs.modal.refs.name.value = ""; + this.refs.modal.refs.email.value = ""; + this.refs.modal.refs.weight.value = 1; + } + return this.refs.modal.open(); + }; + + this.save = () => { + let member = {}; + Object.assign(member, this.opts.member); + member.name = this.refs.modal.refs.name.value; + member.email = this.refs.modal.refs.email.value; + member.weight = this.refs.modal.refs.weight.value; + + let promise; + if (member.id) { + promise = favoriteListService.saveMember(this.opts.favoriteList.id, member).then(() => { + this.errors = {}; + }, errors => { + this.errors = errors; + this.bus.trigger("message", new Message(errors, "error")); + this.update(); + return Promise.reject(); + }); + } else { + promise = favoriteListService.addMember(this.opts.favoriteList.id, member).then(() => { + this.errors = {}; + this.update(); + }, errors => { + this.errors = errors; + this.bus.trigger("message", new Message(errors, "error")); + this.update(); + return Promise.reject(); + }); + } + return promise; + }; + + </script> + +</MemberEditModal> -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm