diff options
Diffstat (limited to 'src/main/java')
21 files changed, 939 insertions, 278 deletions
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<PushLogEntry> { private final Map<String, ReceiveCommand.Type> refUpdates;
private final Map<String, String> refIdChanges;
+
+ private int authorCount;
/**
* Constructor for specified duration of push from start date.
@@ -72,6 +74,7 @@ public class PushLogEntry implements Serializable, Comparable<PushLogEntry> { this.commits = new LinkedHashSet<RepositoryCommit>();
this.refUpdates = new HashMap<String, ReceiveCommand.Type>();
this.refIdChanges = new HashMap<String, String>();
+ this.authorCount = -1;
}
/**
@@ -152,6 +155,7 @@ public class PushLogEntry implements Serializable, Comparable<PushLogEntry> { 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<PushLogEntry> { */
public void addCommits(List<RepositoryCommit> list) {
commits.addAll(list);
+ authorCount = -1;
}
/**
@@ -254,6 +259,18 @@ public class PushLogEntry implements Serializable, Comparable<PushLogEntry> { return list;
}
+ public int getAuthorCount() {
+ if (authorCount == -1) {
+ Set<String> authors = new HashSet<String>();
+ 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<PathChangeModel> 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<String, List<PushLogEntry>> refMap = new HashMap<String, List<PushLogEntry>>(); - for (PushLogEntry push : getPushLog(repositoryName, repository, offset, maxCount)) { + List<PushLogEntry> pushes = getPushLog(repositoryName, repository, offset, maxCount); + for (PushLogEntry push : pushes) { for (String ref : push.getChangedRefs()) { if (!refMap.containsKey(ref)) { refMap.put(ref, new ArrayList<PushLogEntry>()); } // 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<PushLogEntry> getPushLogByRef(String repositoryName, Repository repository, Date minimumDate) { // break the push log into ref push logs and then merge them back into a list Map<String, List<PushLogEntry>> refMap = new HashMap<String, List<PushLogEntry>>(); - for (PushLogEntry push : getPushLog(repositoryName, repository, minimumDate)) { + List<PushLogEntry> pushes = getPushLog(repositoryName, repository, minimumDate); + for (PushLogEntry push : pushes) { for (String ref : push.getChangedRefs()) { if (!refMap.containsKey(ref)) { refMap.put(ref, new ArrayList<PushLogEntry>()); } - - // 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<DailyLogEntry> getDailyLog(String repositoryName, Repository repository, + Date minimumDate, int offset, int maxCount) { + + DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); +// df.setTimeZone(timezone); + + Map<ObjectId, List<RefModel>> allRefs = JGitUtils.getAllRefs(repository); + Map<String, DailyLogEntry> tags = new HashMap<String, DailyLogEntry>(); + Map<String, DailyLogEntry> dailydigests = new HashMap<String, DailyLogEntry>(); + for (RefModel local : JGitUtils.getLocalBranches(repository, true, -1)) { + String branch = local.getName(); + List<RevCommit> 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<DailyLogEntry> list = new ArrayList<DailyLogEntry>(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<DailyLogEntry> getDailyLogByRef(String repositoryName, Repository repository, Date minimumDate) { + // break the push log into ref push logs and then merge them back into a list + Map<String, List<DailyLogEntry>> refMap = new HashMap<String, List<DailyLogEntry>>(); + List<DailyLogEntry> 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<DailyLogEntry>()); + } + + // 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<DailyLogEntry> refPushLog = new ArrayList<DailyLogEntry>(); + for (List<DailyLogEntry> 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<? extends BasePage> HOME_PAGE_CLASS = RepositoriesPage.class;
+ public final static Class<? extends BasePage> 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<ChartValue> 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<ChartValue>();
+ 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<String, Object> variables;
+
+ public NgController(String name) {
+ this.name = name;
+ this.variables = new HashMap<String, Object>();
+ }
+
+ 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("<!-- AngularJS {0} data controller -->", name));
+ line(sb, MessageFormat.format("function {0}($scope) '{'", name));
+ for (Map.Entry<String, Object> 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 @@ <div class="pageTitle">
<h2><wicket:message key="gb.recentActivity"></wicket:message><small> <span class="hidden-phone">/ <span wicket:id="subheader">[days back]</span></span></small></h2>
</div>
- <div class="hidden-phone" style="height: 155px;text-align: center;">
+ <div class="hidden-phone" style="text-align: center;">
<table>
<tr>
- <td><span class="hidden-tablet" id="chartDaily"></span></td>
- <td><span id="chartRepositories"></span></td>
- <td><span id="chartAuthors"></span></td>
+ <td><div style="width:310px; height:150px" class="hidden-tablet" id="chartDaily"></div></td>
+ <td><div style="width:310px; height:175px" id="chartRepositories"></div></td>
+ <td><div style="width:310px; height:175px" id="chartAuthors"></div></td>
</tr>
</table>
</div>
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 @@ <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd"
xml:lang="en"
- lang="en">
+ lang="en"
+ ng-app>
<!-- Head -->
<wicket:head>
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 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd"
+ xml:lang="en"
+ lang="en">
+
+<body>
+<wicket:extend>
+<div class="container">
+ <div class="markdown" style="padding-bottom:5px;" wicket:id="repositoriesMessage">[repositories message]</div>
+
+ <div class="row">
+ <div class="span7">
+ <div class="hidden-phone hidden-tablet" style="text-align:center;">
+ <table>
+ <tr>
+ <td><div id="chartRepositories" style="display:inline-block;width: 175px; height:175px"></div></td>
+ <td><div id="chartAuthors" style="display:inline-block;width: 175px; height: 175px;"></div></td>
+ </tr>
+ </table>
+ </div>
+ <div wicket:id="pushes"></div>
+ </div>
+ <div class="span5">
+ <div wicket:id="active">[active]</div>
+ <div wicket:id="starred">[starred]</div>
+ <div wicket:id="owned">[owned]</div>
+ </div>
+
+ </div>
+</div>
+
+<wicket:fragment wicket:id="starredListFragment">
+ <div ng-controller="starredCtrl" style="border: 1px solid #ddd;border-radius: 4px;margin-bottom: 20px;">
+ <div class="header" style="padding: 5px;border: none;"><i class="icon-star"></i> <wicket:message key="gb.starredRepositories"></wicket:message> ({{starred.length}})
+ <div class="pull-right">
+ <a class="btn btn-mini">more</a>
+ </div>
+ <div style="padding: 5px 0px 0px;">
+ <input type="text" ng-model="query.r" class="input-large" wicket:message="placeholder:gb.filter" style="border-radius: 14px; padding: 3px 14px;margin: 0px;"></input>
+ </div>
+ </div>
+
+ <div ng-repeat="item in starred | limitTo: 20 | filter:query" style="padding: 3px;border-top: 1px solid #ddd;">
+ <b><span class="repositorySwatch" style="background-color:{{item.c}};"><span ng-show="item.wc">!</span><span ng-show="!item.wc"> </span></span></b>
+ <a href="summary/?r={{item.r}}">{{item.p}}<b>{{item.n}}</b></a>
+ <span class="link hidden-tablet hidden-phone" style="color: #bbb;" title="{{item.d}}">{{item.t}}</span>
+ <span ng-show="item.s" class="pull-right">
+ <span style="padding: 0px 5px;color: #888;font-weight:bold;vertical-align:middle;">{{item.s | number}} <i class="iconic-star"></i></span>
+ </span>
+ </div>
+
+ </div>
+</wicket:fragment>
+
+<wicket:fragment wicket:id="ownedListFragment">
+ <div ng-controller="ownedCtrl" style="border: 1px solid #ddd;border-radius: 4px;">
+ <div class="header" style="padding: 5px;border: none;"><i class="icon-user"></i> <wicket:message key="gb.myRepositories"></wicket:message> ({{owned.length}})
+ <div class="pull-right">
+ <span wicket:id="create"></span>
+ </div>
+ <div style="padding: 5px 0px 0px;">
+ <input type="text" ng-model="query.r" class="input-large" wicket:message="placeholder:gb.filter" style="border-radius: 14px; padding: 3px 14px;margin: 0px;"></input>
+ </div>
+ </div>
+
+ <div ng-repeat="item in owned | filter:query" style="padding: 3px;border-top: 1px solid #ddd;">
+ <b><span class="repositorySwatch" style="background-color:{{item.c}};"><span ng-show="item.wc">!</span><span ng-show="!item.wc"> </span></span></b>
+ <a href="summary/?r={{item.r}}">{{item.p}}<b>{{item.n}}</b></a>
+ <span class="link hidden-tablet hidden-phone" style="color: #bbb;" title="{{item.d}}">{{item.t}}</span>
+ <span ng-show="item.s" class="pull-right">
+ <span style="padding: 0px 5px;color: #888;font-weight:bold;vertical-align:middle;">{{item.s | number}} <i class="iconic-star"></i></span>
+ </span>
+ </div>
+ </div>
+</wicket:fragment>
+
+<wicket:fragment wicket:id="activeListFragment">
+ <div ng-controller="activeCtrl" style="border: 1px solid #ddd;border-radius: 4px;">
+ <div class="header" style="padding: 5px;border: none;"><i class="icon-user"></i> <wicket:message key="gb.activeRepositories"></wicket:message> ({{active.length}})
+ <div style="padding: 5px 0px 0px;">
+ <input type="text" ng-model="query.r" class="input-large" wicket:message="placeholder:gb.filter" style="border-radius: 14px; padding: 3px 14px;margin: 0px;"></input>
+ </div>
+ </div>
+
+ <div ng-repeat="item in active | filter:query" style="padding: 3px;border-top: 1px solid #ddd;">
+ <b><span class="repositorySwatch" style="background-color:{{item.c}};"><span ng-show="item.wc">!</span><span ng-show="!item.wc"> </span></span></b>
+ <a href="summary/?r={{item.r}}">{{item.p}}<b>{{item.n}}</b></a>
+ <span class="link hidden-tablet hidden-phone" style="color: #bbb;" title="{{item.d}}">{{item.t}}</span>
+ <span ng-show="item.s" class="pull-right">
+ <span style="padding: 0px 5px;color: #888;font-weight:bold;vertical-align:middle;">{{item.s | number}} <i class="iconic-star"></i></span>
+ </span>
+ </div>
+ </div>
+</wicket:fragment>
+
+</wicket:extend>
+</body>
+</html>
\ 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<RepositoryModel> lastUpdateSort = new Comparator<RepositoryModel>() {
+ @Override
+ public int compare(RepositoryModel o1, RepositoryModel o2) {
+ return o2.lastChange.compareTo(o1.lastChange);
+ }
+ };
+
+ Map<String, RepositoryModel> reposMap = new HashMap<String, RepositoryModel>();
+
+ // owned repositories
+ List<RepositoryModel> owned = new ArrayList<RepositoryModel>();
+ 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<RepositoryModel> starred = new ArrayList<RepositoryModel>();
+ 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<RepositoryModel> active = new ArrayList<RepositoryModel>();
+ if (user == null || UserModel.ANONYMOUS.equals(user)) {
+ List<RepositoryModel> 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<PushLogEntry> pushes = new ArrayList<PushLogEntry>();
+ for (RepositoryModel model : reposMap.values()) {
+ Repository repository = GitBlit.self().getRepository(model.name);
+ List<DailyLogEntry> 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<RepositoryModel> 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<RepoListItem> list = new ArrayList<RepoListItem>();
+ 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<PageRegistration> 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<String> files = new ArrayList<String>();
+ 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<PushLogEntry> recentPushes) {
+ // activity metrics
+ Map<String, Metric> repositoryMetrics = new HashMap<String, Metric>();
+ Map<String, Metric> authorMetrics = new HashMap<String, Metric>();
+
+ // 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 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd"
- xml:lang="en"
- lang="en">
-
-<body>
-<wicket:extend>
-<div class="container">
- <div class="markdown" style="padding-bottom:5px;" wicket:id="repositoriesMessage">[repositories message]</div>
-
-<!-- <div wicket:id="repositoriesPanel">[repositories panel]</div> -->
-</div>
-</wicket:extend>
-</body>
-</html>
\ 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<RepositoryModel> 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<PageRegistration> 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<String> files = new ArrayList<String>();
- 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<PageRegistration> pages = new ArrayList<PageRegistration>();
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 @@ <tr wicket:id="commit">
<td class="hidden-phone date" style="width:60px; vertical-align: middle;text-align: right;padding-right:10px;" ><span wicket:id="time">[time of day]</span></td>
<td style="width:10em;text-align:left;vertical-align: middle;">
- <span wicket:id="repository" class="repositorySwatch">[repository link]</span>
+ <span wicket:id="repository" class="activitySwatch">[repository link]</span>
</td>
<td class="hidden-phone hidden-tablet" style="width:30px;vertical-align: middle;"><span wicket:id="avatar" style="vertical-align: middle;"></span></td>
<td style="vertical-align: middle;padding-left:15px;">
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 @@ <body>
<wicket:panel>
-<div wicket:id="push" style="border-bottom: 1px solid #ddd;margin-bottom: 15px;">
+<div wicket:id="push" class="push">
<table style="padding: 3px 0px;">
<tr>
- <td class="hidden-phone" style="vertical-align: top;padding-top:10px"><i style="font-size:3.25em;color:#bbb;" wicket:id="pushIcon"></i></td>
+ <td class="hidden-phone" style="vertical-align: top;padding-top:10px"><i wicket:id="pushIcon"></i></td>
<td style="padding-left: 7px;">
<div>
<span wicket:id="whenPushed"></span> <span wicket:id="refRewind" class="alert alert-error" style="padding: 1px 5px;font-size: 10px;font-weight: bold;margin-left: 10px;">[rewind]</span>
</div>
- <div style="font-weight:bold;"><span wicket:id="whoPushed">[pusher]</span> <span wicket:id="whatPushed"></span><span wicket:id="refPushed"></span> <span wicket:id="repoPreposition"></span> <span wicket:id="repoPushed"></span></div>
+ <div style="font-weight:bold;"><span wicket:id="whoPushed">[pusher]</span> <span wicket:id="whatPushed"></span><span wicket:id="refPushed"></span> <span wicket:id="repoPreposition"></span> <span wicket:id="repoPushed"></span> <span wicket:id="byAuthors"></span></div>
<div style="padding: 10px 0px 5px;">
<table>
<tr wicket:id="commit">
- <td style="vertical-align:top;"><span wicket:id="commitAuthor"></span></td>
+ <td class="hidden-phone hidden-tablet" style="vertical-align:top;padding-left:7px;"><span wicket:id="commitAuthor"></span></td>
<td style="vertical-align:top;"><span wicket:id="hashLink" style="padding-left: 5px;">[hash link]</span></td>
- <td style="vertical-align:top;"><img wicket:id="commitIcon" /></td>
+ <td style="vertical-align:top;padding-left:5px;"><img wicket:id="commitIcon" /></td>
<td style="vertical-align:top;">
<span wicket:id="commitShortMessage">[commit short message]</span>
</td>
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<PushLogEntry> pushes) {
super(wicketId);
hasPushes = pushes.size() > 0;
- setup(pushes);
+ setup(pushes, true);
add(new Label("morePushes").setVisible(false));
}
- protected void setup(List<PushLogEntry> pushes) {
+ protected void setup(List<PushLogEntry> pushes, final boolean showRepo) {
final int hashLen = GitBlit.getInteger(Keys.web.shortCommitIdLength, 6);
ListDataProvider<PushLogEntry> dp = new ListDataProvider<PushLogEntry>(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<RepositoryCommit> 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<RepositoryCommit> cdp = new ListDataProvider<RepositoryCommit>(commits);
DataView<RepositoryCommit> commitsView = new DataView<RepositoryCommit>("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() {
|