Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions localization/xliff/vscode-mssql.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -4050,9 +4050,6 @@
<trans-unit id="mssql.showGettingStarted">
<source xml:lang="en">Getting Started Guide</source>
</trans-unit>
<trans-unit id="mssql.userFeedback">
<source xml:lang="en">Give Feedback</source>
</trans-unit>
<trans-unit id="mssql.copilot.editorSubmenu">
<source xml:lang="en">MSSQL Copilot (Preview)</source>
</trans-unit>
Expand Down Expand Up @@ -4203,6 +4200,9 @@
<trans-unit id="mssql.selectedAzureSubscriptions">
<source xml:lang="en">Selected Azure subscriptions for browsing and managing servers and databases</source>
</trans-unit>
<trans-unit id="mssql.userFeedback">
<source xml:lang="en">Send Feedback</source>
</trans-unit>
<trans-unit id="mssql.resultsFontFamily">
<source xml:lang="en">Set the font family for the results grid; set to blank to use the editor font</source>
</trans-unit>
Expand Down
2 changes: 1 addition & 1 deletion package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@
"mssql.defaultQueryResultsViewMode.description": "Default view mode for query results display.",
"mssql.defaultQueryResultsViewMode.grid.description": "Display results in a tabular grid format (default)",
"mssql.defaultQueryResultsViewMode.text.description": "Display results in a formatted text format.",
"mssql.userFeedback": "Give Feedback",
"mssql.userFeedback": "Send Feedback",
"mssql.selectedAzureSubscriptions": "Selected Azure subscriptions for browsing and managing servers and databases",
"mssql.schemaDesigner": "Schema Designer",
"mssql.newDeployment": "New Deployment",
Expand Down
3 changes: 3 additions & 0 deletions src/connectionSharing/connectionSharingService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,9 @@ export class ConnectionSharingService implements mssql.IConnectionSharingService
const connectionResult = await this._connectionManager.connect(
connectionUri,
targetConnection,
{
connectionSource: "connectionSharingService",
},
);

