Skip to content

Commit 21f2669

Browse files
committed
Added new 1 by 1 widget
1 parent 6cfc12a commit 21f2669

File tree

9 files changed

+448
-46
lines changed

9 files changed

+448
-46
lines changed

img/example_1x1.png

33.7 KB
Loading

img/example_2x1.png

-15.8 KB
Loading

overview.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
Extension for Azure DevOps that shows the number of open security alerts for the configured repository. Please install it and let me know what you think! Create an issue for feedback or feature requests.
1+
Extension for Azure DevOps that shows the number of open security alerts for the configured repository. Please install it and let me know what you think! Create an issue for feedback or feature requests.
22

33
Install from the marketplace: https://marketplace.visualstudio.com/items?itemName=RobBos.GHAzDoWidget
44

5-
## Example:
6-
![Screenshot of the widget showing the repository name and the alert count for dependencies, secrets, and code scanning](/img/example_2x1.png)
5+
## Examples:
6+
7+
### Show all three alert counts in one widget in 2 by 1 layout:
8+
![Screenshot of the widget in 2 by 1 showing the repository name and the alert count for dependencies, secrets, and code scanning](/img/example_2x1.png)
9+
10+
### Split it into three separate widgets (1 by 1) with just the single value you scan for:
11+
![Screenshot of the widget in 1 by 1 showing the repository name and the alert count for dependencies, secrets, and code scanning](/img/example_1x1.png)
712

813
## GitHub repo
9-
Please report issues, feature request, and feedback here: https://github.com/rajbos/GHAzDo-widget.
14+
Please report issues, feature request, and feedback here: https://github.com/rajbos/GHAzDo-widget.
15+
16+
> Note: only project level dashboards are supported at the moment.

