Skip to content

Commit f520520

Browse files
committed
feat: allow an integration to be deleted via the UI
1 parent 5456eda commit f520520

File tree

11 files changed

+208
-47
lines changed

11 files changed

+208
-47
lines changed

lib/pact_broker/api.rb

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ module PactBroker
8686
add ['test','error'], Api::Resources::ErrorTest, {resource_name: "error_test"}
8787

8888
add ['integrations'], Api::Resources::Integrations, {resource_name: "integrations"}
89+
add ['integrations', 'provider', :provider_name, 'consumer', :consumer_name], Api::Resources::Integration, {resource_name: "integration"}
8990
add [], Api::Resources::Index, {resource_name: "index"}
9091
end
9192
end

lib/pact_broker/api/pact_broker_urls.rb

+4
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ def pact_versions_url consumer_name, provider_name, base_url = ""
7777
"#{base_url}/pacts/provider/#{url_encode(provider_name)}/consumer/#{url_encode(consumer_name)}/versions"
7878
end
7979

80+
def integration_url consumer_name, provider_name, base_url = ""
81+
"#{base_url}/integrations/provider/#{url_encode(provider_name)}/consumer/#{url_encode(consumer_name)}"
82+
end
83+
8084
def previous_distinct_diff_url pact, base_url
8185
pact_url(base_url, pact) + "/diff/previous-distinct"
8286
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
require 'pact_broker/api/resources/base_resource'
2+
3+
module PactBroker
4+
module Api
5+
module Resources
6+
class Integration < BaseResource
7+
def allowed_methods
8+
["OPTIONS", "DELETE"]
9+
end
10+
11+
def resource_exists?
12+
consumer && provider
13+
end
14+
15+
def delete_resource
16+
integration_service.delete(consumer_name, provider_name)
17+
true
18+
end
19+
end
20+
end
21+
end
22+
end

lib/pact_broker/pacts/pact_publication.rb

+5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ class PactPublication < Sequel::Model(:pact_publications)
1818

1919
dataset_module do
2020
include PactBroker::Repositories::Helpers
21+
22+
def tag tag_name
23+
filter = name_like(Sequel.qualify(:tags, :name), tag_name)
24+
join(:tags, {version_id: :consumer_version_id}).where(filter)
25+
end
2126
end
2227

2328
def before_create

lib/pact_broker/ui/view_models/index_item.rb

+4
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ def pact_versions_url
7171
PactBroker::Api::PactBrokerUrls.pact_versions_url(consumer_name, provider_name, PactBroker.configuration.base_url)
7272
end
7373

74+
def integration_url
75+
PactBroker::Api::PactBrokerUrls.integration_url(consumer_name, provider_name, PactBroker.configuration.base_url)
76+
end
77+
7478
def webhook_label
7579
return "" unless show_webhook_status?
7680
case @relationship.webhook_status
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
%link{rel: 'stylesheet', href: '/stylesheets/index.css'}
22
%link{rel: 'stylesheet', href: '/stylesheets/material-menu.css'}
33
%link{rel: 'stylesheet', href: '/stylesheets/material-icon.css'}
4+
%link{rel: 'stylesheet', href: '/stylesheets/jquery-confirm.min.css'}
45
%script{type: 'text/javascript', src:'/javascripts/jquery.tablesorter.min.js'}
56
%script{type: 'text/javascript', src:'/javascripts/material-menu.js'}
67
%script{type: 'text/javascript', src:'/javascripts/index.js'}
8+
%script{type: 'text/javascript', src:'/javascripts/jquery-confirm.min.js'}

lib/pact_broker/ui/views/index/show.haml

+27-28
Original file line numberDiff line numberDiff line change
@@ -27,35 +27,34 @@
2727
Last<br>verified
2828
%th
2929
%tbody
30+
- index_items.each do | index_item |
31+
%tr{'data-pact-versions-url': index_item.pact_versions_url, 'data-consumer-name': index_item.consumer_name, 'data-provider-name': index_item.provider_name, 'data-integration-url': index_item.integration_url}
32+
%td
33+
%td.consumer
34+
%a{ href: index_item.consumer_group_url }
35+
= escape_html(index_item.consumer_name)
36+
%td.pact
37+
%span.pact
38+
%a{ href: index_item.latest_pact_url, :title => "View pact" }
39+
%span.pact-matrix
40+
%a{ href: index_item.pact_matrix_url, title: "View pact matrix" }
41+
%td.provider
42+
%a{ href: index_item.provider_group_url }
43+
= escape_html(index_item.provider_name)
44+
%td
45+
%td
46+
= index_item.publication_date_of_latest_pact
47+
%td{class: index_item.webhook_status}
48+
%a{ href: index_item.webhook_url }
49+
= index_item.webhook_label
3050

