Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to update the target guid for a deployment at any time (from the ... menu) #2576

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
5 changes: 3 additions & 2 deletions .github/workflows/home-view-unit-test.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Lint
name: Unit-Test
on: [workflow_call]
jobs:
lint:
test:
runs-on: ubuntu-latest
defaults:
run:
Expand All @@ -13,5 +13,6 @@ jobs:
node-version: "20"
cache: "npm"
cache-dependency-path: "**/package-lock.json"
- run: npm install --prefix ../..
- run: npm install
- run: npm test
9 changes: 9 additions & 0 deletions extensions/vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@
"title": "Select Active Configuration For Deployment",
"category": "Posit Publisher"
},
{
"command": "posit.publisher.homeView.associateDeployment",
"title": "Associate with a Different Deployment on Connect",
"category": "Posit Publisher"
},
{
"command": "posit.publisher.homeView.createConfigForDeployment",
"title": "Create New Configuration For Destination",
Expand Down Expand Up @@ -325,6 +330,10 @@
"command": "posit.publisher.homeView.showSelectConfigForDeployment",
"when": "webviewId == 'posit.publisher.homeView' && webviewSection == 'even-easier-deploy-more-menu-matching-configs'"
},
{
"command": "posit.publisher.homeView.associateDeployment",
"when": "webviewId == 'posit.publisher.homeView' && webviewSection == 'even-easier-deploy-more-menu-matching-configs' && posit.publish.selection.hasCredentialMatch == 'true' && posit.publish.selection.isPreContentRecord == 'false'"
},
{
"command": "posit.publisher.homeView.createConfigForDeployment",
"when": "webviewId == 'posit.publisher.homeView' && webviewSection == 'even-easier-deploy-more-menu-no-matching-configs'"
Expand Down
30 changes: 22 additions & 8 deletions extensions/vscode/src/actions/showAssociateGUID.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { PublisherState } from "src/state";
import { showProgress } from "src/utils/progress";
import { Views } from "src/constants";
import { useApi } from "src/api";
import { getSummaryStringFromError } from "src/utils/errors";

export async function showAssociateGUID(state: PublisherState) {
const urlOrGuid = "";
Expand Down Expand Up @@ -43,13 +44,26 @@ export async function showAssociateGUID(state: PublisherState) {
return undefined;
}
await showProgress("Updating Content Record", Views.HomeView, async () => {
const api = await useApi();
await api.contentRecords.patch(
targetContentRecord.deploymentName,
targetContentRecord.projectDir,
{
guid,
},
);
try {
const api = await useApi();
await api.contentRecords.patch(
targetContentRecord.deploymentName,
targetContentRecord.projectDir,
{
guid,
},
);
window.showInformationMessage(
`Your deployment is now locally associated with Content GUID ${guid} as requested.`,
);
} catch (error: unknown) {
const summary = getSummaryStringFromError(
"showAssociateGUID, contentRecords.patch",
error,
);
window.showErrorMessage(
`Unable to associate deployment with Content GUID ${guid}. ${summary}`,
);
}
});
}
1 change: 1 addition & 0 deletions extensions/vscode/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ const homeViewCommands = {
Refresh: "posit.publisher.homeView.refresh",
ShowSelectConfigForDeployment:
"posit.publisher.homeView.showSelectConfigForDeployment",
AssociateDeployment: "posit.publisher.homeView.associateDeployment",
CreateConfigForDeployment:
"posit.publisher.homeView.createConfigForDeployment",
SelectDeployment: "posit.publisher.homeView.selectDeployment",
Expand Down
34 changes: 34 additions & 0 deletions extensions/vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,20 @@ enum InitializationInProgress {
false = "false",
}

const SELECTION_HAS_CREDENTIAL_MATCH_CONTEXT =
"posit.publish.selection.hasCredentialMatch";
export enum SelectionCredentialMatch {
true = "true",
false = "false",
}

const SELECTION_IS_PRE_CONTENT_RECORD_CONTEXT =
"posit.publish.selection.isPreContentRecord";
export enum SelectionIsPreContentRecord {
true = "true",
false = "false",
}

// Once the extension is activate, hang on to the service so that we can stop it on deactivation.
let service: Service;

Expand All @@ -42,6 +56,26 @@ function setInitializationInProgressContext(context: InitializationInProgress) {
commands.executeCommand("setContext", INITIALIZING_CONTEXT, context);
}

export function setSelectionHasCredentialMatch(
context: SelectionCredentialMatch,
) {
commands.executeCommand(
"setContext",
SELECTION_HAS_CREDENTIAL_MATCH_CONTEXT,
context,
);
}

export function setSelectionIsPreContentRecord(
context: SelectionIsPreContentRecord,
) {
commands.executeCommand(
"setContext",
SELECTION_IS_PRE_CONTENT_RECORD_CONTEXT,
context,
);
}

// This method is called when your extension is activated
// Your extension is activated the very first time the command is executed
export async function activate(context: ExtensionContext) {
Expand Down
24 changes: 22 additions & 2 deletions extensions/vscode/src/types/messages/webviewToHostMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export enum WebviewToHostMessageType {
NEW_CREDENTIAL = "newCredential",
VIEW_PUBLISHING_LOG = "viewPublishingLog",
SHOW_ASSOCIATE_GUID = "ShowAssociateGUID",
UPDATE_SELECTION_CREDENTIAL_STATE = "UpdateSelectionCredentialStateMsg",
UPDATE_SELECTION_IS_PRE_CONTENT_RECORD = "UpdateSelectionIsPreContentRecordMsg",
}

export type AnyWebviewToHostMessage<
Expand Down Expand Up @@ -62,7 +64,9 @@ export type WebviewToHostMessage =
| NewCredentialForDeploymentMsg
| NewCredentialMsg
| ViewPublishingLog
| ShowAssociateGUIDMsg;
| ShowAssociateGUIDMsg
| UpdateSelectionCredentialStateMsg
| UpdateSelectionIsPreContentRecordMsg;

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function isWebviewToHostMessage(msg: any): msg is WebviewToHostMessage {
Expand All @@ -89,7 +93,9 @@ export function isWebviewToHostMessage(msg: any): msg is WebviewToHostMessage {
msg.kind === WebviewToHostMessageType.NEW_CREDENTIAL_FOR_DEPLOYMENT ||
msg.kind === WebviewToHostMessageType.NEW_CREDENTIAL ||
msg.kind === WebviewToHostMessageType.VIEW_PUBLISHING_LOG ||
msg.kind === WebviewToHostMessageType.SHOW_ASSOCIATE_GUID
msg.kind === WebviewToHostMessageType.SHOW_ASSOCIATE_GUID ||
msg.kind === WebviewToHostMessageType.UPDATE_SELECTION_CREDENTIAL_STATE ||
msg.kind === WebviewToHostMessageType.UPDATE_SELECTION_IS_PRE_CONTENT_RECORD
);
}

Expand Down Expand Up @@ -210,3 +216,17 @@ export type ViewPublishingLog =

export type ShowAssociateGUIDMsg =
AnyWebviewToHostMessage<WebviewToHostMessageType.SHOW_ASSOCIATE_GUID>;

export type UpdateSelectionCredentialStateMsg = AnyWebviewToHostMessage<
WebviewToHostMessageType.UPDATE_SELECTION_CREDENTIAL_STATE,
{
state: string;
}
>;

export type UpdateSelectionIsPreContentRecordMsg = AnyWebviewToHostMessage<
WebviewToHostMessageType.UPDATE_SELECTION_IS_PRE_CONTENT_RECORD,
{
state: string;
}
>;
31 changes: 31 additions & 0 deletions extensions/vscode/src/views/homeView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ import { showAssociateGUID } from "src/actions/showAssociateGUID";
import { extensionSettings } from "src/extension";
import { openFileInEditor } from "src/commands";
import { showImmediateDeploymentFailureMessage } from "./publishFailures";
import {
SelectionCredentialMatch,
setSelectionHasCredentialMatch,
SelectionIsPreContentRecord,
setSelectionIsPreContentRecord,
} from "../extension";

enum HomeViewInitialized {
initialized = "initialized",
Expand Down Expand Up @@ -174,6 +180,10 @@ export class HomeViewProvider implements WebviewViewProvider, Disposable {
return this.showPublishingLog();
case WebviewToHostMessageType.SHOW_ASSOCIATE_GUID:
return showAssociateGUID(this.state);
case WebviewToHostMessageType.UPDATE_SELECTION_CREDENTIAL_STATE:
return this.updateSelectionCredentialState(msg.content.state);
case WebviewToHostMessageType.UPDATE_SELECTION_IS_PRE_CONTENT_RECORD:
return this.updateSelectionIsPreContentRecordState(msg.content.state);
default:
window.showErrorMessage(
`Internal Error: onConduitMessage unhandled msg: ${JSON.stringify(msg)}`,
Expand All @@ -189,6 +199,22 @@ export class HomeViewProvider implements WebviewViewProvider, Disposable {
);
}

private async updateSelectionCredentialState(state: string) {
const match =
state === SelectionCredentialMatch.true
? SelectionCredentialMatch.true
: SelectionCredentialMatch.false;
return await setSelectionHasCredentialMatch(match);
}

private async updateSelectionIsPreContentRecordState(state: string) {
const match =
state === SelectionIsPreContentRecord.true
? SelectionIsPreContentRecord.true
: SelectionIsPreContentRecord.false;
return await setSelectionIsPreContentRecord(match);
}

private async initiateDeployment(
deploymentName: string,
credentialName: string,
Expand Down Expand Up @@ -1782,6 +1808,11 @@ export class HomeViewProvider implements WebviewViewProvider, Disposable {
this.showSelectOrCreateConfigForDeployment,
this,
),
commands.registerCommand(
Commands.HomeView.AssociateDeployment,
() => showAssociateGUID(this.state),
this,
),
commands.registerCommand(
Commands.HomeView.CreateConfigForDeployment,
this.showSelectOrCreateConfigForDeployment,
Expand Down
29 changes: 29 additions & 0 deletions extensions/vscode/webviews/homeView/src/stores/home.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
PreContentRecord,
Configuration,
ConfigurationError,
isPreContentRecord,
} from "../../../../src/api";
import { isConfigurationError } from "../../../../src/api/types/configurations";
import { WebviewToHostMessageType } from "../../../../src/types/messages/webviewToHostMessages";
Expand Down Expand Up @@ -179,6 +180,34 @@ export const useHomeStore = defineStore("home", () => {
selectedContentRecord.value = contentRecord;
}

watch([serverCredential], () => updateSelectionCredentialStatus());

const updateSelectionCredentialStatus = () => {
const hostConduit = useHostConduitService();
hostConduit.sendMsg({
kind: WebviewToHostMessageType.UPDATE_SELECTION_CREDENTIAL_STATE,
content: {
state: serverCredential.value !== undefined ? "true" : "false",
},
});
};

watch([selectedContentRecord], () =>
updateSelectionIsPreContentRecordState(),
);

const updateSelectionIsPreContentRecordState = () => {
const hostConduit = useHostConduitService();
hostConduit.sendMsg({
kind: WebviewToHostMessageType.UPDATE_SELECTION_IS_PRE_CONTENT_RECORD,
content: {
state: isPreContentRecord(selectedContentRecord.value)
? "true"
: "false",
},
});
};

watch([selectedConfiguration], () => updateParentViewSelectionState());

const updateParentViewSelectionState = () => {
Expand Down