vCore: feat: added operation summary messages (#2430)
Added confirmation messages for basic operations. Refactored confirmations.ts to a more appropriate name and location. Propagated success feedback for confirmation messages and future use.
This commit is contained in:
Родитель
a6c79f90d6
Коммит
b1d47fbaed
|
@ -1282,6 +1282,11 @@
|
|||
],
|
||||
"default": "wordConfirmation"
|
||||
},
|
||||
"azureDatabases.showOperationSummaries": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "Show detailed operation summaries, displaying messages for actions such as database drops, document additions, deletions, or similar events."
|
||||
},
|
||||
"cosmosDB.documentLabelFields": {
|
||||
"type": "array",
|
||||
"default": [
|
||||
|
|
|
@ -67,6 +67,7 @@ export namespace ext {
|
|||
export const mongoShellTimeout = 'mongo.shell.timeout';
|
||||
export const batchSize = 'azureDatabases.batchSize';
|
||||
export const confirmationStyle = 'azureDatabases.confirmationStyle';
|
||||
export const showOperationSummaries = 'azureDatabases.showOperationSummaries';
|
||||
|
||||
export namespace vsCode {
|
||||
export const proxyStrictSSL = 'http.proxyStrictSSL';
|
||||
|
|
|
@ -320,14 +320,15 @@ export class MongoClustersClient {
|
|||
}
|
||||
|
||||
async createCollection(databaseName: string, collectionName: string): Promise<boolean> {
|
||||
let newCollection;
|
||||
try {
|
||||
await this._mongoClient.db(databaseName).createCollection(collectionName);
|
||||
newCollection = await this._mongoClient.db(databaseName).createCollection(collectionName);
|
||||
} catch (_e) {
|
||||
console.log(_e); //todo: add to telemetry
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return newCollection !== undefined;
|
||||
}
|
||||
|
||||
async createDatabase(databaseName: string): Promise<boolean> {
|
||||
|
|
|
@ -10,6 +10,7 @@ import { API } from '../../AzureDBExperiences';
|
|||
import { ext } from '../../extensionVariables';
|
||||
import { WorkspaceResourceType } from '../../tree/workspace/sharedWorkspaceResourceProvider';
|
||||
import { SharedWorkspaceStorage } from '../../tree/workspace/sharedWorkspaceStorage';
|
||||
import { showConfirmationAsInSettings } from '../../utils/dialogs/showConfirmation';
|
||||
import { localize } from '../../utils/localize';
|
||||
import { type AddWorkspaceConnectionContext } from '../wizards/addWorkspaceConnection/AddWorkspaceConnectionContext';
|
||||
import { ConnectionStringStep } from '../wizards/addWorkspaceConnection/ConnectionStringStep';
|
||||
|
@ -98,6 +99,10 @@ export async function addWorkspaceConnection(context: IActionContext): Promise<v
|
|||
|
||||
// refresh the workspace tree view
|
||||
ext.mongoClustersWorkspaceBranchDataProvider.refresh();
|
||||
|
||||
showConfirmationAsInSettings(
|
||||
localize('showConfirmation.addedWorkspaceConnecdtion', 'New connection has been added to your workspace.'),
|
||||
);
|
||||
}
|
||||
|
||||
function isMongoDBRU(host: string): boolean {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { AzureWizard, nonNullValue, type IActionContext } from '@microsoft/vscode-azext-utils';
|
||||
import { showConfirmationAsInSettings } from '../../utils/dialogs/showConfirmation';
|
||||
import { localize } from '../../utils/localize';
|
||||
import { type DatabaseItem } from '../tree/DatabaseItem';
|
||||
import { type CreateCollectionWizardContext } from '../wizards/create/createWizardContexts';
|
||||
|
@ -31,5 +32,11 @@ export async function createCollection(context: IActionContext, databaseNode?: D
|
|||
|
||||
const newCollectionName = nonNullValue(wizardContext.newCollectionName);
|
||||
|
||||
await databaseNode.createCollection(context, newCollectionName);
|
||||
const success = await databaseNode.createCollection(context, newCollectionName);
|
||||
|
||||
if (success) {
|
||||
showConfirmationAsInSettings(
|
||||
localize('showConfirmation.createdDatabase', 'The "{0}" collection has been created.', newCollectionName),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { AzureWizard, nonNullValue, type IActionContext } from '@microsoft/vscode-azext-utils';
|
||||
import { showConfirmationAsInSettings } from '../../utils/dialogs/showConfirmation';
|
||||
import { localize } from '../../utils/localize';
|
||||
import { CredentialCache } from '../CredentialCache';
|
||||
import { type MongoClusterResourceItem } from '../tree/MongoClusterResourceItem';
|
||||
|
@ -45,5 +46,11 @@ export async function createDatabase(context: IActionContext, clusterNode?: Mong
|
|||
|
||||
const newDatabaseName = nonNullValue(wizardContext.newDatabaseName);
|
||||
|
||||
await clusterNode.createDatabase(context, newDatabaseName);
|
||||
const success = await clusterNode.createDatabase(context, newDatabaseName);
|
||||
|
||||
if (success) {
|
||||
showConfirmationAsInSettings(
|
||||
localize('showConfirmation.createdDatabase', 'The "{0}" database has been created.', newDatabaseName),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { type IActionContext } from '@microsoft/vscode-azext-utils';
|
||||
import { getConfirmationAsInSettings } from '../../utils/confirmations';
|
||||
import { getConfirmationAsInSettings } from '../../utils/dialogs/getConfirmation';
|
||||
import { showConfirmationAsInSettings } from '../../utils/dialogs/showConfirmation';
|
||||
import { localize } from '../../utils/localize';
|
||||
import { type CollectionItem } from '../tree/CollectionItem';
|
||||
|
||||
export async function dropCollection(context: IActionContext, node?: CollectionItem): Promise<void> {
|
||||
|
@ -23,5 +25,15 @@ export async function dropCollection(context: IActionContext, node?: CollectionI
|
|||
return;
|
||||
}
|
||||
|
||||
await node.delete(context);
|
||||
const success = await node.delete(context);
|
||||
|
||||
if (success) {
|
||||
showConfirmationAsInSettings(
|
||||
localize(
|
||||
'showConfirmation.droppedCollection',
|
||||
'The "{0}" collection has been dropped.',
|
||||
node.collectionInfo.name,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { type IActionContext } from '@microsoft/vscode-azext-utils';
|
||||
import { getConfirmationAsInSettings } from '../../utils/confirmations';
|
||||
import { getConfirmationAsInSettings } from '../../utils/dialogs/getConfirmation';
|
||||
import { showConfirmationAsInSettings } from '../../utils/dialogs/showConfirmation';
|
||||
import { localize } from '../../utils/localize';
|
||||
import { type DatabaseItem } from '../tree/DatabaseItem';
|
||||
|
||||
export async function dropDatabase(context: IActionContext, node?: DatabaseItem): Promise<void> {
|
||||
|
@ -23,5 +25,15 @@ export async function dropDatabase(context: IActionContext, node?: DatabaseItem)
|
|||
return;
|
||||
}
|
||||
|
||||
await node.delete(context);
|
||||
const success = await node.delete(context);
|
||||
|
||||
if (success) {
|
||||
showConfirmationAsInSettings(
|
||||
localize(
|
||||
'showConfirmation.droppedDatabase',
|
||||
'The "{0}" database has been dropped.',
|
||||
node.databaseInfo.name,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ import { type IActionContext } from '@microsoft/vscode-azext-utils';
|
|||
import { ext } from '../../extensionVariables';
|
||||
import { WorkspaceResourceType } from '../../tree/workspace/sharedWorkspaceResourceProvider';
|
||||
import { SharedWorkspaceStorage } from '../../tree/workspace/sharedWorkspaceStorage';
|
||||
import { showConfirmationAsInSettings } from '../../utils/dialogs/showConfirmation';
|
||||
import { localize } from '../../utils/localize';
|
||||
import { type MongoClusterWorkspaceItem } from '../tree/workspace/MongoClusterWorkspaceItem';
|
||||
|
||||
export async function removeWorkspaceConnection(
|
||||
|
@ -18,4 +20,11 @@ export async function removeWorkspaceConnection(
|
|||
});
|
||||
|
||||
ext.mongoClustersWorkspaceBranchDataProvider.refresh();
|
||||
|
||||
showConfirmationAsInSettings(
|
||||
localize(
|
||||
'showConfirmation.removedWorkspaceConnecdtion',
|
||||
'The selected connection has been removed from your workspace.',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -55,13 +55,14 @@ export class CollectionItem {
|
|||
async delete(_context: IActionContext): Promise<boolean> {
|
||||
const client = await MongoClustersClient.getClient(this.mongoCluster.id);
|
||||
|
||||
let success = false;
|
||||
await ext.state.showDeleting(this.id, async () => {
|
||||
await client.dropCollection(this.databaseInfo.name, this.collectionInfo.name);
|
||||
success = await client.dropCollection(this.databaseInfo.name, this.collectionInfo.name);
|
||||
});
|
||||
|
||||
ext.state.notifyChildrenChanged(`${this.mongoCluster.id}/${this.databaseInfo.name}`);
|
||||
|
||||
return true;
|
||||
return success;
|
||||
}
|
||||
|
||||
async insertDocuments(_context: IActionContext, documents: Document[]): Promise<InsertDocumentsResult> {
|
||||
|
|
|
@ -48,13 +48,14 @@ export class DatabaseItem {
|
|||
async delete(_context: IActionContext): Promise<boolean> {
|
||||
const client = await MongoClustersClient.getClient(this.mongoCluster.id);
|
||||
|
||||
let success = false;
|
||||
await ext.state.showDeleting(this.id, async () => {
|
||||
await client.dropDatabase(this.databaseInfo.name);
|
||||
success = await client.dropDatabase(this.databaseInfo.name);
|
||||
});
|
||||
|
||||
ext.state.notifyChildrenChanged(this.mongoCluster.id);
|
||||
|
||||
return true;
|
||||
return success;
|
||||
}
|
||||
|
||||
async createCollection(_context: IActionContext, collectionName: string): Promise<boolean> {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { DialogResponses, UserCancelledError } from '@microsoft/vscode-azext-utils';
|
||||
import vscode from 'vscode';
|
||||
import { ext } from '../extensionVariables';
|
||||
import { ext } from '../../extensionVariables';
|
||||
|
||||
enum ConfirmationStyle {
|
||||
wordConfirmation = 'wordConfirmation',
|
|
@ -0,0 +1,18 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import vscode from 'vscode';
|
||||
import { ext } from '../../extensionVariables';
|
||||
import { localize } from '../localize';
|
||||
|
||||
export function showConfirmationAsInSettings(message: string) {
|
||||
const showSummary: boolean | undefined = vscode.workspace
|
||||
.getConfiguration()
|
||||
.get<boolean>(ext.settingsKeys.showOperationSummaries);
|
||||
|
||||
if (showSummary) {
|
||||
vscode.window.showInformationMessage(message, localize('showConfirmation.ok', 'OK'));
|
||||
}
|
||||
}
|
|
@ -318,7 +318,7 @@ export const CollectionView = (): JSX.Element => {
|
|||
return (
|
||||
<CollectionViewContext.Provider value={[currentContext, setCurrentContext]}>
|
||||
<div className="collectionView">
|
||||
{currentContext.isLoading && <ProgressBar thickness="large" className="progressBar" />}
|
||||
{currentContext.isLoading && <ProgressBar thickness="large" shape="square" className="progressBar" />}
|
||||
|
||||
<div className="toolbarMainView">
|
||||
<ToolbarMainView />
|
||||
|
|
|
@ -8,14 +8,16 @@ import { type JSONSchema } from 'vscode-json-languageservice';
|
|||
import { z } from 'zod';
|
||||
import { type MongoClustersClient } from '../../../mongoClusters/MongoClustersClient';
|
||||
import { MongoClustersSession } from '../../../mongoClusters/MongoClusterSession';
|
||||
import { getConfirmationAsInSettings } from '../../../utils/confirmations';
|
||||
import { getConfirmationAsInSettings } from '../../../utils/dialogs/getConfirmation';
|
||||
import { getKnownFields, type FieldEntry } from '../../../utils/json/mongo/autocomplete/getKnownFields';
|
||||
import { publicProcedure, router } from '../../api/extension-server/trpc';
|
||||
|
||||
import { type CollectionItem } from '../../../mongoClusters/tree/CollectionItem';
|
||||
import { showConfirmationAsInSettings } from '../../../utils/dialogs/showConfirmation';
|
||||
// eslint-disable-next-line import/no-internal-modules
|
||||
import basicFindQuerySchema from '../../../utils/json/mongo/autocomplete/basicMongoFindFilterSchema.json';
|
||||
import { generateMongoFindJsonSchema } from '../../../utils/json/mongo/autocomplete/generateMongoFindJsonSchema';
|
||||
import { localize } from '../../../utils/localize';
|
||||
|
||||
export type RouterContext = {
|
||||
sessionId: string;
|
||||
|
@ -171,6 +173,22 @@ export const collectionsViewRouter = router({
|
|||
|
||||
const acknowledged = await client.deleteDocuments(myCtx.databaseName, myCtx.collectionName, input);
|
||||
|
||||
if (acknowledged) {
|
||||
showConfirmationAsInSettings(
|
||||
input.length > 1
|
||||
? localize(
|
||||
'showConfirmation.deletedNdocuments',
|
||||
'{0} documents have been deleted.',
|
||||
input.length,
|
||||
)
|
||||
: localize(
|
||||
'showConfirmation.deletedNdocuments',
|
||||
'{0} document has been deleted.',
|
||||
input.length,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (!acknowledged) {
|
||||
void vscode.window.showErrorMessage('Failed to delete documents. Unknown error.', {
|
||||
modal: true,
|
||||
|
|
|
@ -9,14 +9,14 @@ import { type JSX } from 'react';
|
|||
import { ToolbarDividerTransparent } from '../../collectionView/components/toolbar/ToolbarDividerTransparent';
|
||||
|
||||
interface ToolbarDocumentsProps {
|
||||
viewerMode: string;
|
||||
disableSaveButton: boolean;
|
||||
onValidateRequest: () => void;
|
||||
onRefreshRequest: () => void;
|
||||
onSaveRequest: () => void;
|
||||
}
|
||||
|
||||
export const ToolbarDocuments = ({
|
||||
viewerMode,
|
||||
disableSaveButton,
|
||||
onValidateRequest,
|
||||
onRefreshRequest,
|
||||
onSaveRequest,
|
||||
|
@ -29,7 +29,7 @@ export const ToolbarDocuments = ({
|
|||
aria-label="Save to the database"
|
||||
icon={<SaveRegular />}
|
||||
appearance={'primary'}
|
||||
disabled={viewerMode === 'view'}
|
||||
disabled={disableSaveButton}
|
||||
>
|
||||
Save
|
||||
</ToolbarButton>
|
||||
|
|
|
@ -45,6 +45,7 @@ export const DocumentView = (): JSX.Element => {
|
|||
|
||||
const [editorContent] = configuration.mode === 'add' ? useState('{ }') : useState('{ "loading...": true }');
|
||||
const [isLoading, setIsLoading] = useState(configuration.mode !== 'add');
|
||||
const [isDirty, setIsDirty] = useState(true);
|
||||
|
||||
// a useEffect without a dependency runs only once after the first render only
|
||||
useEffect(() => {
|
||||
|
@ -194,6 +195,7 @@ export const DocumentView = (): JSX.Element => {
|
|||
configuration.documentId = response.documentId;
|
||||
setContent(response.documentStringified);
|
||||
setIsLoading(false);
|
||||
setIsDirty(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error saving document:', error);
|
||||
|
@ -208,9 +210,9 @@ export const DocumentView = (): JSX.Element => {
|
|||
return (
|
||||
<div className="documentView">
|
||||
<div className="toolbarContainer">
|
||||
{isLoading && <ProgressBar thickness="large" className="progressBar" />}
|
||||
{isLoading && <ProgressBar thickness="large" shape="square" className="progressBar" />}
|
||||
<ToolbarDocuments
|
||||
viewerMode={configuration.mode}
|
||||
disableSaveButton={configuration.mode === 'view' || !isDirty}
|
||||
onSaveRequest={handleOnSaveRequest}
|
||||
onValidateRequest={handleOnValidateRequest}
|
||||
onRefreshRequest={handleOnRefreshRequest}
|
||||
|
@ -224,6 +226,9 @@ export const DocumentView = (): JSX.Element => {
|
|||
options={monacoOptions}
|
||||
value={editorContent}
|
||||
onMount={handleMonacoEditorMount}
|
||||
onChange={() => {
|
||||
setIsDirty(true);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -8,6 +8,8 @@ import { type Document } from 'mongodb';
|
|||
import { z } from 'zod';
|
||||
import { type MongoClustersClient } from '../../../mongoClusters/MongoClustersClient';
|
||||
import { MongoClustersSession } from '../../../mongoClusters/MongoClusterSession';
|
||||
import { showConfirmationAsInSettings } from '../../../utils/dialogs/showConfirmation';
|
||||
import { localize } from '../../../utils/localize';
|
||||
import { publicProcedure, router } from '../../api/extension-server/trpc';
|
||||
|
||||
export type RouterContext = {
|
||||
|
@ -89,6 +91,14 @@ export const documentsViewRouter = router({
|
|||
|
||||
myCtx.viewPanelTitleSetter(`${myCtx.databaseName}/${myCtx.collectionName}/${newDocumentId}`);
|
||||
|
||||
showConfirmationAsInSettings(
|
||||
localize(
|
||||
'showConfirmation.mongoClusters.documentView.saveDocument',
|
||||
'The document with the _id "{0}" has been saved.',
|
||||
newDocumentId,
|
||||
),
|
||||
);
|
||||
|
||||
return { documentStringified: newDocumentStringified, documentId: newDocumentId };
|
||||
}),
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче