diff options
Diffstat (limited to 'src/main/java/com/gitblit/wicket/panels/NestedRepositoryTreePanel.java')
-rw-r--r-- | src/main/java/com/gitblit/wicket/panels/NestedRepositoryTreePanel.java | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/src/main/java/com/gitblit/wicket/panels/NestedRepositoryTreePanel.java b/src/main/java/com/gitblit/wicket/panels/NestedRepositoryTreePanel.java new file mode 100644 index 00000000..fbe1991d --- /dev/null +++ b/src/main/java/com/gitblit/wicket/panels/NestedRepositoryTreePanel.java @@ -0,0 +1,231 @@ +package com.gitblit.wicket.panels; + +import java.util.Map; + +import org.apache.wicket.Component; +import org.apache.wicket.PageParameters; +import org.apache.wicket.behavior.AttributeAppender; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.list.ListItem; +import org.apache.wicket.markup.html.list.ListView; +import org.apache.wicket.markup.html.panel.Fragment; +import org.apache.wicket.markup.repeater.RepeatingView; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; + +import com.gitblit.Constants.AccessRestrictionType; +import com.gitblit.Keys; +import com.gitblit.models.RepositoryModel; +import com.gitblit.models.TreeNodeModel; +import com.gitblit.models.UserModel; +import com.gitblit.utils.ArrayUtils; +import com.gitblit.utils.ModelUtils; +import com.gitblit.utils.StringUtils; +import com.gitblit.wicket.WicketUtils; +import com.gitblit.wicket.pages.BasePage; +import com.gitblit.wicket.pages.ProjectPage; +import com.gitblit.wicket.pages.SummaryPage; +import com.gitblit.wicket.pages.UserPage; + +public class NestedRepositoryTreePanel extends BasePanel { + + private static final long serialVersionUID = 1L; + + public NestedRepositoryTreePanel(final String wicketId, final IModel<TreeNodeModel> model, final Map<AccessRestrictionType, String> accessRestrictionTranslations, final boolean linksActive) { + super(wicketId); + + final boolean showSize = app().settings().getBoolean(Keys.web.showRepositorySizes, true); + final boolean showSwatch = app().settings().getBoolean(Keys.web.repositoryListSwatches, true); + + final TreeNodeModel node = model.getObject(); + Fragment nodeHeader = new Fragment("nodeHeader", "groupRepositoryRow", this); + add(nodeHeader); + WebMarkupContainer firstColumn = new WebMarkupContainer("firstColumn"); + nodeHeader.add(firstColumn); + RepeatingView depth = new RepeatingView("depth"); + for(int i=0; i<node.getDepth();i++) { + depth.add(new WebMarkupContainer(depth.newChildId())); + } + firstColumn.add(depth); + firstColumn.add(new Fragment("groupCollapsible", "tableGroupMinusCollapsible", this)); + if(node.getParent()!=null) { + addChildOfNodeIdCssClassesToRow(nodeHeader, node.getParent()); + } + nodeHeader.add(new AttributeAppender("data-node-id", Model.of(node.hashCode()), " ")); + + String name = node.getName(); + if (name.startsWith(ModelUtils.getUserRepoPrefix())) { + // user page + String username = ModelUtils.getUserNameFromRepoPath(name); + UserModel user = app().users().getUserModel(username); + firstColumn.add(new LinkPanel("groupName", null, (user == null ? username : user.getDisplayName()), UserPage.class, WicketUtils.newUsernameParameter(username))); + nodeHeader.add(new Label("groupDescription", getString("gb.personalRepositories"))); + } else { + // project page + firstColumn.add(new LinkPanel("groupName", null, name, ProjectPage.class, WicketUtils.newProjectParameter(name))); + nodeHeader.add(new Label("groupDescription", "")); + } + WicketUtils.addCssClass(nodeHeader, "group collapsible tree"); + + add(new ListView<TreeNodeModel>("subFolders", node.getSubFolders()) { + private static final long serialVersionUID = 1L; + + @Override + protected void populateItem(ListItem<TreeNodeModel> item) { + item.add(new NestedRepositoryTreePanel("rowContent", item.getModel(), accessRestrictionTranslations, linksActive)); + } + + @Override + public boolean isVisible() { + return super.isVisible() && !node.getSubFolders().isEmpty(); + } + }); + + add(new ListView<RepositoryModel>("repositories", node.getRepositories()) { + private static final long serialVersionUID = 1L; + + int counter = 0; + + @Override + public boolean isVisible() { + return super.isVisible() && !node.getRepositories().isEmpty(); + } + + @Override + protected void populateItem(ListItem<RepositoryModel> item) { + + RepositoryModel entry = item.getModelObject(); + WebMarkupContainer rowContent = new WebMarkupContainer("rowContent"); + item.add(rowContent); + addChildOfNodeIdCssClassesToRow(rowContent, node); + WebMarkupContainer firstColumn = new WebMarkupContainer("firstColumn"); + rowContent.add(firstColumn); + RepeatingView depth = new RepeatingView("depth"); + for(int i=0; i<node.getDepth();i++) { + depth.add(new WebMarkupContainer(depth.newChildId())); + } + firstColumn.add(depth); + + // show colored repository type icon + Fragment iconFragment; + if (entry.isMirror) { + iconFragment = new Fragment("repoIcon", "mirrorIconFragment", this); + } else if (entry.isFork()) { + iconFragment = new Fragment("repoIcon", "forkIconFragment", this); + } else if (entry.isBare) { + iconFragment = new Fragment("repoIcon", "repoIconFragment", this); + } else { + iconFragment = new Fragment("repoIcon", "cloneIconFragment", this); + } + if (showSwatch) { + WicketUtils.setCssStyle(iconFragment, "color:" + StringUtils.getColor(entry.toString())); + } + firstColumn.add(iconFragment); + + // try to strip group name for less cluttered list + String repoName = StringUtils.getLastPathElement(entry.toString()); + + if (linksActive) { + Class<? extends BasePage> linkPage = SummaryPage.class; + PageParameters pp = WicketUtils.newRepositoryParameter(entry.name); + firstColumn.add(new LinkPanel("repositoryName", "list", repoName, linkPage, pp)); + rowContent.add(new LinkPanel("repositoryDescription", "list", entry.description, linkPage, pp)); + } else { + // no links like on a federation page + firstColumn.add(new Label("repositoryName", repoName)); + rowContent.add(new Label("repositoryDescription", entry.description)); + } + if (entry.hasCommits) { + // Existing repository + rowContent.add(new Label("repositorySize", entry.size).setVisible(showSize)); + } else { + // New repository + rowContent.add(new Label("repositorySize", "<span class='empty'>(" + getString("gb.empty") + ")</span>").setEscapeModelStrings(false)); + } + + if (entry.isSparkleshared()) { + rowContent.add(WicketUtils.newImage("sparkleshareIcon", "star_16x16.png", getString("gb.isSparkleshared"))); + } else { + rowContent.add(WicketUtils.newClearPixel("sparkleshareIcon").setVisible(false)); + } + + if (!entry.isMirror && entry.isFrozen) { + rowContent.add(WicketUtils.newImage("frozenIcon", "cold_16x16.png", getString("gb.isFrozen"))); + } else { + rowContent.add(WicketUtils.newClearPixel("frozenIcon").setVisible(false)); + } + + if (entry.isFederated) { + rowContent.add(WicketUtils.newImage("federatedIcon", "federated_16x16.png", getString("gb.isFederated"))); + } else { + rowContent.add(WicketUtils.newClearPixel("federatedIcon").setVisible(false)); + } + + if (entry.isMirror) { + rowContent.add(WicketUtils.newImage("accessRestrictionIcon", "mirror_16x16.png", getString("gb.isMirror"))); + } else { + switch (entry.accessRestriction) { + case NONE: + rowContent.add(WicketUtils.newBlankImage("accessRestrictionIcon")); + break; + case PUSH: + rowContent.add(WicketUtils.newImage("accessRestrictionIcon", "lock_go_16x16.png", accessRestrictionTranslations.get(entry.accessRestriction))); + break; + case CLONE: + rowContent.add(WicketUtils.newImage("accessRestrictionIcon", "lock_pull_16x16.png", accessRestrictionTranslations.get(entry.accessRestriction))); + break; + case VIEW: + rowContent.add(WicketUtils.newImage("accessRestrictionIcon", "shield_16x16.png", accessRestrictionTranslations.get(entry.accessRestriction))); + break; + default: + rowContent.add(WicketUtils.newBlankImage("accessRestrictionIcon")); + } + } + + String owner = ""; + if (!ArrayUtils.isEmpty(entry.owners)) { + // display first owner + for (String username : entry.owners) { + UserModel ownerModel = app().users().getUserModel(username); + if (ownerModel != null) { + owner = ownerModel.getDisplayName(); + break; + } + } + if (entry.owners.size() > 1) { + owner += ", ..."; + } + } + Label ownerLabel = new Label("repositoryOwner", owner); + WicketUtils.setHtmlTooltip(ownerLabel, ArrayUtils.toString(entry.owners)); + rowContent.add(ownerLabel); + + String lastChange; + if (entry.lastChange.getTime() == 0) { + lastChange = "--"; + } else { + lastChange = getTimeUtils().timeAgo(entry.lastChange); + } + Label lastChangeLabel = new Label("repositoryLastChange", lastChange); + rowContent.add(lastChangeLabel); + WicketUtils.setCssClass(lastChangeLabel, getTimeUtils().timeAgoCss(entry.lastChange)); + if (!StringUtils.isEmpty(entry.lastChangeAuthor)) { + WicketUtils.setHtmlTooltip(lastChangeLabel, getString("gb.author") + ": " + entry.lastChangeAuthor); + } + + String clazz = counter % 2 == 0 ? "light" : "dark"; + WicketUtils.addCssClass(rowContent, clazz); + counter++; + } + }); + + } + + private void addChildOfNodeIdCssClassesToRow(Component row, TreeNodeModel parentNode) { + row.add(new AttributeAppender("class", Model.of("child-of-"+ parentNode.hashCode()), " ")); + if(parentNode.getParent() != null) { + addChildOfNodeIdCssClassesToRow(row, parentNode.getParent()); + } + } +} |