From cf17b2267bab439cadafbc1def298bae0d5ea659 Mon Sep 17 00:00:00 2001 From: James Moger Date: Thu, 30 May 2013 23:29:25 -0400 Subject: Added a Dashboard page with a daily ref log of starred/owned repos This is a work-in-progress and is mostly working like I want, but will require some refactoring to make it even more useful and less complex. --- .../java/com/gitblit/models/DailyLogEntry.java | 59 +++ src/main/java/com/gitblit/models/PushLogEntry.java | 17 + src/main/java/com/gitblit/utils/PushLogUtils.java | 176 +++++++-- .../java/com/gitblit/wicket/GitBlitWebApp.java | 5 +- .../com/gitblit/wicket/GitBlitWebApp.properties | 15 +- .../com/gitblit/wicket/charting/GoogleChart.java | 6 + .../gitblit/wicket/charting/GooglePieChart.java | 4 +- .../java/com/gitblit/wicket/ng/NgController.java | 79 ++++ .../com/gitblit/wicket/pages/ActivityPage.html | 8 +- .../com/gitblit/wicket/pages/ActivityPage.java | 10 +- .../java/com/gitblit/wicket/pages/BasePage.html | 3 +- .../com/gitblit/wicket/pages/DashboardPage.html | 99 +++++ .../com/gitblit/wicket/pages/DashboardPage.java | 418 +++++++++++++++++++++ .../java/com/gitblit/wicket/pages/HomePage.html | 16 - .../java/com/gitblit/wicket/pages/HomePage.java | 182 --------- .../com/gitblit/wicket/pages/OverviewPage.java | 2 +- .../java/com/gitblit/wicket/pages/PushesPage.java | 2 +- .../java/com/gitblit/wicket/pages/RootPage.java | 4 +- .../com/gitblit/wicket/panels/ActivityPanel.html | 2 +- .../com/gitblit/wicket/panels/PushesPanel.html | 10 +- .../com/gitblit/wicket/panels/PushesPanel.java | 100 +++-- 21 files changed, 939 insertions(+), 278 deletions(-) create mode 100644 src/main/java/com/gitblit/models/DailyLogEntry.java create mode 100644 src/main/java/com/gitblit/wicket/ng/NgController.java create mode 100644 src/main/java/com/gitblit/wicket/pages/DashboardPage.html create mode 100644 src/main/java/com/gitblit/wicket/pages/DashboardPage.java delete mode 100644 src/main/java/com/gitblit/wicket/pages/HomePage.html delete mode 100644 src/main/java/com/gitblit/wicket/pages/HomePage.java (limited to 'src/main/java') diff --git a/src/main/java/com/gitblit/models/DailyLogEntry.java b/src/main/java/com/gitblit/models/DailyLogEntry.java new file mode 100644 index 00000000..db605268 --- /dev/null +++ b/src/main/java/com/gitblit/models/DailyLogEntry.java @@ -0,0 +1,59 @@ +/* + * Copyright 2013 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.models; + +import java.io.Serializable; +import java.util.Date; + +import org.eclipse.jgit.lib.PersonIdent; + +/** + * Model class to simulate a push for presentation in the push log news feed + * for a repository that does not have a Gitblit push log. Commits are grouped + * by date and may be additionally split by ref. + * + * @author James Moger + */ +public class DailyLogEntry extends PushLogEntry implements Serializable { + + private static final long serialVersionUID = 1L; + + public DailyLogEntry(String repository, Date date) { + super(repository, date, new UserModel("digest")); + } + + public DailyLogEntry(String repository, Date date, UserModel user) { + super(repository, date, user); + } + + @Override + public PersonIdent getCommitterIdent() { + if (getAuthorCount() == 1) { + return getCommits().get(0).getCommitterIdent(); + } + + return super.getCommitterIdent(); + } + + @Override + public PersonIdent getAuthorIdent() { + if (getAuthorCount() == 1) { + return getCommits().get(0).getAuthorIdent(); + } + + return super.getAuthorIdent(); + } +} diff --git a/src/main/java/com/gitblit/models/PushLogEntry.java b/src/main/java/com/gitblit/models/PushLogEntry.java index d8f0b091..8b006d96 100644 --- a/src/main/java/com/gitblit/models/PushLogEntry.java +++ b/src/main/java/com/gitblit/models/PushLogEntry.java @@ -54,6 +54,8 @@ public class PushLogEntry implements Serializable, Comparable { private final Map refUpdates; private final Map refIdChanges; + + private int authorCount; /** * Constructor for specified duration of push from start date. @@ -72,6 +74,7 @@ public class PushLogEntry implements Serializable, Comparable { this.commits = new LinkedHashSet(); this.refUpdates = new HashMap(); this.refIdChanges = new HashMap(); + this.authorCount = -1; } /** @@ -152,6 +155,7 @@ public class PushLogEntry implements Serializable, Comparable { public RepositoryCommit addCommit(String branch, RevCommit commit) { RepositoryCommit commitModel = new RepositoryCommit(repository, branch, commit); if (commits.add(commitModel)) { + authorCount = -1; return commitModel; } return null; @@ -165,6 +169,7 @@ public class PushLogEntry implements Serializable, Comparable { */ public void addCommits(List list) { commits.addAll(list); + authorCount = -1; } /** @@ -254,6 +259,18 @@ public class PushLogEntry implements Serializable, Comparable { return list; } + public int getAuthorCount() { + if (authorCount == -1) { + Set authors = new HashSet(); + for (RepositoryCommit commit : commits) { + String name = commit.getAuthorIdent().getName(); + authors.add(name); + } + authorCount = authors.size(); + } + return authorCount; + } + /** * The total number of commits in the push. * diff --git a/src/main/java/com/gitblit/utils/PushLogUtils.java b/src/main/java/com/gitblit/utils/PushLogUtils.java index 2f076fb5..e10a6864 100644 --- a/src/main/java/com/gitblit/utils/PushLogUtils.java +++ b/src/main/java/com/gitblit/utils/PushLogUtils.java @@ -16,8 +16,11 @@ package com.gitblit.utils; import java.io.IOException; +import java.text.DateFormat; import java.text.MessageFormat; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; @@ -50,6 +53,7 @@ import org.eclipse.jgit.treewalk.TreeWalk; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.gitblit.models.DailyLogEntry; import com.gitblit.models.PathModel.PathChangeModel; import com.gitblit.models.PushLogEntry; import com.gitblit.models.RefModel; @@ -109,6 +113,25 @@ public class PushLogUtils { return null; } + private static UserModel newUserModelFrom(PersonIdent ident) { + String name = ident.getName(); + String username; + String displayname; + if (name.indexOf('/') > -1) { + int slash = name.indexOf('/'); + displayname = name.substring(0, slash); + username = name.substring(slash + 1); + } else { + displayname = name; + username = ident.getEmailAddress(); + } + + UserModel user = new UserModel(username); + user.displayName = displayname; + user.emailAddress = ident.getEmailAddress(); + return user; + } + /** * Updates a push log. * @@ -135,9 +158,15 @@ public class PushLogUtils { DirCache index = createIndex(repository, headId, commands); ObjectId indexTreeId = index.writeTree(odi); - PersonIdent ident = - new PersonIdent(MessageFormat.format("{0}/{1}", user.getDisplayName(), user.username), + PersonIdent ident; + if (UserModel.ANONYMOUS.equals(user)) { + // anonymous push + ident = new PersonIdent("anonymous", "anonymous"); + } else { + // construct real pushing account + ident = new PersonIdent(MessageFormat.format("{0}/{1}", user.getDisplayName(), user.username), user.emailAddress == null ? user.username : user.emailAddress); + } // Create a commit object CommitBuilder commit = new CommitBuilder(); @@ -339,23 +368,9 @@ public class PushLogUtils { continue; } - String name = push.getAuthorIdent().getName(); - String username; - String displayname; - if (name.indexOf('/') > -1) { - int slash = name.indexOf('/'); - displayname = name.substring(0, slash); - username = name.substring(slash + 1); - } else { - displayname = name; - username = push.getAuthorIdent().getEmailAddress(); - } - - UserModel user = new UserModel(username); - user.displayName = displayname; - user.emailAddress = push.getAuthorIdent().getEmailAddress(); - + UserModel user = newUserModelFrom(push.getAuthorIdent()); Date date = push.getAuthorIdent().getWhen(); + PushLogEntry log = new PushLogEntry(repositoryName, date, user); list.add(log); List changedRefs = JGitUtils.getFilesInCommit(repository, push); @@ -413,14 +428,22 @@ public class PushLogUtils { int maxCount) { // break the push log into ref push logs and then merge them back into a list Map> refMap = new HashMap>(); - for (PushLogEntry push : getPushLog(repositoryName, repository, offset, maxCount)) { + List pushes = getPushLog(repositoryName, repository, offset, maxCount); + for (PushLogEntry push : pushes) { for (String ref : push.getChangedRefs()) { if (!refMap.containsKey(ref)) { refMap.put(ref, new ArrayList()); } // construct new ref-specific push log entry - PushLogEntry refPush = new PushLogEntry(push.repository, push.date, push.user); + PushLogEntry refPush; + if (push instanceof DailyLogEntry) { + // simulated push log from commits grouped by date + refPush = new DailyLogEntry(push.repository, push.date); + } else { + // real push log entry + refPush = new PushLogEntry(push.repository, push.date, push.user); + } refPush.updateRef(ref, push.getChangeType(ref), push.getOldId(ref), push.getNewId(ref)); refPush.addCommits(push.getCommits(ref)); refMap.get(ref).add(refPush); @@ -451,15 +474,16 @@ public class PushLogUtils { public static List getPushLogByRef(String repositoryName, Repository repository, Date minimumDate) { // break the push log into ref push logs and then merge them back into a list Map> refMap = new HashMap>(); - for (PushLogEntry push : getPushLog(repositoryName, repository, minimumDate)) { + List pushes = getPushLog(repositoryName, repository, minimumDate); + for (PushLogEntry push : pushes) { for (String ref : push.getChangedRefs()) { if (!refMap.containsKey(ref)) { refMap.put(ref, new ArrayList()); } - - // construct new ref-specific push log entry - PushLogEntry refPush = new PushLogEntry(push.repository, push.date, push.user); - refPush.updateRef(ref, push.getChangeType(ref), push.getOldId(ref), push.getNewId(ref)); + + // construct new ref-specific push log entry + PushLogEntry refPush = new PushLogEntry(push.repository, push.date, push.user); + refPush.updateRef(ref, push.getChangeType(ref), push.getOldId(ref), push.getNewId(ref)); refPush.addCommits(push.getCommits(ref)); refMap.get(ref).add(refPush); } @@ -476,4 +500,106 @@ public class PushLogUtils { return refPushLog; } + + /** + * Returns a commit log grouped by day. + * + * @param repositoryName + * @param repository + * @param minimumDate + * @param offset + * @param maxCount + * if < 0, all pushes are returned. + * @return a list of grouped commit log entries + */ + public static List getDailyLog(String repositoryName, Repository repository, + Date minimumDate, int offset, int maxCount) { + + DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); +// df.setTimeZone(timezone); + + Map> allRefs = JGitUtils.getAllRefs(repository); + Map tags = new HashMap(); + Map dailydigests = new HashMap(); + for (RefModel local : JGitUtils.getLocalBranches(repository, true, -1)) { + String branch = local.getName(); + List commits = JGitUtils.getRevLog(repository, branch, minimumDate); + for (RevCommit commit : commits) { + Date date = JGitUtils.getCommitDate(commit); + String dateStr = df.format(date); + if (!dailydigests.containsKey(dateStr)) { + dailydigests.put(dateStr, new DailyLogEntry(repositoryName, date)); + } + PushLogEntry digest = dailydigests.get(dateStr); + digest.updateRef(branch, ReceiveCommand.Type.UPDATE, commit.getParents()[0].getId().getName(), commit.getName()); + RepositoryCommit repoCommit = digest.addCommit(branch, commit); + if (repoCommit != null) { + repoCommit.setRefs(allRefs.get(commit.getId())); + if (!ArrayUtils.isEmpty(repoCommit.getRefs())) { + // treat tags as special events in the log + for (RefModel ref : repoCommit.getRefs()) { + if (ref.getName().startsWith(Constants.R_TAGS)) { + if (!tags.containsKey(dateStr)) { + UserModel tagUser = newUserModelFrom(commit.getAuthorIdent()); + Date tagDate = commit.getAuthorIdent().getWhen(); + tags.put(dateStr, new DailyLogEntry(repositoryName, tagDate, tagUser)); + } + PushLogEntry tagEntry = tags.get(dateStr); + tagEntry.updateRef(ref.getName(), ReceiveCommand.Type.CREATE); + tagEntry.addCommits(Arrays.asList(repoCommit)); + } + } + } + } + } + } + + List list = new ArrayList(dailydigests.values()); + list.addAll(tags.values()); + Collections.sort(list); + return list; + } + + /** + * Returns the list of commits separated by ref (e.g. each ref has it's own + * PushLogEntry object for each day). + * + * @param repositoryName + * @param repository + * @param minimumDate + * @return a list of push log entries separated by ref and date + */ + public static List getDailyLogByRef(String repositoryName, Repository repository, Date minimumDate) { + // break the push log into ref push logs and then merge them back into a list + Map> refMap = new HashMap>(); + List pushes = getDailyLog(repositoryName, repository, minimumDate, 0, -1); + for (DailyLogEntry push : pushes) { + for (String ref : push.getChangedRefs()) { + if (!refMap.containsKey(ref)) { + refMap.put(ref, new ArrayList()); + } + + // construct new ref-specific push log entry + DailyLogEntry refPush = new DailyLogEntry(push.repository, push.date, push.user); + refPush.updateRef(ref, push.getChangeType(ref), push.getOldId(ref), push.getNewId(ref)); + refPush.addCommits(push.getCommits(ref)); + refMap.get(ref).add(refPush); + } + } + + // merge individual ref pushes into master list + List refPushLog = new ArrayList(); + for (List refPush : refMap.values()) { + for (DailyLogEntry entry : refPush) { + if (entry.getCommitCount() > 0) { + refPushLog.add(entry); + } + } + } + + // sort ref push log + Collections.sort(refPushLog); + + return refPushLog; + } } diff --git a/src/main/java/com/gitblit/wicket/GitBlitWebApp.java b/src/main/java/com/gitblit/wicket/GitBlitWebApp.java index bdb4d455..f4180faa 100644 --- a/src/main/java/com/gitblit/wicket/GitBlitWebApp.java +++ b/src/main/java/com/gitblit/wicket/GitBlitWebApp.java @@ -44,6 +44,7 @@ import com.gitblit.wicket.pages.ForksPage; import com.gitblit.wicket.pages.GitSearchPage; import com.gitblit.wicket.pages.GravatarProfilePage; import com.gitblit.wicket.pages.HistoryPage; +import com.gitblit.wicket.pages.DashboardPage; import com.gitblit.wicket.pages.LogPage; import com.gitblit.wicket.pages.LogoutPage; import com.gitblit.wicket.pages.LuceneSearchPage; @@ -68,7 +69,7 @@ import com.gitblit.wicket.pages.UsersPage; public class GitBlitWebApp extends WebApplication { - public final static Class HOME_PAGE_CLASS = RepositoriesPage.class; + public final static Class HOME_PAGE_CLASS = DashboardPage.class; @Override public void init() { @@ -94,7 +95,7 @@ public class GitBlitWebApp extends WebApplication { } // setup the standard gitweb-ish urls -// mount("/repositories", RepositoriesPage.class); + mount("/repositories", RepositoriesPage.class); mount("/overview", OverviewPage.class, "r", "h"); mount("/summary", SummaryPage.class, "r"); mount("/pushes", PushesPage.class, "r", "h"); diff --git a/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties b/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties index 1b8583e6..036af264 100644 --- a/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties +++ b/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties @@ -452,7 +452,7 @@ gb.incrementalPushTagMessage = Auto-tagged [{0}] branch on push gb.externalPermissions = {0} access permissions are externally maintained gb.viewAccess = You do not have Gitblit read or write access gb.overview = overview -gb.home = home +gb.dashboard = dashboard gb.monthlyActivity = monthly activity gb.myProfile = my profile gb.compare = compare @@ -460,17 +460,28 @@ gb.manual = manual gb.from = from gb.to = to gb.at = at +gb.of = of +gb.in = in gb.morePushes = all pushes... gb.pushes = pushes gb.pushedNCommitsTo = pushed {0} commits to gb.pushedOneCommitTo = pushed 1 commit to +gb.commitsTo = {0} commits to +gb.oneCommitTo = 1 commit to +gb.byNAuthors = by {0} authors +gb.byOneAuthor = by {0} gb.viewComparison = view comparison of these {0} commits \u00bb gb.nMoreCommits = {0} more commits \u00bb gb.oneMoreCommit = 1 more commit \u00bb gb.pushedNewTag = pushed new tag +gb.createdNewTag = created new tag gb.deletedTag = deleted tag gb.pushedNewBranch = pushed new branch gb.deletedBranch = deleted branch gb.rewind = REWIND gb.star = star -gb.unstar = unstar \ No newline at end of file +gb.unstar = unstar +gb.stargazers = stargazers +gb.starredRepositories = starred repositories +gb.failedToUpdateUser = Failed to update user account! +gb.myRepositories = my repositories diff --git a/src/main/java/com/gitblit/wicket/charting/GoogleChart.java b/src/main/java/com/gitblit/wicket/charting/GoogleChart.java index b6309ffe..334b870d 100644 --- a/src/main/java/com/gitblit/wicket/charting/GoogleChart.java +++ b/src/main/java/com/gitblit/wicket/charting/GoogleChart.java @@ -38,6 +38,7 @@ public abstract class GoogleChart implements Serializable { final List values; int width; int height; + boolean showLegend; public GoogleChart(String tagId, String title, String keyName, String valueName) { this.tagId = tagId; @@ -46,6 +47,7 @@ public abstract class GoogleChart implements Serializable { this.keyName = keyName; this.valueName = valueName; values = new ArrayList(); + showLegend = true; } public void setWidth(int width) { @@ -55,6 +57,10 @@ public abstract class GoogleChart implements Serializable { public void setHeight(int height) { this.height = height; } + + public void setShowLegend(boolean val) { + this.showLegend = val; + } public void addValue(String name, int value) { values.add(new ChartValue(name, value)); diff --git a/src/main/java/com/gitblit/wicket/charting/GooglePieChart.java b/src/main/java/com/gitblit/wicket/charting/GooglePieChart.java index 119a8248..945e08b1 100644 --- a/src/main/java/com/gitblit/wicket/charting/GooglePieChart.java +++ b/src/main/java/com/gitblit/wicket/charting/GooglePieChart.java @@ -68,8 +68,8 @@ public class GooglePieChart extends GoogleChart { cName, tagId)); line(sb, MessageFormat - .format("{0}.draw({1}, '{'width: {2,number,0}, height: {3,number,0}, chartArea:'{'left:20,top:20'}', title: ''{4}'', {5} '}');", - cName, dName, width, height, title, colors.toString())); + .format("{0}.draw({1}, '{' title: ''{4}'', {5}, legend: '{' position:''{6}'' '}' '}');", + cName, dName, width, height, title, colors.toString(), showLegend ? "right" : "none")); line(sb, ""); } } \ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/ng/NgController.java b/src/main/java/com/gitblit/wicket/ng/NgController.java new file mode 100644 index 00000000..fb88cf35 --- /dev/null +++ b/src/main/java/com/gitblit/wicket/ng/NgController.java @@ -0,0 +1,79 @@ +/* + Copyright 2013 gitblit.com. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +package com.gitblit.wicket.ng; + +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Map; + +import org.apache.wicket.markup.html.IHeaderContributor; +import org.apache.wicket.markup.html.IHeaderResponse; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +/** + * Simple AngularJS data controller which injects scoped objects as static, + * embedded JSON within the generated page. This allows use of AngularJS + * client-side databinding (magic) with server-generated pages. + * + * @author James Moger + * + */ +public class NgController implements IHeaderContributor { + + private static final long serialVersionUID = 1L; + + final String name; + + final Map variables; + + public NgController(String name) { + this.name = name; + this.variables = new HashMap(); + } + + public void addVariable(String name, Object o) { + variables.put(name, o); + } + + @Override + public void renderHead(IHeaderResponse response) { + // add Google AngularJS reference + response.renderJavascriptReference("bootstrap/js/angular.js"); + + Gson gson = new GsonBuilder().create(); + + StringBuilder sb = new StringBuilder(); + line(sb, MessageFormat.format("", name)); + line(sb, MessageFormat.format("function {0}($scope) '{'", name)); + for (Map.Entry entry : variables.entrySet()) { + String var = entry.getKey(); + Object o = entry.getValue(); + String json = gson.toJson(o); + line(sb, MessageFormat.format("\t$scope.{0} = {1};", var, json)); + } + line(sb, "}"); + + response.renderJavascript(sb.toString(), null); + } + + private void line(StringBuilder sb, String line) { + sb.append(line); + sb.append('\n'); + } +} \ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/pages/ActivityPage.html b/src/main/java/com/gitblit/wicket/pages/ActivityPage.html index 14ae459f..f43b26fd 100644 --- a/src/main/java/com/gitblit/wicket/pages/ActivityPage.html +++ b/src/main/java/com/gitblit/wicket/pages/ActivityPage.html @@ -9,12 +9,12 @@

/ [days back]

-
+
- - - + + +
diff --git a/src/main/java/com/gitblit/wicket/pages/ActivityPage.java b/src/main/java/com/gitblit/wicket/pages/ActivityPage.java index bceac8f4..8e841c79 100644 --- a/src/main/java/com/gitblit/wicket/pages/ActivityPage.java +++ b/src/main/java/com/gitblit/wicket/pages/ActivityPage.java @@ -162,8 +162,6 @@ public class ActivityPage extends RootPage { } // build google charts - int w = 310; - int h = 150; GoogleCharts charts = new GoogleCharts(); // sort in reverse-chronological order and then reverse that @@ -178,8 +176,6 @@ public class ActivityPage extends RootPage { for (Activity metric : recentActivity) { chart.addValue(df.format(metric.startDate), metric.getCommitCount()); } - chart.setWidth(w); - chart.setHeight(h); charts.addChart(chart); // active repositories pie chart @@ -188,8 +184,7 @@ public class ActivityPage extends RootPage { for (Metric metric : repositoryMetrics.values()) { chart.addValue(metric.name, metric.count); } - chart.setWidth(w); - chart.setHeight(h); + chart.setShowLegend(false); charts.addChart(chart); // active authors pie chart @@ -198,8 +193,7 @@ public class ActivityPage extends RootPage { for (Metric metric : authorMetrics.values()) { chart.addValue(metric.name, metric.count); } - chart.setWidth(w); - chart.setHeight(h); + chart.setShowLegend(false); charts.addChart(chart); return charts; diff --git a/src/main/java/com/gitblit/wicket/pages/BasePage.html b/src/main/java/com/gitblit/wicket/pages/BasePage.html index a24f2362..0f96f343 100644 --- a/src/main/java/com/gitblit/wicket/pages/BasePage.html +++ b/src/main/java/com/gitblit/wicket/pages/BasePage.html @@ -2,7 +2,8 @@ + lang="en" + ng-app> diff --git a/src/main/java/com/gitblit/wicket/pages/DashboardPage.html b/src/main/java/com/gitblit/wicket/pages/DashboardPage.html new file mode 100644 index 00000000..d2516f0f --- /dev/null +++ b/src/main/java/com/gitblit/wicket/pages/DashboardPage.html @@ -0,0 +1,99 @@ + + + + + +
+
[repositories message]
+ +
+
+
+ + + + + +
+
+
+
+
+
[active]
+
[starred]
+
[owned]
+
+ +
+
+ + +
+
({{starred.length}}) +
+ more +
+
+ +
+
+ +
+ !  + {{item.p}}{{item.n}} + {{item.t}} + + {{item.s | number}} + +
+ +
+
+ + +
+
({{owned.length}}) +
+ +
+
+ +
+
+ +
+ !  + {{item.p}}{{item.n}} + {{item.t}} + + {{item.s | number}} + +
+
+
+ + +
+
({{active.length}}) +
+ +
+
+ +
+ !  + {{item.p}}{{item.n}} + {{item.t}} + + {{item.s | number}} + +
+
+
+ +
+ + \ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/pages/DashboardPage.java b/src/main/java/com/gitblit/wicket/pages/DashboardPage.java new file mode 100644 index 00000000..6a4c5658 --- /dev/null +++ b/src/main/java/com/gitblit/wicket/pages/DashboardPage.java @@ -0,0 +1,418 @@ +/* + * Copyright 2013 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.wicket.pages; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Serializable; +import java.text.DateFormat; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.wicket.Component; +import org.apache.wicket.PageParameters; +import org.apache.wicket.behavior.HeaderContributor; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.panel.Fragment; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.Repository; + +import com.gitblit.GitBlit; +import com.gitblit.Keys; +import com.gitblit.models.DailyLogEntry; +import com.gitblit.models.Metric; +import com.gitblit.models.PushLogEntry; +import com.gitblit.models.RepositoryCommit; +import com.gitblit.models.RepositoryModel; +import com.gitblit.models.UserModel; +import com.gitblit.utils.ArrayUtils; +import com.gitblit.utils.MarkdownUtils; +import com.gitblit.utils.PushLogUtils; +import com.gitblit.utils.StringUtils; +import com.gitblit.wicket.GitBlitWebApp; +import com.gitblit.wicket.GitBlitWebSession; +import com.gitblit.wicket.PageRegistration; +import com.gitblit.wicket.PageRegistration.DropDownMenuItem; +import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration; +import com.gitblit.wicket.WicketUtils; +import com.gitblit.wicket.charting.GoogleChart; +import com.gitblit.wicket.charting.GoogleCharts; +import com.gitblit.wicket.charting.GooglePieChart; +import com.gitblit.wicket.ng.NgController; +import com.gitblit.wicket.panels.LinkPanel; +import com.gitblit.wicket.panels.PushesPanel; + +public class DashboardPage extends RootPage { + + public DashboardPage() { + super(); + setup(null); + } + + public DashboardPage(PageParameters params) { + super(params); + setup(params); + } + + @Override + protected boolean reusePageParameters() { + return true; + } + + private void setup(PageParameters params) { + setupPage("", ""); + // check to see if we should display a login message + boolean authenticateView = GitBlit.getBoolean(Keys.web.authenticateViewPages, true); + if (authenticateView && !GitBlitWebSession.get().isLoggedIn()) { + String messageSource = GitBlit.getString(Keys.web.loginMessage, "gitblit"); + String message = readMarkdown(messageSource, "login.mkd"); + Component repositoriesMessage = new Label("repositoriesMessage", message); + add(repositoriesMessage.setEscapeModelStrings(false)); + add(new Label("repositoriesPanel")); + return; + } + + // Load the markdown welcome message + String messageSource = GitBlit.getString(Keys.web.repositoriesMessage, "gitblit"); + String message = readMarkdown(messageSource, "welcome.mkd"); + Component repositoriesMessage = new Label("repositoriesMessage", message) + .setEscapeModelStrings(false).setVisible(message.length() > 0); + add(repositoriesMessage); + + UserModel user = GitBlitWebSession.get().getUser(); + + Comparator lastUpdateSort = new Comparator() { + @Override + public int compare(RepositoryModel o1, RepositoryModel o2) { + return o2.lastChange.compareTo(o1.lastChange); + } + }; + + Map reposMap = new HashMap(); + + // owned repositories + List owned = new ArrayList(); + if (user != null && !UserModel.ANONYMOUS.equals(user)) { + for (RepositoryModel model : GitBlit.self().getRepositoryModels(user)) { + reposMap.put(model.name, model); + if (model.isUsersPersonalRepository(user.username) || model.isOwner(user.username)) { + owned.add(model); + } + } + } + Collections.sort(owned, lastUpdateSort); + + // starred repositories + List starred = new ArrayList(); + if (user != null && !UserModel.ANONYMOUS.equals(user)) { + for (String name : user.getPreferences().getStarredRepositories()) { + if (!reposMap.containsKey(name)) { + RepositoryModel repo = GitBlit.self().getRepositoryModel(name); + reposMap.put(name, repo); + } + starred.add(reposMap.get(name)); + } + } + Collections.sort(starred, lastUpdateSort); + + // parameters + int daysBack = params == null ? 0 : WicketUtils.getDaysBack(params); + if (daysBack < 1) { + daysBack = 14; + } + Calendar c = Calendar.getInstance(); + c.add(Calendar.DATE, -1*daysBack); + Date minimumDate = c.getTime(); + + // active repositories (displayed for anonymous users) + List active = new ArrayList(); + if (user == null || UserModel.ANONYMOUS.equals(user)) { + List list = GitBlit.self().getRepositoryModels(UserModel.ANONYMOUS); + for (RepositoryModel model : list) { + if (model.lastChange.after(minimumDate)) { + active.add(model); + reposMap.put(model.name, model); + } + } + Collections.sort(active, lastUpdateSort); + } + + // show pushlog feed + List pushes = new ArrayList(); + for (RepositoryModel model : reposMap.values()) { + Repository repository = GitBlit.self().getRepository(model.name); + List entries = PushLogUtils.getDailyLogByRef(model.name, repository, minimumDate); + pushes.addAll(entries); + repository.close(); + } + + if (pushes.size() == 0) { + if (reposMap.size() == 0) { + add(new LinkPanel("pushes", null, "find some repositories", RepositoriesPage.class)); + } else { + add(new Label("pushes", "all is quiet")); + } + } else { + Collections.sort(pushes); + add(new PushesPanel("pushes", pushes)); + } + + // add the nifty charts + if (!ArrayUtils.isEmpty(pushes)) { + GoogleCharts charts = createCharts(pushes); + add(new HeaderContributor(charts)); + } + + // active repository list + if (ArrayUtils.isEmpty(active)) { + add(new Label("active").setVisible(false)); + } else { + Fragment activeView = createNgList("active", "activeListFragment", "activeCtrl", active); + add(activeView); + } + + // starred repository list + if (ArrayUtils.isEmpty(starred)) { + add(new Label("starred").setVisible(false)); + } else { + Fragment starredView = createNgList("starred", "starredListFragment", "starredCtrl", starred); + add(starredView); + } + + // owned repository list + if (ArrayUtils.isEmpty(owned)) { + add(new Label("owned").setVisible(false)); + } else { + Fragment ownedView = createNgList("owned", "ownedListFragment", "ownedCtrl", owned); + if (user.canCreate) { + // create button + ownedView.add(new LinkPanel("create", "btn btn-mini", getString("gb.newRepository"), EditRepositoryPage.class)); + } else { + // no button + ownedView.add(new Label("create").setVisible(false)); + } + add(ownedView); + } + } + + protected Fragment createNgList(String wicketId, String fragmentId, String ngController, List repositories) { + String format = GitBlit.getString(Keys.web.datestampShortFormat, "MM/dd/yy"); + final DateFormat df = new SimpleDateFormat(format); + df.setTimeZone(getTimeZone()); + + Fragment fragment = new Fragment(wicketId, fragmentId, this); + + List list = new ArrayList(); + for (RepositoryModel repo : repositories) { + String name = StringUtils.stripDotGit(repo.name); + String path = ""; + if (name.indexOf('/') > -1) { + path = name.substring(0, name.lastIndexOf('/') + 1); + name = name.substring(name.lastIndexOf('/') + 1); + } + + RepoListItem item = new RepoListItem(); + item.n = name; + item.p = path; + item.r = repo.name; + item.s = GitBlit.self().getStarCount(repo); + item.t = getTimeUtils().timeAgo(repo.lastChange); + item.d = df.format(repo.lastChange); + item.c = StringUtils.getColor(StringUtils.stripDotGit(repo.name)); + item.wc = repo.isBare ? 0 : 1; + list.add(item); + } + + // inject an AngularJS controller with static data + NgController ctrl = new NgController(ngController); + ctrl.addVariable(wicketId, list); + add(new HeaderContributor(ctrl)); + + return fragment; + } + + @Override + protected void addDropDownMenus(List pages) { + PageParameters params = getPageParameters(); + + DropDownMenuRegistration menu = new DropDownMenuRegistration("gb.filters", + GitBlitWebApp.HOME_PAGE_CLASS); + // preserve time filter option on repository choices + menu.menuItems.addAll(getRepositoryFilterItems(params)); + + // preserve repository filter option on time choices + menu.menuItems.addAll(getTimeFilterItems(params)); + + if (menu.menuItems.size() > 0) { + // Reset Filter + menu.menuItems.add(new DropDownMenuItem(getString("gb.reset"), null, null)); + } + + pages.add(menu); + } + + private String readMarkdown(String messageSource, String resource) { + String message = ""; + if (messageSource.equalsIgnoreCase("gitblit")) { + // Read default message + message = readDefaultMarkdown(resource); + } else { + // Read user-supplied message + if (!StringUtils.isEmpty(messageSource)) { + File file = GitBlit.getFileOrFolder(messageSource); + if (file.exists()) { + try { + FileInputStream fis = new FileInputStream(file); + InputStreamReader reader = new InputStreamReader(fis, + Constants.CHARACTER_ENCODING); + message = MarkdownUtils.transformMarkdown(reader); + reader.close(); + } catch (Throwable t) { + message = getString("gb.failedToRead") + " " + file; + warn(message, t); + } + } else { + message = messageSource + " " + getString("gb.isNotValidFile"); + } + } + } + return message; + } + + private String readDefaultMarkdown(String file) { + String base = file.substring(0, file.lastIndexOf('.')); + String ext = file.substring(file.lastIndexOf('.')); + String lc = getLanguageCode(); + String cc = getCountryCode(); + + // try to read file_en-us.ext, file_en.ext, file.ext + List files = new ArrayList(); + if (!StringUtils.isEmpty(lc)) { + if (!StringUtils.isEmpty(cc)) { + files.add(base + "_" + lc + "-" + cc + ext); + files.add(base + "_" + lc + "_" + cc + ext); + } + files.add(base + "_" + lc + ext); + } + files.add(file); + + for (String name : files) { + String message; + InputStreamReader reader = null; + try { + InputStream is = getClass().getResourceAsStream("/" + name); + if (is == null) { + continue; + } + reader = new InputStreamReader(is, Constants.CHARACTER_ENCODING); + message = MarkdownUtils.transformMarkdown(reader); + reader.close(); + return message; + } catch (Throwable t) { + message = MessageFormat.format(getString("gb.failedToReadMessage"), file); + error(message, t, false); + return message; + } finally { + if (reader != null) { + try { + reader.close(); + } catch (Exception e) { + } + } + } + } + return MessageFormat.format(getString("gb.failedToReadMessage"), file); + } + + /** + * Creates the daily activity line chart, the active repositories pie chart, + * and the active authors pie chart + * + * @param recentPushes + * @return + */ + private GoogleCharts createCharts(List recentPushes) { + // activity metrics + Map repositoryMetrics = new HashMap(); + Map authorMetrics = new HashMap(); + + // aggregate repository and author metrics + for (PushLogEntry push : recentPushes) { + + // aggregate repository metrics + String repository = StringUtils.stripDotGit(push.repository); + if (!repositoryMetrics.containsKey(repository)) { + repositoryMetrics.put(repository, new Metric(repository)); + } + repositoryMetrics.get(repository).count += 1; + + for (RepositoryCommit commit : push.getCommits()) { + String author = commit.getAuthorIdent().getName(); + if (!authorMetrics.containsKey(author)) { + authorMetrics.put(author, new Metric(author)); + } + authorMetrics.get(author).count += 1; + } + } + + // build google charts + GoogleCharts charts = new GoogleCharts(); + + // active repositories pie chart + GoogleChart chart = new GooglePieChart("chartRepositories", getString("gb.activeRepositories"), + getString("gb.repository"), getString("gb.commits")); + for (Metric metric : repositoryMetrics.values()) { + chart.addValue(metric.name, metric.count); + } + chart.setShowLegend(false); + charts.addChart(chart); + + // active authors pie chart + chart = new GooglePieChart("chartAuthors", getString("gb.activeAuthors"), + getString("gb.author"), getString("gb.commits")); + for (Metric metric : authorMetrics.values()) { + chart.addValue(metric.name, metric.count); + } + chart.setShowLegend(false); + charts.addChart(chart); + + return charts; + } + + class RepoListItem implements Serializable { + + private static final long serialVersionUID = 1L; + + String r; // repository + String n; // name + String p; // project/path + String t; // time ago + String d; // last updated + long s; // stars + String c; // html color + int wc; // working copy, 1 = true + } +} diff --git a/src/main/java/com/gitblit/wicket/pages/HomePage.html b/src/main/java/com/gitblit/wicket/pages/HomePage.html deleted file mode 100644 index 3730d786..00000000 --- a/src/main/java/com/gitblit/wicket/pages/HomePage.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - -
-
[repositories message]
- - -
-
- - \ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/pages/HomePage.java b/src/main/java/com/gitblit/wicket/pages/HomePage.java deleted file mode 100644 index 9dfd1ae4..00000000 --- a/src/main/java/com/gitblit/wicket/pages/HomePage.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2011 gitblit.com. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.gitblit.wicket.pages; - -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.List; - -import org.apache.wicket.Component; -import org.apache.wicket.PageParameters; -import org.apache.wicket.markup.html.basic.Label; -import org.eclipse.jgit.lib.Constants; - -import com.gitblit.GitBlit; -import com.gitblit.Keys; -import com.gitblit.utils.MarkdownUtils; -import com.gitblit.utils.StringUtils; -import com.gitblit.wicket.GitBlitWebApp; -import com.gitblit.wicket.GitBlitWebSession; -import com.gitblit.wicket.PageRegistration; -import com.gitblit.wicket.PageRegistration.DropDownMenuItem; -import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration; - -public class HomePage extends RootPage { - - public HomePage() { - super(); - setup(null); - } - - public HomePage(PageParameters params) { - super(params); - setup(params); - } - - @Override - protected boolean reusePageParameters() { - return true; - } - - private void setup(PageParameters params) { - setupPage("", ""); - // check to see if we should display a login message - boolean authenticateView = GitBlit.getBoolean(Keys.web.authenticateViewPages, true); - if (authenticateView && !GitBlitWebSession.get().isLoggedIn()) { - String messageSource = GitBlit.getString(Keys.web.loginMessage, "gitblit"); - String message = readMarkdown(messageSource, "login.mkd"); - Component repositoriesMessage = new Label("repositoriesMessage", message); - add(repositoriesMessage.setEscapeModelStrings(false)); - add(new Label("repositoriesPanel")); - return; - } - - // Load the markdown welcome message - String messageSource = GitBlit.getString(Keys.web.repositoriesMessage, "gitblit"); - String message = readMarkdown(messageSource, "welcome.mkd"); - Component repositoriesMessage = new Label("repositoriesMessage", message) - .setEscapeModelStrings(false).setVisible(message.length() > 0); - add(repositoriesMessage); - -// List repositories = getRepositories(params); -// -// RepositoriesPanel repositoriesPanel = new RepositoriesPanel("repositoriesPanel", showAdmin, -// true, repositories, true, getAccessRestrictions()); -// // push the panel down if we are hiding the admin controls and the -// // welcome message -// if (!showAdmin && !repositoriesMessage.isVisible()) { -// WicketUtils.setCssStyle(repositoriesPanel, "padding-top:5px;"); -// } -// add(repositoriesPanel); - } - - @Override - protected void addDropDownMenus(List pages) { - PageParameters params = getPageParameters(); - - DropDownMenuRegistration menu = new DropDownMenuRegistration("gb.filters", - GitBlitWebApp.HOME_PAGE_CLASS); - // preserve time filter option on repository choices - menu.menuItems.addAll(getRepositoryFilterItems(params)); - - // preserve repository filter option on time choices - menu.menuItems.addAll(getTimeFilterItems(params)); - - if (menu.menuItems.size() > 0) { - // Reset Filter - menu.menuItems.add(new DropDownMenuItem(getString("gb.reset"), null, null)); - } - - pages.add(menu); - } - - private String readMarkdown(String messageSource, String resource) { - String message = ""; - if (messageSource.equalsIgnoreCase("gitblit")) { - // Read default message - message = readDefaultMarkdown(resource); - } else { - // Read user-supplied message - if (!StringUtils.isEmpty(messageSource)) { - File file = GitBlit.getFileOrFolder(messageSource); - if (file.exists()) { - try { - FileInputStream fis = new FileInputStream(file); - InputStreamReader reader = new InputStreamReader(fis, - Constants.CHARACTER_ENCODING); - message = MarkdownUtils.transformMarkdown(reader); - reader.close(); - } catch (Throwable t) { - message = getString("gb.failedToRead") + " " + file; - warn(message, t); - } - } else { - message = messageSource + " " + getString("gb.isNotValidFile"); - } - } - } - return message; - } - - private String readDefaultMarkdown(String file) { - String base = file.substring(0, file.lastIndexOf('.')); - String ext = file.substring(file.lastIndexOf('.')); - String lc = getLanguageCode(); - String cc = getCountryCode(); - - // try to read file_en-us.ext, file_en.ext, file.ext - List files = new ArrayList(); - if (!StringUtils.isEmpty(lc)) { - if (!StringUtils.isEmpty(cc)) { - files.add(base + "_" + lc + "-" + cc + ext); - files.add(base + "_" + lc + "_" + cc + ext); - } - files.add(base + "_" + lc + ext); - } - files.add(file); - - for (String name : files) { - String message; - InputStreamReader reader = null; - try { - InputStream is = getClass().getResourceAsStream("/" + name); - if (is == null) { - continue; - } - reader = new InputStreamReader(is, Constants.CHARACTER_ENCODING); - message = MarkdownUtils.transformMarkdown(reader); - reader.close(); - return message; - } catch (Throwable t) { - message = MessageFormat.format(getString("gb.failedToReadMessage"), file); - error(message, t, false); - return message; - } finally { - if (reader != null) { - try { - reader.close(); - } catch (Exception e) { - } - } - } - } - return MessageFormat.format(getString("gb.failedToReadMessage"), file); - } -} diff --git a/src/main/java/com/gitblit/wicket/pages/OverviewPage.java b/src/main/java/com/gitblit/wicket/pages/OverviewPage.java index aea07bfe..6fd38915 100644 --- a/src/main/java/com/gitblit/wicket/pages/OverviewPage.java +++ b/src/main/java/com/gitblit/wicket/pages/OverviewPage.java @@ -110,7 +110,7 @@ public class OverviewPage extends RepositoryPage { add(new RepositoryUrlPanel("repositoryUrlPanel", false, user, model)); int pushCount = GitBlit.getInteger(Keys.web.overviewPushCount, 5); - PushesPanel pushes = new PushesPanel("pushesPanel", getRepositoryModel(), r, pushCount, 0); + PushesPanel pushes = new PushesPanel("pushesPanel", getRepositoryModel(), r, pushCount, 0, false); add(pushes); add(new TagsPanel("tagsPanel", repositoryName, r, numberRefs).hideIfEmpty()); add(new BranchesPanel("branchesPanel", getRepositoryModel(), r, numberRefs, false).hideIfEmpty()); diff --git a/src/main/java/com/gitblit/wicket/pages/PushesPage.java b/src/main/java/com/gitblit/wicket/pages/PushesPage.java index a0e7c973..866964ac 100644 --- a/src/main/java/com/gitblit/wicket/pages/PushesPage.java +++ b/src/main/java/com/gitblit/wicket/pages/PushesPage.java @@ -33,7 +33,7 @@ public class PushesPage extends RepositoryPage { int nextPage = pageNumber + 1; PushesPanel pushesPanel = new PushesPanel("pushesPanel", getRepositoryModel(), getRepository(), -1, - pageNumber - 1); + pageNumber - 1, false); boolean hasMore = pushesPanel.hasMore(); add(pushesPanel); diff --git a/src/main/java/com/gitblit/wicket/pages/RootPage.java b/src/main/java/com/gitblit/wicket/pages/RootPage.java index 30251516..bbe20f5b 100644 --- a/src/main/java/com/gitblit/wicket/pages/RootPage.java +++ b/src/main/java/com/gitblit/wicket/pages/RootPage.java @@ -118,8 +118,8 @@ public abstract class RootPage extends BasePage { // navigation links List pages = new ArrayList(); if (!authenticateView || (authenticateView && GitBlitWebSession.get().isLoggedIn())) { -// pages.add(new PageRegistration("gb.home", HomePage.class, -// getRootPageParameters())); + pages.add(new PageRegistration("gb.dashboard", DashboardPage.class, + getRootPageParameters())); pages.add(new PageRegistration("gb.repositories", RepositoriesPage.class, getRootPageParameters())); pages.add(new PageRegistration("gb.activity", ActivityPage.class, getRootPageParameters())); diff --git a/src/main/java/com/gitblit/wicket/panels/ActivityPanel.html b/src/main/java/com/gitblit/wicket/panels/ActivityPanel.html index b818e94a..9dff0a7c 100644 --- a/src/main/java/com/gitblit/wicket/panels/ActivityPanel.html +++ b/src/main/java/com/gitblit/wicket/panels/ActivityPanel.html @@ -13,7 +13,7 @@ [time of day] - [repository link] + [repository link] diff --git a/src/main/java/com/gitblit/wicket/panels/PushesPanel.html b/src/main/java/com/gitblit/wicket/panels/PushesPanel.html index cad59323..9fb5aed0 100644 --- a/src/main/java/com/gitblit/wicket/panels/PushesPanel.html +++ b/src/main/java/com/gitblit/wicket/panels/PushesPanel.html @@ -6,21 +6,21 @@ -
+
- +
[rewind]
-
[pusher]
+
[pusher]
- + - + diff --git a/src/main/java/com/gitblit/wicket/panels/PushesPanel.java b/src/main/java/com/gitblit/wicket/panels/PushesPanel.java index 29161ba8..423c44b4 100644 --- a/src/main/java/com/gitblit/wicket/panels/PushesPanel.java +++ b/src/main/java/com/gitblit/wicket/panels/PushesPanel.java @@ -29,6 +29,7 @@ import org.eclipse.jgit.lib.Repository; import com.gitblit.Constants; import com.gitblit.GitBlit; import com.gitblit.Keys; +import com.gitblit.models.DailyLogEntry; import com.gitblit.models.PushLogEntry; import com.gitblit.models.RepositoryCommit; import com.gitblit.models.RepositoryModel; @@ -51,7 +52,7 @@ public class PushesPanel extends BasePanel { private boolean hasMore; - public PushesPanel(String wicketId, final RepositoryModel model, Repository r, int limit, int pageOffset) { + public PushesPanel(String wicketId, final RepositoryModel model, Repository r, int limit, int pageOffset, boolean showRepo) { super(wicketId); boolean pageResults = limit <= 0; int pushesPerPage = GitBlit.getInteger(Keys.web.pushesPerPage, 10); @@ -71,7 +72,7 @@ public class PushesPanel extends BasePanel { hasMore = pushes.size() >= pushesPerPage; hasPushes = pushes.size() > 0; - setup(pushes); + setup(pushes, showRepo); // determine to show pager, more, or neither if (limit <= 0) { @@ -99,11 +100,11 @@ public class PushesPanel extends BasePanel { public PushesPanel(String wicketId, List pushes) { super(wicketId); hasPushes = pushes.size() > 0; - setup(pushes); + setup(pushes, true); add(new Label("morePushes").setVisible(false)); } - protected void setup(List pushes) { + protected void setup(List pushes, final boolean showRepo) { final int hashLen = GitBlit.getInteger(Keys.web.shortCommitIdLength, 6); ListDataProvider dp = new ListDataProvider(pushes); @@ -121,36 +122,58 @@ public class PushesPanel extends BasePanel { shortRefName = shortRefName.substring(org.eclipse.jgit.lib.Constants.R_TAGS.length()); isTag = true; } + boolean isDigest = push instanceof DailyLogEntry; pushItem.add(WicketUtils.createDateLabel("whenPushed", push.date, getTimeZone(), getTimeUtils())); Label pushIcon = new Label("pushIcon"); + if (showRepo) { + // if we are showing the repo, we are showing multiple + // repos. use the repository hash color to differentiate + // the icon. + String color = StringUtils.getColor(StringUtils.stripDotGit(push.repository)); + WicketUtils.setCssStyle(pushIcon, "color: " + color); + } if (isTag) { WicketUtils.setCssClass(pushIcon, "iconic-tag"); - } else { + } else if (isDigest) { WicketUtils.setCssClass(pushIcon, "iconic-loop"); - } - pushItem.add(pushIcon); - if (push.user.username.equals(push.user.emailAddress) && push.user.emailAddress.indexOf('@') > -1) { - // username is an email address - 1.2.1 push log bug - pushItem.add(new Label("whoPushed", push.user.getDisplayName())); } else { - // link to user acount page - pushItem.add(new LinkPanel("whoPushed", null, push.user.getDisplayName(), - UserPage.class, WicketUtils.newUsernameParameter(push.user.username))); + WicketUtils.setCssClass(pushIcon, "iconic-upload"); } + pushItem.add(pushIcon); + + if (isDigest && !isTag) { + pushItem.add(new Label("whoPushed").setVisible(false)); + } else { + if (push.user.username.equals(push.user.emailAddress) && push.user.emailAddress.indexOf('@') > -1) { + // username is an email address - 1.2.1 push log bug + pushItem.add(new Label("whoPushed", push.user.getDisplayName())); + } else { + // link to user account page + pushItem.add(new LinkPanel("whoPushed", null, push.user.getDisplayName(), + UserPage.class, WicketUtils.newUsernameParameter(push.user.username))); + } + } - String preposition = "gb.at"; + String preposition = "gb.of"; boolean isDelete = false; boolean isRewind = false; String what; + String by = null; switch(push.getChangeType(fullRefName)) { case CREATE: if (isTag) { - what = getString("gb.pushedNewTag"); + if (isDigest) { + what = getString("gb.createdNewTag"); + preposition = "gb.in"; + } else { + what = getString("gb.pushedNewTag"); + preposition = "gb.to"; + } } else { what = getString("gb.pushedNewBranch"); + preposition = "gb.to"; } - preposition = "gb.to"; break; case DELETE: isDelete = true; @@ -164,10 +187,21 @@ public class PushesPanel extends BasePanel { case UPDATE_NONFASTFORWARD: isRewind = true; default: - what = MessageFormat.format(push.getCommitCount() > 1 ? getString("gb.pushedNCommitsTo") : getString("gb.pushedOneCommitTo") , push.getCommitCount()); + if (isDigest) { + what = MessageFormat.format(push.getCommitCount() > 1 ? getString("gb.commitsTo") : getString("gb.oneCommitTo"), push.getCommitCount()); + } else { + what = MessageFormat.format(push.getCommitCount() > 1 ? getString("gb.pushedNCommitsTo") : getString("gb.pushedOneCommitTo") , push.getCommitCount()); + } + + if (push.getAuthorCount() == 1) { + by = MessageFormat.format(getString("gb.byOneAuthor"), push.getAuthorIdent().getName()); + } else { + by = MessageFormat.format(getString("gb.byNAuthors"), push.getAuthorCount()); + } break; } pushItem.add(new Label("whatPushed", what)); + pushItem.add(new Label("byAuthors", by).setVisible(!StringUtils.isEmpty(by))); pushItem.add(new Label("refRewind", getString("gb.rewind")).setVisible(isRewind)); @@ -184,13 +218,20 @@ public class PushesPanel extends BasePanel { TreePage.class, WicketUtils.newObjectParameter(push.repository, fullRefName))); } - // to/from/etc - pushItem.add(new Label("repoPreposition", getString(preposition))); - - String repoName = StringUtils.stripDotGit(push.repository); - pushItem.add(new LinkPanel("repoPushed", null, repoName, - SummaryPage.class, WicketUtils.newRepositoryParameter(push.repository))); + if (showRepo) { + // to/from/etc + pushItem.add(new Label("repoPreposition", getString(preposition))); + String repoName = StringUtils.stripDotGit(push.repository); + pushItem.add(new LinkPanel("repoPushed", null, repoName, + SummaryPage.class, WicketUtils.newRepositoryParameter(push.repository))); + } else { + // do not display repository name if we are viewing the push + // log of a repository. + pushItem.add(new Label("repoPreposition").setVisible(false)); + pushItem.add(new Label("repoPushed").setVisible(false)); + } + int maxCommitCount = 5; List commits = push.getCommits(); if (commits.size() > maxCommitCount) { @@ -213,6 +254,8 @@ public class PushesPanel extends BasePanel { pushItem.add(new LinkPanel("compareLink", null, compareLinkText, ComparePage.class, WicketUtils.newRangeParameter(push.repository, startRangeId, endRangeId))); } + final boolean showSwatch = showRepo && GitBlit.getBoolean(Keys.web.repositoryListSwatches, true); + ListDataProvider cdp = new ListDataProvider(commits); DataView commitsView = new DataView("commit", cdp) { private static final long serialVersionUID = 1L; @@ -254,15 +297,20 @@ public class PushesPanel extends BasePanel { WicketUtils.setCssClass(commitHash, "shortsha1"); WicketUtils.setHtmlTooltip(commitHash, commit.getName()); commitItem.add(commitHash); + + if (showSwatch) { + // set repository color + String color = StringUtils.getColor(StringUtils.stripDotGit(push.repository)); + WicketUtils.setCssStyle(commitItem, MessageFormat.format("border-left: 2px solid {0};", color)); + } } }; - + pushItem.add(commitsView); } }; + add(pushView); - - } public boolean hasMore() { -- cgit v1.2.3
[hash link] [commit short message]