diff --git a/make.ps1 b/make.ps1
index 1752268..17f3f15 100644
--- a/make.ps1
+++ b/make.ps1
@@ -303,7 +303,8 @@ function Build {
$json | ConvertTo-Json -Depth 10 | Set-Content .\$vsix
}
catch {
- Write-Host "Error loading the version from Azure DevOps Marketplace"
+ Write-Host "Error loading the version from Azure DevOps Marketplace, check the [$$env:AZURE_DEVOPS_PAT] setting if it has the right scopes"
+ return
}
# build the task
@@ -315,6 +316,7 @@ function Build {
Set-Location ..
# package the whole extension
+ Write-Host "Packaging the extension"
tfx extension create --manifest-globs $vsix --rev-version
# get the new version number from the json file
diff --git a/vss-extension-dev.json b/vss-extension-dev.json
index e2f53cf..665ac4a 100644
--- a/vss-extension-dev.json
+++ b/vss-extension-dev.json
@@ -1,7 +1,7 @@
{
"manifestVersion": 1,
"id": "GHAzDoWidget-DEV",
- "version": "0.2.415",
+ "version": "0.2.427",
"public": false,
"name": "Advanced Security dashboard Widgets [DEV]",
"description": "[DEV] GitHub Advanced Security for Azure DevOps dashboard widgets",
diff --git a/widgets/build-info/index.html b/widgets/build-info/index.html
index d867a70..428a1bd 100644
--- a/widgets/build-info/index.html
+++ b/widgets/build-info/index.html
@@ -23,7 +23,7 @@
const organization = webContext.account.name;
const projectId = project.id;
// convert project.name to url encoding
- const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26");
+ const projectName = handleNames(project.name);
// retrieve build id
try {
// contains: project, collection, account, host, and team info (with their GUID)
diff --git a/widgets/library.js b/widgets/library.js
index 6af3bfe..206d1ee 100644
--- a/widgets/library.js
+++ b/widgets/library.js
@@ -89,17 +89,27 @@ function GetAlertTypeFromValue(value) {
}
}
-function fillSelectRepoDropdown(dropDown, repos) {
+function fillSelectRepoDropdown(dropDown, repos, showAllRepos = false) {
// add a top option to select no repo
- dropDown.append(``);
- dropDown.append(``);
+ dropDown.append(``);
+ if (showAllRepos) {
+ dropDown.append(``);
+ }
// sort the repo alphabetically
repos.sort((a, b) => a.name.localeCompare(b.name));
repos.forEach(r => {
- dropDown.append(``);
+ dropDown.append(``);
});
}
+function getSelectedRepoIdFromDropdown(dropDown) {
+ return dropDown.val();
+}
+
+function getSelectedRepoNameFromDropdown(dropDown) {
+ return dropDown.find("option:selected").text();
+}
+
async function getAlerts(organization, projectName, repoId, repos, project, repo) {
if (repoId) {
// run normally for a single repo
@@ -589,6 +599,12 @@ async function showRepoInfo(repos, project, organization, progressDiv, activeCal
}
}
+function handleNames(input) {
+ // replace spaces with %20 in the input
+ return input.replace(/ /g, '%20') // space with %20
+ .replace(/&/g, "%26") // & with %26
+}
+
let debugInfo = null
function showCallStatus() {
if (!debugInfo) {
diff --git a/widgets/pr-tab/index.html b/widgets/pr-tab/index.html
index 3cd475d..6bc0cb4 100644
--- a/widgets/pr-tab/index.html
+++ b/widgets/pr-tab/index.html
@@ -21,7 +21,7 @@
const organization = webContext.account.name;
const projectId = project.id;
// convert project.name to url encoding
- const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26");
+ const projectName = handleNames(project.name);
consoleLog('project id: ' + projectId);
consoleLog('project name: ' + projectName);
diff --git a/widgets/widgets/chart/chart.html b/widgets/widgets/chart/chart.html
index b26badc..c9105b5 100644
--- a/widgets/widgets/chart/chart.html
+++ b/widgets/widgets/chart/chart.html
@@ -35,7 +35,7 @@
const organization = webContext.account.name
const projectId = project.id
// convert project.name to url encoding
- const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26")
+ const projectName = handleNames(project.name)
consoleLog('project id: ' + projectId)
consoleLog('project name: ' + projectName)
diff --git a/widgets/widgets/testing_widget/testing.html b/widgets/widgets/testing_widget/testing.html
index e3b7c36..77ac65e 100644
--- a/widgets/widgets/testing_widget/testing.html
+++ b/widgets/widgets/testing_widget/testing.html
@@ -200,7 +200,7 @@
const organization = webContext.account.name;
const projectId = project.id;
// convert project.name to url encoding
- const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26");
+ const projectName = handleNames(project.name);
consoleLog('project id: ' + projectId);
consoleLog('project name: ' + projectName);
diff --git a/widgets/widgets/widget_1x1/configuration_1x1.html b/widgets/widgets/widget_1x1/configuration_1x1.html
index d189cba..02e1fa4 100644
--- a/widgets/widgets/widget_1x1/configuration_1x1.html
+++ b/widgets/widgets/widget_1x1/configuration_1x1.html
@@ -17,22 +17,13 @@
var $repoDropdown = $("#repo-dropdown");
var $repoAlertType = $("#repo-alert-type");
var $colorPicker = $("#color-picker");
- const repos = await getRepos(VSS, Service, GitWebApi);
- const projects = await getProjects(VSS, Service, RestClient);
-
- consoleLog(`Found [${repos?.length}] repos and [${projects?.length}] projects`);
async function reloadWidget(widgetConfigurationContext) {
- let repo;
- if (repos) {
- // find the repo with this name
- repo = repos.find(r => r.name === $repoDropdown.val());
- }
var customSettings = {
data: JSON.stringify({
- repo: $repoDropdown.val(),
- repoId: repo?.id,
+ repo: getSelectedRepoNameFromDropdown($repoDropdown),
+ repoId: getSelectedRepoIdFromDropdown($repoDropdown),
repoAlertType: $repoAlertType.val(),
color: $colorPicker.val()
})
@@ -47,6 +38,7 @@
var settings = logWidgetSettings(widgetSettings, VSS, "1x1");
// add all repos as selection options to the dropdown
+ const repos = await getRepos(VSS, Service, GitWebApi);
if (repos) {
// todo: use in all other widget locations as well
fillSelectRepoDropdown($repoDropdown, repos)
@@ -54,7 +46,7 @@
if (settings && settings.repo) {
// select the repo that was saved in the settings
- $repoDropdown.val(settings.repo);
+ $repoDropdown.val(settings.repoId);
}
if (settings && settings.repoAlertType) {
@@ -83,15 +75,17 @@
return WidgetHelpers.WidgetStatusHelper.Success();
},
onSave: async function() {
- let repo;
- if (repos) {
- // find the repo with this name
- repo = repos.find(r => r.name === $repoDropdown.val());
+ let repoId = getSelectedRepoIdFromDropdown($repoDropdown);
+ if (repoId == 0 || repoId == 1) { // 0 = select a repo, 1 = all repos
+ // do not save
+ console.log(`Not saving the settings because repoId is [${repoId}]`);
+ return WidgetHelpers.WidgetConfigurationSave.Invalid();
}
+
var customSettings = {
data: JSON.stringify({
- repo: $repoDropdown.val(),
- repoId: repo?.id,
+ repo: getSelectedRepoNameFromDropdown($repoDropdown),
+ repoId: repoId,
repoAlertType: $repoAlertType.val(),
color: $colorPicker.val()
})
diff --git a/widgets/widgets/widget_1x1/widget_1x1.html b/widgets/widgets/widget_1x1/widget_1x1.html
index b6794d4..0d54137 100644
--- a/widgets/widgets/widget_1x1/widget_1x1.html
+++ b/widgets/widgets/widget_1x1/widget_1x1.html
@@ -23,7 +23,7 @@
const organization = webContext.account.name;
const projectId = project.id;
// convert project.name to url encoding
- const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26");
+ const projectName = handleNames(project.name);
consoleLog('project id: ' + projectId);
consoleLog('project name: ' + projectName);
diff --git a/widgets/widgets/widget_1x1/widget_1x1.js b/widgets/widgets/widget_1x1/widget_1x1.js
index 79449e8..3ae80d6 100644
--- a/widgets/widgets/widget_1x1/widget_1x1.js
+++ b/widgets/widgets/widget_1x1/widget_1x1.js
@@ -43,14 +43,9 @@ async function loadWidget(widgetSettings, organization, projectName, VSS, Servic
}
consoleLog('alerts: ' + JSON.stringify(alerts));
- // remove %20 from the name so that it displays correctly
- repoName = repoName.replace(/%20/g, ' '); //todo: support more of these weird characters
-
// set the title
var title = $('h2.ghazdo-title');
title.text(`${repoName}`);
- title.attr('title', repoName);
- consoleLog(`title set to [${repoName}]`);
// set the color
const color = data.color ? data.color : '#68217a'; // default to purple
@@ -58,6 +53,7 @@ async function loadWidget(widgetSettings, organization, projectName, VSS, Servic
widget.style.backgroundColor = `${color}`;
// GHAS is only available on the SaaS version, so we can hardcode the domain
+ repoName = handleNames(repoName); // handle spaces and other characters in the repo name
linkBase = `https://dev.azure.com/${organization}/${projectName}/_git/${repoName}/alerts`;
}
else {
diff --git a/widgets/widgets/widget_2x1/configuration_2x1.html b/widgets/widgets/widget_2x1/configuration_2x1.html
index 7a567f7..38a93bd 100644
--- a/widgets/widgets/widget_2x1/configuration_2x1.html
+++ b/widgets/widgets/widget_2x1/configuration_2x1.html
@@ -14,21 +14,21 @@
VSS.require(["VSS/Service", "TFS/Dashboards/WidgetHelpers", "VSS/Context", "TFS/VersionControl/GitRestClient"],
function (Service, WidgetHelpers, context, GitWebApi) {
VSS.register("GHAzDoWidget.Configuration", async function () {
- var $repoDropdown = $("#repo-dropdown")
- var $colorPicker = $("#color-picker")
- // get a repos in this project
- const repos = await getRepos(VSS, Service, GitWebApi);
+ var $repoDropdown = $("#repo-dropdown");
+ var $colorPicker = $("#color-picker");
async function reloadWidget(widgetConfigurationContext) {
- let repo;
- if (repos) {
- // find the repo with this name
- repo = repos.find(r => r.name === $repoDropdown.val());
+ let repoId = getSelectedRepoIdFromDropdown($repoDropdown);
+ if (repoId == 0 || repoId == 1) { // 0 = select a repo, 1 = all repos
+ // do not reload with errors
+ console.log(`Not reloading the settings because repoId is [${repoId}]`);
+ return;
}
+
var customSettings = {
data: JSON.stringify({
- repo: $repoDropdown.val(),
- repoId: repo.id,
+ repo: getSelectedRepoNameFromDropdown($repoDropdown),
+ repoId: getSelectedRepoIdFromDropdown($repoDropdown),
color: $colorPicker.val()
})
};
@@ -42,26 +42,22 @@
var settings = logWidgetSettings(widgetSettings, VSS, "2x1");
// add all repos as selection options to the dropdown
+ const repos = await getRepos(VSS, Service, GitWebApi);
if (repos) {
- // add a top option to select no repo
- $repoDropdown.append(``);
- // sort the repo alphabetically
- repos.sort((a, b) => a.name.localeCompare(b.name));
- repos.forEach(r => {
- $repoDropdown.append(``);
- });
+ fillSelectRepoDropdown($repoDropdown, repos, false);
}
- if (settings && settings.repo) {
+ if (settings && settings.repoId) {
// select the repo that was saved in the settings
- $repoDropdown.val(settings.repo);
- }
+ $repoDropdown.val(settings.repoId);
+ }
if (settings && settings.color) {
// select the color that was saved in the settings
$colorPicker.val(settings.color);
}
+ // configure events for the dropdowns to call back to the widget
$colorPicker.on("change", async function () {
await reloadWidget(widgetConfigurationContext);
});
@@ -73,16 +69,17 @@
return WidgetHelpers.WidgetStatusHelper.Success();
},
onSave: async function() {
- const repos = await getRepos(VSS, Service, GitWebApi);
- let repo;
- if (repos) {
- // find the repo with this name
- repo = repos.find(r => r.name === $repoDropdown.val());
+ let repoId = getSelectedRepoIdFromDropdown($repoDropdown);
+ if (repoId == 0 || repoId == 1) { // 0 = select a repo, 1 = all repos
+ // do not save
+ console.log(`Not saving the settings because repoId is [${repoId}]`);
+ return WidgetHelpers.WidgetConfigurationSave.Invalid();
}
+
var customSettings = {
data: JSON.stringify({
- repo: $repoDropdown.val(),
- repoId: repo.id,
+ repo: getSelectedRepoNameFromDropdown($repoDropdown),
+ repoId: repoId,
color: $colorPicker.val()
})
};
diff --git a/widgets/widgets/widget_2x1/widget_2x1.html b/widgets/widgets/widget_2x1/widget_2x1.html
index e1f81f8..3750072 100644
--- a/widgets/widgets/widget_2x1/widget_2x1.html
+++ b/widgets/widgets/widget_2x1/widget_2x1.html
@@ -23,7 +23,7 @@
const organization = webContext.account.name
const projectId = project.id
// convert project.name to url encoding
- const projectName = project.name.replace(/ /g, "%20").replace(/&/g, "%26")
+ const projectName = handleNames(project.name)
consoleLog('project id: ' + projectId)
consoleLog('project name: ' + projectName)
@@ -31,6 +31,7 @@
return {
load: async function (widgetSettings) {
+ consoleLog('load with widgetSettings: ' + JSON.stringify(widgetSettings))
await loadWidget(widgetSettings, organization, projectName)
return WidgetHelpers.WidgetStatusHelper.Success()