31-
- index_items.each do | index_item |
32-
%tr
33-
%td
34-
%td.consumer
35-
%a{ href: index_item.consumer_group_url }
36-
= escape_html(index_item.consumer_name)
37-
%td.pact
38-
%span.pact
39-
%a{ href: index_item.latest_pact_url, :title => "View pact" }
40-
%span.pact-matrix
41-
%a{ href: index_item.pact_matrix_url, title: "View pact matrix" }
42-
%td.provider
43-
%a{ href: index_item.provider_group_url }
44-
= escape_html(index_item.provider_name)
45-
%td
46-
%td
47-
= index_item.publication_date_of_latest_pact
48-
%td{class: index_item.webhook_status}
49-
%a{ href: index_item.webhook_url }
50-
= index_item.webhook_label
51-
52-
%td{ class: index_item.verification_status, title: index_item.verification_tooltip, "data-toggle": "tooltip", "data-placement": "left" }
53-
%div
54-
= index_item.last_verified_date
55-
- if index_item.warning?
56-
%span.glyphicon.glyphicon-warning-sign{ 'aria-hidden': true }
57-
%td
58-
%span.integration-settings.glyphicon.glyphicon-cog{ 'aria-hidden': true, 'data-pact-versions-url': index_item.pact_versions_url, 'data-consumer-name': index_item.consumer_name, 'data-provider-name': index_item.provider_name}
51+
%td{ class: index_item.verification_status, title: index_item.verification_tooltip, "data-toggle": "tooltip", "data-placement": "left" }
52+
%div
53+
= index_item.last_verified_date
54+
- if index_item.warning?
55+
%span.glyphicon.glyphicon-warning-sign{ 'aria-hidden': true }
56+
%td
57+
%span.integration-settings.glyphicon.glyphicon-cog{ 'aria-hidden': true }
5958
%div.relationships-size
6059
= index_items.size_label
6160

public/javascripts/index.js

+119-18
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@ $(document).ready(function() {
66
items: [
77
{
88
type: "normal",
9-
text: "Delete all pact versions...",
10-
click: function(e) {
11-
promptToDeletePactVersions($(e).data(), $(e).closest("tr"));
12-
}
9+
text: "Delete pacts ...",
10+
click: handleDeletePactsSelected
11+
},
12+
{
13+
type: "normal",
14+
text: "Delete integration...",
15+
click: handleDeleteIntegrationsSelected
1316
}
1417
]
1518
})
@@ -18,23 +21,117 @@ $(document).ready(function() {
1821
});
1922
});
2023