if (!connectionResult) {
Expand Down
12 changes: 8 additions & 4 deletions src/connectionconfig/connectionDialogWebviewController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ import { getCloudId } from "../azure/providerSettings";

const FABRIC_WORKSPACE_AUTOLOAD_LIMIT = 10;
export const CLEAR_TOKEN_CACHE = "clearTokenCache";
const CONNECTION_DIALOG_VIEW_ID = "connectionDialog";

export class ConnectionDialogWebviewController extends FormWebviewController<
IConnectionDialogProfile,
Expand Down Expand Up @@ -137,8 +138,8 @@ export class ConnectionDialogWebviewController extends FormWebviewController<
super(
context,
vscodeWrapper,
"connectionDialog",
"connectionDialog",
CONNECTION_DIALOG_VIEW_ID,
CONNECTION_DIALOG_VIEW_ID,
new ConnectionDialogWebviewState(),
{
title: Loc.connectionDialog,
Expand Down Expand Up @@ -1001,7 +1002,10 @@ export class ConnectionDialogWebviewController extends FormWebviewController<
const result = await this._mainController.connectionManager.connect(
tempConnectionUri,
cleanedConnection,
false, // Connect should not handle errors, as we want to handle them here
{
shouldHandleErrors: false, // Connect should not handle errors, as we want to handle them here
connectionSource: CONNECTION_DIALOG_VIEW_ID,
},
);

const connectionInfo =
Expand Down Expand Up @@ -1106,7 +1110,7 @@ export class ConnectionDialogWebviewController extends FormWebviewController<

await this.panel.dispose();
this.dispose();
UserSurvey.getInstance().promptUserForNPSFeedback();
UserSurvey.getInstance().promptUserForNPSFeedback(CONNECTION_DIALOG_VIEW_ID);
} catch (error) {
this.state.connectionStatus = ApiStatus.Error;
this.state.formMessage = { message: getErrorMessage(error) };
Expand Down
14 changes: 12 additions & 2 deletions src/controllers/connectionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1140,8 +1140,13 @@ export default class ConnectionManager {
public async connect(
fileUri: string,
credentials: IConnectionInfo,
shouldHandleErrors: boolean = true,
options: {
shouldHandleErrors?: boolean;
connectionSource?: string;
} = {},
): Promise<boolean> {
const { shouldHandleErrors = true, connectionSource = "" } = options;

if (!fileUri) {
fileUri = `${ObjectExplorerUtils.getNodeUriFromProfile(credentials as IConnectionProfile)}_${Utils.generateGuid()}`;
}
Expand Down Expand Up @@ -1200,6 +1205,7 @@ export default class ConnectionManager {
{
serverTypes: getServerTypes(credentials).join(","),
cloudType: getCloudId(),
connectionSource: connectionSource,
},
);
return false;
Expand All @@ -1222,6 +1228,7 @@ export default class ConnectionManager {
{
serverTypes: getServerTypes(credentials).join(","),
cloudType: getCloudId(),
connectionSource: connectionSource,
},
);
return false;
Expand All @@ -1231,6 +1238,7 @@ export default class ConnectionManager {
sendActionEvent(TelemetryViews.ConnectionManager, TelemetryActions.Connect, {
serverTypes: getServerTypes(credentials).join(","),
cloudType: getCloudId(),
connectionSource: connectionSource,
});

const result = await connectionCompletePromise.promise;
Expand All @@ -1254,7 +1262,9 @@ export default class ConnectionManager {
);

if (errorHandlingResult.isHandled) {
return await this.connect(fileUri, errorHandlingResult.updatedCredentials);
return await this.connect(fileUri, errorHandlingResult.updatedCredentials, {
connectionSource: connectionSource,
});
}
}

Expand Down
43 changes: 33 additions & 10 deletions src/controllers/mainController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ export default class MainController implements vscode.Disposable {
});
this.registerCommand(Constants.cmdRunQuery);
this._event.on(Constants.cmdRunQuery, () => {
void UserSurvey.getInstance().promptUserForNPSFeedback();
void UserSurvey.getInstance().promptUserForNPSFeedback("runQuery");
void this.onRunQuery();
});
this.registerCommand(Constants.cmdManageConnectionProfiles);
Expand Down Expand Up @@ -252,8 +252,13 @@ export default class MainController implements vscode.Disposable {
void this.runAndLogErrors(this.onChooseLanguageFlavor());
});
this.registerCommand(Constants.cmdLaunchUserFeedback);
this._event.on(Constants.cmdLaunchUserFeedback, async () => {
await UserSurvey.getInstance().launchSurvey("nps", getStandardNPSQuestions());
this._event.on(Constants.cmdLaunchUserFeedback, () => {
// Launch directly, bypassing checks/prompt because they explicitly requested to provide feedback
UserSurvey.getInstance().launchSurvey(
"nps",
getStandardNPSQuestions(),
"commandPalette",
);
});
this.registerCommand(Constants.cmdCancelQuery);
this._event.on(Constants.cmdCancelQuery, async () => {
Expand Down Expand Up @@ -741,6 +746,9 @@ export default class MainController implements vscode.Disposable {
const isConnected = await this.connectionManager.connect(
nodeUri,
connectionCreds,
{
connectionSource: "scriptNode",
},
);
if (isConnected) {
node.updateEntraTokenInfo(connectionCreds); // may be updated Entra token after connect() call
Expand Down Expand Up @@ -884,6 +892,8 @@ export default class MainController implements vscode.Disposable {
}
},
);

UserSurvey.getInstance().promptUserForNPSFeedback("scriptAs");
}

/**
Expand Down Expand Up @@ -1116,6 +1126,9 @@ export default class MainController implements vscode.Disposable {
const connectionResult = await this.connectionManager.connect(
connectionUri,
connectionCreds,
{
connectionSource: "searchObjects",
},
);

if (connectionResult) {
Expand Down Expand Up @@ -1744,8 +1757,7 @@ export default class MainController implements vscode.Disposable {
vscode.commands.registerCommand(
Constants.cmdScriptSelect,
async (node: TreeNodeInfo) => {
await this.scriptNode(node, ScriptOperation.Select, true);
UserSurvey.getInstance().promptUserForNPSFeedback();
await this.scriptNode(node, ScriptOperation.Select, true /* executeScript */);
},
),
);
Expand All @@ -1754,31 +1766,39 @@ export default class MainController implements vscode.Disposable {
this._context.subscriptions.push(
vscode.commands.registerCommand(
Constants.cmdScriptCreate,
async (node: TreeNodeInfo) => await this.scriptNode(node, ScriptOperation.Create),
async (node: TreeNodeInfo) => {
await this.scriptNode(node, ScriptOperation.Create);
},
),
);

// Script as Drop
this._context.subscriptions.push(
vscode.commands.registerCommand(
Constants.cmdScriptDelete,
async (node: TreeNodeInfo) => await this.scriptNode(node, ScriptOperation.Delete),
async (node: TreeNodeInfo) => {
await this.scriptNode(node, ScriptOperation.Delete);
},
),
);

// Script as Execute
this._context.subscriptions.push(
vscode.commands.registerCommand(
Constants.cmdScriptExecute,
async (node: TreeNodeInfo) => await this.scriptNode(node, ScriptOperation.Execute),
async (node: TreeNodeInfo) => {
await this.scriptNode(node, ScriptOperation.Execute);
},
),
);

// Script as Alter
this._context.subscriptions.push(
vscode.commands.registerCommand(
Constants.cmdScriptAlter,
async (node: TreeNodeInfo) => await this.scriptNode(node, ScriptOperation.Alter),
async (node: TreeNodeInfo) => {
await this.scriptNode(node, ScriptOperation.Alter);
},
),
);

Expand Down Expand Up @@ -2248,9 +2268,12 @@ export default class MainController implements vscode.Disposable {
uri: string,
connectionInfo: IConnectionInfo,
saveConnection?: boolean,
connectionSource?: string,
): Promise<boolean> {
if (this.canRunCommand() && uri && connectionInfo) {
const connectedSuccessfully = await this._connectionMgr.connect(uri, connectionInfo);
const connectedSuccessfully = await this._connectionMgr.connect(uri, connectionInfo, {
connectionSource,
});
if (connectedSuccessfully) {
if (saveConnection) {
await this.createObjectExplorerSession(connectionInfo);
Expand Down
3 changes: 3 additions & 0 deletions src/copilot/chatAgentRequestHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
connectedLabelPrefix,
serverDatabaseLabelPrefix,
} from "./chatConstants";
import { UserSurvey } from "../nps/userSurvey";

export interface ISqlChatResult extends vscode.ChatResult {
metadata: {
Expand Down Expand Up @@ -508,6 +509,8 @@ export const createSqlAgentRequestHandler = (
logger.logDebug(`Done processing message for '${conversationUri}'`);
// Output reply text if needed
if (printTextout) {
UserSurvey.getInstance().promptUserForNPSFeedback("copilot_askMode");

stream.markdown(replyText);
printTextout = false;
}
Expand Down
3 changes: 3 additions & 0 deletions src/copilot/tools/changeDatabaseTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ export class ChangeDatabaseTool extends ToolBase<ChangeDatabaseToolParams> {
const connectResult = await this._connectionManager.connect(
connectionId,
newConnectionCreds,
{
connectionSource: "copilot_changeDatabaseTool",
},
);

if (connectResult) {
Expand Down
14 changes: 10 additions & 4 deletions src/copilot/tools/connectTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,16 @@ export class ConnectTool extends ToolBase<ConnectToolParams> {
const handlePwdResult =
await this._connectionManager.handlePasswordBasedCredentials(connInfo);
if (handlePwdResult) {
success = await this._connectionManager.connect(connectionId, {
...connInfo,
database: targetDatabase,
});
success = await this._connectionManager.connect(
connectionId,
{
...connInfo,
database: targetDatabase,
},
{
connectionSource: "copilot_connectTool",
},
);
} else {
success = false;
}
Expand Down
3 changes: 3 additions & 0 deletions src/copilot/tools/runQueryTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { getErrorMessage } from "../../utils/utils";
import SqlToolsServiceClient from "../../languageservice/serviceclient";
import { RequestType } from "vscode-languageclient";
import { SimpleExecuteResult, IDbColumn, DbCellValue } from "vscode-mssql";
import { UserSurvey } from "../../nps/userSurvey";

export interface RunQueryToolParams {
connectionId: string;
Expand Down Expand Up @@ -64,6 +65,8 @@ export class RunQueryTool extends ToolBase<RunQueryToolParams> {
},
);

UserSurvey.getInstance().promptUserForNPSFeedback("copilot_agentMode");

return JSON.stringify({
success: true,
rowCount: result.rowCount,
Expand Down
48 changes: 29 additions & 19 deletions src/deployment/deploymentWebviewController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ import * as fabricProvisioning from "./fabricProvisioningHelpers";
import { newDeployment } from "../constants/locConstants";
import { FabricProvisioningState } from "../sharedInterfaces/fabricProvisioning";

/*
Since there's one overarching controller for all deployment types, but each deployment type has differently typed form states + webview states,
there are two form states- one with the overall controller (required because it extends FormWebviewController), and one with each specific deployment state
*/
export const DEPLOYMENT_VIEW_ID = "deployment";

/**
* Overarching controller for the deployment webview.
* Since there's one overarching controller for all deployment types, but each deployment type has differently typed form states + webview states, there are two form states:
* one with the overall controller (required because it extends FormWebviewController), and one with each specific deployment state.
*/
export class DeploymentWebviewController extends FormWebviewController<
DeploymentFormState,
DeploymentWebviewState,
Expand All @@ -46,22 +49,29 @@ export class DeploymentWebviewController extends FormWebviewController<
public mainController: MainController,
initialConnectionGroup?: string,
) {
super(context, vscodeWrapper, "deployment", "deployment", new DeploymentWebviewState(), {
title: newDeployment,
viewColumn: vscode.ViewColumn.Active,
iconPath: {
dark: vscode.Uri.joinPath(
context.extensionUri,
"media",
"connectionDialogEditor_dark.svg",
),
light: vscode.Uri.joinPath(
context.extensionUri,
"media",
"connectionDialogEditor_light.svg",
),
super(
context,
vscodeWrapper,
DEPLOYMENT_VIEW_ID,
DEPLOYMENT_VIEW_ID,
new DeploymentWebviewState(),
{
title: newDeployment,
viewColumn: vscode.ViewColumn.Active,
iconPath: {
dark: vscode.Uri.joinPath(
context.extensionUri,
"media",
"connectionDialogEditor_dark.svg",
),
light: vscode.Uri.joinPath(
context.extensionUri,
"media",
"connectionDialogEditor_light.svg",
),
},
},
});
);
void this.initialize(initialConnectionGroup);
}

Expand Down
Loading