From 8f476353cd0340ad234a3d86abfa858f56007227 Mon Sep 17 00:00:00 2001 From: Kevin Berry <41717340+51ngul4r1ty@users.noreply.github.com> Date: Wed, 11 May 2022 09:44:29 -0400 Subject: [PATCH 1/4] clean ups and fixes --- package-lock.json | 18 ++--- package.json | 4 +- src/chooseStoryCommands.ts | 2 +- src/extension.ts | 130 ++++++++++++++++++++++--------------- 4 files changed, 88 insertions(+), 66 deletions(-) diff --git a/package-lock.json b/package-lock.json index fb1a5e9..ab0c2f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,14 @@ { "name": "atoll-extension", - "version": "0.3.3", + "version": "0.3.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "atoll-extension", - "version": "0.3.3", + "version": "0.3.4", "dependencies": { - "@atoll/client-sdk": "0.18.1", + "@atoll/client-sdk": "0.19.1", "axios": "0.27.2" }, "devDependencies": { @@ -42,9 +42,9 @@ } }, "node_modules/@atoll/client-sdk": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/@atoll/client-sdk/-/client-sdk-0.18.1.tgz", - "integrity": "sha512-GtIFQHQQx3KootLhPm2sV4TS4TCzZfoxHX+67VYJjwNexOeInm8kgeNTamlB1PT3ho2+VN3/djcD4gSkfDzDdw==", + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@atoll/client-sdk/-/client-sdk-0.19.1.tgz", + "integrity": "sha512-+C0gl5BfCn6/l2mZE/Y9cbY1y5J4zGqcAu+kzdhMPnRIhCogOmfdirEQ0tQXpsdWcju9A78eDqqNR3yaVvFHDQ==", "dependencies": { "@atoll/api-types": "0.6.1", "@atoll/rest-fetch": "0.9.0", @@ -3747,9 +3747,9 @@ "integrity": "sha512-I6wCAz3th8shPXzrCusxDJWBxbdQa+eiSrrIRz6TWXbbQwhIqoggnZV07O2NbU0hgdKUXSBfk0om1nEKgAyQWQ==" }, "@atoll/client-sdk": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/@atoll/client-sdk/-/client-sdk-0.18.1.tgz", - "integrity": "sha512-GtIFQHQQx3KootLhPm2sV4TS4TCzZfoxHX+67VYJjwNexOeInm8kgeNTamlB1PT3ho2+VN3/djcD4gSkfDzDdw==", + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@atoll/client-sdk/-/client-sdk-0.19.1.tgz", + "integrity": "sha512-+C0gl5BfCn6/l2mZE/Y9cbY1y5J4zGqcAu+kzdhMPnRIhCogOmfdirEQ0tQXpsdWcju9A78eDqqNR3yaVvFHDQ==", "requires": { "@atoll/api-types": "0.6.1", "@atoll/rest-fetch": "0.9.0", diff --git a/package.json b/package.json index d36f742..0c2bc8f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "atoll-extension", "displayName": "Atoll Extension", "description": "Use Atoll from within VS Code", - "version": "0.3.4", + "version": "0.4.0", "repository": { "type": "git", "url": "https://github.com/51ngul4r1ty/atoll-extensions.git" @@ -67,7 +67,7 @@ "webpack-cli": "4.9.2" }, "dependencies": { - "@atoll/client-sdk": "0.18.1", + "@atoll/client-sdk": "0.19.1", "axios": "0.27.2" } } diff --git a/src/chooseStoryCommands.ts b/src/chooseStoryCommands.ts index cf8e6b6..6885b63 100644 --- a/src/chooseStoryCommands.ts +++ b/src/chooseStoryCommands.ts @@ -59,7 +59,7 @@ export async function chooseStory(context: ExtensionContext) { const backlogItemsUri = atollClient.buildFullUri(backlogItemsRelativeUri); const sprintBacklogItems = await atollClient.fetchSprintBacklogItemsByUri(backlogItemsUri); - if (sprintBacklogItems === null) { + if (sprintBacklogItems === null || sprintBacklogItems.length === 0) { logInfo( "There are no sprint backlog items available - please add sprint backlog items first!", MessageStyle.OutputChannelAndMessage diff --git a/src/extension.ts b/src/extension.ts index 5603ce3..a217a18 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -18,72 +18,94 @@ import { state } from "./extensionState"; let myStatusBarItem: vscode.StatusBarItem; -export async function activate(context: vscode.ExtensionContext) { - logInfo("Atoll extension has been activated."); - await state.loadSettings(context); - if (state.atollRefreshToken) { - atollClient.refreshToken = state.atollRefreshToken; - const handleNotification = async (message: string, level: string) => { - switch (level) { - case "info": { - logInfo(message, MessageStyle.OutputChannelAndMessage); - break; - } - case "warn": { - logWarning(message, MessageStyle.OutputChannelAndMessage); - break; - } - case "error": { - logError(message, MessageStyle.OutputChannelAndMessage); - break; - } - default: { - throw new Error(`Unexpected level "${level}" with message "${message}"`); - } +async function reconnectToAtoll() { + atollClient.refreshToken = state.atollRefreshToken; + const handleNotification = async (message: string, level: string) => { + switch (level) { + case "info": { + logInfo(message, MessageStyle.OutputChannelAndMessage); + break; + } + case "warn": { + logWarning(message, MessageStyle.OutputChannelAndMessage); + break; + } + case "error": { + logError(message, MessageStyle.OutputChannelAndMessage); + break; } - }; - logDebug(`Setting up with refresh token - atoll server URL = ${state.atollServerUrl}...`); - try { - const result = await atollClient.setupWithRefreshToken(state.atollServerUrl || "", handleNotification); - if (result) { - logInfo(`Unable to set up with refresh token: ${result}`, MessageStyle.OutputChannelAndMessage); + default: { + throw new Error(`Unexpected level "${level}" with message "${message}"`); } - } catch (err) { - logError(`Catch triggered: ${err}`); } - logDebug("Set up with refresh token."); - updateStatusBarItem(context); + }; + logDebug(`Setting up with refresh token - atoll server URL = ${state.atollServerUrl}...`); + try { + const result = await atollClient.reconnect(state.atollServerUrl || "", handleNotification); + if (result) { + logInfo(`Unable to set up with refresh token: ${result}`, MessageStyle.OutputChannelAndMessage); + } + } catch (err) { + logError(`Catch triggered: ${err}`); } + logDebug("Set up with refresh token."); +} - const connectCommand = vscode.commands.registerCommand("atoll-extension.connect", async () => { - await connect(context); - updateStatusBarItem(context); - }); - context.subscriptions.push(connectCommand); +let activated = false; - const disconnectCommand = vscode.commands.registerCommand("atoll-extension.disconnect", async () => { - await disconnect(context); - updateStatusBarItem(context); - }); - context.subscriptions.push(disconnectCommand); +async function initialActivation(context: vscode.ExtensionContext) { + activated = true; + try { + logInfo("Atoll extension has been activated."); + await state.loadSettings(context); - const statusBarCommand = vscode.commands.registerCommand("atoll-extension.status-bar-click", async () => { - if (!atollClient.isConnected()) { + // reconnect to Atoll server automatically + if (state.atollRefreshToken && !atollClient.isConnected()) { + await reconnectToAtoll(); + updateStatusBarItem(context); + } + + const connectCommand = vscode.commands.registerCommand("atoll-extension.connect", async () => { await connect(context); updateStatusBarItem(context); - } else { - await chooseStory(context); + }); + context.subscriptions.push(connectCommand); + + const disconnectCommand = vscode.commands.registerCommand("atoll-extension.disconnect", async () => { + await disconnect(context); updateStatusBarItem(context); - } - }); - context.subscriptions.push(statusBarCommand); + }); + context.subscriptions.push(disconnectCommand); - myStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 1000000); - myStatusBarItem.command = "atoll-extension.status-bar-click"; - context.subscriptions.push(myStatusBarItem); + const statusBarCommand = vscode.commands.registerCommand("atoll-extension.status-bar-click", async () => { + if (!atollClient.isConnected()) { + await connect(context); + updateStatusBarItem(context); + } else { + await chooseStory(context); + updateStatusBarItem(context); + } + }); + context.subscriptions.push(statusBarCommand); - // update status bar item once at start - await updateStatusBarItem(context); + myStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 1000000); + myStatusBarItem.command = "atoll-extension.status-bar-click"; + context.subscriptions.push(myStatusBarItem); + + // update status bar item once at start + await updateStatusBarItem(context); + } catch (err) { + // NOTE: This is intentionally done directly with window.showErrorMessage just in case there's + // a problem with `logError` related code - it is essential that the user sees this. + vscode.window.showErrorMessage("Unable to activate Atoll (see output log for details)"); + logError(`Unable to activate Atoll: ${err}`, MessageStyle.OutputChannel); + } +} + +export async function activate(context: vscode.ExtensionContext) { + if (!activated) { + await initialActivation(context); + } } async function updateStatusBarItem(context: vscode.ExtensionContext): Promise { From d0ffe5b02dd80170e1e20f823484ffe447ef2ac3 Mon Sep 17 00:00:00 2001 From: Kevin Berry <41717340+51ngul4r1ty@users.noreply.github.com> Date: Wed, 11 May 2022 09:53:21 -0400 Subject: [PATCH 2/4] added notificationBridge to reduce duplication --- src/connectCommands.ts | 22 ++-------------------- src/extension.ts | 24 ++++-------------------- src/notificationBridge.ts | 26 ++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 40 deletions(-) create mode 100644 src/notificationBridge.ts diff --git a/src/connectCommands.ts b/src/connectCommands.ts index da12f5c..a61b43e 100644 --- a/src/connectCommands.ts +++ b/src/connectCommands.ts @@ -10,6 +10,7 @@ import { state } from "./extensionState"; // utils import { logDebug } from "./logger"; +import * as notificationBridge from "./notificationBridge"; export async function disconnect(context: ExtensionContext) { if (!atollClient.isConnected()) { @@ -78,26 +79,7 @@ export async function connect(context: ExtensionContext) { } const password = rawPassword?.trim() || ""; window.showInformationMessage(`Connecting to "${serverUrl}" using "${userName}"...`); - const handleNotification = async (message: string, level: string) => { - switch (level) { - case "info": { - window.showInformationMessage(message); - break; - } - case "warn": { - window.showWarningMessage(message); - break; - } - case "error": { - window.showErrorMessage(message); - break; - } - default: { - throw new Error(`Unexpected level "${level}" with message "${message}"`); - } - } - }; - const connectionResult = await atollClient.connect(serverUrl || "", userName, password, handleNotification); + const connectionResult = await atollClient.connect(serverUrl || "", userName, password, notificationBridge.handleNotification); if (connectionResult === null) { window.showInformationMessage("Successfully connected to Atoll server - loading projects..."); state.atollServerUrl = serverUrl; diff --git a/src/extension.ts b/src/extension.ts index a217a18..0e9c879 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -16,32 +16,16 @@ import { SETTING_KEY_BACKLOGITEM_FRIENDLY_ID, SETTING_KEY_BACKLOGITEM_STORY_PHRA // state import { state } from "./extensionState"; +// utils +import * as notificationBridge from "./notificationBridge"; + let myStatusBarItem: vscode.StatusBarItem; async function reconnectToAtoll() { atollClient.refreshToken = state.atollRefreshToken; - const handleNotification = async (message: string, level: string) => { - switch (level) { - case "info": { - logInfo(message, MessageStyle.OutputChannelAndMessage); - break; - } - case "warn": { - logWarning(message, MessageStyle.OutputChannelAndMessage); - break; - } - case "error": { - logError(message, MessageStyle.OutputChannelAndMessage); - break; - } - default: { - throw new Error(`Unexpected level "${level}" with message "${message}"`); - } - } - }; logDebug(`Setting up with refresh token - atoll server URL = ${state.atollServerUrl}...`); try { - const result = await atollClient.reconnect(state.atollServerUrl || "", handleNotification); + const result = await atollClient.reconnect(state.atollServerUrl || "", notificationBridge.handleNotification); if (result) { logInfo(`Unable to set up with refresh token: ${result}`, MessageStyle.OutputChannelAndMessage); } diff --git a/src/notificationBridge.ts b/src/notificationBridge.ts new file mode 100644 index 0000000..0a7cac1 --- /dev/null +++ b/src/notificationBridge.ts @@ -0,0 +1,26 @@ +/** + * Purpose: Handle messages from client SDK that need to be shown to the user of the VS Code extension. + */ + +// utils +import { logError, logInfo, logWarning, MessageStyle } from "./logger"; + +export const handleNotification = async (message: string, level: string) => { + switch (level) { + case "info": { + logInfo(message, MessageStyle.OutputChannelAndMessage); + break; + } + case "warn": { + logWarning(message, MessageStyle.OutputChannelAndMessage); + break; + } + case "error": { + logError(message, MessageStyle.OutputChannelAndMessage); + break; + } + default: { + throw new Error(`Unexpected level "${level}" with message "${message}"`); + } + } +}; From d4597cbcf1d7c0bc6e65526c2a4dbc787a38f046 Mon Sep 17 00:00:00 2001 From: Kevin Berry <41717340+51ngul4r1ty@users.noreply.github.com> Date: Sat, 14 May 2022 18:53:57 -0400 Subject: [PATCH 3/4] choose story + update it to in progress --- atoll-extension-main.code-workspace | 3 ++ package-lock.json | 69 ++++++++++++++++++----------- package.json | 9 +++- src/chooseStoryCommands.ts | 27 ++++++++++- 4 files changed, 78 insertions(+), 30 deletions(-) diff --git a/atoll-extension-main.code-workspace b/atoll-extension-main.code-workspace index 61866f1..28e2f61 100644 --- a/atoll-extension-main.code-workspace +++ b/atoll-extension-main.code-workspace @@ -11,6 +11,9 @@ }, { "path": "../atoll-rest-fetch" + }, + { + "path": "../atoll-rich-types" } ], "settings": { diff --git a/package-lock.json b/package-lock.json index ab0c2f7..fc5152f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,15 @@ { "name": "atoll-extension", - "version": "0.3.4", + "version": "0.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "atoll-extension", - "version": "0.3.4", + "version": "0.4.0", "dependencies": { - "@atoll/client-sdk": "0.19.1", + "@atoll/client-sdk": "1.0.0", + "@atoll/rich-types": "0.1.1", "axios": "0.27.2" }, "devDependencies": { @@ -29,25 +30,26 @@ "webpack-cli": "4.9.2" }, "engines": { - "vscode": "1.66.2" + "vscode": ">=1.67.0" } }, "node_modules/@atoll/api-types": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@atoll/api-types/-/api-types-0.6.1.tgz", - "integrity": "sha512-I6wCAz3th8shPXzrCusxDJWBxbdQa+eiSrrIRz6TWXbbQwhIqoggnZV07O2NbU0hgdKUXSBfk0om1nEKgAyQWQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@atoll/api-types/-/api-types-1.0.0.tgz", + "integrity": "sha512-dDxeYYSA8hBZ/V//2z9DXwj1jOTEyQAwVdQSmGJ1yrIs4wQ9P8xpeD5B/YdYDYvVD/40WevaV17BqrbmpmRA3Q==", "engines": { "node": ">=16.14.0", "npm": ">=8.3.1" } }, "node_modules/@atoll/client-sdk": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@atoll/client-sdk/-/client-sdk-0.19.1.tgz", - "integrity": "sha512-+C0gl5BfCn6/l2mZE/Y9cbY1y5J4zGqcAu+kzdhMPnRIhCogOmfdirEQ0tQXpsdWcju9A78eDqqNR3yaVvFHDQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@atoll/client-sdk/-/client-sdk-1.0.0.tgz", + "integrity": "sha512-7QTKzGLwMa3HeaKfBXnudwB8A9YDw5L1nD6qNVRMoSSEB/KlG2z7/8aj2Vchx9m2FwjGNDcVq19FjrBNLcapmw==", "dependencies": { - "@atoll/api-types": "0.6.1", - "@atoll/rest-fetch": "0.9.0", + "@atoll/api-types": "1.0.0", + "@atoll/rest-fetch": "1.1.0", + "@atoll/rich-types": "0.1.1", "http-status-codes": "2.2.0" }, "engines": { @@ -59,9 +61,9 @@ } }, "node_modules/@atoll/rest-fetch": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@atoll/rest-fetch/-/rest-fetch-0.9.0.tgz", - "integrity": "sha512-Yazsdc/vyBXZwk6niqgB9y1NPI5n/L+t80lmHO1PTKLb2Ys4n6WKeNr+aLNWT+7I0g0bG+LbzjowtXXE91iuxA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@atoll/rest-fetch/-/rest-fetch-1.1.0.tgz", + "integrity": "sha512-MKAJDZ/ghIy+4omsizTHNTi/9gPMWiVUJhddoCWo0yx6RHL7UHakvBl9Hh0d4V0NsMh0hspAn0j6ACQHzcKu1Q==", "dependencies": { "http-status-codes": "2.2.0" }, @@ -73,6 +75,15 @@ "axios": "0.27.2" } }, + "node_modules/@atoll/rich-types": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@atoll/rich-types/-/rich-types-0.1.1.tgz", + "integrity": "sha512-v7ik6UCy9tZ9SiKxOlCJGc5X7eU3MA1QplnDXaszWMt1AR/48xpiH6ddH5aAcGNcH1ph3FLGmPEQQynBosewMA==", + "engines": { + "node": ">=16.14.0", + "npm": ">=8.3.1" + } + }, "node_modules/@cspotcode/source-map-consumer": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", @@ -3742,28 +3753,34 @@ }, "dependencies": { "@atoll/api-types": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@atoll/api-types/-/api-types-0.6.1.tgz", - "integrity": "sha512-I6wCAz3th8shPXzrCusxDJWBxbdQa+eiSrrIRz6TWXbbQwhIqoggnZV07O2NbU0hgdKUXSBfk0om1nEKgAyQWQ==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@atoll/api-types/-/api-types-1.0.0.tgz", + "integrity": "sha512-dDxeYYSA8hBZ/V//2z9DXwj1jOTEyQAwVdQSmGJ1yrIs4wQ9P8xpeD5B/YdYDYvVD/40WevaV17BqrbmpmRA3Q==" }, "@atoll/client-sdk": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@atoll/client-sdk/-/client-sdk-0.19.1.tgz", - "integrity": "sha512-+C0gl5BfCn6/l2mZE/Y9cbY1y5J4zGqcAu+kzdhMPnRIhCogOmfdirEQ0tQXpsdWcju9A78eDqqNR3yaVvFHDQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@atoll/client-sdk/-/client-sdk-1.0.0.tgz", + "integrity": "sha512-7QTKzGLwMa3HeaKfBXnudwB8A9YDw5L1nD6qNVRMoSSEB/KlG2z7/8aj2Vchx9m2FwjGNDcVq19FjrBNLcapmw==", "requires": { - "@atoll/api-types": "0.6.1", - "@atoll/rest-fetch": "0.9.0", + "@atoll/api-types": "1.0.0", + "@atoll/rest-fetch": "1.1.0", + "@atoll/rich-types": "0.1.1", "http-status-codes": "2.2.0" } }, "@atoll/rest-fetch": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@atoll/rest-fetch/-/rest-fetch-0.9.0.tgz", - "integrity": "sha512-Yazsdc/vyBXZwk6niqgB9y1NPI5n/L+t80lmHO1PTKLb2Ys4n6WKeNr+aLNWT+7I0g0bG+LbzjowtXXE91iuxA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@atoll/rest-fetch/-/rest-fetch-1.1.0.tgz", + "integrity": "sha512-MKAJDZ/ghIy+4omsizTHNTi/9gPMWiVUJhddoCWo0yx6RHL7UHakvBl9Hh0d4V0NsMh0hspAn0j6ACQHzcKu1Q==", "requires": { "http-status-codes": "2.2.0" } }, + "@atoll/rich-types": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@atoll/rich-types/-/rich-types-0.1.1.tgz", + "integrity": "sha512-v7ik6UCy9tZ9SiKxOlCJGc5X7eU3MA1QplnDXaszWMt1AR/48xpiH6ddH5aAcGNcH1ph3FLGmPEQQynBosewMA==" + }, "@cspotcode/source-map-consumer": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", diff --git a/package.json b/package.json index 0c2bc8f..2c56a87 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,12 @@ "type": "git", "url": "https://github.com/51ngul4r1ty/atoll-extensions.git" }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org/" + }, "engines": { - "vscode": "1.66.2" + "vscode": ">=1.67.0" }, "categories": [ "Other" @@ -67,7 +71,8 @@ "webpack-cli": "4.9.2" }, "dependencies": { - "@atoll/client-sdk": "0.19.1", + "@atoll/client-sdk": "1.0.0", + "@atoll/rich-types": "0.1.1", "axios": "0.27.2" } } diff --git a/src/chooseStoryCommands.ts b/src/chooseStoryCommands.ts index 6885b63..5164cff 100644 --- a/src/chooseStoryCommands.ts +++ b/src/chooseStoryCommands.ts @@ -3,13 +3,14 @@ import { window, ExtensionContext, QuickPickOptions } from "vscode"; // libraries import type { SprintBacklogResourceItem } from "@atoll/api-types"; -import { atollClient } from "@atoll/client-sdk"; +import { atollClient, mapApiToBacklogItemStatus } from "@atoll/client-sdk"; // state import { state } from "./extensionState"; // utils import { logError, logInfo, logWarning, MessageStyle } from "./logger"; +import { BacklogItemStatus } from "@atoll/rich-types"; const buildUniqueBacklogItemName = (backlogItem: SprintBacklogResourceItem) => { const parts: string[] = []; @@ -93,7 +94,29 @@ export async function chooseStory(context: ExtensionContext) { state.currentBacklogItemId = matchingSBI.id; state.currentBacklogItemFriendlyId = id; state.currentBacklogItemStoryPhrase = matchingSBI.storyPhrase; - + const existingStatus = mapApiToBacklogItemStatus(matchingSBI.status); + if ( + existingStatus === BacklogItemStatus.None || + existingStatus === BacklogItemStatus.NotStarted || + existingStatus === BacklogItemStatus.InProgress + ) { + const backlogItemRelativeUri = atollClient.findLinkUriByRel(matchingSBI.links, "related:backlog-item-part"); + if (!backlogItemRelativeUri) { + logError( + 'Unable to update backlog item status to "In Progress"- ' + + `cannot find backlogitem self link for ID "${matchingSBI.id}"` + ); + } else { + // backlog item part ID: 93ee88b671244b99a985d1a164f6e577 + // url: http://localhost:8500/api/v1/backlog-item-parts/93ee88b671244b99a985d1a164f6e577 + // PATCH + // sprint backlog items may return backlogItemPartId? + // why doesn't it provide a link to the backlog item part? + const backlogItemPartsUri = atollClient.buildFullUri(backlogItemRelativeUri); + const result = await atollClient.updateBacklogItemPartStatusByUri(backlogItemPartsUri, BacklogItemStatus.InProgress); + console.log(result); + } + } await state.saveSettings(context); logInfo(`Backlog item "${id} - ${matchingSBI.storyPhrase}" selected.`, MessageStyle.OutputChannelAndMessage); From 66a0c6ea53418fa2c45e349cfd448d0df69b8a03 Mon Sep 17 00:00:00 2001 From: Kevin Berry <41717340+51ngul4r1ty@users.noreply.github.com> Date: Tue, 23 Aug 2022 12:49:24 -0400 Subject: [PATCH 4/4] added second status bar item for work item status --- src/extension.ts | 65 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 0e9c879..fed7889 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -19,7 +19,13 @@ import { state } from "./extensionState"; // utils import * as notificationBridge from "./notificationBridge"; -let myStatusBarItem: vscode.StatusBarItem; +const STATUS_BAR_ITEM_POSITION_PRIORITY_BASE = 1000000; +const STATUS_BAR_ITEM_COUNT = 2; +const STATUS_BAR_ITEM_LEFTMOST_ITEM = STATUS_BAR_ITEM_POSITION_PRIORITY_BASE + STATUS_BAR_ITEM_COUNT - 1; + +// NOTE: Ensure that STATUS_BAR_ITEM_COUNT updated to total up the number of status bar items below: +let primaryStatusBarItem: vscode.StatusBarItem; // STATUS_BAR_ITEM 1 +let secondaryStatusBarItem: vscode.StatusBarItem; // STATUS_BAR_ITEM 2 async function reconnectToAtoll() { atollClient.refreshToken = state.atollRefreshToken; @@ -46,38 +52,54 @@ async function initialActivation(context: vscode.ExtensionContext) { // reconnect to Atoll server automatically if (state.atollRefreshToken && !atollClient.isConnected()) { await reconnectToAtoll(); - updateStatusBarItem(context); + updatePrimaryStatusBarItem(context); } const connectCommand = vscode.commands.registerCommand("atoll-extension.connect", async () => { await connect(context); - updateStatusBarItem(context); + updatePrimaryStatusBarItem(context); }); context.subscriptions.push(connectCommand); const disconnectCommand = vscode.commands.registerCommand("atoll-extension.disconnect", async () => { await disconnect(context); - updateStatusBarItem(context); + updatePrimaryStatusBarItem(context); }); context.subscriptions.push(disconnectCommand); - const statusBarCommand = vscode.commands.registerCommand("atoll-extension.status-bar-click", async () => { + const primaryStatusBarCommand = vscode.commands.registerCommand("atoll-extension.primary-status-bar-click", async () => { if (!atollClient.isConnected()) { await connect(context); - updateStatusBarItem(context); + updatePrimaryStatusBarItem(context); } else { await chooseStory(context); - updateStatusBarItem(context); + updatePrimaryStatusBarItem(context); } }); - context.subscriptions.push(statusBarCommand); + context.subscriptions.push(primaryStatusBarCommand); + + const secondaryStatusBarCommand = vscode.commands.registerCommand( + "atoll-extension.secondary-status-bar-click", + async () => { + updateSecondaryStatusBarItem(context); + } + ); + context.subscriptions.push(secondaryStatusBarCommand); + + primaryStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, STATUS_BAR_ITEM_LEFTMOST_ITEM); + primaryStatusBarItem.command = "atoll-extension.primary-status-bar-click"; + context.subscriptions.push(primaryStatusBarItem); - myStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 1000000); - myStatusBarItem.command = "atoll-extension.status-bar-click"; - context.subscriptions.push(myStatusBarItem); + secondaryStatusBarItem = vscode.window.createStatusBarItem( + vscode.StatusBarAlignment.Left, + STATUS_BAR_ITEM_LEFTMOST_ITEM + 1 + ); + secondaryStatusBarItem.command = "atoll-extension.secondary-status-bar-click"; + context.subscriptions.push(secondaryStatusBarItem); // update status bar item once at start - await updateStatusBarItem(context); + await updatePrimaryStatusBarItem(context); + await updateSecondaryStatusBarItem(context); } catch (err) { // NOTE: This is intentionally done directly with window.showErrorMessage just in case there's // a problem with `logError` related code - it is essential that the user sees this. @@ -92,20 +114,27 @@ export async function activate(context: vscode.ExtensionContext) { } } -async function updateStatusBarItem(context: vscode.ExtensionContext): Promise { - // https://code.visualstudio.com/api/references/icons-in-labels +// Icon information can be obtained here: +// https://code.visualstudio.com/api/references/icons-in-labels + +async function updatePrimaryStatusBarItem(context: vscode.ExtensionContext): Promise { if (atollClient.isConnected()) { const id = await settingStore.loadSetting(context, SETTING_KEY_BACKLOGITEM_FRIENDLY_ID); const storyPhrase = await settingStore.loadSetting(context, SETTING_KEY_BACKLOGITEM_STORY_PHRASE); if (!id) { - myStatusBarItem.text = `$(extensions-star-full) (choose work item)`; + primaryStatusBarItem.text = `$(extensions-star-full) (choose work item)`; } else { - myStatusBarItem.text = `$(extensions-star-full) ${id} » ${storyPhrase}`; + primaryStatusBarItem.text = `$(extensions-star-full) ${id} » ${storyPhrase}`; } } else { - myStatusBarItem.text = `$(extensions-star-full) (connect to Atoll)`; + primaryStatusBarItem.text = `$(extensions-star-full) (connect to Atoll)`; } - myStatusBarItem.show(); + primaryStatusBarItem.show(); +} + +async function updateSecondaryStatusBarItem(context: vscode.ExtensionContext): Promise { + secondaryStatusBarItem.text = "Busy"; + secondaryStatusBarItem.show(); } export function deactivate() {}