Skip to content

Commit

Permalink
Fix issue when repos have a space in their name (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
rajbos authored Jan 15, 2024
1 parent 106d599 commit 59ca6bf
Show file tree
Hide file tree
Showing 12 changed files with 68 additions and 62 deletions.
4 changes: 3 additions & 1 deletion make.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion vss-extension-dev.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
2 changes: 1 addition & 1 deletion widgets/build-info/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
24 changes: 20 additions & 4 deletions widgets/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(`<option value="">Select a repository</option>`);
dropDown.append(`<option value="">All repos in this project</option>`);
dropDown.append(`<option value="0">Select a repository</option>`);
if (showAllRepos) {
dropDown.append(`<option value="1">All repos in this project</option>`);
}
// sort the repo alphabetically
repos.sort((a, b) => a.name.localeCompare(b.name));
repos.forEach(r => {
dropDown.append(`<option value=${r.name}>${r.name}</option>`);
dropDown.append(`<option value=${r.id}>${r.name}</option>`);
});
}

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
Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion widgets/pr-tab/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion widgets/widgets/chart/chart.html
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion widgets/widgets/testing_widget/testing.html
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
30 changes: 12 additions & 18 deletions widgets/widgets/widget_1x1/configuration_1x1.html
Original file line number Diff line number Diff line change
Expand Up @@ -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()
})
Expand All @@ -47,14 +38,15 @@
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)
}

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) {
Expand Down Expand Up @@ -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()
})
Expand Down
2 changes: 1 addition & 1 deletion widgets/widgets/widget_1x1/widget_1x1.html
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 1 addition & 5 deletions widgets/widgets/widget_1x1/widget_1x1.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,17 @@ 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
const widget = document.getElementById('GHAzDo-widget');
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 {
Expand Down
51 changes: 24 additions & 27 deletions widgets/widgets/widget_2x1/configuration_2x1.html
Original file line number Diff line number Diff line change
Expand Up @@ -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()
})
};
Expand All @@ -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(`<option value="">Select a repository</option>`);
// sort the repo alphabetically
repos.sort((a, b) => a.name.localeCompare(b.name));
repos.forEach(r => {
$repoDropdown.append(`<option value=${r.name}>${r.name}</option>`);
});
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);
});
Expand All @@ -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()
})
};
Expand Down
3 changes: 2 additions & 1 deletion widgets/widgets/widget_2x1/widget_2x1.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@
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)
consoleLog('organization name: ' + organization)

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

return WidgetHelpers.WidgetStatusHelper.Success()
Expand Down

0 comments on commit 59ca6bf

Please sign in to comment.