Published
Edited
Jun 9, 2022
Importers
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// viewof PROJECT = projectSelector(connection)
Insert cell
// PROJECT
Insert cell
// fetchTeams({ connection, projectId: PROJECT.id })
Insert cell
// fetchClassificationNodes({ connection, projectId: PROJECT.id })
Insert cell
// connection = await createDevopsConnection({
// organization,
// token
// })
Insert cell
Insert cell
Insert cell
async function findOrCreateClassificationNode({
connection,
projectName,
lookupTable = [],
child,
path,
type
} = {}) {
if (!connection) throw new Error("Please provide the devops connection");
if (!projectName) throw new Error("please provide projectName");
if (!["iterations", "areas"].includes(type))
throw new Error(
"Please specify a classification node type. Either `iterations` or `areas`"
);

if (!child.name || !path)
throw new Error(
"Please provide a path and name for the classification node"
);

const workItemTracking = await connection.getWorkItemTrackingApi();
const element = lookupTable.find((el) => el.name == child.name);
if (element) return Promise.resolve(element);

return await workItemTracking.createOrUpdateClassificationNode(
child,
projectName,
type,
path
);
}
Insert cell
Insert cell
async function fetchClassificationNodes({
connection,
projectId,
depth = 10
} = {}) {
if (!connection) throw new Error("please provide connection");
if (!projectId) throw new Error("please provide projectId");
const workItemTracking = await connection.getWorkItemTrackingApi();
const root = await workItemTracking.getRootNodes(projectId);
const rootArea = root.find((node) => node.url.includes("Areas"));
const rootIteration = root.find((node) => node.url.includes("Iterations"));

const areas = await workItemTracking.getClassificationNodes(
projectId,
[rootArea.id],
depth
);

const iterations = await workItemTracking.getClassificationNodes(
projectId,
[rootIteration.id],
depth
);

return {
areas,
iterations
};
}
Insert cell
Insert cell
async function fetchTeams({ connection, projectId }) {
if (!connection) throw new Error("please provide connection");
if (!projectId) throw new Error("please provide projectId");

const core = await connection.getCoreApi();
const teams = await core.getTeams(projectId);

return await Promise.all(
teams.map(async (team) => ({
...team,
members: await core.getTeamMembersWithExtendedProperties(
projectId,
team.id
)
}))
);
}
Insert cell
Insert cell
async function fetchProject(connection, projectName) {
const core = await connection.getCoreApi();
return await core.getProject(Secret("DEVOPS_PROJECT"));
}
Insert cell
Insert cell
function createDevopsConnection({ organization, token }) {
const orgUrl = `https://dev.azure.com/${organization}`;
const authHandler = azdev.getPersonalAccessTokenHandler(token);
return new azdev.WebApi(orgUrl, authHandler);
}
Insert cell
Insert cell
Insert cell
async function projectSelector(connection) {
const core = await connection.getCoreApi();
const projects = await core.getProjects();
return Inputs.select(projects, {
label: "Selected Project:",
format: (d) => d.name
});
}
Insert cell
Insert cell
azdev = require("https://bundle.run/azure-devops-node-api@11.0.1")
Insert cell
import { signature } from "@mootari/signature@547"
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more