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