vss-extension-dev.json

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"manifestVersion": 1,
33
"id": "GHAzDoWidget-DEV",
4-
"version": "0.0.1.0",
4+
"version": "0.0.1.34",
55
"public": false,
66
"name": "Advanced Security dashboard Widgets [DEV]",
77
"description": "[DEV] GitHub Advanced Security for Azure DevOps dashboard widgets",
@@ -46,14 +46,14 @@
4646
"type": "ms.vss-dashboards-web.widget",
4747
"targets": [
4848
"ms.vss-dashboards-web.widget-catalog",
49-
"RobBos.GHAzDoWidget.GHAzDoWidget.Configuration"
49+
"RobBos.GHAzDoWidget-DEV.GHAzDoWidget.Configuration"
5050
],
5151
"properties": {
52-
"name": "Advanced Security alert information",
53-
"description": "Display the amount of active security alerts from GitHub Advanced Security",
52+
"name": "[DEV] GHAzDO alert information",
53+
"description": "[DEV] Display the amount of active security alerts from GitHub Advanced Security",
5454
"catalogIconUrl": "img/publogo.png",
55-
"previewImageUrl": "img/preview.png",
56-
"uri": "widget_2_by_1.html",
55+
"previewImageUrl": "img/preview.png",
56+
"uri": "widget_2x1/widget_2x1.html",
5757
"supportedSizes": [
5858
{
5959
"rowSpan": 1,
@@ -70,16 +70,48 @@
7070
"properties": {
7171
"name": "GHAzDoWidget Configuration",
7272
"description": "Configures GHAzDoWidget",
73-
"uri": "configuration.html"
73+
"uri": "widget_2x1/configuration_2x1.html"
74+
}
75+
},
76+
{
77+
"id": "GHAzDoWidget.1x1",
78+
"type": "ms.vss-dashboards-web.widget",
79+
"targets": [
80+
"ms.vss-dashboards-web.widget-catalog",
81+
"RobBos.GHAzDoWidget-DEV.GHAzDoWidget.Configuration_1x1"
82+
],
83+
"properties": {
84+
"name": "[DEV] GHAzDO single alert type information",
85+
"description": "[DEV] Display the amount of active security alerts from GitHub Advanced Security for a single type of alert",
86+
"catalogIconUrl": "img/publogo.png",
87+
"previewImageUrl": "img/preview.png",
88+
"uri": "widget_1x1/widget_1x1.html",
89+
"supportedSizes": [
90+
{
91+
"rowSpan": 1,
92+
"columnSpan": 1
93+
}
94+
],
95+
"supportedScopes": ["project_team"]
96+
}
97+
},
98+
{
99+
"id": "GHAzDoWidget.Configuration_1x1",
100+
"type": "ms.vss-dashboards-web.widget-configuration",
101+
"targets": [ "ms.vss-dashboards-web.widget-configuration" ],
102+
"properties": {
103+
"name": "GHAzDoWidget Configuration",
104+
"description": "Configures GHAzDoWidget",
105+
"uri": "widget_1x1/configuration_1x1.html"
74106
}
75107
}
76108
],
77109
"files": [
78110
{
79-
"path": "widget_2_by_1.html", "addressable": true
111+
"path": "widget_1x1", "addressable": true
80112
},
81113
{
82-
"path": "configuration.html", "addressable": true
114+
"path": "widget_2x1", "addressable": true
83115
},
84116
{
85117
"path": "library.js", "addressable": true

vss-extension.json

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"manifestVersion": 1,
33
"id": "GHAzDoWidget",
4-
"version": "0.0.1.3",
4+
"version": "0.0.1.4",
55
"public": true,
66
"name": "Advanced Security dashboard Widgets",
77
"description": "GitHub Advanced Security for Azure DevOps dashboard widgets",
@@ -49,11 +49,11 @@
4949
"RobBos.GHAzDoWidget.GHAzDoWidget.Configuration"
5050
],
5151
"properties": {
52-
"name": "Advanced Security alert information",
52+
"name": "GHAzDO alert information",
5353
"description": "Display the amount of active security alerts from GitHub Advanced Security",
5454
"catalogIconUrl": "img/publogo.png",
55-
"previewImageUrl": "img/preview.png",
56-
"uri": "widget_2_by_1.html",
55+
"previewImageUrl": "img/preview.png",
56+
"uri": "widget_2x1/widget_2x1.html",
5757
"supportedSizes": [
5858
{
5959
"rowSpan": 1,
@@ -70,16 +70,48 @@
7070
"properties": {
7171
"name": "GHAzDoWidget Configuration",
7272
"description": "Configures GHAzDoWidget",
73-
"uri": "configuration.html"
73+
"uri": "widget_2x1/configuration_2x1.html"
74+
}
75+
},
76+
{
77+
"id": "GHAzDoWidget.1x1",
78+
"type": "ms.vss-dashboards-web.widget",
79+
"targets": [
80+
"ms.vss-dashboards-web.widget-catalog",
81+
"RobBos.GHAzDoWidget.GHAzDoWidget.Configuration_1x1"
82+
],
83+
"properties": {
84+
"name": "GHAzDO single alert type information",
85+
"description": "Display the amount of active security alerts from GitHub Advanced Security for a single type of alert",
86+
"catalogIconUrl": "img/publogo.png",
87+
"previewImageUrl": "img/preview.png",
88+
"uri": "widget_1x1/widget_1x1.html",
89+
"supportedSizes": [
90+
{
91+
"rowSpan": 1,
92+
"columnSpan": 1
93+
}
94+
],
95+
"supportedScopes": ["project_team"]
96+
}
97+
},
98+
{
99+
"id": "GHAzDoWidget.Configuration_1x1",
100+
"type": "ms.vss-dashboards-web.widget-configuration",
101+
"targets": [ "ms.vss-dashboards-web.widget-configuration" ],
102+
"properties": {
103+
"name": "GHAzDoWidget Configuration",
104+
"description": "Configures GHAzDoWidget",
105+
"uri": "widget_1x1/configuration_1x1.html"
74106
}
75107
}
76108
],
77109
"files": [
78110
{
79-
"path": "widget_2_by_1.html", "addressable": true
111+
"path": "widget_1x1", "addressable": true
80112
},
81113
{
82-
"path": "configuration.html", "addressable": true
114+
"path": "widget_2x1", "addressable": true
83115
},
84116
{
85117
"path": "library.js", "addressable": true

widget_1x1/configuration_1x1.html

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
<!DOCTYPE html>
2+
<html xmlns="http://www.w3.org/1999/xhtml">
3+
<head>
4+
<script src="../lib/VSS.SDK.min.js"></script>
5+
6+
<script type="text/javascript">
7+
VSS.init({
8+
explicitNotifyLoaded: true,
9+
usePlatformStyles: true
10+
});
11+
12+
VSS.require(["VSS/Service", "TFS/Dashboards/WidgetHelpers", "VSS/Context", "TFS/VersionControl/GitRestClient"],
13+
function (Service, WidgetHelpers, context, GitWebApi) {
14+
VSS.register("GHAzDoWidget.Configuration_1x1", function () {
15+
var $repoDropdown = $("#repo-dropdown");
16+
var $repoAlertType = $("#repo-alert-type");
17+
18+
async function getRepos() {
19+
try {
20+
const webContext = VSS.getWebContext();
21+
const project = webContext.project;
22+
23+
// todo: load the available repos in this project
24+
const gitClient = Service.getClient(GitWebApi.GitHttpClient);
25+
repos = await gitClient.getRepositories(project.name);
26+
console.log(`Found these repos: ${JSON.stringify(repos)}`);
27+
return repos;
28+
}
29+
catch (err) {
30+
console.log(`Error loading the available repos: ${err}`);
31+
return [];
32+
}
33+
}
34+
35+
function reloadWidget(widgetConfigurationContext) {
36+
let repo;
37+
if (repos) {
38+
// find the repo with this name
39+
repo = repos.find(r => r.name === $repoDropdown.val());
40+
}
41+
42+
var customSettings = {
43+
data: JSON.stringify({
44+
repo: $repoDropdown.val(),
45+
repoId: repo.id,
46+
repoAlertType: $repoAlertType.val()
47+
})
48+
};
49+
var eventName = WidgetHelpers.WidgetEvent.ConfigurationChange;
50+
var eventArgs = WidgetHelpers.WidgetEvent.Args(customSettings);
51+
widgetConfigurationContext.notify(eventName, eventArgs);
52+
}
53+
54+
return {
55+
load: async function (widgetSettings, widgetConfigurationContext) {
56+
var settings = JSON.parse(widgetSettings.customSettings.data);
57+
console.log(`Loading the 1x1 settings with ${JSON.stringify(settings)}`)
58+
59+
const repos = await getRepos();
60+
// add all repos as selection options to the dropdown
61+
if (repos) {
62+
// sort the repo alphabetically
63+
repos.sort((a, b) => a.name.localeCompare(b.name));
64+
repos.forEach(r => {
65+
$repoDropdown.append(`<option value=${r.name}>${r.name}</option>`);
66+
});
67+
}
68+
69+
if (settings && settings.repo) {
70+
// select the repo that was saved in the settings
71+
$repoDropdown.val(settings.repo);
72+
}
73+
74+
if (settings && settings.repoAlertType) {
75+
// select the alert type that was saved in the settings
76+
$repoAlertType.val(settings.repoAlertType);
77+
}
78+
79+
// register a change event handler for the dropdowns
80+
$repoDropdown.on("change", function () {
81+
reloadWidget(widgetConfigurationContext)
82+
});
83+
84+
$repoAlertType.on("change", function () {
85+
reloadWidget(widgetConfigurationContext)
86+
});
87+
88+
return WidgetHelpers.WidgetStatusHelper.Success();
89+
},
90+
onSave: async function() {
91+
const repos = await getRepos();
92+
let repo;
93+
if (repos) {
94+
// find the repo with this name
95+
repo = repos.find(r => r.name === $repoDropdown.val());
96+
}
97+
var customSettings = {
98+
data: JSON.stringify({
99+
repo: $repoDropdown.val(),
100+
repoId: repo.id,
101+
repoAlertType: $repoAlertType.val()
102+
})
103+
};
104+
console.log(`Saving the 1x1 settings with ${JSON.stringify(customSettings)}`)
105+
return WidgetHelpers.WidgetConfigurationSave.Valid(customSettings);
106+
}
107+
}
108+
});
109+
VSS.notifyLoadSucceeded();
110+
});
111+
</script>
112+
</head>
113+
<body>
114+
<style>
115+
.dropdown {
116+
margin-top: 10px;
117+
min-width: 150px;
118+
}
119+
</style>
120+
<div class="container">
121+
<table>
122+
<tr>
123+
<td>
124+
<label class="label">Repository: </label>
125+
</td>
126+
<td>
127+
<select id="repo-dropdown" class="dropdown"></select>
128+
</td>
129+
</tr>
130+
<tr>
131+
<td>
132+
<label class="label">Alert type to show: </label>
133+
</td>
134+
<td>
135+
<select id="repo-alert-type" class="dropdown">
136+
<option value="1">Dependency alerts</option>
137+
<option value="2">Secret scanning alerts</option>
138+
<option value="3">Code scanning alerts</option>
139+
</select>
140+
</td>
141+
</tr>
142+
</table>
143+
</div>
144+
</body>
145+
</html>

0 commit comments

Comments
 (0)