From 77f9f2633e9cdaaf492ad71b3502ad21fe81e7e9 Mon Sep 17 00:00:00 2001 From: steve Date: Sun, 13 Oct 2013 11:27:48 +0800 Subject: [PATCH 1/2] Add account permission page --- .../com/pmease/gitop/web/GitopWebApp.java | 18 ++- .../com/pmease/gitop/web/assets/css/base.css | 11 ++ .../component/vex/AjaxConfirmButton.java | 5 +- .../com/pmease/gitop/web/model/TeamModel.java | 12 ++ .../com/pmease/gitop/web/page/BasePage.html | 2 +- .../com/pmease/gitop/web/page/BasePage.java | 140 ++++++++---------- .../permission/AccountPermissionPage.html | 12 +- .../permission/AccountPermissionPage.java | 89 +++++++++++ .../setting/permission/AddTeamPage.java | 15 ++ .../setting/permission/EditTeamPage.html | 5 + .../setting/permission/EditTeamPage.java | 49 ++++++ .../setting/permission/TeamEditor.html | 52 +++++++ .../setting/permission/TeamEditor.java | 122 +++++++++++++++ .../setting/profile/AccountProfilePage.html | 2 +- .../setting/profile/AccountProfilePage.java | 6 + .../pmease/gitop/web/page/home/HomePage.java | 10 +- 16 files changed, 461 insertions(+), 89 deletions(-) create mode 100644 gitop.web/src/main/java/com/pmease/gitop/web/model/TeamModel.java create mode 100644 gitop.web/src/main/java/com/pmease/gitop/web/page/account/setting/permission/AddTeamPage.java create mode 100644 gitop.web/src/main/java/com/pmease/gitop/web/page/account/setting/permission/EditTeamPage.html create mode 100644 gitop.web/src/main/java/com/pmease/gitop/web/page/account/setting/permission/EditTeamPage.java create mode 100644 gitop.web/src/main/java/com/pmease/gitop/web/page/account/setting/permission/TeamEditor.html create mode 100644 gitop.web/src/main/java/com/pmease/gitop/web/page/account/setting/permission/TeamEditor.java diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/GitopWebApp.java b/gitop.web/src/main/java/com/pmease/gitop/web/GitopWebApp.java index dac1e9b778..009be12150 100644 --- a/gitop.web/src/main/java/com/pmease/gitop/web/GitopWebApp.java +++ b/gitop.web/src/main/java/com/pmease/gitop/web/GitopWebApp.java @@ -12,9 +12,11 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.wicket.Application; import org.apache.wicket.Page; +import org.apache.wicket.RuntimeConfigurationType; import org.apache.wicket.Session; import org.apache.wicket.bean.validation.BeanValidationConfiguration; import org.apache.wicket.core.request.mapper.MountedMapper; +import org.apache.wicket.devutils.stateless.StatelessChecker; import org.apache.wicket.markup.html.IPackageResourceGuard; import org.apache.wicket.markup.html.SecurePackageResourceGuard; import org.apache.wicket.request.IRequestMapper; @@ -39,6 +41,8 @@ import com.pmease.gitop.web.page.account.AccountHomePage; import com.pmease.gitop.web.page.account.RegisterPage; import com.pmease.gitop.web.page.account.setting.password.AccountPasswordPage; import com.pmease.gitop.web.page.account.setting.permission.AccountPermissionPage; +import com.pmease.gitop.web.page.account.setting.permission.AddTeamPage; +import com.pmease.gitop.web.page.account.setting.permission.EditTeamPage; import com.pmease.gitop.web.page.account.setting.profile.AccountProfilePage; import com.pmease.gitop.web.page.account.setting.repos.AccountReposPage; import com.pmease.gitop.web.page.home.HomePage; @@ -102,15 +106,17 @@ public class GitopWebApp extends AbstractWicketConfig { loadDefaultUserAvatarData(); - new ShiroWicketPlugin().mountLoginPage("login", LoginPage.class) - .mountLogoutPage("logout", LogoutPage.class).install(this); + new ShiroWicketPlugin() + .mountLoginPage("login", LoginPage.class) + .mountLogoutPage("logout", LogoutPage.class) + .install(this); mountPages(); configureResources(); -// if (getConfigurationType() == RuntimeConfigurationType.DEVELOPMENT) { -// getComponentPreOnBeforeRenderListeners().add(new StatelessChecker()); -// } + if (getConfigurationType() == RuntimeConfigurationType.DEVELOPMENT) { + getComponentPreOnBeforeRenderListeners().add(new StatelessChecker()); + } } public byte[] getDefaultUserAvatar() { @@ -173,6 +179,8 @@ public class GitopWebApp extends AbstractWicketConfig { mountPage("settings/password", AccountPasswordPage.class); mountPage("settings/permission", AccountPermissionPage.class); mountPage("settings/repos", AccountReposPage.class); + mountPage("teams/add", AddTeamPage.class); + mountPage("teams/edit/${teamId}", EditTeamPage.class); mountPage("/test", TestPage.class); mountPage("test2", TestPage2.class); diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/assets/css/base.css b/gitop.web/src/main/java/com/pmease/gitop/web/assets/css/base.css index d271017bd8..702c12a0ca 100644 --- a/gitop.web/src/main/java/com/pmease/gitop/web/assets/css/base.css +++ b/gitop.web/src/main/java/com/pmease/gitop/web/assets/css/base.css @@ -38,6 +38,14 @@ ul.disc { list-style:disc outside; } .piped:after { clear: both; } ul.piped, ol.piped { margin: 0; padding: 0; } +/* LINKS */ +.checkable-link { color: #333; cursor: pointer; } +.checkable-link:hover { text-decoration: none; } +.checkable-link > .icon-checkbox:before { content: "\f096"; width: 16px; } +.checkable-link.checked > .icon-checkbox:before { content: "\f046"; width: 16px; } +.checkable-link.disabled { color: #888; } +em.checkable-link { color: #888 !important; } + /** LIST GROUP */ .list-navs > .list-group-item { border-width: 1px 0; } .list-navs > .list-group-item:first-child, @@ -173,6 +181,9 @@ a > .icon-null, .icon-null { display: inline-block; width: 10px; } background: #2ba6cb; } +.btn-radio-group .btn .icon-ok { display: none; } +.btn-radio-group .btn.active { background: #999; color: white; } +.btn-radio-group .btn.active .icon-ok, .btn-radio-group .btn:hover .icon-ok { display: inline-block; } /** * TABLE */ diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/common/component/vex/AjaxConfirmButton.java b/gitop.web/src/main/java/com/pmease/gitop/web/common/component/vex/AjaxConfirmButton.java index b2fc0ea3e3..69dcadad91 100644 --- a/gitop.web/src/main/java/com/pmease/gitop/web/common/component/vex/AjaxConfirmButton.java +++ b/gitop.web/src/main/java/com/pmease/gitop/web/common/component/vex/AjaxConfirmButton.java @@ -4,7 +4,6 @@ import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.AjaxFormSubmitBehavior; import org.apache.wicket.ajax.markup.html.form.AjaxButton; -import org.apache.wicket.behavior.AttributeAppender; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.head.JavaScriptHeaderItem; import org.apache.wicket.markup.html.form.Form; @@ -20,13 +19,11 @@ public class AjaxConfirmButton extends AjaxButton { } public AjaxConfirmButton(String id, Form form, IModel textModel, - IModel iconModel, IModel yesLabelModel, + final IModel iconModel, IModel yesLabelModel, IModel noLabelModel, IModel confirmCssClassModel) { super(id, form); add(new VexLinkBehavior(textModel, iconModel, yesLabelModel, noLabelModel, confirmCssClassModel)); - - add(AttributeAppender.append("class", "confirm-link")); } @Override diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/model/TeamModel.java b/gitop.web/src/main/java/com/pmease/gitop/web/model/TeamModel.java new file mode 100644 index 0000000000..809bab1e47 --- /dev/null +++ b/gitop.web/src/main/java/com/pmease/gitop/web/model/TeamModel.java @@ -0,0 +1,12 @@ +package com.pmease.gitop.web.model; + +import com.pmease.gitop.core.model.Team; + +public class TeamModel extends EntityModel { + private static final long serialVersionUID = 1L; + + public TeamModel(Team team) { + super(team); + } + +} diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/page/BasePage.html b/gitop.web/src/main/java/com/pmease/gitop/web/page/BasePage.html index efd0917c20..de6fe6544f 100644 --- a/gitop.web/src/main/java/com/pmease/gitop/web/page/BasePage.html +++ b/gitop.web/src/main/java/com/pmease/gitop/web/page/BasePage.html @@ -15,7 +15,7 @@ - + + + com.sun.jersey + jersey-client + 1.17.1 + + com.vaynberg.wicket.select2 @@ -66,7 +72,7 @@ imgscalr-lib 4.2 - + com.pmease commons.jetty diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/WebModule.java b/gitop.web/src/main/java/com/pmease/gitop/web/WebModule.java index 79ed0d4f88..d78cd73599 100644 --- a/gitop.web/src/main/java/com/pmease/gitop/web/WebModule.java +++ b/gitop.web/src/main/java/com/pmease/gitop/web/WebModule.java @@ -2,10 +2,13 @@ package com.pmease.gitop.web; import javax.inject.Singleton; +import com.pmease.commons.jersey.JerseyConfigurator; +import com.pmease.commons.jersey.JerseyEnvironment; import com.pmease.commons.jetty.ServletConfigurator; import com.pmease.commons.loader.AbstractPluginModule; import com.pmease.commons.wicket.AbstractWicketConfig; import com.pmease.gitop.core.validation.UserNameReservation; +import com.pmease.gitop.web.resource.TestResource; /** * NOTE: Do not forget to rename moduleClass property defined in the pom if you've renamed this class. @@ -23,6 +26,15 @@ public class WebModule extends AbstractPluginModule { contribute(ServletConfigurator.class, WebServletConfigurator.class); contribute(UserNameReservation.class, WebUserNameReservation.class); + + contribute(JerseyConfigurator.class, new JerseyConfigurator() { + + @Override + public void configure(JerseyEnvironment environment) { + environment.addComponentFromPackage(TestResource.class); + } + + }); } } diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/assets/css/base.css b/gitop.web/src/main/java/com/pmease/gitop/web/assets/css/base.css index 702c12a0ca..8079cabad0 100644 --- a/gitop.web/src/main/java/com/pmease/gitop/web/assets/css/base.css +++ b/gitop.web/src/main/java/com/pmease/gitop/web/assets/css/base.css @@ -38,6 +38,10 @@ ul.disc { list-style:disc outside; } .piped:after { clear: both; } ul.piped, ol.piped { margin: 0; padding: 0; } +.action-links { white-space: nowrap; } +.action-links > .link-item { display: inline-block; margin-left: 12px; } +.action-links > .link-item:first-child { margin-left: 0;} + /* LINKS */ .checkable-link { color: #333; cursor: pointer; } .checkable-link:hover { text-decoration: none; } @@ -47,10 +51,19 @@ ul.piped, ol.piped { margin: 0; padding: 0; } em.checkable-link { color: #888 !important; } /** LIST GROUP */ -.list-navs > .list-group-item { border-width: 1px 0; } +.list-navs > .list-group-item { border-width: 1px 0; positioin: relative; } .list-navs > .list-group-item:first-child, .list-navs > .list-group-item:last-child { border-radius: 0; } +.list-group.list-group-hoverable .list-group-item:hover { background: #ffe; } +.list-group-item .item-actions { position: absolute; right: 30px; top: 10px; } +.list-group-item .item-actions a { color: #999; } +.list-group-item .item-actions a:hover { color: #333; text-decoration: none; } + +.list-view .list-group-item { border-left: none; border-right: none; position: relative; } +.list-view .list-group-item:first-child, +.list-view .list-group-item:last-child { border-radius: 0; } + /* ADDITIONAL ICONS */ @font-face { @@ -190,17 +203,23 @@ a > .icon-null, .icon-null { display: inline-block; width: 10px; } .table { width: 100%; } .norecords-tr .norecords-td { background: #F9F7ED; font-size: 1.5em; line-height: 3em; font-weight: bold; text-align: center; } .table th a { color: #333; text-decoration: underline; } -.operations-td a { color: #999; } -.operations-td a:hover { color: #333; } +.table .operations-td { white-space: nowrap; } +.operations-td a, .operations-td a.iconlink { color: #999; } +.operations-td a:hover { color: #333; text-decoration: none; } + +.search-nav-td { font-size: 11px; } +.search-nav-td form { position: relative; } +.search-nav-td input.form-control, .search-nav-td select.form-control { padding: 2px 4px; height: 24px; } +.search-nav-td .btn { padding: 2px 8px; height: 24px; } + +.form-inline.navigation-form select.form-control { width: 60px; } +.form-inline.navigation-form input.form-control { width: 40px; } +.form-inline.navigation-form .btn-group { margin-left: 6px; } +.search-form button { position: absolute; right: 2px; top: 1px; border: none; height: 22px; background: transparent; color: #888; } + -/** - * FORM COMPONENT - */ /* FORM COMPONENT */ .select2-container .select2-choice { padding-top: 4px; padding-bottom: 4px; height: auto; } -.user-choice-row .img-thumbnail { float: left; } -.user-choice-row p { margin-left: 44px; margin-bottom: 0; } -.user-choice-row p.text-muted { font-size: 0.85em; } .select2-highlighted .user-choice-row p.text-muted { color: #ccc; } .required { color: #a00; margin-left: 3px;} @@ -258,65 +277,13 @@ a > .icon-null, .icon-null { display: inline-block; width: 10px; } transition: all 0.2s ease-in-out; } +.avatar.img-thumbnail { padding: 1px; } .avatar > img { display: block; margin: 0 auto; width: 100%; height: 100%; border-radius: 3px; } .avatar-circle { border-radius: 50%; } .avatar-circle > img { border-radius: 50%; } - +.avatar-big { width: 32px; height: 32px; } .avatar-xlarge { width: 128px; height: 128px; } -/** - * LAYOUT - */ -#globalheader, #main, #globalfooter {position: relative;} -#globalheader:before, #globalheader:after, #main:before, #main:after, #globalfooter:before, #globalfooter:after { - display: table; - content: " "; -} -#globalheader:after, #main:after, #globalfooter:after { clear: both; } - -/** - * GLOBAL HEADER - */ -#globalheader .navbar { border-width: 0 0 1px 0; border-color: #ddd; border-radius: 0; margin: 0; - background: #f0f2f4; color: white; -} -#globalheader .navbar-brand { padding: 10px 10px 10px 20px; } -#globalheader .search-form { margin-top: 12px; margin-bottom: 0;} -.search-form input.text-field { - height: 30px; - width: 200px; - line-height: normal; - text-indent: 0; - position: relative; - padding: 3px 30px 3px 8px; - font-size: 12px; - -webkit-transition: width 200ms, background 200ms ease; transition: width 200ms, background 200ms ease; - background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAEJWlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XpShal6dgqJJQ6N4mpmxjb6baqT3uBNwb8AUDZAw9IPCGNX2J72fYA2qSpoIpqEtIeOvFDiEl7QVX4rp3YDoqYo15/Pec753zn3GubqO+zkmkaUYVope5YhUxSOX1mUenboig9Sf00RP0lzTYT+fwc4RJccQ9dEaIHPxFWottjPfwhak/YX+a2RhR5BN5G2dZWgM8RxQzNtByi+F3YJ886JnDfU8CPWxAIrApc9XBK4CUPn3Y5xcI0OEKrrNVKZeB14NGlkL0awp4GMJAnw+vc0jVFzCJvNSq6wV2HtzzEHWL+H1wxmujZvYaxDtjL8ydwHxG916yZQht/rJXS88DPwX7DdJLC/gLw783lhQTwAaLoYxXr+ILHj768Viu+DrwH9rLuZItt+1p9KXcSGLHRjeXGCZFHcG5o9jRmSc8A36nxrNhj6JGozFNp4FHg4Vpzpp1fmrVX54XdzbNWm84BI49kvVWazQMPAb9rNQqiFjRLG9zIiFrIL10znXxbg7RTN3KiFvplMrfdHpFT2nFqxRkvlh12rGI7li1W9OPZNn/dNNyzCG3sktUsCG3Iz26VrHQGGHnY37y+IOYGHNtbLqXEbMeBj9GpSIk4NWgJq0Z12iWFCpShJO4mWfBUSCcDFg4vh0WPPErLsPXm5V2OFxMwqm70johGld4cr8K9NqfBBpnKDuHvCJtjR9kkmyKFvcJeZcdYCtYpdsRXkA/pVKhK96DUy/M2NVFZ6DhFyYtDzRE/RrlgvalrN9/7C2qCLhuBH3n8jqG5EZ4A2ZhAp7ux8Jyur3+71/com+zyG7cHrq/TyYfNN3Y3thPbxLoV2w7iY7/EtvHbogR2wHAVrUCV7u6E7fPGunq4CqZDJay/gteA1o7Srh2t1C8OBR4xCf5O7kGOLowGVvVn9Q91U/1EvaT+1lUjyNg1JelD6UvpO+kr6WvpB1KkK9JV6XvpmvSF9I2fs/fee1n8vXf7FTbRrdiFTr3wrDkZclLeJz8rp+Sn5eflOZ+lyIPyhDwj74dnn79vRuDv6kWnM5hVZ6q9a4knQKcFKNHpLLgWpiomXKfzyBp+TtpK2TCbYNn/nNpJcZY7KuLpeCqeICV+ID4Vn4jPCtx58uL74ZvCmvbVe0+Oz+jqgIdYmIqfZ8w9deKsiuhV6Dagmzv8HL4dRNMN87ylV2uOclBVX1IS+JRxJVvXxkeVkmEorstWLG5za5WXx0l8B0Uc0f2C+32L7LkZ2JzXiI7+iXfWrcC22CT63CYafDGwjeCd+MRHRJcPa01r1ctHkciPRHbl0EH3/8hAEu+mO63Wfbyv+j4g2n2/1fpno9Xa/RT5t4muGP8CYGVxecXFpEEAAAEiSURBVCgVhZG9SsRAFIVnkhBwSZ7AYGUXlDSCrYVYaCFKirBZCfgOamvrGySdkGwKEQRXO7XQxiKFINjrvsB2QoT4jThhENELh7nnnHvm5kd2XSeKohh4nncghBiBAEzRT9u2Pcmy7B3elx2G4ZzjODcoQynlA5jQu5z7tm2vNU0zjqLoQyccbjmErDKwkyTJhTbKsty1LOvMdV3lH2vdohkxfGkOKzNN03P0a9o9xXWpQMDzvmjBPNGf4AumpgJTEJmi0S/TvxlcWKwtEdbrut42DfUO8E2g/L5knucD3/dvWb9CeML5jLsEtgCSfOQrbsRxPFMpyYD+D0fwIZgHr2D8zRfN0FcA49eqqipg+A6zD/0ZULf8CN3/GzBCV2ybfQLGkGWtzcDkHAAAAABJRU5ErkJggg==') white no-repeat 180px 8px; -} -.search-form input.text-field:focus { width: 300px; background: white; } -#globalheader .tooltip { white-space: nowrap; } -#globalheader .navbar-right { margin-right: 20px; } -#globalheader .user-links { margin: 0; } -.user-links > li { margin: 0; } -.user-links > li.separator { height: 50px; border-left: 1px solid #d5d5d5; border-right: 1px solid #fefefe; margin: 0 6px;} -.user-links a { padding: 16px 10px 5px; line-height: 20px; } -.user-links a > i { font-size: 16px; } -.user-links a:hover { color: #333; text-decoration: none; } -.user-links li .caret { border-top-color: #09f; } -.user-links li a:hover .caret { border-top-color: #333; } -.user-links > li.avatar-user { white-space: nowrap; } -.user-links > li.avatar-user .avatar { margin-right: 3px; } - -/** - * GLOBAL FOOTER - */ -#globalfooter { padding: 20px; border-top: 1px solid #ddd; font-size: 11.9px; } - -/** - * MAIN - */ -#main { background: white; } - /** FAUX ROW */ .faux { display: table; width: 100%; border-collapse: collapse; table-layout: fixed; border-spacing: 0; } .faux-row { display: table-row; } @@ -325,24 +292,3 @@ a > .icon-null, .icon-null { display: inline-block; width: 10px; } .sidebar-inner { position: relative; width: 240px; overflow-x: hidden; } .faux .content { } -.sidebar .head, .content .head { padding: 15px 20px; white-space: nowrap; overflow: hidden; border-bottom: 1px solid #ddd; margin-bottom: 20px; } -.sidebar .head a { color: #666; font-weight:bold; line-height: 24px; } -.sidebar .head a:hover { text-decoration: none; color: #09F; } - -.sidebar .list-navs > .list-group-item, -.sidebar .list-navs > .list-group-item.active { - padding: 0; margin: 0; border-top-width: 0; background: transparent; -} -.sidebar .list-navs > .list-group-item.active { border-color: #ccc; } - -.sidebar .list-navs > .list-group-item:first-child { border-top-width: 1px; } -.sidebar .list-navs > .list-group-item a { padding: 10px 20px; display: block; color: #888; } -.sidebar .list-navs > .list-group-item a:hover { color: #333; text-decoration: none; background: #f2f2f2; } -.sidebar .list-navs > .list-group-item.active a, -.sidebar .list-navs > .list-group-item.active a:hover { color: #222; background: #e5e5e5; font-weight: bold; } - -section .head { border-style: solid; border-width: 1px 0; border-color: #ddd; } -section:first-child .head { border-top: none; } -section .head h2, section .head h3 { margin: 0; font-size: 18px; line-height: 24px; color: #888; font-weight: 300; } -section .padder, section > .body { padding: 0px 20px 20px; margin-bottom: 18px; } - diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/assets/css/page.css b/gitop.web/src/main/java/com/pmease/gitop/web/assets/css/page.css index d2f6fb44d8..c2066f853b 100644 --- a/gitop.web/src/main/java/com/pmease/gitop/web/assets/css/page.css +++ b/gitop.web/src/main/java/com/pmease/gitop/web/assets/css/page.css @@ -1,3 +1,100 @@ +/** + * LAYOUT + */ +#globalheader, #main, #globalfooter {position: relative;} +#globalheader:before, #globalheader:after, #main:before, #main:after, #globalfooter:before, #globalfooter:after { + display: table; + content: " "; +} +#globalheader:after, #main:after, #globalfooter:after { clear: both; } + +/** + * GLOBAL HEADER + */ +#globalheader .navbar { border-width: 0 0 1px 0; border-color: #ddd; border-radius: 0; margin: 0; + background: #f0f2f4; color: white; +} +#globalheader .navbar-brand { padding: 10px 10px 10px 20px; } +#globalheader .search-form { margin-top: 12px; margin-bottom: 0;} +.search-form input.text-field { + height: 30px; + width: 200px; + line-height: normal; + text-indent: 0; + position: relative; + padding: 3px 30px 3px 8px; + font-size: 12px; + -webkit-transition: width 200ms, background 200ms ease; transition: width 200ms, background 200ms ease; + background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAEJWlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XpShal6dgqJJQ6N4mpmxjb6baqT3uBNwb8AUDZAw9IPCGNX2J72fYA2qSpoIpqEtIeOvFDiEl7QVX4rp3YDoqYo15/Pec753zn3GubqO+zkmkaUYVope5YhUxSOX1mUenboig9Sf00RP0lzTYT+fwc4RJccQ9dEaIHPxFWottjPfwhak/YX+a2RhR5BN5G2dZWgM8RxQzNtByi+F3YJ886JnDfU8CPWxAIrApc9XBK4CUPn3Y5xcI0OEKrrNVKZeB14NGlkL0awp4GMJAnw+vc0jVFzCJvNSq6wV2HtzzEHWL+H1wxmujZvYaxDtjL8ydwHxG916yZQht/rJXS88DPwX7DdJLC/gLw783lhQTwAaLoYxXr+ILHj768Viu+DrwH9rLuZItt+1p9KXcSGLHRjeXGCZFHcG5o9jRmSc8A36nxrNhj6JGozFNp4FHg4Vpzpp1fmrVX54XdzbNWm84BI49kvVWazQMPAb9rNQqiFjRLG9zIiFrIL10znXxbg7RTN3KiFvplMrfdHpFT2nFqxRkvlh12rGI7li1W9OPZNn/dNNyzCG3sktUsCG3Iz26VrHQGGHnY37y+IOYGHNtbLqXEbMeBj9GpSIk4NWgJq0Z12iWFCpShJO4mWfBUSCcDFg4vh0WPPErLsPXm5V2OFxMwqm70johGld4cr8K9NqfBBpnKDuHvCJtjR9kkmyKFvcJeZcdYCtYpdsRXkA/pVKhK96DUy/M2NVFZ6DhFyYtDzRE/RrlgvalrN9/7C2qCLhuBH3n8jqG5EZ4A2ZhAp7ux8Jyur3+71/com+zyG7cHrq/TyYfNN3Y3thPbxLoV2w7iY7/EtvHbogR2wHAVrUCV7u6E7fPGunq4CqZDJay/gteA1o7Srh2t1C8OBR4xCf5O7kGOLowGVvVn9Q91U/1EvaT+1lUjyNg1JelD6UvpO+kr6WvpB1KkK9JV6XvpmvSF9I2fs/fee1n8vXf7FTbRrdiFTr3wrDkZclLeJz8rp+Sn5eflOZ+lyIPyhDwj74dnn79vRuDv6kWnM5hVZ6q9a4knQKcFKNHpLLgWpiomXKfzyBp+TtpK2TCbYNn/nNpJcZY7KuLpeCqeICV+ID4Vn4jPCtx58uL74ZvCmvbVe0+Oz+jqgIdYmIqfZ8w9deKsiuhV6Dagmzv8HL4dRNMN87ylV2uOclBVX1IS+JRxJVvXxkeVkmEorstWLG5za5WXx0l8B0Uc0f2C+32L7LkZ2JzXiI7+iXfWrcC22CT63CYafDGwjeCd+MRHRJcPa01r1ctHkciPRHbl0EH3/8hAEu+mO63Wfbyv+j4g2n2/1fpno9Xa/RT5t4muGP8CYGVxecXFpEEAAAEiSURBVCgVhZG9SsRAFIVnkhBwSZ7AYGUXlDSCrYVYaCFKirBZCfgOamvrGySdkGwKEQRXO7XQxiKFINjrvsB2QoT4jThhENELh7nnnHvm5kd2XSeKohh4nncghBiBAEzRT9u2Pcmy7B3elx2G4ZzjODcoQynlA5jQu5z7tm2vNU0zjqLoQyccbjmErDKwkyTJhTbKsty1LOvMdV3lH2vdohkxfGkOKzNN03P0a9o9xXWpQMDzvmjBPNGf4AumpgJTEJmi0S/TvxlcWKwtEdbrut42DfUO8E2g/L5knucD3/dvWb9CeML5jLsEtgCSfOQrbsRxPFMpyYD+D0fwIZgHr2D8zRfN0FcA49eqqipg+A6zD/0ZULf8CN3/GzBCV2ybfQLGkGWtzcDkHAAAAABJRU5ErkJggg==') white no-repeat 180px 8px; +} +.search-form input.text-field:focus { width: 300px; background: white; } +#globalheader .tooltip { white-space: nowrap; } +#globalheader .navbar-right { margin-right: 20px; } +#globalheader .user-links { margin: 0; } +.user-links > li { margin: 0; } +.user-links > li.separator { height: 50px; border-left: 1px solid #d5d5d5; border-right: 1px solid #fefefe; margin: 0 6px;} +.user-links a { padding: 16px 10px 5px; line-height: 20px; } +.user-links a > i { font-size: 16px; } +.user-links a:hover { color: #333; text-decoration: none; } +.user-links li .caret { border-top-color: #09f; } +.user-links li a:hover .caret { border-top-color: #333; } +.user-links > li.avatar-user { white-space: nowrap; } +.user-links > li.avatar-user .avatar { margin-right: 3px; } + +/** + * GLOBAL FOOTER + */ +#globalfooter { padding: 20px; border-top: 1px solid #ddd; font-size: 11.9px; } + +/** + * MAIN + */ +#main { background: white; } + +.sidebar .head, .content .head { padding: 15px 20px; white-space: nowrap; overflow: hidden; border-bottom: 1px solid #ddd; margin-bottom: 20px; } +.sidebar .head a { color: #666; font-weight:bold; line-height: 24px; } +.sidebar .head a:hover { text-decoration: none; color: #09F; } + +.sidebar .list-navs > .list-group-item, +.sidebar .list-navs > .list-group-item.active { + padding: 0; margin: 0; border-top-width: 0; background: transparent; +} +.sidebar .list-navs > .list-group-item.active { border-color: #ccc; } + +.sidebar .list-navs > .list-group-item:first-child { border-top-width: 1px; } +.sidebar .list-navs > .list-group-item a { padding: 10px 20px; display: block; color: #888; } +.sidebar .list-navs > .list-group-item a:hover { color: #333; text-decoration: none; background: #f2f2f2; } +.sidebar .list-navs > .list-group-item.active a, +.sidebar .list-navs > .list-group-item.active a:hover { color: #222; background: #e5e5e5; font-weight: bold; } + +section .head { border-style: solid; border-width: 1px 0; border-color: #ddd; } +section:first-child .head { border-top: none; } +section .head h2, section .head h3 { margin: 0; font-size: 18px; line-height: 24px; color: #888; font-weight: 300; } +section .padder, section > .body { padding: 0px 20px 20px; margin-bottom: 18px; } + +/** TABLE */ + +th.wicket_orderUp, th.wicket_orderDown, th.wicket_orderNone { position: relative; } +.wicket_orderUp:before, .wicket_orderDown:before, .wicket_orderNone:before { + font-family: pmease-icons; + font-weight: normal; + font-style: normal; + -webkit-font-smoothing: antialiased; + *margin-right: .3em; + text-decoration: none; + display: inline-block; + speak: none; + position: absolute; + left: 5px; + top: 5px; + color: #666; +} +th.wicket_orderUp a, th.wicket_orderDown a { padding-left: 20px; } + +.wicket_orderUp:before { content: "\f062"; } +.wicket_orderDown:before { content: "\f063"; } + +/** SERVER INIT PAGE */ .server-init { text-align: center; width: 50%; @@ -20,28 +117,22 @@ #login-form .btn { width: 100%;} -#dropzone { - background: white; - width: 150px; - height: 50px; - line-height: 50px; - text-align: center; - font-weight: bold; -} -#dropzone.in { - width: 600px; - height: 200px; - line-height: 200px; - font-size: larger; -} -#dropzone.hover { - background: lawngreen; -} -#dropzone.fade { - -webkit-transition: all 0.3s ease-out; - -moz-transition: all 0.3s ease-out; - -ms-transition: all 0.3s ease-out; - -o-transition: all 0.3s ease-out; - transition: all 0.3s ease-out; - opacity: 1; -} +/* TEAM EDIT PAGE */ +.member-list .members { width: 48%; } +.member-list .members.first { float: left; } +.member-list .members.last { float: right; } +.members a { color: #999; font-size: 16px; } +.members .list-group-item:hover a { color: #333; } +.members .item-actions {top: 12px;} +.members .item-actions .img-link { color: #ddd; font-size: 20px; } +.members .list-group-item:hover .img-link, .members .item-actions .img-link:hover { color: #990000; } +.members .avatar { width: 32px; height: 32px; margin-right: 8px; } + +.permission-link { color: #666; } +a.permission-link:hover { color: #333; text-decoration: none; } + +.user-choice-row .img-thumbnail { float: left; } +.user-choice-row p { margin-left: 44px; margin-bottom: 0; } +.user-choice-row p.text-muted { font-size: 0.85em; } + +.btn-group-permissions > a { width: 80px; } diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/common/bootstrap/AjaxIconLink.html b/gitop.web/src/main/java/com/pmease/gitop/web/common/bootstrap/AjaxIconLink.html new file mode 100644 index 0000000000..b55a9b8796 --- /dev/null +++ b/gitop.web/src/main/java/com/pmease/gitop/web/common/bootstrap/AjaxIconLink.html @@ -0,0 +1,5 @@ + + + + + diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/common/bootstrap/AjaxIconLink.java b/gitop.web/src/main/java/com/pmease/gitop/web/common/bootstrap/AjaxIconLink.java new file mode 100644 index 0000000000..21e8283420 --- /dev/null +++ b/gitop.web/src/main/java/com/pmease/gitop/web/common/bootstrap/AjaxIconLink.java @@ -0,0 +1,51 @@ +package com.pmease.gitop.web.common.bootstrap; + +import org.apache.wicket.ajax.markup.html.AjaxLink; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; + +public abstract class AjaxIconLink extends Panel { + + private static final long serialVersionUID = 1L; + + private final IModel iconModel; + private final IModel labelModel; + + public AjaxIconLink(String id, IModel iconModel) { + this(id, iconModel, Model.of("")); + } + + public AjaxIconLink(String id, IModel iconModel, + IModel labelModel) { + super(id); + this.iconModel = iconModel; + this.labelModel = labelModel; + } + + @Override + protected void onInitialize() { + super.onInitialize(); + + AjaxLink link = createLink("link"); + add(link); + link.add(new Icon("icon", iconModel)); + link.add(new Label("label", labelModel)); + } + + @Override + protected void onDetach() { + super.onDetach(); + + if (iconModel != null) { + iconModel.detach(); + } + + if (labelModel != null) { + labelModel.detach(); + } + } + + abstract protected AjaxLink createLink(String id); +} \ No newline at end of file diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/common/bootstrap/Icon.java b/gitop.web/src/main/java/com/pmease/gitop/web/common/bootstrap/Icon.java new file mode 100644 index 0000000000..0e067cce6a --- /dev/null +++ b/gitop.web/src/main/java/com/pmease/gitop/web/common/bootstrap/Icon.java @@ -0,0 +1,29 @@ +package com.pmease.gitop.web.common.bootstrap; + +import org.apache.wicket.behavior.AttributeAppender; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.model.AbstractReadOnlyModel; +import org.apache.wicket.model.IModel; + +public class Icon extends WebMarkupContainer { + + private static final long serialVersionUID = 1L; + + public Icon(String id, final IconType type) { + super(id); + add(type.newCssClassNameModifier()); + } + + @SuppressWarnings("serial") + public Icon(String id, final IModel type) { + super(id); + add(AttributeAppender.append("class", + new AbstractReadOnlyModel() { + + @Override + public String getObject() { + return type.getObject().cssClassName(); + } + })); + } +} \ No newline at end of file diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/common/bootstrap/IconType.java b/gitop.web/src/main/java/com/pmease/gitop/web/common/bootstrap/IconType.java new file mode 100644 index 0000000000..77f3f1d438 --- /dev/null +++ b/gitop.web/src/main/java/com/pmease/gitop/web/common/bootstrap/IconType.java @@ -0,0 +1,400 @@ +package com.pmease.gitop.web.common.bootstrap; + +import org.apache.wicket.behavior.AttributeAppender; + +public enum IconType { + NULL("icon-null"), + ADJUST("icon-adjust"), + ANCHOR("icon-anchor"), + ARCHIVE("icon-archive"), + ASTERISK("icon-asterisk"), + BAN_CIRCLE("icon-ban-circle"), + BAR_CHART("icon-bar-chart"), + BARCODE("icon-barcode"), + BEAKER("icon-beaker"), + BEER("icon-beer"), + BELL("icon-bell"), + BELL_ALT("icon-bell-alt"), + BOLT("icon-bolt"), + BOOK("icon-book"), + BOOKMARK("icon-bookmark"), + BOOKMARK_EMPTY("icon-bookmark-empty"), + BRIEFCASE("icon-briefcase"), + BUG("icon-bug"), + BUILDING("icon-building"), + BULLHORN("icon-bullhorn"), + BULLSEYE("icon-bullseye"), + CALENDAR("icon-calendar"), + CALENDAR_EMPTY("icon-calendar-empty"), + CAMERA("icon-camera"), + CAMERA_RETRO("icon-camera-retro"), + CERTIFICATE("icon-certificate"), + CHECK("icon-check"), + CHECK_EMPTY("icon-check-empty"), + CHECK_MINUS("icon-check-minus"), + CHECK_SIGN("icon-check-sign"), + CIRCLE("icon-circle"), + CIRCLE_BLANK("icon-circle-blank"), + CLOUD("icon-cloud"), + CLOUD_DOWNLOAD("icon-cloud-download"), + CLOUD_UPLOAD("icon-cloud-upload"), + CODE("icon-code"), + CODE_FORK("icon-code-fork"), + COFFEE("icon-coffee"), + COG("icon-cog"), + COGS("icon-cogs"), + COLLAPSE("icon-collapse"), + COLLAPSE_ALT("icon-collapse-alt"), + COLLAPSE_TOP("icon-collapse-top"), + COMMENT("icon-comment"), + COMMENT_ALT("icon-comment-alt"), + COMMENTS("icon-comments"), + COMMENTS_ALT("icon-comments-alt"), + COMPASS("icon-compass"), + CREDIT_CARD("icon-credit-card"), + CROP("icon-crop"), + DASHBOARD("icon-dashboard"), + DESKTOP("icon-desktop"), + DOWNLOAD("icon-download"), + DOWNLOAD_ALT("icon-download-alt"), + EDIT("icon-edit"), + EDIT_SIGN("icon-edit-sign"), + ELLIPSIS_HORIZONTAL("icon-ellipsis-horizontal"), + ELLIPSIS_VERTICAL("icon-ellipsis-vertical"), + ENVELOPE("icon-envelope"), + ENVELOPE_ALT("icon-envelope-alt"), + ERASER("icon-eraser"), + EXCHANGE("icon-exchange"), + EXCLAMATION("icon-exclamation"), + EXCLAMATION_SIGN("icon-exclamation-sign"), + EXPAND("icon-expand"), + EXPAND_ALT("icon-expand-alt"), + EXTERNAL_LINK("icon-external-link"), + EXTERNAL_LINK_SIGN("icon-external-link-sign"), + EYE_CLOSE("icon-eye-close"), + EYE_OPEN("icon-eye-open"), + FACETIME_VIDEO("icon-facetime-video"), + FEMALE("icon-female"), + FIGHTER_JET("icon-fighter-jet"), + FILM("icon-film"), + FILTER("icon-filter"), + FIRE("icon-fire"), + FIRE_EXTINGUISHER("icon-fire-extinguisher"), + FLAG("icon-flag"), + FLAG_ALT("icon-flag-alt"), + FLAG_CHECKERED("icon-flag-checkered"), + FOLDER_CLOSE("icon-folder-close"), + FOLDER_CLOSE_ALT("icon-folder-close-alt"), + FOLDER_OPEN("icon-folder-open"), + FOLDER_OPEN_ALT("icon-folder-open-alt"), + FOOD("icon-food"), + FROWN("icon-frown"), + GAMEPAD("icon-gamepad"), + GEAR("icon-gear"), + GEARS("icon-gears"), + GIFT("icon-gift"), + GLASS("icon-glass"), + GLOBE("icon-globe"), + GROUP("icon-group"), + HDD("icon-hdd"), + HEADPHONES("icon-headphones"), + HEART("icon-heart"), + HEART_EMPTY("icon-heart-empty"), + HOME("icon-home"), + INBOX("icon-inbox"), + INFO("icon-info"), + INFO_SIGN("icon-info-sign"), + KEY("icon-key"), + KEYBOARD("icon-keyboard"), + LAPTOP("icon-laptop"), + LEAF("icon-leaf"), + LEGAL("icon-legal"), + LEMON("icon-lemon"), + LEVEL_DOWN("icon-level-down"), + LEVEL_UP("icon-level-up"), + LIGHTBULB("icon-lightbulb"), + LOCATION_ARROW("icon-location-arrow"), + LOCK("icon-lock"), + MAGIC("icon-magic"), + MAGNET("icon-magnet"), + MAIL_FORWARD("icon-mail-forward"), + MAIL_REPLY("icon-mail-reply"), + MAIL_REPLY_ALL("icon-mail-reply-all"), + MALE("icon-male"), + MAP_MARKER("icon-map-marker"), + MEH("icon-meh"), + MICROPHONE("icon-microphone"), + MICROPHONE_OFF("icon-microphone-off"), + MINUS("icon-minus"), + MINUS_SIGN("icon-minus-sign"), + MINUS_SIGN_ALT("icon-minus-sign-alt"), + MOBILE_PHONE("icon-mobile-phone"), + MONEY("icon-money"), + MOON("icon-moon"), + MOVE("icon-move"), + MUSIC("icon-music"), + OFF("icon-off"), + OK("icon-ok"), + OK_CIRCLE("icon-ok-circle"), + OK_SIGN("icon-ok-sign"), + PENCIL("icon-pencil"), + PHONE("icon-phone"), + PHONE_SIGN("icon-phone-sign"), + PICTURE("icon-picture"), + PLANE("icon-plane"), + PLUS("icon-plus"), + PLUS_SIGN("icon-plus-sign"), + PLUS_SIGN_ALT("icon-plus-sign-alt"), + POWER_OFF("icon-power-off"), + PRINT("icon-print"), + PUSHPIN("icon-pushpin"), + PUZZLE_PIECE("icon-puzzle-piece"), + QRCODE("icon-qrcode"), + QUESTION("icon-question"), + QUESTION_SIGN("icon-question-sign"), + QUOTE_LEFT("icon-quote-left"), + QUOTE_RIGHT("icon-quote-right"), + RANDOM("icon-random"), + REFRESH("icon-refresh"), + REMOVE("icon-remove"), + REMOVE_CIRCLE("icon-remove-circle"), + REMOVE_SIGN("icon-remove-sign"), + REORDER("icon-reorder"), + REPLY("icon-reply"), + REPLY_ALL("icon-reply-all"), + RESIZE_HORIZONTAL("icon-resize-horizontal"), + RESIZE_VERTICAL("icon-resize-vertical"), + RETWEET("icon-retweet"), + ROAD("icon-road"), + ROCKET("icon-rocket"), + RSS("icon-rss"), + RSS_SIGN("icon-rss-sign"), + SCREENSHOT("icon-screenshot"), + SEARCH("icon-search"), + SHARE("icon-share"), + SHARE_ALT("icon-share-alt"), + SHARE_SIGN("icon-share-sign"), + SHIELD("icon-shield"), + SHOPPING_CART("icon-shopping-cart"), + SIGN_BLANK("icon-sign-blank"), + SIGNAL("icon-signal"), + SIGNIN("icon-signin"), + SIGNOUT("icon-signout"), + SITEMAP("icon-sitemap"), + SMILE("icon-smile"), + SORT("icon-sort"), + SORT_BY_ALPHABET("icon-sort-by-alphabet"), + SORT_BY_ALPHABET_ALT("icon-sort-by-alphabet-alt"), + SORT_BY_ATTRIBUTES("icon-sort-by-attributes"), + SORT_BY_ATTRIBUTES_ALT("icon-sort-by-attributes-alt"), + SORT_BY_ORDER("icon-sort-by-order"), + SORT_BY_ORDER_ALT("icon-sort-by-order-alt"), + SORT_DOWN("icon-sort-down"), + SORT_UP("icon-sort-up"), + SPINNER("icon-spinner"), + STAR("icon-star"), + STAR_EMPTY("icon-star-empty"), + STAR_HALF("icon-star-half"), + STAR_HALF_EMPTY("icon-star-half-empty"), + STAR_HALF_FULL("icon-star-half-full"), + SUBSCRIPT("icon-subscript"), + SUITCASE("icon-suitcase"), + SUN("icon-sun"), + SUPERSCRIPT("icon-superscript"), + TABLET("icon-tablet"), + TAG("icon-tag"), + TAGS("icon-tags"), + TASKS("icon-tasks"), + TERMINAL("icon-terminal"), + THUMBS_DOWN("icon-thumbs-down"), + THUMBS_DOWN_ALT("icon-thumbs-down-alt"), + THUMBS_UP("icon-thumbs-up"), + THUMBS_UP_ALT("icon-thumbs-up-alt"), + TICKET("icon-ticket"), + TIME("icon-time"), + TINT("icon-tint"), + TRASH("icon-trash"), + TROPHY("icon-trophy"), + TRUCK("icon-truck"), + UMBRELLA("icon-umbrella"), + UNCHECKED("icon-unchecked"), + UNLOCK("icon-unlock"), + UNLOCK_ALT("icon-unlock-alt"), + UPLOAD("icon-upload"), + UPLOAD_ALT("icon-upload-alt"), + USER("icon-user"), + VOLUME_DOWN("icon-volume-down"), + VOLUME_OFF("icon-volume-off"), + VOLUME_UP("icon-volume-up"), + WARNING_SIGN("icon-warning-sign"), + WRENCH("icon-wrench"), + ZOOM_IN("icon-zoom-in"), + ZOOM_OUT("icon-zoom-out"), + BITCOIN("icon-bitcoin"), + BTC("icon-btc"), + CNY("icon-cny"), + DOLLAR("icon-dollar"), + EUR("icon-eur"), + EURO("icon-euro"), + GBP("icon-gbp"), + INR("icon-inr"), + JPY("icon-jpy"), + KRW("icon-krw"), + RENMINBI("icon-renminbi"), + RUPEE("icon-rupee"), + USD("icon-usd"), + WON("icon-won"), + YEN("icon-yen"), + ALIGN_CENTER("icon-align-center"), + ALIGN_JUSTIFY("icon-align-justify"), + ALIGN_LEFT("icon-align-left"), + ALIGN_RIGHT("icon-align-right"), + BOLD("icon-bold"), + COLUMNS("icon-columns"), + COPY("icon-copy"), + CUT("icon-cut"), + FILE("icon-file"), + FILE_ALT("icon-file-alt"), + FILE_TEXT("icon-file-text"), + FILE_TEXT_ALT("icon-file-text-alt"), + FONT("icon-font"), + INDENT_LEFT("icon-indent-left"), + INDENT_RIGHT("icon-indent-right"), + ITALIC("icon-italic"), + LINK("icon-link"), + LIST("icon-list"), + LIST_ALT("icon-list-alt"), + LIST_OL("icon-list-ol"), + LIST_UL("icon-list-ul"), + PAPER_CLIP("icon-paper-clip"), + PAPERCLIP("icon-paperclip"), + PASTE("icon-paste"), + REPEAT("icon-repeat"), + ROTATE_LEFT("icon-rotate-left"), + ROTATE_RIGHT("icon-rotate-right"), + SAVE("icon-save"), + STRIKETHROUGH("icon-strikethrough"), + TABLE("icon-table"), + TEXT_HEIGHT("icon-text-height"), + TEXT_WIDTH("icon-text-width"), + TH("icon-th"), + TH_LARGE("icon-th-large"), + TH_LIST("icon-th-list"), + UNDERLINE("icon-underline"), + UNDO("icon-undo"), + UNLINK("icon-unlink"), + ANGLE_DOWN("icon-angle-down"), + ANGLE_LEFT("icon-angle-left"), + ANGLE_RIGHT("icon-angle-right"), + ANGLE_UP("icon-angle-up"), + ARROW_DOWN("icon-arrow-down"), + ARROW_LEFT("icon-arrow-left"), + ARROW_RIGHT("icon-arrow-right"), + ARROW_UP("icon-arrow-up"), + CARET_DOWN("icon-caret-down"), + CARET_LEFT("icon-caret-left"), + CARET_RIGHT("icon-caret-right"), + CARET_UP("icon-caret-up"), + CHEVRON_DOWN("icon-chevron-down"), + CHEVRON_LEFT("icon-chevron-left"), + CHEVRON_RIGHT("icon-chevron-right"), + CHEVRON_SIGN_DOWN("icon-chevron-sign-down"), + CHEVRON_SIGN_LEFT("icon-chevron-sign-left"), + CHEVRON_SIGN_RIGHT("icon-chevron-sign-right"), + CHEVRON_SIGN_UP("icon-chevron-sign-up"), + CHEVRON_UP("icon-chevron-up"), + CIRCLE_ARROW_DOWN("icon-circle-arrow-down"), + CIRCLE_ARROW_LEFT("icon-circle-arrow-left"), + CIRCLE_ARROW_RIGHT("icon-circle-arrow-right"), + CIRCLE_ARROW_UP("icon-circle-arrow-up"), + DOUBLE_ANGLE_DOWN("icon-double-angle-down"), + DOUBLE_ANGLE_LEFT("icon-double-angle-left"), + DOUBLE_ANGLE_RIGHT("icon-double-angle-right"), + DOUBLE_ANGLE_UP("icon-double-angle-up"), + HAND_DOWN("icon-hand-down"), + HAND_LEFT("icon-hand-left"), + HAND_RIGHT("icon-hand-right"), + HAND_UP("icon-hand-up"), + LONG_ARROW_DOWN("icon-long-arrow-down"), + LONG_ARROW_LEFT("icon-long-arrow-left"), + LONG_ARROW_RIGHT("icon-long-arrow-right"), + LONG_ARROW_UP("icon-long-arrow-up"), + BACKWARD("icon-backward"), + EJECT("icon-eject"), + FAST_BACKWARD("icon-fast-backward"), + FAST_FORWARD("icon-fast-forward"), + FORWARD("icon-forward"), + FULLSCREEN("icon-fullscreen"), + PAUSE("icon-pause"), + PLAY("icon-play"), + PLAY_CIRCLE("icon-play-circle"), + PLAY_SIGN("icon-play-sign"), + RESIZE_FULL("icon-resize-full"), + RESIZE_SMALL("icon-resize-small"), + STEP_BACKWARD("icon-step-backward"), + STEP_FORWARD("icon-step-forward"), + STOP("icon-stop"), + YOUTUBE_PLAY("icon-youtube-play"), + ADN("icon-adn"), + ANDROID("icon-android"), + APPLE("icon-apple"), + BITBUCKET("icon-bitbucket"), + BITBUCKET_SIGN("icon-bitbucket-sign"), + CSS3("icon-css3"), + DRIBBBLE("icon-dribbble"), + DROPBOX("icon-dropbox"), + FACEBOOK("icon-facebook"), + FACEBOOK_SIGN("icon-facebook-sign"), + FLICKR("icon-flickr"), + FOURSQUARE("icon-foursquare"), + GITHUB("icon-github"), + GITHUB_ALT("icon-github-alt"), + GITHUB_SIGN("icon-github-sign"), + GITTIP("icon-gittip"), + GOOGLE_PLUS("icon-google-plus"), + GOOGLE_PLUS_SIGN("icon-google-plus-sign"), + HTML5("icon-html5"), + INSTAGRAM("icon-instagram"), + LINKEDIN("icon-linkedin"), + LINKEDIN_SIGN("icon-linkedin-sign"), + LINUX("icon-linux"), + MAXCDN("icon-maxcdn"), + PINTEREST("icon-pinterest"), + PINTEREST_SIGN("icon-pinterest-sign"), + RENREN("icon-renren"), + SKYPE("icon-skype"), + STACKEXCHANGE("icon-stackexchange"), + TRELLO("icon-trello"), + TUMBLR("icon-tumblr"), + TUMBLR_SIGN("icon-tumblr-sign"), + TWITTER("icon-twitter"), + TWITTER_SIGN("icon-twitter-sign"), + VK("icon-vk"), + WEIBO("icon-weibo"), + WINDOWS("icon-windows"), + XING("icon-xing"), + XING_SIGN("icon-xing-sign"), + YOUTUBE("icon-youtube"), + YOUTUBE_SIGN("icon-youtube-sign"), + AMBULANCE("icon-ambulance"), + H_SIGN("icon-h-sign"), + HOSPITAL("icon-hospital"), + MEDKIT("icon-medkit"), + STETHOSCOPE("icon-stethoscope"), + USER_MD("icon-user-md"); + + + private final String cssClassName; + + IconType(String cssClassName) { + this.cssClassName = cssClassName; + } + + public String cssClassName() { + return cssClassName; + } + + public AttributeAppender newCssClassNameModifier() { + return AttributeAppender.append("class", cssClassName()); + } +} diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/common/component/datagrid/hibernate/HibernateDataProvider.java b/gitop.web/src/main/java/com/pmease/gitop/web/common/component/datagrid/hibernate/HibernateDataProvider.java index 3a7ed4adbd..1d6c478b89 100644 --- a/gitop.web/src/main/java/com/pmease/gitop/web/common/component/datagrid/hibernate/HibernateDataProvider.java +++ b/gitop.web/src/main/java/com/pmease/gitop/web/common/component/datagrid/hibernate/HibernateDataProvider.java @@ -28,15 +28,15 @@ public abstract class HibernateDataProvider extends So public Iterator iterator(long first, long count) { GeneralDao dao = getDao(); DetachedCriteria criteria = getCriteria(); + SortParam param = getSort(); if (param != null) { - DetachedCriteria crit = getCriteria(); Iterable it = Splitter.on(",").trimResults().split(param.getProperty()); for (String each : it) { if (param.isAscending()) - crit.addOrder(Order.asc(each)); + criteria.addOrder(Order.asc(each)); else - crit.addOrder(Order.desc(each)); + criteria.addOrder(Order.desc(each)); } } diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/common/component/datagrid/toolbar/SearchNavToolbar.java b/gitop.web/src/main/java/com/pmease/gitop/web/common/component/datagrid/toolbar/SearchNavToolbar.java index 5e8446b5e8..026a881087 100644 --- a/gitop.web/src/main/java/com/pmease/gitop/web/common/component/datagrid/toolbar/SearchNavToolbar.java +++ b/gitop.web/src/main/java/com/pmease/gitop/web/common/component/datagrid/toolbar/SearchNavToolbar.java @@ -28,205 +28,217 @@ import com.pmease.gitop.web.common.component.datagrid.event.SearchStringChanged; public class SearchNavToolbar extends AbstractToolbar { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - public SearchNavToolbar(DataTable table) { - super(table); + public SearchNavToolbar(DataTable table) { + super(table); - setOutputMarkupId(true); - } + setOutputMarkupId(true); + } - @Override - protected void onInitialize() { - super.onInitialize(); + @Override + protected void onInitialize() { + super.onInitialize(); - WebMarkupContainer span = new WebMarkupContainer("td"); - add(span); - span.add(AttributeModifier.replace("colspan", new AbstractReadOnlyModel() { - private static final long serialVersionUID = 1L; + WebMarkupContainer span = new WebMarkupContainer("td"); + add(span); + span.add(AttributeModifier.replace("colspan", + new AbstractReadOnlyModel() { + private static final long serialVersionUID = 1L; - @Override - public String getObject() { - return String.valueOf(getTable().getColumns().size()); - } - })); + @Override + public String getObject() { + return String.valueOf(getTable().getColumns().size()); + } + })); - span.add(newSearchForm("search")); - span.add(newNavigationForm("nav")); - } + span.add(newSearchForm("search")); + span.add(newNavigationForm("nav")); + } - @Override - protected void onConfigure() { - super.onConfigure(); - - this.setVisibilityAllowed(getTable().getRowCount() > 0); - } - - protected Component newSearchForm(String id) { - Fragment frag = new Fragment(id, "searchFrag", this); - frag.add(new SearchForm("searchForm")); - return frag; - } - - @SuppressWarnings({"serial"}) - private class SearchForm extends Form { + @Override + protected void onConfigure() { + super.onConfigure(); - private String pattern; - - public SearchForm(String id) { - super(id); - } - - @Override - protected void onInitialize() { - super.onInitialize(); - - TextField input = new TextField("input", new PropertyModel(this, "pattern")); - add(input); - IndicatingAjaxButton submit = new IndicatingAjaxButton("submit", this) { - @Override - protected void onSubmit(AjaxRequestTarget target, Form form) { - send(getTable(), Broadcast.BREADTH, new SearchStringChanged(target, pattern)); - } - }; - add(submit); - setDefaultButton(submit); - } - - @Override - public void onEvent(IEvent event) { - if (event.getPayload() instanceof SearchStringChanged) { - SearchStringChanged e = (SearchStringChanged) event.getPayload(); - this.pattern = e.getPattern(); - e.getTarget().add(this); - } - } - } + this.setVisibilityAllowed(getTable().getRowCount() > 0); + } - protected void onPageChanged(AjaxRequestTarget target) { - target.add(getTable()); - target.add(this); - } - - protected Component newNavigationForm(String id) { - Fragment frag = new Fragment(id, "navFrag", this); - frag.add(new NavigationForm("form")); - return frag; - } + protected Component newSearchForm(String id) { + Fragment frag = new Fragment(id, "searchFrag", this); + frag.add(new SearchForm("searchForm")); + return frag; + } - static final List ROWS_PER_PAGE = ImmutableList.of(10, 25, 50, 100, 250, 500); - - @SuppressWarnings({"serial"}) - private class NavigationForm extends Form { - - private int rowsPerPage = 10; - private int currentPage = 1; - - public NavigationForm(String id) { - super(id); - } - - @Override - protected void onInitialize() { - super.onInitialize(); - - DropDownChoice rowsSelector = new DropDownChoice("rowsSelector", - new PropertyModel(this, "rowsPerPage"), ROWS_PER_PAGE); - add(rowsSelector); - rowsSelector.add(new AjaxFormComponentUpdatingBehavior("onchange") { + @SuppressWarnings({ "serial" }) + private class SearchForm extends Form { - @Override - protected void onUpdate(AjaxRequestTarget target) { - currentPage = 1; - getTable().setItemsPerPage(rowsPerPage); - send(getTable(), Broadcast.BREADTH, new PageChanged(target, currentPage - 1)); - } - }); - - add(new AjaxLink("previousLink") { + private String pattern; - @Override - public void onClick(AjaxRequestTarget target) { - long current = getTable().getCurrentPage(); - if (current == 0) { - return; - } - - current--; - if (current < 0) { - current = 0; - } - - send(getTable(), Broadcast.BREADTH, new PageChanged(target, (int) current)); - } - }); - - add(new AjaxLink("nextLink") { + public SearchForm(String id) { + super(id); + } - @Override - public void onClick(AjaxRequestTarget target) { - long current = getTable().getCurrentPage(); - long totals = getTable().getPageCount(); - if (current == totals) { - return; - } - - current++; - if (current >= totals) { - current = totals - 1; - } - - send(getTable(), Broadcast.BREADTH, new PageChanged(target, (int) current)); - } - - }); - - add(new TextField("pageInput", new PropertyModel(this, "currentPage"))); - - AjaxButton btn = new AjaxButton("submit", this) { - @Override - protected void onSubmit(AjaxRequestTarget target, Form form) { - if (currentPage == getTable().getCurrentPage() + 1) { - return; - } - - long totals = getTable().getPageCount(); - currentPage = Math.min(currentPage, (int) totals); - currentPage = Math.max(currentPage, 0); - - send(getTable(), Broadcast.BREADTH, new PageChanged(target, currentPage - 1)); - } - - @Override - protected void onError(AjaxRequestTarget target, Form form) { - target.add(form); - } - }; - add(btn); - setDefaultButton(btn); - - add(new Label("navlabel", new AbstractReadOnlyModel() { + @Override + protected void onInitialize() { + super.onInitialize(); - @Override - public String getObject() { - long totals = getTable().getRowCount(); - long items = getTable().getItemsPerPage(); - long start = (currentPage - 1) * items + 1; - long end = start + items - 1; - end = Math.min(end, totals); - return start + " - " + end + " of " + totals; - } - })); - } - - @Override - public void onEvent(IEvent event) { - if (event.getPayload() instanceof PageChanged) { - PageChanged e = (PageChanged) event.getPayload(); - currentPage = e.getPage() + 1; - rowsPerPage = (int) getTable().getItemsPerPage(); - e.getTarget().add(this); - } - } - } + TextField input = new TextField("input", + new PropertyModel(this, "pattern")); + add(input); + IndicatingAjaxButton submit = new IndicatingAjaxButton("submit", + this) { + @Override + protected void onSubmit(AjaxRequestTarget target, Form form) { + send(getTable(), Broadcast.BREADTH, + new SearchStringChanged(target, pattern)); + } + }; + add(submit); + setDefaultButton(submit); + } + + @Override + public void onEvent(IEvent event) { + if (event.getPayload() instanceof SearchStringChanged) { + SearchStringChanged e = (SearchStringChanged) event + .getPayload(); + this.pattern = e.getPattern(); + e.getTarget().add(this); + } + } + } + + protected void onPageChanged(AjaxRequestTarget target) { + target.add(getTable()); + target.add(this); + } + + protected Component newNavigationForm(String id) { + Fragment frag = new Fragment(id, "navFrag", this); + frag.add(new NavigationForm("form")); + return frag; + } + + static final List ROWS_PER_PAGE = ImmutableList. of(10, + 25, 50, 100, 250, 500); + + @SuppressWarnings({ "serial" }) + private class NavigationForm extends Form { + + private int rowsPerPage = 10; + private int currentPage = 1; + + public NavigationForm(String id) { + super(id); + } + + @Override + protected void onInitialize() { + super.onInitialize(); + + DropDownChoice rowsSelector = new DropDownChoice( + "rowsSelector", new PropertyModel(this, + "rowsPerPage"), ROWS_PER_PAGE); + add(rowsSelector); + rowsSelector.add(new AjaxFormComponentUpdatingBehavior("onchange") { + + @Override + protected void onUpdate(AjaxRequestTarget target) { + currentPage = 1; + getTable().setItemsPerPage(rowsPerPage); + send(getTable(), Broadcast.BREADTH, new PageChanged(target, + currentPage - 1)); + } + }); + + add(new AjaxLink("previousLink") { + + @Override + public void onClick(AjaxRequestTarget target) { + long current = getTable().getCurrentPage(); + if (current == 0) { + return; + } + + current--; + if (current < 0) { + current = 0; + } + + send(getTable(), Broadcast.BREADTH, new PageChanged(target, + (int) current)); + } + }); + + add(new AjaxLink("nextLink") { + + @Override + public void onClick(AjaxRequestTarget target) { + long current = getTable().getCurrentPage(); + long totals = getTable().getPageCount(); + if (current == totals) { + return; + } + + current++; + if (current >= totals) { + current = totals - 1; + } + + send(getTable(), Broadcast.BREADTH, new PageChanged(target, + (int) current)); + } + + }); + + add(new TextField("pageInput", new PropertyModel( + this, "currentPage"))); + + AjaxButton btn = new AjaxButton("submit", this) { + @Override + protected void onSubmit(AjaxRequestTarget target, Form form) { + if (currentPage == getTable().getCurrentPage() + 1) { + return; + } + + long totals = getTable().getPageCount(); + currentPage = Math.min(currentPage, (int) totals); + currentPage = Math.max(currentPage, 0); + + send(getTable(), Broadcast.BREADTH, new PageChanged(target, + currentPage - 1)); + } + + @Override + protected void onError(AjaxRequestTarget target, Form form) { + target.add(form); + } + }; + add(btn); + setDefaultButton(btn); + + add(new Label("navlabel", new AbstractReadOnlyModel() { + + @Override + public String getObject() { + long totals = getTable().getRowCount(); + long items = getTable().getItemsPerPage(); + long start = (currentPage - 1) * items + 1; + long end = start + items - 1; + end = Math.min(end, totals); + return start + " - " + end + " of " + totals; + } + })); + } + + @Override + public void onEvent(IEvent event) { + if (event.getPayload() instanceof PageChanged) { + PageChanged e = (PageChanged) event.getPayload(); + currentPage = e.getPage() + 1; + rowsPerPage = (int) getTable().getItemsPerPage(); + e.getTarget().add(this); + } + } + } } diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/common/component/messenger/Messenger.java b/gitop.web/src/main/java/com/pmease/gitop/web/common/component/messenger/Messenger.java index d4e0c580e1..bab0fcebb9 100644 --- a/gitop.web/src/main/java/com/pmease/gitop/web/common/component/messenger/Messenger.java +++ b/gitop.web/src/main/java/com/pmease/gitop/web/common/component/messenger/Messenger.java @@ -7,7 +7,7 @@ import com.pmease.gitop.web.common.util.Options; public class Messenger { static enum Type { - INFO, SUCCESS, ERROR + INFO, SUCCESS, WARNING, ERROR } private final String jsFunc; @@ -31,6 +31,10 @@ public class Messenger { public static Messenger error(String message) { return message(message, Type.ERROR); } + + public static Messenger warn(String message) { + return message(message, Type.WARNING); + } private static Messenger message(String message, Type type) { return post(new Options() diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/common/component/messenger/res/css/messenger-theme-flat.css b/gitop.web/src/main/java/com/pmease/gitop/web/common/component/messenger/res/css/messenger-theme-flat.css index 3b39da42f3..3129462992 100644 --- a/gitop.web/src/main/java/com/pmease/gitop/web/common/component/messenger/res/css/messenger-theme-flat.css +++ b/gitop.web/src/main/java/com/pmease/gitop/web/common/component/messenger/res/css/messenger-theme-flat.css @@ -356,6 +356,9 @@ ul.messenger-theme-flat .messenger-message.alert-success .messenger-message-inne ul.messenger-theme-flat .messenger-message.alert-info .messenger-message-inner:before { background: #00B5AD; } +ul.messenger-theme-flat .messenger-message.alert-warning .messenger-message-inner:before { + background: #ff9500; +} /* line 103, ../../src/sass/messenger-theme-flat.sass */ ul.messenger-theme-flat .messenger-message.alert-error .messenger-message-inner:before { background: #ff2a68; diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/common/component/vex/AjaxConfirmButton.java b/gitop.web/src/main/java/com/pmease/gitop/web/common/component/vex/AjaxConfirmButton.java index 69dcadad91..fb7d59ac8a 100644 --- a/gitop.web/src/main/java/com/pmease/gitop/web/common/component/vex/AjaxConfirmButton.java +++ b/gitop.web/src/main/java/com/pmease/gitop/web/common/component/vex/AjaxConfirmButton.java @@ -5,7 +5,6 @@ import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.AjaxFormSubmitBehavior; import org.apache.wicket.ajax.markup.html.form.AjaxButton; import org.apache.wicket.markup.head.IHeaderResponse; -import org.apache.wicket.markup.head.JavaScriptHeaderItem; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.model.IModel; @@ -51,8 +50,5 @@ public class AjaxConfirmButton extends AjaxButton { @Override public void renderHead(IHeaderResponse response) { super.renderHead(response); - - response.render(JavaScriptHeaderItem.forReference(VexConfirmJavaScriptResourceReference.get())); - response.render(JavaScriptHeaderItem.forScript("vex.defaultOptions.className = 'vex-theme-wireframe'", "vex-theme-options")); } } diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/common/component/vex/VexLinkBehavior.java b/gitop.web/src/main/java/com/pmease/gitop/web/common/component/vex/VexLinkBehavior.java index 25665d4d71..884b3c7ddd 100644 --- a/gitop.web/src/main/java/com/pmease/gitop/web/common/component/vex/VexLinkBehavior.java +++ b/gitop.web/src/main/java/com/pmease/gitop/web/common/component/vex/VexLinkBehavior.java @@ -4,6 +4,7 @@ import org.apache.wicket.Component; import org.apache.wicket.behavior.Behavior; import org.apache.wicket.markup.ComponentTag; import org.apache.wicket.markup.head.IHeaderResponse; +import org.apache.wicket.markup.head.JavaScriptHeaderItem; import org.apache.wicket.markup.head.OnDomReadyHeaderItem; import org.apache.wicket.model.IComponentAssignedModel; import org.apache.wicket.model.IModel; @@ -44,6 +45,9 @@ public class VexLinkBehavior extends Behavior { public void renderHead(Component component, IHeaderResponse response) { super.renderHead(component, response); + response.render(JavaScriptHeaderItem.forReference(VexConfirmJavaScriptResourceReference.get())); + response.render(JavaScriptHeaderItem.forScript("vex.defaultOptions.className = 'vex-theme-wireframe'", "vex-theme-options")); + String markupId = component.getMarkupId(true); response.render(OnDomReadyHeaderItem.forScript(String.format( "$('#%s').on('click', function(e){e.preventDefault(); $(this).confirm(); });", diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/MultipleUserChoice.java b/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/MultipleUserChoice.java new file mode 100644 index 0000000000..b39a7f63d6 --- /dev/null +++ b/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/MultipleUserChoice.java @@ -0,0 +1,41 @@ +package com.pmease.gitop.web.component.choice; + +import java.util.Collection; + +import org.apache.wicket.markup.head.IHeaderResponse; +import org.apache.wicket.markup.head.JavaScriptHeaderItem; +import org.apache.wicket.model.IModel; +import org.apache.wicket.request.resource.PackageResourceReference; +import org.apache.wicket.request.resource.ResourceReference; + +import com.pmease.gitop.core.model.User; +import com.vaynberg.wicket.select2.Select2MultiChoice; + +public class MultipleUserChoice extends Select2MultiChoice { + + private static final long serialVersionUID = 1L; + + public MultipleUserChoice(String id, IModel> model) { + super(id, model, new UserChoiceProvider()); + } + + @Override + protected void onInitialize() { + super.onInitialize(); + // getSettings().setMinimumInputLength(1); + getSettings().setPlaceholder("Choose an user ..."); + getSettings().setFormatResult("UserChoice.formatter.formatResult"); + getSettings() + .setFormatSelection("UserChoice.formatter.formatSelection"); + getSettings().setEscapeMarkup("UserChoice.formatter.escapeMarkup"); + } + + private ResourceReference userChoiceReference = new PackageResourceReference( + SingleUserChoice.class, "userchoice.js"); + + @Override + public void renderHead(IHeaderResponse response) { + super.renderHead(response); + response.render(JavaScriptHeaderItem.forReference(userChoiceReference)); + } +} \ No newline at end of file diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/SingleTeamChoice.java b/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/SingleTeamChoice.java new file mode 100644 index 0000000000..63c7e0c126 --- /dev/null +++ b/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/SingleTeamChoice.java @@ -0,0 +1,39 @@ +package com.pmease.gitop.web.component.choice; + +import org.apache.wicket.markup.head.IHeaderResponse; +import org.apache.wicket.markup.head.JavaScriptHeaderItem; +import org.apache.wicket.model.IModel; +import org.apache.wicket.request.resource.JavaScriptResourceReference; +import org.apache.wicket.request.resource.ResourceReference; + +import com.pmease.gitop.core.model.Team; +import com.vaynberg.wicket.select2.ChoiceProvider; +import com.vaynberg.wicket.select2.Select2Choice; + +@SuppressWarnings("serial") +public class SingleTeamChoice extends Select2Choice { + + public SingleTeamChoice(String id, IModel model, + ChoiceProvider teamsProvider) { + super(id, model, teamsProvider); + } + + @Override + protected void onInitialize() { + super.onInitialize(); + getSettings().setPlaceholder("Choose a team ..."); + getSettings().setFormatResult("TeamChoice.formatter.formatResult"); + getSettings() + .setFormatSelection("TeamChoice.formatter.formatSelection"); + getSettings().setEscapeMarkup("TeamChoice.formatter.escapeMarkup"); + } + + private ResourceReference teamChoiceReference = + new JavaScriptResourceReference(SingleUserChoice.class, "teamchoice.js"); + + @Override + public void renderHead(IHeaderResponse response) { + super.renderHead(response); + response.render(JavaScriptHeaderItem.forReference(teamChoiceReference)); + } +} \ No newline at end of file diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/SingleUserChoice.java b/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/SingleUserChoice.java new file mode 100644 index 0000000000..d1243bc3d4 --- /dev/null +++ b/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/SingleUserChoice.java @@ -0,0 +1,39 @@ +package com.pmease.gitop.web.component.choice; + +import org.apache.wicket.markup.head.IHeaderResponse; +import org.apache.wicket.markup.head.JavaScriptHeaderItem; +import org.apache.wicket.model.IModel; +import org.apache.wicket.request.resource.JavaScriptResourceReference; +import org.apache.wicket.request.resource.ResourceReference; + +import com.pmease.gitop.core.model.User; +import com.vaynberg.wicket.select2.Select2Choice; + +@SuppressWarnings("serial") +public class SingleUserChoice extends Select2Choice { + + public SingleUserChoice(String id, IModel model) { + super(id, model, new UserChoiceProvider()); + } + + @Override + protected void onInitialize() { + super.onInitialize(); + // getSettings().setMinimumInputLength(1); + getSettings().setPlaceholder("Choose an user ..."); + getSettings().setFormatResult("UserChoice.formatter.formatResult"); + getSettings() + .setFormatSelection("UserChoice.formatter.formatSelection"); + getSettings().setEscapeMarkup("UserChoice.formatter.escapeMarkup"); + } + + private ResourceReference userChoiceReference = + new JavaScriptResourceReference(SingleUserChoice.class, "userchoice.js"); + + @Override + public void renderHead(IHeaderResponse response) { + super.renderHead(response); + response.render(JavaScriptHeaderItem.forReference(userChoiceReference)); + } + +} diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/TeamChoiceProvider.java b/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/TeamChoiceProvider.java new file mode 100644 index 0000000000..013b1c4b24 --- /dev/null +++ b/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/TeamChoiceProvider.java @@ -0,0 +1,75 @@ +package com.pmease.gitop.web.component.choice; + +import java.util.Collection; +import java.util.List; + +import org.apache.wicket.model.IModel; +import org.hibernate.criterion.DetachedCriteria; +import org.hibernate.criterion.MatchMode; +import org.hibernate.criterion.Order; +import org.hibernate.criterion.Restrictions; +import org.json.JSONException; +import org.json.JSONWriter; + +import com.google.common.collect.Lists; +import com.pmease.commons.hibernate.dao.GeneralDao; +import com.pmease.gitop.core.Gitop; +import com.pmease.gitop.core.manager.TeamManager; +import com.pmease.gitop.core.model.Team; +import com.vaynberg.wicket.select2.ChoiceProvider; +import com.vaynberg.wicket.select2.Response; + +public class TeamChoiceProvider extends ChoiceProvider { + + private static final long serialVersionUID = 1L; + + IModel criteria; + + public TeamChoiceProvider(IModel criteria) { + this.criteria = criteria; + } + + @Override + public void query(String term, int page, Response response) { + DetachedCriteria crit = criteria == null ? null : criteria.getObject(); + if (crit == null) { + crit = DetachedCriteria.forClass(Team.class); + } + + crit.add(Restrictions.ilike("name", term, MatchMode.START)); + crit.addOrder(Order.asc("name")); + int first = page * 10; + @SuppressWarnings("unchecked") + List teams = (List) Gitop.getInstance(GeneralDao.class).query(crit, first, 10); + + response.addAll(teams); + } + + @Override + public void toJson(Team choice, JSONWriter writer) throws JSONException { + writer.key("id").value(choice.getId()) + .key("name").value(choice.getName()) + .key("permission").value(choice.getAuthorizedOperation()); + } + + @Override + public Collection toChoices(Collection ids) { + List teams = Lists.newArrayList(); + TeamManager tm = Gitop.getInstance(TeamManager.class); + for (String each : ids) { + Long id = Long.valueOf(each); + teams.add(tm.get(id)); + } + + return teams; + } + + @Override + public void detach() { + super.detach(); + + if (criteria != null) { + criteria.detach(); + } + } +} \ No newline at end of file diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/UserChoiceProvider.java b/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/UserChoiceProvider.java new file mode 100644 index 0000000000..5464da7be4 --- /dev/null +++ b/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/UserChoiceProvider.java @@ -0,0 +1,81 @@ +package com.pmease.gitop.web.component.choice; + +import java.util.Collection; +import java.util.List; + +import org.apache.wicket.request.cycle.RequestCycle; +import org.hibernate.criterion.Criterion; +import org.hibernate.criterion.MatchMode; +import org.hibernate.criterion.Order; +import org.hibernate.criterion.Restrictions; +import org.json.JSONException; +import org.json.JSONWriter; + +import com.google.common.base.Strings; +import com.google.common.collect.Lists; +import com.pmease.gitop.core.Gitop; +import com.pmease.gitop.core.manager.UserManager; +import com.pmease.gitop.core.model.User; +import com.pmease.gitop.web.GitopWebApp; +import com.pmease.gitop.web.component.avatar.AvatarImageResourceReference; +import com.pmease.gitop.web.util.Gravatar; +import com.pmease.gitop.web.util.WicketUtils; +import com.vaynberg.wicket.select2.ChoiceProvider; +import com.vaynberg.wicket.select2.Response; + +public class UserChoiceProvider extends ChoiceProvider { + + private static final long serialVersionUID = 1L; + + @Override + public void query(String term, int page, Response response) { + if (Strings.isNullOrEmpty(term)) { + return; + } + + UserManager um = Gitop.getInstance(UserManager.class); + int first = page * 10; + List users = um.query(new Criterion[] { + Restrictions.ilike("name", term, MatchMode.START), + Restrictions.ilike("displayName", term, MatchMode.START) + }, new Order[0], first, 10); + + response.addAll(users); + } + + @Override + public void toJson(User choice, JSONWriter writer) throws JSONException { + writer.key("id").value(choice.getId()) + .key("name").value(choice.getName()) + .key("displayName").value(choice.getDisplayName()) + .key("email").value(choice.getEmail()) + .key("avatar").value(getAvatarUrl(choice)); + } + + @Override + public Collection toChoices(Collection ids) { + List users = Lists.newArrayList(); + UserManager um = Gitop.getInstance(UserManager.class); + for (String each : ids) { + Long id = Long.valueOf(each); + users.add(um.get(id)); + } + + return users; + } + + private String getAvatarUrl(User user) { + String path = user.getAvatarUrl(); + if (GitopWebApp.get().isGravatarEnabled() && Strings.isNullOrEmpty(path)) { + return Gravatar.getURL(user.getEmail()); + } else { + CharSequence url = RequestCycle.get().urlFor( + new AvatarImageResourceReference(), + WicketUtils.newPageParams( + "id",String.valueOf(user.getId()), + "type", "user")); + + return url.toString() + "?antiCache=" + System.currentTimeMillis(); + } + } +} \ No newline at end of file diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/teamchoice.js b/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/teamchoice.js new file mode 100644 index 0000000000..c35e8b5949 --- /dev/null +++ b/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/teamchoice.js @@ -0,0 +1,14 @@ +var TeamChoice = TeamChoice || {}; +TeamChoice.formatter = { + formatSelection: function(team) { + return team.name; + }, + + formatResult: function(team) { + return team.name; + }, + + escapeMarkup: function(m) { + return m; + } +}; diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/userchoice.js b/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/userchoice.js new file mode 100644 index 0000000000..fd0cf4a378 --- /dev/null +++ b/gitop.web/src/main/java/com/pmease/gitop/web/component/choice/userchoice.js @@ -0,0 +1,17 @@ +var UserChoice = UserChoice || {}; +UserChoice.formatter = { + formatSelection: function(user) { + return " " + user.name + " (" + user.displayName + ")"; + }, + + formatResult: function(user) { + return "
" + + "

"+ user.name + " (" + user.displayName + ")" + "

" + + "

" + user.email + "

" + + "
"; + }, + + escapeMarkup: function(m) { + return m; + } +}; diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/model/EntityModel.java b/gitop.web/src/main/java/com/pmease/gitop/web/model/EntityModel.java index b51cb2b691..5666f4adf8 100644 --- a/gitop.web/src/main/java/com/pmease/gitop/web/model/EntityModel.java +++ b/gitop.web/src/main/java/com/pmease/gitop/web/model/EntityModel.java @@ -1,36 +1,37 @@ package com.pmease.gitop.web.model; - import org.apache.wicket.model.LoadableDetachableModel; +import com.google.common.base.Preconditions; import com.pmease.commons.hibernate.AbstractEntity; import com.pmease.commons.hibernate.dao.GeneralDao; import com.pmease.commons.loader.AppLoader; public class EntityModel extends LoadableDetachableModel { - private static final long serialVersionUID = 1L; - - protected T entity; - private final Class entityClass; - - protected GeneralDao getDao() { - return AppLoader.getInstance(GeneralDao.class); - } - - @SuppressWarnings("unchecked") -public EntityModel(T entity) { - this.entity = entity; - this.entityClass = (Class) entity.getClass(); - } - - @Override - protected T load() { - if (entity.isNew()) { - return entity; - } else { - return getDao().get(entityClass, entity.getId()); - } - } + private static final long serialVersionUID = 1L; + + protected T entity; + private final Class entityClass; + + protected GeneralDao getDao() { + return AppLoader.getInstance(GeneralDao.class); + } + + @SuppressWarnings("unchecked") + public EntityModel(T entity) { + Preconditions.checkNotNull(entity, "entity"); + this.entity = entity; + this.entityClass = (Class) entity.getClass(); + } + + @Override + protected T load() { + if (entity.isNew()) { + return entity; + } else { + return getDao().get(entityClass, entity.getId()); + } + } } diff --git a/gitop.web/src/main/java/com/pmease/gitop/web/page/BasePage.html b/gitop.web/src/main/java/com/pmease/gitop/web/page/BasePage.html index de6fe6544f..efd0917c20 100644 --- a/gitop.web/src/main/java/com/pmease/gitop/web/page/BasePage.html +++ b/gitop.web/src/main/java/com/pmease/gitop/web/page/BasePage.html @@ -15,7 +15,7 @@ - +