]> source.dussan.org Git - gitblit.git/commitdiff
User list. Revised home page. Updated Jetty. Secure cookies. Docs.
authorJames Moger <james.moger@gitblit.com>
Mon, 23 May 2011 20:46:09 +0000 (16:46 -0400)
committerJames Moger <james.moger@gitblit.com>
Mon, 23 May 2011 20:46:09 +0000 (16:46 -0400)
27 files changed:
.classpath
build.xml
distrib/gitblit.properties
docs/00_index.mkd
docs/00_setup.mkd
docs/01_faq.mkd
docs/01_screenshots.mkd
docs/screenshots/00.png
docs/screenshots/raw/00.png
docs/screenshots/thumbs/00.png
src/com/gitblit/Build.java
src/com/gitblit/BuildSite.java
src/com/gitblit/Constants.java
src/com/gitblit/GitBlitServer.java
src/com/gitblit/wicket/GitBlitWebApp.properties
src/com/gitblit/wicket/WicketUtils.java
src/com/gitblit/wicket/pages/EditUserPage.html
src/com/gitblit/wicket/pages/RepositoriesPage.html
src/com/gitblit/wicket/pages/RepositoriesPage.java
src/com/gitblit/wicket/panels/RepositoriesPanel.html [new file with mode: 0644]
src/com/gitblit/wicket/panels/RepositoriesPanel.java [new file with mode: 0644]
src/com/gitblit/wicket/panels/UsersPanel.html [new file with mode: 0644]
src/com/gitblit/wicket/panels/UsersPanel.java [new file with mode: 0644]
src/com/gitblit/wicket/resources/add_16x16.png [new file with mode: 0644]
src/com/gitblit/wicket/resources/gitblit.css
src/com/gitblit/wicket/resources/gitweb-favicon.png [new file with mode: 0644]
src/com/gitblit/wicket/resources/user_16x16.png [new file with mode: 0644]

index 5cddd2099e8797d9730e7b5e5ea830334457db05..4e3fa85c10f29adae6abceb2dd38a127a796cca3 100644 (file)
                        <attribute name="javadoc_location" value="jar:platform:/resource/gitblit/ext/slf4j-log4j12-1.6.1-javadoc.jar!/"/>\r
                </attributes>\r
        </classpathentry>\r
-       <classpathentry kind="lib" path="ext/jetty-all-7.2.2.v20101205.jar" sourcepath="ext/jetty-all-7.2.2.v20101205-sources.jar">\r
-               <attributes>\r
-                       <attribute name="javadoc_location" value="jar:platform:/resource/gitblit/ext/jetty-all-7.2.2.v20101205-javadoc.jar!/"/>\r
-               </attributes>\r
-       </classpathentry>\r
        <classpathentry kind="lib" path="ext/jcommander-1.17.jar" sourcepath="ext/jcommander-1.17-sources.jar">\r
                <attributes>\r
                        <attribute name="javadoc_location" value="jar:platform:/resource/gitblit/ext/jcommander-1.17-javadoc.jar!/"/>\r
                        <attribute name="javadoc_location" value="jar:platform:/resource/gitblit/ext/bcmail-jdk16-1.46-javadoc.jar!/"/>\r
                </attributes>\r
        </classpathentry>\r
+       <classpathentry kind="lib" path="ext/jetty-all-7.4.1.v20110513.jar" sourcepath="ext/jetty-all-7.4.1.v20110513-sources.jar">\r
+               <attributes>\r
+                       <attribute name="javadoc_location" value="jar:platform:/resource/gitblit/ext/jetty-all-7.2.2.v20101205-javadoc.jar!/"/>\r
+               </attributes>\r
+       </classpathentry>\r
        <classpathentry kind="output" path="bin"/>\r
 </classpath>\r
index f47e5e9b55992a0e0509dc9352ddd06e87c78fb5..a3394c65494d7e682e74c5870b0ebb3b3b59b437 100644 (file)
--- a/build.xml
+++ b/build.xml
@@ -8,7 +8,12 @@
 \r
        <target name="main">\r
 \r
-               <!-- extract version number from source code -->\r
+               <!-- build dsate -->\r
+               <tstamp>\r
+                       <format property="gb.buildDate" pattern="yyyy-MM-dd" />\r
+               </tstamp>\r
+\r
+               <!-- extract Git:Blit version number from source code -->\r
                <loadfile property="gb.version" srcfile="${basedir}/src/com/gitblit/Constants.java">\r
                        <filterchain>\r
                                <linecontains>\r
                                        <replacestring from="&quot;;" to="" />\r
                                        <trim />\r
                                </tokenfilter>\r
+                       </filterchain>                  \r
+               </loadfile>\r
+\r
+               <!-- extract JGit version number from source code -->\r
+               <loadfile property="jgit.version" srcfile="${basedir}/src/com/gitblit/Constants.java">\r
+                       <filterchain>\r
+                               <linecontains>\r
+                                       <contains value="public final static String JGIT_VERSION = " />\r
+                               </linecontains>\r
+                               <striplinebreaks />\r
+                               <tokenfilter>\r
+                                       <replacestring from="public final static String JGIT_VERSION = &quot;" to="" />\r
+                                       <replacestring from="&quot;;" to="" />\r
+                                       <trim />\r
+                               </tokenfilter>\r
                        </filterchain>\r
                </loadfile>\r
                <echo>Building Git:Blit ${gb.version}</echo>\r
                                <include name="book_16x16.png" />\r
                                <include name="blank.png" />\r
                        </fileset>\r
-                       \r
+\r
                        <!-- Copy Doc images -->\r
                        <fileset dir="${basedir}/docs">\r
                                <include name="*.png" />\r
                                <include name="*.js" />\r
                        </fileset>\r
                </copy>\r
-                       \r
+\r
                <!-- Copy Fancybox -->\r
                <mkdir dir="${basedir}/site/fancybox" />\r
-               <copy todir="${basedir}/site/fancybox">                 \r
-                       <fileset dir="${basedir}/docs/fancybox" >\r
+               <copy todir="${basedir}/site/fancybox">\r
+                       <fileset dir="${basedir}/docs/fancybox">\r
                                <exclude name="thumbs.db" />\r
                        </fileset>\r
                </copy>\r
-               \r
+\r
                <!-- Copy screenshot thumbnails -->\r
                <mkdir dir="${basedir}/site/thumbs" />\r
                <copy todir="${basedir}/site/thumbs">\r
                                <include name="*.png" />\r
                        </fileset>\r
                </copy>\r
-               \r
+\r
                <!-- Copy screenshots -->\r
                <mkdir dir="${basedir}/site/screenshots" />\r
                <copy todir="${basedir}/site/screenshots">\r
                        </fileset>\r
                </copy>\r
 \r
+               <!-- Build site pages -->\r
                <java classpath="${project.build.dir}" classname="com.gitblit.BuildSite">\r
                        <classpath refid="master-classpath" />\r
                        <arg value="--sourceFolder" />\r
                        <arg value="${basedir}/docs" />\r
-                       \r
+\r
                        <arg value="--outputFolder" />\r
                        <arg value="${basedir}/site" />\r
 \r
 \r
                        <arg value="--pageFooter" />\r
                        <arg value="${basedir}/docs/page_footer.html" />\r
-                       \r
+\r
                        <arg value="--alias" />\r
                        <arg value="index=overview" />\r
+\r
+                       <arg value="--substitute" />\r
+                       <arg value="%VERSION%=${gb.version}" />\r
+\r
+                       <arg value="--substitute" />\r
+                       <arg value="%DISTRIBUTION%=${distribution.zipfile}" />\r
+\r
+                       <arg value="--substitute" />\r
+                       <arg value="%BUILDDATE%=${gb.buildDate}" />\r
+\r
+                       <arg value="--substitute" />\r
+                       <arg value="%JGIT%=${jgit.version}" />\r
                </java>\r
 \r
        </target>\r
index de243d2a4f42f0a62ea515d5919982cbd9acb859..d0e6375790b76a571b4f288560225c2a1d966298 100644 (file)
@@ -69,7 +69,7 @@ web.datetimestampLongFormat = EEEE, MMMM d, yyyy h:mm a z
 # Choose how to present the repositories list.\r
 # grouped = group nested/subfolder repositories together (no sorting)\r
 # flat = flat list of repositories (sorting allowed)\r
-web.repositoryListType = flat\r
+web.repositoryListType = grouped\r
 \r
 # If using a grouped repository list and there are repositories at the\r
 # root level of your repositories folder, you may specify the displayed\r
index 6fdc0a1d654085c8c0b89ffcbbcfc9a5f2f8ddef..a43ffdcbfdc05fd23f74f523e427e6e0413b3ae5 100644 (file)
@@ -1,19 +1,17 @@
 ## Overview\r
 Git:Blit is an open-source, integrated pure Java stack for managing, viewing, and serving [Git][git] repositories.\r
