Replace window.confirm and window.alert with modal dialog (#965)
This commit is contained in:
parent
7e0c4b7290
commit
042f980b89
|
@ -23,13 +23,66 @@ export interface DialogState {
|
|||
dialogProps?: DialogProps;
|
||||
openDialog: (props: DialogProps) => void;
|
||||
closeDialog: () => void;
|
||||
showOkCancelModalDialog: (
|
||||
title: string,
|
||||
subText: string,
|
||||
okLabel: string,
|
||||
onOk: () => void,
|
||||
cancelLabel: string,
|
||||
onCancel: () => void,
|
||||
choiceGroupProps?: IChoiceGroupProps,
|
||||
textFieldProps?: TextFieldProps,
|
||||
primaryButtonDisabled?: boolean
|
||||
) => void;
|
||||
showOkModalDialog: (title: string, subText: string) => void;
|
||||
}
|
||||
|
||||
export const useDialog: UseStore<DialogState> = create((set) => ({
|
||||
export const useDialog: UseStore<DialogState> = create((set, get) => ({
|
||||
visible: false,
|
||||
openDialog: (props: DialogProps) => set(() => ({ visible: true, dialogProps: props })),
|
||||
closeDialog: () =>
|
||||
set((state) => ({ visible: false, openDialog: state.openDialog, closeDialog: state.closeDialog }), true),
|
||||
showOkCancelModalDialog: (
|
||||
title: string,
|
||||
subText: string,
|
||||
okLabel: string,
|
||||
onOk: () => void,
|
||||
cancelLabel: string,
|
||||
onCancel: () => void,
|
||||
choiceGroupProps?: IChoiceGroupProps,
|
||||
textFieldProps?: TextFieldProps,
|
||||
primaryButtonDisabled?: boolean
|
||||
): void =>
|
||||
get().openDialog({
|
||||
isModal: true,
|
||||
title,
|
||||
subText,
|
||||
primaryButtonText: okLabel,
|
||||
secondaryButtonText: cancelLabel,
|
||||
onPrimaryButtonClick: () => {
|
||||
get().closeDialog();
|
||||
onOk && onOk();
|
||||
},
|
||||
onSecondaryButtonClick: () => {
|
||||
get().closeDialog();
|
||||
onCancel && onCancel();
|
||||
},
|
||||
choiceGroupProps,
|
||||
textFieldProps,
|
||||
primaryButtonDisabled,
|
||||
}),
|
||||
showOkModalDialog: (title: string, subText: string): void =>
|
||||
get().openDialog({
|
||||
isModal: true,
|
||||
title,
|
||||
subText,
|
||||
primaryButtonText: "Close",
|
||||
secondaryButtonText: undefined,
|
||||
onPrimaryButtonClick: () => {
|
||||
get().closeDialog();
|
||||
},
|
||||
onSecondaryButtonClick: undefined,
|
||||
}),
|
||||
}));
|
||||
|
||||
export interface TextFieldProps extends ITextFieldProps {
|
||||
|
|
|
@ -29,6 +29,7 @@ import { QueriesClient } from "../../../Common/QueriesClient";
|
|||
import * as DataModels from "../../../Contracts/DataModels";
|
||||
import { Action } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { useDialog } from "../Dialog";
|
||||
|
||||
const title = "Open Saved Queries";
|
||||
|
||||
|
@ -222,7 +223,11 @@ export class QueriesGridComponent extends React.Component<QueriesGridComponentPr
|
|||
key: "Delete",
|
||||
text: "Delete query",
|
||||
onClick: async () => {
|
||||
if (window.confirm("Are you sure you want to delete this query?")) {
|
||||
useDialog.getState().showOkCancelModalDialog(
|
||||
"Confirm delete",
|
||||
"Are you sure you want to delete this query?",
|
||||
"Delete",
|
||||
async () => {
|
||||
const startKey: number = TelemetryProcessor.traceStart(Action.DeleteSavedQuery, {
|
||||
dataExplorerArea: Constants.Areas.ContextualPane,
|
||||
paneTitle: title,
|
||||
|
@ -250,7 +255,10 @@ export class QueriesGridComponent extends React.Component<QueriesGridComponentPr
|
|||
);
|
||||
}
|
||||
await this.fetchSavedQueries(); // get latest state
|
||||
}
|
||||
},
|
||||
"Cancel",
|
||||
undefined
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
|
@ -17,7 +17,6 @@ describe("DataSampleUtils", () => {
|
|||
collections: ko.observableArray<Collection>([collection]),
|
||||
} as Database;
|
||||
const explorer = {} as Explorer;
|
||||
explorer.showOkModalDialog = () => {};
|
||||
useDatabases.getState().addDatabases([database]);
|
||||
const dataSamplesUtil = new DataSamplesUtil(explorer);
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import { userContext } from "../../UserContext";
|
||||
import { logConsoleError, logConsoleInfo } from "../../Utils/NotificationConsoleUtils";
|
||||
import { useDialog } from "../Controls/Dialog";
|
||||
import Explorer from "../Explorer";
|
||||
import { useDatabases } from "../useDatabases";
|
||||
import { ContainerSampleGenerator } from "./ContainerSampleGenerator";
|
||||
|
@ -20,7 +21,7 @@ export class DataSamplesUtil {
|
|||
const containerName = generator.getCollectionId();
|
||||
if (this.hasContainer(databaseName, containerName, useDatabases.getState().databases)) {
|
||||
const msg = `The container ${containerName} in database ${databaseName} already exists. Please delete it and retry.`;
|
||||
this.container.showOkModalDialog(DataSamplesUtil.DialogTitle, msg);
|
||||
useDialog.getState().showOkModalDialog(DataSamplesUtil.DialogTitle, msg);
|
||||
logConsoleError(msg);
|
||||
return;
|
||||
}
|
||||
|
@ -29,7 +30,7 @@ export class DataSamplesUtil {
|
|||
.createSampleContainerAsync()
|
||||
.catch((error) => logConsoleError(`Error creating sample container: ${error}`));
|
||||
const msg = `The sample ${containerName} in database ${databaseName} has been successfully created.`;
|
||||
this.container.showOkModalDialog(DataSamplesUtil.DialogTitle, msg);
|
||||
useDialog.getState().showOkModalDialog(DataSamplesUtil.DialogTitle, msg);
|
||||
logConsoleInfo(msg);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { IChoiceGroupProps } from "@fluentui/react";
|
||||
import * as ko from "knockout";
|
||||
import React from "react";
|
||||
import _ from "underscore";
|
||||
|
@ -35,7 +34,7 @@ import { fromContentUri, toRawContentUri } from "../Utils/GitHubUtils";
|
|||
import * as NotificationConsoleUtils from "../Utils/NotificationConsoleUtils";
|
||||
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../Utils/NotificationConsoleUtils";
|
||||
import "./ComponentRegisterer";
|
||||
import { DialogProps, TextFieldProps, useDialog } from "./Controls/Dialog";
|
||||
import { DialogProps, useDialog } from "./Controls/Dialog";
|
||||
import { GalleryTab as GalleryTabKind } from "./Controls/NotebookGallery/GalleryViewerComponent";
|
||||
import { useCommandBar } from "./Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import * as FileSystemUtil from "./Notebook/FileSystemUtil";
|
||||
|
@ -548,7 +547,7 @@ export default class Explorer {
|
|||
const promise = this.notebookManager?.notebookContentClient.uploadFileAsync(name, content, parent);
|
||||
promise
|
||||
.then(() => this.resourceTree.triggerRender())
|
||||
.catch((reason) => this.showOkModalDialog("Unable to upload file", reason));
|
||||
.catch((reason) => useDialog.getState().showOkModalDialog("Unable to upload file", reason));
|
||||
return promise;
|
||||
}
|
||||
|
||||
|
@ -614,51 +613,6 @@ export default class Explorer {
|
|||
this.notebookManager?.openCopyNotebookPane(name, content);
|
||||
}
|
||||
|
||||
public showOkModalDialog(title: string, msg: string): void {
|
||||
useDialog.getState().openDialog({
|
||||
isModal: true,
|
||||
title,
|
||||
subText: msg,
|
||||
primaryButtonText: "Close",
|
||||
secondaryButtonText: undefined,
|
||||
onPrimaryButtonClick: () => {
|
||||
useDialog.getState().closeDialog();
|
||||
},
|
||||
onSecondaryButtonClick: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
public showOkCancelModalDialog(
|
||||
title: string,
|
||||
msg: string,
|
||||
okLabel: string,
|
||||
onOk: () => void,
|
||||
cancelLabel: string,
|
||||
onCancel: () => void,
|
||||
choiceGroupProps?: IChoiceGroupProps,
|
||||
textFieldProps?: TextFieldProps,
|
||||
isPrimaryButtonDisabled?: boolean
|
||||
): void {
|
||||
useDialog.getState().openDialog({
|
||||
isModal: true,
|
||||
title,
|
||||
subText: msg,
|
||||
primaryButtonText: okLabel,
|
||||
secondaryButtonText: cancelLabel,
|
||||
onPrimaryButtonClick: () => {
|
||||
useDialog.getState().closeDialog();
|
||||
onOk && onOk();
|
||||
},
|
||||
onSecondaryButtonClick: () => {
|
||||
useDialog.getState().closeDialog();
|
||||
onCancel && onCancel();
|
||||
},
|
||||
choiceGroupProps,
|
||||
textFieldProps,
|
||||
primaryButtonDisabled: isPrimaryButtonDisabled,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: To keep it simple, this creates a disconnected NotebookContentItem that is not connected to the resource tree.
|
||||
* Connecting it to a tree possibly requires the intermediate missing folders if the item is nested in a subfolder.
|
||||
|
@ -732,7 +686,9 @@ export default class Explorer {
|
|||
return tab.notebookPath && FileSystemUtil.isPathEqual(tab.notebookPath(), notebookFile.path);
|
||||
});
|
||||
if (openedNotebookTabs.length > 0) {
|
||||
this.showOkModalDialog("Unable to rename file", "This file is being edited. Please close the tab and try again.");
|
||||
useDialog
|
||||
.getState()
|
||||
.showOkModalDialog("Unable to rename file", "This file is being edited. Please close the tab and try again.");
|
||||
} else {
|
||||
useSidePanel.getState().openSidePanel(
|
||||
"Rename Notebook",
|
||||
|
@ -862,7 +818,9 @@ export default class Explorer {
|
|||
return tab.notebookPath && FileSystemUtil.isPathEqual(tab.notebookPath(), item.path);
|
||||
});
|
||||
if (openedNotebookTabs.length > 0) {
|
||||
this.showOkModalDialog("Unable to delete file", "This file is being edited. Please close the tab and try again.");
|
||||
useDialog
|
||||
.getState()
|
||||
.showOkModalDialog("Unable to delete file", "This file is being edited. Please close the tab and try again.");
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ import { useTabs } from "../../../hooks/useTabs";
|
|||
import { Action as TelemetryAction, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { logConsoleError, logConsoleInfo } from "../../../Utils/NotificationConsoleUtils";
|
||||
import { useDialog } from "../../Controls/Dialog";
|
||||
import * as FileSystemUtil from "../FileSystemUtil";
|
||||
import * as cdbActions from "../NotebookComponent/actions";
|
||||
import { NotebookUtil } from "../NotebookUtil";
|
||||
|
@ -686,10 +687,8 @@ const handleKernelConnectionLostEpic = (
|
|||
logConsoleError(msg);
|
||||
logFailureToTelemetry(state, "Kernel restart error", msg);
|
||||
|
||||
const explorer = window.dataExplorer;
|
||||
if (explorer) {
|
||||
explorer.showOkModalDialog("kernel restarts", msg);
|
||||
}
|
||||
useDialog.getState().showOkModalDialog("kernel restarts", msg);
|
||||
|
||||
return of(EMPTY);
|
||||
}
|
||||
|
||||
|
@ -773,8 +772,7 @@ const closeUnsupportedMimetypesEpic = (
|
|||
ofType(actions.FETCH_CONTENT_FULFILLED),
|
||||
mergeMap((action) => {
|
||||
const mimetype = action.payload.model.mimetype;
|
||||
const explorer = window.dataExplorer;
|
||||
if (explorer && !TextFile.handles(mimetype)) {
|
||||
if (!TextFile.handles(mimetype)) {
|
||||
const filepath = action.payload.filepath;
|
||||
// Close tab and show error message
|
||||
useTabs
|
||||
|
@ -783,7 +781,7 @@ const closeUnsupportedMimetypesEpic = (
|
|||
(tab: any) => (tab as any).notebookPath && FileSystemUtil.isPathEqual((tab as any).notebookPath(), filepath)
|
||||
);
|
||||
const msg = `${filepath} cannot be rendered. Please download the file, in order to view it outside of Data Explorer.`;
|
||||
explorer.showOkModalDialog("File cannot be rendered", msg);
|
||||
useDialog.getState().showOkModalDialog("File cannot be rendered", msg);
|
||||
logConsoleError(msg);
|
||||
}
|
||||
return EMPTY;
|
||||
|
@ -803,8 +801,6 @@ const closeContentFailedToFetchEpic = (
|
|||
return action$.pipe(
|
||||
ofType(actions.FETCH_CONTENT_FAILED),
|
||||
mergeMap((action) => {
|
||||
const explorer = window.dataExplorer;
|
||||
if (explorer) {
|
||||
const filepath = action.payload.filepath;
|
||||
// Close tab and show error message
|
||||
useTabs
|
||||
|
@ -813,9 +809,8 @@ const closeContentFailedToFetchEpic = (
|
|||
(tab: any) => (tab as any).notebookPath && FileSystemUtil.isPathEqual((tab as any).notebookPath(), filepath)
|
||||
);
|
||||
const msg = `Failed to load file: ${filepath}.`;
|
||||
explorer.showOkModalDialog("Failure to load", msg);
|
||||
useDialog.getState().showOkModalDialog("Failure to load", msg);
|
||||
logConsoleError(msg);
|
||||
}
|
||||
return EMPTY;
|
||||
})
|
||||
);
|
||||
|
|
|
@ -18,6 +18,7 @@ import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstan
|
|||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "../../UserContext";
|
||||
import { getFullName } from "../../Utils/UserUtils";
|
||||
import { useDialog } from "../Controls/Dialog";
|
||||
import Explorer from "../Explorer";
|
||||
import { CopyNotebookPane } from "../Panes/CopyNotebookPane/CopyNotebookPane";
|
||||
import { GitHubReposPanel } from "../Panes/GitHubReposPanel/GitHubReposPanel";
|
||||
|
@ -172,7 +173,9 @@ export default class NotebookManager {
|
|||
if (error.status === HttpStatusCodes.Unauthorized) {
|
||||
this.gitHubOAuthService.resetToken();
|
||||
|
||||
this.params.container.showOkCancelModalDialog(
|
||||
useDialog
|
||||
.getState()
|
||||
.showOkCancelModalDialog(
|
||||
undefined,
|
||||
"Cosmos DB cannot access your Github account anymore. Please connect to GitHub again.",
|
||||
"Connect to GitHub",
|
||||
|
@ -196,7 +199,7 @@ export default class NotebookManager {
|
|||
private promptForCommitMsg = (title: string, primaryButtonLabel: string) => {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
let commitMsg = "Committed from Azure Cosmos DB Notebooks";
|
||||
this.params.container.showOkCancelModalDialog(
|
||||
useDialog.getState().showOkCancelModalDialog(
|
||||
title || "Commit",
|
||||
undefined,
|
||||
primaryButtonLabel || "Commit",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Q from "q";
|
||||
import { userContext } from "../../../UserContext";
|
||||
import { useDialog } from "../../Controls/Dialog";
|
||||
import Explorer from "../../Explorer";
|
||||
import * as Entities from "../Entities";
|
||||
import * as DataTableUtilities from "./DataTableUtilities";
|
||||
|
@ -69,11 +70,16 @@ export default class TableCommands {
|
|||
return null; // Error
|
||||
}
|
||||
var entitiesToDelete: Entities.ITableEntity[] = viewModel.selected();
|
||||
let deleteMessage: string = "Are you sure you want to delete the selected entities?";
|
||||
if (userContext.apiType === "Cassandra") {
|
||||
deleteMessage = "Are you sure you want to delete the selected rows?";
|
||||
}
|
||||
if (window.confirm(deleteMessage)) {
|
||||
const deleteMessage: string =
|
||||
userContext.apiType === "Cassandra"
|
||||
? "Are you sure you want to delete the selected rows?"
|
||||
: "Are you sure you want to delete the selected entities?";
|
||||
|
||||
useDialog.getState().showOkCancelModalDialog(
|
||||
"Confirm delete",
|
||||
deleteMessage,
|
||||
"Delete",
|
||||
() => {
|
||||
viewModel.queryTablesTab.container.tableDataClient
|
||||
.deleteDocuments(viewModel.queryTablesTab.collection, entitiesToDelete)
|
||||
.then((results: any) => {
|
||||
|
@ -81,7 +87,11 @@ export default class TableCommands {
|
|||
viewModel.redrawTableThrottled();
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
"Cancel",
|
||||
undefined
|
||||
);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import * as ViewModels from "../../Contracts/ViewModels";
|
|||
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||
import { useDialog } from "../Controls/Dialog";
|
||||
import Explorer from "../Explorer";
|
||||
import { AccessibleVerticalList } from "../Tree/AccessibleVerticalList";
|
||||
import ConflictId from "../Tree/ConflictId";
|
||||
|
@ -228,7 +229,7 @@ export default class ConflictsTab extends TabsBase {
|
|||
this._documentsIterator = this.createIterator();
|
||||
await this.loadNextPage();
|
||||
} catch (error) {
|
||||
window.alert(getErrorMessage(error));
|
||||
useDialog.getState().showOkModalDialog("Refresh documents grid failed", getErrorMessage(error));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,10 +253,23 @@ export default class ConflictsTab extends TabsBase {
|
|||
}
|
||||
|
||||
public onAcceptChangesClick = async (): Promise<void> => {
|
||||
if (this.isEditorDirty() && !this._isIgnoreDirtyEditor()) {
|
||||
return;
|
||||
if (this.isEditorDirty()) {
|
||||
useDialog
|
||||
.getState()
|
||||
.showOkCancelModalDialog(
|
||||
"Unsaved changes",
|
||||
"Changes will be lost. Do you want to continue?",
|
||||
"OK",
|
||||
async () => await this.resolveConflict(),
|
||||
"Cancel",
|
||||
undefined
|
||||
);
|
||||
} else {
|
||||
await this.resolveConflict();
|
||||
}
|
||||
};
|
||||
|
||||
private resolveConflict = async (): Promise<void> => {
|
||||
this.isExecutionError(false);
|
||||
this.isExecuting(true);
|
||||
|
||||
|
@ -318,7 +332,7 @@ export default class ConflictsTab extends TabsBase {
|
|||
} catch (error) {
|
||||
this.isExecutionError(true);
|
||||
const errorMessage = getErrorMessage(error);
|
||||
window.alert(errorMessage);
|
||||
useDialog.getState().showOkModalDialog("Resolve conflict failed", errorMessage);
|
||||
TelemetryProcessor.traceFailure(
|
||||
Action.ResolveConflict,
|
||||
{
|
||||
|
@ -372,7 +386,7 @@ export default class ConflictsTab extends TabsBase {
|
|||
} catch (error) {
|
||||
this.isExecutionError(true);
|
||||
const errorMessage = getErrorMessage(error);
|
||||
window.alert(errorMessage);
|
||||
useDialog.getState().showOkModalDialog("Delete conflict failed", errorMessage);
|
||||
TelemetryProcessor.traceFailure(
|
||||
Action.DeleteConflict,
|
||||
{
|
||||
|
@ -662,11 +676,6 @@ export default class ConflictsTab extends TabsBase {
|
|||
return jsonObject;
|
||||
}
|
||||
|
||||
private _isIgnoreDirtyEditor = (): boolean => {
|
||||
var msg: string = "Changes will be lost. Do you want to continue?";
|
||||
return window.confirm(msg);
|
||||
};
|
||||
|
||||
private _getPartitionKeyPropertyHeader(): string {
|
||||
return (
|
||||
(this.partitionKey &&
|
||||
|
|
|
@ -25,6 +25,7 @@ import { userContext } from "../../UserContext";
|
|||
import { logConsoleError } from "../../Utils/NotificationConsoleUtils";
|
||||
import * as QueryUtils from "../../Utils/QueryUtils";
|
||||
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||
import { useDialog } from "../Controls/Dialog";
|
||||
import Explorer from "../Explorer";
|
||||
import { AccessibleVerticalList } from "../Tree/AccessibleVerticalList";
|
||||
import DocumentId from "../Tree/DocumentId";
|
||||
|
@ -378,7 +379,7 @@ export default class DocumentsTab extends TabsBase {
|
|||
this.isFilterExpanded(false);
|
||||
document.getElementById("errorStatusIcon")?.focus();
|
||||
} catch (error) {
|
||||
window.alert(getErrorMessage(error));
|
||||
useDialog.getState().showOkModalDialog("Refresh documents grid failed", getErrorMessage(error));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -401,18 +402,29 @@ export default class DocumentsTab extends TabsBase {
|
|||
return Q();
|
||||
}
|
||||
|
||||
public onNewDocumentClick = (): Q.Promise<any> => {
|
||||
if (this.isEditorDirty() && !this._isIgnoreDirtyEditor()) {
|
||||
return Q();
|
||||
public onNewDocumentClick = (): void => {
|
||||
if (this.isEditorDirty()) {
|
||||
useDialog
|
||||
.getState()
|
||||
.showOkCancelModalDialog(
|
||||
"Unsaved changes",
|
||||
"Changes will be lost. Do you want to continue?",
|
||||
"OK",
|
||||
() => this.initializeNewDocument(),
|
||||
"Cancel",
|
||||
undefined
|
||||
);
|
||||
} else {
|
||||
this.initializeNewDocument();
|
||||
}
|
||||
this.selectedDocumentId(null);
|
||||
};
|
||||
|
||||
private initializeNewDocument = (): void => {
|
||||
this.selectedDocumentId(null);
|
||||
const defaultDocument: string = this.renderObjectForEditor({ id: "replace_with_new_document_id" }, null, 4);
|
||||
this.initialDocumentContent(defaultDocument);
|
||||
this.selectedDocumentContent.setBaseline(defaultDocument);
|
||||
this.editorState(ViewModels.DocumentExplorerState.newDocumentValid);
|
||||
|
||||
return Q();
|
||||
};
|
||||
|
||||
public onSaveNewDocumentClick = (): Promise<any> => {
|
||||
|
@ -453,7 +465,7 @@ export default class DocumentsTab extends TabsBase {
|
|||
(error) => {
|
||||
this.isExecutionError(true);
|
||||
const errorMessage = getErrorMessage(error);
|
||||
window.alert(errorMessage);
|
||||
useDialog.getState().showOkModalDialog("Create document failed", errorMessage);
|
||||
TelemetryProcessor.traceFailure(
|
||||
Action.CreateDocument,
|
||||
{
|
||||
|
@ -516,7 +528,7 @@ export default class DocumentsTab extends TabsBase {
|
|||
(error) => {
|
||||
this.isExecutionError(true);
|
||||
const errorMessage = getErrorMessage(error);
|
||||
window.alert(errorMessage);
|
||||
useDialog.getState().showOkModalDialog("Update document failed", errorMessage);
|
||||
TelemetryProcessor.traceFailure(
|
||||
Action.UpdateDocument,
|
||||
{
|
||||
|
@ -546,9 +558,16 @@ export default class DocumentsTab extends TabsBase {
|
|||
? "Are you sure you want to delete the selected item ?"
|
||||
: "Are you sure you want to delete the selected document ?";
|
||||
|
||||
if (window.confirm(msg)) {
|
||||
await this._deleteDocument(selectedDocumentId);
|
||||
}
|
||||
useDialog
|
||||
.getState()
|
||||
.showOkCancelModalDialog(
|
||||
"Confirm delete",
|
||||
msg,
|
||||
"Delete",
|
||||
async () => await this._deleteDocument(selectedDocumentId),
|
||||
"Cancel",
|
||||
undefined
|
||||
);
|
||||
};
|
||||
|
||||
public onValidDocumentEdit(): Q.Promise<any> {
|
||||
|
@ -617,11 +636,6 @@ export default class DocumentsTab extends TabsBase {
|
|||
}
|
||||
}
|
||||
|
||||
private _isIgnoreDirtyEditor = (): boolean => {
|
||||
var msg: string = "Changes will be lost. Do you want to continue?";
|
||||
return window.confirm(msg);
|
||||
};
|
||||
|
||||
protected __deleteDocument(documentId: DocumentId): Promise<void> {
|
||||
return deleteDocument(this.collection, documentId);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import * as DataModels from "../../Contracts/DataModels";
|
|||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { useDialog } from "../Controls/Dialog";
|
||||
import DocumentId from "../Tree/DocumentId";
|
||||
import ObjectId from "../Tree/ObjectId";
|
||||
import DocumentsTab from "./DocumentsTab";
|
||||
|
@ -111,7 +112,7 @@ export default class MongoDocumentsTab extends DocumentsTab {
|
|||
(error) => {
|
||||
this.isExecutionError(true);
|
||||
const errorMessage = getErrorMessage(error);
|
||||
window.alert(errorMessage);
|
||||
useDialog.getState().showOkModalDialog("Create document failed", errorMessage);
|
||||
TelemetryProcessor.traceFailure(
|
||||
Action.CreateDocument,
|
||||
{
|
||||
|
@ -169,7 +170,7 @@ export default class MongoDocumentsTab extends DocumentsTab {
|
|||
(error) => {
|
||||
this.isExecutionError(true);
|
||||
const errorMessage = getErrorMessage(error);
|
||||
window.alert(errorMessage);
|
||||
useDialog.getState().showOkModalDialog("Update document failed", errorMessage);
|
||||
TelemetryProcessor.traceFailure(
|
||||
Action.UpdateDocument,
|
||||
{
|
||||
|
|
|
@ -17,6 +17,7 @@ import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
|||
import * as NotebookConfigurationUtils from "../../Utils/NotebookConfigurationUtils";
|
||||
import { logConsoleInfo } from "../../Utils/NotificationConsoleUtils";
|
||||
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||
import { useDialog } from "../Controls/Dialog";
|
||||
import * as CommandBarComponentButtonFactory from "../Menus/CommandBar/CommandBarComponentButtonFactory";
|
||||
import { KernelSpecsDisplay } from "../Notebook/NotebookClientV2";
|
||||
import * as CdbActions from "../Notebook/NotebookComponent/actions";
|
||||
|
@ -59,7 +60,9 @@ export default class NotebookTabV2 extends NotebookTabBase {
|
|||
};
|
||||
|
||||
if (this.notebookComponentAdapter.isContentDirty()) {
|
||||
this.container.showOkCancelModalDialog(
|
||||
useDialog
|
||||
.getState()
|
||||
.showOkCancelModalDialog(
|
||||
"Close without saving?",
|
||||
`File has unsaved changes, close without saving?`,
|
||||
"Close",
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import Q from "q";
|
||||
import { extractPartitionKey } from "@azure/cosmos";
|
||||
import * as ko from "knockout";
|
||||
import * as Constants from "../../Common/Constants";
|
||||
import DocumentId from "./DocumentId";
|
||||
import * as DataModels from "../../Contracts/DataModels";
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import { extractPartitionKey } from "@azure/cosmos";
|
||||
import ConflictsTab from "../Tabs/ConflictsTab";
|
||||
import { readDocument } from "../../Common/dataAccess/readDocument";
|
||||
import * as DataModels from "../../Contracts/DataModels";
|
||||
import { useDialog } from "../Controls/Dialog";
|
||||
import ConflictsTab from "../Tabs/ConflictsTab";
|
||||
import DocumentId from "./DocumentId";
|
||||
|
||||
export default class ConflictId {
|
||||
public container: ConflictsTab;
|
||||
|
@ -50,13 +49,20 @@ export default class ConflictId {
|
|||
}
|
||||
|
||||
public click() {
|
||||
if (
|
||||
!this.container.isEditorDirty() ||
|
||||
window.confirm("Your unsaved changes will be lost. Do you want to continue?")
|
||||
) {
|
||||
if (this.container.isEditorDirty()) {
|
||||
useDialog
|
||||
.getState()
|
||||
.showOkCancelModalDialog(
|
||||
"Unsaved changes",
|
||||
"Your unsaved changes will be lost. Do you want to continue?",
|
||||
"OK",
|
||||
() => this.loadConflict(),
|
||||
"Cancel",
|
||||
undefined
|
||||
);
|
||||
} else {
|
||||
this.loadConflict();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public async loadConflict(): Promise<void> {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import * as ko from "knockout";
|
||||
import * as DataModels from "../../Contracts/DataModels";
|
||||
import { useDialog } from "../Controls/Dialog";
|
||||
import DocumentsTab from "../Tabs/DocumentsTab";
|
||||
|
||||
export default class DocumentId {
|
||||
|
@ -28,10 +29,20 @@ export default class DocumentId {
|
|||
}
|
||||
|
||||
public click() {
|
||||
if (!this.container.isEditorDirty() || window.confirm("Your unsaved changes will be lost.")) {
|
||||
if (this.container.isEditorDirty()) {
|
||||
useDialog
|
||||
.getState()
|
||||
.showOkCancelModalDialog(
|
||||
"Unsaved changes",
|
||||
"Your unsaved changes will be lost. Do you want to continue?",
|
||||
"OK",
|
||||
() => this.loadDocument(),
|
||||
"Cancel",
|
||||
undefined
|
||||
);
|
||||
} else {
|
||||
this.loadDocument();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public partitionKeyHeader(): Object {
|
||||
|
|
|
@ -24,6 +24,7 @@ import { isServerlessAccount } from "../../Utils/CapabilityUtils";
|
|||
import * as GitHubUtils from "../../Utils/GitHubUtils";
|
||||
import * as ResourceTreeContextMenuButtonFactory from "../ContextMenuButtonFactory";
|
||||
import { AccordionComponent, AccordionItemComponent } from "../Controls/Accordion/AccordionComponent";
|
||||
import { useDialog } from "../Controls/Dialog";
|
||||
import { TreeComponent, TreeNode, TreeNodeMenuItem } from "../Controls/TreeComponent/TreeComponent";
|
||||
import Explorer from "../Explorer";
|
||||
import { useCommandBar } from "../Menus/CommandBar/CommandBarComponentAdapter";
|
||||
|
@ -254,7 +255,9 @@ export const ResourceTree: React.FC<ResourceTreeProps> = ({ container }: Resourc
|
|||
label: "Delete",
|
||||
iconSrc: DeleteIcon,
|
||||
onClick: () => {
|
||||
container.showOkCancelModalDialog(
|
||||
useDialog
|
||||
.getState()
|
||||
.showOkCancelModalDialog(
|
||||
"Confirm delete",
|
||||
`Are you sure you want to delete "${item.name}"`,
|
||||
"Delete",
|
||||
|
@ -319,7 +322,9 @@ export const ResourceTree: React.FC<ResourceTreeProps> = ({ container }: Resourc
|
|||
label: "Delete",
|
||||
iconSrc: DeleteIcon,
|
||||
onClick: () => {
|
||||
container.showOkCancelModalDialog(
|
||||
useDialog
|
||||
.getState()
|
||||
.showOkCancelModalDialog(
|
||||
"Confirm delete",
|
||||
`Are you sure you want to delete "${item.name}?"`,
|
||||
"Delete",
|
||||
|
|
|
@ -27,6 +27,7 @@ import { isServerlessAccount } from "../../Utils/CapabilityUtils";
|
|||
import * as GitHubUtils from "../../Utils/GitHubUtils";
|
||||
import * as ResourceTreeContextMenuButtonFactory from "../ContextMenuButtonFactory";
|
||||
import { AccordionComponent, AccordionItemComponent } from "../Controls/Accordion/AccordionComponent";
|
||||
import { useDialog } from "../Controls/Dialog";
|
||||
import { TreeComponent, TreeNode, TreeNodeMenuItem } from "../Controls/TreeComponent/TreeComponent";
|
||||
import Explorer from "../Explorer";
|
||||
import { useCommandBar } from "../Menus/CommandBar/CommandBarComponentAdapter";
|
||||
|
@ -712,7 +713,9 @@ export class ResourceTreeAdapter implements ReactAdapter {
|
|||
label: "Delete",
|
||||
iconSrc: DeleteIcon,
|
||||
onClick: () => {
|
||||
this.container.showOkCancelModalDialog(
|
||||
useDialog
|
||||
.getState()
|
||||
.showOkCancelModalDialog(
|
||||
"Confirm delete",
|
||||
`Are you sure you want to delete "${item.name}"`,
|
||||
"Delete",
|
||||
|
@ -777,7 +780,9 @@ export class ResourceTreeAdapter implements ReactAdapter {
|
|||
label: "Delete",
|
||||
iconSrc: DeleteIcon,
|
||||
onClick: () => {
|
||||
this.container.showOkCancelModalDialog(
|
||||
useDialog
|
||||
.getState()
|
||||
.showOkCancelModalDialog(
|
||||
"Confirm delete",
|
||||
`Are you sure you want to delete "${item.name}?"`,
|
||||
"Delete",
|
||||
|
|
|
@ -8,6 +8,7 @@ import { useTabs } from "../../hooks/useTabs";
|
|||
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "../../UserContext";
|
||||
import { useDialog } from "../Controls/Dialog";
|
||||
import Explorer from "../Explorer";
|
||||
import { getErrorMessage } from "../Tables/Utilities";
|
||||
import { NewStoredProcedureTab } from "../Tabs/StoredProcedureTab/StoredProcedureTab";
|
||||
|
@ -138,10 +139,11 @@ export default class StoredProcedure {
|
|||
}
|
||||
};
|
||||
public delete() {
|
||||
if (!window.confirm("Are you sure you want to delete the stored procedure?")) {
|
||||
return;
|
||||
}
|
||||
|
||||
useDialog.getState().showOkCancelModalDialog(
|
||||
"Confirm delete",
|
||||
"Are you sure you want to delete the stored procedure?",
|
||||
"Delete",
|
||||
() => {
|
||||
deleteStoredProcedure(this.collection.databaseId, this.collection.id(), this.id()).then(
|
||||
() => {
|
||||
useTabs.getState().closeTabsByComparator((tab: TabsBase) => tab.node && tab.node.rid === this.rid);
|
||||
|
@ -149,6 +151,10 @@ export default class StoredProcedure {
|
|||
},
|
||||
(reason) => {}
|
||||
);
|
||||
},
|
||||
"Cancel",
|
||||
undefined
|
||||
);
|
||||
}
|
||||
|
||||
public execute(params: string[], partitionKeyValue?: string): void {
|
||||
|
|
|
@ -6,6 +6,7 @@ import * as ViewModels from "../../Contracts/ViewModels";
|
|||
import { useTabs } from "../../hooks/useTabs";
|
||||
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { useDialog } from "../Controls/Dialog";
|
||||
import Explorer from "../Explorer";
|
||||
import TriggerTab from "../Tabs/TriggerTab";
|
||||
import { useSelectedNode } from "../useSelectedNode";
|
||||
|
@ -99,10 +100,11 @@ export default class Trigger {
|
|||
};
|
||||
|
||||
public delete() {
|
||||
if (!window.confirm("Are you sure you want to delete the trigger?")) {
|
||||
return;
|
||||
}
|
||||
|
||||
useDialog.getState().showOkCancelModalDialog(
|
||||
"Confirm delete",
|
||||
"Are you sure you want to delete the trigger?",
|
||||
"Delete",
|
||||
() => {
|
||||
deleteTrigger(this.collection.databaseId, this.collection.id(), this.id()).then(
|
||||
() => {
|
||||
useTabs.getState().closeTabsByComparator((tab) => tab.node && tab.node.rid === this.rid);
|
||||
|
@ -110,5 +112,9 @@ export default class Trigger {
|
|||
},
|
||||
(reason) => {}
|
||||
);
|
||||
},
|
||||
"Cancel",
|
||||
undefined
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import * as ViewModels from "../../Contracts/ViewModels";
|
|||
import { useTabs } from "../../hooks/useTabs";
|
||||
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { useDialog } from "../Controls/Dialog";
|
||||
import Explorer from "../Explorer";
|
||||
import UserDefinedFunctionTab from "../Tabs/UserDefinedFunctionTab";
|
||||
import { useSelectedNode } from "../useSelectedNode";
|
||||
|
@ -95,10 +96,11 @@ export default class UserDefinedFunction {
|
|||
}
|
||||
|
||||
public delete() {
|
||||
if (!window.confirm("Are you sure you want to delete the user defined function?")) {
|
||||
return;
|
||||
}
|
||||
|
||||
useDialog.getState().showOkCancelModalDialog(
|
||||
"Confirm delete",
|
||||
"Are you sure you want to delete the user defined function?",
|
||||
"Delete",
|
||||
() => {
|
||||
deleteUserDefinedFunction(this.collection.databaseId, this.collection.id(), this.id()).then(
|
||||
() => {
|
||||
useTabs.getState().closeTabsByComparator((tab) => tab.node && tab.node.rid === this.rid);
|
||||
|
@ -108,5 +110,9 @@ export default class UserDefinedFunction {
|
|||
/**/
|
||||
}
|
||||
);
|
||||
},
|
||||
"Cancel",
|
||||
undefined
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import * as GalleryUtils from "./GalleryUtils";
|
||||
import { JunoClient, IGalleryItem } from "../Juno/JunoClient";
|
||||
import { HttpStatusCodes } from "../Common/Constants";
|
||||
import { useDialog } from "../Explorer/Controls/Dialog";
|
||||
import { GalleryTab, SortBy } from "../Explorer/Controls/NotebookGallery/GalleryViewerComponent";
|
||||
import Explorer from "../Explorer/Explorer";
|
||||
import { IGalleryItem, JunoClient } from "../Juno/JunoClient";
|
||||
import * as GalleryUtils from "./GalleryUtils";
|
||||
|
||||
const galleryItem: IGalleryItem = {
|
||||
id: "id",
|
||||
|
@ -29,11 +30,11 @@ describe("GalleryUtils", () => {
|
|||
|
||||
it("downloadItem shows dialog in data explorer", () => {
|
||||
const container = {} as Explorer;
|
||||
container.showOkCancelModalDialog = jest.fn().mockImplementation();
|
||||
|
||||
GalleryUtils.downloadItem(container, undefined, galleryItem, undefined);
|
||||
|
||||
expect(container.showOkCancelModalDialog).toBeCalled();
|
||||
expect(useDialog.getState().visible).toBe(true);
|
||||
expect(useDialog.getState().dialogProps).toBeDefined();
|
||||
expect(useDialog.getState().dialogProps.title).toBe("Download to My Notebooks");
|
||||
});
|
||||
|
||||
it("favoriteItem favorites item", async () => {
|
||||
|
@ -66,11 +67,11 @@ describe("GalleryUtils", () => {
|
|||
|
||||
it("deleteItem shows dialog in data explorer", () => {
|
||||
const container = {} as Explorer;
|
||||
container.showOkCancelModalDialog = jest.fn().mockImplementation();
|
||||
|
||||
GalleryUtils.deleteItem(container, undefined, galleryItem, undefined);
|
||||
|
||||
expect(container.showOkCancelModalDialog).toBeCalled();
|
||||
expect(useDialog.getState().visible).toBe(true);
|
||||
expect(useDialog.getState().dialogProps).toBeDefined();
|
||||
expect(useDialog.getState().dialogProps.title).toBe("Remove published notebook");
|
||||
});
|
||||
|
||||
it("getGalleryViewerProps gets gallery viewer props correctly", () => {
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Notebook } from "@nteract/commutable";
|
|||
import { NotebookV4 } from "@nteract/commutable/lib/v4";
|
||||
import { HttpStatusCodes } from "../Common/Constants";
|
||||
import { getErrorMessage, getErrorStack, handleError } from "../Common/ErrorHandlingUtils";
|
||||
import { TextFieldProps } from "../Explorer/Controls/Dialog";
|
||||
import { TextFieldProps, useDialog } from "../Explorer/Controls/Dialog";
|
||||
import {
|
||||
GalleryTab,
|
||||
GalleryViewerComponent,
|
||||
|
@ -222,7 +222,7 @@ export function downloadItem(
|
|||
});
|
||||
|
||||
const name = data.name;
|
||||
container.showOkCancelModalDialog(
|
||||
useDialog.getState().showOkCancelModalDialog(
|
||||
"Download to My Notebooks",
|
||||
`Download ${name} from gallery as a copy to your notebooks to run and/or edit the notebook.`,
|
||||
"Download",
|
||||
|
@ -388,7 +388,7 @@ export function deleteItem(
|
|||
if (container) {
|
||||
trace(Action.NotebooksGalleryClickDelete, ActionModifiers.Mark, { notebookId: data.id });
|
||||
|
||||
container.showOkCancelModalDialog(
|
||||
useDialog.getState().showOkCancelModalDialog(
|
||||
"Remove published notebook",
|
||||
`Would you like to remove ${data.name} from the gallery?`,
|
||||
"Remove",
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
"./src/Contracts/SelfServeContracts.ts",
|
||||
"./src/Contracts/SubscriptionType.ts",
|
||||
"./src/Contracts/Versions.ts",
|
||||
"./src/Explorer/Controls/Dialog.tsx",
|
||||
"./src/Explorer/Controls/GitHub/GitHubStyleConstants.ts",
|
||||
"./src/Explorer/Controls/SmartUi/InputUtils.ts",
|
||||
"./src/Explorer/Graph/GraphExplorerComponent/ArraysByKeyCache.test.ts",
|
||||
|
|
Loading…
Reference in New Issue