From a502d96a860456ec5e8c96761db70f7cabb74751 Mon Sep 17 00:00:00 2001
From: Paul Martin <paul@paulsputer.com>
Date: Sat, 30 Apr 2016 04:19:14 -0400
Subject: [PATCH] Merge pull request #1073 from gitblit/1062-DocEditorUpdates

---
 src/main/java/com/gitblit/wicket/pages/ProjectPage.java |  260 ++++++++++++++++-----------------------------------
 1 files changed, 81 insertions(+), 179 deletions(-)

diff --git a/src/main/java/com/gitblit/wicket/pages/ProjectPage.java b/src/main/java/com/gitblit/wicket/pages/ProjectPage.java
index 7eba033..d358b77 100644
--- a/src/main/java/com/gitblit/wicket/pages/ProjectPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/ProjectPage.java
@@ -15,52 +15,39 @@
  */
 package com.gitblit.wicket.pages;
 
-import java.text.MessageFormat;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 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.link.ExternalLink;
-import org.apache.wicket.markup.repeater.Item;
-import org.apache.wicket.markup.repeater.data.DataView;
-import org.apache.wicket.markup.repeater.data.ListDataProvider;
 
-import com.gitblit.GitBlit;
 import com.gitblit.Keys;
-import com.gitblit.SyndicationServlet;
-import com.gitblit.models.Activity;
-import com.gitblit.models.Metric;
+import com.gitblit.models.Menu.MenuDivider;
+import com.gitblit.models.Menu.MenuItem;
+import com.gitblit.models.Menu.ParameterMenuItem;
+import com.gitblit.models.NavLink.DropDownPageMenuNavLink;
+import com.gitblit.models.NavLink;
 import com.gitblit.models.ProjectModel;
 import com.gitblit.models.RepositoryModel;
-import com.gitblit.utils.ActivityUtils;
+import com.gitblit.models.UserModel;
+import com.gitblit.servlet.SyndicationServlet;
 import com.gitblit.utils.MarkdownUtils;
 import com.gitblit.utils.StringUtils;
+import com.gitblit.wicket.CacheControl;
+import com.gitblit.wicket.CacheControl.LastModified;
 import com.gitblit.wicket.GitBlitWebApp;
 import com.gitblit.wicket.GitBlitWebSession;
 import com.gitblit.wicket.GitblitRedirectException;
-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.GoogleLineChart;
-import com.gitblit.wicket.charting.GooglePieChart;
-import com.gitblit.wicket.panels.ActivityPanel;
-import com.gitblit.wicket.panels.ProjectRepositoryPanel;
+import com.gitblit.wicket.panels.FilterableRepositoryList;
 