-Its designed primarily as a tool for small workgroups who want to host [Git][git] repositories on a Windows machine.\r
-\r
-Of course, since its pure Java it should run with any JVM on any platform, but there are already [many compelling Git solutions](https://git.wiki.kernel.org/index.php/InterfacesFrontendsAndTools) for non-Windows environments.\r
+Its designed primarily as a tool for small workgroups who want to host [Git][git] repositories on a Windows machine.  Having said that, it works equally well on any standard Linux distribution.\r
  \r
 ### Current Version\r
 \r
-[{0}](http://gitblit.com/{1}) based on [{2}][jgit] &nbsp; (*{3}*)\r
+[%VERSION%](http://gitblit.com/%DISTRIBUTION%) based on [%JGIT%][jgit] &nbsp; (*%BUILDDATE%*)\r
 \r
 sources @ [Github][gitbltsrc]\r
 \r
 ### Design Principles\r
 1. [KISS](http://en.wikipedia.org/wiki/KISS_principle)\r
 2. Offer useful features for serving Git repositories.  If feature is complex, refer to #1.\r
-3. All dependencies must be retrievable from a publicly accessible Maven repository.<br/>This is to ensure authenticity of dependencies and to keep the Git:Blit distribution svelte.  \r
+3. All dependencies must be retrievable from a publicly accessible [Maven](http://maven.apache.org) repository.<br/>This is to ensure authenticity of dependencies and to keep the Git:Blit distribution svelte.  \r
 \r
 ### Features\r
 - Out-of-the-box integrated stack requiring minimal configuration\r
@@ -29,7 +27,7 @@ sources @ [Github][gitbltsrc]
     </ul>\r
 - Gitweb inspired UI\r
 - Administrators may create, edit, rename, or delete repositories through the web UI\r
-- Administrators may create, edit, rename, or delete users through the web UI\r
+- Administrators may create, edit, or delete users through the web UI\r
 - Repository Owners may edit repositories through the web UI\r
 - Automatically generates a self-signed certificate for https communications\r
 - Dates can optionally be displayed using the browser''s reported timezone\r
@@ -53,8 +51,6 @@ sources @ [Github][gitbltsrc]
 - Git:Blit is an integrated, full-stack solution.  There is no WAR build at this time.\r
 \r
 ### Todo List\r
-- Manual certificate generation with BouncyCastle\r
-- User list with edit and delete links\r
 - Review spots where Git:Blit can cache data instead of abusing the disk\r
     - stats\r
     - users.properties access\r
@@ -90,8 +86,9 @@ The following dependencies are bundled with the Git:Blit zip distribution file.
 \r
 - [google-code-prettify](http://code.google.com/p/google-code-prettify) (Apache 2.0)\r
 - [JavaService](http://forge.ow2.org/projects/javaservice) (BSD and LGPL)\r
-- icons courtesy of [FatCow Hosting](http://www.fatcow.com/free-icons) (Creative Commons CC-BY)\r
 - magnifying glass search icon courtesy of [Gnome](http://gnome.org) (Creative Commons CC-BY)\r
+- modified Git logo originally designed by [Henrik Nyh](http://henrik.nyh.se/2007/06/alternative-git-logo-and-favicon)\r
+- other icons courtesy of [FatCow Hosting](http://www.fatcow.com/free-icons) (Creative Commons CC-BY)\r
 \r
 ### Downloaded Dependencies\r
 The following dependencies are automatically downloaded from the Apache Maven repository and from the Eclipse Maven repository when Git:Blit is launched for the first time.\r
index 415ad4747873d97f9cf2a2593947c0e051d85785..a590b59a87a069788d5acea903972dc22f575243 100644 (file)
@@ -1,6 +1,6 @@
 ## Setup and Configuration\r
 \r
-1. Download and unzip Git:Blit.<br/>\r
+1. Download and unzip [%VERSION%](http://gitblit.com/%DISTRIBUTION%).<br/>\r
 *Its best to eliminate spaces in the path name as that can cause troubleshooting headaches.* \r
 2. The server itself is configured through a simple text file.<br/>\r
 Open `gitblit.properties` in your favorite text editor and make sure to review and set:\r
index 94c6dbf41effbcf4550b4b53a1a9bb53b5167adf..23ee2b27654a3fb7b9ef5dda21d9b79cab7d261f 100644 (file)
@@ -10,10 +10,17 @@ Its small.  Its portable.  Its easy to manage.
 No.  Git:Blit is based on [JGit][jgit] which is a pure Java implementation of the [Git version control system][git].<br/>\r
 Everything you need for Git:Blit is either in the zip distribution file or automatically downloaded on execution. \r
 \r
+### Does Git:Blit use a database to store its data?\r
+No.  Git:Blit stores its repository configuration information within the `.git/config` file and its user information in `users.properties` or whatever filename is configured in `gitblit.properties`.\r
+\r
+### I want to deploy Git:Blit into my own servlet container.  Where is the WAR?\r
+At this time there is no WAR build available.\r
+\r
 ### Why doesn't Git:Blit support SSH?\r
-Git:Blit could integrate [Apache Mina](http://mina.apache.org) to provide SSH access.  However, doing so violates design principle #1: KISS.  SSH supports requires creating, exchanging, and managing SSH keys.  While this is doable, its not simple like JGit's SmartHTTP implementation.\r
+Git:Blit could integrate [Apache Mina][mina] to provide SSH access.  However, doing so violates Git:Blit's first design principle: [KISS](http://en.wikipedia.org/wiki/KISS_principle).<br/>\r
+SSH supports requires creating, exchanging, and managing SSH keys.  While this is doable, its not simple like JGit's SmartHTTP implementation.\r
 \r
-You might consider [Gerrit](http://gerrit.googlecode.org) which supports SSH.\r
+You might consider running [Gerrit](http://gerrit.googlecode.org) which does integrate [Apache Mina][mina] and supports SSH or you might consider serving [Git][git] on Linux which would offer real SSH support and also allow use of [many other compelling Git solutions](https://git.wiki.kernel.org/index.php/InterfacesFrontendsAndTools).\r
 \r
 ### What types of Search does Git:Blit support?\r
 Git:Blit supports case-insensitive searches of *commit message* (default), *author*, and *committer*.<br/>\r
@@ -26,9 +33,10 @@ To search by *author* or *committer* use the following syntax in the search box:
 Alternatively, you could enable the search type dropdown list in your `gitblit.properties` file.\r
 \r
 ### How do I run Git:Blit on port 80 or 443 in Linux?\r
-Tricky.  Linux requires root permissions to serve on ports < 1024.<br/>\r
+Linux requires root permissions to serve on ports < 1024.<br/>\r
 Run the server as *root* (security concern) or change the ports you are serving to 8080 (http) or 8443 (https). \r
 \r
 [bitblt]: http://en.wikipedia.org/wiki/Bit_blit "Wikipedia Bitblt"\r
 [jgit]: http://eclipse.org/jgit "Eclipse JGit Site"\r
-[git]: http://git-scm.com "Official Git Site"
\ No newline at end of file
+[git]: http://git-scm.com "Official Git Site"\r
+[mina]: http://mina.apache.org " Apache Mina"
\ No newline at end of file
index 3d2061e9ad9403ac7c199142bcc27b783667cef7..14ec1793600c7f2f7a5b61ee786d54728cc4bda9 100644 (file)
@@ -1,8 +1,8 @@
 ## Screenshots\r
 <table class="screenshots">\r
 <tr><td>\r
-       <a rel="screenshots_group" href="screenshots/00.png" title="Repository List">![Repositories](thumbs/00.png)</a>\r
-       <br/>Repository List\r
+       <a rel="screenshots_group" href="screenshots/00.png" title="Repository & User List">![Repositories](thumbs/00.png)</a>\r
+       <br/>Repository & User List\r
 </td><td>\r
        <a rel="screenshots_group" href="screenshots/01.png" title="New User">![New User](thumbs/01.png)</a>\r
        <br/>New User\r
index 616b31c90f13f49d4c27bbe75e9e3a78cf7bb2f6..c9653f14bb2f1cb2e014baeb0ea328372a2edea7 100644 (file)
Binary files a/docs/screenshots/00.png and b/docs/screenshots/00.png differ
index 314f521c2d7e31a303e0122ca977cfc59e0a2c02..eb501496ab5a7d35d5fab06494a182a77f5fce6e 100644 (file)
Binary files a/docs/screenshots/raw/00.png and b/docs/screenshots/raw/00.png differ
index 6aea6930d9a181a1aa321f890b030c19b8aa50cf..636631ff1b98037d0697c2f672107602bc11be3b 100644 (file)
Binary files a/docs/screenshots/thumbs/00.png and b/docs/screenshots/thumbs/00.png differ
index 89527260c612769b97b8c33c89c40bff595079e5..1d2c0f18ad7c66160c8faf6f9e18f7d8b0224ed1 100644 (file)
@@ -268,7 +268,7 @@ public class Build {
 \r
                public static final MavenObject JCOMMANDER = new MavenObject("jCommander", "com/beust", "jcommander", "1.17", 34000, 32000, 141000, "219a3540f3b27d7cc3b1d91d6ea046cd8723290e", "0bb50eec177acf0e94d58e0cf07262fe5164331d", "c7adc475ca40c288c93054e0f4fe58f3a98c0cb5");\r
 \r
-               public static final MavenObject JETTY = new MavenObject("Jetty", "org/eclipse/jetty/aggregate", "jetty-all", "7.2.2.v20101205", 1430000, 965000, 3871000, "b9b7c812a732721c427e208c54fbb71ca17a2ee1", "cbc4fc72c4a646d8822bf7369c2101d4d5d1ff98", "34c87e11bba426fe97bfe23ccff12eda477c8f57");\r
+               public static final MavenObject JETTY = new MavenObject("Jetty", "org/eclipse/jetty/aggregate", "jetty-all", "7.4.1.v20110513", 1500000, 1000000, 4100000, "1e2de9ed25a7c6ae38717d5ffdc7cfcd6be4bd46", "7b6279d16ce8f663537d9faf55ea353e748dbbaa", "fa06212e751296f1a7abc15c843b135bf49a112b");\r
 \r
                public static final MavenObject SERVLET = new MavenObject("Servlet 2.5", "javax/servlet", "servlet-api", "2.5", 105000, 158000, 0, "5959582d97d8b61f4d154ca9e495aafd16726e34", "021599814ad9a605b86f3e6381571beccd861a32", null);\r
 \r
index 6ea8048c0f567fdf180db026e59a880b49e62e90..dc42cf55de5807f4370c58725f0e1d7c08d0353a 100644 (file)
@@ -46,11 +46,11 @@ public class BuildSite {
                Arrays.sort(markdownFiles);\r
 \r
                Map<String, String> aliasMap = new HashMap<String, String>();\r
-               for (String alias:params.aliases) {\r
-                       String [] values = alias.split("=");\r
+               for (String alias : params.aliases) {\r
+                       String[] values = alias.split("=");\r
                        aliasMap.put(values[0], values[1]);\r
                }\r
-               \r
+\r
                System.out.println(MessageFormat.format("Generating site from {0} Markdown Docs in {1} ", markdownFiles.length, sourceFolder.getAbsolutePath()));\r
                String linkPattern = "<a href=''{0}''>{1}</a>";\r
                StringBuilder sb = new StringBuilder();\r
@@ -66,7 +66,7 @@ public class BuildSite {
                }\r
                sb.setLength(sb.length() - 3);\r
                sb.trimToSize();\r
-               \r
+\r
                String html_header = readContent(new File(params.pageHeader));\r
                String html_footer = readContent(new File(params.pageFooter));\r
                final String links = sb.toString();\r
@@ -76,16 +76,13 @@ public class BuildSite {
                for (File file : markdownFiles) {\r
                        try {\r
                                String documentName = getDocumentName(file);\r
-                               String displayName = documentName;\r
-                               if (aliasMap.containsKey(documentName)) {\r
-                                       displayName = aliasMap.get(documentName);\r
-                               }\r
                                String fileName = documentName + ".html";\r
                                System.out.println(MessageFormat.format("  {0} => {1}", file.getName(), fileName));\r
                                InputStreamReader reader = new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8"));\r
                                String content = MarkdownUtils.transformMarkdown(reader);\r
-                               if (displayName.equalsIgnoreCase("overview")) {\r
-                                       content = MessageFormat.format(content, Constants.VERSION, "gitblit-" + Constants.VERSION + ".zip", Constants.getJGitVersion(), date);\r
+                               for (String token : params.substitutions) {\r
+                                       String [] kv = token.split("=");\r
+                                       content = content.replace(kv[0], kv[1]);\r
                                }\r
                                OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(new File(destinationFolder, fileName)), Charset.forName("UTF-8"));\r
                                writer.write(header);\r
@@ -122,7 +119,7 @@ public class BuildSite {
                // trim leading ##_ which is to control display order\r
                return displayName.substring(3);\r
        }\r
-       \r
+\r
        private static void usage(JCommander jc, ParameterException t) {\r
                System.out.println(Constants.getRunningVersion());\r
                System.out.println();\r
@@ -135,7 +132,7 @@ public class BuildSite {
                }\r
                System.exit(0);\r
        }\r
-       \r
+\r
        @Parameters(separators = " ")\r
        private static class Params {\r
 \r
@@ -154,5 +151,8 @@ public class BuildSite {
                @Parameter(names = { "--alias" }, description = "Filename=Linkname aliases", required = false)\r
                public List<String> aliases = new ArrayList<String>();\r
 \r
+               @Parameter(names = { "--substitute" }, description = "@TOKEN@=value", required = false)\r
+               public List<String> substitutions = new ArrayList<String>();\r
+\r
        }\r
 }\r
index 7e19cefbb50b5858dda28d1bbca2c533b3470c58..46f3208433e0a3ffd5f5edcc3037933d53cea317 100644 (file)
@@ -10,6 +10,10 @@ public class Constants {
        // and only use A-Z a-z 0-9 .-_ in the string. \r
        public final static String VERSION = "0.1.0-SNAPSHOT";\r
 \r
+       // The build script extracts this exact line so be careful editing it\r
+       // and only use A-Z a-z 0-9 .-_ in the string.\r
+       public final static String JGIT_VERSION = "JGit 0.12.1";\r
+\r
        public final static String ADMIN_ROLE = "#admin";\r
 \r
        public final static String PROPERTIES_FILE = "gitblit.properties";\r
@@ -44,7 +48,7 @@ public class Constants {
        }\r
 \r
        public static String getJGitVersion() {\r
-               return "JGit 0.12.1";\r
+               return JGIT_VERSION;\r
        }\r
 \r
        public static String getRunningVersion() {\r
index 08c9b2972d38638ff54815b3d3babc85a128a471..e9e446370e3e30b199adc991bce76b2b46b2deeb 100644 (file)
@@ -29,6 +29,7 @@ import org.eclipse.jetty.server.Handler;
 import org.eclipse.jetty.server.Server;\r
 import org.eclipse.jetty.server.bio.SocketConnector;\r
 import org.eclipse.jetty.server.nio.SelectChannelConnector;\r
+import org.eclipse.jetty.server.session.HashSessionManager;\r
 import org.eclipse.jetty.server.ssl.SslConnector;\r
 import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;\r
 import org.eclipse.jetty.server.ssl.SslSocketConnector;\r
@@ -192,6 +193,16 @@ public class GitBlitServer {
                rootContext.setServer(server);\r
                rootContext.setWar(location.toExternalForm());\r
                rootContext.setTempDirectory(tempDir);\r
+               \r
+               // Mark all cookies HttpOnly so they are not accessible to JavaScript\r
+               // engines.\r
+               // http://erlend.oftedal.no/blog/?blogid=33\r
+               // https://www.owasp.org/index.php/HttpOnly#Browsers_Supporting_HttpOnly\r
+               HashSessionManager sessionManager = new HashSessionManager();\r
+               sessionManager.setHttpOnly(true);\r
+               // Use secure cookies if only serving https\r
+               sessionManager.setSecureCookies(params.port <= 0 && params.securePort > 0);\r
+               rootContext.getSessionHandler().setSessionManager(sessionManager);\r
 \r
                // Wicket Filter\r
                String wicketPathSpec = "/*";\r
index d07f0bc6dd5409e9d702d9a0be77a6b544ee3530..b6dbc1173aaa9ad5677939dacceaffe268ea3c8c 100644 (file)
@@ -43,8 +43,8 @@ gb.head = HEAD
 gb.blame = blame\r
 gb.login = Login\r
 gb.logout = Logout\r
-gb.username = Username\r
-gb.password = Password\r
+gb.username = username\r
+gb.password = password\r
 gb.tagger = tagger\r
 gb.moreHistory = more history...\r
 gb.difftocurrent = diff to current\r
index f0ccbf4b5963d0ebe2410c86eac937f31a1e6dbb..761595b11c89bfd87e39d3ffad76defd483adec4 100644 (file)
@@ -153,6 +153,10 @@ public class WicketUtils {
                return new ContextRelativeResource("/com/gitblit/wicket/resources/" + file);\r
        }\r
 \r
+       public static PageParameters newUsernameParameter(String username) {\r
+               return new PageParameters("user=" + username);\r
+       }\r
+\r
        public static PageParameters newRepositoryParameter(String repositoryName) {\r
                return new PageParameters("r=" + repositoryName);\r
        }\r
index c50bdbac6897d7b123f758f6b1e45ccc16218d3f..a27b712028b8b37f5388c3c7763b5a0cce3a1de5 100644 (file)
@@ -15,7 +15,7 @@
        <form wicket:id="editForm">\r
                <table class="plain">\r
                        <tbody>\r
-                               <tr><th><wicket:message key="gb.name"></wicket:message></th><td class="edit"><input type="text" wicket:id="username" id="username" size="30" tabindex="1" /></td></tr>\r
+                               <tr><th><wicket:message key="gb.username"></wicket:message></th><td class="edit"><input type="text" wicket:id="username" id="username" size="30" tabindex="1" /></td></tr>\r
                                <tr><th><wicket:message key="gb.password"></wicket:message></th><td class="edit"><input type="password" wicket:id="password" size="30" tabindex="2" /></td></tr>\r
                                <tr><th><wicket:message key="gb.confirmPassword"></wicket:message></th><td class="edit"><input type="password" wicket:id="confirmPassword" size="30" tabindex="3" /></td></tr>\r
                                <tr><th><wicket:message key="gb.canAdmin"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="canAdmin" tabindex="6" /> &nbsp;<i><wicket:message key="gb.canAdminDescription"></wicket:message></i></td></tr>                              \r
index d00c498a765d79a02c005f618dd30c208e3ac74e..da91cb2e13400c66fdbcd518604cf150e230a82d 100644 (file)
        \r
        <div class="markdown" style="margin-top:-0.5em;padding-bottom:5px;" wicket:id="repositoriesMessage">[repositories message]</div>\r
        \r
-       <div wicket:id="adminPanel">[admin links]</div>\r
-               \r
-       <table class="repositories">\r
-               <span wicket:id="headerContent"></span>\r
-               <tbody>         \r
-                       <tr wicket:id="row">\r
-                               <span wicket:id="rowContent"></span>\r
-                       </tr>\r
-       </tbody>\r
-       </table>\r
-       \r
-       <wicket:fragment wicket:id="adminLinks">\r
-               <!-- page nav links --> \r
-               <div style="text-align: right;" class="admin_nav">\r
-                       <a wicket:id="newRepository"><wicket:message key="gb.newRepository"></wicket:message></a> | <a wicket:id="newUser"><wicket:message key="gb.newUser"></wicket:message></a> | <a wicket:id="editUsers"><wicket:message key="gb.editUsers"></wicket:message></a>\r
-               </div>  \r
-       </wicket:fragment>\r
-       \r
-       <wicket:fragment wicket:id="repositoryAdminLinks">\r
-               <span class="link"><a wicket:id="editRepository"><wicket:message key="gb.edit">[edit]</wicket:message></a> | <a wicket:id="renameRepository"><wicket:message key="gb.rename">[rename]</wicket:message></a> | <a wicket:id="deleteRepository"><wicket:message key="gb.delete">[delete]</wicket:message></a></span>\r
-       </wicket:fragment>\r
-\r
-       <wicket:fragment wicket:id="repositoryOwnerLinks">\r
-               <span class="link"><a wicket:id="editRepository"><wicket:message key="gb.edit">[edit]</wicket:message></a></span>\r
-       </wicket:fragment>\r
+       <div wicket:id="repositoriesPanel">[repositories panel]</div>\r
 \r
-       <wicket:fragment wicket:id="flatHeader">\r
-               <tr>\r
-                       <th wicket:id="orderByRepository"><wicket:message key="gb.repository">Repository</wicket:message></th>\r
-                       <th wicket:id="orderByDescription"><wicket:message key="gb.description">Description</wicket:message></th>\r
-                       <th wicket:id="orderByOwner"><wicket:message key="gb.owner">Owner</wicket:message></th>\r
-                       <th></th>\r
-                       <th wicket:id="orderByDate"><wicket:message key="gb.lastChange">Last Change</wicket:message></th>\r
-                       <th></th>\r
-               </tr>\r
-       </wicket:fragment>\r
-       \r
-       <wicket:fragment wicket:id="groupHeader">\r
-               <tr>\r
-                       <th><wicket:message key="gb.repository">Repository</wicket:message></th>\r
-                       <th><wicket:message key="gb.description">Description</wicket:message></th>\r
-                       <th><wicket:message key="gb.owner">Owner</wicket:message></th>\r
-                       <th></th>\r
-                       <th><wicket:message key="gb.lastChange">Last Change</wicket:message></th>\r
-                       <th></th>\r
-               </tr>\r
-       </wicket:fragment>\r
-       \r
-       <wicket:fragment wicket:id="groupRow">\r
-        <td colspan="6"><span wicket:id="groupName">[group name]</span></td>\r
-       </wicket:fragment>\r
+       <div style="padding-top: 10px;"wicket:id="usersPanel">[users panel]</div>\r
                \r
-       <wicket:fragment wicket:id="repositoryRow">\r
-        <td><div class="list" wicket:id="repositoryName">[repository name]</div></td>\r
-        <td><div class="list" wicket:id="repositoryDescription">[repository description]</div></td>\r
-        <td class="author"><span wicket:id="repositoryOwner">[repository owner]</span></td>\r
-        <td style="text-align: right;padding-right:10px;"><img class="inlineIcon" wicket:id="ticketsIcon" /><img class="inlineIcon" wicket:id="docsIcon" /><img class="inlineIcon" wicket:id="frozenIcon" /><img class="inlineIcon" wicket:id="accessRestrictionIcon" /></td>\r
-        <td><span wicket:id="repositoryLastChange">[last change]</span></td>\r
-        <td class="rightAlign"><span wicket:id="repositoryLinks"></span></td>\r
-       </wicket:fragment>\r
-       \r
 </wicket:extend>\r
 </body>\r
 </html>
\ No newline at end of file
index 14a54266b122f7e33d03ce3aa563ebc3ed486554..32552f7e1f4c91080db95d8d6e1f2f63a3f76e08 100644 (file)
@@ -4,50 +4,27 @@ import java.io.File;
 import java.io.FileReader;\r
 import java.io.InputStream;\r
 import java.io.InputStreamReader;\r
-import java.util.ArrayList;\r
-import java.util.Collections;\r
-import java.util.Comparator;\r
-import java.util.Date;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.Map;\r
 \r
 import org.apache.wicket.Component;\r
-import org.apache.wicket.PageParameters;\r
-import org.apache.wicket.extensions.markup.html.repeater.data.sort.OrderByBorder;\r
-import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;\r
-import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;\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 org.apache.wicket.markup.repeater.Item;\r
-import org.apache.wicket.markup.repeater.data.DataView;\r
-import org.apache.wicket.markup.repeater.data.IDataProvider;\r
-import org.apache.wicket.markup.repeater.data.ListDataProvider;\r
-import org.apache.wicket.model.IModel;\r
-import org.apache.wicket.model.Model;\r
 import org.apache.wicket.resource.ContextRelativeResource;\r
 \r
-import com.gitblit.Constants.AccessRestrictionType;\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.utils.TimeUtils;\r
 import com.gitblit.wicket.BasePage;\r
 import com.gitblit.wicket.GitBlitWebSession;\r
-import com.gitblit.wicket.LinkPanel;\r
 import com.gitblit.wicket.WicketUtils;\r
-import com.gitblit.wicket.models.RepositoryModel;\r
-import com.gitblit.wicket.models.UserModel;\r
+import com.gitblit.wicket.panels.RepositoriesPanel;\r
+import com.gitblit.wicket.panels.UsersPanel;\r
 \r
 public class RepositoriesPage extends BasePage {\r
 \r
        public RepositoriesPage() {\r
                super();\r
                setupPage("", "");\r
-               \r
+\r
                final boolean showAdmin;\r
                if (GitBlit.self().settings().getBoolean(Keys.web.authenticateAdminPages, true)) {\r
                        boolean allowAdmin = GitBlit.self().settings().getBoolean(Keys.web.allowAdministration, false);\r
@@ -65,12 +42,6 @@ public class RepositoriesPage extends BasePage {
                        }\r
                }\r
 \r
-               Fragment adminLinks = new Fragment("adminPanel", "adminLinks", this);\r
-               adminLinks.add(new BookmarkablePageLink<Void>("newRepository", EditRepositoryPage.class));\r
-               adminLinks.add(new BookmarkablePageLink<Void>("newUser", EditUserPage.class));\r
-               adminLinks.add(new BookmarkablePageLink<Void>("editUsers", RepositoriesPage.class));\r
-               add(adminLinks.setVisible(showAdmin));\r
-\r
                // display an error message cached from a redirect\r
                String cachedMessage = GitBlitWebSession.get().clearErrorMessage();\r
                if (!StringUtils.isEmpty(cachedMessage)) {\r
@@ -111,228 +82,7 @@ public class RepositoriesPage extends BasePage {
                }\r
                Component repositoriesMessage = new Label("repositoriesMessage", message).setEscapeModelStrings(false);\r
                add(repositoriesMessage);\r
-\r
-               final Map<AccessRestrictionType, String> accessRestrictionTranslations = getAccessRestrictions();\r
-               final UserModel user = GitBlitWebSession.get().getUser();\r
-               List<RepositoryModel> models = GitBlit.self().getRepositoryModels(user);\r
-               IDataProvider<RepositoryModel> dp;\r
-               \r
-               if (GitBlit.self().settings().getString(Keys.web.repositoryListType, "flat").equalsIgnoreCase("grouped")) {\r
-                       Map<String, List<RepositoryModel>> groups = new HashMap<String, List<RepositoryModel>>();\r
-                       for (RepositoryModel model : models) {\r
-                               String rootPath = StringUtils.getRootPath(model.name);\r
-                               if (StringUtils.isEmpty(rootPath)) {\r
-                                       rootPath = GitBlit.self().settings().getString(Keys.web.repositoryRootGroupName, " ");\r
-                               }\r
-                               if (!groups.containsKey(rootPath)) {\r
-                                       groups.put(rootPath, new ArrayList<RepositoryModel>());\r
-                               }\r
-                               groups.get(rootPath).add(model);\r
-                       }\r
-                       List<String> roots = new ArrayList<String>(groups.keySet());\r
-                       Collections.sort(roots);\r
-                       List<RepositoryModel> groupedModels = new ArrayList<RepositoryModel>();\r
-                       for (String root : roots) {\r
-                               groupedModels.add(new GroupRepositoryModel(root));\r
-                               groupedModels.addAll(groups.get(root));\r
-                       }\r
-                       dp = new ListDataProvider<RepositoryModel>(groupedModels);\r
-               } else {\r
-                       dp = new DataProvider(models);\r
-               }\r
-\r
-               DataView<RepositoryModel> dataView = new DataView<RepositoryModel>("row", dp) {\r
-                       private static final long serialVersionUID = 1L;\r
-                       int counter = 0;\r
-\r
-                       public void populateItem(final Item<RepositoryModel> item) {\r
-                               final RepositoryModel entry = item.getModelObject();\r
-                               if (entry instanceof GroupRepositoryModel) {\r
-                                       Fragment row = new Fragment("rowContent", "groupRow", this);\r
-                                       item.add(row);\r
-                                       row.add(new Label("groupName", entry.name));\r
-                                       WicketUtils.setCssClass(item, "group");\r
-                                       return;\r
-                               }\r
-                               Fragment row = new Fragment("rowContent", "repositoryRow", this);\r
-                               item.add(row);\r
-                               if (entry.hasCommits) {\r
-                                       // Existing repository\r
-                                       PageParameters pp = WicketUtils.newRepositoryParameter(entry.name);\r
-                                       row.add(new LinkPanel("repositoryName", "list", entry.name, SummaryPage.class, pp));\r
-                                       row.add(new LinkPanel("repositoryDescription", "list", entry.description, SummaryPage.class, pp));\r
-                               } else {\r
-                                       // New repository\r
-                                       row.add(new Label("repositoryName", entry.name + "<span class='empty'>(empty)</span>").setEscapeModelStrings(false));\r
-                                       row.add(new Label("repositoryDescription", entry.description));\r
-                               }\r
-\r
-                               if (entry.useTickets) {\r
-                                       row.add(WicketUtils.newImage("ticketsIcon", "bug_16x16.png", getString("gb.tickets")));\r
-                               } else {\r
-                                       row.add(WicketUtils.newBlankImage("ticketsIcon"));\r
-                               }\r
-\r
-                               if (entry.useDocs) {\r
-                                       row.add(WicketUtils.newImage("docsIcon", "book_16x16.png", getString("gb.docs")));\r
-                               } else {\r
-                                       row.add(WicketUtils.newBlankImage("docsIcon"));\r
-                               }\r
-\r
-                               if (entry.isFrozen) {\r
-                                       row.add(WicketUtils.newImage("frozenIcon", "cold_16x16.png", getString("gb.isFrozen")));\r
-                               } else {\r
-                                       row.add(WicketUtils.newClearPixel("frozenIcon").setVisible(false));\r
-                               }\r
-                               switch (entry.accessRestriction) {\r
-                               case NONE:\r
-                                       row.add(WicketUtils.newBlankImage("accessRestrictionIcon"));\r
-                                       break;\r
-                               case PUSH:\r
-                                       row.add(WicketUtils.newImage("accessRestrictionIcon", "lock_go_16x16.png", accessRestrictionTranslations.get(entry.accessRestriction)));\r
-                                       break;\r
-                               case CLONE:\r
-                                       row.add(WicketUtils.newImage("accessRestrictionIcon", "lock_pull_16x16.png", accessRestrictionTranslations.get(entry.accessRestriction)));\r
-                                       break;\r
-                               case VIEW:\r
-                                       row.add(WicketUtils.newImage("accessRestrictionIcon", "shield_16x16.png", accessRestrictionTranslations.get(entry.accessRestriction)));\r
-                                       break;\r
-                               default:\r
-                                       row.add(WicketUtils.newBlankImage("accessRestrictionIcon"));\r
-                               }\r
-\r
-                               row.add(new Label("repositoryOwner", entry.owner));\r
-\r
-                               String lastChange = TimeUtils.timeAgo(entry.lastChange);\r
-                               Label lastChangeLabel = new Label("repositoryLastChange", lastChange);\r
-                               row.add(lastChangeLabel);\r
-                               WicketUtils.setCssClass(lastChangeLabel, TimeUtils.timeAgoCss(entry.lastChange));\r
-\r
-                               boolean showOwner = user != null && user.getUsername().equalsIgnoreCase(entry.owner);                           \r
-                               if (showAdmin) {\r
-                                       Fragment repositoryLinks = new Fragment("repositoryLinks", "repositoryAdminLinks", this);\r
-                                       repositoryLinks.add(new BookmarkablePageLink<Void>("editRepository", EditRepositoryPage.class, WicketUtils.newRepositoryParameter(entry.name)));\r
-                                       repositoryLinks.add(new BookmarkablePageLink<Void>("renameRepository", EditRepositoryPage.class, WicketUtils.newRepositoryParameter(entry.name)).setEnabled(false));\r
-                                       repositoryLinks.add(new BookmarkablePageLink<Void>("deleteRepository", EditRepositoryPage.class, WicketUtils.newRepositoryParameter(entry.name)).setEnabled(false));\r
-                                       row.add(repositoryLinks);\r
-                               } else if (showOwner) {\r
-                                       Fragment repositoryLinks = new Fragment("repositoryLinks", "repositoryOwnerLinks", this);\r
-                                       repositoryLinks.add(new BookmarkablePageLink<Void>("editRepository", EditRepositoryPage.class, WicketUtils.newRepositoryParameter(entry.name)));\r
-                                       row.add(repositoryLinks);\r
-                               } else {\r
-                                       row.add(new Label("repositoryLinks"));\r
-                               }\r
-                               WicketUtils.setAlternatingBackground(item, counter);\r
-                               counter++;\r
-                       }\r
-               };\r
-               add(dataView);\r
-\r
-               if (dp instanceof SortableDataProvider<?>) {\r
-                       // add sortable header\r
-                       SortableDataProvider<?> sdp = (SortableDataProvider<?>) dp;\r
-                       Fragment fragment = new Fragment("headerContent", "flatHeader", this);\r
-                       fragment.add(newSort("orderByRepository", SortBy.repository, sdp, dataView));\r
-                       fragment.add(newSort("orderByDescription", SortBy.description, sdp, dataView));\r
-                       fragment.add(newSort("orderByOwner", SortBy.owner, sdp, dataView));\r
-                       fragment.add(newSort("orderByDate", SortBy.date, sdp, dataView));\r
-                       add(fragment);\r
-               } else {\r
-                       // not sortable\r
-                       Fragment fragment = new Fragment("headerContent", "groupHeader", this);\r
-                       add(fragment);\r
-               }\r
-       }\r
-\r
-       protected enum SortBy {\r
-               repository, description, owner, date;\r
-       }\r
-\r
-       protected OrderByBorder newSort(String wicketId, SortBy field, SortableDataProvider<?> dp, final DataView<?> dataView) {\r
-               return new OrderByBorder(wicketId, field.name(), dp) {\r
-                       private static final long serialVersionUID = 1L;\r
-\r
-                       @Override\r
-                       protected void onSortChanged() {\r
-                               dataView.setCurrentPage(0);\r
-                       }\r
-               };\r
-       }\r
-\r
-       private class DataProvider extends SortableDataProvider<RepositoryModel> {\r
-               private static final long serialVersionUID = 1L;\r
-               private List<RepositoryModel> list = null;\r
-\r
-               protected DataProvider(List<RepositoryModel> list) {\r
-                       this.list = list;\r
-                       setSort(SortBy.date.name(), false);\r
-               }\r
-\r
-               @Override\r
-               public int size() {\r
-                       if (list == null)\r
-                               return 0;\r
-                       return list.size();\r
-               }\r
-\r
-               @Override\r
-               public IModel<RepositoryModel> model(RepositoryModel header) {\r
-                       return new Model<RepositoryModel>(header);\r
-               }\r
-\r
-               @Override\r
-               public Iterator<RepositoryModel> iterator(int first, int count) {\r
-                       SortParam sp = getSort();\r
-                       String prop = sp.getProperty();\r
-                       final boolean asc = sp.isAscending();\r
-\r
-                       if (prop == null || prop.equals(SortBy.date.name())) {\r
-                               Collections.sort(list, new Comparator<RepositoryModel>() {\r
-                                       @Override\r
-                                       public int compare(RepositoryModel o1, RepositoryModel o2) {\r
-                                               if (asc)\r
-                                                       return o1.lastChange.compareTo(o2.lastChange);\r
-                                               return o2.lastChange.compareTo(o1.lastChange);\r
-                                       }\r
-                               });\r
-                       } else if (prop.equals(SortBy.repository.name())) {\r
-                               Collections.sort(list, new Comparator<RepositoryModel>() {\r
-                                       @Override\r
-                                       public int compare(RepositoryModel o1, RepositoryModel o2) {\r
-                                               if (asc)\r
-                                                       return o1.name.compareTo(o2.name);\r
-                                               return o2.name.compareTo(o1.name);\r
-                                       }\r
-                               });\r
-                       } else if (prop.equals(SortBy.owner.name())) {\r
-                               Collections.sort(list, new Comparator<RepositoryModel>() {\r
-                                       @Override\r
-                                       public int compare(RepositoryModel o1, RepositoryModel o2) {\r
-                                               if (asc)\r
-                                                       return o1.owner.compareTo(o2.owner);\r
-                                               return o2.owner.compareTo(o1.owner);\r
-                                       }\r
-                               });\r
-                       } else if (prop.equals(SortBy.description.name())) {\r
-                               Collections.sort(list, new Comparator<RepositoryModel>() {\r
-                                       @Override\r
-                                       public int compare(RepositoryModel o1, RepositoryModel o2) {\r
-                                               if (asc)\r
-                                                       return o1.description.compareTo(o2.description);\r
-                                               return o2.description.compareTo(o1.description);\r
-                                       }\r
-                               });\r
-                       }\r
-                       return list.subList(first, first + count).iterator();\r
-               }\r
-       }\r
-\r
-       private class GroupRepositoryModel extends RepositoryModel {\r
-\r
-               private static final long serialVersionUID = 1L;\r
-\r
-               GroupRepositoryModel(String name) {\r
-                       super(name, "", "", new Date(0));\r
-               }\r
+               add(new RepositoriesPanel("repositoriesPanel", showAdmin, getAccessRestrictions()));            \r
+               add(new UsersPanel("usersPanel", showAdmin).setVisible(showAdmin));\r
        }\r
 }\r
diff --git a/src/com/gitblit/wicket/panels/RepositoriesPanel.html b/src/com/gitblit/wicket/panels/RepositoriesPanel.html
new file mode 100644 (file)
index 0000000..a066b58
--- /dev/null
@@ -0,0 +1,88 @@
+<!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
+\r
+       <div wicket:id="adminPanel">[admin links]</div>\r
+\r
+       <table class="repositories">\r
+               <span wicket:id="headerContent"></span>\r
+               <tbody>         \r
+                       <tr wicket:id="row">\r
+                               <span wicket:id="rowContent"></span>\r
+                       </tr>\r
+       </tbody>\r
+       </table>\r
+       \r
+       <wicket:fragment wicket:id="adminLinks">\r
+               <!-- page nav links --> \r
+               <div class="admin_nav">\r
+                       <wicket:link>\r
+                               <img style="vertical-align: top;" src="/com/gitblit/wicket/resources/add_16x16.png"/>\r
+                       </wicket:link>  \r
+                       <a wicket:id="newRepository">\r
+                               <wicket:message key="gb.newRepository"></wicket:message>\r
+                       </a>\r
+               </div>  \r
+       </wicket:fragment>\r
+       \r
+       <wicket:fragment wicket:id="repositoryAdminLinks">\r
+               <span class="link"><a wicket:id="editRepository"><wicket:message key="gb.edit">[edit]</wicket:message></a> | <a wicket:id="renameRepository"><wicket:message key="gb.rename">[rename]</wicket:message></a> | <a wicket:id="deleteRepository"><wicket:message key="gb.delete">[delete]</wicket:message></a></span>\r
+       </wicket:fragment>\r
+\r
+       <wicket:fragment wicket:id="repositoryOwnerLinks">\r
+               <span class="link"><a wicket:id="editRepository"><wicket:message key="gb.edit">[edit]</wicket:message></a></span>\r
+       </wicket:fragment>\r
+\r
+       <wicket:fragment wicket:id="flatRepositoryHeader">\r
+               <tr>\r
+                       <th class="left" wicket:id="orderByRepository">\r
+                               <wicket:link>\r
+                                       <img style="vertical-align: top; border: 1px solid #888;" src="/com/gitblit/wicket/resources/gitweb-favicon.png"/>\r
+                               </wicket:link>\r
+                               <wicket:message key="gb.repository">Repository</wicket:message>\r
+                       </th>\r
+                       <th wicket:id="orderByDescription"><wicket:message key="gb.description">Description</wicket:message></th>\r
+                       <th wicket:id="orderByOwner"><wicket:message key="gb.owner">Owner</wicket:message></th>\r
+                       <th></th>\r
+                       <th wicket:id="orderByDate"><wicket:message key="gb.lastChange">Last Change</wicket:message></th>\r
+                       <th clas="right"></th>\r
+               </tr>\r
+       </wicket:fragment>\r
+       \r
+       <wicket:fragment wicket:id="groupRepositoryHeader">\r
+               <tr>\r
+                       <th class="left">\r
+                               <wicket:link>\r
+                                       <img style="vertical-align: top; border: 1px solid #888;" src="/com/gitblit/wicket/resources/gitweb-favicon.png"/>\r
+                               </wicket:link>\r
+                               <wicket:message key="gb.repository">Repository</wicket:message>\r
+                       </th>\r
+                       <th><wicket:message key="gb.description">Description</wicket:message></th>\r
+                       <th><wicket:message key="gb.owner">Owner</wicket:message></th>\r
+                       <th></th>\r
+                       <th><wicket:message key="gb.lastChange">Last Change</wicket:message></th>\r
+                       <th class="right"></th>\r
+               </tr>\r
+       </wicket:fragment>\r
+       \r
+       <wicket:fragment wicket:id="groupRepositoryRow">\r
+        <td colspan="6"><span wicket:id="groupName">[group name]</span></td>\r
+       </wicket:fragment>\r
+               \r
+       <wicket:fragment wicket:id="repositoryRow">\r
+        <td class="left"><div class="list" wicket:id="repositoryName">[repository name]</div></td>\r
+        <td><div class="list" wicket:id="repositoryDescription">[repository description]</div></td>\r
+        <td class="author"><span wicket:id="repositoryOwner">[repository owner]</span></td>\r
+        <td style="text-align: right;padding-right:10px;"><img class="inlineIcon" wicket:id="ticketsIcon" /><img class="inlineIcon" wicket:id="docsIcon" /><img class="inlineIcon" wicket:id="frozenIcon" /><img class="inlineIcon" wicket:id="accessRestrictionIcon" /></td>\r
+        <td><span wicket:id="repositoryLastChange">[last change]</span></td>\r
+        <td class="rightAlign"><span wicket:id="repositoryLinks"></span></td>\r
+       </wicket:fragment>\r
+       \r
+</wicket:panel>\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/panels/RepositoriesPanel.java b/src/com/gitblit/wicket/panels/RepositoriesPanel.java
new file mode 100644 (file)
index 0000000..6d05888
--- /dev/null
@@ -0,0 +1,274 @@
+package com.gitblit.wicket.panels;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.Comparator;\r
+import java.util.Date;\r
+import java.util.HashMap;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.apache.wicket.PageParameters;\r
+import org.apache.wicket.extensions.markup.html.repeater.data.sort.OrderByBorder;\r
+import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;\r
+import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;\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 org.apache.wicket.markup.repeater.Item;\r
+import org.apache.wicket.markup.repeater.data.DataView;\r
+import org.apache.wicket.markup.repeater.data.IDataProvider;\r
+import org.apache.wicket.markup.repeater.data.ListDataProvider;\r
+import org.apache.wicket.model.IModel;\r
+import org.apache.wicket.model.Model;\r
+\r
+import com.gitblit.Constants.AccessRestrictionType;\r
+import com.gitblit.GitBlit;\r
+import com.gitblit.Keys;\r
+import com.gitblit.utils.StringUtils;\r
+import com.gitblit.utils.TimeUtils;\r
+import com.gitblit.wicket.GitBlitWebSession;\r
+import com.gitblit.wicket.LinkPanel;\r
+import com.gitblit.wicket.WicketUtils;\r
+import com.gitblit.wicket.models.RepositoryModel;\r
+import com.gitblit.wicket.models.UserModel;\r
+import com.gitblit.wicket.pages.EditRepositoryPage;\r
+import com.gitblit.wicket.pages.SummaryPage;\r
+\r
+\r
+public class RepositoriesPanel extends BasePanel {\r
+\r
+       private static final long serialVersionUID = 1L;\r
+       \r
+       public RepositoriesPanel(String wicketId, final boolean showAdmin, final Map<AccessRestrictionType, String> accessRestrictionTranslations) {\r
+               super(wicketId);\r
+               \r
+               final UserModel user = GitBlitWebSession.get().getUser();\r
+               List<RepositoryModel> models = GitBlit.self().getRepositoryModels(user);\r
+               IDataProvider<RepositoryModel> dp;\r
+               \r
+               Fragment adminLinks = new Fragment("adminPanel", "adminLinks", this);\r
+               adminLinks.add(new BookmarkablePageLink<Void>("newRepository", EditRepositoryPage.class));\r
+               add(adminLinks.setVisible(showAdmin));\r
+               \r
+               if (GitBlit.self().settings().getString(Keys.web.repositoryListType, "flat").equalsIgnoreCase("grouped")) {\r
+                       Map<String, List<RepositoryModel>> groups = new HashMap<String, List<RepositoryModel>>();\r
+                       for (RepositoryModel model : models) {\r
+                               String rootPath = StringUtils.getRootPath(model.name);\r
+                               if (StringUtils.isEmpty(rootPath)) {\r
+                                       rootPath = GitBlit.self().settings().getString(Keys.web.repositoryRootGroupName, " ");\r
+                               }\r
+                               if (!groups.containsKey(rootPath)) {\r
+                                       groups.put(rootPath, new ArrayList<RepositoryModel>());\r
+                               }\r
+                               groups.get(rootPath).add(model);\r
+                       }\r
+                       List<String> roots = new ArrayList<String>(groups.keySet());\r
+                       Collections.sort(roots);\r
+                       List<RepositoryModel> groupedModels = new ArrayList<RepositoryModel>();\r
+                       for (String root : roots) {\r
+                               List<RepositoryModel> subModels = groups.get(root);\r
+                               groupedModels.add(new GroupRepositoryModel(root + " (" + subModels.size() + ")"));\r
+                               groupedModels.addAll(subModels);\r
+                       }\r
+                       dp = new ListDataProvider<RepositoryModel>(groupedModels);\r
+               } else {\r
+                       dp = new DataProvider(models);\r
+               }\r
+\r
+               DataView<RepositoryModel> dataView = new DataView<RepositoryModel>("row", dp) {\r
+                       private static final long serialVersionUID = 1L;\r
+                       int counter = 0;\r
+\r
+                       public void populateItem(final Item<RepositoryModel> item) {\r
+                               final RepositoryModel entry = item.getModelObject();\r
+                               if (entry instanceof GroupRepositoryModel) {\r
+                                       Fragment row = new Fragment("rowContent", "groupRepositoryRow", this);\r
+                                       item.add(row);\r
+                                       row.add(new Label("groupName", entry.name));\r
+                                       WicketUtils.setCssClass(item, "group");\r
+                                       return;\r
+                               }\r
+                               Fragment row = new Fragment("rowContent", "repositoryRow", this);\r
+                               item.add(row);\r
+                               if (entry.hasCommits) {\r
+                                       // Existing repository\r
+                                       PageParameters pp = WicketUtils.newRepositoryParameter(entry.name);\r
+                                       row.add(new LinkPanel("repositoryName", "list", entry.name, SummaryPage.class, pp));\r
+                                       row.add(new LinkPanel("repositoryDescription", "list", entry.description, SummaryPage.class, pp));\r
+                               } else {\r
+                                       // New repository\r
+                                       row.add(new Label("repositoryName", entry.name + "<span class='empty'>(empty)</span>").setEscapeModelStrings(false));\r
+                                       row.add(new Label("repositoryDescription", entry.description));\r
+                               }\r
+\r
+                               if (entry.useTickets) {\r
+                                       row.add(WicketUtils.newImage("ticketsIcon", "bug_16x16.png", getString("gb.tickets")));\r
+                               } else {\r
+                                       row.add(WicketUtils.newBlankImage("ticketsIcon"));\r
+                               }\r
+\r
+                               if (entry.useDocs) {\r
+                                       row.add(WicketUtils.newImage("docsIcon", "book_16x16.png", getString("gb.docs")));\r
+                               } else {\r
+                                       row.add(WicketUtils.newBlankImage("docsIcon"));\r
+                               }\r
+\r
+                               if (entry.isFrozen) {\r
+                                       row.add(WicketUtils.newImage("frozenIcon", "cold_16x16.png", getString("gb.isFrozen")));\r
+                               } else {\r
+                                       row.add(WicketUtils.newClearPixel("frozenIcon").setVisible(false));\r
+                               }\r
+                               switch (entry.accessRestriction) {\r
+                               case NONE:\r
+                                       row.add(WicketUtils.newBlankImage("accessRestrictionIcon"));\r
+                                       break;\r
+                               case PUSH:\r
+                                       row.add(WicketUtils.newImage("accessRestrictionIcon", "lock_go_16x16.png", accessRestrictionTranslations.get(entry.accessRestriction)));\r
+                                       break;\r
+                               case CLONE:\r
+                                       row.add(WicketUtils.newImage("accessRestrictionIcon", "lock_pull_16x16.png", accessRestrictionTranslations.get(entry.accessRestriction)));\r
+                                       break;\r
+                               case VIEW:\r
+                                       row.add(WicketUtils.newImage("accessRestrictionIcon", "shield_16x16.png", accessRestrictionTranslations.get(entry.accessRestriction)));\r
+                                       break;\r
+                               default:\r
+                                       row.add(WicketUtils.newBlankImage("accessRestrictionIcon"));\r
+                               }\r
+\r
+                               row.add(new Label("repositoryOwner", entry.owner));\r
+\r
+                               String lastChange = TimeUtils.timeAgo(entry.lastChange);\r
+                               Label lastChangeLabel = new Label("repositoryLastChange", lastChange);\r
+                               row.add(lastChangeLabel);\r
+                               WicketUtils.setCssClass(lastChangeLabel, TimeUtils.timeAgoCss(entry.lastChange));\r
+\r
+                               boolean showOwner = user != null && user.getUsername().equalsIgnoreCase(entry.owner);                           \r
+                               if (showAdmin) {\r
+                                       Fragment repositoryLinks = new Fragment("repositoryLinks", "repositoryAdminLinks", this);\r
+                                       repositoryLinks.add(new BookmarkablePageLink<Void>("editRepository", EditRepositoryPage.class, WicketUtils.newRepositoryParameter(entry.name)));\r
+                                       repositoryLinks.add(new BookmarkablePageLink<Void>("renameRepository", EditRepositoryPage.class, WicketUtils.newRepositoryParameter(entry.name)).setEnabled(false));\r
+                                       repositoryLinks.add(new BookmarkablePageLink<Void>("deleteRepository", EditRepositoryPage.class, WicketUtils.newRepositoryParameter(entry.name)).setEnabled(false));\r
+                                       row.add(repositoryLinks);\r
+                               } else if (showOwner) {\r
+                                       Fragment repositoryLinks = new Fragment("repositoryLinks", "repositoryOwnerLinks", this);\r
+                                       repositoryLinks.add(new BookmarkablePageLink<Void>("editRepository", EditRepositoryPage.class, WicketUtils.newRepositoryParameter(entry.name)));\r
+                                       row.add(repositoryLinks);\r
+                               } else {\r
+                                       row.add(new Label("repositoryLinks"));\r
+                               }\r
+                               WicketUtils.setAlternatingBackground(item, counter);\r
+                               counter++;\r
+                       }\r
+               };\r
+               add(dataView);\r
+\r
+               if (dp instanceof SortableDataProvider<?>) {\r
+                       // add sortable header\r
+                       SortableDataProvider<?> sdp = (SortableDataProvider<?>) dp;\r
+                       Fragment fragment = new Fragment("headerContent", "flatRepositoryHeader", this);\r
+                       fragment.add(newSort("orderByRepository", SortBy.repository, sdp, dataView));\r
+                       fragment.add(newSort("orderByDescription", SortBy.description, sdp, dataView));\r
+                       fragment.add(newSort("orderByOwner", SortBy.owner, sdp, dataView));\r
+                       fragment.add(newSort("orderByDate", SortBy.date, sdp, dataView));\r
+                       add(fragment);\r
+               } else {\r
+                       // not sortable\r
+                       Fragment fragment = new Fragment("headerContent", "groupRepositoryHeader", this);\r
+                       add(fragment);\r
+               }\r
+       }\r
+       \r
+       private class GroupRepositoryModel extends RepositoryModel {\r
+\r
+               private static final long serialVersionUID = 1L;\r
+\r
+               GroupRepositoryModel(String name) {\r
+                       super(name, "", "", new Date(0));\r
+               }\r
+       }\r
+       \r
+       protected enum SortBy {\r
+               repository, description, owner, date;\r
+       }\r
+\r
+       protected OrderByBorder newSort(String wicketId, SortBy field, SortableDataProvider<?> dp, final DataView<?> dataView) {\r
+               return new OrderByBorder(wicketId, field.name(), dp) {\r
+                       private static final long serialVersionUID = 1L;\r
+\r
+                       @Override\r
+                       protected void onSortChanged() {\r
+                               dataView.setCurrentPage(0);\r
+                       }\r
+               };\r
+       }\r
+\r
+       private class DataProvider extends SortableDataProvider<RepositoryModel> {\r
+               private static final long serialVersionUID = 1L;\r
+               private List<RepositoryModel> list = null;\r
+\r
+               protected DataProvider(List<RepositoryModel> list) {\r
+                       this.list = list;\r
+                       setSort(SortBy.date.name(), false);\r
+               }\r
+\r
+               @Override\r
+               public int size() {\r
+                       if (list == null)\r
+                               return 0;\r
+                       return list.size();\r
+               }\r
+\r
+               @Override\r
+               public IModel<RepositoryModel> model(RepositoryModel header) {\r
+                       return new Model<RepositoryModel>(header);\r
+               }\r
+\r
+               @Override\r
+               public Iterator<RepositoryModel> iterator(int first, int count) {\r
+                       SortParam sp = getSort();\r
+                       String prop = sp.getProperty();\r
+                       final boolean asc = sp.isAscending();\r
+\r
+                       if (prop == null || prop.equals(SortBy.date.name())) {\r
+                               Collections.sort(list, new Comparator<RepositoryModel>() {\r
+                                       @Override\r
+                                       public int compare(RepositoryModel o1, RepositoryModel o2) {\r
+                                               if (asc)\r
+                                                       return o1.lastChange.compareTo(o2.lastChange);\r
+                                               return o2.lastChange.compareTo(o1.lastChange);\r
+                                       }\r
+                               });\r
+                       } else if (prop.equals(SortBy.repository.name())) {\r
+                               Collections.sort(list, new Comparator<RepositoryModel>() {\r
+                                       @Override\r
+                                       public int compare(RepositoryModel o1, RepositoryModel o2) {\r
+                                               if (asc)\r
+                                                       return o1.name.compareTo(o2.name);\r
+                                               return o2.name.compareTo(o1.name);\r
+                                       }\r
+                               });\r
+                       } else if (prop.equals(SortBy.owner.name())) {\r
+                               Collections.sort(list, new Comparator<RepositoryModel>() {\r
+                                       @Override\r
+                                       public int compare(RepositoryModel o1, RepositoryModel o2) {\r
+                                               if (asc)\r
+                                                       return o1.owner.compareTo(o2.owner);\r
+                                               return o2.owner.compareTo(o1.owner);\r
+                                       }\r
+                               });\r
+                       } else if (prop.equals(SortBy.description.name())) {\r
+                               Collections.sort(list, new Comparator<RepositoryModel>() {\r
+                                       @Override\r
+                                       public int compare(RepositoryModel o1, RepositoryModel o2) {\r
+                                               if (asc)\r
+                                                       return o1.description.compareTo(o2.description);\r
+                                               return o2.description.compareTo(o1.description);\r
+                                       }\r
+                               });\r
+                       }\r
+                       return list.subList(first, first + count).iterator();\r
+               }\r
+       }\r
+}\r
diff --git a/src/com/gitblit/wicket/panels/UsersPanel.html b/src/com/gitblit/wicket/panels/UsersPanel.html
new file mode 100644 (file)
index 0000000..39074b2
--- /dev/null
@@ -0,0 +1,48 @@
+<!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
+\r
+               <div wicket:id="adminPanel">[admin links]</div>\r
+               \r
+               <table class="repositories">\r
+               <tr>\r
+                       <th class="left">\r
+                               <wicket:link>\r
+                                       <img style="vertical-align: top; border: 1px solid #888; background-color: white;" src="/com/gitblit/wicket/resources/user_16x16.png"/>\r
+                               </wicket:link>\r
+                               <wicket:message key="gb.username">[username]</wicket:message>\r
+                       </th>\r
+                       <th class="right"></th>\r
+               </tr>\r
+               <tbody>         \r
+                       <tr wicket:id="userRow">\r
+                               <td class="left" ><div class="list" wicket:id="username">[username]</div></td>\r
+                               <td class="rightAlign"><span wicket:id="userLinks"></span></td>                         \r
+                       </tr>\r
+       </tbody>\r
+       </table>\r
+       \r
+       <wicket:fragment wicket:id="adminLinks">\r
+               <!-- page nav links --> \r
+               <div class="admin_nav">\r
+                       <wicket:link>\r
+                               <img style="vertical-align: top;" src="/com/gitblit/wicket/resources/add_16x16.png"/>\r
+                       </wicket:link>          \r
+                       <a wicket:id="newUser">\r
+                               <wicket:message key="gb.newUser"></wicket:message>\r
+                       </a>\r
+               </div>  \r
+       </wicket:fragment>\r
+       \r
+       <wicket:fragment wicket:id="userAdminLinks">\r
+               <span class="link"><a wicket:id="editUser"><wicket:message key="gb.edit">[edit]</wicket:message></a> | <a wicket:id="deleteUser"><wicket:message key="gb.delete">[delete]</wicket:message></a></span>\r
+       </wicket:fragment>\r
+       \r
+</wicket:panel>\r
+</body>\r
+</html>
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/panels/UsersPanel.java b/src/com/gitblit/wicket/panels/UsersPanel.java
new file mode 100644 (file)
index 0000000..1721272
--- /dev/null
@@ -0,0 +1,46 @@
+package com.gitblit.wicket.panels;\r
+\r
+import org.apache.wicket.markup.html.link.BookmarkablePageLink;\r
+import org.apache.wicket.markup.html.panel.Fragment;\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
+\r
+import com.gitblit.GitBlit;\r
+import com.gitblit.wicket.LinkPanel;\r
+import com.gitblit.wicket.WicketUtils;\r
+import com.gitblit.wicket.pages.EditUserPage;\r
+import com.gitblit.wicket.pages.RepositoriesPage;\r
+\r
+public class UsersPanel extends BasePanel {\r
+\r
+       private static final long serialVersionUID = 1L;\r
+\r
+       public UsersPanel(String wicketId, final boolean showAdmin) {\r
+               super(wicketId);\r
+\r
+               Fragment adminLinks = new Fragment("adminPanel", "adminLinks", this);\r
+               adminLinks.add(new BookmarkablePageLink<Void>("newUser", EditUserPage.class));\r
+               add(adminLinks.setVisible(showAdmin));\r
+               \r
+               DataView<String> usersView = new DataView<String>("userRow", new ListDataProvider<String>(GitBlit.self().getAllUsernames())) {\r
+                       private static final long serialVersionUID = 1L;\r
+                       private int counter = 0;\r
+\r
+                       public void populateItem(final Item<String> item) {\r
+                               final String entry = item.getModelObject();\r
+                               LinkPanel editLink = new LinkPanel("username", "list", entry, EditUserPage.class, WicketUtils.newUsernameParameter(entry));\r
+                               WicketUtils.setHtmlTooltip(editLink, getString("gb.edit") + " " + entry);\r
+                               item.add(editLink);\r
+                               Fragment userLinks = new Fragment("userLinks", "userAdminLinks", this);\r
+                               userLinks.add(new BookmarkablePageLink<Void>("editUser", EditUserPage.class, WicketUtils.newUsernameParameter(entry)));\r
+                               userLinks.add(new BookmarkablePageLink<Void>("deleteUser", RepositoriesPage.class, WicketUtils.newUsernameParameter(entry)).setEnabled(false));\r
+                               item.add(userLinks);\r
+\r
+                               WicketUtils.setAlternatingBackground(item, counter);\r
+                               counter++;\r
+                       }\r
+               };\r
+               add(usersView.setVisible(showAdmin));\r
+       }\r
+}\r
diff --git a/src/com/gitblit/wicket/resources/add_16x16.png b/src/com/gitblit/wicket/resources/add_16x16.png
new file mode 100644 (file)
index 0000000..0ea124a
Binary files /dev/null and b/src/com/gitblit/wicket/resources/add_16x16.png differ
index 3fa1fcf1ce5a9b84bec2ae8c5d317137d5141d0d..4a971a6fa6a8fc83b608c1821dde2490bf22b104 100644 (file)
@@ -190,6 +190,10 @@ div.page_nav2 {
 }\r
 \r
 div.admin_nav {\r
+       border: 1px solid #888;\r
+       border-bottom: 0px;\r
+       background:#dae0d2;\r
+       text-align: right;\r
        padding: 5px 5px 5px 2px;       \r
 }\r
 \r
@@ -493,7 +497,7 @@ table.plain td.edit input:focus, table.plain td.edit input:hover{
        border: 1px solid orange;\r
 }\r
 \r
-table.pretty, table.repositories, table.comments {\r
+table.pretty, table.comments {\r
        margin-bottom:5px;\r
        border-spacing: 0px;\r
        border-left: 1px solid #bbb;\r
@@ -522,6 +526,11 @@ table.comments td {
        line-height: 17px;\r
 }\r
 \r
+table.repositories {\r
+       margin-bottom:5px;\r
+       border-spacing: 0px;\r
+}\r
+\r
 table.repositories th {\r
        background-color:#D2C3AF;\r
        padding: 4px;\r
@@ -529,10 +538,28 @@ table.repositories th {
        border-bottom: 1px solid #808080;\r
 }\r
 \r
+table.repositories th.left, table.repositories td.left {\r
+       border-left: 1px solid #808080;\r
+       padding-left: 5px;\r
+}\r
+\r
+table.repositories td.left {\r
+       padding-left: 10px;\r
+}\r
+\r
+table.repositories th.right, table.repositories td.right {\r
+       border-right: 1px solid #808080;\r
+}\r
+\r
 table.repositories td {\r
        padding: 2px;\r
 }\r
 \r
+table.repositories td.rightAlign {     \r
+       text-align: right;\r
+       border-right: 1px solid #808080;\r
+}      \r
+\r
 table.repositories td.icon img {\r
        vertical-align: top;\r
 }\r
@@ -552,6 +579,20 @@ table.repositories th.wicket_orderDown a, table.repositories th.wicket_orderUp a
        font-weight: bold;\r
 }\r
 \r
+table.repositories tr.group {\r
+       background-color: #E66C2C;\r
+}\r
+\r
+table.repositories tr.group td {\r
+       font-weight: bold;      \r
+       border-bottom: 1px solid orange;\r
+       color: white;\r
+       background-color: #E66C2C;\r
+       border-left: 1px solid #808080;\r
+       border-right: 1px solid #808080;\r
+       padding-left: 5px;\r
+}\r
+\r
 table.palette { border:0;}\r
 table.palette td.header { \r
        font-weight: bold; \r
@@ -570,17 +611,6 @@ tr th.wicket_orderDown a {background-image: url(arrow_down.png); }
 tr th.wicket_orderUp a { background-image: url(arrow_up.png); }\r
 tr th.wicket_orderNone a { background-image: url(arrow_off.png); }\r
 \r
-tr.group {\r
-       background-color: #E66C2C;\r
-}\r
-\r
-tr.group td {\r
-       font-weight: bold;\r
-       border-bottom: 1px solid orange;\r
-       color: white;\r
-       background-color: #E66C2C;      \r
-}\r
-\r
 tr.light {\r
        background-color: #ffffff;\r
 }\r
diff --git a/src/com/gitblit/wicket/resources/gitweb-favicon.png b/src/com/gitblit/wicket/resources/gitweb-favicon.png
new file mode 100644 (file)
index 0000000..de637c0
Binary files /dev/null and b/src/com/gitblit/wicket/resources/gitweb-favicon.png differ
diff --git a/src/com/gitblit/wicket/resources/user_16x16.png b/src/com/gitblit/wicket/resources/user_16x16.png
new file mode 100644 (file)
index 0000000..d5edd4d
Binary files /dev/null and b/src/com/gitblit/wicket/resources/user_16x16.png differ