21-
function promptToDeletePactVersions(rowData, row) {
24+
function handleDeletePactsSelected(clickedElement) {
25+
const tr = $(clickedElement).closest("tr");
26+
const confirmationText = createPactVersionsDeletionConfirmationText(tr.data());
27+
promptToDeleteResources(
28+
tr,
29+
tr.data().pactVersionsUrl,
30+
confirmationText
31+
);
32+
}
33+
34+
function handleDeleteIntegrationsSelected(clickedElement) {
35+
const tr = $(clickedElement).closest("tr");
36+
const confirmationText = createIntegrationDeletionConfirmationText(
37+
tr.data()
38+
);
39+
promptToDeleteResources(
40+
tr,
41+
tr.data().integrationUrl,
42+
confirmationText
43+
);
44+
}
45+
46+
function createIntegrationDeletionConfirmationText(rowData) {
47+
return `This will delete ${rowData.consumerName} and ${
48+
rowData.providerName
49+
}, and all associated data (pacts, verifications, application versions, tags and webhooks) that are not associated with other integrations. Do you wish to continue?`;
50+
}
51+
52+
function promptToDeleteIntegration(rowData, row) {
2253
const agree = confirm(
23-
`This will delete all versions of the pact between ${
24-
rowData.consumerName
25-
} and ${rowData.providerName}. It will keep ${rowData.consumerName} and ${
54+
`This will delete ${rowData.consumerName} and ${
2655
rowData.providerName
27-
}, and all other data related to them (webhooks, application versions, and tags). Do you wish to continue?`
56+
}, and all associated data (pacts, verifications, application versions, tags and webhooks). Do you wish to continue?`
2857
);
29-
if (agree) {
58+
}
59+
60+
function highlightRowsToBeDeleted(table, consumerName, providerName) {
61+
table
62+
.children("tbody")
63+
.find(`[data-consumer-name="${consumerName}"]`)
64+
.children("td")
65+
.addClass("to-be-deleted");
66+
table
67+
.children("tbody")
68+
.find(`[data-provider-name="${providerName}"]`)
69+
.children("td")
70+
.addClass("to-be-deleted");
71+
}
72+
73+
function highlightRowToBeDeleted(row) {
74+
row.children("td").addClass("to-be-deleted");
75+
}
76+
77+
function unHighlightRows(table) {
78+
table.find(".to-be-deleted").removeClass("to-be-deleted");
79+
}
80+
81+
function createPactVersionsDeletionConfirmationText(rowData) {
82+
return `This will delete all versions of the pact between ${
83+
rowData.consumerName
84+
} and ${rowData.providerName}. It will keep ${rowData.consumerName} and ${
85+
rowData.providerName
86+
}, and all other data related to them (webhooks, verifications, application versions, and tags). Do you wish to continue?`;
87+
}
88+
89+
function confirmDeletePactVersions(
90+
rowData,
91+
confirmationText,
92+
confirmCallbak,
93+
cancelCallback
94+
) {
95+
$.confirm({
96+
title: "Confirm!",
97+
content: confirmationText,
98+
buttons: {
99+
delete: {
100+
text: "DELETE",
101+
btnClass: "alert alert-danger",
102+
keys: ["enter", "shift"],
103+
action: confirmCallbak
104+
},
105+
cancel: cancelCallback
106+
}
107+
});
108+
}
109+
110+
function promptToDeleteResources(row, deletionUrl, confirmationText) {
111+
const rowData = row.data();
112+
const table = row.closest("table");
113+
const cancel = function() {
114+
unHighlightRows(table);
115+
};
116+
const confirm = function() {
30117
deletePactVersions(
31-
rowData.pactVersionsUrl,
118+
deletionUrl,
32119
function() {
33120
handleDeletionSuccess(row);
34121
},
35-
handleDeletionFailure
122+
function(response) {
123+
handleDeletionFailure(table, response);
124+
}
36125
);
37-
}
126+
};
127+
128+
highlightRowToBeDeleted(row);
129+
confirmDeletePactVersions(
130+
rowData,
131+
confirmationText,
132+
confirm,
133+
cancel
134+
);
38135
}
39136

40137
function handleDeletionSuccess(row) {
@@ -50,21 +147,25 @@ function handleDeletionSuccess(row) {
50147
});
51148
}
52149

53-
function handleDeletionFailure(response) {
150+
function handleDeletionFailure(table, response) {
151+
unHighlightRows(table);
54152
let errorMessage = null;
55153

56154
if (response.error && response.error.message && response.error.reference) {
57155
errorMessage =
58-
"Could not delete resources due to error: " +
156+
"<p>Could not delete resources due to error: " +
59157
response.error.message +
60-
"\nError reference: " +
61-
response.error.reference;
158+
"</p><p>Error reference: " +
159+
response.error.reference + "</p>";
62160
} else {
63161
errorMessage =
64162
"Could not delete resources due to error: " + JSON.stringify(response);
65163
}
66164

67-
alert(errorMessage);
165+
$.alert({
166+
title: 'Error',
167+
content: errorMessage,
168+
});
68169
}
69170

70171
function deletePactVersions(url, successCallback, errorCallback) {

public/javascripts/jquery-confirm.min.js

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/stylesheets/index.css

+5-1
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,8 @@ div.tag {
118118
div.getting-started {
119119
max-width: 600px;
120120
margin-bottom: 50px;
121-
}
121+
}
122+
123+
td.to-be-deleted {
124+
background-color: #f2dede !important
125+
}

public/stylesheets/jquery-confirm.min.css

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)