mirror of
https://github.com/theonedev/onedev.git
synced 2025-12-08 18:26:30 +00:00
Merge branch 'master' of https://git.pmease.com/p/robin/commons.git
This commit is contained in:
commit
89c6f438a8
@ -72,7 +72,7 @@ public class DefaultGeneralDao implements GeneralDao, Serializable {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (Class<T>) entityClass;
|
||||
return entityClass;
|
||||
}
|
||||
|
||||
@Sessional
|
||||
@ -99,7 +99,7 @@ public class DefaultGeneralDao implements GeneralDao, Serializable {
|
||||
public <T extends AbstractEntity> int count(DetachedCriteria detachedCriteria) {
|
||||
Criteria criteria = detachedCriteria.getExecutableCriteria(getSession());
|
||||
criteria.setProjection(Projections.rowCount());
|
||||
return (Integer) criteria.uniqueResult();
|
||||
return ((Long) criteria.uniqueResult()).intValue();
|
||||
}
|
||||
|
||||
public Object writeReplace() throws ObjectStreamException {
|
||||
|
||||
@ -36,7 +36,13 @@
|
||||
<version>1.0.29</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- JERSEY CLIENT -->
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-client</artifactId>
|
||||
<version>1.17.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- WICKET -->
|
||||
<dependency>
|
||||
<groupId>com.vaynberg.wicket.select2</groupId>
|
||||
@ -66,7 +72,7 @@
|
||||
<artifactId>imgscalr-lib</artifactId>
|
||||
<version>4.2</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.pmease</groupId>
|
||||
<artifactId>commons.jetty</artifactId>
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -38,11 +38,32 @@ 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; }
|
||||
.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 { 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 {
|
||||
@ -173,23 +194,32 @@ 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
|
||||
*/
|
||||
.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;}
|
||||
@ -247,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; }
|
||||
@ -314,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; }
|
||||
|
||||
|
||||
@ -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; }
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
<html xmlns:wicket>
|
||||
<wicket:panel>
|
||||
<a wicket:id="link" class="iconlink"><i wicket:id="icon"></i> <span wicket:id="label"></span></a>
|
||||
</wicket:panel>
|
||||
</html>
|
||||
@ -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<IconType> iconModel;
|
||||
private final IModel<String> labelModel;
|
||||
|
||||
public AjaxIconLink(String id, IModel<IconType> iconModel) {
|
||||
this(id, iconModel, Model.of(""));
|
||||
}
|
||||
|
||||
public AjaxIconLink(String id, IModel<IconType> iconModel,
|
||||
IModel<String> 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);
|
||||
}
|
||||
@ -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<IconType> type) {
|
||||
super(id);
|
||||
add(AttributeAppender.append("class",
|
||||
new AbstractReadOnlyModel<String>() {
|
||||
|
||||
@Override
|
||||
public String getObject() {
|
||||
return type.getObject().cssClassName();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
@ -28,15 +28,15 @@ public abstract class HibernateDataProvider<T extends AbstractEntity> extends So
|
||||
public Iterator<? extends T> iterator(long first, long count) {
|
||||
GeneralDao dao = getDao();
|
||||
DetachedCriteria criteria = getCriteria();
|
||||
|
||||
SortParam<String> param = getSort();
|
||||
if (param != null) {
|
||||
DetachedCriteria crit = getCriteria();
|
||||
Iterable<String> 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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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<String>() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
WebMarkupContainer span = new WebMarkupContainer("td");
|
||||
add(span);
|
||||
span.add(AttributeModifier.replace("colspan",
|
||||
new AbstractReadOnlyModel<String>() {
|
||||
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<Void> {
|
||||
@Override
|
||||
protected void onConfigure() {
|
||||
super.onConfigure();
|
||||
|
||||
private String pattern;
|
||||
|
||||
public SearchForm(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
TextField<String> input = new TextField<String>("input", new PropertyModel<String>(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<Integer> ROWS_PER_PAGE = ImmutableList.<Integer>of(10, 25, 50, 100, 250, 500);
|
||||
|
||||
@SuppressWarnings({"serial"})
|
||||
private class NavigationForm extends Form<Void> {
|
||||
|
||||
private int rowsPerPage = 10;
|
||||
private int currentPage = 1;
|
||||
|
||||
public NavigationForm(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
DropDownChoice<Integer> rowsSelector = new DropDownChoice<Integer>("rowsSelector",
|
||||
new PropertyModel<Integer>(this, "rowsPerPage"), ROWS_PER_PAGE);
|
||||
add(rowsSelector);
|
||||
rowsSelector.add(new AjaxFormComponentUpdatingBehavior("onchange") {
|
||||
@SuppressWarnings({ "serial" })
|
||||
private class SearchForm extends Form<Void> {
|
||||
|
||||
@Override
|
||||
protected void onUpdate(AjaxRequestTarget target) {
|
||||
currentPage = 1;
|
||||
getTable().setItemsPerPage(rowsPerPage);
|
||||
send(getTable(), Broadcast.BREADTH, new PageChanged(target, currentPage - 1));
|
||||
}
|
||||
});
|
||||
|
||||
add(new AjaxLink<Void>("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<Void>("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<Integer>("pageInput", new PropertyModel<Integer>(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<String>() {
|
||||
@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<String> input = new TextField<String>("input",
|
||||
new PropertyModel<String>(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<Integer> ROWS_PER_PAGE = ImmutableList.<Integer> of(10,
|
||||
25, 50, 100, 250, 500);
|
||||
|
||||
@SuppressWarnings({ "serial" })
|
||||
private class NavigationForm extends Form<Void> {
|
||||
|
||||
private int rowsPerPage = 10;
|
||||
private int currentPage = 1;
|
||||
|
||||
public NavigationForm(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
DropDownChoice<Integer> rowsSelector = new DropDownChoice<Integer>(
|
||||
"rowsSelector", new PropertyModel<Integer>(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<Void>("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<Void>("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<Integer>("pageInput", new PropertyModel<Integer>(
|
||||
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<String>() {
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -4,9 +4,7 @@ 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;
|
||||
import org.apache.wicket.model.IModel;
|
||||
|
||||
@ -20,13 +18,11 @@ public class AjaxConfirmButton extends AjaxButton {
|
||||
}
|
||||
|
||||
public AjaxConfirmButton(String id, Form<?> form, IModel<String> textModel,
|
||||
IModel<VexIcon> iconModel, IModel<String> yesLabelModel,
|
||||
final IModel<VexIcon> iconModel, IModel<String> yesLabelModel,
|
||||
IModel<String> noLabelModel, IModel<String> confirmCssClassModel) {
|
||||
super(id, form);
|
||||
add(new VexLinkBehavior(textModel, iconModel, yesLabelModel,
|
||||
noLabelModel, confirmCssClassModel));
|
||||
|
||||
add(AttributeAppender.append("class", "confirm-link"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -54,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"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -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(); });",
|
||||
|
||||
@ -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<User> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public MultipleUserChoice(String id, IModel<Collection<User>> 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));
|
||||
}
|
||||
}
|
||||
@ -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<Team> {
|
||||
|
||||
public SingleTeamChoice(String id, IModel<Team> model,
|
||||
ChoiceProvider<Team> 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));
|
||||
}
|
||||
}
|
||||
@ -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<User> {
|
||||
|
||||
public SingleUserChoice(String id, IModel<User> 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));
|
||||
}
|
||||
|
||||
}
|
||||
@ -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<Team> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
IModel<DetachedCriteria> criteria;
|
||||
|
||||
public TeamChoiceProvider(IModel<DetachedCriteria> criteria) {
|
||||
this.criteria = criteria;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void query(String term, int page, Response<Team> 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<Team> teams = (List<Team>) 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<Team> toChoices(Collection<String> ids) {
|
||||
List<Team> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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<User> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public void query(String term, int page, Response<User> response) {
|
||||
if (Strings.isNullOrEmpty(term)) {
|
||||
return;
|
||||
}
|
||||
|
||||
UserManager um = Gitop.getInstance(UserManager.class);
|
||||
int first = page * 10;
|
||||
List<User> 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<User> toChoices(Collection<String> ids) {
|
||||
List<User> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,17 @@
|
||||
var UserChoice = UserChoice || {};
|
||||
UserChoice.formatter = {
|
||||
formatSelection: function(user) {
|
||||
return "<img class='img-thumbnail avatar' src='" + user.avatar + "' /> " + user.name + " (" + user.displayName + ")";
|
||||
},
|
||||
|
||||
formatResult: function(user) {
|
||||
return "<div class='user-choice-row'><img class='img-thumbnail avatar avatar-big' src='" + user.avatar + "' />"
|
||||
+ "<p>"+ user.name + " (" + user.displayName + ")" + "</p>"
|
||||
+ "<p class='text-muted'>" + user.email + "</p>"
|
||||
+ "</div>";
|
||||
},
|
||||
|
||||
escapeMarkup: function(m) {
|
||||
return m;
|
||||
}
|
||||
};
|
||||
@ -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<T extends AbstractEntity> extends LoadableDetachableModel<T> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected T entity;
|
||||
private final Class<T> entityClass;
|
||||
|
||||
protected GeneralDao getDao() {
|
||||
return AppLoader.getInstance(GeneralDao.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public EntityModel(T entity) {
|
||||
this.entity = entity;
|
||||
this.entityClass = (Class<T>) 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<T> 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<T>) entity.getClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected T load() {
|
||||
if (entity.isNew()) {
|
||||
return entity;
|
||||
} else {
|
||||
return getDao().get(entityClass, entity.getId());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
package com.pmease.gitop.web.model;
|
||||
|
||||
import com.pmease.gitop.core.model.Team;
|
||||
|
||||
public class TeamModel extends EntityModel<Team> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public TeamModel(Team team) {
|
||||
super(team);
|
||||
}
|
||||
|
||||
}
|
||||
@ -183,7 +183,7 @@ public abstract class BasePage extends WebPage {
|
||||
|
||||
protected void onPageInitialize() {
|
||||
if (!isPermitted()) {
|
||||
throw new AccessDeniedException();
|
||||
throw new AccessDeniedException("Access denied");
|
||||
}
|
||||
|
||||
add(new Label("title", getPageTitle()));
|
||||
|
||||
@ -1,9 +1,14 @@
|
||||
package com.pmease.gitop.web.page;
|
||||
|
||||
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
|
||||
import org.apache.wicket.markup.html.link.Link;
|
||||
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||
|
||||
import com.pmease.gitop.core.model.Project;
|
||||
import com.pmease.gitop.core.model.User;
|
||||
import com.pmease.gitop.web.component.avatar.AvatarImage.AvatarImageType;
|
||||
import com.pmease.gitop.web.page.account.AccountHomePage;
|
||||
import com.pmease.gitop.web.page.project.ProjectHomePage;
|
||||
import com.pmease.gitop.web.util.WicketUtils;
|
||||
|
||||
public class PageSpec {
|
||||
@ -11,11 +16,30 @@ public class PageSpec {
|
||||
public static final String ID = "id";
|
||||
public static final String TYPE = "type";
|
||||
public static final String USER = "user";
|
||||
public static final String PROJECT = "project";
|
||||
public static final String REPO = "repo";
|
||||
public static final String TAB = "tab";
|
||||
|
||||
|
||||
public static PageParameters avatarOfUser(User user) {
|
||||
return WicketUtils.newPageParams(TYPE, AvatarImageType.USER.name().toLowerCase(),
|
||||
ID, String.valueOf(user.getId()));
|
||||
return WicketUtils.newPageParams(TYPE, AvatarImageType.USER.name()
|
||||
.toLowerCase(), ID, String.valueOf(user.getId()));
|
||||
}
|
||||
|
||||
public static PageParameters forUser(User user) {
|
||||
return WicketUtils.newPageParams(USER, user.getName());
|
||||
}
|
||||
|
||||
public static PageParameters forProject(Project project) {
|
||||
return WicketUtils.newPageParams(USER, project.getOwner().getName(),
|
||||
PROJECT, project.getName());
|
||||
}
|
||||
|
||||
public static Link<?> newUserHomeLink(String id, User user) {
|
||||
return new BookmarkablePageLink<Void>(id, AccountHomePage.class, forUser(user));
|
||||
}
|
||||
|
||||
public static Link<?> newProjectHomeLink(String id, Project project) {
|
||||
return new BookmarkablePageLink<Void>(id, ProjectHomePage.class, forProject(project));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -51,9 +51,7 @@ public class RegisterPage extends AbstractLayoutPage {
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
add(form);
|
||||
|
||||
|
||||
@ -6,15 +6,24 @@
|
||||
</div>
|
||||
<div class="body">
|
||||
<h4>Anonymous Users</h4>
|
||||
<p><a>Anonymous users can browse and pull any repositories under this account </a></p>
|
||||
<p><a class="checkable-link" wicket:id="anonymouslink"><i class="icon-checkbox"></i> Anonymous users can browse and pull any repositories under this account </a></p>
|
||||
<hr/>
|
||||
|
||||
<h4>Logged-in Users</h4>
|
||||
<p class="text-muted">Logged-in users can access any repositories under this account with permission:</p>
|
||||
<p>Logged-in users can access any repositories under this account with permission:</p>
|
||||
<div class="btn-group btn-group-justified btn-radio-group" wicket:id="loggedInPermissions">
|
||||
<wicket:container wicket:id="permissions">
|
||||
<a wicket:id="permission" class="btn">
|
||||
<span class="icon-ok"></span>
|
||||
<span wicket:id="name"></span>
|
||||
</a>
|
||||
</wicket:container>
|
||||
</div>
|
||||
<hr/>
|
||||
|
||||
<h4>Teams</h4>
|
||||
<p class="text-muted"></p>
|
||||
<p class="text-muted">Manage teams and grant the permissions so that all members in the team can have the permission to access any repositories under this account.</p>
|
||||
<wicket:container wicket:id="teams"></wicket:container>
|
||||
</div>
|
||||
</section>
|
||||
</wicket:extend>
|
||||
|
||||
@ -1,5 +1,20 @@
|
||||
package com.pmease.gitop.web.page.account.setting.permission;
|
||||
|
||||
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||
import org.apache.wicket.ajax.markup.html.AjaxLink;
|
||||
import org.apache.wicket.behavior.AttributeAppender;
|
||||
import org.apache.wicket.markup.html.WebMarkupContainer;
|
||||
import org.apache.wicket.markup.html.basic.Label;
|
||||
import org.apache.wicket.markup.html.list.ListItem;
|
||||
import org.apache.wicket.markup.html.list.ListView;
|
||||
import org.apache.wicket.model.AbstractReadOnlyModel;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.pmease.gitop.core.Gitop;
|
||||
import com.pmease.gitop.core.manager.UserManager;
|
||||
import com.pmease.gitop.core.model.User;
|
||||
import com.pmease.gitop.core.permission.operation.GeneralOperation;
|
||||
import com.pmease.gitop.web.model.UserModel;
|
||||
import com.pmease.gitop.web.page.account.setting.AccountSettingPage;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@ -15,4 +30,81 @@ public class AccountPermissionPage extends AccountSettingPage {
|
||||
return Category.PERMISSION;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPageInitialize() {
|
||||
super.onPageInitialize();
|
||||
|
||||
AjaxLink<?> link = new AjaxLink<Void>("anonymouslink") {
|
||||
|
||||
@Override
|
||||
public void onClick(AjaxRequestTarget target) {
|
||||
User account = getAccount();
|
||||
account.setPubliclyAccessible(!account.isPubliclyAccessible());
|
||||
Gitop.getInstance(UserManager.class).save(account);
|
||||
|
||||
target.add(this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
add(link);
|
||||
link.setOutputMarkupId(true);
|
||||
link.add(AttributeAppender.append("class", new AbstractReadOnlyModel<String>() {
|
||||
|
||||
@Override
|
||||
public String getObject() {
|
||||
return getAccount().isPubliclyAccessible() ?
|
||||
"checked" : "";
|
||||
}
|
||||
|
||||
}));
|
||||
|
||||
WebMarkupContainer loggedInPermissions = new WebMarkupContainer("loggedInPermissions");
|
||||
add(loggedInPermissions);
|
||||
loggedInPermissions.setOutputMarkupId(true);
|
||||
loggedInPermissions.add(new ListView<GeneralOperation>("permissions",
|
||||
ImmutableList.<GeneralOperation>of(GeneralOperation.NO_ACCESS, GeneralOperation.READ, GeneralOperation.WRITE)) {
|
||||
|
||||
@Override
|
||||
protected void populateItem(ListItem<GeneralOperation> item) {
|
||||
AjaxLink<?> link = new PermissionLink("permission", item.getModelObject());
|
||||
item.add(link);
|
||||
link.add(new Label("name", item.getModelObject().toString()));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
add(new TeamsPanel("teams", new UserModel(getAccount())));
|
||||
}
|
||||
|
||||
class PermissionLink extends AjaxLink<Void> {
|
||||
final GeneralOperation permssion;
|
||||
|
||||
PermissionLink(String id, final GeneralOperation permission) {
|
||||
super(id);
|
||||
this.permssion = permission;
|
||||
|
||||
add(AttributeAppender.append("class", new AbstractReadOnlyModel<String>() {
|
||||
|
||||
@Override
|
||||
public String getObject() {
|
||||
return getAccount().getDefaultAuthorizedOperation() == permission ?
|
||||
"btn-default active" : "btn-default";
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(AjaxRequestTarget target) {
|
||||
User account = getAccount();
|
||||
if (account.getDefaultAuthorizedOperation() == permssion) {
|
||||
return;
|
||||
}
|
||||
|
||||
account.setDefaultAuthorizedOperation(permssion);
|
||||
Gitop.getInstance(UserManager.class).save(account);
|
||||
|
||||
target.add(AccountPermissionPage.this.get("loggedInPermissions"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
package com.pmease.gitop.web.page.account.setting.permission;
|
||||
|
||||
import com.pmease.gitop.core.model.Team;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class AddTeamPage extends EditTeamPage {
|
||||
|
||||
public AddTeamPage() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Team getTeam() {
|
||||
return new Team();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
<html xmlns:wicket>
|
||||
<wicket:extend>
|
||||
<section>
|
||||
<div class="head">
|
||||
<h2 wicket:id="head">Edit Team</h2>
|
||||
</div>
|
||||
<div class="body">
|
||||
<div wicket:id="editor"></div>
|
||||
</div>
|
||||
</section>
|
||||
</wicket:extend>
|
||||
</html>
|
||||
@ -0,0 +1,59 @@
|
||||
package com.pmease.gitop.web.page.account.setting.permission;
|
||||
|
||||
import org.apache.wicket.markup.html.basic.Label;
|
||||
import org.apache.wicket.model.AbstractReadOnlyModel;
|
||||
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||
|
||||
import com.pmease.gitop.core.Gitop;
|
||||
import com.pmease.gitop.core.manager.TeamManager;
|
||||
import com.pmease.gitop.core.model.Team;
|
||||
import com.pmease.gitop.web.model.TeamModel;
|
||||
import com.pmease.gitop.web.model.UserModel;
|
||||
import com.pmease.gitop.web.page.account.setting.AccountSettingPage;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class EditTeamPage extends AccountSettingPage {
|
||||
|
||||
protected final Long teamId;
|
||||
|
||||
public EditTeamPage() {
|
||||
this.teamId = null;
|
||||
}
|
||||
|
||||
public EditTeamPage(PageParameters params) {
|
||||
this.teamId = params.get("teamId").toLongObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Category getSettingCategory() {
|
||||
return Category.PERMISSION;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPageTitle() {
|
||||
return "Edit Team";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPageInitialize() {
|
||||
super.onPageInitialize();
|
||||
|
||||
add(new TeamEditor("editor", new UserModel(getAccount()), new TeamModel(getTeam())));
|
||||
add(new Label("head", new AbstractReadOnlyModel<String>() {
|
||||
|
||||
@Override
|
||||
public String getObject() {
|
||||
return getTeam().isNew() ? "Create Team" : "Edit Team";
|
||||
}
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
protected Team getTeam() {
|
||||
if (teamId == null) {
|
||||
throw new IllegalStateException("Team id cannot be null when editing team");
|
||||
} else {
|
||||
return Gitop.getInstance(TeamManager.class).get(teamId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
<html xmlns:wicket>
|
||||
<wicket:panel>
|
||||
<form class="form-inline" wicket:id="infoForm">
|
||||
<div wicket:id="feedback" class="form-feedback"></div>
|
||||
<p>Team Name:</p>
|
||||
<input class="form-control focusable" type="text" placeholder="Team Name" wicket:id="name" />
|
||||
<div class="btn-group btn-radio-group btn-group-permissions" wicket:id="permissionContainer">
|
||||
<wicket:container wicket:id="permissions">
|
||||
<a wicket:id="permission" class="btn btn-default">
|
||||
<span class="icon-ok"></span>
|
||||
<span wicket:id="name"></span>
|
||||
</a>
|
||||
</wicket:container>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-colorful-text" wicket:id="submit"><span wicket:id="label"></span></button>
|
||||
</form>
|
||||
|
||||
<wicket:container wicket:id="span">
|
||||
<hr />
|
||||
<h4>Members</h4>
|
||||
<form class="form-inline" wicket:id="membersForm">
|
||||
<div class="form-feedback" wicket:id="feedback"></div>
|
||||
<input wicket:id="userchoice" class="user-choice" type="hidden" style="width: 300px"></input>
|
||||
<button type="submit" class="btn btn-success btn-colorful-text" wicket:id="submit"><i class="icon-plus"></i> Add</button>
|
||||
</form>
|
||||
<hr/>
|
||||
<div>
|
||||
<h4 class="text-muted"><b wicket:id="total"></b> members total</h4>
|
||||
<div class="member-list clearfix">
|
||||
<div class="members first" wicket:id="oddlist">
|
||||
</div>
|
||||
<div class="members last" wicket:id="evenlist">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</wicket:container>
|
||||
|
||||
<wicket:fragment wicket:id="membersview">
|
||||
<ul class="list-group list-view list-group-hoverable">
|
||||
<li class="list-group-item" wicket:id="member">
|
||||
<span class="avatar" wicket:id="avatar"></span>
|
||||
<a class="name" wicket:id="link">
|
||||
<span wicket:id="name"></span>
|
||||
(<em wicket:id="fullname"></em>)
|
||||
</a>
|
||||
<div class="item-actions">
|
||||
<a class="img-link" wicket:id="remove"><i class="icon-remove-sign"></i></a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</wicket:fragment>
|
||||
|
||||
</wicket:panel>
|
||||
</html>
|
||||
@ -0,0 +1,344 @@
|
||||
package com.pmease.gitop.web.page.account.setting.permission;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.wicket.Component;
|
||||
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||
import org.apache.wicket.ajax.markup.html.AjaxLink;
|
||||
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
|
||||
import org.apache.wicket.behavior.AttributeAppender;
|
||||
import org.apache.wicket.markup.html.WebMarkupContainer;
|
||||
import org.apache.wicket.markup.html.basic.Label;
|
||||
import org.apache.wicket.markup.html.form.Form;
|
||||
import org.apache.wicket.markup.html.form.TextField;
|
||||
import org.apache.wicket.markup.html.link.Link;
|
||||
import org.apache.wicket.markup.html.list.ListItem;
|
||||
import org.apache.wicket.markup.html.list.ListView;
|
||||
import org.apache.wicket.markup.html.panel.Fragment;
|
||||
import org.apache.wicket.markup.html.panel.Panel;
|
||||
import org.apache.wicket.model.AbstractReadOnlyModel;
|
||||
import org.apache.wicket.model.IModel;
|
||||
import org.apache.wicket.model.LoadableDetachableModel;
|
||||
import org.apache.wicket.model.PropertyModel;
|
||||
import org.apache.wicket.validation.IValidatable;
|
||||
import org.apache.wicket.validation.IValidator;
|
||||
import org.apache.wicket.validation.ValidationError;
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.pmease.gitop.core.Gitop;
|
||||
import com.pmease.gitop.core.manager.MembershipManager;
|
||||
import com.pmease.gitop.core.manager.TeamManager;
|
||||
import com.pmease.gitop.core.model.Membership;
|
||||
import com.pmease.gitop.core.model.Team;
|
||||
import com.pmease.gitop.core.model.User;
|
||||
import com.pmease.gitop.core.permission.operation.GeneralOperation;
|
||||
import com.pmease.gitop.web.common.component.messenger.Messenger;
|
||||
import com.pmease.gitop.web.common.form.FeedbackPanel;
|
||||
import com.pmease.gitop.web.component.avatar.AvatarImage;
|
||||
import com.pmease.gitop.web.component.choice.SingleUserChoice;
|
||||
import com.pmease.gitop.web.model.UserModel;
|
||||
import com.pmease.gitop.web.page.PageSpec;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class TeamEditor extends Panel {
|
||||
|
||||
private final IModel<User> userModel;
|
||||
|
||||
private WebMarkupContainer membersContainer;
|
||||
|
||||
public TeamEditor(String id, IModel<User> userModel, IModel<Team> model) {
|
||||
super(id, model);
|
||||
this.userModel = userModel;
|
||||
this.setOutputMarkupId(true);
|
||||
}
|
||||
|
||||
private User getAccount() {
|
||||
return userModel.getObject();
|
||||
}
|
||||
|
||||
private Team getTeam() {
|
||||
return (Team) getDefaultModelObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
this.name = getTeam().getName();
|
||||
this.operation = getTeam().getAuthorizedOperation();
|
||||
|
||||
add(createInfoForm());
|
||||
|
||||
membersContainer = new WebMarkupContainer("span") {
|
||||
@Override
|
||||
protected void onConfigure() {
|
||||
super.onConfigure();
|
||||
this.setVisibilityAllowed(!getTeam().isNew());
|
||||
}
|
||||
};
|
||||
add(membersContainer);
|
||||
membersContainer.setOutputMarkupId(true);
|
||||
|
||||
membersContainer.add(createMembersForm());
|
||||
|
||||
final IModel<List<Membership>> relationModel = new LoadableDetachableModel<List<Membership>>() {
|
||||
|
||||
@Override
|
||||
protected List<Membership> load() {
|
||||
Team team = getTeam();
|
||||
if (team.isNew()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<Membership> r = Gitop.getInstance(MembershipManager.class)
|
||||
.query(Restrictions.eq("team", getTeam()));
|
||||
|
||||
Collections.sort(r, new java.util.Comparator<Membership>() {
|
||||
|
||||
@Override
|
||||
public int compare(Membership o1, Membership o2) {
|
||||
return o1.getUser().getName()
|
||||
.compareTo(o2.getUser().getName());
|
||||
}
|
||||
});
|
||||
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
membersContainer.add(createMemberList("oddlist", relationModel, true));
|
||||
membersContainer.add(createMemberList("evenlist", relationModel, false));
|
||||
membersContainer.add(new Label("total", new AbstractReadOnlyModel<Integer>() {
|
||||
|
||||
@Override
|
||||
public Integer getObject() {
|
||||
return relationModel.getObject().size();
|
||||
}
|
||||
}).setOutputMarkupId(true));
|
||||
}
|
||||
|
||||
private GeneralOperation operation;
|
||||
private String name;
|
||||
|
||||
private Form<?> createInfoForm() {
|
||||
operation = getTeam().getAuthorizedOperation();
|
||||
Form<?> infoForm = new Form<Void>("infoForm");
|
||||
add(infoForm);
|
||||
infoForm.add(new FeedbackPanel("feedback"));
|
||||
infoForm.add(new TextField<String>("name", new PropertyModel<String>(
|
||||
this, "name")).add(new IValidator<String>() {
|
||||
|
||||
@Override
|
||||
public void validate(IValidatable<String> validatable) {
|
||||
TeamManager tm = Gitop.getInstance(TeamManager.class);
|
||||
Team team = tm.find(getAccount(), validatable.getValue());
|
||||
Team current = getTeam();
|
||||
if (team != null && !Objects.equal(team, current)) {
|
||||
validatable.error(new ValidationError()
|
||||
.setMessage("The team is already exist."));
|
||||
}
|
||||
}
|
||||
}).setRequired(true));
|
||||
WebMarkupContainer permissionContainer = new WebMarkupContainer(
|
||||
"permissionContainer");
|
||||
permissionContainer.setOutputMarkupId(true);
|
||||
infoForm.add(permissionContainer);
|
||||
permissionContainer.add(new ListView<GeneralOperation>("permissions",
|
||||
ImmutableList.<GeneralOperation> of(
|
||||
GeneralOperation.READ,
|
||||
GeneralOperation.WRITE,
|
||||
GeneralOperation.ADMIN)) {
|
||||
|
||||
@Override
|
||||
protected void populateItem(ListItem<GeneralOperation> item) {
|
||||
GeneralOperation permission = item.getModelObject();
|
||||
AjaxLink<?> link = new PermissionLink("permission", permission);
|
||||
link.add(new Label("name", permission.toString()));
|
||||
item.add(link);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
AjaxButton btn = new AjaxButton("submit", infoForm) {
|
||||
@Override
|
||||
protected void onError(AjaxRequestTarget target, Form<?> form) {
|
||||
target.add(form);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
|
||||
Team team = getTeam();
|
||||
boolean isNew = team.isNew();
|
||||
User owner = getAccount();
|
||||
Preconditions.checkNotNull(owner, "owner");
|
||||
|
||||
team.setName(name);
|
||||
team.setAuthorizedOperation(operation);
|
||||
team.setOwner(owner);
|
||||
|
||||
Gitop.getInstance(TeamManager.class).save(team);
|
||||
target.add(TeamEditor.this);
|
||||
|
||||
Messenger.success(
|
||||
String.format("Team has been %s successfully.",
|
||||
isNew ? "created" : "updated")).run(target);
|
||||
}
|
||||
};
|
||||
|
||||
btn.add(new Label("label", new AbstractReadOnlyModel<String>() {
|
||||
|
||||
@Override
|
||||
public String getObject() {
|
||||
return getTeam().isNew() ? "Create Team" : "Update Team";
|
||||
}
|
||||
|
||||
}));
|
||||
|
||||
infoForm.add(btn);
|
||||
|
||||
return infoForm;
|
||||
}
|
||||
|
||||
class PermissionLink extends AjaxLink<Void> {
|
||||
final GeneralOperation permission;
|
||||
|
||||
PermissionLink(String id, final GeneralOperation permission) {
|
||||
super(id);
|
||||
this.permission = permission;
|
||||
|
||||
add(AttributeAppender.append("class",
|
||||
new AbstractReadOnlyModel<String>() {
|
||||
|
||||
@Override
|
||||
public String getObject() {
|
||||
return Objects.equal(operation, permission) ?
|
||||
"active" : "";
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(AjaxRequestTarget target) {
|
||||
if (Objects.equal(operation, permission)) {
|
||||
return;
|
||||
}
|
||||
|
||||
operation = permission;
|
||||
target.add(TeamEditor.this.get("infoForm").get("permissionContainer"));
|
||||
}
|
||||
}
|
||||
|
||||
User userToAdd;
|
||||
|
||||
private Form<?> createMembersForm() {
|
||||
Form<?> form = new Form<Void>("membersForm");
|
||||
form.add(new FeedbackPanel("feedback"));
|
||||
form.add(new SingleUserChoice("userchoice", new PropertyModel<User>(
|
||||
this, "userToAdd")));
|
||||
|
||||
form.add(new AjaxButton("submit", form) {
|
||||
@Override
|
||||
protected void onError(AjaxRequestTarget target, Form<?> form) {
|
||||
form.error("Please fix errors below.");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
|
||||
if (userToAdd == null) {
|
||||
form.error("Please select an user first");
|
||||
target.add(form);
|
||||
return;
|
||||
}
|
||||
|
||||
Team team = getTeam();
|
||||
MembershipManager mm = Gitop
|
||||
.getInstance(MembershipManager.class);
|
||||
Membership m = mm.find(Restrictions.eq("team", team),
|
||||
Restrictions.eq("user", userToAdd));
|
||||
if (m != null) {
|
||||
form.warn("User has been added already");
|
||||
target.add(form);
|
||||
return;
|
||||
}
|
||||
|
||||
m = new Membership();
|
||||
m.setUser(userToAdd);
|
||||
m.setTeam(team);
|
||||
mm.save(m);
|
||||
|
||||
Messenger.success(String.format("User [%s] is added to team [%s]",
|
||||
userToAdd.getName(), team.getName()))
|
||||
.run(target);
|
||||
userToAdd = null;
|
||||
target.add(form);
|
||||
onMembersChanged(target);
|
||||
}
|
||||
});
|
||||
|
||||
return form;
|
||||
}
|
||||
|
||||
private void onMembersChanged(AjaxRequestTarget target) {
|
||||
target.add(membersContainer.get("oddlist"));
|
||||
target.add(membersContainer.get("evenlist"));
|
||||
target.add(membersContainer.get("total"));
|
||||
}
|
||||
|
||||
private Component createMemberList(String id,
|
||||
IModel<List<Membership>> model, final boolean expected) {
|
||||
Fragment frag = new Fragment(id, "membersview", this);
|
||||
frag.setOutputMarkupId(true);
|
||||
frag.add(new ListView<Membership>("member", model) {
|
||||
|
||||
@Override
|
||||
protected void populateItem(ListItem<Membership> item) {
|
||||
int index = item.getIndex();
|
||||
boolean odd = index % 2 == 0;
|
||||
if (odd != expected) {
|
||||
item.setVisibilityAllowed(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Membership membership = item.getModelObject();
|
||||
User user = membership.getUser();
|
||||
item.add(new AvatarImage("avatar", new UserModel(user)));
|
||||
Link<?> link = PageSpec.newUserHomeLink("link", user);
|
||||
link.add(new Label("name", user.getName()));
|
||||
link.add(new Label("fullname", user.getDisplayName()));
|
||||
item.add(link);
|
||||
|
||||
final Long id = membership.getId();
|
||||
item.add(new AjaxLink<Void>("remove") {
|
||||
|
||||
@Override
|
||||
public void onClick(AjaxRequestTarget target) {
|
||||
MembershipManager mm = Gitop.getInstance(MembershipManager.class);
|
||||
Membership membership = mm.get(id);
|
||||
Gitop.getInstance(MembershipManager.class).delete(membership);
|
||||
Messenger.warn(String.format("User [%s] is removed from team [%s]",
|
||||
membership.getUser().getName(),
|
||||
membership.getTeam().getName()))
|
||||
.run(target);
|
||||
|
||||
onMembersChanged(target);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
if (userModel != null) {
|
||||
userModel.detach();
|
||||
}
|
||||
|
||||
super.onDetach();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
<html xmlns:wicket>
|
||||
<wicket:panel>
|
||||
<p>
|
||||
<a class="btn btn-info" wicket:id="addTeam"><i class="icon-plus"></i> Create a team</a>
|
||||
</p>
|
||||
<table class="table table-condensed table-hover" wicket:id="teams"></table>
|
||||
|
||||
<wicket:fragment wicket:id="ops">
|
||||
<div class="action-links">
|
||||
<span class="link-item"><a wicket:id="edit"><i class="icon-edit"></i> edit</a></span>
|
||||
<span class="link-item"><a wicket:id="remove"><i class="icon-remove-sign"></i> remove</a></span>
|
||||
</div>
|
||||
</wicket:fragment>
|
||||
|
||||
<wicket:fragment wicket:id="namefrag">
|
||||
<span wicket:id="name"></span> <span class="text-muted">(<b wicket:id="members"></b> members)</span>
|
||||
</wicket:fragment>
|
||||
</wicket:panel>
|
||||
</html>
|
||||
@ -0,0 +1,214 @@
|
||||
package com.pmease.gitop.web.page.account.setting.permission;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.wicket.Component;
|
||||
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||
import org.apache.wicket.ajax.markup.html.AjaxLink;
|
||||
import org.apache.wicket.behavior.AttributeAppender;
|
||||
import org.apache.wicket.event.IEvent;
|
||||
import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackHeadersToolbar;
|
||||
import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
|
||||
import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
|
||||
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
|
||||
import org.apache.wicket.extensions.markup.html.repeater.data.table.NoRecordsToolbar;
|
||||
import org.apache.wicket.markup.html.basic.Label;
|
||||
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
|
||||
import org.apache.wicket.markup.html.panel.Fragment;
|
||||
import org.apache.wicket.markup.html.panel.Panel;
|
||||
import org.apache.wicket.markup.repeater.Item;
|
||||
import org.apache.wicket.model.AbstractReadOnlyModel;
|
||||
import org.apache.wicket.model.IModel;
|
||||
import org.apache.wicket.model.Model;
|
||||
import org.hibernate.criterion.Criterion;
|
||||
import org.hibernate.criterion.DetachedCriteria;
|
||||
import org.hibernate.criterion.MatchMode;
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.pmease.gitop.core.Gitop;
|
||||
import com.pmease.gitop.core.manager.TeamManager;
|
||||
import com.pmease.gitop.core.model.Team;
|
||||
import com.pmease.gitop.core.model.User;
|
||||
import com.pmease.gitop.core.permission.operation.GeneralOperation;
|
||||
import com.pmease.gitop.web.common.bootstrap.AjaxIconLink;
|
||||
import com.pmease.gitop.web.common.bootstrap.IconType;
|
||||
import com.pmease.gitop.web.common.component.datagrid.DataGrid;
|
||||
import com.pmease.gitop.web.common.component.datagrid.event.SearchStringChanged;
|
||||
import com.pmease.gitop.web.common.component.datagrid.hibernate.HibernateDataProvider;
|
||||
import com.pmease.gitop.web.common.component.datagrid.toolbar.SearchNavToolbar;
|
||||
import com.pmease.gitop.web.common.component.vex.AjaxConfirmLink;
|
||||
import com.pmease.gitop.web.util.WicketUtils;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class TeamsPanel extends Panel {
|
||||
|
||||
public TeamsPanel(String id, IModel<User> user) {
|
||||
super(id, user);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
add(new BookmarkablePageLink<Void>("addTeam", AddTeamPage.class));
|
||||
add(createTeamPermissionsTable("teams"));
|
||||
}
|
||||
|
||||
private Component createTeamPermissionsTable(String id) {
|
||||
List<IColumn<Team, String>> columns = Lists.newArrayList();
|
||||
columns.add(new AbstractColumn<Team, String>(Model.of("Name"), "name") {
|
||||
|
||||
@Override
|
||||
public void populateItem(Item<ICellPopulator<Team>> cellItem,
|
||||
String componentId, IModel<Team> rowModel) {
|
||||
Team team = rowModel.getObject();
|
||||
Fragment frag = new Fragment(componentId, "namefrag",
|
||||
TeamsPanel.this);
|
||||
frag.add(new Label("name", team.getName()));
|
||||
frag.add(new Label("members", team.getMemberships().size()));
|
||||
cellItem.add(frag);
|
||||
}
|
||||
});
|
||||
|
||||
columns.add(new TeamPermissionColumn(Model.of("Read"), GeneralOperation.READ));
|
||||
columns.add(new TeamPermissionColumn(Model.of("Write"), GeneralOperation.WRITE));
|
||||
columns.add(new TeamPermissionColumn(Model.of("Admin"), GeneralOperation.ADMIN));
|
||||
|
||||
columns.add(new AbstractColumn<Team, String>(Model.of("")) {
|
||||
|
||||
@Override
|
||||
public void populateItem(Item<ICellPopulator<Team>> cellItem,
|
||||
String componentId, final IModel<Team> rowModel) {
|
||||
Fragment frag = new Fragment(componentId, "ops", TeamsPanel.this);
|
||||
frag.add(new BookmarkablePageLink<Void>("edit",
|
||||
EditTeamPage.class, WicketUtils.newPageParams("teamId", rowModel.getObject().getId())));
|
||||
|
||||
Team team = rowModel.getObject();
|
||||
frag.add(new AjaxConfirmLink<Void>("remove",
|
||||
Model.of("Are you sure you want to remove team " + team.getName())) {
|
||||
|
||||
@Override
|
||||
public void onClick(AjaxRequestTarget target) {
|
||||
Team p = rowModel.getObject();
|
||||
Gitop.getInstance(TeamManager.class).delete(p);
|
||||
onTeamTableChanged(target);
|
||||
}
|
||||
});
|
||||
cellItem.add(frag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCssClass() {
|
||||
return "operations-td";
|
||||
}
|
||||
});
|
||||
|
||||
final List<Criterion> criterions = Lists.newArrayList();
|
||||
|
||||
HibernateDataProvider<Team> teamProvider = new HibernateDataProvider<Team>() {
|
||||
|
||||
@Override
|
||||
protected DetachedCriteria getCriteria() {
|
||||
DetachedCriteria criteria = DetachedCriteria.forClass(Team.class);
|
||||
criteria.add(Restrictions.eq("owner", getUser()));
|
||||
for (Criterion each : criterions) {
|
||||
criteria.add(each);
|
||||
}
|
||||
|
||||
return criteria;
|
||||
}
|
||||
};
|
||||
|
||||
DataGrid<Team> dataTable = new DataGrid<Team>(id, columns,
|
||||
teamProvider, 10) {
|
||||
@Override
|
||||
public void onEvent(IEvent<?> event) {
|
||||
if (event.getPayload() instanceof SearchStringChanged) {
|
||||
SearchStringChanged e = (SearchStringChanged) event.getPayload();
|
||||
|
||||
criterions.clear();
|
||||
|
||||
if (!Strings.isNullOrEmpty(e.getPattern())) {
|
||||
criterions.add(Restrictions.ilike("name", e.getPattern(), MatchMode.ANYWHERE));
|
||||
}
|
||||
|
||||
e.getTarget().add(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
dataTable.setOutputMarkupId(true);
|
||||
dataTable.addTopToolbar(new AjaxFallbackHeadersToolbar<String>(dataTable, teamProvider));
|
||||
dataTable.addBottomToolbar(new NoRecordsToolbar(dataTable, Model.of("No Teams Found")));
|
||||
dataTable.addBottomToolbar(new SearchNavToolbar(dataTable));
|
||||
|
||||
return dataTable;
|
||||
}
|
||||
|
||||
private class TeamPermissionColumn extends AbstractColumn<Team, String> {
|
||||
|
||||
private GeneralOperation expected;
|
||||
|
||||
public TeamPermissionColumn(IModel<String> displayModel,
|
||||
GeneralOperation expected) {
|
||||
super(displayModel);
|
||||
this.expected = expected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateItem(Item<ICellPopulator<Team>> cellItem,
|
||||
String componentId, final IModel<Team> rowModel) {
|
||||
IModel<IconType> iconModel = new AbstractReadOnlyModel<IconType>() {
|
||||
|
||||
@Override
|
||||
public IconType getObject() {
|
||||
return rowModel.getObject().getAuthorizedOperation().can(expected) ?
|
||||
IconType.CHECK : IconType.CHECK_EMPTY;
|
||||
}
|
||||
};
|
||||
|
||||
cellItem.add(new AjaxIconLink(componentId, iconModel) {
|
||||
|
||||
@Override
|
||||
protected AjaxLink<?> createLink(String id) {
|
||||
AjaxLink<?> link = new AjaxLink<Void>(id) {
|
||||
|
||||
@Override
|
||||
public void onClick(AjaxRequestTarget target) {
|
||||
GeneralOperation old = rowModel.getObject().getAuthorizedOperation();
|
||||
Team team = rowModel.getObject();
|
||||
if (old == expected) {
|
||||
int ordinal = expected.ordinal() - 1;
|
||||
if (ordinal < 0) {
|
||||
ordinal = 0;
|
||||
}
|
||||
|
||||
team.setAuthorizedOperation(GeneralOperation.values()[ordinal]);
|
||||
} else {
|
||||
team.setAuthorizedOperation(expected);
|
||||
}
|
||||
|
||||
Gitop.getInstance(TeamManager.class).save(team);
|
||||
onTeamTableChanged(target);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
link.add(AttributeAppender.append("class", "permission-link"));
|
||||
return link;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void onTeamTableChanged(AjaxRequestTarget target) {
|
||||
target.add(get("teams"));
|
||||
}
|
||||
|
||||
private User getUser() {
|
||||
return (User) getDefaultModelObject();
|
||||
}
|
||||
|
||||
}
|
||||
@ -28,7 +28,7 @@
|
||||
<input type="file" wicket:id="fileInput" />
|
||||
</p>
|
||||
<p class="text-muted">
|
||||
Supported image types are png, gif, jpg and jpeg. The image size should be less than 128K bytes.
|
||||
Supported image types are png, gif, jpg and jpeg. The image size should be less than 2M bytes.
|
||||
</p>
|
||||
<hr/>
|
||||
<div class="btn-group btn-group-justified">
|
||||
|
||||
@ -13,6 +13,7 @@ import org.apache.wicket.markup.html.form.upload.FileUploadField;
|
||||
import org.apache.wicket.model.IModel;
|
||||
import org.apache.wicket.model.Model;
|
||||
import org.apache.wicket.model.PropertyModel;
|
||||
import org.apache.wicket.util.lang.Bytes;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.base.Throwables;
|
||||
@ -106,8 +107,13 @@ public class AccountProfilePage extends AccountSettingPage {
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
// limit avatar size to 2M bytes
|
||||
setMaxSize(Bytes.megabytes(2));
|
||||
setMultiPart(true);
|
||||
|
||||
final FileUploadField uploadField = new FileUploadField("fileInput");
|
||||
uploadField.setRequired(false);
|
||||
|
||||
add(uploadField);
|
||||
|
||||
add(new FeedbackPanel("feedback"));
|
||||
|
||||
@ -5,6 +5,7 @@ import org.apache.wicket.markup.html.form.Form;
|
||||
import org.apache.wicket.markup.html.form.RadioGroup;
|
||||
import org.apache.wicket.markup.html.list.ListItem;
|
||||
import org.apache.wicket.markup.html.list.ListView;
|
||||
import org.apache.wicket.model.AbstractReadOnlyModel;
|
||||
import org.apache.wicket.model.Model;
|
||||
import org.apache.wicket.model.PropertyModel;
|
||||
|
||||
@ -60,7 +61,14 @@ public class HomePage extends AbstractLayoutPage {
|
||||
|
||||
form.add(new AjaxConfirmButton("submit", form,
|
||||
Model.of("Are you sure you want to submit the form?"),
|
||||
Model.of(VexIcon.ERROR),
|
||||
new AbstractReadOnlyModel<VexIcon>() {
|
||||
|
||||
@Override
|
||||
public VexIcon getObject() {
|
||||
return vexIcon;
|
||||
}
|
||||
|
||||
},
|
||||
Model.of("Yes"),
|
||||
Model.of("No"),
|
||||
null) {
|
||||
|
||||
@ -0,0 +1,135 @@
|
||||
package com.pmease.gitop.web.resource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.apache.shiro.authc.credential.PasswordService;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.pmease.gitop.core.manager.UserManager;
|
||||
import com.pmease.gitop.core.model.User;
|
||||
import com.sun.jersey.api.client.Client;
|
||||
import com.sun.jersey.api.client.ClientHandlerException;
|
||||
import com.sun.jersey.api.client.UniformInterfaceException;
|
||||
import com.sun.jersey.api.client.WebResource;
|
||||
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
|
||||
|
||||
@Path("/github")
|
||||
public class GitHubUserResource {
|
||||
|
||||
@Inject ObjectMapper objectMapper;
|
||||
@Inject UserManager userManager;
|
||||
@Inject PasswordService passwordService;
|
||||
|
||||
@GET
|
||||
public Response get() {
|
||||
try {
|
||||
updateDatabase("github");
|
||||
} catch (Exception e) {
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
|
||||
return Response.ok("Everything is ok").build();
|
||||
}
|
||||
|
||||
private void updateDatabase(String org) throws JsonParseException,
|
||||
JsonMappingException, UniformInterfaceException,
|
||||
ClientHandlerException, IOException {
|
||||
Client client = Client.create();
|
||||
client.addFilter(new HTTPBasicAuthFilter("zhenyuluo", "hongmei9"));
|
||||
WebResource r = client.resource("https://api.github.com/orgs/" + org
|
||||
+ "/public_members");
|
||||
String content = r.get(String.class);
|
||||
objectMapper.configure(
|
||||
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
List<HubUser> users = objectMapper.readValue(content,
|
||||
new TypeReference<List<HubUser>>() {
|
||||
});
|
||||
users = users.subList(102, users.size());
|
||||
for (HubUser each : users) {
|
||||
try {
|
||||
r = client.resource("https://api.github.com/users/"
|
||||
+ each.login);
|
||||
HubUser u = objectMapper.readValue(r.get(String.class),
|
||||
HubUser.class);
|
||||
User user = new User();
|
||||
user.setName(u.login);
|
||||
user.setDisplayName(u.name);
|
||||
|
||||
if (Strings.isNullOrEmpty(u.email)) {
|
||||
user.setEmail(u.login + "@github.com");
|
||||
} else {
|
||||
user.setEmail(u.email);
|
||||
}
|
||||
|
||||
user.setPasswordHash(passwordService.encryptPassword("12345"));
|
||||
userManager.save(user);
|
||||
System.out.println(user.getId() + " " + user);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class HubUsers {
|
||||
@JsonProperty
|
||||
List<HubUser> users = Lists.newArrayList();
|
||||
|
||||
public List<HubUser> getUsers() {
|
||||
return users;
|
||||
}
|
||||
|
||||
public void setUsers(List<HubUser> users) {
|
||||
this.users = users;
|
||||
}
|
||||
}
|
||||
|
||||
public static class HubUser {
|
||||
@JsonProperty
|
||||
private String login;
|
||||
|
||||
@JsonProperty
|
||||
private String name;
|
||||
|
||||
@JsonProperty
|
||||
private String email;
|
||||
|
||||
public String getLogin() {
|
||||
return login;
|
||||
}
|
||||
|
||||
public void setLogin(String login) {
|
||||
this.login = login;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user