import java.net.InetAddress;\r
import java.net.Socket;\r
\r
+import org.eclipse.jgit.transport.Daemon;\r
import org.eclipse.jgit.transport.PacketLineIn;\r
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;\r
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;\r
import com.gitblit.Keys;\r
import com.gitblit.models.UserModel;\r
import com.gitblit.wicket.pages.BasePage;\r
-import com.gitblit.wicket.pages.RepositoriesPage;\r
\r
public class AuthorizationStrategy extends AbstractPageAuthorizationStrategy implements\r
IUnauthorizedComponentInstantiationListener {\r
@SuppressWarnings({ "unchecked", "rawtypes" })\r
@Override\r
protected boolean isPageAuthorized(Class pageClass) {\r
- if (RepositoriesPage.class.equals(pageClass)) {\r
- // allow all requests to get to the RepositoriesPage with its inline\r
+ if (GitBlitWebApp.HOME_PAGE_CLASS.equals(pageClass)) {\r
+ // allow all requests to get to the HomePage with its inline\r
// authentication form\r
return true;\r
}\r
public void onUnauthorizedInstantiation(Component component) {\r
\r
if (component instanceof BasePage) {\r
- throw new RestartResponseException(RepositoriesPage.class);\r
+ throw new RestartResponseException(GitBlitWebApp.HOME_PAGE_CLASS);\r
}\r
}\r
}\r
import com.gitblit.Keys;\r
import com.gitblit.utils.StringUtils;\r
import com.gitblit.wicket.pages.ActivityPage;\r
+import com.gitblit.wicket.pages.BasePage;\r
import com.gitblit.wicket.pages.BlamePage;\r
import com.gitblit.wicket.pages.BlobDiffPage;\r
import com.gitblit.wicket.pages.BlobPage;\r
import com.gitblit.wicket.pages.LuceneSearchPage;\r
import com.gitblit.wicket.pages.MarkdownPage;\r
import com.gitblit.wicket.pages.MetricsPage;\r
+import com.gitblit.wicket.pages.OverviewPage;\r
import com.gitblit.wicket.pages.PatchPage;\r
import com.gitblit.wicket.pages.ProjectPage;\r
import com.gitblit.wicket.pages.ProjectsPage;\r
\r
public class GitBlitWebApp extends WebApplication {\r
\r
+ public final static Class<? extends BasePage> HOME_PAGE_CLASS = RepositoriesPage.class;\r
+ \r
@Override\r
public void init() {\r
super.init();\r
}\r
\r
// setup the standard gitweb-ish urls\r
+// mount("/repositories", RepositoriesPage.class);\r
+ mount("/overview", OverviewPage.class, "r", "h");\r
mount("/summary", SummaryPage.class, "r");\r
+ mount("/commits", LogPage.class, "r", "h");\r
mount("/log", LogPage.class, "r", "h");\r
mount("/tags", TagsPage.class, "r");\r
mount("/branches", BranchesPage.class, "r");\r
\r
@Override\r
public Class<? extends Page> getHomePage() {\r
- return RepositoriesPage.class;\r
+ return HOME_PAGE_CLASS;\r
}\r
\r
@Override\r
gb.useIncrementalPushTagsDescription = on push, automatically tag each branch tip with an incremental revision number\r
gb.incrementalPushTagMessage = Auto-tagged [{0}] branch on push\r
gb.externalPermissions = {0} access permissions are externally maintained\r
-gb.viewAccess = You do not have Gitblit read or write access
\ No newline at end of file
+gb.viewAccess = You do not have Gitblit read or write access\r
+gb.overview = overview\r
+gb.home = home\r
+gb.monthlyActivity = monthly activity\r
+gb.myProfile = my profile
\ No newline at end of file
lang="en"> \r
<body>\r
<wicket:extend>\r
+ <div class="container">\r
<div class="pageTitle">\r
<h2><wicket:message key="gb.recentActivity"></wicket:message><small> <span class="hidden-phone">/ <span wicket:id="subheader">[days back]</span></span></small></h2>\r
</div>\r
</table>\r
</div>\r
<div wicket:id="activityPanel" style="padding-top:5px;" >[activity panel]</div>\r
+ </div>\r
</wicket:extend>\r
</body>\r
</html>
\ No newline at end of file
<span wicket:id="gbVersion"></span>\r
</a> \r
</p>\r
- <div wicket:id="userPanel">[user panel]</div>\r
</footer>\r
</div>\r
\r
<style>\r
@media (max-width: 979px) {\r
.nav-collapse .nav > li > a:hover, .nav-collapse .dropdown-menu a:hover {\r
- background-color: #000070;\r
+ background-color: #002060;\r
}\r
\r
.navbar div > ul .dropdown-menu li a {\r
<script type="text/javascript" src="bootstrap/js/jquery.js"></script>\r
<script type="text/javascript" src="bootstrap/js/bootstrap.js"></script> \r
</body>\r
- \r
- <!-- user fragment -->\r
- <wicket:fragment wicket:id="userFragment">\r
- <span class="userPanel" wicket:id="username"></span>\r
- <span class="userPanel" wicket:id="loginLink"></span>\r
- <span class="hidden-phone">\r
- <span class="userPanel" wicket:id="separator"></span>\r
- <span class="userPanel"><a wicket:id="changePasswordLink"><wicket:message key="gb.changePassword"></wicket:message></a></span>\r
- </span>\r
- </wicket:fragment>\r
- \r
</html>
\ No newline at end of file
import javax.servlet.http.HttpServletRequest;\r
\r
import org.apache.wicket.Application;\r
-import org.apache.wicket.MarkupContainer;\r
import org.apache.wicket.PageParameters;\r
import org.apache.wicket.RedirectToUrlException;\r
import org.apache.wicket.RestartResponseException;\r
import org.apache.wicket.markup.html.CSSPackageResource;\r
import org.apache.wicket.markup.html.basic.Label;\r
-import org.apache.wicket.markup.html.link.BookmarkablePageLink;\r
import org.apache.wicket.markup.html.link.ExternalLink;\r
import org.apache.wicket.markup.html.panel.FeedbackPanel;\r
-import org.apache.wicket.markup.html.panel.Fragment;\r
import org.apache.wicket.protocol.http.RequestUtils;\r
import org.apache.wicket.protocol.http.servlet.ServletWebRequest;\r
import org.slf4j.Logger;\r
import com.gitblit.models.UserModel;\r
import com.gitblit.utils.StringUtils;\r
import com.gitblit.utils.TimeUtils;\r
+import com.gitblit.wicket.GitBlitWebApp;\r
import com.gitblit.wicket.GitBlitWebSession;\r
import com.gitblit.wicket.WicketUtils;\r
-import com.gitblit.wicket.panels.LinkPanel;\r
\r
public abstract class BasePage extends SessionPage {\r
\r
add(new Label("title", siteName));\r
}\r
\r
- ExternalLink rootLink = new ExternalLink("rootLink", urlFor(RepositoriesPage.class, null).toString());\r
- WicketUtils.setHtmlTooltip(rootLink, siteName);\r
+ ExternalLink rootLink = new ExternalLink("rootLink", urlFor(GitBlitWebApp.HOME_PAGE_CLASS, null).toString());\r
+ WicketUtils.setHtmlTooltip(rootLink, GitBlit.getString(Keys.web.siteName, Constants.NAME));\r
add(rootLink);\r
\r
// Feedback panel for info, warning, and non-fatal error messages\r
add(new FeedbackPanel("feedback"));\r
\r
- // footer\r
- if (GitBlit.getBoolean(Keys.web.authenticateViewPages, true)\r
- || GitBlit.getBoolean(Keys.web.authenticateAdminPages, true)) {\r
- UserFragment userFragment = new UserFragment("userPanel", "userFragment", BasePage.this);\r
- add(userFragment);\r
- } else {\r
- add(new Label("userPanel", ""));\r
- }\r
-\r
add(new Label("gbVersion", "v" + Constants.getVersion()));\r
if (GitBlit.getBoolean(Keys.web.aggressiveHeapManagement, false)) {\r
System.gc();\r
}\r
error(message, true);\r
}\r
-\r
- /**\r
- * Panel fragment for displaying login or logout/change_password links.\r
- * \r
- */\r
- static class UserFragment extends Fragment {\r
-\r
- private static final long serialVersionUID = 1L;\r
-\r
- public UserFragment(String id, String markupId, MarkupContainer markupProvider) {\r
- super(id, markupId, markupProvider);\r
-\r
- GitBlitWebSession session = GitBlitWebSession.get();\r
- if (session.isLoggedIn()) { \r
- UserModel user = session.getUser();\r
- boolean editCredentials = GitBlit.self().supportsCredentialChanges(user);\r
- boolean standardLogin = session.authenticationType.isStandard();\r
-\r
- // username, logout, and change password\r
- add(new Label("username", user.getDisplayName() + ":"));\r
- add(new LinkPanel("loginLink", null, markupProvider.getString("gb.logout"),\r
- LogoutPage.class).setVisible(standardLogin));\r
- \r
- // quick and dirty hack for showing a separator\r
- add(new Label("separator", "|").setVisible(standardLogin && editCredentials));\r
- add(new BookmarkablePageLink<Void>("changePasswordLink", \r
- ChangePasswordPage.class).setVisible(editCredentials));\r
- } else {\r
- // login\r
- add(new Label("username").setVisible(false));\r
- add(new Label("loginLink").setVisible(false));\r
- add(new Label("separator").setVisible(false));\r
- add(new Label("changePasswordLink").setVisible(false));\r
- }\r
- }\r
- }\r
}\r
return getString("gb.blame");\r
}\r
\r
+ @Override\r
+ protected Class<? extends BasePage> getRepoNavPageClass() {\r
+ return TreePage.class;\r
+ }\r
+ \r
protected String missingBlob(String blobPath, RevCommit commit) {\r
StringBuilder sb = new StringBuilder();\r
sb.append("<div class=\"alert alert-error\">");\r
protected String getPageName() {\r
return getString("gb.diff");\r
}\r
+ \r
+ @Override\r
+ protected Class<? extends BasePage> getRepoNavPageClass() {\r
+ return TreePage.class;\r
+ }\r
}\r
protected String getPageName() {\r
return getString("gb.view");\r
}\r
+ \r
+ @Override\r
+ protected Class<? extends BasePage> getRepoNavPageClass() {\r
+ return TreePage.class;\r
+ }\r
}\r
protected String getPageName() {
return getString("gb.commitdiff");
}
+
+ @Override
+ protected Class<? extends BasePage> getRepoNavPageClass() {
+ return LogPage.class;
+ }
private RevCommit getCommit(Repository r, String rev)
{
protected String getPageName() {\r
return getString("gb.commit");\r
}\r
+ \r
+ @Override\r
+ protected Class<? extends BasePage> getRepoNavPageClass() {\r
+ return LogPage.class;\r
+ }\r
}\r
protected boolean requiresPageMap() {\r
return true;\r
}\r
+ \r
+ @Override\r
+ protected Class<? extends BasePage> getRootNavPageClass() {\r
+ return RepositoriesPage.class;\r
+ }\r
\r
protected void setupPage(RepositoryModel model) {\r
this.repositoryModel = model;\r
protected boolean requiresPageMap() {\r
return true;\r
}\r
+ \r
+ @Override\r
+ protected Class<? extends BasePage> getRootNavPageClass() {\r
+ return UsersPage.class;\r
+ }\r
\r
protected void setupPage(final TeamModel teamModel) {\r
if (isCreate) {\r
protected boolean requiresPageMap() {\r
return true;\r
}\r
+ \r
+ @Override\r
+ protected Class<? extends BasePage> getRootNavPageClass() {\r
+ return UsersPage.class;\r
+ }\r
\r
protected void setupPage(final UserModel userModel) {\r
if (isCreate) {\r
\r
<body>\r
<wicket:extend>\r
-\r
+<div class="container">\r
<h2>Empty Repository</h2>\r
<p></p>\r
<div class="row">\r
<li><a href="http://www.sourcetreeapp.com/">SourceTree</a> - A free Git and Mercurial client for Windows & Mac</li>\r
<li><a href="http://www.git-tower.com/">Tower</a> - a Mac OS X Git client</li>\r
</ul>\r
+</div>\r
</wicket:extend> \r
</body>\r
</html>
\ No newline at end of file
add(new Label("cloneSyntax", MessageFormat.format("git clone {0}", primaryUrl)));\r
add(new Label("remoteSyntax", MessageFormat.format("git remote add gitblit {0}\ngit push gitblit master", primaryUrl)));\r
}\r
+ \r
+ @Override\r
+ protected Class<? extends BasePage> getRootNavPageClass() {\r
+ return RepositoriesPage.class;\r
+ }\r
}\r
\r
<body>\r
<wicket:extend>\r
-\r
+<div class="container">\r
<h2>Repositorio Vacío</h2>\r
<p></p>\r
<div class="row">\r
<li><a href="http://www.sourcetreeapp.com/">SourceTree</a> - Un cliente Git gratuito para Mac, Mercurial, y SVN</li>\r
<li><a href="http://www.git-tower.com/">Tower</a> - Cliente Git para Mac OS X</li>\r
</ul>\r
+</div> \r
</wicket:extend> \r
</body>\r
</html>\r
<body>
<wicket:extend>
-
+<div class="container">
<h2>비어있는 저장소</h2>
<p></p>
<div class="row">
<li><a href="http://www.sourcetreeapp.com/">SourceTree</a> - A free Mac Client for Git, Mercurial, and SVN</li>
<li><a href="http://www.git-tower.com/">Tower</a> - a Mac OS X Git client</li>
</ul>
+</div>
</wicket:extend>
</body>
</html>
\ No newline at end of file
\r
<body>\r
<wicket:extend>\r
-\r
+<div class="container">\r
<h2>Empty Repository</h2>\r
<p></p>\r
<div class="row">\r
<li><a href="http://www.sourcetreeapp.com/">SourceTree</a> - Een gratis Mac Client voor Git, Mercurial, en SVN</li>\r
<li><a href="http://www.git-tower.com/">Tower</a> - een Mac OS X Git client</li>\r
</ul>\r
+</div>\r
</wicket:extend> \r
</body>\r
</html>\r
<body>
<wicket:extend>
-
+<div class="container">
<h2>Puste repozytorium</h2>
<p></p>
<div class="row">
<li><a href="http://www.sourcetreeapp.com/">SourceTree</a> - darmowy klient GIT, Mercurial i SVN na Mac OS X</li>
<li><a href="http://www.git-tower.com/">Tower</a> - klient GIT na Mac OS X</li>
</ul>
+</div>
</wicket:extend>
</body>
</html>
\r
<body>\r
<wicket:extend>\r
-\r
+<div class="container">\r
<h2>Repositório Vazio</h2>\r
<p></p>\r
<div class="row">\r
<li><a href="http://www.sourcetreeapp.com/">SourceTree</a> - Client gratuito para o Mac que suporta Git, Mercurial e SVN</li>\r
<li><a href="http://www.git-tower.com/">Tower</a> - um Cliente do Git para Mac OS X</li>\r
</ul>\r
+</div>\r
</wicket:extend> \r
</body>\r
</html>
\ No newline at end of file
<body>
<wicket:extend>
-
+<div class="container">
<h2>空版本库</h2>
<p></p>
<div class="row">
<li><a href="http://www.sourcetreeapp.com/">SourceTree</a> - 免费的 Mac Git Mercurial 以及 SVN 客户端, Mercurial, and SVN</li>
<li><a href="http://www.git-tower.com/">Tower</a> - Mac OS X Git 客户端</li>
</ul>
+</div>
</wicket:extend>
</body>
</html>
\ No newline at end of file
lang="en"> \r
<body>\r
<wicket:extend>\r
-\r
+<div class="container">\r
<div wicket:id="federationTokensPanel">[federation tokens panel]</div>\r
\r
<div style="padding-top: 10px;" wicket:id="federationProposalsPanel">[federation proposals panel]</div>\r
\r
<div style="padding-top: 10px;" wicket:id="federationRegistrationsPanel">[federation registrations panel]</div>\r
-\r
+</div>\r
</wicket:extend>\r
</body>\r
</html>
\ No newline at end of file
};\r
add(dataView);\r
}\r
+ \r
+ @Override\r
+ protected Class<? extends BasePage> getRootNavPageClass() {\r
+ return FederationPage.class;\r
+ }\r
}\r
<wicket:extend>\r
\r
<!-- pager links -->\r
- <div style="padding-top:5px;">\r
- <a wicket:id="firstPageTop"><wicket:message key="gb.pageFirst"></wicket:message></a> | <a wicket:id="prevPageTop"><wicket:message key="gb.pagePrevious"></wicket:message></a> | <a wicket:id="nextPageTop"><wicket:message key="gb.pageNext"></wicket:message></a> \r
+ <div class="page_nav2">\r
+ <a wicket:id="firstPageTop"><wicket:message key="gb.pageFirst"></wicket:message></a> | <a wicket:id="prevPageTop">« <wicket:message key="gb.pagePrevious"></wicket:message></a> | <a wicket:id="nextPageTop"><wicket:message key="gb.pageNext"></wicket:message> »</a> \r
</div>\r
\r
<!-- history -->\r
\r
<!-- pager links -->\r
<div style="padding-bottom:5px;">\r
- <a wicket:id="firstPageBottom"><wicket:message key="gb.pageFirst"></wicket:message></a> | <a wicket:id="prevPageBottom"><wicket:message key="gb.pagePrevious"></wicket:message></a> | <a wicket:id="nextPageBottom"><wicket:message key="gb.pageNext"></wicket:message></a> \r
+ <a wicket:id="firstPageBottom"><wicket:message key="gb.pageFirst"></wicket:message></a> | <a wicket:id="prevPageBottom">« <wicket:message key="gb.pagePrevious"></wicket:message></a> | <a wicket:id="nextPageBottom"><wicket:message key="gb.pageNext"></wicket:message> »</a> \r
</div>\r
\r
</wicket:extend>\r
protected String getPageName() {\r
return getString("gb.search");\r
}\r
+ \r
+ @Override\r
+ protected Class<? extends BasePage> getRepoNavPageClass() {\r
+ return LogPage.class;\r
+ }\r
}\r
lang="en"> \r
<body>\r
<wicket:extend>\r
+<div class="container">\r
<div class="pageTitle">\r
<h2>Gravatar<small> / <span wicket:id="username">[username]</span></small></h2>\r
</div>\r
<p></p>\r
<a wicket:id="profileLink"><wicket:message key="gb.completeGravatarProfile">[Complete profile on Gravatar.com]</wicket:message></a>\r
<p></p>\r
+</div>\r
</wicket:extend>\r
</body>\r
</html>
\ No newline at end of file
<wicket:extend>\r
\r
<!-- pager links -->\r
- <div style="padding-top:5px;">\r
- <a wicket:id="firstPageTop"><wicket:message key="gb.pageFirst"></wicket:message></a> | <a wicket:id="prevPageTop"><wicket:message key="gb.pagePrevious"></wicket:message></a> | <a wicket:id="nextPageTop"><wicket:message key="gb.pageNext"></wicket:message></a> \r
+ <div class="page_nav2">\r
+ <a wicket:id="firstPageTop"><wicket:message key="gb.pageFirst"></wicket:message></a> | <a wicket:id="prevPageTop">« <wicket:message key="gb.pagePrevious"></wicket:message></a> | <a wicket:id="nextPageTop"><wicket:message key="gb.pageNext"></wicket:message> »</a> \r
</div>\r
\r
<!-- history -->\r
\r
<!-- pager links -->\r
<div style="padding-bottom:5px;">\r
- <a wicket:id="firstPageBottom"><wicket:message key="gb.pageFirst"></wicket:message></a> | <a wicket:id="prevPageBottom"><wicket:message key="gb.pagePrevious"></wicket:message></a> | <a wicket:id="nextPageBottom"><wicket:message key="gb.pageNext"></wicket:message></a> \r
+ <a wicket:id="firstPageBottom"><wicket:message key="gb.pageFirst"></wicket:message></a> | <a wicket:id="prevPageBottom">« <wicket:message key="gb.pagePrevious"></wicket:message></a> | <a wicket:id="nextPageBottom"><wicket:message key="gb.pageNext"></wicket:message> »</a> \r
</div>\r
\r
</wicket:extend>\r
protected String getPageName() {\r
return getString("gb.history");\r
}\r
+ \r
+ @Override\r
+ protected Class<? extends BasePage> getRepoNavPageClass() {\r
+ return TreePage.class;\r
+ }\r
}\r
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r
+<html xmlns="http://www.w3.org/1999/xhtml" \r
+ xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd" \r
+ xml:lang="en" \r
+ lang="en"> \r
+\r
+<body>\r
+<wicket:extend>\r
+<div class="container">\r
+ <div class="markdown" style="padding-bottom:5px;" wicket:id="repositoriesMessage">[repositories message]</div>\r
+ \r
+<!-- <div wicket:id="repositoriesPanel">[repositories panel]</div> -->\r
+</div>\r
+</wicket:extend>\r
+</body>\r
+</html>
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright 2011 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit.wicket.pages;\r
+\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.InputStream;\r
+import java.io.InputStreamReader;\r
+import java.text.MessageFormat;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.apache.wicket.Component;\r
+import org.apache.wicket.PageParameters;\r
+import org.apache.wicket.markup.html.basic.Label;\r
+import org.eclipse.jgit.lib.Constants;\r
+\r
+import com.gitblit.GitBlit;\r
+import com.gitblit.Keys;\r
+import com.gitblit.utils.MarkdownUtils;\r
+import com.gitblit.utils.StringUtils;\r
+import com.gitblit.wicket.GitBlitWebApp;\r
+import com.gitblit.wicket.GitBlitWebSession;\r
+import com.gitblit.wicket.PageRegistration;\r
+import com.gitblit.wicket.PageRegistration.DropDownMenuItem;\r
+import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration;\r
+\r
+public class HomePage extends RootPage {\r
+\r
+ public HomePage() {\r
+ super();\r
+ setup(null);\r
+ }\r
+\r
+ public HomePage(PageParameters params) {\r
+ super(params);\r
+ setup(params);\r
+ }\r
+\r
+ @Override\r
+ protected boolean reusePageParameters() {\r
+ return true;\r
+ }\r
+\r
+ private void setup(PageParameters params) {\r
+ setupPage("", "");\r
+ // check to see if we should display a login message\r
+ boolean authenticateView = GitBlit.getBoolean(Keys.web.authenticateViewPages, true);\r
+ if (authenticateView && !GitBlitWebSession.get().isLoggedIn()) {\r
+ String messageSource = GitBlit.getString(Keys.web.loginMessage, "gitblit");\r
+ String message = readMarkdown(messageSource, "login.mkd");\r
+ Component repositoriesMessage = new Label("repositoriesMessage", message);\r
+ add(repositoriesMessage.setEscapeModelStrings(false));\r
+ add(new Label("repositoriesPanel"));\r
+ return;\r
+ }\r
+\r
+ // Load the markdown welcome message\r
+ String messageSource = GitBlit.getString(Keys.web.repositoriesMessage, "gitblit");\r
+ String message = readMarkdown(messageSource, "welcome.mkd");\r
+ Component repositoriesMessage = new Label("repositoriesMessage", message)\r
+ .setEscapeModelStrings(false).setVisible(message.length() > 0);\r
+ add(repositoriesMessage);\r
+\r
+// List<RepositoryModel> repositories = getRepositories(params);\r
+//\r
+// RepositoriesPanel repositoriesPanel = new RepositoriesPanel("repositoriesPanel", showAdmin,\r
+// true, repositories, true, getAccessRestrictions());\r
+// // push the panel down if we are hiding the admin controls and the\r
+// // welcome message\r
+// if (!showAdmin && !repositoriesMessage.isVisible()) {\r
+// WicketUtils.setCssStyle(repositoriesPanel, "padding-top:5px;");\r
+// }\r
+// add(repositoriesPanel);\r
+ }\r
+\r
+ @Override\r
+ protected void addDropDownMenus(List<PageRegistration> pages) {\r
+ PageParameters params = getPageParameters();\r
+\r
+ DropDownMenuRegistration menu = new DropDownMenuRegistration("gb.filters",\r
+ GitBlitWebApp.HOME_PAGE_CLASS);\r
+ // preserve time filter option on repository choices\r
+ menu.menuItems.addAll(getRepositoryFilterItems(params));\r
+\r
+ // preserve repository filter option on time choices\r
+ menu.menuItems.addAll(getTimeFilterItems(params));\r
+\r
+ if (menu.menuItems.size() > 0) {\r
+ // Reset Filter\r
+ menu.menuItems.add(new DropDownMenuItem(getString("gb.reset"), null, null));\r
+ }\r
+\r
+ pages.add(menu);\r
+ }\r
+\r
+ private String readMarkdown(String messageSource, String resource) {\r
+ String message = "";\r
+ if (messageSource.equalsIgnoreCase("gitblit")) {\r
+ // Read default message\r
+ message = readDefaultMarkdown(resource);\r
+ } else {\r
+ // Read user-supplied message\r
+ if (!StringUtils.isEmpty(messageSource)) {\r
+ File file = GitBlit.getFileOrFolder(messageSource);\r
+ if (file.exists()) {\r
+ try {\r
+ FileInputStream fis = new FileInputStream(file);\r
+ InputStreamReader reader = new InputStreamReader(fis,\r
+ Constants.CHARACTER_ENCODING);\r
+ message = MarkdownUtils.transformMarkdown(reader);\r
+ reader.close();\r
+ } catch (Throwable t) {\r
+ message = getString("gb.failedToRead") + " " + file;\r
+ warn(message, t);\r
+ }\r
+ } else {\r
+ message = messageSource + " " + getString("gb.isNotValidFile");\r
+ }\r
+ }\r
+ }\r
+ return message;\r
+ }\r
+\r
+ private String readDefaultMarkdown(String file) {\r
+ String base = file.substring(0, file.lastIndexOf('.'));\r
+ String ext = file.substring(file.lastIndexOf('.'));\r
+ String lc = getLanguageCode();\r
+ String cc = getCountryCode();\r
+\r
+ // try to read file_en-us.ext, file_en.ext, file.ext\r
+ List<String> files = new ArrayList<String>();\r
+ if (!StringUtils.isEmpty(lc)) {\r
+ if (!StringUtils.isEmpty(cc)) {\r
+ files.add(base + "_" + lc + "-" + cc + ext);\r
+ files.add(base + "_" + lc + "_" + cc + ext);\r
+ }\r
+ files.add(base + "_" + lc + ext);\r
+ }\r
+ files.add(file);\r
+\r
+ for (String name : files) {\r
+ String message;\r
+ InputStreamReader reader = null;\r
+ try {\r
+ InputStream is = getClass().getResourceAsStream("/" + name);\r
+ if (is == null) {\r
+ continue;\r
+ }\r
+ reader = new InputStreamReader(is, Constants.CHARACTER_ENCODING);\r
+ message = MarkdownUtils.transformMarkdown(reader);\r
+ reader.close();\r
+ return message;\r
+ } catch (Throwable t) {\r
+ message = MessageFormat.format(getString("gb.failedToReadMessage"), file);\r
+ error(message, t, false);\r
+ return message;\r
+ } finally {\r
+ if (reader != null) {\r
+ try {\r
+ reader.close();\r
+ } catch (Exception e) {\r
+ }\r
+ }\r
+ } \r
+ }\r
+ return MessageFormat.format(getString("gb.failedToReadMessage"), file);\r
+ }\r
+}\r
<wicket:extend>\r
\r
<!-- pager links -->\r
- <div style="padding-top:5px;">\r
- <a wicket:id="firstPageTop"><wicket:message key="gb.pageFirst"></wicket:message></a> | <a wicket:id="prevPageTop"><wicket:message key="gb.pagePrevious"></wicket:message></a> | <a wicket:id="nextPageTop"><wicket:message key="gb.pageNext"></wicket:message></a> \r
+ <div class="page_nav2">\r
+ <a wicket:id="firstPageTop"><wicket:message key="gb.pageFirst"></wicket:message></a> | <a wicket:id="prevPageTop">« <wicket:message key="gb.pagePrevious"></wicket:message></a> | <a wicket:id="nextPageTop"><wicket:message key="gb.pageNext"></wicket:message> »</a> \r
</div>\r
\r
<!-- log -->\r
\r
<!-- pager links -->\r
<div style="padding-bottom:5px;">\r
- <a wicket:id="firstPageBottom"><wicket:message key="gb.pageFirst"></wicket:message></a> | <a wicket:id="prevPageBottom"><wicket:message key="gb.pagePrevious"></wicket:message></a> | <a wicket:id="nextPageBottom"><wicket:message key="gb.pageNext"></wicket:message></a> \r
+ <a wicket:id="firstPageBottom"><wicket:message key="gb.pageFirst"></wicket:message></a> | <a wicket:id="prevPageBottom">« <wicket:message key="gb.pagePrevious"></wicket:message></a> | <a wicket:id="nextPageBottom"><wicket:message key="gb.pageNext"></wicket:message> »</a> \r
</div>\r
\r
</wicket:extend>\r
\r
<wicket:extend>\r
<body onload="document.getElementById('query').focus(); prettyPrint();">\r
+<div class="container">\r
<div class="pageTitle">\r
<h2><wicket:message key="gb.search"></wicket:message></h2>\r
</div>\r
<!-- pager links -->\r
<div wicket:id="bottomPager"></div>\r
\r
- </div> \r
+ </div>\r
+ </div>\r
</body>\r
\r
<wicket:fragment wicket:id="tagsPanel">\r
protected String getPageName() {\r
return getString("gb.markdown");\r
}\r
+ \r
+ @Override\r
+ protected Class<? extends BasePage> getRepoNavPageClass() {\r
+ return DocsPage.class;\r
+ }\r
}\r
provider.addAxis(commitAxis);\r
\r
provider.setLineStyles(new LineStyle[] { new LineStyle(2, 4, 0), new LineStyle(0, 4, 1) });\r
- provider.addShapeMarker(new ShapeMarker(MarkerType.CIRCLE, Color.BLUE, 1, -1, 5));\r
+ provider.addShapeMarker(new ShapeMarker(MarkerType.CIRCLE, Color.decode("#002060"), 1, -1, 5));\r
\r
add(new Chart(wicketId, provider));\r
} else {\r
protected String getPageName() {\r
return getString("gb.metrics");\r
}\r
+ \r
+ @Override\r
+ protected Class<? extends BasePage> getRepoNavPageClass() {\r
+ return SummaryPage.class;\r
+ }\r
}\r
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r
+<html xmlns="http://www.w3.org/1999/xhtml" \r
+ xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd" \r
+ xml:lang="en" \r
+ lang="en"> \r
+<body>\r
+<wicket:extend>\r
+\r
+ <div class="row" style="clear:both;">\r
+ <div class="span6 hidden-phone" style="border-right: 1px solid #ddd; margin-right: -1px;">\r
+ \r
+ <!-- Repository info -->\r
+ <div>\r
+ <table class="summary">\r
+ <tr><th><wicket:message key="gb.description">[description]</wicket:message></th><td><span wicket:id="repositoryDescription">[repository description]</span></td></tr>\r
+ <tr><th><wicket:message key="gb.owners">[owner]</wicket:message></th><td><span wicket:id="repositoryOwners"><span wicket:id="owner"></span><span wicket:id="comma"></span></span></td></tr>\r
+ <tr><th><wicket:message key="gb.lastChange">[last change]</wicket:message></th><td><span wicket:id="repositoryLastChange">[repository last change]</span></td></tr>\r
+ <tr><th><wicket:message key="gb.size">[size]</wicket:message></th><td><span wicket:id="repositorySize">[repository size]</span></td></tr>\r
+ <tr class="hidden-phone hidden-tablet"><th style="vertical-align: top;"><wicket:message key="gb.stats">[stats]</wicket:message></th>\r
+ <td><div><span wicket:id="branchStats">[branch stats]</span> <span class="link"><a wicket:id="metrics"><wicket:message key="gb.metrics">[metrics]</wicket:message></a></span></div>\r
+ <span class="hidden-tablet" style="margin: 10px 0px;" id="chartDaily"></span>\r
+ </td></tr>\r
+ </table>\r
+\r
+ <ul class="nav nav-tabs" style="padding-top:10px;">\r
+ <li class="active"><a data-toggle="tab" href="#branches"><wicket:message key="gb.branches">[branches]</wicket:message></a></li>\r
+ <li><a data-toggle="tab" href="#tags"><wicket:message key="gb.tags">[tags]</wicket:message></a></li>\r
+ <li><a data-toggle="tab" href="#forks"><wicket:message key="gb.forks">[forks]</wicket:message></a></li>\r
+ </ul>\r
+ \r
+ <div class="tab-content">\r
+ <div class="tab-pane active" id="branches">\r
+ <!-- branches -->\r
+ <div style="padding: 0 15px 15px 0px;" wicket:id="branchesPanel">[branches panel]</div>\r
+ </div>\r
+ <div class="tab-pane" id="tags">\r
+ <!-- tags -->\r
+ <div style="padding: 0 15px 15px 0px;" wicket:id="tagsPanel">[tags panel]</div>\r
+ </div>\r
+ <div class="tab-pane" id="forks">\r
+ </div>\r
+ </div> \r
+ </div>\r
+ \r
+ </div>\r
+\r
+ <!-- pushes -->\r
+ <div class="span6">\r
+ <div class="hidden-tablet" style="padding-bottom: 10px; margin-bottom: 10px; border-bottom: 1px solid #ddd;" wicket:id="repositoryUrlPanel">[repository url panel]</div>\r
+ \r
+ <div wicket:id="pushesPanel">[pushes panel]</div> \r
+ </div>\r
+ </div>\r
+\r
+ <wicket:fragment wicket:id="ownersFragment">\r
+ \r
+ </wicket:fragment>\r
+</wicket:extend> \r
+</body>\r
+</html>
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright 2011 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit.wicket.pages;\r
+\r
+import java.text.MessageFormat;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.apache.wicket.PageParameters;\r
+import org.apache.wicket.behavior.HeaderContributor;\r
+import org.apache.wicket.markup.html.basic.Label;\r
+import org.apache.wicket.markup.html.link.BookmarkablePageLink;\r
+import org.apache.wicket.markup.repeater.Item;\r
+import org.apache.wicket.markup.repeater.data.DataView;\r
+import org.apache.wicket.markup.repeater.data.ListDataProvider;\r
+import org.eclipse.jgit.lib.Repository;\r
+\r
+import com.gitblit.GitBlit;\r
+import com.gitblit.Keys;\r
+import com.gitblit.models.Metric;\r
+import com.gitblit.models.RepositoryModel;\r
+import com.gitblit.models.UserModel;\r
+import com.gitblit.utils.JGitUtils;\r
+import com.gitblit.wicket.GitBlitWebSession;\r
+import com.gitblit.wicket.WicketUtils;\r
+import com.gitblit.wicket.charting.GoogleChart;\r
+import com.gitblit.wicket.charting.GoogleCharts;\r
+import com.gitblit.wicket.charting.GoogleLineChart;\r
+import com.gitblit.wicket.panels.BranchesPanel;\r
+import com.gitblit.wicket.panels.LinkPanel;\r
+import com.gitblit.wicket.panels.PushesPanel;\r
+import com.gitblit.wicket.panels.RepositoryUrlPanel;\r
+import com.gitblit.wicket.panels.TagsPanel;\r
+\r
+public class OverviewPage extends RepositoryPage {\r
+\r
+ public OverviewPage(PageParameters params) {\r
+ super(params);\r
+\r
+ int numberRefs = GitBlit.getInteger(Keys.web.summaryRefsCount, 5);\r
+\r
+ Repository r = getRepository();\r
+ final RepositoryModel model = getRepositoryModel();\r
+ UserModel user = GitBlitWebSession.get().getUser();\r
+ if (user == null) {\r
+ user = UserModel.ANONYMOUS;\r
+ }\r
+\r
+ List<Metric> metrics = null;\r
+ Metric metricsTotal = null;\r
+ if (!model.skipSummaryMetrics && GitBlit.getBoolean(Keys.web.generateActivityGraph, true)) {\r
+ metrics = GitBlit.self().getRepositoryDefaultMetrics(model, r);\r
+ metricsTotal = metrics.remove(0);\r
+ }\r
+\r
+ addSyndicationDiscoveryLink();\r
+\r
+ // repository description\r
+ add(new Label("repositoryDescription", getRepositoryModel().description));\r
+ \r
+ // owner links\r
+ final List<String> owners = new ArrayList<String>(getRepositoryModel().owners);\r
+ ListDataProvider<String> ownersDp = new ListDataProvider<String>(owners);\r
+ DataView<String> ownersView = new DataView<String>("repositoryOwners", ownersDp) {\r
+ private static final long serialVersionUID = 1L;\r
+ int counter = 0;\r
+ public void populateItem(final Item<String> item) {\r
+ UserModel ownerModel = GitBlit.self().getUserModel(item.getModelObject());\r
+ if (ownerModel != null) {\r
+ item.add(new LinkPanel("owner", null, ownerModel.getDisplayName(), UserPage.class,\r
+ WicketUtils.newUsernameParameter(ownerModel.username)).setRenderBodyOnly(true));\r
+ } else {\r
+ item.add(new Label("owner").setVisible(false));\r
+ }\r
+ counter++;\r
+ item.add(new Label("comma", ",").setVisible(counter < owners.size()));\r
+ item.setRenderBodyOnly(true);\r
+ }\r
+ };\r
+ ownersView.setRenderBodyOnly(true);\r
+ add(ownersView);\r
+ \r
+ add(WicketUtils.createTimestampLabel("repositoryLastChange",\r
+ JGitUtils.getLastChange(r), getTimeZone(), getTimeUtils()));\r
+ add(new Label("repositorySize", model.size));\r
+ \r
+ if (metricsTotal == null) {\r
+ add(new Label("branchStats", ""));\r
+ } else {\r
+ add(new Label("branchStats",\r
+ MessageFormat.format(getString("gb.branchStats"), metricsTotal.count,\r
+ metricsTotal.tag, getTimeUtils().duration(metricsTotal.duration))));\r
+ }\r
+ add(new BookmarkablePageLink<Void>("metrics", MetricsPage.class,\r
+ WicketUtils.newRepositoryParameter(repositoryName)));\r
+\r
+ add(new RepositoryUrlPanel("repositoryUrlPanel", false, user, model));\r
+\r
+ PushesPanel pushes = new PushesPanel("pushesPanel", getRepositoryModel(), r, 10, 0);\r
+ add(pushes);\r
+ add(new TagsPanel("tagsPanel", repositoryName, r, numberRefs).hideIfEmpty());\r
+ add(new BranchesPanel("branchesPanel", getRepositoryModel(), r, numberRefs, false).hideIfEmpty());\r
+\r
+ // Display an activity line graph\r
+ insertActivityGraph(metrics);\r
+ }\r
+\r
+ @Override\r
+ protected String getPageName() {\r
+ return getString("gb.overview");\r
+ }\r
+\r
+ private void insertActivityGraph(List<Metric> metrics) {\r
+ if ((metrics != null) && (metrics.size() > 0)\r
+ && GitBlit.getBoolean(Keys.web.generateActivityGraph, true)) {\r
+ \r
+ // daily line chart\r
+ GoogleChart chart = new GoogleLineChart("chartDaily", "", "unit",\r
+ getString("gb.commits"));\r
+ for (Metric metric : metrics) {\r
+ chart.addValue(metric.name, metric.count);\r
+ }\r
+ chart.setWidth(375);\r
+ chart.setHeight(150);\r
+ \r
+ GoogleCharts charts = new GoogleCharts();\r
+ charts.addChart(chart);\r
+ add(new HeaderContributor(charts));\r
+ }\r
+ }\r
+}\r
<body>\r
<wicket:extend>\r
\r
-\r
+<div class="container">\r
<div class="row">\r
<div class="span12">\r
<h2><span wicket:id="projectTitle"></span> <small><span wicket:id="projectDescription"></span></small>\r
\r
</div>\r
</div>\r
+ </div>\r
</wicket:extend>\r
</body>\r
</html>
\ No newline at end of file
\r
<body>\r
<wicket:extend>\r
+<div class="container">\r
<div class="markdown" style="padding-bottom:5px;" wicket:id="projectsMessage">[projects message]</div>\r
\r
<table class="repositories">\r
</tr>\r
</tbody>\r
</table>\r
-\r
+</div>\r
</wicket:extend>\r
</body>\r
</html>
\ No newline at end of file
\r
<body>\r
<wicket:extend>\r
+<div class="container">\r
<div class="markdown" style="padding-bottom:5px;" wicket:id="repositoriesMessage">[repositories message]</div>\r
\r
<div wicket:id="repositoriesPanel">[repositories panel]</div>\r
+</div>\r
</wicket:extend>\r
</body>\r
</html>
\ No newline at end of file
\r
<body>\r
<wicket:extend>\r
- <!-- page nav links -->\r
- <div class="navbar navbar-fixed-top">\r
- <div class="navbar-inner">\r
+ <div class="repositorynavbar">\r
+ <div class="repositorynavbar-inner">\r
<div class="container">\r
- <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">\r
- <span class="icon-bar"></span>\r
- <span class="icon-bar"></span>\r
- <span class="icon-bar"></span>\r
- </a>\r
- <a class="brand" wicket:id="rootLink">\r
- <img src="gitblt_25_white.png" width="79" height="25" alt="gitblit" class="logo"/>\r
- </a>\r
- \r
- <div class="nav-collapse" wicket:id="navPanel"></div>\r
- \r
- <a class="hidden-phone hidden-tablet brand" style="text-decoration: none;" wicket:id="syndication" wicket:message="title:gb.feed">\r
- <img style="border:0px;vertical-align:middle;" src="feed_16x16.png"></img>\r
- </a>\r
- \r
- <form class="hidden-phone hidden-tablet pull-right" style="margin-top:10px;" wicket:id="searchForm">\r
- <span class="search">\r
- <select class="small" wicket:id="searchType"/> \r
- <input type="text" id="searchBox" wicket:id="searchBox" value=""/>\r
- </span>\r
- </form>\r
- </div>\r
- </div>\r
- </div>\r
- \r
- <!-- page content -->\r
- <div class="container">\r
- <div style="text-align:center;" wicket:id="feedback">[Feedback Panel]</div>\r
-\r
- <!-- page header -->\r
- <div class="pageTitle">\r
- <div class="row">\r
- <div class="controls">\r
- <span wicket:id="workingCopyIndicator"></span>\r
- <span class="hidden-phone hidden-tablet" wicket:id="forksProhibitedIndicator"></span>\r
- <div class="hidden-phone btn-group pull-right">\r
- <!-- future spot for other repo buttons -->\r
- <a class="btn btn-info" wicket:id="myForkLink"><img style="border:0px;vertical-align:middle;" src="fork_16x16.png"></img> <wicket:message key="gb.myFork"></wicket:message></a>\r
- <a class="btn btn-info" wicket:id="forkLink"><img style="border:0px;vertical-align:middle;" src="fork_16x16.png"></img> <wicket:message key="gb.fork"></wicket:message></a>\r
+ \r
+ <div class="title">\r
+ <div class="row">\r
+ <!-- search form -->\r
+ <div class="hidden-phone pull-right">\r
+ <form class="form-search" style="margin: 0px;" wicket:id="searchForm">\r
+ <div class="input-append">\r
+ <select class="span2" style="border-radius: 4px;" wicket:id="searchType"/>\r
+ <input type="text" class="search-query" style="width: 170px;border-radius: 14px 0 0 14px; padding-left: 14px;" id="searchBox" wicket:id="searchBox" value=""/>\r
+ <button class="btn" style="border-radius: 0 14px 14px 0px;margin-left:-5px;" type="submit"><i class="icon-search"></i></button>\r
+ </div>\r
+ </form>\r
+ </div>\r
+ \r
+ <div class="span7">\r
+ <div>\r
+ <span class="project" wicket:id="projectTitle">[project title]</span>/<span class="repository" wicket:id="repositoryName">[repository name]</span>\r
+ <a class="hidden-phone hidden-tablet" style="text-decoration: none;" wicket:id="syndication" wicket:message="title:gb.feed">\r
+ <img style="border:0px;vertical-align:baseline;" src="feed_16x16.png"></img>\r
+ </a>\r
+ </div>\r
+ <span wicket:id="originRepository">[origin repository]</span> \r
+ </div>\r
</div>\r
</div>\r
- <div class="span7">\r
- <div><span class="project" wicket:id="projectTitle">[project title]</span>/<span class="repository" wicket:id="repositoryName">[repository name]</span> <span class="hidden-phone"><span wicket:id="pageName">[page name]</span></span></div>\r
- <span wicket:id="originRepository">[origin repository]</span>\r
+ \r
+ <div>\r
+ <div class="hidden-phone btn-group pull-right" style="margin-top:5px;">\r
+ <!-- future spot for other repo buttons -->\r
+<!-- <a class="btn"><i class="icon-star-empty" style="padding-right:3px;"></i>star</a> -->\r
+<!-- <a class="btn"><i class="icon-envelope" style="padding-right:3px;"></i>subscribe</a> -->\r
+ <a class="btn" wicket:id="myForkLink"><img style="border:0px;vertical-align:middle;" src="fork-black_16x16.png"></img> <wicket:message key="gb.myFork"></wicket:message></a>\r
+ <a class="btn" wicket:id="forkLink"><img style="border:0px;vertical-align:middle;" src="fork-black_16x16.png"></img> <wicket:message key="gb.fork"></wicket:message></a>\r
+ </div>\r
+ \r
+ <div wicket:id="repositoryNavPanel"></div>\r
</div>\r
</div>\r
</div>\r
-\r
+ </div>\r
+ \r
+ <div class="container">\r
<wicket:child />\r
</div>\r
\r
<wicket:fragment wicket:id="originFragment">\r
<p class="originRepository"><wicket:message key="gb.forkedFrom">[forked from]</wicket:message> <span wicket:id="originRepository">[origin repository]</span></p>\r
</wicket:fragment>\r
- \r
- <wicket:fragment wicket:id="workingCopyFragment">\r
- <div class="pull-right" style="padding-top:0px;margin-bottom:0px;padding-left:5px">\r
- <span class="alert alert-info" style="padding: 6px 14px 6px 14px;vertical-align: middle;"><i class="icon-exclamation-sign"></i> <span class="hidden-phone" wicket:id="workingCopy" style="font-weight:bold;">[working copy]</span></span>\r
- </div>\r
- </wicket:fragment>\r
-\r
- <wicket:fragment wicket:id="forksProhibitedFragment">\r
- <div class="pull-right" style="padding-top:0px;margin-bottom:0px;padding-left:5px">\r
- <span class="alert alert-error" style="padding: 6px 14px 6px 14px;vertical-align: middle;"><i class="icon-ban-circle"></i> <span class="hidden-phone" wicket:id="forksProhibited" style="font-weight:bold;">[forks prohibited]</span></span>\r
- </div>\r
- </wicket:fragment>\r
- \r
+ \r
</wicket:extend>\r
</body>\r
</html>
\ No newline at end of file
import com.gitblit.models.UserModel;\r
import com.gitblit.utils.ArrayUtils;\r
import com.gitblit.utils.JGitUtils;\r
+import com.gitblit.utils.PushLogUtils;\r
import com.gitblit.utils.StringUtils;\r
import com.gitblit.utils.TicgitUtils;\r
import com.gitblit.wicket.GitBlitWebSession;\r
import com.gitblit.wicket.panels.NavigationPanel;\r
import com.gitblit.wicket.panels.RefsPanel;\r
\r
-public abstract class RepositoryPage extends BasePage {\r
+public abstract class RepositoryPage extends RootPage {\r
\r
protected final String projectName;\r
protected final String repositoryName;\r
\r
// standard page links\r
List<PageRegistration> pages = new ArrayList<PageRegistration>(registeredPages.values());\r
- NavigationPanel navigationPanel = new NavigationPanel("navPanel", getClass(), pages);\r
+ NavigationPanel navigationPanel = new NavigationPanel("repositoryNavPanel", getRepoNavPageClass(), pages);\r
add(navigationPanel);\r
\r
add(new ExternalLink("syndication", SyndicationServlet.asLink(getRequest()\r
// set stateless page preference\r
setStatelessHint(true);\r
}\r
+ \r
+ @Override\r
+ protected Class<? extends BasePage> getRootNavPageClass() {\r
+ return RepositoriesPage.class;\r
+ }\r
\r
+ protected Class<? extends BasePage> getRepoNavPageClass() {\r
+ return getClass();\r
+ }\r
+ \r
private Map<String, PageRegistration> registerPages() {\r
PageParameters params = null;\r
if (!StringUtils.isEmpty(repositoryName)) {\r
}\r
Map<String, PageRegistration> pages = new LinkedHashMap<String, PageRegistration>();\r
\r
+ Repository r = getRepository();\r
+ RepositoryModel model = getRepositoryModel();\r
+\r
// standard links\r
- pages.put("repositories", new PageRegistration("gb.repositories", RepositoriesPage.class));\r
- pages.put("summary", new PageRegistration("gb.summary", SummaryPage.class, params));\r
- pages.put("log", new PageRegistration("gb.log", LogPage.class, params));\r
- pages.put("branches", new PageRegistration("gb.branches", BranchesPage.class, params));\r
- pages.put("tags", new PageRegistration("gb.tags", TagsPage.class, params));\r
+ if (PushLogUtils.getPushLogBranch(r) == null) {\r
+ pages.put("summary", new PageRegistration("gb.summary", SummaryPage.class, params));\r
+ } else {\r
+ pages.put("summary", new PageRegistration("gb.summary", SummaryPage.class, params));\r
+// pages.put("overview", new PageRegistration("gb.overview", OverviewPage.class, params));\r
+ }\r
+ pages.put("commits", new PageRegistration("gb.commits", LogPage.class, params));\r
pages.put("tree", new PageRegistration("gb.tree", TreePage.class, params));\r
if (GitBlit.getBoolean(Keys.web.allowForking, true)) {\r
pages.put("forks", new PageRegistration("gb.forks", ForksPage.class, params));\r
}\r
\r
// conditional links\r
- Repository r = getRepository();\r
- RepositoryModel model = getRepositoryModel();\r
-\r
// per-repository extra page links\r
if (model.useTickets && TicgitUtils.getTicketsBranch(r) != null) {\r
pages.put("tickets", new PageRegistration("gb.tickets", TicketsPage.class, params));\r
}\r
- if (model.useDocs) {\r
+ if (model.showReadme || model.useDocs) {\r
pages.put("docs", new PageRegistration("gb.docs", DocsPage.class, params));\r
}\r
if (JGitUtils.getPagesBranch(r) != null) {\r
}\r
}\r
\r
- if (getRepositoryModel().isBare) {\r
- add(new Label("workingCopyIndicator").setVisible(false));\r
- } else {\r
- Fragment wc = new Fragment("workingCopyIndicator", "workingCopyFragment", this);\r
- Label lbl = new Label("workingCopy", getString("gb.workingCopy"));\r
- WicketUtils.setHtmlTooltip(lbl, getString("gb.workingCopyWarning"));\r
- wc.add(lbl);\r
- add(wc);\r
- }\r
-\r
// fork controls\r
if (!allowForkControls() || user == null || !user.isAuthenticated) {\r
// must be logged-in to fork, hide all fork controls\r
add(new ExternalLink("forkLink", "").setVisible(false));\r
add(new ExternalLink("myForkLink", "").setVisible(false));\r
- add(new Label("forksProhibitedIndicator").setVisible(false));\r
} else {\r
String fork = GitBlit.self().getFork(user.username, model.name);\r
boolean hasFork = fork != null;\r
// user not allowed to fork or fork already exists or repo forbids forking\r
add(new ExternalLink("forkLink", "").setVisible(false));\r
\r
- if (user.canFork() && !model.allowForks) {\r
- // show forks prohibited indicator\r
- Fragment wc = new Fragment("forksProhibitedIndicator", "forksProhibitedFragment", this);\r
- Label lbl = new Label("forksProhibited", getString("gb.forksProhibited"));\r
- WicketUtils.setHtmlTooltip(lbl, getString("gb.forksProhibitedWarning"));\r
- wc.add(lbl);\r
- add(wc);\r
- } else {\r
- // can not fork, no need for forks prohibited indicator\r
- add(new Label("forksProhibitedIndicator").setVisible(false));\r
- }\r
- \r
if (hasFork && !fork.equals(model.name)) {\r
// user has fork, view my fork link\r
String url = getRequestCycle().urlFor(SummaryPage.class, WicketUtils.newRepositoryParameter(fork)).toString();\r
}\r
} else if (canFork) {\r
// can fork and we do not have one\r
- add(new Label("forksProhibitedIndicator").setVisible(false));\r
add(new ExternalLink("myForkLink", "").setVisible(false));\r
String url = getRequestCycle().urlFor(ForkPage.class, WicketUtils.newRepositoryParameter(model.name)).toString();\r
add(new ExternalLink("forkLink", url));\r
public void onSubmit() {\r
Constants.SearchType searchType = searchTypeModel.getObject();\r
String searchString = searchBoxModel.getObject();\r
- if (searchString == null) {\r
+ if (StringUtils.isEmpty(searchString)) {\r
+ // redirect to self to avoid wicket page update bug \r
+ PageParameters params = RepositoryPage.this.getPageParameters();\r
+ String relativeUrl = urlFor(RepositoryPage.this.getClass(), params).toString();\r
+ String absoluteUrl = RequestUtils.toAbsolutePath(relativeUrl);\r
+ getRequestCycle().setRequestTarget(new RedirectRequestTarget(absoluteUrl));\r
return;\r
}\r
for (Constants.SearchType type : Constants.SearchType.values()) {\r
\r
<div class="nav-collapse" wicket:id="navPanel"></div>\r
\r
- <form class="pull-right" wicket:id="loginForm" style="padding-top:3px;">\r
- <span class="form-search">\r
- <input wicket:id="username" class="input-small" type="text" />\r
- <input wicket:id="password" class="input-small" type="password" />\r
- <button class="btn btn-primary" type="submit"><wicket:message key="gb.login"></wicket:message></button>\r
- </span>\r
- </form>\r
+ <ul class="nav pull-right">\r
+ <span wicket:id="userPanel"></span>\r
+ </ul>\r
</div>\r
</div>\r
</div>\r
<!-- subclass content -->\r
<div class="container">\r
<div style="text-align:center" wicket:id="feedback">[Feedback Panel]</div>\r
- \r
- <wicket:child/>\r
</div>\r
+ \r
+ <wicket:child/>\r
+ \r
+ <wicket:fragment wicket:id="loginFormFragment">\r
+ <li>\r
+ <form class="pull-right" wicket:id="loginForm">\r
+ <span class="form-search">\r
+ <input wicket:id="username" class="input-small" type="text" />\r
+ <input wicket:id="password" class="input-small" type="password" />\r
+ <button class="btn btn-primary" type="submit"><wicket:message key="gb.login"></wicket:message></button>\r
+ </span>\r
+ </form>\r
+ </li>\r
+ </wicket:fragment>\r
+ \r
+ <!-- user fragment -->\r
+ <wicket:fragment wicket:id="userMenuFragment">\r
+ <li class="dropdown">\r
+ <a data-toggle="dropdown" class="dropdown-toggle" href="#"><span wicket:id="username"></span> <b class="caret"></b></a>\r
+ <ul class="dropdown-menu">\r
+ <li style="color:#ccc;padding-left:15px;font-weight:bold;"><span wicket:id="displayName"></span></li>\r
+ <li class="divider"></li>\r
+ <li><a wicket:id="myProfile"><wicket:message key="gb.myProfile"></wicket:message></a></li>\r
+ <li><a wicket:id="changePassword"><wicket:message key="gb.changePassword"></wicket:message></a></li>\r
+ <li class="divider"></li>\r
+ <li><a wicket:id="logout"><wicket:message key="gb.logout"></wicket:message></a></li>\r
+ </ul>\r
+ </li>\r
+ </wicket:fragment>\r
+ \r
</wicket:extend>\r
</body>\r
</html>
\ No newline at end of file
import java.util.concurrent.atomic.AtomicInteger;\r
import java.util.regex.Pattern;\r
\r
+import org.apache.wicket.MarkupContainer;\r
import org.apache.wicket.PageParameters;\r
+import org.apache.wicket.markup.html.basic.Label;\r
import org.apache.wicket.markup.html.form.PasswordTextField;\r
import org.apache.wicket.markup.html.form.TextField;\r
+import org.apache.wicket.markup.html.link.BookmarkablePageLink;\r
+import org.apache.wicket.markup.html.panel.Fragment;\r
import org.apache.wicket.model.IModel;\r
import org.apache.wicket.model.Model;\r
import org.apache.wicket.protocol.http.WebResponse;\r
import com.gitblit.wicket.PageRegistration.DropDownMenuItem;\r
import com.gitblit.wicket.SessionlessForm;\r
import com.gitblit.wicket.WicketUtils;\r
+import com.gitblit.wicket.panels.GravatarImage;\r
import com.gitblit.wicket.panels.NavigationPanel;\r
\r
/**\r
setStatelessHint(true);\r
}\r
}\r
+ \r
+ if (authenticateView || authenticateAdmin) {\r
+ if (GitBlitWebSession.get().isLoggedIn()) {\r
+ UserMenu userFragment = new UserMenu("userPanel", "userMenuFragment", RootPage.this);\r
+ add(userFragment);\r
+ } else {\r
+ LoginForm loginForm = new LoginForm("userPanel", "loginFormFragment", RootPage.this);\r
+ add(loginForm);\r
+ }\r
+ } else {\r
+ add(new Label("userPanel").setVisible(false));\r
+ }\r
+ \r
boolean showRegistrations = GitBlit.canFederate()\r
&& GitBlit.getBoolean(Keys.web.showFederationRegistrations, false);\r
\r
// navigation links\r
List<PageRegistration> pages = new ArrayList<PageRegistration>();\r
- pages.add(new PageRegistration("gb.repositories", RepositoriesPage.class,\r
- getRootPageParameters()));\r
- pages.add(new PageRegistration("gb.activity", ActivityPage.class, getRootPageParameters()));\r
- if (GitBlit.getBoolean(Keys.web.allowLuceneIndexing, true)) {\r
- pages.add(new PageRegistration("gb.search", LuceneSearchPage.class));\r
- }\r
- if (showAdmin) {\r
- pages.add(new PageRegistration("gb.users", UsersPage.class));\r
- }\r
- if (showAdmin || showRegistrations) {\r
- pages.add(new PageRegistration("gb.federation", FederationPage.class));\r
- }\r
-\r
if (!authenticateView || (authenticateView && GitBlitWebSession.get().isLoggedIn())) {\r
- addDropDownMenus(pages);\r
- }\r
-\r
- NavigationPanel navPanel = new NavigationPanel("navPanel", getClass(), pages);\r
- add(navPanel);\r
-\r
- // login form\r
- SessionlessForm<Void> loginForm = new SessionlessForm<Void>("loginForm", getClass(), getPageParameters()) {\r
-\r
- private static final long serialVersionUID = 1L;\r
-\r
- @Override\r
- public void onSubmit() {\r
- String username = RootPage.this.username.getObject();\r
- char[] password = RootPage.this.password.getObject().toCharArray();\r
-\r
- UserModel user = GitBlit.self().authenticate(username, password);\r
- if (user == null) {\r
- error(getString("gb.invalidUsernameOrPassword"));\r
- } else if (user.username.equals(Constants.FEDERATION_USER)) {\r
- // disallow the federation user from logging in via the\r
- // web ui\r
- error(getString("gb.invalidUsernameOrPassword"));\r
- user = null;\r
- } else {\r
- loginUser(user);\r
- }\r
+// pages.add(new PageRegistration("gb.home", HomePage.class,\r
+// getRootPageParameters()));\r
+ pages.add(new PageRegistration("gb.repositories", RepositoriesPage.class,\r
+ getRootPageParameters()));\r
+ pages.add(new PageRegistration("gb.activity", ActivityPage.class, getRootPageParameters()));\r
+ if (GitBlit.getBoolean(Keys.web.allowLuceneIndexing, true)) {\r
+ pages.add(new PageRegistration("gb.search", LuceneSearchPage.class));\r
+ }\r
+ if (showAdmin) {\r
+ pages.add(new PageRegistration("gb.users", UsersPage.class));\r
+ }\r
+ if (showAdmin || showRegistrations) {\r
+ pages.add(new PageRegistration("gb.federation", FederationPage.class));\r
}\r
- };\r
- TextField<String> unameField = new TextField<String>("username", username);\r
- WicketUtils.setInputPlaceholder(unameField, getString("gb.username"));\r
- loginForm.add(unameField);\r
- PasswordTextField pwField = new PasswordTextField("password", password);\r
- WicketUtils.setInputPlaceholder(pwField, getString("gb.password"));\r
- loginForm.add(pwField);\r
- add(loginForm);\r
\r
- if (authenticateView || authenticateAdmin) {\r
- loginForm.setVisible(!GitBlitWebSession.get().isLoggedIn());\r
- } else {\r
- loginForm.setVisible(false);\r
+ if (!authenticateView || (authenticateView && GitBlitWebSession.get().isLoggedIn())) {\r
+ addDropDownMenus(pages);\r
+ }\r
}\r
+ \r
+ NavigationPanel navPanel = new NavigationPanel("navPanel", getRootNavPageClass(), pages);\r
+ add(navPanel);\r
\r
// display an error message cached from a redirect\r
String cachedMessage = GitBlitWebSession.get().clearErrorMessage();\r
\r
super.setupPage(repositoryName, pageName);\r
}\r
+ \r
+ protected Class<? extends BasePage> getRootNavPageClass() {\r
+ return getClass();\r
+ }\r
\r
private PageParameters getRootPageParameters() {\r
if (reusePageParameters()) {\r
Collections.sort(list);\r
return list;\r
}\r
+ \r
+ /**\r
+ * Inline login form. \r
+ */\r
+ private class LoginForm extends Fragment {\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ public LoginForm(String id, String markupId, MarkupContainer markupProvider) {\r
+ super(id, markupId, markupProvider);\r
+ setRenderBodyOnly(true);\r
+\r
+ SessionlessForm<Void> loginForm = new SessionlessForm<Void>("loginForm", RootPage.this.getClass(), getPageParameters()) {\r
+\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ @Override\r
+ public void onSubmit() {\r
+ String username = RootPage.this.username.getObject();\r
+ char[] password = RootPage.this.password.getObject().toCharArray();\r
+\r
+ UserModel user = GitBlit.self().authenticate(username, password);\r
+ if (user == null) {\r
+ error(getString("gb.invalidUsernameOrPassword"));\r
+ } else if (user.username.equals(Constants.FEDERATION_USER)) {\r
+ // disallow the federation user from logging in via the\r
+ // web ui\r
+ error(getString("gb.invalidUsernameOrPassword"));\r
+ user = null;\r
+ } else {\r
+ loginUser(user);\r
+ }\r
+ }\r
+ };\r
+ TextField<String> unameField = new TextField<String>("username", username);\r
+ WicketUtils.setInputPlaceholder(unameField, markupProvider.getString("gb.username"));\r
+ loginForm.add(unameField);\r
+ PasswordTextField pwField = new PasswordTextField("password", password);\r
+ WicketUtils.setInputPlaceholder(pwField, markupProvider.getString("gb.password"));\r
+ loginForm.add(pwField);\r
+ add(loginForm);\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Menu for the authenticated user.\r
+ */\r
+ static class UserMenu extends Fragment {\r
+\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ public UserMenu(String id, String markupId, MarkupContainer markupProvider) {\r
+ super(id, markupId, markupProvider);\r
+ setRenderBodyOnly(true);\r
+\r
+ GitBlitWebSession session = GitBlitWebSession.get();\r
+ UserModel user = session.getUser();\r
+ boolean editCredentials = GitBlit.self().supportsCredentialChanges(user);\r
+ boolean standardLogin = session.authenticationType.isStandard();\r
+\r
+ if (GitBlit.getBoolean(Keys.web.allowGravatar, true)) {\r
+ add(new GravatarImage("username", user.getDisplayName(), user.emailAddress, "navbarGravatar", 20, false));\r
+ } else {\r
+ add(new Label("username", user.getDisplayName()));\r
+ }\r
+\r
+ add(new Label("displayName", user.getDisplayName()));\r
+ \r
+ add(new BookmarkablePageLink<Void>("myProfile", \r
+ UserPage.class, WicketUtils.newUsernameParameter(user.username)));\r
+\r
+ add(new BookmarkablePageLink<Void>("changePassword", \r
+ ChangePasswordPage.class).setVisible(editCredentials));\r
+ \r
+ add(new BookmarkablePageLink<Void>("logout",\r
+ LogoutPage.class).setVisible(standardLogin));\r
+ }\r
+ }\r
}\r
\r
<body>\r
<wicket:extend>\r
+<div class="container">\r
<!-- page header -->\r
<div class="pageTitle">\r
<h2><span wicket:id="pageName">[page name]</span> <small><span wicket:id="pageSubName">[sub name]</span></small></h2>\r
\r
<!-- Subclass Content -->\r
<wicket:child/>\r
+</div>\r
</wicket:extend>\r
</body>\r
</html>
\ No newline at end of file
false, repositories, false, getAccessRestrictions());\r
add(repositoriesPanel);\r
}\r
+ \r
+ @Override\r
+ protected Class<? extends BasePage> getRootNavPageClass() {\r
+ return FederationPage.class;\r
+ }\r
}\r
\r
<!-- Repository info -->\r
<div class="hidden-phone"> \r
- <table class="plain">\r
+ <table class="summary">\r
<tr><th><wicket:message key="gb.description">[description]</wicket:message></th><td><span wicket:id="repositoryDescription">[repository description]</span></td></tr>\r
<tr><th><wicket:message key="gb.owners">[owner]</wicket:message></th><td><span wicket:id="repositoryOwners"><span wicket:id="owner"></span><span wicket:id="comma"></span></span></td></tr>\r
<tr><th><wicket:message key="gb.lastChange">[last change]</wicket:message></th><td><span wicket:id="repositoryLastChange">[repository last change]</span></td></tr>\r
+ <tr><th><wicket:message key="gb.size">[size]</wicket:message></th><td><span wicket:id="repositorySize">[repository size]</span></td></tr>\r
<tr><th><wicket:message key="gb.stats">[stats]</wicket:message></th><td><span wicket:id="branchStats">[branch stats]</span> <span class="link"><a wicket:id="metrics"><wicket:message key="gb.metrics">[metrics]</wicket:message></a></span></td></tr>\r
<tr><th style="vertical-align:top;padding-top:4px;"><wicket:message key="gb.repositoryUrl">[URL]</wicket:message></th>\r
<td><div wicket:id="repositoryUrlPanel">[repository url panel]</div></td>\r
</div>\r
\r
<!-- commits -->\r
- <div style="padding-bottom:15px;" wicket:id="commitsPanel">[commits panel]</div> \r
+ <div style="padding-bottom:15px;padding-top:5px;" wicket:id="commitsPanel">[commits panel]</div> \r
\r
<!-- tags -->\r
<div style="padding-bottom:15px;" wicket:id="tagsPanel">[tags panel]</div>\r
<wicket:fragment wicket:id="ownersFragment">\r
\r
</wicket:fragment>\r
+ \r
</wicket:extend> \r
</body>\r
</html>
\ No newline at end of file
\r
add(WicketUtils.createTimestampLabel("repositoryLastChange",\r
JGitUtils.getLastChange(r), getTimeZone(), getTimeUtils()));\r
+ add(new Label("repositorySize", getRepositoryModel().size));\r
if (metricsTotal == null) {\r
add(new Label("branchStats", ""));\r
} else {\r
String.valueOf((int) WicketUtils.maxValue(metrics)) });\r
provider.addAxis(commitAxis);\r
provider.setLineStyles(new LineStyle[] { new LineStyle(2, 4, 0), new LineStyle(0, 4, 1) });\r
- provider.addShapeMarker(new ShapeMarker(MarkerType.CIRCLE, Color.BLUE, 1, -1, 5));\r
+ provider.addShapeMarker(new ShapeMarker(MarkerType.CIRCLE, Color.decode("#002060"), 1, -1, 5));\r
\r
add(new Chart("commitsChart", provider));\r
} else {\r
import java.util.List;\r
\r
import org.apache.wicket.PageParameters;\r
+import org.apache.wicket.markup.html.WebPage;\r
import org.apache.wicket.markup.html.basic.Label;\r
import org.eclipse.jgit.lib.Constants;\r
import org.eclipse.jgit.lib.Repository;\r
}\r
\r
// Display tag.\r
- Class<? extends RepositoryPage> linkClass;\r
+ Class<? extends WebPage> linkClass;\r
PageParameters linkParameters = newCommitParameter(tagRef.getReferencedObjectId().getName());\r
String typeKey;\r
switch (tagRef.getReferencedObjectType()) {\r
protected String getPageName() {\r
return getString("gb.tag");\r
}\r
+ \r
+ @Override\r
+ protected Class<? extends BasePage> getRepoNavPageClass() {\r
+ return LogPage.class;\r
+ }\r
}\r
protected String getPageName() {\r
return getString("gb.tags");\r
}\r
+ \r
+ @Override\r
+ protected Class<? extends BasePage> getRepoNavPageClass() {\r
+ return LogPage.class;\r
+ }\r
}\r
protected String getPageName() {\r
return getString("gb.ticket");\r
}\r
+ \r
+ @Override\r
+ protected Class<? extends BasePage> getRepoNavPageClass() {\r
+ return TicketsPage.class;\r
+ }\r
\r
private String prepareComment(String comment) {\r
String html = StringUtils.escapeForHtml(comment, false);\r
<body>\r
<wicket:extend>\r
\r
- <!-- header --> \r
- <div style="margin-top:5px;" class="header" wicket:id="header">[header]</div>\r
- \r
<!-- tickets --> \r
<table class="pretty">\r
<tbody>\r
\r
List<TicketModel> tickets = TicgitUtils.getTickets(getRepository());\r
\r
- // header\r
- add(new LinkPanel("header", "title", repositoryName, SummaryPage.class,\r
- newRepositoryParameter()));\r
-\r
ListDataProvider<TicketModel> ticketsDp = new ListDataProvider<TicketModel>(tickets);\r
DataView<TicketModel> ticketsView = new DataView<TicketModel>("ticket", ticketsDp) {\r
private static final long serialVersionUID = 1L;\r
\r
<body>\r
<wicket:extend>\r
-\r
+<div class="container">\r
<div class="row">\r
<div class="span4">\r
<div wicket:id="gravatar"></div>\r
</div>\r
</div>\r
</div>\r
+</div>\r
</wicket:extend>\r
</body>\r
</html>
\ No newline at end of file
lang="en"> \r
<body>\r
<wicket:extend>\r
+<div class="container">\r
<div wicket:id="teamsPanel">[teams panel]</div>\r
\r
<div wicket:id="usersPanel">[users panel]</div>\r
+</div>\r
</wicket:extend>\r
</body>\r
</html>
\ No newline at end of file
}\r
\r
public GravatarImage(String id, PersonIdent person, int width, boolean linked) {\r
+ this(id, person.getName(), person.getEmailAddress(), "gravatar", width, linked);\r
+ }\r
+ \r
+ public GravatarImage(String id, String username, String emailaddress, String cssClass, int width, boolean linked) {\r
super(id);\r
\r
- String email = person.getEmailAddress() == null ? person.getName().toLowerCase() : person.getEmailAddress().toLowerCase();\r
+ String email = emailaddress == null ? username.toLowerCase() : emailaddress.toLowerCase();\r
String hash = StringUtils.getMD5(email);\r
Link<Void> link = new BookmarkablePageLink<Void>("link", GravatarProfilePage.class,\r
WicketUtils.newObjectParameter(hash));\r
link.add(new SimpleAttributeModifier("target", "_blank"));\r
String url = ActivityUtils.getGravatarThumbnailUrl(email, width);\r
ExternalImage image = new ExternalImage("image", url);\r
- WicketUtils.setCssClass(image, "gravatar");\r
+ if (cssClass != null) {\r
+ WicketUtils.setCssClass(image, cssClass);\r
+ }\r
link.add(image);\r
if (linked) {\r
WicketUtils.setHtmlTooltip(link,\r
- MessageFormat.format("View Gravatar profile for {0}", person.getName()));\r
+ MessageFormat.format("View Gravatar profile for {0}", username));\r
} else {\r
- WicketUtils.setHtmlTooltip(link, person.getName());\r
+ WicketUtils.setHtmlTooltip(link, username);\r
}\r
add(link.setEnabled(linked));\r
setVisible(GitBlit.getBoolean(Keys.web.allowGravatar, true));\r
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r
+<html xmlns="http://www.w3.org/1999/xhtml" \r
+ xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd" \r
+ xml:lang="en" \r
+ lang="en"> \r
+\r
+<body>\r
+<wicket:panel>\r
+<div wicket:id="push">\r
+ <table style="padding: 3px 0px;">\r
+ <tr>\r
+ <td class="hidden-phone" style="vertical-align: top;"><span wicket:id="whoAvatar"></span></td>\r
+ <td style="padding-left: 7px;">\r
+ <div><span wicket:id="whoPushed">[pusher]</span> <span wicket:id="whatPushed"></span><span wicket:id="wherePushed"></span></div>\r
+ <div wicket:id="whenPushed"></div>\r
+ <button type="button" class="btn btn-mini" style="padding: 1px 3px;line-height: 12px;" data-toggle="collapse" data-target="#demo"><span class="caret"></span></button>\r
+ <div id="demo" class="collapse">\r
+ <div style="padding: 10px 0px;">\r
+ <table>\r
+ <tr wicket:id="commit" style="border-left: 1px solid #ddd;">\r
+ <td style="vertical-align:top;"><span wicket:id="hashLink" style="padding-left: 10px;">[hash link]</span></td>\r
+ <td><img wicket:id="commitIcon" /></td>\r
+ <td style="vertical-align:top;"> \r
+ <div wicket:id="commitShortMessage">[commit short message]</div>\r
+ <div wicket:id="commitRefs">[commit refs]</div>\r
+ </td>\r
+ </tr>\r
+ </table>\r
+ </div>\r
+ </div>\r
+ </td>\r
+ </tr> \r
+ </table>\r
+</div>\r
+</wicket:panel>\r
+</body>\r
+</html>
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright 2011 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit.wicket.panels;\r
+\r
+import java.text.MessageFormat;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.apache.wicket.markup.html.basic.Label;\r
+import org.apache.wicket.markup.repeater.Item;\r
+import org.apache.wicket.markup.repeater.data.DataView;\r
+import org.apache.wicket.markup.repeater.data.ListDataProvider;\r
+import org.eclipse.jgit.lib.Repository;\r
+\r
+import com.gitblit.Constants;\r
+import com.gitblit.GitBlit;\r
+import com.gitblit.Keys;\r
+import com.gitblit.models.PushLogEntry;\r
+import com.gitblit.models.RepositoryCommit;\r
+import com.gitblit.models.RepositoryModel;\r
+import com.gitblit.models.UserModel;\r
+import com.gitblit.utils.PushLogUtils;\r
+import com.gitblit.utils.StringUtils;\r
+import com.gitblit.wicket.WicketUtils;\r
+import com.gitblit.wicket.pages.CommitPage;\r
+import com.gitblit.wicket.pages.GitSearchPage;\r
+import com.gitblit.wicket.pages.SummaryPage;\r
+import com.gitblit.wicket.pages.UserPage;\r
+\r
+public class PushesPanel extends BasePanel {\r
+\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ private final boolean hasPushes;\r
+ \r
+ private boolean hasMore;\r
+\r
+ public PushesPanel(String wicketId, final RepositoryModel model, Repository r, int limit, int pageOffset) {\r
+ super(wicketId);\r
+ boolean pageResults = limit <= 0;\r
+ int itemsPerPage = GitBlit.getInteger(Keys.web.itemsPerPage, 50);\r
+ if (itemsPerPage <= 1) {\r
+ itemsPerPage = 50;\r
+ }\r
+\r
+ final Map<String, String> usernameLookup = new HashMap<String, String>();\r
+ final int hashLen = GitBlit.getInteger(Keys.web.shortCommitIdLength, 6);\r
+ List<PushLogEntry> entries = PushLogUtils.getPushLog(model.name, r, limit);\r
+ // establish pusher identities\r
+ for (PushLogEntry push : entries) {\r
+ // handle push logs with email address instead of account name\r
+ String username = push.user.username;\r
+ if (push.user.username.indexOf('@') > -1) {\r
+ // push username is an email address, reverse lookup for account\r
+ if (!usernameLookup.containsKey(push.user.username)) {\r
+ for (UserModel user : GitBlit.self().getAllUsers()) {\r
+ if (push.user.username.equals(user.emailAddress)) {\r
+ username = user.username;\r
+ usernameLookup.put(push.user.username, username);\r
+ break;\r
+ }\r
+ }\r
+ } else {\r
+ username = usernameLookup.get(push.user.username);\r
+ }\r
+ } else {\r
+ // push username is an account name, lookup for email address\r
+ if (!usernameLookup.containsKey(push.user.username)) {\r
+ UserModel user = GitBlit.self().getUserModel(push.user.username);\r
+ if (user != null) {\r
+ push.user.emailAddress = user.emailAddress;\r
+ usernameLookup.put(push.user.username, user.emailAddress);\r
+ }\r
+ } else {\r
+ push.user.emailAddress = usernameLookup.get(push.user.username);\r
+ }\r
+ }\r
+ }\r
+ \r
+ hasPushes = entries.size() > 0;\r
+ \r
+ ListDataProvider<PushLogEntry> dp = new ListDataProvider<PushLogEntry>(entries);\r
+ DataView<PushLogEntry> pushView = new DataView<PushLogEntry>("push", dp) {\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ public void populateItem(final Item<PushLogEntry> pushItem) {\r
+ final PushLogEntry push = pushItem.getModelObject();\r
+ \r
+ \r
+ pushItem.add(new GravatarImage("whoAvatar", push.getCommitterIdent(), 40));\r
+ pushItem.add(new LinkPanel("whoPushed", null, push.user.getDisplayName(),\r
+ UserPage.class, WicketUtils.newUsernameParameter(push.user.username)));\r
+ pushItem.add(new Label("whatPushed", \r
+ MessageFormat.format(push.getCommitCount() > 1 ? "pushed {0} commits to":"pushed 1 commit to", push.getCommitCount())));\r
+ String repoName = StringUtils.stripDotGit(model.name);\r
+ pushItem.add(new LinkPanel("wherePushed", null, repoName,\r
+ SummaryPage.class, WicketUtils.newRepositoryParameter(model.name)));\r
+ pushItem.add(WicketUtils.createDateLabel("whenPushed", push.date, getTimeZone(), getTimeUtils()));\r
+\r
+ ListDataProvider<RepositoryCommit> cdp = new ListDataProvider<RepositoryCommit>(push.getCommits());\r
+ DataView<RepositoryCommit> commitsView = new DataView<RepositoryCommit>("commit", cdp) {\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ public void populateItem(final Item<RepositoryCommit> commitItem) {\r
+ final RepositoryCommit commit = commitItem.getModelObject();\r
+\r
+ // author search link\r
+ String author = commit.getAuthorIdent().getName();\r
+ LinkPanel authorLink = new LinkPanel("commitAuthor", "list", author,\r
+ GitSearchPage.class, WicketUtils.newSearchParameter(model.name,\r
+ null, author, Constants.SearchType.AUTHOR));\r
+ setPersonSearchTooltip(authorLink, author, Constants.SearchType.AUTHOR);\r
+ commitItem.add(authorLink);\r
+ \r
+ // merge icon\r
+ if (commit.getParentCount() > 1) {\r
+ commitItem.add(WicketUtils.newImage("commitIcon", "commit_merge_16x16.png"));\r
+ } else {\r
+ commitItem.add(WicketUtils.newBlankImage("commitIcon"));\r
+ }\r
+\r
+ // short message\r
+ String shortMessage = commit.getShortMessage();\r
+ String trimmedMessage = shortMessage;\r
+ if (commit.getRefs() != null && commit.getRefs().size() > 0) {\r
+ trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG_REFS);\r
+ } else {\r
+ trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG);\r
+ }\r
+ LinkPanel shortlog = new LinkPanel("commitShortMessage", "list",\r
+ trimmedMessage, CommitPage.class, WicketUtils.newObjectParameter(\r
+ model.name, commit.getName()));\r
+ if (!shortMessage.equals(trimmedMessage)) {\r
+ WicketUtils.setHtmlTooltip(shortlog, shortMessage);\r
+ }\r
+ commitItem.add(shortlog);\r
+\r
+ commitItem.add(new RefsPanel("commitRefs", commit.repository, commit.getRefs()));\r
+\r
+ // commit hash link\r
+ LinkPanel commitHash = new LinkPanel("hashLink", null, commit.getName().substring(0, hashLen),\r
+ CommitPage.class, WicketUtils.newObjectParameter(\r
+ model.name, commit.getName()));\r
+ WicketUtils.setCssClass(commitHash, "shortsha1");\r
+ WicketUtils.setHtmlTooltip(commitHash, commit.getName());\r
+ commitItem.add(commitHash);\r
+ \r
+// item.add(new BookmarkablePageLink<Void>("diff", CommitDiffPage.class, WicketUtils\r
+// .newObjectParameter(repositoryName, entry.getName())).setEnabled(entry\r
+// .getParentCount() > 0));\r
+// item.add(new BookmarkablePageLink<Void>("tree", TreePage.class, WicketUtils\r
+// .newObjectParameter(repositoryName, entry.getName())));\r
+ }\r
+ };\r
+ \r
+ pushItem.add(commitsView);\r
+ }\r
+ };\r
+ add(pushView);\r
+\r
+ // determine to show pager, more, or neither\r
+// if (limit <= 0) {\r
+// // no display limit\r
+// add(new Label("moreLogs", "").setVisible(false));\r
+// } else {\r
+// if (pageResults) {\r
+// // paging\r
+// add(new Label("moreLogs", "").setVisible(false));\r
+// } else {\r
+// // more\r
+// if (commits.size() == limit) {\r
+// // show more\r
+// add(new LinkPanel("moreLogs", "link", new StringResourceModel("gb.moreLogs",\r
+// this, null), LogPage.class,\r
+// WicketUtils.newRepositoryParameter(repositoryName)));\r
+// } else {\r
+// // no more\r
+// add(new Label("moreLogs", "").setVisible(false));\r
+// }\r
+// }\r
+// }\r
+ }\r
+\r
+ public boolean hasMore() {\r
+ return hasMore;\r
+ }\r
+ \r
+ public boolean hideIfEmpty() {\r
+ setVisible(hasPushes);\r
+ return hasPushes;\r
+ }\r
+}\r
import java.util.Map;\r
\r
import org.apache.wicket.Component;\r
+import org.apache.wicket.markup.html.WebPage;\r
import org.apache.wicket.markup.html.basic.Label;\r
import org.apache.wicket.markup.html.panel.Panel;\r
import org.apache.wicket.markup.repeater.Item;\r
import com.gitblit.wicket.WicketUtils;\r
import com.gitblit.wicket.pages.CommitPage;\r
import com.gitblit.wicket.pages.LogPage;\r
-import com.gitblit.wicket.pages.RepositoryPage;\r
import com.gitblit.wicket.pages.TagPage;\r
\r
public class RefsPanel extends Panel {\r
String name = entry.displayName;\r
String objectid = entry.getReferencedObjectId().getName();\r
boolean breakLine = false;\r
- Class<? extends RepositoryPage> linkClass = CommitPage.class;\r
+ Class<? extends WebPage> linkClass = CommitPage.class;\r
String cssClass = "";\r
if (name.startsWith(Constants.R_HEADS)) {\r
// local branch\r
\r
<div wicket:id="repositoryUrlPanel"></div>\r
<div wicket:id="applicationMenusPanel"></div>\r
-\r
+ <div wicket:id="repositoryIndicators"></div>\r
\r
<wicket:fragment wicket:id="repositoryUrlFragment">\r
<div class="btn-toolbar" style="margin: 0px;">\r
<div class="btn-group repositoryUrlContainer">\r
<img style="vertical-align: middle;padding: 0px 0px 1px 3px;" wicket:id="accessRestrictionIcon"></img>\r
<span wicket:id="menu"></span>\r
- <span class="repositoryUrl">\r
+ <div class="repositoryUrl">\r
<span wicket:id="primaryUrl">[repository primary url]</span>\r
<span class="hidden-phone hidden-tablet" wicket:id="copyFunction"></span>\r
- </span>\r
+ </div>\r
<span class="hidden-phone hidden-tablet repositoryUrlRightCap" wicket:id="primaryUrlPermission">[repository primary url permission]</span>\r
</div>\r
</div>\r
</wicket:fragment>\r
\r
+ <wicket:fragment wicket:id="indicatorsFragment">\r
+ <div>\r
+ <div wicket:id="workingCopyIndicator"></div>\r
+ <div wicket:id="forksProhibitedIndicator"></div>\r
+ </div>\r
+ </wicket:fragment>\r
+ \r
<wicket:fragment wicket:id="applicationMenusFragment">\r
<div class="btn-toolbar" style="margin: 4px 0px 0px 0px;">\r
<div class="btn-group" wicket:id="appMenus">\r
scale="noscale"\r
allowScriptAccess="always"></object>\r
</wicket:fragment>\r
- \r
+\r
+ <wicket:fragment wicket:id="workingCopyFragment">\r
+ <div class="repositoryIndicator">\r
+ <span class="alert alert-info"><i class="icon-exclamation-sign"></i> <span class="hidden-phone" wicket:id="workingCopy">[working copy]</span></span>\r
+ </div>\r
+ </wicket:fragment>\r
+\r
+ <wicket:fragment wicket:id="forksProhibitedFragment">\r
+ <div class="repositoryIndicator">\r
+ <span class="alert alert-error"><i class="icon-ban-circle"></i> <span class="hidden-phone" wicket:id="forksProhibited">[forks prohibited]</span></span>\r
+ </div>\r
+ </wicket:fragment>\r
+ \r
</wicket:panel>\r
</html>
\ No newline at end of file
// no urls, nothing to show.\r
add(new Label("repositoryUrlPanel").setVisible(false));\r
add(new Label("applicationMenusPanel").setVisible(false));\r
+ add(new Label("repositoryIndicators").setVisible(false));\r
return;\r
}\r
\r
// display primary url\r
add(createPrimaryUrlPanel("repositoryUrlPanel", repository, repositoryUrls));\r
\r
+ if (onlyUrls) {\r
+ add(new Label("repositoryIndicators").setVisible(false));\r
+ } else {\r
+ add(createRepositoryIndicators(repository));\r
+ }\r
+\r
boolean allowAppLinks = GitBlit.getBoolean(Keys.web.allowAppCloneLinks, true);\r
if (onlyUrls || !canClone || !allowAppLinks) {\r
// only display the url(s)\r
}\r
return accessRestrictionsMap;\r
}\r
+ \r
+ protected Component createRepositoryIndicators(RepositoryModel repository) {\r
+ Fragment fragment = new Fragment("repositoryIndicators", "indicatorsFragment", this);\r
+ if (repository.isBare) {\r
+ fragment.add(new Label("workingCopyIndicator").setVisible(false));\r
+ } else {\r
+ Fragment wc = new Fragment("workingCopyIndicator", "workingCopyFragment", this);\r
+ Label lbl = new Label("workingCopy", getString("gb.workingCopy"));\r
+ WicketUtils.setHtmlTooltip(lbl, getString("gb.workingCopyWarning"));\r
+ wc.add(lbl);\r
+ fragment.add(wc);\r
+ }\r
+ \r
+ boolean allowForking = GitBlit.getBoolean(Keys.web.allowForking, true);\r
+ if (!allowForking || user == null || !user.isAuthenticated) {\r
+ // must be logged-in to fork, hide all fork controls\r
+ fragment.add(new Label("forksProhibitedIndicator").setVisible(false));\r
+ } else {\r
+ String fork = GitBlit.self().getFork(user.username, repository.name);\r
+ boolean hasFork = fork != null;\r
+ boolean canFork = user.canFork(repository);\r
+\r
+ if (hasFork || !canFork) {\r
+ if (user.canFork() && !repository.allowForks) {\r
+ // show forks prohibited indicator\r
+ Fragment wc = new Fragment("forksProhibitedIndicator", "forksProhibitedFragment", this);\r
+ Label lbl = new Label("forksProhibited", getString("gb.forksProhibited"));\r
+ WicketUtils.setHtmlTooltip(lbl, getString("gb.forksProhibitedWarning"));\r
+ wc.add(lbl);\r
+ fragment.add(wc);\r
+ } else {\r
+ // can not fork, no need for forks prohibited indicator\r
+ fragment.add(new Label("forksProhibitedIndicator").setVisible(false));\r
+ }\r
+ } else if (canFork) {\r
+ // can fork and we do not have one\r
+ fragment.add(new Label("forksProhibitedIndicator").setVisible(false));\r
+ }\r
+ }\r
+ return fragment;\r
+ }\r
}\r
\r
import java.util.List;\r
\r
+import org.apache.wicket.markup.html.WebPage;\r
import org.apache.wicket.markup.html.basic.Label;\r
import org.apache.wicket.markup.html.link.BookmarkablePageLink;\r
import org.apache.wicket.markup.html.panel.Fragment;\r
import com.gitblit.wicket.pages.CommitPage;\r
import com.gitblit.wicket.pages.LogPage;\r
import com.gitblit.wicket.pages.RawPage;\r
-import com.gitblit.wicket.pages.RepositoryPage;\r
import com.gitblit.wicket.pages.TagPage;\r
import com.gitblit.wicket.pages.TagsPage;\r
import com.gitblit.wicket.pages.TreePage;\r
\r
item.add(WicketUtils.createDateLabel("tagDate", entry.getDate(), getTimeZone(), getTimeUtils()));\r
\r
- Class<? extends RepositoryPage> linkClass;\r
+ Class<? extends WebPage> linkClass;\r
switch (entry.getReferencedObjectType()) {\r
case Constants.OBJ_BLOB:\r
linkClass = BlobPage.class;\r
ul, ol {\r
margin-bottom: 10px !important;\r
}\r
+\r
+a {\r
+ color: #2F58A0;\r
+}\r
+\r
+a:hover {\r
+ color: #002060;\r
+}\r
+\r
a:focus {\r
outline: none;\r
}\r
color: #ffffff !important;\r
}\r
\r
+.repositorynavbar {\r
+ background-color: #fbfbfb;\r
+ border-bottom: 1px solid #ccc;\r
+ margin-top: -8px;\r
+ margin-bottom: 10px;\r
+}\r
+\r
+.repositorynavbar .title {\r
+ line-height: 32px;\r
+}\r
+\r
+.repositorynavbar .repository {\r
+ font-weight: bold;\r
+}\r
+\r
+.repositorynavbar .project a, .repositorynavbar .repository a {\r
+ font-family: Helvetica,arial,freesans,clean,sans-serif;\r
+ font-size: 22px;\r
+ color: #002060;\r
+}\r
+\r
+.repositorynavbar .repositorynavbar-inner { \r
+}\r
+\r
+.repositorynavbar ul {\r
+ list-style: none outside;\r
+ display: block;\r
+ position: relative;\r
+ border-top: 1px solid #ccc;\r
+}\r
+\r
+.repositorynavbar ul li {\r
+ display: block;\r
+ float: left;\r
+ padding: 10px;\r
+}\r
+\r
+.repositorynavbar ul li:focus, .repositorynavbar .active {\r
+ color: black;\r
+ background-repeat:no-repeat;\r
+ background-image: url(arrow_project.png);\r
+ background-position: center bottom;\r
+ font-weight: bold;\r
+ outline: 0; \r
+}\r
+\r
+.repositorynavbar ul a {\r
+ color: #002060;\r
+}\r
+\r
+.repositorynavbar ul li:hover {\r
+ background-color: #eee;\r
+}\r
+\r
+.repositorynavbar ul li a:hover {\r
+ background-color: inherit;\r
+ text-decoration: underline;\r
+}\r
+\r
.btn-appmenu {\r
border-radius: 4px !important;\r
background-color: #002060;\r
}\r
\r
.breadcrumb {\r
- margin-top: 5px !important;\r
- margin-bottom: 5px !important;\r
+ margin-top: 10px !important;\r
+ margin-bottom: 10px !important;\r
}\r
\r
.pageTitle { \r
font-family:menlo,consolas,monospace;\r
}\r
\r
-span.repositoryUrl {\r
+div.repositoryUrl {\r
+ display: inline-block; \r
font-size: 1em;\r
- padding: 2px 4px 3px 4px; \r
+ padding: 1px 4px 2px 4px; \r
background-color: #fff;\r
- border-left: 1px solid #ddd;\r
- border-right: 1px solid #ddd;\r
+ border: 1px solid #ddd;\r
+ margin: 1px;\r
+}\r
+\r
+div.repositoryIndicator {\r
+ display:inline;\r
+ padding-top:0px;\r
+ margin-bottom:0px;\r
+}\r
+\r
+div.repositoryIndicator span.alert {\r
+ padding: 2px 7px 2px 7px;\r
+ vertical-align: middle;\r
+ font-size:0.85em;\r
+ font-weight:normal;\r
}\r
\r
ul.urlMenu {\r
padding: 2px;\r
}\r
\r
+img.navbarGravatar {\r
+ border: 1px solid #fff;\r
+}\r
+\r
div.searchResult {\r
padding: 10px 5px 10px 5px;\r
}\r
}\r
\r
div.header, div.commitHeader, table.repositories th {\r
- background-color:#e0e0e0;\r
- background-repeat:repeat-x;\r
- background-image:-khtml-gradient(linear, left top, left bottom, from(#ffffff), to(#e0e0e0));\r
- background-image:-moz-linear-gradient(top, #ffffff, #e0e0e0);\r
- background-image:-ms-linear-gradient(top, #ffffff, #e0e0e0);\r
- background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffffff), color-stop(100%, #e0e0e0));\r
- background-image:-webkit-linear-gradient(top, #ffffff, #e0e0e0);\r
- background-image:-o-linear-gradient(top, #ffffff, #e0e0e0);\r
- background-image:linear-gradient(top, #ffffff, #e0e0e0);\r
- filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e0e0e0', GradientType=0);\r
- -webkit-box-shadow:inset 0 1px 0 #ffffff;\r
- -moz-box-shadow:inset 0 1px 0 #ffffff;\r
- box-shadow:inset 0 1px 0 #ffffff; \r
+ background-color: #fbfbfb;\r
}\r
\r
div.header {\r
}\r
\r
div.page_nav2 {\r
- padding: 2px 5px 7px 5px; \r
+ padding: 5px 10px;\r
+ margin: -10px 0px 10px;\r
+ border-left: 1px solid #ccc;\r
+ border-right: 1px solid #ccc;\r
+ border-bottom: 1px solid #ccc;\r
+ border-radius: 0px 0px 3px 3px; \r
+ background-color: #ECF1F4;\r
+ color: #666;\r
+ text-align: left;\r
+}\r
+\r
+div.page_nav2 a {\r
+ color: #002060;\r
}\r
\r
div.admin_nav {\r
text-align: right;\r
}\r
\r
-table.plain {\r
+table.plain, table.summary {\r
width: 0 !important;\r
border: 0;\r
}\r
\r
-table.plain th, table.plain td {\r
+table.plain th, table.plain td, table.summary th, table.summary td {\r
white-space: nowrap;\r
padding: 1px 3px;\r
border: 0;\r
}\r
\r
+table.summary {\r
+ margin: 0px;\r
+}\r
+\r
+table.summary th {\r
+ color: #999;\r
+ padding-right: 10px;\r
+ text-align: right;\r
+ font-weight: normal;\r
+}\r
+\r
table.pretty {\r
border:1px solid #ddd;\r
border-radius: 0 0 3px 3px;\r
}\r
\r
tr.dark {\r
- background-color: #f5f5f5;\r
+ background-color: #f6f6f6;\r
}\r
\r
/* currently both use the same, but it can change */\r