Skip to content
This repository was archived by the owner on Jun 9, 2021. It is now read-only.

Commit 8904d03

Browse files
committed
Adding repo and global admin pages #25
1 parent 1fc12a7 commit 8904d03

File tree

10 files changed

+399
-594
lines changed

10 files changed

+399
-594
lines changed

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,16 @@ Changelog of Pull Request Notifier for Bitbucket.
66
### GitHub [#109](https://github.com/tomasbjerre/pull-request-notifier-for-bitbucket/issues/109) Refactor admin pages
77
Refactoring #109
88

9-
[39e9178185e939a](https://github.com/tomasbjerre/pull-request-notifier-for-bitbucket/commit/39e9178185e939a) Tomas Bjerre *2016-05-03 15:33:36*
9+
[3e1fddaecb4aab8](https://github.com/tomasbjerre/pull-request-notifier-for-bitbucket/commit/3e1fddaecb4aab8) Tomas Bjerre *2016-05-03 16:01:52*
10+
11+
### GitHub [#25](https://github.com/tomasbjerre/pull-request-notifier-for-bitbucket/issues/25) Enable configuration in per-repository hook screen
12+
Adding repo and global admin pages #25
13+
14+
[f648c5012cf4706](https://github.com/tomasbjerre/pull-request-notifier-for-bitbucket/commit/f648c5012cf4706) Tomas Bjerre *2016-05-03 18:16:19*
15+
16+
Adding project and repo filter to notification #25
17+
18+
[1fc12a72100afe8](https://github.com/tomasbjerre/pull-request-notifier-for-bitbucket/commit/1fc12a72100afe8) Tomas Bjerre *2016-05-03 16:44:25*
1019

1120
### No issue
1221
changelog maven plugin 1.29

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,16 @@ The filter text as well as the URL support variables. These are:
7676
* ${PULL_REQUEST_FROM_REPO_PROJECT_ID} Example: 1
7777
* ${PULL_REQUEST_FROM_REPO_PROJECT_KEY} Example: PROJECT_1
7878
* ${PULL_REQUEST_FROM_REPO_SLUG} Example: rep_1
79-
* And same variables for TO, like: ${PULL_REQUEST_TO_HASH}
79+
* ${PULL_REQUEST_TO_SSH_CLONE_URL} Example: ssh://git@localhost:7999/project_1/rep_1
80+
* ${PULL_REQUEST_TO_HTTP_CLONE_URL} Example: http://admin@localhost:7990/bitbucket/scm/project_1/rep_1.git
81+
* ${PULL_REQUEST_TO_HASH} Example: 6053a1eaa1c009dd11092d09a72f3c41af1b59ad
82+
* ${PULL_REQUEST_TO_ID} Example: refs/heads/branchmodmerge
83+
* ${PULL_REQUEST_TO_BRANCH} Example: branchmodmerge
84+
* ${PULL_REQUEST_TO_REPO_ID} Example: 1
85+
* ${PULL_REQUEST_TO_REPO_NAME} Example: rep_1
86+
* ${PULL_REQUEST_TO_REPO_PROJECT_ID} Example: 1
87+
* ${PULL_REQUEST_TO_REPO_PROJECT_KEY} Example: PROJECT_1
88+
* ${PULL_REQUEST_TO_REPO_SLUG} Example: rep_1
8089

8190
The ${PULL_REQUEST_USER...} contains information about the user who issued the event. Who commented it, who rejected it, who approved it...
8291

src/main/java/se/bjurr/prnfb/presentation/GlobalAdminServlet.java

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,40 @@
11
package se.bjurr.prnfb.presentation;
22

3+
import static com.google.common.base.Optional.absent;
4+
import static com.google.common.base.Preconditions.checkNotNull;
35
import static com.google.common.base.Throwables.propagate;
6+
import static com.google.common.collect.ImmutableMap.of;
7+
import static com.google.common.collect.Maps.newHashMap;
48

59
import java.net.URI;
10+
import java.util.Map;
611

712
import javax.servlet.http.HttpServlet;
813
import javax.servlet.http.HttpServletRequest;
914
import javax.servlet.http.HttpServletResponse;
1015

16+
import com.atlassian.bitbucket.repository.Repository;
17+
import com.atlassian.bitbucket.repository.RepositoryService;
1118
import com.atlassian.sal.api.auth.LoginUriProvider;
1219
import com.atlassian.sal.api.user.UserManager;
1320
import com.atlassian.sal.api.user.UserProfile;
1421
import com.atlassian.templaterenderer.TemplateRenderer;
22+
import com.google.common.annotations.VisibleForTesting;
23+
import com.google.common.base.Optional;
1524

1625
public class GlobalAdminServlet extends HttpServlet {
1726
private static final long serialVersionUID = 3846987953228399693L;
1827
private final LoginUriProvider loginUriProvider;
1928
private final TemplateRenderer renderer;
29+
private final RepositoryService repositoryService;
2030
private final UserManager userManager;
2131

22-
public GlobalAdminServlet(UserManager userManager, LoginUriProvider loginUriProvider, TemplateRenderer renderer) {
32+
public GlobalAdminServlet(UserManager userManager, LoginUriProvider loginUriProvider, TemplateRenderer renderer,
33+
RepositoryService repositoryService) {
2334
this.userManager = userManager;
2435
this.loginUriProvider = loginUriProvider;
2536
this.renderer = renderer;
37+
this.repositoryService = repositoryService;
2638
}
2739

2840
@Override
@@ -33,8 +45,20 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) {
3345
response.sendRedirect(this.loginUriProvider.getLoginUri(getUri(request)).toASCIIString());
3446
return;
3547
}
36-
response.setContentType("text/html;charset=utf-8");
37-
this.renderer.render("admin.vm", response.getWriter());
48+
49+
final Optional<Repository> repository = getRepository(request.getPathInfo());
50+
Map<String, Object> context = newHashMap();
51+
if (repository.isPresent()) {
52+
context = of( //
53+
"repository", repository.orNull() //
54+
);
55+
}
56+
57+
response.setContentType("text/html;charset=UTF-8");
58+
this.renderer.render( //
59+
"admin.vm", //
60+
context, //
61+
response.getWriter());
3862
} catch (Exception e) {
3963
propagate(e);
4064
}
@@ -48,4 +72,21 @@ private URI getUri(HttpServletRequest request) {
4872
}
4973
return URI.create(builder.toString());
5074
}
75+
76+
@VisibleForTesting
77+
Optional<Repository> getRepository(String pathInfo) {
78+
if (pathInfo == null || !pathInfo.contains("/") || pathInfo.endsWith("prnfb/admin")
79+
|| pathInfo.endsWith("prnfb/admin/")) {
80+
return absent();
81+
}
82+
String[] components = pathInfo.split("/");
83+
if (components.length == 0) {
84+
return absent();
85+
}
86+
String project = components[components.length - 2];
87+
String repoSlug = components[components.length - 1];
88+
final Repository repository = checkNotNull(this.repositoryService.getBySlug(project, repoSlug), //
89+
"Did not find " + project + " " + repoSlug);
90+
return Optional.of(repository);
91+
}
5192
}

src/main/resources/admin.css

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +0,0 @@
1-
.config-area {
2-
border: 1px;
3-
border-color: black;
4-
border-style: dotted;
5-
width: 400px;
6-
padding: 5px 15px;
7-
}
8-
9-
fieldset {
10-
border: 1px;
11-
padding: 5px 15px;
12-
}
13-
14-
legend {
15-
font-weight: bold;
16-
font-size: 20px;
17-
}
18-
19-
.left {
20-
float: left;
21-
}
22-
23-
.right {
24-
float: right;
25-
}
26-
27-
.error {
28-
font-weight: bold;
29-
color: red;
30-
}
31-
32-
input[type="text"],
33-
input[type="password"] {
34-
width: 100%;
35-
}
36-
37-
.prnfb > form {
38-
margin: 10px 0 0 0;
39-
}
40-
41-
.prnfb-template {
42-
display: none;
43-
}
44-
45-
.visibleif {
46-
display: none;
47-
}
48-
49-
th {
50-
text-align: left;
51-
}
52-
53-
td > input[type="text"] {
54-
width: 90%;
55-
margin: 0 10% 0 0;
56-
float: left
57-
}
58-
59-
.expandable .content {
60-
display: none;
61-
}
62-
63-
.expandable.expanded .content {
64-
display: inherit;
65-
}

src/main/resources/admin.js

Lines changed: 15 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -1,160 +1,17 @@
1-
(function($) {
2-
'use strict';
3-
var config_resource = AJS.contextPath() + "/rest/prnfb-admin/1.0/";
4-
$(document).ready(function() {
5-
function getEmpties($headers) {
6-
var empties = [];
7-
$('.header', $headers).each(function(iheader, $header) {
8-
var allValue = "";
9-
$('input[type="text"]', $header).each(function(iinput, $input) {
10-
allValue += $input.value.trim();
11-
});
12-
if (allValue === "") {
13-
empties.push($header);
14-
}
15-
});
16-
return empties;
17-
}
18-
19-
function adjustHeaders($headers) {
20-
var empties = getEmpties($headers);
21-
if (empties.length === 0) {
22-
$headers.append($(".prnfb-template .header")[0].outerHTML);
23-
}
24-
25-
if (empties.length > 1) {
26-
empties[1].remove();
27-
}
28-
}
29-
30-
function setEvents() {
31-
$('input[name="delete"]').click(function(e) {
32-
var $form = $(this).closest('form');
33-
var formIdentifier = $('input[name="FORM_IDENTIFIER"]', $form).val();
34-
$.ajax({
35-
url: config_resource + formIdentifier,
36-
dataType: "json",
37-
type: "DELETE",
38-
error: function(xhr, data, error) {
39-
console.log(xhr);
40-
console.log(data);
41-
console.log(error);
42-
},
43-
success: function(data, text, xhr) {
44-
$form.remove();
45-
}
46-
});
47-
});
48-
49-
$('.expandable').each(function(index, el) {
50-
var $element = $(el);
51-
$element.find('.toggle').click(function() {
52-
$element.toggleClass('expanded');
53-
});
54-
});
55-
//If there are only a few triggers configured, they can be expanded by default without confusion.
56-
if ($('.expandable').length < 4) {
57-
$('.expandable').addClass('expanded');
58-
}
59-
60-
$('.headers').keyup(function(e) {
61-
var $headers = $(this);
62-
adjustHeaders($headers);
63-
});
64-
65-
$('input[name="save"]').click(function(e) {
66-
var $form = $(this).closest('form');
67-
$(".post", $form).html("Saving...");
68-
$.ajax({
69-
url: config_resource,
70-
dataType: "json",
71-
type: "POST",
72-
contentType: "application/json",
73-
data: JSON.stringify($form.serializeArray(), null, 2),
74-
processData: false,
75-
error: function(xhr, data, error) {
76-
$(".error." + xhr.responseJSON.field, $form).html(xhr.responseJSON.error);
77-
if (xhr.responseJSON.field) {
78-
$(".post", $form).html("There were errors, form not saved!");
79-
} else {
80-
$(".post", $form).html(xhr.responseText);
81-
}
82-
},
83-
success: function(data, text, xhr) {
84-
getAll();
85-
}
86-
});
87-
});
88-
}
89-
90-
function addNewForm(formType) {
91-
var $template = $(".prnfb-template-" + formType).clone();
92-
$('input[name="delete"]', $template).remove();
93-
$('input[name=method][value=GET]', $template).attr('checked', 'checked');
94-
$('.expandable', $template).addClass('expanded');
95-
$(".prnfb-" + formType).append($template.html());
96-
}
1+
define('plugin/prnfb/admin', [
2+
'jquery',
3+
'aui',
4+
'plugin/prnfb/utils'
5+
], function($, AJS, common) {
976

98-
function getAll() {
99-
$.ajax({
100-
url: config_resource,
101-
dataType: "json"
102-
}).done(function(configs) {
103-
$(".prnfb-TRIGGER_CONFIG_FORM").html("");
104-
$(".prnfb-BUTTON_CONFIG_FORM").html("");
105-
$(".prnfb-GLOBAL_SETTINGS").html("");
106-
$.each(configs, function(index, config) {
107-
var formType = 'TRIGGER_CONFIG_FORM';
108-
$.each(config, function(fieldIndex, field_map) {
109-
if (field_map.name === 'FORM_TYPE') {
110-
formType = field_map.value;
111-
}
112-
});
113-
114-
var $template = $(".prnfb-template-" + formType).clone();
115-
116-
$.each(config, function(fieldIndex, field_map) {
117-
var safe_value = field_map.value.replace(/[^a-zA-Z\_]/g, '');
118-
$('.variable[data-variable="' + field_map.name + '"]', $template).html(field_map.value);
119-
$('input[type="text"][name="' + field_map.name + '"]', $template).attr('value', field_map.value);
120-
$('input[type="password"][name="' + field_map.name + '"]', $template).attr('value', field_map.value);
121-
$('textarea[name="' + field_map.name + '"]', $template).text(field_map.value);
122-
$('input[type="hidden"][name="' + field_map.name + '"]', $template).attr('value', field_map.value);
123-
$('input[type="checkbox"][name="' + field_map.name + '"][value="' + safe_value + '"]', $template).attr('checked', 'checked');
124-
$('input[type="radio"][name="' + field_map.name + '"][value="' + safe_value + '"]', $template).attr('checked', 'checked');
125-
$('.visibleif.' + field_map.name + '_' + safe_value, $template).show();
126-
});
127-
128-
var header_names = [];
129-
var header_values = [];
130-
$.each(config, function(fieldIndex, field_map) {
131-
if (field_map.name === 'header_name') {
132-
header_names.push(field_map.value);
133-
} else if (field_map.name === 'header_value') {
134-
header_values.push(field_map.value);
135-
}
136-
});
137-
for (var i = 0; i < header_names.length; i++) {
138-
$('input[type="text"][name="header_name"]', $template).last().attr('value', header_names[i]);
139-
$('input[type="text"][name="header_value"]', $template).last().attr('value', header_values[i]);
140-
adjustHeaders($(".headers", $template));
141-
}
142-
143-
if (!$('input[name=method]:checked', $template).val()) {
144-
$('input[name=method][value=GET]', $template).attr('checked', 'checked');
145-
}
146-
147-
$(".prnfb-" + formType).append($template.html());
148-
});
149-
addNewForm('TRIGGER_CONFIG_FORM');
150-
addNewForm('BUTTON_CONFIG_FORM');
151-
if ($('[name="FORM_TYPE"][value="GLOBAL_SETTINGS"]').length < 2) {
152-
addNewForm('GLOBAL_SETTINGS');
153-
}
154-
setEvents();
155-
});
156-
}
157-
158-
getAll();
7+
$(document).ready(function() {
8+
var globalRepoAdminUrl = AJS.contextPath() + "/rest/prnfb-admin/1.0"; 
9+
$.getJSON(globalRepoAdminUrl, function(data) {
10+
common.setupRepoSettingsForm(data);
11+
});
15912
});
160-
})(AJS.$ || jQuery);
13+
});
14+
15+
AJS.$(document).ready(function() {
16+
require('plugin/prnfb/admin');
17+
});

0 commit comments

Comments
 (0)