Skip to content

Commit 59ca6bf

Browse files
authored
Fix issue when repos have a space in their name (#45)
1 parent 106d599 commit 59ca6bf

File tree

12 files changed

+68
-62
lines changed

12 files changed

+68
-62
lines changed

make.ps1

+3-1
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,8 @@ function Build {
303303
$json | ConvertTo-Json -Depth 10 | Set-Content .\$vsix
304304
}
305305
catch {
306-
Write-Host "Error loading the version from Azure DevOps Marketplace"
306+
Write-Host "Error loading the version from Azure DevOps Marketplace, check the [$$env:AZURE_DEVOPS_PAT] setting if it has the right scopes"
307+
return
307308
}
308309

309310
# build the task
@@ -315,6 +316,7 @@ function Build {
315316
Set-Location ..
316317

317318
# package the whole extension
319+
Write-Host "Packaging the extension"
318320
tfx extension create --manifest-globs $vsix --rev-version
319321

320322
# get the new version number from the json file

vss-extension-dev.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"manifestVersion": 1,
33
"id": "GHAzDoWidget-DEV",
4-
"version": "0.2.415",
4+
"version": "0.2.427",
55
"public": false,
66
"name": "Advanced Security dashboard Widgets [DEV]",
77
"description": "[DEV] GitHub Advanced Security for Azure DevOps dashboard widgets",

widgets/build-info/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
const organization = webContext.account.name;
2424
const projectId = project.id;
2525
// convert project.name to url encoding
26-
const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26");
26+
const projectName = handleNames(project.name);
2727
// retrieve build id
2828
try {
2929
// contains: project, collection, account, host, and team info (with their GUID)

widgets/library.js

+20-4
Original file line numberDiff line numberDiff line change
@@ -89,17 +89,27 @@ function GetAlertTypeFromValue(value) {
8989
}
9090
}
9191

92-
function fillSelectRepoDropdown(dropDown, repos) {
92+
function fillSelectRepoDropdown(dropDown, repos, showAllRepos = false) {
9393
// add a top option to select no repo
94-
dropDown.append(`<option value="">Select a repository</option>`);
95-
dropDown.append(`<option value="">All repos in this project</option>`);
94+
dropDown.append(`<option value="0">Select a repository</option>`);
95+
if (showAllRepos) {
96+
dropDown.append(`<option value="1">All repos in this project</option>`);
97+
}
9698
// sort the repo alphabetically
9799
repos.sort((a, b) => a.name.localeCompare(b.name));
98100
repos.forEach(r => {
99-
dropDown.append(`<option value=${r.name}>${r.name}</option>`);
101+
dropDown.append(`<option value=${r.id}>${r.name}</option>`);
100102
});
101103
}
102104

105+
function getSelectedRepoIdFromDropdown(dropDown) {
106+
return dropDown.val();
107+
}
108+
109+
function getSelectedRepoNameFromDropdown(dropDown) {
110+
return dropDown.find("option:selected").text();
111+
}
112+
103113
async function getAlerts(organization, projectName, repoId, repos, project, repo) {
104114
if (repoId) {
105115
// run normally for a single repo
@@ -589,6 +599,12 @@ async function showRepoInfo(repos, project, organization, progressDiv, activeCal
589599
}
590600
}
591601

602+
function handleNames(input) {
603+
// replace spaces with %20 in the input
604+
return input.replace(/ /g, '%20') // space with %20
605+
.replace(/&/g, "%26") // & with %26
606+
}
607+
592608
let debugInfo = null
593609
function showCallStatus() {
594610
if (!debugInfo) {

widgets/pr-tab/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
const organization = webContext.account.name;
2222
const projectId = project.id;
2323
// convert project.name to url encoding
24-
const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26");
24+
const projectName = handleNames(project.name);
2525

2626
consoleLog('project id: ' + projectId);
2727
consoleLog('project name: ' + projectName);

widgets/widgets/chart/chart.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
const organization = webContext.account.name
3636
const projectId = project.id
3737
// convert project.name to url encoding
38-
const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26")
38+
const projectName = handleNames(project.name)
3939

4040
consoleLog('project id: ' + projectId)
4141
consoleLog('project name: ' + projectName)

widgets/widgets/testing_widget/testing.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@
200200
const organization = webContext.account.name;
201201
const projectId = project.id;
202202
// convert project.name to url encoding
203-
const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26");
203+
const projectName = handleNames(project.name);
204204

205205
consoleLog('project id: ' + projectId);
206206
consoleLog('project name: ' + projectName);

widgets/widgets/widget_1x1/configuration_1x1.html

+12-18
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,13 @@
1717
var $repoDropdown = $("#repo-dropdown");
1818
var $repoAlertType = $("#repo-alert-type");
1919
var $colorPicker = $("#color-picker");
20-
const repos = await getRepos(VSS, Service, GitWebApi);
21-
const projects = await getProjects(VSS, Service, RestClient);
22-
23-
consoleLog(`Found [${repos?.length}] repos and [${projects?.length}] projects`);
2420

2521
async function reloadWidget(widgetConfigurationContext) {
26-
let repo;
27-
if (repos) {
28-
// find the repo with this name
29-
repo = repos.find(r => r.name === $repoDropdown.val());
30-
}
3122

3223
var customSettings = {
3324
data: JSON.stringify({
34-
repo: $repoDropdown.val(),
35-
repoId: repo?.id,
25+
repo: getSelectedRepoNameFromDropdown($repoDropdown),
26+
repoId: getSelectedRepoIdFromDropdown($repoDropdown),
3627
repoAlertType: $repoAlertType.val(),
3728
color: $colorPicker.val()
3829
})
@@ -47,14 +38,15 @@
4738
var settings = logWidgetSettings(widgetSettings, VSS, "1x1");
4839

4940
// add all repos as selection options to the dropdown
41+
const repos = await getRepos(VSS, Service, GitWebApi);
5042
if (repos) {
5143
// todo: use in all other widget locations as well
5244
fillSelectRepoDropdown($repoDropdown, repos)
5345
}
5446

5547
if (settings && settings.repo) {
5648
// select the repo that was saved in the settings
57-
$repoDropdown.val(settings.repo);
49+
$repoDropdown.val(settings.repoId);
5850
}
5951

6052
if (settings && settings.repoAlertType) {
@@ -83,15 +75,17 @@
8375
return WidgetHelpers.WidgetStatusHelper.Success();
8476
},
8577
onSave: async function() {
86-
let repo;
87-
if (repos) {
88-
// find the repo with this name
89-
repo = repos.find(r => r.name === $repoDropdown.val());
78+
let repoId = getSelectedRepoIdFromDropdown($repoDropdown);
79+
if (repoId == 0 || repoId == 1) { // 0 = select a repo, 1 = all repos
80+
// do not save
81+
console.log(`Not saving the settings because repoId is [${repoId}]`);
82+
return WidgetHelpers.WidgetConfigurationSave.Invalid();
9083
}
84+
9185
var customSettings = {
9286
data: JSON.stringify({
93-
repo: $repoDropdown.val(),
94-
repoId: repo?.id,
87+
repo: getSelectedRepoNameFromDropdown($repoDropdown),
88+
repoId: repoId,
9589
repoAlertType: $repoAlertType.val(),
9690
color: $colorPicker.val()
9791
})

widgets/widgets/widget_1x1/widget_1x1.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
const organization = webContext.account.name;
2424
const projectId = project.id;
2525
// convert project.name to url encoding
26-
const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26");
26+
const projectName = handleNames(project.name);
2727

2828
consoleLog('project id: ' + projectId);
2929
consoleLog('project name: ' + projectName);

widgets/widgets/widget_1x1/widget_1x1.js

+1-5
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,17 @@ async function loadWidget(widgetSettings, organization, projectName, VSS, Servic
4343
}
4444
consoleLog('alerts: ' + JSON.stringify(alerts));
4545

46-
// remove %20 from the name so that it displays correctly
47-
repoName = repoName.replace(/%20/g, ' '); //todo: support more of these weird characters
48-
4946
// set the title
5047
var title = $('h2.ghazdo-title');
5148
title.text(`${repoName}`);
52-
title.attr('title', repoName);
53-
consoleLog(`title set to [${repoName}]`);
5449

5550
// set the color
5651
const color = data.color ? data.color : '#68217a'; // default to purple
5752
const widget = document.getElementById('GHAzDo-widget');
5853
widget.style.backgroundColor = `${color}`;
5954

6055
// GHAS is only available on the SaaS version, so we can hardcode the domain
56+
repoName = handleNames(repoName); // handle spaces and other characters in the repo name
6157
linkBase = `https://dev.azure.com/${organization}/${projectName}/_git/${repoName}/alerts`;
6258
}
6359
else {

widgets/widgets/widget_2x1/configuration_2x1.html

+24-27
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,21 @@
1414
VSS.require(["VSS/Service", "TFS/Dashboards/WidgetHelpers", "VSS/Context", "TFS/VersionControl/GitRestClient"],
1515
function (Service, WidgetHelpers, context, GitWebApi) {
1616
VSS.register("GHAzDoWidget.Configuration", async function () {
17-
var $repoDropdown = $("#repo-dropdown")
18-
var $colorPicker = $("#color-picker")
19-
// get a repos in this project
20-
const repos = await getRepos(VSS, Service, GitWebApi);
17+
var $repoDropdown = $("#repo-dropdown");
18+
var $colorPicker = $("#color-picker");
2119

2220
async function reloadWidget(widgetConfigurationContext) {
23-
let repo;
24-
if (repos) {
25-
// find the repo with this name
26-
repo = repos.find(r => r.name === $repoDropdown.val());
21+
let repoId = getSelectedRepoIdFromDropdown($repoDropdown);
22+
if (repoId == 0 || repoId == 1) { // 0 = select a repo, 1 = all repos
23+
// do not reload with errors
24+
console.log(`Not reloading the settings because repoId is [${repoId}]`);
25+
return;
2726
}
27+
2828
var customSettings = {
2929
data: JSON.stringify({
30-
repo: $repoDropdown.val(),
31-
repoId: repo.id,
30+
repo: getSelectedRepoNameFromDropdown($repoDropdown),
31+
repoId: getSelectedRepoIdFromDropdown($repoDropdown),
3232
color: $colorPicker.val()
3333
})
3434
};
@@ -42,26 +42,22 @@
4242
var settings = logWidgetSettings(widgetSettings, VSS, "2x1");
4343

4444
// add all repos as selection options to the dropdown
45+
const repos = await getRepos(VSS, Service, GitWebApi);
4546
if (repos) {
46-
// add a top option to select no repo
47-
$repoDropdown.append(`<option value="">Select a repository</option>`);
48-
// sort the repo alphabetically
49-
repos.sort((a, b) => a.name.localeCompare(b.name));
50-
repos.forEach(r => {
51-
$repoDropdown.append(`<option value=${r.name}>${r.name}</option>`);
52-
});
47+
fillSelectRepoDropdown($repoDropdown, repos, false);
5348
}
5449

55-
if (settings && settings.repo) {
50+
if (settings && settings.repoId) {
5651
// select the repo that was saved in the settings
57-
$repoDropdown.val(settings.repo);
58-
}
52+
$repoDropdown.val(settings.repoId);
53+
}
5954

6055
if (settings && settings.color) {
6156
// select the color that was saved in the settings
6257
$colorPicker.val(settings.color);
6358
}
6459

60+
// configure events for the dropdowns to call back to the widget
6561
$colorPicker.on("change", async function () {
6662
await reloadWidget(widgetConfigurationContext);
6763
});
@@ -73,16 +69,17 @@
7369
return WidgetHelpers.WidgetStatusHelper.Success();
7470
},
7571
onSave: async function() {
76-
const repos = await getRepos(VSS, Service, GitWebApi);
77-
let repo;
78-
if (repos) {
79-
// find the repo with this name
80-
repo = repos.find(r => r.name === $repoDropdown.val());
72+
let repoId = getSelectedRepoIdFromDropdown($repoDropdown);
73+
if (repoId == 0 || repoId == 1) { // 0 = select a repo, 1 = all repos
74+
// do not save
75+
console.log(`Not saving the settings because repoId is [${repoId}]`);
76+
return WidgetHelpers.WidgetConfigurationSave.Invalid();
8177
}
78+
8279
var customSettings = {
8380
data: JSON.stringify({
84-
repo: $repoDropdown.val(),
85-
repoId: repo.id,
81+
repo: getSelectedRepoNameFromDropdown($repoDropdown),
82+
repoId: repoId,
8683
color: $colorPicker.val()
8784
})
8885
};

widgets/widgets/widget_2x1/widget_2x1.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,15 @@
2323
const organization = webContext.account.name
2424
const projectId = project.id
2525
// convert project.name to url encoding
26-
const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26")
26+
const projectName = handleNames(project.name)
2727

2828
consoleLog('project id: ' + projectId)
2929
consoleLog('project name: ' + projectName)
3030
consoleLog('organization name: ' + organization)
3131

3232
return {
3333
load: async function (widgetSettings) {
34+
consoleLog('load with widgetSettings: ' + JSON.stringify(widgetSettings))
3435
await loadWidget(widgetSettings, organization, projectName)
3536

3637
return WidgetHelpers.WidgetStatusHelper.Success()

0 commit comments

Comments
 (0)