-public class ProjectPage extends RootPage {
-	
+@CacheControl(LastModified.PROJECT)
+public class ProjectPage extends DashboardPage {
+
 	List<ProjectModel> projectModels = new ArrayList<ProjectModel>();
 
 	public ProjectPage() {
@@ -74,38 +61,58 @@
 	}
 
 	@Override
-	protected boolean reusePageParameters() {
-		return true;
+	protected Class<? extends BasePage> getRootNavPageClass() {
+		return RepositoriesPage.class;
+	}
+
+	@Override
+	protected void setLastModified() {
+		if (getClass().isAnnotationPresent(CacheControl.class)) {
+			CacheControl cacheControl = getClass().getAnnotation(CacheControl.class);
+			switch (cacheControl.value()) {
+			case PROJECT:
+				String projectName = WicketUtils.getProjectName(getPageParameters());
+				if (!StringUtils.isEmpty(projectName)) {
+					ProjectModel project = getProjectModel(projectName);
+					if (project != null) {
+						setLastModified(project.lastChange);
+					}
+				}
+				break;
+			default:
+				super.setLastModified();
+			}
+		}
 	}
 
 	private void setup(PageParameters params) {
 		setupPage("", "");
 		// check to see if we should display a login message
-		boolean authenticateView = GitBlit.getBoolean(Keys.web.authenticateViewPages, true);
+		boolean authenticateView = app().settings().getBoolean(Keys.web.authenticateViewPages, true);
 		if (authenticateView && !GitBlitWebSession.get().isLoggedIn()) {
 			authenticationError("Please login");
 			return;
 		}
 
-		String projectName = WicketUtils.getProjectName(params);
+		String projectName = params == null ? null : WicketUtils.getProjectName(params);
 		if (StringUtils.isEmpty(projectName)) {
 			throw new GitblitRedirectException(GitBlitWebApp.get().getHomePage());
 		}
-		
+
 		ProjectModel project = getProjectModel(projectName);
 		if (project == null) {
 			throw new GitblitRedirectException(GitBlitWebApp.get().getHomePage());
 		}
-		
+
 		add(new Label("projectTitle", project.getDisplayName()));
 		add(new Label("projectDescription", project.description));
-		
+
 		String feedLink = SyndicationServlet.asLink(getRequest().getRelativePathPrefixToContextRoot(), projectName, null, 0);
 		add(new ExternalLink("syndication", feedLink));
 
 		add(WicketUtils.syndicationDiscoveryLink(SyndicationServlet.getTitle(project.getDisplayName(),
 				null), feedLink));
-		
+
 		// project markdown message
 		String pmessage = transformMarkdown(project.projectMarkdown);
 		Component projectMessage = new Label("projectMessage", pmessage)
@@ -118,8 +125,22 @@
 				.setEscapeModelStrings(false).setVisible(rmessage.length() > 0);
 		add(repositoriesMessage);
 
+		UserModel user = GitBlitWebSession.get().getUser();
+		if (user == null) {
+			user = UserModel.ANONYMOUS;
+		}
+		int daysBack = params == null ? 0 : WicketUtils.getDaysBack(params);
+		if (daysBack < 1) {
+			daysBack = app().settings().getInteger(Keys.web.activityDuration, 7);
+		}
+		// reset the daysback parameter so that we have a complete project
+		// repository list.  the recent activity will be built up by the
+		// reflog utils.
+		if (params != null) {
+			params.remove("db");
+		}
+
 		List<RepositoryModel> repositories = getRepositories(params);
-		
 		Collections.sort(repositories, new Comparator<RepositoryModel>() {
 			@Override
 			public int compare(RepositoryModel o1, RepositoryModel o2) {
@@ -128,146 +149,22 @@
 			}
 		});
 
-		final ListDataProvider<RepositoryModel> dp = new ListDataProvider<RepositoryModel>(repositories);
-		DataView<RepositoryModel> dataView = new DataView<RepositoryModel>("repositoryList", dp) {
-			private static final long serialVersionUID = 1L;
+		addActivity(user, repositories, getString("gb.recentActivity"), daysBack);
 
-			public void populateItem(final Item<RepositoryModel> item) {
-				final RepositoryModel entry = item.getModelObject();
-				
-				ProjectRepositoryPanel row = new ProjectRepositoryPanel("repository", 
-						getLocalizer(), this, showAdmin, entry, getAccessRestrictions());
-				item.add(row);
-			}
-		};
-		add(dataView);
-
-		// project activity
-		// parameters
-		int daysBack = WicketUtils.getDaysBack(params);
-		if (daysBack < 1) {
-			daysBack = 14;
-		}
-		String objectId = WicketUtils.getObject(params);
-
-		List<Activity> recentActivity = ActivityUtils.getRecentActivity(repositories, 
-				daysBack, objectId, getTimeZone());
-		if (recentActivity.size() == 0) {
-			// no activity, skip graphs and activity panel
-			add(new Label("subheader", MessageFormat.format(getString("gb.recentActivityNone"),
-					daysBack)));
-			add(new Label("activityPanel"));
+		if (repositories.isEmpty()) {
+			add(new Label("repositoryList").setVisible(false));
 		} else {
-			// calculate total commits and total authors
-			int totalCommits = 0;
-			Set<String> uniqueAuthors = new HashSet<String>();
-			for (Activity activity : recentActivity) {
-				totalCommits += activity.getCommitCount();
-				uniqueAuthors.addAll(activity.getAuthorMetrics().keySet());
-			}
-			int totalAuthors = uniqueAuthors.size();
-
-			// add the subheader with stat numbers
-			add(new Label("subheader", MessageFormat.format(getString("gb.recentActivityStats"),
-					daysBack, totalCommits, totalAuthors)));
-
-			// create the activity charts
-			GoogleCharts charts = createCharts(recentActivity);
-			add(new HeaderContributor(charts));
-
-			// add activity panel
-			add(new ActivityPanel("activityPanel", recentActivity));
+			FilterableRepositoryList repoList = new FilterableRepositoryList("repositoryList", repositories);
+			repoList.setAllowCreate(user.canCreate(project.name + "/"));
+			add(repoList);
 		}
-	}
-	
-	/**
-	 * Creates the daily activity line chart, the active repositories pie chart,
-	 * and the active authors pie chart
-	 * 
-	 * @param recentActivity
-	 * @return
-	 */
-	private GoogleCharts createCharts(List<Activity> recentActivity) {
-		// activity metrics
-		Map<String, Metric> repositoryMetrics = new HashMap<String, Metric>();
-		Map<String, Metric> authorMetrics = new HashMap<String, Metric>();
-
-		// aggregate repository and author metrics
-		for (Activity activity : recentActivity) {
-
-			// aggregate author metrics
-			for (Map.Entry<String, Metric> entry : activity.getAuthorMetrics().entrySet()) {
-				String author = entry.getKey();
-				if (!authorMetrics.containsKey(author)) {
-					authorMetrics.put(author, new Metric(author));
-				}
-				authorMetrics.get(author).count += entry.getValue().count;
-			}
-
-			// aggregate repository metrics
-			for (Map.Entry<String, Metric> entry : activity.getRepositoryMetrics().entrySet()) {
-				String repository = StringUtils.stripDotGit(entry.getKey());
-				if (!repositoryMetrics.containsKey(repository)) {
-					repositoryMetrics.put(repository, new Metric(repository));
-				}
-				repositoryMetrics.get(repository).count += entry.getValue().count;
-			}
-		}
-
-		// build google charts
-		int w = 310;
-		int h = 150;
-		GoogleCharts charts = new GoogleCharts();
-
-		// sort in reverse-chronological order and then reverse that
-		Collections.sort(recentActivity);
-		Collections.reverse(recentActivity);
-
-		// daily line chart
-		GoogleChart chart = new GoogleLineChart("chartDaily", getString("gb.dailyActivity"), "day",
-				getString("gb.commits"));
-		SimpleDateFormat df = new SimpleDateFormat("MMM dd");
-		df.setTimeZone(getTimeZone());
-		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
-		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.setWidth(w);
-		chart.setHeight(h);
-		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.setWidth(w);
-		chart.setHeight(h);
-		charts.addChart(chart);
-
-		return charts;
 	}
 
 	@Override
-	protected void addDropDownMenus(List<PageRegistration> pages) {
+	protected void addDropDownMenus(List<NavLink> navLinks) {
 		PageParameters params = getPageParameters();
 
-		DropDownMenuRegistration projects = new DropDownMenuRegistration("gb.projects",
-				ProjectPage.class);
-		projects.menuItems.addAll(getProjectsMenu());
-		pages.add(0, projects);
-
-		DropDownMenuRegistration menu = new DropDownMenuRegistration("gb.filters",
+		DropDownPageMenuNavLink menu = new DropDownPageMenuNavLink("gb.filters",
 				ProjectPage.class);
 		// preserve time filter option on repository choices
 		menu.menuItems.addAll(getRepositoryFilterItems(params));
@@ -277,22 +174,27 @@
 
 		if (menu.menuItems.size() > 0) {
 			// Reset Filter
-			menu.menuItems.add(new DropDownMenuItem(getString("gb.reset"), null, null));
+			menu.menuItems.add(new ParameterMenuItem(getString("gb.reset"), "p", WicketUtils.getProjectName(params)));
 		}
 
-		pages.add(menu);
+		navLinks.add(menu);
+
+		DropDownPageMenuNavLink projects = new DropDownPageMenuNavLink("gb.projects",
+				ProjectPage.class);
+		projects.menuItems.addAll(getProjectsMenu());
+		navLinks.add(projects);
 	}
-	
+
 	@Override
 	protected List<ProjectModel> getProjectModels() {
 		if (projectModels.isEmpty()) {
 			List<RepositoryModel> repositories = getRepositoryModels();
-			List<ProjectModel> projects = GitBlit.self().getProjectModels(repositories, false);
+			List<ProjectModel> projects = app().projects().getProjectModels(repositories, false);
 			projectModels.addAll(projects);
 		}
 		return projectModels;
 	}
-	
+
 	private ProjectModel getProjectModel(String name) {
 		for (ProjectModel project : getProjectModels()) {
 			if (name.equalsIgnoreCase(project.name)) {
@@ -301,9 +203,9 @@
 		}
 		return null;
 	}
-	
-	protected List<DropDownMenuItem> getProjectsMenu() {
-		List<DropDownMenuItem> menu = new ArrayList<DropDownMenuItem>();
+
+	protected List<MenuItem> getProjectsMenu() {
+		List<MenuItem> menu = new ArrayList<MenuItem>();
 		List<ProjectModel> projects = new ArrayList<ProjectModel>();
 		for (ProjectModel model : getProjectModels()) {
 			if (!model.isUserProject()) {
@@ -330,15 +232,15 @@
 		}
 
 		for (ProjectModel project : projects) {
-			menu.add(new DropDownMenuItem(project.getDisplayName(), "p", project.name));
+			menu.add(new ParameterMenuItem(project.getDisplayName(), "p", project.name));
 		}
 		if (showAllProjects) {
-			menu.add(new DropDownMenuItem());
-			menu.add(new DropDownMenuItem("all projects", null, null));
+			menu.add(new MenuDivider());
+			menu.add(new ParameterMenuItem("all projects"));
 		}
 		return menu;
 	}
-	
+
 	private String transformMarkdown(String markdown) {
 		String message = "";
 		if (!StringUtils.isEmpty(markdown)) {

--
Gitblit v1.9.1